Repository navigation
Conversation
innocarpe
force-pushed
the
fix-20665-diff-collapse-scroll
branch
from
October 1, 2026 22:52
930a554 to
c20289d
Compare
2 tasks done
Owner
Author
Sync update (
|
innocarpe
force-pushed
the
fix-20665-diff-collapse-scroll
branch
3 times, most recently
from
October 22, 2026 00:27
2d00768 to
b908916
Compare
…till holds a dispatch (stablyai#33295) Windows Codex: when a large dispatch/worker-start/agent prompt paste is still held in Codex's composer (Codex reads the paste as key events and treats an early Enter as a newline), Orca re-presses Enter only while the composer visibly holds exactly that pasted prompt, re-checking turn start, permission and the deadline right before each Enter, within the worker-start budget. Non-Windows unchanged except the blind launch retry is skipped once a turn starts. Fixes stablyai#11343.
…e's terminals in a shared workspace (stablyai#33414) * fix(runtime): keep another paired runtime's terminals when one runtime republishes a shared workspace Desktop B can mirror one SSH workspace from two paired runtimes: the host's server, which runs its terminals, and desktop A's app, which hosts a browser tab A opened there. Any frame from A's app replaced every mirrored terminal row in the workspace, so B dropped the server's terminals until the server's next frame re-created them. A frame now replaces only the mirrored terminals and chats its own runtime owns, matching how browser and editor rows were already scoped. Fixes stablyai#31983 Reported-by: amara-black * fix(runtime): retire an omitted host's rows without waiting on a sibling host's replay A tombstone now retires only its own host's rows, so the visibility-resume repair no longer has to hold it back until every surviving host has a frame to replay over the wiped workspace. * refactor(runtime): one ownership rule for rows a paired runtime's frame may retire Bindings first, then the frames that last published the row, then the workspace's own server; owners that were removed no longer count, so any runtime's frame can retire their rows. * fix(runtime): address review on cross-runtime mirror ownership Drop the workspace-owner guess for rows with no evidence, let a frame that publishes the same chat take its row over, and refocus a surviving runtime's terminal when the active one is retired. * refactor(runtime): a mirrored terminal stays while any other live runtime claims it Union pane bindings and last-frame mappings into one claim set, so a row two runtimes share survives one runtime's retraction. Drop the chat ownership extension: chats are shared across runtimes by session id, and the reported bug is terminals only. * refactor(runtime): claims come from the frames that published a terminal A runtime that stopped publishing a terminal no longer claims it through a cached pane binding; bindings only speak before any frame this session. Keep the visibility-resume repair's survivor deferral as it was. * fix(runtime): bound pane resources decide a mirrored terminal's runtime; chats follow the same rule A shared terminal whose bound runtime drops it is retired and rebuilt by the other runtime's next frame, so it never streams from a runtime that left. Chats another live runtime owns survive this frame unless it publishes or replaces them. * fix(terminal): close another paired runtime's terminal on that runtime A workspace can now keep terminals another runtime publishes, so a close follows the runtime the tab's own PTY names before the workspace catalog. * fix(runtime): only this machine or a live paired runtime keeps a chat another frame omits
…ut (stablyai#33423) * fix(windows): respawn a ConPTY pane that started without an input reader Bundled ConPTY occasionally starts a pane whose console host never reads its input pipe: the shell prints its banner and prompt, but every keystroke and the typed launch command are dropped. Such a pane is identifiable from its first output, because a healthy one always queries DA1 before relaying anything else. The daemon now waits for that first output, respawns once when it is missing, and replays the buffered startup output so no byte is lost. The table stress probe now waits for node-pty's own readiness rather than typed input. * fix(windows): bound the ConPTY startup check and never re-run a command - Respawn only when no command rode in the shell's argv; otherwise keep the pane and say on screen that it cannot take input. - Accept the pane unverified after 5s of silence instead of stalling the spawn. - Distrust the check after two misses with no pane ever announcing, so a changed ConPTY build cannot respawn every pane. - Kill a discarded pane through its job before closing the pseudoconsole. - Report a cancel during the wait as an attach cancel, not a spawn failure. - Assert on real Windows ConPTY that a fresh pane announces its input reader. * fix(windows): respawn only Orca's own shell argv and close an unready pane now - Treat user shell args like an argv startup command: never respawn, show the notice instead, so a command such as pwsh -Command never runs twice. - Close a discarded pane's pseudoconsole directly; node-pty defers kill() until first output, which a silent pane never produces. Kill the shell by pid when no job owns it. - Reconcile a master node-pty retired during the startup wait. - Drop the test-only respawn counter; the count rides in the daemon log. * fix(windows): tear a discarded unready pane down through node-pty's agent node-pty defers kill() until first output, so closing only the native pseudoconsole left the input pipe and output worker of a silent discarded pane alive until daemon exit. The agent's kill closes all three. * fix(windows): discard startup panes by handle only; account for the mock prelude A pid-addressed kill could hit a recycled pid when the shell exited during startup; the job and the agent's native kill both act on handles. Lifecycle assertions now expect the replayed DA1 query when the suite runs on Windows. * test(e2e): give the mocked Windows pane its ConPTY prelude
…ving them in the composer (stablyai#33347) Orchestration mailbox pointers now get their delayed Enter for Cursor too (the Cursor no-Enter skip from stablyai#3156 left mail delivered but never acted on). Verified with real cursor-agent. Fixes stablyai#19760. Supersedes stablyai#19761. Co-authored-by: Maple <54388301+zleo-ai@users.noreply.github.com>
…s one draft (stablyai#33339) Windows + Codex: Ctrl+V, Shift+Insert and Edit > Paste send multi-line pastes with Alt+Enter newlines like right-click already does (restoring stablyai#14456 wiring lost in a refactor), so pasted lines no longer submit one by one when Codex's paste-burst heuristic doesn't catch them (e.g. disable_paste_burst = true). macOS/Linux clients unchanged. Fixes stablyai#30470. Supersedes stablyai#30550. Co-authored-by: STiFLeR7 <157357792+STiFLeR7@users.noreply.github.com>
* refactor: group local and WSL filesystem watchers * test: isolate startup ordering from watcher initialization * test: collect the startup preflight subject once
…i#21491) (stablyai#33296) macOS: Option+Forward-Delete sends ESC d (delete word forward) for shells and inline agent TUIs, so Claude Code deletes a word instead of the whole line; full-screen non-agent apps (vim, nano, less) keep the native CSI 3;3~. Linux/Windows unchanged. Fixes stablyai#21491. Supersedes stablyai#21893. Co-authored-by: bbingz <11211020+bbingz@users.noreply.github.com>
… checks (stablyai#33406) * feat(devex): component fixtures with headless screenshots for fast UI checks Colocated *.fixture.tsx files export named fixtures (render + optional store seed, setup, interact, width). A dev-only Vite entry (vite.fixtures.config.ts, extending vite.web.config.ts) renders one fixture in isolation with the real I18nProvider, TooltipProvider, theme class, default-seeded store, and the web client's preload bridge (installWebPreloadApi) as window.api. `pnpm fixtures:shot <id|glob> [--theme dark|light|both]` starts or reuses a detached server (Vite + one headless Chromium) and writes PNGs to .cache/fixtures/. A warm page re-renders in place (~100ms/shot) and reloads only after source changes. A stdio MCP server (registered in .mcp.json) exposes list_fixtures and screenshot_fixture. Fixtures load only through import.meta.glob in the fixture entry, which is not a production build input; oxlint rejects static imports of *.fixture. * Keep fixture config and agent config inside reviewed root entries * Baseline the fixture page's default-settings seed in the focus-read ratchet * docs(agents): shorten fixtures pointer * Allowlist the dev-only fixture explorer's labels in localization coverage
…tablyai#33430) * perf(lint): keep JS plugins out of default oxlint and adopt ast-grep Any jsPlugin makes Oxlint hand every file's AST to Node, so the seven custom plugins cost the default `oxlint` run several times its native time. - Move app-store-performance, quadratic-buffer-concat, renderer-scrollbar-style and ime-enter-guard (scope- or dataflow-aware) to config/oxlint-js-plugins.json, run by `pnpm lint:js-plugins`, CI, lint-staged and the changed-lines gate. - Port sort-comparator-performance, mobile-pairing and native-chat-design-tokens to ast-grep rules with rule tests, and delete the plugins. - Add @ast-grep/cli, config/sgconfig.yml, `pnpm lint:ast-grep` / `test:ast-grep`, a CI step, and an ast-grep pass in check-changed-code-quality. - Add flaky-test rules (wall-clock reads, real-time waits, polling loops, unquarantined skips, unexplained timeout bumps), baselined by a count ratchet. * Enforce flaky-test ratchet on changed files; refresh baseline * docs(agents): keep custom-rule details out of AGENTS.md * Resolve ast-grep from the repo so gate scans of other roots work
…ts through the host's Orca server (stablyai#32484) (stablyai#33388) * test(e2e): a saved SSH forward on a managed host comes back after a restart (stablyai#32484) * test(e2e): a restart that reaches the host only through its server's tunnel restores saved forwards (stablyai#32484) * fix(ssh): restore saved port forwards whenever a host's server is up, not only after an SSH connect (stablyai#32484) A host whose managed server the app reaches at startup through its tunnel publishes its served status from the tunnel path, which never ran the forward restore. The served status itself now triggers the restore, from any publisher, and a host kept on the legacy relay bridge restores too. * test(ssh): type the restore spy's target argument * fix(ssh): user forward edits keep unrestored saved forwards; restore once the tunnel is up Add, edit and remove now merge with saved forwards that aren't live, so a restart that restored nothing no longer lets one re-added forward erase the rest. A call that brings up the managed server's tunnel restores too, so a failed update check or redeploy can't skip it, and a restore runs once per transport instead of on every status note. * fix(ssh): a forward that failed to bind is retried on the same transport * fix(ssh): restore again when a restored forward closed; a reused local port replaces its old mapping * fix(ssh): user forward edits and restores share one per-host queue A restore that ran mid-edit could reopen the mapping the edit was replacing and save both. Every add, edit, remove and restore for a host now runs in order through the same queue. * fix(ssh): pace forward restores and back off a forward that keeps failing Each runtime call triggers a restore over the managed tunnel, and with system SSH every attempt is a new login. Restores on the same transport now run at most once per 30 s, a forward that keeps failing waits longer each time, and teardown forgets both. A tunnel with no status yet counts only outside a connect; a remove re-checks its forward inside the queue; drop a circular listener test and the plain restart e2e case. * fix(ssh): a start a teardown cancelled records no backoff * fix(ssh): a reconnected transport retries failed forwards at once
…he prompt (stablyai#33316) DSH: Orca re-presses Enter (up to a 30s launch budget) while dsh's launchpad still visibly holds the launch prompt — dsh refuses Enter while its session is starting — and stops as soon as the prompt leaves the screen, so no Enter reaches the first-run guide. The shared draft reader recognises dsh's boxed launchpad composer. Fixes stablyai#29131, stablyai#33227. Supersedes stablyai#33229. Co-authored-by: Xulin Wu <35489799+wuuli@users.noreply.github.com>
…tory and folder when slept (stablyai#33425) * fix(terminal): a pane a relaunched app has not reopened keeps its history and folder when slept After an app relaunch, a terminal the window had not shown again was known to the daemon client only from its terminal list: no history writer and, for a WSL pane, no distro or pane key. Its Sleep then wrote no final checkpoint at all (only output.log), so Wake restored from older output and, for a WSL pane on Windows, reopened at the spawn folder (awin verify-10, X2). stablyai#33398 learned those facts in `reconcileOnStartup`, which nothing in the app calls. Sleep now adopts such a session first: one `listSessions`, then the same history reconciliation, distro and pane key a startup adoption records. Its final checkpoint then lands with the shell's folder. Sessions the client spawned or reattached skip this. Co-Authored-By: Claude <noreply@anthropic.com> * fix(terminal): Sleep never re-adopts a session this client suspended after a seed failure Review of stablyai#33425: adopting an unattached session before Sleep also caught sessions this client already holds but suspended after a history seed failed (an old daemon, an oversized seed, a transfer failure). Re-adopting one wrote its fresh-only screen as the authoritative checkpoint, so Wake lost everything from before the restore. Sleep now adopts only sessions the client does not already hold as active. A session it does adopt becomes active only once its history writer is open, so an exit during the reconcile leaves it out. Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
…yai#33449) * perf(dev): serve the renderer with bundled dev mode by default * test(dev): expect bundled renderer dev by default
…aude account switch (stablyai#30328) Leave a user's node or python program alone after a Claude account switch; unchecked terminals get an accurate toast. Fixes stablyai#30327 Co-authored-by: Adif Sgaid <69080239+adifsgaid@users.noreply.github.com>
* Reduce tab preview tooltip delay to 500 ms * Reduce tab hover card test delay expectations
* refactor: group filesystem IPC registration and suites * refactor: preserve lint baseline counts for relocated filesystem suites
…tablyai#33453) * test: remove low-value cases and repair behavioral assertions * test: prune repaired wall-clock finding from flaky-test baseline --------- Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
…unch metadata (stablyai#33317) Graceful close (mobile pane, headless tab, worktree stop) of a shell without launch metadata now sweeps descendants on macOS/Linux, matching desktop tab close, while sparing the shell's own nohup/disown jobs (login-wrapper aware). Windows graceful plain-shell close is unchanged. Fixes stablyai#16714
… TUI (stablyai#33466) Terminals created with a flagged agent command (e.g. `omp --thinking high`) now get the agent's identity at creation, so `tui-idle` waits for the agent instead of reporting ready early. Fixes stablyai#25264 Supersedes stablyai#25320 Co-authored-by: ggbdpq <67929842+ggbdpq@users.noreply.github.com>
…r its Stop hook (stablyai#33335) Keep tui-idle blocked when Codex paints its plan menu after the Stop hook. Fixes stablyai#25912 Supersedes stablyai#26492 Co-authored-by: Jinwoo Hong <73622457+Jinwoo-H@users.noreply.github.com>
…ws ConPTY (stablyai#33473) Ctrl+Enter reaches Claude Code as CSI-u (`\x1b[13;5u`) on local Windows ConPTY panes, matching macOS/Linux, so custom ctrl+enter keybindings work. Fixes stablyai#29711
…din (stablyai#33470) Windows managed hook skip paths (Devin/Grok/Cursor replay guards, and orca-agent-hook.exe) exit immediately instead of draining stdin through more.com, so a held-open writer can no longer hang the hook. Fixes stablyai#24907 Supersedes stablyai#24909 Co-authored-by: inforanger <29155427+inforanger@users.noreply.github.com>
…lient in the background (stablyai#33828) Rolldown defaults to 1.5x physical cores Tokio workers plus a Rayon pool per logical CPU (24+24 here). Capping both at 8 on >8-core hosts cuts electron-vite build CPU 24% with byte-identical output. pnpm dev no longer blocks on a stale pairing web build; it stages into out/.web-next and swaps on success. Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
…lyai#33392) * fix(native-chat): remove misleading usage-limit Continue action Keep limit warnings, reset times and provider details without offering an immediate continuation or adding manual continuation guidance. Preserve restart-interruption Continue and provider detection. * fix(i18n): sync runtime catalog for removed notice fallback * fix(i18n): remove unused usage-limit action translations * test(native-chat): cover historical usage-limit wording * test: admit historical notice fixtures through journal reader * test(mobile): admit the old-host usage-limit fixture through the journal reader --------- Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com>
* Fix Codex goal Stop and selected model settings * Preserve settings evidence and captured Stop outcomes * Preserve refused goal pauses and bound Stop retry diagnostics * Use checked settings state in goal contract tests * Narrow captured Stop child and type its timing fixture * Coordinate Stop timing fixture with deferred phases * Fix typed mobile warning icon assertion * Align Stop tests with reconciled controls and owned shutdown * Check integration attach parameters without a type cast * Match restart offer close calls to optional observer contract
…tablyai#33834) Tests leak os.tmpdir() fixtures broadly (8.6k dirs from repeated prefixes on one shared dev host; orca-runtime-rpc alone 2,729). run-vitest.mjs now points TMPDIR/TEMP/TMP at a marked per-run dir, removes it after Vitest exits (including on SIGINT/SIGTERM), and sweeps marked dirs whose launcher died. On POSIX a root longer than 50 chars (macOS /var/folders) falls back to /tmp so Unix socket paths stay under sun_path limits. Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
…tablyai#33835) Local panes printed '[Orca skipped hidden terminal output because main recovery was unavailable.]' inside idle Codex/Claude Code frames and it stayed until a workspace swap, because the one-row redraw nudge from stablyai#31482 only ran for remote PTYs. Differential TUIs never rewrite cells they believe unchanged, so the banner row persisted. Local PTYs now get the same nudge, restoring the row on a timer since local main sends no desktop-fit confirmation.
…tablyai#33833) Concurrent new-PTY resolver probes shared the 'resolver-health-check' clientId, so the daemon evicted the older probe's control socket and that probe waited out the 3s timeout before its terminal could spawn. Use a per-probe UUID clientId and settle as 'unknown' as soon as the probe socket closes. Fixes stablyai#27751 Co-authored-by: outof-place <contact@outofplace.space>
…tablyai#33820) Each desktop socket to a WSL host's orcad, and the liveness watch, ran a Node process in the distro just to copy bytes (~42-50 MB RSS each). A bash /dev/tcp relay does the same with bash and two cats (~4.5 MB). The Node bridge stays as the fallback for hosts without bash 4.3+ or /dev/tcp and for refused dials, so refusal and missing-runtime signals are unchanged. SSH hosts keep the Node bridge.
…rvers (stablyai#33845) Only desktop requests reach a host's scanner child, which holds ~60 MB of RSS even idle, and the 10-minute default kept it alive most of the time. orcad now sets a 60 s idle timeout; the desktop keeps its default.
… mimalloc purge) (stablyai#33836) * perf(dev): size the dev server's Rolldown runtime for many parallel instances ~93% of idle electron-vite RSS is Rolldown's native mimalloc arenas. The dev wrapper now gives electron-vite MIMALLOC_PURGE_DELAY=0 and 4 Rolldown/Rayon threads; a serve-only renderer plugin strips exactly those keys before Electron spawns, so dev Orca's terminals never inherit them. * fix(dev): add the runtime-env plugin only when the dev wrapper set its keys Keeps createDevServeConfig returning the renderer config unchanged when there is no port and nothing to strip, as electron-vite-output-contract pins. --------- Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
…ses (stablyai#33848) A killed Vitest left its node-runtime worker running the rest of the file (still alive after 150s). Exit on 'disconnect' with process.exit captured before Vitest replaces it with a throwing guard. Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
Grok's installer defaults to ~/.grok/bin and only symlinks into ~/.local/bin when that dir is already on PATH. A GUI-launched Orca never looked in ~/.grok/bin, so the Agents page reported Grok as not installed. Append ~/.grok/bin after ~/.vite-plus/bin in the three lists that must stay in step: the packaged PATH seed, the system install-dir lookup fallback, and the POSIX/WSL guest fallback prelude. Fixes stablyai#17590 Co-authored-by: brynnclaw <261708852+brynnclaw@users.noreply.github.com>
…stablyai#33783) * fix(terminal): answer queries in ACK-pending output a paused paired view discards Refs stablyai#32944 * fix(terminal): capture yielded-query ownership at ingestion and cap reply age Refs stablyai#32944 * fix(terminal): settle yielded queries by their own end seq across split frames Refs stablyai#32944 * test: use a fixed timestamp in the yielded-query responder test * test(cross-version-wire): stub yielded-query runtime methods on the host runtime Refs stablyai#32944
stablyai#33027) * test(e2e): a pane moved to a new tab on a paired server workspace stays moved * fix(terminal): keep a pane moved to a new tab on paired runtimes Moving a split pane to a new tab in a paired-runtime worktree changed only the window store. The host never learned about the move, so the next host snapshot rebuilt the old tab and the pane snapped back. Add a session.tabs.movePaneToNewTab RPC that commits the move in the host session through planTerminalLeafMove and republishes the session tabs. For a mirrored host tab, the renderer applies the move first under the mirrored id the host snapshot will use, then asks the host to commit it. An older host or a refused move falls back to the old local-only move. Fixes stablyai#32939 * fix(terminal): commit a host pane move through the existing leaf-move writer The layout-writer ratchet allows no new main-process layout writers. The headless host now hands the move to commitLeafMoveAndRekey, the same commit a local window uses, and keeps only the window check, validation, rehydrate and notify. * fix(terminal): gate the host pane move on a host capability An older host keeps today's window-only move under a local tab id instead of a mirrored one it never confirms. Adds a terminal.list check to the e2e. * test: drop type assertions from the pane-move tests * fix(terminal): the host keeps a moved pane's place, focus and live terminal After the host commits the move, the window gives it the drop position and focus through the existing tab move and activate calls; a refusal redraws the host's tabs. The host moves the live PTY's surface with its pane and checks the target tab id. The move lives in its own runtime module. * fix(terminal): hold a moved pane's drop order until the host has it The host's snapshot of the commit goes out before its reply and appends the tab, so the window records the drawn order as a reorder intent at the drop and sends that order, and the focus read then, once the host answers. * fix(terminal): route the moved tab's reorder to its owning host The follow-up names the worktree's host instead of reading the active-server setting (focus-read ratchet); the e2e narrows host rows to terminal tabs. * fix(terminal): the host places a moved pane's tab in the move itself; a refusal reverts The move carries the drop's group and index (optional; an older host appends) and the host places and selects the tab before its one publish, replacing the follow-up reorder and the drop-time order hold. A refused move closes the tab this window drew without stopping its terminal and redraws the host's tabs even when unchanged. E2e covers a same-group drop and a refusal; host unit tests cover same-group and cross-group placement. * fix(terminal): a refused pane move keeps its pane records; drop index in host order The revert hands the pane's status and launch records back to the source tab before closing the drawn tab. The host turns a projected client's drop index into its raw order with translateProjectedSessionTabMove, as session.tabs.move does. * fix(terminal): only an unknown drop group appends a moved pane's tab The host catches only target_group_not_found and invalid_tab_order from the index translation and rethrows anything else. * fix(terminal): settle a pane move by what the host holds when its reply is lost A lost reply is not a refusal: the window asks the host whether it holds the pane in the new tab before undoing anything, and waits for the next snapshot when it cannot ask. A move the host committed but this window could not draw takes the host's tabs. * fix(terminal): a lost transport on a pane move is unknown, not a refusal runtimeEnvironments.call answers a dropped or overloaded transport with an error envelope; those codes (the shared recoverable set) now ask the host instead of undoing a move it may have committed. * test(e2e): pane-move spec waits on real signals, not delays The source tab is created on the server and split once its shell is listed, so the split no longer races a desktop-seeded tab's first spawn (the CI failure). The stay check follows output from the moved pane; the refusal check waits for the drawn tab to appear and go. * test(e2e): read the refused move's tab counts without Reflect (anti-slop) * fix(terminal): a moved pane's tab joins the order the user had, not a rebuilt one The host inserts the new tab into the group order captured before the commit, appending without a drop position, so editors and pages keep their places. The shared group-move fallback is no longer used here. * fix(terminal): a moved pane's groups hold the host's current tabs, in the user's order Placement takes membership from the rebuild after the commit and only the order from before it, so a tab opened while the commit was pending stays (after the user's tabs) and no stale id is written. * fix(terminal): a moved pane's placement keeps a reorder made while it committed The order is read after the commit, from the host's current tabs, not before it. * fix(terminal): a moved pane keeps the lone group the user merged into A rebuild names a single group with the default id; placement keeps the user's id for it, so the drop position still applies after a split was merged back. * fix: import error classification from its new shared/remote-runtime path * fix(terminal): a pane or divider drag survives focus moving inside the window The drag's window blur listener was registered in the capture phase, so it also heard every element blur. A terminal attach or host snapshot that moved focus between panes mid-gesture ended the drag; in the paired pane-move e2e on CI it cancelled the drag before the drop. Only the window losing focus ends it now. * test: drive the focus-change drag test through a real pane manager, without casts * fix(terminal): a headless host moves a pane with its live terminal and never empties its source The host names the PTY it holds for the pane, so a session copy an SSH respawn left with an old id no longer refuses the move as a mismatch. A move that would leave its source tab with no pane (a sibling closed meanwhile) is refused, since no headless cleanup retires the emptied tab and it would publish as a phantom. The e2e fences its stays-moved check on a later server rename instead of sampling on a timer. --------- Co-authored-by: Ben Grynhaus <ben.grynhaus@wiz.io>
…blyai#29832) * fix(wsl-host): bind a WSL host record to its pairing's server key (R31) A valid but stale record could overlay WSL hosting onto a different loopback server re-paired under the same environment id and bridge port. The record now carries the paired orcad's host key; the overlay ignores a record whose key differs from the pairing's. Add writes the key and a pairing refresh rewrites it with the ports, so a relaunch that changes the key still matches. Records written before carry no key and keep port-only binding until their next refresh. Co-Authored-By: Claude <noreply@anthropic.com> * fix(wsl-host): validate a refreshed pairing before writing, and accept the previous key mid-refresh Review: the refresh wrote the record's new key before validating the pairing, so a refused or interrupted refresh could leave a real WSL host without its overlay. Validate first, and keep the replaced key as previousPairingPublicKeyB64 so the record stays bound across the two writes. Co-Authored-By: Claude <noreply@anthropic.com> * test(wsl-host): use a key distinct from the fixture's own in the R31 overlay tests Main gave the WSL fixture its own pairing key (stablyai#30676), the same one these tests used as the 'other server' key, so both cases inverted after the rebase. Production code is unchanged. Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
stablyai#33819) Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
…hen its connect hangs (stablyai#33865)
…ps failing (stablyai#33841) * fix(agent-awake): keep sleep-assertion failures warn-once across respawns A successful spawn reset the failure streak, so a systemd-inhibit or caffeinate that exits right away re-warned on every 30s retry. * fix(agent-awake): back off sleep-assertion retries after consecutive failures * test(agent-awake): dispose the real-timer assertion
…, −75 MB after bursts) (stablyai#33837) * perf(daemon): cap the terminal daemon's young generation Idle terminal polling in the daemon allocates a few MB/s of short-lived strings (process-table captures), and V8 answers by growing the young generation to its 64 MB semispace maximum. Nothing is retained (heapUsed returns to ~12 MB after GC), but the committed semispaces held ~120 MB of resident memory per daemon. Launch the daemon with --max-semi-space-size=4 on the fork, direct and extracted-AppImage paths. The flag goes on the command line, not NODE_OPTIONS, because PTYs inherit the daemon's env. * perf(daemon): pass the young-generation cap through the macOS launchd job Release macOS builds start the terminal daemon from the signed helper bundle through a launchd job, not the fork path, so the flag must be in its ProgramArguments too. --------- Co-authored-by: m4air <m4air@Mac.localdomain>
…oo (stablyai#33829) A visible local shell pane with no agent evidence was inspected every 2 s forever. Each inspection is a full-system `ps -axo ...,tty=,lstart=,command=` capture in the terminal daemon (0.155 s of CPU at ~1,100 processes, ~1.15 s at ~1,950), which also churned ~2.7 MB/s of short-lived strings and grew the daemon's young generation to ~120 MB resident. Apply the existing no-evidence cadence (15 s while quiet; output, title or hook activity re-arms 2 s for 10 s; agent evidence returns to the active/idle tiers) to local POSIX panes, as it already is for Windows and remote panes. Co-authored-by: m4air <m4air@Mac.localdomain>
…tablyai#33786) V8 stores a script source as UTF-16 when any character is above U+00FF, so a single em dash in a hot chunk doubled that chunk's resident source. Emit ASCII (escaped) output for main, preload, renderer and worker bundles, escape the CJK sentence marks in the prose URL regex source, and fail the renderer boot-graph check if a boot chunk regresses to two-byte. Co-authored-by: m4air <m4air@Mac.localdomain>
…tablyai#33810) Monaco's TypeScript WorkerManager has no idle stop, so viewing a single .ts file kept a ~40 MB language worker alive for the rest of the session. After 60 s with no typescript/javascript model, re-apply the current compiler options, which makes Monaco dispose the worker; the next TS/JS model starts a fresh one lazily. Co-authored-by: m4air <m4air@Mac.localdomain>
…ver save (stablyai#33864) * fix(runtime): recover from a NUL-filled server list instead of blocking every save Fixes stablyai#18766 * fix(runtime): recover only crash-zeroed server lists; keep removal proofs fail-closed * fix(runtime): copy the blank server list aside on write instead of renaming it on read * fix(runtime): recover a crash-zeroed server list only when saving a server Plain reads stay fail-closed so startup cleanup cannot treat the zeroed file as 'every server was removed'; saving copies the bytes aside and publishes an empty store only if the file is still blank. * fix(runtime): publish the recovered server list only together with the saved server A failed save now leaves the zeroed file in place instead of an empty registry that startup cleanup would read as 'every server was removed'. * fix(runtime): let SSH and WSL server setup save over a crash-zeroed server list Their duplicate and conflict pre-checks read the list before the add and threw on the zeroed file. The blank-file backup is now taken only once the write is attempted. * test(runtime): give the fsynced interleaving property test room on slow disks * test(runtime): run three guard-killing seeds instead of raising the interleaving timeout The fsync on every store write made 40 seeds x 40 steps slow; seeds 1, 6 and 8 each fail when one of the three guards this test protects is removed.
…eady painted (stablyai#33766) (stablyai#33880) Main seeds its terminal model from the renderer's xterm and queues live chunks behind the seed. The renderer keeps parsing those chunks while it serializes, so they were in the seed and then written again, doubling TUI frames and splitting escapes (literal ';242m'). Hidden-pane reveals repaint from this model. Skip queued chunks at or below the seed's seq and carry any unfinished escape into the next chunk.
…ai#33876) Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
…n Linux (stablyai#33878) * feat(serve): keep macOS serve out of the Dock and opt in to the GPU on Linux On macOS, orca serve now runs as an accessory app with no Dock icon or Cmd-Tab entry, and gets them back only while it hosts a desktop window. On Linux, ORCA_SERVE_GPU=1 keeps hardware acceleration on for hosts that expose a GPU to the server. * fix(serve): restore the Dock only for real launches, after window services resolve Gate the restore on any background or E2E launch, since dock.show() activates the app, and run it just before the window is created so a services failure cannot leave a windowless Dock tile. Say in the docs what the GPU opt-in can't do on Orca's own Xvfb.
…universal binary (stablyai#21146) SwiftPM 6.4 (Xcode 27) defaults to the swiftbuild build system, which writes products to an xcodebuild-style layout instead of .build/<triple>/release, so the lipo step in build-computer-macos.mjs finds no inputs. Pass --build-system native to both per-triple builds. Fixes stablyai#21145
…e machine-id (stablyai#33775) * fix(ssh): keep machines cloned with one machine-id off each other's Orca server data (stablyai#32918) Machines cloned from one image share /etc/machine-id. On a shared home both got the same machine key, so both managed servers ran in ~/.orca, and each judged the other's PID locally and reclaimed its live instance lock. - Record the claiming hostname in the shared-home claim and machine homes; a Linux machine whose machine-id matches but hostname differs gets its own machine home. Older claims fall back to data-root owner records. - orcad's instance lock no longer treats a holder with this machine-id but another hostname as local, and refuses to start when an older clone's profile-state owner record shows it is using the data root. Co-Authored-By: Claude <noreply@anthropic.com> * fix(ssh): keep a clone's established machine home, and let a host renamed within its boot restart Co-Authored-By: Claude <noreply@anthropic.com> * fix(ssh): call a machine a clone only with positive evidence A renamed host keeps its boot and a local disk has one machine, so only another host and boot with this machine-id on a shared filesystem counts as a clone, on Linux only. When both clones already write the login home, stay and let the server lock refuse the second writer. Drop the machine-home owner markers. Co-Authored-By: Claude <noreply@anthropic.com> * fix(ssh): refuse a second server from a cloned host instead of relocating data Drop the inferred clone relocation. orcad refuses to start when a holder or profile-state owner on a shared filesystem reports this machine-id from another hostname and boot, naming that host and the fixes. Add ORCA_MACHINE_NAME, an explicit host-env name that gives a managed SSH host its own machine home. Co-Authored-By: Claude <noreply@anthropic.com> * fix(ssh): judge cloned machines by boot and freshness, not hostname A peer with this machine-id is another live machine only when its record is from another boot, was written after this boot began, and is fresh. The orcad lock now heartbeats its mtime. That drops the hostname test, which renames broke and same-hostname clones evaded. It also drops the participant-owner precheck that stale records could block forever, and keeps profile-state owner cleanup from deleting a live clone's owner. stale-lock reclaim uses the same rule. ORCA_MACHINE_NAME now rejects invalid names and keeps a host on the home its running server or own machine-id already uses. Hints are role-specific and aimed only at the clone. Co-Authored-By: Claude <noreply@anthropic.com> * fix(orcad): stale-lock reclaim waits out the lock freshness window Co-Authored-By: Claude <noreply@anthropic.com> * fix(orcad): log a failed lock heartbeat and say a crashed clone's lock frees itself Co-Authored-By: Claude <noreply@anthropic.com> * fix(orcad): align reclaim help, age evidence and clone hint with the freshness window Co-Authored-By: Claude <noreply@anthropic.com> * fix(ssh): ORCA_MACHINE_NAME always selects its own home Inferring which home to keep from running owners flipped after shutdown or reboot and couldn't see macOS boots. A name now deterministically selects its home, and a multi-line name is refused. Co-Authored-By: Claude <noreply@anthropic.com> * fix(ssh): refuse a whitespace-only ORCA_MACHINE_NAME, and pin reclaim test clocks Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
Collapsing the section the View all diff viewport was inside kept the scroll anchor's within-section offset, which pointed into the removed body, so the structural restore landed on later sections. Pin the anchor to the section header before the collapse is published. Fixes stablyai#20665
nwparker
force-pushed
the
fix-20665-diff-collapse-scroll
branch
from
October 26, 2026 10:30
b908916 to
efdce1e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Upstream
Summary
Description In the View all diff, collapsing the section the viewport is inside left the scroll anchor pointing at an offset inside that section's body. The body is gone after the collapse, so restore kept the old offset and the viewport landed on later sections. ## Focused
Note
innocarpe/orcamainuntil the upstream PR is merged.