Commit Graph
21378 Commits
Author SHA1 Message Date
Jinjing 006bef5155 Improve experimental worktree cards with compact agent summaries
- Add an optional details row for workspace metadata and indicators
- Roll up descendant activity timestamps to parent cards
2026-11-13 18:25:06 -08:00
Jinjing 6dcb54f71d wip 2026-11-13 18:25:06 -08:00
Jinjing 976921f7a0 wip 2026-11-13 18:25:06 -08:00
Jinjing ec1e404944 wip 2026-11-13 18:25:06 -08:00
Jinjing bccbc15484 wip 2026-11-13 18:25:05 -08:00
Pr1pandNeil e784f9803d fix(i18n): retry a failed language catalog when the saved language is picked again (#41538)
When the saved UI language's catalog fails to load, Orca falls back to
English. Re-picking the same language in Settings > Appearance > Language
was a no-op because the select dropped same-value picks and an unchanged
uiLanguage never re-ran the I18nProvider load.

The language select now sets allowReselect. A different language still
calls updateSettings; re-picking the saved one calls retryLanguageLoad()
only when useLanguageReadiness reports a load error. The language row moves
into AppearanceLanguageSetting to keep AppearanceInterfaceSection under the
max-lines cap.

Refs #41513

Co-authored-by: Neil <neil@stably.ai>
2026-11-13 18:20:31 -08:00
OrcaWinandOrcaWin 233469f883 test: remove low-value onboarding and plugin validation cases (#42243)
* test: remove signal bookkeeping and repeated option cases

* test: remove low-value onboarding and plugin validation cases

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-13 18:15:04 -08:00
Kelvin Amoaba f49eb51f95 feat(computer): launch-app starts desktop apps without taking the foreground (#42197)
* feat(computer): add launch-app to start apps without taking the foreground

* fix(computer): leave running apps alone and keep the launch env clean

* fix(computer): recheck aliases, keep focused launches visible, refine launch hints

* chore(computer): document the launch result casts

* test(computer): check launch-app reports where the app ended up on Windows CI

* docs(computer): point app_not_found at launch-app

* test(computer): format the merged Windows background e2e

* fix(computer): match launch paths to the running file and word background launch as an attempt
2026-11-14 02:11:33 +00:00
Pr1pandNeil ea7c94faef fix(terminal): aim app-menu paste at the pane owning focus (#41585)
Edit > Paste dispatches without a renderer keydown, so it skipped the
keydown active-pane repair and targeted manager.getActivePane(). When
focus reached another pane's xterm without a pointerdown (for example a
file drop from the explorer onto an inactive split), the paste was
cancelled with "Paste cancelled: terminal focus changed before paste
started." Resolve the pane from the dispatch-time focus with the same
synchronizeTerminalKeyboardPane helper keydown uses.

Refs #41352

Co-authored-by: Neil <neil@stably.ai>
2026-11-13 18:05:11 -08:00
Pranav Tomar faa759d606 fix(worktrees): stream the submodule probe so large repos can be deleted (#42174)
The delete preflight listed the whole index with a buffered
`git ls-files --stage -z`, which overflows the 10 MiB Git output cap in
large repositories and blocks workspace deletion. Stream the listing
through gitStreamStdout and keep only gitlink (mode 160000) paths, so
memory scales with the number of submodules instead of the index size.

Fixes #42134
2026-11-13 18:05:01 -08:00
Bubu-Dudu-52hzandNeil 996510fff0 fix(native-chat): preview pasted images whose link target has no extension (#41984)
Telegram Desktop on macOS puts a .jpg symlink on the clipboard that points
at an extensionless JPEG. Chat-image access classified the real target by
extension only, so the composer chip and sent message showed an empty
placeholder.

For an extensionless target, chat-image access now stats it (regular files
only, so devices and FIFOs are never opened) and accepts it only when its
header carries a PNG/JPEG/GIF/WebP signature. Desktop fs:readFile and the
runtime readChatImagePreview take the MIME type from that signature. Targets
with a non-image extension are still refused. The header sniff is shared
with runtime upload staging.

Fixes #41977

Co-authored-by: Neil <neil@stably.ai>
2026-11-13 17:59:50 -08:00
OrcaWinandOrcaWin 2fc7b1a750 test: remove catalogue and animation suites and repeated input cases (#42238)
* test: remove catalogue and animation bookkeeping cases

* test: trim repeated extension inputs and pairing copy checks

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-13 17:58:09 -08:00
Vitalii KulishandNeil 762f7bf6a7 fix(source-control): open another workspace from the branch picker like the sidebar (#41930)
Open workspace in the branch picker, Git Graph's open-workspace action and
the folder workspace Source Control header called the raw setActiveWorktree.
A workspace whose tabs were closed on purpose then had no surface and the
window stayed blank. Use activateAndRevealWorktree with the user-open intent,
the same activation the sidebar uses, while keeping the sidebar filters.

Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com>
2026-11-13 17:54:25 -08:00
085859850b fix(rate-limits): show a Codex individual spend limit as the monthly usage window (#41791)
Codex workspace seats can report only an individual spend cap with no
5h/7d window, which left the Codex usage meter blank. Map the cap to the
existing monthly window when no 5h/7d window is reported, from both the
app-server `individualLimit` and the backend `spend_control.individual_limit`,
fetch the backend when an ok RPC result has no usage window, and keep
monthly-only Codex snapshots for the account switcher preview.

Fixes #8664

Co-authored-by: Neil <neil@stably.ai>
Co-authored-by: Swaroop <27270424+swaroop477@users.noreply.github.com>
2026-11-13 17:54:12 -08:00
registered2ndandNeil 3436c2c3f5 fix(terminal): sync parked watchers with the current park verdict, not the first render's (#42021)
useParkedTerminalWatcherSynchronization routed its sync through
useEffectEvent. React 19.2.x only refreshes effect-event closures for
plain function components, and the hook's caller
(TerminalPaneOverlayLayer) is memoized, so every sync used the first
render's parkedTabIds/terminalTabs. Tabs deferred at startup kept their
parked watcher (and hidden-delivery claim) after being revealed, and
tabs parked later never got a watcher.

Use the existing useLatestHandler instead, which refreshes its ref in a
layout effect before the passive sync runs.

Fixes #42020
Fixes #42023

Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com>
2026-11-13 17:48:50 -08:00
OrcaWinandOrcaWin e2e69135f9 test: remove low-value runtime and bridge cases (#42234)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-13 17:45:56 -08:00
gaokui2010 8de46df462 fix(i18n): translate Add project menu and collapse-all tour tip into Simplified Chinese (#42106)
Add the missing zh.json entries for the Add project menu
(auto.components.sidebar.AddProjectMenu.*), the contextual-tour "New"
badge, and the collapse-all-projects tour step. Keys follow en.json
ordering and preserve the {{host}}, {{modifier}} and
{sidebar.projects.toggleCollapse} placeholders.
2026-11-13 17:43:11 -08:00
BingZandNeil 8677fa099f fix(browser): wipe a deleted profile's storage when extension teardown fails (#41928)
Deleting a browser profile with extensions forgot the extension API host
twice, and Electron's protocol.unhandle throws once the scheme is gone.
That throw skipped the partition storage wipe and the persisted extension
store cleanup.

- Only unhandle orca-extension-api while it is still registered.
- Forget the extension state, sync storage, and DNR stores in finally.
- Log a detach failure on profile delete and still wipe the partition.

Fixes #41907

Co-authored-by: Neil <neil@stably.ai>
2026-11-13 17:42:58 -08:00
Kelvin Amoaba f264e1324f fix(browser): keep the user's agent-browser env and config away from Orca's desktop browser helper (#42231)
* fix(browser): keep the user's agent-browser env and config away from desktop helpers

* fix(browser): drop an inherited agent-browser namespace from desktop helpers

* fix(browser): write the desktop helper's empty config off the main thread

* fix(browser): wait for the Orca agent-browser config before the startup sweep
2026-11-14 01:39:16 +00:00
Jinwoo Hong 0d7a48df9b feat(daemon): capture macOS's verdict when a terminal host is refused a folder (#42153)
* feat(daemon): capture macOS's verdict when a terminal host is refused a folder

On a confirmed app/host divergence in Documents, Desktop or Downloads, read
macOS's own record once per host incarnation and folder class: tccd decisions
and kernel sandbox denies for the host pid, host signature checks, host age
and origin, earlier good reads, time since wake signals, Full Disk Access,
fork-fallback reason, and the class root's dataless, iCloud and volume state
(read before the app-side opendir). Telemetry is enum-only in a new
daemon_pty_cwd_denial_capture event; raw filtered lines go to a capped local
file under userData logs. Every subprocess is bounded and failures are
swallowed off the spawn path.

* fix(daemon): keep the wake clock Electron-free and avoid casts in the log parser

* fix(daemon): tighten denial capture attribution and bounds

Snapshot good-read and wake context at the denial, bound the class-root
realpath, keep earlier captures when one entry is over the cap, require the
app or host in requirement failures, let an explicit pid outrank a shared copy
path, and report a capped log read as truncated.

* fix(daemon): collect Info requirement checks and claim captures before probing

Ask log show for Info records in a 30 s window ending at the denial, claim a
helper/class capture before the folder probes and release it when the app is
refused too, and report a requirement failure tied only to the shared app
identifier as uncorrelated instead of blaming this helper.

* fix(daemon): keep folder-denial capture in telemetry labels only

Drop the local diagnostics file and stop retaining raw log lines: the parser
reads them in memory to derive enums and keeps nothing.

* fix(daemon): skip the folder-denial capture when telemetry is off

Gate the folder probes and the log/codesign capture on the telemetry client's
consent check so opted-out users never have their log read or checks run.

* fix(daemon): recheck telemetry consent at every capture stage

Run every capture subprocess through a consent-checked runner (now a required
probe argument), ask again before and after the identity probe and after the
remaining probes, and free the claim when an opt-out stops a capture so a
later opt-in can still capture.

* fix(daemon): recheck consent after the access reader's lazy import

The Full Disk Access reader started after its import resolved without asking
again, and its catch swallowed the opt-out; ask after the import and let the
opt-out end the capture so its claim is freed.

* fix(daemon): report a helper's denial over a later allowed result

Overlapping tccd requests can resolve out of order; when any result for the
denied folder class is a denial, report it.
2026-11-13 20:37:46 -05:00
c2b4e4281f fix(tasks): show cached GitHub rows on filter change and keep issue-number order (#42128)
* fix(tasks): show cached GitHub rows instead of the skeleton on filter change

Filter handlers set tasksFiltering and only the forced fetch settlement
cleared it, so rows the landing run had already painted from the
per-query cache stayed hidden behind the skeleton. The landing run now
clears the flag when every selected repo (or the restored page) is
cached for the applied query; the forced refetch still runs under the
toolbar spinner and replaces the rows in place.

Rebuilds #41998 by @piotrpawlik (fixes #41997).

Co-authored-by: Piotr Pawlik <piotr.pawlik@apollo.io>

* fix(tasks): keep GitHub Tasks pages in issue-number order

materializeTaskPageItemList re-sorted every page by updatedAt while the
host search, the cross-repo aggregate, the landing pre-paint and mobile
all order by issue number. A triage edit moved old issues to the top,
and the landing probe saw a different key order and reset pagination.
Use the shared sortWorkItemsByNumber so retained pending rows keep
their number slot too.

Rebuilds #41999 by @bbingz (fixes #41987).

Co-authored-by: Bing.Z <zzb@gxsmjx.com>

* test(tasks): make landing tests revert-sensitive; scope refetch comment

Address C1 review: every landing case now fails without the cached-rows
fix, names say what they verify, and the comment no longer claims typed
search forces the refetch.

* test(tasks): replace landing test casts with annotations

* fix(tasks): hold GitHub pagination while a forced refresh is in flight

Cached rows now show during a filter switch's forced refetch, which made the
pager live; opening page 2 then got undone when the refetch replaced every
page. Disable the pager until it lands, as the phone does while revalidating.
Also drops two landing tests that covered no new behavior.

* fix(tasks): hold GitHub pagination for any in-flight landing fetch

A typed search over stale cached rows lands without a forced fetch, so the
pager was still live and its page could be undone when the landing fetch
replaced the pages. Track the landing fetch itself, as the phone holds paging
while any list load revalidates. Shares the retry-key release between the
fetch's settle paths to keep the run under the file-length limit.

---------

Co-authored-by: Piotr Pawlik <piotr.pawlik@apollo.io>
Co-authored-by: Bing.Z <zzb@gxsmjx.com>
Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com>
2026-11-13 17:31:49 -08:00
Kelvin Amoaba 4ccda83aff fix(browser): keep tabs and windows that extensions open for an agent out of the user's view (#42218)
* fix(browser): keep extension tabs and windows an agent sets off from taking the user's view

* fix(browser): follow the agent-lead rename for extension callers

* fix(browser): let the newest input or extension gesture decide who set an extension call off
2026-11-14 01:29:40 +00:00
Kelvin Amoaba e2fb873c0a fix(computer): type into Windows text boxes without bringing the window forward (#42165)
* fix(computer): type into Windows text fields without raising the window

Adds type-text --element-index on Windows through EM_REPLACESEL for user32,
RichEdit and WinForms edits (owner-checked, read back with WM_GETTEXT), or a
ValuePattern write merged with the TextPattern selection. Keyboard verbs on a
background window now refuse with background_unavailable before sending
anything and point at type-text --element-index. Foreground typing uses one
SendInput KEYEVENTF_UNICODE batch instead of WM_CHAR posted to the top-level
window, and get-app-state shows multiline edit text again.

* fix(computer): refuse typing into Windows list items, keep the caret on a confirmed prefix
2026-11-14 01:28:30 +00:00
OrcaWinandOrcaWin f15962da9c test: remove low-value CLI, terminal, and projection cases (#42228)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-13 17:26:54 -08:00
Kelvin Amoaba 8ecb4f80e3 fix(browser): refuse --environment browser commands that name no page or worktree (#42221) 2026-11-14 01:21:17 +00:00
Brennan BensonandAnubhav Banerjee a62fbb4229 Give OpenCode the component fixtures MCP server (#42208)
* Give OpenCode the component fixtures MCP server

The repository registered orca-component-fixtures only in .mcp.json, so
Claude Code got the fixture tools and OpenCode did not. opencode.json
already mirrors the repo's TypeScript language server for OpenCode; it
now registers the same fixtures server, in the per-server form the rest
of the file uses, which OpenCode 1.x reads and OpenCode 2 migrates.

Tracked in #41836 (STA-15139).

Co-authored-by: Anubhav Banerjee <76914348+Anubhav-2003@users.noreply.github.com>

* Find the fixtures server from any OpenCode start folder

OpenCode reads opencode.json from the nearest ancestor but starts MCP
servers in the folder it was launched from, so a relative script path
failed outside the repository root. Walk up to the script and import it.

---------

Co-authored-by: Anubhav Banerjee <76914348+Anubhav-2003@users.noreply.github.com>
2026-11-13 17:19:10 -08:00
Kelvin Amoaba ee49c567dc fix(browser): keep print and Windows Hello dialogs an agent sets off from taking the screen (#42209)
window.print() opens the system print dialog and, on Windows, a passkey request
opens Windows Hello. Both are modal windows that take the foreground, and an
agent click could set either off over the user's work. Main now tells each
page's frames whether an agent drove it since the desktop user last gave it
input, and the session frame preload refuses print() on such a page (reported
to the agent as effects.blockedPrint, pointing at pdf) and, on Windows, holds
its passkey requests unsent, still reported as passkeyRequest. The user's own
input releases the page and cancels held requests so the page can retry.
2026-11-14 01:15:23 +00:00
Jinjing b8b29df2b9 feat(automations): unify Automations pages (option D) (#41620)
* feat(automations): record subpages in app navigation history

* feat(automations): unify page layout and redesign list, detail, and runs

* chore(i18n): remove obsolete automation page strings

* fix(automations): keep focus effects compatible with React compiler

* fix(automations): resolve run workspaces from historical ownership

* fix(automations): preserve replay and guard in-flight dispatches

* fix(automations): give the All runs link a singular default

* fix(automations): let Escape step back to the parent history entry

Escape returns to the parent page. When that page is the previous history
entry, move the index back instead of appending a duplicate, so Forward
still reaches the page that was left.

* chore(i18n): sync the All runs runtime catalog entry

* fix(automations): keep Back/Forward replays from re-recording the page left

- Record a sub-page only when the page itself changes. Clearing a replay
  request could render once with the old page state and record the page
  Back just left, cutting Forward history. Adds a hook-level test.
- Escape on the list closes the page without arming the step-back mode,
  and closing resets it.
- Run now's busy state only clears from the open automation's runs, and a
  dispatch that never answers releases the button after 60s.

* fix(automations): truncate a long automation name on the run-not-found button

* test(automations): type the history hook test's props

* fix(automations): address C1 review and UX-I1 findings

C1 (code review):
- C1-01: a Back/Forward replay that settles on another page (its run
  history could not be read) replaces its history entry instead of
  appending, so Forward history survives.
- C1-02: Run now's busy state is request-specific; a late failure or
  acknowledgement for an earlier click no longer clears a later one.
- C1-03: the page title takes focus when the user opens Automations
  (sidebar, deep link, Back/Forward); a page restored at launch or on
  reload leaves focus alone.
- C1-04: returning to an off-screen run scrolls the virtualized table to
  that row before focusing it.
- C1-05: a deleted-run deep link records the run it asked for, so
  Back/Forward return to the same not-found page.

UX-I1:
- One "Open workspace" label on the run page.
- Run status is a dot and label everywhere; the run header uses a soft
  tinted pill.
- Every failed run gets one plain-language banner. Blocked-agent reasons
  are translated (trust prompt: "<Agent> is waiting for you to trust this
  folder", with Open workspace), never shown as internal codes.
- A run that started off its slot shows "Scheduled … · Started …"; the
  detail's Last run says "Started …" in that case.
- The three stats stay in one row down to a 480px container.
- "—" instead of "n/a" for spend and tokens.
- An automation's Runs page drops the "Run history" header and shows the
  run count under the title.
- The not-found button reads "Open automation".

* fix(automations): address CodeRabbit review

- Run now tracks one request per automation, so starting another
  automation's run never frees this one's busy state.
- Back/Forward to the list or Runs keeps the list search.
- While Back/Forward resolves an automation, show the loading skeleton
  instead of leaving the page being left interactive.
- A new run request clears an earlier run-not-found result.
- A stale external job key no longer opens a different job.
- Spend reads "Unavailable" when run history could not be read.
- The external row's accessible name includes its host when the Host
  column is shown.

* fix(automations): address internal review round 2

- A Back/Forward replay that falls back to the page just before its entry
  steps back to it instead of leaving a duplicate Back step.
- The detail's Last run says "Started …" only for a run that started.
- A failed run with no recorded reason still gets a banner.
- Back/Forward to the bare Automations entry focuses the page title.
- Remove the unused status-badge variant helper.

* fix(automations): address UX-I2 findings

- UXI2-1: the detail's Last run stat shows the run's scheduled time, the
  same time its rows show; only the run page labels Scheduled/Started.
- UXI2-2: a row you return to (list, rail, Runs tables) is centered when it
  was off screen and gets a brief tint that fades over 1.5s, since focus
  set from code after a click draws no ring. Focus survives a table that
  is still re-rendering, and waits up to 3s for a reloading list.
- Trust-blocked runs use the primary Open workspace button; empty output
  reads "No output."

* fix(automations): address C2 review and UX-I3 findings

C2:
- C2-01: a Back/Forward replay that cannot show its run (history read
  failed) records nothing, so the entry keeps the requested run and
  Forward history is untouched.
- C2-02: the list and global Runs pages focus their search field
  ("Search automations" / "Search runs") on user navigation; the list
  search no longer autofocuses, so a restored page leaves focus alone.
- C2-03: returning to a run waits up to 5s for the table's data to list
  it (cancelled when the page changes or the user focuses elsewhere),
  instead of a fixed frame budget.
- C2-04: "Started" appears only with launch evidence (dispatch time, or
  the start time of a completed/dispatched older record); skipped and
  missed runs show their slot only.

UX-I3:
- UXI3-1: the list, detail stat, rail and run tables all show a run's
  listed time: its scheduled slot, or a folded run's latest occurrence.
  The usage summary carries it as lastRunListedAt; older hosts fall back.
- UXI3-2: a returned row that is already visible stays put; only an
  off-screen row is centered.

* fix(automations): address CodeRabbit round 2 and UX-I4 note

- Spend reads "Unavailable" whenever the latest history read failed,
  instead of totals from the retained earlier read.
- The run a table reveals on return becomes its current row, so arrow
  keys continue from it.
- Back/Forward to Runs spans every host, as the Runs tab does.
- Revealing a returned run scrolls only as far as needed (align auto).

* fix(automations): address C3 review

- C3-01: "Started" needs real launch evidence. A failed run counts as
  launched only if it reached a chat session or terminal; the chat
  launcher's dispatchedAt on a refusal or early throw is not a launch.
- C3-02: each Run now request has its own deadline. An answer that
  arrives after the request's 60s dispatch deadline ends it instead of
  starting a fresh 20s wait, whichever automation is selected.
- C3-03: the returned-to row stays focused through the whole readiness
  budget, including a refetch that clears the cached row and lists it
  again later; the reveal is re-requested while it is missing.
- C3-04: focus and reveal use the host-qualified run key in the global
  Runs table, so the same run id under two hosts returns to the right
  one.
- C3-05: once the user focuses anything else, the repair stops for good.

* fix(automations): address C4 review and the rail listed time

- C4-01: a failed terminal run keeps its Started time after terminal
  retention clears the pane key; terminal runs get dispatchedAt only at
  dispatch. A failed chat run still needs a chat session.
- C4-02: when a refetch drops the returned row for good, focus lands on
  the page search once the readiness budget ends instead of the body.
- C4-03: the run page's focus key is host-qualified, so moving between
  same-id runs on different hosts focuses the new title.
- The Recent runs rail lists a folded run at its latest occurrence, the
  time the list and detail show.
2026-11-13 17:13:38 -08:00
OrcaWinandOrcaWin 404c3de880 test: remove low-value startup and account coverage (#42206)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-13 17:08:26 -08:00
Kelvin Amoaba f86697bdef fix(files): opening a file from the phone no longer switches the desktop's view (#42212)
* fix(files): phone file opens no longer switch the desktop's view

files.open and files.openDiff passed an absent navigation target straight
to the window, which treats absence as a host switch. Phones send none,
so every phone file or diff open moved the desktop to that workspace and
the editor. Resolve an absent target to caller at the RPC; host/all from
the CLI's --focus still move the window.

* fix(mobile): Open in session selects the diff on the phone itself

The review screen relied on the desktop switching to the opened diff,
which only reached phones still following the host. Select the opened
diff for this phone before going to the session.

* fix(mobile): select only the working-tree diff and stop when the review screen closes

* test: drop type casts the changed-code gate flags
2026-11-14 01:07:57 +00:00
Neil b8507d4d4a fix(settings): give unnamed Settings controls accessible names (#42216)
Add aria-labels to the UI zoom and terminal font size steppers and the
word separators input, name the scroll speed slider thumbs, and link the
visible Branch prefix, Arguments and Command template labels to their
fields via htmlFor/id.

Fixes #41604
2026-11-13 17:07:08 -08:00
OrcaWinandOrcaWin 2d6c923126 test: remove low-value terminal, tray, and updater coverage (#42213)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-13 17:04:28 -08:00
Brennan BensonandClaude Opus 5.5 e5e4f6f4c9 perf(pickers): window the Automations and Skill install workspace pickers (#41396)
* perf(pickers): window workspace comboboxes and the Cmd+J result list

The Automations and Skill install workspace comboboxes mounted one cmdk row
per workspace while open, and the Cmd+J result list mounted every capped
section row plus each See more page. cmdk moves the highlight, runs Enter and
publishes aria-activedescendant by querying mounted rows, so these lists could
not be windowed while cmdk owned selection.

Each surface now owns its highlight over the full ordered result list:
movement keys follow cmdk's bindings over every result, Enter and click share
one activation path, and the input's aria-activedescendant names the
highlighted option, which stays mounted. Rows render as plain listbox options
outside cmdk's registry and only the visible window mounts (TanStack
virtualizer; Cmd+J keeps natural layout below 50 rows). Filtering, ranking,
section caps and See more are unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* refactor(pickers): share the windowed command virtualizer and keep the compiler gate

Move the active-option pin and command-list reveal padding into one hook used
by all three surfaces, keep virtualizer consumers out of React Compiler like
the other TanStack lists, and express the dialog row styles and the flush skill
rows as command variants.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* chore(pickers): record the windowed command virtualizer hook's compiler bailout

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix(pickers): keep virtualizer geometry across scrolls and match prior highlight/IME behavior

- Stable per-list key/size getters so scrolling and hovering no longer rebuild
  every row's virtual geometry.
- Moving the pointer over the already-highlighted option does no work.
- Jump to… numbers every rendered option, disabled ones included.
- The task Cmd/Ctrl+Enter shortcut ignores IME composition keys.
- The skill install workspace picker opened with nothing chosen highlights the
  first workspace again.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix(pickers): let the shared virtualizer own row key identity

Callers now pass their ordered row keys; the shared hook keeps one key array
per ordered sequence and derives the key getter from it, so a list rebuilt
with the same rows (for example after an unrelated workspace metadata update)
no longer forces a full geometry rebuild, while real reorder, insert, remove
and filter changes still do.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix(pickers): keep the row See more selects in view when Jump to… starts windowing

Crossing 50 rows through See more switches the list to windowed rendering;
reveal the newly highlighted row after that commit so it stays on screen as
it did before.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* perf(pickers): keep Jump to… on its original list; window only the two workspace pickers

The real-app benchmark showed no meaningful gain for the Jump to… results
(they rarely reach 50 rows), and windowing them changed the See more
behaviour at the threshold. Restore Jump to… exactly as on main and keep the
windowed list, model-owned selection and option primitive for the Automations
and Skill install workspace pickers, which measured clear wins.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-11-13 17:03:58 -08:00
Neil 6a0d446ccf fix(release): build Linux x64 on ubuntu-24.04 to keep node-pty baseline x86-64 (#42210)
ubuntu-latest now resolves to the Ubuntu 26.04 image, which installs the
amd64v3 package variant. Its GCC defaults to -march=x86-64-v3, so the
Electron-ABI node-pty in 1.4.257 shipped AVX instructions and the terminal
daemon died with SIGILL on CPUs without AVX. Pin the Linux x64 release
build to ubuntu-24.04, the image that produced the working 1.4.256.

Fixes #41637
2026-11-13 17:01:54 -08:00
Jinjing 4d3cfb7dcc fix(notifications): remap accent/input/border onto the notice surface (#42207)
Outline and ghost buttons in toasts and corner cards painted dark:bg-input/30
and hover:bg-accent from the app palette under popover text, and panels and
buttons drew edges from the app's --border and --input. For app themes the
notice scope now remaps --accent, --accent-foreground and --input onto the
readable secondary fill, and --border onto a popover-text edge. Dark outline
buttons get an inset edge, and --notice-border now follows the popover text.
Built-in themes paint as before.
2026-11-13 16:58:47 -08:00
Kelvin Amoaba 62b22aeab0 fix(computer-use): read minimized, hidden and other-Space macOS windows without --restore-window (#42182)
* fix(computer-use): observe minimized, hidden and other-Space windows on macOS without a restore

macOS only enumerated on-screen windows and dropped minimized AX windows,
so an app whose window was minimized, hidden or on another Space (any
full-screen app) could not be observed, and agents fell back to
--restore-window, which activated every window of the app and switched
the user's Space.

Enumerate every window, keep the off-screen ones accessibility can still
read (other-Space windows by remote token, closed windows dropped by
their Space membership), and report their real minimized and off-screen
state. Background pointer and key input on such a window refuses before
sending anything. --restore-window now raises only the target window,
once per request, and delivery is measured from whether the target
became frontmost.

* fix(computer-use): pin the restored window and prefer visible windows by default

* fix(computer-use): keep window-index cache keys and stale-element checks across a restore

* fix(computer-use): restore only this app's resolved window and refuse a closed target before raising

* docs(computer-use): say macOS reads minimized, hidden and other-Space windows
2026-11-14 00:58:33 +00:00
Kelvin Amoaba cf02703c13 fix(browser): refuse exec commands that leave Orca's page; keep orcad Chromium headless (#42200)
* fix(browser): keep agent-browser exec on Orca's page and orcad Chromium headless

exec passed raw agent-browser argv through after stripping only --cdp and
--session, so connect, tab/window, close, set viewport, batch items and
global launch options could move the helper to another browser or create
targets behind Orca's tab model. Refuse them in one shared gate used by the
desktop bridge and orcad's external-Chromium provider.

orcad's external-Chromium helper inherited AGENT_BROWSER_* and read the
user's ~/.agent-browser/config.json and ./agent-browser.json, so headed or
extensions settings opened a visible window. Drop inherited settings, point
AGENT_BROWSER_CONFIG at an empty Orca-owned file and pin --headed false.

* fix(browser): refuse inspect, stream and auth in exec and match agent-browser's batch escapes

* fix(browser): retry orcad's agent-browser config write after a failure
2026-11-14 00:57:19 +00:00
Brennan Benson 70525610f7 Keep remote browser certificate warnings actionable (#41235)
* Preserve remote browser certificate warnings through navigation

* Apply current remote observations at the session boundary

* Document array proxy forwarding in the performance contract

* Keep remote browser failure fallbacks within current observations

* Defer remote observation reads to lifecycle callbacks

* Apply remote page observations without preempting pending outcomes

* Preserve command loading ownership across partial page updates

* Reuse browser host identity within each mirror record

* Explain transparent record access in the loading contract fixture

* Keep adoption fixture aligned with remote loading session

* Name the remote navigation fixture return contract
2026-11-14 00:52:46 +00:00
Kelvin Amoaba 80a514cfb6 fix(browser): stop agent CLI clicks over --environment from moving the desktop (#42205) 2026-11-14 00:51:47 +00:00
Kelvin Amoaba a376f8fbe3 fix(cli): keep orca open and computer permissions from taking the foreground (#42166)
* fix(cli): keep Orca in the background when orca open launches it

* docs(cli): say orca open leaves the foreground alone

* fix(cli): ask a running Orca to open its window in the background

* fix(main): keep background reveals inactive on Linux maximize and drop the flag on admin restart

* fix(cli): narrow the open status before returning it

* fix(main): keep focus-existing-window free of main-window contracts for the web typecheck

* fix(cli): cap the open window request at five seconds
2026-11-14 00:51:45 +00:00
Kelvin Amoaba 746b031870 fix(terminal): keep the user's focus when an agent splits a terminal (#42204) 2026-11-14 00:44:02 +00:00
Brennan Benson 235d446873 perf(codex): derive mirror section headers once per document (#42190) 2026-11-13 16:37:49 -08:00
Brennan Benson 8c306365dd perf: refresh agent models when CLI inputs change (#41976)
* perf: refresh agent model catalogs when launch inputs change

* test: cover model catalog launch input changes

* test: require explicit refresh intent for floating agents

* fix: combine model catalog ownership imports

* Observe direct agent scripts after interpreter options

* Expose refresh intent in preflight API types

* Keep slow model discovery alive beyond picker waits

* Explain the real transport regression test budget

* Use typed catalog test requests and locate cast rationale

* Assert discovered ACP effort choices directly

* Fix catalog regression fixture types
2026-11-13 16:34:06 -08:00
Jinjing 9f956312e3 perf(hooks): skip lint-staged's serial worktree walks in pre-commit (#42184)
lint-staged 16.4.0 walks the whole worktree several times before any
linter runs. On a cold stat cache that made small commits take over a
minute. Extend the existing lint-staged patch:

- getDeletedFiles: replace the serial `ls-files --deleted` with
  `diff-files -D` (parallel preload, fsmonitor bypassed) plus
  assume-unchanged entries, filtered by the same lstat rule, so the
  deleted-file contract is unchanged.
- getUnstagedFiles: `status --untracked-files=no`; the `??` lines were
  already discarded.
- config discovery: list tracked config files only. A nested config
  must be tracked or staged to apply; untracked configs at the repo
  root are still found.

Run lint-staged directly from the hook; husky already puts
node_modules/.bin on PATH, so `pnpm exec` only added startup time.
2026-11-13 16:33:59 -08:00
Brennan BensonandJinjing a36620afd0 perf(github): share automatic PR reads and reuse the host budget (#42033)
* perf(github): share and pace timed pull request reads on the host

Reuse exact completed results for automatic refreshes, back off unchanged
settled pull requests, and route server revalidation through the existing
host budget while preserving foreground reads and older clients.

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>

* fix(github): preserve shared producer settlement and selected demand

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>

* test(github): cover paired receipt retries and watch fairness

* test(github): explain shared fake-clock fixture

* test(github): typecheck host and renderer integration together

* test(github): name exported fixture mock types

* Revert "test(github): typecheck host and renderer integration together"

This reverts commit 756a38787c.

* test(github): place host and renderer loops in cross-layer suite

* fix(github): preserve refresh policy and shared callers

Use the same validated freshness for cached queue reads and their follow-up. Keep forced mergeability rereads and detach cancelled consumers independently from the shared lookup.

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>

* fix(github): refresh settled rows when exposed again

Use the same finite foreground age to admit and consume the queued read. A recent exact result can still satisfy it, and settled rows do not acquire a recurring timer.

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>

* fix(github): accept only current PR read completions

Keep shared publication and retry planning on the accepted actual read. Preserve legacy own replies, terminal loading and ordinary work after a superseded lookup, and honor the accepted error gate before automatic recovery.

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>

* test(github): follow moved request contracts

* test(github): explain the partial event fixture type assertion

* fix(github): preserve queued deadlines and detachable PR waits

* fix(github): compare refresh wakes on the elapsed clock

* test(github): format queued refresh deadline cases

* fix(github): charge actual producers and fence retry gates

* fix(github): preserve fresh intent and producer error policy

* fix(github): retain owned cold-read retry gates

---------

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
2026-11-13 16:33:07 -08:00
Kelvin Amoaba bff57f1e37 fix(browser): keep late page-opened tabs and system-browser opens from moving the user (#42199)
A tab a page opened with no gesture counted as the agent's only within the
agent's 20 s idle window, so a late open (an OAuth tab finishing after the
agent went quiet) switched the user's visible tab. Track, per guest, whether an
agent drove the page since the desktop user last gave it input, carry it into
popups the page opens, and keep such opens in the background.

A popup whose owner tab was gone handed any http(s) open to the system browser,
including agent, phone and scripted ones, which took the foreground. Only the
desktop user's own click opens it there now; the rest are reported blocked.
2026-11-14 00:31:44 +00:00
Kelvin Amoaba cc1e3740da feat(computer-use): scroll and select list rows in background Linux windows, and aim GTK 4 clicks (#42201)
* feat(computer-use): scroll and select rows in background Linux windows, and aim GTK 4 pointer input

Scroll moves the nearest scroll bar's value by whole viewports, handing
the scroll outward at a view's end, or pages a web document with
Component.ScrollTo, before falling back to the pointer. A click on a
list row with no action selects it through the list's Selection when
the index is proven to name that row. GTK 4 rectangles come from
WINDOW extents plus the X11 client origin, since its SCREEN extents
read [0, 0, w, h].

* fix(computer-use): keep Linux background scroll and select honest under partial and slow results

Wait for ScrollTo to move before planning the next page, report pages
already scrolled instead of falling back, let refused scroll bars fall
through, clear a multi-select list before a plain-click select, accept
only an InvalidArgs refusal as index proof, bound child walks, and
read GTK 4 origins lazily.

* fix(computer-use): scroll the innermost Linux view that overflows, and bound the scroll search

ScrollTo now runs on each ancestor that overflows its own box, innermost
first, so an inner scroller moves before the page; coordinate scrolls
start from the deepest node under the point. Cap the scroll bar search
to small containers, report a document at its end as a no-op, keep
looking past an unusable spanning child, and look up GTK 4 window names
once per operation.
2026-11-14 00:31:34 +00:00
OrcaWinandOrcaWin 5463aa10d6 test: delete shallow telemetry schema and allowlist suites (#42203)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-13 16:21:12 -08:00
Yasyf Mohamedali 0bc55330fc fix(orchestration): mark a question read when reply answers it (#41979) 2026-11-13 19:15:46 -05:00
Jinjing f993c66b74 refactor(menus): share menu row styles and add a compact density (#41847)
* refactor(menus): share menu row styles and add a compact density

* test(menus): drop the CSS-class density test
2026-11-13 16:12:40 -08:00