@eldrforge/kodrdriv 1.2.23 → 1.2.24
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/PARALLEL-EXECUTION-FIXES.md +132 -0
- package/PARALLEL_EXECUTION_FIX.md +146 -0
- package/RECOVERY-FIXES.md +72 -0
- package/dist/arguments.js +26 -3
- package/dist/arguments.js.map +1 -1
- package/dist/commands/audio-commit.js +3 -3
- package/dist/commands/audio-commit.js.map +1 -1
- package/dist/commands/audio-review.js +13 -13
- package/dist/commands/audio-review.js.map +1 -1
- package/dist/commands/link.js +13 -13
- package/dist/commands/link.js.map +1 -1
- package/dist/commands/publish.js +200 -146
- package/dist/commands/publish.js.map +1 -1
- package/dist/commands/review.js +6 -6
- package/dist/commands/review.js.map +1 -1
- package/dist/commands/select-audio.js +4 -4
- package/dist/commands/select-audio.js.map +1 -1
- package/dist/commands/tree.js +242 -318
- package/dist/commands/tree.js.map +1 -1
- package/dist/commands/unlink.js +8 -8
- package/dist/commands/unlink.js.map +1 -1
- package/dist/commands/versions.js +3 -3
- package/dist/commands/versions.js.map +1 -1
- package/dist/constants.js +4 -4
- package/dist/constants.js.map +1 -1
- package/dist/content/diff.js +5 -2
- package/dist/content/diff.js.map +1 -1
- package/dist/content/files.js +4 -4
- package/dist/content/files.js.map +1 -1
- package/dist/execution/CommandValidator.js +160 -0
- package/dist/execution/CommandValidator.js.map +1 -0
- package/dist/execution/DependencyChecker.js +102 -0
- package/dist/execution/DependencyChecker.js.map +1 -0
- package/dist/execution/DynamicTaskPool.js +455 -0
- package/dist/execution/DynamicTaskPool.js.map +1 -0
- package/dist/execution/RecoveryManager.js +502 -0
- package/dist/execution/RecoveryManager.js.map +1 -0
- package/dist/execution/ResourceMonitor.js +125 -0
- package/dist/execution/ResourceMonitor.js.map +1 -0
- package/dist/execution/Scheduler.js +98 -0
- package/dist/execution/Scheduler.js.map +1 -0
- package/dist/execution/TreeExecutionAdapter.js +170 -0
- package/dist/execution/TreeExecutionAdapter.js.map +1 -0
- package/dist/logging.js +3 -3
- package/dist/logging.js.map +1 -1
- package/dist/ui/ProgressFormatter.js +230 -0
- package/dist/ui/ProgressFormatter.js.map +1 -0
- package/dist/util/checkpointManager.js +168 -0
- package/dist/util/checkpointManager.js.map +1 -0
- package/dist/util/dependencyGraph.js +224 -0
- package/dist/util/dependencyGraph.js.map +1 -0
- package/dist/util/fileLock.js +204 -0
- package/dist/util/fileLock.js.map +1 -0
- package/dist/util/general.js +5 -5
- package/dist/util/general.js.map +1 -1
- package/dist/util/gitMutex.js +116 -0
- package/dist/util/gitMutex.js.map +1 -0
- package/dist/util/mutex.js +96 -0
- package/dist/util/mutex.js.map +1 -0
- package/dist/util/performance.js +4 -4
- package/dist/util/performance.js.map +1 -1
- package/dist/util/safety.js +4 -4
- package/dist/util/safety.js.map +1 -1
- package/dist/util/storage.js +2 -2
- package/dist/util/storage.js.map +1 -1
- package/package.json +6 -6
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ProgressFormatter creates beautiful formatted output for parallel execution
|
|
3
|
+
*/ class ProgressFormatter {
|
|
4
|
+
/**
|
|
5
|
+
* Create a visual progress bar
|
|
6
|
+
*/ static createProgressBar(current, total, width = 30) {
|
|
7
|
+
const percent = total > 0 ? current / total : 0;
|
|
8
|
+
const filled = Math.round(width * percent);
|
|
9
|
+
const empty = width - filled;
|
|
10
|
+
return '█'.repeat(filled) + '░'.repeat(empty);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Format duration in human-readable format
|
|
14
|
+
*/ static formatDuration(ms) {
|
|
15
|
+
if (ms < 1000) {
|
|
16
|
+
return `${ms}ms`;
|
|
17
|
+
}
|
|
18
|
+
const seconds = Math.floor(ms / 1000);
|
|
19
|
+
const minutes = Math.floor(seconds / 60);
|
|
20
|
+
const hours = Math.floor(minutes / 60);
|
|
21
|
+
if (hours > 0) {
|
|
22
|
+
return `${hours}h ${minutes % 60}m ${seconds % 60}s`;
|
|
23
|
+
}
|
|
24
|
+
if (minutes > 0) {
|
|
25
|
+
return `${minutes}m ${seconds % 60}s`;
|
|
26
|
+
}
|
|
27
|
+
return `${seconds}s`;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Format bytes in human-readable format
|
|
31
|
+
*/ static formatBytes(bytes) {
|
|
32
|
+
const units = [
|
|
33
|
+
'B',
|
|
34
|
+
'KB',
|
|
35
|
+
'MB',
|
|
36
|
+
'GB'
|
|
37
|
+
];
|
|
38
|
+
let value = bytes;
|
|
39
|
+
let unitIndex = 0;
|
|
40
|
+
while(value >= 1024 && unitIndex < units.length - 1){
|
|
41
|
+
value /= 1024;
|
|
42
|
+
unitIndex++;
|
|
43
|
+
}
|
|
44
|
+
return `${value.toFixed(2)} ${units[unitIndex]}`;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Format percentage
|
|
48
|
+
*/ static formatPercent(value, decimals = 1) {
|
|
49
|
+
return `${value.toFixed(decimals)}%`;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Create execution summary table
|
|
53
|
+
*/ static createSummaryTable(result) {
|
|
54
|
+
const lines = [];
|
|
55
|
+
lines.push('');
|
|
56
|
+
lines.push('═══════════════════════════════════════════════');
|
|
57
|
+
lines.push(' Parallel Execution Summary');
|
|
58
|
+
lines.push('═══════════════════════════════════════════════');
|
|
59
|
+
lines.push('');
|
|
60
|
+
// Status
|
|
61
|
+
const status = result.success ? '✅ SUCCESS' : '⚠️ PARTIAL SUCCESS';
|
|
62
|
+
lines.push(`Status: ${status}`);
|
|
63
|
+
lines.push('');
|
|
64
|
+
// Package summary
|
|
65
|
+
lines.push('📦 Package Summary:');
|
|
66
|
+
lines.push(` Completed: ${result.completed.length}/${result.totalPackages}`);
|
|
67
|
+
if (result.failed.length > 0) {
|
|
68
|
+
lines.push(` Failed: ${result.failed.length}`);
|
|
69
|
+
}
|
|
70
|
+
if (result.skipped.length > 0) {
|
|
71
|
+
lines.push(` Skipped: ${result.skipped.length}`);
|
|
72
|
+
}
|
|
73
|
+
lines.push('');
|
|
74
|
+
// Performance metrics
|
|
75
|
+
lines.push(...this.createMetricsTable(result.metrics));
|
|
76
|
+
// Failed packages details
|
|
77
|
+
if (result.failed.length > 0) {
|
|
78
|
+
lines.push('');
|
|
79
|
+
lines.push('❌ Failed Packages:');
|
|
80
|
+
for (const failure of result.failed){
|
|
81
|
+
lines.push(` • ${failure.name}`);
|
|
82
|
+
lines.push(` Error: ${failure.error}`);
|
|
83
|
+
if (failure.dependents.length > 0) {
|
|
84
|
+
lines.push(` Blocked: ${failure.dependents.length} dependent(s)`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
lines.push('');
|
|
89
|
+
lines.push('═══════════════════════════════════════════════');
|
|
90
|
+
lines.push('');
|
|
91
|
+
return lines;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Create metrics table
|
|
95
|
+
*/ static createMetricsTable(metrics) {
|
|
96
|
+
const lines = [];
|
|
97
|
+
lines.push('⚡ Performance Metrics:');
|
|
98
|
+
lines.push(` Total Time: ${this.formatDuration(metrics.totalDuration)}`);
|
|
99
|
+
lines.push(` Avg Per Package: ${this.formatDuration(metrics.averagePackageDuration)}`);
|
|
100
|
+
lines.push(` Peak Concurrency: ${metrics.peakConcurrency}`);
|
|
101
|
+
lines.push(` Average Concurrency: ${metrics.averageConcurrency.toFixed(1)}`);
|
|
102
|
+
if (metrics.speedupVsSequential) {
|
|
103
|
+
lines.push(` Speedup: ${metrics.speedupVsSequential.toFixed(2)}x 🚀`);
|
|
104
|
+
}
|
|
105
|
+
return lines;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Create compact progress indicator
|
|
109
|
+
*/ static createCompactProgress(completed, total, running) {
|
|
110
|
+
const percent = total > 0 ? Math.round(completed / total * 100) : 0;
|
|
111
|
+
const bar = this.createProgressBar(completed, total, 20);
|
|
112
|
+
return `[${bar}] ${percent}% (${completed}/${total}) ${running > 0 ? `| Running: ${running}` : ''}`;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Create execution timeline visualization
|
|
116
|
+
*/ static createTimeline(packageTimes, maxConcurrency) {
|
|
117
|
+
const lines = [];
|
|
118
|
+
lines.push('');
|
|
119
|
+
lines.push('📊 Execution Timeline:');
|
|
120
|
+
lines.push('');
|
|
121
|
+
// Find time bounds
|
|
122
|
+
let minTime = Infinity;
|
|
123
|
+
let maxTime = 0;
|
|
124
|
+
for (const [, times] of packageTimes){
|
|
125
|
+
minTime = Math.min(minTime, times.start);
|
|
126
|
+
maxTime = Math.max(maxTime, times.end);
|
|
127
|
+
}
|
|
128
|
+
const totalDuration = maxTime - minTime;
|
|
129
|
+
const timelineWidth = 50;
|
|
130
|
+
// Sort by start time
|
|
131
|
+
const sortedPackages = Array.from(packageTimes.entries()).sort(([, a], [, b])=>a.start - b.start);
|
|
132
|
+
for (const [pkg, times] of sortedPackages){
|
|
133
|
+
const start = times.start - minTime;
|
|
134
|
+
const duration = times.end - times.start;
|
|
135
|
+
const startPos = Math.floor(start / totalDuration * timelineWidth);
|
|
136
|
+
const barLength = Math.max(1, Math.floor(duration / totalDuration * timelineWidth));
|
|
137
|
+
const timeline = ' '.repeat(startPos) + '█'.repeat(barLength);
|
|
138
|
+
const durationStr = this.formatDuration(duration);
|
|
139
|
+
lines.push(` ${pkg.padEnd(20)} │${timeline.padEnd(timelineWidth)}│ ${durationStr}`);
|
|
140
|
+
}
|
|
141
|
+
lines.push('');
|
|
142
|
+
lines.push(` Total: ${this.formatDuration(totalDuration)} with max concurrency ${maxConcurrency}`);
|
|
143
|
+
lines.push('');
|
|
144
|
+
return lines;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Create box around text
|
|
148
|
+
*/ static createBox(title, content, width = 60) {
|
|
149
|
+
const lines = [];
|
|
150
|
+
const topBorder = '╔' + '═'.repeat(width - 2) + '╗';
|
|
151
|
+
const bottomBorder = '╚' + '═'.repeat(width - 2) + '╝';
|
|
152
|
+
const titleLine = '║ ' + title.padEnd(width - 4) + ' ║';
|
|
153
|
+
lines.push(topBorder);
|
|
154
|
+
lines.push(titleLine);
|
|
155
|
+
lines.push('╠' + '═'.repeat(width - 2) + '╣');
|
|
156
|
+
for (const line of content){
|
|
157
|
+
const paddedLine = '║ ' + line.padEnd(width - 4) + ' ║';
|
|
158
|
+
lines.push(paddedLine);
|
|
159
|
+
}
|
|
160
|
+
lines.push(bottomBorder);
|
|
161
|
+
return lines;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Format speedup comparison
|
|
165
|
+
*/ static createSpeedupComparison(parallelTime, sequentialTime, concurrency) {
|
|
166
|
+
const lines = [];
|
|
167
|
+
const speedup = sequentialTime / parallelTime;
|
|
168
|
+
const efficiency = speedup / concurrency * 100;
|
|
169
|
+
const timeSaved = sequentialTime - parallelTime;
|
|
170
|
+
lines.push('');
|
|
171
|
+
lines.push('📈 Speedup Analysis:');
|
|
172
|
+
lines.push(` Sequential Time: ${this.formatDuration(sequentialTime)}`);
|
|
173
|
+
lines.push(` Parallel Time: ${this.formatDuration(parallelTime)}`);
|
|
174
|
+
lines.push(` Speedup: ${speedup.toFixed(2)}x 🚀`);
|
|
175
|
+
lines.push(` Efficiency: ${this.formatPercent(efficiency)}`);
|
|
176
|
+
lines.push(` Time Saved: ${this.formatDuration(timeSaved)} ⏰`);
|
|
177
|
+
lines.push('');
|
|
178
|
+
return lines;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Create error summary
|
|
182
|
+
*/ static createErrorSummary(failures) {
|
|
183
|
+
const lines = [];
|
|
184
|
+
if (failures.length === 0) {
|
|
185
|
+
return lines;
|
|
186
|
+
}
|
|
187
|
+
lines.push('');
|
|
188
|
+
lines.push('❌ Failure Summary:');
|
|
189
|
+
lines.push('');
|
|
190
|
+
for (const failure of failures){
|
|
191
|
+
lines.push(` ${failure.name}:`);
|
|
192
|
+
lines.push(` Error: ${failure.error}`);
|
|
193
|
+
if (failure.dependents.length > 0) {
|
|
194
|
+
const dependentStr = failure.dependents.slice(0, 3).join(', ');
|
|
195
|
+
const more = failure.dependents.length > 3 ? ` +${failure.dependents.length - 3} more` : '';
|
|
196
|
+
lines.push(` Blocked: ${dependentStr}${more}`);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
lines.push('');
|
|
200
|
+
return lines;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Create recovery guidance
|
|
204
|
+
*/ static createRecoveryGuidance(hasRetriable, hasPermanent) {
|
|
205
|
+
const lines = [];
|
|
206
|
+
lines.push('');
|
|
207
|
+
lines.push('🔧 Recovery Options:');
|
|
208
|
+
lines.push('');
|
|
209
|
+
if (hasRetriable) {
|
|
210
|
+
lines.push(' 1. Retry failed packages:');
|
|
211
|
+
lines.push(' kodrdriv tree [command] --continue --retry-failed');
|
|
212
|
+
lines.push('');
|
|
213
|
+
}
|
|
214
|
+
if (hasPermanent) {
|
|
215
|
+
lines.push(' 2. Skip failed packages:');
|
|
216
|
+
lines.push(' kodrdriv tree [command] --continue --skip-failed');
|
|
217
|
+
lines.push('');
|
|
218
|
+
}
|
|
219
|
+
lines.push(' 3. Mark specific package as completed:');
|
|
220
|
+
lines.push(' kodrdriv tree [command] --continue --mark-completed "directory-name"');
|
|
221
|
+
lines.push('');
|
|
222
|
+
lines.push(' 4. Check detailed status:');
|
|
223
|
+
lines.push(' kodrdriv tree --status-parallel');
|
|
224
|
+
lines.push('');
|
|
225
|
+
return lines;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export { ProgressFormatter };
|
|
230
|
+
//# sourceMappingURL=ProgressFormatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProgressFormatter.js","sources":["../../src/ui/ProgressFormatter.ts"],"sourcesContent":["import { ExecutionResult, ExecutionMetrics } from '../types/parallelExecution';\n\n/**\n * ProgressFormatter creates beautiful formatted output for parallel execution\n */\nexport class ProgressFormatter {\n /**\n * Create a visual progress bar\n */\n static createProgressBar(current: number, total: number, width: number = 30): string {\n const percent = total > 0 ? current / total : 0;\n const filled = Math.round(width * percent);\n const empty = width - filled;\n\n return '█'.repeat(filled) + '░'.repeat(empty);\n }\n\n /**\n * Format duration in human-readable format\n */\n static formatDuration(ms: number): string {\n if (ms < 1000) {\n return `${ms}ms`;\n }\n\n const seconds = Math.floor(ms / 1000);\n const minutes = Math.floor(seconds / 60);\n const hours = Math.floor(minutes / 60);\n\n if (hours > 0) {\n return `${hours}h ${minutes % 60}m ${seconds % 60}s`;\n }\n if (minutes > 0) {\n return `${minutes}m ${seconds % 60}s`;\n }\n return `${seconds}s`;\n }\n\n /**\n * Format bytes in human-readable format\n */\n static formatBytes(bytes: number): string {\n const units = ['B', 'KB', 'MB', 'GB'];\n let value = bytes;\n let unitIndex = 0;\n\n while (value >= 1024 && unitIndex < units.length - 1) {\n value /= 1024;\n unitIndex++;\n }\n\n return `${value.toFixed(2)} ${units[unitIndex]}`;\n }\n\n /**\n * Format percentage\n */\n static formatPercent(value: number, decimals: number = 1): string {\n return `${value.toFixed(decimals)}%`;\n }\n\n /**\n * Create execution summary table\n */\n static createSummaryTable(result: ExecutionResult): string[] {\n const lines: string[] = [];\n\n lines.push('');\n lines.push('═══════════════════════════════════════════════');\n lines.push(' Parallel Execution Summary');\n lines.push('═══════════════════════════════════════════════');\n lines.push('');\n\n // Status\n const status = result.success ? '✅ SUCCESS' : '⚠️ PARTIAL SUCCESS';\n lines.push(`Status: ${status}`);\n lines.push('');\n\n // Package summary\n lines.push('📦 Package Summary:');\n lines.push(` Completed: ${result.completed.length}/${result.totalPackages}`);\n if (result.failed.length > 0) {\n lines.push(` Failed: ${result.failed.length}`);\n }\n if (result.skipped.length > 0) {\n lines.push(` Skipped: ${result.skipped.length}`);\n }\n lines.push('');\n\n // Performance metrics\n lines.push(...this.createMetricsTable(result.metrics));\n\n // Failed packages details\n if (result.failed.length > 0) {\n lines.push('');\n lines.push('❌ Failed Packages:');\n for (const failure of result.failed) {\n lines.push(` • ${failure.name}`);\n lines.push(` Error: ${failure.error}`);\n if (failure.dependents.length > 0) {\n lines.push(` Blocked: ${failure.dependents.length} dependent(s)`);\n }\n }\n }\n\n lines.push('');\n lines.push('═══════════════════════════════════════════════');\n lines.push('');\n\n return lines;\n }\n\n /**\n * Create metrics table\n */\n static createMetricsTable(metrics: ExecutionMetrics): string[] {\n const lines: string[] = [];\n\n lines.push('⚡ Performance Metrics:');\n lines.push(` Total Time: ${this.formatDuration(metrics.totalDuration)}`);\n lines.push(` Avg Per Package: ${this.formatDuration(metrics.averagePackageDuration)}`);\n lines.push(` Peak Concurrency: ${metrics.peakConcurrency}`);\n lines.push(` Average Concurrency: ${metrics.averageConcurrency.toFixed(1)}`);\n\n if (metrics.speedupVsSequential) {\n lines.push(` Speedup: ${metrics.speedupVsSequential.toFixed(2)}x 🚀`);\n }\n\n return lines;\n }\n\n /**\n * Create compact progress indicator\n */\n static createCompactProgress(completed: number, total: number, running: number): string {\n const percent = total > 0 ? Math.round((completed / total) * 100) : 0;\n const bar = this.createProgressBar(completed, total, 20);\n\n return `[${bar}] ${percent}% (${completed}/${total}) ${running > 0 ? `| Running: ${running}` : ''}`;\n }\n\n /**\n * Create execution timeline visualization\n */\n static createTimeline(\n packageTimes: Map<string, { start: number; end: number }>,\n maxConcurrency: number\n ): string[] {\n const lines: string[] = [];\n\n lines.push('');\n lines.push('📊 Execution Timeline:');\n lines.push('');\n\n // Find time bounds\n let minTime = Infinity;\n let maxTime = 0;\n\n for (const [, times] of packageTimes) {\n minTime = Math.min(minTime, times.start);\n maxTime = Math.max(maxTime, times.end);\n }\n\n const totalDuration = maxTime - minTime;\n const timelineWidth = 50;\n\n // Sort by start time\n const sortedPackages = Array.from(packageTimes.entries())\n .sort(([, a], [, b]) => a.start - b.start);\n\n for (const [pkg, times] of sortedPackages) {\n const start = times.start - minTime;\n const duration = times.end - times.start;\n\n const startPos = Math.floor((start / totalDuration) * timelineWidth);\n const barLength = Math.max(1, Math.floor((duration / totalDuration) * timelineWidth));\n\n const timeline = ' '.repeat(startPos) + '█'.repeat(barLength);\n const durationStr = this.formatDuration(duration);\n\n lines.push(` ${pkg.padEnd(20)} │${timeline.padEnd(timelineWidth)}│ ${durationStr}`);\n }\n\n lines.push('');\n lines.push(` Total: ${this.formatDuration(totalDuration)} with max concurrency ${maxConcurrency}`);\n lines.push('');\n\n return lines;\n }\n\n /**\n * Create box around text\n */\n static createBox(title: string, content: string[], width: number = 60): string[] {\n const lines: string[] = [];\n\n const topBorder = '╔' + '═'.repeat(width - 2) + '╗';\n const bottomBorder = '╚' + '═'.repeat(width - 2) + '╝';\n const titleLine = '║ ' + title.padEnd(width - 4) + ' ║';\n\n lines.push(topBorder);\n lines.push(titleLine);\n lines.push('╠' + '═'.repeat(width - 2) + '╣');\n\n for (const line of content) {\n const paddedLine = '║ ' + line.padEnd(width - 4) + ' ║';\n lines.push(paddedLine);\n }\n\n lines.push(bottomBorder);\n\n return lines;\n }\n\n /**\n * Format speedup comparison\n */\n static createSpeedupComparison(\n parallelTime: number,\n sequentialTime: number,\n concurrency: number\n ): string[] {\n const lines: string[] = [];\n\n const speedup = sequentialTime / parallelTime;\n const efficiency = (speedup / concurrency) * 100;\n const timeSaved = sequentialTime - parallelTime;\n\n lines.push('');\n lines.push('📈 Speedup Analysis:');\n lines.push(` Sequential Time: ${this.formatDuration(sequentialTime)}`);\n lines.push(` Parallel Time: ${this.formatDuration(parallelTime)}`);\n lines.push(` Speedup: ${speedup.toFixed(2)}x 🚀`);\n lines.push(` Efficiency: ${this.formatPercent(efficiency)}`);\n lines.push(` Time Saved: ${this.formatDuration(timeSaved)} ⏰`);\n lines.push('');\n\n return lines;\n }\n\n /**\n * Create error summary\n */\n static createErrorSummary(failures: Array<{ name: string; error: string; dependents: string[] }>): string[] {\n const lines: string[] = [];\n\n if (failures.length === 0) {\n return lines;\n }\n\n lines.push('');\n lines.push('❌ Failure Summary:');\n lines.push('');\n\n for (const failure of failures) {\n lines.push(` ${failure.name}:`);\n lines.push(` Error: ${failure.error}`);\n\n if (failure.dependents.length > 0) {\n const dependentStr = failure.dependents.slice(0, 3).join(', ');\n const more = failure.dependents.length > 3 ? ` +${failure.dependents.length - 3} more` : '';\n lines.push(` Blocked: ${dependentStr}${more}`);\n }\n }\n\n lines.push('');\n\n return lines;\n }\n\n /**\n * Create recovery guidance\n */\n static createRecoveryGuidance(hasRetriable: boolean, hasPermanent: boolean): string[] {\n const lines: string[] = [];\n\n lines.push('');\n lines.push('🔧 Recovery Options:');\n lines.push('');\n\n if (hasRetriable) {\n lines.push(' 1. Retry failed packages:');\n lines.push(' kodrdriv tree [command] --continue --retry-failed');\n lines.push('');\n }\n\n if (hasPermanent) {\n lines.push(' 2. Skip failed packages:');\n lines.push(' kodrdriv tree [command] --continue --skip-failed');\n lines.push('');\n }\n\n lines.push(' 3. Mark specific package as completed:');\n lines.push(' kodrdriv tree [command] --continue --mark-completed \"directory-name\"');\n lines.push('');\n\n lines.push(' 4. Check detailed status:');\n lines.push(' kodrdriv tree --status-parallel');\n lines.push('');\n\n return lines;\n }\n}\n"],"names":["ProgressFormatter","createProgressBar","current","total","width","percent","filled","Math","round","empty","repeat","formatDuration","ms","seconds","floor","minutes","hours","formatBytes","bytes","units","value","unitIndex","length","toFixed","formatPercent","decimals","createSummaryTable","result","lines","push","status","success","completed","totalPackages","failed","skipped","createMetricsTable","metrics","failure","name","error","dependents","totalDuration","averagePackageDuration","peakConcurrency","averageConcurrency","speedupVsSequential","createCompactProgress","running","bar","createTimeline","packageTimes","maxConcurrency","minTime","Infinity","maxTime","times","min","start","max","end","timelineWidth","sortedPackages","Array","from","entries","sort","a","b","pkg","duration","startPos","barLength","timeline","durationStr","padEnd","createBox","title","content","topBorder","bottomBorder","titleLine","line","paddedLine","createSpeedupComparison","parallelTime","sequentialTime","concurrency","speedup","efficiency","timeSaved","createErrorSummary","failures","dependentStr","slice","join","more","createRecoveryGuidance","hasRetriable","hasPermanent"],"mappings":"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"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import path__default from 'path';
|
|
2
|
+
import fs from 'fs/promises';
|
|
3
|
+
import { getLogger } from '../logging.js';
|
|
4
|
+
import { create } from './storage.js';
|
|
5
|
+
|
|
6
|
+
function _define_property(obj, key, value) {
|
|
7
|
+
if (key in obj) {
|
|
8
|
+
Object.defineProperty(obj, key, {
|
|
9
|
+
value: value,
|
|
10
|
+
enumerable: true,
|
|
11
|
+
configurable: true,
|
|
12
|
+
writable: true
|
|
13
|
+
});
|
|
14
|
+
} else {
|
|
15
|
+
obj[key] = value;
|
|
16
|
+
}
|
|
17
|
+
return obj;
|
|
18
|
+
}
|
|
19
|
+
const CHECKPOINT_VERSION = '1.0.0';
|
|
20
|
+
class CheckpointManager {
|
|
21
|
+
async save(checkpoint) {
|
|
22
|
+
const lock = await this.acquireLock();
|
|
23
|
+
try {
|
|
24
|
+
// Set version and timestamp
|
|
25
|
+
checkpoint.version = CHECKPOINT_VERSION;
|
|
26
|
+
checkpoint.lastUpdated = new Date().toISOString();
|
|
27
|
+
// Validate before saving
|
|
28
|
+
this.validateCheckpoint(checkpoint);
|
|
29
|
+
// Write to temp file
|
|
30
|
+
const serialized = JSON.stringify(checkpoint, null, 2);
|
|
31
|
+
await fs.writeFile(this.tempPath, serialized, 'utf-8');
|
|
32
|
+
// Atomic rename
|
|
33
|
+
await fs.rename(this.tempPath, this.checkpointPath);
|
|
34
|
+
this.logger.debug(`Checkpoint saved: ${this.checkpointPath}`);
|
|
35
|
+
} finally{
|
|
36
|
+
await lock.release();
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
async load() {
|
|
40
|
+
if (!await this.storage.exists(this.checkpointPath)) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
const lock = await this.acquireLock();
|
|
44
|
+
try {
|
|
45
|
+
const content = await fs.readFile(this.checkpointPath, 'utf-8');
|
|
46
|
+
const checkpoint = JSON.parse(content);
|
|
47
|
+
// Validate
|
|
48
|
+
this.validateCheckpoint(checkpoint);
|
|
49
|
+
// Check version
|
|
50
|
+
if (!this.isCompatibleVersion(checkpoint.version)) {
|
|
51
|
+
throw new Error(`Incompatible checkpoint version: ${checkpoint.version}`);
|
|
52
|
+
}
|
|
53
|
+
return checkpoint;
|
|
54
|
+
} catch (error) {
|
|
55
|
+
this.logger.error(`Failed to load checkpoint: ${error.message}`);
|
|
56
|
+
// Try backup
|
|
57
|
+
const backup = await this.loadBackup();
|
|
58
|
+
if (backup) {
|
|
59
|
+
this.logger.info('Recovered from backup checkpoint');
|
|
60
|
+
return backup;
|
|
61
|
+
}
|
|
62
|
+
return null;
|
|
63
|
+
} finally{
|
|
64
|
+
await lock.release();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
async backup() {
|
|
68
|
+
if (!await this.storage.exists(this.checkpointPath)) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const backupPath = `${this.checkpointPath}.backup`;
|
|
72
|
+
await fs.copyFile(this.checkpointPath, backupPath);
|
|
73
|
+
}
|
|
74
|
+
async cleanup() {
|
|
75
|
+
const files = [
|
|
76
|
+
this.checkpointPath,
|
|
77
|
+
this.lockPath,
|
|
78
|
+
this.tempPath,
|
|
79
|
+
`${this.checkpointPath}.backup`
|
|
80
|
+
];
|
|
81
|
+
await Promise.all(files.map((file)=>fs.unlink(file).catch(()=>{})));
|
|
82
|
+
}
|
|
83
|
+
async acquireLock() {
|
|
84
|
+
const maxWaitMs = 30000;
|
|
85
|
+
const startTime = Date.now();
|
|
86
|
+
while(true){
|
|
87
|
+
try {
|
|
88
|
+
const fileHandle = await fs.open(this.lockPath, 'wx');
|
|
89
|
+
try {
|
|
90
|
+
const pid = process.pid;
|
|
91
|
+
const timestamp = new Date().toISOString();
|
|
92
|
+
await fileHandle.writeFile(`${pid}\n${timestamp}`);
|
|
93
|
+
} finally{
|
|
94
|
+
await fileHandle.close();
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
release: async ()=>{
|
|
98
|
+
await fs.unlink(this.lockPath).catch(()=>{});
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
} catch (error) {
|
|
102
|
+
if (error.code !== 'EEXIST') {
|
|
103
|
+
throw error;
|
|
104
|
+
}
|
|
105
|
+
const elapsed = Date.now() - startTime;
|
|
106
|
+
if (elapsed > maxWaitMs) {
|
|
107
|
+
this.logger.warn('Breaking stale checkpoint lock');
|
|
108
|
+
await fs.unlink(this.lockPath).catch(()=>{});
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
await new Promise((resolve)=>setTimeout(resolve, 100));
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
validateCheckpoint(checkpoint) {
|
|
116
|
+
if (!checkpoint.executionId) {
|
|
117
|
+
throw new Error('Invalid checkpoint: missing executionId');
|
|
118
|
+
}
|
|
119
|
+
if (!checkpoint.state) {
|
|
120
|
+
throw new Error('Invalid checkpoint: missing state');
|
|
121
|
+
}
|
|
122
|
+
// Validate state consistency
|
|
123
|
+
const allPackages = new Set([
|
|
124
|
+
...checkpoint.state.pending,
|
|
125
|
+
...checkpoint.state.ready,
|
|
126
|
+
...checkpoint.state.running.map((r)=>r.name),
|
|
127
|
+
...checkpoint.state.completed,
|
|
128
|
+
...checkpoint.state.failed.map((f)=>f.name),
|
|
129
|
+
...checkpoint.state.skipped
|
|
130
|
+
]);
|
|
131
|
+
if (allPackages.size !== checkpoint.buildOrder.length) {
|
|
132
|
+
this.logger.warn('Checkpoint state inconsistency detected');
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
isCompatibleVersion(version) {
|
|
136
|
+
// Simple major version check
|
|
137
|
+
const [major] = version.split('.');
|
|
138
|
+
const [expectedMajor] = CHECKPOINT_VERSION.split('.');
|
|
139
|
+
return major === expectedMajor;
|
|
140
|
+
}
|
|
141
|
+
async loadBackup() {
|
|
142
|
+
const backupPath = `${this.checkpointPath}.backup`;
|
|
143
|
+
if (!await this.storage.exists(backupPath)) {
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
try {
|
|
147
|
+
const content = await fs.readFile(backupPath, 'utf-8');
|
|
148
|
+
return JSON.parse(content);
|
|
149
|
+
} catch {
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
constructor(outputDirectory = process.cwd()){
|
|
154
|
+
_define_property(this, "checkpointPath", void 0);
|
|
155
|
+
_define_property(this, "lockPath", void 0);
|
|
156
|
+
_define_property(this, "tempPath", void 0);
|
|
157
|
+
_define_property(this, "logger", getLogger());
|
|
158
|
+
_define_property(this, "storage", create({
|
|
159
|
+
log: this.logger.info
|
|
160
|
+
}));
|
|
161
|
+
this.checkpointPath = path__default.join(outputDirectory, '.kodrdriv-parallel-context.json');
|
|
162
|
+
this.lockPath = `${this.checkpointPath}.lock`;
|
|
163
|
+
this.tempPath = `${this.checkpointPath}.tmp`;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export { CheckpointManager };
|
|
168
|
+
//# sourceMappingURL=checkpointManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkpointManager.js","sources":["../../src/util/checkpointManager.ts"],"sourcesContent":["import path from 'path';\nimport fs from 'fs/promises';\nimport { getLogger } from '../logging';\nimport { ParallelExecutionCheckpoint } from '../types/parallelExecution';\nimport { create as createStorage } from './storage';\n\nconst CHECKPOINT_VERSION = '1.0.0';\n\ninterface Lock {\n release: () => Promise<void>;\n}\n\nexport class CheckpointManager {\n private checkpointPath: string;\n private lockPath: string;\n private tempPath: string;\n private logger = getLogger();\n private storage = createStorage({ log: this.logger.info });\n\n constructor(outputDirectory: string = process.cwd()) {\n this.checkpointPath = path.join(outputDirectory, '.kodrdriv-parallel-context.json');\n this.lockPath = `${this.checkpointPath}.lock`;\n this.tempPath = `${this.checkpointPath}.tmp`;\n }\n\n async save(checkpoint: ParallelExecutionCheckpoint): Promise<void> {\n const lock = await this.acquireLock();\n\n try {\n // Set version and timestamp\n checkpoint.version = CHECKPOINT_VERSION;\n checkpoint.lastUpdated = new Date().toISOString();\n\n // Validate before saving\n this.validateCheckpoint(checkpoint);\n\n // Write to temp file\n const serialized = JSON.stringify(checkpoint, null, 2);\n await fs.writeFile(this.tempPath, serialized, 'utf-8');\n\n // Atomic rename\n await fs.rename(this.tempPath, this.checkpointPath);\n\n this.logger.debug(`Checkpoint saved: ${this.checkpointPath}`);\n } finally {\n await lock.release();\n }\n }\n\n async load(): Promise<ParallelExecutionCheckpoint | null> {\n if (!await this.storage.exists(this.checkpointPath)) {\n return null;\n }\n\n const lock = await this.acquireLock();\n\n try {\n const content = await fs.readFile(this.checkpointPath, 'utf-8');\n const checkpoint = JSON.parse(content) as ParallelExecutionCheckpoint;\n\n // Validate\n this.validateCheckpoint(checkpoint);\n\n // Check version\n if (!this.isCompatibleVersion(checkpoint.version)) {\n throw new Error(`Incompatible checkpoint version: ${checkpoint.version}`);\n }\n\n return checkpoint;\n } catch (error: any) {\n this.logger.error(`Failed to load checkpoint: ${error.message}`);\n\n // Try backup\n const backup = await this.loadBackup();\n if (backup) {\n this.logger.info('Recovered from backup checkpoint');\n return backup;\n }\n\n return null;\n } finally {\n await lock.release();\n }\n }\n\n async backup(): Promise<void> {\n if (!await this.storage.exists(this.checkpointPath)) {\n return;\n }\n\n const backupPath = `${this.checkpointPath}.backup`;\n await fs.copyFile(this.checkpointPath, backupPath);\n }\n\n async cleanup(): Promise<void> {\n const files = [\n this.checkpointPath,\n this.lockPath,\n this.tempPath,\n `${this.checkpointPath}.backup`\n ];\n\n await Promise.all(\n files.map(file => fs.unlink(file).catch(() => {}))\n );\n }\n\n private async acquireLock(): Promise<Lock> {\n const maxWaitMs = 30000;\n const startTime = Date.now();\n\n while (true) {\n try {\n const fileHandle = await fs.open(this.lockPath, 'wx');\n try {\n const pid = process.pid;\n const timestamp = new Date().toISOString();\n await fileHandle.writeFile(`${pid}\\n${timestamp}`);\n } finally {\n await fileHandle.close();\n }\n\n return {\n release: async () => {\n await fs.unlink(this.lockPath).catch(() => {});\n }\n };\n } catch (error: any) {\n if (error.code !== 'EEXIST') {\n throw error;\n }\n\n const elapsed = Date.now() - startTime;\n if (elapsed > maxWaitMs) {\n this.logger.warn('Breaking stale checkpoint lock');\n await fs.unlink(this.lockPath).catch(() => {});\n continue;\n }\n\n await new Promise(resolve => setTimeout(resolve, 100));\n }\n }\n }\n\n private validateCheckpoint(checkpoint: ParallelExecutionCheckpoint): void {\n if (!checkpoint.executionId) {\n throw new Error('Invalid checkpoint: missing executionId');\n }\n\n if (!checkpoint.state) {\n throw new Error('Invalid checkpoint: missing state');\n }\n\n // Validate state consistency\n const allPackages = new Set([\n ...checkpoint.state.pending,\n ...checkpoint.state.ready,\n ...checkpoint.state.running.map(r => r.name),\n ...checkpoint.state.completed,\n ...checkpoint.state.failed.map(f => f.name),\n ...checkpoint.state.skipped\n ]);\n\n if (allPackages.size !== checkpoint.buildOrder.length) {\n this.logger.warn('Checkpoint state inconsistency detected');\n }\n }\n\n private isCompatibleVersion(version: string): boolean {\n // Simple major version check\n const [major] = version.split('.');\n const [expectedMajor] = CHECKPOINT_VERSION.split('.');\n return major === expectedMajor;\n }\n\n private async loadBackup(): Promise<ParallelExecutionCheckpoint | null> {\n const backupPath = `${this.checkpointPath}.backup`;\n if (!await this.storage.exists(backupPath)) {\n return null;\n }\n\n try {\n const content = await fs.readFile(backupPath, 'utf-8');\n return JSON.parse(content) as ParallelExecutionCheckpoint;\n } catch {\n return null;\n }\n }\n}\n"],"names":["CHECKPOINT_VERSION","CheckpointManager","save","checkpoint","lock","acquireLock","version","lastUpdated","Date","toISOString","validateCheckpoint","serialized","JSON","stringify","fs","writeFile","tempPath","rename","checkpointPath","logger","debug","release","load","storage","exists","content","readFile","parse","isCompatibleVersion","Error","error","message","backup","loadBackup","info","backupPath","copyFile","cleanup","files","lockPath","Promise","all","map","file","unlink","catch","maxWaitMs","startTime","now","fileHandle","open","pid","process","timestamp","close","code","elapsed","warn","resolve","setTimeout","executionId","state","allPackages","Set","pending","ready","running","r","name","completed","failed","f","skipped","size","buildOrder","length","major","split","expectedMajor","outputDirectory","cwd","getLogger","createStorage","log","path","join"],"mappings":"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"}
|