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,421 @@
|
|
|
1
|
+
import { DEFAULT_ANALYSIS_MAX_COST_USD } from "../analysis/automatic-config.js";
|
|
2
|
+
export const DEFAULT_LOCAL_BROWSER_STARTER = {
|
|
3
|
+
appUrl: "http://127.0.0.1:3000",
|
|
4
|
+
mission: "Use the app's primary flow. Explain anything confusing and stop when the task is complete or you are stuck.",
|
|
5
|
+
};
|
|
6
|
+
function localBrowserStudy(starter = DEFAULT_LOCAL_BROWSER_STARTER) {
|
|
7
|
+
return {
|
|
8
|
+
path: "humanish/studies/local-browser.yaml",
|
|
9
|
+
plane: "source",
|
|
10
|
+
contents: `schema: humanish.study.v3
|
|
11
|
+
id: local-browser
|
|
12
|
+
title: Local browser · your app · Codex account
|
|
13
|
+
description: >-
|
|
14
|
+
Runs one participant on your Codex account in an isolated local browser against your loopback
|
|
15
|
+
app. Needs no E2B or OpenAI API key: inference is remote and uses your Codex account quota.
|
|
16
|
+
Before the first live run, check the Codex login and the local runtime with humanish doctor
|
|
17
|
+
--study local-browser.
|
|
18
|
+
route: computer-use
|
|
19
|
+
mode: live
|
|
20
|
+
subject:
|
|
21
|
+
source: app-url
|
|
22
|
+
appUrl: ${JSON.stringify(starter.appUrl)}
|
|
23
|
+
actor:
|
|
24
|
+
type: local-agent
|
|
25
|
+
localAgent: codex
|
|
26
|
+
persona: synthetic-new-user
|
|
27
|
+
mission: ${JSON.stringify(starter.mission)}
|
|
28
|
+
execution:
|
|
29
|
+
target: local
|
|
30
|
+
concurrency: 1
|
|
31
|
+
timeoutMs: 120000
|
|
32
|
+
defaults:
|
|
33
|
+
open: true
|
|
34
|
+
`,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The flagship live study. A ChatGPT-account Codex participant has no API-dollar price, so preflight
|
|
39
|
+
* refuses a dollar cap on it (HUMANISH_COMPUTER_USE_UNPRICED_CAP); that variant is bounded by the
|
|
40
|
+
* session timeout instead of a cap it could never enforce.
|
|
41
|
+
*/
|
|
42
|
+
function tryLiveStudy(actor, localAgent = "codex") {
|
|
43
|
+
const account = actor === "local-agent";
|
|
44
|
+
const needs = account
|
|
45
|
+
? ` Needs E2B_API_KEY and the coding agent signed in on this machine. Cost: one small task, a few
|
|
46
|
+
E2B desktop minutes and the agent's account usage. humanish cannot put a dollar cap on account
|
|
47
|
+
usage, so the ten-minute session limit below bounds the run. When OPENAI_API_KEY is set, the
|
|
48
|
+
analysis after the run bills it: humanish refuses that request before it starts if its estimate
|
|
49
|
+
is over $${DEFAULT_ANALYSIS_MAX_COST_USD}. Set review.analysis: false to skip it.`
|
|
50
|
+
: ` Needs E2B_API_KEY and OPENAI_API_KEY. Cost: one small task with a $2 cap on estimated model
|
|
51
|
+
spend. The run stops before its next model request once the estimate passes $2, so the last
|
|
52
|
+
request can go slightly over, and hosted desktop time is billed separately. The analysis after
|
|
53
|
+
the run bills the same key outside that cap: humanish refuses it before it starts if its
|
|
54
|
+
estimate is over $${DEFAULT_ANALYSIS_MAX_COST_USD}. Set review.analysis: false to skip it.`;
|
|
55
|
+
const participant = account
|
|
56
|
+
? `# Your machine has a coding agent signed in, so this study uses it: no provider API key, only
|
|
57
|
+
# E2B. To use a provider key instead, swap to \`type: openai-computer-use\` and add caps.maxUsd.
|
|
58
|
+
actor:
|
|
59
|
+
type: local-agent
|
|
60
|
+
localAgent: ${localAgent}`
|
|
61
|
+
: `actor:
|
|
62
|
+
type: openai-computer-use
|
|
63
|
+
# Bounds each model reply. Under the cap below it also bounds what a stalled or lost request
|
|
64
|
+
# can cost, so the run can retry it instead of stopping.
|
|
65
|
+
maxOutputTokens: 8192`;
|
|
66
|
+
const caps = account
|
|
67
|
+
? ""
|
|
68
|
+
: `caps:
|
|
69
|
+
maxUsd: 2 # estimated model spend; the run stops before its next request once it passes this
|
|
70
|
+
`;
|
|
71
|
+
const timeout = account
|
|
72
|
+
? " timeoutMs: 600000 # bounds the run; a dollar cap cannot be enforced on account usage"
|
|
73
|
+
: " timeoutMs: 600000";
|
|
74
|
+
return {
|
|
75
|
+
path: "humanish/studies/try-live.yaml",
|
|
76
|
+
plane: "source",
|
|
77
|
+
contents: `schema: humanish.study.v3
|
|
78
|
+
id: try-live
|
|
79
|
+
title: "Your first live study: one participant on a demo app"
|
|
80
|
+
description: >-
|
|
81
|
+
Runs one participant live on drawDB, a public open-source diagram editor that humanish clones
|
|
82
|
+
and serves in a hosted desktop, so it runs with nothing to configure. The app under study is
|
|
83
|
+
that demo, not yours. The other starter studies need your app's details first.
|
|
84
|
+
${needs}
|
|
85
|
+
A participant who gets stuck and says where is a useful result: humanish does not count that
|
|
86
|
+
run as a pass, and the friction the participant describes is the finding. To study your own
|
|
87
|
+
app, change subject; humanish/studies/cua-browser.yaml shows the shape.
|
|
88
|
+
route: computer-use
|
|
89
|
+
mode: live # the other starter studies start as dry runs
|
|
90
|
+
subject:
|
|
91
|
+
source: clone
|
|
92
|
+
repos:
|
|
93
|
+
- drawdb-io/drawdb
|
|
94
|
+
clone:
|
|
95
|
+
depth: 1
|
|
96
|
+
serve:
|
|
97
|
+
# Plain npm: humanish provides the Node runtime that the stock desktop image lacks.
|
|
98
|
+
install: npm install --no-audit --no-fund
|
|
99
|
+
build: npm run build
|
|
100
|
+
start: npx vite preview --host 127.0.0.1 --port 3000
|
|
101
|
+
url: http://127.0.0.1:3000/
|
|
102
|
+
${participant}
|
|
103
|
+
persona: synthetic-new-user
|
|
104
|
+
mission: >-
|
|
105
|
+
You have never seen this diagram tool before. Add two tables and give them meaningful names,
|
|
106
|
+
then stop and say what you did, what confused you, and where you hesitated.
|
|
107
|
+
${caps}execution:
|
|
108
|
+
target: e2b-desktop
|
|
109
|
+
${timeout}
|
|
110
|
+
defaults:
|
|
111
|
+
open: true
|
|
112
|
+
`,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
export const starterFiles = [
|
|
116
|
+
{
|
|
117
|
+
path: "humanish/README.md",
|
|
118
|
+
plane: "source",
|
|
119
|
+
contents: `# humanish
|
|
120
|
+
|
|
121
|
+
This directory holds the committed definitions of this app's humanish studies: study files,
|
|
122
|
+
personas and scenarios.
|
|
123
|
+
|
|
124
|
+
Keep this directory public-safe:
|
|
125
|
+
|
|
126
|
+
- synthetic personas only;
|
|
127
|
+
- synthetic fixtures only;
|
|
128
|
+
- env var names only, never values;
|
|
129
|
+
- no PII, PHI, secrets, raw private transcripts, private screenshots, customer data, or patient data.
|
|
130
|
+
|
|
131
|
+
Generated run bundles, screenshots, traces, logs, and local overrides belong in ignored \`.humanish/\`.
|
|
132
|
+
|
|
133
|
+
Studies:
|
|
134
|
+
|
|
135
|
+
- committed reusable studies live in humanish/studies/*.yaml;
|
|
136
|
+
- private or machine-local studies live in ignored .humanish/studies/*.yaml or
|
|
137
|
+
.humanish/local/studies/*.yaml;
|
|
138
|
+
- run a study with \`humanish run <study>\`, or \`humanish watch <study>\` to stay attached;
|
|
139
|
+
- files under humanish/labs/ move there with \`humanish migrate\`.
|
|
140
|
+
|
|
141
|
+
Format standard:
|
|
142
|
+
|
|
143
|
+
- human-authored humanish source uses .yaml;
|
|
144
|
+
- generated artifacts, synthetic fixtures, and event streams use .json or .ndjson;
|
|
145
|
+
- .yml is reserved for outside ecosystem files such as GitHub Actions, not humanish source.
|
|
146
|
+
`,
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
path: "humanish/personas/synthetic-new-user.yaml",
|
|
150
|
+
plane: "source",
|
|
151
|
+
contents: `schema: humanish.persona.v1
|
|
152
|
+
id: synthetic-new-user
|
|
153
|
+
name: Synthetic New User
|
|
154
|
+
summary: A privacy-safe first-time user evaluating the app with realistic but synthetic needs.
|
|
155
|
+
traits:
|
|
156
|
+
patience: medium
|
|
157
|
+
technical_confidence: medium
|
|
158
|
+
constraints:
|
|
159
|
+
- Do not use real personal data.
|
|
160
|
+
- Do not use production accounts.
|
|
161
|
+
- Treat all credentials as env var names only.
|
|
162
|
+
`,
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
path: "humanish/personas/skeptical-power-user.yaml",
|
|
166
|
+
plane: "source",
|
|
167
|
+
contents: `schema: humanish.persona.v1
|
|
168
|
+
id: skeptical-power-user
|
|
169
|
+
name: Skeptical Power User
|
|
170
|
+
summary: A privacy-safe experienced user looking for speed, reversibility, and clear proof.
|
|
171
|
+
traits:
|
|
172
|
+
patience: low
|
|
173
|
+
technical_confidence: high
|
|
174
|
+
accessibility_needs: keyboard_first
|
|
175
|
+
constraints:
|
|
176
|
+
- Do not use real personal data.
|
|
177
|
+
- Prefer synthetic fixture inputs.
|
|
178
|
+
- Flag unclear recovery paths.
|
|
179
|
+
`,
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
path: "humanish/scenarios/first-run-smoke.yaml",
|
|
183
|
+
plane: "source",
|
|
184
|
+
contents: `schema: humanish.scenario.v1
|
|
185
|
+
id: first-run-smoke
|
|
186
|
+
title: First-run smoke
|
|
187
|
+
persona: synthetic-new-user
|
|
188
|
+
goal: Reach the first meaningful product state without using private data.
|
|
189
|
+
mode: dry-run
|
|
190
|
+
steps:
|
|
191
|
+
- name: Open the app
|
|
192
|
+
expectation: The app shell is reachable.
|
|
193
|
+
- name: Complete the first synthetic action
|
|
194
|
+
expectation: The user sees a clear next state.
|
|
195
|
+
- name: Capture review notes
|
|
196
|
+
expectation: Notes are public-safe and evidence-backed.
|
|
197
|
+
`,
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
path: "humanish/scenarios/onboarding-regression.yaml",
|
|
201
|
+
plane: "source",
|
|
202
|
+
contents: `schema: humanish.scenario.v1
|
|
203
|
+
id: onboarding-regression
|
|
204
|
+
title: Onboarding regression
|
|
205
|
+
persona: skeptical-power-user
|
|
206
|
+
goal: Exercise onboarding friction using synthetic inputs and explicit recovery checks.
|
|
207
|
+
mode: dry-run
|
|
208
|
+
steps:
|
|
209
|
+
- name: Start onboarding
|
|
210
|
+
expectation: Required information is clear.
|
|
211
|
+
- name: Use synthetic fixture data
|
|
212
|
+
expectation: No real user data is entered.
|
|
213
|
+
- name: Check recovery path
|
|
214
|
+
expectation: The user can back out or retry safely.
|
|
215
|
+
`,
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
path: "humanish/studies/first-run.yaml",
|
|
219
|
+
plane: "source",
|
|
220
|
+
contents: `schema: humanish.study.v3
|
|
221
|
+
id: first-run
|
|
222
|
+
title: First-run synthetic Observer
|
|
223
|
+
description: >-
|
|
224
|
+
Does a dry run: writes a synthetic run bundle and Observer for four participants. Needs no browser,
|
|
225
|
+
model or keys, and costs nothing. Run it with humanish run first-run.
|
|
226
|
+
route: preview
|
|
227
|
+
mode: dry-run
|
|
228
|
+
subject:
|
|
229
|
+
source: this-repo
|
|
230
|
+
actor:
|
|
231
|
+
type: synthetic-persona
|
|
232
|
+
participants: 4
|
|
233
|
+
defaults:
|
|
234
|
+
open: true
|
|
235
|
+
`,
|
|
236
|
+
},
|
|
237
|
+
tryLiveStudy("openai-computer-use"),
|
|
238
|
+
localBrowserStudy(),
|
|
239
|
+
{
|
|
240
|
+
path: "humanish/studies/cua-browser.yaml",
|
|
241
|
+
plane: "source",
|
|
242
|
+
contents: `schema: humanish.study.v3
|
|
243
|
+
id: cua-browser
|
|
244
|
+
title: Computer-use browser study
|
|
245
|
+
description: >-
|
|
246
|
+
A computer-use participant drives your app in a hosted desktop browser and writes its evidence
|
|
247
|
+
to gitignored .humanish/. Starts as a dry run. For a live session, set mode to live
|
|
248
|
+
and pass OPENAI_API_KEY and E2B_API_KEY with --env-file. The clone subject below serves your
|
|
249
|
+
repo inside the sandbox, and the env names declared under subject get their values from
|
|
250
|
+
--env-file without the values being saved. Screenshots keep full fidelity by default; set
|
|
251
|
+
policies.redactScreenshots: true to blur them at capture for a bundle you can share as is.
|
|
252
|
+
Typed text is recorded as its length only.
|
|
253
|
+
route: computer-use
|
|
254
|
+
mode: dry-run
|
|
255
|
+
subject:
|
|
256
|
+
source: clone
|
|
257
|
+
repos: [your-org/your-app]
|
|
258
|
+
serve:
|
|
259
|
+
install: pnpm install --frozen-lockfile
|
|
260
|
+
build: pnpm build
|
|
261
|
+
start: pnpm start
|
|
262
|
+
url: http://127.0.0.1:3000/
|
|
263
|
+
# installTimeoutMs: 1200000 # bump for monorepo-scale installs/builds (default 600000)
|
|
264
|
+
# buildTimeoutMs: 1800000
|
|
265
|
+
# env: [DATABASE_URL]
|
|
266
|
+
# state: # the subject's state, recorded as provenance:
|
|
267
|
+
# seed: # ordered, bounded seed/migration/fixture steps (commands are
|
|
268
|
+
# - name: db-up # author-trusted; evidence records sha256 digests, never text)
|
|
269
|
+
# command: sudo service postgresql start && pg_isready -t 30
|
|
270
|
+
# when: before-start # before-build | before-start (default) | after-ready
|
|
271
|
+
# - name: db-migrate
|
|
272
|
+
# command: pnpm prisma migrate deploy
|
|
273
|
+
# timeoutMs: 300000 # per-step budget (default 300000)
|
|
274
|
+
# - name: admin-user # after-ready steps run against the running app
|
|
275
|
+
# command: curl -sf -X POST http://127.0.0.1:3000/api/test/bootstrap-admin
|
|
276
|
+
# when: after-ready
|
|
277
|
+
# # Or point at a shared DB you do not control; provenance records it as unpinned.
|
|
278
|
+
# # each name must also be declared in subject.env:
|
|
279
|
+
# # external: [DATABASE_URL]
|
|
280
|
+
# clone:
|
|
281
|
+
# keep: true # keep the sandbox after a failure to debug install or boot
|
|
282
|
+
# Alternative: drive a deployment you own (Vercel preview, staging) instead of a clone:
|
|
283
|
+
# source: app-url
|
|
284
|
+
# appUrl: https://your-preview.vercel.app/
|
|
285
|
+
actor:
|
|
286
|
+
type: openai-computer-use
|
|
287
|
+
persona: synthetic-new-user
|
|
288
|
+
mission: >-
|
|
289
|
+
Explore the app as a brand-new user trying to complete its primary flow. Note anything
|
|
290
|
+
confusing. Stop when the flow completes or you are stuck.
|
|
291
|
+
execution:
|
|
292
|
+
target: e2b-desktop
|
|
293
|
+
# 20 minutes, the longest this route allows, so a session ends when the participant finishes.
|
|
294
|
+
# The route clones, installs, builds and serves the subject before the participant starts, so
|
|
295
|
+
# the sandbox deadline is this budget plus 40 minutes of provisioning and teardown, and a sandbox
|
|
296
|
+
# lives at most 60 minutes. A value above 20 minutes fails the run before it starts; raise
|
|
297
|
+
# execution.desktop.sandboxTimeoutMs if you need more. The dollar caps limit spend.
|
|
298
|
+
timeoutMs: 1200000
|
|
299
|
+
desktop:
|
|
300
|
+
device: desktop # mobile | small-mobile | narrow-mobile | tablet | desktop | wide
|
|
301
|
+
# browser: chrome # default | chrome | chromium | firefox; concrete values fail closed
|
|
302
|
+
# Presets size the physical screen; Chrome's window width has a ~500px minimum.
|
|
303
|
+
# For mobile presets, opt into CSS viewport, touch, DPR and mobile user-agent emulation:
|
|
304
|
+
# fidelity: { mobileEmulation: true } # Chrome/Chromium only; desktop and tablet are unchanged
|
|
305
|
+
# The bundle records measured screen, page viewport and emulation fidelity separately.
|
|
306
|
+
# policies:
|
|
307
|
+
# redactScreenshots: true # blur saved frames (off by default: full fidelity for local use)
|
|
308
|
+
# allowPublicTargets: true # required to drive a non-loopback app-url (a deployment you own)
|
|
309
|
+
defaults:
|
|
310
|
+
open: true
|
|
311
|
+
`,
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
path: "humanish/studies/lobby-trivia-3player.yaml",
|
|
315
|
+
plane: "source",
|
|
316
|
+
contents: `schema: humanish.study.v3
|
|
317
|
+
id: lobby-trivia-3player
|
|
318
|
+
title: "Shared world on a public app: three mobile participants in one lobby"
|
|
319
|
+
description: >-
|
|
320
|
+
A worked example of the external-public shared-world route: three participants on mobile layouts
|
|
321
|
+
play the same multiplayer lobby on a public deployment at the same time. The public site is the
|
|
322
|
+
shared plane, so there is no clone, subject sandbox or seed. The host participant creates the
|
|
323
|
+
lobby, humanish reads the session code from the host's page URL, and the other participants get
|
|
324
|
+
it in their missions and join through the app's own join flow. Starts as a dry run, which writes
|
|
325
|
+
one evidence bundle at no cost. A live run needs OPENAI_API_KEY, E2B_API_KEY and mode: live. Point appUrl and publicTarget at a public deployment you own or operate. Mobile layout:
|
|
326
|
+
Chrome's physical window is at least 500px wide and has no touch emulation, desktop pixel ratio
|
|
327
|
+
and a desktop user agent. Set execution.desktop.fidelity.mobileEmulation to true to request the
|
|
328
|
+
preset's CSS viewport, touch, pixel ratio and mobile user agent on Chrome or Chromium; the bundle
|
|
329
|
+
records the measured geometry and emulation fidelity. A run on a public site proves less than a
|
|
330
|
+
provisioned one: its provenance is external-public, it carries no synthetic-data attestation and
|
|
331
|
+
no authoritative shared-state proof, and concurrency rests on overlapping sessions and every
|
|
332
|
+
participant reaching the same lobby.
|
|
333
|
+
route: shared-world
|
|
334
|
+
mode: dry-run # a live run opens three mobile-layout desktops against the public app
|
|
335
|
+
subject:
|
|
336
|
+
source: app-url # the public deployment is the shared plane: no clone and no getHost
|
|
337
|
+
appUrl: https://your-public-app.example/ # a deployment you own or operate
|
|
338
|
+
publicTarget: # required: your attestation that you own or operate this deployment
|
|
339
|
+
owner: your-org/your-app
|
|
340
|
+
authorized: true
|
|
341
|
+
policies:
|
|
342
|
+
allowPublicTargets: true # required: the shared plane is a public, non-loopback deployment
|
|
343
|
+
actor:
|
|
344
|
+
type: openai-computer-use
|
|
345
|
+
mission: You are one of several users on the same shared session at once. Play your role, then stop.
|
|
346
|
+
participants: # at least two participants, exactly one with host: true
|
|
347
|
+
- id: host
|
|
348
|
+
host: true # this participant creates the shared session
|
|
349
|
+
device: mobile # 414x896 preset; physical window width floors to 500 (see emulation above)
|
|
350
|
+
instruction: Create a shared lobby, wait for the others to join, then start and play.
|
|
351
|
+
- id: player-2
|
|
352
|
+
device: mobile
|
|
353
|
+
instruction: Join the lobby you're told the code for, then play.
|
|
354
|
+
- id: player-3
|
|
355
|
+
device: small-mobile
|
|
356
|
+
instruction: Join the lobby you're told the code for, then play.
|
|
357
|
+
execution:
|
|
358
|
+
target: e2b-desktop
|
|
359
|
+
# Each participant's session budget, which also bounds the host's handoff deadline. It has to
|
|
360
|
+
# cover provisioning, joining the shared session and play; 420000 ms (7 minutes) does.
|
|
361
|
+
timeoutMs: 420000
|
|
362
|
+
concurrency: 3 # all three participants at once, the default; lower it only to limit paid desktops
|
|
363
|
+
# desktop:
|
|
364
|
+
# fidelity: { mobileEmulation: true } # opt into mobile CSS viewport, touch, DPR and user agent
|
|
365
|
+
defaults:
|
|
366
|
+
open: true
|
|
367
|
+
`,
|
|
368
|
+
},
|
|
369
|
+
{
|
|
370
|
+
path: "humanish/coverage-map.md",
|
|
371
|
+
plane: "source",
|
|
372
|
+
contents: `# Coverage Map
|
|
373
|
+
|
|
374
|
+
This file should enumerate screens, roles, states, and paths before scenarios are treated as complete.
|
|
375
|
+
|
|
376
|
+
Current starter coverage is intentionally minimal and synthetic.
|
|
377
|
+
`,
|
|
378
|
+
},
|
|
379
|
+
{
|
|
380
|
+
path: "humanish/coverage-matrix.md",
|
|
381
|
+
plane: "source",
|
|
382
|
+
contents: `# Coverage Matrix
|
|
383
|
+
|
|
384
|
+
| Area | Persona | Happy Path | Sad Path | Status |
|
|
385
|
+
| --- | --- | --- | --- | --- |
|
|
386
|
+
| First run | synthetic-new-user | planned | planned | starter |
|
|
387
|
+
| Onboarding | skeptical-power-user | planned | planned | starter |
|
|
388
|
+
`,
|
|
389
|
+
},
|
|
390
|
+
];
|
|
391
|
+
export const runtimeDirectories = [
|
|
392
|
+
{ path: ".humanish/runs", plane: "runtime" },
|
|
393
|
+
{ path: ".humanish/cache", plane: "runtime" },
|
|
394
|
+
{ path: ".humanish/tmp", plane: "runtime" },
|
|
395
|
+
{ path: ".humanish/logs", plane: "runtime" },
|
|
396
|
+
{ path: ".humanish/studies", plane: "runtime" },
|
|
397
|
+
{ path: ".humanish/local/studies", plane: "runtime" },
|
|
398
|
+
{ path: ".humanish/local/personas", plane: "runtime" },
|
|
399
|
+
];
|
|
400
|
+
export const humanishScripts = {
|
|
401
|
+
humanish: "humanish",
|
|
402
|
+
"humanish:doctor": "humanish doctor",
|
|
403
|
+
"humanish:run": "humanish run --dry-run",
|
|
404
|
+
"humanish:watch": "humanish watch",
|
|
405
|
+
"humanish:watch:ci": "humanish watch --json --no-open",
|
|
406
|
+
"humanish:verify": "humanish verify",
|
|
407
|
+
};
|
|
408
|
+
/**
|
|
409
|
+
* The starter files, with the live study written for the brain this machine can use.
|
|
410
|
+
*
|
|
411
|
+
* `local-agent` is not a variant of the study so much as a different participant: on a machine with
|
|
412
|
+
* a signed-in Codex and no provider key, the study runs with the operator's own agent and needs
|
|
413
|
+
* only E2B. Writing the other one there would hand someone homework instead of a first run.
|
|
414
|
+
*/
|
|
415
|
+
export function starterFilesFor(actor, localBrowser = DEFAULT_LOCAL_BROWSER_STARTER, localAgent) {
|
|
416
|
+
return starterFiles.map((file) => file.path === "humanish/studies/local-browser.yaml"
|
|
417
|
+
? localBrowserStudy(localBrowser)
|
|
418
|
+
: file.path === "humanish/studies/try-live.yaml"
|
|
419
|
+
? tryLiveStudy(actor, localAgent)
|
|
420
|
+
: file);
|
|
421
|
+
}
|
|
@@ -5,7 +5,7 @@ export interface InitOptions {
|
|
|
5
5
|
yes?: boolean;
|
|
6
6
|
/** Injected so a test can decide what credentials this machine appears to have. */
|
|
7
7
|
env?: NodeJS.ProcessEnv;
|
|
8
|
-
/** Configure the starter local-browser
|
|
8
|
+
/** Configure the starter local-browser study without making the operator edit YAML. */
|
|
9
9
|
localBrowser?: {
|
|
10
10
|
appUrl: string;
|
|
11
11
|
mission?: string;
|
|
@@ -26,7 +26,7 @@ export interface InitResult {
|
|
|
26
26
|
changes: InitChange[];
|
|
27
27
|
warnings: string[];
|
|
28
28
|
/**
|
|
29
|
-
* The next one or two commands, already resolved against
|
|
29
|
+
* The next one or two commands, already resolved against this machine's credentials. Present on
|
|
30
30
|
* an applied init; absent on a dry-run or a failure, where there is no "next" yet.
|
|
31
31
|
*/
|
|
32
32
|
nextSteps?: string[];
|
|
@@ -8,6 +8,7 @@ import { assertPreparedSelectedOutputDirectory, prepareContainedOutputDirectory,
|
|
|
8
8
|
import { validateCwd } from "../run/project.js";
|
|
9
9
|
import { pathExists, readTextIfExists, validateInitProjectPaths } from "./init-paths.js";
|
|
10
10
|
import { planGitignore, planPackageJson } from "./init-plan.js";
|
|
11
|
+
import { otherStudyFiles, STUDY_DIRECTORIES, studyFileStem } from "./files.js";
|
|
11
12
|
const INIT_RESPONSE_SCHEMA = "humanish.init-result.v1";
|
|
12
13
|
export async function runInit(options) {
|
|
13
14
|
const requestedCwd = path.resolve(options.cwd);
|
|
@@ -37,9 +38,9 @@ export async function runInit(options) {
|
|
|
37
38
|
return failed(initialPathCheck);
|
|
38
39
|
}
|
|
39
40
|
await planAgentsFile(preparedProjectRoot, cwd, plan);
|
|
40
|
-
// The starter live
|
|
41
|
+
// The starter live study is written for the brain this machine can actually use. Shipping it as
|
|
41
42
|
// openai-computer-use on a machine with no provider key but a signed-in Codex would hand someone
|
|
42
|
-
// a file that asks for a credential they were just told they do not need
|
|
43
|
+
// a file that asks for a credential they were just told they do not need.
|
|
43
44
|
const machine = await firstRunEnvironment(options.env ?? process.env, requestedCwd);
|
|
44
45
|
const starterActor = starterActorFor(machine);
|
|
45
46
|
await planStarterFiles(preparedProjectRoot, cwd, starterFilesFor(starterActor, localBrowser.value, starterLocalAgentFor(machine)), options.localBrowser !== undefined, plan);
|
|
@@ -77,16 +78,16 @@ export async function runInit(options) {
|
|
|
77
78
|
cwd: requestedCwd,
|
|
78
79
|
changes: plan.changes,
|
|
79
80
|
warnings: plan.warnings,
|
|
80
|
-
// Resolved against
|
|
81
|
+
// Resolved against this machine, because a next step that cannot work is worse than none.
|
|
81
82
|
...(mode === "applied" ? { nextSteps: firstRunGuidance(machine) } : {}),
|
|
82
83
|
};
|
|
83
84
|
}
|
|
84
|
-
// Leave instructions for the
|
|
85
|
-
// Codex, Claude Code, Cursor, Aider and others read it
|
|
85
|
+
// Leave instructions for the next agent. `AGENTS.md` is the cross-vendor convention (agents.md);
|
|
86
|
+
// Codex, Claude Code, Cursor, Aider and others read it, and increasingly the thing that runs
|
|
86
87
|
// `humanish init` is a coding agent doing setup on someone's behalf. Without this, the agent
|
|
87
88
|
// that arrives tomorrow finds a humanish/ directory and no idea what to do with it.
|
|
88
89
|
//
|
|
89
|
-
//
|
|
90
|
+
// Append-only and idempotent: an existing `AGENTS.md` is a file someone wrote, so humanish adds its
|
|
90
91
|
// own section once and never rewrites theirs.
|
|
91
92
|
async function planAgentsFile(preparedProjectRoot, cwd, plan) {
|
|
92
93
|
const agentsPath = "AGENTS.md";
|
|
@@ -136,10 +137,25 @@ async function planStarterFiles(preparedProjectRoot, cwd, files, localBrowserReq
|
|
|
136
137
|
const existing = await readTextIfExists(preparedProjectRoot, file.path);
|
|
137
138
|
if (existing !== null &&
|
|
138
139
|
localBrowserRequested &&
|
|
139
|
-
file.path === "humanish/
|
|
140
|
-
plan.warnings.push("Skipped --local-browser/--local-mission: humanish/
|
|
140
|
+
file.path === "humanish/studies/local-browser.yaml") {
|
|
141
|
+
plan.warnings.push("Skipped --local-browser/--local-mission: humanish/studies/local-browser.yaml already exists and init never overwrites it.");
|
|
141
142
|
}
|
|
142
|
-
|
|
143
|
+
const others = existing === null ? await otherStudyFilesFor(preparedProjectRoot, file.path) : [];
|
|
144
|
+
if (others.length > 0) {
|
|
145
|
+
const stem = studyFileStem(path.basename(file.path));
|
|
146
|
+
plan.changes.push({
|
|
147
|
+
path: file.path,
|
|
148
|
+
action: "skip",
|
|
149
|
+
target: file.plane,
|
|
150
|
+
reason: `${others.join(", ")} already uses the name ${stem}`,
|
|
151
|
+
});
|
|
152
|
+
// humanish no longer reads a labs/ file, but migrate needs its name free to move it.
|
|
153
|
+
const legacy = others.some((other) => other.split(path.sep).includes("labs"));
|
|
154
|
+
plan.warnings.push(legacy
|
|
155
|
+
? `Skipped ${file.path}: ${others.join(", ")} already uses the name ${stem}. Move it to a studies/ directory; humanish migrate converts and moves a v2 file.`
|
|
156
|
+
: `Skipped ${file.path}: ${others.join(", ")} already uses the name ${stem}, and a second file with that name would make \`run ${stem}\` fail.`);
|
|
157
|
+
}
|
|
158
|
+
else if (existing === null) {
|
|
143
159
|
plan.changes.push({
|
|
144
160
|
path: file.path,
|
|
145
161
|
action: "create",
|
|
@@ -172,6 +188,25 @@ async function planStarterFiles(preparedProjectRoot, cwd, files, localBrowserReq
|
|
|
172
188
|
}
|
|
173
189
|
}
|
|
174
190
|
}
|
|
191
|
+
/**
|
|
192
|
+
* The study files that already use a starter study's name in any study directory, other than the
|
|
193
|
+
* starter's own path. An unsafe path counts as present, so init skips the starter rather than
|
|
194
|
+
* failing.
|
|
195
|
+
*/
|
|
196
|
+
async function otherStudyFilesFor(preparedProjectRoot, relativePath) {
|
|
197
|
+
const stem = studyFileStem(path.basename(relativePath));
|
|
198
|
+
const inStudyDirectory = STUDY_DIRECTORIES.some((directory) => directory.relativeDir === path.dirname(relativePath));
|
|
199
|
+
if (stem === undefined || !inStudyDirectory)
|
|
200
|
+
return [];
|
|
201
|
+
return otherStudyFiles(stem, async (candidate) => {
|
|
202
|
+
try {
|
|
203
|
+
return (await readTextIfExists(preparedProjectRoot, candidate)) !== null;
|
|
204
|
+
}
|
|
205
|
+
catch {
|
|
206
|
+
return true;
|
|
207
|
+
}
|
|
208
|
+
}, relativePath);
|
|
209
|
+
}
|
|
175
210
|
/** Create each ignored runtime directory that is missing. */
|
|
176
211
|
async function planRuntimeDirectories(preparedProjectRoot, cwd, plan) {
|
|
177
212
|
for (const directory of runtimeDirectories) {
|
|
@@ -236,7 +271,7 @@ function validateLocalBrowserStarter(input) {
|
|
|
236
271
|
return { ok: true, value };
|
|
237
272
|
}
|
|
238
273
|
/**
|
|
239
|
-
* What this machine can run, for the starter
|
|
274
|
+
* What this machine can run, for the starter study and the next steps. Local CLI status is
|
|
240
275
|
* classified without returning its output or reading its credential file. Provider keys go
|
|
241
276
|
* through the same discovery chain as every other command (process env, the project overlay,
|
|
242
277
|
* `e2b auth login`, the `humanish keys set` store) and only their presence is read, never a value.
|
|
@@ -254,7 +289,7 @@ async function firstRunEnvironment(env, cwd) {
|
|
|
254
289
|
const present = (name) => keys.some((key) => key.name === name && key.source !== null);
|
|
255
290
|
let hasDesktopSdk = false;
|
|
256
291
|
try {
|
|
257
|
-
// Resolution from the
|
|
292
|
+
// Resolution starts from the project, wherever humanish itself is installed.
|
|
258
293
|
const { createRequire } = await import("node:module");
|
|
259
294
|
createRequire(path.join(process.cwd(), "package.json")).resolve("@e2b/desktop");
|
|
260
295
|
hasDesktopSdk = true;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** The first key in `raw` that V2_KEYS does not list, as an error message; undefined if none. */
|
|
2
|
+
export declare function findUnknownV2Key(raw: unknown): string | undefined;
|
|
3
|
+
/** The first key in a humanish.study.v3 document that the format does not have; undefined if none. */
|
|
4
|
+
export declare function findUnknownStudyKey(raw: unknown): string | undefined;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Every mapping key
|
|
1
|
+
// Every mapping key parseStudy reads, by path. A key that is not listed fails the study as
|
|
2
2
|
// unknown, so a typo stops the run instead of being dropped. `true` marks a leaf: its parser
|
|
3
3
|
// checks the value (scalars, lists, and mappings that check their own keys). Each level satisfies
|
|
4
4
|
// the parsed type's keys, so a field added to a Lab* interface must be added here too.
|
|
@@ -93,7 +93,10 @@ const ACTOR = {
|
|
|
93
93
|
count: true,
|
|
94
94
|
lanes: PARTICIPANT_ENTRY,
|
|
95
95
|
// Roster groups are participants with a count; the parser expands them into `lanes[]`.
|
|
96
|
-
roster: {
|
|
96
|
+
roster: {
|
|
97
|
+
...PARTICIPANT_ENTRY,
|
|
98
|
+
count: true,
|
|
99
|
+
},
|
|
97
100
|
persona: true,
|
|
98
101
|
mission: true,
|
|
99
102
|
model: true,
|
|
@@ -163,7 +166,7 @@ const EMAIL = {
|
|
|
163
166
|
allowedOrigins: true,
|
|
164
167
|
recipients: { lane: true, address: true },
|
|
165
168
|
};
|
|
166
|
-
const
|
|
169
|
+
const V2_KEYS = {
|
|
167
170
|
schema: true,
|
|
168
171
|
id: true,
|
|
169
172
|
title: true,
|
|
@@ -200,14 +203,45 @@ const LAB_KEYS = {
|
|
|
200
203
|
defaults: { open: true },
|
|
201
204
|
comms: { email: EMAIL },
|
|
202
205
|
};
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
+
function without(shape, ...keys) {
|
|
207
|
+
return Object.fromEntries(Object.entries(shape).filter(([key]) => !keys.includes(key)));
|
|
208
|
+
}
|
|
209
|
+
// humanish.study.v3. The route is declared, so `subject.topology` goes. The participant keys leave
|
|
210
|
+
// the actor for `participants`, and `caps` is one top-level block. Top-level `personas` and
|
|
211
|
+
// `scenario.inline` are read by no route, and `scenario` is a string.
|
|
212
|
+
const STUDY_KEYS = {
|
|
213
|
+
schema: true,
|
|
214
|
+
id: true,
|
|
215
|
+
title: true,
|
|
216
|
+
description: true,
|
|
217
|
+
route: true,
|
|
218
|
+
mode: true,
|
|
219
|
+
subject: without(SUBJECT, "topology"),
|
|
220
|
+
actor: without(ACTOR, "count", "lanes", "roster", "laneFocus"),
|
|
221
|
+
// A count, `{ count, instruction }` or a list of entries. studyToV2 checks which form the route
|
|
222
|
+
// takes; an entry with a count is a group.
|
|
223
|
+
participants: { ...PARTICIPANT_ENTRY, count: true },
|
|
224
|
+
surfaces: true,
|
|
225
|
+
caps: CAPS,
|
|
226
|
+
execution: without(EXECUTION, "caps"),
|
|
227
|
+
scenario: true,
|
|
228
|
+
policies: V2_KEYS.policies,
|
|
229
|
+
review: V2_KEYS.review,
|
|
230
|
+
defaults: V2_KEYS.defaults,
|
|
231
|
+
comms: V2_KEYS.comms,
|
|
232
|
+
};
|
|
233
|
+
/** The first key in `raw` that V2_KEYS does not list, as an error message; undefined if none. */
|
|
234
|
+
export function findUnknownV2Key(raw) {
|
|
235
|
+
return walk(raw, V2_KEYS, "", "study");
|
|
236
|
+
}
|
|
237
|
+
/** The first key in a humanish.study.v3 document that the format does not have; undefined if none. */
|
|
238
|
+
export function findUnknownStudyKey(raw) {
|
|
239
|
+
return walk(raw, STUDY_KEYS, "", "study");
|
|
206
240
|
}
|
|
207
|
-
function walk(value, shape, path) {
|
|
241
|
+
function walk(value, shape, path, noun) {
|
|
208
242
|
if (Array.isArray(value)) {
|
|
209
243
|
for (const [index, item] of value.entries()) {
|
|
210
|
-
const found = walk(item, shape, `${path}[${index}]
|
|
244
|
+
const found = walk(item, shape, `${path}[${index}]`, noun);
|
|
211
245
|
if (found)
|
|
212
246
|
return found;
|
|
213
247
|
}
|
|
@@ -220,23 +254,23 @@ function walk(value, shape, path) {
|
|
|
220
254
|
// Object.hasOwn: a key like `constructor` must not match Object.prototype.
|
|
221
255
|
const unknown = Object.keys(record).filter((key) => !Object.hasOwn(shape, key));
|
|
222
256
|
if (unknown.length > 0)
|
|
223
|
-
return unknownKeysMessage(path, unknown, known);
|
|
257
|
+
return unknownKeysMessage(path, unknown, known, noun);
|
|
224
258
|
for (const [key, child] of Object.entries(record)) {
|
|
225
259
|
const expected = shape[key];
|
|
226
260
|
if (expected !== true && expected !== undefined) {
|
|
227
|
-
const found = walk(child, expected, path ? `${path}.${key}` : key);
|
|
261
|
+
const found = walk(child, expected, path ? `${path}.${key}` : key, noun);
|
|
228
262
|
if (found)
|
|
229
263
|
return found;
|
|
230
264
|
}
|
|
231
265
|
}
|
|
232
266
|
return undefined;
|
|
233
267
|
}
|
|
234
|
-
function unknownKeysMessage(path, unknown, known) {
|
|
268
|
+
function unknownKeysMessage(path, unknown, known, noun) {
|
|
235
269
|
const named = unknown.map((key) => {
|
|
236
270
|
const suggestion = closest(key, known);
|
|
237
271
|
return suggestion ? `${key} (did you mean \`${suggestion}\`?)` : key;
|
|
238
272
|
});
|
|
239
|
-
return `Unknown
|
|
273
|
+
return `Unknown ${noun} ${unknown.length === 1 ? "field" : "fields"}${path ? ` in \`${path}\`` : ""}: ${named.join(", ")}. Known fields: ${known.join(", ")}.`;
|
|
240
274
|
}
|
|
241
275
|
// The known key within edit distance 2, or one that differs only in case.
|
|
242
276
|
function closest(key, known) {
|