ma-agents 3.12.3 → 3.13.1

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.
Files changed (257) hide show
  1. package/bin/cli.js +67 -13
  2. package/docs/architecture.md +18 -0
  3. package/lib/bmad-cache/bmb/.claude-plugin/marketplace.json +1 -1
  4. package/lib/bmad-cache/bmb/_git_preserved/hooks/commit-msg.sample +52 -2
  5. package/lib/bmad-cache/bmb/_git_preserved/hooks/fsmonitor-watchman.sample +2 -8
  6. package/lib/bmad-cache/bmb/_git_preserved/index +0 -0
  7. package/lib/bmad-cache/bmb/_git_preserved/objects/pack/pack-8f8b045fef5af6911495cf3b2a89f1ed75e120f7.idx +0 -0
  8. package/lib/bmad-cache/bmb/_git_preserved/objects/pack/pack-8f8b045fef5af6911495cf3b2a89f1ed75e120f7.pack +0 -0
  9. package/lib/bmad-cache/bmb/_git_preserved/objects/pack/pack-8f8b045fef5af6911495cf3b2a89f1ed75e120f7.rev +0 -0
  10. package/lib/bmad-cache/bmb/_git_preserved/packed-refs +1 -1
  11. package/lib/bmad-cache/bmb/_git_preserved/refs/heads/main +1 -1
  12. package/lib/bmad-cache/bmb/_git_preserved/shallow +1 -1
  13. package/lib/bmad-cache/bmb/package-lock.json +2 -2
  14. package/lib/bmad-cache/bmb/package.json +1 -1
  15. package/lib/bmad-cache/bmb/samples/bmad-agent-dream-weaver/assets/module-help.csv +1 -1
  16. package/lib/bmad-cache/bmb/samples/bmad-agent-dream-weaver/scripts/merge-config.py +33 -0
  17. package/lib/bmad-cache/bmb/samples/bmad-agent-dream-weaver/scripts/merge-help-csv.py +28 -0
  18. package/lib/bmad-cache/bmb/samples/sample-module-setup/assets/module-help.csv +1 -1
  19. package/lib/bmad-cache/bmb/samples/sample-module-setup/scripts/cleanup-legacy.py +28 -0
  20. package/lib/bmad-cache/bmb/samples/sample-module-setup/scripts/merge-config.py +33 -0
  21. package/lib/bmad-cache/bmb/samples/sample-module-setup/scripts/merge-help-csv.py +28 -0
  22. package/lib/bmad-cache/bmb/skills/bmad-bmb-setup/assets/module-help.csv +1 -1
  23. package/lib/bmad-cache/bmb/skills/bmad-bmb-setup/scripts/cleanup-legacy.py +28 -0
  24. package/lib/bmad-cache/bmb/skills/bmad-bmb-setup/scripts/merge-config.py +33 -0
  25. package/lib/bmad-cache/bmb/skills/bmad-bmb-setup/scripts/merge-help-csv.py +28 -0
  26. package/lib/bmad-cache/bmb/skills/bmad-eval-runner/assets/Dockerfile +29 -0
  27. package/lib/bmad-cache/bmb/skills/bmad-eval-runner/scripts/docker_setup.py +115 -0
  28. package/lib/bmad-cache/bmb/skills/bmad-eval-runner/scripts/generate_report.py +184 -0
  29. package/lib/bmad-cache/bmb/skills/bmad-eval-runner/scripts/pty_runner.py +171 -0
  30. package/lib/bmad-cache/bmb/skills/bmad-eval-runner/scripts/run_evals.py +492 -0
  31. package/lib/bmad-cache/bmb/skills/bmad-eval-runner/scripts/run_triggers.py +366 -0
  32. package/lib/bmad-cache/bmb/skills/bmad-eval-runner/scripts/utils.py +260 -0
  33. package/lib/bmad-cache/bmb/skills/bmad-module-builder/assets/setup-skill-template/assets/module-help.csv +1 -1
  34. package/lib/bmad-cache/bmb/skills/bmad-module-builder/assets/setup-skill-template/scripts/cleanup-legacy.py +28 -0
  35. package/lib/bmad-cache/bmb/skills/bmad-module-builder/assets/setup-skill-template/scripts/merge-config.py +33 -0
  36. package/lib/bmad-cache/bmb/skills/bmad-module-builder/assets/setup-skill-template/scripts/merge-help-csv.py +28 -0
  37. package/lib/bmad-cache/bmb/skills/bmad-module-builder/assets/standalone-module-template/merge-config.py +33 -0
  38. package/lib/bmad-cache/bmb/skills/bmad-module-builder/assets/standalone-module-template/merge-help-csv.py +28 -0
  39. package/lib/bmad-cache/bmb/skills/bmad-module-builder/scripts/tests/test-validate-module.py +74 -1
  40. package/lib/bmad-cache/bmb/skills/bmad-module-builder/scripts/validate-module.py +24 -13
  41. package/lib/bmad-cache/bmb/skills/bmad-workflow-builder/assets/sample-customize-product-brief.toml +48 -33
  42. package/lib/bmad-cache/bmb/skills/bmad-workflow-builder/scripts/extract-report-json.py +287 -0
  43. package/lib/bmad-cache/bmb/skills/bmad-workflow-builder/scripts/generate-html-report.py +57 -8
  44. package/lib/bmad-cache/bmb/skills/bmad-workflow-builder/scripts/prepass-prompt-metrics.py +7 -7
  45. package/lib/bmad-cache/bmb/skills/module-help.csv +1 -1
  46. package/lib/bmad-cache/bmb/website/public/img/eval-test-types.png +0 -0
  47. package/lib/bmad-cache/cache-manifest.json +17 -18
  48. package/lib/bmad-cache/cis/_git_preserved/hooks/commit-msg.sample +52 -2
  49. package/lib/bmad-cache/cis/_git_preserved/hooks/fsmonitor-watchman.sample +2 -8
  50. package/lib/bmad-cache/cis/_git_preserved/index +0 -0
  51. package/lib/bmad-cache/cis/_git_preserved/objects/pack/pack-18c8290560a98bcb7bf0676e6cc9b2ac5ca2823e.idx +0 -0
  52. package/lib/bmad-cache/cis/_git_preserved/objects/pack/{pack-42ffc048f54e58ce94c6331bc6be97ebbb7936f2.pack → pack-18c8290560a98bcb7bf0676e6cc9b2ac5ca2823e.pack} +0 -0
  53. package/lib/bmad-cache/cis/_git_preserved/objects/pack/pack-18c8290560a98bcb7bf0676e6cc9b2ac5ca2823e.rev +0 -0
  54. package/lib/bmad-cache/cis/_git_preserved/packed-refs +1 -1
  55. package/lib/bmad-cache/cis/_git_preserved/refs/heads/main +1 -1
  56. package/lib/bmad-cache/cis/_git_preserved/refs/tags/v0.2.1 +1 -0
  57. package/lib/bmad-cache/cis/_git_preserved/shallow +1 -1
  58. package/lib/bmad-cache/cis/package-lock.json +2 -2
  59. package/lib/bmad-cache/cis/package.json +1 -1
  60. package/lib/bmad-cache/cis/src/module-help.csv +1 -1
  61. package/lib/bmad-cache/gds/.claude-plugin/marketplace.json +4 -7
  62. package/lib/bmad-cache/gds/README.md +3 -1
  63. package/lib/bmad-cache/gds/_git_preserved/hooks/commit-msg.sample +52 -2
  64. package/lib/bmad-cache/gds/_git_preserved/hooks/fsmonitor-watchman.sample +2 -8
  65. package/lib/bmad-cache/gds/_git_preserved/index +0 -0
  66. package/lib/bmad-cache/gds/_git_preserved/objects/pack/pack-dcb7c556d9bb6b6b70d2301e094eaac6d7300552.idx +0 -0
  67. package/lib/bmad-cache/gds/_git_preserved/objects/pack/{pack-9427a146a90c00bb542cba038874bf9671ba4dc0.pack → pack-dcb7c556d9bb6b6b70d2301e094eaac6d7300552.pack} +0 -0
  68. package/lib/bmad-cache/gds/_git_preserved/objects/pack/pack-dcb7c556d9bb6b6b70d2301e094eaac6d7300552.rev +0 -0
  69. package/lib/bmad-cache/gds/_git_preserved/packed-refs +1 -1
  70. package/lib/bmad-cache/gds/_git_preserved/refs/heads/main +1 -1
  71. package/lib/bmad-cache/gds/_git_preserved/shallow +1 -1
  72. package/lib/bmad-cache/gds/package.json +1 -1
  73. package/lib/bmad-cache/gds/src/agents/gds-agent-game-designer/customize.toml +5 -5
  74. package/lib/bmad-cache/gds/src/agents/gds-agent-game-dev/customize.toml +5 -5
  75. package/lib/bmad-cache/gds/src/agents/gds-agent-game-solo-dev/customize.toml +0 -5
  76. package/lib/bmad-cache/gds/src/module-help.csv +6 -12
  77. package/lib/bmad-cache/gds/src/module.yaml +1 -1
  78. package/lib/bmad-cache/gds/src/workflows/1-preproduction/gds-create-game-brief/customize.toml +97 -22
  79. package/lib/bmad-cache/gds/src/workflows/2-design/gds-gdd/assets/validation-report-template.html +190 -0
  80. package/lib/bmad-cache/gds/src/workflows/2-design/gds-gdd/customize.toml +99 -0
  81. package/lib/bmad-cache/gds/src/workflows/2-design/gds-gdd/scripts/render-validation-html.py +290 -0
  82. package/lib/bmad-cache/gds/src/workflows/2-design/gds-prd/assets/validation-report-template.html +190 -0
  83. package/lib/bmad-cache/gds/src/workflows/2-design/gds-prd/customize.toml +84 -0
  84. package/lib/bmad-cache/gds/src/workflows/2-design/gds-ux/assets/validation-report-template.html +319 -0
  85. package/lib/bmad-cache/gds/src/workflows/2-design/gds-ux/customize.toml +101 -0
  86. package/lib/bmad-cache/gds/src/workflows/3-technical/gds-game-architecture/architecture-patterns.yaml +1 -0
  87. package/lib/bmad-cache/gds/src/workflows/3-technical/gds-game-architecture/decision-catalog.yaml +88 -0
  88. package/lib/bmad-cache/gds/src/workflows/3-technical/gds-game-architecture/engine-mcps.yaml +124 -2
  89. package/lib/bmad-cache/gds/src/workflows/4-production/gds-investigate/customize.toml +62 -0
  90. package/lib/bmad-cache/tea/.claude-plugin/marketplace.json +1 -1
  91. package/lib/bmad-cache/tea/.github/workflows/docs.yaml +3 -3
  92. package/lib/bmad-cache/tea/.github/workflows/quality.yaml +10 -10
  93. package/lib/bmad-cache/tea/AGENTS.md +31 -0
  94. package/lib/bmad-cache/tea/CHANGELOG.md +42 -1
  95. package/lib/bmad-cache/tea/README.md +8 -5
  96. package/lib/bmad-cache/tea/_git_preserved/hooks/commit-msg.sample +52 -2
  97. package/lib/bmad-cache/tea/_git_preserved/hooks/fsmonitor-watchman.sample +2 -8
  98. package/lib/bmad-cache/tea/_git_preserved/index +0 -0
  99. package/lib/bmad-cache/tea/_git_preserved/objects/pack/pack-9e4197e37df7763dd7a05c2965ee921dfd2eb617.idx +0 -0
  100. package/lib/bmad-cache/tea/_git_preserved/objects/pack/{pack-f0df537f2649464ff6c5aee241165eb9c8664227.pack → pack-9e4197e37df7763dd7a05c2965ee921dfd2eb617.pack} +0 -0
  101. package/lib/bmad-cache/tea/_git_preserved/objects/pack/pack-9e4197e37df7763dd7a05c2965ee921dfd2eb617.rev +0 -0
  102. package/lib/bmad-cache/tea/_git_preserved/packed-refs +1 -1
  103. package/lib/bmad-cache/tea/_git_preserved/refs/heads/main +1 -1
  104. package/lib/bmad-cache/tea/_git_preserved/refs/tags/v1.19.0 +1 -0
  105. package/lib/bmad-cache/tea/_git_preserved/shallow +1 -1
  106. package/lib/bmad-cache/tea/docs/explanation/engagement-models.md +15 -16
  107. package/lib/bmad-cache/tea/docs/explanation/knowledge-base-system.md +2 -0
  108. package/lib/bmad-cache/tea/docs/explanation/risk-based-testing.md +1 -1
  109. package/lib/bmad-cache/tea/docs/explanation/tea-overview.md +88 -52
  110. package/lib/bmad-cache/tea/docs/explanation/testing-as-engineering.md +13 -12
  111. package/lib/bmad-cache/tea/docs/glossary/index.md +2 -2
  112. package/lib/bmad-cache/tea/docs/how-to/brownfield/use-tea-for-enterprise.md +19 -18
  113. package/lib/bmad-cache/tea/docs/how-to/brownfield/use-tea-with-existing-tests.md +1 -1
  114. package/lib/bmad-cache/tea/docs/how-to/workflows/run-nfr-assess.md +32 -26
  115. package/lib/bmad-cache/tea/docs/how-to/workflows/run-test-design.md +20 -14
  116. package/lib/bmad-cache/tea/docs/how-to/workflows/run-trace.md +3 -3
  117. package/lib/bmad-cache/tea/docs/index.md +13 -11
  118. package/lib/bmad-cache/tea/docs/reference/commands.md +37 -13
  119. package/lib/bmad-cache/tea/docs/reference/knowledge-base.md +2 -2
  120. package/lib/bmad-cache/tea/package-lock.json +2 -2
  121. package/lib/bmad-cache/tea/package.json +1 -1
  122. package/lib/bmad-cache/tea/src/agents/bmad-tea/customize.toml +20 -15
  123. package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/confidence-gate.md +73 -0
  124. package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/knowledge/test-quality.md +1 -0
  125. package/lib/bmad-cache/tea/src/agents/bmad-tea/resources/tea-index.csv +2 -1
  126. package/lib/bmad-cache/tea/src/module-help.csv +2 -2
  127. package/lib/bmad-cache/tea/src/workflows/testarch/README.md +5 -4
  128. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/data/role-paths.yaml +1 -1
  129. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/data/tea-resources-index.yaml +1 -1
  130. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/steps-c/step-04-session-01.md +2 -2
  131. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/steps-c/step-04-session-07.md +1 -1
  132. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/templates/certificate-template.md +1 -1
  133. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/resources/tea-index.csv +1 -1
  134. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/resources/tea-index.csv +1 -1
  135. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/resources/tea-index.csv +1 -1
  136. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/resources/tea-index.csv +1 -1
  137. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/SKILL.md +3 -3
  138. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/checklist.md +11 -11
  139. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/instructions.md +4 -2
  140. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/nfr-report-template.md +5 -5
  141. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/resources/tea-index.csv +1 -1
  142. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/steps-c/step-01-load-context.md +1 -1
  143. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/steps-c/step-01b-resume.md +1 -1
  144. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/steps-c/step-02-define-thresholds.md +14 -3
  145. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/steps-c/step-04-evaluate-and-score.md +7 -7
  146. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/steps-c/step-04a-subagent-security.md +4 -4
  147. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/steps-c/step-04b-subagent-performance.md +4 -4
  148. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/steps-c/step-04c-subagent-reliability.md +4 -4
  149. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/steps-c/step-04d-subagent-scalability.md +4 -4
  150. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/steps-c/step-04e-aggregate-nfr.md +4 -4
  151. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/steps-c/step-05-generate-report.md +1 -1
  152. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/workflow-plan.md +1 -1
  153. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/workflow.yaml +3 -3
  154. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/checklist.md +23 -3
  155. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/resources/tea-index.csv +1 -1
  156. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/steps-c/step-02-load-context.md +7 -0
  157. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/steps-c/step-03-risk-and-testability.md +16 -2
  158. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/steps-c/step-04-coverage-plan.md +20 -4
  159. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/steps-c/step-05-generate-output.md +2 -0
  160. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/test-design-architecture-template.md +17 -0
  161. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/test-design-qa-template.md +15 -0
  162. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/test-design-template.md +16 -0
  163. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/resources/tea-index.csv +1 -1
  164. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/checklist.md +1 -1
  165. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/resources/tea-index.csv +1 -1
  166. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/trace-template.md +1 -1
  167. package/lib/bmad-cache/tea/test/test-installation-components.js +49 -0
  168. package/lib/bmad-cache/tea/website/astro.config.mjs +2 -2
  169. package/lib/bmad-cache/wds/README.md +1 -1
  170. package/lib/bmad-cache/wds/_git_preserved/hooks/commit-msg.sample +52 -2
  171. package/lib/bmad-cache/wds/_git_preserved/hooks/fsmonitor-watchman.sample +2 -8
  172. package/lib/bmad-cache/wds/_git_preserved/index +0 -0
  173. package/lib/bmad-cache/wds/_git_preserved/objects/pack/pack-656c3d8d5426e73043b6a7f45eedaab74e3c419e.idx +0 -0
  174. package/lib/bmad-cache/wds/_git_preserved/objects/pack/{pack-96877c1c09123cccb1f91c1412184b11d2b492ad.pack → pack-656c3d8d5426e73043b6a7f45eedaab74e3c419e.pack} +0 -0
  175. package/lib/bmad-cache/wds/_git_preserved/objects/pack/pack-656c3d8d5426e73043b6a7f45eedaab74e3c419e.rev +0 -0
  176. package/lib/bmad-cache/wds/_git_preserved/packed-refs +1 -1
  177. package/lib/bmad-cache/wds/_git_preserved/refs/heads/main +1 -1
  178. package/lib/bmad-cache/wds/_git_preserved/refs/tags/v0.4.3 +1 -0
  179. package/lib/bmad-cache/wds/_git_preserved/shallow +1 -1
  180. package/lib/bmad-cache/wds/eslint.config.mjs +1 -1
  181. package/lib/bmad-cache/wds/package.json +1 -1
  182. package/lib/bmad-cache/wds/src/agents/wds-agent-freya-ux/customize.toml +80 -0
  183. package/lib/bmad-cache/wds/src/agents/wds-agent-mimir-builder/customize.toml +52 -0
  184. package/lib/bmad-cache/wds/src/agents/wds-agent-saga-analyst/customize.toml +70 -0
  185. package/lib/bmad-cache/wds/src/module-help.csv +19 -19
  186. package/lib/bmad-cache/wds/src/module.yaml +28 -0
  187. package/lib/bmad-cache/wds/src/scripts/README.md +155 -0
  188. package/lib/bmad-cache/wds/src/scripts/wds-add-object.js +202 -0
  189. package/lib/bmad-cache/wds/src/scripts/wds-add-spacing.js +158 -0
  190. package/lib/bmad-cache/wds/src/scripts/wds-init-page.js +229 -0
  191. package/lib/bmad-cache/wds/src/scripts/wds-init-scenario.js +120 -0
  192. package/lib/bmad-cache/wds/src/scripts/wds-nav.js +201 -0
  193. package/lib/bmad-cache/wds/src/scripts/wds-validate.js +301 -0
  194. package/lib/bmad-cache/wds/src/workflows/wds-3-scenarios/workflow.xml +450 -0
  195. package/lib/bmad-cache/wds/src/workflows/wds-4-ux-design/workflow-specify.xml +387 -0
  196. package/lib/bmad-extension/.claude-plugin/marketplace.json.template +1 -1
  197. package/lib/bmad-extension-plugin/.claude-plugin/marketplace.json +2 -2
  198. package/lib/bmad.js +361 -18
  199. package/lib/installer.js +296 -26
  200. package/lib/mil498-templates/OCD.md +169 -169
  201. package/lib/mil498-templates/README.md +4 -4
  202. package/lib/mil498-templates/SDD.md +163 -163
  203. package/lib/mil498-templates/SDP.md +307 -307
  204. package/lib/mil498-templates/SRS.md +219 -219
  205. package/lib/mil498-templates/SSDD.md +154 -154
  206. package/lib/mil498-templates/SSS.md +225 -225
  207. package/lib/mil498-templates/STD.md +188 -188
  208. package/lib/profile.js +96 -5
  209. package/lib/templates/instruction-block-git.template.md +25 -0
  210. package/lib/templates/instruction-block-onprem.template.md +86 -86
  211. package/lib/templates/instruction-block-universal.template.md +29 -29
  212. package/package.json +5 -4
  213. package/scripts/build-bmad-cache.js +143 -42
  214. package/lib/bmad-cache/bmb/_git_preserved/objects/pack/pack-6ecd9fc6445b1281449c5ec49a6c5794708e662e.idx +0 -0
  215. package/lib/bmad-cache/bmb/_git_preserved/objects/pack/pack-6ecd9fc6445b1281449c5ec49a6c5794708e662e.pack +0 -0
  216. package/lib/bmad-cache/bmb/_git_preserved/objects/pack/pack-6ecd9fc6445b1281449c5ec49a6c5794708e662e.rev +0 -0
  217. package/lib/bmad-cache/bmb/_git_preserved/refs/remotes/origin/HEAD +0 -1
  218. package/lib/bmad-cache/bmb/_git_preserved/refs/tags/v1.7.0 +0 -1
  219. package/lib/bmad-cache/bmb/skills/bmad-workflow-builder/scripts/generate-convert-report.py +0 -406
  220. package/lib/bmad-cache/bmb/skills/bmad-workflow-builder/scripts/tests/test_generate_convert_report.py +0 -243
  221. package/lib/bmad-cache/cis/_git_preserved/objects/pack/pack-42ffc048f54e58ce94c6331bc6be97ebbb7936f2.idx +0 -0
  222. package/lib/bmad-cache/cis/_git_preserved/objects/pack/pack-42ffc048f54e58ce94c6331bc6be97ebbb7936f2.rev +0 -0
  223. package/lib/bmad-cache/cis/_git_preserved/refs/remotes/origin/HEAD +0 -1
  224. package/lib/bmad-cache/gds/_git_preserved/objects/pack/pack-9427a146a90c00bb542cba038874bf9671ba4dc0.idx +0 -0
  225. package/lib/bmad-cache/gds/_git_preserved/objects/pack/pack-9427a146a90c00bb542cba038874bf9671ba4dc0.rev +0 -0
  226. package/lib/bmad-cache/gds/_git_preserved/refs/remotes/origin/HEAD +0 -1
  227. package/lib/bmad-cache/gds/src/workflows/2-design/gds-create-gdd/customize.toml +0 -41
  228. package/lib/bmad-cache/gds/src/workflows/2-design/gds-create-prd/customize.toml +0 -41
  229. package/lib/bmad-cache/gds/src/workflows/2-design/gds-create-prd/data/domain-complexity.csv +0 -15
  230. package/lib/bmad-cache/gds/src/workflows/2-design/gds-create-prd/data/project-types.csv +0 -11
  231. package/lib/bmad-cache/gds/src/workflows/2-design/gds-create-ux-design/customize.toml +0 -41
  232. package/lib/bmad-cache/gds/src/workflows/2-design/gds-edit-gdd/customize.toml +0 -41
  233. package/lib/bmad-cache/gds/src/workflows/2-design/gds-edit-prd/customize.toml +0 -41
  234. package/lib/bmad-cache/gds/src/workflows/2-design/gds-validate-gdd/customize.toml +0 -41
  235. package/lib/bmad-cache/gds/src/workflows/2-design/gds-validate-prd/customize.toml +0 -41
  236. package/lib/bmad-cache/gds/src/workflows/2-design/gds-validate-prd/data/domain-complexity.csv +0 -15
  237. package/lib/bmad-cache/gds/src/workflows/2-design/gds-validate-prd/data/project-types.csv +0 -11
  238. package/lib/bmad-cache/tea/_git_preserved/objects/pack/pack-f0df537f2649464ff6c5aee241165eb9c8664227.idx +0 -0
  239. package/lib/bmad-cache/tea/_git_preserved/objects/pack/pack-f0df537f2649464ff6c5aee241165eb9c8664227.rev +0 -0
  240. package/lib/bmad-cache/tea/_git_preserved/refs/remotes/origin/HEAD +0 -1
  241. package/lib/bmad-cache/wds/_git_preserved/objects/pack/pack-96877c1c09123cccb1f91c1412184b11d2b492ad.idx +0 -0
  242. package/lib/bmad-cache/wds/_git_preserved/objects/pack/pack-96877c1c09123cccb1f91c1412184b11d2b492ad.rev +0 -0
  243. package/lib/bmad-cache/wds/_git_preserved/refs/remotes/origin/HEAD +0 -1
  244. package/lib/bmad-cache/wds/src/agents/wds-agent-freya-ux/bmad-skill-manifest.yaml +0 -12
  245. package/lib/bmad-cache/wds/src/agents/wds-agent-saga-analyst/bmad-skill-manifest.yaml +0 -12
  246. package/lib/bmad-cache/wds/src/workflows/wds-0-alignment-signoff/bmad-skill-manifest.yaml +0 -1
  247. package/lib/bmad-cache/wds/src/workflows/wds-0-project-setup/bmad-skill-manifest.yaml +0 -1
  248. package/lib/bmad-cache/wds/src/workflows/wds-1-project-brief/bmad-skill-manifest.yaml +0 -1
  249. package/lib/bmad-cache/wds/src/workflows/wds-2-trigger-mapping/bmad-skill-manifest.yaml +0 -1
  250. package/lib/bmad-cache/wds/src/workflows/wds-3-scenarios/bmad-skill-manifest.yaml +0 -1
  251. package/lib/bmad-cache/wds/src/workflows/wds-4-ux-design/bmad-skill-manifest.yaml +0 -1
  252. package/lib/bmad-cache/wds/src/workflows/wds-5-agentic-development/bmad-skill-manifest.yaml +0 -1
  253. package/lib/bmad-cache/wds/src/workflows/wds-6-asset-generation/bmad-skill-manifest.yaml +0 -1
  254. package/lib/bmad-cache/wds/src/workflows/wds-7-design-system/bmad-skill-manifest.yaml +0 -1
  255. package/lib/bmad-cache/wds/src/workflows/wds-8-product-evolution/bmad-skill-manifest.yaml +0 -1
  256. /package/lib/bmad-cache/gds/src/workflows/2-design/{gds-create-gdd → gds-gdd/assets}/game-types.csv +0 -0
  257. /package/lib/bmad-cache/gds/src/workflows/2-design/{gds-validate-gdd/data → gds-gdd/assets}/genre-complexity.csv +0 -0
package/lib/installer.js CHANGED
@@ -12,6 +12,7 @@ const MANIFEST_VERSION = '1.2.0';
12
12
  const MA_AGENTS_SOURCE = 'ma-agents';
13
13
  const TEMPLATE_PATH = path.join(__dirname, 'templates', 'project-context.template.md');
14
14
  const UNIVERSAL_INSTRUCTION_TEMPLATE_PATH = path.join(__dirname, 'templates', 'instruction-block-universal.template.md');
15
+ const GIT_INSTRUCTION_TEMPLATE_PATH = path.join(__dirname, 'templates', 'instruction-block-git.template.md');
15
16
  const ONPREM_INSTRUCTION_TEMPLATE_PATH = path.join(__dirname, 'templates', 'instruction-block-onprem.template.md');
16
17
  const CLINERULES_TEMPLATE_PATH = path.join(__dirname, 'templates', 'clinerules.template.md');
17
18
  const EXTRA_TEMPLATE_DIR = path.join(__dirname, 'templates');
@@ -133,19 +134,44 @@ function composeInstructionBlock({ profile, projectRoot } = {}) {
133
134
  );
134
135
  }
135
136
 
137
+ // Story 26.1 — the git workflow guardrail block is appended to EVERY profile
138
+ // (standard and on-prem), so this read must be as robust as the universal
139
+ // read above. Any failure to load a non-empty git template surfaces as a
140
+ // clear, path-identifying error — the guardrails must never silently vanish.
141
+ let git;
142
+ try {
143
+ git = fs.readFileSync(GIT_INSTRUCTION_TEMPLATE_PATH, 'utf-8');
144
+ } catch (err) {
145
+ throw new Error(
146
+ `git instruction template not found or unreadable at ${GIT_INSTRUCTION_TEMPLATE_PATH} — ma-agents installation may be corrupted: ${err.message}`
147
+ );
148
+ }
149
+ if (git.trim() === '') {
150
+ throw new Error(
151
+ `git instruction template at ${GIT_INSTRUCTION_TEMPLATE_PATH} is empty — ma-agents installation may be corrupted`
152
+ );
153
+ }
154
+
155
+ // Compose in the exact order universal + git (+ on-prem). Each piece is
156
+ // trailing-whitespace-normalized and joined by exactly one blank line so that
157
+ // first-insert and in-place-replace produce byte-identical marker content
158
+ // (FR176 / NFR46 idempotency).
159
+ let composed = universal.replace(/\s+$/, '') + '\n\n' + git.replace(/\s+$/, '');
160
+
136
161
  if (profile === 'on-prem') {
137
162
  if (!fs.existsSync(ONPREM_INSTRUCTION_TEMPLATE_PATH)) {
138
163
  throw new Error('on-prem profile selected but instruction-block-onprem.template.md is missing');
139
164
  }
140
165
  const onprem = fs.readFileSync(ONPREM_INSTRUCTION_TEMPLATE_PATH, 'utf-8');
141
- // Normalize both pieces so the concatenation has exactly one blank line between them
142
- // and no trailing whitespace — feeds NFR46 byte-identity.
143
- return universal.replace(/\s+$/, '') + '\n\n' + onprem.replace(/\s+$/, '') + '\n';
166
+ composed += '\n\n' + onprem.replace(/\s+$/, '');
144
167
  }
145
168
 
146
- // Normalize trailing whitespace so first-insert and in-place-replace both
147
- // produce byte-identical content inside the markers (NFR46, AC #6).
148
- return universal.replace(/\s+$/, '') + '\n';
169
+ // Bug 27.10 the source templates are authored with CRLF line endings, but the
170
+ // segment seams and terminator above are hand-written LF. That mix yields a block
171
+ // whose body lines are CRLF while the joins are LF. Normalize to pure LF once here
172
+ // so the composed block is EOL-consistent regardless of how templates were checked
173
+ // out on Windows, and so downstream marker-merge (which assumes LF) stays stable.
174
+ return composed.replace(/\r\n/g, '\n') + '\n';
149
175
  }
150
176
 
151
177
  /**
@@ -224,6 +250,17 @@ function resolveBmadOutputDirs(projectRoot) {
224
250
  const CLAUDE_CODE_HOOK_ID = 'ma-agents-verify-manifest';
225
251
  const CLAUDE_CODE_SETTINGS_FILE = '.claude/settings.json';
226
252
 
253
+ // Bug 27.8 — the SessionStart hook must point at a path that exists in a real
254
+ // (npx/node_modules) install, not at the package's own `lib/` which is never
255
+ // copied into the target. The dependency-free hook script is copied into the
256
+ // target's `.claude/hooks/` and the command resolves it via $CLAUDE_PROJECT_DIR
257
+ // (the target project root). The legacy `lib/hooks/...` command string is kept
258
+ // here only so existing installs get it removed/migrated on the next run.
259
+ const CLAUDE_CODE_HOOK_SOURCE = path.join(__dirname, 'hooks', 'claude-code', 'verify-manifest.js');
260
+ const CLAUDE_CODE_HOOK_TARGET_REL = '.claude/hooks/verify-manifest.js';
261
+ const CLAUDE_CODE_HOOK_COMMAND = `node "$CLAUDE_PROJECT_DIR/${CLAUDE_CODE_HOOK_TARGET_REL}"`;
262
+ const CLAUDE_CODE_HOOK_LEGACY_COMMAND = `node "$CLAUDE_PROJECT_DIR/lib/hooks/claude-code/verify-manifest.js"`;
263
+
227
264
  function getPackageVersion() {
228
265
  const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf-8'));
229
266
  return pkg.version;
@@ -376,13 +413,91 @@ function ensurePluginStageIgnored(projectRoot) {
376
413
  );
377
414
  }
378
415
 
416
+ // Bug 27.11 — the installer writes the `_bmad/` module tree which is
417
+ // "Installer-managed. Regenerated on every install — treat as read-only."
418
+ // Leaving it tracked guarantees churn and merge conflicts on every reinstall.
419
+ // This sister-policy to PLUGIN_STAGE_PATTERNS ensures `_bmad/` is gitignored.
420
+ //
421
+ // IMPORTANT: this targets ONLY the regenerated `_bmad/` tree. The
422
+ // `_bmad-output/` directory holds tracked project knowledge and is
423
+ // deliberately kept OUT of .gitignore (see ensureBmadOutputTracked) — the
424
+ // patterns below never match it because git treats `_bmad/` (trailing-slash
425
+ // anchored) and `_bmad-output` as distinct entries.
426
+ const BMAD_DIR_NAME = '_bmad';
427
+ const BMAD_DIR_PATTERNS = [
428
+ BMAD_DIR_NAME, // _bmad
429
+ `${BMAD_DIR_NAME}/`, // _bmad/
430
+ `/${BMAD_DIR_NAME}`, // /_bmad
431
+ `/${BMAD_DIR_NAME}/`, // /_bmad/
432
+ ];
433
+ const BMAD_DIR_CANONICAL_ENTRY = `${BMAD_DIR_NAME}/`;
434
+
435
+ /**
436
+ * Ensure `_bmad/` is present in the target project's `.gitignore`. Mirrors the
437
+ * append-only, idempotent, EOL-preserving contract of `ensurePluginStageIgnored`.
438
+ *
439
+ * - If `.gitignore` is absent, create it with the single canonical entry.
440
+ * - If any active (non-comment) line already matches any BMAD_DIR_PATTERNS
441
+ * variant, do nothing.
442
+ * - Otherwise, append `BMAD_DIR_CANONICAL_ENTRY` preserving existing EOL style.
443
+ *
444
+ * Defensive: no-op on falsy/non-string projectRoot, matching the sister helper.
445
+ *
446
+ * @param {string} projectRoot - Absolute path to the target project root.
447
+ */
448
+ function ensureBmadDirIgnored(projectRoot) {
449
+ if (typeof projectRoot !== 'string' || projectRoot.length === 0) {
450
+ return;
451
+ }
452
+
453
+ const gitignorePath = path.join(projectRoot, '.gitignore');
454
+
455
+ let content = '';
456
+ let fileExists = true;
457
+ try {
458
+ content = fs.readFileSync(gitignorePath, 'utf-8');
459
+ } catch (err) {
460
+ if (err.code !== 'ENOENT') throw err;
461
+ fileExists = false;
462
+ }
463
+
464
+ if (fileExists) {
465
+ const alreadyPresent = content.split(/\r?\n/).some(rawLine => {
466
+ const line = rawLine.trim();
467
+ if (!line || line.startsWith('#')) return false; // skip blanks & comments
468
+ return BMAD_DIR_PATTERNS.includes(line);
469
+ });
470
+ if (alreadyPresent) return; // idempotent no-op
471
+ }
472
+
473
+ const usesCrlf = fileExists && /\r\n/.test(content);
474
+ const eol = usesCrlf ? '\r\n' : '\n';
475
+
476
+ let next = content;
477
+ if (next && !next.endsWith('\n') && !next.endsWith('\r\n')) {
478
+ next += eol; // ensure the append lands on its own line
479
+ }
480
+ next += BMAD_DIR_CANONICAL_ENTRY + eol;
481
+
482
+ fs.writeFileSync(gitignorePath, next, 'utf-8');
483
+ console.log(
484
+ chalk.green(
485
+ `${BMAD_DIR_CANONICAL_ENTRY} added to .gitignore (installer-managed BMAD tree — regenerated on every install)`
486
+ )
487
+ );
488
+ }
489
+
379
490
  function ensureManifest(installPath, agentId, scope) {
380
491
  let manifest = readManifest(installPath);
381
492
  if (!manifest) {
493
+ // Bug 27.9 — when bootstrapped before any agent is known (e.g. profile
494
+ // bootstrap via setProfile → ensureManifest(root, null, 'project')), agentId
495
+ // is null. Mirror the migrate-branch guard so we never write the malformed
496
+ // `agent: null` / `agents: [null]` shape; an empty agents array is valid.
382
497
  manifest = {
383
498
  manifestVersion: MANIFEST_VERSION,
384
- agent: agentId,
385
- agents: [agentId],
499
+ agent: agentId || null,
500
+ agents: agentId ? [agentId] : [],
386
501
  scope: scope,
387
502
  skills: {}
388
503
  };
@@ -1244,6 +1359,116 @@ async function performInstall(skillId, skill, agent, installPath) {
1244
1359
  return true;
1245
1360
  }
1246
1361
 
1362
+ // --- Bug 27.16 — .agents/skills pipeline-consistency reconciliation ----------
1363
+ //
1364
+ // Two pipelines write skills: ma-agents' own standalone loop (installSkill →
1365
+ // performInstall + generateSkillsManifest — the ONLY writer of MANIFEST.yaml),
1366
+ // and bmad-method's PluginResolver (via --custom-source) which routes
1367
+ // copilot/roo/kilo to the shared `.agents/skills/` dir. The standalone loop only
1368
+ // targets `.agents/skills` when a copilot/kilocode/roo-code agent is selected.
1369
+ //
1370
+ // When the user selects only claude-code/cline/opencode, BMAD still writes the
1371
+ // BMAD-family skills into `.agents/skills` (175 of them in the Workshop repro)
1372
+ // but the standalone catalog and MANIFEST.yaml are never written there — leaving
1373
+ // a dir that looks installed but is silently partial AND missing the
1374
+ // MANIFEST.yaml the stamped instruction block points agents at.
1375
+ //
1376
+ // This pass makes `.agents/skills` pipeline-consistent: if BMAD populated it but
1377
+ // no `.agents`-targeting agent was selected (so the standalone loop skipped it),
1378
+ // install the full standalone catalog there and generate MANIFEST.yaml. The set
1379
+ // of `.agents`-targeting agent ids is derived from agents whose project skills
1380
+ // dir resolves to `.agents/skills`.
1381
+
1382
+ const AGENTS_SHARED_SKILLS_DIRNAME = '.agents';
1383
+
1384
+ /**
1385
+ * Return the list of agent ids whose project-level skills dir is the shared
1386
+ * `.agents/skills/` directory (copilot, kilocode, roo-code). Derived from the
1387
+ * agent registry's `skillsDir` so a future registry change surfaces here.
1388
+ */
1389
+ function getAgentsSharedSkillAgentIds() {
1390
+ return listAgents()
1391
+ .filter(a => a.skillsDir === path.join(AGENTS_SHARED_SKILLS_DIRNAME, 'skills') ||
1392
+ a.skillsDir === `${AGENTS_SHARED_SKILLS_DIRNAME}/skills`)
1393
+ .map(a => a.id);
1394
+ }
1395
+
1396
+ /**
1397
+ * Bug 27.16 — reconcile a BMAD-populated `.agents/skills` directory that the
1398
+ * standalone loop never targeted. No-op unless ALL of:
1399
+ * - scope === 'project'
1400
+ * - `<projectRoot>/.agents/skills` exists on disk (BMAD created it)
1401
+ * - no `.agents`-targeting agent was among the selected agents
1402
+ * - the dir has no MANIFEST.yaml (the standalone-loop signature)
1403
+ *
1404
+ * When triggered, installs the full standalone catalog into `.agents/skills`
1405
+ * (using a representative `.agents`-targeting agent for template resolution),
1406
+ * records the skills into that dir's `.ma-agents.json`, and generates
1407
+ * MANIFEST.yaml — so the dir is never BMAD-only without a manifest.
1408
+ *
1409
+ * Idempotent: once MANIFEST.yaml exists the early-return fires.
1410
+ *
1411
+ * @param {string} projectRoot
1412
+ * @param {string[]} selectedAgentIds - agent ids the user selected this run
1413
+ * @param {string} scope - 'project' | 'global'
1414
+ * @returns {Promise<{reconciled: boolean, installed: number}>}
1415
+ */
1416
+ async function reconcileAgentsSharedSkills(projectRoot, selectedAgentIds = [], scope = 'project') {
1417
+ const result = { reconciled: false, installed: 0 };
1418
+ if (scope !== 'project') return result;
1419
+ if (typeof projectRoot !== 'string' || !projectRoot) return result;
1420
+
1421
+ const sharedDir = path.join(projectRoot, AGENTS_SHARED_SKILLS_DIRNAME, 'skills');
1422
+ if (!fs.existsSync(sharedDir)) return result; // BMAD never populated it
1423
+
1424
+ const sharedAgentIds = getAgentsSharedSkillAgentIds();
1425
+ const selectedSet = new Set(selectedAgentIds || []);
1426
+ const anySharedSelected = sharedAgentIds.some(id => selectedSet.has(id));
1427
+ if (anySharedSelected) return result; // standalone loop already targeted it
1428
+
1429
+ // If a MANIFEST.yaml already exists, the dir is not standalone-orphaned.
1430
+ if (fs.existsSync(path.join(sharedDir, 'MANIFEST.yaml'))) return result;
1431
+
1432
+ // Pick a representative `.agents`-targeting agent for template resolution.
1433
+ const repAgent = sharedAgentIds.map(id => getAgent(id)).find(Boolean);
1434
+ if (!repAgent) return result; // registry has no such agent — nothing to do
1435
+
1436
+ console.log(chalk.yellow(
1437
+ ` Note: ${sharedDir} was populated by BMAD but carries no MANIFEST.yaml ` +
1438
+ `(no .agents-targeting agent selected) — backfilling the standalone catalog (bug 27.16).`
1439
+ ));
1440
+
1441
+ const skills = listSkills();
1442
+ const manifest = ensureManifest(sharedDir, repAgent.id, scope);
1443
+ const now = new Date().toISOString();
1444
+
1445
+ for (const skill of skills) {
1446
+ try {
1447
+ const ok = await performInstall(skill.id, skill, repAgent, sharedDir);
1448
+ if (!ok) continue;
1449
+ const existing = manifest.skills[skill.id];
1450
+ manifest.skills[skill.id] = {
1451
+ version: skill.version,
1452
+ installedAt: existing ? existing.installedAt : now,
1453
+ updatedAt: now,
1454
+ installerVersion: getPackageVersion(),
1455
+ agentVersion: repAgent.version
1456
+ };
1457
+ result.installed++;
1458
+ } catch (err) {
1459
+ console.log(chalk.yellow(` x ${skill.id} skipped in .agents/skills backfill: ${err.message}`));
1460
+ }
1461
+ }
1462
+
1463
+ writeManifest(sharedDir, manifest);
1464
+ await generateSkillsManifest(sharedDir);
1465
+ result.reconciled = true;
1466
+ console.log(chalk.green(
1467
+ ` Backfilled ${result.installed} standalone skill(s) + MANIFEST.yaml into ${sharedDir}`
1468
+ ));
1469
+ return result;
1470
+ }
1471
+
1247
1472
  // --- Install with upgrade detection ---
1248
1473
 
1249
1474
  async function installSkill(skillId, agentIds, customPath = '', scope = 'project', options = {}) {
@@ -1861,7 +2086,12 @@ function getStatus(agentIds, customPath = '', scope = 'project') {
1861
2086
 
1862
2087
  for (const { path: checkPath, scope: checkScope } of pathsToCheck) {
1863
2088
  const manifest = readManifest(checkPath);
1864
- if (!manifest || !manifest.skills || Object.keys(manifest.skills).length === 0) {
2089
+ // Bug 27.12 never treat the PROFILE-ONLY project-root manifest as a
2090
+ // skill inventory. The per-agent skills manifests are authoritative; a
2091
+ // manifest carrying the `project-root` scope discriminator is a
2092
+ // profile/settings store and must be skipped here.
2093
+ if (!manifest || manifest.scope === 'project-root' ||
2094
+ !manifest.skills || Object.keys(manifest.skills).length === 0) {
1865
2095
  continue;
1866
2096
  }
1867
2097
 
@@ -1903,27 +2133,49 @@ async function deployClaudeCodeHook(projectRoot) {
1903
2133
  settings.hooks.SessionStart = [];
1904
2134
  }
1905
2135
 
1906
- // Check if our hook is already present
1907
- const hookCommand = `node "$CLAUDE_PROJECT_DIR/lib/hooks/claude-code/verify-manifest.js"`;
2136
+ // Bug 27.8 copy the self-contained hook into the target so the command
2137
+ // resolves in any install (npx/node_modules/dev-repo). The legacy command
2138
+ // string (which pointed at the never-copied package `lib/`) is migrated to
2139
+ // the new command on every run.
2140
+ const hookTargetPath = path.join(projectRoot, CLAUDE_CODE_HOOK_TARGET_REL);
2141
+ await fs.ensureDir(path.dirname(hookTargetPath));
2142
+ await fs.copy(CLAUDE_CODE_HOOK_SOURCE, hookTargetPath, { overwrite: true });
2143
+
2144
+ const hookCommand = CLAUDE_CODE_HOOK_COMMAND;
2145
+ let migrated = false;
2146
+ for (const group of settings.hooks.SessionStart) {
2147
+ if (!group.hooks) continue;
2148
+ for (const h of group.hooks) {
2149
+ if (h.command === CLAUDE_CODE_HOOK_LEGACY_COMMAND || h._id === CLAUDE_CODE_HOOK_ID) {
2150
+ h.command = hookCommand;
2151
+ h._id = CLAUDE_CODE_HOOK_ID;
2152
+ migrated = true;
2153
+ }
2154
+ }
2155
+ }
2156
+
1908
2157
  const alreadyInstalled = settings.hooks.SessionStart.some(group =>
1909
2158
  group.hooks && group.hooks.some(h => h.command === hookCommand)
1910
2159
  );
1911
2160
 
1912
- if (alreadyInstalled) {
1913
- return; // Already deployed
2161
+ if (!alreadyInstalled) {
2162
+ settings.hooks.SessionStart.push({
2163
+ matcher: 'startup',
2164
+ hooks: [
2165
+ {
2166
+ type: 'command',
2167
+ command: hookCommand,
2168
+ _id: CLAUDE_CODE_HOOK_ID
2169
+ }
2170
+ ]
2171
+ });
2172
+ } else if (!migrated) {
2173
+ // Hook entry already current and file copied — still ensure settings exist.
2174
+ await fs.ensureDir(path.dirname(settingsPath));
2175
+ await fs.writeFile(settingsPath, JSON.stringify(settings, null, 2) + '\n', 'utf-8');
2176
+ return;
1914
2177
  }
1915
2178
 
1916
- settings.hooks.SessionStart.push({
1917
- matcher: 'startup',
1918
- hooks: [
1919
- {
1920
- type: 'command',
1921
- command: hookCommand,
1922
- _id: CLAUDE_CODE_HOOK_ID
1923
- }
1924
- ]
1925
- });
1926
-
1927
2179
  await fs.ensureDir(path.dirname(settingsPath));
1928
2180
  await fs.writeFile(settingsPath, JSON.stringify(settings, null, 2) + '\n', 'utf-8');
1929
2181
  console.log(chalk.cyan(' + Deployed Claude Code verify-manifest hook'));
@@ -1935,6 +2187,15 @@ async function deployClaudeCodeHook(projectRoot) {
1935
2187
  async function removeClaudeCodeHook(projectRoot) {
1936
2188
  const settingsPath = path.join(projectRoot, CLAUDE_CODE_SETTINGS_FILE);
1937
2189
 
2190
+ // Bug 27.8 — remove the copied hook file first, before any settings.json
2191
+ // early-return, so a missing/corrupt settings.json never orphans the file.
2192
+ const hookTargetPath = path.join(projectRoot, CLAUDE_CODE_HOOK_TARGET_REL);
2193
+ try {
2194
+ await fs.remove(hookTargetPath);
2195
+ } catch {
2196
+ // best-effort cleanup — never fail uninstall over a missing file
2197
+ }
2198
+
1938
2199
  if (!fs.existsSync(settingsPath)) return;
1939
2200
 
1940
2201
  let settings;
@@ -1946,10 +2207,15 @@ async function removeClaudeCodeHook(projectRoot) {
1946
2207
 
1947
2208
  if (!settings.hooks || !settings.hooks.SessionStart) return;
1948
2209
 
1949
- const hookCommand = `node "$CLAUDE_PROJECT_DIR/lib/hooks/claude-code/verify-manifest.js"`;
2210
+ // Match both the current command and the legacy package-relative command so
2211
+ // older installs get cleaned up too.
1950
2212
  settings.hooks.SessionStart = settings.hooks.SessionStart.filter(group => {
1951
2213
  if (!group.hooks) return true;
1952
- group.hooks = group.hooks.filter(h => h.command !== hookCommand && h._id !== CLAUDE_CODE_HOOK_ID);
2214
+ group.hooks = group.hooks.filter(h =>
2215
+ h.command !== CLAUDE_CODE_HOOK_COMMAND &&
2216
+ h.command !== CLAUDE_CODE_HOOK_LEGACY_COMMAND &&
2217
+ h._id !== CLAUDE_CODE_HOOK_ID
2218
+ );
1953
2219
  return group.hooks.length > 0;
1954
2220
  });
1955
2221
 
@@ -1988,6 +2254,9 @@ module.exports = {
1988
2254
  removeClaudeCodeHook,
1989
2255
  ensureBmadOutputTracked,
1990
2256
  ensurePluginStageIgnored,
2257
+ ensureBmadDirIgnored,
2258
+ reconcileAgentsSharedSkills,
2259
+ getAgentsSharedSkillAgentIds,
1991
2260
  generateSkillsManifest,
1992
2261
  generateProjectContext,
1993
2262
  generateRepoLayoutSection,
@@ -2000,6 +2269,7 @@ module.exports = {
2000
2269
  buildBackupFilename,
2001
2270
  formatBackupTimestamp,
2002
2271
  UNIVERSAL_INSTRUCTION_TEMPLATE_PATH,
2272
+ GIT_INSTRUCTION_TEMPLATE_PATH,
2003
2273
  ONPREM_INSTRUCTION_TEMPLATE_PATH,
2004
2274
  // Story 21.4 — AGENTS.md template, markdown-markers merger, extraInstructionTemplates processor.
2005
2275
  // Story 21.3 (rebased) — yaml-customModes merger dispatch is integrated into stampExtraInstructionTemplates.