@zeyue0329/xiaoma-cli 1.0.8 → 1.0.9
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/CHANGELOG.md +686 -0
- package/LICENSE +6 -1
- package/README.md +173 -460
- package/common/tasks/create-doc.md +3 -1
- package/common/tasks/execute-checklist.md +2 -7
- package/common/utils/bmad-doc-template.md +7 -5
- package/common/utils/workflow-management.md +2 -0
- package/dist/agents/analyst.txt +1143 -1118
- package/dist/agents/architect.txt +1555 -1531
- package/dist/agents/dev.txt +170 -22
- package/dist/agents/pm.txt +1103 -1106
- package/dist/agents/po.txt +329 -334
- package/dist/agents/qa.txt +1773 -154
- package/dist/agents/sm.txt +101 -102
- package/dist/agents/ux-expert.txt +93 -91
- package/dist/agents/xiaoma-master.txt +745 -673
- package/dist/agents/xiaoma-orchestrator.txt +107 -77
- package/dist/expansion-packs/bmad-2d-phaser-game-dev/agents/game-designer.txt +2386 -0
- package/dist/expansion-packs/bmad-2d-phaser-game-dev/agents/game-developer.txt +1627 -0
- package/dist/expansion-packs/bmad-2d-phaser-game-dev/agents/game-sm.txt +822 -0
- package/dist/expansion-packs/bmad-2d-phaser-game-dev/teams/phaser-2d-nodejs-game-team.txt +11008 -0
- package/dist/expansion-packs/bmad-2d-unity-game-dev/agents/game-architect.txt +4031 -0
- package/dist/expansion-packs/bmad-2d-unity-game-dev/agents/game-designer.txt +3717 -0
- package/dist/expansion-packs/bmad-2d-unity-game-dev/agents/game-developer.txt +456 -0
- package/dist/expansion-packs/bmad-2d-unity-game-dev/agents/game-sm.txt +982 -0
- package/dist/expansion-packs/bmad-2d-unity-game-dev/teams/unity-2d-game-team.txt +15450 -0
- package/dist/expansion-packs/bmad-creative-writing/agents/beta-reader.txt +921 -0
- package/dist/expansion-packs/bmad-creative-writing/agents/book-critic.txt +81 -0
- package/dist/expansion-packs/bmad-creative-writing/agents/character-psychologist.txt +886 -0
- package/dist/expansion-packs/bmad-creative-writing/agents/cover-designer.txt +85 -0
- package/dist/expansion-packs/bmad-creative-writing/agents/dialog-specialist.txt +903 -0
- package/dist/expansion-packs/bmad-creative-writing/agents/editor.txt +837 -0
- package/dist/expansion-packs/bmad-creative-writing/agents/genre-specialist.txt +989 -0
- package/dist/expansion-packs/bmad-creative-writing/agents/narrative-designer.txt +888 -0
- package/dist/expansion-packs/bmad-creative-writing/agents/plot-architect.txt +1173 -0
- package/dist/expansion-packs/bmad-creative-writing/agents/world-builder.txt +914 -0
- package/dist/expansion-packs/bmad-creative-writing/teams/agent-team.txt +6511 -0
- package/dist/expansion-packs/bmad-infrastructure-devops/agents/infra-devops-platform.txt +2087 -0
- package/dist/teams/team-all.txt +5710 -3857
- package/dist/teams/team-fullstack.txt +3242 -3157
- package/dist/teams/team-ide-minimal.txt +2330 -534
- package/dist/teams/team-no-ui.txt +2935 -2857
- package/docs/GUIDING-PRINCIPLES.md +91 -0
- package/docs/core-architecture.md +219 -0
- package/docs/enhanced-ide-development-workflow.md +248 -0
- package/docs/expansion-packs.md +200 -0
- package/docs/how-to-contribute-with-pull-requests.md +158 -0
- package/docs/user-guide.md +530 -0
- package/docs/versioning-and-releases.md +155 -0
- package/docs/versions.md +48 -0
- package/docs/working-in-the-brownfield.md +597 -0
- package/expansion-packs/bmad-2d-phaser-game-dev/agent-teams/phaser-2d-nodejs-game-team.yaml +14 -0
- package/expansion-packs/bmad-2d-phaser-game-dev/agents/game-designer.md +73 -0
- package/expansion-packs/bmad-2d-phaser-game-dev/agents/game-developer.md +80 -0
- package/expansion-packs/bmad-2d-phaser-game-dev/agents/game-sm.md +66 -0
- package/expansion-packs/bmad-2d-phaser-game-dev/checklists/game-design-checklist.md +203 -0
- package/expansion-packs/bmad-2d-phaser-game-dev/checklists/game-story-dod-checklist.md +162 -0
- package/expansion-packs/bmad-2d-phaser-game-dev/config.yaml +9 -0
- package/expansion-packs/bmad-2d-phaser-game-dev/data/bmad-kb.md +252 -0
- package/expansion-packs/bmad-2d-phaser-game-dev/data/development-guidelines.md +649 -0
- package/expansion-packs/bmad-2d-phaser-game-dev/tasks/advanced-elicitation.md +112 -0
- package/expansion-packs/bmad-2d-phaser-game-dev/tasks/create-game-story.md +218 -0
- package/expansion-packs/bmad-2d-phaser-game-dev/tasks/game-design-brainstorming.md +292 -0
- package/expansion-packs/bmad-2d-phaser-game-dev/templates/game-architecture-tmpl.yaml +614 -0
- package/expansion-packs/bmad-2d-phaser-game-dev/templates/game-brief-tmpl.yaml +357 -0
- package/expansion-packs/bmad-2d-phaser-game-dev/templates/game-design-doc-tmpl.yaml +344 -0
- package/expansion-packs/bmad-2d-phaser-game-dev/templates/game-story-tmpl.yaml +254 -0
- package/expansion-packs/bmad-2d-phaser-game-dev/templates/level-design-doc-tmpl.yaml +485 -0
- package/expansion-packs/bmad-2d-phaser-game-dev/workflows/game-dev-greenfield.yaml +184 -0
- package/expansion-packs/bmad-2d-phaser-game-dev/workflows/game-prototype.yaml +176 -0
- package/expansion-packs/bmad-2d-unity-game-dev/agent-teams/unity-2d-game-team.yaml +15 -0
- package/expansion-packs/bmad-2d-unity-game-dev/agents/game-architect.md +82 -0
- package/expansion-packs/bmad-2d-unity-game-dev/agents/game-designer.md +79 -0
- package/expansion-packs/bmad-2d-unity-game-dev/agents/game-developer.md +80 -0
- package/expansion-packs/bmad-2d-unity-game-dev/agents/game-sm.md +67 -0
- package/expansion-packs/bmad-2d-unity-game-dev/checklists/game-architect-checklist.md +393 -0
- package/expansion-packs/bmad-2d-unity-game-dev/checklists/game-change-checklist.md +205 -0
- package/expansion-packs/bmad-2d-unity-game-dev/checklists/game-design-checklist.md +203 -0
- package/expansion-packs/bmad-2d-unity-game-dev/checklists/game-story-dod-checklist.md +126 -0
- package/expansion-packs/bmad-2d-unity-game-dev/config.yaml +7 -0
- package/expansion-packs/bmad-2d-unity-game-dev/data/bmad-kb.md +771 -0
- package/expansion-packs/bmad-2d-unity-game-dev/data/development-guidelines.md +588 -0
- package/expansion-packs/bmad-2d-unity-game-dev/tasks/advanced-elicitation.md +112 -0
- package/expansion-packs/bmad-2d-unity-game-dev/tasks/correct-course-game.md +143 -0
- package/expansion-packs/bmad-2d-unity-game-dev/tasks/create-game-story.md +186 -0
- package/expansion-packs/bmad-2d-unity-game-dev/tasks/game-design-brainstorming.md +292 -0
- package/expansion-packs/bmad-2d-unity-game-dev/tasks/validate-game-story.md +202 -0
- package/expansion-packs/bmad-2d-unity-game-dev/templates/game-architecture-tmpl.yaml +1031 -0
- package/expansion-packs/bmad-2d-unity-game-dev/templates/game-brief-tmpl.yaml +357 -0
- package/expansion-packs/bmad-2d-unity-game-dev/templates/game-design-doc-tmpl.yaml +706 -0
- package/expansion-packs/bmad-2d-unity-game-dev/templates/game-story-tmpl.yaml +257 -0
- package/expansion-packs/bmad-2d-unity-game-dev/templates/level-design-doc-tmpl.yaml +485 -0
- package/expansion-packs/bmad-2d-unity-game-dev/workflows/game-dev-greenfield.yaml +184 -0
- package/expansion-packs/bmad-2d-unity-game-dev/workflows/game-prototype.yaml +176 -0
- package/expansion-packs/bmad-creative-writing/README.md +146 -0
- package/expansion-packs/bmad-creative-writing/agent-teams/agent-team.yaml +20 -0
- package/expansion-packs/bmad-creative-writing/agents/beta-reader.md +94 -0
- package/expansion-packs/bmad-creative-writing/agents/book-critic.md +40 -0
- package/expansion-packs/bmad-creative-writing/agents/character-psychologist.md +93 -0
- package/expansion-packs/bmad-creative-writing/agents/cover-designer.md +46 -0
- package/expansion-packs/bmad-creative-writing/agents/dialog-specialist.md +92 -0
- package/expansion-packs/bmad-creative-writing/agents/editor.md +93 -0
- package/expansion-packs/bmad-creative-writing/agents/genre-specialist.md +95 -0
- package/expansion-packs/bmad-creative-writing/agents/narrative-designer.md +93 -0
- package/expansion-packs/bmad-creative-writing/agents/plot-architect.md +95 -0
- package/expansion-packs/bmad-creative-writing/agents/world-builder.md +94 -0
- package/expansion-packs/bmad-creative-writing/checklists/beta-feedback-closure-checklist.md +23 -0
- package/expansion-packs/bmad-creative-writing/checklists/character-consistency-checklist.md +23 -0
- package/expansion-packs/bmad-creative-writing/checklists/comedic-timing-checklist.md +23 -0
- package/expansion-packs/bmad-creative-writing/checklists/cyberpunk-aesthetic-checklist.md +23 -0
- package/expansion-packs/bmad-creative-writing/checklists/ebook-formatting-checklist.md +21 -0
- package/expansion-packs/bmad-creative-writing/checklists/epic-poetry-meter-checklist.md +23 -0
- package/expansion-packs/bmad-creative-writing/checklists/fantasy-magic-system-checklist.md +23 -0
- package/expansion-packs/bmad-creative-writing/checklists/foreshadowing-payoff-checklist.md +22 -0
- package/expansion-packs/bmad-creative-writing/checklists/genre-tropes-checklist.md +22 -0
- package/expansion-packs/bmad-creative-writing/checklists/historical-accuracy-checklist.md +23 -0
- package/expansion-packs/bmad-creative-writing/checklists/horror-suspense-checklist.md +23 -0
- package/expansion-packs/bmad-creative-writing/checklists/kdp-cover-ready-checklist.md +25 -0
- package/expansion-packs/bmad-creative-writing/checklists/line-edit-quality-checklist.md +23 -0
- package/expansion-packs/bmad-creative-writing/checklists/marketing-copy-checklist.md +23 -0
- package/expansion-packs/bmad-creative-writing/checklists/mystery-clue-trail-checklist.md +23 -0
- package/expansion-packs/bmad-creative-writing/checklists/orbital-mechanics-checklist.md +23 -0
- package/expansion-packs/bmad-creative-writing/checklists/plot-structure-checklist.md +59 -0
- package/expansion-packs/bmad-creative-writing/checklists/publication-readiness-checklist.md +23 -0
- package/expansion-packs/bmad-creative-writing/checklists/romance-emotional-beats-checklist.md +23 -0
- package/expansion-packs/bmad-creative-writing/checklists/scene-quality-checklist.md +23 -0
- package/expansion-packs/bmad-creative-writing/checklists/scifi-technology-plausibility-checklist.md +22 -0
- package/expansion-packs/bmad-creative-writing/checklists/sensitivity-representation-checklist.md +23 -0
- package/expansion-packs/bmad-creative-writing/checklists/steampunk-gadget-checklist.md +23 -0
- package/expansion-packs/bmad-creative-writing/checklists/thriller-pacing-stakes-checklist.md +23 -0
- package/expansion-packs/bmad-creative-writing/checklists/timeline-continuity-checklist.md +23 -0
- package/expansion-packs/bmad-creative-writing/checklists/world-building-continuity-checklist.md +23 -0
- package/expansion-packs/bmad-creative-writing/checklists/ya-appropriateness-checklist.md +23 -0
- package/expansion-packs/bmad-creative-writing/config.yaml +12 -0
- package/expansion-packs/bmad-creative-writing/data/bmad-kb.md +209 -0
- package/expansion-packs/bmad-creative-writing/data/story-structures.md +67 -0
- package/expansion-packs/bmad-creative-writing/docs/brief.md +212 -0
- package/expansion-packs/bmad-creative-writing/tasks/advanced-elicitation.md +119 -0
- package/expansion-packs/bmad-creative-writing/tasks/analyze-reader-feedback.md +23 -0
- package/expansion-packs/bmad-creative-writing/tasks/analyze-story-structure.md +67 -0
- package/expansion-packs/bmad-creative-writing/tasks/assemble-kdp-package.md +29 -0
- package/expansion-packs/bmad-creative-writing/tasks/brainstorm-premise.md +23 -0
- package/expansion-packs/bmad-creative-writing/tasks/build-world.md +24 -0
- package/expansion-packs/bmad-creative-writing/tasks/character-depth-pass.md +22 -0
- package/expansion-packs/bmad-creative-writing/tasks/create-doc.md +103 -0
- package/expansion-packs/bmad-creative-writing/tasks/create-draft-section.md +26 -0
- package/expansion-packs/bmad-creative-writing/tasks/critical-review.md +26 -0
- package/expansion-packs/bmad-creative-writing/tasks/develop-character.md +24 -0
- package/expansion-packs/bmad-creative-writing/tasks/execute-checklist.md +88 -0
- package/expansion-packs/bmad-creative-writing/tasks/expand-premise.md +23 -0
- package/expansion-packs/bmad-creative-writing/tasks/expand-synopsis.md +23 -0
- package/expansion-packs/bmad-creative-writing/tasks/final-polish.md +23 -0
- package/expansion-packs/bmad-creative-writing/tasks/generate-cover-brief.md +25 -0
- package/expansion-packs/bmad-creative-writing/tasks/generate-cover-prompts.md +26 -0
- package/expansion-packs/bmad-creative-writing/tasks/generate-scene-list.md +23 -0
- package/expansion-packs/bmad-creative-writing/tasks/incorporate-feedback.md +25 -0
- package/expansion-packs/bmad-creative-writing/tasks/outline-scenes.md +23 -0
- package/expansion-packs/bmad-creative-writing/tasks/provide-feedback.md +24 -0
- package/expansion-packs/bmad-creative-writing/tasks/publish-chapter.md +23 -0
- package/expansion-packs/bmad-creative-writing/tasks/quick-feedback.md +22 -0
- package/expansion-packs/bmad-creative-writing/tasks/select-next-arc.md +23 -0
- package/expansion-packs/bmad-creative-writing/tasks/workshop-dialog.md +64 -0
- package/expansion-packs/bmad-creative-writing/templates/beta-feedback-form.yaml +97 -0
- package/expansion-packs/bmad-creative-writing/templates/chapter-draft-tmpl.yaml +82 -0
- package/expansion-packs/bmad-creative-writing/templates/character-profile-tmpl.yaml +92 -0
- package/expansion-packs/bmad-creative-writing/templates/cover-design-brief-tmpl.yaml +98 -0
- package/expansion-packs/bmad-creative-writing/templates/premise-brief-tmpl.yaml +78 -0
- package/expansion-packs/bmad-creative-writing/templates/scene-list-tmpl.yaml +55 -0
- package/expansion-packs/bmad-creative-writing/templates/story-outline-tmpl.yaml +96 -0
- package/expansion-packs/bmad-creative-writing/templates/world-guide-tmpl.yaml +89 -0
- package/expansion-packs/bmad-creative-writing/workflows/book-cover-design-workflow.md +218 -0
- package/expansion-packs/bmad-creative-writing/workflows/novel-greenfield-workflow.yaml +56 -0
- package/expansion-packs/bmad-creative-writing/workflows/novel-serial-workflow.yaml +50 -0
- package/expansion-packs/bmad-creative-writing/workflows/novel-snowflake-workflow.yaml +69 -0
- package/expansion-packs/bmad-creative-writing/workflows/novel-writing.yaml +91 -0
- package/expansion-packs/bmad-creative-writing/workflows/screenplay-development.yaml +85 -0
- package/expansion-packs/bmad-creative-writing/workflows/series-planning.yaml +78 -0
- package/expansion-packs/bmad-creative-writing/workflows/short-story-creation.yaml +64 -0
- package/expansion-packs/bmad-infrastructure-devops/README.md +147 -0
- package/expansion-packs/bmad-infrastructure-devops/agents/infra-devops-platform.md +73 -0
- package/expansion-packs/bmad-infrastructure-devops/checklists/infrastructure-checklist.md +486 -0
- package/expansion-packs/bmad-infrastructure-devops/config.yaml +10 -0
- package/expansion-packs/bmad-infrastructure-devops/data/bmad-kb.md +307 -0
- package/expansion-packs/bmad-infrastructure-devops/tasks/review-infrastructure.md +161 -0
- package/expansion-packs/bmad-infrastructure-devops/tasks/validate-infrastructure.md +155 -0
- package/expansion-packs/bmad-infrastructure-devops/templates/infrastructure-architecture-tmpl.yaml +425 -0
- package/expansion-packs/bmad-infrastructure-devops/templates/infrastructure-platform-from-arch-tmpl.yaml +630 -0
- package/implement-fork-friendly-ci.sh +229 -0
- package/package.json +75 -45
- package/prettier.config.mjs +32 -0
- package/test.md +1 -0
- package/tools/builders/web-builder.js +128 -129
- package/tools/bump-all-versions.js +42 -33
- package/tools/bump-expansion-version.js +23 -16
- package/tools/cli.js +15 -15
- package/tools/flattener/aggregate.js +76 -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/ignoreRules.js +176 -0
- package/tools/flattener/main.js +458 -460
- package/tools/flattener/projectRoot.js +206 -0
- package/tools/flattener/prompts.js +44 -0
- package/tools/flattener/stats.helpers.js +395 -0
- package/tools/flattener/stats.js +80 -0
- package/tools/flattener/test-matrix.js +413 -0
- package/tools/flattener/xml.js +88 -0
- package/tools/installer/README.md +1 -1
- package/tools/installer/bin/xiaoma.js +377 -137
- package/tools/installer/config/ide-agent-config.yaml +3 -3
- package/tools/installer/config/install.config.yaml +73 -22
- package/tools/installer/lib/config-loader.js +48 -44
- package/tools/installer/lib/file-manager.js +91 -116
- package/tools/installer/lib/ide-base-setup.js +57 -56
- package/tools/installer/lib/ide-setup.js +816 -407
- package/tools/installer/lib/installer.js +915 -690
- package/tools/installer/lib/memory-profiler.js +54 -53
- package/tools/installer/lib/module-manager.js +19 -15
- package/tools/installer/lib/resource-locator.js +26 -28
- package/tools/installer/package-lock.json +67 -56
- package/tools/installer/package.json +24 -23
- package/tools/lib/dependency-resolver.js +30 -34
- package/tools/lib/yaml-utils.js +7 -7
- package/tools/md-assets/web-agent-startup-instructions.md +1 -1
- package/tools/preview-release-notes.js +66 -0
- package/tools/setup-hooks.sh +37 -0
- package/tools/shared/bannerArt.js +105 -0
- package/tools/sync-installer-version.js +7 -9
- package/tools/sync-version.sh +23 -0
- package/tools/update-expansion-version.js +14 -15
- package/tools/upgraders/v3-to-v4-upgrader.js +208 -299
- package/tools/version-bump.js +41 -26
- package/tools/xiaoma-npx-wrapper.js +11 -11
- package/tools/yaml-format.js +56 -43
- package/xiaoma-core/agent-teams/team-all.yaml +2 -1
- package/xiaoma-core/agent-teams/team-fullstack.yaml +1 -0
- package/xiaoma-core/agent-teams/team-ide-minimal.yaml +1 -0
- package/xiaoma-core/agent-teams/team-no-ui.yaml +1 -0
- package/xiaoma-core/agents/analyst.md +20 -17
- package/xiaoma-core/agents/architect.md +15 -14
- package/xiaoma-core/agents/dev.md +23 -18
- package/xiaoma-core/agents/pm.md +18 -15
- package/xiaoma-core/agents/po.md +13 -10
- package/xiaoma-core/agents/qa.md +46 -24
- package/xiaoma-core/agents/sm.md +11 -8
- package/xiaoma-core/agents/ux-expert.md +10 -7
- package/xiaoma-core/agents/xiaoma-master.md +24 -22
- package/xiaoma-core/agents/xiaoma-orchestrator.md +30 -33
- package/xiaoma-core/checklists/architect-checklist.md +2 -5
- package/xiaoma-core/checklists/change-checklist.md +4 -2
- package/xiaoma-core/checklists/pm-checklist.md +2 -5
- package/xiaoma-core/checklists/po-master-checklist.md +2 -9
- package/xiaoma-core/checklists/story-dod-checklist.md +2 -7
- package/xiaoma-core/checklists/story-draft-checklist.md +2 -3
- package/xiaoma-core/core-config.yaml +4 -1
- package/xiaoma-core/data/{xiaoma-kb.md → bmad-kb.md} +43 -37
- package/xiaoma-core/data/brainstorming-techniques.md +2 -0
- package/xiaoma-core/data/elicitation-methods.md +22 -0
- package/xiaoma-core/data/technical-preferences.md +2 -0
- package/xiaoma-core/data/test-levels-framework.md +148 -0
- package/xiaoma-core/data/test-priorities-matrix.md +174 -0
- package/xiaoma-core/tasks/advanced-elicitation.md +2 -0
- package/xiaoma-core/tasks/apply-qa-fixes.md +150 -0
- package/xiaoma-core/tasks/brownfield-create-epic.md +2 -0
- package/xiaoma-core/tasks/brownfield-create-story.md +2 -0
- package/xiaoma-core/tasks/correct-course.md +2 -0
- package/xiaoma-core/tasks/create-brownfield-story.md +14 -4
- package/xiaoma-core/tasks/create-deep-research-prompt.md +2 -11
- package/xiaoma-core/tasks/create-next-story.md +3 -1
- package/xiaoma-core/tasks/document-project.md +17 -13
- package/xiaoma-core/tasks/facilitate-brainstorming-session.md +5 -3
- package/xiaoma-core/tasks/generate-ai-frontend-prompt.md +2 -0
- package/xiaoma-core/tasks/index-docs.md +2 -6
- package/xiaoma-core/tasks/kb-mode-interaction.md +17 -15
- package/xiaoma-core/tasks/nfr-assess.md +345 -0
- package/xiaoma-core/tasks/qa-gate.md +163 -0
- package/xiaoma-core/tasks/review-story.md +245 -74
- package/xiaoma-core/tasks/risk-profile.md +355 -0
- package/xiaoma-core/tasks/shard-doc.md +2 -2
- package/xiaoma-core/tasks/test-design.md +176 -0
- package/xiaoma-core/tasks/trace-requirements.md +266 -0
- package/xiaoma-core/tasks/validate-next-story.md +2 -0
- package/xiaoma-core/templates/architecture-tmpl.yaml +50 -49
- package/xiaoma-core/templates/brainstorming-output-tmpl.yaml +5 -5
- package/xiaoma-core/templates/brownfield-architecture-tmpl.yaml +32 -31
- package/xiaoma-core/templates/brownfield-prd-tmpl.yaml +14 -13
- package/xiaoma-core/templates/competitor-analysis-tmpl.yaml +20 -6
- package/xiaoma-core/templates/front-end-architecture-tmpl.yaml +22 -9
- package/xiaoma-core/templates/front-end-spec-tmpl.yaml +25 -24
- package/xiaoma-core/templates/fullstack-architecture-tmpl.yaml +123 -104
- package/xiaoma-core/templates/market-research-tmpl.yaml +3 -2
- package/xiaoma-core/templates/prd-tmpl.yaml +10 -9
- package/xiaoma-core/templates/project-brief-tmpl.yaml +5 -4
- package/xiaoma-core/templates/qa-gate-tmpl.yaml +103 -0
- package/xiaoma-core/templates/story-tmpl.yaml +13 -12
- package/xiaoma-core/workflows/brownfield-fullstack.yaml +13 -12
- package/xiaoma-core/workflows/brownfield-service.yaml +5 -4
- package/xiaoma-core/workflows/brownfield-ui.yaml +5 -4
- package/xiaoma-core/workflows/greenfield-fullstack.yaml +7 -6
- package/xiaoma-core/workflows/greenfield-service.yaml +5 -4
- package/xiaoma-core/workflows/greenfield-ui.yaml +6 -5
- package/.releaserc.json +0 -18
- package/.vscode/settings.json +0 -44
- package/XiaoMa-Web/345/244/232/346/231/272/350/203/275/344/275/2230-1/351/241/271/347/233/256/345/274/200/345/217/221/345/256/214/346/225/264/346/214/207/345/215/227.md +0 -977
- package/XiaoMa-Web/347/216/260/346/234/211/351/241/271/347/233/256/351/234/200/346/261/202/345/274/200/345/217/221/345/256/214/346/225/264/346/214/207/345/215/227.md +0 -873
- package/XiaoMa-Web/347/272/257/345/211/215/347/253/257/351/241/271/347/233/256Claude-Code/345/274/200/345/217/221/345/256/214/346/225/264/346/214/207/345/215/227.md +0 -372
- package/XiaoMa-Web/351/241/271/347/233/256/346/200/273/347/273/223/346/212/245/345/221/212.md +0 -310
- package/dist/agents/dev-cn.txt +0 -428
- package/docs/quick-start.md +0 -179
- package/tools/bmad-npx-wrapper.js +0 -39
- package/tools/semantic-release-sync-installer.js +0 -30
- package/xiaoma-core/bmad-core/user-guide.md +0 -0
- package/xiaoma-core/enhanced-ide-development-workflow.md +0 -43
- package/xiaoma-core/user-guide.md +0 -251
- package/xiaoma-core/working-in-the-brownfield.md +0 -364
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const fs = require('fs');
|
|
4
|
-
const path = require('path');
|
|
1
|
+
const fs = require('node:fs');
|
|
2
|
+
const path = require('node:path');
|
|
5
3
|
const yaml = require('js-yaml');
|
|
6
4
|
|
|
7
|
-
const
|
|
8
|
-
const bumpType =
|
|
5
|
+
const arguments_ = process.argv.slice(2);
|
|
6
|
+
const bumpType = arguments_[0] || 'minor'; // default to minor
|
|
9
7
|
|
|
10
8
|
if (!['major', 'minor', 'patch'].includes(bumpType)) {
|
|
11
9
|
console.log('Usage: node bump-all-versions.js [major|minor|patch]');
|
|
@@ -15,22 +13,26 @@ if (!['major', 'minor', 'patch'].includes(bumpType)) {
|
|
|
15
13
|
|
|
16
14
|
function bumpVersion(currentVersion, type) {
|
|
17
15
|
const [major, minor, patch] = currentVersion.split('.').map(Number);
|
|
18
|
-
|
|
16
|
+
|
|
19
17
|
switch (type) {
|
|
20
|
-
case 'major':
|
|
18
|
+
case 'major': {
|
|
21
19
|
return `${major + 1}.0.0`;
|
|
22
|
-
|
|
20
|
+
}
|
|
21
|
+
case 'minor': {
|
|
23
22
|
return `${major}.${minor + 1}.0`;
|
|
24
|
-
|
|
23
|
+
}
|
|
24
|
+
case 'patch': {
|
|
25
25
|
return `${major}.${minor}.${patch + 1}`;
|
|
26
|
-
|
|
26
|
+
}
|
|
27
|
+
default: {
|
|
27
28
|
return currentVersion;
|
|
29
|
+
}
|
|
28
30
|
}
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
async function bumpAllVersions() {
|
|
32
34
|
const updatedItems = [];
|
|
33
|
-
|
|
35
|
+
|
|
34
36
|
// First, bump the core version (package.json)
|
|
35
37
|
const packagePath = path.join(__dirname, '..', 'package.json');
|
|
36
38
|
try {
|
|
@@ -38,69 +40,76 @@ async function bumpAllVersions() {
|
|
|
38
40
|
const packageJson = JSON.parse(packageContent);
|
|
39
41
|
const oldCoreVersion = packageJson.version || '1.0.0';
|
|
40
42
|
const newCoreVersion = bumpVersion(oldCoreVersion, bumpType);
|
|
41
|
-
|
|
43
|
+
|
|
42
44
|
packageJson.version = newCoreVersion;
|
|
43
|
-
|
|
45
|
+
|
|
44
46
|
fs.writeFileSync(packagePath, JSON.stringify(packageJson, null, 2) + '\n');
|
|
45
|
-
|
|
46
|
-
updatedItems.push({
|
|
47
|
+
|
|
48
|
+
updatedItems.push({
|
|
49
|
+
type: 'core',
|
|
50
|
+
name: 'BMad Core',
|
|
51
|
+
oldVersion: oldCoreVersion,
|
|
52
|
+
newVersion: newCoreVersion,
|
|
53
|
+
});
|
|
47
54
|
console.log(`✓ BMad Core (package.json): ${oldCoreVersion} → ${newCoreVersion}`);
|
|
48
55
|
} catch (error) {
|
|
49
56
|
console.error(`✗ Failed to update BMad Core: ${error.message}`);
|
|
50
57
|
}
|
|
51
|
-
|
|
58
|
+
|
|
52
59
|
// Then, bump all expansion packs
|
|
53
60
|
const expansionPacksDir = path.join(__dirname, '..', 'expansion-packs');
|
|
54
|
-
|
|
61
|
+
|
|
55
62
|
try {
|
|
56
63
|
const entries = fs.readdirSync(expansionPacksDir, { withFileTypes: true });
|
|
57
|
-
|
|
64
|
+
|
|
58
65
|
for (const entry of entries) {
|
|
59
66
|
if (entry.isDirectory() && !entry.name.startsWith('.') && entry.name !== 'README.md') {
|
|
60
67
|
const packId = entry.name;
|
|
61
68
|
const configPath = path.join(expansionPacksDir, packId, 'config.yaml');
|
|
62
|
-
|
|
69
|
+
|
|
63
70
|
if (fs.existsSync(configPath)) {
|
|
64
71
|
try {
|
|
65
72
|
const configContent = fs.readFileSync(configPath, 'utf8');
|
|
66
73
|
const config = yaml.load(configContent);
|
|
67
74
|
const oldVersion = config.version || '1.0.0';
|
|
68
75
|
const newVersion = bumpVersion(oldVersion, bumpType);
|
|
69
|
-
|
|
76
|
+
|
|
70
77
|
config.version = newVersion;
|
|
71
|
-
|
|
78
|
+
|
|
72
79
|
const updatedYaml = yaml.dump(config, { indent: 2 });
|
|
73
80
|
fs.writeFileSync(configPath, updatedYaml);
|
|
74
|
-
|
|
81
|
+
|
|
75
82
|
updatedItems.push({ type: 'expansion', name: packId, oldVersion, newVersion });
|
|
76
83
|
console.log(`✓ ${packId}: ${oldVersion} → ${newVersion}`);
|
|
77
|
-
|
|
78
84
|
} catch (error) {
|
|
79
85
|
console.error(`✗ Failed to update ${packId}: ${error.message}`);
|
|
80
86
|
}
|
|
81
87
|
}
|
|
82
88
|
}
|
|
83
89
|
}
|
|
84
|
-
|
|
90
|
+
|
|
85
91
|
if (updatedItems.length > 0) {
|
|
86
|
-
const coreCount = updatedItems.filter(
|
|
87
|
-
const expansionCount = updatedItems.filter(
|
|
88
|
-
|
|
89
|
-
console.log(
|
|
92
|
+
const coreCount = updatedItems.filter((index) => index.type === 'core').length;
|
|
93
|
+
const expansionCount = updatedItems.filter((index) => index.type === 'expansion').length;
|
|
94
|
+
|
|
95
|
+
console.log(
|
|
96
|
+
`\n✓ Successfully bumped ${updatedItems.length} item(s) with ${bumpType} version bump`,
|
|
97
|
+
);
|
|
90
98
|
if (coreCount > 0) console.log(` - ${coreCount} core`);
|
|
91
99
|
if (expansionCount > 0) console.log(` - ${expansionCount} expansion pack(s)`);
|
|
92
|
-
|
|
100
|
+
|
|
93
101
|
console.log('\nNext steps:');
|
|
94
102
|
console.log('1. Test the changes');
|
|
95
|
-
console.log(
|
|
103
|
+
console.log(
|
|
104
|
+
'2. Commit: git add -A && git commit -m "chore: bump all versions (' + bumpType + ')"',
|
|
105
|
+
);
|
|
96
106
|
} else {
|
|
97
107
|
console.log('No items found to update');
|
|
98
108
|
}
|
|
99
|
-
|
|
100
109
|
} catch (error) {
|
|
101
110
|
console.error('Error reading expansion packs directory:', error.message);
|
|
102
111
|
process.exit(1);
|
|
103
112
|
}
|
|
104
113
|
}
|
|
105
114
|
|
|
106
|
-
bumpAllVersions();
|
|
115
|
+
bumpAllVersions();
|
|
@@ -1,17 +1,15 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
1
|
// Load required modules
|
|
4
|
-
const fs = require('fs');
|
|
5
|
-
const path = require('path');
|
|
2
|
+
const fs = require('node:fs');
|
|
3
|
+
const path = require('node:path');
|
|
6
4
|
const yaml = require('js-yaml');
|
|
7
5
|
|
|
8
6
|
// Parse CLI arguments
|
|
9
|
-
const
|
|
10
|
-
const packId =
|
|
11
|
-
const bumpType =
|
|
7
|
+
const arguments_ = process.argv.slice(2);
|
|
8
|
+
const packId = arguments_[0];
|
|
9
|
+
const bumpType = arguments_[1] || 'minor';
|
|
12
10
|
|
|
13
11
|
// Validate arguments
|
|
14
|
-
if (!packId ||
|
|
12
|
+
if (!packId || arguments_.length > 2) {
|
|
15
13
|
console.log('Usage: node bump-expansion-version.js <expansion-pack-id> [major|minor|patch]');
|
|
16
14
|
console.log('Default: minor');
|
|
17
15
|
console.log('Example: node bump-expansion-version.js bmad-creator-tools patch');
|
|
@@ -28,10 +26,18 @@ function bumpVersion(currentVersion, type) {
|
|
|
28
26
|
const [major, minor, patch] = currentVersion.split('.').map(Number);
|
|
29
27
|
|
|
30
28
|
switch (type) {
|
|
31
|
-
case 'major':
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
29
|
+
case 'major': {
|
|
30
|
+
return `${major + 1}.0.0`;
|
|
31
|
+
}
|
|
32
|
+
case 'minor': {
|
|
33
|
+
return `${major}.${minor + 1}.0`;
|
|
34
|
+
}
|
|
35
|
+
case 'patch': {
|
|
36
|
+
return `${major}.${minor}.${patch + 1}`;
|
|
37
|
+
}
|
|
38
|
+
default: {
|
|
39
|
+
return currentVersion;
|
|
40
|
+
}
|
|
35
41
|
}
|
|
36
42
|
}
|
|
37
43
|
|
|
@@ -47,11 +53,11 @@ async function updateVersion() {
|
|
|
47
53
|
const packsDir = path.join(__dirname, '..', 'expansion-packs');
|
|
48
54
|
const entries = fs.readdirSync(packsDir, { withFileTypes: true });
|
|
49
55
|
|
|
50
|
-
|
|
56
|
+
for (const entry of entries) {
|
|
51
57
|
if (entry.isDirectory() && !entry.name.startsWith('.')) {
|
|
52
58
|
console.log(` - ${entry.name}`);
|
|
53
59
|
}
|
|
54
|
-
}
|
|
60
|
+
}
|
|
55
61
|
|
|
56
62
|
process.exit(1);
|
|
57
63
|
}
|
|
@@ -72,8 +78,9 @@ async function updateVersion() {
|
|
|
72
78
|
console.log(`\n✓ Successfully bumped ${packId} with ${bumpType} version bump`);
|
|
73
79
|
console.log('\nNext steps:');
|
|
74
80
|
console.log(`1. Test the changes`);
|
|
75
|
-
console.log(
|
|
76
|
-
|
|
81
|
+
console.log(
|
|
82
|
+
`2. Commit: git add -A && git commit -m "chore: bump ${packId} version (${bumpType})"`,
|
|
83
|
+
);
|
|
77
84
|
} catch (error) {
|
|
78
85
|
console.error('Error updating version:', error.message);
|
|
79
86
|
process.exit(1);
|
package/tools/cli.js
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
1
|
const { Command } = require('commander');
|
|
4
2
|
const WebBuilder = require('./builders/web-builder');
|
|
5
3
|
const V3ToV4Upgrader = require('./upgraders/v3-to-v4-upgrader');
|
|
6
4
|
const IdeSetup = require('./installer/lib/ide-setup');
|
|
7
|
-
const path = require('path');
|
|
5
|
+
const path = require('node:path');
|
|
8
6
|
|
|
9
7
|
const program = new Command();
|
|
10
8
|
|
|
11
9
|
program
|
|
12
|
-
.name('
|
|
13
|
-
.description('
|
|
10
|
+
.name('bmad-build')
|
|
11
|
+
.description('BMAD-METHOD™ build tool for creating web bundles')
|
|
14
12
|
.version('4.0.0');
|
|
15
13
|
|
|
16
14
|
program
|
|
@@ -23,7 +21,7 @@ program
|
|
|
23
21
|
.option('--no-clean', 'Skip cleaning output directories')
|
|
24
22
|
.action(async (options) => {
|
|
25
23
|
const builder = new WebBuilder({
|
|
26
|
-
rootDir: process.cwd()
|
|
24
|
+
rootDir: process.cwd(),
|
|
27
25
|
});
|
|
28
26
|
|
|
29
27
|
try {
|
|
@@ -66,7 +64,7 @@ program
|
|
|
66
64
|
.option('--no-clean', 'Skip cleaning output directories')
|
|
67
65
|
.action(async (options) => {
|
|
68
66
|
const builder = new WebBuilder({
|
|
69
|
-
rootDir: process.cwd()
|
|
67
|
+
rootDir: process.cwd(),
|
|
70
68
|
});
|
|
71
69
|
|
|
72
70
|
try {
|
|
@@ -92,7 +90,8 @@ program
|
|
|
92
90
|
const builder = new WebBuilder({ rootDir: process.cwd() });
|
|
93
91
|
const agents = await builder.resolver.listAgents();
|
|
94
92
|
console.log('Available agents:');
|
|
95
|
-
|
|
93
|
+
for (const agent of agents) console.log(` - ${agent}`);
|
|
94
|
+
process.exit(0);
|
|
96
95
|
});
|
|
97
96
|
|
|
98
97
|
program
|
|
@@ -102,7 +101,8 @@ program
|
|
|
102
101
|
const builder = new WebBuilder({ rootDir: process.cwd() });
|
|
103
102
|
const expansions = await builder.listExpansionPacks();
|
|
104
103
|
console.log('Available expansion packs:');
|
|
105
|
-
|
|
104
|
+
for (const expansion of expansions) console.log(` - ${expansion}`);
|
|
105
|
+
process.exit(0);
|
|
106
106
|
});
|
|
107
107
|
|
|
108
108
|
program
|
|
@@ -114,19 +114,19 @@ program
|
|
|
114
114
|
// Validate by attempting to build all agents and teams
|
|
115
115
|
const agents = await builder.resolver.listAgents();
|
|
116
116
|
const teams = await builder.resolver.listTeams();
|
|
117
|
-
|
|
117
|
+
|
|
118
118
|
console.log('Validating agents...');
|
|
119
119
|
for (const agent of agents) {
|
|
120
120
|
await builder.resolver.resolveAgentDependencies(agent);
|
|
121
121
|
console.log(` ✓ ${agent}`);
|
|
122
122
|
}
|
|
123
|
-
|
|
123
|
+
|
|
124
124
|
console.log('\nValidating teams...');
|
|
125
125
|
for (const team of teams) {
|
|
126
126
|
await builder.resolver.resolveTeamDependencies(team);
|
|
127
127
|
console.log(` ✓ ${team}`);
|
|
128
128
|
}
|
|
129
|
-
|
|
129
|
+
|
|
130
130
|
console.log('\nAll configurations are valid!');
|
|
131
131
|
} catch (error) {
|
|
132
132
|
console.error('Validation failed:', error.message);
|
|
@@ -136,7 +136,7 @@ program
|
|
|
136
136
|
|
|
137
137
|
program
|
|
138
138
|
.command('upgrade')
|
|
139
|
-
.description('Upgrade a
|
|
139
|
+
.description('Upgrade a BMAD-METHOD™ V3 project to V4')
|
|
140
140
|
.option('-p, --project <path>', 'Path to V3 project (defaults to current directory)')
|
|
141
141
|
.option('--dry-run', 'Show what would be changed without making changes')
|
|
142
142
|
.option('--no-backup', 'Skip creating backup (not recommended)')
|
|
@@ -145,8 +145,8 @@ program
|
|
|
145
145
|
await upgrader.upgrade({
|
|
146
146
|
projectPath: options.project,
|
|
147
147
|
dryRun: options.dryRun,
|
|
148
|
-
backup: options.backup
|
|
148
|
+
backup: options.backup,
|
|
149
149
|
});
|
|
150
150
|
});
|
|
151
151
|
|
|
152
|
-
program.parse();
|
|
152
|
+
program.parse();
|
|
@@ -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,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
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
const path = require('node:path');
|
|
2
|
+
const discovery = require('./discovery.js');
|
|
3
|
+
const ignoreRules = require('./ignoreRules.js');
|
|
4
|
+
const { isBinaryFile } = require('./binary.js');
|
|
5
|
+
const { aggregateFileContents } = require('./aggregate.js');
|
|
6
|
+
|
|
7
|
+
// Backward-compatible signature; delegate to central loader
|
|
8
|
+
async function parseGitignore(gitignorePath) {
|
|
9
|
+
return await ignoreRules.parseGitignore(gitignorePath);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async function discoverFiles(rootDir) {
|
|
13
|
+
try {
|
|
14
|
+
// Delegate to discovery module which respects .gitignore and defaults
|
|
15
|
+
return await discovery.discoverFiles(rootDir, { preferGit: true });
|
|
16
|
+
} catch (error) {
|
|
17
|
+
console.error('Error discovering files:', error.message);
|
|
18
|
+
return [];
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async function filterFiles(files, rootDir) {
|
|
23
|
+
const { filter } = await ignoreRules.loadIgnore(rootDir);
|
|
24
|
+
const relativeFiles = files.map((f) => path.relative(rootDir, f));
|
|
25
|
+
const filteredRelative = relativeFiles.filter((p) => filter(p));
|
|
26
|
+
return filteredRelative.map((p) => path.resolve(rootDir, p));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
module.exports = {
|
|
30
|
+
parseGitignore,
|
|
31
|
+
discoverFiles,
|
|
32
|
+
isBinaryFile,
|
|
33
|
+
aggregateFileContents,
|
|
34
|
+
filterFiles,
|
|
35
|
+
};
|