@eldrforge/kodrdriv 1.2.23 → 1.2.25

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 (67) hide show
  1. package/PARALLEL-EXECUTION-FIXES.md +132 -0
  2. package/PARALLEL_EXECUTION_FIX.md +146 -0
  3. package/RECOVERY-FIXES.md +72 -0
  4. package/SUBMODULE-LOCK-FIX.md +132 -0
  5. package/dist/arguments.js +26 -3
  6. package/dist/arguments.js.map +1 -1
  7. package/dist/commands/audio-commit.js +3 -3
  8. package/dist/commands/audio-commit.js.map +1 -1
  9. package/dist/commands/audio-review.js +13 -13
  10. package/dist/commands/audio-review.js.map +1 -1
  11. package/dist/commands/link.js +13 -13
  12. package/dist/commands/link.js.map +1 -1
  13. package/dist/commands/publish.js +200 -146
  14. package/dist/commands/publish.js.map +1 -1
  15. package/dist/commands/review.js +6 -6
  16. package/dist/commands/review.js.map +1 -1
  17. package/dist/commands/select-audio.js +4 -4
  18. package/dist/commands/select-audio.js.map +1 -1
  19. package/dist/commands/tree.js +242 -318
  20. package/dist/commands/tree.js.map +1 -1
  21. package/dist/commands/unlink.js +8 -8
  22. package/dist/commands/unlink.js.map +1 -1
  23. package/dist/commands/versions.js +3 -3
  24. package/dist/commands/versions.js.map +1 -1
  25. package/dist/constants.js +4 -4
  26. package/dist/constants.js.map +1 -1
  27. package/dist/content/diff.js +5 -2
  28. package/dist/content/diff.js.map +1 -1
  29. package/dist/content/files.js +4 -4
  30. package/dist/content/files.js.map +1 -1
  31. package/dist/execution/CommandValidator.js +160 -0
  32. package/dist/execution/CommandValidator.js.map +1 -0
  33. package/dist/execution/DependencyChecker.js +102 -0
  34. package/dist/execution/DependencyChecker.js.map +1 -0
  35. package/dist/execution/DynamicTaskPool.js +455 -0
  36. package/dist/execution/DynamicTaskPool.js.map +1 -0
  37. package/dist/execution/RecoveryManager.js +502 -0
  38. package/dist/execution/RecoveryManager.js.map +1 -0
  39. package/dist/execution/ResourceMonitor.js +125 -0
  40. package/dist/execution/ResourceMonitor.js.map +1 -0
  41. package/dist/execution/Scheduler.js +98 -0
  42. package/dist/execution/Scheduler.js.map +1 -0
  43. package/dist/execution/TreeExecutionAdapter.js +170 -0
  44. package/dist/execution/TreeExecutionAdapter.js.map +1 -0
  45. package/dist/logging.js +3 -3
  46. package/dist/logging.js.map +1 -1
  47. package/dist/ui/ProgressFormatter.js +230 -0
  48. package/dist/ui/ProgressFormatter.js.map +1 -0
  49. package/dist/util/checkpointManager.js +168 -0
  50. package/dist/util/checkpointManager.js.map +1 -0
  51. package/dist/util/dependencyGraph.js +224 -0
  52. package/dist/util/dependencyGraph.js.map +1 -0
  53. package/dist/util/fileLock.js +241 -0
  54. package/dist/util/fileLock.js.map +1 -0
  55. package/dist/util/general.js +5 -5
  56. package/dist/util/general.js.map +1 -1
  57. package/dist/util/gitMutex.js +116 -0
  58. package/dist/util/gitMutex.js.map +1 -0
  59. package/dist/util/mutex.js +96 -0
  60. package/dist/util/mutex.js.map +1 -0
  61. package/dist/util/performance.js +4 -4
  62. package/dist/util/performance.js.map +1 -1
  63. package/dist/util/safety.js +4 -4
  64. package/dist/util/safety.js.map +1 -1
  65. package/dist/util/storage.js +2 -2
  66. package/dist/util/storage.js.map +1 -1
  67. package/package.json +6 -6
@@ -0,0 +1,125 @@
1
+ import { getLogger } from '../logging.js';
2
+
3
+ function _define_property(obj, key, value) {
4
+ if (key in obj) {
5
+ Object.defineProperty(obj, key, {
6
+ value: value,
7
+ enumerable: true,
8
+ configurable: true,
9
+ writable: true
10
+ });
11
+ } else {
12
+ obj[key] = value;
13
+ }
14
+ return obj;
15
+ }
16
+ /**
17
+ * ResourceMonitor manages concurrency limits and tracks resource utilization
18
+ */ class ResourceMonitor {
19
+ /**
20
+ * Check if we can allocate N slots
21
+ */ canAllocate(count = 1) {
22
+ return this.currentConcurrency + count <= this.maxConcurrency;
23
+ }
24
+ /**
25
+ * Allocate resource slots
26
+ * @returns true if allocation succeeded, false if not enough slots available
27
+ */ allocate(count = 1) {
28
+ if (!this.canAllocate(count)) {
29
+ return false;
30
+ }
31
+ this.currentConcurrency += count;
32
+ this.metrics.totalAllocations += count;
33
+ this.metrics.peakConcurrency = Math.max(this.metrics.peakConcurrency, this.currentConcurrency);
34
+ this.allocationHistory.push(this.currentConcurrency);
35
+ this.updateAverageConcurrency();
36
+ this.logger.debug(`Allocated ${count} slot(s) (${this.currentConcurrency}/${this.maxConcurrency})`);
37
+ return true;
38
+ }
39
+ /**
40
+ * Release resource slots
41
+ */ release(count = 1) {
42
+ this.currentConcurrency = Math.max(0, this.currentConcurrency - count);
43
+ this.metrics.totalReleases += count;
44
+ this.allocationHistory.push(this.currentConcurrency);
45
+ this.updateAverageConcurrency();
46
+ this.logger.debug(`Released ${count} slot(s) (${this.currentConcurrency}/${this.maxConcurrency})`);
47
+ }
48
+ /**
49
+ * Get number of available slots
50
+ */ getAvailableSlots() {
51
+ return this.maxConcurrency - this.currentConcurrency;
52
+ }
53
+ /**
54
+ * Get current concurrency level
55
+ */ getCurrentConcurrency() {
56
+ return this.currentConcurrency;
57
+ }
58
+ /**
59
+ * Get maximum concurrency limit
60
+ */ getMaxConcurrency() {
61
+ return this.maxConcurrency;
62
+ }
63
+ /**
64
+ * Get resource utilization metrics
65
+ */ getMetrics() {
66
+ return {
67
+ ...this.metrics
68
+ };
69
+ }
70
+ /**
71
+ * Get utilization percentage (0-100)
72
+ */ getUtilization() {
73
+ if (this.maxConcurrency === 0) return 0;
74
+ return this.currentConcurrency / this.maxConcurrency * 100;
75
+ }
76
+ /**
77
+ * Check if resources are fully utilized
78
+ */ isFullyUtilized() {
79
+ return this.currentConcurrency >= this.maxConcurrency;
80
+ }
81
+ /**
82
+ * Check if resources are idle
83
+ */ isIdle() {
84
+ return this.currentConcurrency === 0;
85
+ }
86
+ /**
87
+ * Update average concurrency calculation
88
+ */ updateAverageConcurrency() {
89
+ if (this.allocationHistory.length === 0) {
90
+ this.metrics.averageConcurrency = 0;
91
+ return;
92
+ }
93
+ const sum = this.allocationHistory.reduce((a, b)=>a + b, 0);
94
+ this.metrics.averageConcurrency = sum / this.allocationHistory.length;
95
+ }
96
+ /**
97
+ * Reset metrics (useful for testing)
98
+ */ reset() {
99
+ this.currentConcurrency = 0;
100
+ this.allocationHistory = [];
101
+ this.metrics = {
102
+ peakConcurrency: 0,
103
+ averageConcurrency: 0,
104
+ totalAllocations: 0,
105
+ totalReleases: 0
106
+ };
107
+ }
108
+ constructor(maxConcurrency){
109
+ _define_property(this, "maxConcurrency", void 0);
110
+ _define_property(this, "currentConcurrency", 0);
111
+ _define_property(this, "metrics", void 0);
112
+ _define_property(this, "allocationHistory", []);
113
+ _define_property(this, "logger", getLogger());
114
+ this.maxConcurrency = maxConcurrency;
115
+ this.metrics = {
116
+ peakConcurrency: 0,
117
+ averageConcurrency: 0,
118
+ totalAllocations: 0,
119
+ totalReleases: 0
120
+ };
121
+ }
122
+ }
123
+
124
+ export { ResourceMonitor };
125
+ //# sourceMappingURL=ResourceMonitor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResourceMonitor.js","sources":["../../src/execution/ResourceMonitor.ts"],"sourcesContent":["import { getLogger } from '../logging';\n\nexport interface ResourceMetrics {\n peakConcurrency: number;\n averageConcurrency: number;\n totalAllocations: number;\n totalReleases: number;\n}\n\n/**\n * ResourceMonitor manages concurrency limits and tracks resource utilization\n */\nexport class ResourceMonitor {\n private maxConcurrency: number;\n private currentConcurrency: number = 0;\n private metrics: ResourceMetrics;\n private allocationHistory: number[] = [];\n private logger = getLogger();\n\n constructor(maxConcurrency: number) {\n this.maxConcurrency = maxConcurrency;\n this.metrics = {\n peakConcurrency: 0,\n averageConcurrency: 0,\n totalAllocations: 0,\n totalReleases: 0\n };\n }\n\n /**\n * Check if we can allocate N slots\n */\n canAllocate(count: number = 1): boolean {\n return this.currentConcurrency + count <= this.maxConcurrency;\n }\n\n /**\n * Allocate resource slots\n * @returns true if allocation succeeded, false if not enough slots available\n */\n allocate(count: number = 1): boolean {\n if (!this.canAllocate(count)) {\n return false;\n }\n\n this.currentConcurrency += count;\n this.metrics.totalAllocations += count;\n this.metrics.peakConcurrency = Math.max(\n this.metrics.peakConcurrency,\n this.currentConcurrency\n );\n\n this.allocationHistory.push(this.currentConcurrency);\n this.updateAverageConcurrency();\n\n this.logger.debug(`Allocated ${count} slot(s) (${this.currentConcurrency}/${this.maxConcurrency})`);\n\n return true;\n }\n\n /**\n * Release resource slots\n */\n release(count: number = 1): void {\n this.currentConcurrency = Math.max(0, this.currentConcurrency - count);\n this.metrics.totalReleases += count;\n\n this.allocationHistory.push(this.currentConcurrency);\n this.updateAverageConcurrency();\n\n this.logger.debug(`Released ${count} slot(s) (${this.currentConcurrency}/${this.maxConcurrency})`);\n }\n\n /**\n * Get number of available slots\n */\n getAvailableSlots(): number {\n return this.maxConcurrency - this.currentConcurrency;\n }\n\n /**\n * Get current concurrency level\n */\n getCurrentConcurrency(): number {\n return this.currentConcurrency;\n }\n\n /**\n * Get maximum concurrency limit\n */\n getMaxConcurrency(): number {\n return this.maxConcurrency;\n }\n\n /**\n * Get resource utilization metrics\n */\n getMetrics(): ResourceMetrics {\n return { ...this.metrics };\n }\n\n /**\n * Get utilization percentage (0-100)\n */\n getUtilization(): number {\n if (this.maxConcurrency === 0) return 0;\n return (this.currentConcurrency / this.maxConcurrency) * 100;\n }\n\n /**\n * Check if resources are fully utilized\n */\n isFullyUtilized(): boolean {\n return this.currentConcurrency >= this.maxConcurrency;\n }\n\n /**\n * Check if resources are idle\n */\n isIdle(): boolean {\n return this.currentConcurrency === 0;\n }\n\n /**\n * Update average concurrency calculation\n */\n private updateAverageConcurrency(): void {\n if (this.allocationHistory.length === 0) {\n this.metrics.averageConcurrency = 0;\n return;\n }\n\n const sum = this.allocationHistory.reduce((a, b) => a + b, 0);\n this.metrics.averageConcurrency = sum / this.allocationHistory.length;\n }\n\n /**\n * Reset metrics (useful for testing)\n */\n reset(): void {\n this.currentConcurrency = 0;\n this.allocationHistory = [];\n this.metrics = {\n peakConcurrency: 0,\n averageConcurrency: 0,\n totalAllocations: 0,\n totalReleases: 0\n };\n }\n}\n"],"names":["ResourceMonitor","canAllocate","count","currentConcurrency","maxConcurrency","allocate","metrics","totalAllocations","peakConcurrency","Math","max","allocationHistory","push","updateAverageConcurrency","logger","debug","release","totalReleases","getAvailableSlots","getCurrentConcurrency","getMaxConcurrency","getMetrics","getUtilization","isFullyUtilized","isIdle","length","averageConcurrency","sum","reduce","a","b","reset","getLogger"],"mappings":"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"}
@@ -0,0 +1,98 @@
1
+ function _define_property(obj, key, value) {
2
+ if (key in obj) {
3
+ Object.defineProperty(obj, key, {
4
+ value: value,
5
+ enumerable: true,
6
+ configurable: true,
7
+ writable: true
8
+ });
9
+ } else {
10
+ obj[key] = value;
11
+ }
12
+ return obj;
13
+ }
14
+ /**
15
+ * Scheduler determines which packages to execute next based on priority
16
+ */ class Scheduler {
17
+ /**
18
+ * Get next packages to schedule based on available slots
19
+ * Returns packages sorted by priority (highest priority first)
20
+ */ getNext(availableSlots, state) {
21
+ if (availableSlots <= 0 || state.ready.length === 0) {
22
+ return [];
23
+ }
24
+ // Sort ready packages by priority
25
+ const sorted = [
26
+ ...state.ready
27
+ ].sort((a, b)=>this.calculatePriority(b, state) - this.calculatePriority(a, state));
28
+ // Return top N packages that fit in available slots
29
+ return sorted.slice(0, availableSlots);
30
+ }
31
+ /**
32
+ * Calculate priority score for a package
33
+ * Higher score = higher priority = execute sooner
34
+ *
35
+ * Priority factors:
36
+ * 1. Number of dependents (more = higher priority, unblocks more packages)
37
+ * 2. Depth in dependency tree (shallower = higher priority, enables earlier unlocking)
38
+ * 3. Retry attempts (fewer = higher priority, give fresh packages a chance)
39
+ */ calculatePriority(packageName, state) {
40
+ let score = 0;
41
+ // Factor 1: More dependents = higher priority (weight: 100)
42
+ // Packages that unblock many others should run first
43
+ const dependentCount = this.checker.getDependentCount(packageName);
44
+ score += dependentCount * 100;
45
+ // Factor 2: Depth penalty (weight: -10)
46
+ // Prefer packages closer to the root of the dependency tree
47
+ const depth = this.checker.getDepth(packageName);
48
+ score -= depth * 10;
49
+ // Factor 3: Retry penalty (weight: -50)
50
+ // Packages that have failed before get lower priority
51
+ const retries = state.failed.filter((f)=>f.name === packageName).length;
52
+ score -= retries * 50;
53
+ // Factor 4: Bonus for packages with no dependents (leaf nodes)
54
+ // These are usually final deliverables and good to complete early for feedback
55
+ if (!this.checker.hasDependents(packageName)) {
56
+ score += 5;
57
+ }
58
+ return score;
59
+ }
60
+ /**
61
+ * Get estimated completion order (for progress reporting)
62
+ */ getEstimatedOrder(state) {
63
+ const allPending = [
64
+ ...state.pending,
65
+ ...state.ready
66
+ ];
67
+ return allPending.sort((a, b)=>this.calculatePriority(b, state) - this.calculatePriority(a, state));
68
+ }
69
+ /**
70
+ * Predict which packages will become ready next
71
+ * Useful for pre-loading or progress estimation
72
+ */ predictNextReady(state) {
73
+ const predictions = [];
74
+ // Look at currently running packages
75
+ const runningNames = state.running.map((r)=>r.name);
76
+ // For each running package, see which pending packages only depend on it
77
+ for (const runningPkg of runningNames){
78
+ for (const pendingPkg of state.pending){
79
+ const deps = this.checker.getDependencies(pendingPkg);
80
+ // Check if this pending package will be ready when running completes
81
+ const blockedBy = Array.from(deps).filter((dep)=>!state.completed.includes(dep) && dep !== runningPkg);
82
+ if (blockedBy.length === 0) {
83
+ predictions.push(pendingPkg);
84
+ }
85
+ }
86
+ }
87
+ return predictions;
88
+ }
89
+ constructor(graph, checker){
90
+ _define_property(this, "graph", void 0);
91
+ _define_property(this, "checker", void 0);
92
+ this.graph = graph;
93
+ this.checker = checker;
94
+ }
95
+ }
96
+
97
+ export { Scheduler };
98
+ //# sourceMappingURL=Scheduler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Scheduler.js","sources":["../../src/execution/Scheduler.ts"],"sourcesContent":["import { DependencyGraph } from '../util/dependencyGraph';\nimport { ExecutionState } from '../types/parallelExecution';\nimport { DependencyChecker } from './DependencyChecker';\n\n/**\n * Scheduler determines which packages to execute next based on priority\n */\nexport class Scheduler {\n private graph: DependencyGraph;\n private checker: DependencyChecker;\n\n constructor(graph: DependencyGraph, checker: DependencyChecker) {\n this.graph = graph;\n this.checker = checker;\n }\n\n /**\n * Get next packages to schedule based on available slots\n * Returns packages sorted by priority (highest priority first)\n */\n getNext(availableSlots: number, state: ExecutionState): string[] {\n if (availableSlots <= 0 || state.ready.length === 0) {\n return [];\n }\n\n // Sort ready packages by priority\n const sorted = [...state.ready].sort((a, b) =>\n this.calculatePriority(b, state) - this.calculatePriority(a, state)\n );\n\n // Return top N packages that fit in available slots\n return sorted.slice(0, availableSlots);\n }\n\n /**\n * Calculate priority score for a package\n * Higher score = higher priority = execute sooner\n *\n * Priority factors:\n * 1. Number of dependents (more = higher priority, unblocks more packages)\n * 2. Depth in dependency tree (shallower = higher priority, enables earlier unlocking)\n * 3. Retry attempts (fewer = higher priority, give fresh packages a chance)\n */\n calculatePriority(packageName: string, state: ExecutionState): number {\n let score = 0;\n\n // Factor 1: More dependents = higher priority (weight: 100)\n // Packages that unblock many others should run first\n const dependentCount = this.checker.getDependentCount(packageName);\n score += dependentCount * 100;\n\n // Factor 2: Depth penalty (weight: -10)\n // Prefer packages closer to the root of the dependency tree\n const depth = this.checker.getDepth(packageName);\n score -= depth * 10;\n\n // Factor 3: Retry penalty (weight: -50)\n // Packages that have failed before get lower priority\n const retries = state.failed.filter(f => f.name === packageName).length;\n score -= retries * 50;\n\n // Factor 4: Bonus for packages with no dependents (leaf nodes)\n // These are usually final deliverables and good to complete early for feedback\n if (!this.checker.hasDependents(packageName)) {\n score += 5;\n }\n\n return score;\n }\n\n /**\n * Get estimated completion order (for progress reporting)\n */\n getEstimatedOrder(state: ExecutionState): string[] {\n const allPending = [...state.pending, ...state.ready];\n\n return allPending.sort((a, b) =>\n this.calculatePriority(b, state) - this.calculatePriority(a, state)\n );\n }\n\n /**\n * Predict which packages will become ready next\n * Useful for pre-loading or progress estimation\n */\n predictNextReady(state: ExecutionState): string[] {\n const predictions: string[] = [];\n\n // Look at currently running packages\n const runningNames = state.running.map(r => r.name);\n\n // For each running package, see which pending packages only depend on it\n for (const runningPkg of runningNames) {\n for (const pendingPkg of state.pending) {\n const deps = this.checker.getDependencies(pendingPkg);\n\n // Check if this pending package will be ready when running completes\n const blockedBy = Array.from(deps).filter(dep =>\n !state.completed.includes(dep) && dep !== runningPkg\n );\n\n if (blockedBy.length === 0) {\n predictions.push(pendingPkg);\n }\n }\n }\n\n return predictions;\n }\n}\n"],"names":["Scheduler","getNext","availableSlots","state","ready","length","sorted","sort","a","b","calculatePriority","slice","packageName","score","dependentCount","checker","getDependentCount","depth","getDepth","retries","failed","filter","f","name","hasDependents","getEstimatedOrder","allPending","pending","predictNextReady","predictions","runningNames","running","map","r","runningPkg","pendingPkg","deps","getDependencies","blockedBy","Array","from","dep","completed","includes","push","graph"],"mappings":"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"}
@@ -0,0 +1,170 @@
1
+ import { DynamicTaskPool } from './DynamicTaskPool.js';
2
+ import { getLogger } from '../logging.js';
3
+ import { ProgressFormatter } from '../ui/ProgressFormatter.js';
4
+
5
+ function _define_property(obj, key, value) {
6
+ if (key in obj) {
7
+ Object.defineProperty(obj, key, {
8
+ value: value,
9
+ enumerable: true,
10
+ configurable: true,
11
+ writable: true
12
+ });
13
+ } else {
14
+ obj[key] = value;
15
+ }
16
+ return obj;
17
+ }
18
+ /**
19
+ * TreeExecutionAdapter bridges DynamicTaskPool with tree.ts executePackage
20
+ */ class TreeExecutionAdapter {
21
+ /**
22
+ * Create wrapper that adapts tree.ts executePackage to DynamicTaskPool format
23
+ */ createExecutePackageWrapper() {
24
+ return async (packageName, _signal)=>{
25
+ const packageInfo = this.config.graph.packages.get(packageName);
26
+ if (!packageInfo) {
27
+ throw new Error(`Package not found: ${packageName}`);
28
+ }
29
+ const allPackageNames = new Set(this.config.graph.packages.keys());
30
+ const isDryRun = this.config.config.dryRun || false;
31
+ const isBuiltInCommand = !this.config.command.startsWith('npm') && !this.config.command.includes('&&');
32
+ // Increment started count and use it as index for progress display
33
+ const currentIndex = this.startedCount++;
34
+ // Call tree.ts executePackage
35
+ const startTime = Date.now();
36
+ const result = await this.executePackageFn(packageName, packageInfo, this.config.command, this.config.config, isDryRun, currentIndex, this.config.graph.packages.size, allPackageNames, isBuiltInCommand);
37
+ const duration = Date.now() - startTime;
38
+ if (!result.success) {
39
+ throw result.error || new Error('Package execution failed');
40
+ }
41
+ return {
42
+ success: true,
43
+ duration,
44
+ // Extract published version if available (from output or state)
45
+ publishedVersion: undefined,
46
+ stdout: undefined,
47
+ stderr: undefined
48
+ };
49
+ };
50
+ }
51
+ /**
52
+ * Execute parallel execution
53
+ */ async execute() {
54
+ return await this.pool.execute();
55
+ }
56
+ /**
57
+ * Get the underlying task pool for event listeners
58
+ */ getPool() {
59
+ return this.pool;
60
+ }
61
+ constructor(config, executePackageFn){
62
+ _define_property(this, "pool", void 0);
63
+ _define_property(this, "executePackageFn", void 0);
64
+ _define_property(this, "config", void 0);
65
+ _define_property(this, "startedCount", 0);
66
+ _define_property(this, "completedCount", 0);
67
+ this.config = config;
68
+ this.executePackageFn = executePackageFn;
69
+ // Create custom pool that uses our execute function
70
+ this.pool = new DynamicTaskPool(config);
71
+ // Track completion count for progress display
72
+ this.pool.on('package:completed', ()=>{
73
+ this.completedCount++;
74
+ });
75
+ // Override the executePackage method to use tree.ts function
76
+ this.pool.executePackage = this.createExecutePackageWrapper();
77
+ }
78
+ }
79
+ /**
80
+ * Create progress logger that listens to pool events
81
+ */ function createParallelProgressLogger(pool, config) {
82
+ const logger = getLogger();
83
+ const startTime = Date.now();
84
+ let completedCount = 0;
85
+ let totalPackages = 0;
86
+ pool.on('execution:started', ({ totalPackages: total })=>{
87
+ totalPackages = total;
88
+ logger.info(`\nšŸ“¦ Executing ${total} packages in parallel\n`);
89
+ });
90
+ pool.on('package:started', ({ packageName })=>{
91
+ if (config.verbose || config.debug) {
92
+ logger.info(`ā–¶ļø Started: ${packageName}`);
93
+ }
94
+ });
95
+ pool.on('package:completed', ({ packageName, result })=>{
96
+ completedCount++;
97
+ const percent = Math.round(completedCount / totalPackages * 100);
98
+ const elapsed = Math.round((Date.now() - startTime) / 1000);
99
+ if (config.debug) {
100
+ logger.info(`āœ… Completed: ${packageName} (${result.duration}ms) [${completedCount}/${totalPackages} - ${percent}% - ${elapsed}s elapsed]`);
101
+ } else if (config.verbose) {
102
+ logger.info(`āœ… Completed: ${packageName} [${completedCount}/${totalPackages}]`);
103
+ } else {
104
+ // Minimal output
105
+ logger.info(`[${completedCount}/${totalPackages}] āœ… ${packageName}`);
106
+ }
107
+ });
108
+ pool.on('package:failed', ({ packageName, error })=>{
109
+ logger.error(`āŒ Failed: ${packageName} - ${error.message}`);
110
+ });
111
+ pool.on('package:retrying', ({ packageName, attemptNumber })=>{
112
+ logger.warn(`šŸ”„ Retrying: ${packageName} (attempt ${attemptNumber})`);
113
+ });
114
+ pool.on('package:skipped', ({ packageName, reason })=>{
115
+ logger.warn(`⊘ Skipped: ${packageName} (${reason})`);
116
+ });
117
+ pool.on('checkpoint:saved', ()=>{
118
+ if (config.debug) {
119
+ logger.debug('šŸ’¾ Checkpoint saved');
120
+ }
121
+ });
122
+ pool.on('execution:completed', ({ result })=>{
123
+ const totalTime = Math.round((Date.now() - startTime) / 1000);
124
+ logger.info(`\n✨ Parallel execution completed in ${totalTime}s`);
125
+ if (config.verbose || config.debug) {
126
+ logger.info(`\nMetrics:`);
127
+ logger.info(` Total packages: ${result.totalPackages}`);
128
+ logger.info(` Completed: ${result.completed.length}`);
129
+ logger.info(` Failed: ${result.failed.length}`);
130
+ logger.info(` Skipped: ${result.skipped.length}`);
131
+ logger.info(` Peak concurrency: ${result.metrics.peakConcurrency}`);
132
+ logger.info(` Average concurrency: ${result.metrics.averageConcurrency.toFixed(1)}`);
133
+ }
134
+ });
135
+ }
136
+ /**
137
+ * Format parallel execution result for display
138
+ */ function formatParallelResult(result) {
139
+ const lines = [];
140
+ if (result.success && result.skipped.length === 0) {
141
+ lines.push(`\n✨ All ${result.totalPackages} packages completed successfully! šŸŽ‰\n`);
142
+ } else if (result.success && result.skipped.length > 0) {
143
+ lines.push(`\nāš ļø Execution completed with ${result.skipped.length} package(s) skipped\n`);
144
+ } else {
145
+ lines.push(`\nāš ļø Execution completed with ${result.failed.length} failure(s)\n`);
146
+ }
147
+ // Use ProgressFormatter for metrics
148
+ const metricsLines = ProgressFormatter.createMetricsTable(result.metrics);
149
+ lines.push(...metricsLines);
150
+ // Failed packages with formatted error summary
151
+ if (result.failed.length > 0) {
152
+ const errorLines = ProgressFormatter.createErrorSummary(result.failed);
153
+ lines.push(...errorLines);
154
+ // Recovery guidance
155
+ const hasRetriable = result.failed.some((f)=>f.isRetriable);
156
+ const hasPermanent = result.failed.some((f)=>!f.isRetriable);
157
+ const recoveryLines = ProgressFormatter.createRecoveryGuidance(hasRetriable, hasPermanent);
158
+ lines.push(...recoveryLines);
159
+ }
160
+ // Skipped packages
161
+ if (result.skipped.length > 0) {
162
+ lines.push(`\n⊘ Skipped packages (due to failed dependencies):`);
163
+ lines.push(` ${result.skipped.join(', ')}`);
164
+ lines.push('');
165
+ }
166
+ return lines.join('\n');
167
+ }
168
+
169
+ export { TreeExecutionAdapter, createParallelProgressLogger, formatParallelResult };
170
+ //# sourceMappingURL=TreeExecutionAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TreeExecutionAdapter.js","sources":["../../src/execution/TreeExecutionAdapter.ts"],"sourcesContent":["import { DynamicTaskPool, PoolConfig } from './DynamicTaskPool';\nimport { PackageInfo } from '../util/dependencyGraph';\nimport { Config } from '../types';\nimport { PackageResult } from '../types/parallelExecution';\nimport { getLogger } from '../logging';\n\n/**\n * ExecutePackageFunction type matches the signature of tree.ts executePackage\n */\nexport type ExecutePackageFunction = (\n packageName: string,\n packageInfo: PackageInfo,\n commandToRun: string,\n runConfig: Config,\n isDryRun: boolean,\n index: number,\n total: number,\n allPackageNames: Set<string>,\n isBuiltInCommand?: boolean\n) => Promise<{ success: boolean; error?: any; isTimeoutError?: boolean }>;\n\n/**\n * TreeExecutionAdapter bridges DynamicTaskPool with tree.ts executePackage\n */\nexport class TreeExecutionAdapter {\n private pool: DynamicTaskPool;\n private executePackageFn: ExecutePackageFunction;\n private config: PoolConfig;\n private startedCount: number = 0;\n private completedCount: number = 0;\n\n constructor(config: PoolConfig, executePackageFn: ExecutePackageFunction) {\n this.config = config;\n this.executePackageFn = executePackageFn;\n\n // Create custom pool that uses our execute function\n this.pool = new DynamicTaskPool(config);\n\n // Track completion count for progress display\n this.pool.on('package:completed', () => {\n this.completedCount++;\n });\n\n // Override the executePackage method to use tree.ts function\n (this.pool as any).executePackage = this.createExecutePackageWrapper();\n }\n\n /**\n * Create wrapper that adapts tree.ts executePackage to DynamicTaskPool format\n */\n private createExecutePackageWrapper() {\n return async (packageName: string, _signal: AbortSignal): Promise<PackageResult> => {\n const packageInfo = this.config.graph.packages.get(packageName);\n if (!packageInfo) {\n throw new Error(`Package not found: ${packageName}`);\n }\n\n const allPackageNames = new Set(this.config.graph.packages.keys());\n const isDryRun = this.config.config.dryRun || false;\n const isBuiltInCommand = !this.config.command.startsWith('npm') &&\n !this.config.command.includes('&&');\n\n // Increment started count and use it as index for progress display\n const currentIndex = this.startedCount++;\n\n // Call tree.ts executePackage\n const startTime = Date.now();\n const result = await this.executePackageFn(\n packageName,\n packageInfo,\n this.config.command,\n this.config.config,\n isDryRun,\n currentIndex, // Use incremented started count for proper [N/Total] display\n this.config.graph.packages.size,\n allPackageNames,\n isBuiltInCommand\n );\n\n const duration = Date.now() - startTime;\n\n if (!result.success) {\n throw result.error || new Error('Package execution failed');\n }\n\n return {\n success: true,\n duration,\n // Extract published version if available (from output or state)\n publishedVersion: undefined,\n stdout: undefined,\n stderr: undefined\n };\n };\n }\n\n /**\n * Execute parallel execution\n */\n async execute() {\n return await this.pool.execute();\n }\n\n /**\n * Get the underlying task pool for event listeners\n */\n getPool(): DynamicTaskPool {\n return this.pool;\n }\n}\n\n/**\n * Create progress logger that listens to pool events\n */\nexport function createParallelProgressLogger(pool: DynamicTaskPool, config: Config): void {\n const logger = getLogger();\n const startTime = Date.now();\n let completedCount = 0;\n let totalPackages = 0;\n\n pool.on('execution:started', ({ totalPackages: total }) => {\n totalPackages = total;\n logger.info(`\\nšŸ“¦ Executing ${total} packages in parallel\\n`);\n });\n\n pool.on('package:started', ({ packageName }) => {\n if (config.verbose || config.debug) {\n logger.info(`ā–¶ļø Started: ${packageName}`);\n }\n });\n\n pool.on('package:completed', ({ packageName, result }) => {\n completedCount++;\n const percent = Math.round((completedCount / totalPackages) * 100);\n const elapsed = Math.round((Date.now() - startTime) / 1000);\n\n if (config.debug) {\n logger.info(`āœ… Completed: ${packageName} (${result.duration}ms) [${completedCount}/${totalPackages} - ${percent}% - ${elapsed}s elapsed]`);\n } else if (config.verbose) {\n logger.info(`āœ… Completed: ${packageName} [${completedCount}/${totalPackages}]`);\n } else {\n // Minimal output\n logger.info(`[${completedCount}/${totalPackages}] āœ… ${packageName}`);\n }\n });\n\n pool.on('package:failed', ({ packageName, error }) => {\n logger.error(`āŒ Failed: ${packageName} - ${error.message}`);\n });\n\n pool.on('package:retrying', ({ packageName, attemptNumber }) => {\n logger.warn(`šŸ”„ Retrying: ${packageName} (attempt ${attemptNumber})`);\n });\n\n pool.on('package:skipped', ({ packageName, reason }) => {\n logger.warn(`⊘ Skipped: ${packageName} (${reason})`);\n });\n\n pool.on('checkpoint:saved', () => {\n if (config.debug) {\n logger.debug('šŸ’¾ Checkpoint saved');\n }\n });\n\n pool.on('execution:completed', ({ result }) => {\n const totalTime = Math.round((Date.now() - startTime) / 1000);\n logger.info(`\\n✨ Parallel execution completed in ${totalTime}s`);\n\n if (config.verbose || config.debug) {\n logger.info(`\\nMetrics:`);\n logger.info(` Total packages: ${result.totalPackages}`);\n logger.info(` Completed: ${result.completed.length}`);\n logger.info(` Failed: ${result.failed.length}`);\n logger.info(` Skipped: ${result.skipped.length}`);\n logger.info(` Peak concurrency: ${result.metrics.peakConcurrency}`);\n logger.info(` Average concurrency: ${result.metrics.averageConcurrency.toFixed(1)}`);\n }\n });\n}\n\nimport { ProgressFormatter } from '../ui/ProgressFormatter';\n\n/**\n * Format parallel execution result for display\n */\nexport function formatParallelResult(result: any): string {\n const lines: string[] = [];\n\n if (result.success && result.skipped.length === 0) {\n lines.push(`\\n✨ All ${result.totalPackages} packages completed successfully! šŸŽ‰\\n`);\n } else if (result.success && result.skipped.length > 0) {\n lines.push(`\\nāš ļø Execution completed with ${result.skipped.length} package(s) skipped\\n`);\n } else {\n lines.push(`\\nāš ļø Execution completed with ${result.failed.length} failure(s)\\n`);\n }\n\n // Use ProgressFormatter for metrics\n const metricsLines = ProgressFormatter.createMetricsTable(result.metrics);\n lines.push(...metricsLines);\n\n // Failed packages with formatted error summary\n if (result.failed.length > 0) {\n const errorLines = ProgressFormatter.createErrorSummary(result.failed);\n lines.push(...errorLines);\n\n // Recovery guidance\n const hasRetriable = result.failed.some((f: any) => f.isRetriable);\n const hasPermanent = result.failed.some((f: any) => !f.isRetriable);\n const recoveryLines = ProgressFormatter.createRecoveryGuidance(hasRetriable, hasPermanent);\n lines.push(...recoveryLines);\n }\n\n // Skipped packages\n if (result.skipped.length > 0) {\n lines.push(`\\n⊘ Skipped packages (due to failed dependencies):`);\n lines.push(` ${result.skipped.join(', ')}`);\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n"],"names":["TreeExecutionAdapter","createExecutePackageWrapper","packageName","_signal","packageInfo","config","graph","packages","get","Error","allPackageNames","Set","keys","isDryRun","dryRun","isBuiltInCommand","command","startsWith","includes","currentIndex","startedCount","startTime","Date","now","result","executePackageFn","size","duration","success","error","publishedVersion","undefined","stdout","stderr","execute","pool","getPool","completedCount","DynamicTaskPool","on","executePackage","createParallelProgressLogger","logger","getLogger","totalPackages","total","info","verbose","debug","percent","Math","round","elapsed","message","attemptNumber","warn","reason","totalTime","completed","length","failed","skipped","metrics","peakConcurrency","averageConcurrency","toFixed","formatParallelResult","lines","push","metricsLines","ProgressFormatter","createMetricsTable","errorLines","createErrorSummary","hasRetriable","some","f","isRetriable","hasPermanent","recoveryLines","createRecoveryGuidance","join"],"mappings":"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"}
package/dist/logging.js CHANGED
@@ -1,13 +1,13 @@
1
1
  import winston from 'winston';
2
2
  import * as fs from 'fs';
3
- import path from 'path';
3
+ import path__default from 'path';
4
4
  import { PROGRAM_NAME, DEFAULT_OUTPUT_DIRECTORY, DATE_FORMAT_YEAR_MONTH_DAY_HOURS_MINUTES_SECONDS_MILLISECONDS } from './constants.js';
5
5
 
6
6
  // Track if debug directory has been ensured for this session
7
7
  let debugDirectoryEnsured = false;
8
8
  const ensureDebugDirectory = ()=>{
9
9
  if (debugDirectoryEnsured) return;
10
- const debugDir = path.join(DEFAULT_OUTPUT_DIRECTORY, 'debug');
10
+ const debugDir = path__default.join(DEFAULT_OUTPUT_DIRECTORY, 'debug');
11
11
  try {
12
12
  fs.mkdirSync(debugDir, {
13
13
  recursive: true
@@ -56,7 +56,7 @@ const createTransports = (level)=>{
56
56
  // Add file transport for debug levels (debug and silly)
57
57
  if (level === 'debug' || level === 'silly') {
58
58
  ensureDebugDirectory();
59
- const debugLogPath = path.join(DEFAULT_OUTPUT_DIRECTORY, 'debug', generateDebugLogFilename());
59
+ const debugLogPath = path__default.join(DEFAULT_OUTPUT_DIRECTORY, 'debug', generateDebugLogFilename());
60
60
  transports.push(new winston.transports.File({
61
61
  filename: debugLogPath,
62
62
  level: 'debug',
@@ -1 +1 @@
1
- {"version":3,"file":"logging.js","sources":["../src/logging.ts"],"sourcesContent":["import winston from 'winston';\n// eslint-disable-next-line no-restricted-imports\nimport * as fs from 'fs';\nimport path from 'path';\nimport { DATE_FORMAT_YEAR_MONTH_DAY_HOURS_MINUTES_SECONDS_MILLISECONDS, PROGRAM_NAME, DEFAULT_OUTPUT_DIRECTORY } from './constants';\n\nexport interface LogContext {\n [key: string]: any;\n}\n\n// Track if debug directory has been ensured for this session\nlet debugDirectoryEnsured = false;\n\nconst ensureDebugDirectory = () => {\n if (debugDirectoryEnsured) return;\n\n const debugDir = path.join(DEFAULT_OUTPUT_DIRECTORY, 'debug');\n\n try {\n fs.mkdirSync(debugDir, { recursive: true });\n debugDirectoryEnsured = true;\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error(`Failed to create debug directory ${debugDir}:`, error);\n }\n};\n\nconst generateDebugLogFilename = () => {\n const now = new Date();\n const timestamp = now.toISOString()\n .replace(/[-:]/g, '')\n .replace(/\\./g, '')\n .replace('T', '-')\n .replace('Z', '');\n\n return `${timestamp}-debug.log`;\n};\n\nconst createTransports = (level: string) => {\n const transports: winston.transport[] = [];\n\n // Always add console transport for info level and above\n if (level === 'info') {\n transports.push(\n new winston.transports.Console({\n format: winston.format.combine(\n winston.format.colorize(),\n winston.format.printf(({ level, message, dryRun }): string => {\n const dryRunPrefix = dryRun ? 'šŸ” DRY RUN: ' : '';\n // For info level messages, don't show the level prefix\n if (level.includes('info')) {\n return `${dryRunPrefix}${String(message)}`;\n }\n // For warn, error, etc., show the level prefix\n return `${level}: ${dryRunPrefix}${String(message)}`;\n })\n )\n })\n );\n } else {\n // For debug/verbose levels, add console transport that shows info and above\n transports.push(\n new winston.transports.Console({\n level: 'info', // Show info, warn, and error on console\n format: winston.format.combine(\n winston.format.colorize(),\n winston.format.printf(({ timestamp, level, message, dryRun, ...meta }): string => {\n // For info level messages, use simpler format without timestamp\n if (level.includes('info')) {\n const dryRunPrefix = dryRun ? 'šŸ” DRY RUN: ' : '';\n return `${dryRunPrefix}${String(message)}`;\n }\n const metaStr = Object.keys(meta).length ? ` ${JSON.stringify(meta)}` : '';\n const dryRunPrefix = dryRun ? 'šŸ” DRY RUN: ' : '';\n return `${timestamp} ${level}: ${dryRunPrefix}${String(message)}${metaStr}`;\n })\n )\n })\n );\n\n // Add file transport for debug levels (debug and silly)\n if (level === 'debug' || level === 'silly') {\n ensureDebugDirectory();\n\n const debugLogPath = path.join(DEFAULT_OUTPUT_DIRECTORY, 'debug', generateDebugLogFilename());\n\n transports.push(\n new winston.transports.File({\n filename: debugLogPath,\n level: 'debug', // Capture debug and above in the file\n format: winston.format.combine(\n winston.format.timestamp({ format: DATE_FORMAT_YEAR_MONTH_DAY_HOURS_MINUTES_SECONDS_MILLISECONDS }),\n winston.format.errors({ stack: true }),\n winston.format.splat(),\n winston.format.printf(({ timestamp, level, message, ...meta }) => {\n const metaStr = Object.keys(meta).length ? ` ${JSON.stringify(meta)}` : '';\n return `${timestamp} ${level}: ${message}${metaStr}`;\n })\n )\n })\n );\n }\n }\n\n return transports;\n};\n\nconst createFormat = (level: string) => {\n const baseFormats = [\n winston.format.errors({ stack: true }),\n winston.format.splat(),\n ];\n\n if (level === 'info') {\n return winston.format.combine(\n ...baseFormats,\n winston.format.printf(({ message, dryRun, ..._meta }): string => {\n // Auto-format dry-run messages\n if (dryRun) {\n return `šŸ” DRY RUN: ${message}`;\n }\n return String(message);\n })\n );\n }\n\n return winston.format.combine(\n winston.format.timestamp({ format: DATE_FORMAT_YEAR_MONTH_DAY_HOURS_MINUTES_SECONDS_MILLISECONDS }),\n ...baseFormats,\n winston.format.printf(({ timestamp, level, message, dryRun, ...meta }): string => {\n const metaStr = Object.keys(meta).length ? ` ${JSON.stringify(meta)}` : '';\n const dryRunPrefix = dryRun ? 'šŸ” DRY RUN: ' : '';\n return `${timestamp} ${level}: ${dryRunPrefix}${String(message)}${metaStr}`;\n })\n );\n};\n\n// Create the logger instance once\nconst logger = winston.createLogger({\n level: 'info',\n format: createFormat('info'),\n defaultMeta: { service: PROGRAM_NAME },\n transports: createTransports('info'),\n});\n\nexport const setLogLevel = (level: string) => {\n // Reconfigure the existing logger instead of creating a new one\n logger.configure({\n level,\n format: createFormat(level),\n defaultMeta: { service: PROGRAM_NAME },\n transports: createTransports(level),\n });\n};\n\nexport const getLogger = () => logger;\n\n/**\n * Get a logger that automatically formats messages for dry-run mode\n */\nexport const getDryRunLogger = (isDryRun: boolean) => {\n if (!isDryRun) {\n return logger;\n }\n\n // Return a wrapper that adds dry-run context to all log calls\n return {\n info: (message: string, ...args: any[]) => logger.info(message, { dryRun: true }, ...args),\n warn: (message: string, ...args: any[]) => logger.warn(message, { dryRun: true }, ...args),\n error: (message: string, ...args: any[]) => logger.error(message, { dryRun: true }, ...args),\n debug: (message: string, ...args: any[]) => logger.debug(message, { dryRun: true }, ...args),\n verbose: (message: string, ...args: any[]) => logger.verbose(message, { dryRun: true }, ...args),\n silly: (message: string, ...args: any[]) => logger.silly(message, { dryRun: true }, ...args),\n };\n};\n"],"names":["debugDirectoryEnsured","ensureDebugDirectory","debugDir","path","join","DEFAULT_OUTPUT_DIRECTORY","fs","mkdirSync","recursive","error","console","generateDebugLogFilename","now","Date","timestamp","toISOString","replace","createTransports","level","transports","push","winston","Console","format","combine","colorize","printf","message","dryRun","dryRunPrefix","includes","String","meta","metaStr","Object","keys","length","JSON","stringify","debugLogPath","File","filename","DATE_FORMAT_YEAR_MONTH_DAY_HOURS_MINUTES_SECONDS_MILLISECONDS","errors","stack","splat","createFormat","baseFormats","_meta","logger","createLogger","defaultMeta","service","PROGRAM_NAME","setLogLevel","configure","getLogger","getDryRunLogger","isDryRun","info","args","warn","debug","verbose","silly"],"mappings":"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"}
1
+ {"version":3,"file":"logging.js","sources":["../src/logging.ts"],"sourcesContent":["import winston from 'winston';\n// eslint-disable-next-line no-restricted-imports\nimport * as fs from 'fs';\nimport path from 'path';\nimport { DATE_FORMAT_YEAR_MONTH_DAY_HOURS_MINUTES_SECONDS_MILLISECONDS, PROGRAM_NAME, DEFAULT_OUTPUT_DIRECTORY } from './constants';\n\nexport interface LogContext {\n [key: string]: any;\n}\n\n// Track if debug directory has been ensured for this session\nlet debugDirectoryEnsured = false;\n\nconst ensureDebugDirectory = () => {\n if (debugDirectoryEnsured) return;\n\n const debugDir = path.join(DEFAULT_OUTPUT_DIRECTORY, 'debug');\n\n try {\n fs.mkdirSync(debugDir, { recursive: true });\n debugDirectoryEnsured = true;\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error(`Failed to create debug directory ${debugDir}:`, error);\n }\n};\n\nconst generateDebugLogFilename = () => {\n const now = new Date();\n const timestamp = now.toISOString()\n .replace(/[-:]/g, '')\n .replace(/\\./g, '')\n .replace('T', '-')\n .replace('Z', '');\n\n return `${timestamp}-debug.log`;\n};\n\nconst createTransports = (level: string) => {\n const transports: winston.transport[] = [];\n\n // Always add console transport for info level and above\n if (level === 'info') {\n transports.push(\n new winston.transports.Console({\n format: winston.format.combine(\n winston.format.colorize(),\n winston.format.printf(({ level, message, dryRun }): string => {\n const dryRunPrefix = dryRun ? 'šŸ” DRY RUN: ' : '';\n // For info level messages, don't show the level prefix\n if (level.includes('info')) {\n return `${dryRunPrefix}${String(message)}`;\n }\n // For warn, error, etc., show the level prefix\n return `${level}: ${dryRunPrefix}${String(message)}`;\n })\n )\n })\n );\n } else {\n // For debug/verbose levels, add console transport that shows info and above\n transports.push(\n new winston.transports.Console({\n level: 'info', // Show info, warn, and error on console\n format: winston.format.combine(\n winston.format.colorize(),\n winston.format.printf(({ timestamp, level, message, dryRun, ...meta }): string => {\n // For info level messages, use simpler format without timestamp\n if (level.includes('info')) {\n const dryRunPrefix = dryRun ? 'šŸ” DRY RUN: ' : '';\n return `${dryRunPrefix}${String(message)}`;\n }\n const metaStr = Object.keys(meta).length ? ` ${JSON.stringify(meta)}` : '';\n const dryRunPrefix = dryRun ? 'šŸ” DRY RUN: ' : '';\n return `${timestamp} ${level}: ${dryRunPrefix}${String(message)}${metaStr}`;\n })\n )\n })\n );\n\n // Add file transport for debug levels (debug and silly)\n if (level === 'debug' || level === 'silly') {\n ensureDebugDirectory();\n\n const debugLogPath = path.join(DEFAULT_OUTPUT_DIRECTORY, 'debug', generateDebugLogFilename());\n\n transports.push(\n new winston.transports.File({\n filename: debugLogPath,\n level: 'debug', // Capture debug and above in the file\n format: winston.format.combine(\n winston.format.timestamp({ format: DATE_FORMAT_YEAR_MONTH_DAY_HOURS_MINUTES_SECONDS_MILLISECONDS }),\n winston.format.errors({ stack: true }),\n winston.format.splat(),\n winston.format.printf(({ timestamp, level, message, ...meta }) => {\n const metaStr = Object.keys(meta).length ? ` ${JSON.stringify(meta)}` : '';\n return `${timestamp} ${level}: ${message}${metaStr}`;\n })\n )\n })\n );\n }\n }\n\n return transports;\n};\n\nconst createFormat = (level: string) => {\n const baseFormats = [\n winston.format.errors({ stack: true }),\n winston.format.splat(),\n ];\n\n if (level === 'info') {\n return winston.format.combine(\n ...baseFormats,\n winston.format.printf(({ message, dryRun, ..._meta }): string => {\n // Auto-format dry-run messages\n if (dryRun) {\n return `šŸ” DRY RUN: ${message}`;\n }\n return String(message);\n })\n );\n }\n\n return winston.format.combine(\n winston.format.timestamp({ format: DATE_FORMAT_YEAR_MONTH_DAY_HOURS_MINUTES_SECONDS_MILLISECONDS }),\n ...baseFormats,\n winston.format.printf(({ timestamp, level, message, dryRun, ...meta }): string => {\n const metaStr = Object.keys(meta).length ? ` ${JSON.stringify(meta)}` : '';\n const dryRunPrefix = dryRun ? 'šŸ” DRY RUN: ' : '';\n return `${timestamp} ${level}: ${dryRunPrefix}${String(message)}${metaStr}`;\n })\n );\n};\n\n// Create the logger instance once\nconst logger = winston.createLogger({\n level: 'info',\n format: createFormat('info'),\n defaultMeta: { service: PROGRAM_NAME },\n transports: createTransports('info'),\n});\n\nexport const setLogLevel = (level: string) => {\n // Reconfigure the existing logger instead of creating a new one\n logger.configure({\n level,\n format: createFormat(level),\n defaultMeta: { service: PROGRAM_NAME },\n transports: createTransports(level),\n });\n};\n\nexport const getLogger = () => logger;\n\n/**\n * Get a logger that automatically formats messages for dry-run mode\n */\nexport const getDryRunLogger = (isDryRun: boolean) => {\n if (!isDryRun) {\n return logger;\n }\n\n // Return a wrapper that adds dry-run context to all log calls\n return {\n info: (message: string, ...args: any[]) => logger.info(message, { dryRun: true }, ...args),\n warn: (message: string, ...args: any[]) => logger.warn(message, { dryRun: true }, ...args),\n error: (message: string, ...args: any[]) => logger.error(message, { dryRun: true }, ...args),\n debug: (message: string, ...args: any[]) => logger.debug(message, { dryRun: true }, ...args),\n verbose: (message: string, ...args: any[]) => logger.verbose(message, { dryRun: true }, ...args),\n silly: (message: string, ...args: any[]) => logger.silly(message, { dryRun: true }, ...args),\n };\n};\n"],"names":["debugDirectoryEnsured","ensureDebugDirectory","debugDir","path","join","DEFAULT_OUTPUT_DIRECTORY","fs","mkdirSync","recursive","error","console","generateDebugLogFilename","now","Date","timestamp","toISOString","replace","createTransports","level","transports","push","winston","Console","format","combine","colorize","printf","message","dryRun","dryRunPrefix","includes","String","meta","metaStr","Object","keys","length","JSON","stringify","debugLogPath","File","filename","DATE_FORMAT_YEAR_MONTH_DAY_HOURS_MINUTES_SECONDS_MILLISECONDS","errors","stack","splat","createFormat","baseFormats","_meta","logger","createLogger","defaultMeta","service","PROGRAM_NAME","setLogLevel","configure","getLogger","getDryRunLogger","isDryRun","info","args","warn","debug","verbose","silly"],"mappings":"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"}