specweave 0.32.2 → 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 (191) hide show
  1. package/CLAUDE.md +39 -0
  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.d.ts.map +1 -1
  26. package/dist/src/cli/commands/init.js +111 -69
  27. package/dist/src/cli/commands/init.js.map +1 -1
  28. package/dist/src/cli/helpers/init/external-import.d.ts +3 -0
  29. package/dist/src/cli/helpers/init/external-import.d.ts.map +1 -1
  30. package/dist/src/cli/helpers/init/external-import.js +17 -4
  31. package/dist/src/cli/helpers/init/external-import.js.map +1 -1
  32. package/dist/src/cli/helpers/init/index.d.ts +1 -0
  33. package/dist/src/cli/helpers/init/index.d.ts.map +1 -1
  34. package/dist/src/cli/helpers/init/index.js +2 -0
  35. package/dist/src/cli/helpers/init/index.js.map +1 -1
  36. package/dist/src/cli/helpers/init/jira-ado-auto-detect.d.ts +70 -0
  37. package/dist/src/cli/helpers/init/jira-ado-auto-detect.d.ts.map +1 -1
  38. package/dist/src/cli/helpers/init/jira-ado-auto-detect.js +214 -4
  39. package/dist/src/cli/helpers/init/jira-ado-auto-detect.js.map +1 -1
  40. package/dist/src/cli/helpers/init/living-docs-preflight.d.ts +4 -0
  41. package/dist/src/cli/helpers/init/living-docs-preflight.d.ts.map +1 -1
  42. package/dist/src/cli/helpers/init/living-docs-preflight.js +34 -3
  43. package/dist/src/cli/helpers/init/living-docs-preflight.js.map +1 -1
  44. package/dist/src/cli/helpers/init/testing-config.d.ts +3 -0
  45. package/dist/src/cli/helpers/init/testing-config.d.ts.map +1 -1
  46. package/dist/src/cli/helpers/init/testing-config.js +9 -2
  47. package/dist/src/cli/helpers/init/testing-config.js.map +1 -1
  48. package/dist/src/cli/helpers/init/translation-config.d.ts +3 -0
  49. package/dist/src/cli/helpers/init/translation-config.d.ts.map +1 -1
  50. package/dist/src/cli/helpers/init/translation-config.js +21 -4
  51. package/dist/src/cli/helpers/init/translation-config.js.map +1 -1
  52. package/dist/src/cli/helpers/init/wizard-navigation.d.ts +45 -0
  53. package/dist/src/cli/helpers/init/wizard-navigation.d.ts.map +1 -0
  54. package/dist/src/cli/helpers/init/wizard-navigation.js +97 -0
  55. package/dist/src/cli/helpers/init/wizard-navigation.js.map +1 -0
  56. package/dist/src/core/increment/increment-archiver.d.ts +25 -4
  57. package/dist/src/core/increment/increment-archiver.d.ts.map +1 -1
  58. package/dist/src/core/increment/increment-archiver.js +64 -20
  59. package/dist/src/core/increment/increment-archiver.js.map +1 -1
  60. package/dist/src/core/increment/increment-utils.d.ts +65 -0
  61. package/dist/src/core/increment/increment-utils.d.ts.map +1 -1
  62. package/dist/src/core/increment/increment-utils.js +114 -0
  63. package/dist/src/core/increment/increment-utils.js.map +1 -1
  64. package/dist/src/core/living-docs/feature-archiver.d.ts +4 -0
  65. package/dist/src/core/living-docs/feature-archiver.d.ts.map +1 -1
  66. package/dist/src/core/living-docs/feature-archiver.js +32 -10
  67. package/dist/src/core/living-docs/feature-archiver.js.map +1 -1
  68. package/dist/src/core/living-docs/feature-id-manager.d.ts.map +1 -1
  69. package/dist/src/core/living-docs/feature-id-manager.js +7 -3
  70. package/dist/src/core/living-docs/feature-id-manager.js.map +1 -1
  71. package/dist/src/core/living-docs/governance/ecosystem-detector.d.ts +38 -0
  72. package/dist/src/core/living-docs/governance/ecosystem-detector.d.ts.map +1 -0
  73. package/dist/src/core/living-docs/governance/ecosystem-detector.js +325 -0
  74. package/dist/src/core/living-docs/governance/ecosystem-detector.js.map +1 -0
  75. package/dist/src/core/living-docs/governance/frontend-standards-parser.d.ts +74 -0
  76. package/dist/src/core/living-docs/governance/frontend-standards-parser.d.ts.map +1 -0
  77. package/dist/src/core/living-docs/governance/frontend-standards-parser.js +366 -0
  78. package/dist/src/core/living-docs/governance/frontend-standards-parser.js.map +1 -0
  79. package/dist/src/core/living-docs/governance/go-standards-parser.d.ts +64 -0
  80. package/dist/src/core/living-docs/governance/go-standards-parser.d.ts.map +1 -0
  81. package/dist/src/core/living-docs/governance/go-standards-parser.js +229 -0
  82. package/dist/src/core/living-docs/governance/go-standards-parser.js.map +1 -0
  83. package/dist/src/core/living-docs/governance/index.d.ts +50 -0
  84. package/dist/src/core/living-docs/governance/index.d.ts.map +1 -0
  85. package/dist/src/core/living-docs/governance/index.js +56 -0
  86. package/dist/src/core/living-docs/governance/index.js.map +1 -0
  87. package/dist/src/core/living-docs/governance/java-standards-parser.d.ts +89 -0
  88. package/dist/src/core/living-docs/governance/java-standards-parser.d.ts.map +1 -0
  89. package/dist/src/core/living-docs/governance/java-standards-parser.js +356 -0
  90. package/dist/src/core/living-docs/governance/java-standards-parser.js.map +1 -0
  91. package/dist/src/core/living-docs/governance/python-standards-parser.d.ts +83 -0
  92. package/dist/src/core/living-docs/governance/python-standards-parser.d.ts.map +1 -0
  93. package/dist/src/core/living-docs/governance/python-standards-parser.js +347 -0
  94. package/dist/src/core/living-docs/governance/python-standards-parser.js.map +1 -0
  95. package/dist/src/core/living-docs/governance/standards-generator.d.ts +38 -0
  96. package/dist/src/core/living-docs/governance/standards-generator.d.ts.map +1 -0
  97. package/dist/src/core/living-docs/governance/standards-generator.js +476 -0
  98. package/dist/src/core/living-docs/governance/standards-generator.js.map +1 -0
  99. package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.d.ts.map +1 -1
  100. package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.js +54 -2
  101. package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.js.map +1 -1
  102. package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.d.ts +5 -1
  103. package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.d.ts.map +1 -1
  104. package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.js +358 -30
  105. package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.js.map +1 -1
  106. package/dist/src/core/living-docs/intelligent-analyzer/types.d.ts +44 -0
  107. package/dist/src/core/living-docs/intelligent-analyzer/types.d.ts.map +1 -1
  108. package/dist/src/core/living-docs/living-docs-sync.d.ts +6 -3
  109. package/dist/src/core/living-docs/living-docs-sync.d.ts.map +1 -1
  110. package/dist/src/core/living-docs/living-docs-sync.js +17 -8
  111. package/dist/src/core/living-docs/living-docs-sync.js.map +1 -1
  112. package/dist/src/core/living-docs/module-analyzer.d.ts +22 -0
  113. package/dist/src/core/living-docs/module-analyzer.d.ts.map +1 -1
  114. package/dist/src/core/living-docs/module-analyzer.js +123 -19
  115. package/dist/src/core/living-docs/module-analyzer.js.map +1 -1
  116. package/dist/src/core/llm/provider-factory.js +2 -2
  117. package/dist/src/core/llm/provider-factory.js.map +1 -1
  118. package/dist/src/core/llm/providers/anthropic-provider.js +1 -1
  119. package/dist/src/core/llm/providers/bedrock-provider.d.ts.map +1 -1
  120. package/dist/src/core/llm/providers/bedrock-provider.js +8 -4
  121. package/dist/src/core/llm/providers/bedrock-provider.js.map +1 -1
  122. package/dist/src/importers/jira-importer.d.ts +14 -0
  123. package/dist/src/importers/jira-importer.d.ts.map +1 -1
  124. package/dist/src/importers/jira-importer.js +75 -0
  125. package/dist/src/importers/jira-importer.js.map +1 -1
  126. package/dist/src/integrations/jira/jira-token-provider.d.ts +93 -0
  127. package/dist/src/integrations/jira/jira-token-provider.d.ts.map +1 -0
  128. package/dist/src/integrations/jira/jira-token-provider.js +160 -0
  129. package/dist/src/integrations/jira/jira-token-provider.js.map +1 -0
  130. package/dist/src/sync/ado-reconciler.d.ts +92 -0
  131. package/dist/src/sync/ado-reconciler.d.ts.map +1 -0
  132. package/dist/src/sync/ado-reconciler.js +335 -0
  133. package/dist/src/sync/ado-reconciler.js.map +1 -0
  134. package/dist/src/sync/jira-reconciler.d.ts +106 -0
  135. package/dist/src/sync/jira-reconciler.d.ts.map +1 -0
  136. package/dist/src/sync/jira-reconciler.js +405 -0
  137. package/dist/src/sync/jira-reconciler.js.map +1 -0
  138. package/dist/src/types/model-selection.d.ts +6 -4
  139. package/dist/src/types/model-selection.d.ts.map +1 -1
  140. package/dist/src/types/model-selection.js +3 -1
  141. package/dist/src/types/model-selection.js.map +1 -1
  142. package/dist/src/utils/external-tool-drift-detector.d.ts +1 -1
  143. package/dist/src/utils/external-tool-drift-detector.d.ts.map +1 -1
  144. package/dist/src/utils/external-tool-drift-detector.js +5 -4
  145. package/dist/src/utils/external-tool-drift-detector.js.map +1 -1
  146. package/dist/src/utils/feature-id-derivation.d.ts +8 -3
  147. package/dist/src/utils/feature-id-derivation.d.ts.map +1 -1
  148. package/dist/src/utils/feature-id-derivation.js +14 -6
  149. package/dist/src/utils/feature-id-derivation.js.map +1 -1
  150. package/dist/src/utils/model-selection.d.ts +3 -4
  151. package/dist/src/utils/model-selection.d.ts.map +1 -1
  152. package/dist/src/utils/model-selection.js +3 -4
  153. package/dist/src/utils/model-selection.js.map +1 -1
  154. package/package.json +1 -1
  155. package/plugins/specweave/agents/code-standards-detective/AGENT.md +48 -0
  156. package/plugins/specweave/commands/specweave-costs.md +4 -4
  157. package/plugins/specweave/commands/specweave-do.md +9 -9
  158. package/plugins/specweave/commands/specweave-done.md +13 -0
  159. package/plugins/specweave/commands/specweave-validate.md +27 -1
  160. package/plugins/specweave/hooks/hooks.json +10 -0
  161. package/plugins/specweave/hooks/spec-project-validator.sh +80 -25
  162. package/plugins/specweave/hooks/v2/guards/increment-duplicate-guard.sh +135 -0
  163. package/plugins/specweave/scripts/read-costs.sh +3 -3
  164. package/plugins/specweave/skills/code-standards-analyzer/SKILL.md +58 -6
  165. package/plugins/specweave/skills/increment-planner/SKILL.md +56 -25
  166. package/plugins/specweave/skills/increment-planner/templates/spec-multi-project.md +4 -2
  167. package/plugins/specweave/skills/increment-planner/templates/spec-single-project.md +2 -1
  168. package/plugins/specweave/skills/increment-planner/templates/tasks-multi-project.md +1 -1
  169. package/plugins/specweave/skills/increment-planner/templates/tasks-single-project.md +1 -1
  170. package/plugins/specweave-ado/commands/cleanup-duplicates.md +212 -0
  171. package/plugins/specweave-ado/commands/reconcile.md +120 -0
  172. package/plugins/specweave-ado/lib/ado-duplicate-detector.js +279 -0
  173. package/plugins/specweave-ado/lib/ado-duplicate-detector.ts +407 -0
  174. package/plugins/specweave-github/agents/github-manager/AGENT.md +2 -2
  175. package/plugins/specweave-infrastructure/skills/hetzner-provisioner/README.md +1 -1
  176. package/plugins/specweave-jira/agents/jira-manager/AGENT.md +1 -1
  177. package/plugins/specweave-jira/agents/jira-multi-project-mapper/AGENT.md +530 -0
  178. package/plugins/specweave-jira/agents/jira-sync-judge/AGENT.md +438 -0
  179. package/plugins/specweave-jira/commands/cleanup-duplicates.md +219 -0
  180. package/plugins/specweave-jira/commands/close.md +297 -0
  181. package/plugins/specweave-jira/commands/create.md +198 -0
  182. package/plugins/specweave-jira/commands/reconcile.md +123 -0
  183. package/plugins/specweave-jira/commands/status.md +215 -0
  184. package/plugins/specweave-jira/lib/jira-duplicate-detector.js +296 -0
  185. package/plugins/specweave-jira/lib/jira-duplicate-detector.ts +434 -0
  186. package/plugins/specweave-jira/lib/jira-permission-gate.js +160 -0
  187. package/plugins/specweave-jira/lib/jira-permission-gate.ts +276 -0
  188. package/plugins/specweave-jira/lib/jira-profile-resolver.js +222 -0
  189. package/plugins/specweave-jira/lib/jira-profile-resolver.ts +427 -0
  190. package/plugins/specweave-jira/reference/jira-specweave-mapping.md +16 -11
  191. package/plugins/specweave-release/commands/specweave-release-npm.md +140 -14
@@ -0,0 +1,335 @@
1
+ /**
2
+ * Azure DevOps Reconciler (NEW in v0.33.0)
3
+ *
4
+ * Reconciles ADO work item states with increment metadata.json statuses.
5
+ * Fixes drift between local SpecWeave state and ADO:
6
+ * - Closes work items for completed increments that are still active
7
+ * - Reactivates work items for in-progress increments that are closed
8
+ *
9
+ * Mirrors the GitHub reconciler pattern for consistency.
10
+ *
11
+ * Triggered by:
12
+ * - /specweave-ado:reconcile command (manual)
13
+ * - SessionStart hook (automatic, if configured)
14
+ * - post-increment-status-change.sh (on resume/abandon)
15
+ */
16
+ import { promises as fs, existsSync } from 'fs';
17
+ import path from 'path';
18
+ import { consoleLogger } from '../utils/logger.js';
19
+ /**
20
+ * ADO Status Mapping
21
+ */
22
+ const ADO_STATUSES = {
23
+ CLOSED: ['Closed', 'Done', 'Resolved', 'Removed'],
24
+ ACTIVE: ['Active', 'New', 'In Progress', 'Committed'],
25
+ };
26
+ export class AdoReconciler {
27
+ constructor(options) {
28
+ this.projectRoot = options.projectRoot;
29
+ this.dryRun = options.dryRun ?? false;
30
+ this.logger = options.logger ?? consoleLogger;
31
+ }
32
+ /**
33
+ * Main reconciliation entry point
34
+ */
35
+ async reconcile() {
36
+ const result = {
37
+ scanned: 0,
38
+ mismatches: 0,
39
+ closed: 0,
40
+ reopened: 0,
41
+ errors: [],
42
+ details: [],
43
+ };
44
+ try {
45
+ // 1. Check if ADO sync is enabled
46
+ const config = await this.loadConfig();
47
+ const canUpdate = config.sync?.settings?.canUpdateExternalItems ?? false;
48
+ const adoEnabled = config.sync?.ado?.enabled ?? false;
49
+ if (!canUpdate || !adoEnabled) {
50
+ this.logger.log('ℹ️ ADO sync is disabled - skipping reconciliation');
51
+ this.logger.log(' Enable with: canUpdateExternalItems=true AND sync.ado.enabled=true');
52
+ return result;
53
+ }
54
+ // 2. Verify ADO credentials
55
+ const hasCredentials = this.hasAdoCredentials();
56
+ if (!hasCredentials) {
57
+ result.errors.push('ADO credentials not configured');
58
+ this.logger.error('❌ ADO PAT not found. Set AZURE_DEVOPS_PAT environment variable.');
59
+ return result;
60
+ }
61
+ // 3. Scan all non-archived increments
62
+ const increments = await this.scanIncrements();
63
+ result.scanned = increments.length;
64
+ this.logger.log(`\n📊 Scanning ${increments.length} increment(s) for ADO state drift...\n`);
65
+ // 4. Check and fix each increment
66
+ for (const inc of increments) {
67
+ await this.reconcileIncrement(inc, result);
68
+ }
69
+ // 5. Report summary
70
+ this.logger.log('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
71
+ this.logger.log('📊 ADO RECONCILIATION SUMMARY');
72
+ this.logger.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
73
+ this.logger.log(` Increments scanned: ${result.scanned}`);
74
+ this.logger.log(` Mismatches found: ${result.mismatches}`);
75
+ this.logger.log(` Work items closed: ${result.closed}`);
76
+ this.logger.log(` Work items reopened: ${result.reopened}`);
77
+ this.logger.log(` Errors: ${result.errors.length}`);
78
+ if (this.dryRun) {
79
+ this.logger.log('\n ⚠️ DRY RUN - No changes were made');
80
+ }
81
+ this.logger.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
82
+ return result;
83
+ }
84
+ catch (error) {
85
+ result.errors.push(`Reconciliation error: ${error.message}`);
86
+ this.logger.error('❌ Reconciliation failed:', error.message);
87
+ return result;
88
+ }
89
+ }
90
+ /**
91
+ * Reconcile a single increment
92
+ */
93
+ async reconcileIncrement(inc, result) {
94
+ const status = inc.metadataStatus;
95
+ // Determine expected ADO state
96
+ const shouldBeClosed = status === 'completed' || status === 'abandoned';
97
+ const shouldBeActive = status === 'in-progress' || status === 'active' || status === 'planning';
98
+ // Check main work item
99
+ if (inc.workItem) {
100
+ await this.reconcileWorkItem(inc.incrementId, inc.workItem.id, shouldBeClosed, shouldBeActive, status, result);
101
+ }
102
+ // Check User Story work items
103
+ for (const us of inc.userStoryWorkItems) {
104
+ await this.reconcileWorkItem(`${inc.incrementId}/${us.userStoryId}`, us.workItemId, shouldBeClosed, shouldBeActive, status, result);
105
+ }
106
+ }
107
+ /**
108
+ * Reconcile a single work item
109
+ */
110
+ async reconcileWorkItem(context, workItemId, shouldBeClosed, shouldBeActive, metadataStatus, result) {
111
+ try {
112
+ // Get current ADO state
113
+ const workItem = await this.getWorkItem(workItemId);
114
+ const currentState = workItem?.fields?.['System.State'] ?? 'Unknown';
115
+ const isCurrentlyClosed = ADO_STATUSES.CLOSED.includes(currentState);
116
+ // Check for mismatch
117
+ if (shouldBeClosed && !isCurrentlyClosed) {
118
+ // Should be closed but is active
119
+ result.mismatches++;
120
+ this.logger.log(` ❌ Work Item #${workItemId} (${context}): ${currentState} but should be CLOSED (status=${metadataStatus})`);
121
+ if (!this.dryRun) {
122
+ const comment = `## 🔄 Auto-Reconciled by SpecWeave
123
+
124
+ This work item was closed by SpecWeave reconciliation.
125
+
126
+ **Reason**: Increment status is \`${metadataStatus}\` but ADO work item was still active.
127
+
128
+ ---
129
+ 🤖 Auto-reconciled by SpecWeave`;
130
+ await this.updateWorkItemState(workItemId, 'Closed', comment);
131
+ result.closed++;
132
+ this.logger.log(` ✅ Closed work item #${workItemId}`);
133
+ }
134
+ else {
135
+ this.logger.log(` [DRY RUN] Would close work item #${workItemId}`);
136
+ }
137
+ result.details.push({
138
+ incrementId: context,
139
+ action: this.dryRun ? 'skip' : 'close',
140
+ workItemId,
141
+ reason: `Status=${metadataStatus}, ADO=${currentState}`,
142
+ });
143
+ }
144
+ else if (shouldBeActive && isCurrentlyClosed) {
145
+ // Should be active but is closed
146
+ result.mismatches++;
147
+ this.logger.log(` ❌ Work Item #${workItemId} (${context}): CLOSED but should be ACTIVE (status=${metadataStatus})`);
148
+ if (!this.dryRun) {
149
+ const comment = `## 🔄 Auto-Reconciled by SpecWeave
150
+
151
+ This work item was reactivated by SpecWeave reconciliation.
152
+
153
+ **Reason**: Increment status is \`${metadataStatus}\` but ADO work item was closed.
154
+ This typically happens when an increment was resumed after being paused/completed.
155
+
156
+ ---
157
+ 🤖 Auto-reconciled by SpecWeave`;
158
+ await this.updateWorkItemState(workItemId, 'Active', comment);
159
+ result.reopened++;
160
+ this.logger.log(` ✅ Reactivated work item #${workItemId}`);
161
+ }
162
+ else {
163
+ this.logger.log(` [DRY RUN] Would reactivate work item #${workItemId}`);
164
+ }
165
+ result.details.push({
166
+ incrementId: context,
167
+ action: this.dryRun ? 'skip' : 'reopen',
168
+ workItemId,
169
+ reason: `Status=${metadataStatus}, ADO=${currentState}`,
170
+ });
171
+ }
172
+ else {
173
+ // State matches
174
+ this.logger.log(` ✅ Work Item #${workItemId} (${context}): State matches (${currentState})`);
175
+ result.details.push({
176
+ incrementId: context,
177
+ action: 'skip',
178
+ workItemId,
179
+ reason: 'State matches',
180
+ });
181
+ }
182
+ }
183
+ catch (error) {
184
+ result.errors.push(`Work item #${workItemId}: ${error.message}`);
185
+ result.details.push({
186
+ incrementId: context,
187
+ action: 'error',
188
+ workItemId,
189
+ reason: error.message,
190
+ });
191
+ }
192
+ }
193
+ /**
194
+ * Scan increments directory for non-archived increments
195
+ */
196
+ async scanIncrements() {
197
+ const incrementsPath = path.join(this.projectRoot, '.specweave', 'increments');
198
+ const results = [];
199
+ if (!existsSync(incrementsPath)) {
200
+ return results;
201
+ }
202
+ const entries = await fs.readdir(incrementsPath, { withFileTypes: true });
203
+ for (const entry of entries) {
204
+ if (!entry.isDirectory())
205
+ continue;
206
+ if (entry.name === '_archive' || entry.name.startsWith('.'))
207
+ continue;
208
+ const incrementPath = path.join(incrementsPath, entry.name);
209
+ const metadataPath = path.join(incrementPath, 'metadata.json');
210
+ if (!existsSync(metadataPath))
211
+ continue;
212
+ try {
213
+ const metadataContent = await fs.readFile(metadataPath, 'utf-8');
214
+ const metadata = JSON.parse(metadataContent);
215
+ // Check for ADO work item link
216
+ const adoSync = metadata.external_sync?.ado;
217
+ if (!adoSync?.workItemId)
218
+ continue;
219
+ const state = {
220
+ incrementId: entry.name,
221
+ incrementPath,
222
+ metadataStatus: metadata.status || 'unknown',
223
+ featureId: metadata.featureId,
224
+ workItem: {
225
+ id: adoSync.workItemId,
226
+ url: adoSync.workItemUrl,
227
+ },
228
+ userStoryWorkItems: [],
229
+ };
230
+ // Extract user story work items if present
231
+ if (adoSync.userStories && Array.isArray(adoSync.userStories)) {
232
+ for (const us of adoSync.userStories) {
233
+ if (us.workItemId) {
234
+ state.userStoryWorkItems.push({
235
+ userStoryId: us.id || us.userStoryId,
236
+ workItemId: us.workItemId,
237
+ });
238
+ }
239
+ }
240
+ }
241
+ results.push(state);
242
+ }
243
+ catch {
244
+ // Skip invalid metadata
245
+ }
246
+ }
247
+ return results;
248
+ }
249
+ /**
250
+ * Load config.json
251
+ */
252
+ async loadConfig() {
253
+ const configPath = path.join(this.projectRoot, '.specweave', 'config.json');
254
+ try {
255
+ const content = await fs.readFile(configPath, 'utf-8');
256
+ return JSON.parse(content);
257
+ }
258
+ catch {
259
+ return {};
260
+ }
261
+ }
262
+ /**
263
+ * Check if ADO credentials are configured
264
+ */
265
+ hasAdoCredentials() {
266
+ return !!(process.env.AZURE_DEVOPS_PAT || process.env.AZURE_DEVOPS_TOKEN);
267
+ }
268
+ /**
269
+ * Get work item from ADO API
270
+ */
271
+ async getWorkItem(workItemId) {
272
+ const org = process.env.AZURE_DEVOPS_ORG;
273
+ const pat = process.env.AZURE_DEVOPS_PAT || process.env.AZURE_DEVOPS_TOKEN;
274
+ if (!org || !pat) {
275
+ throw new Error('ADO credentials not configured');
276
+ }
277
+ const url = `https://dev.azure.com/${org}/_apis/wit/workitems/${workItemId}?api-version=7.1`;
278
+ const auth = Buffer.from(`:${pat}`).toString('base64');
279
+ const response = await fetch(url, {
280
+ headers: {
281
+ Authorization: `Basic ${auth}`,
282
+ 'Content-Type': 'application/json',
283
+ },
284
+ });
285
+ if (!response.ok) {
286
+ throw new Error(`Failed to get work item: ${response.status}`);
287
+ }
288
+ return response.json();
289
+ }
290
+ /**
291
+ * Update work item state in ADO
292
+ */
293
+ async updateWorkItemState(workItemId, newState, comment) {
294
+ const org = process.env.AZURE_DEVOPS_ORG;
295
+ const pat = process.env.AZURE_DEVOPS_PAT || process.env.AZURE_DEVOPS_TOKEN;
296
+ if (!org || !pat) {
297
+ throw new Error('ADO credentials not configured');
298
+ }
299
+ const url = `https://dev.azure.com/${org}/_apis/wit/workitems/${workItemId}?api-version=7.1`;
300
+ const auth = Buffer.from(`:${pat}`).toString('base64');
301
+ const operations = [
302
+ {
303
+ op: 'add',
304
+ path: '/fields/System.State',
305
+ value: newState,
306
+ },
307
+ {
308
+ op: 'add',
309
+ path: '/fields/System.History',
310
+ value: comment,
311
+ },
312
+ ];
313
+ const response = await fetch(url, {
314
+ method: 'PATCH',
315
+ headers: {
316
+ Authorization: `Basic ${auth}`,
317
+ 'Content-Type': 'application/json-patch+json',
318
+ },
319
+ body: JSON.stringify(operations),
320
+ });
321
+ if (!response.ok) {
322
+ const error = await response.text();
323
+ throw new Error(`Failed to update work item: ${response.status} - ${error}`);
324
+ }
325
+ }
326
+ }
327
+ /**
328
+ * Convenience function for quick reconciliation
329
+ */
330
+ export async function reconcileAdo(projectRoot = process.cwd(), dryRun = false) {
331
+ const reconciler = new AdoReconciler({ projectRoot, dryRun });
332
+ return reconciler.reconcile();
333
+ }
334
+ export default AdoReconciler;
335
+ //# sourceMappingURL=ado-reconciler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ado-reconciler.js","sourceRoot":"","sources":["../../../src/sync/ado-reconciler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChD,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAU,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAqC3D;;GAEG;AACH,MAAM,YAAY,GAAG;IACnB,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,CAAC;IACjD,MAAM,EAAE,CAAC,QAAQ,EAAE,KAAK,EAAE,aAAa,EAAE,WAAW,CAAC;CACtD,CAAC;AAEF,MAAM,OAAO,aAAa;IAKxB,YAAY,OAA4B;QACtC,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;QACvC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC;QACtC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,aAAa,CAAC;IAChD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,SAAS;QACb,MAAM,MAAM,GAAuB;YACjC,OAAO,EAAE,CAAC;YACV,UAAU,EAAE,CAAC;YACb,MAAM,EAAE,CAAC;YACT,QAAQ,EAAE,CAAC;YACX,MAAM,EAAE,EAAE;YACV,OAAO,EAAE,EAAE;SACZ,CAAC;QAEF,IAAI,CAAC;YACH,kCAAkC;YAClC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;YACvC,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,sBAAsB,IAAI,KAAK,CAAC;YACzE,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,IAAI,KAAK,CAAC;YAEtD,IAAI,CAAC,SAAS,IAAI,CAAC,UAAU,EAAE,CAAC;gBAC9B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC;gBACtE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,uEAAuE,CAAC,CAAC;gBACzF,OAAO,MAAM,CAAC;YAChB,CAAC;YAED,4BAA4B;YAC5B,MAAM,cAAc,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAChD,IAAI,CAAC,cAAc,EAAE,CAAC;gBACpB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;gBACrD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,iEAAiE,CAAC,CAAC;gBACrF,OAAO,MAAM,CAAC;YAChB,CAAC;YAED,sCAAsC;YACtC,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;YAC/C,MAAM,CAAC,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC;YAEnC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,iBAAiB,UAAU,CAAC,MAAM,wCAAwC,CAAC,CAAC;YAE5F,kCAAkC;YAClC,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;gBAC7B,MAAM,IAAI,CAAC,kBAAkB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAC7C,CAAC;YAED,oBAAoB;YACpB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAC;YACjF,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;YACjD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,6DAA6D,CAAC,CAAC;YAC/E,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,4BAA4B,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;YAC9D,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,4BAA4B,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;YACjE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,4BAA4B,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;YAC7D,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,4BAA4B,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;YAC/D,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,4BAA4B,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;YACpE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBAChB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;YAC7D,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAC;YAEjF,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,yBAAyB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YAC7D,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,0BAA0B,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;YAC7D,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,kBAAkB,CAC9B,GAAsB,EACtB,MAA0B;QAE1B,MAAM,MAAM,GAAG,GAAG,CAAC,cAAc,CAAC;QAElC,+BAA+B;QAC/B,MAAM,cAAc,GAAG,MAAM,KAAK,WAAW,IAAI,MAAM,KAAK,WAAW,CAAC;QACxE,MAAM,cAAc,GAAG,MAAM,KAAK,aAAa,IAAI,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,UAAU,CAAC;QAEhG,uBAAuB;QACvB,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;YACjB,MAAM,IAAI,CAAC,iBAAiB,CAC1B,GAAG,CAAC,WAAW,EACf,GAAG,CAAC,QAAQ,CAAC,EAAE,EACf,cAAc,EACd,cAAc,EACd,MAAM,EACN,MAAM,CACP,CAAC;QACJ,CAAC;QAED,8BAA8B;QAC9B,KAAK,MAAM,EAAE,IAAI,GAAG,CAAC,kBAAkB,EAAE,CAAC;YACxC,MAAM,IAAI,CAAC,iBAAiB,CAC1B,GAAG,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC,WAAW,EAAE,EACtC,EAAE,CAAC,UAAU,EACb,cAAc,EACd,cAAc,EACd,MAAM,EACN,MAAM,CACP,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,iBAAiB,CAC7B,OAAe,EACf,UAAkB,EAClB,cAAuB,EACvB,cAAuB,EACvB,cAAsB,EACtB,MAA0B;QAE1B,IAAI,CAAC;YACH,wBAAwB;YACxB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;YACpD,MAAM,YAAY,GAAG,QAAQ,EAAE,MAAM,EAAE,CAAC,cAAc,CAAC,IAAI,SAAS,CAAC;YACrE,MAAM,iBAAiB,GAAG,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;YAErE,qBAAqB;YACrB,IAAI,cAAc,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBACzC,iCAAiC;gBACjC,MAAM,CAAC,UAAU,EAAE,CAAC;gBACpB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,kBAAkB,UAAU,KAAK,OAAO,MAAM,YAAY,iCAAiC,cAAc,GAAG,CAAC,CAAC;gBAE9H,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;oBACjB,MAAM,OAAO,GAAG;;;;oCAIU,cAAc;;;gCAGlB,CAAC;oBAEvB,MAAM,IAAI,CAAC,mBAAmB,CAAC,UAAU,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;oBAC9D,MAAM,CAAC,MAAM,EAAE,CAAC;oBAChB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,4BAA4B,UAAU,EAAE,CAAC,CAAC;gBAC5D,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,yCAAyC,UAAU,EAAE,CAAC,CAAC;gBACzE,CAAC;gBAED,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC;oBAClB,WAAW,EAAE,OAAO;oBACpB,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO;oBACtC,UAAU;oBACV,MAAM,EAAE,UAAU,cAAc,SAAS,YAAY,EAAE;iBACxD,CAAC,CAAC;YAEL,CAAC;iBAAM,IAAI,cAAc,IAAI,iBAAiB,EAAE,CAAC;gBAC/C,iCAAiC;gBACjC,MAAM,CAAC,UAAU,EAAE,CAAC;gBACpB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,kBAAkB,UAAU,KAAK,OAAO,0CAA0C,cAAc,GAAG,CAAC,CAAC;gBAErH,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;oBACjB,MAAM,OAAO,GAAG;;;;oCAIU,cAAc;;;;gCAIlB,CAAC;oBAEvB,MAAM,IAAI,CAAC,mBAAmB,CAAC,UAAU,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;oBAC9D,MAAM,CAAC,QAAQ,EAAE,CAAC;oBAClB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,iCAAiC,UAAU,EAAE,CAAC,CAAC;gBACjE,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,8CAA8C,UAAU,EAAE,CAAC,CAAC;gBAC9E,CAAC;gBAED,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC;oBAClB,WAAW,EAAE,OAAO;oBACpB,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ;oBACvC,UAAU;oBACV,MAAM,EAAE,UAAU,cAAc,SAAS,YAAY,EAAE;iBACxD,CAAC,CAAC;YAEL,CAAC;iBAAM,CAAC;gBACN,gBAAgB;gBAChB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,kBAAkB,UAAU,KAAK,OAAO,qBAAqB,YAAY,GAAG,CAAC,CAAC;gBAC9F,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC;oBAClB,WAAW,EAAE,OAAO;oBACpB,MAAM,EAAE,MAAM;oBACd,UAAU;oBACV,MAAM,EAAE,eAAe;iBACxB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,UAAU,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YACjE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC;gBAClB,WAAW,EAAE,OAAO;gBACpB,MAAM,EAAE,OAAO;gBACf,UAAU;gBACV,MAAM,EAAE,KAAK,CAAC,OAAO;aACtB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,cAAc;QAC1B,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC;QAC/E,MAAM,OAAO,GAAwB,EAAE,CAAC;QAExC,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;YAChC,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAE1E,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;gBAAE,SAAS;YACnC,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,SAAS;YAEtE,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YAC5D,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,eAAe,CAAC,CAAC;YAE/D,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC;gBAAE,SAAS;YAExC,IAAI,CAAC;gBACH,MAAM,eAAe,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;gBACjE,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;gBAE7C,+BAA+B;gBAC/B,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,EAAE,GAAG,CAAC;gBAC5C,IAAI,CAAC,OAAO,EAAE,UAAU;oBAAE,SAAS;gBAEnC,MAAM,KAAK,GAAsB;oBAC/B,WAAW,EAAE,KAAK,CAAC,IAAI;oBACvB,aAAa;oBACb,cAAc,EAAE,QAAQ,CAAC,MAAM,IAAI,SAAS;oBAC5C,SAAS,EAAE,QAAQ,CAAC,SAAS;oBAC7B,QAAQ,EAAE;wBACR,EAAE,EAAE,OAAO,CAAC,UAAU;wBACtB,GAAG,EAAE,OAAO,CAAC,WAAW;qBACzB;oBACD,kBAAkB,EAAE,EAAE;iBACvB,CAAC;gBAEF,2CAA2C;gBAC3C,IAAI,OAAO,CAAC,WAAW,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;oBAC9D,KAAK,MAAM,EAAE,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;wBACrC,IAAI,EAAE,CAAC,UAAU,EAAE,CAAC;4BAClB,KAAK,CAAC,kBAAkB,CAAC,IAAI,CAAC;gCAC5B,WAAW,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,WAAW;gCACpC,UAAU,EAAE,EAAE,CAAC,UAAU;6BAC1B,CAAC,CAAC;wBACL,CAAC;oBACH,CAAC;gBACH,CAAC;gBAED,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACtB,CAAC;YAAC,MAAM,CAAC;gBACP,wBAAwB;YAC1B,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,UAAU;QACtB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,YAAY,EAAE,aAAa,CAAC,CAAC;QAE5E,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;YACvD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC7B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAED;;OAEG;IACK,iBAAiB;QACvB,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IAC5E,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,WAAW,CAAC,UAAkB;QAC1C,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;QACzC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;QAE3E,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;QACpD,CAAC;QAED,MAAM,GAAG,GAAG,yBAAyB,GAAG,wBAAwB,UAAU,kBAAkB,CAAC;QAC7F,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAEvD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,OAAO,EAAE;gBACP,aAAa,EAAE,SAAS,IAAI,EAAE;gBAC9B,cAAc,EAAE,kBAAkB;aACnC;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,4BAA4B,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QACjE,CAAC;QAED,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;IACzB,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,mBAAmB,CAC/B,UAAkB,EAClB,QAAgB,EAChB,OAAe;QAEf,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;QACzC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;QAE3E,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;QACpD,CAAC;QAED,MAAM,GAAG,GAAG,yBAAyB,GAAG,wBAAwB,UAAU,kBAAkB,CAAC;QAC7F,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAEvD,MAAM,UAAU,GAAG;YACjB;gBACE,EAAE,EAAE,KAAK;gBACT,IAAI,EAAE,sBAAsB;gBAC5B,KAAK,EAAE,QAAQ;aAChB;YACD;gBACE,EAAE,EAAE,KAAK;gBACT,IAAI,EAAE,wBAAwB;gBAC9B,KAAK,EAAE,OAAO;aACf;SACF,CAAC;QAEF,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,MAAM,EAAE,OAAO;YACf,OAAO,EAAE;gBACP,aAAa,EAAE,SAAS,IAAI,EAAE;gBAC9B,cAAc,EAAE,6BAA6B;aAC9C;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC;SACjC,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CAAC,+BAA+B,QAAQ,CAAC,MAAM,MAAM,KAAK,EAAE,CAAC,CAAC;QAC/E,CAAC;IACH,CAAC;CACF;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,cAAsB,OAAO,CAAC,GAAG,EAAE,EACnC,SAAkB,KAAK;IAEvB,MAAM,UAAU,GAAG,IAAI,aAAa,CAAC,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,CAAC;IAC9D,OAAO,UAAU,CAAC,SAAS,EAAE,CAAC;AAChC,CAAC;AAED,eAAe,aAAa,CAAC"}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * JIRA Reconciler (NEW in v0.33.0)
3
+ *
4
+ * Reconciles JIRA issue states with increment metadata.json statuses.
5
+ * Fixes drift between local SpecWeave state and JIRA:
6
+ * - Closes issues for completed increments that are still open
7
+ * - Reopens issues for in-progress increments that are closed
8
+ *
9
+ * Mirrors the GitHub reconciler pattern for consistency.
10
+ *
11
+ * Triggered by:
12
+ * - /specweave-jira:reconcile command (manual)
13
+ * - SessionStart hook (automatic, if configured)
14
+ * - post-increment-status-change.sh (on resume/abandon)
15
+ */
16
+ import { Logger } from '../utils/logger.js';
17
+ export interface JiraReconcileOptions {
18
+ projectRoot: string;
19
+ dryRun?: boolean;
20
+ logger?: Logger;
21
+ }
22
+ export interface IncrementJiraState {
23
+ incrementId: string;
24
+ incrementPath: string;
25
+ metadataStatus: string;
26
+ featureId?: string;
27
+ issue?: {
28
+ key: string;
29
+ url?: string;
30
+ };
31
+ userStoryIssues: Array<{
32
+ userStoryId: string;
33
+ issueKey: string;
34
+ }>;
35
+ }
36
+ export interface JiraReconcileResult {
37
+ scanned: number;
38
+ mismatches: number;
39
+ closed: number;
40
+ reopened: number;
41
+ errors: string[];
42
+ details: Array<{
43
+ incrementId: string;
44
+ action: 'close' | 'reopen' | 'skip' | 'error';
45
+ issueKey: string;
46
+ reason: string;
47
+ }>;
48
+ }
49
+ export declare class JiraReconciler {
50
+ private projectRoot;
51
+ private dryRun;
52
+ private logger;
53
+ private domain;
54
+ private auth;
55
+ constructor(options: JiraReconcileOptions);
56
+ /**
57
+ * Main reconciliation entry point
58
+ */
59
+ reconcile(): Promise<JiraReconcileResult>;
60
+ /**
61
+ * Reconcile a single increment
62
+ */
63
+ private reconcileIncrement;
64
+ /**
65
+ * Reconcile a single issue
66
+ */
67
+ private reconcileIssue;
68
+ /**
69
+ * Scan increments directory for non-archived increments
70
+ */
71
+ private scanIncrements;
72
+ /**
73
+ * Load config.json
74
+ */
75
+ private loadConfig;
76
+ /**
77
+ * Initialize JIRA credentials
78
+ */
79
+ private initCredentials;
80
+ /**
81
+ * Get issue from JIRA API
82
+ */
83
+ private getIssue;
84
+ /**
85
+ * Get available transitions for an issue
86
+ */
87
+ private getTransitions;
88
+ /**
89
+ * Transition issue to new status and add comment
90
+ */
91
+ private transitionIssue;
92
+ /**
93
+ * Execute transition
94
+ */
95
+ private doTransition;
96
+ /**
97
+ * Add comment to issue
98
+ */
99
+ private addComment;
100
+ }
101
+ /**
102
+ * Convenience function for quick reconciliation
103
+ */
104
+ export declare function reconcileJira(projectRoot?: string, dryRun?: boolean): Promise<JiraReconcileResult>;
105
+ export default JiraReconciler;
106
+ //# sourceMappingURL=jira-reconciler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jira-reconciler.d.ts","sourceRoot":"","sources":["../../../src/sync/jira-reconciler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,EAAE,MAAM,EAAiB,MAAM,oBAAoB,CAAC;AAE3D,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE;QACN,GAAG,EAAE,MAAM,CAAC;QACZ,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC;IACF,eAAe,EAAE,KAAK,CAAC;QACrB,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,KAAK,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;QAC9C,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC,CAAC;CACJ;AAUD,qBAAa,cAAc;IACzB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,IAAI,CAAc;gBAEd,OAAO,EAAE,oBAAoB;IAMzC;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAqE/C;;OAEG;YACW,kBAAkB;IAmChC;;OAEG;YACW,cAAc;IA+F5B;;OAEG;YACW,cAAc;IA4D5B;;OAEG;YACW,UAAU;IAWxB;;OAEG;IACH,OAAO,CAAC,eAAe;IAavB;;OAEG;YACW,QAAQ;IAiBtB;;OAEG;YACW,cAAc;IAkB5B;;OAEG;YACW,eAAe;IAwC7B;;OAEG;YACW,YAAY;IAoB1B;;OAEG;YACW,UAAU;CAiCzB;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,WAAW,GAAE,MAAsB,EACnC,MAAM,GAAE,OAAe,GACtB,OAAO,CAAC,mBAAmB,CAAC,CAG9B;AAED,eAAe,cAAc,CAAC"}