bmad-elsabro 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/.auto-claude-security.json +209 -0
- package/.claude_settings.json +34 -0
- package/.coderabbit.yaml +40 -0
- package/.nvmrc +1 -0
- package/.prettierignore +9 -0
- package/AI_TEST_GENERATOR_VERIFICATION.md +260 -0
- package/BUDGET_ALERT_TESTING.md +325 -0
- package/CHANGELOG.md +1488 -0
- package/CNAME +1 -0
- package/CONTRIBUTING.md +167 -0
- package/CONTRIBUTORS.md +32 -0
- package/LEGACY_MIGRATION_TESTING.md +428 -0
- package/LICENSE +30 -0
- package/PARTY_MODE_VERIFICATION.md +274 -0
- package/PROJECT_DETECTOR_TESTING.md +288 -0
- package/README.md +236 -0
- package/SECURITY.md +85 -0
- package/TRADEMARK.md +55 -0
- package/WORKFLOW_ROUTER_IMPLEMENTATION.md +379 -0
- package/Wordmark.png +0 -0
- package/banner-bmad-method.png +0 -0
- package/build/icons/512x512.png +0 -0
- package/build-mac.sh +3 -0
- package/docs/404.md +9 -0
- package/docs/_STYLE_GUIDE.md +367 -0
- package/docs/developer/api-reference.md +945 -0
- package/docs/developer/architecture.md +563 -0
- package/docs/developer/contributing.md +831 -0
- package/docs/downloads.md +74 -0
- package/docs/explanation/advanced-elicitation.md +24 -0
- package/docs/explanation/adversarial-review.md +57 -0
- package/docs/explanation/brainstorming.md +31 -0
- package/docs/explanation/brownfield-faq.md +55 -0
- package/docs/explanation/party-mode.md +57 -0
- package/docs/explanation/preventing-agent-conflicts.md +110 -0
- package/docs/explanation/quick-flow.md +27 -0
- package/docs/explanation/why-solutioning-matters.md +75 -0
- package/docs/how-to/brownfield/index.md +84 -0
- package/docs/how-to/brownfield/quick-fix-in-brownfield.md +76 -0
- package/docs/how-to/customize-bmad.md +158 -0
- package/docs/how-to/get-answers-about-bmad.md +102 -0
- package/docs/how-to/install-bmad.md +82 -0
- package/docs/how-to/shard-large-documents.md +101 -0
- package/docs/how-to/upgrade-to-v6.md +131 -0
- package/docs/index.md +56 -0
- package/docs/reference/workflow-map.md +83 -0
- package/docs/tea/explanation/engagement-models.md +710 -0
- package/docs/tea/explanation/fixture-architecture.md +457 -0
- package/docs/tea/explanation/knowledge-base-system.md +554 -0
- package/docs/tea/explanation/network-first-patterns.md +853 -0
- package/docs/tea/explanation/risk-based-testing.md +586 -0
- package/docs/tea/explanation/tea-overview.md +410 -0
- package/docs/tea/explanation/test-quality-standards.md +907 -0
- package/docs/tea/explanation/testing-as-engineering.md +112 -0
- package/docs/tea/glossary/index.md +159 -0
- package/docs/tea/how-to/brownfield/use-tea-for-enterprise.md +525 -0
- package/docs/tea/how-to/brownfield/use-tea-with-existing-tests.md +577 -0
- package/docs/tea/how-to/customization/enable-tea-mcp-enhancements.md +424 -0
- package/docs/tea/how-to/customization/integrate-playwright-utils.md +813 -0
- package/docs/tea/how-to/workflows/run-atdd.md +436 -0
- package/docs/tea/how-to/workflows/run-automate.md +653 -0
- package/docs/tea/how-to/workflows/run-nfr-assess.md +679 -0
- package/docs/tea/how-to/workflows/run-test-design.md +135 -0
- package/docs/tea/how-to/workflows/run-test-review.md +605 -0
- package/docs/tea/how-to/workflows/run-trace.md +883 -0
- package/docs/tea/how-to/workflows/setup-ci.md +712 -0
- package/docs/tea/how-to/workflows/setup-test-framework.md +98 -0
- package/docs/tea/reference/commands.md +276 -0
- package/docs/tea/reference/configuration.md +678 -0
- package/docs/tea/reference/knowledge-base.md +340 -0
- package/docs/tea/tutorials/tea-lite-quickstart.md +444 -0
- package/docs/tutorials/getting-started.md +205 -0
- package/docs/user-guide/getting-started.md +348 -0
- package/docs/user-guide/token-economy.md +601 -0
- package/docs/user-guide/workflows.md +546 -0
- package/electron-builder.yml +75 -0
- package/eslint.config.mjs +152 -0
- package/package.json +162 -0
- package/prettier.config.mjs +32 -0
- package/public/monaco-workers/index.js +21 -0
- package/renderer/App.tsx +311 -0
- package/renderer/components/ChatPanel.tsx +285 -0
- package/renderer/components/CodeEditor.tsx +327 -0
- package/renderer/components/CodeEditor.types.ts +245 -0
- package/renderer/components/FlowSelector.tsx +534 -0
- package/renderer/components/MessageInput.tsx +252 -0
- package/renderer/components/MessageList.tsx +204 -0
- package/renderer/components/MigrationWizard.tsx +896 -0
- package/renderer/components/NotificationCenter.tsx +291 -0
- package/renderer/components/OnboardingWizard.tsx +112 -0
- package/renderer/components/PartyMode.tsx +555 -0
- package/renderer/components/Sidebar.module.css +258 -0
- package/renderer/components/Sidebar.tsx +157 -0
- package/renderer/components/TemplateSelector.tsx +553 -0
- package/renderer/components/Terminal.tsx +523 -0
- package/renderer/components/TestCenter.tsx +364 -0
- package/renderer/components/TokenAnalytics.tsx +607 -0
- package/renderer/components/TokenMonitor.tsx +331 -0
- package/renderer/components/TutorialOverlay.tsx +483 -0
- package/renderer/components/WorkflowEditor.tsx +470 -0
- package/renderer/components/onboarding/Step1Welcome.tsx +72 -0
- package/renderer/components/onboarding/Step2Setup.tsx +193 -0
- package/renderer/components/onboarding/Step3CreateProject.tsx +209 -0
- package/renderer/components/test-center/CoverageDashboard.tsx +588 -0
- package/renderer/components/test-center/ELI5Guide.tsx +521 -0
- package/renderer/components/test-center/TestList.tsx +381 -0
- package/renderer/components/test-center/TestRunner.tsx +431 -0
- package/renderer/components/test-center/TestStepWizard.tsx +1000 -0
- package/renderer/components/test-center/VisualTestBuilder.tsx +460 -0
- package/renderer/components/workflow/DependencyEdge.tsx +200 -0
- package/renderer/components/workflow/StepNode.tsx +234 -0
- package/renderer/components/workflow/StepPalette.tsx +412 -0
- package/renderer/context/ThemeContext.tsx +97 -0
- package/renderer/data/shortcuts.json +94 -0
- package/renderer/data/testing-guides.json +261 -0
- package/renderer/data/tutorials.json +546 -0
- package/renderer/hooks/useKeyboardShortcuts.ts +249 -0
- package/renderer/hooks/useNotifications.ts +267 -0
- package/renderer/hooks/useTheme.ts +149 -0
- package/renderer/hooks/useTokenTracking.ts +464 -0
- package/renderer/hooks/useWorkflowState.ts +309 -0
- package/renderer/index.html +16 -0
- package/renderer/index.tsx +17 -0
- package/renderer/lib/MONACO_OFFLINE_CONFIG.md +153 -0
- package/renderer/lib/chart-utils.ts +472 -0
- package/renderer/lib/file-system-provider.ts +295 -0
- package/renderer/lib/monaco-loader.ts +247 -0
- package/renderer/renderer/components/NOTIFICATION_SYSTEM.md +192 -0
- package/renderer/styles.css +55 -0
- package/renderer/types/css-modules.d.ts +21 -0
- package/renderer/types/electron.d.ts +316 -0
- package/src/bmm/_module-installer/installer.js +48 -0
- package/src/bmm/agents/analyst.agent.yaml +36 -0
- package/src/bmm/agents/architect.agent.yaml +28 -0
- package/src/bmm/agents/dev.agent.yaml +38 -0
- package/src/bmm/agents/parallel-orchestrator.agent.yaml +50 -0
- package/src/bmm/agents/pm.agent.yaml +46 -0
- package/src/bmm/agents/quick-flow-solo-dev.agent.yaml +32 -0
- package/src/bmm/agents/sm.agent.yaml +36 -0
- package/src/bmm/agents/tea.agent.yaml +63 -0
- package/src/bmm/agents/tech-writer/tech-writer-sidecar/documentation-standards.md +224 -0
- package/src/bmm/agents/tech-writer/tech-writer.agent.yaml +45 -0
- package/src/bmm/agents/ux-designer.agent.yaml +26 -0
- package/src/bmm/agents/yolo-dev.agent.yaml +41 -0
- package/src/bmm/data/auto-testing-config.yaml +84 -0
- package/src/bmm/data/guided-mode-instructions.yaml +112 -0
- package/src/bmm/data/parallelization-config.yaml +136 -0
- package/src/bmm/data/project-context-template.md +26 -0
- package/src/bmm/data/speed-profiles.yaml +127 -0
- package/src/bmm/module-help.csv +32 -0
- package/src/bmm/module.yaml +60 -0
- package/src/bmm/teams/default-party.csv +21 -0
- package/src/bmm/teams/team-fullstack.yaml +12 -0
- package/src/bmm/testarch/knowledge/adr-quality-readiness-checklist.md +350 -0
- package/src/bmm/testarch/knowledge/api-request.md +442 -0
- package/src/bmm/testarch/knowledge/api-testing-patterns.md +843 -0
- package/src/bmm/testarch/knowledge/auth-session.md +552 -0
- package/src/bmm/testarch/knowledge/burn-in.md +273 -0
- package/src/bmm/testarch/knowledge/ci-burn-in.md +675 -0
- package/src/bmm/testarch/knowledge/component-tdd.md +486 -0
- package/src/bmm/testarch/knowledge/contract-testing.md +957 -0
- package/src/bmm/testarch/knowledge/data-factories.md +500 -0
- package/src/bmm/testarch/knowledge/email-auth.md +721 -0
- package/src/bmm/testarch/knowledge/error-handling.md +725 -0
- package/src/bmm/testarch/knowledge/feature-flags.md +750 -0
- package/src/bmm/testarch/knowledge/file-utils.md +463 -0
- package/src/bmm/testarch/knowledge/fixture-architecture.md +401 -0
- package/src/bmm/testarch/knowledge/fixtures-composition.md +382 -0
- package/src/bmm/testarch/knowledge/intercept-network-call.md +430 -0
- package/src/bmm/testarch/knowledge/log.md +429 -0
- package/src/bmm/testarch/knowledge/network-error-monitor.md +405 -0
- package/src/bmm/testarch/knowledge/network-first.md +486 -0
- package/src/bmm/testarch/knowledge/network-recorder.md +527 -0
- package/src/bmm/testarch/knowledge/nfr-criteria.md +670 -0
- package/src/bmm/testarch/knowledge/overview.md +286 -0
- package/src/bmm/testarch/knowledge/playwright-config.md +730 -0
- package/src/bmm/testarch/knowledge/probability-impact.md +601 -0
- package/src/bmm/testarch/knowledge/recurse.md +421 -0
- package/src/bmm/testarch/knowledge/risk-governance.md +615 -0
- package/src/bmm/testarch/knowledge/selective-testing.md +732 -0
- package/src/bmm/testarch/knowledge/selector-resilience.md +527 -0
- package/src/bmm/testarch/knowledge/test-healing-patterns.md +644 -0
- package/src/bmm/testarch/knowledge/test-levels-framework.md +473 -0
- package/src/bmm/testarch/knowledge/test-priorities-matrix.md +373 -0
- package/src/bmm/testarch/knowledge/test-quality.md +664 -0
- package/src/bmm/testarch/knowledge/timing-debugging.md +372 -0
- package/src/bmm/testarch/knowledge/visual-debugging.md +524 -0
- package/src/bmm/testarch/tea-index.csv +35 -0
- package/src/bmm/workflows/1-analysis/create-product-brief/product-brief.template.md +10 -0
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-01-init.md +177 -0
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-01b-continue.md +161 -0
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-02-vision.md +199 -0
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-03-users.md +202 -0
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-04-metrics.md +205 -0
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-05-scope.md +219 -0
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-06-complete.md +162 -0
- package/src/bmm/workflows/1-analysis/create-product-brief/workflow.md +58 -0
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-01-init.md +137 -0
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-02-domain-analysis.md +229 -0
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-03-competitive-landscape.md +238 -0
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-04-regulatory-focus.md +206 -0
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-05-technical-trends.md +234 -0
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-06-research-synthesis.md +443 -0
- package/src/bmm/workflows/1-analysis/research/market-steps/step-01-init.md +182 -0
- package/src/bmm/workflows/1-analysis/research/market-steps/step-02-customer-behavior.md +237 -0
- package/src/bmm/workflows/1-analysis/research/market-steps/step-02-customer-insights.md +200 -0
- package/src/bmm/workflows/1-analysis/research/market-steps/step-03-customer-pain-points.md +249 -0
- package/src/bmm/workflows/1-analysis/research/market-steps/step-04-customer-decisions.md +259 -0
- package/src/bmm/workflows/1-analysis/research/market-steps/step-05-competitive-analysis.md +177 -0
- package/src/bmm/workflows/1-analysis/research/market-steps/step-06-research-completion.md +475 -0
- package/src/bmm/workflows/1-analysis/research/research.template.md +29 -0
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-01-init.md +137 -0
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-02-technical-overview.md +239 -0
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-03-integration-patterns.md +248 -0
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-04-architectural-patterns.md +202 -0
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-05-implementation-research.md +239 -0
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-06-research-synthesis.md +486 -0
- package/src/bmm/workflows/1-analysis/research/workflow.md +173 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/data/domain-complexity.csv +13 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/data/prd-purpose.md +197 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/data/project-types.csv +11 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-01-init.md +191 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-01b-continue.md +153 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-02-discovery.md +224 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-03-success.md +226 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-04-journeys.md +213 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-05-domain.md +207 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-06-innovation.md +226 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-07-project-type.md +237 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-08-scoping.md +228 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-09-functional.md +231 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-10-nonfunctional.md +242 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-11-polish.md +217 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-12-complete.md +124 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-01-discovery.md +247 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-01b-legacy-conversion.md +208 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-02-review.md +249 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-03-edit.md +253 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-04-complete.md +168 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-01-discovery.md +218 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-02-format-detection.md +191 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-02b-parity-check.md +209 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-03-density-validation.md +174 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-04-brief-coverage-validation.md +214 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-05-measurability-validation.md +228 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-06-traceability-validation.md +217 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-07-implementation-leakage-validation.md +205 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-08-domain-compliance-validation.md +243 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-09-project-type-validation.md +263 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-10-smart-validation.md +209 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-11-holistic-quality-validation.md +264 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-12-completeness-validation.md +242 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-13-report-complete.md +231 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/templates/prd-template.md +10 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/validation-report-prd-workflow.md +433 -0
- package/src/bmm/workflows/2-plan-workflows/create-prd/workflow.md +150 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-01-init.md +135 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-01b-continue.md +127 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-02-discovery.md +190 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-03-core-experience.md +216 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-04-emotional-response.md +219 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-05-inspiration.md +234 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-06-design-system.md +252 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-07-defining-experience.md +254 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-08-visual-foundation.md +224 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-09-design-directions.md +224 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-10-user-journeys.md +241 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-11-component-strategy.md +248 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-12-ux-patterns.md +237 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-13-responsive-accessibility.md +264 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-14-complete.md +171 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/ux-design-template.md +13 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/workflow.md +43 -0
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-01-document-discovery.md +190 -0
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-02-prd-analysis.md +178 -0
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-03-epic-coverage-validation.md +179 -0
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-04-ux-alignment.md +139 -0
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-05-epic-quality-review.md +252 -0
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-06-final-assessment.md +135 -0
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/templates/readiness-report-template.md +4 -0
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/workflow.md +55 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/architecture-decision-template.md +12 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/data/domain-complexity.csv +11 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/data/project-types.csv +7 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-01-init.md +153 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-01b-continue.md +164 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-02-context.md +224 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-03-starter.md +331 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-04-decisions.md +318 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-05-patterns.md +359 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-06-structure.md +379 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-07-validation.md +359 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-08-complete.md +76 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/workflow.md +50 -0
- package/src/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-01-validate-prerequisites.md +259 -0
- package/src/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-02-design-epics.md +233 -0
- package/src/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-03-create-stories.md +272 -0
- package/src/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-04-final-validation.md +149 -0
- package/src/bmm/workflows/3-solutioning/create-epics-and-stories/templates/epics-template.md +57 -0
- package/src/bmm/workflows/3-solutioning/create-epics-and-stories/workflow.md +59 -0
- package/src/bmm/workflows/4-implementation/code-review/checklist.md +23 -0
- package/src/bmm/workflows/4-implementation/code-review/instructions.xml +227 -0
- package/src/bmm/workflows/4-implementation/code-review/workflow.yaml +51 -0
- package/src/bmm/workflows/4-implementation/correct-course/checklist.md +288 -0
- package/src/bmm/workflows/4-implementation/correct-course/instructions.md +206 -0
- package/src/bmm/workflows/4-implementation/correct-course/workflow.yaml +60 -0
- package/src/bmm/workflows/4-implementation/create-story/checklist.md +358 -0
- package/src/bmm/workflows/4-implementation/create-story/instructions.xml +345 -0
- package/src/bmm/workflows/4-implementation/create-story/template.md +49 -0
- package/src/bmm/workflows/4-implementation/create-story/workflow.yaml +61 -0
- package/src/bmm/workflows/4-implementation/dev-story/checklist.md +80 -0
- package/src/bmm/workflows/4-implementation/dev-story/instructions.xml +410 -0
- package/src/bmm/workflows/4-implementation/dev-story/workflow.yaml +32 -0
- package/src/bmm/workflows/4-implementation/fix-and-test/workflow.md +197 -0
- package/src/bmm/workflows/4-implementation/retrospective/instructions.md +1443 -0
- package/src/bmm/workflows/4-implementation/retrospective/workflow.yaml +58 -0
- package/src/bmm/workflows/4-implementation/sprint-planning/checklist.md +33 -0
- package/src/bmm/workflows/4-implementation/sprint-planning/instructions.md +225 -0
- package/src/bmm/workflows/4-implementation/sprint-planning/sprint-status-template.yaml +55 -0
- package/src/bmm/workflows/4-implementation/sprint-planning/workflow.yaml +54 -0
- package/src/bmm/workflows/4-implementation/sprint-status/instructions.md +229 -0
- package/src/bmm/workflows/4-implementation/sprint-status/workflow.yaml +36 -0
- package/src/bmm/workflows/bmad-quick-flow/brownfield-fast-track/steps/step-01-detect.md +55 -0
- package/src/bmm/workflows/bmad-quick-flow/brownfield-fast-track/steps/step-02-confirm.md +48 -0
- package/src/bmm/workflows/bmad-quick-flow/brownfield-fast-track/steps/step-03-implement.md +61 -0
- package/src/bmm/workflows/bmad-quick-flow/brownfield-fast-track/workflow.md +41 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-01-mode-detection.md +176 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-02-context-gathering.md +120 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-03-execute.md +153 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-04-self-check.md +113 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-05-adversarial-review.md +106 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-06-resolve-findings.md +149 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/workflow.md +73 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-01-understand.md +192 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-02-investigate.md +145 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-03-generate.md +128 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-04-review.md +201 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-spec/tech-spec-template.md +74 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-spec/workflow.md +93 -0
- package/src/bmm/workflows/bmad-quick-flow/yolo-mode/steps/step-01-rapid-spec.md +54 -0
- package/src/bmm/workflows/bmad-quick-flow/yolo-mode/steps/step-02-ship-it.md +65 -0
- package/src/bmm/workflows/bmad-quick-flow/yolo-mode/workflow.md +54 -0
- package/src/bmm/workflows/document-project/checklist.md +245 -0
- package/src/bmm/workflows/document-project/documentation-requirements.csv +12 -0
- package/src/bmm/workflows/document-project/instructions.md +221 -0
- package/src/bmm/workflows/document-project/templates/deep-dive-template.md +345 -0
- package/src/bmm/workflows/document-project/templates/index-template.md +169 -0
- package/src/bmm/workflows/document-project/templates/project-overview-template.md +103 -0
- package/src/bmm/workflows/document-project/templates/project-scan-report-schema.json +160 -0
- package/src/bmm/workflows/document-project/templates/source-tree-template.md +135 -0
- package/src/bmm/workflows/document-project/workflow.yaml +30 -0
- package/src/bmm/workflows/document-project/workflows/deep-dive-instructions.md +298 -0
- package/src/bmm/workflows/document-project/workflows/deep-dive.yaml +31 -0
- package/src/bmm/workflows/document-project/workflows/full-scan-instructions.md +1106 -0
- package/src/bmm/workflows/document-project/workflows/full-scan.yaml +31 -0
- package/src/bmm/workflows/excalidraw-diagrams/_shared/excalidraw-library.json +90 -0
- package/src/bmm/workflows/excalidraw-diagrams/_shared/excalidraw-templates.yaml +127 -0
- package/src/bmm/workflows/excalidraw-diagrams/create-dataflow/checklist.md +39 -0
- package/src/bmm/workflows/excalidraw-diagrams/create-dataflow/instructions.md +130 -0
- package/src/bmm/workflows/excalidraw-diagrams/create-dataflow/workflow.yaml +27 -0
- package/src/bmm/workflows/excalidraw-diagrams/create-diagram/checklist.md +43 -0
- package/src/bmm/workflows/excalidraw-diagrams/create-diagram/instructions.md +141 -0
- package/src/bmm/workflows/excalidraw-diagrams/create-diagram/workflow.yaml +27 -0
- package/src/bmm/workflows/excalidraw-diagrams/create-flowchart/checklist.md +49 -0
- package/src/bmm/workflows/excalidraw-diagrams/create-flowchart/instructions.md +241 -0
- package/src/bmm/workflows/excalidraw-diagrams/create-flowchart/workflow.yaml +27 -0
- package/src/bmm/workflows/excalidraw-diagrams/create-wireframe/checklist.md +38 -0
- package/src/bmm/workflows/excalidraw-diagrams/create-wireframe/instructions.md +133 -0
- package/src/bmm/workflows/excalidraw-diagrams/create-wireframe/workflow.yaml +27 -0
- package/src/bmm/workflows/parallel-work/parallel-analysis/steps/step-01-parse-target.md +49 -0
- package/src/bmm/workflows/parallel-work/parallel-analysis/steps/step-02-launch-streams.md +135 -0
- package/src/bmm/workflows/parallel-work/parallel-analysis/steps/step-03-sync-point.md +74 -0
- package/src/bmm/workflows/parallel-work/parallel-analysis/steps/step-04-merge-insights.md +179 -0
- package/src/bmm/workflows/parallel-work/parallel-analysis/workflow.md +55 -0
- package/src/bmm/workflows/parallel-work/parallel-generation/workflow.md +109 -0
- package/src/bmm/workflows/parallel-work/parallel-reviews/workflow.md +111 -0
- package/src/bmm/workflows/parallel-work/parallel-stories/workflow.md +112 -0
- package/src/bmm/workflows/parallel-work/sprint-mode/steps/step-01-load-sprint.md +54 -0
- package/src/bmm/workflows/parallel-work/sprint-mode/steps/step-02-plan-execution.md +63 -0
- package/src/bmm/workflows/parallel-work/sprint-mode/steps/step-03-execute-stories.md +112 -0
- package/src/bmm/workflows/parallel-work/sprint-mode/steps/step-04-code-review.md +148 -0
- package/src/bmm/workflows/parallel-work/sprint-mode/steps/step-05-integration-testing.md +200 -0
- package/src/bmm/workflows/parallel-work/sprint-mode/steps/step-06-sprint-report.md +290 -0
- package/src/bmm/workflows/parallel-work/sprint-mode/workflow.md +58 -0
- package/src/bmm/workflows/testarch/atdd/atdd-checklist-template.md +363 -0
- package/src/bmm/workflows/testarch/atdd/checklist.md +374 -0
- package/src/bmm/workflows/testarch/atdd/instructions.md +806 -0
- package/src/bmm/workflows/testarch/atdd/workflow.yaml +47 -0
- package/src/bmm/workflows/testarch/automate/checklist.md +582 -0
- package/src/bmm/workflows/testarch/automate/instructions.md +1324 -0
- package/src/bmm/workflows/testarch/automate/workflow.yaml +54 -0
- package/src/bmm/workflows/testarch/ci/checklist.md +247 -0
- package/src/bmm/workflows/testarch/ci/github-actions-template.yaml +198 -0
- package/src/bmm/workflows/testarch/ci/gitlab-ci-template.yaml +149 -0
- package/src/bmm/workflows/testarch/ci/instructions.md +536 -0
- package/src/bmm/workflows/testarch/ci/workflow.yaml +47 -0
- package/src/bmm/workflows/testarch/framework/checklist.md +320 -0
- package/src/bmm/workflows/testarch/framework/instructions.md +481 -0
- package/src/bmm/workflows/testarch/framework/workflow.yaml +49 -0
- package/src/bmm/workflows/testarch/nfr-assess/checklist.md +407 -0
- package/src/bmm/workflows/testarch/nfr-assess/instructions.md +726 -0
- package/src/bmm/workflows/testarch/nfr-assess/nfr-report-template.md +461 -0
- package/src/bmm/workflows/testarch/nfr-assess/workflow.yaml +49 -0
- package/src/bmm/workflows/testarch/test-design/checklist.md +407 -0
- package/src/bmm/workflows/testarch/test-design/instructions.md +1158 -0
- package/src/bmm/workflows/testarch/test-design/test-design-architecture-template.md +213 -0
- package/src/bmm/workflows/testarch/test-design/test-design-qa-template.md +286 -0
- package/src/bmm/workflows/testarch/test-design/test-design-template.md +294 -0
- package/src/bmm/workflows/testarch/test-design/workflow.yaml +71 -0
- package/src/bmm/workflows/testarch/test-review/checklist.md +472 -0
- package/src/bmm/workflows/testarch/test-review/instructions.md +628 -0
- package/src/bmm/workflows/testarch/test-review/test-review-template.md +390 -0
- package/src/bmm/workflows/testarch/test-review/workflow.yaml +48 -0
- package/src/bmm/workflows/testarch/trace/checklist.md +642 -0
- package/src/bmm/workflows/testarch/trace/instructions.md +1030 -0
- package/src/bmm/workflows/testarch/trace/trace-template.md +675 -0
- package/src/bmm/workflows/testarch/trace/workflow.yaml +57 -0
- package/src/core/_module-installer/installer.js +60 -0
- package/src/core/agents/bmad-master.agent.yaml +29 -0
- package/src/core/module-help.csv +9 -0
- package/src/core/module.yaml +25 -0
- package/src/core/resources/excalidraw/README.md +160 -0
- package/src/core/resources/excalidraw/excalidraw-helpers.md +127 -0
- package/src/core/resources/excalidraw/library-loader.md +50 -0
- package/src/core/resources/excalidraw/validate-json-instructions.md +79 -0
- package/src/core/tasks/editorial-review-prose.xml +100 -0
- package/src/core/tasks/editorial-review-structure.xml +209 -0
- package/src/core/tasks/help.md +62 -0
- package/src/core/tasks/index-docs.xml +65 -0
- package/src/core/tasks/review-adversarial-general.xml +48 -0
- package/src/core/tasks/shard-doc.xml +109 -0
- package/src/core/tasks/workflow.xml +235 -0
- package/src/core/workflows/advanced-elicitation/methods.csv +51 -0
- package/src/core/workflows/advanced-elicitation/workflow.xml +117 -0
- package/src/core/workflows/brainstorming/brain-methods.csv +62 -0
- package/src/core/workflows/brainstorming/steps/step-01-session-setup.md +197 -0
- package/src/core/workflows/brainstorming/steps/step-01b-continue.md +122 -0
- package/src/core/workflows/brainstorming/steps/step-02a-user-selected.md +225 -0
- package/src/core/workflows/brainstorming/steps/step-02b-ai-recommended.md +237 -0
- package/src/core/workflows/brainstorming/steps/step-02c-random-selection.md +209 -0
- package/src/core/workflows/brainstorming/steps/step-02d-progressive-flow.md +264 -0
- package/src/core/workflows/brainstorming/steps/step-03-technique-execution.md +399 -0
- package/src/core/workflows/brainstorming/steps/step-04-idea-organization.md +303 -0
- package/src/core/workflows/brainstorming/template.md +15 -0
- package/src/core/workflows/brainstorming/workflow.md +58 -0
- package/src/core/workflows/party-mode/steps/step-01-agent-loading.md +138 -0
- package/src/core/workflows/party-mode/steps/step-02-discussion-orchestration.md +187 -0
- package/src/core/workflows/party-mode/steps/step-03-graceful-exit.md +157 -0
- package/src/core/workflows/party-mode/workflow.md +194 -0
- package/src/utility/agent-components/activation-rules.txt +6 -0
- package/src/utility/agent-components/activation-steps.txt +14 -0
- package/src/utility/agent-components/agent-command-header.md +1 -0
- package/src/utility/agent-components/agent.customize.template.yaml +41 -0
- package/src/utility/agent-components/handler-action.txt +4 -0
- package/src/utility/agent-components/handler-data.txt +5 -0
- package/src/utility/agent-components/handler-exec.txt +6 -0
- package/src/utility/agent-components/handler-multi.txt +14 -0
- package/src/utility/agent-components/handler-tmpl.txt +5 -0
- package/src/utility/agent-components/handler-validate-workflow.txt +7 -0
- package/src/utility/agent-components/handler-workflow.txt +10 -0
- package/src/utility/agent-components/menu-handlers.txt +6 -0
- package/tools/bmad-npx-wrapper.js +69 -0
- package/tools/build-docs.js +577 -0
- package/tools/cli/README.md +7 -0
- package/tools/cli/bmad-cli.js +65 -0
- package/tools/cli/commands/diagnostics.js +303 -0
- package/tools/cli/commands/install.js +87 -0
- package/tools/cli/commands/module.js +210 -0
- package/tools/cli/commands/status.js +65 -0
- package/tools/cli/commands/uninstall.js +86 -0
- package/tools/cli/external-official-modules.yaml +54 -0
- package/tools/cli/installers/install-messages.yaml +59 -0
- package/tools/cli/installers/lib/core/config-collector.js +1079 -0
- package/tools/cli/installers/lib/core/custom-module-cache.js +259 -0
- package/tools/cli/installers/lib/core/dependency-resolver.js +739 -0
- package/tools/cli/installers/lib/core/detector.js +223 -0
- package/tools/cli/installers/lib/core/ide-config-manager.js +156 -0
- package/tools/cli/installers/lib/core/installer.js +2812 -0
- package/tools/cli/installers/lib/core/manifest-generator.js +1054 -0
- package/tools/cli/installers/lib/core/manifest.js +1036 -0
- package/tools/cli/installers/lib/custom/handler.js +363 -0
- package/tools/cli/installers/lib/ide/_base-ide.js +655 -0
- package/tools/cli/installers/lib/ide/_config-driven.js +450 -0
- package/tools/cli/installers/lib/ide/codex.js +440 -0
- package/tools/cli/installers/lib/ide/kilo.js +250 -0
- package/tools/cli/installers/lib/ide/kiro-cli.js +326 -0
- package/tools/cli/installers/lib/ide/manager.js +271 -0
- package/tools/cli/installers/lib/ide/platform-codes.js +100 -0
- package/tools/cli/installers/lib/ide/platform-codes.yaml +227 -0
- package/tools/cli/installers/lib/ide/shared/agent-command-generator.js +181 -0
- package/tools/cli/installers/lib/ide/shared/bmad-artifacts.js +163 -0
- package/tools/cli/installers/lib/ide/shared/module-injections.js +136 -0
- package/tools/cli/installers/lib/ide/shared/path-utils.js +292 -0
- package/tools/cli/installers/lib/ide/shared/task-tool-command-generator.js +270 -0
- package/tools/cli/installers/lib/ide/shared/workflow-command-generator.js +319 -0
- package/tools/cli/installers/lib/ide/templates/agent-command-template.md +14 -0
- package/tools/cli/installers/lib/ide/templates/combined/antigravity.md +8 -0
- package/tools/cli/installers/lib/ide/templates/combined/default-agent.md +15 -0
- package/tools/cli/installers/lib/ide/templates/combined/default-workflow-yaml.md +14 -0
- package/tools/cli/installers/lib/ide/templates/combined/default-workflow.md +6 -0
- package/tools/cli/installers/lib/ide/templates/combined/gemini-agent.toml +14 -0
- package/tools/cli/installers/lib/ide/templates/combined/gemini-workflow-yaml.toml +16 -0
- package/tools/cli/installers/lib/ide/templates/combined/gemini-workflow.toml +14 -0
- package/tools/cli/installers/lib/ide/templates/combined/rovodev.md +9 -0
- package/tools/cli/installers/lib/ide/templates/combined/trae.md +9 -0
- package/tools/cli/installers/lib/ide/templates/combined/windsurf-workflow.md +10 -0
- package/tools/cli/installers/lib/ide/templates/split/opencode/body.md +10 -0
- package/tools/cli/installers/lib/ide/templates/split/opencode/header.md +4 -0
- package/tools/cli/installers/lib/ide/templates/workflow-command-template.md +13 -0
- package/tools/cli/installers/lib/ide/templates/workflow-commander.md +5 -0
- package/tools/cli/installers/lib/message-loader.js +85 -0
- package/tools/cli/installers/lib/modules/external-manager.js +135 -0
- package/tools/cli/installers/lib/modules/manager.js +1375 -0
- package/tools/cli/lib/activation-builder.js +163 -0
- package/tools/cli/lib/agent/compiler.js +522 -0
- package/tools/cli/lib/agent/compiler.ts +572 -0
- package/tools/cli/lib/agent/installer.js +716 -0
- package/tools/cli/lib/agent/template-engine.js +152 -0
- package/tools/cli/lib/agent/types.ts +155 -0
- package/tools/cli/lib/agent-analyzer.js +109 -0
- package/tools/cli/lib/agent-party-generator.js +194 -0
- package/tools/cli/lib/cli-utils.js +227 -0
- package/tools/cli/lib/config.js +213 -0
- package/tools/cli/lib/config.ts +227 -0
- package/tools/cli/lib/file-ops.js +204 -0
- package/tools/cli/lib/file-ops.ts +215 -0
- package/tools/cli/lib/platform-codes.js +116 -0
- package/tools/cli/lib/project-root.js +77 -0
- package/tools/cli/lib/prompts.js +433 -0
- package/tools/cli/lib/prompts.ts +541 -0
- package/tools/cli/lib/types/config.types.ts +43 -0
- package/tools/cli/lib/types/xml-handler.types.ts +50 -0
- package/tools/cli/lib/ui.js +1660 -0
- package/tools/cli/lib/xml-handler.js +177 -0
- package/tools/cli/lib/xml-handler.ts +188 -0
- package/tools/cli/lib/xml-to-markdown.js +82 -0
- package/tools/cli/lib/yaml-format.js +245 -0
- package/tools/cli/lib/yaml-xml-builder.js +587 -0
- package/tools/docs/BUNDLE_DISTRIBUTION_SETUP.md +95 -0
- package/tools/docs/fix-refs.md +91 -0
- package/tools/docs/index.md +2 -0
- package/tools/fix-doc-links.js +288 -0
- package/tools/flattener/aggregate.js +76 -0
- package/tools/flattener/aggregate.ts +78 -0
- package/tools/flattener/binary.js +80 -0
- package/tools/flattener/discovery.js +71 -0
- package/tools/flattener/files.js +35 -0
- package/tools/flattener/files.ts +31 -0
- package/tools/flattener/ignoreRules.js +172 -0
- package/tools/flattener/main.js +483 -0
- package/tools/flattener/main.ts +262 -0
- package/tools/flattener/projectRoot.js +201 -0
- package/tools/flattener/prompts.js +44 -0
- package/tools/flattener/stats.helpers.js +368 -0
- package/tools/flattener/stats.js +75 -0
- package/tools/flattener/test-matrix.js +409 -0
- package/tools/flattener/types.ts +53 -0
- package/tools/flattener/xml.js +82 -0
- package/tools/format-workflow-md.js +263 -0
- package/tools/lib/xml-utils.js +13 -0
- package/tools/maintainer/review-pr-README.md +55 -0
- package/tools/maintainer/review-pr.md +242 -0
- package/tools/migrate-custom-module-paths.js +124 -0
- package/tools/platform-codes.yaml +157 -0
- package/tools/schema/agent.js +491 -0
- package/tools/schema/agent.ts +489 -0
- package/tools/schema/agent.types.ts +31 -0
- package/tools/update-bmad.sh +24 -0
- package/tools/validate-agent-schema.js +110 -0
- package/tools/validate-doc-links.js +371 -0
- package/tools/validate-svg-changes.sh +356 -0
- package/vite-plugin-monaco-editor.ts +108 -0
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
const xml2js = require('xml2js');
|
|
2
|
+
const fs = require('fs-extra');
|
|
3
|
+
const path = require('node:path');
|
|
4
|
+
const { getProjectRoot, getSourcePath } = require('./project-root');
|
|
5
|
+
const { YamlXmlBuilder } = require('./yaml-xml-builder');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* XML utility functions for BMAD installer
|
|
9
|
+
* Now supports both legacy XML agents and new YAML-based agents
|
|
10
|
+
*/
|
|
11
|
+
class XmlHandler {
|
|
12
|
+
constructor() {
|
|
13
|
+
this.parser = new xml2js.Parser({
|
|
14
|
+
preserveChildrenOrder: true,
|
|
15
|
+
explicitChildren: true,
|
|
16
|
+
explicitArray: false,
|
|
17
|
+
trim: false,
|
|
18
|
+
normalizeTags: false,
|
|
19
|
+
attrkey: '$',
|
|
20
|
+
charkey: '_',
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
this.builder = new xml2js.Builder({
|
|
24
|
+
renderOpts: {
|
|
25
|
+
pretty: true,
|
|
26
|
+
indent: ' ',
|
|
27
|
+
newline: '\n',
|
|
28
|
+
},
|
|
29
|
+
xmldec: {
|
|
30
|
+
version: '1.0',
|
|
31
|
+
encoding: 'utf8',
|
|
32
|
+
standalone: false,
|
|
33
|
+
},
|
|
34
|
+
headless: true, // Don't add XML declaration
|
|
35
|
+
attrkey: '$',
|
|
36
|
+
charkey: '_',
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
this.yamlBuilder = new YamlXmlBuilder();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Load and parse the activation template
|
|
44
|
+
* @returns {Object} Parsed activation block
|
|
45
|
+
*/
|
|
46
|
+
async loadActivationTemplate() {
|
|
47
|
+
console.error('Failed to load activation template:', error);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Inject activation block into agent XML content
|
|
52
|
+
* @param {string} agentContent - The agent file content
|
|
53
|
+
* @param {Object} metadata - Metadata containing module and name
|
|
54
|
+
* @returns {string} Modified content with activation block
|
|
55
|
+
*/
|
|
56
|
+
async injectActivation(agentContent, metadata = {}) {
|
|
57
|
+
try {
|
|
58
|
+
// Check if already has activation
|
|
59
|
+
if (agentContent.includes('<activation')) {
|
|
60
|
+
return agentContent;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Extract the XML portion from markdown if needed
|
|
64
|
+
let xmlContent = agentContent;
|
|
65
|
+
let beforeXml = '';
|
|
66
|
+
let afterXml = '';
|
|
67
|
+
|
|
68
|
+
const xmlBlockMatch = agentContent.match(/([\s\S]*?)```xml\n([\s\S]*?)\n```([\s\S]*)/);
|
|
69
|
+
if (xmlBlockMatch) {
|
|
70
|
+
beforeXml = xmlBlockMatch[1] + '```xml\n';
|
|
71
|
+
xmlContent = xmlBlockMatch[2];
|
|
72
|
+
afterXml = '\n```' + xmlBlockMatch[3];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Parse the agent XML
|
|
76
|
+
const parsed = await this.parser.parseStringPromise(xmlContent);
|
|
77
|
+
|
|
78
|
+
// Get the activation template
|
|
79
|
+
const activationBlock = await this.loadActivationTemplate();
|
|
80
|
+
if (!activationBlock) {
|
|
81
|
+
console.warn('Could not load activation template');
|
|
82
|
+
return agentContent;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Find the agent node
|
|
86
|
+
if (
|
|
87
|
+
parsed.agent && // Insert activation as the first child
|
|
88
|
+
!parsed.agent.activation
|
|
89
|
+
) {
|
|
90
|
+
// Ensure proper structure
|
|
91
|
+
if (!parsed.agent.$$) {
|
|
92
|
+
parsed.agent.$$ = [];
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Create the activation node with proper structure
|
|
96
|
+
const activationNode = {
|
|
97
|
+
'#name': 'activation',
|
|
98
|
+
$: { critical: '1' },
|
|
99
|
+
$$: activationBlock.$$,
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
// Insert at the beginning
|
|
103
|
+
parsed.agent.$$.unshift(activationNode);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Convert back to XML
|
|
107
|
+
let modifiedXml = this.builder.buildObject(parsed);
|
|
108
|
+
|
|
109
|
+
// Fix indentation - xml2js doesn't maintain our exact formatting
|
|
110
|
+
// Add 2-space base indentation to match our style
|
|
111
|
+
const lines = modifiedXml.split('\n');
|
|
112
|
+
const indentedLines = lines.map((line) => {
|
|
113
|
+
if (line.trim() === '') return line;
|
|
114
|
+
if (line.startsWith('<agent')) return line; // Keep agent at column 0
|
|
115
|
+
return ' ' + line; // Indent everything else
|
|
116
|
+
});
|
|
117
|
+
modifiedXml = indentedLines.join('\n');
|
|
118
|
+
|
|
119
|
+
// Reconstruct the full content
|
|
120
|
+
return beforeXml + modifiedXml + afterXml;
|
|
121
|
+
} catch (error) {
|
|
122
|
+
console.error('Error injecting activation:', error);
|
|
123
|
+
return agentContent;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* TODO: DELETE THIS METHOD
|
|
129
|
+
*/
|
|
130
|
+
injectActivationSimple(agentContent, metadata = {}) {
|
|
131
|
+
console.error('Error in simple injection:', error);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Build agent from YAML source
|
|
136
|
+
* @param {string} yamlPath - Path to .agent.yaml file
|
|
137
|
+
* @param {string} customizePath - Path to .customize.yaml file (optional)
|
|
138
|
+
* @param {Object} metadata - Build metadata
|
|
139
|
+
* @returns {string} Generated XML content
|
|
140
|
+
*/
|
|
141
|
+
async buildFromYaml(yamlPath, customizePath = null, metadata = {}) {
|
|
142
|
+
try {
|
|
143
|
+
// Use YamlXmlBuilder to convert YAML to XML
|
|
144
|
+
const mergedAgent = await this.yamlBuilder.loadAndMergeAgent(yamlPath, customizePath);
|
|
145
|
+
|
|
146
|
+
// Build metadata
|
|
147
|
+
const buildMetadata = {
|
|
148
|
+
sourceFile: path.basename(yamlPath),
|
|
149
|
+
sourceHash: await this.yamlBuilder.calculateFileHash(yamlPath),
|
|
150
|
+
customizeFile: customizePath ? path.basename(customizePath) : null,
|
|
151
|
+
customizeHash: customizePath ? await this.yamlBuilder.calculateFileHash(customizePath) : null,
|
|
152
|
+
builderVersion: '1.0.0',
|
|
153
|
+
includeMetadata: metadata.includeMetadata !== false,
|
|
154
|
+
forWebBundle: metadata.forWebBundle || false, // Pass through forWebBundle flag
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
// Convert to XML
|
|
158
|
+
const xml = await this.yamlBuilder.convertToXml(mergedAgent, buildMetadata);
|
|
159
|
+
|
|
160
|
+
return xml;
|
|
161
|
+
} catch (error) {
|
|
162
|
+
console.error('Error building agent from YAML:', error);
|
|
163
|
+
throw error;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Check if a path is a YAML agent file
|
|
169
|
+
* @param {string} filePath - Path to check
|
|
170
|
+
* @returns {boolean} True if it's a YAML agent file
|
|
171
|
+
*/
|
|
172
|
+
isYamlAgent(filePath) {
|
|
173
|
+
return filePath.endsWith('.agent.yaml');
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
module.exports = { XmlHandler };
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
// @ts-ignore - xml2js doesn't have types
|
|
2
|
+
import * as xml2js from 'xml2js';
|
|
3
|
+
import * as path from 'node:path';
|
|
4
|
+
// @ts-ignore - YamlXmlBuilder is not yet converted to TypeScript
|
|
5
|
+
import { YamlXmlBuilder } from './yaml-xml-builder';
|
|
6
|
+
import type { AgentMetadata, BuildMetadata, ParsedAgent, XmlNode } from './types/xml-handler.types';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* XML utility functions for BMAD installer
|
|
10
|
+
* Now supports both legacy XML agents and new YAML-based agents
|
|
11
|
+
*/
|
|
12
|
+
export class XmlHandler {
|
|
13
|
+
private parser: xml2js.Parser;
|
|
14
|
+
private builder: xml2js.Builder;
|
|
15
|
+
private yamlBuilder: YamlXmlBuilder;
|
|
16
|
+
|
|
17
|
+
constructor() {
|
|
18
|
+
this.parser = new xml2js.Parser({
|
|
19
|
+
preserveChildrenOrder: true,
|
|
20
|
+
explicitChildren: true,
|
|
21
|
+
explicitArray: false,
|
|
22
|
+
trim: false,
|
|
23
|
+
normalizeTags: false,
|
|
24
|
+
attrkey: '$',
|
|
25
|
+
charkey: '_',
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
this.builder = new xml2js.Builder({
|
|
29
|
+
renderOpts: {
|
|
30
|
+
pretty: true,
|
|
31
|
+
indent: ' ',
|
|
32
|
+
newline: '\n',
|
|
33
|
+
},
|
|
34
|
+
xmldec: {
|
|
35
|
+
version: '1.0',
|
|
36
|
+
encoding: 'utf8',
|
|
37
|
+
standalone: false,
|
|
38
|
+
},
|
|
39
|
+
headless: true, // Don't add XML declaration
|
|
40
|
+
attrkey: '$',
|
|
41
|
+
charkey: '_',
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
this.yamlBuilder = new YamlXmlBuilder();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Load and parse the activation template
|
|
49
|
+
* @returns Parsed activation block
|
|
50
|
+
*/
|
|
51
|
+
async loadActivationTemplate(): Promise<XmlNode | null> {
|
|
52
|
+
console.error('Failed to load activation template:', 'error');
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Inject activation block into agent XML content
|
|
58
|
+
* @param agentContent - The agent file content
|
|
59
|
+
* @param _metadata - Metadata containing module and name (unused)
|
|
60
|
+
* @returns Modified content with activation block
|
|
61
|
+
*/
|
|
62
|
+
async injectActivation(agentContent: string, _metadata: AgentMetadata = {}): Promise<string> {
|
|
63
|
+
try {
|
|
64
|
+
// Check if already has activation
|
|
65
|
+
if (agentContent.includes('<activation')) {
|
|
66
|
+
return agentContent;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Extract the XML portion from markdown if needed
|
|
70
|
+
let xmlContent = agentContent;
|
|
71
|
+
let beforeXml = '';
|
|
72
|
+
let afterXml = '';
|
|
73
|
+
|
|
74
|
+
const xmlBlockMatch = agentContent.match(/([\s\S]*?)```xml\n([\s\S]*?)\n```([\s\S]*)/);
|
|
75
|
+
if (xmlBlockMatch) {
|
|
76
|
+
beforeXml = xmlBlockMatch[1] + '```xml\n';
|
|
77
|
+
xmlContent = xmlBlockMatch[2];
|
|
78
|
+
afterXml = '\n```' + xmlBlockMatch[3];
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Parse the agent XML
|
|
82
|
+
const parsed = (await this.parser.parseStringPromise(xmlContent)) as ParsedAgent;
|
|
83
|
+
|
|
84
|
+
// Get the activation template
|
|
85
|
+
const activationBlock = await this.loadActivationTemplate();
|
|
86
|
+
if (!activationBlock) {
|
|
87
|
+
console.warn('Could not load activation template');
|
|
88
|
+
return agentContent;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Find the agent node
|
|
92
|
+
if (
|
|
93
|
+
parsed.agent && // Insert activation as the first child
|
|
94
|
+
!parsed.agent.activation
|
|
95
|
+
) {
|
|
96
|
+
// Ensure proper structure
|
|
97
|
+
if (!parsed.agent.$$) {
|
|
98
|
+
parsed.agent.$$ = [];
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Create the activation node with proper structure
|
|
102
|
+
const activationNode: XmlNode = {
|
|
103
|
+
'#name': 'activation',
|
|
104
|
+
$: { critical: '1' },
|
|
105
|
+
$$: activationBlock.$$,
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
// Insert at the beginning
|
|
109
|
+
parsed.agent.$$.unshift(activationNode);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Convert back to XML
|
|
113
|
+
let modifiedXml = this.builder.buildObject(parsed);
|
|
114
|
+
|
|
115
|
+
// Fix indentation - xml2js doesn't maintain our exact formatting
|
|
116
|
+
// Add 2-space base indentation to match our style
|
|
117
|
+
const lines = modifiedXml.split('\n');
|
|
118
|
+
const indentedLines = lines.map((line: string) => {
|
|
119
|
+
if (line.trim() === '') return line;
|
|
120
|
+
if (line.startsWith('<agent')) return line; // Keep agent at column 0
|
|
121
|
+
return ' ' + line; // Indent everything else
|
|
122
|
+
});
|
|
123
|
+
modifiedXml = indentedLines.join('\n');
|
|
124
|
+
|
|
125
|
+
// Reconstruct the full content
|
|
126
|
+
return beforeXml + modifiedXml + afterXml;
|
|
127
|
+
} catch (error) {
|
|
128
|
+
console.error('Error injecting activation:', error);
|
|
129
|
+
return agentContent;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* TODO: DELETE THIS METHOD
|
|
135
|
+
*/
|
|
136
|
+
injectActivationSimple(_agentContent: string, _metadata: AgentMetadata = {}): void {
|
|
137
|
+
console.error('Error in simple injection:', 'error');
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Build agent from YAML source
|
|
142
|
+
* @param yamlPath - Path to .agent.yaml file
|
|
143
|
+
* @param customizePath - Path to .customize.yaml file (optional)
|
|
144
|
+
* @param metadata - Build metadata
|
|
145
|
+
* @returns Generated XML content
|
|
146
|
+
*/
|
|
147
|
+
async buildFromYaml(
|
|
148
|
+
yamlPath: string,
|
|
149
|
+
customizePath?: string | null,
|
|
150
|
+
metadata: AgentMetadata = {}
|
|
151
|
+
): Promise<string> {
|
|
152
|
+
try {
|
|
153
|
+
// Use YamlXmlBuilder to convert YAML to XML
|
|
154
|
+
const mergedAgent = await this.yamlBuilder.loadAndMergeAgent(yamlPath, customizePath || undefined);
|
|
155
|
+
|
|
156
|
+
// Build metadata
|
|
157
|
+
const buildMetadata: BuildMetadata = {
|
|
158
|
+
sourceFile: path.basename(yamlPath),
|
|
159
|
+
sourceHash: await this.yamlBuilder.calculateFileHash(yamlPath),
|
|
160
|
+
customizeFile: customizePath ? path.basename(customizePath) : null,
|
|
161
|
+
customizeHash: customizePath ? await this.yamlBuilder.calculateFileHash(customizePath) : null,
|
|
162
|
+
builderVersion: '1.0.0',
|
|
163
|
+
includeMetadata: metadata.includeMetadata !== false,
|
|
164
|
+
forWebBundle: metadata.forWebBundle || false, // Pass through forWebBundle flag
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
// Convert to XML
|
|
168
|
+
const xml = await this.yamlBuilder.convertToXml(mergedAgent, buildMetadata);
|
|
169
|
+
|
|
170
|
+
return xml;
|
|
171
|
+
} catch (error) {
|
|
172
|
+
console.error('Error building agent from YAML:', error);
|
|
173
|
+
throw error;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Check if a path is a YAML agent file
|
|
179
|
+
* @param filePath - Path to check
|
|
180
|
+
* @returns True if it's a YAML agent file
|
|
181
|
+
*/
|
|
182
|
+
isYamlAgent(filePath: string): boolean {
|
|
183
|
+
return filePath.endsWith('.agent.yaml');
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Export for backward compatibility
|
|
188
|
+
module.exports = { XmlHandler };
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
const fs = require('node:fs');
|
|
2
|
+
const path = require('node:path');
|
|
3
|
+
|
|
4
|
+
function convertXmlToMarkdown(xmlFilePath) {
|
|
5
|
+
if (!xmlFilePath.endsWith('.xml')) {
|
|
6
|
+
throw new Error('Input file must be an XML file');
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const xmlContent = fs.readFileSync(xmlFilePath, 'utf8');
|
|
10
|
+
|
|
11
|
+
const basename = path.basename(xmlFilePath, '.xml');
|
|
12
|
+
const dirname = path.dirname(xmlFilePath);
|
|
13
|
+
const mdFilePath = path.join(dirname, `${basename}.md`);
|
|
14
|
+
|
|
15
|
+
// Extract version and name/title from root element attributes
|
|
16
|
+
let title = basename;
|
|
17
|
+
let version = '';
|
|
18
|
+
|
|
19
|
+
// Match the root element and its attributes
|
|
20
|
+
const rootMatch = xmlContent.match(
|
|
21
|
+
/<[^>\s]+[^>]*?\sv="([^"]+)"[^>]*?(?:\sname="([^"]+)")?|<[^>\s]+[^>]*?(?:\sname="([^"]+)")?[^>]*?\sv="([^"]+)"/,
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
if (rootMatch) {
|
|
25
|
+
// Handle both v="x" name="y" and name="y" v="x" orders
|
|
26
|
+
version = rootMatch[1] || rootMatch[4] || '';
|
|
27
|
+
const nameAttr = rootMatch[2] || rootMatch[3] || '';
|
|
28
|
+
|
|
29
|
+
if (nameAttr) {
|
|
30
|
+
title = nameAttr;
|
|
31
|
+
} else {
|
|
32
|
+
// Try to find name in a <name> element if not in attributes
|
|
33
|
+
const nameElementMatch = xmlContent.match(/<name>([^<]+)<\/name>/);
|
|
34
|
+
if (nameElementMatch) {
|
|
35
|
+
title = nameElementMatch[1];
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const heading = version ? `# ${title} v${version}` : `# ${title}`;
|
|
41
|
+
|
|
42
|
+
const markdownContent = `${heading}
|
|
43
|
+
|
|
44
|
+
\`\`\`xml
|
|
45
|
+
${xmlContent}
|
|
46
|
+
\`\`\`
|
|
47
|
+
`;
|
|
48
|
+
|
|
49
|
+
fs.writeFileSync(mdFilePath, markdownContent, 'utf8');
|
|
50
|
+
|
|
51
|
+
return mdFilePath;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function main() {
|
|
55
|
+
const args = process.argv.slice(2);
|
|
56
|
+
|
|
57
|
+
if (args.length === 0) {
|
|
58
|
+
console.error('Usage: node xml-to-markdown.js <xml-file-path>');
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const xmlFilePath = path.resolve(args[0]);
|
|
63
|
+
|
|
64
|
+
if (!fs.existsSync(xmlFilePath)) {
|
|
65
|
+
console.error(`Error: File not found: ${xmlFilePath}`);
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
try {
|
|
70
|
+
const mdFilePath = convertXmlToMarkdown(xmlFilePath);
|
|
71
|
+
console.log(`Successfully converted: ${xmlFilePath} -> ${mdFilePath}`);
|
|
72
|
+
} catch (error) {
|
|
73
|
+
console.error(`Error converting file: ${error.message}`);
|
|
74
|
+
process.exit(1);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (require.main === module) {
|
|
79
|
+
main();
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
module.exports = { convertXmlToMarkdown };
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
const fs = require('node:fs');
|
|
2
|
+
const path = require('node:path');
|
|
3
|
+
const yaml = require('yaml');
|
|
4
|
+
const { execSync } = require('node:child_process');
|
|
5
|
+
|
|
6
|
+
// Dynamic import for ES module
|
|
7
|
+
let chalk;
|
|
8
|
+
|
|
9
|
+
// Initialize ES modules
|
|
10
|
+
async function initializeModules() {
|
|
11
|
+
if (!chalk) {
|
|
12
|
+
chalk = (await import('chalk')).default;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* YAML Formatter and Linter for BMad-Method
|
|
18
|
+
* Formats and validates YAML files and YAML embedded in Markdown
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
async function formatYamlContent(content, filename) {
|
|
22
|
+
await initializeModules();
|
|
23
|
+
try {
|
|
24
|
+
// First try to fix common YAML issues
|
|
25
|
+
let fixedContent = content
|
|
26
|
+
// Fix "commands :" -> "commands:"
|
|
27
|
+
.replaceAll(/^(\s*)(\w+)\s+:/gm, '$1$2:')
|
|
28
|
+
// Fix inconsistent list indentation
|
|
29
|
+
.replaceAll(/^(\s*)-\s{3,}/gm, '$1- ');
|
|
30
|
+
|
|
31
|
+
// Skip auto-fixing for .roomodes files - they have special nested structure
|
|
32
|
+
if (!filename.includes('.roomodes')) {
|
|
33
|
+
fixedContent = fixedContent
|
|
34
|
+
// Fix unquoted list items that contain special characters or multiple parts
|
|
35
|
+
.replaceAll(/^(\s*)-\s+(.*)$/gm, (match, indent, content) => {
|
|
36
|
+
// Skip if already quoted
|
|
37
|
+
if (content.startsWith('"') && content.endsWith('"')) {
|
|
38
|
+
return match;
|
|
39
|
+
}
|
|
40
|
+
// If the content contains special YAML characters or looks complex, quote it
|
|
41
|
+
// BUT skip if it looks like a proper YAML key-value pair (like "key: value")
|
|
42
|
+
if (
|
|
43
|
+
(content.includes(':') || content.includes('-') || content.includes('{') || content.includes('}')) &&
|
|
44
|
+
!/^\w+:\s/.test(content)
|
|
45
|
+
) {
|
|
46
|
+
// Remove any existing quotes first, escape internal quotes, then add proper quotes
|
|
47
|
+
const cleanContent = content.replaceAll(/^["']|["']$/g, '').replaceAll('"', String.raw`\"`);
|
|
48
|
+
return `${indent}- "${cleanContent}"`;
|
|
49
|
+
}
|
|
50
|
+
return match;
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Debug: show what we're trying to parse
|
|
55
|
+
if (fixedContent !== content) {
|
|
56
|
+
console.log(chalk.blue(`🔧 Applied YAML fixes to ${filename}`));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Parse and re-dump YAML to format it
|
|
60
|
+
const parsed = yaml.parse(fixedContent);
|
|
61
|
+
const formatted = yaml.stringify(parsed, {
|
|
62
|
+
indent: 2,
|
|
63
|
+
lineWidth: 0, // Disable line wrapping
|
|
64
|
+
sortKeys: false, // Preserve key order
|
|
65
|
+
});
|
|
66
|
+
// Ensure POSIX-compliant final newline
|
|
67
|
+
return formatted.endsWith('\n') ? formatted : formatted + '\n';
|
|
68
|
+
} catch (error) {
|
|
69
|
+
console.error(chalk.red(`❌ YAML syntax error in ${filename}:`), error.message);
|
|
70
|
+
console.error(chalk.yellow(`💡 Try manually fixing the YAML structure first`));
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async function processMarkdownFile(filePath) {
|
|
76
|
+
await initializeModules();
|
|
77
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
78
|
+
let modified = false;
|
|
79
|
+
let newContent = content;
|
|
80
|
+
|
|
81
|
+
// Fix untyped code blocks by adding 'text' type
|
|
82
|
+
// Match ``` at start of line followed by newline, but only if it's an opening fence
|
|
83
|
+
newContent = newContent.replaceAll(/^```\n([\s\S]*?)\n```$/gm, '```text\n$1\n```');
|
|
84
|
+
if (newContent !== content) {
|
|
85
|
+
modified = true;
|
|
86
|
+
console.log(chalk.blue(`🔧 Added 'text' type to untyped code blocks in ${filePath}`));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Find YAML code blocks
|
|
90
|
+
const yamlBlockRegex = /```ya?ml\n([\s\S]*?)\n```/g;
|
|
91
|
+
let match;
|
|
92
|
+
const replacements = [];
|
|
93
|
+
|
|
94
|
+
while ((match = yamlBlockRegex.exec(newContent)) !== null) {
|
|
95
|
+
const [fullMatch, yamlContent] = match;
|
|
96
|
+
const formatted = await formatYamlContent(yamlContent, filePath);
|
|
97
|
+
if (formatted !== null) {
|
|
98
|
+
const trimmedFormatted = formatted.replace(/\n$/, '');
|
|
99
|
+
|
|
100
|
+
if (trimmedFormatted !== yamlContent) {
|
|
101
|
+
modified = true;
|
|
102
|
+
console.log(chalk.green(`✓ Formatted YAML in ${filePath}`));
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
replacements.push({
|
|
106
|
+
start: match.index,
|
|
107
|
+
end: match.index + fullMatch.length,
|
|
108
|
+
replacement: `\`\`\`yaml\n${trimmedFormatted}\n\`\`\``,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Apply replacements in reverse order to maintain indices
|
|
114
|
+
for (let index = replacements.length - 1; index >= 0; index--) {
|
|
115
|
+
const { start, end, replacement } = replacements[index];
|
|
116
|
+
newContent = newContent.slice(0, start) + replacement + newContent.slice(end);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (modified) {
|
|
120
|
+
fs.writeFileSync(filePath, newContent);
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
async function processYamlFile(filePath) {
|
|
127
|
+
await initializeModules();
|
|
128
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
129
|
+
const formatted = await formatYamlContent(content, filePath);
|
|
130
|
+
|
|
131
|
+
if (formatted === null) {
|
|
132
|
+
return false; // Syntax error
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (formatted !== content) {
|
|
136
|
+
fs.writeFileSync(filePath, formatted);
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
async function lintYamlFile(filePath) {
|
|
143
|
+
await initializeModules();
|
|
144
|
+
try {
|
|
145
|
+
// Use yaml-lint for additional validation
|
|
146
|
+
execSync(`npx yaml-lint "${filePath}"`, { stdio: 'pipe' });
|
|
147
|
+
return true;
|
|
148
|
+
} catch (error) {
|
|
149
|
+
console.error(chalk.red(`❌ YAML lint error in ${filePath}:`));
|
|
150
|
+
console.error(error.stdout?.toString() || error.message);
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
async function main() {
|
|
156
|
+
await initializeModules();
|
|
157
|
+
const arguments_ = process.argv.slice(2);
|
|
158
|
+
const glob = require('glob');
|
|
159
|
+
|
|
160
|
+
if (arguments_.length === 0) {
|
|
161
|
+
console.error('Usage: node yaml-format.js <file1> [file2] ...');
|
|
162
|
+
process.exit(1);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
let hasErrors = false;
|
|
166
|
+
let hasChanges = false;
|
|
167
|
+
let filesProcessed = [];
|
|
168
|
+
|
|
169
|
+
// Expand glob patterns and collect all files
|
|
170
|
+
const allFiles = [];
|
|
171
|
+
for (const argument of arguments_) {
|
|
172
|
+
if (argument.includes('*')) {
|
|
173
|
+
// It's a glob pattern
|
|
174
|
+
const matches = glob.sync(argument);
|
|
175
|
+
allFiles.push(...matches);
|
|
176
|
+
} else {
|
|
177
|
+
// It's a direct file path
|
|
178
|
+
allFiles.push(argument);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
for (const filePath of allFiles) {
|
|
183
|
+
if (!fs.existsSync(filePath)) {
|
|
184
|
+
// Skip silently for glob patterns that don't match anything
|
|
185
|
+
if (!arguments_.some((argument) => argument.includes('*') && filePath === argument)) {
|
|
186
|
+
console.error(chalk.red(`❌ File not found: ${filePath}`));
|
|
187
|
+
hasErrors = true;
|
|
188
|
+
}
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const extension = path.extname(filePath).toLowerCase();
|
|
193
|
+
const basename = path.basename(filePath).toLowerCase();
|
|
194
|
+
|
|
195
|
+
try {
|
|
196
|
+
let changed = false;
|
|
197
|
+
if (extension === '.md') {
|
|
198
|
+
changed = await processMarkdownFile(filePath);
|
|
199
|
+
} else if (
|
|
200
|
+
extension === '.yaml' ||
|
|
201
|
+
extension === '.yml' ||
|
|
202
|
+
basename.includes('roomodes') ||
|
|
203
|
+
basename.includes('.yaml') ||
|
|
204
|
+
basename.includes('.yml')
|
|
205
|
+
) {
|
|
206
|
+
// Handle YAML files and special cases like .roomodes
|
|
207
|
+
changed = await processYamlFile(filePath);
|
|
208
|
+
|
|
209
|
+
// Also run linting
|
|
210
|
+
const lintPassed = await lintYamlFile(filePath);
|
|
211
|
+
if (!lintPassed) hasErrors = true;
|
|
212
|
+
} else {
|
|
213
|
+
// Skip silently for unsupported files
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if (changed) {
|
|
218
|
+
hasChanges = true;
|
|
219
|
+
filesProcessed.push(filePath);
|
|
220
|
+
}
|
|
221
|
+
} catch (error) {
|
|
222
|
+
console.error(chalk.red(`❌ Error processing ${filePath}:`), error.message);
|
|
223
|
+
hasErrors = true;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if (hasChanges) {
|
|
228
|
+
console.log(chalk.green(`\n✨ YAML formatting completed! Modified ${filesProcessed.length} files:`));
|
|
229
|
+
for (const file of filesProcessed) console.log(chalk.blue(` 📝 ${file}`));
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
if (hasErrors) {
|
|
233
|
+
console.error(chalk.red('\n💥 Some files had errors. Please fix them before committing.'));
|
|
234
|
+
process.exit(1);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
if (require.main === module) {
|
|
239
|
+
main().catch((error) => {
|
|
240
|
+
console.error('Error:', error);
|
|
241
|
+
process.exit(1);
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
module.exports = { formatYamlContent, processMarkdownFile, processYamlFile };
|