Repository navigation
Conversation
… identity mismatches (stablyai#23551) When an imported or cloned folder's derived project id does not match the selected project, the error now names the id the folder resolves to (for example github:owner/repo) instead of a generic mismatch message. Host-local ids and identical ids keep the generic message. The setup-existing-folder help notes which ids --project accepts. Fixes stablyai#23528 Co-authored-by: Neil <neil@stably.ai>
…ocused terminal (stablyai#34037) Closing the Agent Dashboard drawer or workspace board with Escape still forwarded the key to a focused xterm, because xterm ignores defaultPrevented. Stop propagation only when the target is the xterm helper textarea so other fields keep their own Escape handling.
…tablyai#34035) sanitizeWorkspaceStatusLabel cut labels with slice(0, 32), which could keep only the high surrogate of an emoji straddling the limit and render U+FFFD. Use the existing surrogate-safe sliceAtCodeUnitLimit helper instead.
…; machines list the sources they accept (stablyai#33862) A connector conversation now names its source (slack, discord or linear), and a posted reply reports a neutral messageId. Each machine's hello lists the sources it accepts, and the cloud only routes a Slack conversation to machines that list Slack. Machine events from other sources are filtered out where they arrive, and a reply for a non-Slack conversation is refused, so a Discord or Linear conversation can never post into a Slack thread with the same id. The unused turn-bound cancel fields are removed (they return with Stop). Inert: no shipped desktop uses the contract, and Slack is off unless configured.
…ses (stablyai#33961) A host whose move to its Orca server was refused over saved state (an enabled SSH automation and its runs, stale workspace details, unsupported saved tabs) stayed in error on every Connect. Move anyway, which connects it and leaves those items on this computer, was only in the card's overflow menu, so the host looked stuck. The card now offers Move anyway next to its refusal, as it already does for Recover server. Refs stablyai#29083.
…blyai#33852) With the experimentalConnectors setting on and the desktop signed in to Orca, the desktop keeps one long-poll request open to the Orca Cloud connector and hands each delivery to the existing connector code that starts or talks to an agent. Each delivery is confirmed twice (received, then its result), and the agent's turn and prompt events are reported back. The desktop authenticates with a 5-minute connector token from the Orca sign-in service, follows the relay's start/stop lifecycle, and stops on sign-out. Its hello lists Slack as the one source it accepts. Off by default with no settings UI.
…yai#33990) * fix(ssh): say why SSH failed when Connect never reaches the host When the SSH session itself could not open (key rejected, port refused, host not answering, host key not trusted), Connect on a host Orca had not set up yet said "Orca couldn't start its server on this host" and offered a plain SSH terminal that could not work either. Errors from opening the SSH session are now marked where they are dialed, and a setup that fails on one ends the connect with SSH's own reason. A held move keeps its status. The connect-failure toast also drops Electron's IPC prefix. * fix(ssh): lead an SSH connect failure with what to do about it stablyai#33928 shows SSH's own reason when Connect never reaches the host. Raw reasons like "connect ECONNREFUSED 10.0.0.1:22" or "Timed out while waiting for SSH authentication" still leave users guessing. A failure from opening the SSH session is now published with a next step for the kinds users can act on (host key mismatch, rejected sign-in, refused port, unknown host name, no route, timeout), and SSH's words follow in parentheses. The connect-failure toast reads the same published text.
…in zh/ja/ko/fr (stablyai#33561) Replace mistranslated subagent summaries ("kicked off" rendered as "fired"/ "kicked out", untranslated "Ran") and add missing measure words to the zh tool-run clauses. Leading tool-run clauses are now joined with a translated runListSeparator so CJK locales use 、 instead of an English comma. Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com>
…yai#16413) The Team, Lead, Members and Labels popovers in the Linear new-project dialog are portaled outside the dialog, so its scroll-lock cancelled native wheel input over their inner max-h-64 lists. Opt their PopoverContent into the shared wheel shim via wheelScroll, and move the p-1 padding onto the children so the layout is unchanged. Fixes stablyai#16412 Co-authored-by: Neil <neil@stably.ai>
…ai#33889) Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
…(E9 C) (stablyai#33840) * fix(forge): skip PR refreshes for a WSL host that is off, and say so E9 connect policy, part 3. PR status for a workspace on a WSL host is fetched through the host, and a poll never boots it. While the host isn't ready, the visible-row refresh skips it (the row keeps its last badge and the existing "host disconnected" mark), a direct PR refresh keeps the last answer and records a 'host-off' skip, and the Checks panel says the host is off and to reconnect it. The cached-field half of the refresh candidate moves to its own helper to keep the lookup file in bounds. Co-Authored-By: Claude <noreply@anthropic.com> * test(forge): a WSL host that goes off keeps its last PR badge and records host-off Co-Authored-By: Claude <noreply@anthropic.com> * fix(forge): only a stopped or closed WSL host is "off"; mark row badges as last known (E9 review) Review of stablyai#33840: - Connecting, reconnecting and unverifiable hosts were treated as off. Only a confirmed-stopped (or parked) host, or one closed with WSL hosts turned off, is off now; anything else lets the call proceed or fail as usual. A status change re-runs the visible refresh, so rows refresh as soon as the host turns ready. - Row badges now carry the stale mark too: the card's review status gets the hover card's last-known treatment and "Last known status" in its label, and the hover card's reference rows are stale and not fetched while the host is off. Co-Authored-By: Claude <noreply@anthropic.com> * test(forge): build the host-off PR refresh test on the shared GitHub slice harness Drops the copied store and seed casts. Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
… session (stablyai#34048) OMP's ACP session advertises commands it handles itself (e.g. /fast), but native chat claimed them as host-only TUI commands and refused them as unavailable. Commands the running session reports in its slash menu are now left unclaimed so they send through, on desktop and mobile. Mobile reads the session command list once in the native-chat lane and shares it between the send path and the composer menu.
… down (E9 A) (stablyai#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 stablyai#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>
Co-authored-by: Radu Toader <radu.m.toader@gmail.com>
…cs (stablyai#34055) Co-authored-by: m4air <m4air@Mac.localdomain>
…st's move (stablyai#34041) * fix(ssh): show Move anyway on a host card whose move saved state refuses A host whose move to its Orca server was refused over saved state (an enabled SSH automation and its runs, stale workspace details, unsupported saved tabs) stayed in error on every Connect. Move anyway, which connects it and leaves those items on this computer, was only in the card's overflow menu, so the host looked stuck. The card now offers Move anyway next to its refusal, as it already does for Recover server. Refs stablyai#29083. * fix(ssh): make Move anyway the next step when saved items refuse a host's move When a host's move to its Orca server is refused only over saved items that Move anyway can leave on this computer (stablyai#29083's enabled automation and its runs, for example), every surface now leads with it: - the host card says which items can't move and that Move anyway connects the host and keeps them here, with Move anyway as its primary button; - the refusal toast says the same and offers Move anyway, opening SSH Hosts where the move is confirmed; - the terminal pane's Move anyway is primary too; - the host picker and connect toast read the same line. Refs stablyai#29083.
…tablyai#17714) The packaged agent-browser binary resolves its version-matched skills from the nearest skills/ directory above it (Resources/). Only the binary shipped, so `agent-browser skills get core` answered "Skill not found" and `skills list` "No skills found". Ship node_modules/agent-browser/skills/agent-browser and skill-data beside it on mac, linux and win, and cover it with a test that stages the host's extraResources slice and runs the real binary. Refs stablyai#17705 Co-authored-by: zerone0x <zerone0x@users.noreply.github.com> Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com>
…i#29321) Several zh.json strings used a translation with the wrong meaning for the UI context (e.g. git base ref, dividers, host, browser profile, search keywords). Align them with the intended sense and consistent terminology. Co-authored-by: Neil <neil@stably.ai>
…ai#31546) * fix(native-chat): render math and center standalone equations * fix(native-chat): parse math without rewriting message source * fix(native-chat): accept element roots for math selections * fix(native-chat): preserve math boundaries and selected source * fix(native-chat): derive math fence closure from accepted parser events * fix(native-chat): reuse exhausted math searches per tokenizer * fix(native-chat): load math typesetting after parsed formulas * Use declaration references for chat math augmentations * Declare chat math metadata and register equation label * Preserve i18n exports in selection quote test mock * test: expect cached legacy failure display reuse --------- Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com>
…yai#31985) * fix(opencode): allow picked models across CLI updates * test(opencode): prune obsolete timeout ratchet allowance * fix(opencode): use resolved agents and refuse unsafe workers upfront * fix(i18n): include OpenCode refusal messages in runtime catalog
…32045) * fix(ports): bound macOS scans by the lifetime of each operation * refactor(ports): keep Darwin metadata acquisition together * fix(ports): preserve valid Darwin observations and source host routing * fix(ports): retain scan admission outside aged temporary cleanup * perf(ports): skip unused listener acquisition for ownership actions * test(ports): make child fixture streams portable across runtimes * fix(ports): share source host derivation across scan rows * test(ports): initialize scan projection without a type assertion * fix(ports): restore existing browser open routing * fix(ports): preserve scanner compatibility on degraded hosts * test(ports): explain real process lifetime timing
…eybinding (stablyai#31679) * fix(native-chat): make the chat view toggle a remappable keybinding The terminal and Chat UI toggle was hardcoded to Mod+Shift+J, so users could not rebind or disable it, Settings did not list it, and it overrode user bindings on that chord. Declare it as terminal.toggleNativeChat in the keybinding registry, match it through the user's keybindings, and render its menu labels from the registry. * fix(keybindings): align native chat toggle admission and execution * fix(keybindings): preserve runtime input and defer closed menu hints * test(keybindings): use typed alias read instrumentation * Fix keybinding dependency direction and physical modifier inputs * Preserve typed input facts in floating shortcut arbitration * Clarify native chat shortcut precedence on Windows and Linux * Simplify native chat shortcut resolution and nominal labels --------- Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com>
* fix(worktree): track explicit remote branch * test(worktree): cover remote branch path retry * fix(worktree): resolve cached remote branches canonically * fix(git): retain commit validation in bounded ref probes * fix(worktree): preserve selected remote identity during creation * test(worktree): count cached resolver Git work during path retries * Fix branch intent state in composer source fixture * Make Git and daemon regression fixtures portable * Use the selected base for existing branch creation --------- Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com>
…#32919) * Fix automatic branch naming for workspace labels in every language * Use creature branch seeds for typed workspace labels * Keep first-work generator mocks in creator test suites * Type the created worktree test mock from its production signature * Assert created worktree results before exercising first work * Match the missing-folder update contract in first-work fixtures
…ablyai#33084) * feat(wsl): let an idle WSL distro stop once its orcad idle-exits The WSL host's holder kept the distro (and the WSL VM) running after Orca quit, even with nothing running in it. orcad now leaves a release request in ~/.orca when a managed idle stop retired its terminal daemon; the holder waits for that orcad to exit, claims the request and ends, so WSL can stop the distro. Live terminals, working agents, enabled automations or a returning client keep the distro held as before. A host whose distro is stopped at startup reads as stopped instead of unreachable, and the real-WSL lane gains a phase that proves the release and records memory. * fix(wsl): key the holder release on the WSL-host launch marker; name the lane phase The real-WSL lane showed orcad idle-stopping with its daemon retired while the distro stayed up: the setsid'd orcad's environment is not guaranteed to carry WSL_DISTRO_NAME, so the release request was never written. Use ORCA_WSL_ORCAD_HOST, which only WSL-host launches set. Phase 3 now carries its phase name and path filter, and records what kept a distro running. * test(wsl): dispose the idle-release lane's guest transports Each guest command left its exec loop running, a wsl.exe client that kept the distro up after the holder had already let go (the receipt showed no holder, no orcad, no request left). * test(wsl): record which wsl.exe clients keep the idle-release lane's distro up * test(wsl): satisfy the flaky-test ratchet; feed the new idle port in the release test * test(wsl): snapshot guest processes after launch to find what holds the session * test(wsl): locate the step that leaves the zombie holding the idle distro * test(wsl): log the idle-release lane's guest commands with times to place the zombie * test(wsl): follow the remote runtime client's move * test(wsl): record when each leftover WSL session init started * fix(wsl): keep the distro while the user still runs anything, and never trip on the request file Review of stablyai#33084: - The holder now checks, before claiming a release, that no process of the user runs outside the holder itself (session plumbing aside: systemd --user, (sd-pam), dbus-daemon). A detached tmux, nohup job or dev server keeps the distro; it fails toward holding. - A new holder drops any request left from before it started, so an older orcad's request can never end a holder a client just asked for. - orcad touches the request file only for WSL-host launches and never throws over it. - The real-WSL lane proves a detached job keeps the holder and its request, and the distro stops once the job ends. * fix(wsl): a running container keeps the distro, whoever owns its shim Docker's containerd-shim processes run as root, so the user-only scan missed them and a release would have stopped running containers. Any containerd-shim process now keeps the hold. * fix(wsl): read each process status only up to Uid; document what keeps the hold Delta review of stablyai#33084: dash reads a status file a byte at a time, so stop at Uid. Document that a root default user never releases, that per-user agents hold it, and the hidepid exception. The lane's pkill no longer matches the shell running it.
… per scroll frame (stablyai#34323) * perf(mobile): stop redrawing the chat per keystroke and scanning every row per scroll frame Typing re-rendered the whole session screen because the draft text was subscribed in the drafts hook at the route; the composer now subscribes by draft key. The page list's reading place indexed every drawn row with a page-wide querySelectorAll on each scroll event; it now binary-searches the row box's children. The list also observes its viewport so composer resizes keep a parked reader's place without a list commit. * test(mobile): keep the keystroke redraw test in the draft-store suite under the line cap
…tablyai#34324) The runs API serves at most 1000 results per query. On 2026-10-27 one hour crossed that and the daily report threw. Halve any oversized interval until each query fits. Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
…tablyai#34325) The owner-loss smoke builds the Swift helper and forks the computer sidecar; neither imports src/cli or src/main/daemon, yet those paths started the paid macOS runner on every computer-e2e trigger. Move it to its own workflow with the macOS-relevant subset of the old paths. Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
It raced the relay's kill against the stub cats setting their TERM trap, and picked the cat to keep blocked by start order. It now hangs up only once both traps are in place, and tells the socket reader from the stdin reader by whether its stdin is the relay's socket (fd 3).
…ablyai#24327) On repos whose base branch requires a merge queue and that disable auto-merge, gh pr merge --auto always calls enablePullRequestAutoMerge, which GitHub rejects. Call the enqueuePullRequest mutation directly in that case and report enqueue failures as merge-queue errors. Fixes stablyai#19638 Co-authored-by: Neil <neil@stably.ai>
* refactor: group shared native chat composer input * refactor: consolidate concrete composer imports
…#34113) * Import cookies without clearing existing sessions * fix(browser): keep new cookie imports merge-only * fix(browser): admit native cookie preparation through session lock * fix(browser): retire superseded shipped cookie imports * test(browser): make cookie expiry fixtures deterministic * test(browser): restore cookie clear mock type import * fix(browser): show skipped cookies in import result toast * test(browser): expect native cookie imports to preserve existing coordinates * fix(browser): report only successfully imported native cookie domains
…tory stack frames (stablyai#34335) Vitest's reporter checks existsSync(file) and then reads the file to find a source map. When an error stack names a directory, readFileSync throws EISDIR as an unhandled error, so the shard fails with every test passing. Read only regular files. Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
…1793) Pin commit.gpgsign=false and tag.gpgsign=false in the throwaway repos built by the release script tests so a global signing config cannot turn lightweight fixture tags into annotated tags that abort with "fatal: no tag message?".
…ai#34337) Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
…anup (stablyai#25478) The queued-message test rig deleted its temp state directory while the shared journal SQLite handle was still open, so teardown failed with EBUSY on Windows. Close the rig root's journal database after the host drains, then remove the directory.
…ication (stablyai#34327) Both arch jobs overlapped ~2.5 min of setup with qualification, then polled for the template for 400-560 s on the most expensive runner we use. Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
…d base (stablyai#33782) check:changed --base=<ref> resolved a merge base for the gates it drives directly, but the flaky-test ratchet subprocess re-derived its scope from origin/main. On a checkout whose origin is a stale fork that pulled in unrelated files and could fail the run. check:changed now forwards its merge base via ORCA_CODE_QUALITY_BASE (the env the other changed-code gates already honor), and the ratchet uses it before falling back to origin/main. Fixes stablyai#33763 Co-authored-by: Neil <neil@stably.ai>
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
Bell, test, task-complete, tool-preview, permission-probe and startup registration notifications now read their sentences from the i18n catalogs instead of English literals. The notification translator accepts interpolation values; the English default fills them so headless hosts produce unchanged English copy. The startup permission prompt waits for main-process i18n before it is shown. Fixes stablyai#27068 Co-authored-by: outof-place <contact@outofplace.space>
…022 runner (stablyai#34350) The free windows-11-arm and macos-15-intel lanes already set the matrix's wall time; the paid 8-vCPU Blacksmith Windows lane finished minutes earlier for ~$48/day. Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
Only the automations and client-hosted-browser steps had an id-keyed entry in the localized step copy map, so every other contextual tour (workspace board, agent sessions, browser, tasks, floating workspace, workspace creation) rendered English titles, bodies, and action labels next to localized Back/Next/Done controls. Give every tour step a required stable id and move the copy lookup into contextual-tour-step-copy.ts. The map `satisfies` a record over all step ids, so a new step without localized copy is a type error. Primary and secondary action labels (Split terminal, Got it, Browser settings) are localized through the same entry. Existing automations and client-hosted-browser keys are unchanged so shipped translations keep resolving. Add the new strings to en and translate them for ko, es, ja, zh, fr, and pt. Co-authored-by: Neil <neil@stably.ai>
* test(wsl): hand the reap test's fake cat its real stdin The fake cat backgrounded the real cat with `&`, which a non-interactive sh starts on /dev/null (dash even under `<&0`). The socket reader therefore ended at once, before orcad hung up, and the relay killed its partner, sometimes before that cat's TERM trap was set: on Linux under load the trap count stayed at 1 even after stablyai#34329 (3 of 6 rounds of 50 failed). The fake cat now passes stdin on fd 5, as the relay itself does, so the socket reader ends only when orcad hangs up and the stdin reader blocks until killed. * test(wsl): mark the fake cat armed only once its child is known; tighten the comment
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Sync stopped for operator decisions: #61. As expected, this PR is
#61 has the comparisons, the options, everything that was resolved, and the checks that ran. This PR stays open until the merge moves to a sync branch; |
ELI5
Upstream Orca moved forward 359 commits since yesterday's sync (#58). This PR proposes merging them into
swaplabs/mainstraight from the fork's mirrormain.What Changed
Upstream range
33ddab70b7..df95be4090, 359 commits (compare). The head is the fork's mirrormain, so the PR adds no fork commit.A read-only
git merge-treeofdf95be4090intoswaplabs/main(4997ffc041) reports 19 content conflicts and 2 file-location conflicts, so this PR is expected to beCONFLICTING; the automation then moves the merge to async/upstream-20261027branch and closes this PR as superseded:.gitignoreAGENTS.mddocs/reference/swaplabs-agent-resume.md(file location: upstream renamed the directory todocs/agents-md-refs/)docs/reference/swaplabs-fork-builds.md(file location: same rename)src/main/ai-vault/runtime-session-scanner.tssrc/main/daemon/daemon-pty-runtime-state.tssrc/main/updater-prerelease-feed.tssrc/main/updater-test-harness.tssrc/main/updater.check-failure.test.tssrc/main/updater.nudge-campaign.test.tssrc/main/updater.startup-scheduling.test.tssrc/main/updater/updater-release-feed.tssrc/main/updater/updater-status.tssrc/renderer/src/components/settings/settings-project-list.tssrc/renderer/src/components/settings/use-settings-store-model.tssrc/renderer/src/i18n/en-runtime-required.jsonsrc/renderer/src/i18n/locales/en.jsonsrc/renderer/src/lib/workspace-session-host-persistence.tssrc/renderer/src/lib/workspace-session-host-split.tssrc/renderer/src/store/repos/repo-removal.tssrc/renderer/src/store/repos/repo-state.tsWhy
Daily upstream sync.
Linked Issue
N/A: daily upstream sync.
Visual Proof
N/A: upstream code only.
Testing
None on this head:
mainis the mirror and takes no commits. Validation happens on the sync branch.AI Disclosure
Prepared by the "Orca upstream sync" automation (Claude Code, Claude Opus 5.5).
Agent skill upstream boundary
Notes
orca-fork-ops statusforswaplabs/main(4997ffc041) against upstreamdf95be4090:LOCAL:prefix and no upstream PR.Upstream release tag
v1.4.242was copied to the fork.🤖 Generated with Claude Code
Need help on this PR? Tag
@codesmith-botwith what you need.