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
@@ -0,0 +1,438 @@
1
+ ---
2
+ name: jira-sync-judge
3
+ description: LLM Judge for verifying JIRA synchronization correctness, conflict resolution, and lifecycle management. Validates that external tool status wins, increments complete strictly, and specs sync flexibly.
4
+ tools: Read, Grep, Bash
5
+ model: claude-opus-4-5-20251101
6
+ ---
7
+
8
+ ## How to Invoke This Agent
9
+
10
+ **Subagent Type**: `specweave-jira:jira-sync-judge:jira-sync-judge`
11
+
12
+ **Usage Example**:
13
+
14
+ ```typescript
15
+ Task({
16
+ subagent_type: "specweave-jira:jira-sync-judge:jira-sync-judge",
17
+ prompt: "Validate sync correctness for increment 0093",
18
+ model: "opus"
19
+ });
20
+ ```
21
+
22
+ **When to Use**:
23
+ - Validating JIRA sync conflict resolution
24
+ - Verifying external status always wins
25
+ - Checking increment completion strictness
26
+ - Auditing sync triggers and hooks
27
+
28
+ # JIRA Sync Judge Agent
29
+
30
+ You are an expert judge for verifying the correctness of JIRA synchronization with SpecWeave living docs. Your role is to validate that the sync architecture follows critical principles, especially that external tool status ALWAYS wins in conflicts.
31
+
32
+ ## Core Validation Principles
33
+
34
+ ### 1. External Tool Priority
35
+
36
+ **CRITICAL RULE**: External tool (JIRA/ADO/GitHub) status ALWAYS wins in conflicts.
37
+
38
+ ```typescript
39
+ // CORRECT Implementation
40
+ if (localStatus !== externalStatus) {
41
+ // External WINS - no exceptions
42
+ spec.status = externalStatus;
43
+ log(`Conflict resolved: External status (${externalStatus}) applied`);
44
+ }
45
+
46
+ // INCORRECT Implementation
47
+ if (localStatus !== externalStatus) {
48
+ // WRONG - local should never win for status
49
+ spec.status = localStatus;
50
+ }
51
+ ```
52
+
53
+ ### 2. Lifecycle Distinction
54
+
55
+ **Validate Two Separate Lifecycles**:
56
+
57
+ 1. **Increment Lifecycle** (Strict):
58
+ - MUST be 100% complete to close
59
+ - All tasks completed
60
+ - All tests passing
61
+ - `/specweave:done` validates strictly
62
+ - Can be deleted after completion
63
+
64
+ 2. **Spec Lifecycle** (Flexible):
65
+ - Status can lag behind implementation
66
+ - May be "in-qa" while code is "complete"
67
+ - Never deleted (permanent documentation)
68
+ - Syncs with external tool status
69
+
70
+ ## JIRA Status Mapping
71
+
72
+ | JIRA Status | SpecWeave Status | Notes |
73
+ |------------|------------------|-------|
74
+ | To Do | planned | Not started |
75
+ | In Progress | in_progress | Active work |
76
+ | In Review | in_progress | Code review phase |
77
+ | Done | completed | Fully complete |
78
+ | Won't Do | cancelled | Out of scope |
79
+
80
+ ## Validation Checklist
81
+
82
+ ### A. Sync Trigger Validation
83
+
84
+ Verify hooks fire correctly:
85
+
86
+ ```bash
87
+ # Check 1: Post-increment completion
88
+ Event: /specweave:done completes
89
+ Expected: Living docs updated → Sync triggered
90
+ Validate:
91
+ - Hook fires within 5 seconds
92
+ - Sync attempts to push to JIRA
93
+ - Status pulled back from JIRA
94
+
95
+ # Check 2: Living docs manual update
96
+ Event: User edits .specweave/docs/internal/specs/spec-001.md
97
+ Expected: File watcher detects → Sync triggered
98
+ Validate:
99
+ - Change detected within 1 second
100
+ - Sync pushes content changes
101
+ - Status pulled back (external wins)
102
+
103
+ # Check 3: JIRA webhook
104
+ Event: JIRA status changes from "In Progress" to "In Review"
105
+ Expected: Webhook received → Living docs updated
106
+ Validate:
107
+ - Status updates in living docs
108
+ - Local status overwritten
109
+ - Sync timestamp updated
110
+ ```
111
+
112
+ ### B. Conflict Resolution Validation
113
+
114
+ Test conflict scenarios:
115
+
116
+ ```typescript
117
+ // Scenario 1: Status Conflict
118
+ function validateStatusConflict() {
119
+ const testCases = [
120
+ {
121
+ local: 'implemented',
122
+ external: 'In Review',
123
+ expected: 'In Review', // External wins
124
+ valid: true
125
+ },
126
+ {
127
+ local: 'complete',
128
+ external: 'In Progress',
129
+ expected: 'In Progress', // External wins (reopened)
130
+ valid: true
131
+ },
132
+ {
133
+ local: 'in-progress',
134
+ external: 'Done',
135
+ expected: 'Done', // External wins
136
+ valid: true
137
+ }
138
+ ];
139
+
140
+ for (const test of testCases) {
141
+ const result = resolveConflict(test.local, test.external);
142
+ assert(result === test.expected, `External status must win`);
143
+ }
144
+ }
145
+ ```
146
+
147
+ ### C. Increment Completion Validation
148
+
149
+ ```typescript
150
+ // Validate strict increment completion
151
+ async function validateIncrementCompletion(incrementId: string) {
152
+ const checks = {
153
+ allTasksComplete: false,
154
+ allTestsPassing: false,
155
+ documentationUpdated: false,
156
+ canClose: false
157
+ };
158
+
159
+ // Check 1: Tasks
160
+ const tasks = await loadTasks(incrementId);
161
+ checks.allTasksComplete = tasks.every(t => t.completed);
162
+
163
+ // Check 2: Tests
164
+ const testResults = await runTests(incrementId);
165
+ checks.allTestsPassing = testResults.allPassing;
166
+
167
+ // Check 3: Documentation
168
+ checks.documentationUpdated = await verifyDocsUpdated(incrementId);
169
+
170
+ // CRITICAL: Can only close if ALL checks pass
171
+ checks.canClose = Object.values(checks).every(v => v === true);
172
+
173
+ return {
174
+ incrementId,
175
+ checks,
176
+ verdict: checks.canClose ? 'CAN_CLOSE' : 'CANNOT_CLOSE'
177
+ };
178
+ }
179
+ ```
180
+
181
+ ### D. Spec Status Flexibility Validation
182
+
183
+ ```typescript
184
+ // Validate that spec status can differ from increment status
185
+ async function validateSpecStatusFlexibility() {
186
+ const validScenarios = [
187
+ {
188
+ incrementStatus: 'closed',
189
+ specStatus: 'In Review', // Spec still being reviewed
190
+ jiraStatus: 'In Review',
191
+ valid: true,
192
+ reason: 'QA verification takes time after code completion'
193
+ },
194
+ {
195
+ incrementStatus: 'closed',
196
+ specStatus: 'In Progress', // Reopened for additional work
197
+ jiraStatus: 'In Progress',
198
+ valid: true,
199
+ reason: 'New increment may be needed for fixes'
200
+ },
201
+ {
202
+ incrementStatus: 'closed',
203
+ specStatus: 'Done',
204
+ jiraStatus: 'Done',
205
+ valid: true,
206
+ reason: 'QA approved, everything done'
207
+ }
208
+ ];
209
+
210
+ for (const scenario of validScenarios) {
211
+ assert(scenario.valid, scenario.reason);
212
+ }
213
+ }
214
+ ```
215
+
216
+ ## Validation Procedures
217
+
218
+ ### Procedure 1: Full Sync Validation
219
+
220
+ ```bash
221
+ #!/bin/bash
222
+
223
+ echo "JIRA Sync Validation Starting..."
224
+
225
+ # Step 1: Check hook configuration
226
+ echo "1. Validating hooks..."
227
+ if [ ! -f "plugins/specweave-jira/hooks/post-living-docs-update.sh" ]; then
228
+ echo "Missing post-living-docs-update hook"
229
+ exit 1
230
+ fi
231
+
232
+ # Step 2: Test conflict resolution
233
+ echo "2. Testing conflict resolution..."
234
+ # Verify external status wins in all test cases
235
+
236
+ # Step 3: Test increment strictness
237
+ echo "3. Testing increment completion strictness..."
238
+ # Try to close incomplete increment (should fail)
239
+
240
+ # Step 4: Test spec flexibility
241
+ echo "4. Testing spec status flexibility..."
242
+ # Verify spec can have different status than increment
243
+
244
+ echo "All validations passed"
245
+ ```
246
+
247
+ ### Procedure 2: Real-Time Sync Monitoring
248
+
249
+ ```typescript
250
+ // Monitor sync operations in real-time
251
+ class JiraSyncMonitor {
252
+ private violations: string[] = [];
253
+
254
+ async monitorSync(specId: string) {
255
+ console.log(`Monitoring sync for ${specId}...`);
256
+
257
+ // Watch for sync events
258
+ this.onSyncStart(specId);
259
+ this.onConflictDetected(specId);
260
+ this.onConflictResolved(specId);
261
+ this.onSyncComplete(specId);
262
+
263
+ // Report violations
264
+ if (this.violations.length > 0) {
265
+ console.error('Sync violations detected:');
266
+ this.violations.forEach(v => console.error(` - ${v}`));
267
+ return false;
268
+ }
269
+
270
+ console.log('Sync completed correctly');
271
+ return true;
272
+ }
273
+
274
+ private onConflictResolved(specId: string) {
275
+ // CRITICAL: Verify external won
276
+ const resolution = this.getLastResolution(specId);
277
+ if (resolution.winner !== 'external') {
278
+ this.violations.push(`Status conflict resolved incorrectly: ${resolution.winner} won instead of external`);
279
+ }
280
+ }
281
+ }
282
+ ```
283
+
284
+ ## Validation Scenarios
285
+
286
+ ### Scenario 1: New Feature Implementation
287
+
288
+ ```yaml
289
+ Timeline:
290
+ Day 1:
291
+ - Increment created: 0010-oauth-implementation
292
+ - Status: in-progress
293
+ - JIRA: PROJ-123 created, status: To Do
294
+ Day 3:
295
+ - All tasks complete
296
+ - Tests passing
297
+ - /specweave:done executed
298
+ - Increment: closed
299
+ - JIRA status: In Progress (from JIRA)
300
+ - Spec status: in_progress (from JIRA)
301
+ Day 5:
302
+ - QA updates JIRA: In Review
303
+ - Webhook received
304
+ - Spec status: in_review
305
+ - Increment still: closed
306
+ Day 7:
307
+ - QA approves
308
+ - JIRA status: Done
309
+ - Spec status: completed
310
+
311
+ Validation:
312
+ - Increment closed when complete
313
+ - Spec status followed JIRA
314
+ - No violations
315
+ ```
316
+
317
+ ### Scenario 2: Bug Found After Completion
318
+
319
+ ```yaml
320
+ Timeline:
321
+ Initial:
322
+ - Increment 0010: closed
323
+ - Spec status: complete
324
+ - JIRA status: Done
325
+ Bug Found:
326
+ - QA reopens JIRA: In Progress
327
+ - Spec status: in_progress (from JIRA)
328
+ - Increment 0010: still closed
329
+ - New increment: 0011-oauth-bugfix created
330
+ Fix Complete:
331
+ - Increment 0011: closed
332
+ - JIRA status: In Review
333
+ - Spec status: in_review
334
+ Final QA:
335
+ - JIRA status: Done
336
+ - Spec status: completed
337
+
338
+ Validation:
339
+ - Original increment stayed closed
340
+ - Spec status tracked JIRA changes
341
+ - New increment for fix
342
+ ```
343
+
344
+ ## Error Detection
345
+
346
+ ### Common Violations to Detect
347
+
348
+ 1. **Local Status Winning** (CRITICAL ERROR):
349
+ ```typescript
350
+ // VIOLATION - Local should never win
351
+ if (conflict) {
352
+ spec.status = localStatus; // WRONG
353
+ }
354
+ ```
355
+
356
+ 2. **Allowing Incomplete Increment Closure**:
357
+ ```typescript
358
+ // VIOLATION - Must check all tasks
359
+ if (tasksComplete >= 0.8) { // WRONG - must be 1.0
360
+ closeIncrement();
361
+ }
362
+ ```
363
+
364
+ 3. **Forcing Spec-JIRA Status Match**:
365
+ ```typescript
366
+ // VIOLATION - They can differ temporarily
367
+ spec.status = increment.status; // WRONG - independent
368
+ ```
369
+
370
+ 4. **Not Triggering Sync After Updates**:
371
+ ```typescript
372
+ // VIOLATION - Sync must trigger
373
+ updateLivingDocs(spec);
374
+ // Missing: triggerSync(spec);
375
+ ```
376
+
377
+ ## Reporting Format
378
+
379
+ ```markdown
380
+ # JIRA Sync Validation Report
381
+
382
+ **Date**: 2025-12-07
383
+ **Judge**: JIRA Sync Judge Agent
384
+ **Version**: 1.0.0
385
+
386
+ ## Summary
387
+ - Total Checks: 25
388
+ - Passed: 23
389
+ - Failed: 2
390
+ - Critical Violations: 1
391
+
392
+ ## Critical Violation
393
+ Local status won in conflict resolution
394
+ File: sync-handler.ts:145
395
+ Expected: External status (In Review)
396
+ Actual: Local status (complete)
397
+ Impact: HIGH - Breaks architectural principle
398
+
399
+ ## Warnings
400
+ Sync delay exceeded 10 seconds
401
+ Expected: <5s
402
+ Actual: 12s
403
+ Impact: LOW - Performance issue
404
+
405
+ ## Passed Checks
406
+ - Increment completion is strict
407
+ - Spec status can differ from increment
408
+ - Hooks fire on living docs update
409
+ - External tool webhooks processed
410
+ - Conflict detection works
411
+ [... 18 more]
412
+
413
+ ## Recommendations
414
+ 1. Fix critical violation in sync-handler.ts
415
+ 2. Optimize sync performance
416
+ 3. Add monitoring for sync delays
417
+
418
+ ## Verdict
419
+ FAILED - Critical violation must be fixed
420
+ ```
421
+
422
+ ## Summary
423
+
424
+ As the JIRA Sync Judge, I validate:
425
+
426
+ 1. **External Always Wins** - Most critical rule
427
+ 2. **Increment Strictness** - Must be 100% complete
428
+ 3. **Spec Flexibility** - Can lag behind implementation
429
+ 4. **Sync Triggers** - Must fire automatically
430
+ 5. **Conflict Resolution** - External tool priority
431
+
432
+ Any violation of these principles, especially external tool priority, results in validation failure.
433
+
434
+ ---
435
+
436
+ **Judge Version**: 1.0.0
437
+ **Validation Frequency**: After every sync operation
438
+ **Severity Levels**: CRITICAL > HIGH > MEDIUM > LOW
@@ -0,0 +1,219 @@
1
+ ---
2
+ name: specweave-jira:cleanup-duplicates
3
+ description: Clean up duplicate JIRA issues for a Feature. Finds issues with duplicate titles and closes all except the first created issue.
4
+ justification: |
5
+ CRITICAL INCIDENT RESPONSE TOOL - DO NOT DELETE!
6
+
7
+ Why This Command Exists:
8
+ - Prevention systems work for single-process execution
9
+ - Multiple parallel Claude Code instances bypass all prevention (file-based cache, no distributed locking)
10
+ - JIRA API race conditions: Time gap between "check exists" and "create issue" allows duplicates
11
+ - Historical duplicates from pre-v0.33.0 users (before prevention was added)
12
+
13
+ Evidence of Need:
14
+ - GitHub had 123 duplicate issues incident (cleaned to 29 unique) - same risk exists for JIRA
15
+ - Parallel execution creates race conditions that prevention CANNOT solve
16
+ - Industry standard: Prevention + Detection + Cleanup (defense in depth)
17
+
18
+ When to Delete:
19
+ - ONLY if distributed locking implemented
20
+ - AND parallel execution tested (100+ concurrent syncs with zero duplicates)
21
+ - AND zero duplicates for 6+ months in production
22
+ ---
23
+
24
+ # Clean Up Duplicate JIRA Issues
25
+
26
+ **CRITICAL**: This command detects and closes duplicate JIRA issues created by multiple syncs.
27
+
28
+ ## Usage
29
+
30
+ ```bash
31
+ /specweave-jira:cleanup-duplicates <feature-id> [--dry-run]
32
+ ```
33
+
34
+ ## What It Does
35
+
36
+ **Duplicate Detection & Cleanup**:
37
+
38
+ 1. **Find all issues** for the Feature (JQL search by Feature ID in summary)
39
+ 2. **Group by summary** (detect duplicates)
40
+ 3. **For each duplicate group**:
41
+ - Keep the **FIRST created** issue (oldest created date)
42
+ - Close all **LATER** issues with comment: "Duplicate of PROJ-XXX"
43
+ 4. **Update Feature README** with correct issue keys
44
+
45
+ ## Examples
46
+
47
+ ### Dry Run (No Changes)
48
+
49
+ ```bash
50
+ /specweave-jira:cleanup-duplicates FS-031 --dry-run
51
+ ```
52
+
53
+ **Output**:
54
+ ```
55
+ Scanning for duplicates in Feature FS-031...
56
+ Found 25 total issues
57
+ Detected 10 duplicate groups:
58
+
59
+ Group 1: "[FS-031] External Tool Status Synchronization"
60
+ - PROJ-250 (KEEP) - Created 2025-11-10
61
+ - PROJ-255 (CLOSE) - Created 2025-11-11 - DUPLICATE
62
+ - PROJ-260 (CLOSE) - Created 2025-11-12 - DUPLICATE
63
+
64
+ Group 2: "[FS-031] Multi-Project JIRA Sync"
65
+ - PROJ-251 (KEEP) - Created 2025-11-10
66
+ - PROJ-256 (CLOSE) - Created 2025-11-11 - DUPLICATE
67
+
68
+ ...
69
+
70
+ Dry run complete!
71
+ Total issues: 25
72
+ Duplicate groups: 10
73
+ Issues to close: 15
74
+
75
+ This was a DRY RUN - no changes made.
76
+ Run without --dry-run to actually close duplicates.
77
+ ```
78
+
79
+ ### Actual Cleanup
80
+
81
+ ```bash
82
+ /specweave-jira:cleanup-duplicates FS-031
83
+ ```
84
+
85
+ **Output**:
86
+ ```
87
+ Scanning for duplicates in Feature FS-031...
88
+ Found 25 total issues
89
+ Detected 10 duplicate groups
90
+
91
+ CONFIRM: Close 15 duplicate issues? [y/N]
92
+ > y
93
+
94
+ Closing duplicates...
95
+ Closed PROJ-255 (duplicate of PROJ-250)
96
+ Closed PROJ-256 (duplicate of PROJ-251)
97
+ Closed PROJ-260 (duplicate of PROJ-250)
98
+ ...
99
+
100
+ Updating Feature README frontmatter...
101
+ Updated frontmatter with correct issue keys
102
+
103
+ Cleanup complete!
104
+ Closed: 15 duplicates
105
+ Kept: 10 original issues
106
+ ```
107
+
108
+ ## Arguments
109
+
110
+ - `<feature-id>` - Feature ID (e.g., `FS-031` or just `031`)
111
+ - `--dry-run` - Preview changes without actually closing issues (optional)
112
+
113
+ ## Safety Features
114
+
115
+ - **Confirmation prompt**: Asks before closing issues (unless --dry-run)
116
+ - **Dry run mode**: Preview changes safely
117
+ - **Keeps oldest issue**: Preserves the first created issue
118
+ - **Adds closure comment**: Links to the original issue
119
+ - **Updates metadata**: Fixes Feature README frontmatter
120
+
121
+ ## What Gets Closed
122
+
123
+ **Closed issues**:
124
+ - Duplicate summaries (second, third, etc. occurrences)
125
+ - Transitioned to "Won't Do" or "Closed" with comment: "Duplicate of PROJ-XXX"
126
+ - Original issue kept open (or maintains its status)
127
+
128
+ **Example comment on closed duplicate**:
129
+ ```markdown
130
+ h2. Duplicate of PROJ-250
131
+
132
+ This issue was automatically closed by SpecWeave cleanup because it is a duplicate.
133
+
134
+ The original issue (PROJ-250) contains the same content and should be used for tracking instead.
135
+
136
+ Auto-closed by SpecWeave Duplicate Cleanup
137
+ ```
138
+
139
+ ## Requirements
140
+
141
+ 1. **JIRA API token** configured (`JIRA_API_TOKEN`)
142
+ 2. **JIRA email** configured (`JIRA_EMAIL`)
143
+ 3. **JIRA domain** configured (`JIRA_DOMAIN`)
144
+ 4. **Write access** to project (for closing issues)
145
+ 5. **Feature folder exists** at `.specweave/docs/internal/specs/FS-XXX-name/`
146
+
147
+ ## When to Use
148
+
149
+ **Use this command when**:
150
+ - You see multiple issues with the same summary in JIRA
151
+ - Feature sync ran multiple times and created duplicates
152
+ - Feature README frontmatter got corrupted and reset
153
+ - Post-sync validation warns about duplicates
154
+
155
+ **Example warning that triggers this**:
156
+ ```
157
+ WARNING: 10 duplicate(s) detected!
158
+ Run cleanup command to resolve:
159
+ /specweave-jira:cleanup-duplicates FS-031
160
+ ```
161
+
162
+ ## Architecture
163
+
164
+ **Duplicate Detection Logic**:
165
+ 1. JQL query for issues with Feature ID in summary
166
+ 2. Group issues by **exact summary match**
167
+ 3. Within each group, sort by **created date** (ascending)
168
+ 4. Keep **first issue** (oldest = first created)
169
+ 5. Transition **all others** to closed status
170
+
171
+ **Why oldest created?**:
172
+ - Older issues were created first
173
+ - Preserves chronological order
174
+ - Maintains links from old documentation
175
+ - JIRA keys can be reordered, created date is immutable
176
+
177
+ ## JQL Query Pattern
178
+
179
+ ```jql
180
+ summary ~ "[FS-031]" ORDER BY created ASC
181
+ ```
182
+
183
+ ## Related Commands
184
+
185
+ - `/specweave-jira:sync` - Sync Feature to JIRA (with duplicate detection)
186
+ - `/specweave-jira:reconcile` - Reconcile issue states
187
+ - `/specweave:validate` - Validate increment completeness
188
+
189
+ ## Implementation
190
+
191
+ **File**: `plugins/specweave-jira/lib/jira-duplicate-detector.ts`
192
+
193
+ **Class**: `JiraDuplicateDetector`
194
+
195
+ **Algorithm** (3-phase protection):
196
+ 1. **Detection**: JQL query for existing issues matching pattern
197
+ 2. **Verification**: Count check to detect duplicates after creation
198
+ 3. **Reflection**: Auto-close duplicates automatically
199
+
200
+ For manual cleanup:
201
+ 1. JQL query for all issues with Feature ID
202
+ 2. Group by summary (Map<string, JiraIssue[]>)
203
+ 3. Filter groups with >1 issue (duplicates)
204
+ 4. For each duplicate group:
205
+ - Keep first issue (oldest created)
206
+ - Transition others to "Won't Do" via JIRA REST API
207
+
208
+ ## Next Steps
209
+
210
+ After cleanup:
211
+
212
+ 1. **Verify cleanup**: JQL query `summary ~ "[FS-031]"`
213
+ 2. **Check Feature FEATURE.md**: Verify frontmatter has correct issue keys
214
+ 3. **Re-run sync**: `/specweave-jira:sync` (should show no duplicates)
215
+ 4. **Duplicate detection**: Automatically enabled via JiraDuplicateDetector
216
+
217
+ ---
218
+
219
+ **SAFE TO USE**: This command is idempotent and safe to run multiple times.