-
-
Notifications
You must be signed in to change notification settings - Fork 0
Coco UI
coco ui is Coco's full-screen Git workstation. It builds on the interactive log work and moves toward a terminal-native alternative to GitKraken, lazygit, and gitui for daily repository work.
coco log -i remains supported. Internally it opens coco ui --view history, so existing muscle memory keeps working while new workflows grow around the broader coco ui entrypoint.
# Open the history browser
coco ui
# Start on worktree status
coco ui --view status
# Start on the focused diff surface
coco ui --view diff
# Keep using the existing interactive log entrypoint
coco log -i
# Browse all refs or filter history before opening
coco ui --all
coco ui --branch feature/ui --path src --limit 500
# Force a theme preset
coco ui --theme catppuccin
NO_COLOR=1 coco uiIf coco ui is not running in a TTY, Coco falls back to non-interactive output so automation and packaged CLI smoke checks do not hang.
The UI uses a persistent Git workstation layout:
-
Header: command label (
coco), repository, branch, dirty state, provider/PR state, search text, and a›-separated breadcrumb showing where you are in the navigation stack (e.g.history › diff). - Sidebar: status, branches, tags, stashes, and worktrees tabs. When focused, items inside the active tab are cursor-navigable and per-entity actions (checkout / apply / pop / drop / etc.) fire without leaving the workstation view.
- Main panel: the active view — history graph, status, diff, compose, branches, tags, stash, worktrees, or pull-request.
-
Right dock (inspector): contextual metadata + per-entity action list. Narrow at rest (~22% of width) so the commit graph dominates; expands to ~40% when focused via
tab. On short terminals, collapses into a tabbed[Inspector] Actionslayout so neither section gets clipped. -
Footer: two slots — view-specific contextual hints on the left, and persistent global affordances anchored to the right (
g jump · < back · ? help · : cmds · q quit).
The goal is calm density. Common actions stay visible; advanced or destructive actions move behind help, the command palette, or confirmation prompts.
coco ui has twelve top-level views. Each is a first-class destination — reachable from any other view through the navigation stack.
| View | Chord | Start flag | Purpose |
|---|---|---|---|
| History | g h |
--view history |
Browse commits, refs, changed files, and commit metadata. |
| Status | g s |
--view status |
Select changed files, stage/unstage, revert with confirmation. |
| Diff | g d |
--view diff |
Inspect the selected commit or worktree file diff with hunk navigation and staging. Toggle unified ↔ side-by-side with d. |
| Compose | g c |
— | Full-screen commit draft editor with summary/body cursors, AI draft, and hook feedback. |
| Branches | g b |
— | List local branches with divergence info; checkout/delete/create-PR via workflow keys. Current branch pinned at row 0. |
| Tags | g t |
— | List tags. |
| Stash | g z |
— | List stashes; apply/drop via workflow keys. (gs is reserved for status, so stash uses gz.) |
| Worktrees | g w |
— | List linked worktrees with current/dirty markers; remove via W. |
| Pull request | g p |
— | Dedicated PR action panel: header, checks table, reviews summary, body preview. Action keys: m merge, x close, a approve, R request changes, c comment, O open in browser. |
| Conflicts | g x |
— | Conflict resolution helper, available during merge / rebase / cherry-pick / revert. Per-row keys s stage / u theirs / U ours / o edit / C continue. |
| Reflog | g r |
— | Chronological recovery log — every HEAD movement (commit, checkout, merge, reset, …) with relative time, action, hash, and message. Enter drills into the diff for the entry's hash. |
| Bisect | g B |
— | Bisect workflow surface. Shows the current candidate, the parsed decision log, and the action keys: g good / b bad / s skip / x reset. The title bar shows a BISECTING badge whenever a bisect is in progress. |
The --view flag accepts history, status, or diff for the historical command-line surface. The other views are reached interactively via chords or by pressing Enter on a contextual selection.
History mode starts in compact graph mode. Press \ to toggle to full graph mode when you want higher topology fidelity — pattern junctions (├╮ / ├╯), per-lane coloring, distinct merge / HEAD glyphs (◆ / ◉), and graph continuation rows.
Diff any two refs (branches, tags, or commits) without leaving the workstation. The flow:
- From branches, tags, or history, press
mon a row to mark the cursored ref as the compare base. The status banner sticks ("Compare base: <label> — press enter on another ref to diff") and the footer adapts to showenter compare · m clear. - Navigate to a second ref on any of those three views.
- Press
Enterto push the diff view incomparemode (git diff <base>..<head>). -
<orEscpops the diff and clears the base automatically.
m again on the same ref toggles the base off without leaving the view. Outside the compare flow, m is unbound on those views.
coco ui shares a chord-driven navigation model with coco log -i. Press g and then a second key to jump anywhere; < or Esc pops the navigation stack to where you came from.
g h history g c compose g b branches g t tags g w worktrees
g s status g d diff g z stash g p PR g x conflicts
g r reflog g B bisect < back
Selection state per view is preserved across navigation, and a ›-separated breadcrumb in the header shows your current path.
For the full navigation reference — chord rules, contextual transitions (Enter on a commit, e/c from status), the interactive command palette (:), the / global search across views, the help overlay, the per-context [/] and ←/→ keys, theming, and accessibility — see TUI Navigation.
In status view:
- Files render under
▾ Staged (n)/▾ Unstaged (n)/▾ Untracked (n)headers in canonical order. -
j/kor arrows move through files within the active group. -
←/→jumps between groups (lands on the group's first file). -
↑at the first file of a group promotes the cursor onto the group header.↓from the header re-enters the group. -
Enteron a file opens the diff.Enteron a group header fires the batch action:Unstage all staged files,Stage all unstaged files, orStage all untracked files(the last requires y-confirm). -
Spacestages or unstages the selected file. -
zasks to revert the selected file. Pressyto confirm orn/Escto cancel. -
1/2/3toggle the staged / unstaged / untracked visibility mask.
In diff view:
-
j/kmove between hunks. -
PageUp/PageDownscroll the diff. -
Spacestages or unstages the selected hunk. -
zasks to revert the selected hunk. Pressyto confirm orn/Escto cancel. -
[/]jumps between hunks (or files in stash diffs). -
Escor<pops the navigation stack so you return to whichever view pushed diff (status or history).
Stash diffs render multiple files in one scrolling stream. Each diff --git row paints as a compact ▾ <path> header (> <path> in ASCII mode), and the file the cursor is currently scrolled inside gets selection styling so the active context is always visible.
Real diffs stay in the main panel so long diffs do not overflow the right dock. The right dock stays focused on metadata and commit actions.
Status and diff views show a commit box in the right dock.
| Key | Action |
|---|---|
e |
Edit the commit summary/body fields. |
Tab |
Switch fields while editing. |
Enter |
Move from summary to body, or finish body editing. |
Ctrl+U |
Clear the active field while editing. |
Esc |
Leave edit mode. |
c |
Commit staged changes with the current draft. |
I |
Ask for an AI commit draft after explicit confirmation. |
Manual commits require staged changes and a non-empty summary. Hook failures are shown in the TUI status/commit feedback instead of breaking terminal state.
AI drafts are opt-in. Pressing I shows a confirmation panel with an estimated token impact before Coco calls a provider. Confirmed AI drafts populate editable summary/body fields; they do not commit automatically.
For the navigation model (chords, back, palette, search, help, breadcrumb, themes, context-routed [/] and ←/→), see TUI Navigation. The keys below are specific to the surfaces coco ui exposes — they're available alongside the global navigation set.
| Key | Action |
|---|---|
j / k, arrows |
Move selection in the active list |
PageUp / PageDown
|
Scroll history / detail / diff |
G |
Jump to last visible commit |
n / N
|
Next or previous visible search result |
[ / ]
|
Previous or next sidebar tab (sidebar focused) / inspector tab (inspector focused, short terminals) / diff hunk or file (diff view) |
← / →
|
Switch sidebar tabs (sidebar focused) |
1–5
|
Jump to sidebar tab |
Enter |
Open the diff for the selected commit (history) or file (status), checkout (branches), open diff (stash), drill in (sidebar tab) |
Space |
Stage/unstage the selected file or hunk (status/diff) |
z |
Revert the selected file or hunk after confirmation |
y / Y
|
Yank cursored identifier (commit hash, branch, tag, stash ref, file path) to the system clipboard |
O |
Open the cursored entity in the browser (commit on history; PR / repo elsewhere) |
r |
Refresh repository context |
History view actions all route through y-confirm or a mode prompt — none fire silently from the keystroke.
| Key | Action |
|---|---|
c |
Cherry-pick the cursored commit |
R |
Revert the cursored commit (git revert --no-edit) |
Z |
Reset to the cursored commit. Opens a soft / mixed / hard mode prompt; recovery instructions surface in the status line for --hard. |
i |
Start an interactive rebase from the cursored commit's parent (git rebase -i <sha>^). Lowercase i so the global I ai-commit-summary stays reachable. |
B |
Create a branch rooted at the cursored commit (git branch <name> <sha>). Prompts for the name; HEAD stays put. |
gT |
Create a lightweight tag at the cursored commit (git tag <name> <sha>). |
| Key | Action |
|---|---|
d |
Toggle between unified and side-by-side rendering. Persists per-repo. Falls back to unified on terminals narrower than 120 cols. |
Space |
Stage/unstage the cursored hunk (worktree diff). |
z |
Revert the cursored hunk (worktree diff). |
c |
Cherry-pick the cursored file from a commit-diff or stash-diff explore. |
H |
Apply the cursored hunk to the worktree (git apply). |
gH |
Apply the cursored hunk to the index (git apply --cached). |
[ / ]
|
Jump to previous / next hunk (or file in stash-diff). |
Reachable via g p. Each action routes through a confirmation gate or an input prompt.
| Key | Action |
|---|---|
m |
Merge the PR. Prompts for merge / squash / rebase, then y-confirms. |
x |
Close the PR (without merging). |
a |
Approve the PR. |
R |
Request changes. Opens a multi-line review-body prompt (Enter inserts a newline; Ctrl+D submits). |
c |
Comment on the PR. Multi-line prompt as above. |
O |
Open the PR in the browser. |
When the sidebar is focused (via tab or by opening it directly), navigation runs on two axes plus an "escape upward" to the active tab's title:
┌─ Status (3) ──┐
│ Branches (12)│ ←/→ between tab titles
│ Tags (4) │ (header focus carries
│ Stashes (1) │ across switches)
└─ Worktrees (2)┘
↑↓
──────────────
[Branches (12)] ← Header is its own cursor target.
↑ from item index 0 lands here.
Enter drills to the dedicated view (`g b`).
──────────────
* main ← Items list. ↑/↓ navigates;
feat/x Enter performs per-entity action;
feat/y ↓ from header re-enters here.
| Key | Action |
|---|---|
← / →
|
Switch between sidebar tabs (Status / Branches / Tags / Stashes / Worktrees). Header focus carries across switches. |
↑ / ↓, j / k
|
Navigate items within the active tab's list. ↑ at index 0 promotes the cursor onto the active tab's header. |
Enter (on items) |
Per-entity primary action — checkout for branches, open diff for stashes, drill into the dedicated view for tabs without a primary action. |
Enter (on header) |
Drill into the dedicated view for the active tab (g b / g t / g z / g w / g s) regardless of items. |
D / R / u / +P / F
|
Branches: delete / rename / set-upstream / push / fetch |
a / p / X
|
Stashes: apply / pop / drop |
T / P
|
Tags: delete / push |
W |
Worktrees: remove |
The cursor only ever appears in one place. When the header is focused, the items render without their selection highlight; when an item is focused, the header renders as the normal active title. The per-entity ops fire via the same dispatch as the dedicated views, so muscle memory carries across.
When focused (via tab), the inspector expands to ~40% of width. Two tabs share the panel: [Inspector] shows commit metadata and the changed-file list; [Actions] shows the per-entity action cheat-sheet and is itself a cursor-navigable list.
| Key | Action |
|---|---|
[ / ]
|
Toggle between [Inspector] and [Actions] tabs |
↑ / ↓ (Inspector tab) |
Move the file-list cursor |
↑ / ↓ (Actions tab) |
Move the cursor through the action list |
Enter (Inspector tab) |
Open the diff for the cursored file |
Enter (Actions tab) |
Fire the cursored action (cherry-pick / revert / reset / yank / open in browser, etc.) |
The Actions tab dispatches the same events the matching keystroke would fire, so the action list stays in sync with the keyboard. The active row gets the same selection styling sidebar headers and status group headers use, so the visual cue is consistent across surfaces.
| Key | Action |
|---|---|
e |
Edit commit compose fields (also pushes compose if you're elsewhere) |
c |
Commit staged changes (also pushes compose first so the result lands in view) |
Tab |
Switch summary/body fields while editing |
Enter (in editor) |
Move from summary to body, or finish body editing |
Ctrl+U (in editor) |
Clear the active field |
Esc (in editor) |
Leave edit mode |
I |
Confirm and generate an AI commit draft |
Most prompts are single-line (Enter submits). Two are multi-line: pr-comment and pr-request-changes. In multi-line mode:
| Key | Action |
|---|---|
Enter |
Insert a newline (does not submit) |
Ctrl+D |
Submit |
Esc |
Cancel |
Backspace |
Delete the previous character (including newlines) |
Ctrl+U |
Clear the entire buffer |
D (delete branch), T (delete tag), X (drop stash), W (remove worktree), A (abort operation), M (AI conflict help), and C (create PR) launch workflow actions, gated behind confirmation prompts where destructive. All workflow actions are also reachable from the command palette (:).
| GitKraken concept | Coco UI equivalent | Notes |
|---|---|---|
| Commit graph | History view with \ toggle for full graph mode |
Pattern junctions (├╮ / ├╯), per-lane coloring, distinct merge / HEAD glyphs (◆ / ◉) |
| File tree / changes panel | Status view (g s) |
Stage with Space, revert with z, navigate hunks in diff view |
| Diff view | Dedicated diff view (g d) with d to toggle unified ↔ side-by-side |
120-col fallback to unified on narrow terminals |
| Stage file / hunk |
Space in status / diff |
Hunk-level apply via H (worktree) / gH (index) on commit-diff and stash-diff explores |
| Commit panel | Right-dock commit compose (g c) |
Edit / commit / AI draft inline; multi-line input prompt for free-form text |
| AI commit summary |
I confirmed draft action |
Token cost shown before the call; cancellable from the prompt |
| PR / provider panel | Dedicated pull-request view (g p) |
Header, checks table, reviews summary, body preview; m merge / x close / a approve / R request changes / c comment |
| Right-click commit menu | Inspector Actions: section + per-key bindings on history view |
c cherry-pick, R revert, Z reset (mode prompt), i interactive rebase, B create branch here, gT create tag here, O open in browser |
| Branches sidebar |
g b view + sidebar Branches tab |
Current branch pinned at row 0; ≡ synced / ↕ diverged / ◌ no upstream / * current markers; relative timestamps |
| Stash list |
g z view + sidebar Stashes tab |
Enter opens diff; a apply, p pop, X drop |
| Worktrees |
g w view + sidebar Worktrees tab |
W remove (current worktree refused) |
Use this checklist when validating changes to the TUI:
- Clean repo:
coco ui - Dirty repo with staged, unstaged, and untracked files:
coco ui --view status - Long diff file: open status, press
Enter, scroll withPageDown - Hunk flow: press
j/k,Space, then refresh/status check - Revert safety: press
z, cancel withnandEsc, then confirm only on disposable changes - Commit compose: edit summary/body with
e, commit staged changes withc - AI draft: press
I, cancel once, then confirm in a test repo/provider setup - Narrow terminal: verify minimum-size messaging
- Wide terminal: verify panels remain stable
NO_COLOR=1 coco ui- Non-TTY fallback:
coco ui < /dev/null
- The UI does not open: verify the command is running in a real TTY.
-
Colors look wrong: try
NO_COLOR=1 coco uior setlogTui.theme.presettomonochrome. - A commit is blocked by hooks: the commit box shows hook output. Fix or restage the affected files, then commit again.
-
AI draft is not running: AI calls require explicit
Iconfirmation and a configured provider.
Plain coco log --format table and coco log --format json remain the stable interfaces for scripts.