feat: sidebar pane rename, one-shot default agent launch, neutral row status - #551
feat: sidebar pane rename, one-shot default agent launch, neutral row status#551tbrownio wants to merge 12 commits into
Conversation
Add a shared Pane context menu (Rename, Pin/Unpin, Archive) to the expanded, compact, and pinned sidebar entries, backed by a rename dialog that trims input and rejects blanks. Renames go through one main-process helper that writes only the display name plus a new name_manually_set provenance bit, which the AI namer now respects; the stored name is the label everywhere and PR titles stay metadata, so the dormant auto-rename-to-PR-title setting is removed. Expanded rows lose the coloured accent bar and label animation and show agent state through SessionStatusBadge instead. Adds the DB columns both workstreams need and extracts runAgentDoctor into a service module. Claude-Session: https://claude.ai/code/session_01A6ystbZhfNVGeSUc7x8DNm
The interactive Add Repository dialog now discloses the configured default agent and sends launchDefaultAgent: true; projects:create then runs a main-owned, single-flight one-shot that validates platform and executable, creates the main session and a terminal panel, spawns the PTY, waits for CLI readiness, and only then writes a durable receipt. Any failure destroys the panel, leaves the project blank, writes no receipt, is memoised so nothing retries, and surfaces a non-modal notice with a manual Open agent action. The default agent setting copy now names both uses. Claude-Session: https://claude.ai/code/session_01A6ystbZhfNVGeSUc7x8DNm
|
React Doctor found 1 new issue in 1 file · 1 warning · score 74 / 100 (Needs work) · 0 fixed · vs Reviewed by React Doctor for commit |
Suppress the default Terminal that session-created auto-creates when the one-shot launch owns the session, so a launch yields exactly one agent tab and a failed launch leaves none. Verify provisional-panel removal with a retry and DB fallback and report any stale panel. Send the launch flag only when the dialog actually disclosed the agent, ignore dialog close while creating, and keep the failure notice if Open agent fails. Make the Pane context menu keyboard-operable (focus, arrows, Home/End, Escape restores the opener). Return raw rename errors only for the typed validation error, fix the stale single-flight entry on skip paths, drop the unused menu label field, and de-flake the Playwright text assertion. Claude-Session: https://claude.ai/code/session_01A6ystbZhfNVGeSUc7x8DNm
Pre-allocate the agent panel id so a persist-then-reject createPanel is still cleaned up, create the suppressed-terminal main session before the agent doctor runs so every attempted launch that fails leaves Explorer and Diff only, and bound the spawn plus readiness wait with one 45 s deadline so Add Repository can never hang. Context-menu opener falls back to the row element; Playwright covers the pinned expanded copy. Claude-Session: https://claude.ai/code/session_01A6ystbZhfNVGeSUc7x8DNm
When the 45 s launch deadline fires while the terminal is still queued for a spawn slot, the failure path now arms a late guard that destroys a terminal registering after cleanup, and initializeTerminal revalidates that its panel still exists after acquiring the slot and before spawning, so a deleted panel never runs the permissive agent command. The dialog also sends the agent it disclosed and main refuses to launch a different one. Cleanup probes are guarded so a DB read cannot escape the catch. Claude-Session: https://claude.ai/code/session_01A6ystbZhfNVGeSUc7x8DNm
An automatic launch now needs both the launch flag and the exact agent the dialog disclosed; a request without a disclosed agent, or with a different one, is skipped before any session or panel exists. Claude-Session: https://claude.ai/code/session_01A6ystbZhfNVGeSUc7x8DNm
Whitespace only (git diff -w is empty); applied from the refactor pass. Claude-Session: https://claude.ai/code/session_01A6ystbZhfNVGeSUc7x8DNm
QA drive evidence — PR #551Driver: the repo's own Playwright harness (Chromium + J1 — Rename from the sidebar (M1–M4, AC1/2/4/5)
📹 Journey video: J1-rename-propagation.webm (4.5 s; local J2 — Add repository, launch once (M5 renderer half, AC6)
📹 Journey video: J2-launch-once.webm (3.2 s; local J3 — Failed launch → notice → Open agent / Dismiss (M8 renderer half, M9, AC10)
📹 Journey video: J3-failed-launch-open-agent.webm (1.1 s; local J5 — No default agent (M10, AC9) and J6 — Clone from GitHub sends no flag (M11)
📹 Journey video: J6-clone-from-github.webm (0.7 s; local Other videos: J1-cancel-escape-pr-refresh.webm, J3-dismiss.webm, J5-no-default.webm. Playwright traces for all 18 tests are hosted as Console (rubric 5): every journey asserted zero console errors after filtering one pre-existing mock artifact — the mock leaves Passed automatedM1, M3, M4, M10, M13 in full; M2, M9, M12 for their renderer halves; AC1, AC2, AC4, AC5, AC6 (renderer), AC9 (mock approximation), AC10 (renderer), AC12, AC13. Remaining for the human
|
tbrownio
left a comment
There was a problem hiding this comment.
Surviving Should-Fix / Nice-to-Have findings from the automated review + refactor passes (none block merge; details inline).
type: wrap-up-report
|
type: postmortem
|
| Step / dispatch | Start | End | Dur | Tokens | Est. cost | Note |
|---|---|---|---|---|---|---|
| Step 0 preflight + load + brief.html | 18:24 | 18:28 | 04:04 | overseer | — | gh/codex/pnpm probes, install no-op, intake artifact |
| code-researcher (Codex) | 18:28 | 18:30 | 02:09 | 95,070 | unknown (blended) | ran while Overseer read anchors |
| Overseer anchor reading + plan.md | 18:28 | 18:40 | 12:06 | overseer | — | serial with research (overlapped) |
| plan-reviewer pass 1 (Codex) | 18:40 | 18:43 | 02:57 | 133,573 | unknown | parallel with Claude lane |
| plan-reviewer pass 1 (Claude) | 18:40 | 18:48 | 07:22 | 144,459 | unknown (no class split) | 7:22 — the slower lane |
| plan revision 1 (Overseer) | 18:48 | 18:52 | 04:37 | overseer | — | 14 MF folded |
| plan-reviewer pass 2 (Codex) | 18:52 | 18:55 | 02:26 | 100,767 | unknown | parallel |
| plan-reviewer pass 2 (Claude) | 18:53 | 18:59 | 06:27 | 104,699 | unknown | 6:27 |
| plan revision 2 (Overseer) | 18:59 | 19:02 | 02:37 | overseer | — | |
| plan-reviewer pass 3 (Codex) | 19:02 | 19:05 | 03:20 | 120,406 | unknown | parallel |
| plan-reviewer pass 3 (Claude) | 19:02 | 19:09 | 06:54 | 113,234 | unknown | 6:54 |
| plan revision 3 + implementer launch | 19:09 | 19:10 | 01:21 | overseer | — | cap reached |
| implementer (Codex, all 22 tasks) | 19:10 | 19:27 | 17:05 | 400,698 | unknown | 17:05; diagram authored in parallel |
| Excalidraw diagram + hosting (Overseer) | 19:11 | 19:20 | 08:41 | overseer | — | overlapped implementer |
| backend-verifier (Codex) | 19:28 | 19:30 | 02:26 | 66,526 | unknown | 2:26 |
| build gate + commits + push + PR open | 19:30 | 19:34 | 03:06 | overseer | — | frontend build in background |
| code-reviewer pass 1 (Codex) | 19:34 | 19:37 | 03:44 | 172,211 | unknown | 4 MF incl. events.ts double terminal |
| code-reviewer pass 1 (Claude) | 19:34 | 19:41 | 07:03 | 140,096 | unknown | 0 MF / 3 SF |
| implementer fix round 1 (resume) | 19:41 | 19:48 | 07:01 | 412,786 | unknown | 7:01 |
| code-reviewer pass 2 (Codex) | 19:49 | 19:52 | 02:38 | 134,187 | unknown | 2 new MF |
| code-reviewer pass 2 (Claude) | 19:49 | 19:57 | 08:04 | 146,135 | unknown | 0 MF / 2 SF |
| implementer fix round 2 (resume) | 19:58 | 20:05 | 07:03 | 103,336 | unknown | 7:03 |
| code-reviewer pass 3 (Codex) | 20:06 | 20:09 | 02:59 | 134,843 | unknown | 1 MF (orphan PTY) |
| code-reviewer pass 3 (Claude) | 20:06 | 20:09 | 03:31 | 87,277 | unknown | 0 MF / 1 SF (same orphan PTY) |
| implementer fix round 3 (resume) | 20:10 | 20:13 | 03:18 | 108,591 | unknown | 3:18 |
| scoped code-reviewer 1 (Codex) | 20:14 | 20:16 | 01:49 | 91,257 | unknown | 1 MF (disclosure omitted) |
| implementer fix round 4 (resume) | 20:16 | 20:19 | 02:36 | 65,267 | unknown | 2:36 |
| scoped code-reviewer 2 (Codex) | 20:19 | 20:21 | 01:04 | 68,538 | unknown | clean |
| refactor-simple (Codex) | 20:19 | 20:21 | 01:55 | 117,464 | unknown | parallel with scoped review |
| refactor-deep (Codex) | 20:19 | 20:24 | 04:20 | 200,525 | unknown | 2 'Critical' = owner decisions |
| implementer refactor apply (whitespace) | 20:24 | 20:26 | 01:24 | 20,726 | unknown | git diff -w empty |
| fresh-eyes PR body: Overseer + 2 agents | 20:25 | 20:29 | 04:22 | 86,776 (agents) | unknown | pass 3 no change |
| frontend-verifier QA drive (Claude) | 20:27 | 20:35 | 08:07 | 126,951 | unknown | 18 tests, 45 shots, 7 videos |
| QA hosting + body + evidence comment + inline comments | 20:35 | 20:38 | 03:00 | overseer | — | 70 assets to qa-assets |
| wrap-up + fresh-eyes ×2 + label + notify | 20:38 | 20:41 | 02:37 | overseer | — |
Aggregates (share of 2:17): Step 0 + research + plan writing 16 m (12 %) · plan-review loop 30 m (22 %) · implement 17 m (12 %) · verify + PR 6 m (4 %) · post-PR review + fix loop 46 m (34 %) · scoped/refactor 9 m (7 %) · fresh-eyes + QA drive + evidence 12 m (9 %) · wrap-up 3 m (2 %). Summed Overseer turnaround gaps between a report landing and the next dispatch: ≈ 14 m total, never more than ~4 m each (plan revisions were the largest). Human-idle 0.
Ranked stalls: none in-run. The longest productive waits were the implementer's first dispatch (17:05) and each Claude review lane (6–8 m per pass, consistently the slower lane by 3–5 m).
Per-phase pacing from commits (PDT): 12:32 feature commits ×2 → 12:49 fix 1 → 13:06 fix 2 → 13:14 fix 3 → 13:19 fix 4 → 13:26 whitespace refactor. Fix rounds every 8–17 m, each gated by a full dual-lane review pass.
Blocker inventory: AskUserQuestion gates 0 · rate-limit hits 0 · red gates 0 · environment notes 2 (no Playwright MCP registered for Claude sub-agents → QA drive used the repo's Playwright harness; the Claude reviewer's node ABI mismatched better-sqlite3, so it could not run three Vitest suites and read them instead — Codex lanes and the verifier ran them green).
Tokens & cost. Overseer (claude-fable-5, 1 h cache TTL): input 23,619 + output 222,302 + cache read 67,938,206 + cache write 598,829 → ≈ $91 (0.24 + 11.12 + 67.94 + 11.98). Claude sub-agents 949,627 (notification totals; per-class split not harvested → cost unknown). Codex 2,546,771 blended tokens used → cost unknown (no class split survives the blend). The overseer's cache reads are 94 % of raw volume: a 186-message turn loop over a ~370 k-token context.
The single change that would have cut the most time: the post-PR loop spent 46 m on three full dual-lane passes plus two scoped passes because the first implementer pass shipped a defect the plan could not have known about only by reading (events.ts auto-creates a Terminal on every session-created). A cheap, targeted "listener/side-effect sweep" in the code-researcher dispatch (grep every sessionManager.on(...) / panelManager event consumer touched by the plan) would have surfaced it at plan time, collapsing at least one review pass and one fix round (~15 m, ~700 k Codex tokens).
What we asked for
Owner-approved brief: display-only Pane rename from the sidebar; once-only default-agent launch on Add Repository with blank state on skip/failure; neutral sidebar rows with the status badge instead of the accent bar. Zone 1, escalated to effective 0.
Outcome vs intended
On-target as far as the run can tell — every AC has automated or QA-drive evidence except the real-agent manual items (AC6–AC8) and three owner decisions recorded in the PR. The outcome half of this postmortem runs after PR review.
Why the gap happened
Omitted — operations-only.
What to change so it doesn't recur
claude/agents/code-researcher.md(dcouple/orchestra) — add to Method step 2: "For every event the plan will emit or listen to (emit('…'),.on('…')), enumerate all existing listeners and their side effects withpath:line; a listener that creates, deletes, or launches something is a load-bearing finding." Evidence:main/src/events.ts:64-75was missed by the researcher and by three plan-review passes; it cost one review pass + one fix round.claude/skills/do/SKILL.md— Step 1, plan-review dispatch: when the item touches process/PTY lifecycle, instruct reviewers to trace the full lifecycle including deadline/cancellation paths ("what happens if the awaited call completes after the caller gave up?"). The orphan-PTY-after-deadline defect (pass 3 + scoped pass) is the generic "late completion after cancellation" class; naming it in the dispatch would have caught it in pass 2 when the deadline was introduced.references/zones.md— data point, no edit proposed yet: at effective zone 0 the Claude review lane found 0 Must Fix in all three post-PR passes (its findings were Should Fix that Codex escalated or duplicated), while costing 373 k tokens; the Codex lane found every Must Fix. Two more runs like this would justify making the second lane plan-review-only at zone 0 for single-phase items.references/notify.md/claude/skills/do/SKILL.mdStep 0 — preflight should probe for a registered Playwright MCP server (claude mcp list) when the item is browser-required and say explicitly which driver the QA drive will use; this run discovered the gap at preflight but only by reading the agent charter.
Dial record & right-sizing
zone: 1 # item; Overseer-escalated to effective 0 (permissive agent launch = trust boundary)
lanes: dual
passes: {plan: 3/3, post_pr: 3/3, post_pr_scoped_extra: 2}
findings: {plan: {pass1: {codex: 9, claude: 5}, later: {codex: 5, claude: 7}},
post_pr: {pass1: {codex: 4, claude: 0}, later: {codex: 3, claude: 0}}} # Must Fix counts; Claude lane raised 3+2+1 Should Fix
verifiers: {frontend: ran, qa_pass: ran}
qa_findings: 0
cleanup: {disposition: none_created, markers: [agent-e2e-20260829], registered: 0}
wall_clock: 2:13 (transcript first event 2026-08-29T18:24Z → wrap-up 20:37Z; single session, no resume)
deviations: "escalated 1→0: permissive agent auto-launch is a trust boundary; dual review lanes"
pr_size: {files_changed: 53, additions: 2412, deletions: 711}
tokens:
codex: {total: 2546771, by_role: {implementer: 1111404, plan_reviewer: 354746, code_reviewer: 601036, code_researcher: 95070, backend_verifier: 66526, refactor_simple: 117464, refactor_deep: 200525}}
claude_subagents: 949627 # plan-reviewer 362392, code-reviewer 373508, fresh-eyes 86776, frontend-verifier 126951 (harness usage summaries)
overseer: 68782956 # transcript JSONL, dedup by message.id: input 23619 + cache_create 598829 + cache_read 67938206 + output 222302
total: 72279354
spend_ratio: 23144.2 # tokens.total ÷ 3123 changed lines; cache reads dominate the overseer figure
agents:
- {role: code-researcher, model: gpt-5.6-sol, effort: low, dispatches: 1, wall_clock: 2:09, tokens: 95070}
- {role: plan-reviewer, model: gpt-5.6-sol, effort: medium, dispatches: 3, wall_clock: 8:43, tokens: 354746}
- {role: plan-reviewer, model: claude-opus, effort: thinking, dispatches: 3, wall_clock: 20:42, tokens: 362392}
- {role: implementer, model: gpt-5.6-sol, effort: medium, dispatches: 6, wall_clock: 38:27, tokens: 1111404}
- {role: backend-verifier, model: gpt-5.6-sol, effort: low, dispatches: 1, wall_clock: 2:26, tokens: 66526}
- {role: code-reviewer, model: gpt-5.6-sol, effort: medium, dispatches: 5, wall_clock: 12:14, tokens: 601036}
- {role: code-reviewer, model: claude-opus, effort: thinking, dispatches: 3, wall_clock: 18:38, tokens: 373508}
- {role: refactor-simple, model: gpt-5.6-sol, effort: medium, dispatches: 1, wall_clock: 1:55, tokens: 117464}
- {role: refactor-deep, model: gpt-5.6-sol, effort: medium, dispatches: 1, wall_clock: 4:20, tokens: 200525}
- {role: fresh-eyes, model: claude-opus, effort: thinking, dispatches: 2, wall_clock: 2:37, tokens: 86776}
- {role: frontend-verifier, model: claude-sonnet, effort: thinking, dispatches: 1, wall_clock: 8:07, tokens: 126951}Judgment: review effort slightly overdone — right-sized on the Codex lane, overdone on the Claude diff-review lane. Plan review (3 passes, both lanes) paid for itself: 14 Must Fix folded before code. Post-PR: Codex passes 1–3 found 4/2/1 Must Fix (all real; pass 3's orphan PTY was security-relevant), so the cap was earned; the Claude diff lane caught 0 Must Fix across three passes for 373 k tokens — the single dial that would have changed it is review_lanes: single for the post-PR loop at this zone (keep dual for plan review).
Acceptance
Still awaiting review (operations-only postmortem).
System changes
- PR comment: (filled after posting)
- Work item: local-only intake artifact (no tracker) — no second anchor.
- Proposals 1–4 above: pending human verdict; nothing applied.
Make the AC11 import-guard test separator-agnostic so it passes on windows-2022. Drop the React Doctor prop-change effects by keying the context-menu body, rename dialog body, and dialog error state instead. Extract the duplicated sidebar menu/rename/focus lifecycle into usePaneContextMenu, split launchDefaultAgentOnce into attempt, readiness, and cleanup helpers, and forget a project's launch memo when the project is deleted. Claude-Session: https://claude.ai/code/session_01A6ystbZhfNVGeSUc7x8DNm
…eted Each launch attempt carries an AbortController; projects:delete aborts it before teardown and forgets the memo regardless of the delete result. The attempt re-checks cancellation and the project row before every stage, runs the normal provisional-panel cleanup, and never writes a receipt after cancellation. Rejected attempts are memoised as a failed result, and the rename dialog selects its prefilled text once. Claude-Session: https://claude.ai/code/session_01A6ystbZhfNVGeSUc7x8DNm
Final readiness evidence —
|
Sidebar rows and headers now use the navigation text family instead of body text-primary, and the dark/light navigation-primary tokens sit a step below body text so the rail reads as navigation. The pane hover card drops the PR body, status prose, and 10px type for a compact card: name, branch, last activity, PR number + state pill + diff size, title, and a View on GitHub link. Claude-Session: https://claude.ai/code/session_01LfUbWdfJ7xSx8a3TPq4XWC
The archive and pin buttons were transparent but still occupied their slots, so every idle row reserved 48px to the right of its git stats. They now sit left of the stats and collapse to zero width until the row is hovered or focused, which leaves the stats on the row's right edge and gives the pane name that width at rest. A pinned pane keeps its pin visible. Claude-Session: https://claude.ai/code/session_01LfUbWdfJ7xSx8a3TPq4XWC















































Summary
Three independent sidebar/workspace-entry changes. They share a theme — the sidebar behaved like a Git control, not a workspace navigator — but review them separately; nothing in one depends on another.
Change 2 is the one to read closely: it is new main-process ownership of "first entry" with a receipt (a nullable
projects.default_agent_launched_attimestamp meaning "the automatic tab was created"), a deadline, and a cleanup path.1. Rename
Why. There was no way to give a Pane a human label without renaming its branch.
How. One main-process helper (
renameSessionDisplayName) shared by the UI and the RunPane CLI: it trims, rejects blanks, writessessions.nameplus a newname_manually_setprovenance bit, and emits the existingsession-updated. The stored name is now the label everywhere; PR title/number stay metadata (tooltip, title-bar pill, diff header,#n). The automatic AI namer honours the provenance bit instead of comparing strings. The dormant "Auto-rename panes to pull request titles" setting is removed — nothing produced it.Done means. Right-click → Rename works on all four Pane renderings (expanded row, expanded pinned copy, compact icon, compact pinned icon) and touches nothing but the label.
2. One-shot default-agent launch
Why. A freshly added repository opened onto an empty stage.
How. Launch is owned by main, not a React effect.
projects:createacceptslaunchDefaultAgent: trueplusdisclosedAgent— sent only by the Add Repository dialog, and only when it actually rendered the disclosure — and runslaunchDefaultAgentOnce:projects.default_agent_launched_at) is written last;runpane agents doctor) before any panel exists;session-createdlistener not to auto-create the plain shell Terminal every new session otherwise gets (main/src/events.ts), so a successful launch yields exactly one terminal — the agent's;initializeTerminalre-checks its panel still exists after acquiring a spawn slot — a cleaned-up panel can never run the permissive command.Done means. Adding a repo with a default agent configured yields one live agent tab that never duplicates across remount, navigation, restart, or tab close; a failed launch leaves the project with Explorer/Diff only plus a non-modal Open agent notice; no default agent means nothing is launched.
3. Neutral rows
Why. Expanded rows carried a second, full-height colour channel that duplicated the status dot and fought with selection/hover.
How.
StatusAccentBarand both row animations are deleted;SessionStatusBadge(sizesm) sits in a fixed trailing slot; selected/hover keepbg-surface-selected/hover:bg-surface-hover.Done means. No accent bar or label animation remains and every agent state is still announced accessibly.
Whole PR, green across the board:
pnpm lint,pnpm typecheck, main Vitest,pnpm theme:contrast, and the focused Playwright specs.Visual overview
The launch is the flow-shaped change — before, nothing owned "first entry"; after, main runs a gate sequence with a receipt written last:
Before — the compact Pane menu offered only Pin and Archive (expanded rows had no context menu at all):
After — from the QA drive (Electron-mock Playwright, night-owl theme unless noted):
Full galleries (five agent states × two modes, four themes × selected/hover/focus, narrow width, dialogs) are in the QA evidence comment.
User journeys
J1 — Rename a Pane from the sidebar. Right-click a Pane (expanded row, compact icon, or either pinned copy) → Rename → a small dialog with the current name selected → type
Human label→ Enter → the row, the compact tooltip, the pinned copy, and the window title all readHuman labelimmediately; the branch, worktree folder, and PR badge are untouched. Blank input can't be saved; Escape/Cancel changes nothing.J2 — Add a repository with a default agent configured. Sidebar → Add repository → name + path → the dialog says "Creating this repository will start Claude Code in it (
claude --dangerously-skip-permissions). Close the tab at any time." → Create (button reads "Starting Claude Code…" while main validates and spawns) → the project opens with Explorer, Diff, and one live Claude Code tab already running. Navigate away and back, close the tab, restart Pane — no second tab ever appears.J3 — Add a repository when the agent can't start. Same dialog → Create → main finds the agent binary missing (or the platform unsupported, or the process exits/never becomes ready) → the project still opens with Explorer and Diff only (no terminal tab at all) and a bottom notice: "Repository added, but Codex could not start. " and Open agent / Dismiss. Open agent creates the same agent tab through the normal
+-menu path; nothing retries on its own.J4–J6 are the paths with no new UI: J4 replay (second call, restart), J5 no default configured, J6 other project creators. The map shows where each one exits.
Flow map (Add Repository)
Gap flagged honestly: an agent that starts and then shows its own login/trust prompt is a live tab, not a failure — see Residual risks.
Verification
Every AC below is covered by automated tests except where it says Manual — those are AC6–AC8, whose end-to-end proof is the real-agent Manual items (M5–M9 and M11) a mock can't reach.
Rename (AC1–AC5)
tests/sidebar-pane-actions.spec.ts(menu orderRename, Pin, Archiveon all four renderings) → 14 passed. Driven again in the QA drive.' Human label '→ call['regular','Human label']; blank disables Save; Escape makes no call) → passed.name+ provenance written —main/src/ipc/session.rename.test.tsassertsupdateSession(id, { name: 'Human label', name_manually_set: true })and untouchedworktree_name/worktree_path/base_branch→ 4/4.document.title— same Playwright spec → passed.emitGitStatusUpdatedwith a newprTitle) → passed.Launch (AC6–AC11)
tests/add-repository.spec.ts(5/5); main half inmain/src/services/workspaceEntry.test.ts(23/23); real-agent end-to-end is Manual (M5).createPanel; a later call replays the identical memoised result; receipt asserted after readiness (call order). Real remount/restart is Manual (M6).already-launched) + Manual (M7).no-default, nocreatePanel) + Playwright (omitDefaultOrchestratorAgent).deletePanel, a rejectingdeletePanelfalls back to DB removal, noupdateProject, Explorer re-selected;main/src/events.test.tsproves the default Terminal is skipped only whenautoCreateTerminal === false) + Playwright (notice →panels.createPanelwithcodex --yolo/agentType: 'codex'; Dismiss creates nothing).main/src/ipc/project.tsimports the service), exactinitialStateassertion,project.create.test.ts(flag absent/false → never invoked); Playwright: Clone from GitHub sends no flag.Neutral rows (AC12–AC13)
.w-1rail, nosidebar-active-label/status-workingclass,bg-surface-selectedkept) +pnpm theme:contrast148/148. Visual pass across themes in the QA drive.[role=status][aria-label="Agent <state>"], expanded unknown →Agent status unknown, compact placeholder unchanged) → passed.Suite-wide (AC14) and gates
pnpm lint(oxlint, ESLint, boundary conformance, Knip) ✓ ·pnpm typecheck✓ ·pnpm --filter main exec vitest run856 passed / 1 skipped ✓ ·pnpm theme:contrast✓ ·pnpm --filter frontend build✓ · focused Playwright 14 + 5 passed ✓.Manual tests
Fourteen items; the six Must ones need a real repository and a real agent binary.
Must (breaks data/auth/money if wrong):
Default agent= Claude Code, add a real repository → dialog discloses the agent → one Claude Code tab starts next to Explorer/Diff; Create was the only confirmation. — left to human: needs a real Electron app + agent binary (renderer half driven: disclosure, busy state, single confirmation)runpane repos addcreate projects with no automatic agent tab. — Clone from GitHub driven (no flag sent); left to human: onboarding andrunpane repos add(proven by the static import guard in Vitest)Important (user-facing behaviour):
Human label→ row, compact tooltip/aria-label, pinned copy, and window title showHuman label;git branch --show-currentand the worktree folder are unchanged. — label propagation driven; left to human: the Git-identity check needs a real worktreeNice (cosmetic):
Areas not affected: worktree creation/archiving, terminal restore/resume, Pane Chat, PR metadata fetching, the remote PWA sidebar, project rename/delete.
QA results
QA drive (Electron-mock Playwright, 18 driven tests, 45 screenshots, 7 journey videos, axe clean on menu/rename/Add-Repository dialogs): 8 of 14 items executed and passed (M1–M4, M9, M10, M12, M13; several with a real-app half left to you as annotated), 6 left to the human (M5–M8 and M11 need a real Electron window / agent binary / restart; M14 is a Settings-copy read). No bug found. One pre-existing test-mock artifact disclosed (unmocked
sessions.getlogs a console error on project creation; not a product change). Cleanup: none created — all state lived in the in-memory mock. Proof with galleries and video links: see the QA evidence comment below.Deploy notes
Nothing for an operator to do. Two additive nullable columns land through Pane's own startup migration.
ALTER TABLE sessions ADD COLUMN name_manually_set BOOLEAN DEFAULT 0—main/src/database/migrations/add_session_name_provenance.sql, runtime check inmain/src/database/database.ts.ALTER TABLE projects ADD COLUMN default_agent_launched_at TEXT—main/src/database/migrations/add_project_default_agent_launch.sql, runtime check inmain/src/database/database.ts.Residual risks
The first two are the owner decisions from the Summary.
isCliReady); an agent that then shows its own login/trust screen is treated as a live tab, exactly like one opened from the+menu. Owner decision to confirm; tearing such tabs down would need per-agent output heuristics and a longer wait.launchDefaultAgent: trueis honoured for any authenticatedprojects:createcaller (desktop renderer, remote PWA, daemon clients) — the flag is the authorisation, not the transport. Pinned bymain/src/ipc/project.create.test.ts.main/src/events.ts, unchanged by this PR; the no-default branch is unreachable through Settings because config normalises to Claude). Only an attempted automatic launch suppresses it, so after a failed launch the project has Explorer/Diff only — deliberate, so no failed/placeholder tab survives. AC9's "zero terminal panels" is therefore proven as "no agent panel, no launch" (Vitest); the Playwright "Open a terminal" stage is the mock's approximation. Owner decision to confirm.Sidebar.tsxstill names its local statecompactSessionMenu/openCompactSessionMenu(theCompactSessionMenucomponent itself is deleted) — naming only.https://claude.ai/code/session_01A6ystbZhfNVGeSUc7x8DNm