@elie-laloum/outpost 3.0.0 → 4.0.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 +18 -0
- package/README.md +3 -1
- package/SECURITY.md +3 -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 +21 -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/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/doctor-command.js +1 -1
- package/dist/cli/doctor-command.js.map +1 -1
- package/dist/cli/main.constants.d.ts +11 -2
- package/dist/cli/main.constants.js +8 -4
- 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 +2 -2
- package/dist/cli/scaffold-files.js.map +1 -1
- package/dist/cli/scaffold-validation.js +1 -1
- package/dist/cli/scaffold-validation.js.map +1 -1
- package/dist/cli/scaffold.constants.d.ts +5 -0
- package/dist/cli/scaffold.constants.js +7 -2
- package/dist/cli/scaffold.constants.js.map +1 -1
- package/dist/cli/scaffold.types.d.ts +1 -1
- package/dist/cli/scaffold.types.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 +2 -0
- 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.js +3 -2
- package/dist/providers/daytona-command.js.map +1 -1
- package/dist/providers/daytona-terminal.d.ts +3 -0
- package/dist/providers/daytona-terminal.js +128 -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-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 +5 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor-agent.js","sourceRoot":"","sources":["../../src/application/doctor-agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AAErD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EACL,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,6BAA6B,CAAC;AAGrC,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,KAAkB,EAClB,OAAiB;IAEjB,MAAM,MAAM,GAAsB,EAAE,CAAC;IACrC,KAAK,MAAM,IAAI,IAAI,oBAAoB,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;QACjD,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,MAAM,KAAK,GAAG,MAAM,eAAe,CACjC;YACE,EAAE,EAAE,aAAa,IAAI,CAAC,IAAI,EAAE;YAC5B,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,uBAAuB,CAAC,MAAM,EAAE;YACpE,aAAa,EAAE,MAAM;YACrB,MAAM,EACJ,
|
|
1
|
+
{"version":3,"file":"doctor-agent.js","sourceRoot":"","sources":["../../src/application/doctor-agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AAErD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EACL,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,6BAA6B,CAAC;AAGrC,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,KAAkB,EAClB,OAAiB;IAEjB,MAAM,MAAM,GAAsB,EAAE,CAAC;IACrC,KAAK,MAAM,IAAI,IAAI,oBAAoB,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;QACjD,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,MAAM,KAAK,GAAG,MAAM,eAAe,CACjC;YACE,EAAE,EAAE,aAAa,IAAI,CAAC,IAAI,EAAE;YAC5B,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,uBAAuB,CAAC,MAAM,EAAE;YACpE,aAAa,EAAE,MAAM;YACrB,MAAM,EACJ,gGAAgG;SACnG,EACD,KAAK,EAAE,OAAO,EAAE,EAAE;YAChB,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;YACtC,IAAI,GAAG,wBAAwB,CAAC,GAAG,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;YACtE,OAAO,MAAM,CAAC;QAChB,CAAC,CACF,CAAC;QACF,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YAC5B,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACnB,SAAS;QACX,CAAC;QACD,MAAM,KAAK,GAAG,IAAI;aACf,KAAK,CAAC,OAAO,CAAC;aACd,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;QACpE,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,CAAC,IAAI,CAAC;gBACV,EAAE,EAAE,KAAK,CAAC,EAAE;gBACZ,MAAM,EAAE,MAAM;gBACd,OAAO,EACL,uGAAuG;aAC1G,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,GAAG,CACtB;YACE,GAAG,IAAI,CAAC,QAAQ,CAAC,mDAAmD,CAAC;SACtE,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAC3B,CAAC;QACF,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;QACvE,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnB,MAAM,CAAC,IAAI,CAAC;gBACV,EAAE,EAAE,KAAK,CAAC,EAAE;gBACZ,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,2CAA2C,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,yEAAyE;aAChJ,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QACD,MAAM,CAAC,IAAI,CAAC;YACV,EAAE,EAAE,KAAK,CAAC,EAAE;YACZ,MAAM,EAAE,MAAM;YACd,OAAO,EACL,sJAAsJ;SACzJ,CAAC,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["import { stripVTControlCharacters } from \"node:util\";\nimport type { Executor } from \"../infrastructure/process.types.ts\";\nimport { diagnosticProbe } from \"./diagnostic-probe.ts\";\nimport {\n agentDiagnosticDefaults,\n agentDiagnosticPlans,\n} from \"./doctor-agent.constants.ts\";\nimport type { DiagnosticCheck, DoctorAgent } from \"./doctor.types.ts\";\n\nexport async function diagnoseAgentCli(\n agent: DoctorAgent,\n execute: Executor,\n): Promise<readonly DiagnosticCheck[]> {\n const checks: DiagnosticCheck[] = [];\n for (const plan of agentDiagnosticPlans[agent]()) {\n let help = \"\";\n const check = await diagnosticProbe(\n {\n id: `agent.cli.${plan.mode}`,\n command: { ...plan.command, retain: agentDiagnosticDefaults.retain },\n failureStatus: \"fail\",\n remedy:\n \"The agent CLI help command failed. Check the agent CLI in this image and rebuild it if needed.\",\n },\n async (command) => {\n const result = await execute(command);\n help = stripVTControlCharacters(`${result.stdout}\\n${result.stderr}`);\n return result;\n },\n );\n if (check.status !== \"pass\") {\n checks.push(check);\n continue;\n }\n const usage = help\n .split(/\\r?\\n/)\n .some((line) => line.trim().startsWith(`Usage: ${plan.usage} [`));\n if (!usage) {\n checks.push({\n id: check.id,\n status: \"warn\",\n message:\n \"Command exited successfully but the expected help could not be identified; CLI support is unverified.\",\n });\n continue;\n }\n const declared = new Set(\n [\n ...help.matchAll(/^\\s*(?:-[A-Za-z0-9?],?\\s+)?(--[A-Za-z][\\w-]*)\\b/gm),\n ].map((match) => match[1]),\n );\n const missing = plan.options.filter((option) => !declared.has(option));\n if (missing.length) {\n checks.push({\n id: check.id,\n status: \"fail\",\n message: `Help does not declare required options: ${missing.join(\", \")}. Rebuild the image with a CLI supporting Outpost's default invocation.`,\n });\n continue;\n }\n checks.push({\n id: check.id,\n status: \"pass\",\n message:\n \"Help identifies the command and declares the options used by Outpost's default invocation. Conversation execution and event decoding are not tested.\",\n });\n }\n return checks;\n}\n"]}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { isDeepStrictEqual } from "node:util";
|
|
2
2
|
import { claude } from "../adapters/agents/claude-adapter.js";
|
|
3
3
|
import { codex } from "../adapters/agents/codex-adapter.js";
|
|
4
|
+
import { gemini } from "../adapters/agents/gemini-adapter.js";
|
|
4
5
|
import { protocolFixtures } from "../adapters/agents/protocol-fixtures.constants.js";
|
|
5
6
|
import { agentVersions } from "../providers/versions.constants.js";
|
|
6
7
|
export function diagnoseAgentProtocol(agent) {
|
|
7
|
-
const adapter = { claude, codex }[agent]();
|
|
8
|
+
const adapter = { claude, codex, gemini }[agent]();
|
|
8
9
|
const checks = protocolFixtures[agent].map((fixture) => {
|
|
9
10
|
const events = fixture.lines.flatMap((line) => adapter.events(line));
|
|
10
11
|
const passed = isDeepStrictEqual(events, fixture.expected);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor-protocol.js","sourceRoot":"","sources":["../../src/application/doctor-protocol.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,sCAAsC,CAAC;AAC9D,OAAO,EAAE,KAAK,EAAE,MAAM,qCAAqC,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,mDAAmD,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AAInE,MAAM,UAAU,qBAAqB,CAAC,KAAkB;IACtD,MAAM,OAAO,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"doctor-protocol.js","sourceRoot":"","sources":["../../src/application/doctor-protocol.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,sCAAsC,CAAC;AAC9D,OAAO,EAAE,KAAK,EAAE,MAAM,qCAAqC,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,sCAAsC,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,mDAAmD,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AAInE,MAAM,UAAU,qBAAqB,CAAC,KAAkB;IACtD,MAAM,OAAO,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;IACnD,MAAM,MAAM,GAAsB,gBAAgB,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;QACxE,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;QACrE,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC3D,OAAO;YACL,EAAE,EAAE,oBAAoB,OAAO,CAAC,IAAI,EAAE;YACtC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;YAChC,OAAO,EAAE,MAAM;gBACb,CAAC,CAAC,iHAAiH;gBACnH,CAAC,CAAC,6EAA6E;SAClF,CAAC;IACJ,CAAC,CAAC,CAAC;IACH,OAAO;QACL,KAAK,EAAE,2BAA2B;QAClC,KAAK;QACL,gBAAgB,EAAE,aAAa,CAAC,KAAK,CAAC;QACtC,YAAY,EAAE,YAAY;QAC1B,kBAAkB,EAAE,YAAY;QAChC,MAAM;QACN,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC;KAC7D,CAAC;AACJ,CAAC","sourcesContent":["import { isDeepStrictEqual } from \"node:util\";\nimport { claude } from \"../adapters/agents/claude-adapter.ts\";\nimport { codex } from \"../adapters/agents/codex-adapter.ts\";\nimport { gemini } from \"../adapters/agents/gemini-adapter.ts\";\nimport { protocolFixtures } from \"../adapters/agents/protocol-fixtures.constants.ts\";\nimport { agentVersions } from \"../providers/versions.constants.ts\";\nimport type { AgentProtocolReport } from \"./doctor-protocol.types.ts\";\nimport type { DiagnosticCheck, DoctorAgent } from \"./doctor.types.ts\";\n\nexport function diagnoseAgentProtocol(agent: DoctorAgent): AgentProtocolReport {\n const adapter = { claude, codex, gemini }[agent]();\n const checks: DiagnosticCheck[] = protocolFixtures[agent].map((fixture) => {\n const events = fixture.lines.flatMap((line) => adapter.events(line));\n const passed = isDeepStrictEqual(events, fixture.expected);\n return {\n id: `protocol.fixture.${fixture.name}`,\n status: passed ? \"pass\" : \"fail\",\n message: passed\n ? \"Bundled synthetic events decode to the expected structural observations. No installed CLI or model was invoked.\"\n : \"Bundled synthetic events do not match the expected structural observations.\",\n };\n });\n return {\n scope: \"bundled-protocol-fixtures\",\n agent,\n referenceVersion: agentVersions[agent],\n installedCli: \"unverified\",\n modelCompatibility: \"unverified\",\n checks,\n hasFailures: checks.some((check) => check.status === \"fail\"),\n };\n}\n"]}
|
|
@@ -10,6 +10,6 @@ export const providerDiagnostics = {
|
|
|
10
10
|
podman: { placement: "mounted", interactiveTerminal: true },
|
|
11
11
|
local: { placement: "host", interactiveTerminal: true },
|
|
12
12
|
vercel: { placement: "remote", interactiveTerminal: false },
|
|
13
|
-
daytona: { placement: "remote", interactiveTerminal:
|
|
13
|
+
daytona: { placement: "remote", interactiveTerminal: true },
|
|
14
14
|
};
|
|
15
15
|
//# sourceMappingURL=doctor.constants.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.constants.js","sourceRoot":"","sources":["../../src/application/doctor.constants.ts"],"names":[],"mappings":"AACA,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC;IAC1C,QAAQ,EAAE,QAAQ;IAClB,KAAK,EAAE,OAAO;IACd,UAAU,EAAE,KAAK;IACjB,MAAM,EAAE,KAAK;IACb,gBAAgB,EAAE,EAAE;CACZ,CAAC,CAAC;AACZ,MAAM,CAAC,MAAM,mBAAmB,GAK5B;IACF,MAAM,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,mBAAmB,EAAE,IAAI,EAAE;IAC3D,MAAM,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,mBAAmB,EAAE,IAAI,EAAE;IAC3D,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,mBAAmB,EAAE,IAAI,EAAE;IACvD,MAAM,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,mBAAmB,EAAE,KAAK,EAAE;IAC3D,OAAO,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,mBAAmB,EAAE,
|
|
1
|
+
{"version":3,"file":"doctor.constants.js","sourceRoot":"","sources":["../../src/application/doctor.constants.ts"],"names":[],"mappings":"AACA,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC;IAC1C,QAAQ,EAAE,QAAQ;IAClB,KAAK,EAAE,OAAO;IACd,UAAU,EAAE,KAAK;IACjB,MAAM,EAAE,KAAK;IACb,gBAAgB,EAAE,EAAE;CACZ,CAAC,CAAC;AACZ,MAAM,CAAC,MAAM,mBAAmB,GAK5B;IACF,MAAM,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,mBAAmB,EAAE,IAAI,EAAE;IAC3D,MAAM,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,mBAAmB,EAAE,IAAI,EAAE;IAC3D,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,mBAAmB,EAAE,IAAI,EAAE;IACvD,MAAM,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,mBAAmB,EAAE,KAAK,EAAE;IAC3D,OAAO,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,mBAAmB,EAAE,IAAI,EAAE;CAC5D,CAAC","sourcesContent":["import type { DoctorProvider, DoctorReport } from \"./doctor.types.ts\";\nexport const doctorDefaults = Object.freeze({\n provider: \"docker\",\n agent: \"codex\",\n deadlineMs: 5_000,\n retain: 4_096,\n minimumNodeMajor: 24,\n} as const);\nexport const providerDiagnostics: Readonly<\n Record<\n DoctorProvider,\n Pick<DoctorReport, \"placement\" | \"interactiveTerminal\">\n >\n> = {\n docker: { placement: \"mounted\", interactiveTerminal: true },\n podman: { placement: \"mounted\", interactiveTerminal: true },\n local: { placement: \"host\", interactiveTerminal: true },\n vercel: { placement: \"remote\", interactiveTerminal: false },\n daytona: { placement: \"remote\", interactiveTerminal: true },\n};\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Command } from "../domain/command.types.ts";
|
|
2
2
|
export type DoctorProvider = "docker" | "podman" | "local" | "vercel" | "daytona";
|
|
3
|
-
export type DoctorAgent = "codex" | "claude";
|
|
3
|
+
export type DoctorAgent = "codex" | "claude" | "gemini";
|
|
4
4
|
export type DiagnosticStatus = "pass" | "warn" | "fail" | "skipped";
|
|
5
5
|
export interface DiagnosticCheck {
|
|
6
6
|
readonly id: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.types.js","sourceRoot":"","sources":["../../src/application/doctor.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { Command } from \"../domain/command.types.ts\";\nexport type DoctorProvider =\n \"docker\" | \"podman\" | \"local\" | \"vercel\" | \"daytona\";\nexport type DoctorAgent = \"codex\" | \"claude\";\nexport type DiagnosticStatus = \"pass\" | \"warn\" | \"fail\" | \"skipped\";\nexport interface DiagnosticCheck {\n readonly id: string;\n readonly status: DiagnosticStatus;\n readonly message: string;\n readonly version?: string;\n readonly referenceVersion?: string;\n}\nexport interface DoctorOptions {\n readonly image?: string;\n readonly provider: DoctorProvider;\n readonly agent: DoctorAgent;\n}\nexport interface DoctorImageOptions {\n readonly provider: \"docker\" | \"podman\";\n readonly agent: DoctorAgent;\n readonly image: string;\n}\nexport interface DoctorReport {\n readonly provider: DoctorProvider;\n readonly agent: DoctorAgent;\n readonly scope: \"host\" | \"host-and-image\";\n readonly image?: string;\n readonly placement: \"mounted\" | \"host\" | \"remote\";\n readonly interactiveTerminal: boolean;\n readonly checks: readonly DiagnosticCheck[];\n readonly hasFailures: boolean;\n}\nexport interface DiagnosticProbe {\n readonly id: string;\n readonly command: Command;\n readonly failureStatus: \"fail\" | \"warn\";\n readonly remedy: string;\n readonly readVersion?: boolean;\n readonly referenceVersion?: string;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"doctor.types.js","sourceRoot":"","sources":["../../src/application/doctor.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { Command } from \"../domain/command.types.ts\";\nexport type DoctorProvider =\n \"docker\" | \"podman\" | \"local\" | \"vercel\" | \"daytona\";\nexport type DoctorAgent = \"codex\" | \"claude\" | \"gemini\";\nexport type DiagnosticStatus = \"pass\" | \"warn\" | \"fail\" | \"skipped\";\nexport interface DiagnosticCheck {\n readonly id: string;\n readonly status: DiagnosticStatus;\n readonly message: string;\n readonly version?: string;\n readonly referenceVersion?: string;\n}\nexport interface DoctorOptions {\n readonly image?: string;\n readonly provider: DoctorProvider;\n readonly agent: DoctorAgent;\n}\nexport interface DoctorImageOptions {\n readonly provider: \"docker\" | \"podman\";\n readonly agent: DoctorAgent;\n readonly image: string;\n}\nexport interface DoctorReport {\n readonly provider: DoctorProvider;\n readonly agent: DoctorAgent;\n readonly scope: \"host\" | \"host-and-image\";\n readonly image?: string;\n readonly placement: \"mounted\" | \"host\" | \"remote\";\n readonly interactiveTerminal: boolean;\n readonly checks: readonly DiagnosticCheck[];\n readonly hasFailures: boolean;\n}\nexport interface DiagnosticProbe {\n readonly id: string;\n readonly command: Command;\n readonly failureStatus: \"fail\" | \"warn\";\n readonly remedy: string;\n readonly readVersion?: boolean;\n readonly referenceVersion?: string;\n}\n"]}
|
|
@@ -3,11 +3,13 @@ import type { Command, CommandResult } from "../domain/command.types.ts";
|
|
|
3
3
|
import type { Brief } from "../domain/prompts.types.ts";
|
|
4
4
|
import type { SandboxProvider } from "../domain/sandbox.types.ts";
|
|
5
5
|
import type { BranchPolicy, Commit, Disposal, LifecycleHooks, StageLimits, WorkspaceRecord } from "../domain/workspace.types.ts";
|
|
6
|
+
import type { StorageReservationOptions } from "../infrastructure/storage-reservations.types.ts";
|
|
6
7
|
import type { Logging } from "../infrastructure/journal.types.ts";
|
|
7
8
|
import type { SandboxDiagnosticOptions, SandboxDiagnosticReport } from "./doctor-sandbox.types.ts";
|
|
8
9
|
import type { DispatchOptions, Execution } from "./execution.types.ts";
|
|
9
10
|
import type { VariableQuestion } from "./interactive-brief.types.ts";
|
|
10
11
|
export interface WorkspaceOptions {
|
|
12
|
+
readonly storageQuota?: Omit<StorageReservationOptions, "signal">;
|
|
11
13
|
readonly signal?: AbortSignal;
|
|
12
14
|
readonly repository?: string;
|
|
13
15
|
readonly branch?: BranchPolicy;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"outpost.types.js","sourceRoot":"","sources":["../../src/application/outpost.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { AgentAdapter } from \"../domain/agent.types.ts\";\nimport type { Command, CommandResult } from \"../domain/command.types.ts\";\nimport type { Brief } from \"../domain/prompts.types.ts\";\nimport type { SandboxProvider } from \"../domain/sandbox.types.ts\";\nimport type {\n BranchPolicy,\n Commit,\n Disposal,\n LifecycleHooks,\n StageLimits,\n WorkspaceRecord,\n} from \"../domain/workspace.types.ts\";\nimport type { Logging } from \"../infrastructure/journal.types.ts\";\nimport type {\n SandboxDiagnosticOptions,\n SandboxDiagnosticReport,\n} from \"./doctor-sandbox.types.ts\";\nimport type { DispatchOptions, Execution } from \"./execution.types.ts\";\nimport type { VariableQuestion } from \"./interactive-brief.types.ts\";\n\nexport interface WorkspaceOptions {\n readonly signal?: AbortSignal;\n readonly repository?: string;\n readonly branch?: BranchPolicy;\n readonly copies?: readonly string[];\n readonly limits?: StageLimits;\n readonly label?: string;\n readonly hooks?: LifecycleHooks;\n}\n\nexport interface Workspace extends WorkspaceRecord {\n dispatch<T = undefined>(\n options: Omit<\n SandboxOptions,\n Exclude<keyof WorkspaceOptions, \"hooks\" | \"label\"> | \"workspace\"\n > &\n DispatchOptions<T> & { readonly agent: AgentAdapter },\n ): Promise<DispatchResult<T>>;\n sandbox(\n options?: Omit<\n SandboxOptions,\n Exclude<keyof WorkspaceOptions, \"hooks\" | \"label\"> | \"workspace\"\n >,\n ): Promise<Sandbox>;\n attach(\n options: Omit<\n SandboxOptions,\n Exclude<keyof WorkspaceOptions, \"hooks\" | \"label\"> | \"workspace\"\n > &\n AttachOptions & { readonly agent: AgentAdapter },\n ): Promise<AttachResult>;\n close(options?: { readonly preserve?: boolean }): Promise<Disposal>;\n integrate(): Promise<void>;\n [Symbol.asyncDispose](): Promise<void>;\n}\n\nexport interface SandboxOptions extends WorkspaceOptions {\n readonly includeUncommitted?: boolean;\n readonly agent?: AgentAdapter;\n readonly provider?: SandboxProvider;\n readonly workspace?: Workspace;\n readonly hooks?: LifecycleHooks;\n readonly signal?: AbortSignal;\n readonly logging?: Logging;\n readonly bootstrap?: boolean;\n readonly conversationHome?: string;\n}\n\nexport interface AttachOptions {\n readonly ask?: VariableQuestion;\n readonly agent?: AgentAdapter;\n readonly brief?: Brief;\n readonly continuation?: { readonly id: string; readonly fork?: boolean };\n readonly signal?: AbortSignal;\n readonly terminal?: Command[\"terminal\"];\n}\n\nexport interface AttachResult extends CommandResult, Disposal {\n readonly commits: readonly Commit[];\n readonly branch: string;\n readonly directory: string;\n}\n\nexport interface DispatchResult<T> extends Execution<T> {\n readonly branch: string;\n readonly directory: string;\n readonly commits: readonly Commit[];\n readonly transcript?: string;\n readonly log?: string;\n readonly retainedDirectory?: string;\n resume<U = undefined>(\n options: ContinuationOptions<U>,\n ): Promise<DispatchResult<U>>;\n fork<U = undefined>(\n options: ContinuationOptions<U>,\n ): Promise<DispatchResult<U>>;\n}\n\nexport type ContinuationOptions<T = undefined> = DispatchOptions<T> &\n Omit<SandboxOptions, \"agent\">;\n\nexport interface WarmDispatchResult<T> extends Omit<\n DispatchResult<T>,\n \"resume\" | \"fork\"\n> {\n resume<U = undefined>(\n options: DispatchOptions<U>,\n ): Promise<WarmDispatchResult<U>>;\n fork<U = undefined>(\n options: DispatchOptions<U>,\n ): Promise<WarmDispatchResult<U>>;\n}\n\nexport interface Sandbox {\n diagnose(\n options?: SandboxDiagnosticOptions,\n ): Promise<SandboxDiagnosticReport>;\n readonly workspace: Workspace;\n readonly root: string;\n dispatch<T = undefined>(\n options: DispatchOptions<T>,\n ): Promise<WarmDispatchResult<T>>;\n resume<T = undefined>(\n id: string,\n options: DispatchOptions<T>,\n ): Promise<WarmDispatchResult<T>>;\n fork<T = undefined>(\n id: string,\n options: DispatchOptions<T>,\n ): Promise<WarmDispatchResult<T>>;\n attach(options?: AttachOptions): Promise<AttachResult>;\n command(command: Command): Promise<CommandResult>;\n close(options?: { readonly preserve?: boolean }): Promise<Disposal>;\n [Symbol.asyncDispose](): Promise<void>;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"outpost.types.js","sourceRoot":"","sources":["../../src/application/outpost.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { AgentAdapter } from \"../domain/agent.types.ts\";\nimport type { Command, CommandResult } from \"../domain/command.types.ts\";\nimport type { Brief } from \"../domain/prompts.types.ts\";\nimport type { SandboxProvider } from \"../domain/sandbox.types.ts\";\nimport type {\n BranchPolicy,\n Commit,\n Disposal,\n LifecycleHooks,\n StageLimits,\n WorkspaceRecord,\n} from \"../domain/workspace.types.ts\";\nimport type { StorageReservationOptions } from \"../infrastructure/storage-reservations.types.ts\";\nimport type { Logging } from \"../infrastructure/journal.types.ts\";\nimport type {\n SandboxDiagnosticOptions,\n SandboxDiagnosticReport,\n} from \"./doctor-sandbox.types.ts\";\nimport type { DispatchOptions, Execution } from \"./execution.types.ts\";\nimport type { VariableQuestion } from \"./interactive-brief.types.ts\";\n\nexport interface WorkspaceOptions {\n readonly storageQuota?: Omit<StorageReservationOptions, \"signal\">;\n readonly signal?: AbortSignal;\n readonly repository?: string;\n readonly branch?: BranchPolicy;\n readonly copies?: readonly string[];\n readonly limits?: StageLimits;\n readonly label?: string;\n readonly hooks?: LifecycleHooks;\n}\n\nexport interface Workspace extends WorkspaceRecord {\n dispatch<T = undefined>(\n options: Omit<\n SandboxOptions,\n Exclude<keyof WorkspaceOptions, \"hooks\" | \"label\"> | \"workspace\"\n > &\n DispatchOptions<T> & { readonly agent: AgentAdapter },\n ): Promise<DispatchResult<T>>;\n sandbox(\n options?: Omit<\n SandboxOptions,\n Exclude<keyof WorkspaceOptions, \"hooks\" | \"label\"> | \"workspace\"\n >,\n ): Promise<Sandbox>;\n attach(\n options: Omit<\n SandboxOptions,\n Exclude<keyof WorkspaceOptions, \"hooks\" | \"label\"> | \"workspace\"\n > &\n AttachOptions & { readonly agent: AgentAdapter },\n ): Promise<AttachResult>;\n close(options?: { readonly preserve?: boolean }): Promise<Disposal>;\n integrate(): Promise<void>;\n [Symbol.asyncDispose](): Promise<void>;\n}\n\nexport interface SandboxOptions extends WorkspaceOptions {\n readonly includeUncommitted?: boolean;\n readonly agent?: AgentAdapter;\n readonly provider?: SandboxProvider;\n readonly workspace?: Workspace;\n readonly hooks?: LifecycleHooks;\n readonly signal?: AbortSignal;\n readonly logging?: Logging;\n readonly bootstrap?: boolean;\n readonly conversationHome?: string;\n}\n\nexport interface AttachOptions {\n readonly ask?: VariableQuestion;\n readonly agent?: AgentAdapter;\n readonly brief?: Brief;\n readonly continuation?: { readonly id: string; readonly fork?: boolean };\n readonly signal?: AbortSignal;\n readonly terminal?: Command[\"terminal\"];\n}\n\nexport interface AttachResult extends CommandResult, Disposal {\n readonly commits: readonly Commit[];\n readonly branch: string;\n readonly directory: string;\n}\n\nexport interface DispatchResult<T> extends Execution<T> {\n readonly branch: string;\n readonly directory: string;\n readonly commits: readonly Commit[];\n readonly transcript?: string;\n readonly log?: string;\n readonly retainedDirectory?: string;\n resume<U = undefined>(\n options: ContinuationOptions<U>,\n ): Promise<DispatchResult<U>>;\n fork<U = undefined>(\n options: ContinuationOptions<U>,\n ): Promise<DispatchResult<U>>;\n}\n\nexport type ContinuationOptions<T = undefined> = DispatchOptions<T> &\n Omit<SandboxOptions, \"agent\">;\n\nexport interface WarmDispatchResult<T> extends Omit<\n DispatchResult<T>,\n \"resume\" | \"fork\"\n> {\n resume<U = undefined>(\n options: DispatchOptions<U>,\n ): Promise<WarmDispatchResult<U>>;\n fork<U = undefined>(\n options: DispatchOptions<U>,\n ): Promise<WarmDispatchResult<U>>;\n}\n\nexport interface Sandbox {\n diagnose(\n options?: SandboxDiagnosticOptions,\n ): Promise<SandboxDiagnosticReport>;\n readonly workspace: Workspace;\n readonly root: string;\n dispatch<T = undefined>(\n options: DispatchOptions<T>,\n ): Promise<WarmDispatchResult<T>>;\n resume<T = undefined>(\n id: string,\n options: DispatchOptions<T>,\n ): Promise<WarmDispatchResult<T>>;\n fork<T = undefined>(\n id: string,\n options: DispatchOptions<T>,\n ): Promise<WarmDispatchResult<T>>;\n attach(options?: AttachOptions): Promise<AttachResult>;\n command(command: Command): Promise<CommandResult>;\n close(options?: { readonly preserve?: boolean }): Promise<Disposal>;\n [Symbol.asyncDispose](): Promise<void>;\n}\n"]}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { setTimeout as delay } from "node:timers/promises";
|
|
2
|
+
import { queueMaxStringLength, queueDefaultLeaseMs, queueDefaultPollMs, } from "../domain/task-queue.constants.js";
|
|
3
|
+
import { queueLeaseMs, queueNumber, queueString, queueResult, } from "../domain/task-queue.js";
|
|
4
|
+
export async function runQueueWorker(options) {
|
|
5
|
+
const leaseMs = queueLeaseMs(options.leaseMs ?? queueDefaultLeaseMs);
|
|
6
|
+
const pollMs = queueNumber(options.pollMs ?? queueDefaultPollMs);
|
|
7
|
+
if (!pollMs)
|
|
8
|
+
throw new Error("Worker poll interval must be positive");
|
|
9
|
+
const handlers = new Map(Object.entries(options.handlers));
|
|
10
|
+
if (!handlers.size ||
|
|
11
|
+
[...handlers.values()].some((handler) => typeof handler !== "function"))
|
|
12
|
+
throw new Error("Worker requires trusted handlers");
|
|
13
|
+
const worker = queueString(options.worker);
|
|
14
|
+
async function execute(job) {
|
|
15
|
+
if (options.signal.aborted)
|
|
16
|
+
return;
|
|
17
|
+
const stop = new AbortController();
|
|
18
|
+
const signal = AbortSignal.any([options.signal, stop.signal]);
|
|
19
|
+
const lease = { id: job.id, worker, fence: job.fence };
|
|
20
|
+
const heartbeat = (async () => {
|
|
21
|
+
try {
|
|
22
|
+
while (!signal.aborted) {
|
|
23
|
+
await delay(Math.max(10, Math.floor(leaseMs / 3)), undefined, {
|
|
24
|
+
signal,
|
|
25
|
+
});
|
|
26
|
+
await options.queue.renew(lease, leaseMs);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
if (!signal.aborted)
|
|
31
|
+
stop.abort(error);
|
|
32
|
+
}
|
|
33
|
+
})();
|
|
34
|
+
try {
|
|
35
|
+
const handler = handlers.get(job.handler);
|
|
36
|
+
if (!handler)
|
|
37
|
+
throw new Error("Worker handler unavailable");
|
|
38
|
+
let result;
|
|
39
|
+
try {
|
|
40
|
+
result = queueResult(await handler(job.input, { signal, job }));
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
result = {
|
|
44
|
+
value: null,
|
|
45
|
+
error: (error instanceof Error ? error.message : String(error)).slice(0, queueMaxStringLength) || "Queue handler failed",
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
if (!signal.aborted)
|
|
49
|
+
await options.queue.complete(lease, result);
|
|
50
|
+
}
|
|
51
|
+
finally {
|
|
52
|
+
stop.abort();
|
|
53
|
+
await heartbeat;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
while (!options.signal.aborted) {
|
|
58
|
+
const job = await options.queue.claim({
|
|
59
|
+
worker,
|
|
60
|
+
handlers: [...handlers.keys()],
|
|
61
|
+
leaseMs,
|
|
62
|
+
});
|
|
63
|
+
if (job) {
|
|
64
|
+
await execute(job);
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
await delay(pollMs, undefined, { signal: options.signal });
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
if (!options.signal.aborted)
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=queue-worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue-worker.js","sourceRoot":"","sources":["../../src/application/queue-worker.ts"],"names":[],"mappings":"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","sourcesContent":["import { setTimeout as delay } from \"node:timers/promises\";\nimport {\n queueMaxStringLength,\n queueDefaultLeaseMs,\n queueDefaultPollMs,\n} from \"../domain/task-queue.constants.ts\";\nimport {\n queueLeaseMs,\n queueNumber,\n queueString,\n queueResult,\n} from \"../domain/task-queue.ts\";\nimport type { QueueWorkerOptions } from \"./queue-worker.types.ts\";\nimport type { QueueJob, QueueResult } from \"../domain/task-queue.types.ts\";\n\nexport async function runQueueWorker(\n options: QueueWorkerOptions,\n): Promise<void> {\n const leaseMs = queueLeaseMs(options.leaseMs ?? queueDefaultLeaseMs);\n const pollMs = queueNumber(options.pollMs ?? queueDefaultPollMs);\n if (!pollMs) throw new Error(\"Worker poll interval must be positive\");\n const handlers = new Map(Object.entries(options.handlers));\n if (\n !handlers.size ||\n [...handlers.values()].some((handler) => typeof handler !== \"function\")\n )\n throw new Error(\"Worker requires trusted handlers\");\n const worker = queueString(options.worker);\n async function execute(job: QueueJob) {\n if (options.signal.aborted) return;\n const stop = new AbortController();\n const signal = AbortSignal.any([options.signal, stop.signal]);\n const lease = { id: job.id, worker, fence: job.fence };\n const heartbeat = (async () => {\n try {\n while (!signal.aborted) {\n await delay(Math.max(10, Math.floor(leaseMs / 3)), undefined, {\n signal,\n });\n await options.queue.renew(lease, leaseMs);\n }\n } catch (error) {\n if (!signal.aborted) stop.abort(error);\n }\n })();\n try {\n const handler = handlers.get(job.handler);\n if (!handler) throw new Error(\"Worker handler unavailable\");\n let result: QueueResult;\n try {\n result = queueResult(await handler(job.input, { signal, job }));\n } catch (error) {\n result = {\n value: null,\n error:\n (error instanceof Error ? error.message : String(error)).slice(\n 0,\n queueMaxStringLength,\n ) || \"Queue handler failed\",\n };\n }\n if (!signal.aborted) await options.queue.complete(lease, result);\n } finally {\n stop.abort();\n await heartbeat;\n }\n }\n try {\n while (!options.signal.aborted) {\n const job = await options.queue.claim({\n worker,\n handlers: [...handlers.keys()],\n leaseMs,\n });\n if (job) {\n await execute(job);\n continue;\n }\n await delay(pollMs, undefined, { signal: options.signal });\n }\n } catch (error) {\n if (!options.signal.aborted) throw error;\n }\n}\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { QueueJob, QueueResult, TaskQueue } from "../domain/task-queue.types.ts";
|
|
2
|
+
import type { WorkflowJson } from "../domain/workflow/checkpoint.types.ts";
|
|
3
|
+
export interface QueueHandlerContext {
|
|
4
|
+
readonly signal: AbortSignal;
|
|
5
|
+
readonly job: QueueJob;
|
|
6
|
+
}
|
|
7
|
+
export type QueueHandler = (input: WorkflowJson, context: QueueHandlerContext) => Promise<QueueResult> | QueueResult;
|
|
8
|
+
export interface QueueWorkerOptions {
|
|
9
|
+
readonly queue: TaskQueue;
|
|
10
|
+
readonly worker: string;
|
|
11
|
+
readonly handlers: Readonly<Record<string, QueueHandler>>;
|
|
12
|
+
readonly signal: AbortSignal;
|
|
13
|
+
readonly leaseMs?: number;
|
|
14
|
+
readonly pollMs?: number;
|
|
15
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue-worker.types.js","sourceRoot":"","sources":["../../src/application/queue-worker.types.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n QueueJob,\n QueueResult,\n TaskQueue,\n} from \"../domain/task-queue.types.ts\";\nimport type { WorkflowJson } from \"../domain/workflow/checkpoint.types.ts\";\nexport interface QueueHandlerContext {\n readonly signal: AbortSignal;\n readonly job: QueueJob;\n}\nexport type QueueHandler = (\n input: WorkflowJson,\n context: QueueHandlerContext,\n) => Promise<QueueResult> | QueueResult;\nexport interface QueueWorkerOptions {\n readonly queue: TaskQueue;\n readonly worker: string;\n readonly handlers: Readonly<Record<string, QueueHandler>>;\n readonly signal: AbortSignal;\n readonly leaseMs?: number;\n readonly pollMs?: number;\n}\n"]}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { setTimeout as delay } from "node:timers/promises";
|
|
3
|
+
import { task } from "../domain/workflow.js";
|
|
4
|
+
import { queueDefaultPollMs } from "../domain/task-queue.constants.js";
|
|
5
|
+
import { queueNumber, queueString } from "../domain/task-queue.js";
|
|
6
|
+
export function queuedTask(options) {
|
|
7
|
+
const { queue, handler, input, decode, deadline, pollMs = queueDefaultPollMs, ...definition } = options;
|
|
8
|
+
queueString(handler);
|
|
9
|
+
if (!queueNumber(pollMs))
|
|
10
|
+
throw new Error("Queue poll interval must be positive");
|
|
11
|
+
if (deadline !== undefined)
|
|
12
|
+
queueNumber(deadline);
|
|
13
|
+
return task({
|
|
14
|
+
...definition,
|
|
15
|
+
async perform(context) {
|
|
16
|
+
context.signal.throwIfAborted();
|
|
17
|
+
const id = createHash("sha256")
|
|
18
|
+
.update(JSON.stringify([context.executionId, definition.key]))
|
|
19
|
+
.digest("hex");
|
|
20
|
+
let job = await queue.enqueue({
|
|
21
|
+
id,
|
|
22
|
+
handler,
|
|
23
|
+
input: input(context),
|
|
24
|
+
...(deadline === undefined ? {} : { deadline }),
|
|
25
|
+
});
|
|
26
|
+
try {
|
|
27
|
+
while (job.status === "pending" || job.status === "active") {
|
|
28
|
+
await delay(pollMs, undefined, { signal: context.signal });
|
|
29
|
+
const latest = await queue.get(id);
|
|
30
|
+
if (!latest)
|
|
31
|
+
throw new Error("Queued workflow job disappeared");
|
|
32
|
+
job = latest;
|
|
33
|
+
}
|
|
34
|
+
if (job.result?.usage) {
|
|
35
|
+
if (context.reportUsageOnce)
|
|
36
|
+
context.reportUsageOnce(`queue:${id}`, job.result.usage);
|
|
37
|
+
else
|
|
38
|
+
context.reportUsage(job.result.usage);
|
|
39
|
+
}
|
|
40
|
+
if (job.status !== "done" || !job.result)
|
|
41
|
+
throw new Error(job.result?.error ?? "Queued workflow job cancelled");
|
|
42
|
+
context.signal.throwIfAborted();
|
|
43
|
+
return decode(job.result.value);
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
if (context.signal.aborted) {
|
|
47
|
+
const latest = await queue.get(id);
|
|
48
|
+
if (latest)
|
|
49
|
+
await queue.cancel(id, latest.fence);
|
|
50
|
+
}
|
|
51
|
+
throw error;
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=queued-task.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queued-task.js","sourceRoot":"","sources":["../../src/application/queued-task.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"node:crypto\";\nimport { setTimeout as delay } from \"node:timers/promises\";\nimport { task } from \"../domain/workflow.ts\";\nimport { queueDefaultPollMs } from \"../domain/task-queue.constants.ts\";\nimport { queueNumber, queueString } from \"../domain/task-queue.ts\";\nimport type { Task } from \"../domain/workflow.types.ts\";\nimport type { QueuedTaskOptions } from \"./queued-task.types.ts\";\n\nexport function queuedTask<T>(options: QueuedTaskOptions<T>): Task<T> {\n const {\n queue,\n handler,\n input,\n decode,\n deadline,\n pollMs = queueDefaultPollMs,\n ...definition\n } = options;\n queueString(handler);\n if (!queueNumber(pollMs))\n throw new Error(\"Queue poll interval must be positive\");\n if (deadline !== undefined) queueNumber(deadline);\n return task({\n ...definition,\n async perform(context) {\n context.signal.throwIfAborted();\n const id = createHash(\"sha256\")\n .update(JSON.stringify([context.executionId, definition.key]))\n .digest(\"hex\");\n let job = await queue.enqueue({\n id,\n handler,\n input: input(context),\n ...(deadline === undefined ? {} : { deadline }),\n });\n try {\n while (job.status === \"pending\" || job.status === \"active\") {\n await delay(pollMs, undefined, { signal: context.signal });\n const latest = await queue.get(id);\n if (!latest) throw new Error(\"Queued workflow job disappeared\");\n job = latest;\n }\n if (job.result?.usage) {\n if (context.reportUsageOnce)\n context.reportUsageOnce(`queue:${id}`, job.result.usage);\n else context.reportUsage(job.result.usage);\n }\n if (job.status !== \"done\" || !job.result)\n throw new Error(job.result?.error ?? \"Queued workflow job cancelled\");\n context.signal.throwIfAborted();\n return decode(job.result.value);\n } catch (error) {\n if (context.signal.aborted) {\n const latest = await queue.get(id);\n if (latest) await queue.cancel(id, latest.fence);\n }\n throw error;\n }\n },\n });\n}\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { TaskContext, TaskOptions } from "../domain/workflow.types.ts";
|
|
2
|
+
import type { WorkflowJson } from "../domain/workflow/checkpoint.types.ts";
|
|
3
|
+
import type { TaskQueue } from "../domain/task-queue.types.ts";
|
|
4
|
+
export type QueuedTaskOptions<T> = Omit<TaskOptions<T>, "perform"> & {
|
|
5
|
+
readonly queue: TaskQueue;
|
|
6
|
+
readonly handler: string;
|
|
7
|
+
readonly input: (context: TaskContext) => WorkflowJson;
|
|
8
|
+
readonly decode: (value: WorkflowJson) => T;
|
|
9
|
+
readonly deadline?: number;
|
|
10
|
+
readonly pollMs?: number;
|
|
11
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queued-task.types.js","sourceRoot":"","sources":["../../src/application/queued-task.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { TaskContext, TaskOptions } from \"../domain/workflow.types.ts\";\nimport type { WorkflowJson } from \"../domain/workflow/checkpoint.types.ts\";\nimport type { TaskQueue } from \"../domain/task-queue.types.ts\";\nexport type QueuedTaskOptions<T> = Omit<TaskOptions<T>, \"perform\"> & {\n readonly queue: TaskQueue;\n readonly handler: string;\n readonly input: (context: TaskContext) => WorkflowJson;\n readonly decode: (value: WorkflowJson) => T;\n readonly deadline?: number;\n readonly pollMs?: number;\n};\n"]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { inspectResourceActivity } from "../infrastructure/resource-activity-inspection.js";
|
|
1
2
|
import { inspectLocks } from "../infrastructure/git/lock-inspection.js";
|
|
2
3
|
import { join } from "node:path";
|
|
3
4
|
import { directory } from "../infrastructure/files.js";
|
|
@@ -16,10 +17,14 @@ export async function inspectRecovery(options = {}) {
|
|
|
16
17
|
? await inspectLocks(inventory.categories.find((category) => category.name === "locks")
|
|
17
18
|
?.entries ?? [])
|
|
18
19
|
: undefined;
|
|
20
|
+
const resources = options.resources
|
|
21
|
+
? await inspectResourceActivity(repository, options.maxEntries)
|
|
22
|
+
: undefined;
|
|
19
23
|
return {
|
|
20
24
|
repository,
|
|
21
25
|
activity: "unverified",
|
|
22
26
|
...inventory,
|
|
27
|
+
...(resources ? { resources } : {}),
|
|
23
28
|
...(gitReport ? { git: gitReport } : {}),
|
|
24
29
|
...(lockReport ? { locks: lockReport } : {}),
|
|
25
30
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recovery-inspection.js","sourceRoot":"","sources":["../../src/application/recovery-inspection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,0CAA0C,CAAC;AACxE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,EAAE,GAAG,EAAE,MAAM,kCAAkC,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,8CAA8C,CAAC;AAClF,OAAO,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAC;AAM1E,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,UAAqC,EAAE;IAEvC,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACtD,MAAM,UAAU,GAAG,MAAM,SAAS,CAChC,CAAC,MAAM,GAAG,CAAC,SAAS,EAAE,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAChE,CAAC;IACF,MAAM,SAAS,GAAG,MAAM,gBAAgB,CACtC,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,EAC5B,OAAO,CAAC,UAAU,CACnB,CAAC;IACF,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG;QAC3B,CAAC,CAAC,MAAM,kBAAkB,CACtB,UAAU,EACV,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY,CAAC;YACrE,EAAE,OAAO,IAAI,EAAE,CAClB;QACH,CAAC,CAAC,SAAS,CAAC;IACd,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK;QAC9B,CAAC,CAAC,MAAM,YAAY,CAChB,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,KAAK,OAAO,CAAC;YAChE,EAAE,OAAO,IAAI,EAAE,CAClB;QACH,CAAC,CAAC,SAAS,CAAC;IACd,OAAO;QACL,UAAU;QACV,QAAQ,EAAE,YAAY;QACtB,GAAG,SAAS;QACZ,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC7C,CAAC;AACJ,CAAC","sourcesContent":["import { inspectLocks } from \"../infrastructure/git/lock-inspection.ts\";\nimport { join } from \"node:path\";\nimport { directory } from \"../infrastructure/files.ts\";\nimport { git } from \"../infrastructure/git/command.ts\";\nimport { inspectWorktreeGit } from \"../infrastructure/git/worktree-inspection.ts\";\nimport { storageInventory } from \"../infrastructure/storage-inventory.ts\";\nimport type {\n RecoveryInspection,\n RecoveryInspectionOptions,\n} from \"./recovery-inspection.types.ts\";\n\nexport async function inspectRecovery(\n options: RecoveryInspectionOptions = {},\n): Promise<RecoveryInspection> {\n const requested = await directory(options.repository);\n const repository = await directory(\n (await git(requested, [\"rev-parse\", \"--show-toplevel\"])).trim(),\n );\n const inventory = await storageInventory(\n join(repository, \".outpost\"),\n options.maxEntries,\n );\n const gitReport = options.git\n ? await inspectWorktreeGit(\n repository,\n inventory.categories.find((category) => category.name === \"workspaces\")\n ?.entries ?? [],\n )\n : undefined;\n const lockReport = options.locks\n ? await inspectLocks(\n inventory.categories.find((category) => category.name === \"locks\")\n ?.entries ?? [],\n )\n : undefined;\n return {\n repository,\n activity: \"unverified\",\n ...inventory,\n ...(gitReport ? { git: gitReport } : {}),\n ...(lockReport ? { locks: lockReport } : {}),\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"recovery-inspection.js","sourceRoot":"","sources":["../../src/application/recovery-inspection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,mDAAmD,CAAC;AAC5F,OAAO,EAAE,YAAY,EAAE,MAAM,0CAA0C,CAAC;AACxE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,EAAE,GAAG,EAAE,MAAM,kCAAkC,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,8CAA8C,CAAC;AAClF,OAAO,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAC;AAM1E,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,UAAqC,EAAE;IAEvC,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACtD,MAAM,UAAU,GAAG,MAAM,SAAS,CAChC,CAAC,MAAM,GAAG,CAAC,SAAS,EAAE,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAChE,CAAC;IACF,MAAM,SAAS,GAAG,MAAM,gBAAgB,CACtC,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,EAC5B,OAAO,CAAC,UAAU,CACnB,CAAC;IACF,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG;QAC3B,CAAC,CAAC,MAAM,kBAAkB,CACtB,UAAU,EACV,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY,CAAC;YACrE,EAAE,OAAO,IAAI,EAAE,CAClB;QACH,CAAC,CAAC,SAAS,CAAC;IACd,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK;QAC9B,CAAC,CAAC,MAAM,YAAY,CAChB,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,KAAK,OAAO,CAAC;YAChE,EAAE,OAAO,IAAI,EAAE,CAClB;QACH,CAAC,CAAC,SAAS,CAAC;IACd,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS;QACjC,CAAC,CAAC,MAAM,uBAAuB,CAAC,UAAU,EAAE,OAAO,CAAC,UAAU,CAAC;QAC/D,CAAC,CAAC,SAAS,CAAC;IACd,OAAO;QACL,UAAU;QACV,QAAQ,EAAE,YAAY;QACtB,GAAG,SAAS;QACZ,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC7C,CAAC;AACJ,CAAC","sourcesContent":["import { inspectResourceActivity } from \"../infrastructure/resource-activity-inspection.ts\";\nimport { inspectLocks } from \"../infrastructure/git/lock-inspection.ts\";\nimport { join } from \"node:path\";\nimport { directory } from \"../infrastructure/files.ts\";\nimport { git } from \"../infrastructure/git/command.ts\";\nimport { inspectWorktreeGit } from \"../infrastructure/git/worktree-inspection.ts\";\nimport { storageInventory } from \"../infrastructure/storage-inventory.ts\";\nimport type {\n RecoveryInspection,\n RecoveryInspectionOptions,\n} from \"./recovery-inspection.types.ts\";\n\nexport async function inspectRecovery(\n options: RecoveryInspectionOptions = {},\n): Promise<RecoveryInspection> {\n const requested = await directory(options.repository);\n const repository = await directory(\n (await git(requested, [\"rev-parse\", \"--show-toplevel\"])).trim(),\n );\n const inventory = await storageInventory(\n join(repository, \".outpost\"),\n options.maxEntries,\n );\n const gitReport = options.git\n ? await inspectWorktreeGit(\n repository,\n inventory.categories.find((category) => category.name === \"workspaces\")\n ?.entries ?? [],\n )\n : undefined;\n const lockReport = options.locks\n ? await inspectLocks(\n inventory.categories.find((category) => category.name === \"locks\")\n ?.entries ?? [],\n )\n : undefined;\n const resources = options.resources\n ? await inspectResourceActivity(repository, options.maxEntries)\n : undefined;\n return {\n repository,\n activity: \"unverified\",\n ...inventory,\n ...(resources ? { resources } : {}),\n ...(gitReport ? { git: gitReport } : {}),\n ...(lockReport ? { locks: lockReport } : {}),\n };\n}\n"]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ResourceInspection } from "../infrastructure/resource-activity.types.ts";
|
|
1
2
|
import type { LockInspection } from "../infrastructure/git/lock-inspection.types.ts";
|
|
2
3
|
import type { WorkspaceGitInspection } from "../infrastructure/git/worktree-inspection.types.ts";
|
|
3
4
|
import type { StorageInventory } from "../infrastructure/storage-inventory.types.ts";
|
|
@@ -6,10 +7,12 @@ export interface RecoveryInspectionOptions {
|
|
|
6
7
|
readonly maxEntries?: number;
|
|
7
8
|
readonly git?: boolean;
|
|
8
9
|
readonly locks?: boolean;
|
|
10
|
+
readonly resources?: boolean;
|
|
9
11
|
}
|
|
10
12
|
export interface RecoveryInspection extends StorageInventory {
|
|
11
13
|
readonly repository: string;
|
|
12
14
|
readonly activity: "unverified";
|
|
13
15
|
readonly git?: WorkspaceGitInspection;
|
|
14
16
|
readonly locks?: LockInspection;
|
|
17
|
+
readonly resources?: ResourceInspection;
|
|
15
18
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recovery-inspection.types.js","sourceRoot":"","sources":["../../src/application/recovery-inspection.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { LockInspection } from \"../infrastructure/git/lock-inspection.types.ts\";\nimport type { WorkspaceGitInspection } from \"../infrastructure/git/worktree-inspection.types.ts\";\nimport type { StorageInventory } from \"../infrastructure/storage-inventory.types.ts\";\n\nexport interface RecoveryInspectionOptions {\n readonly repository?: string;\n readonly maxEntries?: number;\n readonly git?: boolean;\n readonly locks?: boolean;\n}\nexport interface RecoveryInspection extends StorageInventory {\n readonly repository: string;\n readonly activity: \"unverified\";\n readonly git?: WorkspaceGitInspection;\n readonly locks?: LockInspection;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"recovery-inspection.types.js","sourceRoot":"","sources":["../../src/application/recovery-inspection.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { ResourceInspection } from \"../infrastructure/resource-activity.types.ts\";\nimport type { LockInspection } from \"../infrastructure/git/lock-inspection.types.ts\";\nimport type { WorkspaceGitInspection } from \"../infrastructure/git/worktree-inspection.types.ts\";\nimport type { StorageInventory } from \"../infrastructure/storage-inventory.types.ts\";\n\nexport interface RecoveryInspectionOptions {\n readonly repository?: string;\n readonly maxEntries?: number;\n readonly git?: boolean;\n readonly locks?: boolean;\n readonly resources?: boolean;\n}\nexport interface RecoveryInspection extends StorageInventory {\n readonly repository: string;\n readonly activity: \"unverified\";\n readonly git?: WorkspaceGitInspection;\n readonly locks?: LockInspection;\n readonly resources?: ResourceInspection;\n}\n"]}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { cp, lstat, mkdir, mkdtemp, realpath, rm, writeFile, } from "node:fs/promises";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { dirname, join } from "node:path";
|
|
5
|
+
import { invariant, positive } from "../domain/errors.js";
|
|
6
|
+
import { directory, safeDestination } from "../infrastructure/files.js";
|
|
7
|
+
import { readInspectionFile } from "../infrastructure/inspection-file.js";
|
|
8
|
+
import { recoveryChecksumPaths } from "./recovery-checksum-paths.js";
|
|
9
|
+
import { recoveryChecksumDefaults } from "./recovery-checksums.constants.js";
|
|
10
|
+
import { recoveryVerificationDefaults } from "./recovery-verification.constants.js";
|
|
11
|
+
import { transferState, verifyRecoveryTransfer, } from "./recovery-verification.js";
|
|
12
|
+
export async function snapshotRecoveryTransfer(path, maxBytes = recoveryChecksumDefaults.maxBytes) {
|
|
13
|
+
positive(maxBytes, "maxBytes");
|
|
14
|
+
const source = await directory(path);
|
|
15
|
+
const stateBytes = await readInspectionFile(join(source, "state.json"), recoveryVerificationDefaults.maxStateBytes);
|
|
16
|
+
const state = JSON.parse(stateBytes.toString("utf8"));
|
|
17
|
+
invariant(transferState(state), "Invalid recovery transfer state");
|
|
18
|
+
const manifest = await readInspectionFile(join(source, recoveryChecksumDefaults.filename), recoveryChecksumDefaults.maxManifestBytes);
|
|
19
|
+
const snapshot = await realpath(await mkdtemp(join(tmpdir(), "outpost-restore-")));
|
|
20
|
+
const dispose = () => rm(snapshot, { recursive: true, force: true, maxRetries: 3 });
|
|
21
|
+
try {
|
|
22
|
+
await writeFile(join(snapshot, "state.json"), stateBytes, { mode: 0o600 });
|
|
23
|
+
await writeFile(join(snapshot, recoveryChecksumDefaults.filename), manifest, { mode: 0o600 });
|
|
24
|
+
let bytes = stateBytes.length;
|
|
25
|
+
for (const entry of recoveryChecksumPaths(state).filter((name) => name !== "state.json")) {
|
|
26
|
+
const from = await safeDestination(source, entry);
|
|
27
|
+
const info = await lstat(from);
|
|
28
|
+
invariant(info.isFile() || info.isSymbolicLink(), "Unsupported recovery payload type");
|
|
29
|
+
bytes += info.size;
|
|
30
|
+
invariant(bytes <= maxBytes, "Recovery snapshot byte limit exceeded");
|
|
31
|
+
const to = await safeDestination(snapshot, entry);
|
|
32
|
+
await mkdir(dirname(to), { recursive: true, mode: 0o700 });
|
|
33
|
+
await cp(from, to, {
|
|
34
|
+
dereference: false,
|
|
35
|
+
verbatimSymlinks: true,
|
|
36
|
+
force: false,
|
|
37
|
+
errorOnExist: true,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
const verified = await verifyRecoveryTransfer(snapshot, {
|
|
41
|
+
checksums: true,
|
|
42
|
+
maxBytes,
|
|
43
|
+
});
|
|
44
|
+
invariant(verified.complete && verified.integrity === "checksums-match", "Recovery snapshot integrity verification failed");
|
|
45
|
+
return {
|
|
46
|
+
directory: snapshot,
|
|
47
|
+
state,
|
|
48
|
+
manifestSha256: createHash("sha256").update(manifest).digest("hex"),
|
|
49
|
+
dispose,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
await dispose();
|
|
54
|
+
throw error;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=recovery-restore-snapshot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recovery-restore-snapshot.js","sourceRoot":"","sources":["../../src/application/recovery-restore-snapshot.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"node:crypto\";\nimport {\n cp,\n lstat,\n mkdir,\n mkdtemp,\n realpath,\n rm,\n writeFile,\n} from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { invariant, positive } from \"../domain/errors.ts\";\nimport { directory, safeDestination } from \"../infrastructure/files.ts\";\nimport { readInspectionFile } from \"../infrastructure/inspection-file.ts\";\nimport { recoveryChecksumPaths } from \"./recovery-checksum-paths.ts\";\nimport { recoveryChecksumDefaults } from \"./recovery-checksums.constants.ts\";\nimport { recoveryVerificationDefaults } from \"./recovery-verification.constants.ts\";\nimport {\n transferState,\n verifyRecoveryTransfer,\n} from \"./recovery-verification.ts\";\nimport type { RecoveryRestoreSnapshot } from \"./recovery-restore.types.ts\";\n\nexport async function snapshotRecoveryTransfer(\n path: string,\n maxBytes: number = recoveryChecksumDefaults.maxBytes,\n): Promise<RecoveryRestoreSnapshot> {\n positive(maxBytes, \"maxBytes\");\n const source = await directory(path);\n const stateBytes = await readInspectionFile(\n join(source, \"state.json\"),\n recoveryVerificationDefaults.maxStateBytes,\n );\n const state: unknown = JSON.parse(stateBytes.toString(\"utf8\"));\n invariant(transferState(state), \"Invalid recovery transfer state\");\n const manifest = await readInspectionFile(\n join(source, recoveryChecksumDefaults.filename),\n recoveryChecksumDefaults.maxManifestBytes,\n );\n const snapshot = await realpath(\n await mkdtemp(join(tmpdir(), \"outpost-restore-\")),\n );\n const dispose = () =>\n rm(snapshot, { recursive: true, force: true, maxRetries: 3 });\n try {\n await writeFile(join(snapshot, \"state.json\"), stateBytes, { mode: 0o600 });\n await writeFile(\n join(snapshot, recoveryChecksumDefaults.filename),\n manifest,\n { mode: 0o600 },\n );\n let bytes = stateBytes.length;\n for (const entry of recoveryChecksumPaths(state).filter(\n (name) => name !== \"state.json\",\n )) {\n const from = await safeDestination(source, entry);\n const info = await lstat(from);\n invariant(\n info.isFile() || info.isSymbolicLink(),\n \"Unsupported recovery payload type\",\n );\n bytes += info.size;\n invariant(bytes <= maxBytes, \"Recovery snapshot byte limit exceeded\");\n const to = await safeDestination(snapshot, entry);\n await mkdir(dirname(to), { recursive: true, mode: 0o700 });\n await cp(from, to, {\n dereference: false,\n verbatimSymlinks: true,\n force: false,\n errorOnExist: true,\n });\n }\n const verified = await verifyRecoveryTransfer(snapshot, {\n checksums: true,\n maxBytes,\n });\n invariant(\n verified.complete && verified.integrity === \"checksums-match\",\n \"Recovery snapshot integrity verification failed\",\n );\n return {\n directory: snapshot,\n state,\n manifestSha256: createHash(\"sha256\").update(manifest).digest(\"hex\"),\n dispose,\n };\n } catch (error) {\n await dispose();\n throw error;\n }\n}\n"]}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { RecoveryRestoreOptions, RecoveryRestorePlan, RecoveryRestoreResult } from "./recovery-restore.types.ts";
|
|
2
|
+
export declare function planRecoveryRestore(options: RecoveryRestoreOptions): Promise<RecoveryRestorePlan>;
|
|
3
|
+
export declare function restoreRecoveryTransfer(plan: RecoveryRestorePlan): Promise<RecoveryRestoreResult>;
|