@calmo/task-runner 4.0.4 → 4.2.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 (91) hide show
  1. package/.github/workflows/codeql.yml +1 -1
  2. package/.github/workflows/release-please.yml +2 -2
  3. package/.jules/nexus.md +10 -0
  4. package/.release-please-manifest.json +1 -1
  5. package/AGENTS.md +3 -0
  6. package/CHANGELOG.md +46 -0
  7. package/CODE_OF_CONDUCT.md +131 -0
  8. package/CONTRIBUTING.md +89 -0
  9. package/README.md +34 -0
  10. package/conductor/code_styleguides/general.md +23 -0
  11. package/conductor/code_styleguides/javascript.md +51 -0
  12. package/conductor/code_styleguides/typescript.md +43 -0
  13. package/conductor/product-guidelines.md +14 -0
  14. package/conductor/product.md +16 -0
  15. package/conductor/setup_state.json +1 -0
  16. package/conductor/tech-stack.md +19 -0
  17. package/conductor/workflow.md +334 -0
  18. package/dist/EventBus.js +16 -16
  19. package/dist/EventBus.js.map +1 -1
  20. package/dist/PluginManager.d.ts +22 -0
  21. package/dist/PluginManager.js +39 -0
  22. package/dist/PluginManager.js.map +1 -0
  23. package/dist/TaskGraphValidator.d.ts +1 -1
  24. package/dist/TaskGraphValidator.js +16 -21
  25. package/dist/TaskGraphValidator.js.map +1 -1
  26. package/dist/TaskResult.d.ts +9 -0
  27. package/dist/TaskRunner.d.ts +8 -1
  28. package/dist/TaskRunner.js +64 -41
  29. package/dist/TaskRunner.js.map +1 -1
  30. package/dist/TaskStateManager.d.ts +22 -6
  31. package/dist/TaskStateManager.js +105 -45
  32. package/dist/TaskStateManager.js.map +1 -1
  33. package/dist/WorkflowExecutor.js +36 -20
  34. package/dist/WorkflowExecutor.js.map +1 -1
  35. package/dist/contracts/Plugin.d.ts +30 -0
  36. package/dist/contracts/Plugin.js +2 -0
  37. package/dist/contracts/Plugin.js.map +1 -0
  38. package/dist/strategies/DryRunExecutionStrategy.d.ts +1 -1
  39. package/dist/strategies/DryRunExecutionStrategy.js +2 -4
  40. package/dist/strategies/DryRunExecutionStrategy.js.map +1 -1
  41. package/dist/utils/PriorityQueue.d.ts +13 -0
  42. package/dist/utils/PriorityQueue.js +82 -0
  43. package/dist/utils/PriorityQueue.js.map +1 -0
  44. package/openspec/changes/add-middleware-support/proposal.md +19 -0
  45. package/openspec/changes/add-middleware-support/specs/task-runner/spec.md +34 -0
  46. package/openspec/changes/add-middleware-support/tasks.md +9 -0
  47. package/openspec/changes/add-resource-concurrency/proposal.md +18 -0
  48. package/openspec/changes/add-resource-concurrency/specs/task-runner/spec.md +25 -0
  49. package/openspec/changes/add-resource-concurrency/tasks.md +10 -0
  50. package/openspec/changes/allow-plugin-hooks/design.md +51 -0
  51. package/openspec/changes/allow-plugin-hooks/proposal.md +12 -0
  52. package/openspec/changes/allow-plugin-hooks/specs/post-task/spec.md +21 -0
  53. package/openspec/changes/allow-plugin-hooks/specs/pre-task/spec.md +32 -0
  54. package/openspec/changes/allow-plugin-hooks/tasks.md +7 -0
  55. package/openspec/changes/{feat-task-metrics → archive/2026-01-22-feat-task-metrics}/proposal.md +1 -1
  56. package/openspec/changes/archive/2026-01-22-feat-task-metrics/tasks.md +6 -0
  57. package/openspec/changes/archive/2026-02-15-implement-plugin-system/design.md +45 -0
  58. package/openspec/changes/archive/2026-02-15-implement-plugin-system/proposal.md +13 -0
  59. package/openspec/changes/archive/2026-02-15-implement-plugin-system/specs/plugin-context/spec.md +17 -0
  60. package/openspec/changes/archive/2026-02-15-implement-plugin-system/specs/plugin-loading/spec.md +27 -0
  61. package/openspec/changes/archive/2026-02-15-implement-plugin-system/tasks.md +7 -0
  62. package/openspec/changes/feat-completion-dependencies/proposal.md +58 -0
  63. package/openspec/changes/feat-completion-dependencies/tasks.md +46 -0
  64. package/openspec/changes/feat-conditional-retries/proposal.md +18 -0
  65. package/openspec/changes/feat-conditional-retries/specs/task-runner/spec.md +23 -0
  66. package/openspec/changes/feat-conditional-retries/tasks.md +37 -0
  67. package/openspec/changes/feat-state-persistence/specs/task-runner/spec.md +47 -0
  68. package/openspec/changes/feat-task-loop/proposal.md +22 -0
  69. package/openspec/changes/feat-task-loop/specs/task-runner/spec.md +34 -0
  70. package/openspec/changes/feat-task-loop/tasks.md +8 -0
  71. package/openspec/specs/plugin-context/spec.md +19 -0
  72. package/openspec/specs/plugin-loading/spec.md +29 -0
  73. package/openspec/specs/release-pr/spec.md +31 -0
  74. package/openspec/specs/task-runner/spec.md +12 -0
  75. package/package.json +1 -1
  76. package/src/EventBus.ts +7 -8
  77. package/src/PluginManager.ts +41 -0
  78. package/src/TaskGraphValidator.ts +22 -24
  79. package/src/TaskResult.ts +9 -0
  80. package/src/TaskRunner.ts +78 -46
  81. package/src/TaskStateManager.ts +118 -46
  82. package/src/WorkflowExecutor.ts +45 -22
  83. package/src/contracts/Plugin.ts +32 -0
  84. package/src/strategies/DryRunExecutionStrategy.ts +2 -3
  85. package/src/utils/PriorityQueue.ts +101 -0
  86. package/openspec/changes/feat-task-metrics/tasks.md +0 -6
  87. /package/openspec/changes/{adopt-release-pr → archive/2026-01-22-adopt-release-pr}/design.md +0 -0
  88. /package/openspec/changes/{adopt-release-pr → archive/2026-01-22-adopt-release-pr}/proposal.md +0 -0
  89. /package/openspec/changes/{adopt-release-pr → archive/2026-01-22-adopt-release-pr}/specs/release-pr/spec.md +0 -0
  90. /package/openspec/changes/{adopt-release-pr → archive/2026-01-22-adopt-release-pr}/tasks.md +0 -0
  91. /package/openspec/changes/{feat-task-metrics → archive/2026-01-22-feat-task-metrics}/specs/001-generic-task-runner/spec.md +0 -0
@@ -0,0 +1,334 @@
1
+ # Project Workflow
2
+
3
+ ## Guiding Principles
4
+
5
+ 1. **The Plan is the Source of Truth:** All work must be tracked in `plan.md`
6
+ 2. **The Tech Stack is Deliberate:** Changes to the tech stack must be documented in `tech-stack.md` *before* implementation
7
+ 3. **Test-Driven Development:** Write unit tests before implementing functionality
8
+ 4. **High Code Coverage:** Aim for 100% code coverage for all modules
9
+ 5. **User Experience First:** Every decision should prioritize user experience
10
+ 6. **Non-Interactive & CI-Aware:** Prefer non-interactive commands. Use `CI=true` for watch-mode tools (tests, linters) to ensure single execution.
11
+
12
+ ## Task Workflow
13
+
14
+ All tasks follow a strict lifecycle:
15
+
16
+ ### Standard Task Workflow
17
+
18
+ 1. **Select Task:** Choose the next available task from `plan.md` in sequential order
19
+
20
+ 2. **Mark In Progress:** Before beginning work, edit `plan.md` and change the task from `[ ]` to `[~]`
21
+
22
+ 3. **Write Failing Tests (Red Phase):**
23
+ - Create a new test file for the feature or bug fix.
24
+ - Write one or more unit tests that clearly define the expected behavior and acceptance criteria for the task.
25
+ - **CRITICAL:** Run the tests and confirm that they fail as expected. This is the "Red" phase of TDD. Do not proceed until you have failing tests.
26
+
27
+ 4. **Implement to Pass Tests (Green Phase):**
28
+ - Write the minimum amount of application code necessary to make the failing tests pass.
29
+ - Run the test suite again and confirm that all tests now pass. This is the "Green" phase.
30
+
31
+ 5. **Refactor (Optional but Recommended):**
32
+ - With the safety of passing tests, refactor the implementation code and the test code to improve clarity, remove duplication, and enhance performance without changing the external behavior.
33
+ - Rerun tests to ensure they still pass after refactoring.
34
+
35
+ 6. **Verify Coverage:** Run coverage reports using the project's chosen tools. For example, in a Python project, this might look like:
36
+ ```bash
37
+ pytest --cov=app --cov-report=html
38
+ ```
39
+ Target: 100% coverage for new code. The specific tools and commands will vary by language and framework.
40
+
41
+ 7. **Document Deviations:** If implementation differs from tech stack:
42
+ - **STOP** implementation
43
+ - Update `tech-stack.md` with new design
44
+ - Add dated note explaining the change
45
+ - Resume implementation
46
+
47
+ 8. **Commit Code Changes:**
48
+ - Stage all code changes related to the task.
49
+ - Always use conventional commits
50
+ - Propose a clear, concise commit message e.g, `feat(ui): Create basic HTML structure for calculator`.
51
+ - Perform the commit.
52
+
53
+ 9. **Attach Task Summary with Git Notes:**
54
+ - **Step 9.1: Get Commit Hash:** Obtain the hash of the *just-completed commit* (`git log -1 --format="%H"`).
55
+ - **Step 9.2: Draft Note Content:** Create a detailed summary for the completed task. This should include the task name, a summary of changes, a list of all created/modified files, and the core "why" for the change.
56
+ - **Step 9.3: Attach Note:** Use the `git notes` command to attach the summary to the commit.
57
+ ```bash
58
+ # The note content from the previous step is passed via the -m flag.
59
+ git notes add -m "<note content>" <commit_hash>
60
+ ```
61
+
62
+ 10. **Get and Record Task Commit SHA:**
63
+ - **Step 10.1: Update Plan:** Read `plan.md`, find the line for the completed task, update its status from `[~]` to `[x]`, and append the first 7 characters of the *just-completed commit's* commit hash.
64
+ - **Step 10.2: Write Plan:** Write the updated content back to `plan.md`.
65
+
66
+ 11. **Commit Plan Update:**
67
+ - **Action:** Stage the modified `plan.md` file.
68
+ - **Action:** Commit this change with a descriptive message (e.g., `conductor(plan): Mark task 'Create user model' as complete`).
69
+
70
+ ### Phase Completion Verification and Checkpointing Protocol
71
+
72
+ **Trigger:** This protocol is executed immediately after a task is completed that also concludes a phase in `plan.md`.
73
+
74
+ 1. **Announce Protocol Start:** Inform the user that the phase is complete and the verification and checkpointing protocol has begun.
75
+
76
+ 2. **Ensure Test Coverage for Phase Changes:**
77
+ - **Step 2.1: Determine Phase Scope:** To identify the files changed in this phase, you must first find the starting point. Read `plan.md` to find the Git commit SHA of the *previous* phase's checkpoint. If no previous checkpoint exists, the scope is all changes since the first commit.
78
+ - **Step 2.2: List Changed Files:** Execute `git diff --name-only <previous_checkpoint_sha> HEAD` to get a precise list of all files modified during this phase.
79
+ - **Step 2.3: Verify and Create Tests:** For each file in the list:
80
+ - **CRITICAL:** First, check its extension. Exclude non-code files (e.g., `.json`, `.md`, `.yaml`).
81
+ - For each remaining code file, verify a corresponding test file exists.
82
+ - If a test file is missing, you **must** create one. Before writing the test, **first, analyze other test files in the repository to determine the correct naming convention and testing style.** The new tests **must** validate the functionality described in this phase's tasks (`plan.md`).
83
+
84
+ 3. **Execute Automated Tests with Proactive Debugging:**
85
+ - Before execution, you **must** announce the exact shell command you will use to run the tests.
86
+ - **Example Announcement:** "I will now run the automated test suite to verify the phase. **Command:** `CI=true npm test`"
87
+ - Execute the announced command.
88
+ - If tests fail, you **must** inform the user and begin debugging. You may attempt to propose a fix a **maximum of two times**. If the tests still fail after your second proposed fix, you **must stop**, report the persistent failure, and ask the user for guidance.
89
+
90
+ 4. **Propose a Detailed, Actionable Manual Verification Plan:**
91
+ - **CRITICAL:** To generate the plan, first analyze `product.md`, `product-guidelines.md`, and `plan.md` to determine the user-facing goals of the completed phase.
92
+ - You **must** generate a step-by-step plan that walks the user through the verification process, including any necessary commands and specific, expected outcomes.
93
+ - The plan you present to the user **must** follow this format:
94
+
95
+ **For a Frontend Change:**
96
+ ```
97
+ The automated tests have passed. For manual verification, please follow these steps:
98
+
99
+ **Manual Verification Steps:**
100
+ 1. **Start the development server with the command:** `npm run dev`
101
+ 2. **Open your browser to:** `http://localhost:3000`
102
+ 3. **Confirm that you see:** The new user profile page, with the user's name and email displayed correctly.
103
+ ```
104
+
105
+ **For a Backend Change:**
106
+ ```
107
+ The automated tests have passed. For manual verification, please follow these steps:
108
+
109
+ **Manual Verification Steps:**
110
+ 1. **Ensure the server is running.**
111
+ 2. **Execute the following command in your terminal:** `curl -X POST http://localhost:8080/api/v1/users -d '{"name": "test"}'`
112
+ 3. **Confirm that you receive:** A JSON response with a status of `201 Created`.
113
+ ```
114
+
115
+ 5. **Await Explicit User Feedback:**
116
+ - After presenting the detailed plan, ask the user for confirmation: "**Does this meet your expectations? Please confirm with yes or provide feedback on what needs to be changed.**"
117
+ - **PAUSE** and await the user's response. Do not proceed without an explicit yes or confirmation.
118
+
119
+ 6. **Create Checkpoint Commit:**
120
+ - Stage all changes. If no changes occurred in this step, proceed with an empty commit.
121
+ - Perform the commit with a clear and concise message (e.g., `conductor(checkpoint): Checkpoint end of Phase X`).
122
+
123
+ 7. **Attach Auditable Verification Report using Git Notes:**
124
+ - **Step 7.1: Draft Note Content:** Create a detailed verification report including the automated test command, the manual verification steps, and the user's confirmation.
125
+ - **Step 7.2: Attach Note:** Use the `git notes` command and the full commit hash from the previous step to attach the full report to the checkpoint commit.
126
+
127
+ 8. **Get and Record Phase Checkpoint SHA:**
128
+ - **Step 8.1: Get Commit Hash:** Obtain the hash of the *just-created checkpoint commit* (`git log -1 --format="%H"`).
129
+ - **Step 8.2: Update Plan:** Read `plan.md`, find the heading for the completed phase, and append the first 7 characters of the commit hash in the format `[checkpoint: <sha>]`.
130
+ - **Step 8.3: Write Plan:** Write the updated content back to `plan.md`.
131
+
132
+ 9. **Commit Plan Update:**
133
+ - **Action:** Stage the modified `plan.md` file.
134
+ - **Action:** Commit this change with a descriptive message following the format `conductor(plan): Mark phase '<PHASE NAME>' as complete`.
135
+
136
+ 10. **Announce Completion:** Inform the user that the phase is complete and the checkpoint has been created, with the detailed verification report attached as a git note.
137
+
138
+ ### Quality Gates
139
+
140
+ Before marking any task complete, verify:
141
+
142
+ - [ ] All tests pass
143
+ - [ ] Code coverage meets requirements (100%)
144
+ - [ ] Code follows project's code style guidelines (as defined in `code_styleguides/`)
145
+ - [ ] All public functions/methods are documented (e.g., docstrings, JSDoc, GoDoc)
146
+ - [ ] Type safety is enforced (e.g., type hints, TypeScript types, Go types)
147
+ - [ ] No linting or static analysis errors (using the project's configured tools)
148
+ - [ ] Works correctly on mobile (if applicable)
149
+ - [ ] Documentation updated if needed
150
+ - [ ] No security vulnerabilities introduced
151
+
152
+ ## Development Commands
153
+
154
+ **AI AGENT INSTRUCTION: This section should be adapted to the project's specific language, framework, and build tools.**
155
+
156
+ ### Setup
157
+ ```bash
158
+ # Example: Commands to set up the development environment (e.g., install dependencies, configure database)
159
+ # e.g., for a Node.js project: npm install
160
+ # e.g., for a Go project: go mod tidy
161
+ ```
162
+
163
+ ### Daily Development
164
+ ```bash
165
+ # Example: Commands for common daily tasks (e.g., start dev server, run tests, lint, format)
166
+ # e.g., for a Node.js project: npm run dev, npm test, npm run lint
167
+ # e.g., for a Go project: go run main.go, go test ./..., go fmt ./...
168
+ ```
169
+
170
+ ### Before Committing
171
+ ```bash
172
+ # Example: Commands to run all pre-commit checks (e.g., format, lint, type check, run tests)
173
+ # e.g., for a Node.js project: npm run check
174
+ # e.g., for a Go project: make check (if a Makefile exists)
175
+ ```
176
+
177
+ ## Testing Requirements
178
+
179
+ ### Unit Testing
180
+ - Every module must have corresponding tests.
181
+ - Use appropriate test setup/teardown mechanisms (e.g., fixtures, beforeEach/afterEach).
182
+ - Mock external dependencies.
183
+ - Test both success and failure cases.
184
+
185
+ ### Integration Testing
186
+ - Test complete user flows
187
+ - Verify database transactions
188
+ - Test authentication and authorization
189
+ - Check form submissions
190
+
191
+ ### Mobile Testing
192
+ - Test on actual iPhone when possible
193
+ - Use Safari developer tools
194
+ - Test touch interactions
195
+ - Verify responsive layouts
196
+ - Check performance on 3G/4G
197
+
198
+ ## Code Review Process
199
+
200
+ ### Self-Review Checklist
201
+ Before requesting review:
202
+
203
+ 1. **Functionality**
204
+ - Feature works as specified
205
+ - Edge cases handled
206
+ - Error messages are user-friendly
207
+
208
+ 2. **Code Quality**
209
+ - Follows style guide
210
+ - DRY principle applied
211
+ - Clear variable/function names
212
+ - Appropriate comments
213
+
214
+ 3. **Testing**
215
+ - Unit tests comprehensive
216
+ - Integration tests pass
217
+ - Coverage adequate (100%)
218
+
219
+ 4. **Security**
220
+ - No hardcoded secrets
221
+ - Input validation present
222
+ - SQL injection prevented
223
+ - XSS protection in place
224
+
225
+ 5. **Performance**
226
+ - Database queries optimized
227
+ - Images optimized
228
+ - Caching implemented where needed
229
+
230
+ 6. **Mobile Experience**
231
+ - Touch targets adequate (44x44px)
232
+ - Text readable without zooming
233
+ - Performance acceptable on mobile
234
+ - Interactions feel native
235
+
236
+ ## Commit Guidelines
237
+
238
+ ### Message Format
239
+ ```
240
+ <type>(<scope>): <description>
241
+
242
+ [optional body]
243
+
244
+ [optional footer]
245
+ ```
246
+
247
+ ### Types
248
+ - `feat`: New feature
249
+ - `fix`: Bug fix
250
+ - `docs`: Documentation only
251
+ - `style`: Formatting, missing semicolons, etc.
252
+ - `refactor`: Code change that neither fixes a bug nor adds a feature
253
+ - `test`: Adding missing tests
254
+ - `chore`: Maintenance tasks
255
+
256
+ ### Examples
257
+ ```bash
258
+ git commit -m "feat(auth): Add remember me functionality"
259
+ git commit -m "fix(posts): Correct excerpt generation for short posts"
260
+ git commit -m "test(comments): Add tests for emoji reaction limits"
261
+ git commit -m "style(mobile): Improve button touch targets"
262
+ ```
263
+
264
+ ## Definition of Done
265
+
266
+ A task is complete when:
267
+
268
+ 1. All code implemented to specification
269
+ 2. Unit tests written and passing
270
+ 3. Code coverage meets project requirements
271
+ 4. Documentation complete (if applicable)
272
+ 5. Code passes all configured linting and static analysis checks
273
+ 6. Works beautifully on mobile (if applicable)
274
+ 7. Implementation notes added to `plan.md`
275
+ 8. Changes committed with proper message
276
+ 9. Git note with task summary attached to the commit
277
+
278
+ ## Emergency Procedures
279
+
280
+ ### Critical Bug in Production
281
+ 1. Create hotfix branch from main
282
+ 2. Write failing test for bug
283
+ 3. Implement minimal fix
284
+ 4. Test thoroughly including mobile
285
+ 5. Deploy immediately
286
+ 6. Document in plan.md
287
+
288
+ ### Data Loss
289
+ 1. Stop all write operations
290
+ 2. Restore from latest backup
291
+ 3. Verify data integrity
292
+ 4. Document incident
293
+ 5. Update backup procedures
294
+
295
+ ### Security Breach
296
+ 1. Rotate all secrets immediately
297
+ 2. Review access logs
298
+ 3. Patch vulnerability
299
+ 4. Notify affected users (if any)
300
+ 5. Document and update security procedures
301
+
302
+ ## Deployment Workflow
303
+
304
+ ### Pre-Deployment Checklist
305
+ - [ ] All tests passing
306
+ - [ ] Coverage 100%
307
+ - [ ] No linting errors
308
+ - [ ] Mobile testing complete
309
+ - [ ] Environment variables configured
310
+ - [ ] Database migrations ready
311
+ - [ ] Backup created
312
+
313
+ ### Deployment Steps
314
+ 1. Merge feature branch to main
315
+ 2. Tag release with version
316
+ 3. Push to deployment service
317
+ 4. Run database migrations
318
+ 5. Verify deployment
319
+ 6. Test critical paths
320
+ 7. Monitor for errors
321
+
322
+ ### Post-Deployment
323
+ 1. Monitor analytics
324
+ 2. Check error logs
325
+ 3. Gather user feedback
326
+ 4. Plan next iteration
327
+
328
+ ## Continuous Improvement
329
+
330
+ - Review workflow weekly
331
+ - Update based on pain points
332
+ - Document lessons learned
333
+ - Optimize for user happiness
334
+ - Keep things simple and maintainable
package/dist/EventBus.js CHANGED
@@ -37,28 +37,28 @@ export class EventBus {
37
37
  const listeners = this.listeners[event];
38
38
  if (listeners) {
39
39
  for (const listener of listeners) {
40
- // We use Promise.resolve().then() to schedule the listener on the microtask queue,
40
+ // We use queueMicrotask() to schedule the listener on the microtask queue,
41
41
  // ensuring the emit method remains non-blocking.
42
- // The final .catch() ensures that any errors in the promise infrastructure itself are logged.
43
- Promise.resolve()
44
- .then(() => {
42
+ queueMicrotask(() => {
45
43
  try {
46
- const result = listener(data);
47
- if (result instanceof Promise) {
48
- // Handle async listener rejections
49
- result.catch((error) => {
50
- console.error(`Error in event listener for ${String(event)}:`, error);
51
- });
44
+ try {
45
+ const result = listener(data);
46
+ if (result instanceof Promise) {
47
+ // Handle async listener rejections
48
+ result.catch((error) => {
49
+ console.error(`Error in event listener for ${String(event)}:`, error);
50
+ });
51
+ }
52
+ }
53
+ catch (error) {
54
+ // Handle sync listener errors
55
+ console.error(`Error in event listener for ${String(event)}:`, error);
52
56
  }
53
57
  }
54
58
  catch (error) {
55
- // Handle sync listener errors
56
- console.error(`Error in event listener for ${String(event)}:`, error);
59
+ // detailed handling for the microtask execution itself
60
+ console.error(`Unexpected error in event bus execution for ${String(event)}:`, error);
57
61
  }
58
- })
59
- .catch((error) => {
60
- // detailed handling for the promise chain itself
61
- console.error(`Unexpected error in event bus execution for ${String(event)}:`, error);
62
62
  });
63
63
  }
64
64
  }
@@ -1 +1 @@
1
- {"version":3,"file":"EventBus.js","sourceRoot":"","sources":["../src/EventBus.ts"],"names":[],"mappings":"AAMA;;;GAGG;AACH,MAAM,OAAO,QAAQ;IACX,SAAS,GAA0B,EAAE,CAAC;IAE9C;;;;OAIG;IACI,EAAE,CACP,KAAQ,EACR,QAA0C;QAE1C,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,4EAA4E;YAC5E,iEAAiE;YACjE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,GAAG,EAAyC,CAAC;QAC3E,CAAC;QACD,oFAAoF;QACnF,IAAI,CAAC,SAAS,CAAC,KAAK,CAA2C,CAAC,GAAG,CAClE,QAAQ,CACT,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACI,GAAG,CACR,KAAQ,EACR,QAA0C;QAE1C,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,SAAS,CAAC,KAAK,CAA2C,CAAC,MAAM,CACrE,QAAQ,CACT,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;;;OAIG;IACI,IAAI,CACT,KAAQ,EACR,IAAsC;QAEtC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAEzB,CAAC;QACd,IAAI,SAAS,EAAE,CAAC;YACd,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;gBACjC,mFAAmF;gBACnF,iDAAiD;gBACjD,8FAA8F;gBAC9F,OAAO,CAAC,OAAO,EAAE;qBACd,IAAI,CAAC,GAAG,EAAE;oBACT,IAAI,CAAC;wBACH,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;wBAC9B,IAAI,MAAM,YAAY,OAAO,EAAE,CAAC;4BAC9B,mCAAmC;4BACnC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;gCACrB,OAAO,CAAC,KAAK,CACX,+BAA+B,MAAM,CAAC,KAAK,CAAC,GAAG,EAC/C,KAAK,CACN,CAAC;4BACJ,CAAC,CAAC,CAAC;wBACL,CAAC;oBACH,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBACf,8BAA8B;wBAC9B,OAAO,CAAC,KAAK,CACX,+BAA+B,MAAM,CAAC,KAAK,CAAC,GAAG,EAC/C,KAAK,CACN,CAAC;oBACJ,CAAC;gBACH,CAAC,CAAC;qBACD,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;oBACf,iDAAiD;oBACjD,OAAO,CAAC,KAAK,CACX,+CAA+C,MAAM,CAAC,KAAK,CAAC,GAAG,EAC/D,KAAK,CACN,CAAC;gBACJ,CAAC,CAAC,CAAC;YACP,CAAC;QACH,CAAC;IACH,CAAC;CACF"}
1
+ {"version":3,"file":"EventBus.js","sourceRoot":"","sources":["../src/EventBus.ts"],"names":[],"mappings":"AAMA;;;GAGG;AACH,MAAM,OAAO,QAAQ;IACX,SAAS,GAA0B,EAAE,CAAC;IAE9C;;;;OAIG;IACI,EAAE,CACP,KAAQ,EACR,QAA0C;QAE1C,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,4EAA4E;YAC5E,iEAAiE;YACjE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,GAAG,EAAyC,CAAC;QAC3E,CAAC;QACD,oFAAoF;QACnF,IAAI,CAAC,SAAS,CAAC,KAAK,CAA2C,CAAC,GAAG,CAClE,QAAQ,CACT,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACI,GAAG,CACR,KAAQ,EACR,QAA0C;QAE1C,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,SAAS,CAAC,KAAK,CAA2C,CAAC,MAAM,CACrE,QAAQ,CACT,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;;;OAIG;IACI,IAAI,CACT,KAAQ,EACR,IAAsC;QAEtC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAEzB,CAAC;QACd,IAAI,SAAS,EAAE,CAAC;YACd,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;gBACjC,2EAA2E;gBAC3E,iDAAiD;gBACjD,cAAc,CAAC,GAAG,EAAE;oBAClB,IAAI,CAAC;wBACH,IAAI,CAAC;4BACH,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;4BAC9B,IAAI,MAAM,YAAY,OAAO,EAAE,CAAC;gCAC9B,mCAAmC;gCACnC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;oCACrB,OAAO,CAAC,KAAK,CACX,+BAA+B,MAAM,CAAC,KAAK,CAAC,GAAG,EAC/C,KAAK,CACN,CAAC;gCACJ,CAAC,CAAC,CAAC;4BACL,CAAC;wBACH,CAAC;wBAAC,OAAO,KAAK,EAAE,CAAC;4BACf,8BAA8B;4BAC9B,OAAO,CAAC,KAAK,CACX,+BAA+B,MAAM,CAAC,KAAK,CAAC,GAAG,EAC/C,KAAK,CACN,CAAC;wBACJ,CAAC;oBACH,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBACf,uDAAuD;wBACvD,OAAO,CAAC,KAAK,CACX,+CAA+C,MAAM,CAAC,KAAK,CAAC,GAAG,EAC/D,KAAK,CACN,CAAC;oBACJ,CAAC;gBACH,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,22 @@
1
+ import { Plugin, PluginContext } from "./contracts/Plugin.js";
2
+ /**
3
+ * Manages the lifecycle of plugins.
4
+ */
5
+ export declare class PluginManager<TContext> {
6
+ private context;
7
+ private plugins;
8
+ constructor(context: PluginContext<TContext>);
9
+ /**
10
+ * Registers a plugin.
11
+ * @param plugin The plugin to register.
12
+ */
13
+ use(plugin: Plugin<TContext>): void;
14
+ /**
15
+ * Initializes all registered plugins.
16
+ */
17
+ initialize(): Promise<void>;
18
+ /**
19
+ * Returns the list of registered plugins.
20
+ */
21
+ getPlugins(): ReadonlyArray<Plugin<TContext>>;
22
+ }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Manages the lifecycle of plugins.
3
+ */
4
+ export class PluginManager {
5
+ context;
6
+ plugins = [];
7
+ constructor(context) {
8
+ this.context = context;
9
+ }
10
+ /**
11
+ * Registers a plugin.
12
+ * @param plugin The plugin to register.
13
+ */
14
+ use(plugin) {
15
+ // Check if plugin is already registered
16
+ if (this.plugins.some((p) => p.name === plugin.name)) {
17
+ // For now, we allow overwriting or just warn?
18
+ // Let's just allow it but maybe log it if we had a logger.
19
+ // Strict check: don't allow duplicate names.
20
+ throw new Error(`Plugin with name '${plugin.name}' is already registered.`);
21
+ }
22
+ this.plugins.push(plugin);
23
+ }
24
+ /**
25
+ * Initializes all registered plugins.
26
+ */
27
+ async initialize() {
28
+ for (const plugin of this.plugins) {
29
+ await plugin.install(this.context);
30
+ }
31
+ }
32
+ /**
33
+ * Returns the list of registered plugins.
34
+ */
35
+ getPlugins() {
36
+ return this.plugins;
37
+ }
38
+ }
39
+ //# sourceMappingURL=PluginManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PluginManager.js","sourceRoot":"","sources":["../src/PluginManager.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,OAAO,aAAa;IAGJ;IAFZ,OAAO,GAAuB,EAAE,CAAC;IAEzC,YAAoB,OAAgC;QAAhC,YAAO,GAAP,OAAO,CAAyB;IAAG,CAAC;IAExD;;;OAGG;IACI,GAAG,CAAC,MAAwB;QACjC,wCAAwC;QACxC,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;YACrD,8CAA8C;YAC9C,2DAA2D;YAC3D,6CAA6C;YAC7C,MAAM,IAAI,KAAK,CAAC,qBAAqB,MAAM,CAAC,IAAI,0BAA0B,CAAC,CAAC;QAC9E,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5B,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,UAAU;QACrB,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAClC,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAED;;OAEG;IACI,UAAU;QACf,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;CACF"}
@@ -19,7 +19,7 @@ export declare class TaskGraphValidator implements ITaskGraphValidator {
19
19
  * @returns A formatted error string.
20
20
  */
21
21
  createErrorMessage(result: ValidationResult): string;
22
- private checkDuplicateTasks;
22
+ private buildTaskMapAndCheckDuplicates;
23
23
  private checkMissingDependencies;
24
24
  private checkCycles;
25
25
  private detectCycle;
@@ -12,15 +12,15 @@ export class TaskGraphValidator {
12
12
  */
13
13
  validate(taskGraph) {
14
14
  const errors = [];
15
- // 1. Check for duplicate tasks
16
- const taskIds = this.checkDuplicateTasks(taskGraph, errors);
15
+ // 1. Build Map and Check Duplicates (Single Pass)
16
+ const taskMap = this.buildTaskMapAndCheckDuplicates(taskGraph, errors);
17
17
  // 2. Check for missing dependencies
18
- this.checkMissingDependencies(taskGraph, taskIds, errors);
18
+ this.checkMissingDependencies(taskGraph, taskMap, errors);
19
19
  // 3. Check for cycles
20
20
  // Only run cycle detection if there are no missing dependencies, otherwise we might chase non-existent nodes.
21
21
  const hasMissingDependencies = errors.some((e) => e.type === ERROR_MISSING_DEPENDENCY);
22
22
  if (!hasMissingDependencies) {
23
- this.checkCycles(taskGraph, errors);
23
+ this.checkCycles(taskGraph, taskMap, errors);
24
24
  }
25
25
  return {
26
26
  isValid: errors.length === 0,
@@ -36,10 +36,10 @@ export class TaskGraphValidator {
36
36
  const errorDetails = result.errors.map((e) => e.message);
37
37
  return `Task graph validation failed: ${errorDetails.join("; ")}`;
38
38
  }
39
- checkDuplicateTasks(taskGraph, errors) {
40
- const taskIds = new Set();
39
+ buildTaskMapAndCheckDuplicates(taskGraph, errors) {
40
+ const taskMap = new Map();
41
41
  for (const task of taskGraph.tasks) {
42
- if (taskIds.has(task.id)) {
42
+ if (taskMap.has(task.id)) {
43
43
  errors.push({
44
44
  type: ERROR_DUPLICATE_TASK,
45
45
  message: `Duplicate task detected with ID: ${task.id}`,
@@ -47,15 +47,15 @@ export class TaskGraphValidator {
47
47
  });
48
48
  }
49
49
  else {
50
- taskIds.add(task.id);
50
+ taskMap.set(task.id, task);
51
51
  }
52
52
  }
53
- return taskIds;
53
+ return taskMap;
54
54
  }
55
- checkMissingDependencies(taskGraph, taskIds, errors) {
55
+ checkMissingDependencies(taskGraph, taskMap, errors) {
56
56
  for (const task of taskGraph.tasks) {
57
57
  for (const dependenceId of task.dependencies) {
58
- if (!taskIds.has(dependenceId)) {
58
+ if (!taskMap.has(dependenceId)) {
59
59
  errors.push({
60
60
  type: ERROR_MISSING_DEPENDENCY,
61
61
  message: `Task '${task.id}' depends on missing task '${dependenceId}'`,
@@ -65,12 +65,7 @@ export class TaskGraphValidator {
65
65
  }
66
66
  }
67
67
  }
68
- checkCycles(taskGraph, errors) {
69
- // Build adjacency list
70
- const adjacencyList = new Map();
71
- for (const task of taskGraph.tasks) {
72
- adjacencyList.set(task.id, task.dependencies);
73
- }
68
+ checkCycles(taskGraph, taskMap, errors) {
74
69
  const visited = new Set();
75
70
  const recursionStack = new Set();
76
71
  for (const task of taskGraph.tasks) {
@@ -78,7 +73,7 @@ export class TaskGraphValidator {
78
73
  continue;
79
74
  }
80
75
  const path = [];
81
- if (this.detectCycle(task.id, path, visited, recursionStack, adjacencyList)) {
76
+ if (this.detectCycle(task.id, path, visited, recursionStack, taskMap)) {
82
77
  // Extract the actual cycle from the path
83
78
  // The path might look like A -> B -> C -> B (if we started at A and found cycle B-C-B)
84
79
  const cycleStart = path[path.length - 1];
@@ -94,7 +89,7 @@ export class TaskGraphValidator {
94
89
  }
95
90
  }
96
91
  }
97
- detectCycle(startTaskId, path, visited, recursionStack, adjacencyList) {
92
+ detectCycle(startTaskId, path, visited, recursionStack, taskMap) {
98
93
  // Use an explicit stack to avoid maximum call stack size exceeded errors
99
94
  const stack = [];
100
95
  visited.add(startTaskId);
@@ -103,7 +98,7 @@ export class TaskGraphValidator {
103
98
  stack.push({
104
99
  taskId: startTaskId,
105
100
  index: 0,
106
- dependencies: adjacencyList.get(startTaskId),
101
+ dependencies: taskMap.get(startTaskId).dependencies,
107
102
  });
108
103
  while (stack.length > 0) {
109
104
  const frame = stack[stack.length - 1];
@@ -123,7 +118,7 @@ export class TaskGraphValidator {
123
118
  stack.push({
124
119
  taskId: dependenceId,
125
120
  index: 0,
126
- dependencies: adjacencyList.get(dependenceId),
121
+ dependencies: taskMap.get(dependenceId).dependencies,
127
122
  });
128
123
  }
129
124
  }
@@ -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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"}
@@ -11,4 +11,13 @@ export interface TaskResult {
11
11
  error?: string;
12
12
  /** Optional data produced by the step for later inspection. */
13
13
  data?: unknown;
14
+ /** Optional execution metrics for the task. */
15
+ metrics?: {
16
+ /** Start time in milliseconds (performance.now). */
17
+ startTime: number;
18
+ /** End time in milliseconds (performance.now). */
19
+ endTime: number;
20
+ /** Duration in milliseconds. */
21
+ duration: number;
22
+ };
14
23
  }
@@ -3,7 +3,7 @@ import { TaskResult } from "./TaskResult.js";
3
3
  import { RunnerEventPayloads, RunnerEventListener } from "./contracts/RunnerEvents.js";
4
4
  import { TaskRunnerExecutionConfig } from "./TaskRunnerExecutionConfig.js";
5
5
  import { IExecutionStrategy } from "./strategies/IExecutionStrategy.js";
6
- export { RunnerEventPayloads, RunnerEventListener, TaskRunnerExecutionConfig };
6
+ import { Plugin } from "./contracts/Plugin.js";
7
7
  /**
8
8
  * The main class that orchestrates the execution of a list of tasks
9
9
  * based on their dependencies, with support for parallel execution.
@@ -14,6 +14,7 @@ export declare class TaskRunner<TContext> {
14
14
  private eventBus;
15
15
  private validator;
16
16
  private executionStrategy;
17
+ private pluginManager;
17
18
  /**
18
19
  * @param context The shared context object to be passed to each task.
19
20
  */
@@ -30,6 +31,12 @@ export declare class TaskRunner<TContext> {
30
31
  * @param callback The callback to remove.
31
32
  */
32
33
  off<K extends keyof RunnerEventPayloads<TContext>>(event: K, callback: RunnerEventListener<TContext, K>): void;
34
+ /**
35
+ * Registers a plugin.
36
+ * @param plugin The plugin to register.
37
+ * @returns The TaskRunner instance for chaining.
38
+ */
39
+ use(plugin: Plugin<TContext>): this;
33
40
  /**
34
41
  * Sets the execution strategy to be used.
35
42
  * @param strategy The execution strategy.