bmad-method-quarkus 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/.claude-plugin/marketplace.json +53 -0
- package/AGENTS.md +12 -0
- package/LICENSE +30 -0
- package/README.md +94 -0
- package/README_CN.md +108 -0
- package/README_VN.md +109 -0
- package/bmad-modules.yaml +133 -0
- package/package.json +123 -0
- package/removals.txt +87 -0
- package/src/bmm-skills/agents/bmad-agent-analyst/SKILL.md +76 -0
- package/src/bmm-skills/agents/bmad-agent-analyst/customize.toml +105 -0
- package/src/bmm-skills/agents/bmad-agent-architect/SKILL.md +76 -0
- package/src/bmm-skills/agents/bmad-agent-architect/customize.toml +65 -0
- package/src/bmm-skills/agents/bmad-agent-dev/SKILL.md +76 -0
- package/src/bmm-skills/agents/bmad-agent-dev/customize.toml +83 -0
- package/src/bmm-skills/agents/bmad-agent-pm/SKILL.md +76 -0
- package/src/bmm-skills/agents/bmad-agent-pm/customize.toml +75 -0
- package/src/bmm-skills/agents/bmad-agent-ux-designer/SKILL.md +76 -0
- package/src/bmm-skills/agents/bmad-agent-ux-designer/customize.toml +60 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/.memlog.md +12 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/.memlog.md:Zone.Identifier +0 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/SKILL.md +86 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/SKILL.md:Zone.Identifier +0 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/customize.toml +37 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/customize.toml:Zone.Identifier +0 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/references/enrich-stories.md +19 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/references/enrich-stories.md:Zone.Identifier +0 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/references/prompt-quality-canon.md +79 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/references/prompt-quality-canon.md:Zone.Identifier +0 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/bqa-setup/SKILL.md +80 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/bqa-setup/SKILL.md:Zone.Identifier +0 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/bqa-setup/assets/module-help.csv +9 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/bqa-setup/assets/module-help.csv:Zone.Identifier +0 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/bqa-setup/assets/module.yaml +16 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/bqa-setup/assets/module.yaml:Zone.Identifier +0 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/bqa-setup/scripts/cleanup-legacy.py +287 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/bqa-setup/scripts/cleanup-legacy.py:Zone.Identifier +0 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/bqa-setup/scripts/merge-config.py +441 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/bqa-setup/scripts/merge-config.py:Zone.Identifier +0 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/bqa-setup/scripts/merge-help-csv.py +246 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/bqa-setup/scripts/merge-help-csv.py:Zone.Identifier +0 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/quarkus-error-handling-i18n/SKILL.md +181 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/quarkus-error-handling-i18n/SKILL.md:Zone.Identifier +0 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/quarkus-grpc-services/SKILL.md +141 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/quarkus-grpc-services/SKILL.md:Zone.Identifier +0 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/quarkus-hexagonal-core/SKILL.md +392 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/quarkus-hexagonal-core/SKILL.md:Zone.Identifier +0 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/quarkus-kafka-messaging/SKILL.md +148 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/quarkus-kafka-messaging/SKILL.md:Zone.Identifier +0 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/quarkus-observability-otel/SKILL.md +180 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/quarkus-observability-otel/SKILL.md:Zone.Identifier +0 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/quarkus-openapi-tmforum/SKILL.md +128 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/quarkus-openapi-tmforum/SKILL.md:Zone.Identifier +0 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/quarkus-sql-jdbc-agroal/SKILL.md +245 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/quarkus-sql-jdbc-agroal/SKILL.md:Zone.Identifier +0 -0
- package/src/bmm-skills/module-help.csv +19 -0
- package/src/bmm-skills/module.yaml +92 -0
- package/src/bmm-skills/plan/bmad-architecture/SKILL.md +85 -0
- package/src/bmm-skills/plan/bmad-architecture/assets/spine-template.md +79 -0
- package/src/bmm-skills/plan/bmad-architecture/customize.toml +102 -0
- package/src/bmm-skills/plan/bmad-architecture/references/headless.md +26 -0
- package/src/bmm-skills/plan/bmad-architecture/references/reviewer-gate.md +13 -0
- package/src/bmm-skills/plan/bmad-architecture/scripts/lint_spine.py +257 -0
- package/src/bmm-skills/plan/bmad-architecture/scripts/tests/test_lint_spine.py +270 -0
- package/src/bmm-skills/plan/bmad-create-epics-and-stories/SKILL.md +93 -0
- package/src/bmm-skills/plan/bmad-create-epics-and-stories/customize.toml +41 -0
- package/src/bmm-skills/plan/bmad-create-epics-and-stories/steps/step-01-validate-prerequisites.md +263 -0
- package/src/bmm-skills/plan/bmad-create-epics-and-stories/steps/step-02-design-epics.md +242 -0
- package/src/bmm-skills/plan/bmad-create-epics-and-stories/steps/step-03-create-stories.md +255 -0
- package/src/bmm-skills/plan/bmad-create-epics-and-stories/steps/step-04-final-validation.md +143 -0
- package/src/bmm-skills/plan/bmad-create-epics-and-stories/templates/epics-template.md +61 -0
- package/src/bmm-skills/plan/bmad-generate-project-context/SKILL.md +10 -0
- package/src/bmm-skills/plan/bmad-prd/SKILL.md +94 -0
- package/src/bmm-skills/plan/bmad-prd/assets/headless-schemas.md +76 -0
- package/src/bmm-skills/plan/bmad-prd/assets/prd-template.md +165 -0
- package/src/bmm-skills/plan/bmad-prd/assets/prd-validation-checklist.md +135 -0
- package/src/bmm-skills/plan/bmad-prd/assets/validation-report-template.html +325 -0
- package/src/bmm-skills/plan/bmad-prd/customize.toml +149 -0
- package/src/bmm-skills/plan/bmad-prd/references/headless.md +39 -0
- package/src/bmm-skills/plan/bmad-prd/references/validate.md +97 -0
- package/src/bmm-skills/plan/bmad-prfaq/SKILL.md +135 -0
- package/src/bmm-skills/plan/bmad-prfaq/agents/artifact-analyzer.md +60 -0
- package/src/bmm-skills/plan/bmad-prfaq/agents/web-researcher.md +49 -0
- package/src/bmm-skills/plan/bmad-prfaq/assets/prfaq-template.md +62 -0
- package/src/bmm-skills/plan/bmad-prfaq/bmad-manifest.json +16 -0
- package/src/bmm-skills/plan/bmad-prfaq/customize.toml +41 -0
- package/src/bmm-skills/plan/bmad-prfaq/references/customer-faq.md +55 -0
- package/src/bmm-skills/plan/bmad-prfaq/references/internal-faq.md +51 -0
- package/src/bmm-skills/plan/bmad-prfaq/references/press-release.md +60 -0
- package/src/bmm-skills/plan/bmad-prfaq/references/verdict.md +83 -0
- package/src/bmm-skills/plan/bmad-product-brief/SKILL.md +91 -0
- package/src/bmm-skills/plan/bmad-product-brief/assets/brief-template.md +41 -0
- package/src/bmm-skills/plan/bmad-product-brief/customize.toml +101 -0
- package/src/bmm-skills/plan/bmad-project-context/SKILL.md +110 -0
- package/src/bmm-skills/plan/bmad-project-context/customize.toml +24 -0
- package/src/bmm-skills/plan/bmad-project-context/references/best-practices.md +65 -0
- package/src/bmm-skills/plan/bmad-project-context/references/template.md +55 -0
- package/src/bmm-skills/plan/bmad-spec/SKILL.md +160 -0
- package/src/bmm-skills/plan/bmad-spec/assets/headless-schemas.md +33 -0
- package/src/bmm-skills/plan/bmad-spec/assets/spec-template.md +49 -0
- package/src/bmm-skills/plan/bmad-spec/assets/stories-schema.md +44 -0
- package/src/bmm-skills/plan/bmad-spec/customize.toml +52 -0
- package/src/bmm-skills/plan/bmad-sprint-planning/SKILL.md +62 -0
- package/src/bmm-skills/plan/bmad-sprint-planning/customize.toml +41 -0
- package/src/bmm-skills/plan/bmad-sprint-planning/references/fix-sprint-status.md +30 -0
- package/src/bmm-skills/plan/bmad-sprint-planning/references/generate-tracking.md +25 -0
- package/src/bmm-skills/plan/bmad-sprint-planning/references/readiness-gate.md +20 -0
- package/src/bmm-skills/plan/bmad-sprint-planning/references/status-view.md +14 -0
- package/src/bmm-skills/plan/bmad-sprint-planning/references/validate.md +10 -0
- package/src/bmm-skills/plan/bmad-sprint-planning/scripts/__pycache__/sprint_plan.cpython-311.pyc +0 -0
- package/src/bmm-skills/plan/bmad-sprint-planning/scripts/sprint_plan.py +697 -0
- package/src/bmm-skills/plan/bmad-sprint-planning/scripts/tests/__pycache__/test_sprint_plan.cpython-311-pytest-9.1.1.pyc +0 -0
- package/src/bmm-skills/plan/bmad-sprint-planning/scripts/tests/test_sprint_plan.py +524 -0
- package/src/bmm-skills/plan/bmad-sprint-planning/sprint-status-template.yaml +71 -0
- package/src/bmm-skills/plan/bmad-ux/SKILL.md +90 -0
- package/src/bmm-skills/plan/bmad-ux/assets/color-themes.md +9 -0
- package/src/bmm-skills/plan/bmad-ux/assets/design-directions.md +9 -0
- package/src/bmm-skills/plan/bmad-ux/assets/design-example-editorial.md +158 -0
- package/src/bmm-skills/plan/bmad-ux/assets/design-example-mobile.md +93 -0
- package/src/bmm-skills/plan/bmad-ux/assets/design-example-shadcn.md +109 -0
- package/src/bmm-skills/plan/bmad-ux/assets/excalidraw-wireframe.md +19 -0
- package/src/bmm-skills/plan/bmad-ux/assets/experience-example-mobile.md +112 -0
- package/src/bmm-skills/plan/bmad-ux/assets/experience-example-shadcn.md +133 -0
- package/src/bmm-skills/plan/bmad-ux/assets/headless-schemas.md +84 -0
- package/src/bmm-skills/plan/bmad-ux/assets/key-screens.md +29 -0
- package/src/bmm-skills/plan/bmad-ux/assets/validation-report-template.html +319 -0
- package/src/bmm-skills/plan/bmad-ux/customize.toml +102 -0
- package/src/bmm-skills/plan/bmad-ux/references/creative-tools.md +19 -0
- package/src/bmm-skills/plan/bmad-ux/references/design-md-spec.md +50 -0
- package/src/bmm-skills/plan/bmad-ux/references/headless.md +37 -0
- package/src/bmm-skills/plan/bmad-ux/references/validate.md +115 -0
- package/src/bmm-skills/ship/bmad-build/SKILL.md +13 -0
- package/src/bmm-skills/ship/bmad-build/compile-epic-context.md +62 -0
- package/src/bmm-skills/ship/bmad-build/customize.toml +164 -0
- package/src/bmm-skills/ship/bmad-build/references/deletion-check.md +14 -0
- package/src/bmm-skills/ship/bmad-build/review-prompts/edge-case-hunter.md +88 -0
- package/src/bmm-skills/ship/bmad-build/review-prompts/verification-gap.md +113 -0
- package/src/bmm-skills/ship/bmad-build/spec-template.md +89 -0
- package/src/bmm-skills/ship/bmad-build/step-01-clarify-and-route.md +105 -0
- package/src/bmm-skills/ship/bmad-build/step-02-plan.md +47 -0
- package/src/bmm-skills/ship/bmad-build/step-03-implement.md +49 -0
- package/src/bmm-skills/ship/bmad-build/step-04-review.md +55 -0
- package/src/bmm-skills/ship/bmad-build/step-05-present.md +75 -0
- package/src/bmm-skills/ship/bmad-build/step-oneshot.md +77 -0
- package/src/bmm-skills/ship/bmad-build/sync-sprint-status.md +19 -0
- package/src/bmm-skills/ship/bmad-build/workflow.md +84 -0
- package/src/bmm-skills/ship/bmad-build-auto/SKILL.md +13 -0
- package/src/bmm-skills/ship/bmad-build-auto/compile-epic-context.md +62 -0
- package/src/bmm-skills/ship/bmad-build-auto/customize.toml +121 -0
- package/src/bmm-skills/ship/bmad-build-auto/references/deletion-check.md +14 -0
- package/src/bmm-skills/ship/bmad-build-auto/review-prompts/edge-case-hunter.md +88 -0
- package/src/bmm-skills/ship/bmad-build-auto/review-prompts/verification-gap.md +113 -0
- package/src/bmm-skills/ship/bmad-build-auto/spec-template.md +99 -0
- package/src/bmm-skills/ship/bmad-build-auto/step-01-clarify-and-route.md +83 -0
- package/src/bmm-skills/ship/bmad-build-auto/step-02-plan.md +27 -0
- package/src/bmm-skills/ship/bmad-build-auto/step-03-implement.md +44 -0
- package/src/bmm-skills/ship/bmad-build-auto/step-04-review.md +96 -0
- package/src/bmm-skills/ship/bmad-build-auto/workflow.md +104 -0
- package/src/bmm-skills/ship/bmad-checkpoint-preview/SKILL.md +68 -0
- package/src/bmm-skills/ship/bmad-checkpoint-preview/customize.toml +41 -0
- package/src/bmm-skills/ship/bmad-checkpoint-preview/generate-trail.md +38 -0
- package/src/bmm-skills/ship/bmad-checkpoint-preview/step-01-orientation.md +105 -0
- package/src/bmm-skills/ship/bmad-checkpoint-preview/step-02-walkthrough.md +89 -0
- package/src/bmm-skills/ship/bmad-checkpoint-preview/step-03-detail-pass.md +106 -0
- package/src/bmm-skills/ship/bmad-checkpoint-preview/step-04-testing.md +74 -0
- package/src/bmm-skills/ship/bmad-checkpoint-preview/step-05-wrapup.md +30 -0
- package/src/bmm-skills/ship/bmad-code-review/SKILL.md +90 -0
- package/src/bmm-skills/ship/bmad-code-review/customize.toml +113 -0
- package/src/bmm-skills/ship/bmad-code-review/references/deletion-check.md +14 -0
- package/src/bmm-skills/ship/bmad-code-review/review-prompts/edge-case-hunter.md +88 -0
- package/src/bmm-skills/ship/bmad-code-review/review-prompts/verification-gap.md +113 -0
- package/src/bmm-skills/ship/bmad-code-review/steps/step-01-gather-context.md +87 -0
- package/src/bmm-skills/ship/bmad-code-review/steps/step-02-review.md +32 -0
- package/src/bmm-skills/ship/bmad-code-review/steps/step-03-triage.md +50 -0
- package/src/bmm-skills/ship/bmad-code-review/steps/step-04-present.md +132 -0
- package/src/bmm-skills/ship/bmad-correct-course/SKILL.md +300 -0
- package/src/bmm-skills/ship/bmad-correct-course/checklist.md +288 -0
- package/src/bmm-skills/ship/bmad-correct-course/customize.toml +41 -0
- package/src/bmm-skills/ship/bmad-qa-generate-e2e-tests/SKILL.md +176 -0
- package/src/bmm-skills/ship/bmad-qa-generate-e2e-tests/checklist.md +33 -0
- package/src/bmm-skills/ship/bmad-qa-generate-e2e-tests/customize.toml +41 -0
- package/src/bmm-skills/ship/bmad-retrospective/SKILL.md +94 -0
- package/src/bmm-skills/ship/bmad-retrospective/customize.toml +41 -0
- package/src/bmm-skills/ship/bmad-retrospective/references/acceptance-verdict.md +55 -0
- package/src/bmm-skills/ship/bmad-retrospective/references/aggregate-views.md +17 -0
- package/src/bmm-skills/ship/bmad-retrospective/references/evidence-gathering.md +30 -0
- package/src/bmm-skills/ship/bmad-retrospective/references/retro-document.md +84 -0
- package/src/bmm-skills/ship/bmad-retrospective/references/team-discussion.md +22 -0
- package/src/bmm-skills/ship/bmad-retrospective/scripts/__pycache__/sprint_status.cpython-311.pyc +0 -0
- package/src/bmm-skills/ship/bmad-retrospective/scripts/git_evidence.py +304 -0
- package/src/bmm-skills/ship/bmad-retrospective/scripts/sprint_status.py +746 -0
- package/src/bmm-skills/ship/bmad-retrospective/scripts/tests/__pycache__/test_git_evidence.cpython-311-pytest-9.1.1.pyc +0 -0
- package/src/bmm-skills/ship/bmad-retrospective/scripts/tests/__pycache__/test_sprint_status.cpython-311-pytest-9.1.1.pyc +0 -0
- package/src/bmm-skills/ship/bmad-retrospective/scripts/tests/fixtures/sprint-status-template.yaml +71 -0
- package/src/bmm-skills/ship/bmad-retrospective/scripts/tests/test_git_evidence.py +750 -0
- package/src/bmm-skills/ship/bmad-retrospective/scripts/tests/test_sprint_status.py +1579 -0
- package/src/bmm-skills/v6-shims/README.md +28 -0
- package/src/bmm-skills/v6-shims/bmad-create-architecture/SKILL.md +30 -0
- package/src/bmm-skills/v6-shims/bmad-create-architecture/customize.toml +41 -0
- package/src/bmm-skills/v6-shims/bmad-create-prd/SKILL.md +30 -0
- package/src/bmm-skills/v6-shims/bmad-create-prd/customize.toml +41 -0
- package/src/bmm-skills/v6-shims/bmad-create-story/SKILL.md +434 -0
- package/src/bmm-skills/v6-shims/bmad-create-story/checklist.md +357 -0
- package/src/bmm-skills/v6-shims/bmad-create-story/customize.toml +41 -0
- package/src/bmm-skills/v6-shims/bmad-create-story/discover-inputs.md +88 -0
- package/src/bmm-skills/v6-shims/bmad-create-story/template.md +49 -0
- package/src/bmm-skills/v6-shims/bmad-dev-auto/SKILL.md +19 -0
- package/src/bmm-skills/v6-shims/bmad-dev-story/SKILL.md +502 -0
- package/src/bmm-skills/v6-shims/bmad-dev-story/checklist.md +80 -0
- package/src/bmm-skills/v6-shims/bmad-dev-story/customize.toml +44 -0
- package/src/bmm-skills/v6-shims/bmad-document-project/SKILL.md +14 -0
- package/src/bmm-skills/v6-shims/bmad-domain-research/SKILL.md +14 -0
- package/src/bmm-skills/v6-shims/bmad-edit-prd/SKILL.md +30 -0
- package/src/bmm-skills/v6-shims/bmad-edit-prd/customize.toml +42 -0
- package/src/bmm-skills/v6-shims/bmad-market-research/SKILL.md +14 -0
- package/src/bmm-skills/v6-shims/bmad-quick-dev/SKILL.md +19 -0
- package/src/bmm-skills/v6-shims/bmad-sprint-status/SKILL.md +26 -0
- package/src/bmm-skills/v6-shims/bmad-sprint-status/customize.toml +41 -0
- package/src/bmm-skills/v6-shims/bmad-technical-research/SKILL.md +14 -0
- package/src/bmm-skills/v6-shims/bmad-validate-prd/SKILL.md +30 -0
- package/src/bmm-skills/v6-shims/bmad-validate-prd/customize.toml +42 -0
- package/src/core-skills/bmad-advanced-elicitation/SKILL.md +65 -0
- package/src/core-skills/bmad-advanced-elicitation/assets/methods.csv +72 -0
- package/src/core-skills/bmad-advanced-elicitation/customize.toml +54 -0
- package/src/core-skills/bmad-advanced-elicitation/scripts/pick_methods.py +233 -0
- package/src/core-skills/bmad-advanced-elicitation/scripts/tests/test_pick_methods.py +228 -0
- package/src/core-skills/bmad-brainstorming/SKILL.md +80 -0
- package/src/core-skills/bmad-brainstorming/assets/brain-icons.json +166 -0
- package/src/core-skills/bmad-brainstorming/assets/brain-methods.csv +109 -0
- package/src/core-skills/bmad-brainstorming/assets/brain-selector.html +328 -0
- package/src/core-skills/bmad-brainstorming/customize.toml +84 -0
- package/src/core-skills/bmad-brainstorming/references/converge.md +24 -0
- package/src/core-skills/bmad-brainstorming/references/finalize.md +26 -0
- package/src/core-skills/bmad-brainstorming/references/headless.md +54 -0
- package/src/core-skills/bmad-brainstorming/references/in-chat-techniques.md +18 -0
- package/src/core-skills/bmad-brainstorming/references/mode-autonomous.md +10 -0
- package/src/core-skills/bmad-brainstorming/references/mode-facilitator.md +11 -0
- package/src/core-skills/bmad-brainstorming/references/mode-partner.md +16 -0
- package/src/core-skills/bmad-brainstorming/references/resume.md +5 -0
- package/src/core-skills/bmad-brainstorming/scripts/brain.py +770 -0
- package/src/core-skills/bmad-brainstorming/scripts/tests/test_brain.py +239 -0
- package/src/core-skills/bmad-customize/SKILL.md +111 -0
- package/src/core-skills/bmad-customize/scripts/list_customizable_skills.py +231 -0
- package/src/core-skills/bmad-customize/scripts/tests/test_list_customizable_skills.py +249 -0
- package/src/core-skills/bmad-deep-recon/SKILL.md +82 -0
- package/src/core-skills/bmad-deep-recon/assets/research.template.md +18 -0
- package/src/core-skills/bmad-deep-recon/customize.toml +212 -0
- package/src/core-skills/bmad-deep-recon/references/draft.md +8 -0
- package/src/core-skills/bmad-deep-recon/references/finalize.md +11 -0
- package/src/core-skills/bmad-deep-recon/references/html-briefing.md +16 -0
- package/src/core-skills/bmad-deep-recon/references/lifecycle.md +11 -0
- package/src/core-skills/bmad-deep-recon/references/process.md +10 -0
- package/src/core-skills/bmad-deep-recon/references/run.md +73 -0
- package/src/core-skills/bmad-deep-recon/references/selection.md +13 -0
- package/src/core-skills/bmad-deep-recon/references/synthesis.md +16 -0
- package/src/core-skills/bmad-deep-recon/references/verification.md +29 -0
- package/src/core-skills/bmad-deep-recon/scripts/recon_kit.py +322 -0
- package/src/core-skills/bmad-deep-recon/scripts/tests/test_recon_kit.py +144 -0
- package/src/core-skills/bmad-deep-recon/types/academic-lit.md +19 -0
- package/src/core-skills/bmad-deep-recon/types/competitive.md +19 -0
- package/src/core-skills/bmad-deep-recon/types/domain.md +19 -0
- package/src/core-skills/bmad-deep-recon/types/market.md +19 -0
- package/src/core-skills/bmad-deep-recon/types/technical.md +19 -0
- package/src/core-skills/bmad-deep-recon/types/user-voice.md +19 -0
- package/src/core-skills/bmad-forge-idea/SKILL.md +107 -0
- package/src/core-skills/bmad-forge-idea/customize.toml +42 -0
- package/src/core-skills/bmad-forge-idea/scripts/resolve_personas.py +275 -0
- package/src/core-skills/bmad-forge-idea/scripts/tests/test_resolve_personas.py +138 -0
- package/src/core-skills/bmad-help/SKILL.md +75 -0
- package/src/core-skills/bmad-party-mode/SKILL.md +60 -0
- package/src/core-skills/bmad-party-mode/customize.toml +211 -0
- package/src/core-skills/bmad-party-mode/references/create-party.md +70 -0
- package/src/core-skills/bmad-party-mode/references/mode-agent-team.md +13 -0
- package/src/core-skills/bmad-party-mode/references/mode-auto.md +13 -0
- package/src/core-skills/bmad-party-mode/references/mode-subagent.md +31 -0
- package/src/core-skills/bmad-party-mode/references/party-memory.md +51 -0
- package/src/core-skills/bmad-party-mode/scripts/resolve_party.py +282 -0
- package/src/core-skills/bmad-party-mode/scripts/tests/test_resolve_party.py +146 -0
- package/src/core-skills/bmad-review/SKILL.md +49 -0
- package/src/core-skills/bmad-review/customize.toml +141 -0
- package/src/core-skills/bmad-review/references/editorial-common.md +56 -0
- package/src/core-skills/bmad-review/references/lens-adversarial.md +19 -0
- package/src/core-skills/bmad-review/references/lens-edge-case-hunter.md +54 -0
- package/src/core-skills/bmad-review/references/lens-prose.md +7 -0
- package/src/core-skills/bmad-review/references/lens-structure.md +9 -0
- package/src/core-skills/bmad-review/references/lens-verification-gap.md +92 -0
- package/src/core-skills/bmad-review/references/structure-models.md +44 -0
- package/src/core-skills/bmad-review/scripts/tests/test_word_metrics.py +62 -0
- package/src/core-skills/bmad-review/scripts/word_metrics.py +102 -0
- package/src/core-skills/module-help.csv +10 -0
- package/src/core-skills/module.yaml +38 -0
- package/src/core-skills/v6-shims/README.md +25 -0
- package/src/core-skills/v6-shims/bmad-editorial-review/SKILL.md +6 -0
- package/src/core-skills/v6-shims/bmad-editorial-review/customize.toml +31 -0
- package/src/core-skills/v6-shims/bmad-editorial-review-prose/SKILL.md +6 -0
- package/src/core-skills/v6-shims/bmad-editorial-review-structure/SKILL.md +6 -0
- package/src/core-skills/v6-shims/bmad-review-adversarial-general/SKILL.md +6 -0
- package/src/core-skills/v6-shims/bmad-review-edge-case-hunter/SKILL.md +6 -0
- package/src/core-skills/v6-shims/bmad-review-verification-gap/SKILL.md +6 -0
- package/src/scripts/__pycache__/config_utils.cpython-311.pyc +0 -0
- package/src/scripts/config_utils.py +119 -0
- package/src/scripts/memlog.py +224 -0
- package/src/scripts/render_skill.py +401 -0
- package/src/scripts/resolve_config.py +74 -0
- package/src/scripts/resolve_customization.py +99 -0
- package/src/scripts/tests/__pycache__/test_config_utils.cpython-311.pyc +0 -0
- package/src/scripts/tests/__pycache__/test_resolve_config.cpython-311.pyc +0 -0
- package/src/scripts/tests/__pycache__/test_resolve_customization.cpython-311.pyc +0 -0
- package/src/scripts/tests/test_config_utils.py +85 -0
- package/src/scripts/tests/test_memlog.py +306 -0
- package/src/scripts/tests/test_resolve_config.py +89 -0
- package/src/scripts/tests/test_resolve_customization.py +77 -0
- package/tools/bundle-web-bundles.js +117 -0
- package/tools/format-workflow-md.js +263 -0
- package/tools/installer/README.md +60 -0
- package/tools/installer/bmad-cli.js +105 -0
- package/tools/installer/cli-utils.js +57 -0
- package/tools/installer/commands/install.js +149 -0
- package/tools/installer/commands/status.js +65 -0
- package/tools/installer/commands/uninstall.js +167 -0
- package/tools/installer/core/config.js +73 -0
- package/tools/installer/core/existing-install.js +121 -0
- package/tools/installer/core/install-paths.js +132 -0
- package/tools/installer/core/installer.js +1767 -0
- package/tools/installer/core/legacy-warnings.js +151 -0
- package/tools/installer/core/manifest-generator.js +859 -0
- package/tools/installer/core/manifest.js +433 -0
- package/tools/installer/core/uv-check.js +195 -0
- package/tools/installer/core/wsl-node-check.js +109 -0
- package/tools/installer/file-ops.js +204 -0
- package/tools/installer/fs-native.js +116 -0
- package/tools/installer/ide/_config-driven.js +972 -0
- package/tools/installer/ide/manager.js +324 -0
- package/tools/installer/ide/platform-codes.js +80 -0
- package/tools/installer/ide/platform-codes.yaml +343 -0
- package/tools/installer/ide/shared/installed-skills.js +50 -0
- package/tools/installer/ide/shared/path-utils.js +219 -0
- package/tools/installer/ide/shared/skill-manifest.js +57 -0
- package/tools/installer/install-messages.yaml +37 -0
- package/tools/installer/list-options.js +210 -0
- package/tools/installer/message-loader.js +83 -0
- package/tools/installer/modules/channel-plan.js +203 -0
- package/tools/installer/modules/channel-resolver.js +241 -0
- package/tools/installer/modules/custom-module-manager.js +924 -0
- package/tools/installer/modules/external-manager.js +671 -0
- package/tools/installer/modules/git-env.js +47 -0
- package/tools/installer/modules/module-help-schema.js +13 -0
- package/tools/installer/modules/official-modules.js +2257 -0
- package/tools/installer/modules/plugin-resolver.js +398 -0
- package/tools/installer/modules/version-resolver.js +336 -0
- package/tools/installer/project-root.js +224 -0
- package/tools/installer/prompts.js +791 -0
- package/tools/installer/set-overrides.js +330 -0
- package/tools/installer/ui.js +2167 -0
- package/tools/installer/yaml-format.js +245 -0
- package/tools/javascript-conventions.md +5 -0
- package/tools/migrate-custom-module-paths.js +124 -0
- package/tools/skill-validator.md +378 -0
- package/tools/validate-published-implementation-model.mjs +68 -0
- package/tools/validate-sidebar-order.js +388 -0
- package/tools/validate-skills.js +735 -0
- package/tools/validate-svg-changes.sh +356 -0
- package/web-bundles/README.md +46 -0
- package/web-bundles/brainstorming-coach/INSTRUCTIONS.md +86 -0
- package/web-bundles/brainstorming-coach/SKILL.md +83 -0
- package/web-bundles/brainstorming-coach/brain-methods.csv +62 -0
- package/web-bundles/bundles.json +139 -0
- package/web-bundles/market-and-industry-research/INSTRUCTIONS.md +88 -0
- package/web-bundles/market-and-industry-research/SKILL.md +59 -0
- package/web-bundles/prd-coach/INSTRUCTIONS.md +86 -0
- package/web-bundles/prd-coach/SKILL.md +101 -0
- package/web-bundles/prd-coach/prd-template.md +165 -0
- package/web-bundles/prd-coach/prd-validation-checklist.md +135 -0
- package/web-bundles/prfaq-coach/INSTRUCTIONS.md +86 -0
- package/web-bundles/prfaq-coach/SKILL.md +139 -0
- package/web-bundles/product-brief-coach/INSTRUCTIONS.md +86 -0
- package/web-bundles/product-brief-coach/SKILL.md +113 -0
- package/web-bundles/ux-coach/INSTRUCTIONS.md +92 -0
- package/web-bundles/ux-coach/SKILL.md +187 -0
- package/web-bundles/ux-coach/ux-validation.md +100 -0
|
@@ -0,0 +1,433 @@
|
|
|
1
|
+
const path = require('node:path');
|
|
2
|
+
const https = require('node:https');
|
|
3
|
+
const { execFile } = require('node:child_process');
|
|
4
|
+
const { promisify } = require('node:util');
|
|
5
|
+
const fs = require('../fs-native');
|
|
6
|
+
const crypto = require('node:crypto');
|
|
7
|
+
const { resolveModuleVersion } = require('../modules/version-resolver');
|
|
8
|
+
const prompts = require('../prompts');
|
|
9
|
+
|
|
10
|
+
const execFileAsync = promisify(execFile);
|
|
11
|
+
const NPM_LOOKUP_TIMEOUT_MS = 10_000;
|
|
12
|
+
const NPM_PACKAGE_NAME_PATTERN = /^(?:@[a-z0-9][a-z0-9._~-]*\/)?[a-z0-9][a-z0-9._~-]*$/;
|
|
13
|
+
|
|
14
|
+
function isValidNpmPackageName(packageName) {
|
|
15
|
+
return typeof packageName === 'string' && NPM_PACKAGE_NAME_PATTERN.test(packageName);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
class Manifest {
|
|
19
|
+
/**
|
|
20
|
+
* Create a new manifest
|
|
21
|
+
* @param {string} bmadDir - Path to bmad directory
|
|
22
|
+
* @param {Object} data - Manifest data
|
|
23
|
+
* @param {Array} installedFiles - List of installed files (no longer used, files tracked in files-manifest.csv)
|
|
24
|
+
*/
|
|
25
|
+
async create(bmadDir, data, installedFiles = []) {
|
|
26
|
+
const manifestPath = path.join(bmadDir, '_config', 'manifest.yaml');
|
|
27
|
+
const yaml = require('yaml');
|
|
28
|
+
|
|
29
|
+
// Ensure _config directory exists
|
|
30
|
+
await fs.ensureDir(path.dirname(manifestPath));
|
|
31
|
+
|
|
32
|
+
// Get the BMad version from package.json
|
|
33
|
+
const bmadVersion = data.version || require(path.join(process.cwd(), 'package.json')).version;
|
|
34
|
+
|
|
35
|
+
// Convert module list to new detailed format
|
|
36
|
+
const moduleDetails = [];
|
|
37
|
+
if (data.modules && Array.isArray(data.modules)) {
|
|
38
|
+
for (const moduleName of data.modules) {
|
|
39
|
+
// Core and BMM modules use the BMad version
|
|
40
|
+
const moduleVersion = moduleName === 'core' || moduleName === 'bmm' ? bmadVersion : null;
|
|
41
|
+
const now = data.installDate || new Date().toISOString();
|
|
42
|
+
|
|
43
|
+
moduleDetails.push({
|
|
44
|
+
name: moduleName,
|
|
45
|
+
version: moduleVersion,
|
|
46
|
+
installDate: now,
|
|
47
|
+
lastUpdated: now,
|
|
48
|
+
source: moduleName === 'core' || moduleName === 'bmm' ? 'built-in' : 'unknown',
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Structure the manifest data
|
|
54
|
+
const manifestData = {
|
|
55
|
+
installation: {
|
|
56
|
+
version: bmadVersion,
|
|
57
|
+
installDate: data.installDate || new Date().toISOString(),
|
|
58
|
+
lastUpdated: data.lastUpdated || new Date().toISOString(),
|
|
59
|
+
},
|
|
60
|
+
modules: moduleDetails,
|
|
61
|
+
ides: data.ides || [],
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
// Write YAML manifest
|
|
65
|
+
// Clean the manifest data to remove any non-serializable values
|
|
66
|
+
const cleanManifestData = structuredClone(manifestData);
|
|
67
|
+
|
|
68
|
+
const yamlContent = yaml.stringify(cleanManifestData, {
|
|
69
|
+
indent: 2,
|
|
70
|
+
lineWidth: 0,
|
|
71
|
+
sortKeys: false,
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Ensure POSIX-compliant final newline
|
|
75
|
+
const content = yamlContent.endsWith('\n') ? yamlContent : yamlContent + '\n';
|
|
76
|
+
await fs.writeFile(manifestPath, content, 'utf8');
|
|
77
|
+
return { success: true, path: manifestPath, filesTracked: 0 };
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Read existing manifest
|
|
82
|
+
* @param {string} bmadDir - Path to bmad directory
|
|
83
|
+
* @returns {Object|null} Manifest data or null if not found
|
|
84
|
+
*/
|
|
85
|
+
async read(bmadDir) {
|
|
86
|
+
const yamlPath = path.join(bmadDir, '_config', 'manifest.yaml');
|
|
87
|
+
const yaml = require('yaml');
|
|
88
|
+
|
|
89
|
+
if (await fs.pathExists(yamlPath)) {
|
|
90
|
+
try {
|
|
91
|
+
const content = await fs.readFile(yamlPath, 'utf8');
|
|
92
|
+
const manifestData = yaml.parse(content);
|
|
93
|
+
|
|
94
|
+
// Handle new detailed module format
|
|
95
|
+
const modules = manifestData.modules || [];
|
|
96
|
+
|
|
97
|
+
// For backward compatibility: if modules is an array of strings (old format),
|
|
98
|
+
// the calling code may need the array of names
|
|
99
|
+
const moduleNames = modules.map((m) => (typeof m === 'string' ? m : m.name));
|
|
100
|
+
|
|
101
|
+
// Check if we have the new detailed format
|
|
102
|
+
const hasDetailedModules = modules.length > 0 && typeof modules[0] === 'object';
|
|
103
|
+
|
|
104
|
+
// Flatten the structure for compatibility with existing code
|
|
105
|
+
return {
|
|
106
|
+
version: manifestData.installation?.version,
|
|
107
|
+
installDate: manifestData.installation?.installDate,
|
|
108
|
+
lastUpdated: manifestData.installation?.lastUpdated,
|
|
109
|
+
modules: moduleNames, // Simple array of module names for backward compatibility
|
|
110
|
+
modulesDetailed: hasDetailedModules ? modules : null, // New detailed format
|
|
111
|
+
ides: manifestData.ides || [],
|
|
112
|
+
};
|
|
113
|
+
} catch (error) {
|
|
114
|
+
await prompts.log.error(`Failed to read YAML manifest: ${error.message}`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Read raw manifest data without flattening
|
|
123
|
+
* @param {string} bmadDir - Path to bmad directory
|
|
124
|
+
* @returns {Object|null} Raw manifest data or null if not found
|
|
125
|
+
*/
|
|
126
|
+
async _readRaw(bmadDir) {
|
|
127
|
+
const yamlPath = path.join(bmadDir, '_config', 'manifest.yaml');
|
|
128
|
+
const yaml = require('yaml');
|
|
129
|
+
|
|
130
|
+
if (await fs.pathExists(yamlPath)) {
|
|
131
|
+
try {
|
|
132
|
+
const content = await fs.readFile(yamlPath, 'utf8');
|
|
133
|
+
return yaml.parse(content);
|
|
134
|
+
} catch (error) {
|
|
135
|
+
await prompts.log.error(`Failed to read YAML manifest: ${error.message}`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Flatten manifest for backward compatibility
|
|
144
|
+
* @param {Object} manifest - Raw manifest data
|
|
145
|
+
* @returns {Object} Flattened manifest
|
|
146
|
+
*/
|
|
147
|
+
_flattenManifest(manifest) {
|
|
148
|
+
const modules = manifest.modules || [];
|
|
149
|
+
const moduleNames = modules.map((m) => (typeof m === 'string' ? m : m.name));
|
|
150
|
+
const hasDetailedModules = modules.length > 0 && typeof modules[0] === 'object';
|
|
151
|
+
|
|
152
|
+
return {
|
|
153
|
+
version: manifest.installation?.version,
|
|
154
|
+
installDate: manifest.installation?.installDate,
|
|
155
|
+
lastUpdated: manifest.installation?.lastUpdated,
|
|
156
|
+
modules: moduleNames,
|
|
157
|
+
modulesDetailed: hasDetailedModules ? modules : null,
|
|
158
|
+
ides: manifest.ides || [],
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Add a module to the manifest with optional version info
|
|
164
|
+
* If module already exists, update its version info
|
|
165
|
+
* @param {string} bmadDir - Path to bmad directory
|
|
166
|
+
* @param {string} moduleName - Module name to add
|
|
167
|
+
* @param {Object} options - Optional version info
|
|
168
|
+
*/
|
|
169
|
+
async addModule(bmadDir, moduleName, options = {}) {
|
|
170
|
+
let manifest = await this._readRaw(bmadDir);
|
|
171
|
+
if (!manifest) {
|
|
172
|
+
// Bootstrap a minimal manifest if it doesn't exist yet
|
|
173
|
+
// (e.g., skill-only modules with no agents to compile)
|
|
174
|
+
manifest = { modules: [] };
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (!manifest.modules) {
|
|
178
|
+
manifest.modules = [];
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const existingIndex = manifest.modules.findIndex((m) => m.name === moduleName);
|
|
182
|
+
|
|
183
|
+
if (existingIndex === -1) {
|
|
184
|
+
// Module doesn't exist, add it
|
|
185
|
+
const entry = {
|
|
186
|
+
name: moduleName,
|
|
187
|
+
version: options.version || null,
|
|
188
|
+
installDate: new Date().toISOString(),
|
|
189
|
+
lastUpdated: new Date().toISOString(),
|
|
190
|
+
source: options.source || 'unknown',
|
|
191
|
+
npmPackage: options.npmPackage || null,
|
|
192
|
+
repoUrl: options.repoUrl || null,
|
|
193
|
+
};
|
|
194
|
+
if (options.channel) entry.channel = options.channel;
|
|
195
|
+
if (options.sha) entry.sha = options.sha;
|
|
196
|
+
if (options.localPath) entry.localPath = options.localPath;
|
|
197
|
+
if (options.rawSource) entry.rawSource = options.rawSource;
|
|
198
|
+
if (options.registryApprovedTag) entry.registryApprovedTag = options.registryApprovedTag;
|
|
199
|
+
if (options.registryApprovedSha) entry.registryApprovedSha = options.registryApprovedSha;
|
|
200
|
+
manifest.modules.push(entry);
|
|
201
|
+
} else {
|
|
202
|
+
// Module exists, update its version info
|
|
203
|
+
const existing = manifest.modules[existingIndex];
|
|
204
|
+
manifest.modules[existingIndex] = {
|
|
205
|
+
...existing,
|
|
206
|
+
version: options.version === undefined ? existing.version : options.version,
|
|
207
|
+
source: options.source || existing.source,
|
|
208
|
+
npmPackage: options.npmPackage === undefined ? existing.npmPackage : options.npmPackage,
|
|
209
|
+
repoUrl: options.repoUrl === undefined ? existing.repoUrl : options.repoUrl,
|
|
210
|
+
localPath: options.localPath === undefined ? existing.localPath : options.localPath,
|
|
211
|
+
channel: options.channel === undefined ? existing.channel : options.channel,
|
|
212
|
+
sha: options.sha === undefined ? existing.sha : options.sha,
|
|
213
|
+
rawSource: options.rawSource === undefined ? existing.rawSource : options.rawSource,
|
|
214
|
+
registryApprovedTag: options.registryApprovedTag === undefined ? existing.registryApprovedTag : options.registryApprovedTag,
|
|
215
|
+
registryApprovedSha: options.registryApprovedSha === undefined ? existing.registryApprovedSha : options.registryApprovedSha,
|
|
216
|
+
lastUpdated: new Date().toISOString(),
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
await this._writeRaw(bmadDir, manifest);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Get all modules with their version info
|
|
225
|
+
* @param {string} bmadDir - Path to bmad directory
|
|
226
|
+
* @returns {Array} Array of module info objects
|
|
227
|
+
*/
|
|
228
|
+
async getAllModuleVersions(bmadDir) {
|
|
229
|
+
const manifest = await this._readRaw(bmadDir);
|
|
230
|
+
if (!manifest || !manifest.modules) {
|
|
231
|
+
return [];
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return manifest.modules;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Write raw manifest data to file
|
|
239
|
+
* @param {string} bmadDir - Path to bmad directory
|
|
240
|
+
* @param {Object} manifestData - Raw manifest data to write
|
|
241
|
+
*/
|
|
242
|
+
async _writeRaw(bmadDir, manifestData) {
|
|
243
|
+
const yaml = require('yaml');
|
|
244
|
+
const manifestPath = path.join(bmadDir, '_config', 'manifest.yaml');
|
|
245
|
+
|
|
246
|
+
await fs.ensureDir(path.dirname(manifestPath));
|
|
247
|
+
|
|
248
|
+
const cleanManifestData = structuredClone(manifestData);
|
|
249
|
+
|
|
250
|
+
const yamlContent = yaml.stringify(cleanManifestData, {
|
|
251
|
+
indent: 2,
|
|
252
|
+
lineWidth: 0,
|
|
253
|
+
sortKeys: false,
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
const content = yamlContent.endsWith('\n') ? yamlContent : yamlContent + '\n';
|
|
257
|
+
await fs.writeFile(manifestPath, content, 'utf8');
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Calculate SHA256 hash of a file
|
|
262
|
+
* @param {string} filePath - Path to file
|
|
263
|
+
* @returns {string} SHA256 hash
|
|
264
|
+
*/
|
|
265
|
+
async calculateFileHash(filePath) {
|
|
266
|
+
try {
|
|
267
|
+
const content = await fs.readFile(filePath);
|
|
268
|
+
return crypto.createHash('sha256').update(content).digest('hex');
|
|
269
|
+
} catch {
|
|
270
|
+
return null;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Get module version info from source
|
|
276
|
+
* @param {string} moduleName - Module name/code
|
|
277
|
+
* @param {string} bmadDir - Path to bmad directory
|
|
278
|
+
* @param {string} moduleSourcePath - Optional source path for custom modules
|
|
279
|
+
* @returns {Object} Version info object with version, source, npmPackage, repoUrl
|
|
280
|
+
*/
|
|
281
|
+
async getModuleVersionInfo(moduleName, bmadDir, moduleSourcePath = null) {
|
|
282
|
+
// Resolve source type first, then read version with the correct path context
|
|
283
|
+
if (['core', 'bmm'].includes(moduleName)) {
|
|
284
|
+
const versionInfo = await resolveModuleVersion(moduleName, { moduleSourcePath });
|
|
285
|
+
return {
|
|
286
|
+
version: versionInfo.version,
|
|
287
|
+
source: 'built-in',
|
|
288
|
+
npmPackage: null,
|
|
289
|
+
repoUrl: null,
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// Check if this is an external official module
|
|
294
|
+
const { ExternalModuleManager } = require('../modules/external-manager');
|
|
295
|
+
const extMgr = new ExternalModuleManager();
|
|
296
|
+
const moduleInfo = await extMgr.getModuleByCode(moduleName);
|
|
297
|
+
|
|
298
|
+
if (moduleInfo) {
|
|
299
|
+
const externalResolution = extMgr.getResolution(moduleName);
|
|
300
|
+
const versionInfo = await resolveModuleVersion(moduleName, { moduleSourcePath });
|
|
301
|
+
return {
|
|
302
|
+
// Git tag recorded during install trumps the on-disk package.json
|
|
303
|
+
// version, so the manifest carries "v1.7.0" instead of "1.7.0".
|
|
304
|
+
version: externalResolution?.version || versionInfo.version,
|
|
305
|
+
source: 'external',
|
|
306
|
+
npmPackage: moduleInfo.npmPackage || null,
|
|
307
|
+
repoUrl: moduleInfo.url || null,
|
|
308
|
+
channel: externalResolution?.channel || null,
|
|
309
|
+
sha: externalResolution?.sha || null,
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// Check if this is a custom module (from user-provided URL or local path)
|
|
314
|
+
const { CustomModuleManager } = require('../modules/custom-module-manager');
|
|
315
|
+
const customMgr = new CustomModuleManager();
|
|
316
|
+
const resolved = customMgr.getResolution(moduleName);
|
|
317
|
+
const customSource = await customMgr.findModuleSourceByCode(moduleName, { bmadDir });
|
|
318
|
+
if (customSource || resolved) {
|
|
319
|
+
const versionInfo = await resolveModuleVersion(moduleName, {
|
|
320
|
+
moduleSourcePath: moduleSourcePath || customSource,
|
|
321
|
+
fallbackVersion: resolved?.version,
|
|
322
|
+
marketplacePluginNames: resolved?.pluginName ? [resolved.pluginName] : [],
|
|
323
|
+
});
|
|
324
|
+
const hasGitClone = !!resolved?.repoUrl;
|
|
325
|
+
return {
|
|
326
|
+
// Prefer the git ref we actually cloned over the package.json version.
|
|
327
|
+
version: resolved?.cloneRef || (hasGitClone ? 'main' : versionInfo.version),
|
|
328
|
+
source: 'custom',
|
|
329
|
+
npmPackage: null,
|
|
330
|
+
repoUrl: resolved?.repoUrl || null,
|
|
331
|
+
localPath: resolved?.localPath || null,
|
|
332
|
+
channel: hasGitClone ? (resolved?.cloneRef ? 'pinned' : 'next') : null,
|
|
333
|
+
sha: resolved?.cloneSha || null,
|
|
334
|
+
rawSource: resolved?.rawInput || null,
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// Unknown module
|
|
339
|
+
const versionInfo = await resolveModuleVersion(moduleName, { moduleSourcePath });
|
|
340
|
+
return {
|
|
341
|
+
version: versionInfo.version,
|
|
342
|
+
source: 'unknown',
|
|
343
|
+
npmPackage: null,
|
|
344
|
+
repoUrl: null,
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Fetch latest version from npm for a package
|
|
350
|
+
* @param {string} packageName - npm package name
|
|
351
|
+
* @returns {string|null} Latest version or null
|
|
352
|
+
*/
|
|
353
|
+
async fetchNpmVersion(packageName) {
|
|
354
|
+
if (!isValidNpmPackageName(packageName)) {
|
|
355
|
+
return null;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
try {
|
|
359
|
+
// Try using npm view first (more reliable)
|
|
360
|
+
try {
|
|
361
|
+
const { stdout } = await execFileAsync('npm', ['view', packageName, 'version'], {
|
|
362
|
+
encoding: 'utf8',
|
|
363
|
+
timeout: NPM_LOOKUP_TIMEOUT_MS,
|
|
364
|
+
});
|
|
365
|
+
return stdout.trim();
|
|
366
|
+
} catch {
|
|
367
|
+
// Fallback to npm registry API
|
|
368
|
+
return new Promise((resolve) => {
|
|
369
|
+
const request = https.get(`https://registry.npmjs.org/${encodeURIComponent(packageName)}`, (res) => {
|
|
370
|
+
let data = '';
|
|
371
|
+
res.on('data', (chunk) => (data += chunk));
|
|
372
|
+
res.on('end', () => {
|
|
373
|
+
try {
|
|
374
|
+
const pkg = JSON.parse(data);
|
|
375
|
+
resolve(pkg['dist-tags']?.latest || pkg.version || null);
|
|
376
|
+
} catch {
|
|
377
|
+
resolve(null);
|
|
378
|
+
}
|
|
379
|
+
});
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
request.setTimeout(NPM_LOOKUP_TIMEOUT_MS, () => {
|
|
383
|
+
request.destroy();
|
|
384
|
+
resolve(null);
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
request.on('error', () => resolve(null));
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
} catch {
|
|
391
|
+
return null;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* Check for available updates for installed modules
|
|
397
|
+
* @param {string} bmadDir - Path to bmad directory
|
|
398
|
+
* @returns {Array} Array of update info objects
|
|
399
|
+
*/
|
|
400
|
+
async checkForUpdates(bmadDir) {
|
|
401
|
+
const semver = require('semver');
|
|
402
|
+
const modules = await this.getAllModuleVersions(bmadDir);
|
|
403
|
+
const updates = [];
|
|
404
|
+
|
|
405
|
+
for (const module of modules) {
|
|
406
|
+
if (!module.npmPackage) {
|
|
407
|
+
continue; // Skip modules without npm package (built-in)
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
const latestVersion = await this.fetchNpmVersion(module.npmPackage);
|
|
411
|
+
if (!latestVersion) {
|
|
412
|
+
continue;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
const installedVersion = semver.valid(module.version) || semver.valid(semver.coerce(module.version || ''));
|
|
416
|
+
const availableVersion = semver.valid(latestVersion) || semver.valid(semver.coerce(latestVersion));
|
|
417
|
+
|
|
418
|
+
if (installedVersion && availableVersion && semver.gt(availableVersion, installedVersion)) {
|
|
419
|
+
updates.push({
|
|
420
|
+
name: module.name,
|
|
421
|
+
installedVersion: module.version,
|
|
422
|
+
latestVersion: latestVersion,
|
|
423
|
+
npmPackage: module.npmPackage,
|
|
424
|
+
updateAvailable: true,
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
return updates;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
module.exports = { Manifest };
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
const { spawnSync } = require('node:child_process');
|
|
2
|
+
const prompts = require('../prompts');
|
|
3
|
+
|
|
4
|
+
// `uv` (https://docs.astral.sh/uv/) is how BMAD runs the Python scripts its
|
|
5
|
+
// skills shell out to: `uv run <script>` resolves the interpreter and any
|
|
6
|
+
// dependencies on demand from the script's own `requires-python` metadata, so
|
|
7
|
+
// skills don't have to assume a particular `python3` is on PATH.
|
|
8
|
+
//
|
|
9
|
+
// As of v6.11.0 this is a requirement, not a preference: the rendered skills
|
|
10
|
+
// (`bmad-build`, `bmad-build-auto`) render through `render_skill.py` and HALT
|
|
11
|
+
// on activation if `uv` is unavailable — there is no interpreter fallback.
|
|
12
|
+
//
|
|
13
|
+
// The check still never blocks the install. Core-only, docs-only, and CI
|
|
14
|
+
// installs are legitimate and never touch a rendered skill, so a missing `uv`
|
|
15
|
+
// must not fail the run. What it does is tell the truth about what will and
|
|
16
|
+
// will not work afterwards, here and again in the post-install summary.
|
|
17
|
+
const RUNTIME_COMMAND = 'uv';
|
|
18
|
+
|
|
19
|
+
// Probed only when `uv` is absent. Some skills still invoke the interpreter
|
|
20
|
+
// directly (`python3 .../resolve_customization.py`), and those scripts declare
|
|
21
|
+
// `requires-python = ">=3.11"` — `resolve_config.py` hard-exits below it
|
|
22
|
+
// because `tomllib` is a 3.11 stdlib addition. When `uv` is present it
|
|
23
|
+
// provisions its own interpreter and whatever `python3` resolves to on PATH is
|
|
24
|
+
// irrelevant, so probing it then would report a problem that doesn't exist.
|
|
25
|
+
const PYTHON_COMMAND = 'python3';
|
|
26
|
+
const MIN_PYTHON = { major: 3, minor: 11 };
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Parse `uv --version` output into version parts.
|
|
30
|
+
* Example outputs: "uv 0.5.31", "uv 0.5.31 (Homebrew 2025-02-12)".
|
|
31
|
+
* @param {string} output - stdout/stderr from `uv --version`
|
|
32
|
+
* @returns {{major: number, minor: number, patch: number, raw: string}|null}
|
|
33
|
+
*/
|
|
34
|
+
function parseUvVersion(output) {
|
|
35
|
+
if (!output) return null;
|
|
36
|
+
const match = output.match(/uv\s+(\d+)\.(\d+)(?:\.(\d+))?/i);
|
|
37
|
+
if (!match) return null;
|
|
38
|
+
return {
|
|
39
|
+
major: Number(match[1]),
|
|
40
|
+
minor: Number(match[2]),
|
|
41
|
+
patch: Number(match[3] || 0),
|
|
42
|
+
raw: `${match[1]}.${match[2]}.${match[3] || 0}`,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Parse `python3 --version` output into version parts.
|
|
48
|
+
* Example outputs: "Python 3.11.7", "Python 3.13.0rc1".
|
|
49
|
+
* @param {string} output - stdout/stderr from `python3 --version`
|
|
50
|
+
* @returns {{major: number, minor: number, patch: number, raw: string}|null}
|
|
51
|
+
*/
|
|
52
|
+
function parsePythonVersion(output) {
|
|
53
|
+
if (!output) return null;
|
|
54
|
+
const match = output.match(/Python\s+(\d+)\.(\d+)(?:\.(\d+))?/i);
|
|
55
|
+
if (!match) return null;
|
|
56
|
+
return {
|
|
57
|
+
major: Number(match[1]),
|
|
58
|
+
minor: Number(match[2]),
|
|
59
|
+
patch: Number(match[3] || 0),
|
|
60
|
+
raw: `${match[1]}.${match[2]}.${match[3] || 0}`,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Whether a parsed Python version satisfies the 3.11+ floor the scripts declare.
|
|
66
|
+
* @param {{major: number, minor: number}|null} version
|
|
67
|
+
* @returns {boolean}
|
|
68
|
+
*/
|
|
69
|
+
function pythonMeetsMinimum(version) {
|
|
70
|
+
if (!version) return false;
|
|
71
|
+
if (version.major !== MIN_PYTHON.major) return version.major > MIN_PYTHON.major;
|
|
72
|
+
return version.minor >= MIN_PYTHON.minor;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Run `<command> --version` and hand the combined output to a parser.
|
|
77
|
+
* @param {string} command
|
|
78
|
+
* @param {(output: string) => Object|null} parse
|
|
79
|
+
* @returns {{version: Object}|null}
|
|
80
|
+
*/
|
|
81
|
+
function probeVersion(command, parse) {
|
|
82
|
+
let result;
|
|
83
|
+
try {
|
|
84
|
+
result = spawnSync(command, ['--version'], {
|
|
85
|
+
encoding: 'utf8',
|
|
86
|
+
timeout: 5000,
|
|
87
|
+
windowsHide: true,
|
|
88
|
+
});
|
|
89
|
+
} catch {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
if (!result || result.error) return null;
|
|
93
|
+
const version = parse(`${result.stdout || ''}\n${result.stderr || ''}`);
|
|
94
|
+
return version ? { version } : null;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Probe the local environment for `uv`.
|
|
99
|
+
* @returns {{version: {major: number, minor: number, patch: number, raw: string}}|null}
|
|
100
|
+
*/
|
|
101
|
+
function detectUv() {
|
|
102
|
+
return probeVersion(RUNTIME_COMMAND, parseUvVersion);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Probe the local environment for `python3`.
|
|
107
|
+
* @returns {{version: {major: number, minor: number, patch: number, raw: string}}|null}
|
|
108
|
+
*/
|
|
109
|
+
function detectPython3() {
|
|
110
|
+
return probeVersion(PYTHON_COMMAND, parsePythonVersion);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function setupHints() {
|
|
114
|
+
return [
|
|
115
|
+
'`uv run` provisions the interpreter and dependencies for you — no manual',
|
|
116
|
+
'venv or pip, and no need for a particular python3 on PATH.',
|
|
117
|
+
'',
|
|
118
|
+
'Easiest path: ask your AI agent to "install and set up uv for me".',
|
|
119
|
+
'',
|
|
120
|
+
'Or install it yourself:',
|
|
121
|
+
' macOS/Linux: curl -LsSf https://astral.sh/uv/install.sh | sh',
|
|
122
|
+
' Windows: powershell -c "irm https://astral.sh/uv/install.ps1 | iex"',
|
|
123
|
+
' Homebrew: brew install uv',
|
|
124
|
+
' Docs: https://docs.astral.sh/uv/getting-started/installation/',
|
|
125
|
+
].join('\n');
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Describe what a missing `uv` leaves working, based on the `python3` fallback.
|
|
130
|
+
*
|
|
131
|
+
* With `uv` gone the rendered skills are lost either way; the only question is
|
|
132
|
+
* whether the skills that invoke the interpreter directly still run, and that
|
|
133
|
+
* turns on `python3` being 3.11+.
|
|
134
|
+
*
|
|
135
|
+
* @param {{version: Object}|null} python - result of detectPython3()
|
|
136
|
+
* @returns {string}
|
|
137
|
+
*/
|
|
138
|
+
function pythonFallbackNote(python) {
|
|
139
|
+
if (!python) {
|
|
140
|
+
return 'No python3 on PATH either, so no Python-backed skill will run.';
|
|
141
|
+
}
|
|
142
|
+
if (pythonMeetsMinimum(python.version)) {
|
|
143
|
+
return (
|
|
144
|
+
`python3 ${python.version.raw} is present, so skills that call the interpreter ` +
|
|
145
|
+
'directly still work — but the rendered skills above stay unavailable.'
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
return (
|
|
149
|
+
`python3 ${python.version.raw} is present but below the required ` +
|
|
150
|
+
`${MIN_PYTHON.major}.${MIN_PYTHON.minor}, so no Python-backed skill will run.`
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Check whether `uv` is available and inform the user.
|
|
156
|
+
*
|
|
157
|
+
* Warn-don't-block: a missing `uv` never stops or fails the install, because
|
|
158
|
+
* core-only and CI installs are legitimate and never render a skill. But the
|
|
159
|
+
* warning names the concrete consequence — `bmad-build` and `bmad-build-auto`
|
|
160
|
+
* halt — rather than describing `uv` as a nice-to-have, and `installer.js`
|
|
161
|
+
* repeats it in the post-install summary so it isn't lost in the scrollback.
|
|
162
|
+
*
|
|
163
|
+
* @returns {Promise<{status: 'found'|'missing', detected: Object|null, python: Object|null}>}
|
|
164
|
+
*/
|
|
165
|
+
async function checkUvEnvironment() {
|
|
166
|
+
// Called via module.exports so tests can stub detection.
|
|
167
|
+
const detected = module.exports.detectUv();
|
|
168
|
+
|
|
169
|
+
if (detected) {
|
|
170
|
+
await prompts.log.success(`✅ Python UV check pass (uv ${detected.version.raw} detected).`);
|
|
171
|
+
return { status: 'found', detected, python: null };
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const python = module.exports.detectPython3();
|
|
175
|
+
|
|
176
|
+
await prompts.log.warn(
|
|
177
|
+
'uv not found on PATH. BMAD requires it to run the Python scripts its skills\n' +
|
|
178
|
+
'shell out to: bmad-build and bmad-build-auto render through `uv run` and will\n' +
|
|
179
|
+
'HALT on activation without it — there is no interpreter fallback.\n' +
|
|
180
|
+
`${pythonFallbackNote(python)}\n` +
|
|
181
|
+
'The install itself completes either way.',
|
|
182
|
+
);
|
|
183
|
+
await prompts.note(setupHints(), 'uv required');
|
|
184
|
+
return { status: 'missing', detected: null, python };
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
module.exports = {
|
|
188
|
+
checkUvEnvironment,
|
|
189
|
+
detectUv,
|
|
190
|
+
detectPython3,
|
|
191
|
+
parseUvVersion,
|
|
192
|
+
parsePythonVersion,
|
|
193
|
+
pythonMeetsMinimum,
|
|
194
|
+
MIN_PYTHON,
|
|
195
|
+
};
|