specweave 1.0.351 → 1.0.352

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 (211) hide show
  1. package/bin/specweave.js +9 -0
  2. package/dist/plugins/specweave-ado/lib/ado-client-v2.d.ts +5 -0
  3. package/dist/plugins/specweave-ado/lib/ado-client-v2.d.ts.map +1 -1
  4. package/dist/plugins/specweave-ado/lib/ado-client-v2.js +61 -23
  5. package/dist/plugins/specweave-ado/lib/ado-client-v2.js.map +1 -1
  6. package/dist/plugins/specweave-ado/lib/ado-duplicate-detector.d.ts.map +1 -1
  7. package/dist/plugins/specweave-ado/lib/ado-duplicate-detector.js +3 -2
  8. package/dist/plugins/specweave-ado/lib/ado-duplicate-detector.js.map +1 -1
  9. package/dist/plugins/specweave-ado/lib/ado-profile-resolver.d.ts.map +1 -1
  10. package/dist/plugins/specweave-ado/lib/ado-profile-resolver.js +2 -1
  11. package/dist/plugins/specweave-ado/lib/ado-profile-resolver.js.map +1 -1
  12. package/dist/plugins/specweave-ado/lib/ado-spec-sync.d.ts +1 -1
  13. package/dist/plugins/specweave-ado/lib/ado-spec-sync.d.ts.map +1 -1
  14. package/dist/plugins/specweave-ado/lib/ado-spec-sync.js +25 -9
  15. package/dist/plugins/specweave-ado/lib/ado-spec-sync.js.map +1 -1
  16. package/dist/plugins/specweave-ado/lib/conflict-resolver.d.ts.map +1 -1
  17. package/dist/plugins/specweave-ado/lib/conflict-resolver.js +17 -1
  18. package/dist/plugins/specweave-ado/lib/conflict-resolver.js.map +1 -1
  19. package/dist/plugins/specweave-ado/lib/per-us-sync.d.ts +3 -0
  20. package/dist/plugins/specweave-ado/lib/per-us-sync.d.ts.map +1 -1
  21. package/dist/plugins/specweave-ado/lib/per-us-sync.js +14 -1
  22. package/dist/plugins/specweave-ado/lib/per-us-sync.js.map +1 -1
  23. package/dist/plugins/specweave-github/lib/github-client-v2.d.ts.map +1 -1
  24. package/dist/plugins/specweave-github/lib/github-client-v2.js +10 -7
  25. package/dist/plugins/specweave-github/lib/github-client-v2.js.map +1 -1
  26. package/dist/plugins/specweave-github/lib/github-client.d.ts +1 -1
  27. package/dist/plugins/specweave-github/lib/github-client.d.ts.map +1 -1
  28. package/dist/plugins/specweave-github/lib/github-client.js +7 -5
  29. package/dist/plugins/specweave-github/lib/github-client.js.map +1 -1
  30. package/dist/plugins/specweave-github/lib/github-cross-repo-sync.js +13 -3
  31. package/dist/plugins/specweave-github/lib/github-cross-repo-sync.js.map +1 -1
  32. package/dist/plugins/specweave-github/lib/github-feature-sync-cli.d.ts +24 -1
  33. package/dist/plugins/specweave-github/lib/github-feature-sync-cli.d.ts.map +1 -1
  34. package/dist/plugins/specweave-github/lib/github-feature-sync-cli.js +36 -20
  35. package/dist/plugins/specweave-github/lib/github-feature-sync-cli.js.map +1 -1
  36. package/dist/plugins/specweave-github/lib/github-graphql-client.d.ts +1 -0
  37. package/dist/plugins/specweave-github/lib/github-graphql-client.d.ts.map +1 -1
  38. package/dist/plugins/specweave-github/lib/github-graphql-client.js +32 -22
  39. package/dist/plugins/specweave-github/lib/github-graphql-client.js.map +1 -1
  40. package/dist/plugins/specweave-github/lib/github-spec-frontmatter-updater.js +144 -8
  41. package/dist/plugins/specweave-github/lib/github-spec-frontmatter-updater.js.map +1 -1
  42. package/dist/plugins/specweave-github/lib/github-spec-sync.d.ts +8 -1
  43. package/dist/plugins/specweave-github/lib/github-spec-sync.d.ts.map +1 -1
  44. package/dist/plugins/specweave-github/lib/github-spec-sync.js +94 -24
  45. package/dist/plugins/specweave-github/lib/github-spec-sync.js.map +1 -1
  46. package/dist/plugins/specweave-github/lib/github-sync-orchestrator.d.ts +1 -0
  47. package/dist/plugins/specweave-github/lib/github-sync-orchestrator.d.ts.map +1 -1
  48. package/dist/plugins/specweave-github/lib/github-sync-orchestrator.js +2 -1
  49. package/dist/plugins/specweave-github/lib/github-sync-orchestrator.js.map +1 -1
  50. package/dist/plugins/specweave-github/lib/github-us-auto-closer.d.ts.map +1 -1
  51. package/dist/plugins/specweave-github/lib/github-us-auto-closer.js +25 -0
  52. package/dist/plugins/specweave-github/lib/github-us-auto-closer.js.map +1 -1
  53. package/dist/plugins/specweave-github/lib/per-us-sync.d.ts +3 -0
  54. package/dist/plugins/specweave-github/lib/per-us-sync.d.ts.map +1 -1
  55. package/dist/plugins/specweave-github/lib/per-us-sync.js +29 -9
  56. package/dist/plugins/specweave-github/lib/per-us-sync.js.map +1 -1
  57. package/dist/plugins/specweave-jira/lib/content-format-adapter.d.ts +59 -0
  58. package/dist/plugins/specweave-jira/lib/content-format-adapter.d.ts.map +1 -0
  59. package/dist/plugins/specweave-jira/lib/content-format-adapter.js +159 -0
  60. package/dist/plugins/specweave-jira/lib/content-format-adapter.js.map +1 -0
  61. package/dist/plugins/specweave-jira/lib/jira-deployment-detector.d.ts +45 -0
  62. package/dist/plugins/specweave-jira/lib/jira-deployment-detector.d.ts.map +1 -0
  63. package/dist/plugins/specweave-jira/lib/jira-deployment-detector.js +92 -0
  64. package/dist/plugins/specweave-jira/lib/jira-deployment-detector.js.map +1 -0
  65. package/dist/plugins/specweave-jira/lib/jira-duplicate-detector.d.ts.map +1 -1
  66. package/dist/plugins/specweave-jira/lib/jira-duplicate-detector.js +13 -28
  67. package/dist/plugins/specweave-jira/lib/jira-duplicate-detector.js.map +1 -1
  68. package/dist/plugins/specweave-jira/lib/jira-epic-sync.d.ts +2 -1
  69. package/dist/plugins/specweave-jira/lib/jira-epic-sync.d.ts.map +1 -1
  70. package/dist/plugins/specweave-jira/lib/jira-epic-sync.js +19 -7
  71. package/dist/plugins/specweave-jira/lib/jira-epic-sync.js.map +1 -1
  72. package/dist/plugins/specweave-jira/lib/jira-field-discovery.d.ts +47 -0
  73. package/dist/plugins/specweave-jira/lib/jira-field-discovery.d.ts.map +1 -0
  74. package/dist/plugins/specweave-jira/lib/jira-field-discovery.js +110 -0
  75. package/dist/plugins/specweave-jira/lib/jira-field-discovery.js.map +1 -0
  76. package/dist/plugins/specweave-jira/lib/jira-paginated-search.d.ts +26 -0
  77. package/dist/plugins/specweave-jira/lib/jira-paginated-search.d.ts.map +1 -0
  78. package/dist/plugins/specweave-jira/lib/jira-paginated-search.js +77 -0
  79. package/dist/plugins/specweave-jira/lib/jira-paginated-search.js.map +1 -0
  80. package/dist/plugins/specweave-jira/lib/jira-spec-commit-sync.d.ts.map +1 -1
  81. package/dist/plugins/specweave-jira/lib/jira-spec-commit-sync.js +5 -3
  82. package/dist/plugins/specweave-jira/lib/jira-spec-commit-sync.js.map +1 -1
  83. package/dist/plugins/specweave-jira/lib/jira-spec-sync.d.ts +17 -2
  84. package/dist/plugins/specweave-jira/lib/jira-spec-sync.d.ts.map +1 -1
  85. package/dist/plugins/specweave-jira/lib/jira-spec-sync.js +103 -33
  86. package/dist/plugins/specweave-jira/lib/jira-spec-sync.js.map +1 -1
  87. package/dist/plugins/specweave-jira/lib/jira-status-sync.d.ts +4 -0
  88. package/dist/plugins/specweave-jira/lib/jira-status-sync.d.ts.map +1 -1
  89. package/dist/plugins/specweave-jira/lib/jira-status-sync.js +19 -6
  90. package/dist/plugins/specweave-jira/lib/jira-status-sync.js.map +1 -1
  91. package/dist/plugins/specweave-jira/lib/metadata-paths.d.ts +29 -0
  92. package/dist/plugins/specweave-jira/lib/metadata-paths.d.ts.map +1 -0
  93. package/dist/plugins/specweave-jira/lib/metadata-paths.js +73 -0
  94. package/dist/plugins/specweave-jira/lib/metadata-paths.js.map +1 -0
  95. package/dist/plugins/specweave-jira/lib/reorganization-detector.d.ts +15 -2
  96. package/dist/plugins/specweave-jira/lib/reorganization-detector.d.ts.map +1 -1
  97. package/dist/plugins/specweave-jira/lib/reorganization-detector.js +121 -33
  98. package/dist/plugins/specweave-jira/lib/reorganization-detector.js.map +1 -1
  99. package/dist/src/cli/commands/sync-progress.d.ts +6 -0
  100. package/dist/src/cli/commands/sync-progress.d.ts.map +1 -1
  101. package/dist/src/cli/commands/sync-progress.js +37 -0
  102. package/dist/src/cli/commands/sync-progress.js.map +1 -1
  103. package/dist/src/cli/commands/sync-task.d.ts +16 -0
  104. package/dist/src/cli/commands/sync-task.d.ts.map +1 -0
  105. package/dist/src/cli/commands/sync-task.js +42 -0
  106. package/dist/src/cli/commands/sync-task.js.map +1 -0
  107. package/dist/src/core/hooks/LifecycleHookDispatcher.d.ts +9 -1
  108. package/dist/src/core/hooks/LifecycleHookDispatcher.d.ts.map +1 -1
  109. package/dist/src/core/hooks/LifecycleHookDispatcher.js +26 -8
  110. package/dist/src/core/hooks/LifecycleHookDispatcher.js.map +1 -1
  111. package/dist/src/core/increment/metadata-manager.d.ts.map +1 -1
  112. package/dist/src/core/increment/metadata-manager.js +26 -0
  113. package/dist/src/core/increment/metadata-manager.js.map +1 -1
  114. package/dist/src/core/increment/status-commands.d.ts.map +1 -1
  115. package/dist/src/core/increment/status-commands.js +33 -11
  116. package/dist/src/core/increment/status-commands.js.map +1 -1
  117. package/dist/src/locales/de/cli.json +245 -77
  118. package/dist/src/locales/es/cli.json +238 -3
  119. package/dist/src/locales/fr/cli.json +254 -86
  120. package/dist/src/locales/ja/cli.json +246 -78
  121. package/dist/src/locales/ko/cli.json +246 -78
  122. package/dist/src/locales/pt/cli.json +245 -77
  123. package/dist/src/locales/zh/cli.json +251 -83
  124. package/dist/src/sync/github-reconciler.d.ts +30 -0
  125. package/dist/src/sync/github-reconciler.d.ts.map +1 -1
  126. package/dist/src/sync/github-reconciler.js +235 -1
  127. package/dist/src/sync/github-reconciler.js.map +1 -1
  128. package/package.json +1 -1
  129. package/plugins/specweave/hooks/v2/guards/task-ac-sync-guard.sh +31 -0
  130. package/plugins/specweave/lib/vendor/core/increment/metadata-manager.js +26 -0
  131. package/plugins/specweave/lib/vendor/core/increment/metadata-manager.js.map +1 -1
  132. package/plugins/specweave/lib/vendor/sync/github-reconciler.d.ts +30 -0
  133. package/plugins/specweave/lib/vendor/sync/github-reconciler.js +235 -1
  134. package/plugins/specweave/lib/vendor/sync/github-reconciler.js.map +1 -1
  135. package/plugins/specweave/skills/team-lead/agents/security.md +0 -1
  136. package/plugins/specweave-ado/hooks/post-task-completion.sh +2 -2
  137. package/plugins/specweave-ado/lib/ado-client-v2.js +51 -21
  138. package/plugins/specweave-ado/lib/ado-client-v2.ts +62 -23
  139. package/plugins/specweave-ado/lib/ado-duplicate-detector.js +4 -4
  140. package/plugins/specweave-ado/lib/ado-duplicate-detector.ts +4 -3
  141. package/plugins/specweave-ado/lib/ado-hierarchical-sync.js +54 -12
  142. package/plugins/specweave-ado/lib/ado-hierarchical-sync.ts +88 -18
  143. package/plugins/specweave-ado/lib/ado-profile-resolver.js +1 -1
  144. package/plugins/specweave-ado/lib/ado-profile-resolver.ts +3 -1
  145. package/plugins/specweave-ado/lib/ado-spec-sync.js +22 -9
  146. package/plugins/specweave-ado/lib/ado-spec-sync.ts +27 -9
  147. package/plugins/specweave-ado/lib/conflict-resolver.js +17 -1
  148. package/plugins/specweave-ado/lib/conflict-resolver.ts +17 -1
  149. package/plugins/specweave-ado/lib/enhanced-ado-sync.js +11 -1
  150. package/plugins/specweave-ado/lib/per-us-sync.js +8 -1
  151. package/plugins/specweave-ado/lib/per-us-sync.ts +17 -2
  152. package/plugins/specweave-github/hooks/github-auto-create-handler.sh +28 -2
  153. package/plugins/specweave-github/hooks/post-task-completion.sh +6 -3
  154. package/plugins/specweave-github/lib/enhanced-github-sync.js +35 -6
  155. package/plugins/specweave-github/lib/github-board-resolver.js +4 -4
  156. package/plugins/specweave-github/lib/github-board-resolver.ts +4 -4
  157. package/plugins/specweave-github/lib/github-client-v2.js +6 -6
  158. package/plugins/specweave-github/lib/github-client-v2.ts +11 -7
  159. package/plugins/specweave-github/lib/github-client.js +5 -4
  160. package/plugins/specweave-github/lib/github-client.ts +7 -5
  161. package/plugins/specweave-github/lib/github-cross-repo-sync.js +17 -3
  162. package/plugins/specweave-github/lib/github-cross-repo-sync.ts +16 -3
  163. package/plugins/specweave-github/lib/github-feature-sync-cli.js +20 -11
  164. package/plugins/specweave-github/lib/github-feature-sync-cli.ts +42 -20
  165. package/plugins/specweave-github/lib/github-graphql-client.js +29 -20
  166. package/plugins/specweave-github/lib/github-graphql-client.ts +34 -22
  167. package/plugins/specweave-github/lib/github-hierarchical-sync.js +2 -2
  168. package/plugins/specweave-github/lib/github-hierarchical-sync.ts +2 -2
  169. package/plugins/specweave-github/lib/github-multi-project-sync.js +23 -7
  170. package/plugins/specweave-github/lib/github-multi-project-sync.ts +26 -8
  171. package/plugins/specweave-github/lib/github-spec-frontmatter-updater.js +110 -5
  172. package/plugins/specweave-github/lib/github-spec-frontmatter-updater.ts +135 -9
  173. package/plugins/specweave-github/lib/github-spec-sync.js +85 -24
  174. package/plugins/specweave-github/lib/github-spec-sync.ts +100 -26
  175. package/plugins/specweave-github/lib/github-sync-orchestrator.js +2 -1
  176. package/plugins/specweave-github/lib/github-sync-orchestrator.ts +3 -1
  177. package/plugins/specweave-github/lib/github-us-auto-closer.js +25 -0
  178. package/plugins/specweave-github/lib/github-us-auto-closer.ts +43 -0
  179. package/plugins/specweave-github/lib/per-us-sync.js +26 -11
  180. package/plugins/specweave-github/lib/per-us-sync.ts +29 -11
  181. package/plugins/specweave-jira/hooks/post-task-completion.sh +2 -1
  182. package/plugins/specweave-jira/lib/content-format-adapter.js +116 -0
  183. package/plugins/specweave-jira/lib/content-format-adapter.ts +189 -0
  184. package/plugins/specweave-jira/lib/enhanced-jira-sync.js +21 -5
  185. package/plugins/specweave-jira/lib/jira-deployment-detector.js +63 -0
  186. package/plugins/specweave-jira/lib/jira-deployment-detector.ts +113 -0
  187. package/plugins/specweave-jira/lib/jira-duplicate-detector.js +12 -29
  188. package/plugins/specweave-jira/lib/jira-duplicate-detector.ts +13 -27
  189. package/plugins/specweave-jira/lib/jira-epic-sync.js +15 -5
  190. package/plugins/specweave-jira/lib/jira-epic-sync.ts +22 -7
  191. package/plugins/specweave-jira/lib/jira-field-discovery.js +76 -0
  192. package/plugins/specweave-jira/lib/jira-field-discovery.ts +139 -0
  193. package/plugins/specweave-jira/lib/jira-hierarchical-sync.js +10 -0
  194. package/plugins/specweave-jira/lib/jira-hierarchical-sync.ts +11 -0
  195. package/plugins/specweave-jira/lib/jira-multi-project-sync.js +19 -9
  196. package/plugins/specweave-jira/lib/jira-multi-project-sync.ts +25 -14
  197. package/plugins/specweave-jira/lib/jira-paginated-search.js +55 -0
  198. package/plugins/specweave-jira/lib/jira-paginated-search.ts +108 -0
  199. package/plugins/specweave-jira/lib/jira-spec-commit-sync.js +5 -3
  200. package/plugins/specweave-jira/lib/jira-spec-commit-sync.ts +5 -3
  201. package/plugins/specweave-jira/lib/jira-spec-sync.js +102 -31
  202. package/plugins/specweave-jira/lib/jira-spec-sync.ts +123 -45
  203. package/plugins/specweave-jira/lib/jira-status-sync.js +18 -5
  204. package/plugins/specweave-jira/lib/jira-status-sync.ts +21 -6
  205. package/plugins/specweave-jira/lib/metadata-paths.js +38 -0
  206. package/plugins/specweave-jira/lib/metadata-paths.ts +73 -0
  207. package/plugins/specweave-jira/lib/reorganization-detector.js +101 -23
  208. package/plugins/specweave-jira/lib/reorganization-detector.ts +125 -35
  209. package/plugins/specweave-jira/scripts/refresh-cache.js +1 -1
  210. package/plugins/specweave-jira/scripts/refresh-cache.ts +2 -2
  211. package/plugins/specweave-jira/skills/jira-resource-validator/SKILL.md +3 -5
@@ -0,0 +1,47 @@
1
+ /**
2
+ * JIRA Field Discovery
3
+ *
4
+ * Dynamically discovers custom field IDs (e.g., Epic Link) and
5
+ * detects project style (Next-gen vs Classic).
6
+ *
7
+ * Results are cached per domain/project to avoid repeated lookups.
8
+ *
9
+ * @module jira-field-discovery
10
+ */
11
+ /**
12
+ * Discover the Epic Link custom field ID by querying /rest/api/field.
13
+ * Searches for fields with name "Epic Link" or schema type "com.pyxis.greenhopper.jira:gh-epic-link".
14
+ *
15
+ * @returns The custom field ID (e.g., "customfield_10014") or null if not found
16
+ */
17
+ export declare function discoverEpicLinkField(domain: string, auth: {
18
+ email: string;
19
+ apiToken: string;
20
+ }): Promise<string | null>;
21
+ /**
22
+ * Detect whether a JIRA project uses Next-gen (Team-managed) or Classic (Company-managed) style.
23
+ *
24
+ * Next-gen projects use `parent` field for epic linking.
25
+ * Classic projects use a custom field (Epic Link).
26
+ */
27
+ export declare function detectProjectStyle(domain: string, projectKey: string, auth: {
28
+ email: string;
29
+ apiToken: string;
30
+ }): Promise<'next-gen' | 'classic'>;
31
+ /**
32
+ * Get the correct field name/ID for linking an issue to an epic,
33
+ * based on project style.
34
+ *
35
+ * - Next-gen: uses `parent` field
36
+ * - Classic: uses the discovered Epic Link custom field ID
37
+ */
38
+ export declare function getEpicLinkFieldForProject(domain: string, projectKey: string, auth: {
39
+ email: string;
40
+ apiToken: string;
41
+ }): Promise<{
42
+ field: 'parent' | string;
43
+ style: 'next-gen' | 'classic';
44
+ }>;
45
+ /** Clear caches (for testing) */
46
+ export declare function clearFieldDiscoveryCache(): void;
47
+ //# sourceMappingURL=jira-field-discovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jira-field-discovery.d.ts","sourceRoot":"","sources":["../../../../plugins/specweave-jira/lib/jira-field-discovery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAWH;;;;;GAKG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACxC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAgCxB;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACxC,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CA+BjC;AAED;;;;;;GAMG;AACH,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACxC,OAAO,CAAC;IAAE,KAAK,EAAE,QAAQ,GAAG,MAAM,CAAC;IAAC,KAAK,EAAE,UAAU,GAAG,SAAS,CAAA;CAAE,CAAC,CAetE;AAED,iCAAiC;AACjC,wBAAgB,wBAAwB,IAAI,IAAI,CAG/C"}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * JIRA Field Discovery
3
+ *
4
+ * Dynamically discovers custom field IDs (e.g., Epic Link) and
5
+ * detects project style (Next-gen vs Classic).
6
+ *
7
+ * Results are cached per domain/project to avoid repeated lookups.
8
+ *
9
+ * @module jira-field-discovery
10
+ */
11
+ import axios from 'axios';
12
+ import { getApiBaseUrl } from './jira-deployment-detector.js';
13
+ /** Cache: domain → epic link field ID */
14
+ const epicLinkFieldCache = new Map();
15
+ /** Cache: projectKey → project style */
16
+ const projectStyleCache = new Map();
17
+ /**
18
+ * Discover the Epic Link custom field ID by querying /rest/api/field.
19
+ * Searches for fields with name "Epic Link" or schema type "com.pyxis.greenhopper.jira:gh-epic-link".
20
+ *
21
+ * @returns The custom field ID (e.g., "customfield_10014") or null if not found
22
+ */
23
+ export async function discoverEpicLinkField(domain, auth) {
24
+ // Check cache
25
+ const cached = epicLinkFieldCache.get(domain);
26
+ if (cached !== undefined)
27
+ return cached;
28
+ try {
29
+ const baseUrl = getApiBaseUrl(domain);
30
+ const response = await axios.get(`${baseUrl}/field`, {
31
+ auth: {
32
+ username: auth.email,
33
+ password: auth.apiToken,
34
+ },
35
+ headers: { Accept: 'application/json' },
36
+ timeout: 10000,
37
+ });
38
+ const fields = response.data;
39
+ // Find Epic Link field by name or schema
40
+ const epicLinkField = fields.find((f) => f.name === 'Epic Link' ||
41
+ f.schema?.custom === 'com.pyxis.greenhopper.jira:gh-epic-link');
42
+ const fieldId = epicLinkField?.id || null;
43
+ epicLinkFieldCache.set(domain, fieldId);
44
+ return fieldId;
45
+ }
46
+ catch {
47
+ epicLinkFieldCache.set(domain, null);
48
+ return null;
49
+ }
50
+ }
51
+ /**
52
+ * Detect whether a JIRA project uses Next-gen (Team-managed) or Classic (Company-managed) style.
53
+ *
54
+ * Next-gen projects use `parent` field for epic linking.
55
+ * Classic projects use a custom field (Epic Link).
56
+ */
57
+ export async function detectProjectStyle(domain, projectKey, auth) {
58
+ const cacheKey = `${domain}:${projectKey}`;
59
+ const cached = projectStyleCache.get(cacheKey);
60
+ if (cached)
61
+ return cached;
62
+ try {
63
+ const baseUrl = getApiBaseUrl(domain);
64
+ const response = await axios.get(`${baseUrl}/project/${projectKey}`, {
65
+ auth: {
66
+ username: auth.email,
67
+ password: auth.apiToken,
68
+ },
69
+ headers: { Accept: 'application/json' },
70
+ timeout: 10000,
71
+ });
72
+ const project = response.data;
73
+ // Next-gen projects have style: "next-gen" or projectTypeKey: "software" with simplified: true
74
+ const isNextGen = project.style === 'next-gen' ||
75
+ project.simplified === true;
76
+ const style = isNextGen ? 'next-gen' : 'classic';
77
+ projectStyleCache.set(cacheKey, style);
78
+ return style;
79
+ }
80
+ catch {
81
+ // Default to classic if detection fails
82
+ projectStyleCache.set(cacheKey, 'classic');
83
+ return 'classic';
84
+ }
85
+ }
86
+ /**
87
+ * Get the correct field name/ID for linking an issue to an epic,
88
+ * based on project style.
89
+ *
90
+ * - Next-gen: uses `parent` field
91
+ * - Classic: uses the discovered Epic Link custom field ID
92
+ */
93
+ export async function getEpicLinkFieldForProject(domain, projectKey, auth) {
94
+ const style = await detectProjectStyle(domain, projectKey, auth);
95
+ if (style === 'next-gen') {
96
+ return { field: 'parent', style };
97
+ }
98
+ const epicLinkFieldId = await discoverEpicLinkField(domain, auth);
99
+ if (!epicLinkFieldId) {
100
+ throw new Error(`Could not discover Epic Link custom field for ${domain}. ` +
101
+ `Ensure the JIRA instance has the Epic Link field and API credentials have field read access.`);
102
+ }
103
+ return { field: epicLinkFieldId, style };
104
+ }
105
+ /** Clear caches (for testing) */
106
+ export function clearFieldDiscoveryCache() {
107
+ epicLinkFieldCache.clear();
108
+ projectStyleCache.clear();
109
+ }
110
+ //# sourceMappingURL=jira-field-discovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jira-field-discovery.js","sourceRoot":"","sources":["../../../../plugins/specweave-jira/lib/jira-field-discovery.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * JIRA Paginated Search with Rate-Limit Retry
3
+ *
4
+ * Provides a paginated JQL search that fetches all results
5
+ * by iterating through pages using startAt/maxResults.
6
+ *
7
+ * Includes exponential backoff retry on HTTP 429 (rate limit).
8
+ *
9
+ * @module jira-paginated-search
10
+ */
11
+ import { AxiosInstance } from 'axios';
12
+ export interface PaginatedSearchOptions {
13
+ jql: string;
14
+ fields?: string;
15
+ maxResults?: number;
16
+ }
17
+ /**
18
+ * Search all issues matching a JQL query with full pagination.
19
+ * Handles rate limiting with exponential backoff.
20
+ *
21
+ * @param client - Axios instance configured with JIRA auth
22
+ * @param options - Search options (jql, fields, maxResults per page)
23
+ * @returns All matching issues across all pages
24
+ */
25
+ export declare function searchAllIssues(client: AxiosInstance, options: PaginatedSearchOptions): Promise<any[]>;
26
+ //# sourceMappingURL=jira-paginated-search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jira-paginated-search.d.ts","sourceRoot":"","sources":["../../../../plugins/specweave-jira/lib/jira-paginated-search.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAc,EAAE,aAAa,EAAc,MAAM,OAAO,CAAC;AAMzD,MAAM,WAAW,sBAAsB;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,GAAG,EAAE,CAAC,CA4BhB"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * JIRA Paginated Search with Rate-Limit Retry
3
+ *
4
+ * Provides a paginated JQL search that fetches all results
5
+ * by iterating through pages using startAt/maxResults.
6
+ *
7
+ * Includes exponential backoff retry on HTTP 429 (rate limit).
8
+ *
9
+ * @module jira-paginated-search
10
+ */
11
+ const DEFAULT_PAGE_SIZE = 50;
12
+ const MAX_RETRIES = 3;
13
+ const BASE_DELAY_MS = 1000;
14
+ /**
15
+ * Search all issues matching a JQL query with full pagination.
16
+ * Handles rate limiting with exponential backoff.
17
+ *
18
+ * @param client - Axios instance configured with JIRA auth
19
+ * @param options - Search options (jql, fields, maxResults per page)
20
+ * @returns All matching issues across all pages
21
+ */
22
+ export async function searchAllIssues(client, options) {
23
+ const { jql, fields, maxResults = DEFAULT_PAGE_SIZE } = options;
24
+ const allIssues = [];
25
+ let startAt = 0;
26
+ let total = Infinity;
27
+ while (startAt < total) {
28
+ const response = await requestWithRetry(client, '/search', {
29
+ params: {
30
+ jql,
31
+ startAt,
32
+ maxResults,
33
+ ...(fields ? { fields } : {}),
34
+ },
35
+ });
36
+ const data = response.data;
37
+ total = data.total;
38
+ const issues = data.issues || [];
39
+ allIssues.push(...issues);
40
+ startAt += issues.length;
41
+ // Safety: if no issues returned, break to avoid infinite loop
42
+ if (issues.length === 0)
43
+ break;
44
+ }
45
+ return allIssues;
46
+ }
47
+ /**
48
+ * Make an HTTP GET request with exponential backoff retry on 429.
49
+ */
50
+ async function requestWithRetry(client, url, config, attempt = 0) {
51
+ try {
52
+ return await client.get(url, config);
53
+ }
54
+ catch (error) {
55
+ const axiosError = error;
56
+ const status = axiosError.response?.status;
57
+ if (status === 429 && attempt < MAX_RETRIES) {
58
+ // Read Retry-After header (seconds) or use exponential backoff
59
+ const retryAfterHeader = axiosError.response?.headers?.['retry-after'];
60
+ const retryAfterMs = retryAfterHeader
61
+ ? parseInt(retryAfterHeader, 10) * 1000
62
+ : BASE_DELAY_MS * Math.pow(2, attempt);
63
+ console.warn(`Rate limited (429). Retry ${attempt + 1}/${MAX_RETRIES} after ${retryAfterMs}ms...`);
64
+ await sleep(retryAfterMs);
65
+ return requestWithRetry(client, url, config, attempt + 1);
66
+ }
67
+ if (status === 429) {
68
+ throw new Error(`JIRA rate limit exceeded after ${MAX_RETRIES} retries. ` +
69
+ `Try again later or reduce request frequency.`);
70
+ }
71
+ throw error;
72
+ }
73
+ }
74
+ function sleep(ms) {
75
+ return new Promise((resolve) => setTimeout(resolve, ms));
76
+ }
77
+ //# sourceMappingURL=jira-paginated-search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jira-paginated-search.js","sourceRoot":"","sources":["../../../../plugins/specweave-jira/lib/jira-paginated-search.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAC7B,MAAM,WAAW,GAAG,CAAC,CAAC;AACtB,MAAM,aAAa,GAAG,IAAI,CAAC;AAQ3B;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,MAAqB,EACrB,OAA+B;IAE/B,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,UAAU,GAAG,iBAAiB,EAAE,GAAG,OAAO,CAAC;IAChE,MAAM,SAAS,GAAU,EAAE,CAAC;IAC5B,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,KAAK,GAAG,QAAQ,CAAC;IAErB,OAAO,OAAO,GAAG,KAAK,EAAE,CAAC;QACvB,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC,MAAM,EAAE,SAAS,EAAE;YACzD,MAAM,EAAE;gBACN,GAAG;gBACH,OAAO;gBACP,UAAU;gBACV,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC9B;SACF,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;QAC3B,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACnB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;QACjC,SAAS,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;QAE1B,OAAO,IAAI,MAAM,CAAC,MAAM,CAAC;QAEzB,8DAA8D;QAC9D,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,MAAM;IACjC,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,gBAAgB,CAC7B,MAAqB,EACrB,GAAW,EACX,MAAW,EACX,UAAkB,CAAC;IAEnB,IAAI,CAAC;QACH,OAAO,MAAM,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACvC,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,MAAM,UAAU,GAAG,KAAmB,CAAC;QACvC,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC;QAE3C,IAAI,MAAM,KAAK,GAAG,IAAI,OAAO,GAAG,WAAW,EAAE,CAAC;YAC5C,+DAA+D;YAC/D,MAAM,gBAAgB,GAAG,UAAU,CAAC,QAAQ,EAAE,OAAO,EAAE,CAAC,aAAa,CAAC,CAAC;YACvE,MAAM,YAAY,GAAG,gBAAgB;gBACnC,CAAC,CAAC,QAAQ,CAAC,gBAAgB,EAAE,EAAE,CAAC,GAAG,IAAI;gBACvC,CAAC,CAAC,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YAEzC,OAAO,CAAC,IAAI,CACV,6BAA6B,OAAO,GAAG,CAAC,IAAI,WAAW,UAAU,YAAY,OAAO,CACrF,CAAC;YAEF,MAAM,KAAK,CAAC,YAAY,CAAC,CAAC;YAC1B,OAAO,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,GAAG,CAAC,CAAC,CAAC;QAC5D,CAAC;QAED,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CACb,kCAAkC,WAAW,YAAY;gBACzD,8CAA8C,CAC/C,CAAC;QACJ,CAAC;QAED,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"jira-spec-commit-sync.d.ts","sourceRoot":"","sources":["../../../../plugins/specweave-jira/lib/jira-spec-commit-sync.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAOL,SAAS,EACT,aAAa,EAEd,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAIL,SAAS,EACV,MAAM,6CAA6C,CAAC;AAYrD,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,WAAW,EAAE,SAAS,EAAE,CAAC;CAC1B;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,CAAC,CAiNrB;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,UAAU,EAClB,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,SAAS,EAAE,EACpB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,aAAa,EACnB,MAAM,GAAE,OAAe,GACtB,OAAO,CAAC,OAAO,CAAC,CAgDlB;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAC3C,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,OAAO,CAAC,CASlB;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAYxB"}
1
+ {"version":3,"file":"jira-spec-commit-sync.d.ts","sourceRoot":"","sources":["../../../../plugins/specweave-jira/lib/jira-spec-commit-sync.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAOL,SAAS,EACT,aAAa,EAEd,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAIL,SAAS,EACV,MAAM,6CAA6C,CAAC;AAcrD,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,WAAW,EAAE,SAAS,EAAE,CAAC;CAC1B;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,CAAC,CAiNrB;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,UAAU,EAClB,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,SAAS,EAAE,EACpB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,aAAa,EACnB,MAAM,GAAE,OAAe,GACtB,OAAO,CAAC,OAAO,CAAC,CAgDlB;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAC3C,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,OAAO,CAAC,CASlB;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAYxB"}
@@ -8,6 +8,8 @@ import axios from 'axios';
8
8
  import { getRecentCommits, detectRepository, getCommitUrl, findPRForCommit, getLastSyncCommit, updateLastSyncCommit, } from '../../../src/utils/git-utils.js';
9
9
  import { getSpecTaskMapping, getCompletedUserStories, } from '../../../src/core/specs/spec-task-mapper.js';
10
10
  import { buildUserStoryComment, buildCommitBatchComment, buildShortComment, generateSmartSummary, formatForJira, } from '../../../src/core/comment-builder.js';
11
+ import { readIssueKey } from './metadata-paths.js';
12
+ import { getApiBaseUrl } from './jira-deployment-detector.js';
11
13
  import path from 'path';
12
14
  import fs from 'fs/promises';
13
15
  /**
@@ -33,7 +35,7 @@ export async function syncSpecCommitsToJira(config, options) {
33
35
  result.errors.push('No metadata.json found');
34
36
  return result;
35
37
  }
36
- const jiraIssueKey = metadata.jira?.issueKey;
38
+ const jiraIssueKey = readIssueKey(metadata);
37
39
  if (!jiraIssueKey) {
38
40
  if (verbose) {
39
41
  console.log('No JIRA issue linked to increment');
@@ -42,7 +44,7 @@ export async function syncSpecCommitsToJira(config, options) {
42
44
  }
43
45
  // 2. Create JIRA client
44
46
  const client = axios.create({
45
- baseURL: `https://${config.domain}/rest/api/3`,
47
+ baseURL: getApiBaseUrl(config.domain),
46
48
  auth: {
47
49
  username: config.email,
48
50
  password: config.apiToken,
@@ -208,7 +210,7 @@ export async function syncSpecCommitsToJira(config, options) {
208
210
  export async function postCommitBatchUpdate(config, incrementPath, commits, issueKey, repo, dryRun = false) {
209
211
  try {
210
212
  const client = axios.create({
211
- baseURL: `https://${config.domain}/rest/api/3`,
213
+ baseURL: getApiBaseUrl(config.domain),
212
214
  auth: {
213
215
  username: config.email,
214
216
  password: config.apiToken,
@@ -1 +1 @@
1
- {"version":3,"file":"jira-spec-commit-sync.js","sourceRoot":"","sources":["../../../../plugins/specweave-jira/lib/jira-spec-commit-sync.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"jira-spec-commit-sync.js","sourceRoot":"","sources":["../../../../plugins/specweave-jira/lib/jira-spec-commit-sync.ts"],"names":[],"mappings":"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"}
@@ -13,11 +13,12 @@
13
13
  * @module jira-spec-sync
14
14
  */
15
15
  import { SpecSyncResult } from '../../../src/core/types/spec-metadata.js';
16
+ import { AdfDocument } from './content-format-adapter.js';
16
17
  export interface JiraEpic {
17
18
  id: string;
18
19
  key: string;
19
20
  summary: string;
20
- description: string;
21
+ description: string | AdfDocument;
21
22
  status: {
22
23
  name: string;
23
24
  };
@@ -45,6 +46,10 @@ export declare class JiraSpecSync {
45
46
  private client;
46
47
  private config;
47
48
  constructor(config: JiraConfig, projectRoot?: string);
49
+ /**
50
+ * Initialize: detect deployment type and update client baseURL
51
+ */
52
+ init(): Promise<void>;
48
53
  /**
49
54
  * Sync spec to Jira Epic (CREATE or UPDATE)
50
55
  */
@@ -78,9 +83,19 @@ export declare class JiraSpecSync {
78
83
  */
79
84
  private detectConflicts;
80
85
  /**
81
- * Resolve conflicts
86
+ * Resolve conflicts based on configurable strategy.
87
+ *
88
+ * Strategies:
89
+ * - 'manual' (default): Halt sync, report conflicts to user, no auto-resolve
90
+ * - 'remote-wins': Auto-resolve in favor of JIRA (remote)
91
+ * - 'local-wins': Auto-resolve in favor of spec (local)
92
+ * - 'report-only': Log conflicts, continue without resolving
82
93
  */
83
94
  private resolveConflicts;
95
+ /**
96
+ * Write conflict report JSON file for detected conflicts.
97
+ */
98
+ private writeConflictReport;
84
99
  /**
85
100
  * Fetch Jira Epic details
86
101
  */
@@ -1 +1 @@
1
- {"version":3,"file":"jira-spec-sync.d.ts","sourceRoot":"","sources":["../../../../plugins/specweave-jira/lib/jira-spec-sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,EAGL,cAAc,EAEf,MAAM,0CAA0C,CAAC;AAIlD,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,WAAW,CAAsB;IACzC,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,MAAM,CAAa;gBAEf,MAAM,EAAE,UAAU,EAAE,WAAW,GAAE,MAAsB;IAkBnE;;OAEG;IACG,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IA+D7D;;OAEG;IACG,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAsE3D;;OAEG;YACW,cAAc;IAoD5B;;OAEG;YACW,cAAc;IA6B5B;;OAEG;YACW,eAAe;IAmD7B;;OAEG;IACH,OAAO,CAAC,uBAAuB;IA8B/B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAqBhC;;OAEG;YACW,eAAe;IAwB7B;;OAEG;YACW,gBAAgB;IAiB9B;;OAEG;YACW,aAAa;IAc3B;;OAEG;YACW,gBAAgB;IAsB9B;;OAEG;YACW,WAAW;IAsDzB;;OAEG;YACW,WAAW;IAwBzB;;OAEG;YACW,eAAe;IAuB7B;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAiBzB;;;;OAIG;IACH,OAAO,CAAC,aAAa;CAgBtB"}
1
+ {"version":3,"file":"jira-spec-sync.d.ts","sourceRoot":"","sources":["../../../../plugins/specweave-jira/lib/jira-spec-sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAMH,OAAO,EAGL,cAAc,EAEf,MAAM,0CAA0C,CAAC;AAGlD,OAAO,EAAiB,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAKzE,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,GAAG,WAAW,CAAC;IAClC,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,WAAW,CAAsB;IACzC,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,MAAM,CAAa;gBAEf,MAAM,EAAE,UAAU,EAAE,WAAW,GAAE,MAAsB;IAkBnE;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ3B;;OAEG;IACG,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IA+D7D;;OAEG;IACG,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAyE3D;;OAEG;YACW,cAAc;IAoD5B;;OAEG;YACW,cAAc;IA6B5B;;OAEG;YACW,eAAe;IAmD7B;;OAEG;IACH,OAAO,CAAC,uBAAuB;IA8B/B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAqBhC;;OAEG;YACW,eAAe;IAwB7B;;;;;;;;OAQG;YACW,gBAAgB;IAqC9B;;OAEG;YACW,mBAAmB;IA+BjC;;OAEG;YACW,aAAa;IAc3B;;OAEG;YACW,gBAAgB;IAmB9B;;OAEG;YACW,WAAW;IAuDzB;;OAEG;YACW,WAAW;IAwBzB;;OAEG;YACW,eAAe;IAuB7B;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAiBzB;;;;OAIG;IACH,OAAO,CAAC,aAAa;CAgBtB"}
@@ -14,14 +14,20 @@
14
14
  */
15
15
  import { SpecMetadataManager } from '../../../src/core/specs/spec-metadata-manager.js';
16
16
  import { SpecParser } from '../../../src/core/specs/spec-parser.js';
17
+ import * as fs from 'fs/promises';
18
+ import * as path from 'path';
19
+ import { detectDeploymentType, getApiBaseUrl } from './jira-deployment-detector.js';
20
+ import { toDescription } from './content-format-adapter.js';
21
+ import { getEpicLinkFieldForProject } from './jira-field-discovery.js';
22
+ import { searchAllIssues } from './jira-paginated-search.js';
17
23
  import axios from 'axios';
18
24
  export class JiraSpecSync {
19
25
  constructor(config, projectRoot = process.cwd()) {
20
26
  this.specManager = new SpecMetadataManager(projectRoot);
21
27
  this.config = config;
22
- // Create Jira API client
28
+ // Create Jira API client — baseURL set dynamically via init()
23
29
  this.client = axios.create({
24
- baseURL: `https://${config.domain}/rest/api/3`,
30
+ baseURL: getApiBaseUrl(config.domain),
25
31
  auth: {
26
32
  username: config.email,
27
33
  password: config.apiToken
@@ -32,6 +38,16 @@ export class JiraSpecSync {
32
38
  }
33
39
  });
34
40
  }
41
+ /**
42
+ * Initialize: detect deployment type and update client baseURL
43
+ */
44
+ async init() {
45
+ const deployment = await detectDeploymentType(this.config.domain, {
46
+ email: this.config.email,
47
+ apiToken: this.config.apiToken,
48
+ });
49
+ this.client.defaults.baseURL = deployment.baseUrl;
50
+ }
35
51
  /**
36
52
  * Sync spec to Jira Epic (CREATE or UPDATE)
37
53
  */
@@ -131,7 +147,9 @@ export class JiraSpecSync {
131
147
  };
132
148
  }
133
149
  console.log(`⚠️ Detected ${conflicts.length} conflict(s)`);
134
- // 5. Resolve conflicts (Jira wins by default for now)
150
+ // 5. Write conflict report
151
+ await this.writeConflictReport(specId, conflicts);
152
+ // 6. Resolve conflicts using configurable strategy (default: manual)
135
153
  await this.resolveConflicts(spec, conflicts);
136
154
  console.log('✅ Sync FROM Jira complete!');
137
155
  return {
@@ -158,7 +176,7 @@ export class JiraSpecSync {
158
176
  */
159
177
  async createJiraEpic(spec) {
160
178
  const epicSummary = `[${spec.metadata.id.toUpperCase()}] ${spec.metadata.title}`;
161
- const epicDescription = this.generateEpicDescription(spec);
179
+ const epicDescription = toDescription(this.generateEpicDescription(spec), this.config.domain);
162
180
  // Determine issue type based on spec type (supports Bug for bug-type specs)
163
181
  const issueType = this.mapTypeToJira(spec.metadata.type, 'Epic');
164
182
  const payload = {
@@ -197,7 +215,7 @@ export class JiraSpecSync {
197
215
  */
198
216
  async updateJiraEpic(epicKey, spec) {
199
217
  const epicSummary = `[${spec.metadata.id.toUpperCase()}] ${spec.metadata.title}`;
200
- const epicDescription = this.generateEpicDescription(spec);
218
+ const epicDescription = toDescription(this.generateEpicDescription(spec), this.config.domain);
201
219
  const payload = {
202
220
  fields: {
203
221
  summary: epicSummary,
@@ -335,19 +353,69 @@ ${acList}
335
353
  return conflicts;
336
354
  }
337
355
  /**
338
- * Resolve conflicts
356
+ * Resolve conflicts based on configurable strategy.
357
+ *
358
+ * Strategies:
359
+ * - 'manual' (default): Halt sync, report conflicts to user, no auto-resolve
360
+ * - 'remote-wins': Auto-resolve in favor of JIRA (remote)
361
+ * - 'local-wins': Auto-resolve in favor of spec (local)
362
+ * - 'report-only': Log conflicts, continue without resolving
339
363
  */
340
- async resolveConflicts(spec, conflicts) {
364
+ async resolveConflicts(spec, conflicts, strategy = 'manual') {
365
+ if (strategy === 'manual') {
366
+ console.log(` ⚠️ ${conflicts.length} conflict(s) require manual resolution.`);
367
+ for (const conflict of conflicts) {
368
+ console.log(` - ${conflict.field}: local="${conflict.localValue}" vs remote="${conflict.remoteValue}"`);
369
+ }
370
+ console.log(` Sync halted. Review conflicts and resolve manually.`);
371
+ return;
372
+ }
373
+ if (strategy === 'report-only') {
374
+ console.log(` ℹ️ ${conflicts.length} conflict(s) detected (report-only mode):`);
375
+ for (const conflict of conflicts) {
376
+ console.log(` - ${conflict.field}: local="${conflict.localValue}" vs remote="${conflict.remoteValue}"`);
377
+ }
378
+ return;
379
+ }
341
380
  for (const conflict of conflicts) {
342
- if (conflict.resolution === 'remote-wins') {
381
+ if (strategy === 'remote-wins') {
343
382
  console.log(` 🔄 Resolving: ${conflict.description} (Jira wins)`);
344
- // Update spec metadata from Jira
345
383
  if (conflict.field === 'title') {
346
384
  await this.specManager.saveMetadata(spec.metadata.id, {
347
385
  title: conflict.remoteValue
348
386
  });
349
387
  }
350
388
  }
389
+ else if (strategy === 'local-wins') {
390
+ console.log(` 🔄 Resolving: ${conflict.description} (local wins — no remote update)`);
391
+ // Local wins: keep spec as-is, no action needed
392
+ }
393
+ }
394
+ }
395
+ /**
396
+ * Write conflict report JSON file for detected conflicts.
397
+ */
398
+ async writeConflictReport(specId, conflicts) {
399
+ try {
400
+ const report = {
401
+ specId,
402
+ provider: 'jira',
403
+ timestamp: new Date().toISOString(),
404
+ conflicts: conflicts.map((c) => ({
405
+ field: c.field,
406
+ localValue: c.localValue,
407
+ remoteValue: c.remoteValue,
408
+ description: c.description,
409
+ })),
410
+ };
411
+ const reportsDir = path.join(this.specManager.projectRoot || process.cwd(), '.specweave', 'reports');
412
+ await fs.mkdir(reportsDir, { recursive: true });
413
+ const reportPath = path.join(reportsDir, 'conflict-report.json');
414
+ await fs.writeFile(reportPath, JSON.stringify(report, null, 2));
415
+ console.log(` 📄 Conflict report written to ${reportPath}`);
416
+ }
417
+ catch (err) {
418
+ console.warn(' ⚠️ Failed to write conflict report:', err.message);
351
419
  }
352
420
  }
353
421
  /**
@@ -370,14 +438,11 @@ ${acList}
370
438
  */
371
439
  async findStoryByTitle(usId) {
372
440
  const jql = `project = ${this.config.projectKey} AND summary ~ "[${usId}]" AND issuetype = Story`;
373
- const response = await this.client.get('/search', {
374
- params: {
375
- jql,
376
- maxResults: 1,
377
- fields: 'summary,description,status,labels'
378
- }
441
+ const issues = await searchAllIssues(this.client, {
442
+ jql,
443
+ fields: 'summary,description,status,labels',
444
+ maxResults: 1,
379
445
  });
380
- const issues = response.data.issues;
381
446
  return issues.length > 0 ? {
382
447
  id: issues[0].id,
383
448
  key: issues[0].key,
@@ -393,25 +458,30 @@ ${acList}
393
458
  async createStory(story) {
394
459
  // Determine issue type (supports Bug for bug-type stories)
395
460
  const issueType = this.mapTypeToJira(story.type, 'Story');
396
- const payload = {
397
- fields: {
398
- project: {
399
- key: this.config.projectKey
400
- },
401
- summary: story.summary,
402
- description: story.description,
403
- issuetype: {
404
- name: issueType
405
- },
406
- labels: story.labels,
407
- // Link to epic (field name may vary by Jira configuration)
408
- customfield_10014: story.epicLink, // Epic Link field (adjust if needed)
409
- // Set native JIRA priority field
410
- priority: {
411
- name: this.mapPriorityToJira(story.priority)
412
- }
461
+ // Discover epic link field dynamically based on project style
462
+ const { field: epicField, style } = await getEpicLinkFieldForProject(this.config.domain, this.config.projectKey, { email: this.config.email, apiToken: this.config.apiToken });
463
+ const fields = {
464
+ project: {
465
+ key: this.config.projectKey
466
+ },
467
+ summary: story.summary,
468
+ description: story.description,
469
+ issuetype: {
470
+ name: issueType
471
+ },
472
+ labels: story.labels,
473
+ priority: {
474
+ name: this.mapPriorityToJira(story.priority)
413
475
  }
414
476
  };
477
+ // Link to epic using the correct field for project style
478
+ if (style === 'next-gen') {
479
+ fields.parent = { key: story.epicLink };
480
+ }
481
+ else {
482
+ fields[epicField] = story.epicLink;
483
+ }
484
+ const payload = { fields };
415
485
  const response = await this.client.post('/issue', payload);
416
486
  const storyData = response.data;
417
487
  return {