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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jira-token-provider.d.ts","sourceRoot":"","sources":["../../../../src/integrations/jira/jira-token-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAqBD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAoBnD;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAkBnD;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,MAAM,GAAG,uBAAuB,CAMnF;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAS3D;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAErD;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAErD;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,EAAE,CAchD"}
@@ -0,0 +1,160 @@
1
+ /**
2
+ * JIRA Token Provider
3
+ *
4
+ * Centralized API token retrieval logic for JIRA.
5
+ * Supports domain-specific tokens via environment variables.
6
+ *
7
+ * Token Resolution Priority:
8
+ * 1. Domain-specific: JIRA_API_TOKEN_{DOMAIN} (e.g., JIRA_API_TOKEN_ACME)
9
+ * 2. Default: JIRA_API_TOKEN
10
+ *
11
+ * Email Resolution Priority:
12
+ * 1. Domain-specific: JIRA_EMAIL_{DOMAIN} (e.g., JIRA_EMAIL_ACME)
13
+ * 2. Default: JIRA_EMAIL
14
+ *
15
+ * This mirrors the ADO PAT provider pattern for consistency.
16
+ *
17
+ * @module integrations/jira/jira-token-provider
18
+ */
19
+ /**
20
+ * Normalize domain to environment variable suffix
21
+ *
22
+ * @example
23
+ * normalizeDomainToEnvKey('company.atlassian.net') // 'COMPANY'
24
+ * normalizeDomainToEnvKey('acme-corp.atlassian.net') // 'ACME_CORP'
25
+ * normalizeDomainToEnvKey('https://jira.example.com') // 'JIRA_EXAMPLE_COM'
26
+ */
27
+ function normalizeDomainToEnvKey(domain) {
28
+ // Remove protocol if present
29
+ let normalized = domain.replace(/^https?:\/\//, '');
30
+ // Remove .atlassian.net suffix for cleaner keys
31
+ normalized = normalized.replace(/\.atlassian\.net$/, '');
32
+ // Convert to uppercase and replace non-alphanumeric with underscore
33
+ return normalized.toUpperCase().replace(/[^A-Z0-9]/g, '_');
34
+ }
35
+ /**
36
+ * Get API token for a specific JIRA domain
37
+ *
38
+ * Supports domain-specific tokens via JIRA_API_TOKEN_{DOMAIN} env vars.
39
+ * This allows different JIRA instances to use different credentials.
40
+ *
41
+ * @param domain - The JIRA domain (e.g., company.atlassian.net)
42
+ * @returns The API token string
43
+ * @throws Error if no token is configured
44
+ *
45
+ * @example
46
+ * // Uses JIRA_API_TOKEN_ACME if set, otherwise JIRA_API_TOKEN
47
+ * const token = getJiraToken('acme.atlassian.net');
48
+ */
49
+ export function getJiraToken(domain) {
50
+ // SECURITY: Never log the token value itself
51
+ // Try domain-specific token first (e.g., JIRA_API_TOKEN_ACME)
52
+ const domainEnvKey = `JIRA_API_TOKEN_${normalizeDomainToEnvKey(domain)}`;
53
+ const domainToken = process.env[domainEnvKey];
54
+ if (domainToken) {
55
+ return domainToken;
56
+ }
57
+ // Fall back to default token
58
+ const defaultToken = process.env.JIRA_API_TOKEN;
59
+ if (!defaultToken) {
60
+ throw new Error(`JIRA API token not found. Set JIRA_API_TOKEN in .env file ` +
61
+ `or ${domainEnvKey} for domain-specific token.`);
62
+ }
63
+ return defaultToken;
64
+ }
65
+ /**
66
+ * Get email for a specific JIRA domain
67
+ *
68
+ * @param domain - The JIRA domain
69
+ * @returns The email string
70
+ * @throws Error if no email is configured
71
+ */
72
+ export function getJiraEmail(domain) {
73
+ // Try domain-specific email first
74
+ const domainEnvKey = `JIRA_EMAIL_${normalizeDomainToEnvKey(domain)}`;
75
+ const domainEmail = process.env[domainEnvKey];
76
+ if (domainEmail) {
77
+ return domainEmail;
78
+ }
79
+ // Fall back to default email
80
+ const defaultEmail = process.env.JIRA_EMAIL;
81
+ if (!defaultEmail) {
82
+ throw new Error(`JIRA email not found. Set JIRA_EMAIL in .env file ` +
83
+ `or ${domainEnvKey} for domain-specific email.`);
84
+ }
85
+ return defaultEmail;
86
+ }
87
+ /**
88
+ * Get full credentials for a JIRA domain
89
+ *
90
+ * @param domain - The JIRA domain
91
+ * @returns Complete credentials object
92
+ */
93
+ export function getJiraCredentialsForDomain(domain) {
94
+ return {
95
+ apiToken: getJiraToken(domain),
96
+ email: getJiraEmail(domain),
97
+ domain,
98
+ };
99
+ }
100
+ /**
101
+ * Check if credentials are available for a domain
102
+ *
103
+ * @param domain - The JIRA domain (optional, checks default if not provided)
104
+ * @returns true if credentials are available (domain-specific or default)
105
+ */
106
+ export function hasJiraCredentials(domain) {
107
+ if (domain) {
108
+ const domainEnvKey = `JIRA_API_TOKEN_${normalizeDomainToEnvKey(domain)}`;
109
+ if (process.env[domainEnvKey]) {
110
+ return true;
111
+ }
112
+ }
113
+ return !!process.env.JIRA_API_TOKEN;
114
+ }
115
+ /**
116
+ * Get the environment variable key for a domain's token
117
+ *
118
+ * @param domain - The JIRA domain
119
+ * @returns The environment variable key
120
+ *
121
+ * @example
122
+ * getTokenEnvKey('acme.atlassian.net') // returns 'JIRA_API_TOKEN_ACME'
123
+ */
124
+ export function getTokenEnvKey(domain) {
125
+ return `JIRA_API_TOKEN_${normalizeDomainToEnvKey(domain)}`;
126
+ }
127
+ /**
128
+ * Get the environment variable key for a domain's email
129
+ *
130
+ * @param domain - The JIRA domain
131
+ * @returns The environment variable key
132
+ *
133
+ * @example
134
+ * getEmailEnvKey('acme.atlassian.net') // returns 'JIRA_EMAIL_ACME'
135
+ */
136
+ export function getEmailEnvKey(domain) {
137
+ return `JIRA_EMAIL_${normalizeDomainToEnvKey(domain)}`;
138
+ }
139
+ /**
140
+ * List all configured JIRA domains from environment
141
+ *
142
+ * Scans environment variables for JIRA_API_TOKEN_* patterns
143
+ * and returns the list of configured domains.
144
+ *
145
+ * @returns Array of domain suffixes (e.g., ['ACME', 'CORP'])
146
+ */
147
+ export function listConfiguredDomains() {
148
+ const domains = [];
149
+ const prefix = 'JIRA_API_TOKEN_';
150
+ for (const key of Object.keys(process.env)) {
151
+ if (key.startsWith(prefix) && key !== 'JIRA_API_TOKEN') {
152
+ const domainSuffix = key.substring(prefix.length);
153
+ if (domainSuffix) {
154
+ domains.push(domainSuffix);
155
+ }
156
+ }
157
+ }
158
+ return domains;
159
+ }
160
+ //# sourceMappingURL=jira-token-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jira-token-provider.js","sourceRoot":"","sources":["../../../../src/integrations/jira/jira-token-provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,92 @@
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 { Logger } from '../utils/logger.js';
17
+ export interface AdoReconcileOptions {
18
+ projectRoot: string;
19
+ dryRun?: boolean;
20
+ logger?: Logger;
21
+ }
22
+ export interface IncrementAdoState {
23
+ incrementId: string;
24
+ incrementPath: string;
25
+ metadataStatus: string;
26
+ featureId?: string;
27
+ workItem?: {
28
+ id: number;
29
+ url?: string;
30
+ };
31
+ userStoryWorkItems: Array<{
32
+ userStoryId: string;
33
+ workItemId: number;
34
+ }>;
35
+ }
36
+ export interface AdoReconcileResult {
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
+ workItemId: number;
46
+ reason: string;
47
+ }>;
48
+ }
49
+ export declare class AdoReconciler {
50
+ private projectRoot;
51
+ private dryRun;
52
+ private logger;
53
+ constructor(options: AdoReconcileOptions);
54
+ /**
55
+ * Main reconciliation entry point
56
+ */
57
+ reconcile(): Promise<AdoReconcileResult>;
58
+ /**
59
+ * Reconcile a single increment
60
+ */
61
+ private reconcileIncrement;
62
+ /**
63
+ * Reconcile a single work item
64
+ */
65
+ private reconcileWorkItem;
66
+ /**
67
+ * Scan increments directory for non-archived increments
68
+ */
69
+ private scanIncrements;
70
+ /**
71
+ * Load config.json
72
+ */
73
+ private loadConfig;
74
+ /**
75
+ * Check if ADO credentials are configured
76
+ */
77
+ private hasAdoCredentials;
78
+ /**
79
+ * Get work item from ADO API
80
+ */
81
+ private getWorkItem;
82
+ /**
83
+ * Update work item state in ADO
84
+ */
85
+ private updateWorkItemState;
86
+ }
87
+ /**
88
+ * Convenience function for quick reconciliation
89
+ */
90
+ export declare function reconcileAdo(projectRoot?: string, dryRun?: boolean): Promise<AdoReconcileResult>;
91
+ export default AdoReconciler;
92
+ //# sourceMappingURL=ado-reconciler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ado-reconciler.d.ts","sourceRoot":"","sources":["../../../src/sync/ado-reconciler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,EAAE,MAAM,EAAiB,MAAM,oBAAoB,CAAC;AAE3D,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE;QACT,EAAE,EAAE,MAAM,CAAC;QACX,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC;IACF,kBAAkB,EAAE,KAAK,CAAC;QACxB,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,kBAAkB;IACjC,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,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC,CAAC;CACJ;AAUD,qBAAa,aAAa;IACxB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,MAAM,CAAS;gBAEX,OAAO,EAAE,mBAAmB;IAMxC;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,kBAAkB,CAAC;IA+D9C;;OAEG;YACW,kBAAkB;IAmChC;;OAEG;YACW,iBAAiB;IA+F/B;;OAEG;YACW,cAAc;IA4D5B;;OAEG;YACW,UAAU;IAWxB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAIzB;;OAEG;YACW,WAAW;IAyBzB;;OAEG;YACW,mBAAmB;CA0ClC;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,WAAW,GAAE,MAAsB,EACnC,MAAM,GAAE,OAAe,GACtB,OAAO,CAAC,kBAAkB,CAAC,CAG7B;AAED,eAAe,aAAa,CAAC"}
@@ -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":"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"}