Skip to content

Remove the commit box and the staging controls - #47

Merged
cjimti merged 1 commit into
mainfrom
feat/39-remove-commit-ui
Aug 6, 2026
Merged

Remove the commit box and the staging controls#47
cjimti merged 1 commit into
mainfrom
feat/39-remove-commit-ui

Conversation

@cjimti

@cjimti cjimti commented Aug 6, 2026

Copy link
Copy Markdown
Member

Closes #39. Child of #37 §2.

What changes

The AI in the terminal does the committing. It runs the user's own git in the user's own worktree, so a stage button in the sidebar is a second writer of the index that the agent cannot see — two tools disagreeing about one repository.

  • CommitBox is deleted, along with its test.
  • ChangesPanel keeps the staged/unstaged grouping and loses every action. The grouping stays because it is what git status reports whoever put the paths there; a path in the index and a path only on disk are different facts. Each row is now simply the button that opens its file, so Row and FileButton collapsed into one ChangeRow. The conflict hint drops "then stage them", which named a thing the UI can no longer do.
  • BranchBar is untouched. Branch display and switch, pull, push and the ahead/behind counts are what is left, and none of them writes the index.
  • The bound surface shrinks to what the UI calls: GitStage, GitUnstage and GitCommit are gone from internal/app, and frontend/wailsjs is regenerated.
  • The frontend seam follows: Git loses three methods, useGitOps loses three operations (and its internal run stops returning a success flag that only the commit editor read), and gitOps.ts loses CommitDraft, commitMessage, hasMessage, commitBlockedReason, stagedPaths, pathsOf and pathsOfAll.
  • style.css loses the .commit* block and the .changes__action / .changes__all rules.

The judgment call worth reviewing

The issue said the internal/git methods "can stay if the diff viewer (#35) or status still uses them." Nothing does — #35 is read-only and unbuilt — so under the no-vaporware rule they are not "kept for later", they are unreachable code. Stage, Unstage and Commit are removed, along with everything only they reached: pathspecs, relative, ErrNoPaths, ErrOutsideRoot, ErrEmptyMessage, gitDir and invocation.stdin.

If you want them held for #35 instead, that is a revert of internal/git/ops.go and its tests plus the two pin changes; the UI half stands either way.

One thing deliberately kept

run.go's explanation picks stdout when stderr is blank. Its known instance was git commit with an empty index, which this package no longer runs, and I checked pull, push and checkout — none of them was observed putting a failure reason on stdout only. The branch stays anyway: which stream carries the reason is git's decision per subcommand rather than this package's, and the cost of guessing wrong is an error box reading exit status 1 with no way to find out what happened. Five lines and a unit test is the cheaper side of that trade. Its comment now says all of this plainly instead of citing a command m6t runs.

Ratchets

All three come down; none goes up.

Pin Was Now
maxAppMethods 24 21
internal/git exported 27 21
internal/git LOC ceiling 1000 900

maxAppMethods has never come down before. The #9 note argued each of the eight git bindings was a request with an answer and no throughput, which was true and is not the test these three failed — they failed the older one, that the bound surface is only what the UI calls.

Documentation

DESIGN.md described a commit box with a message editor, a commit binding and a git service that commits. Left alone it would now be wrong, so §7 carries the decision and its reason, and §3.2, §3.3 and the summary at the top follow. README's feature line follows too.

Adversarial review

What I went looking for and what it found:

  • Does anything still reach the removed code? Full-tree grep for Commit/Stage/Unstage across Go, TS, TSX, MD and JSON: nothing left but unrelated words (commitFixture, buildinfo.commit, the tree's inline-rename commitRename).
  • Does an absence test pass for the wrong reason? The first version used /^Stage/ and /^Unstage/, which match every row's own accessible name (Staged: a.yaml). It passed on the rows rather than on the missing buttons. Both suites now assert exact names, and ChangesPanel additionally pins the full button list per render — that one fails if a control comes back under any name.
  • Is checkoutBlockedReason's "Commit or stash your changes" still honest? Yes: both happen in the terminal, and the doc comment now says so rather than leaving a reader to wonder which button it means.
  • Did anything become dead that the linters would not catch? gitOutput and stagedState (test helpers), fileIn (still used, checked), the changes__item class and the change: test IDs (nothing read them) — all removed. golangci-lint run ./... over the whole repo, not just the patch scope, reports 0 issues, and deadcode reports nothing.

Gates

make verify green.

  • Go tests pass, total coverage 95.4% (floor 80%)
  • Patch coverage 5/5 executable changed lines = 100% (floor 85%)
  • golangci-lint run ./... — 0 issues (full repo, not just patch scope)
  • gosec + govulncheck + semgrep + licenses clean
  • 645 frontend tests pass; typecheck and eslint clean; suppressions still 0
  • make bindings-check green
  • make build-check green; dead-code reports nothing

The AI in the terminal does the committing. It runs the user's own git in
the user's own worktree, so a stage button in the sidebar is a second
writer of the index that the agent cannot see — two tools disagreeing
about one repository.

CommitBox is gone. ChangesPanel keeps the staged/unstaged grouping,
because that is what git status reports whoever put the paths there, but
its rows carry no action: each row is now the button that opens its file.
BranchBar is untouched — branch switch, pull, push and the ahead/behind
counts are what is left, and none of them writes the index.

The bound surface is only what the UI calls, so GitStage, GitUnstage and
GitCommit go with the controls, and bindings are regenerated. The issue
allowed internal/git to keep its three methods for a future diff viewer;
nothing calls them, and code that is not wired in is dead code that has
to be maintained anyway, so Stage, Unstage and Commit go too, along with
everything only they reached: pathspecs, relative, ErrNoPaths,
ErrOutsideRoot, ErrEmptyMessage and invocation.stdin.

run.go's stdout fallback stays. Its known instance was `git commit` with
an empty index, which this package no longer runs, and no remaining
subcommand was observed choosing stdout for a failure — but which stream
carries the reason is git's decision per subcommand, and the cost of
guessing wrong is an error box reading "exit status 1" with no way to
find out what happened.

Ratchets come down rather than standing still: maxAppMethods 24 -> 21,
internal/git 27 -> 21 exported and 1000 -> 900 LOC. DESIGN.md §7 carries
the decision so the design document stops describing a commit box.

Closes #39.
@codecov

codecov Bot commented Aug 6, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.50%. Comparing base (a36790c) to head (796bb45).

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #47      +/-   ##
==========================================
+ Coverage   93.43%   93.50%   +0.07%     
==========================================
  Files          32       32              
  Lines        1553     1510      -43     
==========================================
- Hits         1451     1412      -39     
+ Misses         64       62       -2     
+ Partials       38       36       -2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@cjimti
cjimti merged commit 5070ef9 into main Aug 6, 2026
11 checks passed
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.

UI: remove the commit and staging UI — push and pull only

1 participant