@eldrforge/kodrdriv 1.2.27 → 1.2.28

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 (78) hide show
  1. package/AI-FRIENDLY-LOGGING-GUIDE.md +237 -0
  2. package/AI-LOGGING-MIGRATION-COMPLETE.md +371 -0
  3. package/ALREADY-PUBLISHED-PACKAGES-FIX.md +264 -0
  4. package/AUDIT-BRANCHES-PROGRESS-FIX.md +90 -0
  5. package/AUDIT-EXAMPLE-OUTPUT.md +113 -0
  6. package/CHECKPOINT-RECOVERY-FIX.md +450 -0
  7. package/LOGGING-MIGRATION-STATUS.md +186 -0
  8. package/PARALLEL-PUBLISH-FIXES-IMPLEMENTED.md +405 -0
  9. package/PARALLEL-PUBLISH-QUICK-REFERENCE.md +375 -0
  10. package/PARALLEL_EXECUTION_FIX.md +2 -2
  11. package/PUBLISH_IMPROVEMENTS_IMPLEMENTED.md +4 -5
  12. package/VERSION-AUDIT-FIX.md +333 -0
  13. package/dist/application.js +6 -6
  14. package/dist/application.js.map +1 -1
  15. package/dist/arguments.js +43 -13
  16. package/dist/arguments.js.map +1 -1
  17. package/dist/commands/audio-commit.js +18 -18
  18. package/dist/commands/audio-commit.js.map +1 -1
  19. package/dist/commands/audio-review.js +32 -32
  20. package/dist/commands/audio-review.js.map +1 -1
  21. package/dist/commands/clean.js +9 -9
  22. package/dist/commands/clean.js.map +1 -1
  23. package/dist/commands/commit.js +20 -20
  24. package/dist/commands/commit.js.map +1 -1
  25. package/dist/commands/development.js +88 -89
  26. package/dist/commands/development.js.map +1 -1
  27. package/dist/commands/link.js +36 -36
  28. package/dist/commands/link.js.map +1 -1
  29. package/dist/commands/publish.js +318 -220
  30. package/dist/commands/publish.js.map +1 -1
  31. package/dist/commands/release.js +14 -14
  32. package/dist/commands/release.js.map +1 -1
  33. package/dist/commands/review.js +15 -17
  34. package/dist/commands/review.js.map +1 -1
  35. package/dist/commands/select-audio.js +5 -5
  36. package/dist/commands/select-audio.js.map +1 -1
  37. package/dist/commands/tree.js +75 -34
  38. package/dist/commands/tree.js.map +1 -1
  39. package/dist/commands/unlink.js +39 -39
  40. package/dist/commands/unlink.js.map +1 -1
  41. package/dist/commands/updates.js +150 -14
  42. package/dist/commands/updates.js.map +1 -1
  43. package/dist/commands/versions.js +14 -13
  44. package/dist/commands/versions.js.map +1 -1
  45. package/dist/constants.js +1 -1
  46. package/dist/content/diff.js +5 -5
  47. package/dist/content/diff.js.map +1 -1
  48. package/dist/content/files.js +2 -2
  49. package/dist/content/files.js.map +1 -1
  50. package/dist/content/log.js +3 -3
  51. package/dist/content/log.js.map +1 -1
  52. package/dist/execution/CommandValidator.js +6 -6
  53. package/dist/execution/CommandValidator.js.map +1 -1
  54. package/dist/execution/DynamicTaskPool.js +33 -10
  55. package/dist/execution/DynamicTaskPool.js.map +1 -1
  56. package/dist/execution/RecoveryManager.js +99 -21
  57. package/dist/execution/RecoveryManager.js.map +1 -1
  58. package/dist/execution/TreeExecutionAdapter.js +19 -19
  59. package/dist/execution/TreeExecutionAdapter.js.map +1 -1
  60. package/dist/main.js +2 -2
  61. package/dist/main.js.map +1 -1
  62. package/dist/util/checkpointManager.js +4 -4
  63. package/dist/util/checkpointManager.js.map +1 -1
  64. package/dist/util/dependencyGraph.js +2 -2
  65. package/dist/util/dependencyGraph.js.map +1 -1
  66. package/dist/util/fileLock.js +1 -1
  67. package/dist/util/fileLock.js.map +1 -1
  68. package/dist/util/general.js +148 -15
  69. package/dist/util/general.js.map +1 -1
  70. package/dist/util/interactive.js +2 -2
  71. package/dist/util/interactive.js.map +1 -1
  72. package/dist/util/performance.js.map +1 -1
  73. package/dist/util/safety.js +13 -13
  74. package/dist/util/safety.js.map +1 -1
  75. package/dist/utils/branchState.js +567 -0
  76. package/dist/utils/branchState.js.map +1 -0
  77. package/package.json +1 -1
  78. package/scripts/update-test-log-assertions.js +73 -0
@@ -1 +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 // Check if this was a \"no changes\" skip (result will have skippedNoChanges flag)\n const skippedNoChanges = (result as any).skippedNoChanges || false;\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 skippedNoChanges\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('package:skipped-no-changes', ({ packageName }) => {\n if (config.verbose || config.debug) {\n logger.info(`⊘ Skipped: ${packageName} (no code changes)`);\n }\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(` Skipped (no changes): ${result.skippedNoChanges.length}`);\n logger.info(` Skipped (dependency failed): ${result.skipped.length}`);\n logger.info(` Failed: ${result.failed.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 // Separator line\n lines.push('\\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');\n lines.push('📊 Publish Summary');\n lines.push('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\n');\n\n // Detailed status breakdown by category\n if (result.completed.length > 0) {\n lines.push(`✅ Published (${result.completed.length}):`);\n for (const pkg of result.completed) {\n lines.push(` - ${pkg}`);\n }\n lines.push('');\n }\n\n if (result.skippedNoChanges.length > 0) {\n lines.push(`⏭️ Skipped (${result.skippedNoChanges.length}) - no code changes:`);\n for (const pkg of result.skippedNoChanges) {\n lines.push(` - ${pkg}`);\n }\n lines.push('');\n }\n\n if (result.failed.length > 0) {\n lines.push(`❌ Failed (${result.failed.length}):`);\n for (const pkg of result.failed) {\n lines.push(` - ${pkg}`);\n }\n lines.push('');\n }\n\n if (result.skipped.length > 0) {\n lines.push(`⊘ Skipped due to dependencies (${result.skipped.length}):`);\n for (const pkg of result.skipped) {\n lines.push(` - ${pkg}`);\n }\n lines.push('');\n }\n\n // Summary line\n lines.push('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\n');\n\n // Calculate success rate\n const totalProcessed = result.completed.length + result.failed.length + result.skippedNoChanges.length;\n const successRate = totalProcessed > 0 ? Math.round((result.completed.length / totalProcessed) * 100) : 0;\n\n // Format elapsed time\n const totalTimeMs = result.metrics?.totalTime || 0;\n const minutes = Math.floor(totalTimeMs / 60000);\n const seconds = Math.floor((totalTimeMs % 60000) / 1000);\n const timeStr = minutes > 0 ? `${minutes}m ${seconds}s` : `${seconds}s`;\n\n lines.push(`Total time: ${timeStr}`);\n lines.push(`Success rate: ${successRate}% (${result.completed.length}/${totalProcessed} packages processed)`);\n\n if (result.metrics?.peakConcurrency) {\n lines.push(`Peak concurrency: ${result.metrics.peakConcurrency} packages`);\n }\n\n lines.push('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');\n\n // Failed packages with formatted error summary\n if (result.failed.length > 0) {\n lines.push('');\n const errorLines = ProgressFormatter.createErrorSummary(result.failed);\n lines.push(...errorLines);\n\n // Next steps for failures\n lines.push('\\n📋 Next steps:');\n lines.push('1. Review the errors above for each failed package');\n lines.push('2. Fix the issues in the failed packages');\n lines.push('3. Retry the publish command');\n\n if (result.skipped.length > 0) {\n lines.push('\\nNote: Once failed packages are fixed, their dependent packages will also be published.');\n }\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 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","skippedNoChanges","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","skipped","failed","metrics","peakConcurrency","averageConcurrency","toFixed","formatParallelResult","lines","push","pkg","totalProcessed","successRate","totalTimeMs","minutes","floor","seconds","timeStr","errorLines","ProgressFormatter","createErrorSummary","hasRetriable","some","f","isRetriable","hasPermanent","recoveryLines","createRecoveryGuidance","join"],"mappings":"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"}
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; skippedNoChanges?: 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 // Check if this was a \"no changes\" skip (result will have skippedNoChanges flag)\n const skippedNoChanges = (result as any).skippedNoChanges || false;\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 skippedNoChanges\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(`\\nPARALLEL_EXECUTION_STARTING: Initiating parallel package execution | Package Count: ${total} | Mode: parallel | Strategy: dependency-aware`);\n });\n\n pool.on('package:started', ({ packageName }) => {\n if (config.verbose || config.debug) {\n logger.info(`PACKAGE_STARTED: Package execution initiated | Package: ${packageName} | Status: running`);\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(`PACKAGE_COMPLETED: Package execution finished successfully | Package: ${packageName} | Duration: ${result.duration}ms | Progress: ${completedCount}/${totalPackages} (${percent}%) | Elapsed: ${elapsed}s`);\n } else if (config.verbose) {\n logger.info(`PACKAGE_COMPLETED: Package execution finished | Package: ${packageName} | Progress: ${completedCount}/${totalPackages}`);\n } else {\n // Minimal output\n logger.info(`PROGRESS: [${completedCount}/${totalPackages}] Package completed: ${packageName}`);\n }\n });\n\n pool.on('package:failed', ({ packageName, error }) => {\n logger.error(`PACKAGE_FAILED: Package execution failed | Package: ${packageName} | Error: ${error.message} | Status: error`);\n });\n\n pool.on('package:retrying', ({ packageName, attemptNumber }) => {\n logger.warn(`PACKAGE_RETRYING: Retrying package execution | Package: ${packageName} | Attempt: ${attemptNumber} | Status: retrying`);\n });\n\n pool.on('package:skipped', ({ packageName, reason }) => {\n logger.warn(`PACKAGE_SKIPPED: Package skipped due to dependency failure | Package: ${packageName} | Reason: ${reason} | Status: skipped`);\n });\n\n pool.on('package:skipped-no-changes', ({ packageName }) => {\n if (config.verbose || config.debug) {\n logger.info(`PACKAGE_SKIPPED_NO_CHANGES: Package skipped due to no code changes | Package: ${packageName} | Reason: no-code-changes | Status: skipped`);\n }\n });\n\n pool.on('checkpoint:saved', () => {\n if (config.debug) {\n logger.debug('CHECKPOINT_SAVED: Execution checkpoint saved | Purpose: Recovery support | Action: State persisted to disk');\n }\n });\n\n pool.on('execution:completed', ({ result }) => {\n const totalTime = Math.round((Date.now() - startTime) / 1000);\n logger.info(`\\nPARALLEL_EXECUTION_COMPLETED: Parallel execution finished | Duration: ${totalTime}s | Status: completed`);\n\n if (config.verbose || config.debug) {\n logger.info(`\\nEXECUTION_METRICS: Performance and execution statistics:`);\n logger.info(` METRIC_TOTAL_PACKAGES: ${result.totalPackages}`);\n logger.info(` METRIC_COMPLETED: ${result.completed.length} packages successfully completed`);\n logger.info(` METRIC_SKIPPED_NO_CHANGES: ${result.skippedNoChanges.length} packages skipped (no changes)`);\n logger.info(` METRIC_SKIPPED_DEPENDENCIES: ${result.skipped.length} packages skipped (dependency failures)`);\n logger.info(` METRIC_FAILED: ${result.failed.length} packages failed`);\n logger.info(` METRIC_PEAK_CONCURRENCY: ${result.metrics.peakConcurrency} packages running simultaneously`);\n logger.info(` METRIC_AVG_CONCURRENCY: ${result.metrics.averageConcurrency.toFixed(1)} average concurrent packages`);\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 // Separator line\n lines.push('\\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');\n lines.push('📊 Publish Summary');\n lines.push('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\n');\n\n // Detailed status breakdown by category\n if (result.completed.length > 0) {\n lines.push(`✅ Published (${result.completed.length}):`);\n for (const pkg of result.completed) {\n lines.push(` - ${pkg}`);\n }\n lines.push('');\n }\n\n if (result.skippedNoChanges.length > 0) {\n lines.push(`⏭️ Skipped (${result.skippedNoChanges.length}) - no code changes:`);\n for (const pkg of result.skippedNoChanges) {\n lines.push(` - ${pkg}`);\n }\n lines.push('');\n }\n\n if (result.failed.length > 0) {\n lines.push(`❌ Failed (${result.failed.length}):`);\n for (const pkg of result.failed) {\n lines.push(` - ${pkg}`);\n }\n lines.push('');\n }\n\n if (result.skipped.length > 0) {\n lines.push(`⊘ Skipped due to dependencies (${result.skipped.length}):`);\n for (const pkg of result.skipped) {\n lines.push(` - ${pkg}`);\n }\n lines.push('');\n }\n\n // Summary line\n lines.push('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\n');\n\n // Calculate success rate\n const totalProcessed = result.completed.length + result.failed.length + result.skippedNoChanges.length;\n const successRate = totalProcessed > 0 ? Math.round((result.completed.length / totalProcessed) * 100) : 0;\n\n // Format elapsed time\n const totalTimeMs = result.metrics?.totalTime || 0;\n const minutes = Math.floor(totalTimeMs / 60000);\n const seconds = Math.floor((totalTimeMs % 60000) / 1000);\n const timeStr = minutes > 0 ? `${minutes}m ${seconds}s` : `${seconds}s`;\n\n lines.push(`Total time: ${timeStr}`);\n lines.push(`Success rate: ${successRate}% (${result.completed.length}/${totalProcessed} packages processed)`);\n\n if (result.metrics?.peakConcurrency) {\n lines.push(`Peak concurrency: ${result.metrics.peakConcurrency} packages`);\n }\n\n lines.push('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');\n\n // Failed packages with formatted error summary\n if (result.failed.length > 0) {\n lines.push('');\n const errorLines = ProgressFormatter.createErrorSummary(result.failed);\n lines.push(...errorLines);\n\n // Next steps for failures\n lines.push('\\n📋 Next steps:');\n lines.push('1. Review the errors above for each failed package');\n lines.push('2. Fix the issues in the failed packages');\n lines.push('3. Retry the publish command');\n\n if (result.skipped.length > 0) {\n lines.push('\\nNote: Once failed packages are fixed, their dependent packages will also be published.');\n }\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 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","skippedNoChanges","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","skipped","failed","metrics","peakConcurrency","averageConcurrency","toFixed","formatParallelResult","lines","push","pkg","totalProcessed","successRate","totalTimeMs","minutes","floor","seconds","timeStr","errorLines","ProgressFormatter","createErrorSummary","hasRetriable","some","f","isRetriable","hasPermanent","recoveryLines","createRecoveryGuidance","join"],"mappings":"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"}
package/dist/main.js CHANGED
@@ -9,7 +9,7 @@ import { getLogger } from './logging.js';
9
9
  await runApplication();
10
10
  } catch (error) {
11
11
  const logger = getLogger();
12
- logger.error('Exiting due to Error: %s, %s', error.message, error.stack);
12
+ logger.error('MAIN_ERROR_EXIT: Exiting due to error | Error: %s | Stack: %s | Status: terminating', error.message, error.stack);
13
13
  process.exit(1);
14
14
  }
15
15
  }
@@ -18,7 +18,7 @@ main().then(()=>{
18
18
  process.exit(0);
19
19
  }).catch((error)=>{
20
20
  const logger = getLogger();
21
- logger.error('Unhandled error in main: %s', error.message || error);
21
+ logger.error('MAIN_UNHANDLED_ERROR: Unhandled error in main process | Error: %s | Type: unhandled', error.message || error);
22
22
  process.exit(1);
23
23
  });
24
24
  //# sourceMappingURL=main.js.map
package/dist/main.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"main.js","sources":["../src/main.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { runApplication } from './application';\nimport { getLogger } from './logging';\n\n/**\n * Main entry point - minimal wrapper around the application logic\n */\nasync function main(): Promise<void> {\n try {\n await runApplication();\n } catch (error: any) {\n const logger = getLogger();\n logger.error('Exiting due to Error: %s, %s', error.message, error.stack);\n process.exit(1);\n }\n}\n\n// Properly handle the main function with error handling and explicit process exit\nmain().then(() => {\n process.exit(0);\n}).catch((error) => {\n const logger = getLogger();\n logger.error('Unhandled error in main: %s', error.message || error);\n process.exit(1);\n});\n"],"names":["main","runApplication","error","logger","getLogger","message","stack","process","exit","then","catch"],"mappings":"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"}
1
+ {"version":3,"file":"main.js","sources":["../src/main.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { runApplication } from './application';\nimport { getLogger } from './logging';\n\n/**\n * Main entry point - minimal wrapper around the application logic\n */\nasync function main(): Promise<void> {\n try {\n await runApplication();\n } catch (error: any) {\n const logger = getLogger();\n logger.error('MAIN_ERROR_EXIT: Exiting due to error | Error: %s | Stack: %s | Status: terminating', error.message, error.stack);\n process.exit(1);\n }\n}\n\n// Properly handle the main function with error handling and explicit process exit\nmain().then(() => {\n process.exit(0);\n}).catch((error) => {\n const logger = getLogger();\n logger.error('MAIN_UNHANDLED_ERROR: Unhandled error in main process | Error: %s | Type: unhandled', error.message || error);\n process.exit(1);\n});\n"],"names":["main","runApplication","error","logger","getLogger","message","stack","process","exit","then","catch"],"mappings":";;;;AAIA,CAAA,CAAA,CAAA;;AAEC,CAAA,CAAA,CAAA,CACD,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAeA,IAAAA,CAAAA,CAAAA,CAAAA,CAAAA;IACX,CAAA,CAAA,CAAA,CAAI,CAAA;QACA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAMC,cAAAA,CAAAA,CAAAA,CAAAA;AACV,CAAA,CAAA,CAAA,CAAA,CAAA,CAAE,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAOC,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAY,CAAA;AACjB,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAMC,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAASC,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA;AACfD,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAOD,CAAAA,CAAAA,CAAAA,CAAAA,CAAK,CAAC,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAuFA,CAAAA,CAAAA,CAAAA,CAAAA,EAAMG,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAO,CAAA,CAAEH,CAAAA,CAAAA,CAAAA,CAAAA,EAAMI,KAAK,CAAA,CAAA;AAC9HC,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAQC,CAAAA,CAAAA,CAAAA,CAAI,CAAC,CAAA,CAAA,CAAA;AACjB,CAAA,CAAA,CAAA,CAAA,CAAA;AACJ,CAAA;AAEA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;AACAR,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAOS,CAAAA,CAAAA,CAAAA,CAAI,CAAC,CAAA,CAAA,CAAA,CAAA,CAAA;AACRF,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAQC,CAAAA,CAAAA,CAAAA,CAAI,CAAC,CAAA,CAAA,CAAA;AACjB,CAAA,CAAA,CAAGE,CAAAA,CAAAA,CAAAA,CAAAA,CAAK,CAAC,CAACR,KAAAA,CAAAA,CAAAA,CAAAA,CAAAA;AACN,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAMC,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAASC,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA;AACfD,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAOD,CAAAA,CAAAA,CAAAA,CAAAA,CAAK,CAAC,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAuFA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAMG,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAO,CAAA,CAAA,CAAA,CAAIH,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA;AACrHK,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAQC,CAAAA,CAAAA,CAAAA,CAAI,CAAC,CAAA,CAAA,CAAA;AACjB,CAAA,CAAA"}
@@ -52,11 +52,11 @@ class CheckpointManager {
52
52
  }
53
53
  return checkpoint;
54
54
  } catch (error) {
55
- this.logger.error(`Failed to load checkpoint: ${error.message}`);
55
+ this.logger.error(`CHECKPOINT_LOAD_FAILED: Failed to load checkpoint file | Error: ${error.message} | Impact: Cannot resume execution`);
56
56
  // Try backup
57
57
  const backup = await this.loadBackup();
58
58
  if (backup) {
59
- this.logger.info('Recovered from backup checkpoint');
59
+ this.logger.info('CHECKPOINT_RECOVERED_BACKUP: Recovered from backup checkpoint | Source: backup | Status: loaded');
60
60
  return backup;
61
61
  }
62
62
  return null;
@@ -104,7 +104,7 @@ class CheckpointManager {
104
104
  }
105
105
  const elapsed = Date.now() - startTime;
106
106
  if (elapsed > maxWaitMs) {
107
- this.logger.warn('Breaking stale checkpoint lock');
107
+ this.logger.warn('CHECKPOINT_LOCK_STALE: Breaking stale checkpoint lock | Reason: Lock expired | Action: Force break lock');
108
108
  await fs.unlink(this.lockPath).catch(()=>{});
109
109
  continue;
110
110
  }
@@ -129,7 +129,7 @@ class CheckpointManager {
129
129
  ...checkpoint.state.skipped
130
130
  ]);
131
131
  if (allPackages.size !== checkpoint.buildOrder.length) {
132
- this.logger.warn('Checkpoint state inconsistency detected');
132
+ this.logger.warn('CHECKPOINT_INCONSISTENCY: Checkpoint state inconsistency detected | Issue: State validation failed | Impact: May need manual recovery');
133
133
  }
134
134
  }
135
135
  isCompatibleVersion(version) {
@@ -1 +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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"}
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(`CHECKPOINT_LOAD_FAILED: Failed to load checkpoint file | Error: ${error.message} | Impact: Cannot resume execution`);\n\n // Try backup\n const backup = await this.loadBackup();\n if (backup) {\n this.logger.info('CHECKPOINT_RECOVERED_BACKUP: Recovered from backup checkpoint | Source: backup | Status: loaded');\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('CHECKPOINT_LOCK_STALE: Breaking stale checkpoint lock | Reason: Lock expired | Action: Force break 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_INCONSISTENCY: Checkpoint state inconsistency detected | Issue: State validation failed | Impact: May need manual recovery');\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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"}
@@ -69,7 +69,7 @@ import { create } from './storage.js';
69
69
  }
70
70
  }
71
71
  } catch (error) {
72
- logger.error(`Failed to scan directory ${directory}: ${error}`);
72
+ logger.error(`DEPENDENCY_GRAPH_SCAN_FAILED: Failed to scan directory | Directory: ${directory} | Error: ${error}`);
73
73
  throw error;
74
74
  }
75
75
  return packageJsonPaths;
@@ -116,7 +116,7 @@ import { create } from './storage.js';
116
116
  localDependencies: new Set() // Will be populated later
117
117
  };
118
118
  } catch (error) {
119
- logger.error(`Failed to parse package.json at ${packageJsonPath}: ${error}`);
119
+ logger.error(`DEPENDENCY_GRAPH_PARSE_FAILED: Failed to parse package.json | Path: ${packageJsonPath} | Error: ${error}`);
120
120
  throw error;
121
121
  }
122
122
  }
@@ -1 +1 @@
1
- {"version":3,"file":"dependencyGraph.js","sources":["../../src/util/dependencyGraph.ts"],"sourcesContent":["import path from 'path';\nimport fs from 'fs/promises';\nimport { safeJsonParse, validatePackageJson } from '@eldrforge/git-tools';\nimport { getLogger } from '../logging';\nimport { create as createStorage } from './storage';\n\n/**\n * Check if a file path matches a glob pattern\n */\nconst matchesPattern = (filePath: string, pattern: string): boolean => {\n // Convert simple glob patterns to regex\n const regexPattern = pattern\n .replace(/\\\\/g, '\\\\\\\\') // Escape backslashes\n .replace(/\\*\\*/g, '.*') // ** matches any path segments\n .replace(/\\*/g, '[^/]*') // * matches any characters except path separator\n .replace(/\\?/g, '.') // ? matches any single character\n .replace(/\\./g, '\\\\.'); // Escape literal dots\n\n const regex = new RegExp(`^${regexPattern}$`);\n return regex.test(filePath) || regex.test(path.basename(filePath));\n};\n\n/**\n * Check if a package should be excluded based on patterns\n */\nexport function shouldExclude(packageJsonPath: string, excludedPatterns: string[]): boolean {\n if (!excludedPatterns || excludedPatterns.length === 0) {\n return false;\n }\n\n // Check both the full path and relative path patterns\n const relativePath = path.relative(process.cwd(), packageJsonPath);\n\n return excludedPatterns.some(pattern =>\n matchesPattern(packageJsonPath, pattern) ||\n matchesPattern(relativePath, pattern) ||\n matchesPattern(path.dirname(packageJsonPath), pattern) ||\n matchesPattern(path.dirname(relativePath), pattern)\n );\n}\n\nexport interface PackageInfo {\n name: string;\n version: string;\n path: string;\n dependencies: Set<string>;\n devDependencies: Set<string>;\n localDependencies: Set<string>;\n}\n\nexport interface DependencyGraph {\n packages: Map<string, PackageInfo>;\n edges: Map<string, Set<string>>; // package -> dependencies\n reverseEdges: Map<string, Set<string>>; // package -> dependents\n}\n\nexport interface SerializedGraph {\n packages: Array<{\n name: string;\n version: string;\n path: string;\n dependencies: string[];\n }>;\n edges: Array<[string, string[]]>;\n}\n\n/**\n * Scan directory for package.json files\n */\nexport async function scanForPackageJsonFiles(\n directory: string,\n excludedPatterns: string[] = []\n): Promise<string[]> {\n const logger = getLogger();\n const packageJsonPaths: string[] = [];\n\n try {\n // First check if there's a package.json in the specified directory itself\n const directPackageJsonPath = path.join(directory, 'package.json');\n try {\n await fs.access(directPackageJsonPath);\n\n // Check if this package should be excluded\n if (!shouldExclude(directPackageJsonPath, excludedPatterns)) {\n packageJsonPaths.push(directPackageJsonPath);\n logger.verbose(`Found package.json at: ${directPackageJsonPath}`);\n } else {\n logger.verbose(`Excluding package.json at: ${directPackageJsonPath} (matches exclusion pattern)`);\n }\n } catch {\n // No package.json in the root of this directory, that's fine\n }\n\n // Then scan subdirectories for package.json files\n const entries = await fs.readdir(directory, { withFileTypes: true });\n\n for (const entry of entries) {\n if (entry.isDirectory()) {\n const subDirPath = path.join(directory, entry.name);\n const packageJsonPath = path.join(subDirPath, 'package.json');\n\n try {\n await fs.access(packageJsonPath);\n\n // Check if this package should be excluded\n if (shouldExclude(packageJsonPath, excludedPatterns)) {\n logger.verbose(`Excluding package.json at: ${packageJsonPath} (matches exclusion pattern)`);\n continue;\n }\n\n packageJsonPaths.push(packageJsonPath);\n logger.verbose(`Found package.json at: ${packageJsonPath}`);\n } catch {\n // No package.json in this directory, continue\n }\n }\n }\n } catch (error) {\n logger.error(`Failed to scan directory ${directory}: ${error}`);\n throw error;\n }\n\n return packageJsonPaths;\n}\n\n/**\n * Parse a single package.json file\n */\nexport async function parsePackageJson(packageJsonPath: string): Promise<PackageInfo> {\n const logger = getLogger();\n const storage = createStorage({ log: logger.info });\n\n try {\n const content = await storage.readFile(packageJsonPath, 'utf-8');\n const parsed = safeJsonParse(content, packageJsonPath);\n const packageJson = validatePackageJson(parsed, packageJsonPath);\n\n if (!packageJson.name) {\n throw new Error(`Package at ${packageJsonPath} has no name field`);\n }\n\n const dependencies = new Set<string>();\n const devDependencies = new Set<string>();\n\n // Collect all types of dependencies\n const depTypes = ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies'];\n for (const depType of depTypes) {\n if (packageJson[depType]) {\n Object.keys(packageJson[depType]).forEach(dep => {\n dependencies.add(dep);\n if (depType === 'devDependencies') {\n devDependencies.add(dep);\n }\n });\n }\n }\n\n return {\n name: packageJson.name,\n version: packageJson.version || '0.0.0',\n path: path.dirname(packageJsonPath),\n dependencies,\n devDependencies,\n localDependencies: new Set() // Will be populated later\n };\n } catch (error) {\n logger.error(`Failed to parse package.json at ${packageJsonPath}: ${error}`);\n throw error;\n }\n}\n\n/**\n * Build dependency graph from package.json paths\n */\nexport async function buildDependencyGraph(\n packageJsonPaths: string[]\n): Promise<DependencyGraph> {\n const logger = getLogger();\n const packages = new Map<string, PackageInfo>();\n const edges = new Map<string, Set<string>>();\n\n // First pass: parse all package.json files\n for (const packageJsonPath of packageJsonPaths) {\n const packageInfo = await parsePackageJson(packageJsonPath);\n packages.set(packageInfo.name, packageInfo);\n logger.verbose(`Parsed package: ${packageInfo.name} at ${packageInfo.path}`);\n }\n\n // Second pass: identify local dependencies and build edges\n for (const [packageName, packageInfo] of packages) {\n const localDeps = new Set<string>();\n const edgesSet = new Set<string>();\n\n for (const dep of packageInfo.dependencies) {\n if (packages.has(dep)) {\n localDeps.add(dep);\n edgesSet.add(dep);\n logger.verbose(`${packageName} depends on local package: ${dep}`);\n }\n }\n\n packageInfo.localDependencies = localDeps;\n edges.set(packageName, edgesSet);\n }\n\n // Build reverse edges (dependents)\n const reverseEdges = buildReverseGraph(edges);\n\n return { packages, edges, reverseEdges };\n}\n\n/**\n * Build reverse dependency graph (package -> dependents)\n */\nexport function buildReverseGraph(\n edges: Map<string, Set<string>>\n): Map<string, Set<string>> {\n const reverse = new Map<string, Set<string>>();\n\n for (const [pkg, deps] of edges) {\n for (const dep of deps) {\n if (!reverse.has(dep)) {\n reverse.set(dep, new Set());\n }\n reverse.get(dep)!.add(pkg);\n }\n }\n\n return reverse;\n}\n\n/**\n * Perform topological sort on dependency graph\n */\nexport function topologicalSort(graph: DependencyGraph): string[] {\n const logger = getLogger();\n const { packages, edges } = graph;\n const visited = new Set<string>();\n const visiting = new Set<string>();\n const result: string[] = [];\n\n const visit = (packageName: string): void => {\n if (visited.has(packageName)) {\n return;\n }\n\n if (visiting.has(packageName)) {\n throw new Error(`Circular dependency detected involving package: ${packageName}`);\n }\n\n visiting.add(packageName);\n\n // Visit all dependencies first\n const deps = edges.get(packageName) || new Set();\n for (const dep of deps) {\n visit(dep);\n }\n\n visiting.delete(packageName);\n visited.add(packageName);\n result.push(packageName);\n };\n\n // Visit all packages\n for (const packageName of packages.keys()) {\n if (!visited.has(packageName)) {\n visit(packageName);\n }\n }\n\n logger.verbose(`Topological sort completed. Build order determined for ${result.length} packages.`);\n return result;\n}\n\n/**\n * Find all dependents of a package (packages that depend on it)\n */\nexport function findAllDependents(\n packageName: string,\n graph: DependencyGraph\n): Set<string> {\n const dependents = new Set<string>();\n const visited = new Set<string>();\n\n const traverse = (pkg: string) => {\n if (visited.has(pkg)) return;\n visited.add(pkg);\n\n const directDependents = graph.reverseEdges.get(pkg) || new Set();\n for (const dependent of directDependents) {\n dependents.add(dependent);\n traverse(dependent);\n }\n };\n\n traverse(packageName);\n return dependents;\n}\n\n/**\n * Serialize graph for checkpoint persistence\n */\nexport function serializeGraph(graph: DependencyGraph): SerializedGraph {\n return {\n packages: Array.from(graph.packages.values()).map(pkg => ({\n name: pkg.name,\n version: pkg.version,\n path: pkg.path,\n dependencies: Array.from(pkg.dependencies)\n })),\n edges: Array.from(graph.edges.entries()).map(([pkg, deps]) => [\n pkg,\n Array.from(deps)\n ])\n };\n}\n\n/**\n * Deserialize graph from checkpoint\n */\nexport function deserializeGraph(serialized: SerializedGraph): DependencyGraph {\n const packages = new Map<string, PackageInfo>();\n const edges = new Map<string, Set<string>>();\n\n // Restore packages\n for (const pkg of serialized.packages) {\n packages.set(pkg.name, {\n name: pkg.name,\n version: pkg.version,\n path: pkg.path,\n dependencies: new Set(pkg.dependencies),\n devDependencies: new Set(),\n localDependencies: new Set()\n });\n }\n\n // Restore edges\n for (const [pkg, deps] of serialized.edges) {\n edges.set(pkg, new Set(deps));\n }\n\n // Build reverse edges\n const reverseEdges = buildReverseGraph(edges);\n\n return { packages, edges, reverseEdges };\n}\n\n/**\n * Validate graph integrity\n */\nexport function validateGraph(graph: DependencyGraph): {\n valid: boolean;\n errors: string[];\n} {\n const errors: string[] = [];\n\n // Check all edge targets exist\n for (const [pkg, deps] of graph.edges) {\n for (const dep of deps) {\n if (!graph.packages.has(dep)) {\n errors.push(`Package ${pkg} depends on ${dep} which doesn't exist`);\n }\n }\n }\n\n // Check for circular dependencies\n try {\n topologicalSort(graph);\n } catch (error: any) {\n errors.push(error.message);\n }\n\n return {\n valid: errors.length === 0,\n errors\n };\n}\n"],"names":["matchesPattern","filePath","pattern","regexPattern","replace","regex","RegExp","test","path","basename","shouldExclude","packageJsonPath","excludedPatterns","length","relativePath","relative","process","cwd","some","dirname","scanForPackageJsonFiles","directory","logger","getLogger","packageJsonPaths","directPackageJsonPath","join","fs","access","push","verbose","entries","readdir","withFileTypes","entry","isDirectory","subDirPath","name","error","parsePackageJson","storage","createStorage","log","info","content","readFile","parsed","safeJsonParse","packageJson","validatePackageJson","Error","dependencies","Set","devDependencies","depTypes","depType","Object","keys","forEach","dep","add","version","localDependencies","buildDependencyGraph","packages","Map","edges","packageInfo","set","packageName","localDeps","edgesSet","has","reverseEdges","buildReverseGraph","reverse","pkg","deps","get","topologicalSort","graph","visited","visiting","result","visit","delete","findAllDependents","dependents","traverse","directDependents","dependent"],"mappings":"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"}
1
+ {"version":3,"file":"dependencyGraph.js","sources":["../../src/util/dependencyGraph.ts"],"sourcesContent":["import path from 'path';\nimport fs from 'fs/promises';\nimport { safeJsonParse, validatePackageJson } from '@eldrforge/git-tools';\nimport { getLogger } from '../logging';\nimport { create as createStorage } from './storage';\n\n/**\n * Check if a file path matches a glob pattern\n */\nconst matchesPattern = (filePath: string, pattern: string): boolean => {\n // Convert simple glob patterns to regex\n const regexPattern = pattern\n .replace(/\\\\/g, '\\\\\\\\') // Escape backslashes\n .replace(/\\*\\*/g, '.*') // ** matches any path segments\n .replace(/\\*/g, '[^/]*') // * matches any characters except path separator\n .replace(/\\?/g, '.') // ? matches any single character\n .replace(/\\./g, '\\\\.'); // Escape literal dots\n\n const regex = new RegExp(`^${regexPattern}$`);\n return regex.test(filePath) || regex.test(path.basename(filePath));\n};\n\n/**\n * Check if a package should be excluded based on patterns\n */\nexport function shouldExclude(packageJsonPath: string, excludedPatterns: string[]): boolean {\n if (!excludedPatterns || excludedPatterns.length === 0) {\n return false;\n }\n\n // Check both the full path and relative path patterns\n const relativePath = path.relative(process.cwd(), packageJsonPath);\n\n return excludedPatterns.some(pattern =>\n matchesPattern(packageJsonPath, pattern) ||\n matchesPattern(relativePath, pattern) ||\n matchesPattern(path.dirname(packageJsonPath), pattern) ||\n matchesPattern(path.dirname(relativePath), pattern)\n );\n}\n\nexport interface PackageInfo {\n name: string;\n version: string;\n path: string;\n dependencies: Set<string>;\n devDependencies: Set<string>;\n localDependencies: Set<string>;\n}\n\nexport interface DependencyGraph {\n packages: Map<string, PackageInfo>;\n edges: Map<string, Set<string>>; // package -> dependencies\n reverseEdges: Map<string, Set<string>>; // package -> dependents\n}\n\nexport interface SerializedGraph {\n packages: Array<{\n name: string;\n version: string;\n path: string;\n dependencies: string[];\n }>;\n edges: Array<[string, string[]]>;\n}\n\n/**\n * Scan directory for package.json files\n */\nexport async function scanForPackageJsonFiles(\n directory: string,\n excludedPatterns: string[] = []\n): Promise<string[]> {\n const logger = getLogger();\n const packageJsonPaths: string[] = [];\n\n try {\n // First check if there's a package.json in the specified directory itself\n const directPackageJsonPath = path.join(directory, 'package.json');\n try {\n await fs.access(directPackageJsonPath);\n\n // Check if this package should be excluded\n if (!shouldExclude(directPackageJsonPath, excludedPatterns)) {\n packageJsonPaths.push(directPackageJsonPath);\n logger.verbose(`Found package.json at: ${directPackageJsonPath}`);\n } else {\n logger.verbose(`Excluding package.json at: ${directPackageJsonPath} (matches exclusion pattern)`);\n }\n } catch {\n // No package.json in the root of this directory, that's fine\n }\n\n // Then scan subdirectories for package.json files\n const entries = await fs.readdir(directory, { withFileTypes: true });\n\n for (const entry of entries) {\n if (entry.isDirectory()) {\n const subDirPath = path.join(directory, entry.name);\n const packageJsonPath = path.join(subDirPath, 'package.json');\n\n try {\n await fs.access(packageJsonPath);\n\n // Check if this package should be excluded\n if (shouldExclude(packageJsonPath, excludedPatterns)) {\n logger.verbose(`Excluding package.json at: ${packageJsonPath} (matches exclusion pattern)`);\n continue;\n }\n\n packageJsonPaths.push(packageJsonPath);\n logger.verbose(`Found package.json at: ${packageJsonPath}`);\n } catch {\n // No package.json in this directory, continue\n }\n }\n }\n } catch (error) {\n logger.error(`DEPENDENCY_GRAPH_SCAN_FAILED: Failed to scan directory | Directory: ${directory} | Error: ${error}`);\n throw error;\n }\n\n return packageJsonPaths;\n}\n\n/**\n * Parse a single package.json file\n */\nexport async function parsePackageJson(packageJsonPath: string): Promise<PackageInfo> {\n const logger = getLogger();\n const storage = createStorage({ log: logger.info });\n\n try {\n const content = await storage.readFile(packageJsonPath, 'utf-8');\n const parsed = safeJsonParse(content, packageJsonPath);\n const packageJson = validatePackageJson(parsed, packageJsonPath);\n\n if (!packageJson.name) {\n throw new Error(`Package at ${packageJsonPath} has no name field`);\n }\n\n const dependencies = new Set<string>();\n const devDependencies = new Set<string>();\n\n // Collect all types of dependencies\n const depTypes = ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies'];\n for (const depType of depTypes) {\n if (packageJson[depType]) {\n Object.keys(packageJson[depType]).forEach(dep => {\n dependencies.add(dep);\n if (depType === 'devDependencies') {\n devDependencies.add(dep);\n }\n });\n }\n }\n\n return {\n name: packageJson.name,\n version: packageJson.version || '0.0.0',\n path: path.dirname(packageJsonPath),\n dependencies,\n devDependencies,\n localDependencies: new Set() // Will be populated later\n };\n } catch (error) {\n logger.error(`DEPENDENCY_GRAPH_PARSE_FAILED: Failed to parse package.json | Path: ${packageJsonPath} | Error: ${error}`);\n throw error;\n }\n}\n\n/**\n * Build dependency graph from package.json paths\n */\nexport async function buildDependencyGraph(\n packageJsonPaths: string[]\n): Promise<DependencyGraph> {\n const logger = getLogger();\n const packages = new Map<string, PackageInfo>();\n const edges = new Map<string, Set<string>>();\n\n // First pass: parse all package.json files\n for (const packageJsonPath of packageJsonPaths) {\n const packageInfo = await parsePackageJson(packageJsonPath);\n packages.set(packageInfo.name, packageInfo);\n logger.verbose(`Parsed package: ${packageInfo.name} at ${packageInfo.path}`);\n }\n\n // Second pass: identify local dependencies and build edges\n for (const [packageName, packageInfo] of packages) {\n const localDeps = new Set<string>();\n const edgesSet = new Set<string>();\n\n for (const dep of packageInfo.dependencies) {\n if (packages.has(dep)) {\n localDeps.add(dep);\n edgesSet.add(dep);\n logger.verbose(`${packageName} depends on local package: ${dep}`);\n }\n }\n\n packageInfo.localDependencies = localDeps;\n edges.set(packageName, edgesSet);\n }\n\n // Build reverse edges (dependents)\n const reverseEdges = buildReverseGraph(edges);\n\n return { packages, edges, reverseEdges };\n}\n\n/**\n * Build reverse dependency graph (package -> dependents)\n */\nexport function buildReverseGraph(\n edges: Map<string, Set<string>>\n): Map<string, Set<string>> {\n const reverse = new Map<string, Set<string>>();\n\n for (const [pkg, deps] of edges) {\n for (const dep of deps) {\n if (!reverse.has(dep)) {\n reverse.set(dep, new Set());\n }\n reverse.get(dep)!.add(pkg);\n }\n }\n\n return reverse;\n}\n\n/**\n * Perform topological sort on dependency graph\n */\nexport function topologicalSort(graph: DependencyGraph): string[] {\n const logger = getLogger();\n const { packages, edges } = graph;\n const visited = new Set<string>();\n const visiting = new Set<string>();\n const result: string[] = [];\n\n const visit = (packageName: string): void => {\n if (visited.has(packageName)) {\n return;\n }\n\n if (visiting.has(packageName)) {\n throw new Error(`Circular dependency detected involving package: ${packageName}`);\n }\n\n visiting.add(packageName);\n\n // Visit all dependencies first\n const deps = edges.get(packageName) || new Set();\n for (const dep of deps) {\n visit(dep);\n }\n\n visiting.delete(packageName);\n visited.add(packageName);\n result.push(packageName);\n };\n\n // Visit all packages\n for (const packageName of packages.keys()) {\n if (!visited.has(packageName)) {\n visit(packageName);\n }\n }\n\n logger.verbose(`Topological sort completed. Build order determined for ${result.length} packages.`);\n return result;\n}\n\n/**\n * Find all dependents of a package (packages that depend on it)\n */\nexport function findAllDependents(\n packageName: string,\n graph: DependencyGraph\n): Set<string> {\n const dependents = new Set<string>();\n const visited = new Set<string>();\n\n const traverse = (pkg: string) => {\n if (visited.has(pkg)) return;\n visited.add(pkg);\n\n const directDependents = graph.reverseEdges.get(pkg) || new Set();\n for (const dependent of directDependents) {\n dependents.add(dependent);\n traverse(dependent);\n }\n };\n\n traverse(packageName);\n return dependents;\n}\n\n/**\n * Serialize graph for checkpoint persistence\n */\nexport function serializeGraph(graph: DependencyGraph): SerializedGraph {\n return {\n packages: Array.from(graph.packages.values()).map(pkg => ({\n name: pkg.name,\n version: pkg.version,\n path: pkg.path,\n dependencies: Array.from(pkg.dependencies)\n })),\n edges: Array.from(graph.edges.entries()).map(([pkg, deps]) => [\n pkg,\n Array.from(deps)\n ])\n };\n}\n\n/**\n * Deserialize graph from checkpoint\n */\nexport function deserializeGraph(serialized: SerializedGraph): DependencyGraph {\n const packages = new Map<string, PackageInfo>();\n const edges = new Map<string, Set<string>>();\n\n // Restore packages\n for (const pkg of serialized.packages) {\n packages.set(pkg.name, {\n name: pkg.name,\n version: pkg.version,\n path: pkg.path,\n dependencies: new Set(pkg.dependencies),\n devDependencies: new Set(),\n localDependencies: new Set()\n });\n }\n\n // Restore edges\n for (const [pkg, deps] of serialized.edges) {\n edges.set(pkg, new Set(deps));\n }\n\n // Build reverse edges\n const reverseEdges = buildReverseGraph(edges);\n\n return { packages, edges, reverseEdges };\n}\n\n/**\n * Validate graph integrity\n */\nexport function validateGraph(graph: DependencyGraph): {\n valid: boolean;\n errors: string[];\n} {\n const errors: string[] = [];\n\n // Check all edge targets exist\n for (const [pkg, deps] of graph.edges) {\n for (const dep of deps) {\n if (!graph.packages.has(dep)) {\n errors.push(`Package ${pkg} depends on ${dep} which doesn't exist`);\n }\n }\n }\n\n // Check for circular dependencies\n try {\n topologicalSort(graph);\n } catch (error: any) {\n errors.push(error.message);\n }\n\n return {\n valid: errors.length === 0,\n errors\n };\n}\n"],"names":["matchesPattern","filePath","pattern","regexPattern","replace","regex","RegExp","test","path","basename","shouldExclude","packageJsonPath","excludedPatterns","length","relativePath","relative","process","cwd","some","dirname","scanForPackageJsonFiles","directory","logger","getLogger","packageJsonPaths","directPackageJsonPath","join","fs","access","push","verbose","entries","readdir","withFileTypes","entry","isDirectory","subDirPath","name","error","parsePackageJson","storage","createStorage","log","info","content","readFile","parsed","safeJsonParse","packageJson","validatePackageJson","Error","dependencies","Set","devDependencies","depTypes","depType","Object","keys","forEach","dep","add","version","localDependencies","buildDependencyGraph","packages","Map","edges","packageInfo","set","packageName","localDeps","edgesSet","has","reverseEdges","buildReverseGraph","reverse","pkg","deps","get","topologicalSort","graph","visited","visiting","result","visit","delete","findAllDependents","dependents","traverse","directDependents","dependent"],"mappings":"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"}
@@ -195,7 +195,7 @@ function _define_property(obj, key, value) {
195
195
  process.exit(143); // Standard exit code for SIGTERM
196
196
  });
197
197
  process.on('uncaughtException', (error)=>{
198
- this.logger.error('Uncaught exception, cleaning up locks:', error);
198
+ this.logger.error('FILELOCK_UNCAUGHT_EXCEPTION: Uncaught exception detected, cleaning up locks | Error: ' + error + ' | Action: Release all locks');
199
199
  cleanup();
200
200
  process.exit(1);
201
201
  });
@@ -1 +1 @@
1
- {"version":3,"file":"fileLock.js","sources":["../../src/util/fileLock.ts"],"sourcesContent":["// eslint-disable-next-line no-restricted-imports\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\nimport { getLogger } from '../logging';\n\n/**\n * File-based lock for cross-process synchronization\n * Uses atomic file operations to coordinate across multiple Node processes\n */\nexport class FileLock {\n private lockPath: string;\n private lockAcquired = false;\n private maxRetries = 100; // Maximum number of lock attempts\n private retryDelay = 100; // Initial retry delay in ms\n private maxRetryDelay = 2000; // Maximum retry delay in ms\n private lockTimeout = 30000; // Consider lock stale after 30 seconds\n private logger = getLogger();\n\n constructor(lockPath: string) {\n this.lockPath = lockPath;\n }\n\n /**\n * Acquire the file lock with exponential backoff retry\n */\n async lock(): Promise<void> {\n let attempts = 0;\n let currentDelay = this.retryDelay;\n\n while (attempts < this.maxRetries) {\n try {\n // Try to create lock file atomically with 'wx' flag (fails if exists)\n const lockData = {\n pid: process.pid,\n timestamp: Date.now(),\n hostname: os.hostname()\n };\n\n // Check if lock file exists and is stale\n if (fs.existsSync(this.lockPath)) {\n const lockContent = fs.readFileSync(this.lockPath, 'utf-8');\n try {\n const existingLock = JSON.parse(lockContent);\n const lockAge = Date.now() - existingLock.timestamp;\n\n // If lock is stale, try to remove it\n if (lockAge > this.lockTimeout) {\n this.logger.debug(`Removing stale lock file (age: ${lockAge}ms, pid: ${existingLock.pid})`);\n try {\n fs.unlinkSync(this.lockPath);\n } catch {\n // Lock might have been removed by another process, continue\n }\n }\n } catch {\n // Invalid lock file, try to remove it\n try {\n fs.unlinkSync(this.lockPath);\n } catch {\n // Ignore errors\n }\n }\n }\n\n // Try to acquire lock\n fs.writeFileSync(this.lockPath, JSON.stringify(lockData, null, 2), { flag: 'wx' });\n this.lockAcquired = true;\n\n if (attempts > 0) {\n this.logger.debug(`Acquired file lock after ${attempts} attempts: ${this.lockPath}`);\n }\n\n return;\n } catch (error: any) {\n if (error.code === 'EEXIST') {\n // Lock file exists, retry with backoff\n attempts++;\n\n if (attempts === 1 || attempts % 10 === 0) {\n this.logger.verbose(`Waiting for file lock (attempt ${attempts}/${this.maxRetries}): ${this.lockPath}`);\n }\n\n await new Promise(resolve => setTimeout(resolve, currentDelay));\n\n // Exponential backoff\n currentDelay = Math.min(currentDelay * 1.5, this.maxRetryDelay);\n } else {\n // Unexpected error\n throw new Error(`Failed to acquire file lock ${this.lockPath}: ${error.message}`);\n }\n }\n }\n\n throw new Error(`Failed to acquire file lock after ${this.maxRetries} attempts: ${this.lockPath}`);\n }\n\n /**\n * Release the file lock\n */\n unlock(): void {\n if (!this.lockAcquired) {\n return;\n }\n\n try {\n if (fs.existsSync(this.lockPath)) {\n fs.unlinkSync(this.lockPath);\n }\n this.lockAcquired = false;\n this.logger.silly(`Released file lock: ${this.lockPath}`);\n } catch (error: any) {\n // Lock file might have been removed by another process or stale lock cleanup\n this.logger.debug(`Error releasing file lock ${this.lockPath}: ${error.message}`);\n this.lockAcquired = false;\n }\n }\n\n /**\n * Check if this instance currently holds the lock\n */\n isLocked(): boolean {\n return this.lockAcquired;\n }\n}\n\n/**\n * Manages file-based locks for git repositories (cross-process safe)\n */\nexport class RepositoryFileLockManager {\n private locks: Map<string, FileLock> = new Map();\n private logger = getLogger();\n private cleanupRegistered = false;\n\n /**\n * Get or create a file lock for a specific git repository\n * @param repoPath Path to the git repository root\n * @returns FileLock for this repository\n */\n getRepositoryLock(repoPath: string): FileLock {\n const normalizedPath = path.resolve(repoPath);\n\n if (!this.locks.has(normalizedPath)) {\n // Resolve the actual .git directory (handles both regular repos and submodules)\n const gitDirPath = this.resolveGitDirectory(normalizedPath);\n const lockPath = path.join(gitDirPath, 'kodrdriv.lock');\n this.logger.debug(`Creating file lock for repository: ${normalizedPath} at ${lockPath}`);\n this.locks.set(normalizedPath, new FileLock(lockPath));\n\n // Register cleanup handler on first lock creation\n if (!this.cleanupRegistered) {\n this.registerCleanupHandlers();\n this.cleanupRegistered = true;\n }\n }\n\n return this.locks.get(normalizedPath)!;\n }\n\n /**\n * Resolve the actual .git directory path, handling both regular repos and submodules\n * @param repoPath Path to the repository root\n * @returns Path to the actual .git directory\n */\n private resolveGitDirectory(repoPath: string): string {\n const gitPath = path.join(repoPath, '.git');\n\n try {\n const stat = fs.statSync(gitPath);\n\n if (stat.isDirectory()) {\n // Regular git repository\n return gitPath;\n } else if (stat.isFile()) {\n // Git submodule - .git is a file with format: gitdir: <path>\n const gitFileContent = fs.readFileSync(gitPath, 'utf-8').trim();\n const match = gitFileContent.match(/^gitdir:\\s*(.+)$/);\n\n if (match && match[1]) {\n // Resolve the gitdir path (it's relative to the repo path)\n const gitDirPath = path.resolve(repoPath, match[1]);\n this.logger.debug(`Resolved submodule gitdir: ${gitDirPath}`);\n\n // Ensure the git directory exists\n if (!fs.existsSync(gitDirPath)) {\n throw new Error(`Submodule git directory does not exist: ${gitDirPath}`);\n }\n\n return gitDirPath;\n }\n\n throw new Error(`Invalid .git file format in ${gitPath}: ${gitFileContent}`);\n }\n } catch (error: any) {\n // Check if error is from statSync (file doesn't exist)\n if (error.code === 'ENOENT') {\n throw new Error(`No .git directory or file found in ${repoPath}`);\n }\n throw new Error(`Failed to resolve git directory for ${repoPath}: ${error.message}`);\n }\n\n throw new Error(`No .git directory or file found in ${repoPath}`);\n }\n\n /**\n * Register cleanup handlers to release locks on process exit\n */\n private registerCleanupHandlers(): void {\n const cleanup = () => {\n this.destroy();\n };\n\n // Handle various exit scenarios\n process.on('exit', cleanup);\n process.on('SIGINT', () => {\n cleanup();\n process.exit(130); // Standard exit code for SIGINT\n });\n process.on('SIGTERM', () => {\n cleanup();\n process.exit(143); // Standard exit code for SIGTERM\n });\n process.on('uncaughtException', (error) => {\n this.logger.error('Uncaught exception, cleaning up locks:', error);\n cleanup();\n process.exit(1);\n });\n }\n\n /**\n * Execute a git operation with repository-level file locking\n * @param repoPath Path to the git repository root\n * @param operation The async operation to execute under lock\n * @param operationName Optional name for logging\n * @returns Result of the operation\n */\n async withGitLock<T>(\n repoPath: string,\n operation: () => Promise<T>,\n operationName?: string\n ): Promise<T> {\n const lock = this.getRepositoryLock(repoPath);\n const startWait = Date.now();\n\n this.logger.silly(\n `Acquiring file lock for ${repoPath}${operationName ? ` for: ${operationName}` : ''}`\n );\n\n await lock.lock();\n\n const waitTime = Date.now() - startWait;\n if (waitTime > 100) {\n this.logger.debug(\n `Acquired file lock for ${repoPath} after ${waitTime}ms${operationName ? ` for: ${operationName}` : ''}`\n );\n }\n\n try {\n return await operation();\n } finally {\n lock.unlock();\n }\n }\n\n /**\n * Clean up all locks\n */\n destroy(): void {\n this.logger.debug(`Cleaning up ${this.locks.size} file lock(s)`);\n for (const lock of this.locks.values()) {\n lock.unlock();\n }\n this.locks.clear();\n }\n}\n"],"names":["FileLock","lock","attempts","currentDelay","retryDelay","maxRetries","lockData","pid","process","timestamp","Date","now","hostname","os","fs","existsSync","lockPath","lockContent","readFileSync","existingLock","JSON","parse","lockAge","lockTimeout","logger","debug","unlinkSync","writeFileSync","stringify","flag","lockAcquired","error","code","verbose","Promise","resolve","setTimeout","Math","min","maxRetryDelay","Error","message","unlock","silly","isLocked","getLogger","RepositoryFileLockManager","getRepositoryLock","repoPath","normalizedPath","path","locks","has","gitDirPath","resolveGitDirectory","join","set","cleanupRegistered","registerCleanupHandlers","get","gitPath","stat","statSync","isDirectory","isFile","gitFileContent","trim","match","cleanup","destroy","on","exit","withGitLock","operation","operationName","startWait","waitTime","size","values","clear","Map"],"mappings":";;;;;AAAA;;;;;;;;;;;;;;AAMA;;;AAGC,IACM,MAAMA,QAAAA,CAAAA;AAaT;;AAEC,QACD,MAAMC,IAAAA,GAAsB;AACxB,QAAA,IAAIC,QAAAA,GAAW,CAAA;QACf,IAAIC,YAAAA,GAAe,IAAI,CAACC,UAAU;AAElC,QAAA,MAAOF,QAAAA,GAAW,IAAI,CAACG,UAAU,CAAE;YAC/B,IAAI;;AAEA,gBAAA,MAAMC,QAAAA,GAAW;AACbC,oBAAAA,GAAAA,EAAKC,QAAQD,GAAG;AAChBE,oBAAAA,SAAAA,EAAWC,KAAKC,GAAG,EAAA;AACnBC,oBAAAA,QAAAA,EAAUC,GAAGD,QAAQ;AACzB,iBAAA;;AAGA,gBAAA,IAAIE,GAAGC,UAAU,CAAC,IAAI,CAACC,QAAQ,CAAA,EAAG;AAC9B,oBAAA,MAAMC,cAAcH,EAAAA,CAAGI,YAAY,CAAC,IAAI,CAACF,QAAQ,EAAE,OAAA,CAAA;oBACnD,IAAI;wBACA,MAAMG,YAAAA,GAAeC,IAAAA,CAAKC,KAAK,CAACJ,WAAAA,CAAAA;AAChC,wBAAA,MAAMK,OAAAA,GAAUZ,IAAAA,CAAKC,GAAG,EAAA,GAAKQ,aAAaV,SAAS;;AAGnD,wBAAA,IAAIa,OAAAA,GAAU,IAAI,CAACC,WAAW,EAAE;AAC5B,4BAAA,IAAI,CAACC,MAAM,CAACC,KAAK,CAAC,CAAC,+BAA+B,EAAEH,OAAAA,CAAQ,SAAS,EAAEH,YAAAA,CAAaZ,GAAG,CAAC,CAAC,CAAC,CAAA;4BAC1F,IAAI;AACAO,gCAAAA,EAAAA,CAAGY,UAAU,CAAC,IAAI,CAACV,QAAQ,CAAA;AAC/B,4BAAA,CAAA,CAAE,OAAM;;AAER,4BAAA;AACJ,wBAAA;AACJ,oBAAA,CAAA,CAAE,OAAM;;wBAEJ,IAAI;AACAF,4BAAAA,EAAAA,CAAGY,UAAU,CAAC,IAAI,CAACV,QAAQ,CAAA;AAC/B,wBAAA,CAAA,CAAE,OAAM;;AAER,wBAAA;AACJ,oBAAA;AACJ,gBAAA;;gBAGAF,EAAAA,CAAGa,aAAa,CAAC,IAAI,CAACX,QAAQ,EAAEI,IAAAA,CAAKQ,SAAS,CAACtB,QAAAA,EAAU,IAAA,EAAM,CAAA,CAAA,EAAI;oBAAEuB,IAAAA,EAAM;AAAK,iBAAA,CAAA;gBAChF,IAAI,CAACC,YAAY,GAAG,IAAA;AAEpB,gBAAA,IAAI5B,WAAW,CAAA,EAAG;AACd,oBAAA,IAAI,CAACsB,MAAM,CAACC,KAAK,CAAC,CAAC,yBAAyB,EAAEvB,QAAAA,CAAS,WAAW,EAAE,IAAI,CAACc,QAAQ,CAAA,CAAE,CAAA;AACvF,gBAAA;AAEA,gBAAA;AACJ,YAAA,CAAA,CAAE,OAAOe,KAAAA,EAAY;gBACjB,IAAIA,KAAAA,CAAMC,IAAI,KAAK,QAAA,EAAU;;AAEzB9B,oBAAAA,QAAAA,EAAAA;AAEA,oBAAA,IAAIA,QAAAA,KAAa,CAAA,IAAKA,QAAAA,GAAW,EAAA,KAAO,CAAA,EAAG;wBACvC,IAAI,CAACsB,MAAM,CAACS,OAAO,CAAC,CAAC,+BAA+B,EAAE/B,QAAAA,CAAS,CAAC,EAAE,IAAI,CAACG,UAAU,CAAC,GAAG,EAAE,IAAI,CAACW,QAAQ,CAAA,CAAE,CAAA;AAC1G,oBAAA;AAEA,oBAAA,MAAM,IAAIkB,OAAAA,CAAQC,CAAAA,OAAAA,GAAWC,WAAWD,OAAAA,EAAShC,YAAAA,CAAAA,CAAAA;;AAGjDA,oBAAAA,YAAAA,GAAekC,KAAKC,GAAG,CAACnC,eAAe,GAAA,EAAK,IAAI,CAACoC,aAAa,CAAA;gBAClE,CAAA,MAAO;;AAEH,oBAAA,MAAM,IAAIC,KAAAA,CAAM,CAAC,4BAA4B,EAAE,IAAI,CAACxB,QAAQ,CAAC,EAAE,EAAEe,KAAAA,CAAMU,OAAO,CAAA,CAAE,CAAA;AACpF,gBAAA;AACJ,YAAA;AACJ,QAAA;AAEA,QAAA,MAAM,IAAID,KAAAA,CAAM,CAAC,kCAAkC,EAAE,IAAI,CAACnC,UAAU,CAAC,WAAW,EAAE,IAAI,CAACW,QAAQ,CAAA,CAAE,CAAA;AACrG,IAAA;AAEA;;AAEC,QACD0B,MAAAA,GAAe;AACX,QAAA,IAAI,CAAC,IAAI,CAACZ,YAAY,EAAE;AACpB,YAAA;AACJ,QAAA;QAEA,IAAI;AACA,YAAA,IAAIhB,GAAGC,UAAU,CAAC,IAAI,CAACC,QAAQ,CAAA,EAAG;AAC9BF,gBAAAA,EAAAA,CAAGY,UAAU,CAAC,IAAI,CAACV,QAAQ,CAAA;AAC/B,YAAA;YACA,IAAI,CAACc,YAAY,GAAG,KAAA;YACpB,IAAI,CAACN,MAAM,CAACmB,KAAK,CAAC,CAAC,oBAAoB,EAAE,IAAI,CAAC3B,QAAQ,CAAA,CAAE,CAAA;AAC5D,QAAA,CAAA,CAAE,OAAOe,KAAAA,EAAY;;AAEjB,YAAA,IAAI,CAACP,MAAM,CAACC,KAAK,CAAC,CAAC,0BAA0B,EAAE,IAAI,CAACT,QAAQ,CAAC,EAAE,EAAEe,KAAAA,CAAMU,OAAO,CAAA,CAAE,CAAA;YAChF,IAAI,CAACX,YAAY,GAAG,KAAA;AACxB,QAAA;AACJ,IAAA;AAEA;;AAEC,QACDc,QAAAA,GAAoB;QAChB,OAAO,IAAI,CAACd,YAAY;AAC5B,IAAA;AAxGA,IAAA,WAAA,CAAYd,QAAgB,CAAE;AAR9B,QAAA,gBAAA,CAAA,IAAA,EAAQA,YAAR,MAAA,CAAA;AACA,QAAA,gBAAA,CAAA,IAAA,EAAQc,cAAAA,EAAe,KAAA,CAAA;QACvB,gBAAA,CAAA,IAAA,EAAQzB,YAAAA,EAAa;QACrB,gBAAA,CAAA,IAAA,EAAQD,YAAAA,EAAa;QACrB,gBAAA,CAAA,IAAA,EAAQmC,eAAAA,EAAgB;QACxB,gBAAA,CAAA,IAAA,EAAQhB,aAAAA,EAAc;AACtB,QAAA,gBAAA,CAAA,IAAA,EAAQC,QAAAA,EAASqB,SAAAA,EAAAA,CAAAA;QAGb,IAAI,CAAC7B,QAAQ,GAAGA,QAAAA;AACpB,IAAA;AAuGJ;AAEA;;AAEC,IACM,MAAM8B,yBAAAA,CAAAA;AAKT;;;;QAKAC,iBAAAA,CAAkBC,QAAgB,EAAY;QAC1C,MAAMC,cAAAA,GAAiBC,IAAAA,CAAKf,OAAO,CAACa,QAAAA,CAAAA;AAEpC,QAAA,IAAI,CAAC,IAAI,CAACG,KAAK,CAACC,GAAG,CAACH,cAAAA,CAAAA,EAAiB;;AAEjC,YAAA,MAAMI,UAAAA,GAAa,IAAI,CAACC,mBAAmB,CAACL,cAAAA,CAAAA;AAC5C,YAAA,MAAMjC,QAAAA,GAAWkC,IAAAA,CAAKK,IAAI,CAACF,UAAAA,EAAY,eAAA,CAAA;YACvC,IAAI,CAAC7B,MAAM,CAACC,KAAK,CAAC,CAAC,mCAAmC,EAAEwB,cAAAA,CAAe,IAAI,EAAEjC,QAAAA,CAAAA,CAAU,CAAA;AACvF,YAAA,IAAI,CAACmC,KAAK,CAACK,GAAG,CAACP,cAAAA,EAAgB,IAAIjD,QAAAA,CAASgB,QAAAA,CAAAA,CAAAA;;AAG5C,YAAA,IAAI,CAAC,IAAI,CAACyC,iBAAiB,EAAE;AACzB,gBAAA,IAAI,CAACC,uBAAuB,EAAA;gBAC5B,IAAI,CAACD,iBAAiB,GAAG,IAAA;AAC7B,YAAA;AACJ,QAAA;AAEA,QAAA,OAAO,IAAI,CAACN,KAAK,CAACQ,GAAG,CAACV,cAAAA,CAAAA;AAC1B,IAAA;AAEA;;;;QAKQK,mBAAAA,CAAoBN,QAAgB,EAAU;AAClD,QAAA,MAAMY,OAAAA,GAAUV,IAAAA,CAAKK,IAAI,CAACP,QAAAA,EAAU,MAAA,CAAA;QAEpC,IAAI;YACA,MAAMa,IAAAA,GAAO/C,EAAAA,CAAGgD,QAAQ,CAACF,OAAAA,CAAAA;YAEzB,IAAIC,IAAAA,CAAKE,WAAW,EAAA,EAAI;;gBAEpB,OAAOH,OAAAA;YACX,CAAA,MAAO,IAAIC,IAAAA,CAAKG,MAAM,EAAA,EAAI;;AAEtB,gBAAA,MAAMC,iBAAiBnD,EAAAA,CAAGI,YAAY,CAAC0C,OAAAA,EAAS,SAASM,IAAI,EAAA;gBAC7D,MAAMC,KAAAA,GAAQF,cAAAA,CAAeE,KAAK,CAAC,kBAAA,CAAA;AAEnC,gBAAA,IAAIA,KAAAA,IAASA,KAAK,CAAC,CAAA,CAAE,EAAE;;AAEnB,oBAAA,MAAMd,aAAaH,IAAAA,CAAKf,OAAO,CAACa,QAAAA,EAAUmB,KAAK,CAAC,CAAA,CAAE,CAAA;oBAClD,IAAI,CAAC3C,MAAM,CAACC,KAAK,CAAC,CAAC,2BAA2B,EAAE4B,UAAAA,CAAAA,CAAY,CAAA;;AAG5D,oBAAA,IAAI,CAACvC,EAAAA,CAAGC,UAAU,CAACsC,UAAAA,CAAAA,EAAa;AAC5B,wBAAA,MAAM,IAAIb,KAAAA,CAAM,CAAC,wCAAwC,EAAEa,UAAAA,CAAAA,CAAY,CAAA;AAC3E,oBAAA;oBAEA,OAAOA,UAAAA;AACX,gBAAA;gBAEA,MAAM,IAAIb,MAAM,CAAC,4BAA4B,EAAEoB,OAAAA,CAAQ,EAAE,EAAEK,cAAAA,CAAAA,CAAgB,CAAA;AAC/E,YAAA;AACJ,QAAA,CAAA,CAAE,OAAOlC,KAAAA,EAAY;;YAEjB,IAAIA,KAAAA,CAAMC,IAAI,KAAK,QAAA,EAAU;AACzB,gBAAA,MAAM,IAAIQ,KAAAA,CAAM,CAAC,mCAAmC,EAAEQ,QAAAA,CAAAA,CAAU,CAAA;AACpE,YAAA;YACA,MAAM,IAAIR,KAAAA,CAAM,CAAC,oCAAoC,EAAEQ,SAAS,EAAE,EAAEjB,KAAAA,CAAMU,OAAO,CAAA,CAAE,CAAA;AACvF,QAAA;AAEA,QAAA,MAAM,IAAID,KAAAA,CAAM,CAAC,mCAAmC,EAAEQ,QAAAA,CAAAA,CAAU,CAAA;AACpE,IAAA;AAEA;;AAEC,QACD,uBAAQU,GAAgC;AACpC,QAAA,MAAMU,OAAAA,GAAU,IAAA;AACZ,YAAA,IAAI,CAACC,OAAO,EAAA;AAChB,QAAA,CAAA;;QAGA7D,OAAAA,CAAQ8D,EAAE,CAAC,MAAA,EAAQF,OAAAA,CAAAA;QACnB5D,OAAAA,CAAQ8D,EAAE,CAAC,QAAA,EAAU,IAAA;AACjBF,YAAAA,OAAAA,EAAAA;YACA5D,OAAAA,CAAQ+D,IAAI,CAAC,GAAA,CAAA,CAAA;AACjB,QAAA,CAAA,CAAA;QACA/D,OAAAA,CAAQ8D,EAAE,CAAC,SAAA,EAAW,IAAA;AAClBF,YAAAA,OAAAA,EAAAA;YACA5D,OAAAA,CAAQ+D,IAAI,CAAC,GAAA,CAAA,CAAA;AACjB,QAAA,CAAA,CAAA;QACA/D,OAAAA,CAAQ8D,EAAE,CAAC,mBAAA,EAAqB,CAACvC,KAAAA,GAAAA;AAC7B,YAAA,IAAI,CAACP,MAAM,CAACO,KAAK,CAAC,wCAAA,EAA0CA,KAAAA,CAAAA;AAC5DqC,YAAAA,OAAAA,EAAAA;AACA5D,YAAAA,OAAAA,CAAQ+D,IAAI,CAAC,CAAA,CAAA;AACjB,QAAA,CAAA,CAAA;AACJ,IAAA;AAEA;;;;;;AAMC,QACD,MAAMC,WAAAA,CACFxB,QAAgB,EAChByB,SAA2B,EAC3BC,aAAsB,EACZ;AACV,QAAA,MAAMzE,IAAAA,GAAO,IAAI,CAAC8C,iBAAiB,CAACC,QAAAA,CAAAA;QACpC,MAAM2B,SAAAA,GAAYjE,KAAKC,GAAG,EAAA;AAE1B,QAAA,IAAI,CAACa,MAAM,CAACmB,KAAK,CACb,CAAC,wBAAwB,EAAEK,QAAAA,CAAAA,EAAW0B,gBAAgB,CAAC,MAAM,EAAEA,aAAAA,CAAAA,CAAe,GAAG,EAAA,CAAA,CAAI,CAAA;AAGzF,QAAA,MAAMzE,KAAKA,IAAI,EAAA;QAEf,MAAM2E,QAAAA,GAAWlE,IAAAA,CAAKC,GAAG,EAAA,GAAKgE,SAAAA;AAC9B,QAAA,IAAIC,WAAW,GAAA,EAAK;YAChB,IAAI,CAACpD,MAAM,CAACC,KAAK,CACb,CAAC,uBAAuB,EAAEuB,QAAAA,CAAS,OAAO,EAAE4B,QAAAA,CAAS,EAAE,EAAEF,aAAAA,GAAgB,CAAC,MAAM,EAAEA,aAAAA,CAAAA,CAAe,GAAG,EAAA,CAAA,CAAI,CAAA;AAEhH,QAAA;QAEA,IAAI;AACA,YAAA,OAAO,MAAMD,SAAAA,EAAAA;QACjB,CAAA,QAAU;AACNxE,YAAAA,IAAAA,CAAKyC,MAAM,EAAA;AACf,QAAA;AACJ,IAAA;AAEA;;AAEC,QACD2B,OAAAA,GAAgB;AACZ,QAAA,IAAI,CAAC7C,MAAM,CAACC,KAAK,CAAC,CAAC,YAAY,EAAE,IAAI,CAAC0B,KAAK,CAAC0B,IAAI,CAAC,aAAa,CAAC,CAAA;AAC/D,QAAA,KAAK,MAAM5E,IAAAA,IAAQ,IAAI,CAACkD,KAAK,CAAC2B,MAAM,EAAA,CAAI;AACpC7E,YAAAA,IAAAA,CAAKyC,MAAM,EAAA;AACf,QAAA;QACA,IAAI,CAACS,KAAK,CAAC4B,KAAK,EAAA;AACpB,IAAA;;AA/IA,QAAA,gBAAA,CAAA,IAAA,EAAQ5B,SAA+B,IAAI6B,GAAAA,EAAAA,CAAAA;AAC3C,QAAA,gBAAA,CAAA,IAAA,EAAQxD,QAAAA,EAASqB,SAAAA,EAAAA,CAAAA;AACjB,QAAA,gBAAA,CAAA,IAAA,EAAQY,mBAAAA,EAAoB,KAAA,CAAA;;AA8IhC;;;;"}
1
+ {"version":3,"file":"fileLock.js","sources":["../../src/util/fileLock.ts"],"sourcesContent":["// eslint-disable-next-line no-restricted-imports\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\nimport { getLogger } from '../logging';\n\n/**\n * File-based lock for cross-process synchronization\n * Uses atomic file operations to coordinate across multiple Node processes\n */\nexport class FileLock {\n private lockPath: string;\n private lockAcquired = false;\n private maxRetries = 100; // Maximum number of lock attempts\n private retryDelay = 100; // Initial retry delay in ms\n private maxRetryDelay = 2000; // Maximum retry delay in ms\n private lockTimeout = 30000; // Consider lock stale after 30 seconds\n private logger = getLogger();\n\n constructor(lockPath: string) {\n this.lockPath = lockPath;\n }\n\n /**\n * Acquire the file lock with exponential backoff retry\n */\n async lock(): Promise<void> {\n let attempts = 0;\n let currentDelay = this.retryDelay;\n\n while (attempts < this.maxRetries) {\n try {\n // Try to create lock file atomically with 'wx' flag (fails if exists)\n const lockData = {\n pid: process.pid,\n timestamp: Date.now(),\n hostname: os.hostname()\n };\n\n // Check if lock file exists and is stale\n if (fs.existsSync(this.lockPath)) {\n const lockContent = fs.readFileSync(this.lockPath, 'utf-8');\n try {\n const existingLock = JSON.parse(lockContent);\n const lockAge = Date.now() - existingLock.timestamp;\n\n // If lock is stale, try to remove it\n if (lockAge > this.lockTimeout) {\n this.logger.debug(`Removing stale lock file (age: ${lockAge}ms, pid: ${existingLock.pid})`);\n try {\n fs.unlinkSync(this.lockPath);\n } catch {\n // Lock might have been removed by another process, continue\n }\n }\n } catch {\n // Invalid lock file, try to remove it\n try {\n fs.unlinkSync(this.lockPath);\n } catch {\n // Ignore errors\n }\n }\n }\n\n // Try to acquire lock\n fs.writeFileSync(this.lockPath, JSON.stringify(lockData, null, 2), { flag: 'wx' });\n this.lockAcquired = true;\n\n if (attempts > 0) {\n this.logger.debug(`Acquired file lock after ${attempts} attempts: ${this.lockPath}`);\n }\n\n return;\n } catch (error: any) {\n if (error.code === 'EEXIST') {\n // Lock file exists, retry with backoff\n attempts++;\n\n if (attempts === 1 || attempts % 10 === 0) {\n this.logger.verbose(`Waiting for file lock (attempt ${attempts}/${this.maxRetries}): ${this.lockPath}`);\n }\n\n await new Promise(resolve => setTimeout(resolve, currentDelay));\n\n // Exponential backoff\n currentDelay = Math.min(currentDelay * 1.5, this.maxRetryDelay);\n } else {\n // Unexpected error\n throw new Error(`Failed to acquire file lock ${this.lockPath}: ${error.message}`);\n }\n }\n }\n\n throw new Error(`Failed to acquire file lock after ${this.maxRetries} attempts: ${this.lockPath}`);\n }\n\n /**\n * Release the file lock\n */\n unlock(): void {\n if (!this.lockAcquired) {\n return;\n }\n\n try {\n if (fs.existsSync(this.lockPath)) {\n fs.unlinkSync(this.lockPath);\n }\n this.lockAcquired = false;\n this.logger.silly(`Released file lock: ${this.lockPath}`);\n } catch (error: any) {\n // Lock file might have been removed by another process or stale lock cleanup\n this.logger.debug(`Error releasing file lock ${this.lockPath}: ${error.message}`);\n this.lockAcquired = false;\n }\n }\n\n /**\n * Check if this instance currently holds the lock\n */\n isLocked(): boolean {\n return this.lockAcquired;\n }\n}\n\n/**\n * Manages file-based locks for git repositories (cross-process safe)\n */\nexport class RepositoryFileLockManager {\n private locks: Map<string, FileLock> = new Map();\n private logger = getLogger();\n private cleanupRegistered = false;\n\n /**\n * Get or create a file lock for a specific git repository\n * @param repoPath Path to the git repository root\n * @returns FileLock for this repository\n */\n getRepositoryLock(repoPath: string): FileLock {\n const normalizedPath = path.resolve(repoPath);\n\n if (!this.locks.has(normalizedPath)) {\n // Resolve the actual .git directory (handles both regular repos and submodules)\n const gitDirPath = this.resolveGitDirectory(normalizedPath);\n const lockPath = path.join(gitDirPath, 'kodrdriv.lock');\n this.logger.debug(`Creating file lock for repository: ${normalizedPath} at ${lockPath}`);\n this.locks.set(normalizedPath, new FileLock(lockPath));\n\n // Register cleanup handler on first lock creation\n if (!this.cleanupRegistered) {\n this.registerCleanupHandlers();\n this.cleanupRegistered = true;\n }\n }\n\n return this.locks.get(normalizedPath)!;\n }\n\n /**\n * Resolve the actual .git directory path, handling both regular repos and submodules\n * @param repoPath Path to the repository root\n * @returns Path to the actual .git directory\n */\n private resolveGitDirectory(repoPath: string): string {\n const gitPath = path.join(repoPath, '.git');\n\n try {\n const stat = fs.statSync(gitPath);\n\n if (stat.isDirectory()) {\n // Regular git repository\n return gitPath;\n } else if (stat.isFile()) {\n // Git submodule - .git is a file with format: gitdir: <path>\n const gitFileContent = fs.readFileSync(gitPath, 'utf-8').trim();\n const match = gitFileContent.match(/^gitdir:\\s*(.+)$/);\n\n if (match && match[1]) {\n // Resolve the gitdir path (it's relative to the repo path)\n const gitDirPath = path.resolve(repoPath, match[1]);\n this.logger.debug(`Resolved submodule gitdir: ${gitDirPath}`);\n\n // Ensure the git directory exists\n if (!fs.existsSync(gitDirPath)) {\n throw new Error(`Submodule git directory does not exist: ${gitDirPath}`);\n }\n\n return gitDirPath;\n }\n\n throw new Error(`Invalid .git file format in ${gitPath}: ${gitFileContent}`);\n }\n } catch (error: any) {\n // Check if error is from statSync (file doesn't exist)\n if (error.code === 'ENOENT') {\n throw new Error(`No .git directory or file found in ${repoPath}`);\n }\n throw new Error(`Failed to resolve git directory for ${repoPath}: ${error.message}`);\n }\n\n throw new Error(`No .git directory or file found in ${repoPath}`);\n }\n\n /**\n * Register cleanup handlers to release locks on process exit\n */\n private registerCleanupHandlers(): void {\n const cleanup = () => {\n this.destroy();\n };\n\n // Handle various exit scenarios\n process.on('exit', cleanup);\n process.on('SIGINT', () => {\n cleanup();\n process.exit(130); // Standard exit code for SIGINT\n });\n process.on('SIGTERM', () => {\n cleanup();\n process.exit(143); // Standard exit code for SIGTERM\n });\n process.on('uncaughtException', (error) => {\n this.logger.error('FILELOCK_UNCAUGHT_EXCEPTION: Uncaught exception detected, cleaning up locks | Error: ' + error + ' | Action: Release all locks');\n cleanup();\n process.exit(1);\n });\n }\n\n /**\n * Execute a git operation with repository-level file locking\n * @param repoPath Path to the git repository root\n * @param operation The async operation to execute under lock\n * @param operationName Optional name for logging\n * @returns Result of the operation\n */\n async withGitLock<T>(\n repoPath: string,\n operation: () => Promise<T>,\n operationName?: string\n ): Promise<T> {\n const lock = this.getRepositoryLock(repoPath);\n const startWait = Date.now();\n\n this.logger.silly(\n `Acquiring file lock for ${repoPath}${operationName ? ` for: ${operationName}` : ''}`\n );\n\n await lock.lock();\n\n const waitTime = Date.now() - startWait;\n if (waitTime > 100) {\n this.logger.debug(\n `Acquired file lock for ${repoPath} after ${waitTime}ms${operationName ? ` for: ${operationName}` : ''}`\n );\n }\n\n try {\n return await operation();\n } finally {\n lock.unlock();\n }\n }\n\n /**\n * Clean up all locks\n */\n destroy(): void {\n this.logger.debug(`Cleaning up ${this.locks.size} file lock(s)`);\n for (const lock of this.locks.values()) {\n lock.unlock();\n }\n this.locks.clear();\n }\n}\n"],"names":["FileLock","lock","attempts","currentDelay","retryDelay","maxRetries","lockData","pid","process","timestamp","Date","now","hostname","os","fs","existsSync","lockPath","lockContent","readFileSync","existingLock","JSON","parse","lockAge","lockTimeout","logger","debug","unlinkSync","writeFileSync","stringify","flag","lockAcquired","error","code","verbose","Promise","resolve","setTimeout","Math","min","maxRetryDelay","Error","message","unlock","silly","isLocked","getLogger","RepositoryFileLockManager","getRepositoryLock","repoPath","normalizedPath","path","locks","has","gitDirPath","resolveGitDirectory","join","set","cleanupRegistered","registerCleanupHandlers","get","gitPath","stat","statSync","isDirectory","isFile","gitFileContent","trim","match","cleanup","destroy","on","exit","withGitLock","operation","operationName","startWait","waitTime","size","values","clear","Map"],"mappings":"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"}