mirror of
https://github.com/stablyai/orca.git
synced 2026-11-01 01:27:35 +00:00
bc80bc59fb962534f6ff6bea70d4e4624ca95fd4
934
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
bc80bc59fb |
fix: retire extension iframe event listeners with native frame (#35011)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> |
||
|
|
808aaee3f6 |
fix(wsl): hide the sidebar setup-script card while the repo's distro is stopped (#35163)
A background hooks:check refused for a stopped WSL distro now says so (unavailable: 'wsl-distro-stopped'). The setup-script prompt maps it to a distro-stopped state: the card hides instead of showing 'Couldn't verify…' with a Retry that cannot succeed, and focus re-inspects, so the card returns once the distro runs. An unverifiable distro stays a retryable error. |
||
|
|
c58591e56d |
fix(wsl): refuse render-driven hook checks on a stopped distro instead of booting it (#35155)
hooks:check takes an optional background flag. The sidebar setup-script prompt and the setup guide's progress probe, which run on render, pass it: on a stopped or unverifiable WSL distro the check answers status 'error' without opening orca.yaml over \\\\wsl.localhost, which would boot the distro. Launch preflight and settings, user acts that start the distro anyway, are unchanged. |
||
|
|
f231d1cde6 |
feat(files): play remote audio and video through one byte-range preview path (#35038)
* feat(media): read remote media ranges through the paired runtime Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(media): stream remote media through orca-media grants Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(editor): play video and audio from remote runtime workspaces Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(media): surface update-required for remote media and cancel in-flight chunks Probe files.readChunk once per environment and pairing revision before minting a grant so older servers show the update message. Closing a media stream now aborts the in-flight remote chunk. Also validate the IPC address, fix extension-only names, and tighten the preview return type. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * refactor(files): one classifier decides which viewer opens a file Local reads, files.readPreview on hosts, git blob previews and the desktop's remote binary handling each kept their own image/PDF extension table, and media had another. file-preview-kind.ts is now the one table: image, PDF, audio or video, with the MIME type. AVIF, which only local reads knew, previews on hosts and in git diffs too. * perf(runtime): give byte-range reads their own small call lane files.readChunk (media streams, paged files, downloads) now runs in a two-call lane per environment, so a playing video or a download never holds the slots terminal input and workspace calls use. * feat(files): stream previews from paired runtimes by byte range Generalises the remote media grant into one byte-range preview path: an orca-media:// grant keyed by environment, worktree, path and pairing revision, streamed over files.stat/readChunk. Audio and video use it now; the shared classifier decides which viewers do. - One files.stat at mint replaces the readChunk probe: it proves the host serves range reads and that the path is a file, so an old host or a missing file fails in the tab, not as a silent player error. - A burst of range requests shares one stat (reused for 1s), so seeking costs one round trip less on a slow link; later requests re-stat, so a growing recording keeps playing. - Removing a paired runtime revokes its grants; a re-paired one answers 410 and drops the grant. - Only readers that render bytes mint a stream; baseline checks don't. Co-authored-by: Sahil Sharma <128581847+SahilSharma0810@users.noreply.github.com> * fix(files): prove chunk reads at mint, and let a reload report the new size Hosts from v1.4.5 answer files.stat but only v1.4.111 and later answer files.readChunk, and no capability names it, so minting reads one byte, cached per pairing, and an older host fails in the tab with the update message. A re-mint seeds the grant with its fresh stat, so a reload never reuses an older size. A renderer gone mid-mint mints nothing. Preview chunks time out after 20s so a stalled one frees its lane sooner. Co-authored-by: Sahil Sharma <128581847+SahilSharma0810@users.noreply.github.com> * fix(files): resolve preview hosts in the pairing registry's own directory The remote preview reader looked environments up under the canonical user-data path, while the pairing IPC writes the registry under app.getPath('userData'), which can differ in casing on case-sensitive installs. Both now use one getter. A chunk-read verdict is cached only when a pairing revision pins it, so it can't outlive a re-pair. Co-authored-by: Sahil Sharma <128581847+SahilSharma0810@users.noreply.github.com> * fix(files): read the pairing registry from one directory everywhere Doc previews resolved paired servers under the canonical user-data path, the same casing mismatch the media reader had. They and every other main caller that names the registry directory inline now use getRuntimeEnvironmentRegistryRoot(), so it has one source. Co-authored-by: Sahil Sharma <128581847+SahilSharma0810@users.noreply.github.com> * fix(files): pin an unpinned preview grant to the pairing it was minted on A renderer that hadn't loaded the environment's pairing revision yet sent none, and every later chunk read went unguarded, so a re-pair under the same environment id would let the old URL read from the new host. Main now pins the registered revision at mint. Co-authored-by: Sahil Sharma <128581847+SahilSharma0810@users.noreply.github.com> * refactor(files): route the remaining pairing-registry readers through the one getter AI-vault host scans, the settings runtime-environment preference, skill capability checks and the mobile relay host list named the registry directory inline. They now use getRuntimeEnvironmentRegistryRoot() too; callers that also use the directory for other storage keep their own path. Co-authored-by: Sahil Sharma <128581847+SahilSharma0810@users.noreply.github.com> * refactor(files): write new pairings through the same registry root The ephemeral VM pairing writer named the registry directory inline; it now uses getRuntimeEnvironmentRegistryRoot() like every reader. Co-authored-by: Sahil Sharma <128581847+SahilSharma0810@users.noreply.github.com> --------- Co-authored-by: Sahil Sharma <128581847+SahilSharma0810@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
15fac13c5f |
Limit extension visible-tab capture admission (#34962)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> |
||
|
|
2747079f94 |
fix(wsl-mover): ask before quitting while a WSL project move runs (#34860)
* fix(wsl-mover): ask before quitting while a WSL project move runs A plain quit (Cmd/Ctrl+Q, closing the window) during a move gave no warning: the next launch recovers safely, but the move is lost. While main reports a move running, the window's close guards now ask "A project is moving to its WSL host. Quit anyway? The move will be undone at next launch." Behind the internal WSL hosts gate: the guard registers only with it open, and main answers false with it closed. An intentional restart and an unanswered question never prompt. * fix(wsl-mover): the quit prompt's running check gives up after 2 s The close request is acknowledged before the guards run, so a hung wslMove:isRunning would block quitting for good. The guard now treats no answer within 2 s as no move running, like a failed ask. * test(wsl-mover): give the flag-off host test the confirmation dialog the quit guard reads Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
ad8d35eb59 |
feat(wsl): serve saved WSL work behind a closed hosts gate (gate states, kill switch 1/2) (#34683)
* feat(wsl): serve saved WSL work behind a closed hosts gate (serve-only) The WSL hosts gate gains three states. A closed gate with a saved WSL host or a committed move becomes serve-only: saved hosts stay listed and reachable, committed rewrites, retention, interrupted-move recovery and the way back keep running, and the preload API is exposed through a stamped window argument. Adding hosts and starting moves still need the open gate. With nothing saved the gate stays closed exactly as before. * fix(wsl): stamp serve-only into the dashboard popout and Space windows too They load the same preload, so without the argument they hid saved WSL hosts' status and Connect in serve-only. One helper now supplies the argument for every window on the shared preload. * fix(wsl): reviewer follow-ups for the serve-only gate - Refuse wslHosts:add unless the internal gate is open here, so this PR is safe on its own. - Promote on any move journal entry, so recovery can reset an in-flight move whose host record is gone. - List unfinished moves in serve-only. - An unreadable WSL deployment store fails closed in serve-only too, through a shared serving flag main sets at startup. - Report the gate state in wsl_usage_snapshot as an optional field. |
||
|
|
f173998203 |
feat(wsl-host): a chat on a stopped WSL distro says so and offers Start (#34681)
* feat(wsl-host): a chat on a stopped WSL distro says so and offers Start * fix(wsl-host): a chat's Start never cancels a pending WSL host Remove |
||
|
|
1eaaf85e9f |
Land the WSL project mover dark (merges only after verify-15b, the flag-off audit and green CI) (#34059)
* test(orcad-migration): pin the SSH manifest through the real dormant collectors Co-Authored-By: Claude <noreply@anthropic.com> * refactor(orcad-migration): read the dormant-state export through a source-kind scope A local-WSL scope lives on host local and owns only its projects, so host-wide matches stay an SSH whole-host rule. SSH bytes are pinned by the collector golden. Co-Authored-By: Claude <noreply@anthropic.com> * feat(wsl-mover): export a local WSL move's signed manifest with its dormant state (D1b-3c) Collects the scoped projects, their groups and every dormant-state kind through the local-WSL export scope, rewrites UNC paths to the distro's, and returns blockers for anything the collectors can't carry instead of dropping it. Automations move disabled, as the wire requires, and come back as a list to re-enable on the host after commit. Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): reset an interrupted move to zero, or finish it once the host proves a commit Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): abort a move by its identity when its manifest is too large for a request Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): cap a new move's manifest below the request limit, and move forward on a by-reference commit only once the host flushed it Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): remove only the newest move of a distro, so its chain stays readable Co-Authored-By: Claude <noreply@anthropic.com> * feat(runtime): clients read a migrated pane's scrollback from its host (D1b-6d-1) * fix(runtime): hold a remote pane only when its host is known to serve scrollback, and never read bytes in render (D1b-6d-1) * fix(runtime): route the scrollback read by the tab's own host, never the focused one (D1b-6d-1) * fix(runtime): resolve the scrollback host through resolveOwner and use the shared RPC error check, after main moved both (D1b-6d-1) * feat(wsl-mover): a moved project's existing chats stay listed and resumable on this computer (D1b-7a) * fix(wsl-mover): moved-project chats go through the layout owner instead of writing layout directly (D1b-7a) * test(wsl-mover): run the moved-project chat runtime test in the Node runtime (D1b-7a) * test(wsl-mover): read the hidden local row through main's per-host hidden-repo API (D1b-7a) * feat(wsl-mover): rewrite the desktop's routing and seed the host's session after a move (D1b-7c) Registers the main-side desktop rewrite stores ui-routing, session-globals and host-session-seed. Adds a +2 main layout-writer baseline line for wsl-move-main-rewrite-stores.ts: these are one-shot, ledgered move rewrites, and no LayoutCommand can set focus or seed a runtime host's partition. * fix(wsl-mover): finish the main rewrite before the window loads, keep one copy of each moved tab, and copy instead of move (D1b-7c) * feat(wsl-move): rewrite renderer stores for moved projects and keep their UI through catalog prunes (D1b-7d) Registers the renderer-side desktop rewrite stores quick-open-history, file-view-preferences and notebook-environments. The renderer copies each moved workspace's entry to its WSL host key, marks it applied in the same storage, and records the ledger entry; main requests a storage flush first and accepts only the main window. Committed moves are re-listed for re-application at every startup. Catalog prunes keep filters, hook trust and setup-script dismissals of moved repos. * fix(wsl-move): import the migration manifest types from main's orcad-migration folder (D1b-7d) * fix(wsl-move): import wslUncPathToLinux from shared wsl-paths in the manifest exporter, where 7d moved it (D1b-7d) * feat(wsl-mover): rewrite a moved project's orchestration history on the desktop (D1b-7e) Settled local worker dispatches and their worker-terminal rows in a moved project take the WSL host's worktree id, in one ledgered, idempotent store. Chat workers, live rows, federated attachments and JSON receipts stay as written; automations keep their unchanged local copy (the scheduler only advances it). Per-table dispositions for orchestration.db. Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): hold the orchestration store while a worker in scope is live; skip federated rows (D1b-7e review) Co-Authored-By: Claude <noreply@anthropic.com> * feat(wsl-mover): copy in-app browser logins into the WSL host on a move (D1b-7f) A committed WSL move now copies each in-app browser profile's cookies once into the WSL host's stable route partition (owner decision 3a), merging without overwriting what the host jar holds and never touching the source. Where that is infeasible (no deployment link so no stable partition, the destination is not a WSL host or is gone, or the partition name is held by another identity) the host starts fresh and the move journal records why (3b). Registered as the ledgered browser-cookies rewrite store; it runs only once browser sessions and an app window exist. WSL_MOVE_DESKTOP_REWRITE_REGISTRY_COMPLETE stays false. * feat(wsl-mover): retain moved source rows, reconcile them on start, and plan delta moves (D1b-8) * fix(wsl-mover): keep the retained mark out of the WSL move manifest (D1b-8) * feat(wsl-mover): the move driver runs a WSL move end to end, with production gate facts and journaled restore folders One entry point (and preview/start/cancel/listUnfinished IPC for D1b-9) plans the move, gates terminals on the hook server's agent status, the close-tab process probe, running automation runs and live dispatches, pauses and proves exit, stages, sends blobs, commits only from blobs-transferred (#29825), and finishes on the desktop. Any failure resets to zero or goes forward when the host committed. Restore folders and the automations to turn back on are kept in the journal; the host turns those automations back on after commit, retried until it confirms. A real-PTY test pauses daemon shells, and runs on a real distro in the WSL orcad lane. * feat(wsl-mover): move dialog with preview, blockers, progress and result behind the internal WSL hosts gate (D1b-9) * fix(wsl-mover): move dialog hides instead of blocking, follows runs after a reload, and lets a start settle an unfinished move (D1b-9 review) * fix(wsl-mover): word an unfinished earlier move as still finishing (D1b-9) * test(wsl-mover): type the e2e's fake move state instead of reading it through Reflect (D1b-9) * WIP(wsl-mover): 7f-2 registry complete, coverage proof, startup re-apply (D1b-7f-2) * test(wsl-mover): registry-complete lifecycle, stale-focus restart, unload re-apply (D1b-7f-2) * fix(wsl-mover): share the session focus write so the re-apply adds no layout writer (D1b-7f-2) * fix(wsl-mover): redo additive rewrites once at a stale window's unload; behavioural coverage proof (D1b-7f-2 review) * test(wsl-mover): the IPC record test now finishes the rewrite with the registry complete (D1b-7f-2) * fix(wsl-mover): fence worktree-less spawns by cwd and re-prove terminal exit before commit (R46, WIP) * test(wsl-mover): pin the commit re-proof, browser jar identity and repeated move generations (R45, R46, R47) * fix(wsl-mover): fence any spawn by its folder and name the re-proof's reason (R46 review) * fix(wsl-mover): a terminal in a known folder outside the move never blocks it (R46 follow-up) * test(wsl-mover): kill the real move driver at every point against a real host store; abort a reset move's leftover stage on reconnect Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): carry unsaved drafts into the moved project; round-trip every fixture through the real export, driver and host import Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): reset a move waiting on a distro that is proven unregistered; test updates mid-move (R41), lost distros (R38) and two desktops (R39) Co-Authored-By: Claude <noreply@anthropic.com> * test(wsl-mover): list the D1b-10 real-SQLite mover tests Co-Authored-By: Claude <noreply@anthropic.com> * test(wsl-mover): type the fault test's journal hook without a cast Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): reset for a lost distro even when its kept host fails to connect, never for a renamed one; compare filled-in repo keys only where the source lacked them Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): carry markdown frontmatter visibility and closed-terminal-tab tombstones into the moved project Co-Authored-By: Claude <noreply@anthropic.com> * test(wsl-mover): read the persisted stage through a typed record, not Reflect Co-Authored-By: Claude <noreply@anthropic.com> * feat(telemetry): report how WSL moves end, by phase and reason code (R43) Co-Authored-By: Claude <noreply@anthropic.com> * fix(telemetry): report a pause refusal's reason, an outcome for a thrown run, and only real transport errors as unreachable Co-Authored-By: Claude <noreply@anthropic.com> * fix(agent-hooks): a WSL host's orcad never removes the hook entries the WSL bridge shares (R42) Co-Authored-By: Claude <noreply@anthropic.com> * fix(agent-hooks): a WSL host's Codex account-home launch with hooks off skips too; mark the R42 guard to drop with the bridge Co-Authored-By: Claude <noreply@anthropic.com> * feat(wsl-mover): "Use on this computer again" brings a moved project back as it was before the move Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): judge a bridge WSL pane's foreground inside its distro On Windows every live bridge pane's own process is wsl.exe, so the busy-terminal gate read every open WSL terminal as running a program and refused the move. Read the pane's terminal foreground process group inside the distro (processes carry ORCA_PANE_KEY): only shells means idle, anything else blocks, and an unreadable guest stays unverifiable. Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): only the selected projects' session rows can refuse a WSL move The session eligibility check treated host local's whole partition as the move's, as the SSH conversion does. So an agent session or unsaved draft in any other project on this desktop, or in a project an earlier move retained, refused every later WSL move from that distro. Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): sign the manifest as the journal and the host read it The digest was computed over in-memory rows. A value with toJSON (a Date on a row added this session) canonicalized to {} when signing but to its string once written to the journal or sent to the host, so the first move after adding a project reset with orcad_migration_manifest_digest_mismatch until a restart reloaded the row. Normalize through JSON before signing. Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): carry a slept pane's scrollback from its daemon checkpoint The move sleeps every pane first, and a slept pane's history lives only in the daemon's checkpoint, never in a renderer snapshot. The export carried renderer snapshots only, so moved terminals opened empty. After Sleep the driver reads each paused pane's checkpoint (as cold restore would replay it) and the export carries it under the pane's own snapshot ref; the snapshot channel serves those bytes, checked against the signed hash. SSH conversions pass no reader and are unchanged. Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): say why when a move can't be prepared, instead of a bare reset An export or journal failure after the pause (a digest mismatch, on awin) was rethrown and shown as "everything was put back" with no reason. Nothing is journaled yet at that point, so refuse with the error named instead. Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): retry a renderer store main refused to record The renderer applied a store and wrote its marker, but ignored a refused ledger record (gated-off, failed, not-main-window), so a committed move stayed unfinished and refused every later move of the distro until the next app start. Log the reason and retry with backoff until it lands. Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): a WSL pane is idle only when its shell has nothing else Review of #32343: reading only the terminal's foreground group let background jobs, nohup and disowned work, setsid daemons and a script waiting at read pass as idle, and the move's Sleep would end them. Scan the pane shell's subtree, its session and every process carrying its key; any non-shell process, or a shell running a script, blocks. Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): never leave behind an agent whose key may be the selected project Review of #32343: scoping the session check to the selected projects let an unqualified key for a repo id another host also registers fall out of both the transfer and the refusal. Such a key now refuses. Adds tests that fail on the old code: another project's live agent with its tab open and its draft don't refuse, the same kinds of state in the selected project still do. Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): refuse an unreadable slept checkpoint, prefer it, and spool it to disk Review of #32343: - A checkpoint behind an unreadable log (or an unreadable one) refuses with the pane named instead of carrying stale history. - For a pane the move just slept the checkpoint is the newest copy, so it wins over an older renderer buffer or snapshot. - Buffers spool to a per-move folder and only their hashes and sizes stay in memory; the snapshot channel reads them by offset. The folder is removed whatever the outcome. - A journal write that landed before it threw is reset, so no orphan record blocks the next move. awin's checkpoints were 310-615 KB, well inside the 5 MB per-pane cap, so nothing there is trimmed. Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): retry a failed listing, never a record another window was refused Review of #32343: not-main-window can't clear by waiting, while a listing failure is transient. Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): sign the manifest as the host parses it The likelier cause of awin's digest mismatch: the signature covered the exported objects, but the manifest parser keeps only the fields it knows, so a session field it drops (one a sleep can write) left the journal and the host hashing something else. Sign the parsed form, and warn when the parser dropped anything, since such a field does not move. Co-Authored-By: Claude <noreply@anthropic.com> * chore(wsl-mover): split the journal step out of the driver, and format The review fixes took wsl-move-driver.ts past the line limit; the export-and-journal step moves to its own module unchanged. Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-mover): a slept pane passes the busy check; say what each move dropped or lacked Re-run on awin ( |
||
|
|
8d908764dc |
Revert "Keep same-machine folders with matching Git remotes in separate projects (#32272)" (#34662)
* Revert "Keep same-machine folders with matching Git remotes in separate projects (#32272)"
This reverts commit
|
||
|
|
917ef9c737 | feat(browser): install Chrome extensions from the Web Store into Orca's browser (#30940) | ||
|
|
f57d00f045 | refactor: group shared native-chat upgrade-tip audience (#34509) | ||
|
|
9802866ed5 |
fix(editor): Copy Remote URL links to the code the workspace is on, with the selected line range (#33597)
* fix(editor): Copy Remote URL links to the code the workspace is on, with the selected line range The gutter menu's Copy Remote URL always built the link on the default branch and dropped any multi-line selection. Prefer the HEAD commit when origin already has it, then the origin branch the current branch tracks, then the default branch; carry an optional end line through IPC, RPC and the git provider so a selection becomes a line range. * fix: pair remote file links with published repository refs * fix: prepare exact remote file fallback before publication scan * test: consolidate remote file URL integration coverage * test: document real-clock cancellation deadline proof * test: handle optional cancellation signal in assertion * test: reuse spawned child fixture across runtimes --------- Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> |
||
|
|
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> |
||
|
|
a7c9d19048 |
fix(file-explorer): offer permanent delete when moving to Trash fails (#33956)
Offer confirmed permanent deletion when moving an item to Trash fails. Preserve authorization and workspace ownership checks, cancellation behavior, text-snapshot undo, remote compatibility, and all supported translations. Fixes #33944 Co-authored-by: nori <dosukoicrypto@gmail.com> Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> |
||
|
|
362104ca18 |
fix(wsl): background Git and the roots catalog never start a stopped WSL distro (E9) (#34231)
* fix(wsl): background Git and the roots catalog never start a stopped WSL distro git status ran on the UNC project root 0.45 s after a terminate, next to the explorer read; either boots the distro. Background Git (status, conflict operation, upstream status, branch compare, the upstream-ref watch) now asks the shared running gate first and refuses for a stopped distro, including host paths whose Git runs through wsl.exe. The authorized-roots rebuild skips a stopped distro's repo and leaves it dirty, and the detected-worktree scan fails as unavailable, so rows are kept and the next scan after the distro runs lists it. * fix(wsl): the active workspace's first status and a wake read's roots rebuild may start WSL - Drive-path projects whose Git runs through WSL had no wake path: the active workspace's first git:status after it becomes active now passes wakeWslDistro, so Source Control starts the distro; later polls stay gated. - A user act runs in an async scope naming its distro; gated work inside it (the authorized-roots rebuild an authorization miss triggers, the detected scan, the Git) may start that distro and no other. External worktrees on a stopped distro no longer fail a wake read with access denied. - After a user act wakes a distro, background reads stop trusting the older 'stopped' read and probe again. * fix(wsl): explicit WSL launches refresh the running read; wake only on tab change; gate the home probe - Any wsl.exe Git/CLI run (commit, push, fetch) or WSL terminal spawn for a distro last read as stopped records that it started, so background reads probe again instead of refusing for up to 60 s. - The active editor tab wakes only when the active tab changes; effect re-runs driven by git status or overview views read without waking. - The authorization roots' WSL home probe no longer runs wsl.exe in a stopped distro when the home is uncached. - The settle window no longer imports the orcad liveness module (it pulled main code into the web typecheck); a test pins it to EXIT_SETTLE_MS. * fix(wsl): deferred work and running-list listeners never inherit a user act A user act's async scope could leak into work it triggers indirectly: a drain of deferred tasks it caused, or listeners of a running-list probe started inside it. Both now run outside the scope, so only the act's own work may start its distro. * fix(wsl): keep shared modules free of main-only gate imports worktree-logic.ts and wsl-running-distro-cache.ts are also compiled by the web project, which cannot see main-only modules (AsyncLocalStorage, wsl.exe). getAllowedRoots now injects the gated home lookup into computeWorkspaceRootWithin, and the background gate's own cache subscriptions run outside the user-act scope instead of the cache knowing about it. |
||
|
|
fe82078909 |
fix(wsl): background file reads and watches never start a stopped WSL distro (E9) (#34222)
* fix(wsl): background file reads and watches never start a stopped WSL distro Any Windows touch of a \\wsl.localhost path boots a stopped distro. After a terminate, the dying explorer watcher's overflow refresh ran realpath on the project root 0.23 s later and booted the distro again. Background reads, stats and watch installs now ask a fresh running list first (shared, with a 5 s lease and a stop signal from the watcher exit and the hook relay link) and refuse when the distro is stopped. Opening the workspace and Retry still start it. A stopped watch waits for the distro and resyncs the explorer when it runs again. * fix(wsl): trust a confirmed running read for 60 s without a stop signal * fix(wsl): user acts wake; unverifiable is not stopped; settle after a stop - Opening a workspace, expanding a folder, opening a path (explorer, quick-open, links), the active editor tab's load and every Retry pass wakeWslDistro on readDir, readFile, stat and readFileChunk. Background reloads, restored-tab scans and watchers stay gated. - A failed running-list read is 'unverifiable', not 'stopped': the gate re-reads once past the failure backoff (once per failure window) and otherwise refuses with 'WSL didn't answer', never touching the path. - After any stop signal, a running read that started within EXIT_SETTLE_MS of it never counts, in isWslDistroRunning itself, so neither the watcher's own overflow refresh nor the hook relay's restart check can read a stale listing. - A confirmed read that sees a distro stop records a stop signal, resetting the 60 s lease. * test: user-opened stats now carry the WSL wake flag |
||
|
|
e882d8eda7 |
fix(window): pump hidden-window frames from the renderer on Windows background launches (#34197)
* fix(window): repaint a never-shown background window on Windows so CDP screenshots return Windows composites nothing for an idle window that was never shown, so Page.captureScreenshot under ORCA_BACKGROUND_LAUNCH=1 waited forever once the status-bar usage chip stopped animating (#33799). * fix(window): pump hidden-window frames from the renderer on Windows background launches Main-process webContents.invalidate() did not make a never-shown Windows window produce a frame CDP can capture (verified on Windows 11). A one-frame root background flip from the preload does, so main stamps a preload flag for ORCA_BACKGROUND_LAUNCH=1 on win32 and tells the preload to stop on first show. * fix(window): stop the hidden-frame pump only on main's show signal, including after reloads A never-shown Windows window can report visible after a desktop change, so the preload no longer stops on visibilitychange; main re-sends the stop after any reload once the window has been shown. * fix(window): register the frame-pump stop with on('show') so every window double supports it createMainWindow suites simulate win32 under the runner's ORCA_BACKGROUND_LAUNCH=1, so they install the pump stop; their window doubles implement on() but not once(). |
||
|
|
284411d893 |
fix(wsl-host): uninstall and startup release WSL holders; a partial Remove keeps the host pending (#33843)
* fix(wsl-host): uninstall and startup release the WSL distro holders Orca left running The detached wsl.exe holder outlives the app, so an uninstall left its distro, orcad and shells running. The uninstaller now runs Orca with --orca-uninstall-release-wsl-holders after killing the app and its daemon; it ends only the holders this profile recorded, each verified by pid, start time and command line, and keeps any it cannot verify. At startup the WSL host service now releases holders whose distro is no longer a host (a failed add or remove), and every holder while WSL hosts are off; a closed gate releases them too. Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-host): a Remove that can't prove the server stopped keeps the host, pending A partial Remove dropped the host anyway, leaving a server whose live terminals block the next add's activation. Remove now drops the host only on a proven stop; otherwise it records a pending stop on the WSL record, keeps the host listed and says why (live or unverifiable). Remove again retries without ever booting a stopped distro (it says to start it); Connect or Add on the same distro keeps the host; a distro that is no longer registered finishes. Nothing reconnects a pending host on its own. Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-host): E11 review — keep holders when records are unreadable; finish removals a stopped or renamed distro proves - Startup keeps every holder when the WSL host records can't all be read (unverifiable), and no longer re-adopts a pending host's holder. - Remove matches a renamed distro by GUID (isWslDistroRegistered), and a stopped distro finishes a pending Remove: the cold probe proves the stop. - Only the user's Connect or Add withdraws a pending Remove; other connects are refused, and re-adding respects startIfStopped. - Settings' Remove carries the kept result, so it warns instead of 'Removed'. - A holder record without a start time is never killed on its command line alone, except the one this process just spawned. Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-host): E11 review 2 — a closed gate keeps live hosts' holders; stop a renamed distro by its current name - With the gate closed, a launch releases only orphan holders (no host record, or a pending Remove), under the same keep rule as startup; a user with no holder records costs one folder check, nothing else. - The keep rule re-reads host records per holder and keeps an Add in flight. - Remove resolves the distro's current name from its GUID and stops it there. - The uninstall command arms its exit timer first and exits 1 if setup throws; NSIS launches it only when a userData holder folder exists. Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-host): never boot a host whose Remove is pending at the next launch Early wake built its host list from every record, so a host focused when its Remove ended pending was booted at each launch, undoing the stop's proof. It now skips pending records, and Remove forgets the host's early wake whatever the outcome. Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-host): no wake for a pending host; the e2e fake stops an unbridged server like the real one - mayWake skips a host whose Remove is pending, so a due automation can't boot it (focus already couldn't). - The e2e fake connector read a host with no bridge as stopped. Since E9 a re-enable connects nothing, so Remove after off/on left the host's shells running. Like the real connector, it now reconnects the always-running fake distro to stop its server. - Status bookkeeping moves to WslHostStatusBoard, and the pending-host connect rule to admitConnectToPendingHost, to keep the service under max-lines. Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
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 |
||
|
|
6e3c10c835 |
Honor browser preferences and modifiers for HTML preview links (#33622)
* fix(browser): honor preview link destinations and modifiers * Clarify the source browser provider contract * test(browser): check preview guest before reporting modifiers * fix(browser): report system link failures and cover preview routes * test(browser): combine HTTP link destination imports * refactor(browser): require source ownership for preview links * test(browser): type the forbidden Active Server getter * fix(i18n): retain required preview error catalog entry |
||
|
|
2e67ba5a64 |
perf(wsl-host): start booting only the focused WSL host early at launch (E9, replaces #33141) (#33924)
* perf(wsl-host): start booting the distros the last run had open work on as the app launches The WSL host connect can only start once the store has loaded, about 1.5-2 s into startup on a slow PC, and its first command then waits for the distro to boot. The service now remembers which distros had open work, and the next launch starts booting just those right after taking the single-instance lock. * perf(wsl-host): wake only the focused WSL host early at launch (replaces #33141's list) open work on, which conflicts with E9 (a launch boots only the focused host). Each focus entry now records just that host's distro for the next launch's early boot, and focusing a workspace off WSL (reported as a null focus entry), turning WSL hosts off, or a host that can't run clears it. Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-host): the early-wake list is authoritative: deleted when off, forgotten on Remove Review of #33924: the early wake runs before settings load, so it can't read the WSL hosts setting. Turning WSL hosts off now deletes the list synchronously (emptying it if the delete fails; a missing or unreadable list wakes nothing), and removing a host drops it from the list. There is no pendingStop field on host records yet (E11); the existing registered-host filter covers removed records until then. Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
2dd8207369 |
fix(wsl-host): boot only the focused WSL host, and keep a stopped one down (E9 A) (#33838)
* fix(wsl-host): boot only the focused WSL host, and keep a stopped one down E9 connect policy, part 1. A stopped distro now boots only for an explicit user action or when its host becomes focused: - Visible work is the active workspace plus workspaces focused earlier in this window that still have tabs. Saved tabs alone no longer count, so a launch with two hosts boots only the focused one. - After a confirmed stop (wsl --shutdown, WSL update) the host is parked. Liveness no longer reboots it even when it is visible, and polls get "<distro> was stopped" instead of a boot. Re-focusing the host, Connect, or the distro running again lifts it. - Liveness recovery always needs a confirmed-running distro, so a distro that stops mid-recovery is never booted again. Co-Authored-By: Claude <noreply@anthropic.com> * test(wsl-host): launch boots one of two hosts; polls never boot; lost contact never parks Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-host): only a focus entry or a user action boots a WSL host (E9 review) Review of #33838: - Re-focus never lifted a park: a host focused earlier stayed in the visible set, and the renderer skips unchanged reports. The renderer now sends a separate focus entry (focusHost) each time the user switches to a workspace on a WSL host, including the launch restore; only that, or Connect, lifts a park and may boot. - Runtime calls could boot: ensureForRuntimeCall connected any visible, unparked host. It now reads the host's reachability first: a confirmed-stopped distro parks at once, an unreadable running list refuses, and only a distro confirmed running is reconnected (for visible work). Visible work itself never connects anything. - Turning WSL hosts on no longer boots every visible host, and focus isn't recorded while they're off; the window re-reports its focused host instead. - Each window's visible work is kept apart and unioned, so one window can't drop another's. - wakeForAutomation/isConnected move to the automation PR, which uses them. Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-host): a poll waits for liveness's verdict right after an exit (E9 re-review) Right after `wsl --shutdown` WSL can still list the stopping distro as running (the supervisor waits and re-reads for exactly this). A poll's cold probe then read 'unreachable', reconnected, superseded the pending distro-stopped verdict and booted the distro again. The supervisor now reports when it is settling (a verdict in progress, or a watch/holder exit within the last few seconds), and a runtime call refuses instead of reconnecting then; the verdict parks the host as before. Co-Authored-By: Claude <noreply@anthropic.com> * test(wsl-host): a new supervised entry starts with no recorded exit Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
0afedab10d |
fix(lifecycle): keep UI listener failures from vetoing the shutdown checkpoint (#21029)
A throwing ui-changed listener (e.g. webContents.send on a destroyed secondary window) propagated out of store.updateUI() during app:stage-before-unload-sync and cancelled the shutdown checkpoint, leaving the user unable to quit. notifyUIChanged now isolates each listener, the ui:stateChanged broadcast skips destroyed webContents, and the staging failure cause is returned to preload so the error toast names it. Fixes #20897 Co-authored-by: Neil <neil@stably.ai> |
||
|
|
a93f73c032 |
fix(terminal): skip an escape tail an abandoned hidden-output restore would print (#33905)
* fix(terminal): skip an escape tail an abandoned hidden-output restore would print (#33766) Main drops a hidden pane's renderer delivery after its model ingests the bytes, so the first chunk sent on reveal can begin inside an escape whose start was dropped. When the restore is abandoned, the renderer resets its parser and writes the queued chunks, and xterm printed the tail (';242m', the rest of a Codex OSC title). Main tracks each PTY's escape state over every accepted payload and labels the first delivery after a hidden or pending-cap drop with the escape it resumes inside (gapEscapeState). Only the abandon path strips that continuation; a successful restore keeps every byte so the snapshot's pending escape tail can complete. No label means no change. * fix(terminal): make the escape-continuation scan's switch exhaustive (#33766) |
||
|
|
c9eee6b54c |
fix(runtime-environments): every window sees a server saved from the CLI (#33930)
`orca environment add` writes the saved-server file directly. Main already watched that file but only repaired the Active Server preference, so every renderer surface listing saved servers (the Agent Session History host picker, host menus, the status bar) kept the old list until something else refreshed it. Main now tells every window when the file changes, and the renderer refreshes through the existing coalesced catalog refresher. Co-authored-by: Tian-yi Liang <tianyilt@qq.com> |
||
|
|
a66f6bf011 |
fix(agent-resume): keep a background agent launch's flags when it is resumed (#33776)
* fix(agent-resume): record a background agent launch's recipe so resume keeps its flags * test: narrow the reveal's notifier so the test needs no cast * refactor(agent-resume): one recipe registration path; skip adopted panes * test: add the launch-recipe listener to the remaining window mocks |
||
|
|
bfc633af8f |
Offer to resume chats after managed server updates (#28978)
* Guard managed server restarts with host work reservations * Protect legacy server update requests with host admission * Reserve chat-safe restarts in SSH and WSL server updates * Keep activation host fixtures within the module line limit * fix(orcad): preserve session queue timing during admission * Explain chat-safe update deferrals and superseded restarts * Clarify managed server Force upgrades and retry instructions * Separate chat entry delegates from conversation creation * Report child work through main's child evidence in the restart drain test * Drive main's snapshot-room tests through the restart reservation Main's room tests deployed over a serving incumbent with a census that has no chat work count and no restart admission, so the update deferred before the room probe ran. Give them the same idle census and slot admission as the other activation tests, and pin the probe before the reservation instead of before the recount it replaced. * fix(native-chat): an update keeps waiting on a chat start after its conversation is closed The restart check counted a start only while its conversation stayed open, so an idle close during a stalled start let a managed update through. Every tracked attach, create, start and open now counts as restart work in the same tracker that counts the session queue. * fix(native-chat): keep the structured session view within its line limit once formatted Main's copy sat at 400 lines only because one line was left unformatted; the merge's formatter pushed it to 401. Inlining the one-use question list keeps it at 400 with identical behavior. * fix(orcad): a recovery stop request stops the server; only an older client's empty request waits for idle Stopping a slot and restarting it for an older client's update were both an empty .orcad-stop-request file, so routing that file through restart admission let a crash recovery, stranded-setup release or rejected-candidate rollback leave the server running. New clients now write "stop-now" into the request (renamed in whole), which stops at once as before; an empty or unrecognized request takes the chat-safe restart, and a deferred restart logs why. Also gives the restart admission activation fixtures the now-required recount. * docs(orcad): say a directory at the stop-request path is refused, not restarted * docs(orcad): the plain stop request's comment states both of its meanings * style: format the restart admission files for the format check * test(wsl): count the incumbent's recount bridge after the reservation's * fix(orcad): a Windows stop request retries its rename while antivirus holds the new file Renaming the just-written stop-now request can briefly fail with EPERM, EACCES or EBUSY on Windows; the stop now retries those with the same bounded delays as record-publish instead of answering SIGNAL_FAILED and leaving the server up. * test(orcad): a real Windows host stops on the slot's stop-now request and relaunches * test(orcad): recovery stops a real server whose restart admission refuses * test(orcad): the recovery-stop cell tunnels over the cell's SSH connection * test(orcad): the recovery-stop cell names itself in the CI log * fix(settings): a deferred WSL update shows its full reason below the row * test(orcad): fixtures pass releaseIncumbentAdmission; the census test calls its own method * test(orcad): the capable-server census in the fence test reports idle chat work * Record server chat restart offers and desktop creation history * Offer interrupted chat recovery per managed runtime * Ship the remote chat resume action labels in the runtime catalog * Update removal contracts for desktop chat history cleanup * Scope remote chat recovery to each server occurrence * Preserve recovery choices and uncertain continuation outcomes * fix: preserve uncertain restart action outcomes * Fix restart recovery CI imports and fixtures * test: align resume assertions with unconfirmed outcomes * test: bound restart recovery work across scaled populations * fix(native-chat): title the remote resume dialog with the restart The dialog can appear out of nowhere when another desktop updates a shared server, so its title now says what happened: "<machine> restarted". |
||
|
|
1b0e56e385 | feat(browser): make Orca shortcuts, split focus and mouse back/forward work inside pages (#31859) | ||
|
|
eb499478da | feat(browser): show agent browsing live, with a jump to the page from chat (#33075) | ||
|
|
883b768bc7 |
A chat never starts writing a conversation a terminal is still writing, and restored panes respect open chats (#30930)
* fix(native-chat): one ownership index with link roles, and a chat refuses to start while a terminal writes its conversation Each chat link now carries its role (head or earlier) and key; Session History names the chat continuing a conversation first, duplicate adoption checks only head links in both the pre-commit check and the store transaction, and terminal resumes stay refused exactly as before. The terminal-writer check now also runs inside acquireOwner before the spawn, refusing with the typed pre-spawn reason conversationOpenInTerminal. * fix(native-chat): hold a terminal start Orca issues until its terminal reports it An in-memory registry of managed terminal starts per conversation, registered in the same step as the resume admission (terminal.send with a resume command, createTerminal with a command), bound to the PTY execution that runs it, and ended only when that terminal's hooks report the conversation or the execution is gone. A chat's agent start refuses while an entry may hold its conversation. * fix(terminal): an automatic pane restore never resumes a conversation an open chat continues Resume recipes built from a pane's saved facts (cold restore, deferred and late reattach, sleeping wake, host mobile materialization) carry resumeOrigin 'saved'. The execution host decides before any command is issued: while an open chat continues the conversation, or a chat may be writing it, the pane starts its plain shell with the started-fresh notice and its saved claim is forgotten; with unreadable records only a saved restore is refused and its record kept. An admitted resume registers its managed start in the same step, so the chat's agent start refuses until the terminal reports it or exits. Clearing the last saved record now reaches disk. * Fix saved terminal resume ownership and effective launch results * Preserve conversation case and clear refused cold restore identity * fix: publish effective terminal launch results on attachment * fix: preserve terminal launch callback and candidate ownership * fix: keep existing terminal attachments observational * fix: consolidate terminal launch imports * test: document snapshot runtime fixture boundary * fix: preserve terminal launch identity types * fix: accept reattach payload policy sessions * fix: preserve terminal result validation contracts * refactor: separate terminal create contract * test: document partial terminal runtime fixtures * test: align sleeping resume store fixture * Fix terminal create type contracts * fix: return the terminal main started to its waiting view * fix: register reattached terminals before publishing their handles * Check unavailable-resume test fixture types * Complete sidebar resume test store fixture * test: bound saved resume ownership and refusal work * Settle refused saved resume claims from actual launch results * Fix saved resume test type contracts * test(e2e): capture exact terminal parking diagnostics * test: verify parked terminal with fresh host inventory * Consolidate agent session imports in remote terminal transport * Clarify terminal conversation refusal guidance * Admit note-only saved conversations without hiding live writers * Retain terminal writer proofs through final admission |
||
|
|
82a3214049 |
fix(sleep): reopen a slept agent whose tab is gone in a fresh tab instead of stranding it (#33598)
A slept agent whose tab disappeared now resumes in a fresh tab (with --resume, through the existing duplicate/host guards) when its workspace opens, and main's stranded workspace-sleep record is then dropped (only if no tab still lists that pane), instead of the record sitting forever while the workspace opens a bare shell. Fixes #22657 |
||
|
|
9485e73207 | feat(browser): dock DevTools in the browser pane, with dock side, resizing and pop-out (#33003) | ||
|
|
0b28553093 |
feat(ssh): show saved port forwards that couldn't start, with why, and let you remove them (#33450)
* feat(ssh): list saved port forwards that couldn't start, with why, and let you remove them (#32484) A saved forward whose local port is taken, or that keeps failing, stayed saved but invisible, retried in the background with no way to remove it. The port-forward lists now show each saved forward that isn't open, with the last start error, and Remove deletes it by its mapping. * fix(ssh): a forward whose ssh exits after starting backs off like a failed start * fix(ssh): re-register the new forward channels, close a forward a restore reopened before removing it, and update IPC fixtures * fix(ssh): a flapping forward keeps its backoff streak until it stays up * fix(ssh): translate the saved-forward row, say Stopped for a forward that died, toast a failed remove, and reset backoff on manual edits * fix(ssh): keep saved forwards listed and removable while the host is offline; label the remove button; test the healthy-uptime reset * fix(ssh): mirror saved forwards from main with a stale-read guard, including hosts that never connect * fix(ssh): scroll the offline ports panel when saved forwards overflow it * test(e2e): give the saved-forward restart case's timeout its reason |
||
|
|
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> |
||
|
|
25b9ce5168 | feat(browser): show a hovered or focused link's URL in a bubble at the bottom of the page (#32978) | ||
|
|
76f0f35bad | feat(browser): speaker icon on tabs playing sound, with tab mute (#32981) | ||
|
|
b900d9843f | refactor(shared): colocate Jira rules and direct imports (#33164) | ||
|
|
785daec1e1 | fix(browser): show profiles changed outside the window in the profile menu without a reload (#32723) | ||
|
|
5dc197e5ec | feat(browser): history controls: Chrome-style Escape, removable suggestions, history view (#31846) | ||
|
|
7cafdb072b |
feat(ssh): Recover server for a managed host refused on a stale lock, and surface that refusal in seconds (#32951)
* feat(orcad): run --reclaim-stale-lock on a managed host's active slot The desktop can now dry-run and confirm the stale instance-lock recovery on a Linux managed host, serialized with launches, then start the server again and reconnect the way the restart action does. Co-authored-by: Jesse Sanford <108698+jessesanford@users.noreply.github.com> * feat(settings): offer Recover server for a managed host refused on a stale lock When a managed orcad start names --reclaim-stale-lock, the SSH host row offers Recover server. The dialog dry-runs the check, shows the host's evidence, and clears the lock only after the user confirms no other machine sharing the home runs Orca. Co-authored-by: Jesse Sanford <108698+jessesanford@users.noreply.github.com> * feat(mobile): point a host refused on a stale lock to the desktop's Recover server Co-authored-by: Jesse Sanford <108698+jessesanford@users.noreply.github.com> * fix(settings): mount the Recover server dialog per opening A fresh mount starts each opening from a new check instead of resetting state in an effect. Co-authored-by: Jesse Sanford <108698+jessesanford@users.noreply.github.com> * fix(orcad): end the readiness wait once the host proves the launch exited A managed orcad refused at start (such as on a possibly stale instance lock) left the client waiting out the full readiness deadline. Each host-side wait now also checks the launch's PID file with kill -0 and ends early on a proven exit, so the caller reports the same pending readiness, with the orcad.log tail, within a poll. No PID, a denied probe or a reused PID keeps the old deadline. Co-authored-by: Jesse Sanford <108698+jessesanford@users.noreply.github.com> * fix(orcad): refuse a managed slot without --reclaim-stale-lock before running it An older orcad ignores the flag and starts serving in the foreground. The same remote exec now checks that the slot's server bundle names the flag and answers unsupported otherwise, without invoking orcad. Co-authored-by: Jesse Sanford <108698+jessesanford@users.noreply.github.com> * fix(settings): show the manual stale-lock command as literal mono text The rendered dialog ran the command into the sentence, so it was hard to read or copy. It now sits in its own mono block, like Details. Co-authored-by: Jesse Sanford <108698+jessesanford@users.noreply.github.com> * fix(settings): offer only a manual delete when the host can't reclaim, and format the lock's age An unsupported host was told to run the very command it lacks. Main now names the lock path for that case, and the dialog shows only a copyable rm of it with the shared-home caution. The lock's age uses the UI's relative-time formatter instead of a hand-rolled minutes count. Co-authored-by: Jesse Sanford <108698+jessesanford@users.noreply.github.com> * fix(orcad): pin a confirmed stale-lock reclaim to the record the user approved --yes reclaimed whatever record held the lock at that moment, so a lock a same-named machine wrote while the dialog sat open could be cleared. orcad now takes --expect-nonce and refuses unless the lock still holds it; the dry run reports the nonce, the desktop sends it back on confirm, and the managed slot gate requires a build that knows the pin. A reclaimed result carries the evidence it acted on. Co-authored-by: Jesse Sanford <108698+jessesanford@users.noreply.github.com> * fix(settings): keep the Recover server dialog open through its own reclaim The dialog's mount was gated on the status that offered it, and the reclaim clears that note before its answer arrives, so the result was never shown and the card kept the dialog marked open. Only the triggers are gated now; an open dialog keeps the server it opened for until the user closes it. Co-authored-by: Jesse Sanford <108698+jessesanford@users.noreply.github.com> * fix(settings): put the Recover server confirmation on the security surface It asks permission to run a remote command that clears an ownership lock and starts server code, which STYLEGUIDE puts on that surface. Co-authored-by: Jesse Sanford <108698+jessesanford@users.noreply.github.com> * fix(orcad): trust a gone launch PID only on the machine that launched it The PID file sits in a home other login nodes may share, so a wait exec that lands on another node read a starting server as exited. Both launch paths now record the launching machine's boot id and node name beside the PID, and the readiness wait ends early only when its own exec reads the same record. No record, a host without a boot id, or another machine keeps the deadline. The PID path is named once in the launch command so it stays within its sent-byte ceiling. Co-authored-by: Jesse Sanford <108698+jessesanford@users.noreply.github.com> * fix(orcad): keep a slot's unreadable stale-lock answer from offering a manual delete A slot that passed the gate but gave no JSON, or a status this client does not know, read as unsupported and offered rm of the lock. It now reads as no-answer, which points to the slot's own reclaim command, and unsupported is left to a slot without the command, a non-Linux host or no active version. Co-authored-by: Jesse Sanford <108698+jessesanford@users.noreply.github.com> * style(settings): use the text-2xs step for the stale-lock command block Co-authored-by: Jesse Sanford <108698+jessesanford@users.noreply.github.com> * fix(mobile): offer the desktop-recovery hint on the same refusal the desktop does Co-authored-by: Jesse Sanford <108698+jessesanford@users.noreply.github.com> * test(orcad): name the extra fields a fake stale-lock answer carries Co-authored-by: Jesse Sanford <108698+jessesanford@users.noreply.github.com> * fix(settings): end the Recover server flow once the lock is cleared, and keep an unpinned reclaim manual After a reclaim whose restart failed, the dialog kept the old evidence, the enabled confirmation and manual recovery for a lock that was gone. It now shows only that the lock was cleared and why the server did not start, with Close. A slot that has the reclaim but not the nonce pin is now told apart from one without the reclaim, and is pointed to its own reclaim command rather than rm. Co-authored-by: Jesse Sanford <108698+jessesanford@users.noreply.github.com> * fix(orcad): keep a stale-lock reclaim's result when the restart after it throws A wake or tunnel rebuild that threw after the lock was cleared discarded the reclaimed result, so the caller skipped its reconnect and note clearing and the dialog kept a confirmation for a lock that was gone. The restart's failure now becomes the result's notRestarted reason. Co-authored-by: Jesse Sanford <108698+jessesanford@users.noreply.github.com> * fix(orcad): report a reclaimed server as started when only its forward failed to follow A tunnel rebuild that failed after the wake started the server was reported as the server not starting. The rebuild now goes through followLaunchedServerPort, as other relaunches do, which warns and leaves the forward to the next connect. Also drops a caller test that only covered behaviour the fix did not change. Co-authored-by: Jesse Sanford <108698+jessesanford@users.noreply.github.com> * test(mobile): re-record the execution-target goldens for the recovery hint field The SSH gate's projected state gained `needsDesktopServerRecovery`, which is false for every recorded reply (no recorded host sends a managed server refusal). Re-recorded with `pnpm --dir mobile rpc:record` for the two pilot recordings and the four execution-target reply partitions; the only change is that field, plus the value pool reordering around it. Co-authored-by: Jesse Sanford <108698+jessesanford@users.noreply.github.com> --------- Co-authored-by: Jesse Sanford <108698+jessesanford@users.noreply.github.com> |
||
|
|
861299e6cc |
refactor(ipc): remove unreachable runtime-environment provisioning and control-retry IPC (#32960)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
f5f7f172a8 |
chore(ipc): remove unreachable hooks:createIssueCommandRunner IPC (#32953)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
02d7214c1a |
refactor: remove four unreachable preload IPC bridges (#32950)
* refactor(repos): remove unreachable repos:getGitUsername IPC * refactor(mobile): remove unreachable mobile:isWebSocketReady IPC * refactor(skills): remove unreachable skills:deletePackageVersion IPC * refactor(space): remove unreachable workspaceSpace:closeWindow IPC * chore: prune repo-host-read baseline for removed git username handler --------- Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> |
||
|
|
cdba9a7703 |
refactor(dashboard): remove unreachable popout spawn/sleep IPC (#32954)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> |
||
|
|
da620ad632 |
refactor(rate-limits): remove unreachable setPollingInterval and refreshMiniMax IPC (#32945)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> |
||
|
|
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> |
||
|
|
cd59239927 |
fix(workspaces): add main-owned project move pause barrier (#32940)
* fix(workspaces): add main-owned project move pause barrier * test(workspaces): type project move pause reply fixtures |
||
|
|
2351c6de3f |
test: remove copied inventory and strengthen CLI, preload, and Cloud boundaries (#32982)
* test: isolate lock refusal and verify trust probe diagnostics * test: exercise preload close wiring and clarify reserve assertions * test: remove Jira inventory and exercise CLI launch routing --------- Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> |
||
|
|
1cc2a2afd8 | refactor(shared): group remote runtime shared-control lifecycle (#32977) |