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
package/dist/routes/preview.js
CHANGED
|
@@ -2,15 +2,13 @@ import type { ActorPersonaRef } from "../../actors/contract.js";
|
|
|
2
2
|
import type { ScriptedBrowserSessionResult } from "../../actors/scripted-browser/actor.js";
|
|
3
3
|
import type { BrowserPersonaJourney, BrowserSurface } from "../../actors/scripted-browser/types.js";
|
|
4
4
|
import type { DesktopResourceObservation } from "../../substrates/e2b/desktop-resources.js";
|
|
5
|
-
import { type ReviewSummary, type RunBundle, type RunSubjectProvenance } from "../../run/bundle.js";
|
|
6
|
-
import type { RunLabProvenance } from "../../run/status.js";
|
|
5
|
+
import { type ReviewSummary, type RunBundle, type RunSubjectProvenance, type BundleRun } from "../../run/bundle.js";
|
|
7
6
|
/** What the scripted lab's bundle is built from. */
|
|
8
7
|
interface ScriptedBundleArgs {
|
|
9
|
-
/**
|
|
10
|
-
|
|
8
|
+
/** The run this bundle belongs to; the bundle head reads its id, mode, start and lab. */
|
|
9
|
+
run: BundleRun;
|
|
11
10
|
actorId: string;
|
|
12
11
|
appUrl: string;
|
|
13
|
-
createdAt: string;
|
|
14
12
|
desktopTemplate?: string;
|
|
15
13
|
dryRun: boolean;
|
|
16
14
|
hostDigest?: string;
|
|
@@ -18,7 +16,6 @@ interface ScriptedBundleArgs {
|
|
|
18
16
|
labId: string;
|
|
19
17
|
labTitle?: string;
|
|
20
18
|
persona: ActorPersonaRef;
|
|
21
|
-
runId: string;
|
|
22
19
|
scenarioSource: string;
|
|
23
20
|
scenarioSourceDigest: string;
|
|
24
21
|
screenshotsBySurface: Map<string, string[]>;
|
|
@@ -14,20 +14,15 @@ import { scriptedSurfaceIds, scriptedSurfaceRecords } from "./surface-records.js
|
|
|
14
14
|
*/
|
|
15
15
|
export function buildScriptedLabBundle(args) {
|
|
16
16
|
const resultBySurface = new Map(args.sessionResults.map((result) => [result.capture.surface.id, result]));
|
|
17
|
-
|
|
17
|
+
// Each surface's records are stamped with the run's start.
|
|
18
|
+
const context = { ...args, createdAt: args.run.createdAt };
|
|
19
|
+
const records = args.surfaces.map((surface, index) => scriptedSurfaceRecords(context, surface, index, resultBySurface.get(surface.id), args.screenshotsBySurface.get(surface.id) ?? []));
|
|
18
20
|
const events = scriptedEvents(args);
|
|
19
21
|
const review = buildScriptedReview(args);
|
|
20
22
|
const ranLive = args.sessionResults.length > 0 || args.sessionError !== undefined;
|
|
21
23
|
const cost = args.dryRun ? undefined : scriptedCost(args.subjectDesktop);
|
|
22
24
|
return {
|
|
23
|
-
...bundleHead({
|
|
24
|
-
runId: args.runId,
|
|
25
|
-
mode: args.dryRun ? "dry-run" : "live",
|
|
26
|
-
participants: args.surfaces.length,
|
|
27
|
-
createdAt: args.createdAt,
|
|
28
|
-
...(args.lab === undefined ? {} : { lab: args.lab }),
|
|
29
|
-
source: args.source,
|
|
30
|
-
}),
|
|
25
|
+
...bundleHead(args.run, { participants: args.surfaces.length, source: args.source }),
|
|
31
26
|
persona: {
|
|
32
27
|
id: args.persona.id,
|
|
33
28
|
name: `Scripted journey persona (${args.persona.id})`,
|
|
@@ -43,7 +38,7 @@ export function buildScriptedLabBundle(args) {
|
|
|
43
38
|
},
|
|
44
39
|
lifecycle: [
|
|
45
40
|
{
|
|
46
|
-
at: args.createdAt,
|
|
41
|
+
at: args.run.createdAt,
|
|
47
42
|
event: "scripted-lab.run.created",
|
|
48
43
|
message: `Created scripted-browser lab run with ${args.surfaces.length} surface${args.surfaces.length === 1 ? "" : "s"} (actor ${args.actorId}).`,
|
|
49
44
|
},
|
|
@@ -70,17 +65,17 @@ function scriptedEvents(args) {
|
|
|
70
65
|
const events = [
|
|
71
66
|
{
|
|
72
67
|
id: "event-000-created",
|
|
73
|
-
at: args.createdAt,
|
|
68
|
+
at: args.run.createdAt,
|
|
74
69
|
level: "info",
|
|
75
70
|
type: "scripted-lab.run.created",
|
|
76
71
|
message: `Created scripted-browser lab run for ${args.labId} (actor ${args.actorId}, ${args.surfaces.length} surface${args.surfaces.length === 1 ? "" : "s"}).`,
|
|
77
72
|
},
|
|
78
73
|
{
|
|
79
74
|
id: "event-001-subject",
|
|
80
|
-
at: args.createdAt,
|
|
75
|
+
at: args.run.createdAt,
|
|
81
76
|
level: "info",
|
|
82
77
|
type: "scripted-lab.subject.declared",
|
|
83
|
-
// Invariant 5: provenance recorded or its absence
|
|
78
|
+
// Invariant 5: provenance recorded or its absence declared. The lab did not provision
|
|
84
79
|
// this subject on app-url routes; clone routes carry structured subject provenance below.
|
|
85
80
|
message: args.subject
|
|
86
81
|
? `Provisioned synthetic subject: clone of ${args.subject.repo}${args.subject.commit ? `@${args.subject.commit}` : ""}, served + getHost-exposed in-sandbox; env names: ${args.subject.envNames?.join(", ") || "none"} (values never persisted); state provenance: ${args.subject.state.provenance}; evidence host digest: ${args.hostDigest ?? "dry-run"}.`
|
|
@@ -88,7 +83,7 @@ function scriptedEvents(args) {
|
|
|
88
83
|
},
|
|
89
84
|
{
|
|
90
85
|
id: "event-002-spend",
|
|
91
|
-
at: args.createdAt,
|
|
86
|
+
at: args.run.createdAt,
|
|
92
87
|
level: "info",
|
|
93
88
|
type: "scripted-lab.spend",
|
|
94
89
|
message: args.subject
|
|
@@ -110,7 +105,7 @@ function scriptedEvents(args) {
|
|
|
110
105
|
else if (args.sessionError !== undefined) {
|
|
111
106
|
events.push({
|
|
112
107
|
id: "event-003-session-error",
|
|
113
|
-
at: args.createdAt,
|
|
108
|
+
at: args.run.createdAt,
|
|
114
109
|
level: "error",
|
|
115
110
|
type: "scripted-lab.session.error",
|
|
116
111
|
message: args.sessionError,
|
|
@@ -119,7 +114,7 @@ function scriptedEvents(args) {
|
|
|
119
114
|
else {
|
|
120
115
|
events.push({
|
|
121
116
|
id: "event-003-contract",
|
|
122
|
-
at: args.createdAt,
|
|
117
|
+
at: args.run.createdAt,
|
|
123
118
|
level: "info",
|
|
124
119
|
type: "scripted-lab.contract.ready",
|
|
125
120
|
message: `Dry-run contract bundle ready: scenario ${args.journey.scenarioId} @ ${args.scenarioSourceDigest} (${args.scenarioSource}, ${args.journey.steps.length} step${args.journey.steps.length === 1 ? "" : "s"}) parsed and digest-pinned; switch scenario.mode to live to actuate a real browser.`,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import type { LabDeps } from "../../lab/lab-deps.js";
|
|
1
2
|
import type { RoutePlanResult, RouteRefusal, ScriptedPlan } from "../../lab/plan-types.js";
|
|
2
3
|
import type { LabConfig } from "../../lab/types.js";
|
|
3
|
-
import type { RunLabProvenance } from "../../run/status.js";
|
|
4
4
|
/** The error a scripted lab returns before a run starts. */
|
|
5
5
|
export interface ScriptedRefusal extends RouteRefusal<"scripted", "HUMANISH_LAB_ANALYSIS_INVALID" | "HUMANISH_LAB_TASKS_UNSUPPORTED" | "HUMANISH_SCRIPTED_LAB_ACTOR_UNSUPPORTED" | "HUMANISH_SCRIPTED_LAB_SCENARIO_INVALID" | "HUMANISH_SCRIPTED_LAB_SUBJECT_UNSAFE"> {
|
|
6
6
|
/**
|
|
@@ -15,16 +15,14 @@ export interface ScriptedRefusal extends RouteRefusal<"scripted", "HUMANISH_LAB_
|
|
|
15
15
|
export type ScriptedPlanResult = RoutePlanResult<ScriptedPlan, ScriptedRefusal>;
|
|
16
16
|
/** The app URL a run's evidence names: a provisioned subject's getHost URL is never persisted. */
|
|
17
17
|
export declare function evidenceAppUrlOf(subject: ScriptedPlan["subject"]): string;
|
|
18
|
+
/** Whether a test injected the browser, so a live run needs no host browser. */
|
|
19
|
+
export declare function injectedBrowser(deps: LabDeps | undefined): boolean;
|
|
18
20
|
/**
|
|
19
21
|
* Plan a scripted-browser lab. It is called for any config handed to the scripted runner, not only
|
|
20
22
|
* one routeOf sends here, so a config for another route gets this route's refusal.
|
|
21
23
|
*/
|
|
22
24
|
export declare function planScriptedLab(config: LabConfig, input: {
|
|
23
25
|
readonly dryRun: boolean;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
readonly hooks?: {
|
|
27
|
-
readonly launchBrowser?: unknown;
|
|
28
|
-
readonly browserCommand?: string;
|
|
29
|
-
};
|
|
26
|
+
/** A test's injected browser means a live run needs no host browser. */
|
|
27
|
+
readonly injectedBrowser?: boolean;
|
|
30
28
|
}): ScriptedPlanResult;
|
|
@@ -7,13 +7,17 @@ import { browserSurfaces } from "../../actors/scripted-browser/types.js";
|
|
|
7
7
|
import { resolveAutomaticAnalysis } from "../../analysis/automatic-config.js";
|
|
8
8
|
import { isNonEmpty, planBase, provisionedSubject } from "../../lab/plan-base.js";
|
|
9
9
|
import { cloneTargetValidationReason, desktopMediaValidationReason, taskProtocolValidationReason, } from "../../lab/validation.js";
|
|
10
|
-
// Default surface roster is 1 (desktop only): the defaults-table single-
|
|
10
|
+
// Default surface roster is 1 (desktop only): the defaults-table single-participant row governs;
|
|
11
11
|
// `count: 2` is the declared override that adds the mobile surface.
|
|
12
12
|
const DEFAULT_SURFACE_COUNT = 1;
|
|
13
13
|
/** The app URL a run's evidence names: a provisioned subject's getHost URL is never persisted. */
|
|
14
14
|
export function evidenceAppUrlOf(subject) {
|
|
15
15
|
return subject.kind === "clone" ? "[provisioned-subject]" : subject.appUrl;
|
|
16
16
|
}
|
|
17
|
+
/** Whether a test injected the browser, so a live run needs no host browser. */
|
|
18
|
+
export function injectedBrowser(deps) {
|
|
19
|
+
return Boolean(deps?.launchBrowser || deps?.browserCommand);
|
|
20
|
+
}
|
|
17
21
|
/**
|
|
18
22
|
* Plan a scripted-browser lab. It is called for any config handed to the scripted runner, not only
|
|
19
23
|
* one routeOf sends here, so a config for another route gets this route's refusal.
|
|
@@ -62,7 +66,6 @@ export function planScriptedLab(config, input) {
|
|
|
62
66
|
const scenarioRef = config.scenario?.ref;
|
|
63
67
|
if (!scenarioRef?.trim())
|
|
64
68
|
return refuse("HUMANISH_SCRIPTED_LAB_SCENARIO_INVALID", "scripted-browser labs require `scenario.ref` — the committed scenario's browser steps are what this actor executes.", { actor, appUrl: evidenceAppUrlOf(subject) });
|
|
65
|
-
const hooks = input.hooks ?? {};
|
|
66
69
|
const requirements = [];
|
|
67
70
|
if (!input.dryRun && subject.kind === "clone") {
|
|
68
71
|
requirements.push({ kind: "key", name: "E2B_API_KEY" });
|
|
@@ -70,7 +73,7 @@ export function planScriptedLab(config, input) {
|
|
|
70
73
|
requirements.push({ kind: "subject-env", names: subject.env });
|
|
71
74
|
}
|
|
72
75
|
// The browser runs on this machine on both subjects; a clone's is pointed at its getHost URL.
|
|
73
|
-
if (!input.dryRun &&
|
|
76
|
+
if (!input.dryRun && input.injectedBrowser !== true)
|
|
74
77
|
requirements.push({ kind: "host-browser" });
|
|
75
78
|
const persona = config.actors[0]?.persona;
|
|
76
79
|
const timeoutMs = config.execution?.timeoutMs;
|
|
@@ -79,7 +82,6 @@ export function planScriptedLab(config, input) {
|
|
|
79
82
|
plan: {
|
|
80
83
|
...planBase(config, {
|
|
81
84
|
dryRun: input.dryRun,
|
|
82
|
-
...(input.lab === undefined ? {} : { lab: input.lab }),
|
|
83
85
|
analysis,
|
|
84
86
|
}),
|
|
85
87
|
route: "scripted",
|
|
@@ -36,13 +36,16 @@ export interface ScriptedFinishInputs {
|
|
|
36
36
|
}
|
|
37
37
|
/**
|
|
38
38
|
* The scripted run's execution failures: the session's own error, a live surface that never
|
|
39
|
-
* returned, a surface that ended in a harness error,
|
|
39
|
+
* returned, a surface that ended in a harness error, a subject sandbox whose release is
|
|
40
|
+
* unconfirmed, and an Observer that failed.
|
|
40
41
|
*/
|
|
41
42
|
export declare function scriptedExecutionFailures(args: {
|
|
42
43
|
dryRun: boolean;
|
|
44
|
+
runId: string;
|
|
43
45
|
sessionError: string | undefined;
|
|
44
46
|
expected: number;
|
|
45
47
|
sessionResults: readonly Pick<ScriptedBrowserSessionResult, "completionReason" | "reason">[];
|
|
48
|
+
subject: Pick<ScriptedSubject, "sandboxId" | "killed" | "releaseWarning"> | undefined;
|
|
46
49
|
observer: Pick<ObserverResult, "ok" | "error">;
|
|
47
50
|
}): ExecutionFailure[];
|
|
48
51
|
export declare function finishScriptedRun(inputs: ScriptedFinishInputs): Promise<ScriptedBrowserLabResult>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { judgeExecution, judgeScripted, OUTCOME_POLICIES, resultOk, } from "../../run/judge.js";
|
|
1
|
+
import { judgeExecution, sandboxCleanupFailure, judgeScripted, OUTCOME_POLICIES, resultOk, } from "../../run/judge.js";
|
|
2
2
|
import { validatePreparedRunArtifactPaths } from "../../run/paths.js";
|
|
3
3
|
import { resolveSubjectState } from "../computer-use/subject-projection.js";
|
|
4
4
|
import { buildScriptedLabBundle } from "./bundle.js";
|
|
@@ -16,7 +16,8 @@ function scriptedSurfaceFacts(result) {
|
|
|
16
16
|
}
|
|
17
17
|
/**
|
|
18
18
|
* The scripted run's execution failures: the session's own error, a live surface that never
|
|
19
|
-
* returned, a surface that ended in a harness error,
|
|
19
|
+
* returned, a surface that ended in a harness error, a subject sandbox whose release is
|
|
20
|
+
* unconfirmed, and an Observer that failed.
|
|
20
21
|
*/
|
|
21
22
|
export function scriptedExecutionFailures(args) {
|
|
22
23
|
const { sessionError, sessionResults, observer } = args;
|
|
@@ -39,6 +40,9 @@ export function scriptedExecutionFailures(args) {
|
|
|
39
40
|
},
|
|
40
41
|
]
|
|
41
42
|
: []),
|
|
43
|
+
...(args.subject?.sandboxId === undefined || args.subject.killed
|
|
44
|
+
? []
|
|
45
|
+
: [sandboxCleanupFailure("subject", args.subject.releaseWarning, args.runId)]),
|
|
42
46
|
...(observer.ok
|
|
43
47
|
? []
|
|
44
48
|
: [
|
|
@@ -54,7 +58,7 @@ export async function finishScriptedRun(inputs) {
|
|
|
54
58
|
const { surfaces, sessionResults, sessionError, warnings, clone, redactRepoLabel } = inputs;
|
|
55
59
|
const { subjectEnvNames, scriptedSubject } = inputs;
|
|
56
60
|
const { actor, dryRun } = plan;
|
|
57
|
-
const { runId,
|
|
61
|
+
const { runId, paths: runPaths } = run;
|
|
58
62
|
const subjectCommit = scriptedSubject?.commit;
|
|
59
63
|
const subjectSandboxId = scriptedSubject?.sandboxId;
|
|
60
64
|
const subjectKilled = scriptedSubject?.killed ?? false;
|
|
@@ -86,16 +90,14 @@ export async function finishScriptedRun(inputs) {
|
|
|
86
90
|
surfaces: sessionResults.map(scriptedSurfaceFacts),
|
|
87
91
|
});
|
|
88
92
|
const bundle = buildScriptedLabBundle({
|
|
89
|
-
|
|
93
|
+
run,
|
|
90
94
|
actorId: actor,
|
|
91
95
|
appUrl: evidenceAppUrl,
|
|
92
|
-
createdAt,
|
|
93
96
|
dryRun,
|
|
94
97
|
journey,
|
|
95
98
|
labId: plan.labId,
|
|
96
99
|
...(plan.title ? { labTitle: plan.title } : {}),
|
|
97
100
|
persona,
|
|
98
|
-
runId,
|
|
99
101
|
scenarioSource: scenario.source,
|
|
100
102
|
scenarioSourceDigest: scenario.sourceDigest,
|
|
101
103
|
screenshotsBySurface,
|
|
@@ -122,9 +124,11 @@ export async function finishScriptedRun(inputs) {
|
|
|
122
124
|
const policy = OUTCOME_POLICIES.scripted;
|
|
123
125
|
const execution = judgeExecution(scriptedExecutionFailures({
|
|
124
126
|
dryRun,
|
|
127
|
+
runId,
|
|
125
128
|
sessionError,
|
|
126
129
|
expected: surfaces.length,
|
|
127
130
|
sessionResults,
|
|
131
|
+
subject: scriptedSubject,
|
|
128
132
|
observer,
|
|
129
133
|
}), policy);
|
|
130
134
|
const ok = resultOk({ judgment, execution, scorerFailures: [], policy });
|
|
@@ -24,7 +24,7 @@ import { buildRunSource } from "../../run/bundle.js";
|
|
|
24
24
|
import { prepareSelectedOutputDirectory } from "../../run/contained-output.js";
|
|
25
25
|
import { runScope } from "../../run/run.js";
|
|
26
26
|
import { renderScriptedReviewMarkdown } from "./bundle.js";
|
|
27
|
-
import { planScriptedLab } from "./plan.js";
|
|
27
|
+
import { injectedBrowser, planScriptedLab } from "./plan.js";
|
|
28
28
|
import { finishScriptedRun } from "./result.js";
|
|
29
29
|
import { UnsafeScriptedSessionResultError } from "./session-result.js";
|
|
30
30
|
import { prepareScriptedRun } from "./setup.js";
|
|
@@ -36,12 +36,11 @@ import { SCRIPTED_BROWSER_LAB_SCHEMA, } from "./types.js";
|
|
|
36
36
|
* returned at that refusal's stage, and otherwise runs the plan.
|
|
37
37
|
*/
|
|
38
38
|
export async function runScriptedBrowserLab(options) {
|
|
39
|
-
const { config, dryRun,
|
|
39
|
+
const { config, dryRun, ...input } = options;
|
|
40
40
|
// planScriptedLab makes every configuration refusal, in the order this route always has.
|
|
41
41
|
const planned = planScriptedLab(config, {
|
|
42
42
|
dryRun,
|
|
43
|
-
|
|
44
|
-
...(input.hooks === undefined ? {} : { hooks: input.hooks }),
|
|
43
|
+
injectedBrowser: injectedBrowser(input.deps),
|
|
45
44
|
});
|
|
46
45
|
if (planned.ok)
|
|
47
46
|
return runScriptedPlan(planned.plan, input);
|
|
@@ -86,7 +85,7 @@ export async function scriptedLabRefusal(options, refusal) {
|
|
|
86
85
|
error: { code: refusal.code, message: refusal.message },
|
|
87
86
|
};
|
|
88
87
|
const analysis = resolveAutomaticAnalysis(config.review?.analysis);
|
|
89
|
-
return completeAutomaticAnalysis(refused, undefined, analysis.ok ? analysis.config : undefined, options
|
|
88
|
+
return completeAutomaticAnalysis(refused, undefined, analysis.ok ? analysis.config : undefined, options, { trigger: config.review?.analysis === undefined ? "default" : "explicit" });
|
|
90
89
|
}
|
|
91
90
|
/**
|
|
92
91
|
* runLab's step for a scripted plan. It takes no scorer, and its local checks (keys, a browser)
|
|
@@ -97,7 +96,6 @@ export function admitScriptedPlan(plan, input) {
|
|
|
97
96
|
ok: true,
|
|
98
97
|
run: async () => ({
|
|
99
98
|
route: "scripted",
|
|
100
|
-
backend: "scripted",
|
|
101
99
|
result: await runScriptedPlan(plan, input),
|
|
102
100
|
}),
|
|
103
101
|
};
|
|
@@ -112,7 +110,7 @@ export function admitScriptedPlan(plan, input) {
|
|
|
112
110
|
*/
|
|
113
111
|
export async function runScriptedPlan(plan, input) {
|
|
114
112
|
const { result, finished } = await runScope((scope) => runScriptedPlanInScope(plan, input, scope));
|
|
115
|
-
return completeAutomaticAnalysis(result, finished, plan.analysis?.config, input
|
|
113
|
+
return completeAutomaticAnalysis(result, finished, plan.analysis?.config, input, {
|
|
116
114
|
...(plan.analysis === undefined ? {} : { trigger: plan.analysis.trigger }),
|
|
117
115
|
preferLargerOutput: plan.analysis?.preferLargerOutput === true,
|
|
118
116
|
});
|
|
@@ -130,7 +128,7 @@ async function runScriptedPlanInScope(plan, input, scope) {
|
|
|
130
128
|
mode: dryRun ? "dry-run" : "live",
|
|
131
129
|
lab: plan.lab,
|
|
132
130
|
renderReview: renderScriptedReviewMarkdown,
|
|
133
|
-
observer: { open: input.open === true, render: setup.
|
|
131
|
+
observer: { open: input.open === true, render: setup.deps.renderObserver },
|
|
134
132
|
});
|
|
135
133
|
if (!started.ok) {
|
|
136
134
|
return setup.failed(started.code, started.message);
|
|
@@ -148,7 +146,8 @@ async function runScriptedPlanInScope(plan, input, scope) {
|
|
|
148
146
|
? new ScriptedSubject({
|
|
149
147
|
plan,
|
|
150
148
|
clone: setup.clone,
|
|
151
|
-
|
|
149
|
+
deps: setup.deps,
|
|
150
|
+
...(input.prepareDesktop === undefined ? {} : { prepareDesktop: input.prepareDesktop }),
|
|
152
151
|
env: setup.env,
|
|
153
152
|
e2bApiKey: setup.e2bApiKey,
|
|
154
153
|
runPaths,
|
|
@@ -156,7 +155,7 @@ async function runScriptedPlanInScope(plan, input, scope) {
|
|
|
156
155
|
subjectEnvNames: setup.subjectEnvNames,
|
|
157
156
|
hasGithubToken: setup.hasGithubToken,
|
|
158
157
|
scrubKnownValues: setup.scrubKnownValues,
|
|
159
|
-
now: setup.
|
|
158
|
+
now: setup.deps.now ?? Date.now,
|
|
160
159
|
warnings: setup.warnings,
|
|
161
160
|
})
|
|
162
161
|
: undefined;
|
|
@@ -175,7 +174,7 @@ async function runScriptedPlanInScope(plan, input, scope) {
|
|
|
175
174
|
artifactRoot,
|
|
176
175
|
}, {
|
|
177
176
|
surfaces: setup.surfaces,
|
|
178
|
-
|
|
177
|
+
deps: setup.deps,
|
|
179
178
|
browserCommand: setup.browserCommand,
|
|
180
179
|
runPaths,
|
|
181
180
|
});
|
|
@@ -9,7 +9,7 @@ interface ResolvedScriptedScenario {
|
|
|
9
9
|
}
|
|
10
10
|
/**
|
|
11
11
|
* Resolve and consume `scenario.ref`. Path-style refs (contain a separator or end .yaml/.yml)
|
|
12
|
-
* resolve against cwd and are
|
|
12
|
+
* resolve against cwd and are clamped inside it: a ../../ escape is rejected, never recorded
|
|
13
13
|
* as repo-relative provenance. Id-style refs must be public-safe tokens and resolve to
|
|
14
14
|
* humanish/scenarios/<ref>.yaml (then .yml). Every failure mode is fail-closed. planScriptedLab
|
|
15
15
|
* has already refused a missing or blank ref.
|
|
@@ -11,7 +11,7 @@ import { readContainedRegularFile, } from "../../run/contained-output.js";
|
|
|
11
11
|
const SCENARIO_REF_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_.-]*$/;
|
|
12
12
|
/**
|
|
13
13
|
* Resolve and consume `scenario.ref`. Path-style refs (contain a separator or end .yaml/.yml)
|
|
14
|
-
* resolve against cwd and are
|
|
14
|
+
* resolve against cwd and are clamped inside it: a ../../ escape is rejected, never recorded
|
|
15
15
|
* as repo-relative provenance. Id-style refs must be public-safe tokens and resolve to
|
|
16
16
|
* humanish/scenarios/<ref>.yaml (then .yml). Every failure mode is fail-closed. planScriptedLab
|
|
17
17
|
* has already refused a missing or blank ref.
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import type { ActorPersonaRef } from "../../actors/contract.js";
|
|
2
2
|
import type { BrowserPersonaJourney, ScriptedBrowserEvidenceUrlPolicy } from "../../actors/scripted-browser/types.js";
|
|
3
3
|
import type { ScriptedPlan } from "../../lab/plan-types.js";
|
|
4
|
-
import { type
|
|
4
|
+
import { type ScriptedBrowserLabResult, type ScriptedRunInput } from "./types.js";
|
|
5
|
+
import type { LabDeps } from "../../lab/lab-deps.js";
|
|
5
6
|
/** What setup hands the run: the plan's subject and scenario, keys and the browser to launch. */
|
|
6
7
|
export interface ScriptedRunSetup {
|
|
7
8
|
cwd: string;
|
|
8
9
|
physicalCwd: string;
|
|
9
|
-
|
|
10
|
+
deps: LabDeps;
|
|
10
11
|
warnings: string[];
|
|
11
12
|
failed: (code: NonNullable<ScriptedBrowserLabResult["error"]>["code"], message: string) => ScriptedBrowserLabResult;
|
|
12
13
|
clone: Extract<ScriptedPlan["subject"], {
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// the E2B key and subject env of a live clone, a browser to launch) and the values the run reads
|
|
3
3
|
// (the evidence URL policy, the scrubber for clone values, the persona and the session budget).
|
|
4
4
|
import { realpath } from "node:fs/promises";
|
|
5
|
+
import { missingKeys, missingSubjectEnv } from "../../lab/requirements.js";
|
|
5
6
|
import path from "node:path";
|
|
6
7
|
import { resolveBrowserCommand } from "../../actors/scripted-browser/browser-command.js";
|
|
7
8
|
import { describeMissingKeys } from "../../keys/key-resolution.js";
|
|
@@ -21,7 +22,7 @@ export async function prepareScriptedRun(plan, input) {
|
|
|
21
22
|
const cwd = path.resolve(input.cwd);
|
|
22
23
|
const physicalCwd = await realpath(cwd);
|
|
23
24
|
const projectRoot = await prepareSelectedOutputDirectory(path.dirname(physicalCwd), physicalCwd);
|
|
24
|
-
const
|
|
25
|
+
const deps = input.deps ?? {};
|
|
25
26
|
const warnings = [];
|
|
26
27
|
const clone = plan.subject.kind === "clone" ? plan.subject : undefined;
|
|
27
28
|
const evidenceAppUrl = evidenceAppUrlOf(plan.subject);
|
|
@@ -42,7 +43,7 @@ export async function prepareScriptedRun(plan, input) {
|
|
|
42
43
|
? { kind: "provisioned-subject", evidenceOrigin: evidenceAppUrl }
|
|
43
44
|
: { kind: "loopback" };
|
|
44
45
|
const subjectEnvNames = [...(clone?.env ?? [])];
|
|
45
|
-
const env =
|
|
46
|
+
const env = input.env ?? process.env;
|
|
46
47
|
const e2bApiKey = env.E2B_API_KEY?.trim() ?? "";
|
|
47
48
|
const hasGithubToken = subjectEnvNames.includes("GITHUB_TOKEN");
|
|
48
49
|
const redactRepoLabel = plan.residual.policies?.redactRepos ?? hasGithubToken;
|
|
@@ -61,33 +62,33 @@ export async function prepareScriptedRun(plan, input) {
|
|
|
61
62
|
};
|
|
62
63
|
}
|
|
63
64
|
const journey = scenario.journey;
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
}
|
|
77
|
-
}
|
|
65
|
+
// The plan lists E2B_API_KEY and the subject env only for a live clone.
|
|
66
|
+
const missing = missingKeys(plan.requirements, env);
|
|
67
|
+
if (missing.length > 0) {
|
|
68
|
+
return {
|
|
69
|
+
ok: false,
|
|
70
|
+
result: failed("HUMANISH_SCRIPTED_LAB_KEYS_MISSING", `Live clone scripted-browser labs require ${missing.join(" and ")} (dry-run remains $0 and does not provision a subject). ${describeMissingKeys(missing, env)}`),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
const unsetSubjectEnv = missingSubjectEnv(plan.requirements, env);
|
|
74
|
+
if (unsetSubjectEnv.length > 0) {
|
|
75
|
+
return {
|
|
76
|
+
ok: false,
|
|
77
|
+
result: failed("HUMANISH_SCRIPTED_LAB_SUBJECT_ENV_MISSING", `Subject env values missing for live clone scripted-browser lab: ${unsetSubjectEnv.join(", ")}.`),
|
|
78
|
+
};
|
|
78
79
|
}
|
|
79
80
|
const surfaces = plan.surfaces;
|
|
80
81
|
const timeoutMs = plan.sessionTimeoutMs ?? DEFAULT_SESSION_TIMEOUT_MS;
|
|
81
82
|
const persona = {
|
|
82
83
|
id: plan.personaId ?? "scripted-journey",
|
|
83
84
|
traitsApplied: [],
|
|
84
|
-
// The step manifest
|
|
85
|
+
// The step manifest is the "prompt" on this route; the digest binds the trace to the
|
|
85
86
|
// committed scenario text.
|
|
86
87
|
promptDigest: journey.sourceDigest.slice(0, 16),
|
|
87
88
|
};
|
|
88
|
-
// Live runs need a browser
|
|
89
|
-
let browserCommand =
|
|
90
|
-
if (!dryRun && !
|
|
89
|
+
// Live runs need a browser before any actuation (unless one is injected).
|
|
90
|
+
let browserCommand = deps.browserCommand;
|
|
91
|
+
if (!dryRun && !deps.launchBrowser && !browserCommand) {
|
|
91
92
|
const resolved = await resolveBrowserCommand();
|
|
92
93
|
if (!resolved) {
|
|
93
94
|
return {
|
|
@@ -102,7 +103,7 @@ export async function prepareScriptedRun(plan, input) {
|
|
|
102
103
|
setup: {
|
|
103
104
|
cwd,
|
|
104
105
|
physicalCwd,
|
|
105
|
-
|
|
106
|
+
deps,
|
|
106
107
|
warnings,
|
|
107
108
|
failed,
|
|
108
109
|
clone,
|
|
@@ -2,7 +2,8 @@ import type { ScriptedPlan } from "../../lab/plan-types.js";
|
|
|
2
2
|
import { type PreparedRunArtifactPaths } from "../../run/paths.js";
|
|
3
3
|
import type { RunSubjectStateStepRecord } from "../../run/bundle.js";
|
|
4
4
|
import { type DesktopResourceObservation } from "../../substrates/e2b/desktop-resources.js";
|
|
5
|
-
import type {
|
|
5
|
+
import type { LabDeps } from "../../lab/lab-deps.js";
|
|
6
|
+
import type { RunLabHomes } from "../../lab/run-lab-homes.js";
|
|
6
7
|
type ScriptedCloneSubject = Extract<ScriptedPlan["subject"], {
|
|
7
8
|
readonly kind: "clone";
|
|
8
9
|
}>;
|
|
@@ -10,8 +11,10 @@ type ScriptedCloneSubject = Extract<ScriptedPlan["subject"], {
|
|
|
10
11
|
export interface ScriptedSubjectInputs {
|
|
11
12
|
plan: ScriptedPlan;
|
|
12
13
|
clone: ScriptedCloneSubject;
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
deps: LabDeps;
|
|
15
|
+
/** Runs after the subject sandbox exists and before provisioning. */
|
|
16
|
+
prepareDesktop?: NonNullable<RunLabHomes["prepareDesktop"]>;
|
|
17
|
+
env: Readonly<Record<string, string | undefined>>;
|
|
15
18
|
e2bApiKey: string;
|
|
16
19
|
runPaths: PreparedRunArtifactPaths;
|
|
17
20
|
timeoutMs: number;
|
|
@@ -26,6 +29,8 @@ export interface ScriptedSubjectInputs {
|
|
|
26
29
|
export declare class ScriptedSubject {
|
|
27
30
|
sandboxId: string | undefined;
|
|
28
31
|
killed: boolean;
|
|
32
|
+
/** The scrubbed release warning when the subject's release is unconfirmed. */
|
|
33
|
+
releaseWarning: string | undefined;
|
|
29
34
|
commit: string | undefined;
|
|
30
35
|
hostDigest: string | undefined;
|
|
31
36
|
readonly stateStepRecords: RunSubjectStateStepRecord[];
|
|
@@ -37,6 +37,8 @@ function hostOriginDigest(url) {
|
|
|
37
37
|
export class ScriptedSubject {
|
|
38
38
|
sandboxId;
|
|
39
39
|
killed = false;
|
|
40
|
+
/** The scrubbed release warning when the subject's release is unconfirmed. */
|
|
41
|
+
releaseWarning;
|
|
40
42
|
commit;
|
|
41
43
|
hostDigest;
|
|
42
44
|
stateStepRecords = [];
|
|
@@ -50,15 +52,15 @@ export class ScriptedSubject {
|
|
|
50
52
|
}
|
|
51
53
|
/** Acquires, provisions and serves the subject. Returns the tokenless getHost URL to drive. */
|
|
52
54
|
async provision() {
|
|
53
|
-
const { plan, clone,
|
|
55
|
+
const { plan, clone, deps, prepareDesktop, env, e2bApiKey, runPaths, timeoutMs } = this.inputs;
|
|
54
56
|
const { subjectEnvNames, hasGithubToken, scrubKnownValues, now } = this.inputs;
|
|
55
57
|
const requestTimeoutMs = e2bRequestTimeoutMs(env);
|
|
56
|
-
const timers =
|
|
58
|
+
const timers = deps.detachedTimers ?? {};
|
|
57
59
|
const subjectSandboxTimeoutMs = timeoutMs +
|
|
58
60
|
SUBJECT_PROVISION_BUDGET_MS +
|
|
59
61
|
(clone.state?.seed ?? []).reduce((sum, step) => sum + (step.timeoutMs ?? DEFAULT_STATE_STEP_TIMEOUT_MS), 0) +
|
|
60
62
|
SANDBOX_TIMEOUT_BUFFER_MS;
|
|
61
|
-
const subjectModule = await (
|
|
63
|
+
const subjectModule = await (deps.desktopModule ?? loadE2BDesktopModule)();
|
|
62
64
|
await validatePreparedRunArtifactPaths(runPaths);
|
|
63
65
|
// The receipt is on disk before any work on the sandbox, so `humanish reclaim` can kill
|
|
64
66
|
// it by exact id when this process dies mid-run; the finally block below only runs while
|
|
@@ -92,8 +94,8 @@ export class ScriptedSubject {
|
|
|
92
94
|
this.sandboxId = subject.allocation.resourceId;
|
|
93
95
|
this.createdAtMs = now();
|
|
94
96
|
this.resources = await observeDesktopResources(subjectDesktop);
|
|
95
|
-
if (
|
|
96
|
-
await
|
|
97
|
+
if (prepareDesktop) {
|
|
98
|
+
await prepareDesktop(subjectDesktop, { kind: "subject" });
|
|
97
99
|
await validatePreparedRunArtifactPaths(runPaths);
|
|
98
100
|
}
|
|
99
101
|
this.commit = await provisionCloneSubject(e2bShell(subjectDesktop), {
|
|
@@ -137,7 +139,10 @@ export class ScriptedSubject {
|
|
|
137
139
|
this.killed = reading.released;
|
|
138
140
|
if (reading.warning)
|
|
139
141
|
warnings.push(reading.warning);
|
|
140
|
-
|
|
142
|
+
if (!reading.released)
|
|
143
|
+
this.releaseWarning = reading.warning ?? "Subject sandbox release is unconfirmed.";
|
|
144
|
+
// Without a kill method, or in E2B debug mode, no kill reached E2B, so there is no teardown
|
|
145
|
+
// time to record.
|
|
141
146
|
if (released.status !== "unconfirmed" || released.reason !== "release_unavailable")
|
|
142
147
|
this.tornDownAtMs = now();
|
|
143
148
|
}
|
|
@@ -44,7 +44,7 @@ export function scriptedSurfaceRecords(context, surface, index, result, screensh
|
|
|
44
44
|
embed: lastScreenshot
|
|
45
45
|
? { kind: "screenshot", url: `../${lastScreenshot}`, title: `${surface.label} (raw)` }
|
|
46
46
|
: { kind: "placeholder", title: surface.label },
|
|
47
|
-
//
|
|
47
|
+
// Real emulated viewport: isMobile/deviceScaleFactor genuinely render on this route
|
|
48
48
|
// (playwright emulation), unlike the e2b-desktop route's prompt-signal-only fidelity.
|
|
49
49
|
viewport: surface.viewport,
|
|
50
50
|
ui: {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { type ScriptedBrowserSessionOptions, type ScriptedBrowserSessionResult } from "../../actors/scripted-browser/actor.js";
|
|
2
2
|
import type { ScriptedPlan } from "../../lab/plan-types.js";
|
|
3
3
|
import { type PreparedRunArtifactPaths } from "../../run/paths.js";
|
|
4
|
-
import type {
|
|
4
|
+
import type { LabDeps } from "../../lab/lab-deps.js";
|
|
5
5
|
/** One session per surface, in parallel. */
|
|
6
6
|
export declare function runScriptedSessions(session: Required<Pick<ScriptedBrowserSessionOptions, "appUrl" | "evidenceAppUrl" | "urlPolicy" | "journey" | "persona" | "timeoutMs" | "artifactRoot">>, run: {
|
|
7
7
|
surfaces: ScriptedPlan["surfaces"];
|
|
8
|
-
|
|
8
|
+
deps: LabDeps;
|
|
9
9
|
browserCommand: string | undefined;
|
|
10
10
|
runPaths: PreparedRunArtifactPaths;
|
|
11
11
|
}): Promise<ScriptedBrowserSessionResult[]>;
|
|
@@ -7,8 +7,8 @@ import { validateScriptedSessionResult } from "./session-result.js";
|
|
|
7
7
|
/** One session per surface, in parallel. */
|
|
8
8
|
export function runScriptedSessions(session, run) {
|
|
9
9
|
const { appUrl, evidenceAppUrl, urlPolicy, journey, persona, timeoutMs, artifactRoot } = session;
|
|
10
|
-
const { surfaces,
|
|
11
|
-
const runSession =
|
|
10
|
+
const { surfaces, deps, browserCommand, runPaths } = run;
|
|
11
|
+
const runSession = deps.runScriptedSession;
|
|
12
12
|
return Promise.all(surfaces.map((surface) => {
|
|
13
13
|
const sessionOptions = {
|
|
14
14
|
appUrl,
|
|
@@ -20,8 +20,8 @@ export function runScriptedSessions(session, run) {
|
|
|
20
20
|
timeoutMs,
|
|
21
21
|
artifactRoot,
|
|
22
22
|
...(browserCommand === undefined ? {} : { browserCommand }),
|
|
23
|
-
...(
|
|
24
|
-
...(
|
|
23
|
+
...(deps.launchBrowser === undefined ? {} : { launchBrowser: deps.launchBrowser }),
|
|
24
|
+
...(deps.now === undefined ? {} : { now: deps.now }),
|
|
25
25
|
};
|
|
26
26
|
return runSession
|
|
27
27
|
? runSession(sessionOptions).then(async (result) => {
|