bmad-studio 0.1.0 → 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/README.md +6 -0
- package/package.json +27 -2
- package/packages/client/dist/assets/index-CWL4J-eZ.css +1 -0
- package/packages/client/dist/assets/index-DBqsFqD5.js +535 -0
- package/packages/client/dist/assets/inter-tight-cyrillic-400-normal-DPRou3KO.woff +0 -0
- package/packages/client/dist/assets/inter-tight-cyrillic-400-normal-G7BuwYWK.woff2 +0 -0
- package/packages/client/dist/assets/inter-tight-cyrillic-700-normal-DDZiLR3d.woff +0 -0
- package/packages/client/dist/assets/inter-tight-cyrillic-700-normal-DtWWjp29.woff2 +0 -0
- package/packages/client/dist/assets/inter-tight-cyrillic-800-normal-CC_RRmyd.woff2 +0 -0
- package/packages/client/dist/assets/inter-tight-cyrillic-800-normal-ChWbk4mt.woff +0 -0
- package/packages/client/dist/assets/inter-tight-cyrillic-ext-400-normal-CKO3cWyd.woff2 +0 -0
- package/packages/client/dist/assets/inter-tight-cyrillic-ext-400-normal-DiHHcP5k.woff +0 -0
- package/packages/client/dist/assets/inter-tight-cyrillic-ext-700-normal-BFcoPt71.woff +0 -0
- package/packages/client/dist/assets/inter-tight-cyrillic-ext-700-normal-D_7NT8eF.woff2 +0 -0
- package/packages/client/dist/assets/inter-tight-cyrillic-ext-800-normal-CzCOBUhR.woff2 +0 -0
- package/packages/client/dist/assets/inter-tight-cyrillic-ext-800-normal-WowoGRZX.woff +0 -0
- package/packages/client/dist/assets/inter-tight-greek-400-normal-BLLSFQTx.woff +0 -0
- package/packages/client/dist/assets/inter-tight-greek-400-normal-Br_GQm5W.woff2 +0 -0
- package/packages/client/dist/assets/inter-tight-greek-700-normal-DU8XoIeX.woff +0 -0
- package/packages/client/dist/assets/inter-tight-greek-700-normal-RgALSHS4.woff2 +0 -0
- package/packages/client/dist/assets/inter-tight-greek-800-normal-CxHmUlv4.woff +0 -0
- package/packages/client/dist/assets/inter-tight-greek-800-normal-X9eW6L67.woff2 +0 -0
- package/packages/client/dist/assets/inter-tight-greek-ext-400-normal-C3GMUg_S.woff2 +0 -0
- package/packages/client/dist/assets/inter-tight-greek-ext-400-normal-DMqR5RoS.woff +0 -0
- package/packages/client/dist/assets/inter-tight-greek-ext-700-normal-D0RkHJEE.woff2 +0 -0
- package/packages/client/dist/assets/inter-tight-greek-ext-700-normal-mW3dmpoD.woff +0 -0
- package/packages/client/dist/assets/inter-tight-greek-ext-800-normal-DNWjXg9N.woff2 +0 -0
- package/packages/client/dist/assets/inter-tight-greek-ext-800-normal-DfP-QoiQ.woff +0 -0
- package/packages/client/dist/assets/inter-tight-latin-400-normal-BLrFJfvD.woff +0 -0
- package/packages/client/dist/assets/inter-tight-latin-400-normal-iW8qmuJY.woff2 +0 -0
- package/packages/client/dist/assets/inter-tight-latin-700-normal-BZKd_v_8.woff2 +0 -0
- package/packages/client/dist/assets/inter-tight-latin-700-normal-DvYAVZQd.woff +0 -0
- package/packages/client/dist/assets/inter-tight-latin-800-normal-CRGCHRPv.woff2 +0 -0
- package/packages/client/dist/assets/inter-tight-latin-800-normal-D2te1T7i.woff +0 -0
- package/packages/client/dist/assets/inter-tight-latin-ext-400-normal-BQQeeQrv.woff +0 -0
- package/packages/client/dist/assets/inter-tight-latin-ext-400-normal-DN7wyBvd.woff2 +0 -0
- package/packages/client/dist/assets/inter-tight-latin-ext-700-normal-BpKPOkj3.woff2 +0 -0
- package/packages/client/dist/assets/inter-tight-latin-ext-700-normal-CrlzIQ10.woff +0 -0
- package/packages/client/dist/assets/inter-tight-latin-ext-800-normal-A39zhqaD.woff +0 -0
- package/packages/client/dist/assets/inter-tight-latin-ext-800-normal-DfKN99cy.woff2 +0 -0
- package/packages/client/dist/assets/inter-tight-vietnamese-400-normal-CqzIqjuX.woff2 +0 -0
- package/packages/client/dist/assets/inter-tight-vietnamese-400-normal-kSDs3Vd1.woff +0 -0
- package/packages/client/dist/assets/inter-tight-vietnamese-700-normal-Cn_DV52A.woff2 +0 -0
- package/packages/client/dist/assets/inter-tight-vietnamese-700-normal-DwHBAXeT.woff +0 -0
- package/packages/client/dist/assets/inter-tight-vietnamese-800-normal-CbYrLkxo.woff +0 -0
- package/packages/client/dist/assets/inter-tight-vietnamese-800-normal-OJoDhpMd.woff2 +0 -0
- package/packages/client/dist/index.html +13 -0
- package/packages/server/dist/app.d.ts +12 -0
- package/packages/server/dist/app.d.ts.map +1 -0
- package/packages/server/dist/app.js +94 -0
- package/packages/server/dist/app.js.map +1 -0
- package/packages/server/dist/app.test.d.ts +2 -0
- package/packages/server/dist/app.test.d.ts.map +1 -0
- package/packages/server/dist/app.test.js +72 -0
- package/packages/server/dist/app.test.js.map +1 -0
- package/packages/server/dist/core/errors.d.ts +29 -0
- package/packages/server/dist/core/errors.d.ts.map +1 -0
- package/packages/server/dist/core/errors.js +49 -0
- package/packages/server/dist/core/errors.js.map +1 -0
- package/packages/server/dist/core/errors.test.d.ts +2 -0
- package/packages/server/dist/core/errors.test.d.ts.map +1 -0
- package/packages/server/dist/core/errors.test.js +37 -0
- package/packages/server/dist/core/errors.test.js.map +1 -0
- package/packages/server/dist/core/file-store.d.ts +40 -0
- package/packages/server/dist/core/file-store.d.ts.map +1 -0
- package/packages/server/dist/core/file-store.js +160 -0
- package/packages/server/dist/core/file-store.js.map +1 -0
- package/packages/server/dist/core/file-store.test.d.ts +2 -0
- package/packages/server/dist/core/file-store.test.d.ts.map +1 -0
- package/packages/server/dist/core/file-store.test.js +75 -0
- package/packages/server/dist/core/file-store.test.js.map +1 -0
- package/packages/server/dist/core/ide-skill-generator.d.ts +58 -0
- package/packages/server/dist/core/ide-skill-generator.d.ts.map +1 -0
- package/packages/server/dist/core/ide-skill-generator.js +270 -0
- package/packages/server/dist/core/ide-skill-generator.js.map +1 -0
- package/packages/server/dist/core/ide-skill-generator.test.d.ts +2 -0
- package/packages/server/dist/core/ide-skill-generator.test.d.ts.map +1 -0
- package/packages/server/dist/core/ide-skill-generator.test.js +257 -0
- package/packages/server/dist/core/ide-skill-generator.test.js.map +1 -0
- package/packages/server/dist/core/module-installer.d.ts +165 -0
- package/packages/server/dist/core/module-installer.d.ts.map +1 -0
- package/packages/server/dist/core/module-installer.js +445 -0
- package/packages/server/dist/core/module-installer.js.map +1 -0
- package/packages/server/dist/core/module-installer.test.d.ts +2 -0
- package/packages/server/dist/core/module-installer.test.d.ts.map +1 -0
- package/packages/server/dist/core/module-installer.test.js +509 -0
- package/packages/server/dist/core/module-installer.test.js.map +1 -0
- package/packages/server/dist/core/module-registry.d.ts +5 -0
- package/packages/server/dist/core/module-registry.d.ts.map +1 -0
- package/packages/server/dist/core/module-registry.js +109 -0
- package/packages/server/dist/core/module-registry.js.map +1 -0
- package/packages/server/dist/core/module-registry.test.d.ts +2 -0
- package/packages/server/dist/core/module-registry.test.d.ts.map +1 -0
- package/packages/server/dist/core/module-registry.test.js +280 -0
- package/packages/server/dist/core/module-registry.test.js.map +1 -0
- package/packages/server/dist/core/project-detector.d.ts +14 -0
- package/packages/server/dist/core/project-detector.d.ts.map +1 -0
- package/packages/server/dist/core/project-detector.js +67 -0
- package/packages/server/dist/core/project-detector.js.map +1 -0
- package/packages/server/dist/core/project-detector.test.d.ts +2 -0
- package/packages/server/dist/core/project-detector.test.d.ts.map +1 -0
- package/packages/server/dist/core/project-detector.test.js +73 -0
- package/packages/server/dist/core/project-detector.test.js.map +1 -0
- package/packages/server/dist/core/websocket.d.ts +16 -0
- package/packages/server/dist/core/websocket.d.ts.map +1 -0
- package/packages/server/dist/core/websocket.js +30 -0
- package/packages/server/dist/core/websocket.js.map +1 -0
- package/packages/server/dist/core/websocket.test.d.ts +2 -0
- package/packages/server/dist/core/websocket.test.d.ts.map +1 -0
- package/packages/server/dist/core/websocket.test.js +64 -0
- package/packages/server/dist/core/websocket.test.js.map +1 -0
- package/packages/server/dist/core/write-service.d.ts +32 -0
- package/packages/server/dist/core/write-service.d.ts.map +1 -0
- package/packages/server/dist/core/write-service.js +173 -0
- package/packages/server/dist/core/write-service.js.map +1 -0
- package/packages/server/dist/core/write-service.test.d.ts +2 -0
- package/packages/server/dist/core/write-service.test.d.ts.map +1 -0
- package/packages/server/dist/core/write-service.test.js +156 -0
- package/packages/server/dist/core/write-service.test.js.map +1 -0
- package/packages/server/dist/index.d.ts +2 -0
- package/packages/server/dist/index.d.ts.map +1 -0
- package/packages/server/dist/index.js +133 -0
- package/packages/server/dist/index.js.map +1 -0
- package/packages/server/dist/parsers/agent-parser.d.ts +4 -0
- package/packages/server/dist/parsers/agent-parser.d.ts.map +1 -0
- package/packages/server/dist/parsers/agent-parser.js +88 -0
- package/packages/server/dist/parsers/agent-parser.js.map +1 -0
- package/packages/server/dist/parsers/agent-parser.test.d.ts +2 -0
- package/packages/server/dist/parsers/agent-parser.test.d.ts.map +1 -0
- package/packages/server/dist/parsers/agent-parser.test.js +66 -0
- package/packages/server/dist/parsers/agent-parser.test.js.map +1 -0
- package/packages/server/dist/parsers/config-parser.d.ts +14 -0
- package/packages/server/dist/parsers/config-parser.d.ts.map +1 -0
- package/packages/server/dist/parsers/config-parser.js +39 -0
- package/packages/server/dist/parsers/config-parser.js.map +1 -0
- package/packages/server/dist/parsers/config-parser.test.d.ts +2 -0
- package/packages/server/dist/parsers/config-parser.test.d.ts.map +1 -0
- package/packages/server/dist/parsers/config-parser.test.js +56 -0
- package/packages/server/dist/parsers/config-parser.test.js.map +1 -0
- package/packages/server/dist/parsers/csv-parser.d.ts +4 -0
- package/packages/server/dist/parsers/csv-parser.d.ts.map +1 -0
- package/packages/server/dist/parsers/csv-parser.js +50 -0
- package/packages/server/dist/parsers/csv-parser.js.map +1 -0
- package/packages/server/dist/parsers/csv-parser.test.d.ts +2 -0
- package/packages/server/dist/parsers/csv-parser.test.d.ts.map +1 -0
- package/packages/server/dist/parsers/csv-parser.test.js +44 -0
- package/packages/server/dist/parsers/csv-parser.test.js.map +1 -0
- package/packages/server/dist/parsers/ide-config-parser.d.ts +9 -0
- package/packages/server/dist/parsers/ide-config-parser.d.ts.map +1 -0
- package/packages/server/dist/parsers/ide-config-parser.js +28 -0
- package/packages/server/dist/parsers/ide-config-parser.js.map +1 -0
- package/packages/server/dist/parsers/ide-config-parser.test.d.ts +2 -0
- package/packages/server/dist/parsers/ide-config-parser.test.d.ts.map +1 -0
- package/packages/server/dist/parsers/ide-config-parser.test.js +32 -0
- package/packages/server/dist/parsers/ide-config-parser.test.js.map +1 -0
- package/packages/server/dist/parsers/index-builder.d.ts +20 -0
- package/packages/server/dist/parsers/index-builder.d.ts.map +1 -0
- package/packages/server/dist/parsers/index-builder.js +155 -0
- package/packages/server/dist/parsers/index-builder.js.map +1 -0
- package/packages/server/dist/parsers/index-builder.test.d.ts +2 -0
- package/packages/server/dist/parsers/index-builder.test.d.ts.map +1 -0
- package/packages/server/dist/parsers/index-builder.test.js +57 -0
- package/packages/server/dist/parsers/index-builder.test.js.map +1 -0
- package/packages/server/dist/parsers/module-yaml-parser.d.ts +16 -0
- package/packages/server/dist/parsers/module-yaml-parser.d.ts.map +1 -0
- package/packages/server/dist/parsers/module-yaml-parser.js +62 -0
- package/packages/server/dist/parsers/module-yaml-parser.js.map +1 -0
- package/packages/server/dist/parsers/module-yaml-parser.test.d.ts +2 -0
- package/packages/server/dist/parsers/module-yaml-parser.test.d.ts.map +1 -0
- package/packages/server/dist/parsers/module-yaml-parser.test.js +156 -0
- package/packages/server/dist/parsers/module-yaml-parser.test.js.map +1 -0
- package/packages/server/dist/parsers/package-parser.d.ts +4 -0
- package/packages/server/dist/parsers/package-parser.d.ts.map +1 -0
- package/packages/server/dist/parsers/package-parser.js +29 -0
- package/packages/server/dist/parsers/package-parser.js.map +1 -0
- package/packages/server/dist/parsers/package-parser.test.d.ts +2 -0
- package/packages/server/dist/parsers/package-parser.test.d.ts.map +1 -0
- package/packages/server/dist/parsers/package-parser.test.js +34 -0
- package/packages/server/dist/parsers/package-parser.test.js.map +1 -0
- package/packages/server/dist/parsers/skill-parser.d.ts +4 -0
- package/packages/server/dist/parsers/skill-parser.d.ts.map +1 -0
- package/packages/server/dist/parsers/skill-parser.js +58 -0
- package/packages/server/dist/parsers/skill-parser.js.map +1 -0
- package/packages/server/dist/parsers/skill-parser.test.d.ts +2 -0
- package/packages/server/dist/parsers/skill-parser.test.d.ts.map +1 -0
- package/packages/server/dist/parsers/skill-parser.test.js +49 -0
- package/packages/server/dist/parsers/skill-parser.test.js.map +1 -0
- package/packages/server/dist/parsers/team-parser.d.ts +4 -0
- package/packages/server/dist/parsers/team-parser.d.ts.map +1 -0
- package/packages/server/dist/parsers/team-parser.js +108 -0
- package/packages/server/dist/parsers/team-parser.js.map +1 -0
- package/packages/server/dist/parsers/team-parser.test.d.ts +2 -0
- package/packages/server/dist/parsers/team-parser.test.d.ts.map +1 -0
- package/packages/server/dist/parsers/team-parser.test.js +142 -0
- package/packages/server/dist/parsers/team-parser.test.js.map +1 -0
- package/packages/server/dist/parsers/workflow-parser.d.ts +4 -0
- package/packages/server/dist/parsers/workflow-parser.d.ts.map +1 -0
- package/packages/server/dist/parsers/workflow-parser.js +266 -0
- package/packages/server/dist/parsers/workflow-parser.js.map +1 -0
- package/packages/server/dist/parsers/workflow-parser.test.d.ts +2 -0
- package/packages/server/dist/parsers/workflow-parser.test.d.ts.map +1 -0
- package/packages/server/dist/parsers/workflow-parser.test.js +318 -0
- package/packages/server/dist/parsers/workflow-parser.test.js.map +1 -0
- package/packages/server/dist/plugins/agents-plugin.d.ts +3 -0
- package/packages/server/dist/plugins/agents-plugin.d.ts.map +1 -0
- package/packages/server/dist/plugins/agents-plugin.js +129 -0
- package/packages/server/dist/plugins/agents-plugin.js.map +1 -0
- package/packages/server/dist/plugins/agents-plugin.test.d.ts +2 -0
- package/packages/server/dist/plugins/agents-plugin.test.d.ts.map +1 -0
- package/packages/server/dist/plugins/agents-plugin.test.js +94 -0
- package/packages/server/dist/plugins/agents-plugin.test.js.map +1 -0
- package/packages/server/dist/plugins/commands-plugin.d.ts +16 -0
- package/packages/server/dist/plugins/commands-plugin.d.ts.map +1 -0
- package/packages/server/dist/plugins/commands-plugin.js +38 -0
- package/packages/server/dist/plugins/commands-plugin.js.map +1 -0
- package/packages/server/dist/plugins/datasources-plugin.d.ts +3 -0
- package/packages/server/dist/plugins/datasources-plugin.d.ts.map +1 -0
- package/packages/server/dist/plugins/datasources-plugin.js +211 -0
- package/packages/server/dist/plugins/datasources-plugin.js.map +1 -0
- package/packages/server/dist/plugins/files-plugin.d.ts +3 -0
- package/packages/server/dist/plugins/files-plugin.d.ts.map +1 -0
- package/packages/server/dist/plugins/files-plugin.js +77 -0
- package/packages/server/dist/plugins/files-plugin.js.map +1 -0
- package/packages/server/dist/plugins/files-plugin.test.d.ts +2 -0
- package/packages/server/dist/plugins/files-plugin.test.d.ts.map +1 -0
- package/packages/server/dist/plugins/files-plugin.test.js +107 -0
- package/packages/server/dist/plugins/files-plugin.test.js.map +1 -0
- package/packages/server/dist/plugins/modules-plugin.d.ts +3 -0
- package/packages/server/dist/plugins/modules-plugin.d.ts.map +1 -0
- package/packages/server/dist/plugins/modules-plugin.js +1313 -0
- package/packages/server/dist/plugins/modules-plugin.js.map +1 -0
- package/packages/server/dist/plugins/modules-plugin.test.d.ts +2 -0
- package/packages/server/dist/plugins/modules-plugin.test.d.ts.map +1 -0
- package/packages/server/dist/plugins/modules-plugin.test.js +2124 -0
- package/packages/server/dist/plugins/modules-plugin.test.js.map +1 -0
- package/packages/server/dist/plugins/outputs-plugin.d.ts +3 -0
- package/packages/server/dist/plugins/outputs-plugin.d.ts.map +1 -0
- package/packages/server/dist/plugins/outputs-plugin.js +75 -0
- package/packages/server/dist/plugins/outputs-plugin.js.map +1 -0
- package/packages/server/dist/plugins/outputs-plugin.test.d.ts +2 -0
- package/packages/server/dist/plugins/outputs-plugin.test.d.ts.map +1 -0
- package/packages/server/dist/plugins/outputs-plugin.test.js +79 -0
- package/packages/server/dist/plugins/outputs-plugin.test.js.map +1 -0
- package/packages/server/dist/plugins/overview-plugin.d.ts +3 -0
- package/packages/server/dist/plugins/overview-plugin.d.ts.map +1 -0
- package/packages/server/dist/plugins/overview-plugin.js +70 -0
- package/packages/server/dist/plugins/overview-plugin.js.map +1 -0
- package/packages/server/dist/plugins/search-plugin.d.ts +3 -0
- package/packages/server/dist/plugins/search-plugin.d.ts.map +1 -0
- package/packages/server/dist/plugins/search-plugin.js +46 -0
- package/packages/server/dist/plugins/search-plugin.js.map +1 -0
- package/packages/server/dist/plugins/settings-plugin.d.ts +3 -0
- package/packages/server/dist/plugins/settings-plugin.d.ts.map +1 -0
- package/packages/server/dist/plugins/settings-plugin.js +61 -0
- package/packages/server/dist/plugins/settings-plugin.js.map +1 -0
- package/packages/server/dist/plugins/settings-plugin.test.d.ts +2 -0
- package/packages/server/dist/plugins/settings-plugin.test.d.ts.map +1 -0
- package/packages/server/dist/plugins/settings-plugin.test.js +144 -0
- package/packages/server/dist/plugins/settings-plugin.test.js.map +1 -0
- package/packages/server/dist/plugins/skills-plugin.d.ts +3 -0
- package/packages/server/dist/plugins/skills-plugin.d.ts.map +1 -0
- package/packages/server/dist/plugins/skills-plugin.js +72 -0
- package/packages/server/dist/plugins/skills-plugin.js.map +1 -0
- package/packages/server/dist/plugins/teams-plugin.d.ts +3 -0
- package/packages/server/dist/plugins/teams-plugin.d.ts.map +1 -0
- package/packages/server/dist/plugins/teams-plugin.js +162 -0
- package/packages/server/dist/plugins/teams-plugin.js.map +1 -0
- package/packages/server/dist/plugins/teams-plugin.test.d.ts +2 -0
- package/packages/server/dist/plugins/teams-plugin.test.d.ts.map +1 -0
- package/packages/server/dist/plugins/teams-plugin.test.js +171 -0
- package/packages/server/dist/plugins/teams-plugin.test.js.map +1 -0
- package/packages/server/dist/plugins/validation-plugin.d.ts +3 -0
- package/packages/server/dist/plugins/validation-plugin.d.ts.map +1 -0
- package/packages/server/dist/plugins/validation-plugin.js +102 -0
- package/packages/server/dist/plugins/validation-plugin.js.map +1 -0
- package/packages/server/dist/plugins/validation-plugin.test.d.ts +2 -0
- package/packages/server/dist/plugins/validation-plugin.test.d.ts.map +1 -0
- package/packages/server/dist/plugins/validation-plugin.test.js +161 -0
- package/packages/server/dist/plugins/validation-plugin.test.js.map +1 -0
- package/packages/server/dist/plugins/workflows-plugin.d.ts +3 -0
- package/packages/server/dist/plugins/workflows-plugin.d.ts.map +1 -0
- package/packages/server/dist/plugins/workflows-plugin.js +227 -0
- package/packages/server/dist/plugins/workflows-plugin.js.map +1 -0
- package/packages/server/dist/plugins/workflows-plugin.test.d.ts +2 -0
- package/packages/server/dist/plugins/workflows-plugin.test.d.ts.map +1 -0
- package/packages/server/dist/plugins/workflows-plugin.test.js +115 -0
- package/packages/server/dist/plugins/workflows-plugin.test.js.map +1 -0
- package/packages/server/dist/static.d.ts +3 -0
- package/packages/server/dist/static.d.ts.map +1 -0
- package/packages/server/dist/static.js +23 -0
- package/packages/server/dist/static.js.map +1 -0
- package/packages/shared/src/agents.ts +4 -0
- package/packages/shared/src/config.ts +26 -0
- package/packages/shared/src/connections.ts +11 -8
- package/packages/shared/src/index.ts +13 -0
- package/packages/shared/src/modules.ts +42 -0
- package/packages/shared/src/registry.ts +26 -0
- package/packages/shared/src/types.test.ts +41 -4
- package/.prettierrc +0 -8
- package/CONTRIBUTING.md +0 -109
- package/_bmad/_config/agent-manifest.csv +0 -11
- package/_bmad/_config/bmad-help.csv +0 -57
- package/_bmad/_config/files-manifest.csv +0 -646
- package/_bmad/_config/ides/claude-code.yaml +0 -5
- package/_bmad/_config/manifest.yaml +0 -42
- package/_bmad/_config/skill-manifest.csv +0 -48
- package/_bmad/_config/task-manifest.csv +0 -1
- package/_bmad/_config/tool-manifest.csv +0 -1
- package/_bmad/_config/workflow-manifest.csv +0 -1
- package/_bmad/bmb/config.yaml +0 -13
- package/_bmad/bmb/module-help.csv +0 -7
- package/_bmad/bmb/skills/bmad-agent-builder/SKILL.md +0 -65
- package/_bmad/bmb/skills/bmad-agent-builder/assets/SKILL-template.md +0 -97
- package/_bmad/bmb/skills/bmad-agent-builder/assets/autonomous-wake.md +0 -37
- package/_bmad/bmb/skills/bmad-agent-builder/assets/init-template.md +0 -47
- package/_bmad/bmb/skills/bmad-agent-builder/assets/memory-system.md +0 -129
- package/_bmad/bmb/skills/bmad-agent-builder/assets/quality-report-template.md +0 -282
- package/_bmad/bmb/skills/bmad-agent-builder/assets/save-memory.md +0 -29
- package/_bmad/bmb/skills/bmad-agent-builder/bmad-manifest.json +0 -24
- package/_bmad/bmb/skills/bmad-agent-builder/bmad-skill-manifest.yaml +0 -1
- package/_bmad/bmb/skills/bmad-agent-builder/build-process.md +0 -199
- package/_bmad/bmb/skills/bmad-agent-builder/quality-optimizer.md +0 -208
- package/_bmad/bmb/skills/bmad-agent-builder/quality-scan-agent-cohesion.md +0 -272
- package/_bmad/bmb/skills/bmad-agent-builder/quality-scan-enhancement-opportunities.md +0 -277
- package/_bmad/bmb/skills/bmad-agent-builder/quality-scan-execution-efficiency.md +0 -181
- package/_bmad/bmb/skills/bmad-agent-builder/quality-scan-prompt-craft.md +0 -245
- package/_bmad/bmb/skills/bmad-agent-builder/quality-scan-script-opportunities.md +0 -262
- package/_bmad/bmb/skills/bmad-agent-builder/quality-scan-structure.md +0 -183
- package/_bmad/bmb/skills/bmad-agent-builder/references/metadata-reference.md +0 -126
- package/_bmad/bmb/skills/bmad-agent-builder/references/quality-dimensions.md +0 -46
- package/_bmad/bmb/skills/bmad-agent-builder/references/script-opportunities-reference.md +0 -385
- package/_bmad/bmb/skills/bmad-agent-builder/references/skill-best-practices.md +0 -218
- package/_bmad/bmb/skills/bmad-agent-builder/references/standard-fields.md +0 -103
- package/_bmad/bmb/skills/bmad-agent-builder/references/template-substitution-rules.md +0 -72
- package/_bmad/bmb/skills/bmad-agent-builder/references/universal-scan-schema.md +0 -267
- package/_bmad/bmb/skills/bmad-agent-builder/report-quality-scan-creator.md +0 -138
- package/_bmad/bmb/skills/bmad-agent-builder/scripts/bmad-manifest-schema.json +0 -103
- package/_bmad/bmb/skills/bmad-agent-builder/scripts/generate-html-report.py +0 -1002
- package/_bmad/bmb/skills/bmad-agent-builder/scripts/manifest.py +0 -420
- package/_bmad/bmb/skills/bmad-agent-builder/scripts/prepass-execution-deps.py +0 -368
- package/_bmad/bmb/skills/bmad-agent-builder/scripts/prepass-prompt-metrics.py +0 -476
- package/_bmad/bmb/skills/bmad-agent-builder/scripts/prepass-structure-capabilities.py +0 -636
- package/_bmad/bmb/skills/bmad-agent-builder/scripts/scan-path-standards.py +0 -253
- package/_bmad/bmb/skills/bmad-agent-builder/scripts/scan-scripts.py +0 -745
- package/_bmad/bmb/skills/bmad-workflow-builder/SKILL.md +0 -65
- package/_bmad/bmb/skills/bmad-workflow-builder/assets/SKILL-template.md +0 -117
- package/_bmad/bmb/skills/bmad-workflow-builder/assets/quality-report-template.md +0 -260
- package/_bmad/bmb/skills/bmad-workflow-builder/bmad-manifest.json +0 -23
- package/_bmad/bmb/skills/bmad-workflow-builder/bmad-skill-manifest.yaml +0 -1
- package/_bmad/bmb/skills/bmad-workflow-builder/build-process.md +0 -208
- package/_bmad/bmb/skills/bmad-workflow-builder/quality-optimizer.md +0 -209
- package/_bmad/bmb/skills/bmad-workflow-builder/quality-scan-enhancement-opportunities.md +0 -273
- package/_bmad/bmb/skills/bmad-workflow-builder/quality-scan-execution-efficiency.md +0 -322
- package/_bmad/bmb/skills/bmad-workflow-builder/quality-scan-prompt-craft.md +0 -328
- package/_bmad/bmb/skills/bmad-workflow-builder/quality-scan-script-opportunities.md +0 -261
- package/_bmad/bmb/skills/bmad-workflow-builder/quality-scan-skill-cohesion.md +0 -340
- package/_bmad/bmb/skills/bmad-workflow-builder/quality-scan-workflow-integrity.md +0 -280
- package/_bmad/bmb/skills/bmad-workflow-builder/references/classification-reference.md +0 -61
- package/_bmad/bmb/skills/bmad-workflow-builder/references/complex-workflow-patterns.md +0 -523
- package/_bmad/bmb/skills/bmad-workflow-builder/references/metadata-reference.md +0 -126
- package/_bmad/bmb/skills/bmad-workflow-builder/references/quality-dimensions.md +0 -45
- package/_bmad/bmb/skills/bmad-workflow-builder/references/script-opportunities-reference.md +0 -354
- package/_bmad/bmb/skills/bmad-workflow-builder/references/skill-best-practices.md +0 -218
- package/_bmad/bmb/skills/bmad-workflow-builder/references/standard-fields.md +0 -121
- package/_bmad/bmb/skills/bmad-workflow-builder/references/template-substitution-rules.md +0 -85
- package/_bmad/bmb/skills/bmad-workflow-builder/references/universal-scan-schema.md +0 -267
- package/_bmad/bmb/skills/bmad-workflow-builder/report-quality-scan-creator.md +0 -134
- package/_bmad/bmb/skills/bmad-workflow-builder/scripts/bmad-manifest-schema.json +0 -103
- package/_bmad/bmb/skills/bmad-workflow-builder/scripts/generate-html-report.py +0 -1002
- package/_bmad/bmb/skills/bmad-workflow-builder/scripts/manifest.py +0 -420
- package/_bmad/bmb/skills/bmad-workflow-builder/scripts/prepass-execution-deps.py +0 -313
- package/_bmad/bmb/skills/bmad-workflow-builder/scripts/prepass-prompt-metrics.py +0 -285
- package/_bmad/bmb/skills/bmad-workflow-builder/scripts/prepass-workflow-integrity.py +0 -485
- package/_bmad/bmb/skills/bmad-workflow-builder/scripts/scan-path-standards.py +0 -213
- package/_bmad/bmb/skills/bmad-workflow-builder/scripts/scan-scripts.py +0 -745
- package/_bmad/bmm/agents/analyst.md +0 -69
- package/_bmad/bmm/agents/architect.md +0 -59
- package/_bmad/bmm/agents/bmad-skill-manifest.yaml +0 -39
- package/_bmad/bmm/agents/dev.md +0 -66
- package/_bmad/bmm/agents/pm.md +0 -63
- package/_bmad/bmm/agents/qa.md +0 -89
- package/_bmad/bmm/agents/quick-flow-solo-dev.md +0 -61
- package/_bmad/bmm/agents/sm.md +0 -67
- package/_bmad/bmm/agents/tech-writer/bmad-skill-manifest.yaml +0 -3
- package/_bmad/bmm/agents/tech-writer/tech-writer.md +0 -67
- package/_bmad/bmm/agents/ux-designer.md +0 -58
- package/_bmad/bmm/config.yaml +0 -16
- package/_bmad/bmm/data/project-context-template.md +0 -26
- package/_bmad/bmm/module-help.csv +0 -32
- package/_bmad/bmm/teams/default-party.csv +0 -20
- package/_bmad/bmm/teams/team-fullstack.yaml +0 -12
- package/_bmad/bmm/workflows/1-analysis/bmad-create-product-brief/SKILL.md +0 -6
- package/_bmad/bmm/workflows/1-analysis/bmad-create-product-brief/bmad-skill-manifest.yaml +0 -1
- package/_bmad/bmm/workflows/1-analysis/bmad-create-product-brief/product-brief.template.md +0 -10
- package/_bmad/bmm/workflows/1-analysis/bmad-create-product-brief/steps/step-01-init.md +0 -170
- package/_bmad/bmm/workflows/1-analysis/bmad-create-product-brief/steps/step-01b-continue.md +0 -158
- package/_bmad/bmm/workflows/1-analysis/bmad-create-product-brief/steps/step-02-vision.md +0 -193
- package/_bmad/bmm/workflows/1-analysis/bmad-create-product-brief/steps/step-03-users.md +0 -196
- package/_bmad/bmm/workflows/1-analysis/bmad-create-product-brief/steps/step-04-metrics.md +0 -199
- package/_bmad/bmm/workflows/1-analysis/bmad-create-product-brief/steps/step-05-scope.md +0 -213
- package/_bmad/bmm/workflows/1-analysis/bmad-create-product-brief/steps/step-06-complete.md +0 -159
- package/_bmad/bmm/workflows/1-analysis/bmad-create-product-brief/workflow.md +0 -55
- package/_bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/SKILL.md +0 -88
- package/_bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/agents/artifact-analyzer.md +0 -60
- package/_bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/agents/opportunity-reviewer.md +0 -44
- package/_bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/agents/skeptic-reviewer.md +0 -44
- package/_bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/agents/web-researcher.md +0 -49
- package/_bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/bmad-manifest.json +0 -17
- package/_bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/bmad-skill-manifest.yaml +0 -1
- package/_bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/prompts/contextual-discovery.md +0 -57
- package/_bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/prompts/draft-and-review.md +0 -86
- package/_bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/prompts/finalize.md +0 -75
- package/_bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/prompts/guided-elicitation.md +0 -70
- package/_bmad/bmm/workflows/1-analysis/bmad-product-brief-preview/resources/brief-template.md +0 -60
- package/_bmad/bmm/workflows/1-analysis/research/bmad-domain-research/SKILL.md +0 -6
- package/_bmad/bmm/workflows/1-analysis/research/bmad-domain-research/bmad-skill-manifest.yaml +0 -1
- package/_bmad/bmm/workflows/1-analysis/research/bmad-domain-research/domain-steps/step-01-init.md +0 -137
- package/_bmad/bmm/workflows/1-analysis/research/bmad-domain-research/domain-steps/step-02-domain-analysis.md +0 -229
- package/_bmad/bmm/workflows/1-analysis/research/bmad-domain-research/domain-steps/step-03-competitive-landscape.md +0 -238
- package/_bmad/bmm/workflows/1-analysis/research/bmad-domain-research/domain-steps/step-04-regulatory-focus.md +0 -206
- package/_bmad/bmm/workflows/1-analysis/research/bmad-domain-research/domain-steps/step-05-technical-trends.md +0 -234
- package/_bmad/bmm/workflows/1-analysis/research/bmad-domain-research/domain-steps/step-06-research-synthesis.md +0 -444
- package/_bmad/bmm/workflows/1-analysis/research/bmad-domain-research/research.template.md +0 -29
- package/_bmad/bmm/workflows/1-analysis/research/bmad-domain-research/workflow.md +0 -49
- package/_bmad/bmm/workflows/1-analysis/research/bmad-market-research/SKILL.md +0 -6
- package/_bmad/bmm/workflows/1-analysis/research/bmad-market-research/bmad-skill-manifest.yaml +0 -1
- package/_bmad/bmm/workflows/1-analysis/research/bmad-market-research/research.template.md +0 -29
- package/_bmad/bmm/workflows/1-analysis/research/bmad-market-research/steps/step-01-init.md +0 -184
- package/_bmad/bmm/workflows/1-analysis/research/bmad-market-research/steps/step-02-customer-behavior.md +0 -239
- package/_bmad/bmm/workflows/1-analysis/research/bmad-market-research/steps/step-03-customer-pain-points.md +0 -251
- package/_bmad/bmm/workflows/1-analysis/research/bmad-market-research/steps/step-04-customer-decisions.md +0 -261
- package/_bmad/bmm/workflows/1-analysis/research/bmad-market-research/steps/step-05-competitive-analysis.md +0 -173
- package/_bmad/bmm/workflows/1-analysis/research/bmad-market-research/steps/step-06-research-completion.md +0 -478
- package/_bmad/bmm/workflows/1-analysis/research/bmad-market-research/workflow.md +0 -49
- package/_bmad/bmm/workflows/1-analysis/research/bmad-technical-research/SKILL.md +0 -6
- package/_bmad/bmm/workflows/1-analysis/research/bmad-technical-research/bmad-skill-manifest.yaml +0 -1
- package/_bmad/bmm/workflows/1-analysis/research/bmad-technical-research/research.template.md +0 -29
- package/_bmad/bmm/workflows/1-analysis/research/bmad-technical-research/technical-steps/step-01-init.md +0 -137
- package/_bmad/bmm/workflows/1-analysis/research/bmad-technical-research/technical-steps/step-02-technical-overview.md +0 -239
- package/_bmad/bmm/workflows/1-analysis/research/bmad-technical-research/technical-steps/step-03-integration-patterns.md +0 -248
- package/_bmad/bmm/workflows/1-analysis/research/bmad-technical-research/technical-steps/step-04-architectural-patterns.md +0 -202
- package/_bmad/bmm/workflows/1-analysis/research/bmad-technical-research/technical-steps/step-05-implementation-research.md +0 -233
- package/_bmad/bmm/workflows/1-analysis/research/bmad-technical-research/technical-steps/step-06-research-synthesis.md +0 -487
- package/_bmad/bmm/workflows/1-analysis/research/bmad-technical-research/workflow.md +0 -50
- package/_bmad/bmm/workflows/1-analysis/research/market-steps/step-01-init.md +0 -182
- package/_bmad/bmm/workflows/1-analysis/research/market-steps/step-02-customer-behavior.md +0 -237
- package/_bmad/bmm/workflows/1-analysis/research/market-steps/step-03-customer-pain-points.md +0 -249
- package/_bmad/bmm/workflows/1-analysis/research/market-steps/step-04-customer-decisions.md +0 -259
- package/_bmad/bmm/workflows/1-analysis/research/market-steps/step-05-competitive-analysis.md +0 -177
- package/_bmad/bmm/workflows/1-analysis/research/market-steps/step-06-research-completion.md +0 -476
- package/_bmad/bmm/workflows/1-analysis/research/research.template.md +0 -29
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/SKILL.md +0 -6
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/bmad-skill-manifest.yaml +0 -1
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-01-init.md +0 -135
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-01b-continue.md +0 -127
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-02-discovery.md +0 -190
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-03-core-experience.md +0 -217
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-04-emotional-response.md +0 -220
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-05-inspiration.md +0 -235
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-06-design-system.md +0 -253
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-07-defining-experience.md +0 -255
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-08-visual-foundation.md +0 -225
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-09-design-directions.md +0 -225
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-10-user-journeys.md +0 -242
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-11-component-strategy.md +0 -249
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-12-ux-patterns.md +0 -238
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-13-responsive-accessibility.md +0 -265
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/steps/step-14-complete.md +0 -171
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/ux-design-template.md +0 -13
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-create-ux-design/workflow.md +0 -36
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-edit-prd/SKILL.md +0 -6
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-edit-prd/bmad-skill-manifest.yaml +0 -1
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-edit-prd/steps-e/step-e-01-discovery.md +0 -242
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-edit-prd/steps-e/step-e-01b-legacy-conversion.md +0 -204
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-edit-prd/steps-e/step-e-02-review.md +0 -245
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-edit-prd/steps-e/step-e-03-edit.md +0 -250
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-edit-prd/steps-e/step-e-04-complete.md +0 -165
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-edit-prd/workflow.md +0 -63
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/SKILL.md +0 -6
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/bmad-skill-manifest.yaml +0 -1
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/data/domain-complexity.csv +0 -15
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/data/prd-purpose.md +0 -197
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/data/project-types.csv +0 -11
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-01-discovery.md +0 -221
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-02-format-detection.md +0 -188
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-02b-parity-check.md +0 -206
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-03-density-validation.md +0 -171
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-04-brief-coverage-validation.md +0 -211
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-05-measurability-validation.md +0 -225
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-06-traceability-validation.md +0 -214
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-07-implementation-leakage-validation.md +0 -202
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-08-domain-compliance-validation.md +0 -240
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-09-project-type-validation.md +0 -260
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-10-smart-validation.md +0 -206
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-11-holistic-quality-validation.md +0 -261
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-12-completeness-validation.md +0 -239
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/steps-v/step-v-13-report-complete.md +0 -229
- package/_bmad/bmm/workflows/2-plan-workflows/bmad-validate-prd/workflow.md +0 -62
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/data/domain-complexity.csv +0 -15
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/data/prd-purpose.md +0 -197
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/data/project-types.csv +0 -11
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-01-discovery.md +0 -224
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-02-format-detection.md +0 -191
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-02b-parity-check.md +0 -209
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-03-density-validation.md +0 -174
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-04-brief-coverage-validation.md +0 -214
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-05-measurability-validation.md +0 -228
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-06-traceability-validation.md +0 -217
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-07-implementation-leakage-validation.md +0 -205
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-08-domain-compliance-validation.md +0 -243
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-09-project-type-validation.md +0 -263
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-10-smart-validation.md +0 -209
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-11-holistic-quality-validation.md +0 -264
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-12-completeness-validation.md +0 -242
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-13-report-complete.md +0 -232
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/workflow-validate-prd.md +0 -65
- package/_bmad/bmm/workflows/3-solutioning/bmad-check-implementation-readiness/SKILL.md +0 -6
- package/_bmad/bmm/workflows/3-solutioning/bmad-check-implementation-readiness/bmad-skill-manifest.yaml +0 -1
- package/_bmad/bmm/workflows/3-solutioning/bmad-check-implementation-readiness/steps/step-01-document-discovery.md +0 -179
- package/_bmad/bmm/workflows/3-solutioning/bmad-check-implementation-readiness/steps/step-02-prd-analysis.md +0 -168
- package/_bmad/bmm/workflows/3-solutioning/bmad-check-implementation-readiness/steps/step-03-epic-coverage-validation.md +0 -169
- package/_bmad/bmm/workflows/3-solutioning/bmad-check-implementation-readiness/steps/step-04-ux-alignment.md +0 -129
- package/_bmad/bmm/workflows/3-solutioning/bmad-check-implementation-readiness/steps/step-05-epic-quality-review.md +0 -241
- package/_bmad/bmm/workflows/3-solutioning/bmad-check-implementation-readiness/steps/step-06-final-assessment.md +0 -126
- package/_bmad/bmm/workflows/3-solutioning/bmad-check-implementation-readiness/templates/readiness-report-template.md +0 -4
- package/_bmad/bmm/workflows/3-solutioning/bmad-check-implementation-readiness/workflow.md +0 -49
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/SKILL.md +0 -6
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/architecture-decision-template.md +0 -12
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/bmad-skill-manifest.yaml +0 -1
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/data/domain-complexity.csv +0 -13
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/data/project-types.csv +0 -7
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/steps/step-01-init.md +0 -153
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/steps/step-01b-continue.md +0 -173
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/steps/step-02-context.md +0 -224
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/steps/step-03-starter.md +0 -329
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/steps/step-04-decisions.md +0 -318
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/steps/step-05-patterns.md +0 -359
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/steps/step-06-structure.md +0 -379
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/steps/step-07-validation.md +0 -359
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/steps/step-08-complete.md +0 -76
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-architecture/workflow.md +0 -38
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-epics-and-stories/SKILL.md +0 -6
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-epics-and-stories/bmad-skill-manifest.yaml +0 -1
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-epics-and-stories/steps/step-01-validate-prerequisites.md +0 -255
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-epics-and-stories/steps/step-02-design-epics.md +0 -212
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-epics-and-stories/steps/step-03-create-stories.md +0 -255
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-epics-and-stories/steps/step-04-final-validation.md +0 -131
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-epics-and-stories/templates/epics-template.md +0 -61
- package/_bmad/bmm/workflows/3-solutioning/bmad-create-epics-and-stories/workflow.md +0 -53
- package/_bmad/bmm/workflows/4-implementation/bmad-code-review/SKILL.md +0 -6
- package/_bmad/bmm/workflows/4-implementation/bmad-code-review/bmad-skill-manifest.yaml +0 -1
- package/_bmad/bmm/workflows/4-implementation/bmad-code-review/steps/step-01-gather-context.md +0 -61
- package/_bmad/bmm/workflows/4-implementation/bmad-code-review/steps/step-02-review.md +0 -41
- package/_bmad/bmm/workflows/4-implementation/bmad-code-review/steps/step-03-triage.md +0 -50
- package/_bmad/bmm/workflows/4-implementation/bmad-code-review/steps/step-04-present.md +0 -38
- package/_bmad/bmm/workflows/4-implementation/bmad-code-review/workflow.md +0 -54
- package/_bmad/bmm/workflows/4-implementation/bmad-correct-course/SKILL.md +0 -6
- package/_bmad/bmm/workflows/4-implementation/bmad-correct-course/bmad-skill-manifest.yaml +0 -1
- package/_bmad/bmm/workflows/4-implementation/bmad-correct-course/checklist.md +0 -288
- package/_bmad/bmm/workflows/4-implementation/bmad-correct-course/workflow.md +0 -267
- package/_bmad/bmm/workflows/4-implementation/bmad-create-story/SKILL.md +0 -6
- package/_bmad/bmm/workflows/4-implementation/bmad-create-story/bmad-skill-manifest.yaml +0 -1
- package/_bmad/bmm/workflows/4-implementation/bmad-create-story/checklist.md +0 -357
- package/_bmad/bmm/workflows/4-implementation/bmad-create-story/discover-inputs.md +0 -88
- package/_bmad/bmm/workflows/4-implementation/bmad-create-story/template.md +0 -49
- package/_bmad/bmm/workflows/4-implementation/bmad-create-story/workflow.md +0 -380
- package/_bmad/bmm/workflows/4-implementation/bmad-dev-story/SKILL.md +0 -6
- package/_bmad/bmm/workflows/4-implementation/bmad-dev-story/bmad-skill-manifest.yaml +0 -1
- package/_bmad/bmm/workflows/4-implementation/bmad-dev-story/checklist.md +0 -80
- package/_bmad/bmm/workflows/4-implementation/bmad-dev-story/workflow.md +0 -450
- package/_bmad/bmm/workflows/4-implementation/bmad-retrospective/SKILL.md +0 -6
- package/_bmad/bmm/workflows/4-implementation/bmad-retrospective/bmad-skill-manifest.yaml +0 -1
- package/_bmad/bmm/workflows/4-implementation/bmad-retrospective/workflow.md +0 -1479
- package/_bmad/bmm/workflows/4-implementation/bmad-sprint-planning/SKILL.md +0 -6
- package/_bmad/bmm/workflows/4-implementation/bmad-sprint-planning/bmad-skill-manifest.yaml +0 -1
- package/_bmad/bmm/workflows/4-implementation/bmad-sprint-planning/checklist.md +0 -33
- package/_bmad/bmm/workflows/4-implementation/bmad-sprint-planning/sprint-status-template.yaml +0 -56
- package/_bmad/bmm/workflows/4-implementation/bmad-sprint-planning/workflow.md +0 -263
- package/_bmad/bmm/workflows/4-implementation/bmad-sprint-status/SKILL.md +0 -6
- package/_bmad/bmm/workflows/4-implementation/bmad-sprint-status/bmad-skill-manifest.yaml +0 -1
- package/_bmad/bmm/workflows/4-implementation/bmad-sprint-status/workflow.md +0 -261
- package/_bmad/bmm/workflows/bmad-document-project/SKILL.md +0 -6
- package/_bmad/bmm/workflows/bmad-document-project/bmad-skill-manifest.yaml +0 -1
- package/_bmad/bmm/workflows/bmad-document-project/checklist.md +0 -245
- package/_bmad/bmm/workflows/bmad-document-project/documentation-requirements.csv +0 -12
- package/_bmad/bmm/workflows/bmad-document-project/instructions.md +0 -128
- package/_bmad/bmm/workflows/bmad-document-project/templates/deep-dive-template.md +0 -345
- package/_bmad/bmm/workflows/bmad-document-project/templates/index-template.md +0 -169
- package/_bmad/bmm/workflows/bmad-document-project/templates/project-overview-template.md +0 -103
- package/_bmad/bmm/workflows/bmad-document-project/templates/project-scan-report-schema.json +0 -160
- package/_bmad/bmm/workflows/bmad-document-project/templates/source-tree-template.md +0 -135
- package/_bmad/bmm/workflows/bmad-document-project/workflow.md +0 -27
- package/_bmad/bmm/workflows/bmad-document-project/workflows/deep-dive-instructions.md +0 -299
- package/_bmad/bmm/workflows/bmad-document-project/workflows/deep-dive-workflow.md +0 -34
- package/_bmad/bmm/workflows/bmad-document-project/workflows/full-scan-instructions.md +0 -1107
- package/_bmad/bmm/workflows/bmad-document-project/workflows/full-scan-workflow.md +0 -34
- package/_bmad/bmm/workflows/bmad-generate-project-context/SKILL.md +0 -6
- package/_bmad/bmm/workflows/bmad-generate-project-context/bmad-skill-manifest.yaml +0 -1
- package/_bmad/bmm/workflows/bmad-generate-project-context/project-context-template.md +0 -21
- package/_bmad/bmm/workflows/bmad-generate-project-context/steps/step-01-discover.md +0 -186
- package/_bmad/bmm/workflows/bmad-generate-project-context/steps/step-02-generate.md +0 -321
- package/_bmad/bmm/workflows/bmad-generate-project-context/steps/step-03-complete.md +0 -278
- package/_bmad/bmm/workflows/bmad-generate-project-context/workflow.md +0 -43
- package/_bmad/bmm/workflows/bmad-qa-generate-e2e-tests/SKILL.md +0 -6
- package/_bmad/bmm/workflows/bmad-qa-generate-e2e-tests/bmad-skill-manifest.yaml +0 -1
- package/_bmad/bmm/workflows/bmad-qa-generate-e2e-tests/checklist.md +0 -33
- package/_bmad/bmm/workflows/bmad-qa-generate-e2e-tests/workflow.md +0 -136
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev/SKILL.md +0 -6
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev/bmad-skill-manifest.yaml +0 -1
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev/steps/step-01-mode-detection.md +0 -169
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev/steps/step-02-context-gathering.md +0 -114
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev/steps/step-03-execute.md +0 -107
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev/steps/step-04-self-check.md +0 -107
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev/steps/step-05-adversarial-review.md +0 -94
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev/steps/step-06-resolve-findings.md +0 -144
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev/workflow.md +0 -38
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev-new-preview/SKILL.md +0 -6
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev-new-preview/bmad-skill-manifest.yaml +0 -1
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev-new-preview/steps/step-01-clarify-and-route.md +0 -51
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev-new-preview/steps/step-02-plan.md +0 -35
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev-new-preview/steps/step-03-implement.md +0 -33
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev-new-preview/steps/step-04-review.md +0 -50
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev-new-preview/steps/step-05-present.md +0 -17
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev-new-preview/tech-spec-template.md +0 -90
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-dev-new-preview/workflow.md +0 -79
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-spec/SKILL.md +0 -6
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-spec/bmad-skill-manifest.yaml +0 -1
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-spec/steps/step-01-understand.md +0 -185
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-spec/steps/step-02-investigate.md +0 -140
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-spec/steps/step-03-generate.md +0 -123
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-spec/steps/step-04-review.md +0 -195
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-spec/tech-spec-template.md +0 -74
- package/_bmad/bmm/workflows/bmad-quick-flow/bmad-quick-spec/workflow.md +0 -73
- package/_bmad/core/config.yaml +0 -9
- package/_bmad/core/module-help.csv +0 -11
- package/_bmad/core/skills/bmad-advanced-elicitation/SKILL.md +0 -6
- package/_bmad/core/skills/bmad-advanced-elicitation/bmad-skill-manifest.yaml +0 -1
- package/_bmad/core/skills/bmad-advanced-elicitation/methods.csv +0 -51
- package/_bmad/core/skills/bmad-advanced-elicitation/workflow.md +0 -135
- package/_bmad/core/skills/bmad-brainstorming/SKILL.md +0 -6
- package/_bmad/core/skills/bmad-brainstorming/bmad-skill-manifest.yaml +0 -1
- package/_bmad/core/skills/bmad-brainstorming/brain-methods.csv +0 -62
- package/_bmad/core/skills/bmad-brainstorming/steps/step-01-session-setup.md +0 -214
- package/_bmad/core/skills/bmad-brainstorming/steps/step-01b-continue.md +0 -124
- package/_bmad/core/skills/bmad-brainstorming/steps/step-02a-user-selected.md +0 -229
- package/_bmad/core/skills/bmad-brainstorming/steps/step-02b-ai-recommended.md +0 -239
- package/_bmad/core/skills/bmad-brainstorming/steps/step-02c-random-selection.md +0 -211
- package/_bmad/core/skills/bmad-brainstorming/steps/step-02d-progressive-flow.md +0 -266
- package/_bmad/core/skills/bmad-brainstorming/steps/step-03-technique-execution.md +0 -401
- package/_bmad/core/skills/bmad-brainstorming/steps/step-04-idea-organization.md +0 -305
- package/_bmad/core/skills/bmad-brainstorming/template.md +0 -15
- package/_bmad/core/skills/bmad-brainstorming/workflow.md +0 -53
- package/_bmad/core/skills/bmad-distillator/SKILL.md +0 -178
- package/_bmad/core/skills/bmad-distillator/agents/distillate-compressor.md +0 -116
- package/_bmad/core/skills/bmad-distillator/agents/round-trip-reconstructor.md +0 -68
- package/_bmad/core/skills/bmad-distillator/bmad-skill-manifest.yaml +0 -15
- package/_bmad/core/skills/bmad-distillator/resources/compression-rules.md +0 -51
- package/_bmad/core/skills/bmad-distillator/resources/distillate-format-reference.md +0 -227
- package/_bmad/core/skills/bmad-distillator/resources/splitting-strategy.md +0 -78
- package/_bmad/core/skills/bmad-distillator/scripts/analyze_sources.py +0 -300
- package/_bmad/core/skills/bmad-distillator/scripts/tests/test_analyze_sources.py +0 -204
- package/_bmad/core/skills/bmad-editorial-review-prose/SKILL.md +0 -6
- package/_bmad/core/skills/bmad-editorial-review-prose/bmad-skill-manifest.yaml +0 -1
- package/_bmad/core/skills/bmad-editorial-review-prose/workflow.md +0 -81
- package/_bmad/core/skills/bmad-editorial-review-structure/SKILL.md +0 -6
- package/_bmad/core/skills/bmad-editorial-review-structure/bmad-skill-manifest.yaml +0 -1
- package/_bmad/core/skills/bmad-editorial-review-structure/workflow.md +0 -174
- package/_bmad/core/skills/bmad-help/SKILL.md +0 -6
- package/_bmad/core/skills/bmad-help/bmad-skill-manifest.yaml +0 -1
- package/_bmad/core/skills/bmad-help/workflow.md +0 -88
- package/_bmad/core/skills/bmad-index-docs/SKILL.md +0 -6
- package/_bmad/core/skills/bmad-index-docs/bmad-skill-manifest.yaml +0 -1
- package/_bmad/core/skills/bmad-index-docs/workflow.md +0 -61
- package/_bmad/core/skills/bmad-party-mode/SKILL.md +0 -6
- package/_bmad/core/skills/bmad-party-mode/bmad-skill-manifest.yaml +0 -1
- package/_bmad/core/skills/bmad-party-mode/steps/step-01-agent-loading.md +0 -138
- package/_bmad/core/skills/bmad-party-mode/steps/step-02-discussion-orchestration.md +0 -187
- package/_bmad/core/skills/bmad-party-mode/steps/step-03-graceful-exit.md +0 -167
- package/_bmad/core/skills/bmad-party-mode/workflow.md +0 -190
- package/_bmad/core/skills/bmad-review-adversarial-general/SKILL.md +0 -6
- package/_bmad/core/skills/bmad-review-adversarial-general/bmad-skill-manifest.yaml +0 -1
- package/_bmad/core/skills/bmad-review-adversarial-general/workflow.md +0 -32
- package/_bmad/core/skills/bmad-review-edge-case-hunter/SKILL.md +0 -6
- package/_bmad/core/skills/bmad-review-edge-case-hunter/bmad-skill-manifest.yaml +0 -1
- package/_bmad/core/skills/bmad-review-edge-case-hunter/workflow.md +0 -62
- package/_bmad/core/skills/bmad-shard-doc/SKILL.md +0 -6
- package/_bmad/core/skills/bmad-shard-doc/bmad-skill-manifest.yaml +0 -1
- package/_bmad/core/skills/bmad-shard-doc/workflow.md +0 -100
- package/_bmad/core/tasks/bmad-create-prd/SKILL.md +0 -6
- package/_bmad/core/tasks/bmad-create-prd/bmad-skill-manifest.yaml +0 -1
- package/_bmad/core/tasks/bmad-create-prd/data/domain-complexity.csv +0 -15
- package/_bmad/core/tasks/bmad-create-prd/data/prd-purpose.md +0 -197
- package/_bmad/core/tasks/bmad-create-prd/data/project-types.csv +0 -11
- package/_bmad/core/tasks/bmad-create-prd/steps-c/step-01-init.md +0 -178
- package/_bmad/core/tasks/bmad-create-prd/steps-c/step-01b-continue.md +0 -161
- package/_bmad/core/tasks/bmad-create-prd/steps-c/step-02-discovery.md +0 -208
- package/_bmad/core/tasks/bmad-create-prd/steps-c/step-02b-vision.md +0 -142
- package/_bmad/core/tasks/bmad-create-prd/steps-c/step-02c-executive-summary.md +0 -158
- package/_bmad/core/tasks/bmad-create-prd/steps-c/step-03-success.md +0 -214
- package/_bmad/core/tasks/bmad-create-prd/steps-c/step-04-journeys.md +0 -201
- package/_bmad/core/tasks/bmad-create-prd/steps-c/step-05-domain.md +0 -194
- package/_bmad/core/tasks/bmad-create-prd/steps-c/step-06-innovation.md +0 -211
- package/_bmad/core/tasks/bmad-create-prd/steps-c/step-07-project-type.md +0 -222
- package/_bmad/core/tasks/bmad-create-prd/steps-c/step-08-scoping.md +0 -216
- package/_bmad/core/tasks/bmad-create-prd/steps-c/step-09-functional.md +0 -219
- package/_bmad/core/tasks/bmad-create-prd/steps-c/step-10-nonfunctional.md +0 -230
- package/_bmad/core/tasks/bmad-create-prd/steps-c/step-11-polish.md +0 -221
- package/_bmad/core/tasks/bmad-create-prd/steps-c/step-12-complete.md +0 -115
- package/_bmad/core/tasks/bmad-create-prd/templates/prd-template.md +0 -10
- package/_bmad/core/tasks/bmad-create-prd/workflow.md +0 -62
- package/_bmad/tea/agents/tea.md +0 -63
- package/_bmad/tea/config.yaml +0 -25
- package/_bmad/tea/module-help.csv +0 -10
- package/_bmad/tea/teams/default-party.csv +0 -2
- package/_bmad/tea/testarch/knowledge/adr-quality-readiness-checklist.md +0 -377
- package/_bmad/tea/testarch/knowledge/api-request.md +0 -563
- package/_bmad/tea/testarch/knowledge/api-testing-patterns.md +0 -915
- package/_bmad/tea/testarch/knowledge/auth-session.md +0 -548
- package/_bmad/tea/testarch/knowledge/burn-in.md +0 -273
- package/_bmad/tea/testarch/knowledge/ci-burn-in.md +0 -717
- package/_bmad/tea/testarch/knowledge/component-tdd.md +0 -486
- package/_bmad/tea/testarch/knowledge/contract-testing.md +0 -1050
- package/_bmad/tea/testarch/knowledge/data-factories.md +0 -500
- package/_bmad/tea/testarch/knowledge/email-auth.md +0 -721
- package/_bmad/tea/testarch/knowledge/error-handling.md +0 -725
- package/_bmad/tea/testarch/knowledge/feature-flags.md +0 -750
- package/_bmad/tea/testarch/knowledge/file-utils.md +0 -456
- package/_bmad/tea/testarch/knowledge/fixture-architecture.md +0 -401
- package/_bmad/tea/testarch/knowledge/fixtures-composition.md +0 -382
- package/_bmad/tea/testarch/knowledge/intercept-network-call.md +0 -426
- package/_bmad/tea/testarch/knowledge/log.md +0 -426
- package/_bmad/tea/testarch/knowledge/network-error-monitor.md +0 -401
- package/_bmad/tea/testarch/knowledge/network-first.md +0 -486
- package/_bmad/tea/testarch/knowledge/network-recorder.md +0 -527
- package/_bmad/tea/testarch/knowledge/nfr-criteria.md +0 -670
- package/_bmad/tea/testarch/knowledge/overview.md +0 -286
- package/_bmad/tea/testarch/knowledge/pact-consumer-di.md +0 -310
- package/_bmad/tea/testarch/knowledge/pact-consumer-framework-setup.md +0 -635
- package/_bmad/tea/testarch/knowledge/pact-mcp.md +0 -204
- package/_bmad/tea/testarch/knowledge/pactjs-utils-consumer-helpers.md +0 -270
- package/_bmad/tea/testarch/knowledge/pactjs-utils-overview.md +0 -216
- package/_bmad/tea/testarch/knowledge/pactjs-utils-provider-verifier.md +0 -315
- package/_bmad/tea/testarch/knowledge/pactjs-utils-request-filter.md +0 -224
- package/_bmad/tea/testarch/knowledge/playwright-cli.md +0 -165
- package/_bmad/tea/testarch/knowledge/playwright-config.md +0 -730
- package/_bmad/tea/testarch/knowledge/probability-impact.md +0 -601
- package/_bmad/tea/testarch/knowledge/recurse.md +0 -421
- package/_bmad/tea/testarch/knowledge/risk-governance.md +0 -615
- package/_bmad/tea/testarch/knowledge/selective-testing.md +0 -732
- package/_bmad/tea/testarch/knowledge/selector-resilience.md +0 -527
- package/_bmad/tea/testarch/knowledge/test-healing-patterns.md +0 -644
- package/_bmad/tea/testarch/knowledge/test-levels-framework.md +0 -473
- package/_bmad/tea/testarch/knowledge/test-priorities-matrix.md +0 -373
- package/_bmad/tea/testarch/knowledge/test-quality.md +0 -664
- package/_bmad/tea/testarch/knowledge/timing-debugging.md +0 -372
- package/_bmad/tea/testarch/knowledge/visual-debugging.md +0 -524
- package/_bmad/tea/testarch/tea-index.csv +0 -43
- package/_bmad/tea/workflows/testarch/README.md +0 -74
- package/_bmad/tea/workflows/testarch/bmad-teach-me-testing/SKILL.md +0 -6
- package/_bmad/tea/workflows/testarch/bmad-teach-me-testing/bmad-skill-manifest.yaml +0 -1
- package/_bmad/tea/workflows/testarch/bmad-teach-me-testing/checklist.md +0 -197
- package/_bmad/tea/workflows/testarch/bmad-teach-me-testing/data/curriculum.yaml +0 -129
- package/_bmad/tea/workflows/testarch/bmad-teach-me-testing/data/quiz-questions.yaml +0 -206
- package/_bmad/tea/workflows/testarch/bmad-teach-me-testing/data/role-paths.yaml +0 -136
- package/_bmad/tea/workflows/testarch/bmad-teach-me-testing/data/session-content-map.yaml +0 -207
- package/_bmad/tea/workflows/testarch/bmad-teach-me-testing/data/tea-resources-index.yaml +0 -359
- package/_bmad/tea/workflows/testarch/bmad-teach-me-testing/instructions.md +0 -130
- package/_bmad/tea/workflows/testarch/bmad-teach-me-testing/steps-c/step-01-init.md +0 -235
- package/_bmad/tea/workflows/testarch/bmad-teach-me-testing/steps-c/step-01b-continue.md +0 -147
- package/_bmad/tea/workflows/testarch/bmad-teach-me-testing/steps-c/step-02-assess.md +0 -258
- package/_bmad/tea/workflows/testarch/bmad-teach-me-testing/steps-c/step-03-session-menu.md +0 -219
- package/_bmad/tea/workflows/testarch/bmad-teach-me-testing/steps-c/step-04-session-01.md +0 -460
- package/_bmad/tea/workflows/testarch/bmad-teach-me-testing/steps-c/step-04-session-02.md +0 -465
- package/_bmad/tea/workflows/testarch/bmad-teach-me-testing/steps-c/step-04-session-03.md +0 -301
- package/_bmad/tea/workflows/testarch/bmad-teach-me-testing/steps-c/step-04-session-04.md +0 -234
- package/_bmad/tea/workflows/testarch/bmad-teach-me-testing/steps-c/step-04-session-05.md +0 -234
- package/_bmad/tea/workflows/testarch/bmad-teach-me-testing/steps-c/step-04-session-06.md +0 -209
- package/_bmad/tea/workflows/testarch/bmad-teach-me-testing/steps-c/step-04-session-07.md +0 -212
- package/_bmad/tea/workflows/testarch/bmad-teach-me-testing/steps-c/step-05-completion.md +0 -339
- package/_bmad/tea/workflows/testarch/bmad-teach-me-testing/steps-e/step-e-01-assess-workflow.md +0 -141
- package/_bmad/tea/workflows/testarch/bmad-teach-me-testing/steps-e/step-e-02-apply-edits.md +0 -122
- package/_bmad/tea/workflows/testarch/bmad-teach-me-testing/steps-v/step-v-01-validate.md +0 -263
- package/_bmad/tea/workflows/testarch/bmad-teach-me-testing/templates/certificate-template.md +0 -86
- package/_bmad/tea/workflows/testarch/bmad-teach-me-testing/templates/progress-template.yaml +0 -95
- package/_bmad/tea/workflows/testarch/bmad-teach-me-testing/templates/session-notes-template.md +0 -83
- package/_bmad/tea/workflows/testarch/bmad-teach-me-testing/workflow-plan-teach-me-testing.md +0 -950
- package/_bmad/tea/workflows/testarch/bmad-teach-me-testing/workflow.md +0 -90
- package/_bmad/tea/workflows/testarch/bmad-testarch-atdd/SKILL.md +0 -6
- package/_bmad/tea/workflows/testarch/bmad-testarch-atdd/atdd-checklist-template.md +0 -371
- package/_bmad/tea/workflows/testarch/bmad-testarch-atdd/bmad-skill-manifest.yaml +0 -1
- package/_bmad/tea/workflows/testarch/bmad-testarch-atdd/checklist.md +0 -374
- package/_bmad/tea/workflows/testarch/bmad-testarch-atdd/instructions.md +0 -45
- package/_bmad/tea/workflows/testarch/bmad-testarch-atdd/steps-c/step-01-preflight-and-context.md +0 -226
- package/_bmad/tea/workflows/testarch/bmad-testarch-atdd/steps-c/step-01b-resume.md +0 -96
- package/_bmad/tea/workflows/testarch/bmad-testarch-atdd/steps-c/step-02-generation-mode.md +0 -125
- package/_bmad/tea/workflows/testarch/bmad-testarch-atdd/steps-c/step-03-test-strategy.md +0 -110
- package/_bmad/tea/workflows/testarch/bmad-testarch-atdd/steps-c/step-04-generate-tests.md +0 -334
- package/_bmad/tea/workflows/testarch/bmad-testarch-atdd/steps-c/step-04a-subagent-api-failing.md +0 -286
- package/_bmad/tea/workflows/testarch/bmad-testarch-atdd/steps-c/step-04b-subagent-e2e-failing.md +0 -244
- package/_bmad/tea/workflows/testarch/bmad-testarch-atdd/steps-c/step-04c-aggregate.md +0 -370
- package/_bmad/tea/workflows/testarch/bmad-testarch-atdd/steps-c/step-05-validate-and-complete.md +0 -106
- package/_bmad/tea/workflows/testarch/bmad-testarch-atdd/steps-e/step-01-assess.md +0 -65
- package/_bmad/tea/workflows/testarch/bmad-testarch-atdd/steps-e/step-02-apply-edit.md +0 -60
- package/_bmad/tea/workflows/testarch/bmad-testarch-atdd/steps-v/step-01-validate.md +0 -67
- package/_bmad/tea/workflows/testarch/bmad-testarch-atdd/validation-report-20260127-095021.md +0 -73
- package/_bmad/tea/workflows/testarch/bmad-testarch-atdd/validation-report-20260127-102401.md +0 -116
- package/_bmad/tea/workflows/testarch/bmad-testarch-atdd/workflow-plan.md +0 -21
- package/_bmad/tea/workflows/testarch/bmad-testarch-atdd/workflow.md +0 -41
- package/_bmad/tea/workflows/testarch/bmad-testarch-atdd/workflow.yaml +0 -46
- package/_bmad/tea/workflows/testarch/bmad-testarch-automate/SKILL.md +0 -6
- package/_bmad/tea/workflows/testarch/bmad-testarch-automate/bmad-skill-manifest.yaml +0 -1
- package/_bmad/tea/workflows/testarch/bmad-testarch-automate/checklist.md +0 -611
- package/_bmad/tea/workflows/testarch/bmad-testarch-automate/instructions.md +0 -50
- package/_bmad/tea/workflows/testarch/bmad-testarch-automate/steps-c/step-01-preflight-and-context.md +0 -237
- package/_bmad/tea/workflows/testarch/bmad-testarch-automate/steps-c/step-01b-resume.md +0 -94
- package/_bmad/tea/workflows/testarch/bmad-testarch-automate/steps-c/step-02-identify-targets.md +0 -169
- package/_bmad/tea/workflows/testarch/bmad-testarch-automate/steps-c/step-03-generate-tests.md +0 -394
- package/_bmad/tea/workflows/testarch/bmad-testarch-automate/steps-c/step-03a-subagent-api.md +0 -263
- package/_bmad/tea/workflows/testarch/bmad-testarch-automate/steps-c/step-03b-subagent-backend.md +0 -246
- package/_bmad/tea/workflows/testarch/bmad-testarch-automate/steps-c/step-03b-subagent-e2e.md +0 -213
- package/_bmad/tea/workflows/testarch/bmad-testarch-automate/steps-c/step-03c-aggregate.md +0 -393
- package/_bmad/tea/workflows/testarch/bmad-testarch-automate/steps-c/step-04-validate-and-summarize.md +0 -106
- package/_bmad/tea/workflows/testarch/bmad-testarch-automate/steps-e/step-01-assess.md +0 -65
- package/_bmad/tea/workflows/testarch/bmad-testarch-automate/steps-e/step-02-apply-edit.md +0 -60
- package/_bmad/tea/workflows/testarch/bmad-testarch-automate/steps-v/step-01-validate.md +0 -67
- package/_bmad/tea/workflows/testarch/bmad-testarch-automate/validation-report-20260127-095021.md +0 -72
- package/_bmad/tea/workflows/testarch/bmad-testarch-automate/validation-report-20260127-102401.md +0 -114
- package/_bmad/tea/workflows/testarch/bmad-testarch-automate/workflow-plan.md +0 -20
- package/_bmad/tea/workflows/testarch/bmad-testarch-automate/workflow.md +0 -41
- package/_bmad/tea/workflows/testarch/bmad-testarch-automate/workflow.yaml +0 -53
- package/_bmad/tea/workflows/testarch/bmad-testarch-ci/SKILL.md +0 -6
- package/_bmad/tea/workflows/testarch/bmad-testarch-ci/azure-pipelines-template.yaml +0 -155
- package/_bmad/tea/workflows/testarch/bmad-testarch-ci/bmad-skill-manifest.yaml +0 -1
- package/_bmad/tea/workflows/testarch/bmad-testarch-ci/checklist.md +0 -289
- package/_bmad/tea/workflows/testarch/bmad-testarch-ci/github-actions-template.yaml +0 -328
- package/_bmad/tea/workflows/testarch/bmad-testarch-ci/gitlab-ci-template.yaml +0 -158
- package/_bmad/tea/workflows/testarch/bmad-testarch-ci/harness-pipeline-template.yaml +0 -159
- package/_bmad/tea/workflows/testarch/bmad-testarch-ci/instructions.md +0 -45
- package/_bmad/tea/workflows/testarch/bmad-testarch-ci/jenkins-pipeline-template.groovy +0 -129
- package/_bmad/tea/workflows/testarch/bmad-testarch-ci/steps-c/step-01-preflight.md +0 -158
- package/_bmad/tea/workflows/testarch/bmad-testarch-ci/steps-c/step-01b-resume.md +0 -110
- package/_bmad/tea/workflows/testarch/bmad-testarch-ci/steps-c/step-02-generate-pipeline.md +0 -279
- package/_bmad/tea/workflows/testarch/bmad-testarch-ci/steps-c/step-03-configure-quality-gates.md +0 -135
- package/_bmad/tea/workflows/testarch/bmad-testarch-ci/steps-c/step-04-validate-and-summary.md +0 -92
- package/_bmad/tea/workflows/testarch/bmad-testarch-ci/steps-e/step-01-assess.md +0 -65
- package/_bmad/tea/workflows/testarch/bmad-testarch-ci/steps-e/step-02-apply-edit.md +0 -60
- package/_bmad/tea/workflows/testarch/bmad-testarch-ci/steps-v/step-01-validate.md +0 -81
- package/_bmad/tea/workflows/testarch/bmad-testarch-ci/validation-report-20260127-095021.md +0 -72
- package/_bmad/tea/workflows/testarch/bmad-testarch-ci/validation-report-20260127-102401.md +0 -114
- package/_bmad/tea/workflows/testarch/bmad-testarch-ci/workflow-plan.md +0 -20
- package/_bmad/tea/workflows/testarch/bmad-testarch-ci/workflow.md +0 -41
- package/_bmad/tea/workflows/testarch/bmad-testarch-ci/workflow.yaml +0 -48
- package/_bmad/tea/workflows/testarch/bmad-testarch-framework/SKILL.md +0 -6
- package/_bmad/tea/workflows/testarch/bmad-testarch-framework/bmad-skill-manifest.yaml +0 -1
- package/_bmad/tea/workflows/testarch/bmad-testarch-framework/checklist.md +0 -345
- package/_bmad/tea/workflows/testarch/bmad-testarch-framework/instructions.md +0 -45
- package/_bmad/tea/workflows/testarch/bmad-testarch-framework/steps-c/step-01-preflight.md +0 -132
- package/_bmad/tea/workflows/testarch/bmad-testarch-framework/steps-c/step-01b-resume.md +0 -116
- package/_bmad/tea/workflows/testarch/bmad-testarch-framework/steps-c/step-02-select-framework.md +0 -117
- package/_bmad/tea/workflows/testarch/bmad-testarch-framework/steps-c/step-03-scaffold-framework.md +0 -323
- package/_bmad/tea/workflows/testarch/bmad-testarch-framework/steps-c/step-04-docs-and-scripts.md +0 -105
- package/_bmad/tea/workflows/testarch/bmad-testarch-framework/steps-c/step-05-validate-and-summary.md +0 -93
- package/_bmad/tea/workflows/testarch/bmad-testarch-framework/steps-e/step-01-assess.md +0 -65
- package/_bmad/tea/workflows/testarch/bmad-testarch-framework/steps-e/step-02-apply-edit.md +0 -60
- package/_bmad/tea/workflows/testarch/bmad-testarch-framework/steps-v/step-01-validate.md +0 -67
- package/_bmad/tea/workflows/testarch/bmad-testarch-framework/validation-report-20260127-095021.md +0 -73
- package/_bmad/tea/workflows/testarch/bmad-testarch-framework/validation-report-20260127-102401.md +0 -116
- package/_bmad/tea/workflows/testarch/bmad-testarch-framework/workflow-plan.md +0 -22
- package/_bmad/tea/workflows/testarch/bmad-testarch-framework/workflow.md +0 -41
- package/_bmad/tea/workflows/testarch/bmad-testarch-framework/workflow.yaml +0 -48
- package/_bmad/tea/workflows/testarch/bmad-testarch-nfr/SKILL.md +0 -6
- package/_bmad/tea/workflows/testarch/bmad-testarch-nfr/bmad-skill-manifest.yaml +0 -1
- package/_bmad/tea/workflows/testarch/bmad-testarch-nfr/checklist.md +0 -407
- package/_bmad/tea/workflows/testarch/bmad-testarch-nfr/instructions.md +0 -43
- package/_bmad/tea/workflows/testarch/bmad-testarch-nfr/nfr-report-template.md +0 -470
- package/_bmad/tea/workflows/testarch/bmad-testarch-nfr/steps-c/step-01-load-context.md +0 -138
- package/_bmad/tea/workflows/testarch/bmad-testarch-nfr/steps-c/step-01b-resume.md +0 -106
- package/_bmad/tea/workflows/testarch/bmad-testarch-nfr/steps-c/step-02-define-thresholds.md +0 -107
- package/_bmad/tea/workflows/testarch/bmad-testarch-nfr/steps-c/step-03-gather-evidence.md +0 -108
- package/_bmad/tea/workflows/testarch/bmad-testarch-nfr/steps-c/step-04-evaluate-and-score.md +0 -254
- package/_bmad/tea/workflows/testarch/bmad-testarch-nfr/steps-c/step-04a-subagent-security.md +0 -138
- package/_bmad/tea/workflows/testarch/bmad-testarch-nfr/steps-c/step-04b-subagent-performance.md +0 -84
- package/_bmad/tea/workflows/testarch/bmad-testarch-nfr/steps-c/step-04c-subagent-reliability.md +0 -85
- package/_bmad/tea/workflows/testarch/bmad-testarch-nfr/steps-c/step-04d-subagent-scalability.md +0 -88
- package/_bmad/tea/workflows/testarch/bmad-testarch-nfr/steps-c/step-04e-aggregate-nfr.md +0 -264
- package/_bmad/tea/workflows/testarch/bmad-testarch-nfr/steps-c/step-05-generate-report.md +0 -108
- package/_bmad/tea/workflows/testarch/bmad-testarch-nfr/steps-e/step-01-assess.md +0 -65
- package/_bmad/tea/workflows/testarch/bmad-testarch-nfr/steps-e/step-02-apply-edit.md +0 -60
- package/_bmad/tea/workflows/testarch/bmad-testarch-nfr/steps-v/step-01-validate.md +0 -67
- package/_bmad/tea/workflows/testarch/bmad-testarch-nfr/validation-report-20260127-095021.md +0 -73
- package/_bmad/tea/workflows/testarch/bmad-testarch-nfr/validation-report-20260127-102401.md +0 -116
- package/_bmad/tea/workflows/testarch/bmad-testarch-nfr/workflow-plan.md +0 -19
- package/_bmad/tea/workflows/testarch/bmad-testarch-nfr/workflow.md +0 -41
- package/_bmad/tea/workflows/testarch/bmad-testarch-nfr/workflow.yaml +0 -48
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-design/SKILL.md +0 -6
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-design/bmad-skill-manifest.yaml +0 -1
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-design/checklist.md +0 -464
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-design/instructions.md +0 -105
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-design/steps-c/step-01-detect-mode.md +0 -134
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-design/steps-c/step-01b-resume.md +0 -102
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-design/steps-c/step-02-load-context.md +0 -242
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-design/steps-c/step-03-risk-and-testability.md +0 -110
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-design/steps-c/step-04-coverage-plan.md +0 -123
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-design/steps-c/step-05-generate-output.md +0 -222
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-design/steps-e/step-01-assess.md +0 -65
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-design/steps-e/step-02-apply-edit.md +0 -60
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-design/steps-v/step-01-validate.md +0 -67
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-design/test-design-architecture-template.md +0 -230
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-design/test-design-handoff-template.md +0 -70
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-design/test-design-qa-template.md +0 -396
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-design/test-design-template.md +0 -344
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-design/validation-report-20260127-095021.md +0 -73
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-design/validation-report-20260127-102401.md +0 -116
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-design/workflow-plan.md +0 -22
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-design/workflow.md +0 -41
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-design/workflow.yaml +0 -77
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-review/SKILL.md +0 -6
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-review/bmad-skill-manifest.yaml +0 -1
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-review/checklist.md +0 -475
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-review/instructions.md +0 -45
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-review/steps-c/step-01-load-context.md +0 -197
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-review/steps-c/step-01b-resume.md +0 -104
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-review/steps-c/step-02-discover-tests.md +0 -113
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-review/steps-c/step-03-quality-evaluation.md +0 -274
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-review/steps-c/step-03a-subagent-determinism.md +0 -214
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-review/steps-c/step-03b-subagent-isolation.md +0 -125
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-review/steps-c/step-03c-subagent-maintainability.md +0 -102
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-review/steps-c/step-03e-subagent-performance.md +0 -117
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-review/steps-c/step-03f-aggregate-scores.md +0 -277
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-review/steps-c/step-04-generate-report.md +0 -111
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-review/steps-e/step-01-assess.md +0 -65
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-review/steps-e/step-02-apply-edit.md +0 -60
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-review/steps-v/step-01-validate.md +0 -67
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-review/test-review-template.md +0 -387
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-review/validation-report-20260127-095021.md +0 -72
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-review/validation-report-20260127-102401.md +0 -114
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-review/workflow-plan.md +0 -18
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-review/workflow.md +0 -41
- package/_bmad/tea/workflows/testarch/bmad-testarch-test-review/workflow.yaml +0 -48
- package/_bmad/tea/workflows/testarch/bmad-testarch-trace/SKILL.md +0 -6
- package/_bmad/tea/workflows/testarch/bmad-testarch-trace/bmad-skill-manifest.yaml +0 -1
- package/_bmad/tea/workflows/testarch/bmad-testarch-trace/checklist.md +0 -647
- package/_bmad/tea/workflows/testarch/bmad-testarch-trace/instructions.md +0 -43
- package/_bmad/tea/workflows/testarch/bmad-testarch-trace/steps-c/step-01-load-context.md +0 -105
- package/_bmad/tea/workflows/testarch/bmad-testarch-trace/steps-c/step-01b-resume.md +0 -102
- package/_bmad/tea/workflows/testarch/bmad-testarch-trace/steps-c/step-02-discover-tests.md +0 -112
- package/_bmad/tea/workflows/testarch/bmad-testarch-trace/steps-c/step-03-map-criteria.md +0 -97
- package/_bmad/tea/workflows/testarch/bmad-testarch-trace/steps-c/step-04-analyze-gaps.md +0 -421
- package/_bmad/tea/workflows/testarch/bmad-testarch-trace/steps-c/step-05-gate-decision.md +0 -266
- package/_bmad/tea/workflows/testarch/bmad-testarch-trace/steps-e/step-01-assess.md +0 -65
- package/_bmad/tea/workflows/testarch/bmad-testarch-trace/steps-e/step-02-apply-edit.md +0 -60
- package/_bmad/tea/workflows/testarch/bmad-testarch-trace/steps-v/step-01-validate.md +0 -67
- package/_bmad/tea/workflows/testarch/bmad-testarch-trace/trace-template.md +0 -708
- package/_bmad/tea/workflows/testarch/bmad-testarch-trace/validation-report-20260127-095021.md +0 -73
- package/_bmad/tea/workflows/testarch/bmad-testarch-trace/validation-report-20260127-102401.md +0 -116
- package/_bmad/tea/workflows/testarch/bmad-testarch-trace/workflow-plan.md +0 -21
- package/_bmad/tea/workflows/testarch/bmad-testarch-trace/workflow.md +0 -41
- package/_bmad/tea/workflows/testarch/bmad-testarch-trace/workflow.yaml +0 -56
- package/eslint.config.js +0 -38
- package/packages/client/index.html +0 -12
- package/packages/client/package.json +0 -46
- package/packages/client/src/app.tsx +0 -57
- package/packages/client/src/features/about/AboutPage.tsx +0 -144
- package/packages/client/src/features/agents/AgentCard.tsx +0 -52
- package/packages/client/src/features/agents/AgentDetail.tsx +0 -338
- package/packages/client/src/features/agents/AgentOverrideEditor.tsx +0 -127
- package/packages/client/src/features/agents/AgentsPage.tsx +0 -114
- package/packages/client/src/features/agents/EditAgentDialog.tsx +0 -260
- package/packages/client/src/features/agents/SkillAssignment.tsx +0 -153
- package/packages/client/src/features/agents/use-agent-detail.ts +0 -17
- package/packages/client/src/features/agents/use-agent-mutations.ts +0 -47
- package/packages/client/src/features/agents/use-agents.ts +0 -17
- package/packages/client/src/features/connections/ConnectionsPage.tsx +0 -165
- package/packages/client/src/features/files/FilesPage.tsx +0 -177
- package/packages/client/src/features/outputs/OutputsPage.tsx +0 -190
- package/packages/client/src/features/overview/OverviewPage.tsx +0 -282
- package/packages/client/src/features/packages/EditModuleDialog.tsx +0 -118
- package/packages/client/src/features/packages/PackagesPage.tsx +0 -982
- package/packages/client/src/features/settings/SettingsPage.tsx +0 -141
- package/packages/client/src/features/settings/use-settings.ts +0 -34
- package/packages/client/src/features/skills/CreateSkillDialog.tsx +0 -328
- package/packages/client/src/features/skills/SkillDetailSlideOver.tsx +0 -179
- package/packages/client/src/features/skills/SkillsPage.tsx +0 -142
- package/packages/client/src/features/skills/use-skills.ts +0 -27
- package/packages/client/src/features/teams/CreateTeamDialog.tsx +0 -239
- package/packages/client/src/features/teams/TeamDetailPanel.tsx +0 -549
- package/packages/client/src/features/teams/TeamsPage.tsx +0 -196
- package/packages/client/src/features/teams/use-teams.ts +0 -39
- package/packages/client/src/features/workflows/CreateWorkflowDialog.tsx +0 -395
- package/packages/client/src/features/workflows/EditWorkflowDialog.tsx +0 -131
- package/packages/client/src/features/workflows/WorkflowDetailPanel.tsx +0 -503
- package/packages/client/src/features/workflows/WorkflowGraph.tsx +0 -108
- package/packages/client/src/features/workflows/WorkflowsPage.tsx +0 -277
- package/packages/client/src/features/workflows/use-workflows.ts +0 -27
- package/packages/client/src/features/workspace/WorkspacePage.tsx +0 -304
- package/packages/client/src/globals.css +0 -184
- package/packages/client/src/hooks/use-detail-param.ts +0 -31
- package/packages/client/src/hooks/use-file-save.ts +0 -22
- package/packages/client/src/hooks/use-websocket.ts +0 -38
- package/packages/client/src/layout/AppShell.tsx +0 -20
- package/packages/client/src/layout/Breadcrumbs.tsx +0 -52
- package/packages/client/src/layout/NotificationProvider.tsx +0 -95
- package/packages/client/src/layout/Sidebar.tsx +0 -176
- package/packages/client/src/lib/theme.ts +0 -30
- package/packages/client/src/lib/websocket-client.ts +0 -97
- package/packages/client/src/main.tsx +0 -14
- package/packages/client/src/shared/CommandPalette.tsx +0 -151
- package/packages/client/src/shared/CsvViewer.tsx +0 -120
- package/packages/client/src/shared/EmptyState.tsx +0 -20
- package/packages/client/src/shared/EntityPageHeader.tsx +0 -95
- package/packages/client/src/shared/FilepathLink.tsx +0 -22
- package/packages/client/src/shared/Skeleton.tsx +0 -31
- package/packages/client/src/shared/SlideOver.tsx +0 -63
- package/packages/client/src/shared/VocabularyHelper.tsx +0 -48
- package/packages/client/src/shared/diff-viewer/DiffViewer.tsx +0 -93
- package/packages/client/src/shared/markdown-editor/CodeMirrorEditor.tsx +0 -199
- package/packages/client/src/shared/markdown-editor/MarkdownEditor.tsx +0 -95
- package/packages/client/src/stores/ui-store.ts +0 -13
- package/packages/client/tsconfig.json +0 -13
- package/packages/client/vite.config.ts +0 -20
- package/packages/server/package.json +0 -30
- package/packages/server/src/app.test.ts +0 -89
- package/packages/server/src/app.ts +0 -101
- package/packages/server/src/core/errors.test.ts +0 -49
- package/packages/server/src/core/errors.ts +0 -62
- package/packages/server/src/core/file-store.test.ts +0 -104
- package/packages/server/src/core/file-store.ts +0 -209
- package/packages/server/src/core/project-detector.test.ts +0 -94
- package/packages/server/src/core/project-detector.ts +0 -97
- package/packages/server/src/core/websocket.test.ts +0 -80
- package/packages/server/src/core/websocket.ts +0 -47
- package/packages/server/src/core/write-service.test.ts +0 -87
- package/packages/server/src/core/write-service.ts +0 -75
- package/packages/server/src/index.ts +0 -97
- package/packages/server/src/parsers/agent-parser.test.ts +0 -71
- package/packages/server/src/parsers/agent-parser.ts +0 -83
- package/packages/server/src/parsers/config-parser.test.ts +0 -65
- package/packages/server/src/parsers/config-parser.ts +0 -51
- package/packages/server/src/parsers/csv-parser.test.ts +0 -53
- package/packages/server/src/parsers/csv-parser.ts +0 -55
- package/packages/server/src/parsers/ide-config-parser.test.ts +0 -35
- package/packages/server/src/parsers/ide-config-parser.ts +0 -37
- package/packages/server/src/parsers/index-builder.test.ts +0 -78
- package/packages/server/src/parsers/index-builder.ts +0 -195
- package/packages/server/src/parsers/package-parser.test.ts +0 -36
- package/packages/server/src/parsers/package-parser.ts +0 -34
- package/packages/server/src/parsers/skill-parser.test.ts +0 -51
- package/packages/server/src/parsers/skill-parser.ts +0 -26
- package/packages/server/src/parsers/team-parser.test.ts +0 -186
- package/packages/server/src/parsers/team-parser.ts +0 -128
- package/packages/server/src/parsers/workflow-parser.test.ts +0 -415
- package/packages/server/src/parsers/workflow-parser.ts +0 -311
- package/packages/server/src/plugins/agents-plugin.test.ts +0 -111
- package/packages/server/src/plugins/agents-plugin.ts +0 -164
- package/packages/server/src/plugins/files-plugin.test.ts +0 -121
- package/packages/server/src/plugins/files-plugin.ts +0 -93
- package/packages/server/src/plugins/modules-plugin.test.ts +0 -264
- package/packages/server/src/plugins/modules-plugin.ts +0 -386
- package/packages/server/src/plugins/outputs-plugin.test.ts +0 -89
- package/packages/server/src/plugins/outputs-plugin.ts +0 -93
- package/packages/server/src/plugins/overview-plugin.ts +0 -73
- package/packages/server/src/plugins/search-plugin.ts +0 -63
- package/packages/server/src/plugins/settings-plugin.test.ts +0 -82
- package/packages/server/src/plugins/settings-plugin.ts +0 -46
- package/packages/server/src/plugins/skills-plugin.ts +0 -87
- package/packages/server/src/plugins/teams-plugin.test.ts +0 -157
- package/packages/server/src/plugins/teams-plugin.ts +0 -198
- package/packages/server/src/plugins/validation-plugin.test.ts +0 -229
- package/packages/server/src/plugins/validation-plugin.ts +0 -116
- package/packages/server/src/plugins/workflows-plugin.test.ts +0 -145
- package/packages/server/src/plugins/workflows-plugin.ts +0 -270
- package/packages/server/src/static.ts +0 -29
- package/packages/server/tsconfig.json +0 -8
- package/packages/shared/package.json +0 -20
- package/packages/shared/tsconfig.json +0 -8
- package/tsconfig.base.json +0 -19
- package/vitest.config.ts +0 -7
|
@@ -0,0 +1,1313 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import os from 'node:os';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { execSync, spawnSync } from 'node:child_process';
|
|
5
|
+
import yaml from 'js-yaml';
|
|
6
|
+
import { ValidationError, ConflictError, NotFoundError } from '../core/errors.js';
|
|
7
|
+
import { fetchAndCacheRegistryIndex, isRegistryCacheStale, readCachedRegistryIndex, } from '../core/module-registry.js';
|
|
8
|
+
import { generateIdeSkillsForModule, removeIdeSkillsForModule, scanEntities, scanEntityDirs, } from '../core/ide-skill-generator.js';
|
|
9
|
+
import { copyDirThroughWriteService, downloadGithubTarball, extractZipUpload, findCrossReferences, isPlausibleModuleDir, parseGithubSource, readManifestSafe, readOutputFolder, runVariableSubstitution, validateVariables, writeManifestThroughWriteService, } from '../core/module-installer.js';
|
|
10
|
+
import { deleteDirectory, writeFile } from '../core/write-service.js';
|
|
11
|
+
import { parseModuleYaml } from '../parsers/module-yaml-parser.js';
|
|
12
|
+
const MODULE_NAME_RE = /^[a-z][a-z0-9-]*$/;
|
|
13
|
+
export async function modulesPlugin(app) {
|
|
14
|
+
const PREVIEW_CACHE_TTL_MS = 5 * 60 * 1000;
|
|
15
|
+
const previewCache = new Map();
|
|
16
|
+
function previewCacheKey(ghSource) {
|
|
17
|
+
return `${ghSource.owner}/${ghSource.repo}@${ghSource.branch ?? 'main'}${ghSource.subpath ? `/${ghSource.subpath}` : ''}`;
|
|
18
|
+
}
|
|
19
|
+
function getPreviewCacheEntry(key) {
|
|
20
|
+
const entry = previewCache.get(key);
|
|
21
|
+
if (!entry)
|
|
22
|
+
return null;
|
|
23
|
+
if (Date.now() - entry.fetchedAt > PREVIEW_CACHE_TTL_MS) {
|
|
24
|
+
try {
|
|
25
|
+
fs.rmSync(entry.tmpDir, { recursive: true, force: true });
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
/* ignore cleanup errors */
|
|
29
|
+
}
|
|
30
|
+
previewCache.delete(key);
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
return entry;
|
|
34
|
+
}
|
|
35
|
+
// Story 17.3 — Clean-slate remove helper. Called by each install branch when
|
|
36
|
+
// the destination directory already exists so the install can proceed as a
|
|
37
|
+
// silent upgrade rather than throwing 409.
|
|
38
|
+
// Throws ValidationError if the module is built-in (cannot be replaced) or
|
|
39
|
+
// if any I/O step fails. Safe to call when the module dir doesn't exist yet
|
|
40
|
+
// (all steps guard with existsSync / nullish checks).
|
|
41
|
+
function cleanRemoveModule(moduleCode, bmadDir, manifestPath) {
|
|
42
|
+
const moduleDir = path.join(bmadDir, moduleCode);
|
|
43
|
+
const manifest = readManifestSafe(manifestPath);
|
|
44
|
+
const entry = manifest?.modules.find((m) => m.name === moduleCode);
|
|
45
|
+
if (entry?.source === 'built-in') {
|
|
46
|
+
throw new ValidationError(`Cannot reinstall built-in module "${moduleCode}"`);
|
|
47
|
+
}
|
|
48
|
+
// 1. Remove IDE skill launchers
|
|
49
|
+
if (manifest) {
|
|
50
|
+
const r = removeIdeSkillsForModule(app.fileStore.projectRoot, moduleCode, manifest, app.fileStore.studioDir);
|
|
51
|
+
if (!r.ok)
|
|
52
|
+
throw new ValidationError(r.error);
|
|
53
|
+
}
|
|
54
|
+
// 2. Delete the module directory
|
|
55
|
+
if (fs.existsSync(moduleDir)) {
|
|
56
|
+
const r = deleteDirectory(moduleDir, app.fileStore.studioDir);
|
|
57
|
+
if (!r.ok)
|
|
58
|
+
throw new ValidationError(r.error);
|
|
59
|
+
}
|
|
60
|
+
// 3. Remove the manifest entry so the incoming install writes a fresh one
|
|
61
|
+
if (manifest) {
|
|
62
|
+
manifest.modules = manifest.modules.filter((m) => m.name !== moduleCode);
|
|
63
|
+
const wrote = writeManifestThroughWriteService(manifestPath, manifest, app.fileStore.studioDir, app.fileStore);
|
|
64
|
+
if (!wrote.ok)
|
|
65
|
+
throw new ValidationError(wrote.error);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// Story 15.9 — Read-only preview endpoint. Fetches a source (local or github)
|
|
69
|
+
// and returns the parsed module.yaml + entity counts WITHOUT installing anything.
|
|
70
|
+
// For github sources, the downloaded tarball is cached for 5 minutes so the
|
|
71
|
+
// subsequent install call can reuse it without re-downloading.
|
|
72
|
+
app.post('/api/modules/preview-source', async (request) => {
|
|
73
|
+
if (!('fileStore' in app)) {
|
|
74
|
+
throw new ValidationError('No project detected');
|
|
75
|
+
}
|
|
76
|
+
const body = request.body;
|
|
77
|
+
const source = body?.source;
|
|
78
|
+
if (!source || !source.type || !source.value) {
|
|
79
|
+
throw new ValidationError('Request body must include { source: { type, value } }');
|
|
80
|
+
}
|
|
81
|
+
let stagedRoot;
|
|
82
|
+
if (source.type === 'local') {
|
|
83
|
+
stagedRoot = path.isAbsolute(source.value)
|
|
84
|
+
? source.value
|
|
85
|
+
: path.join(app.fileStore.projectRoot, source.value);
|
|
86
|
+
}
|
|
87
|
+
else if (source.type === 'github') {
|
|
88
|
+
let ghSource;
|
|
89
|
+
try {
|
|
90
|
+
ghSource = parseGithubSource(source.value);
|
|
91
|
+
}
|
|
92
|
+
catch (err) {
|
|
93
|
+
throw new ValidationError(err instanceof Error ? err.message : String(err));
|
|
94
|
+
}
|
|
95
|
+
const cacheKey = previewCacheKey(ghSource);
|
|
96
|
+
let entry = getPreviewCacheEntry(cacheKey);
|
|
97
|
+
if (!entry) {
|
|
98
|
+
let downloaded;
|
|
99
|
+
try {
|
|
100
|
+
downloaded = await downloadGithubTarball(ghSource);
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
throw new ValidationError(err instanceof Error ? err.message : String(err));
|
|
104
|
+
}
|
|
105
|
+
entry = {
|
|
106
|
+
extractedRoot: downloaded.extractedRoot,
|
|
107
|
+
tmpDir: downloaded.tmpDir,
|
|
108
|
+
resolvedBranch: downloaded.resolvedBranch,
|
|
109
|
+
fetchedAt: Date.now(),
|
|
110
|
+
};
|
|
111
|
+
previewCache.set(cacheKey, entry);
|
|
112
|
+
}
|
|
113
|
+
stagedRoot = ghSource.subpath
|
|
114
|
+
? path.join(entry.extractedRoot, ghSource.subpath)
|
|
115
|
+
: entry.extractedRoot;
|
|
116
|
+
// Note: no try/finally cleanup here — the tmpDir lives in previewCache and is
|
|
117
|
+
// cleaned up on TTL expiry or when the install endpoint consumes it.
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
throw new ValidationError(`preview-source does not support source type "${source.type}". Use "local" or "github".`);
|
|
121
|
+
}
|
|
122
|
+
if (!isPlausibleModuleDir(stagedRoot)) {
|
|
123
|
+
throw new ValidationError('Source does not look like a BMAD module — expected module.yaml or one of agents/skills/workflows/tasks');
|
|
124
|
+
}
|
|
125
|
+
const parsed = parseModuleYaml(stagedRoot);
|
|
126
|
+
if (!parsed.ok)
|
|
127
|
+
throw new ValidationError(parsed.error);
|
|
128
|
+
const counts = {
|
|
129
|
+
agents: scanEntities(path.join(stagedRoot, 'agents'), '.md').length,
|
|
130
|
+
workflows: scanEntityDirs(path.join(stagedRoot, 'workflows')).length,
|
|
131
|
+
tasks: scanEntityDirs(path.join(stagedRoot, 'tasks')).length,
|
|
132
|
+
};
|
|
133
|
+
const bmadDir = path.join(app.fileStore.projectRoot, '_bmad');
|
|
134
|
+
const existingDir = path.join(bmadDir, parsed.data.code);
|
|
135
|
+
const willReplace = fs.existsSync(existingDir);
|
|
136
|
+
return { ok: true, moduleYaml: parsed.data, counts, willReplace };
|
|
137
|
+
});
|
|
138
|
+
// Polymorphic install endpoint — accepts npm | local | github source types via
|
|
139
|
+
// { source: { type, value }, variables? }, plus the legacy { packageName } shape.
|
|
140
|
+
// Zip uploads go to a separate multipart route POST /api/modules/install/upload (Story 15.4).
|
|
141
|
+
app.post('/api/modules/install', async (request, reply) => {
|
|
142
|
+
if (!('fileStore' in app)) {
|
|
143
|
+
throw new ValidationError('No project detected');
|
|
144
|
+
}
|
|
145
|
+
const body = request.body;
|
|
146
|
+
// Defensive guard: if the request body is missing (e.g. a multipart upload sent
|
|
147
|
+
// to this JSON-only route — multipart goes to /upload), fail loudly with a 422
|
|
148
|
+
// instead of an unhandled TypeError. AC-15.4.11.
|
|
149
|
+
if (!body || typeof body !== 'object') {
|
|
150
|
+
throw new ValidationError('Request body must be JSON. For zip uploads, POST to /api/modules/install/upload instead.');
|
|
151
|
+
}
|
|
152
|
+
// TD-22 — discriminate source vs legacy. Prefer `source` if both are present.
|
|
153
|
+
let source;
|
|
154
|
+
if (body.source) {
|
|
155
|
+
source = body.source;
|
|
156
|
+
if (body.packageName) {
|
|
157
|
+
request.log.warn({ packageName: body.packageName }, 'Both `source` and `packageName` provided to /api/modules/install — using `source`');
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
else if (body.packageName) {
|
|
161
|
+
const pkg = body.packageName.trim();
|
|
162
|
+
if (!pkg) {
|
|
163
|
+
throw new ValidationError('Package name is required');
|
|
164
|
+
}
|
|
165
|
+
source = { type: 'npm', value: pkg };
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
throw new ValidationError('Either `source` or `packageName` is required');
|
|
169
|
+
}
|
|
170
|
+
// Story 15.5 — variables are now consumed (not just threaded through).
|
|
171
|
+
const variables = body.variables ?? {};
|
|
172
|
+
const bmadDir = path.join(app.fileStore.projectRoot, '_bmad');
|
|
173
|
+
const manifestPath = path.join(bmadDir, '_config', 'manifest.yaml');
|
|
174
|
+
// Hard requirement (AC-15.2.9 / finding #8): every install branch needs an existing manifest.
|
|
175
|
+
// Without it, the installed module would be invisible to GET /api/modules.
|
|
176
|
+
if (!fs.existsSync(manifestPath)) {
|
|
177
|
+
throw new ValidationError('Cannot install module: missing _bmad/_config/manifest.yaml. Run `npx bmad-method install` to initialise the project first.');
|
|
178
|
+
}
|
|
179
|
+
// Story 15.5 — validate variables BEFORE any source-type branching so bad input
|
|
180
|
+
// fails fast without wasting CPU on a download/extraction.
|
|
181
|
+
const varValidation = validateVariables(variables);
|
|
182
|
+
if (!varValidation.ok)
|
|
183
|
+
throw new ValidationError(varValidation.error);
|
|
184
|
+
// Helper to build the substitution context for a given module code. Used by every branch.
|
|
185
|
+
const makeSubContext = (moduleCode) => ({
|
|
186
|
+
moduleCode,
|
|
187
|
+
projectRoot: app.fileStore.projectRoot,
|
|
188
|
+
outputFolder: readOutputFolder(app.fileStore.projectRoot),
|
|
189
|
+
variables,
|
|
190
|
+
});
|
|
191
|
+
// Helper to run the IDE skill generator for a freshly-installed module and
|
|
192
|
+
// return per-IDE counts for the response shape (Story 15.6 / AC-15.6.8).
|
|
193
|
+
// Re-reads the manifest to get the latest `ides[]` after the manifest update.
|
|
194
|
+
const runGenerator = (moduleCode) => {
|
|
195
|
+
const updatedManifest = readManifestSafe(manifestPath);
|
|
196
|
+
if (!updatedManifest)
|
|
197
|
+
return {};
|
|
198
|
+
const genResult = generateIdeSkillsForModule(app.fileStore.projectRoot, moduleCode, updatedManifest, app.fileStore.studioDir, app.fileStore);
|
|
199
|
+
if (!genResult.ok)
|
|
200
|
+
throw new ValidationError(genResult.error);
|
|
201
|
+
const counts = {};
|
|
202
|
+
for (const [ide, skills] of Object.entries(genResult.skillsByIde)) {
|
|
203
|
+
counts[ide] = skills.length;
|
|
204
|
+
}
|
|
205
|
+
return counts;
|
|
206
|
+
};
|
|
207
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
208
|
+
// local source
|
|
209
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
210
|
+
if (source.type === 'local') {
|
|
211
|
+
const sourcePath = path.isAbsolute(source.value)
|
|
212
|
+
? source.value
|
|
213
|
+
: path.join(app.fileStore.projectRoot, source.value);
|
|
214
|
+
if (!isPlausibleModuleDir(sourcePath)) {
|
|
215
|
+
throw new ValidationError(`Path "${sourcePath}" does not look like a BMAD module — expected module.yaml or one of agents/skills/workflows/tasks`);
|
|
216
|
+
}
|
|
217
|
+
const parsed = parseModuleYaml(sourcePath);
|
|
218
|
+
if (!parsed.ok)
|
|
219
|
+
throw new ValidationError(parsed.error);
|
|
220
|
+
const moduleCode = parsed.data.code;
|
|
221
|
+
const destDir = path.join(bmadDir, moduleCode);
|
|
222
|
+
// Story 17.3 — clean-slate re-install: silently remove any existing copy before writing.
|
|
223
|
+
if (fs.existsSync(destDir)) {
|
|
224
|
+
cleanRemoveModule(moduleCode, bmadDir, manifestPath);
|
|
225
|
+
}
|
|
226
|
+
const copyResult = copyDirThroughWriteService(sourcePath, destDir, app.fileStore.studioDir, app.fileStore);
|
|
227
|
+
if (!copyResult.ok)
|
|
228
|
+
throw new ValidationError(copyResult.error);
|
|
229
|
+
// Story 15.5 — substitute placeholders in installed text files BEFORE updating the manifest.
|
|
230
|
+
const subResult = runVariableSubstitution(destDir, makeSubContext(moduleCode), app.fileStore.studioDir, app.fileStore);
|
|
231
|
+
if (!subResult.ok)
|
|
232
|
+
throw new ValidationError(subResult.error);
|
|
233
|
+
// Update manifest (guaranteed to exist by the check above)
|
|
234
|
+
const manifest = readManifestSafe(manifestPath);
|
|
235
|
+
const now = new Date().toISOString();
|
|
236
|
+
const existing = manifest.modules.find((m) => m.name === moduleCode);
|
|
237
|
+
if (existing) {
|
|
238
|
+
existing.lastUpdated = now;
|
|
239
|
+
existing.source = 'local';
|
|
240
|
+
existing.npmPackage = null;
|
|
241
|
+
existing.repoUrl = sourcePath;
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
manifest.modules.push({
|
|
245
|
+
name: moduleCode,
|
|
246
|
+
version: parsed.data.version ?? '1.0.0',
|
|
247
|
+
installDate: now,
|
|
248
|
+
lastUpdated: now,
|
|
249
|
+
source: 'local',
|
|
250
|
+
npmPackage: null,
|
|
251
|
+
repoUrl: sourcePath,
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
const wrote = writeManifestThroughWriteService(manifestPath, manifest, app.fileStore.studioDir, app.fileStore);
|
|
255
|
+
if (!wrote.ok)
|
|
256
|
+
throw new ValidationError(wrote.error);
|
|
257
|
+
// Story 15.6 — generate IDE launchers AFTER the manifest is committed.
|
|
258
|
+
// A failure here leaves the user with an installed module + no launchers;
|
|
259
|
+
// recovery is the "Regenerate IDE skills" button (Story 15.8).
|
|
260
|
+
const skillsGenerated = runGenerator(moduleCode);
|
|
261
|
+
app.fileStore.rebuild();
|
|
262
|
+
reply.status(200);
|
|
263
|
+
return {
|
|
264
|
+
ok: true,
|
|
265
|
+
modules: [moduleCode],
|
|
266
|
+
filesCopied: { text: copyResult.textCount, binary: copyResult.binaryCount },
|
|
267
|
+
skillsGenerated,
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
271
|
+
// github source
|
|
272
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
273
|
+
if (source.type === 'github') {
|
|
274
|
+
// parseGithubSource throws plain Error on invalid input — convert to ValidationError.
|
|
275
|
+
let ghSource;
|
|
276
|
+
try {
|
|
277
|
+
ghSource = parseGithubSource(source.value);
|
|
278
|
+
}
|
|
279
|
+
catch (err) {
|
|
280
|
+
throw new ValidationError(err instanceof Error ? err.message : String(err));
|
|
281
|
+
}
|
|
282
|
+
// Story 15.9 — check previewCache before downloading. If the user clicked
|
|
283
|
+
// "Fetch" then "Install" in quick succession the tarball is already on disk;
|
|
284
|
+
// reuse it and skip the second download. Consume the cache entry (delete it)
|
|
285
|
+
// so a future preview call re-downloads fresh content.
|
|
286
|
+
const cacheKey = previewCacheKey(ghSource);
|
|
287
|
+
const cachedEntry = getPreviewCacheEntry(cacheKey);
|
|
288
|
+
let extractedRoot;
|
|
289
|
+
let tmpDir;
|
|
290
|
+
let resolvedBranch;
|
|
291
|
+
if (cachedEntry) {
|
|
292
|
+
previewCache.delete(cacheKey); // consumed — install now owns cleanup
|
|
293
|
+
extractedRoot = cachedEntry.extractedRoot;
|
|
294
|
+
tmpDir = cachedEntry.tmpDir;
|
|
295
|
+
resolvedBranch = cachedEntry.resolvedBranch;
|
|
296
|
+
}
|
|
297
|
+
else {
|
|
298
|
+
// No cache hit — download fresh.
|
|
299
|
+
let downloaded;
|
|
300
|
+
try {
|
|
301
|
+
downloaded = await downloadGithubTarball(ghSource);
|
|
302
|
+
}
|
|
303
|
+
catch (err) {
|
|
304
|
+
throw new ValidationError(err instanceof Error ? err.message : String(err));
|
|
305
|
+
}
|
|
306
|
+
extractedRoot = downloaded.extractedRoot;
|
|
307
|
+
tmpDir = downloaded.tmpDir;
|
|
308
|
+
resolvedBranch = downloaded.resolvedBranch;
|
|
309
|
+
}
|
|
310
|
+
try {
|
|
311
|
+
// Navigate to the optional subpath
|
|
312
|
+
const moduleSrc = ghSource.subpath
|
|
313
|
+
? path.join(extractedRoot, ghSource.subpath)
|
|
314
|
+
: extractedRoot;
|
|
315
|
+
if (!isPlausibleModuleDir(moduleSrc)) {
|
|
316
|
+
throw new ValidationError(`${ghSource.owner}/${ghSource.repo}${ghSource.subpath ? `/${ghSource.subpath}` : ''} does not look like a BMAD module`);
|
|
317
|
+
}
|
|
318
|
+
const parsed = parseModuleYaml(moduleSrc);
|
|
319
|
+
if (!parsed.ok)
|
|
320
|
+
throw new ValidationError(parsed.error);
|
|
321
|
+
const moduleCode = parsed.data.code;
|
|
322
|
+
const destDir = path.join(bmadDir, moduleCode);
|
|
323
|
+
// Story 17.3 — clean-slate re-install.
|
|
324
|
+
if (fs.existsSync(destDir)) {
|
|
325
|
+
cleanRemoveModule(moduleCode, bmadDir, manifestPath);
|
|
326
|
+
}
|
|
327
|
+
const copyResult = copyDirThroughWriteService(moduleSrc, destDir, app.fileStore.studioDir, app.fileStore);
|
|
328
|
+
if (!copyResult.ok)
|
|
329
|
+
throw new ValidationError(copyResult.error);
|
|
330
|
+
// Story 15.5 — substitute placeholders before manifest update
|
|
331
|
+
const subResult = runVariableSubstitution(destDir, makeSubContext(moduleCode), app.fileStore.studioDir, app.fileStore);
|
|
332
|
+
if (!subResult.ok)
|
|
333
|
+
throw new ValidationError(subResult.error);
|
|
334
|
+
// Update manifest (guaranteed to exist by the check at the top of the handler)
|
|
335
|
+
const manifest = readManifestSafe(manifestPath);
|
|
336
|
+
const now = new Date().toISOString();
|
|
337
|
+
const repoUrl = `https://github.com/${ghSource.owner}/${ghSource.repo}`;
|
|
338
|
+
const existing = manifest.modules.find((m) => m.name === moduleCode);
|
|
339
|
+
if (existing) {
|
|
340
|
+
existing.lastUpdated = now;
|
|
341
|
+
existing.source = 'github';
|
|
342
|
+
existing.repoUrl = repoUrl;
|
|
343
|
+
existing.npmPackage = null;
|
|
344
|
+
}
|
|
345
|
+
else {
|
|
346
|
+
manifest.modules.push({
|
|
347
|
+
name: moduleCode,
|
|
348
|
+
version: parsed.data.version ?? '1.0.0',
|
|
349
|
+
installDate: now,
|
|
350
|
+
lastUpdated: now,
|
|
351
|
+
source: 'github',
|
|
352
|
+
npmPackage: null,
|
|
353
|
+
repoUrl,
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
const wrote = writeManifestThroughWriteService(manifestPath, manifest, app.fileStore.studioDir, app.fileStore);
|
|
357
|
+
if (!wrote.ok)
|
|
358
|
+
throw new ValidationError(wrote.error);
|
|
359
|
+
// Story 15.6 — generate IDE launchers after manifest commit
|
|
360
|
+
const skillsGenerated = runGenerator(moduleCode);
|
|
361
|
+
app.fileStore.rebuild();
|
|
362
|
+
reply.status(200);
|
|
363
|
+
return {
|
|
364
|
+
ok: true,
|
|
365
|
+
modules: [moduleCode],
|
|
366
|
+
filesCopied: { text: copyResult.textCount, binary: copyResult.binaryCount },
|
|
367
|
+
source: { type: 'github', value: source.value, branch: resolvedBranch },
|
|
368
|
+
skillsGenerated,
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
finally {
|
|
372
|
+
try {
|
|
373
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
374
|
+
}
|
|
375
|
+
catch {
|
|
376
|
+
/* ignore cleanup errors */
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
381
|
+
// Guard: reject unknown source types before falling through to npm.
|
|
382
|
+
// The InstallSource union only allows 'npm'|'local'|'github', but the body
|
|
383
|
+
// is untyped at the HTTP boundary — 'zip' or any other string would silently
|
|
384
|
+
// run `npm pack <value>` without this check.
|
|
385
|
+
// Cast to string to sidestep TS control-flow narrowing (source is already
|
|
386
|
+
// narrowed to the npm variant by this point, so source.type === 'npm' always,
|
|
387
|
+
// but this guard provides a runtime safety net for unexpected payloads).
|
|
388
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
389
|
+
const sourceTypeStr = source.type;
|
|
390
|
+
if (sourceTypeStr !== 'npm') {
|
|
391
|
+
throw new ValidationError(`Unknown source type "${sourceTypeStr}". Valid types: local, github, npm. For zip uploads use POST /api/modules/install/upload.`);
|
|
392
|
+
}
|
|
393
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
394
|
+
// npm source — refactored to route writes through WriteService
|
|
395
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
396
|
+
const packageName = source.value;
|
|
397
|
+
// TD-20 — realpathSync resolves the macOS /var → /private/var symlink so
|
|
398
|
+
// path comparisons inside the install loop are stable.
|
|
399
|
+
const tmpDir = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), 'bmad-install-')));
|
|
400
|
+
try {
|
|
401
|
+
// 1. Download the package tarball via npm pack
|
|
402
|
+
execSync(`npm pack ${packageName} --pack-destination ${tmpDir}`, {
|
|
403
|
+
cwd: tmpDir,
|
|
404
|
+
stdio: 'pipe',
|
|
405
|
+
timeout: 60000,
|
|
406
|
+
});
|
|
407
|
+
// 2. Find the tarball file
|
|
408
|
+
const tarballs = fs.readdirSync(tmpDir).filter((f) => f.endsWith('.tgz'));
|
|
409
|
+
if (tarballs.length === 0) {
|
|
410
|
+
throw new ValidationError('No tarball downloaded');
|
|
411
|
+
}
|
|
412
|
+
const tarballPath = path.join(tmpDir, tarballs[0]);
|
|
413
|
+
// 3. Extract the tarball
|
|
414
|
+
const extractDir = path.join(tmpDir, 'extracted');
|
|
415
|
+
fs.mkdirSync(extractDir, { recursive: true });
|
|
416
|
+
execSync(`tar -xzf "${tarballPath}" -C "${extractDir}"`, {
|
|
417
|
+
cwd: tmpDir,
|
|
418
|
+
stdio: 'pipe',
|
|
419
|
+
timeout: 30000,
|
|
420
|
+
});
|
|
421
|
+
// 4. Look for _bmad/ directory inside the extracted package
|
|
422
|
+
// npm pack extracts to a 'package/' directory
|
|
423
|
+
const packageDir = path.join(extractDir, 'package');
|
|
424
|
+
const bmadSrcDir = path.join(packageDir, '_bmad');
|
|
425
|
+
if (!fs.existsSync(bmadSrcDir)) {
|
|
426
|
+
throw new ValidationError(`Package "${packageName}" does not contain a _bmad/ directory`);
|
|
427
|
+
}
|
|
428
|
+
// 5. Copy module directories from the package's _bmad/ into the project's _bmad/
|
|
429
|
+
// Routes through WriteService for text files, byte-copies binaries (TD-16).
|
|
430
|
+
const installedModules = [];
|
|
431
|
+
let totalText = 0;
|
|
432
|
+
let totalBinary = 0;
|
|
433
|
+
for (const entry of fs.readdirSync(bmadSrcDir, { withFileTypes: true })) {
|
|
434
|
+
if (entry.isDirectory() && entry.name !== '_config') {
|
|
435
|
+
const srcModuleDir = path.join(bmadSrcDir, entry.name);
|
|
436
|
+
// Read module.yaml for the authoritative module code (AC-15.2.8).
|
|
437
|
+
// Falls back to the directory name if module.yaml is absent or doesn't
|
|
438
|
+
// declare a code field — consistent with local/github/zip branches.
|
|
439
|
+
const parsedMod = parseModuleYaml(srcModuleDir);
|
|
440
|
+
if (!parsedMod.ok)
|
|
441
|
+
throw new ValidationError(parsedMod.error);
|
|
442
|
+
const moduleCode = parsedMod.data.code;
|
|
443
|
+
const destModuleDir = path.join(bmadDir, moduleCode);
|
|
444
|
+
// Story 17.3 — clean-slate re-install.
|
|
445
|
+
if (fs.existsSync(destModuleDir)) {
|
|
446
|
+
cleanRemoveModule(moduleCode, bmadDir, manifestPath);
|
|
447
|
+
}
|
|
448
|
+
const copyResult = copyDirThroughWriteService(srcModuleDir, destModuleDir, app.fileStore.studioDir, app.fileStore);
|
|
449
|
+
if (!copyResult.ok)
|
|
450
|
+
throw new ValidationError(copyResult.error);
|
|
451
|
+
totalText += copyResult.textCount;
|
|
452
|
+
totalBinary += copyResult.binaryCount;
|
|
453
|
+
// Story 15.5 — substitute placeholders in each installed module dir.
|
|
454
|
+
const subResult = runVariableSubstitution(destModuleDir, makeSubContext(moduleCode), app.fileStore.studioDir, app.fileStore);
|
|
455
|
+
if (!subResult.ok)
|
|
456
|
+
throw new ValidationError(subResult.error);
|
|
457
|
+
installedModules.push(moduleCode);
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
if (installedModules.length === 0) {
|
|
461
|
+
throw new ValidationError(`Package "${packageName}" has no module directories in _bmad/`);
|
|
462
|
+
}
|
|
463
|
+
// 6. Update manifest.yaml with new module entries (snapshot via WriteService)
|
|
464
|
+
const manifest = readManifestSafe(manifestPath);
|
|
465
|
+
const now = new Date().toISOString();
|
|
466
|
+
for (const moduleName of installedModules) {
|
|
467
|
+
const existing = manifest.modules.find((m) => m.name === moduleName);
|
|
468
|
+
if (existing) {
|
|
469
|
+
existing.lastUpdated = now;
|
|
470
|
+
existing.npmPackage = packageName;
|
|
471
|
+
existing.source = 'npm';
|
|
472
|
+
}
|
|
473
|
+
else {
|
|
474
|
+
manifest.modules.push({
|
|
475
|
+
name: moduleName,
|
|
476
|
+
version: '1.0.0',
|
|
477
|
+
installDate: now,
|
|
478
|
+
lastUpdated: now,
|
|
479
|
+
source: 'npm',
|
|
480
|
+
npmPackage: packageName,
|
|
481
|
+
repoUrl: null,
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
const wrote = writeManifestThroughWriteService(manifestPath, manifest, app.fileStore.studioDir, app.fileStore);
|
|
486
|
+
if (!wrote.ok)
|
|
487
|
+
throw new ValidationError(wrote.error);
|
|
488
|
+
// Story 15.6 — generate IDE launchers for each installed module.
|
|
489
|
+
// The npm branch installs MULTIPLE modules; sum the per-IDE counts.
|
|
490
|
+
const skillsGenerated = {};
|
|
491
|
+
for (const moduleName of installedModules) {
|
|
492
|
+
const counts = runGenerator(moduleName);
|
|
493
|
+
for (const [ide, count] of Object.entries(counts)) {
|
|
494
|
+
skillsGenerated[ide] = (skillsGenerated[ide] ?? 0) + count;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
// 7. Rebuild file store
|
|
498
|
+
app.fileStore.rebuild();
|
|
499
|
+
reply.status(200);
|
|
500
|
+
return {
|
|
501
|
+
ok: true,
|
|
502
|
+
modules: installedModules,
|
|
503
|
+
filesCopied: { text: totalText, binary: totalBinary },
|
|
504
|
+
skillsGenerated,
|
|
505
|
+
};
|
|
506
|
+
}
|
|
507
|
+
catch (err) {
|
|
508
|
+
// Rethrow known error types so the global handler produces the correct
|
|
509
|
+
// status (422 for ValidationError, 409 for ConflictError). Wrap any
|
|
510
|
+
// unexpected error (e.g. execSync failure) as a ValidationError.
|
|
511
|
+
if (err instanceof ValidationError || err instanceof ConflictError || err instanceof NotFoundError) {
|
|
512
|
+
throw err;
|
|
513
|
+
}
|
|
514
|
+
throw new ValidationError(err instanceof Error ? err.message : 'Installation failed');
|
|
515
|
+
}
|
|
516
|
+
finally {
|
|
517
|
+
// Cleanup temp directory
|
|
518
|
+
try {
|
|
519
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
520
|
+
}
|
|
521
|
+
catch {
|
|
522
|
+
// ignore cleanup errors
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
});
|
|
526
|
+
// Multipart zip upload route — Story 15.4. Separate from POST /api/modules/install
|
|
527
|
+
// because multipart bodies and JSON bodies have different shapes inside Fastify;
|
|
528
|
+
// splitting the routes is cleaner than content-type discrimination inside one handler.
|
|
529
|
+
app.post('/api/modules/install/upload', async (request, reply) => {
|
|
530
|
+
if (!('fileStore' in app)) {
|
|
531
|
+
throw new ValidationError('No project detected');
|
|
532
|
+
}
|
|
533
|
+
// Iterate all multipart parts in stream order so the `variables` field is
|
|
534
|
+
// captured regardless of whether it arrives before or after the file part.
|
|
535
|
+
// Using request.parts() instead of request.file() avoids the ordering bug
|
|
536
|
+
// where data.fields is only populated for fields that precede the file.
|
|
537
|
+
let zipBuffer = null;
|
|
538
|
+
let uploadVariables = {};
|
|
539
|
+
for await (const part of request.parts()) {
|
|
540
|
+
if (part.type === 'file') {
|
|
541
|
+
zipBuffer = await part.toBuffer();
|
|
542
|
+
}
|
|
543
|
+
else if (part.type === 'field' && part.fieldname === 'variables') {
|
|
544
|
+
const raw = part.value;
|
|
545
|
+
if (typeof raw === 'string') {
|
|
546
|
+
try {
|
|
547
|
+
const parsed = JSON.parse(raw);
|
|
548
|
+
if (parsed && typeof parsed === 'object') {
|
|
549
|
+
uploadVariables = parsed;
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
catch {
|
|
553
|
+
throw new ValidationError('Invalid `variables` field — expected JSON object');
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
if (!zipBuffer) {
|
|
559
|
+
throw new ValidationError('No zip file uploaded');
|
|
560
|
+
}
|
|
561
|
+
const buffer = zipBuffer;
|
|
562
|
+
const varValidation = validateVariables(uploadVariables);
|
|
563
|
+
if (!varValidation.ok)
|
|
564
|
+
throw new ValidationError(varValidation.error);
|
|
565
|
+
const bmadDir = path.join(app.fileStore.projectRoot, '_bmad');
|
|
566
|
+
const manifestPath = path.join(bmadDir, '_config', 'manifest.yaml');
|
|
567
|
+
// Manifest existence guard (AC-15.4.9). Runs BEFORE extractZipUpload so a
|
|
568
|
+
// misconfigured project doesn't waste CPU on adm-zip extraction.
|
|
569
|
+
if (!fs.existsSync(manifestPath)) {
|
|
570
|
+
throw new ValidationError('Cannot install module: missing _bmad/_config/manifest.yaml. Run `npx bmad-method install` to initialise the project first.');
|
|
571
|
+
}
|
|
572
|
+
// extractZipUpload throws plain Error on failure (malformed zip, zip-slip, etc.)
|
|
573
|
+
// Convert to ValidationError so the user sees a 422 with a clean message.
|
|
574
|
+
let extracted;
|
|
575
|
+
try {
|
|
576
|
+
extracted = await extractZipUpload(buffer);
|
|
577
|
+
}
|
|
578
|
+
catch (err) {
|
|
579
|
+
throw new ValidationError(err instanceof Error ? err.message : String(err));
|
|
580
|
+
}
|
|
581
|
+
const { extractedRoot, tmpDir } = extracted;
|
|
582
|
+
try {
|
|
583
|
+
if (!isPlausibleModuleDir(extractedRoot)) {
|
|
584
|
+
throw new ValidationError('Uploaded zip does not look like a BMAD module');
|
|
585
|
+
}
|
|
586
|
+
const parsed = parseModuleYaml(extractedRoot);
|
|
587
|
+
if (!parsed.ok)
|
|
588
|
+
throw new ValidationError(parsed.error);
|
|
589
|
+
const moduleCode = parsed.data.code;
|
|
590
|
+
const destDir = path.join(bmadDir, moduleCode);
|
|
591
|
+
// Story 17.3 — clean-slate re-install.
|
|
592
|
+
if (fs.existsSync(destDir)) {
|
|
593
|
+
cleanRemoveModule(moduleCode, bmadDir, manifestPath);
|
|
594
|
+
}
|
|
595
|
+
const copyResult = copyDirThroughWriteService(extractedRoot, destDir, app.fileStore.studioDir, app.fileStore);
|
|
596
|
+
if (!copyResult.ok)
|
|
597
|
+
throw new ValidationError(copyResult.error);
|
|
598
|
+
// Story 15.5 — substitute placeholders before manifest update
|
|
599
|
+
const subResult = runVariableSubstitution(destDir, {
|
|
600
|
+
moduleCode,
|
|
601
|
+
projectRoot: app.fileStore.projectRoot,
|
|
602
|
+
outputFolder: readOutputFolder(app.fileStore.projectRoot),
|
|
603
|
+
variables: uploadVariables,
|
|
604
|
+
}, app.fileStore.studioDir, app.fileStore);
|
|
605
|
+
if (!subResult.ok)
|
|
606
|
+
throw new ValidationError(subResult.error);
|
|
607
|
+
// Update manifest (guaranteed to exist by the check at the top of the handler)
|
|
608
|
+
const manifest = readManifestSafe(manifestPath);
|
|
609
|
+
const now = new Date().toISOString();
|
|
610
|
+
const existing = manifest.modules.find((m) => m.name === moduleCode);
|
|
611
|
+
if (existing) {
|
|
612
|
+
existing.lastUpdated = now;
|
|
613
|
+
existing.source = 'zip';
|
|
614
|
+
existing.npmPackage = null;
|
|
615
|
+
existing.repoUrl = null;
|
|
616
|
+
}
|
|
617
|
+
else {
|
|
618
|
+
manifest.modules.push({
|
|
619
|
+
name: moduleCode,
|
|
620
|
+
version: parsed.data.version ?? '1.0.0',
|
|
621
|
+
installDate: now,
|
|
622
|
+
lastUpdated: now,
|
|
623
|
+
source: 'zip',
|
|
624
|
+
npmPackage: null,
|
|
625
|
+
repoUrl: null,
|
|
626
|
+
});
|
|
627
|
+
}
|
|
628
|
+
const wrote = writeManifestThroughWriteService(manifestPath, manifest, app.fileStore.studioDir, app.fileStore);
|
|
629
|
+
if (!wrote.ok)
|
|
630
|
+
throw new ValidationError(wrote.error);
|
|
631
|
+
// Story 15.6 — generate IDE launchers after manifest commit
|
|
632
|
+
const updatedManifest = readManifestSafe(manifestPath);
|
|
633
|
+
const skillsGenerated = {};
|
|
634
|
+
if (updatedManifest) {
|
|
635
|
+
const genResult = generateIdeSkillsForModule(app.fileStore.projectRoot, moduleCode, updatedManifest, app.fileStore.studioDir, app.fileStore);
|
|
636
|
+
if (!genResult.ok)
|
|
637
|
+
throw new ValidationError(genResult.error);
|
|
638
|
+
for (const [ide, skills] of Object.entries(genResult.skillsByIde)) {
|
|
639
|
+
skillsGenerated[ide] = skills.length;
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
app.fileStore.rebuild();
|
|
643
|
+
reply.status(200);
|
|
644
|
+
return {
|
|
645
|
+
ok: true,
|
|
646
|
+
modules: [moduleCode],
|
|
647
|
+
filesCopied: { text: copyResult.textCount, binary: copyResult.binaryCount },
|
|
648
|
+
source: { type: 'zip' },
|
|
649
|
+
skillsGenerated,
|
|
650
|
+
};
|
|
651
|
+
}
|
|
652
|
+
finally {
|
|
653
|
+
try {
|
|
654
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
655
|
+
}
|
|
656
|
+
catch {
|
|
657
|
+
/* ignore cleanup errors */
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
});
|
|
661
|
+
app.post('/api/modules', async (request, reply) => {
|
|
662
|
+
if (!('fileStore' in app)) {
|
|
663
|
+
throw new ValidationError('No project detected');
|
|
664
|
+
}
|
|
665
|
+
const body = request.body;
|
|
666
|
+
const name = body.name?.trim();
|
|
667
|
+
if (!name) {
|
|
668
|
+
throw new ValidationError('Module name is required');
|
|
669
|
+
}
|
|
670
|
+
if (!MODULE_NAME_RE.test(name)) {
|
|
671
|
+
throw new ValidationError('Module name must be lowercase alphanumeric with hyphens (e.g., my-module)');
|
|
672
|
+
}
|
|
673
|
+
const bmadDir = path.join(app.fileStore.projectRoot, '_bmad');
|
|
674
|
+
const moduleDir = path.join(bmadDir, name);
|
|
675
|
+
const manifestPath = path.join(bmadDir, '_config', 'manifest.yaml');
|
|
676
|
+
if (fs.existsSync(moduleDir)) {
|
|
677
|
+
throw new ConflictError(`Module "${name}" already exists`);
|
|
678
|
+
}
|
|
679
|
+
// Create module directory structure
|
|
680
|
+
const subdirs = ['agents', 'skills', 'workflows'];
|
|
681
|
+
for (const sub of subdirs) {
|
|
682
|
+
fs.mkdirSync(path.join(moduleDir, sub), { recursive: true });
|
|
683
|
+
}
|
|
684
|
+
// Create module config.yaml
|
|
685
|
+
const version = body.version?.trim() || '1.0.0';
|
|
686
|
+
const configContent = [
|
|
687
|
+
`# ${name} Module Configuration`,
|
|
688
|
+
`# Created by BMAD Studio`,
|
|
689
|
+
`# Date: ${new Date().toISOString()}`,
|
|
690
|
+
'',
|
|
691
|
+
`project_name: ${name}`,
|
|
692
|
+
].join('\n');
|
|
693
|
+
const wResult = writeFile(path.join(moduleDir, 'config.yaml'), configContent, app.fileStore.studioDir);
|
|
694
|
+
if (!wResult.ok)
|
|
695
|
+
throw new ValidationError(wResult.error);
|
|
696
|
+
// Update manifest
|
|
697
|
+
const manifest = readManifestSafe(manifestPath);
|
|
698
|
+
if (manifest) {
|
|
699
|
+
const now = new Date().toISOString();
|
|
700
|
+
manifest.modules.push({
|
|
701
|
+
name,
|
|
702
|
+
version,
|
|
703
|
+
installDate: now,
|
|
704
|
+
lastUpdated: now,
|
|
705
|
+
source: 'custom',
|
|
706
|
+
npmPackage: null,
|
|
707
|
+
repoUrl: null,
|
|
708
|
+
});
|
|
709
|
+
const wrote = writeManifestThroughWriteService(manifestPath, manifest, app.fileStore.studioDir, app.fileStore);
|
|
710
|
+
if (!wrote.ok)
|
|
711
|
+
throw new ValidationError(wrote.error);
|
|
712
|
+
}
|
|
713
|
+
// Rebuild index
|
|
714
|
+
app.fileStore.rebuild();
|
|
715
|
+
reply.status(201);
|
|
716
|
+
return { ok: true, name };
|
|
717
|
+
});
|
|
718
|
+
// Story 15.8 — Regenerate IDE skills for an installed module. Removes all
|
|
719
|
+
// prefix-matched launcher dirs and re-runs the generator against the current
|
|
720
|
+
// module contents. Used by the "Regenerate IDE skills" button on PackagesPage
|
|
721
|
+
// and as the Q9 smoke test for dept-aem.
|
|
722
|
+
app.post('/api/modules/:name/regenerate-skills', async (request) => {
|
|
723
|
+
if (!('fileStore' in app)) {
|
|
724
|
+
throw new ValidationError('No project detected');
|
|
725
|
+
}
|
|
726
|
+
const { name } = request.params;
|
|
727
|
+
const bmadDir = path.join(app.fileStore.projectRoot, '_bmad');
|
|
728
|
+
const moduleDir = path.join(bmadDir, name);
|
|
729
|
+
const manifestPath = path.join(bmadDir, '_config', 'manifest.yaml');
|
|
730
|
+
if (!fs.existsSync(moduleDir)) {
|
|
731
|
+
throw new NotFoundError(`Module "${name}" is not installed`);
|
|
732
|
+
}
|
|
733
|
+
const manifest = readManifestSafe(manifestPath);
|
|
734
|
+
if (!manifest)
|
|
735
|
+
throw new ValidationError('No manifest.yaml found');
|
|
736
|
+
// Remove existing launcher files first (snapshots text content via WriteService)
|
|
737
|
+
const removeResult = removeIdeSkillsForModule(app.fileStore.projectRoot, name, manifest, app.fileStore.studioDir);
|
|
738
|
+
if (!removeResult.ok)
|
|
739
|
+
throw new ValidationError(removeResult.error);
|
|
740
|
+
// Regenerate from the current module contents — picks up any manual edits.
|
|
741
|
+
const genResult = generateIdeSkillsForModule(app.fileStore.projectRoot, name, manifest, app.fileStore.studioDir, app.fileStore);
|
|
742
|
+
if (!genResult.ok)
|
|
743
|
+
throw new ValidationError(genResult.error);
|
|
744
|
+
const regenerated = {};
|
|
745
|
+
for (const [ide, skills] of Object.entries(genResult.skillsByIde)) {
|
|
746
|
+
regenerated[ide] = skills.length;
|
|
747
|
+
}
|
|
748
|
+
app.fileStore.rebuild();
|
|
749
|
+
return { ok: true, regenerated };
|
|
750
|
+
});
|
|
751
|
+
// Story 15.7 — Remove preview. Returns a structured pre-flight summary so the
|
|
752
|
+
// remove dialog (Story 15.9) can render an informed confirmation screen.
|
|
753
|
+
app.get('/api/modules/:name/remove-preview', async (request) => {
|
|
754
|
+
if (!('fileStore' in app)) {
|
|
755
|
+
throw new ValidationError('No project detected');
|
|
756
|
+
}
|
|
757
|
+
const { name } = request.params;
|
|
758
|
+
const bmadDir = path.join(app.fileStore.projectRoot, '_bmad');
|
|
759
|
+
const moduleDir = path.join(bmadDir, name);
|
|
760
|
+
const manifestPath = path.join(bmadDir, '_config', 'manifest.yaml');
|
|
761
|
+
const manifest = readManifestSafe(manifestPath);
|
|
762
|
+
const entry = manifest?.modules.find((m) => m.name === name);
|
|
763
|
+
if (!entry)
|
|
764
|
+
throw new NotFoundError(`Module "${name}" not found in manifest`);
|
|
765
|
+
// Built-in modules: blocked
|
|
766
|
+
const removalBlocked = entry.source === 'built-in'
|
|
767
|
+
? `Module "${name}" is built-in and cannot be removed via Studio.`
|
|
768
|
+
: null;
|
|
769
|
+
// Module file count + size
|
|
770
|
+
let fileCount = 0;
|
|
771
|
+
let totalBytes = 0;
|
|
772
|
+
if (fs.existsSync(moduleDir)) {
|
|
773
|
+
const walk = (dir) => {
|
|
774
|
+
for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
775
|
+
const full = path.join(dir, e.name);
|
|
776
|
+
if (e.isDirectory())
|
|
777
|
+
walk(full);
|
|
778
|
+
else {
|
|
779
|
+
fileCount++;
|
|
780
|
+
totalBytes += fs.statSync(full).size;
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
};
|
|
784
|
+
walk(moduleDir);
|
|
785
|
+
}
|
|
786
|
+
// IDE skills (prefix-matched dirs under each configured IDE output dir)
|
|
787
|
+
const ideSkills = {};
|
|
788
|
+
if (manifest?.ides) {
|
|
789
|
+
for (const ide of manifest.ides) {
|
|
790
|
+
if (ide !== 'claude-code' && ide !== 'antigravity')
|
|
791
|
+
continue;
|
|
792
|
+
const dir = path.join(app.fileStore.projectRoot, ide === 'claude-code' ? '.claude/skills' : '.antigravity/skills');
|
|
793
|
+
if (!fs.existsSync(dir)) {
|
|
794
|
+
ideSkills[ide] = [];
|
|
795
|
+
continue;
|
|
796
|
+
}
|
|
797
|
+
const agentPrefix = `bmad-agent-${name}-`;
|
|
798
|
+
const otherPrefix = `bmad-${name}-`;
|
|
799
|
+
ideSkills[ide] = fs
|
|
800
|
+
.readdirSync(dir, { withFileTypes: true })
|
|
801
|
+
.filter((e) => e.isDirectory() &&
|
|
802
|
+
(e.name.startsWith(agentPrefix) || e.name.startsWith(otherPrefix)))
|
|
803
|
+
.map((e) => e.name);
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
// Preserved directories from module.yaml (declared output dirs)
|
|
807
|
+
const parsed = parseModuleYaml(moduleDir);
|
|
808
|
+
const preservedDirectories = [];
|
|
809
|
+
let moduleYamlPresent = false;
|
|
810
|
+
if (parsed.ok && fs.existsSync(path.join(moduleDir, 'module.yaml'))) {
|
|
811
|
+
moduleYamlPresent = true;
|
|
812
|
+
for (const declared of parsed.data.directories ?? []) {
|
|
813
|
+
const resolved = path.isAbsolute(declared)
|
|
814
|
+
? declared
|
|
815
|
+
: path.join(app.fileStore.projectRoot, declared);
|
|
816
|
+
if (fs.existsSync(resolved)) {
|
|
817
|
+
preservedDirectories.push({ path: resolved, declared: true });
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
// Cross-references (TD-19 scope)
|
|
822
|
+
const crossReferences = findCrossReferences(app.fileStore.getIndex(), name);
|
|
823
|
+
// External-installer warning
|
|
824
|
+
const externalInstallerWarning = entry.source === 'external'
|
|
825
|
+
? `Module "${name}" was installed by the BMAD installer. Removing it via Studio will not update the upstream installation — re-running the installer will reinstall it.`
|
|
826
|
+
: null;
|
|
827
|
+
return {
|
|
828
|
+
module: { name: entry.name, version: entry.version, source: entry.source },
|
|
829
|
+
moduleFiles: { count: fileCount, totalBytes },
|
|
830
|
+
ideSkills,
|
|
831
|
+
manifestEntries: { 'manifest.yaml': true },
|
|
832
|
+
preservedDirectories,
|
|
833
|
+
moduleYamlPresent,
|
|
834
|
+
crossReferences,
|
|
835
|
+
crossReferenceScopeNotice: 'Cross-reference scanning covers teams and workflow steps. References from agent menus or skill lists are not detected — review the affected modules manually after removal.',
|
|
836
|
+
recoverableFrom: '.bmad-studio/history/',
|
|
837
|
+
removalBlocked,
|
|
838
|
+
externalInstallerWarning,
|
|
839
|
+
};
|
|
840
|
+
});
|
|
841
|
+
// Story 15.7 — Rich remove handler. Replaces the thin DELETE. Removes IDE
|
|
842
|
+
// launcher files, then deletes the module dir through WriteService (text
|
|
843
|
+
// files snapshot to history/ before unlink), then removes the manifest entry.
|
|
844
|
+
// Preserves directories declared in module.yaml.directories[].
|
|
845
|
+
app.delete('/api/modules/:name', async (request) => {
|
|
846
|
+
if (!('fileStore' in app)) {
|
|
847
|
+
throw new ValidationError('No project detected');
|
|
848
|
+
}
|
|
849
|
+
const { name } = request.params;
|
|
850
|
+
const bmadDir = path.join(app.fileStore.projectRoot, '_bmad');
|
|
851
|
+
const moduleDir = path.join(bmadDir, name);
|
|
852
|
+
const manifestPath = path.join(bmadDir, '_config', 'manifest.yaml');
|
|
853
|
+
const manifest = readManifestSafe(manifestPath);
|
|
854
|
+
const entry = manifest?.modules.find((m) => m.name === name);
|
|
855
|
+
if (!entry)
|
|
856
|
+
throw new NotFoundError(`Module "${name}" not found in manifest`);
|
|
857
|
+
if (entry.source === 'built-in') {
|
|
858
|
+
throw new ValidationError(`Cannot remove built-in module "${name}"`);
|
|
859
|
+
}
|
|
860
|
+
// Read module.yaml BEFORE deletion so we can capture directories: to preserve.
|
|
861
|
+
const parsed = parseModuleYaml(moduleDir);
|
|
862
|
+
const preserved = parsed.ok
|
|
863
|
+
? (parsed.data.directories ?? []).map((d) => path.isAbsolute(d) ? d : path.join(app.fileStore.projectRoot, d))
|
|
864
|
+
: [];
|
|
865
|
+
// 1. Remove prefix-matched IDE skill directories (each deletion snapshots through WriteService)
|
|
866
|
+
let removedSkills = {};
|
|
867
|
+
if (manifest) {
|
|
868
|
+
const r = removeIdeSkillsForModule(app.fileStore.projectRoot, name, manifest, app.fileStore.studioDir);
|
|
869
|
+
if (!r.ok)
|
|
870
|
+
throw new ValidationError(r.error);
|
|
871
|
+
removedSkills = r.removedByIde;
|
|
872
|
+
}
|
|
873
|
+
// 2. Delete the module directory through WriteService (text files snapshot first).
|
|
874
|
+
// Count files before delete so the response summary is accurate.
|
|
875
|
+
let filesRemoved = 0;
|
|
876
|
+
if (fs.existsSync(moduleDir)) {
|
|
877
|
+
const walk = (dir) => {
|
|
878
|
+
for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
879
|
+
const full = path.join(dir, e.name);
|
|
880
|
+
if (e.isDirectory())
|
|
881
|
+
walk(full);
|
|
882
|
+
else
|
|
883
|
+
filesRemoved++;
|
|
884
|
+
}
|
|
885
|
+
};
|
|
886
|
+
walk(moduleDir);
|
|
887
|
+
const r = deleteDirectory(moduleDir, app.fileStore.studioDir);
|
|
888
|
+
if (!r.ok)
|
|
889
|
+
throw new ValidationError(r.error);
|
|
890
|
+
}
|
|
891
|
+
// 3. Update the manifest (snapshot via WriteService)
|
|
892
|
+
if (manifest) {
|
|
893
|
+
manifest.modules = manifest.modules.filter((m) => m.name !== name);
|
|
894
|
+
const wrote = writeManifestThroughWriteService(manifestPath, manifest, app.fileStore.studioDir, app.fileStore);
|
|
895
|
+
if (!wrote.ok)
|
|
896
|
+
throw new ValidationError(wrote.error);
|
|
897
|
+
}
|
|
898
|
+
// 4. Rebuild index and broadcast the change
|
|
899
|
+
app.fileStore.rebuild();
|
|
900
|
+
if ('ws' in app) {
|
|
901
|
+
try {
|
|
902
|
+
;
|
|
903
|
+
app.ws.broadcast({
|
|
904
|
+
type: 'file:deleted',
|
|
905
|
+
path: moduleDir,
|
|
906
|
+
category: 'config',
|
|
907
|
+
});
|
|
908
|
+
}
|
|
909
|
+
catch {
|
|
910
|
+
/* ignore — broadcast is best-effort */
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
return {
|
|
914
|
+
ok: true,
|
|
915
|
+
name,
|
|
916
|
+
removed: {
|
|
917
|
+
filesRemoved,
|
|
918
|
+
skills: removedSkills,
|
|
919
|
+
},
|
|
920
|
+
preservedDirectories: preserved,
|
|
921
|
+
recoverableFrom: '.bmad-studio/history/',
|
|
922
|
+
};
|
|
923
|
+
});
|
|
924
|
+
// Story 12.1 + 12.2: Add/upload entities to a module
|
|
925
|
+
app.post('/api/modules/:name/entities', async (request, reply) => {
|
|
926
|
+
if (!('fileStore' in app)) {
|
|
927
|
+
throw new ValidationError('No project detected');
|
|
928
|
+
}
|
|
929
|
+
const { name } = request.params;
|
|
930
|
+
if (!MODULE_NAME_RE.test(name)) {
|
|
931
|
+
throw new ValidationError('Module name must be lowercase alphanumeric with hyphens');
|
|
932
|
+
}
|
|
933
|
+
const body = request.body;
|
|
934
|
+
const entityType = body.type;
|
|
935
|
+
const entityName = body.name?.trim();
|
|
936
|
+
const entityContent = body.content;
|
|
937
|
+
if (!entityType || !['agent', 'skill', 'workflow'].includes(entityType)) {
|
|
938
|
+
throw new ValidationError('Entity type must be one of: agent, skill, workflow');
|
|
939
|
+
}
|
|
940
|
+
if (!entityName) {
|
|
941
|
+
throw new ValidationError('Entity name is required');
|
|
942
|
+
}
|
|
943
|
+
const bmadDir = path.join(app.fileStore.projectRoot, '_bmad');
|
|
944
|
+
const moduleDir = path.join(bmadDir, name);
|
|
945
|
+
if (!fs.existsSync(moduleDir)) {
|
|
946
|
+
throw new NotFoundError(`Module "${name}" not found`);
|
|
947
|
+
}
|
|
948
|
+
let filePath;
|
|
949
|
+
if (entityType === 'skill') {
|
|
950
|
+
// Skills get their own directory with a SKILL.md file (matches index-builder convention)
|
|
951
|
+
const sanitized = entityName.replace(/\.md$/i, '');
|
|
952
|
+
const skillDir = path.join(moduleDir, 'skills', sanitized);
|
|
953
|
+
fs.mkdirSync(skillDir, { recursive: true });
|
|
954
|
+
filePath = path.join(skillDir, 'SKILL.md');
|
|
955
|
+
if (fs.existsSync(filePath)) {
|
|
956
|
+
throw new ConflictError(`Skill "${sanitized}" already exists in module "${name}"`);
|
|
957
|
+
}
|
|
958
|
+
const content = entityContent ?? [
|
|
959
|
+
'---',
|
|
960
|
+
`name: ${sanitized}`,
|
|
961
|
+
'category: custom',
|
|
962
|
+
'description: ""',
|
|
963
|
+
'---',
|
|
964
|
+
'',
|
|
965
|
+
`# ${sanitized}`,
|
|
966
|
+
'',
|
|
967
|
+
'<!-- Add skill instructions here -->',
|
|
968
|
+
'',
|
|
969
|
+
].join('\n');
|
|
970
|
+
const wResult = writeFile(filePath, content, app.fileStore.studioDir);
|
|
971
|
+
if (!wResult.ok)
|
|
972
|
+
throw new ValidationError(wResult.error);
|
|
973
|
+
}
|
|
974
|
+
else if (entityType === 'workflow') {
|
|
975
|
+
// Workflows get their own directory with a workflow.md file
|
|
976
|
+
const sanitized = entityName.replace(/\.md$/i, '');
|
|
977
|
+
const wfDir = path.join(moduleDir, 'workflows', sanitized);
|
|
978
|
+
fs.mkdirSync(wfDir, { recursive: true });
|
|
979
|
+
filePath = path.join(wfDir, 'workflow.md');
|
|
980
|
+
if (fs.existsSync(filePath)) {
|
|
981
|
+
throw new ConflictError(`Workflow "${sanitized}" already exists in module "${name}"`);
|
|
982
|
+
}
|
|
983
|
+
const content = entityContent ?? [
|
|
984
|
+
'---',
|
|
985
|
+
`name: ${sanitized}`,
|
|
986
|
+
'description: ""',
|
|
987
|
+
'---',
|
|
988
|
+
'',
|
|
989
|
+
`# ${sanitized} Workflow`,
|
|
990
|
+
'',
|
|
991
|
+
'## Step 1: Start',
|
|
992
|
+
'',
|
|
993
|
+
'<!-- Add workflow steps here -->',
|
|
994
|
+
'',
|
|
995
|
+
].join('\n');
|
|
996
|
+
const wResult = writeFile(filePath, content, app.fileStore.studioDir);
|
|
997
|
+
if (!wResult.ok)
|
|
998
|
+
throw new ValidationError(wResult.error);
|
|
999
|
+
}
|
|
1000
|
+
else {
|
|
1001
|
+
// Agent: .md file in agents/ directory
|
|
1002
|
+
const sanitized = entityName.replace(/\.md$/i, '');
|
|
1003
|
+
const agentDir = path.join(moduleDir, 'agents');
|
|
1004
|
+
fs.mkdirSync(agentDir, { recursive: true });
|
|
1005
|
+
filePath = path.join(agentDir, `${sanitized}.md`);
|
|
1006
|
+
if (fs.existsSync(filePath)) {
|
|
1007
|
+
throw new ConflictError(`Agent "${sanitized}" already exists in module "${name}"`);
|
|
1008
|
+
}
|
|
1009
|
+
const content = entityContent ?? [
|
|
1010
|
+
'---',
|
|
1011
|
+
`name: ${sanitized}`,
|
|
1012
|
+
'title: ""',
|
|
1013
|
+
'description: ""',
|
|
1014
|
+
'---',
|
|
1015
|
+
'',
|
|
1016
|
+
`# ${sanitized}`,
|
|
1017
|
+
'',
|
|
1018
|
+
'<!-- Add agent definition here -->',
|
|
1019
|
+
'',
|
|
1020
|
+
].join('\n');
|
|
1021
|
+
const wResult = writeFile(filePath, content, app.fileStore.studioDir);
|
|
1022
|
+
if (!wResult.ok)
|
|
1023
|
+
throw new ValidationError(wResult.error);
|
|
1024
|
+
}
|
|
1025
|
+
// Rebuild index
|
|
1026
|
+
app.fileStore.rebuild();
|
|
1027
|
+
reply.status(201);
|
|
1028
|
+
return { ok: true, type: entityType, name: entityName };
|
|
1029
|
+
});
|
|
1030
|
+
// Story 12.3: Export module manifest
|
|
1031
|
+
app.post('/api/modules/:name/export', async (request) => {
|
|
1032
|
+
if (!('fileStore' in app)) {
|
|
1033
|
+
throw new ValidationError('No project detected');
|
|
1034
|
+
}
|
|
1035
|
+
const { name } = request.params;
|
|
1036
|
+
const bmadDir = path.join(app.fileStore.projectRoot, '_bmad');
|
|
1037
|
+
const manifestPath = path.join(bmadDir, '_config', 'manifest.yaml');
|
|
1038
|
+
const manifest = readManifestSafe(manifestPath);
|
|
1039
|
+
if (!manifest) {
|
|
1040
|
+
throw new NotFoundError('No manifest found');
|
|
1041
|
+
}
|
|
1042
|
+
const entry = manifest.modules.find((m) => m.name === name);
|
|
1043
|
+
if (!entry) {
|
|
1044
|
+
throw new NotFoundError(`Module "${name}" not found in manifest`);
|
|
1045
|
+
}
|
|
1046
|
+
const moduleDir = path.join(bmadDir, name);
|
|
1047
|
+
if (!fs.existsSync(moduleDir)) {
|
|
1048
|
+
throw new NotFoundError(`Module directory "${name}" not found`);
|
|
1049
|
+
}
|
|
1050
|
+
const index = app.fileStore.getIndex();
|
|
1051
|
+
const agentCount = index.agents.filter((a) => a.module === name).length;
|
|
1052
|
+
const skillCount = index.skills.filter((s) => s.module === name).length;
|
|
1053
|
+
const workflowCount = index.workflows.filter((w) => w.module === name).length;
|
|
1054
|
+
// List entity names
|
|
1055
|
+
const agentNames = index.agents.filter((a) => a.module === name).map((a) => a.name);
|
|
1056
|
+
const skillNames = index.skills.filter((s) => s.module === name).map((s) => s.name);
|
|
1057
|
+
const workflowNames = index.workflows.filter((w) => w.module === name).map((w) => w.name);
|
|
1058
|
+
const exportManifest = {
|
|
1059
|
+
module: name,
|
|
1060
|
+
version: entry.version,
|
|
1061
|
+
source: entry.source,
|
|
1062
|
+
exportDate: new Date().toISOString(),
|
|
1063
|
+
entities: {
|
|
1064
|
+
agents: { count: agentCount, names: agentNames },
|
|
1065
|
+
skills: { count: skillCount, names: skillNames },
|
|
1066
|
+
workflows: { count: workflowCount, names: workflowNames },
|
|
1067
|
+
},
|
|
1068
|
+
totalEntities: agentCount + skillCount + workflowCount,
|
|
1069
|
+
note: 'This is a module manifest preview. Full file bundling/archiving is a future enhancement.',
|
|
1070
|
+
};
|
|
1071
|
+
return exportManifest;
|
|
1072
|
+
});
|
|
1073
|
+
// Update module metadata (version, description)
|
|
1074
|
+
app.put('/api/modules/:name', async (request) => {
|
|
1075
|
+
if (!('fileStore' in app)) {
|
|
1076
|
+
throw new ValidationError('No project detected');
|
|
1077
|
+
}
|
|
1078
|
+
const { name } = request.params;
|
|
1079
|
+
if (!MODULE_NAME_RE.test(name)) {
|
|
1080
|
+
throw new ValidationError('Module name must be lowercase alphanumeric with hyphens');
|
|
1081
|
+
}
|
|
1082
|
+
const body = request.body;
|
|
1083
|
+
const bmadDir = path.join(app.fileStore.projectRoot, '_bmad');
|
|
1084
|
+
const moduleDir = path.join(bmadDir, name);
|
|
1085
|
+
const configPath = path.join(moduleDir, 'config.yaml');
|
|
1086
|
+
if (!fs.existsSync(configPath)) {
|
|
1087
|
+
throw new NotFoundError(`Module "${name}" config not found`);
|
|
1088
|
+
}
|
|
1089
|
+
const configContent = fs.readFileSync(configPath, 'utf-8');
|
|
1090
|
+
const config = yaml.load(configContent) ?? {};
|
|
1091
|
+
if (body.version !== undefined)
|
|
1092
|
+
config.version = body.version;
|
|
1093
|
+
if (body.description !== undefined)
|
|
1094
|
+
config.description = body.description;
|
|
1095
|
+
const updated = yaml.dump(config, { lineWidth: -1 });
|
|
1096
|
+
const wResult = writeFile(configPath, updated, app.fileStore.studioDir);
|
|
1097
|
+
if (!wResult.ok)
|
|
1098
|
+
throw new ValidationError(wResult.error);
|
|
1099
|
+
// Also update manifest.yaml
|
|
1100
|
+
const manifestPath = path.join(bmadDir, '_config', 'manifest.yaml');
|
|
1101
|
+
const manifest = readManifestSafe(manifestPath);
|
|
1102
|
+
if (manifest) {
|
|
1103
|
+
const mod = manifest.modules.find((m) => m.name === name);
|
|
1104
|
+
if (mod) {
|
|
1105
|
+
if (body.version !== undefined)
|
|
1106
|
+
mod.version = body.version;
|
|
1107
|
+
mod.lastUpdated = new Date().toISOString();
|
|
1108
|
+
const wrote = writeManifestThroughWriteService(manifestPath, manifest, app.fileStore.studioDir, app.fileStore);
|
|
1109
|
+
if (!wrote.ok)
|
|
1110
|
+
throw new ValidationError(wrote.error);
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
app.fileStore.rebuild();
|
|
1114
|
+
return { ok: true, name };
|
|
1115
|
+
});
|
|
1116
|
+
app.get('/api/modules', async () => {
|
|
1117
|
+
if (!('fileStore' in app)) {
|
|
1118
|
+
return [];
|
|
1119
|
+
}
|
|
1120
|
+
const bmadDir = path.join(app.fileStore.projectRoot, '_bmad');
|
|
1121
|
+
const manifestPath = path.join(bmadDir, '_config', 'manifest.yaml');
|
|
1122
|
+
const manifest = readManifestSafe(manifestPath);
|
|
1123
|
+
if (!manifest) {
|
|
1124
|
+
return [];
|
|
1125
|
+
}
|
|
1126
|
+
const index = app.fileStore.getIndex();
|
|
1127
|
+
return manifest.modules.map((m) => {
|
|
1128
|
+
const moduleAgents = index.agents.filter((a) => a.module === m.name);
|
|
1129
|
+
const moduleSkills = index.skills.filter((s) => s.module === m.name);
|
|
1130
|
+
const moduleWorkflows = index.workflows.filter((w) => w.module === m.name);
|
|
1131
|
+
const moduleTeams = index.teams.filter((t) => t.module === m.name);
|
|
1132
|
+
return {
|
|
1133
|
+
...m,
|
|
1134
|
+
agentCount: moduleAgents.length,
|
|
1135
|
+
skillCount: moduleSkills.length,
|
|
1136
|
+
workflowCount: moduleWorkflows.length,
|
|
1137
|
+
teamCount: moduleTeams.length,
|
|
1138
|
+
agents: moduleAgents.map((a) => ({ id: a.id, name: a.name, title: a.title })),
|
|
1139
|
+
skills: moduleSkills.map((s) => ({ id: s.id, name: s.name })),
|
|
1140
|
+
workflows: moduleWorkflows.map((w) => ({ id: w.id, name: w.name })),
|
|
1141
|
+
teams: moduleTeams.map((t) => ({ id: t.id, name: t.name })),
|
|
1142
|
+
};
|
|
1143
|
+
});
|
|
1144
|
+
});
|
|
1145
|
+
// Package export: create a curated .tar.gz of selected entities
|
|
1146
|
+
app.post('/api/packages/export', async (request, reply) => {
|
|
1147
|
+
if (!('fileStore' in app)) {
|
|
1148
|
+
throw new ValidationError('No project detected');
|
|
1149
|
+
}
|
|
1150
|
+
const body = request.body;
|
|
1151
|
+
const name = body.name?.trim();
|
|
1152
|
+
if (!name) {
|
|
1153
|
+
throw new ValidationError('Package name is required');
|
|
1154
|
+
}
|
|
1155
|
+
if (!/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/.test(name)) {
|
|
1156
|
+
throw new ValidationError('Package name must start with a letter or digit and contain only alphanumeric characters, hyphens, or underscores');
|
|
1157
|
+
}
|
|
1158
|
+
const description = body.description?.trim() || '';
|
|
1159
|
+
const version = body.version?.trim() || '1.0.0';
|
|
1160
|
+
const agentIds = body.agents ?? [];
|
|
1161
|
+
const skillIds = body.skills ?? [];
|
|
1162
|
+
const workflowIds = body.workflows ?? [];
|
|
1163
|
+
if (agentIds.length === 0 && skillIds.length === 0 && workflowIds.length === 0) {
|
|
1164
|
+
throw new ValidationError('At least one entity must be selected for export');
|
|
1165
|
+
}
|
|
1166
|
+
const index = app.fileStore.getIndex();
|
|
1167
|
+
// Create temp directory
|
|
1168
|
+
const tmpBase = fs.mkdtempSync(path.join(os.tmpdir(), 'bmad-export-'));
|
|
1169
|
+
const packageDir = path.join(tmpBase, name);
|
|
1170
|
+
fs.mkdirSync(path.join(packageDir, 'agents'), { recursive: true });
|
|
1171
|
+
fs.mkdirSync(path.join(packageDir, 'skills'), { recursive: true });
|
|
1172
|
+
fs.mkdirSync(path.join(packageDir, 'workflows'), { recursive: true });
|
|
1173
|
+
const includedAgents = [];
|
|
1174
|
+
const includedSkills = [];
|
|
1175
|
+
const includedWorkflows = [];
|
|
1176
|
+
try {
|
|
1177
|
+
// Copy agents
|
|
1178
|
+
for (const agentId of agentIds) {
|
|
1179
|
+
const agent = index.agents.find((a) => a.id === agentId);
|
|
1180
|
+
if (agent && fs.existsSync(agent.filePath)) {
|
|
1181
|
+
const destFile = path.join(packageDir, 'agents', path.basename(agent.filePath));
|
|
1182
|
+
fs.copyFileSync(agent.filePath, destFile);
|
|
1183
|
+
includedAgents.push({ id: agent.id, name: agent.name });
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
// Copy skills (entire directory)
|
|
1187
|
+
for (const skillId of skillIds) {
|
|
1188
|
+
const skill = index.skills.find((s) => s.id === skillId);
|
|
1189
|
+
if (skill && fs.existsSync(skill.filePath)) {
|
|
1190
|
+
const skillSourceDir = path.dirname(skill.filePath);
|
|
1191
|
+
const destDir = path.join(packageDir, 'skills', path.basename(skillSourceDir));
|
|
1192
|
+
fs.cpSync(skillSourceDir, destDir, { recursive: true });
|
|
1193
|
+
includedSkills.push({ id: skill.id, name: skill.name });
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
// Copy workflows (entire directory)
|
|
1197
|
+
for (const wfId of workflowIds) {
|
|
1198
|
+
const wf = index.workflows.find((w) => w.id === wfId);
|
|
1199
|
+
if (wf && fs.existsSync(wf.filePath)) {
|
|
1200
|
+
const wfSourceDir = path.dirname(wf.filePath);
|
|
1201
|
+
const destDir = path.join(packageDir, 'workflows', path.basename(wfSourceDir));
|
|
1202
|
+
fs.cpSync(wfSourceDir, destDir, { recursive: true });
|
|
1203
|
+
includedWorkflows.push({ id: wf.id, name: wf.name });
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
// Generate package.yaml manifest
|
|
1207
|
+
const packageManifest = {
|
|
1208
|
+
name,
|
|
1209
|
+
description,
|
|
1210
|
+
version,
|
|
1211
|
+
created: new Date().toISOString(),
|
|
1212
|
+
platform: 'bmad-v6',
|
|
1213
|
+
agents: includedAgents,
|
|
1214
|
+
skills: includedSkills,
|
|
1215
|
+
workflows: includedWorkflows,
|
|
1216
|
+
};
|
|
1217
|
+
fs.writeFileSync(path.join(packageDir, 'package.yaml'), yaml.dump(packageManifest, { lineWidth: -1 }), 'utf-8');
|
|
1218
|
+
// Create tar.gz archive
|
|
1219
|
+
const archivePath = path.join(tmpBase, `${name}.tar.gz`);
|
|
1220
|
+
const tarResult = spawnSync('tar', ['-czf', archivePath, '-C', tmpBase, name], { stdio: 'pipe' });
|
|
1221
|
+
if (tarResult.status !== 0) {
|
|
1222
|
+
throw new ValidationError('Failed to create package archive');
|
|
1223
|
+
}
|
|
1224
|
+
// Send as downloadable file
|
|
1225
|
+
reply.header('Content-Disposition', `attachment; filename="${name}.tar.gz"`);
|
|
1226
|
+
reply.type('application/gzip');
|
|
1227
|
+
const stream = fs.createReadStream(archivePath);
|
|
1228
|
+
// Clean up temp files after stream is consumed
|
|
1229
|
+
stream.on('end', () => {
|
|
1230
|
+
try {
|
|
1231
|
+
fs.rmSync(tmpBase, { recursive: true, force: true });
|
|
1232
|
+
}
|
|
1233
|
+
catch {
|
|
1234
|
+
// ignore cleanup errors
|
|
1235
|
+
}
|
|
1236
|
+
});
|
|
1237
|
+
stream.on('error', () => {
|
|
1238
|
+
try {
|
|
1239
|
+
fs.rmSync(tmpBase, { recursive: true, force: true });
|
|
1240
|
+
}
|
|
1241
|
+
catch {
|
|
1242
|
+
// ignore cleanup errors
|
|
1243
|
+
}
|
|
1244
|
+
});
|
|
1245
|
+
return reply.send(stream);
|
|
1246
|
+
}
|
|
1247
|
+
catch (err) {
|
|
1248
|
+
// Clean up on error
|
|
1249
|
+
try {
|
|
1250
|
+
fs.rmSync(tmpBase, { recursive: true, force: true });
|
|
1251
|
+
}
|
|
1252
|
+
catch {
|
|
1253
|
+
// ignore cleanup errors
|
|
1254
|
+
}
|
|
1255
|
+
throw new ValidationError(`Export failed: ${err instanceof Error ? err.message : 'Unknown error'}`);
|
|
1256
|
+
}
|
|
1257
|
+
});
|
|
1258
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
1259
|
+
// Story 16.2 — Registry index endpoints
|
|
1260
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
1261
|
+
app.get('/api/registry', async (_request, reply) => {
|
|
1262
|
+
if (!('fileStore' in app)) {
|
|
1263
|
+
return reply.send({ ok: false, configured: false, error: 'No project detected' });
|
|
1264
|
+
}
|
|
1265
|
+
const settingsPath = path.join(app.fileStore.studioDir, 'settings.json');
|
|
1266
|
+
if (!fs.existsSync(settingsPath)) {
|
|
1267
|
+
return reply.send({ ok: false, configured: false, error: 'No registry configured' });
|
|
1268
|
+
}
|
|
1269
|
+
const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
|
|
1270
|
+
if (!settings.registry?.repo) {
|
|
1271
|
+
return reply.send({ ok: false, configured: false, error: 'No registry configured' });
|
|
1272
|
+
}
|
|
1273
|
+
let ghSource;
|
|
1274
|
+
try {
|
|
1275
|
+
ghSource = parseGithubSource(settings.registry.repo);
|
|
1276
|
+
}
|
|
1277
|
+
catch (err) {
|
|
1278
|
+
throw new ValidationError(err instanceof Error ? err.message : String(err));
|
|
1279
|
+
}
|
|
1280
|
+
let cached = readCachedRegistryIndex(app.fileStore.studioDir, ghSource.owner, ghSource.repo);
|
|
1281
|
+
if (!cached || isRegistryCacheStale(cached)) {
|
|
1282
|
+
try {
|
|
1283
|
+
cached = await fetchAndCacheRegistryIndex(app.fileStore.studioDir, settings.registry.repo, settings.registry.branch ?? 'main');
|
|
1284
|
+
}
|
|
1285
|
+
catch (err) {
|
|
1286
|
+
throw new ValidationError(err instanceof Error ? err.message : String(err));
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
return reply.send({ ok: true, configured: true, index: cached });
|
|
1290
|
+
});
|
|
1291
|
+
app.post('/api/registry/refresh', async (_request, reply) => {
|
|
1292
|
+
if (!('fileStore' in app)) {
|
|
1293
|
+
throw new ValidationError('No project detected');
|
|
1294
|
+
}
|
|
1295
|
+
const settingsPath = path.join(app.fileStore.studioDir, 'settings.json');
|
|
1296
|
+
if (!fs.existsSync(settingsPath)) {
|
|
1297
|
+
throw new ValidationError('No registry configured');
|
|
1298
|
+
}
|
|
1299
|
+
const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
|
|
1300
|
+
if (!settings.registry?.repo) {
|
|
1301
|
+
throw new ValidationError('No registry configured');
|
|
1302
|
+
}
|
|
1303
|
+
let index;
|
|
1304
|
+
try {
|
|
1305
|
+
index = await fetchAndCacheRegistryIndex(app.fileStore.studioDir, settings.registry.repo, settings.registry.branch ?? 'main');
|
|
1306
|
+
}
|
|
1307
|
+
catch (err) {
|
|
1308
|
+
throw new ValidationError(err instanceof Error ? err.message : String(err));
|
|
1309
|
+
}
|
|
1310
|
+
return reply.send({ ok: true, index });
|
|
1311
|
+
});
|
|
1312
|
+
}
|
|
1313
|
+
//# sourceMappingURL=modules-plugin.js.map
|