@grunnverk/tree-execution 1.0.0

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 (80) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +1576 -0
  3. package/dist/TreeExecutor.d.ts +113 -0
  4. package/dist/TreeExecutor.d.ts.map +1 -0
  5. package/dist/TreeExecutor.js +113 -0
  6. package/dist/TreeExecutor.js.map +1 -0
  7. package/dist/checkpoint/CheckpointManager.d.ts +18 -0
  8. package/dist/checkpoint/CheckpointManager.d.ts.map +1 -0
  9. package/dist/checkpoint/CheckpointManager.js +156 -0
  10. package/dist/checkpoint/CheckpointManager.js.map +1 -0
  11. package/dist/checkpoint/index.d.ts +5 -0
  12. package/dist/checkpoint/index.d.ts.map +1 -0
  13. package/dist/checkpoint/index.js +5 -0
  14. package/dist/checkpoint/index.js.map +1 -0
  15. package/dist/execution/CommandValidator.d.ts +25 -0
  16. package/dist/execution/CommandValidator.d.ts.map +1 -0
  17. package/dist/execution/CommandValidator.js +129 -0
  18. package/dist/execution/CommandValidator.js.map +1 -0
  19. package/dist/execution/DependencyChecker.d.ts +47 -0
  20. package/dist/execution/DependencyChecker.d.ts.map +1 -0
  21. package/dist/execution/DependencyChecker.js +95 -0
  22. package/dist/execution/DependencyChecker.js.map +1 -0
  23. package/dist/execution/DynamicTaskPool.d.ts +118 -0
  24. package/dist/execution/DynamicTaskPool.d.ts.map +1 -0
  25. package/dist/execution/DynamicTaskPool.js +658 -0
  26. package/dist/execution/DynamicTaskPool.js.map +1 -0
  27. package/dist/execution/RecoveryManager.d.ts +89 -0
  28. package/dist/execution/RecoveryManager.d.ts.map +1 -0
  29. package/dist/execution/RecoveryManager.js +592 -0
  30. package/dist/execution/RecoveryManager.js.map +1 -0
  31. package/dist/execution/ResourceMonitor.d.ts +73 -0
  32. package/dist/execution/ResourceMonitor.d.ts.map +1 -0
  33. package/dist/execution/ResourceMonitor.js +148 -0
  34. package/dist/execution/ResourceMonitor.js.map +1 -0
  35. package/dist/execution/Scheduler.d.ts +36 -0
  36. package/dist/execution/Scheduler.d.ts.map +1 -0
  37. package/dist/execution/Scheduler.js +83 -0
  38. package/dist/execution/Scheduler.js.map +1 -0
  39. package/dist/execution/TreeExecutionAdapter.d.ts +45 -0
  40. package/dist/execution/TreeExecutionAdapter.d.ts.map +1 -0
  41. package/dist/execution/TreeExecutionAdapter.js +260 -0
  42. package/dist/execution/TreeExecutionAdapter.js.map +1 -0
  43. package/dist/index.d.ts +29 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +25 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/tree.d.ts +13 -0
  48. package/dist/tree.d.ts.map +1 -0
  49. package/dist/tree.js +2510 -0
  50. package/dist/tree.js.map +1 -0
  51. package/dist/types/config.d.ts +174 -0
  52. package/dist/types/config.d.ts.map +1 -0
  53. package/dist/types/config.js +2 -0
  54. package/dist/types/config.js.map +1 -0
  55. package/dist/types/index.d.ts +6 -0
  56. package/dist/types/index.d.ts.map +1 -0
  57. package/dist/types/index.js +6 -0
  58. package/dist/types/index.js.map +1 -0
  59. package/dist/types/parallelExecution.d.ts +108 -0
  60. package/dist/types/parallelExecution.d.ts.map +1 -0
  61. package/dist/types/parallelExecution.js +2 -0
  62. package/dist/types/parallelExecution.js.map +1 -0
  63. package/dist/util/commandStubs.d.ts +22 -0
  64. package/dist/util/commandStubs.d.ts.map +1 -0
  65. package/dist/util/commandStubs.js +49 -0
  66. package/dist/util/commandStubs.js.map +1 -0
  67. package/dist/util/logger.d.ts +14 -0
  68. package/dist/util/logger.d.ts.map +1 -0
  69. package/dist/util/logger.js +30 -0
  70. package/dist/util/logger.js.map +1 -0
  71. package/dist/util/mutex.d.ts +38 -0
  72. package/dist/util/mutex.d.ts.map +1 -0
  73. package/dist/util/mutex.js +101 -0
  74. package/dist/util/mutex.js.map +1 -0
  75. package/dist/util/treeUtils.d.ts +46 -0
  76. package/dist/util/treeUtils.d.ts.map +1 -0
  77. package/dist/util/treeUtils.js +74 -0
  78. package/dist/util/treeUtils.js.map +1 -0
  79. package/guide/index.md +84 -0
  80. package/package.json +64 -0
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Simple logger interface for tree-execution
3
+ */
4
+ export interface Logger {
5
+ info(message: string, ...args: any[]): void;
6
+ error(message: string, ...args: any[]): void;
7
+ warn(message: string, ...args: any[]): void;
8
+ verbose(message: string, ...args: any[]): void;
9
+ debug(message: string, ...args: any[]): void;
10
+ silly(message: string, ...args: any[]): void;
11
+ }
12
+ export declare function setLogger(newLogger: Logger): void;
13
+ export declare function getLogger(): Logger;
14
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/util/logger.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,MAAM;IACnB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAC5C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAC7C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAC5C,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAC/C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAC7C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;CAChD;AAwBD,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAEjD;AAED,wBAAgB,SAAS,IAAI,MAAM,CAElC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Check if we're running in MCP server mode.
3
+ * When true, console output must be suppressed as it interferes with the MCP protocol.
4
+ */
5
+ function isMcpServerMode() {
6
+ return process.env.KODRDRIV_MCP_SERVER === 'true';
7
+ }
8
+ /**
9
+ * Default logger that respects MCP server mode.
10
+ * In MCP mode, all output is suppressed (callers should configure a proper logger via setLogger).
11
+ * Outside MCP mode, logs go to console as usual.
12
+ */
13
+ let logger = {
14
+ info: (...args) => { if (!isMcpServerMode())
15
+ console.log(...args); },
16
+ error: (...args) => { if (!isMcpServerMode())
17
+ console.error(...args); },
18
+ warn: (...args) => { if (!isMcpServerMode())
19
+ console.warn(...args); },
20
+ verbose: () => { },
21
+ debug: () => { },
22
+ silly: () => { } // Most verbose level, disabled by default
23
+ };
24
+ export function setLogger(newLogger) {
25
+ logger = newLogger;
26
+ }
27
+ export function getLogger() {
28
+ return logger;
29
+ }
30
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/util/logger.ts"],"names":[],"mappings":"AAYA;;;GAGG;AACH,SAAS,eAAe;IACpB,OAAO,OAAO,CAAC,GAAG,CAAC,mBAAmB,KAAK,MAAM,CAAC;AACtD,CAAC;AAED;;;;GAIG;AACH,IAAI,MAAM,GAAW;IACjB,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,EAAE,GAAG,IAAI,CAAC,eAAe,EAAE;QAAE,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACpE,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,EAAE,GAAG,IAAI,CAAC,eAAe,EAAE;QAAE,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACvE,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,EAAE,GAAG,IAAI,CAAC,eAAe,EAAE;QAAE,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACrE,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC;IACjB,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC;IACf,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC,CAAC,0CAA0C;CAC7D,CAAC;AAEF,MAAM,UAAU,SAAS,CAAC,SAAiB;IACvC,MAAM,GAAG,SAAS,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,SAAS;IACrB,OAAO,MAAM,CAAC;AAClB,CAAC"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Simple mutex implementation for serializing async operations
3
+ * Prevents race conditions when multiple async operations need exclusive access
4
+ */
5
+ export declare class SimpleMutex {
6
+ private locked;
7
+ private queue;
8
+ private destroyed;
9
+ /**
10
+ * Acquire the mutex lock
11
+ * If already locked, waits in queue until released
12
+ */
13
+ lock(): Promise<void>;
14
+ /**
15
+ * Release the mutex lock
16
+ * Allows next waiting operation in queue to proceed
17
+ */
18
+ unlock(): void;
19
+ /**
20
+ * Destroy the mutex and reject all waiting operations
21
+ * Prevents memory leaks when mutex is no longer needed
22
+ */
23
+ destroy(): void;
24
+ /**
25
+ * Check if mutex is currently locked
26
+ */
27
+ isLocked(): boolean;
28
+ /**
29
+ * Get number of operations waiting in queue
30
+ */
31
+ getQueueLength(): number;
32
+ /**
33
+ * Run a function with exclusive access (convenience method)
34
+ * Automatically acquires and releases the lock
35
+ */
36
+ runExclusive<T>(fn: () => Promise<T> | T): Promise<T>;
37
+ }
38
+ //# sourceMappingURL=mutex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mutex.d.ts","sourceRoot":"","sources":["../../src/util/mutex.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,qBAAa,WAAW;IACpB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAyB;IACtC,OAAO,CAAC,SAAS,CAAS;IAE1B;;;OAGG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAgB3B;;;OAGG;IACH,MAAM,IAAI,IAAI;IAuBd;;;OAGG;IACH,OAAO,IAAI,IAAI;IAkBf;;OAEG;IACH,QAAQ,IAAI,OAAO;IAInB;;OAEG;IACH,cAAc,IAAI,MAAM;IAIxB;;;OAGG;IACG,YAAY,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;CAQ9D"}
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Simple mutex implementation for serializing async operations
3
+ * Prevents race conditions when multiple async operations need exclusive access
4
+ */
5
+ export class SimpleMutex {
6
+ locked = false;
7
+ queue = [];
8
+ destroyed = false;
9
+ /**
10
+ * Acquire the mutex lock
11
+ * If already locked, waits in queue until released
12
+ */
13
+ async lock() {
14
+ return new Promise((resolve, reject) => {
15
+ if (this.destroyed) {
16
+ reject(new Error('Mutex has been destroyed'));
17
+ return;
18
+ }
19
+ if (!this.locked) {
20
+ this.locked = true;
21
+ resolve();
22
+ }
23
+ else {
24
+ this.queue.push(resolve);
25
+ }
26
+ });
27
+ }
28
+ /**
29
+ * Release the mutex lock
30
+ * Allows next waiting operation in queue to proceed
31
+ */
32
+ unlock() {
33
+ if (this.destroyed) {
34
+ return;
35
+ }
36
+ this.locked = false;
37
+ const next = this.queue.shift();
38
+ if (next) {
39
+ this.locked = true;
40
+ try {
41
+ next();
42
+ }
43
+ catch {
44
+ // If resolver throws, unlock and continue with next in queue
45
+ this.locked = false;
46
+ const nextInQueue = this.queue.shift();
47
+ if (nextInQueue) {
48
+ this.locked = true;
49
+ nextInQueue();
50
+ }
51
+ }
52
+ }
53
+ }
54
+ /**
55
+ * Destroy the mutex and reject all waiting operations
56
+ * Prevents memory leaks when mutex is no longer needed
57
+ */
58
+ destroy() {
59
+ this.destroyed = true;
60
+ this.locked = false;
61
+ // Reject all queued promises to prevent memory leaks
62
+ while (this.queue.length > 0) {
63
+ const resolve = this.queue.shift();
64
+ if (resolve) {
65
+ try {
66
+ // Resolve with error state
67
+ resolve();
68
+ }
69
+ catch {
70
+ // Ignore errors during cleanup
71
+ }
72
+ }
73
+ }
74
+ }
75
+ /**
76
+ * Check if mutex is currently locked
77
+ */
78
+ isLocked() {
79
+ return this.locked;
80
+ }
81
+ /**
82
+ * Get number of operations waiting in queue
83
+ */
84
+ getQueueLength() {
85
+ return this.queue.length;
86
+ }
87
+ /**
88
+ * Run a function with exclusive access (convenience method)
89
+ * Automatically acquires and releases the lock
90
+ */
91
+ async runExclusive(fn) {
92
+ await this.lock();
93
+ try {
94
+ return await fn();
95
+ }
96
+ finally {
97
+ this.unlock();
98
+ }
99
+ }
100
+ }
101
+ //# sourceMappingURL=mutex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mutex.js","sourceRoot":"","sources":["../../src/util/mutex.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,OAAO,WAAW;IACZ,MAAM,GAAG,KAAK,CAAC;IACf,KAAK,GAAsB,EAAE,CAAC;IAC9B,SAAS,GAAG,KAAK,CAAC;IAE1B;;;OAGG;IACH,KAAK,CAAC,IAAI;QACN,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACzC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACjB,MAAM,CAAC,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC,CAAC;gBAC9C,OAAO;YACX,CAAC;YAED,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACf,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;gBACnB,OAAO,EAAE,CAAC;YACd,CAAC;iBAAM,CAAC;gBACJ,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC7B,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAED;;;OAGG;IACH,MAAM;QACF,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACjB,OAAO;QACX,CAAC;QAED,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QAChC,IAAI,IAAI,EAAE,CAAC;YACP,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;YACnB,IAAI,CAAC;gBACD,IAAI,EAAE,CAAC;YACX,CAAC;YAAC,MAAM,CAAC;gBACL,6DAA6D;gBAC7D,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;gBACpB,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;gBACvC,IAAI,WAAW,EAAE,CAAC;oBACd,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;oBACnB,WAAW,EAAE,CAAC;gBAClB,CAAC;YACL,CAAC;QACL,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,OAAO;QACH,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QAEpB,qDAAqD;QACrD,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACnC,IAAI,OAAO,EAAE,CAAC;gBACV,IAAI,CAAC;oBACD,2BAA2B;oBAC3B,OAAO,EAAE,CAAC;gBACd,CAAC;gBAAC,MAAM,CAAC;oBACL,+BAA+B;gBACnC,CAAC;YACL,CAAC;QACL,CAAC;IACL,CAAC;IAED;;OAEG;IACH,QAAQ;QACJ,OAAO,IAAI,CAAC,MAAM,CAAC;IACvB,CAAC;IAED;;OAEG;IACH,cAAc;QACV,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;IAC7B,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,YAAY,CAAI,EAAwB;QAC1C,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,IAAI,CAAC;YACD,OAAO,MAAM,EAAE,EAAE,CAAC;QACtB,CAAC;gBAAS,CAAC;YACP,IAAI,CAAC,MAAM,EAAE,CAAC;QAClB,CAAC;IACL,CAAC;CACJ"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Utility functions for tree.ts
3
+ * These are stubs/inlines of kodrdriv utilities
4
+ */
5
+ import type { TreeExecutionConfig } from '../types/config.js';
6
+ /**
7
+ * Get output path - can accept config or directory string
8
+ */
9
+ export declare function getOutputPath(configOrDir: TreeExecutionConfig | string, filename?: string): string;
10
+ /**
11
+ * Simple performance timer
12
+ */
13
+ export declare class PerformanceTimer {
14
+ private startTime;
15
+ private label;
16
+ constructor(label: string);
17
+ end(): number;
18
+ getDuration(): number;
19
+ }
20
+ /**
21
+ * Check if in git repository
22
+ */
23
+ export declare function isInGitRepository(dir: string): Promise<boolean>;
24
+ /**
25
+ * Run git command with lock (simplified version)
26
+ */
27
+ export declare function runGitWithLock<T>(fn: () => Promise<T>, _lockKey?: string): Promise<T>;
28
+ /**
29
+ * Optimize precommit command (stub)
30
+ */
31
+ export declare function optimizePrecommitCommand(_packagePath: string, command: string): Promise<{
32
+ optimizedCommand: string;
33
+ skipped: {
34
+ clean?: boolean;
35
+ test?: boolean;
36
+ };
37
+ reasons: {
38
+ clean?: string;
39
+ test?: string;
40
+ };
41
+ }>;
42
+ /**
43
+ * Record test run (stub)
44
+ */
45
+ export declare function recordTestRun(_packagePath: string, _success?: boolean, _duration?: number): Promise<void>;
46
+ //# sourceMappingURL=treeUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"treeUtils.d.ts","sourceRoot":"","sources":["../../src/util/treeUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAE9D;;GAEG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,mBAAmB,GAAG,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAMlG;AAED;;GAEG;AACH,qBAAa,gBAAgB;IACzB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,KAAK,CAAS;gBAEV,KAAK,EAAE,MAAM;IAKzB,GAAG,IAAI,MAAM;IAKb,WAAW,IAAI,MAAM;CAGxB;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAWrE;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,CAAC,EAClC,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,QAAQ,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,CAAC,CAAC,CAIZ;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAC1C,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,GAChB,OAAO,CAAC;IACP,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC7C,OAAO,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9C,CAAC,CAQD;AAED;;GAEG;AACH,wBAAsB,aAAa,CAC/B,YAAY,EAAE,MAAM,EACpB,QAAQ,CAAC,EAAE,OAAO,EAClB,SAAS,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAGf"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Utility functions for tree.ts
3
+ * These are stubs/inlines of kodrdriv utilities
4
+ */
5
+ /**
6
+ * Get output path - can accept config or directory string
7
+ */
8
+ export function getOutputPath(configOrDir, filename) {
9
+ const baseDir = typeof configOrDir === 'string'
10
+ ? configOrDir
11
+ : (configOrDir.outputDirectory || 'output/kodrdriv');
12
+ return filename ? `${baseDir}/${filename}` : baseDir;
13
+ }
14
+ /**
15
+ * Simple performance timer
16
+ */
17
+ export class PerformanceTimer {
18
+ startTime;
19
+ label;
20
+ constructor(label) {
21
+ this.label = label;
22
+ this.startTime = Date.now();
23
+ }
24
+ end() {
25
+ const duration = Date.now() - this.startTime;
26
+ return duration;
27
+ }
28
+ getDuration() {
29
+ return Date.now() - this.startTime;
30
+ }
31
+ }
32
+ /**
33
+ * Check if in git repository
34
+ */
35
+ export async function isInGitRepository(dir) {
36
+ // Simple check - could be enhanced
37
+ const fs = await import('fs/promises');
38
+ const path = await import('path');
39
+ try {
40
+ await fs.access(path.join(dir, '.git'));
41
+ return true;
42
+ }
43
+ catch {
44
+ return false;
45
+ }
46
+ }
47
+ /**
48
+ * Run git command with lock (simplified version)
49
+ */
50
+ export async function runGitWithLock(fn, _lockKey) {
51
+ // Simplified - just run the function
52
+ // In kodrdriv this uses a mutex to prevent concurrent git operations
53
+ return await fn();
54
+ }
55
+ /**
56
+ * Optimize precommit command (stub)
57
+ */
58
+ export async function optimizePrecommitCommand(_packagePath, command) {
59
+ // Stub - return command as-is with no optimizations
60
+ // In kodrdriv this optimizes test commands based on previous runs
61
+ return {
62
+ optimizedCommand: command,
63
+ skipped: {},
64
+ reasons: {}
65
+ };
66
+ }
67
+ /**
68
+ * Record test run (stub)
69
+ */
70
+ export async function recordTestRun(_packagePath, _success, _duration) {
71
+ // Stub - no-op
72
+ // In kodrdriv this records test results for optimization
73
+ }
74
+ //# sourceMappingURL=treeUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"treeUtils.js","sourceRoot":"","sources":["../../src/util/treeUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,WAAyC,EAAE,QAAiB;IACtF,MAAM,OAAO,GAAG,OAAO,WAAW,KAAK,QAAQ;QAC3C,CAAC,CAAC,WAAW;QACb,CAAC,CAAC,CAAC,WAAW,CAAC,eAAe,IAAI,iBAAiB,CAAC,CAAC;IAEzD,OAAO,QAAQ,CAAC,CAAC,CAAC,GAAG,OAAO,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;AACzD,CAAC;AAED;;GAEG;AACH,MAAM,OAAO,gBAAgB;IACjB,SAAS,CAAS;IAClB,KAAK,CAAS;IAEtB,YAAY,KAAa;QACrB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAChC,CAAC;IAED,GAAG;QACC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC;QAC7C,OAAO,QAAQ,CAAC;IACpB,CAAC;IAED,WAAW;QACP,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC;IACvC,CAAC;CACJ;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,GAAW;IAC/C,mCAAmC;IACnC,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;IACvC,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;IAElC,IAAI,CAAC;QACD,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC;QACxC,OAAO,IAAI,CAAC;IAChB,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,KAAK,CAAC;IACjB,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAChC,EAAoB,EACpB,QAAiB;IAEjB,qCAAqC;IACrC,qEAAqE;IACrE,OAAO,MAAM,EAAE,EAAE,CAAC;AACtB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC1C,YAAoB,EACpB,OAAe;IAMf,oDAAoD;IACpD,kEAAkE;IAClE,OAAO;QACH,gBAAgB,EAAE,OAAO;QACzB,OAAO,EAAE,EAAE;QACX,OAAO,EAAE,EAAE;KACd,CAAC;AACN,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAC/B,YAAoB,EACpB,QAAkB,EAClB,SAAkB;IAElB,eAAe;IACf,yDAAyD;AAC7D,CAAC"}
package/guide/index.md ADDED
@@ -0,0 +1,84 @@
1
+ # @grunnverk/tree-execution - Agentic Guide
2
+
3
+ ## Purpose
4
+
5
+ Parallel execution framework and tree orchestration for monorepo workflows. Provides task pool management, checkpoint/recovery, and resource monitoring.
6
+
7
+ ## Key Features
8
+
9
+ - **Parallel Execution** - Execute tasks across dependency graph in parallel
10
+ - **Dynamic Task Pool** - Adaptive concurrency based on resources
11
+ - **Checkpoint/Recovery** - Save and resume execution state
12
+ - **Resource Monitoring** - Track CPU, memory, and disk usage
13
+ - **Dependency Validation** - Ensure dependencies are met before execution
14
+ - **Progress Tracking** - Real-time execution progress
15
+
16
+ ## Usage
17
+
18
+ ```typescript
19
+ import { TreeExecutor, DynamicTaskPool } from '@grunnverk/tree-execution';
20
+
21
+ // Create executor
22
+ const executor = new TreeExecutor({
23
+ maxConcurrency: 4,
24
+ enableCheckpoint: true,
25
+ resourceLimits: {
26
+ maxMemory: 4096,
27
+ maxCpu: 80
28
+ }
29
+ });
30
+
31
+ // Execute tree command
32
+ await executor.execute({
33
+ command: 'npm run build',
34
+ packages: graph.getTopologicalOrder()
35
+ });
36
+
37
+ // Resume from checkpoint
38
+ await executor.resume('/path/to/checkpoint.json');
39
+ ```
40
+
41
+ ## Dependencies
42
+
43
+ - @grunnverk/tree-core - Dependency graph
44
+ - @grunnverk/git-tools - Git operations
45
+ - @grunnverk/shared - Shared utilities
46
+
47
+ ## Package Structure
48
+
49
+ ```
50
+ src/
51
+ ├── execution/ # Execution engine
52
+ │ ├── TreeExecutionAdapter.ts # Execution adapter
53
+ │ ├── DynamicTaskPool.ts # Task pool
54
+ │ ├── Scheduler.ts # Task scheduler
55
+ │ ├── ResourceMonitor.ts # Resource monitoring
56
+ │ ├── RecoveryManager.ts # Recovery logic
57
+ │ ├── DependencyChecker.ts # Dependency validation
58
+ │ └── CommandValidator.ts # Command validation
59
+ ├── checkpoint/ # Checkpoint management
60
+ │ ├── CheckpointManager.ts # Checkpoint logic
61
+ │ └── index.ts
62
+ ├── util/ # Utilities
63
+ │ ├── treeUtils.ts # Tree utilities
64
+ │ ├── commandStubs.ts # Command stubs
65
+ │ ├── mutex.ts # Mutex implementation
66
+ │ └── logger.ts # Logging
67
+ ├── types/ # Type definitions
68
+ │ ├── config.ts
69
+ │ ├── parallelExecution.ts
70
+ │ └── index.ts
71
+ ├── TreeExecutor.ts # Main executor
72
+ ├── tree.ts # Tree command
73
+ └── index.ts
74
+ ```
75
+
76
+ ## Key Exports
77
+
78
+ - `TreeExecutor` - Main execution orchestrator
79
+ - `DynamicTaskPool` - Adaptive task pool
80
+ - `CheckpointManager` - Checkpoint/recovery
81
+ - `ResourceMonitor` - Resource tracking
82
+ - `executeTree()` - Execute tree command
83
+ - `resumeExecution()` - Resume from checkpoint
84
+
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "@grunnverk/tree-execution",
3
+ "version": "1.0.0",
4
+ "description": "Parallel execution framework and tree orchestration for monorepo workflows",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "type": "module",
8
+ "scripts": {
9
+ "build": "tsc",
10
+ "test": "vitest run",
11
+ "test:watch": "vitest",
12
+ "test:coverage": "vitest run --coverage",
13
+ "lint": "eslint 'src/**/*.ts' --ignore-pattern 'src/util/logger.ts'",
14
+ "clean": "rm -rf dist coverage",
15
+ "precommit": "npm run lint && npm run build && npm test",
16
+ "prepublishOnly": "npm run clean && npm run build && npm test"
17
+ },
18
+ "keywords": [
19
+ "parallel-execution",
20
+ "task-pool",
21
+ "dependency-graph",
22
+ "tree-command",
23
+ "monorepo",
24
+ "recovery",
25
+ "checkpoint"
26
+ ],
27
+ "author": "Tim O'Brien <tobrien@discursive.com>",
28
+ "license": "MIT",
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "git+https://github.com/grunnverk/tree-execution.git"
32
+ },
33
+ "bugs": {
34
+ "url": "https://github.com/grunnverk/tree-execution/issues"
35
+ },
36
+ "homepage": "https://github.com/grunnverk/tree-execution#readme",
37
+ "dependencies": {
38
+ "@grunnverk/tree-core": "^1.0.0",
39
+ "@grunnverk/git-tools": "^1.0.1",
40
+ "@grunnverk/shared": "^0.1.11"
41
+ },
42
+ "devDependencies": {
43
+ "@eslint/eslintrc": "^3.2.0",
44
+ "@eslint/js": "^9.17.0",
45
+ "@types/node": "^25.0.3",
46
+ "@typescript-eslint/eslint-plugin": "^8.18.1",
47
+ "@typescript-eslint/parser": "^8.18.1",
48
+ "@vitest/coverage-v8": "^4.0.16",
49
+ "eslint": "^9.17.0",
50
+ "eslint-plugin-import": "^2.32.0",
51
+ "globals": "^16.5.0",
52
+ "typescript": "^5.7.2",
53
+ "vitest": "^4.0.16"
54
+ },
55
+ "engines": {
56
+ "node": ">=24.0.0"
57
+ },
58
+ "files": [
59
+ "dist",
60
+ "guide",
61
+ "README.md",
62
+ "LICENSE"
63
+ ]
64
+ }