* perf(mobile): show the workspace list from memory and refresh it on desktop changes
* fix(mobile): import the host list queries type without an import() annotation
* fix(mobile): keep host labels on a not-connected read and update the phone feed e2e helper
* fix(mobile): keep the event router listening when its stream ends while opening
* fix(mobile): reuse the shared read-view base and remount for the cache-return recording
* Prepare queue rows to preserve accepted delivery intent
* Keep waiting native chat input in one ordered queue
* Keep a typed view of admitted queue records
* Keep the removed queue caption in the runtime catalog
* Remove the unused queue barrier caption
* Keep queue writes local and preserve accepted send provenance
* Read the sender from the queued admission request
* Keep continuation fixture clock within its operation window
* Remove deleted queue-barrier test from ratchet baseline
* Keep ratchet baseline change scoped to the deleted test
* Filter historical acceptance reads before loading payloads
* Instrument cached acceptance cursor once per fixture
* Restore original personal provenance after legacy card cleanup
* Complete legacy sender fixture metadata
* Narrow admitted history record types
* Reconstruct accepted personal proof after restoring original admissions
* Use the fixed clock for historical queue fixtures
* Consolidate queue source and type imports
* Preserve admission refusals and failed startup ownership
* Keep manual queue holds independent of later turn endings
* Remove obsolete mobile queue barrier expectations
* Keep journal format initialization independent of its decoder
* Assert returned-row recovery for released send clients
* Preserve Stop assertion across handoff-only publication
* fix(agents): workspaces created on a paired host use the host's launch settings
Creating a workspace with agent picks or a draft could launch the paired host's agent with desktop settings, or lose the picks during recovery. Let capable hosts compose those launches from their own settings and preserve the user's inputs through fallback creation. Older hosts retain their existing requests.
* fix(agents): workspaces created on a paired host use the host's launch settings
When a workspace is created on a paired computer, agent picks and Arguments can be replaced by this computer's defaults or dropped during recovery. Keep explicit choices with the submission and let the paired computer resolve its own launch settings.
Preserve older-host request behavior, disabled-agent draft substitution and prompt submission, and restore the composer if compatibility preparation fails.
* fix(agents): workspaces created on a paired host use the host's launch settings
Keep the submitted choices available when a background launch has no prepared startup carrier. Tighten the regression checks for restored composer names, legacy commands and prompt submission so recovery preserves the user's work.
* fix(agents): workspaces created on a paired host use the host's launch settings
Creating a workspace on a paired machine could ignore its agent settings or lose a draft while the terminal connected. Keep the selected launch inputs and the pending text together through fallback and reconnect, and never replay partially written input. Preserve older hosts' launch commands and ordinary new-tab prompts' editable behavior.
* fix(agents): workspaces created on a paired host use the host's launch settings
Keep a workspace's pending prompt attached to its original terminal while the pane reconnects. Stop automatic delivery before reporting a final failure, retain the recoverable text, and recognize a launch handed off to the paired host even before its tab appears. Avoid delaying creation on a redundant host status request.
* fix(agents): workspaces created on a paired host use the host's launch settings
New workspaces on a paired computer could lose their first prompt when the terminal briefly disconnected. Delayed delivery could also continue after reporting failure, or leave terminal-only agents without an accessible copy of their prompt.
Keep pending prompts through attachment loss, stop content writes when automatic delivery ends, and offer the existing composer to recover unsent text. Preserve launch identity without inventing empty Arguments or treating missing metadata as a replacement.
* fix(agents): workspaces created on a paired host use the host's launch settings
A replacement pane can learn its terminal before the layout catches up after reconnecting. Re-registering the effective launch settings then dropped the original first-prompt identity.
Recover that identity from the existing verified terminal binding so later remounts keep the same pending prompt.
* fix(agents): workspaces created on a paired host use the host's launch settings
A terminal binding can identify the launch before its effective Arguments are known. Keep permission notifications working in that state without assuming a launch-settings recipe exists.
* fix(agents): workspaces created on a paired host use the host's launch settings
Keep an unsent prompt attached to its launch when a paired host briefly disappears, so reconnecting the same terminal can finish delivery. Clear the rest of the exited pane's status as before, and release the binding after delivery or a confirmed end.
Offer Copy prompt when automatic delivery finally fails, so the prompt can be pasted into the terminal that already opened. Keep creation-failure Reopen separate.
* fix(agents): preserve paired prompt recovery across transport updates
Resolve the consumed startup token through the pane's verified binding instead of reading renderer ownership during every remote attach. Keep the transport's host-authoritative exit and reconnect behavior and its fixture guards.
Settle pending prompt delivery when the host reconfirms a closed surface, including after it discards the terminal's exit record. Update the remount fixture for the Windows PTY model binding.
* fix(agents): merge duplicate imports flagged by type-aware lint
* test(agents): fix type assertions in paired launch fixtures
Type the repository rows, mutable agent choice and terminal tab used by
launch regressions. Reuse the session binding across its real installers
and document the partial-fixture adapters required by the runtime APIs.
Keep the RPC, remount and prompt-delivery assertions unchanged.
* fix(agents): route workspace terminals through their owning host
Creating a terminal for an existing workspace could send it to another focused server. Resolve its owning host when no explicit route was supplied, and keep the host-shaped draft regression within the shared startup contract so renderer checks do not pull in main-process code.
* test(agents): align launch fixtures with runtime dependencies
Retain real i18n exports while replacing translation output, hoist the terminal restore toast spy, and supply the explicit host environment used by paired terminal callers. Keep the existing behavior assertions unchanged.
* fix(agents): isolate prompt failure notice dependencies
Load the prompt failure notice only when a settled hosted launch needs it,
so workspace recovery consumers do not initialize toast and localized agent
catalogs just by importing delivery code. Keep prompt retirement and its
recoverable draft synchronous, and preserve the existing Copy prompt action.
Restore the ordinary new-tab failure toast's original invocation and verify
that Fix Checks retains its edited request through the activation handoff.
* test(agents): route legacy wire launches to their fixture host
Pass the paired environment explicitly in legacy terminal-creation fixtures,
matching real launch callers instead of relying on the focused host. Keep
all compatibility and accepted-creation assertions unchanged.
* fix(agents): preserve paired work-item completion without a startup plan
Blank-terminal work-item launches on paired hosts now keep their successful activation result. If the agent command cannot be built, show that error once instead of reporting an activation failure.
* refactor(agents): deliver paired creation prompts once like agent tabs
Drop the retained hosted-prompt lifecycle (pending map, rebind, deadline,
terminal retirement, token recovery). After the host creates the session the
desktop attempts the prompt once; failure shows the prompt-not-sent toast with
Copy prompt.
* fix(agents): silence prompt failures after closing a workspace terminal
Closing a paired workspace terminal before the agent was ready could report a prompt failure after that terminal was gone. Use shared launch completion and existing tab records to keep deliberate closes silent while preserving one Copy prompt notice after an interrupted delivery. Prepared launches now decide client delivery from the host request.
* fix(agents): report every failed paired prompt delivery
A paired host can retract its tab from inventory without the user cancelling the launch. Always report a failed prompt attempt with Copy prompt, using the same single-attempt completion as agent tabs.
* test(agents): name host-session fixture mock types
* refactor: place native chat media and link code with defining owners
* refactor: preserve code control copy protection after relocation
* style: format rebased native chat owner imports
* refactor(backend): use defining owners for orchestration and ACP startup
* test(orchestration): trim redundant observations and retain safety cases
* test(orchestration): seed restored sessions with one fixed operation clock
* refactor(renderer): organize host and terminal implementation owners
* fix(refactor): align active adoption reliability references
* refactor(terminal): remove forwarding shells and stale mocks
* fix(renderer): consolidate direct owner imports
* fix(refactor): route incoming issue trust type to its owner
* test(runtime): give independent status viewers separate pairing tickets
* style(refactor): normalize rebased terminal mock formatting
* fix(plugins): resolve the active workspace context on remote hosts
* fix(plugins): scope the remote workspace context to its host
* docs(plugins): document the remote context resolver
* fix(plugins): keep remote context ids raw and never fall back for local rows
The stored-row fallback returned host-qualified ids (ssh:host|repo::path), which no
terminal selector or agent-status row matches, so agents.list stayed empty for the
remote workspace. It also answered for a removed local worktree, turning a stale
focus that used to read null into a context for a workspace that no longer exists.
* fix(plugins): resolve a focused paired-server workspace from the desktop's server rows
A paired orcad server's workspaces live in that server's store, so neither the local
catalog nor the desktop's stored rows can name one and workspace.readContext,
workspace.changed and agents.list saw no context. The runtime now asks the relay host
catalog, which answers from the worktree.ps rows the desktop already caches. Only a
miss on a reachable server fetches, bounded at 1.5 s and at most once per 10 s per
missing workspace; an unreachable or hung server answers null.
* fix(plugins): keep a stale local focus stamp resolving as before, and cover #38653 end to end
A focus stamped 'local' whose repo row now routes elsewhere resolved through the
unscoped selector before #38653; the host-scoped lookup turned it into null. A
local stamp now retries unscoped, so local and unstamped focus answers exactly
what main did. Remote stamps keep the scoped lookup, so a paired-server focus
never borrows a local twin's context.
Tests: real-git parity of local, folder and SSH contexts against the pre-change
selector answer for every session shape the renderer writes; panel polling
against a hung or failing server (one fetch, one bounded wait per 10 s window);
an e2e that pairs a desktop with a headless Orca server, clicks a local and a
server row, reads workspace.readContext from a plugin panel, and keeps polling
fast after the server goes away.
---------
Co-authored-by: Neil <neil@stably.ai>
* fix(plugins): isolate development watcher retries by root
* test(plugins): keep coverage for late binding checks after housekeeping disposal
The per-root rewrite replaced the old housekeeping unit tests; restore the
disposal/coalescing case so a slow check that resolves after dispose cannot
restart a watcher or refresh, and per-root checks do not stack.
* fix(plugins): skip the full plugin rediscovery while a dev folder retry keeps failing
A maintenance retry that subscribes already refreshes itself; one that keeps failing (an
unreachable WSL share) rediscovered every plugin each tick. Only a changed root binding needs
discovery now.
Also covers what the per-root rewrite must keep: adding/removing a folder leaves the others'
watchers and frame revisions alone and releases its subscriptions, a rejecting registration
retries once per tick, Linux sibling folders keep separate parent watches, and an Electron e2e
where deleting/recreating/removing one dev folder never reloads another folder's open panel.
---------
Co-authored-by: be0hhh <182023099+be0hhh@users.noreply.github.com>
Co-authored-by: Neil <neil@stably.ai>
* fix(plugins): keep a workspace-scoped panel edit made just before a workspace switch
The guest's persist queue holds atoms, not values, and the renderer stored each
ui.persist under whichever workspace was active when it arrived. An edit made
less than 0.4 s before a switch was flushed after the new workspace's hydrate,
so workspace B's value was written under B and A's edit was lost.
The host now names each ui.hydrate; the guest flushes pending writes before
applying the next hydrate and tags ui.persist with the hydration its values came
from, and the renderer stores the write under that hydration's workspace.
(STA-13316)
* test(plugins): cover workspace-persist hydration routing edge cases and add switch e2e
Adds unit coverage for A->B->A routing, legacy (no hydration) persists, the eight-hydration window, plugin-scope entries, and guest flush/tagging; adds an Electron e2e that types in workspace A, switches inside the persist debounce, and checks both workspaces after switching back and after the panel's guest is recreated. Regenerates orca-testing.mjs after rebasing on main.
* fix(plugins): stop a late replacing command from repeating the built-in action
The renderer ran Orca's own action after 2 s but the still-running replacing
command could then call commands.run for the same action, doing it twice.
Main now owns the 2 s cutoff: it rejects at the deadline (the renderer falls
back on that answer) and from then refuses the late handler's commands.run of
the replaced action; a handler that already ran the action is not followed by a
fallback. The deadline now starts when the renderer asked, not after plugins
load. The renderer's own timer is only a safety net. (STA-13530)
* test(plugins): cover replacement races and verify the sidebar toggles once end to end
A handler's commands.run now counts for the oldest in-flight press only, so a second
concurrent press whose handler fails still gets Orca's fallback. Adds unit cases for a
throwing/crashed handler, two presses racing, and a press after a late handler returns,
plus an Electron e2e spec driving fast, late (2.1 s), throwing and no-op replacements of
sidebar.left.toggle.
* fix(plugins): stop terminal inventories for agent status events nobody hears
Each agent.status.changed event for plugins lists the workspace's terminals,
which refreshes every PTY provider and host. Interest was only checked when an
event was admitted, so after the last panel closed the queued backlog kept
running full inventories with no one to deliver to.
Recheck interest before each lookup and drop the backlog once nobody listens,
and let events queued behind a slow lookup share one listing per workspace
while keeping arrival order. (STA-13319)
* fix(plugins): keep the agent status queue moving past a throwing delivery
A synchronous throw from one emitEvent dropped the rest of its batch and left
later queued events waiting for the next arrival. Catch per delivery, and cover
a failed listing, a 1000-event storm, a panel reopening mid-lookup, and several
panels on the real bridge; the panel e2e now checks a burst arrives in order.
(STA-13319)
* fix(ssh): keep old relay channels off the host's own SSH connection
Each old relay still running a shell held one exec session on the target's
connection. At sshd's MaxSessions (default 10) every later exec failed, so the
host stuck at Connecting with 'Could not detect the remote platform: (SSH)
Channel open failure: open failed'.
* test: say why the session-limit repro needs a longer timeout
* test: note why the relay channel fakes are cast
* test: move the many-relays repro into the existing legacy relay bridge suite
* feat(pairing): show which devices still sign in with their original pairing code
Settings lists paired phones and access links that signed in with a pairing
code but never exchanged it (apps from before single-use pairing) with
"Uses an older pairing method. Update ...". Display only; rows from older
builds are never flagged.
* fix(pairing): no update hint for links used by plain-http browsers or still pairing
A link that served a session-only browser key is marked, so the hint stays
off after a host restart drops those keys. Codes still inside the pairing
window are not flagged either: an updated client exchanges within moments.
* Use Cmd+K for search on new Mac profiles
Preserve existing search and terminal clear shortcuts during migration
on desktop and web.
* Preserve legacy Mac shortcuts during web profile migration
* Preserve keybinding resets across profiles and platforms
* Preserve legacy shortcuts and markdown link bindings
* Separate profile shortcut defaults from shared overrides
* Check shortcut conflicts when restoring defaults
* Fix tab shortcuts targeting floating workspace panels
* feat(pairing): Add server and orca environment add exchange the link for their own token
After verifying the host, Add server (and repair) swap the access link's
token for one generated on this computer when the host advertises
pairing.ticket-exchange.v1, and save that instead. orca environment add does
the same with a short best-effort probe. Any failure saves the link as today;
the host keeps accepting it until the new token is used.
* test(pairing): Add server and CLI leave links unchanged for a released host
* fix(pairing): Add server and orca environment add sign in once after exchanging, and the CLI rejects a refused code
After exchanging a link, sign in once with the new token so the host
retires the link right away instead of at the first later use; a host
downgraded in between would not know the new token.
orca environment add no longer saves a pairing code the host refuses
(for example one another device already used); it asks for a new code.
* feat(pairing): a browser's saved device key retires the pairing link it came from
When a browser signs in for the first time with a saved device key forked
from a ticket row, the row's link token is replaced by a value nobody holds
(the row stays as the fork's anchor; orchestration fingerprint pinned).
Session-only keys re-register from the link on every page load, so they never
retire it. Links from older builds are untouched.
* fix(pairing): a browser key retires a link only during pairing and only if nobody claimed it
A saved browser key now retires its link only when it was registered within
the pairing window of the link's first sign-in, and only when no other
client already proposed its own token for it (that first claim wins, so the
desktop that proposed first is never locked out).
* test(pairing): the web key migration wire test expects a fresh link to be single use
* fix(web): say a refused pairing link may already have been used
A browser opening a single-use link after another device used it is
refused as unauthorized; the message now names that case and asks for a
new pairing link from Orca.
* feat(pairing): let clients exchange a pairing code for their own token
New offers are marked as tickets. A client signed in with the pairing token
can call pairing.exchangeTicket with a token it generated; the host stores it
durably and keeps accepting the pairing token until the client first signs in
with the new one. That sign-in retires the pairing token and cuts sockets
still using it. Advertised as pairing.ticket-exchange.v1; clients that never
call it keep working exactly as before.
* fix(pairing): never retire a code other clients may already rely on
Exchange is offered only within 10 minutes of a ticket's first sign-in;
after that the code may be in use by several older clients and stays a
plain token. The first client to propose keeps its claim: a different
proposal is refused (that client keeps the code) instead of displacing it,
so two clients pairing at once can't lock out the first. Adds cross-version
tests against the pinned release: downgrade keeps exchanged and unexchanged
phones working, rows from an older host are never single-use, and the older
host doesn't advertise the exchange.
* Fit file and browser tabs to their content
Keep terminal tabs at their preferred width and reserve stable editing
space while renaming tabs.
* Remove obsolete tab rename width hook
* feat(ai-vault): reveal an Antigravity session's artifacts folder
* fix(ai-vault): detect agy artifacts from the discovery walk and open inside the folder
* test(e2e): pass onRevealArtifacts in the OMP child history fixture
* refactor(renderer): organize runtime clients and feature state owners
* fix(refactor): preserve incoming consumers and validation routing
* fix(refactor): consolidate defining-owner type imports
* refactor: organize remaining terminal pane features by owner
* refactor(terminal): consolidate replay guard type imports
* refactor(terminal): retarget notification mocks and generated consumer import
* refactor(terminal): repair benchmark owner lookup and stale mock export
* Separate editor tab placement from content ownership
* Show scoped Source Control sections for attached worktrees
* Preserve active diff refresh and validate section catalogs
* Complete folder section test worktree metadata
* Use contextual types for scoped Source Control actions
* Preserve optional scoped action parameters
* Preserve editor ownership through restore, mirroring and workspace removal
* Retire Source Control drafts only after confirmed owner removal
* Limit section work to visible expanded repositories
* Keep editor follow-up actions and bulk closes in their invoking views
* Track the consolidated editor order writer in its owning module
* Use complete typed fixtures for repair contracts
* Preserve live editor placement during layout readback
* Pass projected editor placement directly to serialization
* Read attached worktree lineage from shared graph module
* Retain inferred owner checks and scope placement retirement
* Preserve selection in untouched workspaces during purge
* Exercise editor placements in existing launch and lifecycle fixtures
* Preserve shared buffer prompts and editor strip order
* Pause inactive section context subscriptions
* Keep section recovery and file actions in the folder workspace
* Describe attached Source Control in folder workspace CLI help
* Attribute Git metadata signals once per dispatch
* Watch mounted source control sections outside the warm budget
* Resolve section watches only for served filesystem roots
* Restore restart-stable editor identity across SSH opens
* Apply section terminal routing to explicit Chat choices
* Include cross-store descendants in folder workspace panels
* Keep cross-host recovery on its existing workspace route
* Start cross-host section agents in their workspace without navigation
* Update memoized Source Control labels on language changes
* Remove unused terminal close-to-right implementation
* Suspend inactive Source Control body observers
* Retain base ref query while section observation pauses
* Cover retained base ref search across section visibility
* Resolve note menu ownership from the retained snapshot
* Preserve section agent working directories and background placement
* Keep Source Control sections active while their overlays are open
* Read current settings when Source Control commands execute
* Adapt editor and browser test stores to view subscriptions
* Preserve bound store hooks for ordinary app views
* Trust agent starts outside the placement workspace
* Trust the section worktree through transient launch ownership
* Extract editor follow-up file actions from the panel
* Fail section launches when trust capability lookup fails
Preserve explicit unsupported-host fallback, propagate lookup failures to the existing launch error path, and let the existing transport retry refresh rejected capability probes.
* Follow the moved pane launch test in web configs
* Preserve section file ownership during refresh and close
* Share tab order removal across editor close paths
* Verify companion editor close through the real store
* Close all workspace split copies for legacy mobile file requests
* Keep unmatched mobile close requests within their workspace
* Reuse the agent menu render snapshot
* Keep attached folder roots scoped to their resolved host
* Apply repository trust decisions to the launch trust owner
* Ask once per repo before pre-trusting agent folders
* Route the trust prompt's repo lookup by the launch host; use dialog primitives as designed
* Bound the first-launch trust hold and honour the answer for the launch
* Move agent folder trust settings into their own settings group
* fix(native-chat): list Claude and Codex models per account, not per folder
Opening the chat model picker rebuilt every worktree row to work out which
folder the read was for, because Claude and Codex model lists were keyed by
folder. Only the default model/effort depends on the project, so lists are now
keyed by account, WSL and the resolved CLI invocation and listed from the
account folder; the CLI is still resolved where the chat would launch. The
selected workspace is derived directly from its selector, and its own project
settings decide whether the account's default model and effort are shown.
The worktree projection and its cache are removed.
* test: merge duplicate node:os import
* fix(native-chat): list from Orca's probe folder, keep cwd-relative CLIs in their folder, one project-settings pass
- List Claude/Codex models from Orca's empty probe folder so a home folder's settings never read as another account's project settings.
- A command line naming files relative to the chat's folder lists there and is keyed to it.
- Read project settings once per binding for both the model and effort answers; per-model effort-only Claude settings keep the account model.
- A running chat's catalog withholds the account's configured choice where its project may pick its own.
- Bound the picker's workspace resolution so a stalled floating folder cannot hold it.
* fix(native-chat): catch quoted ./ arguments, list prewarm from Orca's probe folder, fake-timer the shared-listing test
* perf(native-chat): parse each project settings file once for both model and effort
* test: catalog e2e expectations list from Orca's probe folder; phone saturation keys per folder
* fix(native-chat): share a listing while any reader wants it; list custom command lines in the chat's folder; resolve a floating folder within the read's own wait
- A model listing shared by several folders keeps running while any reader still waits on it, queued or running, and stops (never starts) once the last one gives up.
- A Claude or Codex command line with user arguments or a relative command lists in the chat's folder; Claude reads only user settings there so project settings never narrow the account's list.
- A waiting read resolves a floating folder within its own deadline; a read that doesn't wait returns at once and starts the listing when the folder resolves.
* fix(native-chat): every reader of a shared model listing owns it until its own deadline; floating reads list their folder within their own budget
- Readers of the same request share one lookup that lives until the last reader's deadline, so later readers neither repeat CLI/settings setup nor lose the listing when an earlier one ends or is cancelled.
- A shared listing's requests carry no single reader's deadline: the provider timeout bounds them and the last reader leaving stops them.
- A floating picker read that doesn't wait starts its folder's listing under its own deadline and retirement, and says the listing is in progress so the picker follows with a waiting read.
* fix(native-chat): a shared model listing survives the chat that started it; unreadable workspaces list as the account
- Each reader of a shared lookup fences its own request, so one chat closing never ends another chat's listing; the lookup's budget is the latest deadline among readers still waiting, and its listeners are released when it ends.
- A picker for a workspace this host can't inspect (remote, WSL, ambiguous, stalled) lists as the account does from Orca's probe folder, never from wherever Orca itself runs.
* refactor(native-chat): readers of one model request share an ownerless setup and each own only their claim and the listing
- Same-request readers share one setup (folder, account, CLI scope and the folder's own default settings) that belongs to no reader: its budget is fixed when it starts, it ends with the service or the agent's retirement, and it is reused while it runs and while the listing it found runs.
- Each reader keeps its own claim, deadline and cancellation; a binding holds scope facts only and never cancels another reader's claim or a shared listing, so one chat closing never ends another chat's listing.
- A floating picker read that doesn't wait no longer asks to list the unresolved folder.
* fix(native-chat): shared catalog setups end on their budget or a workspace change, readers settle on cancel, and defaults and account seeding happen once
- A shared setup that runs out of its budget, or whose workspace or agent is retired, answers nothing at once and leaves the cache, so a reader with time left resolves afresh (a moved folder never reuses the old path).
- Cancelling a reader, or stopping the service, ends its wait at once.
- A folder's own default settings apply to its binding whenever they arrive; the account list is seeded once per shared setup, not per reader.
- A reader shares a setup only with readers whose own chat agrees on whether it may list.
* fix(native-chat): a settled catalog setup serves its whole listing, and a folder's default settings stay bounded and reach every reader
- A setup that has answered stays reusable while the listing it found runs, past its first reader's deadline, until it is ended or its agent retired, so later readers don't redo CLI and project-settings work.
- The setup's budget holds until the folder's default settings have answered too; settings that outlive it are read again while a reader still has time, and apply to the request's current binding whichever reader asked.
* refactor(native-chat): the catalog service owns each model refresh within one fixed budget; pickers only wait
A refresh (account, folder and CLI resolution, the folder's default settings,
admission and the listing) now belongs to the catalog service with one 30s
budget fixed before setup. Readers join it and wait only until their own
deadline or cancellation; none extends, shortens or ends it. Expiry withdraws
queued listings, stops the process and drops late answers. Defaults apply only
to the refresh's own binding, so a moved folder's late settings never describe
the new folder. A waiting read that used its whole budget is final.
Replaces per-reader claims, shared setups and reader-counted listing demand.
* fix(native-chat): retiring an agent or a chat's folder ends its catalog refresh at once, and a shared setup never rechecks the chat that started it
- Retiring an agent ends a refresh still stalled in setup, so a waiting picker
answers at once instead of after the refresh's budget.
- A listing that runs in a chat's own folder stops, and its answer is dropped,
when that folder's command context retires; listings shared across folders
stay independent.
- Scope resolution uses only the passivity its readers had when they asked,
so another chat's record going away mid-setup no longer turns it saved-only.
- A reader that stops waiting unsubscribes from the listing at once.
* fix(native-chat): one workspace's retirement no longer stops a catalog listing another workspace shares
A listing is keyed by the folder it lists in and the CLI invocation, so moving
one workspace never makes it describe the wrong folder; stopping it there
cancelled a listing another workspace on the same folder still needed. Agent
retirement and shutdown still stop listings at once.
* test(native-chat): a folder change keeps another workspace's shared catalog listing, and never answers the new folder with the old one's
* test(native-chat): a folder agent's listing survives another workspace on its folder moving
* test(native-chat): type the shared-setup harness's held stages without casts
* fix(native-chat): Claude and Codex pickers show the account's default in every folder
The picker no longer reads a repo's own model or effort settings for Claude and
Codex: they show the account's list and default everywhere, and the CLI still
applies the repo's settings at launch. OpenCode, OMP and Pi keep their project
checks. The model/effort split and the peek withholding go back to main's shapes.
* fix(native-chat): a Codex listing in the chat's folder never loads that folder's project config
A Codex command line that may name files in the chat's folder still lists there,
but now marks that folder and its parents untrusted for the listing, so a repo's
own model catalog can't replace the account's. The exported project-settings
check also answers no for Claude and Codex.
* fix(native-chat): Codex lists models only from Orca's probe folder
A Codex listing no longer starts in the chat's folder for custom or relative
command lines, so a repo's own config can never change the picker's list, as
other Codex hosts do. Chats still launch with the user's command line and folder.
Drops the untrusted-folder override.
* fix(native-chat): Codex listings never read project config above Orca's folder
With no project-root markers, Codex reads project config only from the listing's
own folder, so a trusted repo that contains Orca's profile can't supply the
account's model list.
* docs(native-chat): say what Codex listing isolation covers, and what managed config can still restore
Set up later saves the applicable visible Chat/Terminal and agent choices, preserves unvisited saved defaults and Blank, then opens the default agent through ordinary workspace activation in the captured workspace and host. First use and Help replay share the behavior, and failed saves remain retryable.
Independent reviews accepted the main-parent update. All 27 focused tests and final-head CI passed, including twelve unit shards, static/typecheck, changed E2E and packages. Real Claude/Codex Chat and Terminal, saved Blank and graceful-restart QA carries across the main merge. The final local changed-check prerequisite timed out in the resource queue before checks ran; this limitation is documented in the PR.
Fresh desktop profiles start in an ordinary folder workspace at the OS home directory, with the initial repo group named ~. Onboarding Continue saves the selected default agent and launches it in that workspace through the normal activation path. Existing profiles and user-renamed groups remain unchanged.
Independent reviews and prior real Claude/Codex QA are complete. Refreshed-head CI is green, including all unit shards, changed E2E, static/typecheck, packages, persistence and WSL. All 54 focused regression tests passed; three bounded local check timeouts are documented in the PR.
* fix(terminal): finish a paste when focus moves to a non-input control mid-paste
External dictation tools and overlays can leave focus on a control outside the pane while the clipboard read is in flight, and the paste was thrown away as stale. Only cancel when another paste target (terminal, input, frame) took focus.
* fix(terminal): count Monaco and rich editors as paste targets
* test(e2e): a paste survives focus moving to a non-input control mid-read
* refactor(terminal): one focus rule for terminal and popout paste
* test(e2e): scope each focus-move script so later cases actually move focus
* Offer terminal sign-in from native chats and retain refused worker tasks
* Handle sign-in terminal failures and complete failed-start cleanup callers
* Read retry task identity from its dispatch context
* Assert retained transcript identity through the bounded worker read
* Remove obsolete private structured retry teardown assertion
* Use real signed-out Pi and OMP error frames in regression coverage
* Route chat sign-in through explicit host terminal creation
* Keep paired agent launch owner explicit in the tightened terminal contract
* Keep focus baseline pruning limited to the removed reads
* Keep terminal login recovery available for unresolved model notices
* Keep the Grok diagnostic assertion scoped to its refused delivery
* Limit chat sign-in subscriptions to eligible failure rows
* Pass the execution host in terminal creation fixtures
* Scan Pi OAuth failures linearly and verify shared sign-in bounds
* Assert failure metadata and diagnostic routing without translated copy
* Bound diagnostic matcher steps at the Pi failure boundary
* Type the diagnostic matcher receiver explicitly
* Check sign-in button elements with a DOM type guard
* Recognize Pi credential failures and keep one recovery action
* Keep Pi sign-in diagnostics behind failure details
* Verify recovery action changes while refusal wording stays stable
* Use the recorded refusal sentence in the recovery fixture
* Type the recovery fixture as a submission rejection
* Make chat sign-in actions large primary controls
* Reuse primary action styles without duplicate notice subscriptions
* Keep translated primary chat actions within narrow notices
ProseMirror reads a click's selection from the selectionchange event, which a
hidden Xvfb window delivers after Playwright's next step. The spec focused Find
right after clicking, so the editor still held an old selection when focus left,
and the Shift-click extended from the document start. Wait for that event after
the caret click and the range Shift-click; route Find sources to its specs.
Co-authored-by: Claude <noreply@anthropic.com>
* test(e2e): wait for the shell-ready deadline after a startup exec
Since #30978 the terminal host no longer probes for a prompt when a profile
exec drops Orca's ready marker; it submits the startup command once at the
15 s shell-ready deadline. The oracle allowed only 8 s, so the headless serve
case failed unless the exec barrier happened to run long. Wait until that
deadline (measured from terminal creation) plus the recovery budget, and
route the spec from the shell-ready barrier and shell startup sources.
* ci(e2e): route the startup-exec oracle helper to its spec
The spec forged an SSH owner for a local file and relied on the read
falling back to local transport. Since #31617 a tab reads only from its
captured owner, so the forged tab correctly shows 'Couldn't verify which
host owns this file'. Use a paired client that opens the same checkout
locally and on its runtime host instead, and route editor model identity
sources to the spec.
A link whose page is already open now reuses that tab (#32907), so the paged
preview's click of the same URL never added the second tab the spec counted.
Also route CSV viewer sources to the CSV specs.
permission dropdown, and fresh profiles keep OpenCode on its own settings, so
the agents without Auto read Mixed after Full access -> Approve for me. Assert
that, track OpenCode in the stored-permission checks, and route the spec on
permission settings sources.
Claude launches now get --plugin-dir prepended (subagent navigation, #33322),
so the stand-in read '--plugin-dir' as its marker path and the spec never saw
the detached child. Route the spec on descendant-kill and Claude launch-flag
sources.
Since #34683 a move journal promotes the WSL hosts gate to serve-only, so startup
recovery now runs and undoes a move interrupted before blobs-transferred. The
spec restarted at source-fenced and expected the fence to survive; assert the
undo there, fence from blobs-transferred, and expect the committed refusal to
name the host (#34880). Route fence and recovery sources to the spec.
Co-authored-by: Claude <noreply@anthropic.com>
Terminal padding now insets the bottom edge too (#36789), so the terminal sits
paddingY above the pane bottom. Route pane geometry sources to the spec.
The one-time 'This page renders on your desktop' tour opens beside the address
bar of the first client-hosted page and intercepts clicks on the address-bar
suggestion. Seed it as seen for this spec via a new paired-client launch
option, and route address-bar conversion sources to the spec.
Since #31080 a client keeps one saved entry per server, so pairing the same
host a second time under another name is refused. The steady 'Direct host' is
now a different server than the interrupted one. Tooltip checks name the host
so a closing tooltip from the previous card cannot match. Route the spec from
its pairing-store and runtime-status sources.
Board drops send wakeWslDistro (#36230) and network failures toast localized
copy (#34621). Route GitHub Projects sources to the board spec so PRs run it.
Since #33622 a confirmed HTML preview link honors openLinksInApp (default off,
so it opens the system browser) and no longer calls
openBrowserProfileTabInActiveWorkspace, so the spec's store spy never fired.
Opt the client into in-app links and observe the opened page URL directly.
Route doc-preview sources to the spec.
* test: stop unit tests from running the developer's real agent CLIs
A live relay test reached the host's real `claude --version` through the
inherited PATH. On a machine whose claude wrapper never exits, each run left
an orphaned loop behind (14 were found on one host, running for days).
- Add a unit-test setup guard that shadows agent CLI names on PATH with
stand-ins that fail the test which ran them.
- Give the live relay test its own claude/codex stubs.
- Kill the whole process tree when the WSL guest's version probe times out.
* test: keep structured-session tests off the real codex CLI
These hosts get a scripted transport, but the at-rest `/` command read
spawns the resolved codex command directly, so on a machine with codex
installed each run started a real `codex app-server`. Point them at a
missing binary, as on CI.
* test: isolate agent discovery in session fixtures
* fix(automations): Run now returns the saved pending row; quiet, titled, retained run terminals
Run now answers with the durable pending row instead of waiting behind
the automation's lane; one detached handler records a launch failure.
Existing-workspace launches no longer surface their owner, a new
workspace's startup tab carries the run title, and finished-run cleanup
keeps a terminal a user opened after its process started.
* fix(automations): keep launched runs and user-opened run terminals intact
A failed flush after a launch no longer rewrites a dispatched run as a launch failure.
A user tab open marks the pane activation shows, read after any spawn it starts.
* fix(automations): own launch-failure recording in the service; quiet pending pane notice on mobile