@entelligentsia/forgecli 0.6.6 → 0.7.7
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/CHANGELOG.md +112 -0
- package/README.md +99 -190
- package/dist/bin/forge.js +20 -0
- package/dist/bin/forge.js.map +1 -1
- package/dist/extensions/forgecli/approve.d.ts +24 -0
- package/dist/extensions/forgecli/approve.js +202 -0
- package/dist/extensions/forgecli/approve.js.map +1 -0
- package/dist/extensions/forgecli/audience-gate.d.ts +4 -0
- package/dist/extensions/forgecli/audience-gate.js +8 -5
- package/dist/extensions/forgecli/audience-gate.js.map +1 -1
- package/dist/extensions/forgecli/collate.d.ts +24 -0
- package/dist/extensions/forgecli/collate.js +199 -0
- package/dist/extensions/forgecli/collate.js.map +1 -0
- package/dist/extensions/forgecli/commit.d.ts +24 -0
- package/dist/extensions/forgecli/commit.js +202 -0
- package/dist/extensions/forgecli/commit.js.map +1 -0
- package/dist/extensions/forgecli/fix-bug.d.ts +75 -0
- package/dist/extensions/forgecli/fix-bug.js +1133 -0
- package/dist/extensions/forgecli/fix-bug.js.map +1 -0
- package/dist/extensions/forgecli/forge-commands.js +7 -0
- package/dist/extensions/forgecli/forge-commands.js.map +1 -1
- package/dist/extensions/forgecli/forge-header.js +10 -4
- package/dist/extensions/forgecli/forge-header.js.map +1 -1
- package/dist/extensions/forgecli/forge-init.js +16 -8
- package/dist/extensions/forgecli/forge-init.js.map +1 -1
- package/dist/extensions/forgecli/forge-subagent.d.ts +29 -0
- package/dist/extensions/forgecli/forge-subagent.js +14 -1
- package/dist/extensions/forgecli/forge-subagent.js.map +1 -1
- package/dist/extensions/forgecli/hook-dispatcher.d.ts +53 -1
- package/dist/extensions/forgecli/hook-dispatcher.js +47 -1
- package/dist/extensions/forgecli/hook-dispatcher.js.map +1 -1
- package/dist/extensions/forgecli/hooks/post-init-hook.d.ts +15 -0
- package/dist/extensions/forgecli/hooks/post-init-hook.js +127 -0
- package/dist/extensions/forgecli/hooks/post-init-hook.js.map +1 -0
- package/dist/extensions/forgecli/hooks/post-sprint-hook.d.ts +37 -0
- package/dist/extensions/forgecli/hooks/post-sprint-hook.js +166 -0
- package/dist/extensions/forgecli/hooks/post-sprint-hook.js.map +1 -0
- package/dist/extensions/forgecli/index.js +56 -5
- package/dist/extensions/forgecli/index.js.map +1 -1
- package/dist/extensions/forgecli/review-code.d.ts +24 -0
- package/dist/extensions/forgecli/review-code.js +202 -0
- package/dist/extensions/forgecli/review-code.js.map +1 -0
- package/dist/extensions/forgecli/review-plan.d.ts +24 -0
- package/dist/extensions/forgecli/review-plan.js +203 -0
- package/dist/extensions/forgecli/review-plan.js.map +1 -0
- package/dist/extensions/forgecli/run-sprint.d.ts +18 -0
- package/dist/extensions/forgecli/run-sprint.js +33 -1
- package/dist/extensions/forgecli/run-sprint.js.map +1 -1
- package/dist/extensions/forgecli/run-task.d.ts +21 -2
- package/dist/extensions/forgecli/run-task.js +33 -9
- package/dist/extensions/forgecli/run-task.js.map +1 -1
- package/dist/extensions/forgecli/session-registry.d.ts +10 -0
- package/dist/extensions/forgecli/session-registry.js +9 -0
- package/dist/extensions/forgecli/session-registry.js.map +1 -1
- package/dist/extensions/forgecli/validate.d.ts +24 -0
- package/dist/extensions/forgecli/validate.js +202 -0
- package/dist/extensions/forgecli/validate.js.map +1 -0
- package/dist/extensions/forgecli/wf-engine/engine.d.ts +23 -0
- package/dist/extensions/forgecli/wf-engine/engine.js +384 -0
- package/dist/extensions/forgecli/wf-engine/engine.js.map +1 -0
- package/dist/extensions/forgecli/wf-engine/event-parser.d.ts +6 -0
- package/dist/extensions/forgecli/wf-engine/event-parser.js +29 -0
- package/dist/extensions/forgecli/wf-engine/event-parser.js.map +1 -0
- package/dist/extensions/forgecli/wf-engine/id-gen.d.ts +6 -0
- package/dist/extensions/forgecli/wf-engine/id-gen.js +17 -0
- package/dist/extensions/forgecli/wf-engine/id-gen.js.map +1 -0
- package/dist/extensions/forgecli/wf-engine/loader.d.ts +2 -0
- package/dist/extensions/forgecli/wf-engine/loader.js +100 -0
- package/dist/extensions/forgecli/wf-engine/loader.js.map +1 -0
- package/dist/extensions/forgecli/wf-engine/predicate.d.ts +7 -0
- package/dist/extensions/forgecli/wf-engine/predicate.js +36 -0
- package/dist/extensions/forgecli/wf-engine/predicate.js.map +1 -0
- package/dist/extensions/forgecli/wf-engine/prompt-compiler.d.ts +15 -0
- package/dist/extensions/forgecli/wf-engine/prompt-compiler.js +23 -0
- package/dist/extensions/forgecli/wf-engine/prompt-compiler.js.map +1 -0
- package/dist/extensions/forgecli/wf-engine/register.d.ts +9 -0
- package/dist/extensions/forgecli/wf-engine/register.js +59 -0
- package/dist/extensions/forgecli/wf-engine/register.js.map +1 -0
- package/dist/extensions/forgecli/wf-engine/remit-check.d.ts +6 -0
- package/dist/extensions/forgecli/wf-engine/remit-check.js +42 -0
- package/dist/extensions/forgecli/wf-engine/remit-check.js.map +1 -0
- package/dist/extensions/forgecli/wf-engine/state-store.d.ts +13 -0
- package/dist/extensions/forgecli/wf-engine/state-store.js +43 -0
- package/dist/extensions/forgecli/wf-engine/state-store.js.map +1 -0
- package/dist/extensions/forgecli/wf-engine/types.d.ts +66 -0
- package/dist/extensions/forgecli/wf-engine/types.js +2 -0
- package/dist/extensions/forgecli/wf-engine/types.js.map +1 -0
- package/dist/extensions/forgecli/wf-engine/worker.d.ts +11 -0
- package/dist/extensions/forgecli/wf-engine/worker.js +50 -0
- package/dist/extensions/forgecli/wf-engine/worker.js.map +1 -0
- package/dist/forge-payload/.base-pack/workflows/_fragments/context-injection.md +10 -4
- package/dist/forge-payload/.base-pack/workflows/fix_bug.md +12 -0
- package/dist/forge-payload/.schemas/bug.schema.json +4 -2
- package/dist/forge-payload/.schemas/event.schema.json +22 -3
- package/dist/forge-payload/commands/add-pipeline.md +342 -0
- package/dist/forge-payload/commands/add-task.md +269 -0
- package/dist/forge-payload/commands/ask.md +43 -0
- package/dist/forge-payload/commands/calibrate.md +356 -0
- package/dist/forge-payload/commands/config.md +202 -0
- package/dist/forge-payload/commands/enhance.md +38 -0
- package/dist/forge-payload/commands/health.md +225 -0
- package/dist/forge-payload/commands/init.md +165 -0
- package/dist/forge-payload/commands/materialize.md +119 -0
- package/dist/forge-payload/commands/migrate.md +160 -0
- package/dist/forge-payload/commands/quiz-agent.md +38 -0
- package/dist/forge-payload/commands/regenerate.md +673 -0
- package/dist/forge-payload/commands/remove.md +174 -0
- package/dist/forge-payload/commands/report-bug.md +191 -0
- package/dist/forge-payload/commands/store-query.md +73 -0
- package/dist/forge-payload/commands/store-repair.md +187 -0
- package/dist/forge-payload/commands/update-tools.md +56 -0
- package/dist/forge-payload/commands/update.md +1376 -0
- package/dist/forge-payload/tools/preflight-gate.cjs +2 -1
- package/dist/forge-payload/tools/read-verdict.cjs +41 -8
- package/dist/forge-payload/tools/store-cli.cjs +4 -3
- package/node_modules/argparse/CHANGELOG.md +216 -0
- package/node_modules/argparse/LICENSE +254 -0
- package/node_modules/argparse/README.md +84 -0
- package/node_modules/argparse/argparse.js +3707 -0
- package/node_modules/argparse/lib/sub.js +67 -0
- package/node_modules/argparse/lib/textwrap.js +440 -0
- package/node_modules/argparse/package.json +31 -0
- package/node_modules/cliui/CHANGELOG.md +121 -0
- package/node_modules/color-convert/CHANGELOG.md +54 -0
- package/node_modules/esprima/ChangeLog +235 -0
- package/node_modules/js-yaml/LICENSE +21 -0
- package/node_modules/js-yaml/README.md +247 -0
- package/node_modules/js-yaml/bin/js-yaml.js +126 -0
- package/node_modules/js-yaml/dist/js-yaml.js +3880 -0
- package/node_modules/js-yaml/dist/js-yaml.min.js +2 -0
- package/node_modules/js-yaml/dist/js-yaml.mjs +3856 -0
- package/node_modules/js-yaml/index.js +47 -0
- package/node_modules/js-yaml/lib/common.js +59 -0
- package/node_modules/js-yaml/lib/dumper.js +965 -0
- package/node_modules/js-yaml/lib/exception.js +55 -0
- package/node_modules/js-yaml/lib/loader.js +1733 -0
- package/node_modules/js-yaml/lib/schema/core.js +11 -0
- package/node_modules/js-yaml/lib/schema/default.js +22 -0
- package/node_modules/js-yaml/lib/schema/failsafe.js +17 -0
- package/node_modules/js-yaml/lib/schema/json.js +19 -0
- package/node_modules/js-yaml/lib/schema.js +121 -0
- package/node_modules/js-yaml/lib/snippet.js +101 -0
- package/node_modules/js-yaml/lib/type/binary.js +125 -0
- package/node_modules/js-yaml/lib/type/bool.js +35 -0
- package/node_modules/js-yaml/lib/type/float.js +97 -0
- package/node_modules/js-yaml/lib/type/int.js +156 -0
- package/node_modules/js-yaml/lib/type/map.js +8 -0
- package/node_modules/js-yaml/lib/type/merge.js +12 -0
- package/node_modules/js-yaml/lib/type/null.js +35 -0
- package/node_modules/js-yaml/lib/type/omap.js +44 -0
- package/node_modules/js-yaml/lib/type/pairs.js +53 -0
- package/node_modules/js-yaml/lib/type/seq.js +8 -0
- package/node_modules/js-yaml/lib/type/set.js +29 -0
- package/node_modules/js-yaml/lib/type/str.js +8 -0
- package/node_modules/js-yaml/lib/type/timestamp.js +88 -0
- package/node_modules/js-yaml/lib/type.js +66 -0
- package/node_modules/js-yaml/package.json +66 -0
- package/node_modules/mz/HISTORY.md +66 -0
- package/node_modules/proper-lockfile/CHANGELOG.md +108 -0
- package/node_modules/source-map/CHANGELOG.md +301 -0
- package/node_modules/thenify/History.md +11 -0
- package/node_modules/thenify-all/History.md +11 -0
- package/node_modules/y18n/CHANGELOG.md +100 -0
- package/node_modules/yargs/CHANGELOG.md +88 -0
- package/node_modules/yargs-parser/CHANGELOG.md +263 -0
- package/package.json +6 -2
- package/themes/forge-matrix.json +89 -0
- package/themes/forge-mono.json +86 -0
- package/workflows/lead-qualifier/prompts/digest.md +44 -0
- package/workflows/lead-qualifier/prompts/draft-outreach.md +44 -0
- package/workflows/lead-qualifier/prompts/enrich.md +52 -0
- package/workflows/lead-qualifier/prompts/intake.md +48 -0
- package/workflows/lead-qualifier/prompts/mark-cold.md +38 -0
- package/workflows/lead-qualifier/prompts/score.md +45 -0
- package/workflows/lead-qualifier/workflow.yaml +95 -0
- package/workflows/research-brief/prompts/brief-synthesize.md +43 -0
- package/workflows/research-brief/prompts/intake.md +51 -0
- package/workflows/research-brief/prompts/source-critique.md +38 -0
- package/workflows/research-brief/prompts/source-score.md +38 -0
- package/workflows/research-brief/prompts/source-summarize.md +54 -0
- package/workflows/research-brief/workflow.yaml +66 -0
- package/dist/extensions/forgecli/session-monitor-widget.d.ts +0 -37
- package/dist/extensions/forgecli/session-monitor-widget.js +0 -320
- package/dist/extensions/forgecli/session-monitor-widget.js.map +0 -1
- package/dist/extensions/forgecli/session-monitor.d.ts +0 -2
- package/dist/extensions/forgecli/session-monitor.js +0 -135
- package/dist/extensions/forgecli/session-monitor.js.map +0 -1
|
@@ -34,15 +34,21 @@ else:
|
|
|
34
34
|
|
|
35
35
|
## Prior Phase Summary Block
|
|
36
36
|
|
|
37
|
-
Re-read the
|
|
37
|
+
Re-read the record from disk after each phase so summaries accumulate.
|
|
38
|
+
For bugs, pass `record_type="bug"` to read from the bugs store path.
|
|
38
39
|
|
|
39
40
|
```python
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
# record_type: "task" (default) or "bug"
|
|
42
|
+
if record_type == "bug":
|
|
43
|
+
record_fresh = read_json(f".forge/store/bugs/{record_id}.json")
|
|
44
|
+
else:
|
|
45
|
+
record_fresh = read_json(f".forge/store/tasks/{record_id}.json")
|
|
46
|
+
summaries = (record_fresh or {}).get("summaries", {})
|
|
42
47
|
|
|
43
48
|
SUMMARY_PHASE_LABELS = {
|
|
44
49
|
"plan": "Plan", "review_plan": "Plan review",
|
|
45
|
-
"implementation": "Implementation", "code_review": "Code review",
|
|
50
|
+
"implementation": "Implementation", "code_review": "Code review",
|
|
51
|
+
"validation": "Validation", "approve": "Approve", "triage": "Triage"
|
|
46
52
|
}
|
|
47
53
|
summary_lines = []
|
|
48
54
|
for phase_key, label in SUMMARY_PHASE_LABELS.items():
|
|
@@ -47,6 +47,11 @@ deps:
|
|
|
47
47
|
node "$FORGE_ROOT/tools/store-cli.cjs" read bug {BUG_ID} --json
|
|
48
48
|
- Reproduce the bug: create a failing test case or a reproduction script
|
|
49
49
|
- Confirm the root cause via codebase research
|
|
50
|
+
- After creating the bug record, transition to in-progress:
|
|
51
|
+
```sh
|
|
52
|
+
node "$FORGE_ROOT/tools/store-cli.cjs" update-status bug {BUG_ID} status triaged
|
|
53
|
+
node "$FORGE_ROOT/tools/store-cli.cjs" update-status bug {BUG_ID} status in-progress
|
|
54
|
+
```
|
|
50
55
|
|
|
51
56
|
2. Plan:
|
|
52
57
|
- Generate BUG_FIX_PLAN.md following the plan template
|
|
@@ -75,6 +80,9 @@ deps:
|
|
|
75
80
|
- **After Implement phase:**
|
|
76
81
|
Write `IMPLEMENTATION-SUMMARY.json` with `key_changes` and `verdict: "n/a"`.
|
|
77
82
|
Then: `node "$FORGE_ROOT/tools/store-cli.cjs" set-bug-summary {bug_id} implementation ...SUMMARY.json`
|
|
83
|
+
- **After Approve phase:**
|
|
84
|
+
Write `APPROVE-SUMMARY.json` with `objective`, `verdict` (approved|revision), and `artifact_ref`.
|
|
85
|
+
Then: `node "$FORGE_ROOT/tools/store-cli.cjs" set-bug-summary {bug_id} approve ...APPROVE-SUMMARY.json`
|
|
78
86
|
- If set-bug-summary exits non-zero, fix the JSON and retry before proceeding.
|
|
79
87
|
|
|
80
88
|
6. Finalize:
|
|
@@ -245,6 +253,8 @@ identical to `meta-orchestrate.md` — see that file's "Phase Gates" section
|
|
|
245
253
|
for the directive reference.
|
|
246
254
|
|
|
247
255
|
```gates phase=plan-fix
|
|
256
|
+
forbid bug.status == blocked
|
|
257
|
+
forbid bug.status == escalated
|
|
248
258
|
forbid bug.status == fixed
|
|
249
259
|
forbid bug.status == abandoned
|
|
250
260
|
```
|
|
@@ -254,6 +264,8 @@ artifact {engineering}/bugs/{bug}/BUG_FIX_PLAN.md min=200
|
|
|
254
264
|
```
|
|
255
265
|
|
|
256
266
|
```gates phase=implement
|
|
267
|
+
forbid bug.status == blocked
|
|
268
|
+
forbid bug.status == escalated
|
|
257
269
|
artifact {engineering}/bugs/{bug}/BUG_FIX_PLAN.md min=200
|
|
258
270
|
after review-plan = approved
|
|
259
271
|
forbid bug.status == fixed
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"title": { "type": "string" },
|
|
10
10
|
"description": { "type": "string" },
|
|
11
11
|
"severity": { "type": "string", "enum": ["critical", "major", "minor"] },
|
|
12
|
-
"status": { "type": "string", "enum": ["reported", "triaged", "in-progress", "fixed", "verified"] },
|
|
12
|
+
"status": { "type": "string", "enum": ["reported", "triaged", "in-progress", "fixed", "approved", "verified"] },
|
|
13
13
|
"path": { "type": "string" },
|
|
14
14
|
"rootCauseCategory": {
|
|
15
15
|
"type": "string",
|
|
@@ -26,10 +26,12 @@
|
|
|
26
26
|
"description": "Terse structured summaries of phase artifacts. Optional; full artifacts on disk remain authoritative.",
|
|
27
27
|
"properties": {
|
|
28
28
|
"plan": { "$ref": "#/$defs/phaseSummary" },
|
|
29
|
+
"triage": { "$ref": "#/$defs/phaseSummary" },
|
|
29
30
|
"review_plan": { "$ref": "#/$defs/phaseSummary" },
|
|
30
31
|
"implementation": { "$ref": "#/$defs/phaseSummary" },
|
|
31
32
|
"code_review": { "$ref": "#/$defs/phaseSummary" },
|
|
32
|
-
"validation": { "$ref": "#/$defs/phaseSummary" }
|
|
33
|
+
"validation": { "$ref": "#/$defs/phaseSummary" },
|
|
34
|
+
"approve": { "$ref": "#/$defs/phaseSummary" }
|
|
33
35
|
},
|
|
34
36
|
"additionalProperties": false
|
|
35
37
|
}
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"properties": {
|
|
11
11
|
"eventId": { "type": "string" },
|
|
12
12
|
"taskId": { "type": "string" },
|
|
13
|
+
"bugId": { "type": "string" },
|
|
13
14
|
"sprintId": { "type": "string" },
|
|
14
15
|
"role": { "type": "string" },
|
|
15
16
|
"action": { "type": "string" },
|
|
@@ -56,7 +57,11 @@
|
|
|
56
57
|
"task-committed",
|
|
57
58
|
"sprint-complete",
|
|
58
59
|
"sprint-halted",
|
|
59
|
-
"bug-fixed"
|
|
60
|
+
"bug-fixed",
|
|
61
|
+
|
|
62
|
+
"bug-triaged", "fix-planned", "fix-review-passed", "fix-review-failed",
|
|
63
|
+
"fix-implemented", "fix-code-review-passed", "fix-code-review-failed",
|
|
64
|
+
"fix-approved", "bug-committed"
|
|
60
65
|
]
|
|
61
66
|
},
|
|
62
67
|
"workflow": { "type": "string" },
|
|
@@ -99,8 +104,7 @@
|
|
|
99
104
|
"enum": [
|
|
100
105
|
"task-planned", "plan-complete", "plan-approved",
|
|
101
106
|
"task-implemented", "review-passed", "review-failed",
|
|
102
|
-
"task-approved", "task-validated", "task-committed"
|
|
103
|
-
"bug-fixed"
|
|
107
|
+
"task-approved", "task-validated", "task-committed"
|
|
104
108
|
]
|
|
105
109
|
}
|
|
106
110
|
},
|
|
@@ -108,6 +112,21 @@
|
|
|
108
112
|
},
|
|
109
113
|
"then": { "required": ["taskId", "phase", "iteration"] }
|
|
110
114
|
},
|
|
115
|
+
{
|
|
116
|
+
"if": {
|
|
117
|
+
"properties": {
|
|
118
|
+
"type": {
|
|
119
|
+
"enum": [
|
|
120
|
+
"bug-triaged", "fix-planned", "fix-review-passed", "fix-review-failed",
|
|
121
|
+
"fix-implemented", "fix-code-review-passed", "fix-code-review-failed",
|
|
122
|
+
"fix-approved", "bug-committed", "bug-fixed"
|
|
123
|
+
]
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
"required": ["type"]
|
|
127
|
+
},
|
|
128
|
+
"then": { "required": ["bugId", "phase", "iteration"] }
|
|
129
|
+
},
|
|
111
130
|
{
|
|
112
131
|
"if": { "properties": { "type": { "const": "sprint-complete" } }, "required": ["type"] },
|
|
113
132
|
"then": {
|
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: add-pipeline
|
|
3
|
+
description: Conversational pipeline manager — add, customize, view, or remove Forge pipelines and their phase commands
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /forge:add-pipeline
|
|
7
|
+
|
|
8
|
+
🌊 **Pipeline Manager** — I guide you through building and rewiring pipelines.
|
|
9
|
+
|
|
10
|
+
## Setup
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
FORGE_ROOT: !`echo "${CLAUDE_PLUGIN_ROOT}"`
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Read project config values:
|
|
17
|
+
```
|
|
18
|
+
PROJECT_PREFIX: !`node -e "try{console.log(require('./.forge/config.json').project.prefix)}catch{console.log('PROJECT')}"`
|
|
19
|
+
CUSTOM_COMMANDS_DIR: !`node -e "try{console.log(require('./.forge/config.json').paths.customCommands)}catch{console.log('engineering/commands')}"`
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Arguments
|
|
23
|
+
|
|
24
|
+
$ARGUMENTS
|
|
25
|
+
|
|
26
|
+
Parse for shortcuts:
|
|
27
|
+
- `--list` → jump directly to **View mode**
|
|
28
|
+
- `--remove <name>` → jump directly to **Remove mode** for that name
|
|
29
|
+
- A plain pipeline name with no other flags → jump to **Add/Edit mode** pre-filled with that name
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Opening conversation
|
|
34
|
+
|
|
35
|
+
If no shortcut was triggered, greet the user and ask intent:
|
|
36
|
+
|
|
37
|
+
> 🌊 **Pipeline Manager**
|
|
38
|
+
>
|
|
39
|
+
> What would you like to do?
|
|
40
|
+
>
|
|
41
|
+
> **1.** Add a new pipeline
|
|
42
|
+
> **2.** Customize an existing pipeline — override phases, swap commands, change models, rewire
|
|
43
|
+
> **3.** View configured pipelines
|
|
44
|
+
> **4.** Remove a pipeline
|
|
45
|
+
>
|
|
46
|
+
> ── Reply with a number, or just describe what you need.
|
|
47
|
+
|
|
48
|
+
Interpret free-text generously:
|
|
49
|
+
- "I want to change the model on the review phase" → mode 2
|
|
50
|
+
- "add a pipeline for hotfixes" / "new pipeline" → mode 1
|
|
51
|
+
- "show me what's configured" / "list" → mode 3
|
|
52
|
+
- "delete X" / "remove X" → mode 4
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Mode 1 — Add new pipeline
|
|
57
|
+
|
|
58
|
+
### Step 1 — Understand the use case
|
|
59
|
+
|
|
60
|
+
Ask:
|
|
61
|
+
|
|
62
|
+
> What kind of tasks should this pipeline handle?
|
|
63
|
+
> ── Describe the use case in a sentence or two.
|
|
64
|
+
> ── Example: "Data science tasks — need a schema validation step before coding begins"
|
|
65
|
+
|
|
66
|
+
From the description, suggest a pipeline name. The name must be `[a-z0-9_-]`:
|
|
67
|
+
|
|
68
|
+
> How about **`{suggested-name}`**? Does that work, or would you prefer something else?
|
|
69
|
+
|
|
70
|
+
Wait for confirmation or a new name.
|
|
71
|
+
|
|
72
|
+
### Step 2 — Phase-by-phase walkthrough
|
|
73
|
+
|
|
74
|
+
Display the standard phases as a starting point:
|
|
75
|
+
|
|
76
|
+
> Here are the standard Forge phases. For each one I'll ask whether to keep it as-is,
|
|
77
|
+
> adjust the model, replace it with a different command, skip it, or create a new custom command.
|
|
78
|
+
>
|
|
79
|
+
> | # | Phase role | Default command | Default model |
|
|
80
|
+
> |---|-----------|----------------|---------------|
|
|
81
|
+
> | 1 | plan | `plan` | sonnet |
|
|
82
|
+
> | 2 | review-plan | `review-plan` | opus |
|
|
83
|
+
> | 3 | implement | `implement` | sonnet |
|
|
84
|
+
> | 4 | review-code | `review-code` | opus |
|
|
85
|
+
> | 5 | validate | `validate` | opus |
|
|
86
|
+
> | 6 | approve | `approve` | opus |
|
|
87
|
+
> | 7 | commit | `commit` | haiku |
|
|
88
|
+
>
|
|
89
|
+
> ── Walk me through phase by phase, or describe your whole pipeline at once.
|
|
90
|
+
|
|
91
|
+
For each phase the user wants to customise, ask what they're trying to achieve before
|
|
92
|
+
asking for a command name. Based on their description of intent, suggest the right approach:
|
|
93
|
+
|
|
94
|
+
| Intent | Suggested approach |
|
|
95
|
+
|--------|-------------------|
|
|
96
|
+
| Stricter review, same role | Custom command with tighter instructions |
|
|
97
|
+
| Faster / cheaper phase | Keep command, lower the model (e.g. sonnet → haiku) |
|
|
98
|
+
| Domain-specific validation | New custom command |
|
|
99
|
+
| Skip a phase entirely | Remove it from the phase list |
|
|
100
|
+
| Different agent persona | New custom command |
|
|
101
|
+
|
|
102
|
+
For any phase using a custom command — check whether it exists before collecting more input:
|
|
103
|
+
```sh
|
|
104
|
+
ls {CUSTOM_COMMANDS_DIR}/{name}.md 2>/dev/null || ls .claude/commands/{name}.md 2>/dev/null
|
|
105
|
+
```
|
|
106
|
+
If it doesn't exist → go to **Custom Command Creation** below, then return here.
|
|
107
|
+
|
|
108
|
+
### Step 3 — Check for existing pipeline
|
|
109
|
+
|
|
110
|
+
```sh
|
|
111
|
+
node "$FORGE_ROOT/tools/manage-config.cjs" pipeline get {PIPELINE_NAME} 2>/dev/null
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
If output is non-empty, show the existing pipeline and ask:
|
|
115
|
+
> △ A pipeline named `{name}` already exists (shown above).
|
|
116
|
+
> Replace it, edit it instead, or pick a different name?
|
|
117
|
+
|
|
118
|
+
If "edit it" → switch to **Mode 2** for this pipeline, pre-filled with current phases.
|
|
119
|
+
|
|
120
|
+
### Step 4 → Preview and confirm (see Shared section)
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Mode 2 — Customize existing pipeline
|
|
125
|
+
|
|
126
|
+
### Step 1 — Select pipeline
|
|
127
|
+
|
|
128
|
+
List current pipelines:
|
|
129
|
+
```sh
|
|
130
|
+
node "$FORGE_ROOT/tools/manage-config.cjs" list-pipelines
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
If no pipelines exist:
|
|
134
|
+
> △ No pipelines configured yet. Would you like to add one? (Say yes to go to mode 1.)
|
|
135
|
+
|
|
136
|
+
If only one pipeline exists, select it automatically. Otherwise ask:
|
|
137
|
+
> Which pipeline would you like to customize?
|
|
138
|
+
|
|
139
|
+
### Step 2 — Show current phases
|
|
140
|
+
|
|
141
|
+
```sh
|
|
142
|
+
node "$FORGE_ROOT/tools/manage-config.cjs" pipeline get {PIPELINE_NAME}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Display the output as-is. It already renders as a phase table.
|
|
146
|
+
|
|
147
|
+
### Step 3 — Understand the change
|
|
148
|
+
|
|
149
|
+
Ask:
|
|
150
|
+
|
|
151
|
+
> What would you like to change?
|
|
152
|
+
>
|
|
153
|
+
> - **Override** a phase with a different command
|
|
154
|
+
> - **Change model** for one or more phases
|
|
155
|
+
> - **Add** a new phase at a specific position
|
|
156
|
+
> - **Remove** a phase
|
|
157
|
+
> - **Reorder** (rewire) the phases
|
|
158
|
+
>
|
|
159
|
+
> ── Describe what you need in plain language.
|
|
160
|
+
|
|
161
|
+
Listen to intent first, then collect specifics. Examples of intent-to-action mapping:
|
|
162
|
+
|
|
163
|
+
| User says | Action |
|
|
164
|
+
|-----------|--------|
|
|
165
|
+
| "I want a stricter security review" | Override `review-code` with a custom security-focused command |
|
|
166
|
+
| "skip plan review, we move fast" | Remove the `review-plan` phase |
|
|
167
|
+
| "use haiku for planning to save cost" | Update `model` on the `plan` phase to `haiku` |
|
|
168
|
+
| "add a data validation step before coding" | Insert a new `review-plan`-role phase before `implement` |
|
|
169
|
+
| "swap out the architect with my own approval command" | Override `approve` with a custom command |
|
|
170
|
+
|
|
171
|
+
For model changes — after the user names the phases, ask which model:
|
|
172
|
+
> Options: `haiku` (fast/cheap), `sonnet` (balanced), `opus` (thorough)
|
|
173
|
+
|
|
174
|
+
For phase overrides with a custom command — check if the command exists, then go to
|
|
175
|
+
**Custom Command Creation** if not.
|
|
176
|
+
|
|
177
|
+
For reordering — show the current sequence, ask for the new order, verify no
|
|
178
|
+
revision-loop is broken (a `review-*` phase needs a preceding non-review phase to
|
|
179
|
+
loop back to).
|
|
180
|
+
|
|
181
|
+
### Step 4 → Preview and confirm (see Shared section)
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## Mode 3 — View
|
|
186
|
+
|
|
187
|
+
```sh
|
|
188
|
+
node "$FORGE_ROOT/tools/manage-config.cjs" list-pipelines
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
If no pipelines are configured, say so and offer to add one.
|
|
192
|
+
|
|
193
|
+
If pipelines exist, offer to drill into one:
|
|
194
|
+
> ── To see a pipeline's full phase detail, tell me its name.
|
|
195
|
+
|
|
196
|
+
For a named pipeline:
|
|
197
|
+
```sh
|
|
198
|
+
node "$FORGE_ROOT/tools/manage-config.cjs" pipeline get {NAME}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Mode 4 — Remove
|
|
204
|
+
|
|
205
|
+
If no name was provided, list pipelines and ask which to remove.
|
|
206
|
+
|
|
207
|
+
Check for tasks referencing this pipeline:
|
|
208
|
+
```sh
|
|
209
|
+
grep -rl '"pipeline": "{NAME}"' .forge/store/tasks/ 2>/dev/null
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
If any found:
|
|
213
|
+
> △ {N} task(s) reference `{NAME}`. They will fall back to the default pipeline at runtime.
|
|
214
|
+
> The tasks themselves won't be modified — only the routing changes.
|
|
215
|
+
>
|
|
216
|
+
> Confirm removal? (yes / no)
|
|
217
|
+
|
|
218
|
+
On confirmation:
|
|
219
|
+
```sh
|
|
220
|
+
node "$FORGE_ROOT/tools/manage-config.cjs" pipeline remove {NAME}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## Custom Command Creation
|
|
226
|
+
|
|
227
|
+
When a phase needs a command that doesn't exist yet, guide the user through creating it.
|
|
228
|
+
|
|
229
|
+
Tell the user:
|
|
230
|
+
|
|
231
|
+
> The command **`{name}`** doesn't exist yet. I can create it now.
|
|
232
|
+
>
|
|
233
|
+
> A few questions:
|
|
234
|
+
>
|
|
235
|
+
> 1. **What should it do?**
|
|
236
|
+
> Describe the behavior — what it evaluates, produces, or enforces.
|
|
237
|
+
>
|
|
238
|
+
> 2. **What persona should it have?**
|
|
239
|
+
> Describe the agent's character and constraints.
|
|
240
|
+
> Example: "Strict data validator — refuses to approve if schema files are missing"
|
|
241
|
+
>
|
|
242
|
+
> 3. **What artifact does it produce?**
|
|
243
|
+
> Example: `SCHEMA_REVIEW.md`, `VALIDATION_REPORT.md`
|
|
244
|
+
|
|
245
|
+
From the answers, determine:
|
|
246
|
+
- **Persona symbol** — pick based on the phase role:
|
|
247
|
+
- Plan / implement / commit phases → 🌱
|
|
248
|
+
- Review phases → 🌿
|
|
249
|
+
- Approval / sign-off phases → ⛰️
|
|
250
|
+
- Domain-specific validator → 🌿
|
|
251
|
+
- Flow controller → 🌊
|
|
252
|
+
- Analysis / investigation → 🍂
|
|
253
|
+
- **Announcement line** — first-person, present tense, one sentence
|
|
254
|
+
- **Next status** — derive from the phase role (e.g. `review-plan` → `plan-approved` or `plan-revision-required`)
|
|
255
|
+
|
|
256
|
+
Use `.forge/templates/CUSTOM_COMMAND_TEMPLATE.md` as the scaffold. Fill in all
|
|
257
|
+
`{PLACEHOLDER}` values from the conversation.
|
|
258
|
+
|
|
259
|
+
Ensure the directory exists and write the file:
|
|
260
|
+
```sh
|
|
261
|
+
mkdir -p {CUSTOM_COMMANDS_DIR}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Create: `{CUSTOM_COMMANDS_DIR}/{name}.md`
|
|
265
|
+
|
|
266
|
+
Set the phase's `workflow` field to `"{CUSTOM_COMMANDS_DIR}/{name}.md"` in the pipeline
|
|
267
|
+
being built. This allows the orchestrator to read and follow the file directly — the
|
|
268
|
+
command name is used for display and manual reference only.
|
|
269
|
+
|
|
270
|
+
Confirm:
|
|
271
|
+
> 〇 Created `{CUSTOM_COMMANDS_DIR}/{name}.md`
|
|
272
|
+
> ── Review and edit it before running a task with this pipeline.
|
|
273
|
+
> ── The orchestrator will read it directly via the `workflow` field.
|
|
274
|
+
|
|
275
|
+
Return to the phase walkthrough where you left off.
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
## Shared: Preview and confirm
|
|
280
|
+
|
|
281
|
+
Before writing, construct the full pipeline JSON and display it clearly:
|
|
282
|
+
|
|
283
|
+
> 🌊 Here's the pipeline as it will be saved:
|
|
284
|
+
>
|
|
285
|
+
> **`{name}`** — {description}
|
|
286
|
+
>
|
|
287
|
+
> | # | Role | Command | Workflow | Model | maxIter |
|
|
288
|
+
> |---|------|---------|----------|-------|---------|
|
|
289
|
+
> | 1 | plan | `plan` | (built-in) | sonnet | — |
|
|
290
|
+
> | 2 | review-plan | `schema-validator` | `engineering/commands/schema-validator.md` | sonnet | 3 |
|
|
291
|
+
> ...
|
|
292
|
+
>
|
|
293
|
+
> ── Save this pipeline? (yes / edit / cancel)
|
|
294
|
+
|
|
295
|
+
- **yes** → proceed to Write
|
|
296
|
+
- **edit** → return to the relevant collection step
|
|
297
|
+
- **cancel** → exit without writing, no changes made
|
|
298
|
+
|
|
299
|
+
---
|
|
300
|
+
|
|
301
|
+
## Shared: Write
|
|
302
|
+
|
|
303
|
+
Invoke the tool:
|
|
304
|
+
```sh
|
|
305
|
+
node "$FORGE_ROOT/tools/manage-config.cjs" pipeline add {NAME} --description "{DESCRIPTION}" --phases '{PHASES_JSON}'
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
`PHASES_JSON` is a JSON array where each element includes `command`, `role`, `model`,
|
|
309
|
+
and — when a custom command was created — `workflow`. Example:
|
|
310
|
+
```json
|
|
311
|
+
[
|
|
312
|
+
{"command": "plan", "role": "plan", "model": "sonnet"},
|
|
313
|
+
{"command": "schema-validator", "role": "review-plan", "model": "sonnet",
|
|
314
|
+
"workflow": "engineering/commands/schema-validator.md", "maxIterations": 3},
|
|
315
|
+
{"command": "implement", "role": "implement", "model": "sonnet"},
|
|
316
|
+
{"command": "review-code", "role": "review-code", "model": "opus"},
|
|
317
|
+
{"command": "approve", "role": "approve", "model": "opus"},
|
|
318
|
+
{"command": "commit", "role": "commit", "model": "haiku"}
|
|
319
|
+
]
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
On success, print next steps:
|
|
323
|
+
|
|
324
|
+
```
|
|
325
|
+
〇 Pipeline '{NAME}' saved to .forge/config.json.
|
|
326
|
+
|
|
327
|
+
── Next steps:
|
|
328
|
+
1. If you created custom commands, review them in {CUSTOM_COMMANDS_DIR}/
|
|
329
|
+
and fill in any {PLACEHOLDER} sections before running a task.
|
|
330
|
+
2. Assign this pipeline to a task: set "pipeline": "{NAME}" in the task's
|
|
331
|
+
.forge/store/tasks/{TASK_ID}.json, or let the sprint planner auto-assign it.
|
|
332
|
+
3. Run /forge:regenerate to update the orchestrator's pipeline routing.
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
## On error
|
|
338
|
+
|
|
339
|
+
If any step fails unexpectedly:
|
|
340
|
+
> × Something went wrong: {error}
|
|
341
|
+
>
|
|
342
|
+
> ── This may be a Forge bug. Run `/forge:report-bug` and I'll pre-fill the report.
|