orc-ai 0.1.1 → 0.1.3

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 (3) hide show
  1. package/README.md +153 -0
  2. package/dist/index.js +1 -1
  3. package/package.json +63 -63
package/README.md ADDED
@@ -0,0 +1,153 @@
1
+ # orc — Human + AI Orchestration Hub
2
+
3
+ > Persistent memory · Task management with HITL review · Generic job runner · MCP server for Claude Code, Cursor, Codex, and Gemini CLI.
4
+ >
5
+ > One SQLite file. Shared across every agent you use.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install -g orc-ai
11
+ # or
12
+ bun add -g orc-ai
13
+ ```
14
+
15
+ > **Requires [Bun](https://bun.sh) ≥ 1.1** to run. Bun is used as the runtime — install it once, then `orc` works everywhere.
16
+
17
+ ## What it does
18
+
19
+ ORC is the shared brain between you and your AI agents. Every agent connects to the same store of tasks, memories, and jobs — so when you switch from Claude Code to Cursor, context doesn't evaporate.
20
+
21
+ - **Shared memory** — store decisions, rules, discoveries once; any agent can search them
22
+ - **Task board** — tasks move through `todo → doing → review → done`; agents submit for review, you approve
23
+ - **Job runner** — schedule any command (cron, file-watch, manual); logs every run
24
+ - **MCP server** — one config line connects any agent to all of the above
25
+ - **Session continuity** — hooks capture what happened; snapshots survive context compaction
26
+ - **Gateway** — approve agent work from Telegram or Slack; start live Claude/Codex sessions from your phone
27
+
28
+ ## Quick Start
29
+
30
+ ```bash
31
+ # Start the API (keeps the DB open and serves the REST + MCP endpoint)
32
+ orc daemon start
33
+
34
+ # In another terminal — try it
35
+ orc status
36
+ orc task add "Fix the auth bug" --priority high
37
+ orc mem add "Use RWMutex for token refresh" --type decision --scope myproject
38
+ orc job add nightly --command "echo hello" --trigger cron --cron "0 22 * * *"
39
+ ```
40
+
41
+ The database is created automatically at `~/.orc/orc.db` on first run.
42
+
43
+ ## Agent Setup
44
+
45
+ ### Cursor
46
+
47
+ Add to `.cursor/mcp.json` in your project (or the global Cursor MCP config):
48
+
49
+ ```json
50
+ {
51
+ "mcpServers": {
52
+ "orc": {
53
+ "command": "orc",
54
+ "args": ["mcp"],
55
+ "env": {
56
+ "ORC_API_BASE": "http://127.0.0.1:7700",
57
+ "ORC_SESSION_ID": "cursor"
58
+ }
59
+ }
60
+ }
61
+ }
62
+ ```
63
+
64
+ ### Claude Code
65
+
66
+ Copy `hooks/claude-code/settings.json` from the [orc repo](https://github.com/niradler/orc) to `~/.claude/settings.json` and replace the path placeholder with your actual path.
67
+
68
+ ### Codex
69
+
70
+ Copy `hooks/codex/settings.json` from the [orc repo](https://github.com/niradler/orc) to `~/.codex/settings.json`.
71
+
72
+ ### Gemini CLI
73
+
74
+ ```json
75
+ {
76
+ "mcpServers": {
77
+ "orc": {
78
+ "command": "orc",
79
+ "args": ["mcp"],
80
+ "env": {
81
+ "ORC_API_BASE": "http://127.0.0.1:7700",
82
+ "ORC_SESSION_ID": "gemini"
83
+ }
84
+ }
85
+ }
86
+ }
87
+ ```
88
+
89
+ ## CLI Reference
90
+
91
+ ```
92
+ orc daemon start Start API + scheduler + file-watchers + gateway
93
+ orc daemon stop Send SIGTERM to running daemon
94
+ orc daemon status Show scheduler state + next run times per job
95
+ orc home Show ~/.orc directory, daemon state, and config
96
+
97
+ orc api Start the API server only (no scheduler)
98
+ orc mcp Start the MCP server in stdio mode
99
+ orc status Show API health, task count, memory count
100
+
101
+ orc task list [--status] List tasks (default: active)
102
+ orc task add <title> Create a task (--priority, --body, --project)
103
+ orc task done <id> Mark a task done
104
+ orc task review <id> Submit task for HITL review
105
+ orc task approve <id> Approve a review
106
+ orc task reject <id> Request changes
107
+
108
+ orc mem list List recent memories (--limit)
109
+ orc mem add <content> Store a memory (--type, --scope, --title)
110
+ orc mem search <query> Search memories via BM25 + trigram
111
+
112
+ orc job list List all jobs with trigger type and run count
113
+ orc job add <name> Create a job (--command, --trigger, --cron, --watch)
114
+ orc job run <name> Trigger a job immediately
115
+ orc job runs <name> Show run history (--logs, --sessions, --limit)
116
+
117
+ orc session list List recent agent sessions
118
+ orc session show <id> Show session detail
119
+ ```
120
+
121
+ ## Configuration
122
+
123
+ Create `~/.orc/config.json`:
124
+
125
+ ```json
126
+ {
127
+ "api": {
128
+ "port": 7700,
129
+ "host": "127.0.0.1",
130
+ "secret": "optional-bearer-token"
131
+ }
132
+ }
133
+ ```
134
+
135
+ Key env vars: `ORC_DB_PATH`, `ORC_API_PORT` (default 7700), `ORC_API_SECRET`, `ORC_SESSION_ID`, `ORC_LOG_LEVEL`.
136
+
137
+ ## Cross-agent collaboration
138
+
139
+ All agents share one SQLite file — intentionally.
140
+
141
+ ```
142
+ Claude Code ──┐
143
+ Cursor ──┤──→ ~/.orc/orc.db ←── orc cli (you)
144
+ Codex ──┘
145
+ ```
146
+
147
+ A task created by Claude Code appears in Cursor's context. A rule stored by Codex shows up in Claude Code's memory search.
148
+
149
+ Set `ORC_SESSION_ID` per agent (e.g. `cursor`, `codex`, `claude-code`) so sessions don't collide.
150
+
151
+ ---
152
+
153
+ Full documentation: [github.com/niradler/orc](https://github.com/niradler/orc)
package/dist/index.js CHANGED
@@ -509,5 +509,5 @@ Events (${Y.length}/${J.events.length}):`);let A={file:"\uD83D\uDCC4",task:"\u27
509
509
  Snapshot:`),console.log(J.snapshot);else if(X.snapshot&&!J.snapshot)console.log(`
510
510
  No snapshot stored for this session.`)}),$.command("log <summary>").description("Log a session summary (calls session_log MCP tool)").option("-a, --agent <name>","Agent name","human").option("--agent-version <v>","Agent version string").action(async(w,X)=>{let G=Q0(),E=`http://${G.api.host}:${G.api.port}`,J={"Content-Type":"application/json"};if(G.api.secret)J.Authorization=`Bearer ${G.api.secret}`;let W=await fetch(`${E}/mcp/tool`,{method:"POST",headers:J,body:JSON.stringify({name:"session_log",args:{agent:X.agent,agent_version:X.agentVersion,summary:w}})}),Y=await W.json();if(!W.ok)return console.error("Error:",Y.error);console.log(Y.result)}),$}function AM(){return new V$("status").description("Show system status").action(async()=>{let $=r0(),{data:w,error:X}=await $.health.check();if(X){console.error("API unreachable \u2014 is `orc api` running?");return}console.log(`orc API \u25CF running v${w?.version} uptime: ${w?.uptime}s`);let{data:G}=await $.tasks.list({limit:100}),{data:E}=await $.jobs.list(),{data:J}=await $.memories.list(),W=Fv(G?.tasks??[],"status");console.log(`
511
511
  Tasks:`);for(let[Y,A]of Object.entries(W))console.log(` ${Y.padEnd(20)} ${A}`);console.log(`
512
- Jobs: ${E?.jobs.length??0} defined`),console.log(`Memory: ${J?.memories.length??0} recent entries`)})}function Fv($,w){return $.reduce((X,G)=>{let E=String(G[w]);return X[E]=(X[E]??0)+1,X},{})}async function yJ($,w){if(w.length===26)return w;let{data:X}=await $.tasks.list({limit:100}),G=(X?.tasks??[]).find((E)=>E.id.endsWith(w)||E.id===w);if(!G)return console.error(`Task not found: ${w}`),null;return G.id}function DM(){let $=new V$("task").description("Manage tasks");return $.command("list").description("List tasks").option("-p, --project <id>","Filter by project ID").option("-s, --status <status>","Filter by status").option("-l, --limit <n>","Max results","20").action(async(w)=>{let X=r0(),{data:G,error:E}=await X.tasks.list({project_id:w.project,status:w.status,limit:Number(w.limit)});if(E)return console.error("Error:",E);let J=G?.tasks??[];if(J.length===0)return console.log("No tasks found.");for(let W of J){let Y=Mv(W.status),A=zv(W.priority);if(console.log(`${Y} ${A} [${W.id.slice(-6)}] ${W.title}`),W.project_id)console.log(` project: ${W.project_id}`)}}),$.command("add <title>").description("Create a new task").option("-p, --project <id>","Project ID").option("--priority <p>","Priority (low/normal/high/critical)","normal").option("-b, --body <text>","Task body").action(async(w,X)=>{let G=r0(),{data:E,error:J}=await G.tasks.create({title:w,body:X.body,project_id:X.project,priority:X.priority});if(J)return console.error("Error:",J);console.log(`Created: [${E?.id.slice(-6)}] ${E?.title}`)}),$.command("done <id>").description("Mark task as done (accepts full ULID or last-6 suffix)").action(async(w)=>{let X=r0(),G=await yJ(X,w);if(!G)return;let{data:E,error:J}=await X.tasks.update(G,{status:"done"});if(J)return console.error("Error:",J);console.log(`Done: [${E?.id.slice(-6)}] ${E?.title}`)}),$.command("review <id>").description("Submit task for review").action(async(w)=>{let X=r0(),G=await yJ(X,w);if(!G)return;let{data:E,error:J}=await X.tasks.update(G,{status:"review"});if(J)return console.error("Error:",J);console.log(`In review: [${E?.id.slice(-6)}] ${E?.title}`)}),$.command("approve <id>").description("Approve a task in review (HITL)").option("-n, --note <text>","Optional note to add").action(async(w,X)=>{let G=r0(),E=await yJ(G,w);if(!E)return;let{data:J,error:W}=await G.tasks.get(E);if(W)return console.error("Error:",W);if(J?.status!=="review")return console.error(`Task is not in review (current: ${J?.status})`);let{data:Y,error:A}=await G.tasks.update(E,{status:"done"});if(A)return console.error("Error:",A);if(X.note)await G.tasks.addNote(E,X.note,"human");console.log(`Approved: [${Y?.id.slice(-6)}] ${Y?.title}`)}),$.command("reject <id>").description("Reject a task in review, request changes (HITL)").option("-r, --reason <text>","Reason for rejection").action(async(w,X)=>{let G=r0(),E=await yJ(G,w);if(!E)return;let{data:J,error:W}=await G.tasks.get(E);if(W)return console.error("Error:",W);if(J?.status!=="review")return console.error(`Task is not in review (current: ${J?.status})`);let{data:Y,error:A}=await G.tasks.update(E,{status:"changes_requested"});if(A)return console.error("Error:",A);if(X.reason)await G.tasks.addNote(E,X.reason,"human");console.log(`Changes requested: [${Y?.id.slice(-6)}] ${Y?.title}`)}),$}function Mv($){return{todo:"\u25CB",doing:"\u25D0",review:"\u25C9",changes_requested:"\u21A9",blocked:"\u2298",done:"\u25CF",cancelled:"\u2715"}[$]??"?"}function zv($){return{low:"\u2193",normal:"\u2192",high:"\u2191",critical:"\u203C"}[$]??" "}var M1=new V$().name("orc").description("Human + AI Orchestration Hub").version("0.0.1").option("--db <path>","DB file path (overrides ORC_DB_PATH / config.json)").option("--port <n>","API port (overrides ORC_API_PORT / config.json)").option("--host <host>","API host (overrides ORC_API_HOST / config.json)").option("--secret <secret>","API bearer secret (overrides ORC_API_SECRET / config.json)").option("--log-level <level>","Log level: debug|info|warn|error (overrides ORC_LOG_LEVEL)").option("--runner-timeout <secs>","Default job timeout in seconds (overrides ORC_RUNNER_TIMEOUT)").option("--runner-max-jobs <n>","Max concurrent jobs (overrides ORC_RUNNER_MAX_JOBS)").option("--snapshot-max-bytes <n>","Session snapshot budget bytes (overrides ORC_SNAPSHOT_MAX_BYTES)").hook("preSubcommand",($,w)=>{let X=M1.opts();if(X.db)process.env.ORC_DB_PATH=X.db;if(X.port)process.env.ORC_API_PORT=X.port;if(X.host)process.env.ORC_API_HOST=X.host;if(X.secret)process.env.ORC_API_SECRET=X.secret;if(X.logLevel)process.env.ORC_LOG_LEVEL=X.logLevel;if(X.runnerTimeout)process.env.ORC_RUNNER_TIMEOUT=X.runnerTimeout;if(X.runnerMaxJobs)process.env.ORC_RUNNER_MAX_JOBS=X.runnerMaxJobs;if(X.snapshotMaxBytes)process.env.ORC_SNAPSHOT_MAX_BYTES=X.snapshotMaxBytes});M1.addCommand(DM());M1.addCommand(JM());M1.addCommand(GM());M1.addCommand(YM());M1.addCommand(wM());M1.addCommand(XM());M1.addCommand(AM());M1.command("api").description("Start the API server (use --port / --host / --db / --secret to configure)").action(async()=>{await Promise.resolve().then(() => (U7(),D7)),await new Promise(()=>{})});M1.command("home").description("Show ~/.orc directory contents and daemon state").action(()=>{let $=Q0();console.log(`ORC home: ${xw}
512
+ Jobs: ${E?.jobs.length??0} defined`),console.log(`Memory: ${J?.memories.length??0} recent entries`)})}function Fv($,w){return $.reduce((X,G)=>{let E=String(G[w]);return X[E]=(X[E]??0)+1,X},{})}async function yJ($,w){if(w.length===26)return w;let{data:X}=await $.tasks.list({limit:100}),G=(X?.tasks??[]).find((E)=>E.id.endsWith(w)||E.id===w);if(!G)return console.error(`Task not found: ${w}`),null;return G.id}function DM(){let $=new V$("task").description("Manage tasks");return $.command("list").description("List tasks").option("-p, --project <id>","Filter by project ID").option("-s, --status <status>","Filter by status").option("-l, --limit <n>","Max results","20").action(async(w)=>{let X=r0(),{data:G,error:E}=await X.tasks.list({project_id:w.project,status:w.status,limit:Number(w.limit)});if(E)return console.error("Error:",E);let J=G?.tasks??[];if(J.length===0)return console.log("No tasks found.");for(let W of J){let Y=Mv(W.status),A=zv(W.priority);if(console.log(`${Y} ${A} [${W.id.slice(-6)}] ${W.title}`),W.project_id)console.log(` project: ${W.project_id}`)}}),$.command("add <title>").description("Create a new task").option("-p, --project <id>","Project ID").option("--priority <p>","Priority (low/normal/high/critical)","normal").option("-b, --body <text>","Task body").action(async(w,X)=>{let G=r0(),{data:E,error:J}=await G.tasks.create({title:w,body:X.body,project_id:X.project,priority:X.priority});if(J)return console.error("Error:",J);console.log(`Created: [${E?.id.slice(-6)}] ${E?.title}`)}),$.command("done <id>").description("Mark task as done (accepts full ULID or last-6 suffix)").action(async(w)=>{let X=r0(),G=await yJ(X,w);if(!G)return;let{data:E,error:J}=await X.tasks.update(G,{status:"done"});if(J)return console.error("Error:",J);console.log(`Done: [${E?.id.slice(-6)}] ${E?.title}`)}),$.command("review <id>").description("Submit task for review").action(async(w)=>{let X=r0(),G=await yJ(X,w);if(!G)return;let{data:E,error:J}=await X.tasks.update(G,{status:"review"});if(J)return console.error("Error:",J);console.log(`In review: [${E?.id.slice(-6)}] ${E?.title}`)}),$.command("approve <id>").description("Approve a task in review (HITL)").option("-n, --note <text>","Optional note to add").action(async(w,X)=>{let G=r0(),E=await yJ(G,w);if(!E)return;let{data:J,error:W}=await G.tasks.get(E);if(W)return console.error("Error:",W);if(J?.status!=="review")return console.error(`Task is not in review (current: ${J?.status})`);let{data:Y,error:A}=await G.tasks.update(E,{status:"done"});if(A)return console.error("Error:",A);if(X.note)await G.tasks.addNote(E,X.note,"human");console.log(`Approved: [${Y?.id.slice(-6)}] ${Y?.title}`)}),$.command("reject <id>").description("Reject a task in review, request changes (HITL)").option("-r, --reason <text>","Reason for rejection").action(async(w,X)=>{let G=r0(),E=await yJ(G,w);if(!E)return;let{data:J,error:W}=await G.tasks.get(E);if(W)return console.error("Error:",W);if(J?.status!=="review")return console.error(`Task is not in review (current: ${J?.status})`);let{data:Y,error:A}=await G.tasks.update(E,{status:"changes_requested"});if(A)return console.error("Error:",A);if(X.reason)await G.tasks.addNote(E,X.reason,"human");console.log(`Changes requested: [${Y?.id.slice(-6)}] ${Y?.title}`)}),$}function Mv($){return{todo:"\u25CB",doing:"\u25D0",review:"\u25C9",changes_requested:"\u21A9",blocked:"\u2298",done:"\u25CF",cancelled:"\u2715"}[$]??"?"}function zv($){return{low:"\u2193",normal:"\u2192",high:"\u2191",critical:"\u203C"}[$]??" "}var M1=new V$().name("orc").description("Human + AI Orchestration Hub").version("0.1.2").option("--db <path>","DB file path (overrides ORC_DB_PATH / config.json)").option("--port <n>","API port (overrides ORC_API_PORT / config.json)").option("--host <host>","API host (overrides ORC_API_HOST / config.json)").option("--secret <secret>","API bearer secret (overrides ORC_API_SECRET / config.json)").option("--log-level <level>","Log level: debug|info|warn|error (overrides ORC_LOG_LEVEL)").option("--runner-timeout <secs>","Default job timeout in seconds (overrides ORC_RUNNER_TIMEOUT)").option("--runner-max-jobs <n>","Max concurrent jobs (overrides ORC_RUNNER_MAX_JOBS)").option("--snapshot-max-bytes <n>","Session snapshot budget bytes (overrides ORC_SNAPSHOT_MAX_BYTES)").hook("preSubcommand",($,w)=>{let X=M1.opts();if(X.db)process.env.ORC_DB_PATH=X.db;if(X.port)process.env.ORC_API_PORT=X.port;if(X.host)process.env.ORC_API_HOST=X.host;if(X.secret)process.env.ORC_API_SECRET=X.secret;if(X.logLevel)process.env.ORC_LOG_LEVEL=X.logLevel;if(X.runnerTimeout)process.env.ORC_RUNNER_TIMEOUT=X.runnerTimeout;if(X.runnerMaxJobs)process.env.ORC_RUNNER_MAX_JOBS=X.runnerMaxJobs;if(X.snapshotMaxBytes)process.env.ORC_SNAPSHOT_MAX_BYTES=X.snapshotMaxBytes});M1.addCommand(DM());M1.addCommand(JM());M1.addCommand(GM());M1.addCommand(YM());M1.addCommand(wM());M1.addCommand(XM());M1.addCommand(AM());M1.command("api").description("Start the API server (use --port / --host / --db / --secret to configure)").action(async()=>{await Promise.resolve().then(() => (U7(),D7)),await new Promise(()=>{})});M1.command("home").description("Show ~/.orc directory contents and daemon state").action(()=>{let $=Q0();console.log(`ORC home: ${xw}
513
513
  `);let w=[{label:"DB",path:$.db.path},{label:"config",path:`${xw}/config.json`},{label:"pid",path:QG},{label:"daemon log",path:`${xw}/daemon.log`}];for(let G of w)if(np(G.path)){let E=Math.round(pp(G.path).size/1024);console.log(` \u2713 ${G.label.padEnd(12)} ${G.path} (${E}KB)`)}else console.log(` \xB7 ${G.label.padEnd(12)} ${G.path} (not found)`);let X=fJ();if(console.log(),X)try{process.kill(X,0),console.log(` daemon \u25CF running pid:${X}`)}catch{console.log(` daemon \u25CB stopped (stale pid: ${X})`)}else console.log(" daemon \u25CB not running");console.log(),console.log(` config port:${$.api.port} host:${$.api.host} secret:${$.api.secret?"***":"(none)"}`)});M1.command("mcp").description("Start the MCP server (stdio)").action(async()=>{let{startStdioServer:$}=await oI().then(() => iI);await $()});M1.parseAsync(process.argv).catch(($)=>{console.error($ instanceof Error?$.message:$),process.exit(1)});
package/package.json CHANGED
@@ -1,63 +1,63 @@
1
- {
2
- "name": "orc-ai",
3
- "version": "0.1.1",
4
- "description": "Human + AI Orchestration Hub — persistent memory, task management, session continuity and multi-agent collaboration for Cursor, Claude Code, and Codex",
5
- "type": "module",
6
- "bin": {
7
- "orc": "./dist/index.js"
8
- },
9
- "scripts": {
10
- "dev": "bun run --watch src/index.ts",
11
- "start": "bun run src/index.ts",
12
- "typecheck": "tsc --noEmit",
13
- "build": "bun build src/index.ts --outfile dist/index.js --target bun --minify",
14
- "build:bin": "bun run build.ts",
15
- "prepublishOnly": "bun run build",
16
- "test": "bun test",
17
- "clean": "rm -rf dist"
18
- },
19
- "files": [
20
- "dist/index.js"
21
- ],
22
- "devDependencies": {
23
- "@orc/api": "workspace:*",
24
- "@orc/core": "workspace:*",
25
- "@orc/gateway": "workspace:*",
26
- "@orc/mcp": "workspace:*",
27
- "@orc/runner": "workspace:*",
28
- "@orc/sdk": "workspace:*",
29
- "commander": "^13.1.0",
30
- "typescript": "^5.7.3"
31
- },
32
- "peerDependencies": {
33
- "bun": ">=1.0.0"
34
- },
35
- "peerDependenciesMeta": {
36
- "bun": {
37
- "optional": false
38
- }
39
- },
40
- "keywords": [
41
- "ai",
42
- "agent",
43
- "orchestration",
44
- "mcp",
45
- "claude",
46
- "cursor",
47
- "codex",
48
- "memory",
49
- "tasks",
50
- "hitl",
51
- "sessions"
52
- ],
53
- "license": "MIT",
54
- "repository": {
55
- "type": "git",
56
- "url": "https://github.com/niradler/orc"
57
- },
58
- "homepage": "https://github.com/niradler/orc",
59
- "publishConfig": {
60
- "access": "public",
61
- "registry": "https://registry.npmjs.org/"
62
- }
63
- }
1
+ {
2
+ "name": "orc-ai",
3
+ "version": "0.1.3",
4
+ "description": "Human + AI Orchestration Hub — persistent memory, task management, session continuity and multi-agent collaboration for Cursor, Claude Code, and Codex",
5
+ "type": "module",
6
+ "bin": {
7
+ "orc": "./dist/index.js"
8
+ },
9
+ "scripts": {
10
+ "dev": "bun run --watch src/index.ts",
11
+ "start": "bun run src/index.ts",
12
+ "typecheck": "tsc --noEmit",
13
+ "build": "bun build src/index.ts --outfile dist/index.js --target bun --minify",
14
+ "build:bin": "bun run build.ts",
15
+ "prepublishOnly": "bun run build",
16
+ "test": "bun test",
17
+ "clean": "rm -rf dist"
18
+ },
19
+ "files": [
20
+ "dist/index.js"
21
+ ],
22
+ "devDependencies": {
23
+ "@orc/api": "workspace:*",
24
+ "@orc/core": "workspace:*",
25
+ "@orc/gateway": "workspace:*",
26
+ "@orc/mcp": "workspace:*",
27
+ "@orc/runner": "workspace:*",
28
+ "@orc/sdk": "workspace:*",
29
+ "commander": "^13.1.0",
30
+ "typescript": "^5.7.3"
31
+ },
32
+ "peerDependencies": {
33
+ "bun": ">=1.0.0"
34
+ },
35
+ "peerDependenciesMeta": {
36
+ "bun": {
37
+ "optional": false
38
+ }
39
+ },
40
+ "keywords": [
41
+ "ai",
42
+ "agent",
43
+ "orchestration",
44
+ "mcp",
45
+ "claude",
46
+ "cursor",
47
+ "codex",
48
+ "memory",
49
+ "tasks",
50
+ "hitl",
51
+ "sessions"
52
+ ],
53
+ "license": "MIT",
54
+ "repository": {
55
+ "type": "git",
56
+ "url": "git+https://github.com/niradler/orc.git"
57
+ },
58
+ "homepage": "https://github.com/niradler/orc",
59
+ "publishConfig": {
60
+ "access": "public",
61
+ "registry": "https://registry.npmjs.org/"
62
+ }
63
+ }