@vercel/factory 0.0.13 → 0.0.15
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/README.md +307 -1
- package/dist/agent-routes.d.mts +69 -0
- package/dist/agent-routes.mjs +64 -0
- package/dist/agent-routes.mjs.map +1 -0
- package/dist/api-contracts.d.mts +1749 -0
- package/dist/api-contracts.mjs +118 -0
- package/dist/api-contracts.mjs.map +1 -0
- package/dist/api-images.d.mts +30 -0
- package/dist/api-images.mjs +28 -0
- package/dist/api-images.mjs.map +1 -0
- package/dist/api-task-graph.mjs +57 -0
- package/dist/api-task-graph.mjs.map +1 -0
- package/dist/api.d.mts +77 -0
- package/dist/api.mjs +1087 -0
- package/dist/api.mjs.map +1 -0
- package/dist/approval-access.d.mts +39 -0
- package/dist/approval-access.mjs +62 -0
- package/dist/approval-access.mjs.map +1 -0
- package/dist/approval-contracts.d.mts +692 -0
- package/dist/approval-contracts.mjs +27 -0
- package/dist/approval-contracts.mjs.map +1 -0
- package/dist/approval.d.mts +49 -0
- package/dist/approval.mjs +39 -0
- package/dist/approval.mjs.map +1 -0
- package/dist/blob/artifacts.d.mts +37 -0
- package/dist/blob/artifacts.mjs +45 -0
- package/dist/blob/artifacts.mjs.map +1 -0
- package/dist/blob/index.d.mts +44 -8
- package/dist/blob/index.mjs +159 -35
- package/dist/blob/index.mjs.map +1 -1
- package/dist/budget.d.mts +108 -0
- package/dist/budget.mjs +141 -0
- package/dist/budget.mjs.map +1 -0
- package/dist/budgets.d.mts +4 -0
- package/dist/budgets.mjs +4 -0
- package/dist/build-factory.d.mts +6 -4
- package/dist/build-factory.mjs +2 -1
- package/dist/build-factory.mjs.map +1 -1
- package/dist/change-verification/brief.d.mts +9 -0
- package/dist/change-verification/brief.mjs +13 -0
- package/dist/change-verification/brief.mjs.map +1 -0
- package/dist/change-verification/dispatch.d.mts +24 -0
- package/dist/change-verification/dispatch.mjs +45 -0
- package/dist/change-verification/dispatch.mjs.map +1 -0
- package/dist/change-verification/eve-tool.d.mts +60 -0
- package/dist/change-verification/eve-tool.mjs +101 -0
- package/dist/change-verification/eve-tool.mjs.map +1 -0
- package/dist/changes/eve-record-change.d.mts +56 -0
- package/dist/changes/eve-record-change.mjs +97 -0
- package/dist/changes/eve-record-change.mjs.map +1 -0
- package/dist/changes/presentation.d.mts +14 -0
- package/dist/changes.d.mts +23 -0
- package/dist/changes.mjs +29 -0
- package/dist/changes.mjs.map +1 -0
- package/dist/client-events.d.mts +18 -0
- package/dist/client-events.mjs +41 -0
- package/dist/client-events.mjs.map +1 -0
- package/dist/client-stream.d.mts +28 -0
- package/dist/client-stream.mjs +204 -0
- package/dist/client-stream.mjs.map +1 -0
- package/dist/client-transcript.d.mts +41 -0
- package/dist/client-transcript.mjs +229 -0
- package/dist/client-transcript.mjs.map +1 -0
- package/dist/client.d.mts +234 -0
- package/dist/client.mjs +258 -0
- package/dist/client.mjs.map +1 -0
- package/dist/code-review/contracts.d.mts +26 -0
- package/dist/code-review/eve-post-review.d.mts +70 -0
- package/dist/code-review/eve-post-review.mjs +183 -0
- package/dist/code-review/eve-post-review.mjs.map +1 -0
- package/dist/code-review/eve-review-comments.d.mts +64 -0
- package/dist/code-review/eve-review-comments.mjs +159 -0
- package/dist/code-review/eve-review-comments.mjs.map +1 -0
- package/dist/code-review/github-contracts.d.mts +10 -0
- package/dist/code-review/github-reporter.d.mts +44 -0
- package/dist/code-review/github-reporter.mjs +260 -0
- package/dist/code-review/github-reporter.mjs.map +1 -0
- package/dist/code-review/preparation.d.mts +34 -0
- package/dist/code-review/preparation.mjs +23 -0
- package/dist/code-review/preparation.mjs.map +1 -0
- package/dist/code-review/stall.d.mts +17 -0
- package/dist/code-review/stall.mjs +30 -0
- package/dist/code-review/stall.mjs.map +1 -0
- package/dist/code-review.d.mts +6 -0
- package/dist/code-review.mjs +5 -0
- package/dist/communication.d.mts +9 -0
- package/dist/communication.mjs +9 -0
- package/dist/connectors/github.d.mts +26 -0
- package/dist/connectors/github.mjs +55 -0
- package/dist/connectors/github.mjs.map +1 -0
- package/dist/connectors/index.d.mts +35 -2
- package/dist/connectors/index.mjs +4 -26
- package/dist/connectors/index.mjs.map +1 -1
- package/dist/connectors/outbox.d.mts +34 -0
- package/dist/connectors/outbox.mjs +50 -0
- package/dist/connectors/outbox.mjs.map +1 -0
- package/dist/connectors/slack-approval-blocks.mjs +136 -0
- package/dist/connectors/slack-approval-blocks.mjs.map +1 -0
- package/dist/connectors/slack-approvals.d.mts +29 -0
- package/dist/connectors/slack-approvals.mjs +346 -0
- package/dist/connectors/slack-approvals.mjs.map +1 -0
- package/dist/connectors/slack.d.mts +35 -41
- package/dist/connectors/slack.mjs +13 -69
- package/dist/connectors/slack.mjs.map +1 -1
- package/dist/deepsec/eve-tool.d.mts +110 -0
- package/dist/deepsec/eve-tool.mjs +164 -0
- package/dist/deepsec/eve-tool.mjs.map +1 -0
- package/dist/deepsec/finding.d.mts +84 -0
- package/dist/deepsec/finding.mjs +56 -0
- package/dist/deepsec/finding.mjs.map +1 -0
- package/dist/deepsec.d.mts +3 -0
- package/dist/delivery-metrics/metrics.d.mts +93 -0
- package/dist/delivery-metrics/metrics.mjs +200 -0
- package/dist/delivery-metrics/metrics.mjs.map +1 -0
- package/dist/delivery-metrics.d.mts +2 -0
- package/dist/delivery-metrics.mjs +2 -0
- package/dist/dispatch.d.mts +81 -0
- package/dist/dispatch.mjs +140 -0
- package/dist/dispatch.mjs.map +1 -0
- package/dist/errors.d.mts +15 -0
- package/dist/errors.mjs +38 -0
- package/dist/errors.mjs.map +1 -0
- package/dist/eve/index.d.mts +143 -1561
- package/dist/eve/index.mjs +244 -1063
- package/dist/eve/index.mjs.map +1 -1
- package/dist/eve/invoke.d.mts +144 -0
- package/dist/eve/invoke.mjs +241 -0
- package/dist/eve/invoke.mjs.map +1 -0
- package/dist/eve/session-client.d.mts +68 -0
- package/dist/eve/session-client.mjs +131 -0
- package/dist/eve/session-client.mjs.map +1 -0
- package/dist/eve/task-execution.mjs +18 -0
- package/dist/eve/task-execution.mjs.map +1 -0
- package/dist/eve/task-session.d.mts +87 -0
- package/dist/eve/task-session.mjs +203 -0
- package/dist/eve/task-session.mjs.map +1 -0
- package/dist/eve/transcript.d.mts +37 -0
- package/dist/eve/transcript.mjs +65 -0
- package/dist/eve/transcript.mjs.map +1 -0
- package/dist/execution-public.d.mts +8 -0
- package/dist/execution-public.mjs +7 -0
- package/dist/execution.d.mts +75 -0
- package/dist/execution.mjs +153 -0
- package/dist/execution.mjs.map +1 -0
- package/dist/finding-remediation/admission.d.mts +51 -0
- package/dist/finding-remediation/admission.mjs +87 -0
- package/dist/finding-remediation/admission.mjs.map +1 -0
- package/dist/finding-remediation/brief.d.mts +14 -0
- package/dist/finding-remediation/brief.mjs +25 -0
- package/dist/finding-remediation/brief.mjs.map +1 -0
- package/dist/finding-remediation/eve-tool.d.mts +29 -0
- package/dist/finding-remediation/eve-tool.mjs +34 -0
- package/dist/finding-remediation/eve-tool.mjs.map +1 -0
- package/dist/findings/fingerprint.d.mts +14 -0
- package/dist/findings/fingerprint.mjs +28 -0
- package/dist/findings/fingerprint.mjs.map +1 -0
- package/dist/findings.d.mts +6 -0
- package/dist/findings.mjs +6 -0
- package/dist/github-app.d.mts +54 -0
- package/dist/github-app.mjs +121 -0
- package/dist/github-app.mjs.map +1 -0
- package/dist/github-publication.d.mts +198 -0
- package/dist/github-publication.mjs +429 -0
- package/dist/github-publication.mjs.map +1 -0
- package/dist/github-transfer.d.mts +72 -0
- package/dist/github-transfer.mjs +125 -0
- package/dist/github-transfer.mjs.map +1 -0
- package/dist/github.d.mts +406 -2
- package/dist/github.mjs +250 -37
- package/dist/github.mjs.map +1 -1
- package/dist/image-input.d.mts +51 -0
- package/dist/image-input.mjs +63 -0
- package/dist/image-input.mjs.map +1 -0
- package/dist/index.d.mts +14 -314
- package/dist/index.mjs +14 -1124
- package/dist/intake-contracts.d.mts +56 -0
- package/dist/intake-contracts.mjs +33 -0
- package/dist/intake-contracts.mjs.map +1 -0
- package/dist/integrations/deepsec.d.mts +4 -0
- package/dist/integrations/deepsec.mjs +3 -0
- package/dist/integrations/github.d.mts +11 -0
- package/dist/integrations/github.mjs +9 -0
- package/dist/integrations/slack.d.mts +3 -0
- package/dist/integrations/slack.mjs +3 -0
- package/dist/integrations/vercel.d.mts +3 -0
- package/dist/integrations/vercel.mjs +3 -0
- package/dist/merge-resolution/contracts.d.mts +17 -0
- package/dist/merge-resolution/contracts.mjs +19 -0
- package/dist/merge-resolution/contracts.mjs.map +1 -0
- package/dist/merge-resolution/eve-tools.d.mts +46 -0
- package/dist/merge-resolution/eve-tools.mjs +117 -0
- package/dist/merge-resolution/eve-tools.mjs.map +1 -0
- package/dist/multi-repository-changes/coordination.d.mts +49 -0
- package/dist/multi-repository-changes/coordination.mjs +115 -0
- package/dist/multi-repository-changes/coordination.mjs.map +1 -0
- package/dist/planning/cancellation.mjs +82 -0
- package/dist/planning/cancellation.mjs.map +1 -0
- package/dist/planning/configuration.d.mts +23 -0
- package/dist/planning/configuration.mjs +56 -0
- package/dist/planning/configuration.mjs.map +1 -0
- package/dist/planning/contracts.d.mts +136 -0
- package/dist/planning/contracts.mjs +42 -0
- package/dist/planning/contracts.mjs.map +1 -0
- package/dist/planning/dependencies.mjs +44 -0
- package/dist/planning/dependencies.mjs.map +1 -0
- package/dist/planning/effects.mjs +122 -0
- package/dist/planning/effects.mjs.map +1 -0
- package/dist/planning/reconcile.mjs +273 -0
- package/dist/planning/reconcile.mjs.map +1 -0
- package/dist/planning/runtime.d.mts +27 -0
- package/dist/planning/runtime.mjs +25 -0
- package/dist/planning/runtime.mjs.map +1 -0
- package/dist/planning/state.mjs +92 -0
- package/dist/planning/state.mjs.map +1 -0
- package/dist/planning/turns.mjs +262 -0
- package/dist/planning/turns.mjs.map +1 -0
- package/dist/planning/validation.mjs +106 -0
- package/dist/planning/validation.mjs.map +1 -0
- package/dist/postgres/index.d.mts +7 -1
- package/dist/postgres/index.mjs +7 -3
- package/dist/postgres/index.mjs.map +1 -1
- package/dist/presets/software-development/approval.d.mts +14 -0
- package/dist/presets/software-development/approval.mjs +21 -0
- package/dist/presets/software-development/approval.mjs.map +1 -0
- package/dist/presets/software-development/deepsec-brief.d.mts +8 -0
- package/dist/presets/software-development/deepsec-brief.mjs +14 -0
- package/dist/presets/software-development/deepsec-brief.mjs.map +1 -0
- package/dist/presets/software-development/dispatch.d.mts +53 -0
- package/dist/presets/software-development/dispatch.mjs +66 -0
- package/dist/presets/software-development/dispatch.mjs.map +1 -0
- package/dist/presets/software-development/eve-delegation-policy.d.mts +7 -0
- package/dist/presets/software-development/eve-delegation-policy.mjs +34 -0
- package/dist/presets/software-development/eve-delegation-policy.mjs.map +1 -0
- package/dist/presets/software-development/eve.d.mts +18 -0
- package/dist/presets/software-development/eve.mjs +19 -0
- package/dist/presets/software-development/eve.mjs.map +1 -0
- package/dist/presets/software-development/finish-task-policy.d.mts +7 -0
- package/dist/presets/software-development/finish-task-policy.mjs +9 -0
- package/dist/presets/software-development/finish-task-policy.mjs.map +1 -0
- package/dist/presets/software-development/recovery.d.mts +32 -0
- package/dist/presets/software-development/recovery.mjs +120 -0
- package/dist/presets/software-development/recovery.mjs.map +1 -0
- package/dist/presets/software-development/task-communication.d.mts +23 -0
- package/dist/presets/software-development/task-communication.mjs +120 -0
- package/dist/presets/software-development/task-communication.mjs.map +1 -0
- package/dist/presets/software-development.d.mts +9 -0
- package/dist/presets/software-development.mjs +9 -0
- package/dist/pull-requests/contracts.d.mts +72 -0
- package/dist/pull-requests/eve-fetch.d.mts +57 -0
- package/dist/pull-requests/eve-fetch.mjs +151 -0
- package/dist/pull-requests/eve-fetch.mjs.map +1 -0
- package/dist/pull-requests/github-label-manager.d.mts +27 -0
- package/dist/pull-requests/github-label-manager.mjs +40 -0
- package/dist/pull-requests/github-label-manager.mjs.map +1 -0
- package/dist/pull-requests/github-publisher.d.mts +53 -0
- package/dist/pull-requests/github-publisher.mjs +345 -0
- package/dist/pull-requests/github-publisher.mjs.map +1 -0
- package/dist/pull-requests.d.mts +5 -0
- package/dist/pull-requests.mjs +4 -0
- package/dist/receipts.d.mts +4 -0
- package/dist/receipts.mjs +3 -0
- package/dist/repositories.d.mts +18 -0
- package/dist/repositories.mjs +33 -0
- package/dist/repositories.mjs.map +1 -0
- package/dist/sandbox/command.d.mts +18 -0
- package/dist/sandbox/execution-abort.d.mts +16 -0
- package/dist/sandbox/execution-abort.mjs +49 -0
- package/dist/sandbox/execution-abort.mjs.map +1 -0
- package/dist/sandbox/execution-environment.d.mts +25 -0
- package/dist/sandbox/execution-run-ledger.d.mts +115 -0
- package/dist/sandbox/execution-run-ledger.mjs +209 -0
- package/dist/sandbox/execution-run-ledger.mjs.map +1 -0
- package/dist/sandbox/execution.d.mts +54 -0
- package/dist/sandbox/execution.mjs +228 -0
- package/dist/sandbox/execution.mjs.map +1 -0
- package/dist/sandbox/harness-runner.d.mts +79 -0
- package/dist/sandbox/harness-runner.mjs +162 -0
- package/dist/sandbox/harness-runner.mjs.map +1 -0
- package/dist/sandbox/index.d.mts +9 -0
- package/dist/sandbox/index.mjs +7 -0
- package/dist/sandbox/task-environment.d.mts +50 -0
- package/dist/sandbox/task-environment.mjs +140 -0
- package/dist/sandbox/task-environment.mjs.map +1 -0
- package/dist/sandbox/workspace.d.mts +29 -0
- package/dist/sandbox/workspace.mjs +28 -0
- package/dist/sandbox/workspace.mjs.map +1 -0
- package/dist/schema/agent-route.d.mts +22 -0
- package/dist/schema/agent-route.mjs +15 -0
- package/dist/schema/agent-route.mjs.map +1 -0
- package/dist/schema/answer.d.mts +23 -0
- package/dist/schema/answer.mjs +21 -0
- package/dist/schema/answer.mjs.map +1 -0
- package/dist/schema/budget.d.mts +38 -0
- package/dist/schema/budget.mjs +30 -0
- package/dist/schema/budget.mjs.map +1 -0
- package/dist/schema/catalog.mjs +72 -0
- package/dist/schema/catalog.mjs.map +1 -0
- package/dist/schema/change.d.mts +117 -0
- package/dist/schema/change.mjs +68 -0
- package/dist/schema/change.mjs.map +1 -0
- package/dist/schema/common.d.mts +33 -0
- package/dist/{id-DwCihQr4.mjs → schema/common.mjs} +7 -14
- package/dist/schema/common.mjs.map +1 -0
- package/dist/schema/communication.d.mts +52 -0
- package/dist/schema/communication.mjs +35 -0
- package/dist/schema/communication.mjs.map +1 -0
- package/dist/schema/execution.d.mts +101 -0
- package/dist/schema/execution.mjs +86 -0
- package/dist/schema/execution.mjs.map +1 -0
- package/dist/schema/factory-config.d.mts +95 -0
- package/dist/schema/factory-config.mjs +60 -0
- package/dist/schema/factory-config.mjs.map +1 -0
- package/dist/schema/finding.d.mts +125 -0
- package/dist/schema/finding.mjs +67 -0
- package/dist/schema/finding.mjs.map +1 -0
- package/dist/schema/id.d.mts +43 -0
- package/dist/schema/id.mjs +32 -0
- package/dist/schema/id.mjs.map +1 -0
- package/dist/schema/outbox.d.mts +240 -0
- package/dist/schema/outbox.mjs +53 -0
- package/dist/schema/outbox.mjs.map +1 -0
- package/dist/schema/question-route.mjs +16 -0
- package/dist/schema/question-route.mjs.map +1 -0
- package/dist/schema/receipt.d.mts +81 -0
- package/dist/schema/receipt.mjs +94 -0
- package/dist/schema/receipt.mjs.map +1 -0
- package/dist/schema/repository.d.mts +26 -0
- package/dist/schema/repository.mjs +25 -0
- package/dist/schema/repository.mjs.map +1 -0
- package/dist/schema/session.d.mts +135 -0
- package/dist/schema/session.mjs +53 -0
- package/dist/schema/session.mjs.map +1 -0
- package/dist/schema/signal.d.mts +105 -0
- package/dist/schema/signal.mjs +81 -0
- package/dist/schema/signal.mjs.map +1 -0
- package/dist/schema/stored-session.mjs +10 -0
- package/dist/schema/stored-session.mjs.map +1 -0
- package/dist/schema/stored-task.mjs +20 -0
- package/dist/schema/stored-task.mjs.map +1 -0
- package/dist/schema/task-effect.d.mts +39 -0
- package/dist/schema/task-effect.mjs +29 -0
- package/dist/schema/task-effect.mjs.map +1 -0
- package/dist/schema/task-graph.d.mts +3134 -0
- package/dist/schema/task-graph.mjs +97 -0
- package/dist/schema/task-graph.mjs.map +1 -0
- package/dist/schema/task-message.d.mts +254 -0
- package/dist/schema/task-message.mjs +189 -0
- package/dist/schema/task-message.mjs.map +1 -0
- package/dist/schema/task.d.mts +272 -0
- package/dist/schema/task.mjs +199 -0
- package/dist/schema/task.mjs.map +1 -0
- package/dist/schema/transcript.d.mts +170 -0
- package/dist/schema/transcript.mjs +86 -0
- package/dist/schema/transcript.mjs.map +1 -0
- package/dist/schema/transitions.d.mts +50 -0
- package/dist/schema/transitions.mjs +303 -0
- package/dist/schema/transitions.mjs.map +1 -0
- package/dist/schema/work.d.mts +101 -0
- package/dist/schema/work.mjs +102 -0
- package/dist/schema/work.mjs.map +1 -0
- package/dist/signal-triage.d.mts +20 -0
- package/dist/signal-triage.mjs +85 -0
- package/dist/signal-triage.mjs.map +1 -0
- package/dist/signals.d.mts +19 -0
- package/dist/signals.mjs +19 -0
- package/dist/signals.mjs.map +1 -0
- package/dist/stall.d.mts +38 -0
- package/dist/stall.mjs +79 -0
- package/dist/stall.mjs.map +1 -0
- package/dist/storage.d.mts +4 -0
- package/dist/storage.mjs +4 -0
- package/dist/store/driver.d.mts +65 -0
- package/dist/store/driver.mjs +42 -0
- package/dist/store/driver.mjs.map +1 -0
- package/dist/store/engine.d.mts +485 -0
- package/dist/store/engine.mjs +2175 -0
- package/dist/store/engine.mjs.map +1 -0
- package/dist/store/memory.d.mts +7 -0
- package/dist/store/memory.mjs +52 -0
- package/dist/store/memory.mjs.map +1 -0
- package/dist/store/task-effects.d.mts +38 -0
- package/dist/store/task-effects.mjs +118 -0
- package/dist/store/task-effects.mjs.map +1 -0
- package/dist/store/task-graphs.d.mts +60 -0
- package/dist/store/task-graphs.mjs +212 -0
- package/dist/store/task-graphs.mjs.map +1 -0
- package/dist/store/task-messages.d.mts +136 -0
- package/dist/store/task-messages.mjs +475 -0
- package/dist/store/task-messages.mjs.map +1 -0
- package/dist/store/task-work.d.mts +65 -0
- package/dist/store/task-work.mjs +134 -0
- package/dist/store/task-work.mjs.map +1 -0
- package/dist/store/work-notifications.d.mts +19 -0
- package/dist/store/work-notifications.mjs +48 -0
- package/dist/store/work-notifications.mjs.map +1 -0
- package/dist/sweep.d.mts +57 -0
- package/dist/sweep.mjs +143 -0
- package/dist/sweep.mjs.map +1 -0
- package/dist/task-communication.d.mts +35 -0
- package/dist/task-communication.mjs +47 -0
- package/dist/task-communication.mjs.map +1 -0
- package/dist/task-graph-view.d.mts +264 -0
- package/dist/task-graph-view.mjs +17 -0
- package/dist/task-graph-view.mjs.map +1 -0
- package/dist/task-message-processing.d.mts +60 -0
- package/dist/task-message-processing.mjs +200 -0
- package/dist/task-message-processing.mjs.map +1 -0
- package/dist/task-protocols.d.mts +80 -0
- package/dist/task-protocols.mjs +47 -0
- package/dist/task-protocols.mjs.map +1 -0
- package/dist/tasks.d.mts +17 -0
- package/dist/tasks.mjs +17 -0
- package/dist/vercel-git.d.mts +21 -0
- package/dist/vercel-git.mjs +112 -0
- package/dist/vercel-git.mjs.map +1 -0
- package/dist/vercel.d.mts +33 -2
- package/dist/vercel.mjs +48 -3
- package/dist/vercel.mjs.map +1 -1
- package/dist/work-triage/eve-tool.d.mts +29 -0
- package/dist/work-triage/eve-tool.mjs +32 -0
- package/dist/work-triage/eve-tool.mjs.map +1 -0
- package/dist/work-triage/find-existing-work.d.mts +32 -0
- package/dist/work-triage/find-existing-work.mjs +31 -0
- package/dist/work-triage/find-existing-work.mjs.map +1 -0
- package/dist/work-triage/github.d.mts +15 -0
- package/dist/work-triage/github.mjs +14 -0
- package/dist/work-triage/github.mjs.map +1 -0
- package/dist/work-triage.d.mts +3 -0
- package/dist/work-triage.mjs +3 -0
- package/dist/workflows.d.mts +48 -0
- package/dist/workflows.mjs +86 -0
- package/dist/workflows.mjs.map +1 -0
- package/dist/workspace-diff-assembly.d.mts +33 -0
- package/dist/workspace-diff-assembly.mjs +95 -0
- package/dist/workspace-diff-assembly.mjs.map +1 -0
- package/dist/workspace-diff.d.mts +90 -0
- package/dist/workspace-diff.mjs +61 -0
- package/dist/workspace-diff.mjs.map +1 -0
- package/dist/workspace-snapshot.d.mts +26 -0
- package/dist/workspace-snapshot.mjs +80 -0
- package/dist/workspace-snapshot.mjs.map +1 -0
- package/package.json +129 -40
- package/dist/approval-CwhTP1XB.mjs +0 -269
- package/dist/approval-CwhTP1XB.mjs.map +0 -1
- package/dist/change-CzEAoFVE.mjs +0 -620
- package/dist/change-CzEAoFVE.mjs.map +0 -1
- package/dist/dispatch-B77cuPxh.d.mts +0 -713
- package/dist/driver-BJutB0PE.d.mts +0 -34
- package/dist/driver-Bbd25rNM.mjs +0 -23
- package/dist/driver-Bbd25rNM.mjs.map +0 -1
- package/dist/factory-config-BJcjsPKl.mjs +0 -86
- package/dist/factory-config-BJcjsPKl.mjs.map +0 -1
- package/dist/factory-config-D2yU3G0c.d.mts +0 -58
- package/dist/github-DXsxboUL.d.mts +0 -271
- package/dist/id-DwCihQr4.mjs.map +0 -1
- package/dist/index-Cy4jfXh5.d.mts +0 -67
- package/dist/index.mjs.map +0 -1
- package/dist/signal-CHVEmzvI.d.mts +0 -59
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { AgentRouteBinding } from "./agent-route.mjs";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
//#region src/schema/work.d.ts
|
|
4
|
+
/** Finite JSON data accepted at persisted workflow boundaries. */
|
|
5
|
+
type JsonValue = null | boolean | number | string | readonly JsonValue[] | {
|
|
6
|
+
readonly [key: string]: JsonValue;
|
|
7
|
+
};
|
|
8
|
+
declare const workflowInputType: unique symbol;
|
|
9
|
+
declare const workflowOutputType: unique symbol;
|
|
10
|
+
/** Exact workflow identity carrying its input and output types for safe construction. */
|
|
11
|
+
type WorkflowBinding<Input extends JsonValue = JsonValue, Output extends JsonValue = JsonValue, Id extends string = string, Version extends number = number> = z.infer<typeof workflowBindingSchema> & {
|
|
12
|
+
readonly id: Id;
|
|
13
|
+
readonly version: Version;
|
|
14
|
+
readonly [workflowInputType]?: Input;
|
|
15
|
+
readonly [workflowOutputType]?: Output;
|
|
16
|
+
};
|
|
17
|
+
/** Definition-like value exposing an exact typed workflow binding. */
|
|
18
|
+
interface WorkflowReference<InputSchema extends z.ZodType = z.ZodType, Binding extends WorkflowBinding = WorkflowBinding> {
|
|
19
|
+
readonly binding: Binding;
|
|
20
|
+
readonly input: InputSchema;
|
|
21
|
+
}
|
|
22
|
+
/** Input type carried by a definition-like workflow reference. */
|
|
23
|
+
type WorkflowReferenceInput<Reference extends WorkflowReference> = z.input<Reference["input"]> & JsonValue;
|
|
24
|
+
/** Maximum serialized UTF-8 size of workflow input, output, or message JSON. */
|
|
25
|
+
declare const MAX_WORK_JSON_BYTES: number;
|
|
26
|
+
/** Maximum nesting depth below the root of persisted workflow JSON. */
|
|
27
|
+
declare const MAX_WORK_JSON_DEPTH = 32;
|
|
28
|
+
/** Validates bounded canonical JSON without cycles, accessors, or sparse arrays. */
|
|
29
|
+
declare const jsonValueSchema: z.ZodCustom<JsonValue, JsonValue>;
|
|
30
|
+
/** Validates an exact workflow identifier and positive integer version. */
|
|
31
|
+
declare const workflowBindingSchema: z.core.$ZodBranded<z.ZodObject<{
|
|
32
|
+
id: z.ZodString;
|
|
33
|
+
version: z.ZodNumber;
|
|
34
|
+
}, z.core.$strict>, "WorkflowBinding", "out">;
|
|
35
|
+
/** Plain identifier and version accepted when constructing a workflow binding. */
|
|
36
|
+
interface WorkflowBindingInput<Id extends string = string, Version extends number = number> {
|
|
37
|
+
readonly id: Id;
|
|
38
|
+
readonly version: Version;
|
|
39
|
+
}
|
|
40
|
+
/** Validates and brands an exact workflow binding while preserving literal identity. */
|
|
41
|
+
declare function parseWorkflowBinding<const Input extends WorkflowBindingInput>(input: Input): WorkflowBinding<JsonValue, JsonValue, Input["id"], Input["version"]>;
|
|
42
|
+
/** Validates the required versioned input and completion contract for a Task. */
|
|
43
|
+
declare const taskWorkSchema: z.ZodObject<{
|
|
44
|
+
title: z.ZodString;
|
|
45
|
+
input: z.ZodCustom<JsonValue, JsonValue>;
|
|
46
|
+
completionCriteria: z.ZodReadonly<z.ZodArray<z.ZodString>>;
|
|
47
|
+
workflow: z.core.$ZodBranded<z.ZodObject<{
|
|
48
|
+
id: z.ZodString;
|
|
49
|
+
version: z.ZodNumber;
|
|
50
|
+
}, z.core.$strict>, "WorkflowBinding", "out">;
|
|
51
|
+
route: z.ZodOptional<z.core.$ZodBranded<z.ZodObject<{
|
|
52
|
+
id: z.ZodString;
|
|
53
|
+
version: z.ZodNumber;
|
|
54
|
+
}, z.core.$strict>, "AgentRouteBinding", "out">>;
|
|
55
|
+
}, z.core.$strict>;
|
|
56
|
+
/** Validates canonical output recorded when workflow work completes. */
|
|
57
|
+
declare const taskWorkResultSchema: z.ZodObject<{
|
|
58
|
+
output: z.ZodCustom<JsonValue, JsonValue>;
|
|
59
|
+
completedAt: z.ZodISODateTime;
|
|
60
|
+
}, z.core.$strict>;
|
|
61
|
+
/** Required title, typed input, criteria, workflow, and optional route contract of a Task. */
|
|
62
|
+
interface TaskWork<Input extends JsonValue = JsonValue, Workflow extends WorkflowBinding = WorkflowBinding> {
|
|
63
|
+
readonly title: string;
|
|
64
|
+
readonly input: Input;
|
|
65
|
+
readonly completionCriteria: readonly string[];
|
|
66
|
+
readonly workflow: Workflow;
|
|
67
|
+
readonly route?: AgentRouteBinding;
|
|
68
|
+
}
|
|
69
|
+
/** Validated canonical output and completion timestamp of succeeded workflow work. */
|
|
70
|
+
type TaskWorkResult = z.infer<typeof taskWorkResultSchema>;
|
|
71
|
+
/** Named fields for constructing generic `task@1` work. */
|
|
72
|
+
interface TaskWorkOptions<Input extends JsonValue = JsonValue> {
|
|
73
|
+
readonly title: string;
|
|
74
|
+
readonly input?: Input;
|
|
75
|
+
readonly workflow?: never;
|
|
76
|
+
readonly route?: never;
|
|
77
|
+
readonly completionCriteria?: never;
|
|
78
|
+
}
|
|
79
|
+
/** Named fields for constructing work owned by an exact workflow contract. */
|
|
80
|
+
interface WorkflowTaskWorkOptions<Input extends JsonValue = JsonValue, Workflow extends WorkflowBinding | WorkflowReference = WorkflowBinding | WorkflowReference> {
|
|
81
|
+
readonly title: string;
|
|
82
|
+
readonly input: Input;
|
|
83
|
+
readonly workflow: Workflow;
|
|
84
|
+
readonly route?: never;
|
|
85
|
+
readonly completionCriteria?: never;
|
|
86
|
+
}
|
|
87
|
+
/** Constructs generic `task@1` work with an empty completion-criteria list. */
|
|
88
|
+
declare function taskWork<const Input extends JsonValue = JsonValue>(options: TaskWorkOptions<Input>): TaskWork<Input>;
|
|
89
|
+
/** Constructs work from a definition-like reference with a typed exact workflow binding. */
|
|
90
|
+
declare function taskWork<InputSchema extends z.ZodType, Binding extends WorkflowBinding>(options: WorkflowTaskWorkOptions<NoInfer<z.input<InputSchema>> & JsonValue, {
|
|
91
|
+
readonly input: InputSchema;
|
|
92
|
+
readonly binding: Binding;
|
|
93
|
+
}>): TaskWork<z.input<InputSchema> & JsonValue, Binding>;
|
|
94
|
+
/** Constructs work from an exact typed workflow binding. */
|
|
95
|
+
declare function taskWork<Input extends JsonValue, Output extends JsonValue, const Id extends string, const Version extends number>(options: WorkflowTaskWorkOptions<NoInfer<Input>, WorkflowBinding<Input, Output, Id, Version> & {
|
|
96
|
+
readonly binding?: never;
|
|
97
|
+
readonly input?: never;
|
|
98
|
+
}>): TaskWork<Input, WorkflowBinding<Input, Output, Id, Version>>;
|
|
99
|
+
//#endregion
|
|
100
|
+
export { JsonValue, MAX_WORK_JSON_BYTES, MAX_WORK_JSON_DEPTH, TaskWork, TaskWorkOptions, TaskWorkResult, WorkflowBinding, WorkflowBindingInput, WorkflowReference, WorkflowReferenceInput, WorkflowTaskWorkOptions, jsonValueSchema, parseWorkflowBinding, taskWork, taskWorkResultSchema, taskWorkSchema, workflowBindingSchema };
|
|
101
|
+
//# sourceMappingURL=work.d.mts.map
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { isoDateTimeSchema } from "./common.mjs";
|
|
2
|
+
import { agentRouteBindingSchema } from "./agent-route.mjs";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
//#region src/schema/work.ts
|
|
5
|
+
/** Maximum serialized UTF-8 size of workflow input, output, or message JSON. */
|
|
6
|
+
const MAX_WORK_JSON_BYTES = 65536;
|
|
7
|
+
/** Maximum nesting depth below the root of persisted workflow JSON. */
|
|
8
|
+
const MAX_WORK_JSON_DEPTH = 32;
|
|
9
|
+
const encoder = new TextEncoder();
|
|
10
|
+
function isBoundedJson(value) {
|
|
11
|
+
let bytes = 0;
|
|
12
|
+
const ancestors = /* @__PURE__ */ new Set();
|
|
13
|
+
const addBytes = (count) => {
|
|
14
|
+
bytes += count;
|
|
15
|
+
return bytes <= MAX_WORK_JSON_BYTES;
|
|
16
|
+
};
|
|
17
|
+
const stringFits = (text) => text.length <= 65536 && addBytes(encoder.encode(JSON.stringify(text)).byteLength);
|
|
18
|
+
const visit = (entry, depth) => {
|
|
19
|
+
if (depth > 32) return false;
|
|
20
|
+
if (entry === null) return addBytes(4);
|
|
21
|
+
if (typeof entry === "boolean") return addBytes(entry ? 4 : 5);
|
|
22
|
+
if (typeof entry === "string") return stringFits(entry);
|
|
23
|
+
if (typeof entry === "number") return Number.isFinite(entry) && addBytes(JSON.stringify(entry).length);
|
|
24
|
+
if (typeof entry !== "object" || ancestors.has(entry)) return false;
|
|
25
|
+
const array = Array.isArray(entry);
|
|
26
|
+
const prototype = Object.getPrototypeOf(entry);
|
|
27
|
+
if (array ? prototype !== Array.prototype : prototype !== Object.prototype && prototype !== null) return false;
|
|
28
|
+
if (!addBytes(2)) return false;
|
|
29
|
+
ancestors.add(entry);
|
|
30
|
+
const keys = Reflect.ownKeys(entry);
|
|
31
|
+
if (array) {
|
|
32
|
+
if (entry.length > 65536 || keys.length !== entry.length + 1) return false;
|
|
33
|
+
for (let index = 0; index < entry.length; index++) {
|
|
34
|
+
const descriptor = Object.getOwnPropertyDescriptor(entry, String(index));
|
|
35
|
+
if (!descriptor || !descriptor.enumerable || !("value" in descriptor)) return false;
|
|
36
|
+
if (index > 0 && !addBytes(1)) return false;
|
|
37
|
+
if (!visit(descriptor.value, depth + 1)) return false;
|
|
38
|
+
}
|
|
39
|
+
} else for (const [index, key] of keys.entries()) {
|
|
40
|
+
if (typeof key !== "string") return false;
|
|
41
|
+
const descriptor = Object.getOwnPropertyDescriptor(entry, key);
|
|
42
|
+
if (!descriptor || !descriptor.enumerable || !("value" in descriptor)) return false;
|
|
43
|
+
if (index > 0 && !addBytes(1)) return false;
|
|
44
|
+
if (!stringFits(key) || !addBytes(1) || !visit(descriptor.value, depth + 1)) return false;
|
|
45
|
+
}
|
|
46
|
+
ancestors.delete(entry);
|
|
47
|
+
return true;
|
|
48
|
+
};
|
|
49
|
+
try {
|
|
50
|
+
return visit(value, 0);
|
|
51
|
+
} catch {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/** Validates bounded canonical JSON without cycles, accessors, or sparse arrays. */
|
|
56
|
+
const jsonValueSchema = z.custom(isBoundedJson, { message: `Expected finite JSON with at most ${MAX_WORK_JSON_BYTES} UTF-8 bytes and depth 32; cycles, accessors, sparse arrays, and non-JSON properties are not allowed` }).describe("Finite JSON value, at most 64 KiB serialized UTF-8 and 32 levels below the root.");
|
|
57
|
+
/** Validates an exact workflow identifier and positive integer version. */
|
|
58
|
+
const workflowBindingSchema = z.strictObject({
|
|
59
|
+
id: z.string().max(64).regex(/^[a-z][a-z0-9]*(?:[-_][a-z0-9]+)*$/, "Expected a lowercase hyphenated or snake_case workflow name").describe("Registered workflow name, starting with a lowercase letter; at most 64 characters."),
|
|
60
|
+
version: z.number().int().positive().describe("Exact positive integer version of the registered workflow.")
|
|
61
|
+
}).describe("Explicit workflow identity and version; never resolved to an implicit latest version.").brand();
|
|
62
|
+
/** Validates and brands an exact workflow binding while preserving literal identity. */
|
|
63
|
+
function parseWorkflowBinding(input) {
|
|
64
|
+
return workflowBindingSchema.parse(input);
|
|
65
|
+
}
|
|
66
|
+
/** Validates the required versioned input and completion contract for a Task. */
|
|
67
|
+
const taskWorkSchema = z.strictObject({
|
|
68
|
+
title: z.string().trim().min(1).max(256).describe("Short work title, from 1 to 256 characters."),
|
|
69
|
+
input: jsonValueSchema.describe("Bounded JSON input to validate against the registered workflow input schema."),
|
|
70
|
+
completionCriteria: z.array(z.string().trim().min(1).max(2048).describe("One completion criterion, from 1 to 2048 characters.")).max(32).readonly().describe("Up to 32 explicit completion criteria; workflow code determines completion."),
|
|
71
|
+
workflow: workflowBindingSchema.describe("Exact registered workflow contract that owns this work."),
|
|
72
|
+
route: agentRouteBindingSchema.optional().describe("Exact agent execution route selected by the workflow; absent for work not dispatched to an agent.")
|
|
73
|
+
}).describe("Required versioned work contract; registered workflow validation is owned by the engine.");
|
|
74
|
+
/** Validates canonical output recorded when workflow work completes. */
|
|
75
|
+
const taskWorkResultSchema = z.strictObject({
|
|
76
|
+
output: jsonValueSchema.describe("Canonical bounded JSON output, validated by the engine against the stored workflow output schema."),
|
|
77
|
+
completedAt: isoDateTimeSchema.describe("Engine timestamp when the workflow result was completed.")
|
|
78
|
+
}).describe("Completed result of workflow work; registered output validation is owned by the engine.");
|
|
79
|
+
function taskWork(options) {
|
|
80
|
+
const { title, input = {} } = options;
|
|
81
|
+
const workflow = options.workflow ?? parseWorkflowBinding({
|
|
82
|
+
id: "task",
|
|
83
|
+
version: 1
|
|
84
|
+
});
|
|
85
|
+
const binding = "binding" in workflow ? workflow.binding : workflow;
|
|
86
|
+
const parsed = taskWorkSchema.parse({
|
|
87
|
+
title,
|
|
88
|
+
input,
|
|
89
|
+
workflow: binding,
|
|
90
|
+
completionCriteria: []
|
|
91
|
+
});
|
|
92
|
+
return structuredClone({
|
|
93
|
+
title: parsed.title,
|
|
94
|
+
input,
|
|
95
|
+
workflow: binding,
|
|
96
|
+
completionCriteria: []
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
//#endregion
|
|
100
|
+
export { MAX_WORK_JSON_BYTES, MAX_WORK_JSON_DEPTH, jsonValueSchema, parseWorkflowBinding, taskWork, taskWorkResultSchema, taskWorkSchema, workflowBindingSchema };
|
|
101
|
+
|
|
102
|
+
//# sourceMappingURL=work.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"work.mjs","names":[],"sources":["../../src/schema/work.ts"],"sourcesContent":["import { z } from \"zod\";\nimport { agentRouteBindingSchema, type AgentRouteBinding } from \"./agent-route\";\nimport { isoDateTimeSchema } from \"./common\";\n\n/** Finite JSON data accepted at persisted workflow boundaries. */\nexport type JsonValue =\n | null\n | boolean\n | number\n | string\n | readonly JsonValue[]\n | { readonly [key: string]: JsonValue };\n\ndeclare const workflowInputType: unique symbol;\ndeclare const workflowOutputType: unique symbol;\n\n/** Exact workflow identity carrying its input and output types for safe construction. */\nexport type WorkflowBinding<\n Input extends JsonValue = JsonValue,\n Output extends JsonValue = JsonValue,\n Id extends string = string,\n Version extends number = number,\n> = z.infer<typeof workflowBindingSchema> & {\n readonly id: Id;\n readonly version: Version;\n readonly [workflowInputType]?: Input;\n readonly [workflowOutputType]?: Output;\n};\n\n/** Definition-like value exposing an exact typed workflow binding. */\nexport interface WorkflowReference<\n InputSchema extends z.ZodType = z.ZodType,\n Binding extends WorkflowBinding = WorkflowBinding,\n> {\n readonly binding: Binding;\n readonly input: InputSchema;\n}\n\n/** Input type carried by a definition-like workflow reference. */\nexport type WorkflowReferenceInput<Reference extends WorkflowReference> = z.input<\n Reference[\"input\"]\n> &\n JsonValue;\n\n/** Maximum serialized UTF-8 size of workflow input, output, or message JSON. */\nexport const MAX_WORK_JSON_BYTES = 64 * 1024;\n/** Maximum nesting depth below the root of persisted workflow JSON. */\nexport const MAX_WORK_JSON_DEPTH = 32;\n\nconst encoder = new TextEncoder();\n\nfunction isBoundedJson(value: unknown): boolean {\n let bytes = 0;\n const ancestors = new Set<object>();\n const addBytes = (count: number): boolean => {\n bytes += count;\n return bytes <= MAX_WORK_JSON_BYTES;\n };\n const stringFits = (text: string): boolean =>\n text.length <= MAX_WORK_JSON_BYTES && addBytes(encoder.encode(JSON.stringify(text)).byteLength);\n\n const visit = (entry: unknown, depth: number): boolean => {\n if (depth > MAX_WORK_JSON_DEPTH) return false;\n if (entry === null) return addBytes(4);\n if (typeof entry === \"boolean\") return addBytes(entry ? 4 : 5);\n if (typeof entry === \"string\") return stringFits(entry);\n if (typeof entry === \"number\") {\n return Number.isFinite(entry) && addBytes(JSON.stringify(entry).length);\n }\n if (typeof entry !== \"object\" || ancestors.has(entry)) return false;\n\n const array = Array.isArray(entry);\n const prototype: unknown = Object.getPrototypeOf(entry);\n if (\n array ? prototype !== Array.prototype : prototype !== Object.prototype && prototype !== null\n ) {\n return false;\n }\n if (!addBytes(2)) return false;\n ancestors.add(entry);\n const keys = Reflect.ownKeys(entry);\n if (array) {\n if (entry.length > MAX_WORK_JSON_BYTES || keys.length !== entry.length + 1) return false;\n for (let index = 0; index < entry.length; index++) {\n const descriptor = Object.getOwnPropertyDescriptor(entry, String(index));\n if (!descriptor || !descriptor.enumerable || !(\"value\" in descriptor)) return false;\n if (index > 0 && !addBytes(1)) return false;\n if (!visit(descriptor.value, depth + 1)) return false;\n }\n } else {\n for (const [index, key] of keys.entries()) {\n if (typeof key !== \"string\") return false;\n const descriptor = Object.getOwnPropertyDescriptor(entry, key);\n if (!descriptor || !descriptor.enumerable || !(\"value\" in descriptor)) return false;\n if (index > 0 && !addBytes(1)) return false;\n if (!stringFits(key) || !addBytes(1) || !visit(descriptor.value, depth + 1)) return false;\n }\n }\n ancestors.delete(entry);\n return true;\n };\n\n try {\n return visit(value, 0);\n } catch {\n return false;\n }\n}\n\n/** Validates bounded canonical JSON without cycles, accessors, or sparse arrays. */\nexport const jsonValueSchema = z\n .custom<JsonValue>(isBoundedJson, {\n message: `Expected finite JSON with at most ${MAX_WORK_JSON_BYTES} UTF-8 bytes and depth ${MAX_WORK_JSON_DEPTH}; cycles, accessors, sparse arrays, and non-JSON properties are not allowed`,\n })\n .describe(\"Finite JSON value, at most 64 KiB serialized UTF-8 and 32 levels below the root.\");\n\n/** Validates an exact workflow identifier and positive integer version. */\nexport const workflowBindingSchema = z\n .strictObject({\n id: z\n .string()\n .max(64)\n .regex(\n /^[a-z][a-z0-9]*(?:[-_][a-z0-9]+)*$/,\n \"Expected a lowercase hyphenated or snake_case workflow name\",\n )\n .describe(\n \"Registered workflow name, starting with a lowercase letter; at most 64 characters.\",\n ),\n version: z\n .number()\n .int()\n .positive()\n .describe(\"Exact positive integer version of the registered workflow.\"),\n })\n .describe(\"Explicit workflow identity and version; never resolved to an implicit latest version.\")\n .brand<\"WorkflowBinding\">();\n\n/** Plain identifier and version accepted when constructing a workflow binding. */\nexport interface WorkflowBindingInput<Id extends string = string, Version extends number = number> {\n readonly id: Id;\n readonly version: Version;\n}\n\n/** Validates and brands an exact workflow binding while preserving literal identity. */\nexport function parseWorkflowBinding<const Input extends WorkflowBindingInput>(\n input: Input,\n): WorkflowBinding<JsonValue, JsonValue, Input[\"id\"], Input[\"version\"]> {\n return workflowBindingSchema.parse(input) as WorkflowBinding<\n JsonValue,\n JsonValue,\n Input[\"id\"],\n Input[\"version\"]\n >;\n}\n\n/** Validates the required versioned input and completion contract for a Task. */\nexport const taskWorkSchema = z\n .strictObject({\n title: z\n .string()\n .trim()\n .min(1)\n .max(256)\n .describe(\"Short work title, from 1 to 256 characters.\"),\n input: jsonValueSchema.describe(\n \"Bounded JSON input to validate against the registered workflow input schema.\",\n ),\n completionCriteria: z\n .array(\n z\n .string()\n .trim()\n .min(1)\n .max(2048)\n .describe(\"One completion criterion, from 1 to 2048 characters.\"),\n )\n .max(32)\n .readonly()\n .describe(\"Up to 32 explicit completion criteria; workflow code determines completion.\"),\n workflow: workflowBindingSchema.describe(\n \"Exact registered workflow contract that owns this work.\",\n ),\n route: agentRouteBindingSchema\n .optional()\n .describe(\n \"Exact agent execution route selected by the workflow; absent for work not dispatched to an agent.\",\n ),\n })\n .describe(\n \"Required versioned work contract; registered workflow validation is owned by the engine.\",\n );\n\n/** Validates canonical output recorded when workflow work completes. */\nexport const taskWorkResultSchema = z\n .strictObject({\n output: jsonValueSchema.describe(\n \"Canonical bounded JSON output, validated by the engine against the stored workflow output schema.\",\n ),\n completedAt: isoDateTimeSchema.describe(\n \"Engine timestamp when the workflow result was completed.\",\n ),\n })\n .describe(\n \"Completed result of workflow work; registered output validation is owned by the engine.\",\n );\n\n/** Required title, typed input, criteria, workflow, and optional route contract of a Task. */\nexport interface TaskWork<\n Input extends JsonValue = JsonValue,\n Workflow extends WorkflowBinding = WorkflowBinding,\n> {\n readonly title: string;\n readonly input: Input;\n readonly completionCriteria: readonly string[];\n readonly workflow: Workflow;\n readonly route?: AgentRouteBinding;\n}\n/** Validated canonical output and completion timestamp of succeeded workflow work. */\nexport type TaskWorkResult = z.infer<typeof taskWorkResultSchema>;\n\n/** Named fields for constructing generic `task@1` work. */\nexport interface TaskWorkOptions<Input extends JsonValue = JsonValue> {\n readonly title: string;\n readonly input?: Input;\n readonly workflow?: never;\n readonly route?: never;\n readonly completionCriteria?: never;\n}\n\n/** Named fields for constructing work owned by an exact workflow contract. */\nexport interface WorkflowTaskWorkOptions<\n Input extends JsonValue = JsonValue,\n Workflow extends WorkflowBinding | WorkflowReference = WorkflowBinding | WorkflowReference,\n> {\n readonly title: string;\n readonly input: Input;\n readonly workflow: Workflow;\n readonly route?: never;\n readonly completionCriteria?: never;\n}\n\n/** Constructs generic `task@1` work with an empty completion-criteria list. */\nexport function taskWork<const Input extends JsonValue = JsonValue>(\n options: TaskWorkOptions<Input>,\n): TaskWork<Input>;\n/** Constructs work from a definition-like reference with a typed exact workflow binding. */\nexport function taskWork<InputSchema extends z.ZodType, Binding extends WorkflowBinding>(\n options: WorkflowTaskWorkOptions<\n NoInfer<z.input<InputSchema>> & JsonValue,\n { readonly input: InputSchema; readonly binding: Binding }\n >,\n): TaskWork<z.input<InputSchema> & JsonValue, Binding>;\n/** Constructs work from an exact typed workflow binding. */\nexport function taskWork<\n Input extends JsonValue,\n Output extends JsonValue,\n const Id extends string,\n const Version extends number,\n>(\n options: WorkflowTaskWorkOptions<\n NoInfer<Input>,\n WorkflowBinding<Input, Output, Id, Version> & {\n readonly binding?: never;\n readonly input?: never;\n }\n >,\n): TaskWork<Input, WorkflowBinding<Input, Output, Id, Version>>;\nexport function taskWork(options: TaskWorkOptions | WorkflowTaskWorkOptions): TaskWork {\n const { title, input = {} } = options;\n const workflow =\n options.workflow ??\n parseWorkflowBinding({\n id: \"task\",\n version: 1,\n });\n const binding = \"binding\" in workflow ? workflow.binding : workflow;\n const parsed = taskWorkSchema.parse({ title, input, workflow: binding, completionCriteria: [] });\n return structuredClone({\n title: parsed.title,\n input,\n workflow: binding,\n completionCriteria: [],\n });\n}\n"],"mappings":";;;;;AA6CA,MAAa,sBAAsB;;AAEnC,MAAa,sBAAsB;AAEnC,MAAM,UAAU,IAAI,YAAY;AAEhC,SAAS,cAAc,OAAyB;CAC9C,IAAI,QAAQ;CACZ,MAAM,4BAAY,IAAI,IAAY;CAClC,MAAM,YAAY,UAA2B;EAC3C,SAAS;EACT,OAAO,SAAS;CAClB;CACA,MAAM,cAAc,SAClB,KAAK,UAAA,SAAiC,SAAS,QAAQ,OAAO,KAAK,UAAU,IAAI,CAAC,CAAC,CAAC,UAAU;CAEhG,MAAM,SAAS,OAAgB,UAA2B;EACxD,IAAI,QAAA,IAA6B,OAAO;EACxC,IAAI,UAAU,MAAM,OAAO,SAAS,CAAC;EACrC,IAAI,OAAO,UAAU,WAAW,OAAO,SAAS,QAAQ,IAAI,CAAC;EAC7D,IAAI,OAAO,UAAU,UAAU,OAAO,WAAW,KAAK;EACtD,IAAI,OAAO,UAAU,UACnB,OAAO,OAAO,SAAS,KAAK,KAAK,SAAS,KAAK,UAAU,KAAK,CAAC,CAAC,MAAM;EAExE,IAAI,OAAO,UAAU,YAAY,UAAU,IAAI,KAAK,GAAG,OAAO;EAE9D,MAAM,QAAQ,MAAM,QAAQ,KAAK;EACjC,MAAM,YAAqB,OAAO,eAAe,KAAK;EACtD,IACE,QAAQ,cAAc,MAAM,YAAY,cAAc,OAAO,aAAa,cAAc,MAExF,OAAO;EAET,IAAI,CAAC,SAAS,CAAC,GAAG,OAAO;EACzB,UAAU,IAAI,KAAK;EACnB,MAAM,OAAO,QAAQ,QAAQ,KAAK;EAClC,IAAI,OAAO;GACT,IAAI,MAAM,SAAA,SAAgC,KAAK,WAAW,MAAM,SAAS,GAAG,OAAO;GACnF,KAAK,IAAI,QAAQ,GAAG,QAAQ,MAAM,QAAQ,SAAS;IACjD,MAAM,aAAa,OAAO,yBAAyB,OAAO,OAAO,KAAK,CAAC;IACvE,IAAI,CAAC,cAAc,CAAC,WAAW,cAAc,EAAE,WAAW,aAAa,OAAO;IAC9E,IAAI,QAAQ,KAAK,CAAC,SAAS,CAAC,GAAG,OAAO;IACtC,IAAI,CAAC,MAAM,WAAW,OAAO,QAAQ,CAAC,GAAG,OAAO;GAClD;EACF,OACE,KAAK,MAAM,CAAC,OAAO,QAAQ,KAAK,QAAQ,GAAG;GACzC,IAAI,OAAO,QAAQ,UAAU,OAAO;GACpC,MAAM,aAAa,OAAO,yBAAyB,OAAO,GAAG;GAC7D,IAAI,CAAC,cAAc,CAAC,WAAW,cAAc,EAAE,WAAW,aAAa,OAAO;GAC9E,IAAI,QAAQ,KAAK,CAAC,SAAS,CAAC,GAAG,OAAO;GACtC,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,WAAW,OAAO,QAAQ,CAAC,GAAG,OAAO;EACtF;EAEF,UAAU,OAAO,KAAK;EACtB,OAAO;CACT;CAEA,IAAI;EACF,OAAO,MAAM,OAAO,CAAC;CACvB,QAAQ;EACN,OAAO;CACT;AACF;;AAGA,MAAa,kBAAkB,EAC5B,OAAkB,eAAe,EAChC,SAAS,qCAAqC,oBAAoB,sGACpE,CAAC,CAAC,CACD,SAAS,kFAAkF;;AAG9F,MAAa,wBAAwB,EAClC,aAAa;CACZ,IAAI,EACD,OAAO,CAAC,CACR,IAAI,EAAE,CAAC,CACP,MACC,sCACA,6DACF,CAAC,CACA,SACC,oFACF;CACF,SAAS,EACN,OAAO,CAAC,CACR,IAAI,CAAC,CACL,SAAS,CAAC,CACV,SAAS,4DAA4D;AAC1E,CAAC,CAAC,CACD,SAAS,uFAAuF,CAAC,CACjG,MAAyB;;AAS5B,SAAgB,qBACd,OACsE;CACtE,OAAO,sBAAsB,MAAM,KAAK;AAM1C;;AAGA,MAAa,iBAAiB,EAC3B,aAAa;CACZ,OAAO,EACJ,OAAO,CAAC,CACR,KAAK,CAAC,CACN,IAAI,CAAC,CAAC,CACN,IAAI,GAAG,CAAC,CACR,SAAS,6CAA6C;CACzD,OAAO,gBAAgB,SACrB,8EACF;CACA,oBAAoB,EACjB,MACC,EACG,OAAO,CAAC,CACR,KAAK,CAAC,CACN,IAAI,CAAC,CAAC,CACN,IAAI,IAAI,CAAC,CACT,SAAS,sDAAsD,CACpE,CAAC,CACA,IAAI,EAAE,CAAC,CACP,SAAS,CAAC,CACV,SAAS,6EAA6E;CACzF,UAAU,sBAAsB,SAC9B,yDACF;CACA,OAAO,wBACJ,SAAS,CAAC,CACV,SACC,mGACF;AACJ,CAAC,CAAC,CACD,SACC,0FACF;;AAGF,MAAa,uBAAuB,EACjC,aAAa;CACZ,QAAQ,gBAAgB,SACtB,mGACF;CACA,aAAa,kBAAkB,SAC7B,0DACF;AACF,CAAC,CAAC,CACD,SACC,yFACF;AA+DF,SAAgB,SAAS,SAA8D;CACrF,MAAM,EAAE,OAAO,QAAQ,CAAC,MAAM;CAC9B,MAAM,WACJ,QAAQ,YACR,qBAAqB;EACnB,IAAI;EACJ,SAAS;CACX,CAAC;CACH,MAAM,UAAU,aAAa,WAAW,SAAS,UAAU;CAC3D,MAAM,SAAS,eAAe,MAAM;EAAE;EAAO;EAAO,UAAU;EAAS,oBAAoB,CAAC;CAAE,CAAC;CAC/F,OAAO,gBAAgB;EACrB,OAAO,OAAO;EACd;EACA,UAAU;EACV,oBAAoB,CAAC;CACvB,CAAC;AACH"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Signal } from "./schema/signal.mjs";
|
|
2
|
+
import { FactoryStores } from "./store/engine.mjs";
|
|
3
|
+
import { AuthFn } from "eve/channels/auth";
|
|
4
|
+
//#region src/signal-triage.d.ts
|
|
5
|
+
/** Bind optional signal attempt headers only after the underlying caller authenticates. */
|
|
6
|
+
declare function withSignalTriage(authenticate: AuthFn<Request>): AuthFn<Request>;
|
|
7
|
+
/** Encode the admitted Signal attempt for a trusted Foreman launch. */
|
|
8
|
+
declare function signalTriageHeaders(signal: Signal): Record<string, string>;
|
|
9
|
+
/** Persist admission before launching; an ambiguous launch stays visible and cannot be retried blindly. */
|
|
10
|
+
declare function runSignalTriage(stores: Pick<FactoryStores, "signals">, signal: Signal, options: {
|
|
11
|
+
expectedAttempt: number;
|
|
12
|
+
by: string;
|
|
13
|
+
}, launch: (admitted: Signal, operationId: string) => Promise<{
|
|
14
|
+
sessionId: string;
|
|
15
|
+
} | void>): Promise<Signal>;
|
|
16
|
+
/** Record taskless Foreman failures from authenticated, repository-scoped Eve lifecycle events. */
|
|
17
|
+
declare function createSignalTriageHook(stores: Pick<FactoryStores, "signals">): import("eve/hooks").HookDefinition<"session.failed" | "turn.cancelled" | "turn.completed" | "turn.failed">;
|
|
18
|
+
//#endregion
|
|
19
|
+
export { createSignalTriageHook, runSignalTriage, signalTriageHeaders, withSignalTriage };
|
|
20
|
+
//# sourceMappingURL=signal-triage.d.mts.map
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { signalIdSchema } from "./schema/id.mjs";
|
|
2
|
+
import { repositoryIdsForSession } from "./eve/task-session.mjs";
|
|
3
|
+
import { defineHook } from "eve/hooks";
|
|
4
|
+
import { ForbiddenError } from "eve/channels/auth";
|
|
5
|
+
//#region src/signal-triage.ts
|
|
6
|
+
const signalHeader = "x-factory-signal-id";
|
|
7
|
+
const attemptHeader = "x-factory-signal-attempt";
|
|
8
|
+
/** Bind optional signal attempt headers only after the underlying caller authenticates. */
|
|
9
|
+
function withSignalTriage(authenticate) {
|
|
10
|
+
return async (request) => {
|
|
11
|
+
const auth = await authenticate(request);
|
|
12
|
+
if (auth == null) return auth;
|
|
13
|
+
const id = request.headers.get(signalHeader);
|
|
14
|
+
const attempt = request.headers.get(attemptHeader);
|
|
15
|
+
if (id === null && attempt === null) return auth;
|
|
16
|
+
if (!signalIdSchema.safeParse(id).success || !attempt || !/^[1-9]\d*$/u.test(attempt) || !Number.isSafeInteger(Number(attempt))) throw new ForbiddenError();
|
|
17
|
+
return {
|
|
18
|
+
...auth,
|
|
19
|
+
attributes: {
|
|
20
|
+
...auth.attributes,
|
|
21
|
+
factorySignalId: id,
|
|
22
|
+
factorySignalAttempt: attempt
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/** Encode the admitted Signal attempt for a trusted Foreman launch. */
|
|
28
|
+
function signalTriageHeaders(signal) {
|
|
29
|
+
if (!signal.triage) throw new Error("Signal has no admitted triage attempt");
|
|
30
|
+
return {
|
|
31
|
+
[signalHeader]: signal.id,
|
|
32
|
+
[attemptHeader]: String(signal.triage.attempt)
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/** Persist admission before launching; an ambiguous launch stays visible and cannot be retried blindly. */
|
|
36
|
+
async function runSignalTriage(stores, signal, options, launch) {
|
|
37
|
+
const admitted = await stores.signals.beginTriage(signal.id, options);
|
|
38
|
+
const attempt = admitted.triage.attempt;
|
|
39
|
+
let execution;
|
|
40
|
+
try {
|
|
41
|
+
execution = await launch(admitted, attempt === 1 ? `factory-signal:${signal.id}` : `factory-signal:${signal.id}:${attempt}`);
|
|
42
|
+
} catch {
|
|
43
|
+
return stores.signals.updateTriage(signal.id, attempt, {
|
|
44
|
+
state: "uncertain",
|
|
45
|
+
failure: "launch_unconfirmed"
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
if (!execution) return stores.signals.updateTriage(signal.id, attempt, {
|
|
49
|
+
state: "uncertain",
|
|
50
|
+
failure: "launch_unconfirmed"
|
|
51
|
+
});
|
|
52
|
+
return stores.signals.updateTriage(signal.id, attempt, {
|
|
53
|
+
state: "running",
|
|
54
|
+
sessionId: execution.sessionId
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
/** Record taskless Foreman failures from authenticated, repository-scoped Eve lifecycle events. */
|
|
58
|
+
function createSignalTriageHook(stores) {
|
|
59
|
+
async function stopped(ctx, failure) {
|
|
60
|
+
const auth = ctx.session.auth.initiator;
|
|
61
|
+
const id = signalIdSchema.safeParse(auth?.attributes.factorySignalId);
|
|
62
|
+
const attempt = Number(auth?.attributes.factorySignalAttempt);
|
|
63
|
+
if (!id.success || !Number.isSafeInteger(attempt) || attempt < 1) return;
|
|
64
|
+
const signal = await stores.signals.get(id.data);
|
|
65
|
+
if (!signal || !repositoryIdsForSession(auth)?.includes(signal.repositoryId)) return;
|
|
66
|
+
await stores.signals.updateTriage(id.data, attempt, {
|
|
67
|
+
state: "blocked",
|
|
68
|
+
failure,
|
|
69
|
+
sessionId: ctx.session.id
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
function category(code, message) {
|
|
73
|
+
return `${code} ${message}`.includes("customer_verification_required") ? "billing_verification_required" : "provider_failed";
|
|
74
|
+
}
|
|
75
|
+
return defineHook({ events: {
|
|
76
|
+
"turn.failed": (event, ctx) => stopped(ctx, category(event.data.code, event.data.message)),
|
|
77
|
+
"session.failed": (event, ctx) => stopped(ctx, category(event.data.code, event.data.message)),
|
|
78
|
+
"turn.cancelled": (_event, ctx) => stopped(ctx, "cancelled"),
|
|
79
|
+
"turn.completed": (_event, ctx) => stopped(ctx, "no_decision")
|
|
80
|
+
} });
|
|
81
|
+
}
|
|
82
|
+
//#endregion
|
|
83
|
+
export { createSignalTriageHook, runSignalTriage, signalTriageHeaders, withSignalTriage };
|
|
84
|
+
|
|
85
|
+
//# sourceMappingURL=signal-triage.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signal-triage.mjs","names":[],"sources":["../src/signal-triage.ts"],"sourcesContent":["import { ForbiddenError, type AuthFn } from \"eve/channels/auth\";\nimport type { SessionContext } from \"eve/context\";\nimport { defineHook } from \"eve/hooks\";\nimport { signalIdSchema } from \"./schema/id\";\nimport type { Signal, SignalTriage } from \"./schema/signal\";\nimport type { FactoryStores } from \"./store/engine\";\nimport { repositoryIdsForSession } from \"./eve/task-session\";\n\nconst signalHeader = \"x-factory-signal-id\";\nconst attemptHeader = \"x-factory-signal-attempt\";\n\n/** Bind optional signal attempt headers only after the underlying caller authenticates. */\nexport function withSignalTriage(authenticate: AuthFn<Request>): AuthFn<Request> {\n return async (request) => {\n const auth = await authenticate(request);\n if (auth == null) return auth;\n const id = request.headers.get(signalHeader);\n const attempt = request.headers.get(attemptHeader);\n if (id === null && attempt === null) return auth;\n if (\n !signalIdSchema.safeParse(id).success ||\n !attempt ||\n !/^[1-9]\\d*$/u.test(attempt) ||\n !Number.isSafeInteger(Number(attempt))\n )\n throw new ForbiddenError();\n return {\n ...auth,\n attributes: { ...auth.attributes, factorySignalId: id!, factorySignalAttempt: attempt },\n };\n };\n}\n\n/** Encode the admitted Signal attempt for a trusted Foreman launch. */\nexport function signalTriageHeaders(signal: Signal): Record<string, string> {\n if (!signal.triage) throw new Error(\"Signal has no admitted triage attempt\");\n return { [signalHeader]: signal.id, [attemptHeader]: String(signal.triage.attempt) };\n}\n\n/** Persist admission before launching; an ambiguous launch stays visible and cannot be retried blindly. */\nexport async function runSignalTriage(\n stores: Pick<FactoryStores, \"signals\">,\n signal: Signal,\n options: { expectedAttempt: number; by: string },\n launch: (admitted: Signal, operationId: string) => Promise<{ sessionId: string } | void>,\n): Promise<Signal> {\n const admitted = await stores.signals.beginTriage(signal.id, options);\n const attempt = admitted.triage!.attempt;\n let execution: { sessionId: string } | void;\n try {\n execution = await launch(\n admitted,\n attempt === 1 ? `factory-signal:${signal.id}` : `factory-signal:${signal.id}:${attempt}`,\n );\n } catch {\n return stores.signals.updateTriage(signal.id, attempt, {\n state: \"uncertain\",\n failure: \"launch_unconfirmed\",\n });\n }\n if (!execution)\n return stores.signals.updateTriage(signal.id, attempt, {\n state: \"uncertain\",\n failure: \"launch_unconfirmed\",\n });\n return stores.signals.updateTriage(signal.id, attempt, {\n state: \"running\",\n sessionId: execution.sessionId,\n });\n}\n\n/** Record taskless Foreman failures from authenticated, repository-scoped Eve lifecycle events. */\nexport function createSignalTriageHook(stores: Pick<FactoryStores, \"signals\">) {\n async function stopped(ctx: Pick<SessionContext, \"session\">, failure: SignalTriage[\"failure\"]) {\n const auth = ctx.session.auth.initiator;\n const id = signalIdSchema.safeParse(auth?.attributes.factorySignalId);\n const attempt = Number(auth?.attributes.factorySignalAttempt);\n if (!id.success || !Number.isSafeInteger(attempt) || attempt < 1) return;\n const signal = await stores.signals.get(id.data);\n if (!signal || !repositoryIdsForSession(auth)?.includes(signal.repositoryId)) return;\n await stores.signals.updateTriage(id.data, attempt, {\n state: \"blocked\",\n failure,\n sessionId: ctx.session.id,\n });\n }\n function category(code: string, message: string): SignalTriage[\"failure\"] {\n return `${code} ${message}`.includes(\"customer_verification_required\")\n ? \"billing_verification_required\"\n : \"provider_failed\";\n }\n return defineHook({\n events: {\n \"turn.failed\": (event, ctx) => stopped(ctx, category(event.data.code, event.data.message)),\n \"session.failed\": (event, ctx) => stopped(ctx, category(event.data.code, event.data.message)),\n \"turn.cancelled\": (_event, ctx) => stopped(ctx, \"cancelled\"),\n \"turn.completed\": (_event, ctx) => stopped(ctx, \"no_decision\"),\n },\n });\n}\n"],"mappings":";;;;;AAQA,MAAM,eAAe;AACrB,MAAM,gBAAgB;;AAGtB,SAAgB,iBAAiB,cAAgD;CAC/E,OAAO,OAAO,YAAY;EACxB,MAAM,OAAO,MAAM,aAAa,OAAO;EACvC,IAAI,QAAQ,MAAM,OAAO;EACzB,MAAM,KAAK,QAAQ,QAAQ,IAAI,YAAY;EAC3C,MAAM,UAAU,QAAQ,QAAQ,IAAI,aAAa;EACjD,IAAI,OAAO,QAAQ,YAAY,MAAM,OAAO;EAC5C,IACE,CAAC,eAAe,UAAU,EAAE,CAAC,CAAC,WAC9B,CAAC,WACD,CAAC,cAAc,KAAK,OAAO,KAC3B,CAAC,OAAO,cAAc,OAAO,OAAO,CAAC,GAErC,MAAM,IAAI,eAAe;EAC3B,OAAO;GACL,GAAG;GACH,YAAY;IAAE,GAAG,KAAK;IAAY,iBAAiB;IAAK,sBAAsB;GAAQ;EACxF;CACF;AACF;;AAGA,SAAgB,oBAAoB,QAAwC;CAC1E,IAAI,CAAC,OAAO,QAAQ,MAAM,IAAI,MAAM,uCAAuC;CAC3E,OAAO;GAAG,eAAe,OAAO;GAAK,gBAAgB,OAAO,OAAO,OAAO,OAAO;CAAE;AACrF;;AAGA,eAAsB,gBACpB,QACA,QACA,SACA,QACiB;CACjB,MAAM,WAAW,MAAM,OAAO,QAAQ,YAAY,OAAO,IAAI,OAAO;CACpE,MAAM,UAAU,SAAS,OAAQ;CACjC,IAAI;CACJ,IAAI;EACF,YAAY,MAAM,OAChB,UACA,YAAY,IAAI,kBAAkB,OAAO,OAAO,kBAAkB,OAAO,GAAG,GAAG,SACjF;CACF,QAAQ;EACN,OAAO,OAAO,QAAQ,aAAa,OAAO,IAAI,SAAS;GACrD,OAAO;GACP,SAAS;EACX,CAAC;CACH;CACA,IAAI,CAAC,WACH,OAAO,OAAO,QAAQ,aAAa,OAAO,IAAI,SAAS;EACrD,OAAO;EACP,SAAS;CACX,CAAC;CACH,OAAO,OAAO,QAAQ,aAAa,OAAO,IAAI,SAAS;EACrD,OAAO;EACP,WAAW,UAAU;CACvB,CAAC;AACH;;AAGA,SAAgB,uBAAuB,QAAwC;CAC7E,eAAe,QAAQ,KAAsC,SAAkC;EAC7F,MAAM,OAAO,IAAI,QAAQ,KAAK;EAC9B,MAAM,KAAK,eAAe,UAAU,MAAM,WAAW,eAAe;EACpE,MAAM,UAAU,OAAO,MAAM,WAAW,oBAAoB;EAC5D,IAAI,CAAC,GAAG,WAAW,CAAC,OAAO,cAAc,OAAO,KAAK,UAAU,GAAG;EAClE,MAAM,SAAS,MAAM,OAAO,QAAQ,IAAI,GAAG,IAAI;EAC/C,IAAI,CAAC,UAAU,CAAC,wBAAwB,IAAI,CAAC,EAAE,SAAS,OAAO,YAAY,GAAG;EAC9E,MAAM,OAAO,QAAQ,aAAa,GAAG,MAAM,SAAS;GAClD,OAAO;GACP;GACA,WAAW,IAAI,QAAQ;EACzB,CAAC;CACH;CACA,SAAS,SAAS,MAAc,SAA0C;EACxE,OAAO,GAAG,KAAK,GAAG,UAAU,SAAS,gCAAgC,IACjE,kCACA;CACN;CACA,OAAO,WAAW,EAChB,QAAQ;EACN,gBAAgB,OAAO,QAAQ,QAAQ,KAAK,SAAS,MAAM,KAAK,MAAM,MAAM,KAAK,OAAO,CAAC;EACzF,mBAAmB,OAAO,QAAQ,QAAQ,KAAK,SAAS,MAAM,KAAK,MAAM,MAAM,KAAK,OAAO,CAAC;EAC5F,mBAAmB,QAAQ,QAAQ,QAAQ,KAAK,WAAW;EAC3D,mBAAmB,QAAQ,QAAQ,QAAQ,KAAK,aAAa;CAC/D,EACF,CAAC;AACH"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { DecidedSignal, PendingSignal, Signal, SignalOutcome, SignalSource, SignalTriage, signalOutcomeSchema, signalSchema, signalSourceSchema, signalTriageSchema, standardSignalSources } from "./schema/signal.mjs";
|
|
2
|
+
import { SignalId, signalIdSchema } from "./schema/id.mjs";
|
|
3
|
+
import { CreateSignalInput, DecideSignalInput, FactoryStores } from "./store/engine.mjs";
|
|
4
|
+
import { signalInitialOutcome, signalOutcomeTransitions, signalTriageTransitions } from "./schema/transitions.mjs";
|
|
5
|
+
import { createSignalTriageHook, runSignalTriage, signalTriageHeaders, withSignalTriage } from "./signal-triage.mjs";
|
|
6
|
+
//#region src/signals.d.ts
|
|
7
|
+
/** Narrow intake boundary that persists normalized Signals without starting workflow work. */
|
|
8
|
+
interface SignalCreator {
|
|
9
|
+
create(input: CreateSignalInput): Promise<Signal>;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Bind normalized intake to signal creation alone. Connectors and API routes
|
|
13
|
+
* own authentication and normalization; configured workflows own what happens
|
|
14
|
+
* next.
|
|
15
|
+
*/
|
|
16
|
+
declare function createSignalCreator(stores: Pick<FactoryStores, "signals">): SignalCreator;
|
|
17
|
+
//#endregion
|
|
18
|
+
export { type CreateSignalInput, type DecideSignalInput, type DecidedSignal, type PendingSignal, type Signal, SignalCreator, type SignalId, type SignalOutcome, type SignalSource, type SignalTriage, createSignalCreator, createSignalTriageHook, runSignalTriage, signalIdSchema, signalInitialOutcome, signalOutcomeSchema, signalOutcomeTransitions, signalSchema, signalSourceSchema, signalTriageHeaders, signalTriageSchema, signalTriageTransitions, standardSignalSources, withSignalTriage };
|
|
19
|
+
//# sourceMappingURL=signals.d.mts.map
|
package/dist/signals.mjs
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { signalIdSchema } from "./schema/id.mjs";
|
|
2
|
+
import { signalInitialOutcome, signalOutcomeTransitions, signalTriageTransitions } from "./schema/transitions.mjs";
|
|
3
|
+
import { signalOutcomeSchema, signalSchema, signalSourceSchema, signalTriageSchema, standardSignalSources } from "./schema/signal.mjs";
|
|
4
|
+
import { createSignalTriageHook, runSignalTriage, signalTriageHeaders, withSignalTriage } from "./signal-triage.mjs";
|
|
5
|
+
//#region src/signals.ts
|
|
6
|
+
/**
|
|
7
|
+
* Bind normalized intake to signal creation alone. Connectors and API routes
|
|
8
|
+
* own authentication and normalization; configured workflows own what happens
|
|
9
|
+
* next.
|
|
10
|
+
*/
|
|
11
|
+
function createSignalCreator(stores) {
|
|
12
|
+
return { create(input) {
|
|
13
|
+
return stores.signals.create(input);
|
|
14
|
+
} };
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
export { createSignalCreator, createSignalTriageHook, runSignalTriage, signalIdSchema, signalInitialOutcome, signalOutcomeSchema, signalOutcomeTransitions, signalSchema, signalSourceSchema, signalTriageHeaders, signalTriageSchema, signalTriageTransitions, standardSignalSources, withSignalTriage };
|
|
18
|
+
|
|
19
|
+
//# sourceMappingURL=signals.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signals.mjs","names":[],"sources":["../src/signals.ts"],"sourcesContent":["import type { Signal } from \"./schema/signal\";\nimport type { CreateSignalInput, FactoryStores } from \"./store/engine\";\n\nexport { signalIdSchema, type SignalId } from \"./schema/id\";\nexport {\n signalOutcomeSchema,\n signalTriageSchema,\n type SignalTriage,\n signalSchema,\n signalSourceSchema,\n standardSignalSources,\n type DecidedSignal,\n type PendingSignal,\n type Signal,\n type SignalOutcome,\n type SignalSource,\n} from \"./schema/signal\";\nexport {\n signalInitialOutcome,\n signalOutcomeTransitions,\n signalTriageTransitions,\n} from \"./schema/transitions\";\nexport { type CreateSignalInput, type DecideSignalInput } from \"./store/engine\";\n\n/** Narrow intake boundary that persists normalized Signals without starting workflow work. */\nexport interface SignalCreator {\n create(input: CreateSignalInput): Promise<Signal>;\n}\n\n/**\n * Bind normalized intake to signal creation alone. Connectors and API routes\n * own authentication and normalization; configured workflows own what happens\n * next.\n */\nexport function createSignalCreator(stores: Pick<FactoryStores, \"signals\">): SignalCreator {\n return {\n create(input) {\n return stores.signals.create(input);\n },\n };\n}\n\nexport {\n createSignalTriageHook,\n withSignalTriage,\n signalTriageHeaders,\n runSignalTriage,\n} from \"./signal-triage\";\n"],"mappings":";;;;;;;;;;AAkCA,SAAgB,oBAAoB,QAAuD;CACzF,OAAO,EACL,OAAO,OAAO;EACZ,OAAO,OAAO,QAAQ,OAAO,KAAK;CACpC,EACF;AACF"}
|
package/dist/stall.d.mts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { TaskId } from "./schema/id.mjs";
|
|
2
|
+
import { Task } from "./schema/task.mjs";
|
|
3
|
+
import { DateClock, MaybePromise } from "./schema/common.mjs";
|
|
4
|
+
import { FactoryStores } from "./store/engine.mjs";
|
|
5
|
+
import { ExecutionPolicy } from "./schema/factory-config.mjs";
|
|
6
|
+
//#region src/stall.d.ts
|
|
7
|
+
/** Execution policy, clock, snapshot, and optional workflow cancellation hook for stall recovery. */
|
|
8
|
+
interface StallSweepOptions {
|
|
9
|
+
policy: ExecutionPolicy;
|
|
10
|
+
now?: DateClock;
|
|
11
|
+
/** A dispatcher-wide snapshot avoids another complete task read. */
|
|
12
|
+
tasks?: readonly Task[];
|
|
13
|
+
/** Optional workflow policy that cancels a stalled task instead of retrying it. */
|
|
14
|
+
cancelStalled?: (task: Task, tasks: readonly Task[]) => MaybePromise<string | null>;
|
|
15
|
+
}
|
|
16
|
+
/** Task IDs transitioned at each stage of one stall-recovery pass. */
|
|
17
|
+
interface TaskStallSweepResult {
|
|
18
|
+
readonly stalled: readonly TaskId[];
|
|
19
|
+
readonly requeued: readonly TaskId[];
|
|
20
|
+
readonly failed: readonly TaskId[];
|
|
21
|
+
readonly cancelled: readonly TaskId[];
|
|
22
|
+
}
|
|
23
|
+
/** Task capability required to detect and recover stalled work. */
|
|
24
|
+
type TaskStallSweepStores = Pick<FactoryStores, "tasks">;
|
|
25
|
+
/** Resolve the progress timeout for a Task kind from the configured execution policy. */
|
|
26
|
+
declare function stallWindowMinutes(policy: ExecutionPolicy, kind: Task["kind"]): number;
|
|
27
|
+
/**
|
|
28
|
+
* The reconciler's stall pass. A running task whose execution has not
|
|
29
|
+
* progressed within its stall window is marked stalled; a stalled task is
|
|
30
|
+
* re-queued for a replacement attempt while attempts remain, and failed once
|
|
31
|
+
* they are exhausted. Only `running` tasks can stall: a task whose result has
|
|
32
|
+
* already been recorded (verifying, or terminal) is never retried by this
|
|
33
|
+
* pass. Workflows explicitly waiting for messages are skipped.
|
|
34
|
+
*/
|
|
35
|
+
declare function sweepTaskStalls(stores: TaskStallSweepStores, options: StallSweepOptions): Promise<TaskStallSweepResult>;
|
|
36
|
+
//#endregion
|
|
37
|
+
export { StallSweepOptions, TaskStallSweepResult, TaskStallSweepStores, stallWindowMinutes, sweepTaskStalls };
|
|
38
|
+
//# sourceMappingURL=stall.d.mts.map
|
package/dist/stall.mjs
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
//#region src/stall.ts
|
|
2
|
+
/** Resolve the progress timeout for a Task kind from the configured execution policy. */
|
|
3
|
+
function stallWindowMinutes(policy, kind) {
|
|
4
|
+
return policy.stallMinutesByKind[kind] ?? policy.stallMinutes;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* The reconciler's stall pass. A running task whose execution has not
|
|
8
|
+
* progressed within its stall window is marked stalled; a stalled task is
|
|
9
|
+
* re-queued for a replacement attempt while attempts remain, and failed once
|
|
10
|
+
* they are exhausted. Only `running` tasks can stall: a task whose result has
|
|
11
|
+
* already been recorded (verifying, or terminal) is never retried by this
|
|
12
|
+
* pass. Workflows explicitly waiting for messages are skipped.
|
|
13
|
+
*/
|
|
14
|
+
async function sweepTaskStalls(stores, options) {
|
|
15
|
+
const nowMs = (options.now ?? (() => /* @__PURE__ */ new Date()))().getTime();
|
|
16
|
+
const result = {
|
|
17
|
+
stalled: [],
|
|
18
|
+
requeued: [],
|
|
19
|
+
failed: [],
|
|
20
|
+
cancelled: []
|
|
21
|
+
};
|
|
22
|
+
const tasks = options.tasks ?? await stores.tasks.list();
|
|
23
|
+
const newlyStalled = [];
|
|
24
|
+
for (const task of tasks) {
|
|
25
|
+
if (task.waitingForMessages || task.state !== "running") continue;
|
|
26
|
+
const minutes = stallWindowMinutes(options.policy, task.kind);
|
|
27
|
+
const sinceProgress = nowMs - Date.parse(task.lastProgressAt ?? task.updatedAt);
|
|
28
|
+
if (sinceProgress < minutes * 6e4) continue;
|
|
29
|
+
try {
|
|
30
|
+
const stalled = await stores.tasks.transition(task.id, "stalled", {
|
|
31
|
+
reason: `no progress for ${Math.floor(sinceProgress / 6e4)} minutes (window ${minutes})`,
|
|
32
|
+
expectFrom: "running"
|
|
33
|
+
});
|
|
34
|
+
result.stalled.push(task.id);
|
|
35
|
+
newlyStalled.push(stalled);
|
|
36
|
+
} catch {
|
|
37
|
+
if (options.tasks !== void 0) {
|
|
38
|
+
const current = await stores.tasks.get(task.id).catch(() => null);
|
|
39
|
+
if (current?.state === "stalled") newlyStalled.push(current);
|
|
40
|
+
}
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const stalledCandidates = options.tasks === void 0 ? await stores.tasks.list() : [...tasks.filter((task) => task.state === "stalled"), ...newlyStalled];
|
|
45
|
+
for (const task of stalledCandidates) {
|
|
46
|
+
if (task.waitingForMessages || task.state !== "stalled") continue;
|
|
47
|
+
const cancellationReason = await options.cancelStalled?.(task, tasks) ?? null;
|
|
48
|
+
try {
|
|
49
|
+
if (cancellationReason !== null) {
|
|
50
|
+
await stores.tasks.transition(task.id, "cancelled", {
|
|
51
|
+
reason: cancellationReason,
|
|
52
|
+
expectFrom: "stalled"
|
|
53
|
+
});
|
|
54
|
+
result.cancelled.push(task.id);
|
|
55
|
+
} else if (task.attempt < options.policy.maxAttempts) {
|
|
56
|
+
await stores.tasks.transition(task.id, "queued", {
|
|
57
|
+
reason: `stalled on attempt ${task.attempt} of ${options.policy.maxAttempts}; replacing`,
|
|
58
|
+
phase: "retry",
|
|
59
|
+
expectFrom: "stalled"
|
|
60
|
+
});
|
|
61
|
+
result.requeued.push(task.id);
|
|
62
|
+
} else {
|
|
63
|
+
await stores.tasks.transition(task.id, "failed", {
|
|
64
|
+
reason: `stalled on attempt ${task.attempt} of ${options.policy.maxAttempts}; attempts exhausted`,
|
|
65
|
+
phase: "retry",
|
|
66
|
+
expectFrom: "stalled"
|
|
67
|
+
});
|
|
68
|
+
result.failed.push(task.id);
|
|
69
|
+
}
|
|
70
|
+
} catch {
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return result;
|
|
75
|
+
}
|
|
76
|
+
//#endregion
|
|
77
|
+
export { stallWindowMinutes, sweepTaskStalls };
|
|
78
|
+
|
|
79
|
+
//# sourceMappingURL=stall.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stall.mjs","names":[],"sources":["../src/stall.ts"],"sourcesContent":["import type { ExecutionPolicy } from \"./schema/factory-config\";\nimport type { DateClock, MaybePromise } from \"./schema/common\";\nimport type { TaskId } from \"./schema/id\";\nimport type { Task } from \"./schema/task\";\nimport type { FactoryStores } from \"./store/engine\";\n\n/** Execution policy, clock, snapshot, and optional workflow cancellation hook for stall recovery. */\nexport interface StallSweepOptions {\n policy: ExecutionPolicy;\n now?: DateClock;\n /** A dispatcher-wide snapshot avoids another complete task read. */\n tasks?: readonly Task[];\n /** Optional workflow policy that cancels a stalled task instead of retrying it. */\n cancelStalled?: (task: Task, tasks: readonly Task[]) => MaybePromise<string | null>;\n}\n\n/** Task IDs transitioned at each stage of one stall-recovery pass. */\nexport interface TaskStallSweepResult {\n readonly stalled: readonly TaskId[];\n readonly requeued: readonly TaskId[];\n readonly failed: readonly TaskId[];\n readonly cancelled: readonly TaskId[];\n}\n\n/** Task capability required to detect and recover stalled work. */\nexport type TaskStallSweepStores = Pick<FactoryStores, \"tasks\">;\n\n/** Resolve the progress timeout for a Task kind from the configured execution policy. */\nexport function stallWindowMinutes(policy: ExecutionPolicy, kind: Task[\"kind\"]): number {\n return policy.stallMinutesByKind[kind] ?? policy.stallMinutes;\n}\n\n/**\n * The reconciler's stall pass. A running task whose execution has not\n * progressed within its stall window is marked stalled; a stalled task is\n * re-queued for a replacement attempt while attempts remain, and failed once\n * they are exhausted. Only `running` tasks can stall: a task whose result has\n * already been recorded (verifying, or terminal) is never retried by this\n * pass. Workflows explicitly waiting for messages are skipped.\n */\nexport async function sweepTaskStalls(\n stores: TaskStallSweepStores,\n options: StallSweepOptions,\n): Promise<TaskStallSweepResult> {\n const nowMs = (options.now ?? (() => new Date()))().getTime();\n const result: {\n stalled: TaskId[];\n requeued: TaskId[];\n failed: TaskId[];\n cancelled: TaskId[];\n } = {\n stalled: [],\n requeued: [],\n failed: [],\n cancelled: [],\n };\n const tasks = options.tasks ?? (await stores.tasks.list());\n const newlyStalled: Task[] = [];\n\n for (const task of tasks) {\n if (task.waitingForMessages || task.state !== \"running\") {\n continue;\n }\n const minutes = stallWindowMinutes(options.policy, task.kind);\n const sinceProgress = nowMs - Date.parse(task.lastProgressAt ?? task.updatedAt);\n if (sinceProgress < minutes * 60_000) {\n continue;\n }\n // A concurrent writer may have moved the task; skip rather than abort.\n try {\n const stalled = await stores.tasks.transition(task.id, \"stalled\", {\n reason: `no progress for ${Math.floor(sinceProgress / 60_000)} minutes (window ${minutes})`,\n expectFrom: \"running\",\n });\n result.stalled.push(task.id);\n newlyStalled.push(stalled);\n } catch {\n if (options.tasks !== undefined) {\n const current = await stores.tasks.get(task.id).catch(() => null);\n if (current?.state === \"stalled\") newlyStalled.push(current);\n }\n continue;\n }\n }\n\n // Resolve every stalled task, including ones stalled by an earlier pass that\n // crashed before reaching this step.\n const stalledCandidates =\n options.tasks === undefined\n ? await stores.tasks.list()\n : [...tasks.filter((task) => task.state === \"stalled\"), ...newlyStalled];\n for (const task of stalledCandidates) {\n if (task.waitingForMessages || task.state !== \"stalled\") {\n continue;\n }\n const cancellationReason = (await options.cancelStalled?.(task, tasks)) ?? null;\n try {\n if (cancellationReason !== null) {\n await stores.tasks.transition(task.id, \"cancelled\", {\n reason: cancellationReason,\n expectFrom: \"stalled\",\n });\n result.cancelled.push(task.id);\n } else if (task.attempt < options.policy.maxAttempts) {\n await stores.tasks.transition(task.id, \"queued\", {\n reason: `stalled on attempt ${task.attempt} of ${options.policy.maxAttempts}; replacing`,\n phase: \"retry\",\n expectFrom: \"stalled\",\n });\n result.requeued.push(task.id);\n } else {\n await stores.tasks.transition(task.id, \"failed\", {\n reason: `stalled on attempt ${task.attempt} of ${options.policy.maxAttempts}; attempts exhausted`,\n phase: \"retry\",\n expectFrom: \"stalled\",\n });\n result.failed.push(task.id);\n }\n } catch {\n continue;\n }\n }\n return result;\n}\n"],"mappings":";;AA4BA,SAAgB,mBAAmB,QAAyB,MAA4B;CACtF,OAAO,OAAO,mBAAmB,SAAS,OAAO;AACnD;;;;;;;;;AAUA,eAAsB,gBACpB,QACA,SAC+B;CAC/B,MAAM,SAAS,QAAQ,8BAAc,IAAI,KAAK,GAAA,CAAI,CAAC,CAAC,QAAQ;CAC5D,MAAM,SAKF;EACF,SAAS,CAAC;EACV,UAAU,CAAC;EACX,QAAQ,CAAC;EACT,WAAW,CAAC;CACd;CACA,MAAM,QAAQ,QAAQ,SAAU,MAAM,OAAO,MAAM,KAAK;CACxD,MAAM,eAAuB,CAAC;CAE9B,KAAK,MAAM,QAAQ,OAAO;EACxB,IAAI,KAAK,sBAAsB,KAAK,UAAU,WAC5C;EAEF,MAAM,UAAU,mBAAmB,QAAQ,QAAQ,KAAK,IAAI;EAC5D,MAAM,gBAAgB,QAAQ,KAAK,MAAM,KAAK,kBAAkB,KAAK,SAAS;EAC9E,IAAI,gBAAgB,UAAU,KAC5B;EAGF,IAAI;GACF,MAAM,UAAU,MAAM,OAAO,MAAM,WAAW,KAAK,IAAI,WAAW;IAChE,QAAQ,mBAAmB,KAAK,MAAM,gBAAgB,GAAM,EAAE,mBAAmB,QAAQ;IACzF,YAAY;GACd,CAAC;GACD,OAAO,QAAQ,KAAK,KAAK,EAAE;GAC3B,aAAa,KAAK,OAAO;EAC3B,QAAQ;GACN,IAAI,QAAQ,UAAU,KAAA,GAAW;IAC/B,MAAM,UAAU,MAAM,OAAO,MAAM,IAAI,KAAK,EAAE,CAAC,CAAC,YAAY,IAAI;IAChE,IAAI,SAAS,UAAU,WAAW,aAAa,KAAK,OAAO;GAC7D;GACA;EACF;CACF;CAIA,MAAM,oBACJ,QAAQ,UAAU,KAAA,IACd,MAAM,OAAO,MAAM,KAAK,IACxB,CAAC,GAAG,MAAM,QAAQ,SAAS,KAAK,UAAU,SAAS,GAAG,GAAG,YAAY;CAC3E,KAAK,MAAM,QAAQ,mBAAmB;EACpC,IAAI,KAAK,sBAAsB,KAAK,UAAU,WAC5C;EAEF,MAAM,qBAAsB,MAAM,QAAQ,gBAAgB,MAAM,KAAK,KAAM;EAC3E,IAAI;GACF,IAAI,uBAAuB,MAAM;IAC/B,MAAM,OAAO,MAAM,WAAW,KAAK,IAAI,aAAa;KAClD,QAAQ;KACR,YAAY;IACd,CAAC;IACD,OAAO,UAAU,KAAK,KAAK,EAAE;GAC/B,OAAO,IAAI,KAAK,UAAU,QAAQ,OAAO,aAAa;IACpD,MAAM,OAAO,MAAM,WAAW,KAAK,IAAI,UAAU;KAC/C,QAAQ,sBAAsB,KAAK,QAAQ,MAAM,QAAQ,OAAO,YAAY;KAC5E,OAAO;KACP,YAAY;IACd,CAAC;IACD,OAAO,SAAS,KAAK,KAAK,EAAE;GAC9B,OAAO;IACL,MAAM,OAAO,MAAM,WAAW,KAAK,IAAI,UAAU;KAC/C,QAAQ,sBAAsB,KAAK,QAAQ,MAAM,QAAQ,OAAO,YAAY;KAC5E,OAAO;KACP,YAAY;IACd,CAAC;IACD,OAAO,OAAO,KAAK,KAAK,EAAE;GAC5B;EACF,QAAQ;GACN;EACF;CACF;CACA,OAAO;AACT"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { CollectionName, InsertStoreRecordInput, RecordExistsError, RecordNotFoundError, StoreDriver, StoredEntry, StoredRecord, TransientStoreError, UpdateStoreRecordInput, VersionConflictError } from "./store/driver.mjs";
|
|
2
|
+
import { CacheContinuationContextInput, CreateStoresOptions, FactoryStores, createStores } from "./store/engine.mjs";
|
|
3
|
+
import { createInMemoryDriver } from "./store/memory.mjs";
|
|
4
|
+
export { type CacheContinuationContextInput, type CollectionName, type CreateStoresOptions, type FactoryStores, type InsertStoreRecordInput, RecordExistsError, RecordNotFoundError, type StoreDriver, type StoredEntry, type StoredRecord, TransientStoreError, type UpdateStoreRecordInput, VersionConflictError, createInMemoryDriver, createStores };
|
package/dist/storage.mjs
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { RecordExistsError, RecordNotFoundError, TransientStoreError, VersionConflictError } from "./store/driver.mjs";
|
|
2
|
+
import { createStores } from "./store/engine.mjs";
|
|
3
|
+
import { createInMemoryDriver } from "./store/memory.mjs";
|
|
4
|
+
export { RecordExistsError, RecordNotFoundError, TransientStoreError, VersionConflictError, createInMemoryDriver, createStores };
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
//#region src/store/driver.d.ts
|
|
2
|
+
/** Closed set of persistence collections understood by Factory store drivers. */
|
|
3
|
+
type CollectionName = "repositories" | "signals" | "tasks" | "changes" | "receipts" | "budgets" | "answers" | "sessions" | "externalSessions" | "transcripts" | "images" | "questionRoutes" | "taskCatalogs" | "changeCatalogs" | "sessionCatalogs" | "externalSessionCatalogs" | "taskRoutes" | "outboxQueues" | "outboxDeliveries" | "taskGraphs" | "taskMessages" | "taskEffects" | "taskInboxes" | "taskMessageProcessing" | "taskMessageDecisions" | "taskMessageDiscards" | "plannerActivations" | "plannerCancellations";
|
|
4
|
+
/** Opaque persisted value paired with its compare-and-swap version. */
|
|
5
|
+
interface StoredRecord {
|
|
6
|
+
readonly value: unknown;
|
|
7
|
+
readonly version: number;
|
|
8
|
+
}
|
|
9
|
+
/** Collection-listing entry containing its storage key and versioned record. */
|
|
10
|
+
interface StoredEntry {
|
|
11
|
+
readonly id: string;
|
|
12
|
+
readonly record: StoredRecord;
|
|
13
|
+
}
|
|
14
|
+
/** Collection, storage key, and opaque value for one insert-only write. */
|
|
15
|
+
interface InsertStoreRecordInput {
|
|
16
|
+
readonly collection: CollectionName;
|
|
17
|
+
readonly id: string;
|
|
18
|
+
readonly value: unknown;
|
|
19
|
+
}
|
|
20
|
+
/** Collection, storage key, opaque value, and compare-and-swap version for one update. */
|
|
21
|
+
interface UpdateStoreRecordInput extends InsertStoreRecordInput {
|
|
22
|
+
readonly expectedVersion: number;
|
|
23
|
+
}
|
|
24
|
+
/** Error raised when an insert targets an already occupied storage key. */
|
|
25
|
+
declare class RecordExistsError extends Error {
|
|
26
|
+
constructor(collection: CollectionName, id: string);
|
|
27
|
+
}
|
|
28
|
+
/** Error raised when an operation requires a storage record that does not exist. */
|
|
29
|
+
declare class RecordNotFoundError extends Error {
|
|
30
|
+
constructor(collection: CollectionName, id: string);
|
|
31
|
+
}
|
|
32
|
+
/** Error raised when atomic update loses its expected-version comparison. */
|
|
33
|
+
declare class VersionConflictError extends Error {
|
|
34
|
+
constructor(collection: CollectionName, id: string, expectedVersion: number);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* A transient infrastructure failure (network error, 5xx/429 response) that
|
|
38
|
+
* a driver's own bounded, backed-off low-level retries could not resolve.
|
|
39
|
+
* Distinct from VersionConflictError (a concurrent writer legitimately won)
|
|
40
|
+
* and from validation or "already exists" errors (the request itself is
|
|
41
|
+
* rejected): the same operation may still succeed if retried again later,
|
|
42
|
+
* but every caller retrying on this error must keep its own bound so a real
|
|
43
|
+
* outage surfaces as a failure instead of hanging a dispatch cycle.
|
|
44
|
+
*/
|
|
45
|
+
declare class TransientStoreError extends Error {
|
|
46
|
+
constructor(collection: CollectionName, id: string, cause: unknown);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Raw persistence contract. Drivers store opaque values and enforce nothing
|
|
50
|
+
* about their content; every invariant lives in the engine above. `update`
|
|
51
|
+
* must be an atomic compare-and-swap on `expectedVersion`. A driver may
|
|
52
|
+
* throw TransientStoreError for a read or write that failed only because of
|
|
53
|
+
* infrastructure trouble (network errors, 5xx/429 responses); it must not
|
|
54
|
+
* use TransientStoreError for version conflicts or malformed input.
|
|
55
|
+
*/
|
|
56
|
+
interface StoreDriver {
|
|
57
|
+
readonly name: string;
|
|
58
|
+
get(collection: CollectionName, id: string): Promise<StoredRecord | null>;
|
|
59
|
+
insert(input: InsertStoreRecordInput): Promise<void>;
|
|
60
|
+
update(input: UpdateStoreRecordInput): Promise<void>;
|
|
61
|
+
list(collection: CollectionName): Promise<readonly StoredEntry[]>;
|
|
62
|
+
}
|
|
63
|
+
//#endregion
|
|
64
|
+
export { CollectionName, InsertStoreRecordInput, RecordExistsError, RecordNotFoundError, StoreDriver, StoredEntry, StoredRecord, TransientStoreError, UpdateStoreRecordInput, VersionConflictError };
|
|
65
|
+
//# sourceMappingURL=driver.d.mts.map
|