Commit Graph
84 Commits
Author SHA1 Message Date
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
f13a67a7c4 fix(skills): stop the orchestration stub repeating its description (#37850)
The orchestration stub body opened with a near-verbatim copy of its front
matter description plus a paragraph on why the guide lives in the binary.
Give it the one-line opening every other stub uses and keep its only unique
rule: never substitute a non-Orca subagent tool for Orca orchestration. The
description is unchanged since it drives skill routing.

Regenerated skills/orchestration/SKILL.md, the bundle manifest, bundled
sources, and the released-digest ledger (adds the new stub digest only).

Fixes #37849

Co-authored-by: Michael <mhoeykens@wattvibe.eu>
Co-authored-by: Jinwoo-H <jinwoo0825@gmail.com>
2026-11-05 17:20:22 -08:00
Kelvin Amoaba 7f885c19a6 fix(skills): rename computer use to orca-computer-use (#37659)
* fix(skills): rename computer use to orca-computer-use

* test(skills): resolve rename fixture after main cleanup
2026-11-03 21:05:37 +00:00
Neil b17d408416 Plugin dev loop: TS workers, hot reload with state, orca plugin dev watch, authoring skill (#36982)
* feat(plugins): build-less TypeScript workers

A worker's main may be .ts/.mts. The plugin host installs module.registerHooks scoped to the
plugin folder: .ts files are transpiled with the frames' sucrase options (lines kept, inline
source map, source maps on), relative imports fall back to the frames' candidate files, and a
value import of the type-only 'orca/worker' fails with a clear error. Needs engines.orca
>=1.4.246.

* feat(plugins): components panels hot reload with their state

- In dev folders a save swaps only the hidden guest: keyed memory atoms are handed to the new
  guest (ui.retain → ui.hydrate memory), dropped when an atom's version changes.
- A save that fails to load keeps the last good render and shows an inline file:line:col
  error banner; the next good save clears it. A subtle Reloaded mark follows a reload.
- Transpile and import errors carry line and column; dev worker restarts keep storage.

* feat(plugins): orca plugin dev watch

One command for the inner loop: refreshes .orca/types, dev-loads the folder, follows its frame
and worker logs (plugins.getLogs gains an optional cursor), prints reloads (optional
devChangeCount on list entries) and status changes, and unloads on Ctrl-C. --json streams
NDJSON events for agents.

* feat(skills): orca-plugin-authoring bundled skill guide

A guide for agents to build Orca plugins end to end (decision table, build-less rules, the
dev watch loop, test/check, validate, release-entry, approvals, gotchas) with references
generated from the component catalog, host API table, event schemas, manifest schema and CLI
specs, checked for drift. Fixes the components template's Reset to set(count, 0).

* feat(plugins): orca plugin dev watch --check; test kit details in the authoring skill

- --check runs orca plugin check after the load and after each reload (one at a time; saves
  made meanwhile fold into one rerun) and prints each panel's render or errors inline, as a
  `check` event with --json. Local folders only, since it runs the plugin's code here.
- The orca-plugin-authoring guide's Test and check section now documents orca plugin test and
  check from #36969 exactly (JSON results, exit codes, test placement, the orca/testing kit and
  its common mistakes), and the loop uses dev watch --check.

* refactor(plugins): move the components renderer's timing and helper constants to their own module
2026-11-01 03:32:25 -08:00
Jinwoo Hong 8138232c4f Print concise orchestration CLI output for agents, with --full for the full record (#36498)
Orchestration commands print small flat fields in text and --json by default; --full prints the previous output. Failures exit non-zero with error: <code>: <message> on stderr.
2026-10-30 23:11:56 -04:00
Jinwoo Hong a1f7f97671 Orchestration v3: coordinators end their turn and Orca wakes them (#36137)
* fix(orchestration): keep a terminal's mail from being consumed by another terminal, and let settled structured workers take further tasks

A plain orchestration check consumed the named terminal's mail whatever terminal ran it, so a
coordinator checking a worker's handle took the worker's message. A consuming check from a
terminal whose own live pane is a different terminal's is now refused; --peek and --all still read
it without consuming.

worker-start --terminal and dispatch --inject routed a structured worker (structworker_ handle) as
a terminal and failed with terminal_unsupported_for_agent_session. Any agent-session party now
takes its task as a send into its session, while a structured worker keeps the pane and process
authority its first Dispatch had.

* fix(orchestration): fence check by live terminal incl. acks; defer injecting structured workers

Review fixes for the mail fence and structured worker reuse:
- The check fence compares the caller's and the mailbox's live terminal process instead of
  recorded panes, so exited terminals keep the old behaviour and two processes sharing a
  recorded pane are told apart. It also covers --ack in every read mode. The caller lookup is
  shared with the lifecycle caller fence.
- dispatch --inject to a structured worker stays refused as before: an injected Dispatch takes
  no custody, so releasing the first Dispatch could close a session working on the second.
  worker-start --terminal reuse transfers custody and stays supported.
- worker-start decides pane-less chat authority from the resolved party and passes the session
  down, so delivery and next commands no longer re-derive it from the address spelling.
- Receipts name an agent session, not a chat.

* fix(orchestration): an exited caller's env pane names no caller

The caller lookup fell back to the env pane key whenever the env handle was not live, so an
exited terminal's pane resolved to whatever terminal now occupies it, and a tmux worker's own
check was refused. The pane fallback now applies only when the env handle is not proven exited.

* fix(terminal): keep surviving terminals streaming to main after a restart

Main now attaches every live local daemon session it adopts at startup,
not only ones a window pane or remote view is showing, and re-attaches
after a daemon endpoint drop. The attach snapshot seeds main's screen,
tail and title, and an attached-but-silent agent gets an output clock so
readiness can see it has gone quiet. Waits on a survivor main could not
attach fail at once instead of timing out.

* fix(terminal): restore only pane-less streams after endpoint loss; one attach state

- Endpoint loss re-attaches in main only sessions no renderer view reports; a pane restores its own.
- The attach hide skips views mid-attach and leaves a pane's own hidden claim alone on failure.
- One per-session stream state (attaching, attached, lost) replaces three sets and is forgotten on exit.
- Waits retry the attach before failing, including after a failed re-attach.
- The output clock starts wherever a reattach result is seeded, so pane reattaches get it too.

* refactor(terminal): attach survivors at inventory adoption only; waits on unattached survivors fail at once; one ptyId output clock

* test(e2e): scope the restart attach spec's terminal listing to the unopened workspace

* fix(terminal): narrow survivor attach: waits behave as on main, one quiet clock per generation, keep main's hidden mark on failed attach

* Teach the orchestration guide when to hand off and to end the turn after dispatch

* Rewrap a messaging reference line

* Keep the original placement default and skill trigger; keep the accuracy fixes

* Point DAG retries at --retry-of and drop the last blocking-wait instruction

* Check the served orchestration guide by its new worker heading

* Apply council review: best-effort wake, full completion rule, restored safety rules, fixed scope and settled wording

* Say when the orchestration skill applies, and prefer own subagents otherwise

* Name the polling, steering, checkout, and worker fan-out habits to avoid

* fix(orchestration): wake a coordinator whose turn ended while its program still reports working

Claude Code keeps its OSC 7501 report on working while an agent-teams
teammate is alive, even after the lead's own turn ends. The mailbox gate,
idle edges and tui-idle all read that report, so worker mail was stored and
never typed. A hook turn end newer than the program's working report now
counts as rest; hook rows re-classify the PTY so the existing idle edge
delivers. Agent Teams panes now join their claude hook rows.

* fix(orchestration): compare the lead's own turn end, not the row's receipt

A child's hook restamps the row's receivedAt while the lead's turn is still
the old one, which could mark rest under a newer program working report.
Use the lead's turn-end stamp on this runtime's clock, after the latest input.

* feat(orchestration): a consuming check marks the batch it returns as handled

* Say why watch scripts and open waits block the wake

* feat(orchestration): release settled workers automatically after a grace period

* fix(orchestration): use checked row reads for delivery cursors

* fix(orchestration): trust a live own-process turn end instead of comparing clocks

Drop programActivitySince and the turn-end clock mapping: replays and SSH
host clocks made the comparison unreliable. A Claude lead counts as at rest
under a program working report when its hook turn end is a live transition
from this pane's host and launch, past the existing input and respawn floors.

* test(orchestration): drop cast in ack no-op check

* test(orchestration): seed legacy outstanding batch for held chat nudges

* test(orchestration): built CLI check hands its batch over

* test(orchestration): annotate unchanged casts and stub the keep item in tab menu tests

* fix(orchestration): let real input, explicit release and host releases converge with automatic release

- Record worker takeover at the owning runtime when it accepts UI input, before the bytes reach the PTY.
- Run remote attachment releases through the same per-resource single-flight as local ones.
- Apply the confirmed-release home projection when host observation reports a host-side release, and carry the host deadline in fleet snapshots.
- Prove restart recovery with a file-backed database reopened by a fresh runtime.

* test(orchestration): classify the keep RPC's worker fields instead of counting methods

* fix(orchestration): checked delivery reads and observer and recovery help

* refactor(orchestration): end a check when it hands over a batch; wake rides the wait result

* fix(orchestration): refuse an automatic close after real input, join remote releases, converge the home

- An automatic close checks the terminal's last driving-input time right before closing and keeps a worker someone typed into after worker_done; typing itself does no orchestration database work.
- Remote releases share the per-resource single-flight with local release, so a home worker-release joins the host timer's close.
- Host fleet snapshots and federationShow report released and the pending deadline; the home applies the existing release projection inside its observation fence.
- Real restart tests: a file-backed database reopened by a fresh runtime releases a missed deadline once and finishes interrupted requests.

* fix(orchestration): receipt a shared wake batch on arrival and report the applied Run ack

* fix(orchestration): deliver the wake to a working coordinator; agents queue mid-turn input

The wake was typed only into a live idle pane, so a Claude lead whose program
status stayed working (teammate alive) never got it. Agents queue or steer text
typed mid-turn, so a pane takes mail when live idle or working; dialogs,
permission prompts, exited agents, unsettled panes and cold-parked Enter still
hold it. Drops the held-batch Enter deferral and the per-turn-end hook logic.

* fix(orchestration): record each remote release request before joining, publish archives only through the conditional commit

- Each remote release caller records its own request before joining a close under way, and the close decides on the current row, so an explicit release that overlaps the host timer clears the automatic deadline.
- Remote capture publishes its archive through commitWorkerTerminalArchiveForRelease, so a retain during capture leaves no stale archive for worker-read.
- Remote worker-show projects the fenced host deadline and its next action.
- The input guard lives in its own module instead of the scheduler.

* feat(orchestration): start a worker in one step; worker-start creates the coordinator's Run when none is bound

worker-start --spec now creates and binds a Run for a root coordinator with
no bound Run, through the same path run-create uses, and names the Run it
created or joined in every receipt. Workers on a Dispatch keep starting
helpers in their own Run and never get a new one. A new CLI against an older
runtime runs run-create and retries; old CLIs need no change.

* fix(orchestration): drop the older-runtime fallback; check the spec before a Run is created

The CLI fallback matched a refusal text the client decorates, could not
prove the caller was a root coordinator on an older runtime, and recovered
an inner run-create under the worker-start command. Older runtimes keep
their refusal and the guide says to run-create first there. The prompt
budget check now runs before worker-start can create a Run.

* Route report-back requests to coordinators, complete the steer command, and label the wake loop branches

* Say workers are done only when worker_done confirms, wait for helpers to settle, and let bare-shell workers exit

* Route report-back requests away from handoff and steer supervised workers through their mailbox

* docs(orchestration): teach auto-handled check, retry-request and inbox recovery in the guides

* Describe the mid-turn wake in the messaging reference

* docs(orchestration): say terminal workers are released 2 minutes after worker_done

- The guide's Completion section, the reuse recipe and the recovery reference now describe the automatic release and its autoReleaseAt deadline: reuse or worker-retain before it; explicit worker-release still works and is required for chat workers and workers without a deadline.
- The worker preamble says the terminal stays available until Orca releases it, about 2 minutes after worker_done unless retained.
- Regenerated the bundled guides.

* feat(orchestration): receipts say when to end the turn

* feat(orchestration): tell the coordinator when a worker stops without worker_done

* test+docs: worker stop reports

* fix(orchestration): judge the empty-check stop with execution-host verdicts

* test: drop casts from worker stop tests

* Say that report-back requests still mean end the turn

* Say that report-back requests still mean end the turn

* fix(orchestration): stop reports wait for children, keep their Dispatch, and relay intact

* fix(orchestration): a stop belongs to the Dispatch active when it was seen; restored stamps announce nothing

* fix(orchestration): never say to stop while a remote worker runs

* Shrink the orchestration guide to the end-state workflow

* fix(orchestration): stop reports quote the agent's last words, or the screen for errors and prompts

* fix(orchestration): withhold the stop while chat failure mail is off

* test: a clean finish quotes the agent's last words

* fix(orchestration): stop asking workers for heartbeats

Workers are no longer told to send periodic heartbeats. A heartbeat that
still arrives from an older worker or peer only records last_heartbeat_at:
it is stored already handled, so it never lands in a coordinator inbox and
never wakes a coordinator or a check --wait. Removes the stale-heartbeat
warning and the heartbeat interval plumbing that only fed the preamble.

* fix(settings): remove the worker heartbeat controls

The Worker heartbeats switch and Heartbeat interval field only changed the
worker preamble text, which no longer mentions heartbeats. Saved values are
dropped on load as retired settings.

* fix(orchestration): wake a coordinator that reports program status but never sets a title

Program status only re-classified a pane that had a title, so a titleless
agent (agy) never got a live status and the wake gate refused it.

* fix(orchestration): a new Run no longer cuts a coordinator off from its earlier Run

* test(orchestration): drop heartbeat-batch cases the handled heartbeat row removed

* fix(orchestration): redact capabilities from a stop report's quoted output

* fix(orchestration): never wake a mailbox for a heartbeat

One rule at the runtime notification entry replaces per-call-site read
checks, so mutation replay and federated control-mail import stay silent
for heartbeats too.

* Shrink the orchestration references and worker preamble to the end-state workflow

* Name the older-Orca bind refusal as worker-start prints it

* Owner-fence test: a refused foreign ack changes nothing, whatever the worker's own check already handled

* Integration: drop the duplicate consumingCheck after merging #34043 and #35293

* Integration: await the worker-start next receipt before naming its Run

* Apply review round 1: drain to zero, release without auto-release, retry after stop, Run before a DAG

* Apply review round 2: start ready DAG Tasks, block when no failure wake, replay sends by request ID

* Apply review round 3: one receipt-based wait rule for starts and wakes

* fix(orchestration): a worker stopped without reporting needs action, and stop keeps its output

worker-list projected a stop-reported attempt as live, in_progress, no action. It now
projects finished_unverified with a worker-read recovery until mail reaches the worker.
worker-stop closed the terminal before anything archived it, so release reported the
archive unavailable; stop now archives the output first.

* Revert "Owner-fence test: a refused foreign ack changes nothing, whatever the worker's own check already handled"

This reverts commit 336ff91737.

* Revert "Merge #34043 (terminal mail guard, chat worker reuse) into integration"

This reverts commit 9c01b1a06e, reversing
changes made to d4b0c6c5f7.

* Revert "Merge #33720 (restart: attach surviving terminals) into integration"

This reverts commit d4b0c6c5f7, reversing
changes made to 53f9735bfe.

* Integration: restore #35293's check-methods after removing #34043

* fix(orchestration): bound the pre-stop archive and keep it through retain

* fix(orchestration): a failed pre-stop archive never blocks the stop

* fix(orchestration): answering a question says to end the turn while the worker runs

* fix(orchestration): a settled worker whose terminal moved owes nothing

* Cut the orchestration guide to what Orca does not already enforce or explain

* Drop the terminal-send recovery the CLI already prints

* Restore a short never-do block: no polling, no terminal steering, no hand-made checkouts

* Trigger on named-agent review requests, define failure in specs, show the reuse commands

* Restore six guide rules from the cut review and drop the preamble heartbeat block

* Integration: drop the removed heartbeat interval from preamble tests

* Drop the outside-Orca wait and run-use lines; Orca's errors teach both

* Release finished chat workers like terminal workers unless the user touched them

A finished chat worker now closes ~2 min after its accepted worker_done, like a
terminal worker. Clients report a touch when a chat is on screen at rest (opened
idle, or its turn ends on screen); the owning host keeps a finished worker's
chat on that report, until its automatic release commits the archive and closes
in the same tick. Chat workers arm only while every connected client advertises
the touch capability; old clients keep today's manual release.

* Decide an automatic chat close in the session lane, recheck clients there, re-touch after reconnect

The automatic close now asks the database in the chat's session lane right before
Stop: a touch until then keeps the chat, and a client that cannot report touches
(joined during the grace or after a restart) sends it back to manual release.
Touch reports wait for a read chat, so a reconnect re-reads and reports again.

* Keep explicit chat releases eager and re-touch a desktop chat after lost contact

* Resolve a chat touch by durable worker identity, so a closing chat's hidden tab stays touchable

* Keep the mobile touch report free of route and app-state hooks: shown counts as seen

* List workerChatTouch's identity fields and the close's optional admission in their census tests

* Release a settled remote worker from the home when its host predates automatic release

* Replace Keep Worker Open with an auto-close setting, and tell agents when an older server needs a Run

The coordinator's runtime decides whether finished workers close: it gates local arming, the
settlement ack's autoRelease opt-in to a remote host, and the home deadline for older hosts.
worker-start and run-create name an older server's one-Run-per-coordinator behaviour instead
of failing or rebinding silently.

* Escalate a parent's prompt or error even while its helper is open

* Report a chat touch when a worker chat is opened while working, and on each turn edge

* Record worker takeover when the host admits a person's chat send, so mobile sends keep the worker

* End a reported worker stop when the worker resumes, not only when Dispatch mail arrives

* Recheck a chat mail notice at admission so mail a check consumed starts no turn

* Type the resumed-turn stop test's pane move directly

* Keep the stop decision in an empty check, report muted chat failures as stops, and bind a new Run only once a start passes preflight

A start or reply receipt now sends the caller to drain its mail with check instead of ending its turn, so a mid-batch answer cannot skip a later report and a replayed receipt carries no stale stop. With chat error mail off, a failed chat request still reports a plain stop through the existing stop report path. worker-start creates and binds its Run just before the Task and Dispatch, so a start refused in preflight leaves no Run behind. worker-release help no longer says chats never auto-release.

* Reuse a Run a parallel first start bound, refuse dependencies before creating a Run, and relay a paired-server worker exit home as a stop report

* Read a reported worker stop against live agent status instead of recording resume observations

A stop report is mail the coordinator reads once. Whether a worker shows as
finished now comes from its live status: a fresh working agent status (local
pane, chat session, or the execution host's fleet snapshot) outranks the
report, so nothing needs clearing on resume.

* Drop agent steps Orca already covers: start receipts say Orca wakes you, a check asks for another only when a capped batch leaves mail, workers get no mail-check or ack lines, and chat errors always report with the exact error

* Keep the home's remote auto-release deadline until the host answers, and let a retain win at the send

Claiming a due deadline postpones it instead of moving it to a releasing state, so a restart or
a failed attempt runs it again; the release send rechecks the deadline with no await before it.
A host that cannot be asked at settlement still gets the deadline, and a host upgraded since
settlement is released by the home, since it never armed its own.

* Close a finished worker automatically only if the user never opened it

Seeing a worker's terminal or chat now writes the user's Keep record (owned,
retained) on its host, at any point before its close is admitted, so a worker
seen while it worked is never armed and a pending automatic close is cancelled;
the coordinator can still release, stop or re-engage it. Desktop reports from
the on-screen attention scan for every on-screen terminal pane and chat once a
present user is on that workspace; mobile reports the tab a session opens on
and each tab switch. The weaker chat-only touch hooks are removed. A chat send
admitted after the automatic close committed its archive now keeps the chat.

* Show only live facts for a worker that reported a stop

A stop report is escalation mail that wakes the coordinator once. worker-list
and worker-show no longer project it as finished_unverified with a recovery
action, so the live-working override that cleared that label goes too.

* Report a paired-server worker's process exit home even while its ask or check --wait is still registered

* Report a seen worker until its host records the keep, including chats shown before custody and mobile auto-selections

The touch reply now says pending while a structured worker's custody row is
not yet recorded; desktop and mobile keep a subject unreported after a
failed or pending reply and retry on the next scan, snapshot or reconnect.
Mobile reports whichever terminal or chat is displayed, tapped or selected
by a snapshot, instead of only the first per workspace.

* Record a person's chat send or command takeover inside the session lane

Takeover moves from the RPC wrappers into the host's in-lane acceptance
of userSend sends, /compact and /clear, so a close queued behind an
accepted send cannot admit before the keep, including during /compact's
handover wait. Host orchestration sends never set userSend.

* Say which stop reports a deliberate wait suppresses

* Align merged tests with the shorter preamble and the fixed start hint

* Retry an unrecorded mobile worker touch when the phone reconnects

* Drop the removed worker check line from the CLI boundary test

* fix(orchestration): wake a coordinator that survived an app restart

After a restart, main typed the mail wake only into an agent whose status it
had seen live since starting, so a coordinator whose turn had already ended
never woke. At reattach, take the agent's own last hook report, which the hook
server restores from disk and from its offline spool, as that observation while
an agent still holds the surviving process.

* fix(orchestration): restore the lead's own turn, hold a restored draft, fence respawns

Read the lead agent's turn from the restored report so background work does
not hide an ended turn, keep the wake out of a composer that still holds text
typed before the restart, and drop a restore that a respawn has overtaken.

* fix(orchestration): restore a reattached status only from a current screen without a draft

The whole-screen accessor hides a model the provider still owns after attach, so a
draft there read as none. Read the screen the way wait gates do, provider image
included, and decline the restoration when it is unavailable.

* fix(orchestration): restore a reattached status without reading the screen

After a restart main has no record of typing, so the existing draft hold cannot
apply; a screen read here could miss a draft and, when slow, strand the
coordinator for good. A draft left before the restart now meets the same rule
as an abandoned one.

* fix(orchestration): let a slow foreground probe still restore a reattached status

A probe answering after the interactive two-second bound was dropped for good,
stranding the coordinator. Restoration has no caller waiting, so it takes the
real answer; the existing fences still guard application.

* test(orchestration): mark the slow foreground probe as fake-clock driven

* Report a terminal worker whose agent died while its shell lives

A killed agent sends no stop hook and its shell keeps the PTY open, so its
Dispatch stayed open and the coordinator was never woken. The shell's
command-finished already retires the PTY's launched-agent authority; the
panes it retires now go to the worker stop reporter as an 'exited' stop
(same mail and wake as a PTY exit, once per Dispatch, none once settled).

* refactor(orchestration): key mail, waits and settle checks by terminal

Reapplies #34056 on the integrated orchestration work: mail delivery, the
settle recheck and terminal waits are keyed by ptyId instead of the window
pane, deleting the pane-keyed leaf lane and the headless-only PTY lane.

Keeps #34706's delivery rule (a terminal taking input, idle or mid-turn,
gets the wake; dialogs, permission prompts and unsent drafts hold it; the
cold-park fence still defers a parked Enter) and #35274's multi-Run
coordinator mailboxes.

* fix(orchestration): keep best-effort delivery's catch; stage the remount e2e

deliverForHandle keeps the integration branch's catch: ownership resolution
still reads SQLite, and a notification queued before teardown must not throw.

The remount e2e now asserts each stage on its own (mid-turn mail before the
workspace opens, the wait across the remount, mail after it), since #34706
types mail mid-turn and the old single mail check could pass before the
remount happened.

* refactor(orchestration): settle a new terminal wait from its first reading

A wait now keeps the PTY record it resolved, and nothing runs between the
first evaluation and the waiter's registration, so the second evaluation
re-read the same evidence. Starts the poll from the first verdict instead.

Deletes the leaf wait-result builders the leaf lane left without callers,
and adds a unit test that a tui-idle wait survives its pane remounting
(the e2e cannot order the wait's registration before the remount).

* Report a dead worker agent only once its shell is proven alone

A command-finished marker alone does not prove the launched agent exited: a
nested interactive shell in a live worker emits the same marker. The exit
report now waits for the execution host's shell-alone proof and is fenced to
the Dispatch and launch seen at the marker, so a relaunch in the pane is not
reported by an older completion. It no longer hangs on launch-authority
retirement, so a nested completion that retires metadata does not stop a later
real death from being reported. The agent-exited fact feeds the same path for
shells without OSC 133.

The shell-alone report and a paired-server worker's PTY exit share one exit
entry point and key, so the Run home gets one report per process.

* fix(orchestration): resolve a terminal's mailbox across every pane that shows it

Two panes can show one PTY; ownership read only the first listed pane, so a
Run bound to the other was never woken. The mailbox terminal now carries
every pane alias and ownership, discovery and the delayed-Enter recheck
consult them all.

* Report a killed worker agent from its launch's exit receipt

The launch command now ends with a per-shell marker the shell prints once
the agent returns, however it ended. The execution host scans it before
thinning (main and daemon), checks it against the PTY's current launch and
incarnation, and reports through reportWorkerExit. A nested shell has no
receipt and a relaunch names a new one, so the shell-alone inference is gone.
A later local PTY exit reuses the same exit message id, so it settles the
Dispatch without a second report.

* Revert "Revert "Merge #33720 (restart: attach surviving terminals) into integration""

Reapplies survivor attach (72b3b79fd3, fe906ea2a2, f46777ba18) so the
#33720 merge that follows carries it; integration reverted it in 2f945fa715.
The output clock now feeds v3's terminal-keyed wait path; the leaf lane it
also fed is gone in v3.

* test(orchestration): give exit-path DB stubs the remote-attachment lookup

The paired-server exit relay now asks the Orchestration DB for an active remote
attachment on every local pty exit; partial stubs without it threw.

* Report a worker killed after a restart from its Dispatch's launch commitment

The exit receipt ID is now derived from the launch-token hash a Dispatch
persists, so a PTY reattached after restart (no launch token in memory)
accepts its receipt when the pane's active Dispatch committed that launch
in the same shell process.

* test(orchestration): stub main's session-dispatch presentation read in the stale-leaf DB

Main's projection scope now reads listSessionDispatchesForPresentation on every
projection; v3's hand-rolled stub predates it.

* test(orchestration): drop the stale-leaf stub key integration's merge now supplies

* test(orchestration): align main's new tests with integration's mid-turn mail, admitted close and nameless worktrees

Main's titleless-turn test assumed mail waits for Stop; v3 types it into a working agent.
Main dropped the --name requirement, so that preflight case now fails on the missing repo.
The evict close now forwards the session lane's admitClose.

* perf(orchestration): read the next federated release deadline through its partial index

The armed-state filter alone cannot use the non-null partial index, so every rearm walked retained federation history.

* perf(terminal): keep unviewed restart survivors to the daemon's live window

Main now attaches every surviving terminal at startup; each mirror took the full
5,000-row depth with no viewer. A survivor nobody views keeps the 1,000 rows the
daemon itself holds, and grows to full depth from those rows once a view subscribes.

* chore(orchestration): clear check:changed findings on the main merge

Format a listing statement, prune the flaky-pattern baseline, and justify or remove the
test casts the changed-code gate flags.

* Revert the unviewed-survivor mirror cap: it can lose desktop history after a restart

A capped survivor mirror is still served as complete history to desktop recovery, and a desktop pane
added after inventory never lifts the cap. Restart memory for unviewed survivors moves to a follow-up
that defers the screen model instead of truncating it.

This reverts commit 4ea934ca7f.

* Key main's new null-agent idle-wait test by terminal, as integration's waits are

* fix(orchestration): type mid-turn mail only into a recognized agent

An unrecognized terminal's working verdict may be a running program reading stdin,
so null-agent panes keep waiting for quiet before the pointer is typed.

* Remove killed-worker exit receipts from orchestration v3

The launch-bound receipt added a visible printf to every agent launch line. Owner decision: ship v3
without killed-worker detection (behaves as main does today) and revisit it later, e.g. by watching the
agent's hook-reported process.

This reverts merge b9a30b6e74.

* Stop re-arming a delivery recheck once the quiet window has passed

A refusal that outlives the quiet window (an unrecognized terminal still reading as working) is not
time-bound, so a 50 ms recheck spun forever. The next output, title or mail edge rechecks it.

* Keep retrying deliverable mail past the quiet window; gate mid-turn delivery on terminal agent identity

A refusal outliving the quiet window can wait on a hook final-frame deadline or a late foreground
recognition, neither of which emits a delivery edge, so poll slowly while that terminal still has
deliverable mail and stop once none is pending. Mid-turn delivery now asks whether the terminal agent
is recognized at all, not whether it has readiness rules, so a recognized reusable agent keeps it.

* Keep structured-agent-session.ts within the 300-line cap

* fix(orchestration): arm delivery rechecks only for actionable delivery work

The recheck predicate now counts persisted pointer reservations awaiting
recovery as well as selectable new mail, and gates every recheck (quiet
window, post-quiet, and holds) on it, using the canonical output clock.

* Check the served orchestration guide by a heading the v3 guide keeps

* test(e2e): launch the mail-pane fake under its agent CLI's name

v3 types mid-turn mail only into a recognized terminal agent, and a title alone no longer
recognizes one, so the fake runs as `node …/codex` (or cursor-agent) like an npm shim.
The hold-while-working case now models the unrecognized program that contract still holds for.

* test(e2e): align idle mail delivery spec with v3 auto-ack, mid-turn Enter and multi-Run coordinators

A consuming check now marks its batch handled (8fbb395a32), so the live
waiter's mail is pulled once returned and the held-batch case is seeded
as an older Orca leaves it. Agents queue mid-turn input (e0cb9a68d2), so
the held reminder's Enter is no longer withheld. A coordinator keeps its
earlier Run (#35274), so Run A direct mail is pointed with --run A.

* Wake a Run's coordinator through its pane when the Run's stored terminal handle belongs to the pane's previous PTY

* Make check --ack acknowledge only, so it never takes new mail

A check carrying --ack acknowledged that Delivery and then took (and,
since checks now acknowledge what they show, consumed) the next batch.
A caller that discarded the output lost that mail. --ack now returns
after acknowledging; newer mail stays unread, so the wake path still
fires and the next plain check shows it. The receipt says --ack is not
needed. Removes the ack-then-take receipts this made dead.

* Print every message body and payload in a plain orchestration check, since current hosts acknowledge the batch on read

* Keep acknowledge-then-take for check --ack --wait, and reject --ack on direct mail

A waiting caller reads what the wait takes, so --ack --wait acknowledges
and then waits for and takes the next batch, as before; --ack alone
stays acknowledge-only. Direct mail has no Delivery, so --ack there now
fails as a foreign delivery instead of consuming the mail.

* Keep a user-kept worker terminal kept when a new Dispatch reuses it, since its on-screen pane reports only once

* Tell a coordinator to check a remote worker itself when its host cannot report turn stops

* Find a Run's pane terminal for mail without re-issuing its handle mid-reload

* Keep the original ack-then-take path for check --ack --wait

Composing an ack with a second check lost the acknowledged consumer
generation and persisted subcall receipts. --ack --wait now runs the
original single-generation path unchanged; only --ack without --wait
returns after acknowledging, and direct mail still rejects --ack.

* Settle the e2e agent idle before newer mail so the mid-turn pointer cannot race the idle title

* Record a user's view of a worker terminal as user_seen so only it, not a coordinator's retain, survives reuse by a new Dispatch

* Let a worker ask, end its turn, and be woken with the answer

* Drop casts from the ask tests and the pending-question query

* Tell agents to run a plain check after acknowledging a held Delivery

--ack without --wait no longer takes newer mail, so the held-delivery
pointer now names the follow-up check for the new messages.

* Deliver Run and Dispatch mail to the pane's current PTY, issuing its handle only when none exists

* Wait for a PTY's exported handle before mail, and wake it when that handle is adopted

* Keep a cancelled ask from taking its answer, scope the asked-question stop mute to the asking turn, and end a waiting ask when its Dispatch settles

* Order the asked-question stop mute by message sequence, not same-second timestamps

* Wake a PTY's deferred mail whenever it gets a handle, by any path

* Make the headless Dispatch adoption test hold in both layout modes

* Mock the finished-worker strip states with neutral pane and chat notice fixtures

* Mock the temporary-worker strip with the owner's copy and the Allow auto-close tab menu item

* Mock chat workers with a goal-style composer strip instead of the composer notice

* Keep a worker open only by Keep open; hold its countdown while its agent works again

* Remove viewing and typing as implicit keeps on desktop and mobile

* Update the routing specs to acknowledge a held Delivery, then take with a plain check

* Show the temporary-worker strip with Keep open and its countdown, and Allow Auto-Close in tab menus

* Share the worker auto-close poll and key its read to the subject

* Re-read kept workers often so Allow Auto-Close shows its countdown promptly

* Hold auto-close through every turn, refuse stopping kept workers before anything changes, and read worker state only for known workers

* Keep a claimed close final, check the agent before claiming, refuse remote stops without a Keep open answer, and keep re-reading known workers

* Classify workerChatTouch caller fields and drop a test-only cast
2026-10-30 14:20:02 -04:00
Jinwoo Hong 4e326e2371 Show Orca publishing guidance only when the host has it on (STA-12225) (#34547) 2026-10-27 18:20:40 -04:00
Neil b35fb1ccfb fix(orchestration): route dispatched workers to the skill and stop heartbeat loops before worker_done (#34404)
The orchestration skill description only advertised coordinator work, so a
dispatched worker never loaded it and built its heartbeat loop from the
preamble alone. Neither the preamble nor the guide said to stop a background
heartbeat loop before worker_done, so the loop outlived the task.

Add worker-role triggers (heartbeats, ask, worker_done) to the description and
stub, and tell workers in the preamble and guide to restart an expired
heartbeat loop mid-task and stop it before worker_done.

Fixes #26605
2026-10-27 05:12:22 -07:00
7ac2dcc7d4 feat(cli): let agents read and update Jira tickets safely (#28592)
Expose host-owned verified Jira reads and single-attempt writes through the CLI. Preserve site ambiguity checks, old-host capability refusal, atomic label changes, and uncertainty after failed writes.

Refs #11986 and #26055.

Co-authored-by: Dan Cieslak <dcieslak19973@users.noreply.github.com>
Co-authored-by: kokbee <kok2209@gmail.com>
2026-10-14 03:03:50 -07:00
Jinwoo Hongandlifeodyssey 9af6a3d798 fix(cli): report a denied runtime connection instead of a dead Orca (#22341)
* fix(cli): report a denied runtime connection instead of a dead Orca

Inside Codex's macOS Seatbelt sandbox, connect() on the runtime socket fails
with EPERM. The CLI dropped the errno and reported "Could not connect ...
Restart Orca", appended "Orca is not running. Run 'orca open' first.", and
`orca status` answered ok:true with `starting` (its pid probe also gets EPERM).
An agent following that advice restarts a healthy app, which cannot help.

EPERM/EACCES on the metadata read or the socket/pipe connect now fails with a
CLI-local `runtime_access_denied` error: ok:false, non-zero exit,
operation/systemCode/processState:"unverifiable"/retryable:false and nextSteps
that say to re-run with escalated permissions and not restart. CODEX_SANDBOX
only picks the wording. `orca open` stops before launching.

The status pid probe is unchanged: a refused or missing socket proves the
caller reached the endpoint, so a later EPERM probe is another uid and keeps
#20098's `starting`. Missing, refused, stale-pid and timeout paths are
unchanged.

Adapted from the diagnosis and tests in #20487 (and #19605, #13583).

Co-authored-by: lifeodyssey <zhenjiazhou0127@outlook.com>

* docs(skills): tell agents runtime_access_denied means escalate, not restart

The shared CLI-resolution block told every bundled skill to run `orca open`
when a command says Orca is not running. Add the counterpart for the new
access-denied code so sandboxed agents re-run with escalated permissions
instead of launching or restarting Orca. Regenerated stubs and manifest.

* refactor(cli): classify only a denied runtime connect, with a leaner error

A denied metadata read was never observed under a sandbox, and it turned an
unreadable user-data path (the Linux launch contract's root-owned HOME) into
runtime_access_denied instead of "Orca is not running". Keep metadata reads as
on main and classify only the socket/pipe connect.

One helper now maps a socket errno to the error or null; the error data keeps
only systemCode and nextSteps. Tests drop cases already pinned by status.test.ts.

* fix(cli): give not-running advice when a denied socket belongs to a dead Orca

A crashed Orca leaves its metadata and socket file behind, and a sandbox denies
the connect with EPERM before the CLI can see ECONNREFUSED. The sandbox still
reports ESRCH for a gone pid, so a denied connect now probes the metadata pid
and falls through to the ordinary unavailable path when the pid is proven gone.
isProcessRunning moves to its own module so transport and status share it.

* refactor(cli): inline the runtime_access_denied code like other CLI error codes

---------

Co-authored-by: lifeodyssey <zhenjiazhou0127@outlook.com>
2026-09-22 22:46:17 -04:00
Jinwoo Hong 12d744f253 fix(skills): keep computer-use off filesystem and shell tasks (#21069)
* fix(skills): keep computer-use off filesystem and shell tasks

STA-7615: "On my desktop create a folder" was matching computer-use because
discovery copy said OS/window-level and neighboring skills advertised desktop UI.
Scope the trigger to visible GUI with no CLI path, and exclude files/folders/git/shell.

* fix(skills): prefer programmatic paths over computer-use

State the last-resort rule in discovery copy instead of enumerating
files/folders/git/shell. computer-use prefers shell, filesystem, git, HTTP,
CLIs, and Playwright/CDP; neighboring skills route to Computer Use only when
a visible window needs GUI control those cannot do.

* fix(skills): stop advertising computer-use from orchestration

Orchestration coordinates workers; it does not drive a GUI. Drop Computer Use
and Playwright/embedded-browser routing from its discovery description so
those tools are not pulled in from a coordination skill.

* fix(skills): drop Playwright from orca-cli discovery

orca-cli should not prescribe Playwright or CDP. Those tools may not be
installed, and page automation is not this skill's job.

* fix(skills): drop the page-only ban from computer-use discovery

Page automation is a preference, not a prohibition. If Playwright or CDP is
not available, a visible browser window is valid Computer Use. Keep the
hard split for Orca's embedded browser (`orca-cli`) only.
2026-09-16 15:43:11 -04:00
Jinwoo Hong fb322046e8 skills: rewrite and trim the seven non-orchestration guides (#19128)
* skills: rewrite the seven non-orchestration guides to one outcome-first standard

Every guide leads with Result / Done / Safe failure, states conditions instead of case lists, keeps one done bar and one autonomy envelope, and loads references at the point of use via `skills get <topic> --full`. orca-cli drops from 424 to 260 always-loaded lines with three references; orca-per-workspace-env from 794 to 397 with five.

Defects fixed in shipped guides: `emulator camera` (no such command), iOS `permissions` (backend refuses it), Android pane described as in development, `relayGracePeriodSeconds: 0` documented as immediate teardown (it is unbounded), doctor `ok: true` hiding `warn`, an SSH exemplar setting both `jumpHost` and `proxyCommand`, a provisioned-root fetch from `origin`, and the Linear unconfirmed-write rule keyed on four verbs when ten emit it.

The resolver ladder, placeholder rule, and older-binary fallback shared by every installable SKILL.md now come from one skill-stubs/_shared/cli-resolution.md fragment composed by the generator, which also bundles per-guide references into --full. New guards: every ORCA invocation and flag resolves against COMMAND_SPECS, descriptions carry no angle-bracket tokens, reference routing is checked both ways, and an always-loaded size ratchet (300 lines) that guides may leave but never join.

* skills: address review on the SSH recipe and the parity guard

- ssh-host create script: route the bootstrap ssh through the chosen jump host or proxy command, refuse both at once, use StrictHostKeyChecking=accept-new instead of a blind ssh-keyscan append, and pass gh_token/project_root/repo_url/repo_ref to the remote bash via printf %q so a quote in a value cannot break out of the command.
- per-workspace-env envelope: the step-10 workspace test the user asked for is no longer forbidden by the same paragraph.
- linear guides: name the full verb, ORCA linear list-issues.
- parity guard: a prefix reference such as ORCA linear --help or ORCA emulator --webcam now has its flags checked against every command under that prefix; only an exact path or an explicit ... was checked before.

* skills: tighten prose in the seven rewritten guides

Shorter outcome spines, one idea per sentence, no restated rationale after a rule. No rule, command, or pinned phrase changes; 47 net lines fewer across the guides and references.

* skills: route orca-cli and per-workspace-env gates through --reference

Both guides told agents to load --full at a gate because the per-reference
selector did not exist when they were written. Now that main serves
`skills get <topic> --reference references/<file>.md`, load only the
named file and keep --full as the fallback for an older CLI, matching the
orchestration kernel.

* skills: drop outcome-spine boilerplate from the CLI-wrapper guides

The Result/Done/Safe-failure preambles and Next Action closers restated
rules the body already carries. Agents stop fine without them, and for
a CLI wrapper the command surface is the guide. Keeps the one substantive
rule computer-use's Done block added (never report unverified as success)
inside Action Rules. orchestration and per-workspace-env keep theirs:
those are multi-step workflows where the done bar is load-bearing.

(cherry picked from commit 44a74baf73)

* skills: trim the guides and stubs to what agents actually need

- Drop the Result/Done/Safe-failure preambles and Next Action closers from
  the six CLI-wrapper guides; the one substantive rule (never report an
  unverified computer-use action as success) moves into Action Rules.
- Drop the 'guide may be stale, trust --help' lines: the guide is served by
  the binary that runs the commands, so it cannot be stale relative to it.
- Drop the status --json / open --json preflight from every guide; the stub
  no-guessing paragraph now says to start Orca only when a command reports
  it is not running.
- Cut the ORCA placeholder paragraph in each guide to one line that points
  back at the stub's resolution.
- Trim the orchestration, orca-cli, and computer-use descriptions to trigger
  phrases plus one line of scope.
- Remove the older-binary fallback section from every stub (and its two
  shared blocks); a binary without skills get gets one sentence.
- Remove the guide size ratchet test.

* skills: apply independent review cleanup

* skills: clarify guide loading and Linear command discovery

* skills: harden environment recipe examples

* test: complete branch rename journal doubles

* skills: clarify custom Codex launch and refresh model example

* test: deduplicate journal fix now present on main
2026-09-07 00:03:48 -04:00
Jinwoo Hong b8311d509a Revert "skills: rewrite the seven non-orchestration guides to one outcome-first standard (#18724)" (#19126)
This reverts commit 15d0f8aedf.
2026-09-06 17:01:49 -04:00
Jinwoo Hong 15d0f8aedf skills: rewrite the seven non-orchestration guides to one outcome-first standard (#18724)
<!-- orca-pr-loc -->
<!-- Programmatic LoC summary. Do not edit by hand; rewritten on every commit. -->

| | Files | Added | Deleted | Net |
| :--- | ---: | ---: | ---: | ---: |
| Test | 6 | $\color{#1a7f37}{\Huge{\mathbf{+}}}$​544 | $\color{#cf222e}{\Huge{\mathbf{−}}}$​49 | $\color{#1a7f37}{\Huge{\mathbf{+}}}$​495 |
| Prod | 36 | $\color{#1a7f37}{\Huge{\mathbf{+}}}$​1719 | $\color{#cf222e}{\Huge{\mathbf{−}}}$​1703 | $\color{#1a7f37}{\Huge{\mathbf{+}}}$​16 |

<!-- /orca-pr-loc -->

## ELI5

Orca ships eight skill guides that agents read before running the CLI. Seven of them (everything except `orchestration`, which #16904 rewrites) were command catalogs that had drifted from the binary. This PR rewrites them so an agent reads the outcome, the done bar, and the safe-failure rule first, loads reference material only at the step that needs it, and never sees a command or flag the installed CLI does not define.

## What changed

- **Seven guides rewritten** to one standard: outcome spine first (Result / Done / Safe failure), conditions instead of case lists, one done bar, one autonomy envelope, references loaded at the point of use via `skills get <topic> --full`, every runnable invocation spelled `ORCA`. `orca-cli` is 424→260 always-loaded lines with three references (browser, automations, publishing); `orca-per-workspace-env` is 794→397 with five (provider-vercel, ssh-host, docker-ssh, windows-scripts, failure-modes).
- **Defects fixed in shipped guides:** `emulator camera` (no such command), iOS `permissions` (backend refuses it), Android pane described as "in development" (shipped in June), `relayGracePeriodSeconds: 0` documented as immediate teardown (it is unbounded), doctor `ok: true` hiding `warn`, an SSH exemplar setting both `jumpHost` and `proxyCommand`, a provisioned-root fetch from `origin`, the Linear unconfirmed-write rule keyed on four verbs when ten emit it. Linear and emulator descriptions dropped embedded commands and angle-bracket placeholders (651→329, 732→404 chars).
- **Generator bundles references.** `skill-guides/<name>/references/*.md` is appended to `--full`; `skills get` help says compact by default, full with references.
- **Stubs single-authored.** The resolver ladder, placeholder rule, and older-binary fallback shared by all eight installable `SKILL.md` files come from one `skill-stubs/_shared/cli-resolution.md` fragment composed by the generator. Projections were byte-identical before the content fixes.
- **Guards:** every `ORCA <cmd>` and flag in every guide and reference resolves against `COMMAND_SPECS` (this found the camera defect); descriptions ≤1024 chars with no angle-bracket tokens; reference routing checked both directions; an always-loaded size ratchet (300 lines) that guides may leave but never join. `orchestration` (440 lines on main) is recorded as an exception until #16904 lands its kernel.

## Relationship to #16904

Split out of #16904 so that PR carries only the orchestration guide. On main, `terminal send` has no `--wait-submit` / `--retry-request` and the orchestration kernel still carries the resolver ladder and worktree-selector rule, so this branch pins `accepted: true` for handoff receipts and leaves the orchestration pins where main has them. The merge in either direction is mechanical: #16904 rebased on this becomes a one-file `orchestration.md` change plus dropping the two exceptions.

## Standard

Compound Engineering's portable skill-authoring guidance (outcome spine, conditions not cases, pinned fragile commands with an ordered hatch, references at point of use). NVIDIA SkillEvaluator Tier 1 (`schema,pii,license,quality,unicode,lint`) was run on every guide; its deterministic checks pass, its template nudges (Instructions/Examples sections, 50–150 char descriptions) do not apply to Orca's stub architecture and were not applied.

## Testing

- `pnpm typecheck:tsc:cli` clean; `check:code-quality:changed` and `check:react-doctor:changed` 0 findings
- `pnpm verify:bundled-skill-guides` and skill-bundle manifest verify clean
- vitest over `config/scripts`, `src/cli/skill-guide-cli-parity.test.ts`, `src/cli/skills.test.ts`, `src/cli/specs/skills.test.ts`, `src/cli/help.test.ts`, `src/main/skills`: 240 files / 2,019 pass
- Live smoke on the built CLI of every `skills get <topic>` and `--full`, every emulator, linear, and vm verb named in the guides, and every projection's resolver, GNOME warning, and bounded fallback (done on the #16904 branch before the split; the guide bodies are identical here except the send-receipt vocabulary noted above)

## Deferred product decisions

Merging `orca-emulator` and `orca-emulator-android` into one skill with a platform branch; collapsing `linear-tickets` to a guide alias; a `skills get --reference <name>` selector so a gate table can load one file; a fresh-agent routing eval before trimming the `orca-cli` (1,015 chars) and `orchestration` descriptions, whose quoted triggers each fixed a routing misroute.
2026-09-06 16:10:16 -04:00
Jinwoo Hong 06a607a1d7 feat(orchestration): make multi-agent workflows durable (#16904)
<!-- orca-pr-loc -->
<!-- Programmatic LoC summary. Do not edit by hand; rewritten on every commit. -->

| | Files | Added | Deleted | Net |
| :--- | ---: | ---: | ---: | ---: |
| Test | 225 | $\color{#1a7f37}{\Huge{\mathbf{+}}}$​21666 | $\color{#cf222e}{\Huge{\mathbf{−}}}$​2820 | $\color{#1a7f37}{\Huge{\mathbf{+}}}$​18846 |
| Prod | 348 | $\color{#1a7f37}{\Huge{\mathbf{+}}}$​17107 | $\color{#cf222e}{\Huge{\mathbf{−}}}$​4706 | $\color{#1a7f37}{\Huge{\mathbf{+}}}$​12401 |

<!-- /orca-pr-loc -->

## ELI5

Orca now treats orchestration like a durable control plane instead of inferring success from terminal keystrokes. Agents can tell whether a prompt was accepted or a turn started, replay an ambiguous request without sending twice, and recover coordinator mail after a crash. Completed workers can be inspected, released, or retained, and their panes no longer auto-resume as if the work were still running.

## What changed

- **Run receipts** from `run-create/use/current/show/list` are the row without routing plumbing (`home_database`, `coordinator_pane_key`) and without the duplicate `binding` object.
- **`terminal send` receipts are honest and idempotent.** `input_accepted` and `turn_started` are the only stages; `--wait-submit` observes without resending; `--retry-request <uuid>` replays the exact request against the same process incarnation. A transport timeout keeps the retry ID; only a different runtime answering strips it. Value-less or non-UUID `--retry-request` is rejected on the CLI and the SSH shim.
- **Mailbox delivery is committed before wakeup.** Pointer writes are staged in the DB before any PTY byte, replayed once after restart, and never emit a naked Enter. The watermark that parks concurrent deliveries is released with the DB reservation. Restart rescans pointer-pending and `dispatch:` mailboxes.
- **Lifecycle is a guarded transition graph** (`lifecycle-transition.ts`) with a table-driven test over every caller edge. Task reopen/overturn stays in the public contract. A PTY exit during `worker-stop` is the stop succeeding, not a failure.
- **Worker lifecycle CLI:** `worker-start` (`--spec` creates Task + attempt in one call), `worker-show`, `worker-read` (provider transcript first, bounded terminal fallback with a typed reason, local/WSL/SSH), `worker-stop`, `worker-abandon`, `worker-release`, `worker-retain`, `worker-list` (rowid-fenced pagination, fleet liveness, `attention`, literal `nextAction`).
- **Release is an explicit ownership table** (`decideWorkerTerminalRelease`): only an `owned` resource can be settled, the archive is mandatory where reachable, and an owner whose process is proven exited can always get out of `retained` via `archive_status: unavailable`. User-taken-over, external, and transferred panes stay retained.
- **Settled-worker resume fence** (folds in #17651): a settled dispatch whose pane is still open is fenced at settlement, on stop/abandon/exit, and at startup; lifted on release, retain, takeover, and pane reuse.
- **Liveness is `live` / `unverifiable` / `exited` only**, from execution-host evidence. Fleet projection reads the evidence clock, not the relay delivery clock. A host-certified exit outranks the worker's settled state. `unverifiable` never authorizes stop, abandon, retry, or release, in code or in the guide.
- **Federation:** structured reads negotiate by `method_not_found` so every shipped host keeps transcript-first output; exited remote workers are closed before being reported closed; epoch fencing holds across peer restart, downgrade, and pairing rotation; no per-second forced capability probe.
- **Schema v35:** repairs databases stamped v34 by the pre-fix branch (mailbox_handle default, index predicates), drops the write-only `lifecycle_transition_receipts` ledger and five never-read v31 identity columns.
- **Schema v36:** `dispatch:<id>` mailboxes get a real consumer generation on `dispatch_contexts` and `remote_dispatch_attachments`, bumped and fenced in the same transaction on every re-attach (manual inject, worker-start, federated attach). A stale worker whose Dispatch moved to another process now gets `consumer_fenced` instead of silently acking the new worker's Delivery. Run mailboxes already worked this way.
- **Schema v37:** `dispatch_contexts` records its creator (`creator_handle`, `creator_pane_key`), so a coordinator's context-only self-dispatch is bookkeeping rather than a nesting parent; before this, one self-dispatch made every later `worker-start` from that coordinator fail the depth cap. Pre-v37 rows keep counting (fails closed).
- **Dispatch-mailbox ownership is checked, not inferred.** A `check` from a process whose pane no longer holds the Dispatch, or whose last Attempt was abandoned/failed and moved to another terminal, gets `consumer_fenced` instead of an empty inbox that reads as "no mail yet". `--peek`/`--all` stay readable. A paneless caller still gets `stable_pane_required` with the rebind recovery.
- **Liveness certification is stricter:** a `process_exited` stage whose termination reason is `unknown` (a stop that was issued but never observed) projects `unverifiable`, not `exited`. Federated `worker-show` carries the execution host's verdict and host kind instead of a local guess. A live, ready worker with nothing pending has `nextAction: none` rather than pointing at the `worker-show` that produced it.
- **Wire:** `workerShow` keeps `dispatch.task_id` next to `taskId` for shipped CLIs. `ask --json` uses the standard `{ok, result}` envelope like every sibling verb.
- **Migration start-version detection** treats the two v32 recovery columns as versioned. Before this, every shipped database stamped below 32 resolved to the v6 floor and replayed the whole chain (the v23 backfill synthesized 68 phantom retained workers on a real v30 profile). Verified on a copy of a real 62 MB v30 profile: starts at 30, no row delta, integrity ok, 11 ms.
- **Skill guide** rewritten as a ≤200-line kernel plus seven references, to the outcome-first standard (Result / Done / Safe failure first, conditions not case lists, one done bar, references loaded at the point of use). The canonical loop uses `worker-start --spec`, names `worker-list` for completion accounting, documents `--retry-request` / `request-show` / `--wait-submit`, and requires positive evidence before any stall action. The other seven guides get the same treatment in #18724, split out so this PR stays orchestration-only.
- **`rpc/methods/orchestration-*`** (126 flat files) regrouped into `orchestration/{worker,federation,messaging,runs,gates}/`.

## Why

User reports showed the same boundary failures: false `agent_prompt_stalled` causing duplicate sends (#15180), coordinators unable to trust screen scrapes, cold-parked terminals receiving a pointer without the submit, settled workers accumulating as live tabs and auto-resuming after restart, and no way to tell a stalled worker from a working one.

## Linked issues

Fixes #15180. Fixes #17935 (orchestration skill description is 866 characters; a guard now caps every bundled skill at 1,024). Supersedes #17651 (fence folded in). Advances #16660, #16522, #14907, #13047.

## Review record

This PR was reviewed adversarially after revival: eight independent lenses (lifecycle, mailbox, send, worker, federation, transcript, complexity, live ergonomics), each required to prove findings with a failing test. That produced 16 proven blockers, all fixed with red-then-green regression tests, followed by two re-review rounds and a third fix wave that caught 3 regressions introduced by the fixes and 7 fixes that missed their target; all closed. A final pass (five lenses incl. a live built-runtime smoke, then a re-review of the fix wave) found and fixed seven more, chiefly the stale-worker mailbox steal, the self-dispatch depth wedge, and the unproven-exit certification. Three independent Codex (gpt-6-astra) passes followed: the first found nothing new, the second found and fixed 3 defects (task-status reachability, WSL-local host classification, peer-capability epoch), the third found and fixed 6 (production PTY controller never installed settled writes, ambiguous in-flight pointer failures allowed duplicate replay, SSH/relay deadlines cut off a valid `--wait-submit`, stop-vs-exit race during inspection, and two release-recovery paths for vanished or exited terminals). The full record (findings, proof tests, triage, declines with reasons) is archived outside the repo.

**Rework after the live smoke.** A first live cross-host run on the shipped adhoc build (this Mac, a paired Windows host on the same build, a paired Mac on 1.4.195, and an SSH host) found a P1: a running local worker read `unverifiable`/`missing_status` because the fleet snapshot rows lacked the terminal handle the matcher keyed on. A 59-row failure table over every bug fixed during review showed the same two classes recurring: a fact dropped in transit through optional fields, and two authorities for one fact. Two blind designs (Opus, Codex) converged on the same mechanisms, and the scoped tranches landed here with red-then-green seam tests from the real producer to the real consumer, faults injected only at the transport or hook-ingest boundary:

- **Settlement (data-loss class):** one three-valued `WriteSettlement` (`accepted | refused{reason} | unverifiable{reason, bytesHandedToTransport}`) from the SSH multiplexer through daemon client, providers, controller, to pointer staging. No boolean, no rejection-as-third-state. The two silent degrades that fabricated a handoff are deleted; a provider that cannot settle refuses before any effect. Pointer text and Enter share the contract; a partial flush is `unverifiable`, never `refused`.
- **Evidence identity (false-liveness class):** fleet agent-status evidence is a tagged union (`binding: worker | pane | unresolved{reason}`, `clock: observed | delivery`) minted once at ingest, so a hook row captured on one process incarnation can never bind to a later dispatch on the same pane. The matcher's `!worker.paneKey ||` defaults are gone. One host-scope parser replaces two.
- **Small pre-merge items:** `capability_unsupported` from an old peer is no longer relabelled `host_unavailable`; a producer census test asserts every agent-status consumer path projects a pane-only hook row as `live`.

Two ergonomics defects the second live run surfaced on a real database are fixed here too: a pre-v3 dispatch already marked `completed` projected as `outcome_unknown` / `requiresAction: true` forever (three copies of the outcome ladder disagreed on legacy rows; now one resolver, legacy `completed` reads `succeeded` with nothing to act on, legacy `failed` stays actionable on the failure), and an unscoped `worker-list` enumerated the entire database (now defaults to the Run bound to the calling terminal, `--run` overrides, and the receipt's additive `scope` field says which).

A third live round on the shipped adhoc build of `b082443e1f` (same four hosts) plus an unscripted run in the user's own prompt style (a plain Claude Code shell, `/orchestration`, three workers, zero errors, bound-Run default confirmed) found two more branch defects, fixed with red-then-green tests: a worker freshly started on a paired server projected `unverifiable`/`host_indeterminate` with `requiresAction` for ~3 minutes, including after its own `worker_done`, because the host's federation observation returned `missing_liveness_verdict` for any PTY the liveness register had not yet swept (the host now reads a connected pane it owns locally as `live`; disconnected or SSH-scoped panes stay `unverifiable`); and six pre-v3 completed rows still carried an `input` category because settling through the task-status path or `failDispatch` never closed the Dispatch's pending question threads (both paths close them now, and schema v38 closes threads already pending on settled rows). The guide's `worker-start` examples now show `--model sonnet`, since an omitted model inherits the launcher's default.

A Codex adversarial pass on the tranche diff found one real design hole (identity minted at read time instead of ingest, now closed) and two daemon settlement paths that threw instead of settling (fixed). Two `@ts-nocheck` runtime mixins on these paths were extracted into checked modules; the repo-wide `@ts-nocheck` count is unchanged at 171.

Deletions during review: ~1,900 lines (write-only ledger, unread columns, dead v1 archive path, test harnesses shipped in prod, duplicated liveness and state-machine copies, self-capability checks that were compile-time true).

## Testing

- `pnpm typecheck:tsc:node|cli|web` clean
- `pnpm run check:code-quality:changed` 0 findings; `check:react-doctor:changed` 0
- `pnpm verify:bundled-skill-guides`, `verify:skill-bundle-manifest`
- full `pnpm test` on the integrated head: 72,332 pass / 292 skipped; the only failures were three non-PR files (two zsh live-shell suites hit a node-pty spawn-helper ENOENT while a concurrent native rebuild ran, 44/44 in isolation; `release-checkout.unit.test.ts` is a known 30 s load timeout that passes in isolation on `origin/main` too).
- CI on 70b4811267 (rerun, pre-Codex): the only reds are five SSH e2e specs plus `terminal-send-agent-prompt-submit:198`, each shown failing identically on main (main's E2E workflow is red on its last 40 runs). The terminal-send spec is root-caused and fixed separately in #18707. The Windows hook-service flake (#17721) and the federation load flake did not recur.
- Skills: `pnpm exec vitest run` over the skill gate files plus `src/cli`, `config/scripts`, `src/main/skills` pass; live smoke on the built CLI of `skills get orchestration` and `--full` (7 references).
- live headless runtime (`orca-dev serve`, isolated profile): canonical loop, stop, release, archive read, retry rejection, stale-handle check, SIGKILL-and-replay all verified with receipts
- Live cross-host smoke on the shipped adhoc build of `0d465e7931` (this Mac and a paired Windows host on the build, a paired Mac left on 1.4.195, an SSH host): local, paired-new, paired-old and SSH loops all settle; running workers read `live` on every host and `exited` after release; the old peer reads `capability_unsupported` and refuses release honestly. Injected 10 s relay stall with a send in flight: delivered exactly once after recovery, zero duplicates. Every liveness field across 104 receipts is only `live` / `unverifiable` / `exited`.
- Final live cross-host smoke on the shipped adhoc build of `b082443e1f` (same hosts): every loop settles; 942 of 948 legacy completed rows read settled with `requiresAction: false` before the question-thread fix and all of them after; `worker-list` scope reads `bound` / `flag` / `all` correctly; 122 JSON receipts carry only `live` / `unverifiable` / `exited`. Unscripted prompt-style run: clean.
- Confirmation smoke on the shipped adhoc build of `2da076d4e9` (this Mac and the paired Windows host, both updated): a freshly started Windows worker reads `live` on the first fleet poll and on all 20 that follow, with no `host_indeterminate` at any point, and `exited` after release; all 948 legacy completed rows read `requiresAction: false` with `nextAction: none` after schema v38; every verdict across 60 receipts is `live` / `unverifiable` / `exited`.
- Not physically exercised: WSL hosts, the renderer notification bell (headless has no renderer), same-session fence via a real pane close (renderer-only state), restart mid-delivery on a real app (covered by e2e only).

## Notes

- Remote-wire additions are optional fields or `method_not_found`-negotiated methods; one new Electron-only IPC channel (`agentStatus:legacyWorkerTerminalResumeFence`) never crosses the wire.
- SSH contact loss remains `unverifiable`; the execution host stays authoritative.
- Intentional wire projection change: an SSH host scope with an empty `targetId` now projects host id `ssh` instead of an empty string (remote-wire-compatibility rule 3, old clients decode the same field). A fleet pane key without a terminal handle is now `unidentifiable` rather than matched by pane key alone.
- Found live but pre-existing on main, filed separately: a relay daemon-start collision during transport loss rewrites the endpoint credential and wedges the surviving relay (host needs a manual kill); `terminal create` on a reconnecting SSH host reports an opaque `No PTY provider for connection`; `terminal list` reports `orphaned:false` and `terminal close` reports `ptyKilled:true` for a pane whose relay is gone (orchestration's own projection reads `unverifiable` correctly at the same moment).
- Downgrade after this PR is not a supported path: main opens a v37 database and early-returns (its inserts still work against the v36/v37 defaulted columns), but its one-outstanding-Delivery-per-Run index is a no-op against the branch's mailbox-scoped index of the same name.
- Known follow-ups (not blockers): `worker-list` materializes every dispatch row per call; a positive "agent absent" signal distinct from PTY liveness is a product decision left open (a headless fake agent never reaches `live`, so its `nextAction` stays `inspect`); a context-only self-dispatch still lists as `role: worker` in `worker-list`; `dispatch` task-not-found / task-not-ready / inject-rejected still surface as `runtime_error`; task and inbox receipts still expose raw row columns. Deferred skill product decisions live on #18724.
2026-09-06 14:34:03 -04:00
Jinwoo Hong 3e4fd4a7af Shorten orchestration skill description under the Agent Skills 1024-char limit (#18683)
* Shorten orchestration skill description under the Agent Skills 1024-char limit

The folded description was 1038 chars, so spec-conforming installers such
as SkillStar rejected the bundled orchestration skill. Drop the two clauses
already covered elsewhere in the same description: "decomposing work across
agents" (implied by "structured multi-agent coordination") and "automation
of the browser embedded inside Orca" (restated by the locked `orca-cli`
embedded-pages sentence). Every routing trigger asserted by
orchestration-skill-guidance.test.mjs, the orca-cli handoff boundary, and
the Computer Use boundary are unchanged. Result: 958 chars.

Add config/scripts/skill-description-length.test.mjs, which parses every
skills/*/SKILL.md frontmatter with `yaml` and fails on an empty or >1024
char description, so the regression cannot return. orca-cli sits at 1015
and is left as is.

Fixes #17935

* Keep the embedded browser in the orchestration description's orca-cli routing

Restores the word "browser" in the orca-cli sentence ("and the Orca embedded
browser") so agents scanning for it still route embedded-browser control to
orca-cli. Description is 985 chars, 39 under the spec limit.
2026-09-04 14:27:07 -04:00
Jinwoo Hong b44ef1e59d fix(skills): narrow computer-use discovery boundary (#17736)
* fix(skills): narrow computer-use discovery boundary

* chore: remove merge-formatting noise

* fix(skills): name browser page automation surfaces
2026-08-31 18:57:52 -04:00
Jinwoo Hong fa9b20cb41 feat(skills): reland private bundle sharing safely (#14934) 2026-08-16 13:45:54 -07:00
Jinjing 763b1febeb Revert "feat(skills): add private bundle sharing (#14401)" (#14913)
This reverts commit 757fae28d7.
2026-08-16 10:39:57 -07:00
Jinwoo HongandE2E Test 757fae28d7 feat(skills): add private bundle sharing (#14401)
Co-authored-by: E2E Test <e2e@test.local>
2026-08-16 02:36:18 -07:00
Jinwoo Hong c991bb27d3 Add account-backed artifact sharing (#13012) 2026-08-07 23:02:29 -07:00
Brennan Benson 1a9e819c40 feat(skills): land remaining hybrid stubs (#9846)
* feat(skills): land remaining hybrid stubs

* fix(build): exclude skill stub sources from packages
2026-07-22 11:43:01 -07:00
Brennan Benson a10a2ba53c feat(linear): add MCP-style save issue (#9670)
* feat(linear): add MCP-style save issue

* fix(linear): harden save issue parity

* fix(linear): close save issue contract gaps

* docs(linear): bundle project discovery with save issue
2026-07-21 13:25:22 -07:00
Brennan Benson 87af1c8673 feat(linear): add complete issue relations (#9674)
* feat(linear): add complete issue relations

* fix(linear): harden relation reads and writes

* fix(linear): classify ambiguous relation writes
2026-07-21 13:21:19 -07:00
Brennan Benson 42a4f017b4 feat(linear): add MCP-compatible issue listing (#9672) 2026-07-21 13:16:44 -07:00
Brennan Benson be066fe8e9 feat(linear): expose issue activity history (#9667) 2026-07-21 13:13:05 -07:00
Brennan Benson f8b430f725 feat(skills): ship orca-cli as a first-generation hybrid stub (#9238)
* feat(skills): ship orca-cli as a first-generation hybrid stub

Convert the installable orca-cli SKILL.md from a full fat guide into a
hybrid discovery stub: a safe CLI resolver, an `orca skills get orca-cli`
pointer, and a bounded read-only fallback for pre-guide binaries. The
version-matched command reference now lives only in the Orca binary
(embedded guide table, served by `orca skills get`), so the distributed
file can no longer drift from the binary that runs the commands.

- generator projects STUB_TOPICS from skill-stubs/<name>.md, reusing the
  guide's own frontmatter so the routing/description surface is unchanged;
  the embedded full guide (bundled-skill-guides.ts) is untouched.
- manifest regenerated: orca-cli releaseRevision 32->33 as an append-only
  snapshot; existing fat installs classify `outdated` and get the targeted
  `npx skills update` nudge (no in-app writes).
- tests: command-guidance assertions repointed to the guide source (their
  home now), plus stub-projection + safety coverage.

Only orca-cli converts; the other skills stay fat. Per
notes/skill-freshness-design.md, the E.3 pointer-compliance spike and the
E.5 RC window remain before any further thinning. allowed-tools is
intentionally not added yet (frontmatter kept byte-identical to the guide).

* fix(skills): distinguish guide lookup failures

* chore(skills): refresh released skill mapping
2026-07-20 13:13:21 -07:00
Jinjing a6df23c762 Tighten orchestration worktree isolation policy (#9482)
* docs(orchestration): require true isolation for worker worktrees

* docs(orchestration): deduplicate parallel worker guidance

* docs(orchestration): clarify isolation exceptions

* docs(orchestration): clarify checkout preference

* Tighten orchestration worktree isolation policy guidance

- Clarify that same-worktree workers remain orchestration children
  despite appearing as peers in the sidebar
- Define new-worktree creation as required only for explicit requests
  or concrete filesystem/checkout conflicts, not convenience
- Distinguish stacked worktrees from independent ones via --no-parent
- Rename agent-first guidance to reflect conditional requirement

* Release orchestration skill v25 with tightened worktree policy
2026-07-19 17:17:40 -07:00
Brennan Benson 31f643ca42 Add version-matched skill guides to the CLI (#8624)
* Add version-matched bundled skill guides

* Clarify skill freshness rollout PRs

* Add canonical skills show alias

* fix(skills): address guide review feedback

* fix(skills): make guide commands cross-platform

* fix(skills): apply the ORCA convention to the emulator guides

Review follow-up: the emulator guides still instructed literal
`orca emulator ...` in sh fences with no Linux disambiguation, so on
unmanaged Linux they could launch the GNOME screen reader — the exact
failure the executable-selection preamble prevents. Both emulator
guides now carry the preamble and ORCA placeholder across fences,
tables, and prose, and the cross-platform safety test covers all four
converted guides. Also replaces computer-use's "unless a block names a
shell" carve-out, which contradicted its own POSIX example, with the
unconditional placeholder rule.
2026-07-14 02:17:55 -07:00
nikg24andnikg24 67cd462b24 Add Cursor orchestration group routing (#8436)
Co-authored-by: nikg24 <228026988+nikg24@users.noreply.github.com>
2026-07-12 17:39:18 -07:00
JinjingandOrca 26934b11bf fix(orchestration): complete tasks on worker_done + coordinator UX fixes (#8030)
* fix(orchestration): complete worker tasks and improve coordinator UX

* Fix orchestration lifecycle sender resolution and peek/check compat hand

- Lifecycle sends (worker_done/heartbeat) now use ORCA_TERMINAL_HANDLE
  verbatim, skipping the liveness probe and pane remint that could
  block delivery during restarts or mismatch stale-runtime assignee
  handles.
- --peek now round-trips as {peek:true, unread:false} so older runtimes
  that strip unknown params degrade to non-destructive "all" instead of
  mark-read, with client-side filtering to restore peek semantics and a
  clear error when --peek --wait can't be honored.
- Reject combined read-mode flags (--unread/--peek/--all) before calling
  the runtime.
- Distinguish suppressed (already-consumed) lifecycle messages from
  ignored ones so send doesn't wake --wait waiters for stale heartbeats.
- Fix task summary truncation to avoid splitting UTF-16 surrogate pairs
  and to not misreport whitespace normalization as truncation.

* Add shared helper to abbreviate orchestration task specs for brief listi

- Normalizes whitespace and caps spec length at 160 chars, flagging
  truncation separately from whitespace-only changes
- Truncates on UTF-16 code point boundaries to avoid splitting
  surrogate pairs and emitting malformed strings

* Add pane-key identity to worker_done/heartbeat reconciliation and server

- Records the sender's pane key on messages and dispatch contexts so
  worker_done/heartbeat ownership can be verified by the remint-stable
  pane leaf instead of the terminal handle, which is reissued across
  restarts.
- Rejects lifecycle messages from a genuinely foreign pane while still
  tolerating handle remints, tab break-outs, and older CLIs that lack
  pane identity.
- Moves task-spec abbreviation server-side (orchestration.taskList
  --brief) so full specs no longer cross SSH/relay transports, with a
  client-side fallback for older runtimes; consolidates the shared
  abbreviation helper under src/shared.
- Adds a stderr warning when a pre-peek runtime's --peek response hits
  the 100-row cap, since older unread messages may be missing.

* Isolate ORCA_PANE_KEY in CLI test beforeEach to fix leaked senderPaneKey

Co-authored-by: Orca <help@stably.ai>

* Fix pane-key remint bypassing dispatch mutual-exclusion lock

- Dispatch locking only matched on assignee_handle, so a reminted
  terminal handle (tab break-out) could open a second concurrent
  dispatch on the same pane.
- Add leaf-UUID-based pane key comparison (parsePaneKey) as a
  secondary lock, falling back to exact handle match for legacy
  rows without pane keys.

* Update orchestration skill docs for lifecycle authority and CLI flag add

- Clarify that dispatch lifecycle is tied to taskId+dispatchId verified against
  the dispatched pane, not the terminal handle, since handles can be reminted
  after restart
- Document new `check --peek`/`--all` and `task-list --brief` flags, with
  fallback guidance for older CLIs that reject them
- Note that a valid worker_done auto-completes the task/dispatch, so workers
  shouldn't also call task-update manually

---------

Co-authored-by: Orca <help@stably.ai>
2026-07-12 02:15:11 -07:00
NeilandOrca 42cf64cdc9 fix(linux): stop Orca terminals from launching the GNOME Orca screen reader via bare orca (#8347)
On Linux the CLI installs as orca-ide so it never shadows /usr/bin/orca
(GNOME's screen reader), but agent-facing surfaces (orca-cli skill,
dispatch preambles, CLI hints) all invoke bare `orca` — so on stock
Ubuntu an agent inside an Orca terminal launched the screen reader,
which started speaking (#7904).

Fix: prepend a userData-scoped shim dir (bare `orca` -> bundled
orca-ide launcher, or the stable AppImage) to the PATH of every
packaged-Linux managed PTY, mirroring the existing dev-mode cli/bin
prepend. The user's own shells — and their real screen reader command —
stay untouched. Also flip the orca-cli skill probe to prefer orca-ide
so agents outside Orca terminals never execute the screen reader.

Fixes #7904

Co-authored-by: Orca <help@stably.ai>
2026-07-12 00:38:35 -07:00
11f116f6b4 docs(computer-use): clarify get-app-state JSON tree field (#7788)
* docs(computer-use): document get-app-state JSON response fields

* docs(computer-use): correct get-app-state JSON guidance

---------

Co-authored-by: 循安 林 <andylin2@fmt.com.tw>
Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
2026-07-11 22:50:30 -07:00
Rod BoevandJinjing 3090ff0edb fix(runtime): explain full worktree id selectors (#7432) (#7892)
* fix(runtime): explain full worktree id selectors (#7432)

* Fix full worktree id selectors for bare repo ids and doc guidance

- Reject bare repo-id selectors up front via a shared validator instead
  of relying on worktree-list scanning, so RPC callers no longer trigger
  an unnecessary rescan just to detect the mistake
- Propagate the structured worktree_id_requires_full_path code through
  RPC error mapping so callers get a typed error, not just a message
- Update orca-cli, orca-emulator, and orchestration skill docs to show
  the full `<repo-id>::<path>` id shape and stop implying a bare repo
  id is a valid worktree selector

---------

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
2026-07-11 22:40:44 -07:00
BingZandJinjing be258e23ec Add Grok orchestration group routing (#8058)
* docs: design Grok orchestration group

* docs: plan Grok orchestration group implementation

* fix: add Grok orchestration group

* test(orchestration): accept Windows skill newlines

* Fix @grok orchestration group matching and remove stale planning docs

- Reuse the shared buildAgentNameRe matcher in groups.ts instead of a
  divergent local regex, so orchestration groups honor the same
  Windows launcher-suffix rule (grok.exe/.cmd/.bat/.ps1) as the rest
  of Orca's agent-title detection.
- Add test coverage for real Grok OSC title shapes (spinner-collapsed,
  session titles) and Windows launcher-suffix titles.
- Delete the now-completed design and implementation-plan docs for
  the Grok orchestration group work.

---------

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
2026-07-11 21:43:20 -07:00
JinjingandOrca 667e04e72f fix: use dynamic agent name in orca-cli worktree fallback command (#8341)
Co-authored-by: Orca <help@stably.ai>
2026-07-11 18:37:05 -07:00
ryushioneandJinjing eaddccf7c3 skills: prefer agent-first worktree launch; avoid empty shell tabs (#7957)
* skills: prefer agent-first worktree launch; avoid empty shell tabs

Document Orca's first-terminal behavior so agents do not leave dead
shell tabs: --agent runs in the first terminal (one tab), bare
worktree create + terminal create leaves shell + agent (two tabs).

Also: re-resolve live handles via terminal list after create, message
one handle only, and prefer orchestration check --inject over terminal
send for pure orchestration pings. Aligns with CLI docs
(--agent launches the selected agent in the first terminal).

* fix skill guidance for agent-first worktrees

---------

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
2026-07-11 18:00:48 -07:00
Jinjing 3dd3cc9f68 Clarify Orca orchestration tool boundary and sidebar lineage (#7522)
* Clarify Orca orchestration tool boundary and sidebar lineage

Add a "Tool Boundary" section to the orchestration skill, requiring
explicit Orca runtime state instead of generic subagent tools or
chat-only parallel workers. Also add tests to verify the tool boundary
and clarify sidebar lineage for same-worktree workers.

* Clarify worktree lineage guidance and parent-child boundaries

Update orchestration guidance and tests to clarify when to use child versus
top-level worktree lineages, and when to prefer same-worktree workers.

* Require stating the desired Orca lineage before creating a worktree from
  an active feature branch.
* Limit child worktrees to conceptually stacked or dependent tasks.
* Prefer same-worktree workers unless isolated checkouts are explicitly
  needed and do not require uncommitted changes.
2026-07-06 00:05:49 -07:00
Brennan Benson 7b7a21e3c7 Give agents access to inline Linear ticket screenshots and media (#7484) 2026-07-05 23:55:56 -07:00
Jinjing c97d3a4977 Replace post-worker_done polling with idle behavior (#7509)
- Instruct workers to stop and idle or exit immediately after sending
  `worker_done`, rather than running a 10-minute polling loop.
- Distinguish instructions based on worker kind: prompt-returning
  agents should remain idle for re-engagement, while bare-shell
  workers should exit.
- Prevent infinite polling overhead since the coordinator re-engages
  workers via fresh terminal input instead of inbox polling.
2026-07-05 23:10:20 -07:00
JinjingandOrca 45370a5987 fix(skill): fix 6 dogfood bugs in orca-per-workspace-env templates (#7485)
* fix(skill): fix 6 dogfood bugs in orca-per-workspace-env templates

Fixes found while standing up a local Docker SSH per-workspace env (§7h) end to end:

1. GIT_ASKPASS helper broke under set -u — the printf interpolated $1/$GH_TOKEN
   at write-time, aborting the clone with "$1: unbound variable". Escape both so
   they land literally and resolve at git-runtime (also keeps the token out of the
   file); rm the helper after. (§5, §7f base-snapshot + create, §10)
2. Agent-auth verify missed stderr — 'codex login status' prints "Logged in" to
   stderr, so the stdout-only grep wrongly reported not-logged-in. Fold 2>&1.
   (§4, §7b, §7f Phase 3, §7h, §10)
3. --device-auth is mandatory on headless VMs — plain OAuth login binds an
   unreachable loopback callback port and hangs. (§4, §7b, §7h, §10)
4. Interactive Phase-3 login can't be driven by a non-interactive orchestrator
   (no TTY for docker exec -it / ssh -t) — user runs it themselves, or via the
   harness bang-prefix. (§1, §4)
5. Local Docker host-key churn — ephemeral containers regenerating host keys churn
   known_hosts on localhost as ports rotate; bake host keys into the base image at
   build time. (§7h + validation notes, §10)
6. Orchestrator must ask the user to report back when the interactive login
   finishes before resuming non-interactive phases. (§1, §4, §7b, §7h)

Co-authored-by: Orca <help@stably.ai>

* fix(skill): tighten login gate, de-dup gotchas in orca-per-workspace-env

- Verify login via exit code first; when grepping, match the agent's exact
  success line, never `grep -qi 'logged in'` (also matches "not logged in")
- Keep the generic template agent-agnostic; hardcode codex strings only in
  the codex-based Vercel worked example (now case-insensitive)
- Collapse repeated device-auth / stderr-fold / GIT_ASKPASS rationale to
  §4/§5 cross-refs; add a load-bearing-escaping test note
- Add a connection-mode orientation block up front; fix front-matter grammar

Co-authored-by: Orca <help@stably.ai>

* docs(skill): replace 'orchestrator' jargon with plain no-TTY wording

The term meant 'the agent running these steps runs commands
non-interactively, so it has no TTY.' Say that directly instead, and
drop the redundant 'orchestrating agent'/'non-interactive orchestrator'
doubling at the Phase-3 checkpoint.

Co-authored-by: Orca <help@stably.ai>

---------

Co-authored-by: Orca <help@stably.ai>
2026-07-05 21:23:13 -07:00
Jinwoo HongandOrca 39964149c8 Per-Workspace Environments (on-demand disposable runtimes) + Add Project remote host setup (#6320)
Co-authored-by: Orca <help@stably.ai>
2026-06-30 11:31:55 -07:00
42b2ecc5c6 feat(emulator): Android emulation via scrcpy (cross-platform, iOS parity) (#6434)
* docs: add Android emulation design spec

Adds the design for first-class Android emulator support as a cross-platform
peer of the iOS simulator feature: an extracted EmulatorBackend interface
(iOS + Android), full AVD lifecycle management via the Android SDK, a live
scrcpy H.264 pane decoded in-renderer with WebCodecs, the full control surface
(tap/gesture/type/buttons/rotate), accessibility tree, app install/launch,
runtime permissions, logcat, and a dedicated orca-emulator-android skill.

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

* refactor(emulator): add EmulatorBackend interface + backend/codec session tags

First step of multi-backend emulator support: introduce the EmulatorBackend
type and tag each session with its backend kind + stream codec, defaulting to
ios/mjpeg so existing serve-sim behavior is unchanged.

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

* refactor(emulator): extract IosEmulatorBackend and make the bridge a router

Move the serve-sim/simctl device + helper + input mechanics out of
EmulatorBridge into IosEmulatorBackend (implementing EmulatorBackend). The
bridge now owns the session registry and lifecycle orchestration and routes
each command to the backend that owns the target device. iOS behavior is
unchanged; the existing bridge tests pass untouched and the backend gains its
own input-op coverage.

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

* feat(emulator): add pure Android leaf modules (sdk/adb/avd/scrcpy/input/ax)

Dependency-injected building blocks for the Android emulator backend, each unit-
tested in isolation: SDK + tool discovery, adb device/output parsing, AVD list +
boot arg building, scrcpy control-socket byte encoders, normalized<->pixel +
keycode mapping, and a uiautomator XML accessibility-tree parser. Not yet wired;
AndroidEmulatorBackend composes these in the next phase.

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

* refactor(emulator): gate availability on the iOS backend + lock it with tests

inspectEmulatorAvailability now decides iOS host support via the registered iOS
backend instead of a bare platform literal, routing the decision through the
multi-backend seam. Output shape and all messages are unchanged (the settings
pane still reads simctl/serveSim). Adds the previously-missing regression tests
covering the unsupported, ready, no-devices, and tool-failure paths.

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

* feat(emulator): add Android app/permissions/logcat arg builders

Pure adb arg-builders + a logcat line parser for app install/launch, runtime
permission grant/revoke/reset, and logcat capture. Unit-tested in isolation;
wired into AndroidEmulatorBackend's capability verbs in a later phase.

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

* feat(emulator): AndroidEmulatorBackend device management + unified device list

Adds the Android backend (registered alongside iOS in the bridge): SDK-gated
host support, device/AVD discovery and merge, AVD boot + boot-completion wait,
shutdown, and tap/swipe/type/button/rotate/exec via `adb shell input` so control
works without the scrcpy server (the live H.264 stream lands in the streaming
phase). Surfaces everything through a new cross-platform `orca emulator devices`
command (RPC emulator.listDevices -> bridge.listAllDevices) with a platform
column. Device inventory is split into its own module to keep files focused.

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

* feat(emulator): Android capability verbs (install/launch/permissions/ax/logcat)

Wires the Android capability operations into AndroidEmulatorBackend and exposes
them through a capability-gated bridge router (runCapability), RPC, and CLI:
- orca emulator install/launch/permissions/ax/logcat
Capabilities are advertised per backend; calling one on a backend that lacks it
(e.g. iOS) fails with emulator_unsupported instead of a silent no-op. Input ops
and capability ops are split into focused modules to keep files under the
line cap; the runtime shares one target-param type.

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

* docs(skill): add orca-emulator-android skill + cross-ref from iOS skill

Documents the cross-platform Android emulator control surface (devices, input,
hardware buttons, rotate, install/launch, permissions, ax, logcat) driveable via
the orca CLI today, and notes the live visual pane is in development. Points the
iOS skill's "when not to use" at the new Android skill.

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

* feat(emulator): Android live-pane streaming scaffolding (scrcpy + WebCodecs)

Builds the H.264 video path as scaffolding: scrcpy frame/codec-meta parsing,
server-deploy arg builders, control-protocol encoders (committed earlier), the
stream session (server + sockets), a video pub/sub registry, the
emulator:videoStream* IPC channel, and a renderer WebCodecs->canvas hook. Pure
framing/deploy/registry are unit-tested; the socket/WebCodecs/jar integration is
clearly flagged UNVERIFIED and the remaining wiring (startSession, preload,
pane codec branch, packaging the jar) is documented in
docs/android-emulation-streaming.md.

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

* docs: fix streaming notes doc path in video-stream hook comment

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

* chore(emulator): add diagnostic probes for Android testing

Adds an emulator-probe logger (console + temp file at
os.tmpdir()/orca-android-emu-probe.log) and wires probes at four layers so
errors surface during manual testing: every emulator.* RPC call + error (RPC
dispatcher), every adb/emulator command + non-zero exit (command runner), and
the scrcpy session + video-stream IPC lifecycle. Temporary diagnostics; remove
or gate behind a flag once the Android pane is validated.

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

* feat(emulator): show Mobile Emulator settings cross-platform + aggregate Android availability

The Mobile Emulator settings section is no longer macOS-gated (Android works on
Windows/Linux), and inspectEmulatorAvailability now aggregates the iOS and
Android backends: Android devices/AVDs appear in the device list and a host
without iOS gets the Android setup message instead of "requires macOS".

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

* fix(emulator): show Mobile Emulator sidebar nav entry on non-mac desktops

The settings sidebar nav registered the Mobile Emulator entry behind isMac, so
it stayed hidden on Windows/Linux even after the section content was ungated.
Widen it to showDesktopOnlySettings to match the section.

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

* feat(emulator): wire Android startSession to scrcpy + client-downloaded jar

AndroidEmulatorBackend.startSession now boots the device, ensures the scrcpy
server jar (downloaded by the client into the per-user cache on first use, not
bundled), starts a ScrcpyStreamSession, and feeds its H.264 frames to the video
registry; stopHelperForDevice tears it down. Sessions carry their backend kind
so worktree-active routing picks the right backend. Boot, host SDK discovery,
and the stream starter are split into focused modules to stay under the line cap.

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

* fix(emulator): stop the iOS backend from claiming Android devices off-mac

iOS ownsDevice now returns false unless the host supports it, so on Windows an
Android serial routes to the Android backend instead of erroring with
"requires macOS". Backend-for-device fallback prefers a host-supported backend.

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

* fix(emulator): scrcpy scid 31-bit + retry video socket until server delivers

Two fixes validated against a real emulator: scrcpy parses scid as a signed
32-bit hex int, so mask to 31 bits + pad to 8 digits (8-byte values overflowed
and the server exited). And adb accepts the forwarded TCP connection before the
server's abstract socket exists then resets it, so retry the video socket until
it actually delivers the dummy byte before connecting control. H.264 meta now
arrives (576x1280). Adds socket/server-exit diagnostics probes.

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

* feat(emulator): render the Android H.264 pane via WebCodecs

Wires the live Android pane end-to-end: preload exposes emulator video stream
APIs; the pane's device list uses the unified emulator.listDevices (Android +
iOS); and emulator-screen-stream-content renders a WebCodecs <canvas> for
scrcpy:// sessions (H.264, SPS/PPS prepended to the first keyframe) instead of
the MJPEG <img>. The video hook reports the stream size for the device frame.

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

* feat(emulator): buffer the current GOP for late video subscribers

The renderer subscribes after attach already started the scrcpy stream, so the
registry now caches the current GOP (keyframe + following deltas) alongside the
codec meta and config, and replays it on subscribe. A pane opened mid-stream
decodes from the keyframe immediately instead of showing black until scrcpy's
next periodic keyframe (~10s). Refreshes the now-validated session doc comment.

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

* fix(emulator): show New Mobile Emulator tab action off macOS

The tab create menu and its dropdown item gated the New Mobile Emulator action
on isMacOs, hiding it on Windows/Linux where Android emulation is now supported.
Gate on mobileEmulatorEnabled + onNewSimulatorTab (already cross-platform) so
the action appears wherever a mobile emulator backend is available.

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

* fix(emulator): open the Mobile Emulator tab off macOS

openMobileEmulatorTab and ensureSimulatorTab both returned null unless the host
was macOS, so the New Mobile Emulator action no-opped on Windows/Linux even
though the menu entry showed. Drop the isMacOsHost early-returns; the
mobileEmulatorEnabled setting and backend availability already gate the feature.

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

* fix(emulator): resolve a default attach device across backends

emulatorAttach with no device fell back only to the iOS listSimulators picker
(empty on Windows/Linux), so the pane's no-device launch flow errored. Extract
resolveDefaultAttachDevice: iOS default first, else the first booted (else
first) device across host backends, so Android attaches without an explicit
device. Split into its own module to stay under the line cap.

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

* fix(emulator): render the pane off macOS instead of an unavailable wall

EmulatorPane short-circuited to the "macOS only" EmulatorUnavailablePane on any
non-Mac host, blocking the now-working Android pane. Always render the pane
content; its device discovery and error surface handle a missing backend.

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

* fix(emulator): let attach boot a shut-down AVD with a stale active session

getReusableActiveForWorktree called resolveDeviceId on the requested device,
which throws for a not-yet-booted Android AVD, aborting the attach. Guard it so
a resolve failure means "not the active device" and the attach falls through to
a fresh boot — so picking a shut-down AVD in the pane and hitting Connect boots
it via ensureBooted instead of erroring.

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

* fix(emulator): launch the AVD detached instead of via execFile

bootAndroidDevice started the emulator through the command runner (execFile with
a timeout + 1MB stdout maxBuffer), which kills the long-running, verbose emulator
process — so booting an AVD from the pane never actually came up. Spawn it
detached with no stdio and unref it so it outlives the call, mirroring how the
scrcpy server is launched.

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

* fix(emulator): dedupe concurrent attaches into one scrcpy stream

Extract AndroidStreamController to own the per-serial scrcpy lifecycle and
dedupe starts: concurrent attaches (e.g. the pane's auto-attach racing the tab
launch) now share one in-flight start and reuse the live stream instead of
spawning a second scrcpy server that fights for the port and kills the first.
Also initialize the registry GOP buffer in register() (latent type error).

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

* fix(emulator): boot the AVD headless without a console window

The detached spawn opened a Windows console (showing the emulator's verbose
qemu/netsim logs) and a redundant native emulator window. Pass windowsHide and
run the emulator with -no-window so it boots headless — the scrcpy pane is the
view, matching how iOS hides Simulator.app.

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

* fix(emulator): boot the AVD with a hidden console, not detached

detached: true sets DETACHED_PROCESS, which gives the console-subsystem emulator
no console — so it and its qemu/netsim children pop their own visible cmd window
that windowsHide can't suppress. Drop detached and rely on windowsHide
(CREATE_NO_WINDOW = hidden console) + unref; spawn already keeps it alive past
the launch call, and managed emulators are shut down on app quit.

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

* fix(emulator): keep Android emulators alive when switching devices

Attaching a different device shut down the active one (shutdownDevice: true),
which for Android meant killing the running emulator and cold-booting the target
(~60s) on every switch — and switching back. Add bridge.stopActiveForSwitch:
Android emulators stay running for instant switch-back, while iOS simulators are
still replaced. Switching to an already-running emulator is now immediate.

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

* perf(emulator): only resize the video canvas when dimensions change

The decoder output handler set canvas.width/height on every frame, which
reallocates the canvas backing store and forces an object-contain reflow each
frame — a needless per-frame cost. Resize only when the frame dimensions
actually change.

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

* feat(emulator): genericize copy + add Android Studio setup link

Replace iOS-only wording (Xcode/Simulator/iPhone) in the pane and settings with
backend-neutral copy so Android reads correctly on every platform. When no
emulator is available, the Mobile Emulator settings now show a "Download Android
Studio" link plus setup guidance (ANDROID_HOME / default install path). Removes
the now-unused, macOS-only EmulatorUnavailablePane.

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

* feat(emulator): show emulator SDK status in settings

The backend availability now reports the resolved Android SDK path, aggregated
into emulator.availability as an `android` block. The Mobile Emulator settings
render an "Emulator SDKs" card showing Android SDK (detected at <path> / not
found, with a Download Android Studio link) and, on macOS, iOS Simulator (Xcode)
status — mirroring the agent-control card.

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

* feat(emulator): locate a custom Android SDK folder from settings

Add an androidSdkPath setting and a "Locate SDK folder…" / Clear action in the
emulator SDK status card. The path is applied as the highest-priority discovery
candidate (falls back if invalid), and the backend's SDK is re-resolved on use
via a new AndroidSdkState — so locating or installing the SDK takes effect on
Refresh without restarting Orca. Guards the status card against older runtimes.

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

* fix(emulator): settle the scrcpy video socket once to stop retry storms

A failed TCP connect emits both 'error' and 'close', so retry ran twice and
scheduled openVideoSocket(attempt+1) twice — fanning out into an exponential
connection storm while waiting for the server to start listening. A runaway
chain could then hit attempt 100 and fail/close a stream that had already
connected. Replace the delivered flag with a single settled latch so each
socket retries (or delivers) exactly once.

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

* fix(emulator): address CodeRabbit review findings

- avd-boot: handle spawn 'error' (an unhandled ChildProcess error crashed the
  main process); validate the target is a known AVD before launching.
- capability-ops: propagate adb non-zero exits for launch/permission/logcat and
  check the uiautomator dump before reading (avoids stale XML).
- scrcpy-video-registry: actually replay the buffered GOP on subscribe so late
  subscribers decode immediately.
- android-sdk-state: re-resolve host discovery every call so a changed SDK path
  takes effect live (no restart).
- android-sdk-discovery: require both adb and the emulator binary.
- emulator-bridge: fall back to the platform-primary backend (Android off-mac)
  so setup errors aren't iOS/CoreSimulator on Windows/Linux.
- scrcpy-server-download: dedupe concurrent first-use downloads + add a timeout.
- scrcpy-stream-session: idle-socket connect timeout; surface control-socket
  errors instead of swallowing them.
- android-exec: pass the whole command so the device shell parses quotes/pipes.
- avd-manager: match emulator log prefixes exactly (keep AVD names like
  PixelWARNINGTest).
- permissions: `pm reset-permissions` is global and takes no package argument.
- stream controller/starter: drop stale handles for dead streams; idempotent
  teardown. use-emulator-video-stream: stopVideoStream returns Promise.

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

* fix(emulator): populate the GOP buffer and reuse live scrcpy streams

Self-audit follow-ups in the same class as the CodeRabbit GOP-replay finding:

- scrcpy-video-registry: pushFrame never wrote to entry.gop, so the replay
  loop added for late subscribers iterated an empty array — a no-op. Build the
  GOP on ingest (start at each keyframe, append following deltas; don't buffer
  deltas before the first keyframe). Adds tests for population, reset, and the
  pre-keyframe guard.
- android backend: isSessionReusable was stubbed to always return false with a
  "no persistent stream yet" note, but scrcpy streams are persistent now — so
  every renderer remount tore down and respawned the server. Reuse a live
  stream (scrcpyVideoRegistry.has) so remounts reconnect, matching iOS. The
  device-mismatch check still runs first, so device switching is unaffected.
- Refresh stale comments that implied unfinished/unverified work.

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

* WIP: Changes before auto-review fixes

Co-authored-by: Orca <help@stably.ai>

* Refine mobile emulator availability settings

Co-authored-by: Orca <help@stably.ai>

* Address emulator review follow-ups

Co-authored-by: Orca <help@stably.ai>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Jinwoo-H <jinwoo0825@gmail.com>
Co-authored-by: Orca <help@stably.ai>
2026-06-28 21:01:09 -07:00
Jinjing 2edfad0fc6 Clarify full handoff routing guidance (#6687) 2026-06-28 19:51:14 -07:00
Brennan BensonandOrca 4ac1e960d4 Harden Orca CLI skill security guidance (#6131)
Co-authored-by: Orca <help@stably.ai>
2026-06-24 13:55:53 -07:00
Neil f5b50b6091 Document Orca CLI card status (#6122) 2026-06-22 20:43:57 -07:00
Brennan BensonandOrca a856c7d6b6 Rename Orca Linear agent skill (#5855)
Co-authored-by: Orca <help@stably.ai>
2026-06-21 16:16:37 -07:00
Jinjing a1cbb31f27 Clarify worktree lineage and handoff rules in skills and CLI help (#5892)
- Explain that `--no-parent` only controls Orca lineage, not the Git
  base branch, and detail how to target independent top-level work.
- Define full handoffs as ownership transfer and forbid the use of
  orchestration dispatch injection for them.
- Update CLI help text for `orca worktree create` to reflect the
  lineage and base-branch guidance.
- Add tests to verify that these guidance patterns exist in the skill
  markdown files.
2026-06-20 01:51:35 -07:00
WolfieandWolfgang Schoenberger 1d5efeb976 fix: support worktree name selectors (#5696)
Co-authored-by: Wolfgang Schoenberger <221313372+wolfiesch@users.noreply.github.com>
2026-06-18 23:10:21 -07:00
Brennan Benson cfc003452c Hide workspace parent flag from worktree create CLI (#5743) 2026-06-18 17:53:19 -07:00