Skip to content

Commit 099608a

Browse files
VikingLichensamwebexpertcursoragent
authored
docs: agentic orchestrator (#115)
* docs(orchestrator): add README for plan-driven workflow Document how to run the orchestrator, plan.json issue shape, iteration workflow (plan, implement, review, merge), agents, worktrees, and layout. Co-authored-by: Cursor <cursoragent@cursor.com> * chore(skills): rename to-issues-as-json to to-issues-as-json2 Move skill to to-issues-as-json2 and use SKILL.md filename convention. Co-authored-by: Cursor <cursoragent@cursor.com> * chore(skills): rename to-issues-as-json2 back to to-issues-as-json Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: André Masson <amwebexpert@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent cda7ea0 commit 099608a

2 files changed

Lines changed: 126 additions & 0 deletions

File tree

ai-orchestrator/README.md

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# AI Orchestrator
2+
3+
The AI orchestrator drives a multi-issue implementation plan from [plan.json](plan.json): it plans dependencies, implements AFK (away-from-keyboard) issues in isolated git worktrees, reviews changes, merges successful branches into the main repo, and cleans up implementation branches when all AFK work is done.
4+
5+
Skills to run in order to produce the `plan.json`
6+
7+
- grill-with-docs
8+
- to-prd
9+
- to-issues-as-json
10+
11+
## Running
12+
13+
Entry point: [main.ts](main.ts) — resolves the repository root (`..`), `plan.json`, and `logs/`.
14+
15+
```bash
16+
npm run ai:run:plan
17+
```
18+
19+
This runs `npx tsx ai-orchestrator/main.ts`.
20+
21+
## Plan file (`plan.json`)
22+
23+
Each issue in `plan.json` follows the [Issue](utils/orchestrator.types.ts) shape:
24+
25+
| Field | Role |
26+
| -------------------------------------------------- | ---------------------------------------------------------------------------- |
27+
| `id`, `title`, `whatToBuild`, `acceptanceCriteria` | Fed to the implement agent |
28+
| `type` | `AFK` (automated) or `HITL` (human-in-the-loop; skipped by the orchestrator) |
29+
| `isPlanned`, `blockedBy` | Set by the planning phase |
30+
| `passes` | Set to `true` after a successful merge |
31+
32+
An issue is **unblocked** when it is `isPlanned`, not yet `passes`, has `type === "AFK"`, and every id in `blockedBy` has `passes: true` (see [plan.ts](utils/plan.ts) `getUnblocked()`).
33+
34+
The plan file is reloaded at the start of each iteration and saved after planning and merge phases.
35+
36+
## Workflow
37+
38+
`Orchestrator.run()` in [orchestrator.ts](orchestrator.ts) runs up to `maxIterations` (default **20**). Each iteration:
39+
40+
1. **Reload plan**`plan.load()` re-reads `plan.json` from disk.
41+
2. **Planning** — If any issue has `isPlanned: false`, the **planner** agent runs (`prompts/plan.md`) with the full plan JSON. It returns `{ id, blockedBy }[]`; the orchestrator calls `markPlanned` and saves the plan.
42+
3. **Select work**`getUnblocked()`. If there are no unblocked issues, the loop exits (logs distinguish: all AFK complete vs. blocked/circular dependency vs. remaining HITL).
43+
4. **Implementation** — Unblocked issues run in parallel via `Promise.allSettled`:
44+
- Branch name: `orchestrator/implementation-task-{issueId}`
45+
- [withWorktree](utils/worktree.utils.ts) creates a worktree under `.orchestrator-worktrees/`, symlinks `node_modules`, runs the callback, then removes the worktree in `finally`
46+
- **Implement** agent (`implement.md`, cwd = worktree)
47+
- If the branch has commits not on `HEAD` (`hasCommits`), run the **Review** agent (`review.md`); otherwise skip review
48+
- Collect issues that produced commits; failures are logged and the iteration continues
49+
5. **Merge** — If any issue produced commits this iteration, the **merger** agent (`merge.md`) runs in the main repo. Structured output `{ merged, failed }`; merged issue ids get `markPassed` and the plan is saved.
50+
6. If no issue produced commits, skip merge and start the next iteration.
51+
52+
After the loop, if there are **no remaining AFK issues** (`remainingAfkIssues.length === 0`), **cleanup** deletes `orchestrator/implementation-task-*` branches for passed AFK issues.
53+
54+
## Agents
55+
56+
| Phase | Prompt | Model | Working directory |
57+
| --------- | ------------------------------------ | ----------------- | ----------------- |
58+
| Plan | [plan.md](prompts/plan.md) | claude-opus-4-7 | repo root |
59+
| Implement | [implement.md](prompts/implement.md) | claude-opus-4-7 | worktree |
60+
| Review | [review.md](prompts/review.md) | claude-sonnet-4-6 | worktree |
61+
| Merge | [merge.md](prompts/merge.md) | claude-sonnet-4-6 | repo root |
62+
63+
Agent execution uses the Claude Agent SDK in [agent.utils.ts](utils/agent.utils.ts). Per-agent logs are written under `logs/` via [agent-logger.utils.ts](utils/agent-logger.utils.ts).
64+
65+
## Worktrees and branches
66+
67+
- Implementation branches: `orchestrator/implementation-task-{issueId}`
68+
- Worktrees live under `.orchestrator-worktrees/` (branch slashes become `--` in the directory name)
69+
- The worktree is removed after each issue’s implement/review callback; the branch may remain until global cleanup
70+
- Cleanup runs only when all AFK issues have `passes: true`
71+
72+
## Project layout
73+
74+
```
75+
ai-orchestrator/
76+
main.ts # CLI entry
77+
orchestrator.ts # Orchestrator class
78+
plan.json # Issue backlog (mutable at runtime)
79+
prompts/ # Agent prompt templates
80+
utils/ # plan, worktree, agent helpers
81+
logs/ # Per-agent run logs (created at runtime)
82+
```
83+
84+
## Workflow diagram
85+
86+
Main iteration loop:
87+
88+
```mermaid
89+
flowchart TD
90+
start([run]) --> iter{iteration le maxIterations}
91+
iter --> load[load plan.json]
92+
load --> planPhase{unplanned issues?}
93+
planPhase -->|yes| planner[Planner agent: set blockedBy]
94+
planPhase -->|no| unblocked
95+
planner --> savePlan1[save plan]
96+
savePlan1 --> unblocked{unblocked AFK issues?}
97+
unblocked -->|no| exitLoop[break loop]
98+
unblocked -->|yes| implParallel[Parallel: worktree per issue]
99+
implParallel --> implement[Implement agent]
100+
implement --> hasCommits{commits on branch?}
101+
hasCommits -->|yes| review[Review agent]
102+
hasCommits -->|no| skipReview[skip review]
103+
review --> collect[collect issues with commits]
104+
skipReview --> collect
105+
collect --> anyDone{any completed?}
106+
anyDone -->|no| iter
107+
anyDone -->|yes| merger[Merger agent]
108+
merger --> markPassed[markPassed + save plan]
109+
markPassed --> iter
110+
exitLoop --> cleanup{all AFK done?}
111+
cleanup -->|yes| deleteBranches[delete implementation branches]
112+
cleanup -->|no| done([All done])
113+
deleteBranches --> done
114+
```
115+
116+
Per-issue worktree lifecycle:
117+
118+
```mermaid
119+
flowchart LR
120+
create[create worktree + symlink node_modules] --> implement[Implement agent]
121+
implement --> check{hasCommits?}
122+
check -->|yes| review[Review agent]
123+
check -->|no| remove[remove worktree]
124+
review --> remove
125+
remove --> branchRemains[branch kept until cleanup]
126+
```

0 commit comments

Comments
 (0)