Skip to content

feat(tui): add git status overlay with inline + preview push/pull stats#316

Merged
jongio merged 3 commits into
mainfrom
go/git-status
Jul 17, 2026
Merged

feat(tui): add git status overlay with inline + preview push/pull stats#316
jongio merged 3 commits into
mainfrom
go/git-status

Conversation

@jongio

@jongio jongio commented Jul 17, 2026

Copy link
Copy Markdown
Owner

What

Add a Git Status feature for the folder each session is mapped to, surfaced in three places:

  • On-demand overlay (key i / command palette): branch → upstream, push/pull stats (commits ahead/behind), working-tree counts (staged, modified, untracked, deleted, conflicts), and a scrollable list of changed files. Esc closes, ↑↓ scroll, c copies a summary.
  • Session row (inline): a compact colored ↑N ↓N ● segment (ahead to push, behind to pull, dirty marker) at wider terminals. The old single-glyph badge is suppressed on rows that show the inline stats, so there's never a duplicate indicator.
  • Preview pane: a git section under the Branch field with branch → upstream, push/pull, and per-category change counts.

Why

Sessions map to working directories, but the list only showed a single collapsed git badge - hiding the numbers that matter when triaging many sessions: how far ahead/behind you are, whether you owe a push or a pull, and how much uncommitted work is sitting there. Answering that meant leaving dispatch to run git status.

How

DetectGitStatus is the single git-scanning entry point: one git status --porcelain=v2 --branch per session (a pure parser makes it testable). GitStatus.State() derives the badge enum, and ScanGitStatuses replaces the old enum-only scanners (DetectGitState/ScanGitStates), so the inline row, preview, and badge all come from one scan instead of up to three git commands. The overlay follows the existing Compare/CommandPalette pattern. Non-repo, missing, detached-HEAD, and no-upstream folders are handled without error.

Security: all git invocations pass -c core.fsmonitor=false -c core.hooksPath= so a session pointing at an untrusted repo can't execute arbitrary code via repo-local git config during status collection (CWE-829). Verified by a positive-control regression test.

Coupled fix: wordWrap now hard-breaks tokens longer than the wrap width. Previously it only broke on spaces, so a message with a long path/URL overflowed the chat bubble and corrupted the preview's border.

Also fixes three pre-existing CI breakages on main from earlier PRs (#299 parseOpenArgs arity + open.go gofmt, #284 duplicated test block).

Testing

  • go build ./cmd/dispatch/ passes
  • go test ./... passes (full suite green, incl. race detector via mage install)
  • go vet ./... passes
  • New tests added for new functionality (60+ new test functions)
  • Existing tests still pass

Quality Gates

Gate Status Notes
mq (max-quality) PASS 2 issues found + fixed (rune-safe truncation; overlay push/pull consistency)
cr (code-review) PASS 2 independent passes, 0 high-confidence findings; verified no badge/filter regression from the consolidation
pf (preflight) PASS format/tidy/vet/build/test/gofumpt/race/deadcode clean; golangci-lint "0 issues"
secops (security) PASS 2 passes; 1 HIGH (core.fsmonitor RCE) found + fixed + regression-tested; RCE hardening confirmed intact after consolidation
th (test-health) PASS test plan reconciled, zero functionality gaps

Screenshots

Terminal UI (no static image). Inline row shows ↑N ↓N ●; the preview git section shows branch → upstream, push/pull, and change counts; the i overlay adds the scrollable changed-files list.

jongio and others added 3 commits July 17, 2026 05:48
Add an "i" keybinding (and command-palette entry) that opens a modal
overlay showing the git status of the folder a session is mapped to:
current branch and upstream, the standard push/pull stats (commits ahead
to push, behind to pull), working-tree counts (staged, modified,
untracked, deleted, conflicts), and a scrollable list of changed files.

The status is gathered off the UI thread with a single bounded
`git status --porcelain=v2 --branch` command. Non-repo, missing,
detached-HEAD, and no-upstream folders are reported without error.

Security: harden all git invocations in gitstate.go with
`-c core.fsmonitor=false -c core.hooksPath=` so a session pointing at an
untrusted repository cannot execute arbitrary code via repo-local git
config during status collection (CWE-829). Covered by a positive-control
regression test.

Also fixes three pre-existing CI breakages on main from earlier PRs
(#299 parseOpenArgs arity + open.go gofmt, #284 duplicated test block).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 524cf702-8922-4cfd-b23f-4069b734e09b
Show the git push/pull state everywhere a session appears, not only in the
on-demand overlay:

- Session row: a compact, colored `↑N ↓N ●` segment (commits ahead to push,
  behind to pull, plus a dirty marker) at wider terminals. The single-glyph
  badge is suppressed on rows that show the inline stats so there is never a
  duplicate git indicator; a missing-workspace marker folds into the segment.
- Preview pane: a git section under the Branch field with branch -> upstream,
  push/pull counts, and per-category working-tree counts (or a clean label).

To feed both surfaces without scanning twice, DetectGitStatus becomes the single
git-scanning entry point: GitStatus.State() derives the badge enum and
ScanGitStatuses replaces the old enum-only DetectGitState/ScanGitStates (one
`git status --porcelain=v2 --branch` per session instead of up to three
commands). All badge rendering and git-dirty/missing filters keep working off
the derived enum.

Also fix a pre-existing preview rendering bug: wordWrap only broke on spaces, so
a message containing a long unbreakable token (a path or URL) overflowed the
chat bubble and corrupted the preview's outer border. It now hard-breaks tokens
longer than the wrap width. Covered by regression tests.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 524cf702-8922-4cfd-b23f-4069b734e09b
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 524cf702-8922-4cfd-b23f-4069b734e09b
@jongio
jongio merged commit 27b173d into main Jul 17, 2026
2 checks passed
@jongio
jongio deleted the go/git-status branch July 17, 2026 17:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant