@scpz24/pi-worktree-hud
v0.1.1
Published
Source-control worktree HUD for Pi's interactive TUI
Readme
@scpz24/pi-worktree-hud
A source-control HUD for the Pi Coding Agent. It keeps a compact Git worktree summary in a non-capturing top-right overlay, expands into a keyboard-driven file manager, and opens bounded read-only diff previews.
Requirements
- Pi 0.84.1 or newer
- Node.js 22.19.0 or newer
- Git 2.23.0 or newer
- macOS or Linux
- Pi's interactive TUI mode and a Git worktree
The extension deliberately does nothing in non-TUI sessions and does not start polling outside Focused mode.
Install
After the package is published:
pi install npm:@scpz24/pi-worktree-hudFor development from this monorepo:
pi -e ./packages/pi-worktree-hudPi loads the TypeScript entry point directly; this package does not ship a dist directory or require a build step at runtime.
Use
The HUD starts in Compact mode. On macOS, open and focus the file list with Control+Command+W; on Linux, use Ctrl+Alt+W. Both shortcuts only open the panel—close it with Esc or q. Repeating the shortcut while the HUD is focused keeps it open. /worktree-hud open is always available when the terminal cannot report the modifiers or another extension or user keybinding claims the same combination.
Pi expresses the macOS shortcut as Ctrl+Super+W and the Linux shortcut as Ctrl+Alt+W, and registers only the shortcut for the current platform. The macOS combination requires a terminal that reports Command/Super separately, typically through the Kitty keyboard protocol or an equivalent extended-key protocol. Bare Option+W is deliberately not used because the default macOS keyboard layout may enter ∑ instead of reporting an Alt shortcut. Neither target combination conflicts with Pi 0.84.1's default keybindings, although custom keybindings.json entries and other extensions can still introduce conflicts.
macOS Compact HUD:
╭ Worktree · feature/worktree-hud ───────────────╮
│4 files +18 -6 │
╰ ⌃⌘W ───────────────────────────────────────────╯Linux Compact HUD:
╭ Worktree · feature/worktree-hud ───────────────╮
│4 files +18 -6 │
╰ Ctrl+Alt+W ─────────────────────────────────────╯The frame follows the active Pi theme. Non-zero additions use Pi's diff-added color, non-zero deletions use its diff-removed color, and zero-valued directions are omitted. These totals include staged and unstaged changes to tracked files; untracked files are counted in the file sections but do not contribute lines.
Focused keys:
| Key | Action |
| --- | --- |
| Up / k, Down / j | Move between file rows |
| Tab, Shift+Tab | Jump between non-empty sections |
| Space | Stage the selected conflict/change/untracked row, or unstage a staged row |
| A | Stage all changes |
| U | Unstage all, unless conflicts exist |
| Enter | Open a read-only diff preview |
| r | Refresh immediately (the normal footer intentionally omits this hint) |
| Esc / q | Return to Compact mode and release focus |
Preview keys:
| Key | Action |
| --- | --- |
| Up / k, Down / j | Scroll one line |
| PageUp, PageDown | Scroll one page |
| Left / h, Right / l | Scroll horizontally |
| n, p | Next or previous hunk |
| Esc, q | Close Preview and focus the HUD again |
Commands:
/worktree-hud
/worktree-hud open
/worktree-hud close
/worktree-hud refresh
/worktree-hud hide
/worktree-hud show
/worktree-hud statushide permanently removes the current Overlay entry. show creates a fresh component and Overlay handle. status reports the repository, branch/HEAD state, snapshot generation/freshness/completeness, agent lock, mutation queue, HUD mode, polling interval, and Overlay state.
Behavior and safety
stateDiagram-v2
[*] --> Compact: valid Git worktree + TUI
Compact --> Focused: Control+Command+W (macOS), Ctrl+Alt+W (Linux), or open
Focused --> Compact: Esc, q, or close
Focused --> Preview: Enter
Preview --> Focused: Esc or q
Compact --> Unmounted: hide or shutdown
Focused --> Unmounted: hide or shutdownSections always appear as Conflicts → Staged → Changes → Untracked. A path changed in both the index and worktree appears once in Staged and once in Changes; conflicts appear only in Conflicts. Rename rows display old → new, while Git receives only the current path.
Section headings and status codes use theme semantics: Staged is success, Changes is warning, Conflicts is error, and Untracked is accent. File paths remain normal text so the panel stays readable in both light and dark themes.
Index operations are serialized through one FIFO queue. Every write is followed by a successful refresh before the next operation is considered. File operations are revalidated against the latest row and file/index signature; stale queued requests are skipped. All-operations are skipped when their originating generation is no longer current.
While Pi runs an edit, write, or bash tool, new index operations are rejected and the existing queue pauses. It resumes only after the last mutating tool finishes and Git refresh succeeds.
The extension uses only argv-based Git processes with shell: false and -- before pathspecs. It never uses git reset, never modifies worktree content, never temporarily stages a file for preview, and never follows an untracked symlink. Conflict rows can be staged but cannot be individually unstaged; Unstage All is disabled while any conflict exists.
Status, statistics, diffs, and untracked reads have timeout/size/record limits. Partial status locks all writes. A truncated status still allows Stage All and operations on parsed rows. A failed refresh preserves the previous snapshot as stale for browsing and preview, but locks index writes until a complete successful refresh.
Compact, hidden, non-Git, and non-TUI states have no polling timer. Focused polling backs off from approximately one second to three seconds after ten quiet seconds and five seconds after thirty quiet seconds. No watcher, daemon, socket, IPC, or cross-process state is used.
The Overlay uses row one (margin.top: 1), leaving row zero available for extensions such as pi-breath without importing or detecting them. Terminals smaller than 72×12 hide the Overlay automatically; narrow render widths use progressively reduced layouts.
In fullscreen mode, Pi owns transcript scrolling and composites the Overlay at screen-relative top-right coordinates after each PageUp or mouse-wheel update. The package regression-tests both paths through Pi's public TuiAltScreen. If a particular Pi/terminal combination still moves the HUD with the transcript, report the Pi version, terminal, and reproduction steps; the extension deliberately does not use ANSI cursor positioning, private renderer state, input interception, or forced redraw timers as a workaround.
Development
Run from the monorepo root:
npm install
npm --workspace @scpz24/pi-worktree-hud run lint
npm --workspace @scpz24/pi-worktree-hud run typecheck
npm --workspace @scpz24/pi-worktree-hud test
npm --workspace @scpz24/pi-worktree-hud run build
npm --workspace @scpz24/pi-worktree-hud run pack:check
npm run checkVitest covers parsers, real temporary repositories, state derivation, refresh/polling, mutation/soft-lock behavior, diff safety, viewport logic, HUD keys/layout, Overlay disposal, and Pi registration. Biome is scoped to this package only. Both typecheck and build are no-output TypeScript validation.
License
MIT
