Claudebox Specification
Purpose: This document describes user-facing behavior only—what the user sees and experiences. It is not concerned with implementation details, architecture, or code structure.
Overview
Claudebox is a containerized development environment for AI coding agents. The web UI provides:
- Real-time streaming chat
- Dockable panel layout with persistence
- Session management
- Interactive tool execution
1. Layout
1.1 Structure
┌─────────────────────────────────────────────────────────────┐│ [Left Strip] │ Center Panels │ [Right Strip] ││ │ │ ││ Sessions │ ┌─────────────────────┐ │ Todos ││ │ │ Chat Tab │ │ Stash ││ │ │ │ │ Tasks ││ │ │ │ │ Bookmarks ││ │ └─────────────────────┘ │ Boards ││ │ │ Usage ││ │ │ MCP ││ │ │ Commands ││ │ │ Help │├─────────────────────────────────────────────────────────────┤│ Logs strip (when open, full width) │├─────────────────────────────────────────────────────────────┤│ Footer │└─────────────────────────────────────────────────────────────┘When the logs panel is open, it occupies the full screen width above the footer; closing it returns the space to the main row.
When two bottom-slot panels are open at the same time, they split the bottom strip 50/50 horizontally (left slot on the left, right slot on the right); when only one is open it fills the whole strip; closing the last one returns the space to the main row.
1.2 Icon Strips
- Left strip: Sessions (top); Containers sits at the bottom of the left strip
- Right strip: Todos, Stash, Tasks, Bookmarks, Boards, Usage, MCP, Skills, Help (top to bottom); Logs sits at the bottom of the right strip
- The Logs icon lives at the bottom of the right strip
- Icons show badge counts for Todos (incomplete) and Stash (item count)
- Clicking toggles panel visibility
- Tooltip shows panel name and shortcut
1.3 Panel Behavior
| Behavior | Expected |
|---|---|
| Toggle panel on | Opens at canonical position (see 1.4) |
| Toggle panel off | Saves width, panel closes |
| Reopen panel | Restores saved width |
| Close all panels on side | Chat expands to fill |
| Reopen after closing all | Restores previous widths |
| Drag panel to new position | Removes panel from side order |
- Chat panel always visible (cannot be closed)
- Skills, Tasks, and Containers panel rows share a padded-card look with a subtle background, brighter on hover, and consistent vertical spacing. Identifier values are monospaced; other text uses the regular font.
- Hovering an icon while panels are maximized opens that panel as a floating overlay anchored to the icon, after a short hover-intent delay. The overlay grows to fit its content and stays within the icon strip's vertical bounds
- Logs and Containers floating previews open wider than other panels to fit their horizontally-dense rows
- When no panels are maximized, hovering an icon for a panel that is not currently visible (a closed side panel, or the closed logs strip) opens its floating preview after a short hover-intent delay
1.4 Canonical Panel Order
Panels maintain consistent vertical stacking within each side:
- Left: Sessions (top), Containers (bottom)
- Right: Todos (top), Stash, Tasks, Bookmarks, Boards, Usage, MCP, Skills, Help (bottom)
Opening a panel inserts it at correct position relative to visible panels.
1.5 Layout Persistence
- Layout saved automatically on every change
- Includes panel configuration and widths
- Restored on page load; falls back to default if unavailable
- New sessions inherit panel layout from most recent session
1.6 Default Layout
- Main panel in center, default content is the welcome view (chat content appears once a session is opened)
- Sessions panel opens on left
- Todos, Stash, Tasks, Bookmarks, Boards panels open on right; Usage and MCP remain hidden by default
1.7 Browser Tab Title
- Format:
[Session Name] | [Workspace] | Claudebox; before session init, format is[Workspace] | Claudebox - Updates when session name changes
1.8 Session URL
The browser URL hash reflects the active session and the user's current scroll position within it:
| Hash form | Meaning |
|---|---|
#/workspaces/{id} | Welcome state, no active session |
#/workspaces/{id}/sessions/{sessionId} | Active session; scrolled to the latest message, following new responses |
#/workspaces/{id}/sessions/{sessionId}/turns/u-{turnId} | Active session; paused at user message in turn {turnId} |
#/workspaces/{id}/sessions/{sessionId}/turns/a-{turnId} | Active session; paused at assistant message in turn {turnId} |
#/workspaces/{id}/boards/{boardId} | Active board |
A workspace-only URL may also carry one or more messages, opening a new session and submitting them as its first turns:
-
Repeated carried text submits in the order it appears in the URL
-
Text submits automatically only when it matches a pattern the workspace's settings approve; if any piece of carried text does not match, none of it submits
-
Text that does not submit waits in the message box instead, with a notice explaining why
-
The carried text is used once — reloading the page the link produced reopens the same session without submitting anything again
-
A link naming a workspace that is not registered opens no session and submits nothing
-
Hash auto-updates as the user scrolls: gains
/turns/<role>-<id>segment when autoscroll disengages; loses the segment when the user scrolls back to bottom and autoscroll re-engages -
Hash updates apply to all scroll causes — user scroll, programmatic jump (bookmark click, scroll-to-edge), autoscroll re-engage
-
Hash updates do not add entries to browser back/forward history
-
On reload, the URL form is honored: bare URL → scroll to bottom and autoscroll engaged; turn URL → scroll to that turn and autoscroll disengaged
-
Bookmarks and other cross-session navigation produce URLs with the appropriate
/turns/<role>-<id>segment so deep-links and Alt+click-to-new-browser-tab land on the targeted message -
The hash names the session currently in focus; the sessions it descended from appear alongside it without appearing in the URL
2. Keyboard Shortcuts
2.1 Panel Navigation
| Shortcut | Action |
|---|---|
| Alt+C | Focus Chat tab |
| Alt+0 | Toggle Logs |
| Alt+1 | Toggle Sessions |
| Alt+2 | Toggle Todos |
| Alt+3 | Toggle Stash |
| Alt+4 | Toggle Tasks |
| Alt+5 | Toggle Bookmarks |
| Alt+6 | Toggle Boards |
| Alt+7 | Toggle Usage |
| Alt+8 | Toggle MCP |
| Alt+9 | Toggle Skills |
| Alt+? (or Alt+/) | Help overlay (toggle) |
| Alt+N | New session (current browser tab) |
| Alt+Shift+N | New session (new browser tab) |
- Alt+? opens Help panel as centered modal overlay; Escape or clicking backdrop closes it
2.2 Chat Input
| Shortcut | Action |
|---|---|
| Enter | Send message |
| Shift+Enter | Insert newline with inherited indent; on markdown list lines, auto-continue the list marker (auto-incremented for numbered, always unchecked for tasks); empty marker exits the list |
| Tab | Indent — snap leading whitespace to next multiple of 2 (or insert 2 spaces at caret in content zone) |
| Shift+Tab | Dedent — snap leading whitespace to previous multiple of 2; no-op if no leading whitespace |
| Up Arrow | Previous message in history (when cursor at position 0 with no selection); cursor placed at beginning |
| Down Arrow | Next message in history (when cursor at end); cursor placed at end |
| Ctrl+. | Interrupt/stop response |
| Ctrl+S | Stash current input (save) |
| Ctrl+Shift+S | Pop from stash (remove and insert) |
| Ctrl+, | Wrap selection in <this></this> |
| Ctrl+' | Collapse nearest XML block at cursor |
| Ctrl+Shift+' | Collapse all XML blocks |
| Ctrl+\ | Expand nearest collapsed block at cursor |
| Ctrl+Shift+\ | Expand all collapsed blocks |
- Ctrl+, with no selection inserts empty
<this></this>at cursor - Collapsed blocks display as
<tag...N>placeholder in textarea text (N is a sequence number) - Collapse targets innermost enclosing block; repeated Ctrl+' collapses next outer
- Collapsed blocks auto-expand before submit (full content sent to server)
- Chat input shortcuts require chat panel focus (except Alt navigation shortcuts, which are global)
2.3 Chat Navigation
Alt+Up/Down/Home/End below act on the chat transcript specifically:
| Shortcut | Action |
|---|---|
| Alt+Up | Jump to previous human message |
| Alt+Down | Jump to next human message |
| Alt+Home | Jump to first message (top of chat) |
| Alt+End | Jump to last message (bottom of chat) |
Alt+PageUp/PageDown belong to whichever view occupies the right split slot - the terminal column today:
| Shortcut | Action |
|---|---|
| Alt+PageUp | Step the right-hand column to the nearest entry above the visible area |
| Alt+PageDown | Step the right-hand column to the next entry below the visible area |
Alt+Shift+Left/Right move focus one group along the session rail (§3.19), clamping at both ends:
| Shortcut | Action |
|---|---|
| Alt+Shift+Left | Focus the rail group to the left of the one currently focused |
| Alt+Shift+Right | Focus the rail group to the right of the one currently focused |
- Alt+Up/Down/Home/End act on the focused group's transcript, whichever group that is
- Alt+Up/Down navigate relative to the visible area: previous means above the visible area, next means below
- Alt+Down past last message scrolls to bottom; Alt+Up past first message scrolls to top
- Jumped-to message scrolls to the top of the visible area and receives a brief highlight flash
- The right-hand column has no jump-to-top or jump-to-end binding - only step prev/next
- Browser Back and Forward move between rail groups too, but in visit order rather than the rail's ancestry order - stepping back can return to a branch no longer on the rail
2.4 Tab Interactions
| Shortcut | Action |
|---|---|
| Double-click tab | Maximize panel (toggle) |
| Middle-click tab | Close panel (except Chat) |
- Session header strip "+" button: creates new session in current browser tab, focuses chat; Alt+Click or middle-click opens new session in new browser tab
- "+" button has chevron dropdown with options: "New session", "New session in new browser tab"
- Where multiple side panels share a tab bar, that tab bar fades from a neutral dark on the left edge to the workspace accent color on the right edge
- Header buttons in those tab bars tint toward a brightened workspace accent color on hover when a workspace color is set; tint clears when no workspace color is set
2.5 Maximize Behavior
- Double-click saves full layout before maximizing
- Second double-click restores exact previous layout
- All panel sizes preserved after unmaximize
- Toggling an already-open side panel while maximized just unmaximizes (panel stays visible)
- Toggling a closed side panel while maximized unmaximizes and opens the panel
- Toggling the logs strip while maximized unmaximizes; if closed, also opens it
2.6 Session Header Strip
A horizontal strip at the top of the main panel that hosts session context (left) and global controls (right):
| Slot | Contents |
|---|---|
| LEFT | Session rail path: one entry per rail group, ordered by how each was started from inside the one to its left, each with that group's status dot, session name, and Stop button where that group owns its own container; the focused group's entry is visually marked |
| RIGHT | "+" new session button + chevron dropdown ("New session", "New session in new browser tab"); workspace switcher |
When the main panel renders a board view, the LEFT slot replaces the path with a board icon and the board's name; clicking the name copies the board's filesystem path.
- A browser tab hosts one session and the sessions it descended from, shown side by side on the session rail (§3.19); unrelated sessions still mean separate browser tabs
- Clicking a path entry's name focuses that group; clicking the focused entry's own name focuses the chat textarea
- Each entry's status dot color follows its own container lifecycle: green (running), amber (stopping), gray (stopped or no container)
- An entry's Stop button appears when that entry's session has a running container of its own; clicking while it is responding opens a confirmation modal, while idle stops it silently — the focused entry's own responding state is known directly, so it alone can skip straight to a silent stop
- A side conversation offers no Stop button of its own — stopping it ends only that conversation, never the one it came from; this holds regardless of whether it is the focused entry or elsewhere on the path
- Welcome state (no active session): the LEFT slot is empty; the RIGHT slot remains active
- The header strip stays visible while a panel is maximized
- The header strip has no right-click context menu — Stop is the only header-strip action; rename, pin/unpin, and "open in new browser tab" live in the SessionsPanel right-click menu
- Strip background fades from a neutral dark on the left edge to the workspace accent color on the right edge when a workspace accent is set; clears to a neutral dark when no accent is set
- Strip interactive elements (path entry name/Stop buttons, "+" new session split-button, workspace switcher trigger) tint toward a brightened workspace accent on hover when a workspace accent is set; tint clears to a neutral hover background when no accent is set
2.7 Confirmation Policy and Replace-While-Responding Toast
Confirmations are reserved for destructive actions — those that terminate or interrupt in-progress work. Non-destructive actions execute silently.
| Action | While Claude is responding | While idle |
|---|---|---|
| Stop session (header strip Stop button or SessionsPanel right-click) | Confirmation modal | Silent |
| Fork-here (whole session, from chat control bar) — same container | Confirmation modal | Silent |
| Rewind-here (per-turn, from message rewind button) — same container | Confirmation modal | Silent |
| Fork-browser-tab / Rewind-browser-tab (new browser tab) | Silent | Silent |
| Resume session (SessionsPanel click or Bookmark click) in current browser tab | Toast | Silent |
| New session in current browser tab | Toast | Silent |
| Workspace switch (when previous session was responding) | Toast | Silent |
| Browser tab close, page reload | Silent | Silent |
Confirmation modal:
- Title: "Claude is working"
- Detail: states the action and its effect (e.g., "Stopping the session will end the response. Continue?")
- Buttons: Cancel (returns without action) and Continue (proceeds with the destructive action)
Replace-while-responding toast: when the user navigates the current browser tab to a different session while the previous session was responding — and the navigation does not interrupt the response (resume, bookmark click, new session, workspace switch) — a passive toast appears:
- Text: "Session [previous name] still running"
- Click action: returns to the previous session
- Auto-dismiss: 5 seconds
- Does not appear when: the action is destructive (covered by modal instead), the action opens a new browser tab, or the action is browser back/forward navigation
Switching sessions in the current browser tab is instant — the previous session continues running in the background.
Progress label reflects actual action: "Starting session" for new sessions, "Loading session" when returning to an already-running session.
2.8 Main Panel
The center area of the workspace shows a single main panel whose content is selected by the active URL:
| URL hash form | Main panel content |
|---|---|
#/workspaces/{id} | Welcome content |
#/workspaces/{id}/sessions/{sessionId} (with optional /turns/...) | Chat for that session |
#/workspaces/{id}/boards/{boardId} | That board |
- The main panel shows exactly one of {welcome, chat, board} at a time; "chat" is the session rail (§3.19) - one or more groups, of which exactly one is focused
- No tab bar appears on the main panel — the Session Header Strip (§2.6) is its sole chrome
- Opening a board (via Boards Panel click, bookmark, or deep-link) updates the URL to
#/workspaces/{id}/boards/{boardId}and the main panel content swaps to that board - A bare workspace URL (
#/workspaces/{id}) shows welcome content in the main panel; the Session Header Strip remains visible - Switching between chat and board (or vice versa) follows the active URL — bookmark click, board sidebar click, deep-link, and browser back/forward all swap the main panel content
3. Chat Panel
3.1 Message Display
- Messages grouped into turns (user message + assistant response); when the right column shows the work view, a turn's assistant response is empty in the transcript for any turn whose tool calls all moved to that column, leaving just the user message
- While such a turn is still running, the transcript shows a working indication under the user message, outside any assistant bubble - no background, no border, no header, no timestamp; completion removes only that indication, and nothing else in the transcript shifts
- A turn that has not yet produced any content shows its working indication inside its own surface, matching the assistant bubble it will become
- Turn shows duration badge (live ticking while active)
- Duration format: compact ("5s", "1m 23s", "1h 5m 12s")
- Error turns have red left border
- Completed turns show final duration
- Pending turns render at reduced opacity
- Pending messages are scoped per session — switching sessions clears pending state
- Empty state: "Waiting for messages..."
- Assistant messages rendered as markdown (code blocks, inline code, lists, links, LaTeX math); the same renderer is used for ticket detail content so chat and ticket markdown look identical
- Messages may include common inline and block HTML — collapsible details/summary, keyboard keys, definition lists, figures, and tables with merged cells — which appears as formatted content rather than literal tag text
- A details block appears as an expandable section the reader can open and close
- Unsafe HTML in a message never runs: scripts, inline event handlers, and javascript: links are removed, and embedded frames and standalone vector graphics do not appear
- A link in a message opens in a new tab without giving the opened page access back to the app
- Large sessions with many turns stay responsive: only the turns near the viewport are built, so opening and scrolling a long conversation costs the same whether it holds twenty turns or a thousand
- Turns outside the viewport are not present in the page, so the browser's own find-on-page and Print/Save-as-PDF reach only the turns currently on screen; scrolling to a turn brings it back
- A session with a long history stays usable while it loads: the tab keeps responding, the page stays put, and the message box accepts typing throughout
Turn Progress Indicators:
- Active turn shows spinning ◐ symbol with "Working..." and animated dots
- When stopping, displays "Stopping..." instead of "Working..."
- Completed turns show green "✓ worked for [duration]" summary; appears only when the current runtime reports cost telemetry
- The compaction indicator appears only while a compaction is in progress, then clears when the compaction completes
- The auto-compaction indicator appears only when the current runtime fires pre-compact lifecycle hooks
Setting Change Dividers:
- Horizontal divider rendered between turns when model, permission mode, or effort level changes mid-conversation
- Effort level divider labeled
Effort: <level> - Amber divider appears at the resume point whenever a session resumes with prior messages in the chat; labeled
Restartedfor an ordinary restart, orForked from <parent>on the first viewing of a forked session - Reopening a session under a workspace whose runtime has changed since the session was created shows a red warning divider naming both runtimes, instead of silently running the new one
3.2 Input Behavior
| Feature | Behavior |
|---|---|
| Auto-resize | Textarea grows with content, capped at roughly ⅓ of panel height |
| Scroll compensation | Chat scroll adjusts when textarea shrinks (if not autoscrolling) |
| Draft persistence | Draft saved automatically per session |
| Editing shortcuts persist | Text shaped with a composer editing shortcut (tag-wrap, block collapse/expand, bracket auto-pair) is saved and restored exactly like typed text |
| Draft restoration | Only restored when textarea is empty (prevents overwriting user input) |
| Draft flush | Page close triggers immediate save of current draft |
| History | Up/Down arrows navigate submitted messages; edits update item in-place; persists across page reloads |
| History retention | History keeps only a bounded number of the most recent entries; once the limit is reached, the oldest entries drop as new ones are added |
| Draft stack | Down pushes to stack; Up navigates through drafts then history (non-destructive); edits update in-place; submit from draft removes it from stack and adds to history |
| Selection wrap | Typing ', ", `, (, [, or { with text selected wraps selection with matching pair; no effect without selection |
| Placeholder | No visible placeholder text |
| Always enabled | Textarea is always usable; user can type at any time regardless of session state |
| Always focused | Textarea has focus whenever the chat tab is active; focus is preserved when starting a new session, switching sessions, and finishing replay (mobile excepted, where the keyboard would pop up unsolicited) |
| Queue send | Alt+Enter queues message instead of sending; input clears for next message |
| Smooth while working | Typing remains smooth and immediate while the agent is working |
3.3 Slash Commands
- Typing
/at the start of the input opens the slash command picker, regardless of whether the input already contains other text - Case-insensitive substring matching
- Selection inserts command text
- Accepting a command via Tab or Enter places the caret immediately after the command and its trailing space; any text typed after the partial command is preserved
- The slash command picker is available on the welcome screen and lists the workspace's custom commands and skills; in-session it additionally lists MCP and built-in commands
- The new-session dropdown menu in the main area header is fully visible regardless of which side panels are open
- Double-clicking the main area header (outside its interactive controls) toggles the main area's maximize state, mirroring panel-tab double-click behavior
- Clicking the session name in the main area header copies the session directory path to clipboard and flashes a "Copied!" indicator
- The session directory tooltip is identical across the main area header, the sessions panel item, and the footer
- Clicking empty chat space focuses the prompt textarea; clicking message content does nothing and preserves OS-standard text selection (double-click selects the word, drag selects a range); selecting text in a message additionally shows a small floating quote button near the selection
- Stopping the active session immediately deselects it: the main area transitions to the welcome screen and the session appears as stopped in the sessions panel
- Slash commands in user messages render with bold weight; recognised commands also show a subtle dotted underline and a hover card with usage, description, and metadata; unrecognised commands render with bold weight only
- The slash-command autocomplete appears only when the current runtime supports skills; when unsupported, typing
/types the literal character with no dropdown
3.4 Following New Responses
| State | Behavior |
|---|---|
| User near bottom | View follows new content as it streams in |
| User moves the view off the bottom (scrolling, wheel, touch, Alt+Up/Down/Home/End, or a control-bar jump button) | View stops following immediately and stays where the user left it, even while new content arrives |
| View returns to the bottom (scrolling back, Alt+End, Alt+Down past the last message, or the control-bar jump-to-bottom button) | View resumes following new content; no jump-to-bottom button or other affordance |
| Scroll within code block / nested scrollable | View keeps following; only scrolling the conversation itself stops it |
| Click bookmark for active session | Stops following when the resulting position will not be at the bottom; if the target keeps the chat scrolled to the bottom, the view keeps following |
| Click a task in the Tasks panel | Governs whichever column the task's block landed in - stops that column's following when the resulting position will not be at the bottom, keeps it following when the target is at the bottom; the other column is untouched |
| Tab switch | Preserve scroll position |
| Session rename | Preserve scroll position across rename via chat control bar pencil, sessions panel right-click, or panel-tab right-click |
| During streaming | Scrolling feels as smooth as when no response is in flight |
3.5 Pending Messages
- Shown immediately after send (before server confirmation)
- Removed when server confirms the message
- Prevents duplicate display
3.6 Chat Control Bar
Control bar at top of Chat panel with two groups: with the terminal column shown, the bar divides at the column boundary - the two groups below sit left of it, and the terminal's own group sits right of it
Left group:
| Control | Icon | Action |
|---|---|---|
| Pin | Pin icon | Toggle pinned state for current session; pressed when pinned |
| Rename | Pencil icon | Enter inline edit mode to rename session; disabled when no session |
| Separator | ||
| Reload | Refresh icon | Restart session (picks up config changes) |
| Compact | Package icon | Send /compact message to trigger compaction; appears only when the current runtime supports manual compaction |
| Fork | Fork icon | Split-button: main button forks entire session (reuse container); chevron opens dropdown with fork variants. Alt+click or middle-click on the main button forks into a new browser tab. While a fork initiated from this control bar is in flight, the icon shows a spinner and both buttons disable — same as the per-turn rewind control. Appears only when the current runtime supports session forking. |
| Separator | ||
| Session Prompt | Note icon | Toggle dropdown editor for per-session prompt text |
| Auto-collapse | Chevrons-down-up icon | Toggle auto-collapse of earlier turns, keeping only the last turn expanded; on by default; pressed when on |
| Right column view | Two buttons: split-square-horizontal, wrench | The right column offers two views, terminal and work, plus off - a two-button picker where clicking a view's own button selects it and clicking the pressed one turns the column off, so only one view is ever shown; the terminal button carries the session's shell commands, the work button carries every tool call the agent made; both off by default |
Right group:
| Control | Icon | Action |
|---|---|---|
| Previous message | Chevron up | Jump to previous human message |
| Next message | Chevron down | Jump to next human message |
| Separator | ||
| Last message | Down-arrow-to-line | Scroll to bottom; pressed+disabled when autoscroll enabled |
| Separator | ||
| Minimap toggle | Map icon | Toggle minimap pinned/transient |
Terminal group (right of the division, present only while the terminal column is shown):
| Control | Icon | Action |
|---|---|---|
| Previous entry | Chevron up | Step to the nearest entry above the visible area |
| Next entry | Chevron down | Step to the next entry below the visible area |
| Last entry | Down-arrow-to-line | Jump to the terminal column's newest entry and resume following; pressed+disabled when already following - same semantics as the transcript's own |
| Overview toggle | Map icon | Toggle the terminal's own overview pinned/transient, independent of the transcript's minimap toggle |
Work group (right of the division, present only while the work column is shown):
| Control | Icon | Action |
|---|---|---|
| Previous turn | Chevron up | Step to the nearest working turn above the visible area |
| Next turn | Chevron down | Step to the next working turn below the visible area |
| Last turn | Down-arrow-to-line | Jump to the work column's newest entry and resume following; pressed+disabled when already following - same semantics as the transcript's own |
| Overview toggle | Map icon | Toggle the work column's own overview pinned/transient, independent of the transcript's and the terminal's minimap toggles |
3.7 Message Timestamps
- Each turn shows timestamp right of duration counter
- Format: relative ("2m ago", "1h ago"), full datetime on hover
- Timestamp corresponds to when the turn started
- No visual effects on hover (no icon change, no color change)
3.8 Collapsible Turns
- Click turn header to collapse/expand
- Collapsed: full user message + assistant first line + status + metadata, for a turn that has an assistant response; a turn whose response moved entirely to the work column has no assistant first line to show, since it has no assistant response left in the transcript
- Collapsed preview strips markdown to plain text (no raw
**bold**,# headers, etc.) - A turn whose blocks all moved to the work column shows a collapsed preview naming no tool count, since none of its tool calls are in the transcript to count
- When a reply's visible content is only code, only a table, or only an image, the collapsed preview shows the first line of that content instead, and the turn keeps its normal collapsed height
- Collapsed content remains searchable via browser Ctrl+F
- With auto-collapse on, only the last turn stays expanded; turning it off expands every collapsed turn, and when a new turn arrives the previously-last turn collapses; a turn you expand by hand stays open as new turns arrive, until you collapse it by hand or turn auto-collapse off and back on
3.9 Input Animations
Chat input border provides ambient state feedback:
- Empty and unfocused: Subtle ripple animation on border
- Working: Color-cycling border animation (shifts through hues)
- Focus: Glow box-shadow when focused
- Focus color: Breathing glow effect on border (green)
3.10 Mini-map
This section describes the transcript's own overview. The terminal column has a separate one - see Terminal overview below. On the session rail (§3.19), the minimap belongs to the focused group alone - an unfocused group has none.
Conversation overview sidebar (replaces native scrollbar):
Structure:
- Segments: One segment per compaction period; no gap between segments
- Sub-bars: Each turn is a sub-bar within its segment (no vertical gaps between sub-bars)
- Two alternating muted colors (blue-gray and purple) per segment
- White horizontal lines mark human messages (at start of sub-bar)
- Human line height proportional to human message size
Dimensions:
- Sub-bar height proportional to actual rendered height of turn content (scrollbar replacement)
- Sub-bar width relative to turn processing duration (normalized across turns)
Visibility:
- Rendered as overlay on top of chat, not at same level
- Auto show/hide on scrolling
- Auto show/hide when mouse near edge
- Transparent appearance (subtle, not distracting)
Animation:
- Show/hide animation: slower than default, smooth curve (not linear)
- Show fades in (0.3s); auto-hides after brief idle or mouse-leave
Interaction:
- Click to jump to that position in chat
- Drag to scroll continuously
- Visible-area indicator: translucent overlay showing the currently visible portion of the conversation
- The visible-area indicator slides smoothly as the user scrolls
- On opening a session, each subbar's size reflects its turn's content shape from the start and refines to the final proportion within a few seconds
Toggle:
- Toggle button in chat control bar (Map icon, after separator, rightmost in right group)
- Pressed state when minimap is pinned to always-visible
- When pinned: minimap stays visible (no auto-hide)
- When unpinned: minimap returns to transient show/hide behavior
- Toggle state persisted per session; default: pinned (always-visible)
- In every column that has one - transcript, terminal, work - a pinned overview keeps that column's own content ending clear of it, the same gap in each; unpinning returns the content to running underneath it on hover, as before it was pinned
Terminal overview:
With the terminal column shown, it carries its own overview down its own right edge, toggled from its own control-bar group and persisted independently of the transcript's minimap:
- One bar per command run in the session, oldest at the top, in the same order as the column; no segments and no human-message lines - those are compaction/turn concepts the terminal has no equivalent of
- Bar height is proportional to the command's share of the column's content
- Bar width reflects the command's duration, normalized across every command in the session
- Bar colour reflects the command's exit status; a still-running command's bar is present but carries neither a passed nor a failed colour until it lands
- Visibility, click-to-jump, drag-to-scroll, the visible-area indicator, and auto show/hide behave the same way the transcript's overview's do
- The two overviews toggle and persist independently - pinning or unpinning one never changes the other
Work overview:
With the work column shown, it carries its own overview down its own right edge, toggled from its own control-bar group and persisted independently of the transcript's and the terminal's:
- One bar per turn that routed something to the column, oldest at the top, in the same order as the column; no segments and no human-message lines, the same as the terminal's own
- Bar height is proportional to the turn's share of the column's content
- Bar width reflects the turn's duration, normalized across every working turn in the session
- Bar colour reflects whether any of the turn's calls failed; a turn with a call still unresolved shows neither a passed nor a failed colour until it settles
- Visibility, click-to-jump, drag-to-scroll, the visible-area indicator, and auto show/hide behave the same way the other two overviews' do
- All three overviews toggle and persist independently - pinning or unpinning one never changes another
3.11 Media Attachments
Attach files/images to messages:
| Feature | Behavior |
|---|---|
| Drag-drop | Drop zone on input area |
| Paste | Ctrl+V in textarea pastes images |
| Preview | Preview row above input with remove (×) buttons (thumbnails for images, file icons for others) |
| Max size | 10MB per file |
| Supported types | Any file type |
- Image attachments in message history appear correctly; an attachment-only send with an empty composer draws the thumbnails on the message's own surface, with no separate empty message box above them
- Click image attachment in message history to open zoom overlay
- Escape, backdrop click, or close button closes zoom overlay
3.12 Conversation Rewind
Fork conversation from any human message:
- Rewind button on human messages (top-right, visible on hover); appears only when the current runtime supports session rewinding
- Split-button: main button forks here (reuse container); chevron opens dropdown with variants
- Confirmation modal only when forking in same container while Claude is responding; all other forks execute immediately
- Fork button shows spinner while forking is in progress
- Modal confirm button shows spinner and is disabled while forking is in progress
- Original session preserved; new session auto-switched
- "Fork here" makes the new session the running one; the original session shows as not-running with its history still viewable; stopping affects only the new session
- "Fork in new tab" and "Fork in new browser tab" leave the original session running and start the new session as its own running session
- Forked sessions nest in the sessions panel under the conversation they were forked from, under the Conversations and All filters - normally that conversation's own row, or its source conversation when the direct fork point has no row of its own (a promoted side conversation nests under the conversation its side thread came from, since the thread itself is never listed); the Threads and Subsessions filters show what a session came from instead of nesting
- Forked sessions inherit every parent session setting — name, model, permission mode, effort level, session prompt — plus display metadata (timestamp, turn count, cost, message previews) on creation; values stay until the user changes them in the fork or the fork diverges naturally
Fork variants (available from both rewind button and control bar fork):
| Variant | Container | Navigation |
|---|---|---|
| Fork here | Reuse current container | Replace current view |
| Fork in new browser tab | New container | Opens in a new browser tab |
| Fork as a side conversation | Shared with the source | Stays in place |
A fork stands where the conversation it came from stood, and that conversation stays in the sessions panel under the conversation it was forked from.
Starting a side conversation keeps the source conversation running and does not add a row for it to the sessions list.
Full-session fork (control bar only): forks the entire conversation without truncation. Rewind button forks from the clicked message.
3.13 Copy Buttons
Copy buttons at multiple levels:
| Level | Content | Position |
|---|---|---|
| Turn bubble | Full turn content | Top-right of turn |
| Assistant message | Individual message | Right edge, aligned with message top |
| Code block | Code content | Top-right of code block |
All code blocks in the app have copy buttons (markdown, tool output, commands, etc.).
User message copy:
Copying a user message transforms special content to readable form:
| Content | Copied as |
|---|---|
| Slash command | /command args |
| Question response | Q/A text only, plus any note it was sent with |
| Command output | Output text only |
| Arbitrary XML | Unchanged |
3.14 Mermaid Diagrams
Mermaid code blocks render as visual diagrams:
```mermaidblocks render as SVG diagrams instead of code text- Toggle button switches between diagram and syntax-highlighted source
- Invalid mermaid syntax falls back to a syntax-highlighted code block
- A diagram that cannot be drawn shows a failure notice above its source, naming the reason
- Click diagram to open zoom overlay for inspecting complex diagrams
- The overlay opens showing the whole diagram, both axes - a diagram smaller than the viewport opens at its natural size rather than enlarged to fill it
- A zoom in, zoom out, fit, and four directional controls sit in the overlay's bottom-left corner
+/=/-zoom the same way the buttons do; the arrow keys pan the same way the directional controls do; both leave the page behind the overlay unscrolled- Scrolling the wheel over the diagram zooms about the pointer - whatever was under it stays under it; pressing and dragging pans, following the pointer
- Zooming stops at a minimum and a maximum; the control at whichever bound is reached reads unavailable
- The fit control returns to the opening view in one action; closing and reopening the overlay always starts at that view too, never wherever it was left
- Escape or backdrop click closes zoom overlay; a drag that merely ends over the backdrop does not
- Diagram colors match dark theme palette
- Copy button copies raw mermaid source
- Non-mermaid code blocks unaffected
3.15 Session Prompt
Per-session editable text re-supplied to Claude after each compaction so it persists across long conversations:
| Feature | Behavior |
|---|---|
| Button | Note icon in control bar left group, after Compact |
| Blue badge | Dot on button when content is set |
| Dropdown editor | Opens below button, left-aligned; textarea with monospace font |
| Save | Content saved on close (click outside or Escape) |
| Clear | Empty/whitespace-only text clears the prompt |
| Persistence | Survives refresh and resume |
| Compaction | After compaction, prompt re-supplied to Claude |
| Disabled | Button disabled when no session loaded |
3.16 Message Queue
Queue messages for sequential delivery while Claude is responding:
- Queued messages appear as dimmed inline bubbles below the current response
- Queued bubbles show send now (⇒), edit (✎), and cancel (✕) buttons on hover
- Send now sends a queued message immediately, skipping queue order
- Queue drains FIFO — each completed reply or compaction boundary auto-sends the next queued message; replies replayed while a conversation is still loading do not
- Interrupt pauses all queued messages (won't auto-send)
- Error pauses all queued messages
- Paused bubbles show re-queue (▶) and cancel (✕) buttons
- Edit returns message content to input textarea; message removed from queue
- Cancel removes message from queue
- Re-queue returns paused message to active queue
- Enter sends immediately, bypassing queue; queued messages send after response completes
- Session switch restores that session's queued messages from storage
- Queue persists per session; survives page refresh
- Queued messages preserve attachments
3.17 Inline Replies
Quote any part of a turn - prose, code, tool output, or a thinking block - and reply beside the quoted span. A reply either sends on its own, without touching the conversation, or joins the others in the buffer to go out together as one turn. Quoting and replying are desktop-only.
- Selecting text anywhere in a turn - prose, code, tool output, or a thinking block - and clicking the quote button paints a durable highlight on the quoted span and opens a reply box beside it, pre-filled with the quoted text and its source (the user or the assistant) and with the reply field focused and empty
- Unsent replies accumulate, each editable in the reply box beside its quoted span; a reply can be deleted, which clears its highlight; the unsent replies and their highlights are restored after a page reload or a return to the session
- Sending from the message box delivers one turn carrying every reply still buffered there, plus the composer message and any attachments; each sent reply's highlight stays on its quoted span and its reply is shown read-only when the span is hovered or clicked; the send-turn shows a compact "Replied inline - N comments" placeholder that expands in place to reveal each quote and its reply; comments left with a blank reply are omitted; a reply-only send with an empty composer draws the placeholder on the message's own surface, with no separate empty message box above it. A reply already answered on its own is never part of this send
- The placeholder is display-only: its wording never appears as raw text in the transcript, and it is the quote-and-reply pairs, not the placeholder, that reach the assistant
- The quoted span shows a dotted underline over a subtle fill and stays highlighted for the rest of the session and across reload; hovering a highlighted span briefly shows its reply beside the span, and clicking the span opens that reply box and clicking it again closes it; a reply sent from the message box shows read-only once sent, still editable while unsent, and its highlight is permanent; a reply answered on its own keeps showing its whole exchange and stays editable for a follow-up, however long ago it was asked - until it is promoted, after which it shows that same exchange permanently read-only with no reply field. Promoted onto the rail (below), clicking its span focuses that group instead of opening a box, and hovering shows the quote and its opening reply read-only with a control that does the same
- Each reply box opens beside its highlighted span and stays beside it as the transcript scrolls; several reply boxes can be open at once without overlapping one another; hovering a highlight shows its box briefly, clicking the highlight opens the box and clicking it again closes it, and its close button also dismisses it - closing a box whose reply is still empty discards the quote and its highlight; a box holding its own answered exchange also offers two controls to promote it into a full group of its own, gone again once either is used, leaving only the close button. A reply promoted onto the rail has no box at all - its highlighted span is what reaches it from then on
- A reply box opened near the edge of the conversation slides inward to stay fully visible instead of narrowing
- Reply boxes are the same width wherever their quote sits
- The reply box supports the same text-editing keys as the message box: wrapping a selection, continuing a markdown list on a new line, indenting and dedenting, collapsing and expanding a block of text, auto-pairing quotes and brackets, and interrupting a response - each behaves exactly as it does in the message box
- Message history, stash, and slash-command autocomplete stay with the message box; arrow keys in a reply box move the caret instead
- A collapsed block of text left in a reply is delivered in full when sent, never as its collapsed placeholder
- Answering a reply on its own, rather than sending it with the others, asks right there beside its quote and shows the answer arriving in the same box; the conversation it was quoted from is unchanged throughout - same turns, same count, no placeholder added for it
- A reply box asking on its own does not stop or wait for the conversation it was quoted from, whether that conversation is idle or already answering something else
- A box shows only the exchange it asked for; the conversation it was quoted from answers in the conversation, never in the box, whichever one is still arriving when the other finishes
- Reloading the page while a reply's own answer is arriving picks the box back up mid-answer rather than freezing it at the moment of reload, and the rest keeps filling in; reloading after it has finished shows the whole exchange, question and answer together
- Answering one reply on its own leaves every other buffered reply exactly as it was - still unsent, still editable, unaffected by the one that was asked
- A reply answered on its own stops - however that answer ends, whether it completes, fails, or is interrupted - and typing a follow-up and pressing Enter starts it answering again with the whole earlier exchange still in view. This holds for a thread still in its float; once promoted onto the rail, it runs until stopped like any other group, the same as the conversation it came from
- The follow-up field never locks while a box's own answer is still arriving - typing and pressing Enter work exactly as they do once it has finished, starting the next exchange immediately rather than waiting; each exchange's own text stays under the question that asked for it
- A reply answered on its own can be promoted into a full session of its own, opening in a new browser tab; the reply box stops where it was, still showing everything said up to that point, permanently read-only, with a link to where the conversation continues, and stays that way across a reload
A reply answered on its own has three destinations:
| Destination | Container | Where it lives |
|---|---|---|
| Stays in its float | Shared with the source | Beside its quote, in the source conversation |
| Promoted onto the rail | Shared with the source | A group on the source conversation's own rail, focused |
| Promoted to its own session | New container, new browser tab | Its own conversation |
Promoting a reply onto the rail gives it its own group there, focused, with the conversation it was quoted from immediately beside it, reading; the group is an ordinary child session in every respect but one - it opens at its own exchange, with what it inherited standing behind one line
That line names the conversation the turns came from and how many turns are behind it; clicking it reveals them in place, and clicking again folds them back - in every reading of the group, and again after a reload
Whichever of the three destinations a reply answered on its own takes, it is listed the same way in the sessions panel (§5.1 owns the filters that decide how; proven there, not here)
3.18 Right Column (Terminal / Work)
The chat content area can split into two columns: the transcript on the left, and one of two
right-column views - desktop only. The two views are mutually exclusive: one right slot, one
occupant. On the session rail (§3.19), this split belongs to the focused group alone - every
claim in this section describes that group; an unfocused group mounts no right column at all,
which is the state claim:chat:terminal-split-toggle-off already describes for the split off.
Shared by either view:
- The chat content area shows two columns of equal width, with a draggable boundary between them
- Dragging the boundary between the columns resizes both live; neither column can be dragged below a minimum width
- The boundary position is restored after a page reload
- The boundary between the columns extends up through the control bar, dividing it at the same point, including while the boundary is being dragged; when the column is hidden - by the picker, by a narrow panel, or on a phone - the bar is undivided
- The bar never appears undivided and then divides, or divides at the wrong place and then moves - it is absent until the session's layout is known, then appears already divided
- The chosen view - terminal, work, or off - is restored after a page reload, and each session remembers its own choice independently of any other open session
- While a session is loading, one screen covers the whole chat content area - transcript, boundary and right view together - with no right view drawn beside it; the split is already in place underneath, so lifting the screen reveals it settled rather than reflowing into place
Terminal view:
- A shell command the assistant runs appears in the terminal column instead of as a block in its turn; every other tool call still renders in its turn exactly as before
- A terminal entry shows the model's description as a dimmed comment line above the command, then the command on a prompt line, then its output beneath; a call with no description starts directly at the command
- A terminal entry's lines are never broken to fit the column; a line wider than the column scrolls sideways on its own, independent of the rest of the entry
- A command the tool reports as failed is marked on its command line; its output still shows beneath it
- A command the tool reports as failed is identifiable from the terminal's own overview without scrolling to it
- Hovering a terminal entry reveals a jump button alongside a copy button; the copy button copies that command alone
- The hover controls sit level with the entry's first line, whichever it is - the description comment when there is one, the command otherwise
- A terminal entry appears as soon as its command text arrives, before the command completes; its output fills in beneath it once the call lands
- A terminal entry's output is coloured when its content is recognisable (e.g. JSON), the same way an inline tool block's output is; unrecognisable output, including markdown-looking text, stays plain
- The terminal column shows every shell command run since the session started, oldest first, regardless of which turn ran it
- Entries outside the viewport are not present in the page, so the browser's own find-on-page and Print/Save-as-PDF reach only the entries currently on screen; scrolling to an entry brings it back
- The terminal column scrolls to a newly landed entry when it was already scrolled to the bottom, and stays where it was left when it was scrolled up
- The terminal column opens scrolled to its newest entry and follows further output until the reader scrolls away - on opening a session, and on choosing the terminal view mid-session - whether or not the URL names a turn
- While a shell command is still running, the terminal column stays scrolled to the bottom as its output arrives, not only once the command finishes
- Clicking a terminal entry's jump button scrolls the transcript to the turn that ran it and highlights it, including when that turn is not currently mounted; an entry belonging to a turn the transcript cannot address shows no jump button
- Stepping to an entry, by button or by Alt+PageUp/PageDown, lands its top edge at the top of the column and flashes it; stepping past the last entry settles at the end and re-engages following, stepping past the first stays at the top; stepping away from the end stops the column following, and stepping back to it resumes following
- A session that has run no shell commands shows the terminal column with a message stating none have run
- A subagent's shell commands stay nested inside its own activity section in the transcript and never appear in the terminal column
- Turning the right column off restores every shell command inline in its turn, with the command and its output intact - one of the picker's three positions, and the choice is restored after a page reload
Work view:
The work view carries every tool call the agent makes, in chat's own block UI - a Bash call looks exactly like the Bash block it would have been inline, with header, description, Command and Result sections, not a terminal entry.
- Every top-level tool call the agent makes appears in the work column, in call order, and none of them appears in the transcript; the transcript keeps the user's messages, the assistant's prose, and its thinking
- A work-column block looks and behaves exactly like the same block does inline, including expanding to its own output with the same default collapsed or expanded state
- A subagent's own calls stay nested inside its Task block; the Task block is what moves to the work column, and the subagent's calls are not listed separately alongside it
- The work column shows every tool call since the session started, oldest first, grouped by the turn that made it
- Entries outside the viewport are not present in the page, so the browser's own find-on-page and Print/Save-as-PDF reach only the entries currently on screen; scrolling to an entry brings it back
- A session that has used no tools shows the work column with a message stating none have run; a brand-new session shows the same message before anything is sent
- Clicking a work-column block's jump affordance scrolls the transcript to the turn that made the call and highlights it, including when that turn is not currently mounted
- The work column scrolls to a newly landed call when it was already scrolled to the bottom, and stays where it was left when it was scrolled up
- The work column opens scrolled to its newest entry and follows further calls until the reader scrolls away - on opening a session, and on choosing the work view mid-session
- While a turn is still making calls, the work column stays scrolled to the bottom as each one lands, not only once the turn ends
- The work column's following state is its own - scrolling the transcript never disengages it, and scrolling it never disengages the transcript's
- Stepping to a turn, by button or by Alt+PageUp/PageDown, lands its top edge at the top of the column and flashes it; turns that did no work are never a stop; stepping past the last working turn settles at the end and re-engages following, stepping past the first stays at the top; stepping away from the end stops the column following, and stepping back to it resumes following
- Clicking a task in the Tasks panel lands its block's top edge at the top of the work column and flashes it, the same landing the step controls use; the transcript does not move. Landing off the bottom stops the work column following; landing on the newest task leaves it following
3.19 Session Rail
Depth has its own axis, separate from the transcript/right-column split above. A session that spawned children - a side thread promoted to its own session, or a sibling an agent started, and only those two - shows them alongside it on a horizontal rail, root at the left:
- Forking a conversation, by any variant, gives the new conversation the place its source held, keeping any groups that stood to the source's left
- The rail orders its groups by how each was started from inside the one to its left, root at the left, ending at the group currently focused
- Exactly one group is focused - the one the reader writes into, the only one that splits into transcript plus right column, and the only one with its own message box and control bar
- Every group other than the focused one shows one column: its conversation, with tool blocks and compaction and interrupt markers inline, no divider, no right column, no control bar, no message box
- A group other than the focused one shows the conversation as it stood when the rail last read it; it takes up where it left off, with the newest messages there, once it becomes the focused group
- Drilling into a child pushes a new group to the rail's right and gives it focus; the group the reader drilled from stays on the rail, now reading
- Focusing a group already on the rail brings the group that was focused a moment ago along for the ride, reading, to its side
- Drilling into a different child after focusing an earlier group ends the rail at that group and pushes the new child next; the branch left behind is no longer on the rail
- Beyond a certain depth, the rail shows the root and the nearest groups to focus; the ones between them are reachable from the session header path (§2.6) instead of taking up rail width
- Each group other than the focused one holds a fixed column width; the focused group takes what remains and never drops below one transcript column - a group scrolls off the rail's edge before the focused group's transcript is squeezed at all (computed-width comparison; proven visually, not functionally)
- Drilling deep enough that the groups no longer fit scrolls the rail sideways and brings the focused group fully into view (scroll-position geometry; proven visually, not functionally)
- Opening a side panel, or narrowing the window, until the focused group cannot hold both its columns collapses its split before its transcript would go below one column's width; its right-view toggle still reads as on (computed-width threshold, the same class as the existing split-collapse claim; proven visually, not functionally)
- The message box sits inside the focused group, under its columns; a group other than the focused one has none
- The message box moves with focus, taking keyboard focus with it; each group keeps its own draft, history, and queue independently
- Sending reaches the focused group's session alone; no other group's conversation changes
- Scrolling one group moves only that group; its neighbors hold their own position (two independent scroll-position comparisons; proven visually, not functionally)
- Each group remembers its own divider position and its own right-view choice, independent of every other group on the rail
- The rail survives a reload - the same groups return, in the same order, with the same one focused
- A branch left behind by focusing an earlier group belongs to the browser tab it happened in; a second browser tab open on the same tree keeps its own rail, and neither tab's left-behind branch appears in the other
- Opening a child session's own URL directly gives that session focus, with its ancestors on the rail beside it and nothing to its other side
- The moment a child session's URL opens, the focused group is already there; its ancestors fill in beside it as they arrive, without moving the focused group once it has painted
- A group whose own session has stopped keeps its place on the rail and keeps reading; only its status dot in the session header path changes
- A group whose conversation cannot be read keeps its place on the rail and states that it is unavailable, rather than being dropped from the chain
- A group appears on the rail regardless of whether the Sessions panel would list it on its own
- Among groups that began inside another conversation, the rail draws no distinction between how each came to exist - a reply answered on its own, promoted onto the rail (§3.17), reads like any other
- Stopping the focused group's session returns focus to the group it descended from; stopping the root group's session returns to the welcome screen
- Stopping a group other than the focused one, from its entry in the session header path, leaves the focused group running
- No rail on a phone or tablet - one session at a time, as elsewhere on touch
4. Tool Display
Note: Wireframes in this section are schematic. Actual rendering uses CSS-styled elements (colored bullets, borders, animations) rather than the literal symbols shown.
4.1 Tool Block Structure
[Icon] Tool Name | Summary────────────────────────────Expanded content (if clicked)Tool Bullet Colors:
- Pending: cyan with pulsing animation
- Completed: green (solid)
- Error: red
4.1.1 Block Timing
Each block shows inline timing information in the header line:
- Completed tool blocks: offset only, e.g.
@ +8s - Thinking blocks: relative offset only, e.g.
@ +3s - Pending tool blocks: duration after 30s + offset, e.g.
32s · @ +8s - Background tasks: no timing displayed (tracked in Tasks panel)
- Nested tool blocks: timing relative to parent turn start
- Timing displayed right-aligned in the header line, muted color
- Relative offset = time from turn start to block completion (or start if pending)
4.2 Tool-Specific Formatting
| Tool | Header | Summary |
|---|---|---|
| Read | Read(filename) | Line count; warning if present |
| Edit | Edit(filename) | Diff summary ("+N, -M") |
| Write | Write(filename) | "Wrote N lines" |
| Bash | Bash(description), falling back to Bash(command) when none was given | Line count, output preview (single-line), or "Done" (empty) |
| Grep | Grep(pattern) or Grep(pattern:path) | Context-aware count (see below) |
| Glob | Glob(pattern) | File count |
| Task | Task(description) | Status/first line |
| Skill | Skill(name) | "Launching skill: {name}" |
| WebFetch | WebFetch(url) | First line of result |
| WebSearch | WebSearch(query) | First line of result |
| TodoWrite | TodoWrite | Diff counts: ● 2 ◐ 1 ○ 3 ✕ 1 |
| MCPSearch | MCPSearch | "Tool loaded" or "Found N tools" |
| AskUserQuestion (once answered) | AskUserQuestion(N questions) | Question count |
| ExitPlanMode | ExitPlanMode(title) | Plan title (first heading, truncated if long) |
| TaskOutput | TaskOutput(task_id) | Status: Running/Completed/Failed/Timeout/Killed |
Skill Output:
- Skill body content displays inside the Skill tool block's expandable content
- Skill body stays attached to its tool block regardless of intervening tool results
MCP Output:
- A result made of several pieces shows every piece, in the order the result lists them
- Prose renders as text; markdown renders as markdown - headings, lists, code fences
- A piece that is itself a JSON document still shows as a JSON tree
- An image shows as an image
- A linked resource shows its name, its description and its URI
- Content the app cannot display (audio, a binary resource) is named by its media type rather than shown as an empty box
Saved Output:
- Large tool results show file path and size
- Preview content displayed when expanded
- Very large tool output truncated; truncated blocks show expand and download buttons
- Download button on saved-output blocks
Background Tasks:
- Background tasks show "Background task running" status
- Output file path displayed as informational text
Grep Output:
Summary varies by output mode:
| Mode | Summary Format |
|---|---|
| files_with_matches (default) | "X files" |
| content | "X matches" |
| count | "X files with matches" |
Visual styling for expanded Grep output:
- Match lines (
:separator): highlighted background with left border accent - Context lines (
-separator): dimmed text (reduced opacity) - Highlight extends full line width on horizontal scroll
- Pagination metadata stripped from output
4.2.1 File Path Display
- File tools (Read/Edit/Write) show filename only in collapsed header
- Collapsed: hover shows full path in tooltip
- Expanded: header shows full path instead of filename
/tmppaths highlighted across all content (tool output, messages, code blocks); click copies path- General file paths highlighted when resolved to unique workspace match; click copies absolute path
- Alt+Click a highlighted path to open it in your editor instead of copying it
- With no editor configured, Alt+Click copies the path like an ordinary click
- File tool blocks offer a control that opens the file in your editor
- With no editor configured, no such control appears
- The control opens the file at the read's starting line when one is known
4.3 Interactive Tools
AskUserQuestion:
- Renders form with single or multi-select options
- Always includes "Other" with text input
- "Other" textarea auto-resizes as user types (like main chat input)
- No placeholder hint text in "Other" textarea
- Submit button disabled until user makes a selection
- Selecting "Other" option auto-focuses the text input
- Submit sends answer
- Alongside your choices you can type a message; sending delivers both as one turn, together with any attachments and any inline replies you have waiting
- User's selection shown immediately after submit
- The answer and the message it was sent with are both shown in the transcript
- The message sent with an answer appears in the same bubble as a message sent on its own
- After submit, highlight what was answered (selected option or custom text)
- Tool block collapses after submitting response
- Q/A visual separation: visually distinguish questions from answers, separate pairs
- Previously answered questions show read-only "Answered" display
- Form disabled when follow-up human message exists in conversation
- While a question awaits an answer, only the form appears; no block header above it
- Answered questions show no error styling, even when the question tool reported a failure
- With a choice made, sending from the message box submits the answer and the message together; with no choice made, sending leaves the question unanswered and delivers the message on its own
- A question awaiting an answer shows its form with no error styling, even when the question tool reported a failure
ExitPlanMode:
- Displays plan content as markdown
- Default expanded for user review
- Approve/Reject form rendered below plan content
- Approve and Reject options, plus "Other" for free-text feedback
- Submit button disabled until user makes a selection
- Submit sends the response
- Summary shows "Approved", "Rejected", or "Answered" based on selection
- Plan content re-expandable after answering (unlike AskUserQuestion)
- Form hidden after submit; block auto-collapses
- Form disabled when follow-up human message exists in conversation
4.4 Nested Tool Blocks
- Task tool can contain nested tool calls
- Displayed as indented tree with connectors
- Auto-collapse when task completes
- The subagent's own prose appears in the Activity list too, interleaved with its calls in the order it happened, rendered as markdown the same way an assistant's prose renders in the transcript - no clamp, no per-entry collapse
4.4.1 Realtime Nested Display
Nested tool calls in Task blocks display progressively in real-time:
| Event | Display |
|---|---|
| New nested tool call | Nested block appears with pending spinner |
| Nested tool completes | Nested block updates with result summary |
| Subagent narrates | Its prose appears in place, alongside the calls |
Behavior:
- Task blocks collapsed by default during execution, the same as every other tool
- Once expanded, nested tools appear immediately as they stream in, not deferred until Task completion
- Pending nested tools show cyan pulsing bullet with spinner
- Completed nested tools show green bullet with result summary
- User can expand a running Task by hand to watch it live, and collapse it again
- A collapsed running Task's header shows a one-line activity feed: a status dot and title for the newest nested call, or the newest line of narration for prose
- The activity line always reflects the most recently arrived nested item, replacing whatever it showed before
Collapsed Task during execution:
◐ Task(description) ● Bash(check pytest status) [▶]Expanded Task during execution:
◐ Task(description) [▼] ● Read /src/file.py <- completed └ Read 50 lines The file confirms it - trying the other module next. ◐ Grep "pattern" in /src <- in progress └ 🔄4.5 Expandable Content
- Click tool header to expand/collapse, wherever a header is shown
- Collapsible content based on content length
- Default collapsed: JSON, Read, Grep, Skill, WebSearch, WebFetch, TodoWrite, TaskOutput, Task, MCP results
- Default expanded: ExitPlanMode; a question awaiting an answer shows its form immediately
4.6 Thinking Blocks
- Clickable header shows first line as preview (truncated with ellipsis, no quotes)
- Expands to show full content as formatted Markdown
- Expanded content replaces the ellipsized preview line in place
- Uses hollow circle bullet (○) to distinguish from tools
4.7 Compaction Blocks
- Displayed when context compaction occurs
- Shows
128K tokens, auto_compacton one line (token count + trigger reason) - Expandable summary of what was compacted
- Uses circled dot bullet (◎), animated spinner while compacting
- When the right column shows the work view, the compaction marker appears once in the transcript and once in the work column, at the corresponding point in each timeline, and each expands independently of the other
4.8 Tool Input Display
- Hover on tool header shows full input as tooltip, wherever a header is shown
- Bash tool: the command appears in the header (or its description, when given) and, expanded, in its own "Command" section above the output
- Bash header shows the description of what the command does, falling back to the command itself when none was given
- Expanding a Bash block shows the full command in its own section above the output
- A Bash block shows its command while the command is still running
- A Bash block's command is shown without line numbers
- Unhandled tools (no specialized formatter) show tool input as collapsible "Input" section in expanded content
- Input section rendered above tool output
- Input section expanded by default when tool block is expanded
- Input section visible while tool is pending (shows what was sent before result arrives)
- Input section is omitted when the tool input is empty (
{}) - Handled tools (Read, Edit, Write, Bash, Grep, Glob, Task, etc.) use their specialized formatters and omit the generic input section
- Unhandled tools wrap output in collapsible "Output" section (symmetric with "Input" section)
- A Bash block's command and its output are shown in the same fixed-width type as other code, on a single surface
- A shell command appears in the terminal column while the terminal view is on, in the work column while the work view is on, and as a block in its turn while the right column is off
- Every other tool call likewise appears in the work column while the work view is on, and as a block in its turn otherwise
4.9 Todos Details
-
When several task creations or updates land in a row from the same source, the chat shows them together inside a single "Todos" panel; inspection-only task actions (looking up an existing list) render as ordinary tool blocks instead. When another action appears between two task updates, the chat shows a separate "Todos" panel before and after it
-
The "Todos" panel uses the standard tool-block chrome: a header line showing the label
Todosand a summary line showing a count for each state that has at least one task; the panel opens expanded and clicking the header collapses the row body -
Each task appears once on its own row, showing its latest state from that group of updates
-
A task waiting on another task shows
⊘; once everything it waits on is done, the icon goes back to the task's own state icon -
State icons:
○pending,◐in progress,●completed,✕removed -
Removed tasks appear muted with strikethrough
-
When a task has a description, the description appears in a third column on the same row as the title, truncating with an ellipsis when it overflows; hovering the description surfaces the full text
-
Rows in the "Todos" panel align across the group: the state-icon column, the title column, and the description column have the same width on every row
-
The "Todos" panel opens with its row body visible; collapsing it folds the rows away
-
When the "Todos" panel would have nothing to show, the panel does not appear in the chat at all
-
Task prompt expanded by default for running tasks; auto-collapses when task completes; past completed tasks show collapsed with truncated first-line preview
-
Click prompt header to reveal full multi-line prompt text
4.9.1 Lookups Details
- A turn's file reads, searches, and other read-only calls appear together in a single "Lookups" panel placed after the turn's last block
- A single lookup in a turn appears as an ordinary block, in place
- The "Lookups" panel uses the standard tool-block chrome: a header line showing the label
Lookupsand a summary line showing a count for each kind of call it holds; the panel opens collapsed and clicking the header reveals the row body - Each row expands on its own, showing that call's output the same way it would as a standalone block
- Rows appear in the order the calls happened
- A subagent's own lookups stay inside its Task block, not pulled into the turn's "Lookups" panel
4.9.2 Tool-Schema Search
- A tool-schema search is not shown in the conversation unless it failed
4.10 Task Block Behavior
- Click anywhere on Task header to expand/collapse
- Loading spinner vertically aligned with text
- A hand toggle on a running Task, expanded or collapsed, survives its next nested event arriving
4.11 Write Tool Display
Match Read tool styling:
- Show actual written content, not just success message
- Syntax highlighting based on file extension (
.py→ Python,.js→ JavaScript) - Same line number gutter styling as Read
- Verbose confirmation header not shown; content displayed directly
4.11.1 Edit Diff Display
Inline character highlighting for changes:
- Consecutive add/remove line pairs show word-level diff
- Changed characters within paired lines highlighted (like GitHub word-diff)
- Unrelated add/remove lines show full-line highlighting
4.12 System Reminders
Extract and render system reminders separately:
- System reminders extracted from main content
- Render each unique reminder as separate collapsible section
- Default collapsed with "System reminder" label
- Identical reminders deduplicated by exact text match; shown once with ×N count badge
- Header shows count of unique reminders
- Applies to all tool results and message content
4.13 Tool Error Display
- Error message shown in red subtitle line
- When full error fits in subtitle, suppress duplicate code block below
4.14 Read Tool Line Numbers
- All lines aligned consistently (first line not misaligned)
- Line numbers right-aligned in gutter
4.14.1 Code Block Gutter Behavior
Applies to Grep, Read, Write tool output:
- Gutter is sticky during horizontal scroll
- Gutter width matches the highest line number in the block (3-character minimum), constant across every row
- Gutter background extends to all container edges (no gaps at corners)
- Line highlighting: match/active lines have distinct background, gutter accent
4.15 Local Command Output
Render command output blocks from user messages:
- Collapsible, expanded by default
- Header shows "stdout" or "stderr" based on content type
- stderr content in red/warning styling
- Markup stripped from visible content
4.16 Background Task Notifications
Background tasks show status updates in the original Tool block:
| Status | Icon | Color | Summary |
|---|---|---|---|
| running | ● (cyan pulse) | default | "Background task running" |
| completed | ● (green) | green | Summary text |
| failed | ● (red) | red | Summary text |
| killed | ● (yellow) | yellow | Summary text |
- Status updates correlate to their originating task across turns
4.17 Background Task Consolidated Rendering
Render background tasks as single consolidated blocks:
- Single block per background task (like synchronous Task rendering)
- A single block covers the entire background task's tool calls and output
- TaskOutput blocks still appear inline in assistant messages for narrative flow
- Example: "Let me check again:" →
● TaskOutput(ab58f94) └ Completed
- Example: "Let me check again:" →
- Clicking in-progress tasks expands to show details
4.17.1 Background Task Nested Tools
Background tasks show nested tool calls streaming in real-time, identical to foreground tasks:
- Nested tools appear with spinner as they start
- Nested tools show result summary when complete
- Visible immediately during background execution
- Preserved after session reload
- Each nested call and each line of narration appears once, however many times the session recorded it - including after a reload or a restart mid-task
- The subagent's own prose appears in the Activity list too, interleaved with its calls, the same as a foreground task's
- While pending, a background task's header shows the same one-line activity feed as a foreground task's
Wireframe:
● Task(background-research) [ab58f94] ⟳├─ Prompt: "Research the codebase..."├─ ● Read(/src/file.py) ✓│ └ Read 50 lines├─ ◐ Grep("pattern") ⟳│ └ 🔄└─ Status: Running in background4.18 Code Block Rendering
Tool output with code or text content:
- Known file types: syntax highlighted by extension
- Unknown content: auto-detected language, highlighted if recognized
- Markdown files and markdown-like output render as formatted text (headings, lists, links) instead of raw code
- Hovering a markdown block reveals a toolbar with a source toggle and copy button
- Source toggle switches between rendered markdown and syntax-highlighted code view
- Copy button copies the raw markdown source
- Plain text: displayed as monospace text
5. Sessions Panel
5.1 Session List
- Shows all sessions (newest first)
- Each row: status dot (green/gray), ID (first 8 chars) + name (if set), time ago, turns, cost
- A row for a session whose runtime is known also shows that runtime's name
- Resume button (Play icon) shows a spinner from click until the tab switch / new browser tab paints; disabled while spinning
- Hovering turns / cost / each timestamp segment reveals informative tooltips: "Turns — N", "API cost this session — $X.XX", "Started — …", "Last active — …"
- Clicking session ID copies full session directory path to clipboard; shows "Copied!" briefly
- Preview of first and last messages (last prefixed with "...")
- Auto-refresh when sessions change
- A session whose container has stopped shows as stopped (gray dot), never stuck on "stopping"
- Current session row highlighted
- Loading state: "Loading..."
- Error state: "Failed to load sessions" with Retry button
- Empty state: "No sessions yet"
- Sessions with 0 turns hidden from list (except active session)
- Three-tier sort: pinned first, then unpinned-with-container by max descendant timestamp, then unpinned-without-container by max descendant timestamp
- Fork activity bubbles up via max timestamp across all descendants
- After "Fork here", the running indicator moves from the original session to the new one; the stop button hides on the original session
- Starting a side conversation leaves the original session's running indicator exactly where it was; no row is added for the side conversation
- Active fork auto-expands ancestor chain in session tree; pinned active session collapses all
- Hover on truncated session name shows full name in tooltip
- Six filters sit on the panel's button row, each an icon with a count badge and no visible name; hovering one shows its name in a tooltip: Conversations, Named, Pinned, Threads, Subsessions, All. Hidden while the search box is open
- When the filters do not all fit, the row scrolls sideways instead of clipping - by wheel, trackpad, touch, or drag - with no scrollbar visible at rest or while scrolling
- A chevron appears on whichever side has more filters beyond it, and is gone from a side once scrolled fully to that end
- The chosen filter always ends up fully in view, whether it was reached by scrolling and clicking or by the auto-switch to All
- Conversations (default): the sessions the reader started, with forks nested underneath
- Named: only sessions given a name by hand
- Pinned: only pinned sessions
- Threads: side conversations opened from a quote popup, each showing what conversation it came from
- Subsessions: sessions started by an agent on another agent's behalf, each showing what session started it
- All: every session, of every kind, in one tree
- Each filter's count matches the number of rows it lists
- Choosing a filter with nothing in it shows a message saying so, not a blank area
- Opening a session the chosen filter does not list shows All until a session it does list is opened; nothing else moves the filter, including a session ceasing to be listed after the filter was chosen
- The filter the reader chose survives a reload; a move to All the panel made for itself is not remembered
- A search control sits between the new-session chevron and refresh; clicking it opens a box across the header row and puts focus in it
- The search box matches a session by name or by id, case-insensitively, whether typed or pasted in full
- A search is found whether or not the chosen filter would have listed it - it spans every session
- Search results are a flat list: no session is nested under another, no unmatched parent appears as context, and a pinned fork that would otherwise appear twice appears once
- A search with no matches shows a message saying so, not a blank area
- Closing the search box - by Escape, or by clearing it and clicking away - restores the filter icons and the filter chosen before searching, unchanged
- The search box is not remembered across a reload; it always opens closed
5.2 Actions
| Action | Behavior |
|---|---|
| Resume | Load session, reconnect, focus chat; progress bar during hydration |
| New | Create blank session, reconnect, focus chat |
| Rename | Inline edit field; Save (✓) and Cancel (✕) buttons; clicking away cancels |
| Kill | Stop session; spinner and disabled while stopping; visible only when session has a container |
Panel Buttons:
- New (+) button: Creates new session (in panel header); Alt+Click or middle-click opens in new browser tab
- Refresh button: Reloads session list (in panel header)
- Edit button: Revealed on row hover for rename action
- Kill button: Stop icon, revealed on row hover when session has a container; red on hover; spinner and disabled while stopping
- A side conversation's row offers no Kill button, even while it is answering — stopping it ends only that conversation, never the one it came from
5.3 Display Format
- Time: "just now" (<1m), "Xm ago", "Xh ago", "Xd ago" (<7d), then full date
- Time range: "started – updated" when different
- Cost: USD with 2 decimal places (
$X.XX),$X.XXKfor ≥$1K; em dash if null - Turns: "X turns", "—" if null
- Messages: truncated with ellipsis
5.4 Pinned Sessions
- Pin button left of resume icon
- Orange when pinned, muted when unpinned
- Pinned sessions sorted to top, maintain original order within pinned group
- Pinned state persists across sessions
5.5 Resume Button
- Split-button: Play icon (▶) resumes session in current tab; chevron opens dropdown with "Resume session" and "Resume in new browser tab"
- Middle-click on Play button resumes session in new browser tab
6. Boards Panel & Ticket Board
6.1 Boards Panel (Right Strip)
Right-strip panel listing discovered boards per workspace:
- Boards icon in right strip, below Bookmarks
- Lists all boards discovered in the workspace
- Each board shows name and file path
- Hover reveals pencil icon to rename board inline (Save/Cancel buttons)
- Clicking a board opens its board view in the main panel; the URL updates to
#/workspaces/{id}/boards/{boardId} - Alt+click or middle-click a board item opens it in a new browser tab
- Deep-link URL of the form
#/workspaces/{id}/boards/{id}selects the workspace before opening the board, so the board renders fully populated - Refresh meta-item appears at the end of the list (and below the "No boards found" placeholder in the empty state); tapping it reloads the board list
- The panel has no dedicated header row — boards begin at the top of the panel
- On fresh page load before a workspace is selected, the panel shows the loading state — never a raw error message
- Loading state: panel-level italic muted "Loading..." text matching the canonical empty-state styling
- Error state: "Failed to load boards" — centered, italic, red
- Empty state: "No boards found" — centered, italic
6.2 Board Layout
Ticket board displays in the main panel with 6 columns and horizontal swimlane bands:
Columns (left to right):
| Column | Display Name |
|---|---|
| backlog | Backlog |
| in-progress | In Progress |
| review | Review |
| done | Done |
| rejected | Rejected |
| definitely-rejected | Def. Rejected |
- Terminal columns (Done, Rejected, Def. Rejected) collapsed by default with ▸ toggle
- Click ▸/▾ to expand/collapse any column
- Non-terminal columns expanded by default
- Column headers have drag handle (visible on hover) for horizontal drag-and-drop reorder
- Column header context menu: Move left, Move right, separator, "Archive all tickets in [State] state (N tickets)"
- Collapsed column headers show the first grapheme of the state label, anchored to the top of the rotated strip
- Collapsed cells render only the ticket count; cells with zero tickets are blank
- Right-clicking a cell (state × swimlane intersection) opens "Archive all tickets in [State] state and [Swimlane] swimlane (N tickets)"
6.3 Swimlanes
Horizontal bands spanning all columns, grouping tickets by category:
- Named swimlanes from the board configuration displayed in order
- Click ▸/▾ chevron on swimlane header to collapse/expand (hides cards when collapsed)
- Tickets without a swimlane appear in "(Unsorted)" lane at bottom
- Swimlane headers have drag handle (visible on hover) for vertical drag-and-drop reorder
Swimlane CRUD:
| Action | Mechanism |
|---|---|
| Create | "Add swimlane" button at bottom of board → click → inline name input |
| Rename | Double-click swimlane header → inline edit; Enter saves, Escape cancels |
| Delete | Right-click header → context menu → "Delete"; tickets move to (Unsorted) |
| Reorder | Right-click header → context menu → "Move up" / "Move down"; or drag handle |
- Context menu on swimlane header: Rename, Delete, separator, Move up, Move down, separator, "Archive all tickets in [Swimlane] swimlane (N tickets)"
- Unsorted lane is read-only: rename, delete, and the swimlane context menu apply only to user-defined swimlanes
6.4 Ticket Cards
Each ticket rendered as a card in its column × swimlane cell:
- Card shows ticket title (from first
#heading, fallback to filename) - Cards with an assigned session show status indicator: dot + status text + truncated session ID
- Session status dot: green (running), amber (stopping), gray (no container)
- Click card to open detail overlay
- Ctrl+click / Cmd+click to toggle multi-select
6.5 Drag and Drop
- Drag card between columns to move ticket
- Dragging a selected ticket carries every selected ticket with it; dragging an unselected ticket moves only that ticket (selection unchanged); bulk drag also reorders within the destination cell, preserving the relative order between selected tickets
- Tickets within a cell can be reordered vertically by dragging; the new order persists across reload
- Dropping a ticket between two existing cards in a cell inserts it at that slot rather than appending at the end
- Bulk move into an active column spawns a single shared session for all moved tickets, reassigning every selected ticket to it; the prompt sequence's
{ticket}placeholder expands to a newline-separated list of all moved tickets - Drag card into collapsed columns (drop target highlights on hover)
- Drag card between swimlanes to reassign swimlane
- When the multi-selection spans multiple swimlanes, moving the selection keeps each ticket in its original swimlane (only the column changes); when every selected ticket is in the same swimlane, the target swimlane is respected
- Dropping a ticket on a column header moves it to that column without changing its swimlane
- Double-clicking a column header opens an inline input to rename the column's display label; Enter or blur saves, Escape discards; empty/whitespace input reverts to the prior label; renaming changes only the display label, not folder paths or ticket file locations
- Drag column headers horizontally to reorder columns
- Drag swimlane headers vertically to reorder swimlanes
- Drag ghost follows cursor during drag
- Moving a ticket to an active column (e.g. In Progress) auto-creates a session if none assigned
- Auto-created session receives the board's configured
prompt.sequenceas user messages, with{ticket}substituted by the ticket path
6.6 Ticket Detail Overlay
Read-only overlay showing ticket content:
- Title displayed in header
- Metadata: status (display label), swimlane (display name), session (ID + status or "—")
- Full ticket file rendered as formatted markdown
- Loading state: "Loading..." while fetching content
- Close with × button or Escape key
- Click backdrop to close
6.7 Multi-Select
- Ctrl+click / Cmd+click toggles ticket selection
- Checkbox click toggles selection without clearing other selections
6.8 Archive
- Right-click card opens context menu with "Archive ticket" option
- Right-click column header → "Archive all tickets" bulk-archives all tickets in that column
- Right-click swimlane header → "Archive all tickets" bulk-archives all tickets in that lane
- Archive removes the ticket from the board view; file stays in place
- No confirmation dialog
6.9 Loading & Error States
| State | Display |
|---|---|
| Board loading | Spinner centered: "Loading board..." |
| Parse failure | "Failed to parse board.yaml: {error}" |
| No board data | Nothing rendered (null) |
6.10 Real-Time Updates
- Board auto-refreshes when board contents change
- Board auto-refreshes when session status changes
6.11 Density Modes
- A control-bar button switches the board between comfortable (cards) and terse (inline ticket-ID links) layouts; the choice is reflected in the URL
- In terse mode, each cell shows tickets as comma-separated wrapping ID links; clicking a link opens the ticket detail; tickets with attached sessions are colored differently. Each link's text is the ticket-file name's prefix before the first hyphen, supporting alphanumeric IDs (e.g.
1.04.A)
7. Stash Panel
7.1 Purpose
Temporary text clipboard for storing/retrieving prompts.
7.2 Items
- Stored per-session
- Items displayed newest first (stack order)
- Show first line as preview (truncated)
- Hover shows full text in tooltip
- Empty/whitespace-only text rejected when stashing
7.3 States
- Empty: "No stashed items" with "Ctrl+S to stash" hint (no full footer)
- Footer (non-empty): "Ctrl+S to stash | Ctrl+Shift+S to pop"
7.4 Actions
| Action | Behavior |
|---|---|
| Click copy button | Copy to clipboard (keep in stash) |
| Click remove button | Remove item and insert into input |
Button Icons:
- Copy button: Copy icon with tooltip "Copy"
- Remove button: Arrow icon with tooltip "Insert into input and remove"
Edge Cases:
- Pop with empty stash: no effect
8. Todos Panel
8.1 Display
- Read-only list showing current todos
- Each row shows the state icon and the task title
- State icons: ○ (pending), ◐ (in progress), ● (completed)
- Completed items show strikethrough text
- Empty state: "No todos yet"
- Hovering a row shows the task's description as a tooltip when one is set
- A task waiting on another task shows
⊘; once everything it waits on is done, the icon goes back to the task's own state icon
8.2 Subagent Segmentation
- Main agent todos appear first, without section header
- Subagent todos grouped under labeled sections
- Section label: uppercase Task description, truncated with ellipsis; full text in tooltip
- Falls back to truncated task ID when description unavailable
- Sections disappear when their Task completes
8.3 Badge
- Icon strip shows count of incomplete todos across all subagents
- Updates in real-time as todos change
8.4 Other Icon-Strip Badges
- Stash icon shows count of stashed items in the default Todos style; hidden when zero
- Tasks icon shows count of currently-running subagent Tasks in the default Todos style; hidden when none active
- MCP icon shows count of MCP servers in the
failedstate in a red (danger) variant; hidden when no failures
9. Help Panel
Displays keyboard shortcuts reference tables.
10. Footer
10.1 DEV Mode Indicator
- In development mode, "DEV" label appears at the leftmost position of the footer
10.2 Status Indicators
| Element | States |
|---|---|
| Connection dot | Green (connected), Amber (connecting/stopping), Red (error/reconnecting) |
| Status text | "Ready", "Submitting...", "Working...", "Waiting...", "Stopping...", "Stopped", "Connecting", "Resuming...", "Forking...", "Creating session...", "Opening board...", "Opening workspace...", "Reconnecting...", "Disconnected", error |
| Elapsed timer | "(Ns)" suffix on Submitting/Working/Waiting, counts seconds since response started |
| Interrupt hint | "Ctrl+. to stop" (when working or submitting) |
Status Dot Animations:
- Working: Color-cycling animation (blue -> purple -> magenta)
- Stopping: Amber color with pulsing glow animation
- Reconnecting: Red dot, "Reconnecting..." with animated dots; retries indefinitely until restored
Silence Detection:
- "Working..." transitions to "Waiting..." after 5 seconds without server events
- Waiting state dims status dot (color changes to muted gray) and text (reduced opacity, no animation)
- Reverts to "Working..." immediately when new events arrive
10.3 Session Stats
| Stat | Format | Tooltip |
|---|---|---|
| Workspace | Directory name only; visible immediately on page load, before session initialization | "Workspace — /path/..." |
| Turns | Integer count | "Turns — N" |
| Cost | $X.XX (2 decimals), defaults to $0.00 | "API cost this session — $X.XX" |
| Duration | H:MM:SS (updates periodically while responding) | "Time Claude spent responding — H:MM:SS" |
| Context | Token count + percentage bar (max 200K); exponential color gradient blue→yellow→orange; appears only when the current runtime reports token usage | "Context — X / Y tokens" |
| Runtime | Display name of the active runtime (e.g., "Claude") | "Runtime — name" |
| Model | Model name + chevron, "—" if null; clickable to open model picker | "Model — name" |
| Effort | Effort level name + chevron; clickable to open effort picker | "Effort — level" |
| Permission mode | Permission mode label + chevron; clickable to open mode picker | "Permission mode — label" |
| Session ID | First fragment (before the first "-"); full id stays in the tooltip / copy | "Session directory — /path/..." |
| Runtime ID | 8-char prefix; "—" when no container; clicking copies the full id; transitions to "—" immediately when the container stops | "Container — full-id" |
On a brand-new session, every footer field shows a real value from the moment the session view appears.
On the welcome screen (no active session), the footer shows the workspace, model, permission mode, and effort level the next session will use. The values stay visible across the welcome → new session transition.
Capability-Aware Visibility. When the active runtime declares it does not support a footer control, the affected picker is hidden:
- Model picker is hidden when the runtime does not support switching models mid-session
- Effort picker is hidden when the runtime does not support effort levels
- Permission mode picker is hidden when the runtime does not support permission modes
10.4 Actions
| Action | Behavior |
|---|---|
| Click session ID | Copies session directory path; shows "Copied!" briefly |
10.5 Model Picker
Dropdown for switching the Claude model at runtime:
- Trigger: click model name in footer
- Dropdown opens upward, right-aligned to model label
- Lists available models with friendly name and full model ID
- Current model highlighted with checkmark
- Selecting a model updates footer immediately; takes effect on next message
- Closes on: selection, Escape, click outside
- Disabled while Claude is responding
- New sessions start with the default model, not the previous session's model
10.6 Notifications Toggle
Toggle for sound and desktop notifications:
- Position: right of session ID
- Icon ON: Bell icon with slightly lighter color
- Icon OFF: Bell icon with diagonal strike-through (top-left to bottom-right)
- Controls both sound chime and desktop notifications
- Default: disabled (opt-in)
- Stored per-session; survives refresh and resume
10.7 Claude Service Status
Indicator showing Claude service health from status.claude.com:
- Position: right of notifications toggle
- Colored dot: green (operational), yellow (minor), orange (major), red (critical), gray (error)
- Tooltip shows status description; for incidents includes incident name
- Click opens status.claude.com in new tab
10.8 Permission Mode Picker
Dropdown for switching Claude's permission mode at runtime:
- Trigger: click mode label in footer
- Dropdown opens upward, aligned to mode label
- Lists every permission mode the underlying agent recognises with friendly labels: Default (standard behavior), Plan (planning mode), Accept Edits (auto-accept file edits), Bypass (bypass permission checks), Don't Ask (allow all tools without prompting), Auto (automatically determine mode)
- Current mode highlighted with checkmark
- Selecting a mode updates footer immediately; takes effect on next action
- Closes on: selection, Escape, click outside
- Disabled while Claude is responding
- New sessions start with full permissions (default)
10.9 Effort Level Picker
Dropdown for switching Claude's reasoning effort level at runtime:
- Trigger: click effort label in footer
- Position: between model picker and permission mode picker
- Dropdown opens upward, aligned to effort label
- Lists available effort levels with friendly labels
- Current level highlighted with checkmark
- Selecting a level updates footer immediately
- Closes on: selection, Escape, click outside
- Disabled while Claude is responding
- Default effort level: "xhigh"
- All effort levels available on all models
- Effort level persisted in session; survives refresh and resume
10.10 Plan Limit Warnings
An item per usage window appears in the footer, immediately left of the workspace name, only while that window is being approached or has been reached:
- Position: immediately after the status indicator, before the workspace name; each item carries its own separator, so multiple items and the workspace name each stay visually distinct
- Two windows: "Session" and "Weekly"; when both are being approached at once, Session appears first, then Weekly
- Reads "Session
%" or "Weekly %" while a percentage is known - Tinted from amber toward red as the percentage climbs; solid red once at or past the danger threshold, however much higher it climbs
- Once a window is fully reached, its item reads "Session limit reached" or "Weekly limit reached" in red, with no percentage
- Hovering an item shows which window it is, the percentage (when known), and when it resets
- An item disappears on its own once its window resets or usage falls back to normal, and its separator disappears with it
- An item belongs to the workspace it appeared in: it stays visible after switching sessions or reloading the page within that workspace, and clears once a new session in that workspace reports the window back to normal
- Nothing appears here before any usage information is known
11. Error Handling
11.1 Error Display
| Error Type | Display |
|---|---|
| API error | Footer transient message (4s) |
| Connection error | Connection status + auto-reconnect |
| Turn error | Red border on turn |
| Tool error | Error styling in tool block |
| Interrupt | Yellow border on interrupted turn, and on its last work-column block while the work view is on |
Interrupt Visualization:
- User interrupts (Ctrl+. or stop button) show visual indication
- Interrupted turn shows yellow left border
- While the work view is on, an interrupted turn's last work-column tool block carries the same yellow left border, only when that block is the turn's trailing block; a turn interrupted after prose, or with no tool calls at all, marks no work-column block - the transcript's own border carries those cases
- Internal interrupt confirmation not shown as user bubble
11.2 Recovery
- Network errors trigger automatic reconnection
- Intentional session close transitions cleanly to disconnected state
- User can manually reconnect via reload button
- Session state preserved across reconnects
- Error state auto-clears after 4 seconds
- "Stopped" state clears automatically after a short delay once the result event arrives
- All live panels show "Resuming..." during replay
- Session automatically recovers after a service restart; shows "Session reconnect failed" on failure
11.3 Render Failure Containment
- When part of the app stops responding, that part shows an error state with a retry control, and the rest of the app keeps working
12. Performance Requirements
12.1 Responsiveness
| Action | Expectation |
|---|---|
| Keystroke in textarea | Immediate |
| Panel toggle | Instant feedback |
| New message display | Near-instant |
| Scroll | Smooth, no jank |
13. Notifications
13.1 Desktop Notifications
Browser notification when response completes:
- Trigger: response completes AND tab not visible AND notifications enabled
- Title: matches browser tab title
- Body: first ~50 chars of assistant message (not thinking block)
- Click action: focus claudebox tab
- Requires browser permission
- Do NOT notify on session resume
13.2 Sound Alerts
Audio notification on completion:
- Trigger: on completion AND tab not visible AND sound enabled
- Sound: single chime (same for success/error)
- Volume: quiet (not full volume)
- Default: disabled (opt-in via footer toggle)
13.3 Favicon Indicator
Visual indicator when tab not focused:
- Show breathing arc animation while Claude is responding
- Change to notification variant when response completes
- Restore normal favicon on tab focus
- Circular background tinted in the workspace accent color fills the favicon (inscribed inside a small transparent margin) when a workspace color is set; the C-shape appears in white on top
- Badge fills the favicon as a centered circle inscribed inside a small transparent margin
- Badge fill color is a brightened version of the workspace accent color
- No badge appears when no workspace color is set
- Badge background appears at reduced opacity while the notification state is active; the C-shape stays at full opacity
- Badge background pulses in opacity in sync with the C-shape's breathing animation while Claude is responding
13.4 Tab Title Indicator
Visual indicator in browser tab:
- Prepend
*to tab title when Claude finishes and user hasn't interacted - Clear prefix on any user interaction (click, typing) or window focus
14. MCP Status Panel
14.1 Panel Content
- List of MCP servers with status indicators
- Status dot colors: green (connected), red (disconnected/failed), amber (pending/needs-auth), muted gray (disabled)
- Non-connected, non-disabled servers show status text label; dot tooltip shows status
- Empty state: "No MCP servers connected"
- The MCP panel only appears when the current runtime exposes MCP server control
14.2 Server Management
- Reconnect button (refresh icon) shown for disconnected/failed servers
- Enable/Disable toggle button shown for all servers
- Disabled servers show green-bordered "Enable" button; connected servers show "Disable" button
- Buttons disabled while an action is in progress; reconnect icon spins during loading
- After successful action, panel refreshes to show updated server status
- Error message shown at top of panel on action failure; auto-clears after 4 seconds
15. Bookmarks
15.1 Bookmark Toggle
- Bookmark button shown on user message rows (between rewind and copy buttons); on assistant turns, bookmark button is persistently visible in the turn's meta area alongside the copy button
- User-turn bookmark hidden by default, visible on hover; assistant-turn bookmark always visible; filled yellow when active, outline when inactive
- Clicking toggles bookmark state; survives refresh and resume
15.2 Minimap Indicators
- Bookmarked turns display as fully highlighted yellow sub-bar segments in minimap
15.3 Bookmarks Panel
- Side panel on right strip below Tasks and above Boards, accessible via Alt+5
- Two tabs: "This session" and "All sessions", with count badges
- Active tab tracks active-session presence: "This session" while a session is open, "All sessions" while none is. Manual clicks override; the next session-state change re-asserts the auto-mapping (auto-switch wins)
- "This session" tab lists bookmarks in current session; clicking scrolls to the bookmarked turn
- "All sessions" tab lists bookmarks from all sessions, sorted by recency; clicking navigates to the session; visible without an active session
- Loading state on cold load: panel-level italic muted "Loading..." placeholder; tabs and list appear only after first load
- Empty state on both tabs: centered, italic, muted "No bookmarks"
- Each bookmark shows preview text (first 80 chars), relative timestamp, and a colored container-status dot reflecting the source session's state (green/amber/gray)
- Hovering a truncated preview reveals the full text in a native tooltip
- Remove button anchored to the top-right corner of each item, visible on hover
- Middle-click or Alt+click opens the bookmarked session in a new browser tab; the originating item flashes briefly to confirm the action
15.4 Cross-Tab Sync
- Bookmark changes sync across browser tabs
16. Tasks Panel
16.1 Purpose
Panel for monitoring background tasks:
- Filter tabs: "Active" (running only) and "All" (including completed/failed/killed); badge counts per filter
- Tasks sorted chronologically (oldest first)
- Click task focuses chat tab, then scrolls the column holding its block to the top of the visible area with a brief highlight pulse
- With the agent's work shown, a task click lands in the work column instead of the transcript; the transcript does not move
- Clicking a task whose place in the conversation has scrolled out of view still brings it into view
- Clicking a task inside a collapsed turn opens that turn and shows the task
- Empty state: "No tasks"
- Resume state: "Resuming..."
16.2 Task Item Display
| Element | Content |
|---|---|
| Status indicator | Running/completed/failed colored left border; "killed" displayed as "failed" |
| Description | Task description from invocation |
| Duration | Time since start (live for running) |
16.3 Staleness Indication
Running tasks show staleness via left border color gradient:
- Fresh (≤15s since last event): blue
- Transitioning (15–90s): blue → purple → amber gradient
- Stale (>90s): amber fading toward gray
- New event resets color to fresh immediately
- Only running tasks show staleness coloring; completed tasks use static status colors
17. Usage Panel
17.1 Panel Content
Aggregated cost display over time intervals:
| Interval | Description |
|---|---|
| 24 hours | Cost from sessions started within 24 hours |
| 7 days | Cost from sessions started within 7 days |
| 30 days | Cost from sessions started within 30 days |
| All time | Total cost across all sessions |
- Cost formatted as
$X.XX - Zero cost shows
$0.00 - Refreshes when sessions change
- Forked sessions contribute only their post-fork spend to the totals; pre-fork spend is attributed once to the ancestor session it originated in
18. Logs Panel
18.1 Panel Content
Real-time log viewer:
- Entry format: timestamp, log level, logger name, message
- Log levels color-coded (debug, info, warning, error, critical)
- Auto-scroll to latest; respects user scroll position
- No container: "No active session"
- Connecting state: "Connecting..."
- Empty state: "No logs yet"
- Resume state: "Resuming..."
19. Skills Panel
19.1 Panel Content
Displays available slash commands organized by category:
- Three tabs: Custom (default), MCP, All
- MCP tab: commands starting with
mcp__ - Custom tab: all other commands
- All tab: all commands unfiltered
- Tab badges show count per category
- Commands displayed with
/prefix (e.g.,/deploy) - Empty state: "No commands"
- Resume state: "Resuming..."
20. Workspaces & Containers
20.1 Workspace Discovery
- Available workspaces appear on page load
- Single workspace: auto-selected; no workspace-list dropdown shown (color palette still appears in chat group; see §20.2)
- Multiple workspaces: selection priority is URL hash > saved preference > first workspace
20.2 Workspace Switcher
- Dropdown in the chat-area header tab bar (right-aligned)
- Shows current workspace name with chevron
- Always visible in chat group; shows color palette for single workspace, workspace list + palette for multiple
- Dropdown lists all workspaces with path; checkmark on active
- External link icon per workspace: opens workspace in new browser tab
- Middle-click on workspace item opens it in a new browser tab
- Switching workspaces clears session data and stash
- Each workspace row has a trash icon (revealed on hover) — clicking it opens a confirm modal that deregisters the workspace on confirm
- Deregistering preserves the
.workspacemarker file on disk; only the workspace's registration with Claudebox is removed - A "+ Register workspace…" footer item below the color palette opens a modal that accepts an absolute path and registers it
- Registering an already-known path is idempotent: the modal shows an inline notice and auto-closes; no duplicate workspace row is created
20.3 Deep Linking
- URL form:
#/workspaces/{workspaceId}/sessions/{sessionId} - Supports deep linking and browser back/forward navigation
- Deep link to session in different workspace triggers automatic workspace switch
- URL updates on session switch, workspace switch, and new session creation
20.4 Container Status Indicators
- Colored dot on the session header strip: green (running), amber (stopping), gray (no container)
- Colored dot on session panel rows: same colors and states
- Dot color mapping: running (green), stopping (amber), all other states (gray)
- Stopping a session shows the stopping color on every status dot at once; once the container is gone, all dots clear together — no dot stays showing stopping, and none keeps showing running
- A side conversation finishing its answer clears only its own dot; the conversation it came from keeps showing running throughout
20.5 Session Creation Overlay
When creating a new session:
| Feature | Behavior |
|---|---|
| Header strip indicator | Session name slot shows "Creating…" with a spinner |
| Progress bar | Indeterminate (no percentage) |
| Status text | "Creating session...", "Starting session..." |
| Textarea | Visible and editable; submitted messages queued and auto-sent when session is ready |
| Submitted messages | Appear in the chat history as regular pending and queued user messages — same shape and width as during a normal chat |
| On success | Header strip swaps "Creating…" for the session name; overlay dismissed |
| On failure | Header strip clears the "Creating…" placeholder; error shown |
20.6 Session Resume Overlay
When resuming an existing session:
| Feature | Behavior |
|---|---|
| Progress bar | Determinate (fills as events replay) |
| Phase 1 | "Starting session...", "Resuming session..." |
| Phase 2 | Replay progress: "Replaying events (X/Y)..." |
| Textarea | Stays usable and focused during resume; a message typed while the conversation is still loading stays in the composer, ready to send once the conversation is on screen |
20.7 Containers Panel
A bottom-slot panel listing every container the app knows about, across all registered workspaces. Mounted at the bottom-left slot of the bottom-panel strip.
- Each row shows: a colored state dot, the container's 8-character identifier (the same one shown in the footer when the active session is attached to that container), the 8-character session identifier (matching the Sessions panel), the session name, the capitalized state name (Running / Starting / Stopping / Crashed / Stopped), the capitalized kind label, and the relative age
- Hovering the container identifier shows a tooltip reading
Container — <full identifier>(the same string the footer's container pill shows) - Hovering the session identifier shows a tooltip reading
Session directory — <full path>(the same string the Sessions panel and the footer show on the session identifier) - Clicking the container identifier copies the full identifier to the clipboard; a brief "Copied!" indicator appears in the same slot and reverts after a short interval
- Clicking the session identifier copies the session directory path to the clipboard; a brief "Copied!" indicator appears in the same slot and reverts after a short interval
- Columns line up vertically across all rows
- The container and session identifiers appear in a small monospace font
- When the attached session has no custom name, the session-name cell is empty
- Row text and icons share a common vertical baseline
- Containers for the current workspace appear in the list — switching workspaces refreshes the panel to show that workspace's containers
- Rows are sorted by state group (running → starting → stopping → crashed → stopped); within each group, newer containers appear first
- Rows update without manual refresh as containers start, transition state, or stop
- A "Stop" button on each running or starting row stops and removes the container (matches the sessions-panel and main-header stop affordance)
- Rows with an attached session show a Play+chevron resume control: clicking Play opens the session in the current tab; Alt-click or middle-click opens in a new browser tab; the chevron opens a dropdown with both options explicit. The resume control is not shown on the current container's row (the session you are already viewing).
- The current container's row is highlighted with an accent-colored left border and a darker background, matching how the active session is highlighted in the Sessions panel
- The Resume control is not shown on the current container's row
- Empty state: "No containers"
20.8 Welcome State
- When no session is active, chat panel shows welcome page
- Workspace name displayed prominently; colored with workspace accent if set, otherwise default text color
- Workspace path displayed below name (muted)
- Chat input anchored to the bottom of the chat panel, visually indistinguishable from the active-session input (full panel width, same surrounding controls); submitting Enter creates a new session and sends the typed message as its first message
- Picker changes (model, permission mode, effort level) made on the welcome screen apply to the next session created from that welcome view; only the latest value per picker is applied; pickers display the chosen values immediately
- Keyboard shortcuts reference card listing key bindings (Alt+N, Alt+Shift+N, Alt+arrows, Alt+C, Alt+1..9, Alt+?)
20.9 Nested Containers
- A workspace may opt in so the agent can run and build its own containers inside its session
- Containers the agent runs stay invisible to the host and to other sessions, and disappear when the session ends
21. Mobile
A single-column layout for narrow screens: top bar, status strip, chat area only. No side panels, icon strips, or tab bar.
21.1 Activation
- On touch-primary devices (phones and tablets), the app shows the mobile layout instead of the desktop layout
- Layout classification depends on device type, not browser window size
21.2 Layout Structure
Top to bottom: top bar, status strip, chat area. The drawer slides in from the left and the details sheet drops down from below the top bar — both appear over the chat area when opened.
21.3 Top Bar
| Element | Behavior |
|---|---|
| Hamburger (left) | Tapping opens the navigation drawer |
| Session name (center) | Shows the active session name |
| Session name fallback | Shows "claudebox" when there is no session name |
| Stop affordance | The chat send button doubles as the stop control on mobile |
| Details button (right) | Tapping toggles the details sheet open and closed |
21.4 Status Strip
A thin, non-interactive bar below the top bar.
- Connection dot is green when connected
- Connection dot is gray when disconnected
- Context usage percentage is displayed next to a fill bar that grows with usage
- Percentage display caps at 100% even when context is exceeded
- Fill bar color shifts with usage level (e.g. green → amber → red as usage rises)
21.5 Navigation Drawer
Slides in from the left when the hamburger is tapped.
- Tapping the X close button at the top-left closes the drawer
- The drawer covers the full screen when open
- Workspace switcher is hidden when only one workspace is registered
- Workspace switcher lists all workspaces when more than one is registered; tapping a workspace switches to it and closes the drawer
- New session button starts a new session and closes the drawer
- Session list shows every session for the active workspace
- Tapping a session row switches to that session and closes the drawer
- Sessions without a name fall back to a short prefix of their identifier as the label
- Close session button stops the active session
- Close session button is disabled when there is no active session or the app is disconnected
21.6 Details Sheet
Drops down from below the top bar when the details button is tapped.
- Tapping outside the sheet closes it
- Shows: connection status, workspace name, turn count, total cost (two decimals, USD), elapsed duration, context usage percentage, model, effort level, and permission mode
- The sheet's background is visually distinct from the chat behind it
21.7 Chat Area
- The welcome screen leads with a touch-suited usage prompt
- Chat occupies the full content width
- The send button doubles as a stop button while a response is in flight; tapping it interrupts the response
- Tapping the chat input keeps the page at its current zoom level
21.8 Drawer Session Rows
- Each drawer session row shows a status dot, ID prefix, optional name, an edit pencil, started–updated timestamps, turns, cost, and first/last message previews — matching the desktop session item content
- Tapping anywhere on a non-current session row resumes that session in the current browser tab and closes the drawer
22. CLI
The host-side claudebox binary is a verb-mode command line: claudebox <verb> [options] [-- agent-args]. Each verb is a discrete subcommand with its own help and options.
22.1 Run
Running claudebox run launches an agent session in a fresh container:
- The agent's exit code is the command's exit code
- Arguments after
--are forwarded to the agent - If no
.workspacemarker is found by walking up from the current directory, the current directory is used as the workspace; no error, no prompt runoperates without registering the workspace; the session works in cwd-as-workspace fallback mode
22.2 Build
Running claudebox build produces a container image:
- Running
buildproduces a usable image; no agent session is started --layer allrebuilds the entire image;--layer agentrebuilds only the agent layer- When the build fails, the command exits with the same code the build tool would have
The
buildverb operates on the container image;updateoperates on Claudebox itself (Claudebox's library on the host). They are unrelated despite both being able to refresh "the agent" —buildrebuilds the agent layer in the image;updaterefreshes Claudebox's own installed code.
22.3 Shell
Running claudebox shell opens a fresh container with a bash prompt
22.4 Prune
Running claudebox prune removes accumulated resources:
- Running
pruneremoves stale temp directories, dangling claudebox images, and stopped claudebox containers (typically none under auto-removal) - If a removal fails, the rest still run; the command exits non-zero
22.5 Version
Running claudebox version prints a multi-line block: the package version, the branch and short commit of the installed library, the install path, and the Python and container-runtime versions
22.6 Doctor
Running claudebox doctor runs an ordered set of environment checks and prints a result row per check; the command exits non-zero if any check failed
The profile check names the profile from your settings; when that profile cannot be read, the check fails
22.7 Update
Running claudebox update refreshes Claudebox itself:
- Running
updaterefreshes Claudebox; verbose output is forwarded when-vis passed - Running
updatetwice in parallel: the second invocation fails immediately with a clear message
22.8 Daemon
Running claudebox daemon start, stop, restart, or status controls the host daemon
22.9 Logs
Running claudebox logs tails the daemon log:
- Running
logsshows the most recent daemon output and continues following it - Errors appear red, warnings yellow, regular lines default
- Running
logs allinterleaves daemon and container output; every line is prefixed with its source logsshows each record on one line with a date and time, the log level, the logger name, and any extra fields; the on-disk log file is unchangedlogs allshows what the agent and the container API write, interleaved in time order with each line markedagentorapilogs allpicks up containers that start while it is already running; a short notice names the container when it starts streaming and when it stops- When a container log stream ends, the message says why — exit, connection error, or server error — instead of a bare "stream ended" notice
22.10 Status
Running claudebox status shows daemon, container, and workspace state:
- Running
statusshows daemon, container, and workspace state in three sections - When the daemon is stopped, status still shows container and workspace info; the daemon section reports its stopped state
22.11 Containers
Running claudebox containers list, stop, or kill manages containers across all workspaces:
- The table lists every container across every workspace
- Stop signals the container gracefully; the container exits and disappears from the list; supports a single ID or
all - Kill signals the container forcefully; the container exits and disappears from the list; supports a single ID or
all - You can pass any unique prefix of a container ID; ambiguous prefixes show matching IDs
- When stopping or killing multiple containers, each is reported individually; failures don't abort the rest; the command exits non-zero if any failed
22.12 Workspaces
Running claudebox workspaces list, register, or deregister manages the daemon's workspace registry:
- Running
workspaces listshows every registered workspace - Running
workspaces registerregisters the current directory (or the given path) as a workspace and creates the.workspacemarker if absent - Registering an already-registered workspace succeeds and reports it was already registered
- Two paths sharing a basename get distinct workspace IDs
- Running
workspaces deregister <id>removes the workspace from the registry; the.workspacemarker file is preserved
22.13 Shell completion
Bash tab-completion is opt-in; once enabled, pressing Tab offers context-appropriate completions:
- With bash completion enabled, pressing Tab completes the command tree: verbs, each noun group's actions, and flags
- Completing a container target offers container ids across all workspaces plus
all, falling back toallwhen the daemon is unreachable - Completing a workspace to deregister offers the registered workspace ids without contacting the daemon
22.14 Help
Command help is colourised - usage, section headings, verb names, option flags and their defaults - and falls back to plain text when colour is unavailable, staying readable and greppable when piped
23. Multi-Runtime Support
Workspaces choose their agent runtime via the agent field in .claudebox/settings.toml. The active runtime appears in the footer identity pill (§10). Each runtime declares its capability surface, and the frontend shows or hides controls accordingly.
23.1 LangGraph Workspaces
- LangGraph workspaces have file-system, shell, search, web, and notebook tools available; the model invokes them and their results appear as tool-use blocks identically to Claude workspaces. Unlike Claude workspaces, there is no per-action approval step or permission mode - the container is the isolation boundary for the whole tool surface
- LangGraph workspaces can spawn sub-agents for focused tasks; the sub-agent runs to completion and its final report appears as a tool result in the parent's chat
- LangGraph workspaces have agentic task-list tools (create / get / list / output / stop / update); task state appears in the tasks panel and as in-chat task blocks identically to Claude workspaces
- LangGraph workspaces can ask the user structured questions through the interactive Q&A form; the user's selections return to the model as the next message identically to Claude workspaces
- LangGraph workspaces discover workspace skills and invoke them by name; the skill body appears as turn-level instructions identically to Claude workspaces, and the slash-command autocomplete plus skills panel surface them on the welcome screen
- LangGraph workspaces route a typed
/<skill>command directly to that skill instead of sending it as plain text; the transcript shows the message exactly as typed, and the skill's effect shows up as an ordinary reply with no tool-use block - LangGraph workspaces have a tool-search meta-tool the model invokes for self-discovery; the conversation shows the search only when it fails, with what was searched for and what came back
- LangGraph workspaces connect to MCP servers declared per-workspace; the model can list and read their resources and invoke their tools identically to Claude workspaces, and one misbehaving server does not prevent the others from working
- LangGraph workspaces talk to the model provider declared in their
[langgraph] model = "provider:model"workspace setting; the runtime identity pill displays "LangGraph" and the assistant turn appears identically regardless of which provider answers - A workspace's agent can hand a piece of work to a second session, ask it questions and wait for its answers, and read its transcript, in both Claude and LangGraph workspaces identically; the second session appears as an ordinary row in the Sessions and Containers panels the moment it starts, and either side can be opened in a tab at any time. Depth is capped; a workspace's MCP status panel is unaffected either way