Commit Graph
16883 Commits
Author SHA1 Message Date
Neil 1dec1ebc35 refactor(shared): group native chat visual contracts (#34296) 2026-10-27 00:03:29 -07:00
Kelvin Amoaba 30872835cd fix(browser): type text that starts with a dash literally instead of as an agent-browser option (#34289)
* fix(browser): type text starting with a dash literally instead of as an agent-browser flag

* fix(browser): keep fill scripts on eval --stdin and send well-formed batch text

* fix(browser): leave passthrough multi-command batch replies unwrapped

* fix(orcad): pass the wait process timeout through the run options

* refactor(browser): let caller stdin imply argv mode and share the batch decoder in tests

* test(orcad): decode batch commands in the provider selection fake
2026-10-27 07:01:46 +00:00
Brennan Benson a0e7fa0619 Keep Claude approval choices across model changes without freezing delivery (#34031)
* fix(native-chat): keep Claude approval choices across model changes without freezing delivery

A Claude chat saved as "Approve for me" could reopen asking for every approval,
because Orca read the folder's saved model list as launch policy, and a model
change could keep running in a weaker approval mode Claude opened with. The
first fix for this was reverted after it froze the app: restored history left
a turn reading as running, a send was refused against it, and delivery retried
the same send with nothing changed.

- The saved approval choice goes to Claude as-is; the menu offers every mode.
- Orca records the mode Claude actually opened in. A send that picks a new
  model reopens Claude first when that mode differs from the one requested,
  only when the chat owes no work; Orca mail notices never reopen it.
- A message sent while a Claude turn is running joins that turn on its current
  choices; new choices apply at the next new turn. Nothing is refused.
- History catch-up closes every turn it opens, in the thread it opened in.
- At startup, a turn reading as running under the new agent that the agent is
  not running is ended as interrupted.
- Delivery goes round again only after a step shows what it changed (a commit,
  a different child, a start it joined ending, or a wake); otherwise it waits
  for the next change instead of repeating the same step.

Tracked in STA-10953.

* fix(native-chat): preserve execution evidence at dispatch

* Fix delivery iteration ownership and progress contracts

* Correct journal fixture types in delivery regressions

* Separate Claude input choices from error correlation
2026-10-27 00:01:09 -07:00
Brennan Benson 1c4d4a03bc feat: drag to reorder queued messages on desktop and phone (#34026)
* feat: drag to reorder queued messages on desktop and phone

* fix: use the queue grip button padding from its primitive

* fix: preserve the queue grip touch width with hit slop

* test: carry queue animation mocks into the chat view harness

* test: complete the shared chat view harness registrations

* test: carry the queue move cross-version wire contract

* Scope queue move feedback to the issuing chat and preserve phone touch width

* Keep queue reorder presentation stable during measurement and pending moves

* Keep measured row handoff tokens constant size

* Avoid rebuilding queue arrival IDs on unchanged renders

* Fix mobile queue regression test fixture boundaries

* Share the queued message leading slot with its reorder grip

* Fix queue regression fixture quality findings

* Check queue icons within the leading slot

* Allow every unsettled queued message to reorder

* Supply stable scope in queued row test mock
2026-10-26 23:57:36 -07:00
Kelvin Amoaba b01dc62972 fix(browser): copy and cut from streamed browser pages to the local clipboard (#34290)
* fix(browser): copy and cut from streamed browser pages to the local clipboard

The streamed frame forwarded Ctrl/Cmd+C and X to the host page as a
keypress, so the host's Chromium copied into the host machine's
clipboard. The chord now runs copy or cut inside the page over the
existing browser.eval and writes the text to the viewer's clipboard. A
cut deletes the selection only after that write succeeds.

* test(browser): read streamed keyboard RPC calls through the typed helper
2026-10-27 06:53:41 +00:00
217f935597 fix(updater): skip IPC when the main window is destroyed (#11567)
The updater kept a reference to the main BrowserWindow after it closed, and
every status/nudge/install-abort send read `webContents` on it. Electron throws
"Object has been destroyed" from that getter, so the hourly background check
produced main-process unhandled rejections from the MacUpdater failure path.

Route all updater IPC through UpdaterState.sendToMainWindow, which drops the
send when the window or its webContents is destroyed. The renderer re-pulls
status via updater:getStatus on mount, so nothing is lost. Updater test window
mocks now come from the shared updaterMainWindow helper.

Fixes #11544

Co-authored-by: Brennan Benson <brennan@stably.ai>
Co-authored-by: Neil <neil@stably.ai>
2026-10-26 23:51:44 -07:00
Kelvin Amoaba 50f898fbc3 fix(agents): recognise OMP and Pi titles after Orca rebrands them (#34292) 2026-10-27 06:49:11 +00:00
Kelvin Amoabaandoutof-place 8655ce670f fix(browser): deliver agent clicks and keys to pages that loaded while their pane was hidden (#34291)
A page that loads while its browser pane is parked (display:none) never
paints, and Chromium drops input to a document before its first paint.
orca click/hover/keypress/mouse on such a page reported success after a
~5 s mouseMoved stall while the page got no press or key.

Before agent input reaches a webview guest, from the CDP proxy queue or
the bridge's direct pointer and key routes, ask the page whether it has
painted. If not, hold its paint with the existing capture paint hold
until a paint entry appears or a few frames pass, once per document.

Co-authored-by: outof-place <contact@outofplace.space>
2026-10-27 06:48:31 +00:00
OrcaWinandOrcaWin 136721fcb9 test: remove53 low-value cases and8 suites (#34264)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-26 23:45:26 -07:00
MeapriandNeil 47567c6ac7 fix(terminal): refuse non-finite mouse coordinates so scroll never sends NaN to the PTY (#23330)
xterm's touch inertia gesture events carry no clientX/clientY, so with a
TUI requesting wheel reports a flick sent `ESC[<65;NaN;NaNM` to the PTY
(#20983). NaN slipped past `col < 0 || col >= cols`; the patched range
check in MouseService._triggerMouseEvent is negated so it fails closed.
Regenerate the beta.304 bundle and lock hash.

Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com>
2026-10-26 23:36:01 -07:00
Neil b29ae01912 fix(automations): show why a hook-review-blocked automation fails, keep it running, and stop stuck-tab pile-up (#33638)
* fix(automations): pause a schedule whose agent is stuck on a hook review

Codex opens a blocking 'Hooks need review' dialog when a hook in hooks.json is
new or changed. Only a person can answer it, so every later scheduled run of
an automation hit the same dialog and failed. Pause the schedule on the first
such failure and say how to recover. Also re-enable Orca's own Codex hook on
SSH installs, matching local installs.

Refs #28252 #23289

* fix(automations): keep a hook-review-blocked schedule running and say why it fails

Replace the auto-pause with a visible, self-clearing failure: the run error
explains the Codex hook review, the automation and run pages show it above
saved output, and earlier tabs stuck on the same prompt close so only the
newest stays open to answer. Runs succeed again on their own once the hooks
are trusted or removed.

* fix(automations): only close hook-review tabs the run still owns and that are provably unused

- Cleanup resolves the pane through runOwnHandle, so a cold-restored pane holding a new process is left alone.
- Close only on definite 'unused' input history, matching headless run-terminal retention.
- Catch failures from the fire-and-forget cleanup call.
- Show the run page error notice only for dispatch_failed runs, and add the missing en catalog keys.
2026-10-26 23:21:28 -07:00
Kelvin Amoaba cd757f4b19 fix(browser): pass orca wait's timeout through to agent-browser (#34283)
Condition waits never forwarded --timeout, so agent-browser always stopped at its own 25s default and --timeout 60000 still failed at 25s. orcad's external Chromium run and Electron sidecar socket also capped waits at a fixed 90s. One builder now passes --timeout (explicit or the documented 25000 default) on the local and orcad paths, process kills sit 5s above it, and every forwarding hop waits max(60s, T+30s).
2026-10-27 06:17:21 +00:00
Neil 43eb0b969c fix(opencode): give OpenCode 2 a private server only when another data dir holds the service port (#33784)
* fix(opencode): run managed OpenCode 2 accounts on a private server

OpenCode 2's background service binds one fixed port per machine, so a
second managed account's service could never start. Launch managed
accounts with --standalone, which picks its own port.

Fixes #33780

* chore(opencode): tighten standalone rewrite comments

* fix(opencode): use a private OpenCode 2 server only when another data dir holds the service port

Users with one managed account keep the shared background service. Orca
adds --standalone only when a live upstream registration
($XDG_STATE_HOME/opencode/service.json) belongs to a different data dir,
plus a short in-process claim for launches that start together.

* fix(opencode): judge resumed accounts by their applied data dir and claim the port only for real launches

Daemon spawns consume the resume request before the private-server check runs, so
derive the launch's own data dir from the applied account env when present. Only
take the shared-port claim when the --standalone rewrite can apply.
2026-10-26 23:06:43 -07:00
Neil ec8f4dd8bd refactor: group repository source-control AI settings (#34278) 2026-10-26 23:05:39 -07:00
OrcaWinandOrcaWin 0fcc74ea2a test: remove 56 low-value cases and 5 suites (#34268)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-26 23:03:21 -07:00
Wooseong KimandNeil 845e4668e3 fix(orchestration): stop calling unobserved worker input "submitted" (#21453)
When a worker's turn start was not observed, the dispatch receipt claimed
the input was "written and submitted". A swallowed Enter leaves the prompt
in the composer, so say the text and Enter were written, keep the wait bound
and possible causes, and point at `terminal read` before resending.

Co-authored-by: Neil <neil@stably.ai>
2026-10-26 22:59:09 -07:00
OrcaWinandOrcaWin 84494ce394 test: remove 338 low-value cases and 28 suites (#34234)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-26 22:58:55 -07:00
Neil fa4d2e99db fix(wsl): reap the bash stdio relay's cats before it exits (#34260)
* fix(wsl): reap the bash stdio relay's cats before it exits

The relay killed the surviving cat and exited at once. WSL's per-session init never reaps
orphans, so that cat stayed a zombie, its session never ended, and the distro never stopped
even with nothing of Orca's left in it (seen on every real-WSL idle-release run). Wait for both
cats after the kill.

* test(wsl): prove the bash relay waits for the cat it kills
2026-10-26 22:54:27 -07:00
hwantageandNeil 483573f0b9 fix(browser): focus newly opened image tabs (#34127)
* fix(browser): focus newly opened image tabs

Focus the window before the webview so Command+W closes the new
image tab instead of the original tab after a plain image click.

Add tests for focus order, image loading, and close-shortcut forwarding.

Fixes #34114

* test(browser): verify image tab focus with native keyboard input

* refactor(ci): keep browser E2E routes within registry size limit

* fix(ci): enable background launch for native browser regression

* test(ci): include browser routes in isolated detector fixture

---------

Co-authored-by: Neil <neil@stably.ai>
2026-10-26 22:52:40 -07:00
Neilandlorenzozanee bca89125ce fix(updater): apply the app proxy to electron-updater's session (#34276)
electron-updater sends checks and downloads through its own
"electron-updater" partition, so a proxy configured only in Orca settings
never reached update requests. Apply the same proxy policy (and request
guard) to that partition at updater setup and on settings changes, and
answer its proxy login challenges with the configured credentials.

Co-authored-by: lorenzozanee <195543813+lorenzozanee@users.noreply.github.com>
2026-10-26 22:52:25 -07:00
Kelvin Amoabaandzhangxaochen 18da0e998f fix(mobile): offer Retry on a stuck terminal while other tab recovery polls (#34277)
The pending-terminal budget was skipped whenever another session-tabs
recovery need was active, so it never ran out and the terminal never
reached "Terminal is taking longer than expected" with Retry.

Refs #32231

Co-authored-by: zhangxaochen <zhangxaochen@163.com>
2026-10-27 05:51:20 +00:00
EvgeniiandNeil 8d72873b78 fix(i18n): resolve plugin-pack plurals with the pack's declared locale (#12505)
Plugin language packs register under synthetic plugin<hex> resource
languages, so i18next's plural resolver fell back to English rules and
Russian/Polish/etc. packs never selected their _few/_many forms. Map each
pack's resource language to its declared (Intl-supported) locale inside
the plural resolver, and fill missing plural categories from the key's
_other form so packs that only ship _one/_other stay in-language.

Co-authored-by: Neil <neil@stably.ai>
2026-10-26 22:42:57 -07:00
Ulises MillánandNeil 7815c07874 fix(session-history): close other row action menus when opening one (#31801)
Opening the "..." menu on one Session History row left another row's
menu open, because the row wrapper's pointerdown stopPropagation hides
the click from Radix's outside-dismiss. Each row now controls its menu
state and broadcasts the shared close-all-context-menus event when it
opens, so any other open row menu closes.

Fixes #31563

Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com>
2026-10-26 22:42:39 -07:00
Neil 6ae3fbc89b fix(browser): open target=_blank file links from a local page in an Orca tab (#34057) 2026-10-26 22:42:19 -07:00
hiro 1fdf89685e fix(i18n): use the product name "Finder" in Japanese reveal/open labels (#30081)
macOS Japanese UI shows Finder by its product name, not the katakana
transliteration. Update openInFinder and revealInFinder accordingly.
2026-10-26 22:31:19 -07:00
Neilandoutof-place d5070dedb8 fix(app-icon): restore the sharp bundle icon on the Dock for packaged Classic macOS builds (#34094)
Packaged Classic builds left the live Dock tile on the 256px icon.png set by
applyAppIcon. Once the queued AppKit custom-icon clear succeeds and no newer
icon request is pending, persistMacDockIcon now calls
app.dock.setIcon(nativeImage.createEmpty()); Electron passes that to AppKit as
nil, so the Dock draws the full-resolution bundle icns. A failed or timed-out
clear keeps the PNG, as before.

Fixes #27138

Co-authored-by: outof-place <contact@outofplace.space>
2026-10-26 22:30:59 -07:00
Kelvin Amoaba f719d0fb10 fix(mobile): open terminal urls and file paths with desktop's link detection (#33964)
* fix(mobile): open wrapped terminal urls and paths with desktop's link detection

Desktop's terminal URL and file-link detectors move to src/shared and the phone's
WebView document calls them, replacing its single-row copies. File taps carry every
reading of the tapped text so the phone opens the longest one the host finds, as
desktop does.

* fix(mobile): keep the unc host of osc 8 file links for the host to resolve

* fix(mobile): resolve terminal file-tap readings a few at a time

A tap inside a run of path rows yields hundreds of hard-wrap guesses; firing them all at once overflowed the page bridge's pending-request cap and the real path was never checked.

* refactor(terminal): share the osc 8 link classifier and trim file-tap plumbing

Desktop and the phone now read OSC 8 targets through one shared classifier. Terminal file taps carry only their candidate list, deduped by path, and desktop checks OSC overlap only for candidates it can resolve.

* refactor(terminal): keep shared link files under the line cap

The xterm buffer subset gets its own module, and the text-only OSC resolver goes now that the router uses findExactTerminalFileLink.
2026-10-27 05:30:05 +00:00
Kelvin Amoaba 9d2e441947 fix(mobile): compare branches and show diffs with desktop's base-ref and whitespace settings (#34038)
* fix(mobile): compare branches and show diffs with desktop's base-ref and whitespace settings

Base-ref resolution moves to src/shared and the host publishes the compare-against-upstream
and show-whitespace settings, so the phone's branch compare and diffs match desktop.

* fix(mobile): use the upstream compare policy on the review screen and rebuild diffs when whitespace changes

* fix(mobile): reread Source Control settings on Refresh and restart diffs loading under the old whitespace setting

* test(mobile): cover diffs dropped when desktop's whitespace setting arrives

* refactor(mobile): share one Source Control settings read per host across screens
2026-10-27 05:29:46 +00:00
Neil 6d43596fda fix(wsl): keep a user's GLIBC_TUNABLES and delegate the launch-env wrapper (#34248)
* fix(wsl): keep a user's GLIBC_TUNABLES and delegate the launch-env wrapper

The orcad launch now sets GLIBC_TUNABLES only when the launching shell has
none, so a value forwarded through WSLENV wins and the claim leaves it in
place. withOwnBuildLaunchEnv delegates to the transport instead of copying
its own properties, so a class-based transport keeps its methods.

* test(wsl): read the delegated transport through its type, not Reflect

withOwnBuildLaunchEnv now returns the transport's own type, so the test
calls the class method directly. The comment no longer claims #private
class fields survive delegation.
2026-10-26 22:26:11 -07:00
Max HsuandNeil c915be1a22 fix(test): carry Error objects across the node-runtime vitest pool IPC (#30079)
devalue rejects Error objects, so when a NODE_RUNTIME_INCLUDE test file
failed to load, the pool's send() threw DevalueError and the run ended
without a summary. Give both ends of the IPC channel one codec with a
matching Error reducer/reviver (name, message, stack, cause) so the load
failure reaches the reporter as a normal FAIL.

Fixes #29854

Co-authored-by: Neil <neil@stably.ai>
2026-10-26 22:25:16 -07:00
a7c9d19048 fix(file-explorer): offer permanent delete when moving to Trash fails (#33956)
Offer confirmed permanent deletion when moving an item to Trash fails.
Preserve authorization and workspace ownership checks, cancellation behavior,
text-snapshot undo, remote compatibility, and all supported translations.

Fixes #33944

Co-authored-by: nori <dosukoicrypto@gmail.com>
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-26 22:25:01 -07:00
Neil 362104ca18 fix(wsl): background Git and the roots catalog never start a stopped WSL distro (E9) (#34231)
* fix(wsl): background Git and the roots catalog never start a stopped WSL distro

git status ran on the UNC project root 0.45 s after a terminate, next to the
explorer read; either boots the distro. Background Git (status, conflict
operation, upstream status, branch compare, the upstream-ref watch) now asks the
shared running gate first and refuses for a stopped distro, including host
paths whose Git runs through wsl.exe. The authorized-roots rebuild skips a
stopped distro's repo and leaves it dirty, and the detected-worktree scan fails
as unavailable, so rows are kept and the next scan after the distro runs lists it.

* fix(wsl): the active workspace's first status and a wake read's roots rebuild may start WSL

- Drive-path projects whose Git runs through WSL had no wake path: the active
  workspace's first git:status after it becomes active now passes
  wakeWslDistro, so Source Control starts the distro; later polls stay gated.
- A user act runs in an async scope naming its distro; gated work inside it
  (the authorized-roots rebuild an authorization miss triggers, the detected
  scan, the Git) may start that distro and no other. External worktrees on a
  stopped distro no longer fail a wake read with access denied.
- After a user act wakes a distro, background reads stop trusting the older
  'stopped' read and probe again.

* fix(wsl): explicit WSL launches refresh the running read; wake only on tab change; gate the home probe

- Any wsl.exe Git/CLI run (commit, push, fetch) or WSL terminal spawn for a
  distro last read as stopped records that it started, so background reads probe
  again instead of refusing for up to 60 s.
- The active editor tab wakes only when the active tab changes; effect re-runs
  driven by git status or overview views read without waking.
- The authorization roots' WSL home probe no longer runs wsl.exe in a stopped
  distro when the home is uncached.
- The settle window no longer imports the orcad liveness module (it pulled main
  code into the web typecheck); a test pins it to EXIT_SETTLE_MS.

* fix(wsl): deferred work and running-list listeners never inherit a user act

A user act's async scope could leak into work it triggers indirectly: a drain of
deferred tasks it caused, or listeners of a running-list probe started inside
it. Both now run outside the scope, so only the act's own work may start its
distro.

* fix(wsl): keep shared modules free of main-only gate imports

worktree-logic.ts and wsl-running-distro-cache.ts are also compiled by the web
project, which cannot see main-only modules (AsyncLocalStorage, wsl.exe).
getAllowedRoots now injects the gated home lookup into computeWorkspaceRootWithin,
and the background gate's own cache subscriptions run outside the user-act scope
instead of the cache knowing about it.
2026-10-26 22:23:07 -07:00
OrcaWinandOrcaWin a8f7afe84b test: remove 128 low-value cases and 22 suites (#34206)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-26 22:21:44 -07:00
Kelvin Amoaba 577af08b12 fix(browser): scroll off-screen elements into view before agent clicks (#34262)
Bump agent-browser to 0.27.3. Its 0.27.2 release scrolls the target node into
view (nested scroll containers included) before computing the click point and
errors when another element covers that point, instead of reporting a click
that never reached the page.
2026-10-27 05:21:38 +00:00
Brennan Benson 2e181b1b78 Reuse chat history snapshots across readers (#34215)
* Reuse rendered chat history across readers

* test: cover current journal reads across source changes

* test: align journal assertions with current snapshot reuse
2026-10-26 22:19:15 -07:00
9dd44715ba fix(mobile): keep a renamed tab's name on mobile after the host restarts (#33743)
* fix(mobile): keep a renamed tab's name on mobile after the host restarts

After a restart, the reconnecting client restarts each saved tab's
terminal (restored-pane-materialize -> createRuntimeOwnedMobileSessionTerminal),
and the mobile row built from the new terminal carried no customTitle, so
the phone showed the terminal's own title although the saved session still
held the name. publishPtyBackedMobileSessionTerminal kept a name only from
an earlier mobile row, which a restart does not have.

Both builders now resolve the name through one helper: a value already on
the mobile row wins, including a cleared null; only a row with no value
falls back to the tab's saved name.

Fixes #33737

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

* refactor(mobile): resolve a restarted tab's saved name through getPtyManualTitle

getPtyManualTitle already owns a terminal's manual name (the saved tab's,
else the live rename), so the row builders use it instead of a second
saved-session lookup. A cleared name reads as cleared from the saved
session, so the test now covers that instead of a row-only clear.

* fix(mobile): keep a row's cleared name instead of falling back to the saved one

A null customTitle on a row is a clear: paired desktops need it to drop a
cached name, and a desktop clear lands on the row before the debounced
session write. Only a row with no value falls back to getPtyManualTitle.

* test(mobile): pin that a row's cleared name survives a terminal restart

---------

Co-authored-by: clayphi <193966884+clayphi@users.noreply.github.com>
Co-authored-by: Claude Code <noreply@anthropic.com>
Co-authored-by: Kelvin Amoaba <97001695+AmoabaKelvin@users.noreply.github.com>
2026-10-27 05:18:58 +00:00
NeilandLance Woodson 4514634faa fix(scripts): resolve pnpm when npx or npm run exports npm's own CLI (#34271)
`npx` and `npm run` set npm_execpath to npm's own npm-cli.js/npx-cli.js,
so resolvePnpmCliInvocation ran npm with pnpm's arguments. Skip npm's CLI
by file name and fall back to PNPM_HOME / pnpm on PATH. Route
build-workspace-packages and terminal layout parity through the shared
resolver instead of their own npm_execpath parsing.

Fixes #29438

Co-authored-by: Lance Woodson <65194841+woodsonl@users.noreply.github.com>
2026-10-26 22:18:56 -07:00
Neil bff2843fca refactor(shared): organize native chat ask input owners (#34251)
* refactor(shared): group native chat ask input owners

* refactor(shared): keep split ask type imports erased
2026-10-26 22:18:52 -07:00
Kelvin AmoabaandChris Stephens 619ee954c9 fix(browser): paste the local clipboard into streamed browser pages (#34269)
The streamed page's keydown handler forwarded Ctrl/Cmd+V to the host as a
keypress and cancelled the browser's paste event, so the host pasted its
own (usually empty) clipboard. Native paste chords now fall through, and
the frame's paste event inserts the clipboard text with
browser.keyboardInsertText on the pane's input queue, split into chunks
that fit the runtime socket frame.

Co-authored-by: Chris Stephens <nyldn@users.noreply.github.com>
2026-10-27 05:16:01 +00:00
Kelvin Amoaba e79388e3ab fix(agents): keep OMP session titles when a turn finishes (#34266)
Orca wrote a synthetic "OMP ready" / "OMP - action required" title over
the session title that OMP and Orca's titlebar extension already paint.
OMP's hooks are authoritative and its own rest title reads as idle, so
stop synthesizing terminal titles for OMP, as for OpenCode.

Linear: STA-11986
2026-10-27 05:15:58 +00:00
Kelvin AmoabaandFelipe 19c53e5248 fix(browser): let Grab page element pick and track elements inside open shadow roots (#34265)
* fix(browser): let Grab page element pick and track elements inside open shadow roots

Document hit-testing and marker lookups stop at a shadow host, so Grab only
ever picked the host. The overlay now descends through open shadow roots,
and both the overlay and the annotation viewport bridge find the marked
element and listen for scrolls inside them. Closed roots stay opaque.

Co-authored-by: Felipe <5784455+fbetancourtc@users.noreply.github.com>

* fix(browser): track slotted ancestors and stop re-walking shadow roots for a lost target

* fix(browser): walk shadow roots once per selection and count fixed shadow hosts

* fix(browser): restore grab pointer events if a page's shadowRoot throws; type the shadow fixtures

* fix(browser): keep composed-tree walks safe from page-named form controls

---------

Co-authored-by: Felipe <5784455+fbetancourtc@users.noreply.github.com>
2026-10-27 05:15:54 +00:00
Neil 51c393bc2e fix(wsl): close a WSL host's loopback listener once it idles out or its distro stops (#34046)
* fix(wsl): close a WSL host's loopback listener once its orcad idled out or its distro stopped

The supervisor already stops watching an idle or stopped host and never relaunches it for
background work, but the bridge's loopback listener stayed open, and any dial to it (a status
probe, a stale client) spawned wsl.exe and booted the distro again. Retire the listener in both
branches without publishing 'closed', so the host keeps reading as idle or stopped; the next
user connect binds a new one.

* fix(wsl): a retired listener never proves orcad live; never retire a connect in flight

Review of the listener retirement: with no connection, the port probe answered 'ready', so a
wake verify with no orcad pid to compare read the host as live, published ready and re-held
the distro. It now reads as refused. retireListener also leaves alone a key whose user connect
is in flight, so a trigger mid-connect cannot retire the entry that connect produces.

* fix(wsl): retire the listener on E9's single park path too

E9 A parks every confirmed stop, visible work or not; retire the loopback listener there,
before the deferred re-check, so a dial cannot boot the parked distro.

* fix(wsl): read the park generation before retiring the listener
2026-10-26 22:15:00 -07:00
Jinwoo Hong c23ab5546c Antigravity: show a login with no quota as unavailable, not "Refresh failed" (#34163) 2026-10-26 22:07:52 -07:00
Jinwoo Hong 3b1ecd6de4 Antigravity: show usage for a login Orca can't identify instead of "account changed" (#34159) 2026-10-26 22:07:34 -07:00
Jinwoo Hong ad4b9af825 Stop opening a Google sign-in page every hour when agy is signed out (#34165) 2026-10-26 22:05:27 -07:00
Brennan Benson 192f5783ab fix(runtime): keep terminal.send under the file-length limit with one refusal helper (#34256)
#33968 pushed terminal-send-method.ts to 301 counted lines against the 300-line rule, failing Lint on main and every PR that merges it. Eight refusal branches spelled out the same zero-byte result; one helper builds it.
2026-10-26 22:01:45 -07:00
Kelvin Amoabaandpullfrog[bot] 3c8e40a4c9 fix(browser): make orca set media --reduced-motion apply and reject unknown values (#34253)
* fix(browser): make orca set media --reduced-motion actually apply

agent-browser's set media only looks for the bare tokens dark, light and
reduced-motion and ignores anything else, so the documented reduce value
was dropped and the command still reported success. Map Orca's values
onto those tokens in one builder used by the desktop bridge and the
orcad external Chromium path, and reject unknown values.

Co-authored-by: pullfrog[bot] <226033991+pullfrog[bot]@users.noreply.github.com>

* fix(browser): reject bad set media values before queuing and list both flags in help

---------

Co-authored-by: pullfrog[bot] <226033991+pullfrog[bot]@users.noreply.github.com>
2026-10-27 04:40:53 +00:00
Jinjing 887b781d72 Move palette matching utilities into shared modules (#34252) 2026-10-26 21:29:57 -07:00
NeilandClaude e2b8332804 fix(terminal): closing a kept host-loss tab after a relaunch ends its history (#34205)
* fix(terminal): closing a kept host-loss tab after a relaunch ends its history

A WSL bridge pane lost with its distro keeps its tab and unended history. The
adapter only remembers the loss in memory, so after a relaunch closing that
tab before waking it hit SessionNotFound and left its history directory
behind. The router now ends that history when the id's history is unended and
every daemon, current and legacy, answers that it does not list the id. A
listing or an unanswered daemon keeps the history.

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

* fix(terminal): end a lost session's history only when every daemon can answer for it

Review of the close-after-relaunch path: the router-only check never ran
when the app has no legacy daemons (the provider is then the bare adapter),
and the router's adapters are not every daemon sharing the history dir. An
older daemon whose socket probe failed at startup gets no adapter, and a
daemon held for a newer protocol has none either; both may still run the id.

The check now lives in the adapter's close. It ends the history only when it
is unended, no daemon is held for a newer protocol, no older protocol's pid
file names a process that may be alive without an adapter to ask, and every
known daemon answers listSessions without the id. A router shares its
adapters as the daemons to ask.

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

* fix(terminal): decide a lost session's close in one lock, and never connect a daemon to list it

Review: the unlisted-session check already runs inside shutdownWithHistoryLock,
so a spawn queued for the same id waits until the close has decided; a test
now holds the listing open and proves the spawn cannot slip in. listsSession
no longer connects (or respawns) a daemon just to list it: an unconnected
daemon cannot answer, which keeps the history.

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

* fix(terminal): count an older daemon Orca may not signal as alive; cover slept-tab closes

process.kill(pid, 0) failing with EPERM means the process exists under another
user, so legacyDaemonProcessMayBeAlive now treats it as alive; only a missing
pid file or ESRCH counts as gone. Tests pin that, and pin the wider scope of
the unlisted close: closing a slept tab without waking it ends its unended
history, and keeps it while another daemon lists the session.

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

* refactor(terminal): move the lost-session listing and check out of session control

daemon-pty-session-control.ts went over max-lines. The daemon listing read and
the unended-history check now live in daemon-unlisted-session.ts beside
mayAnyDaemonRunSession; the adapter keeps only thin calls. No behaviour change.

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-26 21:28:36 -07:00
Kelvin Amoaba 75bcd328cf fix(mobile): answer multi-question asks like desktop and clear Claude's wait on phone answers (#33968)
* fix(runtime): clear Claude's question wait when a phone keystroke answers it

Claude sends no hook after AskUserQuestion is answered; desktop infers it, phone answers left the pane waiting.

* fix(mobile): answer multi-question cards like desktop, with Skip and back-stepping

Mobile required every answer and locked grouped structured questions once tapped; the card rules and structured mapping now live in shared code.

* fix(mobile): announce ask card options as checkboxes or radios

* fix(mobile): answer a grouped question only on the prompt it was picked on

* test(runtime): drop the multi-question case the shared answer rule already covers

* refactor(native-chat): share the typed-answer rules and fold the host answer check into terminal.send
2026-10-27 04:27:06 +00:00