gilvt
English · 简体中文
macOS · Rust + gpui · for Claude Code and Codex

gilvt: a terminal that knows what your agents are doing

A complete native macOS terminal. Claude Code and Codex run in its panes with their own native interfaces as usual, while gilvt tells you alongside who is waiting for you and what each turn did, takes you there in one step, and brings back past sessions in one step.

Needs you (awaiting approval / asking you) Error Running Done, unseen
Part 1 · Introduction

What gilvt is

With three or four Claude Code and Codex sessions open at once, the hard part is not writing code. It is knowing which session has stopped to wait for your approval, which one just finished with failing tests, and which one is done and waiting for you to look at the result. An ordinary terminal only gives you grids of text, so you end up flipping through the tabs one by one.

gilvt is first of all a complete, normally interactive terminal that you can use every day. On top of that, it understands the runtime state of Claude Code and Codex:

  • The left sidebar lists all sessions in one place, with the ones marked “Needs you” at the top; ⌘⇧J takes you there in one keystroke.
  • Pane borders and tab dots show each session’s state by color, so you do not have to switch over to check.
  • The inspector on the right lists, turn by turn, every command the Agent ran and every file it changed this turn; click one and the terminal scrolls back to that line.
  • System notifications and the Dock badge alert you while you are in another app.
  • ⌘⇧R brings back a session from days ago so you can pick up where you left off, and ⌘⇧N starts a new Agent in a chosen directory in one step.
  • Quick Look shows code diffs, rendered Markdown and Mermaid diagrams right inside the terminal, without switching to an editor.

Design principles

The Agent is always its native TUI

In a pane, Claude Code and Codex are their own interfaces. gilvt does not build a separate chat interface and does not provide approval buttons.

Observe, never answer for you

The inspector and the sidebar only display and navigate; they never send a single keystroke to the Agent. You approve and answer questions yourself, in the Agent’s own interface.

Your configuration stays untouched

Shell integration and hooks are injected through launch arguments and temporary files. Not a single character of your rc files, ~/.claude or ~/.codex is changed.

Problems never break the terminal

If parsing an Agent’s records fails or a hook does not take effect, gilvt falls back to “Lite mode” or a plain terminal, and input and output keep working.

Features at a glance

AreaWhat it doesEntry point
Core terminalTabs, splits, true color, Kitty keyboard protocol, IME input (e.g. Chinese), find, 100,000 lines of scrollback⌘T ⌘D ⌘F
File previewCode highlighting and diffs, rendered Markdown with change markers, Mermaid diagrams, pinning as a live-refreshing pane⌘+click a path, gilvt view
Finding filesFuzzy search within the repository, dropping files in from Finder⌘P, drag and drop
Session overviewAll Agent sessions, their state, how long they have waited, context usageSidebar ⌘B
MonitorGlobal activity view: Agent sessions and terminals from every window laid out as cards, grouped by state, expandable to catch up; a command bar at the bottom of any tab lets you ask questions at any time⌘⇧O / ⌘⇧M
Execution processStatus card, TODO, timeline, the key error lines of failed commands, jumping back to the terminalInspector ⌘I
Agent configurationThe current session’s model, permissions, MCP, Hooks, extensions, memory and sources, read-only and redacted⌥⌘3
AlertsSystem notifications, Dock badge and bounce, ⌘⇧J to cycle through sessions waiting for youAutomatic
Session managementSearch, resume, rename, archive and clean up (move to Trash) past sessions; cleanup wizard⌘⇧R, ⌘⇧K
New AgentPick the Agent, directory, initial task, model and permission mode, optionally run it in a new git worktree, and start it in one step⌘⇧N
Themes725 built-in themes plus custom themes, one each for light and dark; window chrome and status colors follow the theme⌘, → “Appearance”
Built-in editorEdit Skills, commands or any text file with syntax highlighting, never losing content silently; live preview (Markdown / Mermaid / SVG / changes)E / ⌘O, ⌘⇧+click, ⌘⇧V
Restore after restartRestores windows, tabs, splits and directories after quitting or a crash; Agent sessions are listed as “Pending resume” for you to resume with one clickAutomatic
Git awarenessThe sidebar shows each session’s branch, change count and ahead / behind; worktrees of the same repository are grouped into one projectAutomatic
Close protectionAsks for confirmation before closing a pane, tab or window, or quitting, when that would interrupt an AgentAutomatic

Current version

Completed milestones: M1 core terminal; M2a–M2c preview and file finding; M3a–M3d Agent state, execution process, session management and offline Review; M4a artifacts (per-turn file changes and the “This turn” diff); M5a read-only configuration summary. Also available: workspace persistence, git and worktree awareness, close confirmation (P0); session archiving, deletion together with companion data, the cleanup wizard and run-directory display; terminal rows in the sidebar; the Monitor (S1: global activity view; S2 phase 1: ✦ AI Summary; phase 2: the ⌘, settings window; phase 3: read-only chat; phase 4: the bottom command bar); the built-in editor (with syntax highlighting and live preview); Codex subagents and background terminals shown in the timeline. M4b (seen state, diff range switching) and M5b (configuration editing and safe write-back) are not available yet (the Monitor’s [monitor] table can already be changed in the settings window and safely written back).

M1 ✓ · M2a ✓ · M2b ✓ · M2c ✓ · M3a ✓ · M3b ✓ · M3c ✓ · M3d ✓ · M4a Artifacts ✓ · M5a Configuration summary ✓ · M4b / M5b to do

Part 2 · User guide

Install and launch

You need macOS, Rust 1.95 (selected automatically by the repository’s rust-toolchain.toml) and the Xcode Command Line Tools; the full Xcode is not required.

  1. Build and bundle Gilvt.app. Native system notifications and the Dock badge require launching from the app. Build in a directory outside /tmp; macOS ignores apps under /tmp.
    cd gilvt
    scripts/bundle.sh            # or scripts/bundle.sh release
    open target/debug/Gilvt.app
  2. Set up stable signing first (recommended). Follow “Stable signing” in HACKING.md to create a self-signed gilvt-dev certificate; scripts/bundle.sh signs with it automatically. Otherwise, after every rebuild you may have to grant system permissions such as notifications and screen recording again.
  3. Allow notifications. The first time a session needs you, macOS asks whether gilvt may send notifications. Choose Allow; you can change it later in “System Settings → Notifications → gilvt”. The Dock badge also depends on this switch.
  4. Use it as usual. Run claude or codex directly in a pane; its state appears automatically in the sidebar and the inspector, with no extra setup.

If you only want to try it out, you can also run the debug build directly: cargo build --workspace && ./target/debug/gilvt-app. In that case notifications go through osascript, have no sound, and clicking them cannot take you back to the pane.

When installing from the download, drag Gilvt into the Applications folder before opening it. If you open it straight from the dmg window or from Downloads, gilvt shows a banner saying it is running from a temporary location: macOS then runs a random read-only copy, so later updates and the hooks written by gilvt integrate install would stop working. Click “Move to Applications” on the banner and gilvt copies itself to /Applications (~/Applications when that is not writable) and reopens from there; an older copy already there goes to the Trash first. “Not Now” hides the banner for this run only.

Updates

The downloaded gilvt updates itself. By default it checks release.gilvt.com in the background, downloads a new version when there is one, and installs it when you quit gilvt: the swap happens after gilvt has exited, so running agents are never cut off by an update. While a downloaded update is waiting, the bottom of the sidebar says “gilvt X is ready and installs when you quit · Quit now”. “Check for Updates…” in the app menu (after Settings…) checks right away and shows the result.

[update] mode in config.toml picks the behavior: download (default), check (only checks; a window asks before anything is downloaded) or off (never checks; turning it back on needs a restart). Updates are signed with gilvt’s EdDSA key and notarized by Apple; the check sends no identifiers (see PRIVACY.md). Builds from source have no updater.

Layout and basics

The gilvt window has three columns: the session overview on the left, terminal tabs and splits in the middle, and the inspector on the right. ⌘B and ⌘I collapse the two sides; with both collapsed, it is a plain terminal.

Tabs and splits

⌘T / ⌘NNew tab / new window
⌘,Settings window (“Appearance” themes, “Monitor”)
⌘D / ⌘⇧DSplit right / down
⌘⌥←↑→↓Move pane focus
⌘⌃←↑→↓Resize the pane; you can also drag the divider
⌘⇧⏎Maximize / restore the current pane
⌘⇧TMove the current pane to a new tab; press it again in that tab to put the pane back into its split
⌘W / ⌘⇧WClose pane / close tab

Shell integration

zsh, bash and fish in a new pane load gilvt’s hook: it reports the current directory (new panes inheriting the directory and relative path detection both depend on it) and marks prompts and command boundaries. Your own rc files load as usual and are never modified. If you do not want it, set shell_integration = false in the configuration.

Clicking paths and links

⌘-clicking a file path in terminal output (including forms with line and column such as src/main.rs:42:7) opens it in Quick Look at that position; ⌘⇧+click opens it in the built-in editor (see “Built-in editor” below). Only files that actually exist are recognized. ⌘+clicking an http / https / mailto link opens it in the browser.

Restoring your workspace after a restart

Every second, gilvt saves the windows, tabs, split directions and ratios, each pane’s directory, and window positions and sizes to ~/Library/Application Support/gilvt/state/workspace.json (it writes only when something changed). When you reopen after quitting with ⌘Q, a crash or a force quit, the layout returns to its state from the last second or two. Things to know:

  • Agents do not start automatically. After a restart, every pane is a plain shell; panes that were running an Agent are listed in the sidebar under “Needs you” as “Pending resume · N”. Click a row and gilvt types cd <directory> && claude --resume <id> into its original pane (for Codex, codex resume <id>); “Resume All” resumes one about every 0.5 seconds. If you start an Agent in that pane yourself, the session actually detected wins and the “Pending resume” mark disappears automatically.
  • If a pane’s directory has been deleted, that pane starts in your home directory instead, and the top of the window says “Directory … no longer exists; the pane was started in the home directory”.
  • If workspace.json is corrupted, gilvt starts blank, saves the original file as workspace.json.bad, and then saves new layouts normally.
  • Deliberately closing the last window (rather than ⌘Q) counts as “don’t keep this”, so the next launch opens a blank window.
  • Built-in editor panes and Quick Look previews are not restored.

Close confirmation

When what you are closing contains an Agent that is thinking, running a tool, awaiting approval or asking you something, ⌘W (pane), ⌘⇧W (tab), closing a window and ⌘Q all show a confirmation bar first, listing the affected sessions and their states; ⌘Q combines the sessions of all windows into one bar. The default is to cancel (↩ or Esc); only ⌘↩ means “Close Anyway”. Idle, ended and errored Agents and plain shells close right away. After “Close Anyway” the sessions remain in history, and ⌘⇧R can resume them so you can continue the conversation.

Quick Look preview

Quick Look is a preview overlay on top of the terminal area; the terminal keeps updating in the background. In a git repository it shows changes against HEAD by default: syntax highlighting, word-level diff, and unchanged lines folded. Press ⏎ to pin it as a split pane that refreshes automatically when the file is saved. When a split is too narrow to read comfortably, drag the title bar of the pinned pane (or an editor pane) onto the tab bar and drop it, and it moves into a new tab of its own; pressing T in a pinned preview does the same. In the new tab, Esc or ⌘W closes it and returns you to the original tab.

KeyAction
j k / ↑ ↓, ⌃D ⌃U, g GScroll
n / pNext / previous change hunk
← / →Switch between files of the same batch
UUnified / side-by-side view (chosen automatically by width by default)
DSwitch the comparison base: against HEAD (or a given branch) / file only
RReload (the overlay tells you when the file has changed)
⏎Pin as a split pane
TOpen in a new tab (in a pinned preview: move it from the split to a new tab)
E / ⌘OOpen in the built-in editor (hold ⌥ to flip split / new tab)
⌘⌥OOpen at the current line in an external editor (VS Code when code is available)
Esc / SpaceClose
Text in the preview cannot be selected and copied yet. To copy, press E to open the file in the built-in editor, or cat it in the terminal and use the terminal’s selection. This is on the plan for a later version.

Built-in editor

gilvt comes with a general-purpose text editor, so you no longer have to switch to another app to edit a Skill, a command or any other text file.

Opening it. In the Configuration tab, click “View ›” for Skills / commands / subagents, and hover over a row to reveal its “Edit” button; press E (or ⌘O) in a Quick Look preview; or ⌘⇧+click a path in terminal output. If the file is already open in an editor pane, opening it again only focuses that pane instead of opening a duplicate.

Split or new tab. By default it opens as a split to the right of the current terminal pane, so the terminal stays visible. If the current tab already has 3 or more panes, or either side would end up narrower than 60 columns after splitting, it opens in a new tab instead; closing that tab takes you back to the tab you came from. Hold ⌥ (when clicking “Edit” or with ⌥E) to flip this choice.

Editing and saving. Long lines wrap automatically, with the line-number gutter left blank on continuation lines; IME input (e.g. Chinese), mouse selection, undo/redo and Tab / ⇧Tab indentation are supported. ⌘S (or “Save” in the header) saves; while there are unsaved changes, the header and its tab show ●. ⌘⌥O opens the file on disk in an external editor instead (without saving).

KeyAction
⌘SSave
⌘Z / ⇧⌘ZUndo / redo
⌘C / ⌘X / ⌘V / ⌘ACopy / cut / paste / select all
⌘WClose the editor pane
Tab / ⇧TabIndent / outdent
⌥⌫Delete by word
Home / EndFirst to the start / end of the display line, then, pressed again, to the start / end of the whole line

Content is never lost. If, when you save, the file has been changed on disk by another program, a “file was modified on disk” banner appears (Reload / Compare / Overwrite Anyway) instead of silently overwriting. Closing a pane or tab with unsaved content asks whether to save, not save, or cancel; closing a window or pressing ⌘Q lists all unsaved files, where ↩ is “Save All and Close”, Esc cancels, and ⌘↩ closes without saving.

The file changed on disk. An editor pane keeps an eye on its file (for example, when an Agent is editing the same Skill). With no unsaved changes, the new content loads silently and the left side of the status bar briefly flashes “Updated”. With unsaved changes, a yellow banner appears below the header: “The file was modified on disk while you have unsaved changes.”:

  • Reload: replaces the editor content with the disk content. This is a single undoable edit; ⌘Z brings your version back.
  • Compare: opens the compare overlay (see below).
  • Overwrite Anyway: overwrites the disk with your version.
  • Esc only dismisses the banner; a later ⌘S is still stopped, so nothing is quietly overwritten.

When the file has been deleted or moved, the banner reads “The file was deleted or moved.”: Save (re-create) / Close / Dismiss.

The compare overlay. Disk Version on the left, Your Version on the right (merged into a top-to-bottom unified diff when the window is narrow); deleted lines have a red background, added lines a green one, and long unchanged stretches fold into one line that expands on click. If only line endings or encoding differ, it says the content is identical. The overlay reads the disk once when it opens and does not follow later changes. The three buttons at the bottom: Use Disk Version (same as “Reload”, undoable), Keep Mine for Now (only closes the overlay; the banner stays), and Overwrite Disk Anyway (red). Esc returns to editing. This is a text comparison; there is no three-way merge.

Changing encoding, opening read-only. The encoding in the status bar is clickable (for example “GBK ▾”). The menu offers UTF-8, UTF-8 (with BOM), UTF-16 LE / BE, GBK, Shift_JIS, EUC-KR, Big5, windows-1252 and gb18030; picking one rereads the file with it, and the current one is checked ✓. With unsaved changes, it first asks “Discard Changes and Reopen”. The last menu item toggles between “Open as Read Only” and “Open as Editable”; when the file is not writable, or decoding had to replace characters, “Open as Editable” is grayed out. Only an encoding that re-encodes to exactly the file’s bytes can be edited; otherwise the file is read-only, unrepresentable characters show as replacement symbols, and the header is marked “Read only · some characters replaced”.

Rejected files in legacy encodings. When a file is rejected because “the legacy encoding cannot be written back unchanged”, the red banner gains two buttons: “Choose Encoding…” and “Open as Read Only”. Both first open the file read-only in the guessed encoding; the former then pops up the encoding menu, and once you pick an encoding that writes back unchanged, you can edit.

Mixed line endings. When a file mixes several line endings such as LF and CRLF, the line-ending indicator in the status bar shows an amber “LF · Mixed” (saving unifies to this one). Click it to choose LF / CRLF / CR; on save the whole file is written with the chosen line ending. If the file was originally mixed, or the choice differs from the current one, the header shows ● until you save; choosing the current one on a uniform file does not make it dirty. Read-only files cannot change line endings.

Syntax highlighting. Text is colored by file type (Rust, Markdown (including leading YAML front matter), TOML, JSON, Shell and other common languages; colors follow the terminal palette and the light / dark theme). Plain text is not colored and the status bar says “Plain Text”; large files (over 2 MiB or 50,000 lines) are not colored either, and the status bar appends “(not highlighted)” to the language name. Code blocks in Markdown use the code color as a whole and are not colored again by the fence’s language.

Live preview. “Preview ⌘⇧V” in the editor pane header (or just ⌘⇧V) opens a preview pane to the right of the editor pane showing what you are editing, unsaved changes included; it refreshes about 0.2 seconds after you stop typing, and pressing ⌘⇧V again closes it. The preview is read-only; closing either side closes the other, and it is not restored after a restart.

File being editedAvailable previews (the first is the default)
.md / .markdownRendered document (with Mermaid diagrams and local images) · Changes
.mmd / .mermaidRendered diagram · Changes
.svgImage · Changes
Other text filesChanges: the unsaved content compared with the version on disk

With the preview open, the header button reads “Preview: Rendered”, “Preview: Diagram”, “Preview: Image” or “Preview: Changes”; click it to cycle to the next available preview, and when only one is available, clicking it closes the preview. gilvt remembers your choice for each file type. When you scroll the editor or move the cursor, the preview follows to the position matching the editor’s top line (the editor drives the preview, not the other way round). When Mermaid has an error, the source and the error message are shown right in the preview, as in Quick Look; an SVG that cannot be parsed shows “Could not read image”. The “Changes” preview compares against the version on disk at your last edit or save and does not watch the file. For very large files (over 2 MiB or 50,000 lines), the preview is built once when it opens and immediately says “File too large for live preview · updates on save”; after that, typing updates it only when you save. The preview does not respond to Quick Look’s D, S, dropped files or file-link navigation; press Esc to return to the editor.

Files that cannot be edited. Binary files, files over 64 MB, and files in legacy encodings that cannot be written back unchanged are not opened for editing; instead, a red banner at the top of the window explains why, and you can use the preview or an external editor. Files without write permission open read-only; files containing an extremely long line of more than 200,000 characters also open read-only.

Known limitations: in an editor pane, ⌘⇧↑ / ⌘⇧↓ still switch sessions, so you cannot select to the start / end of the document in one keystroke; editor panes are not restored after a restart; there is no find and replace yet.

Markdown and Mermaid

In Quick Look, .md files are shown as a rendered document by default: body text in a proportional font, code and table numbers in a monospaced font. Changes against the comparison base are marked by block: a green bar on the left for added blocks, a yellow bar for modified blocks, and fully deleted passages shown as “Deleted N lines · click to expand”.

  • S switches between the rendered view and the source diff view, keeping your position.
  • Relative links to local files open in the same Quick Look, and ⌘[ goes back; external links open in the browser.
  • Local images are shown at reading width; remote images show only their address and are not loaded.
  • Mermaid diagrams render offline in the background without requesting any network resources; on a syntax error, the source and the error message are shown, and R retries.

⌘P and dropping files

⌘P file search

Press ⌘P in a terminal pane to search all files of the git repository that pane is in (respecting .gitignore); outside a repository it searches the current directory. Files with uncommitted changes, files under the current directory and recently previewed files rank first. The query syntax is the same as fzf: separate several terms with spaces, anchor with ^ / $, match exactly with ', exclude with !.

⏎Quick Look preview
⌘⏎Pin as a pane on the right
⌥⏎Insert the path (escaped by shell rules) into the command line without running it

Dropping from Finder

Drag a file from Finder onto a pane: when claude / codex is in the foreground, the path is inserted so the Agent can read it as an attachment; for other programs, it opens in a Quick Look preview by default. Hold ⌥ when you let go to get the other behavior. While you drag, the pane shows what will happen when you drop.

The gilvt command line

Every pane has a gilvt command on its PATH; use it to open previews from the command line:

gilvt view src/main.rs:42          # open and jump to line 42
gilvt view --pin README.md         # pin as a preview pane on the right; refreshes on save
git show HEAD:a.rs | gilvt view --as rs -   # preview standard input
gilvt diff                         # preview every file changed against HEAD, one by one (←→ to switch)
gilvt diff main                    # against the main branch

When run in another terminal app, gilvt prints the content directly, with color.

Agent sessions

Once you run claude or codex in a pane (including scripts like codex-w that end up executing codex), gilvt recognizes it automatically and gets its state in real time through injected hooks. Everything happens in the background; you keep working in the Agent’s interface as usual.

Session states

Needs youAwaiting approval or asking you. Yellow border, listed at the top of the sidebar.
ErrorAPI errors and the like. Red border.
RunningThinking or running a tool. No border; the tab dot is blue.
Done, unseenThe turn ended and you have not looked yet. Green border, cleared on focus.

The sidebar

  • Needs you: sessions awaiting approval / asking you, longest wait first.
  • Pending resume: sessions not yet resumed after a restart (see “Restoring your workspace after a restart”); click a row to resume it, or “Resume All” to resume them all at once.
  • All Sessions: grouped by project (the git root directory name) by default, switchable to grouping by status; groups where everything is idle collapse automatically. A repository’s main checkout and its linked worktrees count as the same project.
  • Terminal rows: terminal panes not running an Agent also appear in the sidebar as gray rows (the header reads “Sessions · N · Terminals M”); click one to jump to that pane. They never go into “Needs you”, and ⌘⇧↑ / ⌘⇧↓ skip them. When grouped by status, they go into the “Terminals” group at the end, collapsed by default. When the Agent in a pane exits, its row turns back into a terminal row.
  • Ended: sessions that ended during this run, collapsed by default. Double-click to resume; right-click to resume or move to Trash.
  • Each row shows: the Agent icon (C = Claude, X = Codex), the session name (see the naming rules in “Resume and manage sessions”), the time, the current action (such as ⏳ Awaiting approval · Bash(rm -rf build)), the location (tab · left / right) and a thin context-usage bar (yellow at ≥ 80%, red at ≥ 90%).
  • Git line: when the session’s directory is a git repository, the row gets an extra line ⎇ main; with uncommitted changes it shows their count (⎇ main ●2), and with an upstream it shows ahead / behind (⎇ main ●1 ↑1↓0); a detached HEAD shows the short commit; inside a linked worktree, the worktree’s directory name is added as a prefix. Refreshes about every 10 seconds. Directories that are not git repositories have no such line.
  • Long text: long session names wrap onto two lines and long status lines are truncated with an ellipsis; hover for about 0.5 seconds to see the full name, status, location and cwd.
  • Click a row to jump to that pane; right-click to rename, mute notifications or copy the session ID.

Jumping between sessions

⌘⇧JCycle through the “Needs you” sessions by how long they have waited
⌘⇧↑ / ⌘⇧↓Previous / next session in sidebar order
Clicking a sidebar row or a system notificationJumps to that pane with focus in the Agent’s interface, ready for typing

Lite mode

When hooks do not take effect (for example with claude --bare, or when Codex has hooks turned off), gilvt infers the state by reading the session records instead, and the sidebar marks the session “Lite mode”. Approvals and questions are not visible in this mode; everything else works as usual.

Inspector: Process

The inspector on the right follows the focused pane and shows what this session did in each turn. It only displays and navigates; it has no approval or input buttons at all.

  • Status card: state and current action, turn number and time spent this turn, context usage, model and permission mode, and token counts for this turn and the session.
  • Waiting banner: appears at the top when another session is waiting for you; clicking it is the same as ⌘⇧J.
  • TODO: from Claude’s TodoWrite or Codex’s update_plan; completed items are struck through, the one in progress is bold.
  • Timeline: one event per line, filterable by All / Bash / Edit / Failed. Failed commands show their key error lines directly (up to 3 lines); edits carry +N −M; subagents are nested under a purple vertical line. The gray time after the heading is when the turn started.
  • Codex subagents and background terminals: subagents appear as purple process rows; a long-running terminal command stays on a single row, and later wait / write_stdin calls only update it instead of adding rows.
  • Jump back to the terminal: click a row and the terminal scrolls to where that command appears in the terminal, briefly highlighted; ⌘+click a file name to open that file in Quick Look.
  • Earlier turns: below the current turn are the previous turns, one row each (with start time and duration); click to expand.

The inspector width can be dragged (240–560 px). ⌥⌘1, ⌥⌘2 and ⌥⌘3 switch to “Process”, “Artifacts” and “Configuration”.

Inspector: Artifacts

⌥⌘2 switches to the “Artifacts” tab. It lists, task by task, which files this session changed: one card per task, newest at the top; at the top is the summary “▸ Net changes in this session · N files +a −b”.

  • Card = task: each prompt starts a task; short replies that immediately follow it, such as “continue / sounds good / ok”, are merged into it. The title is “start time · first sentence of the prompt”, with a small line below reading “Turns n–m · k follow-ups”, and on the right “N files +a −b · duration”. Files and line counts are the net changes of the whole task (before the first turn → after the last turn), shown as “Calculating” until computed. The card holds the file list (M modified, A added, D deleted, R renamed, plus +a −b), the test or build result (recognizes go test, npm test, pnpm test, pytest, cargo test and make test; with several runs the last one counts; ✓ passed, ✗ failed with the exit code) and the first sentence of the Agent’s last reply (a gray quote).
  • Turn in progress: dashed border; the file list updates live with the working tree. With more than 8 files only the first 8 are shown, and the rest can be viewed grouped by directory.
  • Tasks with no changes: consecutive ones fold into a single row “▸ N turns with no file changes · titles, …”; click to see them one by one.
  • Net changes in this session: the summary row at the top expands to list the net changes from before the first turn to after the latest turn, counting only files the Agent changed; other files you changed yourself between turns are not counted, but their number is noted. When a session has worked in several repositories in turn, only the most recent repository is counted, noted as “Only counting repository name”.
  • “Changed later · Turn n”: a file this task changed was changed again in a later turn; the card marks which turn.
  • Keyboard: ↑ ↓ move between cards and file rows; ⏎ expands or collapses on cards, the summary row and folded rows, and on a file row, like Space, shows the selected file’s diff in Quick Look (labeled “This turn (Turn n before → after)”, “This task (before Turn a → after Turn b)” or “This session (before Turn a → after Turn b)”, with line counts matching the card); ← → switch between files of the same card. Clicking a card title also expands or collapses it; ⌘+click a file row to open Quick Look, while a plain click only selects it. Right-click a file row for “Copy path:line” (the line is the file’s first change).
  • Fallback messages: “Not a Git directory; file changes are not recorded” shows only the title, duration and quote; “No snapshot: gilvt was not recording during this turn” marks turns from before gilvt started or that it missed, and no file list is made up; “Snapshot failed: reason” means a git call failed, without affecting the Agent or the terminal; “Skipped N large files” refers to files over 5 MB; “Interrupted: the end of this turn was not observed” means the end of the turn was never seen (gilvt quit, or the next prompt arrived first), so only the beginning of the turn exists.
  • Snapshots: at the start and end of every turn, gilvt takes a snapshot of the working tree and stores it in its own directory, without touching your repository (it does not touch .git/index, create commits or write .git/objects). When a repository has had no new snapshot for 30 days, all of its snapshots are cleaned up; clicking a file afterwards says “Snapshot was cleaned up”, while the file list on the card remains. During a turn, files that are neither tracked nor ignored by git are copied into ~/Library/Application Support/gilvt/state/snapshots (a node_modules without a .gitignore will take up its full size there); when a repository has had no new snapshot for 30 days, its whole snapshot directory is deleted. With Git LFS, git add runs its clean filter, and the cache stays in the repository’s .git/lfs.

Inspector: Configuration

⌥⌘3 switches to the “Configuration” tab. In the background it reads the configuration for the current Agent and working directory and shows it as cards: model / permission mode, MCP, Hooks, the number of Skills / commands / subagents, CLAUDE.md / AGENTS.md, and configuration sources. The “this session / user / project / project · local” label next to each value tells you which layer it comes from; the model and permissions actually reported by a running session take precedence. Expand the MCP / Hooks / memory rows to see redacted details; click Skills / commands / subagents under “Extensions” to open a list dialog (name, description, path), click an item to view its Markdown in Quick Look, and use the “Edit” button that appears on hover to edit it in the built-in editor.

This page is strictly read-only: it does not run MCP commands and does not show MCP commands, URLs, tokens or environment variable values. If configuration files change while the page is open, it does not poll for them; click “Refresh” in the top-right corner to reread. When a file is corrupted, only its redacted path and line/column are shown, and the other sources are still displayed. M5a currently provides only the summary; layered editing, diff before save, format-preserving write-back and conflict detection belong to M5b.

Monitor: global activity view (⌘⇧O)

⌘⇧O (or the menu “Sessions → Monitor”) opens the “◎ Monitor” tab at the far left; press it again to return to it. It lays out the Agent sessions and plain terminals of every window as cards, so you do not have to switch to each one; while shown, it refreshes once per second.

  • Groups: the same as the sidebar’s “Status” grouping: Needs you, Error, Running, Done, unseen, Idle, Terminals, and finally “Ended”, collapsed by default. The filter bar at the top has “All” plus each non-empty group (except “Ended”); click one to see only that group, click it again to return to “All”, and when the filtered group becomes empty it also returns to “All” automatically. The tab title shows “· N Needs you”.
  • Agent cards: session name and location, state and current action; ⎇ git · Turn N · this turn X / took X · +a −b · N files (branch, turn number, time spent this turn, lines added and removed, and file count; when the task’s net changes are not available (still calculating or not computable), only the file count is shown); a TODO progress bar with “TODO a/b · Context N%”; and for Done, unseen, a quote “…” of the first sentence of the last reply.
  • Terminal cards: name · ~directory; while a command is running, “● command · running time”, otherwise “Last: ✓ / ✗ command · exit N · duration · how long ago” (multi-line commands show only the first line plus …; failed commands also show the last line of output); the last line is “Foreground: program”, or “Idle” when there is no foreground program. Commands require gilvt’s shell integration (on by default).
  • Catch up: click “Catch up” on a card (or select it and press Space). For an Agent it lists every turn (first line of the prompt, result, duration, lines added and removed); for a terminal, the last 10 commands. Click a turn to go back to that session with the turn expanded in the inspector’s “Process”; click a command to go back to that terminal, scrolled to the command.
  • Keyboard: arrow keys select cards, ⏎ jumps there, Space expands or collapses Catch up.
  • The Monitor only reads, never writes: it never types anything into any terminal. The Monitor tab is restored after a restart.

✦ AI Summary

When enabled, each card can carry a “✦ AI Summary” block (goal, recent progress), and sidebar session rows also show the first sentence of the summary’s “recent” part. Summaries are generated by the Claude or Codex CLI on your own machine and are off by default.

Turning it on: add [monitor] to config.toml and set enabled = true. You can also turn it on and adjust it directly in the settings window (see the next subsection).

[monitor]
enabled = true            # default false; when false, no CLI is ever called and cards and the sidebar behave as if it were off
provider = "claude"       # "claude" or "codex"
model = ""                # empty = the CLI's default model
summary_model = ""        # model used only for summaries; empty = same as model
command = ""              # path to the CLI executable; empty = look it up on the login shell's PATH
auto_summary = true       # refresh summaries automatically
summary_interval = "2m"   # automatic refresh interval while running; supports s / m / h, minimum 30s
sidebar_summary = true    # show the summary's first sentence on sidebar session rows
exclude_paths = []        # sessions / terminals under these directories are never summarized; ~ is supported

If summary_interval cannot be parsed (or contains non-ASCII characters), it falls back to 2m and a startup error says so.

Settings window (⌘,)

⌘, (or the menu “gilvt → Settings…”) opens the settings window. There is only one: pressing it again while it is open just brings it to the front. ⌘W closes it; if no workspace window is left after closing it, gilvt quits. The navigation on the left has two pages: “◐ Appearance” (themes, see the “Themes” section) and “◎ Monitor”; it opens on the page you last viewed, “Appearance” the first time.

Changes take effect immediately and are written back to config.toml: every control takes effect in the running app as soon as you change it (turning enabled off clears the summary queue and removes the ✦ blocks, while cached summaries are kept; provider, model and CLI path apply from the next call), and is written into the [monitor] table at the same time. Write-back touches only the keys you changed, keeping the comments and layout of your file intact; it rereads the file from disk before writing, so it never clobbers what you just changed in an editor; when config.toml is a symlink, it writes to the file the link points to, and file permissions stay the same. If you never open the settings window and have no [monitor] table, config.toml is never changed by a single byte. When write-back fails, the settings page shows a red notice and the change still applies for this run. When config.toml is read-only, gilvt does not overwrite it (the same goes for themes picked on the “Appearance” page): the red text at the top of the settings page first says “config.toml is read-only; not written”, the next line is the file path, and the change applies only for this run.

Editing the file by hand also reloads automatically: edit config.toml in an editor and save; about 200 milliseconds after the file stops changing, gilvt rereads it and refreshes all windows (changes caused by gilvt’s own write-back are ignored). Only keys that changed in the file override the running values, so a font size you adjusted temporarily with ⌘+ / ⌘− is not reset because you clicked something in the settings window or changed some other key in the file; only when font_size itself changes in the file does the file win. The same holds when there is no ~/.config/gilvt/ directory yet: watching starts as soon as the directory appears (it is created on the first write-back or when you click “Open in Editor”). When the file has a syntax error, a yellow notice appears at the top of the settings page, all controls become read-only, and gilvt keeps using the last valid configuration; it recovers automatically once you fix and save the file. If the file is deleted, the defaults apply again.

  • Model: “Provider” selects Claude or Codex; switching provider resets both models to “CLI default”. Claude’s drop-down offers fixed aliases: CLI default, fable, opus, sonnet, haiku; Codex’s list comes from model/list of codex app-server, fetched once when the page opens; “↻ Refresh” next to it fetches again, and on failure only “CLI default” is offered, with the reason shown. “Summary model” has one extra option, “Same as chat model”.
  • “Other…”: the last option; selecting it turns the row into a text field (placeholder “Model name; press Return to try”). Type a model name and press ⏎; gilvt runs one trial summary with that name and writes it only if it succeeds; Esc cancels. On failure the old value stays and the reason is shown: usually “the model does not exist or you do not have access (…)”, or possibly “claude not found; set the CLI path in Settings”, “claude authentication failed (run claude in a terminal to log in)” or “timed out” (likewise for Codex). When the configured value is not in the list, it shows “<value> ⚠ Not in list”.
  • Custom CLI path: leave the field empty to search PATH; or click “Choose…” to pick an executable.
  • Test Connection: runs once with the current settings. It checks the CLI version, one summary, and then one real chat turn (asking the model to call list_sessions once); on success it shows “✓ program version · authenticated · summary N s · chat N s (list_sessions ✓)”. That chat turn uses a temporary token generated for the occasion, which becomes invalid once the settings window closes. When the Monitor’s main switch is off, the chat is not run (no session data is sent out), and the result line ends with “· chat not tested (Monitor is off)”; turn the switch on and test again. Common failures: “claude not found; set the CLI path in Settings” → fill in the path above; “claude authentication failed (run claude in a terminal to log in)” → log in from a terminal (likewise for Codex). If the settings change again during the test, the result is discarded and you need to test again.
  • ✦ AI Summary: the “Automatic refresh” switch; the “Minimum interval” segmented control (the minimum time between two automatic summaries of the same session); the “Show summaries in sidebar” switch.
  • Excluded directories: “+ Add…” picks a directory; click the × on a directory chip to remove it; when written to the file, directories under your home directory are written as ~/…. Sessions and terminals under these directories are never sent to the model: their cards show as usual, but without a ✦ block.
  • Open in Editor: opens config.toml directly in your default editor.

When each key takes effect (whether it comes from the settings window or from editing the file): fonts (font_family, font_size, line_height, fallback_fonts), theme, option_as_meta, [notify] and [monitor] take effect immediately; claude_launch / codex_launch under [agent] apply from the next time gilvt types a launch command for you, and claude_commands / codex_commands are used immediately to recognize foreground Agent processes. scrollback, kitty_keyboard and shell only affect panes opened afterwards; the part of claude_commands / codex_commands handed to shell integration (which lets Agents report their state to gilvt) also applies only in newly opened panes. Only shell_integration requires restarting gilvt.

Privacy:

  • Off by default; when on, only sessions and terminals that are not excluded have their content handed to the CLI.
  • exclude_paths matches by path component (symlinks are resolved first): a session or terminal whose directory is among them is not summarized. A single terminal command is not sent either if the shell’s directory at its start or after it ends is in an excluded directory (for example cd ~/secret && cat notes run in ~), or if the command line spells out a path to an excluded directory (absolute path, ~/… or $HOME/…, for example (cd ~/secret && make)).
  • Exclusion only looks at the working directory and the paths written on the command line; it does not look at which files a program actually reads or writes: a script run in an ordinary directory that reads files in an excluded directory may still have its command and the tail of its output sent.
  • Data sent: for an Agent session, the first summary uses the last 2 turns, and later ones roll forward (the previous summary + at most 3 newer turns); for a terminal, the last 10 commands and the tail of their output. Total size is capped at 24 KiB, and 4 KiB per tool call.
  • The CLI runs headless: tools off, hooks off, none of your configured MCP servers connected, no session files written (claude -p … --strict-mcp-config --no-session-persistence; codex exec --ephemeral -s read-only, with a -c mcp_servers={"<name>"={enabled=false},…} that turns off every MCP server in ~/.codex/config.toml (names containing dots or spaces work too)), working directory <state>/monitor/run, 90-second timeout, at most 2 at a time; CLIs still running when gilvt quits are terminated. The chat process likewise turns off tools, hooks and your configured MCP servers: Claude with --strict-mcp-config, and Codex with the same -c mcp_servers={…} turning off every MCP server in ~/.codex/config.toml, keeping only gilvt’s own gilvt. The Claude chat process always uses --permission-mode dontAsk (it does not follow your configured default permission mode; only gilvt’s tools are usable); Codex (both summaries and chat) runs with -c notify=[], so your configured notify program does not receive the Monitor’s answers. Note: if your own Codex configuration also has an MCP server named gilvt, its settings are merged with the one gilvt injects; please rename it.
  • Finding the CLI: a gilvt opened from Finder or the Dock has only the system default PATH, so at startup gilvt reads the PATH once from your login shell ($SHELL -lic), looks up claude / codex in it, and passes it on to the CLI (CLIs installed with npm also need it to find node). If it still shows “✦ Summary failed: claude not found (set the full path in [monitor] command)”, set command to the output of which claude.

Refresh rules:

  • Automatic: when a turn ends, when the session becomes “Needs you” or errors, and every summary_interval while running; at least summary_interval apart, and only when there is new activity.
  • Manual: click “✦ Summarize Again”, click “✦ Generate Summary” or “Retry”, or select a card and press s (ignored with ⌘ / ⌃ / ⌥).
  • After 3 consecutive failures, automatic summaries for that session pause and the card shows “✦ Automatic summaries paused: …”; they resume after a successful manual run.
  • States of the ✦ block on a card: generating… / updating… / generated (just now, N minutes ago, covering which turns or the last few commands) / new activity / failed / paused.
  • Ended sessions show their saved summary (cached in <state>/monitor/summaries/) and cannot be summarized again; terminal summaries live only in memory and are gone after a restart.
Known limitations: command output is approximate text with escape sequences removed; programs that draw progress bars by moving the cursor up may produce repeated lines, and programs that redraw the whole screen without using the alternate screen may appear out of order; terminal summaries do not survive restarts. Command output is now cut precisely from the PTY between OSC 133 C and D, so terminal cards can once again show the last line of output of a failed command.

Chat

With the Monitor open and [monitor] enabled turned on, the right side of the “◎ Monitor” tab holds a chat panel (360 px wide) for questions like “What needs me?” or “What went wrong?”. When the tab is narrower than 760 px, the panel collapses into a 26 px “◎” strip on the right edge (with a badge when there are unread answers); click it to expand it as an overlay on top of the card wall, and “⇥” in the panel’s title bar collapses it. With the Monitor not enabled (enabled = false), there is no panel, no strip and no “◎ Ask”, and the A key does nothing.

How to ask:

  • Type directly into the input box; ⏎ sends, ⇧⏎ inserts a newline. When the box is empty, three quick questions are offered: “✦ Generate Standup Brief” (first lists what “needs you”, then gives an “overall” overview), “What needs me?” and “What went wrong?”.
  • “◎ Ask” on a card, or selecting a card and pressing A (the letter key; ignored with ⌘ / ⌃ / ⌥), puts that card into the input box as the scope.
  • Typing @ in the input box (the full-width @ works too) pops up a session list: ↑ / ↓ to select, ⏎ to confirm, Esc to close; you can pick several, and the × on a scope chip removes it. The scope stays on the message bubble, and also in the input box for follow-up questions.
  • Session names in answers are links; click one to go back to that session or card.

What it can see: five read-only tools — list sessions, session overview, the timeline of some turns (at most 3 turns), terminal commands (at most 20), and reading the screen (at most 200 lines; the chat shows “Reading the screen of …” and “Read the screen of … (last N lines)”). Every tool call is shown in the answer. Sessions and terminals under exclude_paths do not exist for it. It cannot take any action: writing to a pane, approving and sending messages are all off-limits (that is for a later phase).

Processes and cost:

  • Your own claude or codex starts only with the first message; all windows share the same process, which uses the “Provider” and chat model from Settings and draws on your own account’s quota.
  • After 30 minutes idle the process ends automatically (the chat history is kept; the next message restarts it automatically, with the last 6 questions and answers as context); “New Chat” clears the history and ends the process.
  • Sending another message while an answer is in progress first interrupts the current turn (if it has not stopped within 5 seconds, the process is ended and restarted with context); “Stop” stops only the current turn; a turn with no output at all for 5 minutes straight is also interrupted automatically, showing “(this turn was interrupted)”.
  • When the process exits unexpectedly, the chat shows “Monitor process exited (…)”, and the next message restarts it automatically.
  • Codex must be able to turn off shell_tool, unified_exec and hooks, so that it can only query data through gilvt’s read-only tools; if any of these switches cannot be found, the panel shows a red “Could not start Codex chat” explanation card, and you can switch to Claude or upgrade; ✦ summaries are not affected.

Privacy: the chat history lives only in memory and is cleared when gilvt restarts; every tool call is shown in the chat; each time gilvt starts the chat process (and for “Test Connection”) it generates a random token that is given only to the process it started itself, becomes invalid when that process ends, and never appears on the command line.

Troubleshooting: “View Log” on an error card opens ~/Library/Application Support/gilvt/state/monitor/chat.log, and “Open Settings” jumps to the settings window; “Test Connection” in the settings window runs one chat turn and calls list_sessions once.

Known limitations: chat history is not kept across restarts (for other limitations, see “Known limitations and troubleshooting”).

Command bar (⌘⇧M)

  • With the Monitor enabled, every workspace window (except the settings window) has a thin 20 px line below the pane area: while answering, starting or stopping it shows “◎ Monitor · Answering…” (likewise “Starting…” and “Stopping…”); after an answer it shows the first sentence of the latest answer (or its heading, if the answer has only a heading and no body text); on errors it shows “◎ Monitor · Error: …”; before any chat it shows just “◎ Monitor”. The hint on the right is “⇧⌘M ask”, with a red dot when there are answers you have not seen.
  • In any tab (terminal, Agent, editor, Monitor), press ⌘⇧M (or click the thin line, or use the menu “Sessions → Monitor Command Bar”) to focus the input box, with the latest question and answer shown above it; ⏎ sends (the overlay stays expanded after sending and the answer appears above), ⇧⏎ inserts a newline, @ picks sessions, just like the chat panel. This key combination is never written into the terminal or the Agent.
  • Esc or pressing ⌘⇧M again collapses it and returns the keyboard to where it was; while the @ candidates are open, the first Esc only closes them. With the command bar expanded, ⌘W only collapses the command bar and does not close the pane below; the “Close Tab” menu item, clicking a pane, or switching tabs with ⌘1–⌘9 also collapse it. When the pane closes by itself (for example when the shell exits), the command bar stays expanded with the keyboard still in the input box. Unsent text in the input box is kept when collapsing (@ candidates and unfinished IME composition are not).
  • “View in Monitor ↗”: switches to this window’s “◎ Monitor” tab (creating it if there is none) and opens the chat panel; clicking a session name in an answer jumps to that session (excluded or missing sessions are shown as plain text only).
  • The command bars and chat panels of all windows share one conversation; the expanded / collapsed state and the input draft are separate per window. Expanding the command bar does not resize the terminal (the overlay covers the bottom of the pane, up to 260 px tall, scrolling beyond that).
  • With the Monitor disabled, the command bar does not appear and ⌘⇧M does nothing; disabling the Monitor while it is running collapses an expanded command bar.

Resume and manage sessions (⌘⇧R)

The “Sessions” overlay lists all Claude Code and Codex sessions on this machine, showing only the current project by default. When you type, it switches to “All projects” and matches titles, first prompts, project names and directories; you can also type the beginning of a session ID.

What a session is called: no longer just its first prompt. Titles that Claude and Codex give sessions themselves take priority (a title you changed in Claude > a title generated by the Agent > the first informative prompt, cleaned up, skipping replies like “continue” or “sounds good”); a name you set in gilvt with ⌘R always wins. Search finds sessions both by title and by your original wording. A new session’s title appears only after the next refresh (press ⌘⇧R again).

KeyAction
↩Resume: in place if the focused pane is an idle shell, otherwise in a new tab; a running session jumps straight to its pane
⌘↩ / ⌘⇧↩Resume in a split to the right / below
⌘RRename
⌘⇧CCopy Session ID
⇧+click / ⌘+clickSelect a range / select individually
⌘EArchive / unarchive the selected sessions
⌘⌫Move the selected sessions to Trash (confirmation bar first)
⌘⇧KOpen the cleanup wizard
EscClose the context menu, the confirmation bar, then the overlay, in that order

Resuming does exactly what you would type by hand: gilvt types cd <original directory> && claude --resume <id> into the pane (for Codex, codex resume <id>). After resuming, the sidebar shows the original session name and the inspector fills in the earlier turns.

Under each name, a small gray line shows the directory the session ran in (~/…/project/subdirectory · branch · N turns); if the directory no longer exists (such as a deleted worktree), it is struck through and marked “Directory missing”, so you can see that before resuming.

Archive: for sessions you are done with but want to keep, select them and press ⌘E (or right-click “Archive”) to put them away: they leave the default list, the To Review queue and the sidebar’s “Ended”, and searches no longer match them by default; the files are untouched. The “Archived” filter lets you view, search, resume or unarchive them. If an archived session later completes a new turn, it is unarchived automatically and goes back to To Review, so nothing slips by; changing only the title does not count. Running sessions cannot be archived.

Cleaning up old sessions: the “Inactive ≥ 7 days” filter shows each session’s size; select several and press ⌘⌫ to move them to the system Trash, from where Finder’s “Put Back” restores them. Running sessions cannot be deleted. Deleting also takes along the companion data named after the session ID (Claude’s file-history/<id>/, tasks/<id>/ and so on, Codex’s shell snapshots), with sizes shown separately in the confirmation bar (“X MB + Y MB companion data”); shared data such as history.jsonl and Codex’s sqlite database is left alone.

Cleanup wizard (⌘⇧K): handles a batch at once. Four presets on the left, a preview of the matching sessions on the right, each row with a checkbox, all checked by default; the bottom shows “Selected N / M · X MB” live.

PresetMatchesDefault action
Empty sessionsNo meaningful prompt, or only 1 turn with no tool callsMove to Trash
Reviewed and inactive for 30 daysThe latest turn has been seen, and no activity for 30 daysArchive
Largest 20The top 20 by size (including companion data)Move to Trash
Archived and inactive for 90 daysNo activity for 90 days after archivingMove to Trash

Running sessions never match; pinned sessions are unchecked by default; sessions not yet reviewed appear only under “Empty sessions” and “Largest 20”, marked “Not reviewed”. “Move to Trash” still shows a confirmation bar first, and cancelling moves nothing. The wizard can also be opened from “Clean Up…” in the sessions overlay and from the “Sessions” menu.

Only sessions running in gilvt are protected. gilvt does not know that a session running in another terminal app is running, so quit it in that terminal before resuming or deleting it.

To Review: have you looked yet? (⌘⇧R → ⌘2)

The Session Center opened by ⌘⇧R has four tabs: ⌘1 Needs you, ⌘2 To Review, ⌘3 Running, ⌘4 All Sessions (the resume and management view above). Once you have many sessions, “To Review” tells you which results you have not looked at yet: new turns completed by an Agent enter the queue, with failures first. “To Review N” under the sidebar header is another entry point.

Select a row and press Space to view, read-only and without starting the Agent, this session’s new prompts, the Agent’s final response, tool calls and errors. When you are done, press ⌘↩ for “Reviewed, Next”; to look later, press Z to pick a reminder time; to just move on to another one, press S to skip; F shows the full history.

KeyAction
SpaceOpen the read-only Review
⌘↩Reviewed, Next (removed from the queue only if saving succeeds; with more than one page, go to the last page first)
S / Z / PSkip / remind me later (then 1 in 1 hour, 2 later today, 3 tomorrow) / pin
FFull history ⇄ unreviewed only
E / LEarlier / later turns ([ / ] also work, but a Chinese IME turns them into the full-width 【 】, so E / L are preferred)
↩Back to the Agent (jumps to the pane of a running one, resumes an ended one)
EscBack to the list; press again to close

In a Review, ⇧⌘E “Mark Reviewed and Archive” removes the session from the queue and opens the next item automatically.

Things to know: the first time this is enabled, all existing past sessions count as “seen”, so the queue is not flooded all at once; merely opening, scrolling or closing a Review does not mark it as seen, you have to press ⌘↩; new turns the Agent completes while a Review is open are not swallowed by that confirmation and stay in the queue; the Review page never types anything into a terminal; letters pressed with ⌘ / ⌥ / ⌃ are not shortcuts, so nothing triggers by accident.

If a session’s record has been truncated or replaced, its saved Review position can no longer be found. Such a session shows up as “Failed”; open it and press B for “Start from Here” (everything existing counts as seen) or A for “Review All Visible History” (every existing turn goes back to To Review).

As with resuming, “Running” only includes sessions running in gilvt; sessions running in other terminals are not visible for now.

New Agent (⌘⇧N)

Typing claude directly in the terminal is still the most common way. ⌘⇧N is handy for starting several Agents at once, or for starting one in another directory:

  • Agent: ⌘1 Claude / ⌘2 Codex.
  • Directory: defaults to the current pane’s directory; Tab completes subdirectories.
  • Initial task: optional; ⇧↩ inserts a newline.
  • More: model and permission mode; → expands it.
  • Run in a new worktree (⌥W): off by default; grayed out when the chosen directory is not in a git repository. When checked, gilvt creates a worktree at <repo>.worktrees/gilvt-<name>-<4 chars> on branch gilvt/<name>-<4 chars>, and the Agent starts inside it. If it cannot be created, the panel stays open with a red error in it, and nothing is started. gilvt never deletes worktrees automatically; clean them up yourself once the session is over.
  • Command preview: the bottom shows, live, the complete command that will run and where; this line is exactly what gets typed. If the directory does not exist, it turns red and will not run.

↩ / ⌘↩ / ⌘⇧↩ decide where it opens, with the same rules as the “Sessions” overlay. gilvt remembers the Agent, model and permission mode you last chose.

Notifications and the Dock

StateWhen notifiedSound
Awaiting approval / asking youImmediatelyYes
ErrorImmediatelyNo
Turn completedWhen the turn took ≥ 30 secondsNo
Context ≥ 90%Once per sessionNo

Notifications are sent only when gilvt is not in the foreground or that pane is not visible; muted sessions send none. Clicking a notification jumps to its pane.

The Dock badge shows the number of sessions that “Need you” (muted ones excluded). While gilvt is in the background, the Dock icon bounces once each time a session starts waiting for you. To turn off the bouncing, set [notify] dock_bounce = false.

Themes (⌘, → “Appearance”)

Themes are chosen on the “◐ Appearance” page of the ⌘, settings window (the first page in its sidebar; the window opens on the page you last viewed, “Appearance” the first time). The overlay picker previously opened from the menu gilvt → Themes… has been removed.

  • Search and filter: type a theme name in the search box; “All / Dark / Light” switches the filter.
  • Fixed / Follow System: “Fixed” always uses one theme; “Follow System” has a light slot and a dark slot and switches automatically when the system appearance changes.
  • Selecting applies it: click an item, use ↑↓, or press ⏎ (selects the highlighted row), and every window (the settings window included) switches to it at once; there is no separate preview-and-revert step; Esc only clears the search. Window chrome, status colors and the window title bar all follow (with a fixed theme the title bar is forced to light / dark; with Follow System the system decides). The preview on the right shows the highlighted theme’s 16 colors, sample output and the four status markers; when [colors] overrides are present, the page says so.
  • Write-back: about 300 ms after the selection settles, it is written to config.toml (only the theme key changes, comments are kept, and symlinked configuration files work too); holding ↑↓ does not write the file at every step.
  • Write-back failures: when the configuration file is read-only or similar, the theme applies only for this run, and red text at the top of the page first gives the reason (such as “config.toml is read-only; not written”), with the file path on the next line. When the configuration file has a syntax error, the page is read-only, and you can pick again only after fixing it.
  • Editing the configuration by hand: edit theme or [colors] in config.toml directly; it takes effect as soon as you save, without a restart. A misspelled name also brings up an error banner.

Your own themes: put theme files (plain text, one key = value per line, the same format as the built-in themes) into ~/.config/gilvt/themes/; the file name is the theme name. They take precedence over built-in themes of the same name (exact name match first, then case-insensitive). In config.toml, write:

theme = "My Theme"                                   # fixed
# theme = { light = "gilvt Light", dark = "My Theme" }   # follow system
[colors]                                             # optional: override individual colors on top of the theme
# background = "#1b1b26"
# palette = { 1 = "#ff5f5f" }

[colors] supports background, foreground, cursor, cursor_text, selection_background, selection_foreground and palette (0–15). When a name is misspelled or a theme file is invalid, an error banner appears at the top with a “did you mean …” suggestion, and gilvt uses the default theme for the time being. Status colors come from the theme’s ANSI 3 / 1 / 4 / 2 and are corrected automatically when contrast is insufficient; with the default theme, the Markdown preview keeps GitHub colors.

Configuration

The configuration file is ~/.config/gilvt/config.toml; every field is optional:

font_family = "Menlo"
font_size = 13.0
line_height = 1.25
fallback_fonts = ["PingFang SC", "Apple Color Emoji"]
theme = "system"          # system | light | dark | theme name | { light = "…", dark = "…" } (see "Themes")
scrollback = 100000
option_as_meta = true     # Option acts as Meta
kitty_keyboard = true
shell_integration = true

[agent]
claude_commands = ["claude"]            # command names recognized as Agents
codex_commands = ["codex"]              # add wrapper scripts too, e.g. ["codex", "codex-w"]
claude_launch = "claude"                # command name typed when resuming / creating
codex_launch = "codex"

[notify]
dock_bounce = true

[update]
mode = "download"         # download | check | off (see "Updates")

[colors]                  # optional: override individual colors on top of the theme
# background = "#1b1b26"

If you start Codex through a wrapper script such as codex-w, add it to codex_commands (so gilvt recognizes it) and set codex_launch to it, so resuming and creating use it. If you have already defined an alias for claude, gilvt does not override it; to have it recognized too, change the alias to alias claude='gilvt_agent claude claude --model opus'.

gilvt’s own state (renames, mutes, panel widths, session index cache) is stored in ~/Library/Application Support/gilvt/state/.

Keyboard shortcuts

ShortcutAction
⌘T / ⌘NNew tab / new window
⌘D / ⌘⇧DSplit right / down
⌘⌥←↑→↓Move pane focus
⌘⌃←↑→↓Resize pane
⌘⇧⏎Maximize / restore pane
⌘⇧TMove pane to a new tab / back
⌘W / ⌘⇧WClose pane / tab
⌘1…9, ⌘⇧[ ⌘⇧]Switch tabs
⌘PSearch files
⌘B / ⌘IShow / hide the sidebar / inspector
⌥⌘1 / ⌥⌘2 / ⌥⌘3Inspector “Process” / “Artifacts” / “Configuration”
⌘⇧OMonitor: open / return to the global activity view
⌘⇧MMonitor command bar: expand / collapse (Esc also collapses)
⌘,Settings (the Monitor’s [monitor])
A (card selected in the Monitor)Ask: put this card into the chat input box as the scope (ignored with ⌘ / ⌃ / ⌥)
⌘⇧JNext session that needs you
⌘⇧↑ / ⌘⇧↓Previous / next session
⌘⇧RSession Center (⌘1–⌘4 switch tabs, Space read-only Review; ⌘E archive)
⌘⇧KCleanup wizard
⌘⇧N“New Agent” overlay (⌥W run in a new worktree)
⌘FFind (⏎ previous, ⇧⏎ next)
⌘KClear the scrollback buffer
⌘= / ⌘- / ⌘0Font size
⌘⇧VEditor: toggle live preview
⌘+click / ⌘⇧+clickOpen a link or open a path in Quick Look / open a path in the built-in editor

Known limitations and troubleshooting

Known limitations

  • Text in Quick Look and pinned preview panes cannot be selected and copied yet (scheduled for a later version).
  • “Artifacts” records file changes only inside git repositories; non-git directories get only the title, duration and quote.
  • The net changes of a multi-turn task include whatever you changed by hand between turns; only whole-sentence replies such as “continue” or “sounds good” count as follow-ups, so “sounds good, now also change X” is not merged.
  • Turns gilvt was not recording (resumed old sessions, turns before gilvt started) have no file list.
  • When several sessions change files in the same directory at the same time, each one’s snapshots pick up the other’s changes, and the cards do not attribute them.
  • Files over 5 MB are not snapshotted; for those already tracked by git and modified, the snapshot keeps their old committed content (only noted as “skipped”), so their changes are not visible.
  • Settings window: changing shell_integration still requires restarting gilvt, and scrollback, kitty_keyboard and shell only affect newly opened panes; Claude’s model list is fixed aliases.
  • “Configuration” is read-only for now; it does not check MCP connection status and cannot edit or write back (M5b).
  • gilvt does not know that a session running in another terminal app is running.
  • The Monitor’s terminal cards depend on gilvt’s shell integration: with shell_integration turned off, or when bash already has its own DEBUG trap, no commands are recorded; in bash, commands that do not enter history (starting with a space under HISTCONTROL=ignorespace) are recorded as “(command unknown)”; for a command with the same history number as the previous one, only a simple command whose whole line is identical to the previous one is recorded (repeated simple commands work fine under HISTCONTROL=ignoredups, while repeated pipelines or compound commands are recorded as “(command unknown)”). The command text is cut at 2000 bytes on the shell side (600 characters in fish), with the cut marked by a trailing ….
  • Monitor chat: history is not kept across restarts.
  • Monitor chat: exclude_paths only blocks sessions and terminals under excluded directories. When it reads the screen of a terminal that is not excluded (read_screen), the screen may still hold output of commands that touched excluded directories; reading the screen is an explicit action shown in the chat.
  • Monitor chat: when the tab is narrower than 760 px, the panel collapses into the “◎” strip on the right edge, and clicking it opens an overlay on top of the card wall; at the default window size with the inspector shown, the Monitor tab is narrower than 760 px, so to see the side panel, hide the inspector with ⌘I or widen the window.
  • Monitor chat: Codex must be able to turn off the three switches shell_tool, unified_exec and hooks; otherwise the panel shows “Could not start Codex chat”, while ✦ summaries work as usual; chat has only two providers, Claude and Codex.
  • Command output excerpts may have a line or two more or fewer; command records are not kept across restarts, and each terminal keeps at most 50.
  • When the Monitor and a terminal are split in the same tab, only the terminal part is restored after a restart; a window with only the Monitor and no terminal tab is not saved and is not restored after a restart.
  • Live preview follows scrolling in one direction only (editor to preview), and you cannot edit in the preview.
  • Agents are not resumed automatically after a restart; click them under “Pending resume” in the sidebar; editor panes and previews are not restored either.
  • Archiving and cleanup apply only to existing sessions; custom criteria and scheduled automatic cleanup are not supported; sessions in the Trash must be restored in Finder.
  • Codex may start in Lite mode the first time: gilvt needs less than a second in the background to obtain its hooks trust information, after which sessions start normally.
  • Codex uses an alternate-screen interface by default, so clicking events in its timeline only expands details and does not jump in the terminal.
  • In Follow System mode, when you edit the slot on the “Appearance” page that differs from the current system appearance, you can see the effect only in the preview on the right.
  • Themes added to ~/.config/gilvt/themes/ while the settings window is open appear in the “Appearance” page’s list only after you close and reopen the settings window.
  • Background transparency and blur are not supported.
  • Symlinks in the themes directory are followed: a link pointing elsewhere is read as a theme file.
  • Sidebar hover tooltips always keep a dark style.

Common questions

  • No badge on the Dock: open “System Settings → Notifications → gilvt” and make sure “Allow notifications” is on. macOS also hides the badge when notifications are off.
  • No system notifications, or clicking a notification opens “Script Editor”: bundle with scripts/bundle.sh and launch from Gilvt.app.
  • The sidebar shows “Lite mode”: hooks did not take effect. Check whether you used claude --bare, or whether your own claude alias was not changed to call gilvt_agent.
  • The status card shows “This version is not fully supported yet”: the record format changed after a Claude / Codex upgrade; the terminal itself is unaffected.