7.5 KiB
Electron Desktop E2E Record: Terminal Drawer
Date: 2026-04-25
Slice
Slice 13 basic scoped terminal.
User-Visible Scenario
- Launch the desktop app with a temporary HOME/QWEN_RUNTIME_DIR and fake ACP.
- Open a temporary project directory.
- Use the bottom Terminal drawer to run a harmless command.
- Verify command output appears in the drawer.
- Copy the terminal transcript and verify the UI reports copy success.
- Start a command that waits for stdin, send input through the drawer, and verify the command output includes that stdin.
- Attach the terminal output to the composer, verify no AI turn starts until the composer Send action is clicked, then approve the fake ACP command request.
- Start a long-running command and click Kill.
- Click Clear and verify the drawer output resets.
Assertions
POST /api/terminalsrequires a registered project id and non-empty command.- Terminal cwd is resolved from the registered project path server-side.
GET /api/terminals/:idreturns output and exit status.POST /api/terminals/:id/writewrites stdin only while the terminal is running and returnsterminal_not_runningafter completion.POST /api/terminals/:id/killmarks a running terminal as killed.- Renderer terminal controls for run, stdin, copy, kill, clear, and send to AI are visible in the bottom drawer and do not use Node integration.
- Copy output uses the preload-whitelisted Electron clipboard IPC, not renderer Node integration or an unbounded IPC channel.
- Attach Output appends a bounded terminal transcript to the composer draft, does not touch the session WebSocket immediately, and requires the normal composer Send action before a new agent turn starts.
Diagnostics on Failure
- Save renderer screenshot.
- Save renderer console errors and failed network requests.
- Save Electron main stdout/stderr.
- Save DesktopServer terminal route responses.
- Save the temporary workspace path and command used.
Automated Coverage Added In Slice 13
Slice 13 added server-level coverage in
packages/desktop/src/server/index.test.ts:
- runs
printf terminal-outputscoped to a registered project; - polls
/api/terminals/:iduntil output and exit code are available; - starts a long-running Node command and verifies
/killreturnskilled.
Automated Coverage Added In Slice 16
Slice 16 adds server and Electron CDP coverage:
- server test starts a command waiting on stdin, writes to
/api/terminals/:id/write, verifies output, and verifies a stale write fails withterminal_not_running; - CDP smoke runs a command, copies output, starts a stdin-driven command, sends input, sends the terminal transcript to the fake ACP session, approves the command request, and verifies the fake ACP response includes the terminal prompt.
- the real Electron CDP run exposed that browser clipboard fallback is not
reliable from the built
file://renderer; Slice 16 now covers the preload-backed Electron clipboard path.
Automated Coverage Added In Codex Alignment Iteration 4
Iteration 4 makes Terminal a collapsed status strip by default and updates the real Electron CDP smoke to cover the expand/collapse user path:
- Launch real Electron with isolated HOME/runtime/user-data and fake ACP.
- Assert the initial workbench has a 54px collapsed terminal strip, no expanded terminal body, no document overflow, and a conversation-dominant grid.
- Open the fake Git project, create a thread from the composer, approve the fake command, review and commit changes, and open Settings.
- Return to Conversation, expand Terminal, assert the expanded panel remains a supporting 252px region docked below the workspace grid, then run terminal commands with stdout and stdin.
- Copy output, send output to the fake ACP session, approve the follow-up command, collapse Terminal again, and assert the completed workbench returns to the compact strip.
Executable harness:
packages/desktop/scripts/e2e-cdp-smoke.mjs
Additional artifacts collected:
initial-layout.jsonterminal-expanded-layout.jsonterminal-expanded.pngcompleted-layout.jsoncompleted-workspace.png
Automated Coverage Added In Codex Alignment Iteration 5
Iteration 5 changes terminal follow-up from direct AI send to explicit attach-to-composer and updates the real Electron CDP smoke to cover the safer workflow:
- Launch real Electron with isolated HOME/runtime/user-data and fake ACP.
- Open the fake Git project, create a thread from the project composer, and complete the existing approval/review/commit path.
- Expand Terminal, run stdout and stdin commands, then click
Attach Output. - Assert the composer contains the bounded terminal transcript, the terminal
action is labeled
Attach Output, the legacySend to AIaction is absent, and no newApprove Oncerequest appears before composer Send. - Click composer
Send, approve the fake ACP request, and verify the fake ACP response includes the terminal-output prompt.
Executable harness:
packages/desktop/scripts/e2e-cdp-smoke.mjs
Additional artifacts collected:
terminal-attachment.jsonterminal-expanded-layout.jsonterminal-expanded.pngcompleted-layout.jsoncompleted-workspace.png
Execution Results
Codex alignment iteration 4:
cd packages/desktop && SHELL=/bin/bash npx vitest run src/renderer/components/layout/WorkspacePage.test.tsxpassed: 4 tests.cd packages/desktop && npm run typecheckpassed.cd packages/desktop && npm run lintpassed.cd packages/desktop && npm run buildpassed.cd packages/desktop && npm run e2e:cdppassed.- Success artifacts:
.qwen/e2e-tests/electron-desktop/artifacts/2026-04-25T17-00-08-461Z/.
Codex alignment iteration 5:
cd packages/desktop && SHELL=/bin/bash npx vitest run src/renderer/components/layout/WorkspacePage.test.tsxpassed: 5 tests.cd packages/desktop && npm run typecheckpassed.cd packages/desktop && npm run lintpassed.cd packages/desktop && npm run buildpassed.cd packages/desktop && npm run e2e:cdppassed.- Success artifacts:
.qwen/e2e-tests/electron-desktop/artifacts/2026-04-25T17-08-17-022Z/.
Slice 16:
npm run test --workspace=packages/desktoppassed: 9 files, 55 tests.npm run typecheck --workspace=packages/desktoppassed.npm run lint --workspace=packages/desktoppassed.npm run build --workspace=packages/desktoppassed.- Initial
npm run e2e:cdp --workspace=packages/desktopfailed on the copy status assertion. Diagnostics:.qwen/e2e-tests/electron-desktop/artifacts/2026-04-25T04-42-48-004Z/. - After adding the preload clipboard IPC, the CDP smoke passed. Success
artifacts:
.qwen/e2e-tests/electron-desktop/artifacts/2026-04-25T04-45-53-738Z/. - Final iteration 12 CDP run also covered terminal copy/stdin/send-to-AI while
exercising the commit path. Success artifacts:
.qwen/e2e-tests/electron-desktop/artifacts/2026-04-25T04-52-52-305Z/. npm run typecheckpassed across workspaces.npm run buildpassed across workspaces. Existing VS Code companion lint warnings remained warnings only.
Slice 13:
npm run test --workspace=packages/desktoppassed: 8 files, 52 tests.npm run typecheck --workspace=packages/desktoppassed.npm run lint --workspace=packages/desktoppassed.npm run build --workspace=packages/desktoppassed.
Remaining Risk
The current terminal is still a command runner with stdin pipes, not a full interactive PTY. PTY resize, terminal tabs/history, and richer output selection remain deferred beyond the P0 path.