Commit Graph
17532 Commits
Author SHA1 Message Date
Neil a33b40f0d6 fix(orcad): harden the startup qualification marker (execPath, node-pty load failure) (#35513)
* fix(orcad): harden the startup qualification marker (execPath, node-pty load failure)

- The key includes process.execPath, so a slot re-pointed at another Node build re-qualifies.
- A node-pty load failure in orcad (degraded local PTY routing) discards the slot's marker, so
  the next launch re-probes node-pty and reports the cause; reported through a small listener so
  the shared provider stays free of orcad imports.
- Tests: a schema-1 marker never matches; a Windows slot is never qualified by a matching marker.

* fix(orcad): discard the startup marker only after an in-flight record lands

A node-pty failure right after readiness could unlink the marker before the confirm's write
renamed it into place, recreating it. The discard now waits for the last marker write first.
2026-10-28 18:02:47 -07:00
Neil 9babef2866 fix(wsl): background preflight and agent detection never boot a stopped WSL distro (E9) (#35411)
* fix(wsl): background preflight and agent detection never boot a stopped WSL distro (E9)

Integration checks (git/gh/glab --version and auth status) and agent detection ran inside the
focused workspace's WSL distro on every mount, poll and status-bar render, and wsl.exe starts a
stopped distro. They now take a settled running read first and refuse (WSL_DISTRO_STOPPED or
WSL_DISTRO_UNVERIFIABLE) when it is not running. Window focus/visibility, retry buttons, agent
refresh buttons, a runtime choice in Settings and first-run onboarding pass wakeWslDistro, which
runs the check as a user act on that distro only. Running distros behave exactly as before.

* fix(wsl): a focus wakes only a focused WSL workspace's distro; end-to-end preflight gate test

A focus with a native workspace active sends no wake. Ports the real running-list preflight case
from #35395 and adds user-act scoping cases.

* test(wsl): model the running gate in the preflight RPC suite and cover a stopped distro

Windows CI runs the real gate, so the WSL detection case must state that the distro runs.

* fix(wsl): an agent refresh click never joins a background refresh it would be refused with

Store the wake flag with each in-flight refresh, as preflight.ts does, so a status-bar or Agents
refresh click during a mount refresh reaches main as a user act. Note why the RPC project branch
stays ungated.

* fix(wsl): a refused background check waits for the distro, and an agent picker wakes it

A preflight or agent detection refused for a stopped WSL distro was final: once the distro came
up, nothing re-ran it, so the tab-bar + menu offered no WSL agents (real-WSL golden). Now a refusal
is deferred until the distro is next confirmed running (deferUntilWslDistroRunning), and main tells
renderers to re-ask. Opening an agent-launch picker (tab-bar +, composer, continuation dialog,
source-control action dialog) whose list was refused retries it as a wake, never joining a
background probe.

* fix(wsl): an open agent picker wakes a refused list once, and never retries real failures

The picker wake fired whenever the list read 'failed', so a woken probe that failed again
(pending -> failed) re-fired it: an endless wsl.exe loop while the picker stayed open, and repeated
probes for native failures too. It now fires at most once per open per target, and only when the
last probe was an E9 refusal (distro not running/unverifiable), matched by the gate's message.

* fix(wsl): forget agent-inventory refusals when the inventory or its project contexts are cleared
2026-10-28 18:01:42 -07:00
3a51382df5 feat(wsl): scope and path map for converting UNC Windows-drive projects (D1c-4a) (#33108)
* feat(wsl): offer Git for Windows in a Windows-drive WSL project's settings

Project settings show a Git row for a WSL-runtime project on a Windows drive (WSL
hosts on). "Use Git for Windows" checks the project, shows any blocker in plain words,
optionally sets core.autocrlf in the repo, and saves the returned runtime through the
normal project update. Once converted the row says where Git and terminals run.
Switching the distro keeps Git for Windows instead of silently dropping it.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(wsl): offer the Git choice only for a Git repo, not a folder

Co-Authored-By: Claude <noreply@anthropic.com>

* feat(wsl): scope and path map for converting UNC Windows-drive projects (D1c-4a)

The mover refuses a project kept as a distro's UNC path into a Windows drive
(\\wsl.localhost\<d>\mnt\c\x). D1c converts it in place to C:\x. This adds the pure
part: which local repos and folder workspaces qualify (every stored path on the drive;
not remote; not already a C:\ project here), the UNC → drive path map, and the
worktree id each converted worktree gets (same repo id, drive path). Reuses the mover's
list of a repo's stored paths. Nothing calls it yet.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(wsl): say Windows denied access when adding a WSL path it refuses, not that it isn't a repo

* fix(wsl): name a refused WSL path only with WSL hosts on

The new message replaced "Not a valid git repository", which the renderer
matches to offer adding the folder as a non-git project. With the WSL hosts
gate closed the add fails with the usual text again.

(cherry picked from commit a5a70dad7743f679fd764c3e17a3e27b71c9f28b)

* fix(wsl): convert one UNC spelling per drive folder, and only folders the distro mounts from that Windows drive

- Two UNC spellings of one drive path (\\wsl$ vs \\wsl.localhost, \mnt\C vs \mnt\c) would
  both convert into two projects. Each accepted conversion now claims its drive path, so the
  next spelling is refused as a duplicate. Folder workspaces get the same duplicate check.
- Any /mnt/<letter> read as a Windows drive. The scope now takes the distro's Windows-drive
  mounts (drvfs/9p from its mountinfo, parsed as the WSL-host drive guard does) and converts a
  path only when its mount is that same whole drive. A folder workspace has one path, so that
  check is its mixed-location check too.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(wsl): match the distro's drive mount point case-sensitively, so a real /mnt/C directory never converts onto C:

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-28 18:00:29 -07:00
Neil 134226ae5e fix(runtime): never hand a parent the token of a delegated child the save dropped (#35510)
upsertDelegatedMobileDevices returned every planned entry, including a child whose row was
removed on disk and so dropped by the merged save; the parent would pass that dead token to the
phone. It now returns only entries still in the written registry.
2026-10-28 17:58:31 -07:00
OrcaWinandOrcaWin 43cf7b4b24 fix(browser): release native messaging startup queue on close (#35344)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-28 17:56:07 -07:00
OrcaWinandOrcaWin 1775410850 perf(renderer): reuse folder connection inference across store writes (#34800)
* perf: cache folder workspace connection inference

* fix: preserve folder resolver fallback for partial catalogs

* test(renderer): trim folder connection cache test to one direct warm-read check

Drop the zustand store wrapper and duplicate 1,000-repo case, and use a neutral fixture path.

* test(renderer): drop folder connection read-count test

The invalidation and tri-state test guards observable behavior; the getter
read counter only pinned the cache implementation.

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-29 00:55:53 +00:00
OrcaWinandOrcaWin 601bf63c62 Preserve concurrent PR comment changes when thread resolution fails (#35315)
* fix(github): preserve concurrent changes on thread rollback

* test(github): assert reaction publication before rollback

* fix: restore thread resolution on newly posted replies

* test(github): trim thread rollback tests to behavior guards

Drop duplicate false/throw variants, the cleared-cache and paired-source
cases, and the helper case already covered by the remaining lib tests.

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-28 17:55:26 -07:00
Jinjing 33d57df894 test(preflight): align enabled agent detection mock 2026-10-28 17:51:53 -07:00
Jinjing 5af784a77e fix(preflight): ship worker and preserve CLI liveness 2026-10-28 17:51:53 -07:00
Jinjing 0eb18d9775 fix(preflight): isolate directory enumeration 2026-10-28 17:51:53 -07:00
Jinjing 0710886dc5 fix(preflight): preserve network path detection 2026-10-28 17:51:53 -07:00
Jinjing 7c364fa757 fix(preflight): preserve path detection compatibility 2026-10-28 17:51:53 -07:00
Chen f54448bfb7 Limit literal PATH probes to agent detection 2026-10-28 17:51:53 -07:00
Chen b2fb4d1d38 Preserve extensionless PATH command detection 2026-10-28 17:51:53 -07:00
Pr1p a40db68ed5 fix(preflight): address review on the batched PATH lookup
- Deduplicate candidates per command: 'tool' and 'tool.CMD' may resolve to
  the same on-disk file and both must still be found.
- Probe known candidate names directly when readdir is denied (EACCES/EPERM):
  an execute-only directory cannot be listed, but stat on known names works,
  which is what the per-candidate lookup did.
- Skip the install-dir fallback's PATH re-scan: the batch already proved the
  missed commands absent on the PATH it searched, and that PATH is a superset
  of the fallback's (merged persisted PATH on Windows, the same filtered PATH
  on a WSL host), so the fallback scans install directories only.
2026-10-28 17:51:53 -07:00
Pr1p 6af1ef000a perf(preflight): read each PATH directory once during agent detection
findCommandsOnLocalPath() replaces one isCommandOnPath() call per agent
command: it reads each absolute PATH directory once with readdir and matches
command names and PATHEXT permutations in memory, then verifies only the
hits through isExecutableFile. Symlink, directory, permission,
case-insensitivity and absolute-only PATH semantics match the per-candidate
lookup. On the machine in the issue this replaces about 24,000 stat() calls
per detection run with about 38 directory reads.

Fixes #34636
2026-10-28 17:51:53 -07:00
OrcaWinandOrcaWin 769d382f24 fix(editor): restore Mermaid reading position after rendering (#35031)
* fix(editor): restore diagram scroll after async rendering

* fix(editor): retain pending diagram scroll while hidden

* fix(editor): key Mermaid restore on rendered source and cancel it on user scroll

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-28 17:51:35 -07:00
OrcaWinandOrcaWin 78279250d0 Keep Markdown completions available when a sibling pane changes files (#34975)
* Keep Markdown completion catalogs owned by surviving panes

* Assign completion test editor ref in a layout effect

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-28 17:50:04 -07:00
OrcaWinandOrcaWin 8600995271 fix(editor): preserve folds and horizontal scroll across tab switches (#34810)
* fix(editor): preserve folds and horizontal scroll across tabs

* refactor(editor): keep reading state cache with its lifecycle

* test(editor): give stale-cache model its URI

* refactor(editor): keep editor view state cache beside diff view state

Move editorViewStateCache into scroll-cache.ts, clear it in the shared model
lifetime fixture, drop the e2e evidence spec and the duplicate LRU test.

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-28 17:48:32 -07:00
OrcaWinandOrcaWin ed7fe7d5dc Combine exact PR fields and stack summary queries (#35295)
* Read sidebar PR and stack metadata in one GraphQL query

* Preserve direct PR error recovery without duplicate GraphQL reads

* Keep combined sidebar queries out of merge preflight

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-28 17:46:20 -07:00
OrcaWinandOrcaWin 4c42c4448b Combine PR participants and viewed-file queries (#34842)
* perf(github): combine PR detail context reads

* perf(github): avoid redundant file retry after context failure

* Isolate viewed-state failures and preserve cached PR metadata

* Start participant recovery independently of cached metadata

* Give cached metadata and PR context independent semaphore permits

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-28 17:46:16 -07:00
OrcaWinandOrcaWin a516ba9a03 perf(github): reuse repository merge metadata reads (#34848)
* perf(github): reuse repository merge metadata reads

* Preserve capability reuse across worktree directories

* Use required braces for capability writer cleanup

* Isolate capability configuration and cancellation lifetimes

* Keep capability fixtures independent of ambient configuration

* fix(github): isolate fallback configuration directories

* Keep successful merge metadata through competing read failures

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-28 17:46:11 -07:00
OrcaWinandOrcaWin 127487f931 perf(github): load PR conversations without duplicate REST requests (#34747)
* perf(github): avoid redundant REST reads for PR conversations

* fix(github): retain valid inline comments beside missing numeric IDs

* fix(github): preserve comment quota errors during REST recovery

* fix(github): order review summaries by submission time

* fix(github): keep forced PR conversation refreshes out of in-flight sharing

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-28 17:46:07 -07:00
e6a27089e6 feat(wsl): offer Git for Windows in a Windows-drive WSL project's settings (D1c-3) (#33097)
* feat(wsl): offer Git for Windows in a Windows-drive WSL project's settings

Project settings show a Git row for a WSL-runtime project on a Windows drive (WSL
hosts on). "Use Git for Windows" checks the project, shows any blocker in plain words,
optionally sets core.autocrlf in the repo, and saves the returned runtime through the
normal project update. Once converted the row says where Git and terminals run.
Switching the distro keeps Git for Windows instead of silently dropping it.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(wsl): offer the Git choice only for a Git repo, not a folder

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-28 17:44:41 -07:00
OrcaWinandOrcaWin d57e55472c perf(editor): skip full-text reads for ignored Monaco content events (#34920)
Subscribe to onDidChangeModelContent directly instead of the
@monaco-editor/react onChange prop, which calls editor.getValue() before
Orca's ownership and programmatic-sync checks run. Programmatic echoes
(external reloads, shared-record commits, read-only live tail) no longer
materialize the full model text only to discard it.

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-28 17:43:51 -07:00
OrcaWinandOrcaWin b510cd1f77 perf(browser): reuse tab resolution within extension enumeration (#35327)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-28 17:42:58 -07:00
NeilandClaude d4b1041147 fix(scripts): show check:changed progress and bound each step (#35507)
Output stays buffered per task, so a long unit-test step looked hung for
30+ minutes. Print each task's completion, a 60s heartbeat naming running
tasks, and kill any step after 30 min (--timeout=<minutes> overrides).

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-29 00:42:05 +00:00
OrcaWinandOrcaWin c8fe5d4b96 perf(editor): skip Markdown classification beyond the hard render cap (#34798)
Above the 1 MiB override cap a Markdown file can never render rich, so
skip the unsupported-syntax scan and keep those documents out of the
eligibility cache.

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-28 17:41:37 -07:00
OrcaWinandOrcaWin 53cbc49e76 fix(editor): keep conflict navigation in its owning pane (#34902)
Conflict Next/Previous published a path-only reveal, so every editable pane
showing that file jumped, and overview mirrors never moved. Target the reveal
at the requesting file id and pane view id, and let read-only overview
mirrors accept only reveals that name them.

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-28 17:41:33 -07:00
OrcaWinandOrcaWin f0c86458c3 fix(editor): copy gutter URLs from the owning file (#34922)
* fix(editor): copy gutter URLs from the owning file

* fix(editor): scope gutter remote URL fallback to the editor owner

Look up the gutter menu's owning file by fileId, falling back to a
same-path match only within the editor's worktree so conflict-overview
editors with synthetic ids still copy a URL. Drop the e2e proof spec
and trim the unit test to the same-path/different-owner regression.

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-28 17:41:09 -07:00
OrcaWinandOrcaWin 3b81adb330 fix(editor): scope default-pane reading positions by file owner (#34816)
Same-path files with different owners (runtime hosts or worktrees) shared
Monaco, rich-markdown, notebook, and PDF/media reading positions when the
tab id equals the file id. Key them by file id, matching the diff and
markdown preview keys.

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-28 17:41:05 -07:00
NeilandKelvin Amoaba 5470ff907c fix(mobile): stop review notes from disappearing or coming back after deletion (#31699)
* fix(mobile): stop review notes disappearing or coming back after deletion

The phone sent its whole notes list on every add or delete, and the host
stored it as is. A note added on desktop after the phone loaded was wiped
by the phone's next edit, two quick taps could overwrite each other, and a
failed save rolled back to an old snapshot.

worktree.set now takes an optional diffCommentsBase, like linkedItemsBase:
the host applies only the writer's own adds, edits and removals to the
stored notes. The phone sends the list it started from, shows the host's
merged list from the reply, and undoes only its own change on failure.
Older hosts drop the field and replace the list as before; older phones
send no base and get the same.

Co-authored-by: Neil <neil@stably.ai>

* fix(mobile): keep loaded review notes when an early save fails

The first load was discarded once any save started, so a save that failed
before it landed left the host's notes hidden. The load now applies the
phone's changes made during the read onto the host's list instead.

* fix(mobile): send review-note requests one at a time

Two in-flight saves could reach the host in either order, so adopting the
later reply hid a note the earlier save had stored. Session notes now send
one request at a time and reconcile every reply with the phone's changes
made since it was sent, replacing the sequence counters.

* fix(mobile): drop review-note saves queued behind a failed one

A save queued behind one that failed still sent the list built on the
failed change, and an older host stores that list whole. Those saves now
undo their own change instead of sending. Also renames the shared base
type so it no longer shares a name with the renderer's mutation record.

* fix(mobile): show review notes as the host's list plus pending saves

A queued reply was reconciled against the list captured at tap time, so a
note desktop deleted meanwhile came back on the phone. The phone now keeps
the host's last list and its unanswered saves per workspace and shows the
two combined; a reply for another workspace is ignored. The review screen
also shows the host's list after a save, so an edit to a note desktop
deleted no longer looks saved.

* fix(mobile): fail queued review-note requests while disconnected

A notes request queued behind a pending load waited for a reconnect with
no timeout, holding every later save. Notes requests now fail at once when
the connection is down, like terminal input.

* fix(mobile): drop every review-note save built on a failed or dropped one

A save made while a dropped save was still pending carried its change,
so an older host could store it. Each failed or dropped save now moves
the failure count.

* fix(mobile): send each review-note save as the host's list plus its change

Each queued save now builds its payload when it is sent, from the host's
last list plus only its own change. A note added before the first load
no longer replaces the loaded notes on an older host, and a failed save's
change never rides along, so later saves no longer need dropping.
Delivered-note cleanup waits for a reconnect again so those notes are not
sent twice.

---------

Co-authored-by: Kelvin Amoaba <97001695+AmoabaKelvin@users.noreply.github.com>
2026-10-29 00:40:56 +00:00
OrcaWinandOrcaWin dd34216da9 perf(editor): skip Markdown link structure scans without link delimiters (#35055)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-28 17:40:46 -07:00
OrcaWinandOrcaWin 7a614b0cc4 perf(editor): reuse the content snapshot during mount sync (#34921)
The mount reconciliation already reads the full model text for its
stale-cache guard. Pass that snapshot into syncContentOnMount so a mount
reads the model once instead of twice.

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-28 17:40:42 -07:00
OrcaWinandOrcaWin 1bd7f54712 fix(editor): apply diff Rich mode to the opened file ID (#34898)
handleOpenDiffTargetFile keyed editor/markdown view-mode preferences by
the raw file path, but openFile returns owner-scoped IDs for remote
runtime files and same-path tabs in other worktrees, so Rich mode was
lost or written onto another owner's tab.

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-28 17:40:17 -07:00
OrcaWinandOrcaWin 05c2667b68 Fix notebook scroll tracking after source recovery (#35034)
Key the notebook scroll listener and restore effects on notebook
readiness instead of raw content, so the listener attaches once an
invalid notebook becomes valid and content republishes no longer snap
the view back to a stale cached position.

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-28 17:40:12 -07:00
OrcaWinandOrcaWin aadde96e4e fix(editor): keep notebook cell undo across cell and tab switches (#34952)
Notebook cell models were anonymous and disposed whenever a cell lost
focus or the notebook view unmounted on a tab switch, so Undo did
nothing after returning to a cell.

Give cells that have a stable nbformat id a vscode-userdata model URI,
scoped to the view, so Monaco's model service keeps and restores the
disposed model's undo stack. Monaco restores only when the text is
unchanged and bounds retained history to its closed-file budget.
Id-less cells keep anonymous models because their position-based key
can move to a different cell, and a duplicate id falls back to an
anonymous model instead of colliding.

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-28 17:40:06 -07:00
OrcaWinandOrcaWin cdbaccb583 fix(editor): cancel paste when its target model changes (#34904)
Snapshot the paste target (model, container, focus) before the context-menu
clipboard IPC read and before the yielding byte measurement of large pastes,
and re-check it afterwards so a model swapped during the await (e.g. a diff
refresh via setModel) does not receive the paste.

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-28 17:40:00 -07:00
Kelvin Amoaba 785cd30ee9 chore(mobile): bump to 0.0.60 and Android versionCode 24 (#35505) mobile-android-v0.0.60 2026-10-29 00:39:21 +00:00
OrcaWinandOrcaWin 90da32500f fix(editor): keep CRLF pairs in one chunk during large Monaco paste (#34976)
Monaco normalizes line endings per edit, so splitting a CR from its LF
across chunked executeEdits calls inserted an extra blank line.

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-28 17:39:09 -07:00
Neil 28b904939c fix(runtime): a device registry save never resurrects a device removed on disk (#35483)
* fix(runtime): a device registry save never resurrects a device removed on disk

Every DeviceRegistry save wrote orcad's whole in-memory list. A lastSeen flush (250 ms after any
socket auth, and again at shutdown) could therefore write back a device an admin had just removed
from orca-devices.json on the host, silently undoing the revoke; it also dropped rows another
writer had added. Saves now re-read the file and write the in-memory change merged over it: rows
this process knew of that are gone from disk stay gone (in memory too), rows added on disk are
kept, and this save's own adds and removals apply. The write stays the secure-file atomic rename.
The pairing-repair e2e logs the registry's device ids after the kill and after the reconnect.

* fix(runtime): tombstone devices this process removed so a stale writer can't restore them

Review of #35483: after removeDevice(a), a stale writer (an old orcad's flush during an SSH
relaunch or upgrade overlap, an external tool) could write a back; the next save treated it as
new on disk, adopted it and let it authenticate. DeviceRegistryWriter now remembers every id
this process removed, recorded before the write so a failed load-time cleanup counts too, and
never adopts those from disk. replaceRow reports false when the merge dropped the row, and a
pending offer removed on disk is replaced instead of handed out.
2026-10-28 17:38:05 -07:00
Neil 70db375c56 perf(orcad): spawn the terminal daemon before the runtime graph evaluates (#35486)
* perf(orcad): spawn the terminal daemon before the runtime graph evaluates

The daemon spawn now starts right after the login env lands, before the runtime graph's imports
instead of midway through them. Bundled dynamic imports resolve as microtasks without yielding to
the event loop, so two loop turns between the first imports let a finished login env start the
daemon process, which then boots on another core while ~0.4 s of runtime modules evaluate.

* fix(orcad): register the daemon disconnect as soon as its spawn starts

An import or init step that throws between the daemon spawn and the old registration point left
no cleanup to disconnect the in-flight daemon. It is now registered right after daemonStartup,
first, so it still runs last.
2026-10-28 17:37:46 -07:00
OrcaWinandOrcaWin 6f41a55b8b fix(clipboard): preserve copy order across text, images and files (#35332)
* fix(clipboard): order text, image and file IPC copies

* fix(clipboard): time out stalled file path resolution in the shared copy queue

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-28 17:36:22 -07:00
Neil 828fe5fea3 fix(wsl-mover): say when a refused undo left the host's terminals asleep (#35449)
* fix(wsl-mover): say when a refused undo left the host's terminals asleep

* fix(wsl-mover): count only running workspaces as asleep, and flag post-sleep refusals
2026-10-28 17:34:55 -07:00
Kelvin Amoaba bbb7f2d695 fix(agent-status): keep Grok background work visible after a cancel (#35495)
StopCancelled carries no backgroundTasks, so a cancelled Grok turn settled
done while the shells and subagents it left running kept going. Track
Grok's own task ids per pane and settle the cancelled row on each task's
own end.
2026-10-29 00:34:00 +00:00
Neil ed8f62cf94 fix(wsl): session history reads never boot a stopped WSL distro (E9) (#35367)
* fix(wsl): session history reads never boot a stopped WSL distro (E9)

Transcript and session-history reads touched \\wsl.localhost shares, and ran
`wsl.exe --exec` probes, for any distro the root list named. Those touches are
the OpenCode reader, its setup, HOME and realpath probes, and the session
scanner and search index. Nothing re-checked that the distro still ran. A
`wsl --terminate` mid-scan, or a list taken while the distro was still
stopping, let background work boot it again.

Every UNC transcript touch (stat, readdir, open, access, readFile) and every
scanner `--exec` now asks a settled running read first. That read is no older
than 5 s, because the scanner process hears of no stop by itself. A user act on
the distro still passes.

* fix(wsl): opening a chat starts its stopped distro; scanner hears main's stop notes

A user-opened chat, a history page and an AI Vault resume start the
transcript's stopped WSL distro once, as a user act, so its history
shows; watch and scan reads stay background. Main forwards WSL stop and
wake notes to the session-scanner process so a terminate main saw is
honoured there at once.

* fix(wsl): type the scanner note channel structurally; test the resume wake

Keeps node:child_process out of the new scanner-notes module (the
process-host import check) and adds a test that fails if an AI Vault
resume stops starting the session's WSL distro.
2026-10-28 17:32:51 -07:00
Neil bc6a5ec32e fix(wsl): flag-on liveness and post-launch WSL steps use settled running reads (E9) (#35433)
L1: the orcad liveness supervisor's heartbeat/verify reads, its recovery gate, the no-boot
reconnect check and the connector's passive probe now take a settled read of their own distro, so
a list probed while the distro is still stopping cannot admit a holder spawn, identity read or
reconnect that would boot it again.
L2: a Git cancel/timeout's guest kill, the WSL move's process table and each step of the Codex
session bridge chain check the distro first. A confirmed stop counts as the group gone / an empty
table / the end of the chain; an unanswered read proves nothing and spawns nothing.
2026-10-28 17:32:29 -07:00
OrcaWinandOrcaWin b685340243 perf(browser): skip unused frame scans for site permissions (#35326)
* perf(browser): skip unused permission frame inventories

* test(browser): collapse frame-inventory regression to one case

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-28 17:29:45 -07:00
Jinjing 2b73288a0b Recover native OpenCode failures in chat sessions (#35247)
- Read per-turn provider errors from OpenCode’s SQLite history
- Preserve quota, billing, access, and retry details over generic ACP errors
2026-10-28 17:29:10 -07:00
OrcaWinandOrcaWin 34643c383c fix(emulator): settle gestures when the peer closes after the final point (#35329)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-28 17:28:35 -07:00