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.
Files changed (521) hide show
  1. package/ARCHITECTURE.md +22 -17
  2. package/CHANGELOG.md +14 -0
  3. package/CONTEXT.md +51 -44
  4. package/README.md +145 -172
  5. package/SECURITY.md +16 -26
  6. package/TELEMETRY.md +8 -6
  7. package/dist/actors/affordance.d.ts +4 -4
  8. package/dist/actors/affordance.js +12 -12
  9. package/dist/actors/agent-session.d.ts +2 -2
  10. package/dist/actors/agent-session.js +7 -7
  11. package/dist/actors/codex/app-server-actor-trace.d.ts +1 -1
  12. package/dist/actors/codex/app-server-actor-trace.js +1 -1
  13. package/dist/actors/codex/app-server-ui.js +1 -1
  14. package/dist/actors/codex/codex-admission.d.ts +91 -0
  15. package/dist/actors/codex/codex-admission.js +150 -0
  16. package/dist/actors/codex/restricted-executable.d.ts +4 -4
  17. package/dist/actors/codex/restricted-executable.js +8 -8
  18. package/dist/actors/codex/restricted-launch.d.ts +2 -1
  19. package/dist/actors/codex/restricted-launch.js +1 -1
  20. package/dist/actors/codex/restricted-participant.js +8 -6
  21. package/dist/actors/codex/restricted-policy.d.ts +2 -2
  22. package/dist/actors/codex/restricted-policy.js +2 -2
  23. package/dist/actors/codex/restricted-session.d.ts +2 -2
  24. package/dist/actors/codex/restricted-session.js +10 -5
  25. package/dist/actors/computer-use/actor.d.ts +16 -16
  26. package/dist/actors/computer-use/actor.js +2 -2
  27. package/dist/actors/computer-use/admission-limit.d.ts +1 -1
  28. package/dist/actors/computer-use/admission-limit.js +1 -1
  29. package/dist/actors/computer-use/loop/actions.d.ts +3 -3
  30. package/dist/actors/computer-use/loop/actions.js +10 -10
  31. package/dist/actors/computer-use/loop/backstop.d.ts +3 -3
  32. package/dist/actors/computer-use/loop/backstop.js +14 -12
  33. package/dist/actors/computer-use/loop/ending.d.ts +5 -5
  34. package/dist/actors/computer-use/loop/ending.js +7 -7
  35. package/dist/actors/computer-use/loop/observation.d.ts +2 -2
  36. package/dist/actors/computer-use/loop/observation.js +9 -9
  37. package/dist/actors/computer-use/loop/provider-call.d.ts +1 -1
  38. package/dist/actors/computer-use/loop/provider-call.js +1 -1
  39. package/dist/actors/computer-use/loop/session.js +3 -3
  40. package/dist/actors/computer-use/loop/spend.d.ts +1 -1
  41. package/dist/actors/computer-use/loop/spend.js +1 -1
  42. package/dist/actors/computer-use/loop/trace.js +9 -8
  43. package/dist/actors/computer-use/loop/types.d.ts +25 -23
  44. package/dist/actors/computer-use/loop/usage.js +2 -2
  45. package/dist/actors/computer-use/openai-context.d.ts +37 -0
  46. package/dist/actors/computer-use/openai-context.js +214 -0
  47. package/dist/actors/computer-use/openai-provider.d.ts +11 -8
  48. package/dist/actors/computer-use/openai-provider.js +45 -34
  49. package/dist/actors/computer-use/openai-requests.d.ts +36 -10
  50. package/dist/actors/computer-use/openai-requests.js +82 -15
  51. package/dist/actors/computer-use/openai-wire.d.ts +19 -7
  52. package/dist/actors/computer-use/openai-wire.js +36 -34
  53. package/dist/actors/contract.d.ts +78 -43
  54. package/dist/actors/contract.js +29 -23
  55. package/dist/actors/local-agent/claude-session.d.ts +1 -1
  56. package/dist/actors/local-agent/claude-session.js +10 -9
  57. package/dist/actors/local-agent/cli.d.ts +8 -6
  58. package/dist/actors/local-agent/cli.js +24 -28
  59. package/dist/actors/local-agent/readiness.d.ts +2 -2
  60. package/dist/actors/local-agent/readiness.js +4 -4
  61. package/dist/actors/reasoning-effort.js +6 -6
  62. package/dist/actors/registry.d.ts +10 -10
  63. package/dist/actors/registry.js +18 -17
  64. package/dist/actors/scripted-browser/actor.d.ts +8 -8
  65. package/dist/actors/scripted-browser/actor.js +16 -16
  66. package/dist/actors/scripted-browser/browser-command.js +1 -1
  67. package/dist/actors/scripted-browser/steps.js +1 -1
  68. package/dist/actors/scripted-browser/types.d.ts +1 -1
  69. package/dist/actors/stop-conditions.d.ts +1 -1
  70. package/dist/analysis/codex-config.d.ts +6 -2
  71. package/dist/analysis/codex-config.js +22 -14
  72. package/dist/analysis/service.js +5 -5
  73. package/dist/cli/commands/analyze.js +19 -16
  74. package/dist/cli/commands/codex.js +9 -9
  75. package/dist/cli/commands/comms.js +54 -33
  76. package/dist/cli/commands/feedback.js +20 -21
  77. package/dist/cli/commands/lab-format.d.ts +5 -4
  78. package/dist/cli/commands/lab-format.js +35 -23
  79. package/dist/cli/commands/lab-route-computer-use.js +6 -7
  80. package/dist/cli/commands/lab-route-preview.js +4 -3
  81. package/dist/cli/commands/lab-route-shared-world.js +3 -3
  82. package/dist/cli/commands/lab-run.js +10 -11
  83. package/dist/cli/commands/lab-scorer.d.ts +2 -2
  84. package/dist/cli/commands/lab-scorer.js +1 -1
  85. package/dist/cli/commands/migrate.d.ts +4 -0
  86. package/dist/cli/commands/migrate.js +65 -0
  87. package/dist/cli/commands/observe.js +147 -108
  88. package/dist/cli/commands/run-command.d.ts +10 -0
  89. package/dist/cli/commands/run-command.js +85 -0
  90. package/dist/cli/commands/runs.js +137 -138
  91. package/dist/cli/commands/setup.d.ts +2 -2
  92. package/dist/cli/commands/setup.js +26 -21
  93. package/dist/cli/commands/study.d.ts +3 -0
  94. package/dist/cli/commands/study.js +182 -0
  95. package/dist/cli/commands/tui.d.ts +4 -4
  96. package/dist/cli/commands/tui.js +21 -21
  97. package/dist/cli/commands/watch.js +60 -75
  98. package/dist/cli/deprecations.d.ts +18 -0
  99. package/dist/cli/deprecations.js +48 -0
  100. package/dist/cli/doctor.d.ts +15 -5
  101. package/dist/cli/doctor.js +103 -48
  102. package/dist/cli/first-run-path.d.ts +12 -10
  103. package/dist/cli/first-run-path.js +30 -28
  104. package/dist/cli/io.d.ts +41 -6
  105. package/dist/cli/io.js +97 -22
  106. package/dist/cli/observer-follow.d.ts +2 -2
  107. package/dist/cli/observer-follow.js +5 -6
  108. package/dist/cli/orientation.d.ts +6 -3
  109. package/dist/cli/orientation.js +43 -39
  110. package/dist/cli/product-sentence.d.ts +6 -0
  111. package/dist/cli/product-sentence.js +6 -0
  112. package/dist/cli/program.d.ts +6 -1
  113. package/dist/cli/program.js +109 -40
  114. package/dist/cli/telemetry.d.ts +15 -15
  115. package/dist/cli/telemetry.js +48 -40
  116. package/dist/cli.js +1 -1
  117. package/dist/comms/capture-surface.d.ts +13 -12
  118. package/dist/comms/capture-surface.js +23 -22
  119. package/dist/comms/catch-host.d.ts +7 -7
  120. package/dist/comms/catch-host.js +14 -14
  121. package/dist/comms/email-catch.d.ts +3 -3
  122. package/dist/comms/email-catch.js +8 -8
  123. package/dist/comms/external-evidence.js +2 -2
  124. package/dist/comms/extract.js +2 -2
  125. package/dist/comms/fake-inbox.d.ts +2 -2
  126. package/dist/comms/fake-inbox.js +2 -2
  127. package/dist/comms/receiving-render.d.ts +1 -1
  128. package/dist/comms/receiving-render.js +2 -2
  129. package/dist/comms/sandbox-catch-script.d.ts +6 -6
  130. package/dist/comms/sandbox-catch-script.js +6 -6
  131. package/dist/comms/sandbox-catch.d.ts +36 -37
  132. package/dist/comms/sandbox-catch.js +34 -35
  133. package/dist/comms/setup.js +42 -8
  134. package/dist/comms/thread-evidence.d.ts +1 -1
  135. package/dist/comms/thread-evidence.js +6 -6
  136. package/dist/comms/types.d.ts +6 -6
  137. package/dist/comms/types.js +3 -3
  138. package/dist/evidence/frame-signature.d.ts +1 -1
  139. package/dist/evidence/frame-signature.js +4 -4
  140. package/dist/evidence/redaction.d.ts +3 -3
  141. package/dist/evidence/redaction.js +4 -4
  142. package/dist/feedback/draft.js +36 -78
  143. package/dist/feedback/export-bundle.js +1 -1
  144. package/dist/feedback/export.d.ts +5 -1
  145. package/dist/feedback/export.js +7 -8
  146. package/dist/feedback/feedback.d.ts +2 -2
  147. package/dist/feedback/feedback.js +21 -3
  148. package/dist/guest/chromium-text.js +2 -2
  149. package/dist/guest/desktop-native.d.ts +1 -1
  150. package/dist/guest/runtime.js +1 -1
  151. package/dist/index.d.ts +12 -10
  152. package/dist/index.js +8 -6
  153. package/dist/keys/key-resolution.d.ts +5 -5
  154. package/dist/keys/key-resolution.js +23 -23
  155. package/dist/lab/adapter-extension.d.ts +7 -7
  156. package/dist/lab/adapter-extension.js +13 -36
  157. package/dist/lab/adapter-scorer-loader.d.ts +7 -7
  158. package/dist/lab/adapter-scorer-loader.js +32 -32
  159. package/dist/lab/composition-rules.js +42 -42
  160. package/dist/lab/config.js +65 -25
  161. package/dist/lab/deprecated-fields.d.ts +10 -0
  162. package/dist/lab/deprecated-fields.js +24 -0
  163. package/dist/lab/device-presets.d.ts +8 -8
  164. package/dist/lab/device-presets.js +11 -11
  165. package/dist/lab/discover.d.ts +13 -9
  166. package/dist/lab/discover.js +117 -57
  167. package/dist/lab/doctor.d.ts +10 -3
  168. package/dist/lab/doctor.js +47 -9
  169. package/dist/lab/init-templates.js +147 -147
  170. package/dist/lab/init.d.ts +1 -1
  171. package/dist/lab/init.js +41 -9
  172. package/dist/lab/keys.d.ts +2 -0
  173. package/dist/lab/keys.js +42 -8
  174. package/dist/lab/lab-deps.d.ts +7 -12
  175. package/dist/lab/parse/actors.js +9 -9
  176. package/dist/lab/parse/comms.js +5 -5
  177. package/dist/lab/parse/execution.js +13 -13
  178. package/dist/lab/parse/study-v3.d.ts +23 -0
  179. package/dist/lab/parse/study-v3.js +259 -0
  180. package/dist/lab/parse/subject-state.d.ts +7 -7
  181. package/dist/lab/parse/subject-state.js +16 -16
  182. package/dist/lab/parse/subject.js +28 -28
  183. package/dist/lab/parse/values.d.ts +1 -1
  184. package/dist/lab/parse/values.js +3 -3
  185. package/dist/lab/persona-resolve.d.ts +4 -4
  186. package/dist/lab/persona-resolve.js +4 -4
  187. package/dist/lab/plan-participants.d.ts +2 -2
  188. package/dist/lab/plan-types.d.ts +4 -4
  189. package/dist/lab/plan.d.ts +1 -7
  190. package/dist/lab/plan.js +10 -41
  191. package/dist/lab/preflight-probes.js +11 -11
  192. package/dist/lab/preflight-result.d.ts +2 -1
  193. package/dist/lab/preflight-result.js +5 -4
  194. package/dist/lab/preflight.d.ts +7 -5
  195. package/dist/lab/preflight.js +5 -5
  196. package/dist/lab/routing.d.ts +31 -25
  197. package/dist/lab/routing.js +60 -29
  198. package/dist/lab/run-lab-events.d.ts +0 -3
  199. package/dist/lab/run-lab-events.js +0 -6
  200. package/dist/lab/run-lab-homes.d.ts +22 -10
  201. package/dist/lab/run-lab-homes.js +5 -1
  202. package/dist/lab/run-lab-options.d.ts +1 -1
  203. package/dist/lab/run-lab-options.js +16 -13
  204. package/dist/lab/summary.d.ts +7 -6
  205. package/dist/lab/summary.js +10 -10
  206. package/dist/lab/tasks.d.ts +15 -15
  207. package/dist/lab/tasks.js +14 -14
  208. package/dist/lab/types.d.ts +101 -95
  209. package/dist/lab/types.js +2 -0
  210. package/dist/lab/validation.d.ts +13 -13
  211. package/dist/lab/validation.js +44 -42
  212. package/dist/lab/warnings.d.ts +10 -0
  213. package/dist/lab/warnings.js +61 -33
  214. package/dist/library-aliases.d.ts +56 -0
  215. package/dist/library-aliases.js +22 -0
  216. package/dist/observer/artifact.d.ts +1 -1
  217. package/dist/observer/artifact.js +6 -6
  218. package/dist/observer/data.d.ts +6 -6
  219. package/dist/observer/data.js +5 -4
  220. package/dist/observer/exposure.d.ts +1 -1
  221. package/dist/observer/exposure.js +11 -11
  222. package/dist/observer/http.js +1 -1
  223. package/dist/observer/library.d.ts +1 -1
  224. package/dist/observer/library.js +4 -2
  225. package/dist/observer/listen.js +5 -4
  226. package/dist/observer/render.d.ts +1 -1
  227. package/dist/observer/render.js +10 -5
  228. package/dist/observer/run-routes.d.ts +3 -3
  229. package/dist/observer/run-routes.js +1 -1
  230. package/dist/observer/serve.js +7 -3
  231. package/dist/observer/tunnel.js +1 -1
  232. package/dist/observer-app.html +4 -4
  233. package/dist/routes/computer-use/bundle-parts.d.ts +9 -9
  234. package/dist/routes/computer-use/bundle-parts.js +15 -15
  235. package/dist/routes/computer-use/bundle.js +3 -3
  236. package/dist/routes/computer-use/e2b-desktop/comms.d.ts +1 -1
  237. package/dist/routes/computer-use/e2b-desktop/comms.js +14 -14
  238. package/dist/routes/computer-use/e2b-desktop/desktop.js +4 -4
  239. package/dist/routes/computer-use/e2b-desktop/fidelity.d.ts +4 -3
  240. package/dist/routes/computer-use/e2b-desktop/fidelity.js +11 -10
  241. package/dist/routes/computer-use/e2b-desktop/prepare.js +7 -7
  242. package/dist/routes/computer-use/e2b-desktop/start.js +9 -8
  243. package/dist/routes/computer-use/e2b-desktop/teardown.js +5 -4
  244. package/dist/routes/computer-use/external-comms.d.ts +1 -1
  245. package/dist/routes/computer-use/external-comms.js +1 -1
  246. package/dist/routes/computer-use/fanout-bundle.js +18 -18
  247. package/dist/routes/computer-use/fanout-records.js +10 -11
  248. package/dist/routes/computer-use/live-flush.d.ts +1 -1
  249. package/dist/routes/computer-use/live-flush.js +6 -6
  250. package/dist/routes/computer-use/live-phase.d.ts +4 -2
  251. package/dist/routes/computer-use/live-phase.js +6 -6
  252. package/dist/routes/computer-use/local-vm.js +1 -1
  253. package/dist/routes/computer-use/participant-desktop.d.ts +4 -4
  254. package/dist/routes/computer-use/participant-desktop.js +4 -4
  255. package/dist/routes/computer-use/participant-execution.d.ts +4 -4
  256. package/dist/routes/computer-use/participant-execution.js +9 -9
  257. package/dist/routes/computer-use/participant-model.d.ts +6 -0
  258. package/dist/routes/computer-use/participant-model.js +31 -13
  259. package/dist/routes/computer-use/participant-prompt.d.ts +11 -11
  260. package/dist/routes/computer-use/participant-prompt.js +6 -6
  261. package/dist/routes/computer-use/participant-runs.d.ts +7 -7
  262. package/dist/routes/computer-use/participant-runs.js +13 -13
  263. package/dist/routes/computer-use/plan.js +22 -22
  264. package/dist/routes/computer-use/preflight.js +21 -21
  265. package/dist/routes/computer-use/rerun-selection.js +1 -1
  266. package/dist/routes/computer-use/result.js +11 -11
  267. package/dist/routes/computer-use/route.d.ts +2 -1
  268. package/dist/routes/computer-use/route.js +15 -14
  269. package/dist/routes/computer-use/self-report.d.ts +7 -7
  270. package/dist/routes/computer-use/self-report.js +31 -31
  271. package/dist/routes/computer-use/setup.d.ts +1 -1
  272. package/dist/routes/computer-use/setup.js +17 -18
  273. package/dist/routes/computer-use/single-bundle.d.ts +7 -7
  274. package/dist/routes/computer-use/single-bundle.js +28 -30
  275. package/dist/routes/computer-use/subject-projection.d.ts +1 -1
  276. package/dist/routes/computer-use/subject-projection.js +6 -6
  277. package/dist/routes/computer-use/types.d.ts +40 -42
  278. package/dist/routes/computer-use/types.js +10 -10
  279. package/dist/routes/preview.d.ts +8 -2
  280. package/dist/routes/preview.js +8 -4
  281. package/dist/routes/scripted/bundle.d.ts +2 -2
  282. package/dist/routes/scripted/bundle.js +13 -12
  283. package/dist/routes/scripted/plan.d.ts +1 -1
  284. package/dist/routes/scripted/plan.js +9 -9
  285. package/dist/routes/scripted/result.js +5 -5
  286. package/dist/routes/scripted/route.js +5 -6
  287. package/dist/routes/scripted/scenario.js +2 -2
  288. package/dist/routes/scripted/setup.js +7 -7
  289. package/dist/routes/scripted/subject.js +1 -1
  290. package/dist/routes/scripted/surface-records.js +3 -3
  291. package/dist/routes/scripted/types.d.ts +3 -5
  292. package/dist/routes/scripted/types.js +1 -1
  293. package/dist/routes/shared-world/bundle-records.js +9 -8
  294. package/dist/routes/shared-world/bundle.d.ts +5 -5
  295. package/dist/routes/shared-world/bundle.js +40 -38
  296. package/dist/routes/shared-world/checkpoints.d.ts +1 -1
  297. package/dist/routes/shared-world/checkpoints.js +1 -1
  298. package/dist/routes/shared-world/comms.d.ts +5 -5
  299. package/dist/routes/shared-world/comms.js +14 -14
  300. package/dist/routes/shared-world/external-public.d.ts +4 -3
  301. package/dist/routes/shared-world/external-public.js +16 -12
  302. package/dist/routes/shared-world/handoff.d.ts +7 -6
  303. package/dist/routes/shared-world/handoff.js +65 -57
  304. package/dist/routes/shared-world/lobby-code.d.ts +2 -2
  305. package/dist/routes/shared-world/lobby-code.js +9 -9
  306. package/dist/routes/shared-world/participant-specs.d.ts +7 -6
  307. package/dist/routes/shared-world/participant-specs.js +31 -24
  308. package/dist/routes/shared-world/plan.js +7 -7
  309. package/dist/routes/shared-world/provenance.d.ts +2 -2
  310. package/dist/routes/shared-world/provenance.js +2 -2
  311. package/dist/routes/shared-world/provisioned.js +14 -13
  312. package/dist/routes/shared-world/result.js +20 -21
  313. package/dist/routes/shared-world/route.js +23 -22
  314. package/dist/routes/shared-world/setup.d.ts +3 -3
  315. package/dist/routes/shared-world/setup.js +4 -4
  316. package/dist/routes/shared-world/types.d.ts +30 -28
  317. package/dist/routes/shared-world/types.js +4 -4
  318. package/dist/routes/terminal/adapter.d.ts +3 -3
  319. package/dist/routes/terminal/adapter.js +5 -5
  320. package/dist/routes/terminal/bundle.d.ts +3 -3
  321. package/dist/routes/terminal/bundle.js +22 -21
  322. package/dist/routes/terminal/credentials.d.ts +4 -4
  323. package/dist/routes/terminal/credentials.js +7 -7
  324. package/dist/routes/terminal/dry-run.js +4 -4
  325. package/dist/routes/terminal/encoding.js +2 -2
  326. package/dist/routes/terminal/ledger.d.ts +3 -3
  327. package/dist/routes/terminal/ledger.js +14 -14
  328. package/dist/routes/terminal/live-finish.js +3 -3
  329. package/dist/routes/terminal/live-sandbox.js +12 -13
  330. package/dist/routes/terminal/persona.js +1 -1
  331. package/dist/routes/terminal/plan.js +11 -11
  332. package/dist/routes/terminal/recorder.js +2 -2
  333. package/dist/routes/terminal/result.js +8 -8
  334. package/dist/routes/terminal/route.js +6 -7
  335. package/dist/routes/terminal/sandbox.d.ts +1 -1
  336. package/dist/routes/terminal/sandbox.js +1 -1
  337. package/dist/routes/terminal/session.js +8 -7
  338. package/dist/routes/terminal/token-usage.d.ts +1 -1
  339. package/dist/routes/terminal/token-usage.js +7 -8
  340. package/dist/routes/terminal/trace.d.ts +2 -2
  341. package/dist/routes/terminal/trace.js +2 -2
  342. package/dist/routes/terminal/types.d.ts +26 -28
  343. package/dist/routes/terminal/types.js +3 -3
  344. package/dist/run/bundle-shape.js +3 -3
  345. package/dist/run/bundle.d.ts +46 -46
  346. package/dist/run/bundle.js +2 -1
  347. package/dist/run/cost-summary.js +3 -3
  348. package/dist/run/costs.js +7 -1
  349. package/dist/run/detail.d.ts +6 -6
  350. package/dist/run/detail.js +4 -4
  351. package/dist/run/dry-run-inputs.js +1 -1
  352. package/dist/run/dry-run.js +18 -18
  353. package/dist/run/judge.d.ts +19 -13
  354. package/dist/run/judge.js +18 -8
  355. package/dist/run/paths.d.ts +1 -1
  356. package/dist/run/paths.js +1 -1
  357. package/dist/run/pricing.d.ts +11 -6
  358. package/dist/run/pricing.js +20 -13
  359. package/dist/run/projection.d.ts +14 -14
  360. package/dist/run/projection.js +15 -15
  361. package/dist/run/reclaim.js +2 -2
  362. package/dist/run/results.d.ts +5 -5
  363. package/dist/run/run-index.d.ts +8 -6
  364. package/dist/run/run-index.js +15 -16
  365. package/dist/run/run-not-found.d.ts +5 -0
  366. package/dist/run/run-not-found.js +15 -0
  367. package/dist/run/run.d.ts +5 -4
  368. package/dist/run/run.js +1 -1
  369. package/dist/run/sandbox-receipts.d.ts +2 -2
  370. package/dist/run/sandbox-receipts.js +3 -3
  371. package/dist/run/shared-world-evidence.d.ts +36 -35
  372. package/dist/run/shared-world-evidence.js +4 -4
  373. package/dist/run/shared-world-shape.d.ts +1 -1
  374. package/dist/run/shared-world-shape.js +6 -6
  375. package/dist/run/stats.d.ts +12 -6
  376. package/dist/run/stats.js +116 -58
  377. package/dist/run/status.d.ts +8 -29
  378. package/dist/run/status.js +5 -27
  379. package/dist/run/stored-runs.js +2 -1
  380. package/dist/run/stream-shape.js +1 -1
  381. package/dist/run/streams.d.ts +6 -6
  382. package/dist/run/study-provenance.d.ts +47 -0
  383. package/dist/run/study-provenance.js +63 -0
  384. package/dist/run/study-result.d.ts +16 -0
  385. package/dist/run/study-result.js +9 -0
  386. package/dist/run/text.d.ts +2 -0
  387. package/dist/run/text.js +4 -0
  388. package/dist/run-lab.d.ts +7 -7
  389. package/dist/run-lab.js +1 -3
  390. package/dist/study/convert.d.ts +33 -0
  391. package/dist/study/convert.js +432 -0
  392. package/dist/study/field-paths.d.ts +12 -0
  393. package/dist/study/field-paths.js +126 -0
  394. package/dist/study/files.d.ts +26 -0
  395. package/dist/study/files.js +43 -0
  396. package/dist/study/migrate.d.ts +48 -0
  397. package/dist/study/migrate.js +408 -0
  398. package/dist/study/owned-files.d.ts +38 -0
  399. package/dist/study/owned-files.js +182 -0
  400. package/dist/subject/clone.d.ts +1 -1
  401. package/dist/subject/desktop-cli.d.ts +1 -1
  402. package/dist/subject/desktop-cli.js +2 -2
  403. package/dist/subject/local-tree-archive.js +1 -1
  404. package/dist/subject/local-tree.d.ts +1 -1
  405. package/dist/subject/node-bootstrap.js +1 -1
  406. package/dist/subject/runtime.js +8 -9
  407. package/dist/subject/serve.d.ts +1 -1
  408. package/dist/subject/serve.js +3 -3
  409. package/dist/subject/state.d.ts +1 -1
  410. package/dist/subject/steps.d.ts +5 -5
  411. package/dist/subject/steps.js +4 -4
  412. package/dist/substrates/command-failure.d.ts +3 -3
  413. package/dist/substrates/command-failure.js +3 -3
  414. package/dist/substrates/detached.d.ts +6 -6
  415. package/dist/substrates/detached.js +7 -7
  416. package/dist/substrates/e2b/cdp-probe.d.ts +9 -9
  417. package/dist/substrates/e2b/cdp-probe.js +14 -17
  418. package/dist/substrates/e2b/desktop-browser.d.ts +2 -2
  419. package/dist/substrates/e2b/desktop-browser.js +8 -8
  420. package/dist/substrates/e2b/desktop-cdp.d.ts +9 -9
  421. package/dist/substrates/e2b/desktop-cdp.js +8 -8
  422. package/dist/substrates/e2b/desktop-executor.d.ts +1 -1
  423. package/dist/substrates/e2b/desktop-executor.js +1 -1
  424. package/dist/substrates/e2b/desktop-geometry.d.ts +3 -3
  425. package/dist/substrates/e2b/desktop-geometry.js +7 -7
  426. package/dist/substrates/e2b/desktop-media.d.ts +1 -1
  427. package/dist/substrates/e2b/desktop-media.js +1 -1
  428. package/dist/substrates/e2b/desktop-screenshot-cleanup.d.ts +3 -3
  429. package/dist/substrates/e2b/desktop-screenshot-cleanup.js +3 -3
  430. package/dist/substrates/e2b/sandbox.d.ts +1 -1
  431. package/dist/substrates/e2b/sandbox.js +1 -1
  432. package/dist/substrates/e2b/sdk.d.ts +11 -11
  433. package/dist/substrates/e2b/sdk.js +6 -6
  434. package/dist/tui/actions.d.ts +1 -1
  435. package/dist/tui/actions.js +13 -13
  436. package/dist/tui/contract.d.ts +16 -16
  437. package/dist/tui/contract.js +10 -10
  438. package/dist/tui/launch.d.ts +4 -4
  439. package/dist/tui/launch.js +18 -19
  440. package/dist/tui/project.js +5 -5
  441. package/dist/tui-app.js +82 -82
  442. package/dist/verify/actor.d.ts +8 -8
  443. package/dist/verify/actor.js +36 -36
  444. package/dist/verify/artifacts.d.ts +2 -2
  445. package/dist/verify/artifacts.js +3 -3
  446. package/dist/verify/context-growth.d.ts +9 -0
  447. package/dist/verify/context-growth.js +62 -0
  448. package/dist/verify/costs.d.ts +6 -6
  449. package/dist/verify/costs.js +8 -8
  450. package/dist/verify/shared-world-concurrent.d.ts +2 -2
  451. package/dist/verify/shared-world-concurrent.js +79 -76
  452. package/dist/verify/shared-world.d.ts +2 -2
  453. package/dist/verify/shared-world.js +16 -16
  454. package/dist/verify/subject.d.ts +4 -4
  455. package/dist/verify/subject.js +18 -18
  456. package/dist/verify/verify.js +92 -43
  457. package/docs/README.md +25 -32
  458. package/docs/architecture/actor-contract.md +56 -87
  459. package/docs/architecture/desktop-sessions.md +7 -7
  460. package/docs/architecture/external-public-shared-world.md +61 -59
  461. package/docs/architecture/github-feedback-loop.md +1 -4
  462. package/docs/architecture/guest-desktop.md +2 -2
  463. package/docs/architecture/observer.md +34 -34
  464. package/docs/architecture/restricted-codex-analysis.md +34 -28
  465. package/docs/architecture/serve.md +34 -37
  466. package/docs/architecture/state-driven-executor.md +55 -58
  467. package/docs/architecture/task-protocol-support.md +5 -5
  468. package/docs/architecture/terminal-product-route.md +67 -107
  469. package/docs/contracts/README.md +24 -0
  470. package/docs/contracts/adapter-admission.md +3 -3
  471. package/docs/contracts/adapter-fixtures.md +2 -5
  472. package/docs/contracts/core.md +1 -3
  473. package/docs/contracts/errors.md +62 -0
  474. package/docs/contracts/feedback.md +8 -9
  475. package/docs/contracts/policy.md +7 -12
  476. package/docs/contracts/run-bundle.md +45 -44
  477. package/docs/contracts/schemas.md +421 -362
  478. package/docs/contracts/study-analysis.md +3 -3
  479. package/docs/contracts/study-costs.md +11 -7
  480. package/docs/decisions/0001-run-bundle-is-the-source-of-truth.md +1 -1
  481. package/docs/decisions/0002-observer-is-one-self-contained-file.md +2 -2
  482. package/docs/decisions/0003-contained-paths-and-cleanup-authority.md +3 -3
  483. package/docs/principles/actor-fidelity.md +4 -4
  484. package/docs/principles/engineering.md +3 -3
  485. package/docs/principles/invariants-and-defaults.md +38 -38
  486. package/docs/principles/self-driving-harness.md +1 -5
  487. package/docs/principles/three-roles.md +1 -1
  488. package/docs/product/automatic-analysis.md +7 -7
  489. package/examples/participant/README.md +5 -5
  490. package/examples/participant/run.mjs +11 -10
  491. package/examples/scorer/README.md +3 -3
  492. package/examples/scorer/run.mjs +11 -12
  493. package/package.json +16 -17
  494. package/skills/humanish/SKILL.md +60 -58
  495. package/skills/humanish/agents/openai.yaml +1 -1
  496. package/AGENTS.md +0 -99
  497. package/CONTRIBUTING.md +0 -148
  498. package/dist/actors/codex/qualified-versions.d.ts +0 -72
  499. package/dist/actors/codex/qualified-versions.js +0 -132
  500. package/dist/cli/commands/lab.d.ts +0 -3
  501. package/dist/cli/commands/lab.js +0 -199
  502. package/dist/cli/renamed-options.d.ts +0 -11
  503. package/dist/cli/renamed-options.js +0 -18
  504. package/dist/observer/static.d.ts +0 -39
  505. package/dist/observer/static.js +0 -369
  506. package/docs/architecture/comms-inbox.md +0 -122
  507. package/docs/architecture/desktop-recording.md +0 -80
  508. package/docs/architecture/local-browser-runtime.md +0 -178
  509. package/docs/architecture/observer-review.md +0 -144
  510. package/docs/architecture/participant-media.md +0 -90
  511. package/docs/architecture/project-layout.md +0 -62
  512. package/docs/architecture/real-email-receiving.md +0 -136
  513. package/docs/assets/humanish-drawdb-hero.png +0 -0
  514. package/docs/assets/humanish-observer-hero.png +0 -0
  515. package/docs/goals/current.md +0 -207
  516. package/docs/product/lobby-trivia-3player-external-public.md +0 -77
  517. package/docs/product/open-source-install-experience.md +0 -240
  518. package/docs/ramp/README.md +0 -295
  519. package/docs/release/open-source-readiness.md +0 -222
  520. package/docs/release/public-readiness-standard.md +0 -210
  521. package/docs/roadmap/world-class-open-source-v0.md +0 -311
@@ -2,6 +2,11 @@ import { type KeyResolutionDeps } from "../keys/key-resolution.js";
2
2
  import { type DetectLocalAgentsOptions } from "../actors/local-agent/cli.js";
3
3
  import { type LabSetupCheckArgs } from "../lab/doctor.js";
4
4
  declare const DOCTOR_SCHEMA = "humanish.doctor-result.v1";
5
+ /**
6
+ * A row's verdict, as the human output prints it. A "note" is advisory: it never fails the run, so
7
+ * its `ok` is true. "not_checked" goes with `checked: false`.
8
+ */
9
+ type DoctorStatus = "ok" | "missing" | "not_checked" | "note";
5
10
  export interface DoctorResult {
6
11
  schema: typeof DOCTOR_SCHEMA;
7
12
  ok: boolean;
@@ -9,14 +14,15 @@ export interface DoctorResult {
9
14
  checks: Array<{
10
15
  name: string;
11
16
  ok: boolean;
17
+ status: DoctorStatus;
12
18
  message: string;
13
19
  /**
14
- * ADDITIVE + OPTIONAL. `false` means the check never ran — the directory could not be read, so
20
+ * Additive + optional. `false` means the check never ran: the directory could not be read, so
15
21
  * there is nothing to report about it either way. Absent means it ran and `ok` is its verdict.
16
22
  *
17
- * It exists because a failed check and an unrun one used to render identically, and the unrun
18
- * rows carried the SUCCESS text: a participant read `missing package.json: package.json is
19
- * present and safe to read` off a real screen (labs/tui-self-study.yaml).
23
+ * It exists so a failed check and an unrun one render differently. Without it an unrun row
24
+ * shows the success text, such as `missing package.json: package.json is present and safe to
25
+ * read` (labs/tui-self-study.yaml).
20
26
  */
21
27
  checked?: boolean;
22
28
  }>;
@@ -25,11 +31,15 @@ export interface DoctorResult {
25
31
  * Version 2.3.1 stopped holding a launched background command's event stream open. Version 2.3.2
26
32
  * also requires an e2b release whose background command handle supports sendStdin and closeStdin,
27
33
  * which the optional speech transport needs. On older releases the CLI could stay alive minutes
28
- * past a written result (#581, measured 2026-09-04 on 2.2.3: twelve minutes).
34
+ * past a written result (measured 2026-09-04 on 2.2.3: twelve minutes).
29
35
  */
30
36
  export declare const DESKTOP_SDK_FLOOR = "2.3.2";
31
37
  /** The advisory `doctor` attaches to an installed desktop SDK older than the floor, else undefined. */
32
38
  export declare function desktopSdkAdvisory(version: string | undefined): string | undefined;
39
+ /** A row as a check writes it. Doctor derives `status`; an advisory row sets "note" itself. */
40
+ export type DoctorCheckDraft = Omit<DoctorResult["checks"][number], "status"> & {
41
+ status?: "note";
42
+ };
33
43
  export declare function doctor(cwdInput: string, options?: {
34
44
  lab?: string;
35
45
  env?: NodeJS.ProcessEnv;
@@ -3,8 +3,8 @@ import { existsSync } from "node:fs";
3
3
  import path from "node:path";
4
4
  import { probeKeySources, } from "../keys/key-resolution.js";
5
5
  import { nodeSupportsTui, terminalSurfaceMessage, TUI_BUNDLE_URL } from "../tui/contract.js";
6
- import { detectLocalAgents, localAgentDoctorMessage, } from "../actors/local-agent/cli.js";
7
- import { labSetupChecks } from "../lab/doctor.js";
6
+ import { detectLocalAgents, localAgentDoctorMessage, NO_LOCAL_AGENT_MESSAGE, } from "../actors/local-agent/cli.js";
7
+ import { labSetupChecks, studiesByRequiredKey } from "../lab/doctor.js";
8
8
  import { prepareSelectedOutputDirectory, } from "../run/contained-output.js";
9
9
  import { implicitProjectDirectoryExists, readImplicitProjectFile, validateCwd, } from "../run/project.js";
10
10
  const DOCTOR_SCHEMA = "humanish.doctor-result.v1";
@@ -12,7 +12,7 @@ const DOCTOR_SCHEMA = "humanish.doctor-result.v1";
12
12
  * Version 2.3.1 stopped holding a launched background command's event stream open. Version 2.3.2
13
13
  * also requires an e2b release whose background command handle supports sendStdin and closeStdin,
14
14
  * which the optional speech transport needs. On older releases the CLI could stay alive minutes
15
- * past a written result (#581, measured 2026-09-04 on 2.2.3: twelve minutes).
15
+ * past a written result (measured 2026-09-04 on 2.2.3: twelve minutes).
16
16
  */
17
17
  export const DESKTOP_SDK_FLOOR = "2.3.2";
18
18
  /** The advisory `doctor` attaches to an installed desktop SDK older than the floor, else undefined. */
@@ -31,7 +31,7 @@ export function desktopSdkAdvisory(version) {
31
31
  (have[0] === floor[0] &&
32
32
  (have[1] < floor[1] || (have[1] === floor[1] && have[2] < floor[2])));
33
33
  return older
34
- ? `@e2b/desktop ${version} is older than ${DESKTOP_SDK_FLOOR}, the supported floor for background command cleanup and stdin handles (older releases could keep the CLI alive minutes past its result, #581). Update with \`npm i -D @e2b/desktop@latest\`.`
34
+ ? `@e2b/desktop ${version} is older than ${DESKTOP_SDK_FLOOR}, the supported floor for background command cleanup and stdin handles (older releases could keep the CLI alive for minutes after its result). Update with \`npm i -D @e2b/desktop@latest\`.`
35
35
  : undefined;
36
36
  }
37
37
  /** The version of the @e2b/desktop that `import("@e2b/desktop")` resolves to from here, if readable. */
@@ -52,47 +52,46 @@ export async function doctor(cwdInput, options = {}) {
52
52
  .then((error) => error === null)
53
53
  .catch(() => false);
54
54
  if (!cwdOk) {
55
- const checks = uncheckedProjectChecks("this directory does not exist, or humanish cannot read it", "not checked — the target directory could not be read");
56
- return { schema: DOCTOR_SCHEMA, ok: false, cwd, checks };
55
+ const checks = uncheckedProjectChecks("this directory does not exist, or humanish cannot read it", "not checked: the target directory could not be read");
56
+ return { schema: DOCTOR_SCHEMA, ok: false, cwd, checks: withStatus(checks) };
57
57
  }
58
58
  let projectRoot;
59
59
  try {
60
60
  projectRoot = await prepareSelectedOutputDirectory(path.dirname(cwd), cwd);
61
61
  }
62
62
  catch {
63
- const checks = uncheckedProjectChecks("target directory failed containment validation", "not checked — containment validation failed first");
64
- return { schema: DOCTOR_SCHEMA, ok: false, cwd, checks };
63
+ const checks = uncheckedProjectChecks("target directory failed containment validation", "not checked: the containment check failed first");
64
+ return { schema: DOCTOR_SCHEMA, ok: false, cwd, checks: withStatus(checks) };
65
65
  }
66
66
  const env = options.env ?? process.env;
67
67
  const agents = await detectLocalAgents({ ...options.localAgents, env });
68
68
  const { probes, receivingKey } = await probeDoctorKeys(cwd, env, options.lab, options.keyDeps);
69
+ const keyPresent = (name) => probes.some((probe) => probe.name === name && probe.source !== null);
69
70
  const setup = options.lab
70
71
  ? await labSetupChecks({
71
72
  cwd,
72
73
  lab: options.lab,
73
74
  env,
74
75
  agents,
75
- keyPresent: (name) => probes.some((probe) => probe.name === name && probe.source !== null),
76
+ keyPresent,
76
77
  ...(options.codexParticipantReadiness === undefined
77
78
  ? {}
78
79
  : { codexParticipantReadiness: options.codexParticipantReadiness }),
79
80
  })
80
81
  : undefined;
82
+ // Without --lab, each key row names the labs that need it instead of failing.
83
+ const keyUsers = setup ? undefined : await studiesByRequiredKey(cwd, keyPresent);
81
84
  const checks = [
82
85
  ...(await projectChecks(projectRoot)),
83
86
  await desktopSdkCheck(setup),
84
87
  terminalSurfaceCheck(),
85
- // The operator's own signed-in coding agent, reported as a CAPABILITY and never a gate: a
86
- // machine with none is not broken, it just needs a provider key. This row exists because
87
- // "go make an API key" is where most people trying humanish stop, and a developer very often
88
- // already has one of these signed in.
89
- { name: "local agents", ok: true, message: localAgentDoctorMessage(agents) },
90
- ...keyChecks(probes, receivingKey, setup, agents),
88
+ ...localAgentChecks(agents),
89
+ ...keyChecks(probes, receivingKey, setup, keyUsers),
91
90
  ...(setup?.checks ?? [
92
91
  {
93
92
  name: "setup route",
94
93
  ok: true,
95
- message: "General capabilities only. Use humanish doctor --lab <lab> for the selected participant's requirements and separate analysis readiness.",
94
+ message: "General capabilities only. Use humanish doctor --study <study> for the selected participant's requirements and separate analysis readiness.",
96
95
  },
97
96
  ]),
98
97
  ];
@@ -100,9 +99,15 @@ export async function doctor(cwdInput, options = {}) {
100
99
  schema: DOCTOR_SCHEMA,
101
100
  ok: checks.every((check) => check.ok),
102
101
  cwd,
103
- checks,
102
+ checks: withStatus(checks),
104
103
  };
105
104
  }
105
+ function withStatus(checks) {
106
+ return checks.map((check) => ({
107
+ ...check,
108
+ status: check.ok ? (check.status ?? "ok") : check.checked === false ? "not_checked" : "missing",
109
+ }));
110
+ }
106
111
  /** The rows for a target directory doctor could not open: the failure, then three unrun checks. */
107
112
  function uncheckedProjectChecks(targetMessage, reason) {
108
113
  return [
@@ -147,23 +152,35 @@ async function projectChecks(projectRoot) {
147
152
  };
148
153
  }
149
154
  })(),
150
- {
151
- name: "humanish source",
152
- ok: await safeCheck(() => implicitProjectDirectoryExists(projectRoot, "humanish")),
153
- message: "committed humanish/ source directory is present and safe to read",
154
- },
155
- {
156
- name: "runtime ignore",
157
- ok: await safeCheck(async () => (await readImplicitProjectFile(projectRoot, ".gitignore"))?.includes(".humanish/") ??
158
- false),
159
- message: ".gitignore safely contains .humanish/",
160
- },
155
+ await sourceCheck(projectRoot),
156
+ await runtimeIgnoreCheck(projectRoot),
161
157
  ];
162
158
  }
159
+ // Each row says what it found, and a failing one names the command that fixes it.
160
+ async function sourceCheck(projectRoot) {
161
+ const ok = await safeCheck(() => implicitProjectDirectoryExists(projectRoot, "humanish"));
162
+ return {
163
+ name: "humanish source",
164
+ ok,
165
+ message: ok
166
+ ? "committed humanish/ source directory is present and safe to read"
167
+ : "no readable humanish/ source directory; run humanish init --yes",
168
+ };
169
+ }
170
+ async function runtimeIgnoreCheck(projectRoot) {
171
+ const ok = await safeCheck(async () => (await readImplicitProjectFile(projectRoot, ".gitignore"))?.includes(".humanish/") ?? false);
172
+ return {
173
+ name: "runtime ignore",
174
+ ok,
175
+ message: ok
176
+ ? ".gitignore lists .humanish/"
177
+ : ".gitignore does not list .humanish/; run humanish init --yes",
178
+ };
179
+ }
163
180
  /**
164
- * The optional peer dep every live browser and terminal route needs (#346). `npx -y humanish` does
165
- * not pull optional peers, so an adopter's FIRST live run used to fail on it — safely and at $0,
166
- * but as a burned first impression on the flagship path. Answering it here means the readiness
181
+ * The optional peer dep every live browser and terminal route needs. `npx -y humanish` does not
182
+ * pull optional peers, so without this check an adopter's first live run fails on it, safely and at
183
+ * $0, but as a burned first impression on the flagship path. Answering it here means the readiness
167
184
  * command actually answers readiness.
168
185
  */
169
186
  async function desktopSdkCheck(setup) {
@@ -178,27 +195,30 @@ async function desktopSdkCheck(setup) {
178
195
  });
179
196
  const version = present ? await installedDesktopSdkVersion() : undefined;
180
197
  const advisory = desktopSdkAdvisory(version);
198
+ // Without --lab nothing selects a desktop route yet, so an absent SDK is advisory.
199
+ const advisoryOnly = !present && setup === undefined;
181
200
  return {
182
201
  name: "e2b desktop sdk",
183
- ok: present || setup?.desktop === false,
202
+ ok: present || advisoryOnly || setup?.desktop === false,
203
+ ...(advisoryOnly ? { status: "note" } : {}),
184
204
  message: present
185
205
  ? `optional peer @e2b/desktop ${version ?? "(version unread)"} is installed; provider access is not tested${advisory === undefined ? "" : `. ${advisory}`}`
186
206
  : setup?.desktop === false
187
207
  ? "optional peer @e2b/desktop is absent; not required by the selected route"
188
- : "optional peer @e2b/desktop is NOT installed: dry runs work, but any live desktop participant will fail closed. Install it with `npm i -D @e2b/desktop`.",
208
+ : "optional peer @e2b/desktop is not installed: dry runs work, but a live run with a desktop participant fails when it starts. Install it with `npm i -D @e2b/desktop`.",
189
209
  };
190
210
  }
191
211
  /**
192
- * The stakeholder surface (#455). Reported as capability, never as a gate: the TUI is optional,
212
+ * The stakeholder surface. Reported as capability, never as a gate: the TUI is optional,
193
213
  * and `doctor` is itself mostly run by agents through a pipe, where a TTY requirement says
194
- * nothing about whether the PROJECT is ready. So this row is always ok.
214
+ * nothing about whether the project is ready. So this row is always ok.
195
215
  *
196
- * WHO IS READING decides the wording, and a real first-contact study
216
+ * Who is reading decides the wording, and a real first-contact study
197
217
  * (labs/first-contact.yaml) is why. An agent evaluating humanish read
198
218
  * "`humanish tui` is available in an interactive terminal", correctly concluded it was not in
199
- * one, and dropped it — then wrote a report FOR A HUMAN that never mentioned the human
219
+ * one, and dropped it, then wrote a report for a human that never mentioned the human
200
220
  * surface at all. Discovery worked; handoff did not. A capability described to a reader who
201
- * cannot use it has to be phrased as something to PASS ON, or it reads as "not for you" and
221
+ * cannot use it has to be phrased as something to pass on, or it reads as "not for you" and
202
222
  * dies there.
203
223
  */
204
224
  function terminalSurfaceCheck() {
@@ -207,6 +227,7 @@ function terminalSurfaceCheck() {
207
227
  return {
208
228
  name: "terminal surface",
209
229
  ok: true,
230
+ ...(supported && bundlePresent ? {} : { status: "note" }),
210
231
  message: terminalSurfaceMessage({
211
232
  supported,
212
233
  bundlePresent,
@@ -237,25 +258,59 @@ async function probeDoctorKeys(cwd, env, lab, keyDeps) {
237
258
  return { probes, receivingKey };
238
259
  }
239
260
  /**
240
- * Provider-key discovery (#436): which source supplies each live-run key, through the same
261
+ * The operator's own coding agents, one row each, reported as a capability and never a gate: a
262
+ * machine with none is not broken, it just needs a provider key. These rows exist because "go make
263
+ * an API key" is where most people trying humanish stop, and a developer very often already has one
264
+ * of these signed in. An agent that is installed but not signed in is a note.
265
+ */
266
+ function localAgentChecks(agents) {
267
+ if (agents.length === 0)
268
+ return [{ name: "local agents", ok: true, message: NO_LOCAL_AGENT_MESSAGE }];
269
+ return agents.map((agent) => ({
270
+ name: `local agent ${agent.bin}`,
271
+ ok: true,
272
+ ...(agent.authStatus === "authenticated" ? {} : { status: "note" }),
273
+ message: localAgentDoctorMessage(agent),
274
+ }));
275
+ }
276
+ /** "try-live", "try-live and local-browser", "a, b and c". */
277
+ function studyList(studies) {
278
+ return studies.length < 2
279
+ ? studies.join("")
280
+ : `${studies.slice(0, -1).join(", ")} and ${studies.at(-1)}`;
281
+ }
282
+ /**
283
+ * Provider-key discovery: which source supplies each live-run key, through the same
241
284
  * chain a live command resolves (env/--env-file, project overlay, vendor stores, the
242
285
  * humanish user store). Values never appear; sources and fill commands do.
286
+ *
287
+ * With --lab, a key the selected route requires fails when missing. Without it, `keyUsers` maps
288
+ * each key to the project's labs that need it, and a key row never fails: a missing key one of
289
+ * them needs is a note.
243
290
  */
244
- function keyChecks(probes, receivingKey, setup, agents) {
291
+ function keyChecks(probes, receivingKey, setup, keyUsers) {
245
292
  return probes.map((probe) => {
246
293
  const present = probe.source !== null;
247
294
  const hint = probe.name === receivingKey
248
295
  ? `provide ${probe.name} through process env or --env-file`
249
296
  : probe.hint;
297
+ if (!setup) {
298
+ const users = keyUsers?.get(probe.name) ?? [];
299
+ const usedBy = users.length > 0 ? `used by ${studyList(users)}` : undefined;
300
+ return {
301
+ name: `key ${probe.name}`,
302
+ ok: true,
303
+ ...(present || usedBy === undefined ? {} : { status: "note" }),
304
+ message: present
305
+ ? `supplied by ${probe.source}; presence only, validity not tested${usedBy ? `; ${usedBy}` : ""}`
306
+ : `missing; ${usedBy ?? "not used by any lab in this project"}; ${hint}`,
307
+ };
308
+ }
250
309
  // GH_TOKEN is needed only for private clone subjects, so its absence is informational.
251
- const required = setup
252
- ? setup.keys.includes(probe.name)
253
- : probe.name === "E2B_API_KEY" ||
254
- (probe.name === "OPENAI_API_KEY" &&
255
- !agents.some((agent) => agent.authStatus === "authenticated"));
310
+ const required = setup.keys.includes(probe.name);
256
311
  // A key the lab is known not to read says so, so a present but unused key does not read as
257
312
  // one the run will use.
258
- const unused = setup?.reads !== undefined && !setup.reads.has(probe.name);
313
+ const unused = setup.reads !== undefined && !setup.reads.has(probe.name);
259
314
  return {
260
315
  name: `key ${probe.name}`,
261
316
  ok: present || !required,
@@ -264,8 +319,8 @@ function keyChecks(probes, receivingKey, setup, agents) {
264
319
  ? `present (${probe.source}), not used by this lab`
265
320
  : `supplied by ${probe.source}; presence only, validity not tested`
266
321
  : required
267
- ? `missing from every source — ${hint}`
268
- : `not required for ${setup ? "the selected participant route" : "every route"}; ${hint}`,
322
+ ? `missing from every source; ${hint}`
323
+ : `not required for the selected participant route; ${hint}`,
269
324
  };
270
325
  });
271
326
  }
@@ -8,23 +8,23 @@ export interface FirstRunEnvironment {
8
8
  /** A sandbox to run the study in. Nothing live happens without it. */
9
9
  hasE2bKey: boolean;
10
10
  /**
11
- * Whether `@e2b/desktop` resolves from this project. It is an OPTIONAL peer — the no-keys path
12
- * does not need it — so a fresh `npx humanish` install does not have it, and a live run stops
11
+ * Whether `@e2b/desktop` resolves from this project. It is an optional peer: the no-keys path
12
+ * does not need it, so a fresh `npx humanish` install does not have it, and a live run stops
13
13
  * with "install this other package first". Found by running the published artifact cold, after
14
14
  * two local runs passed because they resolved the peer from the repo's own node_modules.
15
15
  */
16
16
  hasDesktopSdk: boolean;
17
17
  /**
18
18
  * Whether humanish itself is installed in this project rather than running from an npx cache.
19
- * It changes what advice is TRUE: a one-shot `npx humanish` resolves its optional peer relative
20
- * to itself, so "install the peer here" cannot work — humanish has to be installed alongside it.
19
+ * It changes what advice is true: a one-shot `npx humanish` resolves its optional peer relative
20
+ * to itself, so "install the peer here" cannot work; humanish has to be installed alongside it.
21
21
  */
22
22
  installedInProject: boolean;
23
23
  /** A provider API key for the model. */
24
24
  hasProviderKey: boolean;
25
25
  /** The coding agents already signed in locally: Codex, Claude Code, or both. */
26
26
  localAgents: readonly SignedInAgent[];
27
- /** Host shape only; `doctor --lab local-browser` owns exact read-only readiness. */
27
+ /** Host shape only; `doctor --study local-browser` owns exact read-only readiness. */
28
28
  platform?: NodeJS.Platform;
29
29
  arch?: string;
30
30
  }
@@ -32,7 +32,7 @@ export type FirstRunActor = "openai-computer-use" | "local-agent";
32
32
  /**
33
33
  * Which brain the starter live lab should be written for. A machine with a signed-in coding agent
34
34
  * and no provider key can still do a real live run; writing the lab for the credential the
35
- * operator DOESN'T have is how a starter file becomes homework.
35
+ * operator doesn't have is how a starter file becomes homework.
36
36
  */
37
37
  export declare function starterActorFor(env: FirstRunEnvironment): FirstRunActor;
38
38
  /**
@@ -40,6 +40,8 @@ export declare function starterActorFor(env: FirstRunEnvironment): FirstRunActor
40
40
  * refuse to run on a machine where only Claude Code is signed in.
41
41
  */
42
42
  export declare function starterLocalAgentFor(env: FirstRunEnvironment): LocalAgentId | undefined;
43
+ /** Hosts the local browser lab runs on: Linux x64 and Apple Silicon Macs. */
44
+ export declare function supportsLocalBrowser(platform: NodeJS.Platform | undefined, arch: string | undefined): boolean;
43
45
  export interface FirstRunStep {
44
46
  /** The exact command to run. */
45
47
  command: string;
@@ -47,7 +49,7 @@ export interface FirstRunStep {
47
49
  why: string;
48
50
  }
49
51
  /**
50
- * The next one or two commands, in order. Deliberately SHORT: a list of twelve options is the same
52
+ * The next one or two commands, in order. Deliberately short: a list of twelve options is the same
51
53
  * as no guidance, and the reader here has just been handed twenty files.
52
54
  */
53
55
  export declare function firstRunSteps(env: FirstRunEnvironment): FirstRunStep[];
@@ -56,12 +58,12 @@ export declare function firstRunGuidance(env: FirstRunEnvironment): string[];
56
58
  /** Lets init recognise its own section without rewriting a file someone else wrote. */
57
59
  export declare const AGENTS_SECTION_MARKER = "<!-- humanish:agents-guide -->";
58
60
  /**
59
- * What the NEXT coding agent needs to know about humanish in this project.
61
+ * What the next coding agent needs to know about humanish in this project.
60
62
  *
61
- * AGENTS.md is the cross-vendor convention (agents.md) that Codex, Claude Code, Cursor and others
63
+ * `AGENTS.md` is the cross-vendor convention (agents.md) that Codex, Claude Code, Cursor and others
62
64
  * read on arrival. Increasingly the thing that ran `humanish init` was itself an agent working for
63
65
  * someone, and the agent that shows up tomorrow finds a `humanish/` directory with no idea what it
64
- * is for. Deliberately SHORT and command-first: an agent acts on commands, not on prose.
66
+ * is for. Deliberately short and command-first, because an agent acts on the commands it is given.
65
67
  */
66
68
  export declare function agentsSection(): string;
67
69
  export {};
@@ -1,21 +1,21 @@
1
- // What a person — or the coding agent setting humanish up for them — should do NEXT.
1
+ // What a person, or the coding agent setting humanish up for them, should do next.
2
2
  //
3
- // WHY: `humanish init` wrote twenty files and stopped. The only lab that could actually run was a
3
+ // Why: `humanish init` wrote twenty files and stopped. The only lab that could actually run was a
4
4
  // $0 dry run; the two live ones were templates with `your-org/your-app` in them, so the first live
5
5
  // run a newcomer tried could not succeed no matter what credentials they had. Three independent
6
- // sources reached the same place — a participant in our own TUI study walked to the Start row and
6
+ // sources reached the same place: a participant in our own TUI study walked to the Start row and
7
7
  // found a placeholder URL, an adoption review concluded "the funnel is broken at the first live
8
8
  // run", and the release-gate participant said, unprompted, "validate one paid live study before
9
- // committing" (#505).
9
+ // committing".
10
10
  //
11
11
  // The fix is not more surface. Increasingly the thing running `init` is a coding agent acting for
12
12
  // someone, and an agent reads stdout and does what it says. So init ends by naming the next
13
- // command — and names the one that will actually work ON THIS MACHINE, because a next step that
13
+ // command, and names the one that will actually work on this machine, because a next step that
14
14
  // fails is worse than none.
15
15
  /**
16
16
  * Which brain the starter live lab should be written for. A machine with a signed-in coding agent
17
17
  * and no provider key can still do a real live run; writing the lab for the credential the
18
- * operator DOESN'T have is how a starter file becomes homework.
18
+ * operator doesn't have is how a starter file becomes homework.
19
19
  */
20
20
  export function starterActorFor(env) {
21
21
  if (!env.hasProviderKey && env.localAgents.length > 0)
@@ -35,29 +35,31 @@ export function starterLocalAgentFor(env) {
35
35
  }
36
36
  /**
37
37
  * How each hint invokes the CLI. \`npx humanish\` works from a project install and from an npx cache;
38
- * a dev-dependency install puts no \`humanish\` on PATH, so a bare name can reach a stale global one.
38
+ * a dev-dependency install puts no \`humanish\` on \`PATH\`, so a bare name can reach a stale global one.
39
39
  */
40
40
  const HUMANISH = "npx humanish";
41
+ /** Hosts the local browser lab runs on: Linux x64 and Apple Silicon Macs. */
42
+ export function supportsLocalBrowser(platform, arch) {
43
+ return (platform === "linux" && arch === "x64") || (platform === "darwin" && arch === "arm64");
44
+ }
41
45
  /**
42
- * The next one or two commands, in order. Deliberately SHORT: a list of twelve options is the same
46
+ * The next one or two commands, in order. Deliberately short: a list of twelve options is the same
43
47
  * as no guidance, and the reader here has just been handed twenty files.
44
48
  */
45
49
  export function firstRunSteps(env) {
46
50
  const steps = [
47
51
  {
48
52
  command: `${HUMANISH} run first-run`,
49
- why: "an evidence preview: no browser or model runs, no keys, no spend",
53
+ why: "a dry run: no browser or model runs, no keys, no spend",
50
54
  },
51
55
  ];
52
- const localPlatform = (env.platform === "linux" && env.arch === "x64") ||
53
- (env.platform === "darwin" && env.arch === "arm64");
54
- if (localPlatform) {
56
+ if (supportsLocalBrowser(env.platform, env.arch)) {
55
57
  const prerequisites = env.platform === "darwin"
56
58
  ? "M3-or-newer Mac, native ARM64 Node, Lima 2.2+, and a supported signed-in Codex CLI"
57
59
  : "local rootful Docker, KVM, TUN, and a supported signed-in Codex CLI";
58
60
  steps.push({
59
- command: `${HUMANISH} doctor --lab local-browser`,
60
- why: `check the local browser lab (${prerequisites}); no resources or quota used. Run \`${HUMANISH} runtime setup\` to prepare it, then start your app and run \`${HUMANISH} run local-browser\`; no E2B or model API key`,
61
+ command: `${HUMANISH} doctor --study local-browser`,
62
+ why: `check the local browser study (${prerequisites}); no resources or quota used. Run \`${HUMANISH} runtime setup\` to prepare it, then start your app and run \`${HUMANISH} run local-browser\`; no E2B or model API key`,
61
63
  });
62
64
  return steps;
63
65
  }
@@ -74,7 +76,7 @@ export function firstRunSteps(env) {
74
76
  if (env.hasProviderKey || env.localAgents.length > 0) {
75
77
  const brain = env.hasProviderKey
76
78
  ? "your provider key"
77
- : `${preferredAgent(env)?.label} (already signed in — no API key needed)`;
79
+ : `${preferredAgent(env)?.label} (already signed in, so no API key is needed)`;
78
80
  // Everything the step needs, in one line. Splitting it across two commands means the second
79
81
  // one fails, which is the same dead end this guidance exists to remove.
80
82
  const command = env.hasDesktopSdk
@@ -86,7 +88,7 @@ export function firstRunSteps(env) {
86
88
  `npm i -D humanish @e2b/desktop && ${HUMANISH} run try-live`;
87
89
  steps.push({
88
90
  command,
89
- why: `a REAL study: one participant drives a real app in a hosted desktop, using ${brain}` +
91
+ why: `a live study: one participant drives a real app in a hosted desktop, using ${brain}` +
90
92
  (env.hasDesktopSdk ? "" : " (the desktop SDK is an optional peer, so it installs first)") +
91
93
  (!env.hasProviderKey
92
94
  ? "; automatic findings analysis is skipped without OPENAI_API_KEY"
@@ -110,12 +112,12 @@ export function firstRunGuidance(env) {
110
112
  /** Lets init recognise its own section without rewriting a file someone else wrote. */
111
113
  export const AGENTS_SECTION_MARKER = "<!-- humanish:agents-guide -->";
112
114
  /**
113
- * What the NEXT coding agent needs to know about humanish in this project.
115
+ * What the next coding agent needs to know about humanish in this project.
114
116
  *
115
- * AGENTS.md is the cross-vendor convention (agents.md) that Codex, Claude Code, Cursor and others
117
+ * `AGENTS.md` is the cross-vendor convention (agents.md) that Codex, Claude Code, Cursor and others
116
118
  * read on arrival. Increasingly the thing that ran `humanish init` was itself an agent working for
117
119
  * someone, and the agent that shows up tomorrow finds a `humanish/` directory with no idea what it
118
- * is for. Deliberately SHORT and command-first: an agent acts on commands, not on prose.
120
+ * is for. Deliberately short and command-first, because an agent acts on the commands it is given.
119
121
  */
120
122
  export function agentsSection() {
121
123
  return [
@@ -125,22 +127,22 @@ export function agentsSection() {
125
127
  "This project uses humanish: synthetic participants use the product and leave evidence.",
126
128
  "",
127
129
  "```bash",
128
- "humanish doctor --lab try-live # requirements for the selected participant and analysis",
129
- "humanish lab list --json # the labs in this project",
130
- "humanish run first-run # evidence preview only: no browser, model, keys, or spend",
131
- "humanish doctor --lab local-browser # local Docker/Firecracker + Codex-account readiness",
130
+ "humanish doctor --study try-live # requirements for the selected participant and analysis",
131
+ "humanish study list --json # the studies in this project",
132
+ "humanish run first-run # dry run: no browser, model, keys, or spend",
133
+ "humanish doctor --study local-browser # local Docker/Firecracker + Codex-account readiness",
132
134
  "humanish run local-browser # your loopback app; no E2B or model API key",
133
135
  "humanish run try-live # demo app study: E2B plus the selected participant's authentication",
134
136
  "humanish verify --run latest --json # is the evidence share-safe",
135
137
  "```",
136
138
  "",
137
- "- Labs are declared in `humanish/labs/*.yaml`. Edit `try-live.yaml`'s `subject` to point at",
138
- " this project's own app once you have seen a run work.",
139
- "- Configure the local lab without editing YAML: `humanish init --yes --local-browser",
139
+ "- Studies are declared in `humanish/studies/*.yaml`. Edit `try-live.yaml`'s `subject` to point",
140
+ " at this project's own app once you have seen a run work.",
141
+ "- Configure the local study without editing YAML: `humanish init --yes --local-browser",
140
142
  ' http://127.0.0.1:3000 --local-mission "Complete the primary flow"` on first setup.',
141
143
  "- Evidence lands in gitignored `.humanish/runs/`. Never commit it, and never paste raw run",
142
- " bundles into an issue — `humanish feedback issue` produces a redacted, share-safe draft.",
143
- "- `humanish tui` is a HUMAN surface and refuses to run in an agent session. Use the `--json`",
144
+ " bundles into an issue; `humanish feedback issue` writes a redacted, share-safe draft.",
145
+ "- `humanish tui` is for people and refuses to run in an agent session. Use the `--json`",
144
146
  " commands above instead, and tell the person you are working for that `humanish tui` exists.",
145
147
  "- A live run spends money. `execution.caps.maxUsd` in each lab caps estimated model spend: the run",
146
148
  " stops before its next request once the estimate passes it, so the last request can go over, and",
package/dist/cli/io.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Command } from "commander";
1
+ import { Command, Option } from "commander";
2
2
  import { discoverProviderKeys } from "../keys/key-resolution.js";
3
3
  import { type TelemetryProperties } from "./telemetry.js";
4
4
  import type { RunResult } from "../run/results.js";
@@ -11,6 +11,12 @@ export interface CliIo {
11
11
  keyDiscovery?: typeof discoverProviderKeys;
12
12
  }
13
13
  export declare const JSON_OPTION_DESCRIPTION = "Print a machine-readable JSON response.";
14
+ export declare const CWD_OPTION_DESCRIPTION = "Project directory.";
15
+ export declare const RUN_OPTION_DESCRIPTION = "Run id, or latest.";
16
+ export declare const ENV_FILE_OPTION_DESCRIPTION = "Load unset variables from this env file. Values are never printed or saved.";
17
+ export declare const PORT_OPTION_DESCRIPTION = "Port to listen on at 127.0.0.1.";
18
+ /** `--port` for a loopback server whose default, 0, lets the OS pick a free port. */
19
+ export declare function freePortOption(): Option;
14
20
  export interface LabCommandOptions {
15
21
  count?: string | undefined;
16
22
  cwd: string;
@@ -23,7 +29,7 @@ export interface LabCommandOptions {
23
29
  port?: string | undefined;
24
30
  rerunFailedFrom?: string | undefined;
25
31
  runId?: string | undefined;
26
- /** #316: repo-relative path to an adopter scorer module; overrides review.scorer.ref when set. */
32
+ /** Repo-relative path to an adopter scorer module; overrides review.scorer.ref when set. */
27
33
  scorer?: string | undefined;
28
34
  expose?: boolean | undefined;
29
35
  tunnel?: "ngrok" | undefined;
@@ -48,7 +54,7 @@ export declare function applyEnvFileOption(args: {
48
54
  discoverKeys?: boolean;
49
55
  }): Promise<boolean>;
50
56
  /**
51
- * Provider-key discovery (#436): fill still-missing keys from the documented project overlay, the
57
+ * Provider-key discovery: fill still-missing keys from the documented project overlay, the
52
58
  * owning vendors' native stores, and the humanish user store. It is fill-only (an explicit
53
59
  * --env-file or process env always wins), and each fill is announced by name and source on
54
60
  * stderr, never by value. HUMANISH_STRICT_KEYS=1 restores env-only behavior.
@@ -63,11 +69,36 @@ export declare function discoverCliKeys(args: {
63
69
  }): Promise<void>;
64
70
  export declare function parseLabCount(value: string | undefined, fallback: number): number | null;
65
71
  export declare function parseParticipantIds(value: string | undefined): string[];
66
- export declare function writeResult<T>(command: Command, io: CliIo, result: T, formatHuman: (result: T) => string): void;
72
+ /** An error as a result carries it. A result with only a message, such as keys or comms, has no code. */
73
+ export interface CliError {
74
+ code?: string;
75
+ message: string;
76
+ }
77
+ /**
78
+ * What a human formatter prints: text for stdout, or stdout lines plus an error that writeResult
79
+ * prints on stderr through formatCliError. --json output never goes through it.
80
+ */
81
+ export type HumanOutput = string | {
82
+ stdout?: string;
83
+ error?: CliError | undefined;
84
+ };
85
+ /** `<command> failed: <message>`, then `code: <CODE>`, then `next: <command>` when one is known. */
86
+ export declare function formatCliError(command: string, error: CliError): string;
87
+ /** A result whose human output is its message: stdout when it passed, stderr when it failed. */
88
+ export declare function messageOutput(value: {
89
+ ok: boolean;
90
+ message: string;
91
+ }): HumanOutput;
92
+ /** A failed result's human output: its error on stderr and nothing on stdout. */
93
+ export declare function humanError(error: CliError | undefined): HumanOutput;
94
+ /** Prints a human formatter's output: text to stdout, an error to stderr through formatCliError. */
95
+ export declare function writeHuman(command: Command, io: CliIo, human: HumanOutput): void;
96
+ export declare function writeResult<T>(command: Command, io: CliIo, result: T, formatHuman: (result: T) => HumanOutput): void;
67
97
  export declare function noteRunFacts(command: Command, facts: TelemetryProperties): void;
68
98
  /** Exported for tests: the facts writeResult read off a command's result document. */
69
99
  export declare function runFactsFor(command: Command): TelemetryProperties;
70
- export declare function formatRunHuman(result: RunResult): string;
100
+ /** A run result, or the preview route's study result: they differ only in `schema`. */
101
+ export declare function formatRunHuman(result: Omit<RunResult, "schema">): HumanOutput;
71
102
  export declare function parsePositiveInteger(value: string): number | null;
72
103
  export declare function parseTimeoutMs(value: string): number | null;
73
104
  export declare function parseObserverPort(value: string): number | null;
@@ -81,6 +112,10 @@ export declare function candidateOption(options: {
81
112
  analysis?: string;
82
113
  finding?: string;
83
114
  };
84
- export declare function collectRepeated(value: string, previous: string[]): string[];
115
+ export declare function collectRepeated(value: string, previous?: string[]): string[];
85
116
  export declare function wantsJson(command: Command): boolean;
117
+ export declare function analysisOutcomeText(analysis: {
118
+ state: string;
119
+ reason: string | null;
120
+ }): string;
86
121
  export declare function automaticAnalysisEnvelope<T>(result: T): T;