Commit Graph
792 Commits
Author SHA1 Message Date
OrcaWinandOrcaWin c2e716dbbb test: remove 17 low-value wrapper and private-state suites (#41292)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-11 15:51:03 -08:00
NeilandBaeTab 823a707e72 fix(cli): align Linear CLI tables by terminal display width (#41287)
Pad Linear CLI and project-list columns using terminal display width (wide CJK/Hangul cells as 2 columns, combining marks and ZWJ sequences aligned to Orca's Unicode11 xterm provider) while preserving terminal-safe line sanitization.

Refs #11883

Co-authored-by: BaeTab <bhwoo48@gmail.com>
2026-11-11 15:38:48 -08:00
Kelvin Amoaba cab41b4075 fix(browser): tell agents when a page waits on a passkey, and let them cancel it (#41048) 2026-11-11 23:27:38 +00:00
OrcaWinandOrcaWin ce08e6b25e test: remove low-value CLI, mobile, and clipboard cases (#41273)
* test: remove low-value CLI, mobile, and clipboard cases

* test: trim unused keyboard synthesis fakes

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-11 15:16:34 -08:00
Neil 1f1158f7cb docs(orchestration): replace hardcoded worker-start agent ids with <agent> placeholder (#41279)
The orchestration skill guide and reference examples hardcoded --agent codex, leading coordinators on hosts without Codex installed to fail at agent_readiness. Replace hardcoded worker-start agent ids with <agent>, document how to pick an agent id across shared vs remote/WSL/--on execution hosts, and regenerate bundled skill guides.

Fixes #30495
2026-11-11 15:03:56 -08:00
OrcaWinandOrcaWin a9a0e8cd21 test: remove shallow catalog, browser and launch checks (#41258)
* test: remove routine native and catalog suites

* test: remove shallow browser, bridge and CLI checks

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-11 14:44:15 -08:00
Neil 1708f1caee refactor(claude-accounts): organize sign-in and profile owners (#41222) 2026-11-11 13:47:58 -08:00
OrcaWinandOrcaWin 6dd068e672 test: remove weak suites and duplicate recorder replays (#41234)
* test: remove weak suites and duplicate recorder replays

* test: satisfy recorder branch lint gate

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-11 12:00:24 -08:00
Jinwoo Hong c6467bbc53 fix(orchestration): tell the coordinator when a worker is lost (#40983)
* fix(orchestration): tell the coordinator when a worker is lost

A worker that could no longer run its task sent no mail: a failed start,
a person closing its pane, tab or chat, or a terminal gone after a restart.
Each now sends one "Worker lost without reporting" alert through the
turn-stop report, with its cause, last output and any leftover workspace.
An unexpected exit and a lost Codex app-server use the same path. An exit
or loss says the Dispatch is closed as failed and gives the retry command.
Failure text in the alert is redacted like terminal output.

The coordinator's own worker-stop stays silent, locally and on a paired
server. A finished turn is not reported when that turn's worker_done was
rejected; later turns still are. worker-read and worker-show say
"never started" for a start that never got a terminal.

* fix(orchestration): a lost worker's restart command names its Task id and suits its Task's state

- The command named the Task's label, not its id.
- Restart recovery puts the Task back to ready, which --retry-of refuses:
  the command is a plain worker-start then.
- worker-show does not call a paired server's failed worker "never
  started": its record carries no terminal details.

* test(orchestration): import the turn-stop report after main's test cleanup
2026-11-11 14:56:05 -05:00
Brennan Benson 9a10464bec Make chat wait check the chat's work state instead of reading its history every second (#41129)
* fix(cli): chat wait checks the chat's work state instead of reading its history every second

`orca chat wait` and `orca chat send --wait` polled `agentSession.history` once a second only to
learn whether the chat was still working. Each poll made the host build a transcript page, scan
every retained item twice for the running turn, and send the newest reply's full text, all
ignored by the waiter.

The host now answers `agentSession.workState` with just the facts a wait decides from (working,
a waiting question or approval, queued ids, the next queued send, the fence), and the journal's
running turn comes from its existing per-row turn index instead of a scan. The CLI polls that
read and falls back to history pages on hosts without it. The final transcript read is unchanged.

* test(cli): type the chat wait host test without assertions

* docs(cli): say what a work-state check skips, not that it does no history work

* test(cli): pin the chat wait's exact final reply and its single history read

* docs(cli): name the scan a work-state check skips

* ci: typecheck the chat wait host test with the cross-process test project
2026-11-11 10:53:57 -08:00
OrcaWinandOrcaWin 9576e55773 test: remove 1,144 low-value declarations (#41177)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-11 09:11:06 -08:00
OrcaWinandOrcaWin 5796c30c97 test: remove 161 low-value cases and 12 suites (#41151)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-11 05:16:06 -08:00
Neil e9e77a5962 refactor: organize GitLab and Linear implementation owners (#41130)
* refactor: organize GitLab and Linear implementation owners

* fix: package moved GitLab parser and consolidate owner import
2026-11-11 03:30:03 -08:00
Neil 386afed0ca refactor(persistence): organize profile state and Store domains (#41106)
* refactor(persistence): organize profile state and Store domains

* fix(test): locate relocated profile state worker fixtures
2026-11-11 02:44:06 -08:00
Jinwoo Hong 818055fcbb feat(orchestration): answer workers' permission prompts from the coordinator (#40756)
* feat(orchestration): deny a worker's permission prompt, and say when mail is held

A chat worker that stops at a permission prompt now escalates with the prompt
itself as structured data (approval id, state, worker, summary, allowed
actions). The coordinator can deny it with a reason through
`orchestration deny`; the worker carries on and gets the reason as mail.
Only a person can allow a prompt: the answer method decides "person" from
the transport, never from params. The stop report keys one escalation per
approval and sends one closing line when it is answered, and no longer tells
the coordinator that `orchestration send` answers a prompt.

`orchestration send` now warns when the delivery gate would hold the mail
right now (an open prompt, a blocked status, typed text), and says delivery
state is unknown for a worker on a paired server.

* fix(orchestration): only the desktop app counts as a person for worker approvals

A paired device can carry a remote CLI, so it is treated as an agent: it can deny with a reason but never allow.

* fix(orchestration): approval answers and held receipts follow the real gates

- A same-option answer counts as Orca's only when Orca recorded it; a retry returns the same
  receipt with no second reason mail.
- An unreadable chat is not a closed prompt: the answer refuses, and the closer keeps watching.
- A closing line tells a reason only when it went to the worker as mail.
- The terminal held receipt prints the delivery gate's own refusal; the chat one prints what the
  pointer's admission and queue gate would do (not attached, refused, or behind an open prompt).

* fix(orchestration): read the held receipt only after the mail is stored

An await before the insert let a worker settle meanwhile, so the mail could land on a settled
Dispatch after its follow-up scan. The closer also removes only the approval map it read.

* fix(orchestration): tell the coordinator not to block on a worker's permission prompt

The approval escalation now says the worker is waiting for permission, tells a chat
coordinator the user has been shown Allow/Deny (a terminal coordinator: a person must
answer it in Orca or the worker), asks it to carry on with other work and not message
the worker until the answer arrives, and offers deny only as the way out when the
prompt is holding up the task. The guide and CLI docs say the same.

* fix(orchestration): a paired coordinator without an Orca session id mails a deny reason from its Run

* feat(orchestration): answer a Claude terminal worker's permission prompt

A worker pane's PermissionRequest hook now waits for Orca's answer, so the coordinator can deny
it with a reason (the worker continues) and a person can allow it. One record per waiting hook,
keyed by Claude's prompt and tool call; it is answerable only while the hook waits and the dialog
is on screen, and anything else gets `{}` as before.

* test: annotate the fake screen instead of casting

* test: wait on the hang-up instead of sleeping

* fix(orchestration): claim a terminal answer only from what Claude shows

An answer is written only while a caught-up screen still shows the dialog
in the same process run, and claimed only once Claude shows it applied: the
hook's deny line for a deny, no other close for an allow. A Yes, a No or the
2:00 auto-block that wins the race is refused and named from the screen.

A hook that hangs up is not an answer: with the dialog still up the
coordinator is told a person must answer it in the worker's terminal.

A PermissionRequest entry the user made async stays async: it prints {}
first and never waits for a decision.

* fix(orchestration): name a terminal prompt's close from its tool_result

The screen could show an older prompt's close, so who answered is now read
from the tool_result Claude's transcript records for that tool call: Orca's
own deny text credits Orca, the user's No and the 2:00 safety-check block
name themselves, and a run names an allow. Hook events cannot say this: a
deny or a No fires no PostToolUse. The screen only says whether the dialog
is still up before a write, and a PostToolUse seen mid-answer is kept.

* fix(orchestration): read a prompt's tool_result without blocking main

The transcript read is async, reads only its tail, and skips any path that
is not a regular file, so a FIFO or device cannot stall the main process.
A closed prompt still awaiting its result gets one last read when the lead's
turn stops, so a result written late still names the close.

* feat(native-chat): answer workers' approvals from the coordinator chat

A worker's open permission prompt appears as a card at the end of its coordinator's chat, drawn
from the escalation payload as soon as it is stored. The person allows or denies it there; the
card's buttons answer the worker's own prompt over the desktop app's IPC, so only a person can
allow. Once answered, the card turns into a receipt saying who answered.

* fix(orchestration): read a terminal prompt's countdown when it is first escalated

* refactor(orchestration): give a terminal prompt's hold state its own module

* fix(native-chat): let a worker's approval card answer, and drop it once it lapses

The window's runtime calls never carried the orchestration contract
version, so the card's Allow and Deny were refused as an obsolete client.
The renderer ships with its main process, so desktop IPC states the current
contract. An open card whose agent's own countdown has passed, with no
closing message (the app restarted while it was open), is no longer shown.

* test: say why the desktop fence test's runtime stub is enough

* fix(orchestration): a chat worker's approval asks to allow its tool, like a terminal worker's

* fix(native-chat): pause the approval countdown while the window is hidden

* chore(i18n): protect the approval card's worker line copy

* fix(orchestration): close a terminal prompt's card as soon as Orca can't answer it

When the dialog leaves without an answer through Orca, the closing line is
published at once, so the coordinator's card becomes a receipt; a tool
result that arrives later adds a second line naming how it closed, without
waking the coordinator. On startup, open terminal prompts left by an earlier
run are closed the same way, since their holds lived in memory. A Claude
terminal card's reason is the warning Claude prints under the command.

* fix(orchestration): keep the dialog-warning patterns ASCII for the orcad bundle

* fix(native-chat): say when a deny reason reached the worker as a separate message

A coordinator's deny reason for a chat worker whose prompt takes no message is sent
as mail. The receipt showed it the same as a reason that went with the denial, so it
now labels it 'Reason, sent as a message'.

* chore(native-chat): follow main's moved window-activity and agent-session modules

* fix(orchestration): only Orca's own reports draw approval cards, and every card closes

- Cards and the startup sweep read approvals only from rows whose id is the stop report's own
  stable id for that approval, through one shared parser; a worker's send cannot draw a card.
- A chat worker's card closes as soon as its own chat answers it (a journal watch replaces the
  turn-edge check), when an answer finds the prompt already gone, and after a restart.
- A terminal coordinator is told nobody was shown the prompt and to tell the user; the
  terminal-only close asks the same and goes out as an escalation.
- A chat coordinator's line names only the answers its card offers; a prompt with none is a
  plain prompt with no card.
- A person's Deny on a chat worker mails no extra reason.
- A record a quit or budget end closed stays closed.
- One closed-approval builder; `waitingOn` becomes `awaitsReply`.

* fix(orchestration): a failing read cannot hang an answer, fail a stored send, or fail the database open

* refactor(orchestration): add the held-send line in send-delivery-hold, keeping send-methods under the size cap

* test(orchestration): read the worker's mail with a schema, not a cast

* fix(orchestration): an open approval stays visible and closes even behind many closed ones or a missing database
2026-11-11 04:36:35 -05:00
Jinwoo Hong d0a15d824f feat(orchestration): a worker started with --on becomes the paired computer's own worker (#40731)
* feat(orchestration): records, import and settlement for workers a paired server owns (inert until B5)

* fix(orchestration): name the re-pair when a closed link refuses a send

* feat(orchestration): offline reads of workers a paired server owns (inert until B5)

worker-show from this Orca's record when the server can't be reached, labelled
with the server and when it last reported; remote rows in worker-list named by
server; unreachable failures said in the server's terms, apart from the
server's own unknown outcome.

* fix(orchestration): remote rows share the page limit, label re-made pairings, and say what the record's time means

* fix(orchestration): keep remote rows in every page's total, date the record by state only, and retry only by request ID

* chore(orchestration): annotate the remote count query's row type

* test(orchestration): check CLI views of remote workers at the CLI layer

* docs(orchestration): say remote rows get their own page limit

* feat(orchestration): run commands about a paired server's workers there, and switch new pairs to it

* feat(orchestration): offline show and server-named failures for forwarded commands

* fix(orchestration): forwarded start timeout, receipt Run and stop key in the caller's terms

* fix(orchestration): forwarded answers name this Orca's Run

* fix(orchestration): a remote worker's question is answered only by its Run's coordinator; tests for the forwarder

* fix(orchestration): a start answered after its Run was reset says so

* fix(orchestration): refuse a chat session terminal before asking any server; test the late start after a reset

* test(orchestration): lint

* fix(orchestration): review fixes for the forwarder: retry-of stays local, legacy retries stay legacy, unknown outcomes stay fenced, refused starts leave no Task

* chore(orchestration): no type assertions in the forwarder

* fix(orchestration): a start answered after a re-pair frees its Task

* fix(orchestration): worker-show of a worker whose pairing was re-made gives this Orca's record

* fix(orchestration): a retry with --on names the server's Task instead of resending its spec

* fix(orchestration): a read about a remote worker gives up within seconds on a sleeping server

worker-show then answers from this Orca's record, as it does for a server that is off. Changes keep their longer wait.

* fix(orchestration): a refused remote start keeps the Task it created, failed

A local start that fails after creating its Task leaves it failed; deleting it here left any dependent added while the start waited pointing at nothing.

* fix(orchestration): worker-show of a remote worker reads this Orca's record, never its server

Show answers at once whether the server is awake, asleep or off, and agrees with worker-list.
Its note says when the record is from and what the pull loop last heard from the server; a
prompt wait already arrives as the server's mail. worker-read stays forwarded with its 5 s cap.

* refactor(orchestration): drop the orphaned-start lookup; the server's queue item adopts a lost start

A start whose answer was lost stays reserved until the server's dispatch-insert item names its
Dispatch, which adopts it. The 30 s dispatchShow lookup and its two placement columns repeated that.

* fix(orchestration): a stop or abandon the server does not answer settles the Task here at once

As a local stop does, the Task goes blocked so it can be retried, and the stop stays owed with its
count. The first result stands: a later state from the server changes only the attempt's record.

* fix(orchestration): task-update on this Orca's own Task applies here, by the local rule

A Task placed on a paired server is this Orca's; its update goes through the ordinary owner, which
refuses it while the worker there holds it, exactly as for a local worker. Stop first: an
unanswered stop settles the Task here at once. Nothing is forwarded to the server.

* fix(orchestration): a link that can no longer answer fails the Tasks it held, with the reason

When a re-pair closes a link, or its server is removed from this Orca, each Task a worker there
still held fails here through the ordinary Task half ("The pairing with devB was re-made. Its
worker may still run there."), and its placements go. Before, the Task stayed dispatched for good.

* fix(orchestration): a paired Orca's reads on this server are no longer narrowed to its Run

* test(orchestration): a lost start is never looked up on its server

* fix(orchestration): review fixes for the remote Task settlements

- An abandon the server does not answer stops nothing, as a local abandon: it settles the Task here
  and owes no stop, with abandon's own receipt.
- A link a re-pair or removal closes tells the Run's coordinator about each Task it failed, as a
  local worker failure does, naming the server in the reason.
- An unreleased database drops the placement lookup columns and gains task_settled_here on open.
- A failure settling a removed server's Runs no longer ends the pull loop's bookkeeping.

* fix(orchestration): retries of a remote attempt follow the local rule, and owed stops go out on reconnect

A retry here may follow the Task's attempt on a paired server once it settled there or was
abandoned here, exactly as a local retry follows a local prior; an unproven stop, like a local
stop_unknown, leaves nothing to follow yet. When a server answers again, every stop and cancel
owed to it is due at once through the existing resend, so a retry there follows the proven stop.

* fix(orchestration): a re-pair settles held Tasks at once, lists the Run there, and refuses reuse of its Tasks

- the pull loop closes links of a changed pairing, so their held Tasks fail without a call through them
- worker-list --on lists a Run's workers by its server Run even after its link closed
- a start --on of a Task placed through a closed link is refused here, naming the server
- the server's restart recovery readies its Task, and this Orca follows as the local rule does
- a closed link's note gives why it closed and the server's recorded name

* fix(orchestration): review fixes for the re-pair settlements

- worker-list picks the Run's latest link a server Run answered for, so a refused start's new link hides nothing
- a start answered after a re-pair keeps its placement, so the Task's next start there is refused here
- worker-list --on errors read in this Orca's terms, as other forwarded reads do

* fix(orchestration): a re-pair fails a Task a stop left blocked, and a reset still fails a readied Task

- a closed link also fails a held Task an unanswered stop blocked, which nothing can prove now
- a server reset's removal fails the Task even after its recovery readied the server's Task
- a closed link keeps why it closed when a later queue item cannot be read

* fix(orchestration): a re-paired Run's worker-list says so plainly, with no new read path

- worker-list --on for a Run whose link a re-pair closed names the re-pair instead of runtime_error or an empty page
- a Task placed through an earlier pairing still starts on another server

* fix(orchestration): a re-made pairing's refusals keep their own error code

server_pairing_changed passes through RPC instead of becoming runtime_error.

* fix(orchestration): a re-pair fails a blocked Task only while its stop is owed

A Task a proven stop or an abandon blocked stays blocked; only an unanswered stop, which nothing can prove now, fails it.

* fix(orchestration): a refused start writes no link, and a re-paired Run's list tells a reset apart

- the refusal of a Task an earlier pairing placed runs before any link is written, so the Run's list still names the re-pair
- worker-list decides from the Run's newest link: closed says re-paired, a reset lists nothing, a link closed mid-call says re-paired

* test(orchestration): a paired Orca reads another Run's work on this server, and still cannot change it
2026-11-11 04:25:36 -05:00
OrcaWinandOrcaWin fce98d7d21 test: remove 167 low-value cases and 93 suites (#41057)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-10 23:17:08 -08:00
Kelvin Amoaba 8afd012d69 feat(browser): move extensions out of Experimental into Settings › Browser, on by default (#40939)
* feat(browser): move extensions out of Experimental into Settings › Browser, on by default

The old experimentalBrowserExtensions key is retired on load so profiles that saved the old false default start with extensions on.

* test(startup): mock extension startup in the ready-phase identity test

Extensions now default on, so ready-phase startup installs extension support, which this browser-identity fixture's Electron and store fakes don't cover.
2026-11-11 04:25:48 +00:00
Neil 45b433671e fix(recipes): show credentials recipe scripts inherit, add opt-in passEnv allowlist (#40757)
* fix(recipes): warn which credentials recipe scripts inherit, add opt-in passEnv allowlist

Recipe lifecycle scripts run locally with Orca's full environment. Keep that
default (provider CLIs and git auth rely on it) but name the credential-like
variables in Settings and let a recipe opt into passEnv so only listed
variables plus a safe base set reach its scripts.

* fix(recipes): fail closed on a malformed passEnv instead of dropping the recipe

Dropping the recipe let a stored snapshot or a same-id plugin recipe run with
the full environment. Keep it with an empty allowlist and a diagnostic, match
base variable names exactly outside Windows, and make the warning copy apply
to any recipe source.

* fix(recipes): import user-agent-platform from its new app-shell location
2026-11-10 17:58:06 -08:00
Jinjing 5f3b2fa4bf feat(artifacts): allow artifact publishing by default for new profiles (#40948)
New profiles default artifactSharingEnabled to true. Existing users are
unchanged: stored settings win over defaults on load, and a stored profile
saved before the key existed loads as false instead of inheriting the new
default. The gate still requires an explicit true, sign-in is still
required, and web clients still mirror the host (their local fallback no
longer inherits the desktop default). showArtifactsButton is unchanged.
2026-11-10 17:28:29 -08:00
Kelvin Amoaba 9cedbae881 fix(native-chat): browser run's Show button opens its own chat's page, not another agent's (#40910)
* fix(native-chat): show the page a browser run drove, not another chat's

* fix(browser): run each queued agent command in its own RPC call

* fix(native-chat): once a chat claims its browser activity, ignore unclaimed activity
2026-11-10 23:32:57 +00:00
Kelvin AmoabaandYangNuoCheng c2e6ebbf0b feat(cli): read, message and wait on agent chats with orca chat list/read/send/wait (#40836)
* feat(cli): read and message agent chats with orca chat list/read/send

Carried over from #33115 (squashed onto current main; conflicts with chat rename resolved).

* feat(cli): wait for a chat to settle, read text from stdin, refuse paired hosts

chat send --wait and chat wait poll the history's working flag until the
chat is idle or waits on a question, keeping a queued message pending until
it runs. chat read is one history fetch and returns a cursor. Unattached
and paired-host refusals say what they mean.

* fix(cli): settle a held queued message, skip subagent rows, resolve chat list --worktree

* fix(cli): show chat errors, keep waiting through queue handoffs, return the whole settled turn

* fix(cli): settle any queued message the host will not send, show grouped questions and only answerable prompts

* test(cli): drive chat tests through a real client and fake timers

* fix(cli): describe chat --session, --wait and --state in command help

* fix(cli): report chat wait in chat list's states, reject unknown --state, flag truncated reads

* docs(cli): say chat wait settles on the chat's own turn; no truncated flag on held

* fix(cli): chat rename help asks for a session id, not a handle

---------

Co-authored-by: YangNuoCheng <42427439+YangNuoCheng@users.noreply.github.com>
2026-11-10 22:37:31 +00:00
Kelvin Amoaba 6dfb4dc60d feat(cli): add orca tab annotations so agents can read a tab's unsent notes (#40873)
Prints the notes the user left on a browser tab and has not sent, the same text the tab's Copy button gives (--json returns them). Reads the saved session, so it works for closed-and-restored tabs; SSH hosts reach it through the desktop browser bridge. A page drawn by a paired desktop reports that its notes stay there.
2026-11-10 22:02:43 +00:00
Jinwoo Hong 88880fca7a feat(orchestration): a paired Orca as a Run's coordinator on the server it placed work on (inert) (#40717)
* feat(orchestration): a paired Orca as a Run's coordinator on the server it placed work on (inert)

The server half of remote-owned workers. A paired Orca's call names one of its
Runs; the server admits it as a peer caller kind, writes that Run at frame
receipt, and holds it to the one access check. Its workers' mail and state
queue home under a sequence no reset reuses. Nothing sends the envelope until
the coordinator side ships, so this changes nothing today.

* fix(orchestration): reserve the peer address, keep conversation kinds apart, queue a correction once with its result

* fix(orchestration): hold back a corrected Task's change whatever its latest attempt; rotate pulls in a stable order per database

* chore(orchestration): typed field read, cast rationales, a wake test on fake timers

* fix(orchestration): a peer's receipts per conversation, its sends only into its Run, a page that fits every conversation, pending adopted Tasks keep their gate

* fix(orchestration): a peer's follow-up places where its worker ran

* fix(orchestration): a peer's current/new-child start gets the --on placement refusal
2026-11-10 14:56:02 -05:00
Brennan Benson fb5a8a0860 Run setup and archive scripts for folder projects (#40034)
* feat(workspaces): run setup and archive scripts for folder projects

Folder projects get the setup and archive scripts git projects have:
creating a workspace runs setup in a Setup tab, and removing one runs
archive first. The script sees the workspace's name and id, so
`orca worktree create` inside it attaches each new worktree to that
workspace, however the workspace was created.

- Folder creates (desktop IPC and runtime) prepare setup through the
  shared setup prep; runtime creates start it with the worktree terminal
  startup, so Setup-before-agent ordering matches.
- Runner files live in <folder>/.orca, one fresh file per launch, removed
  with the workspace.
- Only the host whose catalog holds the folder reads its orca.yaml or runs
  its scripts; a setup problem becomes a warning, never a failed create.
- Shared orca.yaml setup with no approval from an older client is skipped;
  ask/inherit never refuses a folder create.
- No orca.yaml default tabs for folders, since every workspace shares the
  directory.
- New capability worktree.folder-setup.v1 gates the Settings section on
  runtime hosts; the composer, Settings and trust prompt reuse the
  existing setup surfaces.

* i18n: add folder workspace hooks strings

* chore: drop the runner's sync-fs baseline and an array cast

* fix(workspaces): close review gaps in folder project setup

- Whole-project trust sends an explicit run for folder creates the
  policy would run, since it carries no content hash.
- Folder setup skips file access for a skipped setup and never starts a
  stopped WSL distro for a create nobody started; removal does the same.
- Runtime folder creates return the trust mismatch, so the window re-asks.
- The composer hides folder setup controls on hosts without
  worktree.folder-setup.v1 and keeps their old explicit skip.
- Hook checks read a folder only on the host that owns it.
- Git archive hooks get the removed workspace's id; WSL hooks blank
  inherited pane identity too.
- Runner files are written through the drive path WSL needs for its
  drive mounts, and kept out of git status with .orca/.gitignore.
- The CLI's older-host warning covers --agent creates and --json output.

* fix(workspaces): wait for the folder setup capability and read orca.yaml once

Create now waits for a runtime host's folder-setup answer instead of
sending Skip while the probe is pending, and runtime setup reuses the
parsed orca.yaml when merging effective hooks.

* fix(workspaces): keep a failed folder setup probe unknown and retry it on create

* fix(workspaces): share folder setup capability answers with the composer

* fix(workspaces): re-ask the host for folder setup support on every create

* fix(settings): read orca.yaml for folder projects and use workspace copy in hook rows

QA found Settings reporting no orca.yaml for folder projects while the
composer ran that script, and the inner hook rows still said worktree.

* fix(folder-workspaces): open one Setup tab for an instant folder create

* fix(workspaces): run setup when a created workspace has only editor tabs

* perf(folder-workspaces): per-workspace runner dir, bounded setup answers, one archive config read

* fix(folder-workspaces): retain setup capability for active consumers

* fix(folder-workspaces): match hook search to workspace descriptions

* fix(i18n): drop obsolete hook search descriptions

* test(folder-workspaces): follow relocated setup trust modules
2026-11-10 10:12:12 -08:00
Neil 9ef5e48f09 Plugins: add editor.readTypography and editor.typography.changed (#40736)
* feat(plugins): add editor.readTypography and editor.typography.changed

Plugins that render code next to Orca's editor had to open the private
profile database and reimplement Orca's font rules to match it. Host API 1.6
adds editor.readTypography (no capability; worker, panel and editor frames):
the font family and CSS stack, size with editor zoom, weight, line height in
px, ligatures, word wrap and minimap that the file editor resolves now.
editor.typography.changed carries the same values after a settings write or
an editor zoom changes them; it is the first event that needs no capability.

The pure resolution (editor typography, editor zoom, monospace font stack)
moves to src/shared so main and the renderer use one implementation.

* fix(plugins): keep editor typography resolution from throwing in main

A hand-edited profile with a non-string font family made the shared resolver
throw, which the main-process watcher would surface at startup and on every
settings write. Font values are now type-checked, the watcher catches and
logs, and it reads live settings so a write without listeners cannot leave the
event payload stale. Over-long font families are cut to the schema bound
instead of failing every read. Regenerates the testing runtime.
2026-11-10 03:38:47 -08:00
OrcaWinandOrcaWin 5ff661378b test: remove low-value markdown, agent, and pricing cases (#40566)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-09 17:20:55 -08:00
Jinwoo Hong 0bebd121b6 fix(orchestration): worker worktrees follow the project's setup setting (#40547)
worker-start defaulted --setup to run, so new worker worktrees ran the
setup script even when the project had setup turned off. Without an
explicit --setup, a worker now skips setup when the project skips it by
default; run-by-default and ask keep running it as before. Remote
workers resolve this on the host that owns the project.
2026-11-09 20:16:22 -05:00
Vyacheslav ScherbininandKelvin Amoaba 1bdadc903b fix(skills): load Orca browser guidance for ordinary web tasks (#39916)
* docs: load Orca browser guidance for ordinary web tasks

Extend the Orca CLI skill description to include local and external page opening, reading, testing, and captures while working in Orca. Preserve explicitly chosen browser tools and the Computer Use boundary. Regenerate discovery/install bytes and append the new digest.

Fixes #39880

* fix: route existing Edge windows to desktop browser control

* docs: preserve configured desktop-control tool precedence

* docs(skills): scope orca-cli browser trigger to page work and keep the Computer Use rule

Drop "reading" so doc lookups stay on fetch tools, say plain HTTP/API calls don't need the skill, and restore the original Computer Use sentence and guide body, which the issue didn't ask to change.

* docs(skills): list Edge among existing browser windows in the orca-cli guide

The wider page trigger makes "screenshot my open Edge tab" load orca-cli, and the guide named only Chrome and Safari as windows that go to desktop control.

---------

Co-authored-by: Kelvin Amoaba <97001695+AmoabaKelvin@users.noreply.github.com>
2026-11-09 23:27:58 +00:00
Jinwoo Hong bd56be7146 feat(orchestration): mail an agent on a paired server with send --on; its reply comes back by itself (#40106)
* feat(orchestration): mail agents on a paired server with send --on, replies come back by themselves

* fix(orchestration): gate --on on the carrying Orca, ack retried deliveries, refuse payloads and federated workers

* chore(orchestration): annotate peer-mail row casts and drop a wall-clock wait in its test

* chore(orchestration): name mail-between-servers codes server_mail_unsupported and mail_requires_server_pairing

* docs(cli): list --on in the orchestration reply usage

* fix(orchestration): name --environment, the flag on main, in agent mail refusals and the guide

* chore(orchestration): mark the two deliberate agent-kind branches mail between servers needs

* docs(cli): leave --on out of the reply usage; it is accepted only to refuse it

* fix(orchestration): keep peer conversations to peer ids, survive resets and re-pairs, keep pulling on a registry error

- A server takes only peerconv_ conversation ids, so a paired computer cannot name another Orca's dispatch in the relay.
- A replayed reply after a mail reset is acknowledged, not retried forever; reset tasks keeps replies waiting to be pulled.
- A re-paired server starts a new conversation instead of refusing every later send and reply.
- A failed registry read keeps the pull loop retrying.
- Drop the two ast-grep-ignore lines that only #40193's rule needed.

* fix(orchestration): worker-start --on runs on the caller's own Orca, like send --on

An inherited ORCA_ENVIRONMENT sent worker-start --on to that server, so the
--on command the agent refusal suggests did not work. One rule now keeps
send, reply and worker-start with --on on the caller's own Orca.

* fix(orchestration): refuse reply --on on both sides of a conversation between servers

The side that opened the conversation still took --on when it named the right
server; the reply usage says --on is accepted only to refuse it.
2026-11-09 17:00:11 -05:00
OrcaWinandOrcaWin cff5a151fc test: remove low-value CLI, browser and E2E checks (#40466)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-09 11:58:10 -08:00
OrcaWinandOrcaWin 0680d9753e test: remove low-value browser, CLI and budget checks (#40459)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-09 11:44:48 -08:00
OrcaWinandOrcaWin 9e128042fa test: remove low-value suites and redundant examples (#40457)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-09 11:31:20 -08:00
OrcaWinandOrcaWin 77781c71f7 test: remove low-value CLI and renderer inventories (#40445)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-09 11:14:08 -08:00
Kelvin Amoaba d291670a01 refactor(speech): remove sherpa-onnx (#39473)
transcribe-cpp is now the only on-device engine on every platform, so
the sherpa-onnx packages, their packaging (extraResources, the darwin
libonnxruntime prune, the native-variant assert and the Linux libstdc++
exemption), the sherpa recognizer in the speech process and the
per-model engine choice all go. Hotwords are written as plain terms.
2026-11-09 18:59:10 +00:00
OrcaWinandOrcaWin 85f58ec64f test: remove low-value CLI, settings and shortcut suites (#40441)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-09 10:53:47 -08:00
OrcaWinandOrcaWin fc379afda7 test: remove low-value locale, automation and settings cases (#40437)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-09 09:49:58 -08:00
Kelvin Amoaba 0b8e94aa5c feat(speech): run GGUF models on transcribe-cpp with a CPU fallback (#39326)
* feat(speech): run GGUF models on transcribe-cpp, falling back to the CPU

The speech host child can now load a second engine. A model whose files
are GGUF runs on transcribe-cpp (Metal on Apple silicon, Vulkan on
Windows and Linux, CPU otherwise); everything else stays on sherpa-onnx,
which remains the only engine on Intel Macs.

A GPU that fails to load, errors, stalls for 25 s or crashes the process
moves the dictation to a CPU-only process (TRANSCRIBE_BACKENDS=cpu) that
replays the audio the GPU had not decoded yet, so no words are lost or
repeated. A GPU that crashed or would not load is remembered per
transcribe-cpp version and OS release, and voice.speechGpu = 'off' keeps
it on the CPU.

Packaging copies transcribe-cpp, koffi and the target's native package
into resources/node_modules outside asar, fails when a target's package
is missing, and ships the MSVC runtime beside transcribe.dll on Windows.

No catalog model is GGUF yet, so nothing runs on transcribe-cpp until
the catalog change that follows.

* fix(speech): keep the speech queue running after a failed task, and drop audio frames after a discard

* fix(speech): keep the engine's file reads off the main thread's hot paths

The engine lookup and the GPU failure marker are read once per process
instead of on every dictation start and mobile catalog request, the marker
is written asynchronously, and the child reads the hotwords file with
fs/promises. The baseline moves the existing engine presence checks from
stt-worker-paths to the shared package table and adds the once-per-process
marker reads.
2026-11-09 16:37:03 +00:00
Neil f358eb6a7d Plugins: add workspace.rename and project names in workspace.list (#40197)
* feat(plugins): add workspace.rename and project names in workspace.list

Plugins that name workspaces had to read Orca's private runtime token and call
worktree.set over the runtime socket, bypassing capability consent. workspace.rename
(workspace:write, worker only, host API 1.5) does the same update as a sidebar
rename. workspace.list rows gain the project name so plugins can prefix names
without reading the runtime's repo list.

* fix(plugins): harden workspace.rename against twin folders and hidden characters

Folder renames require a unique folder id, so twins on two hosts are not both renamed,
and fail when no folder has the id. Names refuse C1, bidi and zero-width characters,
which could make a label read as another workspace's name.

* fix(plugins): workspace.rename matches a sidebar rename for folders and reports kept names

A folder rename also cancels a pending first-agent-message rename, so the automatic
title cannot replace the plugin's name. A rename Orca does not apply (during a WSL
move) is a conflict instead of a silent success. workspace.list's project is optional,
so mocks written for host API 1.4 still validate. More invisible characters are refused.
2026-11-09 00:48:33 -08:00
Neil 920a83889c refactor: move browser contracts and publication to defining owners (#40209)
* refactor: move atomic publication to its filesystem owner

* refactor: group shared browser definitions by feature

* refactor: bind proxy process and session contracts to defining owners

* refactor: consolidate direct session contract type imports

* refactor: retain atomic publication test timing under moved owner

* fix(benchmark): resolve historical tunnel framing source before loading
2026-11-09 00:45:45 -08:00
Neil 02ad6d9671 feat(cli): add orca vm env doctor to check that an environment can run agents (#40120)
* feat(cli): add orca vm env doctor to check a workspace environment

Checks required CLIs (git plus what the repo manifests imply), agent CLIs
and their sign-in, Git fetch and a dry-run push, the orca.yaml setup script
(optionally re-running it with Orca's runner), and free disk. Pass/warn/fail
with --json; checks live in src/main/environment-doctor for runtime reuse.

* fix(env-doctor): ship the doctor modules in the packaged CLI and share the check formatter

* fix(env-doctor): run Git probes in the C locale so folder detection is locale-independent
2026-11-09 00:09:00 -08:00
Jinwoo Hong 1a60595845 fix(orchestration): record orchestration as the origin of nested workers on connected servers; lead the guide with new-child (#40091)
worker-start --on <server> --worktree new-child now tells the server that
orchestration picked the parent, so the server records the child's lineage as
orchestration, as a local child is, instead of cli. Older coordinators omit the
field and keep cli. The guide now shows new-child first and new-top-level as
the no-parent choice.
2026-11-09 02:48:36 -05:00
Neil 815854777b refactor: give browser, RPC and process contracts concrete owners (#40167)
* refactor: separate execution route and child exit owners

* refactor: move browser data into defining feature owners

* refactor: give runtime RPC entry its shutdown implementation

* refactor: use defining process types and colocate host telemetry test

* docs(process-host): point piped child contract to Node owner

* docs(process-host): clarify both piped contract owners
2026-11-08 23:32:21 -08:00
Neil f36751f79f Revert "feat(cli): create workspaces on environment recipes (#40108)" (#40184)
This reverts commit 862d315575.
2026-11-08 23:10:35 -08:00
NeilandJustas Brazauskas 862d315575 feat(cli): create workspaces on environment recipes (#40108)
* feat(cli): create workspaces on environment recipes

`orca worktree create --recipe <id>` creates the workspace on a new
environment from one of the repo's environment recipes, and
`orca vm recipe list` shows which recipes it accepts.

The desktop app on the provisioning computer runs the same main-side
provisioning the composer uses (write-ahead record, per-step timeouts,
cancellation), registers the project on the environment's Orca server,
then creates (orca-worktree) or adopts (provisioned-root) the
workspace there. Named progress steps ride on long-poll keepalive
frames, so the CLI prints them to stderr; older CLIs ignore them. A
failure after the VM exists destroys it through the shared cleanup and
returns recipe_workspace_create_failed with the failed step, the
recipe failure code and whether the destroy finished. Ctrl+C aborts
the request and destroys a started environment.

Paired devices cannot start a recipe create. Hosts advertise
worktree.recipe-create.v1 only when the desktop wires the recipe
service, so orcad and older hosts are refused before anything runs.

Based on #39228 by jutaz, a port of #28439.

Co-authored-by: Justas Brazauskas <brazauskasjustas@gmail.com>

* fix(cli): report the VM outcome when connecting fails; record no cross-host parent

* fix(vm-recipes): destroy the VM when recording its environment fails; reset exitCode in CLI tests

* perf(types): keep recipe orchestration out of the runtime's type graph

---------

Co-authored-by: Justas Brazauskas <brazauskasjustas@gmail.com>
2026-11-08 22:19:52 -08:00
Neil 39902f398b refactor: bind browser and remote runtime consumers to concrete owners (#40135)
* refactor: use concrete browser and input owners

* refactor: bind remote runtime callers to concrete transport owners

* Use checked subscription mock argument types

* Type browser lease mock with its subscription contract

* refactor: bind sleeping VM status probe test to socket owner
2026-11-08 21:41:28 -08:00
OrcaWinandOrcaWin 6c3ca0ab6d test: remove 34 low-value suites and redundant cases (#40115)
* test: remove low-value ACP, CLI and simulated scroll suites

* test: remove redundant runtime, session composition and timing suites

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-08 20:10:32 -08:00
OrcaWinandOrcaWin d714d577bf test: remove 45 low-value suites and redundant cases (#40072)
* test: remove low-value synthetic and duplicated cases

* test: remove low-value IPC and renderer cases

* test: remove marginal mobile web build helper cases

* test: remove marginal browser coverage

* test: remove low-value mobile coverage

* test: remove fixture inventories and diagnostic-only cases

* test: remove low-value shared test suites and matrices

* test: remove internal-work and mock-only coverage

* test: remove prose passthrough and scan-count assertions

* test: remove low-value renderer suites and copy counters

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-08 19:50:37 -08:00
NeilandClaude 72e5893944 fix(serve): keep the crash notice across an identity reset and drop stray staged identity files (#40081)
A reset that reclaims a crashed run's lock now puts that record back on release,
without overwriting a lock another start took, so the next start still reports the
crash. Starts without a rotating marker delete leftover .next staged files (one holds
a secret key); an unreadable marker leaves them for recovery by hand.

Co-authored-by: Claude <noreply@anthropic.com>
2026-11-08 19:30:11 -08:00
Kelvin Amoaba b41ab35b72 fix(clone): let a clone use its own folder when the repo's name is taken (#40066)
Cloning always went into <parent>/<repo name>, so a same-named repository
from another owner (or any non-empty folder of that name) could not be
cloned into the same parent. Before cloning, Orca now checks the target
on the clone host. If it is taken, the clone forms show a Folder name
field with a free suggestion (<repo>-<owner>, then <repo>-2...) and clone
into that instead. RPC repo.clone and `orca project setup-clone` accept
the folder name too.
2026-11-09 03:14:06 +00:00