The shell has a coherent desktop frame: title bar, project rail, tool surfaces, conversation, editor, browser preview, terminal tray, dialogs, and accessible empty/loading/error states. Source and automated gates are strong: 305 test files/916 tests, production build, Chrome contract, module-size ratchet, and daily-driver metrics passed. The audit found two implementation gaps and several validation gaps that should remain roadmap work.
The workbench shell mounts with title bar, project rail, conversation area, tool area, and bottom utility tray. Empty surfaces provide project/chat entry actions rather than blank panes.
Primary action: Open Project… → native folder picker and workspace load.
Project creation and clone dialogs preserve the created path, expose progress, and offer retry/open-without-Git branches. The project switcher also exposes New Project and Open Project.
Primary action: New Project… / Clone Repository… → project setup then workspace.
New Task routes to the active project, or opens project selection when no project is active. The empty chat offers clickable suggestions and the composer.
Primary action: Send → streaming assistant turn.
| Screen | Purpose | Primary action | States |
|---|---|---|---|
| Workbench shell | Orient the user and host surfaces | Open Project / New Task | Empty suggestions; launch error alert; crash recovery notice |
| ProjectCreationDialog | Create folder and optional Git repository | Create project | Creating, initializing, opening, retry, open without Git |
| CloneRepositoryDialog | Clone into a chosen destination | Clone | Progress, cancellation, error, open project |
| Check | Verdict | Note |
|---|---|---|
| No blank shell panes | PASS | Empty chat, editor, browser, and project surfaces have purposeful actions or copy. |
| Multi-step workflow avoids an oversized modal | WARN | Creation and clone are multi-phase dialogs. They are usable and recoverable, but a full-surface route would reduce modal density. |
| Failures preserve user work and offer recovery | PASS | Creation retains path; Git/open failures expose retry alternatives. |
| Packaged project-entry flow is executed | WARN | Packaged startup/window paint was captured outside the sandbox; full operator-driven create/clone/open interaction remains unverified. |
The project switcher filters open/recent projects, marks the current project, supports arrows/Enter/Escape, and exposes New/Open Project actions.
Primary action: Switch Project… → selected workspace.
Projects, Git, Browser, Settings, and Files are represented by labeled tabs. Collapsed mode keeps visually hidden labels and tooltips for icon-only controls.
Primary action: Files / Git / Browser → corresponding dock surface.
The command/search dialog groups chat results as Tasks and actions as Commands, with a listbox, keyboard navigation, loading text, and an unavailable-search state.
Primary action: Run → command action or selected task.
| Screen | Purpose | Primary action | States |
|---|---|---|---|
| ProjectSwitcher | Move between workspace context | Choose project/session | Filtered list; current item; empty list; keyboard escape |
| WorkspaceSideRail | Change the active tool surface | Select rail tab | Collapsed/expanded; selected tab; disabled/empty tool contents |
| SearchCommandDialog | Find tasks and invoke actions | Run selected result | Loading; no match; chat search unavailable |
| Check | Verdict | Note |
|---|---|---|
| Every navigation path has a visible destination | PASS | Rail, project switcher, title-bar actions, command palette, and context menus route to named surfaces. |
| Keyboard and pointer paths agree | PASS | Switcher and command dialog implement arrows/Enter/Escape; controls are real buttons. |
| Deep-link/back-forward semantics | WARN | This is a native desktop app with no browser URL state; reopening a prior task depends on persisted app records, not a shareable route. |
| Open chat in a separate window | FAIL | No “Open in New Window” action or multi-window routing is present in the source; roadmap cards remain open. |
The composer supports attachments, context, permissions, goal, provider/model/reasoning pickers, keyboard submit, and an Add menu rendered through a portal.
Primary action: Send → active run.
The thread is a log with polite live announcements, aria-busy while active, turn grouping, activity timeline, tool details, approval controls, minimap, and Jump to latest.
Primary action: Stop → terminate active run.
Assistant markdown supports code highlighting/copy. Message actions support Copy, Fork, and Bookmark; file tool cards can open a review surface.
Primary action: Fork chat from this message → branch conversation.
Error messages expose Retry when a retry prompt exists; the composer remains available after completion/error.
Primary action: Retry → a new run from the saved prompt.
| Screen | Purpose | Primary action | States |
|---|---|---|---|
| AgentComposerSurface | Enter task and configure run | Send / Stop | Empty; attachments; disabled while sending; provider/model controls |
| ChatThreadSurface | Read streamed turns and activity | Approve tool / Jump latest | Running, complete, error, approval pending, empty suggestions |
| ChatMessageArticle | Review and act on a message | Copy / Fork / Bookmark / Retry | Assistant, user, tool, error, focused message |
| Check | Verdict | Note |
|---|---|---|
| Streaming has visible progress and stop | PASS | Live status, activity timeline, running tool rows, aria-busy, and Stop are implemented. |
| Composer remains useful during generation | WARN | Initial send disables composer while active; there is no queue/interject path for a long run. |
| Errors are actionable and retryable | PASS | Retry is conditional on a persisted retry prompt; tool approvals have explicit decisions. |
| Edit/regenerate/version history | FAIL | No edit-message, regenerate, alternate-answer pager, or explanation of branch semantics exists. |
| Citations/feedback for grounded answers | WARN | Markdown and code copy exist, but citation/source cards and answer feedback controls are absent; treat as a product decision. |
The editor maintains tabs, snapshots, cursor state, load/save state, and dirty buffers. Search, diff review, reveal, and external open are available.
Primary action: Save → persisted file or conflict recovery.
Save errors show the cause and offer Retry. Conflicts branch to Reload or Overwrite; external open is offered when supported.
Primary action: Retry / Reload / Overwrite → restored editor state.
Tool docks and the utility tray preserve the conversation shell while switching context; terminal actions include clear, paste, focus, restart, and worktree persistence.
Primary action: Open Browser / Git / Terminal → selected dock.
| Screen | Purpose | Primary action | States |
|---|---|---|---|
| Editor surface | Edit and review workspace files | Save / search / diff | Loading, dirty, saved, conflict, save error |
| Browser preview | Inspect the project preview | Open/reload preview | No URL/server, loading, runtime error |
| Utility tray/terminal | Run and observe shell work | Focus, paste, restart, resize | Closed/open, active panes, launch failure |
| Check | Verdict | Note |
|---|---|---|
| Independent scroll regions | PASS | Conversation scrolling and tool/editor surfaces are separately owned; Jump to latest is explicit. |
| Save errors explain safe choices | PASS | Conflict UI distinguishes Reload from Overwrite and retains recovery error text. |
| Terminal input works for international text | WARN | Roadmap still calls out native Option-dead-key é, CJK IME, and visual fallback as unverified. |
| Long-running background work remains observable | WARN | In-surface activity exists; daily-driver and packaged timing/notification coverage is not equivalent to a background notification contract. |
Settings lists Codex, Gemini, Claude, and OpenCode model fields. Native provider keys are write-only in Keychain; OpenCode delegates authentication to its own runtime.
Primary action: Save key → Keychain state becomes configured.
MCP rows expose enabled state, transport/target/auth summary, Check, Remove, and OAuth actions. Validation status and OAuth message are shown inline.
Primary action: Check → target status.
OAuth rows expose Authorize/Reauthorize, pending state, connected state, and Disconnect. The source has explicit OAuth status plumbing.
Primary action: Authorize → external consent flow, then connected state.
| Screen | Purpose | Primary action | States |
|---|---|---|---|
| ConnectionSettingsPanel | Configure provider, project, and MCP connection inputs | Save/check/authorize | Keychain empty/configured; inline alert; validation; OAuth pending/connected/error |
| Provider row | Set model and credential presence | Save key / Clear | Write-only secret; disabled actions; save failure |
| MCP row | Control server and auth state | Check / Authorize | Enabled; checking; OAuth pending/connected; remove |
| Check | Verdict | Note |
|---|---|---|
| Secrets are not echoed back | PASS | Provider text is password input and presence is represented as Keychain configured/empty. |
| Auth state is visible and reversible | PASS | Authorize/Reauthorize, connected status, and Disconnect are explicit. |
| Errors retain context and recovery | WARN | Inline error plumbing exists, but packaged OpenCode execution, OAuth consent, and provider credential validation remain unexecuted. |
| Provider setup is verified in the native app | WARN | Source/test evidence is not a substitute for the operator-consented packaged run listed in ROADMAP.md. |
Session context actions include rename, export, stop, fork, checkpoint capture/restore, pin, archive, and delete, with eligibility based on active/running state.
Primary action: Archive / Delete / Restore checkpoint → updated session state.
Launch failures expose Open Project and Use Shell profile. Crash notices are dismissible status notices. Terminal panes can be restarted.
Primary action: Use Shell profile / Restart pane → alternate execution path.
Checkpoint restore blocks when a dirty editor buffer would be overwritten and names the protected path, requiring save or discard first.
Primary action: Save or discard the dirty buffer → safe restore.
| Screen | Purpose | Primary action | States |
|---|---|---|---|
| Session context menu | Operate on a conversation | Fork/archive/delete/export | Active/running gating; checkpoint protection |
| AppNotices | Surface global recovery | Open project / shell profile | Crash status; action status; launch alert |
| EditorSaveError | Resolve persistence conflict | Retry/reload/overwrite | Conflict, saving, recovery error |
| Check | Verdict | Note |
|---|---|---|
| Destructive actions have confirmation or undo | WARN | Eligibility gating is explicit, but this audit did not find a consistent undo affordance in the context-menu assembly; verify delete/archive confirmation in packaged use. |
| Dirty work is protected | PASS | Checkpoint restore names the protected dirty path and blocks unsafe replacement. |
| Global errors state cause, fix, and work safety | WARN | LaunchError renders the backend message plus two recovery buttons, but does not consistently explain cause, safety, or a direct Retry action. |
| Failures are visually announced | PASS | Save and launch errors use role=alert; recovery/action notices use role=status. |
qa:perf-budget currently fails with missing-budget-evidence.