@garygentry/feature-forge 0.2.14 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -3
- package/adapters/GENERATION-REPORT.md +20 -0
- package/adapters/claude/.feature-forge-bundle.json +1 -1
- package/adapters/claude/agents/forge-verifier.md +1 -1
- package/adapters/claude/references/forge-config-schema.json +2 -2
- package/adapters/claude/references/pipeline-state-schema.json +1 -1
- package/adapters/claude/references/shared-conventions.md +62 -12
- package/adapters/claude/references/stage-exit-protocol.md +14 -4
- package/adapters/claude/references/vendor-construct-inventory.md +1 -1
- package/adapters/claude/scripts/epic-manifest.py +49 -6
- package/adapters/claude/scripts/forge-root.sh +47 -3
- package/adapters/claude/scripts/forge-session.py +1179 -9
- package/adapters/claude/scripts/validate-traceability.py +6 -1
- package/adapters/claude/skills/forge/SKILL.md +11 -5
- package/adapters/claude/skills/forge/references/pipeline-state-schema.json +1 -1
- package/adapters/claude/skills/forge/references/shared-conventions.md +62 -12
- package/adapters/claude/skills/forge/references/stage-exit-protocol.md +14 -4
- package/adapters/claude/skills/forge-0-epic/SKILL.md +1 -1
- package/adapters/claude/skills/forge-0-epic/references/pipeline-state-schema.json +1 -1
- package/adapters/claude/skills/forge-0-epic/references/shared-conventions.md +62 -12
- package/adapters/claude/skills/forge-0-epic/references/stage-exit-protocol.md +14 -4
- package/adapters/claude/skills/forge-1-prd/SKILL.md +25 -8
- package/adapters/claude/skills/forge-1-prd/references/shared-conventions.md +62 -12
- package/adapters/claude/skills/forge-1-prd/references/stage-exit-protocol.md +14 -4
- package/adapters/claude/skills/forge-2-tech/SKILL.md +25 -7
- package/adapters/claude/skills/forge-2-tech/references/shared-conventions.md +62 -12
- package/adapters/claude/skills/forge-2-tech/references/stage-exit-protocol.md +14 -4
- package/adapters/claude/skills/forge-3-specs/SKILL.md +24 -7
- package/adapters/claude/skills/forge-3-specs/references/shared-conventions.md +62 -12
- package/adapters/claude/skills/forge-3-specs/references/stage-exit-protocol.md +14 -4
- package/adapters/claude/skills/forge-4-backlog/SKILL.md +23 -7
- package/adapters/claude/skills/forge-4-backlog/references/shared-conventions.md +62 -12
- package/adapters/claude/skills/forge-4-backlog/references/stage-exit-protocol.md +14 -4
- package/adapters/claude/skills/forge-5-loop/SKILL.md +25 -25
- package/adapters/claude/skills/forge-5-loop/references/agent-selection.md +116 -0
- package/adapters/claude/skills/forge-5-loop/references/runner-contract.md +14 -107
- package/adapters/claude/skills/forge-5-loop/references/shared-conventions.md +62 -12
- package/adapters/claude/skills/forge-5-loop/references/stage-exit-protocol.md +14 -4
- package/adapters/claude/skills/forge-6-docs/SKILL.md +11 -5
- package/adapters/claude/skills/forge-6-docs/references/shared-conventions.md +62 -12
- package/adapters/claude/skills/forge-fix/references/shared-conventions.md +62 -12
- package/adapters/claude/skills/forge-fix/references/stage-exit-protocol.md +14 -4
- package/adapters/claude/skills/forge-guide/references/forge-config-schema.json +2 -2
- package/adapters/claude/skills/forge-guide/references/shared-conventions.md +62 -12
- package/adapters/claude/skills/forge-verify/SKILL.md +22 -12
- package/adapters/claude/skills/forge-verify/references/findings-template.md +157 -0
- package/adapters/claude/skills/forge-verify/references/pipeline-state-schema.json +1 -1
- package/adapters/claude/skills/forge-verify/references/shared-conventions.md +62 -12
- package/adapters/claude/skills/forge-verify/references/verification-checklists/backlog.md +97 -0
- package/adapters/claude/skills/forge-verify/references/verification-checklists/epic.md +79 -0
- package/adapters/claude/skills/forge-verify/references/verification-checklists/impl.md +48 -0
- package/adapters/claude/skills/forge-verify/references/verification-checklists/prd.md +31 -0
- package/adapters/claude/skills/forge-verify/references/verification-checklists/specs.md +64 -0
- package/adapters/claude/skills/forge-verify/references/verification-checklists/tech.md +35 -0
- package/adapters/codex/.feature-forge-bundle.json +1 -1
- package/adapters/codex/agents/forge-verifier.toml +1 -1
- package/adapters/codex/references/forge-config-schema.json +2 -2
- package/adapters/codex/references/pipeline-state-schema.json +1 -1
- package/adapters/codex/references/shared-conventions.md +62 -12
- package/adapters/codex/references/stage-exit-protocol.md +14 -4
- package/adapters/codex/references/vendor-construct-inventory.md +1 -1
- package/adapters/codex/scripts/epic-manifest.py +49 -6
- package/adapters/codex/scripts/forge-root.sh +47 -3
- package/adapters/codex/scripts/forge-session.py +1179 -9
- package/adapters/codex/scripts/validate-traceability.py +6 -1
- package/adapters/codex/skills/forge/SKILL.md +11 -5
- package/adapters/codex/skills/forge/references/pipeline-state-schema.json +1 -1
- package/adapters/codex/skills/forge/references/shared-conventions.md +62 -12
- package/adapters/codex/skills/forge/references/stage-exit-protocol.md +14 -4
- package/adapters/codex/skills/forge-0-epic/SKILL.md +1 -1
- package/adapters/codex/skills/forge-0-epic/references/pipeline-state-schema.json +1 -1
- package/adapters/codex/skills/forge-0-epic/references/shared-conventions.md +62 -12
- package/adapters/codex/skills/forge-0-epic/references/stage-exit-protocol.md +14 -4
- package/adapters/codex/skills/forge-1-prd/SKILL.md +25 -8
- package/adapters/codex/skills/forge-1-prd/references/shared-conventions.md +62 -12
- package/adapters/codex/skills/forge-1-prd/references/stage-exit-protocol.md +14 -4
- package/adapters/codex/skills/forge-2-tech/SKILL.md +25 -7
- package/adapters/codex/skills/forge-2-tech/references/shared-conventions.md +62 -12
- package/adapters/codex/skills/forge-2-tech/references/stage-exit-protocol.md +14 -4
- package/adapters/codex/skills/forge-3-specs/SKILL.md +24 -7
- package/adapters/codex/skills/forge-3-specs/references/shared-conventions.md +62 -12
- package/adapters/codex/skills/forge-3-specs/references/stage-exit-protocol.md +14 -4
- package/adapters/codex/skills/forge-4-backlog/SKILL.md +23 -7
- package/adapters/codex/skills/forge-4-backlog/references/shared-conventions.md +62 -12
- package/adapters/codex/skills/forge-4-backlog/references/stage-exit-protocol.md +14 -4
- package/adapters/codex/skills/forge-5-loop/SKILL.md +25 -25
- package/adapters/codex/skills/forge-5-loop/references/agent-selection.md +116 -0
- package/adapters/codex/skills/forge-5-loop/references/runner-contract.md +14 -107
- package/adapters/codex/skills/forge-5-loop/references/shared-conventions.md +62 -12
- package/adapters/codex/skills/forge-5-loop/references/stage-exit-protocol.md +14 -4
- package/adapters/codex/skills/forge-6-docs/SKILL.md +11 -5
- package/adapters/codex/skills/forge-6-docs/references/shared-conventions.md +62 -12
- package/adapters/codex/skills/forge-fix/references/shared-conventions.md +62 -12
- package/adapters/codex/skills/forge-fix/references/stage-exit-protocol.md +14 -4
- package/adapters/codex/skills/forge-guide/references/forge-config-schema.json +2 -2
- package/adapters/codex/skills/forge-guide/references/shared-conventions.md +62 -12
- package/adapters/codex/skills/forge-verify/SKILL.md +22 -12
- package/adapters/codex/skills/forge-verify/references/findings-template.md +157 -0
- package/adapters/codex/skills/forge-verify/references/pipeline-state-schema.json +1 -1
- package/adapters/codex/skills/forge-verify/references/shared-conventions.md +62 -12
- package/adapters/codex/skills/forge-verify/references/verification-checklists/backlog.md +97 -0
- package/adapters/codex/skills/forge-verify/references/verification-checklists/epic.md +79 -0
- package/adapters/codex/skills/forge-verify/references/verification-checklists/impl.md +48 -0
- package/adapters/codex/skills/forge-verify/references/verification-checklists/prd.md +31 -0
- package/adapters/codex/skills/forge-verify/references/verification-checklists/specs.md +64 -0
- package/adapters/codex/skills/forge-verify/references/verification-checklists/tech.md +35 -0
- package/adapters/copilot/.feature-forge-bundle.json +1 -1
- package/adapters/copilot/agents/forge-verifier.md +1 -1
- package/adapters/copilot/references/forge-config-schema.json +2 -2
- package/adapters/copilot/references/pipeline-state-schema.json +1 -1
- package/adapters/copilot/references/shared-conventions.md +62 -12
- package/adapters/copilot/references/stage-exit-protocol.md +14 -4
- package/adapters/copilot/references/vendor-construct-inventory.md +1 -1
- package/adapters/copilot/scripts/epic-manifest.py +49 -6
- package/adapters/copilot/scripts/forge-root.sh +47 -3
- package/adapters/copilot/scripts/forge-session.py +1179 -9
- package/adapters/copilot/scripts/validate-traceability.py +6 -1
- package/adapters/copilot/skills/forge/forge.md +11 -5
- package/adapters/copilot/skills/forge/references/pipeline-state-schema.json +1 -1
- package/adapters/copilot/skills/forge/references/shared-conventions.md +62 -12
- package/adapters/copilot/skills/forge/references/stage-exit-protocol.md +14 -4
- package/adapters/copilot/skills/forge-0-epic/forge-0-epic.md +1 -1
- package/adapters/copilot/skills/forge-0-epic/references/pipeline-state-schema.json +1 -1
- package/adapters/copilot/skills/forge-0-epic/references/shared-conventions.md +62 -12
- package/adapters/copilot/skills/forge-0-epic/references/stage-exit-protocol.md +14 -4
- package/adapters/copilot/skills/forge-1-prd/forge-1-prd.md +25 -8
- package/adapters/copilot/skills/forge-1-prd/references/shared-conventions.md +62 -12
- package/adapters/copilot/skills/forge-1-prd/references/stage-exit-protocol.md +14 -4
- package/adapters/copilot/skills/forge-2-tech/forge-2-tech.md +25 -7
- package/adapters/copilot/skills/forge-2-tech/references/shared-conventions.md +62 -12
- package/adapters/copilot/skills/forge-2-tech/references/stage-exit-protocol.md +14 -4
- package/adapters/copilot/skills/forge-3-specs/forge-3-specs.md +24 -7
- package/adapters/copilot/skills/forge-3-specs/references/shared-conventions.md +62 -12
- package/adapters/copilot/skills/forge-3-specs/references/stage-exit-protocol.md +14 -4
- package/adapters/copilot/skills/forge-4-backlog/forge-4-backlog.md +23 -7
- package/adapters/copilot/skills/forge-4-backlog/references/shared-conventions.md +62 -12
- package/adapters/copilot/skills/forge-4-backlog/references/stage-exit-protocol.md +14 -4
- package/adapters/copilot/skills/forge-5-loop/forge-5-loop.md +25 -25
- package/adapters/copilot/skills/forge-5-loop/references/agent-selection.md +116 -0
- package/adapters/copilot/skills/forge-5-loop/references/runner-contract.md +14 -107
- package/adapters/copilot/skills/forge-5-loop/references/shared-conventions.md +62 -12
- package/adapters/copilot/skills/forge-5-loop/references/stage-exit-protocol.md +14 -4
- package/adapters/copilot/skills/forge-6-docs/forge-6-docs.md +11 -5
- package/adapters/copilot/skills/forge-6-docs/references/shared-conventions.md +62 -12
- package/adapters/copilot/skills/forge-fix/references/shared-conventions.md +62 -12
- package/adapters/copilot/skills/forge-fix/references/stage-exit-protocol.md +14 -4
- package/adapters/copilot/skills/forge-guide/references/forge-config-schema.json +2 -2
- package/adapters/copilot/skills/forge-guide/references/shared-conventions.md +62 -12
- package/adapters/copilot/skills/forge-verify/forge-verify.md +22 -12
- package/adapters/copilot/skills/forge-verify/references/findings-template.md +157 -0
- package/adapters/copilot/skills/forge-verify/references/pipeline-state-schema.json +1 -1
- package/adapters/copilot/skills/forge-verify/references/shared-conventions.md +62 -12
- package/adapters/copilot/skills/forge-verify/references/verification-checklists/backlog.md +97 -0
- package/adapters/copilot/skills/forge-verify/references/verification-checklists/epic.md +79 -0
- package/adapters/copilot/skills/forge-verify/references/verification-checklists/impl.md +48 -0
- package/adapters/copilot/skills/forge-verify/references/verification-checklists/prd.md +31 -0
- package/adapters/copilot/skills/forge-verify/references/verification-checklists/specs.md +64 -0
- package/adapters/copilot/skills/forge-verify/references/verification-checklists/tech.md +35 -0
- package/adapters/cursor/.feature-forge-bundle.json +1 -1
- package/adapters/cursor/agents/forge-verifier.mdc +1 -1
- package/adapters/cursor/references/forge-config-schema.json +2 -2
- package/adapters/cursor/references/pipeline-state-schema.json +1 -1
- package/adapters/cursor/references/shared-conventions.md +62 -12
- package/adapters/cursor/references/stage-exit-protocol.md +14 -4
- package/adapters/cursor/references/vendor-construct-inventory.md +1 -1
- package/adapters/cursor/scripts/epic-manifest.py +49 -6
- package/adapters/cursor/scripts/forge-root.sh +47 -3
- package/adapters/cursor/scripts/forge-session.py +1179 -9
- package/adapters/cursor/scripts/validate-traceability.py +6 -1
- package/adapters/cursor/skills/forge/forge.mdc +11 -5
- package/adapters/cursor/skills/forge/references/pipeline-state-schema.json +1 -1
- package/adapters/cursor/skills/forge/references/shared-conventions.md +62 -12
- package/adapters/cursor/skills/forge/references/stage-exit-protocol.md +14 -4
- package/adapters/cursor/skills/forge-0-epic/forge-0-epic.mdc +1 -1
- package/adapters/cursor/skills/forge-0-epic/references/pipeline-state-schema.json +1 -1
- package/adapters/cursor/skills/forge-0-epic/references/shared-conventions.md +62 -12
- package/adapters/cursor/skills/forge-0-epic/references/stage-exit-protocol.md +14 -4
- package/adapters/cursor/skills/forge-1-prd/forge-1-prd.mdc +25 -8
- package/adapters/cursor/skills/forge-1-prd/references/shared-conventions.md +62 -12
- package/adapters/cursor/skills/forge-1-prd/references/stage-exit-protocol.md +14 -4
- package/adapters/cursor/skills/forge-2-tech/forge-2-tech.mdc +25 -7
- package/adapters/cursor/skills/forge-2-tech/references/shared-conventions.md +62 -12
- package/adapters/cursor/skills/forge-2-tech/references/stage-exit-protocol.md +14 -4
- package/adapters/cursor/skills/forge-3-specs/forge-3-specs.mdc +24 -7
- package/adapters/cursor/skills/forge-3-specs/references/shared-conventions.md +62 -12
- package/adapters/cursor/skills/forge-3-specs/references/stage-exit-protocol.md +14 -4
- package/adapters/cursor/skills/forge-4-backlog/forge-4-backlog.mdc +23 -7
- package/adapters/cursor/skills/forge-4-backlog/references/shared-conventions.md +62 -12
- package/adapters/cursor/skills/forge-4-backlog/references/stage-exit-protocol.md +14 -4
- package/adapters/cursor/skills/forge-5-loop/forge-5-loop.mdc +25 -25
- package/adapters/cursor/skills/forge-5-loop/references/agent-selection.md +116 -0
- package/adapters/cursor/skills/forge-5-loop/references/runner-contract.md +14 -107
- package/adapters/cursor/skills/forge-5-loop/references/shared-conventions.md +62 -12
- package/adapters/cursor/skills/forge-5-loop/references/stage-exit-protocol.md +14 -4
- package/adapters/cursor/skills/forge-6-docs/forge-6-docs.mdc +11 -5
- package/adapters/cursor/skills/forge-6-docs/references/shared-conventions.md +62 -12
- package/adapters/cursor/skills/forge-fix/references/shared-conventions.md +62 -12
- package/adapters/cursor/skills/forge-fix/references/stage-exit-protocol.md +14 -4
- package/adapters/cursor/skills/forge-guide/references/forge-config-schema.json +2 -2
- package/adapters/cursor/skills/forge-guide/references/shared-conventions.md +62 -12
- package/adapters/cursor/skills/forge-verify/forge-verify.mdc +22 -12
- package/adapters/cursor/skills/forge-verify/references/findings-template.md +157 -0
- package/adapters/cursor/skills/forge-verify/references/pipeline-state-schema.json +1 -1
- package/adapters/cursor/skills/forge-verify/references/shared-conventions.md +62 -12
- package/adapters/cursor/skills/forge-verify/references/verification-checklists/backlog.md +97 -0
- package/adapters/cursor/skills/forge-verify/references/verification-checklists/epic.md +79 -0
- package/adapters/cursor/skills/forge-verify/references/verification-checklists/impl.md +48 -0
- package/adapters/cursor/skills/forge-verify/references/verification-checklists/prd.md +31 -0
- package/adapters/cursor/skills/forge-verify/references/verification-checklists/specs.md +64 -0
- package/adapters/cursor/skills/forge-verify/references/verification-checklists/tech.md +35 -0
- package/adapters/gemini/.feature-forge-bundle.json +1 -1
- package/adapters/gemini/agents/forge-verifier.md +1 -1
- package/adapters/gemini/gemini-extension.json +1 -1
- package/adapters/gemini/references/forge-config-schema.json +2 -2
- package/adapters/gemini/references/pipeline-state-schema.json +1 -1
- package/adapters/gemini/references/shared-conventions.md +62 -12
- package/adapters/gemini/references/stage-exit-protocol.md +14 -4
- package/adapters/gemini/references/vendor-construct-inventory.md +1 -1
- package/adapters/gemini/scripts/epic-manifest.py +49 -6
- package/adapters/gemini/scripts/forge-root.sh +47 -3
- package/adapters/gemini/scripts/forge-session.py +1179 -9
- package/adapters/gemini/scripts/validate-traceability.py +6 -1
- package/adapters/gemini/skills/forge/forge.md +11 -5
- package/adapters/gemini/skills/forge/references/pipeline-state-schema.json +1 -1
- package/adapters/gemini/skills/forge/references/shared-conventions.md +62 -12
- package/adapters/gemini/skills/forge/references/stage-exit-protocol.md +14 -4
- package/adapters/gemini/skills/forge-0-epic/forge-0-epic.md +1 -1
- package/adapters/gemini/skills/forge-0-epic/references/pipeline-state-schema.json +1 -1
- package/adapters/gemini/skills/forge-0-epic/references/shared-conventions.md +62 -12
- package/adapters/gemini/skills/forge-0-epic/references/stage-exit-protocol.md +14 -4
- package/adapters/gemini/skills/forge-1-prd/forge-1-prd.md +25 -8
- package/adapters/gemini/skills/forge-1-prd/references/shared-conventions.md +62 -12
- package/adapters/gemini/skills/forge-1-prd/references/stage-exit-protocol.md +14 -4
- package/adapters/gemini/skills/forge-2-tech/forge-2-tech.md +25 -7
- package/adapters/gemini/skills/forge-2-tech/references/shared-conventions.md +62 -12
- package/adapters/gemini/skills/forge-2-tech/references/stage-exit-protocol.md +14 -4
- package/adapters/gemini/skills/forge-3-specs/forge-3-specs.md +24 -7
- package/adapters/gemini/skills/forge-3-specs/references/shared-conventions.md +62 -12
- package/adapters/gemini/skills/forge-3-specs/references/stage-exit-protocol.md +14 -4
- package/adapters/gemini/skills/forge-4-backlog/forge-4-backlog.md +23 -7
- package/adapters/gemini/skills/forge-4-backlog/references/shared-conventions.md +62 -12
- package/adapters/gemini/skills/forge-4-backlog/references/stage-exit-protocol.md +14 -4
- package/adapters/gemini/skills/forge-5-loop/forge-5-loop.md +25 -25
- package/adapters/gemini/skills/forge-5-loop/references/agent-selection.md +116 -0
- package/adapters/gemini/skills/forge-5-loop/references/runner-contract.md +14 -107
- package/adapters/gemini/skills/forge-5-loop/references/shared-conventions.md +62 -12
- package/adapters/gemini/skills/forge-5-loop/references/stage-exit-protocol.md +14 -4
- package/adapters/gemini/skills/forge-6-docs/forge-6-docs.md +11 -5
- package/adapters/gemini/skills/forge-6-docs/references/shared-conventions.md +62 -12
- package/adapters/gemini/skills/forge-fix/references/shared-conventions.md +62 -12
- package/adapters/gemini/skills/forge-fix/references/stage-exit-protocol.md +14 -4
- package/adapters/gemini/skills/forge-guide/references/forge-config-schema.json +2 -2
- package/adapters/gemini/skills/forge-guide/references/shared-conventions.md +62 -12
- package/adapters/gemini/skills/forge-verify/forge-verify.md +22 -12
- package/adapters/gemini/skills/forge-verify/references/findings-template.md +157 -0
- package/adapters/gemini/skills/forge-verify/references/pipeline-state-schema.json +1 -1
- package/adapters/gemini/skills/forge-verify/references/shared-conventions.md +62 -12
- package/adapters/gemini/skills/forge-verify/references/verification-checklists/backlog.md +97 -0
- package/adapters/gemini/skills/forge-verify/references/verification-checklists/epic.md +79 -0
- package/adapters/gemini/skills/forge-verify/references/verification-checklists/impl.md +48 -0
- package/adapters/gemini/skills/forge-verify/references/verification-checklists/prd.md +31 -0
- package/adapters/gemini/skills/forge-verify/references/verification-checklists/specs.md +64 -0
- package/adapters/gemini/skills/forge-verify/references/verification-checklists/tech.md +35 -0
- package/adapters/pi/.feature-forge-bundle.json +6 -0
- package/adapters/pi/agents/forge-researcher.md +139 -0
- package/adapters/pi/agents/forge-spec-writer.md +116 -0
- package/adapters/pi/agents/forge-verifier.md +126 -0
- package/adapters/pi/extensions/ask-user-question/LICENSE +21 -0
- package/adapters/pi/extensions/ask-user-question/README.md +91 -0
- package/adapters/pi/extensions/ask-user-question/ask-user-question.ts +298 -0
- package/adapters/pi/extensions/ask-user-question/config.ts +78 -0
- package/adapters/pi/extensions/ask-user-question/events.ts +57 -0
- package/adapters/pi/extensions/ask-user-question/index.ts +61 -0
- package/adapters/pi/extensions/ask-user-question/locales/de.json +27 -0
- package/adapters/pi/extensions/ask-user-question/locales/en.json +27 -0
- package/adapters/pi/extensions/ask-user-question/locales/es.json +27 -0
- package/adapters/pi/extensions/ask-user-question/locales/fr.json +27 -0
- package/adapters/pi/extensions/ask-user-question/locales/pt-BR.json +27 -0
- package/adapters/pi/extensions/ask-user-question/locales/pt.json +27 -0
- package/adapters/pi/extensions/ask-user-question/locales/ru.json +27 -0
- package/adapters/pi/extensions/ask-user-question/locales/uk.json +27 -0
- package/adapters/pi/extensions/ask-user-question/locales/zh.json +29 -0
- package/adapters/pi/extensions/ask-user-question/reconcile.ts +49 -0
- package/adapters/pi/extensions/ask-user-question/rpc-fallback.ts +168 -0
- package/adapters/pi/extensions/ask-user-question/state/build-questionnaire.ts +302 -0
- package/adapters/pi/extensions/ask-user-question/state/i18n-bridge.ts +53 -0
- package/adapters/pi/extensions/ask-user-question/state/key-router.ts +277 -0
- package/adapters/pi/extensions/ask-user-question/state/questionnaire-session.ts +234 -0
- package/adapters/pi/extensions/ask-user-question/state/row-intent.ts +145 -0
- package/adapters/pi/extensions/ask-user-question/state/selectors/contract.ts +26 -0
- package/adapters/pi/extensions/ask-user-question/state/selectors/derivations.ts +42 -0
- package/adapters/pi/extensions/ask-user-question/state/selectors/focus.ts +19 -0
- package/adapters/pi/extensions/ask-user-question/state/selectors/projections.ts +101 -0
- package/adapters/pi/extensions/ask-user-question/state/state-reducer.ts +292 -0
- package/adapters/pi/extensions/ask-user-question/state/state.ts +55 -0
- package/adapters/pi/extensions/ask-user-question/tool/format-answer.ts +31 -0
- package/adapters/pi/extensions/ask-user-question/tool/response-envelope.ts +49 -0
- package/adapters/pi/extensions/ask-user-question/tool/types.ts +147 -0
- package/adapters/pi/extensions/ask-user-question/tool/validate-questionnaire.ts +58 -0
- package/adapters/pi/extensions/ask-user-question/vendor-config-shim.ts +65 -0
- package/adapters/pi/extensions/ask-user-question/view/component-binding.ts +47 -0
- package/adapters/pi/extensions/ask-user-question/view/components/inline-input.ts +98 -0
- package/adapters/pi/extensions/ask-user-question/view/components/multi-select-view.ts +193 -0
- package/adapters/pi/extensions/ask-user-question/view/components/option-list-view.ts +70 -0
- package/adapters/pi/extensions/ask-user-question/view/components/preview/markdown-content-cache.ts +79 -0
- package/adapters/pi/extensions/ask-user-question/view/components/preview/preview-block-renderer.ts +111 -0
- package/adapters/pi/extensions/ask-user-question/view/components/preview/preview-box-renderer.ts +88 -0
- package/adapters/pi/extensions/ask-user-question/view/components/preview/preview-layout-decider.ts +202 -0
- package/adapters/pi/extensions/ask-user-question/view/components/preview/preview-pane.ts +228 -0
- package/adapters/pi/extensions/ask-user-question/view/components/submit-picker.ts +67 -0
- package/adapters/pi/extensions/ask-user-question/view/components/tab-bar.ts +59 -0
- package/adapters/pi/extensions/ask-user-question/view/components/wrapping-select.ts +293 -0
- package/adapters/pi/extensions/ask-user-question/view/dialog-builder.ts +224 -0
- package/adapters/pi/extensions/ask-user-question/view/props-adapter.ts +125 -0
- package/adapters/pi/extensions/ask-user-question/view/stateful-view.ts +26 -0
- package/adapters/pi/extensions/ask-user-question/view/tab-components.ts +18 -0
- package/adapters/pi/extensions/ask-user-question/view/tab-content-strategy.ts +252 -0
- package/adapters/pi/package.json +26 -0
- package/adapters/pi/references/epic-manifest-schema.json +125 -0
- package/adapters/{claude/skills/forge-5-loop → pi}/references/forge-config-schema.json +4 -4
- package/adapters/{claude/skills/forge-1-prd → pi}/references/pipeline-state-schema.json +1 -1
- package/adapters/pi/references/portable-root.md +71 -0
- package/adapters/pi/references/process-overview.md +143 -0
- package/adapters/pi/references/ralph-loop-contract.md +221 -0
- package/adapters/pi/references/shared-conventions.md +345 -0
- package/adapters/pi/references/skill-frontmatter.schema.json +17 -0
- package/adapters/pi/references/stack-resolution.md +54 -0
- package/adapters/pi/references/stacks/_generic.md +111 -0
- package/adapters/pi/references/stacks/go.md +157 -0
- package/adapters/pi/references/stacks/python.md +184 -0
- package/adapters/pi/references/stacks/rust.md +170 -0
- package/adapters/pi/references/stacks/typescript.md +134 -0
- package/adapters/pi/references/stage-exit-protocol.md +268 -0
- package/adapters/pi/references/templates/specs-hygiene/AGENTS.md +32 -0
- package/adapters/pi/references/templates/specs-hygiene/CLAUDE.md +31 -0
- package/adapters/pi/references/vendor-construct-inventory.md +50 -0
- package/adapters/pi/scripts/epic-manifest.py +1737 -0
- package/adapters/pi/scripts/forge-bootstrap.py +1070 -0
- package/adapters/pi/scripts/forge-init.sh +58 -0
- package/adapters/pi/scripts/forge-root.sh +179 -0
- package/adapters/pi/scripts/forge-session.py +3036 -0
- package/adapters/pi/scripts/validate-traceability.py +155 -0
- package/adapters/pi/skills/forge/SKILL.md +249 -0
- package/adapters/{claude/skills/forge-4-backlog → pi/skills/forge}/references/pipeline-state-schema.json +1 -1
- package/adapters/pi/skills/forge/references/process-overview.md +143 -0
- package/adapters/pi/skills/forge/references/shared-conventions.md +345 -0
- package/adapters/pi/skills/forge/references/stage-exit-protocol.md +268 -0
- package/adapters/pi/skills/forge-0-epic/SKILL.md +308 -0
- package/adapters/pi/skills/forge-0-epic/references/edit-mode.md +266 -0
- package/adapters/pi/skills/forge-0-epic/references/epic-manifest-subcommands.md +75 -0
- package/adapters/{claude/skills/forge-2-tech → pi/skills/forge-0-epic}/references/pipeline-state-schema.json +1 -1
- package/adapters/pi/skills/forge-0-epic/references/portable-root.md +71 -0
- package/adapters/pi/skills/forge-0-epic/references/shared-conventions.md +345 -0
- package/adapters/pi/skills/forge-0-epic/references/stage-exit-protocol.md +268 -0
- package/adapters/pi/skills/forge-1-prd/SKILL.md +181 -0
- package/adapters/pi/skills/forge-1-prd/references/prd-template.md +106 -0
- package/adapters/pi/skills/forge-1-prd/references/shared-conventions.md +345 -0
- package/adapters/pi/skills/forge-1-prd/references/stage-exit-protocol.md +268 -0
- package/adapters/pi/skills/forge-2-tech/SKILL.md +243 -0
- package/adapters/pi/skills/forge-2-tech/references/shared-conventions.md +345 -0
- package/adapters/pi/skills/forge-2-tech/references/stack-discovery-checklist.md +95 -0
- package/adapters/pi/skills/forge-2-tech/references/stack-resolution.md +54 -0
- package/adapters/pi/skills/forge-2-tech/references/stacks/_generic.md +111 -0
- package/adapters/pi/skills/forge-2-tech/references/stacks/go.md +157 -0
- package/adapters/pi/skills/forge-2-tech/references/stacks/python.md +184 -0
- package/adapters/pi/skills/forge-2-tech/references/stacks/rust.md +170 -0
- package/adapters/pi/skills/forge-2-tech/references/stacks/typescript.md +134 -0
- package/adapters/pi/skills/forge-2-tech/references/stage-exit-protocol.md +268 -0
- package/adapters/pi/skills/forge-3-specs/SKILL.md +195 -0
- package/adapters/pi/skills/forge-3-specs/references/shared-conventions.md +345 -0
- package/adapters/pi/skills/forge-3-specs/references/spec-archetypes.md +106 -0
- package/adapters/pi/skills/forge-3-specs/references/spec-examples.md +71 -0
- package/adapters/pi/skills/forge-3-specs/references/stacks/_generic.md +111 -0
- package/adapters/pi/skills/forge-3-specs/references/stacks/go.md +157 -0
- package/adapters/pi/skills/forge-3-specs/references/stacks/python.md +184 -0
- package/adapters/pi/skills/forge-3-specs/references/stacks/rust.md +170 -0
- package/adapters/pi/skills/forge-3-specs/references/stacks/typescript.md +134 -0
- package/adapters/pi/skills/forge-3-specs/references/stage-exit-protocol.md +268 -0
- package/adapters/pi/skills/forge-4-backlog/SKILL.md +191 -0
- package/adapters/pi/skills/forge-4-backlog/references/shared-conventions.md +345 -0
- package/adapters/pi/skills/forge-4-backlog/references/stage-exit-protocol.md +268 -0
- package/adapters/pi/skills/forge-5-loop/SKILL.md +314 -0
- package/adapters/pi/skills/forge-5-loop/references/agent-selection.md +116 -0
- package/adapters/pi/skills/forge-5-loop/references/ralph-loop-contract.md +221 -0
- package/adapters/pi/skills/forge-5-loop/references/result-reporting.md +85 -0
- package/adapters/pi/skills/forge-5-loop/references/runner-contract.md +248 -0
- package/adapters/pi/skills/forge-5-loop/references/shared-conventions.md +345 -0
- package/adapters/pi/skills/forge-5-loop/references/stage-exit-protocol.md +268 -0
- package/adapters/pi/skills/forge-6-docs/SKILL.md +208 -0
- package/adapters/pi/skills/forge-6-docs/references/doc-conventions.md +126 -0
- package/adapters/pi/skills/forge-6-docs/references/shared-conventions.md +345 -0
- package/adapters/pi/skills/forge-bootstrap/SKILL.md +250 -0
- package/adapters/pi/skills/forge-bootstrap/references/templates/ci/github-actions.yml +12 -0
- package/adapters/pi/skills/forge-bootstrap/references/templates/generic/run.sh +3 -0
- package/adapters/pi/skills/forge-bootstrap/references/templates/generic/test.sh +13 -0
- package/adapters/pi/skills/forge-bootstrap/references/templates/go/go.mod +3 -0
- package/adapters/pi/skills/forge-bootstrap/references/templates/go/main.go +12 -0
- package/adapters/pi/skills/forge-bootstrap/references/templates/go/main_test.go +11 -0
- package/adapters/pi/skills/forge-bootstrap/references/templates/hygiene/AGENTS.md +35 -0
- package/adapters/pi/skills/forge-bootstrap/references/templates/hygiene/CLAUDE.md +36 -0
- package/adapters/pi/skills/forge-bootstrap/references/templates/hygiene/README.md +11 -0
- package/adapters/pi/skills/forge-bootstrap/references/templates/licenses/Apache-2.0/LICENSE +198 -0
- package/adapters/pi/skills/forge-bootstrap/references/templates/licenses/MIT/LICENSE +21 -0
- package/adapters/pi/skills/forge-bootstrap/references/templates/python/pyproject.toml +24 -0
- package/adapters/pi/skills/forge-bootstrap/references/templates/python/src/{{PKG}}/__init__.py +5 -0
- package/adapters/pi/skills/forge-bootstrap/references/templates/python/src/{{PKG}}/main.py +13 -0
- package/adapters/pi/skills/forge-bootstrap/references/templates/python/tests/test_smoke.py +8 -0
- package/adapters/pi/skills/forge-bootstrap/references/templates/rust/Cargo.toml +15 -0
- package/adapters/pi/skills/forge-bootstrap/references/templates/rust/src/lib.rs +7 -0
- package/adapters/pi/skills/forge-bootstrap/references/templates/rust/src/main.rs +5 -0
- package/adapters/pi/skills/forge-bootstrap/references/templates/rust/tests/smoke.rs +6 -0
- package/adapters/pi/skills/forge-bootstrap/references/templates/typescript/package.json +15 -0
- package/adapters/pi/skills/forge-bootstrap/references/templates/typescript/src/index.ts +4 -0
- package/adapters/pi/skills/forge-bootstrap/references/templates/typescript/test/smoke.test.ts +6 -0
- package/adapters/pi/skills/forge-bootstrap/references/templates/typescript/tsconfig.json +14 -0
- package/adapters/pi/skills/forge-fix/SKILL.md +98 -0
- package/adapters/pi/skills/forge-fix/references/shared-conventions.md +345 -0
- package/adapters/pi/skills/forge-fix/references/stage-exit-protocol.md +268 -0
- package/adapters/pi/skills/forge-guide/SKILL.md +192 -0
- package/adapters/{codex/skills/forge-4-backlog → pi/skills/forge-guide}/references/forge-config-schema.json +4 -4
- package/adapters/pi/skills/forge-guide/references/process-overview.md +143 -0
- package/adapters/pi/skills/forge-guide/references/ralph-loop-contract.md +221 -0
- package/adapters/pi/skills/forge-guide/references/shared-conventions.md +345 -0
- package/adapters/pi/skills/forge-guide/references/stack-resolution.md +54 -0
- package/adapters/pi/skills/forge-guide/references/stacks/_generic.md +111 -0
- package/adapters/pi/skills/forge-guide/references/stacks/go.md +157 -0
- package/adapters/pi/skills/forge-guide/references/stacks/python.md +184 -0
- package/adapters/pi/skills/forge-guide/references/stacks/rust.md +170 -0
- package/adapters/pi/skills/forge-guide/references/stacks/typescript.md +134 -0
- package/adapters/pi/skills/forge-init/SKILL.md +72 -0
- package/adapters/pi/skills/forge-verify/SKILL.md +283 -0
- package/adapters/pi/skills/forge-verify/references/findings-template.md +157 -0
- package/adapters/{claude/skills/forge-3-specs → pi/skills/forge-verify}/references/pipeline-state-schema.json +1 -1
- package/adapters/pi/skills/forge-verify/references/shared-conventions.md +345 -0
- package/adapters/pi/skills/forge-verify/references/verification-checklists/backlog.md +97 -0
- package/adapters/pi/skills/forge-verify/references/verification-checklists/epic.md +79 -0
- package/adapters/pi/skills/forge-verify/references/verification-checklists/impl.md +48 -0
- package/adapters/pi/skills/forge-verify/references/verification-checklists/prd.md +31 -0
- package/adapters/pi/skills/forge-verify/references/verification-checklists/specs.md +64 -0
- package/adapters/pi/skills/forge-verify/references/verification-checklists/tech.md +35 -0
- package/dist/agent-targets.d.ts +1 -1
- package/dist/agent-targets.js +23 -3
- package/dist/detect.d.ts +1 -1
- package/dist/detect.js +2 -1
- package/dist/manifest.d.ts +1 -1
- package/dist/manifest.js +2 -2
- package/dist/placements.js +5 -1
- package/dist/rauf.d.ts +4 -4
- package/dist/rauf.js +3 -3
- package/dist/types.d.ts +31 -6
- package/dist/types.js +6 -3
- package/package.json +14 -3
- package/adapters/claude/skills/forge-4-backlog/references/forge-config-schema.json +0 -236
- package/adapters/claude/skills/forge-6-docs/references/pipeline-state-schema.json +0 -191
- package/adapters/claude/skills/forge-verify/references/verification-checklists.md +0 -477
- package/adapters/codex/skills/forge-1-prd/references/pipeline-state-schema.json +0 -191
- package/adapters/codex/skills/forge-2-tech/references/pipeline-state-schema.json +0 -191
- package/adapters/codex/skills/forge-3-specs/references/pipeline-state-schema.json +0 -191
- package/adapters/codex/skills/forge-4-backlog/references/pipeline-state-schema.json +0 -191
- package/adapters/codex/skills/forge-5-loop/references/forge-config-schema.json +0 -236
- package/adapters/codex/skills/forge-6-docs/references/pipeline-state-schema.json +0 -191
- package/adapters/codex/skills/forge-verify/references/verification-checklists.md +0 -477
- package/adapters/copilot/skills/forge-1-prd/references/pipeline-state-schema.json +0 -191
- package/adapters/copilot/skills/forge-2-tech/references/pipeline-state-schema.json +0 -191
- package/adapters/copilot/skills/forge-3-specs/references/pipeline-state-schema.json +0 -191
- package/adapters/copilot/skills/forge-4-backlog/references/forge-config-schema.json +0 -236
- package/adapters/copilot/skills/forge-4-backlog/references/pipeline-state-schema.json +0 -191
- package/adapters/copilot/skills/forge-5-loop/references/forge-config-schema.json +0 -236
- package/adapters/copilot/skills/forge-6-docs/references/pipeline-state-schema.json +0 -191
- package/adapters/copilot/skills/forge-verify/references/verification-checklists.md +0 -477
- package/adapters/cursor/skills/forge-1-prd/references/pipeline-state-schema.json +0 -191
- package/adapters/cursor/skills/forge-2-tech/references/pipeline-state-schema.json +0 -191
- package/adapters/cursor/skills/forge-3-specs/references/pipeline-state-schema.json +0 -191
- package/adapters/cursor/skills/forge-4-backlog/references/forge-config-schema.json +0 -236
- package/adapters/cursor/skills/forge-4-backlog/references/pipeline-state-schema.json +0 -191
- package/adapters/cursor/skills/forge-5-loop/references/forge-config-schema.json +0 -236
- package/adapters/cursor/skills/forge-6-docs/references/pipeline-state-schema.json +0 -191
- package/adapters/cursor/skills/forge-verify/references/verification-checklists.md +0 -477
- package/adapters/gemini/skills/forge-1-prd/references/pipeline-state-schema.json +0 -191
- package/adapters/gemini/skills/forge-2-tech/references/pipeline-state-schema.json +0 -191
- package/adapters/gemini/skills/forge-3-specs/references/pipeline-state-schema.json +0 -191
- package/adapters/gemini/skills/forge-4-backlog/references/forge-config-schema.json +0 -236
- package/adapters/gemini/skills/forge-4-backlog/references/pipeline-state-schema.json +0 -191
- package/adapters/gemini/skills/forge-5-loop/references/forge-config-schema.json +0 -236
- package/adapters/gemini/skills/forge-6-docs/references/pipeline-state-schema.json +0 -191
- package/adapters/gemini/skills/forge-verify/references/verification-checklists.md +0 -477
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
# forge-0-epic — Edit Mode (E1–E6) + Observability / Pipeline State & Commit
|
|
2
|
+
|
|
3
|
+
Lookup detail relocated out of the `forge-0-epic` SKILL.md body. The skill body keeps the
|
|
4
|
+
entry condition (the **EXISTS** branch from Step 0) and the high-level "every mutation is
|
|
5
|
+
committed individually" rule, and points here for the full mechanics. The exact mutator flag
|
|
6
|
+
surface and per-subcommand exit-code handling live in `references/epic-manifest-subcommands.md`.
|
|
7
|
+
|
|
8
|
+
Entered from Step 0 when `{specsDir}/{epic}/epic-manifest.json` already exists (the **EXISTS**
|
|
9
|
+
branch). The edit branch mutates the manifest **only** through helper mutators — the skill never
|
|
10
|
+
hand-rolls an in-place write. Every mutator is atomic (temp file + `os.replace`) and re-validates
|
|
11
|
+
the edited graph internally, so a refused write leaves the manifest **byte-identical**. Every
|
|
12
|
+
question goes through `AskUserQuestion`.
|
|
13
|
+
|
|
14
|
+
## Step E1 — Load + Validate, Refuse if Invalid
|
|
15
|
+
|
|
16
|
+
Before offering any edit, validate the existing manifest:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
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
|
+
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
21
|
+
python3 "$R/scripts/epic-manifest.py" validate "{epic}" --specs-dir "{specsDir}" --json
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
- Exit `0` → the manifest is well-formed; proceed to E2.
|
|
25
|
+
- Exit `1` or `2` → the manifest is corrupt or invalid (hand-edited, `corrupt-json`, `cycle`,
|
|
26
|
+
`dangling-ref`, `duplicate-name`, `cached-status`, `unsafe-name`, …). Surface **every**
|
|
27
|
+
`findings[]` entry **verbatim**, then **refuse ALL mutation** until the user repairs the
|
|
28
|
+
manifest by hand. **Never auto-repair**, never offer an edit operation, and never proceed past
|
|
29
|
+
this gate. Tell the user what is wrong and STOP.
|
|
30
|
+
|
|
31
|
+
## Step E0-read — Surface Pending Epic Change Requests (backflow)
|
|
32
|
+
|
|
33
|
+
Immediately after E1's validate gate passes, and **before** offering the E2 operation menu,
|
|
34
|
+
scan for epic-level change requests that a member stage recorded during the pipeline (the
|
|
35
|
+
backflow path — see `references/pipeline-state-schema.json` `epicChangeRequests[]`, written by
|
|
36
|
+
`forge-1-prd`/`forge-2-tech`). Enumerate the manifest's feature list (already loaded in E1) and
|
|
37
|
+
read each member's `{specsDir}/{epic}/{member}/.pipeline-state.json`, collecting every
|
|
38
|
+
`epicChangeRequests[]` entry with `status: "open"`. If a member state is missing or unreadable,
|
|
39
|
+
report it and continue with the rest — do **not** abort edit mode over one bad member file (mirror
|
|
40
|
+
E1's "report, never silently repair" posture).
|
|
41
|
+
|
|
42
|
+
If any open requests exist, present them grouped (show `kind`, `target`, `rationale`,
|
|
43
|
+
`blocksCurrent`, `raisedBy`), then for **each** request use `AskUserQuestion` to offer **Apply**,
|
|
44
|
+
**Dismiss**, or **Skip for now**:
|
|
45
|
+
|
|
46
|
+
- **Apply — simple kinds (`add-feature`, `redep`):** pre-fill the matching E2 operation and flow
|
|
47
|
+
through E3→E4→E5→E6 unchanged. `add-feature` seeds the new feature's charter from the request's
|
|
48
|
+
`rationale` (the user still edits `exposes`/`consumes`/`dependsOn` before commit, exactly as
|
|
49
|
+
C3/C4/C5); `redep` pre-fills `set-dep {epic} {target} --depends-on "…"`. The existing E4 impact
|
|
50
|
+
warning fires normally — a `blocksCurrent` boundary change naturally trips it, which is correct.
|
|
51
|
+
- **Apply — composite kinds (`move-boundary`, `split`):** there is no single mutator (v1). Walk the
|
|
52
|
+
user through a **guided-manual** sequence — the relevant `set-dep` and/or direct `exposes`/
|
|
53
|
+
`consumes` edits on the composed manifest entries (per E3's "Contracts have no mutator" rule),
|
|
54
|
+
across **both** affected features — re-validating after each step. Confirm each mutation via
|
|
55
|
+
`AskUserQuestion`; never batch-apply.
|
|
56
|
+
- **Dismiss:** the user decides the epic is fine after all — flip the source request's `status` to
|
|
57
|
+
`"dismissed"` (no manifest mutation). Explicit only; there is **no auto-expiry**.
|
|
58
|
+
- **Skip for now:** leave the request `open`; it resurfaces on the next edit-mode entry and stays
|
|
59
|
+
visible in the navigator/verify (once Phase 2 surfacing lands).
|
|
60
|
+
|
|
61
|
+
**On a successful Apply** (mutator exit 0, or the guided-manual sequence confirmed), flip the
|
|
62
|
+
**source** request's `status` from `"open"` to `"applied"` in its member `.pipeline-state.json`,
|
|
63
|
+
using the same atomic temp-file + `os.replace` write the skill uses for any state edit. The E6 git
|
|
64
|
+
step already stages the whole `{specsDir}/{epic}/` subtree, so the flipped member state is captured
|
|
65
|
+
in the **same commit** as the manifest mutation — no new commit machinery. If a **Dismiss** is the
|
|
66
|
+
only action taken (no manifest mutation follows), still commit the member-state change under the
|
|
67
|
+
standard edit-mode message form, e.g. `forge({epic}): dismiss epic change request`.
|
|
68
|
+
|
|
69
|
+
E0-read is **read-then-offer** — it never auto-applies. Every apply still passes through E3/E4 with
|
|
70
|
+
explicit human confirmation, preserving the human-approves-every-mutation invariant. If **no** open
|
|
71
|
+
requests exist, say nothing and proceed straight to E2.
|
|
72
|
+
|
|
73
|
+
## Step E2 — Choose Operation
|
|
74
|
+
|
|
75
|
+
Use `AskUserQuestion` to offer the edit operations, each mapping to one helper mutator:
|
|
76
|
+
|
|
77
|
+
| Operation | Helper subcommand |
|
|
78
|
+
|-----------|-------------------|
|
|
79
|
+
| Add a feature | `add-feature` |
|
|
80
|
+
| Remove a feature | `remove-feature` |
|
|
81
|
+
| Reorder features | `reorder` |
|
|
82
|
+
| Change a dependency edge | `set-dep` |
|
|
83
|
+
| Change epic lifecycle status | `set-status` |
|
|
84
|
+
|
|
85
|
+
For **add-feature**, first run `check-name "{feature}"` (exactly as C2) so no new duplicate is
|
|
86
|
+
introduced — surface a `duplicate-name`/`unsafe-name` finding verbatim and re-prompt — then
|
|
87
|
+
elicit the new feature's **charter** + **`exposes`/`consumes`** + **`dependsOn`** exactly as in
|
|
88
|
+
C3/C4.
|
|
89
|
+
|
|
90
|
+
## Step E3 — Apply via Helper Mutator (re-validated)
|
|
91
|
+
|
|
92
|
+
Issue the chosen mutator. Each writes atomically and re-runs full validation internally, refusing
|
|
93
|
+
the write if it would introduce a cycle, dangling ref, duplicate, or schema violation. For the
|
|
94
|
+
exact `epic-manifest.py` mutator flag surface and per-subcommand exit-code handling, read
|
|
95
|
+
`references/epic-manifest-subcommands.md`.
|
|
96
|
+
|
|
97
|
+
**Contracts have no mutator.** `add-feature` seeds empty `exposes`/`consumes`. To populate the
|
|
98
|
+
new feature's contracts, edit its `exposes`/`consumes` arrays **directly in the composed manifest
|
|
99
|
+
entry** (exactly as creation C5 does), then re-run `validate "{epic}" --json` to confirm — there
|
|
100
|
+
is intentionally no `--exposes-json`/`--consumes-json` flag.
|
|
101
|
+
|
|
102
|
+
**remove-feature leaves the member directory in place (§7.5).** The mutator drops only the
|
|
103
|
+
manifest entry. The skill does **not** delete or relocate `{specsDir}/{epic}/{feature}/`. WARN the
|
|
104
|
+
user verbatim:
|
|
105
|
+
|
|
106
|
+
> Removed `{feature}` from the manifest. Its directory `{specsDir}/{epic}/{feature}/` is left in
|
|
107
|
+
> place; move it to `{specsDir}/{feature}/` by hand if you want it as a standalone feature.
|
|
108
|
+
> Relocation is manual — there is no migration tooling.
|
|
109
|
+
|
|
110
|
+
The orphaned subdir still holds a `.pipeline-state.json` with an `epic` back-pointer the manifest
|
|
111
|
+
no longer lists; per the conflict rule the **manifest wins**, and `forge-verify` epic mode
|
|
112
|
+
CHECK-E07 reports the inconsistency non-fatally. The skill does **not** silently edit the orphaned
|
|
113
|
+
state file.
|
|
114
|
+
|
|
115
|
+
## Step E4 — Impact Warning (in-flight / completed features)
|
|
116
|
+
|
|
117
|
+
Before applying — or immediately after eliciting — a mutation that affects a feature whose derived
|
|
118
|
+
status is **not** `not-started`, warn the user. Read the **live** status (never re-derive
|
|
119
|
+
completion in prose):
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
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')"
|
|
123
|
+
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
124
|
+
python3 "$R/scripts/epic-manifest.py" render-status "{epic}" --specs-dir "{specsDir}" --json
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
If the operation removes, reorders-around, or re-deps a feature whose derived status is
|
|
128
|
+
`in-progress` or `complete`, use `AskUserQuestion` with an explicit warning naming the affected
|
|
129
|
+
in-flight/completed feature(s) and **require confirmation** before applying. Example: "`token-service`
|
|
130
|
+
is already in-progress (forge-3-specs). Removing `config-store`, which it consumes `JWT_SECRET`
|
|
131
|
+
from, may invalidate its in-flight specs. Proceed?" If `render-status` exits `≥ 1`, surface the
|
|
132
|
+
findings and STOP (do not mutate over an invalid graph).
|
|
133
|
+
|
|
134
|
+
## Step E5 — Patch EPIC.md
|
|
135
|
+
|
|
136
|
+
Patch **only** the affected feature/Contracts section(s) — the section(s) for the added, removed,
|
|
137
|
+
or changed feature and any feature whose `dependsOn`/`consumes` changed — applying the §C6 mirror
|
|
138
|
+
rule (one bullet per `exposes`/`consumes` entry). **Full regeneration happens only on explicit
|
|
139
|
+
user request**: offer it via `AskUserQuestion` but default to the targeted patch. The skill keeps
|
|
140
|
+
EPIC.md in sync but does not itself diff it against the manifest — drift detection is `forge-verify`
|
|
141
|
+
epic mode CHECK-E06.
|
|
142
|
+
|
|
143
|
+
## Step E6 — Pipeline State & Commit
|
|
144
|
+
|
|
145
|
+
Proceed to the **Observability, Pipeline State & Commit** section below. Each edit-mode mutation is
|
|
146
|
+
committed individually so git history is the audit trail.
|
|
147
|
+
|
|
148
|
+
## Observability, Pipeline State & Commit
|
|
149
|
+
|
|
150
|
+
### Manifest `updatedAt`
|
|
151
|
+
|
|
152
|
+
Every helper mutator bumps the manifest's top-level `updatedAt` to the current ISO-8601 UTC
|
|
153
|
+
timestamp as part of the same atomic write. The skill does **not** bump it manually in edit mode.
|
|
154
|
+
For the initial creation write (C5) the skill sets `createdAt == updatedAt`.
|
|
155
|
+
|
|
156
|
+
### Pipeline state
|
|
157
|
+
|
|
158
|
+
- **Epic-level:** the epic subtree has **no `.pipeline-state.json` of its own** (that is what
|
|
159
|
+
distinguishes an epic root from a feature). The epic's lifecycle lives in the manifest `status`
|
|
160
|
+
field. The `forge-0-epic` run is recorded in **member** states, not in an epic-level state file.
|
|
161
|
+
- **Member-level (creation):** each member's `.pipeline-state.json` records
|
|
162
|
+
`stages["forge-0-epic"].status = "complete"` and `currentStage = "forge-1-prd"` (see C7).
|
|
163
|
+
- **Edit mode:** edits mutate the **manifest**, not member pipeline states — except the
|
|
164
|
+
newly-created subdir for `add-feature`, which follows C7 (create the member subdir + back-pointer
|
|
165
|
+
state). The skill does **not** rewrite existing members' `stages` on an edit.
|
|
166
|
+
- **`.epic-state.json` (lazily created, written by skills — NOT the helper):** epic-*scoped* stage
|
|
167
|
+
entries that belong to no single member — currently only `forge-verify-epic` — are persisted in a
|
|
168
|
+
dedicated `{specsDir}/{epic}/.epic-state.json`. It holds **only** epic-scoped stage entries,
|
|
169
|
+
never derived per-feature status (so it does not violate REQ-STATE-02). `forge-0-epic` does
|
|
170
|
+
**not** create this file — no epic-scoped stage runs during creation or edit; it appears only once
|
|
171
|
+
`forge-verify` epic mode runs. When a skill does write it (e.g. forge-verify epic mode), it writes
|
|
172
|
+
**directly** using an atomic temp-file + `os.replace` pattern — the helper exposes no subcommand
|
|
173
|
+
for it. On I/O failure the skill reports and leaves any prior file intact (never a partial write).
|
|
174
|
+
Minimal schema:
|
|
175
|
+
|
|
176
|
+
```jsonc
|
|
177
|
+
{
|
|
178
|
+
"epic": "auth-overhaul", // matches manifest `epic`
|
|
179
|
+
"stages": {
|
|
180
|
+
"forge-verify-epic": {
|
|
181
|
+
"status": "findings-reported", // "findings-reported" | "passed" | "findings-applied"
|
|
182
|
+
"findingsFile": ".verification/VERIFY-epic-2026-06-12.md",
|
|
183
|
+
"findingsCount": 3,
|
|
184
|
+
"verifiedAt": "2026-06-12T00:00:00Z"
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
The git-commit step below stages the whole epic subtree, so `.epic-state.json` is captured
|
|
191
|
+
automatically when present.
|
|
192
|
+
|
|
193
|
+
### Git Commit Protocol
|
|
194
|
+
|
|
195
|
+
After creation (C8) **and after each edit-mode mutation (E6)**, if `gitCommitAfterStage` is true,
|
|
196
|
+
follow the Git Commit Protocol in shared-conventions:
|
|
197
|
+
|
|
198
|
+
1. Stage the whole epic subtree only: `git add {specsDir}/{epic}/` — **never** `git add -A`. This
|
|
199
|
+
captures `epic-manifest.json`, `EPIC.md`, member `.pipeline-state.json` files, and any
|
|
200
|
+
`.epic-state.json` together atomically.
|
|
201
|
+
2. Commit with message `"{commitPrefix}({epic}): <action>"`, e.g.
|
|
202
|
+
`"forge({epic}): create epic with 4 features"`, `"forge({epic}): add feature api-gateway"`,
|
|
203
|
+
`"forge({epic}): remove feature legacy-session"`, `"forge({epic}): reorder features"`,
|
|
204
|
+
`"forge({epic}): set dependency on token-service"`, or `"forge({epic}): set status paused"`.
|
|
205
|
+
3. On success, capture the commit hash for reporting only — the epic manifest has no `commitHash`
|
|
206
|
+
field, so nothing is written back into a committed file and the two-commit step of the Git Commit
|
|
207
|
+
Protocol does not apply here. On failure (pre-commit hook, conflict), report and do **not** mark
|
|
208
|
+
complete; never use `--amend`/`--no-verify`/`--force`.
|
|
209
|
+
|
|
210
|
+
Because every mutation is committed, the git history of `epic-manifest.json` is the audit trail; no
|
|
211
|
+
separate in-manifest audit log is kept.
|
|
212
|
+
|
|
213
|
+
### Closing message
|
|
214
|
+
|
|
215
|
+
After a successful **creation**, present the next-steps message (already specified in C8). After a
|
|
216
|
+
successful **edit-mode mutation**, confirm the change and re-surface the dashboard pointer:
|
|
217
|
+
|
|
218
|
+
> Epic `{epic}` updated (`<action>`). Run `/skill:forge {epic}` to see the refreshed
|
|
219
|
+
> dashboard, or re-run `/skill:forge-0-epic {epic}` to make another change.
|
|
220
|
+
|
|
221
|
+
## EPIC.md Mirror Template (creation C6 / edit E5)
|
|
222
|
+
|
|
223
|
+
`forge-0-epic` Step C6 generates `{specsDir}/{epic}/EPIC.md` from the **validated** manifest; the
|
|
224
|
+
edit-mode E5 patch applies the **same mirror rule** to the affected sections. The full skeleton:
|
|
225
|
+
|
|
226
|
+
```markdown
|
|
227
|
+
# {epic} — Epic
|
|
228
|
+
|
|
229
|
+
## Overall Goal
|
|
230
|
+
{the epic goal from C1, expanded into narrative prose}
|
|
231
|
+
|
|
232
|
+
## Decomposition Rationale
|
|
233
|
+
{why the change was split this way; right-sizing notes; ordering rationale}
|
|
234
|
+
|
|
235
|
+
## Features
|
|
236
|
+
{for each feature, in manifest order:}
|
|
237
|
+
|
|
238
|
+
### {feature.name}
|
|
239
|
+
{feature.charter, as prose}
|
|
240
|
+
|
|
241
|
+
**Depends on:** {comma-separated dependsOn, or "nothing"}
|
|
242
|
+
|
|
243
|
+
#### Contracts
|
|
244
|
+
**Exposes:**
|
|
245
|
+
- `{exposes[i].name}` ({exposes[i].kind}) — {exposes[i].summary}
|
|
246
|
+
{… or "Nothing exposed." if the exposes array is empty}
|
|
247
|
+
|
|
248
|
+
**Consumes:**
|
|
249
|
+
- `{consumes[i].name}` from `{consumes[i].from}` — {consumes[i].summary}
|
|
250
|
+
{… or "Nothing consumed." if the consumes array is empty}
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
## Member State Example (creation C7)
|
|
254
|
+
|
|
255
|
+
Each member's `.pipeline-state.json` (created in Step C7) conforms to
|
|
256
|
+
`references/pipeline-state-schema.json`. Example member state:
|
|
257
|
+
|
|
258
|
+
```json
|
|
259
|
+
{
|
|
260
|
+
"epic": "{epic}",
|
|
261
|
+
"currentStage": "forge-1-prd",
|
|
262
|
+
"stages": {
|
|
263
|
+
"forge-0-epic": { "status": "complete", "version": 1, "completedAt": "<iso-8601-utc>" }
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
```
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# forge-0-epic — `epic-manifest.py` Subcommand Reference
|
|
2
|
+
|
|
3
|
+
Lookup detail relocated out of the `forge-0-epic` SKILL.md body (Step E3 command
|
|
4
|
+
catalog + exit-code disposition, and the Error Handling table). The skill body keeps
|
|
5
|
+
the decision logic and step ordering; this file is the flag-surface catalog and the
|
|
6
|
+
per-subcommand exit-code reference.
|
|
7
|
+
|
|
8
|
+
## Edit-Mode Mutator Flag Surface (Step E3)
|
|
9
|
+
|
|
10
|
+
Issue the chosen mutator. Each writes atomically and re-runs full validation internally, refusing
|
|
11
|
+
the write if it would introduce a cycle, dangling ref, duplicate, or schema violation. The exact
|
|
12
|
+
flag surface (owned by 02 §7):
|
|
13
|
+
|
|
14
|
+
```bash
|
|
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
|
+
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
17
|
+
# Add a feature — seeds EMPTY exposes/consumes; contracts are populated below.
|
|
18
|
+
python3 "$R/scripts/epic-manifest.py" add-feature "{epic}" "{feature}" \
|
|
19
|
+
--charter "…" --specs-dir "{specsDir}" [--depends-on a,b]
|
|
20
|
+
|
|
21
|
+
# Remove a feature (drops its manifest entry; directory is left in place — see E3 note).
|
|
22
|
+
python3 "$R/scripts/epic-manifest.py" remove-feature "{epic}" "{feature}" \
|
|
23
|
+
--specs-dir "{specsDir}"
|
|
24
|
+
|
|
25
|
+
# Reorder the features[] sequence (must be an exact permutation of current member names).
|
|
26
|
+
python3 "$R/scripts/epic-manifest.py" reorder "{epic}" \
|
|
27
|
+
--order "feat-a,feat-c,feat-b" --specs-dir "{specsDir}"
|
|
28
|
+
|
|
29
|
+
# Change a dependency edge (--depends-on "" clears it).
|
|
30
|
+
python3 "$R/scripts/epic-manifest.py" set-dep "{epic}" "{feature}" \
|
|
31
|
+
--depends-on "config-store,token-service" --specs-dir "{specsDir}"
|
|
32
|
+
|
|
33
|
+
# Change epic lifecycle status (active|paused|abandoned|complete).
|
|
34
|
+
python3 "$R/scripts/epic-manifest.py" set-status "{epic}" \
|
|
35
|
+
--status paused --specs-dir "{specsDir}"
|
|
36
|
+
|
|
37
|
+
# Adopt a detached standalone INTO this epic as a member (split-brain recovery, #126).
|
|
38
|
+
# Relocates specs/{feature}/ → specs/{epic}/{feature}/, MERGES the standalone's stage
|
|
39
|
+
# history onto the member stub while preserving the stub's epic/branch back-pointers,
|
|
40
|
+
# removes the flat dir, and add-features it to the manifest if absent. Both dirs must be
|
|
41
|
+
# on the CURRENT tree (bring a cross-branch standalone onto the epic's home branch first,
|
|
42
|
+
# per docs/recovery-detached-epic-member.md). EPIC.md prose is NOT regenerated — re-run
|
|
43
|
+
# forge-0-epic (Step C6) afterward. Re-entrant; exit 1 (with findings) only if the manifest
|
|
44
|
+
# add is refused (e.g. a bad --depends-on) — the relocation still stands, re-run to finish.
|
|
45
|
+
python3 "$R/scripts/epic-manifest.py" adopt-feature "{epic}" "{feature}" \
|
|
46
|
+
--specs-dir "{specsDir}" [--charter "…"] [--depends-on a,b] [--json]
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Per-Subcommand Exit-Code Disposition (Step E3)
|
|
50
|
+
|
|
51
|
+
- Exit `0` → the mutator wrote the manifest and bumped `updatedAt`. Proceed to E4/E5.
|
|
52
|
+
- Exit `1` → surface the `findings[]` **verbatim** and **abort the edit**. The manifest is
|
|
53
|
+
unchanged (the write was refused atomically — byte-identical). Loop back to E2 or re-elicit.
|
|
54
|
+
- Exit `2` → unsafe name / missing|corrupt manifest / bad `--status` value / write failure.
|
|
55
|
+
Surface and STOP.
|
|
56
|
+
|
|
57
|
+
## Error Handling
|
|
58
|
+
|
|
59
|
+
The skill **never** repairs a corrupt manifest automatically and **never** proceeds past a gating
|
|
60
|
+
helper exit `≥ 1`. All findings are surfaced **verbatim**.
|
|
61
|
+
|
|
62
|
+
| Condition | Helper signal | Skill behavior |
|
|
63
|
+
|-----------|---------------|----------------|
|
|
64
|
+
| Epic name duplicates an existing name | `check-name` exit 1 (`duplicate-name`) | STOP creation; surface finding; ask for a new name via `AskUserQuestion` |
|
|
65
|
+
| Member feature name duplicates | `check-name` exit 1 (`duplicate-name`) | Reject that name in C2 / add-feature; surface verbatim; re-prompt |
|
|
66
|
+
| Unsafe name (`/`, `..`, absolute) | `check-name`/mutator exit 2 (`unsafe-name`) | Reject; surface; re-prompt |
|
|
67
|
+
| Composed manifest has a cycle | `validate` exit 1 (`cycle`) | Surface verbatim; re-open the dependency interview (C4); never finalize |
|
|
68
|
+
| Dangling `dependsOn`/`consumes.from` | `validate` exit 1 (`dangling-ref`) | Surface verbatim; re-open C4 (bad `dependsOn`) or C3 (bad `consumes.from`) |
|
|
69
|
+
| Corrupt/unparseable manifest (edit) | `validate` exit 1 (`corrupt-json`) | Surface ALL findings verbatim; **refuse all mutation** until repaired; never auto-repair |
|
|
70
|
+
| Existing manifest otherwise invalid (edit) | `validate` exit 1/2 | Surface ALL findings verbatim; **refuse all mutation** (E1) |
|
|
71
|
+
| Mutator would introduce cycle/dangling ref/duplicate | mutator exit 1 | Abort the edit; manifest byte-identical (atomic refusal); surface finding |
|
|
72
|
+
| Bad `--status` value | `set-status` exit 2 (argparse) | Surface; re-prompt via `AskUserQuestion` with the valid choices |
|
|
73
|
+
| Edit affects in-flight/completed feature | `render-status` derived status (`in-progress`/`complete`) | Warn naming the affected feature(s); require confirmation before applying (E4) |
|
|
74
|
+
| `render-status` over an invalid graph | `render-status` exit ≥ 1 | Surface findings; STOP (do not mutate over an invalid graph) |
|
|
75
|
+
| Git commit fails | — | Report; leave state `in-progress`; never bypass hooks (`--no-verify`/`--force`) |
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"currentStage": {
|
|
34
34
|
"type": "string",
|
|
35
35
|
"enum": ["forge-1-prd", "forge-2-tech", "forge-3-specs", "forge-4-backlog", "forge-5-loop", "forge-6-docs", "complete", "forge-verify-prd", "forge-verify-tech", "forge-verify-specs", "forge-verify-backlog", "forge-verify-impl", "forge-0-epic", "forge-verify-epic"],
|
|
36
|
-
"description": "Where the pipeline IS: the most recently started stage — its `stages[<currentStage>].status` is `in-progress` while that stage is being authored, then `complete` once its artifacts are committed. A stage skill sets this to its own id when it starts. This is deliberately NOT 'the next stage to run': the next stage is DERIVED, never stored — it is the first production stage whose `stages[].status` is not `complete` (see `next_stage()` in forge-session.py, surfaced as the navigator/doctor `nextStage`). Consumers that need 'what runs next' compute it from `stages[].status`, not from this field. `complete`
|
|
36
|
+
"description": "Where the pipeline IS: the most recently started stage — its `stages[<currentStage>].status` is `in-progress` while that stage is being authored, then `complete` once its artifacts are committed. A stage skill sets this to its own id when it starts. This is deliberately NOT 'the next stage to run': the next stage is DERIVED, never stored — it is the first production stage whose `stages[].status` is not `complete` (see `next_stage()` in forge-session.py, surfaced as the navigator/doctor `nextStage`). Consumers that need 'what runs next' compute it from `stages[].status`, not from this field. `complete` is a LEGACY enum value, retained so pre-0.14 state files still validate: no writer produces it (the `state-*` verbs are the only writers, and only `state-enter` touches this field, setting it to the stage being entered). A finished pipeline therefore records the last stage it started — `forge-6-docs` — and 'the whole pipeline is done' is DERIVED too: `next_stage()` returns null (surfaced as `nextStage: null` / `complete: true`). Never test this field against `complete` to decide whether a pipeline finished. (Legacy/absent value: tools fall back to the derived next stage for display only — `build_rows` in forge-session.py.)"
|
|
37
37
|
},
|
|
38
38
|
"notes": {
|
|
39
39
|
"type": "string",
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Portable Script-Root Resolution
|
|
2
|
+
|
|
3
|
+
This file is the **single canonical home** of the feature-forge bootstrap prelude and the
|
|
4
|
+
portable invocation convention. Each fenced shell block an agent runs is a separate process
|
|
5
|
+
with no persisted state, so the plugin root must be re-resolved within the same block as every
|
|
6
|
+
bundled-script call. The prelude below is the fixed, byte-identical snippet that does this by
|
|
7
|
+
discovering and delegating to `scripts/forge-root.sh`. Downstream consumers
|
|
8
|
+
(`forge-agent-adapters-build`, `cross-agent-installer`) and the spec-purity checker treat this
|
|
9
|
+
file as authoritative: the checker's rule 5 compares every prelude occurrence across the canon
|
|
10
|
+
against the fenced block here, byte-for-byte.
|
|
11
|
+
|
|
12
|
+
## Canonical bootstrap prelude
|
|
13
|
+
|
|
14
|
+
```bash
|
|
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
|
+
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
Prepend the prelude to a fenced shell block once, then invoke bundled scripts via `$R`:
|
|
22
|
+
`python3 "$R/scripts/<x>"` or `bash "$R/scripts/<x>"`. One prelude per fenced block — if a block
|
|
23
|
+
makes several calls, add the prelude once and reuse `$R` for each. A fresh block gets its own
|
|
24
|
+
prelude (per-block re-resolution). Worked example:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
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')"
|
|
28
|
+
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
29
|
+
python3 "$R/scripts/epic-manifest.py" render-status "{epic}" --specs-dir "{specsDir}" --json
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Invariants (do NOT "fix" these)
|
|
33
|
+
|
|
34
|
+
1. **First hint is the Claude plugin-root env var; the rest are paths.** The prelude's
|
|
35
|
+
`for d in …` list leads with the `CLAUDE_PLUGIN_ROOT` env var (in default-empty `:-` form)
|
|
36
|
+
— the exact bundle dir Claude exports in every marketplace/plugin session — followed by the
|
|
37
|
+
directory-path candidates. The hint gives exact, glob-free resolution on any current/future
|
|
38
|
+
Claude layout (no version-skew window); when unset it expands to empty and is harmlessly
|
|
39
|
+
skipped, so other hosts fall through to the path candidates unchanged. This is the **one
|
|
40
|
+
sanctioned** appearance of that variable in canonical surfaces: spec-purity rule 3 allows it
|
|
41
|
+
by stripping the byte-pinned prelude before its residual-var scan (so a stray var anywhere
|
|
42
|
+
else — including the default-empty form — still fails), and `forge-agent-adapters-build`
|
|
43
|
+
translates it to `FEATURE_FORGE_ROOT` for non-Claude bundles (which `forge-root.sh` already
|
|
44
|
+
prefers). The exact literal is shown only in the fenced prelude above and audited in
|
|
45
|
+
`vendor-construct-inventory.md`.
|
|
46
|
+
2. **First-discoverable-resolver-wins.** The `exec` inside the `$(…)` command substitution means
|
|
47
|
+
the loop stops at the first directory holding an executable `forge-root.sh` and delegates ALL
|
|
48
|
+
final root resolution to that script. The `for` list is a discovery order for `forge-root.sh`
|
|
49
|
+
itself, not a fallback chain for the plugin root. Removing the `exec` to "keep looping" is a
|
|
50
|
+
regression — once `exec`'d, the loop is replaced by the resolver process and never advances.
|
|
51
|
+
3. **Prelude candidate set is an agent-neutral bootstrap subset (after the env hint).** The
|
|
52
|
+
prelude's `for d` list exists only to bootstrap-discover `forge-root.sh`; the authoritative
|
|
53
|
+
multi-root probe lives in `forge-root.sh` step 2. After the leading env-var hint (invariant 1),
|
|
54
|
+
the list enumerates install roots across agents — the Claude
|
|
55
|
+
skill/plugin dirs — including the marketplace-cache layout
|
|
56
|
+
`~/.claude/plugins/cache/<marketplace>/feature-forge/<version>/`, listed before the
|
|
57
|
+
single-star plugins glob so a versioned cache install always beats the marketplace clone —
|
|
58
|
+
**and** the agent-neutral `.agents/skills/feature-forge` dirs (`$HOME` and the
|
|
59
|
+
project-relative `./.agents/...`) — so a non-Claude install (e.g. Codex under `.agents/skills`)
|
|
60
|
+
can still discover the resolver. When adding an install root, update `forge-root.sh` first;
|
|
61
|
+
extend the prelude only if the new root is needed to bootstrap-discover `forge-root.sh` itself.
|
|
62
|
+
|
|
63
|
+
## The resolver
|
|
64
|
+
|
|
65
|
+
The prelude delegates to [`scripts/forge-root.sh`](../scripts/forge-root.sh) — the portable
|
|
66
|
+
skill/plugin-root resolver. It takes no arguments, prints the absolute plugin root to stdout and
|
|
67
|
+
exits `0`, or writes an actionable message to stderr and exits `1`. It resolves the root by
|
|
68
|
+
self-location → candidate-root probe → plugin-root environment-variable fallback → actionable failure,
|
|
69
|
+
and never sources or executes a discovered path — it only ever prints a directory string. The
|
|
70
|
+
spec-purity checker (rule 5) enforces that every prelude occurrence across the canon is
|
|
71
|
+
byte-identical to the fenced block in this file.
|