@elie-laloum/outpost 3.0.0 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -0
- package/README.md +5 -3
- package/SECURITY.md +3 -1
- package/dist/adapters/agents/codex-adapter.js +2 -0
- package/dist/adapters/agents/codex-adapter.js.map +1 -1
- package/dist/adapters/agents/codex-provider.d.ts +2 -0
- package/dist/adapters/agents/codex-provider.js +32 -0
- package/dist/adapters/agents/codex-provider.js.map +1 -0
- package/dist/adapters/agents/codex-request.js +2 -1
- package/dist/adapters/agents/codex-request.js.map +1 -1
- package/dist/adapters/agents/gemini-adapter.d.ts +3 -0
- package/dist/adapters/agents/gemini-adapter.js +15 -0
- package/dist/adapters/agents/gemini-adapter.js.map +1 -0
- package/dist/adapters/agents/gemini-diagnostics.d.ts +2 -0
- package/dist/adapters/agents/gemini-diagnostics.js +15 -0
- package/dist/adapters/agents/gemini-diagnostics.js.map +1 -0
- package/dist/adapters/agents/gemini-events.d.ts +2 -0
- package/dist/adapters/agents/gemini-events.js +50 -0
- package/dist/adapters/agents/gemini-events.js.map +1 -0
- package/dist/adapters/agents/gemini-request.d.ts +4 -0
- package/dist/adapters/agents/gemini-request.js +23 -0
- package/dist/adapters/agents/gemini-request.js.map +1 -0
- package/dist/adapters/agents/gemini.types.d.ts +6 -0
- package/dist/adapters/agents/gemini.types.js +2 -0
- package/dist/adapters/agents/gemini.types.js.map +1 -0
- package/dist/adapters/agents/protocol-fixtures.constants.d.ts +1 -1
- package/dist/adapters/agents/protocol-fixtures.constants.js +37 -0
- package/dist/adapters/agents/protocol-fixtures.constants.js.map +1 -1
- package/dist/adapters/agents/settings.types.d.ts +5 -0
- package/dist/adapters/agents/settings.types.js.map +1 -1
- package/dist/application/agent-bootstrap.constants.d.ts +1 -0
- package/dist/application/agent-bootstrap.constants.js +1 -0
- package/dist/application/agent-bootstrap.constants.js.map +1 -1
- package/dist/application/agent-bootstrap.js +6 -2
- package/dist/application/agent-bootstrap.js.map +1 -1
- package/dist/application/agent-output.js +9 -2
- package/dist/application/agent-output.js.map +1 -1
- package/dist/application/artifact-tasks.d.ts +5 -0
- package/dist/application/artifact-tasks.js +31 -0
- package/dist/application/artifact-tasks.js.map +1 -0
- package/dist/application/artifact-tasks.types.d.ts +8 -0
- package/dist/application/artifact-tasks.types.js +2 -0
- package/dist/application/artifact-tasks.types.js.map +1 -0
- package/dist/application/dispatch-validation.js +2 -0
- package/dist/application/dispatch-validation.js.map +1 -1
- package/dist/application/doctor-agent.constants.d.ts +2 -0
- package/dist/application/doctor-agent.constants.js +2 -0
- package/dist/application/doctor-agent.constants.js.map +1 -1
- package/dist/application/doctor-agent.js +1 -1
- package/dist/application/doctor-agent.js.map +1 -1
- package/dist/application/doctor-protocol.js +2 -1
- package/dist/application/doctor-protocol.js.map +1 -1
- package/dist/application/doctor.constants.js +1 -1
- package/dist/application/doctor.constants.js.map +1 -1
- package/dist/application/doctor.types.d.ts +1 -1
- package/dist/application/doctor.types.js.map +1 -1
- package/dist/application/outpost.types.d.ts +2 -0
- package/dist/application/outpost.types.js.map +1 -1
- package/dist/application/queue-worker.d.ts +2 -0
- package/dist/application/queue-worker.js +75 -0
- package/dist/application/queue-worker.js.map +1 -0
- package/dist/application/queue-worker.types.d.ts +15 -0
- package/dist/application/queue-worker.types.js +2 -0
- package/dist/application/queue-worker.types.js.map +1 -0
- package/dist/application/queued-task.d.ts +3 -0
- package/dist/application/queued-task.js +56 -0
- package/dist/application/queued-task.js.map +1 -0
- package/dist/application/queued-task.types.d.ts +11 -0
- package/dist/application/queued-task.types.js +2 -0
- package/dist/application/queued-task.types.js.map +1 -0
- package/dist/application/recovery-inspection.js +5 -0
- package/dist/application/recovery-inspection.js.map +1 -1
- package/dist/application/recovery-inspection.types.d.ts +3 -0
- package/dist/application/recovery-inspection.types.js.map +1 -1
- package/dist/application/recovery-restore-snapshot.d.ts +2 -0
- package/dist/application/recovery-restore-snapshot.js +57 -0
- package/dist/application/recovery-restore-snapshot.js.map +1 -0
- package/dist/application/recovery-restore.d.ts +3 -0
- package/dist/application/recovery-restore.js +161 -0
- package/dist/application/recovery-restore.js.map +1 -0
- package/dist/application/recovery-restore.types.d.ts +28 -0
- package/dist/application/recovery-restore.types.js +2 -0
- package/dist/application/recovery-restore.types.js.map +1 -0
- package/dist/application/recovery-retention.js +5 -0
- package/dist/application/recovery-retention.js.map +1 -1
- package/dist/application/recovery-verification.d.ts +2 -1
- package/dist/application/recovery-verification.js +1 -1
- package/dist/application/recovery-verification.js.map +1 -1
- package/dist/application/remote-apply.js +6 -0
- package/dist/application/remote-apply.js.map +1 -1
- package/dist/application/remote-download.js +2 -2
- package/dist/application/remote-download.js.map +1 -1
- package/dist/application/remote-history.d.ts +6 -0
- package/dist/application/remote-history.js +114 -0
- package/dist/application/remote-history.js.map +1 -0
- package/dist/application/remote-upload.d.ts +2 -0
- package/dist/application/remote-upload.js +17 -0
- package/dist/application/remote-upload.js.map +1 -0
- package/dist/application/remote-validation.js +20 -28
- package/dist/application/remote-validation.js.map +1 -1
- package/dist/application/remote-workspace.js +4 -10
- package/dist/application/remote-workspace.js.map +1 -1
- package/dist/application/sandbox-activity.d.ts +3 -0
- package/dist/application/sandbox-activity.js +25 -0
- package/dist/application/sandbox-activity.js.map +1 -0
- package/dist/application/sandbox-provision.js +55 -10
- package/dist/application/sandbox-provision.js.map +1 -1
- package/dist/application/sandbox-session.types.d.ts +2 -0
- package/dist/application/sandbox-session.types.js.map +1 -1
- package/dist/application/sandbox.js +23 -11
- package/dist/application/sandbox.js.map +1 -1
- package/dist/application/speculation-host.d.ts +2 -0
- package/dist/application/speculation-host.js +30 -0
- package/dist/application/speculation-host.js.map +1 -0
- package/dist/application/speculation.constants.d.ts +4 -0
- package/dist/application/speculation.constants.js +2 -0
- package/dist/application/speculation.constants.js.map +1 -0
- package/dist/application/speculation.d.ts +2 -0
- package/dist/application/speculation.js +166 -0
- package/dist/application/speculation.js.map +1 -0
- package/dist/application/speculation.types.d.ts +56 -0
- package/dist/application/speculation.types.js +2 -0
- package/dist/application/speculation.types.js.map +1 -0
- package/dist/application/storage-reservation.d.ts +3 -0
- package/dist/application/storage-reservation.js +10 -0
- package/dist/application/storage-reservation.js.map +1 -0
- package/dist/application/storage-reservation.types.d.ts +4 -0
- package/dist/application/storage-reservation.types.js +2 -0
- package/dist/application/storage-reservation.types.js.map +1 -0
- package/dist/application/task-usage.d.ts +1 -1
- package/dist/application/task-usage.js.map +1 -1
- package/dist/application/tasks.js +1 -1
- package/dist/application/tasks.js.map +1 -1
- package/dist/application/tasks.types.d.ts +4 -3
- package/dist/application/tasks.types.js.map +1 -1
- package/dist/application/workspace-allocation.d.ts +3 -0
- package/dist/application/workspace-allocation.js +34 -0
- package/dist/application/workspace-allocation.js.map +1 -0
- package/dist/application/workspace.js +2 -2
- package/dist/application/workspace.js.map +1 -1
- package/dist/cli/commands.js +55 -18
- package/dist/cli/commands.js.map +1 -1
- package/dist/cli/doctor-command.js +1 -1
- package/dist/cli/doctor-command.js.map +1 -1
- package/dist/cli/init-authentication.constants.d.ts +13 -0
- package/dist/cli/init-authentication.constants.js +10 -0
- package/dist/cli/init-authentication.constants.js.map +1 -0
- package/dist/cli/init-authentication.d.ts +4 -0
- package/dist/cli/init-authentication.js +43 -0
- package/dist/cli/init-authentication.js.map +1 -0
- package/dist/cli/init-command.js +74 -15
- package/dist/cli/init-command.js.map +1 -1
- package/dist/cli/main.constants.d.ts +111 -2
- package/dist/cli/main.constants.js +148 -42
- package/dist/cli/main.constants.js.map +1 -1
- package/dist/cli/recovery-command.js +28 -4
- package/dist/cli/recovery-command.js.map +1 -1
- package/dist/cli/recovery-restore-command.d.ts +2 -0
- package/dist/cli/recovery-restore-command.js +34 -0
- package/dist/cli/recovery-restore-command.js.map +1 -0
- package/dist/cli/scaffold-files.js +3 -2
- package/dist/cli/scaffold-files.js.map +1 -1
- package/dist/cli/scaffold-validation.js +20 -1
- package/dist/cli/scaffold-validation.js.map +1 -1
- package/dist/cli/scaffold.constants.js +2 -2
- package/dist/cli/scaffold.constants.js.map +1 -1
- package/dist/cli/scaffold.js +13 -0
- package/dist/cli/scaffold.js.map +1 -1
- package/dist/cli/scaffold.types.d.ts +4 -1
- package/dist/cli/scaffold.types.js.map +1 -1
- package/dist/cli/starters.js +9 -2
- package/dist/cli/starters.js.map +1 -1
- package/dist/domain/agent.types.d.ts +2 -0
- package/dist/domain/agent.types.js.map +1 -1
- package/dist/domain/artifact-reference.d.ts +4 -0
- package/dist/domain/artifact-reference.js +90 -0
- package/dist/domain/artifact-reference.js.map +1 -0
- package/dist/domain/artifact.constants.d.ts +2 -0
- package/dist/domain/artifact.constants.js +3 -0
- package/dist/domain/artifact.constants.js.map +1 -0
- package/dist/domain/artifact.d.ts +7 -0
- package/dist/domain/artifact.js +104 -0
- package/dist/domain/artifact.js.map +1 -0
- package/dist/domain/artifact.types.d.ts +44 -0
- package/dist/domain/artifact.types.js +2 -0
- package/dist/domain/artifact.types.js.map +1 -0
- package/dist/domain/egress.constants.d.ts +1 -0
- package/dist/domain/egress.constants.js +7 -0
- package/dist/domain/egress.constants.js.map +1 -0
- package/dist/domain/egress.d.ts +2 -0
- package/dist/domain/egress.js +48 -0
- package/dist/domain/egress.js.map +1 -0
- package/dist/domain/egress.types.d.ts +8 -0
- package/dist/domain/egress.types.js +2 -0
- package/dist/domain/egress.types.js.map +1 -0
- package/dist/domain/sandbox.types.d.ts +1 -0
- package/dist/domain/sandbox.types.js.map +1 -1
- package/dist/domain/task-queue.constants.d.ts +8 -0
- package/dist/domain/task-queue.constants.js +9 -0
- package/dist/domain/task-queue.constants.js.map +1 -0
- package/dist/domain/task-queue.d.ts +11 -0
- package/dist/domain/task-queue.js +105 -0
- package/dist/domain/task-queue.js.map +1 -0
- package/dist/domain/task-queue.types.d.ts +41 -0
- package/dist/domain/task-queue.types.js +2 -0
- package/dist/domain/task-queue.types.js.map +1 -0
- package/dist/domain/workflow/budget.d.ts +2 -2
- package/dist/domain/workflow/budget.js +5 -3
- package/dist/domain/workflow/budget.js.map +1 -1
- package/dist/domain/workflow/checkpoint-validation.d.ts +3 -0
- package/dist/domain/workflow/checkpoint-validation.js +81 -0
- package/dist/domain/workflow/checkpoint-validation.js.map +1 -0
- package/dist/domain/workflow/checkpoint-value.d.ts +2 -0
- package/dist/domain/workflow/checkpoint-value.js +49 -0
- package/dist/domain/workflow/checkpoint-value.js.map +1 -0
- package/dist/domain/workflow/checkpoint.d.ts +3 -0
- package/dist/domain/workflow/checkpoint.js +70 -0
- package/dist/domain/workflow/checkpoint.js.map +1 -0
- package/dist/domain/workflow/checkpoint.types.d.ts +40 -0
- package/dist/domain/workflow/checkpoint.types.js +2 -0
- package/dist/domain/workflow/checkpoint.types.js.map +1 -0
- package/dist/domain/workflow/gate-validation.d.ts +4 -0
- package/dist/domain/workflow/gate-validation.js +71 -0
- package/dist/domain/workflow/gate-validation.js.map +1 -0
- package/dist/domain/workflow/gates.constants.d.ts +4 -0
- package/dist/domain/workflow/gates.constants.js +5 -0
- package/dist/domain/workflow/gates.constants.js.map +1 -0
- package/dist/domain/workflow/gates.d.ts +7 -0
- package/dist/domain/workflow/gates.js +85 -0
- package/dist/domain/workflow/gates.js.map +1 -0
- package/dist/domain/workflow/gates.types.d.ts +27 -0
- package/dist/domain/workflow/gates.types.js +2 -0
- package/dist/domain/workflow/gates.types.js.map +1 -0
- package/dist/domain/workflow/task-runner.js +14 -2
- package/dist/domain/workflow/task-runner.js.map +1 -1
- package/dist/domain/workflow/usage-receipt.constants.d.ts +2 -0
- package/dist/domain/workflow/usage-receipt.constants.js +3 -0
- package/dist/domain/workflow/usage-receipt.constants.js.map +1 -0
- package/dist/domain/workflow/usage-receipt.d.ts +2 -0
- package/dist/domain/workflow/usage-receipt.js +18 -0
- package/dist/domain/workflow/usage-receipt.js.map +1 -0
- package/dist/domain/workflow/validation.js +6 -0
- package/dist/domain/workflow/validation.js.map +1 -1
- package/dist/domain/workflow/workflow-scheduler.js +65 -32
- package/dist/domain/workflow/workflow-scheduler.js.map +1 -1
- package/dist/domain/workflow/workflow-state.d.ts +2 -1
- package/dist/domain/workflow/workflow-state.js +91 -16
- package/dist/domain/workflow/workflow-state.js.map +1 -1
- package/dist/domain/workflow.types.d.ts +13 -2
- package/dist/domain/workflow.types.js.map +1 -1
- package/dist/index.d.ts +32 -2
- package/dist/index.js +14 -1
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/artifact-store.constants.d.ts +1 -0
- package/dist/infrastructure/artifact-store.constants.js +2 -0
- package/dist/infrastructure/artifact-store.constants.js.map +1 -0
- package/dist/infrastructure/artifact-store.d.ts +3 -0
- package/dist/infrastructure/artifact-store.js +100 -0
- package/dist/infrastructure/artifact-store.js.map +1 -0
- package/dist/infrastructure/artifact-store.types.d.ts +4 -0
- package/dist/infrastructure/artifact-store.types.js +2 -0
- package/dist/infrastructure/artifact-store.types.js.map +1 -0
- package/dist/infrastructure/file-manifest.d.ts +1 -1
- package/dist/infrastructure/file-manifest.js +3 -2
- package/dist/infrastructure/file-manifest.js.map +1 -1
- package/dist/infrastructure/git/verification-command.d.ts +1 -1
- package/dist/infrastructure/git/verification-command.js +3 -2
- package/dist/infrastructure/git/verification-command.js.map +1 -1
- package/dist/infrastructure/opentelemetry.js +1 -1
- package/dist/infrastructure/opentelemetry.js.map +1 -1
- package/dist/infrastructure/resource-activity-inspection.d.ts +2 -0
- package/dist/infrastructure/resource-activity-inspection.js +152 -0
- package/dist/infrastructure/resource-activity-inspection.js.map +1 -0
- package/dist/infrastructure/resource-activity.constants.d.ts +8 -0
- package/dist/infrastructure/resource-activity.constants.js +26 -0
- package/dist/infrastructure/resource-activity.constants.js.map +1 -0
- package/dist/infrastructure/resource-activity.d.ts +2 -0
- package/dist/infrastructure/resource-activity.js +166 -0
- package/dist/infrastructure/resource-activity.js.map +1 -0
- package/dist/infrastructure/resource-activity.types.d.ts +53 -0
- package/dist/infrastructure/resource-activity.types.js +2 -0
- package/dist/infrastructure/resource-activity.types.js.map +1 -0
- package/dist/infrastructure/storage-mutation-lock.constants.d.ts +5 -0
- package/dist/infrastructure/storage-mutation-lock.constants.js +6 -0
- package/dist/infrastructure/storage-mutation-lock.constants.js.map +1 -0
- package/dist/infrastructure/storage-mutation-lock.d.ts +1 -0
- package/dist/infrastructure/storage-mutation-lock.js +21 -0
- package/dist/infrastructure/storage-mutation-lock.js.map +1 -0
- package/dist/infrastructure/storage-reservations.constants.d.ts +4 -0
- package/dist/infrastructure/storage-reservations.constants.js +5 -0
- package/dist/infrastructure/storage-reservations.constants.js.map +1 -0
- package/dist/infrastructure/storage-reservations.d.ts +2 -0
- package/dist/infrastructure/storage-reservations.js +150 -0
- package/dist/infrastructure/storage-reservations.js.map +1 -0
- package/dist/infrastructure/storage-reservations.types.d.ts +21 -0
- package/dist/infrastructure/storage-reservations.types.js +2 -0
- package/dist/infrastructure/storage-reservations.types.js.map +1 -0
- package/dist/infrastructure/task-queue-http.constants.d.ts +2 -0
- package/dist/infrastructure/task-queue-http.constants.js +3 -0
- package/dist/infrastructure/task-queue-http.constants.js.map +1 -0
- package/dist/infrastructure/task-queue-http.d.ts +4 -0
- package/dist/infrastructure/task-queue-http.js +158 -0
- package/dist/infrastructure/task-queue-http.js.map +1 -0
- package/dist/infrastructure/task-queue-http.types.d.ts +16 -0
- package/dist/infrastructure/task-queue-http.types.js +2 -0
- package/dist/infrastructure/task-queue-http.types.js.map +1 -0
- package/dist/infrastructure/task-queue.d.ts +2 -0
- package/dist/infrastructure/task-queue.js +134 -0
- package/dist/infrastructure/task-queue.js.map +1 -0
- package/dist/infrastructure/transfer.js +5 -0
- package/dist/infrastructure/transfer.js.map +1 -1
- package/dist/infrastructure/workflow-checkpoint.constants.d.ts +1 -0
- package/dist/infrastructure/workflow-checkpoint.constants.js +2 -0
- package/dist/infrastructure/workflow-checkpoint.constants.js.map +1 -0
- package/dist/infrastructure/workflow-checkpoint.d.ts +3 -0
- package/dist/infrastructure/workflow-checkpoint.js +77 -0
- package/dist/infrastructure/workflow-checkpoint.js.map +1 -0
- package/dist/infrastructure/workflow-checkpoint.types.d.ts +4 -0
- package/dist/infrastructure/workflow-checkpoint.types.js +2 -0
- package/dist/infrastructure/workflow-checkpoint.types.js.map +1 -0
- package/dist/providers/agents.d.ts +3 -1
- package/dist/providers/agents.js +1 -0
- package/dist/providers/agents.js.map +1 -1
- package/dist/providers/container-isolation.d.ts +2 -0
- package/dist/providers/container-isolation.js +29 -0
- package/dist/providers/container-isolation.js.map +1 -0
- package/dist/providers/container-mounts.js +7 -2
- package/dist/providers/container-mounts.js.map +1 -1
- package/dist/providers/container-network.d.ts +2 -0
- package/dist/providers/container-network.js +14 -0
- package/dist/providers/container-network.js.map +1 -0
- package/dist/providers/container-plan.js +4 -2
- package/dist/providers/container-plan.js.map +1 -1
- package/dist/providers/container.constants.d.ts +1 -0
- package/dist/providers/container.constants.js +1 -0
- package/dist/providers/container.constants.js.map +1 -1
- package/dist/providers/container.js +19 -2
- package/dist/providers/container.js.map +1 -1
- package/dist/providers/container.types.d.ts +3 -0
- package/dist/providers/container.types.js.map +1 -1
- package/dist/providers/daytona-command.constants.d.ts +2 -0
- package/dist/providers/daytona-command.constants.js +13 -0
- package/dist/providers/daytona-command.constants.js.map +1 -0
- package/dist/providers/daytona-command.js +12 -5
- package/dist/providers/daytona-command.js.map +1 -1
- package/dist/providers/daytona-output.d.ts +4 -0
- package/dist/providers/daytona-output.js +37 -0
- package/dist/providers/daytona-output.js.map +1 -0
- package/dist/providers/daytona-terminal.d.ts +3 -0
- package/dist/providers/daytona-terminal.js +130 -0
- package/dist/providers/daytona-terminal.js.map +1 -0
- package/dist/providers/daytona.js +2 -0
- package/dist/providers/daytona.js.map +1 -1
- package/dist/providers/docker.d.ts +1 -0
- package/dist/providers/docker.js.map +1 -1
- package/dist/providers/file-batches.d.ts +1 -1
- package/dist/providers/file-batches.js +9 -0
- package/dist/providers/file-batches.js.map +1 -1
- package/dist/providers/file-upload.constants.d.ts +1 -0
- package/dist/providers/file-upload.constants.js +68 -0
- package/dist/providers/file-upload.constants.js.map +1 -0
- package/dist/providers/file-upload.d.ts +2 -0
- package/dist/providers/file-upload.js +146 -0
- package/dist/providers/file-upload.js.map +1 -0
- package/dist/providers/firecracker-command.d.ts +5 -0
- package/dist/providers/firecracker-command.js +114 -0
- package/dist/providers/firecracker-command.js.map +1 -0
- package/dist/providers/firecracker-files.constants.d.ts +1 -0
- package/dist/providers/firecracker-files.constants.js +21 -0
- package/dist/providers/firecracker-files.constants.js.map +1 -0
- package/dist/providers/firecracker-files.d.ts +3 -0
- package/dist/providers/firecracker-files.js +110 -0
- package/dist/providers/firecracker-files.js.map +1 -0
- package/dist/providers/firecracker-machine.d.ts +3 -0
- package/dist/providers/firecracker-machine.js +155 -0
- package/dist/providers/firecracker-machine.js.map +1 -0
- package/dist/providers/firecracker.constants.d.ts +10 -0
- package/dist/providers/firecracker.constants.js +11 -0
- package/dist/providers/firecracker.constants.js.map +1 -0
- package/dist/providers/firecracker.d.ts +4 -0
- package/dist/providers/firecracker.js +103 -0
- package/dist/providers/firecracker.js.map +1 -0
- package/dist/providers/firecracker.types.d.ts +36 -0
- package/dist/providers/firecracker.types.js +2 -0
- package/dist/providers/firecracker.types.js.map +1 -0
- package/dist/providers/local.js +2 -1
- package/dist/providers/local.js.map +1 -1
- package/dist/providers/podman.d.ts +1 -0
- package/dist/providers/podman.js.map +1 -1
- package/dist/providers/terminal-bridge.d.ts +14 -0
- package/dist/providers/terminal-bridge.js +100 -0
- package/dist/providers/terminal-bridge.js.map +1 -0
- package/dist/providers/vercel-command.js +2 -2
- package/dist/providers/vercel-command.js.map +1 -1
- package/dist/providers/vercel-directory.d.ts +2 -0
- package/dist/providers/vercel-directory.js +7 -0
- package/dist/providers/vercel-directory.js.map +1 -0
- package/dist/providers/vercel-files.js +3 -2
- package/dist/providers/vercel-files.js.map +1 -1
- package/dist/providers/vercel-network.d.ts +2 -0
- package/dist/providers/vercel-network.js +18 -0
- package/dist/providers/vercel-network.js.map +1 -0
- package/dist/providers/vercel.d.ts +1 -0
- package/dist/providers/vercel.js +5 -1
- package/dist/providers/vercel.js.map +1 -1
- package/dist/providers/vercel.types.d.ts +2 -0
- package/dist/providers/vercel.types.js.map +1 -1
- package/dist/providers/versions.constants.d.ts +1 -0
- package/dist/providers/versions.constants.js +1 -0
- package/dist/providers/versions.constants.js.map +1 -1
- package/package.json +10 -2
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { isIP } from "node:net";
|
|
2
|
+
import { egressFields } from "./egress.constants.js";
|
|
3
|
+
import { invariant } from "./errors.js";
|
|
4
|
+
function entries(value, label, validate) {
|
|
5
|
+
if (value === undefined)
|
|
6
|
+
return [];
|
|
7
|
+
invariant(Array.isArray(value), `${label} must be an array`);
|
|
8
|
+
const items = Array.from(value);
|
|
9
|
+
invariant(items.every((entry) => typeof entry === "string" && validate(entry)), `Invalid ${label} entry`);
|
|
10
|
+
return [...new Set(items)];
|
|
11
|
+
}
|
|
12
|
+
function domain(value) {
|
|
13
|
+
const name = value.startsWith("*.") ? value.slice(2) : value;
|
|
14
|
+
return (name.length <= 253 &&
|
|
15
|
+
!isIP(name) &&
|
|
16
|
+
name.includes(".") &&
|
|
17
|
+
name
|
|
18
|
+
.split(".")
|
|
19
|
+
.every((label) => /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/i.test(label)));
|
|
20
|
+
}
|
|
21
|
+
function cidr(value) {
|
|
22
|
+
const parts = value.split("/");
|
|
23
|
+
if (parts.length !== 2)
|
|
24
|
+
return false;
|
|
25
|
+
const version = isIP(parts[0]);
|
|
26
|
+
return (version !== 0 &&
|
|
27
|
+
/^(0|[1-9][0-9]*)$/.test(parts[1]) &&
|
|
28
|
+
Number(parts[1]) <= (version === 4 ? 32 : 128) &&
|
|
29
|
+
!parts[0].includes("%"));
|
|
30
|
+
}
|
|
31
|
+
export function validateEgress(value) {
|
|
32
|
+
if (value === undefined)
|
|
33
|
+
return undefined;
|
|
34
|
+
invariant(value !== null && typeof value === "object" && !Array.isArray(value), "egress must be a policy object");
|
|
35
|
+
invariant("mode" in value, "egress requires a mode");
|
|
36
|
+
if (value.mode === "deny-all") {
|
|
37
|
+
invariant(Object.keys(value).every((key) => key === "mode"), "deny-all does not accept allowlist fields");
|
|
38
|
+
return { mode: "deny-all" };
|
|
39
|
+
}
|
|
40
|
+
invariant(value.mode === "allowlist", "egress mode must be deny-all or allowlist");
|
|
41
|
+
invariant(Object.keys(value).every((key) => egressFields.includes(key)), "Unknown egress policy field");
|
|
42
|
+
const domains = entries("domains" in value ? value.domains : undefined, "egress domains", domain);
|
|
43
|
+
const allowCidrs = entries("allowCidrs" in value ? value.allowCidrs : undefined, "egress allowCidrs", cidr);
|
|
44
|
+
const denyCidrs = entries("denyCidrs" in value ? value.denyCidrs : undefined, "egress denyCidrs", cidr);
|
|
45
|
+
invariant(domains.length + allowCidrs.length > 0, "egress allowlist requires an allowed domain or CIDR; use deny-all to block everything");
|
|
46
|
+
return { mode: "allowlist", domains, allowCidrs, denyCidrs };
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=egress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"egress.js","sourceRoot":"","sources":["../../src/domain/egress.ts"],"names":[],"mappings":"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","sourcesContent":["import { isIP } from \"node:net\";\nimport { egressFields } from \"./egress.constants.ts\";\nimport { invariant } from \"./errors.ts\";\nimport type { EgressPolicy } from \"./egress.types.ts\";\n\nfunction entries(\n value: unknown,\n label: string,\n validate: (entry: string) => boolean,\n): string[] {\n if (value === undefined) return [];\n invariant(Array.isArray(value), `${label} must be an array`);\n const items = Array.from(value);\n invariant(\n items.every((entry) => typeof entry === \"string\" && validate(entry)),\n `Invalid ${label} entry`,\n );\n return [...new Set<string>(items)];\n}\n\nfunction domain(value: string): boolean {\n const name = value.startsWith(\"*.\") ? value.slice(2) : value;\n return (\n name.length <= 253 &&\n !isIP(name) &&\n name.includes(\".\") &&\n name\n .split(\".\")\n .every((label) => /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/i.test(label))\n );\n}\n\nfunction cidr(value: string): boolean {\n const parts = value.split(\"/\");\n if (parts.length !== 2) return false;\n const version = isIP(parts[0]!);\n return (\n version !== 0 &&\n /^(0|[1-9][0-9]*)$/.test(parts[1]!) &&\n Number(parts[1]) <= (version === 4 ? 32 : 128) &&\n !parts[0]!.includes(\"%\")\n );\n}\n\nexport function validateEgress(value: unknown): EgressPolicy | undefined {\n if (value === undefined) return undefined;\n invariant(\n value !== null && typeof value === \"object\" && !Array.isArray(value),\n \"egress must be a policy object\",\n );\n invariant(\"mode\" in value, \"egress requires a mode\");\n if (value.mode === \"deny-all\") {\n invariant(\n Object.keys(value).every((key) => key === \"mode\"),\n \"deny-all does not accept allowlist fields\",\n );\n return { mode: \"deny-all\" };\n }\n invariant(\n value.mode === \"allowlist\",\n \"egress mode must be deny-all or allowlist\",\n );\n invariant(\n Object.keys(value).every((key) => egressFields.includes(key)),\n \"Unknown egress policy field\",\n );\n const domains = entries(\n \"domains\" in value ? value.domains : undefined,\n \"egress domains\",\n domain,\n );\n const allowCidrs = entries(\n \"allowCidrs\" in value ? value.allowCidrs : undefined,\n \"egress allowCidrs\",\n cidr,\n );\n const denyCidrs = entries(\n \"denyCidrs\" in value ? value.denyCidrs : undefined,\n \"egress denyCidrs\",\n cidr,\n );\n invariant(\n domains.length + allowCidrs.length > 0,\n \"egress allowlist requires an allowed domain or CIDR; use deny-all to block everything\",\n );\n return { mode: \"allowlist\", domains, allowCidrs, denyCidrs };\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"egress.types.js","sourceRoot":"","sources":["../../src/domain/egress.types.ts"],"names":[],"mappings":"","sourcesContent":["export type EgressPolicy =\n | { readonly mode: \"deny-all\" }\n | {\n readonly mode: \"allowlist\";\n readonly domains?: readonly string[];\n readonly allowCidrs?: readonly string[];\n readonly denyCidrs?: readonly string[];\n };\n"]}
|
|
@@ -23,6 +23,7 @@ export interface FileManifestEntry {
|
|
|
23
23
|
readonly sha256: string;
|
|
24
24
|
}
|
|
25
25
|
export interface FileTransfers {
|
|
26
|
+
uploadBatch?(source: string, entries: readonly FileManifestEntry[], destination: string, options?: TransferOptions): Promise<void>;
|
|
26
27
|
manifest(source: string, paths: readonly string[], options?: TransferOptions): Promise<readonly FileManifestEntry[]>;
|
|
27
28
|
downloadBatch(source: string, entries: readonly FileManifestEntry[], destination: string, options?: TransferOptions): Promise<void>;
|
|
28
29
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sandbox.types.js","sourceRoot":"","sources":["../../src/domain/sandbox.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { Command, CommandResult, Variables } from \"./command.types.ts\";\n\nexport interface Volume {\n readonly source: string;\n readonly target: string;\n readonly readOnly?: boolean;\n}\n\nexport interface SandboxContext {\n readonly repository: string;\n readonly directory: string;\n readonly gitDirectories: readonly string[];\n readonly variables: Variables;\n readonly signal?: AbortSignal;\n}\n\nexport interface TransferOptions {\n readonly signal?: AbortSignal;\n readonly deadlineMs?: number;\n}\n\nexport interface FileManifestEntry {\n readonly path: string;\n readonly kind: \"file\" | \"link\";\n readonly mode: number;\n readonly size: number;\n readonly sha256: string;\n}\n\nexport interface FileTransfers {\n manifest(\n source: string,\n paths: readonly string[],\n options?: TransferOptions,\n ): Promise<readonly FileManifestEntry[]>;\n downloadBatch(\n source: string,\n entries: readonly FileManifestEntry[],\n destination: string,\n options?: TransferOptions,\n ): Promise<void>;\n}\n\nexport interface SandboxLease {\n readonly fileTransfers?: FileTransfers;\n readonly root: string;\n readonly home: string;\n invoke(command: Command): Promise<CommandResult>;\n upload(\n source: string,\n destination: string,\n options?: TransferOptions,\n ): Promise<void>;\n download(\n source: string,\n destination: string,\n options?: TransferOptions,\n ): Promise<void>;\n release(): Promise<void>;\n}\n\nexport interface SandboxProvider {\n readonly name: string;\n readonly placement: \"mounted\" | \"remote\" | \"host\";\n readonly variables?: Variables;\n acquire(context: SandboxContext): Promise<SandboxLease>;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"sandbox.types.js","sourceRoot":"","sources":["../../src/domain/sandbox.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { Command, CommandResult, Variables } from \"./command.types.ts\";\n\nexport interface Volume {\n readonly source: string;\n readonly target: string;\n readonly readOnly?: boolean;\n}\n\nexport interface SandboxContext {\n readonly repository: string;\n readonly directory: string;\n readonly gitDirectories: readonly string[];\n readonly variables: Variables;\n readonly signal?: AbortSignal;\n}\n\nexport interface TransferOptions {\n readonly signal?: AbortSignal;\n readonly deadlineMs?: number;\n}\n\nexport interface FileManifestEntry {\n readonly path: string;\n readonly kind: \"file\" | \"link\";\n readonly mode: number;\n readonly size: number;\n readonly sha256: string;\n}\n\nexport interface FileTransfers {\n uploadBatch?(\n source: string,\n entries: readonly FileManifestEntry[],\n destination: string,\n options?: TransferOptions,\n ): Promise<void>;\n manifest(\n source: string,\n paths: readonly string[],\n options?: TransferOptions,\n ): Promise<readonly FileManifestEntry[]>;\n downloadBatch(\n source: string,\n entries: readonly FileManifestEntry[],\n destination: string,\n options?: TransferOptions,\n ): Promise<void>;\n}\n\nexport interface SandboxLease {\n readonly fileTransfers?: FileTransfers;\n readonly root: string;\n readonly home: string;\n invoke(command: Command): Promise<CommandResult>;\n upload(\n source: string,\n destination: string,\n options?: TransferOptions,\n ): Promise<void>;\n download(\n source: string,\n destination: string,\n options?: TransferOptions,\n ): Promise<void>;\n release(): Promise<void>;\n}\n\nexport interface SandboxProvider {\n readonly name: string;\n readonly placement: \"mounted\" | \"remote\" | \"host\";\n readonly variables?: Variables;\n acquire(context: SandboxContext): Promise<SandboxLease>;\n}\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const queueMaxBytes = 1048576;
|
|
2
|
+
export declare const queueMaxValueBytes = 262144;
|
|
3
|
+
export declare const queueDefaultLeaseMs = 30000;
|
|
4
|
+
export declare const queueDefaultPollMs = 250;
|
|
5
|
+
export declare const queueMaxLeaseMs = 300000;
|
|
6
|
+
export declare const queueMaxStringLength = 512;
|
|
7
|
+
export declare const queueMinLeaseMs = 30;
|
|
8
|
+
export declare const queueMaxHandlers = 100;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export const queueMaxBytes = 1_048_576;
|
|
2
|
+
export const queueMaxValueBytes = 262_144;
|
|
3
|
+
export const queueDefaultLeaseMs = 30_000;
|
|
4
|
+
export const queueDefaultPollMs = 250;
|
|
5
|
+
export const queueMaxLeaseMs = 300_000;
|
|
6
|
+
export const queueMaxStringLength = 512;
|
|
7
|
+
export const queueMinLeaseMs = 30;
|
|
8
|
+
export const queueMaxHandlers = 100;
|
|
9
|
+
//# sourceMappingURL=task-queue.constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-queue.constants.js","sourceRoot":"","sources":["../../src/domain/task-queue.constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,aAAa,GAAG,SAAS,CAAC;AACvC,MAAM,CAAC,MAAM,kBAAkB,GAAG,OAAO,CAAC;AAC1C,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC;AAC1C,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,CAAC;AACtC,MAAM,CAAC,MAAM,eAAe,GAAG,OAAO,CAAC;AACvC,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAG,CAAC;AACxC,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,CAAC;AAClC,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,CAAC","sourcesContent":["export const queueMaxBytes = 1_048_576;\nexport const queueMaxValueBytes = 262_144;\nexport const queueDefaultLeaseMs = 30_000;\nexport const queueDefaultPollMs = 250;\nexport const queueMaxLeaseMs = 300_000;\nexport const queueMaxStringLength = 512;\nexport const queueMinLeaseMs = 30;\nexport const queueMaxHandlers = 100;\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { QueueClaim, QueueJob, QueueLease, QueueRequest, QueueResult } from "./task-queue.types.ts";
|
|
2
|
+
export declare function queueObject(value: unknown): Record<string, unknown>;
|
|
3
|
+
export declare function queueString(value: unknown): string;
|
|
4
|
+
export declare function queueNumber(value: unknown): number;
|
|
5
|
+
export declare function queueLeaseMs(value: unknown): number;
|
|
6
|
+
export declare function queueJson(value: unknown): import("./workflow/checkpoint.types.ts").WorkflowJson;
|
|
7
|
+
export declare function queueRequest(value: unknown): QueueRequest;
|
|
8
|
+
export declare function queueClaim(value: unknown): QueueClaim;
|
|
9
|
+
export declare function queueLease(value: unknown): QueueLease;
|
|
10
|
+
export declare function queueResult(value: unknown): QueueResult;
|
|
11
|
+
export declare function queueJob(value: unknown): QueueJob;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { queueMaxValueBytes, queueMaxLeaseMs, queueMaxStringLength, queueMinLeaseMs, queueMaxHandlers, } from "./task-queue.constants.js";
|
|
2
|
+
import { checkpointValue } from "./workflow/checkpoint-value.js";
|
|
3
|
+
export function queueObject(value) {
|
|
4
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
5
|
+
throw new Error("Invalid queue object");
|
|
6
|
+
return Object.fromEntries(Object.entries(value));
|
|
7
|
+
}
|
|
8
|
+
export function queueString(value) {
|
|
9
|
+
if (typeof value !== "string" ||
|
|
10
|
+
!value.length ||
|
|
11
|
+
value.length > queueMaxStringLength)
|
|
12
|
+
throw new Error("Invalid queue identifier");
|
|
13
|
+
return value;
|
|
14
|
+
}
|
|
15
|
+
export function queueNumber(value) {
|
|
16
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0)
|
|
17
|
+
throw new Error("Invalid queue number");
|
|
18
|
+
return value;
|
|
19
|
+
}
|
|
20
|
+
export function queueLeaseMs(value) {
|
|
21
|
+
const ms = queueNumber(value);
|
|
22
|
+
if (ms < queueMinLeaseMs || ms > queueMaxLeaseMs)
|
|
23
|
+
throw new Error("Queue lease must be between 30 and 300000 milliseconds");
|
|
24
|
+
return ms;
|
|
25
|
+
}
|
|
26
|
+
export function queueJson(value) {
|
|
27
|
+
const checked = checkpointValue(value);
|
|
28
|
+
if (checked.kind !== "json")
|
|
29
|
+
throw new Error("Queue values must be JSON");
|
|
30
|
+
if (Buffer.byteLength(JSON.stringify(checked.value)) > queueMaxValueBytes)
|
|
31
|
+
throw new Error("Queue value exceeds size limit");
|
|
32
|
+
return checked.value;
|
|
33
|
+
}
|
|
34
|
+
export function queueRequest(value) {
|
|
35
|
+
const data = queueObject(value);
|
|
36
|
+
return {
|
|
37
|
+
id: queueString(data.id),
|
|
38
|
+
handler: queueString(data.handler),
|
|
39
|
+
input: queueJson(data.input),
|
|
40
|
+
...(data.deadline === undefined
|
|
41
|
+
? {}
|
|
42
|
+
: { deadline: queueNumber(data.deadline) }),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
export function queueClaim(value) {
|
|
46
|
+
const data = queueObject(value);
|
|
47
|
+
if (!Array.isArray(data.handlers) ||
|
|
48
|
+
!data.handlers.length ||
|
|
49
|
+
data.handlers.length > queueMaxHandlers)
|
|
50
|
+
throw new Error("Invalid queue handlers");
|
|
51
|
+
return {
|
|
52
|
+
worker: queueString(data.worker),
|
|
53
|
+
handlers: data.handlers.map(queueString),
|
|
54
|
+
leaseMs: queueLeaseMs(data.leaseMs),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
export function queueLease(value) {
|
|
58
|
+
const data = queueObject(value);
|
|
59
|
+
return {
|
|
60
|
+
id: queueString(data.id),
|
|
61
|
+
worker: queueString(data.worker),
|
|
62
|
+
fence: queueNumber(data.fence),
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
export function queueResult(value) {
|
|
66
|
+
const data = queueObject(value);
|
|
67
|
+
const usage = data.usage === undefined ? undefined : queueObject(data.usage);
|
|
68
|
+
return {
|
|
69
|
+
value: queueJson(data.value),
|
|
70
|
+
...(data.error === undefined ? {} : { error: queueString(data.error) }),
|
|
71
|
+
...(usage === undefined
|
|
72
|
+
? {}
|
|
73
|
+
: {
|
|
74
|
+
usage: {
|
|
75
|
+
input: queueNumber(usage.input),
|
|
76
|
+
output: queueNumber(usage.output),
|
|
77
|
+
cached: queueNumber(usage.cached),
|
|
78
|
+
...(usage.cacheCreated === undefined
|
|
79
|
+
? {}
|
|
80
|
+
: { cacheCreated: queueNumber(usage.cacheCreated) }),
|
|
81
|
+
},
|
|
82
|
+
}),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
export function queueJob(value) {
|
|
86
|
+
const data = queueObject(value);
|
|
87
|
+
const status = data.status;
|
|
88
|
+
if (status !== "pending" &&
|
|
89
|
+
status !== "active" &&
|
|
90
|
+
status !== "done" &&
|
|
91
|
+
status !== "failed" &&
|
|
92
|
+
status !== "cancelled")
|
|
93
|
+
throw new Error("Invalid queue status");
|
|
94
|
+
return {
|
|
95
|
+
...queueRequest(data),
|
|
96
|
+
status,
|
|
97
|
+
fence: queueNumber(data.fence),
|
|
98
|
+
...(data.worker === undefined ? {} : { worker: queueString(data.worker) }),
|
|
99
|
+
...(data.expires === undefined
|
|
100
|
+
? {}
|
|
101
|
+
: { expires: queueNumber(data.expires) }),
|
|
102
|
+
...(data.result === undefined ? {} : { result: queueResult(data.result) }),
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=task-queue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-queue.js","sourceRoot":"","sources":["../../src/domain/task-queue.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n QueueClaim,\n QueueJob,\n QueueLease,\n QueueRequest,\n QueueResult,\n} from \"./task-queue.types.ts\";\nimport {\n queueMaxValueBytes,\n queueMaxLeaseMs,\n queueMaxStringLength,\n queueMinLeaseMs,\n queueMaxHandlers,\n} from \"./task-queue.constants.ts\";\nimport { checkpointValue } from \"./workflow/checkpoint-value.ts\";\n\nexport function queueObject(value: unknown): Record<string, unknown> {\n if (!value || typeof value !== \"object\" || Array.isArray(value))\n throw new Error(\"Invalid queue object\");\n return Object.fromEntries(Object.entries(value));\n}\nexport function queueString(value: unknown): string {\n if (\n typeof value !== \"string\" ||\n !value.length ||\n value.length > queueMaxStringLength\n )\n throw new Error(\"Invalid queue identifier\");\n return value;\n}\nexport function queueNumber(value: unknown): number {\n if (typeof value !== \"number\" || !Number.isSafeInteger(value) || value < 0)\n throw new Error(\"Invalid queue number\");\n return value;\n}\nexport function queueLeaseMs(value: unknown): number {\n const ms = queueNumber(value);\n if (ms < queueMinLeaseMs || ms > queueMaxLeaseMs)\n throw new Error(\"Queue lease must be between 30 and 300000 milliseconds\");\n return ms;\n}\nexport function queueJson(value: unknown) {\n const checked = checkpointValue(value);\n if (checked.kind !== \"json\") throw new Error(\"Queue values must be JSON\");\n if (Buffer.byteLength(JSON.stringify(checked.value)) > queueMaxValueBytes)\n throw new Error(\"Queue value exceeds size limit\");\n return checked.value;\n}\nexport function queueRequest(value: unknown): QueueRequest {\n const data = queueObject(value);\n return {\n id: queueString(data.id),\n handler: queueString(data.handler),\n input: queueJson(data.input),\n ...(data.deadline === undefined\n ? {}\n : { deadline: queueNumber(data.deadline) }),\n };\n}\nexport function queueClaim(value: unknown): QueueClaim {\n const data = queueObject(value);\n if (\n !Array.isArray(data.handlers) ||\n !data.handlers.length ||\n data.handlers.length > queueMaxHandlers\n )\n throw new Error(\"Invalid queue handlers\");\n return {\n worker: queueString(data.worker),\n handlers: data.handlers.map(queueString),\n leaseMs: queueLeaseMs(data.leaseMs),\n };\n}\nexport function queueLease(value: unknown): QueueLease {\n const data = queueObject(value);\n return {\n id: queueString(data.id),\n worker: queueString(data.worker),\n fence: queueNumber(data.fence),\n };\n}\nexport function queueResult(value: unknown): QueueResult {\n const data = queueObject(value);\n const usage = data.usage === undefined ? undefined : queueObject(data.usage);\n return {\n value: queueJson(data.value),\n ...(data.error === undefined ? {} : { error: queueString(data.error) }),\n ...(usage === undefined\n ? {}\n : {\n usage: {\n input: queueNumber(usage.input),\n output: queueNumber(usage.output),\n cached: queueNumber(usage.cached),\n ...(usage.cacheCreated === undefined\n ? {}\n : { cacheCreated: queueNumber(usage.cacheCreated) }),\n },\n }),\n };\n}\nexport function queueJob(value: unknown): QueueJob {\n const data = queueObject(value);\n const status = data.status;\n if (\n status !== \"pending\" &&\n status !== \"active\" &&\n status !== \"done\" &&\n status !== \"failed\" &&\n status !== \"cancelled\"\n )\n throw new Error(\"Invalid queue status\");\n return {\n ...queueRequest(data),\n status,\n fence: queueNumber(data.fence),\n ...(data.worker === undefined ? {} : { worker: queueString(data.worker) }),\n ...(data.expires === undefined\n ? {}\n : { expires: queueNumber(data.expires) }),\n ...(data.result === undefined ? {} : { result: queueResult(data.result) }),\n };\n}\n"]}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Usage } from "./agent.types.ts";
|
|
2
|
+
import type { WorkflowJson } from "./workflow/checkpoint.types.ts";
|
|
3
|
+
export interface QueueRequest {
|
|
4
|
+
readonly id: string;
|
|
5
|
+
readonly handler: string;
|
|
6
|
+
readonly input: WorkflowJson;
|
|
7
|
+
readonly deadline?: number;
|
|
8
|
+
}
|
|
9
|
+
export interface QueueResult {
|
|
10
|
+
readonly value: WorkflowJson;
|
|
11
|
+
readonly usage?: Usage;
|
|
12
|
+
readonly error?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface QueueJob extends QueueRequest {
|
|
15
|
+
readonly status: "pending" | "active" | "done" | "failed" | "cancelled";
|
|
16
|
+
readonly fence: number;
|
|
17
|
+
readonly worker?: string;
|
|
18
|
+
readonly expires?: number;
|
|
19
|
+
readonly result?: QueueResult;
|
|
20
|
+
}
|
|
21
|
+
export interface QueueClaim {
|
|
22
|
+
readonly worker: string;
|
|
23
|
+
readonly handlers: readonly string[];
|
|
24
|
+
readonly leaseMs: number;
|
|
25
|
+
}
|
|
26
|
+
export interface QueueLease {
|
|
27
|
+
readonly id: string;
|
|
28
|
+
readonly worker: string;
|
|
29
|
+
readonly fence: number;
|
|
30
|
+
}
|
|
31
|
+
export interface TaskQueue {
|
|
32
|
+
enqueue(request: QueueRequest): Promise<QueueJob>;
|
|
33
|
+
get(id: string): Promise<QueueJob | undefined>;
|
|
34
|
+
claim(request: QueueClaim): Promise<QueueJob | undefined>;
|
|
35
|
+
renew(lease: QueueLease, leaseMs: number): Promise<QueueJob>;
|
|
36
|
+
complete(lease: QueueLease, result: QueueResult): Promise<QueueJob>;
|
|
37
|
+
cancel(id: string, fence: number): Promise<QueueJob>;
|
|
38
|
+
}
|
|
39
|
+
export interface DurableTaskQueue extends TaskQueue {
|
|
40
|
+
close(): void;
|
|
41
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-queue.types.js","sourceRoot":"","sources":["../../src/domain/task-queue.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { Usage } from \"./agent.types.ts\";\nimport type { WorkflowJson } from \"./workflow/checkpoint.types.ts\";\n\nexport interface QueueRequest {\n readonly id: string;\n readonly handler: string;\n readonly input: WorkflowJson;\n readonly deadline?: number;\n}\nexport interface QueueResult {\n readonly value: WorkflowJson;\n readonly usage?: Usage;\n readonly error?: string;\n}\nexport interface QueueJob extends QueueRequest {\n readonly status: \"pending\" | \"active\" | \"done\" | \"failed\" | \"cancelled\";\n readonly fence: number;\n readonly worker?: string;\n readonly expires?: number;\n readonly result?: QueueResult;\n}\nexport interface QueueClaim {\n readonly worker: string;\n readonly handlers: readonly string[];\n readonly leaseMs: number;\n}\nexport interface QueueLease {\n readonly id: string;\n readonly worker: string;\n readonly fence: number;\n}\nexport interface TaskQueue {\n enqueue(request: QueueRequest): Promise<QueueJob>;\n get(id: string): Promise<QueueJob | undefined>;\n claim(request: QueueClaim): Promise<QueueJob | undefined>;\n renew(lease: QueueLease, leaseMs: number): Promise<QueueJob>;\n complete(lease: QueueLease, result: QueueResult): Promise<QueueJob>;\n cancel(id: string, fence: number): Promise<QueueJob>;\n}\nexport interface DurableTaskQueue extends TaskQueue {\n close(): void;\n}\n"]}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { Usage } from "../agent.types.ts";
|
|
2
|
-
import type { WorkflowAccounting, WorkflowBudget } from "./budget.types.ts";
|
|
2
|
+
import type { WorkflowAccounting, WorkflowBudget, WorkflowUsage } from "./budget.types.ts";
|
|
3
3
|
export declare class WorkflowBudgetExceeded extends Error {
|
|
4
4
|
readonly dimension: "attempts" | keyof Usage;
|
|
5
5
|
readonly limit: number;
|
|
6
6
|
readonly observed: number;
|
|
7
7
|
constructor(dimension: "attempts" | keyof Usage, limit: number, observed: number);
|
|
8
8
|
}
|
|
9
|
-
export declare function workflowAccounting(budget: WorkflowBudget | undefined, exhaust: (error: WorkflowBudgetExceeded) => void): WorkflowAccounting;
|
|
9
|
+
export declare function workflowAccounting(budget: WorkflowBudget | undefined, exhaust: (error: WorkflowBudgetExceeded) => void, initial?: WorkflowUsage): WorkflowAccounting;
|
|
@@ -12,7 +12,7 @@ export class WorkflowBudgetExceeded extends Error {
|
|
|
12
12
|
this.observed = observed;
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
|
-
export function workflowAccounting(budget, exhaust) {
|
|
15
|
+
export function workflowAccounting(budget, exhaust, initial) {
|
|
16
16
|
for (const [key, value] of Object.entries({
|
|
17
17
|
attempts: budget?.attempts,
|
|
18
18
|
...budget?.usage,
|
|
@@ -20,8 +20,10 @@ export function workflowAccounting(budget, exhaust) {
|
|
|
20
20
|
if (value !== undefined && (!Number.isSafeInteger(value) || value < 0))
|
|
21
21
|
throw new Error(`Workflow budget ${key} must be a nonnegative safe integer`);
|
|
22
22
|
}
|
|
23
|
-
let attempts = 0;
|
|
24
|
-
let tokens =
|
|
23
|
+
let attempts = initial?.attempts ?? 0;
|
|
24
|
+
let tokens = initial
|
|
25
|
+
? { ...initial.tokens }
|
|
26
|
+
: { input: 0, cached: 0, output: 0 };
|
|
25
27
|
let exhausted = false;
|
|
26
28
|
let usageExhausted = false;
|
|
27
29
|
function fail(dimension, limit, observed) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"budget.js","sourceRoot":"","sources":["../../../src/domain/workflow/budget.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"budget.js","sourceRoot":"","sources":["../../../src/domain/workflow/budget.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Usage } from \"../agent.types.ts\";\nimport { addUsage } from \"../usage.ts\";\nimport { usageDimensions } from \"./budget.constants.ts\";\nimport type {\n WorkflowAccounting,\n WorkflowBudget,\n WorkflowUsage,\n} from \"./budget.types.ts\";\n\nexport class WorkflowBudgetExceeded extends Error {\n readonly dimension: \"attempts\" | keyof Usage;\n readonly limit: number;\n readonly observed: number;\n constructor(\n dimension: \"attempts\" | keyof Usage,\n limit: number,\n observed: number,\n ) {\n super(\n `Workflow budget exhausted: ${dimension} limit ${limit}, observed ${observed}`,\n );\n this.name = \"WorkflowBudgetExceeded\";\n this.dimension = dimension;\n this.limit = limit;\n this.observed = observed;\n }\n}\n\nexport function workflowAccounting(\n budget: WorkflowBudget | undefined,\n exhaust: (error: WorkflowBudgetExceeded) => void,\n initial?: WorkflowUsage,\n): WorkflowAccounting {\n for (const [key, value] of Object.entries({\n attempts: budget?.attempts,\n ...budget?.usage,\n })) {\n if (value !== undefined && (!Number.isSafeInteger(value) || value < 0))\n throw new Error(\n `Workflow budget ${key} must be a nonnegative safe integer`,\n );\n }\n let attempts = initial?.attempts ?? 0;\n let tokens: Usage = initial\n ? { ...initial.tokens }\n : { input: 0, cached: 0, output: 0 };\n let exhausted = false;\n let usageExhausted = false;\n function fail(\n dimension: \"attempts\" | keyof Usage,\n limit: number,\n observed: number,\n ): WorkflowBudgetExceeded {\n const error = new WorkflowBudgetExceeded(dimension, limit, observed);\n if (!exhausted || (dimension !== \"attempts\" && !usageExhausted)) {\n exhausted = true;\n if (dimension !== \"attempts\") usageExhausted = true;\n exhaust(error);\n }\n return error;\n }\n return {\n get exhausted() {\n return exhausted;\n },\n admit() {\n if (budget?.attempts !== undefined && attempts >= budget.attempts)\n throw fail(\"attempts\", budget.attempts, attempts);\n for (const dimension of usageDimensions) {\n const limit = budget?.usage?.[dimension];\n if (limit !== undefined && (tokens[dimension] ?? 0) >= limit)\n throw fail(dimension, limit, tokens[dimension] ?? 0);\n }\n attempts++;\n },\n report(usage) {\n for (const dimension of usageDimensions) {\n const value = usage[dimension] ?? 0;\n if (!Number.isSafeInteger(value) || value < 0)\n throw new Error(\n `Reported usage ${dimension} must be a nonnegative safe integer`,\n );\n }\n tokens = addUsage(tokens, usage);\n for (const dimension of usageDimensions) {\n const limit = budget?.usage?.[dimension];\n if (limit !== undefined && (tokens[dimension] ?? 0) >= limit)\n fail(dimension, limit, tokens[dimension] ?? 0);\n }\n },\n snapshot: () =>\n Object.freeze({ attempts, tokens: Object.freeze({ ...tokens }) }),\n };\n}\n"]}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { validateUsageReceipts } from "./usage-receipt.js";
|
|
2
|
+
import { validateGateRecord } from "./gate-validation.js";
|
|
3
|
+
import { checkpointValue } from "./checkpoint-value.js";
|
|
4
|
+
function object(value) {
|
|
5
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
6
|
+
}
|
|
7
|
+
function integer(value) {
|
|
8
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
|
|
9
|
+
}
|
|
10
|
+
export function validateCheckpoint(value, identity, tasks) {
|
|
11
|
+
const invalid = () => new Error("Invalid or incompatible workflow checkpoint");
|
|
12
|
+
if (!object(value) ||
|
|
13
|
+
value.format !== 1 ||
|
|
14
|
+
value.identity !== identity ||
|
|
15
|
+
typeof value.executionId !== "string" ||
|
|
16
|
+
!value.executionId ||
|
|
17
|
+
!Array.isArray(value.records) ||
|
|
18
|
+
!object(value.values) ||
|
|
19
|
+
!object(value.usage))
|
|
20
|
+
throw invalid();
|
|
21
|
+
if (!integer(value.usage.attempts) || !object(value.usage.tokens))
|
|
22
|
+
throw invalid();
|
|
23
|
+
for (const dimension of ["input", "cached", "output"])
|
|
24
|
+
if (!integer(value.usage.tokens[dimension]))
|
|
25
|
+
throw invalid();
|
|
26
|
+
for (const count of Object.values(value.usage.tokens))
|
|
27
|
+
if (!integer(count))
|
|
28
|
+
throw invalid();
|
|
29
|
+
if (value.records.length !== tasks.length)
|
|
30
|
+
throw invalid();
|
|
31
|
+
const keys = new Set(tasks.map((item) => item.key));
|
|
32
|
+
let attempts = 0;
|
|
33
|
+
for (const record of value.records) {
|
|
34
|
+
if (!object(record) ||
|
|
35
|
+
typeof record.key !== "string" ||
|
|
36
|
+
!keys.delete(record.key) ||
|
|
37
|
+
!integer(record.attempts) ||
|
|
38
|
+
![
|
|
39
|
+
"waiting",
|
|
40
|
+
"active",
|
|
41
|
+
"done",
|
|
42
|
+
"failed",
|
|
43
|
+
"skipped",
|
|
44
|
+
"cancelled",
|
|
45
|
+
"paused",
|
|
46
|
+
"rejected",
|
|
47
|
+
].includes(String(record.status)))
|
|
48
|
+
throw invalid();
|
|
49
|
+
for (const field of ["startedAt", "finishedAt", "error"])
|
|
50
|
+
if (record[field] !== undefined && typeof record[field] !== "string")
|
|
51
|
+
throw invalid();
|
|
52
|
+
validateUsageReceipts(record.usageReceipts);
|
|
53
|
+
attempts += record.attempts;
|
|
54
|
+
const output = Object.hasOwn(value.values, record.key)
|
|
55
|
+
? value.values[record.key]
|
|
56
|
+
: undefined;
|
|
57
|
+
validateGateRecord(record, tasks.find((item) => item.key === record.key), value.executionId, output);
|
|
58
|
+
if (record.status !== "done") {
|
|
59
|
+
if (output !== undefined)
|
|
60
|
+
throw invalid();
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (!object(output) || !["undefined", "json"].includes(String(output.kind)))
|
|
64
|
+
throw invalid();
|
|
65
|
+
if (output.kind === "json") {
|
|
66
|
+
if (!Object.hasOwn(output, "value") || output.value === undefined)
|
|
67
|
+
throw invalid();
|
|
68
|
+
checkpointValue(output.value);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (attempts !== value.usage.attempts)
|
|
72
|
+
throw invalid();
|
|
73
|
+
if (Object.keys(value.values).some((key) => !tasks.some((item) => item.key === key)))
|
|
74
|
+
throw invalid();
|
|
75
|
+
const records = new Map(value.records.map((entry) => [entry.key, entry]));
|
|
76
|
+
for (const item of tasks)
|
|
77
|
+
if (["done", "paused", "rejected"].includes(String(records.get(item.key)?.status)) &&
|
|
78
|
+
item.after.some((dependency) => records.get(dependency.key)?.status !== "done"))
|
|
79
|
+
throw invalid();
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=checkpoint-validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkpoint-validation.js","sourceRoot":"","sources":["../../../src/domain/workflow/checkpoint-validation.ts"],"names":[],"mappings":"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","sourcesContent":["import { validateUsageReceipts } from \"./usage-receipt.ts\";\nimport { validateGateRecord } from \"./gate-validation.ts\";\nimport type { WorkflowCheckpoint } from \"./checkpoint.types.ts\";\nimport type { Task } from \"../workflow.types.ts\";\nimport { checkpointValue } from \"./checkpoint-value.ts\";\n\nfunction object(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\nfunction integer(value: unknown): value is number {\n return typeof value === \"number\" && Number.isSafeInteger(value) && value >= 0;\n}\n\nexport function validateCheckpoint(\n value: unknown,\n identity: string,\n tasks: readonly Task[],\n): asserts value is WorkflowCheckpoint {\n const invalid = () =>\n new Error(\"Invalid or incompatible workflow checkpoint\");\n if (\n !object(value) ||\n value.format !== 1 ||\n value.identity !== identity ||\n typeof value.executionId !== \"string\" ||\n !value.executionId ||\n !Array.isArray(value.records) ||\n !object(value.values) ||\n !object(value.usage)\n )\n throw invalid();\n if (!integer(value.usage.attempts) || !object(value.usage.tokens))\n throw invalid();\n for (const dimension of [\"input\", \"cached\", \"output\"])\n if (!integer(value.usage.tokens[dimension])) throw invalid();\n for (const count of Object.values(value.usage.tokens))\n if (!integer(count)) throw invalid();\n if (value.records.length !== tasks.length) throw invalid();\n const keys = new Set(tasks.map((item) => item.key));\n let attempts = 0;\n for (const record of value.records) {\n if (\n !object(record) ||\n typeof record.key !== \"string\" ||\n !keys.delete(record.key) ||\n !integer(record.attempts) ||\n ![\n \"waiting\",\n \"active\",\n \"done\",\n \"failed\",\n \"skipped\",\n \"cancelled\",\n \"paused\",\n \"rejected\",\n ].includes(String(record.status))\n )\n throw invalid();\n for (const field of [\"startedAt\", \"finishedAt\", \"error\"])\n if (record[field] !== undefined && typeof record[field] !== \"string\")\n throw invalid();\n validateUsageReceipts(record.usageReceipts);\n attempts += record.attempts;\n const output = Object.hasOwn(value.values, record.key)\n ? value.values[record.key]\n : undefined;\n validateGateRecord(\n record,\n tasks.find((item) => item.key === record.key)!,\n value.executionId,\n output,\n );\n if (record.status !== \"done\") {\n if (output !== undefined) throw invalid();\n continue;\n }\n if (!object(output) || ![\"undefined\", \"json\"].includes(String(output.kind)))\n throw invalid();\n if (output.kind === \"json\") {\n if (!Object.hasOwn(output, \"value\") || output.value === undefined)\n throw invalid();\n checkpointValue(output.value);\n }\n }\n if (attempts !== value.usage.attempts) throw invalid();\n if (\n Object.keys(value.values).some(\n (key) => !tasks.some((item) => item.key === key),\n )\n )\n throw invalid();\n const records = new Map(value.records.map((entry) => [entry.key, entry]));\n for (const item of tasks)\n if (\n [\"done\", \"paused\", \"rejected\"].includes(\n String(records.get(item.key)?.status),\n ) &&\n item.after.some(\n (dependency) => records.get(dependency.key)?.status !== \"done\",\n )\n )\n throw invalid();\n}\n"]}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export function checkpointValue(value) {
|
|
2
|
+
if (value === undefined)
|
|
3
|
+
return { kind: "undefined" };
|
|
4
|
+
return { kind: "json", value: jsonValue(value, new Set()) };
|
|
5
|
+
}
|
|
6
|
+
function jsonValue(value, ancestors) {
|
|
7
|
+
if (value === null || typeof value === "boolean" || typeof value === "string")
|
|
8
|
+
return value;
|
|
9
|
+
if (typeof value === "number" &&
|
|
10
|
+
Number.isFinite(value) &&
|
|
11
|
+
!Object.is(value, -0))
|
|
12
|
+
return value;
|
|
13
|
+
if (typeof value !== "object" || value === null || ancestors.has(value))
|
|
14
|
+
throw new Error("Checkpoint outputs must be lossless JSON values or top-level undefined");
|
|
15
|
+
const prototype = Object.getPrototypeOf(value);
|
|
16
|
+
if (!Array.isArray(value) &&
|
|
17
|
+
prototype !== Object.prototype &&
|
|
18
|
+
prototype !== null)
|
|
19
|
+
throw new Error("Checkpoint outputs must contain plain JSON objects");
|
|
20
|
+
ancestors.add(value);
|
|
21
|
+
try {
|
|
22
|
+
if (Array.isArray(value)) {
|
|
23
|
+
if (prototype !== Array.prototype)
|
|
24
|
+
throw new Error("Checkpoint arrays must have the standard prototype");
|
|
25
|
+
if (Reflect.ownKeys(value).length !== value.length + 1)
|
|
26
|
+
throw new Error("Checkpoint arrays must be dense and have no extra properties");
|
|
27
|
+
return Array.from({ length: value.length }, (_, index) => {
|
|
28
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, String(index));
|
|
29
|
+
if (!descriptor || !("value" in descriptor) || !descriptor.enumerable)
|
|
30
|
+
throw new Error("Checkpoint arrays must have enumerable data properties");
|
|
31
|
+
return jsonValue(descriptor.value, ancestors);
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
const result = Object.create(null);
|
|
35
|
+
for (const key of Reflect.ownKeys(value)) {
|
|
36
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
37
|
+
if (typeof key !== "string" ||
|
|
38
|
+
!descriptor.enumerable ||
|
|
39
|
+
!("value" in descriptor))
|
|
40
|
+
throw new Error("Checkpoint objects must have enumerable string data properties");
|
|
41
|
+
result[key] = jsonValue(descriptor.value, ancestors);
|
|
42
|
+
}
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
45
|
+
finally {
|
|
46
|
+
ancestors.delete(value);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=checkpoint-value.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkpoint-value.js","sourceRoot":"","sources":["../../../src/domain/workflow/checkpoint-value.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n WorkflowCheckpointValue,\n WorkflowJson,\n} from \"./checkpoint.types.ts\";\n\nexport function checkpointValue(value: unknown): WorkflowCheckpointValue {\n if (value === undefined) return { kind: \"undefined\" };\n return { kind: \"json\", value: jsonValue(value, new Set()) };\n}\n\nfunction jsonValue(value: unknown, ancestors: Set<object>): WorkflowJson {\n if (value === null || typeof value === \"boolean\" || typeof value === \"string\")\n return value;\n if (\n typeof value === \"number\" &&\n Number.isFinite(value) &&\n !Object.is(value, -0)\n )\n return value;\n if (typeof value !== \"object\" || value === null || ancestors.has(value))\n throw new Error(\n \"Checkpoint outputs must be lossless JSON values or top-level undefined\",\n );\n const prototype: unknown = Object.getPrototypeOf(value);\n if (\n !Array.isArray(value) &&\n prototype !== Object.prototype &&\n prototype !== null\n )\n throw new Error(\"Checkpoint outputs must contain plain JSON objects\");\n ancestors.add(value);\n try {\n if (Array.isArray(value)) {\n if (prototype !== Array.prototype)\n throw new Error(\"Checkpoint arrays must have the standard prototype\");\n if (Reflect.ownKeys(value).length !== value.length + 1)\n throw new Error(\n \"Checkpoint arrays must be dense and have no extra properties\",\n );\n return Array.from({ length: value.length }, (_, index) => {\n const descriptor = Object.getOwnPropertyDescriptor(\n value,\n String(index),\n );\n if (!descriptor || !(\"value\" in descriptor) || !descriptor.enumerable)\n throw new Error(\n \"Checkpoint arrays must have enumerable data properties\",\n );\n return jsonValue(descriptor.value, ancestors);\n });\n }\n const result: Record<string, WorkflowJson> = Object.create(null);\n for (const key of Reflect.ownKeys(value)) {\n const descriptor = Object.getOwnPropertyDescriptor(value, key)!;\n if (\n typeof key !== \"string\" ||\n !descriptor.enumerable ||\n !(\"value\" in descriptor)\n )\n throw new Error(\n \"Checkpoint objects must have enumerable string data properties\",\n );\n result[key] = jsonValue(descriptor.value, ancestors);\n }\n return result;\n } finally {\n ancestors.delete(value);\n }\n}\n"]}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { Task } from "../workflow.types.ts";
|
|
2
|
+
import type { WorkflowCheckpointOptions, WorkflowCheckpointSession } from "./checkpoint.types.ts";
|
|
3
|
+
export declare function openCheckpoint(name: string, tasks: readonly Task[], options: WorkflowCheckpointOptions): Promise<WorkflowCheckpointSession>;
|