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,111 @@
1
+ /**
2
+ * CancelationHandler - Graceful Ctrl+C (SIGINT) handling with state persistence
3
+ *
4
+ * Features:
5
+ * - Single Ctrl+C: Save state and exit gracefully
6
+ * - Double Ctrl+C (within 2s): Force exit immediately
7
+ * - Polling mechanism for cooperative cancelation
8
+ * - State persistence to resume later
9
+ *
10
+ * @module core/progress/cancelation-handler
11
+ */
12
+ import { consoleLogger } from '../../utils/logger.js';
13
+ /**
14
+ * CancelationHandler - Handles SIGINT gracefully with double Ctrl+C force exit
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * const handler = new CancelationHandler({
19
+ * onSaveState: async () => {
20
+ * await saveImportState();
21
+ * }
22
+ * });
23
+ *
24
+ * handler.register();
25
+ *
26
+ * // In import loop
27
+ * for (const project of projects) {
28
+ * if (handler.shouldCancel()) {
29
+ * break;
30
+ * }
31
+ * await importProject(project);
32
+ * }
33
+ *
34
+ * handler.unregister();
35
+ * ```
36
+ */
37
+ export class CancelationHandler {
38
+ constructor(options = {}) {
39
+ this.cancelRequested = false;
40
+ this.firstCtrlCTime = null;
41
+ this.sigintHandler = null;
42
+ this.logger = options.logger ?? consoleLogger;
43
+ this.onSaveState = options.onSaveState;
44
+ this.forceExitTimeout = options.forceExitTimeout ?? 2000;
45
+ }
46
+ /**
47
+ * Register SIGINT listener
48
+ */
49
+ register() {
50
+ this.sigintHandler = () => {
51
+ void this.handleSigint();
52
+ };
53
+ process.on('SIGINT', this.sigintHandler);
54
+ }
55
+ /**
56
+ * Unregister SIGINT listener
57
+ */
58
+ unregister() {
59
+ if (this.sigintHandler) {
60
+ process.off('SIGINT', this.sigintHandler);
61
+ this.sigintHandler = null;
62
+ }
63
+ }
64
+ /**
65
+ * Check if cancelation was requested (polling mechanism)
66
+ *
67
+ * @returns true if Ctrl+C was pressed
68
+ */
69
+ shouldCancel() {
70
+ return this.cancelRequested;
71
+ }
72
+ /**
73
+ * Handle SIGINT signal (Ctrl+C)
74
+ */
75
+ async handleSigint() {
76
+ const now = Date.now();
77
+ // Double Ctrl+C detection
78
+ if (this.firstCtrlCTime !== null) {
79
+ const elapsed = now - this.firstCtrlCTime;
80
+ if (elapsed < this.forceExitTimeout) {
81
+ // Force exit on double Ctrl+C
82
+ this.logger.warn('\n⚠️ Forced exit (progress may be lost)');
83
+ process.exit(1);
84
+ }
85
+ }
86
+ // First Ctrl+C
87
+ this.firstCtrlCTime = now;
88
+ this.cancelRequested = true;
89
+ this.logger.log('\n⏸️ Cancelation requested. Saving progress...');
90
+ try {
91
+ // Save state if callback provided
92
+ if (this.onSaveState) {
93
+ await this.onSaveState();
94
+ }
95
+ this.logger.log('✅ Progress saved. Run with --resume to continue.');
96
+ process.exit(0);
97
+ }
98
+ catch (error) {
99
+ this.logger.error('❌ Failed to save progress:', error);
100
+ process.exit(1);
101
+ }
102
+ }
103
+ /**
104
+ * Reset cancelation state (useful for testing)
105
+ */
106
+ reset() {
107
+ this.cancelRequested = false;
108
+ this.firstCtrlCTime = null;
109
+ }
110
+ }
111
+ //# sourceMappingURL=cancelation-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cancelation-handler.js","sourceRoot":"","sources":["../../../../src/core/progress/cancelation-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AActD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,OAAO,kBAAkB;IAS7B,YAAY,UAA8B,EAAE;QAJpC,oBAAe,GAAY,KAAK,CAAC;QACjC,mBAAc,GAAkB,IAAI,CAAC;QACrC,kBAAa,GAAwB,IAAI,CAAC;QAGhD,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,aAAa,CAAC;QAC9C,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;QACvC,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,IAAI,IAAI,CAAC;IAC3D,CAAC;IAED;;OAEG;IACH,QAAQ;QACN,IAAI,CAAC,aAAa,GAAG,GAAG,EAAE;YACxB,KAAK,IAAI,CAAC,YAAY,EAAE,CAAC;QAC3B,CAAC,CAAC;QAEF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;IAC3C,CAAC;IAED;;OAEG;IACH,UAAU;QACR,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;YAC1C,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC5B,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,YAAY;QACV,OAAO,IAAI,CAAC,eAAe,CAAC;IAC9B,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,YAAY;QACxB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEvB,0BAA0B;QAC1B,IAAI,IAAI,CAAC,cAAc,KAAK,IAAI,EAAE,CAAC;YACjC,MAAM,OAAO,GAAG,GAAG,GAAG,IAAI,CAAC,cAAc,CAAC;YAC1C,IAAI,OAAO,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBACpC,8BAA8B;gBAC9B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC;gBAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;QAED,eAAe;QACf,IAAI,CAAC,cAAc,GAAG,GAAG,CAAC;QAC1B,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QAE5B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;QAEnE,IAAI,CAAC;YACH,kCAAkC;YAClC,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;gBACrB,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;YAC3B,CAAC;YAED,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC;YACpE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,4BAA4B,EAAE,KAAK,CAAC,CAAC;YACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;QAC7B,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;IAC7B,CAAC;CACF"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * ImportState - State persistence for resumable imports
3
+ *
4
+ * Features:
5
+ * - Save/load import progress
6
+ * - 24-hour TTL for stale state cleanup
7
+ * - Error tracking for retry logic
8
+ *
9
+ * @module core/progress/import-state
10
+ */
11
+ /**
12
+ * Import error record
13
+ */
14
+ export interface ImportError {
15
+ /** Item identifier (e.g., project key) */
16
+ id: string;
17
+ /** Error message */
18
+ error: string;
19
+ /** Timestamp when error occurred */
20
+ timestamp: number;
21
+ }
22
+ /**
23
+ * Import state structure
24
+ */
25
+ export interface ImportState {
26
+ /** Total number of items to import */
27
+ total: number;
28
+ /** Number of items completed (success + failed) */
29
+ completed: number;
30
+ /** Number of successful imports */
31
+ succeeded: number;
32
+ /** Number of failed imports */
33
+ failed: number;
34
+ /** Array of import errors */
35
+ errors: ImportError[];
36
+ /** Timestamp when state was saved */
37
+ timestamp: number;
38
+ /** Whether import was canceled by user */
39
+ canceled: boolean;
40
+ /** Optional: Last successfully processed item ID */
41
+ lastProcessedId?: string;
42
+ }
43
+ /**
44
+ * Save import state to disk
45
+ *
46
+ * @param state Import state to save
47
+ * @param projectRoot Project root directory
48
+ */
49
+ export declare function saveImportState(state: ImportState, projectRoot?: string): Promise<void>;
50
+ /**
51
+ * Load import state from disk with TTL validation
52
+ *
53
+ * @param projectRoot Project root directory
54
+ * @param ttlMs Time-to-live in milliseconds (default: 24 hours)
55
+ * @returns Import state if valid, null if expired or missing
56
+ */
57
+ export declare function loadImportState(projectRoot?: string, ttlMs?: number): Promise<ImportState | null>;
58
+ /**
59
+ * Delete import state file
60
+ *
61
+ * @param projectRoot Project root directory
62
+ */
63
+ export declare function deleteImportState(projectRoot?: string): Promise<void>;
64
+ /**
65
+ * Check if import state exists (without loading)
66
+ *
67
+ * @param projectRoot Project root directory
68
+ * @returns true if state file exists
69
+ */
70
+ export declare function hasImportState(projectRoot?: string): boolean;
71
+ //# sourceMappingURL=import-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"import-state.d.ts","sourceRoot":"","sources":["../../../../src/core/progress/import-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,0CAA0C;IAC1C,EAAE,EAAE,MAAM,CAAC;IACX,oBAAoB;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,sCAAsC;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,mDAAmD;IACnD,SAAS,EAAE,MAAM,CAAC;IAClB,mCAAmC;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,+BAA+B;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,6BAA6B;IAC7B,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,0CAA0C;IAC1C,QAAQ,EAAE,OAAO,CAAC;IAClB,oDAAoD;IACpD,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAYD;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,WAAW,EAClB,WAAW,GAAE,MAAsB,GAClC,OAAO,CAAC,IAAI,CAAC,CAef;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,WAAW,GAAE,MAAsB,EACnC,KAAK,GAAE,MAA4B,GAClC,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CA0B7B;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,WAAW,GAAE,MAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAM1F;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,WAAW,GAAE,MAAsB,GAAG,OAAO,CAG3E"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * ImportState - State persistence for resumable imports
3
+ *
4
+ * Features:
5
+ * - Save/load import progress
6
+ * - 24-hour TTL for stale state cleanup
7
+ * - Error tracking for retry logic
8
+ *
9
+ * @module core/progress/import-state
10
+ */
11
+ import { promises as fs } from 'fs';
12
+ import { join } from 'path';
13
+ import { existsSync } from 'fs';
14
+ import { mkdirpSync } from '../../utils/fs-native.js';
15
+ /**
16
+ * Get import state file path
17
+ *
18
+ * @param projectRoot Project root directory
19
+ * @returns Path to import-state.json
20
+ */
21
+ function getStateFilePath(projectRoot = process.cwd()) {
22
+ return join(projectRoot, '.specweave', 'cache', 'import-state.json');
23
+ }
24
+ /**
25
+ * Save import state to disk
26
+ *
27
+ * @param state Import state to save
28
+ * @param projectRoot Project root directory
29
+ */
30
+ export async function saveImportState(state, projectRoot = process.cwd()) {
31
+ const stateFilePath = getStateFilePath(projectRoot);
32
+ const cacheDir = join(projectRoot, '.specweave', 'cache');
33
+ // Ensure cache directory exists
34
+ mkdirpSync(cacheDir);
35
+ // Add timestamp
36
+ const stateWithTimestamp = {
37
+ ...state,
38
+ timestamp: Date.now(),
39
+ };
40
+ // Write to file
41
+ await fs.writeFile(stateFilePath, JSON.stringify(stateWithTimestamp, null, 2), 'utf-8');
42
+ }
43
+ /**
44
+ * Load import state from disk with TTL validation
45
+ *
46
+ * @param projectRoot Project root directory
47
+ * @param ttlMs Time-to-live in milliseconds (default: 24 hours)
48
+ * @returns Import state if valid, null if expired or missing
49
+ */
50
+ export async function loadImportState(projectRoot = process.cwd(), ttlMs = 24 * 60 * 60 * 1000 // 24 hours
51
+ ) {
52
+ const stateFilePath = getStateFilePath(projectRoot);
53
+ // Check if file exists
54
+ if (!existsSync(stateFilePath)) {
55
+ return null;
56
+ }
57
+ try {
58
+ // Read and parse file
59
+ const content = await fs.readFile(stateFilePath, 'utf-8');
60
+ const state = JSON.parse(content);
61
+ // Validate TTL
62
+ const age = Date.now() - state.timestamp;
63
+ if (age > ttlMs) {
64
+ // State is expired, delete it
65
+ await deleteImportState(projectRoot);
66
+ return null;
67
+ }
68
+ return state;
69
+ }
70
+ catch (error) {
71
+ // Invalid JSON or read error
72
+ return null;
73
+ }
74
+ }
75
+ /**
76
+ * Delete import state file
77
+ *
78
+ * @param projectRoot Project root directory
79
+ */
80
+ export async function deleteImportState(projectRoot = process.cwd()) {
81
+ const stateFilePath = getStateFilePath(projectRoot);
82
+ if (existsSync(stateFilePath)) {
83
+ await fs.unlink(stateFilePath);
84
+ }
85
+ }
86
+ /**
87
+ * Check if import state exists (without loading)
88
+ *
89
+ * @param projectRoot Project root directory
90
+ * @returns true if state file exists
91
+ */
92
+ export function hasImportState(projectRoot = process.cwd()) {
93
+ const stateFilePath = getStateFilePath(projectRoot);
94
+ return existsSync(stateFilePath);
95
+ }
96
+ //# sourceMappingURL=import-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"import-state.js","sourceRoot":"","sources":["../../../../src/core/progress/import-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAoCtD;;;;;GAKG;AACH,SAAS,gBAAgB,CAAC,cAAsB,OAAO,CAAC,GAAG,EAAE;IAC3D,OAAO,IAAI,CAAC,WAAW,EAAE,YAAY,EAAE,OAAO,EAAE,mBAAmB,CAAC,CAAC;AACvE,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,KAAkB,EAClB,cAAsB,OAAO,CAAC,GAAG,EAAE;IAEnC,MAAM,aAAa,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAC;IACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;IAE1D,gCAAgC;IAChC,UAAU,CAAC,QAAQ,CAAC,CAAC;IAErB,gBAAgB;IAChB,MAAM,kBAAkB,GAAgB;QACtC,GAAG,KAAK;QACR,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;KACtB,CAAC;IAEF,gBAAgB;IAChB,MAAM,EAAE,CAAC,SAAS,CAAC,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC,kBAAkB,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;AAC1F,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,cAAsB,OAAO,CAAC,GAAG,EAAE,EACnC,QAAgB,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,WAAW;;IAE/C,MAAM,aAAa,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAC;IAEpD,uBAAuB;IACvB,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QAC/B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACH,sBAAsB;QACtB,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;QAC1D,MAAM,KAAK,GAAgB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAE/C,eAAe;QACf,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS,CAAC;QACzC,IAAI,GAAG,GAAG,KAAK,EAAE,CAAC;YAChB,8BAA8B;YAC9B,MAAM,iBAAiB,CAAC,WAAW,CAAC,CAAC;YACrC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,6BAA6B;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,cAAsB,OAAO,CAAC,GAAG,EAAE;IACzE,MAAM,aAAa,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAC;IAEpD,IAAI,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QAC9B,MAAM,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IACjC,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,cAAsB,OAAO,CAAC,GAAG,EAAE;IAChE,MAAM,aAAa,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAC;IACpD,OAAO,UAAU,CAAC,aAAa,CAAC,CAAC;AACnC,CAAC"}
@@ -0,0 +1,139 @@
1
+ /**
2
+ * ProgressTracker - Real-time progress tracking with ETA calculation
3
+ *
4
+ * Features:
5
+ * - ASCII progress bar (30 characters)
6
+ * - Linear ETA extrapolation
7
+ * - Elapsed time tracking
8
+ * - Project-level status display (✅ ❌ ⏳)
9
+ * - Configurable update frequency
10
+ *
11
+ * @module core/progress/progress-tracker
12
+ */
13
+ import { Logger } from '../../utils/logger.js';
14
+ /**
15
+ * Item status types
16
+ */
17
+ export type ItemStatus = 'pending' | 'success' | 'error';
18
+ /**
19
+ * Progress tracker options
20
+ */
21
+ export interface ProgressTrackerOptions {
22
+ /** Total number of items to process */
23
+ total: number;
24
+ /** Label for the operation (e.g., "Importing projects") */
25
+ label: string;
26
+ /** Show ETA calculation */
27
+ showEta?: boolean;
28
+ /** Update frequency (update every N items, default: 5) */
29
+ updateFrequency?: number;
30
+ /** Logger instance */
31
+ logger?: Logger;
32
+ }
33
+ /**
34
+ * Item with status
35
+ */
36
+ interface TrackedItem {
37
+ name: string;
38
+ status: ItemStatus;
39
+ timestamp: number;
40
+ }
41
+ /**
42
+ * ProgressTracker - Real-time progress tracking with ASCII progress bar and ETA
43
+ *
44
+ * @example
45
+ * ```typescript
46
+ * const tracker = new ProgressTracker({
47
+ * total: 127,
48
+ * label: 'Importing projects',
49
+ * showEta: true,
50
+ * updateFrequency: 5
51
+ * });
52
+ *
53
+ * for (const project of projects) {
54
+ * await importProject(project);
55
+ * tracker.update(project.key, 'success');
56
+ * }
57
+ *
58
+ * tracker.finish(120, 5, 2);
59
+ * ```
60
+ */
61
+ export declare class ProgressTracker {
62
+ private total;
63
+ private label;
64
+ private showEta;
65
+ private updateFrequency;
66
+ private logger;
67
+ private items;
68
+ private startTime;
69
+ private lastUpdateCount;
70
+ constructor(options: ProgressTrackerOptions);
71
+ /**
72
+ * Update progress for a specific item
73
+ *
74
+ * @param itemName Item identifier (e.g., project key)
75
+ * @param status Item status (pending, success, error)
76
+ */
77
+ update(itemName: string, status: ItemStatus): void;
78
+ /**
79
+ * Finish progress tracking and show final summary
80
+ *
81
+ * @param succeeded Count of successful items
82
+ * @param failed Count of failed items
83
+ * @param skipped Count of skipped items
84
+ */
85
+ finish(succeeded: number, failed: number, skipped: number): void;
86
+ /**
87
+ * Render progress bar to console
88
+ */
89
+ private render;
90
+ /**
91
+ * Render ASCII progress bar
92
+ *
93
+ * @param percentage Completion percentage (0-100)
94
+ * @returns ASCII progress bar (30 characters)
95
+ *
96
+ * @example
97
+ * renderProgressBar(0) => "[> ]"
98
+ * renderProgressBar(37) => "[==========> ]"
99
+ * renderProgressBar(100) => "[==============================]"
100
+ */
101
+ renderProgressBar(percentage: number): string;
102
+ /**
103
+ * Get elapsed time in human-readable format
104
+ *
105
+ * @returns Elapsed time string (e.g., "2m 34s", "45s")
106
+ */
107
+ getElapsedTime(): string;
108
+ /**
109
+ * Get estimated time remaining (ETA) using linear extrapolation
110
+ *
111
+ * Formula: ETA = (total - completed) * (elapsed / completed)
112
+ *
113
+ * @returns ETA string (e.g., ", ~2m remaining", ", ~45s remaining")
114
+ */
115
+ getEta(): string;
116
+ /**
117
+ * Get count of completed items (success + error)
118
+ */
119
+ private getCompletedCount;
120
+ /**
121
+ * Get items by status
122
+ */
123
+ getItemsByStatus(status: ItemStatus): TrackedItem[];
124
+ /**
125
+ * Get current progress statistics
126
+ */
127
+ getStats(): {
128
+ total: number;
129
+ completed: number;
130
+ succeeded: number;
131
+ failed: number;
132
+ pending: number;
133
+ percentage: number;
134
+ elapsedMs: number;
135
+ etaMs: number | null;
136
+ };
137
+ }
138
+ export {};
139
+ //# sourceMappingURL=progress-tracker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress-tracker.d.ts","sourceRoot":"","sources":["../../../../src/core/progress/progress-tracker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,MAAM,EAAiB,MAAM,uBAAuB,CAAC;AAE9D;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AAEzD;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,uCAAuC;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,KAAK,EAAE,MAAM,CAAC;IACd,2BAA2B;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,0DAA0D;IAC1D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,sBAAsB;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,MAAM,CAAS;IAEvB,OAAO,CAAC,KAAK,CAAuC;IACpD,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,eAAe,CAAa;gBAExB,OAAO,EAAE,sBAAsB;IAS3C;;;;;OAKG;IACH,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI;IAoBlD;;;;;;OAMG;IACH,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAgBhE;;OAEG;IACH,OAAO,CAAC,MAAM;IAcd;;;;;;;;;;OAUG;IACH,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IAuB7C;;;;OAIG;IACH,cAAc,IAAI,MAAM;IAaxB;;;;;;OAMG;IACH,MAAM,IAAI,MAAM;IAyBhB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAUzB;;OAEG;IACH,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,WAAW,EAAE;IAUnD;;OAEG;IACH,QAAQ,IAAI;QACV,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;KACtB;CA0BF"}
@@ -0,0 +1,223 @@
1
+ /**
2
+ * ProgressTracker - Real-time progress tracking with ETA calculation
3
+ *
4
+ * Features:
5
+ * - ASCII progress bar (30 characters)
6
+ * - Linear ETA extrapolation
7
+ * - Elapsed time tracking
8
+ * - Project-level status display (✅ ❌ ⏳)
9
+ * - Configurable update frequency
10
+ *
11
+ * @module core/progress/progress-tracker
12
+ */
13
+ import { consoleLogger } from '../../utils/logger.js';
14
+ /**
15
+ * ProgressTracker - Real-time progress tracking with ASCII progress bar and ETA
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * const tracker = new ProgressTracker({
20
+ * total: 127,
21
+ * label: 'Importing projects',
22
+ * showEta: true,
23
+ * updateFrequency: 5
24
+ * });
25
+ *
26
+ * for (const project of projects) {
27
+ * await importProject(project);
28
+ * tracker.update(project.key, 'success');
29
+ * }
30
+ *
31
+ * tracker.finish(120, 5, 2);
32
+ * ```
33
+ */
34
+ export class ProgressTracker {
35
+ constructor(options) {
36
+ this.items = new Map();
37
+ this.lastUpdateCount = 0;
38
+ this.total = options.total;
39
+ this.label = options.label;
40
+ this.showEta = options.showEta ?? true;
41
+ this.updateFrequency = options.updateFrequency ?? 5;
42
+ this.logger = options.logger ?? consoleLogger;
43
+ this.startTime = Date.now();
44
+ }
45
+ /**
46
+ * Update progress for a specific item
47
+ *
48
+ * @param itemName Item identifier (e.g., project key)
49
+ * @param status Item status (pending, success, error)
50
+ */
51
+ update(itemName, status) {
52
+ // Track item
53
+ this.items.set(itemName, {
54
+ name: itemName,
55
+ status,
56
+ timestamp: Date.now(),
57
+ });
58
+ const completed = this.getCompletedCount();
59
+ // Only render if we've processed enough items since last update
60
+ if (completed - this.lastUpdateCount >= this.updateFrequency ||
61
+ completed === this.total) {
62
+ this.render();
63
+ this.lastUpdateCount = completed;
64
+ }
65
+ }
66
+ /**
67
+ * Finish progress tracking and show final summary
68
+ *
69
+ * @param succeeded Count of successful items
70
+ * @param failed Count of failed items
71
+ * @param skipped Count of skipped items
72
+ */
73
+ finish(succeeded, failed, skipped) {
74
+ // Final render
75
+ this.render();
76
+ // Show summary
77
+ console.log(''); // Blank line
78
+ console.log(`✅ Succeeded: ${succeeded}`);
79
+ if (failed > 0) {
80
+ console.log(`❌ Failed: ${failed}`);
81
+ }
82
+ if (skipped > 0) {
83
+ console.log(`⏭️ Skipped: ${skipped}`);
84
+ }
85
+ console.log(''); // Blank line
86
+ }
87
+ /**
88
+ * Render progress bar to console
89
+ */
90
+ render() {
91
+ const completed = this.getCompletedCount();
92
+ const percentage = Math.round((completed / this.total) * 100);
93
+ const progressBar = this.renderProgressBar(percentage);
94
+ const elapsed = this.getElapsedTime();
95
+ const eta = this.showEta ? this.getEta() : '';
96
+ // Clear current line and print progress
97
+ process.stdout.write('\r'); // Carriage return to beginning of line
98
+ process.stdout.write(`${this.label}... ${completed}/${this.total} (${percentage}%) ${progressBar} [${elapsed}${eta}]`);
99
+ }
100
+ /**
101
+ * Render ASCII progress bar
102
+ *
103
+ * @param percentage Completion percentage (0-100)
104
+ * @returns ASCII progress bar (30 characters)
105
+ *
106
+ * @example
107
+ * renderProgressBar(0) => "[> ]"
108
+ * renderProgressBar(37) => "[==========> ]"
109
+ * renderProgressBar(100) => "[==============================]"
110
+ */
111
+ renderProgressBar(percentage) {
112
+ const barLength = 30;
113
+ const filledLength = Math.round((percentage / 100) * barLength);
114
+ const emptyLength = barLength - filledLength;
115
+ let bar = '[';
116
+ // Filled portion
117
+ if (filledLength > 0) {
118
+ bar += '='.repeat(Math.max(0, filledLength - 1));
119
+ bar += '>';
120
+ bar += ' '.repeat(Math.max(0, emptyLength));
121
+ }
122
+ else {
123
+ // At 0%, show cursor at start
124
+ bar += '>';
125
+ bar += ' '.repeat(Math.max(0, emptyLength - 1));
126
+ }
127
+ bar += ']';
128
+ return bar;
129
+ }
130
+ /**
131
+ * Get elapsed time in human-readable format
132
+ *
133
+ * @returns Elapsed time string (e.g., "2m 34s", "45s")
134
+ */
135
+ getElapsedTime() {
136
+ const elapsedMs = Date.now() - this.startTime;
137
+ const elapsedSeconds = Math.floor(elapsedMs / 1000);
138
+ if (elapsedSeconds < 60) {
139
+ return `${elapsedSeconds}s elapsed`;
140
+ }
141
+ const minutes = Math.floor(elapsedSeconds / 60);
142
+ const seconds = elapsedSeconds % 60;
143
+ return `${minutes}m ${seconds}s elapsed`;
144
+ }
145
+ /**
146
+ * Get estimated time remaining (ETA) using linear extrapolation
147
+ *
148
+ * Formula: ETA = (total - completed) * (elapsed / completed)
149
+ *
150
+ * @returns ETA string (e.g., ", ~2m remaining", ", ~45s remaining")
151
+ */
152
+ getEta() {
153
+ const completed = this.getCompletedCount();
154
+ if (completed === 0) {
155
+ return ', ~? remaining';
156
+ }
157
+ if (completed === this.total) {
158
+ return ', ~0s remaining';
159
+ }
160
+ const elapsedMs = Date.now() - this.startTime;
161
+ const avgTimePerItem = elapsedMs / completed;
162
+ const remaining = this.total - completed;
163
+ const etaMs = remaining * avgTimePerItem;
164
+ const etaSeconds = Math.floor(etaMs / 1000);
165
+ if (etaSeconds < 60) {
166
+ return `, ~${etaSeconds}s remaining`;
167
+ }
168
+ const minutes = Math.floor(etaSeconds / 60);
169
+ return `, ~${minutes}m remaining`;
170
+ }
171
+ /**
172
+ * Get count of completed items (success + error)
173
+ */
174
+ getCompletedCount() {
175
+ let count = 0;
176
+ for (const item of this.items.values()) {
177
+ if (item.status === 'success' || item.status === 'error') {
178
+ count++;
179
+ }
180
+ }
181
+ return count;
182
+ }
183
+ /**
184
+ * Get items by status
185
+ */
186
+ getItemsByStatus(status) {
187
+ const result = [];
188
+ for (const item of this.items.values()) {
189
+ if (item.status === status) {
190
+ result.push(item);
191
+ }
192
+ }
193
+ return result;
194
+ }
195
+ /**
196
+ * Get current progress statistics
197
+ */
198
+ getStats() {
199
+ const completed = this.getCompletedCount();
200
+ const succeeded = this.getItemsByStatus('success').length;
201
+ const failed = this.getItemsByStatus('error').length;
202
+ const pending = this.getItemsByStatus('pending').length;
203
+ const percentage = Math.round((completed / this.total) * 100);
204
+ const elapsedMs = Date.now() - this.startTime;
205
+ let etaMs = null;
206
+ if (completed > 0 && completed < this.total) {
207
+ const avgTimePerItem = elapsedMs / completed;
208
+ const remaining = this.total - completed;
209
+ etaMs = remaining * avgTimePerItem;
210
+ }
211
+ return {
212
+ total: this.total,
213
+ completed,
214
+ succeeded,
215
+ failed,
216
+ pending,
217
+ percentage,
218
+ elapsedMs,
219
+ etaMs,
220
+ };
221
+ }
222
+ }
223
+ //# sourceMappingURL=progress-tracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress-tracker.js","sourceRoot":"","sources":["../../../../src/core/progress/progress-tracker.ts"],"names":[],"mappings":"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"}