mirror of
https://github.com/stablyai/orca.git
synced 2026-11-03 02:27:43 +00:00
ea532813b1f8464b4de54c81663152ee07cb8da1
328
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
46c0a1f453 |
test(e2e): skip contributor git hooks and signing when seeding fixture repos (#31591)
Global setup and the worker-scoped fallback now share one seedTestRepository() that runs its commit and worktree add with per-command `-c core.hooksPath=/dev/null -c commit.gpgsign=false`, so a contributor's global hooks or always-on signing no longer abort e2e before any spec runs, and the test repo's own hook config stays untouched for specs that install hooks. Fixes #31587 Co-authored-by: Neil <neil@stably.ai> |
||
|
|
2327180d12 |
feat(quit): add Quit and Stop All Sessions to the app menu and tray (#32153)
* feat(quit): add Quit and Stop All Sessions to the app menu and tray Quit keeps daemon sessions alive for warm reattach. The new item, placed directly above Quit in the macOS app menu and menu bar icon, the Windows File menu and tray, and the Linux File menu, asks for confirmation, runs Settings' Kill all sessions in the renderer, and quits only when every session stopped. Closing the tabs first means nothing reopens or resumes on the next launch. Serve hosts do not offer the item. * fix(quit): keep Orca open when Kill all cannot prove every session stopped - Kill all no longer reads a daemon generation that failed to list as "no sessions": a failed poll keeps the last confirmed remaining set, and a failed initial listing sets listingIncomplete. - Quit and Stop All Sessions stays open on an incomplete listing or a terminal tab opened during the sweep, logs why it stayed open, and reveals the window before the final quit. - Share the main-window message box helper, stub the request on the web client, and add Portuguese strings. - Cover the windowless path, request expiry, the in-flight guard, and failed listings in tests; bound the E2E exit wait. * fix(terminal): count Kill all per daemon generation within a time window - A poll updates only the daemon generations that answered, so one failing generation no longer hides the kills of the others. - Poll for 6.5 s of wall-clock time instead of 65 attempts, because a wedged generation fails each listing only at the request timeout. - Flag a sweep with no daemon provider as listingIncomplete. - Log the leftover-tab exit, share the one-shot window intent with Open Settings, and cover the sender check, the reveal before the final quit, and retries in tests. * fix(quit): stay open while a newer build's daemon is held - Set listingIncomplete while this build holds a newer protocol's daemon, whose sessions it can neither list nor stop. - Reuse getDaemonAdapters in Kill all, type the shared one-shot helper by its flag factory, and move the app-menu quit handlers next to the tray options so both serve/desktop splits are tested. - Cover a quit that outlasts the request expiry and a failed request pull, and fix the docs lead-in for the new quit-time case. * fix(quit): explain, without stopping anything, while a newer version runs terminals - Check the newer-version daemon hold before the confirmation and show an explanation instead, so Kill all no longer closes every tab and then refuses. listingIncomplete stays as the backstop. - Translate the explanation, describe listingIncomplete generically, and assert the single timed-out poll in the Kill all test. * fix(quit): explain before asking whenever Kill all cannot list every session - Show the explanation instead of the confirmation while the daemon provider is missing (still starting or failed) as well as while a newer version's daemon is held. - Name only the steps that work (wait for terminals to open, reopen a terminal opened in a newer version), avoid stating a hold as fact, and label the dialog's button through the catalog. * fix(quit): add the relaunch step to the explanation and align the ja wording * test(pty): keep a confirmed stop when its generation fails a later poll * test(quit): give the E2E timeout bump its reason * fix(quit): stay open when the daemon still lists a session after Kill all Kill all counts only the sessions of its first listing, so a session started since then, for example from the CLI or an automation before its tab reaches the renderer, would outlive the quit. Main now lists every daemon generation again before quitting, and quits only after a listing in which every generation answers and none lists a session. It polls within Kill all's 6.5 s window so the tab sweep's PTY shutdowns can finish; otherwise the renderer shows the existing error and Orca stays open. ui:quitAfterStoppingAllSessions becomes an invoke that answers whether main quits. * feat(quit): rename to Quit Completely with a macOS hover hint, and explain plain Quit in the confirmation * fix(quit): show progress while Quit Completely runs, and refuse at once when the daemon can't be fully listed --------- Co-authored-by: Neil <neil@stably.ai> |
||
|
|
483573f0b9 |
fix(browser): focus newly opened image tabs (#34127)
* fix(browser): focus newly opened image tabs Focus the window before the webview so Command+W closes the new image tab instead of the original tab after a plain image click. Add tests for focus order, image loading, and close-shortcut forwarding. Fixes #34114 * test(browser): verify image tab focus with native keyboard input * refactor(ci): keep browser E2E routes within registry size limit * fix(ci): enable background launch for native browser regression * test(ci): include browser routes in isolated detector fixture --------- Co-authored-by: Neil <neil@stably.ai> |
||
|
|
29a5f89b8a |
Keep same-machine folders with matching Git remotes in separate projects (#32272)
* WIP: same-host same-remote checkouts keep their own project id * WIP: claim the shared project id per checkout surface; drop the display-only clone split * WIP: index derived ids by repo in the hydration normalizer * Resolve workspace project affiliation from current checkout owners * fix: preserve concrete project ownership across catalogs and operations * fix: combine recent project selector imports * fix: enforce canonical catalog reads and preserve search continuity * fix: scope catalog lint exceptions to renderer files * Resolve project search ownership before native candidate limits * Combine duplicate session scope imports * fix: derive returned history row ownership on the host * Reconcile full session history replies by content * Require authoritative project catalogs for terminal snapshots * Preserve registered project claims and partial history results * test: check orphaned setup cleanup state without assertions * fix: align catalog callers and native search fixture contracts * test: check full repo shapes in runtime routing fixtures * Fix checked catalog inputs in compiler regression fixtures * Keep checked PTY fixture repos mutable * test: align catalog fixtures with canonical readers * test: check catalog and runtime fixture inputs * test: check catalog fixtures without outer assertions * test: follow persistence harness relocation * Adapt catalog test inputs to integrated main checks * Test History hashing across cached depth revalidation * test(settings): expect host-qualified setup removal * test: capture host split listings and scope relay recovery * ci: regenerate merge ref * test: type host-split listing diagnostics |
||
|
|
7a9abe48f3 | refactor: group remote runtime client modules (#34133) | ||
|
|
ad2156c358 |
test: remove 140 low-value cases and 49 suites (#34062)
* test: remove 140 low-value cases and redundant browser probes * fix: remove unused upstream chat menu import * test: pin the host-split layout fixture branch --------- Co-authored-by: Orca Test Audit <test-audit@stably.ai> Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> |
||
|
|
d1f04e6042 |
fix(terminal): a pane moved to a new tab stays moved on paired servers (#33027)
* test(e2e): a pane moved to a new tab on a paired server workspace stays moved * fix(terminal): keep a pane moved to a new tab on paired runtimes Moving a split pane to a new tab in a paired-runtime worktree changed only the window store. The host never learned about the move, so the next host snapshot rebuilt the old tab and the pane snapped back. Add a session.tabs.movePaneToNewTab RPC that commits the move in the host session through planTerminalLeafMove and republishes the session tabs. For a mirrored host tab, the renderer applies the move first under the mirrored id the host snapshot will use, then asks the host to commit it. An older host or a refused move falls back to the old local-only move. Fixes #32939 * fix(terminal): commit a host pane move through the existing leaf-move writer The layout-writer ratchet allows no new main-process layout writers. The headless host now hands the move to commitLeafMoveAndRekey, the same commit a local window uses, and keeps only the window check, validation, rehydrate and notify. * fix(terminal): gate the host pane move on a host capability An older host keeps today's window-only move under a local tab id instead of a mirrored one it never confirms. Adds a terminal.list check to the e2e. * test: drop type assertions from the pane-move tests * fix(terminal): the host keeps a moved pane's place, focus and live terminal After the host commits the move, the window gives it the drop position and focus through the existing tab move and activate calls; a refusal redraws the host's tabs. The host moves the live PTY's surface with its pane and checks the target tab id. The move lives in its own runtime module. * fix(terminal): hold a moved pane's drop order until the host has it The host's snapshot of the commit goes out before its reply and appends the tab, so the window records the drawn order as a reorder intent at the drop and sends that order, and the focus read then, once the host answers. * fix(terminal): route the moved tab's reorder to its owning host The follow-up names the worktree's host instead of reading the active-server setting (focus-read ratchet); the e2e narrows host rows to terminal tabs. * fix(terminal): the host places a moved pane's tab in the move itself; a refusal reverts The move carries the drop's group and index (optional; an older host appends) and the host places and selects the tab before its one publish, replacing the follow-up reorder and the drop-time order hold. A refused move closes the tab this window drew without stopping its terminal and redraws the host's tabs even when unchanged. E2e covers a same-group drop and a refusal; host unit tests cover same-group and cross-group placement. * fix(terminal): a refused pane move keeps its pane records; drop index in host order The revert hands the pane's status and launch records back to the source tab before closing the drawn tab. The host turns a projected client's drop index into its raw order with translateProjectedSessionTabMove, as session.tabs.move does. * fix(terminal): only an unknown drop group appends a moved pane's tab The host catches only target_group_not_found and invalid_tab_order from the index translation and rethrows anything else. * fix(terminal): settle a pane move by what the host holds when its reply is lost A lost reply is not a refusal: the window asks the host whether it holds the pane in the new tab before undoing anything, and waits for the next snapshot when it cannot ask. A move the host committed but this window could not draw takes the host's tabs. * fix(terminal): a lost transport on a pane move is unknown, not a refusal runtimeEnvironments.call answers a dropped or overloaded transport with an error envelope; those codes (the shared recoverable set) now ask the host instead of undoing a move it may have committed. * test(e2e): pane-move spec waits on real signals, not delays The source tab is created on the server and split once its shell is listed, so the split no longer races a desktop-seeded tab's first spawn (the CI failure). The stay check follows output from the moved pane; the refusal check waits for the drawn tab to appear and go. * test(e2e): read the refused move's tab counts without Reflect (anti-slop) * fix(terminal): a moved pane's tab joins the order the user had, not a rebuilt one The host inserts the new tab into the group order captured before the commit, appending without a drop position, so editors and pages keep their places. The shared group-move fallback is no longer used here. * fix(terminal): a moved pane's groups hold the host's current tabs, in the user's order Placement takes membership from the rebuild after the commit and only the order from before it, so a tab opened while the commit was pending stays (after the user's tabs) and no stale id is written. * fix(terminal): a moved pane's placement keeps a reorder made while it committed The order is read after the commit, from the host's current tabs, not before it. * fix(terminal): a moved pane keeps the lone group the user merged into A rebuild names a single group with the default id; placement keeps the user's id for it, so the drop position still applies after a split was merged back. * fix: import error classification from its new shared/remote-runtime path * fix(terminal): a pane or divider drag survives focus moving inside the window The drag's window blur listener was registered in the capture phase, so it also heard every element blur. A terminal attach or host snapshot that moved focus between panes mid-gesture ended the drag; in the paired pane-move e2e on CI it cancelled the drag before the drop. Only the window losing focus ends it now. * test: drive the focus-change drag test through a real pane manager, without casts * fix(terminal): a headless host moves a pane with its live terminal and never empties its source The host names the PTY it holds for the pane, so a session copy an SSH respawn left with an old id no longer refuses the move as a mismatch. A move that would leave its source tab with no pane (a sibling closed meanwhile) is refused, since no headless cleanup retires the emptied tab and it would publish as a phantom. The e2e fences its stays-moved check on a later server rename instead of sampling on a timer. --------- Co-authored-by: Ben Grynhaus <ben.grynhaus@wiz.io> |
||
|
|
cc3ca668d8 |
test: remove low-value predicates, inventories and helper echoes (#33778)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> |
||
|
|
28de913868 |
test(connectors): drive a connector conversation end to end on a headless serve host (#33613)
Adds an end-to-end test that boots an isolated headless serve host and drives the orca connector CLI against a scripted Claude. Runs in the existing PR e2e job only when connector code changes. |
||
|
|
7d6603aa17 |
[comment audit] Complete repository-wide comment cleanup (#33249)
* [comment audit] Align legacy failure-read counts with cached display * [comment audit] Condense shared provider lifecycle and browser recovery comments [skip ci] * [comment audit] Condense shared generation, path and preview comments [skip ci] * [comment audit] Condense host, file and Git contract rationale [skip ci] * [comment audit] Tighten Git lifecycle and provider contract comments [skip ci] * [comment audit] Clarify shared host authority and launch isolation [skip ci] * [comment audit] simplify local access mobile and native chat contracts [skip ci] * [comment audit] simplify native chat presentation and state contracts [skip ci] * [comment audit] simplify native runtime and provider contracts [skip ci] * [comment audit] simplify migration and orchestration contracts [skip ci] * [comment audit] simplify plugin trust and process capture rationale [skip ci] * [comment audit] simplify terminal delivery and remote compatibility rationale [skip ci] * [comment audit] clarify remote recovery and launch wire rationale [skip ci] * [comment audit] shorten shared RPC compatibility and runtime evidence comments [skip ci] * [comment audit] simplify secure storage shell startup and sidebar rationale [skip ci] * [comment audit] clarify sidebar, skill and SSH invariants [skip ci] * [comment audit] condense structured chat delivery and timing rationale [skip ci] * [comment audit] condense terminal replay and telemetry invariants [skip ci] * [comment audit] clarify launch permission and terminal delivery rationale [skip ci] * [comment audit] clarify workspace ownership and layout contracts [skip ci] * [comment audit] wait for fitted and painted SSH terminal links * [comment audit] clarify layout persistence and session ownership [skip ci] * [comment audit] clarify host routing and workspace lifecycle contracts [skip ci] * [comment audit] clarify startup persistence and app lifetime comments [skip ci] * [comment audit] clarify recovery and activity boundaries [skip ci] * [comment audit] condense activity and artifact invariants [skip ci] * [comment audit] condense automation authority contracts [skip ci] * [comment audit] simplify automation scheduling and history contracts [skip ci] * [comment audit] clarify browser chrome and annotation lifecycles [skip ci] * [comment audit] clarify browser routing and retained guest ownership [skip ci] * [comment audit] clarify browser recovery and document ownership comments [skip ci] * [comment audit] restore hosted runners required by native IME fixtures * [comment audit] shorten preview, palette and dashboard invariants [skip ci] * [comment audit] clarify terminal preview, dashboard and retention comments [skip ci] * [comment audit] clarify diff-note recovery and editor lifecycle comments [skip ci] * [comment audit] shorten rich-text and combined-diff ownership comments [skip ci] * [comment audit] shorten autosave, draft recovery and model ownership comments [skip ci] * [comment audit] shorten save-queue, notebook and Markdown constraints [skip ci] * [comment audit] shorten Monaco, PDF and rich Markdown safeguards [skip ci] * [comment audit] clarify rich Markdown source and selection safeguards [skip ci] * [comment audit] clarify editor loading and emulator stream lifetimes [skip ci] * [comment audit] trim emulator and feature tour narration [skip ci] * [comment audit] clarify floating workspace and GitHub cache ownership [skip ci] * [comment audit] trim provider controls and Linear filter explanations [skip ci] * [comment audit] clarify pairing and chat resume lifetimes [skip ci] * [comment audit] clarify chat delivery and transcript lifetimes [skip ci] * [comment audit] clarify session options and host-owned status [skip ci] * [comment audit] clarify draft durability and live-status precedence [skip ci] * [comment audit] Trim chat send and model ownership explanations [skip ci] * [comment audit] Shorten transcript ownership and send recovery comments [skip ci] * [comment audit] Simplify native chat composer and transcript hook comments [skip ci] * [comment audit] Shorten native chat scroll and structured session explanations [skip ci] * [comment audit] Trim workspace picker and onboarding commentary [skip ci] * [comment audit] Simplify pet rendering, review cache and quick open comments [skip ci] * [comment audit] Trim sidebar and session history explanations [skip ci] * [comment audit] Condense session resume and review checks comments [skip ci] * [comment audit] Shorten checks state and file explorer refresh comments [skip ci] * [comment audit] Trim plugin bridge and source-control action rationale [skip ci] * [comment audit] Trim source-control listing and review rationale [skip ci] * [comment audit] Shorten sidebar lifecycle and explorer safeguards [skip ci] * [comment audit] Condense Settings account and appearance rationale [skip ci] * [comment audit] Trim pairing and repository Settings explanations [skip ci] * [comment audit] Condense Settings search SSH and terminal safeguards [skip ci] * [comment audit] Shorten Settings voice and provider ownership comments [skip ci] * [comment audit] Condense Settings draft persistence and host-state rationale [skip ci] * [comment audit] Trim Settings hooks and sidebar setup rationale [skip ci] * [comment audit] Condense sidebar deletion and board-filter safeguards [skip ci] * [comment audit] Condense worktree cards, host ownership and Markdown contracts [skip ci] * [comment audit] Condense sidebar drag, folder and filtering contracts [skip ci] * [comment audit] Condense sidebar parity, sleep and host ownership contracts [skip ci] * [comment audit] Prune focus-read baseline after comment cleanup * [comment audit] Clarify sidebar visibility, board drops and agent evidence [skip ci] * [comment audit] Tighten sidebar listing, drag and reveal contracts [skip ci] * [comment audit] Clarify viewport geometry and skill update safeguards [skip ci] * [comment audit] Tighten skill inventory, usage and host status comments [skip ci] * [comment audit] Clarify usage ownership and resource kill safeguards [skip ci] * [comment audit] Tighten tab selection, rename and search contracts [skip ci] * [comment audit] Tighten tab-strip geometry and drag ownership comments [skip ci] * [comment audit] Tighten Tasks recovery, pagination and mutation comments [skip ci] * [comment audit] Tighten provider loading and terminal recovery comments [skip ci] * [comment audit] Tighten completion, cadence and PTY ownership comments [skip ci] * [comment audit] Clarify terminal restore and parked-pane boundaries [skip ci] * [comment audit] Tighten PTY startup and replay explanations [skip ci] * [comment audit] Clarify PTY identity and delivery ownership [skip ci] * [comment audit] Shorten remote reconnect and input replay rationale [skip ci] * [comment audit] Condense terminal parking clipboard and file link comments [skip ci] * [comment audit] Clarify IME ownership and trim trace history [skip ci] * [comment audit] Shorten pane recovery and parked watcher explanations [skip ci] * [comment audit] Condense snapshot replay and visibility recovery rationale [skip ci] * [comment audit] Shorten terminal parking and keyboard ownership rationale [skip ci] * [comment audit] Trim renderer lifecycle and menu rationale [skip ci] * [comment audit] Condense workspace cleanup ownership and settlement notes [skip ci] * [comment audit] Clarify renderer hook evidence and source ownership [skip ci] * [comment audit] Tighten IPC ownership and reconnect explanations [skip ci] * [comment audit] Trim renderer focus, paste and attention comments [skip ci] * [comment audit] Shorten scroll, locale and agent lifecycle comments [skip ci] * [comment audit] Trim agent launch, resume and ownership commentary [skip ci] * [comment audit] Shorten account, browser and editor comments [skip ci] * [comment audit] Clarify host-mirror waits, previews and input ownership [skip ci] * [comment audit] Condense launch recovery and editor tokenization comments [skip ci] * [comment audit] Condense workspace selection and terminal pane rationale [skip ci] * [comment audit] Condense terminal fitting and rendering recovery comments [skip ci] * [comment audit] Condense terminal input and host routing explanations [skip ci] * [comment audit] Condense ownership and sleeping-session recovery rationale [skip ci] * [comment audit] Condense structured launch and terminal link explanations [skip ci] * [comment audit] Condense terminal ownership and workspace file routing rationale [skip ci] * [comment audit] Condense session persistence and workspace activation rationale [skip ci] * [comment audit] Condense workspace routing and browser ownership rationale [skip ci] * [comment audit] Condense mirror recovery and layout authority rationale [skip ci] * [comment audit] Condense runtime transport and file safety rationale [skip ci] * [comment audit] Condense runtime graph and structured session rationale [skip ci] * [comment audit] Condense browser creation and remote tab recovery rationale [skip ci] * [comment audit] Condense snapshot authority and publisher recovery rationale [skip ci] * [comment audit] Condense frame, startup and provider cache rationale [skip ci] * [comment audit] Condense host twin and agent lifecycle rationale [skip ci] * [comment audit] Condense browser authority and editor cleanup rationale [skip ci] * [comment audit] Condense editor buffer identity and review cache rationale [skip ci] * [comment audit] Condense provider lifetime and repository ownership rationale [skip ci] * [comment audit] Condense reconnect, hydration and terminal retirement rationale [skip ci] * [comment audit] Condense recovery, reconciliation and persistence rationale [skip ci] * [comment audit] Condense cleanup ownership and listing admission rationale [skip ci] * [comment audit] Condense teardown ordering and terminal ownership rationale [skip ci] * [comment audit] Condense recovery ledger and web host-boundary rationale [skip ci] * [comment audit] Condense web reconnect and credential lifecycle rationale [skip ci] * [comment audit] Condense cloud rollout and assignment safety rationale [skip ci] * [comment audit] Condense relay session and database recovery rationale [skip ci] * [comment audit] Condense relay placement and protocol compatibility rationale [skip ci] * [comment audit] Condense build and packaging constraints [skip ci] * [comment audit] Condense CI gates and validation isolation rationale [skip ci] * [comment audit] Condense catalog identity and browser validation rationale [skip ci] * [comment audit] Condense mobile browser and frame-budget rationale [skip ci] * [comment audit] Shorten mobile route and browser test explanations [skip ci] * [comment audit] Condense editor and session seam test rationale [skip ci] * [comment audit] Trim session and terminal closure history [skip ci] * [comment audit] Shorten terminal browser and census explanations [skip ci] * [comment audit] Preserve root-only E2E diagnostic baseline * [comment audit] Condense mobile seam and HTML preview test rationale [skip ci] * [comment audit] Condense preview instrumentation and render harness rationale [skip ci] * [comment audit] Condense bundle contracts and native-build constraints [skip ci] * [comment audit] Shorten native packaging and CI routing rationale [skip ci] * [comment audit] Condense release tooling and benchmark constraints [skip ci] * [comment audit] Condense packaging and platform gate rationale [skip ci] * [comment audit] Shorten mobile route and history rationale [skip ci] * [comment audit] Condense mobile browser and component rationale [skip ci] * [comment audit] Shorten drawer and workspace-form rationale [skip ci] * [comment audit] Trim mobile review and editor-document explanations [skip ci] * [comment audit] Condense editor lifecycle and Markdown explanations [skip ci] * [comment audit] Trim mobile file, diagnostics and dictation commentary [skip ci] * [comment audit] Simplify mobile host-list and workspace-view explanations [skip ci] * [comment audit] Clarify mobile shell lifetime and bridge delivery constraints [skip ci] * [comment audit] Condense bridge stream, native request and audio rationale [skip ci] * [comment audit] Reduce bridge schema and page-client commentary [skip ci] * [comment audit] Tighten mobile page bridge contracts [skip ci] * [comment audit] Clarify mobile cache and session constraints [skip ci] * [comment audit] Condense mobile route and lifecycle rationale [skip ci] * [comment audit] Tighten mobile shell hook timing rationale [skip ci] * [comment audit] Clarify route handoff and notification compatibility [skip ci] * [comment audit] Clarify push registration and dictation cleanup constraints [skip ci] * [comment audit] Condense keyboard geometry and native media ownership rationale [skip ci] * [comment audit] Tighten mobile chat scroll and composer concurrency rationale [skip ci] * [comment audit] Condense mobile reply compatibility and upload ownership rationale [skip ci] * [comment audit] Condense optimistic echo and scroll ownership rationale [skip ci] * [comment audit] Tighten stream replay and queued session ownership rationale [skip ci] * [comment audit] Condense mobile composer and reply-schema constraints [skip ci] * [comment audit] Clarify mobile transcript recovery and session ownership [skip ci] * [comment audit] Clarify mobile queue and source-control compatibility [skip ci] * [comment audit] Condense storage and task launch constraints [skip ci] * [comment audit] Clarify task schemas and terminal document ownership [skip ci] * [comment audit] Tighten terminal input and viewport rationale [skip ci] * [comment audit] Shorten terminal and RPC recorder contracts [skip ci] * [comment audit] Condense recorder engine and connection contracts [skip ci] * [comment audit] Shorten host credential and relay recovery comments [skip ci] * [comment audit] Tighten pairing recovery and bundle transport rationale [skip ci] * [comment audit] Clarify RPC delivery and workspace catalog boundaries [skip ci] * [comment audit] Condense catalog and relay entry contracts [skip ci] * [comment audit] Shorten shutdown and SSH relay delivery contracts [skip ci] * [comment audit] Condense WSL relay and E2E regression rationale [skip ci] * [comment audit] Shorten cross-version harness and renderer fixture explanations [skip ci] * [comment audit] Condense paired-host and E2E lifecycle rationale [skip ci] * [comment audit] Shorten layout oracle and regression explanations [skip ci] * [comment audit] Condense paired recovery and ownership regression contracts [skip ci] * [comment audit] Shorten restart, sidebar and SSH lifecycle contracts [skip ci] * [comment audit] Condense terminal rendering and IME regression rationale [skip ci] * [comment audit] Shorten terminal recovery and benchmark contracts [skip ci] * [comment audit] Condense tooling and Windows lifecycle proof rationale [skip ci] * [comment audit] Condense workflow routing and release rationale [skip ci] * [comment audit] Condense mobile security and installer contracts [skip ci] * [comment audit] Shorten native rationale and stylesheet workarounds [skip ci] * [comment audit] Shorten Windows visibility probe rationale [skip ci] * [comment audit] Condense embedded release and signing rationale [skip ci] * [comment audit] Retain current main test behavior in final reconciliation [skip ci] * [comment audit] Complete final comment review across current source inventory * [comment audit] Handle consolidated audit reports before final CI * [comment audit] Preserve credential storage census detail [skip ci] * [comment audit] Scale broad changed E2E selections with verified timing shards * [comment audit] Align E2E assertions with browser close and settled session metadata * [comment audit] Match existing E2Es to current resource and windowing contracts * [comment audit] Observe the shared server outage notice in reconnect coverage * [comment audit] Make existing renderer probes measure settled tab and PTY work * [comment audit] Align palette E2E selector with task search * [comment audit] Refresh remaining palette search selectors * [comment audit] Keep selector correction within selected audit specs * [comment audit] Await emoji fixture settings inside renderer evaluation * [comment audit] Cancel fixture fit retries between terminal tests --------- Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> |
||
|
|
e1ee51dec4 |
fix(ssh): saved port forwards come back after a restart that reconnects through the host's Orca server (#32484) (#33388)
* test(e2e): a saved SSH forward on a managed host comes back after a restart (#32484) * test(e2e): a restart that reaches the host only through its server's tunnel restores saved forwards (#32484) * fix(ssh): restore saved port forwards whenever a host's server is up, not only after an SSH connect (#32484) A host whose managed server the app reaches at startup through its tunnel publishes its served status from the tunnel path, which never ran the forward restore. The served status itself now triggers the restore, from any publisher, and a host kept on the legacy relay bridge restores too. * test(ssh): type the restore spy's target argument * fix(ssh): user forward edits keep unrestored saved forwards; restore once the tunnel is up Add, edit and remove now merge with saved forwards that aren't live, so a restart that restored nothing no longer lets one re-added forward erase the rest. A call that brings up the managed server's tunnel restores too, so a failed update check or redeploy can't skip it, and a restore runs once per transport instead of on every status note. * fix(ssh): a forward that failed to bind is retried on the same transport * fix(ssh): restore again when a restored forward closed; a reused local port replaces its old mapping * fix(ssh): user forward edits and restores share one per-host queue A restore that ran mid-edit could reopen the mapping the edit was replacing and save both. Every add, edit, remove and restore for a host now runs in order through the same queue. * fix(ssh): pace forward restores and back off a forward that keeps failing Each runtime call triggers a restore over the managed tunnel, and with system SSH every attempt is a new login. Restores on the same transport now run at most once per 30 s, a forward that keeps failing waits longer each time, and teardown forgets both. A tunnel with no status yet counts only outside a connect; a remove re-checks its forward inside the queue; drop a circular listener test and the plain restart e2e case. * fix(ssh): a start a teardown cancelled records no backoff * fix(ssh): a reconnected transport retries failed forwards at once |
||
|
|
e13e5e8b7d |
fix(orchestration): submit mail pointers to Cursor CLI instead of leaving them in the composer (#33347)
Orchestration mailbox pointers now get their delayed Enter for Cursor too (the Cursor no-Enter skip from #3156 left mail delivered but never acted on). Verified with real cursor-agent. Fixes #19760. Supersedes #19761. Co-authored-by: Maple <54388301+zleo-ai@users.noreply.github.com> |
||
|
|
fef00e4461 |
feat(dev): give each worktree its own pnpm dev profile and ports (#33416)
Linked worktrees now get a per-worktree userData profile under
orca-dev-wt/<hash>, a deterministic collision-checked renderer port
(15200+) and CDP port (9333+), so parallel `pnpm dev` runs no longer hit
the single-instance lock. The main checkout keeps the shared orca-dev
profile; --shared-profile / --worktree-profile / ORCA_DEV_PROFILE override.
The runner prints `ORCA_DEV_INSTANCE {json}` on stdout and mirrors it to
out/dev-instance.json so agents can attach over CDP. orca-dev.mjs and the
terminal wrappers follow the profile the worktree's dev app used.
Adds profile seeding (pnpm dev:seed-profile, pnpm dev --seed-profile,
pnpm dev:fresh --seed-from): an allowlisted slim copy of projects,
workspaces, settings, SSH targets, and the account session, written as
orca-data.json for Orca's own import; the source is only read.
Storage reclaim removes per-worktree profiles once their worktree is gone
and no app, runtime, or daemon still uses them. dev-fresh-profile.sh is
replaced by a cross-platform dev-fresh-profile.mjs.
|
||
|
|
8e9f86b119 |
feat(managed-server): Update and Update anyway for a managed SSH server, keeping its running terminals (#33397)
* feat(managed-server): offer Update and Update anyway on a managed SSH server's row A managed SSH server only updated on connect, and every connect deferred while a terminal ran there. Its row now offers Update when this desktop bundles a newer build than the Orca that runs the host. When running terminals defer it, Update anyway restarts the server past them; the terminal daemon carries them across the restart. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(managed-server): Update anyway passes only counted live terminals and keeps Update's version admission Update anyway now sends the incumbent build it confirmed over; under the host fence it is refused if another desktop activated a build since, keeps the newer-host downgrade refusal, and never passes an uncounted terminal census. The offer also covers hosts activated before the Orca version was recorded, for the build this desktop already deferred there. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(managed-server): Update anyway also confirms a menu Update the row does not advertise Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(managed-server): the row shows one confirmation at a time Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * ci(e2e): route managed-server update sources to the Update anyway Docker spec Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> |
||
|
|
fdcf887bf0 |
chore(lint): fix suppressed lint violations instead of ignoring them (#33294)
* chore(lint): remove disable directives that suppress nothing
Each was reported unused by the oxlint config that owns its rule (root,
casting, react-doctor, anti-slop, native-plugins), including 17 file-level
react-doctor blanket disables whose rule no longer fires. An unused
react-hooks disable was masking a react/purity finding in
useAgentBucketCounts (compiler rules skip functions with hook
suppressions); suppress that one explicitly where the code explains it.
* test(tab-bar): use typed tab/file fixtures instead of @ts-expect-error partials
* chore(lint): fix misc suppressed lint violations instead of disabling
- consistent-type-imports: the "vi.importActual requires inline import()"
rationale was wrong; use typed vi.mock(import(...), importOriginal) or a
type-only namespace import.
- no-control-regex: source-control commit/push failure summaries, shell PATH
hydration, and ipynb ANSI parsing reuse the shared ansi-escape-sequences
stripper and control-character pattern instead of private copies.
- no-explicit-any / no-useless-spread / no-this-alias: typed `this` in
bridge test mocks, drop blanket file-level disables, drop a this-alias.
* refactor(main): replace avoidable type assertions with checked narrowing
17 production cast suppressions in main/wsl-guest removed: untrusted IPC
and RPC payloads (Jira issue update, WSL guest plugin install, handshake
type) now narrow through isRecord/type guards and build typed results;
redundant casts dropped; hand-rolled object checks and errno casts use the
existing isRecord / hasErrorCode helpers.
* refactor(renderer,mobile): replace avoidable type assertions with checked types
13 production cast suppressions removed: RPC failures read through the
`ok` discriminant instead of casting to RpcFailure; react-native-web host
refs narrowed with instanceof HTMLElement; redundant reply/diff casts
become checked annotations; the TUI agent param uses z.custom(isTuiAgent)
like its sibling schemas; the agent-status slice cast that hid missing
actions is gone so the creator's return type checks the whole slice.
* chore(lint): drop dead tiptap wrapper; scope anti-slop mocking rule to test support
- safe-react-node-view-renderer patched handleSelectionUpdate, which
@tiptap/react 3.31.3 no longer has, so it always returned early. Use the
stock ReactNodeViewRenderer.
- The anti-slop test override only matched *.test.{ts,tsx}, forcing
file-level no-module-mocking disables in test harnesses and fixtures.
Match *-test-harness, *-test-fixture(s), .test-fixture and *.test.mjs,
then drop those disables and the now-redundant per-file exemptions.
* test: replace repeated cast suppressions with typed fixtures (main/shared/e2e)
Net -119 cast directives. Typed fixtures replace recurring casts:
unusedSshConnection/unusedOrcadHostTransport placeholders, a typed
readPersistedState harness read (exposed a test treating optional
httpProxyUrl as always set), real Response objects in fetch spies, an
updater main-window fixture, a CDP webContents adapter, one shared
releaseModuleExport for cross-version tests, and requireOverlayDir in
place of `as string` on possibly-undefined overlay paths.
* fix(runtime): validate loaded device rows and host scope instead of casting
Two cast suppressions claimed checks that did not happen:
- device-registry-file-read: "normalizeLoadedDeviceRow re-validates every
field" was false; deviceId, token, name and timestamps were never
checked. Rows without an identity are now dropped and the file is set
aside through the existing corrupt-file path (registry reads as
doubtful, so no revocation verdicts); a non-string token is stripped
so the row stays listed but cannot authenticate.
- client-ui: "only optionality differs" was false; any string reached
persisted workspaceHostScope. Narrow it with isWorkspaceHostScope and
ignore unknown scopes (wire schema unchanged for mixed versions). The
remaining cast now states what it actually covers.
* test(runtime,ipc): drop redundant cast suppressions; typed runtime store fixture
-98 cast directives across runtime/ipc tests: 61 casts that typecheck
without the assertion; a typed vi.fn for scoped invalidation; a
partialRuntimeStore fixture in place of `store as never` for
OrcaRuntimeService; typed worker terminal/authority builders in the
incarnation-fallback suite (the old stub lacked runtimeId, ptyId,
worktreeId and launchTokenHash) plus removal of stacked duplicate
directives there.
* chore(lint): typed vi.mock imports and explicit listener snapshot in shared-bucket tests
Remaining files from the misc-rule pass that overlapped other buckets:
codex-accounts mocks use the typed vi.mock(import(...)) form instead of
a consistent-type-imports disable; the daemon late-exit fixture copies
its listener set with Array.from instead of a no-useless-spread disable.
* refactor(github,mobile): narrow routing settings type; drop remaining avoidable casts
- work-item-routing cast a one-field object to AppState['settings'] under
a claim that readers only consume activeRuntimeEnvironmentId. Return the
existing RuntimeFocusSettings pick instead and narrow the cache-key
chain's parameters, so the compiler enforces that claim.
- mobile file preview reads refusals through the RpcResponse `ok`
discriminant rather than a cast.
- terminal document host-notify accepts `unknown` errors, removing the
message-bridge cast.
- native chat readability drops a redundant repo-list cast.
* test(renderer): replace repeated cast suppressions with typed fixtures
-140 cast directives (and ~150 unsuppressed casts of the same shapes):
- mockPanePtyArgs owns the connectPanePty fixture casts, so a wrong
argument order or fixture is now a type error; drop binding casts for
members PanePtyBinding already declares.
- Seed AppState tab rows with the typed makeTerminalTab; this exposed a
split direction 'row' that is not a TerminalPaneSplitDirection.
- Partial GlobalSettings use getDefaultSettings overrides; Jira-only
stores use createTestStore; runtime environment rows/statuses come from
a typed paired-runtime-environment fixture.
* chore(lint): drop no-module-mocking disable now covered by the test-fixture glob
* test(e2e): fix all 221 grandfathered e2e type errors; baseline to zero
The e2e typecheck baseline grandfathered 221 errors in 119 files. About a
third were tests drifted from the current API, several of which would
fail or mislead at runtime:
- terminal-shortcuts called a nonexistent xterm buffer method;
- the daemon-lifecycle fake lacked terminateOwnedTree, hidden by importing
its type from a module that does not export it;
- arguments in the wrong position (listProcesses(hostId, opts), a dropped
pty.write inputKind, an extra toWebTerminalSurfaceTabId argument);
- removed enum values ('drawer', 'idle', 'editor',
'session-insecure-origin') and a launch_source the telemetry schema
rejects;
- missing required fields (turnScope, childWorkOpen, providerIdentity,
reviewLookupOutcome, runtimeServiceAccount behind an `as RelayConfig`);
- dead reads (tab.customTitle, bucket.targets, changedPixels).
Also lifts variables that narrowed to `never` after poll-callback
assignment, and adds a typed xterm render-dimensions accessor. Includes
the cross-version suites' shared releaseModuleExport adoption.
* chore(typecheck): gate the now-clean e2e typecheck in local lint
The e2e baseline is empty, so the ratchet now rejects any tests/ type
error. CI already runs it via run-ratchets; add it to pnpm lint's
explicit ratchet list and replace the stale 'not yet clean' note.
* test(mobile): typecheck every mobile test; baseline 105 files -> 0
mobile/tests-typecheck-baseline.txt grandfathered 105 test files (531
errors) whose types CI never checked. Contract changes had landed without
these tests following, and type pins in them silently checked nothing.
- Root cause: salvagedOptional (src/shared/zod-salvage.ts) cast away
zod's optional marker, so every reply type built on it claimed
salvaged fields were always present. Return a real ZodOptional;
runtime is unchanged (the outer optional short-circuits undefined).
- Production now takes the port it uses: RpcOperationSender instead of
RpcClient for send-only callers, a narrow fetch signature, and only the
request fields push-receive reads.
- findAllByHostType/findByHostType replace `'Text' as never` lookups;
stubRpcClient gives tests a typed RpcClient.
- Real test bugs: settings-host-client-lifecycle "relay" hosts were
direct hosts (relayHostId no longer exists); two toEqualTypeOf pins
could never hold; a recovery hook ran with an undefined scope key;
a create-PR test cast to a never-imported type; "no URL" assertions
passed on null; plus stale required props, args and enum values.
* test(e2e): parse workerStart result instead of casting it
* test(runtime): typed partial runtime stores with production-shaped fixture data
Route every partial store passed to OrcaRuntimeService through
partialRuntimeStore with typed row builders, removing 60 cast directives
that hid fixture data production never produces:
- paired-client-navigation-test-harness keyed setWorktreeMeta writes by
`[object Object]` (it took an id where the store takes a target), so
reads never saw them;
- invalid worktree lineage origin/capture and incomplete workspace lineage;
- getWorkspaceSession returning null where the store returns the default
session; getGitHubCache returning undefined;
- orcad migration states missing migrationId/manifest/receipt, with a
toEqual pinned to that incomplete shape;
- partial repos, metadata, folders, project groups and notification rows.
* refactor(renderer): resolve suppressed React hook lint instead of disabling it
109 of 187 react-hooks/react-doctor suppressions fixed:
- ~95 exhaustive-deps disables only hid stable refs and setters passed
through controller objects; list them (identity never changes, so
nothing re-runs), plus a few real stale closures (tabId/worktreeId).
- Effects keyed on one value that read the latest props now use
useEffectEvent (WebConnect, skill freshness, Bitbucket dialog seeding,
Landing preflight, automation catalog, structured-session recovery,
file explorer).
- The conditional layout-owner hook is selected once at module load from
the build constant instead of a rules-of-hooks disable that also hid
the whole controller from compiler and react-doctor rules.
- A hook disable was masking a react/purity Date.now() in the palette's
recent-tabs memo; sample it when the snapshot is captured.
- Three identical debounced-search effects share
useTaskSearchDebouncedApply; layout snapshot merge helpers move out to
stay under max-lines.
Remaining suppressions are mount-once resources, invalidation epochs,
deliberately keyed fields, and test harnesses that mock the dispatcher.
* chore(ratchet): exempt test harnesses and fixtures from the focus-read ratchet
The ratchet skipped *.test-fixture.ts but scanned *-test-harness,
*-test-fixture(s) and *.test-support files. Those seed settings with
getDefaultSettings (which the ratchet discovers as a focus reader) and
never route host work, so 17 baseline entries were false positives, and
replacing a test's `settings: {...} as never` with typed defaults tripped
it. Match the repo's test-support names and prune (which also drops one
stale entry), and rename the frame-ordering harness to *-test-harness like
its siblings. A blanket "-harness" match would also exempt
e2e-terminal-pty-harness, which production imports, so the names stay
explicit.
* test: merge duplicate shared/constants imports
* revert(file-explorer): restore original tree load effects pending SSH e2e investigation
* test(runtime): drop RuntimeStore cast now that the fixture is typed
---------
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
|
||
|
|
7190b835f1 |
test(e2e): stop restarted serve hosts with SIGTERM so the PTY daemon survives (#33067)
On macOS, orca serve vetoes an unmarked app.quit() (#15537), so Playwright's close never finished and its fallback force-killed the whole process tree, including the detached PTY daemon's terminals. The restart spec's fixture process got SIGTERM and the spec failed on every macOS run. Restart now stops serve the way a supervisor does (SIGTERM, a marked quit), and the restart spec no longer shows or focuses its client window. |
||
|
|
82534d0183 | refactor: colocate remote runtime passthrough socket (#33009) | ||
|
|
d1aef1eee9 |
refactor(worktrees): remove unreachable legacy worktree list IPC (#32942)
* refactor(worktrees): remove unreachable legacy worktree list IPC The desktop and web preloads both always provide `worktrees.listDetected`, so the renderer's fallback to `worktrees.list` never ran, and nothing calls `worktrees.listAll`. Remove both IPC handlers, their preload/web wrappers, the renderer fallback, and helpers only they used. Tests that observed behaviour through the removed handlers now go through `worktrees:listDetected`. * test(worktrees): drop removed list channels from SSH listing matrix Address review: the canonical SSH listing test built channel names dynamically and still invoked worktrees:list/listAll. Also fold the detected-result reader into the shared worktree test fixtures, refresh stale comments, and assert the backfill no-op test listed authoritatively. --------- Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> |
||
|
|
4c7991509f | feat(browser): say why a page failed to load and reload it when it can (#31847) | ||
|
|
8fc1698ebb |
Add Resource Manager PTY inventory and checked terminal termination (#31593)
* feat(resources): end local terminals with checked identity checks - Add a PTYs view to the Resource Manager that lists local terminals and can end one. Before stopping, the host confirms the terminal's incarnation, agent ownership, and attachments. This prevents ending a same-ID replacement that started after the list was read. - Bump the daemon protocol to v50 and gate the new fenced kill on it. Older daemons ignore the extra fields, so the client refuses End instead of sending an unchecked kill. - Admit diagnostic reads (PTY listing and memory snapshot) only while the Resources view is visible, so a hidden window does no background scanning. - Report incarnation and host on spawn and exit events so the renderer can match them to the terminal it showed. - Replace the popover's terminal-session list with the new inventory and move memory polling into the Resources view. * Show unrouted daemon PTYs in the Resource Manager * Simplify PTY controls and clarify safe termination * Format local build compatibility protocol lists * Add PTY resource management localization strings * Harden PTY resource manager test fixtures * Use typed IPC event in PTY kill test fixture * Refine local PTY resource view model typing * Refine local PTY resource view model typing * Include local host identity in PTY lifecycle event tests |
||
|
|
4dd97f02d5 |
A paired desktop's tab moves, splits, resizes, props and renames in a server workspace go to the server's layout (switch-on builds only) (#31714)
* wip(h5c-1): server workspace layout intents go to the server's main; positions per stream * wip(h5c-1): e2e without a cast * fix(h5c-1): a routed move never moves here; routed callers read the server's stream; a restarted main starts its positions over * fix(h5c-1): layout-apply-send back under its line limit * test(h5c-1): a routed answer reaches the handler with the server's stream key * fix(terminal): a CLI or phone close through main keeps a pinned tab, as the window-era close did * feat(terminal): main applies phone closes, renames, pane titles, sleeps and agent-launch tabs itself, with or without a window (layout-owner build) * fix(terminal): a tab close through main also ends the tab's dormant SSH relay session; agent-launch tabs main writes keep the window's focus rule, prompt and outcome (layout-owner build) * feat(terminal): main starts a new tab's first terminal under the window's ids, and the pane attaches to it (layout-owner build) * test(terminal): tests that counted the window's create calls or publications see main's start of a new tab * fix(terminal): an account-switch restart binds only into a pane main's layout holds, with no window tree (layout-owner build, L197) * test(terminal): the new-tab start tests hold no type assertions; the start's ledger row is L252 * fix(terminal): a new tab's pane attaches to any terminal main binds it to, and a failed start keeps the tab's startup * test(terminal): a Claude account-switch restart's tests draw the pane main holds * fix(terminal): a launch pane main takes back still tells the window why, which drops its hold and prompt; a rename through main answers the name it stored (layout-owner build) * fix(terminal): a new tab another owner's terminal won attaches to it, and a failed start's startup never runs twice * fix(terminal): main's pane close reads its stop result as a type only, so no runtime module loads before its base class * fix(terminal): a phone's close through main drops the closed rows from what phones list at once, not at the window's next publish (layout-owner build) * chore(terminal): mark the phone-close row drop interim (ledger L260) * test(worktree-create): a new local tab's startup counts as run when main starts it (layout-owner build) * test(worktree-create): record main's starts without a type assertion * fix(terminal): a tab closed before main declines its start gets no startup back (layout-owner build) * fix(terminal): the window's new tab starts in main when its own window asks over IPC, which labels itself a client (layout-owner build) * feat(h5c-2): a paired desktop's writes to a server workspace its frames draw land in that server's main (layout-owner build) - Routes setTabProps, setChatPane and non-terminal renameTab to the server's main as layout.apply; closes, starts, sleeps and terminal names keep the RPCs that main now applies (session.tabs.close, terminal.close, terminal.split, session.tabs.createTerminal, terminal.rename). A window-style closeTabs is never routed: main takes it as already stopped and stops nothing. - A close the server refuses (a pinned tab) redraws the workspace from the server's frames, so the window's optimistic drop never outlives the answer; same for a refused pane close. - A frame-drawn workspace keeps none of the mirror's ledgers (L240): no tab-id mappings, close or focus intents; they stay only for servers without layout.intents.v1 until the Phase 2 cutoff. Its pane-geometry push is skipped (it goes as intents); pane renames still push. - e2e: paired-desktop-server-layout-writes covers close (layout, session.tabs, terminal stop), rename, split and new tab on a windowless switch-on serve. * fix(h5c-2): an undelivered close of a frame-drawn tab is held for replay; a launch-agent clear stays off the server route * refactor(h5c-2): the undelivered-close test moves to its own module, keeping the lifecycle file under its line cap * fix(h5c): a routed tab move anchors on the server's tabs only, and never sends an anchor the server does not hold (layout-owner build) * fix(h5c): every routed tab move is placed among the server's tabs at the routing point, skipping desktop-only tabs (layout-owner build) |
||
|
|
ed13ca1e6f |
Layout groundwork (switched off): main starts and restores every pane, and the window only attaches and paints the host's history (#31567)
* feat(terminal): the window's store shows main's pane start status (layout-owner build) A status-only frame changes one store entry and no pane tree, so the pane's view stays mounted. * refactor(terminal): keep the frame sync within its line budget * feat(terminal): every pane main starts shows 'starting' from before it is written (layout-owner build) * feat(terminal): a pane main is starting waits and attaches; a failed start shows why (layout-owner build) Fixes owner-visible row 15: a failed agent or setup start no longer opens a plain shell. * test(terminal): iterate store listeners directly * fix(terminal): an exit that reports no code keeps its pane, as lost contact (layout-owner build) * test(terminal): a pane main started attaches to main's terminal at its own grid * test(terminal): detach census tests assert main's move and frame with the switch on * fix(terminal): a restored pane paints history only from its terminal's host, never the window's copy (layout-owner build only) * fix(terminal): main releases a painted cold restore only for the pane's current terminal (layout-owner build only) * test(terminal): typed ack args in the painted cold-restore test * test(terminal): exited-pane tests assert main's close with the switch on These 8 have failed switch-on since #31130 moved the exit close to main. * feat(layout): main starts the panes a client's startPane or wake names, through its one restored-pane starter (layout-owner build only) The model's start and stop effects reach the runtime once the command is written, never the reply. startPane starts a pane whose binding has a start status, and a slept pane from its record. A wake keeps a pane's resume record until its start binds; a failed start keeps it and shows why. With the switch on, main owns a running agent's wake even with a window open. * fix(layout): a window's wake of a pane it resumed itself is record-only, so main does not start it again (layout-owner build only) * test(layout): a client's startPane starts the pane before any other trigger * Revert "fix(terminal): a restored pane paints history only from its terminal's host, never the window's copy (layout-owner build only)" This reverts commit |
||
|
|
98007cb5f5 |
refactor(sidebar): one shared feed client for the desktop window and the phone (#31524)
* fix(sidebar): land flip-a's switch-on fixes on main, still dark (no flip) The fixes found while the sidebar ran from main's feed, without turning that on: ORCA_SIDEBAR_INPUTS_IS_MAIN stays false, and none of flip-a's stop-gaps come along. - Main stops counting a closed tab's terminal once it was asked to stop and no pane shows it; a failed or refused stop takes the request back, and a host out of contact stays unverifiable. - Main fetches a paired server's rows with the transport's normal bound, so a server slower than 5 s still lists. - A deferred unread raise flips the folder row it was decided for, and a read while the owner check is out cancels it. - Phone: no worktree.ps flash before the feed; a host's last installed feed stands in while a fresh read is out; it highlights its own last-opened workspace and a fold never scrolls; projects file under their project group with the desktop's indent; the collapse spinner shows only after 500 ms; "Reopen to update" keeps the rows on screen. - e2e helpers and journeys for the switch-on suite. * fix(sidebar): keep an owed relay stop marked, clear a thrown stop, and prune pending unread raises - A stop-and-wait that throws takes its stop request back, like one that fails. - A final stop the legacy relay still owes stays marked, since the relay retries it. - Pending unread raises are tracked only while one waits, so the map no longer grows. - The paired-server fallback poll test gives its third fetch a reply and asserts live. * refactor(sidebar): read the sidebar feed through one shared client library on desktop and phone The window and the phone each had their own feed reader. Both now use one reader under src/shared/sidebar-feed-client: paging, notices, retries and the snapshot it installs. A snapshot reuses each unchanged entity's parsed object, so one row's change re-parses one row instead of its whole domain. Adds the gesture and view-report pieces later cuts wire up. Lists are unchanged on both sides. Co-Authored-By: Claude <noreply@anthropic.com> * refactor(sidebar): drop the feed client's unused pieces until their callers land Co-Authored-By: Claude <noreply@anthropic.com> * test(sidebar): key the snapshot test's rows by host identity, as main's feed types now do Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
92bbb380a6 |
Sidebar: land the switch-on fixes from the flip branch on main, switch still off (#31466)
* fix(sidebar): land flip-a's switch-on fixes on main, still dark (no flip) The fixes found while the sidebar ran from main's feed, without turning that on: ORCA_SIDEBAR_INPUTS_IS_MAIN stays false, and none of flip-a's stop-gaps come along. - Main stops counting a closed tab's terminal once it was asked to stop and no pane shows it; a failed or refused stop takes the request back, and a host out of contact stays unverifiable. - Main fetches a paired server's rows with the transport's normal bound, so a server slower than 5 s still lists. - A deferred unread raise flips the folder row it was decided for, and a read while the owner check is out cancels it. - Phone: no worktree.ps flash before the feed; a host's last installed feed stands in while a fresh read is out; it highlights its own last-opened workspace and a fold never scrolls; projects file under their project group with the desktop's indent; the collapse spinner shows only after 500 ms; "Reopen to update" keeps the rows on screen. - e2e helpers and journeys for the switch-on suite. * fix(sidebar): keep an owed relay stop marked, clear a thrown stop, and prune pending unread raises - A stop-and-wait that throws takes its stop request back, like one that fails. - A final stop the legacy relay still owes stays marked, since the relay retries it. - Pending unread raises are tracked only while one waits, so the map no longer grows. - The paired-server fallback poll test gives its third fetch a reply and asserts live. |
||
|
|
c149395c20 |
fix(remote-terminal): repaint an idle full-screen program when a reconnect can't image its pane (#31482)
* fix(remote-terminal): repaint an idle program when a reconnect can't image its pane After an SSH reconnect the pane is repainted from the host's screen snapshot. When the host cannot give one (too large for the replay limit, no buffer, unanswered, overflowed), the pane only printed a loss banner and an idle full-screen program that writes diffs kept its pre-disconnect frame until the user resized. The two places a remote pane declares it has no host image now ask the program to repaint through one choke point: a one-row viewport claim and back, which every TUI honours (Node's tty ignores a same-size SIGWINCH). It respects a phone or another desktop holding the size, skips hidden panes, and puts the row back even if the pane unmounts mid-nudge. Fixes #26887 * test(e2e): idle full-screen program frame after a managed SSH outage * test(e2e): wait for the pane before typing in the idle-frame spec * fix(remote-terminal): pick the redraw height on the host's clamped grid * fix(remote-terminal): wait for the host's grid before putting the redraw row back * test: give transport mocks a connection status for the redraw gate * test(e2e): keep the orcad idle-frame proxy typed for the e2e ratchet * fix(remote-terminal): let a new PTY's redraw supersede a swapped-out nudge * test: keep new transport-mock lines free of type assertions * ci(e2e): route the managed-SSH idle-frame spec to its sources |
||
|
|
b3e6705337 |
fix(orcad-migration): a sidebar view setting never blocks moving an SSH host to its server (#31374)
* fix(orcad-migration): a sidebar view preference never blocks moving an SSH host to its server * fix(orcad-migration): keep repo filters on the desktop, keep later acknowledgements; e2e repro |
||
|
|
ce71535bbf |
Layout groundwork (switched off): main starts every split and new pane, the window only attaches (#31258)
* feat(terminal): the window's store shows main's pane start status (layout-owner build) A status-only frame changes one store entry and no pane tree, so the pane's view stays mounted. * refactor(terminal): keep the frame sync within its line budget * feat(terminal): every pane main starts shows 'starting' from before it is written (layout-owner build) * feat(terminal): a pane main is starting waits and attaches; a failed start shows why (layout-owner build) Fixes owner-visible row 15: a failed agent or setup start no longer opens a plain shell. * test(terminal): iterate store listeners directly * fix(terminal): an exit that reports no code keeps its pane, as lost contact (layout-owner build) * test(terminal): a pane main started attaches to main's terminal at its own grid * test(terminal): detach census tests assert main's move and frame with the switch on * test(terminal): exited-pane tests assert main's close with the switch on These 8 have failed switch-on since #31130 moved the exit close to main. * feat(terminal): main writes and starts every split of a pane it holds; the window attaches (layout-owner build) The window's split, a startup split with its command, and a CLI split all go through main's terminal.split; main's frame mounts the pane, with or without a window intent. Deletes the window's split wait and withdraw, the split appear intents, and the queued-split skip and cancel. The e2e helper uses the real split. A startup split leaves focus on its source pane. * fix(terminal): the attach-only wait leaves sleeping, resuming and held panes to their restore path * fix(terminal): a split pane attaches to the terminal main bound it to; a taken pane id is refused Also restores the proof that a split closed while it starts gets one answer and leaves no pane or start status behind. * fix(terminal): a window split main cannot start still shows its pane, failed, with why * fix(terminal): check a taken pane id first, keep the start's own error, clear a gone pane's status Three test stores gain the pane-start field the window's store always has. * test(terminal): the admission stub answers whether its pane is still written; a closed pane's failed start clears * refactor(terminal): the rebound workspaces' bindings show through one call in the bindings module * test(terminal): a pane main wrote and the user closed mid-start drops its failed status * fix(terminal): a split main starts is listed to phones and session.tabs without a window's report * fix(terminal): a reconnect shows its pane starting and why it failed; a lost owner race shows no failure; a split no one asked to see keeps the phones' tab * fix(terminal): a kept create another owner won shows no failure; the window attaches to the winner |
||
|
|
b99552cabc |
fix(runtime): a phone reads and saves Markdown tabs on a headless server (#31101)
* fix(runtime): a phone reads and saves Markdown tabs on a headless server With no window to relay through, markdown.readTab and markdown.saveTab answered renderer_unavailable. Main now reads the tab's file (or its saved draft) from disk and saves with a version compare plus the disk write precondition, in the shapes the window's editor relay returns. With a window attached the relay is unchanged. * Headless Markdown save: keep the draft's disk baseline, honour read-only tabs, re-find the record to clear * Use the disk baseline only for a draft * ci: run the phone Markdown spec's orcad case in the orca serve mode-switch job * Headless Markdown: answer from disk only; a window's saved draft stays its view state Clearing a saved draft wrote workspace layout from main, which no layout command carries. Main now never shows or edits a draft; the desktop's restore check reports a disk change. * Phone Markdown: one path through main and the disk, window or not A paired server's workspace is read and saved on that server with files.read / files.writeIfUnchanged, so it answers from its own disk and keeps the precondition. The window relay (ui:mobileMarkdownRequest and the renderer bridge) is removed. * e2e: a phone saves a Markdown tab the desktop holds unsaved edits in The phone reads the disk with the tab marked dirty; its save lands on disk, and the desktop keeps its draft and shows the changed-on-disk banner. * Group the Markdown disk host's imports * Drop an unneeded store cast from the dirty-readers test * Phone Markdown: refuse a save on a server too old to check the disk; cover the untitled tab A server before #30605 has no files.writeIfUnchanged, so the save is refused with the existing update-required message rather than written unchecked. * Phone Markdown: refuse a file an SSH host holds outside the workspace; pin the untitled answer * Phone Markdown: untitled tabs stay read-only; older servers save like the desktop editor; a closed-source preview still reads - The desktop lists an untitled document's tab with isUntitled (optional, additive); main answers it read-only with unsupported_untitled and refuses its save before touching the disk. - A server without the files.write.disk-precondition capability gets the desktop editor's guarded save: compare from here, then a plain files.write, or a conflict. Every call of a save is pinned to the pairing it probed. - A preview whose source tab was closed has no saved record; it reads its own file, read-only. * e2e: read the untitled tab's answer without a cast * Phone Markdown: pin a save's pairing before its first read A save captures the server's pairing before it reads, and every call of the save, the read included, is pinned to it, so a re-pair between the read and the write is refused. * Test: with no window, a phone saves an existing untitled.md and never creates a deleted one --------- Co-authored-by: E2E Test <e2e@test.local> |
||
|
|
065e6873f6 |
A paired desktop shows the held-terminal banner and Reopen for a server's held terminals (switch-on builds only) (#31275)
* A paired desktop shows a layout-owner server's held panes on the existing banner; Reopen asks the server (switch-on builds only) The server's frames carry status 'held' on a pane a newer build's terminal service may still run. The desktop now lists those panes on its existing newer-build banner, with the same wording and states. Reopen calls the server's new `layout.reopenHeldPanes` under the server's ids: the server stops its newer service, as the desktop's own Reopen does, and starts each pane still held. The desktop starts nothing; the server's next frames clear the status and bind the pane. A refusal or failure shows the banner's failed state. Served and advertised (`layout.reopenHeldPanes.v1`) only by a layout-owner build, to paired desktops (not phones). A server without the capability, or that publishes no status, shows no banner, as today. * test(layout): held server pane stays Reopening until the reattach frame, stays failed after a refusal, and shows nothing without the reopen capability * fix(layout): a held pane's Reopen acts only on its own host and on main's published status (switch-on builds only) - Reopen needs the clicked pane's key; a pane that already left the banner's store does nothing, so a server banner clicked as its frame drops the pane never stops this machine's newer service. - Local versus server is decided by the pane's host, not by whether it has a release. - The banner portal for a pane with no terminal handle exists only in a layout-owner build. - The server reopens only panes its published layout shows held, the status the desktop saw. * test(layout): Reopen ignores a pane rebound to a new terminal whose held entry is still stored * test(layout): the dropped-pane Reopen test checks for the reopen method, since the view report shares the RPC client |
||
|
|
893c4e24a4 |
fix(ssh): an old SSH host moves to its managed server while a relay shell named only on its tab still runs (#31093)
* fix(ssh): an old SSH host converts while a relay shell named only on its tab still runs The conversion check counted legacy pane-key aliases as terminals waiting to reconnect. An alias only routes hook events to a pane whose terminal the lease check, the bridge or the terminal gate already accounts for, so it no longer blocks the move. * Tighten the alias census comment * Register the tab-only relay spec: typed deployment lookup, relay fence baseline, PR route --------- Co-authored-by: E2E Test <e2e@test.local> |
||
|
|
b887483e55 |
fix(sidebar): the phone reads projects and project groups from main's sidebar feed, installed with the rows (#31102)
* fix(sidebar): the phone reads projects and project groups from main's sidebar feed, installed with the rows The phone built its project sections from a catalog the desktop window published through a side channel (mobileRelay.projectSections). That copy changed on a timer after the event that told the phone to re-read it, and a re-read asked for during a read in flight was dropped, so the phone could keep an old grouping (a project under the wrong group, a group missing) indefinitely. Main now publishes the catalog (repos with their group and order, project groups, projects and host setups, every host's including paired servers') as a projectCatalog domain of the sidebar feed, from its own store and its own reads of each paired server. The phone reads it from the same install as the rows. mobileRelay.projectSections stays, answered from the same builder, for pages that predate the domain; a page on a desktop without the domain still reads it, now re-reading when an invalidation lands mid-read. The phone e2e list helper runs the page's real refresh lifecycle instead of re-reading on every assertion, and covers a group move while a read is held. * test(mobile): stand AppState in for the screen hooks' react-native mocks, and tolerate a world with no project rows in the parity catalog * fix(sidebar): main files a server's copy of a grouped project under its group, and reads a server's catalog only on catalog events - The window gives an ungrouped paired-server repo the group of an existing copy of the same project (applyInheritedProjectGroups). That function now lives in src/shared and main's catalog builder folds each server's repos through it, so the phone files the copy where the desktop does. - A paired server's change watch now says whether the event can carry a catalog change. Only ready, a replay and reposChanged mark the catalog stale; worktreesChanged (pins, unread, sort stamps) reads rows only. - The parity fixture now builds the server side from raw server answers, folded through the window's mergeFetchedReposForHost and through main's own server read and builder, with a server copy of a grouped project and a partial saved manual order. It fails without the inheritance. * fix(sidebar): parse a paired server's catalog rows with a schema instead of reading keys reflectively * fix(mobile): sync the feed ref after render and re-read queued project sections without an await loop * fix(mobile): spell the AppState shape the refresh reads, so the e2e helper pulls in no React Native types * test(sidebar): give the merged builder test's feed domains a project catalog --------- Co-authored-by: E2E Test <e2e@test.local> |
||
|
|
49a2203b0e |
Remote Orca Servers: one list instead of six sections; SSH Hosts: bulk remove that stays removed (#31082)
* feat(settings): one-list Remote Orca Servers page and bulk-manageable SSH Hosts Remote Orca Servers: replace the three mode cards, Advanced fold, duplicate managed/SSH-access lists and troubleshooting accordion with a single list (one row per server: status, one action, overflow menu), an always-visible 'New projects open on' row, and Share / Cloud VM cards that open dialogs. SSH Hosts: group by source, filter, checkbox + shift-range selection, one confirm for bulk remove (skipping hosts with a managed server or workspaces), bulk Test. 'Sync ~/.ssh/config' no longer clears removal tombstones; 'Restore removed hosts (n)' is a separate confirmed action. * fix(settings): address review findings on servers and SSH hosts redesign - SSH filter stays clearable when the list shrinks under the threshold - Cmd/Ctrl-A only selects hosts when pressed in the list itself - group legacy no-source hosts with main's import predicate (now shared) - capture the shift-range anchor before queuing the selection update - blank server names de-duplicate instead of colliding - Share dialog Done refreshes link count and resets name editing - Install / SSH-route dialogs reload SSH hosts when opened - default-host row shows the selector when the default is a WSL host - managed 'Not running' no longer masks connecting/revoked/update states - servers without a dropped transport can be re-checked * test(e2e): WSL host spec matches repo.rm ending a removed project's shells repo.rm now stops the project's terminals on the host (#29964), so the 'orphan left by older builds' setup can no longer be built; use a shell only the host knows of instead. Resolve the project path so macOS /private/var matches what the host reports. * fix(settings): carry 'Orca on <host>' naming and paired-twice warning into the new server list Ports #31099 and #31100 into the redesigned rows, install dialog and SSH host dialogs. * test(e2e): keep the WSL spec's project path as created |
||
|
|
a2e0f20b1e |
Main sends one layout update per action, with only what changed (dark, layout-owner build only) (#31109)
* A respawned terminal's pane rebinds in one write, and the window shows a binding-only frame without a rebuild (dark, layout-owner build only) Main: when the window's spawn for a restored pane finds its process gone, the spawn that holds the pane's reservation keeps the dead binding and its fresh bind swaps it (the restart swap), so the pane is never published unbound: a same-id respawn publishes no frame, a new id one. A failed spawn still retires the dead binding. Other callers and window-owned builds retire early as before. Window: a frame that differs from the shown one only in panes' terminal bindings updates the store's pane trees as a rebuild would, falling back to a rebuild for holds and shared terminals. * Dead-owner respawn tests expect the layout-owner build's one swapped bind instead of the early retire * Main publishes one records frame per layout operation, and the window resubscribes on a missed frame (dark, layout-owner build only) Main: a durable mutation (a layout.apply, the renameTabs batch, a binding write, a repair) is one operation. It names the partitions it wrote, and at its end the layout stream publishes once: one `records` frame holding only the changed records (tab rows, workspace groups, a pane tree per tab, a binding record per pane, editor files, browser tabs, removed workspaces), each keyed by main's own ids. Writes no operation scopes (window saves) still publish when their task ends. The snapshot and every records frame carry a stream epoch. Each pane's binding carries `ptyGeneration`, which rises on every binding write in this process, so a same-id respawn is one frame with one binding record. Readers beside the stream get the end of each operation and the stream's own per-partition loaded model (`workspaceLayoutReads`), so they need no second Loader pass, with or without a window. Window: the cache applies records frames to its full layouts, so the existing flush and the binding-only path are unchanged. A records frame of another epoch or out of sequence, a malformed frame, or one the cache cannot apply resubscribes at once for a fresh snapshot. Tests install main's model check, which applies each frame to what subscribers held and compares it with a fresh projection; dev builds log a mismatch, release builds run none. * E1 review fixes: keep a swapped binding, bound the window's resyncs, guard operation listeners (dark, layout-owner build only) - A spawn whose swap bind persisted no longer retires that pane's binding when a later commit step fails; a pane on an SSH host keeps the early retire, since its dead owner lives there. - The window resubscribes at once at most three times before a frame applies cleanly, then takes the loss path's backoff. A skipped frame of a newer type still advances its position. - A throwing operation listener is logged; it no longer fails a committed mutation. - Tests freeze the shared partition model a reader gets; the dev-build model check skips frames that only change live titles. Generation and model-check comments say what is true. * Keep the layout stream's backoff reset after a single resync; only a resync storm holds it * A layout stream that recovers from a resync storm reopens on the normal delay again * Move the replaced pane owner into its own module so the stable owner no longer imports its replacement (dark, layout-owner build only) --------- Co-authored-by: E2E Test <e2e@test.local> |
||
|
|
e278bc9a17 |
feat(orcad-migration): unsaved drafts stay on this desktop and are renamed to the server on commit (#30894)
* feat(orcad-migration): unsaved drafts stay on this desktop and are renamed to the server on commit * fix(orcad-migration): refuse clashing drafts from the rename's own collection; stricter live spec * fix(orcad-migration): stamp renamed drafts with the server, rename at startup after a cut-off commit, keep draft refusals * fix(orcad-migration): retain only after a startup rename is durable; startup survives an unreadable journal * fix(orcad-migration): a cut-off commit is renamed and retained at startup, so the rename runs once * fix(orcad-migration): one retain per migration at a time; no rollback that could drop newer edits * test(e2e): check the visible draft in whichever editor a large file opens in * fix(orcad-migration): startup retains only migrations of hosts this profile owns * ci(e2e): route the editor-drafts migration spec to the sources it covers |
||
|
|
b358328b7f |
test(e2e): pane-close specs close panes the way the user does and check main's copy (#30745)
The pane-close consistency spec closed panes with a bare PaneManager.closePane, the drawing-layer call that never asks main. In a layout-owner build that close reached main only because killing the pane's terminal made main retire the pane; right after a reveal the terminal has not attached yet, so main kept the pane. Every user close path already sends the close to main first. The helpers now close through the pane close request the menu and shortcut use, and every scenario also checks that main's stored panes match the window's. |
||
|
|
9a46695f9f |
test(e2e): mount-authority spec polls through the host's "can't answer yet" terminal list (#30743)
* test(e2e): mount-authority polls retry the host's "can't answer yet" terminal list First-mount adoption briefly makes terminal.list refuse with terminal_surface_ownership_unavailable. Thrown out of an expect.poll callback, that ended the poll instead of retrying it, so the spec failed whenever a slow runner's probe landed in that window. * test(e2e): say the refused read returns undefined |
||
|
|
36913fd4f5 |
test(e2e): a phone lists the desktop's managed SSH workspace as the desktop sidebar does (switch on) (#30718)
* test(e2e): a phone lists the desktop's managed SSH workspace as the desktop sidebar does (switch on) * fix(sidebar): key folder workspace rows by host in the shared builder so the phone matches the desktop Co-Authored-By: Claude <noreply@anthropic.com> * test(sidebar): pin the SSH folder row key encoding Co-Authored-By: Claude <noreply@anthropic.com> * test(e2e): route the SSH phone feed list spec from its sources Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
162e07cf97 | fix(browser): refuse agent clicks while the user is mid-IME composition (#30358) | ||
|
|
78bad24d33 |
test(e2e): nine sidebar specs create workspaces and links through main so they pass with the switch on (#30667)
* test(e2e): create reveal-spec workspaces through main so they pass with the sidebar switch on The agent-send picker and host-section reveal specs injected fake repos and workspaces into the window store. With ORCA_SIDEBAR_INPUTS=main the sidebar lists main's rows, so those workspaces never appeared. The SSH host is now an unreachable target seeded into the stopped profile, and the paired-server host is a real headless orca serve host; pins, lineage and notes go through main. Co-Authored-By: Claude <noreply@anthropic.com> * test(e2e): type the seeded hosts as execution host ids Co-Authored-By: Claude <noreply@anthropic.com> * test(e2e): poll the reveal specs' page setup instead of awaiting it across CDP An evaluate that awaits a preload promise sometimes fails with "Resulting promise was garbage collected" in switch-on runs. evaluatePolled runs the work in the page, polls its outcome, and still fails on a rejected or failed write. Co-Authored-By: Claude <noreply@anthropic.com> * test(e2e): parent reorder spec creates its workspaces and links through main Co-Authored-By: Claude <noreply@anthropic.com> * test(e2e): lineage specs create their workspaces and links through main seedLineageScenario names and orders the two seeded workspaces and links them with assignWorktreeParent. Extra families and surrounding rows come from a fresh repo with real worktrees; pins and stale instances are main writes. Co-Authored-By: Claude <noreply@anthropic.com> * test(e2e): default-branch and downward-drag specs create their workspaces through main Co-Authored-By: Claude <noreply@anthropic.com> * test(e2e): reveal and active-delete specs create workspaces through main The 60-row reveal, the folder-workspace reveal and both active-delete tests now use real workspaces and folder workspaces added through main, ordered with metadata writes. The deletes go through the real removal path, so the row removal sampler waits by time rather than a frame count. Co-Authored-By: Claude <noreply@anthropic.com> * test(e2e): address review on the switch-on spec follow-up writeWorkspaceMeta now fails unless main lists the written values; the sleep test's parent is a real worktree instead of a store-faked one; the legacy inline-lineage case stays window-only and is skipped with the switch on; the parent-reorder collapse key is built from the row's host. Co-Authored-By: Claude <noreply@anthropic.com> * test(e2e): read-back reports an unlisted workspace and compares values structurally Co-Authored-By: Claude <noreply@anthropic.com> * test(e2e): wait for the added repo before showing its worktrees updateRepo returns false without writing when the store does not list the repo yet. On CI the add's own refresh superseded the helper's fetch, so the visibility write was skipped and every discovered worktree stayed hidden. The helper now waits until the store lists the repo and fails if the write is refused. Co-Authored-By: Claude <noreply@anthropic.com> * test(e2e): name the repo wait in its failure message Co-Authored-By: Claude <noreply@anthropic.com> * test(e2e): size the setup poll budget to the number of main writes evaluatePolled waited a fixed 10 s, sized for one write. Linking 53 children takes about 8 s locally and 36 folder workspaces about 4.5 s, so CI ran past it ("page work never settled"). Bulk setup now passes a budget of 10 s plus 500 ms per write. Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
0c3807e73b |
test(e2e): reveal specs create workspaces through main so they pass with the sidebar switch on (#30642)
* test(e2e): create reveal-spec workspaces through main so they pass with the sidebar switch on The agent-send picker and host-section reveal specs injected fake repos and workspaces into the window store. With ORCA_SIDEBAR_INPUTS=main the sidebar lists main's rows, so those workspaces never appeared. The SSH host is now an unreachable target seeded into the stopped profile, and the paired-server host is a real headless orca serve host; pins, lineage and notes go through main. Co-Authored-By: Claude <noreply@anthropic.com> * test(e2e): type the seeded hosts as execution host ids Co-Authored-By: Claude <noreply@anthropic.com> * test(e2e): poll the reveal specs' page setup instead of awaiting it across CDP An evaluate that awaits a preload promise sometimes fails with "Resulting promise was garbage collected" in switch-on runs. evaluatePolled runs the work in the page, polls its outcome, and still fails on a rejected or failed write. Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
6328a104bd |
refactor(ssh): split ssh-connection-utils into concretely named modules (#30488)
* refactor(ssh): split ssh-connection-utils into concretely named modules - classifiers -> ssh-reconnect-error-classification.ts - retry/timeout constants and sleep -> connection/ssh-connection-timing.ts - buildConnectConfig -> connection/ssh-connect-config.ts - credential callbacks -> connection/ssh-connection-callbacks.ts - exec options and abort error -> connection/ssh-exec-options.ts - wrapRemoteCommandForPosixShell -> ssh-posix-command-wrapper.ts - shellEscape and shared/wsl-login-shell-command quotePosixShell (identical) -> shared/shell-argument-quoting.ts quotePosixShell No re-exports are left behind. Co-Authored-By: Claude <noreply@anthropic.com> * fix: point the WSL git benchmark and the WSL lane route at shell-argument-quoting Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
88241bcd1e |
feat(sidebar): the phone reads its workspace list from the sidebar inputs (dark) (#30462)
* feat(mobile): the phone page lists workspaces from the host's sidebar feed (dark) * fix(mobile): settle pending option changes by latest intent; feed carries the desktop's focused host and host names (dark) * fix(sidebar): the feed carries the desktop's pinned placement; e2e compares the phone list to the desktop sidebar (dark) * test(sidebar): the phone list e2e also expands and unpins * fix(sidebar): phone feed list review fixes (dark) A collapsed or worktree.ps-failing feed list no longer shows an empty or error state; a queued worktree read uses the latest client; a superseded option change does not report a refusal; the window shadow leaves the focused host to main's test (focus-read ratchet). * fix(sidebar): phone feed tests typecheck; e2e helper no longer pulls the native runtime types Mobile test fixtures fill the fields the test project's types require; the feed trigger type lives with the feed reader, so the e2e helper's imports stop dragging react-native globals into the e2e program; React Doctor's two blocking findings. |
||
|
|
19e45b7921 |
feat(sidebar): the desktop window lists main's sidebar inputs behind the build switch (dark) (#30461)
* feat(sidebar): the desktop window lists main's sidebar inputs, with its own writes shown until main does (dark) Co-Authored-By: Claude <noreply@anthropic.com> * fix(sidebar): a newer write wins in the pending layer, created rows hold the stamped record, writes name their host (dark) Co-Authored-By: Claude <noreply@anthropic.com> * chore(sidebar): move the focus-read allowance with the window list model it moved into (dark) * perf(sidebar): main's sidebar feed publishes a change after a quiet spell at once, not 50 ms later (dark) * test(e2e): the desktop reads-main spec skips on a switch-off build and waits for a frame after collapse --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
3ad036551e |
fix(native-chat): clicking Send or Stop keeps focus in the message box (#30456)
* fix(native-chat): clicking Send or Stop keeps focus in the composer A click focused the Send/Stop button; when it disabled (empty draft after the turn, or while a Stop is in flight) Chromium dropped focus to <body>. A pointer press on it no longer moves focus, matching Enter. Adds an e2e regression with a turn-capable Claude stub. Fixes STA-10897. * Tighten comments |
||
|
|
2d1ec53533 |
refactor(ssh): fence the legacy relay in ssh/legacy-relay/ and drop the relay name from live deploy primitives (#30292)
Moves legacy-relay-bridge/ plus the relay-only census and endpoint files into ssh/legacy-relay/, so the 2027-01-15 retirement deletes one folder. Live install, exec and framing modules that only carried the relay name become remote-*. git mv plus import, path-literal, routing and workflow path-filter rewrites only; no remote file name or path changes. |
||
|
|
9bd47de3cf |
feat(sidebar): after a restart, the host clears sort tiers nothing backs any more (dark) (#30259)
* feat(sidebar): sort stamps reconcile stored tiers at startup against live hook rows and terminals (dark) * test(sidebar): a restart clears an unbacked local tier and keeps an SSH host's * fix(sidebar): run the sort tier reconcile once hook rows and PTYs settle, seeding hydrated rows * fix(sidebar): clear a stored tier only on proof its terminals died; a rest seed adds no clear * chore(sidebar): merge origin/main; locality helper moved to shared |
||
|
|
1de30d8235 |
test(e2e): the Windows CLI matrix convert cell calls the convert helper that exists (#30231)
convertThenRetire was never exported, so the spec failed to load; convertAndRetain is what the other upgraded-profile cells use. Also narrows the deployment union so the helper typechecks. |
||
|
|
dbb84f4ad9 | fix(ssh): move parked terminal history through the snapshot channel so a big saved buffer no longer blocks a host's move (#30126) (#30188) | ||
|
|
6fcc183ab9 | feat(sidebar): put main's sidebar inputs behind the ORCA_SIDEBAR_INPUTS dark build switch (#30050) | ||
|
|
77c511b316 |
feat(sidebar): main produces per-workspace activity facts, checked against the window in dev and test (#29980)
* feat(sidebar): main produces per-workspace activity facts in shadow mode * perf(sidebar): agent pings keep last-read surfaces; shadow counts comparisons * fix(sidebar): settle review findings in the activity-facts producer and shadow check * fix(sidebar): refresh on inventory verdict clears; resync agents only when tabs move * fix(sidebar): scope the shadow comparison by each row's owner, not the focused host * refactor(sidebar): name the shadow scope after what it keeps * fix(sidebar): classify sidebarInputs as host-owned in the operation ownership census |