New and touched sources reach the CI per-file 100% thresholds: HoverCard
(timers, placement clamp, disabled guard), Menu label/danger/pointer-leave
branches, WorkspaceBrowser (mode switch, search, rail icons, rename dialog,
drag), rows and tree derivations, the workspace fixture stubs, the rename/
insertSessionBefore wire rows, and the entity move semantics. HoverCard's
position state narrows to {left, top} (equivalent refactor, no behavior
change).
- rename same-title no-op moves inside the serialized creation chain
- insertSessionBefore maps only the typed WorkspaceMoveInvalidError to
workspace-move-invalid; storage failures stay internal
- workspace upsert rejects snapshots older than the installed projection
- flat-mode empty state shows when the query hides the intent row
- intent row no longer forces group expansion; header twist stays live
- group-by menu rides a portal; menu clicks stop propagating to the row
- intent row uses the same single-slot indent in both list modes
- regenerate cordis api/catalog + doc graphs
Sidebar session list grows the figma 239-10458 feature set and the
workspace/session browsing region moves wholesale into ui-workspace:
- Group-by menu (WorkSpace / In one list): flat mode lists every session
top-level, strictly newest-first; the choice persists across reloads.
- Session rows get a 500ms hover detail card (title / relative time /
status line) and a ... menu (Rename / Fork session / Delete session,
visual-only for now); workspace headers get ... with Rename (wired) and
Delete workspace (visual-only).
- workspace.rename RPC: trims, rejects duplicate titles on the create
chain (workspace-name-conflict), no-op on same title; modal dialog with
client-side duplicate pre-check.
- workspace.insertSessionBefore RPC (DOM-insertBefore semantics, omitted
anchor appends): HTML5 drag reorder of root sessions inside a workspace
group; order truth stays host-side, the view refreshes from the
response/changed frame.
- Activity pinning removed: the session/event touchSession chain is gone;
workspace accounts are manually owned (new sessions prepend, explicit
reordering only). Contracts and tests updated, api catalog regenerated.
- ui-sidebar reduced to the column shell (brand, fold state machine, New
Session, Settings) exposing one sidebar.workspaces hole with a two-fact
owner share {wide, expandSidebar}; ui-workspace owns the whole region
(header, search, grouped/flat lists, dialogs, drag) plus the picker via
a shared WorkspaceCreateFlow. The old sidebar.workspace picker slot and
its deferral indirection are gone.
- ui-primitives: Menu gains label entries, danger rows, and
closeOnPointerLeave; new HoverCard (portaled, open-delay, disabled
guard). Hover card and row menu never coexist.
Integrate the Commander adapter with master's `dsh web --workspace-root`
(workspace-aware session flow).
- args.ts: add `--workspace-root <path>` to the web subcommand; WebInvocation
carries workspaceRoot.
- web.ts: keep the adapter-parsed signature, take (host, port, dev,
workspaceRoot) and pass workspaceRoot through to AppCLIEntry (drop master's
re-added parseArgs and CLI host/port validation — the schema owns those).
- bin.ts forwards invocation.workspaceRoot; args.spec + the Agent Note pair note
the flag.
Integrate the Commander adapter with master's headless rework (dsh -p now boots
through AppCLIEntry — the same cordis.yml composition as dsh web, web-observable
while it runs — via toFetchHandler(ctx.apiProxy)).
- headless.ts: keep master's AppCLIEntry-based body but take the adapter's
pre-parsed `task` (drop the re-added parseArgs). Old startHost path and the
now-deleted packages/host/runtime dependency are gone.
- remove the stale packages/host/runtime dir left on disk by master's deletion
(mirrors the earlier packages/ui/acp cleanup).
ds-review-bot: `dsh web -p task`, `dsh web --resume s`, and `dsh --config c.yml
web` reached the web action with those values in program.opts() but the action
ignored them and served — silently dropping mode-specific inputs. The web
action now reads the parent opts and fails loud (exit 1) on a leaked
--config/-p/--resume, matching the root mode's mixing guard. Covered in
args.spec.ts.
Also (ds-review-bot): tui-demo/README documented the removed `dsh
[path-to-cordis.yml]` positional form; corrected to bare `dsh` / `dsh --config
<path>`. Agent Note + Chinese pair note the web-leak guard.
Coverage: api-proxy.ts joins the web-transport exclusion block (its
behavior specs moved here with it; the assembled-entry coverage lands with
the GUI test lane). Static: config-catalog regenerated after the log-round
revert shifted a source anchor. Prose brought current per review: the cli
README now describes the one shared composition (and its build
prerequisite), the apiproxy README points at the api-gateway row instead of
the deleted runtime package, and the config-tree agent note's headless
deferral paragraph records what actually landed (bilingual pair
re-recorded).
Boots a test-only cordis.yml through the real Loader and asserts the route
service's behavior surface: exact/longest-prefix matching, tapIndex
transform order and unsubscription, traversal 403, non-GET 405, SPA-200
fallback, malformed-request 400 without process exit, duplicate-pattern
throw, dispose closing held connections with register/disposer symmetry,
and a listen-failure fail-loud case (EADDRINUSE -> FAILED fiber + late
rejection). Replaces the retired factory-era specs.