humanish 0.106.0 → 0.107.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/AGENTS.md +4 -2
- package/ARCHITECTURE.md +17 -16
- package/CHANGELOG.md +24 -0
- package/CONTEXT.md +42 -39
- package/CONTRIBUTING.md +8 -6
- package/README.md +8 -3
- package/dist/actors/codex/app-server-client.js +2 -1
- package/dist/actors/codex/app-server-trace.d.ts +0 -1
- package/dist/actors/codex/app-server-trace.js +1 -3
- package/dist/actors/codex/app-server.js +2 -1
- package/dist/actors/codex/protocol-compat.d.ts +27 -0
- package/dist/actors/codex/protocol-compat.js +357 -0
- package/dist/actors/codex/protocol-contract.d.ts +61 -0
- package/dist/actors/codex/protocol-contract.js +471 -0
- package/dist/actors/codex/qualified-versions.d.ts +31 -4
- package/dist/actors/codex/qualified-versions.js +51 -6
- package/dist/actors/codex/restricted-executable.d.ts +24 -0
- package/dist/actors/codex/restricted-executable.js +97 -22
- package/dist/actors/codex/restricted-launch.d.ts +7 -1
- package/dist/actors/codex/restricted-launch.js +42 -3
- package/dist/actors/codex/restricted-notifications.d.ts +101 -0
- package/dist/actors/codex/restricted-notifications.js +277 -0
- package/dist/actors/codex/restricted-participant.d.ts +30 -0
- package/dist/actors/codex/restricted-participant.js +60 -2
- package/dist/actors/codex/restricted-policy.d.ts +9 -1
- package/dist/actors/codex/restricted-session.d.ts +14 -1
- package/dist/actors/codex/restricted-session.js +50 -17
- package/dist/actors/codex/restricted-transport.d.ts +29 -0
- package/dist/actors/codex/restricted-transport.js +139 -27
- package/dist/actors/codex/restricted-turn.d.ts +19 -4
- package/dist/actors/codex/restricted-turn.js +43 -30
- package/dist/actors/computer-use/actor.d.ts +1 -1
- package/dist/actors/computer-use/actor.js +4 -4
- package/dist/actors/computer-use/loop/backstop.js +1 -1
- package/dist/actors/computer-use/loop/ending.d.ts +2 -2
- package/dist/actors/computer-use/loop/ending.js +2 -2
- package/dist/actors/computer-use/loop/spend.d.ts +1 -1
- package/dist/actors/computer-use/loop/spend.js +3 -3
- package/dist/actors/computer-use/loop/trace.js +2 -2
- package/dist/actors/computer-use/loop/types.d.ts +14 -5
- package/dist/actors/computer-use/loop.js +4 -4
- package/dist/actors/computer-use/openai-provider.d.ts +1 -1
- package/dist/actors/computer-use/openai-provider.js +2 -2
- package/dist/actors/contract.d.ts +10 -8
- package/dist/actors/contract.js +7 -1
- package/dist/actors/local-agent/cli.js +1 -1
- package/dist/actors/scripted-browser/actor.d.ts +2 -2
- package/dist/actors/scripted-browser/journey.js +15 -4
- package/dist/actors/scripted-browser/steps.js +18 -0
- package/dist/actors/scripted-browser/types.d.ts +11 -1
- package/dist/actors/stop-conditions.js +1 -3
- package/dist/analysis/automatic-completion.d.ts +13 -8
- package/dist/analysis/automatic-completion.js +14 -8
- package/dist/analysis/automatic-config.d.ts +1 -1
- package/dist/analysis/automatic-config.js +2 -2
- package/dist/analysis/automatic.d.ts +10 -4
- package/dist/analysis/automatic.js +17 -13
- package/dist/analysis/diagnostics.d.ts +23 -0
- package/dist/analysis/diagnostics.js +112 -0
- package/dist/analysis/evidence-sources.js +2 -2
- package/dist/analysis/evidence.js +6 -6
- package/dist/analysis/execute.d.ts +7 -1
- package/dist/analysis/execute.js +39 -12
- package/dist/analysis/job.d.ts +8 -5
- package/dist/analysis/job.js +15 -14
- package/dist/analysis/load.d.ts +1 -1
- package/dist/analysis/load.js +5 -5
- package/dist/analysis/provider.d.ts +9 -1
- package/dist/analysis/restricted-codex.d.ts +2 -0
- package/dist/analysis/restricted-codex.js +10 -1
- package/dist/analysis/service.d.ts +2 -0
- package/dist/analysis/service.js +31 -12
- package/dist/analysis/sharing.d.ts +2 -2
- package/dist/analysis/sharing.js +5 -5
- package/dist/analysis/store-executions.d.ts +5 -5
- package/dist/analysis/store-executions.js +12 -12
- package/dist/analysis/store.d.ts +4 -4
- package/dist/analysis/store.js +13 -13
- package/dist/cli/commands/analysis-signals.d.ts +2 -1
- package/dist/cli/commands/analysis-signals.js +4 -1
- package/dist/cli/commands/analyze.js +4 -2
- package/dist/cli/commands/comms.js +8 -1
- package/dist/cli/commands/lab-route-computer-use.d.ts +0 -2
- package/dist/cli/commands/lab-route-computer-use.js +26 -14
- package/dist/cli/commands/lab-route-preview.d.ts +1 -3
- package/dist/cli/commands/lab-route-preview.js +3 -4
- package/dist/cli/commands/lab-route-run.d.ts +6 -4
- package/dist/cli/commands/lab-route-run.js +6 -2
- package/dist/cli/commands/lab-route-scripted.d.ts +0 -2
- package/dist/cli/commands/lab-route-scripted.js +0 -1
- package/dist/cli/commands/lab-route-shared-world.d.ts +0 -2
- package/dist/cli/commands/lab-route-shared-world.js +0 -1
- package/dist/cli/commands/lab-route-terminal.d.ts +0 -2
- package/dist/cli/commands/lab-route-terminal.js +0 -1
- package/dist/cli/commands/lab-run.js +76 -45
- package/dist/cli/commands/lab-scorer.d.ts +0 -2
- package/dist/cli/commands/lab.js +12 -6
- package/dist/cli/commands/observe.js +22 -0
- package/dist/cli/commands/run-signals.d.ts +30 -0
- package/dist/cli/commands/run-signals.js +146 -0
- package/dist/cli/commands/runs.js +10 -8
- package/dist/cli/commands/watch.js +12 -10
- package/dist/cli/doctor.d.ts +3 -0
- package/dist/cli/doctor.js +10 -2
- package/dist/cli/io.d.ts +5 -4
- package/dist/cli/io.js +12 -8
- package/dist/cli/program.js +3 -3
- package/dist/cli/renamed-options.d.ts +11 -0
- package/dist/cli/renamed-options.js +18 -0
- package/dist/cli/telemetry.d.ts +2 -2
- package/dist/cli/telemetry.js +1 -1
- package/dist/comms/capture-surface.d.ts +1 -1
- package/dist/comms/catch-host.d.ts +1 -1
- package/dist/comms/connections.js +4 -4
- package/dist/comms/external-evidence.d.ts +27 -0
- package/dist/comms/external-evidence.js +93 -0
- package/dist/comms/lease-store.js +7 -7
- package/dist/comms/types.js +1 -1
- package/dist/evidence/browser-hygiene.d.ts +1 -1
- package/dist/evidence/browser-hygiene.js +1 -1
- package/dist/evidence/redaction.js +1 -1
- package/dist/evidence/secret-scrub.d.ts +9 -0
- package/dist/evidence/secret-scrub.js +96 -0
- package/dist/feedback/draft.js +7 -9
- package/dist/feedback/export-bundle.js +4 -4
- package/dist/feedback/export.js +9 -9
- package/dist/feedback/feedback.d.ts +1 -1
- package/dist/index.d.ts +3 -6
- package/dist/index.js +3 -6
- package/dist/keys/key-resolution.d.ts +3 -1
- package/dist/keys/key-resolution.js +18 -16
- package/dist/lab/adapter-extension.d.ts +28 -6
- package/dist/lab/adapter-extension.js +65 -126
- package/dist/lab/adapter-scorer-loader.d.ts +25 -5
- package/dist/lab/adapter-scorer-loader.js +24 -0
- package/dist/lab/composition-rules.d.ts +2 -0
- package/dist/lab/composition-rules.js +35 -26
- package/dist/lab/config.js +28 -26
- package/dist/lab/device-presets.d.ts +2 -2
- package/dist/lab/discover.js +1 -3
- package/dist/lab/doctor.d.ts +44 -9
- package/dist/lab/doctor.js +149 -41
- package/dist/lab/init-plan.js +1 -3
- package/dist/lab/keys.js +1 -1
- package/dist/lab/lab-deps.d.ts +85 -0
- package/dist/lab/lab-deps.js +4 -0
- package/dist/lab/parse/actors.js +8 -7
- package/dist/lab/parse/comms.js +3 -2
- package/dist/lab/parse/execution.js +3 -2
- package/dist/lab/parse/subject-state.js +2 -1
- package/dist/lab/parse/subject.js +2 -1
- package/dist/lab/parse/values.d.ts +0 -1
- package/dist/lab/parse/values.js +0 -3
- package/dist/lab/persona-resolve.d.ts +3 -3
- package/dist/lab/persona-resolve.js +4 -4
- package/dist/lab/persona.js +1 -3
- package/dist/lab/plan-base.d.ts +6 -2
- package/dist/lab/plan-base.js +22 -7
- package/dist/lab/plan-participants.d.ts +5 -5
- package/dist/lab/plan-participants.js +2 -2
- package/dist/lab/plan-types.d.ts +33 -7
- package/dist/lab/plan.d.ts +3 -11
- package/dist/lab/plan.js +18 -42
- package/dist/lab/preflight-result.js +0 -2
- package/dist/lab/preflight.d.ts +0 -3
- package/dist/lab/preflight.js +1 -1
- package/dist/lab/requirements.d.ts +20 -0
- package/dist/lab/requirements.js +54 -0
- package/dist/lab/route-inputs.d.ts +23 -12
- package/dist/lab/route-inputs.js +48 -51
- package/dist/lab/routing.d.ts +19 -24
- package/dist/lab/routing.js +14 -47
- package/dist/lab/run-lab-events.d.ts +6 -11
- package/dist/lab/run-lab-events.js +3 -11
- package/dist/lab/run-lab-homes.d.ts +64 -0
- package/dist/lab/run-lab-homes.js +3 -0
- package/dist/lab/run-lab-options.d.ts +12 -66
- package/dist/lab/run-lab-options.js +45 -275
- package/dist/lab/summary.d.ts +9 -4
- package/dist/lab/summary.js +15 -8
- package/dist/lab/types.d.ts +132 -132
- package/dist/lab/validation.d.ts +15 -15
- package/dist/lab/validation.js +28 -28
- package/dist/lab/warnings.js +20 -19
- package/dist/observer/artifact.d.ts +1 -1
- package/dist/observer/artifact.js +3 -3
- package/dist/observer/data.js +2 -2
- package/dist/observer/render.js +2 -2
- package/dist/observer/run-routes.d.ts +1 -1
- package/dist/observer/run-routes.js +5 -5
- package/dist/observer/serve.d.ts +17 -0
- package/dist/observer/serve.js +34 -3
- package/dist/observer-app.html +1 -1
- package/dist/routes/computer-use/bundle-parts.d.ts +1 -1
- package/dist/routes/computer-use/bundle-parts.js +10 -3
- package/dist/routes/computer-use/bundle.d.ts +4 -11
- package/dist/routes/computer-use/bundle.js +9 -15
- package/dist/routes/computer-use/diagnostics.d.ts +1 -1
- package/dist/routes/computer-use/diagnostics.js +1 -1
- package/dist/routes/computer-use/e2b-desktop/comms.d.ts +10 -10
- package/dist/routes/computer-use/e2b-desktop/comms.js +11 -14
- package/dist/routes/computer-use/e2b-desktop/desktop.d.ts +2 -2
- package/dist/routes/computer-use/e2b-desktop/desktop.js +4 -7
- package/dist/routes/computer-use/e2b-desktop/fidelity.d.ts +13 -13
- package/dist/routes/computer-use/e2b-desktop/fidelity.js +11 -11
- package/dist/routes/computer-use/e2b-desktop/prepare.d.ts +3 -3
- package/dist/routes/computer-use/e2b-desktop/prepare.js +33 -36
- package/dist/routes/computer-use/e2b-desktop/start.d.ts +1 -1
- package/dist/routes/computer-use/e2b-desktop/start.js +24 -23
- package/dist/routes/computer-use/e2b-desktop/state.d.ts +5 -4
- package/dist/routes/computer-use/e2b-desktop/state.js +5 -3
- package/dist/routes/computer-use/e2b-desktop/teardown.d.ts +1 -1
- package/dist/routes/computer-use/e2b-desktop/teardown.js +29 -17
- package/dist/routes/computer-use/external-comms.d.ts +4 -4
- package/dist/routes/computer-use/external-comms.js +19 -43
- package/dist/routes/computer-use/fanout-bundle.d.ts +3 -3
- package/dist/routes/computer-use/fanout-bundle.js +25 -29
- package/dist/routes/computer-use/{fanout-lanes.js → fanout-records.js} +25 -19
- package/dist/routes/computer-use/in-process-desktop.d.ts +3 -10
- package/dist/routes/computer-use/in-process-desktop.js +3 -9
- package/dist/routes/computer-use/live-flush.d.ts +7 -5
- package/dist/routes/computer-use/live-flush.js +19 -27
- package/dist/routes/computer-use/{run-lanes.js → live-phase.js} +14 -13
- package/dist/routes/computer-use/local-tree-pack.d.ts +3 -3
- package/dist/routes/computer-use/local-tree-pack.js +4 -5
- package/dist/routes/computer-use/local-vm.d.ts +11 -8
- package/dist/routes/computer-use/local-vm.js +39 -66
- package/dist/routes/computer-use/participant-desktop.d.ts +8 -23
- package/dist/routes/computer-use/participant-desktop.js +5 -25
- package/dist/routes/computer-use/{lanes.d.ts → participant-execution.d.ts} +10 -10
- package/dist/routes/computer-use/{lanes.js → participant-execution.js} +35 -22
- package/dist/routes/computer-use/participant-facts.d.ts +7 -1
- package/dist/routes/computer-use/participant-facts.js +12 -1
- package/dist/routes/computer-use/participant-model.d.ts +19 -11
- package/dist/routes/computer-use/participant-model.js +58 -33
- package/dist/routes/computer-use/participant-prompt.d.ts +3 -3
- package/dist/routes/computer-use/participant-prompt.js +4 -4
- package/dist/routes/computer-use/participant-runs.d.ts +6 -6
- package/dist/routes/computer-use/participant-runs.js +8 -8
- package/dist/routes/computer-use/plan.d.ts +21 -29
- package/dist/routes/computer-use/plan.js +59 -65
- package/dist/routes/computer-use/preflight.d.ts +6 -11
- package/dist/routes/computer-use/preflight.js +26 -18
- package/dist/routes/computer-use/rerun-selection.js +10 -6
- package/dist/routes/computer-use/result.d.ts +1 -1
- package/dist/routes/computer-use/result.js +40 -30
- package/dist/routes/computer-use/route.d.ts +3 -4
- package/dist/routes/computer-use/route.js +21 -19
- package/dist/routes/computer-use/self-report.d.ts +2 -2
- package/dist/routes/computer-use/self-report.js +4 -4
- package/dist/routes/computer-use/setup.d.ts +8 -17
- package/dist/routes/computer-use/setup.js +98 -86
- package/dist/routes/computer-use/single-bundle.d.ts +8 -11
- package/dist/routes/computer-use/single-bundle.js +20 -25
- package/dist/routes/computer-use/subject-projection.d.ts +5 -7
- package/dist/routes/computer-use/subject-projection.js +20 -19
- package/dist/routes/computer-use/types.d.ts +169 -211
- package/dist/routes/computer-use/types.js +13 -6
- package/dist/routes/preview.js +0 -1
- package/dist/routes/scripted/bundle.d.ts +3 -6
- package/dist/routes/scripted/bundle.js +11 -16
- package/dist/routes/scripted/plan.d.ts +5 -7
- package/dist/routes/scripted/plan.js +6 -4
- package/dist/routes/scripted/result.d.ts +4 -1
- package/dist/routes/scripted/result.js +10 -6
- package/dist/routes/scripted/route.js +10 -11
- package/dist/routes/scripted/scenario.d.ts +1 -1
- package/dist/routes/scripted/scenario.js +1 -1
- package/dist/routes/scripted/setup.d.ts +3 -2
- package/dist/routes/scripted/setup.js +22 -21
- package/dist/routes/scripted/subject.d.ts +8 -3
- package/dist/routes/scripted/subject.js +11 -6
- package/dist/routes/scripted/surface-records.js +1 -1
- package/dist/routes/scripted/surface-sessions.d.ts +2 -2
- package/dist/routes/scripted/surface-sessions.js +4 -4
- package/dist/routes/scripted/types.d.ts +19 -36
- package/dist/routes/scripted/types.js +1 -2
- package/dist/routes/shared-world/{seat-records.js → bundle-records.js} +8 -8
- package/dist/routes/shared-world/bundle.d.ts +2 -2
- package/dist/routes/shared-world/bundle.js +22 -26
- package/dist/routes/shared-world/checkpoints.d.ts +4 -4
- package/dist/routes/shared-world/checkpoints.js +4 -4
- package/dist/routes/shared-world/comms.d.ts +5 -4
- package/dist/routes/shared-world/comms.js +28 -41
- package/dist/routes/shared-world/external-public.d.ts +5 -5
- package/dist/routes/shared-world/external-public.js +19 -20
- package/dist/routes/shared-world/handoff.d.ts +4 -4
- package/dist/routes/shared-world/handoff.js +50 -50
- package/dist/routes/shared-world/lobby-code.d.ts +5 -5
- package/dist/routes/shared-world/lobby-code.js +13 -13
- package/dist/routes/shared-world/{seats.d.ts → participant-specs.d.ts} +8 -6
- package/dist/routes/shared-world/{seats.js → participant-specs.js} +46 -51
- package/dist/routes/shared-world/plan.d.ts +2 -6
- package/dist/routes/shared-world/plan.js +1 -2
- package/dist/routes/shared-world/provenance.d.ts +4 -4
- package/dist/routes/shared-world/provenance.js +4 -4
- package/dist/routes/shared-world/provisioned.d.ts +3 -2
- package/dist/routes/shared-world/provisioned.js +48 -41
- package/dist/routes/shared-world/result.js +31 -19
- package/dist/routes/shared-world/route.js +37 -41
- package/dist/routes/shared-world/setup.d.ts +5 -4
- package/dist/routes/shared-world/setup.js +12 -14
- package/dist/routes/shared-world/types.d.ts +53 -126
- package/dist/routes/shared-world/types.js +2 -2
- package/dist/routes/terminal/adapter.d.ts +8 -8
- package/dist/routes/terminal/adapter.js +28 -125
- package/dist/routes/terminal/bundle.d.ts +7 -12
- package/dist/routes/terminal/bundle.js +24 -34
- package/dist/routes/terminal/credentials.d.ts +2 -2
- package/dist/routes/terminal/credentials.js +16 -16
- package/dist/routes/terminal/dry-run.d.ts +1 -1
- package/dist/routes/terminal/dry-run.js +9 -11
- package/dist/routes/terminal/encoding.d.ts +1 -1
- package/dist/routes/terminal/encoding.js +2 -2
- package/dist/routes/terminal/ledger.d.ts +6 -6
- package/dist/routes/terminal/ledger.js +9 -9
- package/dist/routes/terminal/live-finish.d.ts +1 -2
- package/dist/routes/terminal/live-finish.js +21 -20
- package/dist/routes/terminal/live-sandbox.d.ts +4 -2
- package/dist/routes/terminal/live-sandbox.js +25 -21
- package/dist/routes/terminal/participant-text.d.ts +23 -0
- package/dist/routes/terminal/participant-text.js +165 -0
- package/dist/routes/terminal/plan.d.ts +2 -6
- package/dist/routes/terminal/plan.js +13 -9
- package/dist/routes/terminal/recorder.d.ts +6 -1
- package/dist/routes/terminal/recorder.js +12 -4
- package/dist/routes/terminal/result.js +4 -4
- package/dist/routes/terminal/route.js +26 -26
- package/dist/routes/terminal/runtime.d.ts +3 -2
- package/dist/routes/terminal/runtime.js +3 -3
- package/dist/routes/terminal/sandbox.d.ts +5 -3
- package/dist/routes/terminal/sandbox.js +13 -16
- package/dist/routes/terminal/session.js +16 -14
- package/dist/routes/terminal/token-usage.js +5 -5
- package/dist/routes/terminal/trace.d.ts +5 -8
- package/dist/routes/terminal/trace.js +9 -64
- package/dist/routes/terminal/types.d.ts +85 -93
- package/dist/routes/terminal/types.js +9 -4
- package/dist/run/active-runs.d.ts +13 -0
- package/dist/run/active-runs.js +12 -0
- package/dist/run/bundle-shape.d.ts +2 -1
- package/dist/run/bundle-shape.js +4 -4
- package/dist/run/bundle.d.ts +63 -56
- package/dist/run/bundle.js +9 -8
- package/dist/run/cost-summary.js +3 -2
- package/dist/run/costs.d.ts +6 -6
- package/dist/run/costs.js +10 -10
- package/dist/run/detail.d.ts +5 -5
- package/dist/run/detail.js +6 -6
- package/dist/run/dry-run.js +5 -12
- package/dist/run/{study-files.d.ts → evidence-files.d.ts} +4 -4
- package/dist/run/{study-files.js → evidence-files.js} +5 -5
- package/dist/run/feedback-shape.js +1 -1
- package/dist/run/judge.d.ts +16 -4
- package/dist/run/judge.js +24 -7
- package/dist/run/locate.d.ts +2 -0
- package/dist/run/locate.js +3 -1
- package/dist/run/outcomes.d.ts +3 -3
- package/dist/run/outcomes.js +3 -3
- package/dist/run/participant-records.d.ts +2 -2
- package/dist/run/participant-records.js +2 -2
- package/dist/run/paths.js +1 -1
- package/dist/run/pricing.d.ts +19 -9
- package/dist/run/pricing.js +30 -18
- package/dist/run/projection.d.ts +13 -13
- package/dist/run/projection.js +8 -8
- package/dist/run/reclaim.d.ts +7 -1
- package/dist/run/reclaim.js +24 -4
- package/dist/run/results.d.ts +1 -1
- package/dist/run/run-index.d.ts +1 -1
- package/dist/run/run-index.js +11 -11
- package/dist/run/run.d.ts +4 -2
- package/dist/run/run.js +9 -5
- package/dist/run/sandbox-receipts.d.ts +4 -4
- package/dist/run/sandbox-receipts.js +4 -4
- package/dist/run/shared-world-evidence.d.ts +47 -47
- package/dist/run/shared-world-shape.d.ts +3 -3
- package/dist/run/shared-world-shape.js +11 -11
- package/dist/run/stats.d.ts +5 -5
- package/dist/run/stats.js +8 -8
- package/dist/run/status.d.ts +16 -6
- package/dist/run/status.js +31 -8
- package/dist/run/streams.d.ts +26 -19
- package/dist/run/terminal-contract.d.ts +5 -5
- package/dist/run/terminal-contract.js +4 -4
- package/dist/run/transient-comms-secrets.d.ts +5 -0
- package/dist/run/transient-comms-secrets.js +12 -0
- package/dist/run-lab.d.ts +36 -34
- package/dist/run-lab.js +41 -37
- package/dist/subject/desktop-cli.d.ts +1 -1
- package/dist/subject/desktop-cli.js +1 -1
- package/dist/subject/local-tree-archive.d.ts +1 -1
- package/dist/subject/local-tree-archive.js +4 -4
- package/dist/subject/local-tree.d.ts +2 -2
- package/dist/subject/local-tree.js +1 -1
- package/dist/subject/node-bootstrap.d.ts +1 -1
- package/dist/subject/node-bootstrap.js +4 -4
- package/dist/subject/runtime.js +5 -5
- package/dist/subject/serve.js +1 -1
- package/dist/subject/steps.d.ts +4 -4
- package/dist/subject/steps.js +5 -5
- package/dist/substrates/desktop-session.d.ts +2 -0
- package/dist/substrates/e2b/cdp-probe.d.ts +2 -2
- package/dist/substrates/e2b/cdp-probe.js +1 -1
- package/dist/substrates/e2b/desktop-browser.d.ts +3 -3
- package/dist/substrates/e2b/desktop-browser.js +4 -4
- package/dist/substrates/e2b/desktop-cdp.d.ts +7 -7
- package/dist/substrates/e2b/desktop-cdp.js +4 -4
- package/dist/substrates/e2b/desktop-geometry.d.ts +4 -4
- package/dist/substrates/e2b/desktop-geometry.js +3 -3
- package/dist/substrates/e2b/desktop-media.js +2 -2
- package/dist/substrates/e2b/sandbox.d.ts +2 -0
- package/dist/substrates/e2b/sandbox.js +22 -8
- package/dist/substrates/e2b/sdk.d.ts +12 -1
- package/dist/substrates/e2b/sdk.js +30 -9
- package/dist/substrates/local/runtime-host.d.ts +2 -0
- package/dist/substrates/local/runtime-host.js +6 -0
- package/dist/tui/actions.d.ts +7 -5
- package/dist/tui/actions.js +18 -9
- package/dist/tui-app.js +42 -42
- package/dist/verify/actor.d.ts +10 -10
- package/dist/verify/actor.js +15 -15
- package/dist/verify/artifacts.d.ts +1 -1
- package/dist/verify/artifacts.js +3 -3
- package/dist/verify/costs.d.ts +2 -2
- package/dist/verify/costs.js +2 -2
- package/dist/verify/liveness.d.ts +1 -1
- package/dist/verify/liveness.js +4 -1
- package/dist/verify/rerun.d.ts +1 -1
- package/dist/verify/rerun.js +1 -1
- package/dist/verify/shared-world.js +2 -2
- package/dist/verify/verify.js +6 -6
- package/docs/README.md +1 -1
- package/docs/architecture/actor-contract.md +60 -22
- package/docs/architecture/desktop-sessions.md +9 -9
- package/docs/architecture/external-public-shared-world.md +5 -0
- package/docs/architecture/observer.md +4 -4
- package/docs/architecture/restricted-codex-analysis.md +40 -4
- package/docs/architecture/state-driven-executor.md +4 -5
- package/docs/architecture/task-protocol-support.md +3 -5
- package/docs/architecture/{terminal-product-lane.md → terminal-product-route.md} +24 -16
- package/docs/contracts/run-bundle.md +10 -8
- package/docs/contracts/schemas.md +109 -53
- package/docs/contracts/study-analysis.md +24 -0
- package/docs/decisions/0004-participant-desktops-stay-in-the-route.md +2 -1
- package/docs/product/automatic-analysis.md +1 -0
- package/docs/ramp/README.md +2 -1
- package/package.json +4 -4
- package/skills/humanish/SKILL.md +3 -2
- package/skills/humanish/agents/openai.yaml +1 -1
- package/dist/deprecated.d.ts +0 -90
- package/dist/deprecated.js +0 -106
- package/dist/lab/bag-overrides.d.ts +0 -18
- package/dist/lab/bag-overrides.js +0 -121
- package/dist/routes/computer-use/legacy-lane-spec.d.ts +0 -62
- package/dist/routes/computer-use/legacy-lane-spec.js +0 -39
- /package/dist/routes/computer-use/{fanout-lanes.d.ts → fanout-records.d.ts} +0 -0
- /package/dist/routes/computer-use/{run-lanes.d.ts → live-phase.d.ts} +0 -0
- /package/dist/routes/shared-world/{seat-records.d.ts → bundle-records.d.ts} +0 -0
|
@@ -2,17 +2,17 @@ import { type ChromeMobileEmulationRequest } from "./cdp-probe.js";
|
|
|
2
2
|
import type { RunDesktopGeometry } from "../../run/streams.js";
|
|
3
3
|
import type { E2BDesktopSandbox } from "./sdk.js";
|
|
4
4
|
/**
|
|
5
|
-
* Runtime-only CDP endpoint attribution for the exact chromium this
|
|
5
|
+
* Runtime-only CDP endpoint attribution for the exact chromium this participant launched. Port
|
|
6
6
|
* resolution at OBSERVE time: the cached launch-time `cdpPort` wins; absent that, the observer
|
|
7
7
|
* probe re-reads `profileDir`'s DevToolsActivePort marker (a slow cold start can publish it
|
|
8
|
-
* after the launch-time poll gave up); absent both it uses 9222, the port every
|
|
8
|
+
* after the launch-time poll gave up); absent both it uses 9222, the port every participant launches
|
|
9
9
|
* Chrome with, where a dead endpoint degrades into a warning that names the cause.
|
|
10
10
|
*/
|
|
11
11
|
export interface ChromeCdpEndpoint {
|
|
12
12
|
cdpPort?: number;
|
|
13
13
|
/** The launched profile dir; lets observers re-read DevToolsActivePort at observe time. */
|
|
14
14
|
profileDir?: string;
|
|
15
|
-
/** The URL this
|
|
15
|
+
/** The URL this participant opened; attributes the CDP page when no target id is pinned yet. */
|
|
16
16
|
targetUrl: string;
|
|
17
17
|
}
|
|
18
18
|
/**
|
|
@@ -20,7 +20,7 @@ export interface ChromeCdpEndpoint {
|
|
|
20
20
|
* after the launch page, so a tab the participant opens later should lay out at the phone width
|
|
21
21
|
* too. The first observation on each new target reads that page's own report; a target that
|
|
22
22
|
* reports the requested width is recorded through `onCovered`, and one that does not (or cannot be
|
|
23
|
-
* read) fires `onDrift` once, so a phone-labelled
|
|
23
|
+
* read) fires `onDrift` once, so a phone-labelled participant that spent part of its session at desktop
|
|
24
24
|
* layout says so with the number the page gave.
|
|
25
25
|
*/
|
|
26
26
|
export interface ChromeEmulationDrift {
|
|
@@ -44,7 +44,7 @@ export interface ChromeEmulationDrift {
|
|
|
44
44
|
* reading the old tab forever).
|
|
45
45
|
*
|
|
46
46
|
* `onUnavailable` fires ONCE, on the first probe that could not read the page, with the reason.
|
|
47
|
-
* The observer still degrades to `{}` for the loop; the callback is how a
|
|
47
|
+
* The observer still degrades to `{}` for the loop; the callback is how a participant says out loud that
|
|
48
48
|
* url/text criteria are not being measured, instead of letting the funnel report 0/N (#514).
|
|
49
49
|
*/
|
|
50
50
|
export declare function makeChromeBrowserStateObserver(desktop: E2BDesktopSandbox, requestTimeoutMs: number, endpoint: ChromeCdpEndpoint, options?: {
|
|
@@ -59,10 +59,10 @@ export declare function makeChromeBrowserStateObserver(desktop: E2BDesktopSandbo
|
|
|
59
59
|
text?: string;
|
|
60
60
|
scrollY?: number;
|
|
61
61
|
}>;
|
|
62
|
-
/** The user agent a mobile-emulated
|
|
62
|
+
/** The user agent a mobile-emulated participant presents unless the lab sets its own. */
|
|
63
63
|
export declare const DEFAULT_MOBILE_USER_AGENT = "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1";
|
|
64
64
|
/**
|
|
65
|
-
* Apply mobile emulation (#221) to the
|
|
65
|
+
* Apply mobile emulation (#221) to the participant's launch page and read back what the page reports.
|
|
66
66
|
* Fails CLOSED: a request that cannot be applied throws, because a desktop run labelled mobile is
|
|
67
67
|
* the over-trust this feature exists to prevent. A read-back that cannot be taken is a warning
|
|
68
68
|
* (the emulation was applied; only the proof is missing).
|
|
@@ -14,7 +14,7 @@ import { e2bShell } from "./shell.js";
|
|
|
14
14
|
* reading the old tab forever).
|
|
15
15
|
*
|
|
16
16
|
* `onUnavailable` fires ONCE, on the first probe that could not read the page, with the reason.
|
|
17
|
-
* The observer still degrades to `{}` for the loop; the callback is how a
|
|
17
|
+
* The observer still degrades to `{}` for the loop; the callback is how a participant says out loud that
|
|
18
18
|
* url/text criteria are not being measured, instead of letting the funnel report 0/N (#514).
|
|
19
19
|
*/
|
|
20
20
|
export function makeChromeBrowserStateObserver(desktop, requestTimeoutMs, endpoint, options = {}) {
|
|
@@ -97,10 +97,10 @@ export function makeChromeBrowserStateObserver(desktop, requestTimeoutMs, endpoi
|
|
|
97
97
|
};
|
|
98
98
|
};
|
|
99
99
|
}
|
|
100
|
-
/** The user agent a mobile-emulated
|
|
100
|
+
/** The user agent a mobile-emulated participant presents unless the lab sets its own. */
|
|
101
101
|
export const DEFAULT_MOBILE_USER_AGENT = "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1";
|
|
102
102
|
/**
|
|
103
|
-
* Apply mobile emulation (#221) to the
|
|
103
|
+
* Apply mobile emulation (#221) to the participant's launch page and read back what the page reports.
|
|
104
104
|
* Fails CLOSED: a request that cannot be applied throws, because a desktop run labelled mobile is
|
|
105
105
|
* the over-trust this feature exists to prevent. A read-back that cannot be taken is a warning
|
|
106
106
|
* (the emulation was applied; only the proof is missing).
|
|
@@ -129,7 +129,7 @@ export async function applyMobileEmulation(desktop, requestTimeoutMs, endpoint,
|
|
|
129
129
|
};
|
|
130
130
|
// The UA / touch / DPR overrides are bound to the DevTools session that set them and lapse the
|
|
131
131
|
// moment its socket closes (measured: only the viewport width survived a one-shot apply). So the
|
|
132
|
-
// applier stays attached for the
|
|
132
|
+
// applier stays attached for the participant's whole life as a detached process; the sandbox teardown
|
|
133
133
|
// ends it. Its first stdout line says what was applied.
|
|
134
134
|
const holderName = `mobile-emulation-${Date.now().toString(36)}`;
|
|
135
135
|
await startDetachedProcess(shell, {
|
|
@@ -19,9 +19,9 @@ export declare function declaredScreenForRender(preset: DevicePreset, presetName
|
|
|
19
19
|
preset: string;
|
|
20
20
|
} | undefined;
|
|
21
21
|
/**
|
|
22
|
-
* Verify the desktop screen geometry IN-SANDBOX (the
|
|
22
|
+
* Verify the desktop screen geometry IN-SANDBOX (the participant's device claim is checked, never
|
|
23
23
|
* assumed). A parseable mismatch fails closed. Unavailable/unparseable evidence is returned as
|
|
24
|
-
* an explicit warning: the
|
|
24
|
+
* an explicit warning: the participant may still run, but its bundle records only the requested screen
|
|
25
25
|
* and never upgrades that request into a verified measurement.
|
|
26
26
|
*/
|
|
27
27
|
export declare function inspectDesktopScreenGeometry(args: {
|
|
@@ -57,7 +57,7 @@ export declare function makeChromeDesktopGeometryObserver(desktop: E2BDesktopSan
|
|
|
57
57
|
}) | undefined>;
|
|
58
58
|
/** Root-relative physical client bounds from xwininfo's C-locale stats. */
|
|
59
59
|
export declare function parseXwininfoGeometry(output: string): RunDesktopGeometry["browserWindow"] | undefined;
|
|
60
|
-
/** Hosted-browser geometry capture shared by the
|
|
60
|
+
/** Hosted-browser geometry capture shared by the computer-use and shared-world routes. */
|
|
61
61
|
export declare function captureDesktopBrowserGeometry(args: {
|
|
62
62
|
desktop: E2BDesktopSandbox;
|
|
63
63
|
browserFamily: DesktopBrowserFamily;
|
|
@@ -67,7 +67,7 @@ export declare function captureDesktopBrowserGeometry(args: {
|
|
|
67
67
|
pagePreference?: ChromeCdpPagePreference;
|
|
68
68
|
browserWindowId?: string;
|
|
69
69
|
participantId: string;
|
|
70
|
-
/** Runtime-only
|
|
70
|
+
/** Runtime-only participant target URL (attributes the CDP page); never persisted by this capture. */
|
|
71
71
|
targetUrl: string;
|
|
72
72
|
requestedScreen: readonly [number, number];
|
|
73
73
|
requestTimeoutMs: number;
|
|
@@ -22,9 +22,9 @@ export function declaredScreenForRender(preset, presetName, rendered) {
|
|
|
22
22
|
return { width: preset.width, height: preset.height, preset: presetName };
|
|
23
23
|
}
|
|
24
24
|
/**
|
|
25
|
-
* Verify the desktop screen geometry IN-SANDBOX (the
|
|
25
|
+
* Verify the desktop screen geometry IN-SANDBOX (the participant's device claim is checked, never
|
|
26
26
|
* assumed). A parseable mismatch fails closed. Unavailable/unparseable evidence is returned as
|
|
27
|
-
* an explicit warning: the
|
|
27
|
+
* an explicit warning: the participant may still run, but its bundle records only the requested screen
|
|
28
28
|
* and never upgrades that request into a verified measurement.
|
|
29
29
|
*/
|
|
30
30
|
export async function inspectDesktopScreenGeometry(args) {
|
|
@@ -229,7 +229,7 @@ async function fitBrowserWindowWithinDesktop(desktop, windowId, resolution, requ
|
|
|
229
229
|
}
|
|
230
230
|
return resized;
|
|
231
231
|
}
|
|
232
|
-
/** Hosted-browser geometry capture shared by the
|
|
232
|
+
/** Hosted-browser geometry capture shared by the computer-use and shared-world routes. */
|
|
233
233
|
export async function captureDesktopBrowserGeometry(args) {
|
|
234
234
|
const warnings = [];
|
|
235
235
|
let browserWindowId = args.browserWindowId;
|
|
@@ -81,7 +81,7 @@ export async function startE2BDesktopMedia(options) {
|
|
|
81
81
|
},
|
|
82
82
|
});
|
|
83
83
|
}
|
|
84
|
-
/** Where a
|
|
84
|
+
/** Where a participant's synthetic camera feed lives inside the sandbox: a tmpfs the sandbox user can
|
|
85
85
|
* write, and a path that contains neither /tmp/ nor /home/, which the public-safety scan reads
|
|
86
86
|
* as an operator's local path (this one is the harness's own and belongs in the bundle). */
|
|
87
87
|
const SANDBOX_MEDIA_DIR = "/dev/shm/humanish-media";
|
|
@@ -101,7 +101,7 @@ export async function prepareDesktopMedia(desktop, media, permission, cwd, reque
|
|
|
101
101
|
throw new Error("Microphone source-file injection is unsupported; use source: speech.");
|
|
102
102
|
if (media.camera !== undefined)
|
|
103
103
|
throw new Error("Hosted synthetic cameras cannot be combined with speech.");
|
|
104
|
-
// The
|
|
104
|
+
// The participant's setup starts and admits the speech worker before launching the browser.
|
|
105
105
|
return {
|
|
106
106
|
microphone: { source: "speech" },
|
|
107
107
|
permission,
|
|
@@ -48,6 +48,8 @@ export declare function readE2BRelease(result: DesktopReleaseResult, options: {
|
|
|
48
48
|
scrub: (text: string) => string;
|
|
49
49
|
costSpan?: boolean;
|
|
50
50
|
}): E2BReleaseReading;
|
|
51
|
+
/** A release_unavailable result as one lowercase line, for routes and reclaim that report it. */
|
|
52
|
+
export declare function releaseUnavailableDetail(detail: string | undefined): string;
|
|
51
53
|
/** Reclaim's persisted outcome; run/reclaim.ts writes these strings. */
|
|
52
54
|
export type E2BSandboxDestroyOutcome = {
|
|
53
55
|
state: "killed" | "already-gone";
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import { redactText, toErrorMessage } from "../../evidence/redaction.js";
|
|
8
8
|
import { appendSandboxReceipt } from "../../run/sandbox-receipts.js";
|
|
9
9
|
import { ownDesktopAllocation, } from "../desktop-session.js";
|
|
10
|
-
import { E2BDesktopStartupError, isSandboxNotFoundError, } from "./sdk.js";
|
|
10
|
+
import { E2B_DEBUG_KILL_DETAIL, E2BDesktopStartupError, e2bDebugMode, isSandboxNotFoundError, } from "./sdk.js";
|
|
11
11
|
/** A desktop sandbox, on the stock `desktop` template or a named one. */
|
|
12
12
|
export function acquireE2BDesktopSandbox(request) {
|
|
13
13
|
return acquire(request, request.template);
|
|
@@ -27,7 +27,7 @@ async function acquire(request, template) {
|
|
|
27
27
|
if (request.receipt !== null) {
|
|
28
28
|
const { root, participantId, now = Date.now } = request.receipt;
|
|
29
29
|
// Best effort by contract: a failed write leaves the TTL as the only backstop and never
|
|
30
|
-
// fails the
|
|
30
|
+
// fails the participant.
|
|
31
31
|
await appendSandboxReceipt(root, {
|
|
32
32
|
at: new Date(now()).toISOString(),
|
|
33
33
|
laneId: participantId,
|
|
@@ -56,13 +56,22 @@ function boundKill(module) {
|
|
|
56
56
|
* The SDK resolves false for an id it no longer knows (a 404), and a SandboxNotFoundError,
|
|
57
57
|
* recognized by type, means the same. Every other throw is unconfirmed, whatever its message
|
|
58
58
|
* says: the SDK answers a 404 with false before it throws, so "not found" or "404" in a thrown
|
|
59
|
-
* message comes from some other failure, such as a trace id.
|
|
59
|
+
* message comes from some other failure, such as a trace id. A true in debug mode sent no
|
|
60
|
+
* request, so it confirms nothing. Never list the account.
|
|
60
61
|
*/
|
|
61
62
|
async function killById(kill, sandboxId, options) {
|
|
62
63
|
if (kill === undefined)
|
|
63
64
|
return { status: "unconfirmed", reason: "release_unavailable" };
|
|
65
|
+
// The SDK reads the variable when the call starts, so read it at the same point.
|
|
66
|
+
const debug = e2bDebugMode();
|
|
64
67
|
try {
|
|
65
68
|
const result = await kill(sandboxId, options);
|
|
69
|
+
if (result === true && debug)
|
|
70
|
+
return {
|
|
71
|
+
status: "unconfirmed",
|
|
72
|
+
reason: "release_unavailable",
|
|
73
|
+
detail: E2B_DEBUG_KILL_DETAIL,
|
|
74
|
+
};
|
|
66
75
|
if (result === true)
|
|
67
76
|
return { status: "released", reason: "terminated" };
|
|
68
77
|
if (result === false)
|
|
@@ -105,7 +114,9 @@ export function readE2BRelease(result, options) {
|
|
|
105
114
|
case "release_unavailable":
|
|
106
115
|
return {
|
|
107
116
|
released: false,
|
|
108
|
-
warning:
|
|
117
|
+
warning: result.detail === undefined
|
|
118
|
+
? `Installed @e2b/desktop SDK does not expose Sandbox.kill; server-side kill-on-timeout will reclaim the ${label.toLowerCase()}.`
|
|
119
|
+
: `${label} release is unconfirmed: ${result.detail}. If it exists, server-side kill-on-timeout will reclaim it.`,
|
|
109
120
|
};
|
|
110
121
|
case "release_failed":
|
|
111
122
|
return {
|
|
@@ -119,6 +130,12 @@ export function readE2BRelease(result, options) {
|
|
|
119
130
|
};
|
|
120
131
|
}
|
|
121
132
|
}
|
|
133
|
+
/** A release_unavailable result as one lowercase line, for routes and reclaim that report it. */
|
|
134
|
+
export function releaseUnavailableDetail(detail) {
|
|
135
|
+
return detail === undefined
|
|
136
|
+
? "installed @e2b/desktop SDK does not expose Sandbox.kill; server-side kill-on-timeout will reclaim the sandbox"
|
|
137
|
+
: `${detail}; if the sandbox exists, server-side kill-on-timeout will reclaim it`;
|
|
138
|
+
}
|
|
122
139
|
/**
|
|
123
140
|
* Kill one sandbox by its exact recorded id, for reclaim, and map the shared release result onto
|
|
124
141
|
* reclaim's persisted outcome. It never lists the account.
|
|
@@ -129,10 +146,7 @@ export async function destroyE2BSandbox(module, sandboxId, options) {
|
|
|
129
146
|
return { state: released.reason === "terminated" ? "killed" : "already-gone" };
|
|
130
147
|
switch (released.reason) {
|
|
131
148
|
case "release_unavailable":
|
|
132
|
-
return {
|
|
133
|
-
state: "kill-failed",
|
|
134
|
-
detail: "installed @e2b/desktop SDK does not expose Sandbox.kill; server-side kill-on-timeout will reclaim the sandbox",
|
|
135
|
-
};
|
|
149
|
+
return { state: "kill-failed", detail: releaseUnavailableDetail(released.detail) };
|
|
136
150
|
case "invalid_result":
|
|
137
151
|
return {
|
|
138
152
|
state: "kill-failed",
|
|
@@ -165,7 +165,8 @@ type DesktopCreateCleanup = "killed" | "already_gone" | "unconfirmed";
|
|
|
165
165
|
/** Startup failed after this call acquired a handle. No credentials/options are included here. */
|
|
166
166
|
export declare class E2BDesktopStartupError extends Error {
|
|
167
167
|
readonly cleanup: DesktopCreateCleanup;
|
|
168
|
-
|
|
168
|
+
readonly cleanupDetail?: string | undefined;
|
|
169
|
+
constructor(error: unknown, cleanup: DesktopCreateCleanup, cleanupDetail?: string | undefined);
|
|
169
170
|
}
|
|
170
171
|
/**
|
|
171
172
|
* Preserve ownership before the desktop SDK starts Xvfb/XFCE (#581). Its public generic create
|
|
@@ -191,4 +192,14 @@ export declare function guardDesktopSandboxCreate(module: E2BDesktopModule): E2B
|
|
|
191
192
|
* that the exact sandbox humanish created is gone (confirmed reclaimed), never a re-list.
|
|
192
193
|
*/
|
|
193
194
|
export declare function isSandboxNotFoundError(error: unknown): boolean;
|
|
195
|
+
/** The variable that puts the E2B SDK in debug mode. */
|
|
196
|
+
export declare const E2B_DEBUG_ENV = "E2B_DEBUG";
|
|
197
|
+
/**
|
|
198
|
+
* Whether the E2B SDK runs in debug mode, read the way the SDK reads it when a call starts. In
|
|
199
|
+
* debug mode `Sandbox.kill` returns true without sending a request to E2B, so a true confirms
|
|
200
|
+
* nothing.
|
|
201
|
+
*/
|
|
202
|
+
export declare function e2bDebugMode(env?: NodeJS.ProcessEnv): boolean;
|
|
203
|
+
/** Why a kill that returned true in debug mode is unconfirmed. */
|
|
204
|
+
export declare const E2B_DEBUG_KILL_DETAIL = "E2B_DEBUG=true makes the E2B SDK return true from Sandbox.kill without contacting E2B";
|
|
194
205
|
export {};
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
// real @e2b/desktop Sandbox. Every desktop route launches through this one seam; the peer dep is
|
|
3
3
|
// optional and lazily loaded, so it stays out of the published tarball and CI.
|
|
4
4
|
//
|
|
5
|
-
// E2BDesktopSandbox is the command, file, stream, launch and input subset the
|
|
6
|
-
// optional because older SDKs lack it (the computer-use
|
|
5
|
+
// E2BDesktopSandbox is the command, file, stream, launch and input subset the participants use; `open` is
|
|
6
|
+
// optional because older SDKs lack it (the computer-use route then falls back to launch). It
|
|
7
7
|
// satisfies the executor's E2BDesktopLike port (src/substrates/e2b/desktop-executor.ts) as is.
|
|
8
8
|
import { sep } from "node:path";
|
|
9
9
|
import { fileURLToPath } from "node:url";
|
|
@@ -29,15 +29,17 @@ export const DESKTOP_CREATE_CLEANUP_TIMEOUT_MS = 10_000;
|
|
|
29
29
|
/** Startup failed after this call acquired a handle. No credentials/options are included here. */
|
|
30
30
|
export class E2BDesktopStartupError extends Error {
|
|
31
31
|
cleanup;
|
|
32
|
-
|
|
32
|
+
cleanupDetail;
|
|
33
|
+
constructor(error, cleanup, cleanupDetail) {
|
|
33
34
|
const detail = error instanceof Error ? error.message : String(error);
|
|
34
35
|
const cleanupNote = cleanup === "killed"
|
|
35
36
|
? "the allocated sandbox was reclaimed"
|
|
36
37
|
: cleanup === "already_gone"
|
|
37
38
|
? "the allocated sandbox was already gone"
|
|
38
|
-
:
|
|
39
|
+
: `cleanup of the allocated sandbox was not confirmed${cleanupDetail === undefined ? "" : ` (${cleanupDetail})`}; no retry is allowed and its provider timeout remains the backstop`;
|
|
39
40
|
super(`Desktop startup failed after allocation; ${cleanupNote}. ${detail}`, { cause: error });
|
|
40
41
|
this.cleanup = cleanup;
|
|
42
|
+
this.cleanupDetail = cleanupDetail;
|
|
41
43
|
this.name = "E2BDesktopStartupError";
|
|
42
44
|
}
|
|
43
45
|
}
|
|
@@ -78,7 +80,7 @@ export function guardDesktopSandboxCreate(module) {
|
|
|
78
80
|
// SDK 2.4 calls this method before create rejects. Keep its boolean contract while
|
|
79
81
|
// recording unconfirmed cleanup independently of the SDK's catch-and-discard path.
|
|
80
82
|
this.kill = async () => {
|
|
81
|
-
const cleanup = await reclaim();
|
|
83
|
+
const { cleanup } = await reclaim();
|
|
82
84
|
if (cleanup === "unconfirmed")
|
|
83
85
|
throw new Error("Desktop startup cleanup was not confirmed");
|
|
84
86
|
return cleanup === "killed";
|
|
@@ -103,8 +105,8 @@ export function guardDesktopSandboxCreate(module) {
|
|
|
103
105
|
catch (error) {
|
|
104
106
|
if (cleanupOwned === undefined)
|
|
105
107
|
throw error;
|
|
106
|
-
const cleanup = await cleanupOwned();
|
|
107
|
-
throw new E2BDesktopStartupError(error, cleanup);
|
|
108
|
+
const { cleanup, detail } = await cleanupOwned();
|
|
109
|
+
throw new E2BDesktopStartupError(error, cleanup, detail);
|
|
108
110
|
}
|
|
109
111
|
}
|
|
110
112
|
}
|
|
@@ -113,6 +115,8 @@ export function guardDesktopSandboxCreate(module) {
|
|
|
113
115
|
async function reclaimFailedDesktopCreate(kill, timeoutMs) {
|
|
114
116
|
const controller = new AbortController();
|
|
115
117
|
let timer;
|
|
118
|
+
// The SDK reads the variable when the call starts, so read it at the same point.
|
|
119
|
+
const debug = e2bDebugMode();
|
|
116
120
|
try {
|
|
117
121
|
const result = await Promise.race([
|
|
118
122
|
kill({ requestTimeoutMs: timeoutMs, signal: controller.signal }),
|
|
@@ -123,12 +127,17 @@ async function reclaimFailedDesktopCreate(kill, timeoutMs) {
|
|
|
123
127
|
}, timeoutMs);
|
|
124
128
|
}),
|
|
125
129
|
]);
|
|
130
|
+
// A true in debug mode sent no request, so it confirms nothing.
|
|
131
|
+
if (result === true && debug)
|
|
132
|
+
return { cleanup: "unconfirmed", detail: E2B_DEBUG_KILL_DETAIL };
|
|
126
133
|
// The installed SDK documents false as an exact-id 404: already absent is also reclaimed.
|
|
127
|
-
|
|
134
|
+
if (result === true)
|
|
135
|
+
return { cleanup: "killed" };
|
|
136
|
+
return { cleanup: result === false ? "already_gone" : "unconfirmed" };
|
|
128
137
|
}
|
|
129
138
|
catch {
|
|
130
139
|
// Do not serialize cleanup options, connection state, or provider errors that may echo auth.
|
|
131
|
-
return "unconfirmed";
|
|
140
|
+
return { cleanup: "unconfirmed" };
|
|
132
141
|
}
|
|
133
142
|
finally {
|
|
134
143
|
if (timer !== undefined)
|
|
@@ -166,3 +175,15 @@ export function isSandboxNotFoundError(error) {
|
|
|
166
175
|
const value = error;
|
|
167
176
|
return (value.name === "SandboxNotFoundError" || value.constructor?.name === "SandboxNotFoundError");
|
|
168
177
|
}
|
|
178
|
+
/** The variable that puts the E2B SDK in debug mode. */
|
|
179
|
+
export const E2B_DEBUG_ENV = "E2B_DEBUG";
|
|
180
|
+
/**
|
|
181
|
+
* Whether the E2B SDK runs in debug mode, read the way the SDK reads it when a call starts. In
|
|
182
|
+
* debug mode `Sandbox.kill` returns true without sending a request to E2B, so a true confirms
|
|
183
|
+
* nothing.
|
|
184
|
+
*/
|
|
185
|
+
export function e2bDebugMode(env = process.env) {
|
|
186
|
+
return env[E2B_DEBUG_ENV]?.toLowerCase() === "true";
|
|
187
|
+
}
|
|
188
|
+
/** Why a kill that returned true in debug mode is unconfirmed. */
|
|
189
|
+
export const E2B_DEBUG_KILL_DETAIL = `${E2B_DEBUG_ENV}=true makes the E2B SDK return true from Sandbox.kill without contacting E2B`;
|
|
@@ -16,6 +16,8 @@ export declare function runtimeExec(file: string, args: string[], options?: Runt
|
|
|
16
16
|
stdout: string;
|
|
17
17
|
stderr: string;
|
|
18
18
|
}>;
|
|
19
|
+
/** The shell command an operator runs for `docker <args>` on this host, as runtimeDocker runs it. */
|
|
20
|
+
export declare function dockerCommandLine(args: string[], options?: RuntimeHostOptions): string;
|
|
19
21
|
export declare function runtimeDocker(args: string[], options?: RuntimeHostOptions, timeout?: number): Promise<{
|
|
20
22
|
stdout: string;
|
|
21
23
|
stderr: string;
|
|
@@ -30,6 +30,12 @@ export async function runtimeExec(file, args, options = {}, timeout = 15_000) {
|
|
|
30
30
|
? hostExec("limactl", ["shell", "--workdir", "/", LIMA_INSTANCE, "--", file, ...args], options, timeout)
|
|
31
31
|
: hostExec(file, args, options, timeout);
|
|
32
32
|
}
|
|
33
|
+
/** The shell command an operator runs for `docker <args>` on this host, as runtimeDocker runs it. */
|
|
34
|
+
export function dockerCommandLine(args, options = {}) {
|
|
35
|
+
return usesLima(options)
|
|
36
|
+
? `limactl shell ${LIMA_INSTANCE} -- sudo docker --host unix:///var/run/docker.sock ${args.join(" ")}`
|
|
37
|
+
: `docker ${args.join(" ")}`;
|
|
38
|
+
}
|
|
33
39
|
export async function runtimeDocker(args, options = {}, timeout = 15_000) {
|
|
34
40
|
return usesLima(options)
|
|
35
41
|
? runtimeExec("sudo", ["-n", "docker", "--host", "unix:///var/run/docker.sock", ...args], options, timeout)
|
package/dist/tui/actions.d.ts
CHANGED
|
@@ -29,11 +29,13 @@ export declare function createTuiObserverSession(cwdInput: string, options?: {
|
|
|
29
29
|
* has children: the CLI, and whatever it spawned to reach the sandbox. Signalling only the parent
|
|
30
30
|
* leaves those orphaned and still working.
|
|
31
31
|
*
|
|
32
|
-
* SIGTERM, never SIGKILL
|
|
33
|
-
*
|
|
34
|
-
*
|
|
32
|
+
* SIGTERM, never SIGKILL, so the run's handler gets to act. Outside post-run analysis the run
|
|
33
|
+
* command (src/cli/commands/run-signals.ts) marks the run `interrupted` in status.json, kills the
|
|
34
|
+
* E2B sandboxes its receipts name, writes reclaim-receipt.json and exits; run.json keeps its last
|
|
35
|
+
* live flush. During analysis the signal cancels analysis instead. A local VM's container exits
|
|
36
|
+
* when the run's process goes.
|
|
35
37
|
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
+
* `Reclaim` stays on offer: it retries by id any kill the handler could not confirm within its
|
|
39
|
+
* 10 s deadline. Each sandbox's create-time timeout is the backstop.
|
|
38
40
|
*/
|
|
39
41
|
export declare function stopRun(cwd: string, runId: string, intent?: "run" | "analysis"): Promise<TuiActionResult>;
|
package/dist/tui/actions.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { requestAutomaticAnalysisCancellation } from "../analysis/automatic.js";
|
|
2
2
|
// The two things a run card can DO (#455 rev 8).
|
|
3
3
|
//
|
|
4
4
|
// The mock's run screen is an outcome CARD with actions, not a field list, and an action that does
|
|
@@ -108,18 +108,20 @@ export function createTuiObserverSession(cwdInput, options = {}) {
|
|
|
108
108
|
* has children: the CLI, and whatever it spawned to reach the sandbox. Signalling only the parent
|
|
109
109
|
* leaves those orphaned and still working.
|
|
110
110
|
*
|
|
111
|
-
* SIGTERM, never SIGKILL
|
|
112
|
-
*
|
|
113
|
-
*
|
|
111
|
+
* SIGTERM, never SIGKILL, so the run's handler gets to act. Outside post-run analysis the run
|
|
112
|
+
* command (src/cli/commands/run-signals.ts) marks the run `interrupted` in status.json, kills the
|
|
113
|
+
* E2B sandboxes its receipts name, writes reclaim-receipt.json and exits; run.json keeps its last
|
|
114
|
+
* live flush. During analysis the signal cancels analysis instead. A local VM's container exits
|
|
115
|
+
* when the run's process goes.
|
|
114
116
|
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
+
* `Reclaim` stays on offer: it retries by id any kill the handler could not confirm within its
|
|
118
|
+
* 10 s deadline. Each sandbox's create-time timeout is the backstop.
|
|
117
119
|
*/
|
|
118
120
|
export async function stopRun(cwd, runId, intent = "run") {
|
|
119
121
|
// The selected action carries its authority. Never infer permission to signal a process from
|
|
120
122
|
// mutable status metadata after the operator asked only to cancel analysis.
|
|
121
123
|
if (intent === "analysis") {
|
|
122
|
-
const analysis = await
|
|
124
|
+
const analysis = await requestAutomaticAnalysisCancellation(cwd, runId);
|
|
123
125
|
return {
|
|
124
126
|
schema: TUI_ACTION_SCHEMA,
|
|
125
127
|
ok: analysis.requested,
|
|
@@ -153,7 +155,7 @@ export async function stopRun(cwd, runId, intent = "run") {
|
|
|
153
155
|
};
|
|
154
156
|
}
|
|
155
157
|
if (record.state === "finished") {
|
|
156
|
-
const analysis = await
|
|
158
|
+
const analysis = await requestAutomaticAnalysisCancellation(cwd, runId);
|
|
157
159
|
if (analysis.requested)
|
|
158
160
|
return {
|
|
159
161
|
schema: TUI_ACTION_SCHEMA,
|
|
@@ -162,6 +164,13 @@ export async function stopRun(cwd, runId, intent = "run") {
|
|
|
162
164
|
};
|
|
163
165
|
return { schema: TUI_ACTION_SCHEMA, ok: false, message: "this run already finished" };
|
|
164
166
|
}
|
|
167
|
+
if (record.state === "interrupted") {
|
|
168
|
+
return {
|
|
169
|
+
schema: TUI_ACTION_SCHEMA,
|
|
170
|
+
ok: false,
|
|
171
|
+
message: `this run already stopped (${record.signal ?? "interrupted"}); Reclaim releases any sandbox it left`,
|
|
172
|
+
};
|
|
173
|
+
}
|
|
165
174
|
const pid = record.pid;
|
|
166
175
|
if (typeof pid !== "number" || !Number.isInteger(pid) || pid <= 1) {
|
|
167
176
|
// pid 1 and below are never a run of ours, and signalling them would be catastrophic.
|
|
@@ -198,6 +207,6 @@ export async function stopRun(cwd, runId, intent = "run") {
|
|
|
198
207
|
return {
|
|
199
208
|
schema: TUI_ACTION_SCHEMA,
|
|
200
209
|
ok: true,
|
|
201
|
-
message: "asked the run to stop
|
|
210
|
+
message: "asked the run to stop; it marks itself interrupted and kills its E2B sandboxes, and Reclaim retries any kill it could not confirm",
|
|
202
211
|
};
|
|
203
212
|
}
|