{"_id":"@ai-atomic-workflow/graph-scheduler","_rev":"7-7034553ec5db3d4de3330c5eaca80409","name":"@ai-atomic-workflow/graph-scheduler","dist-tags":{"latest":"0.6.0"},"versions":{"0.1.0":{"name":"@ai-atomic-workflow/graph-scheduler","version":"0.1.0","keywords":["graph","workflow","dag","fsm","taskflow","agent","automation","mcp","orchestration","mcp-server","effect-ts"],"author":{"name":"makarawang","email":"makara15@gmail.com"},"license":"MIT","_id":"@ai-atomic-workflow/graph-scheduler@0.1.0","maintainers":[{"name":"makara","email":"makara15@gmail.com"}],"homepage":"https://github.com/makara/ai-atomic-workflow#readme","bugs":{"url":"https://github.com/makara/ai-atomic-workflow/issues"},"bin":{"atom-graph-scheduler":"server.ts"},"dist":{"shasum":"b5af5f92d3eab377851ae0a3072c1443dccbbe30","tarball":"https://registry.npmjs.org/@ai-atomic-workflow/graph-scheduler/-/graph-scheduler-0.1.0.tgz","fileCount":58,"integrity":"sha512-w/OoEP8zwkMbSwuiAe/U+kF04+Cir2Xcg9Mc+9FYBMGr75si+QIpsmUMiy5mo0At+QTs9I221TElzPei3FgFJg==","signatures":[{"sig":"MEYCIQDoQmiAoxoDpixX4JLP4nMHX5Q1AZYjZ0Tm2vhMv0ntlwIhAM0BvV684R0yNQT2Ka6Iw+ixbEm4NHiue9+V/z4+GNxF","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":654061},"type":"module","engines":{"bun":">=1.0.0","node":">=22.0.0"},"gitHead":"004e748c148997f7f2e2e28fc8eaafd38e9e169f","scripts":{"test":"vitest run","build":"tsup","start":"bun run server.ts","prepack":"yarn build && yarn test","typecheck":"tsc --noEmit -p tsconfig.typecheck.json","test:watch":"vitest"},"_npmUser":{"name":"makara","email":"makara15@gmail.com"},"repository":{"url":"git+https://github.com/makara/ai-atomic-workflow.git","type":"git","directory":"packages/graph-scheduler"},"_npmVersion":"10.9.8","description":"Graph-driven work-order system for AI agents — explicit phases, scoped context, and non-bypassable approval gates.","directories":{},"_nodeVersion":"22.23.0","dependencies":{"zod":"4.4.3","yaml":"2.9.0","effect":"3.22.1","libsql":"0.5.29","@modelcontextprotocol/sdk":"1.30.0"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","vitest":"^4.1.10","typescript":"^6.0.3","@types/node":"^26.1.2"},"_npmOperationalInternal":{"tmp":"tmp/graph-scheduler_0.1.0_1785678886788_0.8402154996738092","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@ai-atomic-workflow/graph-scheduler","version":"0.2.0","keywords":["graph","workflow","dag","fsm","taskflow","agent","automation","mcp","orchestration","mcp-server","effect-ts"],"author":{"name":"makarawang","email":"makara15@gmail.com"},"license":"MIT","_id":"@ai-atomic-workflow/graph-scheduler@0.2.0","maintainers":[{"name":"makara","email":"makara15@gmail.com"}],"homepage":"https://github.com/makara/ai-atomic-workflow#readme","bugs":{"url":"https://github.com/makara/ai-atomic-workflow/issues"},"bin":{"atom-graph-scheduler":"server.ts"},"dist":{"shasum":"37b53748e41b521db33a2301651d2e3fd1184114","tarball":"https://registry.npmjs.org/@ai-atomic-workflow/graph-scheduler/-/graph-scheduler-0.2.0.tgz","fileCount":62,"integrity":"sha512-O1tTBo0mFW+UFXiKGmmCi1aiiZHrtCkRCOieGFR43sX6j/PLrpXGrG6KNstLqE/k+wZ5tD/HuKR2WsGlDuZVFw==","signatures":[{"sig":"MEUCICennqMsOZUNpntiaBi22oAZHCRxMdkt/U1zc+g8MC76AiEAhfcqzA6mWN4BmKIcesNG7PcmesYz82yqTKQTPfBAvBw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":772105},"type":"module","engines":{"bun":">=1.0.0","node":">=22.0.0"},"gitHead":"bf8ce32f38379344de9e7d64a5aa7cb860caaee6","scripts":{"test":"vitest run","build":"tsup","start":"bun run server.ts","prepack":"yarn build && yarn test","typecheck":"tsc --noEmit -p tsconfig.typecheck.json","test:watch":"vitest"},"_npmUser":{"name":"makara","email":"makara15@gmail.com"},"repository":{"url":"git+https://github.com/makara/ai-atomic-workflow.git","type":"git","directory":"packages/graph-scheduler"},"_npmVersion":"10.9.8","description":"Graph-driven work-order system for AI agents — explicit phases, scoped context, and non-bypassable approval gates.","directories":{},"_nodeVersion":"22.23.0","dependencies":{"zod":"4.4.3","yaml":"2.9.0","effect":"3.22.1","libsql":"0.5.29","@modelcontextprotocol/sdk":"1.30.0"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","vitest":"^4.1.10","typescript":"^6.0.3","@types/node":"^26.1.2"},"_npmOperationalInternal":{"tmp":"tmp/graph-scheduler_0.2.0_1785857398787_0.9820379537789656","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@ai-atomic-workflow/graph-scheduler","version":"0.3.0","keywords":["graph","workflow","dag","fsm","taskflow","agent","automation","mcp","orchestration","mcp-server","effect-ts"],"author":{"name":"makarawang","email":"makara15@gmail.com"},"license":"MIT","_id":"@ai-atomic-workflow/graph-scheduler@0.3.0","maintainers":[{"name":"makara","email":"makara15@gmail.com"}],"homepage":"https://github.com/makara/ai-atomic-workflow#readme","bugs":{"url":"https://github.com/makara/ai-atomic-workflow/issues"},"bin":{"atom-graph-scheduler":"server.ts"},"dist":{"shasum":"86d461617d36c8ca0d33d9093122b89c6e7ce199","tarball":"https://registry.npmjs.org/@ai-atomic-workflow/graph-scheduler/-/graph-scheduler-0.3.0.tgz","fileCount":57,"integrity":"sha512-WeDMl7/43+tWjh/LsQvP+hq0jdnJMvG1r3bFuy3mHfnJessOxO1Q7H/6GxhFZ2Cp10JnK3WyFsQbfhmvIMP1Fw==","signatures":[{"sig":"MEUCIQDD0bphdQxGjIQQlvpycPM+jAPsxh43U/IXi8btLOka8wIgZ8Anryizjn+mi8cWEX7Nbk+I8mcjzgAjsN3SqZLvU74=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":790994},"type":"module","engines":{"bun":">=1.0.0","node":">=22.0.0"},"gitHead":"a06661e6ef9138d60de9434738e62ea0fc86c9be","scripts":{"test":"vitest run","build":"tsup","start":"bun run server.ts","prepack":"yarn build && yarn test","typecheck":"tsc --noEmit -p tsconfig.typecheck.json","test:watch":"vitest"},"_npmUser":{"name":"makara","email":"makara15@gmail.com"},"repository":{"url":"git+https://github.com/makara/ai-atomic-workflow.git","type":"git","directory":"packages/graph-scheduler"},"_npmVersion":"10.9.8","description":"Graph-driven work-order system for AI agents — explicit phases, scoped context, and non-bypassable approval gates.","directories":{},"_nodeVersion":"22.23.0","dependencies":{"zod":"4.4.3","yaml":"2.9.0","effect":"3.22.1","libsql":"0.5.29","@modelcontextprotocol/sdk":"1.30.0"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","vitest":"^4.1.10","typescript":"^6.0.3","@types/node":"^26.1.2"},"_npmOperationalInternal":{"tmp":"tmp/graph-scheduler_0.3.0_1786009520627_0.18571041933732602","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@ai-atomic-workflow/graph-scheduler","version":"0.3.1","keywords":["graph","workflow","dag","fsm","taskflow","agent","automation","mcp","orchestration","mcp-server","effect-ts"],"author":{"name":"makarawang","email":"makara15@gmail.com"},"license":"MIT","_id":"@ai-atomic-workflow/graph-scheduler@0.3.1","maintainers":[{"name":"makara","email":"makara15@gmail.com"}],"homepage":"https://github.com/makara/ai-atomic-workflow#readme","bugs":{"url":"https://github.com/makara/ai-atomic-workflow/issues"},"bin":{"atom-graph-scheduler":"server.ts"},"dist":{"shasum":"f62b2f61b04b9eb9e597d1214b83513800e8cf52","tarball":"https://registry.npmjs.org/@ai-atomic-workflow/graph-scheduler/-/graph-scheduler-0.3.1.tgz","fileCount":57,"integrity":"sha512-d84Dbdc1BUNZVj95YCgQXFNR8NURuh90L0TKzjXvo4ZeYxCT94heP/86UDAYgH7MSG7jkIhd5S0irlhEVwH4Ow==","signatures":[{"sig":"MEUCIQDApj+OEf6rrVkUaU1mcNi9CiZ5Q5NwFp53xwQnOqc9RQIgSU3YUduFhpJjTwcSHV3CWGo00ZNphOLvVPzbpocaDTQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":790994},"type":"module","engines":{"bun":">=1.0.0","node":">=22.0.0"},"gitHead":"3b9fd5df1274f73a8a0ffb274ceca94236882975","scripts":{"test":"vitest run","build":"tsup","start":"bun run server.ts","prepack":"yarn build && yarn test","typecheck":"tsc --noEmit -p tsconfig.typecheck.json","test:watch":"vitest"},"_npmUser":{"name":"makara","email":"makara15@gmail.com"},"repository":{"url":"git+https://github.com/makara/ai-atomic-workflow.git","type":"git","directory":"packages/graph-scheduler"},"_npmVersion":"10.9.8","description":"Graph-driven work-order system for AI agents — explicit phases, scoped context, and non-bypassable approval gates.","directories":{},"_nodeVersion":"22.23.0","dependencies":{"zod":"4.4.3","yaml":"2.9.0","effect":"3.22.1","libsql":"0.5.29","@modelcontextprotocol/sdk":"1.30.0"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","vitest":"^4.1.10","typescript":"^6.0.3","@types/node":"^26.1.2"},"_npmOperationalInternal":{"tmp":"tmp/graph-scheduler_0.3.1_1786009721757_0.47042499484971234","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@ai-atomic-workflow/graph-scheduler","version":"0.4.0","keywords":["agent","agent-skills","agentic-engineering","agentic-workflow","graph-engineering","mcp-server","mcp","openspec","workflow","workflow-automation","workflow-orchestration"],"author":{"name":"makarawang","email":"makara15@gmail.com"},"license":"MIT","_id":"@ai-atomic-workflow/graph-scheduler@0.4.0","maintainers":[{"name":"makara","email":"makara15@gmail.com"}],"homepage":"https://github.com/makara/ai-atomic-workflow#readme","bugs":{"url":"https://github.com/makara/ai-atomic-workflow/issues"},"bin":{"atom-graph-scheduler":"server.ts"},"dist":{"shasum":"7aebc2d7ef5f5567ca0eae0d6a105b079fe4eccc","tarball":"https://registry.npmjs.org/@ai-atomic-workflow/graph-scheduler/-/graph-scheduler-0.4.0.tgz","fileCount":59,"integrity":"sha512-LIy3MU3sX80pofR/fMd789JJXyGLDiz3SqRlKoVbk0dW6SsACOykUOXSx8zSKfWTGDNC0QtDlL3B6zTtE9Noqw==","signatures":[{"sig":"MEQCIDJOfScHyIn5VuL96dYPDXzhgFOnnuK5r1s7rbBcZdouAiADnkW6n115C+Qs9DkIprEDKOJXbPrRluEkHLr731XoPQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":840202},"type":"module","engines":{"bun":">=1.0.0","node":">=22.0.0"},"gitHead":"7726b20d406d6d000f6a1f33d1d38e560bfc783f","scripts":{"test":"vitest run","build":"tsup","start":"bun run server.ts","prepack":"yarn build && yarn test","typecheck":"tsc --noEmit -p tsconfig.typecheck.json","test:watch":"vitest"},"_npmUser":{"name":"makara","email":"makara15@gmail.com"},"repository":{"url":"git+https://github.com/makara/ai-atomic-workflow.git","type":"git","directory":"packages/graph-scheduler"},"_npmVersion":"10.9.8","description":"Graph-Engineering for Real Engineers: Graphs define workflows; workflows build graphs. Based on mattpocock/skills.","directories":{},"_nodeVersion":"22.23.0","dependencies":{"zod":"4.4.3","yaml":"2.9.0","effect":"3.22.1","libsql":"0.5.29","@modelcontextprotocol/sdk":"1.30.0"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","vitest":"^4.1.10","typescript":"^6.0.3","@types/node":"^26.1.2"},"_npmOperationalInternal":{"tmp":"tmp/graph-scheduler_0.4.0_1786342970160_0.3758970230922425","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@ai-atomic-workflow/graph-scheduler","version":"0.5.0","keywords":["agent","agent-skills","agentic-engineering","agentic-workflow","graph-engineering","mcp-server","mcp","openspec","workflow","workflow-automation","workflow-orchestration"],"author":{"name":"makarawang","email":"makara15@gmail.com"},"license":"MIT","_id":"@ai-atomic-workflow/graph-scheduler@0.5.0","maintainers":[{"name":"makara","email":"makara15@gmail.com"}],"homepage":"https://github.com/makara/ai-atomic-workflow#readme","bugs":{"url":"https://github.com/makara/ai-atomic-workflow/issues"},"bin":{"atom-graph-scheduler":"server.ts"},"dist":{"shasum":"f47d5f0c278886169fb23dd48703f022e13f365c","tarball":"https://registry.npmjs.org/@ai-atomic-workflow/graph-scheduler/-/graph-scheduler-0.5.0.tgz","fileCount":58,"integrity":"sha512-GqKOGSG9QHjJ8Bh46A6qL9zoBJz8x70xiaj+D1eze3ZnK2xgVSL/AS7Dvupg9t+Gka23l2cPIka08TkR4AaowQ==","signatures":[{"sig":"MEQCIDQbHMF1AHCtDRAWP8XYU+xEKiRV9kOousx1APcBxF4dAiB8td+xgeIS5IlkwUFnIJTTS1tDolmMa7t96oWi7ze6bQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":721260},"type":"module","engines":{"bun":">=1.0.0","node":">=22.0.0"},"gitHead":"4ecaafd73218aa3735e1ba67897e60d804d78e55","scripts":{"test":"vitest run","build":"tsup","start":"bun run server.ts","prepack":"yarn build && yarn test","typecheck":"tsc --noEmit -p tsconfig.typecheck.json","test:watch":"vitest"},"_npmUser":{"name":"makara","email":"makara15@gmail.com"},"repository":{"url":"git+https://github.com/makara/ai-atomic-workflow.git","type":"git","directory":"packages/graph-scheduler"},"_npmVersion":"10.9.8","description":"Graph-Engineering for Real Engineers: Graphs define workflows; workflows build graphs. Based on mattpocock/skills.","directories":{},"_nodeVersion":"22.23.0","dependencies":{"zod":"4.4.3","yaml":"2.9.0","effect":"3.22.1","libsql":"0.5.29","@modelcontextprotocol/sdk":"1.30.0"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","vitest":"^4.1.10","typescript":"^6.0.3","@types/node":"^26.2.0"},"_npmOperationalInternal":{"tmp":"tmp/graph-scheduler_0.5.0_1786728587768_0.10585380282296031","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"@ai-atomic-workflow/graph-scheduler","version":"0.6.0","description":"Graph-Engineering for Real Engineers: Graphs define workflows; workflows build graphs. Based on mattpocock/skills.","keywords":["agent","agent-skills","agentic-engineering","agentic-workflow","graph-engineering","mcp-server","mcp","openspec","workflow","workflow-automation","workflow-orchestration"],"homepage":"https://github.com/makara/ai-atomic-workflow#readme","bugs":{"url":"https://github.com/makara/ai-atomic-workflow/issues"},"repository":{"type":"git","url":"git+https://github.com/makara/ai-atomic-workflow.git","directory":"packages/graph-scheduler"},"license":"MIT","author":{"name":"makarawang","email":"makara15@gmail.com"},"type":"module","bin":{"atom-graph-scheduler":"server.ts"},"scripts":{"build":"tsup","prepack":"yarn build && yarn test","schema:gen":"bun run scripts/schema-gen.ts","start":"bun run server.ts","test":"vitest run","test:watch":"vitest","typecheck":"tsc --noEmit -p tsconfig.typecheck.json"},"dependencies":{"@langchain/core":"^1.1.48","@langchain/langgraph":"1.4.10","@langchain/langgraph-checkpoint":"1.1.3","@modelcontextprotocol/sdk":"1.30.0","effect":"3.22.1","jsdom":"30.0.1","libsql":"0.5.29","mermaid":"11.16.1","yaml":"2.9.0","zod":"4.4.3"},"devDependencies":{"@types/jsdom":"^30","@types/node":"^26.2.0","prettier":"^3.9.6","tsup":"^8.5.1","typescript":"^6.0.3","vitest":"^4.1.10"},"engines":{"bun":">=1.0.0","node":">=22.0.0"},"_id":"@ai-atomic-workflow/graph-scheduler@0.6.0","gitHead":"77991b61666ad9527da0b2e3150fd2edf5423c83","_nodeVersion":"22.23.0","_npmVersion":"10.9.8","dist":{"integrity":"sha512-Sy77+WntHFih6An9d8hYUvHZgVRJKX/5smt3aEXha2Qd1Ys7Yi/TJHQtEs0QUQhfKLh/aVOMfuh6mVMZojunyA==","shasum":"4861d17a67cc8ee0589b2139ce828bfa60f3c185","tarball":"https://registry.npmjs.org/@ai-atomic-workflow/graph-scheduler/-/graph-scheduler-0.6.0.tgz","fileCount":57,"unpackedSize":799287,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCP36xN6k08pfWOR9aaYhuAleCxzgLwr8U/ihKMRdWU5wIgB23XU4c9ANVABoga99RhbWzuggtjf/FvHijEbNY9z64="}]},"_npmUser":{"name":"makara","email":"makara15@gmail.com"},"directories":{},"maintainers":[{"name":"makara","email":"makara15@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/graph-scheduler_0.6.0_1787225031204_0.6483486565297436"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-02T13:54:46.560Z","modified":"2026-08-20T11:23:51.577Z","0.1.0":"2026-08-02T13:54:47.011Z","0.2.0":"2026-08-04T15:29:58.947Z","0.3.0":"2026-08-06T09:45:20.803Z","0.3.1":"2026-08-06T09:48:41.930Z","0.4.0":"2026-08-10T06:22:50.311Z","0.5.0":"2026-08-14T17:29:47.934Z","0.6.0":"2026-08-20T11:23:51.372Z"},"bugs":{"url":"https://github.com/makara/ai-atomic-workflow/issues"},"author":{"name":"makarawang","email":"makara15@gmail.com"},"license":"MIT","homepage":"https://github.com/makara/ai-atomic-workflow#readme","keywords":["agent","agent-skills","agentic-engineering","agentic-workflow","graph-engineering","mcp-server","mcp","openspec","workflow","workflow-automation","workflow-orchestration"],"repository":{"type":"git","url":"git+https://github.com/makara/ai-atomic-workflow.git","directory":"packages/graph-scheduler"},"description":"Graph-Engineering for Real Engineers: Graphs define workflows; workflows build graphs. Based on mattpocock/skills.","maintainers":[{"name":"makara","email":"makara15@gmail.com"}],"readme":"# graph-scheduler\n\n> ⚠️ AI-generated README — edit [docs/readme-blueprint.md](../../docs/readme-blueprint.md) instead.\n\n## Table of Contents\n\n- [graph-scheduler](#graph-scheduler)\n  - [Table of Contents](#table-of-contents)\n  - [Overview](#overview)\n  - [Requirements](#requirements)\n  - [Install](#install)\n  - [MCP Registration](#mcp-registration)\n    - [Environment](#environment)\n  - [Project Setup](#project-setup)\n  - [Graph Format](#graph-format)\n    - [Phase fields](#phase-fields)\n    - [Top-level `flow` field](#top-level-flow-field)\n  - [MCP Tools](#mcp-tools)\n    - [NextNode types](#nextnode-types)\n    - [Typical call flow](#typical-call-flow)\n  - [Built-in Graphs](#built-in-graphs)\n  - [arch-review-loop — one loop, one problem](#arch-review-loop--one-loop-one-problem)\n  - [Making a Graph](#making-a-graph)\n  - [Development](#development)\n  - [FAQ](#faq)\n    - [graph\\_start returns a node but the agent doesn't respond?](#graph_start-returns-a-node-but-the-agent-doesnt-respond)\n    - [Does graph\\_start take a mode parameter?](#does-graph_start-take-a-mode-parameter)\n    - [How do I see run history?](#how-do-i-see-run-history)\n    - [How do I abort a stuck run?](#how-do-i-abort-a-stuck-run)\n    - [Where is the database?](#where-is-the-database)\n\n## Overview\n\nGraph-Engineering for Real Engineers: Graphs define workflows; workflows build graphs. Based on mattpocock/skills.\n\nGraph execution engine as a standalone **MCP Server** (stdio transport) — 10 MCP tools, no network port.\n\ngraph-scheduler is the infrastructure half of Atomic Workflow. It loads workflow YAML graph definitions (`.yaml` — schema-determined identity), schedules phases in topological order, manages approval decisions, and persists run state. The agent does all the actual work; the scheduler only issues work orders and tracks progress.\n\n**Stack**: bun · Effect-TS · zod v4 (validation) · libsql (persistence) · MCP SDK\n\n## Requirements\n\nTwo supported runtimes — pick one; the installer matches the runtime:\n\n|Runtime|Version|Used by|\n|-|-|-|\n|[Node](https://nodejs.org)|>= 22|npm route — runs the compiled entry `dist/server.js`|\n|[bun](https://bun.sh)|>= 1|bun route — runs the TypeScript entry `server.ts` natively|\n\n## Install\n\nTwo routes — the runtime matches the installer:\n\n**Option A: npm + Node runtime**\n\n```bash\nnpm install -g @ai-atomic-workflow/graph-scheduler\n```\n\nResolve the global path (used by the MCP registration below):\n\n```bash\nnpm root -g   # → <npm-root>, e.g. /usr/local/lib/node_modules\n```\n\n**Option B: bun**\n\n```bash\nbun add -g @ai-atomic-workflow/graph-scheduler\n```\n\nResolve the global bin folder:\n\n```bash\nbun pm bin -g   # → <bun-bin>, e.g. ~/.bun/bin\n```\n\nVerify either route:\n\n```bash\nnpm list -g @ai-atomic-workflow/graph-scheduler\n# @ai-atomic-workflow/graph-scheduler@0.6.0\n```\n\nThis installs the `atom-graph-scheduler` bin alongside the package.\n\n## MCP Registration\n\ngraph-scheduler speaks MCP JSON-RPC 2.0 over stdio. Register it in your platform's MCP config — the command invokes your chosen runtime explicitly:\n\n**npm + Node** — replace `<npm-root>` with the `npm root -g` output:\n\n```json\n{\n  \"mcpServers\": {\n    \"graph-scheduler\": {\n      \"command\": \"node\",\n      \"args\": [\"<npm-root>/@ai-atomic-workflow/graph-scheduler/dist/server.js\"]\n    }\n  }\n}\n```\n\n**bun** — replace `<bun-bin>` with the `bun pm bin -g` output:\n\n```json\n{\n  \"mcpServers\": {\n    \"graph-scheduler\": {\n      \"command\": \"bun\",\n      \"args\": [\"<bun-bin>/atom-graph-scheduler\"]\n    }\n  }\n}\n```\n\nConfig file locations: OMP → `~/.omp/agent/mcp.json`, OpenCode → `opencode.json` — same JSON either way.\n\nThe platform manages the process lifecycle: discover → spawn → connect → health check → reconnect. A crash doesn't kill the session — the platform reconnects automatically.\n\n### Environment\n\n|Variable|Default|Meaning|\n|-|-|-|\n|`GS_DB_PATH`|`:memory:`|libsql database file — stores `graph_runs` and the checkpoint store (`checkpoints` + `checkpoint_writes`). Scaffolded `config.json` supplies `.graph-scheduler/data/graph-scheduler.db`; env overrides config; falls back to `:memory:` when unset everywhere.|\n\n## Project Setup\n\nInitialize a project with the **setup-atomic-workflow** skill (the retired `atom-graph-config` CLI no longer exists):\n\n```text\nUse setup-atomic-workflow to initialize this project\n```\n\nThe skill runs a four-step flow (explore → present → confirm → write) and scaffolds `.graph-scheduler/`:\n\n- `config.json` — dbPath, taskflowDir, registryPaths; optional `context:` = USER-supplement layer (user-owned ambient files, existence-validated — never required; platform estate is organically discovered, no declaration needed)\n- `graphs/` — where your custom workflow YAML graph files live (any `.yaml` passing schema validation)\n- `constraints.md` — rules enforced on every graph run\n\nIdempotent: never overwrites existing files. Re-running writes nothing.\n\n## Graph Format\n\nA workflow YAML graph declares phases and their dependencies — any `.yaml` file that passes schema validation is a graph (suffix-free, self-describing via `$schema` + `version` headers):\n\n```yaml\nname: e2e-minimal\n$schema: workflow.schema.json\nversion: 1.0.0\nphases:\n  - id: agent-echo\n    type: main\n    dependsOn: []\n    task: say hello in a random language.\n\n  - id: approval-review\n    type: main\n    dependsOn: [agent-echo]\n    task: |\n      Review the agent output.\n\n      Agent output produced. Accept → proceed. Recommendation: accept when the\n      output is correct; free input overrides; dynamic option regenerate\n      re-runs agent-echo with feedback.\n```\n\n### Phase fields\n\n|Field|Meaning|\n|-|-|\n|`id`|Unique phase id — referenced by `dependsOn` and rework/branch targets|\n|`type`|`main` (inline execution + decision) — the only phase type (the `flow` type is removed; subgraph composition via `use` is deleted — nested execution is `template: router` sibling runs)|\n|`dependsOn`|Declared upstream phases — the graph runs a phase only when all of them completed|\n|`task`|Main: the work order — exact prompt for the agent, `{args.key}` templates interpolated at run time; the main node's confirmation text follows the work order (Accept + free input + contextual options)|\n|`skill`|Execution skill for this phase (e.g. `atom-scope-interview`) — how the phase's work gets done|\n|`agent`|Priority hints — `string[]` of agent types (e.g. `[reviewer, task]`); advisory, consumed by skills when they dispatch sub-agents (main type only)|\n|`operations`|Operation classes — declared execution classes (declarative only; scheduler passes through to NodeDetail, Tool usage check verifies evidence-only)|\n|`channels`|Context patterns — graph-level global `context:` (config `context:` = the USER-supplement layer, merged once config-first) plus per-phase `channels:` additions. Entries are `skill:<name>` (skill content), file globs (workflow runtime artifacts only), or `node:<id>` (read edge to a non-`dependsOn` node's output stream; `context: [node:<id>]` promotes a stream into the global channel), resolved against the execution skill's Context Requirements contract; main carries any entry kind. The platform estate (`docs/adr/**`, `openspec/**`, CHANGELOG, README) is read organically by the agent when present — never declared in config|\n|`template`|Builtin task-template reference — closed enum (`startup` \\| `router`); the node's task text is injected from the template registry at load time. Mutually exclusive with `task` (the `use` field no longer exists); `startup` template nodes are graph entries (`dependsOn` empty), `router` nodes sit mid-graph and select among candidate graphs (paths). The `loop` template is removed (ADR 0238 → graph-flow) — loop/rework semantics are top-level `flow` self-edges|\n|`template_args`|Template parameters — `{ paths: [<graph-name>, ...] }` for `template: router` (candidate graphs — the only selection form; required with the template, rejected without). The loop `{ graph, until }` shape does not exist|\n\n### Top-level `flow` field\n\nThe workflow SHALL optionally declare a top-level `flow` array — mermaid-subset transition edges (`A --> B` unlabeled sequence default, `A -->|condition| B` condition-matched), compiled into the per-node transition table (node × condition → target). The backend routes a condition-matched advance mechanically (string equality — the condition vocabulary is flow-defined, zero machine validation axis; governance = graph-maintain flow audit + user maintenance, mirroring the inventory regime). Loop/rework semantics are flow self-edges (`review -->|fail| execute`) — inline bounded loops (constraint prose + retryCount), never a subgraph/task-template mechanism. The frontend never picks a next node — it reports the condition value and the graph decides.\n\n## MCP Tools\n\n10 tools, one action per tool, each with its own JSON Schema (MCP tool parameter schemas — distinct from the graph-format JSON Schema at `schemas/workflow.schema.json`):\n\n|Tool|Parameters|What it does|\n|-|-|-|\n|`graph_start`|`graphName: string`, `args?: object`|Create a run, return the first ready node (NextNode) — plus resolution identity (`resolvedFrom` / `resolvedPath` / `description`) and load-time machine `problems` (inventory consistency, description drift; empty when clean)|\n|`graph_advance`|`runId`, `nodeId`, `condition?`, `jump?`, `end?`|Report a node complete — notify + ask next in one step. Dual channel (graph-flow): `condition` = the reported flow-defined condition value — the backend matches it against the node's outgoing flow-edge labels (transition table) and activates the matched target (no match → loud error, missed-condition guard); `jump` = forced rework — backward-only (target ⊆ topological ancestors ∪ `__handoff`, forward rejected loudly, retryCount++). `end: true` = direct-end (adapter-level completion — reported node done, run completes `completed` without resuming the graph). No `branchTo` (removed — ADR 0238). Runs complete via natural drain. Output and duration are not passed in — content lives in the agent session, duration is derived from timestamps|\n|`graph_jump`|`runId`, `targetPhaseId`|Jump to a specific phase — operator control (PCL back/jump/re-review); the only backward reset (graph-external, ADR 0238). Resets the target + downstream terminals to pending|\n|`graph_force_end`|`runId`|Force-terminate a run — run marked terminated. Completed/terminated runs are a no-op. **Irreversible**. Returns the unified envelope `{ snapshot, node: null }`|\n|`graph_status`|`runId`|Full run snapshot — the shared delta shape (`nodes` one-line rows + `changed` full-field rows)|\n|`graph_list`|—|All run summaries (runId, graphName, fsmState, createdAt, updatedAt), newest first|\n|`graph_assets`|—|All graph assets — the perception list: `{ id, description, run_conditions, source, problems }` per graph from the merged registries (project-first) plus schema-valid workflow YAMLs (`source: fallback`). `description`/`run_conditions` project from the loaded graph definition (catalog single source; registry entries are a pure `{name, path}` index). Read-only — never creates a run. The passive information channel for graph-workflow (graph selection, run-condition awareness, problem surfacing)|\n|`graph_init`|—|Initialize the database (create tables + run migration) plus a full machine health check (schema + contract/inventory pass per graph, per-graph problems, config health report). Idempotent|\n|`graph_clean_completed`|`before?: string`|Delete completed run records, optionally before an ISO 8601 date|\n|`graph_clean_all`|—|Delete ALL run records — running/blocked/terminated. **Dangerous**|\n\n### NextNode types\n\n`graph_start` / `graph_advance` return a NextNode:\n\n|type|Meaning|Agent behavior|\n|-|-|-|\n|`main`|Execution node|Execute the task inline — context assembled from `channels`, `## Agent hints:` injected when declared; completes with a confirmation card (Accept + free input + contextual options)|\n\nSubgraph composition is deleted (graph-subgraph-route-unify) — `graph_start` / `graph_advance` only ever return `main` nodes, and every dispatched node is a root-graph phase. Nested execution is the `template: router` sibling run: the router node's agent selects a candidate graph (single candidate / hard criterion → auto, else recommendation card), starts it via `graph_start` with the required args, drives it to completion, and reports the result — downstream reads via `node:<router>`. Rework/loop = `template: loop` sibling-run execution: the loop node repeats the looped subgraph (fresh `graph_start` per iteration) until the `until` conditions hold — no `branchTo`, no in-run backward reset (ADR 0238); the operator `graph_jump` is the only backward reset (PCL, graph-external).\n\n### Typical call flow\n\n```text\ngraph_start({ graphName: \"e2e-minimal\" })\n  → { runId, node: { nodeId: \"agent-echo\", type: \"main\", task: \"say hello in a random language.\", ... } }\n  → agent executes the task\n  → graph_advance({ runId, nodeId: \"agent-echo\" })\n  → { snapshot, node: { nodeId: \"approval-review\", type: \"main\", completion: { default: \"continue\", direct_end: \"end the round.\" }, ... } }\n  → ... loop until node is null (graph complete)\n```\n\n## Built-in Graphs\n\n12 graphs ship with the package (in `graphs/`, registered in `graphs/registry.json`). The project's `.graph-scheduler/graphs/` is searched first — a project graph with the same name overrides a built-in.\n\n|Graph|What it does|\n|-|-|\n|**e2e-minimal**|Minimal E2E: main → main confirmation loop|\n|**arch-review**|Requirement production graph, standalone: scope-entry interview (entry node — scope + output path + report input fresh\\|existing) → arch-review report (improve-codebase-architecture — producer) → report output. Independently executable requirement production; arch-review-loop launches it as a sibling run (router stage) and hosts the requirement accept loop on its requirement node.|\n|**adopt-with-docs**|Requirement adoption (adopt stage) + spec production: adopting (grilling conversation, inline domain-modeling side effects — the consensus IS the acceptance; the adoption goal is confirmed in the grilling first-round frontier, ADR 0247) → spec-propose (openspec-propose — adopted requirements materialize as the OpenSpec change). Standalone raw idea entry; launched by the loop's adopt router stage — receives the produced report via graph_start args (input document) and appends its record as a dated appendix section.|\n|**graph-generate**|Graph production — the maker journey: entry (atom-scope-interview) → spec (atom-graph-design per atom-graph-spec) → spec-accept → implement (atom-graph-writer: writes .yaml + registry entry, load-probe validated) → review → rework decision. Single kind (graph), single operation (create)|\n|**spec-implement**|Implementation graph: spec-extract (produced change — {args.changeName}, passed by the launching router) → track router (template: router — openspec-apply minimal / openspec-engineer detailed sibling run) → workflow-done. Pure implementation of an existing change — no spec generation; rework is the loop in arch-review-loop.|\n|**openspec-apply**|OpenSpec apply workflow: apply change → dual review → bounded rework decision → plain archive (openspec-archive-change)|\n|**openspec-engineer**|OpenSpec detailed implementation: spec synthesis → tickets → tdd implementation → dual review → rework decision → lifecycle closure (reverse-validated archive + ADR fold + index)|\n|**arch-review-loop**|Three-stage loop with router-launched stage graphs: requirement (router → arch-review sibling run: scope → report; the requirement accept loop is caller-declared on the router node — accept → adopt, revise → flow self-edge re-run, ADR 0246) → adopt (router → adopt-with-docs sibling run: confirms the report via grilling consensus, appends dated appendix, produces the OpenSpec change) → implementation (router → spec-implement sibling run: consumes the change → track machinery → archive) → round-report (round condition remaining \\| complete — flow self-edge re-entry or drain; termination at the direct-end options of scope-entry / adopt-scope / adopting)|\n|**estate-maintain**|Estate maintenance graph: entry (trigger classification — domain-change/skill-change/proactive + workstream selection) → domains-index (atom-doc-maintain per atom-domain-spec) / specs-sync (atom-spec-maintain) / adr-align (atom-adr-maintain) → review (consistency gate + reverse-validation + read-only deployment-mirror check).|\n|**release-prep**|Pre-release preparation — propose (release-prep-analyze: version from git tag history, deterministic + idempotent pre-tag, never executes git tag/commit/push) → plan-grill (grilling confirmation of every planned operation — interview, never auto-gated) → apply (release-prep-apply: version bump on release-line surfaces + CHANGELOG [Unreleased] fold per spec + README list sync vs ground truth, overwrite-style + verified) → release-review (main; continue completes the run — final report prints tag/commit commands, user executes manually; jump re-runs a phase).|\n|**graph-maintain**|Graph file maintenance — the maintenance flow: entry (atom-scope-interview — target graph via graph_assets + maintenance intent) → audit (atom-graph-writer maintain mode: inventory compliance + content-vs-inventory) → propose (per-finding fix proposals) → confirm (mandatory user gate) → execute (two-path bundle apply + load-probe) → review → rework decision. Mirrors the maker journey; pairs with the problem-surfacing channel (graph_start problems / graph_init full pass / graph_assets query).|\n|**first-principles-dev**|First-principles-prerequisite development flow — requirement (arch-review sibling run: scope + requirement/diff input → report; the requirement accept loop is caller-declared on the router node — accept → adopt, revise → flow self-edge re-run, ADR 0246) → adopt (adopt-with-docs: grilling consensus confirms, appends dated appendix, produces the OpenSpec change) → implement (spec-implement: change → track machinery → archive) → fp-doc-update (folds requirement/diff + reasoning conclusions into docs/first-principles/development-flow.md per the fp README update-maintenance contract; reports round condition remaining \\| complete — flow self-edge re-entry or drain)|\n\n**estate-maintain** — doc-estate maintenance as a graph: keeps the derived-view / normative / contract doc classes in sync after a domain or skill change. The root README features it; the skeleton at a glance:\n\n```mermaid\ngraph LR\n   ENTRY[Entry<br/>trigger classification] --> REQ{user-request?}\n   REQ -->|yes| GRILL[Grill requirements]\n   REQ -->|no| DOM[domains-index]\n   GRILL --> DOM\n   DOM --> SYN[specs-sync]\n   SYN --> ALN[adr-align]\n   ALN --> REV[Review]\n   REV -->|rework| ENTRY\n   REV -->|pass| DONE[Pass completes]\n```\n\nThe entry classifies the trigger (domain-change / skill-change / proactive / user-request — user-request adds a grilling confirmation step, no ADR), then runs the three workstreams in sequence — `domains-index` (atom-doc-maintain per atom-domain-spec), `specs-sync` (atom-spec-maintain), `adr-align` (atom-adr-maintain); the review is a consistency gate (requirements class + reverse-validation + read-only deployment-mirror check).\n\n## arch-review-loop — one loop, one problem\n\nThe flagship graph: each loop round takes the biggest remaining architectural problem from review to shipped change. The loop at a glance — implementation runs on two tracks (minimal apply / detailed engineer), approval decisions merged into one display:\n\n```mermaid\ngraph LR\n   SCOPE[scope-entry<br/>scope interview] --> REQ[Requirement<br/>router → arch-review]\n   REQ -->|revise| REQ\n   REQ --> GRILL[Adopting<br/>grilling consensus]\n   GRILL --> ADOPT[Adopt<br/>router → adopt-with-docs]\n   ADOPT --> IMPL[Implement<br/>router → spec-implement]\n   IMPL --> ROUND[round-report<br/>remaining OR complete]\n   ROUND -->|remaining| SCOPE\n   ROUND -->|complete| DONE[completed]\n```\n\nPhases (arch-review-loop — flat; stage graphs run as router-launched siblings):\n\n|Phase|Type|Role|\n|-|-|-|\n|`startup`|main (template: startup)|Full startup — constraints session load + serena activation + jcodemunch indexing|\n|`scope-entry`|main (input node)|Scope interview (`atom-scope-interview`) — **re-confirmed every round**, never auto-skipped: domain/feature/problem + focus dimensions, plus report input — `fresh` (write a new report to a confirmed output path) or `existing` (closed-loop re-review of a prior report; the path's Top Recommendation is read)|\n|`requirement`|main (template: router)|Launches the arch-review graph as a sibling run (single path — auto-select) — the producer (`improve-codebase-architecture`) runs inside the sibling: explore → first-principles → present-candidates; then presents the caller-declared accept question (`template_args.questions` — accept → adopting via the unlabeled sequence default; revise → flow self-edge re-run; accept-node consolidation)|\n|`adopting`|main|Adoption conversation (`grilling` skill) — challenges and confirms the produced requirements (adoption goal + trace intent confirmed in the first-round frontier), appends the adoption record as a dated appendix to the report, may offer an ADR; nothing to adopt (change_name empty) → direct end (accept-node consolidation)|\n|`adopt`|main (template: router)|Launches the adopt-with-docs graph as a sibling run — the adopted requirements materialize as the OpenSpec change (spec-propose); report path + adoption echo pass via graph_start args|\n|`implement`|main (template: router)|Launches the spec-implement graph as a sibling run — spec-extract reads `{args.changeName}`; track router picks openspec-apply minimal / openspec-engineer detailed|\n|`round-report`|main|Round condition — reports `remaining \\| complete` (flow-defined vocabulary): `remaining` re-enters scope-entry via the flow self-edge; `complete` drains to `__handoff`. Never a next-node choice|\n\nKey semantics:\n\n- **Round restart** loops back to `scope-entry` (an input node) via the flow self-edge `round-report -->|remaining| scope-entry`, so the whole input stage re-acquires (constraints re-loaded, scope re-confirmed) and the round (requirement → adopt → implement) re-runs.\n- **One loop**: spec-implement has no internal auto-iteration — the loop is single (round-report self-edge); a failed implementation is re-judged in the next round's re-review.\n- **Termination** = the user's decision at a direct-end option (scope-entry / adopting — `direct_end: true` → pilot advances with the end decision — run completes as `completed`, never `force_end`); the loop is human-bounded, not retryCount-capped (rework-law exception).\n\n## Making a Graph\n\nAtomic Workflow bootstraps itself — the maker journey for authoring graphs is a built-in graph:\n\n**Generate a graph** — `graph-generate` is the maker journey graph: a concrete 6-phase workflow (entry → spec → spec-accept → implement → review → rework decision; the name states the operation). Entry (atom-scope-interview) confirms the graph name, topology scope, and save location (default `.graph-scheduler/graphs/`) — no CONTEXT.md dependency. Spec designs the phase topology against atom-graph-spec; implement writes the `.yaml` + registry entry; review validates per code-review with atom-graph-spec; a rework decision applies bounded rework; a clean review closes the run (natural drain). Single kind (graph), single operation (create) — no skill co-production:\n\n```text\nUse atom-pilot to run graph-generate: generate a workflow for release notes from merged PRs.\n```\n\nThe maker journey at a glance:\n\n```mermaid\ngraph LR\n   ENTRY[Entry<br/>scope interview] --> SPEC[Spec<br/>atom-graph-design]\n   SPEC --> ACCEPT[spec-accept]\n   ACCEPT --> IMPL[Implement<br/>atom-graph-writer]\n   IMPL --> REVIEW[Review]\n   REVIEW -->|fail: rework| IMPL\n   REVIEW -->|pass| DONE[Accepted]\n```\n\n**Post-archive closure** — each track owns it: openspec-apply archives plain (openspec-archive-change); openspec-engineer closes through atom-doc-lifecycle (reverse-validated archive + ADR decision-fold + index rebuild). Full estate maintenance moves to the next-phase maintain graph.\n\nSkill production (create/edit) flows through `arch-review-loop` openspec changes (improver journey) — implementation loads the spec skill per affected domain (graph → atom-graph-spec, skill → atom-skill-spec, doc → atom-doc-maintain).\n\nAll of them are driven by `atom-pilot` from [graph-workflow](../graph-workflow/README.md).\n\n## Development\n\n```bash\ncd packages/graph-scheduler\n\nnpm install        # install dependencies\nnpm run build      # build (tsup)\nnpm test           # run tests (vitest)\nnpm run typecheck  # type check\nnpm start          # start the server\n```\n\nTests live in `tests/`, covering types, topology, state persistence, scheduler runtime, graph execution, graph definitions, and integration. Every zod schema in `src/schemas/` has unit tests (valid / invalid / boundary).\n\n## FAQ\n\n### graph_start returns a node but the agent doesn't respond?\n\nCheck the MCP connection. Confirm `command`/`args` in your `mcp.json` resolve, and that the scheduler process is alive (platform MCP health-check logs).\n\n### Does graph_start take a mode parameter?\n\nNo — `graph_start` accepts only `graphName` and `args?` (opaque run data); there is no mode parameter. Runs complete via natural drain: `graph_advance` returns `node: null` when no node is active and none is eligible.\n\n### How do I see run history?\n\n`graph_list` for run summaries, then `graph_status({ runId })` for phase-level detail.\n\n### How do I abort a stuck run?\n\n`graph_force_end({ runId })`. **Irreversible** — the run is marked `terminated` and cannot be recovered.\n\n### Where is the database?\n\nScaffolded `config.json` sets `.graph-scheduler/data/graph-scheduler.db` (relative to the working directory). Override with `GS_DB_PATH` (beats config.json); unset everywhere → in-memory. Tables: `graph_runs` (run metadata) and the checkpoint store (`checkpoints` + `checkpoint_writes` — per-node status, retry count, timestamps; duration is computed from timestamps, not stored). Output is **not** persisted — it lives in the agent session or on disk.\n","readmeFilename":"README.md"}