Co-authored-by: Jelloeater's Agent <agent@jello.dev> Co-authored-by: Henry <nova28@users.noreply.github.com> Co-authored-by: nova28 <17953305+nova28@users.noreply.github.com> Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
5.3 KiB
created, status, requirements, system_design, legacy_specs
| created | status | requirements | system_design | legacy_specs | ||
|---|---|---|---|---|---|---|
| 2026-09-03 | implemented |
|
|
Implementation Plan: Keep Changes File Action Feedback Visible
Overview
Make per-file stage and unstage pending feedback override the tree row's idle hover swap. One focused work order first captures the failure by pausing the worktree request in Chromium, then makes the minimum shared component change and verifies the completed stage and unstage transitions.
Confirmed root cause
StageButtoncorrectly rendersIconLoader2wheneverFileRow.isPendingis true.- In tree mode,
TreeModeFileActionSlotwraps that button in a fine-pointer layer whose visibility is controlled only bygroup-hoverclasses. - The adjacent
FileIconalso follows only the inverse hover rule. It does not considerisPending. - Leaving the row therefore makes the action layer, including its spinner, transparent and restores the file-type icon even though the repository/path pending key remains active.
- Coarse-pointer rows do not receive the hover-only classes, so their action and spinner already remain visible.
Scope
In scope
- Give pending state precedence over the fine-pointer file-icon/action hover swap.
- Keep the existing spinner visible after pointer leave for both stage and unstage operations.
- Preserve per-repository, per-path pending-state scoping.
- Add deterministic Chromium coverage that holds each WebSocket request open, leaves the row, and observes the pending and completed states.
- Preserve the existing coarse-pointer action visibility and touch sizing.
Out of scope
- Git operation dispatch, status polling, WebSocket contracts, and pending-key lifecycle changes.
- Bulk actions, discard/edit feedback, cancellation, notifications, and new copy.
- Changes-panel layout, path truncation, navigation, or mobile composition.
Technical approach
Update TreeModeFileActionSlot in
apps/web/components/task/changes-panel-file-row.tsx so the fine-pointer idle
hover classes apply only when isPending is false. While pending, keep the
file-type icon hidden and the spinner layer visible independent of the row's
hover state. Continue rendering the same StageButton; do not introduce
component-local request state.
Extend apps/web/e2e/tests/git/git-changes-panel.spec.ts with a narrow
WebSocket transport controller patterned after the existing request-pause
helpers. It shall pause only the armed worktree.stage or
worktree.unstage frame and forward all other frames. The regression creates a
target file (pending-action.txt) and a sibling file (pending-sibling.txt),
starts each action from the UI, waits until the request is paused, moves the
pointer to a neutral location, and asserts the existing spinner is still
visible only for the target row before releasing the request and observing the
file's new section.
Tests
- AC-UI-CHANGES-FILE-ACTION-FEEDBACK-001.1 through .4: the focused Chromium scenario proves spinner visibility for both request types after pointer leave, per-row scoping, and the final staged/unstaged section.
- AC-UI-CHANGES-FILE-ACTION-FEEDBACK-001.5: the existing
changes-panel-file-row.test.tsxcoarse-pointer assertion andmobile-changes-panel.spec.tsstage/unstage path remain unchanged and green.
E2E tests
- Add
keeps stage and unstage progress visible after pointer leavestoapps/web/e2e/tests/git/git-changes-panel.spec.tsin the Chromium project. - No new Pixel 5 case is planned because the coarse-pointer branch already keeps the action slot visible and this work changes neither its markup nor its interaction. Existing mobile coverage exercises both stage and unstage controls through the shared row.
Work orders
Dependency order
Task 01
The browser regression and component correction share one presentation boundary and proceed sequentially through Red-Green-Refactor.
Verification results
- RED: the focused Chromium scenario failed after pointer leave because the
pending action layer reached
opacity: 0whileworktree.stageremained paused. - GREEN: the production-build Chromium scenario passed both the paused stage and paused unstage flows. A final no-build rerun after test formatting also passed.
- The existing
changes-panel-file-row.test.tsxsuite passes all 16 tests, including the coarse-pointer action visibility and touch-size assertion. - Targeted ESLint, web typecheck, specification lint, and scoped diff checks pass.
Risks
- A visibility change that hides the file icon without explicitly revealing the spinner layer could leave the slot blank after pointer leave. The E2E assertion observes the rendered spinner, not only class names.
- A WebSocket pause helper can disrupt unrelated live updates if it buffers a whole message instead of only the matching newline-delimited frame. The helper must partition and forward unrelated frames immediately.
- Completion can move the row between sections and detach its locator. The test must reacquire the row from the destination section before testing the inverse action.
Open questions
None.