Commit Graph
5069 Commits
Author SHA1 Message Date
Brennan Benson aa50c6d988 fix(terminal): reject exited daemon admissions 2026-07-13 12:47:49 -07:00
Brennan Benson c1fd70bc97 Merge remote-tracking branch 'origin/main' into fix/renderer-crash-white-screen 2026-07-13 12:21:33 -07:00
Brennan Benson 5024b4d8d4 fix(terminal): fence synchronous daemon exits 2026-07-13 12:21:01 -07:00
Brennan Benson 4dacb08ec5 fix(terminal): publish daemon sessions before output 2026-07-13 12:00:21 -07:00
Brennan Benson 2384370d25 fix: fence teardown from replacement sessions 2026-07-13 11:43:21 -07:00
Brennan Benson 9a2379211e Search worktrees by cached review metadata (#8505)
* feat(renderer): search worktrees by review metadata

* fix(renderer): scope review search by execution host
2026-07-13 11:23:28 -07:00
Brennan Benson 971b1d9b0c fix: retain terminal shutdown ownership until exit proof 2026-07-13 11:10:20 -07:00
Brennan Benson 7ba4ff0c7e fix: preserve terminal shutdown ownership under concurrency 2026-07-13 10:22:58 -07:00
Brennan Benson 79b6036a7b fix terminal teardown admission and retry races 2026-07-13 09:51:47 -07:00
Brennan Benson 173300196a fix retained terminal shutdown ownership gaps 2026-07-13 09:09:15 -07:00
Brennan Benson 498b3ea3a8 fix terminal exit proof generation races 2026-07-13 08:21:55 -07:00
Brennan Benson 905777c49a refactor: remove dead renderer retry hooks 2026-07-13 07:40:29 -07:00
Brennan Benson 42c5017e66 fix: retain unknown daemon exit proof 2026-07-13 07:27:01 -07:00
Brennan Benson 5d607ddbbb Merge remote-tracking branch 'origin/main' into fix/renderer-crash-white-screen
# Conflicts:
#	config/reliability-gates.jsonc
#	src/main/ipc/pty.ts
2026-07-13 07:13:52 -07:00
Brennan Benson 4d299463b2 fix: fence stale PTY exit generations 2026-07-13 07:10:42 -07:00
Brennan Benson 9bc3b6bd0f fix: fence provider route generations 2026-07-13 06:51:04 -07:00
fsdwen 7b3103f890 fix(i18n): correct 'run' translations from '跑步' to '执行' in zh.json (#8554)
Fixes #8553

'跑步' (jogging) was used in computing/automation contexts where
the correct term is '执行' (execute). 11 entries fixed across:
- TabBarQuickCommandsButton: Run
- Scripts settings: When to run
- quick.commands.search: run (keyword tag)
- ReviewPRViewAnimatedVisual: Running
- AutomationRunHistory: Run (column header)
- AutomationRunPageFrame: Back to runs
- AutomationsPage: Runs, run
- ExternalAutomationManagers: run
- ExternalAutomationRunTable: Runs, run

Note: key e66091daf4 already correctly translated as '运行'.
2026-07-13 06:50:18 -07:00
Brennan Benson 73709e16f2 fix: preserve teardown ownership across fallback paths 2026-07-13 06:31:52 -07:00
Brennan Benson e70046a757 fix: drain terminal owners before process shutdown 2026-07-13 05:46:23 -07:00
JinjingandOrca 13ed697cc2 Fix windows serve wsl barrier (#8559)
* fix(startup): bound serve WSL reconciliation wait

* test(startup): cover WSL barrier fail-open on early reconciliation rejection

Co-authored-by: Orca <help@stably.ai>

* feat(serve): surface managed WSL reconciliation status to headless clients

Expose reconciliation state ('pending'|'settled'|'failed') in the
orca_server_ready payload and a wsl-cli-barrier startup milestone, so
headless/SSH agents can tell the fail-open barrier outlived its budget
and a WSL PTY launch may still race an un-migrated registration.

Co-authored-by: Orca <help@stably.ai>

---------

Co-authored-by: Orca <help@stably.ai>
2026-07-13 05:40:09 -07:00
Jinjing 6091995e75 perf(worktree-watcher): skip head-identity reads on index-only bursts (#8558)
An index rewrite cannot move HEAD, yet every quiet local Git-common status
burst was calling readGitCommonHeadIdentities, which scans the primary
checkout plus every linked worktree sequentially (~1,500 file reads for 500
worktrees) even when only index files changed.

Split the conflated git-status signal into two: index churn stays
`gitStatusRepoIds`, while logs/HEAD (and other reflog head moves) become a
distinct `headIdentityRepoIds` signal. Source Control is still notified for
both, but readGitCommonHeadIdentities now runs only for true head triggers
(and structural ticks, which re-baseline silently). Index-only bursts do zero
head-identity reads.

Adds deterministic tests: index-only bursts read zero head identities across
linked and primary checkouts; logs/HEAD still refreshes identities for both;
plus coalescing and debounce coverage.
2026-07-13 05:40:02 -07:00
Jinjing 17f032dbd5 Fix WSL orchestration CLI preambles (#8561) 2026-07-13 05:39:52 -07:00
Jinjing 6eda9cdb27 fix(ssh): bound healthy relay watcher processes (#8556) 2026-07-13 05:32:31 -07:00
Brennan Benson 0839a48b93 fix: retain daemon and relay shutdown owners 2026-07-13 05:09:54 -07:00
Brennan Benson bfd28680a3 fix: preserve terminal teardown ownership until exit 2026-07-13 04:37:41 -07:00
Brennan Benson a18b7fda26 fix: close terminal removal races 2026-07-13 03:36:31 -07:00
Brennan Benson 9f38d7da18 fix: retain shutdown proof ownership 2026-07-13 03:02:15 -07:00
Brennan Benson 3ded598253 Merge origin/main into PR review
# Conflicts:
#	src/relay/pty-handler.ts
2026-07-13 02:36:17 -07:00
Brennan Benson d9d04aeeae fix: fence terminal teardown ownership 2026-07-13 02:34:37 -07:00
Brennan BensonandBrennan Benson 0b65d725c9 "Hide sleeping" never hides a workspace with an open agent session (#7197) (#7511)
* Keep running-agent workspaces visible under "Hide sleeping" (#7197)

The "Hide sleeping" sidebar filter judged a workspace active only when it
had a live PTY (or a browser tab), so a workspace with a running agent
whose live-PTY entry was momentarily absent — an SSH reconnect grace
window, an unmounted pane, a remote surface not yet `ready`, or an
orchestration worker reporting before its tab is mirrored — was
classified as "sleeping" and hidden while its session was still open.

The smart sort already treats a fresh `agentStatusByPaneKey` entry as
"working" independent of live-PTY, so the filter and sort disagreed. Add
`getWorktreeIdsWithLiveAgent`, which derives the worktrees with an open
agent session from the live agent-status map (sleep/teardown drop those
entries via dropAgentStatusByWorktree, so slept/hibernated workspaces
still hide), and consult it in `hasActiveWorkspaceActivity`. Wire it
through the sidebar list, Cmd+J jump palette, and kanban board.

* fix(agent-status): align live workspace attribution

* fix(mobile): preserve live-agent workspace activity

* fix(mobile): prefer newest agent status source

* chore: restore unrelated benchmark formatting

* fix(mobile): resolve projected agent worktree ids

* perf(mobile): index projected worktree summaries

* fix(mobile): preserve projected activity under limits

* fix(mobile): preserve POSIX path identity

* perf(mobile): cache projected summary fallbacks

* fix(mobile): preserve remote path and priority contracts

* perf(mobile): index projected paths by host flavor

* test(mobile): prove projected path index keys

* perf(mobile): bound projected path fallback

* perf(mobile): reuse projected repo platforms

* test(mobile): enforce projected lookup bounds

* chore(runtime): remove review instrumentation

* perf(mobile): skip unresolved repo platform scans

* perf(mobile): batch represented project runtimes

* perf(mobile): batch cold project runtime scans

* fix(mobile): couple worktree platform snapshots

* fix(sidebar): prioritize attributed headless agents

* fix(sidebar): activate smart sort for headless agents

* fix(sidebar): prefer mirrored agent ownership

* fix(mobile): follow mirrored agent ownership

* fix(sidebar): resolve mirrored unstamped agents

---------

Co-authored-by: Brennan Benson <brennanbenson@Brennans-MacBook-Pro.local>
2026-07-13 01:10:38 -07:00
JinjingandOrca e98bfd67c1 Fix e2e tests (#8495)
* fix(e2e): repair release e2e suite — parking regression tests, stale/flaky specs, profile switcher gate

Diagnosed 20 failing tests across the release e2e shards. Most are test debt,
plus two genuine product-side issues.

Product fixes:
- OrcaProfileSwitcher: the PROD gate hid the "Switch profile" button in the
  e2e build (electron-vite build bakes NODE_ENV=production). Exempt
  MODE==='e2e' so the specs render it while packaged prod builds stay hidden.

Parking cluster (8 tests): #8262 intentionally keeps the most-recently-hidden
tab warm (exempt from cold-park). The specs hid exactly one tab — always the
exempt one — so it never parked. Open a throwaway decoy tab that absorbs the
last-active exemption so the target parks. (terminal-hidden-view-parking,
terminal-pane-close-layout-consistency)

Stale tests updated to match intended product behavior:
- rich-markdown-link-bubble: match Edit link by aria-label (title dropped in #8307)
- terminal-codex-hidden-startup-background: drop the dead hiddenRendererSkipCount
  poll (Phase-4 main-side delivery gate #7214 bypasses that renderer path)

Brittle threshold/geometry/timing hardening (no product regression):
- agent-session-log-tail-stability: assert full-model length instead of a
  machine-specific word-wrap pixel baseline
- artificial-opencode revisit: dedicated under-backpressure latency bound
- terminal-history-size-typing-latency: gate p90 not max (tolerate one
  checkpoint-in-window spike; median stays strict)
- combined-diff-scroll-restore: assert viewport barely moved vs exact anchor key
- terminal-shortcuts: idempotent kitty-flag reset instead of a racing stack pop
- agent-session-live-force-exit-resume: drive the product quit-capture path
- renderer-crash-recovery-terminal-input: poll the transport probe over the
  recovery budget (still flags a permanently frozen pane)

terminal-push-delivery-loss-recovery left unchanged (no safe test-only
improvement; recovery is wall-clock bounded with ample slack).

* Extract shared parking helpers into terminal-hidden-parking.ts for e2e s

- Deduplicate waitForTabParked/parkHiddenTabBehindDecoy, previously
  copy-pasted across the parking and layout-consistency specs
- Parameterize parkDelayMs so the helper no longer depends on a
  file-local PARKING_DELAY_MS constant

* fix(e2e): second pass — fix link-editor Escape regression + deeper test failures

CI validated round 1 (parking + 5 areas green). This fixes the tests that were
still red because the first fix cleared only the first assertion or the root
cause was deeper.

Product fix (real regression found by the test):
- RichMarkdownLinkBubble: Escape while editing a link dismissed the whole bubble
  instead of cancelling the edit. #8307 added a container-level Escape→onDismiss
  with stopPropagation, but the edit input's older Escape→onEditCancel never
  stopped propagation, so both fired. Add e.stopPropagation() in the input's
  Escape branch so editing Escape only cancels the edit.

Test fixes:
- agent-session-live-force-exit-resume: wait for hydrationSucceeded (not just
  workspaceSessionReady) before persisting — shouldPersistWorkspaceSession gates
  the writer on it, so the record write was a silent no-op until hydration.
- terminal-shortcuts: clear the shell line deterministically (Ctrl-U + Ctrl-C)
  then send the kitty flag reset as its own settled command, so the reset byte
  isn't swallowed mid line-edit.
- agent-session-log-tail-stability: allow a 25MB GC-noise margin on the
  append-vs-replacement peak comparison. The append path provably allocates less
  than the replacement control (which also encode/decode/setValue), so a peak
  above it is uncollected-transient noise, not a regression; the deterministic
  retention budget and bench are untouched.
- artificial-opencode hidden-restore: 1500→2000ms for whole-buffer serialize-poll
  overhead under reveal (still 2x stricter than main's 4s).
- terminal-push-delivery-loss-recovery: assert the observable watchdog healCount>0
  instead of 'wedged-123' in the pane. In headless e2e a desktop-only local pty
  has no main headless emulator, so getMainBufferSnapshot falls back to the
  blackholed renderer xterm and the repaint cannot carry the wedged bytes.

* fix(e2e): third pass — harden the last 4 chronic/flaky e2e gates

- agent-session-live-force-exit-resume: raise persisted-record poll 15s→30s
  (two-stage debounced write + main scheduleSave needs headroom under the CI
  event-loop starvation that also drifts renderer timers ~1s in this shard);
  on miss, dump store vs disk state to distinguish a lost write from slow flush.
- artificial-opencode-terminal-load: add MAX_TIMER_DRIFT_UNDER_LOAD_MS (2.5s)
  for the injected-load scenarios, mirroring MAX_WORST_KEY_LATENCY_UNDER_LOAD_MS;
  baseline single-terminal gate stays at 250ms.
- combined-diff-scroll-restore: converge the after-tab-switch anchor via bounded
  retry (Monaco restores scroll over several layout passes) before asserting;
  a genuine restore miss still fails since the last anchor is returned on timeout.
- terminal-reattach-mouse-mode-leak: poll rAFs until the enable-mouse-events
  class lands after re-arming instead of a single frame (batched xterm render).

Co-authored-by: Orca <help@stably.ai>

* Widen timer-drift and scroll-restore budgets for loaded/slow e2e scenari

- Add maxTimerDriftUnderLoadMs budget so multi-pane opencode redraw
  scenarios aren't judged against the unloaded timer-drift ceiling
- Start the combined-diff scroll-restore poll window after the initial
  viewport anchor settles, since that settle can itself take up to 15s

* fix(e2e): round-2 — gate mouse-probe on arm capability; align revisit budgets

- terminal-reattach-mouse-mode-leak: xterm binds the enable-mouse-events class
  and the motion listener together in one _handleProtocolChange; some headless CI
  renderers never bind it on a warm reattach (core mouseTrackingMode still flips),
  so the positive control cannot arm. Poll a bounded window for arming, then skip
  when it never arms (matching the pane-manager/shell guards) instead of failing.
- artificial-opencode-terminal-load: the worktree-revisit scenario sampled worst-key
  and timer drift under ACK-gate-held load but asserted the strict unloaded budgets
  (worst seen ~2s); switch it to the under-load budgets like its siblings.

Co-authored-by: Orca <help@stably.ai>

* Expand timer-drift budget test coverage to all scenario branches

- Splits the pass/fail assertions into separate it blocks and adds
  it.each over all four isUnderLoadTimerDriftScenario matches (two
  exact, two prefix) so a predicate regression can't silently fall
  back to the unloaded 150ms ceiling for any of them.

---------

Co-authored-by: Orca <help@stably.ai>
2026-07-13 00:48:51 -07:00
Jinjing 7e303d26f2 Fix windows build failure (#8504)
* Fix PTY shutdown crash on Windows by dropping unsupported signals

- node-pty's Windows agent throws when kill() is called with a signal
  argument; route all pty.kill() calls through killPtyProcess(), which
  drops the signal on win32 and forwards it on POSIX

* Expand Windows PTY kill-signal-drop test coverage to all call sites

Replace the single graceful-shutdown test with a suite covering every
place killPtyProcess is invoked (graceful/immediate shutdown, stale-spawn
cleanup, SIGKILL fallback timers, and dispose), so a future regression
that reintroduces a signal argument on any Windows code path is caught.
2026-07-13 00:34:04 -07:00
Kaynan Sampaio de CamargoandJinjing c3ab805d12 fix(agent-hooks): drain stdin before hook script early exits so agents never hit EPIPE (#8430)
* Fix hook scripts to drain stdin before any early-exit path

Generated agent hook scripts and missing-script launchers could exit
successfully before consuming the payload written to their stdin,
leaving the writer with a broken pipe (EPIPE/ERROR_BROKEN_PIPE) once
the reader closed early. Capture stdin (or drain it via a shared
epilogue/fast-path guard) before any whole-script success exit across
all POSIX, batch, PowerShell, and Git Bash launcher variants, and add
a cross-agent lifecycle test suite plus a live Electron verification
script to guard the contract going forward.

* Harden hook scripts against unreadable managed scripts and add a Claude/

- Extend the POSIX launcher guard to also require `[ -r ]`, not just `-f`/`-x`,
  so an executable-but-unreadable managed script still drains stdin instead of
  erroring or silently misbehaving.
- Add a verifier case (`verifyClaudeDevinSkip`) that spins up a local HTTP
  server and confirms the Claude hook never forwards a request that Devin
  already imported, catching accidental double-forwarding.
- Update installer-utils tests and stdin-lifecycle docs to match the new
  readable-file guard and the added verification case.

* Fix hook-launcher verification to derive script paths from the installed

Extract the quoted path from the launcher's `if [ -f '...'` clause instead of
reconstructing it via join(home, ...), so missing/failing-script test cases
can't silently fall through to the real script if the install layout changes.

---------

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
2026-07-13 00:26:22 -07:00
Brennan Benson 3bba070975 fix: fence terminal teardown ownership races 2026-07-13 00:13:24 -07:00
Brennan Benson 106c680000 Merge remote-tracking branch 'origin/main' into fix/renderer-crash-white-screen 2026-07-12 23:55:11 -07:00
Brennan Benson 2ab7a9b46e fix: make teardown journal appends constant size 2026-07-12 23:54:56 -07:00
Trevin ChowandJinjing 06ea55181d Redesign Agents sidebar cards for cross-worktree scanning (#8420)
* Redesign Agents sidebar cards for cross-worktree scanning.

Lead with project and workspace identity, keep stable task titles across follow-up turns, and stop user replies from replacing agent status previews.

* fix(activity): honor generated-title setting and follow the active turn

Activity sidebar task-title/preview fixes surfaced in review of the
cross-worktree redesign:

- Apply generatedTitlesEnabled instead of ignoring it, so a disabled
  tabAutoGenerateTitle no longer resurfaces auto-titles (mirrors
  resolveTerminalTabTitle's gate).
- Guard orchestration labels with orchestrationLabelsMatchLiveDispatch so
  sticky completed metadata can't pin the title over new work.
- Prefer a substantive live prompt over history, and pick history by most
  recent startedAt (not longest), so the row title follows the active turn.
- Clear a stale status preview on a new substantive turn; only bridge a
  previous preview across a terse follow-up.
- Drop the duplicated workspace name in thread search text; index the
  branch instead.

Fixes two previously-red buildActivityEvents tests and adds coverage for
the generated-title gate and orchestration staleness.

---------

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
2026-07-12 23:52:23 -07:00
db9421dd3c Prevent index churn from refreshing worktrees (#8431)
* Prevent index churn from refreshing worktrees

* Cover IPC contract in worktree reliability gate

* Refresh background worktree heads without re-entering structural fanout

External commits, amends, and soft resets in non-active worktrees now reach
store rows through spawn-free Git metadata reads diffed in the watcher's
existing debounce, emitted only on real head moves. HEAD reflog appends become
status-only triggers, config.worktree becomes structural for sparse-flag
freshness, and the non-darwin poller gains a periodic ungated index re-stat
so in-place rewrites on coarse-mtime filesystems cannot be missed forever.

* Reject unsafe symref paths and validate object ids in the head reader

Ref content comes from repo files an attacker can craft. Backslash segments
traverse on Windows where join treats them as separators, and colons are
forbidden in Git ref names; both now fail isSafeRefName before any path is
built. Resolved values are additionally emitted only when they match a hex
SHA-1/SHA-256 object id, so no file content can leak through the identity
event even in principle.

---------

Co-authored-by: Brennan Benson <brennanbenson@Brennans-MacBook-Pro.local>
Co-authored-by: Brennan Benson <>
2026-07-12 23:43:33 -07:00
Brennan Benson 43e481b1c3 Revert "Decouple feature copy from translated locale catalogs (#8488)" (#8500)
This reverts commit a5e9e139b1.
2026-07-12 23:43:07 -07:00
Brennan Benson a5e9e139b1 Decouple feature copy from translated locale catalogs (#8488)
* Decouple feature copy from locale catalogs

* Update PR workflow contract tests

* Address localization review findings

* Document localization cache context
2026-07-12 23:42:45 -07:00
Brennan Benson 1a5fa8a36e Merge remote-tracking branch 'origin/main' into fix/renderer-crash-white-screen 2026-07-12 23:35:08 -07:00
Brennan Benson afd1b73643 fix: recover torn teardown intent journals 2026-07-12 23:34:46 -07:00
91f56c7255 Fix Windows focus stealing from agent foreground-process scan (hide conhost window) (#8053)
* Hide console window for Windows agent foreground-process scan

Agent foreground-process inspection re-forks powershell.exe (or the wmic fallback) to detect which agent runs in each terminal. Both spawns omitted windowsHide, so on Windows each fork popped a fresh conhost console window that flashed and stole keyboard focus from the foreground app — including Orca's own terminal — recurring roughly once every few tens of seconds while an agent session was open (and more often under continuous agent output).

Add windowsHide: true to both probes (matching the codebase-wide convention) plus a regression test asserting the spawn options.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* test(windows): include scan root in foreground fixtures

---------

Co-authored-by: xucongwei <xucongwei@bytedance.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Jinwoo Hong <73622457+Jinwoo-H@users.noreply.github.com>
2026-07-12 23:32:17 -07:00
Brennan Benson 410924399c Merge remote-tracking branch 'origin/main' into fix/renderer-crash-white-screen 2026-07-12 23:20:30 -07:00
Brennan Benson 57a8b4195d fix: bound durable terminal teardown persistence 2026-07-12 23:20:18 -07:00
Jinjing 34a9df7795 Fix wsl cli rc4 migration (#8471)
* fix(cli): migrate managed WSL launchers to native exe

* refactor(cli): reconcile managed WSL registrations

* fix(cli): harden WSL registration reconciliation

* fix(cli): serialize and harden WSL CLI registration lifecycle

- Cap per-distro concurrent repairs and add a filesystem lock so two
  Orca installs can't race the same distro's launcher/bridge files
- Skip re-adopting a legacy managed launcher when its bridge is user-
  owned, avoiding a doomed install retried on every startup
- Track per-distro reconciliation against launcher target + app
  version so unchanged registrations aren't re-probed each boot
- Replace command install with a single atomic rename instead of a
  move-based backup, closing a window where no orca-ide exists
- Remove the registry invalidate-on-persist-failure path now that
  writes are atomic and repair is disk-authoritative
- Add brief negative caching to WSL distro discovery to bound
  wsl.exe respawns on persistently broken hosts
- Extract keyed-promise-queue as a shared serialization primitive
2026-07-12 23:19:15 -07:00
Brennan Benson 317a8a52f7 Merge remote-tracking branch 'origin/main' into fix/renderer-crash-white-screen 2026-07-12 22:48:08 -07:00
Jinjing ec7cc2df56 Restyle Open/Start button as primary Button component (#8487)
Replace the raw <button> in the task list row with the shadcn Button
component so Open/Start gets consistent styling and hover/focus states.
Open uses the solid variant to read as the stronger action (resuming
existing work) versus outline Start (new workspace).
2026-07-12 22:48:01 -07:00
Jinjing 52388c1ab7 Fix worker done pane identity (#8473)
* fix(orchestration): bind lifecycle sends to dispatched pane

* fix(orchestration): bind injected worker messaging

* Fix worker_done pane identity gating and rename SSH linear CLI files

- Lifecycle reconciliation now returns an explicit `rejected` action
  (instead of `ignored`) for persisted sender_not_assignee markers, and
  only treats a payload's `_orcaLifecycleRejection` as trusted state
  when it exactly matches that reserved shape, preventing caller-
  supplied markers from spoofing a rejected send as success.
- SSH legacy fallback CLI now fails closed with
  `no_active_sender_terminal` when a worker_done/heartbeat send has no
  resolvable sender identity, rejects mixed raw/structured payload
  flags, and reconstructs structured lifecycle payload fields
  (task/dispatch id, files-modified, report-path, phase) instead of
  dropping them — extracted into ssh-remote-orchestration-send.ts.
- Renamed ssh-remote-linear-argument-error.ts to
  ssh-remote-cli-argument-error.ts since RemoteCliArgumentError is now
  shared beyond the Linear CLI.

* Add re-read logging for already-converted lifecycle rejections

Send-path reconcile converts worker_done/heartbeat rejections with a
no-op logger, so the coordinator's later re-read is the only chance
to surface the rejection message. Log it there instead of dropping it.
2026-07-12 22:45:33 -07:00
Jinjing 220811cbad fix(e2e): repair release e2e suite (parking regression tests, stale/flaky specs, profile switcher gate) (#8486)
* fix(e2e): repair release e2e suite — parking regression tests, stale/flaky specs, profile switcher gate

Diagnosed 20 failing tests across the release e2e shards. Most are test debt,
plus two genuine product-side issues.

Product fixes:
- OrcaProfileSwitcher: the PROD gate hid the "Switch profile" button in the
  e2e build (electron-vite build bakes NODE_ENV=production). Exempt
  MODE==='e2e' so the specs render it while packaged prod builds stay hidden.

Parking cluster (8 tests): #8262 intentionally keeps the most-recently-hidden
tab warm (exempt from cold-park). The specs hid exactly one tab — always the
exempt one — so it never parked. Open a throwaway decoy tab that absorbs the
last-active exemption so the target parks. (terminal-hidden-view-parking,
terminal-pane-close-layout-consistency)

Stale tests updated to match intended product behavior:
- rich-markdown-link-bubble: match Edit link by aria-label (title dropped in #8307)
- terminal-codex-hidden-startup-background: drop the dead hiddenRendererSkipCount
  poll (Phase-4 main-side delivery gate #7214 bypasses that renderer path)

Brittle threshold/geometry/timing hardening (no product regression):
- agent-session-log-tail-stability: assert full-model length instead of a
  machine-specific word-wrap pixel baseline
- artificial-opencode revisit: dedicated under-backpressure latency bound
- terminal-history-size-typing-latency: gate p90 not max (tolerate one
  checkpoint-in-window spike; median stays strict)
- combined-diff-scroll-restore: assert viewport barely moved vs exact anchor key
- terminal-shortcuts: idempotent kitty-flag reset instead of a racing stack pop
- agent-session-live-force-exit-resume: drive the product quit-capture path
- renderer-crash-recovery-terminal-input: poll the transport probe over the
  recovery budget (still flags a permanently frozen pane)

terminal-push-delivery-loss-recovery left unchanged (no safe test-only
improvement; recovery is wall-clock bounded with ample slack).

* Extract shared parking helpers into terminal-hidden-parking.ts for e2e s

- Deduplicate waitForTabParked/parkHiddenTabBehindDecoy, previously
  copy-pasted across the parking and layout-consistency specs
- Parameterize parkDelayMs so the helper no longer depends on a
  file-local PARKING_DELAY_MS constant
2026-07-12 22:40:57 -07:00