feat(review): add working-tree staging, hunk actions, and focused files-pane UX - #1021
feat(review): add working-tree staging, hunk actions, and focused files-pane UX#1021yusing wants to merge 27 commits into
Conversation
|
PR author is not in the allowed authors list. |
|
@yusing is attempting to deploy a commit to the Modem Team on Vercel. A member of the Team first needs to authorize it. |
|
@yusing This feels like a large UX change, with no screenshots/video etc. Did you consider building this as an extension instead? (It's unlikely I'm going to merge this because it's not aligned with the project goals. The core is not trying to rebuild lazygit. But if you need more extension points to make that happen, that's worth discussing.) |
Expose both Git status sides through the public VCS and sidebar contracts. Stage or unstage exact files with Space and consecutive mouse double-clicks, preserve unrelated changes, and reconcile writes through reload and graceful shutdown. Add provider, command, component, and PTY coverage plus extension and keybinding documentation.
Apply byte-preserving canonical Git hunks with status and HEAD attestation. Keep unrelated hunks and worktree content intact, refuse text-converted patches, and integrate scoped Space and release-confirmed double-click actions through the provider contract.
Add exact-file confirmation and stash-message prompts with contextual keys and mouse parity. Preserve unrelated live changes and stash trees, partial staging, tracked modes, and recoverable published stashes when cleanup fails.
Track deliberate line selection separately from viewport seeding, fall back to the active hunk's first change, and map staged source addresses through later worktree edits. Guard asynchronous lookups by review generation and refuse unsupported editor line syntax.
Render index and worktree status columns with semantic colors, highlight selected rows across the full sidebar width, and color fully staged filenames. Add optional `statusCode` to the v21 extension API, expose Git status codes, and document and test the new sidebar behavior and theme contrast.
Hide shadowed key hints from help and menus, keep file quick actions scoped to the focused sidebar, and fall back to file staging when hunk staging is unavailable. Add coverage for pointer focus, shortcut precedence, and working-tree behavior.
Track focus ownership between the files pane and the review stream so pointer and command toggles move cursor ownership cleanly: `↑`/`↓`/`j`/`k` now step files when the files pane is focused, review focus stays in the diff stream, and `Space` stages the file when a selected hunk is not stageable. Review-stream clicks now drop files-pane quick-action scope, and focused panes are visually emphasized with brighter frame and divider styling. Centralize shortcut labeling for help and menus through first-match command ownership so a command only advertises keys that are actually reachable, preventing shadowed aliases from appearing while preserving visible alternatives on the real owner. Updated command descriptions, docs, and focused-pane/interaction tests to match the new focus model and selection behavior.
Add a files-pane selection model that tracks folder rows alongside files, and thread folder-aware entry IDs through sidebar rendering and extension working-tree props. Folder and file rows are now selectable/clickable with updated focus and highlighting, and the focused entry is kept coherent across tree and compact sidebar modes. Wire the new model into working-tree actions so `Space`, discard, and stash now operate on the focused files-pane row, including folders. Folder actions apply to all nested files in tree view or all files under a compact group row, with updated prompts/messages and selection behavior. Bump extension VCS API version and expose `selectedEntryId`/`selectEntry`/`toggleEntry`, plus a new provider operation `stashFiles` so folder actions can stash multiple attested files in one operation. The Git adapter now performs multi-file stashes while preserving per-file staged-untracked semantics, with docs and tests updated for the new behavior.
Add optional `stats` (`additions`/`deletions`) to working-tree file inventory in API v23 and enrich git status rows from `git diff --numstat` across both staged and unstaged sides, including rename/copy-safe parsing and untracked/symlink/large-file count handling, so sidebar +/- stays visible even when a file is off the active review stream. Preserve folder selection semantics by choosing a nested path on the current tab when available so folder-stage/discard/stash actions do not unexpectedly jump sides, and update sidebar rendering helpers, selection tests, and docs/keybinding wording to reflect file-or-folder actions and stable stats visibility across tabs.
Add `hunk.review.focusDiffPane` and `hunk.review.focusFilesPane` command entries and App bindings so Enter focuses the selected file’s review and Escape returns focus to the files pane, with enablement tied to active pane state and selection kind. Normalize Escape key matching for `escape`, `esc`, and raw `\u001b`, expose both actions in file menu/help/keyboard docs, and extend command, menu, and interaction tests (including mode handoff coverage with overrideable bindings) for the new focus behavior.
Add micro editor line-jump support for the `e` shortcut, including editor flags, documentation, and PTY coverage.
Keep large unwrapped diffs responsive on the first frame by applying provisional row bounds before the terminal viewport is measured. Update PTY coverage for split and stack modes, keyboard readiness, and shared sidebar frame assertions.
|
Rebased onto modem-dev/hunk/main at 6d4440a and resolved the Git-provider, clipboard, and pane integration conflicts. Force-pushed with a lease to c4a0785; GitHub now reports MERGEABLE. The earlier fork-only rebase did not incorporate upstream and has been corrected. Updated the description with fresh validation: 4,087 unit tests pass, 71 focused integration tests pass, 9 TTY smoke tests pass; the full PTY run had two add-note timeouts, followed by a green 21-test notes rerun. |
I appreciate that. Tell me what you need changed from the extension API (or add your own upstream contribs) and we'll make it possible. You might also want to look at https://github.com/victor-software-house/hunk-history |

Problem and user impact
Working-tree review could show a diff, but staging, unstaging, discarding, and stashing still required leaving the TUI. File-list navigation also competed with the review stream for the same keys.
This PR adds default Git working-tree actions while preserving the full multi-file review stream:
[/], Space acts only on that hunk.$EDITOR, mapping staged coordinates through later worktree edits; supported editors include micro.Keyboard and mouse actions share the existing command path. Built-in review shortcuts retain their meaning outside an actionable working-tree files pane.
Approach and ownership
Keep Pierre as the renderer and the shared review document as the semantic model. Optional VCS provider operations implement mutations behind
hunkdiff/extension;useWorkingTreeActionsowns host-side action targeting and AppHost owns write/reload/shutdown coordination. Sidebar selection still navigates the whole stream rather than creating a single-file review.The bundled Git provider implements attested file and canonical byte-preserving hunk staging, scoped discard/stash (including
stashFiles), and staged-to-worktree editor-line mapping. Provider commands remain inpackages/hunk-git.Working-tree inventory and mutation capabilities require API v25:
stageHunk/unstageHunk,discardFile/stashFile,resolveWorkingTreeLine, inventory status and line counts, andstashFiles. Upstream API v20 supplies clipboard capabilities but does not supply these working-tree operations.Sidebar extensions receive
selectedEntryId,selectEntry, andtoggleEntry. These default working-tree controls belong in the host, while provider-specific behavior stays behind the existing extension contract.Review follow-up fixes
Upstream rebase and validation
Rebased onto the actual
modem-dev/hunk/maincommit 6d4440a, resolved conflicts, and pushed the rewritten branch with an explicit force-with-lease. GitHub now reports MERGEABLE at head c4a0785. The earlier pull against the fork'sorigin/maindid not incorporate upstream; this rebase replaces that incorrect update.Conflict resolution preserves upstream's shortened Git comparison titles, clipboard actions, history review metadata, and saved-view quit dialog alongside the PR's working-tree staging, selection, and pane-focus behavior. Test fixtures now include the upstream clipboard action, and capability documentation requires API v25 for working-tree operations rather than implying that upstream API v20 supports them. A targeted independent source inspection approved the integration.
Validated on Linux with Bun 1.4.2 and Node 24.20.0:
bun run typecheckbun run format:checkbun run deps:checkbun run check:docsbun run check:changelogbun run testbun test packages/hunk/src/ui/components/ui-components.test.tsxbun test ./test/review-conformancebun run test:session-broker-nodebun run test:tty-smokebun run install:binFocused rebase integration command:
bun test packages/hunk-git/src/index.test.ts packages/hunk/src/ui/AppHost.working-tree.test.tsx packages/hunk/src/ui/AppHost.workspace.test.tsx packages/hunk/src/ui/AppHost.review-metadata.test.tsx packages/hunk/src/ui/components/panes/ExtensionPane.test.tsxThe ordinary lint traversal is affected by a parent ignore rule. Explicit tracked-file lint passed on 993 files:
Terminal-suite limitations
bun run test:integrationcompleted with 175 passed, 1 skipped, 2 failed:add-note affordance appears only after mouse movement in a real PTYclicked add-note drafts can cancel and save with keyboard shortcutsBoth timed out looking for the add-note affordance. The subsequent complete notes-suite rerun passed all 21 tests:
bun test ./test/pty/notes.test.tsThe two exact cases also passed 20 executions on the new upstream base:
A broader upstream run,
bun test ./test/pty/notes.test.ts --rerun-each 3, produced 56 passes and one failure in the existing CJK draft-frame assertion. Earlier validation on upstream0b730465reproduced the add-note hover timeout, current-line repaint assertion, and CJK draft assertion. These results do not establish that both latest timeouts reproduce on the latest upstream commit; the complete PTY run remains recorded as non-green, not hidden behind the successful rerun. No unrelated terminal behavior was changed to address these intermittent cases.Platforms and visual evidence
Non-goals and limitations