Commit Graph
1742 Commits
Author SHA1 Message Date
Jinjing b96d19d933 Keep overlays open when focusing the chat composer (#37403)
* Preserve open overlays when focusing the chat composer

* Fix chat composer focus after launch menus close

* Fix chat composer focus handoff after overlays close

* Fix composer focus after custom overlays close

* Prevent chat composer from stealing overlay focus

Scope recovery overlays to their own pane and let menus dismiss before
returning focus to the composer. This keeps the quick launcher open
when delayed chat actions complete.

* Fix composer focus across nested overlays

Track focus ownership through portaled overlays so the launch prompt can
regain focus while its model list is open. Close the context menu before
inserting a quote so the caret lands after it.

* Fix overlay focus CI regressions

* Complete overlay focus ownership for inline and retained surfaces

* Declare public overlay focus hook return type
2026-11-02 14:50:41 -07:00
OrcaWin ebf277b4aa test: remove 659 low-value renderer tests (#37544) 2026-11-02 12:58:11 -08:00
Kelvin Amoaba 0cd648d697 fix(browser): publish a server page's in-place address changes (#37547) 2026-11-02 20:57:11 +00:00
Brennan Benson 7872cb5aa1 Disable the lagging experimental orchestration panel (#37527)
* Disable the orchestration panel after reported app lag

* test: expect suspended orchestration card to stay hidden
2026-11-02 11:11:00 -08:00
JinjingandBrennan Benson 96cceba75a Keep selected Codex permission mode visible until the next turn (#37419)
Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com>
2026-11-02 11:00:14 -08:00
Brennan BensonandClaude Opus 5.5 e59b843336 Keep review note changes on the workspace copy they came from (#37204)
* Keep review note changes on their captured workspace owner

* Keep review note actions on the copy whose notes are shown

Review notes now read their owner and their notes together, so an action
always changes the copy the user is looking at:

- A paired SSH copy saves through its server even when its row does not
  name the server, instead of saving on this computer.
- The Markdown preview shows and edits the selected copy's notes, not the
  first copy listed with the same workspace id.
- While the selected copy is not listed yet, no other copy's notes are
  shown; a note started then saves to that copy once it lists.
- A listing that stamps the same copy's host no longer looks like a new
  copy: a pending Send stays held and unsaved note edits are kept.
- Clear all / Clear file confirmations stay on the copy they opened on
  when the selected host changes.
- A copy removed since the user acted reports the existing save or clear
  failure once instead of failing silently.
- Mounted note views skip ownership work on store updates that cannot
  change it, and do not re-render for another copy's changes.

* Keep review notes on the exact workspace copy each surface shows

Notes, their owner and every note action now come from one copy identity.
Previews and editors of a server's copy read and save that copy, paired
SSH copies keep working through their server, an SSH draft never lands on
a local row, and controls stay disabled instead of claiming "All notes
sent" while a copy's notes are unknown. Open Clear confirmations share the
cached read, so unrelated store writes do no row work.

* Resolve review-note copies through the shared workspace ownership rules

Every listed row now gets its copy from the same rules the app routes
writes with, including server provenance from detected listings and the
SSH place behind a paired server for older rows without host stamps.
Previews, editors and diffs read notes from their own tab's provenance
instead of the selected copy, folders honor their source's host, and a
note composer's shortcut captures the copy its surface shows when it
opens.

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

* Keep folder review notes on the folder copy their source names

A folder's notes now come from the same source rules as worktree notes,
so a file from this app never shows or saves to a server's folder with
the same id. Queued folder saves and rollbacks check the captured folder
copy the same way reads do, and resolving copies no longer rescans the
project list for every row.

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

* Read review-note copies through the shared id indexes

Folder and worktree note views now read only their own workspace's
catalog entries from the shared indexes, and readers of one folder
share its qualification, so listing updates cost work proportional to
what is shown rather than catalog size times readers. Also fixes the
type errors and the end-to-end note seeds, which now pass the owner of
the worktree they seed.

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

* Share review-note copy resolution across rows and readers

Rows of one workspace on the same host now share a single ownership
answer per catalog snapshot, so duplicate listings of an SSH worktree
no longer make every note view rescan its peers. Folders that are not
listed return one shared answer instead of leaving cache entries behind.

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

* Name the catalog snapshots review-note ownership results are shared under

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

* Save renamed-file drafts under the new path and encode restored SSH targets

A diff note draft opened before its file was renamed in place now saves
under the file's current path, still on the copy it was opened on. A
restored SSH file whose target id needs encoding now shows and saves its
own copy's notes.

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

* Update the diff note path ref after render instead of during it

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-02 10:32:22 -08:00
Brennan Benson 0747751590 Chat tabs get the terminal's right-click actions (#37442)
* Add standalone chat right-click session actions

* Update fork draft fixtures for source focus callbacks

* Read chat menu data only while the menu is open

Quick Commands and the provider Copy Session ID now read their data from
components that mount only inside the open chat menu, so closed menus in
retained chats do no work on repo, project or agent-status writes. The
add-command editor reuses the terminal's editor dialog and outlives the menu.

Chat menus also stop showing the Insert hint, since they run every quick
command in a new tab the way the tab bar's Quick Commands menu does.
2026-11-02 10:22:29 -08:00
Brennan Benson 21857c7424 Continue in Chat UI refuses before closing the terminal when another terminal runs the conversation (#37397)
* fix(native-chat): let createSupport ask whether another terminal runs a resumed conversation

A resume's createSupport can now carry resumeFrom (behind
agent-session.structured.resume-writer-admission.v1, since older hosts'
strict params reject it). The host runs the same writer check create runs,
leaving out the panes the client will close first (matched by key or by
the PTY they resolve to; a shared tmux/OpenCode server is never left out),
and probes the candidates together so a bounded client wait is not spent
on one probe after another. The host's English refusal says "another chat"
only when it names one. The resume params move to their own module to keep
the params file under its line limit.

Tracked in STA-13440.

* fix(native-chat): refuse a resume before anything closes or opens when another terminal runs it

Continue in Chat UI asks the host before closing the terminal, naming the
panes the close takes; when another terminal runs the conversation it says
so in one toast and leaves the terminal open with no chat. Session History's
Resume in New Chat (and any other resume launch) asks through the launch
admission and, on that refusal, opens no placeholder tab: its caller's one
toast is the only notice. A local admission that times out still never
leads to a close. Older hosts without the capability keep today's flow.
The launch admission's toasts move to their own module to keep that file
under its line limit.

Tracked in STA-13440.

* fix(native-chat): say why a resumed chat failed when a terminal holds it or its history is missing

A failed start refused because a terminal's agent still runs the
conversation (no chat named as holder) now reads the existing "already
running this conversation in another terminal" words instead of a bare
"Chat could not be started.". A transcript the host could not find yet gets
the same history words an unreadable one already had. This covers the
create-time backstop: a terminal started between the pre-check and create,
or an older host without the pre-check.

Tracked in STA-13440.

* fix(native-chat): keep exporting ResumeSource from the session params module

* fix(native-chat): keep a terminal open when its host's resume check could not be confirmed

A failed capability read was taken as an older host, so the resume question
was left out, the host admitted, and the terminal closed before create refused
the conversation another terminal runs. An unread capability now leaves the
resume unanswered; a host that reports an older capability list keeps its path.

* fix(native-chat): say "another terminal" only where the refusal's owner is still known

The write failure drops the refusal's owner, so a chat-owned conflict on a
send, mutation or phone notice read as a terminal. Only the failed start,
which keeps the raw refusal, now records that no chat was named; everywhere
else keeps the generic wording.

* perf(native-chat): resolve panes in the writer check only when some are left out

Every create, resume and acquire check resolved each matching row's pane to
its PTY, even with no panes to leave out, and each unresolved key scanned
every terminal. With nothing to leave out no pane is resolved now; with some,
one identity read context serves every key.

* test(native-chat): pin createSupport's resume refusal to create's, and History's one notice

Runs the real createSupport handler on a runtime whose status store proves
another terminal live: leaving out the source pane admits, otherwise it refuses
with create's code and details. The Session History replacement keeps its chat
and toasts once when the host refuses before anything opens.

* fix(native-chat): translate the "another terminal runs this conversation" toast

It is now the only notice when Continue in Chat is refused before the terminal
closes, and only English carried it, so every other language showed English.

* fix(native-chat): withhold an unread resume capability only where a terminal closes next

Reading an unknown capability as unreachable refused Session History and
/resume launches on a paired host that main admits and create completes. The
host question now asks the plain question on an unread capability and says so
on its answer; only Continue in Chat, which closes the terminal next, treats
that answer as not admitted, from the same read that chose the request.

* test(native-chat): count the writer check's terminal reads with a typed map

The perf contract counted iteration through a proxy, which the type-aware lint
rejects. It now counts record reads on a Map subclass; a scan of every
terminal per row still shows up as rows times terminals.

* test(native-chat): read the writer-check fixtures without type assertions

The changed-code gate rejects casts. The perf contract builds real terminal
records through the identity fixture, and the createSupport parity test reads
create's refusal through the shared refusal parser.

* fix(native-chat): declare the refusal holder that failed-start cause words read

The failed chat's notice passes its launch failure, with the holder its
refusal named, through the cause parts to the words that tell a chat from a
terminal. Those functions now declare that field instead of carrying it
undeclared, which the typecheck rejected for a literal in the test.

* perf(native-chat): probe a conversation's writers a few at a time and stop at a holder

The writer check started a process probe for every matching row at once and
kept them all running after the first live holder refused. It now picks the
rows in one synchronous pass, probes at most eight at a time through the
shared bounded pool, and starts no probe once a holder refused.

* test(native-chat): pin the writer check's single terminal look on the real runtime

The scale contract built its own resolver, so a host that made an identity
read per pane, or passed none, still passed. It now runs the runtime's own
writer check over recorded terminals and counts read contexts and per-key
terminal scans: one context and no scans with panes to leave out, none
without.
2026-11-02 10:18:36 -08:00
OrcaWin c3b7560fb4 test: remove low-value renderer and terminal tests (#37456)
* test: remove low-value renderer and terminal tests

* test: align floating tab geometry with content-fit sizing
2026-11-02 04:50:07 -08:00
OrcaWinandOrcaWin 8fb8e6ef0f test: remove 30 low-value tests and fix selected-host folder activation (#37421)
* test: remove 25 low-value checks and six complete suites

* Remove deleted startup benchmark from plugin CI routes

* Remove CI route for deleted pet layout smoke suite

* test: repair retained E2E labels and collision lifetimes

* test: remove synthetic activation collision scaffolding

* fix: activate folders opened on the selected runtime

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-02 03:32:08 -08:00
Neil 51cb2f189c refactor: organize native chat input and transcript owners (#37334) 2026-11-02 03:14:58 -08:00
NeilandClaude ac4a21f3d2 test(e2e): update two WSL specs to the stopped-distro copy and serve-only Settings (#37394)
wsl-host-paired-phone asserted the pre-#36771 'isn't running' copy; it now
asserts the stable remote_runtime_unavailable code and '<distro> is stopped'.

wsl-move-dialog's gate-closed case seeds a saved host, which since #34683 puts
the app in serve-only: the WSL hosts section still lists the host. Assert
instead that Add is hidden and the host row's menu has no move entry.

Co-authored-by: Claude <noreply@anthropic.com>
2026-11-02 03:10:14 -08:00
OrcaWin 8f2817a4c8 test: remove ten non-gating benchmark cases and obsolete tooling (#37453) 2026-11-02 03:08:09 -08:00
OrcaWin 5cca72e605 test: remove 33 low-value tests and obsolete benchmark runner (#37441)
* test: remove 33 low-value tests and obsolete benchmark runner

* test: remove import left unused by test deletion
2026-11-02 02:47:41 -08:00
OrcaWinandOrcaWin 23c2515586 test: remove 41 low-value test declarations (#37430)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-02 02:12:23 -08:00
Brennan Benson 255401c2a5 Continue chats automatically when a usage limit resets (#36873)
* fix(native-chat): an open chat moves to the account you switch to before its next message

A running chat's agent read its account only when it started, and nothing compared it with the
account a start would use now, so open chats kept answering on the old account after a switch.

The agent a chat runs now records the account its launch used, and the host's replace-before-the-
next-send check replaces an idle one whose account is no longer what a start would use. A chat
mid-reply finishes on the old account first. Claude chats follow; agents whose chats keep the
account they were created on are never compared.

A chat's model-list reads and saves now use the account it runs on, so a moved chat no longer
writes its new account's list under its first account (STA-11281).

Tracked in STA-11211.

* fix(native-chat): declare the launch-account read for the runtime layer that wires the host

* fix(claude): find custom chat history before managed-account resume

* test(claude): assign the complete custom account home

* feat(native-chat): offer account switching and hand-off at usage limits

* fix: track the provider in account-list reload effects

* fix(native-chat): target recovery actions at the chat host and transcript

* fix(native-chat): verify account recovery for each chat on its host

* refactor(native-chat): retain the existing image-support result

* fix(native-chat): withdraw account recovery after failed eligibility reads

* fix(native-chat): leave unavailable recovery facts absent

* Align Japanese usage-limit recovery copy with catalog convention

* Preserve complete chat context through usage-limit recovery

* Keep Continue callback focus optional

* Keep recovery fixtures and account effects type safe

* Keep chat recovery on native sources and native accounts

* Validate native recovery files after path admission

* Use the optional cursor shape in recovery fixture

* fix(native-chat): exclude source CLI family from limit handoff

* Resolve recovery context in the owning workspace directory

* Add the continue-at-usage-limit-reset setting and its chat row lines

* Continue chats automatically after usage limits reset

* Fix automatic continuation fairness, lifecycle and host settings

* fix: bind automatic continuation withdrawal to accepted actions

* fix: withdraw source auto continuation after handoff starts

* Read unopened chats with the saved-record reader for usage-limit continue

Unopened chats were read through the raw-row replay, which no longer sees
chats saved as keyed records, so a usage-limited chat that was not open
was never continued after its reset. Read them the way the rest of the app
reads a chat without opening it. Also use the shared visible-tab check,
keep the ordinary rewind result without a sequence as main does, and adapt
two tests to the current queued-message and saved-status behavior.

* Keep a usage-limited turn idle after any rewind restores it

Rewind completion read the resulting conversation through the raw-row
replay, which no longer sees chats saved as keyed records, and a forked
rewind wrote its completion before the new history's records. So a
limited turn that a rewind brought back was continued automatically
after its reset. The completion now reads the saved result the way the
app reopens a chat, and the forked rewind writes its completion after
the new history in the same transaction.

* Type the usage-limit auto-continue test mock without an assertion

* Fix type errors from main's settings, failure-wording and refusal changes

* Keep ordinary settings replies when the paired host changes mid-call, and list the cancel method in wire contracts

Settings reads and writes that don't carry the automatic-continue choice go
through the common runtime call again, so a reply that completes after the
paired host is removed still merges, as before this change. Only a write of
that choice stays pinned to the host it was made for. The structured method
count and the cross-version method manifest now include the cancel method.

* Keep a stopped turn's automatic continue withdrawn when its usage limit arrives later

A person could Stop a running Codex turn, have the turn then end with a
usage-limit failure, and still get an automatic "Continue where you left
off." after the reset, because Stop had nothing to cancel yet. The journal
write that first reveals a limited turn the latest personal Stop owns now
saves the same exact cancellation in that transaction, and a Stop accepted
just after the limit landed withdraws it too. Resume, deleting a queued card
and restarting keep it withdrawn; manual Continue and later turns are
unaffected.

* Bound the automatic-continue sweep and keep notice rows from re-rendering

The 10-second sweep now does nothing while the setting is off, republishes
only chats with a scheduled continuation, reads at most three unopened chats
per pass, and keeps going when one chat's saved history can't be read (that
chat is retried after the others instead of stopping every chat on the host).
Settings writes republish only when the switch changes. Working out the
usage-limit cut no longer indexes the whole conversation on every streamed
row. The chat's notice rows no longer re-render for status changes they
don't show. Adds operation-count and render-count tests for these bounds.

* Test that streamed journal commits after a Stop scan no history and build no command index

Drives real Codex rows through the host at 20 and 200 history rows: each streamed commit runs the Stop's commit hook and the status projection's cut reader with no newest-turn scan, no render and no full command index; the next turn end scans once and renders nothing.

* Leave a usage limit manual once its reset passed more than a day ago

Turning automatic continue on later no longer sends into chats whose limit reset days ago. Eligibility, which the row's summary, the sweep and the pre-send recheck all read, now requires the reset to be within the last 24 hours; older limits show the usual manual actions and are never continued unasked.

* Show only manual actions for a usage limit Orca can never continue

A limit more than a day past its reset is never continued, but its row still showed the setting link, inviting people to turn on a switch that could not help that chat. One shared check now decides whether a cut can ever be scheduled; the status summary and the sweep's eligibility both use it, so past the bound the row keeps only Continue Now, Hand Off and Add Account. A row already on screen when the day passes drops the line on the shared minute clock; the host alone decides sends.

* List every journal row kind in the Stop cut filter

The type-aware lint requires exhaustive switches; epoch, tombstone, submission and queue rows still cannot reveal a cut.

* Type the status-subscription mock instead of casting its handler

The changed-code casting gate rejects type assertions; the mock now carries the real subscription signature, so the recorded handler is typed.

* Open store-less conversations without the Stop withdrawal hook

Acquisition-only opens have no record store, so a person's Stop followed by a limited turn end made the journal commit throw and drop the turn end. Install the withdrawal only when a store exists; without one there is no continuation to withdraw. Also narrow the status summary before reading it and type the sweep test's send mock.
2026-11-02 01:52:02 -08:00
Brennan Benson c1641a8d7d Show the open Orchestration panel as a floating card (#37412)
* Show the open orchestration panel as a floating card

The open panel now floats in the closed tab's corner as a card as tall as
its rows. In chats it stops above the composer (the transcript frame
already ends there); in terminals it keeps the bottom quarter clear for
the CLI's prompt and recent output. Past that it scrolls inside.

* Keep the orchestration card's collapse button reachable in tiny panes

A terminal split can be 50px high, leaving the card no room under the 75%
limit, so its header and collapse button were clipped away. The card is
now never shorter than its header.

* Keep the orchestration card's collapse button inside narrow cards

In a narrow split the card is 20px narrower than the pane and its title
didn't truncate, so the collapse button was pushed past the card's edge.
The title now truncates and the header's side padding gives way before
the button, down to the 50px pane minimum.
2026-11-02 01:50:54 -08:00
OrcaWinandOrcaWin fe78cff1aa test: remove 20 low-value tests across 11 files (#37404)
* test: remove 20 low-value test declarations

* test: prune allowances for removed Git profiling suite

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-02 00:37:15 -08:00
OrcaWinandOrcaWin 5d59efc3ad test: remove 12 low-value test declarations (#37391)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-01 23:36:39 -08:00
OrcaWinandOrcaWin 1a816faefd test: remove 43 low-value cross-version test cases (#37317)
* test: remove 43 low-value test declarations

* test: update catalog scaling conversation view import

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-01 23:27:11 -08:00
OrcaWinandOrcaWin d061d235b6 test: remove 16 low-value test cases (#37333)
* test: remove 15 low-value test declarations

* test: remove scheduling and routing budget checks; route editor shots

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-01 23:26:03 -08:00
OrcaWinandOrcaWin 5c27709ca3 test: remove 21 low-value test declarations (#37373)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-01 23:07:04 -08:00
OrcaWinandOrcaWin 8d1453fba9 test: remove 17 low-value test declarations (#37327)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-01 21:51:45 -08:00
Neil f908d2f40a feat(plugins): plugin shot --editor to screenshot and drive custom editors (#37302)
* plugins: orca plugin shot --editor, and plugin open --editor opens the file's folder

plugin open --editor now opens the file in the workspace that holds it,
matching its real path too (/tmp vs /private/tmp), and otherwise adds the
file's folder as a folder workspace instead of failing with no_workspace.

plugin shot <dir|key> --editor <file> [--theme] [--width --height]
[--act] loads the editor afresh in a hidden tab, waits for it to get its
document and ask for it (a new editor.subscribed frame event), captures
the editor's guest with the panel shot's capture path, and sends --act
clicks, drags and keys as real input via sendInputEvent. It exits 1 with
the frame's errors when the editor throws, is blocked by its content
policy, or never asks for its document within 5s; theme and size are put
back. New RPC method plugins.shotEditor so older hosts fail cleanly.

* plugins: shot --editor never changes the author's file

With --act the shot copies the file into a temporary folder, shoots the
copy in a temporary folder workspace, then closes its tab and removes the
workspace and folder; --in-place acts on the file itself. Without --act
it opens the real file, leaves its buffer alone and closes the tab if the
shot opened it. Afterwards Orca shows the workspace it showed before.
Regenerates the skill's CLI reference.

* plugins: fix editor shot typecheck (refusal next step, RPC test mock)

* plugins: editor shot targets its own guest, flushes before reload, scopes cleanup per capture

- Main captures the exact guest WebContents the shot's tab mounted, not the first with its URL.
- An open editor's pending edits are flushed before the shot reloads it; the shot fails if not.
- --act --in-place keeps the acted tab and its unsaved edits.
- end-capture undoes only its own capture (per-capture id), so overlapping shots don't clash.
- The file's workspace lookup includes local folder workspaces.

* plugins: shot --status-bar/--window, key acts focus the editor guest, panel shot selects a workspace

- Editor --act keys first give the guest's <webview> DOM focus and refocus its target, so a canvas
  that keeps focus no longer drops later keys; never webContents.focus(), which focuses the window.
- orca plugin shot <dir|key> --status-bar | --window [--theme]: captures Orca's status bar or the
  whole hidden window (plugins.shotChrome) with the existing capture helpers.
- With no workspace showing, a panel shot selects this machine's most recent workspace in the
  hidden window instead of failing.

* plugins: a shot's end restores only its own capture overrides

* plugins: regenerate the testing runtime with the editor subscribed signal

* plugins: editor capture refusals go through one CLI-message helper

* fix(plugins): give the chrome shot refusal a next step
2026-11-01 21:38:04 -08:00
Neil 9b39188021 refactor: organize session option and conversation owners (#37289) 2026-11-01 21:33:42 -08:00
OrcaWinandOrcaWin 98d22faa8d test: remove 96 low-value test cases (#37296)
* test: remove 96 low-value test declarations

* test: update timeout baseline after audit903

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-01 20:33:06 -08:00
Neil bdd997f71f test(cross-version): load moved modules from wherever each release defines them (#37297)
* test(cross-version): load moved modules from wherever each release defines them

v1.4.246 is the first release cut after #36909, #36979, #37036 and #37070 moved
the agent-session modules, so suites that imported the old paths from the
newest release failed with ERR_MODULE_NOT_FOUND for every PR running
cross-version wire. importReleaseCheckoutModule now resolves a moved module to
the path the checked-out release ships, from one table of current and earlier
locations, so both the rolling baseline and older pinned refs load. The
released-chat writers drop their own per-module existsSync fallbacks for it.

v1.4.246 also ships outcome storage, so it reads chats this build writes and
closes its own rows with the outcomes marker. The downgrade test pins its
refusing window to the two releases before outcome storage, and the upgrade
test leaves the marker to the outcome reader, which restoreJournal checks.

* test(cross-version): find a moved module by name in the release instead of a path table

A table of earlier paths is a list of stale src literals the path-literal ratchet rightly refuses, and needs an entry for every future move. The release checkout itself says where it ships each module: the one file with that name under the same source root. Prunes the three released-chat-writers entries the ratchet baseline grandfathered.

* test(cross-version): pin the chat-upgrade writers to the releases before outcome storage

v1.4.246 keeps a chat in outcome tables, so its rows hold only the marker and there is no row upgrade to carry on; the newest release stays the reader this build must match.
2026-11-01 20:19:25 -08:00
Brennan Benson 5020bfead6 Keep Session History open when a chat workspace was deleted (#37200)
* Keep deleted-workspace chat Resume in History

* Address review: keep notification bounce, announce History toast, tidy refusal outcome

* Fix mobile type narrowing in History open failure

* Re-measure mobile web bundle sweep after History notice import removal
2026-11-01 19:31:05 -08:00
Neil 0509a2d83a refactor: group local PTY provider and shell readiness modules (#37235) 2026-11-01 16:16:22 -08:00
Neil ec112c6b01 perf(renderer): stop agent spinners that are scrolled out of view (#37153)
Offscreen or clipped working rings dropped their CSS animation through one
shared IntersectionObserver; revealing a ring restarts it and the existing
animationstart anchor keeps every ring on the shared phase.

The spinner bench gains an always-on comparison variant and reports
compositor frame counts.
2026-11-01 16:05:02 -08:00
Neil b6467f0577 test(e2e): expand child agent lists in spinner benchmark fixture (#37184)
* test(e2e): expand child agent lists in spinner benchmark fixture

Sub-agent lists start collapsed since #36936, so the spinner benchmark's
working subagent rows never mounted and the census assertion failed.

* test(e2e): wait on child-agent disclosure expansion instead of sleeping
2026-11-01 16:04:57 -08:00
Neil 572a9c62e1 refactor(claude): group agent view owners (#37147) 2026-11-01 13:47:24 -08:00
Jinjing 9599d718b6 Clarify Git operation status across workspaces (#37093)
* Clarify Git operation status across workspaces

* fix translation

* Clarify when a Git operation is running in another workspace

* Clarify Git operation feedback in Chinese translations

* Clarify which Git operations can block another workspace

* Show Git operation waiting feedback during PR preparation

* rm file

* Fix remote operation ownership test setup

* Fix remote operation ownership test setup
2026-11-01 14:41:11 -07:00
Brennan Benson 0fa5dae2f9 Read who each agent works with: its manager, workers and peers (#34890)
* Nest chat-UI orchestration workers under the agent that started them

Main's lineage projection only walked terminal panes, so workers running
in the chat UI never got a parent link and listed flat in the sidebar.
It now also projects chat workers, keyed by their visible chat row, and
resolves a chat creator or coordinator to that chat's visible row
instead of its handle or private mailbox pane key.

* Fix public worker lineage across assignment and row identities

* Complete terminal lineage provenance and bound active session selection

* Repair lineage test runtime boundaries and SQLite counters

* Provide read-only crew snapshots for each agent

* Batch public lineage verification after exact recency selection

* Derive crew relations once per meaningful host change

* Remove package manager lockfile churn from hook

* Use checked runtime values in lineage integration tests

* Document the trusted Dispatch SQL row boundary

* Keep lineage integration imports within their test programs

* Load native lineage fixtures before test execution

* test: complete lineage inputs in runtime and sidebar fixtures

* test: seed benchmark facts from active dispatches

* test: replace partial orchestration DB casts with typed fixtures

* test: complete stale-leaf mailbox fixture session input

* Derive durable crew parents from retained assignment proof

* fix(test): render worker lineage fixture with production list

* Add scoped terminal identity acquisition and preserve crew source wakes

* Share raw crew identity inputs through scoped production readers

* Exercise crew generation retirement through actual source owners

* Retire crew inputs on consumed ownership and visibility writes

* Use typed crew mutation and fixture access

* Repair crew fixture and RPC type contracts

* Align crew integration fixtures and RPC parameter contracts

* Encapsulate terminal identity mutations and captured reader contracts

* Seed terminal identity fixtures through canonical mutations

* Fix terminal identity fixture return type

* Cover terminal identity lifecycle schedules

* Align terminal fixtures with canonical identity sources

* Repair runtime fixture source contracts

* Use checked database fixtures for federation contracts

* Update crew source inventories and exit fixtures

* Preserve crew setup outcomes at existing subscription owners

* Match managed restore fixture to its nullable async return type

* Keep absent setup observations distinct from undefined failures

* Drive pending Crew questions from existing metadata

* Preserve nested pairing repair outcomes for shared callers

* Route attached workers to explicit local recipients

* Type Crew pending-question measurement receipts

* Match SSH repair fixture target absence to store contract

* Bound cold terminal layout construction and finite pane acquisition

* test: use public runtime identity in pane acquisition fixture

* Avoid repeated searches in cold workspace layout loading

* Verify cold loader fault identity and hook claimant effects

* Revert "Route attached workers to explicit local recipients"

This reverts commit f1335d1c06.

Keep attached workers on the existing Run-home routing path for this change.

* Omit crew peer addresses outside the active home route

* Keep crew retries on the verified runtime session

* Bound cold layout retirement and recorded-key construction

* Verify original cold layout failure identity

* fix: preserve surviving layout split references

* test: use typed retirement instrumentation properties

* test: preserve pane and retirement fixture contracts with checked types

* Prepare Crew record admission and wake identity changes

* Derive Crew recipient actions from current target owners

* Keep nested Crew process facts within selected acquisition

* Defer Crew legacy facts to consumers and complete raw coverage on success

* Use deterministic time in Crew command fixtures

* Document schema-owned Dispatch row assertions

* test: align Crew authority fixtures with typed project boundaries

* test: place Crew CLI integration in cross-surface project

* Type retained identity test meters with canonical source maps

* Document suffix Dispatch row boundary and preserve fixture unbinding

* test: migrate Crew authority arguments and mailbox observations

* Derive Crew attention and actions from complete recipient authority

* Fix Crew public-command fixture type contracts

* Align Crew fixtures with runtime reader and routing contracts

* Narrow receiving fixture calls to unary RPC methods

* Age pending question fixtures from every actual answer timestamp

* Complete Crew public-command workspace fixture result

* Test delegated helper follow-up through Crew advertised address

* Qualify Crew follow-up addresses through shared command admission

* Complete finite follow-up authority and lifetime evidence

* Assert exact remote authority acquisition error identity

* Consolidate Crew SQL test fixture imports

* Trim Crew read-model tests to the high-impact set

Keep the real CLI/RPC/database command paths, one regression per review-found bug, the cross-version contracts and one N vs 10N operation contract per scaling piece. Drop permutation matrices, equivalence oracles, near-duplicate scenarios and diagnostic output, and return the SSH, managed-server and WSL test files to main, since their production changes were reverted earlier in this PR.

* Drop diagnostic output and a duplicate error case from Crew tests

Remove two leftover console.log diagnostics, an unused 2x2 sample matrix and unused return fields in the follow-up cost contract, and the subscription AbortError serialization case that the subscription identity and preload tests already cover.

* Pass the recorded-leaf reader in main's check-details loader test
2026-11-01 13:28:53 -08:00
Jinjing c24d916f31 Route hosted review operations to the owning host (#36003)
* Route hosted review refreshes to their owning host

* Route remote review operations to their owning host

- Refresh the correct hosted review after remote git operations
- Scope comment mutations and AI acknowledgements to the owner cache

* Route legacy paired SSH reviews through their server owner

- Recover proxied runtime owners for older SSH worktree listings
- Preserve direct and ambiguous host routing safeguards

* Preserve review ownership across remote workspace operations

- Route checks, comments, and linked-review clears through the selected repository owner
- Reject ambiguous or mismatched host context to prevent cross-machine mutations

* Keep check detail tabs scoped to their remote owner

* Preserve remote worktree ownership across reconstructed check tabs

* Preserve direct SSH check tabs when proxy listings overlap

* Scope PR refresh ownership state and safely roll back comment mutations

- Preserve linked-review clear scopes beyond cache eviction and clean them up on expiry
- Handle failed or refused comment reactions and thread resolutions without stale optimistic UI

* Preserve remote review ownership when SSH copies overlap

* Fix review routing for overlapping remote repository hosts

- Preserve server-owned review refreshes when a direct SSH copy exists
- Fail comment mutations and refetches safely when ownership becomes invalid
- Resolve check and sidebar data through the workspace’s owning host

* Relax cache-sensitive test expectations

* Route check refreshes to runtime owners and isolate restored requests

* Scope reconstructed check detail tabs by execution owner

* Fix review refresh ownership for shared remote hosts

- Prefer explicit execution owners when matching worktrees.
- Avoid repeated tab scans when restoring check details.

* Fix hosted review polling for workspaces on multiple hosts

* test: trim redundant review ownership scenarios
2026-11-01 12:57:45 -07:00
Brennan Benson 9eb930173e Keep rich Markdown in place when focus returns from Find (#36781)
* Preserve rich Markdown viewport through bare focus returns

* Retire viewport ownership on editor remount

* Complete no-op navigation and body Tab coverage

* Keep patch metadata keys separate from dependency snapshots

* Retire the viewport before root detach callbacks

* Give the engine writer fixture its native selection

* Keep native focus navigation current in Markdown

* fix: leave smooth Markdown scrolling to native focus cancellation

* Cover focus wrapper removal and routed Markdown writers

* Type the viewport scroll spy and mark the focus-recovery wait as deliberate

* Scope Markdown viewport wheel and touch guards to the editor scroller
2026-11-01 11:46:13 -08:00
Kelvin Amoaba fcf95622a2 fix(browser): open target=_blank links in Server (streamed) pages as new tabs (#37102)
* fix(browser): open target=_blank links from streamed server pages as tabs

Headless serve pages have no renderer, so a page's new-tab request was
denied. The runtime now opens the link as a tab beside the page, in front
only for the paired client whose click or key press opened it.

* test: add the offscreen tab opener to browser manager fakes

* test(e2e): drive the blank-link check through the host client

* fix(browser): credit a link only to the client whose input opened it

A click waiting in the page's command queue keeps its client until it is
delivered, input with no paired client clears an older one, and an
unattributed link no longer moves the agent's tab.

* refactor(browser): credit link opens from the page's command queue

Record the paired client at the bridge's per-page command lease, which
sees the resolved page and every command kind, instead of in four RPC
handlers. A page without a workspace keeps denying new-tab links.

* fix(browser): credit a link to the client whose click reached the page

Credit at the guest's activating input, under the popup owner's tab, to
the command delivering it, so a watcher's scroll can't claim an agent's
link. Announce a background tab at once since bridge selection no
longer does.

* fix(browser): credit a phone's DOM-activated tap before it runs

A tap with a touch radius clicks the element through Runtime.evaluate,
which fires no guest input event, so credit the tapping client first.

* test(e2e): assert the blank-link tab through the page, not the store

* refactor(browser): simplify page-link credit and tab opening

The queue owns the page command credit instead of the agent lease, the
credit skips work while idle and shares the gesture's freshness rule,
one opener serves both link paths, and one opensPageLink marker replaces
the paired follows/leavesAgentTab flags.

* test(e2e): give the blank-link spec's timeout its reason
2026-11-01 18:40:06 +00:00
Neil af6dabd70b feat(plugins): orca plugin shot --scenario replays a check scenario; dev watch shot pendingRequests (#37090)
- shot <key|dir> --scenario <name> renders the panel in that check scenario through the check
  runner (a separate Node process on a mock host and mounted worker), sends the validated drawn
  tree to a new plugins.shotReplay, and captures it in a throwaway preview surface: no guest,
  no live host, no real storage or settings, no real worker, images as placeholders. Window
  hidden or minimized only; --act, --environment and bridged shells refused; an older host
  answers method_not_found (runtime_unsupported) rather than doing a live shot.
- dev watch's shot event carries pendingRequests.
2026-11-01 10:31:11 -08:00
guangyu-reflexioandKelvin Amoaba 5467bf3d25 fix: preview remote HTML outside registered workspaces (#36791)
* fix: preview remote HTML outside registered workspaces

* fix(terminal): keep HTML from hosts without re-grantable files in the editor

* fix(doc-preview): check outside-workspace reads by host-canonical path and page large workspace assets

* fix(doc-preview): check approved folders for workspace assets of outside documents

* test(e2e): read the preview guest without a type assertion

* test(e2e): explain the outside-workspace preview timeout

* test(doc-preview): type the pinned grant target in the share test

---------

Co-authored-by: Kelvin Amoaba <97001695+AmoabaKelvin@users.noreply.github.com>
2026-11-01 18:05:22 +00:00
Neil 5e40d652b2 refactor(persistence): import concrete owners and remove forwarding entry (#37081) 2026-11-01 09:48:22 -08:00
Neil dfbaa2fc29 Plugin shots wait for the worker and restore after --act; terminal approval prompt (#37066)
* feat(plugins): dev watch asks for first-load approval in a terminal; acronym-aware names

- In an interactive terminal without --json, a first dev watch load that needs approval shows
  the grants (as plugin inspect prints them) and asks Approve and load? [y/N]; yes reloads with
  the host's fingerprint and keeps watching. --json and non-TTY runs keep the exit-3 flow.
- create keeps known acronyms uppercase when it derives a name from the id (pr-queue → PR Queue).

* fix(plugins): a declined dev watch approval prints only the re-run command

The person just read the grants in the prompt, so the exit-3 error no longer repeats them:
Not approved. To approve later, run: <command>.

* feat(plugins): shots wait for the worker; --act restores the panel; Table and Tree acts

- A shot settles once the panel has no plugin.request or host call in flight and no new tree for
  a quiet spell (capped at 3 s), so a cold worker's skeleton is not captured; pendingRequests
  reports what was still pending.
- After --act and the capture, the guest restores every plugin-written atom it had before (new
  ui.snapshot/ui.restore; persisted atoms re-persist) and Orca remounts its drawn controls;
  restored: true|false. Worker-side effects are not rolled back.
- --act gains the kit's slide, sort, selectRows, activateRow, loadMore, expand, collapse,
  selectItem and activateItem.
- Docs: the dev watch first-load prompt; shot settle, restore and the new verbs.

* fix(plugins): a shot waits for the theme repaint and retries a bare capture

Linux CI captured a dark --theme shot as a bare background (2 colors). The renderer now waits
until the document shows the asked color scheme and paints, adds a frame after a --width
resize, and main recaptures a panel image that is still a background and a border (two colors
or fewer) up to 8 times, 150 ms apart, before returning it. Html panels keep their guest
composite.

* fix(plugins): capture the main window with stayHidden

webContents.capturePage(rect, { stayHidden: true }) keeps a hidden window rendering for the
capture, as the components gallery screenshots do. The repaint wait stays, and the bare-capture
retry stays as a fallback.
2026-11-01 09:32:38 -08:00
Neil a82538c3be refactor(runtime): organize session records and runtime modules (#37070) 2026-11-01 08:59:05 -08:00
Kelvin Amoaba d95e2324dc fix(notifications): announce finished only when the agent is fully done (#36992) 2026-11-01 16:03:29 +00:00
Kelvin Amoaba 0d724378df feat(notifications): separate agent needs-input alerts from finished alerts (#36941) 2026-11-01 15:46:46 +00:00
Neil 459745d9a4 fix(plugins): workspace.changed replays the current context on subscribe (#37044)
A panel that loaded before Orca focused a workspace showed nothing until the next change, and a
subscription made before the panel's push channel opened was never told at all. Now each new
subscriber gets the current context first: the panel bridge replays it once the channel is
open (or right away), and a worker's events.on('workspace.changed') reads it through
workspace.readContext. Unit tests for both, and the agents e2e checks the first event arrives
with no change happening.
2026-11-01 07:46:18 -08:00
Neil 1ad332d8a9 refactor(mobile): organize native chat view and transcript owners (#37054) 2026-11-01 07:38:29 -08:00
Neil 2666bbddbe Plugin dev loop: dev request, shot --act, worker-panel template, output polish (#37049)
* feat(plugins): orca plugin dev request; --template worker-panel

- orca plugin dev request <dir|key> <name> [--data] [--panel] [--timeout-ms] calls a dev
  plugin's orca.panels.handle handler through the real panel bridge (plugins.devRequest) and
  prints the answer; handler errors become plugin_request_failed with the worker's code.
- orca plugin create --template worker-panel scaffolds a build-less trusted-worker plugin: a
  components panel, src/worker.ts, a shared src/protocol.ts contract, and panel and worker tests
  that pass under orca plugin test and type-check with tsc.

* feat(plugins): shot --act, shots in the plugin folder, quieter logs

- orca plugin shot --act '<json>' presses, types, selects and toggles in the live components
  panel (the test kit's queries and acts, through Orca's own controls and onEvent) before the
  capture, waiting for each to settle. Only that plugin's panel, only with Orca's window hidden
  or minimized; html panels refused; acts are not user gestures. Results in actions[].
- shot run inside a plugin folder defaults to its .orca/shots, like dev watch --shot.
- dev watch prints identical [frame] lines once per reload with a count; logged stacks drop
  <anonymous>/native frames; the floating workspace button hides during a capture.
- Skill: worker-panel template in the decision table, dev request, shot --act, and a gotcha
  that a worker save drops its in-memory state.
2026-11-01 07:31:10 -08:00
Neil b29e7f5316 refactor: group Claude structured session owners (#37036) 2026-11-01 06:33:21 -08:00
Neil e5b87cb8e6 Components catalog 2 and worker tests: forms, tabs, table, tree, markdown, code, images (#36997)
* plugins: components catalog 2 (forms, tabs, table, tree, markdown, code, images)

Adds 18 components to TSX components panels, drawn with Orca's own
primitives and gated by ui.catalog 2 / ui.has() (Orca 1.4.247):
Textarea, Checkbox, RadioGroup, Slider, Field, Tabs/Tab, Collapsible,
Toolbar, Grid, a virtualized Table with sort, selection and pull-based
paging, a keyboard Tree with lazy children, Markdown (sanitized, links
through the checked open path), CodeView (Orca's highlighter), Image
(header-checked plugin files read by main), KeyValue, Callout and
Skeleton, plus a tooltip prop on Button and IconButton.

Value controls share the edit protocol; handlers get plain JSON event
args, including small objects ({ keys }, { key, expanded }). The test kit
gains matching actions and hides unselected tabs and closed collapsibles;
a components-gallery example and e2e cover the catalog end to end.

* plugins: worker test harness, host refusals in tests and check

- orca/testing gains mountWorker(main, { host, events, commands }): it calls
  the default-exported activate(orca) with the orca object Orca itself builds
  (createPluginWorkerOrcaApi, moved to shared so the kit reuses it), backed by
  mockHost. emit() checks payloads against Orca's event schemas and only
  delivers subscribed events; command(), request() (the worker's
  orca.panels.handle, as a panel's plugin.request), posts, logs, refusals and
  deactivate(). Storage and settings share the mock host's in-memory store.
- orca plugin test loads a worker main's module graph as Orca's worker host
  does (.ts/.mts transform, Node resolution, no runtime orca import).
- mockHost records refusals (capability_denied, not_permitted, ...) even
  when plugin code catches them; panel.refusals exposes them and
  orca plugin check reports them as warnings. Check dedupes repeated issues.
- Typings, docs and a generated references/testing.md skill reference; the
  reference generator reads the split orca typings.
2026-11-01 05:43:15 -08:00
OrcaWinandOrcaWin 70256eab83 test: remove 181 low-value tests and 2 suites (#37024)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-01 13:09:05 +00:00