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.
- package/bin/specweave.js +9 -0
- package/dist/plugins/specweave-ado/lib/ado-client-v2.d.ts +5 -0
- package/dist/plugins/specweave-ado/lib/ado-client-v2.d.ts.map +1 -1
- package/dist/plugins/specweave-ado/lib/ado-client-v2.js +61 -23
- package/dist/plugins/specweave-ado/lib/ado-client-v2.js.map +1 -1
- package/dist/plugins/specweave-ado/lib/ado-duplicate-detector.d.ts.map +1 -1
- package/dist/plugins/specweave-ado/lib/ado-duplicate-detector.js +3 -2
- package/dist/plugins/specweave-ado/lib/ado-duplicate-detector.js.map +1 -1
- package/dist/plugins/specweave-ado/lib/ado-profile-resolver.d.ts.map +1 -1
- package/dist/plugins/specweave-ado/lib/ado-profile-resolver.js +2 -1
- package/dist/plugins/specweave-ado/lib/ado-profile-resolver.js.map +1 -1
- package/dist/plugins/specweave-ado/lib/ado-spec-sync.d.ts +1 -1
- package/dist/plugins/specweave-ado/lib/ado-spec-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-ado/lib/ado-spec-sync.js +25 -9
- package/dist/plugins/specweave-ado/lib/ado-spec-sync.js.map +1 -1
- package/dist/plugins/specweave-ado/lib/conflict-resolver.d.ts.map +1 -1
- package/dist/plugins/specweave-ado/lib/conflict-resolver.js +17 -1
- package/dist/plugins/specweave-ado/lib/conflict-resolver.js.map +1 -1
- package/dist/plugins/specweave-ado/lib/per-us-sync.d.ts +3 -0
- package/dist/plugins/specweave-ado/lib/per-us-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-ado/lib/per-us-sync.js +14 -1
- package/dist/plugins/specweave-ado/lib/per-us-sync.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-client-v2.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-client-v2.js +10 -7
- package/dist/plugins/specweave-github/lib/github-client-v2.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-client.d.ts +1 -1
- package/dist/plugins/specweave-github/lib/github-client.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-client.js +7 -5
- package/dist/plugins/specweave-github/lib/github-client.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-cross-repo-sync.js +13 -3
- package/dist/plugins/specweave-github/lib/github-cross-repo-sync.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-feature-sync-cli.d.ts +24 -1
- package/dist/plugins/specweave-github/lib/github-feature-sync-cli.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-feature-sync-cli.js +36 -20
- package/dist/plugins/specweave-github/lib/github-feature-sync-cli.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-graphql-client.d.ts +1 -0
- package/dist/plugins/specweave-github/lib/github-graphql-client.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-graphql-client.js +32 -22
- package/dist/plugins/specweave-github/lib/github-graphql-client.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-spec-frontmatter-updater.js +144 -8
- package/dist/plugins/specweave-github/lib/github-spec-frontmatter-updater.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-spec-sync.d.ts +8 -1
- package/dist/plugins/specweave-github/lib/github-spec-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-spec-sync.js +94 -24
- package/dist/plugins/specweave-github/lib/github-spec-sync.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-sync-orchestrator.d.ts +1 -0
- package/dist/plugins/specweave-github/lib/github-sync-orchestrator.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-sync-orchestrator.js +2 -1
- package/dist/plugins/specweave-github/lib/github-sync-orchestrator.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-us-auto-closer.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-us-auto-closer.js +25 -0
- package/dist/plugins/specweave-github/lib/github-us-auto-closer.js.map +1 -1
- package/dist/plugins/specweave-github/lib/per-us-sync.d.ts +3 -0
- package/dist/plugins/specweave-github/lib/per-us-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/per-us-sync.js +29 -9
- package/dist/plugins/specweave-github/lib/per-us-sync.js.map +1 -1
- package/dist/plugins/specweave-jira/lib/content-format-adapter.d.ts +59 -0
- package/dist/plugins/specweave-jira/lib/content-format-adapter.d.ts.map +1 -0
- package/dist/plugins/specweave-jira/lib/content-format-adapter.js +159 -0
- package/dist/plugins/specweave-jira/lib/content-format-adapter.js.map +1 -0
- package/dist/plugins/specweave-jira/lib/jira-deployment-detector.d.ts +45 -0
- package/dist/plugins/specweave-jira/lib/jira-deployment-detector.d.ts.map +1 -0
- package/dist/plugins/specweave-jira/lib/jira-deployment-detector.js +92 -0
- package/dist/plugins/specweave-jira/lib/jira-deployment-detector.js.map +1 -0
- package/dist/plugins/specweave-jira/lib/jira-duplicate-detector.d.ts.map +1 -1
- package/dist/plugins/specweave-jira/lib/jira-duplicate-detector.js +13 -28
- package/dist/plugins/specweave-jira/lib/jira-duplicate-detector.js.map +1 -1
- package/dist/plugins/specweave-jira/lib/jira-epic-sync.d.ts +2 -1
- package/dist/plugins/specweave-jira/lib/jira-epic-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-jira/lib/jira-epic-sync.js +19 -7
- package/dist/plugins/specweave-jira/lib/jira-epic-sync.js.map +1 -1
- package/dist/plugins/specweave-jira/lib/jira-field-discovery.d.ts +47 -0
- package/dist/plugins/specweave-jira/lib/jira-field-discovery.d.ts.map +1 -0
- package/dist/plugins/specweave-jira/lib/jira-field-discovery.js +110 -0
- package/dist/plugins/specweave-jira/lib/jira-field-discovery.js.map +1 -0
- package/dist/plugins/specweave-jira/lib/jira-paginated-search.d.ts +26 -0
- package/dist/plugins/specweave-jira/lib/jira-paginated-search.d.ts.map +1 -0
- package/dist/plugins/specweave-jira/lib/jira-paginated-search.js +77 -0
- package/dist/plugins/specweave-jira/lib/jira-paginated-search.js.map +1 -0
- package/dist/plugins/specweave-jira/lib/jira-spec-commit-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-jira/lib/jira-spec-commit-sync.js +5 -3
- package/dist/plugins/specweave-jira/lib/jira-spec-commit-sync.js.map +1 -1
- package/dist/plugins/specweave-jira/lib/jira-spec-sync.d.ts +17 -2
- package/dist/plugins/specweave-jira/lib/jira-spec-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-jira/lib/jira-spec-sync.js +103 -33
- package/dist/plugins/specweave-jira/lib/jira-spec-sync.js.map +1 -1
- package/dist/plugins/specweave-jira/lib/jira-status-sync.d.ts +4 -0
- package/dist/plugins/specweave-jira/lib/jira-status-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-jira/lib/jira-status-sync.js +19 -6
- package/dist/plugins/specweave-jira/lib/jira-status-sync.js.map +1 -1
- package/dist/plugins/specweave-jira/lib/metadata-paths.d.ts +29 -0
- package/dist/plugins/specweave-jira/lib/metadata-paths.d.ts.map +1 -0
- package/dist/plugins/specweave-jira/lib/metadata-paths.js +73 -0
- package/dist/plugins/specweave-jira/lib/metadata-paths.js.map +1 -0
- package/dist/plugins/specweave-jira/lib/reorganization-detector.d.ts +15 -2
- package/dist/plugins/specweave-jira/lib/reorganization-detector.d.ts.map +1 -1
- package/dist/plugins/specweave-jira/lib/reorganization-detector.js +121 -33
- package/dist/plugins/specweave-jira/lib/reorganization-detector.js.map +1 -1
- package/dist/src/cli/commands/sync-progress.d.ts +6 -0
- package/dist/src/cli/commands/sync-progress.d.ts.map +1 -1
- package/dist/src/cli/commands/sync-progress.js +37 -0
- package/dist/src/cli/commands/sync-progress.js.map +1 -1
- package/dist/src/cli/commands/sync-task.d.ts +16 -0
- package/dist/src/cli/commands/sync-task.d.ts.map +1 -0
- package/dist/src/cli/commands/sync-task.js +42 -0
- package/dist/src/cli/commands/sync-task.js.map +1 -0
- package/dist/src/core/hooks/LifecycleHookDispatcher.d.ts +9 -1
- package/dist/src/core/hooks/LifecycleHookDispatcher.d.ts.map +1 -1
- package/dist/src/core/hooks/LifecycleHookDispatcher.js +26 -8
- package/dist/src/core/hooks/LifecycleHookDispatcher.js.map +1 -1
- package/dist/src/core/increment/metadata-manager.d.ts.map +1 -1
- package/dist/src/core/increment/metadata-manager.js +26 -0
- package/dist/src/core/increment/metadata-manager.js.map +1 -1
- package/dist/src/core/increment/status-commands.d.ts.map +1 -1
- package/dist/src/core/increment/status-commands.js +33 -11
- package/dist/src/core/increment/status-commands.js.map +1 -1
- package/dist/src/locales/de/cli.json +245 -77
- package/dist/src/locales/es/cli.json +238 -3
- package/dist/src/locales/fr/cli.json +254 -86
- package/dist/src/locales/ja/cli.json +246 -78
- package/dist/src/locales/ko/cli.json +246 -78
- package/dist/src/locales/pt/cli.json +245 -77
- package/dist/src/locales/zh/cli.json +251 -83
- package/dist/src/sync/github-reconciler.d.ts +30 -0
- package/dist/src/sync/github-reconciler.d.ts.map +1 -1
- package/dist/src/sync/github-reconciler.js +235 -1
- package/dist/src/sync/github-reconciler.js.map +1 -1
- package/package.json +1 -1
- package/plugins/specweave/hooks/v2/guards/task-ac-sync-guard.sh +31 -0
- package/plugins/specweave/lib/vendor/core/increment/metadata-manager.js +26 -0
- package/plugins/specweave/lib/vendor/core/increment/metadata-manager.js.map +1 -1
- package/plugins/specweave/lib/vendor/sync/github-reconciler.d.ts +30 -0
- package/plugins/specweave/lib/vendor/sync/github-reconciler.js +235 -1
- package/plugins/specweave/lib/vendor/sync/github-reconciler.js.map +1 -1
- package/plugins/specweave/skills/team-lead/agents/security.md +0 -1
- package/plugins/specweave-ado/hooks/post-task-completion.sh +2 -2
- package/plugins/specweave-ado/lib/ado-client-v2.js +51 -21
- package/plugins/specweave-ado/lib/ado-client-v2.ts +62 -23
- package/plugins/specweave-ado/lib/ado-duplicate-detector.js +4 -4
- package/plugins/specweave-ado/lib/ado-duplicate-detector.ts +4 -3
- package/plugins/specweave-ado/lib/ado-hierarchical-sync.js +54 -12
- package/plugins/specweave-ado/lib/ado-hierarchical-sync.ts +88 -18
- package/plugins/specweave-ado/lib/ado-profile-resolver.js +1 -1
- package/plugins/specweave-ado/lib/ado-profile-resolver.ts +3 -1
- package/plugins/specweave-ado/lib/ado-spec-sync.js +22 -9
- package/plugins/specweave-ado/lib/ado-spec-sync.ts +27 -9
- package/plugins/specweave-ado/lib/conflict-resolver.js +17 -1
- package/plugins/specweave-ado/lib/conflict-resolver.ts +17 -1
- package/plugins/specweave-ado/lib/enhanced-ado-sync.js +11 -1
- package/plugins/specweave-ado/lib/per-us-sync.js +8 -1
- package/plugins/specweave-ado/lib/per-us-sync.ts +17 -2
- package/plugins/specweave-github/hooks/github-auto-create-handler.sh +28 -2
- package/plugins/specweave-github/hooks/post-task-completion.sh +6 -3
- package/plugins/specweave-github/lib/enhanced-github-sync.js +35 -6
- package/plugins/specweave-github/lib/github-board-resolver.js +4 -4
- package/plugins/specweave-github/lib/github-board-resolver.ts +4 -4
- package/plugins/specweave-github/lib/github-client-v2.js +6 -6
- package/plugins/specweave-github/lib/github-client-v2.ts +11 -7
- package/plugins/specweave-github/lib/github-client.js +5 -4
- package/plugins/specweave-github/lib/github-client.ts +7 -5
- package/plugins/specweave-github/lib/github-cross-repo-sync.js +17 -3
- package/plugins/specweave-github/lib/github-cross-repo-sync.ts +16 -3
- package/plugins/specweave-github/lib/github-feature-sync-cli.js +20 -11
- package/plugins/specweave-github/lib/github-feature-sync-cli.ts +42 -20
- package/plugins/specweave-github/lib/github-graphql-client.js +29 -20
- package/plugins/specweave-github/lib/github-graphql-client.ts +34 -22
- package/plugins/specweave-github/lib/github-hierarchical-sync.js +2 -2
- package/plugins/specweave-github/lib/github-hierarchical-sync.ts +2 -2
- package/plugins/specweave-github/lib/github-multi-project-sync.js +23 -7
- package/plugins/specweave-github/lib/github-multi-project-sync.ts +26 -8
- package/plugins/specweave-github/lib/github-spec-frontmatter-updater.js +110 -5
- package/plugins/specweave-github/lib/github-spec-frontmatter-updater.ts +135 -9
- package/plugins/specweave-github/lib/github-spec-sync.js +85 -24
- package/plugins/specweave-github/lib/github-spec-sync.ts +100 -26
- package/plugins/specweave-github/lib/github-sync-orchestrator.js +2 -1
- package/plugins/specweave-github/lib/github-sync-orchestrator.ts +3 -1
- package/plugins/specweave-github/lib/github-us-auto-closer.js +25 -0
- package/plugins/specweave-github/lib/github-us-auto-closer.ts +43 -0
- package/plugins/specweave-github/lib/per-us-sync.js +26 -11
- package/plugins/specweave-github/lib/per-us-sync.ts +29 -11
- package/plugins/specweave-jira/hooks/post-task-completion.sh +2 -1
- package/plugins/specweave-jira/lib/content-format-adapter.js +116 -0
- package/plugins/specweave-jira/lib/content-format-adapter.ts +189 -0
- package/plugins/specweave-jira/lib/enhanced-jira-sync.js +21 -5
- package/plugins/specweave-jira/lib/jira-deployment-detector.js +63 -0
- package/plugins/specweave-jira/lib/jira-deployment-detector.ts +113 -0
- package/plugins/specweave-jira/lib/jira-duplicate-detector.js +12 -29
- package/plugins/specweave-jira/lib/jira-duplicate-detector.ts +13 -27
- package/plugins/specweave-jira/lib/jira-epic-sync.js +15 -5
- package/plugins/specweave-jira/lib/jira-epic-sync.ts +22 -7
- package/plugins/specweave-jira/lib/jira-field-discovery.js +76 -0
- package/plugins/specweave-jira/lib/jira-field-discovery.ts +139 -0
- package/plugins/specweave-jira/lib/jira-hierarchical-sync.js +10 -0
- package/plugins/specweave-jira/lib/jira-hierarchical-sync.ts +11 -0
- package/plugins/specweave-jira/lib/jira-multi-project-sync.js +19 -9
- package/plugins/specweave-jira/lib/jira-multi-project-sync.ts +25 -14
- package/plugins/specweave-jira/lib/jira-paginated-search.js +55 -0
- package/plugins/specweave-jira/lib/jira-paginated-search.ts +108 -0
- package/plugins/specweave-jira/lib/jira-spec-commit-sync.js +5 -3
- package/plugins/specweave-jira/lib/jira-spec-commit-sync.ts +5 -3
- package/plugins/specweave-jira/lib/jira-spec-sync.js +102 -31
- package/plugins/specweave-jira/lib/jira-spec-sync.ts +123 -45
- package/plugins/specweave-jira/lib/jira-status-sync.js +18 -5
- package/plugins/specweave-jira/lib/jira-status-sync.ts +21 -6
- package/plugins/specweave-jira/lib/metadata-paths.js +38 -0
- package/plugins/specweave-jira/lib/metadata-paths.ts +73 -0
- package/plugins/specweave-jira/lib/reorganization-detector.js +101 -23
- package/plugins/specweave-jira/lib/reorganization-detector.ts +125 -35
- package/plugins/specweave-jira/scripts/refresh-cache.js +1 -1
- package/plugins/specweave-jira/scripts/refresh-cache.ts +2 -2
- 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;
|
|
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
|
|
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:
|
|
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:
|
|
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":"AAAA;;;;;GAKG;AAEH,OAAO,KAAwB,MAAM,OAAO,CAAC;AAC7C,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,eAAe,EACf,iBAAiB,EACjB,oBAAoB,GAIrB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,kBAAkB,EAClB,uBAAuB,GAGxB,MAAM,6CAA6C,CAAC;AACrD,OAAO,EACL,qBAAqB,EACrB,uBAAuB,EACvB,iBAAiB,EACjB,oBAAoB,EACpB,aAAa,GAEd,MAAM,sCAAsC,CAAC;AAC9C,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,aAAa,CAAC;AAuB7B;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,MAAkB,EAClB,OAAoB;IAEpB,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,KAAK,EAAE,OAAO,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC;IAEnE,MAAM,MAAM,GAAe;QACzB,OAAO,EAAE,IAAI;QACb,cAAc,EAAE,CAAC;QACjB,MAAM,EAAE,EAAE;QACV,OAAO,EAAE,EAAE;QACX,WAAW,EAAE,EAAE;KAChB,CAAC;IAEF,IAAI,CAAC;QACH,8CAA8C;QAC9C,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,eAAe,CAAC,CAAC;QAC/D,IAAI,QAAa,CAAC;QAElB,IAAI,CAAC;YACH,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC;QAClE,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;YAC7C,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,MAAM,YAAY,GAAG,
|
|
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;
|
|
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:
|
|
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.
|
|
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 (
|
|
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
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
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
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
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 {
|