Repository navigation
sync: upstream 36d295628e into swaplabs/main - #64
Merged
Merged
Conversation
* fix(chat): confirm before closing active native chats * Repair native chat close settings and consent coverage * Cover native close consent in workspace and floating tests * Require consent before closing active native chats * Fix close-warning typed values in deferred actions and tests * Preserve admission ownership and reconcile relevant send evidence * Separate chat read lifetime from send settlement and activation effects * Fix required read activation typing
…34355) * Keep unacknowledged Claude prompts single after reopening * test: bound local prompt recovery indexing at scale
…blyai#34510) Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
…yai#34373) * fix: finish admitted terminal prompts after sender disconnects * test: consolidate prompt input contract assertions * Keep first-submit ownership independent of sender observation * Recheck prompt ownership after awaited guards * Cover abandoned prompt admission during restored pane startup * Use typed provider write spy in prompt socket regression
…ith the selected line range (stablyai#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>
Removes 134 redundant test registrations across native-chat projection, sidebar ordering, and palette matching. Deletes two entire suites: notice appearance mapping and ordering scenarios whose test-owned Host supplies the behavior being asserted. Retains 154 registrations covering state transitions, competing inputs, FIFO tool pairing, sidebar feed application, and search ranking. Production code is unchanged. Removes the two deleted suites’ timing entries and lowers the wall-clock baseline only for the deleted Date.now assertion. Validation: isolated static registration/body preservation, formatting, lint, discovery, runtime routing, and metadata checks. Full PR CI must verify 275 expanded cases across 17 owning test roots, including the transcript-contract aggregator; 185 cases belong to retained selected sources and required counterparts. No local runtime tests were run.
…33730) * fix(ports): attribute listeners through workspace symlinks * fix(ports): bound workspace realpath resolution during scans * Preserve port URLs through incomplete workspace alias observations * Bound workspace alias lookups with expiring FIFO admission * Bound alias admission per workspace scan phase * Document fake-clock lookup timers for the test policy * Keep fake-clock recovery coverage on the alias under test * Wait only on existing workspace alias observations * Assert advertised port URLs within the node test boundary --------- Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com>
* refactor(terminal): separate startup commands from live input * fix(terminal): run POSIX startup commands from shell prompt hooks * fix(terminal): preserve staged commands in shell-owned startup * fix(terminal): correct startup types and release spawn environment * fix: keep startup prompts usable during agent restore * test: run startup prompt regression in the native runtime * fix(zsh): retire deferred startup callback safely * test: make shell readiness fixtures satisfy timing checks
…blyai#33632) * test(native-chat): preserve mixed drops through question submission * test(native-chat): complete send harness setup * test: remove duplicate delayed mixed-drop case
stablyai#33621) * fix(codex): keep the Codex app's bundled plugins in Orca-managed homes Codex only loads the openai-bundled marketplace when its source sits under the active CODEX_HOME. The config mirror copied ~/.codex's source verbatim, so managed homes silently dropped bundled plugins such as visualize. Link ~/.codex/.tmp/bundled-marketplaces into managed homes and rebase the mirrored source onto it. * fix(codex): rebase bundled marketplace onto the canonical managed home Codex canonicalizes CODEX_HOME before comparing the bundled marketplace source, so a managed home reached through a symlink (symlinked userData, /tmp on macOS) was still rejected.
… hosts without ps (stablyai#34519) * fix(ssh): prove a recycled server PID exited on hosts without ps On slim Linux images that ship no ps, the managed server's liveness probe could not read the recorded PID's argv, so after a reboot a PID that now named another process read as LIVE (same user) or UNKNOWN (root). The wake then refused to start the stopped server, the update deferred on the terminal census, and the host stayed unreachable. Read argv and the zombie state from /proc when ps is missing. Fixes stablyai#34149 Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(ssh): name argv-less PIDs from /proc stat; annotate e2e timeout Kernel threads and zombies have an empty cmdline, so a recycled PID owned by one stayed UNKNOWN on hosts without ps. Quote the stat pattern so the probe also parses inside command substitution on older bash. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(ssh): fall back to the stat line only after cmdline was read A failed tr must stay unproven rather than make a live server's PID look recycled. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…#34171) * fix(gitlab): keep paging merge requests when GitLab omits the totals When total headers are absent, a full response advertises another page to probe and a short response ends pagination. Keep the existing header precedence and unknown total count. Tracked in stablyai#33800 * test(gitlab): cover MR pagination exhaustion and header precedence * test(gitlab): verify unknown-total metadata across list consumers * test(gitlab): cover remaining screen consumers of list metadata * test: use checked GitLab RPC runtime fixtures --------- Co-authored-by: Hotragn <103170876+Hotragn@users.noreply.github.com>
…34173) * fix(tasks): make Linear list section headers collapsible * test(tasks): cover Linear section collapse and keyboard activation * test(tasks): bound Linear section toggle work at scale * fix(tasks): compose Linear section surface with standard button * fix(tasks): keep section keyboard focus inside the row --------- Co-authored-by: Isaac Mello <dzordinetwork@gmail.com>
) * Correct GitLab MR check status for failed and manual pipelines Use the same single-MR read for linked and branch-discovered reviews so a list summary cannot hide a failed pipeline. Preserve lookup failures for strict callers and keep detail reads within the existing branch cache. Set mergeable manual pipelines to neutral without claiming an unrun stage passed; keep blocking manual pipelines pending. Co-authored-by: Son of Odin <2700975-son-of-odin@users.noreply.gitlab.com> Co-authored-by: Emily <hadikcze@gmail.com> * test: cover GitLab MR check status consumers * test: type GitLab MR fixtures from mapper input * chore: document GitLab MR boundary assertion exceptions * test: share GitLab MR producer and consumer fixtures --------- Co-authored-by: Son of Odin <2700975-son-of-odin@users.noreply.gitlab.com> Co-authored-by: Emily <hadikcze@gmail.com>
* fix(gitlab): retain successful hosts from partial auth failures Read rejected auth-status output without treating failed host headings or API error advice as successful logins. Publish positive results through the existing context-owned cache; keep backoff when no login succeeds. Co-authored-by: David Anderson <cantspamdave@gmail.com> * fix(gitlab): preserve discovery retries with partial host evidence * fix(gitlab): escape auth marker for ASCII server bundle --------- Co-authored-by: David Anderson <cantspamdave@gmail.com>
…#34185) * fix(github-project): render linked PR and sub-issue progress values * fix(github-project): probe schema support for project column values * fix(github-project): preserve independently supported project fields * Preserve nullable project values and unsupported fetch concurrency * Exercise project relation payloads through unchanged consumers * Combine project coordination test cache imports * Use checked project payload types in consumer tests * Place project provider column contract in cross-layer tests --------- Co-authored-by: Wooseong Kim <innocarpe@gmail.com>
* fix(tasks): derive preset highlights from the applied query Reuse the parsed query and already loaded viewer login for personal preset matching. Keep the stored preset field for resume and task-kind behavior. Co-authored-by: 0668000615 <wen.xiaosong@xydigit.com> * fix(tasks): limit preset identity matching to known sources * fix(tasks): wait for source identity before matching viewer aliases * fix(tasks): match preset highlights to query tokens Require the effective open state and recognize personal presets by their @me query tokens. Remove viewer identity matching while preserving existing preset persistence and task-kind behavior. Co-authored-by: 0668000615 <wen.xiaosong@xydigit.com> --------- Co-authored-by: 0668000615 <wen.xiaosong@xydigit.com>
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
…ntime host's create (stablyai#34525) A desktop-scheduled automation whose project lives on a managed Orca server sent its dispatch token to the server, which never minted it and rejected every run with "Invalid automation provenance request". The token now goes only to this desktop's own create. Fixes stablyai#34433
…yai#34504) * Add native chat hand-off menu on main * Fix saved chat hand-off observations and RPC exports * Reuse indexed chat tabs for hand-off subscriptions * Match saved-chat clear fixture to current journal API
…tablyai#34500) * Stop unrelated host status publications rebuilding sidebar workspace state * Follow sidebar selector lint conventions * Scope sidebar status reads to mounted consumers * Cover each unrelated sidebar status publication * Fix sidebar isolation lint and formatting * Type the composed sidebar header fixture without assertions * Remove unused React imports from sidebar contract tests * Reuse folder record selector and prune stale focus allowance
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
* fix(chat): link naming failures to chat name settings * fix(chat): hide naming settings link when controls are unavailable
…ablyai#34177) Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
…scan closed (stablyai#34534) * feat(wsl): note why an idle distro stays held, and fail the holder's scan closed When user work keeps the holder from releasing, it writes the first few process names (at most 5) to ~/.orca/wsl-holder-blocked, replaced whole and cleared on release, for the desktop to read later. A /proc without the holder's own entry, or a status file it cannot parse, now keeps the hold instead of reading as idle. * fix(wsl): count an unreadable /proc entry only when it is the user's own Review of stablyai#34534: under hidepid=noaccess root's status files are unreadable, so each read as this user's work and the distro never released. An unreadable entry now counts only when its directory belongs to this user. The holder also clears a half-written note on start and rewrites the note only when it changed.
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
…urce mode (stablyai#34537) * feat(editor): VS Code markdown highlighting and sticky headings in source mode * fix(editor): address review on markdown TextMate highlighting - resolve fence grammars from the first word of the info string - give fence grammars the cold-compile retry budget - fall back to Monarch markdown when TextMate fails to load - bound heading-scan line length
…s and Gitea detection (stablyai#30808) Fold every forge SSH host alias (ssh.github.com, altssh.gitlab.com, ssh.bitbucket.org) through one shared normalizeForgeWebHost so main-process provider detection and renderer manual review links agree. Remotes on ssh.bitbucket.org now open bitbucket.org pull request forms instead of ssh.bitbucket.org URLs, and Gitea no longer claims the host. Co-authored-by: Eric Junker <4758+ejunker@users.noreply.github.com> Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com>
…ane terminal (stablyai#31815) The terminal context menu only showed a close item when the tab had split panes. A single-pane terminal now offers "Close tab", which sends the same close request as Cmd/Ctrl+W. Pinned tabs and one-off command terminals keep hiding it, matching the pane header's close button via a shared canCloseTerminalPane/terminalPaneCloseLabel. Fixes stablyai#20598 Co-authored-by: Neil <neil@stably.ai>
… hosts (stablyai#34865) * perf(renderer): release reconnect observers for removed hosts * fix(renderer): forget model-catalog lists of a removed host --------- Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
…and measure a 100 MB read on WSL (stablyai#34882) Follow-ups from the large-file audit (E7): - files.search had no byte budget: a result past the remote reply cap failed outright with reply_too_large. It now keeps the whole files that fit and marks the result truncated, as files.listAll and searchPaths already do. Local callers stay uncapped. - A diff side past the 10 MiB read cap came back as binary, so the diff said "Binary file changed" for a large text file. Blob reads mark it `tooLarge`, the binary diff result carries an optional `tooLarge`, and both diff views say "File too large to diff". Older clients ignore the field and keep the binary view. buildDiffResult builds its binary sides without a cast. - The real-WSL lane pages a 100 MB file over the plain distro's shared control socket in the editor's 384 KiB chunks and records the time, chunk count and orcad's VmHWM. Record-only: it asserts nothing, and a failure is recorded in the receipt.
…#34773) Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
…ai#31180) * fix(native-chat): a refused queued message still blocks the queue when its card write fails Every reader of a queued card goes through one derived view of the journal's dispatch facts, so a card whose message was refused reads as returned even when its card-table update and heal both failed. One decision and one writer store the derived state for every action. * refactor(native-chat): keep each queued message in the chat's journal, not a second table A queued message lived in its own SQL table, and a hook that may be skipped copied each refusal from the journal into it. When that write failed, a refused card vanished: the cards behind it sent, and its Send and Delete did nothing. Each queued message is now a `queue` row in the chat's journal beside the submission that hands it off and the dispatch row that answers it. The reducer folds the card from those rows, so a refusal returns the card and holds the cards behind it with nothing written, and replay reads the same. Every action writes its own rows in one transaction. Cards an earlier build stored are read through the same classification until they move: each action moves its own card, and a bulk import runs once per open. A new epoch restates every card still owed an answer in the transaction that deletes the old rows. The settlement hook and its savepoint, the open-time heal, the drain's heal and the derived-card view are gone. The published card list is unchanged. * test(native-chat): adapt the queue tests to cards kept in the journal Cards are written through the journal, so tests queue them with their body alone and hand them off under their real fingerprint. Tests of the removed settlement hook, heal and SQL store are deleted; the text-update spec now covers the edit decision alone, and a test of an earlier build's stored holds seeds the legacy table and reads the imported cards. Rolling over an epoch now keeps a card whose hand-off was never handed over, so that test checks the retried id never sends rather than that nothing sends. * test(native-chat): a refused card holds the queue through rewind, a new epoch and a restart One whole-flow test through the host: the refusal writes no card row, a rewind that retires the refused hand-off and a rolled-over epoch keep the card returned, a restart and Resume send nothing behind it, its own Send refused again still holds the queue, and its Delete releases the next card in order. * test(native-chat): an earlier build's queued cards move into the journal once, each read the same One mixed-import test through the host. The first open's import fails and moves nothing, yet every card reads as it will; Delete and Send each move only their own card. The next open moves the rest in one transaction, writing a refusal only where its hand-off is gone, nothing for answered cards, and leaving an unreadable row on disk. A later command turn spends a moved command card, a third open writes nothing, an old Delete replays from its receipt, and a chat with only answered legacy rows clears them in a delete-only transaction. * test(native-chat): adapt typechecked tests to cards kept in the journal The row-kind table lists a queue row, the clear and legacy-import tests match the current signatures, and the downgrade test keeps only the leftover-send case: a queued card is now a newer-version journal row an older build keeps read-only, and users don't downgrade. * refactor(native-chat): drop the journal row writer's unused transaction hook No caller passes one since the queue's savepoint bookkeeping left. * test(native-chat): downgrade probes write rows at the version older builds read The highest version this build reads is now 4, the queue row's. A newer build's row in these probes is written at version 3 so the older build meets its kind, not a newer version, and the Stop-event probe hands the older build the rows as stored, since a read raises each row's version. * test(native-chat): unit tests follow the queue row's version 4 The legacy-import test opens real SQLite, so it runs in the Node runtime project. The newest version this build reads is now 4, and a read raises a row's version to it, so the turn-lifecycle test no longer pins the in-memory version (the written one stays pinned by journalRowSchemaVersion). * fix(native-chat): one batch echoing two refused queued messages spends both The per-row delivery check returned only the first waiting card an echo proved delivered, so when one settlement carried echoes for two cards the second stayed waiting and was sent again. It now returns every card the row proves delivered, and the fold withdraws each; replay folds the same. * fix(native-chat): a rewind moves an earlier build's cards into the journal first While the open's import had failed, an earlier build's card that read as refused through its hand-off lost that reading when an in-place rewind retired the hand-off: it disappeared and the card behind it sent. The rewind now adopts every legacy card ahead of its tombstones and deletes their rows in its own transaction, as an epoch replacement already does, so the fold latches each card's reading before its hand-off is gone. * fix(native-chat): keep an earlier build's card whose hand-off is still unconfirmed The import dropped a legacy card handed off as a send whose delivery was unknown, though the fold keeps such a card linked and a later refusal returns it. The import now keeps every card whose hand-off a later row can still answer, through the same check the reducer folds dispatch rows by. * fix(native-chat): one delivery echo withdraws at most one queued card One provider echo proves one delivery, yet it withdrew every waiting card with the same text whose hand-off was refused, so a second identical card was lost. The fold now pairs each echo with one card: on its own row the earliest-positioned match no other echo of that row took, and for a card that waits again the earliest applied echo no card has taken. Paired echoes live in the fold's state, so live and replay pair the same; readers of cards not yet imported work on a copy. * fix(native-chat): a queued message handed to the agent is sent again only on proof it never got it Pressing Stop after Orca handed a queued or steered message to the agent, before the agent confirmed it, put the card back in the queue, and Resume or the next send sent it again. A check matching the agent's echo of the text was the only guard against a double send, and it kept trading a resend for a lost card. Whether the card waited again was decided by the rejection's category, not by proof the agent never got the message. A refused hand-off now waits again only where Orca proves the agent never received it: the host still held it, or whoever settled it recorded that. A failure still returns the card and holds the cards behind it. Anything else may have reached the agent, so the card is spent and its message reads as sent, derived on every fold from the stored rejection: with the turn it was answered into, as that turn's unconfirmed message where it was handed over; withdrawn before any turn opened, as a person's own send a Stop took back. The reopen mark ignores a recovered doubt, and the restart reconciler no longer judges a queued hand-off unsent from what history lacks. The echo text matching and its pairing are deleted. A close or quit while the agent starts settles sends with the unrun hold. The host hands nothing to a child before its start answers (structured-agent-session-delivery-loop.ts: a handover needs phase ready), so such a send went to an earlier child and may have run: it now reads as sent instead of waiting again. * fix(native-chat): Claude's report that it removed a queued message unrun lets the card wait again Claude says when it removed a send without running it: the interrupt receipt's cancelled list, or a command_lifecycle cancelled, discarded or refused frame for a command that never started. Every one settles through rejectClaudeDispatchWaiters, which now marks the settlement unrun. For a queued card's hand-off the host records that as proof the agent never got it, so the card waits again under the queue's pause. A direct send keeps the plain refusal: there the proof would owe it as stopped history. * fix(native-chat): an earlier build's card stopped after hand-over follows the same rule on upgrade Earlier builds put a card back to waiting after any refusal without a verdict and cleared its link, so a card the agent may already have would be sent again after the upgrade. The card's own hand-offs in the journal decide now: unchanged and last sent as one that may have reached the agent, it is spent on that hand-off and its message reads as sent; edited or sent again since, it is held for its own Send under a host-only marker that publishes as a plain hold; with no hand-off in doubt, including one that never left Orca, it waits as before. The import writes a card spent on a hand-off in doubt, so its message shows. * fix(native-chat): read a queued row's hand-off before the lookup that uses it The lookup's callback lost the narrowing of the row's change, which the mobile test typecheck rejects. * test(native-chat): a card steered into a turn a Stop ends stays sent in the Stop tests Three tests pinned the old rule, that a card handed into a running turn comes back to waiting when a Stop ends it. Under the new rule nothing proves the agent never got it, so the card is spent: with the turn named, its message reads as that turn's unconfirmed one; without, as a send the Stop took back. Neither is ever sent again. * fix(native-chat): a queued message stopped before Orca handed it to the agent waits again A Stop that aborts a hand-off after its row is written but before the agent call now records the withdrawal as never reaching the agent, for queued hand-offs only, so plan D's rule returns the card to waiting under the Stop's pause instead of spending it. Direct sends keep the plain withdrawal (the flag would owe them as stopped history). The agent's own refusal while aborted is kept rather than overwritten, and an abort thrown during the call stays in doubt. * fix(native-chat): a queued message stopped while the agent prepares it waits again The abort signal reaches only an adapter's preparation (its options, the previous turn opening), never its write, so the signal's own reason thrown back is the adapter saying nothing was written. The handover now reads that, for queued hand-offs only, as never reaching the agent, so the card waits again under the Stop's pause. Claude no longer wraps that abort as an option refusal, which had returned a stopped card as a refused one blocking the queue. A real refusal keeps its cause and its barrier; any other throw stays in doubt and is never resent. * test(native-chat): the usage-limit Continue backlog case writes its card through the journal queue Main's stablyai#30396 wrote its backlog card with the stored fingerprint and host-instance stamp the journal queue derives instead; the card the Continue must yield to is the same waiting card. * test(claude): the real-CLI queued Stop expects the unrun mark Claude's cancelled-unrun receipt carries * feat(mobile): edit a queued message's images on the phone: remove or attach * fix(mobile): gate queued image edits on the host reader verdict * test(mobile): declare the upload fixture chat mode * fix(native-chat): retain spent legacy messages when import fails * fix(mobile): reveal the full queued image editor on open * fix(mobile): invalidate queued editor geometry without a render ref write * refactor(chat): prepare composer drafts and measured queue dragging * feat(native-chat): add conditional queue removal and authoritative reordering * feat(native-chat): move queued edits into the normal composer on desktop and phone * fix(native-chat): own complete phone drafts before authoring * fix: preserve submitted composer drafts across storage replacement * fix composer validation and mobile CI diagnostics * fix mobile composer test contracts and diagnostic output * Capture mobile test compiler diagnostics in CI * Fix queued message contract typing and English strings * test: complete queued extraction transport fixtures * refactor: separate composer skill binding from send mutations * fix(mobile): grant draft storage within route limits * fix(native-chat): settle each draft save on its own and publish complete composer drafts Phone: a queued Edit copy no longer consumes the save that later typing owns. Each ordinary save and the exact copy settle only their own result; an explicit save waits for its own pending write, and a failed or retired write never schedules another or revives the copy. Desktop: a pasted-text leaf no longer shifts which selected file binds where, and a hand-back held during an IME composition reaches the store only merged with the visible editor document, including writes the editor admits without an update and the composition settle. * fix(native-chat): import the draft type once in the draft cache * test(mobile): type the held-write state without an assertion * test(native-chat): assert the handed-back file on Send without reading a typed transport as a mock * test(mobile): pass main's agent-confirmed flag to the submitted-files harness * fix: reveal queued reorder grip on touch screens * fix: save reopened phone drafts and batch reorder measurements * test: use an explicit React module type * Preserve queued message sortable identities on unchanged renders * Prevent stale queued drag completion after unmount * fix(mobile): hand off navigation across session workspaces * test(mobile): use resolved session identity in dictation fixture * feat: edit queued messages inline with the chat composer * fix: normalize queued edit skill ownership * fix: retire phone skill selections with the sent draft * fix: consolidate queued edit module imports * fix: separate edit save action and stabilize image callbacks * fix: complete phone inline composer integration * fix: retain same-name queued skill selections * fix: complete desktop queued composer integration * test: use typed phone composer host lookups * fix: include queued edit localization keys * Preserve inline edit input across save and attachment completion * Preserve complete queued edits across delayed saves * Preserve queued edit input across delayed completion * Complete queued edit lease loss and pending cancellation * Use recognized queued edit test fixtures * Consolidate queued edit imports and type host test spy * Print mobile test compiler diagnostics on ratchet failure * Correct queued edit integration fixture types * fix: keep queued edit placeholder independent of readiness * Fix queued edit compiler fixture boundaries * Align upload completion test with ordinary insertion * Combine mobile composer draft imports * Load queued edit host fixture during test collection * Size inline phone queue editor to available space * Use typed scroll components in phone presentation contract * Save typed text in a queued edit as written The inline editor is the chat composer, so it keeps the composer's own identity model and no longer refuses Save for text that looks like a command. Command rows picked from the menu are still refused, Enter still means Save, and Edit never sends or runs anything. Regression tests cover Undo after deleting an accepted command or skill pill, a scanned skill named like a command, two saved files behind one token, and typed command text saving literally. Also fixes two merge leftovers in tests: a missing import and a fixture that stored the whole menu row as a skill. * Keep ordinary sends on the main composer contract * Fix mobile composer imports and fixture loading * Consolidate queued edit imports and duplicate regression * Restore ordinary send catalog short circuit and repair test boundaries * Preserve returned rich drafts through send acceptance * Remove obsolete queued editor strings from new locales
…e host's server update during a move (stablyai#34823) * fix(wsl-mover): settle an interrupted move automatically, and hold the host's server update during a move An app update or crash between sending a move's copy and the host's commit leaves a `blobs-transferred` record. Startup recovery has no host to ask, so the projects stay fenced, and the automatic mover only previewed, which refuses an in-flight move, retrying forever. The projects stayed read-only until the user started the move from the dialog. The automatic mover's preview now settles that record first (through the host: back to zero, or forward when the host committed), holding the distro's run while it does so it never races a move the user starts. The dialog's preview stays read-only. The preview moves to its own module. A Settings Update or Force, or any reconnect, could also redeploy the host's server in the middle of a move, cutting it off (safe, but the move is lost). Once a running move has journaled, a version-changing redeploy now keeps the running server and reports the update as waiting for the move, mirroring the SSH path's skip while migrating. The move's own first connect, before it journals, can still update an outdated server. * fix(wsl-mover): an automatic settle never reloads the window, and never holds its own host update Review of stablyai#34823: - A settle that finds the host committed ran the desktop rewrite, which reloads the window past its unload veto. From the automatic mover it now records the commit only (the projects stay fenced), and the next start's rewrite pass finishes it before any window opens. A move the user starts still finishes at once. - The server hold counted any unfinished record of the distro, so an automatic settle of an old record with an outdated server was held, refused for an update, and retried the same way. The hold now counts only the cutover the running move journaled itself. * fix(wsl-mover): let the user finish a committed move in-session; park the automatic mover meanwhile After an automatic settle records a commit for the next start, nothing could finish it in-session: the user's Move refused as already in flight and the orchestrator retried for nothing. - A settle that finds the head committed but not yet rewritten on this desktop finishes it now when the user asked (their Move, or the status line's Retry), returning the existing "finished an earlier move" answer; the automatic mover still leaves it for the next start. - The automatic refusal carries detail `finish-pending`, which parks the distro (new reason `finish-pending`) instead of retrying; the next start, whose rewrite pass finishes the move before any window opens, puts it back to pending. - The park rules move to wsl-move-orchestrator-park.ts. * fix(wsl-mover): give the finish-pending park its own status line Main's move status line (stablyai#34676) names every park reason; the finish-pending reason this PR adds needs one: the earlier move is done on the host, and finishes here at restart or with Check again.
…open on the chat's host (stablyai#31781) * fix(native-chat): open sandbox: images and files on the chat's host Agents sometimes cite files they wrote as sandbox:/abs/path. Markdown sanitizing dropped those addresses, so the chat showed only alt text and an inert link. Chat Markdown now rewrites sandbox: links and sandbox:/file: images to the chat's own file hrefs before sanitizing, and the shared href router reads sandbox:/abs as the absolute path on the chat's host. A paired host now grants a chat client a read-only exact-path grant for any host file the chat links, instead of searching the chat transcript for the path. The search missed structured chats, Markdown link targets and older replies, and guarded nothing: a paired client can already run commands on that host. The grant still refuses network shares, device paths, hardlinks, pipes and sockets. Desktop chat links and images now send their chat to the host, so files outside every workspace on a paired host open and render. A chat link the host does not have is reported missing there and never read from this computer. * Fix chat file reference and granted file actions * Keep granted chat files on existing read-only tab route * Remove accidental package manager lock metadata * Match WSL artifact descriptor fixture to regular file stats * Fix canonical host image grant acquisition * Fix host image test transport request typing * Drop sandbox: address handling from native chat links sandbox:/mnt/data placeholders belong to a hosted code tool that swaps them for its own download links; they never name a file on the chat's host.
…ai#34776) * perf(browser): throttle idle guests between active operations * perf(browser): lease only the guest for non-capture agent commands Keep the renderer paint hold, host unthrottle, and host re-hide readback on capture paths only, and never let the one-way paint-hint send fail the capture. * style: format bridge paint-hold test --------- Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
…/2) (stablyai#34694) * feat(wsl): admit no new WSL host or move in serve-only Main refuses wslHosts:add while the internal gate is closed and reports acceptsNewWork in the WSL host capability; moves already need the open gate. The renderer hides Add WSL distro and every Move entry point once main says serve-only, while saved hosts keep their Connect and Remove. * fix(wsl): offer no new WSL host or move until main answers the capability The renderer's acceptsNewWork now starts false, so Add WSL distro and the Move entries never flash in serve-only before the capability reply. * fix(wsl): point the WSL-bridge chat refusal at Add WSL distro only when it is offered In serve-only Add WSL distro is hidden, so the refusal keeps its terminal-only words there. * test(wsl): give the move status-line test's hosts mock the new-work hook stablyai#34676's test mocks use-wsl-hosts-enabled; WslHostsSection now also reads useWslHostsAcceptNewWork, which follows the same gate there.
…removed (stablyai#34914) stablyai#34650 removed dashboardPopout.terminal.closed from en.json, but ru.json, tr.json and zh-Hant.json kept it, so verify:localization-catalogs fails on main ("extra: dashboardPopout.terminal.closed"). Drop it from those three. No other locale has extra keys; ru's _few/_many plural forms are expected.
…#34675) * fix(terminal): allow automation during phone control * test(terminal): specify driving input in IPC admission fixture * test(terminal): delegate preview input through host admission
…tablyai#34774) Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
* fix(terminal): preserve Codex exit queries across snapshot restore * fix(terminal): replay owed queries from discarded output and superseded replays - Mark yielded queries discarded when ACK overflow trimming, the recovery cutoff, or snapshot-buffer overflow drops their output unsent, and replay them after the covering snapshot (including the ACK recovery snapshot). - Purge snapshot query replays and escape-tail frames still queued behind the ACK window when a newer snapshot is published, and put new replays at the head of the ACK queue so they follow their snapshot. - Share isPrimaryDeviceAttributesQuerySequence across DA1 call sites. - Move replayed-query settlement into settleReplayedYieldedQuery. * fix(terminal): replay DA1 still batched when an ACK recovery snapshot covers it * test(terminal): type the overflowed initial-snapshot stream fixture * test(terminal): give the host-chain recovery stream fixture its required query and batcher state
…lyai#34775) Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
… under max-lines (stablyai#34929) * fix(i18n): drop queued-message keys stablyai#31180 removed from en stablyai#31180 removed components.native-chat.queuedMessages.cancelEditing, .pasteOrDropImages and .saveNeedsContent from en.json; tr.json, added since, still carried them, so the locale catalog check failed on main. They are the only stray keys in any locale. * fix(lint): split runtime-file-read-client under the max-lines cap Move the remote chunked-download helpers into runtime-remote-file-download.ts so runtime-file-read-client.ts is back under the 300-line lint cap. No behaviour change.
…ai#34907) * fix(export): cancel PDF work when requesting document retires * test(export): assert success on non-retired repeated export cycles --------- Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
…4896) Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
Upstream range df95be4..36d2956, 335 commits. 12 conflicted paths, 13 hunks: 11 both modified and 1 modify/delete. Conflicts: - AGENTS.md (#26): upstream's reworded test line (stablyai#34507); the fork's section stays. - Locale catalogs (#6 #7 #9 #10 #13 #14 #17 #31): upstream's catalogs plus the fork's keys. en.json drops the "idle" key upstream retired (stablyai#22056) and keeps the fork's 14 update-source keys; es, ja, ko and zh keep upstream's new terminalPane.hostFile beside the fork's AgentResumeChooser. - server-ingest-remote.ts (#30): upstream stablyai#34724's IncomingAgentHookEvent and codexRosterAuthority beside the fork's reportsUserEndedSessions. - pty-management.ts (#25): upstream stablyai#32153 tracks the generations whose listing failed. Each listed session still carries the adapter that listed it, and the kill poll keys a failed listing by that adapter, not by protocol version: a drained daemon shares the current one's version. - main-process-ready-runtime.ts (#16): upstream stablyai#34059's WSL-move rewrite pass and the fork's mac self-update launch report both run after the first window. - GeneralUpdateSettingsSection.test.tsx (#14): upstream deleted it as low-value (stablyai#34370); the fork's two cases move unchanged, with the setup they use, to GeneralUpdateSettingsSection.single-source.test.tsx. - pane-agent-evidence.test.ts (#6) and terminal-mode-reset-profiles.test.ts (#11): upstream's test removals (stablyai#34612, stablyai#34520); the fork's cases stay, with the imports they use. Breaks the conflict list did not show: - server-ingest-remote.ts reached 305 counted lines (max 300); upstream's copy is at exactly 300. The fork's lines leave it: the relay's user-ended notice is read where payload validation drops it, which is where the notice was designed to stop, and the fork-owned withRelayUserEndedSessionReports in server-terminal-loss-resume.ts stamps reportsUserEndedSessions. Now 299. - Upstream's new ru, tr and zh-Hant catalogs (stablyai#34717, stablyai#34718, stablyai#29795) carried "Orca" for the titlebar key the fork changes in every catalog (#7 #13 #31); they take the fork's value. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 task done
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. |
Author
|
CI after the merge (advisory for syncs): 108 passed, 6 failed, 1 cancelled, 2 pending. None of the failures is in a file the fork changes:
The fork build for |
kiwidream
added a commit
that referenced
this pull request
Oct 28, 2026
Resolve the en.json conflict by keeping both the leaderboard keys and the keys from sync #64. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 28, 2026
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.
ELI5
Upstream Orca moved forward 335 commits since yesterday's sync (#62). This PR merges them into
swaplabs/main. 12 files conflicted with fork changes, all resolved by keeping both sides. Two more things broke without a conflict and are fixed here. Nothing needed an operator decision. This PR replaces #63 (headmain), which could not merge.What Changed
Upstream range
df95be4090..36d295628e, 335 commits (compare). One signed merge commit,dd8ce6ed87(Merge upstream main (36d295628e) into swaplabs/main), onsync/upstream-20261028, cut at the integration head7d5ebba0c2.Conflicts, by fork PR (
orca-fork-ops conflicts)AGENTS.mdsrc/renderer/src/i18n/locales/{en,es,ja,ko,zh}.json"idle"); newterminalPane.hostFileen.jsonkeeps the fork's 14 update-source keys without the retired key; es/ja/ko/zh keephostFilebeside the fork'sAgentResumeChooser. The fork's delta in each catalog is unchangedsrc/main/agent-hooks/server/server-ingest-remote.tsIncomingAgentHookEventand addscodexRosterAuthorityreportsUserEndedSessions(then moved, see below)src/main/ipc/pty/pty-management.tslistSessionsOfEveryAdapter,listingIncomplete,confirmNoDaemonSessionsRemain)src/main/startup/main-process-ready-runtime.tssrc/renderer/src/components/settings/GeneralUpdateSettingsSection.test.tsx(modify/delete)manualInstallUrldownload link), so they move unchanged, with the setup they use, to the fork-ownedGeneralUpdateSettingsSection.single-source.test.tsx, as the table does for a deleted docsrc/renderer/src/lib/pane-agent-evidence.test.tsresolvePaneScopedLaunchTuiAgentcases and import staysrc/shared/terminal-mode-reset-profiles.test.tsPROCESS_BOUNDARY_GROUND/POST_REPLAY_MODE_RESETcase stays, with itsPOST_REPLAY_MODE_RESETimportBreaks the conflict list did not show
server-ingest-remote.ts: 305 counted lines, max 300user-ended-sessionis one no host admits, by the notice's design, and it carries none of the fields checked in between.reportsUserEndedSessionsis stamped by the fork-ownedwithRelayUserEndedSessionReportsinserver-terminal-loss-resume.ts, besideretireRelayUserEndedSession. Now 299src/renderer/src/i18n/locales/{ru,tr,zh-Hant}.json"Orca"for the titlebar key the fork changes in every catalogForca{{value0}} (SwapLabs{{value1}}), so the titlebar keeps the fork name, version and revision in those languagesFork delta check: each of the 336 files the fork changes, before or after, was compared against upstream on both sides of the merge. 326 keep exactly the same fork lines. The other 10 are the changes listed above.
Some notable upstream changes in the range
Why
Daily upstream sync.
Linked Issue
N/A: daily upstream sync. Supersedes #63. Follow-ups: #65 (fork strings untranslated in pt, ru, tr and zh-Hant), and comments on #45 (the
server-ingest-remote.tsmove) and #44 (the drain's kill poll).Visual Proof
N/A. The only user-visible fork change is the titlebar name in the three new languages, which now matches every other language.
Testing
All checks ran on the merge result in the sync worktree, before the commit:
pnpm install --frozen-lockfile.pnpm tcpasses. A deliberate type error in a scratch edit made it fail, so the gate is live.pnpm lint, all 36 steps pass. The first run failed onserver-ingest-remote.tsmax-lines (305), fixed above.check:code-quality:changedwithORCA_SYNC_PR_DIFF_BASE=36d295628e: 0 findings across 313 fork files.src/main/agent-hooks,src/main/ipc/pty,src/main/startup,src/renderer/src/components/settings,src/renderer/src/i18nandsrc/renderer/src/app-shellwhole,pane-agent-evidence.test.tsandterminal-mode-reset-profiles.test.ts: 687 files and 6,332 tests passed, 73 skipped, none failed. This run unset the host'sORCA_*environment, which this agent's terminal exports.orca-runtime.test.ts, which runs the fork'sorca-runtime-testsspecs, passed with fixture signing off: 1,498 passed, 3 skipped. The fork's three Playwright e2e specs were not run.wsl-relay-user-ended-session.test.tsandserver-terminal-loss-presence.test.tsrun a real relay and host end to end, and all 18 tests pass. Each moved piece was also removed in turn: without the notice's retirement 3 tests fail, and without the stamping 7 fail, so both are covered.pty-management.test.tspasses, including the fork's "routes to a drained daemon that shares the current protocol version" and upstream's failed-listing cases. No test covers a drained and a current daemon of the same version where only one listing fails, the one case where keying by adapter differs from keying by version.oxfmt --checkreports all 4,309 staged files formatted (afterpty-management.tswas formatted).oxlint, its JS-plugin and React Doctor configs, andast-grep scan --min-severity warningpass over the 4,148 staged code files. The hook then ran normally, and the tree before the commit (3355fbea76) equalsHEAD^{tree}after it.dd8ce6ed87isGfrom the sync keyBF1DD75F888E96080C2453E2D9E158C5D6874235.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(7d5ebba0c2) against upstream36d295628e, before this merge:LOCAL:prefix and have no upstream PR.Upstream release tag
v1.4.243was copied to the fork.🤖 Generated with Claude Code
Need help on this PR? Tag
@codesmith-botwith what you need.