forge-cc 2.0.0 → 2.0.2
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 +234 -133
- package/dist/cli.js +127 -1
- package/dist/cli.js.map +1 -1
- package/dist/codex-poll.d.ts +17 -1
- package/dist/codex-poll.js +3 -7
- package/dist/codex-poll.js.map +1 -1
- package/dist/linear/client.d.ts +9 -0
- package/dist/linear/client.js +50 -0
- package/dist/linear/client.js.map +1 -1
- package/dist/linear/sync.d.ts +23 -4
- package/dist/linear/sync.js +66 -30
- package/dist/linear/sync.js.map +1 -1
- package/dist/runner/loop.js +34 -23
- package/dist/runner/loop.js.map +1 -1
- package/dist/setup.js +107 -3
- package/dist/setup.js.map +1 -1
- package/hooks/linear-branch-enforce.js +395 -0
- package/hooks/linear-post-action.js +331 -0
- package/hooks/linear-worktree-create.js +337 -0
- package/package.json +1 -1
- package/skills/forge-build.md +97 -49
- package/skills/forge-capture.md +6 -6
- package/skills/forge-fix.md +5 -0
- package/skills/forge-plan.md +16 -4
- package/skills/forge-quick.md +4 -0
- package/skills/ref/codex-review.md +158 -0
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:
|
|
76
|
+
|
|
77
|
+
```
|
|
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
|
|
100
|
+
```
|
|
101
|
+
|
|
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
|
|
70
131
|
|
|
71
132
|
```
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
| Findings go through consensus protocol with builders |
|
|
79
|
-
+-------------------+-------------------+-----------------------------+
|
|
80
|
-
| BUILDER 1 | BUILDER 2 | BUILDER N ... |
|
|
81
|
-
| Parallel agents | Parallel agents | Each gets a task, |
|
|
82
|
-
| within each wave | within each wave | writes + tests code |
|
|
83
|
-
+-------------------+-------------------+-----------------------------+
|
|
84
|
-
| NOTETAKER (optional, for 3+ waves or 4+ agents) |
|
|
85
|
-
| Tracks decisions, file ownership, cross-agent dependencies |
|
|
86
|
-
+---------------------------------------------------------------------+
|
|
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)
|
|
87
139
|
```
|
|
88
140
|
|
|
89
|
-
|
|
141
|
+
### Key Functions
|
|
142
|
+
|
|
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. |
|
|
150
|
+
|
|
151
|
+
### Graph Files
|
|
90
152
|
|
|
91
153
|
```
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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
|
+
...
|
|
98
161
|
```
|
|
99
162
|
|
|
100
|
-
The
|
|
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
|
+
---
|
|
101
166
|
|
|
102
|
-
|
|
167
|
+
## Adversarial Review
|
|
103
168
|
|
|
104
|
-
|
|
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.
|
|
105
170
|
|
|
106
|
-
|
|
171
|
+
**What the reviewer checks:**
|
|
107
172
|
|
|
108
|
-
|
|
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,79 @@ 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 --> In Review -->
|
|
142
|
-
| | | |
|
|
143
|
-
Forge Action:
|
|
144
|
-
|
|
145
|
-
|
|
211
|
+
Linear State: Backlog --> Planned --> In Progress --> In Review --> Completed
|
|
212
|
+
| | | | |
|
|
213
|
+
Forge Action: /forge: /forge:plan /forge:build forge linear forge linear
|
|
214
|
+
capture syncs issues starts each ship opens PR sync-merged
|
|
215
|
+
creates to Linear requirement + links issues after PR merge
|
|
216
|
+
projects
|
|
146
217
|
```
|
|
147
218
|
|
|
148
|
-
|
|
219
|
+
- `syncRequirementStart()` -- Moves the issue to "In Progress" and moves the project to "In Progress" (best-effort, never crashes on API errors)
|
|
220
|
+
- `syncGraphProjectReview()` -- Moves the project to "In Review" when `forge linear ship` opens/reuses a PR
|
|
221
|
+
- `syncGraphProjectPlanned()` -- Moves the project to "Planned" after planning completes (`forge linear sync-planned --slug <slug>`)
|
|
222
|
+
- `syncGraphProjectCompleted()` -- Moves the project to "Completed" after PR merge (`forge linear sync-merged --slug <slug>`)
|
|
223
|
+
|
|
224
|
+
### Deterministic Handoff (Build -> PR -> Merge)
|
|
149
225
|
|
|
150
|
-
|
|
226
|
+
`forge run` completes requirements and leaves the graph in a shippable state. PR handoff is a separate explicit step:
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
# 1) Build requirements
|
|
230
|
+
npx forge run --prd <slug>
|
|
231
|
+
|
|
232
|
+
# 2) Ship: push branch + open/reuse PR + attach PR URL to complete requirement issues
|
|
233
|
+
npx forge linear ship --slug <slug>
|
|
234
|
+
|
|
235
|
+
# Optional override if complete requirements are missing linearIssueId
|
|
236
|
+
npx forge linear ship --slug <slug> --allow-missing-issue-id
|
|
237
|
+
|
|
238
|
+
# 3) After PR merge: move Linear project to Completed
|
|
239
|
+
npx forge linear sync-merged --slug <slug>
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
`forge linear ship` behavior:
|
|
243
|
+
- Pushes the graph branch (`_index.yaml -> branch`) to `origin`
|
|
244
|
+
- Creates a PR if one does not exist, or reuses the existing open PR for that branch
|
|
245
|
+
- Moves the Linear project to **In Review**
|
|
246
|
+
- Attaches the PR URL to all **complete** requirements in the slug that have `linearIssueId`
|
|
247
|
+
- Blocks by default if a complete requirement is missing `linearIssueId` (override with `--allow-missing-issue-id`)
|
|
248
|
+
- Warns and continues if attaching a PR URL to a Linear issue fails
|
|
249
|
+
|
|
250
|
+
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.
|
|
251
|
+
|
|
252
|
+
Set `LINEAR_API_KEY` in your environment to enable.
|
|
151
253
|
|
|
152
254
|
---
|
|
153
255
|
|
|
154
|
-
##
|
|
256
|
+
## Worktree Isolation
|
|
155
257
|
|
|
156
|
-
|
|
258
|
+
Every requirement executes in its own git worktree. You never touch git.
|
|
157
259
|
|
|
158
260
|
```
|
|
159
|
-
main
|
|
160
|
-
|
|
|
161
|
-
|
|
162
|
-
|
|
|
163
|
-
|
|
261
|
+
main ──────────────────────────────────────────────> main (updated)
|
|
262
|
+
| ^
|
|
263
|
+
+──> feat/my-project ──> worktree req-001 ──> merge ──>─+
|
|
264
|
+
| |
|
|
265
|
+
+──> worktree req-002 ──>──+
|
|
266
|
+
| (sequential)
|
|
267
|
+
+──> worktree req-003 ──>──+
|
|
164
268
|
```
|
|
165
269
|
|
|
166
|
-
**
|
|
270
|
+
**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
271
|
|
|
168
|
-
**Minimal footprint** -- Worktree management is 3 functions (
|
|
272
|
+
**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
273
|
|
|
170
|
-
**Automatic cleanup** -- When a
|
|
274
|
+
**Automatic cleanup** -- When a requirement finishes (pass or fail), its worktree is removed. Protected branches (`main`, `master`) are never committed to directly.
|
|
171
275
|
|
|
172
276
|
---
|
|
173
277
|
|
|
@@ -184,7 +288,7 @@ npx forge setup
|
|
|
184
288
|
export LINEAR_API_KEY="lin_api_..."
|
|
185
289
|
|
|
186
290
|
# 4. Start building
|
|
187
|
-
# /forge:
|
|
291
|
+
# /forge:capture -> /forge:plan -> /forge:build
|
|
188
292
|
```
|
|
189
293
|
|
|
190
294
|
`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 +312,11 @@ export LINEAR_API_KEY="lin_api_..."
|
|
|
208
312
|
|--------|------|---------|-------------|
|
|
209
313
|
| `gates` | `string[]` | `["types", "lint", "tests"]` | Which verification gates to run |
|
|
210
314
|
| `gateTimeouts` | `Record<string, number>` | `{}` | Per-gate timeout in ms (default 120000 per gate) |
|
|
211
|
-
| `maxIterations` | `number` | `5` | Max
|
|
315
|
+
| `maxIterations` | `number` | `5` | Max retry iterations per requirement |
|
|
212
316
|
| `linearTeam` | `string` | `""` | Linear team key or name for lifecycle sync |
|
|
213
317
|
| `linearStates` | `object` | see below | Custom Linear state names |
|
|
214
318
|
| `verifyFreshness` | `number` | `600000` | Verify cache validity in ms (default 10 min) |
|
|
215
|
-
| `forgeVersion` | `string` | `"
|
|
319
|
+
| `forgeVersion` | `string` | `"2.0.0"` | Version stamp from setup (used by version-check hook) |
|
|
216
320
|
|
|
217
321
|
**`linearStates` defaults:**
|
|
218
322
|
|
|
@@ -239,11 +343,11 @@ npx forge verify # Run all configured gates
|
|
|
239
343
|
npx forge verify --gate types,lint # Run specific gates
|
|
240
344
|
npx forge verify --json # Output results as JSON
|
|
241
345
|
|
|
242
|
-
#
|
|
243
|
-
npx forge run --prd <slug> #
|
|
346
|
+
# Graph execution
|
|
347
|
+
npx forge run --prd <slug> # Execute all requirements for a graph
|
|
244
348
|
|
|
245
349
|
# Status
|
|
246
|
-
npx forge status # Show
|
|
350
|
+
npx forge status # Show project progress across all graphs
|
|
247
351
|
|
|
248
352
|
# Setup & maintenance
|
|
249
353
|
npx forge setup # Initialize forge for a project
|
|
@@ -251,11 +355,21 @@ npx forge setup --skills-only # Only sync skill files
|
|
|
251
355
|
npx forge doctor # Environment health check
|
|
252
356
|
npx forge update # Check for and install updates
|
|
253
357
|
|
|
254
|
-
# Linear commands
|
|
255
|
-
npx forge linear
|
|
256
|
-
npx forge linear
|
|
257
|
-
npx forge linear
|
|
258
|
-
npx forge linear
|
|
358
|
+
# Linear commands
|
|
359
|
+
npx forge linear create-project --name <name> --team <teamId>
|
|
360
|
+
npx forge linear create-milestone --project <id> --name <name>
|
|
361
|
+
npx forge linear create-issue --team <teamId> --title <title> [--project <id>] [--milestone <id>]
|
|
362
|
+
npx forge linear create-issue-batch --team <teamId> --project <id> --milestone <id> --issues '<json>'
|
|
363
|
+
npx forge linear create-project-relation --project <id> --related-project <id> --type <blocks|related>
|
|
364
|
+
npx forge linear create-issue-relation --issue <id> --related-issue <id> --type <blocks|duplicate|related>
|
|
365
|
+
npx forge linear list-teams
|
|
366
|
+
npx forge linear list-projects --team <teamId>
|
|
367
|
+
npx forge linear sync-planned --slug <slug>
|
|
368
|
+
npx forge linear ship --slug <slug> [--base <branch>] [--title <title>] [--body <body>] [--draft] [--allow-missing-issue-id]
|
|
369
|
+
npx forge linear sync-merged --slug <slug>
|
|
370
|
+
|
|
371
|
+
# GitHub Codex
|
|
372
|
+
npx forge codex-poll --owner <owner> --repo <repo> --pr <number>
|
|
259
373
|
```
|
|
260
374
|
|
|
261
375
|
### Skill Commands
|
|
@@ -264,10 +378,12 @@ Skills are Claude Code slash commands installed to `~/.claude/commands/forge/`:
|
|
|
264
378
|
|
|
265
379
|
| Skill | Description |
|
|
266
380
|
|-------|-------------|
|
|
267
|
-
| `/forge:
|
|
268
|
-
| `/forge:
|
|
269
|
-
| `/forge:
|
|
270
|
-
| `/forge:
|
|
381
|
+
| `/forge:capture` | Brain dump to Linear projects -- extracts, deduplicates, creates |
|
|
382
|
+
| `/forge:plan` | Codebase scan + adaptive interview → requirement graph with dependency DAG |
|
|
383
|
+
| `/forge:build` | Execute requirement graph -- worktree isolation, adversarial review, self-healing verify |
|
|
384
|
+
| `/forge:fix` | Surgical recovery for failed requirements -- diagnose, repair, re-verify |
|
|
385
|
+
| `/forge:quick` | Ad-hoc tasks without planning ceremony -- branch, build, verify, PR |
|
|
386
|
+
| `/forge:setup` | Initialize project scaffolding -- config, hooks, skills, CLAUDE.md |
|
|
271
387
|
| `/forge:update` | Check for updates and upgrade forge-cc |
|
|
272
388
|
|
|
273
389
|
### Enforcement Hooks
|
|
@@ -277,42 +393,19 @@ Forge installs two Claude Code hooks during setup:
|
|
|
277
393
|
- **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
394
|
- **Version check hook** (`version-check.js`) -- Non-blocking notice when a newer forge-cc version is available or when project setup is stale.
|
|
279
395
|
|
|
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
396
|
---
|
|
305
397
|
|
|
306
398
|
## How It's Different
|
|
307
399
|
|
|
308
400
|
| Without forge | With forge |
|
|
309
401
|
|--------------|-----------|
|
|
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
|
|
402
|
+
| Agent writes code, you review everything | Graph-driven execution with adversarial review catches issues before you see them |
|
|
403
|
+
| Manual git branching, PRs, merges | Automatic worktrees per requirement, branches, and PRs |
|
|
404
|
+
| "Tests pass" = done | 3 gates (types + lint + tests) with self-healing retry loop |
|
|
405
|
+
| One agent, one task, serial | Dependency-aware execution with topological ordering |
|
|
406
|
+
| Context rot across long sessions | Fresh session per requirement, file system is the only memory |
|
|
315
407
|
| Linear updated manually | Automatic state transitions through your pipeline |
|
|
408
|
+
| Failed builds need manual triage | `/forge:fix` provides surgical recovery with targeted diagnosis |
|
|
316
409
|
|
|
317
410
|
---
|
|
318
411
|
|
|
@@ -323,7 +416,7 @@ Returns the full pipeline result as JSON (result status, per-gate pass/fail, err
|
|
|
323
416
|
|
|
324
417
|
### `forge run` fails when invoked from within Claude Code
|
|
325
418
|
|
|
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:
|
|
419
|
+
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
420
|
|
|
328
421
|
### Pre-commit hook blocks commits
|
|
329
422
|
|
|
@@ -331,11 +424,13 @@ The pre-commit hook requires a passing verification cached in `.forge/last-verif
|
|
|
331
424
|
|
|
332
425
|
### Linear sync runs but does nothing
|
|
333
426
|
|
|
334
|
-
|
|
427
|
+
Check:
|
|
335
428
|
1. `LINEAR_API_KEY` is set in your environment
|
|
336
|
-
2. Your
|
|
429
|
+
2. Your graph's `_index.yaml` has `linear.projectId` and `linear.teamId` populated (set during `/forge:plan`)
|
|
337
430
|
3. Run `npx forge doctor` to validate the API key and team configuration
|
|
338
431
|
|
|
432
|
+
If `forge linear ship` exits with missing `linearIssueId`, at least one **complete** requirement in the slug is missing issue linkage. Add `linearIssueId` in the graph index, or rerun with `--allow-missing-issue-id` to continue without linking those requirements.
|
|
433
|
+
|
|
339
434
|
### `forge run` on Windows
|
|
340
435
|
|
|
341
436
|
On Windows, to locate the globally installed `forge-cc` package programmatically, use `process.env.APPDATA + '/npm/node_modules/forge-cc'`. Don't use bash path traversal -- backslash escaping breaks (the `\n` in `npm\node_modules` is interpreted as a newline).
|
|
@@ -357,7 +452,7 @@ Run `npx forge doctor` to see which checks fail. Required: Node.js >= 18 and git
|
|
|
357
452
|
forge-cc/
|
|
358
453
|
src/
|
|
359
454
|
cli.ts # CLI entry (npx forge)
|
|
360
|
-
|
|
455
|
+
codex-poll.ts # GitHub Codex PR review polling
|
|
361
456
|
types.ts # Core types
|
|
362
457
|
doctor.ts # Environment health checks
|
|
363
458
|
setup.ts # Project scaffolding
|
|
@@ -369,36 +464,52 @@ forge-cc/
|
|
|
369
464
|
types-gate.ts # TypeScript gate (tsc --noEmit)
|
|
370
465
|
lint-gate.ts # Lint gate (biome check)
|
|
371
466
|
tests-gate.ts # Tests gate (vitest/jest)
|
|
467
|
+
graph/
|
|
468
|
+
types.ts # Graph types (GraphIndex, Requirement, RequirementMeta)
|
|
469
|
+
schemas.ts # Zod schemas for graph YAML
|
|
470
|
+
reader.ts # Load index, requirements, overview from disk
|
|
471
|
+
writer.ts # Atomic writes for index, requirements, overview
|
|
472
|
+
query.ts # findReady, computeWaves, getTransitiveDeps, isProjectComplete
|
|
473
|
+
validator.ts # Structural validation (cycles, dangling deps, file conflicts)
|
|
474
|
+
index.ts # Public re-exports
|
|
372
475
|
linear/
|
|
373
|
-
client.ts # @linear/sdk wrapper (team-scoped)
|
|
374
|
-
sync.ts # Linear state transitions
|
|
476
|
+
client.ts # @linear/sdk wrapper (team-scoped, category+name fallback)
|
|
477
|
+
sync.ts # Linear state transitions (syncRequirementStart, syncGraphProjectReview, syncGraphProjectPlanned, syncGraphProjectCompleted)
|
|
375
478
|
runner/
|
|
376
|
-
loop.ts #
|
|
377
|
-
prompt.ts # Prompt builder
|
|
479
|
+
loop.ts # Graph loop executor (sequential requirement execution)
|
|
480
|
+
prompt.ts # Prompt builder (attention-aware requirement context)
|
|
378
481
|
update.ts # Version check
|
|
379
482
|
state/
|
|
380
|
-
status.ts # PRD status CRUD
|
|
381
483
|
cache.ts # Verify cache writer
|
|
382
484
|
worktree/
|
|
383
485
|
manager.ts # createWorktree, mergeWorktree, removeWorktree
|
|
384
486
|
skills/ # Claude Code skill definitions (markdown)
|
|
487
|
+
ref/ # Reference docs (adversarial-review, requirement-sizing, graph-correction)
|
|
385
488
|
hooks/ # Installable hooks (pre-commit, version-check)
|
|
386
489
|
tests/ # Test suite (vitest)
|
|
387
490
|
```
|
|
388
491
|
|
|
389
492
|
### Design Decisions
|
|
390
493
|
|
|
391
|
-
**
|
|
494
|
+
**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.
|
|
495
|
+
|
|
496
|
+
**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.
|
|
392
497
|
|
|
393
|
-
**File system as memory.**
|
|
498
|
+
**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.
|
|
394
499
|
|
|
395
|
-
**
|
|
500
|
+
**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.
|
|
501
|
+
|
|
502
|
+
**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.
|
|
503
|
+
|
|
504
|
+
**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.
|
|
505
|
+
|
|
506
|
+
**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
507
|
|
|
397
508
|
**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
509
|
|
|
399
510
|
### Extension Points
|
|
400
511
|
|
|
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/
|
|
512
|
+
**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
513
|
|
|
403
514
|
**Custom Linear states:** Override the default state names in `.forge.json`:
|
|
404
515
|
|
|
@@ -423,16 +534,6 @@ forge-cc/
|
|
|
423
534
|
}
|
|
424
535
|
```
|
|
425
536
|
|
|
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
537
|
### Development
|
|
437
538
|
|
|
438
539
|
```bash
|
|
@@ -443,7 +544,7 @@ npx tsc --noEmit # Type check
|
|
|
443
544
|
npx forge verify # Self-verify
|
|
444
545
|
```
|
|
445
546
|
|
|
446
|
-
**Stack:** TypeScript (ES2022 strict), Node.js 18+,
|
|
547
|
+
**Stack:** TypeScript (ES2022 strict), Node.js 18+, Commander, Zod, Vitest
|
|
447
548
|
|
|
448
549
|
</details>
|
|
449
550
|
|