When Antigravity's Orca-managed chat runtime isn't installed, default-chat launches (orchestration workers, agent.launch from CLI/mobile/automations) fall back to a terminal running agy with reason chat_runtime_not_installed instead of failing at terminal_create; an explicit --surface chat is refused with an install hint. Desktop chat tabs still show the install card.
Fixes#30973
A Codex (or Antigravity/Cline/Prime Agent) dialog drawn and erased in place no longer leaves the pane "blocked" forever when no hook/OSC 7501 clears it. The line tail still decides; the live screen may only clear a tail block when caught up, quiet 3s, no blocker anywhere on screen, and the agent's composer is ready — then the stale block stamp is cleared so the send's own echo doesn't re-block. Also defers the daemon re-attach seed's output sequence until the seed lands.
Fixes#24187
Supersedes #24308
Co-authored-by: Wooseong Kim <2222333+innocarpe@users.noreply.github.com>
dsh worker dispatches (and other dsh agent-prompt sends) now get #33316's bounded Enter retry: dsh paints its launchpad before its session opens and refuses the first Enter with "still starting", so a fresh worker's task sat unsent. The retry only re-presses while the launchpad still holds the same prompt and stops once a turn starts.
Fixes#30778
Co-authored-by: Jinwoo Hong <73622457+Jinwoo-H@users.noreply.github.com>
Hold the orchestration mailbox pointer (and coordinator nudges) while the agent's composer has an unsent draft, so Orca never submits over what the user is typing.
Fixes#26992
Supersedes #27195
Co-authored-by: Hotragn <103170876+Hotragn@users.noreply.github.com>
Terminals created with a flagged agent command (e.g. `omp --thinking high`) now get the agent's identity at creation, so `tui-idle` waits for the agent instead of reporting ready early.
Fixes#25264
Supersedes #25320
Co-authored-by: ggbdpq <67929842+ggbdpq@users.noreply.github.com>
DSH: Orca re-presses Enter (up to a 30s launch budget) while dsh's launchpad still visibly holds the launch prompt — dsh refuses Enter while its session is starting — and stops as soon as the prompt leaves the screen, so no Enter reaches the first-run guide. The shared draft reader recognises dsh's boxed launchpad composer. Fixes#29131, #33227. Supersedes #33229.
Co-authored-by: Xulin Wu <35489799+wuuli@users.noreply.github.com>
* refactor: group local and WSL filesystem watchers
* test: isolate startup ordering from watcher initialization
* test: collect the startup preflight subject once
Orchestration mailbox pointers now get their delayed Enter for Cursor too (the Cursor no-Enter skip from #3156 left mail delivered but never acted on). Verified with real cursor-agent. Fixes#19760. Supersedes #19761.
Co-authored-by: Maple <54388301+zleo-ai@users.noreply.github.com>
Windows Codex: when a large dispatch/worker-start/agent prompt paste is still held in Codex's composer (Codex reads the paste as key events and treats an early Enter as a newline), Orca re-presses Enter only while the composer visibly holds exactly that pasted prompt, re-checking turn start, permission and the deadline right before each Enter, within the worker-start budget. Non-Windows unchanged except the blind launch retry is skipped once a turn starts. Fixes#11343.
* fix(worktrees): never leave the create-worktree dialog stuck on a stalled preflight
Bound the same-repo PR branch fetch with the review-head fetch timeout, and
hand a slow composer submit off to a staged sidebar row so the dialog closes.
* fix(worktrees): harden create-worktree handoff from adversarial review
Dedupe handed-off submits against linked creations resolved during preflight,
bound the staged sidebar row with a deadline, offer Reopen on handed-off
failures, and bound the GitLab MR branch fetch.
* test(worktrees): expect the bounded PR/MR branch fetch timeout
---------
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
* fix(mobile): stop losing phone terminal output sent as output spans
Hosts sent stripped/transformed terminal output to terminal.subscribe as
OutputSpan (opcode 15), which no phone has ever decoded. The phone dropped
it silently, e.g. the reset after a killed full-screen program, leaving
the phone stuck on the alternate screen.
- Host: terminal.subscribe sends spans as plain Output text; only the
desktop multiplex (which decodes spans) keeps OutputSpan.
- Mobile: decode OutputSpan for older hosts, use the shared protocol
table, and end the stream with a logged error on any frame it can't read.
* fix(mobile): throttle unreadable-frame resets and log once per stream
* fix(mobile): reset a throttled stream after the window; forget released stream ids
* fix(mobile): defer throttled unreadable-frame resets instead of dropping them
* feat(managed-server): offer Update and Update anyway on a managed SSH server's row
A managed SSH server only updated on connect, and every connect deferred while
a terminal ran there. Its row now offers Update when this desktop bundles a
newer build than the Orca that runs the host. When running terminals defer it,
Update anyway restarts the server past them; the terminal daemon carries them
across the restart.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix(managed-server): Update anyway passes only counted live terminals and keeps Update's version admission
Update anyway now sends the incumbent build it confirmed over; under the host
fence it is refused if another desktop activated a build since, keeps the
newer-host downgrade refusal, and never passes an uncounted terminal census.
The offer also covers hosts activated before the Orca version was recorded,
for the build this desktop already deferred there.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix(managed-server): Update anyway also confirms a menu Update the row does not advertise
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix(managed-server): the row shows one confirmation at a time
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* ci(e2e): route managed-server update sources to the Update anyway Docker spec
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude worker-start also becomes ready when Claude's empty composer (❯ + NBSP, only after Claude's DECSET 2031) draws, racing the title-based tui-idle wait, so worker-start no longer times out when Claude's terminal title is disabled. Fixes#22655.
* fix(agent-teams): run the tmux shim through the headless host's CLI, never the GUI binary
On an orca serve host the runtime has no Electron resources directory, so the
shim fell back to PATH and picked the AppImage's Electron binary, which booted
Chromium and died on the SUID sandbox. Prefer the host's profile-scoped CLI
launcher, and route agent-teams-tmux through the packaged CLI redirect so a
direct Electron invocation never initializes the GUI.
Fixes#33354
* fix(agent-teams): prefer a fresh CLI over a shim bin inherited from an older leader pane
Orchestration mailbox pointers (typing and the delayed Enter) are held while a Claude pane shows an open dialog (AskUserQuestion / permission / plan approval chrome on screen, or a fresh waiting row when the screen can't be read), capped at 10 minutes, so mail no longer answers the dialog. Recheck backs off to 2s while held. Fixes#21745. Supersedes #26928, #21880.
Co-authored-by: yasyf <709645+yasyf@users.noreply.github.com>
Codex workspace trust is also written to the launch CODEX_HOME (managed-account home) at spawn, and native Codex chats pick their launch home before writing trust, so managed-account Codex launches no longer stall on "Trust this folder?". Fixes#27235.
Orca-driven Codex launches that type their prompt after start (workers, automations, continuation/handoff, pane-spawn and other submit-after-ready flows) pass `-c check_for_update_on_startup=false`, so Codex's "Update now" screen can't block them or be accepted by Orca's Enter. User-typed launches and resumes are unchanged. Fixes#15814, #18153. Supersedes #18156.
Co-authored-by: luisgonzaleznf <47302972+luisgonzaleznf@users.noreply.github.com>
* chore(lint): remove disable directives that suppress nothing
Each was reported unused by the oxlint config that owns its rule (root,
casting, react-doctor, anti-slop, native-plugins), including 17 file-level
react-doctor blanket disables whose rule no longer fires. An unused
react-hooks disable was masking a react/purity finding in
useAgentBucketCounts (compiler rules skip functions with hook
suppressions); suppress that one explicitly where the code explains it.
* test(tab-bar): use typed tab/file fixtures instead of @ts-expect-error partials
* chore(lint): fix misc suppressed lint violations instead of disabling
- consistent-type-imports: the "vi.importActual requires inline import()"
rationale was wrong; use typed vi.mock(import(...), importOriginal) or a
type-only namespace import.
- no-control-regex: source-control commit/push failure summaries, shell PATH
hydration, and ipynb ANSI parsing reuse the shared ansi-escape-sequences
stripper and control-character pattern instead of private copies.
- no-explicit-any / no-useless-spread / no-this-alias: typed `this` in
bridge test mocks, drop blanket file-level disables, drop a this-alias.
* refactor(main): replace avoidable type assertions with checked narrowing
17 production cast suppressions in main/wsl-guest removed: untrusted IPC
and RPC payloads (Jira issue update, WSL guest plugin install, handshake
type) now narrow through isRecord/type guards and build typed results;
redundant casts dropped; hand-rolled object checks and errno casts use the
existing isRecord / hasErrorCode helpers.
* refactor(renderer,mobile): replace avoidable type assertions with checked types
13 production cast suppressions removed: RPC failures read through the
`ok` discriminant instead of casting to RpcFailure; react-native-web host
refs narrowed with instanceof HTMLElement; redundant reply/diff casts
become checked annotations; the TUI agent param uses z.custom(isTuiAgent)
like its sibling schemas; the agent-status slice cast that hid missing
actions is gone so the creator's return type checks the whole slice.
* chore(lint): drop dead tiptap wrapper; scope anti-slop mocking rule to test support
- safe-react-node-view-renderer patched handleSelectionUpdate, which
@tiptap/react 3.31.3 no longer has, so it always returned early. Use the
stock ReactNodeViewRenderer.
- The anti-slop test override only matched *.test.{ts,tsx}, forcing
file-level no-module-mocking disables in test harnesses and fixtures.
Match *-test-harness, *-test-fixture(s), .test-fixture and *.test.mjs,
then drop those disables and the now-redundant per-file exemptions.
* test: replace repeated cast suppressions with typed fixtures (main/shared/e2e)
Net -119 cast directives. Typed fixtures replace recurring casts:
unusedSshConnection/unusedOrcadHostTransport placeholders, a typed
readPersistedState harness read (exposed a test treating optional
httpProxyUrl as always set), real Response objects in fetch spies, an
updater main-window fixture, a CDP webContents adapter, one shared
releaseModuleExport for cross-version tests, and requireOverlayDir in
place of `as string` on possibly-undefined overlay paths.
* fix(runtime): validate loaded device rows and host scope instead of casting
Two cast suppressions claimed checks that did not happen:
- device-registry-file-read: "normalizeLoadedDeviceRow re-validates every
field" was false; deviceId, token, name and timestamps were never
checked. Rows without an identity are now dropped and the file is set
aside through the existing corrupt-file path (registry reads as
doubtful, so no revocation verdicts); a non-string token is stripped
so the row stays listed but cannot authenticate.
- client-ui: "only optionality differs" was false; any string reached
persisted workspaceHostScope. Narrow it with isWorkspaceHostScope and
ignore unknown scopes (wire schema unchanged for mixed versions). The
remaining cast now states what it actually covers.
* test(runtime,ipc): drop redundant cast suppressions; typed runtime store fixture
-98 cast directives across runtime/ipc tests: 61 casts that typecheck
without the assertion; a typed vi.fn for scoped invalidation; a
partialRuntimeStore fixture in place of `store as never` for
OrcaRuntimeService; typed worker terminal/authority builders in the
incarnation-fallback suite (the old stub lacked runtimeId, ptyId,
worktreeId and launchTokenHash) plus removal of stacked duplicate
directives there.
* chore(lint): typed vi.mock imports and explicit listener snapshot in shared-bucket tests
Remaining files from the misc-rule pass that overlapped other buckets:
codex-accounts mocks use the typed vi.mock(import(...)) form instead of
a consistent-type-imports disable; the daemon late-exit fixture copies
its listener set with Array.from instead of a no-useless-spread disable.
* refactor(github,mobile): narrow routing settings type; drop remaining avoidable casts
- work-item-routing cast a one-field object to AppState['settings'] under
a claim that readers only consume activeRuntimeEnvironmentId. Return the
existing RuntimeFocusSettings pick instead and narrow the cache-key
chain's parameters, so the compiler enforces that claim.
- mobile file preview reads refusals through the RpcResponse `ok`
discriminant rather than a cast.
- terminal document host-notify accepts `unknown` errors, removing the
message-bridge cast.
- native chat readability drops a redundant repo-list cast.
* test(renderer): replace repeated cast suppressions with typed fixtures
-140 cast directives (and ~150 unsuppressed casts of the same shapes):
- mockPanePtyArgs owns the connectPanePty fixture casts, so a wrong
argument order or fixture is now a type error; drop binding casts for
members PanePtyBinding already declares.
- Seed AppState tab rows with the typed makeTerminalTab; this exposed a
split direction 'row' that is not a TerminalPaneSplitDirection.
- Partial GlobalSettings use getDefaultSettings overrides; Jira-only
stores use createTestStore; runtime environment rows/statuses come from
a typed paired-runtime-environment fixture.
* chore(lint): drop no-module-mocking disable now covered by the test-fixture glob
* test(e2e): fix all 221 grandfathered e2e type errors; baseline to zero
The e2e typecheck baseline grandfathered 221 errors in 119 files. About a
third were tests drifted from the current API, several of which would
fail or mislead at runtime:
- terminal-shortcuts called a nonexistent xterm buffer method;
- the daemon-lifecycle fake lacked terminateOwnedTree, hidden by importing
its type from a module that does not export it;
- arguments in the wrong position (listProcesses(hostId, opts), a dropped
pty.write inputKind, an extra toWebTerminalSurfaceTabId argument);
- removed enum values ('drawer', 'idle', 'editor',
'session-insecure-origin') and a launch_source the telemetry schema
rejects;
- missing required fields (turnScope, childWorkOpen, providerIdentity,
reviewLookupOutcome, runtimeServiceAccount behind an `as RelayConfig`);
- dead reads (tab.customTitle, bucket.targets, changedPixels).
Also lifts variables that narrowed to `never` after poll-callback
assignment, and adds a typed xterm render-dimensions accessor. Includes
the cross-version suites' shared releaseModuleExport adoption.
* chore(typecheck): gate the now-clean e2e typecheck in local lint
The e2e baseline is empty, so the ratchet now rejects any tests/ type
error. CI already runs it via run-ratchets; add it to pnpm lint's
explicit ratchet list and replace the stale 'not yet clean' note.
* test(mobile): typecheck every mobile test; baseline 105 files -> 0
mobile/tests-typecheck-baseline.txt grandfathered 105 test files (531
errors) whose types CI never checked. Contract changes had landed without
these tests following, and type pins in them silently checked nothing.
- Root cause: salvagedOptional (src/shared/zod-salvage.ts) cast away
zod's optional marker, so every reply type built on it claimed
salvaged fields were always present. Return a real ZodOptional;
runtime is unchanged (the outer optional short-circuits undefined).
- Production now takes the port it uses: RpcOperationSender instead of
RpcClient for send-only callers, a narrow fetch signature, and only the
request fields push-receive reads.
- findAllByHostType/findByHostType replace `'Text' as never` lookups;
stubRpcClient gives tests a typed RpcClient.
- Real test bugs: settings-host-client-lifecycle "relay" hosts were
direct hosts (relayHostId no longer exists); two toEqualTypeOf pins
could never hold; a recovery hook ran with an undefined scope key;
a create-PR test cast to a never-imported type; "no URL" assertions
passed on null; plus stale required props, args and enum values.
* test(e2e): parse workerStart result instead of casting it
* test(runtime): typed partial runtime stores with production-shaped fixture data
Route every partial store passed to OrcaRuntimeService through
partialRuntimeStore with typed row builders, removing 60 cast directives
that hid fixture data production never produces:
- paired-client-navigation-test-harness keyed setWorktreeMeta writes by
`[object Object]` (it took an id where the store takes a target), so
reads never saw them;
- invalid worktree lineage origin/capture and incomplete workspace lineage;
- getWorkspaceSession returning null where the store returns the default
session; getGitHubCache returning undefined;
- orcad migration states missing migrationId/manifest/receipt, with a
toEqual pinned to that incomplete shape;
- partial repos, metadata, folders, project groups and notification rows.
* refactor(renderer): resolve suppressed React hook lint instead of disabling it
109 of 187 react-hooks/react-doctor suppressions fixed:
- ~95 exhaustive-deps disables only hid stable refs and setters passed
through controller objects; list them (identity never changes, so
nothing re-runs), plus a few real stale closures (tabId/worktreeId).
- Effects keyed on one value that read the latest props now use
useEffectEvent (WebConnect, skill freshness, Bitbucket dialog seeding,
Landing preflight, automation catalog, structured-session recovery,
file explorer).
- The conditional layout-owner hook is selected once at module load from
the build constant instead of a rules-of-hooks disable that also hid
the whole controller from compiler and react-doctor rules.
- A hook disable was masking a react/purity Date.now() in the palette's
recent-tabs memo; sample it when the snapshot is captured.
- Three identical debounced-search effects share
useTaskSearchDebouncedApply; layout snapshot merge helpers move out to
stay under max-lines.
Remaining suppressions are mount-once resources, invalidation epochs,
deliberately keyed fields, and test harnesses that mock the dispatcher.
* chore(ratchet): exempt test harnesses and fixtures from the focus-read ratchet
The ratchet skipped *.test-fixture.ts but scanned *-test-harness,
*-test-fixture(s) and *.test-support files. Those seed settings with
getDefaultSettings (which the ratchet discovers as a focus reader) and
never route host work, so 17 baseline entries were false positives, and
replacing a test's `settings: {...} as never` with typed defaults tripped
it. Match the repo's test-support names and prune (which also drops one
stale entry), and rename the frame-ordering harness to *-test-harness like
its siblings. A blanket "-harness" match would also exempt
e2e-terminal-pty-harness, which production imports, so the names stay
explicit.
* test: merge duplicate shared/constants imports
* revert(file-explorer): restore original tree load effects pending SSH e2e investigation
* test(runtime): drop RuntimeStore cast now that the fixture is typed
---------
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
The census built a whole-repo TypeScript program (17,740 root files) inside
a unit worker, peaking at about 7 GB, and ran out of memory on loaded
machines. Its invariant, that a layout-owner build never reads or writes a
PTY record's pane copies, is proven at runtime by
pty-pane-copies-untouched-main.test.ts, which traps every access.
* fix(runtime): a workspace sleep no longer fails when another workspace sleeps at the same time
Sleeping two or more workspaces at once failed every one but the last with
terminal_liveness_unavailable, so their terminals kept running. Each sleep asks the terminal
host which PTYs are live; when a newer listing starts while one is in flight, the older answer
is discarded as stale and retried once. Two sleeps leapfrog each other: each retry starts a
listing that makes the other's stale, and the second retry gives up.
A targeted read that a newer listing overtook now waits for that listing and uses its answer,
which is at least as fresh as the read itself, instead of starting another listing. Lifecycle
changes (a PTY spawning or exiting mid-listing) keep the single retry they had.
The listing step moves into its own layer to keep the refresh within the file-size limit.
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(runtime): an overtaken PTY listing joins only a newer one that asked the same question
A targeted read that a newer listing overtook adopts that listing's answer. That newer listing
could have asked without foreground-process evidence, or waited less for slow hosts, so the read
could get rows without the evidence it asked for, or fewer hosts than it would have waited for.
It now joins only a newer listing with the same evidence option and a deadline at least as
late as its own; otherwise it keeps its single re-list.
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(runtime): a PTY read with no deadline stops after one listing budget, however many it joins
Each listing an overtaken read joined got a fresh 3 s when its caller set no deadline, so
pollers starting listings faster than a slow SSH census finished could keep such a read waiting
without end; before joining it gave up after two listings. The read now fixes one deadline up
front (the caller's, or one listing budget from now) and every listing it joins shares it.
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
A hook-reported agent under an older shell title (e.g. zsh before Codex paints its title) keeps its agent status and session id, so mobile can open a fresh Codex chat; PTY titles now record when they were observed. Fixes#32030. Supersedes #32046.
Co-authored-by: dorian-kwon <61652817+dorian-kwon@users.noreply.github.com>
* fix(agent-status): keep a running Codex turn on paired and mobile views while /side is shown
Codex's terminal title follows the thread it displays, so opening /side idles the title while the main turn runs. The paired/mobile session projection read that idle title, newer than the main turn's last hook, as the turn ending and published a title-only done row with no prompt. A Codex row whose hooks report the main turn running now owns the title interval; the turn's end still arrives by hook or rollout.
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(agent-status): keep a Codex main turn waiting on approval through /side on paired views
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(agent-status): leave restored Codex rows to the existing title rules
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(agent-status): stop a running Codex turn at a PTY process replacement
A replacement process on the same PTY id invalidates its predecessor's title-interval evidence; record when that happened so a predecessor's running Codex hook cannot outlive it.
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
* fix(runtime): a pane's new process does not wear its previous run's Done (STA-12043)
* fix(runtime): keep the superseded turn's segment and date process start at spawn request
* fix(runtime): take the identity row's segment from the turn clients were shown
* fix(terminal): answer a background pane's startup queries while its paired view is paused
A paired desktop pauses the output of a terminal it is not showing. The host
drops that output, but it still counted the paused view as the one answering
terminal queries, so main's query responder stayed silent too. A fish started
in such a pane (for example by `orca terminal create`) sent DA1, got no
answer, and stalled 10 s before warning.
A multiplex stream now registers with its pause state, and main answers the
queries of output a paused view drops, exactly as it does for output the
hidden-pane gate drops. A view that receives the output still answers it, so
each query is answered once.
Fixes#32944
Co-authored-by: Ben Grynhaus <ben.grynhaus@wiz.io>
* fix(terminal): answer queries in output a pausing remote view discards unsent
A chunk ingested while the view was still receiving yields its queries to
that view. If the view then pauses, the host drops the chunk from the
output batcher, or clears it from the ack backlog, before the view ever
parses it. Nothing answered those queries.
The pause now carves the query bytes out of what it discards, with the
same extraction the hidden-pane gate uses, and hands them to main's
existing responder. The responder answers only while no other view is
receiving that terminal's output.
Refs #32944
Co-authored-by: Ben Grynhaus <ben.grynhaus@wiz.io>
* revert: answer queries in output a pausing remote view discards unsent
This reverts commit 3fc500fe09. Answering those queries later through
main's emulator injects bytes into its live parser. That can cancel a
partial escape sequence, it answers cursor and mode queries against
state that has since moved on, and it can answer twice when two views
pause one after the other. An exact fix has to capture the replies when
the bytes are first parsed and track delivery per view, so it is left as
a follow-up.
Also renames a test helper to say what it reads.
---------
Co-authored-by: Ben Grynhaus <ben.grynhaus@wiz.io>
Fold a standalone copy of the leading spinner frame in agent titles (Codex 0.155–0.163 `⠙ renaming... ⠙ | x`) so the title tracker stops republishing session tabs every 100ms. Fixes#27598. Supersedes #27599.
Co-authored-by: outof-place <69466055+outof-place@users.noreply.github.com>
* fix(cli): say a headless terminal create found no workspace, not that the window is missing (#33044)
On a windowless `orca serve` host, `orca terminal create` from a folder
outside any workspace failed with "No renderer window available". The
create falls through to the window-only path because no workspace was
resolved, so name that and point at --worktree instead. Behavior is
unchanged; only the error message for this already-failing create.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(runtime): pass the no-workspace message to the window lookup instead of relabeling every error
A catch-all would rename any other window-lookup failure as a missing workspace.
---------
Co-authored-by: tnfhrnsss <tnfhrns@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Starting a saved pane with no live terminal (a paired client opening it, or a restore)
fell back to the tab's launchAgent for every pane with no recorded session, so a shell
split beside an agent pane came back as a fresh agent. The host's tab projection now
publishes the tab-wide launchAgent only on a sole pane, as the window already does, so
the pane start and every reader of that projection see the same per-pane evidence.
Co-authored-by: Claude <noreply@anthropic.com>
* fix(runtime): stop paired desktops republishing mirrored editor tabs
When two desktops pair both ways, B mirrored A's editor tabs and then
published them in its own session inventory as if B had opened them. A
then applied B's copy, which took over A's own tab.
isMobilePublishableOpenFile now skips rows marked
mirroredFromRuntimeSession, the marker is part of the open-files sync
projection so a flip republishes, and the marker is saved with the
session and restored so a relaunched client does not republish its
restored mirrors before the host's first snapshot.
Based on #25877 by BearMett.
Co-authored-by: BearMett <agomdole@gmail.com>
* fix(runtime): keep restored mirrors through unpublished frames and out of headless publication
A restored mirror now carries its marker, so an unpublished host frame
must not cull it (and its recovered draft). The windowless publication
skips persisted mirrored rows for the same reason the window does.
Co-authored-by: BearMett <agomdole@gmail.com>
---------
Co-authored-by: BearMett <agomdole@gmail.com>
* fix(wsl): no synchronous distro-home probe on the main process at startup, and no 5 s kill of a booting distro
Follow-up to #33175, from the startup wsl.exe trace:
- getAllowedRoots (file-access authorization) resolved a WSL-mirrored workspace
root with the synchronous home probe; it and isPathAllowed are now async (every
caller already was).
- skills:discover resolved a WSL target with the synchronous probe on load; the
skill target resolution is now async.
- the async home probe waits up to 60 s instead of killing wsl.exe at 5 s, since a
kill mid-boot leaves the distro failing every call with E_UNEXPECTED.
* fix(wsl): bound file authorization's wait for a WSL home; no sync probe over an async one
Review follow-ups: a hung distro must not hold every file check for the async
probe's 60 s, so authorization waits at most 5 s for a mirrored root's home and
falls back while the probe keeps running and fills the cache. And a synchronous
getWslHome no longer starts its 5 s-bounded probe while an async one is waiting
out the same distro's boot.
* chore: prune the main-process sync launch ratchet (one fewer sync wsl.exe)