@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,570 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scheduler class for managing agent schedule execution
|
|
3
|
+
*
|
|
4
|
+
* The Scheduler continuously checks all agents' interval schedules and triggers
|
|
5
|
+
* due agents according to their configured intervals.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { ResolvedAgent } from "../config/index.js";
|
|
9
|
+
import { calculateNextTrigger, isScheduleDue } from "./interval.js";
|
|
10
|
+
import {
|
|
11
|
+
getScheduleState,
|
|
12
|
+
updateScheduleState,
|
|
13
|
+
type ScheduleStateLogger,
|
|
14
|
+
} from "./schedule-state.js";
|
|
15
|
+
import type {
|
|
16
|
+
SchedulerOptions,
|
|
17
|
+
SchedulerStatus,
|
|
18
|
+
SchedulerState,
|
|
19
|
+
SchedulerLogger,
|
|
20
|
+
ScheduleCheckResult,
|
|
21
|
+
ScheduleSkipReason,
|
|
22
|
+
TriggerInfo,
|
|
23
|
+
SchedulerTriggerCallback,
|
|
24
|
+
StopOptions,
|
|
25
|
+
} from "./types.js";
|
|
26
|
+
import { SchedulerShutdownError } from "./errors.js";
|
|
27
|
+
|
|
28
|
+
// =============================================================================
|
|
29
|
+
// Constants
|
|
30
|
+
// =============================================================================
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Default check interval in milliseconds (1 second)
|
|
34
|
+
*/
|
|
35
|
+
const DEFAULT_CHECK_INTERVAL = 1000;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Default shutdown timeout in milliseconds (30 seconds)
|
|
39
|
+
*/
|
|
40
|
+
const DEFAULT_SHUTDOWN_TIMEOUT = 30000;
|
|
41
|
+
|
|
42
|
+
// =============================================================================
|
|
43
|
+
// Default Logger
|
|
44
|
+
// =============================================================================
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Create a default console-based logger
|
|
48
|
+
*/
|
|
49
|
+
function createDefaultLogger(): SchedulerLogger {
|
|
50
|
+
return {
|
|
51
|
+
debug: (message: string) => console.debug(`[scheduler] ${message}`),
|
|
52
|
+
info: (message: string) => console.info(`[scheduler] ${message}`),
|
|
53
|
+
warn: (message: string) => console.warn(`[scheduler] ${message}`),
|
|
54
|
+
error: (message: string) => console.error(`[scheduler] ${message}`),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// =============================================================================
|
|
59
|
+
// Scheduler Class
|
|
60
|
+
// =============================================================================
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Scheduler for managing agent schedule execution
|
|
64
|
+
*
|
|
65
|
+
* The Scheduler runs a polling loop that:
|
|
66
|
+
* 1. Checks all agents' interval schedules on each iteration
|
|
67
|
+
* 2. Skips non-interval schedule types (cron, webhook, chat)
|
|
68
|
+
* 3. Skips disabled schedules
|
|
69
|
+
* 4. Skips agents at max_concurrent capacity
|
|
70
|
+
* 5. Triggers due schedules via the onTrigger callback
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```typescript
|
|
74
|
+
* const scheduler = new Scheduler({
|
|
75
|
+
* stateDir: '.herdctl',
|
|
76
|
+
* checkInterval: 1000, // 1 second
|
|
77
|
+
* onTrigger: async (info) => {
|
|
78
|
+
* console.log(`Triggering ${info.agent.name}/${info.scheduleName}`);
|
|
79
|
+
* await runAgent(info.agent, info.schedule);
|
|
80
|
+
* },
|
|
81
|
+
* });
|
|
82
|
+
*
|
|
83
|
+
* // Start the scheduler
|
|
84
|
+
* await scheduler.start(agents);
|
|
85
|
+
*
|
|
86
|
+
* // Later, stop the scheduler
|
|
87
|
+
* await scheduler.stop();
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
export class Scheduler {
|
|
91
|
+
private readonly checkInterval: number;
|
|
92
|
+
private readonly stateDir: string;
|
|
93
|
+
private readonly logger: SchedulerLogger;
|
|
94
|
+
private readonly onTrigger?: SchedulerTriggerCallback;
|
|
95
|
+
|
|
96
|
+
private status: SchedulerStatus = "stopped";
|
|
97
|
+
private abortController: AbortController | null = null;
|
|
98
|
+
private agents: ResolvedAgent[] = [];
|
|
99
|
+
private runningSchedules: Map<string, Set<string>> = new Map();
|
|
100
|
+
private runningJobs: Map<string, Promise<void>> = new Map();
|
|
101
|
+
|
|
102
|
+
private startedAt: string | null = null;
|
|
103
|
+
private checkCount = 0;
|
|
104
|
+
private triggerCount = 0;
|
|
105
|
+
private lastCheckAt: string | null = null;
|
|
106
|
+
|
|
107
|
+
constructor(options: SchedulerOptions) {
|
|
108
|
+
this.checkInterval = options.checkInterval ?? DEFAULT_CHECK_INTERVAL;
|
|
109
|
+
this.stateDir = options.stateDir;
|
|
110
|
+
this.logger = options.logger ?? createDefaultLogger();
|
|
111
|
+
this.onTrigger = options.onTrigger;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Check if the scheduler is currently running
|
|
116
|
+
*/
|
|
117
|
+
isRunning(): boolean {
|
|
118
|
+
return this.status === "running";
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Get the current scheduler status
|
|
123
|
+
*/
|
|
124
|
+
getStatus(): SchedulerStatus {
|
|
125
|
+
return this.status;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Get detailed scheduler state for monitoring
|
|
130
|
+
*/
|
|
131
|
+
getState(): SchedulerState {
|
|
132
|
+
return {
|
|
133
|
+
status: this.status,
|
|
134
|
+
startedAt: this.startedAt,
|
|
135
|
+
checkCount: this.checkCount,
|
|
136
|
+
triggerCount: this.triggerCount,
|
|
137
|
+
lastCheckAt: this.lastCheckAt,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Start the scheduler polling loop
|
|
143
|
+
*
|
|
144
|
+
* @param agents - The agents to schedule
|
|
145
|
+
* @throws Error if scheduler is already running
|
|
146
|
+
*/
|
|
147
|
+
async start(agents: ResolvedAgent[]): Promise<void> {
|
|
148
|
+
if (this.status === "running") {
|
|
149
|
+
throw new Error("Scheduler is already running");
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (this.status === "stopping") {
|
|
153
|
+
throw new Error("Scheduler is stopping, wait for it to complete");
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
this.agents = agents;
|
|
157
|
+
this.status = "running";
|
|
158
|
+
this.abortController = new AbortController();
|
|
159
|
+
this.startedAt = new Date().toISOString();
|
|
160
|
+
this.checkCount = 0;
|
|
161
|
+
this.triggerCount = 0;
|
|
162
|
+
this.runningSchedules.clear();
|
|
163
|
+
this.runningJobs.clear();
|
|
164
|
+
|
|
165
|
+
this.logger.info(
|
|
166
|
+
`Scheduler started with ${agents.length} agents, check interval: ${this.checkInterval}ms`
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
// Run the polling loop
|
|
170
|
+
await this.runLoop();
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Stop the scheduler gracefully
|
|
175
|
+
*
|
|
176
|
+
* Signals the polling loop to stop and optionally waits for running jobs to complete.
|
|
177
|
+
*
|
|
178
|
+
* @param options - Options for shutdown behavior
|
|
179
|
+
* @param options.waitForJobs - Whether to wait for running jobs to complete (default: true)
|
|
180
|
+
* @param options.timeout - Maximum time to wait for jobs in milliseconds (default: 30000)
|
|
181
|
+
* @throws SchedulerShutdownError if timeout is reached while waiting for jobs
|
|
182
|
+
*/
|
|
183
|
+
async stop(options?: StopOptions): Promise<void> {
|
|
184
|
+
if (this.status !== "running") {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const waitForJobs = options?.waitForJobs ?? true;
|
|
189
|
+
const timeout = options?.timeout ?? DEFAULT_SHUTDOWN_TIMEOUT;
|
|
190
|
+
|
|
191
|
+
this.status = "stopping";
|
|
192
|
+
this.logger.info("Scheduler stopping...");
|
|
193
|
+
|
|
194
|
+
// Signal the loop to stop - this prevents new triggers from starting
|
|
195
|
+
this.abortController?.abort();
|
|
196
|
+
|
|
197
|
+
// Wait a tick for the loop to recognize the abort
|
|
198
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
199
|
+
|
|
200
|
+
// Optionally wait for running jobs to complete
|
|
201
|
+
if (waitForJobs && this.runningJobs.size > 0) {
|
|
202
|
+
this.logger.info(
|
|
203
|
+
`Waiting for ${this.runningJobs.size} running job(s) to complete...`
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
const runningJobPromises = Array.from(this.runningJobs.values());
|
|
207
|
+
|
|
208
|
+
// Create a timeout promise
|
|
209
|
+
const timeoutPromise = new Promise<"timeout">((resolve) => {
|
|
210
|
+
setTimeout(() => resolve("timeout"), timeout);
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
// Race all running jobs against the timeout
|
|
214
|
+
const result = await Promise.race([
|
|
215
|
+
Promise.all(runningJobPromises).then(() => "completed" as const),
|
|
216
|
+
timeoutPromise,
|
|
217
|
+
]);
|
|
218
|
+
|
|
219
|
+
if (result === "timeout") {
|
|
220
|
+
const runningJobCount = this.runningJobs.size;
|
|
221
|
+
this.status = "stopped";
|
|
222
|
+
this.abortController = null;
|
|
223
|
+
this.logger.error(
|
|
224
|
+
`Shutdown timed out with ${runningJobCount} job(s) still running`
|
|
225
|
+
);
|
|
226
|
+
throw new SchedulerShutdownError(
|
|
227
|
+
`Scheduler shutdown timed out after ${timeout}ms with ${runningJobCount} job(s) still running`,
|
|
228
|
+
{ timedOut: true, runningJobCount }
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
this.logger.info("All running jobs completed");
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
this.status = "stopped";
|
|
236
|
+
this.abortController = null;
|
|
237
|
+
this.logger.info("Scheduler stopped");
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Update the list of agents to schedule
|
|
242
|
+
*
|
|
243
|
+
* Can be called while the scheduler is running to add/remove agents.
|
|
244
|
+
*/
|
|
245
|
+
setAgents(agents: ResolvedAgent[]): void {
|
|
246
|
+
this.agents = agents;
|
|
247
|
+
this.logger.debug(`Updated agents list: ${agents.length} agents`);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Main polling loop
|
|
252
|
+
*/
|
|
253
|
+
private async runLoop(): Promise<void> {
|
|
254
|
+
const signal = this.abortController?.signal;
|
|
255
|
+
|
|
256
|
+
while (this.status === "running" && !signal?.aborted) {
|
|
257
|
+
try {
|
|
258
|
+
await this.checkAllSchedules();
|
|
259
|
+
} catch (error) {
|
|
260
|
+
this.logger.error(
|
|
261
|
+
`Error during schedule check: ${error instanceof Error ? error.message : String(error)}`
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// Sleep until next check, but allow interruption via AbortController
|
|
266
|
+
if (this.status === "running" && !signal?.aborted) {
|
|
267
|
+
await this.sleep(this.checkInterval, signal);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Sleep for the specified duration, interruptible via AbortSignal
|
|
274
|
+
*/
|
|
275
|
+
private sleep(ms: number, signal?: AbortSignal): Promise<void> {
|
|
276
|
+
return new Promise((resolve) => {
|
|
277
|
+
const timeout = setTimeout(resolve, ms);
|
|
278
|
+
|
|
279
|
+
signal?.addEventListener(
|
|
280
|
+
"abort",
|
|
281
|
+
() => {
|
|
282
|
+
clearTimeout(timeout);
|
|
283
|
+
resolve();
|
|
284
|
+
},
|
|
285
|
+
{ once: true }
|
|
286
|
+
);
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Check all agents' schedules and trigger due ones
|
|
292
|
+
*/
|
|
293
|
+
private async checkAllSchedules(): Promise<void> {
|
|
294
|
+
this.checkCount++;
|
|
295
|
+
this.lastCheckAt = new Date().toISOString();
|
|
296
|
+
|
|
297
|
+
for (const agent of this.agents) {
|
|
298
|
+
if (!agent.schedules) {
|
|
299
|
+
continue;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
for (const [scheduleName, schedule] of Object.entries(agent.schedules)) {
|
|
303
|
+
const result = await this.checkSchedule(agent, scheduleName, schedule);
|
|
304
|
+
|
|
305
|
+
if (result.shouldTrigger) {
|
|
306
|
+
await this.triggerSchedule(agent, scheduleName, schedule);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Check if a single schedule should be triggered
|
|
314
|
+
*/
|
|
315
|
+
private async checkSchedule(
|
|
316
|
+
agent: ResolvedAgent,
|
|
317
|
+
scheduleName: string,
|
|
318
|
+
schedule: { type: string; interval?: string }
|
|
319
|
+
): Promise<ScheduleCheckResult> {
|
|
320
|
+
const baseResult = {
|
|
321
|
+
agentName: agent.name,
|
|
322
|
+
scheduleName,
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
// Skip non-interval schedule types (cron, webhook, chat reserved for future)
|
|
326
|
+
if (schedule.type !== "interval") {
|
|
327
|
+
return {
|
|
328
|
+
...baseResult,
|
|
329
|
+
shouldTrigger: false,
|
|
330
|
+
skipReason: "not_interval" as ScheduleSkipReason,
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// Get current schedule state
|
|
335
|
+
const stateLogger: ScheduleStateLogger = { warn: this.logger.warn };
|
|
336
|
+
const scheduleState = await getScheduleState(
|
|
337
|
+
this.stateDir,
|
|
338
|
+
agent.name,
|
|
339
|
+
scheduleName,
|
|
340
|
+
{ logger: stateLogger }
|
|
341
|
+
);
|
|
342
|
+
|
|
343
|
+
// Skip disabled schedules
|
|
344
|
+
if (scheduleState.status === "disabled") {
|
|
345
|
+
this.logger.debug(
|
|
346
|
+
`Skipping ${agent.name}/${scheduleName}: schedule is disabled`
|
|
347
|
+
);
|
|
348
|
+
return {
|
|
349
|
+
...baseResult,
|
|
350
|
+
shouldTrigger: false,
|
|
351
|
+
skipReason: "disabled" as ScheduleSkipReason,
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// Skip if already running (tracked locally)
|
|
356
|
+
const agentRunning = this.runningSchedules.get(agent.name);
|
|
357
|
+
if (agentRunning?.has(scheduleName)) {
|
|
358
|
+
this.logger.debug(
|
|
359
|
+
`Skipping ${agent.name}/${scheduleName}: already running`
|
|
360
|
+
);
|
|
361
|
+
return {
|
|
362
|
+
...baseResult,
|
|
363
|
+
shouldTrigger: false,
|
|
364
|
+
skipReason: "already_running" as ScheduleSkipReason,
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// Check max_concurrent capacity
|
|
369
|
+
const maxConcurrent = agent.session?.max_turns
|
|
370
|
+
? 1
|
|
371
|
+
: this.getMaxConcurrent(agent);
|
|
372
|
+
const runningCount = agentRunning?.size ?? 0;
|
|
373
|
+
|
|
374
|
+
if (runningCount >= maxConcurrent) {
|
|
375
|
+
this.logger.debug(
|
|
376
|
+
`Skipping ${agent.name}/${scheduleName}: at max capacity (${runningCount}/${maxConcurrent})`
|
|
377
|
+
);
|
|
378
|
+
return {
|
|
379
|
+
...baseResult,
|
|
380
|
+
shouldTrigger: false,
|
|
381
|
+
skipReason: "at_capacity" as ScheduleSkipReason,
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
// Calculate next trigger time
|
|
386
|
+
const lastRunAt = scheduleState.last_run_at
|
|
387
|
+
? new Date(scheduleState.last_run_at)
|
|
388
|
+
: null;
|
|
389
|
+
|
|
390
|
+
if (!schedule.interval) {
|
|
391
|
+
this.logger.warn(
|
|
392
|
+
`Skipping ${agent.name}/${scheduleName}: interval schedule missing interval value`
|
|
393
|
+
);
|
|
394
|
+
return {
|
|
395
|
+
...baseResult,
|
|
396
|
+
shouldTrigger: false,
|
|
397
|
+
skipReason: "not_interval" as ScheduleSkipReason,
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
const nextTrigger = calculateNextTrigger(lastRunAt, schedule.interval);
|
|
402
|
+
|
|
403
|
+
// Check if schedule is due
|
|
404
|
+
if (!isScheduleDue(nextTrigger)) {
|
|
405
|
+
return {
|
|
406
|
+
...baseResult,
|
|
407
|
+
shouldTrigger: false,
|
|
408
|
+
skipReason: "not_due" as ScheduleSkipReason,
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
return {
|
|
413
|
+
...baseResult,
|
|
414
|
+
shouldTrigger: true,
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* Get max_concurrent for an agent, defaulting to 1
|
|
420
|
+
*
|
|
421
|
+
* Reads from agent.instances.max_concurrent, which may come from:
|
|
422
|
+
* - Agent-specific config
|
|
423
|
+
* - Fleet defaults (merged during config loading)
|
|
424
|
+
*/
|
|
425
|
+
private getMaxConcurrent(agent: ResolvedAgent): number {
|
|
426
|
+
return agent.instances?.max_concurrent ?? 1;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* Get the count of currently running jobs for a specific agent
|
|
431
|
+
*
|
|
432
|
+
* This is useful for monitoring and debugging concurrency behavior.
|
|
433
|
+
*
|
|
434
|
+
* @param agentName - The name of the agent to check
|
|
435
|
+
* @returns The number of currently running jobs for this agent
|
|
436
|
+
*/
|
|
437
|
+
getRunningJobCount(agentName: string): number {
|
|
438
|
+
return this.runningSchedules.get(agentName)?.size ?? 0;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* Get the total count of running jobs across all agents
|
|
443
|
+
*
|
|
444
|
+
* This is useful for monitoring overall scheduler load.
|
|
445
|
+
*
|
|
446
|
+
* @returns The total number of currently running jobs
|
|
447
|
+
*/
|
|
448
|
+
getTotalRunningJobCount(): number {
|
|
449
|
+
return this.runningJobs.size;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* Trigger a schedule and update state
|
|
454
|
+
*/
|
|
455
|
+
private async triggerSchedule(
|
|
456
|
+
agent: ResolvedAgent,
|
|
457
|
+
scheduleName: string,
|
|
458
|
+
schedule: { type: string; interval?: string; prompt?: string }
|
|
459
|
+
): Promise<void> {
|
|
460
|
+
this.logger.info(`Triggering ${agent.name}/${scheduleName}`);
|
|
461
|
+
this.triggerCount++;
|
|
462
|
+
|
|
463
|
+
// Create a unique key for this job
|
|
464
|
+
const jobKey = `${agent.name}/${scheduleName}`;
|
|
465
|
+
|
|
466
|
+
// Mark schedule as running
|
|
467
|
+
if (!this.runningSchedules.has(agent.name)) {
|
|
468
|
+
this.runningSchedules.set(agent.name, new Set());
|
|
469
|
+
}
|
|
470
|
+
this.runningSchedules.get(agent.name)!.add(scheduleName);
|
|
471
|
+
|
|
472
|
+
const stateLogger: ScheduleStateLogger = { warn: this.logger.warn };
|
|
473
|
+
|
|
474
|
+
// Update schedule state to running
|
|
475
|
+
await updateScheduleState(
|
|
476
|
+
this.stateDir,
|
|
477
|
+
agent.name,
|
|
478
|
+
scheduleName,
|
|
479
|
+
{
|
|
480
|
+
status: "running",
|
|
481
|
+
last_run_at: new Date().toISOString(),
|
|
482
|
+
},
|
|
483
|
+
{ logger: stateLogger }
|
|
484
|
+
);
|
|
485
|
+
|
|
486
|
+
// Create and track the job promise
|
|
487
|
+
const jobPromise = this.executeJob(agent, scheduleName, schedule);
|
|
488
|
+
this.runningJobs.set(jobKey, jobPromise);
|
|
489
|
+
|
|
490
|
+
try {
|
|
491
|
+
await jobPromise;
|
|
492
|
+
} finally {
|
|
493
|
+
// Remove from running jobs tracking
|
|
494
|
+
this.runningJobs.delete(jobKey);
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
/**
|
|
499
|
+
* Execute the actual job logic
|
|
500
|
+
*/
|
|
501
|
+
private async executeJob(
|
|
502
|
+
agent: ResolvedAgent,
|
|
503
|
+
scheduleName: string,
|
|
504
|
+
schedule: { type: string; interval?: string; prompt?: string }
|
|
505
|
+
): Promise<void> {
|
|
506
|
+
const stateLogger: ScheduleStateLogger = { warn: this.logger.warn };
|
|
507
|
+
|
|
508
|
+
try {
|
|
509
|
+
// Get current schedule state for trigger info
|
|
510
|
+
const scheduleState = await getScheduleState(
|
|
511
|
+
this.stateDir,
|
|
512
|
+
agent.name,
|
|
513
|
+
scheduleName,
|
|
514
|
+
{ logger: stateLogger }
|
|
515
|
+
);
|
|
516
|
+
|
|
517
|
+
// Invoke the trigger callback if provided
|
|
518
|
+
if (this.onTrigger) {
|
|
519
|
+
const triggerInfo: TriggerInfo = {
|
|
520
|
+
agent,
|
|
521
|
+
scheduleName,
|
|
522
|
+
schedule: schedule as TriggerInfo["schedule"],
|
|
523
|
+
scheduleState,
|
|
524
|
+
};
|
|
525
|
+
|
|
526
|
+
await this.onTrigger(triggerInfo);
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
// Calculate next trigger time
|
|
530
|
+
const nextTrigger = schedule.interval
|
|
531
|
+
? calculateNextTrigger(new Date(), schedule.interval)
|
|
532
|
+
: null;
|
|
533
|
+
|
|
534
|
+
// Update schedule state to idle with next run time
|
|
535
|
+
await updateScheduleState(
|
|
536
|
+
this.stateDir,
|
|
537
|
+
agent.name,
|
|
538
|
+
scheduleName,
|
|
539
|
+
{
|
|
540
|
+
status: "idle",
|
|
541
|
+
next_run_at: nextTrigger?.toISOString() ?? null,
|
|
542
|
+
last_error: null,
|
|
543
|
+
},
|
|
544
|
+
{ logger: stateLogger }
|
|
545
|
+
);
|
|
546
|
+
|
|
547
|
+
this.logger.info(`Completed ${agent.name}/${scheduleName}`);
|
|
548
|
+
} catch (error) {
|
|
549
|
+
const errorMessage =
|
|
550
|
+
error instanceof Error ? error.message : String(error);
|
|
551
|
+
|
|
552
|
+
// Update schedule state with error
|
|
553
|
+
await updateScheduleState(
|
|
554
|
+
this.stateDir,
|
|
555
|
+
agent.name,
|
|
556
|
+
scheduleName,
|
|
557
|
+
{
|
|
558
|
+
status: "idle",
|
|
559
|
+
last_error: errorMessage,
|
|
560
|
+
},
|
|
561
|
+
{ logger: stateLogger }
|
|
562
|
+
);
|
|
563
|
+
|
|
564
|
+
this.logger.error(`Error in ${agent.name}/${scheduleName}: ${errorMessage}`);
|
|
565
|
+
} finally {
|
|
566
|
+
// Mark schedule as no longer running
|
|
567
|
+
this.runningSchedules.get(agent.name)?.delete(scheduleName);
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
}
|