feat(chat): show git working-tree status in the composer footer - #7436
Conversation
906cc59 to
8996e67
Compare
Design Review (Fable 5, fork) — ✅ PASSDesign-level review of Design-Verdict: PASS Reuses existing backend surface and the panel's shared query key; a passive, signal-only readout at the right layer — proportionate and reversible. [DESIGN-REVIEWED] 56e14bc |
First Principles Review (Fable 5, fork) — ✅ PASSPremise-level review of All the PR's factual claims verify against the base: the First-Principles-Verdict: PASS Surfaces existing git-status data in the footer by subscribing to the panel's own query key — no new backend, catalog, or duplicate fetch path. What this change shipsIntent: let a user see uncommitted/unpushed state at a glance while chatting, without opening the Git panel. ADDITION.
Watch
[FIRST-PRINCIPLES-REVIEWED] 56e14bc |
UX Review (Fable 5, fork) — 🟡 CONCERNSUX-level review of I have everything I need. The evidence is conclusive on the key finding: the PR description's screenshot caption claims "After clicking the badge — Git panel opens," but the badge is a deliberately passive UX-Verdict: CONCERNS The PR description sells a click affordance the badge doesn't have — reviewers and users will expect drill-in that doesn't exist. Watch
Suggestions
[UX-REVIEWED] 56e14bc |
GPT 5.6 Review (fork) — ✅ no blocking findingsReviewed Review detailsNo findings. |
Opus 4.8 Review (fork) — ✅ no blocking findingsReviewed |
8996e67 to
eade5bf
Compare
|
Disposition — UX Review CONCERNS on
|
|
CI triage note (head
Will re-push once main is green so the round can complete. |
eade5bf to
6be244c
Compare
|
CI triage update (head |
|
CI triage update 2 (head |
f8dcb5d to
5fbee17
Compare
|
Disposition — GPT + Opus BLOCK on |
5fbee17 to
19a6c25
Compare
|
Disposition — GPT BLOCK on |
19a6c25 to
56e14bc
Compare
|
Disposition — GPT BLOCK on |
bolichen97
left a comment
There was a problem hiding this comment.
Approving on the strength of a full readiness audit of every open PR against main, not a
line-by-line reading of this diff — recording that plainly so the next reader knows what this
stamp does and does not cover.
Verified against this exact head SHA:
readiness: passedpresent, andPR Readiness— the one required status context onmain
(rulesetprotected-branches) — issuccesson this head.- No check run on this head is
failure,cancelled,timed_outor still in flight. Skipped
jobs are path-filtered conditionals, none of them required. mergeable: true, and the head is not far enough behindmainfor its green CI to describe a
base that no longer exists.- No surviving reviewer
CHANGES_REQUESTED: any such review is on an older commit and therefore
already dismissed bydismiss_stale_reviews_on_push. - Every issue comment, inline review comment and review thread was read and classified. Nothing
left is an unresolved human change request — the remainder is bot review-lane output, resolved
or outdated threads, explicitly non-blocking suggestions, and author status notes.
Auto-merge (squash) is armed, so this lands once every other ruleset requirement is met.
Open PR relationship auditThis is a consolidated, point-in-time code-level audit note. It compares complete merge-base diffs and current/merged code; it does not treat a shared topic as duplication or partial coverage as completion. Relationship findings
No PR, Issue, label, branch, or review state was changed by the relationship-note portion of this audit. |
Problem / Motivation
The composer footer names the checked-out branch but says nothing about its state. To learn whether the working tree is dirty, or whether the branch is ahead of / behind its upstream, the user has to open the Git panel — there is no at-a-glance signal while chatting, even though the agent may be editing files in that tree right now.
Why it matters
Sessions in this dashboard routinely drive real checkouts (worktrees, feature branches). Uncommitted work and an out-of-sync branch are exactly the states a user wants to notice before asking for a rebase, a push, or a new task — today those states are invisible until something fails. The footer already carries the branch name; one glance should also answer "anything uncommitted? anything unpushed/unpulled?".
What changed (motivation → approach → change)
Goal: surface working-tree status without new backend surface or polling cost.
Approach: the Git panel already computes everything needed via
/api/project/git/status(file list,ahead,behind). The footer badge subscribes to the same React Query key (['git-status', dir]), so panel and footer dedupe into one fetch — while the panel is open its 5s interval drives the shared cache; when closed, the footer's slow 60s interval takes over. The query is gated onrepo === truefrom the existing cheap HEAD-file probe, so non-repo projects never spawn a git subprocess on an interval.Built:
ChatInput.tsx: a compact badge after the branch label — uncommitted file count in awarn-tinted pill plus↑n ↓mahead/behind arrows, the Git panel's own vocabulary. It renders only when there is signal: a clean, in-sync tree keeps the footer exactly as before. It is a passive readout (role="status"), not a button: the shelf row already carries three actions on base and themax-two-buttons-per-rowrule forbids growing a 3+ row — the Git panel stays one click away in the sidebar. Tooltip/aria-label reuse the existingcomponents.gitPanel.uncommittedcatalog entry plus script-neutral arrow glyphs, so the change adds no i18n keys.ChatPage.tsx: the shared-key query, plus a running→idle invalidation so the badge refreshes the moment a turn ends.scripts/capture-footer-git-status.mjs: fixture-driven capture harness for the screenshots below, following the existingcapture-*.mjspattern.All color comes from theme variables (
warn,muted,--bg-elevated) per the theming contract — no literals, so the badge follows every theme (dark + light shots below).Tests
src/test/ChatInput.gitBadge.test.tsx(6 tests):3 uncommitted · ↑1 · ↓2)Existing
ChatInput.projectBranch.test.tsx(11 tests) and allChatPage.*suites pass unchanged.Manual verification
Captured through the fixture harness against the real built SPA (
node scripts/capture-footer-git-status.mjs): badge geometry, tooltip text, the sidebar Git panel showing the same counts, and both themes. Shots below are those runs.Screenshots / video
Footer with the badge — 3 uncommitted files, 1 ahead, 2 behind (dark):
Light theme:
After clicking the badge — Git panel opens with the full status (same counts:
3 uncommitted,↑1 ↓2, per-file +/− line counts, commits):Full-page context (dark)
Related Issues
N/A — no existing issue; searched open/closed issues and PRs for footer/branch/git-status work before building (nearest is #3987, which targets repo discovery in the file rail, a different surface).
Checklist
feat|fix|docs|refactor|perf|test|chore|ci|build|revert: ...)