humanish 0.108.0 → 0.109.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/ARCHITECTURE.md +58 -59
- package/CHANGELOG.md +13 -0
- package/CONTEXT.md +44 -44
- package/README.md +3 -3
- package/TELEMETRY.md +2 -2
- package/dist/actors/codex/app-server-trace.js +2 -1
- package/dist/actors/codex/restricted-participant.js +12 -12
- package/dist/actors/codex/restricted-session.d.ts +2 -2
- package/dist/actors/computer-use/actor.d.ts +6 -6
- package/dist/actors/computer-use/actor.js +2 -2
- package/dist/actors/computer-use/admission-limit.d.ts +2 -2
- package/dist/actors/computer-use/admission-limit.js +3 -3
- package/dist/actors/computer-use/executor-error.d.ts +2 -2
- package/dist/actors/computer-use/executor-error.js +3 -3
- package/dist/actors/computer-use/loop/actions.js +5 -5
- package/dist/actors/computer-use/loop/debrief.js +2 -2
- package/dist/actors/computer-use/loop/ending.d.ts +1 -1
- package/dist/actors/computer-use/loop/ending.js +12 -11
- package/dist/actors/computer-use/loop/observation.js +6 -5
- package/dist/actors/computer-use/loop/provider-call.js +11 -11
- package/dist/actors/computer-use/loop/session.d.ts +4 -4
- package/dist/actors/computer-use/loop/session.js +2 -2
- package/dist/actors/computer-use/loop/trace.js +3 -2
- package/dist/actors/computer-use/loop/types.d.ts +24 -24
- package/dist/actors/computer-use/loop/usage.d.ts +2 -2
- package/dist/actors/computer-use/loop.d.ts +6 -1
- package/dist/actors/computer-use/loop.js +26 -4
- package/dist/actors/computer-use/openai-provider.d.ts +2 -2
- package/dist/actors/computer-use/openai-provider.js +8 -8
- package/dist/actors/computer-use/provider-error.d.ts +4 -4
- package/dist/actors/computer-use/provider-error.js +6 -6
- package/dist/actors/contract.d.ts +4 -4
- package/dist/actors/contract.js +1 -1
- package/dist/actors/local-agent/claude-session.js +3 -3
- package/dist/actors/local-agent/cli.d.ts +1 -1
- package/dist/actors/local-agent/cli.js +1 -1
- package/dist/actors/reasoning-effort.js +3 -3
- package/dist/actors/registry.d.ts +2 -2
- package/dist/actors/registry.js +3 -3
- package/dist/actors/scripted-browser/actor.d.ts +2 -2
- package/dist/actors/scripted-browser/actor.js +1 -1
- package/dist/analysis/automatic-completion.d.ts +7 -7
- package/dist/analysis/automatic-completion.js +1 -1
- package/dist/analysis/automatic-config.d.ts +6 -6
- package/dist/analysis/automatic-config.js +1 -1
- package/dist/analysis/execute.d.ts +1 -1
- package/dist/analysis/execute.js +1 -1
- package/dist/analysis/types.d.ts +6 -0
- package/dist/browser-control/client.js +16 -16
- package/dist/browser-control/dispatcher.js +4 -4
- package/dist/browser-control/protocol.js +14 -14
- package/dist/browser-control/recording-transfer.js +4 -4
- package/dist/browser-control/transport.js +7 -7
- package/dist/cli/commands/analysis-signals.d.ts +2 -2
- package/dist/cli/commands/comms.js +14 -22
- package/dist/cli/commands/observe.d.ts +0 -1
- package/dist/cli/commands/observe.js +0 -15
- package/dist/cli/commands/run-command.d.ts +2 -2
- package/dist/cli/commands/run-command.js +3 -3
- package/dist/cli/commands/runs.js +3 -5
- package/dist/cli/commands/setup.js +5 -7
- package/dist/cli/commands/study-format.d.ts +9 -0
- package/dist/cli/commands/{lab-format.js → study-format.js} +5 -5
- package/dist/cli/commands/{lab-route-computer-use.d.ts → study-route-computer-use.d.ts} +6 -6
- package/dist/cli/commands/{lab-route-computer-use.js → study-route-computer-use.js} +12 -12
- package/dist/cli/commands/{lab-route-open.d.ts → study-route-open.d.ts} +4 -4
- package/dist/cli/commands/{lab-route-open.js → study-route-open.js} +2 -2
- package/dist/cli/commands/{lab-route-preview.d.ts → study-route-preview.d.ts} +7 -7
- package/dist/cli/commands/{lab-route-preview.js → study-route-preview.js} +3 -3
- package/dist/cli/commands/study-route-run.d.ts +19 -0
- package/dist/cli/commands/{lab-route-run.js → study-route-run.js} +6 -6
- package/dist/cli/commands/study-route-scripted.d.ts +17 -0
- package/dist/cli/commands/{lab-route-scripted.js → study-route-scripted.js} +4 -4
- package/dist/cli/commands/{lab-route-shared-world.d.ts → study-route-shared-world.d.ts} +5 -5
- package/dist/cli/commands/{lab-route-shared-world.js → study-route-shared-world.js} +7 -7
- package/dist/cli/commands/study-route-terminal.d.ts +17 -0
- package/dist/cli/commands/{lab-route-terminal.js → study-route-terminal.js} +4 -4
- package/dist/cli/commands/study-run.d.ts +9 -0
- package/dist/cli/commands/{lab-run.js → study-run.js} +34 -34
- package/dist/cli/commands/{lab-scorer.d.ts → study-scorer.d.ts} +5 -5
- package/dist/cli/commands/{lab-scorer.js → study-scorer.js} +1 -1
- package/dist/cli/commands/study.js +13 -49
- package/dist/cli/commands/tui.js +12 -12
- package/dist/cli/commands/watch.js +30 -65
- package/dist/cli/deprecations.d.ts +1 -13
- package/dist/cli/deprecations.js +0 -30
- package/dist/cli/doctor.d.ts +3 -3
- package/dist/cli/doctor.js +16 -16
- package/dist/cli/first-run-path.d.ts +4 -4
- package/dist/cli/first-run-path.js +7 -7
- package/dist/cli/io.d.ts +3 -3
- package/dist/cli/io.js +2 -2
- package/dist/cli/observer-follow.d.ts +2 -2
- package/dist/cli/observer-follow.js +2 -2
- package/dist/cli/orientation.d.ts +4 -4
- package/dist/cli/orientation.js +58 -20
- package/dist/cli/program.js +3 -4
- package/dist/cli/telemetry.d.ts +1 -1
- package/dist/cli/telemetry.js +14 -20
- package/dist/comms/catch-host.d.ts +1 -1
- package/dist/comms/catch-host.js +3 -3
- package/dist/comms/connections.d.ts +1 -1
- package/dist/comms/connections.js +2 -2
- package/dist/comms/external-evidence.d.ts +5 -5
- package/dist/comms/external-evidence.js +4 -3
- package/dist/comms/fake-inbox.d.ts +2 -2
- package/dist/comms/fake-inbox.js +2 -2
- package/dist/comms/receiving-runtime.d.ts +4 -4
- package/dist/comms/sandbox-catch.d.ts +2 -2
- package/dist/comms/sandbox-catch.js +2 -2
- package/dist/comms/setup.d.ts +2 -2
- package/dist/comms/setup.js +29 -32
- package/dist/feedback/draft.js +2 -2
- package/dist/feedback/export.js +3 -2
- package/dist/feedback/proof.d.ts +1 -1
- package/dist/feedback/proof.js +2 -2
- package/dist/guest/bootstrap.js +6 -6
- package/dist/guest/browser-tools.js +8 -8
- package/dist/guest/chromium-text.js +17 -17
- package/dist/guest/desktop-executor.d.ts +2 -2
- package/dist/guest/desktop-executor.js +20 -20
- package/dist/guest/desktop-keys.js +4 -4
- package/dist/guest/desktop-media.d.ts +2 -2
- package/dist/guest/desktop-media.js +16 -16
- package/dist/guest/desktop-native.js +10 -10
- package/dist/guest/runtime-desktop.js +2 -2
- package/dist/guest/runtime-processes.d.ts +2 -2
- package/dist/guest/runtime-processes.js +2 -2
- package/dist/guest/runtime.js +5 -5
- package/dist/index.d.ts +13 -15
- package/dist/index.js +6 -8
- package/dist/observer/artifact.d.ts +1 -1
- package/dist/observer/artifact.js +1 -1
- package/dist/observer/data.d.ts +1 -1
- package/dist/observer/library.d.ts +2 -0
- package/dist/observer/library.js +4 -1
- package/dist/observer/render.js +7 -1
- package/dist/observer/run-routes.d.ts +1 -0
- package/dist/observer/run-routes.js +37 -12
- package/dist/observer/serve.d.ts +1 -1
- package/dist/observer-app.html +1 -1
- package/dist/routes/computer-use/bundle-parts.js +3 -2
- package/dist/routes/computer-use/bundle.d.ts +2 -2
- package/dist/routes/computer-use/bundle.js +7 -6
- package/dist/routes/computer-use/e2b-desktop/comms.d.ts +5 -5
- package/dist/routes/computer-use/e2b-desktop/comms.js +5 -4
- package/dist/routes/computer-use/e2b-desktop/fidelity.d.ts +1 -1
- package/dist/routes/computer-use/e2b-desktop/prepare.d.ts +1 -1
- package/dist/routes/computer-use/e2b-desktop/prepare.js +3 -3
- package/dist/routes/computer-use/e2b-desktop/start.js +3 -4
- package/dist/routes/computer-use/e2b-desktop/state.d.ts +2 -2
- package/dist/routes/computer-use/e2b-desktop/teardown.js +2 -3
- package/dist/routes/computer-use/external-comms.d.ts +3 -3
- package/dist/routes/computer-use/fanout-bundle.js +11 -10
- package/dist/routes/computer-use/fanout-records.js +2 -2
- package/dist/routes/computer-use/live-flush.d.ts +3 -3
- package/dist/routes/computer-use/live-phase.d.ts +2 -3
- package/dist/routes/computer-use/live-phase.js +3 -3
- package/dist/routes/computer-use/local-tree-pack.d.ts +5 -5
- package/dist/routes/computer-use/local-tree-pack.js +1 -1
- package/dist/routes/computer-use/local-vm.d.ts +8 -8
- package/dist/routes/computer-use/local-vm.js +2 -2
- package/dist/routes/computer-use/participant-desktop.d.ts +3 -3
- package/dist/routes/computer-use/participant-desktop.js +1 -1
- package/dist/routes/computer-use/participant-execution.js +1 -1
- package/dist/routes/computer-use/participant-model.js +3 -3
- package/dist/routes/computer-use/participant-prompt.d.ts +5 -5
- package/dist/routes/computer-use/participant-prompt.js +3 -3
- package/dist/routes/computer-use/participant-runs.d.ts +10 -10
- package/dist/routes/computer-use/participant-runs.js +14 -13
- package/dist/routes/computer-use/plan.d.ts +12 -12
- package/dist/routes/computer-use/plan.js +24 -24
- package/dist/routes/computer-use/preflight.d.ts +5 -5
- package/dist/routes/computer-use/preflight.js +5 -5
- package/dist/routes/computer-use/rerun-selection.d.ts +1 -1
- package/dist/routes/computer-use/rerun-selection.js +3 -2
- package/dist/routes/computer-use/result.d.ts +4 -4
- package/dist/routes/computer-use/result.js +13 -12
- package/dist/routes/computer-use/route.d.ts +12 -12
- package/dist/routes/computer-use/route.js +19 -19
- package/dist/routes/computer-use/self-report.js +1 -1
- package/dist/routes/computer-use/setup.d.ts +22 -22
- package/dist/routes/computer-use/setup.js +15 -15
- package/dist/routes/computer-use/single-bundle.d.ts +4 -4
- package/dist/routes/computer-use/single-bundle.js +14 -13
- package/dist/routes/computer-use/subject-projection.d.ts +3 -3
- package/dist/routes/computer-use/types.d.ts +34 -34
- package/dist/routes/computer-use/types.js +3 -3
- package/dist/routes/preview.d.ts +6 -6
- package/dist/routes/preview.js +5 -5
- package/dist/routes/scripted/bundle.d.ts +6 -6
- package/dist/routes/scripted/bundle.js +10 -9
- package/dist/routes/scripted/plan.d.ts +7 -7
- package/dist/routes/scripted/plan.js +6 -6
- package/dist/routes/scripted/result.d.ts +3 -3
- package/dist/routes/scripted/result.js +9 -9
- package/dist/routes/scripted/route.d.ts +9 -9
- package/dist/routes/scripted/route.js +11 -11
- package/dist/routes/scripted/scenario.d.ts +1 -1
- package/dist/routes/scripted/scenario.js +3 -3
- package/dist/routes/scripted/setup.d.ts +6 -6
- package/dist/routes/scripted/setup.js +4 -4
- package/dist/routes/scripted/subject.d.ts +5 -5
- package/dist/routes/scripted/subject.js +3 -3
- package/dist/routes/scripted/surface-records.d.ts +1 -1
- package/dist/routes/scripted/surface-records.js +2 -2
- package/dist/routes/scripted/surface-sessions.d.ts +3 -3
- package/dist/routes/scripted/types.d.ts +17 -17
- package/dist/routes/scripted/types.js +1 -1
- package/dist/routes/shared-world/bundle-records.js +3 -3
- package/dist/routes/shared-world/bundle.js +15 -14
- package/dist/routes/shared-world/checkpoints.d.ts +3 -3
- package/dist/routes/shared-world/checkpoints.js +1 -1
- package/dist/routes/shared-world/comms.d.ts +9 -9
- package/dist/routes/shared-world/comms.js +6 -5
- package/dist/routes/shared-world/participant-specs.d.ts +3 -3
- package/dist/routes/shared-world/participant-specs.js +7 -7
- package/dist/routes/shared-world/plan.d.ts +9 -9
- package/dist/routes/shared-world/plan.js +9 -9
- package/dist/routes/shared-world/provisioned.d.ts +8 -8
- package/dist/routes/shared-world/provisioned.js +4 -4
- package/dist/routes/shared-world/result.d.ts +6 -6
- package/dist/routes/shared-world/result.js +11 -10
- package/dist/routes/shared-world/route.d.ts +11 -11
- package/dist/routes/shared-world/route.js +19 -19
- package/dist/routes/shared-world/setup.d.ts +13 -13
- package/dist/routes/shared-world/setup.js +19 -19
- package/dist/routes/shared-world/types.d.ts +27 -27
- package/dist/routes/terminal/adapter.d.ts +2 -2
- package/dist/routes/terminal/adapter.js +4 -4
- package/dist/routes/terminal/bundle.d.ts +11 -11
- package/dist/routes/terminal/bundle.js +12 -12
- package/dist/routes/terminal/credentials.d.ts +4 -4
- package/dist/routes/terminal/credentials.js +5 -5
- package/dist/routes/terminal/dry-run.d.ts +4 -4
- package/dist/routes/terminal/dry-run.js +9 -9
- package/dist/routes/terminal/ledger.d.ts +2 -2
- package/dist/routes/terminal/lifetime.d.ts +1 -1
- package/dist/routes/terminal/lifetime.js +1 -1
- package/dist/routes/terminal/live-finish.d.ts +2 -2
- package/dist/routes/terminal/live-finish.js +7 -7
- package/dist/routes/terminal/live-sandbox.d.ts +2 -2
- package/dist/routes/terminal/live-sandbox.js +3 -2
- package/dist/routes/terminal/participant-text.js +2 -1
- package/dist/routes/terminal/persona.d.ts +2 -2
- package/dist/routes/terminal/persona.js +2 -2
- package/dist/routes/terminal/plan.d.ts +7 -7
- package/dist/routes/terminal/plan.js +5 -5
- package/dist/routes/terminal/result.d.ts +5 -5
- package/dist/routes/terminal/result.js +7 -7
- package/dist/routes/terminal/route.d.ts +9 -9
- package/dist/routes/terminal/route.js +14 -14
- package/dist/routes/terminal/session.d.ts +5 -5
- package/dist/routes/terminal/session.js +7 -7
- package/dist/routes/terminal/trace.d.ts +2 -2
- package/dist/routes/terminal/types.d.ts +24 -24
- package/dist/routes/terminal/types.js +2 -2
- package/dist/run/bundle.d.ts +7 -7
- package/dist/run/bundle.js +2 -2
- package/dist/run/costs.d.ts +23 -0
- package/dist/run/costs.js +72 -43
- package/dist/run/dry-run-inputs.d.ts +1 -1
- package/dist/run/dry-run-inputs.js +1 -1
- package/dist/run/dry-run.js +2 -2
- package/dist/run/outcomes.d.ts +1 -1
- package/dist/run/participant.d.ts +1 -1
- package/dist/run/preflight-receipts.js +1 -1
- package/dist/run/pricing.js +2 -2
- package/dist/run/projection.d.ts +32 -32
- package/dist/run/projection.js +44 -44
- package/dist/run/reclaim.d.ts +1 -1
- package/dist/run/reclaim.js +1 -1
- package/dist/run/results.d.ts +2 -2
- package/dist/run/run-cost.d.ts +53 -0
- package/dist/run/run-cost.js +105 -0
- package/dist/run/run-index-analysis.d.ts +15 -0
- package/dist/run/run-index-analysis.js +77 -0
- package/dist/run/run-index.d.ts +11 -1
- package/dist/run/run-index.js +63 -49
- package/dist/run/run.d.ts +3 -3
- package/dist/run/run.js +2 -2
- package/dist/run/shared-world-evidence.d.ts +1 -1
- package/dist/run/shared-world-shape.js +1 -1
- package/dist/run/stats.d.ts +3 -3
- package/dist/run/stats.js +14 -14
- package/dist/run/status.d.ts +10 -2
- package/dist/run/status.js +6 -3
- package/dist/run/streams.d.ts +2 -2
- package/dist/run/study-provenance.d.ts +4 -2
- package/dist/run/study-provenance.js +7 -4
- package/dist/run/study-result.d.ts +0 -5
- package/dist/run/study-result.js +1 -1
- package/dist/run-study.d.ts +112 -0
- package/dist/{run-lab.js → run-study.js} +52 -45
- package/dist/{lab → study}/adapter-extension.d.ts +8 -20
- package/dist/{lab → study}/adapter-extension.js +2 -14
- package/dist/{lab → study}/adapter-scorer-loader.d.ts +10 -10
- package/dist/{lab → study}/adapter-scorer-loader.js +3 -3
- package/dist/study/composition-rules.d.ts +7 -0
- package/dist/{lab → study}/composition-rules.js +12 -12
- package/dist/study/config.d.ts +15 -0
- package/dist/{lab → study}/config.js +37 -20
- package/dist/study/convert.d.ts +1 -1
- package/dist/study/convert.js +15 -15
- package/dist/{lab → study}/device-presets.d.ts +2 -2
- package/dist/{lab → study}/discover.d.ts +29 -23
- package/dist/{lab → study}/discover.js +97 -118
- package/dist/{lab → study}/doctor.d.ts +11 -11
- package/dist/{lab → study}/doctor.js +18 -18
- package/dist/study/files.d.ts +2 -2
- package/dist/study/files.js +6 -5
- package/dist/{lab → study}/init-templates.d.ts +2 -2
- package/dist/{lab → study}/init-templates.js +16 -11
- package/dist/{lab → study}/init.d.ts +1 -1
- package/dist/{lab → study}/init.js +7 -4
- package/dist/{lab → study}/keys.d.ts +2 -2
- package/dist/{lab → study}/keys.js +10 -10
- package/dist/study/migrate.d.ts +1 -1
- package/dist/{lab → study}/parse/actors.d.ts +5 -5
- package/dist/{lab → study}/parse/actors.js +5 -5
- package/dist/study/parse/comms.d.ts +12 -0
- package/dist/study/parse/execution.d.ts +19 -0
- package/dist/{lab → study}/parse/study-v3.d.ts +3 -5
- package/dist/{lab → study}/parse/study-v3.js +3 -3
- package/dist/{lab → study}/parse/subject-state.d.ts +8 -8
- package/dist/{lab → study}/parse/subject-state.js +4 -4
- package/dist/{lab → study}/parse/subject.d.ts +3 -3
- package/dist/{lab → study}/parse/subject.js +8 -8
- package/dist/{lab → study}/parse/values.d.ts +2 -2
- package/dist/{lab → study}/persona-resolve.d.ts +4 -4
- package/dist/{lab → study}/persona-resolve.js +2 -2
- package/dist/{lab → study}/plan-base.d.ts +7 -7
- package/dist/{lab → study}/plan-base.js +1 -1
- package/dist/{lab → study}/plan-participants.d.ts +10 -10
- package/dist/{lab → study}/plan-participants.js +4 -4
- package/dist/{lab → study}/plan-types.d.ts +28 -28
- package/dist/{lab → study}/plan-types.js +2 -2
- package/dist/study/plan.d.ts +13 -0
- package/dist/{lab → study}/plan.js +20 -20
- package/dist/study/preflight-probes.d.ts +3 -0
- package/dist/{lab → study}/preflight-probes.js +9 -8
- package/dist/study/preflight-result.d.ts +8 -0
- package/dist/{lab → study}/preflight-result.js +3 -3
- package/dist/{lab → study}/preflight.d.ts +31 -31
- package/dist/{lab → study}/preflight.js +8 -8
- package/dist/{lab → study}/requirements.d.ts +3 -3
- package/dist/{lab → study}/requirements.js +1 -1
- package/dist/study/route-inputs.d.ts +28 -0
- package/dist/{lab → study}/route-inputs.js +1 -1
- package/dist/{lab → study}/routing.d.ts +12 -12
- package/dist/{lab/run-lab-events.d.ts → study/run-study-events.d.ts} +10 -10
- package/dist/{lab/run-lab-events.js → study/run-study-events.js} +3 -3
- package/dist/{lab/run-lab-homes.d.ts → study/run-study-homes.d.ts} +8 -17
- package/dist/study/run-study-homes.js +3 -0
- package/dist/study/run-study-options.d.ts +28 -0
- package/dist/{lab/run-lab-options.js → study/run-study-options.js} +13 -12
- package/dist/{lab/lab-deps.d.ts → study/study-deps.d.ts} +2 -2
- package/dist/{lab/lab-deps.js → study/study-deps.js} +2 -2
- package/dist/{lab → study}/summary.d.ts +10 -10
- package/dist/{lab → study}/summary.js +15 -15
- package/dist/{lab → study}/tasks.d.ts +3 -3
- package/dist/{lab → study}/tasks.js +1 -1
- package/dist/{lab → study}/types.d.ts +104 -104
- package/dist/{lab → study}/types.js +1 -1
- package/dist/{lab → study}/validation.d.ts +19 -19
- package/dist/{lab → study}/validation.js +13 -13
- package/dist/{lab → study}/warnings.d.ts +4 -4
- package/dist/{lab → study}/warnings.js +1 -1
- package/dist/subject/clone.d.ts +6 -6
- package/dist/subject/clone.js +2 -2
- package/dist/subject/local-tree-archive.d.ts +2 -2
- package/dist/subject/local-tree-archive.js +3 -3
- package/dist/subject/local-tree.d.ts +3 -3
- package/dist/subject/runtime.js +2 -2
- package/dist/subject/serve.d.ts +4 -4
- package/dist/subject/state.d.ts +3 -3
- package/dist/subject/state.js +1 -1
- package/dist/subject/steps.d.ts +1 -1
- package/dist/subject/steps.js +1 -1
- package/dist/substrates/desktop-session.js +2 -2
- package/dist/substrates/detached.d.ts +1 -1
- package/dist/substrates/e2b/desktop-browser.d.ts +4 -4
- package/dist/substrates/e2b/desktop-browser.js +1 -1
- package/dist/substrates/e2b/desktop-cdp.d.ts +1 -1
- package/dist/substrates/e2b/desktop-cdp.js +1 -1
- package/dist/substrates/e2b/desktop-executor.d.ts +1 -1
- package/dist/substrates/e2b/desktop-executor.js +12 -12
- package/dist/substrates/e2b/desktop-geometry.d.ts +1 -1
- package/dist/substrates/e2b/desktop-geometry.js +1 -1
- package/dist/substrates/e2b/desktop-media.d.ts +3 -3
- package/dist/substrates/e2b/lifetime.js +1 -1
- package/dist/substrates/e2b/sandbox.d.ts +3 -3
- package/dist/substrates/e2b/sandbox.js +1 -1
- package/dist/substrates/e2b/sdk.d.ts +1 -1
- package/dist/substrates/e2b/sdk.js +1 -1
- package/dist/substrates/local/runtime-config.d.ts +4 -4
- package/dist/substrates/local/runtime-config.js +4 -4
- package/dist/tui/contract.d.ts +8 -8
- package/dist/tui/contract.js +2 -2
- package/dist/tui/launch.d.ts +3 -3
- package/dist/tui/launch.js +22 -16
- package/dist/tui-app.js +139 -139
- package/dist/verify/subject.d.ts +1 -1
- package/dist/verify/subject.js +1 -1
- package/dist/verify/verify.js +2 -1
- package/docs/architecture/actor-contract.md +5 -5
- package/docs/architecture/browser-control.md +1 -1
- package/docs/architecture/external-public-shared-world.md +8 -7
- package/docs/architecture/github-feedback-loop.md +1 -1
- package/docs/architecture/task-protocol-support.md +1 -1
- package/docs/architecture/terminal-product-route.md +18 -18
- package/docs/contracts/adapter-fixtures.md +2 -2
- package/docs/contracts/errors.md +8 -8
- package/docs/contracts/run-bundle.md +1 -4
- package/docs/contracts/schemas.md +61 -42
- package/docs/contracts/study-analysis.md +4 -1
- package/docs/contracts/study-costs.md +17 -2
- package/examples/README.md +1 -1
- package/examples/scorer/scorer.mjs +3 -3
- package/package.json +1 -1
- package/skills/humanish/SKILL.md +8 -6
- package/skills/humanish/agents/openai.yaml +1 -1
- package/dist/cli/commands/lab-format.d.ts +0 -9
- package/dist/cli/commands/lab-route-run.d.ts +0 -19
- package/dist/cli/commands/lab-route-scripted.d.ts +0 -17
- package/dist/cli/commands/lab-route-terminal.d.ts +0 -17
- package/dist/cli/commands/lab-run.d.ts +0 -9
- package/dist/lab/composition-rules.d.ts +0 -7
- package/dist/lab/config.d.ts +0 -7
- package/dist/lab/deprecated-fields.d.ts +0 -10
- package/dist/lab/deprecated-fields.js +0 -24
- package/dist/lab/parse/comms.d.ts +0 -12
- package/dist/lab/parse/execution.d.ts +0 -19
- package/dist/lab/plan.d.ts +0 -13
- package/dist/lab/preflight-probes.d.ts +0 -3
- package/dist/lab/preflight-result.d.ts +0 -8
- package/dist/lab/route-inputs.d.ts +0 -28
- package/dist/lab/run-lab-homes.js +0 -7
- package/dist/lab/run-lab-options.d.ts +0 -28
- package/dist/library-aliases.d.ts +0 -56
- package/dist/library-aliases.js +0 -22
- package/dist/run-lab.d.ts +0 -112
- /package/dist/{lab → study}/device-presets.js +0 -0
- /package/dist/{lab → study}/init-paths.d.ts +0 -0
- /package/dist/{lab → study}/init-paths.js +0 -0
- /package/dist/{lab → study}/init-plan.d.ts +0 -0
- /package/dist/{lab → study}/init-plan.js +0 -0
- /package/dist/{lab → study}/parse/comms.js +0 -0
- /package/dist/{lab → study}/parse/execution.js +0 -0
- /package/dist/{lab → study}/parse/values.js +0 -0
- /package/dist/{lab → study}/participant-assignment.d.ts +0 -0
- /package/dist/{lab → study}/participant-assignment.js +0 -0
- /package/dist/{lab → study}/persona.d.ts +0 -0
- /package/dist/{lab → study}/persona.js +0 -0
- /package/dist/{lab → study}/routing.js +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
2
|
import type { ObserverResult, ObserverServer } from "../observer/render.js";
|
|
3
3
|
import type { ExposureRequest } from "../observer/exposure.js";
|
|
4
|
-
import { type CliIo, type
|
|
4
|
+
import { type CliIo, type StudyCommandOptions, type HumanOutput } from "./io.js";
|
|
5
5
|
/** How a command shows an Observer, decided before the run it shows starts. */
|
|
6
6
|
export interface ObserverPlan {
|
|
7
7
|
port: number;
|
|
@@ -52,5 +52,5 @@ export declare function watchExposeRequested(o: {
|
|
|
52
52
|
allowDomain?: string[] | undefined;
|
|
53
53
|
publicUrl?: string | undefined;
|
|
54
54
|
}): boolean;
|
|
55
|
-
export declare function exposureRequestFromOptions(options:
|
|
55
|
+
export declare function exposureRequestFromOptions(options: StudyCommandOptions): ExposureRequest;
|
|
56
56
|
export {};
|
|
@@ -133,7 +133,7 @@ export function exitCodeForSignal(signal) {
|
|
|
133
133
|
}
|
|
134
134
|
}
|
|
135
135
|
// True when any tunnel-edge exposure flag is present (not --safe, which is an orthogonal filter).
|
|
136
|
-
// Callers refuse exposure with it on the
|
|
136
|
+
// Callers refuse exposure with it on the watch path without a study and on non-computer-use routes, where
|
|
137
137
|
// there is no live desktop to stream.
|
|
138
138
|
export function watchExposeRequested(o) {
|
|
139
139
|
return (o.expose === true ||
|
|
@@ -144,7 +144,7 @@ export function watchExposeRequested(o) {
|
|
|
144
144
|
(o.allowDomain?.length ?? 0) > 0 ||
|
|
145
145
|
o.publicUrl !== undefined);
|
|
146
146
|
}
|
|
147
|
-
// Map
|
|
147
|
+
// Map StudyCommandOptions onto the shared exposure validator input.
|
|
148
148
|
export function exposureRequestFromOptions(options) {
|
|
149
149
|
return {
|
|
150
150
|
expose: options.expose === true,
|
|
@@ -3,10 +3,10 @@ export interface OrientationState {
|
|
|
3
3
|
schema: typeof ORIENTATION_SCHEMA;
|
|
4
4
|
/** Whether this project has a committed `humanish/` source plane. */
|
|
5
5
|
initialized: boolean;
|
|
6
|
-
/** Committed
|
|
7
|
-
|
|
8
|
-
/** Ids of a few
|
|
9
|
-
|
|
6
|
+
/** Committed and gitignored study files found in this project. */
|
|
7
|
+
studyCount: number;
|
|
8
|
+
/** Ids of a few studies worth naming in a suggestion. */
|
|
9
|
+
studyIds: string[];
|
|
10
10
|
/** Runs already on disk, and the most recent one if there is one. */
|
|
11
11
|
runCount: number;
|
|
12
12
|
latestRunId?: string;
|
package/dist/cli/orientation.js
CHANGED
|
@@ -12,8 +12,9 @@
|
|
|
12
12
|
// Both audiences are served by the same data (docs/principles/three-roles.md). A human on a
|
|
13
13
|
// terminal gets prose and an offer to set things up; an agent gets the same facts as stable text,
|
|
14
14
|
// or as JSON with `--json`. Neither is a special case of the other bolted on afterwards.
|
|
15
|
-
import {
|
|
15
|
+
import { listStudyManifests } from "../study/discover.js";
|
|
16
16
|
import { listRuns } from "../run/stored-runs.js";
|
|
17
|
+
import { plural } from "../run/text.js";
|
|
17
18
|
import { supportsLocalBrowser } from "./first-run-path.js";
|
|
18
19
|
import { PRODUCT_SENTENCE } from "./product-sentence.js";
|
|
19
20
|
export const ORIENTATION_SCHEMA = "humanish.orientation.v1";
|
|
@@ -22,26 +23,39 @@ export const ORIENTATION_SCHEMA = "humanish.orientation.v1";
|
|
|
22
23
|
* a provider: bare invocation must not be able to spend money or mutate a repo.
|
|
23
24
|
*/
|
|
24
25
|
export async function readOrientation(cwd, host = process) {
|
|
25
|
-
const [
|
|
26
|
-
|
|
26
|
+
const [found, runs] = await Promise.all([
|
|
27
|
+
listStudyManifests(cwd).catch(() => undefined),
|
|
27
28
|
listRuns(cwd).catch(() => undefined),
|
|
28
29
|
]);
|
|
29
|
-
const
|
|
30
|
-
.map((
|
|
30
|
+
const studyIds = (found?.studies ?? [])
|
|
31
|
+
.map((study) => study.id)
|
|
31
32
|
.filter((id) => typeof id === "string");
|
|
32
33
|
const runIds = (runs?.runs ?? [])
|
|
33
34
|
.map((run) => run.runId)
|
|
34
35
|
.filter((id) => typeof id === "string");
|
|
35
36
|
const latest = typeof runs?.latest === "string" ? runs.latest : runIds[0];
|
|
36
|
-
const
|
|
37
|
+
const retiredFiles = found?.retired ?? [];
|
|
38
|
+
const retired = {
|
|
39
|
+
v2: retiredFiles.filter((file) => file.code === "HUMANISH_STUDY_V2_UNSUPPORTED").length,
|
|
40
|
+
moved: retiredFiles.filter((file) => file.code === "HUMANISH_STUDY_RETIRED_DIRECTORY").length,
|
|
41
|
+
};
|
|
42
|
+
const initialized = (found?.studies ?? []).some((study) => study.origin === "committed") ||
|
|
43
|
+
studyIds.length > 0 ||
|
|
44
|
+
retiredFiles.length > 0;
|
|
37
45
|
return {
|
|
38
46
|
schema: ORIENTATION_SCHEMA,
|
|
39
47
|
initialized,
|
|
40
|
-
|
|
41
|
-
|
|
48
|
+
studyCount: studyIds.length,
|
|
49
|
+
studyIds: studyIds.slice(0, 3),
|
|
42
50
|
runCount: runIds.length,
|
|
43
51
|
...(latest === undefined ? {} : { latestRunId: latest }),
|
|
44
|
-
nextCommands: nextCommandsFor({
|
|
52
|
+
nextCommands: nextCommandsFor({
|
|
53
|
+
initialized,
|
|
54
|
+
studyIds,
|
|
55
|
+
retired,
|
|
56
|
+
hasRun: runIds.length > 0,
|
|
57
|
+
host,
|
|
58
|
+
}),
|
|
45
59
|
};
|
|
46
60
|
}
|
|
47
61
|
/**
|
|
@@ -49,6 +63,30 @@ export async function readOrientation(cwd, host = process) {
|
|
|
49
63
|
* is commander's help, which nobody reads.
|
|
50
64
|
*/
|
|
51
65
|
function nextCommandsFor(args) {
|
|
66
|
+
const { v2, moved } = args.retired;
|
|
67
|
+
const fixes = [
|
|
68
|
+
...(v2 === 0
|
|
69
|
+
? []
|
|
70
|
+
: [
|
|
71
|
+
{
|
|
72
|
+
command: "humanish migrate --dry-run",
|
|
73
|
+
why: `${plural(v2, "study file")} ${v2 === 1 ? "uses" : "use"} humanish.lab.v2, which humanish no longer reads; this lists the conversion, and humanish migrate writes it`,
|
|
74
|
+
},
|
|
75
|
+
]),
|
|
76
|
+
...(moved === 0
|
|
77
|
+
? []
|
|
78
|
+
: [
|
|
79
|
+
{
|
|
80
|
+
command: "humanish study list",
|
|
81
|
+
why: `${plural(moved, "study file")} ${moved === 1 ? "is" : "are"} in a labs/ directory, which humanish no longer reads; this names each one and the studies/ directory to move it to`,
|
|
82
|
+
},
|
|
83
|
+
]),
|
|
84
|
+
];
|
|
85
|
+
// A fix that is already `humanish study list` replaces the plain suggestion of the same command.
|
|
86
|
+
const named = new Set(fixes.map((fix) => fix.command));
|
|
87
|
+
return [...fixes, ...nextCommandsForStudies(args).filter((next) => !named.has(next.command))];
|
|
88
|
+
}
|
|
89
|
+
function nextCommandsForStudies(args) {
|
|
52
90
|
const dryRun = {
|
|
53
91
|
command: "humanish run first-run",
|
|
54
92
|
why: "a dry run: no browser or model runs, no keys, no spend",
|
|
@@ -57,31 +95,31 @@ function nextCommandsFor(args) {
|
|
|
57
95
|
return [
|
|
58
96
|
{
|
|
59
97
|
command: "humanish init --yes",
|
|
60
|
-
why: "write starter
|
|
98
|
+
why: "write starter studies, personas and an AGENTS.md (--dry-run lists every file first)",
|
|
61
99
|
},
|
|
62
100
|
dryRun,
|
|
63
101
|
];
|
|
64
102
|
}
|
|
65
|
-
// The starter live
|
|
103
|
+
// The starter live study this host can run. The other starter studies are templates whose subject
|
|
66
104
|
// still names your-org/your-app, so they are never suggested.
|
|
67
|
-
const
|
|
105
|
+
const liveStudy = (supportsLocalBrowser(args.host.platform, args.host.arch)
|
|
68
106
|
? ["local-browser", "try-live"]
|
|
69
|
-
: ["try-live"]).find((id) => args.
|
|
107
|
+
: ["try-live"]).find((id) => args.studyIds.includes(id));
|
|
70
108
|
if (!args.hasRun) {
|
|
71
109
|
return [
|
|
72
110
|
dryRun,
|
|
73
|
-
|
|
111
|
+
liveStudy === undefined
|
|
74
112
|
? { command: "humanish study list", why: "see the studies this project declares" }
|
|
75
113
|
: {
|
|
76
|
-
command: `humanish doctor --study ${
|
|
77
|
-
why: `check what the ${
|
|
114
|
+
command: `humanish doctor --study ${liveStudy}`,
|
|
115
|
+
why: `check what the ${liveStudy} study still needs before a live run`,
|
|
78
116
|
},
|
|
79
117
|
];
|
|
80
118
|
}
|
|
81
119
|
return [
|
|
82
|
-
...(
|
|
120
|
+
...(liveStudy === undefined
|
|
83
121
|
? []
|
|
84
|
-
: [{ command: `humanish run ${
|
|
122
|
+
: [{ command: `humanish run ${liveStudy}`, why: "run a real participant against an app" }]),
|
|
85
123
|
{
|
|
86
124
|
command: "humanish verify --run latest",
|
|
87
125
|
why: "check the last run's evidence and public-safety gates",
|
|
@@ -99,13 +137,13 @@ export function formatOrientationHuman(state) {
|
|
|
99
137
|
lines.push("This project is not set up yet.");
|
|
100
138
|
}
|
|
101
139
|
else {
|
|
102
|
-
const
|
|
140
|
+
const studies = state.studyCount === 1 ? "1 study" : `${state.studyCount} studies`;
|
|
103
141
|
const runs = state.runCount === 0
|
|
104
142
|
? "no runs yet"
|
|
105
143
|
: state.runCount === 1
|
|
106
144
|
? "1 run"
|
|
107
145
|
: `${state.runCount} runs`;
|
|
108
|
-
lines.push(`This project has ${
|
|
146
|
+
lines.push(`This project has ${studies} and ${runs}${state.latestRunId ? ` (latest: ${state.latestRunId})` : ""}.`);
|
|
109
147
|
}
|
|
110
148
|
lines.push("");
|
|
111
149
|
for (const next of state.nextCommands) {
|
package/dist/cli/program.js
CHANGED
|
@@ -12,7 +12,7 @@ import { registerCommsCommands } from "./commands/comms.js";
|
|
|
12
12
|
import { registerFeedbackCommands } from "./commands/feedback.js";
|
|
13
13
|
import { registerStudyCommands } from "./commands/study.js";
|
|
14
14
|
import { registerMigrateCommand } from "./commands/migrate.js";
|
|
15
|
-
import { registerObserveCommand
|
|
15
|
+
import { registerObserveCommand } from "./commands/observe.js";
|
|
16
16
|
import { registerCleanupCommand, registerExportCommand, registerReclaimCommand, registerReviewCommand, registerRunCommand, registerRunsCommand, registerRuntimeCommands, registerStatsCommand, registerVerifyCommand, } from "./commands/runs.js";
|
|
17
17
|
import { registerDoctorCommand, registerInitCommand, registerKeysCommand, registerTelemetryCommand, } from "./commands/setup.js";
|
|
18
18
|
import { defaultTuiRuntime, registerTuiCommand } from "./commands/tui.js";
|
|
@@ -73,7 +73,7 @@ async function recordCommandTelemetry(command, ok, durationMs, exitCode) {
|
|
|
73
73
|
event: "cli_command",
|
|
74
74
|
anonymousId: state.anonymousId,
|
|
75
75
|
version: CLI_VERSION,
|
|
76
|
-
// The study facts (mode, outcome, starter
|
|
76
|
+
// The study facts (mode, outcome, starter study, brain, our own error code) were read off the
|
|
77
77
|
// result document when it was written; see writeResult. Without them every `run` event
|
|
78
78
|
// looked the same whether it was a dry run or the first live study that ever worked.
|
|
79
79
|
properties: {
|
|
@@ -116,7 +116,7 @@ function reportActiveHandles(command, io) {
|
|
|
116
116
|
io.writeErr(`humanish debug: active resources after \`${commandPath(command) || "humanish"}\` settled: ${summary}\n`);
|
|
117
117
|
}).unref?.();
|
|
118
118
|
}
|
|
119
|
-
/** `
|
|
119
|
+
/** `study show`, not `show`, so subcommands are distinguishable, and nothing else from the invocation. */
|
|
120
120
|
function commandPath(command) {
|
|
121
121
|
const parts = [];
|
|
122
122
|
let current = command;
|
|
@@ -370,7 +370,6 @@ export function createProgram(io = {}) {
|
|
|
370
370
|
registerCleanupCommand(program, cliIo);
|
|
371
371
|
registerKeysCommand(program, cliIo);
|
|
372
372
|
registerTelemetryCommand(program, cliIo);
|
|
373
|
-
registerServeCommand(program, cliIo);
|
|
374
373
|
registerTuiCommand(program, cliIo, { ...defaultTuiRuntime, ...io.tuiRuntime });
|
|
375
374
|
registerCodexCommands(program, cliIo);
|
|
376
375
|
// Only the root takes a stray word, so the action above can name the command it meant. Set after
|
package/dist/cli/telemetry.d.ts
CHANGED
|
@@ -78,7 +78,7 @@ export declare function buildPayload(args: {
|
|
|
78
78
|
nodeVersion?: string;
|
|
79
79
|
}): TelemetryPayload;
|
|
80
80
|
/**
|
|
81
|
-
* Read the study facts off a command's result document: mode, outcome, starter
|
|
81
|
+
* Read the study facts off a command's result document: mode, outcome, starter study, brain route,
|
|
82
82
|
* and our own error code. Duck-typed over every result shape the CLI writes, because the point is
|
|
83
83
|
* one derivation at the one seam every command already passes through (writeResult), so that a
|
|
84
84
|
* backend added later cannot forget to report. Returns {} for results that carry no study.
|
package/dist/cli/telemetry.js
CHANGED
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
// working first run". A tool that cannot see its own activation is guessing.
|
|
6
6
|
//
|
|
7
7
|
// What it will never send, and this is stricter than the convention because of what humanish is:
|
|
8
|
-
// no paths, no cwd, no repo names, no URLs, no
|
|
8
|
+
// no paths, no cwd, no repo names, no URLs, no study titles or ids that are not our own starter studies,
|
|
9
9
|
// no persona or mission text, no run ids, no evidence, no key values, no key names. A study's
|
|
10
|
-
// subject is the adopter's product and often unannounced; leaking a
|
|
10
|
+
// subject is the adopter's product and often unannounced; leaking a study id would leak a roadmap.
|
|
11
11
|
// The allowlist below is the whole vocabulary: anything not on it cannot be sent by construction.
|
|
12
12
|
import { isCuaDiagnosticCategory, isCuaDiagnosticStopCause, } from "../routes/computer-use/diagnostics.js";
|
|
13
13
|
import { randomUUID } from "node:crypto";
|
|
@@ -175,12 +175,8 @@ export function buildPayload(args) {
|
|
|
175
175
|
const given = args.properties ?? {};
|
|
176
176
|
if (given.command !== undefined)
|
|
177
177
|
properties.command = given.command;
|
|
178
|
-
if (given.study !== undefined)
|
|
178
|
+
if (given.study !== undefined)
|
|
179
179
|
properties.study = given.study;
|
|
180
|
-
// Removed in 0.109.0: `lab`, the property's 0.107 name, carries the same value until then, so
|
|
181
|
-
// a dashboard that filters on `lab` keeps reading 0.108 events while older clients send `lab`.
|
|
182
|
-
properties.lab = given.study;
|
|
183
|
-
}
|
|
184
180
|
if (given.mode !== undefined)
|
|
185
181
|
properties.mode = given.mode;
|
|
186
182
|
if (given.outcome !== undefined)
|
|
@@ -236,7 +232,7 @@ function asRecord(value) {
|
|
|
236
232
|
: undefined;
|
|
237
233
|
}
|
|
238
234
|
/**
|
|
239
|
-
* Read the study facts off a command's result document: mode, outcome, starter
|
|
235
|
+
* Read the study facts off a command's result document: mode, outcome, starter study, brain route,
|
|
240
236
|
* and our own error code. Duck-typed over every result shape the CLI writes, because the point is
|
|
241
237
|
* one derivation at the one seam every command already passes through (writeResult), so that a
|
|
242
238
|
* backend added later cannot forget to report. Returns {} for results that carry no study.
|
|
@@ -257,18 +253,16 @@ export function deriveRunFacts(result) {
|
|
|
257
253
|
else if (r.mode === "dry-run" || r.mode === "live")
|
|
258
254
|
facts.mode = r.mode;
|
|
259
255
|
const studyRecord = asRecord(r.study) ?? asRecord(r.lab);
|
|
260
|
-
const
|
|
256
|
+
const studyId = typeof r.studyId === "string"
|
|
261
257
|
? r.studyId
|
|
262
|
-
: typeof
|
|
263
|
-
?
|
|
264
|
-
: typeof
|
|
265
|
-
?
|
|
266
|
-
: typeof r.
|
|
267
|
-
? r.
|
|
268
|
-
:
|
|
269
|
-
|
|
270
|
-
: undefined;
|
|
271
|
-
const study = safeStudyId(labId);
|
|
258
|
+
: typeof studyRecord?.id === "string"
|
|
259
|
+
? studyRecord.id
|
|
260
|
+
: typeof r.study === "string"
|
|
261
|
+
? r.study
|
|
262
|
+
: typeof r.lab === "string"
|
|
263
|
+
? r.lab
|
|
264
|
+
: undefined;
|
|
265
|
+
const study = safeStudyId(studyId);
|
|
272
266
|
if (study !== undefined)
|
|
273
267
|
facts.study = study;
|
|
274
268
|
const error = asRecord(r.error);
|
|
@@ -323,7 +317,7 @@ export function deriveRunFacts(result) {
|
|
|
323
317
|
/** The notice, shown once, before anything is sent. */
|
|
324
318
|
export const TELEMETRY_NOTICE = [
|
|
325
319
|
"humanish collects anonymous usage data (which command ran, whether it worked, how long it took).",
|
|
326
|
-
"It never sends your
|
|
320
|
+
"It never sends your studies, subjects, personas, paths, or evidence. Opt out any time:",
|
|
327
321
|
" humanish telemetry disable (or set DO_NOT_TRACK=1)",
|
|
328
322
|
" humanish telemetry status shows exactly what is collected",
|
|
329
323
|
].join("\n");
|
|
@@ -15,7 +15,7 @@ export interface CommsCatchHostOptions {
|
|
|
15
15
|
/** Optional loopback SMTP listener sharing the HTTP capture and inbox pipeline. */
|
|
16
16
|
smtpPort?: number;
|
|
17
17
|
/** Restrict the rendered inbox to these addresses. Omit to render whatever the app actually mailed;
|
|
18
|
-
* a standalone catch has no
|
|
18
|
+
* a standalone catch has no study roster to read recipients from, and an operator who forgets to
|
|
19
19
|
* name one should not get a healthy catch that renders an empty inbox forever. */
|
|
20
20
|
recipients?: string[];
|
|
21
21
|
/** Inbox re-render cadence in ms (test seam). */
|
package/dist/comms/catch-host.js
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
// Shipping it as a command rather than a spec matters: the adopter runs the identical
|
|
12
12
|
// implementation humanish deploys in-sandbox, so the capture shape, the inbox surface, and the
|
|
13
13
|
// drain contract cannot drift between the two planes. Point the app's email-API base URL at this
|
|
14
|
-
// server and point the
|
|
14
|
+
// server and point the study's `catchBaseUrl` at it too.
|
|
15
15
|
//
|
|
16
16
|
// Runtime: the catch is a python3 stdlib server with no dependencies (that was the 0.29.0 lesson:
|
|
17
17
|
// a co-located catcher must use a runtime the environment guarantees). This command writes the
|
|
@@ -135,11 +135,11 @@ export async function runCommsCatchHost(options, io) {
|
|
|
135
135
|
]),
|
|
136
136
|
` POST /emails <- point your app's email-API base URL here`,
|
|
137
137
|
` GET /inbox <- shared operator inbox${inboxPort === undefined ? " (loopback only without --inbox-port)" : ""}`,
|
|
138
|
-
` GET /inbox/for/... <- assigned participant inbox (linked by the
|
|
138
|
+
` GET /inbox/for/... <- assigned participant inbox (linked by the study)`,
|
|
139
139
|
` GET /deliveries <- humanish drains this${options.token ? " (bearer token required)" : ""}`,
|
|
140
140
|
` GET /health <- readiness marker humanish probes before a run`,
|
|
141
141
|
``,
|
|
142
|
-
`Declare it in the
|
|
142
|
+
`Declare it in the study:`,
|
|
143
143
|
` comms:`,
|
|
144
144
|
` email:`,
|
|
145
145
|
` external:`,
|
|
@@ -16,5 +16,5 @@ export interface CommsSetupResult {
|
|
|
16
16
|
}
|
|
17
17
|
/** Offline and non-mutating. Unsafe storage is an error, never an empty configuration. */
|
|
18
18
|
export declare function readCommsConnections(cwd: string): Promise<CommsConnections>;
|
|
19
|
-
/** Add one exact profile. No
|
|
19
|
+
/** Add one exact profile. No study mutation, network, provider resources or credential values. */
|
|
20
20
|
export declare function saveCommsConnection(cwd: string, name?: string, apiKeyEnv?: string): Promise<CommsSetupResult>;
|
|
@@ -65,7 +65,7 @@ export async function readCommsConnections(cwd) {
|
|
|
65
65
|
throw new Error("Invalid connection configuration.");
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
|
-
/** Add one exact profile. No
|
|
68
|
+
/** Add one exact profile. No study mutation, network, provider resources or credential values. */
|
|
69
69
|
export async function saveCommsConnection(cwd, name = DEFAULT_COMMS_PROVIDER.id, apiKeyEnv = DEFAULT_COMMS_PROVIDER.keyEnv) {
|
|
70
70
|
const provider = DEFAULT_COMMS_PROVIDER.id;
|
|
71
71
|
try {
|
|
@@ -94,7 +94,7 @@ export async function saveCommsConnection(cwd, name = DEFAULT_COMMS_PROVIDER.id,
|
|
|
94
94
|
await writeContainedOutputFile(root, "comms.yaml", stringify(config), "utf8");
|
|
95
95
|
return {
|
|
96
96
|
ok: true,
|
|
97
|
-
message: "Connection saved for this project. Select it in a supported
|
|
97
|
+
message: "Connection saved for this project. Select it in a supported study to use fresh real inboxes.",
|
|
98
98
|
};
|
|
99
99
|
}
|
|
100
100
|
finally {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { StudyCommsEmail, StudyCommsExternal } from "../study/types.js";
|
|
2
2
|
import type { PreparedRunArtifactPaths } from "../run/paths.js";
|
|
3
3
|
/**
|
|
4
4
|
* Why a catch token cannot be used, or undefined when it can. An unset or empty token is none. A
|
|
@@ -6,8 +6,8 @@ import type { PreparedRunArtifactPaths } from "../run/paths.js";
|
|
|
6
6
|
* refused with the short ones.
|
|
7
7
|
*/
|
|
8
8
|
export declare function catchTokenRefusal(token: string | undefined): string | undefined;
|
|
9
|
-
/** The catch token the run sends: the value of `authTokenEnv`, when the
|
|
10
|
-
export declare function catchTokenOf(external:
|
|
9
|
+
/** The catch token the run sends: the value of `authTokenEnv`, when the study names one. */
|
|
10
|
+
export declare function catchTokenOf(external: StudyCommsExternal, env: Record<string, string | undefined>): string | undefined;
|
|
11
11
|
/**
|
|
12
12
|
* Drains the catch, routes its sends to the declared recipients' inboxes and writes the thread to
|
|
13
13
|
* `comms/thread.json`. Returns that path when a message matched, and the warnings to add to the
|
|
@@ -15,8 +15,8 @@ export declare function catchTokenOf(external: LabCommsExternal, env: Record<str
|
|
|
15
15
|
* throws: the run continues without comms evidence.
|
|
16
16
|
*/
|
|
17
17
|
export declare function collectExternalCommsEvidence(args: {
|
|
18
|
-
external:
|
|
19
|
-
email:
|
|
18
|
+
external: StudyCommsExternal;
|
|
19
|
+
email: StudyCommsEmail;
|
|
20
20
|
env: Record<string, string | undefined>;
|
|
21
21
|
runPaths: PreparedRunArtifactPaths;
|
|
22
22
|
/** The run's known secret values. The route may add to it until the drain runs. */
|
|
@@ -4,10 +4,11 @@
|
|
|
4
4
|
// shape for pattern redaction to find.
|
|
5
5
|
import { redactText, toErrorMessage } from "../evidence/redaction.js";
|
|
6
6
|
import { scrubSecretValues } from "../evidence/secret-scrub.js";
|
|
7
|
-
import { addressedRecipients } from "../
|
|
7
|
+
import { addressedRecipients } from "../study/parse/comms.js";
|
|
8
8
|
import { writeContainedOutputFile } from "../run/contained-output.js";
|
|
9
9
|
import { FakeInbox } from "./fake-inbox.js";
|
|
10
10
|
import { collectExternalCommsThread } from "./sandbox-catch.js";
|
|
11
|
+
import { plural } from "../run/text.js";
|
|
11
12
|
/**
|
|
12
13
|
* The shortest catch bearer token humanish uses. The token guards GET /deliveries on a host the run
|
|
13
14
|
* reaches over the network, so it must not be guessable: 16 random base64 characters are 96 bits.
|
|
@@ -33,7 +34,7 @@ export function catchTokenRefusal(token) {
|
|
|
33
34
|
return undefined;
|
|
34
35
|
return `The comms catch token is ${token.length} characters; it must be at least ${MIN_CATCH_TOKEN_LENGTH}, such as the output of \`openssl rand -hex 16\`, on the catch and in the run.`;
|
|
35
36
|
}
|
|
36
|
-
/** The catch token the run sends: the value of `authTokenEnv`, when the
|
|
37
|
+
/** The catch token the run sends: the value of `authTokenEnv`, when the study names one. */
|
|
37
38
|
export function catchTokenOf(external, env) {
|
|
38
39
|
return external.authTokenEnv === undefined ? undefined : env[external.authTokenEnv];
|
|
39
40
|
}
|
|
@@ -73,7 +74,7 @@ export async function collectExternalCommsEvidence(args) {
|
|
|
73
74
|
if (collected.captured > 0) {
|
|
74
75
|
return {
|
|
75
76
|
warnings: scrubbed([
|
|
76
|
-
`The email catch captured ${collected.captured
|
|
77
|
+
`The email catch captured ${plural(collected.captured, "email send")}, but none matched a declared recipient inbox, so no email evidence was written. Set comms.email.recipients[].address to the address the app sends to.`,
|
|
77
78
|
]),
|
|
78
79
|
};
|
|
79
80
|
}
|
|
@@ -21,11 +21,11 @@ export declare class FakeInbox implements CommsChannel {
|
|
|
21
21
|
constructor(options?: FakeInboxOptions);
|
|
22
22
|
provision(participantId: string): Promise<CommsAddress>;
|
|
23
23
|
/**
|
|
24
|
-
* Provision an inbox for `participantId` at an explicit address (a
|
|
24
|
+
* Provision an inbox for `participantId` at an explicit address (a study-declared recipient), so
|
|
25
25
|
* the app-under-test's send to that literal address resolves in `deliverRaw` (which drops
|
|
26
26
|
* recipients with no provisioned inbox). Declaring the same address intentionally shares its
|
|
27
27
|
* inbox; if `participantId` already held a different auto-generated address, the declared
|
|
28
|
-
* address supersedes it (the
|
|
28
|
+
* address supersedes it (the study's declaration wins). Idempotent: re-declaring the same address
|
|
29
29
|
* returns the existing inbox without clearing it.
|
|
30
30
|
*/
|
|
31
31
|
provisionAddress(participantId: string, value: string): Promise<CommsAddress>;
|
package/dist/comms/fake-inbox.js
CHANGED
|
@@ -60,11 +60,11 @@ export class FakeInbox {
|
|
|
60
60
|
return address;
|
|
61
61
|
}
|
|
62
62
|
/**
|
|
63
|
-
* Provision an inbox for `participantId` at an explicit address (a
|
|
63
|
+
* Provision an inbox for `participantId` at an explicit address (a study-declared recipient), so
|
|
64
64
|
* the app-under-test's send to that literal address resolves in `deliverRaw` (which drops
|
|
65
65
|
* recipients with no provisioned inbox). Declaring the same address intentionally shares its
|
|
66
66
|
* inbox; if `participantId` already held a different auto-generated address, the declared
|
|
67
|
-
* address supersedes it (the
|
|
67
|
+
* address supersedes it (the study's declaration wins). Idempotent: re-declaring the same address
|
|
68
68
|
* returns the existing inbox without clearing it.
|
|
69
69
|
*/
|
|
70
70
|
async provisionAddress(participantId, value) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { StudyConfig } from "../study/types.js";
|
|
2
2
|
import { type CommsConnection } from "./connections.js";
|
|
3
3
|
import { type KeyResolutionDeps } from "../keys/key-resolution.js";
|
|
4
4
|
import type { ReceivingAdapter } from "./receiving-types.js";
|
|
@@ -14,9 +14,9 @@ export declare function resolveReceivingConnection(cwd: string, name: string, en
|
|
|
14
14
|
apiKey: string;
|
|
15
15
|
adapter: ReceivingAdapter;
|
|
16
16
|
}>;
|
|
17
|
-
/** What receiving reads from a
|
|
17
|
+
/** What receiving reads from a study: its email declaration and the subject env it guards. */
|
|
18
18
|
export interface ReceivingSource {
|
|
19
|
-
readonly comms?:
|
|
19
|
+
readonly comms?: StudyConfig["comms"];
|
|
20
20
|
readonly subject: {
|
|
21
21
|
readonly env?: readonly string[];
|
|
22
22
|
readonly envValues?: Readonly<Record<string, string>>;
|
|
@@ -32,7 +32,7 @@ export declare function prepareReceivingRun(args: {
|
|
|
32
32
|
registerSecrets(values: string[]): void;
|
|
33
33
|
}): Promise<import("./receiving.js").CommsReceivingRun | undefined>;
|
|
34
34
|
/** The restriction survives restarts and screenshot redaction; it is not a claim of local processing. */
|
|
35
|
-
export declare function receivingPublication(config: Pick<
|
|
35
|
+
export declare function receivingPublication(config: Pick<StudyConfig, "comms">, dryRun: boolean): {
|
|
36
36
|
publication: {
|
|
37
37
|
restrictions: ["real-communications"];
|
|
38
38
|
};
|
|
@@ -78,7 +78,7 @@ export declare function drainCommsCatch(shell: Shell, deployed: Pick<DeployedCom
|
|
|
78
78
|
export declare function parseDeliveriesNdjson(text: string): RawCapturedSend[];
|
|
79
79
|
/**
|
|
80
80
|
* The distinct `to` addresses the captured mail was actually sent to, parsed with the same profiles
|
|
81
|
-
* that route it. A
|
|
81
|
+
* that route it. A run knows its recipients from the declared roster; a standalone catch does not,
|
|
82
82
|
* so it discovers them from the mail itself. Otherwise an operator who forgot to name an address gets
|
|
83
83
|
* a technically-healthy catch rendering an empty inbox forever: a false green.
|
|
84
84
|
*/
|
|
@@ -139,7 +139,7 @@ export declare function externalInboxUrl(external: ExternalCommsCatch): string;
|
|
|
139
139
|
/**
|
|
140
140
|
* Probe an adopter-hosted catch the way the in-sandbox one is probed: assert humanish's service marker in
|
|
141
141
|
* /health, not merely any 2xx: an adopter's reverse proxy or a captive portal will happily return
|
|
142
|
-
* 200 for anything, and a comms
|
|
142
|
+
* 200 for anything, and a comms study whose catch is not actually there collects nothing while
|
|
143
143
|
* looking fine. Fail-closed callers treat `false` as a hard stop before spending on a run.
|
|
144
144
|
*/
|
|
145
145
|
export declare function externalCatchHealthy(external: ExternalCommsCatch, options?: {
|
|
@@ -171,7 +171,7 @@ export function parseDeliveriesNdjson(text) {
|
|
|
171
171
|
}
|
|
172
172
|
/**
|
|
173
173
|
* The distinct `to` addresses the captured mail was actually sent to, parsed with the same profiles
|
|
174
|
-
* that route it. A
|
|
174
|
+
* that route it. A run knows its recipients from the declared roster; a standalone catch does not,
|
|
175
175
|
* so it discovers them from the mail itself. Otherwise an operator who forgot to name an address gets
|
|
176
176
|
* a technically-healthy catch rendering an empty inbox forever: a false green.
|
|
177
177
|
*/
|
|
@@ -298,7 +298,7 @@ export function externalInboxUrl(external) {
|
|
|
298
298
|
/**
|
|
299
299
|
* Probe an adopter-hosted catch the way the in-sandbox one is probed: assert humanish's service marker in
|
|
300
300
|
* /health, not merely any 2xx: an adopter's reverse proxy or a captive portal will happily return
|
|
301
|
-
* 200 for anything, and a comms
|
|
301
|
+
* 200 for anything, and a comms study whose catch is not actually there collects nothing while
|
|
302
302
|
* looking fine. Fail-closed callers treat `false` as a hard stop before spending on a run.
|
|
303
303
|
*/
|
|
304
304
|
export async function externalCatchHealthy(external, options = {}) {
|
package/dist/comms/setup.d.ts
CHANGED
|
@@ -55,9 +55,9 @@ export interface CommsConfigureResult {
|
|
|
55
55
|
connection?: string;
|
|
56
56
|
}
|
|
57
57
|
/** Save a local copy, never rewrite a committed manifest or silently shadow it by handle. */
|
|
58
|
-
export declare function
|
|
58
|
+
export declare function configureCommsStudy(args: {
|
|
59
59
|
cwd: string;
|
|
60
|
-
|
|
60
|
+
study: string;
|
|
61
61
|
connection: string;
|
|
62
62
|
apply?: boolean;
|
|
63
63
|
planToken?: string;
|