bmalph 1.0.0
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 +217 -0
- package/bin/bmalph.js +14 -0
- package/bmad/bmm/agents/analyst.agent.yaml +36 -0
- package/bmad/bmm/agents/architect.agent.yaml +28 -0
- package/bmad/bmm/agents/dev.agent.yaml +38 -0
- package/bmad/bmm/agents/pm.agent.yaml +46 -0
- package/bmad/bmm/agents/quick-flow-solo-dev.agent.yaml +32 -0
- package/bmad/bmm/agents/sm.agent.yaml +36 -0
- package/bmad/bmm/agents/tea.agent.yaml +63 -0
- package/bmad/bmm/agents/tech-writer/tech-writer-sidecar/documentation-standards.md +224 -0
- package/bmad/bmm/agents/tech-writer/tech-writer.agent.yaml +45 -0
- package/bmad/bmm/agents/ux-designer.agent.yaml +26 -0
- package/bmad/bmm/data/project-context-template.md +26 -0
- package/bmad/bmm/module-help.csv +31 -0
- package/bmad/bmm/module.yaml +44 -0
- package/bmad/bmm/sub-modules/claude-code/config.yaml +4 -0
- package/bmad/bmm/sub-modules/claude-code/injections.yaml +242 -0
- package/bmad/bmm/sub-modules/claude-code/readme.md +87 -0
- package/bmad/bmm/teams/default-party.csv +21 -0
- package/bmad/bmm/teams/team-fullstack.yaml +12 -0
- package/bmad/bmm/testarch/knowledge/adr-quality-readiness-checklist.md +350 -0
- package/bmad/bmm/testarch/knowledge/api-request.md +442 -0
- package/bmad/bmm/testarch/knowledge/api-testing-patterns.md +843 -0
- package/bmad/bmm/testarch/knowledge/auth-session.md +552 -0
- package/bmad/bmm/testarch/knowledge/burn-in.md +273 -0
- package/bmad/bmm/testarch/knowledge/ci-burn-in.md +675 -0
- package/bmad/bmm/testarch/knowledge/component-tdd.md +486 -0
- package/bmad/bmm/testarch/knowledge/contract-testing.md +957 -0
- package/bmad/bmm/testarch/knowledge/data-factories.md +500 -0
- package/bmad/bmm/testarch/knowledge/email-auth.md +721 -0
- package/bmad/bmm/testarch/knowledge/error-handling.md +725 -0
- package/bmad/bmm/testarch/knowledge/feature-flags.md +750 -0
- package/bmad/bmm/testarch/knowledge/file-utils.md +463 -0
- package/bmad/bmm/testarch/knowledge/fixture-architecture.md +401 -0
- package/bmad/bmm/testarch/knowledge/fixtures-composition.md +382 -0
- package/bmad/bmm/testarch/knowledge/intercept-network-call.md +430 -0
- package/bmad/bmm/testarch/knowledge/log.md +429 -0
- package/bmad/bmm/testarch/knowledge/network-error-monitor.md +405 -0
- package/bmad/bmm/testarch/knowledge/network-first.md +486 -0
- package/bmad/bmm/testarch/knowledge/network-recorder.md +527 -0
- package/bmad/bmm/testarch/knowledge/nfr-criteria.md +670 -0
- package/bmad/bmm/testarch/knowledge/overview.md +286 -0
- package/bmad/bmm/testarch/knowledge/playwright-config.md +730 -0
- package/bmad/bmm/testarch/knowledge/probability-impact.md +601 -0
- package/bmad/bmm/testarch/knowledge/recurse.md +421 -0
- package/bmad/bmm/testarch/knowledge/risk-governance.md +615 -0
- package/bmad/bmm/testarch/knowledge/selective-testing.md +732 -0
- package/bmad/bmm/testarch/knowledge/selector-resilience.md +527 -0
- package/bmad/bmm/testarch/knowledge/test-healing-patterns.md +644 -0
- package/bmad/bmm/testarch/knowledge/test-levels-framework.md +473 -0
- package/bmad/bmm/testarch/knowledge/test-priorities-matrix.md +373 -0
- package/bmad/bmm/testarch/knowledge/test-quality.md +664 -0
- package/bmad/bmm/testarch/knowledge/timing-debugging.md +372 -0
- package/bmad/bmm/testarch/knowledge/visual-debugging.md +524 -0
- package/bmad/bmm/testarch/tea-index.csv +35 -0
- package/bmad/bmm/workflows/1-analysis/create-product-brief/product-brief.template.md +10 -0
- package/bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-01-init.md +177 -0
- package/bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-01b-continue.md +161 -0
- package/bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-02-vision.md +199 -0
- package/bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-03-users.md +202 -0
- package/bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-04-metrics.md +205 -0
- package/bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-05-scope.md +219 -0
- package/bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-06-complete.md +162 -0
- package/bmad/bmm/workflows/1-analysis/create-product-brief/workflow.md +58 -0
- package/bmad/bmm/workflows/1-analysis/research/domain-steps/step-01-init.md +137 -0
- package/bmad/bmm/workflows/1-analysis/research/domain-steps/step-02-domain-analysis.md +229 -0
- package/bmad/bmm/workflows/1-analysis/research/domain-steps/step-03-competitive-landscape.md +238 -0
- package/bmad/bmm/workflows/1-analysis/research/domain-steps/step-04-regulatory-focus.md +206 -0
- package/bmad/bmm/workflows/1-analysis/research/domain-steps/step-05-technical-trends.md +234 -0
- package/bmad/bmm/workflows/1-analysis/research/domain-steps/step-06-research-synthesis.md +443 -0
- package/bmad/bmm/workflows/1-analysis/research/market-steps/step-01-init.md +182 -0
- package/bmad/bmm/workflows/1-analysis/research/market-steps/step-02-customer-behavior.md +237 -0
- package/bmad/bmm/workflows/1-analysis/research/market-steps/step-02-customer-insights.md +200 -0
- package/bmad/bmm/workflows/1-analysis/research/market-steps/step-03-customer-pain-points.md +249 -0
- package/bmad/bmm/workflows/1-analysis/research/market-steps/step-04-customer-decisions.md +259 -0
- package/bmad/bmm/workflows/1-analysis/research/market-steps/step-05-competitive-analysis.md +177 -0
- package/bmad/bmm/workflows/1-analysis/research/market-steps/step-06-research-completion.md +475 -0
- package/bmad/bmm/workflows/1-analysis/research/research.template.md +29 -0
- package/bmad/bmm/workflows/1-analysis/research/technical-steps/step-01-init.md +137 -0
- package/bmad/bmm/workflows/1-analysis/research/technical-steps/step-02-technical-overview.md +239 -0
- package/bmad/bmm/workflows/1-analysis/research/technical-steps/step-03-integration-patterns.md +248 -0
- package/bmad/bmm/workflows/1-analysis/research/technical-steps/step-04-architectural-patterns.md +202 -0
- package/bmad/bmm/workflows/1-analysis/research/technical-steps/step-05-implementation-research.md +239 -0
- package/bmad/bmm/workflows/1-analysis/research/technical-steps/step-06-research-synthesis.md +486 -0
- package/bmad/bmm/workflows/1-analysis/research/workflow.md +173 -0
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-01-init.md +135 -0
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-01b-continue.md +127 -0
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-02-discovery.md +190 -0
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-03-core-experience.md +216 -0
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-04-emotional-response.md +219 -0
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-05-inspiration.md +234 -0
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-06-design-system.md +252 -0
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-07-defining-experience.md +254 -0
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-08-visual-foundation.md +224 -0
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-09-design-directions.md +224 -0
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-10-user-journeys.md +241 -0
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-11-component-strategy.md +248 -0
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-12-ux-patterns.md +237 -0
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-13-responsive-accessibility.md +264 -0
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-14-complete.md +171 -0
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/ux-design-template.md +13 -0
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/workflow.md +43 -0
- package/bmad/bmm/workflows/2-plan-workflows/prd/data/domain-complexity.csv +13 -0
- package/bmad/bmm/workflows/2-plan-workflows/prd/data/prd-purpose.md +197 -0
- package/bmad/bmm/workflows/2-plan-workflows/prd/data/project-types.csv +11 -0
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps-c/step-01-init.md +191 -0
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps-c/step-01b-continue.md +153 -0
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps-c/step-02-discovery.md +224 -0
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps-c/step-03-success.md +226 -0
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps-c/step-04-journeys.md +213 -0
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps-c/step-05-domain.md +207 -0
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps-c/step-06-innovation.md +226 -0
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps-c/step-07-project-type.md +237 -0
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps-c/step-08-scoping.md +228 -0
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps-c/step-09-functional.md +231 -0
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps-c/step-10-nonfunctional.md +242 -0
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps-c/step-11-polish.md +217 -0
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps-c/step-12-complete.md +124 -0
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps-e/step-e-01-discovery.md +247 -0
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps-e/step-e-01b-legacy-conversion.md +208 -0
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps-e/step-e-02-review.md +249 -0
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps-e/step-e-03-edit.md +253 -0
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps-e/step-e-04-complete.md +168 -0
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-01-discovery.md +218 -0
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-02-format-detection.md +191 -0
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-02b-parity-check.md +209 -0
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-03-density-validation.md +174 -0
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-04-brief-coverage-validation.md +214 -0
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-05-measurability-validation.md +228 -0
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-06-traceability-validation.md +217 -0
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-07-implementation-leakage-validation.md +205 -0
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-08-domain-compliance-validation.md +243 -0
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-09-project-type-validation.md +263 -0
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-10-smart-validation.md +209 -0
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-11-holistic-quality-validation.md +264 -0
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-12-completeness-validation.md +242 -0
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-13-report-complete.md +231 -0
- package/bmad/bmm/workflows/2-plan-workflows/prd/templates/prd-template.md +10 -0
- package/bmad/bmm/workflows/2-plan-workflows/prd/validation-report-prd-workflow.md +433 -0
- package/bmad/bmm/workflows/2-plan-workflows/prd/workflow.md +150 -0
- package/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-01-document-discovery.md +190 -0
- package/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-02-prd-analysis.md +178 -0
- package/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-03-epic-coverage-validation.md +179 -0
- package/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-04-ux-alignment.md +139 -0
- package/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-05-epic-quality-review.md +252 -0
- package/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-06-final-assessment.md +135 -0
- package/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/templates/readiness-report-template.md +4 -0
- package/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/workflow.md +55 -0
- package/bmad/bmm/workflows/3-solutioning/create-architecture/architecture-decision-template.md +12 -0
- package/bmad/bmm/workflows/3-solutioning/create-architecture/data/domain-complexity.csv +11 -0
- package/bmad/bmm/workflows/3-solutioning/create-architecture/data/project-types.csv +7 -0
- package/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-01-init.md +153 -0
- package/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-01b-continue.md +164 -0
- package/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-02-context.md +224 -0
- package/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-03-starter.md +331 -0
- package/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-04-decisions.md +318 -0
- package/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-05-patterns.md +359 -0
- package/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-06-structure.md +379 -0
- package/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-07-validation.md +359 -0
- package/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-08-complete.md +76 -0
- package/bmad/bmm/workflows/3-solutioning/create-architecture/workflow.md +50 -0
- package/bmad/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-01-validate-prerequisites.md +259 -0
- package/bmad/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-02-design-epics.md +233 -0
- package/bmad/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-03-create-stories.md +272 -0
- package/bmad/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-04-final-validation.md +149 -0
- package/bmad/bmm/workflows/3-solutioning/create-epics-and-stories/templates/epics-template.md +57 -0
- package/bmad/bmm/workflows/3-solutioning/create-epics-and-stories/workflow.md +59 -0
- package/bmad/bmm/workflows/4-implementation/code-review/checklist.md +23 -0
- package/bmad/bmm/workflows/4-implementation/code-review/instructions.xml +227 -0
- package/bmad/bmm/workflows/4-implementation/code-review/workflow.yaml +51 -0
- package/bmad/bmm/workflows/4-implementation/correct-course/checklist.md +288 -0
- package/bmad/bmm/workflows/4-implementation/correct-course/instructions.md +206 -0
- package/bmad/bmm/workflows/4-implementation/correct-course/workflow.yaml +60 -0
- package/bmad/bmm/workflows/4-implementation/create-story/checklist.md +358 -0
- package/bmad/bmm/workflows/4-implementation/create-story/instructions.xml +345 -0
- package/bmad/bmm/workflows/4-implementation/create-story/template.md +49 -0
- package/bmad/bmm/workflows/4-implementation/create-story/workflow.yaml +61 -0
- package/bmad/bmm/workflows/4-implementation/dev-story/checklist.md +80 -0
- package/bmad/bmm/workflows/4-implementation/dev-story/instructions.xml +410 -0
- package/bmad/bmm/workflows/4-implementation/dev-story/workflow.yaml +27 -0
- package/bmad/bmm/workflows/4-implementation/retrospective/instructions.md +1443 -0
- package/bmad/bmm/workflows/4-implementation/retrospective/workflow.yaml +58 -0
- package/bmad/bmm/workflows/4-implementation/sprint-planning/checklist.md +33 -0
- package/bmad/bmm/workflows/4-implementation/sprint-planning/instructions.md +225 -0
- package/bmad/bmm/workflows/4-implementation/sprint-planning/sprint-status-template.yaml +55 -0
- package/bmad/bmm/workflows/4-implementation/sprint-planning/workflow.yaml +54 -0
- package/bmad/bmm/workflows/4-implementation/sprint-status/instructions.md +229 -0
- package/bmad/bmm/workflows/4-implementation/sprint-status/workflow.yaml +36 -0
- package/bmad/bmm/workflows/bmad-quick-flow/quick-dev/data/project-levels.yaml +59 -0
- package/bmad/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-01-mode-detection.md +156 -0
- package/bmad/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-02-context-gathering.md +120 -0
- package/bmad/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-03-execute.md +113 -0
- package/bmad/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-04-self-check.md +113 -0
- package/bmad/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-05-adversarial-review.md +106 -0
- package/bmad/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-06-resolve-findings.md +140 -0
- package/bmad/bmm/workflows/bmad-quick-flow/quick-dev/workflow.md +50 -0
- package/bmad/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-01-understand.md +189 -0
- package/bmad/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-02-investigate.md +144 -0
- package/bmad/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-03-generate.md +128 -0
- package/bmad/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-04-review.md +191 -0
- package/bmad/bmm/workflows/bmad-quick-flow/quick-spec/tech-spec-template.md +74 -0
- package/bmad/bmm/workflows/bmad-quick-flow/quick-spec/workflow.md +79 -0
- package/bmad/bmm/workflows/document-project/checklist.md +245 -0
- package/bmad/bmm/workflows/document-project/documentation-requirements.csv +12 -0
- package/bmad/bmm/workflows/document-project/instructions.md +221 -0
- package/bmad/bmm/workflows/document-project/templates/deep-dive-template.md +345 -0
- package/bmad/bmm/workflows/document-project/templates/index-template.md +169 -0
- package/bmad/bmm/workflows/document-project/templates/project-overview-template.md +103 -0
- package/bmad/bmm/workflows/document-project/templates/project-scan-report-schema.json +160 -0
- package/bmad/bmm/workflows/document-project/templates/source-tree-template.md +135 -0
- package/bmad/bmm/workflows/document-project/workflow.yaml +30 -0
- package/bmad/bmm/workflows/document-project/workflows/deep-dive-instructions.md +298 -0
- package/bmad/bmm/workflows/document-project/workflows/deep-dive.yaml +31 -0
- package/bmad/bmm/workflows/document-project/workflows/full-scan-instructions.md +1106 -0
- package/bmad/bmm/workflows/document-project/workflows/full-scan.yaml +31 -0
- package/bmad/bmm/workflows/excalidraw-diagrams/_shared/excalidraw-library.json +90 -0
- package/bmad/bmm/workflows/excalidraw-diagrams/_shared/excalidraw-templates.yaml +127 -0
- package/bmad/bmm/workflows/excalidraw-diagrams/create-dataflow/checklist.md +39 -0
- package/bmad/bmm/workflows/excalidraw-diagrams/create-dataflow/instructions.md +130 -0
- package/bmad/bmm/workflows/excalidraw-diagrams/create-dataflow/workflow.yaml +27 -0
- package/bmad/bmm/workflows/excalidraw-diagrams/create-diagram/checklist.md +43 -0
- package/bmad/bmm/workflows/excalidraw-diagrams/create-diagram/instructions.md +141 -0
- package/bmad/bmm/workflows/excalidraw-diagrams/create-diagram/workflow.yaml +27 -0
- package/bmad/bmm/workflows/excalidraw-diagrams/create-flowchart/checklist.md +49 -0
- package/bmad/bmm/workflows/excalidraw-diagrams/create-flowchart/instructions.md +241 -0
- package/bmad/bmm/workflows/excalidraw-diagrams/create-flowchart/workflow.yaml +27 -0
- package/bmad/bmm/workflows/excalidraw-diagrams/create-wireframe/checklist.md +38 -0
- package/bmad/bmm/workflows/excalidraw-diagrams/create-wireframe/instructions.md +133 -0
- package/bmad/bmm/workflows/excalidraw-diagrams/create-wireframe/workflow.yaml +27 -0
- package/bmad/bmm/workflows/testarch/atdd/atdd-checklist-template.md +363 -0
- package/bmad/bmm/workflows/testarch/atdd/checklist.md +374 -0
- package/bmad/bmm/workflows/testarch/atdd/instructions.md +806 -0
- package/bmad/bmm/workflows/testarch/atdd/workflow.yaml +47 -0
- package/bmad/bmm/workflows/testarch/automate/checklist.md +582 -0
- package/bmad/bmm/workflows/testarch/automate/instructions.md +1324 -0
- package/bmad/bmm/workflows/testarch/automate/workflow.yaml +54 -0
- package/bmad/bmm/workflows/testarch/ci/checklist.md +247 -0
- package/bmad/bmm/workflows/testarch/ci/github-actions-template.yaml +198 -0
- package/bmad/bmm/workflows/testarch/ci/gitlab-ci-template.yaml +149 -0
- package/bmad/bmm/workflows/testarch/ci/instructions.md +536 -0
- package/bmad/bmm/workflows/testarch/ci/workflow.yaml +47 -0
- package/bmad/bmm/workflows/testarch/framework/checklist.md +320 -0
- package/bmad/bmm/workflows/testarch/framework/instructions.md +481 -0
- package/bmad/bmm/workflows/testarch/framework/workflow.yaml +49 -0
- package/bmad/bmm/workflows/testarch/nfr-assess/checklist.md +407 -0
- package/bmad/bmm/workflows/testarch/nfr-assess/instructions.md +726 -0
- package/bmad/bmm/workflows/testarch/nfr-assess/nfr-report-template.md +461 -0
- package/bmad/bmm/workflows/testarch/nfr-assess/workflow.yaml +49 -0
- package/bmad/bmm/workflows/testarch/test-design/checklist.md +407 -0
- package/bmad/bmm/workflows/testarch/test-design/instructions.md +1158 -0
- package/bmad/bmm/workflows/testarch/test-design/test-design-architecture-template.md +213 -0
- package/bmad/bmm/workflows/testarch/test-design/test-design-qa-template.md +286 -0
- package/bmad/bmm/workflows/testarch/test-design/test-design-template.md +294 -0
- package/bmad/bmm/workflows/testarch/test-design/workflow.yaml +71 -0
- package/bmad/bmm/workflows/testarch/test-review/checklist.md +472 -0
- package/bmad/bmm/workflows/testarch/test-review/instructions.md +628 -0
- package/bmad/bmm/workflows/testarch/test-review/test-review-template.md +390 -0
- package/bmad/bmm/workflows/testarch/test-review/workflow.yaml +48 -0
- package/bmad/bmm/workflows/testarch/trace/checklist.md +642 -0
- package/bmad/bmm/workflows/testarch/trace/instructions.md +1030 -0
- package/bmad/bmm/workflows/testarch/trace/trace-template.md +675 -0
- package/bmad/bmm/workflows/testarch/trace/workflow.yaml +57 -0
- package/bmad/core/agents/bmad-master.agent.yaml +30 -0
- package/bmad/core/module-help.csv +11 -0
- package/bmad/core/module.yaml +25 -0
- package/bmad/core/resources/excalidraw/README.md +160 -0
- package/bmad/core/resources/excalidraw/excalidraw-helpers.md +127 -0
- package/bmad/core/resources/excalidraw/library-loader.md +50 -0
- package/bmad/core/resources/excalidraw/validate-json-instructions.md +79 -0
- package/bmad/core/tasks/bmad-help.md +62 -0
- package/bmad/core/tasks/editorial-review-prose.xml +91 -0
- package/bmad/core/tasks/editorial-review-structure.xml +198 -0
- package/bmad/core/tasks/index-docs.xml +65 -0
- package/bmad/core/tasks/review-adversarial-general.xml +48 -0
- package/bmad/core/tasks/shard-doc.xml +109 -0
- package/bmad/core/tasks/workflow.xml +235 -0
- package/bmad/core/workflows/advanced-elicitation/methods.csv +51 -0
- package/bmad/core/workflows/advanced-elicitation/workflow.xml +117 -0
- package/bmad/core/workflows/brainstorming/brain-methods.csv +62 -0
- package/bmad/core/workflows/brainstorming/steps/step-01-session-setup.md +197 -0
- package/bmad/core/workflows/brainstorming/steps/step-01b-continue.md +122 -0
- package/bmad/core/workflows/brainstorming/steps/step-02a-user-selected.md +225 -0
- package/bmad/core/workflows/brainstorming/steps/step-02b-ai-recommended.md +237 -0
- package/bmad/core/workflows/brainstorming/steps/step-02c-random-selection.md +209 -0
- package/bmad/core/workflows/brainstorming/steps/step-02d-progressive-flow.md +264 -0
- package/bmad/core/workflows/brainstorming/steps/step-03-technique-execution.md +399 -0
- package/bmad/core/workflows/brainstorming/steps/step-04-idea-organization.md +303 -0
- package/bmad/core/workflows/brainstorming/template.md +15 -0
- package/bmad/core/workflows/brainstorming/workflow.md +58 -0
- package/bmad/core/workflows/party-mode/steps/step-01-agent-loading.md +138 -0
- package/bmad/core/workflows/party-mode/steps/step-02-discussion-orchestration.md +187 -0
- package/bmad/core/workflows/party-mode/steps/step-03-graceful-exit.md +157 -0
- package/bmad/core/workflows/party-mode/workflow.md +194 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +26 -0
- package/dist/commands/doctor.d.ts +1 -0
- package/dist/commands/doctor.js +168 -0
- package/dist/commands/guide.d.ts +1 -0
- package/dist/commands/guide.js +19 -0
- package/dist/commands/implement.d.ts +1 -0
- package/dist/commands/implement.js +83 -0
- package/dist/commands/init.d.ts +6 -0
- package/dist/commands/init.js +67 -0
- package/dist/commands/plan.d.ts +5 -0
- package/dist/commands/plan.js +44 -0
- package/dist/commands/reset.d.ts +5 -0
- package/dist/commands/reset.js +35 -0
- package/dist/commands/resume.d.ts +1 -0
- package/dist/commands/resume.js +44 -0
- package/dist/commands/start.d.ts +5 -0
- package/dist/commands/start.js +54 -0
- package/dist/commands/status.d.ts +1 -0
- package/dist/commands/status.js +53 -0
- package/dist/commands/upgrade.d.ts +1 -0
- package/dist/commands/upgrade.js +34 -0
- package/dist/installer.d.ts +11 -0
- package/dist/installer.js +219 -0
- package/dist/transition.d.ts +52 -0
- package/dist/transition.js +656 -0
- package/dist/utils/config.d.ts +7 -0
- package/dist/utils/config.js +14 -0
- package/dist/utils/json.d.ts +7 -0
- package/dist/utils/json.js +26 -0
- package/dist/utils/logger.d.ts +3 -0
- package/dist/utils/logger.js +13 -0
- package/dist/utils/state.d.ts +29 -0
- package/dist/utils/state.js +78 -0
- package/dist/utils/validate.d.ts +4 -0
- package/dist/utils/validate.js +42 -0
- package/package.json +59 -0
- package/ralph/lib/circuit_breaker.sh +330 -0
- package/ralph/lib/date_utils.sh +53 -0
- package/ralph/lib/response_analyzer.sh +768 -0
- package/ralph/lib/timeout_utils.sh +145 -0
- package/ralph/ralph_loop.sh +1391 -0
- package/ralph/templates/AGENT.md +158 -0
- package/ralph/templates/PROMPT.md +292 -0
- package/ralph/templates/fix_plan.md +27 -0
- package/ralph/templates/specs/.gitkeep +2 -0
- package/slash-commands/advanced-elicitation.md +1 -0
- package/slash-commands/adversarial-review.md +1 -0
- package/slash-commands/analyst.md +1 -0
- package/slash-commands/architect.md +1 -0
- package/slash-commands/atdd.md +1 -0
- package/slash-commands/bmad-help.md +1 -0
- package/slash-commands/bmalph-implement.md +152 -0
- package/slash-commands/bmalph.md +1 -0
- package/slash-commands/brainstorm-project.md +1 -0
- package/slash-commands/brainstorming.md +1 -0
- package/slash-commands/continuous-integration.md +1 -0
- package/slash-commands/correct-course.md +1 -0
- package/slash-commands/create-architecture.md +1 -0
- package/slash-commands/create-brief.md +1 -0
- package/slash-commands/create-dataflow.md +1 -0
- package/slash-commands/create-diagram.md +1 -0
- package/slash-commands/create-epics-stories.md +1 -0
- package/slash-commands/create-flowchart.md +1 -0
- package/slash-commands/create-prd.md +1 -0
- package/slash-commands/create-story.md +1 -0
- package/slash-commands/create-ux.md +1 -0
- package/slash-commands/create-wireframe.md +1 -0
- package/slash-commands/dev.md +1 -0
- package/slash-commands/document-project.md +1 -0
- package/slash-commands/domain-research.md +1 -0
- package/slash-commands/editorial-prose.md +1 -0
- package/slash-commands/editorial-structure.md +1 -0
- package/slash-commands/execute-workflow.md +1 -0
- package/slash-commands/implementation-readiness.md +1 -0
- package/slash-commands/index-docs.md +1 -0
- package/slash-commands/market-research.md +1 -0
- package/slash-commands/nfr-assess.md +1 -0
- package/slash-commands/party-mode.md +1 -0
- package/slash-commands/pm.md +1 -0
- package/slash-commands/quick-dev.md +1 -0
- package/slash-commands/quick-flow-solo-dev.md +1 -0
- package/slash-commands/retrospective.md +1 -0
- package/slash-commands/shard-doc.md +1 -0
- package/slash-commands/sm.md +1 -0
- package/slash-commands/sprint-planning.md +1 -0
- package/slash-commands/sprint-status.md +1 -0
- package/slash-commands/tea.md +1 -0
- package/slash-commands/tech-spec.md +1 -0
- package/slash-commands/technical-research.md +1 -0
- package/slash-commands/test-automate.md +1 -0
- package/slash-commands/test-design.md +1 -0
- package/slash-commands/test-framework.md +1 -0
- package/slash-commands/test-review.md +1 -0
- package/slash-commands/test-trace.md +1 -0
- package/slash-commands/ux-designer.md +1 -0
- package/slash-commands/validate-architecture.md +1 -0
- package/slash-commands/validate-brief.md +1 -0
- package/slash-commands/validate-epics-stories.md +1 -0
- package/slash-commands/validate-prd.md +1 -0
- package/slash-commands/validate-story.md +1 -0
- package/slash-commands/validate-test-design.md +1 -0
- package/slash-commands/validate-ux.md +1 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { readFile } from "fs/promises";
|
|
2
|
+
/**
|
|
3
|
+
* Reads and parses a JSON file with proper error discrimination:
|
|
4
|
+
* - File not found → returns null
|
|
5
|
+
* - Parse error → throws
|
|
6
|
+
* - Permission error → throws
|
|
7
|
+
*/
|
|
8
|
+
export async function readJsonFile(path) {
|
|
9
|
+
let content;
|
|
10
|
+
try {
|
|
11
|
+
content = await readFile(path, "utf-8");
|
|
12
|
+
}
|
|
13
|
+
catch (err) {
|
|
14
|
+
if (err instanceof Error && "code" in err && err.code === "ENOENT") {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
throw err;
|
|
18
|
+
}
|
|
19
|
+
try {
|
|
20
|
+
return JSON.parse(content);
|
|
21
|
+
}
|
|
22
|
+
catch (err) {
|
|
23
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
24
|
+
throw new Error(`Invalid JSON in ${path}: ${message}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
let verbose = false;
|
|
3
|
+
export function setVerbose(value) {
|
|
4
|
+
verbose = value;
|
|
5
|
+
}
|
|
6
|
+
export function isVerbose() {
|
|
7
|
+
return verbose;
|
|
8
|
+
}
|
|
9
|
+
export function debug(message) {
|
|
10
|
+
if (verbose) {
|
|
11
|
+
console.log(chalk.dim(`[debug] ${message}`));
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface BmalphState {
|
|
2
|
+
currentPhase: number;
|
|
3
|
+
status: "planning" | "implementing" | "completed";
|
|
4
|
+
startedAt: string;
|
|
5
|
+
lastUpdated: string;
|
|
6
|
+
}
|
|
7
|
+
export interface PhaseCommand {
|
|
8
|
+
code: string;
|
|
9
|
+
name: string;
|
|
10
|
+
agent: string;
|
|
11
|
+
description: string;
|
|
12
|
+
required: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface PhaseInfo {
|
|
15
|
+
name: string;
|
|
16
|
+
agent: string;
|
|
17
|
+
commands: PhaseCommand[];
|
|
18
|
+
}
|
|
19
|
+
export declare function readState(projectDir: string): Promise<BmalphState | null>;
|
|
20
|
+
export declare function writeState(projectDir: string, state: BmalphState): Promise<void>;
|
|
21
|
+
export declare function getPhaseLabel(phase: number): string;
|
|
22
|
+
export declare function getPhaseInfo(phase: number): PhaseInfo;
|
|
23
|
+
export interface RalphStatus {
|
|
24
|
+
loopCount: number;
|
|
25
|
+
status: "running" | "blocked" | "completed" | "not_started";
|
|
26
|
+
tasksCompleted: number;
|
|
27
|
+
tasksTotal: number;
|
|
28
|
+
}
|
|
29
|
+
export declare function readRalphStatus(projectDir: string): Promise<RalphStatus>;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { writeFile, mkdir, rename } from "fs/promises";
|
|
2
|
+
import { join } from "path";
|
|
3
|
+
import { readJsonFile } from "./json.js";
|
|
4
|
+
import { validateState } from "./validate.js";
|
|
5
|
+
const STATE_DIR = "bmalph/state";
|
|
6
|
+
export async function readState(projectDir) {
|
|
7
|
+
const data = await readJsonFile(join(projectDir, STATE_DIR, "current-phase.json"));
|
|
8
|
+
if (data === null)
|
|
9
|
+
return null;
|
|
10
|
+
return validateState(data);
|
|
11
|
+
}
|
|
12
|
+
export async function writeState(projectDir, state) {
|
|
13
|
+
await mkdir(join(projectDir, STATE_DIR), { recursive: true });
|
|
14
|
+
const target = join(projectDir, STATE_DIR, "current-phase.json");
|
|
15
|
+
const tmp = target + ".tmp";
|
|
16
|
+
await writeFile(tmp, JSON.stringify(state, null, 2) + "\n");
|
|
17
|
+
await rename(tmp, target);
|
|
18
|
+
}
|
|
19
|
+
export function getPhaseLabel(phase) {
|
|
20
|
+
const labels = {
|
|
21
|
+
1: "Analysis",
|
|
22
|
+
2: "Planning",
|
|
23
|
+
3: "Solutioning",
|
|
24
|
+
4: "Implementation",
|
|
25
|
+
};
|
|
26
|
+
return labels[phase] ?? "Unknown";
|
|
27
|
+
}
|
|
28
|
+
export function getPhaseInfo(phase) {
|
|
29
|
+
const info = {
|
|
30
|
+
1: {
|
|
31
|
+
name: "Analysis",
|
|
32
|
+
agent: "Analyst",
|
|
33
|
+
commands: [
|
|
34
|
+
{ code: "BP", name: "Brainstorm Project", agent: "analyst", description: "Expert guided facilitation through brainstorming techniques", required: false },
|
|
35
|
+
{ code: "MR", name: "Market Research", agent: "analyst", description: "Market analysis, competitive landscape, customer needs", required: false },
|
|
36
|
+
{ code: "DR", name: "Domain Research", agent: "analyst", description: "Industry domain deep dive, subject matter expertise", required: false },
|
|
37
|
+
{ code: "TR", name: "Technical Research", agent: "analyst", description: "Technical feasibility, architecture options", required: false },
|
|
38
|
+
{ code: "CB", name: "Create Brief", agent: "analyst", description: "Guided experience to nail down your product idea", required: false },
|
|
39
|
+
{ code: "VB", name: "Validate Brief", agent: "analyst", description: "Validates product brief completeness", required: false },
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
2: {
|
|
43
|
+
name: "Planning",
|
|
44
|
+
agent: "PM (John)",
|
|
45
|
+
commands: [
|
|
46
|
+
{ code: "CP", name: "Create PRD", agent: "pm", description: "Expert led facilitation to produce your PRD", required: true },
|
|
47
|
+
{ code: "VP", name: "Validate PRD", agent: "pm", description: "Validate PRD is comprehensive and cohesive", required: false },
|
|
48
|
+
{ code: "CU", name: "Create UX", agent: "ux-designer", description: "Guidance through realizing the plan for your UX", required: false },
|
|
49
|
+
{ code: "VU", name: "Validate UX", agent: "ux-designer", description: "Validates UX design deliverables", required: false },
|
|
50
|
+
],
|
|
51
|
+
},
|
|
52
|
+
3: {
|
|
53
|
+
name: "Solutioning",
|
|
54
|
+
agent: "Architect",
|
|
55
|
+
commands: [
|
|
56
|
+
{ code: "CA", name: "Create Architecture", agent: "architect", description: "Guided workflow to document technical decisions", required: true },
|
|
57
|
+
{ code: "VA", name: "Validate Architecture", agent: "architect", description: "Validates architecture completeness", required: false },
|
|
58
|
+
{ code: "CE", name: "Create Epics and Stories", agent: "pm", description: "Create the epics and stories listing", required: true },
|
|
59
|
+
{ code: "VE", name: "Validate Epics and Stories", agent: "pm", description: "Validates epics and stories completeness", required: false },
|
|
60
|
+
{ code: "TD", name: "Test Design", agent: "tea", description: "Create comprehensive test scenarios", required: false },
|
|
61
|
+
{ code: "IR", name: "Implementation Readiness", agent: "architect", description: "Ensure PRD, UX, architecture, and stories are aligned", required: true },
|
|
62
|
+
],
|
|
63
|
+
},
|
|
64
|
+
4: {
|
|
65
|
+
name: "Implementation",
|
|
66
|
+
agent: "Developer (Amelia)",
|
|
67
|
+
commands: [],
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
return info[phase] ?? { name: "Unknown", agent: "Unknown", commands: [] };
|
|
71
|
+
}
|
|
72
|
+
export async function readRalphStatus(projectDir) {
|
|
73
|
+
const data = await readJsonFile(join(projectDir, ".ralph/status.json"));
|
|
74
|
+
if (data === null) {
|
|
75
|
+
return { loopCount: 0, status: "not_started", tasksCompleted: 0, tasksTotal: 0 };
|
|
76
|
+
}
|
|
77
|
+
return data;
|
|
78
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
const VALID_STATUSES = ["planning", "implementing", "completed"];
|
|
2
|
+
function assertObject(data, label) {
|
|
3
|
+
if (data === null || data === undefined || typeof data !== "object" || Array.isArray(data)) {
|
|
4
|
+
throw new Error(`${label}: expected an object`);
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
export function validateConfig(data) {
|
|
8
|
+
assertObject(data, "config");
|
|
9
|
+
if (typeof data.name !== "string") {
|
|
10
|
+
throw new Error("config.name must be a string");
|
|
11
|
+
}
|
|
12
|
+
if (typeof data.createdAt !== "string") {
|
|
13
|
+
throw new Error("config.createdAt must be a string");
|
|
14
|
+
}
|
|
15
|
+
const description = typeof data.description === "string" ? data.description : "";
|
|
16
|
+
return {
|
|
17
|
+
name: data.name,
|
|
18
|
+
description,
|
|
19
|
+
createdAt: data.createdAt,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export function validateState(data) {
|
|
23
|
+
assertObject(data, "state");
|
|
24
|
+
if (typeof data.currentPhase !== "number") {
|
|
25
|
+
throw new Error("state.currentPhase must be a number");
|
|
26
|
+
}
|
|
27
|
+
if (typeof data.status !== "string" || !VALID_STATUSES.includes(data.status)) {
|
|
28
|
+
throw new Error(`state.status must be one of: ${VALID_STATUSES.join(", ")}`);
|
|
29
|
+
}
|
|
30
|
+
if (typeof data.startedAt !== "string") {
|
|
31
|
+
throw new Error("state.startedAt must be a string");
|
|
32
|
+
}
|
|
33
|
+
if (typeof data.lastUpdated !== "string") {
|
|
34
|
+
throw new Error("state.lastUpdated must be a string");
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
currentPhase: data.currentPhase,
|
|
38
|
+
status: data.status,
|
|
39
|
+
startedAt: data.startedAt,
|
|
40
|
+
lastUpdated: data.lastUpdated,
|
|
41
|
+
};
|
|
42
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "bmalph",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Unified AI Development Framework - BMAD phases with Ralph execution loop for Claude Code",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"bmalph": "./bin/bmalph.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"prepare": "tsc",
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"test": "vitest run",
|
|
13
|
+
"test:watch": "vitest",
|
|
14
|
+
"lint": "eslint src tests",
|
|
15
|
+
"format": "prettier --write .",
|
|
16
|
+
"prepublishOnly": "npm run lint && npm run build && npm test"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"claude",
|
|
20
|
+
"ai",
|
|
21
|
+
"development",
|
|
22
|
+
"framework",
|
|
23
|
+
"agents"
|
|
24
|
+
],
|
|
25
|
+
"author": "Lars Cowe",
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "https://github.com/LarsCowe/bmalph.git"
|
|
30
|
+
},
|
|
31
|
+
"homepage": "https://github.com/LarsCowe/bmalph#readme",
|
|
32
|
+
"bugs": {
|
|
33
|
+
"url": "https://github.com/LarsCowe/bmalph/issues"
|
|
34
|
+
},
|
|
35
|
+
"engines": {
|
|
36
|
+
"node": ">=20.0.0"
|
|
37
|
+
},
|
|
38
|
+
"files": [
|
|
39
|
+
"bin/",
|
|
40
|
+
"dist/",
|
|
41
|
+
"bmad/",
|
|
42
|
+
"ralph/",
|
|
43
|
+
"slash-commands/"
|
|
44
|
+
],
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"chalk": "^5.6.2",
|
|
47
|
+
"commander": "^14.0.2",
|
|
48
|
+
"inquirer": "^13.2.1"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@eslint/js": "^9.39.2",
|
|
52
|
+
"@types/node": "^25.0.10",
|
|
53
|
+
"eslint": "^9.39.2",
|
|
54
|
+
"prettier": "^3.8.1",
|
|
55
|
+
"typescript": "^5.9.3",
|
|
56
|
+
"typescript-eslint": "^8.53.1",
|
|
57
|
+
"vitest": "^4.0.18"
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Circuit Breaker Component for Ralph
|
|
3
|
+
# Prevents runaway token consumption by detecting stagnation
|
|
4
|
+
# Based on Michael Nygard's "Release It!" pattern
|
|
5
|
+
|
|
6
|
+
# Source date utilities for cross-platform compatibility
|
|
7
|
+
source "$(dirname "${BASH_SOURCE[0]}")/date_utils.sh"
|
|
8
|
+
|
|
9
|
+
# Circuit Breaker States
|
|
10
|
+
CB_STATE_CLOSED="CLOSED" # Normal operation, progress detected
|
|
11
|
+
CB_STATE_HALF_OPEN="HALF_OPEN" # Monitoring mode, checking for recovery
|
|
12
|
+
CB_STATE_OPEN="OPEN" # Failure detected, execution halted
|
|
13
|
+
|
|
14
|
+
# Circuit Breaker Configuration
|
|
15
|
+
# Use RALPH_DIR if set by main script, otherwise default to .ralph
|
|
16
|
+
RALPH_DIR="${RALPH_DIR:-.ralph}"
|
|
17
|
+
CB_STATE_FILE="$RALPH_DIR/.circuit_breaker_state"
|
|
18
|
+
CB_HISTORY_FILE="$RALPH_DIR/.circuit_breaker_history"
|
|
19
|
+
CB_NO_PROGRESS_THRESHOLD=3 # Open circuit after N loops with no progress
|
|
20
|
+
CB_SAME_ERROR_THRESHOLD=5 # Open circuit after N loops with same error
|
|
21
|
+
CB_OUTPUT_DECLINE_THRESHOLD=70 # Open circuit if output declines by >70%
|
|
22
|
+
|
|
23
|
+
# Colors
|
|
24
|
+
RED='\033[0;31m'
|
|
25
|
+
GREEN='\033[0;32m'
|
|
26
|
+
YELLOW='\033[1;33m'
|
|
27
|
+
BLUE='\033[0;34m'
|
|
28
|
+
NC='\033[0m'
|
|
29
|
+
|
|
30
|
+
# Initialize circuit breaker
|
|
31
|
+
init_circuit_breaker() {
|
|
32
|
+
# Check if state file exists and is valid JSON
|
|
33
|
+
if [[ -f "$CB_STATE_FILE" ]]; then
|
|
34
|
+
if ! jq '.' "$CB_STATE_FILE" > /dev/null 2>&1; then
|
|
35
|
+
# Corrupted, recreate
|
|
36
|
+
rm -f "$CB_STATE_FILE"
|
|
37
|
+
fi
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
if [[ ! -f "$CB_STATE_FILE" ]]; then
|
|
41
|
+
cat > "$CB_STATE_FILE" << EOF
|
|
42
|
+
{
|
|
43
|
+
"state": "$CB_STATE_CLOSED",
|
|
44
|
+
"last_change": "$(get_iso_timestamp)",
|
|
45
|
+
"consecutive_no_progress": 0,
|
|
46
|
+
"consecutive_same_error": 0,
|
|
47
|
+
"last_progress_loop": 0,
|
|
48
|
+
"total_opens": 0,
|
|
49
|
+
"reason": ""
|
|
50
|
+
}
|
|
51
|
+
EOF
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
# Check if history file exists and is valid JSON
|
|
55
|
+
if [[ -f "$CB_HISTORY_FILE" ]]; then
|
|
56
|
+
if ! jq '.' "$CB_HISTORY_FILE" > /dev/null 2>&1; then
|
|
57
|
+
# Corrupted, recreate
|
|
58
|
+
rm -f "$CB_HISTORY_FILE"
|
|
59
|
+
fi
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
if [[ ! -f "$CB_HISTORY_FILE" ]]; then
|
|
63
|
+
echo '[]' > "$CB_HISTORY_FILE"
|
|
64
|
+
fi
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
# Get current circuit breaker state
|
|
68
|
+
get_circuit_state() {
|
|
69
|
+
if [[ ! -f "$CB_STATE_FILE" ]]; then
|
|
70
|
+
echo "$CB_STATE_CLOSED"
|
|
71
|
+
return
|
|
72
|
+
fi
|
|
73
|
+
|
|
74
|
+
jq -r '.state' "$CB_STATE_FILE" 2>/dev/null || echo "$CB_STATE_CLOSED"
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
# Check if circuit breaker allows execution
|
|
78
|
+
can_execute() {
|
|
79
|
+
local state=$(get_circuit_state)
|
|
80
|
+
|
|
81
|
+
if [[ "$state" == "$CB_STATE_OPEN" ]]; then
|
|
82
|
+
return 1 # Circuit is open, cannot execute
|
|
83
|
+
else
|
|
84
|
+
return 0 # Circuit is closed or half-open, can execute
|
|
85
|
+
fi
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
# Record loop execution result
|
|
89
|
+
record_loop_result() {
|
|
90
|
+
local loop_number=$1
|
|
91
|
+
local files_changed=$2
|
|
92
|
+
local has_errors=$3
|
|
93
|
+
local output_length=$4
|
|
94
|
+
|
|
95
|
+
init_circuit_breaker
|
|
96
|
+
|
|
97
|
+
local state_data=$(cat "$CB_STATE_FILE")
|
|
98
|
+
local current_state=$(echo "$state_data" | jq -r '.state')
|
|
99
|
+
local consecutive_no_progress=$(echo "$state_data" | jq -r '.consecutive_no_progress' | tr -d '[:space:]')
|
|
100
|
+
local consecutive_same_error=$(echo "$state_data" | jq -r '.consecutive_same_error' | tr -d '[:space:]')
|
|
101
|
+
local last_progress_loop=$(echo "$state_data" | jq -r '.last_progress_loop' | tr -d '[:space:]')
|
|
102
|
+
|
|
103
|
+
# Ensure integers
|
|
104
|
+
consecutive_no_progress=$((consecutive_no_progress + 0))
|
|
105
|
+
consecutive_same_error=$((consecutive_same_error + 0))
|
|
106
|
+
last_progress_loop=$((last_progress_loop + 0))
|
|
107
|
+
|
|
108
|
+
# Detect progress
|
|
109
|
+
local has_progress=false
|
|
110
|
+
if [[ $files_changed -gt 0 ]]; then
|
|
111
|
+
has_progress=true
|
|
112
|
+
consecutive_no_progress=0
|
|
113
|
+
last_progress_loop=$loop_number
|
|
114
|
+
else
|
|
115
|
+
consecutive_no_progress=$((consecutive_no_progress + 1))
|
|
116
|
+
fi
|
|
117
|
+
|
|
118
|
+
# Detect same error repetition
|
|
119
|
+
if [[ "$has_errors" == "true" ]]; then
|
|
120
|
+
consecutive_same_error=$((consecutive_same_error + 1))
|
|
121
|
+
else
|
|
122
|
+
consecutive_same_error=0
|
|
123
|
+
fi
|
|
124
|
+
|
|
125
|
+
# Determine new state and reason
|
|
126
|
+
local new_state="$current_state"
|
|
127
|
+
local reason=""
|
|
128
|
+
|
|
129
|
+
# State transitions
|
|
130
|
+
case $current_state in
|
|
131
|
+
"$CB_STATE_CLOSED")
|
|
132
|
+
# Normal operation - check for failure conditions
|
|
133
|
+
if [[ $consecutive_no_progress -ge $CB_NO_PROGRESS_THRESHOLD ]]; then
|
|
134
|
+
new_state="$CB_STATE_OPEN"
|
|
135
|
+
reason="No progress detected in $consecutive_no_progress consecutive loops"
|
|
136
|
+
elif [[ $consecutive_same_error -ge $CB_SAME_ERROR_THRESHOLD ]]; then
|
|
137
|
+
new_state="$CB_STATE_OPEN"
|
|
138
|
+
reason="Same error repeated in $consecutive_same_error consecutive loops"
|
|
139
|
+
elif [[ $consecutive_no_progress -ge 2 ]]; then
|
|
140
|
+
new_state="$CB_STATE_HALF_OPEN"
|
|
141
|
+
reason="Monitoring: $consecutive_no_progress loops without progress"
|
|
142
|
+
fi
|
|
143
|
+
;;
|
|
144
|
+
|
|
145
|
+
"$CB_STATE_HALF_OPEN")
|
|
146
|
+
# Monitoring mode - either recover or fail
|
|
147
|
+
if [[ "$has_progress" == "true" ]]; then
|
|
148
|
+
new_state="$CB_STATE_CLOSED"
|
|
149
|
+
reason="Progress detected, circuit recovered"
|
|
150
|
+
elif [[ $consecutive_no_progress -ge $CB_NO_PROGRESS_THRESHOLD ]]; then
|
|
151
|
+
new_state="$CB_STATE_OPEN"
|
|
152
|
+
reason="No recovery, opening circuit after $consecutive_no_progress loops"
|
|
153
|
+
fi
|
|
154
|
+
;;
|
|
155
|
+
|
|
156
|
+
"$CB_STATE_OPEN")
|
|
157
|
+
# Circuit is open - stays open (manual intervention required)
|
|
158
|
+
reason="Circuit breaker is open, execution halted"
|
|
159
|
+
;;
|
|
160
|
+
esac
|
|
161
|
+
|
|
162
|
+
# Update state file
|
|
163
|
+
local total_opens=$(echo "$state_data" | jq -r '.total_opens' | tr -d '[:space:]')
|
|
164
|
+
total_opens=$((total_opens + 0))
|
|
165
|
+
if [[ "$new_state" == "$CB_STATE_OPEN" && "$current_state" != "$CB_STATE_OPEN" ]]; then
|
|
166
|
+
total_opens=$((total_opens + 1))
|
|
167
|
+
fi
|
|
168
|
+
|
|
169
|
+
cat > "$CB_STATE_FILE" << EOF
|
|
170
|
+
{
|
|
171
|
+
"state": "$new_state",
|
|
172
|
+
"last_change": "$(get_iso_timestamp)",
|
|
173
|
+
"consecutive_no_progress": $consecutive_no_progress,
|
|
174
|
+
"consecutive_same_error": $consecutive_same_error,
|
|
175
|
+
"last_progress_loop": $last_progress_loop,
|
|
176
|
+
"total_opens": $total_opens,
|
|
177
|
+
"reason": "$reason",
|
|
178
|
+
"current_loop": $loop_number
|
|
179
|
+
}
|
|
180
|
+
EOF
|
|
181
|
+
|
|
182
|
+
# Log state transition
|
|
183
|
+
if [[ "$new_state" != "$current_state" ]]; then
|
|
184
|
+
log_circuit_transition "$current_state" "$new_state" "$reason" "$loop_number"
|
|
185
|
+
fi
|
|
186
|
+
|
|
187
|
+
# Return exit code based on new state
|
|
188
|
+
if [[ "$new_state" == "$CB_STATE_OPEN" ]]; then
|
|
189
|
+
return 1 # Circuit opened, signal to stop
|
|
190
|
+
else
|
|
191
|
+
return 0 # Can continue
|
|
192
|
+
fi
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
# Log circuit breaker state transitions
|
|
196
|
+
log_circuit_transition() {
|
|
197
|
+
local from_state=$1
|
|
198
|
+
local to_state=$2
|
|
199
|
+
local reason=$3
|
|
200
|
+
local loop_number=$4
|
|
201
|
+
|
|
202
|
+
local history=$(cat "$CB_HISTORY_FILE")
|
|
203
|
+
local transition="{
|
|
204
|
+
\"timestamp\": \"$(get_iso_timestamp)\",
|
|
205
|
+
\"loop\": $loop_number,
|
|
206
|
+
\"from_state\": \"$from_state\",
|
|
207
|
+
\"to_state\": \"$to_state\",
|
|
208
|
+
\"reason\": \"$reason\"
|
|
209
|
+
}"
|
|
210
|
+
|
|
211
|
+
history=$(echo "$history" | jq ". += [$transition]")
|
|
212
|
+
echo "$history" > "$CB_HISTORY_FILE"
|
|
213
|
+
|
|
214
|
+
# Console log with colors
|
|
215
|
+
case $to_state in
|
|
216
|
+
"$CB_STATE_OPEN")
|
|
217
|
+
echo -e "${RED}🚨 CIRCUIT BREAKER OPENED${NC}"
|
|
218
|
+
echo -e "${RED}Reason: $reason${NC}"
|
|
219
|
+
;;
|
|
220
|
+
"$CB_STATE_HALF_OPEN")
|
|
221
|
+
echo -e "${YELLOW}⚠️ CIRCUIT BREAKER: Monitoring Mode${NC}"
|
|
222
|
+
echo -e "${YELLOW}Reason: $reason${NC}"
|
|
223
|
+
;;
|
|
224
|
+
"$CB_STATE_CLOSED")
|
|
225
|
+
echo -e "${GREEN}✅ CIRCUIT BREAKER: Normal Operation${NC}"
|
|
226
|
+
echo -e "${GREEN}Reason: $reason${NC}"
|
|
227
|
+
;;
|
|
228
|
+
esac
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
# Display circuit breaker status
|
|
232
|
+
show_circuit_status() {
|
|
233
|
+
init_circuit_breaker
|
|
234
|
+
|
|
235
|
+
local state_data=$(cat "$CB_STATE_FILE")
|
|
236
|
+
local state=$(echo "$state_data" | jq -r '.state')
|
|
237
|
+
local reason=$(echo "$state_data" | jq -r '.reason')
|
|
238
|
+
local no_progress=$(echo "$state_data" | jq -r '.consecutive_no_progress')
|
|
239
|
+
local last_progress=$(echo "$state_data" | jq -r '.last_progress_loop')
|
|
240
|
+
local current_loop=$(echo "$state_data" | jq -r '.current_loop')
|
|
241
|
+
local total_opens=$(echo "$state_data" | jq -r '.total_opens')
|
|
242
|
+
|
|
243
|
+
local color=""
|
|
244
|
+
local status_icon=""
|
|
245
|
+
|
|
246
|
+
case $state in
|
|
247
|
+
"$CB_STATE_CLOSED")
|
|
248
|
+
color=$GREEN
|
|
249
|
+
status_icon="✅"
|
|
250
|
+
;;
|
|
251
|
+
"$CB_STATE_HALF_OPEN")
|
|
252
|
+
color=$YELLOW
|
|
253
|
+
status_icon="⚠️ "
|
|
254
|
+
;;
|
|
255
|
+
"$CB_STATE_OPEN")
|
|
256
|
+
color=$RED
|
|
257
|
+
status_icon="🚨"
|
|
258
|
+
;;
|
|
259
|
+
esac
|
|
260
|
+
|
|
261
|
+
echo -e "${color}╔════════════════════════════════════════════════════════════╗${NC}"
|
|
262
|
+
echo -e "${color}║ Circuit Breaker Status ║${NC}"
|
|
263
|
+
echo -e "${color}╚════════════════════════════════════════════════════════════╝${NC}"
|
|
264
|
+
echo -e "${color}State:${NC} $status_icon $state"
|
|
265
|
+
echo -e "${color}Reason:${NC} $reason"
|
|
266
|
+
echo -e "${color}Loops since progress:${NC} $no_progress"
|
|
267
|
+
echo -e "${color}Last progress:${NC} Loop #$last_progress"
|
|
268
|
+
echo -e "${color}Current loop:${NC} #$current_loop"
|
|
269
|
+
echo -e "${color}Total opens:${NC} $total_opens"
|
|
270
|
+
echo ""
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
# Reset circuit breaker (for manual intervention)
|
|
274
|
+
reset_circuit_breaker() {
|
|
275
|
+
local reason=${1:-"Manual reset"}
|
|
276
|
+
|
|
277
|
+
cat > "$CB_STATE_FILE" << EOF
|
|
278
|
+
{
|
|
279
|
+
"state": "$CB_STATE_CLOSED",
|
|
280
|
+
"last_change": "$(get_iso_timestamp)",
|
|
281
|
+
"consecutive_no_progress": 0,
|
|
282
|
+
"consecutive_same_error": 0,
|
|
283
|
+
"last_progress_loop": 0,
|
|
284
|
+
"total_opens": 0,
|
|
285
|
+
"reason": "$reason"
|
|
286
|
+
}
|
|
287
|
+
EOF
|
|
288
|
+
|
|
289
|
+
echo -e "${GREEN}✅ Circuit breaker reset to CLOSED state${NC}"
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
# Check if loop should halt (used in main loop)
|
|
293
|
+
should_halt_execution() {
|
|
294
|
+
local state=$(get_circuit_state)
|
|
295
|
+
|
|
296
|
+
if [[ "$state" == "$CB_STATE_OPEN" ]]; then
|
|
297
|
+
show_circuit_status
|
|
298
|
+
echo ""
|
|
299
|
+
echo -e "${RED}╔════════════════════════════════════════════════════════════╗${NC}"
|
|
300
|
+
echo -e "${RED}║ EXECUTION HALTED: Circuit Breaker Opened ║${NC}"
|
|
301
|
+
echo -e "${RED}╚════════════════════════════════════════════════════════════╝${NC}"
|
|
302
|
+
echo ""
|
|
303
|
+
echo -e "${YELLOW}Ralph has detected that no progress is being made.${NC}"
|
|
304
|
+
echo ""
|
|
305
|
+
echo -e "${YELLOW}Possible reasons:${NC}"
|
|
306
|
+
echo " • Project may be complete (check .ralph/@fix_plan.md)"
|
|
307
|
+
echo " • Claude may be stuck on an error"
|
|
308
|
+
echo " • .ralph/PROMPT.md may need clarification"
|
|
309
|
+
echo " • Manual intervention may be required"
|
|
310
|
+
echo ""
|
|
311
|
+
echo -e "${YELLOW}To continue:${NC}"
|
|
312
|
+
echo " 1. Review recent logs: tail -20 .ralph/logs/ralph.log"
|
|
313
|
+
echo " 2. Check Claude output: ls -lt .ralph/logs/claude_output_*.log | head -1"
|
|
314
|
+
echo " 3. Update .ralph/@fix_plan.md if needed"
|
|
315
|
+
echo " 4. Reset circuit breaker: ralph --reset-circuit"
|
|
316
|
+
echo ""
|
|
317
|
+
return 0 # Signal to halt
|
|
318
|
+
else
|
|
319
|
+
return 1 # Can continue
|
|
320
|
+
fi
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
# Export functions
|
|
324
|
+
export -f init_circuit_breaker
|
|
325
|
+
export -f get_circuit_state
|
|
326
|
+
export -f can_execute
|
|
327
|
+
export -f record_loop_result
|
|
328
|
+
export -f show_circuit_status
|
|
329
|
+
export -f reset_circuit_breaker
|
|
330
|
+
export -f should_halt_execution
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
# date_utils.sh - Cross-platform date utility functions
|
|
4
|
+
# Provides consistent date formatting and arithmetic across GNU (Linux) and BSD (macOS) systems
|
|
5
|
+
|
|
6
|
+
# Get current timestamp in ISO 8601 format with seconds precision
|
|
7
|
+
# Returns: YYYY-MM-DDTHH:MM:SS+00:00 format
|
|
8
|
+
get_iso_timestamp() {
|
|
9
|
+
local os_type
|
|
10
|
+
os_type=$(uname)
|
|
11
|
+
|
|
12
|
+
if [[ "$os_type" == "Darwin" ]]; then
|
|
13
|
+
# macOS (BSD date)
|
|
14
|
+
# Use manual formatting and add colon to timezone offset
|
|
15
|
+
date -u +"%Y-%m-%dT%H:%M:%S%z" | sed 's/\(..\)$/:\1/'
|
|
16
|
+
else
|
|
17
|
+
# Linux (GNU date) - use -u flag for UTC
|
|
18
|
+
date -u -Iseconds
|
|
19
|
+
fi
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
# Get time component (HH:MM:SS) for one hour from now
|
|
23
|
+
# Returns: HH:MM:SS format
|
|
24
|
+
get_next_hour_time() {
|
|
25
|
+
local os_type
|
|
26
|
+
os_type=$(uname)
|
|
27
|
+
|
|
28
|
+
if [[ "$os_type" == "Darwin" ]]; then
|
|
29
|
+
# macOS (BSD date) - use -v flag for date arithmetic
|
|
30
|
+
date -v+1H '+%H:%M:%S'
|
|
31
|
+
else
|
|
32
|
+
# Linux (GNU date) - use -d flag for date arithmetic
|
|
33
|
+
date -d '+1 hour' '+%H:%M:%S'
|
|
34
|
+
fi
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
# Get current timestamp in a basic format (fallback)
|
|
38
|
+
# Returns: YYYY-MM-DD HH:MM:SS format
|
|
39
|
+
get_basic_timestamp() {
|
|
40
|
+
date '+%Y-%m-%d %H:%M:%S'
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
# Get current Unix epoch time in seconds
|
|
44
|
+
# Returns: Integer seconds since 1970-01-01 00:00:00 UTC
|
|
45
|
+
get_epoch_seconds() {
|
|
46
|
+
date +%s
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
# Export functions for use in other scripts
|
|
50
|
+
export -f get_iso_timestamp
|
|
51
|
+
export -f get_next_hour_time
|
|
52
|
+
export -f get_basic_timestamp
|
|
53
|
+
export -f get_epoch_seconds
|