feat(desktop): v1→v2 terminal migration — lazy recreation at the v1 cwd on workspace open
Merged
KI
4mo ago+336+336+012345678901234567890123456789-1-1-0123456789
Summary
PR 3 of the v1→v2 auto-migration (SUPER-1534 / SUPER-1577, decision D2: lazy terminal recreation, no boot-time PTY storm). Live v1 PTYs can't hand off (separate daemon owners), so the contract is a fresh shell at the persisted v1 cwd, in the right workspace.
migration.readV1TerminalPanes: first read ofapp-state.jsonby the migration router — resolves each v1 terminal pane to its workspace (via tab) and best-known cwd (cwd ?? initialCwd).migrateTerminalsstage inrunV1Migration()(after settings, before presets): assigns each pane a fresh v2 terminal id (v1 pane ids double as v1 daemon session ids — reusing them risks colliding with the live v1 daemon; idempotence comes from the ledger, kindterminal, v1Id = paneId) and queues{terminalId, cwd}per mapped workspace via an injectedterminalTarget. Panes on unmigrated workspaces defer to the next run. Never gates the flip.pendingMigratedTerminalsfield onv2WorkspaceLocalState(healed like the other optional fields) +appendPendingMigratedTerminalshelper that upserts the row (adopted-but-never-opened workspaces have none yet).useCreatePendingMigratedTerminalshook on the v2 workspace page: on first open (layout-ready), creates the queued sessions via the existing idempotent launcher, removes created entries (failures stay queued), and invalidatesterminal.listSessionsso #5740'suseAutoAdoptBackgroundSessionsbuilds the panes immediately.
Dormant until the PR 4 boot trigger wires terminalTarget — the page hook no-ops on an empty queue for all existing users.
Test Plan
-
bun test src/renderer/lib/v1-migration/— 21 tests incl.planTerminalMigration(fresh-id assignment, per-workspace grouping, unmapped deferral) - Desktop typecheck + root lint clean
- CDP E2E once PR 4 wires the runner (v1 terminal panes → sessions at cwd → auto-adopted panes)
Summary by cubic
Adds v1→v2 terminal migration with lazy recreation: on first open of a migrated workspace, we spawn fresh v2 terminals at the v1 cwd instead of at boot to avoid a PTY storm. Aligns with Linear SUPER-1534 / SUPER-1577 (D2).
- New Features
- Migration router exposes
readV1TerminalPanesto read v1 panes fromapp-state.json, mapped to workspace and cwd. - New
migrateTerminalsstage: assigns fresh v2 terminal IDs, records aterminalledger entry per v1 pane, and queues{terminalId, cwd}per migrated workspace via an injectedterminalTarget. Unmapped panes defer; never gates the flip. - Adds
pendingMigratedTerminalsto v2 workspace local state with an append helper; healed by schema defaults. - New
useCreatePendingMigratedTerminalshook: on first workspace open, creates queued sessions via the idempotent launcher, prunes created entries, and invalidatesterminal.listSessionsso auto-adopt builds panes. - Tests cover terminal planning (fresh ID assignment, per-workspace grouping, unmapped deferral). Feature remains dormant until PR 4 wires
terminalTarget.
- Migration router exposes
Summary by CodeRabbit
- New Features
- Migrating from v1 to v2 now includes terminal panes, preserving their workspace assignments and working directories where available.
- Migrated terminals are queued and recreated automatically when the corresponding v2 workspace is opened.
- Terminal migration progress is tracked, including deferred items and migration failures.
- Duplicate terminal creation is prevented, and failed creations remain available for retry.
- Tests
- Added coverage for mapped and unmapped workspace terminal migrations.