@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,93 @@
|
|
|
1
|
+
import { recoveryRestoreCommand } from "./recovery-restore-command.js";
|
|
2
|
+
import { recoveryPruneCommand } from "./recovery-prune-command.js";
|
|
3
|
+
import { recoveryVerifyCommand } from "./recovery-verify-command.js";
|
|
4
|
+
import { inspectRecovery } from "../application/recovery-inspection.js";
|
|
5
|
+
import { invariant, positive } from "../domain/errors.js";
|
|
6
|
+
export async function recoveryCommand({ values, positionals, }) {
|
|
7
|
+
if (positionals[1] === "restore")
|
|
8
|
+
return recoveryRestoreCommand({ values, positionals });
|
|
9
|
+
if (positionals[1] === "prune")
|
|
10
|
+
return recoveryPruneCommand({ values, positionals });
|
|
11
|
+
if (positionals[1] === "verify")
|
|
12
|
+
return recoveryVerifyCommand({ values, positionals });
|
|
13
|
+
invariant(positionals.length === 2 && positionals[1] === "inspect", "Usage: outpost recovery inspect [--repository PATH] [--max-entries NUMBER] [--git] [--locks] [--resources] [--json]");
|
|
14
|
+
for (const key of Object.keys(values))
|
|
15
|
+
invariant([
|
|
16
|
+
"repository",
|
|
17
|
+
"max-entries",
|
|
18
|
+
"git",
|
|
19
|
+
"locks",
|
|
20
|
+
"resources",
|
|
21
|
+
"json",
|
|
22
|
+
].includes(key), `Unsupported recovery option: --${key}`);
|
|
23
|
+
const maxEntries = values["max-entries"] === undefined
|
|
24
|
+
? undefined
|
|
25
|
+
: positive(Number(values["max-entries"]), "max-entries");
|
|
26
|
+
const report = await inspectRecovery({
|
|
27
|
+
...(values.repository !== undefined
|
|
28
|
+
? { repository: values.repository }
|
|
29
|
+
: {}),
|
|
30
|
+
...(maxEntries !== undefined ? { maxEntries } : {}),
|
|
31
|
+
...(values.git ? { git: true } : {}),
|
|
32
|
+
...(values.resources ? { resources: true } : {}),
|
|
33
|
+
...(values.locks ? { locks: true } : {}),
|
|
34
|
+
});
|
|
35
|
+
if (values.json)
|
|
36
|
+
process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
|
|
37
|
+
else {
|
|
38
|
+
process.stdout.write(`Outpost recovery inspection — ${JSON.stringify(report.repository)}\n`);
|
|
39
|
+
for (const category of report.categories) {
|
|
40
|
+
process.stdout.write(`${category.name}: ${category.entries.length} listed entries\n`);
|
|
41
|
+
for (const entry of category.entries)
|
|
42
|
+
process.stdout.write(` ${JSON.stringify(entry.name)} | ${entry.kind} | ${entry.bytes} bytes | ${entry.files} files | ${entry.symlinks} symlinks | ${entry.modifiedAt ?? "unknown time"} | ${entry.complete ? "complete" : "partial"}\n`);
|
|
43
|
+
}
|
|
44
|
+
if (report.git) {
|
|
45
|
+
process.stdout.write(`Workspace Git inspection: ${report.git.complete ? "complete for listed entries" : "partial"}\n`);
|
|
46
|
+
for (const workspace of report.git.workspaces) {
|
|
47
|
+
const detail = workspace.state === "registered"
|
|
48
|
+
? `${workspace.branch === null ? "detached HEAD" : JSON.stringify(workspace.branch)} | ${workspace.dirty ? "dirty" : "clean"} | ${workspace.head}${workspace.locked ? " | Git locked" : ""}`
|
|
49
|
+
: workspace.state;
|
|
50
|
+
process.stdout.write(` ${JSON.stringify(workspace.name)} | ${detail}\n`);
|
|
51
|
+
}
|
|
52
|
+
for (const issue of report.git.issues)
|
|
53
|
+
process.stdout.write(`[PARTIAL] ${issue.code}: ${JSON.stringify(issue.path)}\n`);
|
|
54
|
+
process.stdout.write("Git status excludes ignored files. Clean does not mean safe to delete.\n");
|
|
55
|
+
}
|
|
56
|
+
if (report.locks) {
|
|
57
|
+
process.stdout.write(`Lock PID inspection (local host): ${report.locks.complete ? "complete for listed entries" : "partial"}\n`);
|
|
58
|
+
for (const lock of report.locks.entries) {
|
|
59
|
+
const pid = "pid" in lock ? ` | PID ${lock.pid}` : "";
|
|
60
|
+
const reason = "reason" in lock ? ` | ${lock.reason}` : "";
|
|
61
|
+
process.stdout.write(` ${JSON.stringify(lock.name)} | ${lock.state}${pid}${reason}${lock.ownership ? ` | ownership ${lock.ownership.status}: ${lock.ownership.reason}` : ""}\n`);
|
|
62
|
+
}
|
|
63
|
+
for (const issue of report.locks.issues)
|
|
64
|
+
process.stdout.write(`[PARTIAL] ${issue.code}: ${JSON.stringify(issue.path)}\n`);
|
|
65
|
+
process.stdout.write("PID presence does not prove lock ownership; PID absence does not authorize deletion.\n");
|
|
66
|
+
}
|
|
67
|
+
if (report.resources) {
|
|
68
|
+
process.stdout.write(`Recorded sandbox activity: ${report.resources.complete ? "complete for listed records" : "partial"}\n`);
|
|
69
|
+
for (const entry of report.resources.entries) {
|
|
70
|
+
const detail = entry.record
|
|
71
|
+
? `${JSON.stringify(entry.record.provider)} | ${entry.record.phase} | ${entry.record.operations.map((operation) => `${operation.kind} (${operation.count})`).join(", ") || "idle"}`
|
|
72
|
+
: "unreadable";
|
|
73
|
+
process.stdout.write(` ${JSON.stringify(entry.path)} | ${detail} | ownership ${entry.ownership.status}: ${entry.ownership.reason}\n`);
|
|
74
|
+
}
|
|
75
|
+
for (const issue of report.resources.issues)
|
|
76
|
+
process.stdout.write(`[PARTIAL] ${issue.code}: ${JSON.stringify(issue.path)}\n`);
|
|
77
|
+
process.stdout.write("Recorded activity is a snapshot; stale or unknown ownership does not authorize resource deletion. Provider resources are not queried.\n");
|
|
78
|
+
}
|
|
79
|
+
for (const issue of report.issues)
|
|
80
|
+
process.stdout.write(`[PARTIAL] ${issue.code}: ${JSON.stringify(issue.path)}\n`);
|
|
81
|
+
process.stdout.write(`Total observed: ${report.usage.bytes} bytes in ${report.usage.files} files; ${report.scannedEntries}/${report.maxEntries} entries scanned.\n`);
|
|
82
|
+
process.stdout.write(`${report.complete ? "Inventory complete." : "Inventory incomplete; totals are partial."} File sizes are logical bytes; symlink targets are excluded.\n`);
|
|
83
|
+
process.stdout.write(report.git || report.locks || report.resources
|
|
84
|
+
? "Activity and recovery integrity are unverified. No raw file contents were displayed or files removed.\n"
|
|
85
|
+
: "Activity and recovery integrity are unverified. No files were read for content or removed.\n");
|
|
86
|
+
}
|
|
87
|
+
if (!report.complete ||
|
|
88
|
+
report.git?.complete === false ||
|
|
89
|
+
report.locks?.complete === false ||
|
|
90
|
+
report.resources?.complete === false)
|
|
91
|
+
process.exitCode = 1;
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=recovery-command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recovery-command.js","sourceRoot":"","sources":["../../src/cli/recovery-command.ts"],"names":[],"mappings":"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","sourcesContent":["import { recoveryRestoreCommand } from \"./recovery-restore-command.ts\";\nimport { recoveryPruneCommand } from \"./recovery-prune-command.ts\";\nimport { recoveryVerifyCommand } from \"./recovery-verify-command.ts\";\nimport { inspectRecovery } from \"../application/recovery-inspection.ts\";\nimport { invariant, positive } from \"../domain/errors.ts\";\nimport type { CliInvocation } from \"./main.types.ts\";\n\nexport async function recoveryCommand({\n values,\n positionals,\n}: CliInvocation): Promise<void> {\n if (positionals[1] === \"restore\")\n return recoveryRestoreCommand({ values, positionals });\n if (positionals[1] === \"prune\")\n return recoveryPruneCommand({ values, positionals });\n if (positionals[1] === \"verify\")\n return recoveryVerifyCommand({ values, positionals });\n invariant(\n positionals.length === 2 && positionals[1] === \"inspect\",\n \"Usage: outpost recovery inspect [--repository PATH] [--max-entries NUMBER] [--git] [--locks] [--resources] [--json]\",\n );\n for (const key of Object.keys(values))\n invariant(\n [\n \"repository\",\n \"max-entries\",\n \"git\",\n \"locks\",\n \"resources\",\n \"json\",\n ].includes(key),\n `Unsupported recovery option: --${key}`,\n );\n const maxEntries =\n values[\"max-entries\"] === undefined\n ? undefined\n : positive(Number(values[\"max-entries\"]), \"max-entries\");\n const report = await inspectRecovery({\n ...(values.repository !== undefined\n ? { repository: values.repository }\n : {}),\n ...(maxEntries !== undefined ? { maxEntries } : {}),\n ...(values.git ? { git: true } : {}),\n ...(values.resources ? { resources: true } : {}),\n ...(values.locks ? { locks: true } : {}),\n });\n if (values.json) process.stdout.write(`${JSON.stringify(report, null, 2)}\\n`);\n else {\n process.stdout.write(\n `Outpost recovery inspection — ${JSON.stringify(report.repository)}\\n`,\n );\n for (const category of report.categories) {\n process.stdout.write(\n `${category.name}: ${category.entries.length} listed entries\\n`,\n );\n for (const entry of category.entries)\n process.stdout.write(\n ` ${JSON.stringify(entry.name)} | ${entry.kind} | ${entry.bytes} bytes | ${entry.files} files | ${entry.symlinks} symlinks | ${entry.modifiedAt ?? \"unknown time\"} | ${entry.complete ? \"complete\" : \"partial\"}\\n`,\n );\n }\n if (report.git) {\n process.stdout.write(\n `Workspace Git inspection: ${report.git.complete ? \"complete for listed entries\" : \"partial\"}\\n`,\n );\n for (const workspace of report.git.workspaces) {\n const detail =\n workspace.state === \"registered\"\n ? `${workspace.branch === null ? \"detached HEAD\" : JSON.stringify(workspace.branch)} | ${workspace.dirty ? \"dirty\" : \"clean\"} | ${workspace.head}${workspace.locked ? \" | Git locked\" : \"\"}`\n : workspace.state;\n process.stdout.write(\n ` ${JSON.stringify(workspace.name)} | ${detail}\\n`,\n );\n }\n for (const issue of report.git.issues)\n process.stdout.write(\n `[PARTIAL] ${issue.code}: ${JSON.stringify(issue.path)}\\n`,\n );\n process.stdout.write(\n \"Git status excludes ignored files. Clean does not mean safe to delete.\\n\",\n );\n }\n if (report.locks) {\n process.stdout.write(\n `Lock PID inspection (local host): ${report.locks.complete ? \"complete for listed entries\" : \"partial\"}\\n`,\n );\n for (const lock of report.locks.entries) {\n const pid = \"pid\" in lock ? ` | PID ${lock.pid}` : \"\";\n const reason = \"reason\" in lock ? ` | ${lock.reason}` : \"\";\n process.stdout.write(\n ` ${JSON.stringify(lock.name)} | ${lock.state}${pid}${reason}${lock.ownership ? ` | ownership ${lock.ownership.status}: ${lock.ownership.reason}` : \"\"}\\n`,\n );\n }\n for (const issue of report.locks.issues)\n process.stdout.write(\n `[PARTIAL] ${issue.code}: ${JSON.stringify(issue.path)}\\n`,\n );\n process.stdout.write(\n \"PID presence does not prove lock ownership; PID absence does not authorize deletion.\\n\",\n );\n }\n if (report.resources) {\n process.stdout.write(\n `Recorded sandbox activity: ${report.resources.complete ? \"complete for listed records\" : \"partial\"}\\n`,\n );\n for (const entry of report.resources.entries) {\n const detail = entry.record\n ? `${JSON.stringify(entry.record.provider)} | ${entry.record.phase} | ${entry.record.operations.map((operation) => `${operation.kind} (${operation.count})`).join(\", \") || \"idle\"}`\n : \"unreadable\";\n process.stdout.write(\n ` ${JSON.stringify(entry.path)} | ${detail} | ownership ${entry.ownership.status}: ${entry.ownership.reason}\\n`,\n );\n }\n for (const issue of report.resources.issues)\n process.stdout.write(\n `[PARTIAL] ${issue.code}: ${JSON.stringify(issue.path)}\\n`,\n );\n process.stdout.write(\n \"Recorded activity is a snapshot; stale or unknown ownership does not authorize resource deletion. Provider resources are not queried.\\n\",\n );\n }\n for (const issue of report.issues)\n process.stdout.write(\n `[PARTIAL] ${issue.code}: ${JSON.stringify(issue.path)}\\n`,\n );\n process.stdout.write(\n `Total observed: ${report.usage.bytes} bytes in ${report.usage.files} files; ${report.scannedEntries}/${report.maxEntries} entries scanned.\\n`,\n );\n process.stdout.write(\n `${report.complete ? \"Inventory complete.\" : \"Inventory incomplete; totals are partial.\"} File sizes are logical bytes; symlink targets are excluded.\\n`,\n );\n process.stdout.write(\n report.git || report.locks || report.resources\n ? \"Activity and recovery integrity are unverified. No raw file contents were displayed or files removed.\\n\"\n : \"Activity and recovery integrity are unverified. No files were read for content or removed.\\n\",\n );\n }\n if (\n !report.complete ||\n report.git?.complete === false ||\n report.locks?.complete === false ||\n report.resources?.complete === false\n )\n process.exitCode = 1;\n}\n"]}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { recoveryRetentionLimits } from "../application/recovery-retention.constants.js";
|
|
2
|
+
import { planRecoveryRetention, pruneRecoveryRetention, } from "../application/recovery-retention.js";
|
|
3
|
+
import { retentionPolicy } from "../application/recovery-retention-policy.js";
|
|
4
|
+
import { invariant } from "../domain/errors.js";
|
|
5
|
+
import { readInspectionFile } from "../infrastructure/inspection-file.js";
|
|
6
|
+
import { resolve } from "node:path";
|
|
7
|
+
export async function recoveryPruneCommand({ values, positionals, }) {
|
|
8
|
+
invariant(positionals.length === 2 && !!values.policy, "Usage: outpost recovery prune --policy FILE [--repository PATH] [--apply] [--json]");
|
|
9
|
+
for (const key of Object.keys(values))
|
|
10
|
+
invariant(["policy", "repository", "apply", "json"].includes(key), `Unsupported recovery prune option: --${key}`);
|
|
11
|
+
const policy = JSON.parse((await readInspectionFile(resolve(values.policy), recoveryRetentionLimits.maxPolicyBytes)).toString("utf8"));
|
|
12
|
+
retentionPolicy(policy);
|
|
13
|
+
const plan = await planRecoveryRetention({
|
|
14
|
+
policy,
|
|
15
|
+
...(values.repository ? { repository: values.repository } : {}),
|
|
16
|
+
});
|
|
17
|
+
const result = values.apply ? await pruneRecoveryRetention(plan) : undefined;
|
|
18
|
+
const after = result?.after ?? plan;
|
|
19
|
+
if (values.json)
|
|
20
|
+
process.stdout.write(`${JSON.stringify({ dryRun: !values.apply, plan, ...(result ? { result } : {}) }, null, 2)}\n`);
|
|
21
|
+
else {
|
|
22
|
+
process.stdout.write(`Outpost retention ${values.apply ? "apply" : "dry run"} — ${JSON.stringify(plan.repository)}\n`);
|
|
23
|
+
for (const entry of plan.entries)
|
|
24
|
+
process.stdout.write(`${entry.eligible ? "CANDIDATE" : "RETAIN"} ${JSON.stringify(entry.path)} | ${entry.reason} | ${entry.bytes} bytes\n`);
|
|
25
|
+
for (const path of result?.removed ?? [])
|
|
26
|
+
process.stdout.write(`REMOVED ${JSON.stringify(path)}\n`);
|
|
27
|
+
for (const entry of result?.retained ?? [])
|
|
28
|
+
process.stdout.write(`RETAIN ${JSON.stringify(entry.path)} | ${entry.reason}\n`);
|
|
29
|
+
process.stdout.write(`Observed ${after.usageBytes} logical bytes; projected ${after.projectedBytes}; projected quota ${after.quota}. Branches and recovery artifacts are retained.\n`);
|
|
30
|
+
}
|
|
31
|
+
if (!after.complete || after.quota !== "within" || result?.retained.length)
|
|
32
|
+
process.exitCode = 1;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=recovery-prune-command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recovery-prune-command.js","sourceRoot":"","sources":["../../src/cli/recovery-prune-command.ts"],"names":[],"mappings":"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","sourcesContent":["import { recoveryRetentionLimits } from \"../application/recovery-retention.constants.ts\";\nimport {\n planRecoveryRetention,\n pruneRecoveryRetention,\n} from \"../application/recovery-retention.ts\";\nimport { retentionPolicy } from \"../application/recovery-retention-policy.ts\";\nimport { invariant } from \"../domain/errors.ts\";\nimport { readInspectionFile } from \"../infrastructure/inspection-file.ts\";\nimport { resolve } from \"node:path\";\nimport type { CliInvocation } from \"./main.types.ts\";\n\nexport async function recoveryPruneCommand({\n values,\n positionals,\n}: CliInvocation): Promise<void> {\n invariant(\n positionals.length === 2 && !!values.policy,\n \"Usage: outpost recovery prune --policy FILE [--repository PATH] [--apply] [--json]\",\n );\n for (const key of Object.keys(values))\n invariant(\n [\"policy\", \"repository\", \"apply\", \"json\"].includes(key),\n `Unsupported recovery prune option: --${key}`,\n );\n const policy: unknown = JSON.parse(\n (\n await readInspectionFile(\n resolve(values.policy),\n recoveryRetentionLimits.maxPolicyBytes,\n )\n ).toString(\"utf8\"),\n );\n retentionPolicy(policy);\n const plan = await planRecoveryRetention({\n policy,\n ...(values.repository ? { repository: values.repository } : {}),\n });\n const result = values.apply ? await pruneRecoveryRetention(plan) : undefined;\n const after = result?.after ?? plan;\n if (values.json)\n process.stdout.write(\n `${JSON.stringify({ dryRun: !values.apply, plan, ...(result ? { result } : {}) }, null, 2)}\\n`,\n );\n else {\n process.stdout.write(\n `Outpost retention ${values.apply ? \"apply\" : \"dry run\"} — ${JSON.stringify(plan.repository)}\\n`,\n );\n for (const entry of plan.entries)\n process.stdout.write(\n `${entry.eligible ? \"CANDIDATE\" : \"RETAIN\"} ${JSON.stringify(entry.path)} | ${entry.reason} | ${entry.bytes} bytes\\n`,\n );\n for (const path of result?.removed ?? [])\n process.stdout.write(`REMOVED ${JSON.stringify(path)}\\n`);\n for (const entry of result?.retained ?? [])\n process.stdout.write(\n `RETAIN ${JSON.stringify(entry.path)} | ${entry.reason}\\n`,\n );\n process.stdout.write(\n `Observed ${after.usageBytes} logical bytes; projected ${after.projectedBytes}; projected quota ${after.quota}. Branches and recovery artifacts are retained.\\n`,\n );\n }\n if (!after.complete || after.quota !== \"within\" || result?.retained.length)\n process.exitCode = 1;\n}\n"]}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { planRecoveryRestore, restoreRecoveryTransfer, } from "../application/recovery-restore.js";
|
|
2
|
+
import { invariant, positive } from "../domain/errors.js";
|
|
3
|
+
export async function recoveryRestoreCommand({ values, positionals, }) {
|
|
4
|
+
invariant(positionals.length === 2 &&
|
|
5
|
+
!!values.directory &&
|
|
6
|
+
!!values.repository &&
|
|
7
|
+
!!values.destination &&
|
|
8
|
+
(values.side === "previous" || values.side === "incoming"), "Usage: outpost recovery restore --directory TRANSFER_PATH --repository PATH --destination NEW_PATH --side previous|incoming [--max-bytes NUMBER] [--apply] [--json]");
|
|
9
|
+
for (const key of Object.keys(values))
|
|
10
|
+
invariant([
|
|
11
|
+
"directory",
|
|
12
|
+
"repository",
|
|
13
|
+
"destination",
|
|
14
|
+
"side",
|
|
15
|
+
"max-bytes",
|
|
16
|
+
"apply",
|
|
17
|
+
"json",
|
|
18
|
+
].includes(key), `Unsupported recovery restore option: --${key}`);
|
|
19
|
+
const plan = await planRecoveryRestore({
|
|
20
|
+
directory: values.directory,
|
|
21
|
+
repository: values.repository,
|
|
22
|
+
destination: values.destination,
|
|
23
|
+
side: values.side,
|
|
24
|
+
...(values["max-bytes"] === undefined
|
|
25
|
+
? {}
|
|
26
|
+
: { maxBytes: positive(Number(values["max-bytes"]), "max-bytes") }),
|
|
27
|
+
});
|
|
28
|
+
const result = values.apply ? await restoreRecoveryTransfer(plan) : plan;
|
|
29
|
+
if (values.json)
|
|
30
|
+
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
31
|
+
else
|
|
32
|
+
process.stdout.write(`${values.apply ? "Restored" : "Planned"} ${plan.side} recovery at ${JSON.stringify(plan.destination)}\nCommit: ${plan.commit}; staging: ${plan.staging}. Source retained.\n${values.apply ? "Review the detached checkout before explicitly integrating it.\n" : "No destination created. Use --apply to restore into this new directory.\n"}`);
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=recovery-restore-command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recovery-restore-command.js","sourceRoot":"","sources":["../../src/cli/recovery-restore-command.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAG1D,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,EAC3C,MAAM,EACN,WAAW,GACG;IACd,SAAS,CACP,WAAW,CAAC,MAAM,KAAK,CAAC;QACtB,CAAC,CAAC,MAAM,CAAC,SAAS;QAClB,CAAC,CAAC,MAAM,CAAC,UAAU;QACnB,CAAC,CAAC,MAAM,CAAC,WAAW;QACpB,CAAC,MAAM,CAAC,IAAI,KAAK,UAAU,IAAI,MAAM,CAAC,IAAI,KAAK,UAAU,CAAC,EAC5D,qKAAqK,CACtK,CAAC;IACF,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;QACnC,SAAS,CACP;YACE,WAAW;YACX,YAAY;YACZ,aAAa;YACb,MAAM;YACN,WAAW;YACX,OAAO;YACP,MAAM;SACP,CAAC,QAAQ,CAAC,GAAG,CAAC,EACf,0CAA0C,GAAG,EAAE,CAChD,CAAC;IACJ,MAAM,IAAI,GAAG,MAAM,mBAAmB,CAAC;QACrC,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,SAAS;YACnC,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,EAAE,WAAW,CAAC,EAAE,CAAC;KACtE,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,uBAAuB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACzE,IAAI,MAAM,CAAC,IAAI;QAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;;QAE5E,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,IAAI,IAAI,CAAC,IAAI,gBAAgB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,aAAa,IAAI,CAAC,MAAM,cAAc,IAAI,CAAC,OAAO,uBAAuB,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,kEAAkE,CAAC,CAAC,CAAC,2EAA2E,EAAE,CAChV,CAAC;AACN,CAAC","sourcesContent":["import {\n planRecoveryRestore,\n restoreRecoveryTransfer,\n} from \"../application/recovery-restore.ts\";\nimport { invariant, positive } from \"../domain/errors.ts\";\nimport type { CliInvocation } from \"./main.types.ts\";\n\nexport async function recoveryRestoreCommand({\n values,\n positionals,\n}: CliInvocation): Promise<void> {\n invariant(\n positionals.length === 2 &&\n !!values.directory &&\n !!values.repository &&\n !!values.destination &&\n (values.side === \"previous\" || values.side === \"incoming\"),\n \"Usage: outpost recovery restore --directory TRANSFER_PATH --repository PATH --destination NEW_PATH --side previous|incoming [--max-bytes NUMBER] [--apply] [--json]\",\n );\n for (const key of Object.keys(values))\n invariant(\n [\n \"directory\",\n \"repository\",\n \"destination\",\n \"side\",\n \"max-bytes\",\n \"apply\",\n \"json\",\n ].includes(key),\n `Unsupported recovery restore option: --${key}`,\n );\n const plan = await planRecoveryRestore({\n directory: values.directory,\n repository: values.repository,\n destination: values.destination,\n side: values.side,\n ...(values[\"max-bytes\"] === undefined\n ? {}\n : { maxBytes: positive(Number(values[\"max-bytes\"]), \"max-bytes\") }),\n });\n const result = values.apply ? await restoreRecoveryTransfer(plan) : plan;\n if (values.json) process.stdout.write(`${JSON.stringify(result, null, 2)}\\n`);\n else\n process.stdout.write(\n `${values.apply ? \"Restored\" : \"Planned\"} ${plan.side} recovery at ${JSON.stringify(plan.destination)}\\nCommit: ${plan.commit}; staging: ${plan.staging}. Source retained.\\n${values.apply ? \"Review the detached checkout before explicitly integrating it.\\n\" : \"No destination created. Use --apply to restore into this new directory.\\n\"}`,\n );\n}\n"]}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { verifyRecoveryTransfer } from "../application/recovery-verification.js";
|
|
2
|
+
import { invariant, positive } from "../domain/errors.js";
|
|
3
|
+
export async function recoveryVerifyCommand({ values, positionals, }) {
|
|
4
|
+
invariant(positionals.length === 2 && !!values.directory, "Usage: outpost recovery verify --directory TRANSFER_PATH [--checksums] [--max-bytes NUMBER] [--restorability --repository PATH] [--json]");
|
|
5
|
+
for (const key of Object.keys(values))
|
|
6
|
+
invariant([
|
|
7
|
+
"directory",
|
|
8
|
+
"checksums",
|
|
9
|
+
"max-bytes",
|
|
10
|
+
"json",
|
|
11
|
+
"restorability",
|
|
12
|
+
"repository",
|
|
13
|
+
].includes(key), `Unsupported recovery verify option: --${key}`);
|
|
14
|
+
invariant(values["max-bytes"] === undefined || values.checksums, "--max-bytes requires --checksums");
|
|
15
|
+
invariant(!values.repository || values.restorability, "--repository requires --restorability");
|
|
16
|
+
const report = await verifyRecoveryTransfer(values.directory, {
|
|
17
|
+
...(values.restorability ? { restorability: true } : {}),
|
|
18
|
+
...(values.repository ? { repository: values.repository } : {}),
|
|
19
|
+
...(values.checksums ? { checksums: true } : {}),
|
|
20
|
+
...(values["max-bytes"] !== undefined
|
|
21
|
+
? { maxBytes: positive(Number(values["max-bytes"]), "max-bytes") }
|
|
22
|
+
: {}),
|
|
23
|
+
});
|
|
24
|
+
if (values.json)
|
|
25
|
+
process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
|
|
26
|
+
else {
|
|
27
|
+
process.stdout.write(`Outpost recovery structure verification — ${JSON.stringify(report.directory)}\n`);
|
|
28
|
+
for (const check of report.checks)
|
|
29
|
+
process.stdout.write(`[${check.status.toUpperCase()}] ${check.code}: ${JSON.stringify(check.path)}\n`);
|
|
30
|
+
process.stdout.write(`${report.complete ? "Requested transfer checks passed." : "Transfer checks failed or are incomplete."}\n`);
|
|
31
|
+
if (values.restorability)
|
|
32
|
+
process.stdout.write("Restorability scope: commit objects, bundle validity and three transfer patches applied independently in a temporary clone. Payload restoration, original staging/worktree consistency, session patches, submodules and external dependencies are outside this scope. Target repository unchanged.\n");
|
|
33
|
+
if (values.checksums) {
|
|
34
|
+
process.stdout.write(`Checksums: ${report.integrity}; ${report.checksums?.bytesChecked ?? 0} bytes checked.\n`);
|
|
35
|
+
process.stdout.write("Checksums compare against an unsigned manifest. Activity and full restoration remain unverified. No files were changed.\n");
|
|
36
|
+
}
|
|
37
|
+
if (!values.checksums && !values.restorability)
|
|
38
|
+
process.stdout.write("Patch and bundle contents, commit availability, activity and restorability are unverified. No files were changed.\n");
|
|
39
|
+
}
|
|
40
|
+
if (!report.complete)
|
|
41
|
+
process.exitCode = 1;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=recovery-verify-command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recovery-verify-command.js","sourceRoot":"","sources":["../../src/cli/recovery-verify-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,yCAAyC,CAAC;AACjF,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAG1D,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,EAC1C,MAAM,EACN,WAAW,GACG;IACd,SAAS,CACP,WAAW,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,SAAS,EAC9C,0IAA0I,CAC3I,CAAC;IACF,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;QACnC,SAAS,CACP;YACE,WAAW;YACX,WAAW;YACX,WAAW;YACX,MAAM;YACN,eAAe;YACf,YAAY;SACb,CAAC,QAAQ,CAAC,GAAG,CAAC,EACf,yCAAyC,GAAG,EAAE,CAC/C,CAAC;IACJ,SAAS,CACP,MAAM,CAAC,WAAW,CAAC,KAAK,SAAS,IAAI,MAAM,CAAC,SAAS,EACrD,kCAAkC,CACnC,CAAC;IACF,SAAS,CACP,CAAC,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,aAAa,EAC1C,uCAAuC,CACxC,CAAC;IACF,MAAM,MAAM,GAAG,MAAM,sBAAsB,CAAC,MAAM,CAAC,SAAS,EAAE;QAC5D,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxD,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/D,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChD,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,SAAS;YACnC,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,EAAE,WAAW,CAAC,EAAE;YAClE,CAAC,CAAC,EAAE,CAAC;KACR,CAAC,CAAC;IACH,IAAI,MAAM,CAAC,IAAI;QAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;SACzE,CAAC;QACJ,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,6CAA6C,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAClF,CAAC;QACF,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM;YAC/B,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,IAAI,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CACjF,CAAC;QACJ,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,mCAAmC,CAAC,CAAC,CAAC,2CAA2C,IAAI,CAC3G,CAAC;QACF,IAAI,MAAM,CAAC,aAAa;YACtB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,sSAAsS,CACvS,CAAC;QACJ,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;YACrB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,cAAc,MAAM,CAAC,SAAS,KAAK,MAAM,CAAC,SAAS,EAAE,YAAY,IAAI,CAAC,mBAAmB,CAC1F,CAAC;YACF,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,2HAA2H,CAC5H,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,SAAS,IAAI,CAAC,MAAM,CAAC,aAAa;YAC5C,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,qHAAqH,CACtH,CAAC;IACN,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,QAAQ;QAAE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AAC7C,CAAC","sourcesContent":["import { verifyRecoveryTransfer } from \"../application/recovery-verification.ts\";\nimport { invariant, positive } from \"../domain/errors.ts\";\nimport type { CliInvocation } from \"./main.types.ts\";\n\nexport async function recoveryVerifyCommand({\n values,\n positionals,\n}: CliInvocation): Promise<void> {\n invariant(\n positionals.length === 2 && !!values.directory,\n \"Usage: outpost recovery verify --directory TRANSFER_PATH [--checksums] [--max-bytes NUMBER] [--restorability --repository PATH] [--json]\",\n );\n for (const key of Object.keys(values))\n invariant(\n [\n \"directory\",\n \"checksums\",\n \"max-bytes\",\n \"json\",\n \"restorability\",\n \"repository\",\n ].includes(key),\n `Unsupported recovery verify option: --${key}`,\n );\n invariant(\n values[\"max-bytes\"] === undefined || values.checksums,\n \"--max-bytes requires --checksums\",\n );\n invariant(\n !values.repository || values.restorability,\n \"--repository requires --restorability\",\n );\n const report = await verifyRecoveryTransfer(values.directory, {\n ...(values.restorability ? { restorability: true } : {}),\n ...(values.repository ? { repository: values.repository } : {}),\n ...(values.checksums ? { checksums: true } : {}),\n ...(values[\"max-bytes\"] !== undefined\n ? { maxBytes: positive(Number(values[\"max-bytes\"]), \"max-bytes\") }\n : {}),\n });\n if (values.json) process.stdout.write(`${JSON.stringify(report, null, 2)}\\n`);\n else {\n process.stdout.write(\n `Outpost recovery structure verification — ${JSON.stringify(report.directory)}\\n`,\n );\n for (const check of report.checks)\n process.stdout.write(\n `[${check.status.toUpperCase()}] ${check.code}: ${JSON.stringify(check.path)}\\n`,\n );\n process.stdout.write(\n `${report.complete ? \"Requested transfer checks passed.\" : \"Transfer checks failed or are incomplete.\"}\\n`,\n );\n if (values.restorability)\n process.stdout.write(\n \"Restorability scope: commit objects, bundle validity and three transfer patches applied independently in a temporary clone. Payload restoration, original staging/worktree consistency, session patches, submodules and external dependencies are outside this scope. Target repository unchanged.\\n\",\n );\n if (values.checksums) {\n process.stdout.write(\n `Checksums: ${report.integrity}; ${report.checksums?.bytesChecked ?? 0} bytes checked.\\n`,\n );\n process.stdout.write(\n \"Checksums compare against an unsigned manifest. Activity and full restoration remain unverified. No files were changed.\\n\",\n );\n }\n if (!values.checksums && !values.restorability)\n process.stdout.write(\n \"Patch and bundle contents, commit availability, activity and restorability are unverified. No files were changed.\\n\",\n );\n }\n if (!report.complete) process.exitCode = 1;\n}\n"]}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { readFile } from "node:fs/promises";
|
|
2
|
-
import { imageRecipe, providerPackages } from "./scaffold.constants.js";
|
|
2
|
+
import { agentEnvironment, imageRecipe, providerPackages, } from "./scaffold.constants.js";
|
|
3
3
|
import { starter } from "./starters.js";
|
|
4
4
|
export async function scaffoldFiles(options, hasPackage, extension) {
|
|
5
5
|
const agent = options.agent ?? "codex", provider = options.provider ?? "docker";
|
|
6
6
|
const files = {
|
|
7
7
|
[`run.${extension}`]: starter(options),
|
|
8
8
|
"brief.md": "Objective: {{OBJECTIVE}}\n\nWork on {{WORK_BRANCH}} from {{BASE_BRANCH}}. Inspect the repository, implement the objective, run relevant tests and commit your changes. When finished, write <outpost>done</outpost>.\n",
|
|
9
|
-
".env.example": agent
|
|
9
|
+
".env.example": agentEnvironment[agent],
|
|
10
10
|
".gitignore": "node_modules/\n.env\n.outpost/workspaces/\n.outpost/locks/\n.outpost/recovery/\n.outpost/logs/\n",
|
|
11
11
|
};
|
|
12
12
|
if (provider === "docker" || provider === "podman")
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scaffold-files.js","sourceRoot":"","sources":["../../src/cli/scaffold-files.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,
|
|
1
|
+
{"version":3,"file":"scaffold-files.js","sourceRoot":"","sources":["../../src/cli/scaffold-files.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EACL,gBAAgB,EAChB,WAAW,EACX,gBAAgB,GACjB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,OAAoB,EACpB,UAAmB,EACnB,SAAuB;IAEvB,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,OAAO,EACpC,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,QAAQ,CAAC;IAC1C,MAAM,KAAK,GAA2B;QACpC,CAAC,OAAO,SAAS,EAAE,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC;QACtC,UAAU,EACR,wNAAwN;QAC1N,cAAc,EAAE,gBAAgB,CAAC,KAAK,CAAC;QACvC,YAAY,EACV,kGAAkG;KACrG,CAAC;IACF,IAAI,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,QAAQ;QAChD,KAAK,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,eAAe,CAAC,GAAG,WAAW,CAAC;IAE9E,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CACzB,MAAM,QAAQ,CAAC,IAAI,GAAG,CAAC,oBAAoB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CACvE,CAAC;QACF,KAAK,CAAC,cAAc,CAAC;YACnB,IAAI,CAAC,SAAS,CACZ;gBACE,OAAO,EAAE,IAAI;gBACb,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,EAAE,KAAK,EAAE,YAAY,SAAS,EAAE,EAAE;gBAC3C,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE;gBACzB,eAAe,EAAE;oBACf,sBAAsB,EAAE,IAAI,QAAQ,CAAC,OAAO,EAAE;oBAC9C,GAAG,MAAM,CAAC,WAAW,CACnB,gBAAgB,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;wBACvC,IAAI;wBACJ,QAAQ,CAAC,gBAAgB,CAAC,IAAI,CAAC;qBAChC,CAAC,CACH;iBACF;aACF,EACD,IAAI,EACJ,CAAC,CACF,GAAG,IAAI,CAAC;IACb,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC","sourcesContent":["import { readFile } from \"node:fs/promises\";\nimport {\n agentEnvironment,\n imageRecipe,\n providerPackages,\n} from \"./scaffold.constants.ts\";\nimport type { InitOptions } from \"./scaffold.types.ts\";\nimport { starter } from \"./starters.ts\";\n\nexport async function scaffoldFiles(\n options: InitOptions,\n hasPackage: boolean,\n extension: \"ts\" | \"mts\",\n): Promise<Record<string, string>> {\n const agent = options.agent ?? \"codex\",\n provider = options.provider ?? \"docker\";\n const files: Record<string, string> = {\n [`run.${extension}`]: starter(options),\n \"brief.md\":\n \"Objective: {{OBJECTIVE}}\\n\\nWork on {{WORK_BRANCH}} from {{BASE_BRANCH}}. Inspect the repository, implement the objective, run relevant tests and commit your changes. When finished, write <outpost>done</outpost>.\\n\",\n \".env.example\": agentEnvironment[agent],\n \".gitignore\":\n \"node_modules/\\n.env\\n.outpost/workspaces/\\n.outpost/locks/\\n.outpost/recovery/\\n.outpost/logs/\\n\",\n };\n if (provider === \"docker\" || provider === \"podman\")\n files[provider === \"docker\" ? \"Dockerfile\" : \"Containerfile\"] = imageRecipe;\n\n if (!hasPackage) {\n const manifest = JSON.parse(\n await readFile(new URL(\"../../package.json\", import.meta.url), \"utf8\"),\n );\n files[\"package.json\"] =\n JSON.stringify(\n {\n private: true,\n type: \"module\",\n scripts: { start: `node run.${extension}` },\n engines: { node: \">=24\" },\n devDependencies: {\n \"@elie-laloum/outpost\": `^${manifest.version}`,\n ...Object.fromEntries(\n providerPackages[provider].map((name) => [\n name,\n manifest.peerDependencies[name],\n ]),\n ),\n },\n },\n null,\n 2,\n ) + \"\\n\";\n }\n return files;\n}\n"]}
|
|
@@ -2,7 +2,7 @@ import { invariant } from "../domain/errors.js";
|
|
|
2
2
|
import { supportedAgents, supportedProviders } from "./scaffold.constants.js";
|
|
3
3
|
export function validateInitialization(options) {
|
|
4
4
|
const agent = options.agent ?? "codex", provider = options.provider ?? "docker";
|
|
5
|
-
invariant(supportedAgents.includes(agent), "Choose codex or
|
|
5
|
+
invariant(supportedAgents.includes(agent), "Choose codex, claude or gemini");
|
|
6
6
|
invariant(supportedProviders.includes(provider), "Unknown sandbox provider");
|
|
7
7
|
}
|
|
8
8
|
//# sourceMappingURL=scaffold-validation.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scaffold-validation.js","sourceRoot":"","sources":["../../src/cli/scaffold-validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAG9E,MAAM,UAAU,sBAAsB,CAAC,OAAoB;IACzD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,OAAO,EACpC,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,QAAQ,CAAC;IAC1C,SAAS,CAAC,eAAe,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,
|
|
1
|
+
{"version":3,"file":"scaffold-validation.js","sourceRoot":"","sources":["../../src/cli/scaffold-validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAG9E,MAAM,UAAU,sBAAsB,CAAC,OAAoB;IACzD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,OAAO,EACpC,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,QAAQ,CAAC;IAC1C,SAAS,CAAC,eAAe,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,gCAAgC,CAAC,CAAC;IAC7E,SAAS,CAAC,kBAAkB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,0BAA0B,CAAC,CAAC;AAC/E,CAAC","sourcesContent":["import { invariant } from \"../domain/errors.ts\";\nimport { supportedAgents, supportedProviders } from \"./scaffold.constants.ts\";\nimport type { InitOptions } from \"./scaffold.types.ts\";\n\nexport function validateInitialization(options: InitOptions): void {\n const agent = options.agent ?? \"codex\",\n provider = options.provider ?? \"docker\";\n invariant(supportedAgents.includes(agent), \"Choose codex, claude or gemini\");\n invariant(supportedProviders.includes(provider), \"Unknown sandbox provider\");\n}\n"]}
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
export declare const imageRecipe: string;
|
|
2
|
+
export declare const agentEnvironment: {
|
|
3
|
+
readonly codex: "OPENAI_API_KEY=\n";
|
|
4
|
+
readonly claude: "ANTHROPIC_API_KEY=\n";
|
|
5
|
+
readonly gemini: "GEMINI_API_KEY=\n";
|
|
6
|
+
};
|
|
2
7
|
export declare const supportedAgents: readonly string[];
|
|
3
8
|
export declare const supportedProviders: readonly string[];
|
|
4
9
|
export declare const supportedManagers: readonly string[];
|
|
@@ -3,14 +3,19 @@ export const imageRecipe = `FROM node:24-bookworm-slim
|
|
|
3
3
|
ARG AGENT_UID=1000
|
|
4
4
|
ARG AGENT_GID=1000
|
|
5
5
|
RUN apt-get update && apt-get install -y --no-install-recommends git openssh-client ca-certificates curl procps util-linux python3 && rm -rf /var/lib/apt/lists/*
|
|
6
|
-
RUN npm install -g --allow-scripts=@anthropic-ai/claude-code @openai/codex@${agentVersions.codex} @anthropic-ai/claude-code@${agentVersions.claude}
|
|
6
|
+
RUN npm install -g --allow-scripts=@anthropic-ai/claude-code @openai/codex@${agentVersions.codex} @anthropic-ai/claude-code@${agentVersions.claude} @google/gemini-cli@${agentVersions.gemini}
|
|
7
7
|
RUN groupmod -o -g "$AGENT_GID" node && usermod -o -u "$AGENT_UID" -g "$AGENT_GID" node
|
|
8
8
|
RUN mkdir -p /home/agent && chown "$AGENT_UID:$AGENT_GID" /home/agent && chmod 700 /home/agent
|
|
9
9
|
ENV HOME=/home/agent
|
|
10
10
|
USER $AGENT_UID:$AGENT_GID
|
|
11
11
|
WORKDIR /workspace
|
|
12
12
|
`;
|
|
13
|
-
export const
|
|
13
|
+
export const agentEnvironment = {
|
|
14
|
+
codex: "OPENAI_API_KEY=\n",
|
|
15
|
+
claude: "ANTHROPIC_API_KEY=\n",
|
|
16
|
+
gemini: "GEMINI_API_KEY=\n",
|
|
17
|
+
};
|
|
18
|
+
export const supportedAgents = ["codex", "claude", "gemini"];
|
|
14
19
|
export const supportedProviders = [
|
|
15
20
|
"docker",
|
|
16
21
|
"podman",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scaffold.constants.js","sourceRoot":"","sources":["../../src/cli/scaffold.constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEzD,MAAM,CAAC,MAAM,WAAW,GAAG;;;;6EAIkD,aAAa,CAAC,KAAK,8BAA8B,aAAa,CAAC,MAAM;;;;;;
|
|
1
|
+
{"version":3,"file":"scaffold.constants.js","sourceRoot":"","sources":["../../src/cli/scaffold.constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEzD,MAAM,CAAC,MAAM,WAAW,GAAG;;;;6EAIkD,aAAa,CAAC,KAAK,8BAA8B,aAAa,CAAC,MAAM,uBAAuB,aAAa,CAAC,MAAM;;;;;;CAM5L,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,KAAK,EAAE,mBAAmB;IAC1B,MAAM,EAAE,sBAAsB;IAC9B,MAAM,EAAE,mBAAmB;CACnB,CAAC;AAEX,MAAM,CAAC,MAAM,eAAe,GAAsB,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAChF,MAAM,CAAC,MAAM,kBAAkB,GAAsB;IACnD,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,SAAS;IACT,OAAO;CACR,CAAC;AACF,MAAM,CAAC,MAAM,iBAAiB,GAAsB;IAClD,KAAK;IACL,MAAM;IACN,MAAM;IACN,KAAK;CACN,CAAC;AACF,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAC1B,CAAC,WAAW,EAAE,MAAM,CAAC;IACrB,CAAC,UAAU,EAAE,KAAK,CAAC;IACnB,CAAC,WAAW,EAAE,KAAK,CAAC;CACZ,CAAC;AACX,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,MAAM,EAAE,EAAE;IACV,MAAM,EAAE,EAAE;IACV,KAAK,EAAE,EAAE;IACT,MAAM,EAAE,CAAC,iBAAiB,CAAC;IAC3B,OAAO,EAAE,CAAC,cAAc,CAAC;CACjB,CAAC","sourcesContent":["import { agentVersions } from \"../providers/versions.ts\";\n\nexport const imageRecipe = `FROM node:24-bookworm-slim\nARG AGENT_UID=1000\nARG AGENT_GID=1000\nRUN apt-get update && apt-get install -y --no-install-recommends git openssh-client ca-certificates curl procps util-linux python3 && rm -rf /var/lib/apt/lists/*\nRUN npm install -g --allow-scripts=@anthropic-ai/claude-code @openai/codex@${agentVersions.codex} @anthropic-ai/claude-code@${agentVersions.claude} @google/gemini-cli@${agentVersions.gemini}\nRUN groupmod -o -g \"$AGENT_GID\" node && usermod -o -u \"$AGENT_UID\" -g \"$AGENT_GID\" node\nRUN mkdir -p /home/agent && chown \"$AGENT_UID:$AGENT_GID\" /home/agent && chmod 700 /home/agent\nENV HOME=/home/agent\nUSER $AGENT_UID:$AGENT_GID\nWORKDIR /workspace\n`;\n\nexport const agentEnvironment = {\n codex: \"OPENAI_API_KEY=\\n\",\n claude: \"ANTHROPIC_API_KEY=\\n\",\n gemini: \"GEMINI_API_KEY=\\n\",\n} as const;\n\nexport const supportedAgents: readonly string[] = [\"codex\", \"claude\", \"gemini\"];\nexport const supportedProviders: readonly string[] = [\n \"docker\",\n \"podman\",\n \"vercel\",\n \"daytona\",\n \"local\",\n];\nexport const supportedManagers: readonly string[] = [\n \"npm\",\n \"pnpm\",\n \"yarn\",\n \"bun\",\n];\nexport const managerLocks = [\n [\"pnpm-lock.yaml\", \"pnpm\"],\n [\"yarn.lock\", \"yarn\"],\n [\"bun.lock\", \"bun\"],\n [\"bun.lockb\", \"bun\"],\n] as const;\nexport const providerPackages = {\n docker: [],\n podman: [],\n local: [],\n vercel: [\"@vercel/sandbox\"],\n daytona: [\"@daytona/sdk\"],\n} as const;\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export interface InitOptions {
|
|
2
2
|
readonly directory?: string;
|
|
3
3
|
readonly repository?: string;
|
|
4
|
-
readonly agent?: "claude" | "codex";
|
|
4
|
+
readonly agent?: "claude" | "codex" | "gemini";
|
|
5
5
|
readonly provider?: "docker" | "podman" | "vercel" | "daytona" | "local";
|
|
6
6
|
readonly manager?: "npm" | "pnpm" | "yarn" | "bun";
|
|
7
7
|
readonly model?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scaffold.types.js","sourceRoot":"","sources":["../../src/cli/scaffold.types.ts"],"names":[],"mappings":"","sourcesContent":["export interface InitOptions {\n readonly directory?: string;\n readonly repository?: string;\n readonly agent?: \"claude\" | \"codex\";\n readonly provider?: \"docker\" | \"podman\" | \"vercel\" | \"daytona\" | \"local\";\n readonly manager?: \"npm\" | \"pnpm\" | \"yarn\" | \"bun\";\n readonly model?: string;\n readonly install?: boolean;\n readonly build?: boolean;\n readonly image?: string;\n}\n\nexport interface PackageManifest {\n readonly type?: string;\n readonly packageManager?: string;\n}\nexport interface ProjectSettings {\n readonly extension: \"ts\" | \"mts\";\n readonly hasPackage: boolean;\n readonly manager: string;\n}\nexport interface ScaffoldResult {\n files: readonly string[];\n run: string;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"scaffold.types.js","sourceRoot":"","sources":["../../src/cli/scaffold.types.ts"],"names":[],"mappings":"","sourcesContent":["export interface InitOptions {\n readonly directory?: string;\n readonly repository?: string;\n readonly agent?: \"claude\" | \"codex\" | \"gemini\";\n readonly provider?: \"docker\" | \"podman\" | \"vercel\" | \"daytona\" | \"local\";\n readonly manager?: \"npm\" | \"pnpm\" | \"yarn\" | \"bun\";\n readonly model?: string;\n readonly install?: boolean;\n readonly build?: boolean;\n readonly image?: string;\n}\n\nexport interface PackageManifest {\n readonly type?: string;\n readonly packageManager?: string;\n}\nexport interface ProjectSettings {\n readonly extension: \"ts\" | \"mts\";\n readonly hasPackage: boolean;\n readonly manager: string;\n}\nexport interface ScaffoldResult {\n files: readonly string[];\n run: string;\n}\n"]}
|
|
@@ -67,6 +67,8 @@ export interface AgentInput {
|
|
|
67
67
|
}
|
|
68
68
|
export interface AgentAdapter {
|
|
69
69
|
readonly name: string;
|
|
70
|
+
readonly bootstrap?: string;
|
|
71
|
+
readonly requiresFinishedEvent?: boolean;
|
|
70
72
|
readonly variables?: Variables;
|
|
71
73
|
readonly conversations?: "claude" | "codex";
|
|
72
74
|
readonly storage?: ConversationStore;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.types.js","sourceRoot":"","sources":["../../src/domain/agent.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { Command, Variables } from \"./command.types.ts\";\nimport type { ConversationStore } from \"./conversation.types.ts\";\n\nexport interface Usage {\n readonly input: number;\n readonly cached: number;\n readonly cacheCreated?: number;\n readonly output: number;\n}\n\nexport type AgentEvent =\n | {\n readonly kind: \"phase\";\n readonly name: string;\n readonly agent?: string;\n readonly branch?: string;\n readonly directory?: string;\n }\n | {\n readonly kind: \"summary\";\n readonly durationMs: number;\n readonly status: number;\n readonly tokens: Usage;\n }\n | { readonly kind: \"warning\"; readonly message: string }\n | { readonly kind: \"text\"; readonly text: string }\n | { readonly kind: \"result\"; readonly text: string }\n | { readonly kind: \"prompt\"; readonly text: string }\n | { readonly kind: \"tool\"; readonly name: string; readonly input: unknown }\n | { readonly kind: \"conversation\"; readonly id: string }\n | { readonly kind: \"usage\"; readonly tokens: Usage }\n | { readonly kind: \"failure\"; readonly message: string }\n | { readonly kind: \"finished\" }\n | { readonly kind: \"raw\"; readonly value: unknown };\n\nexport type AgentObservation = AgentEvent & {\n readonly pass: number;\n readonly at: string;\n};\n\nexport type AgentEventHandlers = {\n readonly [Kind in AgentEvent[\"kind\"]]?: (\n event: Extract<AgentEvent, { kind: Kind }>,\n ) => void;\n};\n\nexport interface AgentInput {\n readonly text?: string;\n readonly interactive?: boolean;\n readonly continuation?: { readonly id: string; readonly fork?: boolean };\n}\n\nexport interface AgentAdapter {\n readonly name: string;\n readonly variables?: Variables;\n readonly conversations?: \"claude\" | \"codex\";\n readonly storage?: ConversationStore;\n readonly capture?: boolean;\n readonly resumable?: boolean;\n transcriptUsage?(text: string): Usage | undefined;\n request(input: AgentInput): Command;\n events(line: string): readonly AgentEvent[];\n}\n\nexport interface RequiredAgent {\n readonly agent: AgentAdapter;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"agent.types.js","sourceRoot":"","sources":["../../src/domain/agent.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { Command, Variables } from \"./command.types.ts\";\nimport type { ConversationStore } from \"./conversation.types.ts\";\n\nexport interface Usage {\n readonly input: number;\n readonly cached: number;\n readonly cacheCreated?: number;\n readonly output: number;\n}\n\nexport type AgentEvent =\n | {\n readonly kind: \"phase\";\n readonly name: string;\n readonly agent?: string;\n readonly branch?: string;\n readonly directory?: string;\n }\n | {\n readonly kind: \"summary\";\n readonly durationMs: number;\n readonly status: number;\n readonly tokens: Usage;\n }\n | { readonly kind: \"warning\"; readonly message: string }\n | { readonly kind: \"text\"; readonly text: string }\n | { readonly kind: \"result\"; readonly text: string }\n | { readonly kind: \"prompt\"; readonly text: string }\n | { readonly kind: \"tool\"; readonly name: string; readonly input: unknown }\n | { readonly kind: \"conversation\"; readonly id: string }\n | { readonly kind: \"usage\"; readonly tokens: Usage }\n | { readonly kind: \"failure\"; readonly message: string }\n | { readonly kind: \"finished\" }\n | { readonly kind: \"raw\"; readonly value: unknown };\n\nexport type AgentObservation = AgentEvent & {\n readonly pass: number;\n readonly at: string;\n};\n\nexport type AgentEventHandlers = {\n readonly [Kind in AgentEvent[\"kind\"]]?: (\n event: Extract<AgentEvent, { kind: Kind }>,\n ) => void;\n};\n\nexport interface AgentInput {\n readonly text?: string;\n readonly interactive?: boolean;\n readonly continuation?: { readonly id: string; readonly fork?: boolean };\n}\n\nexport interface AgentAdapter {\n readonly name: string;\n readonly bootstrap?: string;\n readonly requiresFinishedEvent?: boolean;\n readonly variables?: Variables;\n readonly conversations?: \"claude\" | \"codex\";\n readonly storage?: ConversationStore;\n readonly capture?: boolean;\n readonly resumable?: boolean;\n transcriptUsage?(text: string): Usage | undefined;\n request(input: AgentInput): Command;\n events(line: string): readonly AgentEvent[];\n}\n\nexport interface RequiredAgent {\n readonly agent: AgentAdapter;\n}\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ArtifactReference } from "./artifact.types.ts";
|
|
2
|
+
export declare function artifactDigest(bytes: Uint8Array | string): string;
|
|
3
|
+
export declare function artifactId(reference: Omit<ArtifactReference, "id">): string;
|
|
4
|
+
export declare function validateArtifactReference(value: unknown): ArtifactReference;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { artifactDigestPattern, artifactLabelMaxLength, } from "./artifact.constants.js";
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
export function artifactDigest(bytes) {
|
|
4
|
+
return createHash("sha256").update(bytes).digest("hex");
|
|
5
|
+
}
|
|
6
|
+
export function artifactId(reference) {
|
|
7
|
+
return artifactDigest(JSON.stringify([
|
|
8
|
+
reference.format,
|
|
9
|
+
reference.digest,
|
|
10
|
+
reference.size,
|
|
11
|
+
reference.contract.name,
|
|
12
|
+
reference.contract.version,
|
|
13
|
+
reference.contract.encoding,
|
|
14
|
+
reference.producer.executionId,
|
|
15
|
+
reference.producer.taskKey,
|
|
16
|
+
reference.producer.attempt,
|
|
17
|
+
reference.parents,
|
|
18
|
+
]));
|
|
19
|
+
}
|
|
20
|
+
export function validateArtifactReference(value) {
|
|
21
|
+
const invalid = () => new Error("Invalid artifact reference or lineage");
|
|
22
|
+
if (!value ||
|
|
23
|
+
typeof value !== "object" ||
|
|
24
|
+
!("format" in value) ||
|
|
25
|
+
value.format !== 1 ||
|
|
26
|
+
!("id" in value) ||
|
|
27
|
+
!digest(value.id) ||
|
|
28
|
+
!("digest" in value) ||
|
|
29
|
+
!digest(value.digest) ||
|
|
30
|
+
!("size" in value) ||
|
|
31
|
+
typeof value.size !== "number" ||
|
|
32
|
+
!Number.isSafeInteger(value.size) ||
|
|
33
|
+
value.size < 0 ||
|
|
34
|
+
!("contract" in value) ||
|
|
35
|
+
!value.contract ||
|
|
36
|
+
typeof value.contract !== "object" ||
|
|
37
|
+
!("producer" in value) ||
|
|
38
|
+
!value.producer ||
|
|
39
|
+
typeof value.producer !== "object" ||
|
|
40
|
+
!("parents" in value) ||
|
|
41
|
+
!Array.isArray(value.parents) ||
|
|
42
|
+
!value.parents.every(digest) ||
|
|
43
|
+
new Set(value.parents).size !== value.parents.length)
|
|
44
|
+
throw invalid();
|
|
45
|
+
const contract = value.contract, producer = value.producer;
|
|
46
|
+
if (!("name" in contract) ||
|
|
47
|
+
!label(contract.name) ||
|
|
48
|
+
!("version" in contract) ||
|
|
49
|
+
!label(contract.version) ||
|
|
50
|
+
!("encoding" in contract) ||
|
|
51
|
+
(contract.encoding !== "json" && contract.encoding !== "binary") ||
|
|
52
|
+
!("executionId" in producer) ||
|
|
53
|
+
!label(producer.executionId) ||
|
|
54
|
+
!("taskKey" in producer) ||
|
|
55
|
+
!label(producer.taskKey) ||
|
|
56
|
+
!("attempt" in producer) ||
|
|
57
|
+
typeof producer.attempt !== "number" ||
|
|
58
|
+
!Number.isSafeInteger(producer.attempt) ||
|
|
59
|
+
producer.attempt < 1)
|
|
60
|
+
throw invalid();
|
|
61
|
+
const reference = Object.freeze({
|
|
62
|
+
format: 1,
|
|
63
|
+
id: value.id,
|
|
64
|
+
digest: value.digest,
|
|
65
|
+
size: value.size,
|
|
66
|
+
contract: Object.freeze({
|
|
67
|
+
name: contract.name,
|
|
68
|
+
version: contract.version,
|
|
69
|
+
encoding: contract.encoding,
|
|
70
|
+
}),
|
|
71
|
+
producer: Object.freeze({
|
|
72
|
+
executionId: producer.executionId,
|
|
73
|
+
taskKey: producer.taskKey,
|
|
74
|
+
attempt: producer.attempt,
|
|
75
|
+
}),
|
|
76
|
+
parents: Object.freeze([...value.parents]),
|
|
77
|
+
});
|
|
78
|
+
if (artifactId(reference) !== reference.id)
|
|
79
|
+
throw invalid();
|
|
80
|
+
return reference;
|
|
81
|
+
}
|
|
82
|
+
function digest(value) {
|
|
83
|
+
return typeof value === "string" && artifactDigestPattern.test(value);
|
|
84
|
+
}
|
|
85
|
+
function label(value) {
|
|
86
|
+
return (typeof value === "string" &&
|
|
87
|
+
value.trim().length > 0 &&
|
|
88
|
+
value.length <= artifactLabelMaxLength);
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=artifact-reference.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifact-reference.js","sourceRoot":"","sources":["../../src/domain/artifact-reference.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n artifactDigestPattern,\n artifactLabelMaxLength,\n} from \"./artifact.constants.ts\";\nimport { createHash } from \"node:crypto\";\nimport type { ArtifactReference } from \"./artifact.types.ts\";\n\nexport function artifactDigest(bytes: Uint8Array | string): string {\n return createHash(\"sha256\").update(bytes).digest(\"hex\");\n}\n\nexport function artifactId(reference: Omit<ArtifactReference, \"id\">): string {\n return artifactDigest(\n JSON.stringify([\n reference.format,\n reference.digest,\n reference.size,\n reference.contract.name,\n reference.contract.version,\n reference.contract.encoding,\n reference.producer.executionId,\n reference.producer.taskKey,\n reference.producer.attempt,\n reference.parents,\n ]),\n );\n}\n\nexport function validateArtifactReference(value: unknown): ArtifactReference {\n const invalid = () => new Error(\"Invalid artifact reference or lineage\");\n if (\n !value ||\n typeof value !== \"object\" ||\n !(\"format\" in value) ||\n value.format !== 1 ||\n !(\"id\" in value) ||\n !digest(value.id) ||\n !(\"digest\" in value) ||\n !digest(value.digest) ||\n !(\"size\" in value) ||\n typeof value.size !== \"number\" ||\n !Number.isSafeInteger(value.size) ||\n value.size < 0 ||\n !(\"contract\" in value) ||\n !value.contract ||\n typeof value.contract !== \"object\" ||\n !(\"producer\" in value) ||\n !value.producer ||\n typeof value.producer !== \"object\" ||\n !(\"parents\" in value) ||\n !Array.isArray(value.parents) ||\n !value.parents.every(digest) ||\n new Set(value.parents).size !== value.parents.length\n )\n throw invalid();\n const contract = value.contract,\n producer = value.producer;\n if (\n !(\"name\" in contract) ||\n !label(contract.name) ||\n !(\"version\" in contract) ||\n !label(contract.version) ||\n !(\"encoding\" in contract) ||\n (contract.encoding !== \"json\" && contract.encoding !== \"binary\") ||\n !(\"executionId\" in producer) ||\n !label(producer.executionId) ||\n !(\"taskKey\" in producer) ||\n !label(producer.taskKey) ||\n !(\"attempt\" in producer) ||\n typeof producer.attempt !== \"number\" ||\n !Number.isSafeInteger(producer.attempt) ||\n producer.attempt < 1\n )\n throw invalid();\n const reference: ArtifactReference = Object.freeze({\n format: 1,\n id: value.id,\n digest: value.digest,\n size: value.size,\n contract: Object.freeze({\n name: contract.name,\n version: contract.version,\n encoding: contract.encoding,\n }),\n producer: Object.freeze({\n executionId: producer.executionId,\n taskKey: producer.taskKey,\n attempt: producer.attempt,\n }),\n parents: Object.freeze([...value.parents]),\n });\n if (artifactId(reference) !== reference.id) throw invalid();\n return reference;\n}\n\nfunction digest(value: unknown): value is string {\n return typeof value === \"string\" && artifactDigestPattern.test(value);\n}\n\nfunction label(value: unknown): value is string {\n return (\n typeof value === \"string\" &&\n value.trim().length > 0 &&\n value.length <= artifactLabelMaxLength\n );\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifact.constants.js","sourceRoot":"","sources":["../../src/domain/artifact.constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,CAAC;AAC3C,MAAM,CAAC,MAAM,qBAAqB,GAAG,gBAAgB,CAAC","sourcesContent":["export const artifactLabelMaxLength = 1024;\nexport const artifactDigestPattern = /^[a-f0-9]{64}$/;\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ArtifactContract, ArtifactContractOptions, ArtifactReference, ArtifactStore, JsonArtifactOptions, PublishArtifactOptions, ReadArtifactOptions } from "./artifact.types.ts";
|
|
2
|
+
export declare const artifact: {
|
|
3
|
+
json<T>(options: JsonArtifactOptions<T>): ArtifactContract<T>;
|
|
4
|
+
binary(options: ArtifactContractOptions): ArtifactContract<Uint8Array>;
|
|
5
|
+
};
|
|
6
|
+
export declare function publishArtifact<T>(store: ArtifactStore, contract: ArtifactContract<T>, value: T, options: PublishArtifactOptions): Promise<ArtifactReference>;
|
|
7
|
+
export declare function readStoredArtifact<T>(store: ArtifactStore, contract: ArtifactContract<T>, value: unknown, options?: ReadArtifactOptions): Promise<T>;
|