# Orca Cli

> |

- **Type:** Skill
- **Install:** `agentstack add skill-jesamkim-oh-my-skills-orca-cli`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [jesamkim](https://agentstack.voostack.com/s/jesamkim)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [jesamkim](https://github.com/jesamkim)
- **Source:** https://github.com/jesamkim/oh-my-skills/tree/main/my-skills/orca-cli

## Install

```sh
agentstack add skill-jesamkim-oh-my-skills-orca-cli
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Orca CLI Orchestration

Run multi-agent coding work from Claude Code with a clear division of labor:

| Role | Who | How |
|------|-----|-----|
| Orchestrator — decompose, route, judge, integrate | **Claude Code (you)** | this skill |
| Code implementation | **Codex** | `orca dispatch` (lane) or Stably worktree/orchestration |
| Spec writing / second-opinion review | **Kiro CLI** | direct headless call (`kiro-cli chat --no-interactive`) — orca has no Kiro adapter |

You are the orchestrator. Do not write the implementation code yourself when a
task has been routed to a worker; your job is decomposition, dispatch, judging
results, and integration. You still read diffs and run tests — verification is
orchestrator work.

Supported platforms: **macOS and Linux only** (Windows is explicitly out of
scope — orcastrator's kill/process-group semantics are POSIX-only, and the
wrapper scripts assume a POSIX shell).

## Step 0: Detect which "orca" this machine has

Two unrelated tools ship a binary named `orca`. Their command sets are
incompatible, so detect first, then read the matching reference:

```bash
bash /scripts/detect_orca.sh
# prints: VARIANTBIN   e.g. "orcastrator  /home/u/.npm-global/bin/orca"
```

| VARIANT | Tool | Command style | Read next |
|---------|------|---------------|-----------|
| `orcastrator` | happycatlabs/orca (npm `orcastrator`) | `dispatch` / `inspect ` / `answer` / `resume` / `lanes` / `kill` | `references/orcastrator.md` |
| `stably` | Stably Orca ADE (onorca.dev) | `worktree` / `terminal` / `orchestration task-create → dispatch → check --wait` | `references/stably.md`, then `$ORCA skills get orca-cli` for the version-matched guide |
| `unknown` | an explicit `ORCA_CLI_COMMAND`/`ORCA_BIN` override matched neither contract (exit 2) | — | report the override and its error; do not fall through to another binary |
| `none` | neither installed | — | offer `npm i -g orcastrator` (lightweight) or Stably desktop/`orca serve` install; orcastrator can also run via `npx -y -p orcastrator orca ...` without install |

Use the printed BIN path for every later call (`$ORCA` below). Do not trust
bare `orca` on PATH — a Stably relay shim commonly shadows the npm bin, and on
Linux outside Orca terminals bare `orca` can even be the GNOME screen reader
(the script refuses to execute that one; it would start speech aloud).

Overrides are strict: when `ORCA_CLI_COMMAND` (exported by Stably for managed
sessions) or `ORCA_BIN` is set, only that executable is considered — a
mismatch prints `unknown` and exits 2. Report that error instead of falling
back to another binary, which could silently target a different Orca build.

The detection result holds for the whole session; do not re-run it per command.

## Model policy (applies to every dispatch)

- **Default: omit the model flag.** Each agent then runs on its own configured
  default (Codex config, Kiro `auto` routing). This is the right call for most
  tasks and the cheapest.
- **Explicit override: when the user names a model** ("codex는 gpt-5.5로",
  "kiro는 opus로 리뷰"), pass it through — never silently drop it:
  - orcastrator: `--model ` on `dispatch` only — `resume` accepts just
    `--timeout` and keeps the lane's original model; to change models,
    dispatch a new lane. (Valid names come from `$ORCA agents` manifests;
    e.g. the claude adapter lists `fable|opus|sonnet|haiku`.)
  - **Codex model names are provider-qualified and pass through unvalidated.**
    The codex adapter advertises no model list — `--model` goes verbatim to
    the app-server, which resolves it against the `model_provider` in
    `~/.codex/config.toml`. On Bedrock Mantle that means the full provider ID
    (`openai.gpt-5.6-sol`), not the short name: `--model gpt-5.6-sol` fails
    the lane ~14 s in with `agent_failed` / `404 The model 'gpt-5.6-sol' does
    not exist` (measured 2026-08-03). Before overriding, check
    `grep ^model ~/.codex/config.toml` and match its naming scheme — and if
    the user's requested model IS that default, just omit the flag.
  - Stably: model flags go on the agent command itself, e.g.
    `--command 'codex --model gpt-5.5 -c model_reasoning_effort="xhigh"'`
    (`worktree create --agent` does not accept model flags — see reference)
  - Kiro: `--model ` (e.g. `claude-opus-4.8` 2.2x credits,
    `claude-sonnet-4.6` 1.3x, `claude-haiku-4.5` 0.4x). Don't hardcode opus for
    routine work.
- If an override fails with an unknown-model error, report the error and the
  agent's advertised model list; do not quietly fall back to the default.

## Orchestration loop (orcastrator variant)

The lane contract in one pass — full details, envelope schema, exit codes, and
pitfalls in `references/orcastrator.md`:

```bash
# 1. dispatch one focused task per lane (prints a handle line, then blocks
#    until the lane settles; run in background for parallel lanes)
$ORCA dispatch --agent codex --cwd . "Fix the flaky token-refresh test. Repro: npm test -- --grep refresh"

# 2. wait / check state (terminal states also satisfy --wait-for blocked;
#    ALWAYS branch on the returned status field, never on "the wait returned")
$ORCA inspect lane_a3f81c02 --wait-for blocked --timeout 900000

# 3a. if status=blocked: read blocked.questions, then answer — and resume too
#     when the question is parked (see the live/parked split below; the
#     envelope's next[] already lists the right commands)
$ORCA answer lane_a3f81c02 "Use the staging database"

# 3b. if status=completed: JUDGE the result yourself (read the diff, run tests)
#     ok:true means delivery, NOT correctness — semanticOutcome stays "unknown"

# 4. follow-up on a completed lane (the only terminal state that can resume)
$ORCA resume lane_a3f81c02 "Now add tests for the edge cases"

# housekeeping
$ORCA lanes            # list all lanes
$ORCA kill lane_...    # stop a queued/running/blocked lane
```

### Reacting to signals

There is no push notification or callback — you learn a lane's state only by
asking. `dispatch` returns one envelope when the lane settles (blocked or
terminal), and `inspect` is how you ask afterwards. Everything below is
verified against orcastrator 0.2.25; `references/orcastrator.md` has the
event-level detail.

| Signal | What you see | What to do |
|--------|--------------|------------|
| Waiting on a question | `status: blocked`, `ok: true`, exit 0, `blocked.questions[]` (`options[]` only when the agent offered choices), `next[]` prefilled | Answer it — see the live/parked split below |
| Still working | `status: running`, no terminal envelope yet | Keep waiting with a fresh `--wait-for`; don't kill |
| Wait window expired | `ok: false`, `code: timeout`, exit 5, with `status` = the lane's real last-known state, the `lane` block, and `error.message`/`error.remediation` — but **no `blocked`, `next[]`, or `warnings[]`** | The wait command failed; the lane did not. Branch on `status`: only roll the wait forward while `queued`/`running`, since re-waiting a `blocked` lane loops forever. Run a plain `inspect ` to get the omitted parts (the question itself, stale-running warnings) |
| Success | `status: completed`, `nativeStatus: completed` | Judge it yourself: read the diff, run the tests |
| Failure | `status: failed` — branch on `code`, not exit alone (`agent_failed`/`adapter_error`/`agent_unavailable` exit 3; a dispatch/resume that ran out of time with no pending question settles `failed` with `code: timeout`, exit 5) | Read `error.message`; a failed lane cannot resume — re-dispatch |
| Dispatch timed out *with* a pending question | `status: blocked`, exit 0 — the turn parks the question as `live: false` instead of failing | Treat it as blocked, not failed: answer, then resume. Re-dispatching here throws away the agent's work |
| Killed / lost | `status: killed` \| `lost`, terminal | Re-dispatch. (`lost` is a reserved state with no v0 code path) |
| Possibly-orphaned run | `status: running` + a **stale running** warning in `warnings[]` | The warning tests the pid currently in `lane.process`, which a resumed adapter overwrites once it emits `agent_started` — so a healthy resume can still trip it in the window before that. Check the latest `resume_started`: resumer pid alive → a resume is driving the lane, keep waiting and don't kill; pid dead → `resume` reclaims it (preferred, keeps the work); no `resume_started` at all → the original dispatch died, resume fails `invalid_state`, so `kill` then re-dispatch |

Rules that follow from the contract:

- **`--wait-for blocked` is satisfied by terminal states too** (so the wait
  can't hang), and `--wait-for done` means terminal only
  (`completed|failed|killed|lost`). Always branch on the returned `status`;
  never infer it from the fact that the wait returned.
- **`--wait-for` alone prints no events** — it is a synchronization
  primitive. Add `--follow` (or read afterwards with `--since `) when you
  want the event stream. Note `--follow` polls (fs.watch + timer fallback,
  ~150 ms); there is no daemon, and `--detach` is rejected with `usage_error`.
- **Read `warnings[]`.** Stale-running detection lives only in per-lane
  `inspect` — `lanes` returns a snapshot with no warnings, so a dead
  dispatcher is invisible there.
- **Don't kill a quiet lane.** A cursor lane's cold start takes 30–100 s, but
  it emits a single `heartbeat` about a second in (from its early stderr)
  precisely so you can tell a live cold start from a pre-output hang — so the
  signal to watch is that heartbeat's absence, not the long startup itself.
  codex/claude emit no heartbeat at all; their liveness signal is `progress`
  events.
- **blocked: `answer` vs `resume` depends on whether the question is live.**
  A live question (the original dispatch is still polling for the answer)
  takes `answer` and then `--wait-for done`; `resume` on it is rejected with
  `invalid_state` (exit 4) to prevent double-driving. A parked question (the
  dispatch already exited) needs `answer` **and then** `resume` — answering
  alone returns `"Answer recorded (generation N)"` and leaves the lane
  blocked. `next[]` encodes this split and is the right default, with one
  exception it can't see: a stale `live: true` whose poller has died still
  advertises answer-and-wait, but nothing will consume the answer — resume is
  allowed and necessary there.
- **Confirm the answer was consumed by generation, not by presence.** The
  submission `answered` event (no `consumed` field) stays in the append-only
  log forever; consumption appears as a *later* `answered` event with
  `consumed: true` and the same generation. So "still unread" means no later
  matching consumption event exists — not merely that you can see an
  unconsumed one.

Rules that prevent the common failure modes:

- **One write-capable lane per working directory.** Parallel lanes writing the
  same cwd will conflict — give each parallel lane its own git worktree cwd.
  Prompt-level file assignment ("you only touch README.md") is not isolation:
  workers still see each other's uncommitted changes in `git status`, and one
  `git stash` or `commit -a` eats the other's work.
- **Deliver briefs from a file, not inline.** Write the lane brief to a file
  and dispatch with `"$(cat brief.md)"` — inline backticks/quotes in a prompt
  break shell argument splitting and fail the dispatch with `usage_error`.
- **Match the brief to the task's shape — use Codex goals for long work.**
  Codex exposes `create_goal`/`update_goal` tools inside lanes (verified on
  codex-cli 0.146.x, feature `goals` stable). For a multi-step or
  likely-to-resume task, add to the brief: "Start by calling create_goal with
  this objective and the acceptance criteria; when finished call update_goal
  to mark it complete, or blocked if you must stop on a question." The goal
  record survives the thread, so an `orca resume` continues against the same
  tracked objective instead of a cold prompt. Contract limits: one unfinished
  goal per thread (complete it before creating another), and the agent may
  only set `complete`/`blocked` — pause/resume/budget states belong to the
  user/system. Skip goal instructions for short single-pass fixes; they add
  turn overhead without tracking value.
- **`blocked` is success, not failure** (exit 0). Answer the question instead
  of killing the lane.
- **Never infer correctness from `ok:true`.** The envelope separates
  `delivery` / `nativeStatus` / `semanticOutcome`; no envelope ever claims the
  work is right. Verify: run the tests, read the diff. Distrust the agent's
  self-reported numbers too — Codex's sandbox quotes `node --test` file-level
  counts (`# tests 3`) as if they were per-test counts; run the suite yourself
  and cite your own output.
- **Parse only the final stdout line** (one JSON envelope per command); stderr
  is diagnostics, not contract.
- Agent choice within orca: `codex` for real engineering (responds well to
  detailed briefs), `cursor` for narrow scoped edits (30–100 s cold start),
  `claude` lanes are analysis-only (headless `claude -p` denies writes by
  default).

## Orchestration loop (stably variant)

Same roles, different verbs — supervised coordination uses
`orca orchestration task-create → dispatch --inject → check --wait`, fire-and-
forget handoffs use `orca worktree create --agent codex --prompt`. Read
`references/stably.md` before issuing commands; the lifecycle rules (worker_done
authority, full-handoff vs supervised, worktree ids) are easy to get wrong.

## Kiro: spec writing and independent review

Kiro is not an orca agent (`orca agent-context` lists codex/claude/cursor/
opencode, no kiro), so orca cannot dispatch it as a worker. If the `kiro` skill
is installed, prefer it: `scripts/kiro_lane.sh` runs Kiro in an orca terminal
and returns a handle at once, which keeps the spec/review step from blocking
this orchestration loop —

```bash
K=/scripts/kiro_lane.sh
h="$(bash $K start --tier deep --title "spec: " "Write an implementation spec for : requirements, design, tasks. Context: ")"
bash $K wait --handle "$h" --timeout 900 && bash $K read --handle "$h"
```

Bare fallback when that skill is absent:

```bash
# spec writing (read-only file access is enough)
kiro-cli chat --no-interactive --trust-tools=fs_read \
  "Write an implementation spec for : requirements, design, tasks. Context: "

# explicit model override, per the model policy above
kiro-cli chat --no-interactive --model claude-opus-4.8 --trust-tools=fs_read "..."
```

The spec-first flow that makes this trio work:

1. Ambiguous or multi-day feature → Kiro writes the spec (requirements /
   design / task list).
2. You split the spec's task list into lane-sized briefs — each brief carries
   the relevant spec excerpt, file paths, and acceptance criteria. Codex
   responds to detail; "fix the bug" briefs waste a dispatch.
3. Dispatch to Codex, run the loop above.
4. After integration, an independent review pass before commit — the
   orchestrator judging its own dispatches is the same trap as reviewing your
   own code. Review-gate fallback chain (each step's failure is why the next
   exists): (a) Kiro review mode, preferably as a lane
   (`run_kiro_review.sh --lane`) since a real review takes minutes and blocking
   this loop on it buys nothing; if Kiro's non-interactive policy blocks
   `execute_bash` (it is rejected outright — there is no user to approve it),
   (b) re-run Kiro read-only (`--trust-tools=fs_read` — static analysis still
   yields a verdict), then (c) a codex review lane. A run with no review verdict is not "reviewed" —
   say so in the report instead of letting the gate silently pass.
5. Honor the verdict. A no-ship is overridden only with concrete evidence the
   reviewer could not obtain (e.g. you executed the behavior-preservation
   check its static analysis couldn't run) — never with constraints you
   authored yourself ("my brief forbade test edits" is circular, since you
   can change the brief). If the

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [jesamkim](https://github.com/jesamkim)
- **Source:** [jesamkim/oh-my-skills](https://github.com/jesamkim/oh-my-skills)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-jesamkim-oh-my-skills-orca-cli
- Seller: https://agentstack.voostack.com/s/jesamkim
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
