@elie-laloum/outpost 2.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 +42 -0
- package/README.md +3 -1
- package/SECURITY.md +3 -1
- package/dist/adapters/agents/claude-diagnostics.d.ts +1 -0
- package/dist/adapters/agents/claude-diagnostics.js +7 -0
- package/dist/adapters/agents/claude-diagnostics.js.map +1 -0
- package/dist/adapters/agents/cli-diagnostics.constants.d.ts +12 -0
- package/dist/adapters/agents/cli-diagnostics.constants.js +24 -0
- package/dist/adapters/agents/cli-diagnostics.constants.js.map +1 -0
- package/dist/adapters/agents/cli-diagnostics.d.ts +4 -0
- package/dist/adapters/agents/cli-diagnostics.js +14 -0
- package/dist/adapters/agents/cli-diagnostics.js.map +1 -0
- package/dist/adapters/agents/cli-diagnostics.types.d.ts +13 -0
- package/dist/adapters/agents/cli-diagnostics.types.js +2 -0
- package/dist/adapters/agents/cli-diagnostics.types.js.map +1 -0
- package/dist/adapters/agents/codex-diagnostics.d.ts +1 -0
- package/dist/adapters/agents/codex-diagnostics.js +7 -0
- package/dist/adapters/agents/codex-diagnostics.js.map +1 -0
- 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 +2 -0
- package/dist/adapters/agents/protocol-fixtures.constants.js +105 -0
- package/dist/adapters/agents/protocol-fixtures.constants.js.map +1 -0
- package/dist/adapters/agents/protocol-fixtures.types.d.ts +6 -0
- package/dist/adapters/agents/protocol-fixtures.types.js +2 -0
- package/dist/adapters/agents/protocol-fixtures.types.js.map +1 -0
- 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/diagnostic-probe.d.ts +3 -0
- package/dist/application/diagnostic-probe.js +55 -0
- package/dist/application/diagnostic-probe.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 +11 -0
- package/dist/application/doctor-agent.constants.js +10 -0
- package/dist/application/doctor-agent.constants.js.map +1 -0
- package/dist/application/doctor-agent.d.ts +3 -0
- package/dist/application/doctor-agent.js +53 -0
- package/dist/application/doctor-agent.js.map +1 -0
- package/dist/application/doctor-image.d.ts +3 -0
- package/dist/application/doctor-image.js +133 -0
- package/dist/application/doctor-image.js.map +1 -0
- package/dist/application/doctor-protocol.d.ts +3 -0
- package/dist/application/doctor-protocol.js +30 -0
- package/dist/application/doctor-protocol.js.map +1 -0
- package/dist/application/doctor-protocol.types.d.ts +10 -0
- package/dist/application/doctor-protocol.types.js +2 -0
- package/dist/application/doctor-protocol.types.js.map +1 -0
- package/dist/application/doctor-sandbox.constants.d.ts +5 -0
- package/dist/application/doctor-sandbox.constants.js +6 -0
- package/dist/application/doctor-sandbox.constants.js.map +1 -0
- package/dist/application/doctor-sandbox.d.ts +4 -0
- package/dist/application/doctor-sandbox.js +133 -0
- package/dist/application/doctor-sandbox.js.map +1 -0
- package/dist/application/doctor-sandbox.types.d.ts +23 -0
- package/dist/application/doctor-sandbox.types.js +2 -0
- package/dist/application/doctor-sandbox.types.js.map +1 -0
- package/dist/application/doctor-transfers.constants.d.ts +6 -0
- package/dist/application/doctor-transfers.constants.js +7 -0
- package/dist/application/doctor-transfers.constants.js.map +1 -0
- package/dist/application/doctor-transfers.d.ts +4 -0
- package/dist/application/doctor-transfers.js +88 -0
- package/dist/application/doctor-transfers.js.map +1 -0
- package/dist/application/doctor.constants.d.ts +9 -0
- package/dist/application/doctor.constants.js +15 -0
- package/dist/application/doctor.constants.js.map +1 -0
- package/dist/application/doctor.d.ts +3 -0
- package/dist/application/doctor.js +106 -0
- package/dist/application/doctor.js.map +1 -0
- package/dist/application/doctor.types.d.ts +39 -0
- package/dist/application/doctor.types.js +2 -0
- package/dist/application/doctor.types.js.map +1 -0
- package/dist/application/execution.js +1 -0
- package/dist/application/execution.js.map +1 -1
- package/dist/application/outpost.types.d.ts +4 -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-checksum-capture.d.ts +2 -0
- package/dist/application/recovery-checksum-capture.js +32 -0
- package/dist/application/recovery-checksum-capture.js.map +1 -0
- package/dist/application/recovery-checksum-paths.d.ts +2 -0
- package/dist/application/recovery-checksum-paths.js +11 -0
- package/dist/application/recovery-checksum-paths.js.map +1 -0
- package/dist/application/recovery-checksums.constants.d.ts +5 -0
- package/dist/application/recovery-checksums.constants.js +6 -0
- package/dist/application/recovery-checksums.constants.js.map +1 -0
- package/dist/application/recovery-checksums.d.ts +3 -0
- package/dist/application/recovery-checksums.js +94 -0
- package/dist/application/recovery-checksums.js.map +1 -0
- package/dist/application/recovery-checksums.types.d.ts +17 -0
- package/dist/application/recovery-checksums.types.js +2 -0
- package/dist/application/recovery-checksums.types.js.map +1 -0
- package/dist/application/recovery-inspection.d.ts +2 -0
- package/dist/application/recovery-inspection.js +32 -0
- package/dist/application/recovery-inspection.js.map +1 -0
- package/dist/application/recovery-inspection.types.d.ts +18 -0
- package/dist/application/recovery-inspection.types.js +2 -0
- package/dist/application/recovery-inspection.types.js.map +1 -0
- package/dist/application/recovery-restorability.d.ts +2 -0
- package/dist/application/recovery-restorability.js +137 -0
- package/dist/application/recovery-restorability.js.map +1 -0
- 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-policy.d.ts +2 -0
- package/dist/application/recovery-retention-policy.js +21 -0
- package/dist/application/recovery-retention-policy.js.map +1 -0
- package/dist/application/recovery-retention.constants.d.ts +3 -0
- package/dist/application/recovery-retention.constants.js +2 -0
- package/dist/application/recovery-retention.constants.js.map +1 -0
- package/dist/application/recovery-retention.d.ts +4 -0
- package/dist/application/recovery-retention.js +207 -0
- package/dist/application/recovery-retention.js.map +1 -0
- package/dist/application/recovery-retention.types.d.ts +52 -0
- package/dist/application/recovery-retention.types.js +2 -0
- package/dist/application/recovery-retention.types.js.map +1 -0
- package/dist/application/recovery-verification.constants.d.ts +5 -0
- package/dist/application/recovery-verification.constants.js +10 -0
- package/dist/application/recovery-verification.constants.js.map +1 -0
- package/dist/application/recovery-verification.d.ts +3 -0
- package/dist/application/recovery-verification.js +107 -0
- package/dist/application/recovery-verification.js.map +1 -0
- package/dist/application/recovery-verification.types.d.ts +26 -0
- package/dist/application/recovery-verification.types.js +2 -0
- package/dist/application/recovery-verification.types.js.map +1 -0
- package/dist/application/remote-apply.js +30 -6
- package/dist/application/remote-apply.js.map +1 -1
- package/dist/application/remote-backup.js +6 -2
- package/dist/application/remote-backup.js.map +1 -1
- package/dist/application/remote-download.js +38 -6
- 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 +39 -28
- package/dist/application/remote-validation.js.map +1 -1
- package/dist/application/remote-workspace.constants.d.ts +3 -0
- package/dist/application/remote-workspace.constants.js +2 -0
- package/dist/application/remote-workspace.constants.js.map +1 -0
- package/dist/application/remote-workspace.js +10 -10
- package/dist/application/remote-workspace.js.map +1 -1
- package/dist/application/remote-workspace.types.d.ts +3 -1
- package/dist/application/remote-workspace.types.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 +33 -10
- 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 +4 -0
- package/dist/application/task-usage.js +41 -0
- package/dist/application/task-usage.js.map +1 -0
- package/dist/application/task-usage.types.d.ts +5 -0
- package/dist/application/task-usage.types.js +2 -0
- package/dist/application/task-usage.types.js.map +1 -0
- package/dist/application/tasks.js +23 -2
- 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 +4 -0
- package/dist/cli/commands.js.map +1 -1
- package/dist/cli/doctor-command.d.ts +3 -0
- package/dist/cli/doctor-command.js +38 -0
- package/dist/cli/doctor-command.js.map +1 -0
- package/dist/cli/main.constants.d.ts +38 -2
- package/dist/cli/main.constants.js +21 -2
- package/dist/cli/main.constants.js.map +1 -1
- package/dist/cli/recovery-command.d.ts +2 -0
- package/dist/cli/recovery-command.js +93 -0
- package/dist/cli/recovery-command.js.map +1 -0
- package/dist/cli/recovery-prune-command.d.ts +2 -0
- package/dist/cli/recovery-prune-command.js +34 -0
- package/dist/cli/recovery-prune-command.js.map +1 -0
- 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/recovery-verify-command.d.ts +2 -0
- package/dist/cli/recovery-verify-command.js +43 -0
- package/dist/cli/recovery-verify-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/ports.d.ts +1 -1
- package/dist/domain/ports.js.map +1 -1
- package/dist/domain/sandbox.types.d.ts +13 -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.constants.d.ts +1 -0
- package/dist/domain/workflow/budget.constants.js +7 -0
- package/dist/domain/workflow/budget.constants.js.map +1 -0
- package/dist/domain/workflow/budget.d.ts +9 -0
- package/dist/domain/workflow/budget.js +69 -0
- package/dist/domain/workflow/budget.js.map +1 -0
- package/dist/domain/workflow/budget.types.d.ts +15 -0
- package/dist/domain/workflow/budget.types.js +2 -0
- package/dist/domain/workflow/budget.types.js.map +1 -0
- 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 +22 -3
- 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 +68 -33
- 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 +107 -3
- package/dist/domain/workflow/workflow-state.js.map +1 -1
- package/dist/domain/workflow.d.ts +2 -0
- package/dist/domain/workflow.js +1 -0
- package/dist/domain/workflow.js.map +1 -1
- package/dist/domain/workflow.types.d.ts +23 -3
- package/dist/domain/workflow.types.js.map +1 -1
- package/dist/index.d.ts +44 -5
- package/dist/index.js +19 -2
- 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 +6 -0
- package/dist/infrastructure/file-manifest.js +92 -0
- package/dist/infrastructure/file-manifest.js.map +1 -0
- package/dist/infrastructure/git/lock-inspection.constants.d.ts +4 -0
- package/dist/infrastructure/git/lock-inspection.constants.js +5 -0
- package/dist/infrastructure/git/lock-inspection.constants.js.map +1 -0
- package/dist/infrastructure/git/lock-inspection.d.ts +3 -0
- package/dist/infrastructure/git/lock-inspection.js +64 -0
- package/dist/infrastructure/git/lock-inspection.js.map +1 -0
- package/dist/infrastructure/git/lock-inspection.types.d.ts +27 -0
- package/dist/infrastructure/git/lock-inspection.types.js +2 -0
- package/dist/infrastructure/git/lock-inspection.types.js.map +1 -0
- package/dist/infrastructure/git/lock.d.ts +1 -0
- package/dist/infrastructure/git/lock.js +70 -29
- package/dist/infrastructure/git/lock.js.map +1 -1
- package/dist/infrastructure/git/process-identity.d.ts +3 -0
- package/dist/infrastructure/git/process-identity.js +73 -0
- package/dist/infrastructure/git/process-identity.js.map +1 -0
- package/dist/infrastructure/git/process-identity.types.d.ts +10 -0
- package/dist/infrastructure/git/process-identity.types.js +2 -0
- package/dist/infrastructure/git/process-identity.types.js.map +1 -0
- package/dist/infrastructure/git/verification-command.d.ts +1 -0
- package/dist/infrastructure/git/verification-command.js +37 -0
- package/dist/infrastructure/git/verification-command.js.map +1 -0
- package/dist/infrastructure/git/workspace-lease.js +1 -0
- package/dist/infrastructure/git/workspace-lease.js.map +1 -1
- package/dist/infrastructure/git/workspace.js +5 -1
- package/dist/infrastructure/git/workspace.js.map +1 -1
- package/dist/infrastructure/git/worktree-inspection.constants.d.ts +5 -0
- package/dist/infrastructure/git/worktree-inspection.constants.js +16 -0
- package/dist/infrastructure/git/worktree-inspection.constants.js.map +1 -0
- package/dist/infrastructure/git/worktree-inspection.d.ts +3 -0
- package/dist/infrastructure/git/worktree-inspection.js +120 -0
- package/dist/infrastructure/git/worktree-inspection.js.map +1 -0
- package/dist/infrastructure/git/worktree-inspection.types.d.ts +19 -0
- package/dist/infrastructure/git/worktree-inspection.types.js +2 -0
- package/dist/infrastructure/git/worktree-inspection.types.js.map +1 -0
- package/dist/infrastructure/inspection-file.constants.d.ts +1 -0
- package/dist/infrastructure/inspection-file.constants.js +5 -0
- package/dist/infrastructure/inspection-file.constants.js.map +1 -0
- package/dist/infrastructure/inspection-file.d.ts +1 -0
- package/dist/infrastructure/inspection-file.js +43 -0
- package/dist/infrastructure/inspection-file.js.map +1 -0
- package/dist/infrastructure/inspection-hash.constants.d.ts +1 -0
- package/dist/infrastructure/inspection-hash.constants.js +2 -0
- package/dist/infrastructure/inspection-hash.constants.js.map +1 -0
- package/dist/infrastructure/inspection-hash.d.ts +2 -0
- package/dist/infrastructure/inspection-hash.js +62 -0
- package/dist/infrastructure/inspection-hash.js.map +1 -0
- package/dist/infrastructure/inspection-hash.types.d.ts +5 -0
- package/dist/infrastructure/inspection-hash.types.js +2 -0
- package/dist/infrastructure/inspection-hash.types.js.map +1 -0
- package/dist/infrastructure/journal-retention.constants.d.ts +4 -0
- package/dist/infrastructure/journal-retention.constants.js +5 -0
- package/dist/infrastructure/journal-retention.constants.js.map +1 -0
- package/dist/infrastructure/journal-retention.d.ts +2 -0
- package/dist/infrastructure/journal-retention.js +51 -0
- package/dist/infrastructure/journal-retention.js.map +1 -0
- package/dist/infrastructure/journal.js +37 -13
- package/dist/infrastructure/journal.js.map +1 -1
- package/dist/infrastructure/opentelemetry.constants.d.ts +10 -0
- package/dist/infrastructure/opentelemetry.constants.js +11 -0
- package/dist/infrastructure/opentelemetry.constants.js.map +1 -0
- package/dist/infrastructure/opentelemetry.d.ts +3 -0
- package/dist/infrastructure/opentelemetry.js +131 -0
- package/dist/infrastructure/opentelemetry.js.map +1 -0
- package/dist/infrastructure/opentelemetry.types.d.ts +21 -0
- package/dist/infrastructure/opentelemetry.types.js +2 -0
- package/dist/infrastructure/opentelemetry.types.js.map +1 -0
- 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-inventory.constants.d.ts +6 -0
- package/dist/infrastructure/storage-inventory.constants.js +11 -0
- package/dist/infrastructure/storage-inventory.constants.js.map +1 -0
- package/dist/infrastructure/storage-inventory.d.ts +2 -0
- package/dist/infrastructure/storage-inventory.js +123 -0
- package/dist/infrastructure/storage-inventory.js.map +1 -0
- package/dist/infrastructure/storage-inventory.types.d.ts +38 -0
- package/dist/infrastructure/storage-inventory.types.js +2 -0
- package/dist/infrastructure/storage-inventory.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 +17 -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/cloud.constants.d.ts +1 -0
- package/dist/providers/cloud.constants.js +1 -0
- package/dist/providers/cloud.constants.js.map +1 -1
- package/dist/providers/container-cache.constants.d.ts +11 -0
- package/dist/providers/container-cache.constants.js +9 -0
- package/dist/providers/container-cache.constants.js.map +1 -0
- package/dist/providers/container-cache.d.ts +4 -0
- package/dist/providers/container-cache.js +48 -0
- package/dist/providers/container-cache.js.map +1 -0
- package/dist/providers/container-cache.types.d.ts +8 -0
- package/dist/providers/container-cache.types.js +2 -0
- package/dist/providers/container-cache.types.js.map +1 -0
- 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 +6 -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 +50 -3
- package/dist/providers/container.js.map +1 -1
- package/dist/providers/container.types.d.ts +5 -0
- package/dist/providers/container.types.js.map +1 -1
- package/dist/providers/daytona-command.js +10 -6
- 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 +15 -4
- package/dist/providers/daytona.js.map +1 -1
- package/dist/providers/diagnostic-container.d.ts +4 -0
- package/dist/providers/diagnostic-container.js +15 -0
- package/dist/providers/diagnostic-container.js.map +1 -0
- package/dist/providers/docker.d.ts +2 -0
- package/dist/providers/docker.js.map +1 -1
- package/dist/providers/file-batches.constants.d.ts +10 -0
- package/dist/providers/file-batches.constants.js +57 -0
- package/dist/providers/file-batches.constants.js.map +1 -0
- package/dist/providers/file-batches.d.ts +2 -0
- package/dist/providers/file-batches.js +160 -0
- package/dist/providers/file-batches.js.map +1 -0
- 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 +2 -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 +8 -2
- 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 +16 -1
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export function trackedSandboxLease(lease, activity) {
|
|
2
|
+
const transfers = lease.fileTransfers;
|
|
3
|
+
const upload = transfers?.uploadBatch?.bind(transfers);
|
|
4
|
+
const uploadBatch = upload
|
|
5
|
+
? (...args) => activity.run("upload-batch", () => upload(...args))
|
|
6
|
+
: undefined;
|
|
7
|
+
return {
|
|
8
|
+
...lease,
|
|
9
|
+
invoke: (command) => activity.run("invoke", () => lease.invoke(command)),
|
|
10
|
+
upload: (source, destination, options) => activity.run("upload", () => lease.upload(source, destination, options)),
|
|
11
|
+
download: (source, destination, options) => activity.run("download", () => lease.download(source, destination, options)),
|
|
12
|
+
release: lease.release.bind(lease),
|
|
13
|
+
...(transfers
|
|
14
|
+
? {
|
|
15
|
+
fileTransfers: {
|
|
16
|
+
...transfers,
|
|
17
|
+
...(uploadBatch ? { uploadBatch } : {}),
|
|
18
|
+
manifest: (source, paths, options) => activity.run("manifest", () => transfers.manifest(source, paths, options)),
|
|
19
|
+
downloadBatch: (source, entries, destination, options) => activity.run("download-batch", () => transfers.downloadBatch(source, entries, destination, options)),
|
|
20
|
+
},
|
|
21
|
+
}
|
|
22
|
+
: {}),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=sandbox-activity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox-activity.js","sourceRoot":"","sources":["../../src/application/sandbox-activity.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,mBAAmB,CACjC,KAAmB,EACnB,QAA0B;IAE1B,MAAM,SAAS,GAAG,KAAK,CAAC,aAAa,CAAC;IACtC,MAAM,MAAM,GAAG,SAAS,EAAE,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IACvD,MAAM,WAAW,GAAiC,MAAM;QACtD,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,cAAc,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC;QAClE,CAAC,CAAC,SAAS,CAAC;IACd,OAAO;QACL,GAAG,KAAK;QACR,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACxE,MAAM,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,CACvC,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;QAC1E,QAAQ,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,CACzC,QAAQ,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,EAAE,CAC5B,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,CAAC,CAC7C;QACH,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;QAClC,GAAG,CAAC,SAAS;YACX,CAAC,CAAC;gBACE,aAAa,EAAE;oBACb,GAAG,SAAS;oBACZ,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACvC,QAAQ,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,CACnC,QAAQ,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,EAAE,CAC5B,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAC3C;oBACH,aAAa,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,CACvD,QAAQ,CAAC,GAAG,CAAC,gBAAgB,EAAE,GAAG,EAAE,CAClC,SAAS,CAAC,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,CAAC,CAC/D;iBACJ;aACF;YACH,CAAC,CAAC,EAAE,CAAC;KACR,CAAC;AACJ,CAAC","sourcesContent":["import type { FileTransfers, SandboxLease } from \"../domain/sandbox.types.ts\";\nimport type { ResourceActivity } from \"../infrastructure/resource-activity.types.ts\";\n\nexport function trackedSandboxLease(\n lease: SandboxLease,\n activity: ResourceActivity,\n): SandboxLease {\n const transfers = lease.fileTransfers;\n const upload = transfers?.uploadBatch?.bind(transfers);\n const uploadBatch: FileTransfers[\"uploadBatch\"] = upload\n ? (...args) => activity.run(\"upload-batch\", () => upload(...args))\n : undefined;\n return {\n ...lease,\n invoke: (command) => activity.run(\"invoke\", () => lease.invoke(command)),\n upload: (source, destination, options) =>\n activity.run(\"upload\", () => lease.upload(source, destination, options)),\n download: (source, destination, options) =>\n activity.run(\"download\", () =>\n lease.download(source, destination, options),\n ),\n release: lease.release.bind(lease),\n ...(transfers\n ? {\n fileTransfers: {\n ...transfers,\n ...(uploadBatch ? { uploadBatch } : {}),\n manifest: (source, paths, options) =>\n activity.run(\"manifest\", () =>\n transfers.manifest(source, paths, options),\n ),\n downloadBatch: (source, entries, destination, options) =>\n activity.run(\"download-batch\", () =>\n transfers.downloadBatch(source, entries, destination, options),\n ),\n },\n }\n : {}),\n };\n}\n"]}
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { lstat } from "node:fs/promises";
|
|
2
2
|
import { join, posix } from "node:path";
|
|
3
3
|
import { invariant } from "../domain/errors.js";
|
|
4
4
|
import { git } from "../infrastructure/git/command.js";
|
|
5
5
|
import { executeProcess } from "../infrastructure/process.js";
|
|
6
6
|
import { resolveVariables } from "../infrastructure/settings.js";
|
|
7
|
+
import { registerResourceActivity } from "../infrastructure/resource-activity.js";
|
|
8
|
+
import { trackedSandboxLease } from "./sandbox-activity.js";
|
|
7
9
|
import { boundedTransfers } from "../infrastructure/transfer.js";
|
|
8
10
|
import { docker } from "../providers/docker.js";
|
|
9
11
|
import { prepareAdapter } from "./agent-bootstrap.js";
|
|
10
12
|
import { hooks } from "./lifecycle-hooks.js";
|
|
13
|
+
import { uploadFiles } from "./remote-upload.js";
|
|
11
14
|
import { seedRemote } from "./remote-workspace.js";
|
|
12
15
|
import { startupFailure } from "./startup-recovery.js";
|
|
13
16
|
import { workspaces } from "./workspace-registry.js";
|
|
@@ -18,7 +21,10 @@ export async function provisionSandbox(options) {
|
|
|
18
21
|
if (provider.placement === "remote" && !options.workspace && !options.branch)
|
|
19
22
|
options = { ...options, branch: { mode: "integrate" } };
|
|
20
23
|
invariant(!options.workspace ||
|
|
21
|
-
(!options.repository &&
|
|
24
|
+
(!options.repository &&
|
|
25
|
+
!options.branch &&
|
|
26
|
+
!options.copies &&
|
|
27
|
+
!options.storageQuota), "A supplied workspace owns its repository, branch, copied inputs and storage quota");
|
|
22
28
|
const owned = !options.workspace;
|
|
23
29
|
invariant(provider.placement !== "remote" ||
|
|
24
30
|
((options.workspace?.policy ?? options.branch)?.mode !== "current" &&
|
|
@@ -33,9 +39,17 @@ export async function provisionSandbox(options) {
|
|
|
33
39
|
? AbortSignal.any([options.signal, stop.signal])
|
|
34
40
|
: stop.signal;
|
|
35
41
|
let lease, sync;
|
|
42
|
+
let activity;
|
|
43
|
+
let acquisitionStarted = false;
|
|
36
44
|
const prepared = new Map();
|
|
37
45
|
const staging = join(workspace.repository, ".outpost", "recovery", "conversations");
|
|
38
46
|
try {
|
|
47
|
+
activity = await registerResourceActivity({
|
|
48
|
+
repository: workspace.repository,
|
|
49
|
+
workspace: workspace.directory,
|
|
50
|
+
provider: provider.name,
|
|
51
|
+
placement: provider.placement,
|
|
52
|
+
});
|
|
39
53
|
const configured = await resolveVariables(workspace.repository, {}, provider.variables);
|
|
40
54
|
const name = (await git(workspace.repository, ["config", "--get", "user.name"]).catch(() => "Outpost")).trim();
|
|
41
55
|
const email = (await git(workspace.repository, ["config", "--get", "user.email"]).catch(() => "outpost@localhost")).trim();
|
|
@@ -46,13 +60,14 @@ export async function provisionSandbox(options) {
|
|
|
46
60
|
GIT_COMMITTER_EMAIL: email,
|
|
47
61
|
...configured,
|
|
48
62
|
};
|
|
49
|
-
|
|
63
|
+
acquisitionStarted = true;
|
|
64
|
+
lease = boundedTransfers(trackedSandboxLease(await provider.acquire({
|
|
50
65
|
repository: workspace.repository,
|
|
51
66
|
directory: workspace.directory,
|
|
52
67
|
gitDirectories: workspace.gitDirectories,
|
|
53
68
|
variables,
|
|
54
69
|
signal: setupSignal,
|
|
55
|
-
}), {
|
|
70
|
+
}), activity), {
|
|
56
71
|
...(options.limits?.copyMs
|
|
57
72
|
? { deadlineMs: options.limits.copyMs }
|
|
58
73
|
: {}),
|
|
@@ -63,13 +78,24 @@ export async function provisionSandbox(options) {
|
|
|
63
78
|
...(options.limits ? { limits: options.limits } : {}),
|
|
64
79
|
signal: setupSignal,
|
|
65
80
|
});
|
|
66
|
-
|
|
67
|
-
|
|
81
|
+
const copiedFiles = [];
|
|
82
|
+
for (const path of options.copies ?? []) {
|
|
83
|
+
const info = await lstat(join(workspace.directory, path)).catch((error) => {
|
|
68
84
|
if (error.code === "ENOENT")
|
|
69
85
|
return undefined;
|
|
70
86
|
throw error;
|
|
71
|
-
})
|
|
72
|
-
|
|
87
|
+
});
|
|
88
|
+
if (!info)
|
|
89
|
+
continue;
|
|
90
|
+
if (info.isFile() || info.isSymbolicLink()) {
|
|
91
|
+
copiedFiles.push(path.replaceAll("\\", "/"));
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
await lease.upload(join(workspace.directory, path), posix.join(lease.root, path.replaceAll("\\", "/")), { signal: setupSignal });
|
|
95
|
+
}
|
|
96
|
+
await uploadFiles(lease, workspace.directory, [...new Set(copiedFiles)], {
|
|
97
|
+
signal: setupSignal,
|
|
98
|
+
});
|
|
73
99
|
if (options.bootstrap !== false && options.agent)
|
|
74
100
|
prepared.set(options.agent, await prepareAdapter(options.agent, lease, setupSignal));
|
|
75
101
|
}
|
|
@@ -83,13 +109,31 @@ export async function provisionSandbox(options) {
|
|
|
83
109
|
const failure = initialized.find((item) => item.status === "rejected");
|
|
84
110
|
if (failure?.status === "rejected")
|
|
85
111
|
throw failure.reason;
|
|
112
|
+
await activity.phase("ready");
|
|
86
113
|
}
|
|
87
114
|
catch (cause) {
|
|
88
115
|
await startupFailure(workspace, cause, options);
|
|
89
|
-
|
|
116
|
+
const allocationUncertain = acquisitionStarted && !lease;
|
|
117
|
+
let cleanupFailed = allocationUncertain;
|
|
118
|
+
await activity?.phase("closing").catch(() => {
|
|
119
|
+
cleanupFailed = true;
|
|
120
|
+
});
|
|
121
|
+
await lease?.release().catch(() => {
|
|
122
|
+
cleanupFailed = true;
|
|
123
|
+
});
|
|
124
|
+
if (activity && !(await activity.idle()))
|
|
125
|
+
cleanupFailed = true;
|
|
90
126
|
state.active = false;
|
|
91
127
|
if (owned)
|
|
92
|
-
await workspace.close()
|
|
128
|
+
await workspace.close({ preserve: cleanupFailed }).catch(() => {
|
|
129
|
+
cleanupFailed = true;
|
|
130
|
+
});
|
|
131
|
+
if (cleanupFailed)
|
|
132
|
+
await activity
|
|
133
|
+
?.phase(allocationUncertain ? "allocation-uncertain" : "cleanup-failed")
|
|
134
|
+
.catch(() => undefined);
|
|
135
|
+
if (!cleanupFailed)
|
|
136
|
+
await activity?.remove().catch(() => undefined);
|
|
93
137
|
throw cause;
|
|
94
138
|
}
|
|
95
139
|
return {
|
|
@@ -100,6 +144,7 @@ export async function provisionSandbox(options) {
|
|
|
100
144
|
owned,
|
|
101
145
|
stop,
|
|
102
146
|
runtime: lease,
|
|
147
|
+
activity,
|
|
103
148
|
sync,
|
|
104
149
|
prepared,
|
|
105
150
|
staging,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sandbox-provision.js","sourceRoot":"","sources":["../../src/application/sandbox-provision.ts"],"names":[],"mappings":"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","sourcesContent":["import { stat } from \"node:fs/promises\";\nimport { join, posix } from \"node:path\";\nimport type { AgentAdapter } from \"../domain/agent.types.ts\";\nimport { invariant } from \"../domain/errors.ts\";\nimport type { SandboxLease } from \"../domain/sandbox.types.ts\";\nimport { git } from \"../infrastructure/git/command.ts\";\nimport { executeProcess } from \"../infrastructure/process.ts\";\nimport { resolveVariables } from \"../infrastructure/settings.ts\";\nimport { boundedTransfers } from \"../infrastructure/transfer.ts\";\nimport { docker } from \"../providers/docker.ts\";\nimport { prepareAdapter } from \"./agent-bootstrap.ts\";\nimport { hooks } from \"./lifecycle-hooks.ts\";\nimport type { SandboxOptions } from \"./outpost.types.ts\";\nimport { seedRemote } from \"./remote-workspace.ts\";\nimport type { RemoteSync } from \"./remote-workspace.types.ts\";\nimport type { ProvisionedSandbox } from \"./sandbox-session.types.ts\";\nimport { startupFailure } from \"./startup-recovery.ts\";\nimport { workspaces } from \"./workspace-registry.ts\";\nimport { openWorkspace } from \"./workspace.ts\";\n\nexport async function provisionSandbox(\n options: SandboxOptions,\n): Promise<ProvisionedSandbox> {\n options.signal?.throwIfAborted();\n const provider = options.provider ?? docker();\n if (provider.placement === \"remote\" && !options.workspace && !options.branch)\n options = { ...options, branch: { mode: \"integrate\" } };\n invariant(\n !options.workspace ||\n (!options.repository && !options.branch && !options.copies),\n \"A supplied workspace owns its repository, branch and copied inputs\",\n );\n const owned = !options.workspace;\n invariant(\n provider.placement !== \"remote\" ||\n ((options.workspace?.policy ?? options.branch)?.mode !== \"current\" &&\n (options.workspace || options.branch)),\n \"Remote providers require a named or integration workspace\",\n );\n const workspace = options.workspace ?? (await openWorkspace(options));\n const state = workspaces.get(workspace);\n invariant(\n state && !state.closed && !state.active,\n \"Workspace must be open and cannot belong to another sandbox\",\n );\n state.active = true;\n const lifecycle = options.hooks ?? state.hooks;\n const stop = new AbortController();\n const setupSignal = options.signal\n ? AbortSignal.any([options.signal, stop.signal])\n : stop.signal;\n let lease: SandboxLease | undefined, sync: RemoteSync | undefined;\n const prepared = new Map<AgentAdapter, AgentAdapter>();\n const staging = join(\n workspace.repository,\n \".outpost\",\n \"recovery\",\n \"conversations\",\n );\n try {\n const configured = await resolveVariables(\n workspace.repository,\n {},\n provider.variables,\n );\n const name = (\n await git(workspace.repository, [\"config\", \"--get\", \"user.name\"]).catch(\n () => \"Outpost\",\n )\n ).trim();\n const email = (\n await git(workspace.repository, [\"config\", \"--get\", \"user.email\"]).catch(\n () => \"outpost@localhost\",\n )\n ).trim();\n const variables = {\n GIT_AUTHOR_NAME: name,\n GIT_COMMITTER_NAME: name,\n GIT_AUTHOR_EMAIL: email,\n GIT_COMMITTER_EMAIL: email,\n ...configured,\n };\n lease = boundedTransfers(\n await provider.acquire({\n repository: workspace.repository,\n directory: workspace.directory,\n gitDirectories: workspace.gitDirectories,\n variables,\n signal: setupSignal,\n }),\n {\n ...(options.limits?.copyMs\n ? { deadlineMs: options.limits.copyMs }\n : {}),\n },\n );\n if (provider.placement === \"remote\") {\n sync = await seedRemote(workspace, lease, {\n ...(options.includeUncommitted ? { includeUncommitted: true } : {}),\n ...(options.limits ? { limits: options.limits } : {}),\n signal: setupSignal,\n });\n for (const path of options.copies ?? [])\n if (\n await stat(join(workspace.directory, path)).catch((error) => {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\")\n return undefined;\n throw error;\n })\n )\n await lease.upload(\n join(workspace.directory, path),\n posix.join(lease.root, path.replaceAll(\"\\\\\", \"/\")),\n );\n if (options.bootstrap !== false && options.agent)\n prepared.set(\n options.agent,\n await prepareAdapter(options.agent, lease, setupSignal),\n );\n }\n const initialized = await Promise.allSettled(\n [\n hooks(\n lifecycle?.hostReady ?? [],\n workspace.directory,\n executeProcess,\n setupSignal,\n ),\n hooks(\n lifecycle?.sandboxReady ?? [],\n lease.root,\n lease.invoke.bind(lease),\n setupSignal,\n true,\n ),\n ].map((pending) =>\n pending.catch((cause) => {\n stop.abort(cause);\n throw cause;\n }),\n ),\n );\n const failure = initialized.find((item) => item.status === \"rejected\");\n if (failure?.status === \"rejected\") throw failure.reason;\n } catch (cause) {\n await startupFailure(workspace, cause, options);\n await lease?.release().catch(() => undefined);\n state.active = false;\n if (owned) await workspace.close();\n throw cause;\n }\n\n return {\n options,\n provider,\n workspace,\n state,\n owned,\n stop,\n runtime: lease,\n sync,\n prepared,\n staging,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"sandbox-provision.js","sourceRoot":"","sources":["../../src/application/sandbox-provision.ts"],"names":[],"mappings":"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","sourcesContent":["import { lstat } from \"node:fs/promises\";\nimport { join, posix } from \"node:path\";\nimport type { AgentAdapter } from \"../domain/agent.types.ts\";\nimport { invariant } from \"../domain/errors.ts\";\nimport type { SandboxLease } from \"../domain/sandbox.types.ts\";\nimport { git } from \"../infrastructure/git/command.ts\";\nimport { executeProcess } from \"../infrastructure/process.ts\";\nimport { resolveVariables } from \"../infrastructure/settings.ts\";\nimport { registerResourceActivity } from \"../infrastructure/resource-activity.ts\";\nimport type { ResourceActivity } from \"../infrastructure/resource-activity.types.ts\";\nimport { trackedSandboxLease } from \"./sandbox-activity.ts\";\nimport { boundedTransfers } from \"../infrastructure/transfer.ts\";\nimport { docker } from \"../providers/docker.ts\";\nimport { prepareAdapter } from \"./agent-bootstrap.ts\";\nimport { hooks } from \"./lifecycle-hooks.ts\";\nimport type { SandboxOptions } from \"./outpost.types.ts\";\nimport { uploadFiles } from \"./remote-upload.ts\";\nimport { seedRemote } from \"./remote-workspace.ts\";\nimport type { RemoteSync } from \"./remote-workspace.types.ts\";\nimport type { ProvisionedSandbox } from \"./sandbox-session.types.ts\";\nimport { startupFailure } from \"./startup-recovery.ts\";\nimport { workspaces } from \"./workspace-registry.ts\";\nimport { openWorkspace } from \"./workspace.ts\";\n\nexport async function provisionSandbox(\n options: SandboxOptions,\n): Promise<ProvisionedSandbox> {\n options.signal?.throwIfAborted();\n const provider = options.provider ?? docker();\n if (provider.placement === \"remote\" && !options.workspace && !options.branch)\n options = { ...options, branch: { mode: \"integrate\" } };\n invariant(\n !options.workspace ||\n (!options.repository &&\n !options.branch &&\n !options.copies &&\n !options.storageQuota),\n \"A supplied workspace owns its repository, branch, copied inputs and storage quota\",\n );\n const owned = !options.workspace;\n invariant(\n provider.placement !== \"remote\" ||\n ((options.workspace?.policy ?? options.branch)?.mode !== \"current\" &&\n (options.workspace || options.branch)),\n \"Remote providers require a named or integration workspace\",\n );\n const workspace = options.workspace ?? (await openWorkspace(options));\n const state = workspaces.get(workspace);\n invariant(\n state && !state.closed && !state.active,\n \"Workspace must be open and cannot belong to another sandbox\",\n );\n state.active = true;\n const lifecycle = options.hooks ?? state.hooks;\n const stop = new AbortController();\n const setupSignal = options.signal\n ? AbortSignal.any([options.signal, stop.signal])\n : stop.signal;\n let lease: SandboxLease | undefined, sync: RemoteSync | undefined;\n let activity: ResourceActivity | undefined;\n let acquisitionStarted = false;\n const prepared = new Map<AgentAdapter, AgentAdapter>();\n const staging = join(\n workspace.repository,\n \".outpost\",\n \"recovery\",\n \"conversations\",\n );\n try {\n activity = await registerResourceActivity({\n repository: workspace.repository,\n workspace: workspace.directory,\n provider: provider.name,\n placement: provider.placement,\n });\n const configured = await resolveVariables(\n workspace.repository,\n {},\n provider.variables,\n );\n const name = (\n await git(workspace.repository, [\"config\", \"--get\", \"user.name\"]).catch(\n () => \"Outpost\",\n )\n ).trim();\n const email = (\n await git(workspace.repository, [\"config\", \"--get\", \"user.email\"]).catch(\n () => \"outpost@localhost\",\n )\n ).trim();\n const variables = {\n GIT_AUTHOR_NAME: name,\n GIT_COMMITTER_NAME: name,\n GIT_AUTHOR_EMAIL: email,\n GIT_COMMITTER_EMAIL: email,\n ...configured,\n };\n acquisitionStarted = true;\n lease = boundedTransfers(\n trackedSandboxLease(\n await provider.acquire({\n repository: workspace.repository,\n directory: workspace.directory,\n gitDirectories: workspace.gitDirectories,\n variables,\n signal: setupSignal,\n }),\n activity,\n ),\n {\n ...(options.limits?.copyMs\n ? { deadlineMs: options.limits.copyMs }\n : {}),\n },\n );\n if (provider.placement === \"remote\") {\n sync = await seedRemote(workspace, lease, {\n ...(options.includeUncommitted ? { includeUncommitted: true } : {}),\n ...(options.limits ? { limits: options.limits } : {}),\n signal: setupSignal,\n });\n const copiedFiles: string[] = [];\n for (const path of options.copies ?? []) {\n const info = await lstat(join(workspace.directory, path)).catch(\n (error) => {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\")\n return undefined;\n throw error;\n },\n );\n if (!info) continue;\n if (info.isFile() || info.isSymbolicLink()) {\n copiedFiles.push(path.replaceAll(\"\\\\\", \"/\"));\n continue;\n }\n await lease.upload(\n join(workspace.directory, path),\n posix.join(lease.root, path.replaceAll(\"\\\\\", \"/\")),\n { signal: setupSignal },\n );\n }\n await uploadFiles(lease, workspace.directory, [...new Set(copiedFiles)], {\n signal: setupSignal,\n });\n if (options.bootstrap !== false && options.agent)\n prepared.set(\n options.agent,\n await prepareAdapter(options.agent, lease, setupSignal),\n );\n }\n const initialized = await Promise.allSettled(\n [\n hooks(\n lifecycle?.hostReady ?? [],\n workspace.directory,\n executeProcess,\n setupSignal,\n ),\n hooks(\n lifecycle?.sandboxReady ?? [],\n lease.root,\n lease.invoke.bind(lease),\n setupSignal,\n true,\n ),\n ].map((pending) =>\n pending.catch((cause) => {\n stop.abort(cause);\n throw cause;\n }),\n ),\n );\n const failure = initialized.find((item) => item.status === \"rejected\");\n if (failure?.status === \"rejected\") throw failure.reason;\n await activity.phase(\"ready\");\n } catch (cause) {\n await startupFailure(workspace, cause, options);\n const allocationUncertain = acquisitionStarted && !lease;\n let cleanupFailed = allocationUncertain;\n await activity?.phase(\"closing\").catch(() => {\n cleanupFailed = true;\n });\n await lease?.release().catch(() => {\n cleanupFailed = true;\n });\n if (activity && !(await activity.idle())) cleanupFailed = true;\n state.active = false;\n if (owned)\n await workspace.close({ preserve: cleanupFailed }).catch(() => {\n cleanupFailed = true;\n });\n if (cleanupFailed)\n await activity\n ?.phase(allocationUncertain ? \"allocation-uncertain\" : \"cleanup-failed\")\n .catch(() => undefined);\n if (!cleanupFailed) await activity?.remove().catch(() => undefined);\n throw cause;\n }\n\n return {\n options,\n provider,\n workspace,\n state,\n owned,\n stop,\n runtime: lease,\n activity,\n sync,\n prepared,\n staging,\n };\n}\n"]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ResourceActivity } from "../infrastructure/resource-activity.types.ts";
|
|
1
2
|
import type { AgentAdapter } from "../domain/agent.types.ts";
|
|
2
3
|
import type { SandboxLease, SandboxProvider } from "../domain/sandbox.types.ts";
|
|
3
4
|
import type { LifecycleHooks } from "../domain/workspace.types.ts";
|
|
@@ -18,6 +19,7 @@ export interface ProvisionedSandbox {
|
|
|
18
19
|
readonly owned: boolean;
|
|
19
20
|
readonly stop: AbortController;
|
|
20
21
|
readonly runtime: SandboxLease;
|
|
22
|
+
readonly activity: ResourceActivity;
|
|
21
23
|
readonly sync: RemoteSync | undefined;
|
|
22
24
|
readonly prepared: Map<AgentAdapter, AgentAdapter>;
|
|
23
25
|
readonly staging: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sandbox-session.types.js","sourceRoot":"","sources":["../../src/application/sandbox-session.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { AgentAdapter } from \"../domain/agent.types.ts\";\nimport type { SandboxLease, SandboxProvider } from \"../domain/sandbox.types.ts\";\nimport type { LifecycleHooks } from \"../domain/workspace.types.ts\";\nimport type { WorkspaceLease } from \"../infrastructure/git/workspace.types.ts\";\nimport type { SandboxOptions, Workspace } from \"./outpost.types.ts\";\nimport type { RemoteSync } from \"./remote-workspace.types.ts\";\n\nexport interface WorkspaceState {\n lease: WorkspaceLease;\n active: boolean;\n closed: boolean;\n hooks?: LifecycleHooks;\n}\n\nexport interface ProvisionedSandbox {\n readonly options: SandboxOptions;\n readonly provider: SandboxProvider;\n readonly workspace: Workspace;\n readonly state: WorkspaceState;\n readonly owned: boolean;\n readonly stop: AbortController;\n readonly runtime: SandboxLease;\n readonly sync: RemoteSync | undefined;\n readonly prepared: Map<AgentAdapter, AgentAdapter>;\n readonly staging: string;\n}\n\nexport interface SelectedAgent {\n readonly selected: AgentAdapter;\n readonly adapter: AgentAdapter;\n readonly executionLease: SandboxLease;\n}\n\nexport interface SandboxAgents {\n selectAgent(\n agent: AgentAdapter | undefined,\n signal: AbortSignal,\n ): Promise<SelectedAgent>;\n restore(id: string, agent: AgentAdapter): Promise<void>;\n remember(agent: AgentAdapter, id: string): void;\n}\n\nexport interface OperationGate {\n run<T>(action: () => Promise<T>): Promise<T>;\n close(): Promise<void>;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"sandbox-session.types.js","sourceRoot":"","sources":["../../src/application/sandbox-session.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { ResourceActivity } from \"../infrastructure/resource-activity.types.ts\";\nimport type { AgentAdapter } from \"../domain/agent.types.ts\";\nimport type { SandboxLease, SandboxProvider } from \"../domain/sandbox.types.ts\";\nimport type { LifecycleHooks } from \"../domain/workspace.types.ts\";\nimport type { WorkspaceLease } from \"../infrastructure/git/workspace.types.ts\";\nimport type { SandboxOptions, Workspace } from \"./outpost.types.ts\";\nimport type { RemoteSync } from \"./remote-workspace.types.ts\";\n\nexport interface WorkspaceState {\n lease: WorkspaceLease;\n active: boolean;\n closed: boolean;\n hooks?: LifecycleHooks;\n}\n\nexport interface ProvisionedSandbox {\n readonly options: SandboxOptions;\n readonly provider: SandboxProvider;\n readonly workspace: Workspace;\n readonly state: WorkspaceState;\n readonly owned: boolean;\n readonly stop: AbortController;\n readonly runtime: SandboxLease;\n readonly activity: ResourceActivity;\n readonly sync: RemoteSync | undefined;\n readonly prepared: Map<AgentAdapter, AgentAdapter>;\n readonly staging: string;\n}\n\nexport interface SelectedAgent {\n readonly selected: AgentAdapter;\n readonly adapter: AgentAdapter;\n readonly executionLease: SandboxLease;\n}\n\nexport interface SandboxAgents {\n selectAgent(\n agent: AgentAdapter | undefined,\n signal: AbortSignal,\n ): Promise<SelectedAgent>;\n restore(id: string, agent: AgentAdapter): Promise<void>;\n remember(agent: AgentAdapter, id: string): void;\n}\n\nexport interface OperationGate {\n run<T>(action: () => Promise<T>): Promise<T>;\n close(): Promise<void>;\n}\n"]}
|
|
@@ -2,6 +2,7 @@ import { OutpostError } from "../domain/errors.js";
|
|
|
2
2
|
import { validateBrief } from "../domain/prompts.js";
|
|
3
3
|
import { registerCleanup } from "../infrastructure/shutdown.js";
|
|
4
4
|
import { validateDispatch } from "./dispatch-validation.js";
|
|
5
|
+
import { diagnoseSandbox } from "./doctor-sandbox.js";
|
|
5
6
|
import { operationGate } from "./operation-gate.js";
|
|
6
7
|
import { sandboxAgents } from "./sandbox-agents.js";
|
|
7
8
|
import { attachInSandbox } from "./sandbox-attach.js";
|
|
@@ -12,14 +13,14 @@ export async function createSandbox(options = {}) {
|
|
|
12
13
|
const { workspace, runtime, sync, stop, state, owned } = context;
|
|
13
14
|
const agents = sandboxAgents(context);
|
|
14
15
|
const gate = operationGate();
|
|
15
|
-
const exclusive = gate.run;
|
|
16
|
+
const exclusive = (kind, action) => gate.run(() => context.activity.run(kind, action));
|
|
16
17
|
let closing;
|
|
17
18
|
const result = {
|
|
18
19
|
workspace,
|
|
19
20
|
root: runtime.root,
|
|
20
21
|
dispatch(settings) {
|
|
21
22
|
validateDispatch(settings);
|
|
22
|
-
return exclusive(() => dispatchInSandbox(context, agents, result, settings));
|
|
23
|
+
return exclusive("dispatch", () => dispatchInSandbox(context, agents, result, settings));
|
|
23
24
|
},
|
|
24
25
|
resume(id, settings) {
|
|
25
26
|
return result.dispatch({ ...settings, continuation: { id } });
|
|
@@ -30,11 +31,21 @@ export async function createSandbox(options = {}) {
|
|
|
30
31
|
attach(settings = {}) {
|
|
31
32
|
settings.signal?.throwIfAborted();
|
|
32
33
|
validateBrief(settings.brief, true);
|
|
33
|
-
return exclusive(() => attachInSandbox(context, agents, settings));
|
|
34
|
+
return exclusive("attach", () => attachInSandbox(context, agents, settings));
|
|
35
|
+
},
|
|
36
|
+
diagnose(settings = {}) {
|
|
37
|
+
settings.signal?.throwIfAborted();
|
|
38
|
+
return exclusive("diagnose", () => diagnoseSandbox(runtime, {
|
|
39
|
+
...settings,
|
|
40
|
+
provider: context.provider,
|
|
41
|
+
signal: settings.signal
|
|
42
|
+
? AbortSignal.any([settings.signal, stop.signal])
|
|
43
|
+
: stop.signal,
|
|
44
|
+
}));
|
|
34
45
|
},
|
|
35
46
|
command(command) {
|
|
36
47
|
command.signal?.throwIfAborted();
|
|
37
|
-
return exclusive(async () => {
|
|
48
|
+
return exclusive("command", async () => {
|
|
38
49
|
try {
|
|
39
50
|
return await runtime.invoke({
|
|
40
51
|
...command,
|
|
@@ -55,21 +66,33 @@ export async function createSandbox(options = {}) {
|
|
|
55
66
|
stop.abort(new OutpostError("aborted", "Sandbox closed"));
|
|
56
67
|
await gate.close();
|
|
57
68
|
let failure;
|
|
69
|
+
await context.activity.phase("closing").catch(() => undefined);
|
|
58
70
|
try {
|
|
59
71
|
await runtime.release();
|
|
60
72
|
await sync?.close();
|
|
73
|
+
if (!(await context.activity.idle()))
|
|
74
|
+
throw new OutpostError("provider", "Sandbox operations remain unsettled after release");
|
|
61
75
|
}
|
|
62
76
|
catch (cause) {
|
|
63
77
|
failure = cause;
|
|
64
78
|
}
|
|
65
79
|
state.active = false;
|
|
66
80
|
unregister();
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
81
|
+
let disposal = {};
|
|
82
|
+
try {
|
|
83
|
+
if (owned)
|
|
84
|
+
disposal = await workspace.close({
|
|
85
|
+
preserve: settings.preserve || !!failure,
|
|
86
|
+
});
|
|
87
|
+
if (failure)
|
|
88
|
+
throw failure;
|
|
89
|
+
await context.activity.remove();
|
|
90
|
+
return disposal;
|
|
91
|
+
}
|
|
92
|
+
catch (cause) {
|
|
93
|
+
await context.activity.phase("cleanup-failed").catch(() => undefined);
|
|
94
|
+
throw cause;
|
|
95
|
+
}
|
|
73
96
|
})();
|
|
74
97
|
return closing;
|
|
75
98
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../../src/application/sandbox.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../../src/application/sandbox.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ResourceOperationKind } from \"../infrastructure/resource-activity.types.ts\";\nimport { OutpostError } from \"../domain/errors.ts\";\nimport { validateBrief } from \"../domain/prompts.ts\";\nimport type { Disposal } from \"../domain/workspace.types.ts\";\nimport { registerCleanup } from \"../infrastructure/shutdown.ts\";\nimport { validateDispatch } from \"./dispatch-validation.ts\";\nimport { diagnoseSandbox } from \"./doctor-sandbox.ts\";\nimport { operationGate } from \"./operation-gate.ts\";\nimport type { Sandbox, SandboxOptions } from \"./outpost.types.ts\";\nimport { sandboxAgents } from \"./sandbox-agents.ts\";\nimport { attachInSandbox } from \"./sandbox-attach.ts\";\nimport { dispatchInSandbox } from \"./sandbox-dispatch.ts\";\nimport { provisionSandbox } from \"./sandbox-provision.ts\";\n\nexport async function createSandbox(\n options: SandboxOptions = {},\n): Promise<Sandbox> {\n const context = await provisionSandbox(options);\n const { workspace, runtime, sync, stop, state, owned } = context;\n const agents = sandboxAgents(context);\n const gate = operationGate();\n const exclusive = <T>(\n kind: ResourceOperationKind,\n action: () => Promise<T>,\n ) => gate.run(() => context.activity.run(kind, action));\n let closing: Promise<Disposal> | undefined;\n const result: Sandbox = {\n workspace,\n root: runtime.root,\n dispatch(settings) {\n validateDispatch(settings);\n return exclusive(\"dispatch\", () =>\n dispatchInSandbox(context, agents, result, settings),\n );\n },\n resume(id, settings) {\n return result.dispatch({ ...settings, continuation: { id } });\n },\n fork(id, settings) {\n return result.dispatch({ ...settings, continuation: { id, fork: true } });\n },\n attach(settings = {}) {\n settings.signal?.throwIfAborted();\n validateBrief(settings.brief, true);\n return exclusive(\"attach\", () =>\n attachInSandbox(context, agents, settings),\n );\n },\n diagnose(settings = {}) {\n settings.signal?.throwIfAborted();\n return exclusive(\"diagnose\", () =>\n diagnoseSandbox(runtime, {\n ...settings,\n provider: context.provider,\n signal: settings.signal\n ? AbortSignal.any([settings.signal, stop.signal])\n : stop.signal,\n }),\n );\n },\n command(command) {\n command.signal?.throwIfAborted();\n return exclusive(\"command\", async () => {\n try {\n return await runtime.invoke({\n ...command,\n signal: command.signal\n ? AbortSignal.any([command.signal, stop.signal])\n : stop.signal,\n });\n } finally {\n await sync?.pull();\n }\n });\n },\n close(settings = {}) {\n if (closing) return closing;\n closing = (async () => {\n stop.abort(new OutpostError(\"aborted\", \"Sandbox closed\"));\n await gate.close();\n let failure: unknown;\n await context.activity.phase(\"closing\").catch(() => undefined);\n try {\n await runtime.release();\n await sync?.close();\n if (!(await context.activity.idle()))\n throw new OutpostError(\n \"provider\",\n \"Sandbox operations remain unsettled after release\",\n );\n } catch (cause) {\n failure = cause;\n }\n state.active = false;\n\n unregister();\n let disposal: Disposal = {};\n try {\n if (owned)\n disposal = await workspace.close({\n preserve: settings.preserve || !!failure,\n });\n if (failure) throw failure;\n await context.activity.remove();\n return disposal;\n } catch (cause) {\n await context.activity.phase(\"cleanup-failed\").catch(() => undefined);\n throw cause;\n }\n })();\n return closing;\n },\n async [Symbol.asyncDispose]() {\n await result.close();\n },\n };\n const unregister = registerCleanup(() => result.close({ preserve: true }));\n return result;\n}\n"]}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { mkdtemp, rm } from "node:fs/promises";
|
|
2
|
+
import { tmpdir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { git } from "../infrastructure/git/command.js";
|
|
5
|
+
import { digest } from "./workspace-fingerprint.js";
|
|
6
|
+
export async function speculativeHostSnapshot(repository) {
|
|
7
|
+
const temporary = await mkdtemp(join(tmpdir(), "outpost-speculation-"));
|
|
8
|
+
try {
|
|
9
|
+
const head = (await git(repository, ["rev-parse", "--verify", "HEAD^{commit}"])).trim();
|
|
10
|
+
const branch = (await git(repository, ["rev-parse", "--abbrev-ref", "HEAD"])).trim();
|
|
11
|
+
const status = await git(repository, [
|
|
12
|
+
"status",
|
|
13
|
+
"--porcelain",
|
|
14
|
+
"--untracked-files=all",
|
|
15
|
+
"--",
|
|
16
|
+
".",
|
|
17
|
+
":(exclude).outpost",
|
|
18
|
+
]);
|
|
19
|
+
return {
|
|
20
|
+
head,
|
|
21
|
+
branch,
|
|
22
|
+
dirty: !!status.trim(),
|
|
23
|
+
fingerprint: await digest(repository, temporary),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
finally {
|
|
27
|
+
await rm(temporary, { recursive: true, force: true });
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=speculation-host.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"speculation-host.js","sourceRoot":"","sources":["../../src/application/speculation-host.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,GAAG,EAAE,MAAM,kCAAkC,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAGpD,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,UAAkB;IAElB,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,sBAAsB,CAAC,CAAC,CAAC;IACxE,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,CACX,MAAM,GAAG,CAAC,UAAU,EAAE,CAAC,WAAW,EAAE,UAAU,EAAE,eAAe,CAAC,CAAC,CAClE,CAAC,IAAI,EAAE,CAAC;QACT,MAAM,MAAM,GAAG,CACb,MAAM,GAAG,CAAC,UAAU,EAAE,CAAC,WAAW,EAAE,cAAc,EAAE,MAAM,CAAC,CAAC,CAC7D,CAAC,IAAI,EAAE,CAAC;QACT,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,UAAU,EAAE;YACnC,QAAQ;YACR,aAAa;YACb,uBAAuB;YACvB,IAAI;YACJ,GAAG;YACH,oBAAoB;SACrB,CAAC,CAAC;QACH,OAAO;YACL,IAAI;YACJ,MAAM;YACN,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE;YACtB,WAAW,EAAE,MAAM,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC;SACjD,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,MAAM,EAAE,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACxD,CAAC;AACH,CAAC","sourcesContent":["import { mkdtemp, rm } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { git } from \"../infrastructure/git/command.ts\";\nimport { digest } from \"./workspace-fingerprint.ts\";\nimport type { SpeculativeHostSnapshot } from \"./speculation.types.ts\";\n\nexport async function speculativeHostSnapshot(\n repository: string,\n): Promise<SpeculativeHostSnapshot> {\n const temporary = await mkdtemp(join(tmpdir(), \"outpost-speculation-\"));\n try {\n const head = (\n await git(repository, [\"rev-parse\", \"--verify\", \"HEAD^{commit}\"])\n ).trim();\n const branch = (\n await git(repository, [\"rev-parse\", \"--abbrev-ref\", \"HEAD\"])\n ).trim();\n const status = await git(repository, [\n \"status\",\n \"--porcelain\",\n \"--untracked-files=all\",\n \"--\",\n \".\",\n \":(exclude).outpost\",\n ]);\n return {\n head,\n branch,\n dirty: !!status.trim(),\n fingerprint: await digest(repository, temporary),\n };\n } finally {\n await rm(temporary, { recursive: true, force: true });\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"speculation.constants.js","sourceRoot":"","sources":["../../src/application/speculation.constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,UAAU,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAW,CAAC","sourcesContent":["export const speculationLimits = { candidates: 8, concurrency: 2 } as const;\n"]}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { invariant, recoveryDetails } from "../domain/errors.js";
|
|
3
|
+
import { workflowAccounting } from "../domain/workflow/budget.js";
|
|
4
|
+
import { speculativeHostSnapshot } from "./speculation-host.js";
|
|
5
|
+
import { createSandbox } from "./sandbox.js";
|
|
6
|
+
import { speculationLimits } from "./speculation.constants.js";
|
|
7
|
+
import { taskUsage } from "./task-usage.js";
|
|
8
|
+
export async function speculate(options) {
|
|
9
|
+
const { candidates } = options;
|
|
10
|
+
invariant(candidates.length > 0 && candidates.length <= speculationLimits.candidates, `Speculation requires 1 to ${speculationLimits.candidates} candidates`);
|
|
11
|
+
invariant(new Set(candidates.map((candidate) => candidate.key)).size ===
|
|
12
|
+
candidates.length &&
|
|
13
|
+
candidates.every((candidate) => /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$/.test(candidate.key)), "Speculative candidate keys must be unique simple names of 1 to 64 characters");
|
|
14
|
+
const concurrency = options.concurrency ?? speculationLimits.concurrency;
|
|
15
|
+
invariant(Number.isSafeInteger(concurrency) &&
|
|
16
|
+
concurrency > 0 &&
|
|
17
|
+
concurrency <= speculationLimits.candidates, `Speculation concurrency must be 1 to ${speculationLimits.candidates}`);
|
|
18
|
+
const stop = new AbortController();
|
|
19
|
+
const signal = options.signal
|
|
20
|
+
? AbortSignal.any([options.signal, stop.signal])
|
|
21
|
+
: stop.signal;
|
|
22
|
+
let budgetError;
|
|
23
|
+
const accounting = workflowAccounting(options.budget, (error) => {
|
|
24
|
+
budgetError = error;
|
|
25
|
+
// Attempt limits stop admissions; already admitted candidates may finish.
|
|
26
|
+
if (error.dimension !== "attempts")
|
|
27
|
+
stop.abort(error);
|
|
28
|
+
});
|
|
29
|
+
const before = await speculativeHostSnapshot(options.repository);
|
|
30
|
+
const baseline = before.head;
|
|
31
|
+
const id = randomUUID();
|
|
32
|
+
const records = candidates.map((candidate) => ({
|
|
33
|
+
key: candidate.key,
|
|
34
|
+
branch: `outpost/speculation/${id}/${candidate.key}`,
|
|
35
|
+
status: "skipped",
|
|
36
|
+
}));
|
|
37
|
+
let winner;
|
|
38
|
+
let next = 0;
|
|
39
|
+
async function worker() {
|
|
40
|
+
while (!signal.aborted && !winner && !accounting.exhausted) {
|
|
41
|
+
const index = next++;
|
|
42
|
+
const candidate = candidates[index];
|
|
43
|
+
if (!candidate)
|
|
44
|
+
return;
|
|
45
|
+
try {
|
|
46
|
+
accounting.admit();
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const initial = records[index];
|
|
52
|
+
let sandbox;
|
|
53
|
+
let result;
|
|
54
|
+
let error;
|
|
55
|
+
let accepted = false;
|
|
56
|
+
let cleanupFailed = false;
|
|
57
|
+
let retainedDirectory;
|
|
58
|
+
const usage = taskUsage({ reportUsage: (value) => accounting.report(value) }, candidate.request.observe);
|
|
59
|
+
try {
|
|
60
|
+
sandbox = await createSandbox({
|
|
61
|
+
...options.sandbox,
|
|
62
|
+
repository: options.repository,
|
|
63
|
+
provider: options.provider,
|
|
64
|
+
branch: { mode: "named", name: initial.branch, from: baseline },
|
|
65
|
+
agent: candidate.agent,
|
|
66
|
+
signal,
|
|
67
|
+
});
|
|
68
|
+
signal.throwIfAborted();
|
|
69
|
+
invariant(sandbox.workspace.baseline === baseline, "Speculative workspace does not match the pinned baseline");
|
|
70
|
+
const { resume: _resume, fork: _fork, ...output } = await sandbox.dispatch({
|
|
71
|
+
...candidate.request,
|
|
72
|
+
signal,
|
|
73
|
+
observe: usage.observe,
|
|
74
|
+
});
|
|
75
|
+
result = output;
|
|
76
|
+
usage.reconcile(output.usage);
|
|
77
|
+
signal.throwIfAborted();
|
|
78
|
+
accepted = await options.validate({
|
|
79
|
+
key: candidate.key,
|
|
80
|
+
result,
|
|
81
|
+
sandbox,
|
|
82
|
+
signal,
|
|
83
|
+
});
|
|
84
|
+
signal.throwIfAborted();
|
|
85
|
+
}
|
|
86
|
+
catch (cause) {
|
|
87
|
+
error = cause;
|
|
88
|
+
}
|
|
89
|
+
if (sandbox) {
|
|
90
|
+
try {
|
|
91
|
+
const disposal = await sandbox.close({
|
|
92
|
+
preserve: error !== undefined,
|
|
93
|
+
});
|
|
94
|
+
retainedDirectory = disposal.retainedDirectory;
|
|
95
|
+
}
|
|
96
|
+
catch (cause) {
|
|
97
|
+
cleanupFailed = true;
|
|
98
|
+
error =
|
|
99
|
+
error === undefined
|
|
100
|
+
? cause
|
|
101
|
+
: new AggregateError([error, cause], "Speculative execution and cleanup failed");
|
|
102
|
+
retainedDirectory = sandbox.workspace.directory;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
const recovery = recoveryDetails(error);
|
|
106
|
+
const recoveredDirectory = typeof recovery?.directory === "string"
|
|
107
|
+
? recovery.directory
|
|
108
|
+
: undefined;
|
|
109
|
+
const directory = sandbox?.workspace.directory ?? recoveredDirectory;
|
|
110
|
+
retainedDirectory ??= recoveredDirectory;
|
|
111
|
+
function candidateStatus() {
|
|
112
|
+
if (cleanupFailed)
|
|
113
|
+
return "failed";
|
|
114
|
+
if (signal.aborted)
|
|
115
|
+
return "cancelled";
|
|
116
|
+
if (error !== undefined)
|
|
117
|
+
return "failed";
|
|
118
|
+
if (accepted && !winner)
|
|
119
|
+
return "winner";
|
|
120
|
+
return "rejected";
|
|
121
|
+
}
|
|
122
|
+
const status = candidateStatus();
|
|
123
|
+
const record = {
|
|
124
|
+
...initial,
|
|
125
|
+
status,
|
|
126
|
+
...(directory ? { directory } : {}),
|
|
127
|
+
...(retainedDirectory ? { retainedDirectory } : {}),
|
|
128
|
+
...(result ? { result } : {}),
|
|
129
|
+
...(error !== undefined ? { error } : {}),
|
|
130
|
+
};
|
|
131
|
+
records[index] = record;
|
|
132
|
+
if (status === "winner") {
|
|
133
|
+
winner = record;
|
|
134
|
+
stop.abort(new Error(`Speculative candidate ${candidate.key} selected`));
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
await Promise.all(Array.from({ length: Math.min(concurrency, candidates.length) }, worker));
|
|
139
|
+
function outcome() {
|
|
140
|
+
if (winner)
|
|
141
|
+
return "winner";
|
|
142
|
+
if (options.signal?.aborted)
|
|
143
|
+
return "aborted";
|
|
144
|
+
if (budgetError !== undefined)
|
|
145
|
+
return "budget-exhausted";
|
|
146
|
+
return "no-winner";
|
|
147
|
+
}
|
|
148
|
+
const status = outcome();
|
|
149
|
+
const host = await speculativeHostSnapshot(options.repository).then((after) => ({
|
|
150
|
+
before,
|
|
151
|
+
after,
|
|
152
|
+
changed: before.fingerprint !== after.fingerprint ||
|
|
153
|
+
before.branch !== after.branch,
|
|
154
|
+
}), (error) => ({ before, changed: true, error }));
|
|
155
|
+
return {
|
|
156
|
+
id,
|
|
157
|
+
baseline,
|
|
158
|
+
host,
|
|
159
|
+
status,
|
|
160
|
+
candidates: records,
|
|
161
|
+
usage: accounting.snapshot(),
|
|
162
|
+
...(winner ? { winner } : {}),
|
|
163
|
+
...(budgetError !== undefined ? { error: budgetError } : {}),
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=speculation.js.map
|