specweave 0.23.10 → 0.23.12

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 (102) hide show
  1. package/.claude-plugin/marketplace.json +7 -7
  2. package/CLAUDE.md +384 -1449
  3. package/dist/src/cli/commands/cleanup-cache.d.ts +14 -0
  4. package/dist/src/cli/commands/cleanup-cache.d.ts.map +1 -0
  5. package/dist/src/cli/commands/cleanup-cache.js +63 -0
  6. package/dist/src/cli/commands/cleanup-cache.js.map +1 -0
  7. package/dist/src/cli/commands/init.js +40 -0
  8. package/dist/src/cli/commands/init.js.map +1 -1
  9. package/dist/src/cli/helpers/async-project-loader.d.ts +148 -0
  10. package/dist/src/cli/helpers/async-project-loader.d.ts.map +1 -0
  11. package/dist/src/cli/helpers/async-project-loader.js +351 -0
  12. package/dist/src/cli/helpers/async-project-loader.js.map +1 -0
  13. package/dist/src/cli/helpers/cancelation-handler.d.ts +123 -0
  14. package/dist/src/cli/helpers/cancelation-handler.d.ts.map +1 -0
  15. package/dist/src/cli/helpers/cancelation-handler.js +187 -0
  16. package/dist/src/cli/helpers/cancelation-handler.js.map +1 -0
  17. package/dist/src/cli/helpers/import-strategy-prompter.d.ts +43 -0
  18. package/dist/src/cli/helpers/import-strategy-prompter.d.ts.map +1 -0
  19. package/dist/src/cli/helpers/import-strategy-prompter.js +136 -0
  20. package/dist/src/cli/helpers/import-strategy-prompter.js.map +1 -0
  21. package/dist/src/cli/helpers/issue-tracker/ado.d.ts +5 -2
  22. package/dist/src/cli/helpers/issue-tracker/ado.d.ts.map +1 -1
  23. package/dist/src/cli/helpers/issue-tracker/ado.js +90 -40
  24. package/dist/src/cli/helpers/issue-tracker/ado.js.map +1 -1
  25. package/dist/src/cli/helpers/issue-tracker/jira.d.ts +2 -1
  26. package/dist/src/cli/helpers/issue-tracker/jira.d.ts.map +1 -1
  27. package/dist/src/cli/helpers/issue-tracker/jira.js +120 -35
  28. package/dist/src/cli/helpers/issue-tracker/jira.js.map +1 -1
  29. package/dist/src/cli/helpers/progress-tracker.d.ts +121 -0
  30. package/dist/src/cli/helpers/progress-tracker.d.ts.map +1 -0
  31. package/dist/src/cli/helpers/progress-tracker.js +202 -0
  32. package/dist/src/cli/helpers/progress-tracker.js.map +1 -0
  33. package/dist/src/cli/helpers/project-count-fetcher.d.ts +69 -0
  34. package/dist/src/cli/helpers/project-count-fetcher.d.ts.map +1 -0
  35. package/dist/src/cli/helpers/project-count-fetcher.js +173 -0
  36. package/dist/src/cli/helpers/project-count-fetcher.js.map +1 -0
  37. package/dist/src/config/types.d.ts +14 -14
  38. package/dist/src/core/cache/cache-manager.d.ts +119 -0
  39. package/dist/src/core/cache/cache-manager.d.ts.map +1 -0
  40. package/dist/src/core/cache/cache-manager.js +304 -0
  41. package/dist/src/core/cache/cache-manager.js.map +1 -0
  42. package/dist/src/core/cache/rate-limit-checker.d.ts +92 -0
  43. package/dist/src/core/cache/rate-limit-checker.d.ts.map +1 -0
  44. package/dist/src/core/cache/rate-limit-checker.js +160 -0
  45. package/dist/src/core/cache/rate-limit-checker.js.map +1 -0
  46. package/dist/src/core/progress/cancelation-handler.d.ts +79 -0
  47. package/dist/src/core/progress/cancelation-handler.d.ts.map +1 -0
  48. package/dist/src/core/progress/cancelation-handler.js +111 -0
  49. package/dist/src/core/progress/cancelation-handler.js.map +1 -0
  50. package/dist/src/core/progress/import-state.d.ts +71 -0
  51. package/dist/src/core/progress/import-state.d.ts.map +1 -0
  52. package/dist/src/core/progress/import-state.js +96 -0
  53. package/dist/src/core/progress/import-state.js.map +1 -0
  54. package/dist/src/core/progress/progress-tracker.d.ts +139 -0
  55. package/dist/src/core/progress/progress-tracker.d.ts.map +1 -0
  56. package/dist/src/core/progress/progress-tracker.js +223 -0
  57. package/dist/src/core/progress/progress-tracker.js.map +1 -0
  58. package/dist/src/init/architecture/types.d.ts +6 -6
  59. package/dist/src/integrations/ado/ado-client.d.ts +25 -0
  60. package/dist/src/integrations/ado/ado-client.d.ts.map +1 -1
  61. package/dist/src/integrations/ado/ado-client.js +67 -0
  62. package/dist/src/integrations/ado/ado-client.js.map +1 -1
  63. package/dist/src/integrations/ado/ado-dependency-loader.d.ts +99 -0
  64. package/dist/src/integrations/ado/ado-dependency-loader.d.ts.map +1 -0
  65. package/dist/src/integrations/ado/ado-dependency-loader.js +207 -0
  66. package/dist/src/integrations/ado/ado-dependency-loader.js.map +1 -0
  67. package/dist/src/integrations/jira/jira-client.d.ts +32 -0
  68. package/dist/src/integrations/jira/jira-client.d.ts.map +1 -1
  69. package/dist/src/integrations/jira/jira-client.js +81 -0
  70. package/dist/src/integrations/jira/jira-client.js.map +1 -1
  71. package/dist/src/integrations/jira/jira-dependency-loader.d.ts +101 -0
  72. package/dist/src/integrations/jira/jira-dependency-loader.d.ts.map +1 -0
  73. package/dist/src/integrations/jira/jira-dependency-loader.js +200 -0
  74. package/dist/src/integrations/jira/jira-dependency-loader.js.map +1 -0
  75. package/package.json +1 -1
  76. package/plugins/specweave/.claude-plugin/plugin.json +20 -0
  77. package/plugins/specweave/agents/architect/AGENT.md +100 -602
  78. package/plugins/specweave/agents/pm/AGENT.md +96 -597
  79. package/plugins/specweave/agents/pm/AGENT.md.bak +1893 -0
  80. package/plugins/specweave/agents/pm/AGENT.md.bak2 +1754 -0
  81. package/plugins/specweave/commands/check-hooks.md +257 -0
  82. package/plugins/specweave/hooks/post-edit-spec.sh +202 -31
  83. package/plugins/specweave/hooks/post-task-completion.sh +225 -228
  84. package/plugins/specweave/hooks/post-write-spec.sh +207 -31
  85. package/plugins/specweave/hooks/pre-edit-spec.sh +151 -0
  86. package/plugins/specweave/hooks/pre-task-completion.sh +5 -7
  87. package/plugins/specweave/hooks/pre-write-spec.sh +151 -0
  88. package/plugins/specweave/hooks/test-pretooluse-env.sh +72 -0
  89. package/plugins/specweave/skills/compliance-architecture/SKILL.md +374 -0
  90. package/plugins/specweave/skills/external-sync-wizard/SKILL.md +610 -0
  91. package/plugins/specweave/skills/pm-closure-validation/SKILL.md +541 -0
  92. package/plugins/specweave/skills/roadmap-planner/SKILL.md +473 -0
  93. package/plugins/specweave-ado/commands/refresh-cache.js +25 -0
  94. package/plugins/specweave-ado/commands/refresh-cache.ts +40 -0
  95. package/plugins/specweave-ado/hooks/post-task-completion.sh +1 -1
  96. package/plugins/specweave-github/hooks/post-task-completion.sh +1 -1
  97. package/plugins/specweave-jira/commands/refresh-cache.js +25 -0
  98. package/plugins/specweave-jira/commands/refresh-cache.ts +40 -0
  99. package/plugins/specweave-jira/hooks/post-task-completion.sh +1 -1
  100. package/plugins/specweave-kafka-streams/commands/topology.md +437 -0
  101. package/plugins/specweave-n8n/commands/workflow-template.md +262 -0
  102. package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +228 -6465
@@ -0,0 +1,148 @@
1
+ /**
2
+ * Async Project Loader
3
+ *
4
+ * Advanced batch fetching with:
5
+ * - Smart pagination (50-project batches)
6
+ * - Real-time progress tracking
7
+ * - Graceful cancelation (Ctrl+C)
8
+ * - Retry logic with exponential backoff
9
+ * - Rate limit handling
10
+ * - Graceful degradation (reduce batch size on timeout)
11
+ * - Continue-on-failure error handling
12
+ * - Comprehensive error logging
13
+ *
14
+ * @module cli/helpers/async-project-loader
15
+ */
16
+ import { Logger } from '../../utils/logger.js';
17
+ import type { JiraCredentials, AdoCredentials } from './project-count-fetcher.js';
18
+ /**
19
+ * Project provider type
20
+ */
21
+ export type ProjectProvider = 'jira' | 'ado';
22
+ /**
23
+ * Project metadata
24
+ */
25
+ export interface Project {
26
+ id: string;
27
+ key: string;
28
+ name: string;
29
+ projectTypeKey?: string;
30
+ simplified?: boolean;
31
+ }
32
+ /**
33
+ * Fetch options
34
+ */
35
+ export interface FetchOptions {
36
+ batchSize?: number;
37
+ updateFrequency?: number;
38
+ showEta?: boolean;
39
+ stateFile?: string;
40
+ errorLogFile?: string;
41
+ logger?: Logger;
42
+ }
43
+ /**
44
+ * Fetch result
45
+ */
46
+ export interface FetchResult {
47
+ projects: Project[];
48
+ succeeded: number;
49
+ failed: number;
50
+ skipped: number;
51
+ errors: FetchError[];
52
+ canceled?: boolean;
53
+ }
54
+ /**
55
+ * Fetch error with context
56
+ */
57
+ export interface FetchError {
58
+ projectKey: string;
59
+ error: string;
60
+ timestamp: string;
61
+ suggestion: string;
62
+ retryAttempts?: number;
63
+ }
64
+ /**
65
+ * Async Project Loader
66
+ *
67
+ * Handles batch fetching from issue trackers with advanced features:
68
+ * - Smart pagination (50-project batches for optimal performance)
69
+ * - Real-time progress tracking with ETA
70
+ * - Graceful cancelation with state persistence
71
+ * - Retry logic with exponential backoff (1s, 2s, 4s)
72
+ * - Rate limit detection and throttling
73
+ * - Graceful degradation (reduce batch size on timeout)
74
+ * - Continue-on-failure (single error doesn't block batch)
75
+ * - Comprehensive error logging
76
+ *
77
+ * @example
78
+ * ```typescript
79
+ * const loader = new AsyncProjectLoader(credentials, 'jira', {
80
+ * batchSize: 50,
81
+ * showEta: true
82
+ * });
83
+ *
84
+ * const result = await loader.fetchAllProjects(127);
85
+ * console.log(`Imported ${result.succeeded}/${result.projects.length} projects`);
86
+ * ```
87
+ */
88
+ export declare class AsyncProjectLoader {
89
+ private credentials;
90
+ private provider;
91
+ private options;
92
+ private progressTracker?;
93
+ private cancelHandler?;
94
+ private currentBatchSize;
95
+ constructor(credentials: JiraCredentials | AdoCredentials, provider: ProjectProvider, options?: FetchOptions);
96
+ /**
97
+ * Fetch all projects with smart pagination
98
+ *
99
+ * @param totalCount - Total number of projects to fetch
100
+ * @returns Fetch result with projects and statistics
101
+ */
102
+ fetchAllProjects(totalCount: number): Promise<FetchResult>;
103
+ /**
104
+ * Fetch single batch with pagination
105
+ *
106
+ * @param offset - Starting offset
107
+ * @param limit - Number of projects to fetch
108
+ * @returns Array of projects
109
+ */
110
+ fetchBatch(offset: number, limit: number): Promise<Project[]>;
111
+ /**
112
+ * Fetch JIRA batch with pagination
113
+ */
114
+ private fetchJiraBatch;
115
+ /**
116
+ * Fetch Azure DevOps batch with pagination
117
+ */
118
+ private fetchAdoBatch;
119
+ /**
120
+ * Fetch batch with retry logic and exponential backoff
121
+ */
122
+ private fetchBatchWithRetry;
123
+ /**
124
+ * Check rate limit headers and throttle if needed
125
+ */
126
+ private checkRateLimit;
127
+ /**
128
+ * Save partial state on cancelation
129
+ */
130
+ private savePartialState;
131
+ /**
132
+ * Log error to file
133
+ */
134
+ private logError;
135
+ /**
136
+ * Get suggestion for error
137
+ */
138
+ private getSuggestion;
139
+ /**
140
+ * Check if error is auth-related (4XX)
141
+ */
142
+ private isAuthError;
143
+ /**
144
+ * Check if error is timeout-related
145
+ */
146
+ private isTimeoutError;
147
+ }
148
+ //# sourceMappingURL=async-project-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"async-project-loader.d.ts","sourceRoot":"","sources":["../../../../src/cli/helpers/async-project-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH,OAAO,EAAE,MAAM,EAAiB,MAAM,uBAAuB,CAAC;AAG9D,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAoB,MAAM,4BAA4B,CAAC;AAEpG;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,KAAK,CAAC;AAE7C;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,WAAW,CAAmC;IACtD,OAAO,CAAC,QAAQ,CAAkB;IAClC,OAAO,CAAC,OAAO,CAAyB;IAExC,OAAO,CAAC,eAAe,CAAC,CAAkB;IAC1C,OAAO,CAAC,aAAa,CAAC,CAAqB;IAE3C,OAAO,CAAC,gBAAgB,CAAS;gBAG/B,WAAW,EAAE,eAAe,GAAG,cAAc,EAC7C,QAAQ,EAAE,eAAe,EACzB,OAAO,GAAE,YAAiB;IAkB5B;;;;;OAKG;IACG,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAwGhE;;;;;;OAMG;IACG,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAUnE;;OAEG;YACW,cAAc;IAwC5B;;OAEG;YACW,aAAa;IA8B3B;;OAEG;YACW,mBAAmB;IA4BjC;;OAEG;YACW,cAAc;IAiB5B;;OAEG;YACW,gBAAgB;IAgC9B;;OAEG;YACW,QAAQ;IAgBtB;;OAEG;IACH,OAAO,CAAC,aAAa;IA0BrB;;OAEG;IACH,OAAO,CAAC,WAAW;IAKnB;;OAEG;IACH,OAAO,CAAC,cAAc;CAKvB"}
@@ -0,0 +1,351 @@
1
+ /**
2
+ * Async Project Loader
3
+ *
4
+ * Advanced batch fetching with:
5
+ * - Smart pagination (50-project batches)
6
+ * - Real-time progress tracking
7
+ * - Graceful cancelation (Ctrl+C)
8
+ * - Retry logic with exponential backoff
9
+ * - Rate limit handling
10
+ * - Graceful degradation (reduce batch size on timeout)
11
+ * - Continue-on-failure error handling
12
+ * - Comprehensive error logging
13
+ *
14
+ * @module cli/helpers/async-project-loader
15
+ */
16
+ import { promises as fs } from 'fs';
17
+ import path from 'path';
18
+ import chalk from 'chalk';
19
+ import { consoleLogger } from '../../utils/logger.js';
20
+ import { ProgressTracker } from './progress-tracker.js';
21
+ import { CancelationHandler } from './cancelation-handler.js';
22
+ /**
23
+ * Async Project Loader
24
+ *
25
+ * Handles batch fetching from issue trackers with advanced features:
26
+ * - Smart pagination (50-project batches for optimal performance)
27
+ * - Real-time progress tracking with ETA
28
+ * - Graceful cancelation with state persistence
29
+ * - Retry logic with exponential backoff (1s, 2s, 4s)
30
+ * - Rate limit detection and throttling
31
+ * - Graceful degradation (reduce batch size on timeout)
32
+ * - Continue-on-failure (single error doesn't block batch)
33
+ * - Comprehensive error logging
34
+ *
35
+ * @example
36
+ * ```typescript
37
+ * const loader = new AsyncProjectLoader(credentials, 'jira', {
38
+ * batchSize: 50,
39
+ * showEta: true
40
+ * });
41
+ *
42
+ * const result = await loader.fetchAllProjects(127);
43
+ * console.log(`Imported ${result.succeeded}/${result.projects.length} projects`);
44
+ * ```
45
+ */
46
+ export class AsyncProjectLoader {
47
+ constructor(credentials, provider, options = {}) {
48
+ this.credentials = credentials;
49
+ this.provider = provider;
50
+ // Set defaults
51
+ this.options = {
52
+ batchSize: options.batchSize ?? 50,
53
+ updateFrequency: options.updateFrequency ?? 5,
54
+ showEta: options.showEta ?? true,
55
+ stateFile: options.stateFile ?? '.specweave/cache/import-state.json',
56
+ errorLogFile: options.errorLogFile ?? '.specweave/logs/import-errors.log',
57
+ logger: options.logger ?? consoleLogger
58
+ };
59
+ this.currentBatchSize = this.options.batchSize;
60
+ }
61
+ /**
62
+ * Fetch all projects with smart pagination
63
+ *
64
+ * @param totalCount - Total number of projects to fetch
65
+ * @returns Fetch result with projects and statistics
66
+ */
67
+ async fetchAllProjects(totalCount) {
68
+ const projects = [];
69
+ const errors = [];
70
+ // Initialize progress tracker
71
+ this.progressTracker = new ProgressTracker({
72
+ total: totalCount,
73
+ updateFrequency: this.options.updateFrequency,
74
+ showEta: this.options.showEta,
75
+ logger: this.options.logger
76
+ });
77
+ // Initialize cancelation handler
78
+ this.cancelHandler = new CancelationHandler({
79
+ stateFile: this.options.stateFile,
80
+ logger: this.options.logger
81
+ });
82
+ // Register cleanup callback (save state on Ctrl+C)
83
+ this.cancelHandler.onCleanup(async () => {
84
+ await this.savePartialState(projects, totalCount, errors);
85
+ });
86
+ // Main fetch loop
87
+ let offset = 0;
88
+ while (offset < totalCount) {
89
+ // Check for cancelation
90
+ if (this.cancelHandler.shouldCancel()) {
91
+ this.progressTracker.cancel();
92
+ this.cancelHandler.suggestResume('/specweave-jira:import-projects --resume');
93
+ return {
94
+ projects,
95
+ succeeded: this.progressTracker.getSummary().succeeded,
96
+ failed: this.progressTracker.getSummary().failed,
97
+ skipped: this.progressTracker.getSummary().skipped,
98
+ errors,
99
+ canceled: true
100
+ };
101
+ }
102
+ // Calculate batch size (last batch may be smaller)
103
+ const limit = Math.min(this.currentBatchSize, totalCount - offset);
104
+ try {
105
+ // Fetch batch with retry logic
106
+ const batch = await this.fetchBatchWithRetry(offset, limit);
107
+ projects.push(...batch);
108
+ // Update progress for each item in batch
109
+ batch.forEach(project => {
110
+ this.progressTracker.update(project.key, 'success');
111
+ });
112
+ }
113
+ catch (error) {
114
+ // Continue-on-failure: Log error, skip batch, continue
115
+ const batchKey = `BATCH_${offset}-${offset + limit}`;
116
+ const fetchError = {
117
+ projectKey: batchKey,
118
+ error: error.message,
119
+ timestamp: new Date().toISOString(),
120
+ suggestion: this.getSuggestion(error),
121
+ retryAttempts: 3
122
+ };
123
+ errors.push(fetchError);
124
+ await this.logError(fetchError);
125
+ // Update progress (mark all as failed)
126
+ for (let i = 0; i < limit; i++) {
127
+ this.progressTracker.update(`${batchKey}_${i}`, 'failure');
128
+ }
129
+ // Check if we should reduce batch size (graceful degradation)
130
+ if (this.isTimeoutError(error) && this.currentBatchSize > 10) {
131
+ const oldSize = this.currentBatchSize;
132
+ this.currentBatchSize = Math.max(10, Math.floor(this.currentBatchSize / 2));
133
+ this.options.logger.log(chalk.yellow(`⚠️ Timeout detected. Reducing batch size: ${oldSize} → ${this.currentBatchSize}`));
134
+ }
135
+ }
136
+ offset += limit;
137
+ }
138
+ // Finish progress tracking
139
+ this.progressTracker.finish();
140
+ // Clear cancelation state (successful completion)
141
+ await this.cancelHandler.clearState();
142
+ // Cleanup
143
+ this.cancelHandler.dispose();
144
+ return {
145
+ projects,
146
+ succeeded: this.progressTracker.getSummary().succeeded,
147
+ failed: this.progressTracker.getSummary().failed,
148
+ skipped: this.progressTracker.getSummary().skipped,
149
+ errors
150
+ };
151
+ }
152
+ /**
153
+ * Fetch single batch with pagination
154
+ *
155
+ * @param offset - Starting offset
156
+ * @param limit - Number of projects to fetch
157
+ * @returns Array of projects
158
+ */
159
+ async fetchBatch(offset, limit) {
160
+ if (this.provider === 'jira') {
161
+ return this.fetchJiraBatch(offset, limit);
162
+ }
163
+ else if (this.provider === 'ado') {
164
+ return this.fetchAdoBatch(offset, limit);
165
+ }
166
+ else {
167
+ throw new Error(`Unsupported provider: ${this.provider}`);
168
+ }
169
+ }
170
+ /**
171
+ * Fetch JIRA batch with pagination
172
+ */
173
+ async fetchJiraBatch(offset, limit) {
174
+ const creds = this.credentials;
175
+ const { domain, email, token, instanceType } = creds;
176
+ const apiVersion = instanceType === 'cloud' ? '3' : '2';
177
+ const endpoint = instanceType === 'cloud'
178
+ ? `/rest/api/${apiVersion}/project/search?startAt=${offset}&maxResults=${limit}`
179
+ : `/rest/api/${apiVersion}/project?startAt=${offset}&maxResults=${limit}`;
180
+ const url = `https://${domain}${endpoint}`;
181
+ const response = await fetch(url, {
182
+ method: 'GET',
183
+ headers: {
184
+ Authorization: `Basic ${Buffer.from(`${email}:${token}`).toString('base64')}`,
185
+ Accept: 'application/json',
186
+ 'Content-Type': 'application/json'
187
+ },
188
+ signal: AbortSignal.timeout(30000) // 30 second timeout
189
+ });
190
+ // Check rate limit
191
+ await this.checkRateLimit(response.headers);
192
+ if (!response.ok) {
193
+ const errorBody = await response.text().catch(() => 'No error body');
194
+ throw new Error(`JIRA API error: ${response.status} ${response.statusText}. ${errorBody}`);
195
+ }
196
+ if (instanceType === 'cloud') {
197
+ const data = (await response.json());
198
+ return data.values;
199
+ }
200
+ else {
201
+ // Server returns array directly
202
+ return (await response.json());
203
+ }
204
+ }
205
+ /**
206
+ * Fetch Azure DevOps batch with pagination
207
+ */
208
+ async fetchAdoBatch(offset, limit) {
209
+ const creds = this.credentials;
210
+ const { organization, pat } = creds;
211
+ const url = `https://dev.azure.com/${organization}/_apis/projects?$top=${limit}&$skip=${offset}&api-version=7.0`;
212
+ const response = await fetch(url, {
213
+ method: 'GET',
214
+ headers: {
215
+ Authorization: `Basic ${Buffer.from(`:${pat}`).toString('base64')}`,
216
+ Accept: 'application/json'
217
+ },
218
+ signal: AbortSignal.timeout(30000) // 30 second timeout
219
+ });
220
+ if (!response.ok) {
221
+ const errorBody = await response.text().catch(() => 'No error body');
222
+ throw new Error(`Azure DevOps API error: ${response.status} ${response.statusText}. ${errorBody}`);
223
+ }
224
+ const data = (await response.json());
225
+ return data.value.map(p => ({
226
+ id: p.id,
227
+ key: p.name.toUpperCase().replace(/\s+/g, '-'),
228
+ name: p.name
229
+ }));
230
+ }
231
+ /**
232
+ * Fetch batch with retry logic and exponential backoff
233
+ */
234
+ async fetchBatchWithRetry(offset, limit) {
235
+ const delays = [1000, 2000, 4000]; // 1s, 2s, 4s
236
+ let lastError = null;
237
+ for (let attempt = 0; attempt < 3; attempt++) {
238
+ try {
239
+ return await this.fetchBatch(offset, limit);
240
+ }
241
+ catch (error) {
242
+ lastError = error;
243
+ // Don't retry on auth failures (4XX except 429)
244
+ if (this.isAuthError(error) && !error.message.includes('429')) {
245
+ throw error;
246
+ }
247
+ // Retry on network errors, 5XX, or 429 errors
248
+ if (attempt < 2) {
249
+ this.options.logger.log(chalk.yellow(`⚠️ Retry ${attempt + 1}/3 after ${delays[attempt]}ms... (${error.message})`));
250
+ await new Promise(resolve => setTimeout(resolve, delays[attempt]));
251
+ }
252
+ }
253
+ }
254
+ throw lastError || new Error('Failed to fetch batch after 3 attempts');
255
+ }
256
+ /**
257
+ * Check rate limit headers and throttle if needed
258
+ */
259
+ async checkRateLimit(headers) {
260
+ const remaining = headers.get('X-RateLimit-Remaining');
261
+ const reset = headers.get('X-RateLimit-Reset');
262
+ if (remaining && parseInt(remaining, 10) < 10) {
263
+ const resetTime = reset ? parseInt(reset, 10) * 1000 : Date.now() + 60000;
264
+ const waitMs = Math.max(0, resetTime - Date.now());
265
+ const waitSec = Math.ceil(waitMs / 1000);
266
+ this.options.logger.log(chalk.yellow(`⚠️ Rate limit threshold reached (${remaining} requests remaining). Pausing ${waitSec}s...`));
267
+ await new Promise(resolve => setTimeout(resolve, waitMs + 1000)); // Add 1s buffer
268
+ }
269
+ }
270
+ /**
271
+ * Save partial state on cancelation
272
+ */
273
+ async savePartialState(projects, total, errors) {
274
+ const summary = this.progressTracker.getSummary();
275
+ // Calculate remaining projects
276
+ const completed = projects.length;
277
+ const remaining = [];
278
+ // Note: We don't have the list of all projects here, so remaining will be empty
279
+ // In a real implementation, this would be populated from the initial project list
280
+ const state = {
281
+ operation: `${this.provider}-import`,
282
+ provider: this.provider,
283
+ domain: 'credentials' in this.credentials ? this.credentials.domain : undefined,
284
+ timestamp: new Date().toISOString(),
285
+ version: '1.0',
286
+ total,
287
+ completed,
288
+ succeeded: summary.succeeded,
289
+ failed: summary.failed,
290
+ skipped: summary.skipped,
291
+ remaining,
292
+ errors
293
+ };
294
+ await this.cancelHandler.saveState(state);
295
+ }
296
+ /**
297
+ * Log error to file
298
+ */
299
+ async logError(error) {
300
+ try {
301
+ // Ensure log directory exists
302
+ const logDir = path.dirname(this.options.errorLogFile);
303
+ await fs.mkdir(logDir, { recursive: true });
304
+ // Format log entry
305
+ const logEntry = `[${error.timestamp}] ${error.projectKey}: ${error.error} (${error.suggestion})\n`;
306
+ // Append to log file
307
+ await fs.appendFile(this.options.errorLogFile, logEntry, 'utf-8');
308
+ }
309
+ catch (logError) {
310
+ this.options.logger.error('Failed to write error log:', logError);
311
+ }
312
+ }
313
+ /**
314
+ * Get suggestion for error
315
+ */
316
+ getSuggestion(error) {
317
+ const message = error.message || '';
318
+ if (message.includes('401') || message.includes('403')) {
319
+ return 'Check credentials and project permissions';
320
+ }
321
+ if (message.includes('404')) {
322
+ return 'Project may have been deleted or archived';
323
+ }
324
+ if (message.includes('429')) {
325
+ return 'Rate limit exceeded (throttling applied)';
326
+ }
327
+ if (message.includes('ETIMEDOUT') || message.includes('timeout')) {
328
+ return 'Network timeout (try again or reduce batch size)';
329
+ }
330
+ if (message.includes('5')) {
331
+ return 'API server error (retrying with backoff)';
332
+ }
333
+ return 'Unknown error (check logs for details)';
334
+ }
335
+ /**
336
+ * Check if error is auth-related (4XX)
337
+ */
338
+ isAuthError(error) {
339
+ const message = error.message || '';
340
+ return /\b40[0134]\b/.test(message);
341
+ }
342
+ /**
343
+ * Check if error is timeout-related
344
+ */
345
+ isTimeoutError(error) {
346
+ const message = error.message || '';
347
+ const code = error.code || '';
348
+ return message.includes('timeout') || code === 'ETIMEDOUT' || message.includes('ETIMEDOUT');
349
+ }
350
+ }
351
+ //# sourceMappingURL=async-project-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"async-project-loader.js","sourceRoot":"","sources":["../../../../src/cli/helpers/async-project-loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Cancelation Handler
3
+ *
4
+ * Graceful Ctrl+C handling with state persistence and resume capability.
5
+ * Atomic file writes ensure state integrity even during abrupt termination.
6
+ *
7
+ * @module cli/helpers/cancelation-handler
8
+ */
9
+ import { Logger } from '../../utils/logger.js';
10
+ /**
11
+ * Cancelation handler options
12
+ */
13
+ export interface CancelationOptions {
14
+ stateFile: string;
15
+ logger?: Logger;
16
+ }
17
+ /**
18
+ * Cancelation state (persisted to disk)
19
+ */
20
+ export interface CancelationState {
21
+ operation: string;
22
+ provider: string;
23
+ domain?: string;
24
+ timestamp: string;
25
+ version: string;
26
+ total: number;
27
+ completed: number;
28
+ succeeded: number;
29
+ failed: number;
30
+ skipped: number;
31
+ remaining: Array<{
32
+ key: string;
33
+ name: string;
34
+ }>;
35
+ errors: Array<{
36
+ projectKey: string;
37
+ error: string;
38
+ timestamp: string;
39
+ }>;
40
+ }
41
+ /**
42
+ * Cancelation Handler
43
+ *
44
+ * Handles SIGINT (Ctrl+C) signals during long-running operations:
45
+ * - Registers signal handler
46
+ * - Saves partial state to disk (atomic writes)
47
+ * - Provides resume capability
48
+ * - TTL validation (24-hour expiration)
49
+ *
50
+ * @example
51
+ * ```typescript
52
+ * const handler = new CancelationHandler({
53
+ * stateFile: '.specweave/cache/import-state.json'
54
+ * });
55
+ *
56
+ * handler.onCleanup(async () => {
57
+ * await savePartialState(projects, total, errors);
58
+ * });
59
+ *
60
+ * for (const project of projects) {
61
+ * if (handler.shouldCancel()) {
62
+ * break; // Exit gracefully
63
+ * }
64
+ * // ... process project ...
65
+ * }
66
+ * ```
67
+ */
68
+ export declare class CancelationHandler {
69
+ private stateFile;
70
+ private logger;
71
+ private canceled;
72
+ private cleanupCallback;
73
+ private sigintHandler;
74
+ private ctrlCCount;
75
+ constructor(options: CancelationOptions);
76
+ /**
77
+ * Register SIGINT (Ctrl+C) handler
78
+ */
79
+ private registerSigintHandler;
80
+ /**
81
+ * Check if cancelation was requested
82
+ *
83
+ * @returns True if Ctrl+C was pressed
84
+ */
85
+ shouldCancel(): boolean;
86
+ /**
87
+ * Register cleanup callback (executed on Ctrl+C)
88
+ *
89
+ * @param callback - Async cleanup function
90
+ */
91
+ onCleanup(callback: () => Promise<void>): void;
92
+ /**
93
+ * Save cancelation state to disk (atomic write)
94
+ *
95
+ * Uses temp file → rename pattern to ensure atomicity.
96
+ *
97
+ * @param state - Cancelation state to persist
98
+ */
99
+ saveState(state: CancelationState): Promise<void>;
100
+ /**
101
+ * Load cancelation state from disk
102
+ *
103
+ * Validates TTL (24-hour expiration) and version compatibility.
104
+ *
105
+ * @returns Cancelation state or null if not found/expired
106
+ */
107
+ loadState(): Promise<CancelationState | null>;
108
+ /**
109
+ * Clear saved state (delete file)
110
+ */
111
+ clearState(): Promise<void>;
112
+ /**
113
+ * Unregister SIGINT handler (cleanup)
114
+ */
115
+ dispose(): void;
116
+ /**
117
+ * Show resume suggestion to user
118
+ *
119
+ * @param resumeCommand - Command to resume operation (e.g., "/specweave-jira:import-projects --resume")
120
+ */
121
+ suggestResume(resumeCommand: string): void;
122
+ }
123
+ //# sourceMappingURL=cancelation-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cancelation-handler.d.ts","sourceRoot":"","sources":["../../../../src/cli/helpers/cancelation-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,EAAE,MAAM,EAAiB,MAAM,uBAAuB,CAAC;AAE9D;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChD,MAAM,EAAE,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACzE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,MAAM,CAAS;IAEvB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,eAAe,CAAsC;IAC7D,OAAO,CAAC,aAAa,CAAuC;IAC5D,OAAO,CAAC,UAAU,CAAK;gBAEX,OAAO,EAAE,kBAAkB;IAQvC;;OAEG;IACH,OAAO,CAAC,qBAAqB;IA6B7B;;;;OAIG;IACH,YAAY,IAAI,OAAO;IAIvB;;;;OAIG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAI9C;;;;;;OAMG;IACG,SAAS,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBvD;;;;;;OAMG;IACG,SAAS,IAAI,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAmCnD;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAWjC;;OAEG;IACH,OAAO,IAAI,IAAI;IAOf;;;;OAIG;IACH,aAAa,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI;CAG3C"}