bmalph 1.0.0 → 2.2.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/LICENSE +21 -0
- package/README.md +398 -217
- package/bmad/bmm/agents/analyst.agent.yaml +43 -36
- package/bmad/bmm/agents/architect.agent.yaml +29 -28
- package/bmad/bmm/agents/dev.agent.yaml +38 -38
- package/bmad/bmm/agents/pm.agent.yaml +44 -46
- package/bmad/bmm/agents/qa.agent.yaml +58 -0
- package/bmad/bmm/agents/quick-flow-solo-dev.agent.yaml +32 -32
- package/bmad/bmm/agents/sm.agent.yaml +37 -36
- package/bmad/bmm/agents/tech-writer/tech-writer-sidecar/documentation-standards.md +223 -223
- package/bmad/bmm/agents/tech-writer/tech-writer.agent.yaml +46 -45
- package/bmad/bmm/agents/ux-designer.agent.yaml +27 -26
- package/bmad/bmm/data/project-context-template.md +26 -26
- package/bmad/bmm/module-help.csv +31 -31
- package/bmad/bmm/module.yaml +50 -44
- package/bmad/bmm/teams/default-party.csv +20 -21
- package/bmad/bmm/teams/team-fullstack.yaml +12 -12
- package/bmad/bmm/workflows/1-analysis/create-product-brief/product-brief.template.md +10 -10
- package/bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-01-init.md +177 -177
- package/bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-01b-continue.md +161 -161
- package/bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-02-vision.md +199 -199
- package/bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-03-users.md +202 -202
- package/bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-04-metrics.md +205 -205
- package/bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-05-scope.md +219 -219
- package/bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-06-complete.md +162 -162
- package/bmad/bmm/workflows/1-analysis/create-product-brief/workflow.md +57 -58
- package/bmad/bmm/workflows/1-analysis/research/domain-steps/step-01-init.md +137 -137
- package/bmad/bmm/workflows/1-analysis/research/domain-steps/step-02-domain-analysis.md +229 -229
- package/bmad/bmm/workflows/1-analysis/research/domain-steps/step-03-competitive-landscape.md +238 -238
- package/bmad/bmm/workflows/1-analysis/research/domain-steps/step-04-regulatory-focus.md +206 -206
- package/bmad/bmm/workflows/1-analysis/research/domain-steps/step-05-technical-trends.md +234 -234
- package/bmad/bmm/workflows/1-analysis/research/domain-steps/step-06-research-synthesis.md +443 -443
- package/bmad/bmm/workflows/1-analysis/research/market-steps/step-01-init.md +182 -182
- package/bmad/bmm/workflows/1-analysis/research/market-steps/step-02-customer-behavior.md +237 -237
- package/bmad/bmm/workflows/1-analysis/research/market-steps/step-03-customer-pain-points.md +249 -249
- package/bmad/bmm/workflows/1-analysis/research/market-steps/step-04-customer-decisions.md +259 -259
- package/bmad/bmm/workflows/1-analysis/research/market-steps/step-05-competitive-analysis.md +177 -177
- package/bmad/bmm/workflows/1-analysis/research/market-steps/step-06-research-completion.md +475 -475
- package/bmad/bmm/workflows/1-analysis/research/research.template.md +29 -29
- package/bmad/bmm/workflows/1-analysis/research/technical-steps/step-01-init.md +137 -137
- package/bmad/bmm/workflows/1-analysis/research/technical-steps/step-02-technical-overview.md +239 -239
- package/bmad/bmm/workflows/1-analysis/research/technical-steps/step-03-integration-patterns.md +248 -248
- package/bmad/bmm/workflows/1-analysis/research/technical-steps/step-04-architectural-patterns.md +202 -202
- package/bmad/bmm/workflows/1-analysis/research/technical-steps/step-05-implementation-research.md +233 -239
- package/bmad/bmm/workflows/1-analysis/research/technical-steps/step-06-research-synthesis.md +486 -486
- package/bmad/bmm/workflows/1-analysis/research/workflow-domain-research.md +54 -0
- package/bmad/bmm/workflows/1-analysis/research/workflow-market-research.md +54 -0
- package/bmad/bmm/workflows/1-analysis/research/workflow-technical-research.md +54 -0
- package/bmad/bmm/workflows/2-plan-workflows/{prd → create-prd}/data/domain-complexity.csv +14 -12
- package/bmad/bmm/workflows/2-plan-workflows/{prd → create-prd}/data/prd-purpose.md +197 -197
- package/bmad/bmm/workflows/2-plan-workflows/{prd → create-prd}/data/project-types.csv +10 -10
- package/bmad/bmm/workflows/2-plan-workflows/{prd → create-prd}/steps-c/step-01-init.md +191 -191
- package/bmad/bmm/workflows/2-plan-workflows/{prd → create-prd}/steps-c/step-01b-continue.md +153 -153
- package/bmad/bmm/workflows/2-plan-workflows/{prd → create-prd}/steps-c/step-02-discovery.md +224 -224
- package/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-02b-vision.md +154 -0
- package/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-02c-executive-summary.md +170 -0
- package/bmad/bmm/workflows/2-plan-workflows/{prd → create-prd}/steps-c/step-03-success.md +226 -226
- package/bmad/bmm/workflows/2-plan-workflows/{prd → create-prd}/steps-c/step-04-journeys.md +213 -213
- package/bmad/bmm/workflows/2-plan-workflows/{prd → create-prd}/steps-c/step-05-domain.md +207 -207
- package/bmad/bmm/workflows/2-plan-workflows/{prd → create-prd}/steps-c/step-06-innovation.md +226 -226
- package/bmad/bmm/workflows/2-plan-workflows/{prd → create-prd}/steps-c/step-07-project-type.md +237 -237
- package/bmad/bmm/workflows/2-plan-workflows/{prd → create-prd}/steps-c/step-08-scoping.md +228 -228
- package/bmad/bmm/workflows/2-plan-workflows/{prd → create-prd}/steps-c/step-09-functional.md +231 -231
- package/bmad/bmm/workflows/2-plan-workflows/{prd → create-prd}/steps-c/step-10-nonfunctional.md +242 -242
- package/bmad/bmm/workflows/2-plan-workflows/{prd → create-prd}/steps-c/step-11-polish.md +217 -217
- package/bmad/bmm/workflows/2-plan-workflows/{prd → create-prd}/steps-c/step-12-complete.md +124 -124
- package/bmad/bmm/workflows/2-plan-workflows/{prd → create-prd}/steps-e/step-e-01-discovery.md +247 -247
- package/bmad/bmm/workflows/2-plan-workflows/{prd → create-prd}/steps-e/step-e-01b-legacy-conversion.md +208 -208
- package/bmad/bmm/workflows/2-plan-workflows/{prd → create-prd}/steps-e/step-e-02-review.md +249 -249
- package/bmad/bmm/workflows/2-plan-workflows/{prd → create-prd}/steps-e/step-e-03-edit.md +253 -253
- package/bmad/bmm/workflows/2-plan-workflows/{prd → create-prd}/steps-e/step-e-04-complete.md +168 -168
- package/bmad/bmm/workflows/2-plan-workflows/{prd → create-prd}/steps-v/step-v-01-discovery.md +226 -218
- package/bmad/bmm/workflows/2-plan-workflows/{prd → create-prd}/steps-v/step-v-02-format-detection.md +191 -191
- package/bmad/bmm/workflows/2-plan-workflows/{prd → create-prd}/steps-v/step-v-02b-parity-check.md +209 -209
- package/bmad/bmm/workflows/2-plan-workflows/{prd → create-prd}/steps-v/step-v-03-density-validation.md +174 -174
- package/bmad/bmm/workflows/2-plan-workflows/{prd → create-prd}/steps-v/step-v-04-brief-coverage-validation.md +214 -214
- package/bmad/bmm/workflows/2-plan-workflows/{prd → create-prd}/steps-v/step-v-05-measurability-validation.md +228 -228
- package/bmad/bmm/workflows/2-plan-workflows/{prd → create-prd}/steps-v/step-v-06-traceability-validation.md +217 -217
- package/bmad/bmm/workflows/2-plan-workflows/{prd → create-prd}/steps-v/step-v-07-implementation-leakage-validation.md +205 -205
- package/bmad/bmm/workflows/2-plan-workflows/{prd → create-prd}/steps-v/step-v-08-domain-compliance-validation.md +243 -243
- package/bmad/bmm/workflows/2-plan-workflows/{prd → create-prd}/steps-v/step-v-09-project-type-validation.md +263 -263
- package/bmad/bmm/workflows/2-plan-workflows/{prd → create-prd}/steps-v/step-v-10-smart-validation.md +209 -209
- package/bmad/bmm/workflows/2-plan-workflows/{prd → create-prd}/steps-v/step-v-11-holistic-quality-validation.md +264 -264
- package/bmad/bmm/workflows/2-plan-workflows/{prd → create-prd}/steps-v/step-v-12-completeness-validation.md +242 -242
- package/bmad/bmm/workflows/2-plan-workflows/{prd → create-prd}/steps-v/step-v-13-report-complete.md +231 -231
- package/bmad/bmm/workflows/2-plan-workflows/{prd → create-prd}/templates/prd-template.md +10 -10
- package/bmad/bmm/workflows/2-plan-workflows/create-prd/workflow-create-prd.md +63 -0
- package/bmad/bmm/workflows/2-plan-workflows/create-prd/workflow-edit-prd.md +65 -0
- package/bmad/bmm/workflows/2-plan-workflows/create-prd/workflow-validate-prd.md +63 -0
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-01-init.md +135 -135
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-01b-continue.md +127 -127
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-02-discovery.md +190 -190
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-03-core-experience.md +216 -216
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-04-emotional-response.md +219 -219
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-05-inspiration.md +234 -234
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-06-design-system.md +252 -252
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-07-defining-experience.md +254 -254
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-08-visual-foundation.md +224 -224
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-09-design-directions.md +224 -224
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-10-user-journeys.md +241 -241
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-11-component-strategy.md +248 -248
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-12-ux-patterns.md +237 -237
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-13-responsive-accessibility.md +264 -264
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-14-complete.md +171 -171
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/ux-design-template.md +13 -13
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/workflow.md +42 -43
- package/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-01-document-discovery.md +184 -190
- package/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-02-prd-analysis.md +172 -178
- package/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-03-epic-coverage-validation.md +173 -179
- package/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-04-ux-alignment.md +133 -139
- package/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-05-epic-quality-review.md +245 -252
- package/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-06-final-assessment.md +129 -135
- package/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/templates/readiness-report-template.md +4 -4
- package/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/workflow.md +54 -55
- package/bmad/bmm/workflows/3-solutioning/create-architecture/architecture-decision-template.md +12 -12
- package/bmad/bmm/workflows/3-solutioning/create-architecture/data/domain-complexity.csv +12 -10
- package/bmad/bmm/workflows/3-solutioning/create-architecture/data/project-types.csv +6 -6
- package/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-01-init.md +153 -153
- package/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-01b-continue.md +164 -164
- package/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-02-context.md +224 -224
- package/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-03-starter.md +331 -331
- package/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-04-decisions.md +318 -318
- package/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-05-patterns.md +359 -359
- package/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-06-structure.md +379 -379
- package/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-07-validation.md +359 -359
- package/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-08-complete.md +76 -76
- package/bmad/bmm/workflows/3-solutioning/create-architecture/workflow.md +49 -50
- package/bmad/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-01-validate-prerequisites.md +259 -259
- package/bmad/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-02-design-epics.md +233 -233
- package/bmad/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-03-create-stories.md +272 -272
- package/bmad/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-04-final-validation.md +149 -149
- package/bmad/bmm/workflows/3-solutioning/create-epics-and-stories/templates/epics-template.md +57 -57
- package/bmad/bmm/workflows/3-solutioning/create-epics-and-stories/workflow.md +58 -59
- package/bmad/bmm/workflows/4-implementation/code-review/checklist.md +23 -23
- package/bmad/bmm/workflows/4-implementation/code-review/instructions.xml +226 -226
- package/bmad/bmm/workflows/4-implementation/code-review/workflow.yaml +44 -51
- package/bmad/bmm/workflows/4-implementation/correct-course/checklist.md +288 -288
- package/bmad/bmm/workflows/4-implementation/correct-course/instructions.md +207 -206
- package/bmad/bmm/workflows/4-implementation/correct-course/workflow.yaml +54 -60
- package/bmad/bmm/workflows/4-implementation/create-story/checklist.md +358 -358
- package/bmad/bmm/workflows/4-implementation/create-story/instructions.xml +346 -345
- package/bmad/bmm/workflows/4-implementation/create-story/template.md +49 -49
- package/bmad/bmm/workflows/4-implementation/create-story/workflow.yaml +53 -61
- package/bmad/bmm/workflows/4-implementation/dev-story/checklist.md +80 -80
- package/bmad/bmm/workflows/4-implementation/dev-story/instructions.xml +410 -410
- package/bmad/bmm/workflows/4-implementation/dev-story/workflow.yaml +21 -27
- package/bmad/bmm/workflows/4-implementation/retrospective/instructions.md +1444 -1443
- package/bmad/bmm/workflows/4-implementation/retrospective/workflow.yaml +53 -58
- package/bmad/bmm/workflows/4-implementation/sprint-planning/checklist.md +33 -33
- package/bmad/bmm/workflows/4-implementation/sprint-planning/instructions.md +226 -225
- package/bmad/bmm/workflows/4-implementation/sprint-planning/sprint-status-template.yaml +55 -55
- package/bmad/bmm/workflows/4-implementation/sprint-planning/workflow.yaml +47 -54
- package/bmad/bmm/workflows/4-implementation/sprint-status/instructions.md +230 -229
- package/bmad/bmm/workflows/4-implementation/sprint-status/workflow.yaml +25 -36
- package/bmad/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-01-mode-detection.md +174 -156
- package/bmad/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-02-context-gathering.md +118 -120
- package/bmad/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-03-execute.md +111 -113
- package/bmad/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-04-self-check.md +111 -113
- package/bmad/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-05-adversarial-review.md +104 -106
- package/bmad/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-06-resolve-findings.md +146 -140
- package/bmad/bmm/workflows/bmad-quick-flow/quick-dev/workflow.md +50 -50
- package/bmad/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-01-understand.md +191 -189
- package/bmad/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-02-investigate.md +144 -144
- package/bmad/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-03-generate.md +127 -128
- package/bmad/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-04-review.md +200 -191
- package/bmad/bmm/workflows/bmad-quick-flow/quick-spec/tech-spec-template.md +74 -74
- package/bmad/bmm/workflows/bmad-quick-flow/quick-spec/workflow.md +79 -79
- package/bmad/bmm/workflows/document-project/checklist.md +245 -245
- package/bmad/bmm/workflows/document-project/documentation-requirements.csv +12 -12
- package/bmad/bmm/workflows/document-project/instructions.md +130 -221
- package/bmad/bmm/workflows/document-project/templates/deep-dive-template.md +345 -345
- package/bmad/bmm/workflows/document-project/templates/index-template.md +169 -169
- package/bmad/bmm/workflows/document-project/templates/project-overview-template.md +103 -103
- package/bmad/bmm/workflows/document-project/templates/project-scan-report-schema.json +160 -160
- package/bmad/bmm/workflows/document-project/templates/source-tree-template.md +135 -135
- package/bmad/bmm/workflows/document-project/workflow.yaml +22 -30
- package/bmad/bmm/workflows/document-project/workflows/deep-dive-instructions.md +298 -298
- package/bmad/bmm/workflows/document-project/workflows/deep-dive.yaml +31 -31
- package/bmad/bmm/workflows/document-project/workflows/full-scan-instructions.md +1106 -1106
- package/bmad/bmm/workflows/document-project/workflows/full-scan.yaml +31 -31
- package/bmad/bmm/workflows/generate-project-context/project-context-template.md +21 -0
- package/bmad/bmm/workflows/generate-project-context/steps/step-01-discover.md +184 -0
- package/bmad/bmm/workflows/generate-project-context/steps/step-02-generate.md +318 -0
- package/bmad/bmm/workflows/generate-project-context/steps/step-03-complete.md +278 -0
- package/bmad/bmm/workflows/generate-project-context/workflow.md +49 -0
- package/bmad/bmm/workflows/qa/automate/checklist.md +33 -0
- package/bmad/bmm/workflows/qa/automate/instructions.md +110 -0
- package/bmad/bmm/workflows/qa/automate/workflow.yaml +44 -0
- package/bmad/core/agents/bmad-master.agent.yaml +30 -30
- package/bmad/core/module-help.csv +9 -11
- package/bmad/core/module.yaml +25 -25
- package/bmad/core/tasks/editorial-review-prose.xml +102 -91
- package/bmad/core/tasks/editorial-review-structure.xml +209 -198
- package/bmad/core/tasks/help.md +85 -0
- package/bmad/core/tasks/index-docs.xml +64 -64
- package/bmad/core/tasks/review-adversarial-general.xml +48 -48
- package/bmad/core/tasks/shard-doc.xml +107 -108
- package/bmad/core/tasks/workflow.xml +234 -234
- package/bmad/core/workflows/advanced-elicitation/methods.csv +51 -51
- package/bmad/core/workflows/advanced-elicitation/workflow.xml +116 -116
- package/bmad/core/workflows/brainstorming/brain-methods.csv +61 -61
- package/bmad/core/workflows/brainstorming/steps/step-01-session-setup.md +197 -197
- package/bmad/core/workflows/brainstorming/steps/step-01b-continue.md +122 -122
- package/bmad/core/workflows/brainstorming/steps/step-02a-user-selected.md +225 -225
- package/bmad/core/workflows/brainstorming/steps/step-02b-ai-recommended.md +237 -237
- package/bmad/core/workflows/brainstorming/steps/step-02c-random-selection.md +209 -209
- package/bmad/core/workflows/brainstorming/steps/step-02d-progressive-flow.md +264 -264
- package/bmad/core/workflows/brainstorming/steps/step-03-technique-execution.md +399 -399
- package/bmad/core/workflows/brainstorming/steps/step-04-idea-organization.md +303 -303
- package/bmad/core/workflows/brainstorming/template.md +15 -15
- package/bmad/core/workflows/brainstorming/workflow.md +58 -58
- package/bmad/core/workflows/party-mode/steps/step-01-agent-loading.md +138 -138
- package/bmad/core/workflows/party-mode/steps/step-02-discussion-orchestration.md +187 -187
- package/bmad/core/workflows/party-mode/steps/step-03-graceful-exit.md +168 -157
- package/bmad/core/workflows/party-mode/workflow.md +194 -194
- package/bundled-versions.json +3 -0
- package/dist/cli.js +61 -6
- package/dist/commands/check-updates.d.ts +5 -0
- package/dist/commands/check-updates.js +63 -0
- package/dist/commands/doctor.d.ts +39 -1
- package/dist/commands/doctor.js +348 -79
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.js +41 -15
- package/dist/commands/status.d.ts +7 -1
- package/dist/commands/status.js +111 -42
- package/dist/commands/upgrade.d.ts +7 -1
- package/dist/commands/upgrade.js +43 -12
- package/dist/installer.d.ts +19 -2
- package/dist/installer.js +305 -66
- package/dist/transition/artifacts.d.ts +2 -0
- package/dist/transition/artifacts.js +46 -0
- package/dist/transition/context.d.ts +19 -0
- package/dist/transition/context.js +261 -0
- package/dist/transition/fix-plan.d.ts +15 -0
- package/dist/transition/fix-plan.js +94 -0
- package/dist/transition/index.d.ts +9 -0
- package/dist/transition/index.js +16 -0
- package/dist/transition/orchestration.d.ts +2 -0
- package/dist/transition/orchestration.js +243 -0
- package/dist/transition/specs-changelog.d.ts +3 -0
- package/dist/transition/specs-changelog.js +75 -0
- package/dist/transition/specs-index.d.ts +22 -0
- package/dist/transition/specs-index.js +157 -0
- package/dist/transition/story-parsing.d.ts +7 -0
- package/dist/transition/story-parsing.js +124 -0
- package/dist/transition/tech-stack.d.ts +3 -0
- package/dist/transition/tech-stack.js +79 -0
- package/dist/transition/types.d.ts +60 -0
- package/dist/transition/types.js +1 -0
- package/dist/utils/config.d.ts +4 -0
- package/dist/utils/config.js +14 -4
- package/dist/utils/constants.d.ts +70 -0
- package/dist/utils/constants.js +97 -0
- package/dist/utils/dryrun.d.ts +7 -0
- package/dist/utils/dryrun.js +48 -0
- package/dist/utils/errors.d.ts +63 -0
- package/dist/utils/errors.js +86 -0
- package/dist/utils/file-system.d.ts +24 -0
- package/dist/utils/file-system.js +99 -0
- package/dist/utils/github.d.ts +83 -0
- package/dist/utils/github.js +230 -0
- package/dist/utils/json.js +3 -3
- package/dist/utils/logger.d.ts +6 -0
- package/dist/utils/logger.js +27 -0
- package/dist/utils/state.d.ts +4 -7
- package/dist/utils/state.js +147 -26
- package/dist/utils/validate.d.ts +40 -0
- package/dist/utils/validate.js +175 -1
- package/package.json +75 -59
- package/ralph/RALPH-REFERENCE.md +412 -0
- package/ralph/lib/circuit_breaker.sh +463 -330
- package/ralph/lib/date_utils.sh +104 -53
- package/ralph/lib/enable_core.sh +815 -0
- package/ralph/lib/response_analyzer.sh +884 -768
- package/ralph/lib/task_sources.sh +577 -0
- package/ralph/lib/timeout_utils.sh +145 -145
- package/ralph/lib/wizard_utils.sh +547 -0
- package/ralph/ralph_import.sh +636 -0
- package/ralph/ralph_loop.sh +1793 -1391
- package/ralph/ralph_monitor.sh +125 -0
- package/ralph/templates/AGENT.md +158 -158
- package/ralph/templates/PROMPT.md +285 -292
- package/ralph/templates/fix_plan.md +27 -27
- package/ralph/templates/ralphrc.template +102 -0
- package/ralph/templates/specs/.gitkeep +1 -1
- package/slash-commands/advanced-elicitation.md +1 -1
- package/slash-commands/adversarial-review.md +1 -1
- package/slash-commands/analyst.md +1 -1
- package/slash-commands/architect.md +1 -1
- package/slash-commands/bmad-help.md +1 -1
- package/slash-commands/bmalph-implement.md +152 -152
- package/slash-commands/brainstorm-project.md +1 -1
- package/slash-commands/brainstorming.md +1 -1
- package/slash-commands/correct-course.md +1 -1
- package/slash-commands/create-architecture.md +1 -1
- package/slash-commands/create-brief.md +1 -1
- package/slash-commands/create-epics-stories.md +1 -1
- package/slash-commands/create-prd.md +1 -1
- package/slash-commands/create-story.md +1 -1
- package/slash-commands/create-ux.md +1 -1
- package/slash-commands/dev.md +1 -1
- package/slash-commands/document-project.md +1 -1
- package/slash-commands/domain-research.md +1 -1
- package/slash-commands/editorial-prose.md +1 -1
- package/slash-commands/editorial-structure.md +1 -1
- package/slash-commands/execute-workflow.md +1 -1
- package/slash-commands/generate-project-context.md +1 -0
- package/slash-commands/implementation-readiness.md +1 -1
- package/slash-commands/index-docs.md +1 -1
- package/slash-commands/market-research.md +1 -1
- package/slash-commands/party-mode.md +1 -1
- package/slash-commands/pm.md +1 -1
- package/slash-commands/qa-automate.md +1 -0
- package/slash-commands/qa.md +1 -0
- package/slash-commands/quick-dev.md +1 -1
- package/slash-commands/quick-flow-solo-dev.md +1 -1
- package/slash-commands/retrospective.md +1 -1
- package/slash-commands/shard-doc.md +1 -1
- package/slash-commands/sm.md +1 -1
- package/slash-commands/sprint-planning.md +1 -1
- package/slash-commands/sprint-status.md +1 -1
- package/slash-commands/tech-spec.md +1 -1
- package/slash-commands/tech-writer.md +1 -0
- package/slash-commands/technical-research.md +1 -1
- package/slash-commands/ux-designer.md +1 -1
- package/slash-commands/validate-architecture.md +1 -1
- package/slash-commands/validate-brief.md +1 -1
- package/slash-commands/validate-epics-stories.md +1 -1
- package/slash-commands/validate-prd.md +1 -1
- package/slash-commands/validate-story.md +1 -1
- package/slash-commands/validate-ux.md +1 -1
- package/bmad/bmm/agents/tea.agent.yaml +0 -63
- package/bmad/bmm/sub-modules/claude-code/config.yaml +0 -4
- package/bmad/bmm/sub-modules/claude-code/injections.yaml +0 -242
- package/bmad/bmm/sub-modules/claude-code/readme.md +0 -87
- package/bmad/bmm/testarch/knowledge/adr-quality-readiness-checklist.md +0 -350
- package/bmad/bmm/testarch/knowledge/api-request.md +0 -442
- package/bmad/bmm/testarch/knowledge/api-testing-patterns.md +0 -843
- package/bmad/bmm/testarch/knowledge/auth-session.md +0 -552
- package/bmad/bmm/testarch/knowledge/burn-in.md +0 -273
- package/bmad/bmm/testarch/knowledge/ci-burn-in.md +0 -675
- package/bmad/bmm/testarch/knowledge/component-tdd.md +0 -486
- package/bmad/bmm/testarch/knowledge/contract-testing.md +0 -957
- package/bmad/bmm/testarch/knowledge/data-factories.md +0 -500
- package/bmad/bmm/testarch/knowledge/email-auth.md +0 -721
- package/bmad/bmm/testarch/knowledge/error-handling.md +0 -725
- package/bmad/bmm/testarch/knowledge/feature-flags.md +0 -750
- package/bmad/bmm/testarch/knowledge/file-utils.md +0 -463
- package/bmad/bmm/testarch/knowledge/fixture-architecture.md +0 -401
- package/bmad/bmm/testarch/knowledge/fixtures-composition.md +0 -382
- package/bmad/bmm/testarch/knowledge/intercept-network-call.md +0 -430
- package/bmad/bmm/testarch/knowledge/log.md +0 -429
- package/bmad/bmm/testarch/knowledge/network-error-monitor.md +0 -405
- package/bmad/bmm/testarch/knowledge/network-first.md +0 -486
- package/bmad/bmm/testarch/knowledge/network-recorder.md +0 -527
- package/bmad/bmm/testarch/knowledge/nfr-criteria.md +0 -670
- package/bmad/bmm/testarch/knowledge/overview.md +0 -286
- package/bmad/bmm/testarch/knowledge/playwright-config.md +0 -730
- package/bmad/bmm/testarch/knowledge/probability-impact.md +0 -601
- package/bmad/bmm/testarch/knowledge/recurse.md +0 -421
- package/bmad/bmm/testarch/knowledge/risk-governance.md +0 -615
- package/bmad/bmm/testarch/knowledge/selective-testing.md +0 -732
- package/bmad/bmm/testarch/knowledge/selector-resilience.md +0 -527
- package/bmad/bmm/testarch/knowledge/test-healing-patterns.md +0 -644
- package/bmad/bmm/testarch/knowledge/test-levels-framework.md +0 -473
- package/bmad/bmm/testarch/knowledge/test-priorities-matrix.md +0 -373
- package/bmad/bmm/testarch/knowledge/test-quality.md +0 -664
- package/bmad/bmm/testarch/knowledge/timing-debugging.md +0 -372
- package/bmad/bmm/testarch/knowledge/visual-debugging.md +0 -524
- package/bmad/bmm/testarch/tea-index.csv +0 -35
- package/bmad/bmm/workflows/1-analysis/research/market-steps/step-02-customer-insights.md +0 -200
- package/bmad/bmm/workflows/1-analysis/research/workflow.md +0 -173
- package/bmad/bmm/workflows/2-plan-workflows/prd/validation-report-prd-workflow.md +0 -433
- package/bmad/bmm/workflows/2-plan-workflows/prd/workflow.md +0 -150
- package/bmad/bmm/workflows/bmad-quick-flow/quick-dev/data/project-levels.yaml +0 -59
- package/bmad/bmm/workflows/excalidraw-diagrams/_shared/excalidraw-library.json +0 -90
- package/bmad/bmm/workflows/excalidraw-diagrams/_shared/excalidraw-templates.yaml +0 -127
- package/bmad/bmm/workflows/excalidraw-diagrams/create-dataflow/checklist.md +0 -39
- package/bmad/bmm/workflows/excalidraw-diagrams/create-dataflow/instructions.md +0 -130
- package/bmad/bmm/workflows/excalidraw-diagrams/create-dataflow/workflow.yaml +0 -27
- package/bmad/bmm/workflows/excalidraw-diagrams/create-diagram/checklist.md +0 -43
- package/bmad/bmm/workflows/excalidraw-diagrams/create-diagram/instructions.md +0 -141
- package/bmad/bmm/workflows/excalidraw-diagrams/create-diagram/workflow.yaml +0 -27
- package/bmad/bmm/workflows/excalidraw-diagrams/create-flowchart/checklist.md +0 -49
- package/bmad/bmm/workflows/excalidraw-diagrams/create-flowchart/instructions.md +0 -241
- package/bmad/bmm/workflows/excalidraw-diagrams/create-flowchart/workflow.yaml +0 -27
- package/bmad/bmm/workflows/excalidraw-diagrams/create-wireframe/checklist.md +0 -38
- package/bmad/bmm/workflows/excalidraw-diagrams/create-wireframe/instructions.md +0 -133
- package/bmad/bmm/workflows/excalidraw-diagrams/create-wireframe/workflow.yaml +0 -27
- package/bmad/bmm/workflows/testarch/atdd/atdd-checklist-template.md +0 -363
- package/bmad/bmm/workflows/testarch/atdd/checklist.md +0 -374
- package/bmad/bmm/workflows/testarch/atdd/instructions.md +0 -806
- package/bmad/bmm/workflows/testarch/atdd/workflow.yaml +0 -47
- package/bmad/bmm/workflows/testarch/automate/checklist.md +0 -582
- package/bmad/bmm/workflows/testarch/automate/instructions.md +0 -1324
- package/bmad/bmm/workflows/testarch/automate/workflow.yaml +0 -54
- package/bmad/bmm/workflows/testarch/ci/checklist.md +0 -247
- package/bmad/bmm/workflows/testarch/ci/github-actions-template.yaml +0 -198
- package/bmad/bmm/workflows/testarch/ci/gitlab-ci-template.yaml +0 -149
- package/bmad/bmm/workflows/testarch/ci/instructions.md +0 -536
- package/bmad/bmm/workflows/testarch/ci/workflow.yaml +0 -47
- package/bmad/bmm/workflows/testarch/framework/checklist.md +0 -320
- package/bmad/bmm/workflows/testarch/framework/instructions.md +0 -481
- package/bmad/bmm/workflows/testarch/framework/workflow.yaml +0 -49
- package/bmad/bmm/workflows/testarch/nfr-assess/checklist.md +0 -407
- package/bmad/bmm/workflows/testarch/nfr-assess/instructions.md +0 -726
- package/bmad/bmm/workflows/testarch/nfr-assess/nfr-report-template.md +0 -461
- package/bmad/bmm/workflows/testarch/nfr-assess/workflow.yaml +0 -49
- package/bmad/bmm/workflows/testarch/test-design/checklist.md +0 -407
- package/bmad/bmm/workflows/testarch/test-design/instructions.md +0 -1158
- package/bmad/bmm/workflows/testarch/test-design/test-design-architecture-template.md +0 -213
- package/bmad/bmm/workflows/testarch/test-design/test-design-qa-template.md +0 -286
- package/bmad/bmm/workflows/testarch/test-design/test-design-template.md +0 -294
- package/bmad/bmm/workflows/testarch/test-design/workflow.yaml +0 -71
- package/bmad/bmm/workflows/testarch/test-review/checklist.md +0 -472
- package/bmad/bmm/workflows/testarch/test-review/instructions.md +0 -628
- package/bmad/bmm/workflows/testarch/test-review/test-review-template.md +0 -390
- package/bmad/bmm/workflows/testarch/test-review/workflow.yaml +0 -48
- package/bmad/bmm/workflows/testarch/trace/checklist.md +0 -642
- package/bmad/bmm/workflows/testarch/trace/instructions.md +0 -1030
- package/bmad/bmm/workflows/testarch/trace/trace-template.md +0 -675
- package/bmad/bmm/workflows/testarch/trace/workflow.yaml +0 -57
- package/bmad/core/resources/excalidraw/README.md +0 -160
- package/bmad/core/resources/excalidraw/excalidraw-helpers.md +0 -127
- package/bmad/core/resources/excalidraw/library-loader.md +0 -50
- package/bmad/core/resources/excalidraw/validate-json-instructions.md +0 -79
- package/bmad/core/tasks/bmad-help.md +0 -62
- package/dist/commands/guide.d.ts +0 -1
- package/dist/commands/guide.js +0 -19
- package/dist/commands/implement.d.ts +0 -1
- package/dist/commands/implement.js +0 -83
- package/dist/commands/plan.d.ts +0 -5
- package/dist/commands/plan.js +0 -44
- package/dist/commands/reset.d.ts +0 -5
- package/dist/commands/reset.js +0 -35
- package/dist/commands/resume.d.ts +0 -1
- package/dist/commands/resume.js +0 -44
- package/dist/commands/start.d.ts +0 -5
- package/dist/commands/start.js +0 -54
- package/dist/transition.d.ts +0 -52
- package/dist/transition.js +0 -656
- package/slash-commands/atdd.md +0 -1
- package/slash-commands/continuous-integration.md +0 -1
- package/slash-commands/create-dataflow.md +0 -1
- package/slash-commands/create-diagram.md +0 -1
- package/slash-commands/create-flowchart.md +0 -1
- package/slash-commands/create-wireframe.md +0 -1
- package/slash-commands/nfr-assess.md +0 -1
- package/slash-commands/tea.md +0 -1
- package/slash-commands/test-automate.md +0 -1
- package/slash-commands/test-design.md +0 -1
- package/slash-commands/test-framework.md +0 -1
- package/slash-commands/test-review.md +0 -1
- package/slash-commands/test-trace.md +0 -1
- package/slash-commands/validate-test-design.md +0 -1
package/dist/commands/doctor.js
CHANGED
|
@@ -1,67 +1,55 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
|
-
import {
|
|
2
|
+
import { readFile, stat } from "fs/promises";
|
|
3
|
+
import { exists } from "../utils/file-system.js";
|
|
3
4
|
import { join } from "path";
|
|
4
5
|
import { readJsonFile } from "../utils/json.js";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const results = [];
|
|
18
|
-
// 1. Node version
|
|
19
|
-
const major = parseInt(process.versions.node.split(".")[0]);
|
|
20
|
-
results.push({
|
|
21
|
-
label: "Node version >= 20",
|
|
22
|
-
passed: major >= 20,
|
|
23
|
-
detail: major >= 20 ? `v${process.versions.node}` : `got v${process.versions.node}`,
|
|
24
|
-
});
|
|
25
|
-
// 2. bash available
|
|
26
|
-
const bashAvailable = await checkBashAvailable();
|
|
27
|
-
results.push({
|
|
28
|
-
label: "bash available",
|
|
29
|
-
passed: bashAvailable,
|
|
30
|
-
detail: bashAvailable ? undefined : "bash not found in PATH",
|
|
6
|
+
import { readConfig } from "../utils/config.js";
|
|
7
|
+
import { getBundledVersions } from "../installer.js";
|
|
8
|
+
import { checkUpstream, getSkipReason } from "../utils/github.js";
|
|
9
|
+
import { isEnoent, formatError, withErrorHandling } from "../utils/errors.js";
|
|
10
|
+
import { validateCircuitBreakerState, validateRalphSession, validateRalphApiStatus, } from "../utils/validate.js";
|
|
11
|
+
import { SESSION_AGE_WARNING_MS, API_USAGE_WARNING_PERCENT, CONFIG_FILE, RALPH_STATUS_FILE, } from "../utils/constants.js";
|
|
12
|
+
export async function doctorCommand(options) {
|
|
13
|
+
await withErrorHandling(async () => {
|
|
14
|
+
const { failed } = await runDoctor(options);
|
|
15
|
+
if (!options.json && failed > 0) {
|
|
16
|
+
process.exitCode = 1;
|
|
17
|
+
}
|
|
31
18
|
});
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
//
|
|
36
|
-
const
|
|
37
|
-
results.push(bmadResult);
|
|
38
|
-
// 5. .ralph/ralph_loop.sh present and has content
|
|
39
|
-
const loopResult = await checkFileHasContent(join(projectDir, ".ralph/ralph_loop.sh"), "ralph_loop.sh present and has content");
|
|
40
|
-
results.push(loopResult);
|
|
41
|
-
// 6. .ralph/lib/ present
|
|
42
|
-
const libResult = await checkDir(join(projectDir, ".ralph/lib"), ".ralph/lib/ directory present");
|
|
43
|
-
results.push(libResult);
|
|
44
|
-
// 7. .claude/commands/bmalph.md present
|
|
45
|
-
const slashResult = await checkFileExists(join(projectDir, ".claude/commands/bmalph.md"), ".claude/commands/bmalph.md present");
|
|
46
|
-
results.push(slashResult);
|
|
47
|
-
// 8. CLAUDE.md contains BMAD snippet
|
|
48
|
-
const claudeMdResult = await checkClaudeMd(projectDir);
|
|
49
|
-
results.push(claudeMdResult);
|
|
50
|
-
// 9. .gitignore has required entries
|
|
51
|
-
const gitignoreResult = await checkGitignore(projectDir);
|
|
52
|
-
results.push(gitignoreResult);
|
|
53
|
-
// 10. Version marker check
|
|
54
|
-
const versionResult = await checkVersionMarker(projectDir);
|
|
55
|
-
results.push(versionResult);
|
|
19
|
+
}
|
|
20
|
+
export async function runDoctor(options) {
|
|
21
|
+
const projectDir = options.projectDir;
|
|
22
|
+
// Run all checks from the registry
|
|
23
|
+
const results = await Promise.all(CHECK_REGISTRY.map((check) => check.run(projectDir)));
|
|
56
24
|
// Output
|
|
25
|
+
const passed = results.filter((r) => r.passed).length;
|
|
26
|
+
const failed = results.filter((r) => !r.passed).length;
|
|
27
|
+
if (options.json) {
|
|
28
|
+
const output = {
|
|
29
|
+
results: results.map((r) => ({
|
|
30
|
+
label: r.label,
|
|
31
|
+
passed: r.passed,
|
|
32
|
+
...(r.detail && { detail: r.detail }),
|
|
33
|
+
...(r.hint && { hint: r.hint }),
|
|
34
|
+
})),
|
|
35
|
+
summary: {
|
|
36
|
+
passed,
|
|
37
|
+
failed,
|
|
38
|
+
total: results.length,
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
console.log(JSON.stringify(output, null, 2));
|
|
42
|
+
return { passed, failed };
|
|
43
|
+
}
|
|
57
44
|
console.log(chalk.bold("bmalph doctor\n"));
|
|
58
45
|
for (const r of results) {
|
|
59
46
|
const icon = r.passed ? chalk.green("\u2713") : chalk.red("\u2717");
|
|
60
47
|
const detail = r.detail ? chalk.dim(` (${r.detail})`) : "";
|
|
61
48
|
console.log(` ${icon} ${r.label}${detail}`);
|
|
49
|
+
if (!r.passed && r.hint) {
|
|
50
|
+
console.log(chalk.yellow(` → ${r.hint}`));
|
|
51
|
+
}
|
|
62
52
|
}
|
|
63
|
-
const passed = results.filter((r) => r.passed).length;
|
|
64
|
-
const failed = results.filter((r) => !r.passed).length;
|
|
65
53
|
console.log("");
|
|
66
54
|
if (failed === 0) {
|
|
67
55
|
console.log(chalk.green(`${passed} passed, all checks OK`));
|
|
@@ -69,6 +57,7 @@ async function runDoctor() {
|
|
|
69
57
|
else {
|
|
70
58
|
console.log(`${chalk.green(`${passed} passed`)}, ${chalk.red(`${failed} failed`)}`);
|
|
71
59
|
}
|
|
60
|
+
return { passed, failed };
|
|
72
61
|
}
|
|
73
62
|
async function checkBashAvailable() {
|
|
74
63
|
const { execSync } = await import("child_process");
|
|
@@ -81,55 +70,104 @@ async function checkBashAvailable() {
|
|
|
81
70
|
return false;
|
|
82
71
|
}
|
|
83
72
|
}
|
|
73
|
+
// =============================================================================
|
|
74
|
+
// Check functions - each conforms to CheckFunction signature
|
|
75
|
+
// =============================================================================
|
|
76
|
+
async function checkNodeVersion(_projectDir) {
|
|
77
|
+
const major = parseInt(process.versions.node.split(".")[0]);
|
|
78
|
+
return {
|
|
79
|
+
label: "Node version >= 20",
|
|
80
|
+
passed: major >= 20,
|
|
81
|
+
detail: major >= 20 ? `v${process.versions.node}` : `got v${process.versions.node}`,
|
|
82
|
+
hint: major >= 20 ? undefined : "Install Node.js 20+ from nodejs.org or run: nvm install 20",
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
async function checkBash(_projectDir) {
|
|
86
|
+
const bashAvailable = await checkBashAvailable();
|
|
87
|
+
return {
|
|
88
|
+
label: "bash available",
|
|
89
|
+
passed: bashAvailable,
|
|
90
|
+
detail: bashAvailable ? undefined : "bash not found in PATH",
|
|
91
|
+
hint: bashAvailable
|
|
92
|
+
? undefined
|
|
93
|
+
: process.platform === "win32"
|
|
94
|
+
? "Install Git Bash or WSL: https://git-scm.com/downloads"
|
|
95
|
+
: "Install bash via your package manager (apt, brew, etc.)",
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
async function checkBmadDir(projectDir) {
|
|
99
|
+
return checkDir(join(projectDir, "_bmad"), "_bmad/ directory present", "Run: bmalph init");
|
|
100
|
+
}
|
|
101
|
+
async function checkRalphLoop(projectDir) {
|
|
102
|
+
return checkFileHasContent(join(projectDir, ".ralph/ralph_loop.sh"), "ralph_loop.sh present and has content", "Run: bmalph upgrade");
|
|
103
|
+
}
|
|
104
|
+
async function checkRalphLib(projectDir) {
|
|
105
|
+
return checkDir(join(projectDir, ".ralph/lib"), ".ralph/lib/ directory present", "Run: bmalph upgrade");
|
|
106
|
+
}
|
|
107
|
+
async function checkSlashCommand(projectDir) {
|
|
108
|
+
return checkFileExists(join(projectDir, ".claude/commands/bmalph.md"), ".claude/commands/bmalph.md present", "Run: bmalph init");
|
|
109
|
+
}
|
|
84
110
|
async function checkConfig(projectDir) {
|
|
85
|
-
const
|
|
111
|
+
const label = "bmalph/config.json exists and valid";
|
|
112
|
+
const hint = "Run: bmalph init";
|
|
113
|
+
const path = join(projectDir, CONFIG_FILE);
|
|
86
114
|
try {
|
|
87
115
|
const data = await readJsonFile(path);
|
|
88
116
|
if (data === null) {
|
|
89
|
-
return { label
|
|
117
|
+
return { label, passed: false, detail: "file not found", hint };
|
|
90
118
|
}
|
|
91
|
-
return { label
|
|
119
|
+
return { label, passed: true };
|
|
92
120
|
}
|
|
93
121
|
catch (err) {
|
|
94
122
|
const msg = err instanceof Error ? err.message : "invalid";
|
|
95
|
-
return { label
|
|
123
|
+
return { label, passed: false, detail: msg, hint };
|
|
96
124
|
}
|
|
97
125
|
}
|
|
98
|
-
async function checkDir(dirPath, label) {
|
|
126
|
+
async function checkDir(dirPath, label, hint) {
|
|
99
127
|
try {
|
|
100
128
|
const s = await stat(dirPath);
|
|
101
129
|
return { label, passed: s.isDirectory() };
|
|
102
130
|
}
|
|
103
|
-
catch {
|
|
104
|
-
|
|
131
|
+
catch (err) {
|
|
132
|
+
if (isEnoent(err)) {
|
|
133
|
+
return { label, passed: false, detail: "not found", hint };
|
|
134
|
+
}
|
|
135
|
+
return { label, passed: false, detail: `error: ${formatError(err)}`, hint };
|
|
105
136
|
}
|
|
106
137
|
}
|
|
107
|
-
async function checkFileExists(filePath, label) {
|
|
108
|
-
|
|
109
|
-
await access(filePath);
|
|
138
|
+
async function checkFileExists(filePath, label, hint) {
|
|
139
|
+
if (await exists(filePath)) {
|
|
110
140
|
return { label, passed: true };
|
|
111
141
|
}
|
|
112
|
-
|
|
113
|
-
return { label, passed: false, detail: "not found" };
|
|
114
|
-
}
|
|
142
|
+
return { label, passed: false, detail: "not found", hint };
|
|
115
143
|
}
|
|
116
|
-
async function checkFileHasContent(filePath, label) {
|
|
144
|
+
async function checkFileHasContent(filePath, label, hint) {
|
|
117
145
|
try {
|
|
118
146
|
const content = await readFile(filePath, "utf-8");
|
|
119
147
|
return { label, passed: content.trim().length > 0 };
|
|
120
148
|
}
|
|
121
|
-
catch {
|
|
122
|
-
|
|
149
|
+
catch (err) {
|
|
150
|
+
if (isEnoent(err)) {
|
|
151
|
+
return { label, passed: false, detail: "not found", hint };
|
|
152
|
+
}
|
|
153
|
+
return { label, passed: false, detail: `error: ${formatError(err)}`, hint };
|
|
123
154
|
}
|
|
124
155
|
}
|
|
125
156
|
async function checkClaudeMd(projectDir) {
|
|
126
157
|
const label = "CLAUDE.md contains BMAD snippet";
|
|
158
|
+
const hint = "Run: bmalph init";
|
|
127
159
|
try {
|
|
128
160
|
const content = await readFile(join(projectDir, "CLAUDE.md"), "utf-8");
|
|
129
|
-
|
|
161
|
+
if (content.includes("BMAD-METHOD Integration")) {
|
|
162
|
+
return { label, passed: true };
|
|
163
|
+
}
|
|
164
|
+
return { label, passed: false, detail: "missing BMAD-METHOD Integration section", hint };
|
|
130
165
|
}
|
|
131
|
-
catch {
|
|
132
|
-
|
|
166
|
+
catch (err) {
|
|
167
|
+
if (isEnoent(err)) {
|
|
168
|
+
return { label, passed: false, detail: "CLAUDE.md not found", hint };
|
|
169
|
+
}
|
|
170
|
+
return { label, passed: false, detail: `error: ${formatError(err)}`, hint };
|
|
133
171
|
}
|
|
134
172
|
}
|
|
135
173
|
async function checkGitignore(projectDir) {
|
|
@@ -137,18 +175,42 @@ async function checkGitignore(projectDir) {
|
|
|
137
175
|
const required = [".ralph/logs/", "_bmad-output/"];
|
|
138
176
|
try {
|
|
139
177
|
const content = await readFile(join(projectDir, ".gitignore"), "utf-8");
|
|
140
|
-
|
|
178
|
+
// Use line-by-line comparison to avoid substring matching issues
|
|
179
|
+
const existingLines = new Set(content
|
|
180
|
+
.split(/\r?\n/)
|
|
181
|
+
.map((line) => line.trim())
|
|
182
|
+
.filter(Boolean));
|
|
183
|
+
const missing = required.filter((e) => !existingLines.has(e));
|
|
141
184
|
if (missing.length === 0) {
|
|
142
185
|
return { label, passed: true };
|
|
143
186
|
}
|
|
144
|
-
return {
|
|
187
|
+
return {
|
|
188
|
+
label,
|
|
189
|
+
passed: false,
|
|
190
|
+
detail: `missing: ${missing.join(", ")}`,
|
|
191
|
+
hint: `Add to .gitignore: ${missing.join(" ")}`,
|
|
192
|
+
};
|
|
145
193
|
}
|
|
146
|
-
catch {
|
|
147
|
-
|
|
194
|
+
catch (err) {
|
|
195
|
+
if (isEnoent(err)) {
|
|
196
|
+
return {
|
|
197
|
+
label,
|
|
198
|
+
passed: false,
|
|
199
|
+
detail: ".gitignore not found",
|
|
200
|
+
hint: "Create .gitignore with: .ralph/logs/ _bmad-output/",
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
return {
|
|
204
|
+
label,
|
|
205
|
+
passed: false,
|
|
206
|
+
detail: `error: ${formatError(err)}`,
|
|
207
|
+
hint: "Check file permissions on .gitignore",
|
|
208
|
+
};
|
|
148
209
|
}
|
|
149
210
|
}
|
|
150
211
|
async function checkVersionMarker(projectDir) {
|
|
151
212
|
const label = "version marker matches";
|
|
213
|
+
const hint = "Run: bmalph upgrade";
|
|
152
214
|
try {
|
|
153
215
|
const content = await readFile(join(projectDir, ".ralph/ralph_loop.sh"), "utf-8");
|
|
154
216
|
const match = content.match(/# bmalph-version: (.+)/);
|
|
@@ -160,9 +222,216 @@ async function checkVersionMarker(projectDir) {
|
|
|
160
222
|
if (match[1].trim() === current) {
|
|
161
223
|
return { label, passed: true, detail: `v${current}` };
|
|
162
224
|
}
|
|
163
|
-
return {
|
|
225
|
+
return {
|
|
226
|
+
label,
|
|
227
|
+
passed: false,
|
|
228
|
+
detail: `installed: ${match[1].trim()}, current: ${current}`,
|
|
229
|
+
hint,
|
|
230
|
+
};
|
|
164
231
|
}
|
|
165
|
-
catch {
|
|
166
|
-
|
|
232
|
+
catch (err) {
|
|
233
|
+
if (isEnoent(err)) {
|
|
234
|
+
return { label, passed: true, detail: "no marker found" };
|
|
235
|
+
}
|
|
236
|
+
return { label, passed: false, detail: `error: ${formatError(err)}`, hint };
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
async function checkUpstreamVersions(projectDir) {
|
|
240
|
+
const label = "upstream versions tracked";
|
|
241
|
+
const hint = "Run: bmalph upgrade";
|
|
242
|
+
try {
|
|
243
|
+
const config = await readConfig(projectDir);
|
|
244
|
+
if (!config) {
|
|
245
|
+
return { label, passed: false, detail: "config not found", hint: "Run: bmalph init" };
|
|
246
|
+
}
|
|
247
|
+
if (!config.upstreamVersions) {
|
|
248
|
+
return { label, passed: true, detail: "not tracked (pre-1.2.0 install)" };
|
|
249
|
+
}
|
|
250
|
+
const bundled = getBundledVersions();
|
|
251
|
+
const { bmadCommit } = config.upstreamVersions;
|
|
252
|
+
const bmadMatch = bmadCommit === bundled.bmadCommit;
|
|
253
|
+
if (bmadMatch) {
|
|
254
|
+
return {
|
|
255
|
+
label,
|
|
256
|
+
passed: true,
|
|
257
|
+
detail: `BMAD:${bmadCommit.slice(0, 8)}`,
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
return {
|
|
261
|
+
label,
|
|
262
|
+
passed: false,
|
|
263
|
+
detail: `outdated: BMAD:${bmadCommit.slice(0, 8)}→${bundled.bmadCommit.slice(0, 8)}`,
|
|
264
|
+
hint,
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
catch (err) {
|
|
268
|
+
return { label, passed: false, detail: `error: ${formatError(err)}`, hint };
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
async function checkCircuitBreaker(projectDir) {
|
|
272
|
+
const label = "circuit breaker";
|
|
273
|
+
const statePath = join(projectDir, ".ralph/.circuit_breaker_state");
|
|
274
|
+
try {
|
|
275
|
+
const content = await readFile(statePath, "utf-8");
|
|
276
|
+
const parsed = JSON.parse(content);
|
|
277
|
+
const state = validateCircuitBreakerState(parsed);
|
|
278
|
+
if (state.state === "CLOSED") {
|
|
279
|
+
return {
|
|
280
|
+
label,
|
|
281
|
+
passed: true,
|
|
282
|
+
detail: `CLOSED (${state.consecutive_no_progress} loops without progress)`,
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
if (state.state === "HALF_OPEN") {
|
|
286
|
+
return { label, passed: true, detail: `HALF_OPEN - monitoring` };
|
|
287
|
+
}
|
|
288
|
+
// OPEN state is a failure
|
|
289
|
+
return {
|
|
290
|
+
label,
|
|
291
|
+
passed: false,
|
|
292
|
+
detail: `OPEN - ${state.reason ?? "stagnation detected"}`,
|
|
293
|
+
hint: "Ralph detected stagnation. Review logs with: bmalph status",
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
catch (err) {
|
|
297
|
+
if (isEnoent(err)) {
|
|
298
|
+
return { label, passed: true, detail: "not running" };
|
|
299
|
+
}
|
|
300
|
+
return {
|
|
301
|
+
label,
|
|
302
|
+
passed: false,
|
|
303
|
+
detail: "corrupt state file",
|
|
304
|
+
hint: "Delete .ralph/.circuit_breaker_state and restart Ralph",
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
async function checkRalphSession(projectDir) {
|
|
309
|
+
const label = "Ralph session";
|
|
310
|
+
const sessionPath = join(projectDir, ".ralph/.ralph_session");
|
|
311
|
+
try {
|
|
312
|
+
const content = await readFile(sessionPath, "utf-8");
|
|
313
|
+
const parsed = JSON.parse(content);
|
|
314
|
+
const session = validateRalphSession(parsed);
|
|
315
|
+
if (!session.session_id || session.session_id === "") {
|
|
316
|
+
return { label, passed: true, detail: "no active session" };
|
|
317
|
+
}
|
|
318
|
+
const createdAt = new Date(session.created_at);
|
|
319
|
+
const now = new Date();
|
|
320
|
+
const ageMs = now.getTime() - createdAt.getTime();
|
|
321
|
+
// Handle negative age (future timestamp) gracefully
|
|
322
|
+
if (ageMs < 0) {
|
|
323
|
+
return {
|
|
324
|
+
label,
|
|
325
|
+
passed: false,
|
|
326
|
+
detail: "invalid timestamp (future)",
|
|
327
|
+
hint: "Delete .ralph/.ralph_session to reset",
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
const ageHours = Math.floor(ageMs / (1000 * 60 * 60));
|
|
331
|
+
const ageMinutes = Math.floor((ageMs % (1000 * 60 * 60)) / (1000 * 60));
|
|
332
|
+
const ageStr = ageHours > 0 ? `${ageHours}h${ageMinutes}m` : `${ageMinutes}m`;
|
|
333
|
+
// Warn if session is older than threshold
|
|
334
|
+
const maxAgeHours = Math.floor(SESSION_AGE_WARNING_MS / (1000 * 60 * 60));
|
|
335
|
+
if (ageMs >= SESSION_AGE_WARNING_MS) {
|
|
336
|
+
return {
|
|
337
|
+
label,
|
|
338
|
+
passed: false,
|
|
339
|
+
detail: `${ageStr} old (max ${maxAgeHours}h)`,
|
|
340
|
+
hint: "Session is stale. Start a fresh Ralph session",
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
return { label, passed: true, detail: ageStr };
|
|
344
|
+
}
|
|
345
|
+
catch (err) {
|
|
346
|
+
if (isEnoent(err)) {
|
|
347
|
+
return { label, passed: true, detail: "no active session" };
|
|
348
|
+
}
|
|
349
|
+
return {
|
|
350
|
+
label,
|
|
351
|
+
passed: false,
|
|
352
|
+
detail: "corrupt session file",
|
|
353
|
+
hint: "Delete .ralph/.ralph_session to reset",
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
async function checkApiCalls(projectDir) {
|
|
358
|
+
const label = "API calls this hour";
|
|
359
|
+
const statusPath = join(projectDir, RALPH_STATUS_FILE);
|
|
360
|
+
try {
|
|
361
|
+
const content = await readFile(statusPath, "utf-8");
|
|
362
|
+
const parsed = JSON.parse(content);
|
|
363
|
+
const status = validateRalphApiStatus(parsed);
|
|
364
|
+
const calls = status.calls_made_this_hour;
|
|
365
|
+
const max = status.max_calls_per_hour;
|
|
366
|
+
// Avoid division by zero
|
|
367
|
+
if (max <= 0) {
|
|
368
|
+
return { label, passed: true, detail: `${calls}/unlimited` };
|
|
369
|
+
}
|
|
370
|
+
const percentage = (calls / max) * 100;
|
|
371
|
+
// Warn if approaching limit
|
|
372
|
+
if (percentage >= API_USAGE_WARNING_PERCENT) {
|
|
373
|
+
return {
|
|
374
|
+
label,
|
|
375
|
+
passed: false,
|
|
376
|
+
detail: `${calls}/${max} (approaching limit)`,
|
|
377
|
+
hint: "Wait for rate limit reset or increase API quota",
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
return { label, passed: true, detail: `${calls}/${max}` };
|
|
381
|
+
}
|
|
382
|
+
catch (err) {
|
|
383
|
+
if (isEnoent(err)) {
|
|
384
|
+
return { label, passed: true, detail: "not running" };
|
|
385
|
+
}
|
|
386
|
+
return {
|
|
387
|
+
label,
|
|
388
|
+
passed: false,
|
|
389
|
+
detail: "corrupt status file",
|
|
390
|
+
hint: "Delete .ralph/status.json to reset",
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
async function checkUpstreamGitHubStatus(_projectDir) {
|
|
395
|
+
const label = "upstream status";
|
|
396
|
+
try {
|
|
397
|
+
const bundled = getBundledVersions();
|
|
398
|
+
const result = await checkUpstream(bundled);
|
|
399
|
+
// Check if request failed
|
|
400
|
+
if (result.bmad === null) {
|
|
401
|
+
const reason = getSkipReason(result.errors);
|
|
402
|
+
return { label, passed: true, detail: `skipped: ${reason}` };
|
|
403
|
+
}
|
|
404
|
+
return {
|
|
405
|
+
label,
|
|
406
|
+
passed: true,
|
|
407
|
+
detail: `BMAD: ${result.bmad.isUpToDate ? "up to date" : "behind"}`,
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
catch (err) {
|
|
411
|
+
return { label, passed: true, detail: `skipped: ${formatError(err)}` };
|
|
167
412
|
}
|
|
168
413
|
}
|
|
414
|
+
// =============================================================================
|
|
415
|
+
// Check Registry - defines all checks in execution order
|
|
416
|
+
// =============================================================================
|
|
417
|
+
/**
|
|
418
|
+
* Registry of all doctor checks in execution order.
|
|
419
|
+
* Each check has a unique ID and a run function that takes a project directory.
|
|
420
|
+
*/
|
|
421
|
+
export const CHECK_REGISTRY = [
|
|
422
|
+
{ id: "node-version", run: checkNodeVersion },
|
|
423
|
+
{ id: "bash-available", run: checkBash },
|
|
424
|
+
{ id: "config-valid", run: checkConfig },
|
|
425
|
+
{ id: "bmad-dir", run: checkBmadDir },
|
|
426
|
+
{ id: "ralph-loop", run: checkRalphLoop },
|
|
427
|
+
{ id: "ralph-lib", run: checkRalphLib },
|
|
428
|
+
{ id: "slash-command", run: checkSlashCommand },
|
|
429
|
+
{ id: "claude-md", run: checkClaudeMd },
|
|
430
|
+
{ id: "gitignore", run: checkGitignore },
|
|
431
|
+
{ id: "version-marker", run: checkVersionMarker },
|
|
432
|
+
{ id: "upstream-versions", run: checkUpstreamVersions },
|
|
433
|
+
{ id: "circuit-breaker", run: checkCircuitBreaker },
|
|
434
|
+
{ id: "ralph-session", run: checkRalphSession },
|
|
435
|
+
{ id: "api-calls", run: checkApiCalls },
|
|
436
|
+
{ id: "upstream-github", run: checkUpstreamGitHubStatus },
|
|
437
|
+
];
|
package/dist/commands/init.d.ts
CHANGED
package/dist/commands/init.js
CHANGED
|
@@ -1,27 +1,40 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
2
|
import inquirer from "inquirer";
|
|
3
3
|
import { writeConfig } from "../utils/config.js";
|
|
4
|
-
import { installProject, mergeClaudeMd, isInitialized } from "../installer.js";
|
|
4
|
+
import { installProject, mergeClaudeMd, isInitialized, previewInstall, getBundledVersions, } from "../installer.js";
|
|
5
|
+
import { formatDryRunSummary } from "../utils/dryrun.js";
|
|
6
|
+
import { validateProjectName } from "../utils/validate.js";
|
|
7
|
+
import { withErrorHandling } from "../utils/errors.js";
|
|
5
8
|
export async function initCommand(options) {
|
|
6
|
-
|
|
7
|
-
await runInit(options);
|
|
8
|
-
}
|
|
9
|
-
catch (err) {
|
|
10
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
11
|
-
console.error(chalk.red(`Error: ${message}`));
|
|
12
|
-
process.exit(1);
|
|
13
|
-
}
|
|
9
|
+
await withErrorHandling(() => runInit(options));
|
|
14
10
|
}
|
|
15
11
|
async function runInit(options) {
|
|
16
|
-
const projectDir =
|
|
12
|
+
const projectDir = options.projectDir;
|
|
17
13
|
if (await isInitialized(projectDir)) {
|
|
18
14
|
console.log(chalk.yellow("bmalph is already initialized in this project."));
|
|
19
|
-
console.log("Use 'bmalph
|
|
15
|
+
console.log("Use 'bmalph upgrade' to update bundled assets to the latest version.");
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
// Handle dry-run mode
|
|
19
|
+
if (options.dryRun) {
|
|
20
|
+
const preview = await previewInstall(projectDir);
|
|
21
|
+
const actions = [
|
|
22
|
+
...preview.wouldCreate.map((p) => ({ type: "create", path: p })),
|
|
23
|
+
...preview.wouldModify.map((p) => ({ type: "modify", path: p })),
|
|
24
|
+
...preview.wouldSkip.map((p) => ({ type: "skip", path: p })),
|
|
25
|
+
];
|
|
26
|
+
console.log(formatDryRunSummary(actions));
|
|
20
27
|
return;
|
|
21
28
|
}
|
|
22
29
|
let name = options.name;
|
|
23
30
|
let description = options.description;
|
|
24
31
|
if (!name || !description) {
|
|
32
|
+
if (!process.stdin.isTTY) {
|
|
33
|
+
throw new Error("Non-interactive mode requires --name and --description flags");
|
|
34
|
+
}
|
|
35
|
+
// Derive default name from directory, with fallback for edge cases
|
|
36
|
+
const dirName = projectDir.split(/[/\\]/).pop();
|
|
37
|
+
const defaultName = dirName && dirName.trim() ? dirName : "my-project";
|
|
25
38
|
const answers = await inquirer.prompt([
|
|
26
39
|
...(name
|
|
27
40
|
? []
|
|
@@ -30,7 +43,7 @@ async function runInit(options) {
|
|
|
30
43
|
type: "input",
|
|
31
44
|
name: "name",
|
|
32
45
|
message: "Project name:",
|
|
33
|
-
default:
|
|
46
|
+
default: defaultName,
|
|
34
47
|
},
|
|
35
48
|
]),
|
|
36
49
|
...(description
|
|
@@ -46,15 +59,28 @@ async function runInit(options) {
|
|
|
46
59
|
name = name ?? answers.name;
|
|
47
60
|
description = description ?? answers.description;
|
|
48
61
|
}
|
|
62
|
+
// Validate project name (filesystem safety, reserved names, etc.)
|
|
63
|
+
if (!name) {
|
|
64
|
+
throw new Error("Project name cannot be empty");
|
|
65
|
+
}
|
|
66
|
+
const validatedName = validateProjectName(name);
|
|
49
67
|
console.log(chalk.blue("\nInstalling BMAD + Ralph..."));
|
|
50
68
|
await installProject(projectDir);
|
|
69
|
+
const bundledVersions = getBundledVersions();
|
|
51
70
|
const config = {
|
|
52
|
-
name:
|
|
71
|
+
name: validatedName,
|
|
53
72
|
description: description ?? "",
|
|
54
73
|
createdAt: new Date().toISOString(),
|
|
74
|
+
upstreamVersions: bundledVersions,
|
|
55
75
|
};
|
|
56
|
-
|
|
57
|
-
|
|
76
|
+
try {
|
|
77
|
+
await writeConfig(projectDir, config);
|
|
78
|
+
await mergeClaudeMd(projectDir);
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
throw new Error(`Partial installation: files were copied but configuration failed. ` +
|
|
82
|
+
`Run 'bmalph init' again to retry.`, { cause: err });
|
|
83
|
+
}
|
|
58
84
|
console.log(chalk.green("\nbmalph initialized successfully!"));
|
|
59
85
|
console.log(`\n Project: ${chalk.bold(config.name)}`);
|
|
60
86
|
console.log(`\nInstalled:`);
|
|
@@ -1 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
interface StatusOptions {
|
|
2
|
+
json?: boolean;
|
|
3
|
+
projectDir: string;
|
|
4
|
+
}
|
|
5
|
+
export declare function statusCommand(options: StatusOptions): Promise<void>;
|
|
6
|
+
export declare function runStatus(options: StatusOptions): Promise<void>;
|
|
7
|
+
export {};
|