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,91 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Fix Documentation References
|
|
3
|
+
description: Corrects workflow, agent, and command references in BMad documentation
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Fix Documentation References
|
|
7
|
+
|
|
8
|
+
## Scope
|
|
9
|
+
|
|
10
|
+
Fix reference patterns ONLY. Do not modify links, formatting, structure, or other content.
|
|
11
|
+
|
|
12
|
+
## Purpose
|
|
13
|
+
|
|
14
|
+
Fix incorrect references to workflows, agents, and commands in BMad documentation files.
|
|
15
|
+
|
|
16
|
+
## Step 1: Establish Target Audience
|
|
17
|
+
|
|
18
|
+
Before fixing references, determine who the document is for:
|
|
19
|
+
|
|
20
|
+
| Audience | Indicators | Style |
|
|
21
|
+
|----------|------------|-------|
|
|
22
|
+
| **Newbies** | tutorials/, getting-started, installation/, "What You'll Learn" | Keep "workflow", include platform hints |
|
|
23
|
+
| **Experienced** | reference/, explanation/ | Drop "workflow", no platform hints |
|
|
24
|
+
| **How-To** | how-to/ | **Ask** — depends on the task |
|
|
25
|
+
|
|
26
|
+
**How-To guides require judgment**: Don't assume experienced. Ask: "Does this task require prior BMad knowledge?" Early-journey tasks (first PRD, first sprint) are newbie docs. Customization and advanced features are experienced.
|
|
27
|
+
|
|
28
|
+
**If unclear**: Ask the user "Who is the target audience for this document — new users learning BMad, or experienced users who know the system?"
|
|
29
|
+
|
|
30
|
+
This determines whether helper words like "workflow" and platform hints are helpful context or just noise.
|
|
31
|
+
|
|
32
|
+
## Reference Patterns to Fix
|
|
33
|
+
|
|
34
|
+
### Always Wrong
|
|
35
|
+
|
|
36
|
+
| Pattern | Example | Problem |
|
|
37
|
+
|---------|---------|---------|
|
|
38
|
+
| `*workflow` | `*prd` | Obsolete menu shortcut notation |
|
|
39
|
+
| `/workflow` | `/workflow-init` | Platform-specific slash command |
|
|
40
|
+
| `bmad_bmm_*` | `bmad_bmm_workflow-init` | Internal slash command name, platform-specific |
|
|
41
|
+
|
|
42
|
+
### Correct Format
|
|
43
|
+
|
|
44
|
+
Use backticks with plain workflow name:
|
|
45
|
+
- **Wrong**: Run `/workflow-init`
|
|
46
|
+
- **Wrong**: Run `*prd`
|
|
47
|
+
|
|
48
|
+
**When to say "workflow"**:
|
|
49
|
+
- **Newbie docs** (getting-started): "Run the `prd` workflow" — helps them learn what it is
|
|
50
|
+
- **Other docs**: "Run `prd`" — they already know, so "workflow" is noise
|
|
51
|
+
|
|
52
|
+
**Platform hint**: Only in newbie docs, and only on the **first** workflow mention:
|
|
53
|
+
- First mention: Run the `help` workflow (`/bmad-help` on most platforms)
|
|
54
|
+
- Subsequent mentions: Run `prd` — no hint, no "workflow" needed after they've seen the pattern
|
|
55
|
+
|
|
56
|
+
In experienced docs, the hint is always noise — just use the workflow name.
|
|
57
|
+
|
|
58
|
+
### Workflow Name Changes
|
|
59
|
+
|
|
60
|
+
| Old Name | New Name | Notes |
|
|
61
|
+
|----------|----------|-------|
|
|
62
|
+
| `workflow-init` | `bmad-help` | DEPRECATED - help system replaces initialization |
|
|
63
|
+
| `workflow-status` | `bmad-help` | DEPRECATED - help system replaces status checking |
|
|
64
|
+
|
|
65
|
+
### The Help System
|
|
66
|
+
|
|
67
|
+
The `bmad-help` workflow is the modern replacement for both `workflow-init` and `workflow-status`:
|
|
68
|
+
- **Universal**: Works regardless of workflow state or module
|
|
69
|
+
- **Contextual**: Infers completion from artifacts and conversation
|
|
70
|
+
- **Adaptive**: Guides users through workflows based on phase ordering
|
|
71
|
+
- **Anytime**: Can be run at any point, no pre-initialization needed
|
|
72
|
+
|
|
73
|
+
Users can run `bmad-help` to get guidance on what to do next. It detects:
|
|
74
|
+
- What workflows have been completed (by checking for output artifacts)
|
|
75
|
+
- What module is active
|
|
76
|
+
- What the next recommended/required step is
|
|
77
|
+
|
|
78
|
+
## Lessons Learned
|
|
79
|
+
|
|
80
|
+
1. **Platform-agnostic**: Docs should never include platform-specific invocation patterns (slashes, prefixes)
|
|
81
|
+
2. **Backtick the name**: Use backticks around workflow names: `workflow-name`
|
|
82
|
+
3. **Simple names**: Just the workflow name, no `bmad_bmm_` prefix, no `/` prefix
|
|
83
|
+
|
|
84
|
+
## Self-Check
|
|
85
|
+
|
|
86
|
+
Before finishing, verify you ONLY changed reference patterns:
|
|
87
|
+
|
|
88
|
+
- [ ] Did I change any hyperlinks? **If yes, revert.**
|
|
89
|
+
- [ ] Did I change any formatting (horizontal rules, whitespace, structure)? **If yes, revert.**
|
|
90
|
+
- [ ] Did I remove or add any sections? **If yes, revert.**
|
|
91
|
+
- [ ] Did I modify anything not matching the patterns in "Reference Patterns to Fix"? **If yes, revert.**
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fix Documentation Links
|
|
3
|
+
*
|
|
4
|
+
* Converts relative markdown links to repo-relative paths with .md extension.
|
|
5
|
+
* This ensures links work both in GitHub and on the Astro/Starlight site
|
|
6
|
+
* (the rehype plugin transforms /docs/path/file.md → /path/file/ at build time).
|
|
7
|
+
*
|
|
8
|
+
* - ./file.md → /docs/current/path/file.md
|
|
9
|
+
* - ../other/file.md → /docs/resolved/path/file.md
|
|
10
|
+
* - /path/file/ → /docs/path/file.md (or /docs/path/file/index.md if it's a directory)
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* node tools/fix-doc-links.js # Dry run (shows what would change)
|
|
14
|
+
* node tools/fix-doc-links.js --write # Actually write changes
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const fs = require('node:fs');
|
|
18
|
+
const path = require('node:path');
|
|
19
|
+
|
|
20
|
+
const DOCS_ROOT = path.resolve(__dirname, '../docs');
|
|
21
|
+
const DRY_RUN = !process.argv.includes('--write');
|
|
22
|
+
|
|
23
|
+
// Regex to match markdown links:
|
|
24
|
+
// - [text](path.md) or [text](path.md#anchor) - existing .md links
|
|
25
|
+
// - [text](/path/to/page/) or [text](/path/to/page/#anchor) - site-relative links to convert
|
|
26
|
+
const MARKDOWN_LINK_REGEX = /\[([^\]]*)\]\(([^)]+(?:\.md|\/))(?:#[^)]*)?(?:\?[^)]*)?\)/g;
|
|
27
|
+
// Simpler approach: match all markdown links and filter in the handler
|
|
28
|
+
const ALL_MARKDOWN_LINKS_REGEX = /\[([^\]]*)\]\(([^)]+)\)/g;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Get all markdown files in docs directory, excluding _* directories/files
|
|
32
|
+
*/
|
|
33
|
+
function getMarkdownFiles(dir) {
|
|
34
|
+
const files = [];
|
|
35
|
+
|
|
36
|
+
function walk(currentDir) {
|
|
37
|
+
const entries = fs.readdirSync(currentDir, { withFileTypes: true });
|
|
38
|
+
|
|
39
|
+
for (const entry of entries) {
|
|
40
|
+
const fullPath = path.join(currentDir, entry.name);
|
|
41
|
+
|
|
42
|
+
// Skip underscore-prefixed entries
|
|
43
|
+
if (entry.name.startsWith('_')) {
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (entry.isDirectory()) {
|
|
48
|
+
walk(fullPath);
|
|
49
|
+
} else if (entry.isFile() && entry.name.endsWith('.md')) {
|
|
50
|
+
files.push(fullPath);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
walk(dir);
|
|
56
|
+
return files;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Convert a markdown link href to repo-relative path with .md extension
|
|
61
|
+
*
|
|
62
|
+
* @param {string} href - The original href (e.g., "./file.md", "/path/to/page/", "/path/to/page/#anchor")
|
|
63
|
+
* @param {string} currentFilePath - Absolute path to the file containing this link
|
|
64
|
+
* @returns {string|null} - Repo-relative path (e.g., "/docs/path/to/file.md"), or null if shouldn't be converted
|
|
65
|
+
*/
|
|
66
|
+
function convertToRepoRelative(href, currentFilePath) {
|
|
67
|
+
// Skip external links
|
|
68
|
+
if (href.includes('://') || href.startsWith('mailto:') || href.startsWith('tel:')) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Skip anchor-only links
|
|
73
|
+
if (href.startsWith('#')) {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Extract anchor and query string if present
|
|
78
|
+
let anchor = '';
|
|
79
|
+
let query = '';
|
|
80
|
+
let pathPortion = href;
|
|
81
|
+
|
|
82
|
+
const hashIndex = href.indexOf('#');
|
|
83
|
+
const queryIndex = href.indexOf('?');
|
|
84
|
+
|
|
85
|
+
if (hashIndex !== -1 || queryIndex !== -1) {
|
|
86
|
+
const firstDelimiter = Math.min(hashIndex === -1 ? Infinity : hashIndex, queryIndex === -1 ? Infinity : queryIndex);
|
|
87
|
+
pathPortion = href.slice(0, Math.max(0, firstDelimiter));
|
|
88
|
+
|
|
89
|
+
const suffix = href.slice(Math.max(0, firstDelimiter));
|
|
90
|
+
const anchorInSuffix = suffix.indexOf('#');
|
|
91
|
+
|
|
92
|
+
if (suffix.startsWith('?')) {
|
|
93
|
+
if (anchorInSuffix === -1) {
|
|
94
|
+
query = suffix;
|
|
95
|
+
} else {
|
|
96
|
+
query = suffix.slice(0, Math.max(0, anchorInSuffix));
|
|
97
|
+
anchor = suffix.slice(Math.max(0, anchorInSuffix));
|
|
98
|
+
}
|
|
99
|
+
} else {
|
|
100
|
+
anchor = suffix;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Skip non-documentation links (images, external assets, etc.)
|
|
105
|
+
const ext = path.extname(pathPortion).toLowerCase();
|
|
106
|
+
if (
|
|
107
|
+
ext &&
|
|
108
|
+
ext !== '.md' &&
|
|
109
|
+
!['.md'].includes(ext) && // Has an extension that's not .md - skip unless it's a trailing slash path
|
|
110
|
+
!pathPortion.endsWith('/')
|
|
111
|
+
) {
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Check if original path ends with / (directory reference) BEFORE path.join normalizes it
|
|
116
|
+
const isDirectoryPath = pathPortion.endsWith('/');
|
|
117
|
+
|
|
118
|
+
let absolutePath;
|
|
119
|
+
|
|
120
|
+
if (pathPortion.startsWith('/docs/')) {
|
|
121
|
+
// Already repo-relative with /docs/ prefix
|
|
122
|
+
absolutePath = path.join(path.dirname(DOCS_ROOT), pathPortion);
|
|
123
|
+
} else if (pathPortion.startsWith('/')) {
|
|
124
|
+
// Site-relative (e.g., /tutorials/getting-started/) - resolve from docs root
|
|
125
|
+
absolutePath = path.join(DOCS_ROOT, pathPortion);
|
|
126
|
+
} else {
|
|
127
|
+
// Relative path (./, ../, or bare filename) - resolve from current file's directory
|
|
128
|
+
const currentDir = path.dirname(currentFilePath);
|
|
129
|
+
absolutePath = path.resolve(currentDir, pathPortion);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Convert to repo-relative path (with /docs/ prefix)
|
|
133
|
+
let repoRelative = '/docs/' + path.relative(DOCS_ROOT, absolutePath);
|
|
134
|
+
|
|
135
|
+
// Normalize path separators for Windows
|
|
136
|
+
repoRelative = repoRelative.split(path.sep).join('/');
|
|
137
|
+
|
|
138
|
+
// If original path was a directory reference (ended with /), check for index.md or file.md
|
|
139
|
+
if (isDirectoryPath) {
|
|
140
|
+
const relativeDir = repoRelative.slice(6); // Remove '/docs/'
|
|
141
|
+
|
|
142
|
+
// Handle root path case (relativeDir is empty or just '.')
|
|
143
|
+
const normalizedDir = relativeDir === '' || relativeDir === '.' ? '' : relativeDir;
|
|
144
|
+
const indexPath = path.join(DOCS_ROOT, normalizedDir, 'index.md');
|
|
145
|
+
const filePath = normalizedDir ? path.join(DOCS_ROOT, normalizedDir + '.md') : null;
|
|
146
|
+
|
|
147
|
+
if (fs.existsSync(indexPath)) {
|
|
148
|
+
// Avoid double slash when repoRelative is '/docs/' (root case)
|
|
149
|
+
repoRelative = repoRelative.endsWith('/') ? repoRelative + 'index.md' : repoRelative + '/index.md';
|
|
150
|
+
} else if (filePath && fs.existsSync(filePath)) {
|
|
151
|
+
repoRelative = repoRelative + '.md';
|
|
152
|
+
} else {
|
|
153
|
+
// Neither exists - default to index.md and let validation catch it
|
|
154
|
+
repoRelative = repoRelative.endsWith('/') ? repoRelative + 'index.md' : repoRelative + '/index.md';
|
|
155
|
+
}
|
|
156
|
+
} else if (!repoRelative.endsWith('.md')) {
|
|
157
|
+
// Path doesn't end with .md - add .md
|
|
158
|
+
repoRelative = repoRelative + '.md';
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return repoRelative + query + anchor;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Process a single markdown file, skipping links inside fenced code blocks
|
|
166
|
+
*
|
|
167
|
+
* @param {string} filePath - Absolute path to the file
|
|
168
|
+
* @returns {Object} - { changed: boolean, original: string, updated: string, changes: Array }
|
|
169
|
+
*/
|
|
170
|
+
function processFile(filePath) {
|
|
171
|
+
const original = fs.readFileSync(filePath, 'utf-8');
|
|
172
|
+
const changes = [];
|
|
173
|
+
|
|
174
|
+
// Extract fenced code blocks and replace with placeholders
|
|
175
|
+
const codeBlocks = [];
|
|
176
|
+
const CODE_PLACEHOLDER = '\u0000CODE_BLOCK_';
|
|
177
|
+
|
|
178
|
+
let contentWithPlaceholders = original.replaceAll(/```[\s\S]*?```/g, (match) => {
|
|
179
|
+
const index = codeBlocks.length;
|
|
180
|
+
codeBlocks.push(match);
|
|
181
|
+
return `${CODE_PLACEHOLDER}${index}\u0000`;
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
// Process links only in non-code-block content
|
|
185
|
+
contentWithPlaceholders = contentWithPlaceholders.replaceAll(ALL_MARKDOWN_LINKS_REGEX, (match, linkText, href) => {
|
|
186
|
+
const newHref = convertToRepoRelative(href, filePath);
|
|
187
|
+
|
|
188
|
+
// Skip if conversion returned null (external link, anchor, etc.)
|
|
189
|
+
if (newHref === null) {
|
|
190
|
+
return match;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Only record as change if actually different
|
|
194
|
+
if (newHref !== href) {
|
|
195
|
+
changes.push({ from: href, to: newHref });
|
|
196
|
+
return `[${linkText}](${newHref})`;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return match;
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
// Restore code blocks
|
|
203
|
+
const updated = contentWithPlaceholders.replaceAll(
|
|
204
|
+
new RegExp(`${CODE_PLACEHOLDER}(\\d+)\u0000`, 'g'),
|
|
205
|
+
(match, index) => codeBlocks[parseInt(index, 10)],
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
return {
|
|
209
|
+
changed: changes.length > 0,
|
|
210
|
+
original,
|
|
211
|
+
updated,
|
|
212
|
+
changes,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Validate that a repo-relative link points to an existing file
|
|
218
|
+
*/
|
|
219
|
+
function validateLink(repoRelativePath) {
|
|
220
|
+
// Strip anchor/query
|
|
221
|
+
const checkPath = repoRelativePath.split('#')[0].split('?')[0];
|
|
222
|
+
|
|
223
|
+
// Remove /docs/ prefix to get path relative to DOCS_ROOT
|
|
224
|
+
const relativePath = checkPath.startsWith('/docs/') ? checkPath.slice(6) : checkPath.slice(1);
|
|
225
|
+
|
|
226
|
+
return fs.existsSync(path.join(DOCS_ROOT, relativePath));
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Main execution
|
|
230
|
+
console.log(`\nScanning docs in: ${DOCS_ROOT}`);
|
|
231
|
+
console.log(`Mode: ${DRY_RUN ? 'DRY RUN (use --write to apply changes)' : 'WRITE MODE'}\n`);
|
|
232
|
+
|
|
233
|
+
const files = getMarkdownFiles(DOCS_ROOT);
|
|
234
|
+
console.log(`Found ${files.length} markdown files (excluding _* paths)\n`);
|
|
235
|
+
|
|
236
|
+
let totalChanges = 0;
|
|
237
|
+
let filesChanged = 0;
|
|
238
|
+
const brokenLinks = [];
|
|
239
|
+
|
|
240
|
+
for (const filePath of files) {
|
|
241
|
+
const relativePath = path.relative(DOCS_ROOT, filePath);
|
|
242
|
+
const result = processFile(filePath);
|
|
243
|
+
|
|
244
|
+
if (result.changed) {
|
|
245
|
+
filesChanged++;
|
|
246
|
+
totalChanges += result.changes.length;
|
|
247
|
+
|
|
248
|
+
console.log(`\n${relativePath}`);
|
|
249
|
+
for (const change of result.changes) {
|
|
250
|
+
const isValid = validateLink(change.to);
|
|
251
|
+
const status = isValid ? ' ' : '! ';
|
|
252
|
+
|
|
253
|
+
console.log(`${status} ${change.from}`);
|
|
254
|
+
console.log(` -> ${change.to}`);
|
|
255
|
+
|
|
256
|
+
if (!isValid) {
|
|
257
|
+
brokenLinks.push({
|
|
258
|
+
file: relativePath,
|
|
259
|
+
link: change.to,
|
|
260
|
+
original: change.from,
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
if (!DRY_RUN) {
|
|
266
|
+
fs.writeFileSync(filePath, result.updated, 'utf-8');
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
console.log(`\n${'─'.repeat(60)}`);
|
|
272
|
+
console.log(`\nSummary:`);
|
|
273
|
+
console.log(` Files scanned: ${files.length}`);
|
|
274
|
+
console.log(` Files with changes: ${filesChanged}`);
|
|
275
|
+
console.log(` Total link updates: ${totalChanges}`);
|
|
276
|
+
|
|
277
|
+
if (brokenLinks.length > 0) {
|
|
278
|
+
console.log(`\n! Potential broken links (${brokenLinks.length}):`);
|
|
279
|
+
for (const bl of brokenLinks) {
|
|
280
|
+
console.log(` ${bl.file}: ${bl.link}`);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if (DRY_RUN && totalChanges > 0) {
|
|
285
|
+
console.log(`\nRun with --write to apply these changes`);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
console.log('');
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('node:path');
|
|
3
|
+
const os = require('node:os');
|
|
4
|
+
const { isBinaryFile } = require('./binary.js');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Aggregate file contents with bounded concurrency.
|
|
8
|
+
* Returns text files, binary files (with size), and errors.
|
|
9
|
+
* @param {string[]} files absolute file paths
|
|
10
|
+
* @param {string} rootDir
|
|
11
|
+
* @param {{ text?: string, warn?: (msg: string) => void } | null} spinner
|
|
12
|
+
*/
|
|
13
|
+
async function aggregateFileContents(files, rootDir, spinner = null) {
|
|
14
|
+
const results = {
|
|
15
|
+
textFiles: [],
|
|
16
|
+
binaryFiles: [],
|
|
17
|
+
errors: [],
|
|
18
|
+
totalFiles: files.length,
|
|
19
|
+
processedFiles: 0,
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// Automatic concurrency selection based on CPU count and workload size.
|
|
23
|
+
// - Base on 2x logical CPUs, clamped to [2, 64]
|
|
24
|
+
// - For very small workloads, avoid excessive parallelism
|
|
25
|
+
const cpuCount = os.cpus && Array.isArray(os.cpus()) ? os.cpus().length : os.cpus?.length || 4;
|
|
26
|
+
let concurrency = Math.min(64, Math.max(2, (Number(cpuCount) || 4) * 2));
|
|
27
|
+
if (files.length > 0 && files.length < concurrency) {
|
|
28
|
+
concurrency = Math.max(1, Math.min(concurrency, Math.ceil(files.length / 2)));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async function processOne(filePath) {
|
|
32
|
+
try {
|
|
33
|
+
const relativePath = path.relative(rootDir, filePath);
|
|
34
|
+
if (spinner) {
|
|
35
|
+
spinner.text = `Processing: ${relativePath} (${results.processedFiles + 1}/${results.totalFiles})`;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const binary = await isBinaryFile(filePath);
|
|
39
|
+
if (binary) {
|
|
40
|
+
const { size } = await fs.stat(filePath);
|
|
41
|
+
results.binaryFiles.push({ path: relativePath, absolutePath: filePath, size });
|
|
42
|
+
} else {
|
|
43
|
+
const content = await fs.readFile(filePath, 'utf8');
|
|
44
|
+
results.textFiles.push({
|
|
45
|
+
path: relativePath,
|
|
46
|
+
absolutePath: filePath,
|
|
47
|
+
content,
|
|
48
|
+
size: content.length,
|
|
49
|
+
lines: content.split('\n').length,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
} catch (error) {
|
|
53
|
+
const relativePath = path.relative(rootDir, filePath);
|
|
54
|
+
const errorInfo = { path: relativePath, absolutePath: filePath, error: error.message };
|
|
55
|
+
results.errors.push(errorInfo);
|
|
56
|
+
if (spinner) {
|
|
57
|
+
spinner.warn(`Warning: Could not read file ${relativePath}: ${error.message}`);
|
|
58
|
+
} else {
|
|
59
|
+
console.warn(`Warning: Could not read file ${relativePath}: ${error.message}`);
|
|
60
|
+
}
|
|
61
|
+
} finally {
|
|
62
|
+
results.processedFiles++;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
for (let index = 0; index < files.length; index += concurrency) {
|
|
67
|
+
const slice = files.slice(index, index + concurrency);
|
|
68
|
+
await Promise.all(slice.map(processOne));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return results;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
module.exports = {
|
|
75
|
+
aggregateFileContents,
|
|
76
|
+
};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import { isBinaryFile } from './binary.js';
|
|
5
|
+
import type { AggregatedContent, SpinnerInstance } from './types.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Aggregate file contents with bounded concurrency.
|
|
9
|
+
* Returns text files, binary files (with size), and errors.
|
|
10
|
+
* @param files absolute file paths
|
|
11
|
+
* @param rootDir
|
|
12
|
+
* @param spinner Optional spinner instance for progress display
|
|
13
|
+
*/
|
|
14
|
+
export async function aggregateFileContents(
|
|
15
|
+
files: string[],
|
|
16
|
+
rootDir: string,
|
|
17
|
+
spinner: SpinnerInstance = null,
|
|
18
|
+
): Promise<AggregatedContent> {
|
|
19
|
+
const results: AggregatedContent = {
|
|
20
|
+
textFiles: [],
|
|
21
|
+
binaryFiles: [],
|
|
22
|
+
errors: [],
|
|
23
|
+
totalFiles: files.length,
|
|
24
|
+
processedFiles: 0,
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
// Automatic concurrency selection based on CPU count and workload size.
|
|
28
|
+
// - Base on 2x logical CPUs, clamped to [2, 64]
|
|
29
|
+
// - For very small workloads, avoid excessive parallelism
|
|
30
|
+
const cpuCount = os.cpus && Array.isArray(os.cpus()) ? os.cpus().length : os.cpus?.length || 4;
|
|
31
|
+
let concurrency = Math.min(64, Math.max(2, (Number(cpuCount) || 4) * 2));
|
|
32
|
+
if (files.length > 0 && files.length < concurrency) {
|
|
33
|
+
concurrency = Math.max(1, Math.min(concurrency, Math.ceil(files.length / 2)));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async function processOne(filePath: string): Promise<void> {
|
|
37
|
+
try {
|
|
38
|
+
const relativePath = path.relative(rootDir, filePath);
|
|
39
|
+
if (spinner) {
|
|
40
|
+
spinner.text = `Processing: ${relativePath} (${results.processedFiles + 1}/${results.totalFiles})`;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const binary = await isBinaryFile(filePath);
|
|
44
|
+
if (binary) {
|
|
45
|
+
const { size } = await fs.stat(filePath);
|
|
46
|
+
results.binaryFiles.push({ path: relativePath, absolutePath: filePath, size });
|
|
47
|
+
} else {
|
|
48
|
+
const content = await fs.readFile(filePath, 'utf8');
|
|
49
|
+
results.textFiles.push({
|
|
50
|
+
path: relativePath,
|
|
51
|
+
absolutePath: filePath,
|
|
52
|
+
content,
|
|
53
|
+
size: content.length,
|
|
54
|
+
lines: content.split('\n').length,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
} catch (error) {
|
|
58
|
+
const relativePath = path.relative(rootDir, filePath);
|
|
59
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
60
|
+
const errorInfo = { path: relativePath, absolutePath: filePath, error: errorMessage };
|
|
61
|
+
results.errors.push(errorInfo);
|
|
62
|
+
if (spinner) {
|
|
63
|
+
spinner.warn(`Warning: Could not read file ${relativePath}: ${errorMessage}`);
|
|
64
|
+
} else {
|
|
65
|
+
console.warn(`Warning: Could not read file ${relativePath}: ${errorMessage}`);
|
|
66
|
+
}
|
|
67
|
+
} finally {
|
|
68
|
+
results.processedFiles++;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
for (let index = 0; index < files.length; index += concurrency) {
|
|
73
|
+
const slice = files.slice(index, index + concurrency);
|
|
74
|
+
await Promise.all(slice.map(processOne));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return results;
|
|
78
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
const fsp = require('node:fs/promises');
|
|
2
|
+
const path = require('node:path');
|
|
3
|
+
const { Buffer } = require('node:buffer');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Efficiently determine if a file is binary without reading the whole file.
|
|
7
|
+
* - Fast path by extension for common binaries
|
|
8
|
+
* - Otherwise read a small prefix and check for NUL bytes
|
|
9
|
+
* @param {string} filePath
|
|
10
|
+
* @returns {Promise<boolean>}
|
|
11
|
+
*/
|
|
12
|
+
async function isBinaryFile(filePath) {
|
|
13
|
+
try {
|
|
14
|
+
const stats = await fsp.stat(filePath);
|
|
15
|
+
if (stats.isDirectory()) {
|
|
16
|
+
throw new Error('EISDIR: illegal operation on a directory');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const binaryExtensions = new Set([
|
|
20
|
+
'.jpg',
|
|
21
|
+
'.jpeg',
|
|
22
|
+
'.png',
|
|
23
|
+
'.gif',
|
|
24
|
+
'.bmp',
|
|
25
|
+
'.ico',
|
|
26
|
+
'.svg',
|
|
27
|
+
'.pdf',
|
|
28
|
+
'.doc',
|
|
29
|
+
'.docx',
|
|
30
|
+
'.xls',
|
|
31
|
+
'.xlsx',
|
|
32
|
+
'.ppt',
|
|
33
|
+
'.pptx',
|
|
34
|
+
'.zip',
|
|
35
|
+
'.tar',
|
|
36
|
+
'.gz',
|
|
37
|
+
'.rar',
|
|
38
|
+
'.7z',
|
|
39
|
+
'.exe',
|
|
40
|
+
'.dll',
|
|
41
|
+
'.so',
|
|
42
|
+
'.dylib',
|
|
43
|
+
'.mp3',
|
|
44
|
+
'.mp4',
|
|
45
|
+
'.avi',
|
|
46
|
+
'.mov',
|
|
47
|
+
'.wav',
|
|
48
|
+
'.ttf',
|
|
49
|
+
'.otf',
|
|
50
|
+
'.woff',
|
|
51
|
+
'.woff2',
|
|
52
|
+
'.bin',
|
|
53
|
+
'.dat',
|
|
54
|
+
'.db',
|
|
55
|
+
'.sqlite',
|
|
56
|
+
]);
|
|
57
|
+
|
|
58
|
+
const extension = path.extname(filePath).toLowerCase();
|
|
59
|
+
if (binaryExtensions.has(extension)) return true;
|
|
60
|
+
if (stats.size === 0) return false;
|
|
61
|
+
|
|
62
|
+
const sampleSize = Math.min(4096, stats.size);
|
|
63
|
+
const fd = await fsp.open(filePath, 'r');
|
|
64
|
+
try {
|
|
65
|
+
const buffer = Buffer.allocUnsafe(sampleSize);
|
|
66
|
+
const { bytesRead } = await fd.read(buffer, 0, sampleSize, 0);
|
|
67
|
+
const slice = bytesRead === sampleSize ? buffer : buffer.subarray(0, bytesRead);
|
|
68
|
+
return slice.includes(0);
|
|
69
|
+
} finally {
|
|
70
|
+
await fd.close();
|
|
71
|
+
}
|
|
72
|
+
} catch (error) {
|
|
73
|
+
console.warn(`Warning: Could not determine if file is binary: ${filePath} - ${error.message}`);
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
module.exports = {
|
|
79
|
+
isBinaryFile,
|
|
80
|
+
};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
const path = require('node:path');
|
|
2
|
+
const { execFile } = require('node:child_process');
|
|
3
|
+
const { promisify } = require('node:util');
|
|
4
|
+
const { glob } = require('glob');
|
|
5
|
+
const { loadIgnore } = require('./ignoreRules.js');
|
|
6
|
+
|
|
7
|
+
const pExecFile = promisify(execFile);
|
|
8
|
+
|
|
9
|
+
async function isGitRepo(rootDir) {
|
|
10
|
+
try {
|
|
11
|
+
const { stdout } = await pExecFile('git', ['rev-parse', '--is-inside-work-tree'], {
|
|
12
|
+
cwd: rootDir,
|
|
13
|
+
});
|
|
14
|
+
return (
|
|
15
|
+
String(stdout || '')
|
|
16
|
+
.toString()
|
|
17
|
+
.trim() === 'true'
|
|
18
|
+
);
|
|
19
|
+
} catch {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async function gitListFiles(rootDir) {
|
|
25
|
+
try {
|
|
26
|
+
const { stdout } = await pExecFile('git', ['ls-files', '-co', '--exclude-standard'], {
|
|
27
|
+
cwd: rootDir,
|
|
28
|
+
});
|
|
29
|
+
return String(stdout || '')
|
|
30
|
+
.split(/\r?\n/)
|
|
31
|
+
.map((s) => s.trim())
|
|
32
|
+
.filter(Boolean);
|
|
33
|
+
} catch {
|
|
34
|
+
return [];
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Discover files under rootDir.
|
|
40
|
+
* - Prefer git ls-files when available for speed/correctness
|
|
41
|
+
* - Fallback to glob and apply unified ignore rules
|
|
42
|
+
* @param {string} rootDir
|
|
43
|
+
* @param {object} [options]
|
|
44
|
+
* @param {boolean} [options.preferGit=true]
|
|
45
|
+
* @returns {Promise<string[]>} absolute file paths
|
|
46
|
+
*/
|
|
47
|
+
async function discoverFiles(rootDir, options = {}) {
|
|
48
|
+
const { preferGit = true } = options;
|
|
49
|
+
const { filter } = await loadIgnore(rootDir);
|
|
50
|
+
|
|
51
|
+
// Try git first
|
|
52
|
+
if (preferGit && (await isGitRepo(rootDir))) {
|
|
53
|
+
const relFiles = await gitListFiles(rootDir);
|
|
54
|
+
const filteredRel = relFiles.filter((p) => filter(p));
|
|
55
|
+
return filteredRel.map((p) => path.resolve(rootDir, p));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Glob fallback
|
|
59
|
+
const globbed = await glob('**/*', {
|
|
60
|
+
cwd: rootDir,
|
|
61
|
+
nodir: true,
|
|
62
|
+
dot: true,
|
|
63
|
+
follow: false,
|
|
64
|
+
});
|
|
65
|
+
const filteredRel = globbed.filter((p) => filter(p));
|
|
66
|
+
return filteredRel.map((p) => path.resolve(rootDir, p));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
module.exports = {
|
|
70
|
+
discoverFiles,
|
|
71
|
+
};
|