specweave 0.32.2 → 0.32.5

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 (244) hide show
  1. package/CLAUDE.md +51 -9
  2. package/bin/specweave.js +34 -0
  3. package/dist/plugins/specweave-ado/lib/ado-duplicate-detector.d.ts +100 -0
  4. package/dist/plugins/specweave-ado/lib/ado-duplicate-detector.d.ts.map +1 -0
  5. package/dist/plugins/specweave-ado/lib/ado-duplicate-detector.js +291 -0
  6. package/dist/plugins/specweave-ado/lib/ado-duplicate-detector.js.map +1 -0
  7. package/dist/plugins/specweave-jira/lib/jira-duplicate-detector.d.ts +103 -0
  8. package/dist/plugins/specweave-jira/lib/jira-duplicate-detector.d.ts.map +1 -0
  9. package/dist/plugins/specweave-jira/lib/jira-duplicate-detector.js +310 -0
  10. package/dist/plugins/specweave-jira/lib/jira-duplicate-detector.js.map +1 -0
  11. package/dist/plugins/specweave-jira/lib/jira-permission-gate.d.ts +126 -0
  12. package/dist/plugins/specweave-jira/lib/jira-permission-gate.d.ts.map +1 -0
  13. package/dist/plugins/specweave-jira/lib/jira-permission-gate.js +207 -0
  14. package/dist/plugins/specweave-jira/lib/jira-permission-gate.js.map +1 -0
  15. package/dist/src/adapters/codex/README.md +1 -1
  16. package/dist/src/adapters/codex/adapter.js +1 -1
  17. package/dist/src/cli/commands/archive.d.ts +2 -0
  18. package/dist/src/cli/commands/archive.d.ts.map +1 -1
  19. package/dist/src/cli/commands/archive.js +33 -0
  20. package/dist/src/cli/commands/archive.js.map +1 -1
  21. package/dist/src/cli/commands/context.d.ts +92 -0
  22. package/dist/src/cli/commands/context.d.ts.map +1 -0
  23. package/dist/src/cli/commands/context.js +205 -0
  24. package/dist/src/cli/commands/context.js.map +1 -0
  25. package/dist/src/cli/commands/init-multiproject.js +1 -1
  26. package/dist/src/cli/commands/init-multiproject.js.map +1 -1
  27. package/dist/src/cli/commands/init.d.ts.map +1 -1
  28. package/dist/src/cli/commands/init.js +111 -69
  29. package/dist/src/cli/commands/init.js.map +1 -1
  30. package/dist/src/cli/commands/migrate-to-multiproject.js +2 -2
  31. package/dist/src/cli/commands/migrate-to-multiproject.js.map +1 -1
  32. package/dist/src/cli/helpers/init/external-import.d.ts +3 -0
  33. package/dist/src/cli/helpers/init/external-import.d.ts.map +1 -1
  34. package/dist/src/cli/helpers/init/external-import.js +17 -4
  35. package/dist/src/cli/helpers/init/external-import.js.map +1 -1
  36. package/dist/src/cli/helpers/init/index.d.ts +1 -0
  37. package/dist/src/cli/helpers/init/index.d.ts.map +1 -1
  38. package/dist/src/cli/helpers/init/index.js +2 -0
  39. package/dist/src/cli/helpers/init/index.js.map +1 -1
  40. package/dist/src/cli/helpers/init/jira-ado-auto-detect.d.ts +70 -0
  41. package/dist/src/cli/helpers/init/jira-ado-auto-detect.d.ts.map +1 -1
  42. package/dist/src/cli/helpers/init/jira-ado-auto-detect.js +214 -4
  43. package/dist/src/cli/helpers/init/jira-ado-auto-detect.js.map +1 -1
  44. package/dist/src/cli/helpers/init/living-docs-preflight.d.ts +4 -0
  45. package/dist/src/cli/helpers/init/living-docs-preflight.d.ts.map +1 -1
  46. package/dist/src/cli/helpers/init/living-docs-preflight.js +34 -3
  47. package/dist/src/cli/helpers/init/living-docs-preflight.js.map +1 -1
  48. package/dist/src/cli/helpers/init/testing-config.d.ts +3 -0
  49. package/dist/src/cli/helpers/init/testing-config.d.ts.map +1 -1
  50. package/dist/src/cli/helpers/init/testing-config.js +9 -2
  51. package/dist/src/cli/helpers/init/testing-config.js.map +1 -1
  52. package/dist/src/cli/helpers/init/translation-config.d.ts +3 -0
  53. package/dist/src/cli/helpers/init/translation-config.d.ts.map +1 -1
  54. package/dist/src/cli/helpers/init/translation-config.js +21 -4
  55. package/dist/src/cli/helpers/init/translation-config.js.map +1 -1
  56. package/dist/src/cli/helpers/init/wizard-navigation.d.ts +45 -0
  57. package/dist/src/cli/helpers/init/wizard-navigation.d.ts.map +1 -0
  58. package/dist/src/cli/helpers/init/wizard-navigation.js +97 -0
  59. package/dist/src/cli/helpers/init/wizard-navigation.js.map +1 -0
  60. package/dist/src/core/increment/increment-archiver.d.ts +25 -4
  61. package/dist/src/core/increment/increment-archiver.d.ts.map +1 -1
  62. package/dist/src/core/increment/increment-archiver.js +64 -20
  63. package/dist/src/core/increment/increment-archiver.js.map +1 -1
  64. package/dist/src/core/increment/increment-utils.d.ts +65 -0
  65. package/dist/src/core/increment/increment-utils.d.ts.map +1 -1
  66. package/dist/src/core/increment/increment-utils.js +114 -0
  67. package/dist/src/core/increment/increment-utils.js.map +1 -1
  68. package/dist/src/core/living-docs/cross-project-sync.d.ts +97 -0
  69. package/dist/src/core/living-docs/cross-project-sync.d.ts.map +1 -0
  70. package/dist/src/core/living-docs/cross-project-sync.js +135 -0
  71. package/dist/src/core/living-docs/cross-project-sync.js.map +1 -0
  72. package/dist/src/core/living-docs/external-sync-orchestrator.d.ts +106 -0
  73. package/dist/src/core/living-docs/external-sync-orchestrator.d.ts.map +1 -0
  74. package/dist/src/core/living-docs/external-sync-orchestrator.js +146 -0
  75. package/dist/src/core/living-docs/external-sync-orchestrator.js.map +1 -0
  76. package/dist/src/core/living-docs/feature-archiver.d.ts +4 -0
  77. package/dist/src/core/living-docs/feature-archiver.d.ts.map +1 -1
  78. package/dist/src/core/living-docs/feature-archiver.js +32 -10
  79. package/dist/src/core/living-docs/feature-archiver.js.map +1 -1
  80. package/dist/src/core/living-docs/feature-id-manager.d.ts.map +1 -1
  81. package/dist/src/core/living-docs/feature-id-manager.js +7 -3
  82. package/dist/src/core/living-docs/feature-id-manager.js.map +1 -1
  83. package/dist/src/core/living-docs/governance/ecosystem-detector.d.ts +38 -0
  84. package/dist/src/core/living-docs/governance/ecosystem-detector.d.ts.map +1 -0
  85. package/dist/src/core/living-docs/governance/ecosystem-detector.js +325 -0
  86. package/dist/src/core/living-docs/governance/ecosystem-detector.js.map +1 -0
  87. package/dist/src/core/living-docs/governance/frontend-standards-parser.d.ts +74 -0
  88. package/dist/src/core/living-docs/governance/frontend-standards-parser.d.ts.map +1 -0
  89. package/dist/src/core/living-docs/governance/frontend-standards-parser.js +366 -0
  90. package/dist/src/core/living-docs/governance/frontend-standards-parser.js.map +1 -0
  91. package/dist/src/core/living-docs/governance/go-standards-parser.d.ts +64 -0
  92. package/dist/src/core/living-docs/governance/go-standards-parser.d.ts.map +1 -0
  93. package/dist/src/core/living-docs/governance/go-standards-parser.js +229 -0
  94. package/dist/src/core/living-docs/governance/go-standards-parser.js.map +1 -0
  95. package/dist/src/core/living-docs/governance/index.d.ts +50 -0
  96. package/dist/src/core/living-docs/governance/index.d.ts.map +1 -0
  97. package/dist/src/core/living-docs/governance/index.js +56 -0
  98. package/dist/src/core/living-docs/governance/index.js.map +1 -0
  99. package/dist/src/core/living-docs/governance/java-standards-parser.d.ts +89 -0
  100. package/dist/src/core/living-docs/governance/java-standards-parser.d.ts.map +1 -0
  101. package/dist/src/core/living-docs/governance/java-standards-parser.js +356 -0
  102. package/dist/src/core/living-docs/governance/java-standards-parser.js.map +1 -0
  103. package/dist/src/core/living-docs/governance/python-standards-parser.d.ts +83 -0
  104. package/dist/src/core/living-docs/governance/python-standards-parser.d.ts.map +1 -0
  105. package/dist/src/core/living-docs/governance/python-standards-parser.js +347 -0
  106. package/dist/src/core/living-docs/governance/python-standards-parser.js.map +1 -0
  107. package/dist/src/core/living-docs/governance/standards-generator.d.ts +38 -0
  108. package/dist/src/core/living-docs/governance/standards-generator.d.ts.map +1 -0
  109. package/dist/src/core/living-docs/governance/standards-generator.js +476 -0
  110. package/dist/src/core/living-docs/governance/standards-generator.js.map +1 -0
  111. package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.d.ts.map +1 -1
  112. package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.js +54 -2
  113. package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.js.map +1 -1
  114. package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.d.ts +5 -1
  115. package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.d.ts.map +1 -1
  116. package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.js +358 -30
  117. package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.js.map +1 -1
  118. package/dist/src/core/living-docs/intelligent-analyzer/types.d.ts +44 -0
  119. package/dist/src/core/living-docs/intelligent-analyzer/types.d.ts.map +1 -1
  120. package/dist/src/core/living-docs/living-docs-sync.d.ts +7 -3
  121. package/dist/src/core/living-docs/living-docs-sync.d.ts.map +1 -1
  122. package/dist/src/core/living-docs/living-docs-sync.js +94 -10
  123. package/dist/src/core/living-docs/living-docs-sync.js.map +1 -1
  124. package/dist/src/core/living-docs/module-analyzer.d.ts +22 -0
  125. package/dist/src/core/living-docs/module-analyzer.d.ts.map +1 -1
  126. package/dist/src/core/living-docs/module-analyzer.js +123 -19
  127. package/dist/src/core/living-docs/module-analyzer.js.map +1 -1
  128. package/dist/src/core/living-docs/sync-helpers/generators.d.ts +8 -1
  129. package/dist/src/core/living-docs/sync-helpers/generators.d.ts.map +1 -1
  130. package/dist/src/core/living-docs/sync-helpers/generators.js +18 -1
  131. package/dist/src/core/living-docs/sync-helpers/generators.js.map +1 -1
  132. package/dist/src/core/living-docs/sync-helpers/index.d.ts +1 -1
  133. package/dist/src/core/living-docs/sync-helpers/index.d.ts.map +1 -1
  134. package/dist/src/core/living-docs/sync-helpers/index.js.map +1 -1
  135. package/dist/src/core/living-docs/sync-helpers/parsers.d.ts +3 -1
  136. package/dist/src/core/living-docs/sync-helpers/parsers.d.ts.map +1 -1
  137. package/dist/src/core/living-docs/sync-helpers/parsers.js +24 -2
  138. package/dist/src/core/living-docs/sync-helpers/parsers.js.map +1 -1
  139. package/dist/src/core/living-docs/types.d.ts +6 -0
  140. package/dist/src/core/living-docs/types.d.ts.map +1 -1
  141. package/dist/src/core/living-docs/validators/index.d.ts +7 -0
  142. package/dist/src/core/living-docs/validators/index.d.ts.map +1 -0
  143. package/dist/src/core/living-docs/validators/index.js +7 -0
  144. package/dist/src/core/living-docs/validators/index.js.map +1 -0
  145. package/dist/src/core/living-docs/validators/project-validator.d.ts +92 -0
  146. package/dist/src/core/living-docs/validators/project-validator.d.ts.map +1 -0
  147. package/dist/src/core/living-docs/validators/project-validator.js +142 -0
  148. package/dist/src/core/living-docs/validators/project-validator.js.map +1 -0
  149. package/dist/src/core/llm/provider-factory.js +2 -2
  150. package/dist/src/core/llm/provider-factory.js.map +1 -1
  151. package/dist/src/core/llm/providers/anthropic-provider.js +1 -1
  152. package/dist/src/core/llm/providers/bedrock-provider.d.ts.map +1 -1
  153. package/dist/src/core/llm/providers/bedrock-provider.js +8 -4
  154. package/dist/src/core/llm/providers/bedrock-provider.js.map +1 -1
  155. package/dist/src/core/project/project-manager.d.ts.map +1 -1
  156. package/dist/src/core/project/project-manager.js +19 -17
  157. package/dist/src/core/project/project-manager.js.map +1 -1
  158. package/dist/src/core/types/config.d.ts +4 -2
  159. package/dist/src/core/types/config.d.ts.map +1 -1
  160. package/dist/src/core/types/config.js.map +1 -1
  161. package/dist/src/core/types/increment-metadata.d.ts +34 -0
  162. package/dist/src/core/types/increment-metadata.d.ts.map +1 -1
  163. package/dist/src/importers/jira-importer.d.ts +14 -0
  164. package/dist/src/importers/jira-importer.d.ts.map +1 -1
  165. package/dist/src/importers/jira-importer.js +75 -0
  166. package/dist/src/importers/jira-importer.js.map +1 -1
  167. package/dist/src/integrations/jira/jira-token-provider.d.ts +93 -0
  168. package/dist/src/integrations/jira/jira-token-provider.d.ts.map +1 -0
  169. package/dist/src/integrations/jira/jira-token-provider.js +160 -0
  170. package/dist/src/integrations/jira/jira-token-provider.js.map +1 -0
  171. package/dist/src/sync/ado-reconciler.d.ts +92 -0
  172. package/dist/src/sync/ado-reconciler.d.ts.map +1 -0
  173. package/dist/src/sync/ado-reconciler.js +335 -0
  174. package/dist/src/sync/ado-reconciler.js.map +1 -0
  175. package/dist/src/sync/jira-reconciler.d.ts +106 -0
  176. package/dist/src/sync/jira-reconciler.d.ts.map +1 -0
  177. package/dist/src/sync/jira-reconciler.js +405 -0
  178. package/dist/src/sync/jira-reconciler.js.map +1 -0
  179. package/dist/src/types/model-selection.d.ts +6 -4
  180. package/dist/src/types/model-selection.d.ts.map +1 -1
  181. package/dist/src/types/model-selection.js +3 -1
  182. package/dist/src/types/model-selection.js.map +1 -1
  183. package/dist/src/utils/cross-cutting-detector.d.ts +66 -0
  184. package/dist/src/utils/cross-cutting-detector.d.ts.map +1 -0
  185. package/dist/src/utils/cross-cutting-detector.js +179 -0
  186. package/dist/src/utils/cross-cutting-detector.js.map +1 -0
  187. package/dist/src/utils/external-tool-drift-detector.d.ts +1 -1
  188. package/dist/src/utils/external-tool-drift-detector.d.ts.map +1 -1
  189. package/dist/src/utils/external-tool-drift-detector.js +5 -4
  190. package/dist/src/utils/external-tool-drift-detector.js.map +1 -1
  191. package/dist/src/utils/feature-id-derivation.d.ts +8 -3
  192. package/dist/src/utils/feature-id-derivation.d.ts.map +1 -1
  193. package/dist/src/utils/feature-id-derivation.js +14 -6
  194. package/dist/src/utils/feature-id-derivation.js.map +1 -1
  195. package/dist/src/utils/model-selection.d.ts +3 -4
  196. package/dist/src/utils/model-selection.d.ts.map +1 -1
  197. package/dist/src/utils/model-selection.js +3 -4
  198. package/dist/src/utils/model-selection.js.map +1 -1
  199. package/dist/src/utils/project-detection.d.ts +12 -8
  200. package/dist/src/utils/project-detection.d.ts.map +1 -1
  201. package/dist/src/utils/project-detection.js +13 -19
  202. package/dist/src/utils/project-detection.js.map +1 -1
  203. package/package.json +1 -1
  204. package/plugins/specweave/agents/code-standards-detective/AGENT.md +48 -0
  205. package/plugins/specweave/commands/specweave-costs.md +4 -4
  206. package/plugins/specweave/commands/specweave-do.md +9 -9
  207. package/plugins/specweave/commands/specweave-done.md +13 -0
  208. package/plugins/specweave/commands/specweave-status.md +64 -0
  209. package/plugins/specweave/commands/specweave-validate.md +27 -1
  210. package/plugins/specweave/hooks/hooks.json +11 -1
  211. package/plugins/specweave/hooks/spec-project-validator.sh +81 -25
  212. package/plugins/specweave/hooks/v2/guards/increment-duplicate-guard.sh +135 -0
  213. package/plugins/specweave/lib/vendor/core/types/increment-metadata.d.ts +34 -0
  214. package/plugins/specweave/scripts/read-costs.sh +3 -3
  215. package/plugins/specweave/skills/code-standards-analyzer/SKILL.md +58 -6
  216. package/plugins/specweave/skills/increment-planner/SKILL.md +135 -29
  217. package/plugins/specweave/skills/increment-planner/templates/spec-multi-project.md +4 -2
  218. package/plugins/specweave/skills/increment-planner/templates/spec-single-project.md +2 -1
  219. package/plugins/specweave/skills/increment-planner/templates/tasks-multi-project.md +1 -1
  220. package/plugins/specweave/skills/increment-planner/templates/tasks-single-project.md +1 -1
  221. package/plugins/specweave/skills/spec-generator/SKILL.md +78 -7
  222. package/plugins/specweave-ado/commands/cleanup-duplicates.md +212 -0
  223. package/plugins/specweave-ado/commands/reconcile.md +120 -0
  224. package/plugins/specweave-ado/lib/ado-duplicate-detector.js +279 -0
  225. package/plugins/specweave-ado/lib/ado-duplicate-detector.ts +407 -0
  226. package/plugins/specweave-github/agents/github-manager/AGENT.md +2 -2
  227. package/plugins/specweave-infrastructure/skills/hetzner-provisioner/README.md +1 -1
  228. package/plugins/specweave-jira/agents/jira-manager/AGENT.md +1 -1
  229. package/plugins/specweave-jira/agents/jira-multi-project-mapper/AGENT.md +530 -0
  230. package/plugins/specweave-jira/agents/jira-sync-judge/AGENT.md +438 -0
  231. package/plugins/specweave-jira/commands/cleanup-duplicates.md +219 -0
  232. package/plugins/specweave-jira/commands/close.md +297 -0
  233. package/plugins/specweave-jira/commands/create.md +198 -0
  234. package/plugins/specweave-jira/commands/reconcile.md +123 -0
  235. package/plugins/specweave-jira/commands/status.md +215 -0
  236. package/plugins/specweave-jira/lib/jira-duplicate-detector.js +296 -0
  237. package/plugins/specweave-jira/lib/jira-duplicate-detector.ts +434 -0
  238. package/plugins/specweave-jira/lib/jira-permission-gate.js +160 -0
  239. package/plugins/specweave-jira/lib/jira-permission-gate.ts +276 -0
  240. package/plugins/specweave-jira/lib/jira-profile-resolver.js +222 -0
  241. package/plugins/specweave-jira/lib/jira-profile-resolver.ts +427 -0
  242. package/plugins/specweave-jira/reference/jira-specweave-mapping.md +16 -11
  243. package/plugins/specweave-release/commands/specweave-release-npm.md +140 -14
  244. package/plugins/specweave/commands/specweave-switch-project.md +0 -168
package/CLAUDE.md CHANGED
@@ -19,26 +19,29 @@ For **contributors to SpecWeave itself** (not users).
19
19
  # OR close completed increments: /specweave:done XXXX
20
20
  ```
21
21
 
22
- ### 1b. Max 8 Tasks Per Increment (HARD LIMIT!)
22
+ ### 1b. Max 25 Tasks Per Increment (SOFT LIMIT)
23
23
 
24
- **>8 tasks = context explosion = CRASH**
24
+ **>25 tasks = consider splitting for maintainability**
25
25
 
26
26
  ```bash
27
27
  # Check task count before starting work:
28
28
  grep -c "^### T-" .specweave/increments/*/tasks.md
29
29
 
30
- # If >8 tasks: SPLIT the increment
31
- # Pattern: Feature → Increment-Part1 (T-001 to T-004) + Increment-Part2 (T-005 to T-008)
30
+ # If >25 tasks: Consider splitting by phase
31
+ # Pattern: Feature → Phase1 (T-001 to T-008) + Phase2 (T-009 to T-016) + ...
32
32
  ```
33
33
 
34
- **Splitting large features:**
34
+ **When to split (guidelines, not hard rules):**
35
+ - Tasks span unrelated subsystems
36
+ - Different teams would own different phases
37
+ - Review cycles would benefit from smaller PRs
38
+
39
+ **Phase-by-phase execution** (recommended for 15-25 tasks):
35
40
  ```
36
- 0045-auth-system/ 0045-auth-system-core/ (T-001 to T-004)
37
- → 0046-auth-system-ui/ (T-005 to T-008)
38
- → 0047-auth-system-tests/ (T-009 to T-012)
41
+ Execute Phase 1 validate continue to Phase 2 → ...
39
42
  ```
40
43
 
41
- **Token budget per increment**: ~50k tokens max (tasks + spec + plan + context)
44
+ **Token budget per increment**: ~80k tokens max (tasks + spec + plan + context)
42
45
 
43
46
  ### 2. Source of Truth
44
47
 
@@ -129,6 +132,45 @@ const config = detectStructureLevel(projectRoot);
129
132
 
130
133
  **Pre-tool-use hook `features-folder-guard.sh` BLOCKS writes to `_features/` (v0.33.0+).**
131
134
 
135
+ ### 2e. NEVER Create Duplicate Increment IDs (v0.33.0+)
136
+
137
+ **Increment numbers MUST be unique across ALL directories!**
138
+
139
+ ```
140
+ ❌ FORBIDDEN (Bug pattern from 2025-12-07):
141
+ 0121-ado-jira-feature-parity-p2-p3/ ← exists
142
+ 0121-intelligent-living-docs-content/ ← DUPLICATE!
143
+
144
+ ❌ ALSO FORBIDDEN (0001 and 0001E share SAME base number):
145
+ 0001-internal-feature/
146
+ 0001E-external-fix/ ← COLLISION! Same base number!
147
+ ```
148
+
149
+ **VALIDATION RULES:**
150
+ ```
151
+ ✅ ALWAYS use IncrementNumberManager.generateUniqueIncrementId()
152
+ ✅ ALWAYS use IncrementNumberManager.validateUnique() before creating
153
+ ✅ Check ALL directories: active, _archive, _abandoned, _paused
154
+ ```
155
+
156
+ **API (v0.33.0+):**
157
+ ```typescript
158
+ import { IncrementNumberManager } from './core/increment/increment-utils.js';
159
+
160
+ // Safe generation with validation:
161
+ const id = IncrementNumberManager.generateUniqueIncrementId('feature-name');
162
+ // → "0122-feature-name" (guaranteed unique)
163
+
164
+ // Manual validation:
165
+ IncrementNumberManager.validateUnique('0121-new-name'); // throws if duplicate!
166
+
167
+ // Find duplicates:
168
+ IncrementNumberManager.findDuplicates('0121');
169
+ // → ["0121-ado-jira-feature (active)", "0121-intelligent-living-docs (active)"]
170
+ ```
171
+
172
+ **Pre-tool-use hook `increment-duplicate-guard.sh` BLOCKS duplicate increment creation (v0.33.0+).**
173
+
132
174
  ### 3. Protected Directories
133
175
 
134
176
  **NEVER delete**: `.specweave/docs/`, `.specweave/increments/`
package/bin/specweave.js CHANGED
@@ -115,6 +115,7 @@ program
115
115
  .option('--pattern <pattern>', 'Archive increments matching pattern (regex)')
116
116
  .option('--archive-completed', 'Archive all completed increments')
117
117
  .option('--no-preserve-active', 'Allow archiving active/paused increments (dangerous!)')
118
+ .option('--external', 'Archive external living docs (FS-XXXE features imported from ADO/JIRA/GitHub)')
118
119
  .option('--dry-run', 'Preview what would be archived without moving files')
119
120
  .action(async (incrementIds, options) => {
120
121
  const { archiveCommand } = await import('../dist/src/cli/commands/archive.js');
@@ -358,6 +359,36 @@ program
358
359
  await syncCmd.parseAsync(['node', 'sync-scheduled', ...process.argv.slice(3)], { from: 'user' });
359
360
  });
360
361
 
362
+ // Context command - Get project/board context for increment planning
363
+ const contextCmd = program
364
+ .command('context')
365
+ .description('Get project/board context for increment planning');
366
+
367
+ contextCmd
368
+ .command('projects')
369
+ .description('List available projects and structure level')
370
+ .action(async () => {
371
+ const { contextProjectsCommand } = await import('../dist/src/cli/commands/context.js');
372
+ await contextProjectsCommand();
373
+ });
374
+
375
+ contextCmd
376
+ .command('boards')
377
+ .description('List available boards for a project (2-level structures)')
378
+ .option('-p, --project <id>', 'Project ID to filter boards')
379
+ .action(async (options) => {
380
+ const { contextBoardsCommand } = await import('../dist/src/cli/commands/context.js');
381
+ await contextBoardsCommand(options);
382
+ });
383
+
384
+ contextCmd
385
+ .command('select')
386
+ .description('Interactive project/board selection (auto-selects if single option)')
387
+ .action(async () => {
388
+ const { contextSelectCommand } = await import('../dist/src/cli/commands/context.js');
389
+ await contextSelectCommand();
390
+ });
391
+
361
392
  // Help text
362
393
  program.on('--help', () => {
363
394
  console.log('');
@@ -396,6 +427,9 @@ program.on('--help', () => {
396
427
  console.log(' $ specweave cache --rebuild # Rebuild dashboard cache');
397
428
  console.log(' $ specweave cache --debug # Show cache debug info');
398
429
  console.log(' $ specweave validate-jira --env .env.prod # Validate with custom .env file');
430
+ console.log(' $ specweave context projects # Get available projects as JSON');
431
+ console.log(' $ specweave context boards --project myapp # Get boards for a project');
432
+ console.log(' $ specweave context select # Interactive project/board selection');
399
433
  console.log('');
400
434
  console.log('Supported AI Tools:');
401
435
  console.log(' - Claude Code (full automation) - Native skills, agents, hooks');
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Azure DevOps Duplicate Detector (v0.33.0)
3
+ *
4
+ * Implements 3-phase duplicate protection for ADO work items:
5
+ * 1. Detection: Check before create
6
+ * 2. Verification: Count check after create
7
+ * 3. Reflection: Auto-close duplicates
8
+ *
9
+ * Mirrors the GitHub DuplicateDetector pattern for consistency.
10
+ */
11
+ import { Logger } from '../../../src/utils/logger.js';
12
+ export interface AdoWorkItem {
13
+ id: number;
14
+ title: string;
15
+ state: string;
16
+ createdDate: string;
17
+ url?: string;
18
+ }
19
+ export interface DuplicateGroup {
20
+ title: string;
21
+ items: AdoWorkItem[];
22
+ keepItem: AdoWorkItem;
23
+ duplicates: AdoWorkItem[];
24
+ }
25
+ export interface DetectionResult {
26
+ found: boolean;
27
+ existingItem?: AdoWorkItem;
28
+ count: number;
29
+ }
30
+ export interface VerificationResult {
31
+ success: boolean;
32
+ expectedCount: number;
33
+ actualCount: number;
34
+ duplicates: AdoWorkItem[];
35
+ }
36
+ export interface CleanupResult {
37
+ closedCount: number;
38
+ keptCount: number;
39
+ errors: string[];
40
+ }
41
+ export declare class AdoDuplicateDetector {
42
+ private org;
43
+ private project;
44
+ private pat;
45
+ private logger;
46
+ constructor(options?: {
47
+ org?: string;
48
+ project?: string;
49
+ pat?: string;
50
+ logger?: Logger;
51
+ });
52
+ /**
53
+ * Phase 1: Check if work item exists before creating
54
+ */
55
+ checkBeforeCreate(titlePattern: string, incrementId?: string): Promise<DetectionResult>;
56
+ /**
57
+ * Phase 2: Verify count after creation
58
+ */
59
+ verifyAfterCreate(titlePattern: string, expectedCount?: number): Promise<VerificationResult>;
60
+ /**
61
+ * Phase 3: Auto-close duplicates
62
+ */
63
+ closeDuplicates(duplicates: AdoWorkItem[], keepItemId: number): Promise<CleanupResult>;
64
+ /**
65
+ * Full cleanup: Find and close all duplicates for a feature
66
+ */
67
+ cleanupFeatureDuplicates(featureId: string, dryRun?: boolean): Promise<{
68
+ groups: DuplicateGroup[];
69
+ totalItems: number;
70
+ duplicateCount: number;
71
+ closedCount: number;
72
+ }>;
73
+ /**
74
+ * Group work items by title
75
+ */
76
+ private groupByTitle;
77
+ /**
78
+ * Search for work items using WIQL
79
+ */
80
+ private searchWorkItems;
81
+ /**
82
+ * Get work item details by IDs
83
+ */
84
+ private getWorkItemDetails;
85
+ /**
86
+ * Close a work item with duplicate comment
87
+ */
88
+ private closeWorkItem;
89
+ }
90
+ /**
91
+ * Convenience function for quick duplicate cleanup
92
+ */
93
+ export declare function cleanupAdoDuplicates(featureId: string, dryRun?: boolean): Promise<{
94
+ groups: DuplicateGroup[];
95
+ totalItems: number;
96
+ duplicateCount: number;
97
+ closedCount: number;
98
+ }>;
99
+ export default AdoDuplicateDetector;
100
+ //# sourceMappingURL=ado-duplicate-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ado-duplicate-detector.d.ts","sourceRoot":"","sources":["../../../../plugins/specweave-ado/lib/ado-duplicate-detector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,MAAM,EAAiB,MAAM,8BAA8B,CAAC;AAErE,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,QAAQ,EAAE,WAAW,CAAC;IACtB,UAAU,EAAE,WAAW,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,OAAO,CAAC;IACf,YAAY,CAAC,EAAE,WAAW,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,WAAW,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,MAAM,CAAS;gBAEX,OAAO,GAAE;QACnB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,MAAM,CAAC,EAAE,MAAM,CAAC;KACZ;IAON;;OAEG;IACG,iBAAiB,CACrB,YAAY,EAAE,MAAM,EACpB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,eAAe,CAAC;IAoB3B;;OAEG;IACG,iBAAiB,CACrB,YAAY,EAAE,MAAM,EACpB,aAAa,GAAE,MAAU,GACxB,OAAO,CAAC,kBAAkB,CAAC;IAmC9B;;OAEG;IACG,eAAe,CACnB,UAAU,EAAE,WAAW,EAAE,EACzB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,aAAa,CAAC;IAqBzB;;OAEG;IACG,wBAAwB,CAC5B,SAAS,EAAE,MAAM,EACjB,MAAM,GAAE,OAAe,GACtB,OAAO,CAAC;QACT,MAAM,EAAE,cAAc,EAAE,CAAC;QACzB,UAAU,EAAE,MAAM,CAAC;QACnB,cAAc,EAAE,MAAM,CAAC;QACvB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IAyEF;;OAEG;IACH,OAAO,CAAC,YAAY;IA0BpB;;OAEG;YACW,eAAe;IAwC7B;;OAEG;YACW,kBAAkB;IA2BhC;;OAEG;YACW,aAAa;CAwC5B;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,MAAM,EACjB,MAAM,GAAE,OAAe,GACtB,OAAO,CAAC;IACT,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC,CAGD;AAED,eAAe,oBAAoB,CAAC"}
@@ -0,0 +1,291 @@
1
+ /**
2
+ * Azure DevOps Duplicate Detector (v0.33.0)
3
+ *
4
+ * Implements 3-phase duplicate protection for ADO work items:
5
+ * 1. Detection: Check before create
6
+ * 2. Verification: Count check after create
7
+ * 3. Reflection: Auto-close duplicates
8
+ *
9
+ * Mirrors the GitHub DuplicateDetector pattern for consistency.
10
+ */
11
+ import { consoleLogger } from '../../../src/utils/logger.js';
12
+ export class AdoDuplicateDetector {
13
+ constructor(options = {}) {
14
+ this.org = options.org || process.env.AZURE_DEVOPS_ORG || '';
15
+ this.project = options.project || process.env.AZURE_DEVOPS_PROJECT || '';
16
+ this.pat = options.pat || process.env.AZURE_DEVOPS_PAT || process.env.AZURE_DEVOPS_TOKEN || '';
17
+ this.logger = options.logger || consoleLogger;
18
+ }
19
+ /**
20
+ * Phase 1: Check if work item exists before creating
21
+ */
22
+ async checkBeforeCreate(titlePattern, incrementId) {
23
+ try {
24
+ const items = await this.searchWorkItems(titlePattern);
25
+ if (items.length > 0) {
26
+ return {
27
+ found: true,
28
+ existingItem: items[0],
29
+ count: items.length,
30
+ };
31
+ }
32
+ return { found: false, count: 0 };
33
+ }
34
+ catch (error) {
35
+ this.logger.log(`⚠️ Detection check failed: ${error.message}`);
36
+ // Graceful degradation - continue anyway
37
+ return { found: false, count: 0 };
38
+ }
39
+ }
40
+ /**
41
+ * Phase 2: Verify count after creation
42
+ */
43
+ async verifyAfterCreate(titlePattern, expectedCount = 1) {
44
+ try {
45
+ const items = await this.searchWorkItems(titlePattern);
46
+ if (items.length > expectedCount) {
47
+ // Duplicates detected!
48
+ const sorted = items.sort((a, b) => a.id - b.id // Sort by ID (lowest = oldest)
49
+ );
50
+ return {
51
+ success: false,
52
+ expectedCount,
53
+ actualCount: items.length,
54
+ duplicates: sorted.slice(expectedCount), // All items after expected count
55
+ };
56
+ }
57
+ return {
58
+ success: true,
59
+ expectedCount,
60
+ actualCount: items.length,
61
+ duplicates: [],
62
+ };
63
+ }
64
+ catch (error) {
65
+ this.logger.log(`⚠️ Verification check failed: ${error.message}`);
66
+ return {
67
+ success: true, // Assume success on error
68
+ expectedCount,
69
+ actualCount: expectedCount,
70
+ duplicates: [],
71
+ };
72
+ }
73
+ }
74
+ /**
75
+ * Phase 3: Auto-close duplicates
76
+ */
77
+ async closeDuplicates(duplicates, keepItemId) {
78
+ const result = {
79
+ closedCount: 0,
80
+ keptCount: 1,
81
+ errors: [],
82
+ };
83
+ for (const item of duplicates) {
84
+ try {
85
+ await this.closeWorkItem(item.id, keepItemId);
86
+ result.closedCount++;
87
+ this.logger.log(` ✅ Closed #${item.id} (duplicate of #${keepItemId})`);
88
+ }
89
+ catch (error) {
90
+ result.errors.push(`#${item.id}: ${error.message}`);
91
+ this.logger.log(` ❌ Failed to close #${item.id}: ${error.message}`);
92
+ }
93
+ }
94
+ return result;
95
+ }
96
+ /**
97
+ * Full cleanup: Find and close all duplicates for a feature
98
+ */
99
+ async cleanupFeatureDuplicates(featureId, dryRun = false) {
100
+ // 1. Search for all work items with feature ID
101
+ const searchPattern = `[${featureId}]`;
102
+ const items = await this.searchWorkItems(searchPattern);
103
+ this.logger.log(`\n🔍 Scanning for duplicates in Feature ${featureId}...`);
104
+ this.logger.log(` Found ${items.length} total work items`);
105
+ // 2. Group by title
106
+ const groups = this.groupByTitle(items);
107
+ const duplicateGroups = groups.filter(g => g.duplicates.length > 0);
108
+ if (duplicateGroups.length === 0) {
109
+ this.logger.log(` ✅ No duplicates found!`);
110
+ return {
111
+ groups: [],
112
+ totalItems: items.length,
113
+ duplicateCount: 0,
114
+ closedCount: 0,
115
+ };
116
+ }
117
+ this.logger.log(` Detected ${duplicateGroups.length} duplicate groups:\n`);
118
+ // 3. Display groups
119
+ for (let i = 0; i < duplicateGroups.length; i++) {
120
+ const group = duplicateGroups[i];
121
+ this.logger.log(` 📋 Group ${i + 1}: "${group.title.substring(0, 50)}..."`);
122
+ this.logger.log(` - #${group.keepItem.id} (KEEP) - Created ${group.keepItem.createdDate.split('T')[0]}`);
123
+ for (const dup of group.duplicates) {
124
+ this.logger.log(` - #${dup.id} (CLOSE) - Created ${dup.createdDate.split('T')[0]} - DUPLICATE`);
125
+ }
126
+ this.logger.log('');
127
+ }
128
+ const totalDuplicates = duplicateGroups.reduce((sum, g) => sum + g.duplicates.length, 0);
129
+ if (dryRun) {
130
+ this.logger.log(`\n✅ Dry run complete!`);
131
+ this.logger.log(` Total work items: ${items.length}`);
132
+ this.logger.log(` Duplicate groups: ${duplicateGroups.length}`);
133
+ this.logger.log(` Work items to close: ${totalDuplicates}`);
134
+ this.logger.log(`\n⚠️ This was a DRY RUN - no changes made.`);
135
+ return {
136
+ groups: duplicateGroups,
137
+ totalItems: items.length,
138
+ duplicateCount: totalDuplicates,
139
+ closedCount: 0,
140
+ };
141
+ }
142
+ // 4. Close duplicates
143
+ let closedCount = 0;
144
+ this.logger.log(`🗑️ Closing duplicates...`);
145
+ for (const group of duplicateGroups) {
146
+ const result = await this.closeDuplicates(group.duplicates, group.keepItem.id);
147
+ closedCount += result.closedCount;
148
+ }
149
+ this.logger.log(`\n✅ Cleanup complete!`);
150
+ this.logger.log(` Closed: ${closedCount} duplicates`);
151
+ this.logger.log(` Kept: ${duplicateGroups.length} original work items`);
152
+ return {
153
+ groups: duplicateGroups,
154
+ totalItems: items.length,
155
+ duplicateCount: totalDuplicates,
156
+ closedCount,
157
+ };
158
+ }
159
+ /**
160
+ * Group work items by title
161
+ */
162
+ groupByTitle(items) {
163
+ const titleMap = new Map();
164
+ for (const item of items) {
165
+ const existing = titleMap.get(item.title) || [];
166
+ existing.push(item);
167
+ titleMap.set(item.title, existing);
168
+ }
169
+ const groups = [];
170
+ for (const [title, groupItems] of titleMap) {
171
+ // Sort by ID (lowest = oldest)
172
+ const sorted = groupItems.sort((a, b) => a.id - b.id);
173
+ groups.push({
174
+ title,
175
+ items: sorted,
176
+ keepItem: sorted[0],
177
+ duplicates: sorted.slice(1),
178
+ });
179
+ }
180
+ return groups;
181
+ }
182
+ /**
183
+ * Search for work items using WIQL
184
+ */
185
+ async searchWorkItems(titlePattern) {
186
+ if (!this.org || !this.pat) {
187
+ throw new Error('ADO credentials not configured');
188
+ }
189
+ const wiql = {
190
+ query: `SELECT [System.Id], [System.Title], [System.State], [System.CreatedDate]
191
+ FROM WorkItems
192
+ WHERE [System.TeamProject] = '${this.project}'
193
+ AND [System.Title] CONTAINS '${titlePattern}'
194
+ ORDER BY [System.Id] ASC`,
195
+ };
196
+ const auth = Buffer.from(`:${this.pat}`).toString('base64');
197
+ const url = `https://dev.azure.com/${this.org}/${this.project}/_apis/wit/wiql?api-version=7.1`;
198
+ const response = await fetch(url, {
199
+ method: 'POST',
200
+ headers: {
201
+ Authorization: `Basic ${auth}`,
202
+ 'Content-Type': 'application/json',
203
+ },
204
+ body: JSON.stringify(wiql),
205
+ });
206
+ if (!response.ok) {
207
+ throw new Error(`WIQL query failed: ${response.status}`);
208
+ }
209
+ const data = await response.json();
210
+ const workItemIds = data.workItems?.map((wi) => wi.id) || [];
211
+ if (workItemIds.length === 0) {
212
+ return [];
213
+ }
214
+ // Fetch full work item details
215
+ return this.getWorkItemDetails(workItemIds);
216
+ }
217
+ /**
218
+ * Get work item details by IDs
219
+ */
220
+ async getWorkItemDetails(ids) {
221
+ if (ids.length === 0)
222
+ return [];
223
+ const auth = Buffer.from(`:${this.pat}`).toString('base64');
224
+ const url = `https://dev.azure.com/${this.org}/_apis/wit/workitems?ids=${ids.join(',')}&api-version=7.1`;
225
+ const response = await fetch(url, {
226
+ headers: {
227
+ Authorization: `Basic ${auth}`,
228
+ 'Content-Type': 'application/json',
229
+ },
230
+ });
231
+ if (!response.ok) {
232
+ throw new Error(`Failed to get work items: ${response.status}`);
233
+ }
234
+ const data = await response.json();
235
+ return (data.value || []).map((wi) => ({
236
+ id: wi.id,
237
+ title: wi.fields['System.Title'],
238
+ state: wi.fields['System.State'],
239
+ createdDate: wi.fields['System.CreatedDate'],
240
+ url: wi._links?.html?.href,
241
+ }));
242
+ }
243
+ /**
244
+ * Close a work item with duplicate comment
245
+ */
246
+ async closeWorkItem(workItemId, originalId) {
247
+ const auth = Buffer.from(`:${this.pat}`).toString('base64');
248
+ const url = `https://dev.azure.com/${this.org}/_apis/wit/workitems/${workItemId}?api-version=7.1`;
249
+ const comment = `## Duplicate of #${originalId}
250
+
251
+ This work item was automatically closed by SpecWeave cleanup because it is a duplicate.
252
+
253
+ The original work item (#${originalId}) contains the same content and should be used for tracking instead.
254
+
255
+ ---
256
+ 🤖 Auto-closed by SpecWeave Duplicate Cleanup`;
257
+ const operations = [
258
+ {
259
+ op: 'add',
260
+ path: '/fields/System.State',
261
+ value: 'Closed',
262
+ },
263
+ {
264
+ op: 'add',
265
+ path: '/fields/System.History',
266
+ value: comment,
267
+ },
268
+ ];
269
+ const response = await fetch(url, {
270
+ method: 'PATCH',
271
+ headers: {
272
+ Authorization: `Basic ${auth}`,
273
+ 'Content-Type': 'application/json-patch+json',
274
+ },
275
+ body: JSON.stringify(operations),
276
+ });
277
+ if (!response.ok) {
278
+ const error = await response.text();
279
+ throw new Error(`Failed to close work item: ${response.status} - ${error}`);
280
+ }
281
+ }
282
+ }
283
+ /**
284
+ * Convenience function for quick duplicate cleanup
285
+ */
286
+ export async function cleanupAdoDuplicates(featureId, dryRun = false) {
287
+ const detector = new AdoDuplicateDetector();
288
+ return detector.cleanupFeatureDuplicates(featureId, dryRun);
289
+ }
290
+ export default AdoDuplicateDetector;
291
+ //# sourceMappingURL=ado-duplicate-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ado-duplicate-detector.js","sourceRoot":"","sources":["../../../../plugins/specweave-ado/lib/ado-duplicate-detector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,103 @@
1
+ /**
2
+ * JIRA Duplicate Detector (v0.33.0)
3
+ *
4
+ * Implements 3-phase duplicate protection for JIRA issues:
5
+ * 1. Detection: Check before create
6
+ * 2. Verification: Count check after create
7
+ * 3. Reflection: Auto-close duplicates
8
+ *
9
+ * Mirrors the GitHub DuplicateDetector pattern for consistency.
10
+ */
11
+ import { Logger } from '../../../src/utils/logger.js';
12
+ export interface JiraIssue {
13
+ key: string;
14
+ summary: string;
15
+ status: string;
16
+ created: string;
17
+ url?: string;
18
+ }
19
+ export interface DuplicateGroup {
20
+ summary: string;
21
+ issues: JiraIssue[];
22
+ keepIssue: JiraIssue;
23
+ duplicates: JiraIssue[];
24
+ }
25
+ export interface DetectionResult {
26
+ found: boolean;
27
+ existingIssue?: JiraIssue;
28
+ count: number;
29
+ }
30
+ export interface VerificationResult {
31
+ success: boolean;
32
+ expectedCount: number;
33
+ actualCount: number;
34
+ duplicates: JiraIssue[];
35
+ }
36
+ export interface CleanupResult {
37
+ closedCount: number;
38
+ keptCount: number;
39
+ errors: string[];
40
+ }
41
+ export declare class JiraDuplicateDetector {
42
+ private domain;
43
+ private auth;
44
+ private logger;
45
+ constructor(options?: {
46
+ domain?: string;
47
+ email?: string;
48
+ token?: string;
49
+ logger?: Logger;
50
+ });
51
+ /**
52
+ * Phase 1: Check if issue exists before creating
53
+ */
54
+ checkBeforeCreate(summaryPattern: string, incrementId?: string): Promise<DetectionResult>;
55
+ /**
56
+ * Phase 2: Verify count after creation
57
+ */
58
+ verifyAfterCreate(summaryPattern: string, expectedCount?: number): Promise<VerificationResult>;
59
+ /**
60
+ * Phase 3: Auto-close duplicates
61
+ */
62
+ closeDuplicates(duplicates: JiraIssue[], keepIssueKey: string): Promise<CleanupResult>;
63
+ /**
64
+ * Full cleanup: Find and close all duplicates for a feature
65
+ */
66
+ cleanupFeatureDuplicates(featureId: string, dryRun?: boolean): Promise<{
67
+ groups: DuplicateGroup[];
68
+ totalIssues: number;
69
+ duplicateCount: number;
70
+ closedCount: number;
71
+ }>;
72
+ /**
73
+ * Group issues by summary
74
+ */
75
+ private groupBySummary;
76
+ /**
77
+ * Search for issues using JQL
78
+ */
79
+ private searchIssues;
80
+ /**
81
+ * Close an issue with duplicate comment
82
+ */
83
+ private closeIssue;
84
+ /**
85
+ * Get available transitions for an issue
86
+ */
87
+ private getTransitions;
88
+ /**
89
+ * Add duplicate comment to issue
90
+ */
91
+ private addComment;
92
+ }
93
+ /**
94
+ * Convenience function for quick duplicate cleanup
95
+ */
96
+ export declare function cleanupJiraDuplicates(featureId: string, dryRun?: boolean): Promise<{
97
+ groups: DuplicateGroup[];
98
+ totalIssues: number;
99
+ duplicateCount: number;
100
+ closedCount: number;
101
+ }>;
102
+ export default JiraDuplicateDetector;
103
+ //# sourceMappingURL=jira-duplicate-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jira-duplicate-detector.d.ts","sourceRoot":"","sources":["../../../../plugins/specweave-jira/lib/jira-duplicate-detector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,MAAM,EAAiB,MAAM,8BAA8B,CAAC;AAErE,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,SAAS,EAAE,SAAS,CAAC;IACrB,UAAU,EAAE,SAAS,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,OAAO,CAAC;IACf,aAAa,CAAC,EAAE,SAAS,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,SAAS,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,qBAAa,qBAAqB;IAChC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,MAAM,CAAS;gBAEX,OAAO,GAAE;QACnB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACZ;IAQN;;OAEG;IACG,iBAAiB,CACrB,cAAc,EAAE,MAAM,EACtB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,eAAe,CAAC;IAoB3B;;OAEG;IACG,iBAAiB,CACrB,cAAc,EAAE,MAAM,EACtB,aAAa,GAAE,MAAU,GACxB,OAAO,CAAC,kBAAkB,CAAC;IAmC9B;;OAEG;IACG,eAAe,CACnB,UAAU,EAAE,SAAS,EAAE,EACvB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,aAAa,CAAC;IAqBzB;;OAEG;IACG,wBAAwB,CAC5B,SAAS,EAAE,MAAM,EACjB,MAAM,GAAE,OAAe,GACtB,OAAO,CAAC;QACT,MAAM,EAAE,cAAc,EAAE,CAAC;QACzB,WAAW,EAAE,MAAM,CAAC;QACpB,cAAc,EAAE,MAAM,CAAC;QACvB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IAyEF;;OAEG;IACH,OAAO,CAAC,cAAc;IA4BtB;;OAEG;YACW,YAAY;IA6B1B;;OAEG;YACW,UAAU;IAwCxB;;OAEG;YACW,cAAc;IAkB5B;;OAEG;YACW,UAAU;CA0CzB;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,SAAS,EAAE,MAAM,EACjB,MAAM,GAAE,OAAe,GACtB,OAAO,CAAC;IACT,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC,CAGD;AAED,eAAe,qBAAqB,CAAC"}