forge-cc 2.0.0 → 2.0.1
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.
- package/README.md +201 -133
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
</p>
|
|
7
7
|
|
|
8
8
|
<p align="center">
|
|
9
|
-
<strong>Idea to merged PR.
|
|
9
|
+
<strong>Idea to merged PR. Graph-driven execution. Adversarial review. Zero manual git.</strong>
|
|
10
10
|
</p>
|
|
11
11
|
|
|
12
12
|
<p align="center">
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
|
|
21
21
|
## What is forge-cc?
|
|
22
22
|
|
|
23
|
-
forge-cc is a Claude Code plugin that turns your AI coding agent into an autonomous development
|
|
23
|
+
forge-cc is a Claude Code plugin that turns your AI coding agent into an autonomous development pipeline. You describe what you want. Forge decomposes it into a dependency graph of requirements, executes each one in an isolated worktree with adversarial review, runs self-healing verification, syncs state to Linear, and creates the PR -- all without you touching git.
|
|
24
24
|
|
|
25
25
|
```
|
|
26
26
|
npm install -g forge-cc
|
|
@@ -30,7 +30,7 @@ npm install -g forge-cc
|
|
|
30
30
|
|
|
31
31
|
## The Workflow
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
Seven skill commands cover the full lifecycle from raw idea to production-ready code.
|
|
34
34
|
|
|
35
35
|
```
|
|
36
36
|
+-----------------------------------------------------------------------------------+
|
|
@@ -39,73 +39,143 @@ Five skill commands take you from raw idea to production-ready, merged code.
|
|
|
39
39
|
| |
|
|
40
40
|
| "We need auth, +-----------+ +-----------+ +-----------+ |
|
|
41
41
|
| a dashboard, | | | | | | |
|
|
42
|
-
| and email |
|
|
42
|
+
| and email | CAPTURE +---> PLAN +---> BUILD | |
|
|
43
43
|
| notifications" | | | | | | |
|
|
44
44
|
| +-----+-----+ +-----+-----+ +-----+-----+ |
|
|
45
45
|
| | | | |
|
|
46
|
-
| Creates Linear Scans codebase
|
|
47
|
-
| projects from + interviews
|
|
48
|
-
| brain dump you + generates
|
|
49
|
-
|
|
|
50
|
-
|
|
|
51
|
-
|
|
|
52
|
-
|
|
|
53
|
-
|
|
|
54
|
-
|
|
|
46
|
+
| Creates Linear Scans codebase Executes graph |
|
|
47
|
+
| projects from + interviews with adversarial |
|
|
48
|
+
| brain dump you + generates review per |
|
|
49
|
+
| requirement requirement |
|
|
50
|
+
| graph | |
|
|
51
|
+
| v |
|
|
52
|
+
| +----------------+ |
|
|
53
|
+
| | VERIFY + PR | |
|
|
54
|
+
| +----------------+ |
|
|
55
55
|
| |
|
|
56
56
|
+-----------------------------------------------------------------------------------+
|
|
57
57
|
```
|
|
58
58
|
|
|
59
|
-
### `/forge:
|
|
59
|
+
### `/forge:capture` -- Brain Dump to Backlog
|
|
60
60
|
|
|
61
|
-
Paste sticky notes, Slack messages, or stream-of-consciousness feature ideas. Forge extracts distinct projects, deduplicates against your existing Linear backlog, and creates them after your confirmation.
|
|
61
|
+
Paste sticky notes, Slack messages, or stream-of-consciousness feature ideas. Forge extracts distinct projects, deduplicates against your existing Linear backlog, and creates them after your confirmation. Projects are created at "Planned" state.
|
|
62
62
|
|
|
63
|
-
### `/forge:
|
|
63
|
+
### `/forge:plan` -- Interview to Requirement Graph
|
|
64
64
|
|
|
65
|
-
Pick a project
|
|
65
|
+
Pick a project. Forge scans your codebase in parallel (structure, routes, dependencies, patterns), then conducts an adaptive interview -- leading with recommendations based on what it found, not blank-slate questions. The output is a requirement graph at `.planning/graph/{slug}/` with:
|
|
66
66
|
|
|
67
|
-
|
|
67
|
+
- **`_index.yaml`** -- Project metadata, requirement registry (id, status, group, dependencies, priority), group definitions
|
|
68
|
+
- **`overview.md`** -- Project overview and architectural decisions
|
|
69
|
+
- **`requirements/req-NNN.md`** -- Individual requirements with YAML frontmatter (files, acceptance criteria, dependencies)
|
|
68
70
|
|
|
69
|
-
|
|
71
|
+
Requirements are sized with hard limits (max 6 acceptance criteria, max 5 files touched) and validated with `detectCycles()` and `computeWaves()` before committing.
|
|
72
|
+
|
|
73
|
+
### `/forge:build` -- Execute Graph with Adversarial Review
|
|
74
|
+
|
|
75
|
+
This is the engine. Each requirement is executed sequentially in dependency order:
|
|
70
76
|
|
|
71
77
|
```
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
78
|
+
Load graph
|
|
79
|
+
|
|
|
80
|
+
v
|
|
81
|
+
findReady() ─── picks next requirement (pending + all deps complete)
|
|
82
|
+
|
|
|
83
|
+
v
|
|
84
|
+
┌─────────────────────────────────────────────────────┐
|
|
85
|
+
│ Per requirement (isolated worktree): │
|
|
86
|
+
│ │
|
|
87
|
+
│ Create worktree ──> Build ──> Verify ──> Review │
|
|
88
|
+
│ │ │ │ │
|
|
89
|
+
│ │ Self-healing │ │
|
|
90
|
+
│ │ loop (max 3) Pass? │
|
|
91
|
+
│ │ │ │
|
|
92
|
+
│ │ Yes: merge │
|
|
93
|
+
│ │ No: retry │
|
|
94
|
+
│ │ │
|
|
95
|
+
│ Cleanup worktree │
|
|
96
|
+
└─────────────────────────────────────────────────────┘
|
|
97
|
+
|
|
|
98
|
+
v
|
|
99
|
+
Next ready requirement... until graph complete
|
|
87
100
|
```
|
|
88
101
|
|
|
89
|
-
**
|
|
102
|
+
**How it works:**
|
|
103
|
+
|
|
104
|
+
1. `findReady()` selects the next requirement -- pending status, all dependencies complete, sorted by priority then group order then insertion order
|
|
105
|
+
2. A fresh git worktree is created at `../.forge-wt/<repo>/<slug>-<reqId>/`
|
|
106
|
+
3. Claude builds the requirement with attention-aware prompting (overview → dependency context → target requirement loaded last)
|
|
107
|
+
4. Verification gates run (types, lint, tests) with self-healing -- errors are fed back as structured context
|
|
108
|
+
5. An adversarial reviewer checks the actual files on disk (not diffs) against acceptance criteria
|
|
109
|
+
6. On pass: merge worktree back to feature branch, mark requirement complete, sync to Linear
|
|
110
|
+
7. On fail: retry up to 3 iterations before stopping
|
|
111
|
+
|
|
112
|
+
### `/forge:fix` -- Surgical Recovery
|
|
113
|
+
|
|
114
|
+
When a requirement fails during build, `/forge:fix` provides targeted recovery. Select the failed requirement, diagnose the issue, and fix it in isolation with up to 3 repair iterations. Minimal changes only -- no scope creep.
|
|
115
|
+
|
|
116
|
+
### `/forge:quick` -- Ad-Hoc Tasks
|
|
117
|
+
|
|
118
|
+
For tasks that don't need a requirement graph. Creates a branch (`feat/quick-*` or `fix/quick-*`), builds directly, runs verification, and creates the PR. No planning ceremony, no adversarial review.
|
|
119
|
+
|
|
120
|
+
### `/forge:setup` and `/forge:update`
|
|
121
|
+
|
|
122
|
+
`/forge:setup` initializes a project: auto-detects your stack, creates `.forge.json`, installs skills and hooks, scaffolds planning directories, and runs diagnostics. `/forge:update` checks for newer forge-cc versions and upgrades.
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## The Graph Engine
|
|
127
|
+
|
|
128
|
+
Forge's core is a requirement graph engine that models your project as a directed acyclic graph (DAG) of requirements.
|
|
129
|
+
|
|
130
|
+
### Requirement Lifecycle
|
|
90
131
|
|
|
91
132
|
```
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
133
|
+
pending ──> in_progress ──> complete
|
|
134
|
+
|
|
|
135
|
+
+──> (retry on verify/review failure, up to maxIterations)
|
|
136
|
+
|
|
137
|
+
discovered ──> pending (human-gated: new requirements found during build)
|
|
138
|
+
discovered ──> rejected (user declines the discovered requirement)
|
|
98
139
|
```
|
|
99
140
|
|
|
100
|
-
|
|
141
|
+
### Key Functions
|
|
101
142
|
|
|
102
|
-
|
|
143
|
+
| Function | What it does |
|
|
144
|
+
|----------|-------------|
|
|
145
|
+
| `findReady()` | Returns requirements where status is `pending`, all `dependsOn` are `complete`, and group dependencies are satisfied. Sorted by priority → group order → insertion order. |
|
|
146
|
+
| `computeWaves()` | Groups ready requirements into parallel-safe waves with no file conflicts. Used during planning to preview execution order. |
|
|
147
|
+
| `getTransitiveDeps()` | DFS traversal returning all transitive dependencies. Throws on cycle detection. |
|
|
148
|
+
| `isProjectComplete()` | True when every non-rejected requirement has status `complete`. |
|
|
149
|
+
| `buildRequirementContext()` | Assembles dependency context for a requirement -- transitive deps in topological order with their status and file artifacts. |
|
|
103
150
|
|
|
104
|
-
|
|
151
|
+
### Graph Files
|
|
105
152
|
|
|
106
|
-
|
|
153
|
+
```
|
|
154
|
+
.planning/graph/{slug}/
|
|
155
|
+
_index.yaml # Project metadata + requirement registry
|
|
156
|
+
overview.md # Architecture decisions, scope, constraints
|
|
157
|
+
requirements/
|
|
158
|
+
req-001.md # Requirement with YAML frontmatter
|
|
159
|
+
req-002.md # (id, title, files, acceptance, dependsOn)
|
|
160
|
+
...
|
|
161
|
+
```
|
|
107
162
|
|
|
108
|
-
|
|
163
|
+
The index tracks each requirement's `status`, `group`, `dependsOn`, `priority`, and optional `linearIssueId`. Groups define execution phases with their own dependency ordering.
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Adversarial Review
|
|
168
|
+
|
|
169
|
+
Every requirement built by `/forge:build` goes through adversarial review before merge. The reviewer is a separate Claude session that reads the actual files on disk -- not diffs, not summaries.
|
|
170
|
+
|
|
171
|
+
**What the reviewer checks:**
|
|
172
|
+
|
|
173
|
+
- **Stub detection** -- Empty function bodies, TODO comments, hardcoded return values, placeholder implementations
|
|
174
|
+
- **Acceptance criteria** -- Every criterion in the requirement must be demonstrably met
|
|
175
|
+
- **File scope** -- Created files exist, modified files are relevant, no out-of-scope changes
|
|
176
|
+
- **Technical approach** -- Architecture matches the overview, no security vulnerabilities
|
|
177
|
+
|
|
178
|
+
**Output format:** Each finding is tagged `[PASS]`, `[FAIL]`, or `[WARN]` with `file:line` references. No partial credit -- a single `[FAIL]` finding fails the entire review.
|
|
109
179
|
|
|
110
180
|
---
|
|
111
181
|
|
|
@@ -129,45 +199,51 @@ Forge runs **3 verification gates** that catch issues before code ships:
|
|
|
129
199
|
|
|
130
200
|
Gates run sequentially with configurable per-gate timeouts (default 2 minutes each). Results are cached to `.forge/last-verify.json`.
|
|
131
201
|
|
|
132
|
-
**Self-healing
|
|
202
|
+
**Self-healing:** When a gate fails during `forge run` or `/forge:build`, the errors are fed back to Claude as structured context -- file path, line number, error message. Claude fixes the issues and re-runs verification. This loops up to `maxIterations` (default 5) before stopping. Most failures resolve automatically.
|
|
133
203
|
|
|
134
204
|
---
|
|
135
205
|
|
|
136
206
|
## Linear Integration
|
|
137
207
|
|
|
138
|
-
Forge manages your Linear project lifecycle end-to-end.
|
|
208
|
+
Forge manages your Linear project lifecycle end-to-end. State transitions happen automatically as work progresses through the graph:
|
|
139
209
|
|
|
140
210
|
```
|
|
141
|
-
Linear State: Backlog --> Planned --> In Progress -->
|
|
142
|
-
| | |
|
|
143
|
-
Forge Action:
|
|
144
|
-
|
|
145
|
-
|
|
211
|
+
Linear State: Backlog --> Planned --> In Progress --> Done
|
|
212
|
+
| | | |
|
|
213
|
+
Forge Action: /forge: /forge:plan /forge:build all requirements
|
|
214
|
+
capture syncs issues starts each complete,
|
|
215
|
+
creates to Linear requirement project synced
|
|
216
|
+
projects to Done
|
|
146
217
|
```
|
|
147
218
|
|
|
148
|
-
|
|
219
|
+
- `syncRequirementStart()` -- Moves the issue to "In Progress" and the project to "In Progress" (best-effort, never crashes on API errors)
|
|
220
|
+
- `syncGraphProjectDone()` -- Moves all issues to "Done" and the project to "Done"
|
|
149
221
|
|
|
150
|
-
|
|
222
|
+
State names are configurable via `linearStates` in `.forge.json`. The Linear client uses category-based status resolution with name-based fallback -- it works with custom workflow states out of the box.
|
|
223
|
+
|
|
224
|
+
Set `LINEAR_API_KEY` in your environment to enable.
|
|
151
225
|
|
|
152
226
|
---
|
|
153
227
|
|
|
154
|
-
##
|
|
228
|
+
## Worktree Isolation
|
|
155
229
|
|
|
156
|
-
|
|
230
|
+
Every requirement executes in its own git worktree. You never touch git.
|
|
157
231
|
|
|
158
232
|
```
|
|
159
|
-
main
|
|
160
|
-
|
|
|
161
|
-
|
|
162
|
-
|
|
|
163
|
-
|
|
233
|
+
main ──────────────────────────────────────────────> main (updated)
|
|
234
|
+
| ^
|
|
235
|
+
+──> feat/my-project ──> worktree req-001 ──> merge ──>─+
|
|
236
|
+
| |
|
|
237
|
+
+──> worktree req-002 ──>──+
|
|
238
|
+
| (sequential)
|
|
239
|
+
+──> worktree req-003 ──>──+
|
|
164
240
|
```
|
|
165
241
|
|
|
166
|
-
**
|
|
242
|
+
**Isolation** -- Each requirement gets its own worktree at `../.forge-wt/<repo>/<slug>-<reqId>/`. The build agent operates in a clean copy of the repository, preventing cross-requirement interference.
|
|
167
243
|
|
|
168
|
-
**Minimal footprint** -- Worktree management is 3 functions (
|
|
244
|
+
**Minimal footprint** -- Worktree management is 3 functions: `createWorktree` (git worktree add -b), `mergeWorktree` (checkout + merge --ff-only), `removeWorktree` (git worktree remove --force). No session registry, no parallel scheduler.
|
|
169
245
|
|
|
170
|
-
**Automatic cleanup** -- When a
|
|
246
|
+
**Automatic cleanup** -- When a requirement finishes (pass or fail), its worktree is removed. Protected branches (`main`, `master`) are never committed to directly.
|
|
171
247
|
|
|
172
248
|
---
|
|
173
249
|
|
|
@@ -184,7 +260,7 @@ npx forge setup
|
|
|
184
260
|
export LINEAR_API_KEY="lin_api_..."
|
|
185
261
|
|
|
186
262
|
# 4. Start building
|
|
187
|
-
# /forge:
|
|
263
|
+
# /forge:capture -> /forge:plan -> /forge:build
|
|
188
264
|
```
|
|
189
265
|
|
|
190
266
|
`forge setup` auto-detects your stack (TypeScript, Biome, test runner), creates `.forge.json`, installs enforcement hooks, syncs skill files to `~/.claude/commands/forge/`, and updates your `CLAUDE.md`. Run `npx forge doctor` anytime to check your environment.
|
|
@@ -208,11 +284,11 @@ export LINEAR_API_KEY="lin_api_..."
|
|
|
208
284
|
|--------|------|---------|-------------|
|
|
209
285
|
| `gates` | `string[]` | `["types", "lint", "tests"]` | Which verification gates to run |
|
|
210
286
|
| `gateTimeouts` | `Record<string, number>` | `{}` | Per-gate timeout in ms (default 120000 per gate) |
|
|
211
|
-
| `maxIterations` | `number` | `5` | Max
|
|
287
|
+
| `maxIterations` | `number` | `5` | Max retry iterations per requirement |
|
|
212
288
|
| `linearTeam` | `string` | `""` | Linear team key or name for lifecycle sync |
|
|
213
289
|
| `linearStates` | `object` | see below | Custom Linear state names |
|
|
214
290
|
| `verifyFreshness` | `number` | `600000` | Verify cache validity in ms (default 10 min) |
|
|
215
|
-
| `forgeVersion` | `string` | `"
|
|
291
|
+
| `forgeVersion` | `string` | `"2.0.0"` | Version stamp from setup (used by version-check hook) |
|
|
216
292
|
|
|
217
293
|
**`linearStates` defaults:**
|
|
218
294
|
|
|
@@ -239,11 +315,11 @@ npx forge verify # Run all configured gates
|
|
|
239
315
|
npx forge verify --gate types,lint # Run specific gates
|
|
240
316
|
npx forge verify --json # Output results as JSON
|
|
241
317
|
|
|
242
|
-
#
|
|
243
|
-
npx forge run --prd <slug> #
|
|
318
|
+
# Graph execution
|
|
319
|
+
npx forge run --prd <slug> # Execute all requirements for a graph
|
|
244
320
|
|
|
245
321
|
# Status
|
|
246
|
-
npx forge status # Show
|
|
322
|
+
npx forge status # Show project progress across all graphs
|
|
247
323
|
|
|
248
324
|
# Setup & maintenance
|
|
249
325
|
npx forge setup # Initialize forge for a project
|
|
@@ -251,11 +327,18 @@ npx forge setup --skills-only # Only sync skill files
|
|
|
251
327
|
npx forge doctor # Environment health check
|
|
252
328
|
npx forge update # Check for and install updates
|
|
253
329
|
|
|
254
|
-
# Linear commands
|
|
255
|
-
npx forge linear
|
|
256
|
-
npx forge linear
|
|
257
|
-
npx forge linear
|
|
258
|
-
npx forge linear
|
|
330
|
+
# Linear commands
|
|
331
|
+
npx forge linear create-project --name <name> --team <teamId>
|
|
332
|
+
npx forge linear create-milestone --project <id> --name <name>
|
|
333
|
+
npx forge linear create-issue --team <teamId> --title <title> [--project <id>] [--milestone <id>]
|
|
334
|
+
npx forge linear create-issue-batch --team <teamId> --project <id> --milestone <id> --issues '<json>'
|
|
335
|
+
npx forge linear create-project-relation --project <id> --related-project <id> --type <blocks|related>
|
|
336
|
+
npx forge linear create-issue-relation --issue <id> --related-issue <id> --type <blocks|duplicate|related>
|
|
337
|
+
npx forge linear list-teams
|
|
338
|
+
npx forge linear list-projects --team <teamId>
|
|
339
|
+
|
|
340
|
+
# GitHub Codex
|
|
341
|
+
npx forge codex-poll --owner <owner> --repo <repo> --pr <number>
|
|
259
342
|
```
|
|
260
343
|
|
|
261
344
|
### Skill Commands
|
|
@@ -264,10 +347,12 @@ Skills are Claude Code slash commands installed to `~/.claude/commands/forge/`:
|
|
|
264
347
|
|
|
265
348
|
| Skill | Description |
|
|
266
349
|
|-------|-------------|
|
|
267
|
-
| `/forge:
|
|
268
|
-
| `/forge:
|
|
269
|
-
| `/forge:
|
|
270
|
-
| `/forge:
|
|
350
|
+
| `/forge:capture` | Brain dump to Linear projects -- extracts, deduplicates, creates |
|
|
351
|
+
| `/forge:plan` | Codebase scan + adaptive interview → requirement graph with dependency DAG |
|
|
352
|
+
| `/forge:build` | Execute requirement graph -- worktree isolation, adversarial review, self-healing verify |
|
|
353
|
+
| `/forge:fix` | Surgical recovery for failed requirements -- diagnose, repair, re-verify |
|
|
354
|
+
| `/forge:quick` | Ad-hoc tasks without planning ceremony -- branch, build, verify, PR |
|
|
355
|
+
| `/forge:setup` | Initialize project scaffolding -- config, hooks, skills, CLAUDE.md |
|
|
271
356
|
| `/forge:update` | Check for updates and upgrade forge-cc |
|
|
272
357
|
|
|
273
358
|
### Enforcement Hooks
|
|
@@ -277,42 +362,19 @@ Forge installs two Claude Code hooks during setup:
|
|
|
277
362
|
- **Pre-commit hook** (`pre-commit-verify.js`) -- Blocks commits that haven't passed verification. Checks branch protection (no direct commits to main/master), verify cache freshness, and `result === 'PASSED'` in `.forge/last-verify.json`.
|
|
278
363
|
- **Version check hook** (`version-check.js`) -- Non-blocking notice when a newer forge-cc version is available or when project setup is stale.
|
|
279
364
|
|
|
280
|
-
### MCP Server
|
|
281
|
-
|
|
282
|
-
Expose the verification pipeline as an MCP tool for programmatic access:
|
|
283
|
-
|
|
284
|
-
```json
|
|
285
|
-
{
|
|
286
|
-
"mcpServers": {
|
|
287
|
-
"forge-cc": {
|
|
288
|
-
"command": "node",
|
|
289
|
-
"args": ["node_modules/forge-cc/dist/server.js"]
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
```
|
|
294
|
-
|
|
295
|
-
**Tool:** `forge_run_pipeline`
|
|
296
|
-
|
|
297
|
-
| Input | Type | Description |
|
|
298
|
-
|-------|------|-------------|
|
|
299
|
-
| `projectDir` | `string?` | Project directory (defaults to cwd) |
|
|
300
|
-
| `gates` | `string[]?` | Filter to specific gates |
|
|
301
|
-
|
|
302
|
-
Returns the full pipeline result as JSON (result status, per-gate pass/fail, errors with file/line/message).
|
|
303
|
-
|
|
304
365
|
---
|
|
305
366
|
|
|
306
367
|
## How It's Different
|
|
307
368
|
|
|
308
369
|
| Without forge | With forge |
|
|
309
370
|
|--------------|-----------|
|
|
310
|
-
| Agent writes code, you review everything |
|
|
311
|
-
| Manual git branching, PRs, merges | Automatic worktrees, branches, and PRs |
|
|
312
|
-
| "Tests pass" = done | 3 gates
|
|
313
|
-
| One agent, one task, serial |
|
|
314
|
-
| Context rot across long sessions | Fresh session per
|
|
371
|
+
| Agent writes code, you review everything | Graph-driven execution with adversarial review catches issues before you see them |
|
|
372
|
+
| Manual git branching, PRs, merges | Automatic worktrees per requirement, branches, and PRs |
|
|
373
|
+
| "Tests pass" = done | 3 gates (types + lint + tests) with self-healing retry loop |
|
|
374
|
+
| One agent, one task, serial | Dependency-aware execution with topological ordering |
|
|
375
|
+
| Context rot across long sessions | Fresh session per requirement, file system is the only memory |
|
|
315
376
|
| Linear updated manually | Automatic state transitions through your pipeline |
|
|
377
|
+
| Failed builds need manual triage | `/forge:fix` provides surgical recovery with targeted diagnosis |
|
|
316
378
|
|
|
317
379
|
---
|
|
318
380
|
|
|
@@ -323,7 +385,7 @@ Returns the full pipeline result as JSON (result status, per-gate pass/fail, err
|
|
|
323
385
|
|
|
324
386
|
### `forge run` fails when invoked from within Claude Code
|
|
325
387
|
|
|
326
|
-
Forge strips the `CLAUDECODE` environment variable before spawning `claude` subprocesses. Claude Code uses this variable to detect nested sessions and blocks them. If `forge run` hangs or exits immediately, ensure you're running it from a terminal, not from inside an active Claude Code session. When invoked via the `/forge:
|
|
388
|
+
Forge strips the `CLAUDECODE` environment variable before spawning `claude` subprocesses. Claude Code uses this variable to detect nested sessions and blocks them. If `forge run` hangs or exits immediately, ensure you're running it from a terminal, not from inside an active Claude Code session. When invoked via the `/forge:build` skill, this is handled automatically.
|
|
327
389
|
|
|
328
390
|
### Pre-commit hook blocks commits
|
|
329
391
|
|
|
@@ -331,9 +393,9 @@ The pre-commit hook requires a passing verification cached in `.forge/last-verif
|
|
|
331
393
|
|
|
332
394
|
### Linear sync runs but does nothing
|
|
333
395
|
|
|
334
|
-
|
|
396
|
+
Check:
|
|
335
397
|
1. `LINEAR_API_KEY` is set in your environment
|
|
336
|
-
2. Your
|
|
398
|
+
2. Your graph's `_index.yaml` has `linear.projectId` and `linear.teamId` populated (set during `/forge:plan`)
|
|
337
399
|
3. Run `npx forge doctor` to validate the API key and team configuration
|
|
338
400
|
|
|
339
401
|
### `forge run` on Windows
|
|
@@ -357,7 +419,7 @@ Run `npx forge doctor` to see which checks fail. Required: Node.js >= 18 and git
|
|
|
357
419
|
forge-cc/
|
|
358
420
|
src/
|
|
359
421
|
cli.ts # CLI entry (npx forge)
|
|
360
|
-
|
|
422
|
+
codex-poll.ts # GitHub Codex PR review polling
|
|
361
423
|
types.ts # Core types
|
|
362
424
|
doctor.ts # Environment health checks
|
|
363
425
|
setup.ts # Project scaffolding
|
|
@@ -369,36 +431,52 @@ forge-cc/
|
|
|
369
431
|
types-gate.ts # TypeScript gate (tsc --noEmit)
|
|
370
432
|
lint-gate.ts # Lint gate (biome check)
|
|
371
433
|
tests-gate.ts # Tests gate (vitest/jest)
|
|
434
|
+
graph/
|
|
435
|
+
types.ts # Graph types (GraphIndex, Requirement, RequirementMeta)
|
|
436
|
+
schemas.ts # Zod schemas for graph YAML
|
|
437
|
+
reader.ts # Load index, requirements, overview from disk
|
|
438
|
+
writer.ts # Atomic writes for index, requirements, overview
|
|
439
|
+
query.ts # findReady, computeWaves, getTransitiveDeps, isProjectComplete
|
|
440
|
+
validator.ts # Structural validation (cycles, dangling deps, file conflicts)
|
|
441
|
+
index.ts # Public re-exports
|
|
372
442
|
linear/
|
|
373
|
-
client.ts # @linear/sdk wrapper (team-scoped)
|
|
374
|
-
sync.ts # Linear state transitions
|
|
443
|
+
client.ts # @linear/sdk wrapper (team-scoped, category+name fallback)
|
|
444
|
+
sync.ts # Linear state transitions (syncRequirementStart, syncGraphProjectDone)
|
|
375
445
|
runner/
|
|
376
|
-
loop.ts #
|
|
377
|
-
prompt.ts # Prompt builder
|
|
446
|
+
loop.ts # Graph loop executor (sequential requirement execution)
|
|
447
|
+
prompt.ts # Prompt builder (attention-aware requirement context)
|
|
378
448
|
update.ts # Version check
|
|
379
449
|
state/
|
|
380
|
-
status.ts # PRD status CRUD
|
|
381
450
|
cache.ts # Verify cache writer
|
|
382
451
|
worktree/
|
|
383
452
|
manager.ts # createWorktree, mergeWorktree, removeWorktree
|
|
384
453
|
skills/ # Claude Code skill definitions (markdown)
|
|
454
|
+
ref/ # Reference docs (adversarial-review, requirement-sizing, graph-correction)
|
|
385
455
|
hooks/ # Installable hooks (pre-commit, version-check)
|
|
386
456
|
tests/ # Test suite (vitest)
|
|
387
457
|
```
|
|
388
458
|
|
|
389
459
|
### Design Decisions
|
|
390
460
|
|
|
391
|
-
**
|
|
461
|
+
**Graph-driven execution.** Projects are modeled as a DAG of requirements with explicit dependencies. `findReady()` acts as a scheduler, selecting the next executable requirement based on dependency completion, priority, and group ordering. This replaces the earlier milestone/wave architecture with a more granular model that naturally handles partial failures and incremental progress.
|
|
462
|
+
|
|
463
|
+
**Skill-driven orchestration.** The build workflow (adversarial review, discovery flow, retry logic) is defined in skill markdown files, not in TypeScript. The graph engine provides the execution loop and scheduling; the skill files define how each requirement is actually built and reviewed. This separation means orchestration patterns can be modified by editing markdown -- no code changes, no builds.
|
|
464
|
+
|
|
465
|
+
**File system as memory.** Requirements communicate through `.planning/graph/{slug}/` files on disk. No in-memory state passes between requirements. Each requirement gets a fresh Claude session, which avoids context degradation over long projects. The graph index is the single source of truth for project state.
|
|
392
466
|
|
|
393
|
-
**
|
|
467
|
+
**Atomic writes.** All graph mutations (status updates, new requirements, index changes) use crash-safe writes: write to a temp file, then rename. Index is written first so that a crash between index and requirement file writes leaves the system in a recoverable state.
|
|
394
468
|
|
|
395
|
-
**
|
|
469
|
+
**Attention-aware prompting.** When building a requirement, the prompt loads context in a specific order: project overview → dependency artifacts → target requirement. The target requirement is loaded last to exploit recency bias in the model's attention, keeping acceptance criteria and file scope front of mind.
|
|
470
|
+
|
|
471
|
+
**Human-gated discovery.** When a build agent discovers that additional requirements are needed, they are created with `discovered` status. These must be explicitly approved by the user before entering the execution queue. This prevents unbounded scope expansion while still capturing emergent work.
|
|
472
|
+
|
|
473
|
+
**Sequential execution, parallel-safe design.** Requirements execute one at a time in the current implementation, but the graph engine's `computeWaves()` function can identify parallel-safe groups. The architecture supports future parallel execution without structural changes.
|
|
396
474
|
|
|
397
475
|
**Gate pipeline, not gate tree.** Gates run sequentially, not in parallel. This is intentional -- types must pass before lint makes sense, lint before tests. Per-gate timeouts (default 2 minutes) prevent hangs.
|
|
398
476
|
|
|
399
477
|
### Extension Points
|
|
400
478
|
|
|
401
|
-
**Adding a gate:** Create a new file in `src/gates/` implementing the `Gate` interface (`name: string`, `run: (projectDir: string) => Promise<GateResult>`). Register it in `src/
|
|
479
|
+
**Adding a gate:** Create a new file in `src/gates/` implementing the `Gate` interface (`name: string`, `run: (projectDir: string) => Promise<GateResult>`). Register it in `src/gates/index.ts` with `registerGate()`.
|
|
402
480
|
|
|
403
481
|
**Custom Linear states:** Override the default state names in `.forge.json`:
|
|
404
482
|
|
|
@@ -423,16 +501,6 @@ forge-cc/
|
|
|
423
501
|
}
|
|
424
502
|
```
|
|
425
503
|
|
|
426
|
-
### Key Lessons Learned
|
|
427
|
-
|
|
428
|
-
These lessons were learned during forge-cc's own development and are baked into the workflow:
|
|
429
|
-
|
|
430
|
-
- **Milestone sizing matters.** Every milestone must be completable in one agent context window. If it's too large, split it. The `/forge:spec` skill enforces this.
|
|
431
|
-
- **No compaction chaining.** Never rely on Claude Code's context compaction for multi-milestone execution. Fresh processes per milestone (via `forge run`) are the correct pattern -- the file system is the only memory between iterations.
|
|
432
|
-
- **Restage at wave boundaries.** Parallel builder agents can disrupt each other's git index. Restage all files at wave boundaries.
|
|
433
|
-
- **Verify between waves.** Run `tsc --noEmit` between every wave, not just at the end. Catches cross-agent integration issues early.
|
|
434
|
-
- **Silent failure is a bug.** CLI commands that touch external systems must print what they did or why they skipped. No-output-as-success is not acceptable.
|
|
435
|
-
|
|
436
504
|
### Development
|
|
437
505
|
|
|
438
506
|
```bash
|
|
@@ -443,7 +511,7 @@ npx tsc --noEmit # Type check
|
|
|
443
511
|
npx forge verify # Self-verify
|
|
444
512
|
```
|
|
445
513
|
|
|
446
|
-
**Stack:** TypeScript (ES2022 strict), Node.js 18+,
|
|
514
|
+
**Stack:** TypeScript (ES2022 strict), Node.js 18+, Commander, Zod, Vitest
|
|
447
515
|
|
|
448
516
|
</details>
|
|
449
517
|
|