orc-ai 0.1.27 → 0.1.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/README.md +827 -742
  2. package/dist/index.js +377 -353
  3. package/dist/web/assets/FileEditor-BL6Ktjgt.js +1 -0
  4. package/dist/web/assets/SourceEditor-DR6ZsCvb.js +43 -0
  5. package/dist/web/assets/{abnfDiagram-VCTEODGH-BZcYG-iC.js → abnfDiagram-VCTEODGH-BoMZOsal.js} +1 -1
  6. package/dist/web/assets/arc-CP0H0HkE.js +1 -0
  7. package/dist/web/assets/{architectureDiagram-5GKGNRK7-Deau1CnS.js → architectureDiagram-5GKGNRK7-CLIC4R3M.js} +2 -2
  8. package/dist/web/assets/{blockDiagram-I7D4REHJ-DdeN1R4g.js → blockDiagram-I7D4REHJ-CdWBkS7i.js} +4 -4
  9. package/dist/web/assets/{c4Diagram-7LVT6UL2-BXUhMF0B.js → c4Diagram-7LVT6UL2-BZEprxck.js} +1 -1
  10. package/dist/web/assets/channel-BdSvgmGU.js +1 -0
  11. package/dist/web/assets/{chunk-2Q5K7J3B-BLoZFafw.js → chunk-2Q5K7J3B-DSKyLqgX.js} +1 -1
  12. package/dist/web/assets/{chunk-5VM5RSS4-Cx9w9ngg.js → chunk-5VM5RSS4-BU5Ia_Zx.js} +1 -1
  13. package/dist/web/assets/{chunk-F27PBJKO-BE8_lbru.js → chunk-F27PBJKO-BO46jCzc.js} +1 -1
  14. package/dist/web/assets/{chunk-IMKFNOWR-vX57Bl8x.js → chunk-IMKFNOWR-DXVUP8VZ.js} +1 -1
  15. package/dist/web/assets/{chunk-JWPE2WC7-D5vSfVV_.js → chunk-JWPE2WC7-DPovEURl.js} +1 -1
  16. package/dist/web/assets/{chunk-POPQ4Y6H-CotVuYSO.js → chunk-POPQ4Y6H-BAjXk_cY.js} +1 -1
  17. package/dist/web/assets/{chunk-SVP7TREG-Bxy_Tzlx.js → chunk-SVP7TREG-BbmgDsVa.js} +3 -3
  18. package/dist/web/assets/{chunk-TICWLB2K-TC-9gGOR.js → chunk-TICWLB2K-D__yk3_8.js} +2 -2
  19. package/dist/web/assets/chunk-XXDRQBXY-B2CkQoJH.js +1 -0
  20. package/dist/web/assets/classDiagram-ZZMXUADV-CIE_hUlo.js +1 -0
  21. package/dist/web/assets/classDiagram-v2-VYDZK3BY-CIE_hUlo.js +1 -0
  22. package/dist/web/assets/{cose-bilkent-JH36ORCC-ZbKk1HeP.js → cose-bilkent-JH36ORCC-DBIetk9t.js} +1 -1
  23. package/dist/web/assets/{cynefin-OW5HDTMX-2qxNDd_u.js → cynefin-OW5HDTMX-CURzzcAU.js} +1 -1
  24. package/dist/web/assets/cynefinDiagram-5FMLGOSQ-CWaHfsZ-.js +62 -0
  25. package/dist/web/assets/{dagre-GXQ25YYZ-XbgrIiHV.js → dagre-GXQ25YYZ-CMP7VfLG.js} +2 -2
  26. package/dist/web/assets/{diagram-S7CK7UJ4-BfIJFBFB.js → diagram-S7CK7UJ4-DIrD-ND8.js} +5 -5
  27. package/dist/web/assets/{diagram-UQ7AKVKN-rmKNaWf9.js → diagram-UQ7AKVKN-Ck0KfTY6.js} +2 -2
  28. package/dist/web/assets/{diagram-VSXAHHWV-D1pOTYJi.js → diagram-VSXAHHWV-C668Qsg6.js} +3 -3
  29. package/dist/web/assets/{diagram-VX7I27RA-BrlxRNh0.js → diagram-VX7I27RA-C2aDctm_.js} +1 -1
  30. package/dist/web/assets/{diagram-Z3DM3KII-BI62GsPT.js → diagram-Z3DM3KII-Bz5EjVft.js} +2 -2
  31. package/dist/web/assets/{ebnfDiagram-PWID7BFC-ZNs-bvLw.js → ebnfDiagram-PWID7BFC-CwPUwbvM.js} +1 -1
  32. package/dist/web/assets/{erDiagram-RLTQ6QDP-Ci2p-DGR.js → erDiagram-RLTQ6QDP-DcDsk0Et.js} +1 -1
  33. package/dist/web/assets/{flowDiagram-HODETNUW-DqX8CjAg.js → flowDiagram-HODETNUW-DiqmTcf8.js} +4 -4
  34. package/dist/web/assets/{ganttDiagram-EL5Y4UJY-DfkXA8Dp.js → ganttDiagram-EL5Y4UJY-C5yVxABI.js} +4 -4
  35. package/dist/web/assets/{gitGraphDiagram-WWUBYQGX-CtJQtSWb.js → gitGraphDiagram-WWUBYQGX-CskKB9_l.js} +2 -2
  36. package/dist/web/assets/highlighted-body-KPVGNVTW-FCmuFog7.js +1 -0
  37. package/dist/web/assets/index-B71tZPcx.css +1 -0
  38. package/dist/web/assets/index-CLW6N7v0.js +1199 -0
  39. package/dist/web/assets/infoDiagram-27XIBGKW-DA3uyi09.js +2 -0
  40. package/dist/web/assets/{ishikawaDiagram-5VMMS53U-CTwYh2p6.js → ishikawaDiagram-5VMMS53U-sq0Y-reT.js} +4 -4
  41. package/dist/web/assets/{journeyDiagram-3NMN7TZE-BNwk2_MG.js → journeyDiagram-3NMN7TZE-sZFnrITK.js} +1 -1
  42. package/dist/web/assets/{kanban-definition-UXKFOSKX-DXIu-uEr.js → kanban-definition-UXKFOSKX-DFA61kHr.js} +7 -7
  43. package/dist/web/assets/{layout-ffjEa2Yj.js → layout-DWH3Uq0C.js} +1 -1
  44. package/dist/web/assets/{linear-UbIh7yUR.js → linear-CVvCYiAa.js} +1 -1
  45. package/dist/web/assets/{mindmap-definition-YA3MSWOX-C_lDiKCI.js → mindmap-definition-YA3MSWOX-DIxw7PIJ.js} +5 -5
  46. package/dist/web/assets/{pegDiagram-XKGWAZYB-Cka9_nNI.js → pegDiagram-XKGWAZYB-D3My9y4e.js} +1 -1
  47. package/dist/web/assets/pieDiagram-E7YTZNPT-vnthudhw.js +39 -0
  48. package/dist/web/assets/{quadrantDiagram-AXDQQJYC-C1UuMU0A.js → quadrantDiagram-AXDQQJYC-seZjV8O_.js} +1 -1
  49. package/dist/web/assets/{railroadDiagram-O6MQD6OU-XXwtE8TR.js → railroadDiagram-O6MQD6OU-7x7EOXeC.js} +1 -1
  50. package/dist/web/assets/{requirementDiagram-BXWQKSXE-615jkgQK.js → requirementDiagram-BXWQKSXE-dZqOaHAk.js} +4 -4
  51. package/dist/web/assets/{sankeyDiagram-P5KCCOFB--LD6L7HP.js → sankeyDiagram-P5KCCOFB-dtJDUnaJ.js} +4 -4
  52. package/dist/web/assets/{sequenceDiagram-WJ2MYXX4-CaLUT_fe.js → sequenceDiagram-WJ2MYXX4-BmHbHxOy.js} +4 -4
  53. package/dist/web/assets/{sizeCapture-INFHLROL-Djenag-S.js → sizeCapture-INFHLROL-_2CYTyhb.js} +1 -1
  54. package/dist/web/assets/{stateDiagram-D77RDMKH-YAExcKJV.js → stateDiagram-D77RDMKH-ByjPSYC_.js} +1 -1
  55. package/dist/web/assets/stateDiagram-v2-MP3YSRHH-BWLm_iOS.js +1 -0
  56. package/dist/web/assets/{swimlanes-42K2YHIH-CGAIEddU.js → swimlanes-42K2YHIH-Bxbb2UGA.js} +1 -1
  57. package/dist/web/assets/swimlanesDiagram-VR7AAH4N-DALKgwME.js +8 -0
  58. package/dist/web/assets/{timeline-definition-24CTP7MA-CT78C35h.js → timeline-definition-24CTP7MA-x9B0Tgt0.js} +1 -1
  59. package/dist/web/assets/{vennDiagram-4TSXK5OY-B1z8IPmG.js → vennDiagram-4TSXK5OY-DHRMXqJX.js} +5 -5
  60. package/dist/web/assets/{wardleyDiagram-VM6X3IG4-5TKV-HFu.js → wardleyDiagram-VM6X3IG4-D8X0bsKw.js} +4 -4
  61. package/dist/web/assets/{xychartDiagram-S5SC5T6Z-B6ZEwvPc.js → xychartDiagram-S5SC5T6Z-Ch__ZmFS.js} +5 -5
  62. package/dist/web/index.html +19 -19
  63. package/package.json +85 -85
  64. package/dist/web/assets/arc-DP3fJSQz.js +0 -1
  65. package/dist/web/assets/channel-XjZO-4Qv.js +0 -1
  66. package/dist/web/assets/chunk-XXDRQBXY-BittVEpq.js +0 -1
  67. package/dist/web/assets/classDiagram-ZZMXUADV-BV2GFuX-.js +0 -1
  68. package/dist/web/assets/classDiagram-v2-VYDZK3BY-BV2GFuX-.js +0 -1
  69. package/dist/web/assets/cynefinDiagram-5FMLGOSQ-BMVEqfdz.js +0 -62
  70. package/dist/web/assets/highlighted-body-KPVGNVTW-DpebT0da.js +0 -1
  71. package/dist/web/assets/index-B5424mqm.js +0 -981
  72. package/dist/web/assets/index-S_So-SjJ.css +0 -1
  73. package/dist/web/assets/infoDiagram-27XIBGKW-BdXvz-zM.js +0 -2
  74. package/dist/web/assets/pieDiagram-E7YTZNPT-CpT-wtNQ.js +0 -39
  75. package/dist/web/assets/stateDiagram-v2-MP3YSRHH-DMdKY5eZ.js +0 -1
  76. package/dist/web/assets/swimlanesDiagram-VR7AAH4N-Dwrn9eHg.js +0 -8
package/README.md CHANGED
@@ -1,742 +1,827 @@
1
- <div align="center">
2
-
3
- # orc
4
-
5
- **Multi-agent orchestrator with human-in-the-loop review**
6
-
7
- [![npm version](https://img.shields.io/npm/v/orc-ai?style=flat-square)](https://www.npmjs.com/package/orc-ai)
8
- [![License: MIT](https://img.shields.io/badge/license-MIT-blue?style=flat-square)](LICENSE)
9
- ![Bun](https://img.shields.io/badge/Bun-%3E%3D1.1-f472b6?style=flat-square&logo=bun&logoColor=white)
10
- ![TypeScript](https://img.shields.io/badge/TypeScript-strict-3178c6?style=flat-square&logo=typescript&logoColor=white)
11
-
12
- One SQLite file. One CLI. Any agent.<br>
13
- ORC coordinates Claude Code, Cursor, Codex, Gemini, and remote A2A agents through a shared task board, persistent memory, and a review flow that keeps you in control.
14
-
15
- <img src="assets/Architecture.gif" alt="ORC Architecture" width="700" />
16
-
17
- </div>
18
-
19
- ## Overview
20
-
21
- Every AI agent session is an island. Start a new session and it knows nothing about the last one. Run two in parallel and they can't coordinate. Switch agents and you start from zero.
22
-
23
- ORC fixes this. Shared memory across every session. A task board where agents submit work and you approve it. A scheduler that runs agents on a cron. All backed by a single SQLite file - no cloud, no account, no subscription.
24
-
25
- ### Key features
26
-
27
- | Feature | What it does |
28
- | ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
29
- | **Agent orchestration** | Task loop spawns workers across backends (Claude Code, Codex, Gemini, Copilot, A2A), manages concurrency and review cycles |
30
- | **Human-in-the-loop** | Agents submit work for your approval via CLI, Telegram, or Slack before anything lands |
31
- | **Shared memory** | Decisions, rules, and discoveries stored once, searchable by any session via ranked full-text search |
32
- | **Task board** | `todo → queued → doing → review → done` with dependency tracking, priority, and automatic unblocking |
33
- | **Multi-backend routing** | Route to Claude (in-process, nothing to install), ACPX (14+ agents), agentapi, or remote A2A endpoints — with `orc doctor` reporting which are usable |
34
- | **Job runner** | Cron, file-watch, webhook, or manual triggers with full run history |
35
- | **MCP server** | 34 tools connect any [Model Context Protocol](https://modelcontextprotocol.io) (MCP) compatible agent — stdio or Streamable HTTP |
36
- | **Session continuity** | Snapshots survive context compaction so agents resume where they left off |
37
- | **Gateway** | Approve work, search memory, and chat with live agents from Telegram or Slack |
38
- | **Knowledge search** | Index document collections (markdown, notes, wikis) and search them via BM25 or hybrid (vector + reranking) |
39
- | **Skill library** | Discoverable workflow templates (coder, reviewer, planner, bugfix) that encode your standards |
40
- | **Task flows** | Per-task graphs: conditional edges, bounded loops, parallel fan-out with joins, and human gates — with hard termination rails |
41
-
42
- ## Getting started
43
-
44
- ### Prerequisites
45
-
46
- - [Bun](https://bun.sh) >= 1.1
47
-
48
- ### Install
49
-
50
- ```bash
51
- npm install -g orc-ai
52
- ```
53
-
54
- <details>
55
- <summary>Other installation methods</summary>
56
-
57
- #### Pre-built binaries
58
-
59
- Download from [GitHub Releases](https://github.com/niradler/orc/releases):
60
-
61
- ```bash
62
- # macOS (Apple Silicon)
63
- curl -L https://github.com/niradler/orc/releases/latest/download/orc-mac-arm64 -o /usr/local/bin/orc && chmod +x /usr/local/bin/orc
64
-
65
- # macOS (Intel)
66
- curl -L https://github.com/niradler/orc/releases/latest/download/orc-mac-x64 -o /usr/local/bin/orc && chmod +x /usr/local/bin/orc
67
-
68
- # Linux (x64)
69
- curl -L https://github.com/niradler/orc/releases/latest/download/orc-linux-x64 -o /usr/local/bin/orc && chmod +x /usr/local/bin/orc
70
-
71
- # Linux (ARM64)
72
- curl -L https://github.com/niradler/orc/releases/latest/download/orc-linux-arm64 -o /usr/local/bin/orc && chmod +x /usr/local/bin/orc
73
-
74
- # Windows - download orc-windows-x64.exe from the release page and add to PATH
75
- ```
76
-
77
- #### From source
78
-
79
- ```bash
80
- git clone https://github.com/niradler/orc
81
- cd orc && bun install && bun build
82
- ```
83
-
84
- </details>
85
-
86
- ### Quick start
87
-
88
- ```bash
89
- # 1. Start the daemon - runs the REST API on :7700, task loop, job scheduler, gateway, and web UI
90
- orc daemon start
91
-
92
- # 2. Create a project
93
- orc project add my-app -d "My application"
94
- orc project use my-app
95
-
96
- # 3. Add tasks and memories - everything auto-scopes to my-app
97
- orc task add "Fix the auth bug" --priority high
98
- orc mem add "Use RWMutex for token refresh" --type decision
99
- orc job add nightly --command "bun run test" --trigger cron --cron "0 22 * * *"
100
-
101
- # 4. See everything
102
- orc status
103
- orc task list
104
- ```
105
-
106
- Open `http://localhost:7700` to use the web dashboard - task board, kanban, flow runs, jobs, memories, sessions, knowledge, and a live chat panel. The same server hosts both the REST API and the prebuilt React SPA, so there is no separate command to run for the UI.
107
-
108
- > [!TIP]
109
- > The database is created automatically at `~/.orc/orc.db` on first run. No setup needed.
110
-
111
- ### Web dashboard
112
-
113
- The web dashboard ships inside the `orc` binary and is served by the API process at the root path. REST routes live under `/api/<route>` - the SDK, CLI and MCP clients add that prefix themselves - which leaves the root path free for the SPA.
114
-
115
- | Route | Served from |
116
- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
117
- | `GET /` | `index.html` (web SPA shell) |
118
- | `GET /assets/*` | Built JS/CSS bundles |
119
- | `GET /api/*` | All REST routes |
120
- | `GET /openapi.json`, `GET /docs` | Swagger UI |
121
- | `GET /mcp` | MCP server (streamable HTTP) |
122
- | `GET /tasks/<id>`, `/flows/<name>`, … | `index.html` again - a navigation request matching no static file falls back to the SPA shell, so dashboard links are shareable |
123
-
124
- Override the served dist directory with `ORC_WEB_DIST=/path/to/web/dist` if you want to host a custom build (e.g. a fork). If no dist is found, the server runs in pure-API mode.
125
-
126
- ## Docker
127
-
128
- Run ORC in a container with the published image:
129
-
130
- ```bash
131
- docker run -d --name orc \
132
- -p 7700:7700 \
133
- -v orc-data:/data \
134
- -e ORC_API_SECRET=$(openssl rand -hex 32) \
135
- -e ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY \
136
- niradler/orc:latest
137
- ```
138
-
139
- > The container binds `0.0.0.0`. Set a strong `ORC_API_SECRET` before exposing the
140
- > mapped port beyond localhost — without it, every endpoint (including job execution,
141
- > which runs arbitrary shell commands) is open to anyone who can reach the port.
142
-
143
- Or with [docker-compose.yml](docker-compose.yml):
144
-
145
- ```bash
146
- docker compose up -d
147
- ```
148
-
149
- The container defaults to the `claude` backend (direct Anthropic API via SDK — no host CLI needed). To delegate to an agent running on the host instead, set `ORC_AGENT_LOOP_DEFAULT_BACKEND=agentapi` and run [coder/agentapi](https://github.com/coder/agentapi) on the host:
150
-
151
- ```bash
152
- agentapi server --allowed-hosts '*' -- \
153
- claude --allowedTools all \
154
- --mcp-config '{"mcpServers":{"orc":{"type":"http","url":"http://localhost:7700/mcp"}}}'
155
- ```
156
-
157
- The `--mcp-config` flag wires the host agent back to ORC's [HTTP MCP endpoint](#mcp-tools) so it can call `task_update`, `memory_*`, `knowledge_*`, etc. `host.docker.internal` lets the container reach agentapi on the host.
158
-
159
- ## Connect your agent
160
-
161
- ### Claude Code
162
-
163
- Add to `~/.claude/settings.json`:
164
-
165
- ```json
166
- {
167
- "hooks": {
168
- "PostToolUse": [
169
- {
170
- "matcher": "Write|Edit|MultiEdit|StrReplace|EditNotebook|Bash|Shell|Agent|EnterPlanMode|ExitPlanMode|mcp__orc__task_|mcp__orc__memory_store|mcp__orc__memory_delete|mcp__orc__job_run|mcp__orc__job_create|mcp__orc__job_update",
171
- "hooks": [
172
- {
173
- "type": "command",
174
- "command": "bun /path/to/orc/hooks/post-tool-use.ts"
175
- }
176
- ]
177
- }
178
- ],
179
- "PreCompact": [
180
- {
181
- "matcher": "",
182
- "hooks": [
183
- {
184
- "type": "command",
185
- "command": "bun /path/to/orc/hooks/pre-compact.ts"
186
- }
187
- ]
188
- }
189
- ],
190
- "SessionStart": [
191
- {
192
- "matcher": "",
193
- "hooks": [
194
- {
195
- "type": "command",
196
- "command": "bun /path/to/orc/hooks/session-start.ts"
197
- }
198
- ]
199
- }
200
- ]
201
- },
202
- "env": { "ORC_API_BASE": "http://127.0.0.1:7700", "ORC_PROJECT": "" }
203
- }
204
- ```
205
-
206
- > [!NOTE]
207
- > Replace `/path/to/orc/` with the path to your ORC clone or the installed package location (run `npm root -g` to find global installs). Hooks handle session events and snapshots automatically.
208
-
209
- ### Cursor
210
-
211
- Add to `.cursor/mcp.json`:
212
-
213
- ```json
214
- {
215
- "mcpServers": {
216
- "orc": {
217
- "command": "orc",
218
- "args": ["mcp"],
219
- "env": {
220
- "ORC_API_BASE": "http://127.0.0.1:7700",
221
- "ORC_SESSION_ID": "cursor"
222
- }
223
- }
224
- }
225
- }
226
- ```
227
-
228
- <details>
229
- <summary>Codex, Gemini CLI, and other MCP agents</summary>
230
-
231
- **Codex** - Copy `hooks/codex/settings.json` to `~/.codex/settings.json` and update the path.
232
-
233
- **Gemini CLI / any MCP agent** - Add to your MCP config:
234
-
235
- ```json
236
- {
237
- "mcpServers": {
238
- "orc": {
239
- "command": "orc",
240
- "args": ["mcp"],
241
- "env": {
242
- "ORC_API_BASE": "http://127.0.0.1:7700",
243
- "ORC_SESSION_ID": "gemini"
244
- }
245
- }
246
- }
247
- }
248
- ```
249
-
250
- </details>
251
-
252
- ## Usage
253
-
254
- ### How agents use ORC
255
-
256
- ```
257
- 1. Agent starts → context() returns active tasks + key memories
258
- 2. Agent works → creates tasks, stores decisions, records events
259
- 3. Agent submits work → task_update(status: "review", comment: "summary")
260
- 4. You review → approve or request changes via CLI / Telegram / Slack
261
- 5. Agent continues → picks up next task or resumes with feedback
262
- 6. Session ends → session_log() records what happened
263
- ```
264
-
265
- When a context window fills up, `session_snapshot` captures current state into a compact 2KB blob that `session_restore` injects back after compaction - the agent picks up where it left off.
266
-
267
- ### Agent orchestration
268
-
269
- The task loop automatically picks up queued tasks and spawns worker agents:
270
-
271
- ```bash
272
- # Create a task with a workflow and backend
273
- orc task add "Implement user auth" --skill orc-coder --backend claude --priority high
274
-
275
- # Or batch-create with dependencies via MCP
276
- task_batch_create({ tasks: [
277
- { title: "Design schema", skill_name: "orc-planner" },
278
- { title: "Implement API", skill_name: "orc-coder", blocked_by: [0] },
279
- { title: "Review code", skill_name: "orc-reviewer", blocked_by: [1] }
280
- ]})
281
- ```
282
-
283
- The loop handles concurrency, session resume on feedback, review round limits, stale claim cleanup, and backend routing.
284
-
285
- Every task runs a **flow graph** (see [Task flows](#task-flows)); `orc-default` is the build → review → done pipeline described above.
286
-
287
- #### Agent backends
288
-
289
- | Backend | Needs |
290
- | --------------- | ------------------------------------------------------------------------------------------------------------ |
291
- | `claude` | Nothing to install: runs **in-process** via [@anthropic-ai/claude-agent-sdk](https://www.npmjs.com/package/@anthropic-ai/claude-agent-sdk), which ships with orc. Uses the Claude Code CLI's stored credentials, or `ANTHROPIC_API_KEY`. The default. |
292
- | `acpx` | The [ACP CLI](https://github.com/openclaw/acpx) — 14+ agents (Codex, Gemini, Copilot, Kiro, Cursor, …). Installed as an optional dependency, so a normal `npm i -g orc-ai` gets it; orc finds it there even when it is not on your `PATH`. Point `ORC_ACPX_PATH` at a specific copy to override. |
293
- | `agentapi` | A [coder/agentapi](https://github.com/coder/agentapi) server on the host (HTTP+SSE), wrapping any local coding agent. `AGENTAPI_URL` if it is not on the default port. |
294
- | `a2a` | A remote [A2A](https://github.com/google/A2A) endpoint, supplied per task/session — nothing local. |
295
- | `claude-cli` | The `claude` binary on `PATH`. The pre-SDK path, kept for when driving the real CLI matters. |
296
- | `codex-cli` | The `codex` binary on `PATH`, driven natively instead of through acpx. |
297
- | _anything else_ | Passed to acpx as its agent name, so `--agent-backend gemini` means "acpx driving gemini". |
298
-
299
- Which of these actually work on a given machine depends on what is installed, so orc probes them rather than making you guess:
300
-
301
- ```bash
302
- orc doctor # per backend: usable or not, what it resolved to, what a missing one needs
303
- orc doctor --json # same, machine-readable
304
- ```
305
-
306
- The dashboard shows the same probe: the agent-backend field on a task is a picker that marks each backend ready or unavailable, and names the one a task with no backend of its own will use. `GET /api/backends` is the endpoint behind both.
307
-
308
- Enable the task loop in `~/.orc/config.json`:
309
-
310
- ```json
311
- {
312
- "agent_loop": {
313
- "enabled": true,
314
- "poll_interval_minutes": 5,
315
- "max_workers": 1,
316
- "default_backend": "claude",
317
- "session_idle_timeout_minutes": 20,
318
- "worker_auto_approve": true,
319
- "default_flow": "orc-default",
320
- "review_flow": "orc-review-only"
321
- }
322
- }
323
- ```
324
-
325
- ### Projects
326
-
327
- Projects group tasks, memories, and jobs. Set an active project and all commands auto-scope:
328
-
329
- ```bash
330
- orc project add my-app -d "Main application"
331
- orc project use my-app # set active
332
-
333
- orc task list # scoped to my-app
334
- orc mem search "auth" # scoped to my-app
335
- orc task list -p infra # override to different project
336
- orc task list --no-project # see everything
337
- ```
338
-
339
- **Resolution order:** explicit `-p <name>` > `activeProject` from config > error
340
-
341
- MCP tools follow the same logic - pass `project: "name"` to scope, or omit to use the active project.
342
-
343
- ### Memory
344
-
345
- Store decisions, conventions, and discoveries that persist across all sessions:
346
-
347
- ```bash
348
- orc mem add "All IDs are ULIDs" --type rule
349
- orc mem add "Use PostgreSQL for concurrent writes" --type decision
350
- orc mem search "authentication"
351
- ```
352
-
353
- | Type | Weight | Use for |
354
- | ----------- | ------ | ----------------------------------------------- |
355
- | `rule` | High | Conventions: "all IDs are ULIDs" |
356
- | `decision` | High | Choices: "use PostgreSQL for concurrent writes" |
357
- | `discovery` | Medium | Findings: "token refresh has a race condition" |
358
- | `event` | Low | Things that happened: "deployed v1.0" |
359
- | `fact` | Low | General knowledge (default) |
360
-
361
- ### Knowledge
362
-
363
- Index existing document collections (markdown, notes, code docs) and make them searchable by any agent. Unlike memory (short agent-authored notes), knowledge searches pre-existing files on disk.
364
-
365
- ```bash
366
- # Add a document collection
367
- orc knowledge add my-docs --path ~/projects/docs --pattern "**/*.md"
368
-
369
- # Search across indexed documents
370
- orc knowledge search "authentication flow"
371
-
372
- # List collections
373
- orc knowledge list
374
-
375
- # Re-index after files change
376
- orc knowledge update
377
- ```
378
-
379
- Knowledge uses [QMD](https://github.com/nicholasgriffintn/qmd) as the search engine. By default it runs BM25 full-text search (no LLM needed). Set `search_mode: "hybrid"` in config for vector search with reranking - embeddings are generated automatically when documents are indexed.
380
-
381
- Collections can be scoped to projects. When scoped, searches and listing filter to only that project's collections.
382
-
383
- **MCP tools:** `knowledge_search`, `knowledge_get`, `knowledge_collections`, `knowledge_collection_add`, `knowledge_collection_remove`, `knowledge_update`
384
-
385
- ### Task status flow
386
-
387
- ```
388
- todo → queued → doing → review → done
389
- │ │
390
- v v
391
- blocked changes_requested → doing
392
- │
393
- v
394
- paused
395
- ```
396
-
397
- Tasks with `required_review: true` (default) need your approval before moving to `done`. Set `max_review_rounds` to auto-pause tasks that cycle through too many revision rounds.
398
-
399
- `queued` means a node is waiting for a worker slot — the task is claimed but nothing is running on it yet, so it counts as pending rather than in progress (the dashboard's board shows it under Todo, labelled `queued`). It becomes `doing` when a session actually starts, which is what keeps the board from showing more work in flight than `agent_loop.max_workers` allows.
400
-
401
- <img src="assets/TaskFlow.gif" alt="Task Flow" width="600" />
402
-
403
- ### Task flows
404
-
405
- That pipeline is not hardcoded — it is a **flow graph** named `orc-default`. A flow is nodes joined by conditional edges that may cycle, so a task can run whatever shape its work actually needs: a plan → build → verify loop, a bug-fix-then-confirm loop, an executor with an independent supervisor, or three reviewers in parallel joined before a decision.
406
-
407
- The graph itself is deterministic; only the nodes are agents. That means loops, branches, and fan-out behave predictably and are fully unit-testable, while the agents just do the work and report a verdict.
408
-
409
- ```bash
410
- orc flow list # what graphs are available
411
- orc flow show orc-plan-build-verify # nodes, edges, limits
412
- orc task add "Fix the flaky test" --flow orc-fix-verify
413
- orc flow status <taskId> # active nodes + the ledger of outcomes
414
- orc flow resume <taskId> --outcome approved # resolve a human gate
415
- orc flow halt <taskId> # stop it and kill live nodes
416
- ```
417
-
418
- | Built-in flow | Shape |
419
- | ----------------------- | ---------------------------------------------------------------------------- |
420
- | `orc-default` | build → review → done, looping back while `max_review_rounds` allows |
421
- | `orc-review-only` | A single review pass for a task you moved straight to `review` |
422
- | `orc-plan-build-verify` | planner → coder → reviewer, looping until acceptance criteria pass |
423
- | `orc-fix-verify` | bugfix → independent confirmation the fix holds and a regression test exists |
424
- | `orc-supervisor` | Executor keeping its context, plus a supervisor re-verifying from a clean one |
425
- | `orc-parallel-review` | Fan out to correctness / security / tests reviewers, join on all three |
426
-
427
- **Nodes** are `agent` (runs a session with a skill), `gate` (deterministic branching, fan-out, join points), `human` (waits for you), or `terminal` (ends the run and sets the task's final status). **Edges** carry declarative conditions — `outcome`, `visits`, `var`, `elapsed_secs`, composed with `all`/`any`/`not` — which are data, never evaluated code.
428
-
429
- Loops always terminate. Per-node `max_visits`, a per-run node-execution budget, a wall clock, plus deadlock and stall detection each halt the run and hand the task back to you with an explanation of which rail tripped.
430
-
431
- #### Custom graphs per task
432
-
433
- For work no named flow fits, attach a bespoke graph to a single task:
434
-
435
- ```bash
436
- orc flow validate --file ./my-graph.json # catch mistakes before running anything
437
- orc flow attach <taskId> --file ./my-graph.json --start
438
- ```
439
-
440
- Definitions are JSON, validated on load: unknown edge targets, unreachable nodes, a graph that can never finish, or an edge shadowed by an earlier catch-all are all rejected up front rather than discovered mid-run. Reusable flows go in `~/.orc/flows/<name>/flow.json` (or `./.orc/flows/` to pin one per repo), and a user flow shadows a built-in of the same name — that is how you customise `orc-default` without patching orc.
441
-
442
- Agents can do all of this themselves via the `flow_list`, `flow_read`, `flow_create`, `flow_attach`, `flow_status`, and `flow_report` MCP tools, so a planner can design the pipeline for the work it just decomposed.
443
-
444
- #### In the web dashboard
445
-
446
- A task's **Flow** section draws the graph the run froze at start next to its ledger: which node is active, the verdict each visit produced, how many visits a node has spent of its budget, per-node timings and errors, a link to each node's agent transcript, and — when a rail tripped — which one and why. Loopbacks are drawn as edges that go backwards, so a rework cycle looks like one.
447
-
448
- When a run parks on a human gate, that panel is where you answer it: pick one of the outcomes the node's own edges can route, add a comment, and the flow continues. `Halt` stops a run and kills its live sessions. The **Flows** page lists every graph available with its source, marks the one a task with no flow of its own will run, shows any definition, and reports flows that failed validation along with the errors — so a broken graph is visible before a task tries to run it.
449
-
450
- ### Jobs
451
-
452
- ```bash
453
- orc job add deploy --command "bun run deploy" --trigger manual
454
- orc job add nightly --command "bun run test" --trigger cron --cron "0 22 * * *"
455
- orc job add on-change --command "bun run lint" --trigger watch --watch "./src"
456
- orc job add on-push --command "bun run ci" --trigger webhook
457
- ```
458
-
459
- ### Gateway (Telegram / Slack)
460
-
461
- Approve agent work from your phone, search memory, or start a live AI session.
462
-
463
- ```json
464
- {
465
- "gateway": {
466
- "telegram": {
467
- "enabled": true,
468
- "token": "7123456789:AAF...",
469
- "authorized_users": [123456789]
470
- }
471
- }
472
- }
473
- ```
474
-
475
- **Commands:** `/status`, `/tasks`, `/approve <id>`, `/reject <id>`, `/jobs`, `/run <name>`, `/mem <query>`, `/agent <claude|codex>`
476
-
477
- > [!TIP]
478
- > Create a Telegram bot via [@BotFather](https://t.me/BotFather) and find your user ID via [@userinfobot](https://t.me/userinfobot).
479
-
480
- <details>
481
- <summary>Slack setup</summary>
482
-
483
- ```json
484
- {
485
- "gateway": {
486
- "slack": {
487
- "enabled": true,
488
- "bot_token": "xoxb-...",
489
- "app_token": "xapp-...",
490
- "authorized_users": ["U01ABCDEF"]
491
- }
492
- }
493
- }
494
- ```
495
-
496
- Same commands as Telegram. Create a Slack app at [api.slack.com/apps](https://api.slack.com/apps) with Socket Mode enabled.
497
-
498
- </details>
499
-
500
- ## Skills
501
-
502
- ORC ships with agent workflow skills and built-in skill templates for the task loop.
503
-
504
- ### Install skills
505
-
506
- ```bash
507
- # Install all ORC skills into your agent
508
- npx skills add niradler/orc --all
509
-
510
- # Or pick specific ones
511
- npx skills add niradler/orc --skill orc-session orc-tasks
512
-
513
- # Global install
514
- npx skills add niradler/orc --all -g
515
- ```
516
-
517
- ### Agent workflow skills
518
-
519
- | Skill | Triggers on |
520
- | --------------- | -------------------------------------------------------------------------- |
521
- | `orc-session` | Session start, context compaction, resuming work |
522
- | `orc-tasks` | Task creation, status updates, HITL review, task decomposition |
523
- | `orc-knowledge` | Storing decisions, searching memory, "remember this", "what did we decide" |
524
- | `orc-gateway` | Telegram/Slack setup, remote approval, live agent sessions |
525
-
526
- ### Built-in skill templates
527
-
528
- Skill templates live in `skills/*/SKILL.md` (built-in) and `~/.orc/skills/` (user-defined). Agents discover them via `skill_list` and load with `skill_read`.
529
-
530
- | Skill | Type | Purpose |
531
- | ------------------ | -------- | --------------------------------------------------------------------------- |
532
- | `orc-worker-base` | Base | Default worker behavior - ORC awareness, status updates, deliverable format |
533
- | `orc-main-base` | Base | Orchestration agent - planning, decomposition, monitoring |
534
- | `orc-coder` | Workflow | Implementation - understand, plan, implement, verify, submit |
535
- | `orc-planner` | Workflow | Task decomposition with dependencies and workflow assignment |
536
- | `orc-reviewer` | Workflow | Structured evaluation - correctness, tests, security, conventions |
537
- | `orc-bugfix` | Workflow | Bug investigation - reproduce, root-cause, fix, regression test |
538
- | `orc-requirements` | Skill | Requirements interview - outcome, criteria, constraints, scope |
539
- | `orc-report` | Skill | Project status report - health summary, blockers, active work |
540
-
541
- Add custom skills by creating a `SKILL.md` in `~/.orc/skills/my-workflow/SKILL.md`.
542
-
543
- ## MCP tools
544
-
545
- **34 tools** available to any connected agent. Start every session with `context`.
546
-
547
- | Category | Tools |
548
- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
549
- | **Project** | `project_list` |
550
- | **Memory** | `context`, `memory_search`, `memory_get`, `memory_store`, `memory_update` |
551
- | **Task** | `task_list`, `task_get`, `task_create`, `task_update`, `task_batch_create` |
552
- | **Skill** | `skill_list`, `skill_read`, `skill_create` |
553
- | **Flow** | `flow_report`, `flow_status`, `flow_list`, `flow_read`, `flow_create`, `flow_attach` |
554
- | **Knowledge** | `knowledge_search`, `knowledge_get`, `knowledge_collections`, `knowledge_collection_add`, `knowledge_collection_remove`, `knowledge_update` |
555
- | **Search** | `search` |
556
- | **Job** | `job_list`, `job_run`, `job_status` |
557
- | **Session** | `session_event`, `session_snapshot`, `session_restore`, `session_log` |
558
-
559
- ## REST API
560
-
561
- Runs on port 7700 with auto-generated OpenAPI spec.
562
-
563
- - **Swagger UI:** `GET /docs`
564
- - **OpenAPI spec:** `GET /openapi.json`
565
-
566
- <details>
567
- <summary>Full endpoint list</summary>
568
-
569
- | Method | Path | Description |
570
- | ----------------------- | ------------------------------ | ------------------------------ |
571
- | `GET` | `/health` | Health check |
572
- | `GET/POST/PATCH/DELETE` | `/projects` | CRUD projects |
573
- | `GET` | `/projects/by-name/{name}` | Lookup by name |
574
- | `GET` | `/projects/{id}/summary` | Task/memory/job counts |
575
- | `GET/POST/PATCH/DELETE` | `/tasks` | CRUD tasks |
576
- | `GET/POST` | `/tasks/{id}/notes` | Task notes |
577
- | `GET/POST/DELETE` | `/tasks/{id}/links` | Task dependencies |
578
- | `GET/POST/DELETE` | `/memories` | CRUD memories |
579
- | `GET` | `/memories/search` | BM25 search |
580
- | `GET` | `/knowledge/search` | Search documents (BM25/hybrid) |
581
- | `GET` | `/knowledge/documents/{id}` | Get document by docid |
582
- | `GET/POST/DELETE` | `/knowledge/collections` | CRUD collections |
583
- | `POST` | `/knowledge/update` | Re-index collections |
584
- | `GET` | `/knowledge/status` | Index status |
585
- | `GET/POST` | `/jobs` | CRUD jobs |
586
- | `POST` | `/jobs/{id}/trigger` | Trigger a job |
587
- | `GET` | `/jobs/{id}/runs` | Run history |
588
- | `GET` | `/jobs/{id}/runs/{runId}/logs` | Run logs |
589
- | `GET` | `/skills` | Skill templates |
590
- | `GET` | `/backends` | Agent backends + usability |
591
- | `GET/POST` | `/flows` | List/create flow graphs |
592
- | `GET` | `/flows/{name}` | Read a flow definition |
593
- | `POST` | `/flows/validate` | Validate without saving |
594
- | `GET/POST` | `/tasks/{id}/flow` | Get a task's run / attach one |
595
- | `POST` | `/tasks/{id}/flow/resume` | Resolve a human node |
596
- | `POST` | `/tasks/{id}/flow/halt` | Stop a running flow |
597
- | `GET` | `/sessions` | Agent session logs |
598
- | `POST` | `/mcp/tool` | Execute any MCP tool via HTTP |
599
-
600
- </details>
601
-
602
- ## CLI reference
603
-
604
- ```
605
- orc daemon start|stop|status Manage the daemon (API + scheduler + gateway)
606
- orc daemon install|uninstall Register/remove auto-start on login/boot
607
- orc api Start the API server only
608
- orc mcp Start the MCP server (stdio)
609
- orc home Show ~/.orc directory and config
610
- orc status Show API health and counts
611
- orc doctor Check which agent backends are usable here
612
-
613
- orc project list|add|show|use|update|archive
614
- orc task list|add|show|update|done|review|approve|reject|delete
615
- orc mem list|add|search
616
- orc job list|add|run|runs
617
- orc session list|show|log
618
- orc skill list|show
619
- orc flow list|show|validate|create|attach|status|resume|halt
620
- orc kb search|get|collections|add|remove|update|status
621
- ```
622
-
623
- > [!NOTE]
624
- > All task/mem/job/kb commands default to the active project. Use `-p <name>` to override or `--no-project` to see everything. Add `--json` for machine-readable output.
625
-
626
- ## Configuration
627
-
628
- ORC merges config in priority order (later wins):
629
-
630
- 1. `~/.orc/config.json` - user global
631
- 2. `./.orc/config.json` - project-local
632
- 3. Environment variables
633
-
634
- <details>
635
- <summary>Environment variables</summary>
636
-
637
- | Variable | Default | Description |
638
- | -------------------------------- | --------------------- | ------------------------------------------------- |
639
- | `ORC_DB_PATH` | `~/.orc/orc.db` | SQLite database path |
640
- | `ORC_API_HOST` | `127.0.0.1` | API listen host (set to `0.0.0.0` in Docker) |
641
- | `ORC_API_PORT` | `7700` | API listen port |
642
- | `ORC_API_SECRET` | - | Bearer token for auth |
643
- | `ORC_TELEGRAM_TOKEN` | - | Enables the Telegram gateway when set |
644
- | `AGENTAPI_URL` | `http://127.0.0.1:3284` | URL of host agentapi server (for `agentapi` backend) |
645
- | `ANTHROPIC_API_KEY` | - | Required for the `claude` backend (Anthropic SDK) |
646
- | `ORC_SESSION_ID` | `default` | Per-agent session identifier |
647
- | `ORC_LOG_LEVEL` | `info` | `debug`, `info`, `warn`, `error` |
648
- | `ORC_LOG_DIR` | `~/.orc/logs` | Log file directory |
649
- | `ORC_LOG_FILE` | `1` | Set to `0` to disable file logging |
650
- | `ORC_RUNNER_TIMEOUT` | `300` | Default job timeout (seconds) |
651
- | `ORC_AGENT_LOOP_ENABLED` | `false` | Enable the agent task loop |
652
- | `ORC_AGENT_LOOP_POLL_INTERVAL` | `5` | Task loop poll interval (minutes) |
653
- | `ORC_AGENT_LOOP_MAX_WORKERS` | `1` | Max concurrent worker agents |
654
- | `ORC_AGENT_LOOP_DEFAULT_BACKEND` | `claude` | Default agent backend |
655
- | `ORC_AGENT_LOOP_IDLE_TIMEOUT` | `20` | Session idle timeout (minutes) |
656
- | `ORC_AGENT_LOOP_AUTO_APPROVE` | `true` | Auto-approve worker tool permissions |
657
- | `ORC_KNOWLEDGE_DB_PATH` | `~/.orc/knowledge.db` | Knowledge search database path |
658
- | `ORC_KNOWLEDGE_SEARCH_MODE` | `lexical` | `lexical` (BM25) or `hybrid` (vector + reranking) |
659
-
660
- </details>
661
-
662
- ### Logs
663
-
664
- All output goes to **stderr** (colored, human-readable) and **`~/.orc/logs/orc.log`** (JSON lines, machine-readable). Log files rotate at 10 MB with 3 rotated backups (30 MB total).
665
-
666
- ```bash
667
- # Tail recent errors
668
- grep '"level":"error"' ~/.orc/logs/orc.log | tail -20
669
-
670
- # Watch live
671
- tail -f ~/.orc/logs/orc.log | jq .
672
- ```
673
-
674
- ### Running as a background service
675
-
676
- The daemon runs the API server, job scheduler, file watchers, and gateway in one process. To start it automatically on login/boot:
677
-
678
- ```bash
679
- orc daemon install # register auto-start for your OS
680
- orc daemon uninstall # remove auto-start registration
681
- ```
682
-
683
- | Platform | Mechanism | Auto-restart on crash |
684
- | ----------- | ------------------------------------------------------------------ | --------------------- |
685
- | **Windows** | Registry Run key (`HKCU\...\Run`) | No |
686
- | **macOS** | launchd (`~/Library/LaunchAgents/com.orc.daemon.plist`) | Yes |
687
- | **Linux** | systemd user service (`~/.config/systemd/user/orc-daemon.service`) | Yes |
688
-
689
- No admin/root privileges required on any platform.
690
-
691
- ```bash
692
- # Manual control
693
- orc daemon start # start in foreground (API + scheduler + gateway)
694
- orc daemon stop # stop a running daemon
695
- orc daemon status # show scheduled jobs
696
- orc api # start the API server only (no scheduler/gateway)
697
-
698
- # Check daemon health
699
- curl http://localhost:7700/health
700
- ```
701
-
702
- Logs go to `~/.orc/daemon.log`. Config is read from `~/.orc/config.json`.
703
-
704
- ## Architecture
705
-
706
- ```
707
- packages/
708
- core/ Config (Zod), types, logger, ULID IDs
709
- db/ Drizzle ORM + SQLite (~/.orc/orc.db)
710
- api/ Hono REST API + OpenAPI spec (:7700)
711
- sdk/ Typed HTTP client from OpenAPI
712
- cli/ Commander CLI (the `orc` binary)
713
- mcp/ MCP server (stdio + Streamable HTTP at /mcp)
714
- runner/ Job executor + cron/watch scheduler + task loop
715
- gateway/ Telegram + Slack bridge + agent sessions
716
- agent-runtime/ Agent backend registry (claude, acpx, a2a)
717
- task-service/ Task status transitions + side-effects
718
- web/ React dashboard (Vite + Tailwind + shadcn + React Query)
719
- ```
720
-
721
- Data flow: `Agent → MCP → API → DB` / `CLI → SDK → API → DB`
722
-
723
- ## Development
724
-
725
- ```bash
726
- bun install # install all workspace deps
727
- bun dev # API + CLI in watch mode
728
- bun typecheck # typecheck all packages
729
- bun check # biome lint + format
730
- bun test # run all tests
731
- bun build # build all packages
732
- ```
733
-
734
- See [AGENTS.md](./AGENTS.md) for the full development guide and coding conventions.
735
-
736
- ## Learn more
737
-
738
- - [Usage Guide](./docs/usage-guide.md) - best practices for memory, tasks, multi-agent workflows, and configuration
739
- - [Vision](./docs/vision.md) - why ORC exists and the problem it solves
740
- - [Roadmap](./docs/roadmap.md) - what shipped and what's next
741
- - [Agent Orchestration Design](./docs/agent-orchestration-design.md) - architecture spec for the task loop and multi-agent workflow
742
- - [Task Flows](./docs/task-flows.md) - flow graphs: nodes, conditional edges, bounded loops, fan-out and joins, and how to author your own
1
+ <div align="center">
2
+
3
+ # orc
4
+
5
+ **Multi-agent orchestrator with human-in-the-loop review**
6
+
7
+ [![npm version](https://img.shields.io/npm/v/orc-ai?style=flat-square)](https://www.npmjs.com/package/orc-ai)
8
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue?style=flat-square)](LICENSE)
9
+ ![Bun](https://img.shields.io/badge/Bun-%3E%3D1.1-f472b6?style=flat-square&logo=bun&logoColor=white)
10
+ ![TypeScript](https://img.shields.io/badge/TypeScript-strict-3178c6?style=flat-square&logo=typescript&logoColor=white)
11
+
12
+ One SQLite file. One CLI. Any agent.<br>
13
+ ORC coordinates Claude Code, Cursor, Codex, Gemini, and remote A2A agents through a shared task board, persistent memory, and a review flow that keeps you in control.
14
+
15
+ <img src="assets/Architecture.gif" alt="ORC Architecture" width="700" />
16
+
17
+ </div>
18
+
19
+ ## Overview
20
+
21
+ Every AI agent session is an island. Start a new session and it knows nothing about the last one. Run two in parallel and they can't coordinate. Switch agents and you start from zero.
22
+
23
+ ORC fixes this. Shared memory across every session. A task board where agents submit work and you approve it. A scheduler that runs agents on a cron. All backed by a single SQLite file - no cloud, no account, no subscription.
24
+
25
+ ### Key features
26
+
27
+ | Feature | What it does |
28
+ | ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
29
+ | **Agent orchestration** | Task loop spawns workers across backends (Claude Code, Codex, Gemini, Copilot, A2A), manages concurrency and review cycles |
30
+ | **Human-in-the-loop** | Agents submit work for your approval via CLI, Telegram, or Slack before anything lands |
31
+ | **Shared memory** | Decisions, rules, and discoveries stored once, searchable by any session via ranked full-text search |
32
+ | **Task board** | `todo → queued → doing → review → done` with dependency tracking, priority, and automatic unblocking |
33
+ | **Multi-backend routing** | Route to Claude (in-process, nothing to install), ACPX (14+ agents), agentapi, or remote A2A endpoints — with `orc doctor` reporting which are usable |
34
+ | **Job runner** | Cron, file-watch, webhook, or manual triggers with full run history |
35
+ | **MCP server** | 34 tools connect any [Model Context Protocol](https://modelcontextprotocol.io) (MCP) compatible agent — stdio or Streamable HTTP |
36
+ | **Session continuity** | Snapshots survive context compaction so agents resume where they left off |
37
+ | **Gateway** | Approve work, search memory, and chat with live agents from Telegram or Slack |
38
+ | **Knowledge search** | Index document collections (markdown, notes, wikis) and search them via BM25 or hybrid (vector + reranking) |
39
+ | **Skill library** | Discoverable workflow templates (coder, reviewer, planner, bugfix) that encode your standards |
40
+ | **Task flows** | Per-task graphs: conditional edges, bounded loops, parallel fan-out with joins, and human gates — with hard termination rails |
41
+
42
+ ## Getting started
43
+
44
+ ### Install
45
+
46
+ **Recommended: the desktop app.** Download the installer for your machine from [GitHub Releases](https://github.com/niradler/orc/releases) - no Bun, Node or npm needed. Maintainers: see the [local release command](docs/releases.md).
47
+
48
+ | OS | Installer |
49
+ | --------------------- | -------------------------------------------------------- |
50
+ | macOS (Apple Silicon) | `orc-<version>-mac-arm64.dmg` |
51
+ | macOS (Intel) | `orc-<version>-mac-x64.dmg` |
52
+ | Windows (x64) | `orc-<version>-windows-x64-setup.exe` |
53
+ | Linux (x64) | `orc-<version>-linux-x64.AppImage` (`chmod +x`, then run) |
54
+
55
+ On first launch the app sets everything up:
56
+
57
+ - starts the orc daemon (API, scheduler, session watchers, gateway) and opens the dashboard in its window
58
+ - when it starts the daemon, generates an API secret, saves it to `~/.orc/config.json`, and sends it for you - Terminals work with nothing to configure
59
+ - installs the `orc` CLI to `~/.orc/bin` and adds that folder to your `PATH` (a marked block in your login shell's startup file on macOS and Linux, the user `PATH` on Windows) - open a new terminal and run `orc`
60
+ - registers start at login (hidden) and keeps the daemon running from the tray / menu bar when the window is closed; toggle it from the tray menu, quit from there to stop the daemon
61
+
62
+ The builds are unsigned: on macOS right-click the app and choose Open the first time, on Windows choose "More info" then "Run anyway".
63
+
64
+ <details>
65
+ <summary>Headless / CLI-only install (servers, Docker, CI)</summary>
66
+
67
+ Needs [Bun](https://bun.sh) >= 1.4.2 for the npm install.
68
+
69
+ ```bash
70
+ npm install -g orc-ai
71
+ ```
72
+
73
+ #### Pre-built binaries
74
+
75
+ Download from [GitHub Releases](https://github.com/niradler/orc/releases):
76
+
77
+ ```bash
78
+ # macOS (Apple Silicon)
79
+ curl -L https://github.com/niradler/orc/releases/latest/download/orc-mac-arm64 -o /usr/local/bin/orc && chmod +x /usr/local/bin/orc
80
+
81
+ # macOS (Intel)
82
+ curl -L https://github.com/niradler/orc/releases/latest/download/orc-mac-x64 -o /usr/local/bin/orc && chmod +x /usr/local/bin/orc
83
+
84
+ # Linux (x64)
85
+ curl -L https://github.com/niradler/orc/releases/latest/download/orc-linux-x64 -o /usr/local/bin/orc && chmod +x /usr/local/bin/orc
86
+
87
+ # Linux (ARM64)
88
+ curl -L https://github.com/niradler/orc/releases/latest/download/orc-linux-arm64 -o /usr/local/bin/orc && chmod +x /usr/local/bin/orc
89
+
90
+ # Windows - download orc-windows-x64.exe from the release page and add to PATH
91
+ ```
92
+
93
+ #### From source
94
+
95
+ ```bash
96
+ git clone https://github.com/niradler/orc
97
+ cd orc && bun install && bun build
98
+ ```
99
+
100
+ </details>
101
+
102
+ ### Quick start
103
+
104
+ ```bash
105
+ # 1. Start the daemon - runs the REST API on :7700, task loop, job scheduler, gateway, and web UI
106
+ # (skip this if you installed the desktop app: it is already running)
107
+ orc daemon start
108
+
109
+ # 2. Create a project
110
+ orc project add my-app -d "My application"
111
+ orc project use my-app
112
+
113
+ # 3. Add tasks and memories - everything auto-scopes to my-app
114
+ orc task add "Fix the auth bug" --priority high
115
+ orc mem add "Use RWMutex for token refresh" --type decision
116
+ orc job add nightly --command "bun run test" --trigger cron --cron "0 22 * * *"
117
+
118
+ # 4. See everything
119
+ orc status
120
+ orc task list
121
+ ```
122
+
123
+ Open `http://localhost:7700` to use the web dashboard - task board, kanban, flow runs, jobs, memories, sessions, knowledge, and a live chat panel. The same server hosts both the REST API and the prebuilt React SPA, so there is no separate command to run for the UI.
124
+
125
+ > [!TIP]
126
+ > The database is created automatically at `~/.orc/orc.db` on first run. No setup needed.
127
+
128
+ ### Web dashboard
129
+
130
+ The web dashboard ships inside the `orc` binary and is served by the API process at the root path. REST routes live under `/api/<route>` - the SDK, CLI and MCP clients add that prefix themselves - which leaves the root path free for the SPA.
131
+
132
+ | Route | Served from |
133
+ | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
134
+ | `GET /` | `index.html` (web SPA shell) |
135
+ | `GET /assets/*` | Built JS/CSS bundles |
136
+ | `GET /api/*` | All REST routes |
137
+ | `GET /openapi.json`, `GET /docs` | Swagger UI |
138
+ | `GET /mcp` | MCP server (streamable HTTP) |
139
+ | `GET /tasks/<id>`, `/flows/<name>`, … | `index.html` again - a navigation request matching no static file falls back to the SPA shell, so dashboard links are shareable |
140
+
141
+ Override the served dist directory with `ORC_WEB_DIST=/path/to/web/dist` if you want to host a custom build (e.g. a fork). If no dist is found, the server runs in pure-API mode.
142
+
143
+ ### Desktop app
144
+
145
+ `packages/desktop` is the Electron app described under [Install](#install). It attaches to a daemon already answering `/api/health` on the configured port (`api.port`, default 7700) or starts the bundled `orc` binary, and stops only a daemon it started. Its daemon output goes to `~/.orc/desktop-daemon.log`. Launching the app executable with `--quit` quits the running instance (and the daemon it started), which is what installers and scripts should use; `--hidden` starts it without opening a window.
146
+
147
+ Hardening: sandboxed renderer with context isolation and no Node integration, permission requests denied except clipboard, `<webview>` blocked, navigation locked to the daemon origin (everything else opens in the system browser), Electron fuses that disable `ELECTRON_RUN_AS_NODE` and Node CLI/env options.
148
+
149
+ `orc daemon start` merges the login shell's `PATH` into its own on macOS and Linux, so `claude`, `codex` and `cursor-agent` are found when the daemon is started by launchd, systemd or a Finder-launched app.
150
+
151
+ ```bash
152
+ bun run --filter @orc/desktop bin --only host # build the orc binary for this machine
153
+ bun run --filter @orc/desktop dev # run the app from source
154
+ bun run --filter @orc/desktop dist # installer for this machine -> packages/desktop/release
155
+ bun run --filter @orc/desktop dist:mac # also dist:win, dist:linux
156
+ bun packages/desktop/scripts/smoke.ts # end-to-end check of the packaged app
157
+ ```
158
+
159
+ Builds are unsigned and there is no auto-update yet. Building binaries needs `bun >= 1.4.2` on `PATH` ahead of any `node_modules/.bin/bun`.
160
+
161
+ ## Docker
162
+
163
+ Run ORC in a container with the published image:
164
+
165
+ ```bash
166
+ docker run -d --name orc \
167
+ -p 7700:7700 \
168
+ -v orc-data:/data \
169
+ -e ORC_API_SECRET=$(openssl rand -hex 32) \
170
+ -e ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY \
171
+ niradler/orc:latest
172
+ ```
173
+
174
+ > The container binds `0.0.0.0`. Set a strong `ORC_API_SECRET` before exposing the
175
+ > mapped port beyond localhost — without it, every endpoint (including job execution,
176
+ > which runs arbitrary shell commands) is open to anyone who can reach the port.
177
+
178
+ Or with [docker-compose.yml](docker-compose.yml):
179
+
180
+ ```bash
181
+ docker compose up -d
182
+ ```
183
+
184
+ The container defaults to the `claude` backend (direct Anthropic API via SDK — no host CLI needed). To delegate to an agent running on the host instead, set `ORC_AGENT_LOOP_DEFAULT_BACKEND=agentapi` and run [coder/agentapi](https://github.com/coder/agentapi) on the host:
185
+
186
+ ```bash
187
+ agentapi server --allowed-hosts '*' -- \
188
+ claude --allowedTools all \
189
+ --mcp-config '{"mcpServers":{"orc":{"type":"http","url":"http://localhost:7700/mcp"}}}'
190
+ ```
191
+
192
+ The `--mcp-config` flag wires the host agent back to ORC's [HTTP MCP endpoint](#mcp-tools) so it can call `task_update`, `memory_*`, `knowledge_*`, etc. `host.docker.internal` lets the container reach agentapi on the host.
193
+
194
+ ## Connect your agent
195
+
196
+ ### Claude Code
197
+
198
+ Add to `~/.claude/settings.json`:
199
+
200
+ ```json
201
+ {
202
+ "hooks": {
203
+ "PostToolUse": [
204
+ {
205
+ "matcher": "Write|Edit|MultiEdit|StrReplace|EditNotebook|Bash|Shell|Agent|EnterPlanMode|ExitPlanMode|mcp__orc__task_|mcp__orc__memory_store|mcp__orc__memory_delete|mcp__orc__job_run|mcp__orc__job_create|mcp__orc__job_update",
206
+ "hooks": [
207
+ {
208
+ "type": "command",
209
+ "command": "bun /path/to/orc/hooks/post-tool-use.ts"
210
+ }
211
+ ]
212
+ }
213
+ ],
214
+ "PreCompact": [
215
+ {
216
+ "matcher": "",
217
+ "hooks": [
218
+ {
219
+ "type": "command",
220
+ "command": "bun /path/to/orc/hooks/pre-compact.ts"
221
+ }
222
+ ]
223
+ }
224
+ ],
225
+ "SessionStart": [
226
+ {
227
+ "matcher": "",
228
+ "hooks": [
229
+ {
230
+ "type": "command",
231
+ "command": "bun /path/to/orc/hooks/session-start.ts"
232
+ }
233
+ ]
234
+ }
235
+ ]
236
+ },
237
+ "env": { "ORC_API_BASE": "http://127.0.0.1:7700", "ORC_PROJECT": "" }
238
+ }
239
+ ```
240
+
241
+ > [!NOTE]
242
+ > Replace `/path/to/orc/` with the path to your ORC clone or the installed package location (run `npm root -g` to find global installs). Hooks handle session events and snapshots automatically.
243
+
244
+ ### Cursor
245
+
246
+ Add to `.cursor/mcp.json`:
247
+
248
+ ```json
249
+ {
250
+ "mcpServers": {
251
+ "orc": {
252
+ "command": "orc",
253
+ "args": ["mcp"],
254
+ "env": {
255
+ "ORC_API_BASE": "http://127.0.0.1:7700",
256
+ "ORC_SESSION_ID": "cursor"
257
+ }
258
+ }
259
+ }
260
+ }
261
+ ```
262
+
263
+ <details>
264
+ <summary>Codex, Gemini CLI, and other MCP agents</summary>
265
+
266
+ **Codex** - Copy `hooks/codex/settings.json` to `~/.codex/settings.json` and update the path.
267
+
268
+ **Gemini CLI / any MCP agent** - Add to your MCP config:
269
+
270
+ ```json
271
+ {
272
+ "mcpServers": {
273
+ "orc": {
274
+ "command": "orc",
275
+ "args": ["mcp"],
276
+ "env": {
277
+ "ORC_API_BASE": "http://127.0.0.1:7700",
278
+ "ORC_SESSION_ID": "gemini"
279
+ }
280
+ }
281
+ }
282
+ }
283
+ ```
284
+
285
+ </details>
286
+
287
+ ## Usage
288
+
289
+ ### How agents use ORC
290
+
291
+ ```
292
+ 1. Agent starts → context() returns active tasks + key memories
293
+ 2. Agent works → creates tasks, stores decisions, records events
294
+ 3. Agent submits work → task_update(status: "review", comment: "summary")
295
+ 4. You review → approve or request changes via CLI / Telegram / Slack
296
+ 5. Agent continues → picks up next task or resumes with feedback
297
+ 6. Session ends → session_log() records what happened
298
+ ```
299
+
300
+ When a context window fills up, `session_snapshot` captures current state into a compact 2KB blob that `session_restore` injects back after compaction - the agent picks up where it left off.
301
+
302
+ ### Agent orchestration
303
+
304
+ The task loop automatically picks up queued tasks and spawns worker agents:
305
+
306
+ ```bash
307
+ # Create a task with a workflow and backend
308
+ orc task add "Implement user auth" --skill orc-coder --backend claude --priority high
309
+
310
+ # Or batch-create with dependencies via MCP
311
+ task_batch_create({ tasks: [
312
+ { title: "Design schema", skill_name: "orc-planner" },
313
+ { title: "Implement API", skill_name: "orc-coder", blocked_by: [0] },
314
+ { title: "Review code", skill_name: "orc-reviewer", blocked_by: [1] }
315
+ ]})
316
+ ```
317
+
318
+ The loop handles concurrency, session resume on feedback, review round limits, stale claim cleanup, and backend routing.
319
+
320
+ Every task runs a **flow graph** (see [Task flows](#task-flows)); `orc-default` is the build → review → done pipeline described above.
321
+
322
+ #### Agent backends
323
+
324
+ | Backend | Needs |
325
+ | --------------- | ------------------------------------------------------------------------------------------------------------ |
326
+ | `claude` | Nothing to install: runs **in-process** via [@anthropic-ai/claude-agent-sdk](https://www.npmjs.com/package/@anthropic-ai/claude-agent-sdk), which ships with orc. Uses the Claude Code CLI's stored credentials, or `ANTHROPIC_API_KEY`. The default. |
327
+ | `acpx` | The [ACP CLI](https://github.com/openclaw/acpx) — 14+ agents (Codex, Gemini, Copilot, Kiro, Cursor, …). Installed as an optional dependency, so a normal `npm i -g orc-ai` gets it; orc finds it there even when it is not on your `PATH`. Point `ORC_ACPX_PATH` at a specific copy to override. |
328
+ | `agentapi` | A [coder/agentapi](https://github.com/coder/agentapi) server on the host (HTTP+SSE), wrapping any local coding agent. `AGENTAPI_URL` if it is not on the default port. |
329
+ | `a2a` | A remote [A2A](https://github.com/google/A2A) endpoint, supplied per task/session — nothing local. |
330
+ | `claude-cli` | The `claude` binary on `PATH`. The pre-SDK path, kept for when driving the real CLI matters. |
331
+ | `codex-cli` | The `codex` binary on `PATH`, driven natively instead of through acpx. |
332
+ | _anything else_ | Passed to acpx as its agent name, so `--agent-backend gemini` means "acpx driving gemini". |
333
+
334
+ Which of these actually work on a given machine depends on what is installed, so orc probes them rather than making you guess:
335
+
336
+ ```bash
337
+ orc doctor # per backend: usable or not, what it resolved to, what a missing one needs
338
+ orc doctor --json # same, machine-readable
339
+ ```
340
+
341
+ The dashboard shows the same probe: the agent-backend field on a task is a picker that marks each backend ready or unavailable, and names the one a task with no backend of its own will use. `GET /api/backends` is the endpoint behind both.
342
+
343
+ Enable the task loop in `~/.orc/config.json`:
344
+
345
+ ```json
346
+ {
347
+ "agent_loop": {
348
+ "enabled": true,
349
+ "poll_interval_minutes": 5,
350
+ "max_workers": 1,
351
+ "default_backend": "claude",
352
+ "session_idle_timeout_minutes": 20,
353
+ "worker_auto_approve": true,
354
+ "default_flow": "orc-default",
355
+ "review_flow": "orc-review-only"
356
+ }
357
+ }
358
+ ```
359
+
360
+ ### Projects
361
+
362
+ Projects group tasks, memories, and jobs. Set an active project and all commands auto-scope:
363
+
364
+ ```bash
365
+ orc project add my-app -d "Main application"
366
+ orc project use my-app # set active
367
+
368
+ orc task list # scoped to my-app
369
+ orc mem search "auth" # scoped to my-app
370
+ orc task list -p infra # override to different project
371
+ orc task list --no-project # see everything
372
+ ```
373
+
374
+ **Resolution order:** explicit `-p <name>` > `activeProject` from config > error
375
+
376
+ MCP tools follow the same logic - pass `project: "name"` to scope, or omit to use the active project.
377
+
378
+ ### Memory
379
+
380
+ Store decisions, conventions, and discoveries that persist across all sessions:
381
+
382
+ ```bash
383
+ orc mem add "All IDs are ULIDs" --type rule
384
+ orc mem add "Use PostgreSQL for concurrent writes" --type decision
385
+ orc mem search "authentication"
386
+ ```
387
+
388
+ | Type | Weight | Use for |
389
+ | ----------- | ------ | ----------------------------------------------- |
390
+ | `rule` | High | Conventions: "all IDs are ULIDs" |
391
+ | `decision` | High | Choices: "use PostgreSQL for concurrent writes" |
392
+ | `discovery` | Medium | Findings: "token refresh has a race condition" |
393
+ | `event` | Low | Things that happened: "deployed v1.0" |
394
+ | `fact` | Low | General knowledge (default) |
395
+
396
+ ### Knowledge
397
+
398
+ Index existing document collections (markdown, notes, code docs) and make them searchable by any agent. Unlike memory (short agent-authored notes), knowledge searches pre-existing files on disk.
399
+
400
+ ```bash
401
+ # Add a document collection
402
+ orc knowledge add my-docs --path ~/projects/docs --pattern "**/*.md"
403
+
404
+ # Search across indexed documents
405
+ orc knowledge search "authentication flow"
406
+
407
+ # List collections
408
+ orc knowledge list
409
+
410
+ # Re-index after files change
411
+ orc knowledge update
412
+ ```
413
+
414
+ Knowledge uses [QMD](https://github.com/nicholasgriffintn/qmd) as the search engine. By default it runs BM25 full-text search (no LLM needed). Set `search_mode: "hybrid"` in config for vector search with reranking - embeddings are generated automatically when documents are indexed.
415
+
416
+ Collections can be scoped to projects. When scoped, searches and listing filter to only that project's collections.
417
+
418
+ **MCP tools:** `knowledge_search`, `knowledge_get`, `knowledge_collections`, `knowledge_collection_add`, `knowledge_collection_remove`, `knowledge_update`
419
+
420
+ ### Task status flow
421
+
422
+ ```
423
+ todo → queued → doing → review → done
424
+ │ │
425
+ v v
426
+ blocked changes_requested → doing
427
+ │
428
+ v
429
+ paused
430
+ ```
431
+
432
+ Tasks with `required_review: true` (default) need your approval before moving to `done`. Set `max_review_rounds` to auto-pause tasks that cycle through too many revision rounds.
433
+
434
+ `queued` means a node is waiting for a worker slot — the task is claimed but nothing is running on it yet, so it counts as pending rather than in progress (the dashboard's board shows it under Todo, labelled `queued`). It becomes `doing` when a session actually starts, which is what keeps the board from showing more work in flight than `agent_loop.max_workers` allows.
435
+
436
+ <img src="assets/TaskFlow.gif" alt="Task Flow" width="600" />
437
+
438
+ ### Task flows
439
+
440
+ That pipeline is not hardcoded — it is a **flow graph** named `orc-default`. A flow is nodes joined by conditional edges that may cycle, so a task can run whatever shape its work actually needs: a plan → build → verify loop, a bug-fix-then-confirm loop, an executor with an independent supervisor, or three reviewers in parallel joined before a decision.
441
+
442
+ The graph itself is deterministic; only the nodes are agents. That means loops, branches, and fan-out behave predictably and are fully unit-testable, while the agents just do the work and report a verdict.
443
+
444
+ ```bash
445
+ orc flow list # what graphs are available
446
+ orc flow show orc-plan-build-verify # nodes, edges, limits
447
+ orc task add "Fix the flaky test" --flow orc-fix-verify
448
+ orc flow status <taskId> # active nodes + the ledger of outcomes
449
+ orc flow resume <taskId> --outcome approved # resolve a human gate
450
+ orc flow halt <taskId> # stop it and kill live nodes
451
+ ```
452
+
453
+ | Built-in flow | Shape |
454
+ | ----------------------- | ---------------------------------------------------------------------------- |
455
+ | `orc-default` | build → review → done, looping back while `max_review_rounds` allows |
456
+ | `orc-review-only` | A single review pass for a task you moved straight to `review` |
457
+ | `orc-plan-build-verify` | planner → coder → reviewer, looping until acceptance criteria pass |
458
+ | `orc-fix-verify` | bugfix → independent confirmation the fix holds and a regression test exists |
459
+ | `orc-supervisor` | Executor keeping its context, plus a supervisor re-verifying from a clean one |
460
+ | `orc-parallel-review` | Fan out to correctness / security / tests reviewers, join on all three |
461
+
462
+ **Nodes** are `agent` (runs a session with a skill), `gate` (deterministic branching, fan-out, join points), `human` (waits for you), or `terminal` (ends the run and sets the task's final status). **Edges** carry declarative conditions — `outcome`, `visits`, `var`, `elapsed_secs`, composed with `all`/`any`/`not` — which are data, never evaluated code.
463
+
464
+ Loops always terminate. Per-node `max_visits`, a per-run node-execution budget, a wall clock, plus deadlock and stall detection each halt the run and hand the task back to you with an explanation of which rail tripped.
465
+
466
+ #### Custom graphs per task
467
+
468
+ For work no named flow fits, attach a bespoke graph to a single task:
469
+
470
+ ```bash
471
+ orc flow validate --file ./my-graph.json # catch mistakes before running anything
472
+ orc flow attach <taskId> --file ./my-graph.json --start
473
+ ```
474
+
475
+ Definitions are JSON, validated on load: unknown edge targets, unreachable nodes, a graph that can never finish, or an edge shadowed by an earlier catch-all are all rejected up front rather than discovered mid-run. Reusable flows go in `~/.orc/flows/<name>/flow.json` (or `./.orc/flows/` to pin one per repo), and a user flow shadows a built-in of the same name — that is how you customise `orc-default` without patching orc.
476
+
477
+ Agents can do all of this themselves via the `flow_list`, `flow_read`, `flow_create`, `flow_attach`, `flow_status`, and `flow_report` MCP tools, so a planner can design the pipeline for the work it just decomposed.
478
+
479
+ #### In the web dashboard
480
+
481
+ A task's **Flow** section draws the graph the run froze at start next to its ledger: which node is active, the verdict each visit produced, how many visits a node has spent of its budget, per-node timings and errors, a link to each node's agent transcript, and — when a rail tripped — which one and why. Loopbacks are drawn as edges that go backwards, so a rework cycle looks like one.
482
+
483
+ When a run parks on a human gate, that panel is where you answer it: pick one of the outcomes the node's own edges can route, add a comment, and the flow continues. `Halt` stops a run and kills its live sessions. The **Flows** page lists every graph available with its source, marks the one a task with no flow of its own will run, shows any definition, and reports flows that failed validation along with the errors — so a broken graph is visible before a task tries to run it.
484
+
485
+ ### Jobs
486
+
487
+ ```bash
488
+ orc job add deploy --command "bun run deploy" --trigger manual
489
+ orc job add nightly --command "bun run test" --trigger cron --cron "0 22 * * *"
490
+ orc job add on-change --command "bun run lint" --trigger watch --watch "./src"
491
+ orc job add on-push --command "bun run ci" --trigger webhook
492
+ ```
493
+
494
+ ### Gateway (Telegram / Slack)
495
+
496
+ Approve agent work from your phone, search memory, or start a live AI session.
497
+
498
+ ```json
499
+ {
500
+ "gateway": {
501
+ "telegram": {
502
+ "enabled": true,
503
+ "token": "7123456789:AAF...",
504
+ "authorized_users": [123456789]
505
+ }
506
+ }
507
+ }
508
+ ```
509
+
510
+ **Commands:** `/status`, `/tasks`, `/approve <id>`, `/reject <id>`, `/jobs`, `/run <name>`, `/mem <query>`, `/agent <claude|codex>`
511
+
512
+ > [!TIP]
513
+ > Create a Telegram bot via [@BotFather](https://t.me/BotFather) and find your user ID via [@userinfobot](https://t.me/userinfobot).
514
+
515
+ <details>
516
+ <summary>Slack setup</summary>
517
+
518
+ ```json
519
+ {
520
+ "gateway": {
521
+ "slack": {
522
+ "enabled": true,
523
+ "bot_token": "xoxb-...",
524
+ "app_token": "xapp-...",
525
+ "authorized_users": ["U01ABCDEF"]
526
+ }
527
+ }
528
+ }
529
+ ```
530
+
531
+ Same commands as Telegram. Create a Slack app at [api.slack.com/apps](https://api.slack.com/apps) with Socket Mode enabled.
532
+
533
+ </details>
534
+
535
+ ## Skills
536
+
537
+ ORC ships with agent workflow skills and built-in skill templates for the task loop.
538
+
539
+ ### Install skills
540
+
541
+ ```bash
542
+ # Install all ORC skills into your agent
543
+ npx skills add niradler/orc --all
544
+
545
+ # Or pick specific ones
546
+ npx skills add niradler/orc --skill orc-session orc-tasks
547
+
548
+ # Global install
549
+ npx skills add niradler/orc --all -g
550
+ ```
551
+
552
+ ### Agent workflow skills
553
+
554
+ | Skill | Triggers on |
555
+ | --------------- | -------------------------------------------------------------------------- |
556
+ | `orc-session` | Session start, context compaction, resuming work |
557
+ | `orc-tasks` | Task creation, status updates, HITL review, task decomposition |
558
+ | `orc-knowledge` | Storing decisions, searching memory, "remember this", "what did we decide" |
559
+ | `orc-gateway` | Telegram/Slack setup, remote approval, live agent sessions |
560
+
561
+ ### Built-in skill templates
562
+
563
+ Skill templates live in `skills/*/SKILL.md` (built-in) and `~/.orc/skills/` (user-defined). Agents discover them via `skill_list` and load with `skill_read`.
564
+
565
+ | Skill | Type | Purpose |
566
+ | ------------------ | -------- | --------------------------------------------------------------------------- |
567
+ | `orc-worker-base` | Base | Default worker behavior - ORC awareness, status updates, deliverable format |
568
+ | `orc-main-base` | Base | Orchestration agent - planning, decomposition, monitoring |
569
+ | `orc-coder` | Workflow | Implementation - understand, plan, implement, verify, submit |
570
+ | `orc-planner` | Workflow | Task decomposition with dependencies and workflow assignment |
571
+ | `orc-reviewer` | Workflow | Structured evaluation - correctness, tests, security, conventions |
572
+ | `orc-bugfix` | Workflow | Bug investigation - reproduce, root-cause, fix, regression test |
573
+ | `orc-requirements` | Skill | Requirements interview - outcome, criteria, constraints, scope |
574
+ | `orc-report` | Skill | Project status report - health summary, blockers, active work |
575
+
576
+ Add custom skills by creating a `SKILL.md` in `~/.orc/skills/my-workflow/SKILL.md`.
577
+
578
+ Skills are complete folders, following the [Agent Skills format](https://agentskills.io/specification). Keep the entry instructions in `SKILL.md` and reference supporting files with paths relative to the skill root:
579
+
580
+ ```text
581
+ my-workflow/
582
+ SKILL.md
583
+ references/guide.md
584
+ references/topics/details.md
585
+ scripts/check.py
586
+ assets/template.json
587
+ ```
588
+
589
+ `skill_list` loads metadata only. `skill_read` returns the entry instructions plus a recursive `files` inventory; supporting content loads on demand. For example, `skill_read({ name: "my-workflow", ref: "scripts/check.py" })` reads a script without executing it. Bare reference filenames such as `ref: "guide.md"` remain supported. Binary assets are transported as base64 with `encoding: "base64"`.
590
+
591
+ ```bash
592
+ # Import the whole folder through the API
593
+ orc skill create my-workflow --directory ./my-workflow
594
+ orc skill read my-workflow --ref references/topics/details.md
595
+ orc skill validate ./my-workflow
596
+ orc skill export my-workflow ./exported/my-workflow
597
+ ```
598
+
599
+ The dashboard can import a skill folder or add supporting files individually, then open each file from the detail sheet. API `POST /api/skills` and MCP `skill_create` accept optional `files: [{ path, content, encoding? }]` alongside `name` and the full `SKILL.md` `content`. Encoding defaults to `utf8`. Bundles allow 512 supporting files, 8 MiB per file and 16 MiB total. Paths must stay inside the skill folder; symlinks are excluded and cannot be read. The legacy `references` inventory is retained for existing clients. Worker prompts include the skill's entry path and file inventory so relative links resolve from the skill directory.
600
+
601
+ ### Shared agents and APM packages
602
+
603
+ ORC shares authored definitions across coding agents through one library. An agent profile describes the specialist; a backend selects the coding agent that runs it. Profiles use [APM's `.agent.md` format](https://microsoft.github.io/apm/producer/author-primitives/instructions-and-agents/): YAML frontmatter with a required `description`, optional `name`, `model`, `tools`, `color`, and `handoffs`, followed by Markdown instructions. Unknown agent fields are preserved. Standalone profiles live in `~/.orc/agents/`; project profiles in `.apm/agents/` override matching shared IDs.
604
+
605
+ An imported package keeps its entire directory under `~/.orc/packages/<name>/`, including `apm.yml`, `.apm/agents/`, `.apm/skills/<name>/SKILL.md`, `.apm/instructions/`, scripts, references, and binary assets. Root `SKILL.md` packages are supported too. Manifest validation uses Microsoft's pinned OpenAPM v0.1 schema; the v0.1.41 schema is supported when explicitly selected with `$schema`. Import/export preserves dependency declarations, scripts, and extension fields. Import does not resolve dependencies or execute lifecycle scripts; use APM for those operations before importing the resulting package.
606
+
607
+ ```bash
608
+ orc agent-package import ./team-agents
609
+ orc agent list
610
+ orc agent read team-agents/reviewer
611
+ orc agent-package export team-agents ./exported/team-agents
612
+ orc agent create reviewer --file ./reviewer.agent.md
613
+ orc agent export reviewer ./exported/reviewer.agent.md
614
+ ```
615
+
616
+ Select a shared profile independently of its backend in an ORC flow:
617
+
618
+ ```json
619
+ { "kind": "agent", "agent": "team-agents/reviewer", "backend": "codex-cli", "outcomes": ["pass", "fail"] }
620
+ ```
621
+
622
+ The same profile instructions and relative file locations reach every backend. Pinned models are supported by Claude SDK, Claude CLI, Codex CLI, and ACPX. Tool allowlists are enforced by Claude SDK and Claude CLI; other adapters reject profiles declaring tool restrictions. Unsupported model/tool settings fail before launch. Tool names and model IDs must be valid for the selected coding agent. Explicit session/flow model choices override the profile's model. Handoffs remain authored declarations; ORC flow edges control execution. Package instructions without `applyTo` are included automatically; scoped instructions retain their original glob strings or arrays in an on-demand index, which the coding agent applies when working on matching files.
623
+
624
+ The dashboard's Agents page imports packages and creates/reads profiles. API `/api/agents` and `/api/agent-packages`, SDK clients, CLI, and MCP all access the same files. MCP tools are `agent_list`, `agent_read`, `agent_create`, `agent_package_list`, `agent_package_read`, and `agent_package_import`. Package agent IDs are namespaced as `<package>/<file-stem>`.
625
+
626
+ ## MCP tools
627
+
628
+ Tools are available to any connected agent. Start every session with `context`.
629
+
630
+ | Category | Tools |
631
+ | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
632
+ | **Project** | `project_list` |
633
+ | **Memory** | `context`, `memory_search`, `memory_get`, `memory_store`, `memory_update` |
634
+ | **Task** | `task_list`, `task_get`, `task_create`, `task_update`, `task_batch_create` |
635
+ | **Skill** | `skill_list`, `skill_read`, `skill_create` |
636
+ | **Agent** | `agent_list`, `agent_read`, `agent_create`, `agent_package_list`, `agent_package_read`, `agent_package_import` |
637
+ | **Flow** | `flow_report`, `flow_status`, `flow_list`, `flow_read`, `flow_create`, `flow_attach` |
638
+ | **Knowledge** | `knowledge_search`, `knowledge_get`, `knowledge_collections`, `knowledge_collection_add`, `knowledge_collection_remove`, `knowledge_update` |
639
+ | **Search** | `search` |
640
+ | **Job** | `job_list`, `job_run`, `job_status` |
641
+ | **Session** | `session_event`, `session_snapshot`, `session_restore`, `session_log` |
642
+
643
+ ## REST API
644
+
645
+ Runs on port 7700 with auto-generated OpenAPI spec.
646
+
647
+ - **Swagger UI:** `GET /docs`
648
+ - **OpenAPI spec:** `GET /openapi.json`
649
+
650
+ <details>
651
+ <summary>Full endpoint list</summary>
652
+
653
+ | Method | Path | Description |
654
+ | ----------------------- | ------------------------------ | ------------------------------ |
655
+ | `GET` | `/health` | Health check |
656
+ | `GET/POST/PATCH/DELETE` | `/projects` | CRUD projects |
657
+ | `GET` | `/projects/by-name/{name}` | Lookup by name |
658
+ | `GET` | `/projects/{id}/summary` | Task/memory/job counts |
659
+ | `GET/POST/PATCH/DELETE` | `/tasks` | CRUD tasks |
660
+ | `GET/POST` | `/tasks/{id}/notes` | Task notes |
661
+ | `GET/POST/DELETE` | `/tasks/{id}/links` | Task dependencies |
662
+ | `GET/POST/DELETE` | `/memories` | CRUD memories |
663
+ | `GET` | `/memories/search` | BM25 search |
664
+ | `GET` | `/knowledge/search` | Search documents (BM25/hybrid) |
665
+ | `GET` | `/knowledge/documents/{id}` | Get document by docid |
666
+ | `GET/POST/DELETE` | `/knowledge/collections` | CRUD collections |
667
+ | `POST` | `/knowledge/update` | Re-index collections |
668
+ | `GET` | `/knowledge/status` | Index status |
669
+ | `GET/POST` | `/jobs` | CRUD jobs |
670
+ | `POST` | `/jobs/{id}/trigger` | Trigger a job |
671
+ | `GET` | `/jobs/{id}/runs` | Run history |
672
+ | `GET` | `/jobs/{id}/runs/{runId}/logs` | Run logs |
673
+ | `GET` | `/skills` | Skill templates |
674
+ | `GET` | `/backends` | Agent backends + usability |
675
+ | `GET/POST` | `/flows` | List/create flow graphs |
676
+ | `GET` | `/flows/{name}` | Read a flow definition |
677
+ | `POST` | `/flows/validate` | Validate without saving |
678
+ | `GET/POST` | `/tasks/{id}/flow` | Get a task's run / attach one |
679
+ | `POST` | `/tasks/{id}/flow/resume` | Resolve a human node |
680
+ | `POST` | `/tasks/{id}/flow/halt` | Stop a running flow |
681
+ | `GET` | `/sessions` | Agent session logs |
682
+ | `POST` | `/mcp/tool` | Execute any MCP tool via HTTP |
683
+
684
+ </details>
685
+
686
+ ## CLI reference
687
+
688
+ ```
689
+ orc daemon start|stop|status Manage the daemon (API + scheduler + gateway)
690
+ orc daemon install|uninstall Register/remove auto-start on login/boot
691
+ orc api Start the API server only
692
+ orc mcp Start the MCP server (stdio)
693
+ orc home Show ~/.orc directory and config
694
+ orc status Show API health and counts
695
+ orc doctor Check which agent backends are usable here
696
+
697
+ orc project list|add|show|use|update|archive
698
+ orc task list|add|show|update|done|review|approve|reject|delete
699
+ orc mem list|add|search
700
+ orc job list|add|run|runs
701
+ orc session list|show|log
702
+ orc skill list|show
703
+ orc flow list|show|validate|create|attach|status|resume|halt
704
+ orc kb search|get|collections|add|remove|update|status
705
+ ```
706
+
707
+ > [!NOTE]
708
+ > All task/mem/job/kb commands default to the active project. Use `-p <name>` to override or `--no-project` to see everything. Add `--json` for machine-readable output.
709
+
710
+ ## Configuration
711
+
712
+ ORC merges config in priority order (later wins):
713
+
714
+ 1. `~/.orc/config.json` - user global
715
+ 2. `./.orc/config.json` - project-local
716
+ 3. Environment variables
717
+
718
+ <details>
719
+ <summary>Environment variables</summary>
720
+
721
+ | Variable | Default | Description |
722
+ | -------------------------------- | --------------------- | ------------------------------------------------- |
723
+ | `ORC_DB_PATH` | `~/.orc/orc.db` | SQLite database path |
724
+ | `ORC_API_HOST` | `127.0.0.1` | API listen host (set to `0.0.0.0` in Docker) |
725
+ | `ORC_API_PORT` | `7700` | API listen port |
726
+ | `ORC_API_SECRET` | - | Bearer token for auth |
727
+ | `ORC_TERMINALS_ALLOW_WITHOUT_SECRET` | `false` | Allow dashboard Terminals with no API secret (loopback-bound API only) |
728
+ | `ORC_TELEGRAM_TOKEN` | - | Enables the Telegram gateway when set |
729
+ | `AGENTAPI_URL` | `http://127.0.0.1:3284` | URL of host agentapi server (for `agentapi` backend) |
730
+ | `ANTHROPIC_API_KEY` | - | Required for the `claude` backend (Anthropic SDK) |
731
+ | `ORC_SESSION_ID` | `default` | Per-agent session identifier |
732
+ | `ORC_LOG_LEVEL` | `info` | `debug`, `info`, `warn`, `error` |
733
+ | `ORC_LOG_DIR` | `~/.orc/logs` | Log file directory |
734
+ | `ORC_LOG_FILE` | `1` | Set to `0` to disable file logging |
735
+ | `ORC_RUNNER_TIMEOUT` | `300` | Default job timeout (seconds) |
736
+ | `ORC_AGENT_LOOP_ENABLED` | `false` | Enable the agent task loop |
737
+ | `ORC_AGENT_LOOP_POLL_INTERVAL` | `5` | Task loop poll interval (minutes) |
738
+ | `ORC_AGENT_LOOP_MAX_WORKERS` | `1` | Max concurrent worker agents |
739
+ | `ORC_AGENT_LOOP_DEFAULT_BACKEND` | `claude` | Default agent backend |
740
+ | `ORC_AGENT_LOOP_IDLE_TIMEOUT` | `20` | Session idle timeout (minutes) |
741
+ | `ORC_AGENT_LOOP_AUTO_APPROVE` | `true` | Auto-approve worker tool permissions |
742
+ | `ORC_KNOWLEDGE_DB_PATH` | `~/.orc/knowledge.db` | Knowledge search database path |
743
+ | `ORC_KNOWLEDGE_SEARCH_MODE` | `lexical` | `lexical` (BM25) or `hybrid` (vector + reranking) |
744
+
745
+ </details>
746
+
747
+ ### Logs
748
+
749
+ All output goes to **stderr** (colored, human-readable) and **`~/.orc/logs/orc.log`** (JSON lines, machine-readable). Log files rotate at 10 MB with 3 rotated backups (30 MB total).
750
+
751
+ ```bash
752
+ # Tail recent errors
753
+ grep '"level":"error"' ~/.orc/logs/orc.log | tail -20
754
+
755
+ # Watch live
756
+ tail -f ~/.orc/logs/orc.log | jq .
757
+ ```
758
+
759
+ ### Running as a background service
760
+
761
+ The daemon runs the API server, job scheduler, file watchers, and gateway in one process. To start it automatically on login/boot:
762
+
763
+ ```bash
764
+ orc daemon install # register auto-start for your OS
765
+ orc daemon uninstall # remove auto-start registration
766
+ ```
767
+
768
+ | Platform | Mechanism | Auto-restart on crash |
769
+ | ----------- | ------------------------------------------------------------------ | --------------------- |
770
+ | **Windows** | Registry Run key (`HKCU\...\Run`) | No |
771
+ | **macOS** | launchd (`~/Library/LaunchAgents/com.orc.daemon.plist`) | Yes |
772
+ | **Linux** | systemd user service (`~/.config/systemd/user/orc-daemon.service`) | Yes |
773
+
774
+ No admin/root privileges required on any platform.
775
+
776
+ ```bash
777
+ # Manual control
778
+ orc daemon start # start in foreground (API + scheduler + gateway)
779
+ orc daemon stop # stop a running daemon
780
+ orc daemon status # show scheduled jobs
781
+ orc api # start the API server only (no scheduler/gateway)
782
+
783
+ # Check daemon health
784
+ curl http://localhost:7700/health
785
+ ```
786
+
787
+ Logs go to `~/.orc/daemon.log`. Config is read from `~/.orc/config.json`.
788
+
789
+ ## Architecture
790
+
791
+ ```
792
+ packages/
793
+ core/ Config (Zod), types, logger, ULID IDs
794
+ db/ Drizzle ORM + SQLite (~/.orc/orc.db)
795
+ api/ Hono REST API + OpenAPI spec (:7700)
796
+ sdk/ Typed HTTP client from OpenAPI
797
+ cli/ Commander CLI (the `orc` binary)
798
+ mcp/ MCP server (stdio + Streamable HTTP at /mcp)
799
+ runner/ Job executor + cron/watch scheduler + task loop
800
+ gateway/ Telegram + Slack bridge + agent sessions
801
+ agent-runtime/ Agent backend registry (claude, acpx, a2a)
802
+ task-service/ Task status transitions + side-effects
803
+ web/ React dashboard (Vite + Tailwind + shadcn + React Query)
804
+ ```
805
+
806
+ Data flow: `Agent → MCP → API → DB` / `CLI → SDK → API → DB`
807
+
808
+ ## Development
809
+
810
+ ```bash
811
+ bun install # install all workspace deps
812
+ bun dev # API + CLI in watch mode
813
+ bun typecheck # typecheck all packages
814
+ bun check # biome lint + format
815
+ bun test # run all tests
816
+ bun build # build all packages
817
+ ```
818
+
819
+ See [AGENTS.md](./AGENTS.md) for the full development guide and coding conventions.
820
+
821
+ ## Learn more
822
+
823
+ - [Usage Guide](./docs/usage-guide.md) - best practices for memory, tasks, multi-agent workflows, and configuration
824
+ - [Vision](./docs/vision.md) - why ORC exists and the problem it solves
825
+ - [Roadmap](./docs/roadmap.md) - what shipped and what's next
826
+ - [Agent Orchestration Design](./docs/agent-orchestration-design.md) - architecture spec for the task loop and multi-agent workflow
827
+ - [Task Flows](./docs/task-flows.md) - flow graphs: nodes, conditional edges, bounded loops, fan-out and joins, and how to author your own