@garygentry/feature-forge 0.2.5 → 0.2.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/adapters/claude/.feature-forge-bundle.json +1 -1
- package/adapters/claude/agents/forge-verifier.md +2 -0
- package/adapters/claude/references/portable-root.md +18 -9
- package/adapters/claude/references/shared-conventions.md +21 -4
- package/adapters/claude/references/stage-exit-protocol.md +11 -7
- package/adapters/claude/references/vendor-construct-inventory.md +1 -0
- package/adapters/claude/scripts/forge-session.py +248 -5
- package/adapters/claude/skills/forge/SKILL.md +9 -9
- package/adapters/claude/skills/forge-0-epic/SKILL.md +5 -5
- package/adapters/claude/skills/forge-0-epic/references/edit-mode.md +2 -2
- package/adapters/claude/skills/forge-0-epic/references/epic-manifest-subcommands.md +1 -1
- package/adapters/claude/skills/forge-1-prd/SKILL.md +1 -1
- package/adapters/claude/skills/forge-2-tech/SKILL.md +1 -1
- package/adapters/claude/skills/forge-3-specs/SKILL.md +1 -1
- package/adapters/claude/skills/forge-4-backlog/SKILL.md +1 -1
- package/adapters/claude/skills/forge-5-loop/SKILL.md +2 -2
- package/adapters/claude/skills/forge-6-docs/SKILL.md +1 -1
- package/adapters/claude/skills/forge-bootstrap/SKILL.md +4 -4
- package/adapters/claude/skills/forge-init/SKILL.md +1 -1
- package/adapters/claude/skills/forge-verify/SKILL.md +9 -2
- package/adapters/claude/skills/forge-verify/references/verification-checklists.md +1 -1
- package/adapters/codex/.feature-forge-bundle.json +1 -1
- package/adapters/codex/agents/forge-verifier.toml +2 -0
- package/adapters/codex/references/portable-root.md +18 -9
- package/adapters/codex/references/shared-conventions.md +21 -4
- package/adapters/codex/references/stage-exit-protocol.md +11 -7
- package/adapters/codex/references/vendor-construct-inventory.md +1 -0
- package/adapters/codex/scripts/forge-session.py +248 -5
- package/adapters/codex/skills/forge/SKILL.md +9 -9
- package/adapters/codex/skills/forge-0-epic/SKILL.md +5 -5
- package/adapters/codex/skills/forge-0-epic/references/edit-mode.md +2 -2
- package/adapters/codex/skills/forge-0-epic/references/epic-manifest-subcommands.md +1 -1
- package/adapters/codex/skills/forge-1-prd/SKILL.md +1 -1
- package/adapters/codex/skills/forge-2-tech/SKILL.md +1 -1
- package/adapters/codex/skills/forge-3-specs/SKILL.md +1 -1
- package/adapters/codex/skills/forge-4-backlog/SKILL.md +1 -1
- package/adapters/codex/skills/forge-5-loop/SKILL.md +2 -2
- package/adapters/codex/skills/forge-6-docs/SKILL.md +1 -1
- package/adapters/codex/skills/forge-bootstrap/SKILL.md +4 -4
- package/adapters/codex/skills/forge-init/SKILL.md +1 -1
- package/adapters/codex/skills/forge-verify/SKILL.md +9 -2
- package/adapters/codex/skills/forge-verify/references/verification-checklists.md +1 -1
- package/adapters/copilot/.feature-forge-bundle.json +1 -1
- package/adapters/copilot/agents/forge-verifier.md +2 -0
- package/adapters/copilot/references/portable-root.md +18 -9
- package/adapters/copilot/references/shared-conventions.md +21 -4
- package/adapters/copilot/references/stage-exit-protocol.md +11 -7
- package/adapters/copilot/references/vendor-construct-inventory.md +1 -0
- package/adapters/copilot/scripts/forge-session.py +248 -5
- package/adapters/copilot/skills/forge/forge.md +9 -9
- package/adapters/copilot/skills/forge-0-epic/forge-0-epic.md +5 -5
- package/adapters/copilot/skills/forge-0-epic/references/edit-mode.md +2 -2
- package/adapters/copilot/skills/forge-0-epic/references/epic-manifest-subcommands.md +1 -1
- package/adapters/copilot/skills/forge-1-prd/forge-1-prd.md +1 -1
- package/adapters/copilot/skills/forge-2-tech/forge-2-tech.md +1 -1
- package/adapters/copilot/skills/forge-3-specs/forge-3-specs.md +1 -1
- package/adapters/copilot/skills/forge-4-backlog/forge-4-backlog.md +1 -1
- package/adapters/copilot/skills/forge-5-loop/forge-5-loop.md +2 -2
- package/adapters/copilot/skills/forge-6-docs/forge-6-docs.md +1 -1
- package/adapters/copilot/skills/forge-bootstrap/forge-bootstrap.md +4 -4
- package/adapters/copilot/skills/forge-init/forge-init.md +1 -1
- package/adapters/copilot/skills/forge-verify/forge-verify.md +9 -2
- package/adapters/copilot/skills/forge-verify/references/verification-checklists.md +1 -1
- package/adapters/cursor/.feature-forge-bundle.json +1 -1
- package/adapters/cursor/agents/forge-verifier.mdc +2 -0
- package/adapters/cursor/references/portable-root.md +18 -9
- package/adapters/cursor/references/shared-conventions.md +21 -4
- package/adapters/cursor/references/stage-exit-protocol.md +11 -7
- package/adapters/cursor/references/vendor-construct-inventory.md +1 -0
- package/adapters/cursor/scripts/forge-session.py +248 -5
- package/adapters/cursor/skills/forge/forge.mdc +9 -9
- package/adapters/cursor/skills/forge-0-epic/forge-0-epic.mdc +5 -5
- package/adapters/cursor/skills/forge-0-epic/references/edit-mode.md +2 -2
- package/adapters/cursor/skills/forge-0-epic/references/epic-manifest-subcommands.md +1 -1
- package/adapters/cursor/skills/forge-1-prd/forge-1-prd.mdc +1 -1
- package/adapters/cursor/skills/forge-2-tech/forge-2-tech.mdc +1 -1
- package/adapters/cursor/skills/forge-3-specs/forge-3-specs.mdc +1 -1
- package/adapters/cursor/skills/forge-4-backlog/forge-4-backlog.mdc +1 -1
- package/adapters/cursor/skills/forge-5-loop/forge-5-loop.mdc +2 -2
- package/adapters/cursor/skills/forge-6-docs/forge-6-docs.mdc +1 -1
- package/adapters/cursor/skills/forge-bootstrap/forge-bootstrap.mdc +4 -4
- package/adapters/cursor/skills/forge-init/forge-init.mdc +1 -1
- package/adapters/cursor/skills/forge-verify/forge-verify.mdc +9 -2
- package/adapters/cursor/skills/forge-verify/references/verification-checklists.md +1 -1
- package/adapters/gemini/.feature-forge-bundle.json +1 -1
- package/adapters/gemini/agents/forge-verifier.md +2 -0
- package/adapters/gemini/gemini-extension.json +1 -1
- package/adapters/gemini/references/portable-root.md +18 -9
- package/adapters/gemini/references/shared-conventions.md +21 -4
- package/adapters/gemini/references/stage-exit-protocol.md +11 -7
- package/adapters/gemini/references/vendor-construct-inventory.md +1 -0
- package/adapters/gemini/scripts/forge-session.py +248 -5
- package/adapters/gemini/skills/forge/forge.md +9 -9
- package/adapters/gemini/skills/forge-0-epic/forge-0-epic.md +5 -5
- package/adapters/gemini/skills/forge-0-epic/references/edit-mode.md +2 -2
- package/adapters/gemini/skills/forge-0-epic/references/epic-manifest-subcommands.md +1 -1
- package/adapters/gemini/skills/forge-1-prd/forge-1-prd.md +1 -1
- package/adapters/gemini/skills/forge-2-tech/forge-2-tech.md +1 -1
- package/adapters/gemini/skills/forge-3-specs/forge-3-specs.md +1 -1
- package/adapters/gemini/skills/forge-4-backlog/forge-4-backlog.md +1 -1
- package/adapters/gemini/skills/forge-5-loop/forge-5-loop.md +2 -2
- package/adapters/gemini/skills/forge-6-docs/forge-6-docs.md +1 -1
- package/adapters/gemini/skills/forge-bootstrap/forge-bootstrap.md +4 -4
- package/adapters/gemini/skills/forge-init/forge-init.md +1 -1
- package/adapters/gemini/skills/forge-verify/forge-verify.md +9 -2
- package/adapters/gemini/skills/forge-verify/references/verification-checklists.md +1 -1
- package/package.json +1 -1
|
@@ -28,7 +28,7 @@ For pipeline architecture details, read `references/process-overview.md`.
|
|
|
28
28
|
|
|
29
29
|
1. **Epics first.** Identify epic directories as any `{specsDir}/*/` that directly contains an `epic-manifest.json` **and no `.pipeline-state.json` of its own** (an epic root is never itself a feature). For each epic, run:
|
|
30
30
|
```bash
|
|
31
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
31
|
+
R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
32
32
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
33
33
|
python3 "$R/scripts/epic-manifest.py" render-status "{epic}" --specs-dir "{specsDir}" --json
|
|
34
34
|
```
|
|
@@ -36,14 +36,14 @@ python3 "$R/scripts/epic-manifest.py" render-status "{epic}" --specs-dir "{specs
|
|
|
36
36
|
2. **Standalone features below.** Scan the remaining `{specsDir}/*/` that directly contain a `.pipeline-state.json` **without** an `epic` back-pointer. A nested member's `.pipeline-state.json` is **attributed to its epic (Tier 1), never listed as a standalone feature**.
|
|
37
37
|
- **Rank by recency.** Run the recency ranker so the most-recently-touched active feature is the default — the user rarely has to type a name (especially on mobile after a clear your session / start a fresh session):
|
|
38
38
|
```bash
|
|
39
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
39
|
+
R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
40
40
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
41
41
|
python3 "$R/scripts/forge-session.py" rank-features --specs-dir "{specsDir}" --json
|
|
42
42
|
```
|
|
43
|
-
This returns `{active: [...], counts: {...}}` with active features sorted by `updatedAt` **descending** (row 0 is the most recent). Each row carries `currentStage`, `nextStage`, `nextCommand`, `verifyPending`, `verifyCommand`, `verifyStage`, `verifyState` (`fresh`/`stale`/`failing`/`never`/`none`), `autoVerify` (the effective per-stage setting),
|
|
43
|
+
This returns `{active: [...], counts: {...}}` with active features sorted by `updatedAt` **descending** (row 0 is the most recent). Each row carries `currentStage`, `nextStage`, `nextCommand`, `verifyPending`, `verifyCommand`, `verifyStage`, `verifyState` (`fresh`/`stale`/`failing`/`never`/`none`), `autoVerify` (the effective per-stage setting), `autoFix` (the single source of stage order), and `verifyGate` (`none`/`auto`/`standard` — the single resolved verify-gate, computed once by the ranker; read it rather than re-deriving from `verifyPending`+`autoVerify`). A top-level `invalidAutoVerifyKeys` array appears when `forge.config.json` has `autoVerifyStages` keys outside the five verify-capable stages — surface it as a one-line warning. The `active` list excludes nested epic members surfaced in Tier 1 — but the ranker scans them too, so ignore rows whose `epic` is non-null here (they belong to the epic rollup).
|
|
44
44
|
- **Pick the feature:** if exactly one active standalone pipeline exists, show its dashboard. If multiple exist, use the host's question mechanism — **list the most-recently-updated first, labeled `(recommended)`**, each option's description showing its `currentStage` and a relative age ("updated 2h ago"). Always include a free-form escape ("A different feature / something else") so the user is never boxed in. Then render the chosen feature's dashboard.
|
|
45
45
|
|
|
46
|
-
If no epics and no standalone features exist, say: "No active feature pipelines found. Start one with `/feature-forge:forge-1-prd <feature-name>` or group several with `/feature-forge:forge-0-epic <epic-name>`."
|
|
46
|
+
If no epics and no standalone features exist **on the current branch**, do not conclude the pipeline is empty yet — the state may live on topic branches (a fresh clone / default-branch session sees nothing on disk). Run `discover-feature --all` (via the standard prelude: `python3 "$R/scripts/forge-session.py" discover-feature --all --specs-dir "{specsDir}" --json`). If it surfaces features, list them with their branches and offer to switch (explicit accept + clean tree only, per the Feature Directory Resolution block), then render that feature's dashboard. Only when `--all` also returns nothing, say: "No active feature pipelines found. Start one with `/feature-forge:forge-1-prd <feature-name>` or group several with `/feature-forge:forge-0-epic <epic-name>`." Never fabricate a dashboard from memory of earlier sessions.
|
|
47
47
|
|
|
48
48
|
The feature name must be a single kebab-case token. If the user provides multiple words (e.g., "user auth flow"), convert to kebab-case: `user-auth-flow`.
|
|
49
49
|
|
|
@@ -88,11 +88,11 @@ Use these status indicators:
|
|
|
88
88
|
|
|
89
89
|
After rendering a **per-feature** dashboard for an **active** pipeline (skip this for paused/abandoned pipelines and for the Epic Dashboard), don't stop at a text suggestion — actively offer to start the next stage. This removes the copy-paste-after-clear your session / start a fresh session chore that makes long, multi-stage runs painful (especially on mobile).
|
|
90
90
|
|
|
91
|
-
**1. Read the next step.** From the `rank-features --json` output (above), find this feature's row and read its `nextStage`, `nextCommand`, `verifyPending`, `verifyCommand`, `verifyStage`, `verifyState`, `autoVerify`, and `
|
|
91
|
+
**1. Read the next step.** From the `rank-features --json` output (above), find this feature's row and read its `nextStage`, `nextCommand`, `verifyPending`, `verifyCommand`, `verifyStage`, `verifyState`, `autoVerify`, `autoFix`, and `verifyGate` (the resolved gate: `none` → no verify action; `auto` → the §2b catch-up; `standard` → the §3 gate). If the feature is not in the `active` list (paused/abandoned), or `nextStage` is `null` (every production stage complete), skip the drive prompt — instead congratulate the user and, if `forge-6-docs` has not run, offer it; otherwise note the pipeline is complete. If the payload has a non-empty `invalidAutoVerifyKeys`, print a one-line warning first (e.g. "⚠️ forge.config.json `autoVerifyStages` has unknown keys: … — they are ignored; fix the typo").
|
|
92
92
|
|
|
93
93
|
**2. Check the context window.** Run the context-usage helper so you can advise whether to continue here or start the next stage in a fresh session:
|
|
94
94
|
```bash
|
|
95
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
95
|
+
R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
96
96
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
97
97
|
python3 "$R/scripts/forge-session.py" context-usage --json
|
|
98
98
|
```
|
|
@@ -109,7 +109,7 @@ python3 "$R/scripts/forge-session.py" context-usage --json
|
|
|
109
109
|
- **`autoFix` is false (default), or preconditions failed** → present a **compact findings digest** as text, then the host's question mechanism: *Apply fixes now (forge-fix)* / *Review findings* / *Skip & advance*.
|
|
110
110
|
- **`autoVerify` is false/unconfigured** → do not auto-run; use the advance gate in step 3, which gains the folded opt-in verify options ("Verify `{stage}` now" and "Verify `{stage}` now + enable auto-verify going forward").
|
|
111
111
|
|
|
112
|
-
**3. Offer the next step via the host's question mechanism.** (Reached when auto-verify did not fully resolve the step, or `verifyPending` is false.) Output the dashboard + a one-line context note as text, then ask (per the Decision Support protocol in `references/shared-conventions.md`). This is the same **Stage Exit Protocol** the stage skills stamp (`references/stage-exit-protocol.md`) — a clean session at the boundary is recommended on its own merits, and `overThreshold` only modulates *how emphatically*, never *whether*. Options, in this order:
|
|
112
|
+
**3. Offer the next step via the host's question mechanism.** (Reached when auto-verify did not fully resolve the step, or `verifyPending` is false.) Output the dashboard + a one-line context note as text, then ask (per the Decision Support protocol in `references/shared-conventions.md`). **Present this gate exactly once and act only on the option the user chooses — never also narrate the not-taken branch.** Concretely: do not print the "start in a clean session" recommendation as prose and *then* auto-invoke the next stage in the same session (or the reverse) — the host's question mechanism answer is the single decision, and only the chosen path's action follows. This is the same **Stage Exit Protocol** the stage skills stamp (`references/stage-exit-protocol.md`) — a clean session at the boundary is recommended on its own merits, and `overThreshold` only modulates *how emphatically*, never *whether*. Options, in this order:
|
|
113
113
|
- **Start `{nextStage}` in a clean session** — **recommended, unconditionally**, at every boundary. A clean session is the right default for the next stage on its own merits, independent of window size. The work survives a clear because all state is on disk: instruct the user to clear your session / start a fresh session, then re-run `/feature-forge:forge {feature}` (or run `{nextCommand}` directly) in the fresh session. Note plainly that you cannot clear your session / start a fresh session for them. **When `overThreshold` is true**, strengthen this wording (the window is also genuinely full) and add mid-stage compaction advice; **when the window is healthy**, still recommend the clean session — `overThreshold` is a *secondary, additive* modifier here, not the clear on/off switch.
|
|
114
114
|
- **Continue in this session** — the always-available alternative, reasonable when the window is nearly empty and the user would rather not clear. Not the default.
|
|
115
115
|
- **Verify `{stage}` now** — include **only when `verifyPending` is true and `autoVerify` is false**, and the clean-room path is available. **Recommended**, since verify is clean-room and rarely worth skipping. Runs verify now (require-clean mode); **does not** change config.
|
|
@@ -132,7 +132,7 @@ This applies whether the feature was named explicitly (`/feature-forge:forge {fe
|
|
|
132
132
|
When the named argument is an epic (`{specsDir}/{name}/epic-manifest.json` exists), render the epic dashboard instead of a per-feature one. Run:
|
|
133
133
|
|
|
134
134
|
```bash
|
|
135
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
135
|
+
R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
136
136
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
137
137
|
python3 "$R/scripts/epic-manifest.py" render-status "{epic}" --specs-dir "{specsDir}" --json
|
|
138
138
|
```
|
|
@@ -203,7 +203,7 @@ Support these sub-commands for pipeline lifecycle management:
|
|
|
203
203
|
|
|
204
204
|
- Set the manifest's top-level `status` (`paused` / `active` / `abandoned`) via the helper's `set-status` mutator — an atomic write that also bumps `updatedAt`:
|
|
205
205
|
```bash
|
|
206
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
206
|
+
R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
207
207
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
208
208
|
python3 "$R/scripts/epic-manifest.py" set-status "{epic}" --status paused --specs-dir "{specsDir}"
|
|
209
209
|
```
|
|
@@ -38,7 +38,7 @@ checks but still load any on-disk artifacts.
|
|
|
38
38
|
plugin path and the configured specs dir:
|
|
39
39
|
|
|
40
40
|
```bash
|
|
41
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
41
|
+
R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
42
42
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
43
43
|
python3 "$R/scripts/epic-manifest.py" <subcommand> ... --specs-dir "{specsDir}"
|
|
44
44
|
```
|
|
@@ -72,7 +72,7 @@ Resolve the epic subtree path `{specsDir}/{epic}/` and decide which branch to ru
|
|
|
72
72
|
epic, confirm the epic name itself does not collide with any existing feature or epic:
|
|
73
73
|
|
|
74
74
|
```bash
|
|
75
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
75
|
+
R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
76
76
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
77
77
|
python3 "$R/scripts/epic-manifest.py" check-name "{epic}" --specs-dir "{specsDir}"
|
|
78
78
|
```
|
|
@@ -116,7 +116,7 @@ For **each** proposed feature name, before accepting it into the set, enforce gl
|
|
|
116
116
|
and name safety via the helper:
|
|
117
117
|
|
|
118
118
|
```bash
|
|
119
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
119
|
+
R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
120
120
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
121
121
|
python3 "$R/scripts/epic-manifest.py" check-name "{feature}" --specs-dir "{specsDir}"
|
|
122
122
|
```
|
|
@@ -176,7 +176,7 @@ For the *initial* creation write the skill writes the file directly — atomic g
|
|
|
176
176
|
required for in-place mutation, which is the helper mutators' job. Creating the epic dir first creates `{specsDir}/`, so after writing the manifest invoke the **Specs Directory Hygiene** block in `references/shared-conventions.md` (idempotent; stage anything it writes with this stage's commit). Then validate:
|
|
177
177
|
|
|
178
178
|
```bash
|
|
179
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
179
|
+
R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
180
180
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
181
181
|
python3 "$R/scripts/epic-manifest.py" validate "{epic}" --specs-dir "{specsDir}" --json
|
|
182
182
|
```
|
|
@@ -248,7 +248,7 @@ now self-contained: manifest + EPIC.md + one subdirectory per member.
|
|
|
248
248
|
**Close this stage with the Scripted Stage Exit** (contract: `references/stage-exit-protocol.md`; do not improvise a "Next steps" list). Run:
|
|
249
249
|
|
|
250
250
|
```bash
|
|
251
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
251
|
+
R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
252
252
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
253
253
|
python3 "$R/scripts/forge-session.py" stage-exit --feature "{epic}" --stage forge-0-epic --next-feature "{first-actionable-feature}" --specs-dir "{specsDir}" --host generic
|
|
254
254
|
```
|
|
@@ -16,7 +16,7 @@ question goes through `AskUserQuestion`.
|
|
|
16
16
|
Before offering any edit, validate the existing manifest:
|
|
17
17
|
|
|
18
18
|
```bash
|
|
19
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
19
|
+
R="$(bash -c 'for d in "${CLAUDE_PLUGIN_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
20
20
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
21
21
|
python3 "$R/scripts/epic-manifest.py" validate "{epic}" --specs-dir "{specsDir}" --json
|
|
22
22
|
```
|
|
@@ -77,7 +77,7 @@ status is **not** `not-started`, warn the user. Read the **live** status (never
|
|
|
77
77
|
completion in prose):
|
|
78
78
|
|
|
79
79
|
```bash
|
|
80
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
80
|
+
R="$(bash -c 'for d in "${CLAUDE_PLUGIN_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
81
81
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
82
82
|
python3 "$R/scripts/epic-manifest.py" render-status "{epic}" --specs-dir "{specsDir}" --json
|
|
83
83
|
```
|
|
@@ -12,7 +12,7 @@ the write if it would introduce a cycle, dangling ref, duplicate, or schema viol
|
|
|
12
12
|
flag surface (owned by 02 §7):
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
15
|
+
R="$(bash -c 'for d in "${CLAUDE_PLUGIN_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
16
16
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
17
17
|
# Add a feature — seeds EMPTY exposes/consumes; contracts are populated below.
|
|
18
18
|
python3 "$R/scripts/epic-manifest.py" add-feature "{epic}" "{feature}" \
|
|
@@ -116,7 +116,7 @@ Write pipeline state conforming to `references/pipeline-state-schema.json`.
|
|
|
116
116
|
**Close this stage with the Scripted Stage Exit** (contract: `references/stage-exit-protocol.md`; do not improvise a "Next steps" list). Run:
|
|
117
117
|
|
|
118
118
|
```bash
|
|
119
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
119
|
+
R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
120
120
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
121
121
|
python3 "$R/scripts/forge-session.py" stage-exit --feature "{feature}" --stage forge-1-prd --specs-dir "{specsDir}" --host generic
|
|
122
122
|
```
|
|
@@ -193,7 +193,7 @@ Write pipeline state conforming to `references/pipeline-state-schema.json`.
|
|
|
193
193
|
**Close this stage with the Scripted Stage Exit** (contract: `references/stage-exit-protocol.md`; do not improvise a "Next steps" list). Run:
|
|
194
194
|
|
|
195
195
|
```bash
|
|
196
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
196
|
+
R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
197
197
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
198
198
|
python3 "$R/scripts/forge-session.py" stage-exit --feature "{feature}" --stage forge-2-tech --specs-dir "{specsDir}" --host generic
|
|
199
199
|
```
|
|
@@ -147,7 +147,7 @@ Write pipeline state conforming to `references/pipeline-state-schema.json`.
|
|
|
147
147
|
**Close this stage with the Scripted Stage Exit** (contract: `references/stage-exit-protocol.md`; do not improvise a "Next steps" list). Run:
|
|
148
148
|
|
|
149
149
|
```bash
|
|
150
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
150
|
+
R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
151
151
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
152
152
|
python3 "$R/scripts/forge-session.py" stage-exit --feature "{feature}" --stage forge-3-specs --specs-dir "{specsDir}" --host generic
|
|
153
153
|
```
|
|
@@ -141,7 +141,7 @@ Write pipeline state conforming to `references/pipeline-state-schema.json`. Foll
|
|
|
141
141
|
**Close this stage with the Scripted Stage Exit** (contract: `references/stage-exit-protocol.md`; do not improvise a "Next steps" list). Run:
|
|
142
142
|
|
|
143
143
|
```bash
|
|
144
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
144
|
+
R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
145
145
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
146
146
|
python3 "$R/scripts/forge-session.py" stage-exit --feature "{feature}" --stage forge-4-backlog --specs-dir "{specsDir}" --host generic
|
|
147
147
|
```
|
|
@@ -60,7 +60,7 @@ Read the resolved feature's `.pipeline-state.json`. **If it has no `epic` key, s
|
|
|
60
60
|
1. Run `render-status "{epic}" --specs-dir "{specsDir}" --json` via the helper:
|
|
61
61
|
|
|
62
62
|
```bash
|
|
63
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
63
|
+
R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
64
64
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
65
65
|
python3 "$R/scripts/epic-manifest.py" \
|
|
66
66
|
render-status "{epic}" --specs-dir "{specsDir}" --json
|
|
@@ -113,7 +113,7 @@ Verify the file exists on disk. If not, STOP and tell the user: "No backlog.json
|
|
|
113
113
|
|
|
114
114
|
### 1f. Branch Pre-flight (if using git)
|
|
115
115
|
|
|
116
|
-
The runner commits each
|
|
116
|
+
The runner commits each item onto the current branch. Skip if not a git repo or `branchPerFeature` is false. Otherwise run the **Branch Reconciliation** block in `references/shared-conventions.md` (it runs `reconcile-branch` and, on `warn-drift` — you are on the default branch — strongly recommends creating `{branchPrefix}{feature}` via the host's question mechanism before the loop commits; on `adopt-current` it updates the recorded branch to the current one, never pushing you back to a stale/imposed branch). Never hard-stop.
|
|
117
117
|
|
|
118
118
|
## Step 2: Construct the Loop Command
|
|
119
119
|
|
|
@@ -43,7 +43,7 @@ Check `.pipeline-state.json` for `stages.forge-verify-impl`. If it is **absent**
|
|
|
43
43
|
If the resolved feature has an `epic` back-pointer in its `.pipeline-state.json`, run:
|
|
44
44
|
|
|
45
45
|
```bash
|
|
46
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
46
|
+
R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
47
47
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
48
48
|
python3 "$R/scripts/epic-manifest.py" render-status "{epic}" --specs-dir "{specsDir}" --json
|
|
49
49
|
```
|
|
@@ -58,7 +58,7 @@ Every bash invocation begins with the byte-identical portable-root prelude, then
|
|
|
58
58
|
helper. Pass `--specs-dir ./specs` (the default) so the gate allow-lists the specs directory.
|
|
59
59
|
|
|
60
60
|
```bash
|
|
61
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
61
|
+
R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
62
62
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
63
63
|
python3 "$R/scripts/forge-bootstrap.py" check "<target-dir>" --json --specs-dir ./specs
|
|
64
64
|
```
|
|
@@ -135,7 +135,7 @@ when running under a Claude host (e.g. the host's question mechanism is availabl
|
|
|
135
135
|
`CLAUDE.md` only when `host == "claude"`.
|
|
136
136
|
|
|
137
137
|
```bash
|
|
138
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
138
|
+
R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
139
139
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
140
140
|
python3 "$R/scripts/forge-bootstrap.py" scaffold "<target-dir>" --json --answers '<Answers JSON>'
|
|
141
141
|
```
|
|
@@ -143,7 +143,7 @@ python3 "$R/scripts/forge-bootstrap.py" scaffold "<target-dir>" --json --answers
|
|
|
143
143
|
### Step 5 — verify
|
|
144
144
|
|
|
145
145
|
```bash
|
|
146
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
146
|
+
R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
147
147
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
148
148
|
python3 "$R/scripts/forge-bootstrap.py" verify "<target-dir>" --json --answers '<Answers JSON>'
|
|
149
149
|
```
|
|
@@ -169,7 +169,7 @@ and removes the sentinel before staging so it never enters history. Read
|
|
|
169
169
|
leave the sentinel in-progress (resumable) — do **not** declare success.
|
|
170
170
|
|
|
171
171
|
```bash
|
|
172
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
172
|
+
R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
173
173
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
174
174
|
python3 "$R/scripts/forge-bootstrap.py" commit "<target-dir>" --json --answers '<Answers JSON>' [--stage-only]
|
|
175
175
|
```
|
|
@@ -9,7 +9,7 @@ description: Initialize feature-forge configuration in the current project. Use
|
|
|
9
9
|
Run the initialization script to create `forge.config.json` with default settings:
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
12
|
+
R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
13
13
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
14
14
|
bash "$R/scripts/forge-init.sh"
|
|
15
15
|
```
|
|
@@ -8,7 +8,14 @@ description: Verify forge pipeline artifacts for completeness, consistency, and
|
|
|
8
8
|
|
|
9
9
|
Analyze feature artifacts for completeness, consistency, and quality. Produce structured, actionable findings designed for a fresh-context agent to apply.
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Which role are you? (read this first)
|
|
12
|
+
|
|
13
|
+
This skill is loaded in two different roles. Determine yours before proceeding:
|
|
14
|
+
|
|
15
|
+
- **You ARE the `forge-verifier` subagent** — you were dispatched via the host's subagent mechanism, you have read-only tools (Read, Glob, Grep, Bash) and **no** Agent/host's subagent mechanism, and this skill is pre-loaded in your context. **SKIP "Subagent Delegation (parent orchestrator only)" and "Synthesize" below — those describe how a *parent* dispatches *you*, not work for you to do.** Do **not** dispatch anything, do **not** try to spawn a verifier. Go straight to **Prerequisites → Steps 1–6**, execute the checks yourself, and **return your findings as your response** (the parent writes the document to disk). Dispatching a subagent from here is the classic self-referential loop — never do it.
|
|
16
|
+
- **You are the parent orchestrator** — a navigator (`/feature-forge:forge`), a stage skill's in-stage auto-verify, or a direct `/feature-forge:forge-verify` invocation, and you have the host's subagent mechanism. Use "Subagent Delegation" to dispatch the `forge-verifier` subagent, then "Synthesize" to assemble and write the document.
|
|
17
|
+
|
|
18
|
+
## Subagent Delegation (parent orchestrator only)
|
|
12
19
|
|
|
13
20
|
This skill is delegated to the `forge-verifier` subagent via the host's subagent mechanism. The verifier subagent has:
|
|
14
21
|
- **Read-only tools** (Read, Glob, Grep, Bash) — it cannot accidentally modify specs
|
|
@@ -248,7 +255,7 @@ Do NOT mark as `findings-applied` — that happens after the fix pass.
|
|
|
248
255
|
- For specs verification, also run the deterministic traceability validator to supplement agent-driven traceability checks. Include any uncovered requirements or orphaned references as findings:
|
|
249
256
|
|
|
250
257
|
```bash
|
|
251
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
258
|
+
R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
252
259
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
253
260
|
python3 "$R/scripts/validate-traceability.py" {resolvedFeatureDir}/PRD.md {resolvedFeatureDir}/ --json
|
|
254
261
|
```
|
|
@@ -192,7 +192,7 @@ findings to E01/E02/E03/E08. Then perform the judgment checks E04–E07 by readi
|
|
|
192
192
|
manifest, EPIC.md, and completed members' specs.
|
|
193
193
|
|
|
194
194
|
```bash
|
|
195
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
195
|
+
R="$(bash -c 'for d in "${CLAUDE_PLUGIN_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
196
196
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
197
197
|
python3 "$R/scripts/epic-manifest.py" validate "{epic}" --specs-dir "{specsDir}" --json
|
|
198
198
|
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@garygentry/feature-forge",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.7",
|
|
4
4
|
"description": "Cross-agent installer for the feature-forge skill suite — installs the canonical forge pipeline into Claude, Codex, Copilot, Cursor, or Gemini.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|