The previous fix (e3556bd) added `flex: 1 1 0` to `.st-tool-arg` in
`structured.css`, but `styles.css` has a duplicate copy of the same
rules that was left stale. Because both load, the unfixed copy in
`styles.css` can override the fix and re-enable horizontal scroll.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Deletes the vanilla shell and mounts App.tsx on #root. main.ts and the
23 views it drove are gone; App.tsx composes the ported components —
sidebar, multi-view, command bar, spawn modal, help and restart
overlays, daemon link, drawer — around the catalog and layout stores.
The pure parts of four deleted modules moved next to the components
that still use them: the spawn-form model and spawnSimilar into
components/spawn, the transcript's markdown/format helpers and the diff
into components/structured, the help overlay's grouping into
components/dialogs. Document-level event names now live in uiEvents.ts.
Deduplicated two pairs the migration left side by side: the sidebar
uses dialogs/KillDialog and common/ContextMenu. It also listens for the
command bar's kill/rename events, which nothing had picked up since
catalog.ts went away.
styles.css stays as the token and base layer, with `#app` renamed to
`#root` and the pane-body rules re-keyed off the classes the React
panes actually carry.
Closes#253
Queued prompts now appear inline in the transcript as faded user bubbles
instead of a pill badge above the composer.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Block spans + literal \n text nodes inside <pre> caused empty lines
between every diff line. Drop the text nodes, add unified-diff prefixes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Uploaded images now render as thumbnails in the user bubble instead of
showing only the server file path as text.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The "Running 1m ..." status now sits at the tail of the chat
history instead of pinned above the input, matching Claude Code's
placement.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Resolved permission boxes vanish from the transcript instead of
lingering as "answered" cards. When a turn has 2+ tools the resolved
approval is absorbed into the tool group as a compact italic line;
otherwise it is hidden entirely.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Project boxes now use a fixed two-column grid so every card is the
same width. The worktree count line is removed — the information
lives in the worktree picker that follows a project selection.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move the harness/command choice above the project picker so the
operator decides what runs before where. Replace the flat command
tiles with larger centered cards that render each tool's icon from
toolIcon.ts at 24x24. The Custom escape hatch gets a three-dot
ellipsis icon and a dashed border to read as secondary.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Keep icon cancel button, always-"Send" label, and queue status span
from main. Drop unused `active` local after label simplification.
Update test expectation to match.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move max-width constraint from .structured-rows up to .structured-main
so the activity banner and composer match the transcript width. Replace
text cancel button with a stop-sign icon inside a spinning ring. Drop
the accent border-top on composer focus.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Intermediate agent text/thought rows between tool calls in the same
turn now render inside the collapsed tool group instead of after it,
preserving chronological order. The last agent text (no subsequent
tool) stays outside as the prominent final answer.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Drop the per-tool name list from group headers (redundant with the rows
below), remove individual borders inside groups, and tighten padding so
20-tool blocks scan as a dense list instead of a wall of cards.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The attach button precedes the draft in the DOM, so under the ≤520px wrap
rule it took a line of its own above the textarea. An explicit order puts
the draft back on the first line and groups every control below it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Reverts the stacked control strip from f78aa13. The floating card is still
gone — flush band, one hairline against the transcript that doubles as the
focus indicator — but the composer keeps its own `--surface` fill so it
still reads as distinct from the pane, and the draft, gear and Send stay on
one bottom-aligned row.
At phone width that row cannot hold a draft plus three controls, so it
wraps: the draft takes a full line and the controls drop below it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The composer was a floating bordered card inset from the pane edge, and
its send button was bottom-aligned beside the textarea, so it sank as the
draft grew.
It is now a flush band at the foot of the pane: one hairline rule against
the transcript, which doubles as the focus indicator. The textarea spans
the full width and the controls sit in a fixed strip below it, so the send
button keeps its place however tall the draft grows.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Adds a transcript surface for a Structured-view session alongside the
existing xterm attach view: a WS /api/structured/:id connection
(structured.ts) mounted by ConnectionPool whenever a session's `view`
is `"Structured"`, and pure per-row/rail renderers (structuredRender.ts,
structuredDiff.ts) covering all eight transcript row kinds.
Hierarchy follows the design reference (artifact 88ecd690): the
approval is the only lifted, card-like element; a user turn is a
tinted block with an accent rail; agent prose is plain text; tool
calls are compact bordered rows expanding to output or a coloured,
horizontally-scrolling diff computed from ACP's full old/new text.
The client renders `reduced_state` and rows exactly as received, with
no raw-event folding or turn tracking of its own.
Extracted attach.ts's pane-header title building into paneTitle.ts and
its connection interface into pane.ts (PaneConnection) so both
connection kinds share one contract and one header.
There is no ctrl-k on a phone and the web UI is mobile-first, so the field
the operator already reaches for becomes the touch entry point: focusing or
tapping it dispatches OPEN_COMMAND_BAR_EVENT and the shell opens the bar with
an empty query. The field is readonly and blurs itself first, so no keyboard
rises over it and the bar can be closed without reopening it.
This replaces the inline substring filter — one search affordance in the
header, not two. buildTree loses its filter argument, and the tree's "No
matches" empty state goes with it; the bar's own no-results state took over.
The filter's name-and-directory matching is now covered against the bar.
The bar's phone-width sheet moves to the spawn modal's 599px break, with
thumb-sized rows and a field that clears the zoom-on-focus threshold.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Tab on a highlighted session in the web command bar opens that session's
action page in the same overlay: kill, rename, spawn similar, still fuzzy
searchable and headed by the session's name. Escape, or backspace at an
empty query, returns to the result list with the previous query intact.
Each action raises the flow the card already has. The two that lived
inside the sidebar get an event apiece — the confirm-and-blockers kill and
the inline rename prompt — so the bar picks the action and nothing more;
spawn similar reuses the existing SPAWN_SIMILAR_EVENT.
`>` narrows the bar to commands, matched on the label only with the chord
shown beside each row and deduped by action. `~` narrows to directories over
recent dirs and the project list, filled in from /api/dirs as a path is typed;
Enter fast-forward-spawns there, falling back to the pre-filled spawn form
when a default cannot resolve. Without a sigil the list stays mixed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>