humanish 0.107.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 +73 -69
- package/CHANGELOG.md +27 -0
- package/CONTEXT.md +51 -44
- package/README.md +148 -175
- package/SECURITY.md +16 -26
- package/TELEMETRY.md +8 -6
- package/dist/actors/affordance.d.ts +4 -4
- package/dist/actors/affordance.js +12 -12
- package/dist/actors/agent-session.d.ts +2 -2
- package/dist/actors/agent-session.js +7 -7
- package/dist/actors/codex/app-server-actor-trace.d.ts +1 -1
- package/dist/actors/codex/app-server-actor-trace.js +1 -1
- package/dist/actors/codex/app-server-trace.js +2 -1
- package/dist/actors/codex/app-server-ui.js +1 -1
- package/dist/actors/codex/codex-admission.d.ts +91 -0
- package/dist/actors/codex/codex-admission.js +150 -0
- package/dist/actors/codex/restricted-executable.d.ts +4 -4
- package/dist/actors/codex/restricted-executable.js +8 -8
- package/dist/actors/codex/restricted-launch.d.ts +2 -1
- package/dist/actors/codex/restricted-launch.js +1 -1
- package/dist/actors/codex/restricted-participant.js +20 -18
- package/dist/actors/codex/restricted-policy.d.ts +2 -2
- package/dist/actors/codex/restricted-policy.js +2 -2
- package/dist/actors/codex/restricted-session.d.ts +3 -3
- package/dist/actors/codex/restricted-session.js +10 -5
- package/dist/actors/computer-use/actor.d.ts +18 -18
- package/dist/actors/computer-use/actor.js +4 -4
- package/dist/actors/computer-use/admission-limit.d.ts +3 -3
- package/dist/actors/computer-use/admission-limit.js +4 -4
- 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.d.ts +3 -3
- package/dist/actors/computer-use/loop/actions.js +15 -15
- package/dist/actors/computer-use/loop/backstop.d.ts +3 -3
- package/dist/actors/computer-use/loop/backstop.js +14 -12
- package/dist/actors/computer-use/loop/debrief.js +2 -2
- package/dist/actors/computer-use/loop/ending.d.ts +6 -6
- package/dist/actors/computer-use/loop/ending.js +18 -17
- package/dist/actors/computer-use/loop/observation.d.ts +2 -2
- package/dist/actors/computer-use/loop/observation.js +15 -14
- package/dist/actors/computer-use/loop/provider-call.d.ts +1 -1
- package/dist/actors/computer-use/loop/provider-call.js +12 -12
- package/dist/actors/computer-use/loop/session.d.ts +4 -4
- package/dist/actors/computer-use/loop/session.js +4 -4
- package/dist/actors/computer-use/loop/spend.d.ts +1 -1
- package/dist/actors/computer-use/loop/spend.js +1 -1
- package/dist/actors/computer-use/loop/trace.js +11 -9
- package/dist/actors/computer-use/loop/types.d.ts +47 -45
- package/dist/actors/computer-use/loop/usage.d.ts +2 -2
- package/dist/actors/computer-use/loop/usage.js +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-context.d.ts +37 -0
- package/dist/actors/computer-use/openai-context.js +214 -0
- package/dist/actors/computer-use/openai-provider.d.ts +13 -10
- package/dist/actors/computer-use/openai-provider.js +52 -41
- package/dist/actors/computer-use/openai-requests.d.ts +36 -10
- package/dist/actors/computer-use/openai-requests.js +82 -15
- package/dist/actors/computer-use/openai-wire.d.ts +19 -7
- package/dist/actors/computer-use/openai-wire.js +36 -34
- 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 +82 -47
- package/dist/actors/contract.js +30 -24
- package/dist/actors/local-agent/claude-session.d.ts +1 -1
- package/dist/actors/local-agent/claude-session.js +13 -12
- package/dist/actors/local-agent/cli.d.ts +9 -7
- package/dist/actors/local-agent/cli.js +24 -28
- package/dist/actors/local-agent/readiness.d.ts +2 -2
- package/dist/actors/local-agent/readiness.js +4 -4
- package/dist/actors/reasoning-effort.js +8 -8
- package/dist/actors/registry.d.ts +12 -12
- package/dist/actors/registry.js +21 -20
- package/dist/actors/scripted-browser/actor.d.ts +10 -10
- package/dist/actors/scripted-browser/actor.js +17 -17
- package/dist/actors/scripted-browser/browser-command.js +1 -1
- package/dist/actors/scripted-browser/steps.js +1 -1
- package/dist/actors/scripted-browser/types.d.ts +1 -1
- package/dist/actors/stop-conditions.d.ts +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/codex-config.d.ts +6 -2
- package/dist/analysis/codex-config.js +22 -14
- package/dist/analysis/execute.d.ts +1 -1
- package/dist/analysis/execute.js +1 -1
- package/dist/analysis/service.js +5 -5
- 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/analyze.js +19 -16
- package/dist/cli/commands/codex.js +9 -9
- package/dist/cli/commands/comms.js +48 -35
- package/dist/cli/commands/feedback.js +20 -21
- package/dist/cli/commands/migrate.d.ts +4 -0
- package/dist/cli/commands/migrate.js +65 -0
- package/dist/cli/commands/observe.d.ts +0 -1
- package/dist/cli/commands/observe.js +136 -112
- package/dist/cli/commands/run-command.d.ts +10 -0
- package/dist/cli/commands/run-command.js +85 -0
- package/dist/cli/commands/runs.js +136 -139
- package/dist/cli/commands/setup.d.ts +2 -2
- package/dist/cli/commands/setup.js +27 -24
- package/dist/cli/commands/study-format.d.ts +9 -0
- package/dist/cli/commands/{lab-format.js → study-format.js} +39 -27
- 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} +17 -18
- 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} +7 -6
- 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} +10 -10
- 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} +44 -45
- package/dist/cli/commands/{lab-scorer.d.ts → study-scorer.d.ts} +7 -7
- package/dist/cli/commands/{lab-scorer.js → study-scorer.js} +2 -2
- package/dist/cli/commands/study.d.ts +3 -0
- package/dist/cli/commands/study.js +146 -0
- package/dist/cli/commands/tui.d.ts +4 -4
- package/dist/cli/commands/tui.js +31 -31
- package/dist/cli/commands/watch.js +71 -121
- package/dist/cli/deprecations.d.ts +6 -0
- package/dist/cli/deprecations.js +18 -0
- package/dist/cli/doctor.d.ts +18 -8
- package/dist/cli/doctor.js +114 -59
- package/dist/cli/first-run-path.d.ts +15 -13
- package/dist/cli/first-run-path.js +35 -33
- package/dist/cli/io.d.ts +44 -9
- package/dist/cli/io.js +98 -23
- package/dist/cli/observer-follow.d.ts +3 -3
- package/dist/cli/observer-follow.js +6 -7
- package/dist/cli/orientation.d.ts +10 -7
- package/dist/cli/orientation.js +89 -47
- package/dist/cli/product-sentence.d.ts +6 -0
- package/dist/cli/product-sentence.js +6 -0
- package/dist/cli/program.d.ts +6 -1
- package/dist/cli/program.js +111 -43
- package/dist/cli/telemetry.d.ts +16 -16
- package/dist/cli/telemetry.js +46 -44
- package/dist/cli.js +1 -1
- package/dist/comms/capture-surface.d.ts +13 -12
- package/dist/comms/capture-surface.js +23 -22
- package/dist/comms/catch-host.d.ts +7 -7
- package/dist/comms/catch-host.js +17 -17
- package/dist/comms/connections.d.ts +1 -1
- package/dist/comms/connections.js +2 -2
- package/dist/comms/email-catch.d.ts +3 -3
- package/dist/comms/email-catch.js +8 -8
- package/dist/comms/external-evidence.d.ts +5 -5
- package/dist/comms/external-evidence.js +5 -4
- package/dist/comms/extract.js +2 -2
- package/dist/comms/fake-inbox.d.ts +3 -3
- package/dist/comms/fake-inbox.js +3 -3
- package/dist/comms/receiving-render.d.ts +1 -1
- package/dist/comms/receiving-render.js +2 -2
- package/dist/comms/receiving-runtime.d.ts +4 -4
- package/dist/comms/sandbox-catch-script.d.ts +6 -6
- package/dist/comms/sandbox-catch-script.js +6 -6
- package/dist/comms/sandbox-catch.d.ts +38 -39
- package/dist/comms/sandbox-catch.js +36 -37
- package/dist/comms/setup.d.ts +2 -2
- package/dist/comms/setup.js +56 -25
- package/dist/comms/thread-evidence.d.ts +1 -1
- package/dist/comms/thread-evidence.js +6 -6
- package/dist/comms/types.d.ts +6 -6
- package/dist/comms/types.js +3 -3
- package/dist/evidence/frame-signature.d.ts +1 -1
- package/dist/evidence/frame-signature.js +4 -4
- package/dist/evidence/redaction.d.ts +3 -3
- package/dist/evidence/redaction.js +4 -4
- package/dist/feedback/draft.js +38 -80
- package/dist/feedback/export-bundle.js +1 -1
- package/dist/feedback/export.d.ts +5 -1
- package/dist/feedback/export.js +10 -10
- package/dist/feedback/feedback.d.ts +2 -2
- package/dist/feedback/feedback.js +21 -3
- 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 +19 -19
- 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.d.ts +1 -1
- 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 +6 -6
- package/dist/index.d.ts +14 -14
- package/dist/index.js +8 -8
- package/dist/keys/key-resolution.d.ts +5 -5
- package/dist/keys/key-resolution.js +23 -23
- package/dist/observer/artifact.d.ts +2 -2
- package/dist/observer/artifact.js +7 -7
- package/dist/observer/data.d.ts +6 -6
- package/dist/observer/data.js +5 -4
- package/dist/observer/exposure.d.ts +1 -1
- package/dist/observer/exposure.js +11 -11
- package/dist/observer/http.js +1 -1
- package/dist/observer/library.d.ts +3 -1
- package/dist/observer/library.js +8 -3
- package/dist/observer/listen.js +5 -4
- package/dist/observer/render.d.ts +1 -1
- package/dist/observer/render.js +17 -6
- package/dist/observer/run-routes.d.ts +4 -3
- package/dist/observer/run-routes.js +38 -13
- package/dist/observer/serve.d.ts +1 -1
- package/dist/observer/serve.js +7 -3
- package/dist/observer/tunnel.js +1 -1
- package/dist/observer-app.html +4 -4
- package/dist/routes/computer-use/bundle-parts.d.ts +9 -9
- package/dist/routes/computer-use/bundle-parts.js +18 -17
- package/dist/routes/computer-use/bundle.d.ts +2 -2
- package/dist/routes/computer-use/bundle.js +10 -9
- package/dist/routes/computer-use/e2b-desktop/comms.d.ts +6 -6
- package/dist/routes/computer-use/e2b-desktop/comms.js +18 -17
- package/dist/routes/computer-use/e2b-desktop/desktop.js +4 -4
- package/dist/routes/computer-use/e2b-desktop/fidelity.d.ts +5 -4
- package/dist/routes/computer-use/e2b-desktop/fidelity.js +11 -10
- package/dist/routes/computer-use/e2b-desktop/prepare.d.ts +1 -1
- package/dist/routes/computer-use/e2b-desktop/prepare.js +10 -10
- package/dist/routes/computer-use/e2b-desktop/start.js +7 -7
- package/dist/routes/computer-use/e2b-desktop/state.d.ts +2 -2
- package/dist/routes/computer-use/e2b-desktop/teardown.js +2 -2
- package/dist/routes/computer-use/external-comms.d.ts +4 -4
- package/dist/routes/computer-use/external-comms.js +1 -1
- package/dist/routes/computer-use/fanout-bundle.js +27 -26
- package/dist/routes/computer-use/fanout-records.js +12 -13
- package/dist/routes/computer-use/live-flush.d.ts +4 -4
- package/dist/routes/computer-use/live-flush.js +6 -6
- package/dist/routes/computer-use/live-phase.d.ts +5 -4
- package/dist/routes/computer-use/live-phase.js +8 -8
- 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 +3 -3
- package/dist/routes/computer-use/participant-desktop.d.ts +7 -7
- package/dist/routes/computer-use/participant-desktop.js +5 -5
- package/dist/routes/computer-use/participant-execution.d.ts +4 -4
- package/dist/routes/computer-use/participant-execution.js +10 -10
- package/dist/routes/computer-use/participant-model.d.ts +6 -0
- package/dist/routes/computer-use/participant-model.js +33 -15
- package/dist/routes/computer-use/participant-prompt.d.ts +15 -15
- package/dist/routes/computer-use/participant-prompt.js +9 -9
- package/dist/routes/computer-use/participant-runs.d.ts +16 -16
- package/dist/routes/computer-use/participant-runs.js +26 -25
- package/dist/routes/computer-use/plan.d.ts +12 -12
- package/dist/routes/computer-use/plan.js +42 -42
- package/dist/routes/computer-use/preflight.d.ts +5 -5
- package/dist/routes/computer-use/preflight.js +25 -25
- package/dist/routes/computer-use/rerun-selection.d.ts +1 -1
- package/dist/routes/computer-use/rerun-selection.js +4 -3
- package/dist/routes/computer-use/result.d.ts +4 -4
- package/dist/routes/computer-use/result.js +22 -21
- package/dist/routes/computer-use/route.d.ts +12 -11
- package/dist/routes/computer-use/route.js +31 -30
- package/dist/routes/computer-use/self-report.d.ts +7 -7
- package/dist/routes/computer-use/self-report.js +32 -32
- package/dist/routes/computer-use/setup.d.ts +23 -23
- package/dist/routes/computer-use/setup.js +28 -29
- package/dist/routes/computer-use/single-bundle.d.ts +11 -11
- package/dist/routes/computer-use/single-bundle.js +40 -41
- package/dist/routes/computer-use/subject-projection.d.ts +4 -4
- package/dist/routes/computer-use/subject-projection.js +6 -6
- package/dist/routes/computer-use/types.d.ts +71 -73
- package/dist/routes/computer-use/types.js +12 -12
- package/dist/routes/preview.d.ts +13 -7
- package/dist/routes/preview.js +11 -7
- package/dist/routes/scripted/bundle.d.ts +7 -7
- package/dist/routes/scripted/bundle.js +20 -18
- package/dist/routes/scripted/plan.d.ts +8 -8
- package/dist/routes/scripted/plan.js +13 -13
- package/dist/routes/scripted/result.d.ts +3 -3
- package/dist/routes/scripted/result.js +13 -13
- package/dist/routes/scripted/route.d.ts +9 -9
- package/dist/routes/scripted/route.js +15 -16
- package/dist/routes/scripted/scenario.d.ts +1 -1
- package/dist/routes/scripted/scenario.js +5 -5
- package/dist/routes/scripted/setup.d.ts +6 -6
- package/dist/routes/scripted/setup.js +8 -8
- package/dist/routes/scripted/subject.d.ts +5 -5
- package/dist/routes/scripted/subject.js +4 -4
- package/dist/routes/scripted/surface-records.d.ts +1 -1
- package/dist/routes/scripted/surface-records.js +4 -4
- package/dist/routes/scripted/surface-sessions.d.ts +3 -3
- package/dist/routes/scripted/types.d.ts +18 -20
- package/dist/routes/scripted/types.js +2 -2
- package/dist/routes/shared-world/bundle-records.js +11 -10
- package/dist/routes/shared-world/bundle.d.ts +5 -5
- package/dist/routes/shared-world/bundle.js +46 -43
- package/dist/routes/shared-world/checkpoints.d.ts +4 -4
- package/dist/routes/shared-world/checkpoints.js +2 -2
- package/dist/routes/shared-world/comms.d.ts +14 -14
- package/dist/routes/shared-world/comms.js +19 -18
- package/dist/routes/shared-world/external-public.d.ts +4 -3
- package/dist/routes/shared-world/external-public.js +16 -12
- package/dist/routes/shared-world/handoff.d.ts +7 -6
- package/dist/routes/shared-world/handoff.js +65 -57
- package/dist/routes/shared-world/lobby-code.d.ts +2 -2
- package/dist/routes/shared-world/lobby-code.js +9 -9
- package/dist/routes/shared-world/participant-specs.d.ts +10 -9
- package/dist/routes/shared-world/participant-specs.js +38 -31
- package/dist/routes/shared-world/plan.d.ts +9 -9
- package/dist/routes/shared-world/plan.js +16 -16
- package/dist/routes/shared-world/provenance.d.ts +2 -2
- package/dist/routes/shared-world/provenance.js +2 -2
- package/dist/routes/shared-world/provisioned.d.ts +8 -8
- package/dist/routes/shared-world/provisioned.js +18 -17
- package/dist/routes/shared-world/result.d.ts +6 -6
- package/dist/routes/shared-world/result.js +29 -29
- package/dist/routes/shared-world/route.d.ts +11 -11
- package/dist/routes/shared-world/route.js +40 -39
- package/dist/routes/shared-world/setup.d.ts +16 -16
- package/dist/routes/shared-world/setup.js +23 -23
- package/dist/routes/shared-world/types.d.ts +55 -53
- package/dist/routes/shared-world/types.js +4 -4
- package/dist/routes/terminal/adapter.d.ts +5 -5
- package/dist/routes/terminal/adapter.js +9 -9
- package/dist/routes/terminal/bundle.d.ts +13 -13
- package/dist/routes/terminal/bundle.js +28 -27
- package/dist/routes/terminal/credentials.d.ts +8 -8
- package/dist/routes/terminal/credentials.js +12 -12
- package/dist/routes/terminal/dry-run.d.ts +4 -4
- package/dist/routes/terminal/dry-run.js +12 -12
- package/dist/routes/terminal/encoding.js +2 -2
- package/dist/routes/terminal/ledger.d.ts +5 -5
- package/dist/routes/terminal/ledger.js +14 -14
- 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 +10 -10
- package/dist/routes/terminal/live-sandbox.d.ts +2 -2
- package/dist/routes/terminal/live-sandbox.js +15 -15
- package/dist/routes/terminal/participant-text.js +2 -1
- package/dist/routes/terminal/persona.d.ts +2 -2
- package/dist/routes/terminal/persona.js +3 -3
- package/dist/routes/terminal/plan.d.ts +7 -7
- package/dist/routes/terminal/plan.js +15 -15
- package/dist/routes/terminal/recorder.js +2 -2
- package/dist/routes/terminal/result.d.ts +5 -5
- package/dist/routes/terminal/result.js +14 -14
- package/dist/routes/terminal/route.d.ts +9 -9
- package/dist/routes/terminal/route.js +19 -20
- package/dist/routes/terminal/sandbox.d.ts +1 -1
- package/dist/routes/terminal/sandbox.js +1 -1
- package/dist/routes/terminal/session.d.ts +5 -5
- package/dist/routes/terminal/session.js +14 -13
- package/dist/routes/terminal/token-usage.d.ts +1 -1
- package/dist/routes/terminal/token-usage.js +7 -8
- package/dist/routes/terminal/trace.d.ts +4 -4
- package/dist/routes/terminal/trace.js +2 -2
- package/dist/routes/terminal/types.d.ts +48 -50
- package/dist/routes/terminal/types.js +5 -5
- package/dist/run/bundle-shape.js +3 -3
- package/dist/run/bundle.d.ts +49 -49
- package/dist/run/bundle.js +3 -2
- package/dist/run/cost-summary.js +3 -3
- package/dist/run/costs.d.ts +23 -0
- package/dist/run/costs.js +79 -44
- package/dist/run/detail.d.ts +6 -6
- package/dist/run/detail.js +4 -4
- package/dist/run/dry-run-inputs.d.ts +1 -1
- package/dist/run/dry-run-inputs.js +2 -2
- package/dist/run/dry-run.js +20 -20
- package/dist/run/judge.d.ts +19 -13
- package/dist/run/judge.js +18 -8
- package/dist/run/outcomes.d.ts +1 -1
- package/dist/run/participant.d.ts +1 -1
- package/dist/run/paths.d.ts +1 -1
- package/dist/run/paths.js +1 -1
- package/dist/run/preflight-receipts.js +1 -1
- package/dist/run/pricing.d.ts +11 -6
- package/dist/run/pricing.js +22 -15
- package/dist/run/projection.d.ts +46 -46
- package/dist/run/projection.js +57 -57
- package/dist/run/reclaim.d.ts +1 -1
- package/dist/run/reclaim.js +3 -3
- package/dist/run/results.d.ts +5 -5
- 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 +19 -7
- package/dist/run/run-index.js +77 -64
- package/dist/run/run-not-found.d.ts +5 -0
- package/dist/run/run-not-found.js +15 -0
- package/dist/run/run.d.ts +6 -5
- package/dist/run/run.js +3 -3
- package/dist/run/sandbox-receipts.d.ts +2 -2
- package/dist/run/sandbox-receipts.js +3 -3
- package/dist/run/shared-world-evidence.d.ts +37 -36
- package/dist/run/shared-world-evidence.js +4 -4
- package/dist/run/shared-world-shape.d.ts +1 -1
- package/dist/run/shared-world-shape.js +7 -7
- package/dist/run/stats.d.ts +14 -8
- package/dist/run/stats.js +121 -63
- package/dist/run/status.d.ts +16 -29
- package/dist/run/status.js +10 -29
- package/dist/run/stored-runs.js +2 -1
- package/dist/run/stream-shape.js +1 -1
- package/dist/run/streams.d.ts +7 -7
- package/dist/run/study-provenance.d.ts +49 -0
- package/dist/run/study-provenance.js +66 -0
- package/dist/run/study-result.d.ts +11 -0
- package/dist/run/study-result.js +9 -0
- package/dist/run/text.d.ts +2 -0
- package/dist/run/text.js +4 -0
- package/dist/run-study.d.ts +112 -0
- package/dist/{run-lab.js → run-study.js} +52 -47
- package/dist/{lab → study}/adapter-extension.d.ts +15 -27
- package/dist/{lab → study}/adapter-extension.js +10 -45
- package/dist/{lab → study}/adapter-scorer-loader.d.ts +17 -17
- package/dist/{lab → study}/adapter-scorer-loader.js +34 -34
- package/dist/study/composition-rules.d.ts +7 -0
- package/dist/{lab → study}/composition-rules.js +53 -53
- package/dist/study/config.d.ts +15 -0
- package/dist/{lab → study}/config.js +98 -41
- package/dist/study/convert.d.ts +33 -0
- package/dist/study/convert.js +432 -0
- package/dist/{lab → study}/device-presets.d.ts +10 -10
- package/dist/{lab → study}/device-presets.js +11 -11
- package/dist/study/discover.d.ts +75 -0
- package/dist/{lab → study}/discover.js +134 -95
- package/dist/{lab → study}/doctor.d.ts +19 -12
- package/dist/{lab → study}/doctor.js +58 -20
- package/dist/study/field-paths.d.ts +12 -0
- package/dist/study/field-paths.js +126 -0
- package/dist/study/files.d.ts +26 -0
- package/dist/study/files.js +44 -0
- package/dist/{lab → study}/init-templates.d.ts +2 -2
- package/dist/study/init-templates.js +421 -0
- package/dist/{lab → study}/init.d.ts +2 -2
- package/dist/{lab → study}/init.js +46 -11
- package/dist/study/keys.d.ts +4 -0
- package/dist/{lab → study}/keys.js +46 -12
- package/dist/study/migrate.d.ts +48 -0
- package/dist/study/migrate.js +408 -0
- package/dist/study/owned-files.d.ts +38 -0
- package/dist/study/owned-files.js +182 -0
- package/dist/{lab → study}/parse/actors.d.ts +5 -5
- package/dist/{lab → study}/parse/actors.js +14 -14
- package/dist/study/parse/comms.d.ts +12 -0
- package/dist/{lab → study}/parse/comms.js +5 -5
- package/dist/study/parse/execution.d.ts +19 -0
- package/dist/{lab → study}/parse/execution.js +13 -13
- package/dist/study/parse/study-v3.d.ts +21 -0
- package/dist/study/parse/study-v3.js +259 -0
- package/dist/study/parse/subject-state.d.ts +30 -0
- package/dist/{lab → study}/parse/subject-state.js +19 -19
- package/dist/{lab → study}/parse/subject.d.ts +3 -3
- package/dist/{lab → study}/parse/subject.js +34 -34
- package/dist/{lab → study}/parse/values.d.ts +3 -3
- package/dist/{lab → study}/parse/values.js +3 -3
- package/dist/{lab → study}/persona-resolve.d.ts +8 -8
- package/dist/{lab → study}/persona-resolve.js +6 -6
- 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 +12 -12
- package/dist/{lab → study}/plan-participants.js +4 -4
- package/dist/{lab → study}/plan-types.d.ts +31 -31
- package/dist/{lab → study}/plan-types.js +2 -2
- package/dist/study/plan.d.ts +13 -0
- package/dist/study/plan.js +101 -0
- package/dist/study/preflight-probes.d.ts +3 -0
- package/dist/{lab → study}/preflight-probes.js +20 -19
- package/dist/study/preflight-result.d.ts +8 -0
- package/dist/{lab → study}/preflight-result.js +5 -4
- package/dist/study/preflight.d.ts +94 -0
- package/dist/{lab → study}/preflight.js +12 -12
- 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 +39 -33
- package/dist/{lab → study}/routing.js +60 -29
- package/dist/{lab/run-lab-events.d.ts → study/run-study-events.d.ts} +10 -13
- package/dist/{lab/run-lab-events.js → study/run-study-events.js} +3 -9
- package/dist/{lab/run-lab-homes.d.ts → study/run-study-homes.d.ts} +21 -18
- package/dist/{lab/run-lab-homes.js → study/run-study-homes.js} +1 -1
- package/dist/study/run-study-options.d.ts +28 -0
- package/dist/{lab/run-lab-options.js → study/run-study-options.js} +29 -25
- package/dist/{lab/lab-deps.d.ts → study/study-deps.d.ts} +8 -13
- package/dist/{lab/lab-deps.js → study/study-deps.js} +2 -2
- package/dist/{lab → study}/summary.d.ts +16 -15
- package/dist/{lab → study}/summary.js +21 -21
- package/dist/{lab → study}/tasks.d.ts +18 -18
- package/dist/{lab → study}/tasks.js +14 -14
- package/dist/{lab → study}/types.d.ts +202 -196
- package/dist/{lab → study}/types.js +3 -1
- package/dist/{lab → study}/validation.d.ts +27 -27
- package/dist/{lab → study}/validation.js +53 -51
- package/dist/study/warnings.d.ts +12 -0
- package/dist/{lab → study}/warnings.js +62 -34
- package/dist/subject/clone.d.ts +7 -7
- package/dist/subject/clone.js +2 -2
- package/dist/subject/desktop-cli.d.ts +1 -1
- package/dist/subject/desktop-cli.js +2 -2
- package/dist/subject/local-tree-archive.d.ts +2 -2
- package/dist/subject/local-tree-archive.js +4 -4
- package/dist/subject/local-tree.d.ts +4 -4
- package/dist/subject/node-bootstrap.js +1 -1
- package/dist/subject/runtime.js +9 -10
- package/dist/subject/serve.d.ts +5 -5
- package/dist/subject/serve.js +3 -3
- package/dist/subject/state.d.ts +4 -4
- package/dist/subject/state.js +1 -1
- package/dist/subject/steps.d.ts +6 -6
- package/dist/subject/steps.js +5 -5
- package/dist/substrates/command-failure.d.ts +3 -3
- package/dist/substrates/command-failure.js +3 -3
- package/dist/substrates/desktop-session.js +2 -2
- package/dist/substrates/detached.d.ts +6 -6
- package/dist/substrates/detached.js +7 -7
- package/dist/substrates/e2b/cdp-probe.d.ts +9 -9
- package/dist/substrates/e2b/cdp-probe.js +14 -17
- package/dist/substrates/e2b/desktop-browser.d.ts +6 -6
- package/dist/substrates/e2b/desktop-browser.js +9 -9
- package/dist/substrates/e2b/desktop-cdp.d.ts +10 -10
- package/dist/substrates/e2b/desktop-cdp.js +9 -9
- package/dist/substrates/e2b/desktop-executor.d.ts +2 -2
- package/dist/substrates/e2b/desktop-executor.js +13 -13
- package/dist/substrates/e2b/desktop-geometry.d.ts +4 -4
- package/dist/substrates/e2b/desktop-geometry.js +8 -8
- package/dist/substrates/e2b/desktop-media.d.ts +4 -4
- package/dist/substrates/e2b/desktop-media.js +1 -1
- package/dist/substrates/e2b/desktop-screenshot-cleanup.d.ts +3 -3
- package/dist/substrates/e2b/desktop-screenshot-cleanup.js +3 -3
- package/dist/substrates/e2b/lifetime.js +1 -1
- package/dist/substrates/e2b/sandbox.d.ts +4 -4
- package/dist/substrates/e2b/sandbox.js +2 -2
- package/dist/substrates/e2b/sdk.d.ts +12 -12
- package/dist/substrates/e2b/sdk.js +7 -7
- package/dist/substrates/local/runtime-config.d.ts +4 -4
- package/dist/substrates/local/runtime-config.js +4 -4
- package/dist/tui/actions.d.ts +1 -1
- package/dist/tui/actions.js +13 -13
- package/dist/tui/contract.d.ts +23 -23
- package/dist/tui/contract.js +11 -11
- package/dist/tui/launch.d.ts +7 -7
- package/dist/tui/launch.js +36 -31
- package/dist/tui/project.js +5 -5
- package/dist/tui-app.js +139 -139
- package/dist/verify/actor.d.ts +8 -8
- package/dist/verify/actor.js +36 -36
- package/dist/verify/artifacts.d.ts +2 -2
- package/dist/verify/artifacts.js +3 -3
- package/dist/verify/context-growth.d.ts +9 -0
- package/dist/verify/context-growth.js +62 -0
- package/dist/verify/costs.d.ts +6 -6
- package/dist/verify/costs.js +8 -8
- package/dist/verify/shared-world-concurrent.d.ts +2 -2
- package/dist/verify/shared-world-concurrent.js +79 -76
- package/dist/verify/shared-world.d.ts +2 -2
- package/dist/verify/shared-world.js +16 -16
- package/dist/verify/subject.d.ts +5 -5
- package/dist/verify/subject.js +19 -19
- package/dist/verify/verify.js +94 -44
- package/docs/README.md +25 -32
- package/docs/architecture/actor-contract.md +60 -91
- package/docs/architecture/browser-control.md +1 -1
- package/docs/architecture/desktop-sessions.md +7 -7
- package/docs/architecture/external-public-shared-world.md +68 -65
- package/docs/architecture/github-feedback-loop.md +2 -5
- package/docs/architecture/guest-desktop.md +2 -2
- package/docs/architecture/observer.md +34 -34
- package/docs/architecture/restricted-codex-analysis.md +34 -28
- package/docs/architecture/serve.md +34 -37
- package/docs/architecture/state-driven-executor.md +55 -58
- package/docs/architecture/task-protocol-support.md +6 -6
- package/docs/architecture/terminal-product-route.md +70 -110
- package/docs/contracts/README.md +24 -0
- package/docs/contracts/adapter-admission.md +3 -3
- package/docs/contracts/adapter-fixtures.md +4 -7
- package/docs/contracts/core.md +1 -3
- package/docs/contracts/errors.md +62 -0
- package/docs/contracts/feedback.md +8 -9
- package/docs/contracts/policy.md +7 -12
- package/docs/contracts/run-bundle.md +42 -44
- package/docs/contracts/schemas.md +446 -368
- package/docs/contracts/study-analysis.md +7 -4
- package/docs/contracts/study-costs.md +28 -9
- package/docs/decisions/0001-run-bundle-is-the-source-of-truth.md +1 -1
- package/docs/decisions/0002-observer-is-one-self-contained-file.md +2 -2
- package/docs/decisions/0003-contained-paths-and-cleanup-authority.md +3 -3
- package/docs/principles/actor-fidelity.md +4 -4
- package/docs/principles/engineering.md +3 -3
- package/docs/principles/invariants-and-defaults.md +38 -38
- package/docs/principles/self-driving-harness.md +1 -5
- package/docs/principles/three-roles.md +1 -1
- package/docs/product/automatic-analysis.md +7 -7
- package/examples/README.md +1 -1
- package/examples/participant/README.md +5 -5
- package/examples/participant/run.mjs +11 -10
- package/examples/scorer/README.md +3 -3
- package/examples/scorer/run.mjs +11 -12
- package/examples/scorer/scorer.mjs +3 -3
- package/package.json +16 -17
- package/skills/humanish/SKILL.md +64 -60
- package/skills/humanish/agents/openai.yaml +1 -1
- package/AGENTS.md +0 -99
- package/CONTRIBUTING.md +0 -148
- package/dist/actors/codex/qualified-versions.d.ts +0 -72
- package/dist/actors/codex/qualified-versions.js +0 -132
- package/dist/cli/commands/lab-format.d.ts +0 -8
- 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/cli/commands/lab.d.ts +0 -3
- package/dist/cli/commands/lab.js +0 -199
- package/dist/cli/renamed-options.d.ts +0 -11
- package/dist/cli/renamed-options.js +0 -18
- package/dist/lab/composition-rules.d.ts +0 -7
- package/dist/lab/config.d.ts +0 -7
- package/dist/lab/discover.d.ts +0 -65
- package/dist/lab/init-templates.js +0 -416
- package/dist/lab/keys.d.ts +0 -2
- package/dist/lab/parse/comms.d.ts +0 -12
- package/dist/lab/parse/execution.d.ts +0 -19
- package/dist/lab/parse/subject-state.d.ts +0 -30
- package/dist/lab/plan.d.ts +0 -19
- package/dist/lab/plan.js +0 -132
- package/dist/lab/preflight-probes.d.ts +0 -3
- package/dist/lab/preflight-result.d.ts +0 -7
- package/dist/lab/preflight.d.ts +0 -92
- package/dist/lab/route-inputs.d.ts +0 -28
- package/dist/lab/run-lab-options.d.ts +0 -28
- package/dist/lab/warnings.d.ts +0 -2
- package/dist/observer/static.d.ts +0 -39
- package/dist/observer/static.js +0 -369
- package/dist/run-lab.d.ts +0 -112
- package/docs/architecture/comms-inbox.md +0 -122
- package/docs/architecture/desktop-recording.md +0 -80
- package/docs/architecture/local-browser-runtime.md +0 -178
- package/docs/architecture/observer-review.md +0 -144
- package/docs/architecture/participant-media.md +0 -90
- package/docs/architecture/project-layout.md +0 -62
- package/docs/architecture/real-email-receiving.md +0 -136
- package/docs/assets/humanish-drawdb-hero.png +0 -0
- package/docs/assets/humanish-observer-hero.png +0 -0
- package/docs/goals/current.md +0 -207
- package/docs/product/lobby-trivia-3player-external-public.md +0 -77
- package/docs/product/open-source-install-experience.md +0 -240
- package/docs/ramp/README.md +0 -295
- package/docs/release/open-source-readiness.md +0 -222
- package/docs/release/public-readiness-standard.md +0 -210
- package/docs/roadmap/world-class-open-source-v0.md +0 -311
- /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}/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
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
// Convert a humanish.lab.v2 study file to humanish.study.v3. It edits the parsed YAML document in
|
|
2
|
+
// place and moves each pair node, so the comments on a moved key move with it. The result lists
|
|
3
|
+
// every key it moved and every key it dropped. It refuses a file whose v3 form would parse or plan
|
|
4
|
+
// differently from the v2 source with the dropped keys removed.
|
|
5
|
+
import { isAlias, isMap, isScalar, isSeq, LineCounter, Pair, parseDocument, Scalar, visit, YAMLMap, YAMLSeq, } from "yaml";
|
|
6
|
+
import { parseStudyDocument } from "./config.js";
|
|
7
|
+
import { focusOf } from "./parse/actors.js";
|
|
8
|
+
import { posInt } from "./parse/values.js";
|
|
9
|
+
import { planStudy } from "./plan.js";
|
|
10
|
+
import { routeOf } from "./routing.js";
|
|
11
|
+
import { V2_SCHEMA, STUDY_SCHEMA } from "./types.js";
|
|
12
|
+
import { inertFieldPaths } from "./warnings.js";
|
|
13
|
+
import { deleteNodeFieldPath, deletePlainFieldPath, pairIndex, readFieldPath, } from "./field-paths.js";
|
|
14
|
+
function isPlainRecord(value) {
|
|
15
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16
|
+
}
|
|
17
|
+
function refuse(reason) {
|
|
18
|
+
return { ok: false, reason };
|
|
19
|
+
}
|
|
20
|
+
/** Whether a parsed YAML value is a v3 study file. */
|
|
21
|
+
export function isStudyV3(raw) {
|
|
22
|
+
return isPlainRecord(raw) && raw.schema === STUDY_SCHEMA;
|
|
23
|
+
}
|
|
24
|
+
/** Convert one v2 file's text. `cwd` is the project the plan check plans in. */
|
|
25
|
+
export function convertStudyText(text, cwd) {
|
|
26
|
+
const lineCounter = new LineCounter();
|
|
27
|
+
const doc = parseDocument(text, { lineCounter });
|
|
28
|
+
if (doc.errors.length > 0)
|
|
29
|
+
return refuse(`it is not valid YAML: ${doc.errors[0].message}`);
|
|
30
|
+
const anchorLine = firstAnchorLine(doc, lineCounter);
|
|
31
|
+
if (anchorLine !== undefined) {
|
|
32
|
+
return refuse(`line ${anchorLine} uses a YAML anchor or alias. Write the value out in full, then migrate.`);
|
|
33
|
+
}
|
|
34
|
+
const raw = doc.toJS();
|
|
35
|
+
if (!isPlainRecord(raw) || !isMap(doc.contents))
|
|
36
|
+
return refuse("it is not a YAML mapping.");
|
|
37
|
+
if (raw.schema !== V2_SCHEMA)
|
|
38
|
+
return refuse(`its schema is not ${V2_SCHEMA}.`);
|
|
39
|
+
const source = parseStudyDocument(raw);
|
|
40
|
+
if (!source.ok)
|
|
41
|
+
return refuse(`it does not parse: ${source.error.message}`);
|
|
42
|
+
const route = routeOf(source.config);
|
|
43
|
+
const actorRaw = Array.isArray(raw.actors) ? raw.actors[0] : undefined;
|
|
44
|
+
if (route === "terminal" && isPlainRecord(actorRaw)) {
|
|
45
|
+
for (const key of ["count", "laneFocus"]) {
|
|
46
|
+
if (actorRaw[key] !== undefined) {
|
|
47
|
+
return refuse(`actors[0].${key} does nothing on the terminal route, and a v3 terminal study has no participants. Remove it, then migrate.`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
const root = doc.contents;
|
|
52
|
+
const dropped = [];
|
|
53
|
+
for (const path of droppedPaths(source.config, route, raw)) {
|
|
54
|
+
const value = readFieldPath(raw, path);
|
|
55
|
+
const pairs = deleteNodeFieldPath(root, path);
|
|
56
|
+
if (value === undefined || pairs.length === 0)
|
|
57
|
+
continue;
|
|
58
|
+
const comments = pairComments(pairs);
|
|
59
|
+
dropped.push({ path, value, ...(comments === undefined ? {} : { comments }) });
|
|
60
|
+
}
|
|
61
|
+
const moved = [];
|
|
62
|
+
// v2 reads some laneFocus values as no focus at all ({}, a valueless key, valueless fields).
|
|
63
|
+
const focused = focusOf(source.config.actors[0]) !== undefined;
|
|
64
|
+
const converted = convertDocument(root, route, focused, moved);
|
|
65
|
+
if (!converted.ok)
|
|
66
|
+
return converted;
|
|
67
|
+
const out = doc.toString({ lineWidth: foldWidth(text), flowCollectionPadding: false });
|
|
68
|
+
// Fail closed: a comment the conversion did not carry over or report stops it.
|
|
69
|
+
const lost = lostComment(text, out, dropped);
|
|
70
|
+
if (lost !== undefined)
|
|
71
|
+
return refuse(`it would lose the comment "${lost}".`);
|
|
72
|
+
const check = samePlans(raw, dropped.map((key) => key.path), out, cwd);
|
|
73
|
+
if (!check.ok)
|
|
74
|
+
return check;
|
|
75
|
+
return { ok: true, conversion: { text: out, route, moved, dropped } };
|
|
76
|
+
}
|
|
77
|
+
// Every comment line in a YAML text, trimmed.
|
|
78
|
+
function commentLinesOf(text) {
|
|
79
|
+
const doc = parseDocument(text);
|
|
80
|
+
const found = [doc.commentBefore ?? "", doc.comment ?? ""];
|
|
81
|
+
visit(doc, (_key, node) => {
|
|
82
|
+
// An implicit empty value, as `id` in `{id, instruction: x}`, is a null node.
|
|
83
|
+
if (typeof node !== "object" || node === null)
|
|
84
|
+
return;
|
|
85
|
+
const commented = node;
|
|
86
|
+
found.push(commented.commentBefore ?? "", commented.comment ?? "");
|
|
87
|
+
});
|
|
88
|
+
return found
|
|
89
|
+
.flatMap((comment) => comment.split("\n"))
|
|
90
|
+
.map((line) => line.trim())
|
|
91
|
+
.filter(Boolean);
|
|
92
|
+
}
|
|
93
|
+
// The first comment line of the source that is neither in the output nor in a dropped key's report.
|
|
94
|
+
function lostComment(source, output, dropped) {
|
|
95
|
+
const kept = new Map();
|
|
96
|
+
const reported = dropped.flatMap((key) => (key.comments ?? "").split("\n"));
|
|
97
|
+
for (const line of [...commentLinesOf(output), ...reported.map((line) => line.trim())])
|
|
98
|
+
if (line)
|
|
99
|
+
kept.set(line, (kept.get(line) ?? 0) + 1);
|
|
100
|
+
for (const line of commentLinesOf(source)) {
|
|
101
|
+
const left = kept.get(line) ?? 0;
|
|
102
|
+
if (left === 0)
|
|
103
|
+
return line;
|
|
104
|
+
kept.set(line, left - 1);
|
|
105
|
+
}
|
|
106
|
+
return undefined;
|
|
107
|
+
}
|
|
108
|
+
// The inert-field table's paths for the route, plus terminal `execution.timeoutMs`, which no
|
|
109
|
+
// terminal code reads. Parents come before their children, so a child under a dropped parent is
|
|
110
|
+
// reported with the parent.
|
|
111
|
+
function droppedPaths(config, route, raw) {
|
|
112
|
+
const paths = inertFieldPaths(config);
|
|
113
|
+
if (route === "terminal" && readFieldPath(raw, "execution.timeoutMs") !== undefined)
|
|
114
|
+
paths.push("execution.timeoutMs");
|
|
115
|
+
const depth = (path) => path.split(".").length;
|
|
116
|
+
return [...new Set(paths)].sort((left, right) => depth(left) - depth(right));
|
|
117
|
+
}
|
|
118
|
+
// Folded text is folded again on output. Most of a file's long lines end near the width its author
|
|
119
|
+
// folded at, so the 90th percentile of their lengths stands for it, between 80 and 120.
|
|
120
|
+
function foldWidth(text) {
|
|
121
|
+
const long = text
|
|
122
|
+
.split("\n")
|
|
123
|
+
.map((line) => line.length)
|
|
124
|
+
.filter((length) => length > 60)
|
|
125
|
+
.sort((left, right) => left - right);
|
|
126
|
+
if (long.length === 0)
|
|
127
|
+
return 80;
|
|
128
|
+
const width = long[Math.min(long.length - 1, Math.floor(long.length * 0.9))];
|
|
129
|
+
return Math.min(120, Math.max(80, width));
|
|
130
|
+
}
|
|
131
|
+
function firstAnchorLine(doc, lineCounter) {
|
|
132
|
+
let line;
|
|
133
|
+
visit(doc, (_key, node) => {
|
|
134
|
+
const anchored = isAlias(node) ||
|
|
135
|
+
(typeof node === "object" &&
|
|
136
|
+
node !== null &&
|
|
137
|
+
"anchor" in node &&
|
|
138
|
+
Boolean(node.anchor));
|
|
139
|
+
if (!anchored)
|
|
140
|
+
return undefined;
|
|
141
|
+
const offset = node.range?.[0] ?? 0;
|
|
142
|
+
line = lineCounter.linePos(offset).line;
|
|
143
|
+
return visit.BREAK;
|
|
144
|
+
});
|
|
145
|
+
return line;
|
|
146
|
+
}
|
|
147
|
+
// Every comment on a node and everything under it.
|
|
148
|
+
function subtreeComments(node, found) {
|
|
149
|
+
if (typeof node !== "object" || node === null)
|
|
150
|
+
return;
|
|
151
|
+
const commented = node;
|
|
152
|
+
if (commented.commentBefore)
|
|
153
|
+
found.push(commented.commentBefore);
|
|
154
|
+
if (commented.comment)
|
|
155
|
+
found.push(commented.comment);
|
|
156
|
+
if (isMap(node) || isSeq(node)) {
|
|
157
|
+
for (const item of node.items) {
|
|
158
|
+
if (item instanceof Pair) {
|
|
159
|
+
subtreeComments(item.key, found);
|
|
160
|
+
subtreeComments(item.value, found);
|
|
161
|
+
}
|
|
162
|
+
else
|
|
163
|
+
subtreeComments(item, found);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
function pairComments(pairs) {
|
|
168
|
+
const found = [];
|
|
169
|
+
for (const pair of pairs) {
|
|
170
|
+
subtreeComments(pair.key, found);
|
|
171
|
+
subtreeComments(pair.value, found);
|
|
172
|
+
}
|
|
173
|
+
const text = found
|
|
174
|
+
.flatMap((comment) => comment.split("\n"))
|
|
175
|
+
.map((line) => line.trim())
|
|
176
|
+
.filter(Boolean)
|
|
177
|
+
.join("\n");
|
|
178
|
+
return text.length > 0 ? text : undefined;
|
|
179
|
+
}
|
|
180
|
+
function keyNode(pair) {
|
|
181
|
+
return pair.key;
|
|
182
|
+
}
|
|
183
|
+
function rename(pair, key) {
|
|
184
|
+
keyNode(pair).value = key;
|
|
185
|
+
}
|
|
186
|
+
function addCommentBefore(pair, comment) {
|
|
187
|
+
if (!comment)
|
|
188
|
+
return;
|
|
189
|
+
const key = keyNode(pair);
|
|
190
|
+
key.commentBefore = key.commentBefore ? `${comment}\n${key.commentBefore}` : comment;
|
|
191
|
+
}
|
|
192
|
+
// Remove `key` from a mapping. A comment the mapping holds above its first key belongs to that key.
|
|
193
|
+
function take(map, key) {
|
|
194
|
+
if (!isMap(map))
|
|
195
|
+
return undefined;
|
|
196
|
+
const index = pairIndex(map, key);
|
|
197
|
+
if (index < 0)
|
|
198
|
+
return undefined;
|
|
199
|
+
const [pair] = map.items.splice(index, 1);
|
|
200
|
+
if (index === 0 && map.commentBefore) {
|
|
201
|
+
addCommentBefore(pair, map.commentBefore);
|
|
202
|
+
map.commentBefore = null;
|
|
203
|
+
}
|
|
204
|
+
return pair;
|
|
205
|
+
}
|
|
206
|
+
function insertAfter(map, anchors, ...pairs) {
|
|
207
|
+
const anchor = anchors.map((key) => pairIndex(map, key)).find((index) => index >= 0);
|
|
208
|
+
map.items.splice(anchor === undefined ? 0 : anchor + 1, 0, ...pairs);
|
|
209
|
+
}
|
|
210
|
+
// A removed section's trailing comment goes above the pair that followed the section, which is
|
|
211
|
+
// where it sat in the file, or to the end of the file when nothing followed.
|
|
212
|
+
function keepTrailingComment(root, next, comment) {
|
|
213
|
+
if (!comment)
|
|
214
|
+
return;
|
|
215
|
+
if (next !== undefined)
|
|
216
|
+
addCommentBefore(next, comment);
|
|
217
|
+
else
|
|
218
|
+
root.comment = root.comment ? `${root.comment}\n${comment}` : comment;
|
|
219
|
+
}
|
|
220
|
+
// Remove a key from a top-level section, and the section with it once it is empty. The section's
|
|
221
|
+
// own comments move to the promoted key.
|
|
222
|
+
function promote(root, section, key) {
|
|
223
|
+
const index = pairIndex(root, section);
|
|
224
|
+
if (index < 0)
|
|
225
|
+
return undefined;
|
|
226
|
+
const container = root.items[index];
|
|
227
|
+
const pair = take(container.value, key);
|
|
228
|
+
if (pair === undefined)
|
|
229
|
+
return undefined;
|
|
230
|
+
if (isMap(container.value) && container.value.items.length === 0) {
|
|
231
|
+
const next = root.items[index + 1];
|
|
232
|
+
root.items.splice(index, 1);
|
|
233
|
+
addCommentBefore(pair, keyNode(container).commentBefore);
|
|
234
|
+
keepTrailingComment(root, next, container.value.comment);
|
|
235
|
+
}
|
|
236
|
+
return pair;
|
|
237
|
+
}
|
|
238
|
+
function convertDocument(root, route, focused, moved) {
|
|
239
|
+
const schema = root.items[pairIndex(root, "schema")];
|
|
240
|
+
if (schema && isScalar(schema.value))
|
|
241
|
+
schema.value.value = STUDY_SCHEMA;
|
|
242
|
+
// actors[0] becomes actor, at the same position.
|
|
243
|
+
const actorsPair = root.items[pairIndex(root, "actors")];
|
|
244
|
+
if (!actorsPair || !isSeq(actorsPair.value) || !isMap(actorsPair.value.items[0]))
|
|
245
|
+
return refuse("its actors list does not hold one actor mapping.");
|
|
246
|
+
const list = actorsPair.value;
|
|
247
|
+
const actor = list.items[0];
|
|
248
|
+
if (list.commentBefore)
|
|
249
|
+
actor.commentBefore = [list.commentBefore, actor.commentBefore].filter(Boolean).join("\n");
|
|
250
|
+
if (list.comment)
|
|
251
|
+
actor.comment = [actor.comment, list.comment].filter(Boolean).join("\n");
|
|
252
|
+
rename(actorsPair, "actor");
|
|
253
|
+
actorsPair.value = actor;
|
|
254
|
+
moved.push({ from: "actors[0]", to: "actor" });
|
|
255
|
+
let after = "actor";
|
|
256
|
+
const participants = participantsPair(actor, route, focused, moved);
|
|
257
|
+
if (participants !== undefined) {
|
|
258
|
+
insertAfter(root, [after], participants);
|
|
259
|
+
after = String(keyNode(participants).value);
|
|
260
|
+
}
|
|
261
|
+
const capsSection = route === "terminal" ? "scenario" : "execution";
|
|
262
|
+
const caps = promote(root, capsSection, "caps");
|
|
263
|
+
if (caps !== undefined) {
|
|
264
|
+
insertAfter(root, [after], caps);
|
|
265
|
+
moved.push({ from: `${capsSection}.caps`, to: "caps" });
|
|
266
|
+
}
|
|
267
|
+
// scenario.ref becomes scenario, a string, where scenario was; scenario.mode becomes mode.
|
|
268
|
+
let mode;
|
|
269
|
+
const scenarioIndex = pairIndex(root, "scenario");
|
|
270
|
+
if (scenarioIndex >= 0) {
|
|
271
|
+
const scenario = root.items[scenarioIndex];
|
|
272
|
+
mode = take(scenario.value, "mode");
|
|
273
|
+
const ref = take(scenario.value, "ref");
|
|
274
|
+
if (isMap(scenario.value) && scenario.value.items.length > 0) {
|
|
275
|
+
return refuse(`scenario still holds ${scenario.value.items.map((pair) => String(keyNode(pair).value)).join(", ")} after conversion.`);
|
|
276
|
+
}
|
|
277
|
+
const next = root.items[scenarioIndex + 1];
|
|
278
|
+
root.items.splice(scenarioIndex, 1);
|
|
279
|
+
const promoted = mode ?? ref;
|
|
280
|
+
// A comment on the `scenario:` line sits on the section's value, a mapping or an empty scalar,
|
|
281
|
+
// when nothing took it.
|
|
282
|
+
const value = scenario.value;
|
|
283
|
+
const note = [keyNode(scenario).commentBefore, value?.commentBefore].filter(Boolean).join("\n");
|
|
284
|
+
if (promoted !== undefined)
|
|
285
|
+
addCommentBefore(promoted, note);
|
|
286
|
+
else
|
|
287
|
+
keepTrailingComment(root, next, note);
|
|
288
|
+
keepTrailingComment(root, next, value?.comment);
|
|
289
|
+
if (ref !== undefined) {
|
|
290
|
+
rename(ref, "scenario");
|
|
291
|
+
root.items.splice(scenarioIndex, 0, ref);
|
|
292
|
+
moved.push({ from: "scenario.ref", to: "scenario" });
|
|
293
|
+
}
|
|
294
|
+
if (mode !== undefined)
|
|
295
|
+
moved.push({ from: "scenario.mode", to: "mode" });
|
|
296
|
+
}
|
|
297
|
+
const routePair = new Pair(new Scalar("route"), new Scalar(route));
|
|
298
|
+
// subject.topology says shared-world; route says it now, and takes its comments.
|
|
299
|
+
const subject = root.items[pairIndex(root, "subject")];
|
|
300
|
+
const topology = route === "shared-world" && subject ? take(subject.value, "topology") : undefined;
|
|
301
|
+
if (topology !== undefined) {
|
|
302
|
+
addCommentBefore(routePair, keyNode(topology).commentBefore);
|
|
303
|
+
const value = topology.value;
|
|
304
|
+
addCommentBefore(routePair, value?.commentBefore);
|
|
305
|
+
if (value?.comment)
|
|
306
|
+
routePair.value.comment = value.comment;
|
|
307
|
+
moved.push({ from: "subject.topology", to: "route" });
|
|
308
|
+
}
|
|
309
|
+
insertAfter(root, ["description", "title", "id"], ...[routePair, mode].filter((pair) => pair !== undefined));
|
|
310
|
+
return { ok: true };
|
|
311
|
+
}
|
|
312
|
+
// The participant keys leave the actor for `participants`, or `surfaces` on the scripted route.
|
|
313
|
+
function participantsPair(actor, route, focused, moved) {
|
|
314
|
+
const count = take(actor, "count");
|
|
315
|
+
const entries = take(actor, "lanes");
|
|
316
|
+
const roster = take(actor, "roster");
|
|
317
|
+
let focus = take(actor, "laneFocus");
|
|
318
|
+
// A `laneFocus` v2 reads as no focus converts as if absent. Every comment in it goes above the
|
|
319
|
+
// count, or to the end of the actor.
|
|
320
|
+
if (focus !== undefined && !focused) {
|
|
321
|
+
const found = [];
|
|
322
|
+
subtreeComments(focus.key, found);
|
|
323
|
+
subtreeComments(focus.value, found);
|
|
324
|
+
const notes = found.join("\n");
|
|
325
|
+
if (count !== undefined)
|
|
326
|
+
addCommentBefore(count, notes);
|
|
327
|
+
else if (notes)
|
|
328
|
+
actor.comment = [actor.comment, notes].filter(Boolean).join("\n");
|
|
329
|
+
focus = undefined;
|
|
330
|
+
}
|
|
331
|
+
if (route === "scripted") {
|
|
332
|
+
if (count === undefined)
|
|
333
|
+
return undefined;
|
|
334
|
+
const surfaces = new YAMLSeq();
|
|
335
|
+
surfaces.flow = true;
|
|
336
|
+
const two = isScalar(count.value) && Number(count.value.value) === 2;
|
|
337
|
+
surfaces.items.push(new Scalar("desktop"), ...(two ? [new Scalar("mobile")] : []));
|
|
338
|
+
if (isScalar(count.value) && count.value.comment)
|
|
339
|
+
surfaces.comment = count.value.comment;
|
|
340
|
+
if (isScalar(count.value))
|
|
341
|
+
addCommentBefore(count, count.value.commentBefore);
|
|
342
|
+
rename(count, "surfaces");
|
|
343
|
+
count.value = surfaces;
|
|
344
|
+
moved.push({ from: "actors[0].count", to: "surfaces" });
|
|
345
|
+
return count;
|
|
346
|
+
}
|
|
347
|
+
const list = entries ?? roster;
|
|
348
|
+
if (list !== undefined) {
|
|
349
|
+
if (isSeq(list.value))
|
|
350
|
+
for (const item of list.value.items)
|
|
351
|
+
if (isMap(item))
|
|
352
|
+
numericCount(item.items[pairIndex(item, "count")]);
|
|
353
|
+
rename(list, "participants");
|
|
354
|
+
moved.push({ from: `actors[0].${entries ? "lanes" : "roster"}`, to: "participants" });
|
|
355
|
+
return list;
|
|
356
|
+
}
|
|
357
|
+
if (focus !== undefined) {
|
|
358
|
+
const instruction = take(focus.value, "instruction");
|
|
359
|
+
const homogeneous = new YAMLMap();
|
|
360
|
+
// laneFocus's mapping, or the empty scalar a valueless `laneFocus:` holds, carries its comments.
|
|
361
|
+
const focusValue = focus.value;
|
|
362
|
+
if (focusValue?.comment)
|
|
363
|
+
homogeneous.comment = focusValue.comment;
|
|
364
|
+
if (focusValue?.commentBefore)
|
|
365
|
+
homogeneous.commentBefore = focusValue.commentBefore;
|
|
366
|
+
// Fields v2 read as unset (`id: null`) go with the old mapping; their comments stay.
|
|
367
|
+
const rest = [];
|
|
368
|
+
if (isMap(focus.value))
|
|
369
|
+
for (const item of focus.value.items) {
|
|
370
|
+
subtreeComments(item.key, rest);
|
|
371
|
+
subtreeComments(item.value, rest);
|
|
372
|
+
}
|
|
373
|
+
if (rest.length > 0)
|
|
374
|
+
homogeneous.comment = [homogeneous.comment, ...rest].filter(Boolean).join("\n");
|
|
375
|
+
numericCount(count);
|
|
376
|
+
if (count !== undefined)
|
|
377
|
+
homogeneous.items.push(count);
|
|
378
|
+
if (instruction !== undefined)
|
|
379
|
+
homogeneous.items.push(instruction);
|
|
380
|
+
rename(focus, "participants");
|
|
381
|
+
focus.value = homogeneous;
|
|
382
|
+
moved.push({ from: "actors[0].laneFocus", to: "participants" });
|
|
383
|
+
if (count !== undefined)
|
|
384
|
+
moved.push({ from: "actors[0].count", to: "participants.count" });
|
|
385
|
+
return focus;
|
|
386
|
+
}
|
|
387
|
+
if (count !== undefined) {
|
|
388
|
+
numericCount(count);
|
|
389
|
+
rename(count, "participants");
|
|
390
|
+
moved.push({ from: "actors[0].count", to: "participants" });
|
|
391
|
+
return count;
|
|
392
|
+
}
|
|
393
|
+
return undefined;
|
|
394
|
+
}
|
|
395
|
+
// v2 reads a count written as a digit string, such as "2"; v3 takes a number, so write the number.
|
|
396
|
+
function numericCount(pair) {
|
|
397
|
+
if (pair === undefined || !isScalar(pair.value) || typeof pair.value.value !== "string")
|
|
398
|
+
return;
|
|
399
|
+
const count = posInt(pair.value.value);
|
|
400
|
+
if (count === undefined)
|
|
401
|
+
return;
|
|
402
|
+
pair.value.value = count;
|
|
403
|
+
pair.value.type = Scalar.PLAIN;
|
|
404
|
+
}
|
|
405
|
+
// JSON drops undefined fields, so two configs built through different branches compare by value.
|
|
406
|
+
function plain(value) {
|
|
407
|
+
return JSON.parse(JSON.stringify(value));
|
|
408
|
+
}
|
|
409
|
+
function samePlans(raw, dropped, text, cwd) {
|
|
410
|
+
const projected = structuredClone(raw);
|
|
411
|
+
for (const path of dropped)
|
|
412
|
+
deletePlainFieldPath(projected, path);
|
|
413
|
+
const before = parseStudyDocument(projected);
|
|
414
|
+
if (!before.ok) {
|
|
415
|
+
return refuse(`it does not parse once the unread keys are dropped: ${before.error.message}`);
|
|
416
|
+
}
|
|
417
|
+
const after = parseStudyDocument(parseDocument(text).toJS());
|
|
418
|
+
if (!after.ok)
|
|
419
|
+
return refuse(`its v3 form does not parse: ${after.error.message}`);
|
|
420
|
+
if (JSON.stringify(plain({ ...after.config, schema: V2_SCHEMA })) !==
|
|
421
|
+
JSON.stringify(plain(before.config))) {
|
|
422
|
+
return refuse("its v3 form parses to a different study.");
|
|
423
|
+
}
|
|
424
|
+
for (const dryRun of [true, false]) {
|
|
425
|
+
const v2 = plain(planStudy(before.config, { cwd, dryRun }));
|
|
426
|
+
const v3 = plain(planStudy(after.config, { cwd, dryRun }));
|
|
427
|
+
if (JSON.stringify(v2) !== JSON.stringify(v3)) {
|
|
428
|
+
return refuse(`its v3 form plans a different ${dryRun ? "dry" : "live"} run.`);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
return { ok: true };
|
|
432
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { StudyConfig } from "./types.js";
|
|
2
2
|
export interface DevicePreset {
|
|
3
3
|
/** Requested device width; the hosted physical screen may be widened to its minimum. */
|
|
4
4
|
width: number;
|
|
@@ -55,7 +55,7 @@ export declare const DEVICE_PRESETS: {
|
|
|
55
55
|
export type DevicePresetName = keyof typeof DEVICE_PRESETS;
|
|
56
56
|
/**
|
|
57
57
|
* Default device for a run that does not declare one. `desktop` (1440x950) is the median
|
|
58
|
-
* first-run laptop screen
|
|
58
|
+
* first-run laptop screen, the in-house desktop default, within 10px of the 1440x960 dry-run
|
|
59
59
|
* surface in src/run/dry-run.ts. `wide` (1920x1080), the most-common external monitor, is one
|
|
60
60
|
* keystroke away (`execution.desktop.device: wide`) but is deliberately not the default,
|
|
61
61
|
* because the median device a first-time user arrives on is a laptop, not a 1080p monitor.
|
|
@@ -67,28 +67,28 @@ export declare function isDevicePresetName(value: unknown): value is DevicePrese
|
|
|
67
67
|
/** Resolve a preset name (or undefined) to its preset, falling back to the default. */
|
|
68
68
|
export declare function resolveDevicePreset(name: DevicePresetName | undefined): DevicePreset;
|
|
69
69
|
/**
|
|
70
|
-
* The narrowest browser
|
|
70
|
+
* The narrowest browser window Chrome/Chromium will render on the E2B desktop. Chrome refuses to
|
|
71
71
|
* make its window narrower than this (~500 CSS px observed: a 414-wide X screen produced a 500-wide
|
|
72
|
-
* window that
|
|
73
|
-
*
|
|
74
|
-
* narrow-mobile 320) gets a 500-wide screen the window fits exactly
|
|
72
|
+
* window that overflowed it, clipping the right edge of the page off-screen). So the physically
|
|
73
|
+
* rendered screen width is floored here: a sub-500 mobile preset (mobile 414, small-mobile 360,
|
|
74
|
+
* narrow-mobile 320) gets a 500-wide screen the window fits exactly, with no clip. The device preset keeps
|
|
75
75
|
* its true identity (isMobile, nominal width) for the persona prompt + metadata; only the rendered
|
|
76
76
|
* screen is floored. True sub-500 CSS-viewport rendering (page laid out at 414 regardless of window
|
|
77
|
-
* width, via CDP device-metric emulation) is the separate
|
|
77
|
+
* width, via CDP device-metric emulation) is the separate mobileEmulation option.
|
|
78
78
|
*/
|
|
79
79
|
export declare const MIN_DESKTOP_RENDER_WIDTH = 500;
|
|
80
|
-
/** Floor a screen resolution's
|
|
80
|
+
/** Floor a screen resolution's width to what Chrome can actually render (see MIN_DESKTOP_RENDER_WIDTH). */
|
|
81
81
|
export declare function floorRenderResolution(resolution: readonly [number, number]): [number, number];
|
|
82
82
|
/**
|
|
83
83
|
* Resolve a participant's device + rendered resolution (most-specific wins, exactly as the
|
|
84
84
|
* single-participant path always has): a raw execution.desktop.resolution escape hatch (only legal
|
|
85
|
-
* when no roster entry sets a device
|
|
85
|
+
* when no roster entry sets a device; XOR enforced at parse) → the participant's named device → the run-wide
|
|
86
86
|
* execution.desktop.device → the default preset. A raw resolution is an unnamed custom desktop
|
|
87
87
|
* (non-mobile, DSF 1): we never claim a named preset's mobile/DPR for hand-set geometry. The rendered
|
|
88
88
|
* `resolution` is floored to MIN_DESKTOP_RENDER_WIDTH so the browser window fits its X screen (no clip);
|
|
89
89
|
* `preset` keeps the declared device identity (a mobile preset stays 414/isMobile for the prompt).
|
|
90
90
|
*/
|
|
91
|
-
export declare function resolveParticipantDevice(config:
|
|
91
|
+
export declare function resolveParticipantDevice(config: StudyConfig,
|
|
92
92
|
/** The device the participant's roster entry names, if any. */
|
|
93
93
|
device: string | undefined): {
|
|
94
94
|
name: string;
|
|
@@ -4,13 +4,13 @@
|
|
|
4
4
|
* the per-line notes record where the two reference sims agree vs. diverge.
|
|
5
5
|
*/
|
|
6
6
|
export const DEVICE_PRESETS = {
|
|
7
|
-
// phone
|
|
7
|
+
// phone: both reference sims agree
|
|
8
8
|
mobile: { width: 414, height: 896, isMobile: true, deviceScaleFactor: 3 },
|
|
9
|
-
// small phone
|
|
9
|
+
// small phone: both reference sims agree
|
|
10
10
|
"small-mobile": { width: 360, height: 740, isMobile: true, deviceScaleFactor: 3 },
|
|
11
11
|
// older narrow phone
|
|
12
12
|
"narrow-mobile": { width: 320, height: 700, isMobile: true, deviceScaleFactor: 2 },
|
|
13
|
-
// tablet
|
|
13
|
+
// tablet: both reference sims agree
|
|
14
14
|
tablet: { width: 820, height: 1180, isMobile: false, deviceScaleFactor: 2 },
|
|
15
15
|
// laptop baseline (the in-house desktop screen; close to the 1440x960 dry-run surface in
|
|
16
16
|
// src/run/dry-run.ts)
|
|
@@ -20,7 +20,7 @@ export const DEVICE_PRESETS = {
|
|
|
20
20
|
};
|
|
21
21
|
/**
|
|
22
22
|
* Default device for a run that does not declare one. `desktop` (1440x950) is the median
|
|
23
|
-
* first-run laptop screen
|
|
23
|
+
* first-run laptop screen, the in-house desktop default, within 10px of the 1440x960 dry-run
|
|
24
24
|
* surface in src/run/dry-run.ts. `wide` (1920x1080), the most-common external monitor, is one
|
|
25
25
|
* keystroke away (`execution.desktop.device: wide`) but is deliberately not the default,
|
|
26
26
|
* because the median device a first-time user arrives on is a laptop, not a 1080p monitor.
|
|
@@ -36,24 +36,24 @@ export function resolveDevicePreset(name) {
|
|
|
36
36
|
return DEVICE_PRESETS[name ?? DEFAULT_DEVICE_PRESET];
|
|
37
37
|
}
|
|
38
38
|
/**
|
|
39
|
-
* The narrowest browser
|
|
39
|
+
* The narrowest browser window Chrome/Chromium will render on the E2B desktop. Chrome refuses to
|
|
40
40
|
* make its window narrower than this (~500 CSS px observed: a 414-wide X screen produced a 500-wide
|
|
41
|
-
* window that
|
|
42
|
-
*
|
|
43
|
-
* narrow-mobile 320) gets a 500-wide screen the window fits exactly
|
|
41
|
+
* window that overflowed it, clipping the right edge of the page off-screen). So the physically
|
|
42
|
+
* rendered screen width is floored here: a sub-500 mobile preset (mobile 414, small-mobile 360,
|
|
43
|
+
* narrow-mobile 320) gets a 500-wide screen the window fits exactly, with no clip. The device preset keeps
|
|
44
44
|
* its true identity (isMobile, nominal width) for the persona prompt + metadata; only the rendered
|
|
45
45
|
* screen is floored. True sub-500 CSS-viewport rendering (page laid out at 414 regardless of window
|
|
46
|
-
* width, via CDP device-metric emulation) is the separate
|
|
46
|
+
* width, via CDP device-metric emulation) is the separate mobileEmulation option.
|
|
47
47
|
*/
|
|
48
48
|
export const MIN_DESKTOP_RENDER_WIDTH = 500;
|
|
49
|
-
/** Floor a screen resolution's
|
|
49
|
+
/** Floor a screen resolution's width to what Chrome can actually render (see MIN_DESKTOP_RENDER_WIDTH). */
|
|
50
50
|
export function floorRenderResolution(resolution) {
|
|
51
51
|
return [Math.max(resolution[0], MIN_DESKTOP_RENDER_WIDTH), resolution[1]];
|
|
52
52
|
}
|
|
53
53
|
/**
|
|
54
54
|
* Resolve a participant's device + rendered resolution (most-specific wins, exactly as the
|
|
55
55
|
* single-participant path always has): a raw execution.desktop.resolution escape hatch (only legal
|
|
56
|
-
* when no roster entry sets a device
|
|
56
|
+
* when no roster entry sets a device; XOR enforced at parse) → the participant's named device → the run-wide
|
|
57
57
|
* execution.desktop.device → the default preset. A raw resolution is an unnamed custom desktop
|
|
58
58
|
* (non-mobile, DSF 1): we never claim a named preset's mobile/DPR for hand-set geometry. The rendered
|
|
59
59
|
* `resolution` is floored to MIN_DESKTOP_RENDER_WIDTH so the browser window fits its X screen (no clip);
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { ActorPersonaRef } from "../actors/contract.js";
|
|
2
|
+
import { type StudyConfig } from "./types.js";
|
|
3
|
+
declare const STUDY_LIST_SCHEMA = "humanish.study-list.v1";
|
|
4
|
+
declare const STUDY_SHOW_SCHEMA = "humanish.study-show.v1";
|
|
5
|
+
type StudyOrigin = "committed" | "ignored" | "explicit";
|
|
6
|
+
interface ResolvedStudyConfig {
|
|
7
|
+
config: StudyConfig;
|
|
8
|
+
origin: StudyOrigin;
|
|
9
|
+
path: string;
|
|
10
|
+
warnings: string[];
|
|
11
|
+
}
|
|
12
|
+
export interface StudyResolveFailure {
|
|
13
|
+
ok: false;
|
|
14
|
+
cwd: string;
|
|
15
|
+
/** The study the caller asked for, as given. */
|
|
16
|
+
study: string;
|
|
17
|
+
error: {
|
|
18
|
+
code: "HUMANISH_STUDY_NOT_FOUND" | "HUMANISH_STUDY_INVALID" | "HUMANISH_STUDY_V2_UNSUPPORTED" | "HUMANISH_STUDY_RETIRED_DIRECTORY";
|
|
19
|
+
message: string;
|
|
20
|
+
};
|
|
21
|
+
warnings: string[];
|
|
22
|
+
}
|
|
23
|
+
export type StudyResolveResult = ({
|
|
24
|
+
ok: true;
|
|
25
|
+
} & ResolvedStudyConfig) | StudyResolveFailure;
|
|
26
|
+
export interface StudyListEntry {
|
|
27
|
+
id: string;
|
|
28
|
+
source: StudyConfig["subject"]["source"];
|
|
29
|
+
origin: StudyOrigin;
|
|
30
|
+
path: string;
|
|
31
|
+
title?: string;
|
|
32
|
+
/**
|
|
33
|
+
* The manifest's own first sentence. The list is where someone decides which study to open, and a
|
|
34
|
+
* list of names cannot answer "what is this one" for a project with twenty labs in it; the
|
|
35
|
+
* stakeholder feedback that added this was, verbatim, "so i know wtf they are".
|
|
36
|
+
*/
|
|
37
|
+
description?: string;
|
|
38
|
+
}
|
|
39
|
+
/** A file in a study directory that humanish no longer reads, with what to do about it. */
|
|
40
|
+
interface RetiredStudyFile {
|
|
41
|
+
path: string;
|
|
42
|
+
code: "HUMANISH_STUDY_V2_UNSUPPORTED" | "HUMANISH_STUDY_RETIRED_DIRECTORY";
|
|
43
|
+
message: string;
|
|
44
|
+
}
|
|
45
|
+
export interface StudyListResult {
|
|
46
|
+
schema: typeof STUDY_LIST_SCHEMA;
|
|
47
|
+
ok: true;
|
|
48
|
+
cwd: string;
|
|
49
|
+
studies: StudyListEntry[];
|
|
50
|
+
/** Each also has its message in `warnings`. */
|
|
51
|
+
retired: RetiredStudyFile[];
|
|
52
|
+
warnings: string[];
|
|
53
|
+
}
|
|
54
|
+
export interface StudyInspectResult {
|
|
55
|
+
/** Persona context only, before route instructions and runtime grants. */
|
|
56
|
+
personas?: Array<{
|
|
57
|
+
id: string;
|
|
58
|
+
resolved: boolean;
|
|
59
|
+
brief?: ActorPersonaRef["brief"];
|
|
60
|
+
}>;
|
|
61
|
+
schema: typeof STUDY_SHOW_SCHEMA;
|
|
62
|
+
ok: boolean;
|
|
63
|
+
cwd: string;
|
|
64
|
+
/** The study the caller asked for, as given. */
|
|
65
|
+
study: string;
|
|
66
|
+
config?: StudyConfig;
|
|
67
|
+
origin?: StudyOrigin;
|
|
68
|
+
path?: string;
|
|
69
|
+
error?: StudyResolveFailure["error"];
|
|
70
|
+
warnings: string[];
|
|
71
|
+
}
|
|
72
|
+
export declare function resolveStudyManifest(cwd: string, study: string): Promise<StudyResolveResult>;
|
|
73
|
+
export declare function listStudyManifests(cwd: string): Promise<StudyListResult>;
|
|
74
|
+
export declare function inspectStudyManifest(cwd: string, study: string): Promise<StudyInspectResult>;
|
|
75
|
+
export {};
|