@calmo/task-runner 3.7.0 → 3.8.1

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 (68) hide show
  1. package/.github/workflows/ci.yml +3 -0
  2. package/.jules/nexus.md +5 -0
  3. package/.jules/sentinel.md +6 -0
  4. package/AGENTS.md +1 -0
  5. package/CHANGELOG.md +16 -0
  6. package/README.md +2 -0
  7. package/coverage/coverage-final.json +8 -7
  8. package/coverage/index.html +20 -20
  9. package/coverage/lcov-report/index.html +20 -20
  10. package/coverage/lcov-report/src/EventBus.ts.html +4 -4
  11. package/coverage/lcov-report/src/TaskGraphValidationError.ts.html +1 -1
  12. package/coverage/lcov-report/src/TaskGraphValidator.ts.html +142 -82
  13. package/coverage/lcov-report/src/TaskRunner.ts.html +94 -79
  14. package/coverage/lcov-report/src/TaskRunnerBuilder.ts.html +1 -1
  15. package/coverage/lcov-report/src/TaskRunnerExecutionConfig.ts.html +1 -1
  16. package/coverage/lcov-report/src/TaskStateManager.ts.html +42 -54
  17. package/coverage/lcov-report/src/WorkflowExecutor.ts.html +56 -47
  18. package/coverage/lcov-report/src/contracts/ErrorTypes.ts.html +103 -0
  19. package/coverage/lcov-report/src/contracts/RunnerEvents.ts.html +1 -1
  20. package/coverage/lcov-report/src/contracts/index.html +23 -8
  21. package/coverage/lcov-report/src/index.html +15 -15
  22. package/coverage/lcov-report/src/strategies/DryRunExecutionStrategy.ts.html +1 -1
  23. package/coverage/lcov-report/src/strategies/RetryingExecutionStrategy.ts.html +5 -5
  24. package/coverage/lcov-report/src/strategies/StandardExecutionStrategy.ts.html +3 -3
  25. package/coverage/lcov-report/src/strategies/index.html +1 -1
  26. package/coverage/lcov.info +361 -332
  27. package/coverage/src/EventBus.ts.html +4 -4
  28. package/coverage/src/TaskGraphValidationError.ts.html +1 -1
  29. package/coverage/src/TaskGraphValidator.ts.html +142 -82
  30. package/coverage/src/TaskRunner.ts.html +94 -79
  31. package/coverage/src/TaskRunnerBuilder.ts.html +1 -1
  32. package/coverage/src/TaskRunnerExecutionConfig.ts.html +1 -1
  33. package/coverage/src/TaskStateManager.ts.html +42 -54
  34. package/coverage/src/WorkflowExecutor.ts.html +56 -47
  35. package/coverage/src/contracts/ErrorTypes.ts.html +103 -0
  36. package/coverage/src/contracts/RunnerEvents.ts.html +1 -1
  37. package/coverage/src/contracts/index.html +23 -8
  38. package/coverage/src/index.html +15 -15
  39. package/coverage/src/strategies/DryRunExecutionStrategy.ts.html +1 -1
  40. package/coverage/src/strategies/RetryingExecutionStrategy.ts.html +5 -5
  41. package/coverage/src/strategies/StandardExecutionStrategy.ts.html +3 -3
  42. package/coverage/src/strategies/index.html +1 -1
  43. package/dist/TaskGraphValidator.d.ts +3 -0
  44. package/dist/TaskGraphValidator.js +33 -26
  45. package/dist/TaskGraphValidator.js.map +1 -1
  46. package/dist/TaskRunner.d.ts +4 -0
  47. package/dist/TaskRunner.js +39 -45
  48. package/dist/TaskRunner.js.map +1 -1
  49. package/dist/TaskStateManager.js +1 -5
  50. package/dist/TaskStateManager.js.map +1 -1
  51. package/dist/TaskStep.d.ts +6 -0
  52. package/dist/WorkflowExecutor.js +2 -0
  53. package/dist/WorkflowExecutor.js.map +1 -1
  54. package/dist/contracts/ErrorTypes.d.ts +6 -0
  55. package/dist/contracts/ErrorTypes.js +7 -0
  56. package/dist/contracts/ErrorTypes.js.map +1 -0
  57. package/dist/contracts/ValidationError.d.ts +2 -1
  58. package/openspec/changes/feat-task-metrics/proposal.md +17 -0
  59. package/openspec/changes/feat-task-metrics/tasks.md +6 -0
  60. package/package.json +14 -3
  61. package/src/TaskGraphValidator.ts +52 -32
  62. package/src/TaskRunner.ts +52 -47
  63. package/src/TaskStateManager.ts +1 -5
  64. package/src/TaskStep.ts +7 -0
  65. package/src/WorkflowExecutor.ts +3 -0
  66. package/src/contracts/ErrorTypes.ts +6 -0
  67. package/src/contracts/ValidationError.ts +10 -1
  68. package/test-report.xml +145 -123
@@ -1,3 +1,4 @@
1
+ import { ERROR_CYCLE, ERROR_DUPLICATE_TASK, ERROR_MISSING_DEPENDENCY, } from "./contracts/ErrorTypes.js";
1
2
  export class TaskGraphValidator {
2
3
  /**
3
4
  * Validates a given task graph for structural integrity.
@@ -12,11 +13,35 @@ export class TaskGraphValidator {
12
13
  validate(taskGraph) {
13
14
  const errors = [];
14
15
  // 1. Check for duplicate tasks
16
+ const taskIds = this.checkDuplicateTasks(taskGraph, errors);
17
+ // 2. Check for missing dependencies
18
+ this.checkMissingDependencies(taskGraph, taskIds, errors);
19
+ // 3. Check for cycles
20
+ // Only run cycle detection if there are no missing dependencies, otherwise we might chase non-existent nodes.
21
+ const hasMissingDependencies = errors.some((e) => e.type === ERROR_MISSING_DEPENDENCY);
22
+ if (!hasMissingDependencies) {
23
+ this.checkCycles(taskGraph, errors);
24
+ }
25
+ return {
26
+ isValid: errors.length === 0,
27
+ errors,
28
+ };
29
+ }
30
+ /**
31
+ * Creates a human-readable error message from a validation result.
32
+ * @param result The validation result containing errors.
33
+ * @returns A formatted error string.
34
+ */
35
+ createErrorMessage(result) {
36
+ const errorDetails = result.errors.map((e) => e.message);
37
+ return `Task graph validation failed: ${errorDetails.join("; ")}`;
38
+ }
39
+ checkDuplicateTasks(taskGraph, errors) {
15
40
  const taskIds = new Set();
16
41
  for (const task of taskGraph.tasks) {
17
42
  if (taskIds.has(task.id)) {
18
43
  errors.push({
19
- type: "duplicate_task",
44
+ type: ERROR_DUPLICATE_TASK,
20
45
  message: `Duplicate task detected with ID: ${task.id}`,
21
46
  details: { taskId: task.id },
22
47
  });
@@ -25,27 +50,22 @@ export class TaskGraphValidator {
25
50
  taskIds.add(task.id);
26
51
  }
27
52
  }
28
- // 2. Check for missing dependencies
53
+ return taskIds;
54
+ }
55
+ checkMissingDependencies(taskGraph, taskIds, errors) {
29
56
  for (const task of taskGraph.tasks) {
30
57
  for (const dependenceId of task.dependencies) {
31
58
  if (!taskIds.has(dependenceId)) {
32
59
  errors.push({
33
- type: "missing_dependency",
60
+ type: ERROR_MISSING_DEPENDENCY,
34
61
  message: `Task '${task.id}' depends on missing task '${dependenceId}'`,
35
62
  details: { taskId: task.id, missingDependencyId: dependenceId },
36
63
  });
37
64
  }
38
65
  }
39
66
  }
40
- // 3. Check for cycles
41
- // Only run cycle detection if there are no missing dependencies, otherwise we might chase non-existent nodes.
42
- const hasMissingDependencies = errors.some((e) => e.type === "missing_dependency");
43
- if (hasMissingDependencies) {
44
- return {
45
- isValid: errors.length === 0,
46
- errors,
47
- };
48
- }
67
+ }
68
+ checkCycles(taskGraph, errors) {
49
69
  // Build adjacency list
50
70
  const adjacencyList = new Map();
51
71
  for (const task of taskGraph.tasks) {
@@ -65,7 +85,7 @@ export class TaskGraphValidator {
65
85
  const cycleStartIndex = path.indexOf(cycleStart);
66
86
  const cyclePath = path.slice(cycleStartIndex);
67
87
  errors.push({
68
- type: "cycle",
88
+ type: ERROR_CYCLE,
69
89
  message: `Cycle detected: ${cyclePath.join(" -> ")}`,
70
90
  details: { cyclePath },
71
91
  });
@@ -73,19 +93,6 @@ export class TaskGraphValidator {
73
93
  break;
74
94
  }
75
95
  }
76
- return {
77
- isValid: errors.length === 0,
78
- errors,
79
- };
80
- }
81
- /**
82
- * Creates a human-readable error message from a validation result.
83
- * @param result The validation result containing errors.
84
- * @returns A formatted error string.
85
- */
86
- createErrorMessage(result) {
87
- const errorDetails = result.errors.map((e) => e.message);
88
- return `Task graph validation failed: ${errorDetails.join("; ")}`;
89
96
  }
90
97
  detectCycle(startTaskId, path, visited, recursionStack, adjacencyList) {
91
98
  // Use an explicit stack to avoid maximum call stack size exceeded errors
@@ -1 +1 @@
1
- {"version":3,"file":"TaskGraphValidator.js","sourceRoot":"","sources":["../src/TaskGraphValidator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TaskGraphValidator.js","sourceRoot":"","sources":["../src/TaskGraphValidator.ts"],"names":[],"mappings":"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"}
@@ -57,4 +57,8 @@ export declare class TaskRunner<TContext> {
57
57
  * and values are the corresponding TaskResult objects.
58
58
  */
59
59
  execute(steps: TaskStep<TContext>[], config?: TaskRunnerExecutionConfig): Promise<Map<string, TaskResult>>;
60
+ /**
61
+ * Executes tasks with a timeout, ensuring resources are cleaned up.
62
+ */
63
+ private executeWithTimeout;
60
64
  }
@@ -56,21 +56,10 @@ export class TaskRunner {
56
56
  */
57
57
  static getMermaidGraph(steps) {
58
58
  const graphLines = ["graph TD"];
59
- // Helper to sanitize node names or wrap them if needed
60
- // For simplicity, we just wrap in quotes and use the name as ID if it's simple
61
- // or generate an ID if strictly needed. Here we assume names are unique IDs.
62
- // We will wrap names in quotes for the label, but use the name as the ID.
63
- // Actually, Mermaid ID cannot have spaces without quotes.
64
- const safeId = (name) => JSON.stringify(name);
65
59
  const sanitize = (name) => this.sanitizeMermaidId(name);
66
- // Add all nodes first to ensure they exist
67
60
  for (const step of steps) {
68
- // Using the name as both ID and Label for simplicity
69
- // Format: ID["Label"]
70
- // safeId returns a quoted string (e.g. "Task Name"), so we use it directly as the label
71
- graphLines.push(` ${sanitize(step.name)}[${safeId(step.name)}]`);
61
+ graphLines.push(` ${sanitize(step.name)}[${JSON.stringify(step.name)}]`);
72
62
  }
73
- // Add edges
74
63
  for (const step of steps) {
75
64
  if (step.dependencies) {
76
65
  for (const dep of step.dependencies) {
@@ -86,7 +75,7 @@ export class TaskRunner {
86
75
  * @returns The sanitized string.
87
76
  */
88
77
  static sanitizeMermaidId(id) {
89
- return id.replaceAll(/ /g, "_").replaceAll(/:/g, "_").replaceAll(/"/g, "_");
78
+ return id.replaceAll(/[^a-zA-Z0-9_-]/g, "_");
90
79
  }
91
80
  /**
92
81
  * Executes a list of tasks, respecting their dependencies and running
@@ -114,43 +103,48 @@ export class TaskRunner {
114
103
  strategy = new DryRunExecutionStrategy();
115
104
  }
116
105
  const executor = new WorkflowExecutor(this.context, this.eventBus, stateManager, strategy, config?.concurrency);
117
- // We need to handle the timeout cleanup properly.
118
106
  if (config?.timeout !== undefined) {
119
- const controller = new AbortController();
120
- const timeoutId = setTimeout(() => {
121
- controller.abort(new Error(`Workflow timed out after ${config.timeout}ms`));
122
- }, config.timeout);
123
- let effectiveSignal = controller.signal;
124
- let onAbort;
125
- // Handle combination of signals if user provided one
126
- if (config.signal) {
127
- if (config.signal.aborted) {
128
- // If already aborted, use it directly (WorkflowExecutor handles early abort)
129
- // We can cancel timeout immediately
130
- clearTimeout(timeoutId);
131
- effectiveSignal = config.signal;
132
- }
133
- else {
134
- // Listen to user signal to abort our controller
135
- onAbort = () => {
136
- controller.abort(config.signal?.reason);
137
- };
138
- config.signal.addEventListener("abort", onAbort);
139
- }
140
- }
141
- try {
142
- return await executor.execute(steps, effectiveSignal);
143
- }
144
- finally {
145
- clearTimeout(timeoutId);
146
- if (config.signal && onAbort) {
147
- config.signal.removeEventListener("abort", onAbort);
148
- }
149
- }
107
+ return this.executeWithTimeout(executor, steps, config.timeout, config.signal);
150
108
  }
151
109
  else {
152
110
  return executor.execute(steps, config?.signal);
153
111
  }
154
112
  }
113
+ /**
114
+ * Executes tasks with a timeout, ensuring resources are cleaned up.
115
+ */
116
+ async executeWithTimeout(executor, steps, timeout, signal) {
117
+ const controller = new AbortController();
118
+ const timeoutId = setTimeout(() => {
119
+ controller.abort(new Error(`Workflow timed out after ${timeout}ms`));
120
+ }, timeout);
121
+ let effectiveSignal = controller.signal;
122
+ let onAbort;
123
+ // Handle combination of signals if user provided one
124
+ if (signal) {
125
+ if (signal.aborted) {
126
+ // If already aborted, use it directly (WorkflowExecutor handles early abort)
127
+ // We can cancel timeout immediately
128
+ clearTimeout(timeoutId);
129
+ effectiveSignal = signal;
130
+ }
131
+ else {
132
+ // Listen to user signal to abort our controller
133
+ onAbort = () => {
134
+ controller.abort(signal.reason);
135
+ };
136
+ signal.addEventListener("abort", onAbort);
137
+ }
138
+ }
139
+ try {
140
+ return await executor.execute(steps, effectiveSignal);
141
+ }
142
+ finally {
143
+ clearTimeout(timeoutId);
144
+ if (signal && onAbort) {
145
+ signal.removeEventListener("abort", onAbort);
146
+ }
147
+ }
148
+ }
155
149
  }
156
150
  //# sourceMappingURL=TaskRunner.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TaskRunner.js","sourceRoot":"","sources":["../src/TaskRunner.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TaskRunner.js","sourceRoot":"","sources":["../src/TaskRunner.ts"],"names":[],"mappings":"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"}
@@ -91,20 +91,16 @@ export class TaskStateManager {
91
91
  for (const step of this.pendingSteps) {
92
92
  // Also check running? No, running tasks are handled by AbortSignal in Executor.
93
93
  // We only cancel what is pending and hasn't started.
94
- /* v8 ignore next 1 */
95
94
  if (!this.results.has(step.name) && !this.running.has(step.name)) {
96
95
  const result = {
97
96
  status: "cancelled",
98
97
  message,
99
98
  };
100
99
  this.results.set(step.name, result);
100
+ this.eventBus.emit("taskEnd", { step, result });
101
101
  }
102
102
  }
103
103
  // Clear pending set as they are now "done" (cancelled)
104
- // Wait, if we clear pending steps, processDependencies won't pick them up.
105
- // The loop in Executor relies on results.size or pendingSteps.
106
- // The previous implementation iterated `steps` (all steps) to cancel.
107
- // Here we iterate `pendingSteps`.
108
104
  this.pendingSteps.clear();
109
105
  }
110
106
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"TaskStateManager.js","sourceRoot":"","sources":["../src/TaskStateManager.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,MAAM,OAAO,gBAAgB;IAKP;IAJZ,OAAO,GAAG,IAAI,GAAG,EAAsB,CAAC;IACxC,YAAY,GAAG,IAAI,GAAG,EAAsB,CAAC;IAC7C,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAEpC,YAAoB,QAA4B;QAA5B,aAAQ,GAAR,QAAQ,CAAoB;IAAG,CAAC;IAEpD;;;OAGG;IACH,UAAU,CAAC,KAA2B;QACpC,IAAI,CAAC,YAAY,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACrB,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;IAED;;;;OAIG;IACH,mBAAmB;QACjB,MAAM,QAAQ,GAAyB,EAAE,CAAC;QAC1C,MAAM,KAAK,GAAyB,EAAE,CAAC;QAEvC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACrC,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC;YACrC,IAAI,OAAO,GAAG,KAAK,CAAC;YACpB,IAAI,SAA6B,CAAC;YAElC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;gBACvB,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBACxC,IAAI,CAAC,SAAS,EAAE,CAAC;oBACf,8BAA8B;oBAC9B,OAAO,GAAG,IAAI,CAAC;gBACjB,CAAC;qBAAM,IAAI,SAAS,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;oBAC1C,SAAS,GAAG,GAAG,CAAC;oBAChB,MAAM;gBACR,CAAC;YACH,CAAC;YAED,IAAI,SAAS,EAAE,CAAC;gBACd,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;gBAC9C,MAAM,QAAQ,GAAG,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAChE,MAAM,MAAM,GAAe;oBACzB,MAAM,EAAE,SAAS;oBACjB,OAAO,EAAE,+BAA+B,SAAS,WAAW,QAAQ,EAAE;iBACvE,CAAC;gBACF,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;gBAC/B,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtB,CAAC;iBAAM,IAAI,CAAC,OAAO,EAAE,CAAC;gBACpB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACjB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtB,CAAC;QACH,CAAC;QAED,sBAAsB;QACtB,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;YAC5B,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACjC,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;OAGG;IACH,WAAW,CAAC,IAAwB;QAClC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5C,CAAC;IAED;;;;;OAKG;IACH,aAAa,CAAC,IAAwB,EAAE,MAAkB;QACxD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACpC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IAClD,CAAC;IAED;;;OAGG;IACH,gBAAgB,CAAC,OAAe;QAC9B,2CAA2C;QAC3C,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACrC,gFAAgF;YAChF,qDAAqD;YACrD,sBAAsB;YACtB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACjE,MAAM,MAAM,GAAe;oBACzB,MAAM,EAAE,WAAW;oBACnB,OAAO;iBACR,CAAC;gBACF,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YACtC,CAAC;QACH,CAAC;QACD,uDAAuD;QACvD,2EAA2E;QAC3E,+DAA+D;QAC/D,sEAAsE;QACtE,kCAAkC;QAClC,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;IAC5B,CAAC;IAED;;OAEG;IACH,UAAU;QACR,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED;;OAEG;IACH,eAAe;QACb,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,CAAC;IAC/B,CAAC;IAED;;OAEG;IACH,eAAe;QACb,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,GAAG,CAAC,CAAC;IACpC,CAAC;IAED;;;;OAIG;IACH,WAAW,CAAC,IAAwB,EAAE,MAAkB;QACtD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACpC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IACtD,CAAC;CACF"}
1
+ {"version":3,"file":"TaskStateManager.js","sourceRoot":"","sources":["../src/TaskStateManager.ts"],"names":[],"mappings":"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"}
@@ -16,6 +16,12 @@ export interface TaskStep<TContext> {
16
16
  * If it returns false (synchronously or asynchronously), the task is skipped.
17
17
  */
18
18
  condition?: (context: TContext) => boolean | Promise<boolean>;
19
+ /**
20
+ * Optional priority.
21
+ * Higher values are picked first. Default is 0.
22
+ * Only affects ordering when multiple tasks are ready and concurrency slots are limited.
23
+ */
24
+ priority?: number;
19
25
  /**
20
26
  * The core logic of the task.
21
27
  * @param context The shared context object, allowing for state to be passed between tasks.
@@ -92,6 +92,8 @@ export class WorkflowExecutor {
92
92
  for (const task of newlyReady) {
93
93
  this.readyQueue.push(task);
94
94
  }
95
+ // Sort by priority (descending) once after adding new tasks
96
+ this.readyQueue.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
95
97
  // Execute ready tasks while respecting concurrency limit
96
98
  while (this.readyQueue.length > 0) {
97
99
  if (this.concurrency !== undefined &&
@@ -1 +1 @@
1
- {"version":3,"file":"WorkflowExecutor.js","sourceRoot":"","sources":["../src/WorkflowExecutor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"WorkflowExecutor.js","sourceRoot":"","sources":["../src/WorkflowExecutor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Error type constants for task graph validation.
3
+ */
4
+ export declare const ERROR_DUPLICATE_TASK: "duplicate_task";
5
+ export declare const ERROR_MISSING_DEPENDENCY: "missing_dependency";
6
+ export declare const ERROR_CYCLE: "cycle";
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Error type constants for task graph validation.
3
+ */
4
+ export const ERROR_DUPLICATE_TASK = "duplicate_task";
5
+ export const ERROR_MISSING_DEPENDENCY = "missing_dependency";
6
+ export const ERROR_CYCLE = "cycle";
7
+ //# sourceMappingURL=ErrorTypes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ErrorTypes.js","sourceRoot":"","sources":["../../src/contracts/ErrorTypes.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,gBAAyB,CAAC;AAC9D,MAAM,CAAC,MAAM,wBAAwB,GAAG,oBAA6B,CAAC;AACtE,MAAM,CAAC,MAAM,WAAW,GAAG,OAAgB,CAAC"}
@@ -1,9 +1,10 @@
1
+ import { ERROR_CYCLE, ERROR_DUPLICATE_TASK, ERROR_MISSING_DEPENDENCY } from "./ErrorTypes.js";
1
2
  /**
2
3
  * Describes a specific validation error found in the task graph.
3
4
  */
4
5
  export interface ValidationError {
5
6
  /** The type of validation error. */
6
- type: "cycle" | "missing_dependency" | "duplicate_task";
7
+ type: typeof ERROR_CYCLE | typeof ERROR_MISSING_DEPENDENCY | typeof ERROR_DUPLICATE_TASK;
7
8
  /** A human-readable message describing the error. */
8
9
  message: string;
9
10
  /** Optional detailed information about the error, e.g., the cycle path, or the task with a missing dependency. */
@@ -0,0 +1,17 @@
1
+ # Change: Task Execution Metrics
2
+
3
+ ## Why
4
+
5
+ Users currently lack visibility into the performance of individual tasks within a workflow. When a workflow is slow, it is difficult to identify which task is the bottleneck without adding manual logging code to every task. Providing built-in execution metrics (start time, end time, duration) will allow users to optimize their workflows and debug performance issues more effectively.
6
+
7
+ ## What Changes
8
+
9
+ - Update `TaskResult` interface to include an optional `metrics` property containing `startTime`, `endTime`, and `duration`.
10
+ - Update `WorkflowExecutor` to capture these timestamps during task execution and populate the `metrics` property.
11
+ - Ensure these metrics are available in the final `TaskResult` map returned by `TaskRunner.execute`.
12
+
13
+ ## Impact
14
+
15
+ - Affected specs: `001-generic-task-runner`
16
+ - Affected code: `src/TaskResult.ts`, `src/WorkflowExecutor.ts`
17
+ - **Non-breaking change**: The new property is optional, so existing code consuming `TaskResult` will continue to work.
@@ -0,0 +1,6 @@
1
+ ## 1. Implementation
2
+
3
+ - [ ] 1.1 Update `TaskResult` interface in `src/TaskResult.ts` to include `metrics`.
4
+ - [ ] 1.2 Update `WorkflowExecutor.ts` to capture start/end times and calculate duration.
5
+ - [ ] 1.3 Update `WorkflowExecutor.ts` to inject metrics into the `TaskResult`.
6
+ - [ ] 1.4 Add unit tests in `tests/TaskMetrics.test.ts` to verify metrics are present and correct.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@calmo/task-runner",
3
- "version": "3.7.0",
4
- "description": "",
3
+ "version": "3.8.1",
4
+ "description": "A lightweight, type-safe, and domain-agnostic task orchestration engine. It resolves a Directed Acyclic Graph (DAG) of steps, executes independent tasks in parallel, and manages a shared context across the pipeline.",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/thalesraymond/task-runner.git"
@@ -30,7 +30,18 @@
30
30
  "path": "git-cz"
31
31
  }
32
32
  },
33
- "keywords": [],
33
+ "keywords": [
34
+ "task-runner",
35
+ "workflow",
36
+ "pipeline",
37
+ "orchestration",
38
+ "dag",
39
+ "typescript",
40
+ "parallel-execution",
41
+ "dependency-graph",
42
+ "async",
43
+ "type-safe"
44
+ ],
34
45
  "author": "",
35
46
  "license": "ISC",
36
47
  "packageManager": "pnpm@10.28.0",
@@ -2,6 +2,11 @@ import { ITaskGraphValidator } from "./contracts/ITaskGraphValidator.js";
2
2
  import { ValidationResult } from "./contracts/ValidationResult.js";
3
3
  import { ValidationError } from "./contracts/ValidationError.js";
4
4
  import { TaskGraph } from "./TaskGraph.js";
5
+ import {
6
+ ERROR_CYCLE,
7
+ ERROR_DUPLICATE_TASK,
8
+ ERROR_MISSING_DEPENDENCY,
9
+ } from "./contracts/ErrorTypes.js";
5
10
 
6
11
  export class TaskGraphValidator implements ITaskGraphValidator {
7
12
  /**
@@ -18,11 +23,46 @@ export class TaskGraphValidator implements ITaskGraphValidator {
18
23
  const errors: ValidationError[] = [];
19
24
 
20
25
  // 1. Check for duplicate tasks
26
+ const taskIds = this.checkDuplicateTasks(taskGraph, errors);
27
+
28
+ // 2. Check for missing dependencies
29
+ this.checkMissingDependencies(taskGraph, taskIds, errors);
30
+
31
+ // 3. Check for cycles
32
+ // Only run cycle detection if there are no missing dependencies, otherwise we might chase non-existent nodes.
33
+ const hasMissingDependencies = errors.some(
34
+ (e) => e.type === ERROR_MISSING_DEPENDENCY
35
+ );
36
+
37
+ if (!hasMissingDependencies) {
38
+ this.checkCycles(taskGraph, errors);
39
+ }
40
+
41
+ return {
42
+ isValid: errors.length === 0,
43
+ errors,
44
+ };
45
+ }
46
+
47
+ /**
48
+ * Creates a human-readable error message from a validation result.
49
+ * @param result The validation result containing errors.
50
+ * @returns A formatted error string.
51
+ */
52
+ createErrorMessage(result: ValidationResult): string {
53
+ const errorDetails = result.errors.map((e) => e.message);
54
+ return `Task graph validation failed: ${errorDetails.join("; ")}`;
55
+ }
56
+
57
+ private checkDuplicateTasks(
58
+ taskGraph: TaskGraph,
59
+ errors: ValidationError[]
60
+ ): Set<string> {
21
61
  const taskIds = new Set<string>();
22
62
  for (const task of taskGraph.tasks) {
23
63
  if (taskIds.has(task.id)) {
24
64
  errors.push({
25
- type: "duplicate_task",
65
+ type: ERROR_DUPLICATE_TASK,
26
66
  message: `Duplicate task detected with ID: ${task.id}`,
27
67
  details: { taskId: task.id },
28
68
  });
@@ -30,33 +70,28 @@ export class TaskGraphValidator implements ITaskGraphValidator {
30
70
  taskIds.add(task.id);
31
71
  }
32
72
  }
73
+ return taskIds;
74
+ }
33
75
 
34
- // 2. Check for missing dependencies
76
+ private checkMissingDependencies(
77
+ taskGraph: TaskGraph,
78
+ taskIds: Set<string>,
79
+ errors: ValidationError[]
80
+ ): void {
35
81
  for (const task of taskGraph.tasks) {
36
82
  for (const dependenceId of task.dependencies) {
37
83
  if (!taskIds.has(dependenceId)) {
38
84
  errors.push({
39
- type: "missing_dependency",
85
+ type: ERROR_MISSING_DEPENDENCY,
40
86
  message: `Task '${task.id}' depends on missing task '${dependenceId}'`,
41
87
  details: { taskId: task.id, missingDependencyId: dependenceId },
42
88
  });
43
89
  }
44
90
  }
45
91
  }
92
+ }
46
93
 
47
- // 3. Check for cycles
48
- // Only run cycle detection if there are no missing dependencies, otherwise we might chase non-existent nodes.
49
- const hasMissingDependencies = errors.some(
50
- (e) => e.type === "missing_dependency"
51
- );
52
-
53
- if (hasMissingDependencies) {
54
- return {
55
- isValid: errors.length === 0,
56
- errors,
57
- };
58
- }
59
-
94
+ private checkCycles(taskGraph: TaskGraph, errors: ValidationError[]): void {
60
95
  // Build adjacency list
61
96
  const adjacencyList = new Map<string, string[]>();
62
97
  for (const task of taskGraph.tasks) {
@@ -82,7 +117,7 @@ export class TaskGraphValidator implements ITaskGraphValidator {
82
117
  const cyclePath = path.slice(cycleStartIndex);
83
118
 
84
119
  errors.push({
85
- type: "cycle",
120
+ type: ERROR_CYCLE,
86
121
  message: `Cycle detected: ${cyclePath.join(" -> ")}`,
87
122
  details: { cyclePath },
88
123
  });
@@ -90,21 +125,6 @@ export class TaskGraphValidator implements ITaskGraphValidator {
90
125
  break;
91
126
  }
92
127
  }
93
-
94
- return {
95
- isValid: errors.length === 0,
96
- errors,
97
- };
98
- }
99
-
100
- /**
101
- * Creates a human-readable error message from a validation result.
102
- * @param result The validation result containing errors.
103
- * @returns A formatted error string.
104
- */
105
- createErrorMessage(result: ValidationResult): string {
106
- const errorDetails = result.errors.map((e) => e.message);
107
- return `Task graph validation failed: ${errorDetails.join("; ")}`;
108
128
  }
109
129
 
110
130
  private detectCycle(