@herdctl/core 0.0.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.
- package/.turbo/turbo-build.log +4 -0
- package/.turbo/turbo-test.log +219 -0
- package/.turbo/turbo-typecheck.log +4 -0
- package/coverage/base.css +224 -0
- package/coverage/block-navigation.js +87 -0
- package/coverage/coverage-final.json +51 -0
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +251 -0
- package/coverage/prettify.css +1 -0
- package/coverage/prettify.js +2 -0
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +210 -0
- package/coverage/src/config/index.html +191 -0
- package/coverage/src/config/index.ts.html +442 -0
- package/coverage/src/config/interpolate.ts.html +652 -0
- package/coverage/src/config/loader.ts.html +1501 -0
- package/coverage/src/config/merge.ts.html +823 -0
- package/coverage/src/config/parser.ts.html +1213 -0
- package/coverage/src/config/schema.ts.html +1123 -0
- package/coverage/src/fleet-manager/errors.ts.html +2326 -0
- package/coverage/src/fleet-manager/event-types.ts.html +1219 -0
- package/coverage/src/fleet-manager/fleet-manager.ts.html +7030 -0
- package/coverage/src/fleet-manager/index.html +206 -0
- package/coverage/src/fleet-manager/index.ts.html +469 -0
- package/coverage/src/fleet-manager/job-manager.ts.html +2074 -0
- package/coverage/src/fleet-manager/job-queue.ts.html +2479 -0
- package/coverage/src/fleet-manager/types.ts.html +2602 -0
- package/coverage/src/index.html +116 -0
- package/coverage/src/index.ts.html +181 -0
- package/coverage/src/runner/errors.ts.html +1006 -0
- package/coverage/src/runner/index.html +191 -0
- package/coverage/src/runner/index.ts.html +256 -0
- package/coverage/src/runner/job-executor.ts.html +1429 -0
- package/coverage/src/runner/message-processor.ts.html +1150 -0
- package/coverage/src/runner/sdk-adapter.ts.html +658 -0
- package/coverage/src/runner/types.ts.html +559 -0
- package/coverage/src/scheduler/errors.ts.html +388 -0
- package/coverage/src/scheduler/index.html +206 -0
- package/coverage/src/scheduler/index.ts.html +244 -0
- package/coverage/src/scheduler/interval.ts.html +652 -0
- package/coverage/src/scheduler/schedule-runner.ts.html +1411 -0
- package/coverage/src/scheduler/schedule-state.ts.html +718 -0
- package/coverage/src/scheduler/scheduler.ts.html +1795 -0
- package/coverage/src/scheduler/types.ts.html +733 -0
- package/coverage/src/state/directory.ts.html +736 -0
- package/coverage/src/state/errors.ts.html +376 -0
- package/coverage/src/state/fleet-state.ts.html +937 -0
- package/coverage/src/state/index.html +221 -0
- package/coverage/src/state/index.ts.html +322 -0
- package/coverage/src/state/job-metadata.ts.html +1420 -0
- package/coverage/src/state/job-output.ts.html +1033 -0
- package/coverage/src/state/schemas/fleet-state.ts.html +445 -0
- package/coverage/src/state/schemas/index.html +176 -0
- package/coverage/src/state/schemas/index.ts.html +286 -0
- package/coverage/src/state/schemas/job-metadata.ts.html +628 -0
- package/coverage/src/state/schemas/job-output.ts.html +616 -0
- package/coverage/src/state/schemas/session-info.ts.html +361 -0
- package/coverage/src/state/session.ts.html +844 -0
- package/coverage/src/state/types.ts.html +262 -0
- package/coverage/src/state/utils/atomic.ts.html +748 -0
- package/coverage/src/state/utils/index.html +146 -0
- package/coverage/src/state/utils/index.ts.html +103 -0
- package/coverage/src/state/utils/reads.ts.html +1621 -0
- package/coverage/src/work-sources/adapters/github.ts.html +3583 -0
- package/coverage/src/work-sources/adapters/index.html +131 -0
- package/coverage/src/work-sources/adapters/index.ts.html +277 -0
- package/coverage/src/work-sources/errors.ts.html +298 -0
- package/coverage/src/work-sources/index.html +176 -0
- package/coverage/src/work-sources/index.ts.html +529 -0
- package/coverage/src/work-sources/manager.ts.html +1324 -0
- package/coverage/src/work-sources/registry.ts.html +619 -0
- package/coverage/src/work-sources/types.ts.html +568 -0
- package/dist/config/__tests__/agent.test.d.ts +2 -0
- package/dist/config/__tests__/agent.test.d.ts.map +1 -0
- package/dist/config/__tests__/agent.test.js +752 -0
- package/dist/config/__tests__/agent.test.js.map +1 -0
- package/dist/config/__tests__/interpolate.test.d.ts +2 -0
- package/dist/config/__tests__/interpolate.test.d.ts.map +1 -0
- package/dist/config/__tests__/interpolate.test.js +509 -0
- package/dist/config/__tests__/interpolate.test.js.map +1 -0
- package/dist/config/__tests__/loader.test.d.ts +2 -0
- package/dist/config/__tests__/loader.test.d.ts.map +1 -0
- package/dist/config/__tests__/loader.test.js +631 -0
- package/dist/config/__tests__/loader.test.js.map +1 -0
- package/dist/config/__tests__/merge.test.d.ts +2 -0
- package/dist/config/__tests__/merge.test.d.ts.map +1 -0
- package/dist/config/__tests__/merge.test.js +672 -0
- package/dist/config/__tests__/merge.test.js.map +1 -0
- package/dist/config/__tests__/parser.test.d.ts +2 -0
- package/dist/config/__tests__/parser.test.d.ts.map +1 -0
- package/dist/config/__tests__/parser.test.js +476 -0
- package/dist/config/__tests__/parser.test.js.map +1 -0
- package/dist/config/__tests__/schema.test.d.ts +2 -0
- package/dist/config/__tests__/schema.test.d.ts.map +1 -0
- package/dist/config/__tests__/schema.test.js +776 -0
- package/dist/config/__tests__/schema.test.js.map +1 -0
- package/dist/config/index.d.ts +11 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +26 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/interpolate.d.ts +76 -0
- package/dist/config/interpolate.d.ts.map +1 -0
- package/dist/config/interpolate.js +143 -0
- package/dist/config/interpolate.js.map +1 -0
- package/dist/config/loader.d.ts +147 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +336 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/merge.d.ts +84 -0
- package/dist/config/merge.d.ts.map +1 -0
- package/dist/config/merge.js +138 -0
- package/dist/config/merge.js.map +1 -0
- package/dist/config/parser.d.ts +143 -0
- package/dist/config/parser.d.ts.map +1 -0
- package/dist/config/parser.js +316 -0
- package/dist/config/parser.js.map +1 -0
- package/dist/config/schema.d.ts +1906 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +268 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/fleet-manager/__tests__/coverage.test.d.ts +13 -0
- package/dist/fleet-manager/__tests__/coverage.test.d.ts.map +1 -0
- package/dist/fleet-manager/__tests__/coverage.test.js +2282 -0
- package/dist/fleet-manager/__tests__/coverage.test.js.map +1 -0
- package/dist/fleet-manager/__tests__/errors.test.d.ts +7 -0
- package/dist/fleet-manager/__tests__/errors.test.d.ts.map +1 -0
- package/dist/fleet-manager/__tests__/errors.test.js +557 -0
- package/dist/fleet-manager/__tests__/errors.test.js.map +1 -0
- package/dist/fleet-manager/__tests__/event-helpers.test.d.ts +7 -0
- package/dist/fleet-manager/__tests__/event-helpers.test.d.ts.map +1 -0
- package/dist/fleet-manager/__tests__/event-helpers.test.js +368 -0
- package/dist/fleet-manager/__tests__/event-helpers.test.js.map +1 -0
- package/dist/fleet-manager/__tests__/integration.test.d.ts +11 -0
- package/dist/fleet-manager/__tests__/integration.test.d.ts.map +1 -0
- package/dist/fleet-manager/__tests__/integration.test.js +949 -0
- package/dist/fleet-manager/__tests__/integration.test.js.map +1 -0
- package/dist/fleet-manager/__tests__/job-control.test.d.ts +7 -0
- package/dist/fleet-manager/__tests__/job-control.test.d.ts.map +1 -0
- package/dist/fleet-manager/__tests__/job-control.test.js +215 -0
- package/dist/fleet-manager/__tests__/job-control.test.js.map +1 -0
- package/dist/fleet-manager/__tests__/job-manager.test.d.ts +7 -0
- package/dist/fleet-manager/__tests__/job-manager.test.d.ts.map +1 -0
- package/dist/fleet-manager/__tests__/job-manager.test.js +659 -0
- package/dist/fleet-manager/__tests__/job-manager.test.js.map +1 -0
- package/dist/fleet-manager/__tests__/job-queue.test.d.ts +5 -0
- package/dist/fleet-manager/__tests__/job-queue.test.d.ts.map +1 -0
- package/dist/fleet-manager/__tests__/job-queue.test.js +315 -0
- package/dist/fleet-manager/__tests__/job-queue.test.js.map +1 -0
- package/dist/fleet-manager/__tests__/reload.test.d.ts +7 -0
- package/dist/fleet-manager/__tests__/reload.test.d.ts.map +1 -0
- package/dist/fleet-manager/__tests__/reload.test.js +609 -0
- package/dist/fleet-manager/__tests__/reload.test.js.map +1 -0
- package/dist/fleet-manager/__tests__/status-queries.test.d.ts +7 -0
- package/dist/fleet-manager/__tests__/status-queries.test.d.ts.map +1 -0
- package/dist/fleet-manager/__tests__/status-queries.test.js +488 -0
- package/dist/fleet-manager/__tests__/status-queries.test.js.map +1 -0
- package/dist/fleet-manager/__tests__/trigger.test.d.ts +7 -0
- package/dist/fleet-manager/__tests__/trigger.test.d.ts.map +1 -0
- package/dist/fleet-manager/__tests__/trigger.test.js +471 -0
- package/dist/fleet-manager/__tests__/trigger.test.js.map +1 -0
- package/dist/fleet-manager/errors.d.ts +407 -0
- package/dist/fleet-manager/errors.d.ts.map +1 -0
- package/dist/fleet-manager/errors.js +569 -0
- package/dist/fleet-manager/errors.js.map +1 -0
- package/dist/fleet-manager/event-types.d.ts +302 -0
- package/dist/fleet-manager/event-types.d.ts.map +1 -0
- package/dist/fleet-manager/event-types.js +9 -0
- package/dist/fleet-manager/event-types.js.map +1 -0
- package/dist/fleet-manager/fleet-manager.d.ts +699 -0
- package/dist/fleet-manager/fleet-manager.d.ts.map +1 -0
- package/dist/fleet-manager/fleet-manager.js +1906 -0
- package/dist/fleet-manager/fleet-manager.js.map +1 -0
- package/dist/fleet-manager/index.d.ts +17 -0
- package/dist/fleet-manager/index.d.ts.map +1 -0
- package/dist/fleet-manager/index.js +29 -0
- package/dist/fleet-manager/index.js.map +1 -0
- package/dist/fleet-manager/job-manager.d.ts +271 -0
- package/dist/fleet-manager/job-manager.d.ts.map +1 -0
- package/dist/fleet-manager/job-manager.js +443 -0
- package/dist/fleet-manager/job-manager.js.map +1 -0
- package/dist/fleet-manager/job-queue.d.ts +422 -0
- package/dist/fleet-manager/job-queue.d.ts.map +1 -0
- package/dist/fleet-manager/job-queue.js +448 -0
- package/dist/fleet-manager/job-queue.js.map +1 -0
- package/dist/fleet-manager/types.d.ts +680 -0
- package/dist/fleet-manager/types.d.ts.map +1 -0
- package/dist/fleet-manager/types.js +8 -0
- package/dist/fleet-manager/types.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/runner/__tests__/errors.test.d.ts +2 -0
- package/dist/runner/__tests__/errors.test.d.ts.map +1 -0
- package/dist/runner/__tests__/errors.test.js +264 -0
- package/dist/runner/__tests__/errors.test.js.map +1 -0
- package/dist/runner/__tests__/job-executor.test.d.ts +2 -0
- package/dist/runner/__tests__/job-executor.test.d.ts.map +1 -0
- package/dist/runner/__tests__/job-executor.test.js +1345 -0
- package/dist/runner/__tests__/job-executor.test.js.map +1 -0
- package/dist/runner/__tests__/message-processor.test.d.ts +2 -0
- package/dist/runner/__tests__/message-processor.test.d.ts.map +1 -0
- package/dist/runner/__tests__/message-processor.test.js +768 -0
- package/dist/runner/__tests__/message-processor.test.js.map +1 -0
- package/dist/runner/__tests__/sdk-adapter.test.d.ts +2 -0
- package/dist/runner/__tests__/sdk-adapter.test.d.ts.map +1 -0
- package/dist/runner/__tests__/sdk-adapter.test.js +554 -0
- package/dist/runner/__tests__/sdk-adapter.test.js.map +1 -0
- package/dist/runner/errors.d.ts +121 -0
- package/dist/runner/errors.d.ts.map +1 -0
- package/dist/runner/errors.js +212 -0
- package/dist/runner/errors.js.map +1 -0
- package/dist/runner/index.d.ts +12 -0
- package/dist/runner/index.d.ts.map +1 -0
- package/dist/runner/index.js +15 -0
- package/dist/runner/index.js.map +1 -0
- package/dist/runner/job-executor.d.ts +98 -0
- package/dist/runner/job-executor.d.ts.map +1 -0
- package/dist/runner/job-executor.js +333 -0
- package/dist/runner/job-executor.js.map +1 -0
- package/dist/runner/message-processor.d.ts +45 -0
- package/dist/runner/message-processor.d.ts.map +1 -0
- package/dist/runner/message-processor.js +294 -0
- package/dist/runner/message-processor.js.map +1 -0
- package/dist/runner/sdk-adapter.d.ts +60 -0
- package/dist/runner/sdk-adapter.d.ts.map +1 -0
- package/dist/runner/sdk-adapter.js +138 -0
- package/dist/runner/sdk-adapter.js.map +1 -0
- package/dist/runner/types.d.ts +135 -0
- package/dist/runner/types.d.ts.map +1 -0
- package/dist/runner/types.js +7 -0
- package/dist/runner/types.js.map +1 -0
- package/dist/scheduler/__tests__/errors.test.d.ts +2 -0
- package/dist/scheduler/__tests__/errors.test.d.ts.map +1 -0
- package/dist/scheduler/__tests__/errors.test.js +101 -0
- package/dist/scheduler/__tests__/errors.test.js.map +1 -0
- package/dist/scheduler/__tests__/interval.test.d.ts +2 -0
- package/dist/scheduler/__tests__/interval.test.d.ts.map +1 -0
- package/dist/scheduler/__tests__/interval.test.js +419 -0
- package/dist/scheduler/__tests__/interval.test.js.map +1 -0
- package/dist/scheduler/__tests__/schedule-runner.test.d.ts +2 -0
- package/dist/scheduler/__tests__/schedule-runner.test.d.ts.map +1 -0
- package/dist/scheduler/__tests__/schedule-runner.test.js +634 -0
- package/dist/scheduler/__tests__/schedule-runner.test.js.map +1 -0
- package/dist/scheduler/__tests__/schedule-state.test.d.ts +2 -0
- package/dist/scheduler/__tests__/schedule-state.test.d.ts.map +1 -0
- package/dist/scheduler/__tests__/schedule-state.test.js +572 -0
- package/dist/scheduler/__tests__/schedule-state.test.js.map +1 -0
- package/dist/scheduler/__tests__/scheduler.test.d.ts +2 -0
- package/dist/scheduler/__tests__/scheduler.test.d.ts.map +1 -0
- package/dist/scheduler/__tests__/scheduler.test.js +987 -0
- package/dist/scheduler/__tests__/scheduler.test.js.map +1 -0
- package/dist/scheduler/errors.d.ts +61 -0
- package/dist/scheduler/errors.d.ts.map +1 -0
- package/dist/scheduler/errors.js +81 -0
- package/dist/scheduler/errors.js.map +1 -0
- package/dist/scheduler/index.d.ts +13 -0
- package/dist/scheduler/index.d.ts.map +1 -0
- package/dist/scheduler/index.js +17 -0
- package/dist/scheduler/index.js.map +1 -0
- package/dist/scheduler/interval.d.ts +64 -0
- package/dist/scheduler/interval.d.ts.map +1 -0
- package/dist/scheduler/interval.js +139 -0
- package/dist/scheduler/interval.js.map +1 -0
- package/dist/scheduler/schedule-runner.d.ts +149 -0
- package/dist/scheduler/schedule-runner.d.ts.map +1 -0
- package/dist/scheduler/schedule-runner.js +277 -0
- package/dist/scheduler/schedule-runner.js.map +1 -0
- package/dist/scheduler/schedule-state.d.ts +105 -0
- package/dist/scheduler/schedule-state.d.ts.map +1 -0
- package/dist/scheduler/schedule-state.js +151 -0
- package/dist/scheduler/schedule-state.js.map +1 -0
- package/dist/scheduler/scheduler.d.ts +138 -0
- package/dist/scheduler/scheduler.d.ts.map +1 -0
- package/dist/scheduler/scheduler.js +423 -0
- package/dist/scheduler/scheduler.js.map +1 -0
- package/dist/scheduler/types.d.ts +160 -0
- package/dist/scheduler/types.d.ts.map +1 -0
- package/dist/scheduler/types.js +8 -0
- package/dist/scheduler/types.js.map +1 -0
- package/dist/state/__tests__/directory.test.d.ts +2 -0
- package/dist/state/__tests__/directory.test.d.ts.map +1 -0
- package/dist/state/__tests__/directory.test.js +414 -0
- package/dist/state/__tests__/directory.test.js.map +1 -0
- package/dist/state/__tests__/fleet-state.test.d.ts +2 -0
- package/dist/state/__tests__/fleet-state.test.d.ts.map +1 -0
- package/dist/state/__tests__/fleet-state.test.js +696 -0
- package/dist/state/__tests__/fleet-state.test.js.map +1 -0
- package/dist/state/__tests__/job-metadata-schema.test.d.ts +2 -0
- package/dist/state/__tests__/job-metadata-schema.test.d.ts.map +1 -0
- package/dist/state/__tests__/job-metadata-schema.test.js +329 -0
- package/dist/state/__tests__/job-metadata-schema.test.js.map +1 -0
- package/dist/state/__tests__/job-metadata.test.d.ts +2 -0
- package/dist/state/__tests__/job-metadata.test.d.ts.map +1 -0
- package/dist/state/__tests__/job-metadata.test.js +667 -0
- package/dist/state/__tests__/job-metadata.test.js.map +1 -0
- package/dist/state/__tests__/job-output.test.d.ts +2 -0
- package/dist/state/__tests__/job-output.test.d.ts.map +1 -0
- package/dist/state/__tests__/job-output.test.js +672 -0
- package/dist/state/__tests__/job-output.test.js.map +1 -0
- package/dist/state/__tests__/session-schema.test.d.ts +2 -0
- package/dist/state/__tests__/session-schema.test.d.ts.map +1 -0
- package/dist/state/__tests__/session-schema.test.js +323 -0
- package/dist/state/__tests__/session-schema.test.js.map +1 -0
- package/dist/state/__tests__/session.test.d.ts +2 -0
- package/dist/state/__tests__/session.test.d.ts.map +1 -0
- package/dist/state/__tests__/session.test.js +468 -0
- package/dist/state/__tests__/session.test.js.map +1 -0
- package/dist/state/directory.d.ts +42 -0
- package/dist/state/directory.d.ts.map +1 -0
- package/dist/state/directory.js +170 -0
- package/dist/state/directory.js.map +1 -0
- package/dist/state/errors.d.ts +44 -0
- package/dist/state/errors.d.ts.map +1 -0
- package/dist/state/errors.js +82 -0
- package/dist/state/errors.js.map +1 -0
- package/dist/state/fleet-state.d.ts +126 -0
- package/dist/state/fleet-state.d.ts.map +1 -0
- package/dist/state/fleet-state.js +196 -0
- package/dist/state/fleet-state.js.map +1 -0
- package/dist/state/index.d.ts +21 -0
- package/dist/state/index.d.ts.map +1 -0
- package/dist/state/index.js +30 -0
- package/dist/state/index.js.map +1 -0
- package/dist/state/job-metadata.d.ts +151 -0
- package/dist/state/job-metadata.d.ts.map +1 -0
- package/dist/state/job-metadata.js +287 -0
- package/dist/state/job-metadata.js.map +1 -0
- package/dist/state/job-output.d.ts +116 -0
- package/dist/state/job-output.d.ts.map +1 -0
- package/dist/state/job-output.js +218 -0
- package/dist/state/job-output.js.map +1 -0
- package/dist/state/schemas/__tests__/job-output.test.d.ts +2 -0
- package/dist/state/schemas/__tests__/job-output.test.d.ts.map +1 -0
- package/dist/state/schemas/__tests__/job-output.test.js +279 -0
- package/dist/state/schemas/__tests__/job-output.test.js.map +1 -0
- package/dist/state/schemas/fleet-state.d.ts +249 -0
- package/dist/state/schemas/fleet-state.d.ts.map +1 -0
- package/dist/state/schemas/fleet-state.js +97 -0
- package/dist/state/schemas/fleet-state.js.map +1 -0
- package/dist/state/schemas/index.d.ts +10 -0
- package/dist/state/schemas/index.d.ts.map +1 -0
- package/dist/state/schemas/index.js +10 -0
- package/dist/state/schemas/index.js.map +1 -0
- package/dist/state/schemas/job-metadata.d.ts +118 -0
- package/dist/state/schemas/job-metadata.d.ts.map +1 -0
- package/dist/state/schemas/job-metadata.js +123 -0
- package/dist/state/schemas/job-metadata.js.map +1 -0
- package/dist/state/schemas/job-output.d.ts +291 -0
- package/dist/state/schemas/job-output.d.ts.map +1 -0
- package/dist/state/schemas/job-output.js +132 -0
- package/dist/state/schemas/job-output.js.map +1 -0
- package/dist/state/schemas/session-info.d.ts +65 -0
- package/dist/state/schemas/session-info.d.ts.map +1 -0
- package/dist/state/schemas/session-info.js +58 -0
- package/dist/state/schemas/session-info.js.map +1 -0
- package/dist/state/session.d.ts +92 -0
- package/dist/state/session.d.ts.map +1 -0
- package/dist/state/session.js +173 -0
- package/dist/state/session.js.map +1 -0
- package/dist/state/types.d.ts +54 -0
- package/dist/state/types.d.ts.map +1 -0
- package/dist/state/types.js +18 -0
- package/dist/state/types.js.map +1 -0
- package/dist/state/utils/__tests__/atomic.test.d.ts +2 -0
- package/dist/state/utils/__tests__/atomic.test.d.ts.map +1 -0
- package/dist/state/utils/__tests__/atomic.test.js +537 -0
- package/dist/state/utils/__tests__/atomic.test.js.map +1 -0
- package/dist/state/utils/__tests__/reads.test.d.ts +2 -0
- package/dist/state/utils/__tests__/reads.test.d.ts.map +1 -0
- package/dist/state/utils/__tests__/reads.test.js +792 -0
- package/dist/state/utils/__tests__/reads.test.js.map +1 -0
- package/dist/state/utils/atomic.d.ts +89 -0
- package/dist/state/utils/atomic.d.ts.map +1 -0
- package/dist/state/utils/atomic.js +157 -0
- package/dist/state/utils/atomic.js.map +1 -0
- package/dist/state/utils/index.d.ts +6 -0
- package/dist/state/utils/index.d.ts.map +1 -0
- package/dist/state/utils/index.js +6 -0
- package/dist/state/utils/index.js.map +1 -0
- package/dist/state/utils/reads.d.ts +196 -0
- package/dist/state/utils/reads.d.ts.map +1 -0
- package/dist/state/utils/reads.js +346 -0
- package/dist/state/utils/reads.js.map +1 -0
- package/dist/work-sources/__tests__/github.test.d.ts +2 -0
- package/dist/work-sources/__tests__/github.test.d.ts.map +1 -0
- package/dist/work-sources/__tests__/github.test.js +1334 -0
- package/dist/work-sources/__tests__/github.test.js.map +1 -0
- package/dist/work-sources/__tests__/manager.test.d.ts +2 -0
- package/dist/work-sources/__tests__/manager.test.d.ts.map +1 -0
- package/dist/work-sources/__tests__/manager.test.js +424 -0
- package/dist/work-sources/__tests__/manager.test.js.map +1 -0
- package/dist/work-sources/__tests__/registry.test.d.ts +2 -0
- package/dist/work-sources/__tests__/registry.test.d.ts.map +1 -0
- package/dist/work-sources/__tests__/registry.test.js +381 -0
- package/dist/work-sources/__tests__/registry.test.js.map +1 -0
- package/dist/work-sources/__tests__/types.test.d.ts +2 -0
- package/dist/work-sources/__tests__/types.test.d.ts.map +1 -0
- package/dist/work-sources/__tests__/types.test.js +406 -0
- package/dist/work-sources/__tests__/types.test.js.map +1 -0
- package/dist/work-sources/adapters/github.d.ts +290 -0
- package/dist/work-sources/adapters/github.d.ts.map +1 -0
- package/dist/work-sources/adapters/github.js +803 -0
- package/dist/work-sources/adapters/github.js.map +1 -0
- package/dist/work-sources/adapters/index.d.ts +10 -0
- package/dist/work-sources/adapters/index.d.ts.map +1 -0
- package/dist/work-sources/adapters/index.js +31 -0
- package/dist/work-sources/adapters/index.js.map +1 -0
- package/dist/work-sources/errors.d.ts +40 -0
- package/dist/work-sources/errors.d.ts.map +1 -0
- package/dist/work-sources/errors.js +54 -0
- package/dist/work-sources/errors.js.map +1 -0
- package/dist/work-sources/index.d.ts +105 -0
- package/dist/work-sources/index.d.ts.map +1 -0
- package/dist/work-sources/index.js +24 -0
- package/dist/work-sources/index.js.map +1 -0
- package/dist/work-sources/manager.d.ts +370 -0
- package/dist/work-sources/manager.d.ts.map +1 -0
- package/dist/work-sources/manager.js +61 -0
- package/dist/work-sources/manager.js.map +1 -0
- package/dist/work-sources/registry.d.ts +128 -0
- package/dist/work-sources/registry.d.ts.map +1 -0
- package/dist/work-sources/registry.js +132 -0
- package/dist/work-sources/registry.js.map +1 -0
- package/dist/work-sources/types.d.ts +127 -0
- package/dist/work-sources/types.d.ts.map +1 -0
- package/dist/work-sources/types.js +8 -0
- package/dist/work-sources/types.js.map +1 -0
- package/package.json +23 -0
- package/src/config/__tests__/agent.test.ts +864 -0
- package/src/config/__tests__/interpolate.test.ts +644 -0
- package/src/config/__tests__/loader.test.ts +784 -0
- package/src/config/__tests__/merge.test.ts +751 -0
- package/src/config/__tests__/parser.test.ts +533 -0
- package/src/config/__tests__/schema.test.ts +873 -0
- package/src/config/index.ts +119 -0
- package/src/config/interpolate.ts +189 -0
- package/src/config/loader.ts +472 -0
- package/src/config/merge.ts +246 -0
- package/src/config/parser.ts +376 -0
- package/src/config/schema.ts +346 -0
- package/src/fleet-manager/__tests__/coverage.test.ts +2869 -0
- package/src/fleet-manager/__tests__/errors.test.ts +660 -0
- package/src/fleet-manager/__tests__/event-helpers.test.ts +448 -0
- package/src/fleet-manager/__tests__/integration.test.ts +1209 -0
- package/src/fleet-manager/__tests__/job-control.test.ts +283 -0
- package/src/fleet-manager/__tests__/job-manager.test.ts +869 -0
- package/src/fleet-manager/__tests__/job-queue.test.ts +401 -0
- package/src/fleet-manager/__tests__/reload.test.ts +751 -0
- package/src/fleet-manager/__tests__/status-queries.test.ts +595 -0
- package/src/fleet-manager/__tests__/trigger.test.ts +601 -0
- package/src/fleet-manager/errors.ts +747 -0
- package/src/fleet-manager/event-types.ts +378 -0
- package/src/fleet-manager/fleet-manager.ts +2315 -0
- package/src/fleet-manager/index.ts +128 -0
- package/src/fleet-manager/job-manager.ts +663 -0
- package/src/fleet-manager/job-queue.ts +798 -0
- package/src/fleet-manager/types.ts +839 -0
- package/src/index.ts +32 -0
- package/src/runner/__tests__/errors.test.ts +382 -0
- package/src/runner/__tests__/job-executor.test.ts +1708 -0
- package/src/runner/__tests__/message-processor.test.ts +960 -0
- package/src/runner/__tests__/sdk-adapter.test.ts +626 -0
- package/src/runner/errors.ts +307 -0
- package/src/runner/index.ts +57 -0
- package/src/runner/job-executor.ts +448 -0
- package/src/runner/message-processor.ts +355 -0
- package/src/runner/sdk-adapter.ts +191 -0
- package/src/runner/types.ts +158 -0
- package/src/scheduler/__tests__/errors.test.ts +159 -0
- package/src/scheduler/__tests__/interval.test.ts +515 -0
- package/src/scheduler/__tests__/schedule-runner.test.ts +798 -0
- package/src/scheduler/__tests__/schedule-state.test.ts +671 -0
- package/src/scheduler/__tests__/scheduler.test.ts +1280 -0
- package/src/scheduler/errors.ts +101 -0
- package/src/scheduler/index.ts +53 -0
- package/src/scheduler/interval.ts +189 -0
- package/src/scheduler/schedule-runner.ts +442 -0
- package/src/scheduler/schedule-state.ts +211 -0
- package/src/scheduler/scheduler.ts +570 -0
- package/src/scheduler/types.ts +216 -0
- package/src/state/__tests__/directory.test.ts +595 -0
- package/src/state/__tests__/fleet-state.test.ts +868 -0
- package/src/state/__tests__/job-metadata-schema.test.ts +414 -0
- package/src/state/__tests__/job-metadata.test.ts +831 -0
- package/src/state/__tests__/job-output.test.ts +856 -0
- package/src/state/__tests__/session-schema.test.ts +378 -0
- package/src/state/__tests__/session.test.ts +604 -0
- package/src/state/directory.ts +217 -0
- package/src/state/errors.ts +97 -0
- package/src/state/fleet-state.ts +284 -0
- package/src/state/index.ts +79 -0
- package/src/state/job-metadata.ts +445 -0
- package/src/state/job-output.ts +316 -0
- package/src/state/schemas/__tests__/job-output.test.ts +338 -0
- package/src/state/schemas/fleet-state.ts +120 -0
- package/src/state/schemas/index.ts +67 -0
- package/src/state/schemas/job-metadata.ts +181 -0
- package/src/state/schemas/job-output.ts +177 -0
- package/src/state/schemas/session-info.ts +92 -0
- package/src/state/session.ts +253 -0
- package/src/state/types.ts +59 -0
- package/src/state/utils/__tests__/atomic.test.ts +723 -0
- package/src/state/utils/__tests__/reads.test.ts +1071 -0
- package/src/state/utils/atomic.ts +221 -0
- package/src/state/utils/index.ts +6 -0
- package/src/state/utils/reads.ts +512 -0
- package/src/work-sources/__tests__/github.test.ts +1800 -0
- package/src/work-sources/__tests__/manager.test.ts +529 -0
- package/src/work-sources/__tests__/registry.test.ts +477 -0
- package/src/work-sources/__tests__/types.test.ts +479 -0
- package/src/work-sources/adapters/github.ts +1166 -0
- package/src/work-sources/adapters/index.ts +64 -0
- package/src/work-sources/errors.ts +71 -0
- package/src/work-sources/index.ts +148 -0
- package/src/work-sources/manager.ts +413 -0
- package/src/work-sources/registry.ts +178 -0
- package/src/work-sources/types.ts +161 -0
- package/tsconfig.json +9 -0
- package/vitest.config.ts +19 -0
|
@@ -0,0 +1,798 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Job Queue module for concurrency control
|
|
3
|
+
*
|
|
4
|
+
* Provides a job queue with per-agent and fleet-wide concurrency limits.
|
|
5
|
+
* Jobs queue when limits are reached and are processed FIFO within priority levels.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const queue = new JobQueue({
|
|
10
|
+
* defaultAgentConcurrency: 1,
|
|
11
|
+
* fleetConcurrency: 10,
|
|
12
|
+
* });
|
|
13
|
+
*
|
|
14
|
+
* // Enqueue a job
|
|
15
|
+
* const result = queue.enqueue({
|
|
16
|
+
* agentName: 'my-agent',
|
|
17
|
+
* scheduleName: 'hourly',
|
|
18
|
+
* priority: 5,
|
|
19
|
+
* });
|
|
20
|
+
*
|
|
21
|
+
* if (result.queued) {
|
|
22
|
+
* console.log(`Job queued at position ${result.position}`);
|
|
23
|
+
* } else {
|
|
24
|
+
* console.log(`Job ready to run: ${result.jobId}`);
|
|
25
|
+
* }
|
|
26
|
+
*
|
|
27
|
+
* // Dequeue when ready
|
|
28
|
+
* const job = queue.dequeue('my-agent');
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
import { EventEmitter } from "node:events";
|
|
33
|
+
import { randomUUID } from "node:crypto";
|
|
34
|
+
|
|
35
|
+
// =============================================================================
|
|
36
|
+
// Types
|
|
37
|
+
// =============================================================================
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Priority level for queued jobs
|
|
41
|
+
* Lower numbers = higher priority
|
|
42
|
+
* Default priority is 5 (normal)
|
|
43
|
+
*/
|
|
44
|
+
export type JobPriority = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Configuration options for the JobQueue
|
|
48
|
+
*/
|
|
49
|
+
export interface JobQueueOptions {
|
|
50
|
+
/**
|
|
51
|
+
* Default concurrency limit per agent
|
|
52
|
+
* Can be overridden per-agent via setAgentConcurrency()
|
|
53
|
+
* Default: 1
|
|
54
|
+
*/
|
|
55
|
+
defaultAgentConcurrency?: number;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Fleet-wide concurrency limit (optional)
|
|
59
|
+
* When set, limits total concurrent jobs across all agents
|
|
60
|
+
* Default: undefined (no fleet-wide limit)
|
|
61
|
+
*/
|
|
62
|
+
fleetConcurrency?: number;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Logger for queue operations
|
|
66
|
+
*/
|
|
67
|
+
logger?: JobQueueLogger;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Logger interface for job queue operations
|
|
72
|
+
*/
|
|
73
|
+
export interface JobQueueLogger {
|
|
74
|
+
debug: (message: string) => void;
|
|
75
|
+
info: (message: string) => void;
|
|
76
|
+
warn: (message: string) => void;
|
|
77
|
+
error: (message: string) => void;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* A queued job entry
|
|
82
|
+
*/
|
|
83
|
+
export interface QueuedJob {
|
|
84
|
+
/**
|
|
85
|
+
* Unique ID for this queued job
|
|
86
|
+
*/
|
|
87
|
+
id: string;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Name of the agent this job is for
|
|
91
|
+
*/
|
|
92
|
+
agentName: string;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Name of the schedule that triggered this job (optional)
|
|
96
|
+
*/
|
|
97
|
+
scheduleName?: string;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Job priority (1-10, lower = higher priority)
|
|
101
|
+
* Default: 5 (normal)
|
|
102
|
+
*/
|
|
103
|
+
priority: JobPriority;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* ISO timestamp when the job was queued
|
|
107
|
+
*/
|
|
108
|
+
queuedAt: string;
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Prompt override for this job (optional)
|
|
112
|
+
*/
|
|
113
|
+
prompt?: string;
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Whether this is from a scheduled trigger
|
|
117
|
+
*/
|
|
118
|
+
isScheduled: boolean;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Options for enqueueing a job
|
|
123
|
+
*/
|
|
124
|
+
export interface EnqueueOptions {
|
|
125
|
+
/**
|
|
126
|
+
* Name of the agent to run
|
|
127
|
+
*/
|
|
128
|
+
agentName: string;
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Name of the schedule (optional)
|
|
132
|
+
*/
|
|
133
|
+
scheduleName?: string;
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Job priority (1-10, lower = higher priority)
|
|
137
|
+
* Default: 5
|
|
138
|
+
*/
|
|
139
|
+
priority?: JobPriority;
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Prompt override (optional)
|
|
143
|
+
*/
|
|
144
|
+
prompt?: string;
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Whether this is from a scheduled trigger
|
|
148
|
+
* Scheduled triggers are NOT queued - they emit schedule:skipped instead
|
|
149
|
+
* Default: false
|
|
150
|
+
*/
|
|
151
|
+
isScheduled?: boolean;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Result of enqueueing a job
|
|
156
|
+
*/
|
|
157
|
+
export interface EnqueueResult {
|
|
158
|
+
/**
|
|
159
|
+
* The queued job ID
|
|
160
|
+
*/
|
|
161
|
+
jobId: string;
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Whether the job was actually queued (vs ready to run immediately)
|
|
165
|
+
*/
|
|
166
|
+
queued: boolean;
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Position in the queue (1-based) if queued
|
|
170
|
+
* Undefined if not queued (ready to run)
|
|
171
|
+
*/
|
|
172
|
+
position?: number;
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Reason the job was queued, if applicable
|
|
176
|
+
*/
|
|
177
|
+
reason?: "agent_at_capacity" | "fleet_at_capacity";
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Result when a scheduled job is skipped due to concurrency
|
|
182
|
+
*/
|
|
183
|
+
export interface ScheduleSkipResult {
|
|
184
|
+
/**
|
|
185
|
+
* The agent that was at capacity
|
|
186
|
+
*/
|
|
187
|
+
agentName: string;
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* The schedule that was skipped
|
|
191
|
+
*/
|
|
192
|
+
scheduleName?: string;
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Reason for skipping
|
|
196
|
+
*/
|
|
197
|
+
reason: "agent_at_capacity" | "fleet_at_capacity";
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Current running count
|
|
201
|
+
*/
|
|
202
|
+
currentRunning: number;
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* The limit that was hit
|
|
206
|
+
*/
|
|
207
|
+
limit: number;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Status of the job queue for a specific agent
|
|
212
|
+
*/
|
|
213
|
+
export interface AgentQueueStatus {
|
|
214
|
+
/**
|
|
215
|
+
* Name of the agent
|
|
216
|
+
*/
|
|
217
|
+
agentName: string;
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Number of jobs currently running for this agent
|
|
221
|
+
*/
|
|
222
|
+
runningCount: number;
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Maximum concurrent jobs allowed for this agent
|
|
226
|
+
*/
|
|
227
|
+
maxConcurrent: number;
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Number of jobs queued for this agent
|
|
231
|
+
*/
|
|
232
|
+
queuedCount: number;
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* The queued jobs for this agent (in order)
|
|
236
|
+
*/
|
|
237
|
+
queuedJobs: QueuedJob[];
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Overall queue status
|
|
242
|
+
*/
|
|
243
|
+
export interface QueueStatus {
|
|
244
|
+
/**
|
|
245
|
+
* Total jobs currently running across all agents
|
|
246
|
+
*/
|
|
247
|
+
totalRunning: number;
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Fleet-wide concurrency limit (if set)
|
|
251
|
+
*/
|
|
252
|
+
fleetConcurrency: number | null;
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Default per-agent concurrency limit
|
|
256
|
+
*/
|
|
257
|
+
defaultAgentConcurrency: number;
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Total jobs queued across all agents
|
|
261
|
+
*/
|
|
262
|
+
totalQueued: number;
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Per-agent queue status
|
|
266
|
+
*/
|
|
267
|
+
agents: Map<string, AgentQueueStatus>;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Events emitted by the JobQueue
|
|
272
|
+
*/
|
|
273
|
+
export interface JobQueueEventMap {
|
|
274
|
+
/**
|
|
275
|
+
* Emitted when a job is enqueued
|
|
276
|
+
*/
|
|
277
|
+
"job:queued": [job: QueuedJob, position: number];
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Emitted when a job is dequeued and ready to run
|
|
281
|
+
*/
|
|
282
|
+
"job:dequeued": [job: QueuedJob];
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Emitted when a scheduled trigger is skipped due to concurrency
|
|
286
|
+
*/
|
|
287
|
+
"schedule:skipped": [result: ScheduleSkipResult];
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Emitted when a job completes and capacity becomes available
|
|
291
|
+
*/
|
|
292
|
+
"capacity:available": [agentName: string, available: number];
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// =============================================================================
|
|
296
|
+
// Default Logger
|
|
297
|
+
// =============================================================================
|
|
298
|
+
|
|
299
|
+
function createDefaultLogger(): JobQueueLogger {
|
|
300
|
+
return {
|
|
301
|
+
debug: (message: string) => console.debug(`[job-queue] ${message}`),
|
|
302
|
+
info: (message: string) => console.info(`[job-queue] ${message}`),
|
|
303
|
+
warn: (message: string) => console.warn(`[job-queue] ${message}`),
|
|
304
|
+
error: (message: string) => console.error(`[job-queue] ${message}`),
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// =============================================================================
|
|
309
|
+
// JobQueue Class
|
|
310
|
+
// =============================================================================
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Job queue with concurrency control
|
|
314
|
+
*
|
|
315
|
+
* Manages a FIFO queue (within priority levels) with:
|
|
316
|
+
* - Per-agent concurrency limits
|
|
317
|
+
* - Optional fleet-wide concurrency limit
|
|
318
|
+
* - Priority-based ordering (lower number = higher priority)
|
|
319
|
+
*
|
|
320
|
+
* Scheduled triggers are NOT queued - instead, a schedule:skipped event
|
|
321
|
+
* is emitted when the agent or fleet is at capacity.
|
|
322
|
+
*/
|
|
323
|
+
export class JobQueue extends EventEmitter {
|
|
324
|
+
private readonly defaultAgentConcurrency: number;
|
|
325
|
+
private readonly fleetConcurrency: number | null;
|
|
326
|
+
private readonly logger: JobQueueLogger;
|
|
327
|
+
|
|
328
|
+
// Per-agent concurrency limits (overrides default)
|
|
329
|
+
private readonly agentConcurrencyLimits: Map<string, number> = new Map();
|
|
330
|
+
|
|
331
|
+
// Currently running jobs per agent
|
|
332
|
+
private readonly runningJobs: Map<string, Set<string>> = new Map();
|
|
333
|
+
|
|
334
|
+
// Queued jobs per agent (ordered by priority then FIFO)
|
|
335
|
+
private readonly queuedJobs: Map<string, QueuedJob[]> = new Map();
|
|
336
|
+
|
|
337
|
+
// Total running jobs across fleet
|
|
338
|
+
private totalRunningCount = 0;
|
|
339
|
+
|
|
340
|
+
constructor(options: JobQueueOptions = {}) {
|
|
341
|
+
super();
|
|
342
|
+
this.defaultAgentConcurrency = options.defaultAgentConcurrency ?? 1;
|
|
343
|
+
this.fleetConcurrency = options.fleetConcurrency ?? null;
|
|
344
|
+
this.logger = options.logger ?? createDefaultLogger();
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// ===========================================================================
|
|
348
|
+
// Configuration Methods
|
|
349
|
+
// ===========================================================================
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Set the concurrency limit for a specific agent
|
|
353
|
+
*
|
|
354
|
+
* @param agentName - The agent name
|
|
355
|
+
* @param limit - The concurrency limit (must be >= 1)
|
|
356
|
+
*/
|
|
357
|
+
setAgentConcurrency(agentName: string, limit: number): void {
|
|
358
|
+
if (limit < 1) {
|
|
359
|
+
throw new Error(`Concurrency limit must be >= 1, got ${limit}`);
|
|
360
|
+
}
|
|
361
|
+
this.agentConcurrencyLimits.set(agentName, limit);
|
|
362
|
+
this.logger.debug(
|
|
363
|
+
`Set concurrency limit for agent "${agentName}" to ${limit}`
|
|
364
|
+
);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Get the concurrency limit for an agent
|
|
369
|
+
*
|
|
370
|
+
* @param agentName - The agent name
|
|
371
|
+
* @returns The concurrency limit (agent-specific or default)
|
|
372
|
+
*/
|
|
373
|
+
getAgentConcurrency(agentName: string): number {
|
|
374
|
+
return (
|
|
375
|
+
this.agentConcurrencyLimits.get(agentName) ?? this.defaultAgentConcurrency
|
|
376
|
+
);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Get the fleet-wide concurrency limit
|
|
381
|
+
*
|
|
382
|
+
* @returns The fleet concurrency limit or null if not set
|
|
383
|
+
*/
|
|
384
|
+
getFleetConcurrency(): number | null {
|
|
385
|
+
return this.fleetConcurrency;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Get the default agent concurrency limit
|
|
390
|
+
*
|
|
391
|
+
* @returns The default agent concurrency limit
|
|
392
|
+
*/
|
|
393
|
+
getDefaultAgentConcurrency(): number {
|
|
394
|
+
return this.defaultAgentConcurrency;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// ===========================================================================
|
|
398
|
+
// Queue Operations
|
|
399
|
+
// ===========================================================================
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* Check if there's capacity to run a job for an agent
|
|
403
|
+
*
|
|
404
|
+
* @param agentName - The agent name
|
|
405
|
+
* @returns Object with canRun boolean and reason if false
|
|
406
|
+
*/
|
|
407
|
+
checkCapacity(agentName: string): {
|
|
408
|
+
canRun: boolean;
|
|
409
|
+
reason?: "agent_at_capacity" | "fleet_at_capacity";
|
|
410
|
+
currentRunning: number;
|
|
411
|
+
limit: number;
|
|
412
|
+
} {
|
|
413
|
+
const agentLimit = this.getAgentConcurrency(agentName);
|
|
414
|
+
const agentRunning = this.getRunningCount(agentName);
|
|
415
|
+
|
|
416
|
+
// Check agent-level capacity
|
|
417
|
+
if (agentRunning >= agentLimit) {
|
|
418
|
+
return {
|
|
419
|
+
canRun: false,
|
|
420
|
+
reason: "agent_at_capacity",
|
|
421
|
+
currentRunning: agentRunning,
|
|
422
|
+
limit: agentLimit,
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
// Check fleet-level capacity
|
|
427
|
+
if (
|
|
428
|
+
this.fleetConcurrency !== null &&
|
|
429
|
+
this.totalRunningCount >= this.fleetConcurrency
|
|
430
|
+
) {
|
|
431
|
+
return {
|
|
432
|
+
canRun: false,
|
|
433
|
+
reason: "fleet_at_capacity",
|
|
434
|
+
currentRunning: this.totalRunningCount,
|
|
435
|
+
limit: this.fleetConcurrency,
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
return {
|
|
440
|
+
canRun: true,
|
|
441
|
+
currentRunning: agentRunning,
|
|
442
|
+
limit: agentLimit,
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* Enqueue a job or return immediately if capacity is available
|
|
448
|
+
*
|
|
449
|
+
* For scheduled triggers (isScheduled: true), jobs are NOT queued.
|
|
450
|
+
* Instead, a schedule:skipped event is emitted and null is returned.
|
|
451
|
+
*
|
|
452
|
+
* @param options - Enqueue options
|
|
453
|
+
* @returns EnqueueResult if job is queued/ready, or null if scheduled and at capacity
|
|
454
|
+
*/
|
|
455
|
+
enqueue(options: EnqueueOptions): EnqueueResult | null {
|
|
456
|
+
const {
|
|
457
|
+
agentName,
|
|
458
|
+
scheduleName,
|
|
459
|
+
priority = 5,
|
|
460
|
+
prompt,
|
|
461
|
+
isScheduled = false,
|
|
462
|
+
} = options;
|
|
463
|
+
|
|
464
|
+
const capacity = this.checkCapacity(agentName);
|
|
465
|
+
|
|
466
|
+
// If we have capacity, the job can run immediately
|
|
467
|
+
if (capacity.canRun) {
|
|
468
|
+
const jobId = this.generateJobId();
|
|
469
|
+
this.logger.debug(
|
|
470
|
+
`Job ${jobId} for agent "${agentName}" can run immediately`
|
|
471
|
+
);
|
|
472
|
+
return {
|
|
473
|
+
jobId,
|
|
474
|
+
queued: false,
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
// At capacity - handle scheduled vs manual triggers differently
|
|
479
|
+
if (isScheduled) {
|
|
480
|
+
// Scheduled triggers are NOT queued - emit skip event
|
|
481
|
+
const skipResult: ScheduleSkipResult = {
|
|
482
|
+
agentName,
|
|
483
|
+
scheduleName,
|
|
484
|
+
reason: capacity.reason!,
|
|
485
|
+
currentRunning: capacity.currentRunning,
|
|
486
|
+
limit: capacity.limit,
|
|
487
|
+
};
|
|
488
|
+
|
|
489
|
+
this.logger.info(
|
|
490
|
+
`Schedule "${scheduleName}" for agent "${agentName}" skipped: ${capacity.reason} (${capacity.currentRunning}/${capacity.limit})`
|
|
491
|
+
);
|
|
492
|
+
|
|
493
|
+
this.emit("schedule:skipped", skipResult);
|
|
494
|
+
return null;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
// Manual triggers get queued
|
|
498
|
+
const job: QueuedJob = {
|
|
499
|
+
id: this.generateJobId(),
|
|
500
|
+
agentName,
|
|
501
|
+
scheduleName,
|
|
502
|
+
priority: priority as JobPriority,
|
|
503
|
+
queuedAt: new Date().toISOString(),
|
|
504
|
+
prompt,
|
|
505
|
+
isScheduled: false,
|
|
506
|
+
};
|
|
507
|
+
|
|
508
|
+
// Get or create the agent's queue
|
|
509
|
+
if (!this.queuedJobs.has(agentName)) {
|
|
510
|
+
this.queuedJobs.set(agentName, []);
|
|
511
|
+
}
|
|
512
|
+
const agentQueue = this.queuedJobs.get(agentName)!;
|
|
513
|
+
|
|
514
|
+
// Insert job in priority order (lower priority number = higher priority)
|
|
515
|
+
// Within same priority, FIFO order is maintained
|
|
516
|
+
let insertIndex = agentQueue.length;
|
|
517
|
+
for (let i = 0; i < agentQueue.length; i++) {
|
|
518
|
+
if (agentQueue[i].priority > job.priority) {
|
|
519
|
+
insertIndex = i;
|
|
520
|
+
break;
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
agentQueue.splice(insertIndex, 0, job);
|
|
524
|
+
|
|
525
|
+
const position = insertIndex + 1;
|
|
526
|
+
this.logger.info(
|
|
527
|
+
`Job ${job.id} for agent "${agentName}" queued at position ${position} (${capacity.reason})`
|
|
528
|
+
);
|
|
529
|
+
|
|
530
|
+
this.emit("job:queued", job, position);
|
|
531
|
+
|
|
532
|
+
return {
|
|
533
|
+
jobId: job.id,
|
|
534
|
+
queued: true,
|
|
535
|
+
position,
|
|
536
|
+
reason: capacity.reason,
|
|
537
|
+
};
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
/**
|
|
541
|
+
* Dequeue the next job for an agent
|
|
542
|
+
*
|
|
543
|
+
* Returns the next queued job if one exists, otherwise null.
|
|
544
|
+
* Does NOT check capacity - caller should check capacity first.
|
|
545
|
+
*
|
|
546
|
+
* @param agentName - The agent name
|
|
547
|
+
* @returns The next queued job or null
|
|
548
|
+
*/
|
|
549
|
+
dequeue(agentName: string): QueuedJob | null {
|
|
550
|
+
const agentQueue = this.queuedJobs.get(agentName);
|
|
551
|
+
if (!agentQueue || agentQueue.length === 0) {
|
|
552
|
+
return null;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
const job = agentQueue.shift()!;
|
|
556
|
+
this.logger.debug(
|
|
557
|
+
`Dequeued job ${job.id} for agent "${agentName}" (${agentQueue.length} remaining)`
|
|
558
|
+
);
|
|
559
|
+
|
|
560
|
+
this.emit("job:dequeued", job);
|
|
561
|
+
return job;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* Peek at the next job in the queue without removing it
|
|
566
|
+
*
|
|
567
|
+
* @param agentName - The agent name
|
|
568
|
+
* @returns The next queued job or null
|
|
569
|
+
*/
|
|
570
|
+
peek(agentName: string): QueuedJob | null {
|
|
571
|
+
const agentQueue = this.queuedJobs.get(agentName);
|
|
572
|
+
if (!agentQueue || agentQueue.length === 0) {
|
|
573
|
+
return null;
|
|
574
|
+
}
|
|
575
|
+
return agentQueue[0];
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
/**
|
|
579
|
+
* Remove a specific job from the queue
|
|
580
|
+
*
|
|
581
|
+
* @param jobId - The job ID to remove
|
|
582
|
+
* @returns true if the job was found and removed
|
|
583
|
+
*/
|
|
584
|
+
remove(jobId: string): boolean {
|
|
585
|
+
for (const [agentName, queue] of this.queuedJobs) {
|
|
586
|
+
const index = queue.findIndex((job) => job.id === jobId);
|
|
587
|
+
if (index !== -1) {
|
|
588
|
+
queue.splice(index, 1);
|
|
589
|
+
this.logger.debug(
|
|
590
|
+
`Removed job ${jobId} from agent "${agentName}" queue`
|
|
591
|
+
);
|
|
592
|
+
return true;
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
return false;
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
// ===========================================================================
|
|
599
|
+
// Running Job Tracking
|
|
600
|
+
// ===========================================================================
|
|
601
|
+
|
|
602
|
+
/**
|
|
603
|
+
* Mark a job as running for an agent
|
|
604
|
+
*
|
|
605
|
+
* @param agentName - The agent name
|
|
606
|
+
* @param jobId - The job ID
|
|
607
|
+
*/
|
|
608
|
+
markRunning(agentName: string, jobId: string): void {
|
|
609
|
+
if (!this.runningJobs.has(agentName)) {
|
|
610
|
+
this.runningJobs.set(agentName, new Set());
|
|
611
|
+
}
|
|
612
|
+
this.runningJobs.get(agentName)!.add(jobId);
|
|
613
|
+
this.totalRunningCount++;
|
|
614
|
+
|
|
615
|
+
this.logger.debug(
|
|
616
|
+
`Marked job ${jobId} as running for agent "${agentName}" (total: ${this.totalRunningCount})`
|
|
617
|
+
);
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
/**
|
|
621
|
+
* Mark a job as completed for an agent
|
|
622
|
+
*
|
|
623
|
+
* This frees up capacity and may allow queued jobs to run.
|
|
624
|
+
*
|
|
625
|
+
* @param agentName - The agent name
|
|
626
|
+
* @param jobId - The job ID
|
|
627
|
+
*/
|
|
628
|
+
markCompleted(agentName: string, jobId: string): void {
|
|
629
|
+
const agentJobs = this.runningJobs.get(agentName);
|
|
630
|
+
if (agentJobs?.has(jobId)) {
|
|
631
|
+
agentJobs.delete(jobId);
|
|
632
|
+
this.totalRunningCount--;
|
|
633
|
+
|
|
634
|
+
const available = this.getAgentConcurrency(agentName) - agentJobs.size;
|
|
635
|
+
this.logger.debug(
|
|
636
|
+
`Marked job ${jobId} as completed for agent "${agentName}" (${available} slots available)`
|
|
637
|
+
);
|
|
638
|
+
|
|
639
|
+
this.emit("capacity:available", agentName, available);
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
/**
|
|
644
|
+
* Get the number of running jobs for an agent
|
|
645
|
+
*
|
|
646
|
+
* @param agentName - The agent name
|
|
647
|
+
* @returns Number of currently running jobs
|
|
648
|
+
*/
|
|
649
|
+
getRunningCount(agentName: string): number {
|
|
650
|
+
return this.runningJobs.get(agentName)?.size ?? 0;
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
/**
|
|
654
|
+
* Get the total number of running jobs across all agents
|
|
655
|
+
*
|
|
656
|
+
* @returns Total running job count
|
|
657
|
+
*/
|
|
658
|
+
getTotalRunningCount(): number {
|
|
659
|
+
return this.totalRunningCount;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
/**
|
|
663
|
+
* Get the IDs of running jobs for an agent
|
|
664
|
+
*
|
|
665
|
+
* @param agentName - The agent name
|
|
666
|
+
* @returns Set of running job IDs
|
|
667
|
+
*/
|
|
668
|
+
getRunningJobIds(agentName: string): Set<string> {
|
|
669
|
+
return this.runningJobs.get(agentName) ?? new Set();
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
// ===========================================================================
|
|
673
|
+
// Status Queries
|
|
674
|
+
// ===========================================================================
|
|
675
|
+
|
|
676
|
+
/**
|
|
677
|
+
* Get the queue status for a specific agent
|
|
678
|
+
*
|
|
679
|
+
* @param agentName - The agent name
|
|
680
|
+
* @returns Agent queue status
|
|
681
|
+
*/
|
|
682
|
+
getAgentQueueStatus(agentName: string): AgentQueueStatus {
|
|
683
|
+
const queuedJobs = this.queuedJobs.get(agentName) ?? [];
|
|
684
|
+
return {
|
|
685
|
+
agentName,
|
|
686
|
+
runningCount: this.getRunningCount(agentName),
|
|
687
|
+
maxConcurrent: this.getAgentConcurrency(agentName),
|
|
688
|
+
queuedCount: queuedJobs.length,
|
|
689
|
+
queuedJobs: [...queuedJobs], // Return a copy
|
|
690
|
+
};
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
/**
|
|
694
|
+
* Get the overall queue status
|
|
695
|
+
*
|
|
696
|
+
* @returns Overall queue status with per-agent details
|
|
697
|
+
*/
|
|
698
|
+
getQueueStatus(): QueueStatus {
|
|
699
|
+
const agents = new Map<string, AgentQueueStatus>();
|
|
700
|
+
|
|
701
|
+
// Collect all known agent names from both running and queued
|
|
702
|
+
const allAgentNames = new Set<string>([
|
|
703
|
+
...this.runningJobs.keys(),
|
|
704
|
+
...this.queuedJobs.keys(),
|
|
705
|
+
]);
|
|
706
|
+
|
|
707
|
+
let totalQueued = 0;
|
|
708
|
+
for (const agentName of allAgentNames) {
|
|
709
|
+
const status = this.getAgentQueueStatus(agentName);
|
|
710
|
+
agents.set(agentName, status);
|
|
711
|
+
totalQueued += status.queuedCount;
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
return {
|
|
715
|
+
totalRunning: this.totalRunningCount,
|
|
716
|
+
fleetConcurrency: this.fleetConcurrency,
|
|
717
|
+
defaultAgentConcurrency: this.defaultAgentConcurrency,
|
|
718
|
+
totalQueued,
|
|
719
|
+
agents,
|
|
720
|
+
};
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
/**
|
|
724
|
+
* Get the queue depth (number of queued jobs) for an agent
|
|
725
|
+
*
|
|
726
|
+
* @param agentName - The agent name
|
|
727
|
+
* @returns Number of queued jobs
|
|
728
|
+
*/
|
|
729
|
+
getQueueDepth(agentName: string): number {
|
|
730
|
+
return this.queuedJobs.get(agentName)?.length ?? 0;
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
/**
|
|
734
|
+
* Get the total queue depth across all agents
|
|
735
|
+
*
|
|
736
|
+
* @returns Total number of queued jobs
|
|
737
|
+
*/
|
|
738
|
+
getTotalQueueDepth(): number {
|
|
739
|
+
let total = 0;
|
|
740
|
+
for (const queue of this.queuedJobs.values()) {
|
|
741
|
+
total += queue.length;
|
|
742
|
+
}
|
|
743
|
+
return total;
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
// ===========================================================================
|
|
747
|
+
// Utility Methods
|
|
748
|
+
// ===========================================================================
|
|
749
|
+
|
|
750
|
+
/**
|
|
751
|
+
* Clear all queued jobs (does not affect running jobs)
|
|
752
|
+
*/
|
|
753
|
+
clearQueue(): void {
|
|
754
|
+
const totalCleared = this.getTotalQueueDepth();
|
|
755
|
+
this.queuedJobs.clear();
|
|
756
|
+
this.logger.info(`Cleared ${totalCleared} queued jobs`);
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
/**
|
|
760
|
+
* Clear queued jobs for a specific agent
|
|
761
|
+
*
|
|
762
|
+
* @param agentName - The agent name
|
|
763
|
+
* @returns Number of jobs cleared
|
|
764
|
+
*/
|
|
765
|
+
clearAgentQueue(agentName: string): number {
|
|
766
|
+
const queue = this.queuedJobs.get(agentName);
|
|
767
|
+
if (!queue) return 0;
|
|
768
|
+
|
|
769
|
+
const count = queue.length;
|
|
770
|
+
this.queuedJobs.delete(agentName);
|
|
771
|
+
this.logger.debug(`Cleared ${count} queued jobs for agent "${agentName}"`);
|
|
772
|
+
return count;
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
/**
|
|
776
|
+
* Reset all state (running jobs, queued jobs, concurrency limits)
|
|
777
|
+
*/
|
|
778
|
+
reset(): void {
|
|
779
|
+
this.runningJobs.clear();
|
|
780
|
+
this.queuedJobs.clear();
|
|
781
|
+
this.agentConcurrencyLimits.clear();
|
|
782
|
+
this.totalRunningCount = 0;
|
|
783
|
+
this.logger.info("Job queue reset");
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
// ===========================================================================
|
|
787
|
+
// Private Methods
|
|
788
|
+
// ===========================================================================
|
|
789
|
+
|
|
790
|
+
/**
|
|
791
|
+
* Generate a unique job ID
|
|
792
|
+
*/
|
|
793
|
+
private generateJobId(): string {
|
|
794
|
+
const date = new Date().toISOString().slice(0, 10);
|
|
795
|
+
const uuid = randomUUID().slice(0, 8);
|
|
796
|
+
return `queued-${date}-${uuid}`;
|
|
797
|
+
}
|
|
798
|
+
}
|