@eldrforge/kodrdriv 1.2.129 → 1.2.131

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 (48) hide show
  1. package/DUPLICATION-CLEANUP.md +104 -0
  2. package/dist/application.js +1 -2
  3. package/dist/application.js.map +1 -1
  4. package/dist/commands/audio-commit.js +1 -2
  5. package/dist/commands/audio-commit.js.map +1 -1
  6. package/dist/commands/clean.js +1 -2
  7. package/dist/commands/clean.js.map +1 -1
  8. package/dist/commands/commit.js +1 -2
  9. package/dist/commands/commit.js.map +1 -1
  10. package/dist/commands/review.js +1 -2
  11. package/dist/commands/review.js.map +1 -1
  12. package/dist/commands/tree.js +5 -5
  13. package/dist/commands/tree.js.map +1 -1
  14. package/dist/commands/versions.js.map +1 -1
  15. package/dist/constants.js +1 -1
  16. package/dist/content/diff.js +1 -1
  17. package/dist/content/diff.js.map +1 -1
  18. package/dist/content/log.js +1 -1
  19. package/dist/content/log.js.map +1 -1
  20. package/package.json +9 -7
  21. package/dist/error/CancellationError.js +0 -9
  22. package/dist/error/CancellationError.js.map +0 -1
  23. package/dist/error/CommandErrors.js +0 -63
  24. package/dist/error/CommandErrors.js.map +0 -1
  25. package/dist/error/ExitError.js +0 -9
  26. package/dist/error/ExitError.js.map +0 -1
  27. package/dist/execution/CommandValidator.js +0 -192
  28. package/dist/execution/CommandValidator.js.map +0 -1
  29. package/dist/execution/DependencyChecker.js +0 -102
  30. package/dist/execution/DependencyChecker.js.map +0 -1
  31. package/dist/execution/DynamicTaskPool.js +0 -661
  32. package/dist/execution/DynamicTaskPool.js.map +0 -1
  33. package/dist/execution/RecoveryManager.js +0 -584
  34. package/dist/execution/RecoveryManager.js.map +0 -1
  35. package/dist/execution/ResourceMonitor.js +0 -150
  36. package/dist/execution/ResourceMonitor.js.map +0 -1
  37. package/dist/execution/Scheduler.js +0 -98
  38. package/dist/execution/Scheduler.js.map +0 -1
  39. package/dist/execution/TreeExecutionAdapter.js +0 -225
  40. package/dist/execution/TreeExecutionAdapter.js.map +0 -1
  41. package/dist/ui/ProgressFormatter.js +0 -250
  42. package/dist/ui/ProgressFormatter.js.map +0 -1
  43. package/dist/util/checkpointManager.js +0 -166
  44. package/dist/util/checkpointManager.js.map +0 -1
  45. package/dist/util/dependencyGraph.js +0 -222
  46. package/dist/util/dependencyGraph.js.map +0 -1
  47. package/dist/util/mutex.js +0 -96
  48. package/dist/util/mutex.js.map +0 -1
@@ -1,166 +0,0 @@
1
- import path__default from 'path';
2
- import fs from 'fs/promises';
3
- import { getLogger } from '../logging.js';
4
- import { createStorage } from '@eldrforge/shared';
5
-
6
- function _define_property(obj, key, value) {
7
- if (key in obj) {
8
- Object.defineProperty(obj, key, {
9
- value: value,
10
- enumerable: true,
11
- configurable: true,
12
- writable: true
13
- });
14
- } else {
15
- obj[key] = value;
16
- }
17
- return obj;
18
- }
19
- const CHECKPOINT_VERSION = '1.0.0';
20
- class CheckpointManager {
21
- async save(checkpoint) {
22
- const lock = await this.acquireLock();
23
- try {
24
- // Set version and timestamp
25
- checkpoint.version = CHECKPOINT_VERSION;
26
- checkpoint.lastUpdated = new Date().toISOString();
27
- // Validate before saving
28
- this.validateCheckpoint(checkpoint);
29
- // Write to temp file
30
- const serialized = JSON.stringify(checkpoint, null, 2);
31
- await fs.writeFile(this.tempPath, serialized, 'utf-8');
32
- // Atomic rename
33
- await fs.rename(this.tempPath, this.checkpointPath);
34
- this.logger.debug(`Checkpoint saved: ${this.checkpointPath}`);
35
- } finally{
36
- await lock.release();
37
- }
38
- }
39
- async load() {
40
- if (!await this.storage.exists(this.checkpointPath)) {
41
- return null;
42
- }
43
- const lock = await this.acquireLock();
44
- try {
45
- const content = await fs.readFile(this.checkpointPath, 'utf-8');
46
- const checkpoint = JSON.parse(content);
47
- // Validate
48
- this.validateCheckpoint(checkpoint);
49
- // Check version
50
- if (!this.isCompatibleVersion(checkpoint.version)) {
51
- throw new Error(`Incompatible checkpoint version: ${checkpoint.version}`);
52
- }
53
- return checkpoint;
54
- } catch (error) {
55
- this.logger.error(`CHECKPOINT_LOAD_FAILED: Failed to load checkpoint file | Error: ${error.message} | Impact: Cannot resume execution`);
56
- // Try backup
57
- const backup = await this.loadBackup();
58
- if (backup) {
59
- this.logger.info('CHECKPOINT_RECOVERED_BACKUP: Recovered from backup checkpoint | Source: backup | Status: loaded');
60
- return backup;
61
- }
62
- return null;
63
- } finally{
64
- await lock.release();
65
- }
66
- }
67
- async backup() {
68
- if (!await this.storage.exists(this.checkpointPath)) {
69
- return;
70
- }
71
- const backupPath = `${this.checkpointPath}.backup`;
72
- await fs.copyFile(this.checkpointPath, backupPath);
73
- }
74
- async cleanup() {
75
- const files = [
76
- this.checkpointPath,
77
- this.lockPath,
78
- this.tempPath,
79
- `${this.checkpointPath}.backup`
80
- ];
81
- await Promise.all(files.map((file)=>fs.unlink(file).catch(()=>{})));
82
- }
83
- async acquireLock() {
84
- const maxWaitMs = 30000;
85
- const startTime = Date.now();
86
- while(true){
87
- try {
88
- const fileHandle = await fs.open(this.lockPath, 'wx');
89
- try {
90
- const pid = process.pid;
91
- const timestamp = new Date().toISOString();
92
- await fileHandle.writeFile(`${pid}\n${timestamp}`);
93
- } finally{
94
- await fileHandle.close();
95
- }
96
- return {
97
- release: async ()=>{
98
- await fs.unlink(this.lockPath).catch(()=>{});
99
- }
100
- };
101
- } catch (error) {
102
- if (error.code !== 'EEXIST') {
103
- throw error;
104
- }
105
- const elapsed = Date.now() - startTime;
106
- if (elapsed > maxWaitMs) {
107
- this.logger.warn('CHECKPOINT_LOCK_STALE: Breaking stale checkpoint lock | Reason: Lock expired | Action: Force break lock');
108
- await fs.unlink(this.lockPath).catch(()=>{});
109
- continue;
110
- }
111
- await new Promise((resolve)=>setTimeout(resolve, 100));
112
- }
113
- }
114
- }
115
- validateCheckpoint(checkpoint) {
116
- if (!checkpoint.executionId) {
117
- throw new Error('Invalid checkpoint: missing executionId');
118
- }
119
- if (!checkpoint.state) {
120
- throw new Error('Invalid checkpoint: missing state');
121
- }
122
- // Validate state consistency
123
- const allPackages = new Set([
124
- ...checkpoint.state.pending,
125
- ...checkpoint.state.ready,
126
- ...checkpoint.state.running.map((r)=>r.name),
127
- ...checkpoint.state.completed,
128
- ...checkpoint.state.failed.map((f)=>f.name),
129
- ...checkpoint.state.skipped
130
- ]);
131
- if (allPackages.size !== checkpoint.buildOrder.length) {
132
- this.logger.warn('CHECKPOINT_INCONSISTENCY: Checkpoint state inconsistency detected | Issue: State validation failed | Impact: May need manual recovery');
133
- }
134
- }
135
- isCompatibleVersion(version) {
136
- // Simple major version check
137
- const [major] = version.split('.');
138
- const [expectedMajor] = CHECKPOINT_VERSION.split('.');
139
- return major === expectedMajor;
140
- }
141
- async loadBackup() {
142
- const backupPath = `${this.checkpointPath}.backup`;
143
- if (!await this.storage.exists(backupPath)) {
144
- return null;
145
- }
146
- try {
147
- const content = await fs.readFile(backupPath, 'utf-8');
148
- return JSON.parse(content);
149
- } catch {
150
- return null;
151
- }
152
- }
153
- constructor(outputDirectory = process.cwd()){
154
- _define_property(this, "checkpointPath", void 0);
155
- _define_property(this, "lockPath", void 0);
156
- _define_property(this, "tempPath", void 0);
157
- _define_property(this, "logger", getLogger());
158
- _define_property(this, "storage", createStorage());
159
- this.checkpointPath = path__default.join(outputDirectory, '.kodrdriv-parallel-context.json');
160
- this.lockPath = `${this.checkpointPath}.lock`;
161
- this.tempPath = `${this.checkpointPath}.tmp`;
162
- }
163
- }
164
-
165
- export { CheckpointManager };
166
- //# sourceMappingURL=checkpointManager.js.map
@@ -1 +0,0 @@
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 { createStorage } from '@eldrforge/shared';\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();\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","path","join"],"mappings":"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"}
@@ -1,222 +0,0 @@
1
- import path__default from 'path';
2
- import fs from 'fs/promises';
3
- import { safeJsonParse, validatePackageJson } from '@eldrforge/git-tools';
4
- import { getLogger } from '../logging.js';
5
- import { createStorage } from '@eldrforge/shared';
6
-
7
- /**
8
- * Check if a file path matches a glob pattern
9
- */ const matchesPattern = (filePath, pattern)=>{
10
- // Convert simple glob patterns to regex
11
- const regexPattern = pattern.replace(/\\/g, '\\\\') // Escape backslashes
12
- .replace(/\*\*/g, '.*') // ** matches any path segments
13
- .replace(/\*/g, '[^/]*') // * matches any characters except path separator
14
- .replace(/\?/g, '.') // ? matches any single character
15
- .replace(/\./g, '\\.'); // Escape literal dots
16
- const regex = new RegExp(`^${regexPattern}$`);
17
- return regex.test(filePath) || regex.test(path__default.basename(filePath));
18
- };
19
- /**
20
- * Check if a package should be excluded based on patterns
21
- */ function shouldExclude(packageJsonPath, excludedPatterns) {
22
- if (!excludedPatterns || excludedPatterns.length === 0) {
23
- return false;
24
- }
25
- // Check both the full path and relative path patterns
26
- const relativePath = path__default.relative(process.cwd(), packageJsonPath);
27
- return excludedPatterns.some((pattern)=>matchesPattern(packageJsonPath, pattern) || matchesPattern(relativePath, pattern) || matchesPattern(path__default.dirname(packageJsonPath), pattern) || matchesPattern(path__default.dirname(relativePath), pattern));
28
- }
29
- /**
30
- * Scan directory for package.json files
31
- */ async function scanForPackageJsonFiles(directory, excludedPatterns = []) {
32
- const logger = getLogger();
33
- const packageJsonPaths = [];
34
- try {
35
- // First check if there's a package.json in the specified directory itself
36
- const directPackageJsonPath = path__default.join(directory, 'package.json');
37
- try {
38
- await fs.access(directPackageJsonPath);
39
- // Check if this package should be excluded
40
- if (!shouldExclude(directPackageJsonPath, excludedPatterns)) {
41
- packageJsonPaths.push(directPackageJsonPath);
42
- logger.verbose(`Found package.json at: ${directPackageJsonPath}`);
43
- } else {
44
- logger.verbose(`Excluding package.json at: ${directPackageJsonPath} (matches exclusion pattern)`);
45
- }
46
- } catch {
47
- // No package.json in the root of this directory, that's fine
48
- }
49
- // Then scan subdirectories for package.json files
50
- const entries = await fs.readdir(directory, {
51
- withFileTypes: true
52
- });
53
- for (const entry of entries){
54
- if (entry.isDirectory()) {
55
- const subDirPath = path__default.join(directory, entry.name);
56
- const packageJsonPath = path__default.join(subDirPath, 'package.json');
57
- try {
58
- await fs.access(packageJsonPath);
59
- // Check if this package should be excluded
60
- if (shouldExclude(packageJsonPath, excludedPatterns)) {
61
- logger.verbose(`Excluding package.json at: ${packageJsonPath} (matches exclusion pattern)`);
62
- continue;
63
- }
64
- packageJsonPaths.push(packageJsonPath);
65
- logger.verbose(`Found package.json at: ${packageJsonPath}`);
66
- } catch {
67
- // No package.json in this directory, continue
68
- }
69
- }
70
- }
71
- } catch (error) {
72
- logger.error(`DEPENDENCY_GRAPH_SCAN_FAILED: Failed to scan directory | Directory: ${directory} | Error: ${error}`);
73
- throw error;
74
- }
75
- return packageJsonPaths;
76
- }
77
- /**
78
- * Parse a single package.json file
79
- */ async function parsePackageJson(packageJsonPath) {
80
- const logger = getLogger();
81
- const storage = createStorage();
82
- try {
83
- const content = await storage.readFile(packageJsonPath, 'utf-8');
84
- const parsed = safeJsonParse(content, packageJsonPath);
85
- const packageJson = validatePackageJson(parsed, packageJsonPath);
86
- if (!packageJson.name) {
87
- throw new Error(`Package at ${packageJsonPath} has no name field`);
88
- }
89
- const dependencies = new Set();
90
- const devDependencies = new Set();
91
- // Collect all types of dependencies
92
- const depTypes = [
93
- 'dependencies',
94
- 'devDependencies',
95
- 'peerDependencies',
96
- 'optionalDependencies'
97
- ];
98
- for (const depType of depTypes){
99
- if (packageJson[depType]) {
100
- Object.keys(packageJson[depType]).forEach((dep)=>{
101
- dependencies.add(dep);
102
- if (depType === 'devDependencies') {
103
- devDependencies.add(dep);
104
- }
105
- });
106
- }
107
- }
108
- return {
109
- name: packageJson.name,
110
- version: packageJson.version || '0.0.0',
111
- path: path__default.dirname(packageJsonPath),
112
- dependencies,
113
- devDependencies,
114
- localDependencies: new Set() // Will be populated later
115
- };
116
- } catch (error) {
117
- logger.error(`DEPENDENCY_GRAPH_PARSE_FAILED: Failed to parse package.json | Path: ${packageJsonPath} | Error: ${error}`);
118
- throw error;
119
- }
120
- }
121
- /**
122
- * Build dependency graph from package.json paths
123
- */ async function buildDependencyGraph(packageJsonPaths) {
124
- const logger = getLogger();
125
- const packages = new Map();
126
- const edges = new Map();
127
- // First pass: parse all package.json files
128
- for (const packageJsonPath of packageJsonPaths){
129
- const packageInfo = await parsePackageJson(packageJsonPath);
130
- packages.set(packageInfo.name, packageInfo);
131
- logger.verbose(`Parsed package: ${packageInfo.name} at ${packageInfo.path}`);
132
- }
133
- // Second pass: identify local dependencies and build edges
134
- for (const [packageName, packageInfo] of packages){
135
- const localDeps = new Set();
136
- const edgesSet = new Set();
137
- for (const dep of packageInfo.dependencies){
138
- if (packages.has(dep)) {
139
- localDeps.add(dep);
140
- edgesSet.add(dep);
141
- logger.verbose(`${packageName} depends on local package: ${dep}`);
142
- }
143
- }
144
- packageInfo.localDependencies = localDeps;
145
- edges.set(packageName, edgesSet);
146
- }
147
- // Build reverse edges (dependents)
148
- const reverseEdges = buildReverseGraph(edges);
149
- return {
150
- packages,
151
- edges,
152
- reverseEdges
153
- };
154
- }
155
- /**
156
- * Build reverse dependency graph (package -> dependents)
157
- */ function buildReverseGraph(edges) {
158
- const reverse = new Map();
159
- for (const [pkg, deps] of edges){
160
- for (const dep of deps){
161
- if (!reverse.has(dep)) {
162
- reverse.set(dep, new Set());
163
- }
164
- reverse.get(dep).add(pkg);
165
- }
166
- }
167
- return reverse;
168
- }
169
- /**
170
- * Perform topological sort on dependency graph
171
- */ function topologicalSort(graph) {
172
- const logger = getLogger();
173
- const { packages, edges } = graph;
174
- const visited = new Set();
175
- const visiting = new Set();
176
- const result = [];
177
- const visit = (packageName)=>{
178
- if (visited.has(packageName)) {
179
- return;
180
- }
181
- if (visiting.has(packageName)) {
182
- throw new Error(`Circular dependency detected involving package: ${packageName}`);
183
- }
184
- visiting.add(packageName);
185
- // Visit all dependencies first
186
- const deps = edges.get(packageName) || new Set();
187
- for (const dep of deps){
188
- visit(dep);
189
- }
190
- visiting.delete(packageName);
191
- visited.add(packageName);
192
- result.push(packageName);
193
- };
194
- // Visit all packages
195
- for (const packageName of packages.keys()){
196
- if (!visited.has(packageName)) {
197
- visit(packageName);
198
- }
199
- }
200
- logger.verbose(`Topological sort completed. Build order determined for ${result.length} packages.`);
201
- return result;
202
- }
203
- /**
204
- * Find all dependents of a package (packages that depend on it)
205
- */ function findAllDependents(packageName, graph) {
206
- const dependents = new Set();
207
- const visited = new Set();
208
- const traverse = (pkg)=>{
209
- if (visited.has(pkg)) return;
210
- visited.add(pkg);
211
- const directDependents = graph.reverseEdges.get(pkg) || new Set();
212
- for (const dependent of directDependents){
213
- dependents.add(dependent);
214
- traverse(dependent);
215
- }
216
- };
217
- traverse(packageName);
218
- return dependents;
219
- }
220
-
221
- export { buildDependencyGraph, buildReverseGraph, findAllDependents, parsePackageJson, scanForPackageJsonFiles, shouldExclude, topologicalSort };
222
- //# sourceMappingURL=dependencyGraph.js.map
@@ -1 +0,0 @@
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 { createStorage } from '@eldrforge/shared';\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();\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","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,96 +0,0 @@
1
- /**
2
- * Simple mutex implementation for serializing async operations
3
- * Prevents race conditions when multiple async operations need exclusive access
4
- */ function _define_property(obj, key, value) {
5
- if (key in obj) {
6
- Object.defineProperty(obj, key, {
7
- value: value,
8
- enumerable: true,
9
- configurable: true,
10
- writable: true
11
- });
12
- } else {
13
- obj[key] = value;
14
- }
15
- return obj;
16
- }
17
- class SimpleMutex {
18
- /**
19
- * Acquire the mutex lock
20
- * If already locked, waits in queue until released
21
- */ async lock() {
22
- return new Promise((resolve, reject)=>{
23
- if (this.destroyed) {
24
- reject(new Error('Mutex has been destroyed'));
25
- return;
26
- }
27
- if (!this.locked) {
28
- this.locked = true;
29
- resolve();
30
- } else {
31
- this.queue.push(resolve);
32
- }
33
- });
34
- }
35
- /**
36
- * Release the mutex lock
37
- * Allows next waiting operation in queue to proceed
38
- */ unlock() {
39
- if (this.destroyed) {
40
- return;
41
- }
42
- this.locked = false;
43
- const next = this.queue.shift();
44
- if (next) {
45
- this.locked = true;
46
- try {
47
- next();
48
- } catch {
49
- // If resolver throws, unlock and continue with next in queue
50
- this.locked = false;
51
- const nextInQueue = this.queue.shift();
52
- if (nextInQueue) {
53
- this.locked = true;
54
- nextInQueue();
55
- }
56
- }
57
- }
58
- }
59
- /**
60
- * Destroy the mutex and reject all waiting operations
61
- * Prevents memory leaks when mutex is no longer needed
62
- */ destroy() {
63
- this.destroyed = true;
64
- this.locked = false;
65
- // Reject all queued promises to prevent memory leaks
66
- while(this.queue.length > 0){
67
- const resolve = this.queue.shift();
68
- if (resolve) {
69
- try {
70
- // Resolve with error state
71
- resolve();
72
- } catch {
73
- // Ignore errors during cleanup
74
- }
75
- }
76
- }
77
- }
78
- /**
79
- * Check if mutex is currently locked
80
- */ isLocked() {
81
- return this.locked;
82
- }
83
- /**
84
- * Get number of operations waiting in queue
85
- */ getQueueLength() {
86
- return this.queue.length;
87
- }
88
- constructor(){
89
- _define_property(this, "locked", false);
90
- _define_property(this, "queue", []);
91
- _define_property(this, "destroyed", false);
92
- }
93
- }
94
-
95
- export { SimpleMutex };
96
- //# sourceMappingURL=mutex.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mutex.js","sources":["../../src/util/mutex.ts"],"sourcesContent":["/**\n * Simple mutex implementation for serializing async operations\n * Prevents race conditions when multiple async operations need exclusive access\n */\nexport class SimpleMutex {\n private locked = false;\n private queue: Array<() => void> = [];\n private destroyed = false;\n\n /**\n * Acquire the mutex lock\n * If already locked, waits in queue until released\n */\n async lock(): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n if (this.destroyed) {\n reject(new Error('Mutex has been destroyed'));\n return;\n }\n\n if (!this.locked) {\n this.locked = true;\n resolve();\n } else {\n this.queue.push(resolve);\n }\n });\n }\n\n /**\n * Release the mutex lock\n * Allows next waiting operation in queue to proceed\n */\n unlock(): void {\n if (this.destroyed) {\n return;\n }\n\n this.locked = false;\n const next = this.queue.shift();\n if (next) {\n this.locked = true;\n try {\n next();\n } catch {\n // If resolver throws, unlock and continue with next in queue\n this.locked = false;\n const nextInQueue = this.queue.shift();\n if (nextInQueue) {\n this.locked = true;\n nextInQueue();\n }\n }\n }\n }\n\n /**\n * Destroy the mutex and reject all waiting operations\n * Prevents memory leaks when mutex is no longer needed\n */\n destroy(): void {\n this.destroyed = true;\n this.locked = false;\n\n // Reject all queued promises to prevent memory leaks\n while (this.queue.length > 0) {\n const resolve = this.queue.shift();\n if (resolve) {\n try {\n // Resolve with error state\n resolve();\n } catch {\n // Ignore errors during cleanup\n }\n }\n }\n }\n\n /**\n * Check if mutex is currently locked\n */\n isLocked(): boolean {\n return this.locked;\n }\n\n /**\n * Get number of operations waiting in queue\n */\n getQueueLength(): number {\n return this.queue.length;\n }\n}\n"],"names":["SimpleMutex","lock","Promise","resolve","reject","destroyed","Error","locked","queue","push","unlock","next","shift","nextInQueue","destroy","length","isLocked","getQueueLength"],"mappings":"AAAA;;;AAGC,IAAA,SAAA,gBAAA,CAAA,GAAA,EAAA,GAAA,EAAA,KAAA,EAAA;;;;;;;;;;;;;AACM,MAAMA,WAAAA,CAAAA;AAKT;;;AAGC,QACD,MAAMC,IAAAA,GAAsB;QACxB,OAAO,IAAIC,OAAAA,CAAc,CAACC,OAAAA,EAASC,MAAAA,GAAAA;YAC/B,IAAI,IAAI,CAACC,SAAS,EAAE;AAChBD,gBAAAA,MAAAA,CAAO,IAAIE,KAAAA,CAAM,0BAAA,CAAA,CAAA;AACjB,gBAAA;AACJ,YAAA;AAEA,YAAA,IAAI,CAAC,IAAI,CAACC,MAAM,EAAE;gBACd,IAAI,CAACA,MAAM,GAAG,IAAA;AACdJ,gBAAAA,OAAAA,EAAAA;YACJ,CAAA,MAAO;AACH,gBAAA,IAAI,CAACK,KAAK,CAACC,IAAI,CAACN,OAAAA,CAAAA;AACpB,YAAA;AACJ,QAAA,CAAA,CAAA;AACJ,IAAA;AAEA;;;AAGC,QACDO,MAAAA,GAAe;QACX,IAAI,IAAI,CAACL,SAAS,EAAE;AAChB,YAAA;AACJ,QAAA;QAEA,IAAI,CAACE,MAAM,GAAG,KAAA;AACd,QAAA,MAAMI,IAAAA,GAAO,IAAI,CAACH,KAAK,CAACI,KAAK,EAAA;AAC7B,QAAA,IAAID,IAAAA,EAAM;YACN,IAAI,CAACJ,MAAM,GAAG,IAAA;YACd,IAAI;AACAI,gBAAAA,IAAAA,EAAAA;AACJ,YAAA,CAAA,CAAE,OAAM;;gBAEJ,IAAI,CAACJ,MAAM,GAAG,KAAA;AACd,gBAAA,MAAMM,WAAAA,GAAc,IAAI,CAACL,KAAK,CAACI,KAAK,EAAA;AACpC,gBAAA,IAAIC,WAAAA,EAAa;oBACb,IAAI,CAACN,MAAM,GAAG,IAAA;AACdM,oBAAAA,WAAAA,EAAAA;AACJ,gBAAA;AACJ,YAAA;AACJ,QAAA;AACJ,IAAA;AAEA;;;AAGC,QACDC,OAAAA,GAAgB;QACZ,IAAI,CAACT,SAAS,GAAG,IAAA;QACjB,IAAI,CAACE,MAAM,GAAG,KAAA;;AAGd,QAAA,MAAO,IAAI,CAACC,KAAK,CAACO,MAAM,GAAG,CAAA,CAAG;AAC1B,YAAA,MAAMZ,OAAAA,GAAU,IAAI,CAACK,KAAK,CAACI,KAAK,EAAA;AAChC,YAAA,IAAIT,OAAAA,EAAS;gBACT,IAAI;;AAEAA,oBAAAA,OAAAA,EAAAA;AACJ,gBAAA,CAAA,CAAE,OAAM;;AAER,gBAAA;AACJ,YAAA;AACJ,QAAA;AACJ,IAAA;AAEA;;AAEC,QACDa,QAAAA,GAAoB;QAChB,OAAO,IAAI,CAACT,MAAM;AACtB,IAAA;AAEA;;AAEC,QACDU,cAAAA,GAAyB;AACrB,QAAA,OAAO,IAAI,CAACT,KAAK,CAACO,MAAM;AAC5B,IAAA;;AArFA,QAAA,gBAAA,CAAA,IAAA,EAAQR,QAAAA,EAAS,KAAA,CAAA;AACjB,QAAA,gBAAA,CAAA,IAAA,EAAQC,SAA2B,EAAE,CAAA;AACrC,QAAA,gBAAA,CAAA,IAAA,EAAQH,WAAAA,EAAY,KAAA,CAAA;;AAoFxB;;;;"}