humanish 0.107.0 → 0.108.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 +22 -17
- package/CHANGELOG.md +14 -0
- package/CONTEXT.md +51 -44
- package/README.md +145 -172
- 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-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 +8 -6
- 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 +2 -2
- package/dist/actors/codex/restricted-session.js +10 -5
- package/dist/actors/computer-use/actor.d.ts +16 -16
- package/dist/actors/computer-use/actor.js +2 -2
- package/dist/actors/computer-use/admission-limit.d.ts +1 -1
- package/dist/actors/computer-use/admission-limit.js +1 -1
- package/dist/actors/computer-use/loop/actions.d.ts +3 -3
- package/dist/actors/computer-use/loop/actions.js +10 -10
- 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/ending.d.ts +5 -5
- package/dist/actors/computer-use/loop/ending.js +7 -7
- package/dist/actors/computer-use/loop/observation.d.ts +2 -2
- package/dist/actors/computer-use/loop/observation.js +9 -9
- package/dist/actors/computer-use/loop/provider-call.d.ts +1 -1
- package/dist/actors/computer-use/loop/provider-call.js +1 -1
- package/dist/actors/computer-use/loop/session.js +3 -3
- 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 +9 -8
- package/dist/actors/computer-use/loop/types.d.ts +25 -23
- package/dist/actors/computer-use/loop/usage.js +2 -2
- 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 +11 -8
- package/dist/actors/computer-use/openai-provider.js +45 -34
- 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/contract.d.ts +78 -43
- package/dist/actors/contract.js +29 -23
- package/dist/actors/local-agent/claude-session.d.ts +1 -1
- package/dist/actors/local-agent/claude-session.js +10 -9
- package/dist/actors/local-agent/cli.d.ts +8 -6
- 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 +6 -6
- package/dist/actors/registry.d.ts +10 -10
- package/dist/actors/registry.js +18 -17
- package/dist/actors/scripted-browser/actor.d.ts +8 -8
- package/dist/actors/scripted-browser/actor.js +16 -16
- 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/codex-config.d.ts +6 -2
- package/dist/analysis/codex-config.js +22 -14
- package/dist/analysis/service.js +5 -5
- package/dist/cli/commands/analyze.js +19 -16
- package/dist/cli/commands/codex.js +9 -9
- package/dist/cli/commands/comms.js +54 -33
- package/dist/cli/commands/feedback.js +20 -21
- package/dist/cli/commands/lab-format.d.ts +5 -4
- package/dist/cli/commands/lab-format.js +35 -23
- package/dist/cli/commands/lab-route-computer-use.js +6 -7
- package/dist/cli/commands/lab-route-preview.js +4 -3
- package/dist/cli/commands/lab-route-shared-world.js +3 -3
- package/dist/cli/commands/lab-run.js +10 -11
- package/dist/cli/commands/lab-scorer.d.ts +2 -2
- package/dist/cli/commands/lab-scorer.js +1 -1
- package/dist/cli/commands/migrate.d.ts +4 -0
- package/dist/cli/commands/migrate.js +65 -0
- package/dist/cli/commands/observe.js +147 -108
- 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 +137 -138
- package/dist/cli/commands/setup.d.ts +2 -2
- package/dist/cli/commands/setup.js +26 -21
- package/dist/cli/commands/study.d.ts +3 -0
- package/dist/cli/commands/study.js +182 -0
- package/dist/cli/commands/tui.d.ts +4 -4
- package/dist/cli/commands/tui.js +21 -21
- package/dist/cli/commands/watch.js +60 -75
- package/dist/cli/deprecations.d.ts +18 -0
- package/dist/cli/deprecations.js +48 -0
- package/dist/cli/doctor.d.ts +15 -5
- package/dist/cli/doctor.js +103 -48
- package/dist/cli/first-run-path.d.ts +12 -10
- package/dist/cli/first-run-path.js +30 -28
- package/dist/cli/io.d.ts +41 -6
- package/dist/cli/io.js +97 -22
- package/dist/cli/observer-follow.d.ts +2 -2
- package/dist/cli/observer-follow.js +5 -6
- package/dist/cli/orientation.d.ts +6 -3
- package/dist/cli/orientation.js +43 -39
- 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 +109 -40
- package/dist/cli/telemetry.d.ts +15 -15
- package/dist/cli/telemetry.js +48 -40
- 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 +14 -14
- package/dist/comms/email-catch.d.ts +3 -3
- package/dist/comms/email-catch.js +8 -8
- package/dist/comms/external-evidence.js +2 -2
- package/dist/comms/extract.js +2 -2
- package/dist/comms/fake-inbox.d.ts +2 -2
- package/dist/comms/fake-inbox.js +2 -2
- package/dist/comms/receiving-render.d.ts +1 -1
- package/dist/comms/receiving-render.js +2 -2
- 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 +36 -37
- package/dist/comms/sandbox-catch.js +34 -35
- package/dist/comms/setup.js +42 -8
- 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 +36 -78
- package/dist/feedback/export-bundle.js +1 -1
- package/dist/feedback/export.d.ts +5 -1
- package/dist/feedback/export.js +7 -8
- package/dist/feedback/feedback.d.ts +2 -2
- package/dist/feedback/feedback.js +21 -3
- package/dist/guest/chromium-text.js +2 -2
- package/dist/guest/desktop-native.d.ts +1 -1
- package/dist/guest/runtime.js +1 -1
- package/dist/index.d.ts +12 -10
- package/dist/index.js +8 -6
- package/dist/keys/key-resolution.d.ts +5 -5
- package/dist/keys/key-resolution.js +23 -23
- package/dist/lab/adapter-extension.d.ts +7 -7
- package/dist/lab/adapter-extension.js +13 -36
- package/dist/lab/adapter-scorer-loader.d.ts +7 -7
- package/dist/lab/adapter-scorer-loader.js +32 -32
- package/dist/lab/composition-rules.js +42 -42
- package/dist/lab/config.js +65 -25
- package/dist/lab/deprecated-fields.d.ts +10 -0
- package/dist/lab/deprecated-fields.js +24 -0
- package/dist/lab/device-presets.d.ts +8 -8
- package/dist/lab/device-presets.js +11 -11
- package/dist/lab/discover.d.ts +13 -9
- package/dist/lab/discover.js +117 -57
- package/dist/lab/doctor.d.ts +10 -3
- package/dist/lab/doctor.js +47 -9
- package/dist/lab/init-templates.js +147 -147
- package/dist/lab/init.d.ts +1 -1
- package/dist/lab/init.js +41 -9
- package/dist/lab/keys.d.ts +2 -0
- package/dist/lab/keys.js +42 -8
- package/dist/lab/lab-deps.d.ts +7 -12
- package/dist/lab/parse/actors.js +9 -9
- package/dist/lab/parse/comms.js +5 -5
- package/dist/lab/parse/execution.js +13 -13
- package/dist/lab/parse/study-v3.d.ts +23 -0
- package/dist/lab/parse/study-v3.js +259 -0
- package/dist/lab/parse/subject-state.d.ts +7 -7
- package/dist/lab/parse/subject-state.js +16 -16
- package/dist/lab/parse/subject.js +28 -28
- package/dist/lab/parse/values.d.ts +1 -1
- package/dist/lab/parse/values.js +3 -3
- package/dist/lab/persona-resolve.d.ts +4 -4
- package/dist/lab/persona-resolve.js +4 -4
- package/dist/lab/plan-participants.d.ts +2 -2
- package/dist/lab/plan-types.d.ts +4 -4
- package/dist/lab/plan.d.ts +1 -7
- package/dist/lab/plan.js +10 -41
- package/dist/lab/preflight-probes.js +11 -11
- package/dist/lab/preflight-result.d.ts +2 -1
- package/dist/lab/preflight-result.js +5 -4
- package/dist/lab/preflight.d.ts +7 -5
- package/dist/lab/preflight.js +5 -5
- package/dist/lab/routing.d.ts +31 -25
- package/dist/lab/routing.js +60 -29
- package/dist/lab/run-lab-events.d.ts +0 -3
- package/dist/lab/run-lab-events.js +0 -6
- package/dist/lab/run-lab-homes.d.ts +22 -10
- package/dist/lab/run-lab-homes.js +5 -1
- package/dist/lab/run-lab-options.d.ts +1 -1
- package/dist/lab/run-lab-options.js +16 -13
- package/dist/lab/summary.d.ts +7 -6
- package/dist/lab/summary.js +10 -10
- package/dist/lab/tasks.d.ts +15 -15
- package/dist/lab/tasks.js +14 -14
- package/dist/lab/types.d.ts +101 -95
- package/dist/lab/types.js +2 -0
- package/dist/lab/validation.d.ts +13 -13
- package/dist/lab/validation.js +44 -42
- package/dist/lab/warnings.d.ts +10 -0
- package/dist/lab/warnings.js +61 -33
- package/dist/library-aliases.d.ts +56 -0
- package/dist/library-aliases.js +22 -0
- package/dist/observer/artifact.d.ts +1 -1
- package/dist/observer/artifact.js +6 -6
- 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 +1 -1
- package/dist/observer/library.js +4 -2
- package/dist/observer/listen.js +5 -4
- package/dist/observer/render.d.ts +1 -1
- package/dist/observer/render.js +10 -5
- package/dist/observer/run-routes.d.ts +3 -3
- package/dist/observer/run-routes.js +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 +15 -15
- package/dist/routes/computer-use/bundle.js +3 -3
- package/dist/routes/computer-use/e2b-desktop/comms.d.ts +1 -1
- package/dist/routes/computer-use/e2b-desktop/comms.js +14 -14
- package/dist/routes/computer-use/e2b-desktop/desktop.js +4 -4
- package/dist/routes/computer-use/e2b-desktop/fidelity.d.ts +4 -3
- package/dist/routes/computer-use/e2b-desktop/fidelity.js +11 -10
- package/dist/routes/computer-use/e2b-desktop/prepare.js +7 -7
- package/dist/routes/computer-use/e2b-desktop/start.js +9 -8
- package/dist/routes/computer-use/e2b-desktop/teardown.js +5 -4
- package/dist/routes/computer-use/external-comms.d.ts +1 -1
- package/dist/routes/computer-use/external-comms.js +1 -1
- package/dist/routes/computer-use/fanout-bundle.js +18 -18
- package/dist/routes/computer-use/fanout-records.js +10 -11
- package/dist/routes/computer-use/live-flush.d.ts +1 -1
- package/dist/routes/computer-use/live-flush.js +6 -6
- package/dist/routes/computer-use/live-phase.d.ts +4 -2
- package/dist/routes/computer-use/live-phase.js +6 -6
- package/dist/routes/computer-use/local-vm.js +1 -1
- package/dist/routes/computer-use/participant-desktop.d.ts +4 -4
- package/dist/routes/computer-use/participant-desktop.js +4 -4
- package/dist/routes/computer-use/participant-execution.d.ts +4 -4
- package/dist/routes/computer-use/participant-execution.js +9 -9
- package/dist/routes/computer-use/participant-model.d.ts +6 -0
- package/dist/routes/computer-use/participant-model.js +31 -13
- package/dist/routes/computer-use/participant-prompt.d.ts +11 -11
- package/dist/routes/computer-use/participant-prompt.js +6 -6
- package/dist/routes/computer-use/participant-runs.d.ts +7 -7
- package/dist/routes/computer-use/participant-runs.js +13 -13
- package/dist/routes/computer-use/plan.js +22 -22
- package/dist/routes/computer-use/preflight.js +21 -21
- package/dist/routes/computer-use/rerun-selection.js +1 -1
- package/dist/routes/computer-use/result.js +11 -11
- package/dist/routes/computer-use/route.d.ts +2 -1
- package/dist/routes/computer-use/route.js +15 -14
- package/dist/routes/computer-use/self-report.d.ts +7 -7
- package/dist/routes/computer-use/self-report.js +31 -31
- package/dist/routes/computer-use/setup.d.ts +1 -1
- package/dist/routes/computer-use/setup.js +17 -18
- package/dist/routes/computer-use/single-bundle.d.ts +7 -7
- package/dist/routes/computer-use/single-bundle.js +28 -30
- package/dist/routes/computer-use/subject-projection.d.ts +1 -1
- package/dist/routes/computer-use/subject-projection.js +6 -6
- package/dist/routes/computer-use/types.d.ts +40 -42
- package/dist/routes/computer-use/types.js +10 -10
- package/dist/routes/preview.d.ts +8 -2
- package/dist/routes/preview.js +8 -4
- package/dist/routes/scripted/bundle.d.ts +2 -2
- package/dist/routes/scripted/bundle.js +13 -12
- package/dist/routes/scripted/plan.d.ts +1 -1
- package/dist/routes/scripted/plan.js +9 -9
- package/dist/routes/scripted/result.js +5 -5
- package/dist/routes/scripted/route.js +5 -6
- package/dist/routes/scripted/scenario.js +2 -2
- package/dist/routes/scripted/setup.js +7 -7
- package/dist/routes/scripted/subject.js +1 -1
- package/dist/routes/scripted/surface-records.js +3 -3
- package/dist/routes/scripted/types.d.ts +3 -5
- package/dist/routes/scripted/types.js +1 -1
- package/dist/routes/shared-world/bundle-records.js +9 -8
- package/dist/routes/shared-world/bundle.d.ts +5 -5
- package/dist/routes/shared-world/bundle.js +40 -38
- package/dist/routes/shared-world/checkpoints.d.ts +1 -1
- package/dist/routes/shared-world/checkpoints.js +1 -1
- package/dist/routes/shared-world/comms.d.ts +5 -5
- package/dist/routes/shared-world/comms.js +14 -14
- 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 +7 -6
- package/dist/routes/shared-world/participant-specs.js +31 -24
- package/dist/routes/shared-world/plan.js +7 -7
- 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.js +14 -13
- package/dist/routes/shared-world/result.js +20 -21
- package/dist/routes/shared-world/route.js +23 -22
- package/dist/routes/shared-world/setup.d.ts +3 -3
- package/dist/routes/shared-world/setup.js +4 -4
- package/dist/routes/shared-world/types.d.ts +30 -28
- package/dist/routes/shared-world/types.js +4 -4
- package/dist/routes/terminal/adapter.d.ts +3 -3
- package/dist/routes/terminal/adapter.js +5 -5
- package/dist/routes/terminal/bundle.d.ts +3 -3
- package/dist/routes/terminal/bundle.js +22 -21
- package/dist/routes/terminal/credentials.d.ts +4 -4
- package/dist/routes/terminal/credentials.js +7 -7
- package/dist/routes/terminal/dry-run.js +4 -4
- package/dist/routes/terminal/encoding.js +2 -2
- package/dist/routes/terminal/ledger.d.ts +3 -3
- package/dist/routes/terminal/ledger.js +14 -14
- package/dist/routes/terminal/live-finish.js +3 -3
- package/dist/routes/terminal/live-sandbox.js +12 -13
- package/dist/routes/terminal/persona.js +1 -1
- package/dist/routes/terminal/plan.js +11 -11
- package/dist/routes/terminal/recorder.js +2 -2
- package/dist/routes/terminal/result.js +8 -8
- package/dist/routes/terminal/route.js +6 -7
- package/dist/routes/terminal/sandbox.d.ts +1 -1
- package/dist/routes/terminal/sandbox.js +1 -1
- package/dist/routes/terminal/session.js +8 -7
- 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 +2 -2
- package/dist/routes/terminal/trace.js +2 -2
- package/dist/routes/terminal/types.d.ts +26 -28
- package/dist/routes/terminal/types.js +3 -3
- package/dist/run/bundle-shape.js +3 -3
- package/dist/run/bundle.d.ts +46 -46
- package/dist/run/bundle.js +2 -1
- package/dist/run/cost-summary.js +3 -3
- package/dist/run/costs.js +7 -1
- package/dist/run/detail.d.ts +6 -6
- package/dist/run/detail.js +4 -4
- package/dist/run/dry-run-inputs.js +1 -1
- package/dist/run/dry-run.js +18 -18
- package/dist/run/judge.d.ts +19 -13
- package/dist/run/judge.js +18 -8
- package/dist/run/paths.d.ts +1 -1
- package/dist/run/paths.js +1 -1
- package/dist/run/pricing.d.ts +11 -6
- package/dist/run/pricing.js +20 -13
- package/dist/run/projection.d.ts +14 -14
- package/dist/run/projection.js +15 -15
- package/dist/run/reclaim.js +2 -2
- package/dist/run/results.d.ts +5 -5
- package/dist/run/run-index.d.ts +8 -6
- package/dist/run/run-index.js +15 -16
- 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 +5 -4
- package/dist/run/run.js +1 -1
- 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 +36 -35
- 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 +6 -6
- package/dist/run/stats.d.ts +12 -6
- package/dist/run/stats.js +116 -58
- package/dist/run/status.d.ts +8 -29
- package/dist/run/status.js +5 -27
- package/dist/run/stored-runs.js +2 -1
- package/dist/run/stream-shape.js +1 -1
- package/dist/run/streams.d.ts +6 -6
- package/dist/run/study-provenance.d.ts +47 -0
- package/dist/run/study-provenance.js +63 -0
- package/dist/run/study-result.d.ts +16 -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-lab.d.ts +7 -7
- package/dist/run-lab.js +1 -3
- package/dist/study/convert.d.ts +33 -0
- package/dist/study/convert.js +432 -0
- 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 +43 -0
- 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/subject/clone.d.ts +1 -1
- package/dist/subject/desktop-cli.d.ts +1 -1
- package/dist/subject/desktop-cli.js +2 -2
- package/dist/subject/local-tree-archive.js +1 -1
- package/dist/subject/local-tree.d.ts +1 -1
- package/dist/subject/node-bootstrap.js +1 -1
- package/dist/subject/runtime.js +8 -9
- package/dist/subject/serve.d.ts +1 -1
- package/dist/subject/serve.js +3 -3
- package/dist/subject/state.d.ts +1 -1
- package/dist/subject/steps.d.ts +5 -5
- package/dist/subject/steps.js +4 -4
- package/dist/substrates/command-failure.d.ts +3 -3
- package/dist/substrates/command-failure.js +3 -3
- 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 +2 -2
- package/dist/substrates/e2b/desktop-browser.js +8 -8
- package/dist/substrates/e2b/desktop-cdp.d.ts +9 -9
- package/dist/substrates/e2b/desktop-cdp.js +8 -8
- package/dist/substrates/e2b/desktop-executor.d.ts +1 -1
- package/dist/substrates/e2b/desktop-executor.js +1 -1
- package/dist/substrates/e2b/desktop-geometry.d.ts +3 -3
- package/dist/substrates/e2b/desktop-geometry.js +7 -7
- package/dist/substrates/e2b/desktop-media.d.ts +1 -1
- 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/sandbox.d.ts +1 -1
- package/dist/substrates/e2b/sandbox.js +1 -1
- package/dist/substrates/e2b/sdk.d.ts +11 -11
- package/dist/substrates/e2b/sdk.js +6 -6
- package/dist/tui/actions.d.ts +1 -1
- package/dist/tui/actions.js +13 -13
- package/dist/tui/contract.d.ts +16 -16
- package/dist/tui/contract.js +10 -10
- package/dist/tui/launch.d.ts +4 -4
- package/dist/tui/launch.js +18 -19
- package/dist/tui/project.js +5 -5
- package/dist/tui-app.js +82 -82
- 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 +4 -4
- package/dist/verify/subject.js +18 -18
- package/dist/verify/verify.js +92 -43
- package/docs/README.md +25 -32
- package/docs/architecture/actor-contract.md +56 -87
- package/docs/architecture/desktop-sessions.md +7 -7
- package/docs/architecture/external-public-shared-world.md +61 -59
- package/docs/architecture/github-feedback-loop.md +1 -4
- 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 +5 -5
- package/docs/architecture/terminal-product-route.md +67 -107
- package/docs/contracts/README.md +24 -0
- package/docs/contracts/adapter-admission.md +3 -3
- package/docs/contracts/adapter-fixtures.md +2 -5
- 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 +45 -44
- package/docs/contracts/schemas.md +421 -362
- package/docs/contracts/study-analysis.md +3 -3
- package/docs/contracts/study-costs.md +11 -7
- 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/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/package.json +16 -17
- package/skills/humanish/SKILL.md +60 -58
- 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.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/observer/static.d.ts +0 -39
- package/dist/observer/static.js +0 -369
- 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/discover.js
CHANGED
|
@@ -5,16 +5,12 @@ import { lstat, open, readdir, realpath } from "node:fs/promises";
|
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import { parse } from "yaml";
|
|
7
7
|
import { parseLabConfig } from "./config.js";
|
|
8
|
-
import {} from "./types.js";
|
|
8
|
+
import { STUDY_SCHEMA } from "./types.js";
|
|
9
9
|
import { assertPreparedSelectedOutputDirectory, assertSafeOutputPathSegment, prepareSelectedOutputDirectory, readContainedRegularFile, } from "../run/contained-output.js";
|
|
10
10
|
import { isNodeError } from "../run/type-guards.js";
|
|
11
|
-
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const ignoredLabsDirs = [
|
|
15
|
-
path.join(".humanish", "labs"),
|
|
16
|
-
path.join(".humanish", "local", "labs"),
|
|
17
|
-
];
|
|
11
|
+
import { studyFileCandidates, studyFileStem, STUDY_DIRECTORIES } from "../study/files.js";
|
|
12
|
+
const STUDY_LIST_SCHEMA = "humanish.study-list.v1";
|
|
13
|
+
const STUDY_SHOW_SCHEMA = "humanish.study-show.v1";
|
|
18
14
|
export async function resolveLabManifest(cwd, lab) {
|
|
19
15
|
const resolvedCwd = path.resolve(cwd);
|
|
20
16
|
const warnings = [];
|
|
@@ -40,16 +36,10 @@ export async function resolveLabManifest(cwd, lab) {
|
|
|
40
36
|
contents: read.contents,
|
|
41
37
|
});
|
|
42
38
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
...ignoredLabsDirs.flatMap((dir) => [
|
|
47
|
-
{ origin: "ignored", relativePath: path.join(dir, `${lab}.yaml`) },
|
|
48
|
-
{ origin: "ignored", relativePath: path.join(dir, `${lab}.yml`) },
|
|
49
|
-
]),
|
|
50
|
-
];
|
|
39
|
+
// A studies/ file wins over every labs/ file. The same stem under both families is an error, so
|
|
40
|
+
// neither file silently shadows the other.
|
|
41
|
+
const candidates = studyFileCandidates(lab);
|
|
51
42
|
for (const candidate of candidates) {
|
|
52
|
-
const requestedPath = path.join(resolvedCwd, candidate.relativePath);
|
|
53
43
|
const read = await readManagedManifest(projectRoot, candidate.relativePath);
|
|
54
44
|
if (read.status === "missing") {
|
|
55
45
|
continue;
|
|
@@ -57,11 +47,18 @@ export async function resolveLabManifest(cwd, lab) {
|
|
|
57
47
|
if (read.status === "unsafe") {
|
|
58
48
|
return invalidLab({ cwd: resolvedCwd, lab, warnings }, read.message);
|
|
59
49
|
}
|
|
50
|
+
if (candidate.directory.family === "studies") {
|
|
51
|
+
for (const other of candidates.filter((entry) => entry.directory.family === "labs")) {
|
|
52
|
+
const present = await inspectManagedPath(projectRoot, other.relativePath, "file");
|
|
53
|
+
if (present.status !== "missing")
|
|
54
|
+
return ambiguousStudy(resolvedCwd, lab, [candidate.relativePath, other.relativePath], warnings);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
60
57
|
return parseResolvedLab({
|
|
61
58
|
cwd: resolvedCwd,
|
|
62
59
|
lab,
|
|
63
|
-
origin: candidate.origin,
|
|
64
|
-
path:
|
|
60
|
+
origin: candidate.directory.origin,
|
|
61
|
+
path: path.join(resolvedCwd, candidate.relativePath),
|
|
65
62
|
warnings,
|
|
66
63
|
contents: read.contents,
|
|
67
64
|
});
|
|
@@ -71,22 +68,21 @@ export async function resolveLabManifest(cwd, lab) {
|
|
|
71
68
|
export async function listLabManifests(cwd) {
|
|
72
69
|
const resolvedCwd = path.resolve(cwd);
|
|
73
70
|
const warnings = [];
|
|
74
|
-
const
|
|
71
|
+
const listed = new Map();
|
|
75
72
|
const projectRoot = await bindProjectRoot(resolvedCwd);
|
|
76
73
|
if (!projectRoot) {
|
|
77
74
|
return {
|
|
78
|
-
schema:
|
|
75
|
+
schema: STUDY_LIST_SCHEMA,
|
|
79
76
|
ok: true,
|
|
80
77
|
cwd: resolvedCwd,
|
|
81
|
-
|
|
82
|
-
warnings: ["Project root failed containment validation;
|
|
78
|
+
studies: [],
|
|
79
|
+
warnings: ["Project root failed containment validation; study files were skipped."],
|
|
83
80
|
};
|
|
84
81
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
for (const entry of dirs) {
|
|
82
|
+
let legacyFiles = 0;
|
|
83
|
+
// Each stem's files by directory family, to mark the stems that name a file in both.
|
|
84
|
+
const stems = new Map();
|
|
85
|
+
for (const entry of STUDY_DIRECTORIES) {
|
|
90
86
|
const directory = await bindManagedDirectory(projectRoot, entry.relativeDir);
|
|
91
87
|
if (directory.status === "missing") {
|
|
92
88
|
continue;
|
|
@@ -107,13 +103,15 @@ export async function listLabManifests(cwd) {
|
|
|
107
103
|
for (const name of names.filter((value) => value.endsWith(".yaml") || value.endsWith(".yml"))) {
|
|
108
104
|
let relativePath;
|
|
109
105
|
try {
|
|
110
|
-
assertSafeOutputPathSegment(name, "
|
|
106
|
+
assertSafeOutputPathSegment(name, "Study file name");
|
|
111
107
|
relativePath = path.join(entry.relativeDir, name);
|
|
112
108
|
}
|
|
113
109
|
catch {
|
|
114
|
-
warnings.push(`${entry.relativeDir}: unsafe
|
|
110
|
+
warnings.push(`${entry.relativeDir}: unsafe study file name; skipped.`);
|
|
115
111
|
continue;
|
|
116
112
|
}
|
|
113
|
+
const stem = stemSlot(stems, studyFileStem(name) ?? name);
|
|
114
|
+
stem[entry.family === "studies" ? "studies" : "legacy"] ??= relativeToCwd(resolvedCwd, path.join(resolvedCwd, relativePath));
|
|
117
115
|
const requestedPath = path.join(resolvedCwd, relativePath);
|
|
118
116
|
const read = await readManagedManifest(projectRoot, relativePath);
|
|
119
117
|
if (read.status !== "ok") {
|
|
@@ -132,8 +130,11 @@ export async function listLabManifests(cwd) {
|
|
|
132
130
|
warnings.push(`${relativeToCwd(resolvedCwd, requestedPath)}: ${parsed.error.message}`);
|
|
133
131
|
continue;
|
|
134
132
|
}
|
|
133
|
+
if (legacyStudyWarning(parsed.path, parsed.config.schema) !== undefined)
|
|
134
|
+
legacyFiles += 1;
|
|
135
135
|
const key = `${parsed.config.id}:${entry.origin}:${relativeToCwd(resolvedCwd, requestedPath)}`;
|
|
136
|
-
|
|
136
|
+
stem.keys.push(key);
|
|
137
|
+
listed.set(key, {
|
|
137
138
|
id: parsed.config.id,
|
|
138
139
|
source: parsed.config.subject.source,
|
|
139
140
|
origin: entry.origin,
|
|
@@ -146,11 +147,24 @@ export async function listLabManifests(cwd) {
|
|
|
146
147
|
});
|
|
147
148
|
}
|
|
148
149
|
}
|
|
150
|
+
if (legacyFiles > 0) {
|
|
151
|
+
warnings.push(`${legacyFiles === 1 ? "One study file uses" : `${legacyFiles} study files use`} humanish.lab.v2 or a labs/ directory, which 0.109 stops reading. humanish migrate converts and moves the v2 files; humanish study show names the fix for each file.`);
|
|
152
|
+
}
|
|
153
|
+
for (const [name, stem] of stems) {
|
|
154
|
+
if (stem.studies === undefined || stem.legacy === undefined)
|
|
155
|
+
continue;
|
|
156
|
+
const error = `${name} names two files, ${stem.studies} and ${stem.legacy}; running it by name fails until you delete one (humanish migrate moves a kept labs/ file).`;
|
|
157
|
+
for (const key of stem.keys) {
|
|
158
|
+
const entry = listed.get(key);
|
|
159
|
+
if (entry)
|
|
160
|
+
entry.error = error;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
149
163
|
return {
|
|
150
|
-
schema:
|
|
164
|
+
schema: STUDY_LIST_SCHEMA,
|
|
151
165
|
ok: true,
|
|
152
166
|
cwd: resolvedCwd,
|
|
153
|
-
|
|
167
|
+
studies: [...listed.values()].sort((left, right) => `${left.origin}:${left.id}`.localeCompare(`${right.origin}:${right.id}`)),
|
|
154
168
|
warnings,
|
|
155
169
|
};
|
|
156
170
|
}
|
|
@@ -158,10 +172,10 @@ export async function inspectLabManifest(cwd, lab) {
|
|
|
158
172
|
const resolved = await resolveLabManifest(cwd, lab);
|
|
159
173
|
if (!resolved.ok) {
|
|
160
174
|
return {
|
|
161
|
-
schema:
|
|
175
|
+
schema: STUDY_SHOW_SCHEMA,
|
|
162
176
|
ok: false,
|
|
163
177
|
cwd: resolved.cwd,
|
|
164
|
-
lab,
|
|
178
|
+
study: lab,
|
|
165
179
|
error: resolved.error,
|
|
166
180
|
warnings: resolved.warnings,
|
|
167
181
|
};
|
|
@@ -174,23 +188,23 @@ export async function inspectLabManifest(cwd, lab) {
|
|
|
174
188
|
if (!(error instanceof PersonaConfigError))
|
|
175
189
|
throw error;
|
|
176
190
|
return {
|
|
177
|
-
schema:
|
|
191
|
+
schema: STUDY_SHOW_SCHEMA,
|
|
178
192
|
ok: false,
|
|
179
193
|
cwd: path.resolve(cwd),
|
|
180
|
-
lab,
|
|
181
|
-
error: { code: "
|
|
194
|
+
study: lab,
|
|
195
|
+
error: { code: "HUMANISH_STUDY_INVALID", message: error.message },
|
|
182
196
|
warnings: resolved.warnings,
|
|
183
197
|
};
|
|
184
198
|
}
|
|
185
199
|
return {
|
|
186
|
-
schema:
|
|
200
|
+
schema: STUDY_SHOW_SCHEMA,
|
|
187
201
|
personas: labPersonaIds(resolved.config).map((id) => {
|
|
188
202
|
const persona = personaResolution.personas.get(id);
|
|
189
203
|
return { id, resolved: !!persona, ...(persona ? { brief: personaBrief(persona) } : {}) };
|
|
190
204
|
}),
|
|
191
205
|
ok: true,
|
|
192
206
|
cwd: path.resolve(cwd),
|
|
193
|
-
lab,
|
|
207
|
+
study: lab,
|
|
194
208
|
config: resolved.config,
|
|
195
209
|
origin: resolved.origin,
|
|
196
210
|
path: resolved.path,
|
|
@@ -203,13 +217,16 @@ function parseResolvedLab(args) {
|
|
|
203
217
|
raw = parse(args.contents);
|
|
204
218
|
}
|
|
205
219
|
catch (error) {
|
|
206
|
-
return invalidLab(args, error instanceof Error ? error.message : "
|
|
220
|
+
return invalidLab(args, error instanceof Error ? error.message : "The study file's YAML could not be parsed.");
|
|
207
221
|
}
|
|
208
222
|
const parsed = parseLabConfig(raw);
|
|
209
223
|
if (!parsed.ok) {
|
|
210
224
|
return invalidLab(args, parsed.error.message);
|
|
211
225
|
}
|
|
212
226
|
const warnings = [...args.warnings, ...parsed.warnings];
|
|
227
|
+
const legacy = legacyStudyWarning(relativeToCwd(args.cwd, args.path), parsed.config.schema);
|
|
228
|
+
if (legacy !== undefined)
|
|
229
|
+
warnings.push(legacy);
|
|
213
230
|
if (args.path.endsWith(".yml")) {
|
|
214
231
|
warnings.push("Prefer .yaml for humanish-authored lab source; .yml is accepted for compatibility only.");
|
|
215
232
|
}
|
|
@@ -221,6 +238,24 @@ function parseResolvedLab(args) {
|
|
|
221
238
|
warnings,
|
|
222
239
|
};
|
|
223
240
|
}
|
|
241
|
+
/**
|
|
242
|
+
* What 0.109 stops reading in this file: the humanish.lab.v2 format, a labs/ directory, or both, and
|
|
243
|
+
* what to run about it. Undefined for a v3 file outside the labs/ directories.
|
|
244
|
+
*/
|
|
245
|
+
function legacyStudyWarning(relativePath, schema) {
|
|
246
|
+
const retiredDirectory = STUDY_DIRECTORIES.find((directory) => directory.family === "labs" && path.dirname(relativePath) === directory.relativeDir);
|
|
247
|
+
// A file discovery parsed has one of two schemas, so not v3 is v2.
|
|
248
|
+
const v2 = schema !== STUDY_SCHEMA;
|
|
249
|
+
if (retiredDirectory !== undefined) {
|
|
250
|
+
const studies = retiredDirectory.relativeDir.replace(/labs$/, "studies");
|
|
251
|
+
return v2
|
|
252
|
+
? `${relativePath} is a humanish.lab.v2 file in ${retiredDirectory.relativeDir}/, and 0.109 reads neither. Run humanish migrate to convert it and move it to ${studies}/.`
|
|
253
|
+
: `${relativePath} is in ${retiredDirectory.relativeDir}/, which 0.109 stops reading. Move it to ${studies}/.`;
|
|
254
|
+
}
|
|
255
|
+
return v2
|
|
256
|
+
? `${relativePath} is a humanish.lab.v2 file, which 0.109 stops reading. Run humanish migrate ${relativePath} to convert it.`
|
|
257
|
+
: undefined;
|
|
258
|
+
}
|
|
224
259
|
async function bindProjectRoot(cwd) {
|
|
225
260
|
try {
|
|
226
261
|
const lexical = await lstat(cwd);
|
|
@@ -242,7 +277,7 @@ async function readManagedManifest(projectRoot, relativePath) {
|
|
|
242
277
|
if (!contents) {
|
|
243
278
|
return {
|
|
244
279
|
status: "unsafe",
|
|
245
|
-
message: "
|
|
280
|
+
message: "The study file changed or failed containment validation.",
|
|
246
281
|
};
|
|
247
282
|
}
|
|
248
283
|
return { status: "ok", contents: contents.toString("utf8") };
|
|
@@ -264,7 +299,7 @@ async function readExplicitManifest(projectRoot, requestedPath) {
|
|
|
264
299
|
if (!before.isFile() || before.isSymbolicLink() || before.nlink !== 1n) {
|
|
265
300
|
return {
|
|
266
301
|
status: "unsafe",
|
|
267
|
-
message: "
|
|
302
|
+
message: "The study file path must resolve to a single-link regular file.",
|
|
268
303
|
};
|
|
269
304
|
}
|
|
270
305
|
const handle = await open(physicalPath, constants.O_RDONLY | constants.O_NOFOLLOW);
|
|
@@ -276,7 +311,7 @@ async function readExplicitManifest(projectRoot, requestedPath) {
|
|
|
276
311
|
opened.ino !== before.ino) {
|
|
277
312
|
return {
|
|
278
313
|
status: "unsafe",
|
|
279
|
-
message: "
|
|
314
|
+
message: "The study file changed before it could be read safely.",
|
|
280
315
|
};
|
|
281
316
|
}
|
|
282
317
|
const contents = await handle.readFile();
|
|
@@ -293,7 +328,7 @@ async function readExplicitManifest(projectRoot, requestedPath) {
|
|
|
293
328
|
after.ino !== before.ino) {
|
|
294
329
|
return {
|
|
295
330
|
status: "unsafe",
|
|
296
|
-
message: "
|
|
331
|
+
message: "The study file changed while it was being read.",
|
|
297
332
|
};
|
|
298
333
|
}
|
|
299
334
|
return { status: "ok", contents: contents.toString("utf8") };
|
|
@@ -303,7 +338,7 @@ async function readExplicitManifest(projectRoot, requestedPath) {
|
|
|
303
338
|
}
|
|
304
339
|
}
|
|
305
340
|
catch {
|
|
306
|
-
return { status: "unsafe", message: "
|
|
341
|
+
return { status: "unsafe", message: "The study file path failed containment validation." };
|
|
307
342
|
}
|
|
308
343
|
}
|
|
309
344
|
async function bindManagedDirectory(projectRoot, relativePath) {
|
|
@@ -327,7 +362,7 @@ async function inspectManagedPath(projectRoot, relativePath, expectedKind) {
|
|
|
327
362
|
const segments = relativePath.replace(/\\/g, "/").split("/");
|
|
328
363
|
let current = projectRoot.physicalPath;
|
|
329
364
|
for (const [index, segment] of segments.entries()) {
|
|
330
|
-
assertSafeOutputPathSegment(segment, "
|
|
365
|
+
assertSafeOutputPathSegment(segment, "Study file path segment");
|
|
331
366
|
current = path.join(current, segment);
|
|
332
367
|
let stats;
|
|
333
368
|
try {
|
|
@@ -341,18 +376,21 @@ async function inspectManagedPath(projectRoot, relativePath, expectedKind) {
|
|
|
341
376
|
}
|
|
342
377
|
const leaf = index === segments.length - 1;
|
|
343
378
|
if (stats.isSymbolicLink()) {
|
|
344
|
-
return {
|
|
379
|
+
return {
|
|
380
|
+
status: "unsafe",
|
|
381
|
+
message: "Study directory paths must not contain symbolic links.",
|
|
382
|
+
};
|
|
345
383
|
}
|
|
346
384
|
if (!leaf && !stats.isDirectory()) {
|
|
347
|
-
return { status: "unsafe", message: "
|
|
385
|
+
return { status: "unsafe", message: "Study file path parents must be directories." };
|
|
348
386
|
}
|
|
349
387
|
if (leaf && expectedKind === "directory" && !stats.isDirectory()) {
|
|
350
|
-
return { status: "unsafe", message: "
|
|
388
|
+
return { status: "unsafe", message: "A study directory has an unsafe file type." };
|
|
351
389
|
}
|
|
352
390
|
if (leaf && expectedKind === "file" && (!stats.isFile() || stats.nlink !== 1n)) {
|
|
353
391
|
return {
|
|
354
392
|
status: "unsafe",
|
|
355
|
-
message: "
|
|
393
|
+
message: "A study file must be a single-link regular file.",
|
|
356
394
|
};
|
|
357
395
|
}
|
|
358
396
|
if (leaf) {
|
|
@@ -368,7 +406,7 @@ async function inspectManagedPath(projectRoot, relativePath, expectedKind) {
|
|
|
368
406
|
}
|
|
369
407
|
}
|
|
370
408
|
catch {
|
|
371
|
-
return { status: "unsafe", message: "
|
|
409
|
+
return { status: "unsafe", message: "A study file path failed containment validation." };
|
|
372
410
|
}
|
|
373
411
|
return { status: "missing" };
|
|
374
412
|
}
|
|
@@ -387,22 +425,44 @@ function invalidLab(args, message) {
|
|
|
387
425
|
return {
|
|
388
426
|
ok: false,
|
|
389
427
|
cwd: args.cwd,
|
|
390
|
-
|
|
428
|
+
study: args.lab,
|
|
391
429
|
error: {
|
|
392
|
-
code: "
|
|
430
|
+
code: "HUMANISH_STUDY_INVALID",
|
|
393
431
|
message,
|
|
394
432
|
},
|
|
395
433
|
warnings: args.warnings,
|
|
396
434
|
};
|
|
397
435
|
}
|
|
436
|
+
function stemSlot(stems, name) {
|
|
437
|
+
let slot = stems.get(name);
|
|
438
|
+
if (slot === undefined) {
|
|
439
|
+
slot = { keys: [] };
|
|
440
|
+
stems.set(name, slot);
|
|
441
|
+
}
|
|
442
|
+
return slot;
|
|
443
|
+
}
|
|
444
|
+
/** The same stem under a studies/ and a labs/ directory: discovery reads neither. */
|
|
445
|
+
function ambiguousStudy(cwd, name, paths, warnings) {
|
|
446
|
+
const [studiesPath, labsPath] = paths.map((entry) => entry.replace(/\\/g, "/"));
|
|
447
|
+
return {
|
|
448
|
+
ok: false,
|
|
449
|
+
cwd,
|
|
450
|
+
study: name,
|
|
451
|
+
error: {
|
|
452
|
+
code: "HUMANISH_STUDY_AMBIGUOUS",
|
|
453
|
+
message: `${name} names two files, ${studiesPath} and ${labsPath}. Delete the one you do not want; if you keep ${labsPath}, run humanish migrate to move it. Or pass the path of the one to run.`,
|
|
454
|
+
},
|
|
455
|
+
warnings,
|
|
456
|
+
};
|
|
457
|
+
}
|
|
398
458
|
function labNotFound(cwd, lab, warnings) {
|
|
399
459
|
return {
|
|
400
460
|
ok: false,
|
|
401
461
|
cwd,
|
|
402
|
-
lab,
|
|
462
|
+
study: lab,
|
|
403
463
|
error: {
|
|
404
|
-
code: "
|
|
405
|
-
message: `
|
|
464
|
+
code: "HUMANISH_STUDY_NOT_FOUND",
|
|
465
|
+
message: `Study not found: ${lab}. Look in humanish/studies/ or humanish/labs/, or pass a .yaml path.`,
|
|
406
466
|
},
|
|
407
467
|
warnings,
|
|
408
468
|
};
|
package/dist/lab/doctor.d.ts
CHANGED
|
@@ -3,10 +3,10 @@ import type { LabConfig } from "./types.js";
|
|
|
3
3
|
import type { PlanResult } from "./plan-types.js";
|
|
4
4
|
import type { DetectedLocalAgent } from "../actors/local-agent/cli.js";
|
|
5
5
|
import type { ReasoningEffort } from "../actors/reasoning-effort.js";
|
|
6
|
-
import type {
|
|
7
|
-
import { type CodexInstallation } from "../actors/codex/
|
|
6
|
+
import type { DoctorCheckDraft } from "../cli/doctor.js";
|
|
7
|
+
import { type CodexInstallation } from "../actors/codex/codex-admission.js";
|
|
8
8
|
import type { RefusedCodexExecutable } from "../actors/codex/restricted-executable.js";
|
|
9
|
-
type Check =
|
|
9
|
+
type Check = DoctorCheckDraft;
|
|
10
10
|
/**
|
|
11
11
|
* Read-only Codex account readiness. An unadmitted CLI also reports the release it found, and an
|
|
12
12
|
* unavailable one the file humanish found and turned down.
|
|
@@ -66,6 +66,13 @@ export declare function labSetupChecks(args: LabSetupCheckArgs): Promise<{
|
|
|
66
66
|
reads?: ReadonlySet<string>;
|
|
67
67
|
checks: Check[];
|
|
68
68
|
}>;
|
|
69
|
+
/**
|
|
70
|
+
* The ids of the project's labs that need each provider key for a live run, from the same plan
|
|
71
|
+
* `doctor --lab` reads. Each listed manifest resolves by its path, since a file name need not match
|
|
72
|
+
* the id inside. A lab that runs dry, that the plain CLI cannot run, or that does not plan needs
|
|
73
|
+
* none.
|
|
74
|
+
*/
|
|
75
|
+
export declare function studiesByRequiredKey(cwd: string, keyPresent: (name: string) => boolean): Promise<Map<string, string[]>>;
|
|
69
76
|
/**
|
|
70
77
|
* The lab planned with no run options, so its own scenario mode decides dry or live. Doctor and the
|
|
71
78
|
* TUI read a live run's keys and subject env from this plan's requirements.
|
package/dist/lab/doctor.js
CHANGED
|
@@ -6,7 +6,7 @@ import { protocolAdditionsWarning, protocolIncompatibilityMessage, } from "../ac
|
|
|
6
6
|
import { automaticAnalysisBudget } from "../analysis/automatic-config.js";
|
|
7
7
|
import { externalCatchHealthy } from "../comms/sandbox-catch.js";
|
|
8
8
|
import { receivingRequiredKey } from "../comms/setup.js";
|
|
9
|
-
import { classifyCodexInstallation, codexInstallAdvice, codexVersionRecovery, } from "../actors/codex/
|
|
9
|
+
import { classifyCodexInstallation, codexInstallAdvice, codexVersionRecovery, } from "../actors/codex/codex-admission.js";
|
|
10
10
|
/** A ready row's message, with the schema values the launch recorded. */
|
|
11
11
|
function readyMessage(message, readiness) {
|
|
12
12
|
const additions = protocolAdditionsWarning(readiness.cliVersion, readiness.protocolAdditions);
|
|
@@ -110,10 +110,24 @@ export async function localCodexParticipantCheck(args) {
|
|
|
110
110
|
name: "local participant authentication",
|
|
111
111
|
ok: readiness.ready,
|
|
112
112
|
message: readiness.ready
|
|
113
|
-
? readyMessage("
|
|
113
|
+
? readyMessage("Codex CLI and ChatGPT login are ready for restricted local browser participants. No E2B or model API key is required; inference is remote, and model access and account quota remain untested.", readiness)
|
|
114
114
|
: `Local Codex participant setup is unavailable (${readiness.errorCode}). ${codexRecovery(readiness, "Install the supported Codex CLI version and sign in with a ChatGPT account.")} No API fallback is used.`,
|
|
115
115
|
};
|
|
116
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* The discovery and planning functions doctor's study checks use, loaded on first use as
|
|
119
|
+
* labSetupChecks always loaded them, so they stay out of this module's static imports.
|
|
120
|
+
*/
|
|
121
|
+
async function studyLoaders() {
|
|
122
|
+
const discover = await import("./discover.js");
|
|
123
|
+
const plan = await import("./plan.js");
|
|
124
|
+
return {
|
|
125
|
+
listStudies: discover.listLabManifests,
|
|
126
|
+
resolveStudy: discover.resolveLabManifest,
|
|
127
|
+
resolveDryRun: plan.resolveLabDryRun,
|
|
128
|
+
routeOf: plan.routeOf,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
117
131
|
/**
|
|
118
132
|
* Setup checks only: no model turn, browser or desktop creation. CLI startup may use the network.
|
|
119
133
|
* `keys` are the keys a live run requires. `reads` are the provider keys the lab is known to read,
|
|
@@ -121,9 +135,8 @@ export async function localCodexParticipantCheck(args) {
|
|
|
121
135
|
* scorer's host code may read any key.
|
|
122
136
|
*/
|
|
123
137
|
export async function labSetupChecks(args) {
|
|
124
|
-
const {
|
|
125
|
-
const
|
|
126
|
-
const resolved = await resolveLabManifest(args.cwd, args.lab);
|
|
138
|
+
const { resolveStudy, resolveDryRun, routeOf } = await studyLoaders();
|
|
139
|
+
const resolved = await resolveStudy(args.cwd, args.lab);
|
|
127
140
|
if (!resolved.ok)
|
|
128
141
|
return {
|
|
129
142
|
desktop: false,
|
|
@@ -131,7 +144,7 @@ export async function labSetupChecks(args) {
|
|
|
131
144
|
checks: [{ name: "lab", ok: false, message: resolved.error.message }],
|
|
132
145
|
};
|
|
133
146
|
const config = resolved.config, route = routeOf(config);
|
|
134
|
-
const dryRun =
|
|
147
|
+
const dryRun = resolveDryRun(config, undefined, true) === true;
|
|
135
148
|
const checks = [
|
|
136
149
|
{
|
|
137
150
|
name: "lab route",
|
|
@@ -298,19 +311,21 @@ async function analysisCheck(analysis, args, checkAccount) {
|
|
|
298
311
|
? "Use Linux x64 or the Apple Silicon Mac with a supported Codex CLI, or explicitly select provider: openai with an API key."
|
|
299
312
|
: readiness.errorCode === "codex_busy"
|
|
300
313
|
? "Another restricted Codex analyst or setup check is active in this process. Wait for it to finish, then retry."
|
|
301
|
-
: codexRecovery(readiness, "Install the
|
|
314
|
+
: codexRecovery(readiness, "Install the Codex CLI and sign in with a ChatGPT account.");
|
|
302
315
|
return {
|
|
303
316
|
name: "post-run analysis",
|
|
304
317
|
ok: readiness.ready,
|
|
305
318
|
message: readiness.ready
|
|
306
|
-
? readyMessage("
|
|
319
|
+
? readyMessage("Codex CLI and ChatGPT account login are ready for a separate restricted analyst. Analysis sends selected evidence to remote inference; model access and account allowance remain untested. Dollar cost and output-token ceilings are unavailable.", readiness)
|
|
307
320
|
: `Codex account analysis is unavailable (${readiness.errorCode ?? "codex_unavailable"}). ${recovery} No API fallback is used; participant readiness is independent.`,
|
|
308
321
|
};
|
|
309
322
|
}
|
|
323
|
+
const keyed = args.keyPresent("OPENAI_API_KEY");
|
|
310
324
|
return {
|
|
311
325
|
name: "post-run analysis",
|
|
312
326
|
ok: true,
|
|
313
|
-
|
|
327
|
+
...(keyed ? {} : { status: "note" }),
|
|
328
|
+
message: keyed
|
|
314
329
|
? `OPENAI_API_KEY is present for the separate automatic analysis request; model access and quota are not tested. The analysis is refused before it starts if its estimate is over $${analysis.maxCostUsd}; this is not a billing cap. Participant readiness is independent.`
|
|
315
330
|
: "Will be skipped: OPENAI_API_KEY is missing. The participant may run, but there will be no automatic findings report. Add an OpenAI API key or set review.analysis: false deliberately.",
|
|
316
331
|
};
|
|
@@ -325,6 +340,29 @@ function checkScope(analysis) {
|
|
|
325
340
|
: "Local setup only. Provider credentials are not validated, model access/quota and target reachability are untested, and no paid resources were created.",
|
|
326
341
|
};
|
|
327
342
|
}
|
|
343
|
+
/**
|
|
344
|
+
* The ids of the project's labs that need each provider key for a live run, from the same plan
|
|
345
|
+
* `doctor --lab` reads. Each listed manifest resolves by its path, since a file name need not match
|
|
346
|
+
* the id inside. A lab that runs dry, that the plain CLI cannot run, or that does not plan needs
|
|
347
|
+
* none.
|
|
348
|
+
*/
|
|
349
|
+
export async function studiesByRequiredKey(cwd, keyPresent) {
|
|
350
|
+
const { listStudies, resolveStudy, resolveDryRun, routeOf } = await studyLoaders();
|
|
351
|
+
const users = new Map();
|
|
352
|
+
for (const entry of (await listStudies(cwd)).studies) {
|
|
353
|
+
const resolved = await resolveStudy(cwd, entry.path);
|
|
354
|
+
if (!resolved.ok || resolveDryRun(resolved.config, undefined, true) === true)
|
|
355
|
+
continue;
|
|
356
|
+
if (unsupportedCliRoute(resolved.config, routeOf(resolved.config)))
|
|
357
|
+
continue;
|
|
358
|
+
const planned = await planCliRun(resolved.config, cwd);
|
|
359
|
+
if (!planned.ok)
|
|
360
|
+
continue;
|
|
361
|
+
for (const key of requiredKeys(planned.planned.plan.requirements, keyPresent))
|
|
362
|
+
users.set(key, (users.get(key) ?? new Set()).add(entry.id));
|
|
363
|
+
}
|
|
364
|
+
return new Map([...users].map(([key, ids]) => [key, [...ids]]));
|
|
365
|
+
}
|
|
328
366
|
/**
|
|
329
367
|
* The lab planned with no run options, so its own scenario mode decides dry or live. Doctor and the
|
|
330
368
|
* TUI read a live run's keys and subject env from this plan's requirements.
|