Commit Graph
20885 Commits
Author SHA1 Message Date
Eotel abe77d5b63 fix(activity): name a resumed session by its own title in the agents list (#41127)
The Agents list titled a thread with the tab's generated title, the first
prompt that tab saw. After `claude --resume` in a new tab, that is the
message sent after the resume, so the list kept a status note as the
thread's name while the tab and the agent row showed the session's own
name. Rank a named provider title of the pane's own session above the
generated title, as resolveTabNameSource does, and share the session
ownership check with the agent row.
2026-11-12 05:46:32 +00:00
Neil d860f32322 fix(new-workspace): keep the GitLab source steady across composer opens (#41399)
GitLab showed in the new-workspace source tabs on some opens and not others. Its availability required the app-wide preflight status to match the current host/workspace context, and opening the composer for another context invalidated it until the async glab probe returned. Remember the last known glab answer per preflight context while a fresh probe runs, and keep a chosen GitLab tab during the re-check, as Linear already does.
2026-11-12 05:45:26 +00:00
Brennan Benson e944b31538 Own chat approval observation in the installed host (#41390) 2026-11-11 21:43:25 -08:00
Kelvin Amoaba a6dd56b429 feat(workspace-cleanup): store cleanup rules in settings with per-project overrides (#41398)
Adds off-by-default workspace cleanup rules (merged, unchanged, inactive,
automation runs, orchestration workers, keep-when) to global settings and
an inherit/off/custom override on each repo. resolveWorkspaceCleanupPolicy
is the single source of truth for the coming background runner, and the
rules are exposed to paired clients through settings.get/settings.update.
No UI and no behaviour change yet.
2026-11-12 05:43:15 +00:00
buf0-bot[bot] bf181d0385 Update README downloads badge (#41401)
Co-authored-by: buf0-bot[bot] <252831055+buf0-bot[bot]@users.noreply.github.com>
2026-11-12 05:39:05 +00:00
OrcaWinandOrcaWin 86f23bbb6b test: remove low-value policy and parser samples (#41397)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-11 21:35:14 -08:00
Jinwoo Hong d4ce08f8b0 feat(cmd-j): extra sources can lead the empty list and draw in the workspace row box (#41360)
* feat(cmd-j): extra sources can lead the empty list and draw in the workspace row box

A source sets emptyQueryPlacement 'first' to sit above Recent Chats & Terminals; the default
selection stays on the first row below it. Extra rows use the workspace row box with the line
inline after the title. Public registers no sources, so nothing changes in public builds.

* refactor(cmd-j): palette rows share one row-box variant; extra rows reuse the tab title line

* fix(cmd-j): the empty query's default row follows recent tabs that arrive after mount

The deferred-query reset committed the first render's list head, before the recent-tab
snapshot existed, so Enter landed on the first workspace instead of the latest tab.

* test(cmd-j): pin the empty query's Enter default to the latest recent tab under StrictMode

Real cmdk, StrictMode render: the re-run deferred-query effect committed the first render's
head (a workspace) before the recent-tab snapshot existed. Dev builds only; production does
not re-run mount effects.
2026-11-12 00:32:48 -05:00
Jinwoo Hong 2e7e992027 feat(orchestration): let coordinators approve worker permission prompts (opt-in) (#41306)
* feat(orchestration): let coordinators approve worker permission prompts when the user turns it on

One setting on the orchestration page, off by default. When on, the
escalation offers orchestration approve and deny, both with a reason, and
the user still sees Allow/Deny: the first answer wins. A prompt the
worker's agent lets only a person approve is refused and stays with the
user. The machine running the worker enforces its own setting.

* fix(native-chat): a worker approval's receipt shows the command, not its tool input as JSON

* test(orchestration): list every worker-side case in the coordinator approval table

* chore(i18n): ship the coordinator approval setting's search keywords in the runtime catalog

* fix(orchestration): a reasonless allow keeps the person's refusal, and terminal checks no hook may approve are person-only

* fix(orchestration): address review on coordinator approvals

- A person-only chat prompt answered meanwhile reports as closed.
- A terminal allow reads Claude's warning from the screen it checks, so a
  late-painted person-only warning still refuses before the hook is used.
- The receipt keeps a chat worker's whole command.
- orchestration approve prints the reason it sent.

* fix(native-chat): read the receipt's command through a parsed shape, not Reflect

* docs(skills): drop worker permission prompt guidance; the escalation carries it
2026-11-12 00:30:27 -05:00
Kelvin Amoaba 7c83bfc2f1 fix(native-chat): send images over 5 MB to Pi 1.5.1 and newer (#41391)
Pi 1.5.1+ shrinks every image it is sent, including mid-turn ones; older Pi
sends steered images as given, so it keeps a 3.75 MiB (5 MB base64) cap.

Part of #37005
2026-11-12 05:28:46 +00:00
Brennan Benson bb53f94a23 Skip owner resolution for chats without legacy aliases (#41355) 2026-11-11 21:21:42 -08:00
Brennan Benson 042cb123aa Keep automatic Git maintenance opportunities pending (#41370) 2026-11-11 21:19:46 -08:00
Jinwoo Hong 4679867e13 fix(orchestration): label follow-up worker cards, gate remote-owned start cards on ready (#41377)
* fix(orchestration): label follow-up worker cards, gate remote-owned start cards on ready

A send that continues a finished or closed worker starts a follow-up Dispatch,
and the coordinator's chat showed it as "Started worker". The agent-start item
now carries the Dispatch it followed and whether the conversation reopened, and
the card reads "Reopened worker" or "Sent follow-up to worker".

worker-start --on a server that owns its workers wrote the card for any parsed
answer, with no agent kind. It now passes the started agent and writes the
card only once the server readied the worker, as local and attached starts do.

* test(native-chat): assert follow-up heading kind, not its copy
2026-11-12 00:19:04 -05:00
lucumaandKelvin Amoaba 2c7a82cb09 fix(computer-use): capture Wayland windows with grim (#40422)
* fix(computer-use): capture Wayland windows with grim

* fix(computer-use): skip Wayland captures of windows that are not on screen

Sway and Hyprland report windows on other workspaces at coordinates that grim
would fill with whatever is visible there. Require the one matching window to be
visible, name why a capture was skipped, check for a supported compositor before
asking for grim, and load GdkPixbuf without needing Gdk.

* fix(computer-use): keep Wayland screenshots aligned with accessibility frames

Skip the capture when the compositor window size differs from the AT-SPI window
bounds, since element frames are measured against those bounds. Treat a running
Sway or Hyprland as Wayland even when XDG_SESSION_TYPE is tty.

---------

Co-authored-by: Kelvin Amoaba <97001695+AmoabaKelvin@users.noreply.github.com>
2026-11-12 05:16:41 +00:00
Brennan BensonandWooseong Kim 938395bad0 fix(native-chat): keep branch hover beside its label (#41340)
* fix(native-chat): keep branch hover beside its label

Let composer branch controls use their content width and shrink long labels within the footer.

Co-authored-by: Wooseong Kim <innocarpe@gmail.com>

* Keep composer branch hit targets compact under width pressure

Co-authored-by: Wooseong Kim <innocarpe@gmail.com>

* Exercise full composer context at large text sizes

* Seed complete settings in the composer fixture

---------

Co-authored-by: Wooseong Kim <innocarpe@gmail.com>
2026-11-11 21:11:28 -08:00
OrcaWinandOrcaWin 9a04aa89ef test: remove 56 low-value presentation, CLI, and reload tests (#41389)
* test: remove presentation and command-selection inventories

* test: remove CLI and display projection inventories

* test: remove browser reload projection suite

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-11 21:08:44 -08:00
Brennan Benson 545b493529 feat(settings): move Remove project to a confirmed row at the bottom of Project Settings (#41020)
* feat(settings): move Remove project to a confirmed row at the bottom of Project Settings

* chore(i18n): sync protected copy keys for the remove-project dialog

* fix(settings): use primitive variants in the remove-project disclosure and dialog

* fix(settings): keep remove-project row off the per-write store path

The terminal count now lives in a dialog-only component, and the VM-recipe check is
memoized on worktree/runtime identity. Checkouts are grouped by host id, SSH labels
resolve through the setup's runtime owner, and a runtime missing from the catalog
shows as Unknown host instead of its raw id.

* fix(settings): select only the removed repos' worktree lists

Selecting the whole worktreesByRepo map re-rendered the remove-project row on every
other repo's worktree write. Also drop the orphaned terminalCount catalog keys.

* fix(settings): count remove-project terminals once on open; hide raw SSH ids

The dialog's terminal warning reads the count when Remove… is clicked instead of
subscribing, so no store write walks tabs. An SSH host with no label now shows as
Unknown host like an unlisted runtime, since generated target ids mean nothing to users.

* fix(settings): re-check terminal count before removing a project

A terminal opened from another client while the confirm dialog is up would close
without warning. Confirm now re-reads the count and, if it grew, updates the warning
and waits for a second confirm.

* test(settings): build remove-project fixture setups without a type assertion

* test(settings): cover the remove-project confirm holding for new terminals

* test(settings): drop the copy assertion from the remove-project confirm test
2026-11-11 21:06:36 -08:00
Neil e902c9a65b refactor(workspace-layout): organize concrete domain owners (#41350)
* refactor(workspace-layout): organize concrete domain owners

* test(layout): retire obsolete legacy-leaf publication setup
2026-11-11 20:54:34 -08:00
OrcaWinandOrcaWin bbe22681c2 test: remove notification, icon and native policy inventories (#41375)
* test: remove notification and native policy inventories

* test: remove icon projection samples and tray suite

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-11 20:54:07 -08:00
Kelvin Amoaba f4f332e7d5 fix(browser): open links an agent clicks behind the user's current tab (#41349) 2026-11-12 04:49:52 +00:00
Kelvin Amoaba 5bc83d98db fix(browser): stop raw exec commands from opening the system file picker (#41344) 2026-11-12 04:49:47 +00:00
Kelvin Amoaba c5e82a637d feat(mobile): show only the open tab, with a tab count and a sheet of every tab (#41345)
* feat(mobile): show only the open tab, with a tab count and a sheet of every tab

The session bar shows the open tab at full width, then a tab count cell and a + cell. The count opens a sheet of every tab grouped Needs you / Working / Everything else; tapping the tab opens its actions; swiping it steps between tabs; + opens a new tab sheet with agents as tiles. The header subtitle shows the branch. Brings back #40592 on current main.

* fix(mobile): don't switch tabs when a bar swipe is interrupted
2026-11-12 04:45:20 +00:00
Kelvin Amoaba e52823357c fix(browser): make reload report offline failures and work on pages that never loaded (#41347)
Agent reload treated did-fail-load as success, so it returned ok while the page showed a network error page; it now reports the page's load error like goto. A restored page stopped before its first commit holds only Chromium's initial empty entry, so native reload did nothing: the Reload button now navigates to the saved URL, and agent reload fails fast instead of waiting 10s and claiming success.
2026-11-12 04:38:04 +00:00
OrcaWinandOrcaWin bedb2bbaf1 test: remove low-value journal, input and capture examples (#41368)
* test: remove low-value journal and smart-key samples

* test: remove low-value journal, input and capture examples

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-11 20:32:02 -08:00
OrcaWinandOrcaWin 2d0f453776 test: remove low-value skill, host, and WSL suites (#41358)
* test: remove low-value skill and host-environment suites

* test: remove WSL notice and status mapping samples

* test: record WSL example coverage retired from broad gates

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-11 20:04:37 -08:00
Jinjing b80ac94ba4 fix(runtime): hold tui-idle until a cold-starting Claude has painted (STA-2380) (#40539)
* fix(runtime): hold tui-idle until a cold-starting Claude has painted (STA-2380)

A shell auto-title (oh-my-zsh preexec) names the pane `claude` the moment
the command execs. Claude's `idle_title` rule counts that bare name as weak
idle once output has been quiet for 3s, so a Claude that took >3s to draw
its first frame settled `terminal wait --for tui-idle` on a blank screen.
`dispatch --inject` then pasted into a TUI that had not mounted yet and the
prompt was lost.

Name-only idle lanes (agent rule verdicts that require quiet, and the
sustained-title lane) now also require that the running command has painted
something since the shell's OSC 133;C command-start marker. Shells without
the marker keep today's behavior.

* fix(runtime): corroborate Claude's name-only idle with its own composer marker (STA-2380, C1 F1)

Orca's zsh OSC 133;C hook is first in preexec_functions, so a later user or
framework preexec hook (zsh-you-should-use, a custom echo) prints after the
command-start marker and before Claude runs. The any-visible-byte paint latch
counted that text as Claude's paint, so a silent cold start under such a hook
still settled tui-idle ready-weak on the shell's bare `claude` title.

For agents whose worker start already trusts their composer marker (Claude),
"painted" now means that marker (`❯`+NBSP after DECSET 2031, which no shell
sends) arrived since the command started. Other agents keep any-byte paint;
markerless shells and output gaps keep the permissive default.

Evidence: a real-zsh live-shell test under the production wrapper with
oh-my-zsh title-only, p10k/starship-style silent, and you-should-use-style
printing hooks, replayed through the real wait; runtime tests for the hook
text, a boot banner, the positive bare-title + composer path, and worker-start
readiness plus brief delivery timing.

* fix(ci): route command-paint attribution sources to shell_contracts; attribute live-shell bytes by stream offset (STA-2380, C2 F1/F2)

- pr-shell-contract-prefixes: the live-shell test, terminal-command-paint.ts,
  tui-idle-evidence-source.ts and draft-paste-ready-scanner.ts route to the
  shell_contracts job; a routing test reads the job's step from pr.yml and
  asserts every listed test routes there.
- tui-idle-zsh-preexec-hook-order.live-shell.test: locate the DECSET 2031
  anchor by offset in the accumulated stream, split a straddling read, carry
  pending escapes across the shell/agent halves, and assert attribution is
  invariant under coalescing and 3-byte re-chunking.
- terminal-command-paint: disclose the accepted trade-off (a known Claude with
  marker history but no supported composer signal times out; markerless shells
  and output gaps still fail open; no version cutoff claimed).

* test(ci): stream-offset launch-order proof, route tui-idle-evidence.ts, parse the whole shell-contracts step (STA-2380, C3-1/2/3)

- live-shell test: assert the launch order on the joined bytes by stream
  offset (133;C, then the user hook's output, then the agent's anchor and
  composer); no read-boundary or timestamp assertions remain. Re-chunk
  cases add a split anchor and a shell-tail/agent-start coalesced read.
- pr-shell-contract-prefixes: route tui-idle-evidence.ts, the readiness
  evaluator the live-shell replay exercises.
- routing ratchet: read the step's run script through the YAML parser so
  a blank line or later command cannot truncate it; cross-check against
  the real-shell tests UNIT_EXCLUDE drops so a dropped entry fails rather
  than a smaller count; fixture tests for blank line, exact list, missing
  step.

* test(ci): answer compinit's insecure-directory prompt in the zsh preexec live-shell test (STA-2380)

Ubuntu's global zshrc runs a plain compinit, which on CI runners stops at
"Ignore insecure directories and continue [y] or abort compinit [n]?"
before zle exists, so the stand-in never launched and the shell-contracts
job failed with "no composer frame from the stand-in". Answer the prompt
with y as zsh-startup-hook-pty-harness.ts does. The prompt bytes precede
Orca's OSC 133;C marker, so stream-offset attribution is unchanged.
2026-11-11 19:57:53 -08:00
Jinjing be8f5ace6c docs(orchestration): tell workers to report effort from --effort, not reasoning_effort (#41356)
The numeric reasoning_effort a model sees is not on a 0-100 scale
(claude-opus-5-5: low=5, medium=10, high=15, xhigh=40). Workers launched
with --effort high read 15 as low and misreported their effort.
2026-11-11 19:52:08 -08:00
Brennan Benson f068737945 perf(github): skip unused enrichment for CI watches (#41332) 2026-11-11 19:49:26 -08:00
Brennan Benson 79cf868097 Capture executing stacks and machine state for hangs (#41027)
* Preserve bounded diagnostics for main-thread stalls and observer gaps

* Use a typed file-read fault injection in watchdog coverage

* Record reviewed incident-only watchdog file operations

* Clarify watchdog snapshot types and validated parser conversions

* Place validated object assertion rationale at its conversion

* Capture executing stacks after main and renderer hangs

* Preserve hang capture progress through late cleanup and reporting

* Publish renderer hang baseline before collecting stacks

* Service capture cleanup in packaged watchdog smoke

* Release native capture after dependency load failure
2026-11-11 19:48:48 -08:00
OrcaWinandOrcaWin 02209e8a33 test: remove importer, attachment, and launch projection cases (#41346)
* test: remove importer projection samples and orphan fixtures

* test: remove attachment threshold and copy examples

* test: remove dictation wiring and model-list inventory examples

* test: remove resume flag and branch formatting examples

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-11 19:42:58 -08:00
Brennan Benson 3f84308ec1 Revert orca chat list/read/send/wait (#40836) and its perf repair (#41129) (#41241)
* Revert "Make chat wait check the chat's work state instead of reading its history every second (#41129)"

This reverts commit 9a10464bec.

* Revert "feat(cli): read, message and wait on agent chats with orca chat list/read/send/wait (#40836)"

This reverts commit c2e6ebbf0b.
2026-11-11 19:36:32 -08:00
Neil 04d3074e66 fix(wsl): show Connecting instead of a stale read error while a WSL host starts (#41343)
* fix(wsl): show Connecting instead of a stale read error while a WSL host starts

After Start, a WSL host can take tens of seconds to boot and update its server. The editor,
file tree and source control dropped the stopped notice as soon as the host left 'stopped'
and showed the error from the read that failed while it was down, telling the user to go to
Settings. They now keep the notice up as 'Connecting to <distro>…', and the editor's retry
waits for the WSL host and reloads the file when it answers, as it already did for SSH.

* fix(wsl): skip the post-Start reload when the WSL retry already loaded the file

Review follow-up: once the editor's retry reloads a file when its WSL host turns ready, Start's
own reload would clear and re-read it, flashing a spinner. Start now reloads only a file that is
still failed.

* fix(wsl): reduced-motion spinner for Connecting; SSH targets keep their own retry signal

Review follow-up: the Connecting notice uses LoadingSpinner at size-4 per the style guide, and
the editor reads WSL host status only for a workspace with no SSH target.

* test(editor): cover a Start reload of a still-failed file; share reload option constants

* fix(wsl): reduced-motion spinner on the Start button too
2026-11-11 19:36:21 -08:00
Luoqiu1andKelvin Amoaba a78aada6b3 fix(native-chat): refresh skills when reopening the picker (#41023)
* fix(native-chat): refresh skills when reopening the picker

* fix(native-chat): show the last skill list while the reopened picker rechecks

Clearing the renderer snapshot on close made every / or $ open start in a
loading state. Keep the last answer per pane, show it at once on reopen, and
ask the host once per open.

* fix(native-chat): keep a late skill scan as the next open's fallback

* test(native-chat): feed skill picker tests fixed host answers

Importing the main-process scanner pulled src/main into the web typecheck
project.

---------

Co-authored-by: Kelvin Amoaba <97001695+AmoabaKelvin@users.noreply.github.com>
2026-11-12 03:28:54 +00:00
OrcaWinandOrcaWin 333febd77b test: remove narrow mobile, provider, and utility suites (#41342)
* test: remove low-value mobile classification and wiring cases

* test: remove narrow provider identity and utility suites

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-11 19:22:20 -08:00
Wooseong KimandKelvin Amoaba 437d078e18 fix(runtime): close a paired session tab when the desktop window is gone (#41159)
* fix(runtime): close a paired session tab when the desktop window is gone

Paired session-tab closes carry the device id as a navigation id, and that
path captured a renderer graph epoch before the headless retirement. A
closed window leaves the graph unavailable, so the close threw
runtime_unavailable and the phone showed nothing. Skip the epoch only while
the graph is unavailable. A reloading renderer still fails closed.

* refactor(runtime): tighten the windowless paired-close fence

* fix(runtime): keep a booting desktop renderer fenced for paired tab closes

---------

Co-authored-by: Kelvin Amoaba <97001695+AmoabaKelvin@users.noreply.github.com>
2026-11-12 03:16:46 +00:00
Kelvin Amoaba 134a7be89a fix(computer): stop macOS type-text and paste-text entering text twice (#41339)
* fix(computer): stop macOS type-text and paste-text entering text twice

Chromium answers an AX value read from a cache that trails a successful
write by about 100 ms. type-text and paste-text read the field once right
after writing, saw the old value, and typed or pasted the same text again
as keys. set-value read back the same stale value and reported that a
landed write did not take effect.

Both now wait up to 500 ms for the readback to settle, and text input
falls back to keys only when the field still holds its old value. Text
input into Chromium web content skips the AX write and sends real keys,
because the write fires no beforeinput/input events (none at all for a
contenteditable), so editors such as Discord's search never saw the text.

* fix(computer): bound the macOS value readback wait by wall clock

* docs(computer): say why text readback polls for async AX trees
2026-11-12 03:11:53 +00:00
Kelvin AmoabaandWooseong Kim 129227686b fix(editor): open a wikilink from the right half of its label (#41337)
ProseMirror resolves a click on the right half of an inline atom to the
position after it, so the rich editor's modifier-click router read the
following node. Wikilinks and superscript citation links did nothing when
clicked there. Resolve the atom the click landed on instead.

Co-authored-by: Wooseong Kim <innocarpe@gmail.com>
2026-11-12 03:06:04 +00:00
Kelvin Amoaba 7c794af26d fix(speech): commit dictation once per span, not at every pause (#41297)
Each pause cut was decoded and committed on its own, so Parakeet capitalized the word after a mid-sentence pause. Pause cuts now only update the live text.
2026-11-12 03:04:09 +00:00
OrcaWinandOrcaWin 1cc94fdfd6 test: remove low-value workspace and launch suites (#41336)
* test: remove low-value workspace and launch coverage

* test: prune removed orphan cleanup timer baseline

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-11 19:03:54 -08:00
Kelvin Amoaba a0d34074ea fix(native-chat): send Claude images over 5 MB instead of refusing the message (#41333)
Orca refused any image over 5 MiB before handing the message to Claude.
That is the Anthropic API's per-image limit, but Claude Code shrinks every
image it receives over stream-json (to 2000 px, then a ~500 KB JPEG) before
the API sees it, so the check only blocked images Claude would have sent.

The per-image cap now matches the 50 MiB attachment upload cap and the
per-message total is 64 MiB; both only bound host memory.
2026-11-12 03:03:05 +00:00
OrcaWinandOrcaWin 9f32c6d06d test: remove worker approval smoke and duplicate refusal cases (#41331)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-11 18:44:33 -08:00
Kelvin Amoaba 1d3bf2d6a9 fix(mobile): send chat with Cmd+Enter in desktop Mac browsers (#41330) 2026-11-12 02:41:44 +00:00
Neil 3d77f96eba fix(artifacts): trust orca.dev alongside onorca.dev (#41324) 2026-11-11 18:39:16 -08:00
OrcaWinandOrcaWin 7bafdc9f0f test: remove low-value browser, image, and ACP suites (#41329)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-11 18:30:07 -08:00
OrcaWinandOrcaWin 6f2e3bde15 test: remove low-value GitHub and launch-default coverage (#41326)
* test: remove low-value GitHub client projections and inventories

* test: remove launch default projection suites

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-11 18:20:23 -08:00
OrcaWinandOrcaWin e58bf50c78 test: remove query-plan and eligibility test noise (#41323)
* test: remove internal query-plan assertions

* test: remove startup sweep plan-only suite and mailbox plan observer

* test: remove terminal link grant metadata suite

* test: trim hosted review eligibility projections and probe inventories

* test: keep peer reply selection without query plan assertions

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-11 18:08:58 -08:00
Jinwoo Hong b8950a4f66 feat(orchestration): answer workers' permission prompts from the coordinator (re-land with fixes) (#41259)
* revert: worker permission approvals (#40756)

This reverts commit 818055fcbb.

The feature misbehaves in real use: an Allow on a worker's approval card
was recorded as closed without an answer, and closed approval cards render
at the bottom of the coordinator chat, below newer messages.

Removed: the Claude PermissionRequest hook hold and its 130 s timeout,
the approval card in the coordinator chat, `orchestration deny`, the
approval payload on stop escalations, and the held-delivery lines on send
receipts. Escalation text goes back to its pre-#40756 wording.

Kept from later commits:
- #40983 (lost-worker alerts): its `lost` reason, cause/leftover/settled
  fields, turnStartedAt and the rejected-report check stay; only the
  approval branches around them are removed.
- #41158 (owner moves) and the test cleanups (#41151, #41175, #41177)
  only touched approval code that is now deleted.

* feat(orchestration): answer workers' permission prompts from the coordinator (re-land of #40756)

* fix(orchestration): credit an approval from Claude's own decision record and place each worker card at its time

- An Allow that Claude took is answered by the person even when the command then fails or is still running; a failed command's PostToolUseFailure counts as ran.
- Expired means the agent's own timeout only; a close Orca can't name is not an expiry, and reasonDelivered is true only with a reason.
- Escalations wait for the dialog to paint and read Claude's warning even when a long command hides the top of its box.
- Worker cards and receipts render after the message they followed in time, not after the whole conversation; the toast says what happened.

* fix(native-chat): place timed rows without a memo the compiler skips

* perf(orchestration): feed chat approvals from their own stream, pin open cards, close cards whose worker ended

Native chats no longer subscribe to the crew stream for worker approvals. A
narrow orchestration.workerApprovalsSubscribe stream per chat party wakes only
on that party's own mail and on Run/Dispatch changes, never on agent status,
and reads the crew only when the approval list itself changes. The pane no
longer redraws for approvals: the transcript receipts and the pinned stack
each hold the feed themselves.

Open worker prompts are pinned above the composer (above the chat's own
prompt), oldest first, in a bounded scrolling stack; the transcript keeps only
receipts, at the time the worker asked. The countdown ticks only for open
cards in a visible pane.

An approval whose Dispatch is no longer running reads as closed ("No longer
open · worker ended"); a hook that hangs up after its worker is gone closes as
worker-ended rather than "answer it in the terminal"; and a click that finds
the prompt or Dispatch already gone turns the card into its receipt at once.

Also carries over: a stop owes a closing line only to an approval whose
escalation went out.

* fix(native-chat): no toast when a worker approval answer lands; the card's receipt says it

* fix(native-chat): a worker approval card answers on click, as the chat's own prompt does

The card turns into 'Allowed by you' at once and Claude's confirmation runs behind it; only an answer
Claude did not take changes it to the real outcome, and a failure reopens the card.

* fix(orchestration): keep main's stop-report index for the open-approval sweep after the re-land

* fix(orchestration): final-review fixes for chat worker approvals

- A click that gets approval_not_open no longer hides the card: the host's list decides, so a
  prompt the host still holds stays answerable. Only dispatch_inactive closes it locally.
- The approvals stream watches only the orchestration database's own changes (Runs, Dispatches,
  mail), not terminal identity notices, so agent status and title changes cost it nothing in main.
- Receipts are the chat's history: no 30-minute window, bounded by 100 rows with still-open
  prompts kept first.
- The pinned stack is capped against the pane and gives way first, so the chat's own prompt keeps
  its room; a prompt that closes while shown stays pinned as its receipt for 4 s, and one only the
  worker's terminal can answer stays pinned.
- A close no one named, after the worker's Dispatch ended, reads as worker-ended, and an
  unanswered close of an ended worker sends the coordinator no second notice.
- The transcript's receipts keep one array until a receipt changes.

* refactor(native-chat): a worker approval card waits on the host after a click instead of answering ahead of it

Both buttons turn off and the clicked one shows a spinner until the answer returns; the host's list
then turns the card into its receipt. Drops the client-side close and its reconciliation.

* fix(native-chat): let the compiler memoize the worker approval answer handler
2026-11-11 21:04:44 -05:00
Neil a0f1cb0ee2 refactor(git): group root modules by concrete domain owners (#41322)
* refactor(git): group root modules by concrete domain owners

* chore(git): reconcile retired-test metadata with owner cleanup
2026-11-11 18:02:15 -08:00
Neil a82468b023 chore(deps): safely update vetted dependencies across workspaces (#41291)
* chore(deps): safely update vetted dependencies across workspaces

* fix(deps): deduplicate rolldown to 1.2.16 for electron-vite tsc parity
2026-11-11 17:58:44 -08:00
OrcaWinandOrcaWin 252cfa3efd test: remove 34 low-value tests, including five whole suites (#41321)
* test: remove low-value startup and usage suites

* test: drop redundant form driver and lease recipes

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-11 17:40:04 -08:00
Jinwoo Hong fa89bd4356 perf(orchestration): back off idle remote relays and pull only pending peer replies (#41311)
* perf(orchestration): back off idle remote relays and pull only pending peer replies

* test(orchestration): prove idle backoff at the federation relay

* perf(orchestration): a sync another caller ran that moved mail wakes the relay

* perf(orchestration): a re-verified server keeps its relay awake

* perf(orchestration): a relay tick that moves mail keeps the relay awake
2026-11-11 20:33:55 -05:00