specweave 0.23.10 → 0.23.14
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/.claude-plugin/marketplace.json +7 -7
- package/CLAUDE.md +384 -1449
- package/dist/src/cli/commands/cleanup-cache.d.ts +14 -0
- package/dist/src/cli/commands/cleanup-cache.d.ts.map +1 -0
- package/dist/src/cli/commands/cleanup-cache.js +63 -0
- package/dist/src/cli/commands/cleanup-cache.js.map +1 -0
- package/dist/src/cli/commands/init.js +40 -0
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/helpers/async-project-loader.d.ts +148 -0
- package/dist/src/cli/helpers/async-project-loader.d.ts.map +1 -0
- package/dist/src/cli/helpers/async-project-loader.js +351 -0
- package/dist/src/cli/helpers/async-project-loader.js.map +1 -0
- package/dist/src/cli/helpers/cancelation-handler.d.ts +123 -0
- package/dist/src/cli/helpers/cancelation-handler.d.ts.map +1 -0
- package/dist/src/cli/helpers/cancelation-handler.js +187 -0
- package/dist/src/cli/helpers/cancelation-handler.js.map +1 -0
- package/dist/src/cli/helpers/import-strategy-prompter.d.ts +43 -0
- package/dist/src/cli/helpers/import-strategy-prompter.d.ts.map +1 -0
- package/dist/src/cli/helpers/import-strategy-prompter.js +136 -0
- package/dist/src/cli/helpers/import-strategy-prompter.js.map +1 -0
- package/dist/src/cli/helpers/issue-tracker/ado.d.ts +5 -2
- package/dist/src/cli/helpers/issue-tracker/ado.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/ado.js +90 -40
- package/dist/src/cli/helpers/issue-tracker/ado.js.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/jira.d.ts +2 -1
- package/dist/src/cli/helpers/issue-tracker/jira.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/jira.js +120 -35
- package/dist/src/cli/helpers/issue-tracker/jira.js.map +1 -1
- package/dist/src/cli/helpers/progress-tracker.d.ts +121 -0
- package/dist/src/cli/helpers/progress-tracker.d.ts.map +1 -0
- package/dist/src/cli/helpers/progress-tracker.js +202 -0
- package/dist/src/cli/helpers/progress-tracker.js.map +1 -0
- package/dist/src/cli/helpers/project-count-fetcher.d.ts +69 -0
- package/dist/src/cli/helpers/project-count-fetcher.d.ts.map +1 -0
- package/dist/src/cli/helpers/project-count-fetcher.js +173 -0
- package/dist/src/cli/helpers/project-count-fetcher.js.map +1 -0
- package/dist/src/config/types.d.ts +14 -14
- package/dist/src/core/cache/cache-manager.d.ts +119 -0
- package/dist/src/core/cache/cache-manager.d.ts.map +1 -0
- package/dist/src/core/cache/cache-manager.js +304 -0
- package/dist/src/core/cache/cache-manager.js.map +1 -0
- package/dist/src/core/cache/rate-limit-checker.d.ts +92 -0
- package/dist/src/core/cache/rate-limit-checker.d.ts.map +1 -0
- package/dist/src/core/cache/rate-limit-checker.js +160 -0
- package/dist/src/core/cache/rate-limit-checker.js.map +1 -0
- package/dist/src/core/progress/cancelation-handler.d.ts +79 -0
- package/dist/src/core/progress/cancelation-handler.d.ts.map +1 -0
- package/dist/src/core/progress/cancelation-handler.js +111 -0
- package/dist/src/core/progress/cancelation-handler.js.map +1 -0
- package/dist/src/core/progress/error-logger.d.ts +58 -0
- package/dist/src/core/progress/error-logger.d.ts.map +1 -0
- package/dist/src/core/progress/error-logger.js +99 -0
- package/dist/src/core/progress/error-logger.js.map +1 -0
- package/dist/src/core/progress/import-state.d.ts +71 -0
- package/dist/src/core/progress/import-state.d.ts.map +1 -0
- package/dist/src/core/progress/import-state.js +96 -0
- package/dist/src/core/progress/import-state.js.map +1 -0
- package/dist/src/core/progress/progress-tracker.d.ts +139 -0
- package/dist/src/core/progress/progress-tracker.d.ts.map +1 -0
- package/dist/src/core/progress/progress-tracker.js +223 -0
- package/dist/src/core/progress/progress-tracker.js.map +1 -0
- package/dist/src/init/architecture/types.d.ts +6 -6
- package/dist/src/integrations/ado/ado-client.d.ts +25 -0
- package/dist/src/integrations/ado/ado-client.d.ts.map +1 -1
- package/dist/src/integrations/ado/ado-client.js +67 -0
- package/dist/src/integrations/ado/ado-client.js.map +1 -1
- package/dist/src/integrations/ado/ado-dependency-loader.d.ts +99 -0
- package/dist/src/integrations/ado/ado-dependency-loader.d.ts.map +1 -0
- package/dist/src/integrations/ado/ado-dependency-loader.js +207 -0
- package/dist/src/integrations/ado/ado-dependency-loader.js.map +1 -0
- package/dist/src/integrations/jira/jira-client.d.ts +32 -0
- package/dist/src/integrations/jira/jira-client.d.ts.map +1 -1
- package/dist/src/integrations/jira/jira-client.js +81 -0
- package/dist/src/integrations/jira/jira-client.js.map +1 -1
- package/dist/src/integrations/jira/jira-dependency-loader.d.ts +101 -0
- package/dist/src/integrations/jira/jira-dependency-loader.d.ts.map +1 -0
- package/dist/src/integrations/jira/jira-dependency-loader.js +200 -0
- package/dist/src/integrations/jira/jira-dependency-loader.js.map +1 -0
- package/package.json +1 -1
- package/plugins/specweave/.claude-plugin/plugin.json +20 -0
- package/plugins/specweave/agents/architect/AGENT.md +100 -602
- package/plugins/specweave/agents/pm/AGENT.md +96 -597
- package/plugins/specweave/agents/pm/AGENT.md.bak +1893 -0
- package/plugins/specweave/agents/pm/AGENT.md.bak2 +1754 -0
- package/plugins/specweave/commands/check-hooks.md +257 -0
- package/plugins/specweave/hooks/docs-changed.sh +9 -1
- package/plugins/specweave/hooks/docs-changed.sh.backup +79 -0
- package/plugins/specweave/hooks/human-input-required.sh +9 -1
- package/plugins/specweave/hooks/human-input-required.sh.backup +75 -0
- package/plugins/specweave/hooks/post-edit-spec.sh +202 -31
- package/plugins/specweave/hooks/post-first-increment.sh.backup +61 -0
- package/plugins/specweave/hooks/post-increment-change.sh +6 -1
- package/plugins/specweave/hooks/post-increment-change.sh.backup +98 -0
- package/plugins/specweave/hooks/post-increment-completion.sh +6 -1
- package/plugins/specweave/hooks/post-increment-completion.sh.backup +231 -0
- package/plugins/specweave/hooks/post-increment-planning.sh +6 -1
- package/plugins/specweave/hooks/post-increment-planning.sh.backup +1048 -0
- package/plugins/specweave/hooks/post-increment-status-change.sh +6 -1
- package/plugins/specweave/hooks/post-increment-status-change.sh.backup +147 -0
- package/plugins/specweave/hooks/post-metadata-change.sh +7 -1
- package/plugins/specweave/hooks/post-spec-update.sh.backup +158 -0
- package/plugins/specweave/hooks/post-task-completion.sh +225 -228
- package/plugins/specweave/hooks/post-user-story-complete.sh.backup +179 -0
- package/plugins/specweave/hooks/post-write-spec.sh +207 -31
- package/plugins/specweave/hooks/pre-command-deduplication.sh.backup +83 -0
- package/plugins/specweave/hooks/pre-edit-spec.sh +151 -0
- package/plugins/specweave/hooks/pre-implementation.sh +9 -1
- package/plugins/specweave/hooks/pre-implementation.sh.backup +67 -0
- package/plugins/specweave/hooks/pre-task-completion.sh +14 -8
- package/plugins/specweave/hooks/pre-task-completion.sh.backup +194 -0
- package/plugins/specweave/hooks/pre-tool-use.sh +9 -1
- package/plugins/specweave/hooks/pre-tool-use.sh.backup +133 -0
- package/plugins/specweave/hooks/pre-write-spec.sh +151 -0
- package/plugins/specweave/hooks/test-pretooluse-env.sh +72 -0
- package/plugins/specweave/hooks/user-prompt-submit.sh.backup +386 -0
- package/plugins/specweave/skills/compliance-architecture/SKILL.md +374 -0
- package/plugins/specweave/skills/external-sync-wizard/SKILL.md +610 -0
- package/plugins/specweave/skills/pm-closure-validation/SKILL.md +541 -0
- package/plugins/specweave/skills/roadmap-planner/SKILL.md +473 -0
- package/plugins/specweave-ado/commands/refresh-cache.js +25 -0
- package/plugins/specweave-ado/commands/refresh-cache.ts +40 -0
- package/plugins/specweave-ado/hooks/post-living-docs-update.sh +9 -2
- package/plugins/specweave-ado/hooks/post-living-docs-update.sh.backup +353 -0
- package/plugins/specweave-ado/hooks/post-task-completion.sh +10 -2
- package/plugins/specweave-ado/hooks/post-task-completion.sh.backup +172 -0
- package/plugins/specweave-github/hooks/post-task-completion.sh +10 -2
- package/plugins/specweave-github/hooks/post-task-completion.sh.backup +258 -0
- package/plugins/specweave-jira/commands/refresh-cache.js +25 -0
- package/plugins/specweave-jira/commands/refresh-cache.ts +40 -0
- package/plugins/specweave-jira/hooks/post-task-completion.sh +10 -2
- package/plugins/specweave-jira/hooks/post-task-completion.sh.backup +172 -0
- package/plugins/specweave-kafka-streams/commands/topology.md +437 -0
- package/plugins/specweave-n8n/commands/workflow-template.md +262 -0
- package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +252 -6465
- package/plugins/specweave-release/hooks/post-task-completion.sh.backup +110 -0
|
@@ -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"}
|