@elie-laloum/outpost 5.0.0 → 7.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 +54 -0
- package/README.md +11 -11
- package/SECURITY.md +10 -0
- package/dist/adapters/agents/antigravity-adapter.d.ts +3 -0
- package/dist/adapters/agents/antigravity-adapter.js +41 -0
- package/dist/adapters/agents/antigravity-adapter.js.map +1 -0
- package/dist/adapters/agents/antigravity-authentication.d.ts +2 -0
- package/dist/adapters/agents/antigravity-authentication.js +27 -0
- package/dist/adapters/agents/antigravity-authentication.js.map +1 -0
- package/dist/adapters/agents/antigravity-diagnostics.d.ts +1 -0
- package/dist/adapters/agents/antigravity-diagnostics.js +6 -0
- package/dist/adapters/agents/antigravity-diagnostics.js.map +1 -0
- package/dist/adapters/agents/antigravity-events.d.ts +2 -0
- package/dist/adapters/agents/antigravity-events.js +75 -0
- package/dist/adapters/agents/antigravity-events.js.map +1 -0
- package/dist/adapters/agents/antigravity-request.d.ts +5 -0
- package/dist/adapters/agents/antigravity-request.js +37 -0
- package/dist/adapters/agents/antigravity-request.js.map +1 -0
- package/dist/adapters/agents/antigravity.constants.d.ts +3 -0
- package/dist/adapters/agents/antigravity.constants.js +4 -0
- package/dist/adapters/agents/antigravity.constants.js.map +1 -0
- package/dist/adapters/agents/{gemini.types.d.ts → antigravity.types.d.ts} +2 -2
- package/dist/adapters/agents/antigravity.types.js +2 -0
- package/dist/adapters/agents/antigravity.types.js.map +1 -0
- package/dist/adapters/agents/authentication.constants.d.ts +19 -9
- package/dist/adapters/agents/authentication.constants.js +12 -9
- package/dist/adapters/agents/authentication.constants.js.map +1 -1
- package/dist/adapters/agents/authentication.d.ts +11 -2
- package/dist/adapters/agents/authentication.js +70 -47
- package/dist/adapters/agents/authentication.js.map +1 -1
- package/dist/adapters/agents/authentication.types.d.ts +20 -0
- package/dist/adapters/agents/authentication.types.js +2 -0
- package/dist/adapters/agents/authentication.types.js.map +1 -0
- package/dist/adapters/agents/claude-adapter.js +4 -2
- package/dist/adapters/agents/claude-adapter.js.map +1 -1
- package/dist/adapters/agents/claude-authentication.d.ts +2 -0
- package/dist/adapters/agents/claude-authentication.js +34 -0
- package/dist/adapters/agents/claude-authentication.js.map +1 -0
- package/dist/adapters/agents/claude-events.js +52 -9
- package/dist/adapters/agents/claude-events.js.map +1 -1
- package/dist/adapters/agents/claude-request.js +2 -0
- package/dist/adapters/agents/claude-request.js.map +1 -1
- package/dist/adapters/agents/cli-diagnostics.constants.d.ts +6 -6
- package/dist/adapters/agents/cli-diagnostics.constants.js +6 -6
- package/dist/adapters/agents/cli-diagnostics.constants.js.map +1 -1
- package/dist/adapters/agents/cli-diagnostics.d.ts +1 -0
- package/dist/adapters/agents/cli-diagnostics.js +18 -0
- package/dist/adapters/agents/cli-diagnostics.js.map +1 -1
- package/dist/adapters/agents/codex-adapter.js +4 -2
- package/dist/adapters/agents/codex-adapter.js.map +1 -1
- package/dist/adapters/agents/codex-authentication.d.ts +3 -0
- package/dist/adapters/agents/codex-authentication.js +47 -0
- package/dist/adapters/agents/codex-authentication.js.map +1 -0
- package/dist/adapters/agents/codex-events.js +28 -2
- package/dist/adapters/agents/codex-events.js.map +1 -1
- package/dist/adapters/agents/copilot-adapter.d.ts +3 -0
- package/dist/adapters/agents/copilot-adapter.js +45 -0
- package/dist/adapters/agents/copilot-adapter.js.map +1 -0
- package/dist/adapters/agents/copilot-authentication.d.ts +2 -0
- package/dist/adapters/agents/copilot-authentication.js +46 -0
- package/dist/adapters/agents/copilot-authentication.js.map +1 -0
- package/dist/adapters/agents/copilot-diagnostics.d.ts +1 -0
- package/dist/adapters/agents/copilot-diagnostics.js +6 -0
- package/dist/adapters/agents/copilot-diagnostics.js.map +1 -0
- package/dist/adapters/agents/copilot-events.d.ts +2 -0
- package/dist/adapters/agents/copilot-events.js +66 -0
- package/dist/adapters/agents/copilot-events.js.map +1 -0
- package/dist/adapters/agents/copilot-request.d.ts +5 -0
- package/dist/adapters/agents/copilot-request.js +24 -0
- package/dist/adapters/agents/copilot-request.js.map +1 -0
- package/dist/adapters/agents/copilot-usage.d.ts +3 -0
- package/dist/adapters/agents/copilot-usage.js +19 -0
- package/dist/adapters/agents/copilot-usage.js.map +1 -0
- package/dist/adapters/agents/copilot.types.d.ts +6 -0
- package/dist/adapters/agents/copilot.types.js +2 -0
- package/dist/adapters/agents/copilot.types.js.map +1 -0
- package/dist/adapters/agents/event-decoder.d.ts +2 -2
- package/dist/adapters/agents/event-decoder.js +6 -5
- package/dist/adapters/agents/event-decoder.js.map +1 -1
- package/dist/adapters/agents/kimi-adapter.d.ts +3 -0
- package/dist/adapters/agents/kimi-adapter.js +51 -0
- package/dist/adapters/agents/kimi-adapter.js.map +1 -0
- package/dist/adapters/agents/kimi-authentication.d.ts +3 -0
- package/dist/adapters/agents/kimi-authentication.js +63 -0
- package/dist/adapters/agents/kimi-authentication.js.map +1 -0
- package/dist/adapters/agents/kimi-diagnostics.d.ts +2 -0
- package/dist/adapters/agents/kimi-diagnostics.js +14 -0
- package/dist/adapters/agents/kimi-diagnostics.js.map +1 -0
- package/dist/adapters/agents/kimi-events.d.ts +2 -0
- package/dist/adapters/agents/kimi-events.js +55 -0
- package/dist/adapters/agents/kimi-events.js.map +1 -0
- package/dist/adapters/agents/kimi-fork.d.ts +2 -0
- package/dist/adapters/agents/kimi-fork.js +11 -0
- package/dist/adapters/agents/kimi-fork.js.map +1 -0
- package/dist/adapters/agents/{gemini-request.d.ts → kimi-request.d.ts} +2 -2
- package/dist/adapters/agents/kimi-request.js +33 -0
- package/dist/adapters/agents/kimi-request.js.map +1 -0
- package/dist/adapters/agents/kimi-usage.d.ts +2 -0
- package/dist/adapters/agents/kimi-usage.js +7 -0
- package/dist/adapters/agents/kimi-usage.js.map +1 -0
- package/dist/adapters/agents/kimi.constants.d.ts +13 -0
- package/dist/adapters/agents/kimi.constants.js +14 -0
- package/dist/adapters/agents/kimi.constants.js.map +1 -0
- package/dist/adapters/agents/kimi.types.d.ts +7 -0
- package/dist/adapters/agents/kimi.types.js +2 -0
- package/dist/adapters/agents/kimi.types.js.map +1 -0
- package/dist/adapters/agents/model-support.constants.d.ts +3 -1
- package/dist/adapters/agents/model-support.constants.js +12 -2
- package/dist/adapters/agents/model-support.constants.js.map +1 -1
- package/dist/adapters/agents/protocol-fixtures.constants.d.ts +2 -2
- package/dist/adapters/agents/protocol-fixtures.constants.js +131 -9
- package/dist/adapters/agents/protocol-fixtures.constants.js.map +1 -1
- package/dist/adapters/agents/protocol-fixtures.types.d.ts +1 -0
- package/dist/adapters/agents/protocol-fixtures.types.js.map +1 -1
- package/dist/adapters/agents/protocol.d.ts +1 -0
- package/dist/adapters/agents/protocol.js +9 -0
- package/dist/adapters/agents/protocol.js.map +1 -1
- package/dist/adapters/agents/session-usage.constants.d.ts +10 -0
- package/dist/adapters/agents/session-usage.constants.js +110 -0
- package/dist/adapters/agents/session-usage.constants.js.map +1 -0
- package/dist/adapters/agents/session-usage.d.ts +5 -0
- package/dist/adapters/agents/session-usage.js +45 -0
- package/dist/adapters/agents/session-usage.js.map +1 -0
- package/dist/adapters/agents/settings.types.d.ts +1 -0
- package/dist/adapters/agents/settings.types.js.map +1 -1
- package/dist/adapters/agents/tool-result.d.ts +2 -0
- package/dist/adapters/agents/tool-result.js +17 -0
- package/dist/adapters/agents/tool-result.js.map +1 -0
- package/dist/adapters/models/anthropic-response.js +3 -0
- package/dist/adapters/models/anthropic-response.js.map +1 -1
- package/dist/adapters/models/http-provider.js +6 -1
- package/dist/adapters/models/http-provider.js.map +1 -1
- package/dist/adapters/models/openai-responses.js +10 -0
- package/dist/adapters/models/openai-responses.js.map +1 -1
- package/dist/adapters/models/retry-after.d.ts +1 -0
- package/dist/adapters/models/retry-after.js +16 -0
- package/dist/adapters/models/retry-after.js.map +1 -0
- package/dist/application/activity-watchdog.js +1 -2
- package/dist/application/activity-watchdog.js.map +1 -1
- package/dist/application/agent-authentication.d.ts +4 -0
- package/dist/application/agent-authentication.js +32 -0
- package/dist/application/agent-authentication.js.map +1 -0
- package/dist/application/agent-bootstrap.constants.d.ts +2 -5
- package/dist/application/agent-bootstrap.constants.js +27 -4
- package/dist/application/agent-bootstrap.constants.js.map +1 -1
- package/dist/application/agent-bootstrap.js +39 -12
- package/dist/application/agent-bootstrap.js.map +1 -1
- package/dist/application/agent-bootstrap.types.d.ts +19 -0
- package/dist/application/agent-bootstrap.types.js +2 -0
- package/dist/application/agent-bootstrap.types.js.map +1 -0
- package/dist/application/agent-output.js +74 -8
- package/dist/application/agent-output.js.map +1 -1
- package/dist/application/agent-request.d.ts +3 -0
- package/dist/application/agent-request.js +11 -0
- package/dist/application/agent-request.js.map +1 -0
- package/dist/application/agent-turn.js +74 -6
- package/dist/application/agent-turn.js.map +1 -1
- package/dist/application/agent-usage.d.ts +6 -0
- package/dist/application/agent-usage.js +57 -0
- package/dist/application/agent-usage.js.map +1 -0
- package/dist/application/attach.js +2 -0
- package/dist/application/attach.js.map +1 -1
- package/dist/application/credential-installer.constants.d.ts +1 -0
- package/dist/application/credential-installer.constants.js +22 -0
- package/dist/application/credential-installer.constants.js.map +1 -0
- package/dist/application/custom-turn.js +44 -49
- package/dist/application/custom-turn.js.map +1 -1
- package/dist/application/dispatch-observation.d.ts +1 -1
- package/dist/application/dispatch-observation.js +141 -21
- package/dist/application/dispatch-observation.js.map +1 -1
- package/dist/application/dispatch-observation.types.d.ts +2 -0
- package/dist/application/dispatch-observation.types.js.map +1 -1
- package/dist/application/dispatch-validation.js +2 -0
- package/dist/application/dispatch-validation.js.map +1 -1
- package/dist/application/dispatch.js +1 -1
- package/dist/application/dispatch.js.map +1 -1
- package/dist/application/doctor-agent.constants.d.ts +2 -8
- package/dist/application/doctor-agent.constants.js +43 -6
- package/dist/application/doctor-agent.constants.js.map +1 -1
- package/dist/application/doctor-agent.d.ts +2 -1
- package/dist/application/doctor-agent.js +15 -3
- package/dist/application/doctor-agent.js.map +1 -1
- package/dist/application/doctor-image.js +4 -6
- package/dist/application/doctor-image.js.map +1 -1
- package/dist/application/doctor-protocol.js +6 -11
- package/dist/application/doctor-protocol.js.map +1 -1
- package/dist/application/doctor-protocol.types.d.ts +1 -1
- package/dist/application/doctor-protocol.types.js.map +1 -1
- package/dist/application/doctor-sandbox.js +2 -5
- package/dist/application/doctor-sandbox.js.map +1 -1
- package/dist/application/doctor.js +28 -10
- package/dist/application/doctor.js.map +1 -1
- package/dist/application/doctor.types.d.ts +10 -1
- package/dist/application/doctor.types.js.map +1 -1
- package/dist/application/execution.constants.d.ts +2 -0
- package/dist/application/execution.constants.js +2 -0
- package/dist/application/execution.constants.js.map +1 -1
- package/dist/application/execution.types.d.ts +8 -0
- package/dist/application/execution.types.js.map +1 -1
- package/dist/application/harness-budget.d.ts +3 -0
- package/dist/application/harness-budget.js +42 -0
- package/dist/application/harness-budget.js.map +1 -0
- package/dist/application/harness-budget.types.d.ts +5 -0
- package/dist/application/harness-budget.types.js +2 -0
- package/dist/application/harness-budget.types.js.map +1 -0
- package/dist/application/harness-hooks.js +34 -3
- package/dist/application/harness-hooks.js.map +1 -1
- package/dist/application/harness-loop.js +52 -24
- package/dist/application/harness-loop.js.map +1 -1
- package/dist/application/harness-model-provider.d.ts +3 -0
- package/dist/application/harness-model-provider.js +49 -0
- package/dist/application/harness-model-provider.js.map +1 -0
- package/dist/application/harness-model-provider.types.d.ts +10 -0
- package/dist/application/harness-model-provider.types.js +2 -0
- package/dist/application/harness-model-provider.types.js.map +1 -0
- package/dist/application/harness-subagent.d.ts +4 -0
- package/dist/application/harness-subagent.js +110 -0
- package/dist/application/harness-subagent.js.map +1 -0
- package/dist/application/harness.types.d.ts +11 -0
- package/dist/application/harness.types.js.map +1 -1
- package/dist/application/lifecycle-hooks.d.ts +1 -1
- package/dist/application/lifecycle-hooks.js +5 -4
- package/dist/application/lifecycle-hooks.js.map +1 -1
- package/dist/application/observed-lease.d.ts +3 -0
- package/dist/application/observed-lease.js +26 -0
- package/dist/application/observed-lease.js.map +1 -0
- package/dist/application/outpost.types.d.ts +3 -1
- package/dist/application/outpost.types.js.map +1 -1
- package/dist/application/output-lines.d.ts +4 -0
- package/dist/application/output-lines.js +28 -0
- package/dist/application/output-lines.js.map +1 -0
- package/dist/application/queue-worker.js +1 -1
- package/dist/application/queue-worker.js.map +1 -1
- package/dist/application/queue-worker.types.d.ts +1 -0
- package/dist/application/queue-worker.types.js.map +1 -1
- package/dist/application/queued-task.js +24 -5
- package/dist/application/queued-task.js.map +1 -1
- package/dist/application/recovery-archive.d.ts +3 -2
- package/dist/application/recovery-archive.js +9 -2
- package/dist/application/recovery-archive.js.map +1 -1
- package/dist/application/recovery-restore.d.ts +3 -2
- package/dist/application/recovery-restore.js +9 -2
- package/dist/application/recovery-restore.js.map +1 -1
- package/dist/application/recovery-retention.d.ts +3 -2
- package/dist/application/recovery-retention.js +74 -26
- package/dist/application/recovery-retention.js.map +1 -1
- package/dist/application/remote-workspace.js +5 -4
- package/dist/application/remote-workspace.js.map +1 -1
- package/dist/application/remote-workspace.types.d.ts +1 -0
- package/dist/application/remote-workspace.types.js.map +1 -1
- package/dist/application/sandbox-agents.js +19 -19
- package/dist/application/sandbox-agents.js.map +1 -1
- package/dist/application/sandbox-attach.js +12 -3
- package/dist/application/sandbox-attach.js.map +1 -1
- package/dist/application/sandbox-dispatch.js +13 -27
- package/dist/application/sandbox-dispatch.js.map +1 -1
- package/dist/application/sandbox-provision.js +15 -9
- package/dist/application/sandbox-provision.js.map +1 -1
- package/dist/application/sandbox-session.types.d.ts +7 -2
- package/dist/application/sandbox-session.types.js.map +1 -1
- package/dist/application/sandbox.js +13 -6
- package/dist/application/sandbox.js.map +1 -1
- package/dist/application/speculation-checkpoint.d.ts +6 -0
- package/dist/application/speculation-checkpoint.js +206 -0
- package/dist/application/speculation-checkpoint.js.map +1 -0
- package/dist/application/speculation-checkpoint.types.d.ts +24 -0
- package/dist/application/speculation-checkpoint.types.js +2 -0
- package/dist/application/speculation-checkpoint.types.js.map +1 -0
- package/dist/application/speculation-integration.constants.d.ts +4 -0
- package/dist/application/speculation-integration.constants.js +5 -0
- package/dist/application/speculation-integration.constants.js.map +1 -0
- package/dist/application/speculation-integration.d.ts +2 -0
- package/dist/application/speculation-integration.js +67 -0
- package/dist/application/speculation-integration.js.map +1 -0
- package/dist/application/speculation-resume.d.ts +4 -0
- package/dist/application/speculation-resume.js +71 -0
- package/dist/application/speculation-resume.js.map +1 -0
- package/dist/application/speculation-run.d.ts +4 -0
- package/dist/application/speculation-run.js +320 -0
- package/dist/application/speculation-run.js.map +1 -0
- package/dist/application/speculation-timeout.d.ts +1 -0
- package/dist/application/speculation-timeout.js +15 -0
- package/dist/application/speculation-timeout.js.map +1 -0
- package/dist/application/speculation.constants.d.ts +1 -0
- package/dist/application/speculation.constants.js +5 -1
- package/dist/application/speculation.constants.js.map +1 -1
- package/dist/application/speculation.js +41 -149
- package/dist/application/speculation.js.map +1 -1
- package/dist/application/speculation.types.d.ts +23 -0
- package/dist/application/speculation.types.js.map +1 -1
- package/dist/application/startup-recovery.js +14 -1
- package/dist/application/startup-recovery.js.map +1 -1
- package/dist/application/startup-recovery.types.d.ts +1 -0
- package/dist/application/startup-recovery.types.js.map +1 -1
- package/dist/application/stop-reason.d.ts +2 -0
- package/dist/application/stop-reason.js +21 -0
- package/dist/application/stop-reason.js.map +1 -0
- package/dist/application/stop-reason.types.d.ts +4 -0
- package/dist/application/stop-reason.types.js +2 -0
- package/dist/application/stop-reason.types.js.map +1 -0
- package/dist/application/storage-reservation.js +9 -2
- package/dist/application/storage-reservation.js.map +1 -1
- package/dist/application/task-observation.d.ts +3 -0
- package/dist/application/task-observation.js +22 -0
- package/dist/application/task-observation.js.map +1 -0
- package/dist/application/task-usage.js +5 -12
- package/dist/application/task-usage.js.map +1 -1
- package/dist/application/tasks.js +41 -16
- package/dist/application/tasks.js.map +1 -1
- package/dist/application/tool-execution.js +42 -19
- package/dist/application/tool-execution.js.map +1 -1
- package/dist/application/workspace.js +6 -4
- package/dist/application/workspace.js.map +1 -1
- package/dist/cli/doctor-command.js +6 -2
- package/dist/cli/doctor-command.js.map +1 -1
- package/dist/cli/init-authentication.d.ts +4 -1
- package/dist/cli/init-authentication.js +28 -33
- package/dist/cli/init-authentication.js.map +1 -1
- package/dist/cli/init-command.js +3 -3
- package/dist/cli/init-command.js.map +1 -1
- package/dist/cli/main.constants.d.ts +50 -13
- package/dist/cli/main.constants.js +70 -8
- package/dist/cli/main.constants.js.map +1 -1
- package/dist/cli/main.js +2 -1
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/scaffold-files.js +1 -1
- package/dist/cli/scaffold-files.js.map +1 -1
- package/dist/cli/scaffold-validation.js +29 -22
- package/dist/cli/scaffold-validation.js.map +1 -1
- package/dist/cli/scaffold.constants.d.ts +0 -1
- package/dist/cli/scaffold.constants.js +6 -2
- package/dist/cli/scaffold.constants.js.map +1 -1
- package/dist/cli/scaffold.types.d.ts +8 -2
- package/dist/cli/scaffold.types.js.map +1 -1
- package/dist/cli/starters.js +1 -3
- package/dist/cli/starters.js.map +1 -1
- package/dist/domain/agent-observation.d.ts +4 -0
- package/dist/domain/agent-observation.js +27 -0
- package/dist/domain/agent-observation.js.map +1 -0
- package/dist/domain/agent.types.d.ts +122 -14
- package/dist/domain/agent.types.js.map +1 -1
- package/dist/domain/authentication.constants.d.ts +3 -0
- package/dist/domain/authentication.constants.js +11 -0
- package/dist/domain/authentication.constants.js.map +1 -0
- package/dist/domain/authentication.d.ts +3 -0
- package/dist/domain/authentication.js +22 -0
- package/dist/domain/authentication.js.map +1 -0
- package/dist/domain/authentication.types.d.ts +5 -0
- package/dist/domain/authentication.types.js +2 -0
- package/dist/domain/authentication.types.js.map +1 -0
- package/dist/domain/harness.d.ts +2 -2
- package/dist/domain/harness.js +6 -0
- package/dist/domain/harness.js.map +1 -1
- package/dist/domain/harness.types.d.ts +4 -3
- package/dist/domain/harness.types.js.map +1 -1
- package/dist/domain/model.types.d.ts +8 -0
- package/dist/domain/model.types.js.map +1 -1
- package/dist/domain/observation.constants.d.ts +8 -0
- package/dist/domain/observation.constants.js +9 -0
- package/dist/domain/observation.constants.js.map +1 -0
- package/dist/domain/observation.d.ts +2 -0
- package/dist/domain/observation.js +190 -0
- package/dist/domain/observation.js.map +1 -0
- package/dist/domain/observation.types.d.ts +84 -0
- package/dist/domain/observation.types.js +2 -0
- package/dist/domain/observation.types.js.map +1 -0
- package/dist/domain/observed-operation.d.ts +2 -0
- package/dist/domain/observed-operation.js +30 -0
- package/dist/domain/observed-operation.js.map +1 -0
- package/dist/domain/sandbox.types.d.ts +2 -0
- package/dist/domain/sandbox.types.js.map +1 -1
- package/dist/domain/subagent.constants.d.ts +13 -0
- package/dist/domain/subagent.constants.js +9 -0
- package/dist/domain/subagent.constants.js.map +1 -0
- package/dist/domain/subagent.d.ts +4 -0
- package/dist/domain/subagent.js +28 -0
- package/dist/domain/subagent.js.map +1 -0
- package/dist/domain/subagent.types.d.ts +13 -0
- package/dist/domain/subagent.types.js +2 -0
- package/dist/domain/subagent.types.js.map +1 -0
- package/dist/domain/transcript.types.d.ts +2 -0
- package/dist/domain/transcript.types.js.map +1 -1
- package/dist/domain/usage.d.ts +1 -0
- package/dist/domain/usage.js +16 -0
- package/dist/domain/usage.js.map +1 -1
- package/dist/domain/workflow/budget.d.ts +7 -3
- package/dist/domain/workflow/budget.js +26 -0
- package/dist/domain/workflow/budget.js.map +1 -1
- package/dist/domain/workflow/budget.types.d.ts +1 -1
- package/dist/domain/workflow/budget.types.js.map +1 -1
- package/dist/domain/workflow/checkpoint-validation.js +7 -1
- package/dist/domain/workflow/checkpoint-validation.js.map +1 -1
- package/dist/domain/workflow/checkpoint.js +3 -0
- package/dist/domain/workflow/checkpoint.js.map +1 -1
- package/dist/domain/workflow/gate-validation.js +14 -1
- package/dist/domain/workflow/gate-validation.js.map +1 -1
- package/dist/domain/workflow/gates.d.ts +1 -1
- package/dist/domain/workflow/gates.js +52 -4
- package/dist/domain/workflow/gates.js.map +1 -1
- package/dist/domain/workflow/gates.types.d.ts +15 -1
- package/dist/domain/workflow/gates.types.js.map +1 -1
- package/dist/domain/workflow/idempotency.d.ts +1 -0
- package/dist/domain/workflow/idempotency.js +7 -0
- package/dist/domain/workflow/idempotency.js.map +1 -0
- package/dist/domain/workflow/retry.constants.d.ts +2 -0
- package/dist/domain/workflow/retry.constants.js +3 -0
- package/dist/domain/workflow/retry.constants.js.map +1 -0
- package/dist/domain/workflow/retry.d.ts +4 -0
- package/dist/domain/workflow/retry.js +49 -0
- package/dist/domain/workflow/retry.js.map +1 -0
- package/dist/domain/workflow/task-runner.js +9 -5
- package/dist/domain/workflow/task-runner.js.map +1 -1
- package/dist/domain/workflow/task.js +6 -6
- package/dist/domain/workflow/task.js.map +1 -1
- package/dist/domain/workflow/workflow-scheduler.js +110 -72
- package/dist/domain/workflow/workflow-scheduler.js.map +1 -1
- package/dist/domain/workflow/workflow-state.js +28 -12
- package/dist/domain/workflow/workflow-state.js.map +1 -1
- package/dist/domain/workflow.d.ts +1 -1
- package/dist/domain/workflow.js +1 -1
- package/dist/domain/workflow.js.map +1 -1
- package/dist/domain/workflow.types.d.ts +13 -2
- package/dist/domain/workflow.types.js.map +1 -1
- package/dist/index.d.ts +16 -11
- package/dist/index.js +7 -4
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/conversations/capture.js +10 -0
- package/dist/infrastructure/conversations/capture.js.map +1 -1
- package/dist/infrastructure/conversations/harness-transcript.js +6 -0
- package/dist/infrastructure/conversations/harness-transcript.js.map +1 -1
- package/dist/infrastructure/conversations/harness-transcript.types.d.ts +2 -0
- package/dist/infrastructure/conversations/harness-transcript.types.js.map +1 -1
- package/dist/infrastructure/conversations/layout.js +2 -0
- package/dist/infrastructure/conversations/layout.js.map +1 -1
- package/dist/infrastructure/conversations/locate.js +7 -1
- package/dist/infrastructure/conversations/locate.js.map +1 -1
- package/dist/infrastructure/conversations/native-store.js +8 -1
- package/dist/infrastructure/conversations/native-store.js.map +1 -1
- package/dist/infrastructure/conversations/paths.js +3 -0
- package/dist/infrastructure/conversations/paths.js.map +1 -1
- package/dist/infrastructure/conversations/restore.js +7 -0
- package/dist/infrastructure/conversations/restore.js.map +1 -1
- package/dist/infrastructure/conversations/session-bundle.constants.d.ts +5 -0
- package/dist/infrastructure/conversations/session-bundle.constants.js +173 -0
- package/dist/infrastructure/conversations/session-bundle.constants.js.map +1 -0
- package/dist/infrastructure/conversations/session-bundle.d.ts +6 -0
- package/dist/infrastructure/conversations/session-bundle.js +98 -0
- package/dist/infrastructure/conversations/session-bundle.js.map +1 -0
- package/dist/infrastructure/conversations/session-bundle.types.d.ts +1 -0
- package/dist/infrastructure/conversations/session-bundle.types.js +2 -0
- package/dist/infrastructure/conversations/session-bundle.types.js.map +1 -0
- package/dist/infrastructure/conversations.js +4 -2
- package/dist/infrastructure/conversations.js.map +1 -1
- package/dist/infrastructure/conversations.types.d.ts +1 -1
- package/dist/infrastructure/conversations.types.js.map +1 -1
- package/dist/infrastructure/custom-reporter.js +32 -24
- package/dist/infrastructure/custom-reporter.js.map +1 -1
- package/dist/infrastructure/custom-reporter.types.d.ts +2 -0
- package/dist/infrastructure/custom-reporter.types.js.map +1 -1
- package/dist/infrastructure/git/git.constants.d.ts +1 -1
- package/dist/infrastructure/git/git.constants.js +1 -0
- package/dist/infrastructure/git/git.constants.js.map +1 -1
- package/dist/infrastructure/git/workspace-lease.js +4 -3
- package/dist/infrastructure/git/workspace-lease.js.map +1 -1
- package/dist/infrastructure/git/workspace.js +7 -6
- package/dist/infrastructure/git/workspace.js.map +1 -1
- package/dist/infrastructure/git/workspace.types.d.ts +1 -0
- package/dist/infrastructure/git/workspace.types.js.map +1 -1
- package/dist/infrastructure/host-credentials.constants.d.ts +1 -0
- package/dist/infrastructure/host-credentials.constants.js +2 -0
- package/dist/infrastructure/host-credentials.constants.js.map +1 -0
- package/dist/infrastructure/host-credentials.d.ts +4 -0
- package/dist/infrastructure/host-credentials.js +89 -0
- package/dist/infrastructure/host-credentials.js.map +1 -0
- package/dist/infrastructure/inspection-path.js +4 -3
- package/dist/infrastructure/inspection-path.js.map +1 -1
- package/dist/infrastructure/journal.constants.js +10 -1
- package/dist/infrastructure/journal.constants.js.map +1 -1
- package/dist/infrastructure/journal.d.ts +1 -1
- package/dist/infrastructure/journal.js +8 -75
- package/dist/infrastructure/journal.js.map +1 -1
- package/dist/infrastructure/journal.types.d.ts +2 -4
- package/dist/infrastructure/journal.types.js.map +1 -1
- package/dist/infrastructure/local-transport.js +9 -4
- package/dist/infrastructure/local-transport.js.map +1 -1
- package/dist/infrastructure/opentelemetry-dispatch.d.ts +3 -3
- package/dist/infrastructure/opentelemetry-dispatch.js +5 -4
- package/dist/infrastructure/opentelemetry-dispatch.js.map +1 -1
- package/dist/infrastructure/opentelemetry-observation.d.ts +5 -0
- package/dist/infrastructure/opentelemetry-observation.js +59 -0
- package/dist/infrastructure/opentelemetry-observation.js.map +1 -0
- package/dist/infrastructure/opentelemetry.js +15 -1
- package/dist/infrastructure/opentelemetry.js.map +1 -1
- package/dist/infrastructure/opentelemetry.types.d.ts +9 -1
- package/dist/infrastructure/opentelemetry.types.js.map +1 -1
- package/dist/infrastructure/reporter.d.ts +2 -2
- package/dist/infrastructure/reporter.js +5 -1
- package/dist/infrastructure/reporter.js.map +1 -1
- package/dist/infrastructure/repository-transport.constants.d.ts +1 -0
- package/dist/infrastructure/repository-transport.constants.js +2 -0
- package/dist/infrastructure/repository-transport.constants.js.map +1 -0
- package/dist/infrastructure/repository-transport.d.ts +2 -0
- package/dist/infrastructure/repository-transport.js +9 -0
- package/dist/infrastructure/repository-transport.js.map +1 -0
- package/dist/infrastructure/resource-activity-inspection.js +19 -24
- package/dist/infrastructure/resource-activity-inspection.js.map +1 -1
- package/dist/infrastructure/resource-activity.constants.d.ts +0 -1
- package/dist/infrastructure/resource-activity.constants.js +0 -1
- package/dist/infrastructure/resource-activity.constants.js.map +1 -1
- package/dist/infrastructure/resource-activity.js +20 -83
- package/dist/infrastructure/resource-activity.js.map +1 -1
- package/dist/infrastructure/s3-transport.constants.d.ts +2 -0
- package/dist/infrastructure/s3-transport.constants.js +3 -0
- package/dist/infrastructure/s3-transport.constants.js.map +1 -0
- package/dist/infrastructure/s3-transport.js +57 -3
- package/dist/infrastructure/s3-transport.js.map +1 -1
- package/dist/infrastructure/s3-transport.types.d.ts +1 -0
- package/dist/infrastructure/s3-transport.types.js.map +1 -1
- package/dist/infrastructure/speculation-store.constants.d.ts +3 -0
- package/dist/infrastructure/speculation-store.constants.js +2 -0
- package/dist/infrastructure/speculation-store.constants.js.map +1 -0
- package/dist/infrastructure/speculation-store.d.ts +4 -0
- package/dist/infrastructure/speculation-store.js +73 -0
- package/dist/infrastructure/speculation-store.js.map +1 -0
- package/dist/infrastructure/speculation-store.types.d.ts +12 -0
- package/dist/infrastructure/speculation-store.types.js +2 -0
- package/dist/infrastructure/speculation-store.types.js.map +1 -0
- package/dist/infrastructure/storage-inventory.constants.js +1 -0
- package/dist/infrastructure/storage-inventory.constants.js.map +1 -1
- package/dist/infrastructure/storage-inventory.types.d.ts +1 -1
- package/dist/infrastructure/storage-inventory.types.js.map +1 -1
- package/dist/infrastructure/storage-reservations.types.d.ts +0 -8
- package/dist/infrastructure/storage-reservations.types.js.map +1 -1
- package/dist/infrastructure/task-queue-bullmq-resources.js +3 -0
- package/dist/infrastructure/task-queue-bullmq-resources.js.map +1 -1
- package/dist/infrastructure/task-queue-http.js +29 -4
- package/dist/infrastructure/task-queue-http.js.map +1 -1
- package/dist/infrastructure/task-queue-http.types.d.ts +2 -2
- package/dist/infrastructure/task-queue-http.types.js.map +1 -1
- package/dist/infrastructure/transport-conversations.js +2 -0
- package/dist/infrastructure/transport-conversations.js.map +1 -1
- package/dist/infrastructure/transport-journal.d.ts +1 -1
- package/dist/infrastructure/transport-journal.js +8 -2
- package/dist/infrastructure/transport-journal.js.map +1 -1
- package/dist/infrastructure/transport-reservations.d.ts +1 -1
- package/dist/infrastructure/transport-reservations.js +14 -8
- package/dist/infrastructure/transport-reservations.js.map +1 -1
- package/dist/infrastructure/workflow-decision-signature.constants.d.ts +4 -0
- package/dist/infrastructure/workflow-decision-signature.constants.js +5 -0
- package/dist/infrastructure/workflow-decision-signature.constants.js.map +1 -0
- package/dist/infrastructure/workflow-decision-signature.d.ts +4 -0
- package/dist/infrastructure/workflow-decision-signature.js +83 -0
- package/dist/infrastructure/workflow-decision-signature.js.map +1 -0
- package/dist/infrastructure/workflow-decision-signature.types.d.ts +16 -0
- package/dist/infrastructure/workflow-decision-signature.types.js +2 -0
- package/dist/infrastructure/workflow-decision-signature.types.js.map +1 -0
- package/dist/providers/agents.d.ts +7 -2
- package/dist/providers/agents.js +4 -1
- package/dist/providers/agents.js.map +1 -1
- package/dist/providers/antigravity-install.constants.d.ts +2 -0
- package/dist/providers/antigravity-install.constants.js +28 -0
- package/dist/providers/antigravity-install.constants.js.map +1 -0
- package/dist/providers/antigravity-install.d.ts +2 -0
- package/dist/providers/antigravity-install.js +29 -0
- package/dist/providers/antigravity-install.js.map +1 -0
- package/dist/providers/antigravity-install.types.d.ts +4 -0
- package/dist/providers/antigravity-install.types.js +2 -0
- package/dist/providers/antigravity-install.types.js.map +1 -0
- package/dist/providers/container-recovery.d.ts +4 -0
- package/dist/providers/container-recovery.js +28 -0
- package/dist/providers/container-recovery.js.map +1 -0
- package/dist/providers/container.js +8 -0
- package/dist/providers/container.js.map +1 -1
- package/dist/providers/daytona-network.constants.d.ts +5 -0
- package/dist/providers/daytona-network.constants.js +8 -0
- package/dist/providers/daytona-network.constants.js.map +1 -0
- package/dist/providers/daytona-network.d.ts +4 -0
- package/dist/providers/daytona-network.js +33 -0
- package/dist/providers/daytona-network.js.map +1 -0
- package/dist/providers/daytona.d.ts +1 -0
- package/dist/providers/daytona.js +9 -3
- package/dist/providers/daytona.js.map +1 -1
- package/dist/providers/daytona.types.d.ts +2 -0
- package/dist/providers/daytona.types.js.map +1 -1
- package/dist/providers/firecracker-command.js +1 -1
- package/dist/providers/firecracker-command.js.map +1 -1
- package/dist/providers/firecracker-jailer.constants.d.ts +9 -0
- package/dist/providers/firecracker-jailer.constants.js +10 -0
- package/dist/providers/firecracker-jailer.constants.js.map +1 -0
- package/dist/providers/firecracker-jailer.d.ts +4 -0
- package/dist/providers/firecracker-jailer.js +171 -0
- package/dist/providers/firecracker-jailer.js.map +1 -0
- package/dist/providers/firecracker-machine.js +30 -8
- package/dist/providers/firecracker-machine.js.map +1 -1
- package/dist/providers/firecracker.types.d.ts +16 -0
- package/dist/providers/firecracker.types.js.map +1 -1
- package/dist/providers/vercel-network.js +1 -1
- package/dist/providers/vercel-network.js.map +1 -1
- package/dist/providers/vercel.js +6 -3
- package/dist/providers/vercel.js.map +1 -1
- package/dist/providers/versions.constants.d.ts +3 -1
- package/dist/providers/versions.constants.js +3 -1
- package/dist/providers/versions.constants.js.map +1 -1
- package/package.json +3 -3
- package/dist/adapters/agents/gemini-adapter.d.ts +0 -3
- package/dist/adapters/agents/gemini-adapter.js +0 -34
- package/dist/adapters/agents/gemini-adapter.js.map +0 -1
- package/dist/adapters/agents/gemini-diagnostics.d.ts +0 -2
- package/dist/adapters/agents/gemini-diagnostics.js +0 -15
- package/dist/adapters/agents/gemini-diagnostics.js.map +0 -1
- package/dist/adapters/agents/gemini-events.d.ts +0 -2
- package/dist/adapters/agents/gemini-events.js +0 -50
- package/dist/adapters/agents/gemini-events.js.map +0 -1
- package/dist/adapters/agents/gemini-request.js +0 -23
- package/dist/adapters/agents/gemini-request.js.map +0 -1
- package/dist/adapters/agents/gemini.types.js +0 -2
- package/dist/adapters/agents/gemini.types.js.map +0 -1
- package/dist/infrastructure/artifact-store.d.ts +0 -3
- package/dist/infrastructure/artifact-store.js +0 -110
- package/dist/infrastructure/artifact-store.js.map +0 -1
- package/dist/infrastructure/artifact-store.types.d.ts +0 -6
- package/dist/infrastructure/artifact-store.types.js +0 -2
- package/dist/infrastructure/artifact-store.types.js.map +0 -1
- package/dist/infrastructure/journal-retention.constants.d.ts +0 -4
- package/dist/infrastructure/journal-retention.constants.js +0 -5
- package/dist/infrastructure/journal-retention.constants.js.map +0 -1
- package/dist/infrastructure/journal-retention.d.ts +0 -2
- package/dist/infrastructure/journal-retention.js +0 -51
- package/dist/infrastructure/journal-retention.js.map +0 -1
- package/dist/infrastructure/storage-mutation-lock.constants.d.ts +0 -5
- package/dist/infrastructure/storage-mutation-lock.constants.js +0 -6
- package/dist/infrastructure/storage-mutation-lock.constants.js.map +0 -1
- package/dist/infrastructure/storage-mutation-lock.d.ts +0 -1
- package/dist/infrastructure/storage-mutation-lock.js +0 -21
- package/dist/infrastructure/storage-mutation-lock.js.map +0 -1
- package/dist/infrastructure/storage-reservations.constants.d.ts +0 -4
- package/dist/infrastructure/storage-reservations.constants.js +0 -5
- package/dist/infrastructure/storage-reservations.constants.js.map +0 -1
- package/dist/infrastructure/storage-reservations.d.ts +0 -2
- package/dist/infrastructure/storage-reservations.js +0 -150
- package/dist/infrastructure/storage-reservations.js.map +0 -1
- package/dist/infrastructure/workflow-checkpoint.d.ts +0 -3
- package/dist/infrastructure/workflow-checkpoint.js +0 -84
- package/dist/infrastructure/workflow-checkpoint.js.map +0 -1
- package/dist/infrastructure/workflow-checkpoint.types.d.ts +0 -6
- package/dist/infrastructure/workflow-checkpoint.types.js +0 -2
- package/dist/infrastructure/workflow-checkpoint.types.js.map +0 -1
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
export const sessionBundleLimits = Object.freeze({
|
|
2
|
+
bytes: 64 * 1024 * 1024,
|
|
3
|
+
files: 4096,
|
|
4
|
+
});
|
|
5
|
+
export const sessionBundleScript = String.raw `
|
|
6
|
+
const fs = require('node:fs/promises');
|
|
7
|
+
const path = require('node:path');
|
|
8
|
+
const { createHash, randomUUID } = require('node:crypto');
|
|
9
|
+
const [mode, format, id, home, cwd, bundleFile, maxBytesText, maxFilesText] = process.argv.slice(1);
|
|
10
|
+
const maxBytes = Number(maxBytesText), maxFiles = Number(maxFilesText);
|
|
11
|
+
function check(ok, message) { if (!ok) throw new Error(message); }
|
|
12
|
+
check(format === 'copilot' || format === 'kimi', 'Unsupported native session format');
|
|
13
|
+
check(/^[A-Za-z0-9_-]+$/.test(id), 'Invalid conversation identifier');
|
|
14
|
+
const base = format === 'kimi'
|
|
15
|
+
? (process.env.KIMI_CODE_HOME || path.join(home, '.kimi-code'))
|
|
16
|
+
: (process.env.COPILOT_HOME || path.join(home, '.copilot'));
|
|
17
|
+
const sessions = path.join(base, format === 'kimi' ? 'sessions' : 'session-state');
|
|
18
|
+
async function entries(dir) {
|
|
19
|
+
try { return await fs.readdir(dir, { withFileTypes: true }); }
|
|
20
|
+
catch (error) { if (error.code === 'ENOENT') return []; throw error; }
|
|
21
|
+
}
|
|
22
|
+
async function safe(file) {
|
|
23
|
+
for (let at = file;; at = path.dirname(at)) {
|
|
24
|
+
const info = await fs.lstat(at).catch(error => { if (error.code === 'ENOENT') return; throw error; });
|
|
25
|
+
check(!info?.isSymbolicLink(), 'Native session paths must not traverse symlinks');
|
|
26
|
+
if (at === path.dirname(at)) break;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
async function locate() {
|
|
30
|
+
await safe(sessions);
|
|
31
|
+
if (format === 'copilot') return path.join(sessions, id);
|
|
32
|
+
const found = [];
|
|
33
|
+
for (const bucket of await entries(sessions)) {
|
|
34
|
+
if (!bucket.isDirectory()) continue;
|
|
35
|
+
const candidate = path.join(sessions, bucket.name, id);
|
|
36
|
+
const info = await fs.lstat(candidate).catch(error => { if (error.code === 'ENOENT') return; throw error; });
|
|
37
|
+
if (info) { check(info.isDirectory(), 'Invalid native session directory'); found.push(candidate); }
|
|
38
|
+
}
|
|
39
|
+
check(found.length === 1, 'Kimi session is missing or ambiguous');
|
|
40
|
+
return found[0];
|
|
41
|
+
}
|
|
42
|
+
function selected(name) {
|
|
43
|
+
if (format === 'copilot') return /^(?:(?:events\.jsonl|workspace\.yaml|plan\.md)$|(?:checkpoints|files)(?:\/|$))/.test(name);
|
|
44
|
+
return !/^(logs|tasks|cron|notify)(\/|$)/.test(name) && !/(^|\/)[^/]*\.lock$/.test(name);
|
|
45
|
+
}
|
|
46
|
+
function validName(name) {
|
|
47
|
+
return typeof name === 'string' && name.length > 0 && !name.includes('\\') && !name.includes('\0') &&
|
|
48
|
+
!path.isAbsolute(name) && !name.split('/').some(p => !p || p === '.' || p === '..' || p.toLowerCase() === '.git');
|
|
49
|
+
}
|
|
50
|
+
function validate(bundle) {
|
|
51
|
+
check(bundle && bundle.version === 1 && bundle.format === format && bundle.id === id && typeof bundle.source === 'string' && Array.isArray(bundle.files), 'Invalid native session bundle');
|
|
52
|
+
check(bundle.files.length > 0, 'Native session is missing or incomplete');
|
|
53
|
+
check(bundle.files.length <= maxFiles, 'Native session file limit exceeded');
|
|
54
|
+
let bytes = 0;
|
|
55
|
+
const names = new Set();
|
|
56
|
+
for (const file of bundle.files) {
|
|
57
|
+
check(file && validName(file.path) && selected(file.path) && !names.has(file.path) && typeof file.data === 'string', 'Invalid native session entry');
|
|
58
|
+
const data = Buffer.from(file.data, 'base64');
|
|
59
|
+
check(data.toString('base64') === file.data, 'Invalid native session encoding');
|
|
60
|
+
bytes += data.length;
|
|
61
|
+
check(bytes <= maxBytes, 'Native session byte limit exceeded');
|
|
62
|
+
names.add(file.path);
|
|
63
|
+
}
|
|
64
|
+
const required = format === 'kimi' ? ['state.json', 'agents/main/wire.jsonl'] : ['events.jsonl', 'workspace.yaml'];
|
|
65
|
+
check(required.every(name => names.has(name)), 'Native session is incomplete or uses an unsupported format');
|
|
66
|
+
if (format === 'kimi') {
|
|
67
|
+
const meta = JSON.parse(Buffer.from(bundle.files.find(f => f.path === 'state.json').data, 'base64'));
|
|
68
|
+
check(meta.version === 2 && meta.id === id && typeof meta.cwd === 'string' && meta.agents && typeof meta.agents === 'object', 'Unsupported Kimi session metadata');
|
|
69
|
+
}
|
|
70
|
+
return bundle;
|
|
71
|
+
}
|
|
72
|
+
function workDirKey(dir) {
|
|
73
|
+
const normalized = dir.replace(/\\/g, '/').replace(/\/+$/, '');
|
|
74
|
+
let slug = normalized.split('/').pop().toLowerCase().replace(/[^a-z0-9._-]+/g, '-').replace(/^-+|-+$/g, '').slice(0, 40).replace(/^-+|-+$/g, '');
|
|
75
|
+
if (!slug || slug === '.' || slug === '..') slug = 'workspace';
|
|
76
|
+
return 'wd_' + slug + '_' + createHash('sha256').update(normalized).digest('hex').slice(0, 12);
|
|
77
|
+
}
|
|
78
|
+
async function capture() {
|
|
79
|
+
const source = await locate();
|
|
80
|
+
await safe(source);
|
|
81
|
+
const files = [];
|
|
82
|
+
let bytes = 0;
|
|
83
|
+
async function walk(dir, prefix = '') {
|
|
84
|
+
for (const entry of await entries(dir)) {
|
|
85
|
+
const name = prefix + entry.name;
|
|
86
|
+
if (!selected(name)) continue;
|
|
87
|
+
check(validName(name) && !entry.isSymbolicLink(), 'Unsafe native session entry');
|
|
88
|
+
if (entry.isDirectory()) { await walk(path.join(dir, entry.name), name + '/'); continue; }
|
|
89
|
+
check(entry.isFile(), 'Unsupported native session entry');
|
|
90
|
+
const file = path.join(dir, entry.name);
|
|
91
|
+
const before = await fs.stat(file);
|
|
92
|
+
bytes += before.size;
|
|
93
|
+
check(bytes <= maxBytes && files.length < maxFiles, 'Native session limits exceeded');
|
|
94
|
+
const data = await fs.readFile(file);
|
|
95
|
+
const after = await fs.stat(file);
|
|
96
|
+
check(before.size === data.length && before.mtimeMs === after.mtimeMs, 'Native session changed during capture');
|
|
97
|
+
files.push({ path: name, data: data.toString('base64') });
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
await walk(source);
|
|
101
|
+
const bundle = validate({ version: 1, format, id, source, files });
|
|
102
|
+
await safe(bundleFile);
|
|
103
|
+
await fs.mkdir(path.dirname(bundleFile), { recursive: true, mode: 0o700 });
|
|
104
|
+
await fs.writeFile(bundleFile, JSON.stringify(bundle), { mode: 0o600, flag: 'wx' });
|
|
105
|
+
}
|
|
106
|
+
async function readBundle() {
|
|
107
|
+
const info = await fs.stat(bundleFile);
|
|
108
|
+
check(info.size <= maxBytes * 2, 'Native session bundle exceeds byte limit');
|
|
109
|
+
return validate(JSON.parse(await fs.readFile(bundleFile, 'utf8')));
|
|
110
|
+
}
|
|
111
|
+
async function restore() {
|
|
112
|
+
const bundle = await readBundle();
|
|
113
|
+
const target = format === 'kimi' ? path.join(sessions, workDirKey(cwd), id) : path.join(sessions, id);
|
|
114
|
+
await safe(target);
|
|
115
|
+
if (format === 'kimi') {
|
|
116
|
+
for (const bucket of await entries(sessions)) {
|
|
117
|
+
if (!bucket.isDirectory()) continue;
|
|
118
|
+
const candidate = path.join(sessions, bucket.name, id);
|
|
119
|
+
if (candidate !== target && await fs.lstat(candidate).catch(error => { if (error.code === 'ENOENT') return; throw error; }))
|
|
120
|
+
throw new Error('Kimi session already exists under another workspace; restore in a private sandbox home');
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
await fs.mkdir(path.dirname(target), { recursive: true, mode: 0o700 });
|
|
124
|
+
const temporary = await fs.mkdtemp(path.join(path.dirname(target), '.outpost-session-'));
|
|
125
|
+
function relocate(text, name) {
|
|
126
|
+
if (format === 'copilot' && name === 'workspace.yaml')
|
|
127
|
+
return text.replace(/^(cwd|git_root):.*$/gm, (_, key) => key + ': ' + JSON.stringify(cwd));
|
|
128
|
+
if (format === 'kimi' && name === 'state.json') {
|
|
129
|
+
const meta = JSON.parse(text);
|
|
130
|
+
meta.cwd = cwd;
|
|
131
|
+
for (const [agent, value] of Object.entries(meta.agents)) {
|
|
132
|
+
check(/^[A-Za-z0-9_-]+$/.test(agent) && value && typeof value === 'object', 'Invalid Kimi agent metadata');
|
|
133
|
+
value.homedir = path.join(target, 'agents', agent);
|
|
134
|
+
}
|
|
135
|
+
return JSON.stringify(meta);
|
|
136
|
+
}
|
|
137
|
+
if (format === 'copilot' && name === 'events.jsonl')
|
|
138
|
+
return text.split('\n').map(line => {
|
|
139
|
+
if (!line.trim()) return line;
|
|
140
|
+
const event = JSON.parse(line);
|
|
141
|
+
if (event.type === 'session.start' && event.data?.context) {
|
|
142
|
+
event.data.context.cwd = cwd;
|
|
143
|
+
if (event.data.context.gitRoot) event.data.context.gitRoot = cwd;
|
|
144
|
+
}
|
|
145
|
+
return JSON.stringify(event);
|
|
146
|
+
}).join('\n');
|
|
147
|
+
return undefined;
|
|
148
|
+
}
|
|
149
|
+
let backup;
|
|
150
|
+
try {
|
|
151
|
+
for (const entry of bundle.files) {
|
|
152
|
+
const file = path.join(temporary, entry.path);
|
|
153
|
+
await fs.mkdir(path.dirname(file), { recursive: true, mode: 0o700 });
|
|
154
|
+
const data = Buffer.from(entry.data, 'base64');
|
|
155
|
+
const textFile = format === 'kimi' ? entry.path === 'state.json' : ['events.jsonl', 'workspace.yaml'].includes(entry.path);
|
|
156
|
+
const moved = textFile ? relocate(data.toString('utf8'), entry.path) : undefined;
|
|
157
|
+
await fs.writeFile(file, moved === undefined ? data : moved, { mode: 0o600, flag: 'wx' });
|
|
158
|
+
}
|
|
159
|
+
if (await fs.lstat(target).catch(error => { if (error.code === 'ENOENT') return; throw error; })) {
|
|
160
|
+
backup = path.join(base, '.outpost-recovery', id + '-' + randomUUID());
|
|
161
|
+
await fs.mkdir(path.dirname(backup), { recursive: true, mode: 0o700 });
|
|
162
|
+
await safe(backup);
|
|
163
|
+
await fs.rename(target, backup);
|
|
164
|
+
}
|
|
165
|
+
await fs.rename(temporary, target);
|
|
166
|
+
} catch (error) {
|
|
167
|
+
if (backup) await fs.rename(backup, target);
|
|
168
|
+
throw error;
|
|
169
|
+
} finally { await fs.rm(temporary, { recursive: true, force: true }); }
|
|
170
|
+
}
|
|
171
|
+
({ capture, restore, validate: readBundle }[mode]()).catch(error => { process.stderr.write(error.message + '\n'); process.exitCode = 1; });
|
|
172
|
+
`;
|
|
173
|
+
//# sourceMappingURL=session-bundle.constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-bundle.constants.js","sourceRoot":"","sources":["../../../src/infrastructure/conversations/session-bundle.constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,CAAC;IAC/C,KAAK,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI;IACvB,KAAK,EAAE,IAAI;CACZ,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuK5C,CAAC","sourcesContent":["export const sessionBundleLimits = Object.freeze({\n bytes: 64 * 1024 * 1024,\n files: 4096,\n});\n\nexport const sessionBundleScript = String.raw`\nconst fs = require('node:fs/promises');\nconst path = require('node:path');\nconst { createHash, randomUUID } = require('node:crypto');\nconst [mode, format, id, home, cwd, bundleFile, maxBytesText, maxFilesText] = process.argv.slice(1);\nconst maxBytes = Number(maxBytesText), maxFiles = Number(maxFilesText);\nfunction check(ok, message) { if (!ok) throw new Error(message); }\ncheck(format === 'copilot' || format === 'kimi', 'Unsupported native session format');\ncheck(/^[A-Za-z0-9_-]+$/.test(id), 'Invalid conversation identifier');\nconst base = format === 'kimi'\n ? (process.env.KIMI_CODE_HOME || path.join(home, '.kimi-code'))\n : (process.env.COPILOT_HOME || path.join(home, '.copilot'));\nconst sessions = path.join(base, format === 'kimi' ? 'sessions' : 'session-state');\nasync function entries(dir) {\n try { return await fs.readdir(dir, { withFileTypes: true }); }\n catch (error) { if (error.code === 'ENOENT') return []; throw error; }\n}\nasync function safe(file) {\n for (let at = file;; at = path.dirname(at)) {\n const info = await fs.lstat(at).catch(error => { if (error.code === 'ENOENT') return; throw error; });\n check(!info?.isSymbolicLink(), 'Native session paths must not traverse symlinks');\n if (at === path.dirname(at)) break;\n }\n}\nasync function locate() {\n await safe(sessions);\n if (format === 'copilot') return path.join(sessions, id);\n const found = [];\n for (const bucket of await entries(sessions)) {\n if (!bucket.isDirectory()) continue;\n const candidate = path.join(sessions, bucket.name, id);\n const info = await fs.lstat(candidate).catch(error => { if (error.code === 'ENOENT') return; throw error; });\n if (info) { check(info.isDirectory(), 'Invalid native session directory'); found.push(candidate); }\n }\n check(found.length === 1, 'Kimi session is missing or ambiguous');\n return found[0];\n}\nfunction selected(name) {\n if (format === 'copilot') return /^(?:(?:events\\.jsonl|workspace\\.yaml|plan\\.md)$|(?:checkpoints|files)(?:\\/|$))/.test(name);\n return !/^(logs|tasks|cron|notify)(\\/|$)/.test(name) && !/(^|\\/)[^/]*\\.lock$/.test(name);\n}\nfunction validName(name) {\n return typeof name === 'string' && name.length > 0 && !name.includes('\\\\') && !name.includes('\\0') &&\n !path.isAbsolute(name) && !name.split('/').some(p => !p || p === '.' || p === '..' || p.toLowerCase() === '.git');\n}\nfunction validate(bundle) {\n check(bundle && bundle.version === 1 && bundle.format === format && bundle.id === id && typeof bundle.source === 'string' && Array.isArray(bundle.files), 'Invalid native session bundle');\n check(bundle.files.length > 0, 'Native session is missing or incomplete');\n check(bundle.files.length <= maxFiles, 'Native session file limit exceeded');\n let bytes = 0;\n const names = new Set();\n for (const file of bundle.files) {\n check(file && validName(file.path) && selected(file.path) && !names.has(file.path) && typeof file.data === 'string', 'Invalid native session entry');\n const data = Buffer.from(file.data, 'base64');\n check(data.toString('base64') === file.data, 'Invalid native session encoding');\n bytes += data.length;\n check(bytes <= maxBytes, 'Native session byte limit exceeded');\n names.add(file.path);\n }\n const required = format === 'kimi' ? ['state.json', 'agents/main/wire.jsonl'] : ['events.jsonl', 'workspace.yaml'];\n check(required.every(name => names.has(name)), 'Native session is incomplete or uses an unsupported format');\n if (format === 'kimi') {\n const meta = JSON.parse(Buffer.from(bundle.files.find(f => f.path === 'state.json').data, 'base64'));\n check(meta.version === 2 && meta.id === id && typeof meta.cwd === 'string' && meta.agents && typeof meta.agents === 'object', 'Unsupported Kimi session metadata');\n }\n return bundle;\n}\nfunction workDirKey(dir) {\n const normalized = dir.replace(/\\\\/g, '/').replace(/\\/+$/, '');\n let slug = normalized.split('/').pop().toLowerCase().replace(/[^a-z0-9._-]+/g, '-').replace(/^-+|-+$/g, '').slice(0, 40).replace(/^-+|-+$/g, '');\n if (!slug || slug === '.' || slug === '..') slug = 'workspace';\n return 'wd_' + slug + '_' + createHash('sha256').update(normalized).digest('hex').slice(0, 12);\n}\nasync function capture() {\n const source = await locate();\n await safe(source);\n const files = [];\n let bytes = 0;\n async function walk(dir, prefix = '') {\n for (const entry of await entries(dir)) {\n const name = prefix + entry.name;\n if (!selected(name)) continue;\n check(validName(name) && !entry.isSymbolicLink(), 'Unsafe native session entry');\n if (entry.isDirectory()) { await walk(path.join(dir, entry.name), name + '/'); continue; }\n check(entry.isFile(), 'Unsupported native session entry');\n const file = path.join(dir, entry.name);\n const before = await fs.stat(file);\n bytes += before.size;\n check(bytes <= maxBytes && files.length < maxFiles, 'Native session limits exceeded');\n const data = await fs.readFile(file);\n const after = await fs.stat(file);\n check(before.size === data.length && before.mtimeMs === after.mtimeMs, 'Native session changed during capture');\n files.push({ path: name, data: data.toString('base64') });\n }\n }\n await walk(source);\n const bundle = validate({ version: 1, format, id, source, files });\n await safe(bundleFile);\n await fs.mkdir(path.dirname(bundleFile), { recursive: true, mode: 0o700 });\n await fs.writeFile(bundleFile, JSON.stringify(bundle), { mode: 0o600, flag: 'wx' });\n}\nasync function readBundle() {\n const info = await fs.stat(bundleFile);\n check(info.size <= maxBytes * 2, 'Native session bundle exceeds byte limit');\n return validate(JSON.parse(await fs.readFile(bundleFile, 'utf8')));\n}\nasync function restore() {\n const bundle = await readBundle();\n const target = format === 'kimi' ? path.join(sessions, workDirKey(cwd), id) : path.join(sessions, id);\n await safe(target);\n if (format === 'kimi') {\n for (const bucket of await entries(sessions)) {\n if (!bucket.isDirectory()) continue;\n const candidate = path.join(sessions, bucket.name, id);\n if (candidate !== target && await fs.lstat(candidate).catch(error => { if (error.code === 'ENOENT') return; throw error; }))\n throw new Error('Kimi session already exists under another workspace; restore in a private sandbox home');\n }\n }\n await fs.mkdir(path.dirname(target), { recursive: true, mode: 0o700 });\n const temporary = await fs.mkdtemp(path.join(path.dirname(target), '.outpost-session-'));\n function relocate(text, name) {\n if (format === 'copilot' && name === 'workspace.yaml')\n return text.replace(/^(cwd|git_root):.*$/gm, (_, key) => key + ': ' + JSON.stringify(cwd));\n if (format === 'kimi' && name === 'state.json') {\n const meta = JSON.parse(text);\n meta.cwd = cwd;\n for (const [agent, value] of Object.entries(meta.agents)) {\n check(/^[A-Za-z0-9_-]+$/.test(agent) && value && typeof value === 'object', 'Invalid Kimi agent metadata');\n value.homedir = path.join(target, 'agents', agent);\n }\n return JSON.stringify(meta);\n }\n if (format === 'copilot' && name === 'events.jsonl')\n return text.split('\\n').map(line => {\n if (!line.trim()) return line;\n const event = JSON.parse(line);\n if (event.type === 'session.start' && event.data?.context) {\n event.data.context.cwd = cwd;\n if (event.data.context.gitRoot) event.data.context.gitRoot = cwd;\n }\n return JSON.stringify(event);\n }).join('\\n');\n return undefined;\n }\n let backup;\n try {\n for (const entry of bundle.files) {\n const file = path.join(temporary, entry.path);\n await fs.mkdir(path.dirname(file), { recursive: true, mode: 0o700 });\n const data = Buffer.from(entry.data, 'base64');\n const textFile = format === 'kimi' ? entry.path === 'state.json' : ['events.jsonl', 'workspace.yaml'].includes(entry.path);\n const moved = textFile ? relocate(data.toString('utf8'), entry.path) : undefined;\n await fs.writeFile(file, moved === undefined ? data : moved, { mode: 0o600, flag: 'wx' });\n }\n if (await fs.lstat(target).catch(error => { if (error.code === 'ENOENT') return; throw error; })) {\n backup = path.join(base, '.outpost-recovery', id + '-' + randomUUID());\n await fs.mkdir(path.dirname(backup), { recursive: true, mode: 0o700 });\n await safe(backup);\n await fs.rename(target, backup);\n }\n await fs.rename(temporary, target);\n } catch (error) {\n if (backup) await fs.rename(backup, target);\n throw error;\n } finally { await fs.rm(temporary, { recursive: true, force: true }); }\n}\n({ capture, restore, validate: readBundle }[mode]()).catch(error => { process.stderr.write(error.message + '\\n'); process.exitCode = 1; });\n`;\n"]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ConversationStore } from "../../domain/conversation.types.ts";
|
|
2
|
+
import type { Command } from "../../domain/command.types.ts";
|
|
3
|
+
import type { SessionBundleFormat } from "./session-bundle.types.ts";
|
|
4
|
+
export declare function sessionBundleCommand(mode: "capture" | "restore" | "validate", format: SessionBundleFormat, id: string, home: string, cwd: string, file: string): Command;
|
|
5
|
+
export declare function sessionBundlePath(format: SessionBundleFormat, id: string, repository: string, home?: string): string;
|
|
6
|
+
export declare function sessionConversations(format: SessionBundleFormat): ConversationStore;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { access, mkdir, rename, rm } from "node:fs/promises";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { dirname, join, posix } from "node:path";
|
|
5
|
+
import { invariant, OutpostError } from "../../domain/errors.js";
|
|
6
|
+
import { executeProcess, requireSuccess } from "../process.js";
|
|
7
|
+
import { validId } from "./identity.js";
|
|
8
|
+
import { sessionBundleLimits, sessionBundleScript, } from "./session-bundle.constants.js";
|
|
9
|
+
async function sessionOperation(command, invoke) {
|
|
10
|
+
const result = await invoke(command);
|
|
11
|
+
if (result.status !== 0)
|
|
12
|
+
throw new OutpostError("session", `Native session operation failed: ${result.stderr.trim() || "unknown failure"}`);
|
|
13
|
+
}
|
|
14
|
+
export function sessionBundleCommand(mode, format, id, home, cwd, file) {
|
|
15
|
+
validId(id);
|
|
16
|
+
return {
|
|
17
|
+
executable: "node",
|
|
18
|
+
arguments: [
|
|
19
|
+
"-e",
|
|
20
|
+
sessionBundleScript,
|
|
21
|
+
mode,
|
|
22
|
+
format,
|
|
23
|
+
id,
|
|
24
|
+
home,
|
|
25
|
+
cwd,
|
|
26
|
+
file,
|
|
27
|
+
String(sessionBundleLimits.bytes),
|
|
28
|
+
String(sessionBundleLimits.files),
|
|
29
|
+
],
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
export function sessionBundlePath(format, id, repository, home) {
|
|
33
|
+
validId(id);
|
|
34
|
+
return join(home ?? repository, ".outpost", "conversations", format, `${id}.json`);
|
|
35
|
+
}
|
|
36
|
+
export function sessionConversations(format) {
|
|
37
|
+
return {
|
|
38
|
+
name: format,
|
|
39
|
+
async locate(id, repository, home) {
|
|
40
|
+
const file = sessionBundlePath(format, id, repository, home);
|
|
41
|
+
if (await access(file).then(() => true, () => false)) {
|
|
42
|
+
await sessionOperation(sessionBundleCommand("validate", format, id, home ?? homedir(), repository, file), executeProcess);
|
|
43
|
+
return { id, file, format };
|
|
44
|
+
}
|
|
45
|
+
const scratch = `${file}.${randomUUID()}`;
|
|
46
|
+
try {
|
|
47
|
+
await sessionOperation(sessionBundleCommand("capture", format, id, home ?? homedir(), repository, scratch), executeProcess);
|
|
48
|
+
await rename(scratch, file);
|
|
49
|
+
}
|
|
50
|
+
finally {
|
|
51
|
+
await rm(scratch, { force: true });
|
|
52
|
+
}
|
|
53
|
+
return { id, file, format };
|
|
54
|
+
},
|
|
55
|
+
async capture(id, context) {
|
|
56
|
+
const file = sessionBundlePath(format, id, context.repository, context.home);
|
|
57
|
+
const remote = posix.join(context.sandbox.home.replaceAll("\\", "/"), ".outpost", `session-${randomUUID()}.json`);
|
|
58
|
+
const scratch = `${file}.${randomUUID()}`;
|
|
59
|
+
await mkdir(dirname(file), { recursive: true, mode: 0o700 });
|
|
60
|
+
try {
|
|
61
|
+
await sessionOperation(sessionBundleCommand("capture", format, id, context.sandbox.home, context.sandbox.root, remote), context.sandbox.invoke);
|
|
62
|
+
await context.sandbox.download(remote, scratch);
|
|
63
|
+
await rename(scratch, file);
|
|
64
|
+
}
|
|
65
|
+
finally {
|
|
66
|
+
await rm(scratch, { force: true });
|
|
67
|
+
await requireSuccess({
|
|
68
|
+
executable: "node",
|
|
69
|
+
arguments: [
|
|
70
|
+
"-e",
|
|
71
|
+
"require('node:fs').rmSync(process.argv[1], {force:true})",
|
|
72
|
+
remote,
|
|
73
|
+
],
|
|
74
|
+
}, context.sandbox.invoke);
|
|
75
|
+
}
|
|
76
|
+
return { id, file, format };
|
|
77
|
+
},
|
|
78
|
+
async restore(record, context) {
|
|
79
|
+
invariant(record.format === format, "Conversation format does not match its storage");
|
|
80
|
+
const remote = posix.join(context.sandbox.home.replaceAll("\\", "/"), ".outpost", `restore-${randomUUID()}.json`);
|
|
81
|
+
try {
|
|
82
|
+
await context.sandbox.upload(record.file, remote);
|
|
83
|
+
await sessionOperation(sessionBundleCommand("restore", format, record.id, context.sandbox.home, context.sandbox.root, remote), context.sandbox.invoke);
|
|
84
|
+
}
|
|
85
|
+
finally {
|
|
86
|
+
await requireSuccess({
|
|
87
|
+
executable: "node",
|
|
88
|
+
arguments: [
|
|
89
|
+
"-e",
|
|
90
|
+
"require('node:fs').rmSync(process.argv[1], {force:true})",
|
|
91
|
+
remote,
|
|
92
|
+
],
|
|
93
|
+
}, context.sandbox.invoke);
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=session-bundle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-bundle.js","sourceRoot":"","sources":["../../../src/infrastructure/conversations/session-bundle.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { access, mkdir, rename, rm } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { dirname, join, posix } from \"node:path\";\nimport type { ConversationStore } from \"../../domain/conversation.types.ts\";\nimport type { Command, CommandResult } from \"../../domain/command.types.ts\";\nimport { invariant, OutpostError } from \"../../domain/errors.ts\";\nimport { executeProcess, requireSuccess } from \"../process.ts\";\nimport { validId } from \"./identity.ts\";\nimport {\n sessionBundleLimits,\n sessionBundleScript,\n} from \"./session-bundle.constants.ts\";\nimport type { SessionBundleFormat } from \"./session-bundle.types.ts\";\n\nasync function sessionOperation(\n command: Command,\n invoke: (command: Command) => Promise<CommandResult>,\n): Promise<void> {\n const result = await invoke(command);\n if (result.status !== 0)\n throw new OutpostError(\n \"session\",\n `Native session operation failed: ${result.stderr.trim() || \"unknown failure\"}`,\n );\n}\n\nexport function sessionBundleCommand(\n mode: \"capture\" | \"restore\" | \"validate\",\n format: SessionBundleFormat,\n id: string,\n home: string,\n cwd: string,\n file: string,\n): Command {\n validId(id);\n return {\n executable: \"node\",\n arguments: [\n \"-e\",\n sessionBundleScript,\n mode,\n format,\n id,\n home,\n cwd,\n file,\n String(sessionBundleLimits.bytes),\n String(sessionBundleLimits.files),\n ],\n };\n}\n\nexport function sessionBundlePath(\n format: SessionBundleFormat,\n id: string,\n repository: string,\n home?: string,\n): string {\n validId(id);\n return join(\n home ?? repository,\n \".outpost\",\n \"conversations\",\n format,\n `${id}.json`,\n );\n}\n\nexport function sessionConversations(\n format: SessionBundleFormat,\n): ConversationStore {\n return {\n name: format,\n async locate(id, repository, home) {\n const file = sessionBundlePath(format, id, repository, home);\n if (\n await access(file).then(\n () => true,\n () => false,\n )\n ) {\n await sessionOperation(\n sessionBundleCommand(\n \"validate\",\n format,\n id,\n home ?? homedir(),\n repository,\n file,\n ),\n executeProcess,\n );\n return { id, file, format };\n }\n const scratch = `${file}.${randomUUID()}`;\n try {\n await sessionOperation(\n sessionBundleCommand(\n \"capture\",\n format,\n id,\n home ?? homedir(),\n repository,\n scratch,\n ),\n executeProcess,\n );\n await rename(scratch, file);\n } finally {\n await rm(scratch, { force: true });\n }\n return { id, file, format };\n },\n async capture(id, context) {\n const file = sessionBundlePath(\n format,\n id,\n context.repository,\n context.home,\n );\n const remote = posix.join(\n context.sandbox.home.replaceAll(\"\\\\\", \"/\"),\n \".outpost\",\n `session-${randomUUID()}.json`,\n );\n const scratch = `${file}.${randomUUID()}`;\n await mkdir(dirname(file), { recursive: true, mode: 0o700 });\n try {\n await sessionOperation(\n sessionBundleCommand(\n \"capture\",\n format,\n id,\n context.sandbox.home,\n context.sandbox.root,\n remote,\n ),\n context.sandbox.invoke,\n );\n await context.sandbox.download(remote, scratch);\n await rename(scratch, file);\n } finally {\n await rm(scratch, { force: true });\n await requireSuccess(\n {\n executable: \"node\",\n arguments: [\n \"-e\",\n \"require('node:fs').rmSync(process.argv[1], {force:true})\",\n remote,\n ],\n },\n context.sandbox.invoke,\n );\n }\n return { id, file, format };\n },\n async restore(record, context) {\n invariant(\n record.format === format,\n \"Conversation format does not match its storage\",\n );\n const remote = posix.join(\n context.sandbox.home.replaceAll(\"\\\\\", \"/\"),\n \".outpost\",\n `restore-${randomUUID()}.json`,\n );\n try {\n await context.sandbox.upload(record.file, remote);\n await sessionOperation(\n sessionBundleCommand(\n \"restore\",\n format,\n record.id,\n context.sandbox.home,\n context.sandbox.root,\n remote,\n ),\n context.sandbox.invoke,\n );\n } finally {\n await requireSuccess(\n {\n executable: \"node\",\n arguments: [\n \"-e\",\n \"require('node:fs').rmSync(process.argv[1], {force:true})\",\n remote,\n ],\n },\n context.sandbox.invoke,\n );\n }\n },\n };\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type SessionBundleFormat = "copilot" | "kimi";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-bundle.types.js","sourceRoot":"","sources":["../../../src/infrastructure/conversations/session-bundle.types.ts"],"names":[],"mappings":"","sourcesContent":["export type SessionBundleFormat = \"copilot\" | \"kimi\";\n"]}
|
|
@@ -29,8 +29,10 @@ export const conversations = {
|
|
|
29
29
|
validId(id);
|
|
30
30
|
return join(home, ".claude", "projects", projectKey(resolve(repository)), `${id}.jsonl`);
|
|
31
31
|
},
|
|
32
|
-
directory(format, repository, home
|
|
33
|
-
|
|
32
|
+
directory(format, repository, home) {
|
|
33
|
+
if (format === "copilot" || format === "kimi")
|
|
34
|
+
return join(home ?? repository, ".outpost", "conversations", format);
|
|
35
|
+
return conversationLayout(format).directory(repository, home ?? homedir());
|
|
34
36
|
},
|
|
35
37
|
destination: remotePath,
|
|
36
38
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversations.js","sourceRoot":"","sources":["../../src/infrastructure/conversations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AACtE,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAOjE,OAAO,EACL,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEjE,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,WAAW,EAAE,sBAAsB;IACnC,MAAM,EAAE,mBAAmB;IAC3B,OAAO,EAAE,oBAAoB;IAC7B,MAAM,EAAE,kBAAkB;IAC1B,OAAO,EAAE,mBAAmB;IAC5B,OAAO,EAAE,mBAAmB;IAC5B,OAAO,EAAE,kBAAkB;IAC3B,UAAU;IACV,UAAU,CAAC,EAAU,EAAE,UAAkB,EAAE,IAAI,GAAG,OAAO,EAAE;QACzD,OAAO,CAAC,EAAE,CAAC,CAAC;QACZ,OAAO,IAAI,CACT,IAAI,EACJ,SAAS,EACT,UAAU,EACV,UAAU,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,EAC/B,GAAG,EAAE,QAAQ,CACd,CAAC;IACJ,CAAC;IACD,SAAS,CACP,MAA0B,EAC1B,UAAkB,EAClB,IAAI,
|
|
1
|
+
{"version":3,"file":"conversations.js","sourceRoot":"","sources":["../../src/infrastructure/conversations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AACtE,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAOjE,OAAO,EACL,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEjE,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,WAAW,EAAE,sBAAsB;IACnC,MAAM,EAAE,mBAAmB;IAC3B,OAAO,EAAE,oBAAoB;IAC7B,MAAM,EAAE,kBAAkB;IAC1B,OAAO,EAAE,mBAAmB;IAC5B,OAAO,EAAE,mBAAmB;IAC5B,OAAO,EAAE,kBAAkB;IAC3B,UAAU;IACV,UAAU,CAAC,EAAU,EAAE,UAAkB,EAAE,IAAI,GAAG,OAAO,EAAE;QACzD,OAAO,CAAC,EAAE,CAAC,CAAC;QACZ,OAAO,IAAI,CACT,IAAI,EACJ,SAAS,EACT,UAAU,EACV,UAAU,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,EAC/B,GAAG,EAAE,QAAQ,CACd,CAAC;IACJ,CAAC;IACD,SAAS,CACP,MAA0B,EAC1B,UAAkB,EAClB,IAAa;QAEb,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,MAAM;YAC3C,OAAO,IAAI,CAAC,IAAI,IAAI,UAAU,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,CAAC,CAAC;QACvE,OAAO,kBAAkB,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,IAAI,OAAO,EAAE,CAAC,CAAC;IAC7E,CAAC;IACD,WAAW,EAAE,UAAU;CACxB,CAAC","sourcesContent":["import { transportConversations } from \"./transport-conversations.ts\";\nimport { homedir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\nimport type { ConversationFormat } from \"./conversations.types.ts\";\nimport { captureConversation } from \"./conversations/capture.ts\";\nimport { conversationLayout } from \"./conversations/layout.ts\";\nimport { locateConversation } from \"./conversations/locate.ts\";\nimport { harnessConversations } from \"./conversations/harness-store.ts\";\nimport { nativeConversations } from \"./conversations/native-store.ts\";\nimport { projectKey, remotePath, validId } from \"./conversations/paths.ts\";\nimport { relocateTranscript } from \"./conversations/relocate.ts\";\nimport { restoreConversation } from \"./conversations/restore.ts\";\n\nexport type {\n ConversationFormat,\n ConversationLocation,\n StoredConversationFormat,\n} from \"./conversations.types.ts\";\nexport {\n harnessConversations,\n harnessTranscriptPath,\n} from \"./conversations/harness-store.ts\";\nexport { captureConversation } from \"./conversations/capture.ts\";\nexport { locateConversation } from \"./conversations/locate.ts\";\nexport { nativeConversations } from \"./conversations/native-store.ts\";\nexport { projectKey } from \"./conversations/paths.ts\";\nexport { relocateTranscript } from \"./conversations/relocate.ts\";\nexport { restoreConversation } from \"./conversations/restore.ts\";\n\nexport const conversations = {\n transported: transportConversations,\n native: nativeConversations,\n harness: harnessConversations,\n locate: locateConversation,\n capture: captureConversation,\n restore: restoreConversation,\n rewrite: relocateTranscript,\n projectKey,\n claudePath(id: string, repository: string, home = homedir()): string {\n validId(id);\n return join(\n home,\n \".claude\",\n \"projects\",\n projectKey(resolve(repository)),\n `${id}.jsonl`,\n );\n },\n directory(\n format: ConversationFormat,\n repository: string,\n home?: string,\n ): string {\n if (format === \"copilot\" || format === \"kimi\")\n return join(home ?? repository, \".outpost\", \"conversations\", format);\n return conversationLayout(format).directory(repository, home ?? homedir());\n },\n destination: remotePath,\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversations.types.js","sourceRoot":"","sources":["../../src/infrastructure/conversations.types.ts"],"names":[],"mappings":"","sourcesContent":["export type ConversationFormat = \"claude\" | \"codex\";\n\nexport type StoredConversationFormat = ConversationFormat | \"harness\";\n\nexport interface ConversationLocation {\n readonly id: string;\n readonly file: string;\n readonly format: ConversationFormat;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"conversations.types.js","sourceRoot":"","sources":["../../src/infrastructure/conversations.types.ts"],"names":[],"mappings":"","sourcesContent":["export type ConversationFormat = \"claude\" | \"codex\" | \"copilot\" | \"kimi\";\n\nexport type StoredConversationFormat = ConversationFormat | \"harness\";\n\nexport interface ConversationLocation {\n readonly id: string;\n readonly file: string;\n readonly format: ConversationFormat;\n}\n"]}
|
|
@@ -1,32 +1,40 @@
|
|
|
1
|
+
import { agentObservation } from "../domain/agent-observation.js";
|
|
2
|
+
import { createObservationHub } from "../domain/observation.js";
|
|
1
3
|
export function createReporter(handlers, options = {}) {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
4
|
+
const hub = createObservationHub({
|
|
5
|
+
...(options.capacity === undefined ? {} : { capacity: options.capacity }),
|
|
6
|
+
...(options.deliveryTimeoutMs === undefined
|
|
7
|
+
? {}
|
|
8
|
+
: { deliveryTimeoutMs: options.deliveryTimeoutMs }),
|
|
9
|
+
sinks: [
|
|
10
|
+
{
|
|
11
|
+
async observe(value) {
|
|
12
|
+
const event = agentObservation(value);
|
|
13
|
+
if (!event)
|
|
14
|
+
return;
|
|
15
|
+
const handler = handlers[event.kind];
|
|
16
|
+
try {
|
|
17
|
+
await handler?.(event);
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
try {
|
|
21
|
+
await options.onError?.(error, event);
|
|
22
|
+
}
|
|
23
|
+
catch { }
|
|
24
|
+
throw error;
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
});
|
|
5
30
|
const report = (event) => {
|
|
6
|
-
|
|
7
|
-
if (!handler)
|
|
8
|
-
return;
|
|
9
|
-
pending = pending.then(async () => {
|
|
10
|
-
try {
|
|
11
|
-
await handler(event);
|
|
12
|
-
}
|
|
13
|
-
catch (error) {
|
|
14
|
-
if (!failed) {
|
|
15
|
-
failed = true;
|
|
16
|
-
failure = error;
|
|
17
|
-
}
|
|
18
|
-
try {
|
|
19
|
-
await options.onError?.(error, event);
|
|
20
|
-
}
|
|
21
|
-
catch { }
|
|
22
|
-
}
|
|
23
|
-
});
|
|
31
|
+
hub.child({ pass: event.pass }).emit("agent", event);
|
|
24
32
|
};
|
|
25
33
|
return Object.assign(report, {
|
|
26
34
|
async flush() {
|
|
27
|
-
await
|
|
28
|
-
if (
|
|
29
|
-
throw
|
|
35
|
+
await hub.flush();
|
|
36
|
+
if (hub.errors.length)
|
|
37
|
+
throw hub.errors[0];
|
|
30
38
|
},
|
|
31
39
|
});
|
|
32
40
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"custom-reporter.js","sourceRoot":"","sources":["../../src/infrastructure/custom-reporter.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"custom-reporter.js","sourceRoot":"","sources":["../../src/infrastructure/custom-reporter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAQhE,MAAM,UAAU,cAAc,CAC5B,QAA0B,EAC1B,UAAiC,EAAE;IAEnC,MAAM,GAAG,GAAG,oBAAoB,CAAC;QAC/B,GAAG,CAAC,OAAO,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC;QACzE,GAAG,CAAC,OAAO,CAAC,iBAAiB,KAAK,SAAS;YACzC,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,iBAAiB,EAAE,OAAO,CAAC,iBAAiB,EAAE,CAAC;QACrD,KAAK,EAAE;YACL;gBACE,KAAK,CAAC,OAAO,CAAC,KAAK;oBACjB,MAAM,KAAK,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;oBACtC,IAAI,CAAC,KAAK;wBAAE,OAAO;oBACnB,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAC8B,CAAC;oBAClE,IAAI,CAAC;wBACH,MAAM,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC;oBACzB,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBACf,IAAI,CAAC;4BACH,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;wBACxC,CAAC;wBAAC,MAAM,CAAC,CAAA,CAAC;wBACV,MAAM,KAAK,CAAC;oBACd,CAAC;gBACH,CAAC;aACF;SACF;KACF,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,CAAC,KAAuB,EAAQ,EAAE;QAC/C,GAAG,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACvD,CAAC,CAAC;IACF,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE;QAC3B,KAAK,CAAC,KAAK;YACT,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC;YAClB,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM;gBAAE,MAAM,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC7C,CAAC;KACF,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { agentObservation } from \"../domain/agent-observation.ts\";\nimport { createObservationHub } from \"../domain/observation.ts\";\nimport type { AgentObservation } from \"../domain/agent.types.ts\";\nimport type {\n CustomReporter,\n CustomReporterOptions,\n ReporterHandlers,\n} from \"./custom-reporter.types.ts\";\n\nexport function createReporter(\n handlers: ReporterHandlers,\n options: CustomReporterOptions = {},\n): CustomReporter {\n const hub = createObservationHub({\n ...(options.capacity === undefined ? {} : { capacity: options.capacity }),\n ...(options.deliveryTimeoutMs === undefined\n ? {}\n : { deliveryTimeoutMs: options.deliveryTimeoutMs }),\n sinks: [\n {\n async observe(value) {\n const event = agentObservation(value);\n if (!event) return;\n const handler = handlers[event.kind] as\n ((event: AgentObservation) => void | Promise<void>) | undefined;\n try {\n await handler?.(event);\n } catch (error) {\n try {\n await options.onError?.(error, event);\n } catch {}\n throw error;\n }\n },\n },\n ],\n });\n const report = (event: AgentObservation): void => {\n hub.child({ pass: event.pass }).emit(\"agent\", event);\n };\n return Object.assign(report, {\n async flush() {\n await hub.flush();\n if (hub.errors.length) throw hub.errors[0];\n },\n });\n}\n"]}
|
|
@@ -5,6 +5,8 @@ export type ReporterHandlers = {
|
|
|
5
5
|
}>) => void | Promise<void>;
|
|
6
6
|
};
|
|
7
7
|
export interface CustomReporterOptions {
|
|
8
|
+
readonly capacity?: number;
|
|
9
|
+
readonly deliveryTimeoutMs?: number;
|
|
8
10
|
readonly onError?: (error: unknown, event: AgentObservation) => void | Promise<void>;
|
|
9
11
|
}
|
|
10
12
|
export interface CustomReporter {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"custom-reporter.types.js","sourceRoot":"","sources":["../../src/infrastructure/custom-reporter.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { AgentObservation } from \"../domain/agent.types.ts\";\n\nexport type ReporterHandlers = {\n readonly [Kind in AgentObservation[\"kind\"]]?: (\n event: Extract<AgentObservation, { kind: Kind }>,\n ) => void | Promise<void>;\n};\n\nexport interface CustomReporterOptions {\n readonly onError?: (\n error: unknown,\n event: AgentObservation,\n ) => void | Promise<void>;\n}\n\nexport interface CustomReporter {\n (event: AgentObservation): void;\n flush(): Promise<void>;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"custom-reporter.types.js","sourceRoot":"","sources":["../../src/infrastructure/custom-reporter.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { AgentObservation } from \"../domain/agent.types.ts\";\n\nexport type ReporterHandlers = {\n readonly [Kind in AgentObservation[\"kind\"]]?: (\n event: Extract<AgentObservation, { kind: Kind }>,\n ) => void | Promise<void>;\n};\n\nexport interface CustomReporterOptions {\n readonly capacity?: number;\n readonly deliveryTimeoutMs?: number;\n readonly onError?: (\n error: unknown,\n event: AgentObservation,\n ) => void | Promise<void>;\n}\n\nexport interface CustomReporter {\n (event: AgentObservation): void;\n flush(): Promise<void>;\n}\n"]}
|
|
@@ -4,4 +4,4 @@ export declare const gitDefaults: Readonly<{
|
|
|
4
4
|
hashLength: 12;
|
|
5
5
|
labelLength: 48;
|
|
6
6
|
}>;
|
|
7
|
-
export declare const runtimeExclusions: readonly ["/.outpost/workspaces/", "/.outpost/locks/", "/.outpost/recovery/", "/.outpost/logs/", "/.outpost/conversations/"];
|
|
7
|
+
export declare const runtimeExclusions: readonly ["/.outpost/workspaces/", "/.outpost/locks/", "/.outpost/recovery/", "/.outpost/logs/", "/.outpost/storage/", "/.outpost/conversations/"];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git.constants.js","sourceRoot":"","sources":["../../../src/infrastructure/git/git.constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC;IACvC,UAAU,EAAE,MAAM;IAClB,WAAW,EAAE,UAAU;IACvB,UAAU,EAAE,EAAE;IACd,WAAW,EAAE,EAAE;CAChB,CAAC,CAAC;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,uBAAuB;IACvB,kBAAkB;IAClB,qBAAqB;IACrB,iBAAiB;IACjB,0BAA0B;CAClB,CAAC","sourcesContent":["export const gitDefaults = Object.freeze({\n deadlineMs: 30_000,\n retainBytes: 16_777_216,\n hashLength: 12,\n labelLength: 48,\n});\nexport const runtimeExclusions = [\n \"/.outpost/workspaces/\",\n \"/.outpost/locks/\",\n \"/.outpost/recovery/\",\n \"/.outpost/logs/\",\n \"/.outpost/conversations/\",\n] as const;\n"]}
|
|
1
|
+
{"version":3,"file":"git.constants.js","sourceRoot":"","sources":["../../../src/infrastructure/git/git.constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC;IACvC,UAAU,EAAE,MAAM;IAClB,WAAW,EAAE,UAAU;IACvB,UAAU,EAAE,EAAE;IACd,WAAW,EAAE,EAAE;CAChB,CAAC,CAAC;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,uBAAuB;IACvB,kBAAkB;IAClB,qBAAqB;IACrB,iBAAiB;IACjB,oBAAoB;IACpB,0BAA0B;CAClB,CAAC","sourcesContent":["export const gitDefaults = Object.freeze({\n deadlineMs: 30_000,\n retainBytes: 16_777_216,\n hashLength: 12,\n labelLength: 48,\n});\nexport const runtimeExclusions = [\n \"/.outpost/workspaces/\",\n \"/.outpost/locks/\",\n \"/.outpost/recovery/\",\n \"/.outpost/logs/\",\n \"/.outpost/storage/\",\n \"/.outpost/conversations/\",\n] as const;\n"]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { observedOperation } from "../../domain/observed-operation.js";
|
|
1
2
|
import { join } from "node:path";
|
|
2
3
|
import { OutpostError } from "../../domain/errors.js";
|
|
3
4
|
import { inside } from "../files.js";
|
|
@@ -14,7 +15,7 @@ export function workspaceLease(record, options, unlock) {
|
|
|
14
15
|
const current = (await git(repository, ["symbolic-ref", "--short", "HEAD"])).trim();
|
|
15
16
|
if (current !== baseBranch)
|
|
16
17
|
throw new OutpostError("conflict", "Host branch changed during the job", { expected: baseBranch, current, directory: workdir });
|
|
17
|
-
const releaseMerge = await lock(repository, `merge:${baseBranch}`);
|
|
18
|
+
const releaseMerge = await observedOperation(options.observation, "git", "integration.lock", async () => lock(repository, `merge:${baseBranch}`));
|
|
18
19
|
try {
|
|
19
20
|
await git(repository, ["merge", "--no-edit", branch], options.limits?.mergeMs);
|
|
20
21
|
}
|
|
@@ -22,7 +23,7 @@ export function workspaceLease(record, options, unlock) {
|
|
|
22
23
|
throw new OutpostError("conflict", "Automatic integration failed; workspace retained", { directory: workdir, branch }, cause);
|
|
23
24
|
}
|
|
24
25
|
finally {
|
|
25
|
-
await releaseMerge();
|
|
26
|
+
await observedOperation(options.observation, "git", "integration.unlock", async () => releaseMerge());
|
|
26
27
|
}
|
|
27
28
|
},
|
|
28
29
|
dispose(preserve = false) {
|
|
@@ -57,7 +58,7 @@ export function workspaceLease(record, options, unlock) {
|
|
|
57
58
|
return {};
|
|
58
59
|
}
|
|
59
60
|
finally {
|
|
60
|
-
await unlock();
|
|
61
|
+
await observedOperation(options.observation, "git", "workspace.unlock", async () => unlock());
|
|
61
62
|
}
|
|
62
63
|
})();
|
|
63
64
|
return disposal;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace-lease.js","sourceRoot":"","sources":["../../../src/infrastructure/git/workspace-lease.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAKtD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AACnC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAMjC,MAAM,UAAU,cAAc,CAC5B,MAAuB,EACvB,OAAgC,EAChC,MAA2B;IAE3B,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;IAC9E,IAAI,QAAuC,CAAC;IAC5C,OAAO;QACL,GAAG,MAAM;QACT,KAAK,CAAC,SAAS;YACb,IAAI,MAAM,CAAC,IAAI,KAAK,WAAW;gBAAE,OAAO;YACxC,MAAM,OAAO,GAAG,CACd,MAAM,GAAG,CAAC,UAAU,EAAE,CAAC,cAAc,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,CAC3D,CAAC,IAAI,EAAE,CAAC;YACT,IAAI,OAAO,KAAK,UAAU;gBACxB,MAAM,IAAI,YAAY,CACpB,UAAU,EACV,oCAAoC,EACpC,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,CACtD,CAAC;YACJ,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE,SAAS,UAAU,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"workspace-lease.js","sourceRoot":"","sources":["../../../src/infrastructure/git/workspace-lease.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AACvE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAKtD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AACnC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAMjC,MAAM,UAAU,cAAc,CAC5B,MAAuB,EACvB,OAAgC,EAChC,MAA2B;IAE3B,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;IAC9E,IAAI,QAAuC,CAAC;IAC5C,OAAO;QACL,GAAG,MAAM;QACT,KAAK,CAAC,SAAS;YACb,IAAI,MAAM,CAAC,IAAI,KAAK,WAAW;gBAAE,OAAO;YACxC,MAAM,OAAO,GAAG,CACd,MAAM,GAAG,CAAC,UAAU,EAAE,CAAC,cAAc,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,CAC3D,CAAC,IAAI,EAAE,CAAC;YACT,IAAI,OAAO,KAAK,UAAU;gBACxB,MAAM,IAAI,YAAY,CACpB,UAAU,EACV,oCAAoC,EACpC,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,CACtD,CAAC;YACJ,MAAM,YAAY,GAAG,MAAM,iBAAiB,CAC1C,OAAO,CAAC,WAAW,EACnB,KAAK,EACL,kBAAkB,EAClB,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,UAAU,EAAE,CAAC,CACpD,CAAC;YACF,IAAI,CAAC;gBACH,MAAM,GAAG,CACP,UAAU,EACV,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,CAAC,EAC9B,OAAO,CAAC,MAAM,EAAE,OAAO,CACxB,CAAC;YACJ,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,IAAI,YAAY,CACpB,UAAU,EACV,kDAAkD,EAClD,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,EAC9B,KAAK,CACN,CAAC;YACJ,CAAC;oBAAS,CAAC;gBACT,MAAM,iBAAiB,CACrB,OAAO,CAAC,WAAW,EACnB,KAAK,EACL,oBAAoB,EACpB,KAAK,IAAI,EAAE,CAAC,YAAY,EAAE,CAC3B,CAAC;YACJ,CAAC;QACH,CAAC;QACD,OAAO,CAAC,QAAQ,GAAG,KAAK;YACtB,IAAI,QAAQ;gBAAE,OAAO,QAAQ,CAAC;YAC9B,QAAQ,GAAG,CAAC,KAAK,IAAI,EAAE;gBACrB,IAAI,CAAC;oBACH,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS;wBAAE,OAAO,EAAE,CAAC;oBACzC,IAAI,QAAQ;wBAAE,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,CAAC;oBACpD,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,OAAO,EAAE;wBAClC,cAAc;wBACd,SAAS;wBACT,MAAM;qBACP,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;oBACnB,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE;wBAAE,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,CAAC;oBAC5D,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,OAAO,EAAE;wBAC/B,QAAQ;wBACR,aAAa;wBACb,0BAA0B;wBAC1B,WAAW;qBACZ,CAAC,CAAC;oBACH,IAAI,KAAK,CAAC,IAAI,EAAE;wBAAE,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,CAAC;oBACxD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,UAAU,EAAE,YAAY,CAAC,EAAE,OAAO,CAAC;wBAC9D,MAAM,IAAI,YAAY,CACpB,WAAW,EACX,2CAA2C,CAC5C,CAAC;oBACJ,MAAM,GAAG,CAAC,UAAU,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;oBACvD,IAAI,MAAM,CAAC,IAAI,KAAK,WAAW;wBAC7B,MAAM,GAAG,CAAC,UAAU,EAAE,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,CACnD,GAAG,EAAE,CAAC,SAAS,CAChB,CAAC;oBACJ,OAAO,EAAE,CAAC;gBACZ,CAAC;wBAAS,CAAC;oBACT,MAAM,iBAAiB,CACrB,OAAO,CAAC,WAAW,EACnB,KAAK,EACL,kBAAkB,EAClB,KAAK,IAAI,EAAE,CAAC,MAAM,EAAE,CACrB,CAAC;gBACJ,CAAC;YACH,CAAC,CAAC,EAAE,CAAC;YACL,OAAO,QAAQ,CAAC;QAClB,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import { observedOperation } from \"../../domain/observed-operation.ts\";\nimport { join } from \"node:path\";\nimport { OutpostError } from \"../../domain/errors.ts\";\nimport type {\n Disposal,\n WorkspaceRecord,\n} from \"../../domain/workspace.types.ts\";\nimport { inside } from \"../files.ts\";\nimport { git } from \"./command.ts\";\nimport { lock } from \"./lock.ts\";\nimport type {\n AcquireWorkspaceOptions,\n WorkspaceLease,\n} from \"./workspace.types.ts\";\n\nexport function workspaceLease(\n record: WorkspaceRecord,\n options: AcquireWorkspaceOptions,\n unlock: () => Promise<void>,\n): WorkspaceLease {\n const { policy, repository, baseBranch, branch, directory: workdir } = record;\n let disposal: Promise<Disposal> | undefined;\n return {\n ...record,\n async integrate() {\n if (policy.mode !== \"integrate\") return;\n const current = (\n await git(repository, [\"symbolic-ref\", \"--short\", \"HEAD\"])\n ).trim();\n if (current !== baseBranch)\n throw new OutpostError(\n \"conflict\",\n \"Host branch changed during the job\",\n { expected: baseBranch, current, directory: workdir },\n );\n const releaseMerge = await observedOperation(\n options.observation,\n \"git\",\n \"integration.lock\",\n async () => lock(repository, `merge:${baseBranch}`),\n );\n try {\n await git(\n repository,\n [\"merge\", \"--no-edit\", branch],\n options.limits?.mergeMs,\n );\n } catch (cause) {\n throw new OutpostError(\n \"conflict\",\n \"Automatic integration failed; workspace retained\",\n { directory: workdir, branch },\n cause,\n );\n } finally {\n await observedOperation(\n options.observation,\n \"git\",\n \"integration.unlock\",\n async () => releaseMerge(),\n );\n }\n },\n dispose(preserve = false) {\n if (disposal) return disposal;\n disposal = (async () => {\n try {\n if (policy.mode === \"current\") return {};\n if (preserve) return { retainedDirectory: workdir };\n const attached = await git(workdir, [\n \"symbolic-ref\",\n \"--quiet\",\n \"HEAD\",\n ]).catch(() => \"\");\n if (!attached.trim()) return { retainedDirectory: workdir };\n const dirty = await git(workdir, [\n \"status\",\n \"--porcelain\",\n \"--untracked-files=normal\",\n \"--ignored\",\n ]);\n if (dirty.trim()) return { retainedDirectory: workdir };\n if (!inside(join(repository, \".outpost\", \"workspaces\"), workdir))\n throw new OutpostError(\n \"workspace\",\n \"Refusing to remove an unmanaged workspace\",\n );\n await git(repository, [\"worktree\", \"remove\", workdir]);\n if (policy.mode === \"integrate\")\n await git(repository, [\"branch\", \"-d\", branch]).catch(\n () => undefined,\n );\n return {};\n } finally {\n await observedOperation(\n options.observation,\n \"git\",\n \"workspace.unlock\",\n async () => unlock(),\n );\n }\n })();\n return disposal;\n },\n };\n}\n"]}
|