* feat(gateway): task-suggestion acceptance modes with compact split-button card
- taskSuggestions.accept gains additive mode (worktree default | local | cloud | session) + cloudProfileId; operator.admin unchanged; worktree requests stay {taskId}-only for older gateways
- local reuses the plain-cwd create; cloud mirrors the Control UI create-empty -> sessions.dispatch -> send sequence with pre-claim profile validation and full rollback; session delivers the prompt into the source session (steer single active run, plain turn when idle, ambiguous refused) and can only cancel the chip on failure, never touch the source session
- Control UI card redesigned per owner reference: repo-basename eyebrow, clamped summary, instructions expander, split button with per-profile cloud items or a disabled "No cloud environment configured" hint
- TUI gains the same modes as selector rows with capability gating and double-Enter arming
Release-note context: operators now choose where an accepted follow-up runs — isolated worktree (default), the project checkout, a configured cloud worker, or as the next instruction in the current session — from a compact suggestion card.
* fix(gateway): negotiate task-suggestion acceptance modes and enforce steerable-run invariant
- Gate non-worktree task-suggestion actions on the negotiated Gateway capability.
- Require exactly one steerable run ID before delivering into an active source session.
* fix(ui): retain dashboards across view switches
Keep visited dashboard runtimes alive across Chat, Split, and Dashboard transitions, suspend hidden work, and avoid same-face persistence requests.
Refs #120639
* fix(ui): preserve session owner during route loads
Carry the last successful route match through pending loads so face-only navigation retains dashboard runtimes without stranding session or catalog switches.
Refs #120639
* fix(ui): preserve sandbox bridge while hidden
Suspend hidden board frame work without disposing the one-shot sandbox handshake, loaded document, or MessagePort.
Refs #120639
* fix(ui): forward sandbox readiness while hidden
Keep the constrained sandbox message channel alive during dashboard suspension so one-shot proxy readiness reaches the retained host without resuming widget work.
Refs #120639
* fix(ui): pause hidden plugin widgets
Propagate board activity through trusted plugin renderers so Workboard widgets suppress hidden refresh and mutation work, then refresh once without remounting.
Refs #120639
The visible-dock union existed twice: BoardVisibleChatDock (hand-written
literal union in lib/board/settings.ts, persistence layer) and
VisibleBoardDock (derived from the protocol BoardTab shape in
chat-pane-shared.ts, render layer). Follow-up from #120487.
Keep one canonical exported type in lib/board/settings.ts, now derived
from BoardTab so persisted settings can never drift from the wire
contract, and migrate all render-layer consumers to it. Net -5 LOC,
type-only.
* improve(ui): consolidate dashboard chat visibility into one Chat/Split/Dashboard toggle
The dashboard face spread chat visibility across three separate
affordances: a two-option face toggle, an icon-only dock dropdown among
the header actions, and a floating vertically-rotated "Show chat"
button on the board edge that users could not discover. One concept,
three controls.
The header now renders a single segmented control - Chat | Split |
Dashboard - where Split is dashboard plus docked chat and Dashboard is
board-only (the former "Hide chat"). A compact caret attached to the
pill picks the dock side (left/right/bottom) and only appears in Split
mode when dock mutation is allowed; read-only sessions keep the plain
two-option Chat | Dashboard toggle. The floating reopen button, the
standalone dock menu button, and their CSS (including the mobile
overrides) are deleted, so the header ends up with fewer buttons than
before.
Verified in the mock-gateway dev harness: mode mapping, caret dropdown,
unhide-to-remembered-side, and hidden dock rendering board-only.
* fix(ci): unexport board dock settings union and repair stale plugin-sdk baseline
BoardVisibleChatDock lost its last external consumer when the board
view switch consolidated dock controls; keep it file-local so the
production unused-export scan stays clean.
Also regenerate docs/.generated/plugin-sdk-api-baseline.sha256: the
session-catalog module hash was stale on main (check fails on clean
origin/main after the agent-attribution reverts), which blocks every
PR's check-plugin-sdk-api-baseline job.
* docs(web): describe the Chat/Split/Dashboard switch and dock-side picker
deriveSessionTitle no longer falls back to an 8-hex session-id prefix
plus date; derived titles are human content only, so consumers'
key-based fallbacks (Control UI "New thread", TUI formatted key, ACP
displayName/label/key) render instead of an opaque machine title.
* fix(ui): preserve active session status layout
* fix(ui): preserve avatar paths and fork lineage
* fix(ui): preserve avatars under control UI base paths