The two shipped surfaces offered different tools for no recorded reason:
session checkpoints, tool-result pruning, the goal tools, and Ralph were in
`tui.cordis.yml`; `tool-todo` and web search were in `web.cordis.yml`. Neither
offered session search, a string-replacement editor, or a repeat-tool guard,
though none of the three is surface-specific.
Move the rows that are not surface-specific into `base.cordis.yml` and add
those three. Web search moves there too — the TUI decision the change that
made it a Web default deferred. Both surfaces now assemble the same 27 tools.
This adds only. No row is removed from either surface and no existing row's
configuration is edited: executors, sandbox composition, access defaults,
`tools.mode`, and the workflow tool are exactly what they were. Two rows stay
surface-specific: `tmux-context` (no terminal multiplexer in a browser) and
`session-reference` (its index has one writer owner).
Ship `dsh-mcp-client` as a dependency without a row: the plugin mounts one
server per instance and `command` is required, so a default would name a
third-party server and spawn it outside `ctx.bash` on every launch. The CLI
README carries the YAML for mounting one from a personal config.
Drop the pending state and confirm step: Tab cycles the highlighted
entry and applies at once, so the transcript behind the dialog is the
live preview; Enter/Esc/Ctrl+C just close.
DetailsDialog now shows one entry per dimension (Tool cards, Reasoning)
seeded with the current values; Tab cycles the highlighted entry's
pending value (rendered as current -> pending), Enter applies every
changed dimension in one confirm, Esc/Ctrl+C cancels.
DetailsDialog is a centered SelectList over the five transcript-detail
states (three tool-card phases, reasoning shown/hidden); it preselects
the current phase, marks both current values, applies on Enter, and
cancels on Esc/Ctrl+C. Width is the new detailsDialogWidth config key.
The argument grammar is unchanged and shares the same setters.
/details reports the transcript detail state bare, jumps tool cards to
collapsed|expanded|hidden, and sets or toggles reasoning blocks, sharing
the closure state behind Ctrl+O/Ctrl+R via setToolsVisibility/setReasoning.
Also fixes a replay defect the reasoning rebuild exposed: rebuildTranscript
reused a settled StreamingAssistantComponent for a later assistant/message
of the same step, overwriting the earlier content; the settled check now
lives in renderEvent for both live and replay paths (untrusted-controls
re-recorded with the previously dropped content present).
Rewrite the read/search/web/diff card spec suites for the collapsed-by-default
ToolRow composition: each row now needs the conversation `t`, and the card is
absent from the DOM until the row's [data-expandable] toggle is clicked. Refresh
the built-boot and search-card assembled snapshots (they expand the row before
shaping the card) and the code-mode-round golden. Fix a fixture turn-number
collision the 985/986 merge introduced (grep reused turn 67, already the
multi-hunk edit's, so both shared one callId) by renumbering search/web/todo to
68-72. Document the refactor's behavior in the ui-conversation README (both
languages) and add the Agent Note.
- lifecycle-chrome's second scaffold staged its workspace under the OUTER
scaffold's temp root, coupling two supposedly independent worlds and
leaving the aria scrub root wrong; it now uses its own workspaceCwd.
- The direct-open path now carries the same `flowBusy` gate that disables
the equivalent menu entry, so an occupant re-registering mid-adoption
cannot raise a second flow.
- A composition with no directory-picker no longer opens a zero-entry
popover on the hero anchor: with nothing to pick and nothing to add,
the gesture shows nothing. Both behaviors gain a unit test.
- Brought three partially superseded Agent Notes current (the native
picker, the workspace UI product flow, and the sidebar browsing split),
cross-linked to this decision, both languages re-recorded.
- Corrected this Note's own Testing section: the shared e2e helper stages
and adopts its directory, it does not create one in-dialog — only
workspace-management does. Named the client-seam and CLI-README residue
in the follow-up TODO alongside the wire branch.
dsh --dump-config and dsh web --dump-config compose the shipped base,
the surface overlay, and the --config or personal overlay — exactly the
layers that surface boots — and print the entry list as YAML without
booting; --dump-default-config stops at the surface overlay so the two
outputs diff to precisely the user layer's effect.
The dump shares the mounting code: the vendored include exports its
patch algorithm as applyEntryPatches() and its !!js dialect as
entryListSchema (logged in vendor/README.md), dsh-app-boot's
renderConfigDump() composes and renders through both (and now imports
the dialect instead of duplicating it), and the CLI adds a thin
dump-config mode. !!js expressions print verbatim; unmatched patches
warn on stderr; boot-only flags are rejected alongside the dump flags.
(cherry picked from commit 1fdbebfa8a5dc7df840d53666320064a7e3dae59)
The Ctrl+O hidden phase keeps one Assistant header per turn: the first
step with visible text/reasoning owns it, later steps render as
headerless continuations, and bodiless (tool-only) steps render
nothing. Leaving hidden restores per-step headers. Pure TUI
presentation; the session log is unchanged.