[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-94625":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":8,"htmlUrl":8,"language":9,"languages":8,"totalLinesOfCode":8,"stars":10,"forks":11,"watchers":12,"openIssues":13,"contributorsCount":13,"subscribersCount":13,"size":13,"stars1d":13,"stars7d":13,"stars30d":11,"stars90d":13,"forks30d":13,"starsTrendScore":13,"compositeScore":14,"rankGlobal":8,"rankLanguage":8,"license":8,"archived":15,"fork":15,"defaultBranch":16,"hasWiki":17,"hasPages":15,"topics":18,"createdAt":8,"pushedAt":8,"updatedAt":19,"readmeContent":20,"aiSummary":21,"trendingCount":13,"starSnapshotCount":13,"syncStatus":22,"lastSyncTime":23,"discoverSource":24},94625,"Orca-Orchestration","ZinkLu\u002FOrca-Orchestration","ZinkLu",null,"TypeScript",128,7,105,0,37.41,false,"main",true,[],"2026-08-24 04:01:22","# Orca DAG — skill + viewer\n\nEnglish | [简体中文](README_zh.md)\n\nSplit \"planning by chatting with an agent\" from \"visualizing + executing\" into two independent modules:\n\n1. **skill** (`skill\u002FSKILL.md`): teaches **your own agent** (Claude Code \u002F kimi \u002F …) how to break a requirement down into an **Orca orchestration task DAG**, plus the graph-building conventions. The planning \"brain\" stays in your agent — **no embedded Claude Agent SDK**.\n2. **viewer** (`server\u002F` + `web\u002F`, shipped as the `orca-dag` npm package and a standalone binary): connects to Orca's orchestration state and **visualizes the DAG live**; each node **picks its own harness** (claude \u002F kimi \u002F opencode \u002F grok …) and optionally a **model**; click **\"▶ Run with Orca\"** and the viewer's built-in **self-driven coordinator** dispatches ready tasks **in parallel** along the dependencies to autonomous workers spun up on demand, until the whole graph is done.\n\n> Core flow: **agent builds the graph → pick a Run and per-node harnesses in the viewer → Run → the DAG executes in dependency-parallel**. To change a task or a dependency, have the agent redraw the DAG — Orca has no interface for editing a single task.\n>\n> ⚠️ **Requires Orca ≥ 1.4.160.** That release (2026-07-29, PR #9925) rewrote the whole orchestration contract; this project targets it and **no longer supports older Orca**.\n>\n> ⚠️ Why the viewer still acts as its own coordinator: not because `orca orchestration run` is buggy — that command (along with `coordinator-start`) has been **officially retired** (calling it has no side effects; it just says \"go read the skill\"). Orca **deliberately ships no scheduler** — the official skill's words: *\"Agents still choose placement and concurrency; Orca does not schedule workers.\"* So the DAG loop belongs to the viewer, but **every step** inside that loop now uses Orca's own Run \u002F Task \u002F Dispatch primitives.\n\n![Crayon-style viewer: full-width DAG, default-harness\u002Fmax-parallel\u002FRun toolbar, and a read-only node panel with per-node harness and model pickers](docs\u002Fscreenshot.png)\n\n## How it works\n\n```\n   your agent (loads the orca-dag skill)          orca-dag viewer (npx orca-dag)  \n ┌───────────────────────────────┐             ┌──────────────────────────────┐\n │  chat → decompose → build DAG │             │  poll task-list → draw DAG   │\n │  Bash: orca orchestration     │             │  pick harness per node       │\n │        task-create \u002F gate-*   │             │  ▶ Run → self-driven         │\n └───────────────┬───────────────┘             └───────────────┬──────────────┘\n                 │  writes orchestration state                 │  poll + worker-start (parallel)\n                 ▼                                             ▼\n        ┌────────────────────  Orca orchestration state  ────────────────────┐\n        │  tasks \u002F deps \u002F gates  ·  on-demand autonomous workers (per-node   │\n        │                           harness)                                 │\n        └─────────────────────────────────────────────────────────────────────┘\n```\n\n1. You chat in **your own agent**. It loads the `orca-dag` skill, opens a **Run** with `orca orchestration run-create`, then builds the tasks and dependencies into that Run via `task-create --deps …`.\n2. Open the viewer (`npx orca-dag`). Pick the Run in the top bar; it polls `orca orchestration task-list --run \u003Cid> --json` every 2 seconds, lays out with **dagre**, renders with **React Flow**, and recolors statuses live.\n3. In the viewer, pick a harness per node (or rely on a default fallback), set \"Max parallel\", and click **\"▶ Run with Orca\"**.\n4. The viewer's **coordinator loop** takes over: it binds one of its own Orca terminals as the Run's coordinator (gaining mutation authority), then on each tick finds every `ready` task and calls `orca orchestration worker-start --task \u003Cid> --agent \u003Charness>` **in parallel** — **Orca itself** creates the worker terminal, waits for readiness, injects the dispatch, and returns a **Dispatch** (one attempt). The worker finishes with `worker_done --outcome` → Orca **automatically** marks the task and dispatch completed\u002Ffailed → dependents flip to `ready` → repeat until the graph is done, then `worker-stop` reclaims the workers.\n5. To change the plan: go back to the agent conversation and have it redraw the DAG.\n\n### The Run \u002F Task \u002F Dispatch layers\n\n| Layer | What it is | Owned by |\n|---|---|---|\n| **Run** | Namespace + coordinator inbox; only one coordinator is bound at a time (`consumer_generation` does the fencing) | Orca |\n| **Task** | A unit of work; `deps` define the DAG edges, `run_id` scopes it to a Run | Orca |\n| **Dispatch** | **One attempt** (id shaped like `ctx_*`); carries `failure_count` (circuit-breaks at 3), heartbeats, pane identity, capability credentials. A retry mints a new Dispatch | Orca |\n| Per-node harness & model, canvas positions, default harness, max parallel, current Run | The viewer's own preferences | `.orca-dag.config.json` |\n\nA Run is a namespace, **not a DAG** — several unrelated graphs can live in one Run. \"One Run = one DAG\" is a convention from `skill\u002FSKILL.md`, not an Orca constraint.\n\n### The authority model (why the viewer occupies a terminal)\n\nEvery Orca orchestration call goes through `resolveRunScope`:\n\n- **Reads** (`task-list` \u002F `gate-list`) skip the consumer check as long as they pass `--run \u003Cid>` — **any process can read**. That's all the viewer's polling needs.\n- **Mutations** (`dispatch` \u002F `gate-resolve` \u002F `task-create` \u002F `worker-start`) require the caller to **be the Orca terminal currently bound to that Run**, proven by resolving `--from \u003Chandle>` to a pane.\n\nThe viewer is an ordinary process with no terminal identity, so every mutation would fail with `run_required`. The fix: the viewer opens its own Orca terminal titled `orca-dag coordinator`, binds it with `run-use`, and passes `--from` on every mutation. **Binding fences the previous coordinator** (usually the agent terminal that drew your graph), so the viewer asks for explicit confirmation before starting; the agent can reclaim the Run anytime with `orca orchestration run-use --id \u003Crun>`. On stop, the viewer closes that terminal and releases the Run.\n\n## Prerequisites\n\n- **Orca ≥ 1.4.160** (`result.runtime.appVersion` in `orca status --json`). The Run\u002FDispatch contract landed in 1.4.160; older versions lack `run-create` \u002F `worker-start` and the viewer cannot run.\n- **The orchestration experimental feature is enabled**: Settings → Experimental.\n- **Orca is running**: `result.runtime.state` in `orca status --json` should be `\"ready\"`; otherwise run `orca open` first.\n- **The project is an Orca-managed worktree**: adding workers \u002F executing requires the current directory to be a registered repo\u002Fworktree (else `orca terminal create` fails with `selector_not_found`). Register with `orca repo add \u003Cpath>` or `orca worktree …`.\n- **An agent that can run the skill** (graph-building side): Claude Code, or anything that can read `SKILL.md` and run Bash.\n- **The viewer side depends only on the `orca` CLI** — no `claude`, no `ANTHROPIC_API_KEY`.\n- **Node.js ≥ 20** to run `npx orca-dag` — or none at all if you use a release binary. **Bun** only if you want to build a binary yourself.\n\n## Install\n\nOne command, both halves:\n\n```bash\ncd ~\u002Fany\u002Forca-managed\u002Fproject\nnpx orca-dag\n```\n\nThat installs the `orca-dag` **skill** into every coding agent on your machine (Claude Code, Codex, Cursor, OpenCode, Gemini CLI, Droid, and the shared `~\u002F.agents\u002Fskills` directory — whichever of them exist), then starts the **viewer** on \u003Chttp:\u002F\u002Flocalhost:8787> with the current directory as the workspace. It re-runs safely: the skill is only rewritten when it actually changed, and a skill directory you symlinked yourself is left untouched.\n\nThen just chat your requirement to the agent. It builds the DAG into Orca per `SKILL.md` and tells you to open the viewer.\n\nNeeds only **Node.js ≥ 20** — the package is a ~500 KB dependency-free bundle, and `bunx orca-dag` works too. Keep it around with `npm i -g orca-dag`.\n\nNo Node on the machine? Grab a standalone binary from the [releases page](https:\u002F\u002Fgithub.com\u002FZinkLu\u002FOrca-Orchestration\u002Freleases) — same behaviour, bundles its own runtime, needs only the `orca` CLI on PATH:\n\n```bash\ntar xzf orca-dag-darwin-arm64.tar.gz && sudo mv orca-dag \u002Fusr\u002Flocal\u002Fbin\u002F && orca-dag\n```\n\nSwitches: `PORT` (default 8787), `NO_OPEN=1` (don't open the browser), `--no-skill` \u002F `ORCA_DAG_NO_SKILL=1` (don't touch the agent skill directories), `WORKSPACE_DIR` (overrides the `active` worktree).\n\nWant the skill *without* the viewer, or managed by the standard tooling? `npx skills add ZinkLu\u002FOrca-Orchestration --skill orca-dag --global` — the [open agent skills CLI](https:\u002F\u002Fgithub.com\u002Fvercel-labs\u002Fskills), the same one `orca skills install` shells out to.\n\n## Uninstall\n\n```bash\nnpx orca-dag uninstall            # add --dry-run first if you want to see the list\n```\n\nRemoves the skill from every agent directory it was installed into and closes any `orca-dag coordinator` terminal a crashed viewer left bound to a Run (that one matters — a stale coordinator keeps your own agent fenced out). A skill directory you symlinked yourself is unlinked, never followed, so your checkout is safe.\n\nTwo things it won't delete on its own: `.orca-dag.config.json` (your per-node harness\u002Fmodel choices and canvas layout — pass `--purge` to drop it) and the program itself, since a running process can't remove its own binary. It prints the right command for that: `npm rm -g orca-dag`, `rm $(which orca-dag)`, or nothing at all if you only ever ran it through `npx`.\n\n### Building and releasing it yourself\n\n```bash\nnpm install\nnpm run dev            # frontend :5173 + backend :8787 (vite proxies \u002Fapi) → http:\u002F\u002Flocalhost:5173\nnpm run build:npm      # stage the publishable package → dist-npm\u002F (Node only)\nnpm run build:binary   # portable single binary → dist\u002Forca-dag (~100 MB, frontend embedded; needs Bun)\nnpm run release 0.2.0  # tag + push; CI publishes to npm and attaches every binary to a GitHub release\n```\n\nCross-compile a binary for another platform with `TARGET=bun-linux-x64 npm run build:binary`; `bash scripts\u002Fbuild-all-binaries.sh` does every target at once, which is what the release workflow runs.\n\n## Quick start\n\nAn end-to-end pass, starting from nothing installed:\n\n1. **Get your project under Orca** (once per repo) and make sure Orca is up:\n\n   ```bash\n   cd ~\u002Fcode\u002Fmy-project\n   orca repo add .        # skip if already Orca-managed\n   orca status --json     # runtime.state should be \"ready\"; otherwise `orca open`\n   ```\n\n2. **Start the viewer** from that same directory and leave it running:\n\n   ```bash\n   npx orca-dag           # installs the skill into your agents, serves :8787, opens the browser\n   ```\n\n3. **Plan in your agent.** In Claude Code (or any agent that just got the skill), describe what you want and ask for a DAG:\n\n   > Use the orca-dag skill: break \"add CSV export to the reports page\" into a task DAG.\n\n   The agent will ask a few clarifying questions, write `docs\u002FPRD.md` \u002F `docs\u002FTECH_SPEC.md`, then run `orca orchestration run-create` + `task-create --deps …`. When it's done it tells you the **Run id** (like `run_ab12cd34ef56`).\n\n4. **Pick the Run** the agent just named in the top-bar dropdown. The DAG appears and refreshes every 2 seconds — you can keep chatting with the agent to reshape it and watch nodes pop in live.\n\n5. **Choose harnesses.** Set the toolbar's **Default harness** (fallback for every node), and optionally click individual nodes to override harness\u002Fmodel per node. Set **Max parallel**.\n\n6. **Click \"▶ Run with Orca\"** and accept the confirmation (it explains that the viewer takes over the Run's coordinator slot, fencing your agent's terminal — that's expected). Ready tasks fire in parallel; running nodes get the crayon scribble; the graph advances as workers report `worker_done`.\n\n7. **Resolve gates when they pop.** If the plan includes approval gates, approve\u002Freject buttons float over the DAG at the right moment.\n\n8. **Change the plan?** Go back to the agent conversation. It reclaims the Run with `orca orchestration run-use --id \u003Crun>` (or just opens a fresh Run and redraws), and the viewer follows along. Then hit Run again.\n\n## What the viewer can do\n\n- **Live DAG visualization** — node statuses `pending \u002F ready \u002F dispatched \u002F completed \u002F failed \u002F blocked` map to colors; each node wears its harness on its corner.\n- **Switchable layout algorithms**: the \"Layout\" segment in the toolbar toggles **layered horizontal \u002F vertical** (dagre \u002F Sugiyama) and **force-directed** (Fruchterman–Reingold); **↻ Re-layout** reruns auto-layout (clearing manual drags). The choice persists.\n- **Drag to arrange**: nodes drag freely and hold their positions across live polling refreshes (only untouched nodes follow auto-layout).\n- **Execution animations**: `dispatched` (running) nodes get scribbled over and over with diagonal crayon strokes; edges flowing out of a running node start as a swimming dashed draft, then pencil strokes trace them solid toward the downstream node.\n- **Per-node harness**: click a node and pick `claude \u002F kimi \u002F opencode \u002F grok \u002F codex` or a custom command in its panel (persisted to the workspace's `.orca-dag.config.json`); nodes without an explicit choice fall back to the toolbar's **default harness**.\n- **Per-node model override**: for harnesses that support it — opencode gets a dropdown enumerated from `opencode models`; claude \u002F codex \u002F cursor get free-text (passed via `worker-start --model`). Others run on their default model.\n- **▶ Run with Orca \u002F ⏹ Stop** + **Max parallel**: start\u002Fstop the viewer's built-in self-driven coordinator; worker count follows the DAG's parallelism (whatever is ready runs together, capped by \"Max parallel\"), spun up on demand, reused while idle, reclaimed when done — **no manual worker management**. While running it shows \"N workers\".\n- **Approval gates**: after the agent runs `gate-create`, approve\u002Freject buttons float over the DAG.\n- **Node details (read-only spec)**: click a node to see its spec \u002F status \u002F result. To change the spec or deps, have the agent redraw the DAG.\n- **Hand-drawn crayon style**: 🖍️ SVG feTurbulence wobbled strokes on a cream sketchbook canvas.\n\n## HTTP API\n\n| Method | Path | Purpose |\n| --- | --- | --- |\n| `GET` | `\u002Fapi\u002Fdag?run=\u003Cid>` | The Run's DAG: `{ runId, nodes, edges, gates, generatedAt }` |\n| `GET` | `\u002Fapi\u002Fruns` | List orchestration Runs |\n| `POST` | `\u002Fapi\u002Fruns` | `{ objective }`: create a Run (via a throwaway coordinator terminal) |\n| `GET` | `\u002Fapi\u002Fterminals` | List Orca terminals |\n| `POST` | `\u002Fapi\u002Frun` | `{ runId, harnessByTask?, modelByTask?, defaultHarness?, maxConcurrency? }`: start the self-driven coordinator |\n| `POST` | `\u002Fapi\u002Frun-stop` | Stop the coordinator and reclaim its workers |\n| `GET` | `\u002Fapi\u002Frun-status` | Live coordinator status: `{ running, busy, attempts, error, … }` |\n| `POST` | `\u002Fapi\u002Fgates\u002F:id\u002Fresolve` | `{ resolution, runId }`: resolve an approval gate |\n| `POST` | `\u002Fapi\u002Freset` | `{ confirmAllRuns: true }`: `orca orchestration reset --tasks` — clears tasks in **all** Runs |\n| `GET` | `\u002Fapi\u002Fmodels\u002F:harness` | Models selectable for a harness (currently only opencode enumerates) |\n| `GET` | `\u002Fapi\u002Fconfig` | Viewer config (harness\u002Fmodel choices, max parallel, layout, last Run), stored in the workspace's `.orca-dag.config.json` |\n| `PUT` | `\u002Fapi\u002Fconfig` | Merge-write the viewer config |\n| `GET` | `\u002Fapi\u002Fhealth` | Health check (returns the workspace directory) |\n\n## Code layout\n\n```\nskill\u002FSKILL.md            graph-building conventions + spec-writing rules + how execution works + boundaries\nserver\u002Fsrc\u002F\n  index.ts                Express: dag \u002F runs \u002F run \u002F run-stop \u002F run-status \u002F gates \u002F reset \u002F models \u002F config; serves the SPA\n  coordinator.ts          self-driven coordinator loop: polls the DAG, fires ready tasks in parallel via worker-start\n  orca.ts                 orca CLI wrapper: task-list→DAG, worker-start\u002Flegacy\u002Fopencode workers, gates, terminals, models\n  config.ts               viewer config persistence: .orca-dag.config.json in the workspace (\u002Fapi\u002Fconfig)\n  skill.ts                installs skill\u002FSKILL.md into the agents on this machine, on startup\n  uninstall.ts            `orca-dag uninstall`: the exact mirror of skill.ts, plus stale-terminal cleanup\n  webAssets.ts            loader for the frontend assets (and the skill) embedded at build time\nweb\u002Fsrc\u002F\n  App.tsx                 full-width DAG shell, 2s polling, hand-drawn SVG filter defs\n  components\u002FDagView.tsx     React Flow graph + status nodes (harness label, crayon animations)\n  components\u002FExecControls.tsx default harness + max parallel + Run\u002FStop + live status\n  components\u002FNodePanel.tsx    node details + per-node harness & model pickers\n  components\u002FGatePanel.tsx    approval-gate overlay\n  components\u002FRunPicker.tsx    Run selector + \"New Run\"\n  components\u002FDoodleSelect.tsx hand-drawn select (portal dropdown, search, keyboard nav)\n  harness.ts                reactive config store: per-node harness\u002Fmodel, default, max parallel, layout (persisted via \u002Fapi\u002Fconfig)\n  layout.ts                 layout algorithms: dagre layered (LR\u002FTB) + force-directed (Fruchterman–Reingold)\n  types.ts \u002F api.ts\nscripts\u002F\n  build-binary.mjs        vite build → embed assets + skill → bun --compile → dist\u002Forca-dag\n  build-npm.mjs           vite build → esbuild the server → dist-npm\u002F (the publishable `orca-dag` package)\n  build-all-binaries.sh   every Bun target + archives + checksums (what the release workflow runs)\n  check-skill.mjs         guards SKILL.md's frontmatter, which the skills CLI installs by\n  release.mjs             `npm run release \u003Cversion>`: checks, tags, pushes — CI does the rest\n```\n\n## Design notes and boundaries\n\n- **The brain lives outside**: planning is done by the agent you already have (the skill provides the conventions); the viewer embeds no Claude Agent SDK.\n- **The viewer is its own coordinator**: Orca deliberately ships no scheduler, so `server\u002Fsrc\u002Fcoordinator.ts` drives the loop with Orca's Run\u002FTask\u002FDispatch primitives. Parallelism follows the DAG (everything ready fires together, capped by `maxConcurrency`); workers are spun up on demand, reused while idle, reclaimed at the end.\n- **Workers must be autonomous agents**: hands-off execution requires the worker to run `orca orchestration send --type worker_done` on its own — otherwise it stalls on a permission prompt. `worker-start` launches Orca-configured TUI agents with their autonomous flags; for custom commands the legacy path uses `HARNESS_LAUNCH` in `orca.ts` (only `claude --dangerously-skip-permissions` is verified — add and verify flags for others before relying on them).\n- **The `dispatch --inject` quirk** (legacy path): it types the preamble into the agent's input box but often **doesn't submit it** (a readiness race). The coordinator waits ~2s after dispatch and sends an extra Enter; a stray Enter on already-submitted input is a harmless no-op.\n- **opencode goes through its own path**: `worker-start --agent opencode` opens the TUI but the injected preamble never lands, so the coordinator opens a bare shell, mints a tracking dispatch, and runs `opencode run --auto \"$(cat \u003Cpreamble>)\"` (`--auto` is mandatory — the default permission policy silently auto-rejects tool calls).\n- **Per-node harness\u002Fmodel live in a workspace config file**: Orca tasks have no harness\u002Fmetadata field (`task-create` only takes spec\u002Ftitle\u002Fdisplay-name\u002Fdeps\u002Fparent), so the viewer stores harness and model choices, max parallel, and layout in `.orca-dag.config.json` at the workspace root (`server\u002Fsrc\u002Fconfig.ts`, `GET\u002FPUT \u002Fapi\u002Fconfig`) — surviving browser switches and cleared localStorage. The frontend's `harness.ts` is a reactive store that hydrates from the server and migrates old localStorage values once. At Run time the choices are passed to the backend as `harnessByTask` \u002F `modelByTask`.\n- **Created tasks can't be edited**: `orca orchestration task-update` only changes `--status` \u002F `--result` — **no interface to edit spec\u002Ftitle\u002Fdeps**, and no single-task delete (`reset` clears everything, across all Runs). So \"change a task\" = **have the agent redraw the DAG in a fresh Run**.\n","Orca-Orchestration 是一个面向 Orca 1.4.160+ 的轻量级 DAG 编排可视化与执行系统，将任务规划（由外部大模型代理完成）与图构建、调度执行解耦。核心包含两部分：skill 模块指导 LLM（如 Claude、Kimi）按规范生成 Orca 兼容的有向无环图（DAG）；viewer 模块提供 Web 界面实时渲染 DAG，支持为每个节点独立指定执行引擎（harness）和模型，并基于依赖关系并行调度自治 worker 执行任务。项目不内置调度器，完全复用 Orca 原生命令原语（task-create \u002F gate-* \u002F dispatch），适用于需灵活编排多模型协同、强调人机协作规划与可观察执行的 AI 工作流场景。",2,"2026-08-13 02:30:03","CREATED_QUERY"]