specweave 0.32.0 → 0.32.3

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 (347) hide show
  1. package/CLAUDE.md +215 -2
  2. package/README.md +22 -0
  3. package/bin/specweave.js +52 -1
  4. package/dist/plugins/specweave-ado/lib/ado-duplicate-detector.d.ts +100 -0
  5. package/dist/plugins/specweave-ado/lib/ado-duplicate-detector.d.ts.map +1 -0
  6. package/dist/plugins/specweave-ado/lib/ado-duplicate-detector.js +291 -0
  7. package/dist/plugins/specweave-ado/lib/ado-duplicate-detector.js.map +1 -0
  8. package/dist/plugins/specweave-jira/lib/jira-duplicate-detector.d.ts +103 -0
  9. package/dist/plugins/specweave-jira/lib/jira-duplicate-detector.d.ts.map +1 -0
  10. package/dist/plugins/specweave-jira/lib/jira-duplicate-detector.js +310 -0
  11. package/dist/plugins/specweave-jira/lib/jira-duplicate-detector.js.map +1 -0
  12. package/dist/plugins/specweave-jira/lib/jira-permission-gate.d.ts +126 -0
  13. package/dist/plugins/specweave-jira/lib/jira-permission-gate.d.ts.map +1 -0
  14. package/dist/plugins/specweave-jira/lib/jira-permission-gate.js +207 -0
  15. package/dist/plugins/specweave-jira/lib/jira-permission-gate.js.map +1 -0
  16. package/dist/src/adapters/codex/README.md +1 -1
  17. package/dist/src/adapters/codex/adapter.js +1 -1
  18. package/dist/src/cli/commands/archive.d.ts +2 -0
  19. package/dist/src/cli/commands/archive.d.ts.map +1 -1
  20. package/dist/src/cli/commands/archive.js +33 -0
  21. package/dist/src/cli/commands/archive.js.map +1 -1
  22. package/dist/src/cli/commands/cache.d.ts +17 -0
  23. package/dist/src/cli/commands/cache.d.ts.map +1 -0
  24. package/dist/src/cli/commands/cache.js +126 -0
  25. package/dist/src/cli/commands/cache.js.map +1 -0
  26. package/dist/src/cli/commands/context.d.ts +92 -0
  27. package/dist/src/cli/commands/context.d.ts.map +1 -0
  28. package/dist/src/cli/commands/context.js +205 -0
  29. package/dist/src/cli/commands/context.js.map +1 -0
  30. package/dist/src/cli/commands/init.d.ts.map +1 -1
  31. package/dist/src/cli/commands/init.js +112 -70
  32. package/dist/src/cli/commands/init.js.map +1 -1
  33. package/dist/src/cli/commands/plan/increment-detector.js +2 -2
  34. package/dist/src/cli/commands/plan/increment-detector.js.map +1 -1
  35. package/dist/src/cli/commands/sync-spec-commits.js +1 -1
  36. package/dist/src/cli/commands/sync-spec-commits.js.map +1 -1
  37. package/dist/src/cli/commands/sync-specs.js +2 -2
  38. package/dist/src/cli/commands/sync-specs.js.map +1 -1
  39. package/dist/src/cli/helpers/github/increment-profile-selector.js +1 -1
  40. package/dist/src/cli/helpers/github/increment-profile-selector.js.map +1 -1
  41. package/dist/src/cli/helpers/init/external-import.d.ts +3 -0
  42. package/dist/src/cli/helpers/init/external-import.d.ts.map +1 -1
  43. package/dist/src/cli/helpers/init/external-import.js +17 -4
  44. package/dist/src/cli/helpers/init/external-import.js.map +1 -1
  45. package/dist/src/cli/helpers/init/index.d.ts +1 -0
  46. package/dist/src/cli/helpers/init/index.d.ts.map +1 -1
  47. package/dist/src/cli/helpers/init/index.js +2 -0
  48. package/dist/src/cli/helpers/init/index.js.map +1 -1
  49. package/dist/src/cli/helpers/init/jira-ado-auto-detect.d.ts +70 -0
  50. package/dist/src/cli/helpers/init/jira-ado-auto-detect.d.ts.map +1 -1
  51. package/dist/src/cli/helpers/init/jira-ado-auto-detect.js +214 -4
  52. package/dist/src/cli/helpers/init/jira-ado-auto-detect.js.map +1 -1
  53. package/dist/src/cli/helpers/init/living-docs-preflight.d.ts +4 -0
  54. package/dist/src/cli/helpers/init/living-docs-preflight.d.ts.map +1 -1
  55. package/dist/src/cli/helpers/init/living-docs-preflight.js +34 -3
  56. package/dist/src/cli/helpers/init/living-docs-preflight.js.map +1 -1
  57. package/dist/src/cli/helpers/init/testing-config.d.ts +3 -0
  58. package/dist/src/cli/helpers/init/testing-config.d.ts.map +1 -1
  59. package/dist/src/cli/helpers/init/testing-config.js +9 -2
  60. package/dist/src/cli/helpers/init/testing-config.js.map +1 -1
  61. package/dist/src/cli/helpers/init/translation-config.d.ts +3 -0
  62. package/dist/src/cli/helpers/init/translation-config.d.ts.map +1 -1
  63. package/dist/src/cli/helpers/init/translation-config.js +21 -4
  64. package/dist/src/cli/helpers/init/translation-config.js.map +1 -1
  65. package/dist/src/cli/helpers/init/wizard-navigation.d.ts +45 -0
  66. package/dist/src/cli/helpers/init/wizard-navigation.d.ts.map +1 -0
  67. package/dist/src/cli/helpers/init/wizard-navigation.js +97 -0
  68. package/dist/src/cli/helpers/init/wizard-navigation.js.map +1 -0
  69. package/dist/src/cli/workers/living-docs-worker.js +66 -1
  70. package/dist/src/cli/workers/living-docs-worker.js.map +1 -1
  71. package/dist/src/config/types.d.ts +203 -1208
  72. package/dist/src/config/types.d.ts.map +1 -1
  73. package/dist/src/core/discrepancy/increment-generator.d.ts.map +1 -1
  74. package/dist/src/core/discrepancy/increment-generator.js +5 -2
  75. package/dist/src/core/discrepancy/increment-generator.js.map +1 -1
  76. package/dist/src/core/increment/duplicate-detector.js +2 -2
  77. package/dist/src/core/increment/duplicate-detector.js.map +1 -1
  78. package/dist/src/core/increment/increment-archiver.d.ts +49 -4
  79. package/dist/src/core/increment/increment-archiver.d.ts.map +1 -1
  80. package/dist/src/core/increment/increment-archiver.js +123 -22
  81. package/dist/src/core/increment/increment-archiver.js.map +1 -1
  82. package/dist/src/core/increment/increment-status.js +2 -2
  83. package/dist/src/core/increment/increment-status.js.map +1 -1
  84. package/dist/src/core/increment/increment-utils.d.ts +150 -0
  85. package/dist/src/core/increment/increment-utils.d.ts.map +1 -1
  86. package/dist/src/core/increment/increment-utils.js +216 -4
  87. package/dist/src/core/increment/increment-utils.js.map +1 -1
  88. package/dist/src/core/increment/metadata-validator.js +1 -1
  89. package/dist/src/core/increment/metadata-validator.js.map +1 -1
  90. package/dist/src/core/living-docs/feature-archiver.d.ts +4 -0
  91. package/dist/src/core/living-docs/feature-archiver.d.ts.map +1 -1
  92. package/dist/src/core/living-docs/feature-archiver.js +32 -10
  93. package/dist/src/core/living-docs/feature-archiver.js.map +1 -1
  94. package/dist/src/core/living-docs/feature-id-manager.d.ts.map +1 -1
  95. package/dist/src/core/living-docs/feature-id-manager.js +8 -4
  96. package/dist/src/core/living-docs/feature-id-manager.js.map +1 -1
  97. package/dist/src/core/living-docs/governance/ecosystem-detector.d.ts +38 -0
  98. package/dist/src/core/living-docs/governance/ecosystem-detector.d.ts.map +1 -0
  99. package/dist/src/core/living-docs/governance/ecosystem-detector.js +325 -0
  100. package/dist/src/core/living-docs/governance/ecosystem-detector.js.map +1 -0
  101. package/dist/src/core/living-docs/governance/frontend-standards-parser.d.ts +74 -0
  102. package/dist/src/core/living-docs/governance/frontend-standards-parser.d.ts.map +1 -0
  103. package/dist/src/core/living-docs/governance/frontend-standards-parser.js +366 -0
  104. package/dist/src/core/living-docs/governance/frontend-standards-parser.js.map +1 -0
  105. package/dist/src/core/living-docs/governance/go-standards-parser.d.ts +64 -0
  106. package/dist/src/core/living-docs/governance/go-standards-parser.d.ts.map +1 -0
  107. package/dist/src/core/living-docs/governance/go-standards-parser.js +229 -0
  108. package/dist/src/core/living-docs/governance/go-standards-parser.js.map +1 -0
  109. package/dist/src/core/living-docs/governance/index.d.ts +50 -0
  110. package/dist/src/core/living-docs/governance/index.d.ts.map +1 -0
  111. package/dist/src/core/living-docs/governance/index.js +56 -0
  112. package/dist/src/core/living-docs/governance/index.js.map +1 -0
  113. package/dist/src/core/living-docs/governance/java-standards-parser.d.ts +89 -0
  114. package/dist/src/core/living-docs/governance/java-standards-parser.d.ts.map +1 -0
  115. package/dist/src/core/living-docs/governance/java-standards-parser.js +356 -0
  116. package/dist/src/core/living-docs/governance/java-standards-parser.js.map +1 -0
  117. package/dist/src/core/living-docs/governance/python-standards-parser.d.ts +83 -0
  118. package/dist/src/core/living-docs/governance/python-standards-parser.d.ts.map +1 -0
  119. package/dist/src/core/living-docs/governance/python-standards-parser.js +347 -0
  120. package/dist/src/core/living-docs/governance/python-standards-parser.js.map +1 -0
  121. package/dist/src/core/living-docs/governance/standards-generator.d.ts +38 -0
  122. package/dist/src/core/living-docs/governance/standards-generator.d.ts.map +1 -0
  123. package/dist/src/core/living-docs/governance/standards-generator.js +476 -0
  124. package/dist/src/core/living-docs/governance/standards-generator.js.map +1 -0
  125. package/dist/src/core/living-docs/hierarchy-mapper.js +3 -3
  126. package/dist/src/core/living-docs/hierarchy-mapper.js.map +1 -1
  127. package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.d.ts +18 -0
  128. package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.d.ts.map +1 -0
  129. package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.js +299 -0
  130. package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.js.map +1 -0
  131. package/dist/src/core/living-docs/intelligent-analyzer/deep-repo-analyzer.d.ts +15 -0
  132. package/dist/src/core/living-docs/intelligent-analyzer/deep-repo-analyzer.d.ts.map +1 -0
  133. package/dist/src/core/living-docs/intelligent-analyzer/deep-repo-analyzer.js +138 -0
  134. package/dist/src/core/living-docs/intelligent-analyzer/deep-repo-analyzer.js.map +1 -0
  135. package/dist/src/core/living-docs/intelligent-analyzer/file-sampler.d.ts +24 -0
  136. package/dist/src/core/living-docs/intelligent-analyzer/file-sampler.d.ts.map +1 -0
  137. package/dist/src/core/living-docs/intelligent-analyzer/file-sampler.js +198 -0
  138. package/dist/src/core/living-docs/intelligent-analyzer/file-sampler.js.map +1 -0
  139. package/dist/src/core/living-docs/intelligent-analyzer/inconsistency-detector.d.ts +17 -0
  140. package/dist/src/core/living-docs/intelligent-analyzer/inconsistency-detector.d.ts.map +1 -0
  141. package/dist/src/core/living-docs/intelligent-analyzer/inconsistency-detector.js +241 -0
  142. package/dist/src/core/living-docs/intelligent-analyzer/inconsistency-detector.js.map +1 -0
  143. package/dist/src/core/living-docs/intelligent-analyzer/index.d.ts +28 -0
  144. package/dist/src/core/living-docs/intelligent-analyzer/index.d.ts.map +1 -0
  145. package/dist/src/core/living-docs/intelligent-analyzer/index.js +197 -0
  146. package/dist/src/core/living-docs/intelligent-analyzer/index.js.map +1 -0
  147. package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.d.ts +22 -0
  148. package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.d.ts.map +1 -0
  149. package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.js +482 -0
  150. package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.js.map +1 -0
  151. package/dist/src/core/living-docs/intelligent-analyzer/strategy-generator.d.ts +42 -0
  152. package/dist/src/core/living-docs/intelligent-analyzer/strategy-generator.d.ts.map +1 -0
  153. package/dist/src/core/living-docs/intelligent-analyzer/strategy-generator.js +343 -0
  154. package/dist/src/core/living-docs/intelligent-analyzer/strategy-generator.js.map +1 -0
  155. package/dist/src/core/living-docs/intelligent-analyzer/types.d.ts +190 -0
  156. package/dist/src/core/living-docs/intelligent-analyzer/types.d.ts.map +1 -0
  157. package/dist/src/core/living-docs/intelligent-analyzer/types.js +7 -0
  158. package/dist/src/core/living-docs/intelligent-analyzer/types.js.map +1 -0
  159. package/dist/src/core/living-docs/living-docs-sync.d.ts +11 -3
  160. package/dist/src/core/living-docs/living-docs-sync.d.ts.map +1 -1
  161. package/dist/src/core/living-docs/living-docs-sync.js +53 -10
  162. package/dist/src/core/living-docs/living-docs-sync.js.map +1 -1
  163. package/dist/src/core/living-docs/module-analyzer.d.ts +22 -0
  164. package/dist/src/core/living-docs/module-analyzer.d.ts.map +1 -1
  165. package/dist/src/core/living-docs/module-analyzer.js +123 -19
  166. package/dist/src/core/living-docs/module-analyzer.js.map +1 -1
  167. package/dist/src/core/llm/provider-factory.js +2 -2
  168. package/dist/src/core/llm/provider-factory.js.map +1 -1
  169. package/dist/src/core/llm/providers/anthropic-provider.js +1 -1
  170. package/dist/src/core/llm/providers/bedrock-provider.d.ts.map +1 -1
  171. package/dist/src/core/llm/providers/bedrock-provider.js +8 -4
  172. package/dist/src/core/llm/providers/bedrock-provider.js.map +1 -1
  173. package/dist/src/core/sync/spec-increment-mapper.js +3 -3
  174. package/dist/src/core/sync/spec-increment-mapper.js.map +1 -1
  175. package/dist/src/importers/item-converter.d.ts +25 -0
  176. package/dist/src/importers/item-converter.d.ts.map +1 -1
  177. package/dist/src/importers/item-converter.js +135 -5
  178. package/dist/src/importers/item-converter.js.map +1 -1
  179. package/dist/src/importers/jira-importer.d.ts +14 -0
  180. package/dist/src/importers/jira-importer.d.ts.map +1 -1
  181. package/dist/src/importers/jira-importer.js +75 -0
  182. package/dist/src/importers/jira-importer.js.map +1 -1
  183. package/dist/src/init/architecture/types.d.ts +33 -140
  184. package/dist/src/init/architecture/types.d.ts.map +1 -1
  185. package/dist/src/init/compliance/types.d.ts +30 -27
  186. package/dist/src/init/compliance/types.d.ts.map +1 -1
  187. package/dist/src/init/repo/types.d.ts +11 -34
  188. package/dist/src/init/repo/types.d.ts.map +1 -1
  189. package/dist/src/init/research/src/config/types.d.ts +15 -82
  190. package/dist/src/init/research/src/config/types.d.ts.map +1 -1
  191. package/dist/src/init/research/types.d.ts +38 -93
  192. package/dist/src/init/research/types.d.ts.map +1 -1
  193. package/dist/src/init/team/types.d.ts +4 -42
  194. package/dist/src/init/team/types.d.ts.map +1 -1
  195. package/dist/src/integrations/jira/jira-token-provider.d.ts +93 -0
  196. package/dist/src/integrations/jira/jira-token-provider.d.ts.map +1 -0
  197. package/dist/src/integrations/jira/jira-token-provider.js +160 -0
  198. package/dist/src/integrations/jira/jira-token-provider.js.map +1 -0
  199. package/dist/src/sync/ado-reconciler.d.ts +92 -0
  200. package/dist/src/sync/ado-reconciler.d.ts.map +1 -0
  201. package/dist/src/sync/ado-reconciler.js +335 -0
  202. package/dist/src/sync/ado-reconciler.js.map +1 -0
  203. package/dist/src/sync/jira-reconciler.d.ts +106 -0
  204. package/dist/src/sync/jira-reconciler.d.ts.map +1 -0
  205. package/dist/src/sync/jira-reconciler.js +405 -0
  206. package/dist/src/sync/jira-reconciler.js.map +1 -0
  207. package/dist/src/types/dashboard-cache.d.ts +181 -0
  208. package/dist/src/types/dashboard-cache.d.ts.map +1 -0
  209. package/dist/src/types/dashboard-cache.js +65 -0
  210. package/dist/src/types/dashboard-cache.js.map +1 -0
  211. package/dist/src/types/model-selection.d.ts +6 -4
  212. package/dist/src/types/model-selection.d.ts.map +1 -1
  213. package/dist/src/types/model-selection.js +3 -1
  214. package/dist/src/types/model-selection.js.map +1 -1
  215. package/dist/src/utils/docs-validator.d.ts +131 -0
  216. package/dist/src/utils/docs-validator.d.ts.map +1 -0
  217. package/dist/src/utils/docs-validator.js +529 -0
  218. package/dist/src/utils/docs-validator.js.map +1 -0
  219. package/dist/src/utils/external-tool-drift-detector.d.ts +1 -1
  220. package/dist/src/utils/external-tool-drift-detector.d.ts.map +1 -1
  221. package/dist/src/utils/external-tool-drift-detector.js +5 -4
  222. package/dist/src/utils/external-tool-drift-detector.js.map +1 -1
  223. package/dist/src/utils/feature-id-collision.js +1 -1
  224. package/dist/src/utils/feature-id-collision.js.map +1 -1
  225. package/dist/src/utils/feature-id-derivation.d.ts +8 -3
  226. package/dist/src/utils/feature-id-derivation.d.ts.map +1 -1
  227. package/dist/src/utils/feature-id-derivation.js +14 -6
  228. package/dist/src/utils/feature-id-derivation.js.map +1 -1
  229. package/dist/src/utils/html-to-mdx.d.ts +1 -0
  230. package/dist/src/utils/html-to-mdx.d.ts.map +1 -1
  231. package/dist/src/utils/html-to-mdx.js +43 -5
  232. package/dist/src/utils/html-to-mdx.js.map +1 -1
  233. package/dist/src/utils/model-selection.d.ts +3 -4
  234. package/dist/src/utils/model-selection.d.ts.map +1 -1
  235. package/dist/src/utils/model-selection.js +3 -4
  236. package/dist/src/utils/model-selection.js.map +1 -1
  237. package/package.json +1 -1
  238. package/plugins/specweave/agents/code-standards-detective/AGENT.md +48 -0
  239. package/plugins/specweave/agents/pm/AGENT.md +10 -7
  240. package/plugins/specweave/commands/specweave-archive-features.md +5 -7
  241. package/plugins/specweave/commands/specweave-archive.md +2 -1
  242. package/plugins/specweave/commands/specweave-costs.md +4 -4
  243. package/plugins/specweave/commands/specweave-do.md +44 -10
  244. package/plugins/specweave/commands/specweave-done.md +109 -0
  245. package/plugins/specweave/commands/specweave-import-external.md +45 -18
  246. package/plugins/specweave/commands/specweave-increment.md +331 -33
  247. package/plugins/specweave/commands/specweave-jobs.md +2 -2
  248. package/plugins/specweave/commands/specweave-progress.md +4 -4
  249. package/plugins/specweave/commands/specweave-restore-feature.md +5 -4
  250. package/plugins/specweave/commands/specweave-sync-docs.md +1 -1
  251. package/plugins/specweave/commands/specweave-sync-specs.md +216 -322
  252. package/plugins/specweave/commands/specweave-validate-features.md +13 -8
  253. package/plugins/specweave/commands/specweave-validate.md +27 -1
  254. package/plugins/specweave/hooks/docs-changed.sh.backup +79 -0
  255. package/plugins/specweave/hooks/hooks.json +43 -4
  256. package/plugins/specweave/hooks/human-input-required.sh.backup +75 -0
  257. package/plugins/specweave/hooks/lib/common-setup.sh +375 -0
  258. package/plugins/specweave/hooks/lib/crash-prevention.sh +336 -0
  259. package/plugins/specweave/hooks/post-first-increment.sh.backup +61 -0
  260. package/plugins/specweave/hooks/post-increment-change.sh.backup +98 -0
  261. package/plugins/specweave/hooks/post-increment-completion.sh.backup +231 -0
  262. package/plugins/specweave/hooks/post-increment-planning.sh.backup +1048 -0
  263. package/plugins/specweave/hooks/post-increment-status-change.sh.backup +147 -0
  264. package/plugins/specweave/hooks/post-spec-update.sh.backup +158 -0
  265. package/plugins/specweave/hooks/post-task-completion.sh +4 -23
  266. package/plugins/specweave/hooks/post-user-story-complete.sh.backup +179 -0
  267. package/plugins/specweave/hooks/pre-command-deduplication.sh +1 -6
  268. package/plugins/specweave/hooks/pre-command-deduplication.sh.backup +83 -0
  269. package/plugins/specweave/hooks/pre-implementation.sh.backup +67 -0
  270. package/plugins/specweave/hooks/pre-task-completion.sh +8 -37
  271. package/plugins/specweave/hooks/pre-task-completion.sh.backup +194 -0
  272. package/plugins/specweave/hooks/pre-tool-use.sh +2 -11
  273. package/plugins/specweave/hooks/pre-tool-use.sh.backup +133 -0
  274. package/plugins/specweave/hooks/spec-project-validator.sh +80 -25
  275. package/plugins/specweave/hooks/universal/dispatcher.mjs +135 -42
  276. package/plugins/specweave/hooks/universal/fail-fast-wrapper.sh +183 -0
  277. package/plugins/specweave/hooks/user-prompt-submit.sh +140 -38
  278. package/plugins/specweave/hooks/user-prompt-submit.sh.backup +386 -0
  279. package/plugins/specweave/hooks/v2/dispatchers/post-tool-use.sh +12 -0
  280. package/plugins/specweave/hooks/v2/dispatchers/session-start.sh +89 -0
  281. package/plugins/specweave/hooks/v2/guards/bash-file-guard.sh +211 -0
  282. package/plugins/specweave/hooks/v2/guards/bash-file-guard.test.sh +163 -0
  283. package/plugins/specweave/hooks/v2/guards/completion-guard.sh +26 -28
  284. package/plugins/specweave/hooks/v2/guards/features-folder-guard.sh +50 -0
  285. package/plugins/specweave/hooks/v2/guards/increment-duplicate-guard.sh +135 -0
  286. package/plugins/specweave/lib/vendor/core/increment/duplicate-detector.js +2 -2
  287. package/plugins/specweave/lib/vendor/core/increment/duplicate-detector.js.map +1 -1
  288. package/plugins/specweave/scripts/README.md +166 -0
  289. package/plugins/specweave/scripts/cleanup-state.sh +142 -0
  290. package/plugins/specweave/scripts/force-kill.sh +142 -0
  291. package/plugins/specweave/scripts/jobs.js +171 -0
  292. package/plugins/specweave/scripts/progress.js +170 -0
  293. package/plugins/specweave/scripts/read-costs.sh +132 -0
  294. package/plugins/specweave/scripts/read-jobs.sh +324 -0
  295. package/plugins/specweave/scripts/read-progress.sh +185 -0
  296. package/plugins/specweave/scripts/read-status.sh +146 -0
  297. package/plugins/specweave/scripts/read-workflow.sh +173 -0
  298. package/plugins/specweave/scripts/rebuild-dashboard-cache.sh +327 -0
  299. package/plugins/specweave/scripts/session-watchdog.sh +192 -0
  300. package/plugins/specweave/scripts/status.js +154 -0
  301. package/plugins/specweave/scripts/update-dashboard-cache.sh +281 -0
  302. package/plugins/specweave/skills/code-standards-analyzer/SKILL.md +58 -6
  303. package/plugins/specweave/skills/increment-planner/SKILL.md +388 -48
  304. package/plugins/specweave/skills/increment-planner/templates/spec-multi-project.md +17 -7
  305. package/plugins/specweave/skills/increment-planner/templates/spec-single-project.md +6 -1
  306. package/plugins/specweave/skills/increment-planner/templates/tasks-multi-project.md +1 -1
  307. package/plugins/specweave/skills/increment-planner/templates/tasks-single-project.md +1 -1
  308. package/plugins/specweave/skills/instant-status/SKILL.md +70 -0
  309. package/plugins/specweave-ado/commands/cleanup-duplicates.md +212 -0
  310. package/plugins/specweave-ado/commands/reconcile.md +120 -0
  311. package/plugins/specweave-ado/hooks/post-living-docs-update.sh.backup +353 -0
  312. package/plugins/specweave-ado/hooks/post-task-completion.sh.backup +172 -0
  313. package/plugins/specweave-ado/lib/ado-duplicate-detector.js +279 -0
  314. package/plugins/specweave-ado/lib/ado-duplicate-detector.ts +407 -0
  315. package/plugins/specweave-ado/lib/enhanced-ado-sync.js +170 -0
  316. package/plugins/specweave-docs/commands/build.md +32 -4
  317. package/plugins/specweave-docs/commands/preview.md +43 -1
  318. package/plugins/specweave-docs/commands/validate.md +250 -0
  319. package/plugins/specweave-github/agents/github-manager/AGENT.md +2 -2
  320. package/plugins/specweave-github/hooks/.specweave/logs/hooks-debug.log +1262 -0
  321. package/plugins/specweave-github/hooks/post-task-completion.sh.backup +258 -0
  322. package/plugins/specweave-github/lib/enhanced-github-sync.js +220 -0
  323. package/plugins/specweave-infrastructure/skills/hetzner-provisioner/README.md +1 -1
  324. package/plugins/specweave-jira/agents/jira-manager/AGENT.md +1 -1
  325. package/plugins/specweave-jira/agents/jira-multi-project-mapper/AGENT.md +530 -0
  326. package/plugins/specweave-jira/agents/jira-sync-judge/AGENT.md +438 -0
  327. package/plugins/specweave-jira/commands/cleanup-duplicates.md +219 -0
  328. package/plugins/specweave-jira/commands/close.md +297 -0
  329. package/plugins/specweave-jira/commands/create.md +198 -0
  330. package/plugins/specweave-jira/commands/reconcile.md +123 -0
  331. package/plugins/specweave-jira/commands/status.md +215 -0
  332. package/plugins/specweave-jira/hooks/post-task-completion.sh.backup +172 -0
  333. package/plugins/specweave-jira/lib/enhanced-jira-sync.js +134 -0
  334. package/plugins/specweave-jira/lib/jira-duplicate-detector.js +296 -0
  335. package/plugins/specweave-jira/lib/jira-duplicate-detector.ts +434 -0
  336. package/plugins/specweave-jira/lib/jira-permission-gate.js +160 -0
  337. package/plugins/specweave-jira/lib/jira-permission-gate.ts +276 -0
  338. package/plugins/specweave-jira/lib/jira-profile-resolver.js +222 -0
  339. package/plugins/specweave-jira/lib/jira-profile-resolver.ts +427 -0
  340. package/plugins/specweave-jira/reference/jira-specweave-mapping.md +16 -11
  341. package/plugins/specweave-release/commands/specweave-release-npm.md +140 -14
  342. package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +1254 -0
  343. package/plugins/specweave-release/hooks/post-task-completion.sh.backup +110 -0
  344. package/plugins/specweave/hooks/post-edit-spec.sh +0 -265
  345. package/plugins/specweave/hooks/post-write-spec.sh +0 -267
  346. package/plugins/specweave/hooks/pre-edit-spec.sh +0 -151
  347. package/plugins/specweave/hooks/pre-write-spec.sh +0 -151
@@ -167,11 +167,7 @@ fi
167
167
  if [ "$COMPLETING_TASK" = "false" ]; then
168
168
  echo "[$(date)] ⏭️ No tasks being completed, skipping validation" >> "$DEBUG_LOG" 2>/dev/null || true
169
169
  rm -f "$STDIN_DATA"
170
- cat <<EOF
171
- {
172
- "continue": true
173
- }
174
- EOF
170
+ echo '{"continue":true}'
175
171
  exit 0
176
172
  fi
177
173
 
@@ -184,11 +180,7 @@ CURRENT_INCREMENT=$(ls -td .specweave/increments/*/ 2>/dev/null | xargs -n1 base
184
180
  if [ -z "$CURRENT_INCREMENT" ]; then
185
181
  echo "[$(date)] ℹ️ No active increment found, skipping validation" >> "$DEBUG_LOG" 2>/dev/null || true
186
182
  rm -f "$STDIN_DATA"
187
- cat <<EOF
188
- {
189
- "continue": true
190
- }
191
- EOF
183
+ echo '{"continue":true}'
192
184
  exit 0
193
185
  fi
194
186
 
@@ -197,11 +189,7 @@ TASKS_MD=".specweave/increments/$CURRENT_INCREMENT/tasks.md"
197
189
  if [ ! -f "$TASKS_MD" ]; then
198
190
  echo "[$(date)] ℹ️ tasks.md not found for $CURRENT_INCREMENT (increment may be in planning stage)" >> "$DEBUG_LOG" 2>/dev/null || true
199
191
  rm -f "$STDIN_DATA"
200
- cat <<EOF
201
- {
202
- "continue": true
203
- }
204
- EOF
192
+ echo '{"continue":true}'
205
193
  exit 0
206
194
  fi
207
195
 
@@ -231,12 +219,7 @@ fi
231
219
  if [ -z "$VALIDATOR_SCRIPT" ] || ! command -v node &> /dev/null; then
232
220
  echo "[$(date)] ⚠️ AC test validator not found or Node.js missing" >> "$DEBUG_LOG" 2>/dev/null || true
233
221
  rm -f "$STDIN_DATA"
234
- cat <<EOF
235
- {
236
- "continue": true,
237
- "systemMessage": "⚠️ Warning: AC test validator not available. Task completion validation skipped. Install Node.js and rebuild SpecWeave to enable validation."
238
- }
239
- EOF
222
+ echo '{"continue":true,"systemMessage":"⚠️ Warning: AC test validator not available. Task completion validation skipped. Install Node.js and rebuild SpecWeave to enable validation."}'
240
223
  exit 0
241
224
  fi
242
225
 
@@ -262,16 +245,11 @@ if [ "$VALIDATION_EXIT_CODE" = "0" ]; then
262
245
  # Reset circuit breaker on success
263
246
  echo "0" > "$CIRCUIT_BREAKER_FILE" 2>/dev/null || true
264
247
 
265
- VALIDATION_SUMMARY=$(cat "$VALIDATION_OUTPUT" | tail -5 | tr '\n' ' ')
248
+ VALIDATION_SUMMARY=$(cat "$VALIDATION_OUTPUT" | tail -5 | tr '\n' ' ' | sed 's/"/\\"/g')
266
249
 
267
250
  rm -f "$VALIDATION_OUTPUT"
268
251
 
269
- cat <<EOF
270
- {
271
- "continue": true,
272
- "systemMessage": "✅ AC Test Validation Passed: All acceptance criteria have passing tests. Task completion allowed. ${VALIDATION_SUMMARY}"
273
- }
274
- EOF
252
+ printf '{"continue":true,"systemMessage":"✅ AC Test Validation Passed: All acceptance criteria have passing tests. Task completion allowed. %s"}\n' "$VALIDATION_SUMMARY"
275
253
  else
276
254
  # Validation failed - block completion
277
255
  echo "[$(date)] ❌ AC test validation failed" >> "$DEBUG_LOG" 2>/dev/null || true
@@ -280,18 +258,11 @@ else
280
258
  CURRENT_FAILURES=$(cat "$CIRCUIT_BREAKER_FILE" 2>/dev/null || echo 0)
281
259
  echo "$((CURRENT_FAILURES + 1))" > "$CIRCUIT_BREAKER_FILE" 2>/dev/null || true
282
260
 
283
- VALIDATION_ERROR=$(cat "$VALIDATION_OUTPUT" | grep -A 10 "VALIDATION FAILED" | tr '\n' ' ' | cut -c 1-300)
261
+ VALIDATION_ERROR=$(cat "$VALIDATION_OUTPUT" | grep -A 10 "VALIDATION FAILED" | tr '\n' ' ' | cut -c 1-300 | sed 's/"/\\"/g')
284
262
 
285
263
  rm -f "$VALIDATION_OUTPUT"
286
264
 
287
- cat <<EOF
288
- {
289
- "continue": false,
290
- "systemMessage": "❌ AC TEST VALIDATION FAILED: Cannot mark task as complete until all acceptance criteria have passing tests. ${VALIDATION_ERROR}
291
-
292
- Fix the failing tests and try again. Run tests manually: npm test"
293
- }
294
- EOF
265
+ printf '{"continue":false,"systemMessage":"❌ AC TEST VALIDATION FAILED: Cannot mark task as complete until all acceptance criteria have passing tests. %s\\n\\nFix the failing tests and try again. Run tests manually: npm test"}\n' "$VALIDATION_ERROR"
295
266
  fi
296
267
 
297
268
  # ALWAYS exit 0 - NEVER let hook errors crash Claude Code
@@ -0,0 +1,194 @@
1
+ #!/bin/bash
2
+
3
+ # SpecWeave Pre-Task-Completion Hook
4
+ # CRITICAL QUALITY GATE: Validates AC tests before allowing task completion
5
+ #
6
+ # Runs automatically BEFORE any task is marked complete via TodoWrite
7
+ #
8
+ # WORKFLOW:
9
+ # =========
10
+ # 1. TodoWrite called with status="completed"
11
+ # 2. This hook fires (pre-completion validation)
12
+ # 3. Extract task ID from TodoWrite input
13
+ # 4. Find task in tasks.md
14
+ # 5. Run AC test validator
15
+ # 6. If tests PASS → Allow completion (continue: true)
16
+ # 7. If tests FAIL → Block completion (continue: false, show error)
17
+ #
18
+ # ENFORCEMENT:
19
+ # ============
20
+ # This is the ONLY way to mark tasks complete in SpecWeave.
21
+ # Manual edits to tasks.md are detected and flagged by pre-commit hooks.
22
+
23
+ set -e
24
+
25
+ # Find project root
26
+ find_project_root() {
27
+ local dir="$1"
28
+ while [ "$dir" != "/" ]; do
29
+ if [ -d "$dir/.specweave" ]; then
30
+ echo "$dir"
31
+ return 0
32
+ fi
33
+ dir="$(dirname "$dir")"
34
+ done
35
+ pwd
36
+ }
37
+
38
+ PROJECT_ROOT="$(find_project_root "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")"
39
+ cd "$PROJECT_ROOT" 2>/dev/null || true
40
+
41
+ # ============================================================================
42
+ # CONFIGURATION
43
+ # ============================================================================
44
+
45
+ LOGS_DIR=".specweave/logs"
46
+ DEBUG_LOG="$LOGS_DIR/hooks-debug.log"
47
+
48
+ mkdir -p "$LOGS_DIR" 2>/dev/null || true
49
+
50
+ echo "[$(date)] 🔒 Pre-task-completion hook fired" >> "$DEBUG_LOG" 2>/dev/null || true
51
+
52
+ # ============================================================================
53
+ # CAPTURE INPUT
54
+ # ============================================================================
55
+
56
+ STDIN_DATA=$(mktemp)
57
+ cat > "$STDIN_DATA"
58
+
59
+ echo "[$(date)] Input JSON:" >> "$DEBUG_LOG" 2>/dev/null || true
60
+ cat "$STDIN_DATA" >> "$DEBUG_LOG" 2>/dev/null || true
61
+
62
+ # ============================================================================
63
+ # CHECK FOR TASK COMPLETION
64
+ # ============================================================================
65
+
66
+ # Only validate if a task is being marked complete
67
+ COMPLETING_TASK=false
68
+
69
+ if command -v jq >/dev/null 2>&1; then
70
+ # Check if any task is transitioning to "completed" status
71
+ COMPLETED_COUNT=$(jq -r '.tool_input.todos // [] | map(select(.status == "completed")) | length' "$STDIN_DATA" 2>/dev/null || echo "0")
72
+
73
+ if [ "$COMPLETED_COUNT" != "0" ]; then
74
+ COMPLETING_TASK=true
75
+ echo "[$(date)] ✓ Detected task completion (${COMPLETED_COUNT} tasks)" >> "$DEBUG_LOG" 2>/dev/null || true
76
+ fi
77
+ fi
78
+
79
+ # If no tasks being completed, allow without validation
80
+ if [ "$COMPLETING_TASK" = "false" ]; then
81
+ echo "[$(date)] ⏭️ No tasks being completed, skipping validation" >> "$DEBUG_LOG" 2>/dev/null || true
82
+ rm -f "$STDIN_DATA"
83
+ cat <<EOF
84
+ {
85
+ "continue": true
86
+ }
87
+ EOF
88
+ exit 0
89
+ fi
90
+
91
+ # ============================================================================
92
+ # DETECT CURRENT INCREMENT
93
+ # ============================================================================
94
+
95
+ CURRENT_INCREMENT=$(ls -td .specweave/increments/*/ 2>/dev/null | xargs -n1 basename | grep -v "_backlog" | grep -v "_archive" | grep -v "_working" | head -1)
96
+
97
+ if [ -z "$CURRENT_INCREMENT" ]; then
98
+ echo "[$(date)] ℹ️ No active increment found, skipping validation" >> "$DEBUG_LOG" 2>/dev/null || true
99
+ rm -f "$STDIN_DATA"
100
+ cat <<EOF
101
+ {
102
+ "continue": true
103
+ }
104
+ EOF
105
+ exit 0
106
+ fi
107
+
108
+ TASKS_MD=".specweave/increments/$CURRENT_INCREMENT/tasks.md"
109
+
110
+ if [ ! -f "$TASKS_MD" ]; then
111
+ echo "[$(date)] ℹ️ tasks.md not found for $CURRENT_INCREMENT (increment may be in planning stage)" >> "$DEBUG_LOG" 2>/dev/null || true
112
+ rm -f "$STDIN_DATA"
113
+ cat <<EOF
114
+ {
115
+ "continue": true
116
+ }
117
+ EOF
118
+ exit 0
119
+ fi
120
+
121
+ # ============================================================================
122
+ # RUN AC TEST VALIDATION
123
+ # ============================================================================
124
+
125
+ echo "[$(date)] 🧪 Running AC test validation for $CURRENT_INCREMENT" >> "$DEBUG_LOG" 2>/dev/null || true
126
+
127
+ # Determine which validation script to use
128
+ VALIDATOR_SCRIPT=""
129
+ if [ -f "$PROJECT_ROOT/dist/src/core/ac-test-validator-cli.js" ]; then
130
+ VALIDATOR_SCRIPT="$PROJECT_ROOT/dist/src/core/ac-test-validator-cli.js"
131
+ elif [ -f "$PROJECT_ROOT/node_modules/specweave/dist/src/core/ac-test-validator-cli.js" ]; then
132
+ VALIDATOR_SCRIPT="$PROJECT_ROOT/node_modules/specweave/dist/src/core/ac-test-validator-cli.js"
133
+ elif [ -n "${CLAUDE_PLUGIN_ROOT}" ] && [ -f "${CLAUDE_PLUGIN_ROOT}/dist/src/core/ac-test-validator-cli.js" ]; then
134
+ VALIDATOR_SCRIPT="${CLAUDE_PLUGIN_ROOT}/dist/src/core/ac-test-validator-cli.js"
135
+ fi
136
+
137
+ if [ -z "$VALIDATOR_SCRIPT" ] || ! command -v node &> /dev/null; then
138
+ echo "[$(date)] ⚠️ AC test validator not found or Node.js missing" >> "$DEBUG_LOG" 2>/dev/null || true
139
+ rm -f "$STDIN_DATA"
140
+ cat <<EOF
141
+ {
142
+ "continue": true,
143
+ "systemMessage": "⚠️ Warning: AC test validator not available. Task completion validation skipped. Install Node.js and rebuild SpecWeave to enable validation."
144
+ }
145
+ EOF
146
+ exit 0
147
+ fi
148
+
149
+ # Run validator (captures exit code)
150
+ VALIDATION_OUTPUT=$(mktemp)
151
+ VALIDATION_EXIT_CODE=0
152
+
153
+ (cd "$PROJECT_ROOT" && node "$VALIDATOR_SCRIPT" "$CURRENT_INCREMENT") > "$VALIDATION_OUTPUT" 2>&1 || VALIDATION_EXIT_CODE=$?
154
+
155
+ echo "[$(date)] Validator exit code: $VALIDATION_EXIT_CODE" >> "$DEBUG_LOG" 2>/dev/null || true
156
+ cat "$VALIDATION_OUTPUT" >> "$DEBUG_LOG" 2>/dev/null || true
157
+
158
+ rm -f "$STDIN_DATA"
159
+
160
+ # ============================================================================
161
+ # DECISION LOGIC
162
+ # ============================================================================
163
+
164
+ if [ "$VALIDATION_EXIT_CODE" = "0" ]; then
165
+ # Validation passed - allow completion
166
+ echo "[$(date)] ✅ AC test validation passed" >> "$DEBUG_LOG" 2>/dev/null || true
167
+
168
+ VALIDATION_SUMMARY=$(cat "$VALIDATION_OUTPUT" | tail -5 | tr '\n' ' ')
169
+
170
+ rm -f "$VALIDATION_OUTPUT"
171
+
172
+ cat <<EOF
173
+ {
174
+ "continue": true,
175
+ "systemMessage": "✅ AC Test Validation Passed: All acceptance criteria have passing tests. Task completion allowed. ${VALIDATION_SUMMARY}"
176
+ }
177
+ EOF
178
+ else
179
+ # Validation failed - block completion
180
+ echo "[$(date)] ❌ AC test validation failed" >> "$DEBUG_LOG" 2>/dev/null || true
181
+
182
+ VALIDATION_ERROR=$(cat "$VALIDATION_OUTPUT" | grep -A 10 "VALIDATION FAILED" | tr '\n' ' ' | cut -c 1-300)
183
+
184
+ rm -f "$VALIDATION_OUTPUT"
185
+
186
+ cat <<EOF
187
+ {
188
+ "continue": false,
189
+ "systemMessage": "❌ AC TEST VALIDATION FAILED: Cannot mark task as complete until all acceptance criteria have passing tests. ${VALIDATION_ERROR}
190
+
191
+ Fix the failing tests and try again. Run tests manually: npm test"
192
+ }
193
+ EOF
194
+ fi
@@ -128,18 +128,9 @@ rm -f "$STDIN_DATA"
128
128
  # ============================================================================
129
129
 
130
130
  if [ "$TOOL_NAME" = "AskUserQuestion" ]; then
131
- cat <<EOF
132
- {
133
- "continue": true,
134
- "systemMessage": "🔔 Sound played - user notified of question request"
135
- }
136
- EOF
131
+ echo '{"continue":true,"systemMessage":"🔔 Sound played - user notified of question request"}'
137
132
  else
138
- cat <<EOF
139
- {
140
- "continue": true
141
- }
142
- EOF
133
+ echo '{"continue":true}'
143
134
  fi
144
135
 
145
136
  # ALWAYS exit 0 - NEVER let hook errors crash Claude Code
@@ -0,0 +1,133 @@
1
+ #!/bin/bash
2
+
3
+ # SpecWeave Pre-Tool-Use Hook
4
+ # Runs BEFORE Claude calls any tool (PreToolUse event)
5
+ #
6
+ # PURPOSE: Detect when Claude asks questions via AskUserQuestion
7
+ # - Plays sound IMMEDIATELY when question is about to be asked
8
+ # - Complements post-task-completion hook (which only fires after TodoWrite)
9
+ # - Ensures user is always notified when Claude needs input
10
+ #
11
+ # SCOPE:
12
+ # - This hook fires for ALL tool calls (Read, Edit, Write, AskUserQuestion, etc.)
13
+ # - We filter for AskUserQuestion specifically to play sound
14
+ # - Non-blocking and fast (<10ms overhead)
15
+
16
+ set -e
17
+
18
+ # ============================================================================
19
+ # CONFIGURATION
20
+ # ============================================================================
21
+
22
+ # Find project root
23
+ find_project_root() {
24
+ local dir="$1"
25
+ while [ "$dir" != "/" ]; do
26
+ if [ -d "$dir/.specweave" ]; then
27
+ echo "$dir"
28
+ return 0
29
+ fi
30
+ dir="$(dirname "$dir")"
31
+ done
32
+ # Fallback
33
+ if [ -d "$(pwd)/.specweave" ]; then
34
+ pwd
35
+ else
36
+ echo "$(pwd)"
37
+ fi
38
+ }
39
+
40
+ PROJECT_ROOT="$(find_project_root "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")"
41
+ cd "$PROJECT_ROOT" 2>/dev/null || true
42
+
43
+ LOGS_DIR=".specweave/logs"
44
+ DEBUG_LOG="$LOGS_DIR/hooks-debug.log"
45
+
46
+ mkdir -p "$LOGS_DIR" 2>/dev/null || true
47
+
48
+ # ============================================================================
49
+ # CAPTURE INPUT (Tool Call Details)
50
+ # ============================================================================
51
+
52
+ STDIN_DATA=$(mktemp)
53
+ cat > "$STDIN_DATA"
54
+
55
+ # Log the tool call for debugging
56
+ echo "[$(date)] 🔧 PreToolUse hook fired" >> "$DEBUG_LOG" 2>/dev/null || true
57
+ echo "[$(date)] Tool call JSON:" >> "$DEBUG_LOG" 2>/dev/null || true
58
+ cat "$STDIN_DATA" >> "$DEBUG_LOG" 2>/dev/null || true
59
+ echo "" >> "$DEBUG_LOG" 2>/dev/null || true
60
+
61
+ # ============================================================================
62
+ # DETECT AskUserQuestion TOOL
63
+ # ============================================================================
64
+
65
+ TOOL_NAME=""
66
+
67
+ if command -v jq >/dev/null 2>&1; then
68
+ # Use jq if available (most reliable)
69
+ TOOL_NAME=$(jq -r '.tool_name // empty' "$STDIN_DATA" 2>/dev/null)
70
+ else
71
+ # Fallback: grep-based detection
72
+ if grep -q '"tool_name"' "$STDIN_DATA" 2>/dev/null; then
73
+ TOOL_NAME=$(grep -o '"tool_name":"[^"]*"' "$STDIN_DATA" | cut -d'"' -f4)
74
+ fi
75
+ fi
76
+
77
+ echo "[$(date)] Tool name: $TOOL_NAME" >> "$DEBUG_LOG" 2>/dev/null || true
78
+
79
+ # ============================================================================
80
+ # PLAY SOUND IF AskUserQuestion
81
+ # ============================================================================
82
+
83
+ play_sound() {
84
+ case "$(uname -s)" in
85
+ Darwin)
86
+ # macOS: Use afplay with a distinctive sound for questions
87
+ afplay /System/Library/Sounds/Tink.aiff 2>/dev/null || true
88
+ ;;
89
+ Linux)
90
+ # Linux: Use paplay or aplay
91
+ paplay /usr/share/sounds/freedesktop/stereo/dialog-question.oga 2>/dev/null || \
92
+ paplay /usr/share/sounds/freedesktop/stereo/message-new-instant.oga 2>/dev/null || \
93
+ aplay /usr/share/sounds/alsa/Front_Center.wav 2>/dev/null || true
94
+ ;;
95
+ MINGW*|MSYS*|CYGWIN*)
96
+ # Windows: Use PowerShell
97
+ powershell -c "(New-Object Media.SoundPlayer 'C:\Windows\Media\Windows Notify.wav').PlaySync();" 2>/dev/null || true
98
+ ;;
99
+ esac
100
+ }
101
+
102
+ if [ "$TOOL_NAME" = "AskUserQuestion" ]; then
103
+ echo "[$(date)] 🔔 QUESTION DETECTED! Playing notification sound" >> "$DEBUG_LOG" 2>/dev/null || true
104
+ play_sound
105
+
106
+ # Log this event
107
+ echo "[$(date)] Claude is asking for user input via AskUserQuestion" >> "$DEBUG_LOG" 2>/dev/null || true
108
+ fi
109
+
110
+ # ============================================================================
111
+ # CLEANUP
112
+ # ============================================================================
113
+
114
+ rm -f "$STDIN_DATA"
115
+
116
+ # ============================================================================
117
+ # OUTPUT TO CLAUDE (Always continue)
118
+ # ============================================================================
119
+
120
+ if [ "$TOOL_NAME" = "AskUserQuestion" ]; then
121
+ cat <<EOF
122
+ {
123
+ "continue": true,
124
+ "systemMessage": "🔔 Sound played - user notified of question request"
125
+ }
126
+ EOF
127
+ else
128
+ cat <<EOF
129
+ {
130
+ "continue": true
131
+ }
132
+ EOF
133
+ fi
@@ -12,11 +12,21 @@
12
12
  # Rules:
13
13
  # - 1-level structure: spec.md MUST have `project:` in YAML frontmatter
14
14
  # - 2-level structure: spec.md MUST have BOTH `project:` AND `board:` in frontmatter
15
+ # - Project MUST exist in configuration (validated via specweave context projects)
16
+ # - Board MUST exist under project for 2-level (validated via specweave context boards)
15
17
  #
16
18
  # Returns exit code 1 (block) if validation fails, 0 (allow) otherwise.
19
+ #
20
+ # Bypass: Set SPECWEAVE_FORCE_PROJECT=1 to skip validation
17
21
 
18
22
  set -e
19
23
 
24
+ # Check for force bypass
25
+ if [ "$SPECWEAVE_FORCE_PROJECT" = "1" ]; then
26
+ echo '{"decision": "allow", "message": "⚠️ Project validation bypassed (SPECWEAVE_FORCE_PROJECT=1)"}'
27
+ exit 0
28
+ fi
29
+
20
30
  # Read tool input from stdin
21
31
  INPUT=$(cat)
22
32
 
@@ -33,7 +43,7 @@ fi
33
43
  FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // ""')
34
44
 
35
45
  # Only validate spec.md files in increments folder
36
- if [[ ! "$FILE_PATH" =~ \.specweave/increments/[0-9]{4}-[^/]+/spec\.md$ ]]; then
46
+ if [[ ! "$FILE_PATH" =~ \.specweave/increments/[0-9]{4}E?-[^/]+/spec\.md$ ]]; then
37
47
  echo '{"decision": "allow"}'
38
48
  exit 0
39
49
  fi
@@ -52,58 +62,103 @@ FRONTMATTER=$(echo "$CONTENT" | sed -n '/^---$/,/^---$/p' | tail -n +2 | head -n
52
62
 
53
63
  # Check for unresolved project placeholder
54
64
  if echo "$FRONTMATTER" | grep -q 'project:\s*{{PROJECT_ID}}'; then
55
- echo '{"decision": "block", "reason": "spec.md has unresolved placeholder {{PROJECT_ID}}. Run STEP 0B to select project before creating spec.md."}'
65
+ echo '{"decision": "block", "reason": "spec.md has unresolved placeholder {{PROJECT_ID}}. Run '\''specweave context projects'\'' to get available projects, then select one."}'
56
66
  exit 0
57
67
  fi
58
68
 
59
69
  # Check for unresolved board placeholder
60
70
  if echo "$FRONTMATTER" | grep -q 'board:\s*{{BOARD_ID}}'; then
61
- echo '{"decision": "block", "reason": "spec.md has unresolved placeholder {{BOARD_ID}}. Run STEP 0B to select board before creating spec.md."}'
71
+ echo '{"decision": "block", "reason": "spec.md has unresolved placeholder {{BOARD_ID}}. Run '\''specweave context boards --project=<id>'\'' to get available boards, then select one."}'
62
72
  exit 0
63
73
  fi
64
74
 
65
- # Check for project field
75
+ # Extract project and board from frontmatter
66
76
  PROJECT=$(echo "$FRONTMATTER" | grep -E '^project:\s*' | sed 's/^project:\s*//' | tr -d '"'"'" | tr -d '[:space:]')
77
+ BOARD=$(echo "$FRONTMATTER" | grep -E '^board:\s*' | sed 's/^board:\s*//' | tr -d '"'"'" | tr -d '[:space:]')
67
78
 
68
- # Detect structure level by checking config
79
+ # Get project root from file path
69
80
  PROJECT_ROOT="${FILE_PATH%%/.specweave/*}"
70
- CONFIG_PATH="$PROJECT_ROOT/.specweave/config.json"
71
81
 
72
- IS_2_LEVEL=false
82
+ # Change to project root for specweave command
83
+ cd "$PROJECT_ROOT" 2>/dev/null || true
73
84
 
74
- if [ -f "$CONFIG_PATH" ]; then
75
- # Check for ADO area path mapping (indicates 2-level)
76
- if jq -e '.sync.profiles | to_entries[] | select(.value.provider == "ado") | .value.config.areaPathMapping.mappings | length > 0' "$CONFIG_PATH" >/dev/null 2>&1; then
77
- IS_2_LEVEL=true
78
- fi
85
+ # Get project context via CLI command
86
+ CONTEXT_OUTPUT=$(specweave context projects 2>/dev/null || echo '{"level": 1, "projects": []}')
79
87
 
80
- # Check for ADO areaPaths (indicates 2-level)
81
- if jq -e '.sync.profiles | to_entries[] | select(.value.provider == "ado") | .value.config.areaPaths | length > 0' "$CONFIG_PATH" >/dev/null 2>&1; then
82
- IS_2_LEVEL=true
83
- fi
84
- fi
88
+ # Parse structure level
89
+ STRUCTURE_LEVEL=$(echo "$CONTEXT_OUTPUT" | jq -r '.level // 1')
90
+
91
+ # Parse available projects
92
+ AVAILABLE_PROJECTS=$(echo "$CONTEXT_OUTPUT" | jq -r '.projects[].id // empty' | tr '\n' ', ' | sed 's/,$//')
85
93
 
86
94
  # Validation based on structure level
87
- if [ "$IS_2_LEVEL" = true ]; then
95
+ if [ "$STRUCTURE_LEVEL" = "2" ]; then
88
96
  # 2-level: BOTH project AND board required
97
+
98
+ # Check project field exists
89
99
  if [ -z "$PROJECT" ] || [ "$PROJECT" = "null" ]; then
90
- echo '{"decision": "block", "reason": "spec.md missing required '\''project:'\'' field in YAML frontmatter. This is a 2-level structure - add '\''project: <project_name>'\'' to frontmatter."}'
100
+ echo "{\"decision\": \"block\", \"reason\": \"spec.md missing required 'project:' field in YAML frontmatter.\\n\\n2-level structure detected.\\n\\nAvailable projects: ${AVAILABLE_PROJECTS:-none detected}\\n\\nAdd 'project: <project_name>' to frontmatter.\\n\\nRun 'specweave context projects' to see all options.\"}"
91
101
  exit 0
92
102
  fi
93
103
 
94
- BOARD=$(echo "$FRONTMATTER" | grep -E '^board:\s*' | sed 's/^board:\s*//' | tr -d '"'"'" | tr -d '[:space:]')
95
-
104
+ # Check board field exists
96
105
  if [ -z "$BOARD" ] || [ "$BOARD" = "null" ]; then
97
- echo '{"decision": "block", "reason": "spec.md missing required '\''board:'\'' field in YAML frontmatter. This is a 2-level structure - add '\''board: <board_name>'\'' to frontmatter."}'
106
+ # Get available boards for the project
107
+ AVAILABLE_BOARDS=$(specweave context boards --project="$PROJECT" 2>/dev/null | jq -r '.boards[].id // empty' | tr '\n' ', ' | sed 's/,$//')
108
+
109
+ echo "{\"decision\": \"block\", \"reason\": \"spec.md missing required 'board:' field in YAML frontmatter.\\n\\n2-level structure detected (project: ${PROJECT}).\\n\\nAvailable boards: ${AVAILABLE_BOARDS:-none detected}\\n\\nAdd 'board: <board_name>' to frontmatter.\\n\\nRun 'specweave context boards --project=${PROJECT}' to see all options.\"}"
98
110
  exit 0
99
111
  fi
112
+
113
+ # Validate project exists in configuration
114
+ PROJECT_EXISTS=$(echo "$CONTEXT_OUTPUT" | jq --arg proj "$PROJECT" '.projects[] | select(.id == $proj)' 2>/dev/null)
115
+ if [ -z "$PROJECT_EXISTS" ]; then
116
+ # Try case-insensitive match
117
+ PROJECT_EXISTS=$(echo "$CONTEXT_OUTPUT" | jq --arg proj "$PROJECT" '.projects[] | select(.id | ascii_downcase == ($proj | ascii_downcase))' 2>/dev/null)
118
+ fi
119
+
120
+ if [ -z "$PROJECT_EXISTS" ] && [ -n "$AVAILABLE_PROJECTS" ]; then
121
+ echo "{\"decision\": \"block\", \"reason\": \"Project '${PROJECT}' not found in configuration.\\n\\nAvailable projects: ${AVAILABLE_PROJECTS}\\n\\nEither:\\n1. Update project: field to a valid project\\n2. Set SPECWEAVE_FORCE_PROJECT=1 to bypass validation\"}"
122
+ exit 0
123
+ fi
124
+
125
+ # Validate board exists under project
126
+ BOARDS_OUTPUT=$(specweave context boards --project="$PROJECT" 2>/dev/null || echo '{"boards": []}')
127
+ BOARD_EXISTS=$(echo "$BOARDS_OUTPUT" | jq --arg board "$BOARD" '.boards[] | select(.id == $board)' 2>/dev/null)
128
+
129
+ if [ -z "$BOARD_EXISTS" ]; then
130
+ # Try case-insensitive match
131
+ BOARD_EXISTS=$(echo "$BOARDS_OUTPUT" | jq --arg board "$BOARD" '.boards[] | select(.id | ascii_downcase == ($board | ascii_downcase))' 2>/dev/null)
132
+ fi
133
+
134
+ AVAILABLE_BOARDS=$(echo "$BOARDS_OUTPUT" | jq -r '.boards[].id // empty' | tr '\n' ', ' | sed 's/,$//')
135
+
136
+ if [ -z "$BOARD_EXISTS" ] && [ -n "$AVAILABLE_BOARDS" ]; then
137
+ echo "{\"decision\": \"block\", \"reason\": \"Board '${BOARD}' not found under project '${PROJECT}'.\\n\\nAvailable boards: ${AVAILABLE_BOARDS}\\n\\nEither:\\n1. Update board: field to a valid board\\n2. Set SPECWEAVE_FORCE_PROJECT=1 to bypass validation\"}"
138
+ exit 0
139
+ fi
140
+
100
141
  else
101
- # 1-level: project is strongly recommended (warning, not block)
142
+ # 1-level: project is REQUIRED (not just recommended)
143
+
102
144
  if [ -z "$PROJECT" ] || [ "$PROJECT" = "null" ]; then
103
- # For 1-level, we warn but don't block (backward compatibility)
104
- echo '{"decision": "allow", "message": "⚠️ spec.md should have '\''project:'\'' field in YAML frontmatter for explicit sync target."}'
145
+ echo "{\"decision\": \"block\", \"reason\": \"spec.md missing required 'project:' field in YAML frontmatter.\\n\\nAvailable projects: ${AVAILABLE_PROJECTS:-none detected}\\n\\nAdd 'project: <project_name>' to frontmatter.\\n\\nRun 'specweave context projects' to see all options.\"}"
105
146
  exit 0
106
147
  fi
148
+
149
+ # Validate project exists in configuration (if we have projects configured)
150
+ if [ -n "$AVAILABLE_PROJECTS" ]; then
151
+ PROJECT_EXISTS=$(echo "$CONTEXT_OUTPUT" | jq --arg proj "$PROJECT" '.projects[] | select(.id == $proj)' 2>/dev/null)
152
+ if [ -z "$PROJECT_EXISTS" ]; then
153
+ # Try case-insensitive match
154
+ PROJECT_EXISTS=$(echo "$CONTEXT_OUTPUT" | jq --arg proj "$PROJECT" '.projects[] | select(.id | ascii_downcase == ($proj | ascii_downcase))' 2>/dev/null)
155
+ fi
156
+
157
+ if [ -z "$PROJECT_EXISTS" ]; then
158
+ echo "{\"decision\": \"block\", \"reason\": \"Project '${PROJECT}' not found in configuration.\\n\\nAvailable projects: ${AVAILABLE_PROJECTS}\\n\\nEither:\\n1. Update project: field to a valid project\\n2. Set SPECWEAVE_FORCE_PROJECT=1 to bypass validation\"}"
159
+ exit 0
160
+ fi
161
+ fi
107
162
  fi
108
163
 
109
164
  # All validations passed