humanish 0.106.1 → 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 (668) hide show
  1. package/ARCHITECTURE.md +38 -32
  2. package/CHANGELOG.md +28 -0
  3. package/CONTEXT.md +51 -41
  4. package/README.md +152 -174
  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-client.js +2 -1
  14. package/dist/actors/codex/app-server-trace.d.ts +0 -1
  15. package/dist/actors/codex/app-server-trace.js +1 -3
  16. package/dist/actors/codex/app-server-ui.js +1 -1
  17. package/dist/actors/codex/app-server.js +2 -1
  18. package/dist/actors/codex/codex-admission.d.ts +91 -0
  19. package/dist/actors/codex/codex-admission.js +150 -0
  20. package/dist/actors/codex/protocol-compat.d.ts +27 -0
  21. package/dist/actors/codex/protocol-compat.js +357 -0
  22. package/dist/actors/codex/protocol-contract.d.ts +61 -0
  23. package/dist/actors/codex/protocol-contract.js +471 -0
  24. package/dist/actors/codex/restricted-executable.d.ts +28 -4
  25. package/dist/actors/codex/restricted-executable.js +104 -29
  26. package/dist/actors/codex/restricted-launch.d.ts +9 -2
  27. package/dist/actors/codex/restricted-launch.js +43 -4
  28. package/dist/actors/codex/restricted-notifications.d.ts +101 -0
  29. package/dist/actors/codex/restricted-notifications.js +277 -0
  30. package/dist/actors/codex/restricted-participant.d.ts +30 -0
  31. package/dist/actors/codex/restricted-participant.js +66 -6
  32. package/dist/actors/codex/restricted-policy.d.ts +11 -3
  33. package/dist/actors/codex/restricted-policy.js +2 -2
  34. package/dist/actors/codex/restricted-session.d.ts +16 -3
  35. package/dist/actors/codex/restricted-session.js +60 -22
  36. package/dist/actors/codex/restricted-transport.d.ts +29 -0
  37. package/dist/actors/codex/restricted-transport.js +139 -27
  38. package/dist/actors/codex/restricted-turn.d.ts +19 -4
  39. package/dist/actors/codex/restricted-turn.js +43 -30
  40. package/dist/actors/computer-use/actor.d.ts +17 -17
  41. package/dist/actors/computer-use/actor.js +6 -6
  42. package/dist/actors/computer-use/admission-limit.d.ts +1 -1
  43. package/dist/actors/computer-use/admission-limit.js +1 -1
  44. package/dist/actors/computer-use/loop/actions.d.ts +3 -3
  45. package/dist/actors/computer-use/loop/actions.js +10 -10
  46. package/dist/actors/computer-use/loop/backstop.d.ts +3 -3
  47. package/dist/actors/computer-use/loop/backstop.js +15 -13
  48. package/dist/actors/computer-use/loop/ending.d.ts +7 -7
  49. package/dist/actors/computer-use/loop/ending.js +9 -9
  50. package/dist/actors/computer-use/loop/observation.d.ts +2 -2
  51. package/dist/actors/computer-use/loop/observation.js +9 -9
  52. package/dist/actors/computer-use/loop/provider-call.d.ts +1 -1
  53. package/dist/actors/computer-use/loop/provider-call.js +1 -1
  54. package/dist/actors/computer-use/loop/session.js +3 -3
  55. package/dist/actors/computer-use/loop/spend.d.ts +2 -2
  56. package/dist/actors/computer-use/loop/spend.js +4 -4
  57. package/dist/actors/computer-use/loop/trace.js +11 -10
  58. package/dist/actors/computer-use/loop/types.d.ts +37 -26
  59. package/dist/actors/computer-use/loop/usage.js +2 -2
  60. package/dist/actors/computer-use/loop.js +4 -4
  61. package/dist/actors/computer-use/openai-context.d.ts +37 -0
  62. package/dist/actors/computer-use/openai-context.js +214 -0
  63. package/dist/actors/computer-use/openai-provider.d.ts +12 -9
  64. package/dist/actors/computer-use/openai-provider.js +47 -36
  65. package/dist/actors/computer-use/openai-requests.d.ts +36 -10
  66. package/dist/actors/computer-use/openai-requests.js +82 -15
  67. package/dist/actors/computer-use/openai-wire.d.ts +19 -7
  68. package/dist/actors/computer-use/openai-wire.js +36 -34
  69. package/dist/actors/contract.d.ts +86 -49
  70. package/dist/actors/contract.js +29 -23
  71. package/dist/actors/local-agent/claude-session.d.ts +1 -1
  72. package/dist/actors/local-agent/claude-session.js +10 -9
  73. package/dist/actors/local-agent/cli.d.ts +8 -6
  74. package/dist/actors/local-agent/cli.js +24 -28
  75. package/dist/actors/local-agent/readiness.d.ts +2 -2
  76. package/dist/actors/local-agent/readiness.js +4 -4
  77. package/dist/actors/reasoning-effort.js +6 -6
  78. package/dist/actors/registry.d.ts +10 -10
  79. package/dist/actors/registry.js +18 -17
  80. package/dist/actors/scripted-browser/actor.d.ts +8 -8
  81. package/dist/actors/scripted-browser/actor.js +16 -16
  82. package/dist/actors/scripted-browser/browser-command.js +1 -1
  83. package/dist/actors/scripted-browser/journey.js +15 -4
  84. package/dist/actors/scripted-browser/steps.js +19 -1
  85. package/dist/actors/scripted-browser/types.d.ts +12 -2
  86. package/dist/actors/stop-conditions.d.ts +1 -1
  87. package/dist/actors/stop-conditions.js +1 -3
  88. package/dist/analysis/automatic-completion.d.ts +13 -8
  89. package/dist/analysis/automatic-completion.js +14 -8
  90. package/dist/analysis/automatic-config.d.ts +1 -1
  91. package/dist/analysis/automatic-config.js +2 -2
  92. package/dist/analysis/automatic.d.ts +10 -4
  93. package/dist/analysis/automatic.js +17 -13
  94. package/dist/analysis/codex-config.d.ts +6 -2
  95. package/dist/analysis/codex-config.js +22 -14
  96. package/dist/analysis/diagnostics.d.ts +23 -0
  97. package/dist/analysis/diagnostics.js +112 -0
  98. package/dist/analysis/evidence-sources.js +2 -2
  99. package/dist/analysis/evidence.js +6 -6
  100. package/dist/analysis/execute.d.ts +7 -1
  101. package/dist/analysis/execute.js +39 -12
  102. package/dist/analysis/job.d.ts +8 -5
  103. package/dist/analysis/job.js +15 -14
  104. package/dist/analysis/load.d.ts +1 -1
  105. package/dist/analysis/load.js +5 -5
  106. package/dist/analysis/provider.d.ts +9 -1
  107. package/dist/analysis/restricted-codex.d.ts +2 -0
  108. package/dist/analysis/restricted-codex.js +10 -1
  109. package/dist/analysis/service.d.ts +2 -0
  110. package/dist/analysis/service.js +35 -16
  111. package/dist/analysis/sharing.d.ts +2 -2
  112. package/dist/analysis/sharing.js +5 -5
  113. package/dist/analysis/store-executions.d.ts +5 -5
  114. package/dist/analysis/store-executions.js +12 -12
  115. package/dist/analysis/store.d.ts +4 -4
  116. package/dist/analysis/store.js +13 -13
  117. package/dist/cli/commands/analysis-signals.d.ts +2 -1
  118. package/dist/cli/commands/analysis-signals.js +4 -1
  119. package/dist/cli/commands/analyze.js +23 -18
  120. package/dist/cli/commands/codex.js +9 -9
  121. package/dist/cli/commands/comms.js +62 -34
  122. package/dist/cli/commands/feedback.js +20 -21
  123. package/dist/cli/commands/lab-format.d.ts +5 -4
  124. package/dist/cli/commands/lab-format.js +35 -23
  125. package/dist/cli/commands/lab-route-computer-use.d.ts +0 -2
  126. package/dist/cli/commands/lab-route-computer-use.js +32 -21
  127. package/dist/cli/commands/lab-route-preview.d.ts +1 -3
  128. package/dist/cli/commands/lab-route-preview.js +7 -7
  129. package/dist/cli/commands/lab-route-run.d.ts +6 -4
  130. package/dist/cli/commands/lab-route-run.js +6 -2
  131. package/dist/cli/commands/lab-route-scripted.d.ts +0 -2
  132. package/dist/cli/commands/lab-route-scripted.js +0 -1
  133. package/dist/cli/commands/lab-route-shared-world.d.ts +0 -2
  134. package/dist/cli/commands/lab-route-shared-world.js +3 -4
  135. package/dist/cli/commands/lab-route-terminal.d.ts +0 -2
  136. package/dist/cli/commands/lab-route-terminal.js +0 -1
  137. package/dist/cli/commands/lab-run.js +84 -54
  138. package/dist/cli/commands/lab-scorer.d.ts +2 -4
  139. package/dist/cli/commands/lab-scorer.js +1 -1
  140. package/dist/cli/commands/migrate.d.ts +4 -0
  141. package/dist/cli/commands/migrate.js +65 -0
  142. package/dist/cli/commands/observe.js +168 -107
  143. package/dist/cli/commands/run-command.d.ts +10 -0
  144. package/dist/cli/commands/run-command.js +85 -0
  145. package/dist/cli/commands/run-signals.d.ts +30 -0
  146. package/dist/cli/commands/run-signals.js +146 -0
  147. package/dist/cli/commands/runs.js +137 -136
  148. package/dist/cli/commands/setup.d.ts +2 -2
  149. package/dist/cli/commands/setup.js +26 -21
  150. package/dist/cli/commands/study.d.ts +3 -0
  151. package/dist/cli/commands/study.js +182 -0
  152. package/dist/cli/commands/tui.d.ts +4 -4
  153. package/dist/cli/commands/tui.js +21 -21
  154. package/dist/cli/commands/watch.js +64 -77
  155. package/dist/cli/deprecations.d.ts +18 -0
  156. package/dist/cli/deprecations.js +48 -0
  157. package/dist/cli/doctor.d.ts +18 -5
  158. package/dist/cli/doctor.js +111 -48
  159. package/dist/cli/first-run-path.d.ts +12 -10
  160. package/dist/cli/first-run-path.js +30 -28
  161. package/dist/cli/io.d.ts +46 -10
  162. package/dist/cli/io.js +109 -30
  163. package/dist/cli/observer-follow.d.ts +2 -2
  164. package/dist/cli/observer-follow.js +5 -6
  165. package/dist/cli/orientation.d.ts +6 -3
  166. package/dist/cli/orientation.js +43 -39
  167. package/dist/cli/product-sentence.d.ts +6 -0
  168. package/dist/cli/product-sentence.js +6 -0
  169. package/dist/cli/program.d.ts +6 -1
  170. package/dist/cli/program.js +112 -43
  171. package/dist/cli/telemetry.d.ts +17 -17
  172. package/dist/cli/telemetry.js +49 -41
  173. package/dist/cli.js +1 -1
  174. package/dist/comms/capture-surface.d.ts +14 -13
  175. package/dist/comms/capture-surface.js +23 -22
  176. package/dist/comms/catch-host.d.ts +8 -8
  177. package/dist/comms/catch-host.js +14 -14
  178. package/dist/comms/connections.js +4 -4
  179. package/dist/comms/email-catch.d.ts +3 -3
  180. package/dist/comms/email-catch.js +8 -8
  181. package/dist/comms/external-evidence.d.ts +27 -0
  182. package/dist/comms/external-evidence.js +93 -0
  183. package/dist/comms/extract.js +2 -2
  184. package/dist/comms/fake-inbox.d.ts +2 -2
  185. package/dist/comms/fake-inbox.js +2 -2
  186. package/dist/comms/lease-store.js +7 -7
  187. package/dist/comms/receiving-render.d.ts +1 -1
  188. package/dist/comms/receiving-render.js +2 -2
  189. package/dist/comms/sandbox-catch-script.d.ts +6 -6
  190. package/dist/comms/sandbox-catch-script.js +6 -6
  191. package/dist/comms/sandbox-catch.d.ts +36 -37
  192. package/dist/comms/sandbox-catch.js +34 -35
  193. package/dist/comms/setup.js +42 -8
  194. package/dist/comms/thread-evidence.d.ts +1 -1
  195. package/dist/comms/thread-evidence.js +6 -6
  196. package/dist/comms/types.d.ts +6 -6
  197. package/dist/comms/types.js +4 -4
  198. package/dist/evidence/browser-hygiene.d.ts +1 -1
  199. package/dist/evidence/browser-hygiene.js +1 -1
  200. package/dist/evidence/frame-signature.d.ts +1 -1
  201. package/dist/evidence/frame-signature.js +4 -4
  202. package/dist/evidence/redaction.d.ts +3 -3
  203. package/dist/evidence/redaction.js +5 -5
  204. package/dist/evidence/secret-scrub.d.ts +9 -0
  205. package/dist/evidence/secret-scrub.js +96 -0
  206. package/dist/feedback/draft.js +41 -85
  207. package/dist/feedback/export-bundle.js +5 -5
  208. package/dist/feedback/export.d.ts +5 -1
  209. package/dist/feedback/export.js +16 -17
  210. package/dist/feedback/feedback.d.ts +3 -3
  211. package/dist/feedback/feedback.js +21 -3
  212. package/dist/guest/chromium-text.js +2 -2
  213. package/dist/guest/desktop-native.d.ts +1 -1
  214. package/dist/guest/runtime.js +1 -1
  215. package/dist/index.d.ts +14 -15
  216. package/dist/index.js +10 -11
  217. package/dist/keys/key-resolution.d.ts +7 -5
  218. package/dist/keys/key-resolution.js +40 -38
  219. package/dist/lab/adapter-extension.d.ts +35 -13
  220. package/dist/lab/adapter-extension.js +50 -134
  221. package/dist/lab/adapter-scorer-loader.d.ts +32 -12
  222. package/dist/lab/adapter-scorer-loader.js +56 -32
  223. package/dist/lab/composition-rules.js +58 -58
  224. package/dist/lab/config.js +85 -43
  225. package/dist/lab/deprecated-fields.d.ts +10 -0
  226. package/dist/lab/deprecated-fields.js +24 -0
  227. package/dist/lab/device-presets.d.ts +10 -10
  228. package/dist/lab/device-presets.js +11 -11
  229. package/dist/lab/discover.d.ts +13 -9
  230. package/dist/lab/discover.js +118 -60
  231. package/dist/lab/doctor.d.ts +53 -11
  232. package/dist/lab/doctor.js +193 -47
  233. package/dist/lab/init-plan.js +1 -3
  234. package/dist/lab/init-templates.js +147 -147
  235. package/dist/lab/init.d.ts +1 -1
  236. package/dist/lab/init.js +41 -9
  237. package/dist/lab/keys.d.ts +2 -0
  238. package/dist/lab/keys.js +43 -9
  239. package/dist/lab/lab-deps.d.ts +80 -0
  240. package/dist/lab/lab-deps.js +4 -0
  241. package/dist/lab/parse/actors.js +17 -16
  242. package/dist/lab/parse/comms.js +8 -7
  243. package/dist/lab/parse/execution.js +15 -14
  244. package/dist/lab/parse/study-v3.d.ts +23 -0
  245. package/dist/lab/parse/study-v3.js +259 -0
  246. package/dist/lab/parse/subject-state.d.ts +7 -7
  247. package/dist/lab/parse/subject-state.js +18 -17
  248. package/dist/lab/parse/subject.js +30 -29
  249. package/dist/lab/parse/values.d.ts +1 -2
  250. package/dist/lab/parse/values.js +3 -6
  251. package/dist/lab/persona-resolve.d.ts +7 -7
  252. package/dist/lab/persona-resolve.js +8 -8
  253. package/dist/lab/persona.js +1 -3
  254. package/dist/lab/plan-base.d.ts +0 -2
  255. package/dist/lab/plan-base.js +6 -4
  256. package/dist/lab/plan-participants.d.ts +7 -7
  257. package/dist/lab/plan-participants.js +2 -2
  258. package/dist/lab/plan-types.d.ts +26 -8
  259. package/dist/lab/plan.d.ts +4 -18
  260. package/dist/lab/plan.js +24 -79
  261. package/dist/lab/preflight-probes.js +11 -11
  262. package/dist/lab/preflight-result.d.ts +2 -1
  263. package/dist/lab/preflight-result.js +5 -6
  264. package/dist/lab/preflight.d.ts +7 -8
  265. package/dist/lab/preflight.js +6 -6
  266. package/dist/lab/requirements.d.ts +20 -0
  267. package/dist/lab/requirements.js +54 -0
  268. package/dist/lab/route-inputs.d.ts +23 -12
  269. package/dist/lab/route-inputs.js +48 -51
  270. package/dist/lab/routing.d.ts +42 -41
  271. package/dist/lab/routing.js +66 -68
  272. package/dist/lab/run-lab-events.d.ts +3 -11
  273. package/dist/lab/run-lab-events.js +2 -16
  274. package/dist/lab/run-lab-homes.d.ts +76 -0
  275. package/dist/lab/run-lab-homes.js +7 -0
  276. package/dist/lab/run-lab-options.d.ts +12 -66
  277. package/dist/lab/run-lab-options.js +58 -285
  278. package/dist/lab/summary.d.ts +15 -9
  279. package/dist/lab/summary.js +24 -17
  280. package/dist/lab/tasks.d.ts +15 -15
  281. package/dist/lab/tasks.js +14 -14
  282. package/dist/lab/types.d.ts +201 -195
  283. package/dist/lab/types.js +2 -0
  284. package/dist/lab/validation.d.ts +21 -21
  285. package/dist/lab/validation.js +61 -59
  286. package/dist/lab/warnings.d.ts +10 -0
  287. package/dist/lab/warnings.js +70 -41
  288. package/dist/library-aliases.d.ts +56 -0
  289. package/dist/library-aliases.js +22 -0
  290. package/dist/observer/artifact.d.ts +2 -2
  291. package/dist/observer/artifact.js +9 -9
  292. package/dist/observer/data.d.ts +6 -6
  293. package/dist/observer/data.js +7 -6
  294. package/dist/observer/exposure.d.ts +1 -1
  295. package/dist/observer/exposure.js +11 -11
  296. package/dist/observer/http.js +1 -1
  297. package/dist/observer/library.d.ts +1 -1
  298. package/dist/observer/library.js +4 -2
  299. package/dist/observer/listen.js +5 -4
  300. package/dist/observer/render.d.ts +1 -1
  301. package/dist/observer/render.js +12 -7
  302. package/dist/observer/run-routes.d.ts +4 -4
  303. package/dist/observer/run-routes.js +6 -6
  304. package/dist/observer/serve.d.ts +17 -0
  305. package/dist/observer/serve.js +41 -6
  306. package/dist/observer/tunnel.js +1 -1
  307. package/dist/observer-app.html +4 -4
  308. package/dist/routes/computer-use/bundle-parts.d.ts +9 -9
  309. package/dist/routes/computer-use/bundle-parts.js +24 -17
  310. package/dist/routes/computer-use/bundle.d.ts +4 -11
  311. package/dist/routes/computer-use/bundle.js +12 -18
  312. package/dist/routes/computer-use/diagnostics.d.ts +1 -1
  313. package/dist/routes/computer-use/diagnostics.js +1 -1
  314. package/dist/routes/computer-use/e2b-desktop/comms.d.ts +11 -11
  315. package/dist/routes/computer-use/e2b-desktop/comms.js +24 -27
  316. package/dist/routes/computer-use/e2b-desktop/desktop.d.ts +2 -2
  317. package/dist/routes/computer-use/e2b-desktop/desktop.js +8 -11
  318. package/dist/routes/computer-use/e2b-desktop/fidelity.d.ts +16 -15
  319. package/dist/routes/computer-use/e2b-desktop/fidelity.js +20 -19
  320. package/dist/routes/computer-use/e2b-desktop/prepare.d.ts +3 -3
  321. package/dist/routes/computer-use/e2b-desktop/prepare.js +40 -43
  322. package/dist/routes/computer-use/e2b-desktop/start.d.ts +1 -1
  323. package/dist/routes/computer-use/e2b-desktop/start.js +32 -30
  324. package/dist/routes/computer-use/e2b-desktop/state.d.ts +5 -4
  325. package/dist/routes/computer-use/e2b-desktop/state.js +5 -3
  326. package/dist/routes/computer-use/e2b-desktop/teardown.d.ts +1 -1
  327. package/dist/routes/computer-use/e2b-desktop/teardown.js +33 -20
  328. package/dist/routes/computer-use/external-comms.d.ts +4 -4
  329. package/dist/routes/computer-use/external-comms.js +19 -43
  330. package/dist/routes/computer-use/fanout-bundle.d.ts +3 -3
  331. package/dist/routes/computer-use/fanout-bundle.js +38 -42
  332. package/dist/routes/computer-use/{fanout-lanes.js → fanout-records.js} +33 -28
  333. package/dist/routes/computer-use/in-process-desktop.d.ts +3 -10
  334. package/dist/routes/computer-use/in-process-desktop.js +3 -9
  335. package/dist/routes/computer-use/live-flush.d.ts +7 -5
  336. package/dist/routes/computer-use/live-flush.js +20 -28
  337. package/dist/routes/computer-use/{run-lanes.d.ts → live-phase.d.ts} +4 -2
  338. package/dist/routes/computer-use/{run-lanes.js → live-phase.js} +17 -16
  339. package/dist/routes/computer-use/local-tree-pack.d.ts +3 -3
  340. package/dist/routes/computer-use/local-tree-pack.js +4 -5
  341. package/dist/routes/computer-use/local-vm.d.ts +11 -8
  342. package/dist/routes/computer-use/local-vm.js +40 -67
  343. package/dist/routes/computer-use/participant-desktop.d.ts +8 -23
  344. package/dist/routes/computer-use/participant-desktop.js +5 -25
  345. package/dist/routes/computer-use/{lanes.d.ts → participant-execution.d.ts} +11 -11
  346. package/dist/routes/computer-use/{lanes.js → participant-execution.js} +39 -26
  347. package/dist/routes/computer-use/participant-facts.d.ts +7 -1
  348. package/dist/routes/computer-use/participant-facts.js +12 -1
  349. package/dist/routes/computer-use/participant-model.d.ts +25 -11
  350. package/dist/routes/computer-use/participant-model.js +76 -34
  351. package/dist/routes/computer-use/participant-prompt.d.ts +13 -13
  352. package/dist/routes/computer-use/participant-prompt.js +8 -8
  353. package/dist/routes/computer-use/participant-runs.d.ts +11 -11
  354. package/dist/routes/computer-use/participant-runs.js +18 -18
  355. package/dist/routes/computer-use/plan.d.ts +21 -29
  356. package/dist/routes/computer-use/plan.js +70 -78
  357. package/dist/routes/computer-use/preflight.d.ts +3 -5
  358. package/dist/routes/computer-use/preflight.js +40 -36
  359. package/dist/routes/computer-use/rerun-selection.js +11 -7
  360. package/dist/routes/computer-use/result.d.ts +1 -1
  361. package/dist/routes/computer-use/result.js +48 -38
  362. package/dist/routes/computer-use/route.d.ts +5 -5
  363. package/dist/routes/computer-use/route.js +36 -33
  364. package/dist/routes/computer-use/self-report.d.ts +8 -8
  365. package/dist/routes/computer-use/self-report.js +33 -33
  366. package/dist/routes/computer-use/setup.d.ts +9 -15
  367. package/dist/routes/computer-use/setup.js +106 -83
  368. package/dist/routes/computer-use/single-bundle.d.ts +13 -16
  369. package/dist/routes/computer-use/single-bundle.js +46 -53
  370. package/dist/routes/computer-use/subject-projection.d.ts +6 -8
  371. package/dist/routes/computer-use/subject-projection.js +24 -23
  372. package/dist/routes/computer-use/types.d.ts +195 -238
  373. package/dist/routes/computer-use/types.js +21 -13
  374. package/dist/routes/preview.d.ts +8 -2
  375. package/dist/routes/preview.js +8 -5
  376. package/dist/routes/scripted/bundle.d.ts +5 -8
  377. package/dist/routes/scripted/bundle.js +23 -27
  378. package/dist/routes/scripted/plan.d.ts +6 -8
  379. package/dist/routes/scripted/plan.js +15 -13
  380. package/dist/routes/scripted/result.d.ts +4 -1
  381. package/dist/routes/scripted/result.js +15 -11
  382. package/dist/routes/scripted/route.js +15 -17
  383. package/dist/routes/scripted/scenario.d.ts +1 -1
  384. package/dist/routes/scripted/scenario.js +3 -3
  385. package/dist/routes/scripted/setup.d.ts +3 -2
  386. package/dist/routes/scripted/setup.js +27 -26
  387. package/dist/routes/scripted/subject.d.ts +8 -3
  388. package/dist/routes/scripted/subject.js +10 -6
  389. package/dist/routes/scripted/surface-records.js +4 -4
  390. package/dist/routes/scripted/surface-sessions.d.ts +2 -2
  391. package/dist/routes/scripted/surface-sessions.js +4 -4
  392. package/dist/routes/scripted/types.d.ts +21 -40
  393. package/dist/routes/scripted/types.js +2 -3
  394. package/dist/routes/shared-world/{seat-records.js → bundle-records.js} +17 -16
  395. package/dist/routes/shared-world/bundle.d.ts +7 -7
  396. package/dist/routes/shared-world/bundle.js +60 -62
  397. package/dist/routes/shared-world/checkpoints.d.ts +5 -5
  398. package/dist/routes/shared-world/checkpoints.js +5 -5
  399. package/dist/routes/shared-world/comms.d.ts +8 -7
  400. package/dist/routes/shared-world/comms.js +38 -51
  401. package/dist/routes/shared-world/external-public.d.ts +6 -5
  402. package/dist/routes/shared-world/external-public.js +28 -25
  403. package/dist/routes/shared-world/handoff.d.ts +10 -9
  404. package/dist/routes/shared-world/handoff.js +89 -81
  405. package/dist/routes/shared-world/lobby-code.d.ts +7 -7
  406. package/dist/routes/shared-world/lobby-code.js +22 -22
  407. package/dist/routes/shared-world/{seats.d.ts → participant-specs.d.ts} +15 -12
  408. package/dist/routes/shared-world/{seats.js → participant-specs.js} +65 -63
  409. package/dist/routes/shared-world/plan.d.ts +2 -6
  410. package/dist/routes/shared-world/plan.js +8 -9
  411. package/dist/routes/shared-world/provenance.d.ts +4 -4
  412. package/dist/routes/shared-world/provenance.js +4 -4
  413. package/dist/routes/shared-world/provisioned.d.ts +3 -2
  414. package/dist/routes/shared-world/provisioned.js +55 -48
  415. package/dist/routes/shared-world/result.js +47 -36
  416. package/dist/routes/shared-world/route.js +54 -57
  417. package/dist/routes/shared-world/setup.d.ts +6 -5
  418. package/dist/routes/shared-world/setup.js +16 -18
  419. package/dist/routes/shared-world/types.d.ts +70 -141
  420. package/dist/routes/shared-world/types.js +5 -5
  421. package/dist/routes/terminal/adapter.d.ts +10 -10
  422. package/dist/routes/terminal/adapter.js +32 -129
  423. package/dist/routes/terminal/bundle.d.ts +10 -15
  424. package/dist/routes/terminal/bundle.js +43 -52
  425. package/dist/routes/terminal/credentials.d.ts +4 -4
  426. package/dist/routes/terminal/credentials.js +20 -20
  427. package/dist/routes/terminal/dry-run.d.ts +1 -1
  428. package/dist/routes/terminal/dry-run.js +13 -15
  429. package/dist/routes/terminal/encoding.d.ts +1 -1
  430. package/dist/routes/terminal/encoding.js +4 -4
  431. package/dist/routes/terminal/ledger.d.ts +8 -8
  432. package/dist/routes/terminal/ledger.js +22 -22
  433. package/dist/routes/terminal/live-finish.d.ts +1 -2
  434. package/dist/routes/terminal/live-finish.js +24 -23
  435. package/dist/routes/terminal/live-sandbox.d.ts +3 -2
  436. package/dist/routes/terminal/live-sandbox.js +31 -32
  437. package/dist/routes/terminal/participant-text.d.ts +23 -0
  438. package/dist/routes/terminal/participant-text.js +165 -0
  439. package/dist/routes/terminal/persona.js +1 -1
  440. package/dist/routes/terminal/plan.d.ts +2 -6
  441. package/dist/routes/terminal/plan.js +23 -19
  442. package/dist/routes/terminal/recorder.d.ts +6 -1
  443. package/dist/routes/terminal/recorder.js +12 -4
  444. package/dist/routes/terminal/result.js +12 -12
  445. package/dist/routes/terminal/route.js +30 -31
  446. package/dist/routes/terminal/runtime.d.ts +3 -2
  447. package/dist/routes/terminal/runtime.js +3 -3
  448. package/dist/routes/terminal/sandbox.d.ts +4 -4
  449. package/dist/routes/terminal/sandbox.js +10 -10
  450. package/dist/routes/terminal/session.js +22 -19
  451. package/dist/routes/terminal/token-usage.d.ts +1 -1
  452. package/dist/routes/terminal/token-usage.js +10 -11
  453. package/dist/routes/terminal/trace.d.ts +7 -10
  454. package/dist/routes/terminal/trace.js +11 -66
  455. package/dist/routes/terminal/types.d.ts +104 -114
  456. package/dist/routes/terminal/types.js +12 -7
  457. package/dist/run/active-runs.d.ts +13 -0
  458. package/dist/run/active-runs.js +12 -0
  459. package/dist/run/bundle-shape.d.ts +2 -1
  460. package/dist/run/bundle-shape.js +7 -7
  461. package/dist/run/bundle.d.ts +99 -92
  462. package/dist/run/bundle.js +10 -8
  463. package/dist/run/cost-summary.js +6 -5
  464. package/dist/run/costs.d.ts +6 -6
  465. package/dist/run/costs.js +17 -11
  466. package/dist/run/detail.d.ts +9 -9
  467. package/dist/run/detail.js +10 -10
  468. package/dist/run/dry-run-inputs.js +1 -1
  469. package/dist/run/dry-run.js +23 -30
  470. package/dist/run/{study-files.d.ts → evidence-files.d.ts} +4 -4
  471. package/dist/run/{study-files.js → evidence-files.js} +5 -5
  472. package/dist/run/feedback-shape.js +1 -1
  473. package/dist/run/judge.d.ts +34 -16
  474. package/dist/run/judge.js +41 -14
  475. package/dist/run/locate.d.ts +2 -0
  476. package/dist/run/locate.js +3 -1
  477. package/dist/run/outcomes.d.ts +3 -3
  478. package/dist/run/outcomes.js +3 -3
  479. package/dist/run/participant-records.d.ts +2 -2
  480. package/dist/run/participant-records.js +2 -2
  481. package/dist/run/paths.d.ts +1 -1
  482. package/dist/run/paths.js +2 -2
  483. package/dist/run/pricing.d.ts +30 -15
  484. package/dist/run/pricing.js +49 -30
  485. package/dist/run/projection.d.ts +27 -27
  486. package/dist/run/projection.js +23 -23
  487. package/dist/run/reclaim.d.ts +6 -0
  488. package/dist/run/reclaim.js +15 -5
  489. package/dist/run/results.d.ts +5 -5
  490. package/dist/run/run-index.d.ts +9 -7
  491. package/dist/run/run-index.js +24 -25
  492. package/dist/run/run-not-found.d.ts +5 -0
  493. package/dist/run/run-not-found.js +15 -0
  494. package/dist/run/run.d.ts +7 -4
  495. package/dist/run/run.js +10 -6
  496. package/dist/run/sandbox-receipts.d.ts +5 -5
  497. package/dist/run/sandbox-receipts.js +6 -6
  498. package/dist/run/shared-world-evidence.d.ts +67 -66
  499. package/dist/run/shared-world-evidence.js +4 -4
  500. package/dist/run/shared-world-shape.d.ts +3 -3
  501. package/dist/run/shared-world-shape.js +16 -16
  502. package/dist/run/stats.d.ts +17 -11
  503. package/dist/run/stats.js +124 -66
  504. package/dist/run/status.d.ts +21 -32
  505. package/dist/run/status.js +34 -33
  506. package/dist/run/stored-runs.js +2 -1
  507. package/dist/run/stream-shape.js +1 -1
  508. package/dist/run/streams.d.ts +29 -22
  509. package/dist/run/study-provenance.d.ts +47 -0
  510. package/dist/run/study-provenance.js +63 -0
  511. package/dist/run/study-result.d.ts +16 -0
  512. package/dist/run/study-result.js +9 -0
  513. package/dist/run/terminal-contract.d.ts +5 -5
  514. package/dist/run/terminal-contract.js +4 -4
  515. package/dist/run/text.d.ts +2 -0
  516. package/dist/run/text.js +4 -0
  517. package/dist/run/transient-comms-secrets.d.ts +5 -0
  518. package/dist/run/transient-comms-secrets.js +12 -0
  519. package/dist/run-lab.d.ts +40 -38
  520. package/dist/run-lab.js +42 -40
  521. package/dist/study/convert.d.ts +33 -0
  522. package/dist/study/convert.js +432 -0
  523. package/dist/study/field-paths.d.ts +12 -0
  524. package/dist/study/field-paths.js +126 -0
  525. package/dist/study/files.d.ts +26 -0
  526. package/dist/study/files.js +43 -0
  527. package/dist/study/migrate.d.ts +48 -0
  528. package/dist/study/migrate.js +408 -0
  529. package/dist/study/owned-files.d.ts +38 -0
  530. package/dist/study/owned-files.js +182 -0
  531. package/dist/subject/clone.d.ts +1 -1
  532. package/dist/subject/desktop-cli.d.ts +2 -2
  533. package/dist/subject/desktop-cli.js +3 -3
  534. package/dist/subject/local-tree-archive.d.ts +1 -1
  535. package/dist/subject/local-tree-archive.js +5 -5
  536. package/dist/subject/local-tree.d.ts +3 -3
  537. package/dist/subject/local-tree.js +1 -1
  538. package/dist/subject/node-bootstrap.d.ts +1 -1
  539. package/dist/subject/node-bootstrap.js +4 -4
  540. package/dist/subject/runtime.js +10 -11
  541. package/dist/subject/serve.d.ts +1 -1
  542. package/dist/subject/serve.js +4 -4
  543. package/dist/subject/state.d.ts +1 -1
  544. package/dist/subject/steps.d.ts +8 -8
  545. package/dist/subject/steps.js +7 -7
  546. package/dist/substrates/command-failure.d.ts +3 -3
  547. package/dist/substrates/command-failure.js +3 -3
  548. package/dist/substrates/detached.d.ts +6 -6
  549. package/dist/substrates/detached.js +7 -7
  550. package/dist/substrates/e2b/cdp-probe.d.ts +11 -11
  551. package/dist/substrates/e2b/cdp-probe.js +15 -18
  552. package/dist/substrates/e2b/desktop-browser.d.ts +5 -5
  553. package/dist/substrates/e2b/desktop-browser.js +12 -12
  554. package/dist/substrates/e2b/desktop-cdp.d.ts +15 -15
  555. package/dist/substrates/e2b/desktop-cdp.js +11 -11
  556. package/dist/substrates/e2b/desktop-executor.d.ts +1 -1
  557. package/dist/substrates/e2b/desktop-executor.js +1 -1
  558. package/dist/substrates/e2b/desktop-geometry.d.ts +6 -6
  559. package/dist/substrates/e2b/desktop-geometry.js +9 -9
  560. package/dist/substrates/e2b/desktop-media.d.ts +1 -1
  561. package/dist/substrates/e2b/desktop-media.js +3 -3
  562. package/dist/substrates/e2b/desktop-screenshot-cleanup.d.ts +3 -3
  563. package/dist/substrates/e2b/desktop-screenshot-cleanup.js +3 -3
  564. package/dist/substrates/e2b/sandbox.d.ts +1 -1
  565. package/dist/substrates/e2b/sandbox.js +2 -2
  566. package/dist/substrates/e2b/sdk.d.ts +11 -11
  567. package/dist/substrates/e2b/sdk.js +8 -8
  568. package/dist/substrates/local/runtime-host.d.ts +2 -0
  569. package/dist/substrates/local/runtime-host.js +6 -0
  570. package/dist/tui/actions.d.ts +8 -6
  571. package/dist/tui/actions.js +31 -22
  572. package/dist/tui/contract.d.ts +16 -16
  573. package/dist/tui/contract.js +10 -10
  574. package/dist/tui/launch.d.ts +4 -4
  575. package/dist/tui/launch.js +18 -19
  576. package/dist/tui/project.js +5 -5
  577. package/dist/tui-app.js +83 -83
  578. package/dist/verify/actor.d.ts +14 -14
  579. package/dist/verify/actor.js +45 -45
  580. package/dist/verify/artifacts.d.ts +3 -3
  581. package/dist/verify/artifacts.js +6 -6
  582. package/dist/verify/context-growth.d.ts +9 -0
  583. package/dist/verify/context-growth.js +62 -0
  584. package/dist/verify/costs.d.ts +7 -7
  585. package/dist/verify/costs.js +9 -9
  586. package/dist/verify/liveness.d.ts +1 -1
  587. package/dist/verify/liveness.js +4 -1
  588. package/dist/verify/rerun.d.ts +1 -1
  589. package/dist/verify/rerun.js +1 -1
  590. package/dist/verify/shared-world-concurrent.d.ts +2 -2
  591. package/dist/verify/shared-world-concurrent.js +79 -76
  592. package/dist/verify/shared-world.d.ts +2 -2
  593. package/dist/verify/shared-world.js +18 -18
  594. package/dist/verify/subject.d.ts +4 -4
  595. package/dist/verify/subject.js +18 -18
  596. package/dist/verify/verify.js +98 -49
  597. package/docs/README.md +26 -33
  598. package/docs/architecture/actor-contract.md +105 -98
  599. package/docs/architecture/desktop-sessions.md +14 -14
  600. package/docs/architecture/external-public-shared-world.md +66 -59
  601. package/docs/architecture/github-feedback-loop.md +1 -4
  602. package/docs/architecture/guest-desktop.md +2 -2
  603. package/docs/architecture/observer.md +37 -37
  604. package/docs/architecture/restricted-codex-analysis.md +70 -30
  605. package/docs/architecture/serve.md +34 -37
  606. package/docs/architecture/state-driven-executor.md +55 -59
  607. package/docs/architecture/task-protocol-support.md +7 -9
  608. package/docs/architecture/{terminal-product-lane.md → terminal-product-route.md} +83 -115
  609. package/docs/contracts/README.md +24 -0
  610. package/docs/contracts/adapter-admission.md +3 -3
  611. package/docs/contracts/adapter-fixtures.md +2 -5
  612. package/docs/contracts/core.md +1 -3
  613. package/docs/contracts/errors.md +62 -0
  614. package/docs/contracts/feedback.md +8 -9
  615. package/docs/contracts/policy.md +7 -12
  616. package/docs/contracts/run-bundle.md +54 -51
  617. package/docs/contracts/schemas.md +505 -390
  618. package/docs/contracts/study-analysis.md +26 -2
  619. package/docs/contracts/study-costs.md +11 -7
  620. package/docs/decisions/0001-run-bundle-is-the-source-of-truth.md +1 -1
  621. package/docs/decisions/0002-observer-is-one-self-contained-file.md +2 -2
  622. package/docs/decisions/0003-contained-paths-and-cleanup-authority.md +3 -3
  623. package/docs/decisions/0004-participant-desktops-stay-in-the-route.md +2 -1
  624. package/docs/principles/actor-fidelity.md +4 -4
  625. package/docs/principles/engineering.md +3 -3
  626. package/docs/principles/invariants-and-defaults.md +38 -38
  627. package/docs/principles/self-driving-harness.md +1 -5
  628. package/docs/principles/three-roles.md +1 -1
  629. package/docs/product/automatic-analysis.md +8 -7
  630. package/examples/participant/README.md +5 -5
  631. package/examples/participant/run.mjs +11 -10
  632. package/examples/scorer/README.md +3 -3
  633. package/examples/scorer/run.mjs +11 -12
  634. package/package.json +16 -17
  635. package/skills/humanish/SKILL.md +63 -60
  636. package/skills/humanish/agents/openai.yaml +1 -1
  637. package/AGENTS.md +0 -99
  638. package/CONTRIBUTING.md +0 -148
  639. package/dist/actors/codex/qualified-versions.d.ts +0 -45
  640. package/dist/actors/codex/qualified-versions.js +0 -87
  641. package/dist/cli/commands/lab.d.ts +0 -3
  642. package/dist/cli/commands/lab.js +0 -193
  643. package/dist/deprecated.d.ts +0 -90
  644. package/dist/deprecated.js +0 -106
  645. package/dist/lab/bag-overrides.d.ts +0 -18
  646. package/dist/lab/bag-overrides.js +0 -121
  647. package/dist/observer/static.d.ts +0 -39
  648. package/dist/observer/static.js +0 -369
  649. package/dist/routes/computer-use/legacy-lane-spec.d.ts +0 -62
  650. package/dist/routes/computer-use/legacy-lane-spec.js +0 -39
  651. package/docs/architecture/comms-inbox.md +0 -122
  652. package/docs/architecture/desktop-recording.md +0 -80
  653. package/docs/architecture/local-browser-runtime.md +0 -178
  654. package/docs/architecture/observer-review.md +0 -144
  655. package/docs/architecture/participant-media.md +0 -90
  656. package/docs/architecture/project-layout.md +0 -62
  657. package/docs/architecture/real-email-receiving.md +0 -136
  658. package/docs/assets/humanish-drawdb-hero.png +0 -0
  659. package/docs/assets/humanish-observer-hero.png +0 -0
  660. package/docs/goals/current.md +0 -207
  661. package/docs/product/lobby-trivia-3player-external-public.md +0 -77
  662. package/docs/product/open-source-install-experience.md +0 -240
  663. package/docs/ramp/README.md +0 -294
  664. package/docs/release/open-source-readiness.md +0 -222
  665. package/docs/release/public-readiness-standard.md +0 -210
  666. package/docs/roadmap/world-class-open-source-v0.md +0 -311
  667. /package/dist/routes/computer-use/{fanout-lanes.d.ts → fanout-records.d.ts} +0 -0
  668. /package/dist/routes/shared-world/{seat-records.d.ts → bundle-records.d.ts} +0 -0
@@ -10,13 +10,15 @@ import { registerAnalyzeCommand } from "./commands/analyze.js";
10
10
  import { registerCodexCommands } from "./commands/codex.js";
11
11
  import { registerCommsCommands } from "./commands/comms.js";
12
12
  import { registerFeedbackCommands } from "./commands/feedback.js";
13
- import { registerLabCommands } from "./commands/lab.js";
13
+ import { registerStudyCommands } from "./commands/study.js";
14
+ import { registerMigrateCommand } from "./commands/migrate.js";
14
15
  import { registerObserveCommand, registerServeCommand } from "./commands/observe.js";
15
16
  import { registerCleanupCommand, registerExportCommand, registerReclaimCommand, registerReviewCommand, registerRunCommand, registerRunsCommand, registerRuntimeCommands, registerStatsCommand, registerVerifyCommand, } from "./commands/runs.js";
16
17
  import { registerDoctorCommand, registerInitCommand, registerKeysCommand, registerTelemetryCommand, } from "./commands/setup.js";
17
18
  import { defaultTuiRuntime, registerTuiCommand } from "./commands/tui.js";
18
19
  import { registerWatchCommand } from "./commands/watch.js";
19
- import { CLI_RESPONSE_SCHEMA, CLI_VERSION, defaultIo, invocationEnvelopeAlreadyWritten, studyFactsFor, wantsJson, } from "./io.js";
20
+ import { CLI_RESPONSE_SCHEMA, CLI_VERSION, defaultIo, invocationEnvelopeAlreadyWritten, runFactsFor, wantsJson, } from "./io.js";
21
+ import { PRODUCT_SENTENCE } from "./product-sentence.js";
20
22
  // Command boundary catch-all (fix set point 1): every leaf command is created
21
23
  // through HumanishCommand.createCommand, and HumanishCommand.action wraps the caller's
22
24
  // handler so an uncaught throw or promise rejection can never escape as a raw
@@ -27,7 +29,7 @@ import { CLI_RESPONSE_SCHEMA, CLI_VERSION, defaultIo, invocationEnvelopeAlreadyW
27
29
  // none of the ~20 .action() handlers below need their own try/catch for this.
28
30
  /**
29
31
  * Print the disclosure the first time humanish would collect anything, and remember that it was
30
- * shown. AWAITED by the caller: if this loses the race with process exit, a default-on collector
32
+ * shown. Awaited by the caller: if this loses the race with process exit, a default-on collector
31
33
  * becomes a silent one.
32
34
  */
33
35
  async function announceTelemetryOnce(command, io) {
@@ -75,7 +77,7 @@ async function recordCommandTelemetry(command, ok, durationMs, exitCode) {
75
77
  // result document when it was written; see writeResult. Without them every `run` event
76
78
  // looked the same whether it was a dry run or the first live study that ever worked.
77
79
  properties: {
78
- ...studyFactsFor(command),
80
+ ...runFactsFor(command),
79
81
  command: name,
80
82
  ok: ok && exitCode === 0,
81
83
  exitCode,
@@ -95,9 +97,9 @@ async function recordCommandTelemetry(command, ok, durationMs, exitCode) {
95
97
  }
96
98
  /**
97
99
  * HUMANISH_DEBUG_HANDLES=1: after a command's handler settles, name what is still keeping the
98
- * process alive (#581). A live terminal run wrote its result 64 s in and the CLI stayed up for
100
+ * process alive. A live terminal run wrote its result 64 s in and the CLI stayed up for
99
101
  * sixteen more minutes; nothing in the bundle could say what held it, and an in-process probe of
100
- * the lane found nothing of ours. This is the one line that answers it next time: the resource
102
+ * the run found nothing of ours. This is the one line that answers it next time: the resource
101
103
  * types Node reports, once, to stderr, after one macrotask so settled work has cleared.
102
104
  */
103
105
  function reportActiveHandles(command, io) {
@@ -114,7 +116,7 @@ function reportActiveHandles(command, io) {
114
116
  io.writeErr(`humanish debug: active resources after \`${commandPath(command) || "humanish"}\` settled: ${summary}\n`);
115
117
  }).unref?.();
116
118
  }
117
- /** `lab run`, not `run`, so the two are distinguishable — and nothing else from the invocation. */
119
+ /** `lab run`, not `run`, so the two are distinguishable, and nothing else from the invocation. */
118
120
  function commandPath(command) {
119
121
  const parts = [];
120
122
  let current = command;
@@ -133,18 +135,33 @@ class HumanishCommand extends Command {
133
135
  createCommand(name) {
134
136
  return new HumanishCommand(name, this.cliIo);
135
137
  }
138
+ /**
139
+ * Commander rejects unknown options before the root action runs, so `humanish nope --cwd .`
140
+ * reported `--cwd` and never reached the root action's unknown-command message. When the root's
141
+ * first operand names no command, everything after it goes to that action as operands.
142
+ */
143
+ parseOptions(argv) {
144
+ const parsed = super.parseOptions(argv);
145
+ const [word] = parsed.operands;
146
+ if (this.parent !== null || word === undefined || parsed.unknown.length === 0)
147
+ return parsed;
148
+ // `help` is the help command set up in createProgram; commander keeps it out of `commands`.
149
+ const known = word === "help" ||
150
+ this.commands.some((command) => command.name() === word || command.aliases().includes(word));
151
+ return known ? parsed : { operands: [...parsed.operands, ...parsed.unknown], unknown: [] };
152
+ }
136
153
  action(fn) {
137
154
  const cliIo = this.cliIo;
138
155
  const wrapped = function (...args) {
139
- // ONE emission point for every command, at the same seam that already catches every throw.
156
+ // One emission point for every command, at the same seam that already catches every throw.
140
157
  // Twenty .action() handlers each remembering to record a metric is twenty chances to forget
141
158
  // one, and a funnel with a hole in it is worse than no funnel.
142
159
  const startedAt = Date.now();
143
160
  lastExitCode = 0;
144
- // The NOTICE is awaited; the SEND is not. They have opposite requirements: disclosure must
161
+ // The notice is awaited; the send is not. They have opposite requirements: disclosure must
145
162
  // never be lost (a silent default-on collector is indefensible), and a metric must never
146
163
  // make anyone wait. The first version put both in the fire-and-forget path, and the notice
147
- // lost the race with process exit — a real participant ran this build and never saw it.
164
+ // lost the race with process exit: a real participant ran this build and never saw it.
148
165
  const noticed = announceTelemetryOnce(this, cliIo);
149
166
  const finish = (ok) => {
150
167
  void recordCommandTelemetry(this, ok, Date.now() - startedAt, lastExitCode);
@@ -179,12 +196,12 @@ class HumanishCommand extends Command {
179
196
  function reportUnexpectedActionError(command, io, error) {
180
197
  const message = redactText(error instanceof Error ? error.message : String(error));
181
198
  // A taken port is the most expected thing a serving command meets; it gets its own code rather
182
- // than the catch-all's (#484). The message already names the port and whose it is.
199
+ // than the catch-all's. The message already names the port and whose it is.
183
200
  const code = error instanceof PortInUseError ? "HUMANISH_PORT_IN_USE" : "HUMANISH_UNEXPECTED";
184
201
  if (wantsJson(command)) {
185
202
  if (invocationEnvelopeAlreadyWritten(command)) {
186
203
  // Some result already went to stdout for this invocation before the
187
- // failure landed -- e.g. `codex app-server --keep-open --json` writes its
204
+ // failure landed, e.g. `codex app-server --keep-open --json` writes its
188
205
  // "running" envelope via writeResult, then a later `await` can still
189
206
  // reject (src/actors/codex/app-server-ui.ts's persistState() write can fail on
190
207
  // either branch of that command's completion handling). Appending a
@@ -210,7 +227,7 @@ function reportUnexpectedActionError(command, io, error) {
210
227
  }
211
228
  io.setExitCode(2);
212
229
  }
213
- /** `unknown option '--x'` -> the sibling commands that DO declare `--x`. */
230
+ /** `unknown option '--x'` -> the sibling commands that do declare `--x`. */
214
231
  function commandsDeclaring(root, flag) {
215
232
  const found = [];
216
233
  const walk = (command, trail) => {
@@ -228,7 +245,7 @@ function commandsDeclaring(root, flag) {
228
245
  /**
229
246
  * Enrich commander's flag rejections with where the flag actually lives. A bare "unknown option"
230
247
  * is accurate and unhelpful in the same way `no labs here yet` was: it reports a fact about this
231
- * command and says nothing the reader can act on. Silence is preserved when no sibling has it —
248
+ * command and says nothing the reader can act on. Silence is preserved when no sibling has it:
232
249
  * inventing a suggestion would be worse than none.
233
250
  */
234
251
  export function withSiblingFlagHint(text, root) {
@@ -238,7 +255,7 @@ export function withSiblingFlagHint(text, root) {
238
255
  const owners = commandsDeclaring(root, match[1]);
239
256
  if (owners.length === 0)
240
257
  return text;
241
- // Truncation is REPORTED, never silent: a list that quietly drops owners would send a reader
258
+ // Truncation is reported, never silent: a list that quietly drops owners would send a reader
242
259
  // looking in the wrong place and think it had answered them.
243
260
  const shown = owners.slice(0, 3);
244
261
  const list = shown.map((owner) => `\`humanish ${owner}\``).join(", ");
@@ -254,11 +271,23 @@ export function normalizeCliArgv(argv) {
254
271
  }
255
272
  return argv;
256
273
  }
274
+ /**
275
+ * The root help's examples, in the order a newcomer runs them. Each passes on a freshly
276
+ * initialized project (tests/cli/root-help-examples.test.ts).
277
+ */
278
+ export const ROOT_HELP_EXAMPLES = [
279
+ "humanish init --yes",
280
+ "humanish run first-run",
281
+ "humanish observe --run latest --open",
282
+ "humanish doctor --study try-live",
283
+ "humanish run try-live",
284
+ "humanish verify --json",
285
+ ];
257
286
  export function createProgram(io = {}) {
258
287
  const given = { ...defaultIo, ...io };
259
- // Telemetry's `ok` used to mean "the handler did not throw", which is true of nearly every
260
- // failure: commands report failure through their envelope and setExitCode(2), not by throwing.
261
- // 1,359 study events in two days and every one said ok. Record the exit code the command chose.
288
+ // Telemetry's `ok` is the exit code the command chose. "The handler did not throw" is true of
289
+ // nearly every failure: commands report failure through their envelope and setExitCode(2), not
290
+ // by throwing.
262
291
  const cliIo = {
263
292
  ...given,
264
293
  setExitCode: (code) => {
@@ -267,9 +296,19 @@ export function createProgram(io = {}) {
267
296
  },
268
297
  };
269
298
  const program = new HumanishCommand(undefined, cliIo);
270
- // Bare `humanish` orients instead of printing sixteen subcommands (#367). --help is untouched;
271
- // this is only what happens when no command was chosen at all.
299
+ // Bare `humanish` orients instead of printing sixteen subcommands. --help is untouched;
300
+ // this is only what happens when no command was chosen at all. A word that names no command
301
+ // (`humanish verfy`) lands here too, and gets the closest command in place of the help dump.
272
302
  program.action(async (options) => {
303
+ const [word] = program.args;
304
+ if (word !== undefined) {
305
+ const suggestion = closestCommand(word, program.commands.map((command) => command.name()));
306
+ cliIo.writeErr(suggestion === undefined
307
+ ? `error: unknown command '${word}'. humanish --help lists the commands.\n`
308
+ : `error: unknown command '${word}'. Did you mean '${suggestion}'?\n`);
309
+ cliIo.setExitCode(1);
310
+ return;
311
+ }
273
312
  const state = await readOrientation(".");
274
313
  if (options.json === true) {
275
314
  cliIo.writeOut(`${JSON.stringify(state, null, 2)}\n`);
@@ -281,58 +320,88 @@ export function createProgram(io = {}) {
281
320
  });
282
321
  program
283
322
  .name("humanish")
284
- .description("Open-source-safe persona simulation CLI and proof harness.")
285
- .version(CLI_VERSION)
323
+ .description(PRODUCT_SENTENCE)
324
+ .version(CLI_VERSION, "-v, --version", "Print the version.")
325
+ // Set before the commands register: commander copies the help option and help command into
326
+ // each subcommand when it is created.
327
+ .helpOption("-h, --help", "Show help for this command.")
328
+ .helpCommand("help [command]", "Show help for a command.")
286
329
  .showHelpAfterError()
287
330
  .option("--json", "Print machine-readable JSON responses where supported.")
288
331
  .configureOutput({
289
332
  writeOut: (text) => cliIo.writeOut(text),
290
333
  writeErr: (text) => cliIo.writeErr(text),
291
- // A rejected flag should name the command that WOULD have taken it. Found by a real
334
+ // A rejected flag should name the command that would have taken it. Found by a real
292
335
  // first-contact study (labs/first-contact.yaml): a participant reached for
293
336
  // `humanish run --no-open` by analogy with `lab run`, got a bare "unknown option", and
294
- // filed it as a documentation mismatch. The flag is genuinely absent — `run` opens
295
- // nothing — but "unknown" says that badly, because the reader's actual question is
337
+ // filed it as a documentation mismatch. The flag is genuinely absent (`run` opens
338
+ // nothing), but "unknown" says that badly, because the reader's actual question is
296
339
  // "then where does it live?".
297
340
  outputError: (text, write) => write(withSiblingFlagHint(text, program)),
298
341
  })
299
342
  .addHelpText("after", [
300
343
  "",
301
344
  "Examples:",
302
- " humanish watch",
303
- " humanish watch first-run",
304
- " humanish watch --lab .humanish/labs/local.yaml",
305
- " humanish watch --run latest --detach",
306
- " humanish watch --json --no-open",
307
- " humanish lab list",
308
- " humanish lab run first-run --json --no-open",
309
- " humanish verify --run latest --json",
345
+ ...ROOT_HELP_EXAMPLES.map((example) => ` ${example}`),
310
346
  "",
311
347
  "Public-safety boundary:",
312
348
  " humanish must not commit or emit PII, PHI, secrets, keys, raw private transcripts,",
313
349
  " private screenshots, or private upstream artifacts.",
314
- ].join("\n"));
350
+ ].join("\n"))
351
+ .addHelpText("afterAll", "\nDocs: https://humanish.dev/docs\nEvery command and option: https://humanish.dev/docs/cli");
352
+ // --help lists commands in this order: a study's workflow first, then the supporting commands.
315
353
  registerInitCommand(program, cliIo);
316
354
  registerDoctorCommand(program, cliIo);
317
- registerTuiCommand(program, cliIo, { ...defaultTuiRuntime, ...io.tuiRuntime });
318
- registerTelemetryCommand(program, cliIo);
319
- registerKeysCommand(program, cliIo);
320
355
  registerRunCommand(program, cliIo);
356
+ registerWatchCommand(program, cliIo);
357
+ registerObserveCommand(program, cliIo);
321
358
  registerVerifyCommand(program, cliIo);
322
- registerCleanupCommand(program, cliIo);
323
359
  registerReviewCommand(program, cliIo);
324
360
  registerAnalyzeCommand(program, cliIo);
361
+ registerFeedbackCommands(program, cliIo);
362
+ registerExportCommand(program, cliIo);
325
363
  registerRunsCommand(program, cliIo);
326
364
  registerStatsCommand(program, cliIo);
327
- registerExportCommand(program, cliIo);
365
+ registerStudyCommands(program, cliIo);
366
+ registerMigrateCommand(program, cliIo);
328
367
  registerCommsCommands(program, cliIo);
329
368
  registerRuntimeCommands(program, cliIo);
330
369
  registerReclaimCommand(program, cliIo);
331
- registerWatchCommand(program, cliIo);
332
- registerObserveCommand(program, cliIo);
370
+ registerCleanupCommand(program, cliIo);
371
+ registerKeysCommand(program, cliIo);
372
+ registerTelemetryCommand(program, cliIo);
333
373
  registerServeCommand(program, cliIo);
374
+ registerTuiCommand(program, cliIo, { ...defaultTuiRuntime, ...io.tuiRuntime });
334
375
  registerCodexCommands(program, cliIo);
335
- registerLabCommands(program, cliIo);
336
- registerFeedbackCommands(program, cliIo);
376
+ // Only the root takes a stray word, so the action above can name the command it meant. Set after
377
+ // registration: commander copies this setting into each subcommand when it is created.
378
+ program.allowExcessArguments(true);
337
379
  return program;
338
380
  }
381
+ /** The registered command closest to a mistyped word, or undefined when none is close. */
382
+ function closestCommand(word, names) {
383
+ let best;
384
+ for (const name of names) {
385
+ const distance = editDistance(word.toLowerCase(), name);
386
+ if (distance <= Math.max(1, Math.floor(name.length / 3)) && (!best || distance < best.distance))
387
+ best = { name, distance };
388
+ }
389
+ return best?.name;
390
+ }
391
+ /** Levenshtein distance, with an adjacent transposition counted as one edit. */
392
+ function editDistance(a, b) {
393
+ const rows = Array.from({ length: a.length + 1 }, (_, i) => [
394
+ i,
395
+ ...Array(b.length).fill(0),
396
+ ]);
397
+ for (let j = 1; j <= b.length; j++)
398
+ rows[0][j] = j;
399
+ for (let i = 1; i <= a.length; i++)
400
+ for (let j = 1; j <= b.length; j++) {
401
+ const cost = a[i - 1] === b[j - 1] ? 0 : 1;
402
+ rows[i][j] = Math.min(rows[i - 1][j] + 1, rows[i][j - 1] + 1, rows[i - 1][j - 1] + cost);
403
+ if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1])
404
+ rows[i][j] = Math.min(rows[i][j], rows[i - 2][j - 2] + 1);
405
+ }
406
+ return rows[a.length][b.length];
407
+ }
@@ -1,21 +1,21 @@
1
- /** The ONLY event names. */
1
+ /** The only event names. */
2
2
  export type TelemetryEvent = "cli_command" | "project_initialized" | "study_finished";
3
3
  export interface TelemetryProperties {
4
4
  command?: string;
5
- /** A starter lab id, or "custom" — never an adopter's own lab id. */
6
- lab?: string;
5
+ /** A starter study id, or "custom"; never an adopter's own study id. */
6
+ study?: string;
7
7
  mode?: "dry-run" | "live";
8
8
  outcome?: string;
9
9
  /** Bucketed, not exact: a duration is a fingerprint at full precision. */
10
10
  durationBucket?: string;
11
- /** Which brain ran it, as a route name — never a model id the adopter configured. */
11
+ /** Which brain ran it, as a route name; never a model id the adopter configured. */
12
12
  brain?: "provider-key" | "local-agent" | "none";
13
13
  ok?: boolean;
14
14
  exitCode?: number;
15
- /** One of humanish's OWN error codes (`HUMANISH_*`), never a message. Which failure ends a
15
+ /** One of humanish's own error codes (`HUMANISH_*`), never a message. Which failure ends a
16
16
  * first run is the question the funnel exists to answer. */
17
17
  errorCode?: string;
18
- /** Finite result categories and recorded stop causes; never raw errors or lane details. */
18
+ /** Finite result categories and recorded stop causes; never raw errors or participant details. */
19
19
  diagnosticCategory?: string;
20
20
  stopCause?: string;
21
21
  }
@@ -33,9 +33,9 @@ export declare function telemetryStatePath(env?: NodeJS.ProcessEnv, home?: strin
33
33
  */
34
34
  export declare function disabledByEnvironment(env: NodeJS.ProcessEnv): boolean;
35
35
  /**
36
- * True when this process is running from a humanish SOURCE CHECKOUT rather than an install.
36
+ * True when this process is running from a humanish source checkout rather than an install.
37
37
  *
38
- * Checked by walking up from cwd for a package.json whose name is `humanish` AND which carries
38
+ * Checked by walking up from cwd for a package.json whose name is `humanish` and which carries
39
39
  * this repo's private marker. An adopter with a dependency named humanish in node_modules is not
40
40
  * matched: node_modules copies are skipped, and a consumer's own package.json has a different
41
41
  * name. Falls back to "not a checkout" on any read error, because the failure direction that
@@ -43,7 +43,7 @@ export declare function disabledByEnvironment(env: NodeJS.ProcessEnv): boolean;
43
43
  */
44
44
  export declare function inHumanishCheckout(startDir: string, readFileSyncFn: (p: string) => string): boolean;
45
45
  /**
46
- * Is this command one of OUR runs, whichever directory it was started from? Two walks: from the
46
+ * Is this command one of our runs, whichever directory it was started from? Two walks: from the
47
47
  * cwd (catches `pnpm humanish ...` inside the repo) and from the running CLI's own directory
48
48
  * (catches a test, TUI smoke or release-dogfood host that spawns dist/cli.js into a temp
49
49
  * directory with a constructed env). The second walk is the one the 0.63.0 fix lacked: one
@@ -56,8 +56,8 @@ export declare function readTelemetryState(env?: NodeJS.ProcessEnv, home?: strin
56
56
  export declare function writeTelemetryState(state: TelemetryState, env?: NodeJS.ProcessEnv, home?: string): Promise<void>;
57
57
  /** Coarse enough that a duration cannot fingerprint a session. */
58
58
  export declare function durationBucket(ms: number): string;
59
- /** A lab id only if it is one of ours. An adopter's lab id can name an unannounced product. */
60
- export declare function safeLabId(lab: string | undefined): string | undefined;
59
+ /** A study id only if it is one of ours. An adopter's study id can name an unannounced product. */
60
+ export declare function safeStudyId(study: string | undefined): string | undefined;
61
61
  export interface TelemetryPayload {
62
62
  event: TelemetryEvent;
63
63
  distinct_id: string;
@@ -65,8 +65,8 @@ export interface TelemetryPayload {
65
65
  }
66
66
  /**
67
67
  * The exact document that would be sent. Built separately from sending so that
68
- * `HUMANISH_TELEMETRY_DEBUG=1` can show it and so tests can assert on it — "you can read exactly
69
- * what we collect" is the part of this convention that makes it honest rather than merely legal.
68
+ * `HUMANISH_TELEMETRY_DEBUG=1` can show it and so tests can assert on it. "You can read exactly
69
+ * what we collect" is the part of this convention that lets a person check the collection.
70
70
  */
71
71
  export declare function buildPayload(args: {
72
72
  event: TelemetryEvent;
@@ -80,14 +80,14 @@ export declare function buildPayload(args: {
80
80
  /**
81
81
  * Read the study facts off a command's result document: mode, outcome, starter lab, brain route,
82
82
  * and our own error code. Duck-typed over every result shape the CLI writes, because the point is
83
- * ONE derivation at the one seam every command already passes through (writeResult), so that a
83
+ * one derivation at the one seam every command already passes through (writeResult), so that a
84
84
  * backend added later cannot forget to report. Returns {} for results that carry no study.
85
85
  *
86
86
  * The first two days of 0.62.0 data had 1,359 `run`/`lab run` events and not one carried a mode
87
- * or an outcome — the vocabulary existed, nothing populated it — so the one question telemetry
88
- * was added to answer ("does anyone get to a working LIVE first run") had no answer in the data.
87
+ * or an outcome (the vocabulary existed, nothing populated it), so the one question telemetry
88
+ * was added to answer ("does anyone get to a working live first run") had no answer in the data.
89
89
  */
90
- export declare function deriveStudyFacts(result: unknown): TelemetryProperties;
90
+ export declare function deriveRunFacts(result: unknown): TelemetryProperties;
91
91
  /** The notice, shown once, before anything is sent. */
92
92
  export declare const TELEMETRY_NOTICE: string;
93
93
  export interface SendDeps {
@@ -1,25 +1,25 @@
1
1
  // Anonymous usage telemetry, on the convention Next.js and the Vercel CLI established: collected by
2
2
  // default, disclosed the first time it happens, trivially switched off, and inspectable.
3
3
  //
4
- // WHY IT EXISTS: humanish shipped 61 releases without being able to answer "does anyone get to a
5
- // working first run". The funnel was broken at the first live run for months and we learned it from
6
- // an adoption post-mortem, not from data. A tool that cannot see its own activation is guessing.
4
+ // Why it exists: humanish shipped 61 releases without being able to answer "does anyone get to a
5
+ // working first run". A tool that cannot see its own activation is guessing.
7
6
  //
8
- // WHAT IT WILL NEVER SEND, and this is stricter than the convention because of what humanish is:
7
+ // What it will never send, and this is stricter than the convention because of what humanish is:
9
8
  // no paths, no cwd, no repo names, no URLs, no lab titles or ids that are not our own starter labs,
10
9
  // no persona or mission text, no run ids, no evidence, no key values, no key names. A study's
11
10
  // subject is the adopter's product and often unannounced; leaking a lab id would leak a roadmap.
12
- // The allowlist below is the whole vocabulary — anything not on it cannot be sent by construction.
11
+ // The allowlist below is the whole vocabulary: anything not on it cannot be sent by construction.
13
12
  import { isCuaDiagnosticCategory, isCuaDiagnosticStopCause, } from "../routes/computer-use/diagnostics.js";
14
13
  import { randomUUID } from "node:crypto";
15
14
  import { mkdir, readFile, writeFile } from "node:fs/promises";
16
15
  import { homedir } from "node:os";
17
16
  import path from "node:path";
18
- /** Write-only PostHog project key. Public by design — it can ingest, and can read nothing. */
17
+ import { STUDY_RESULT_SCHEMA } from "../run/study-result.js";
18
+ /** Write-only PostHog project key. Public by design: it can ingest, and can read nothing. */
19
19
  const INGEST_KEY = "phc_oeMeBqxDZhZ9tCHMSnuDFimLqHpU5Myc847WD33hAh4C";
20
20
  const INGEST_HOST = "https://us.i.posthog.com";
21
- /** The ONLY lab ids that may be named. Ours, shipped by `init`; everything else is "custom". */
22
- const STARTER_LABS = new Set([
21
+ /** The only study ids that may be named. Ours, shipped by `init`; everything else is "custom". */
22
+ const STARTER_STUDIES = new Set([
23
23
  "first-run",
24
24
  "try-live",
25
25
  "cua-browser",
@@ -28,7 +28,7 @@ const STARTER_LABS = new Set([
28
28
  ]);
29
29
  export function telemetryStatePath(env = process.env, home = homedir()) {
30
30
  const declared = env.XDG_CONFIG_HOME?.trim();
31
- // Same XDG rule the key store uses: a relative value MUST be ignored, or state becomes
31
+ // Same XDG rule the key store uses: a relative value must be ignored, or state becomes
32
32
  // cwd-relative and follows people between projects.
33
33
  const configHome = declared !== undefined && declared !== "" && path.isAbsolute(declared)
34
34
  ? declared
@@ -46,21 +46,21 @@ export function disabledByEnvironment(env) {
46
46
  value.trim().toLowerCase() !== "false";
47
47
  return (truthy(env.DO_NOT_TRACK) ||
48
48
  truthy(env.HUMANISH_TELEMETRY_DISABLED) ||
49
- // Our OWN development and test runs must never reach the adoption dataset. In the first two
49
+ // Our own development and test runs must never reach the adoption dataset. In the first two
50
50
  // days after telemetry shipped, 82% of events (4,042 of 4,932, from 49 of 59 anonymous ids)
51
51
  // came from humanish's own CI and suite: ~50 ids each running nearly every subcommand about
52
52
  // once, which is the shape of a test matrix and not of people. That made the one number whose
53
53
  // job is measuring adoption measure us instead.
54
54
  //
55
- // Deliberately NOT keyed on CI. An adopter running humanish in their pipeline is real usage
55
+ // Deliberately not keyed on CI. An adopter running humanish in their pipeline is real usage
56
56
  // and stays countable; the `ci` property already separates it, which is what Next.js does.
57
57
  // This keys on being inside the humanish source tree, which only we ever are.
58
58
  truthy(env.HUMANISH_DEV));
59
59
  }
60
60
  /**
61
- * True when this process is running from a humanish SOURCE CHECKOUT rather than an install.
61
+ * True when this process is running from a humanish source checkout rather than an install.
62
62
  *
63
- * Checked by walking up from cwd for a package.json whose name is `humanish` AND which carries
63
+ * Checked by walking up from cwd for a package.json whose name is `humanish` and which carries
64
64
  * this repo's private marker. An adopter with a dependency named humanish in node_modules is not
65
65
  * matched: node_modules copies are skipped, and a consumer's own package.json has a different
66
66
  * name. Falls back to "not a checkout" on any read error, because the failure direction that
@@ -68,7 +68,7 @@ export function disabledByEnvironment(env) {
68
68
  */
69
69
  export function inHumanishCheckout(startDir, readFileSyncFn) {
70
70
  let dir = path.resolve(startDir);
71
- // Any node_modules ANYWHERE in the path means this is an installed copy, not our checkout.
71
+ // Any node_modules anywhere in the path means this is an installed copy, not our checkout.
72
72
  // Checking only the basename missed `/app/node_modules/humanish`, which is the single most
73
73
  // likely real-world path to get wrong: it would silence a genuine adopter.
74
74
  if (dir.split(path.sep).includes("node_modules"))
@@ -90,7 +90,7 @@ export function inHumanishCheckout(startDir, readFileSyncFn) {
90
90
  return false;
91
91
  }
92
92
  /**
93
- * Is this command one of OUR runs, whichever directory it was started from? Two walks: from the
93
+ * Is this command one of our runs, whichever directory it was started from? Two walks: from the
94
94
  * cwd (catches `pnpm humanish ...` inside the repo) and from the running CLI's own directory
95
95
  * (catches a test, TUI smoke or release-dogfood host that spawns dist/cli.js into a temp
96
96
  * directory with a constructed env). The second walk is the one the 0.63.0 fix lacked: one
@@ -134,16 +134,16 @@ export function durationBucket(ms) {
134
134
  return "5-15m";
135
135
  return ">15m";
136
136
  }
137
- /** A lab id only if it is one of ours. An adopter's lab id can name an unannounced product. */
138
- export function safeLabId(lab) {
139
- if (lab === undefined)
137
+ /** A study id only if it is one of ours. An adopter's study id can name an unannounced product. */
138
+ export function safeStudyId(study) {
139
+ if (study === undefined)
140
140
  return undefined;
141
- return STARTER_LABS.has(lab) ? lab : "custom";
141
+ return STARTER_STUDIES.has(study) ? study : "custom";
142
142
  }
143
143
  /**
144
144
  * The exact document that would be sent. Built separately from sending so that
145
- * `HUMANISH_TELEMETRY_DEBUG=1` can show it and so tests can assert on it — "you can read exactly
146
- * what we collect" is the part of this convention that makes it honest rather than merely legal.
145
+ * `HUMANISH_TELEMETRY_DEBUG=1` can show it and so tests can assert on it. "You can read exactly
146
+ * what we collect" is the part of this convention that lets a person check the collection.
147
147
  */
148
148
  export function buildPayload(args) {
149
149
  const env = args.env ?? process.env;
@@ -167,7 +167,7 @@ export function buildPayload(args) {
167
167
  // like any other new adopter and is indistinguishable from one. It is also the exact
168
168
  // population we are trying to count, so a busy self-study day reads as an adoption spike.
169
169
  // Stamped rather than suppressed, the same shape as `ci`: participant runs stay visible and
170
- // stay separable, and we keep a genuine measurement of what a cold install does (#546).
170
+ // stay separable, and we keep a genuine measurement of what a cold install does.
171
171
  studyParticipant: env.HUMANISH_STUDY_PARTICIPANT !== undefined &&
172
172
  env.HUMANISH_STUDY_PARTICIPANT !== "" &&
173
173
  env.HUMANISH_STUDY_PARTICIPANT !== "0",
@@ -175,8 +175,12 @@ export function buildPayload(args) {
175
175
  const given = args.properties ?? {};
176
176
  if (given.command !== undefined)
177
177
  properties.command = given.command;
178
- if (given.lab !== undefined)
179
- properties.lab = given.lab;
178
+ if (given.study !== undefined) {
179
+ properties.study = given.study;
180
+ // Removed in 0.109.0: `lab`, the property's 0.107 name, carries the same value until then, so
181
+ // a dashboard that filters on `lab` keeps reading 0.108 events while older clients send `lab`.
182
+ properties.lab = given.study;
183
+ }
180
184
  if (given.mode !== undefined)
181
185
  properties.mode = given.mode;
182
186
  if (given.outcome !== undefined)
@@ -202,7 +206,7 @@ const OWN_ERROR_CODE = /^HUMANISH_[A-Z0-9_]{1,80}$/;
202
206
  /**
203
207
  * The closed vocabulary an outcome may take. Actor statuses (src/actors/contract.ts), the two
204
208
  * shared-world extras, a fan-out roll-up, and the two shapes a non-study command has. Anything
205
- * else — a provider's reason string, a scorer's verdict text — is dropped, never forwarded.
209
+ * else (a provider's reason string, a scorer's verdict text) is dropped, never forwarded.
206
210
  */
207
211
  const OUTCOMES = new Set([
208
212
  "passed",
@@ -234,14 +238,14 @@ function asRecord(value) {
234
238
  /**
235
239
  * Read the study facts off a command's result document: mode, outcome, starter lab, brain route,
236
240
  * and our own error code. Duck-typed over every result shape the CLI writes, because the point is
237
- * ONE derivation at the one seam every command already passes through (writeResult), so that a
241
+ * one derivation at the one seam every command already passes through (writeResult), so that a
238
242
  * backend added later cannot forget to report. Returns {} for results that carry no study.
239
243
  *
240
244
  * The first two days of 0.62.0 data had 1,359 `run`/`lab run` events and not one carried a mode
241
- * or an outcome — the vocabulary existed, nothing populated it — so the one question telemetry
242
- * was added to answer ("does anyone get to a working LIVE first run") had no answer in the data.
245
+ * or an outcome (the vocabulary existed, nothing populated it), so the one question telemetry
246
+ * was added to answer ("does anyone get to a working live first run") had no answer in the data.
243
247
  */
244
- export function deriveStudyFacts(result) {
248
+ export function deriveRunFacts(result) {
245
249
  const r = asRecord(result);
246
250
  if (!r)
247
251
  return {};
@@ -252,21 +256,25 @@ export function deriveStudyFacts(result) {
252
256
  facts.mode = "live";
253
257
  else if (r.mode === "dry-run" || r.mode === "live")
254
258
  facts.mode = r.mode;
255
- const labRecord = asRecord(r.lab);
256
- const labId = typeof r.labId === "string"
257
- ? r.labId
258
- : typeof labRecord?.id === "string"
259
- ? labRecord.id
260
- : typeof r.lab === "string"
261
- ? r.lab
262
- : undefined;
263
- const lab = safeLabId(labId);
264
- if (lab !== undefined)
265
- facts.lab = lab;
259
+ const studyRecord = asRecord(r.study) ?? asRecord(r.lab);
260
+ const labId = typeof r.studyId === "string"
261
+ ? r.studyId
262
+ : typeof r.labId === "string"
263
+ ? r.labId
264
+ : typeof studyRecord?.id === "string"
265
+ ? studyRecord.id
266
+ : typeof r.study === "string"
267
+ ? r.study
268
+ : typeof r.lab === "string"
269
+ ? r.lab
270
+ : undefined;
271
+ const study = safeStudyId(labId);
272
+ if (study !== undefined)
273
+ facts.study = study;
266
274
  const error = asRecord(r.error);
267
275
  if (typeof error?.code === "string" && OWN_ERROR_CODE.test(error.code))
268
276
  facts.errorCode = error.code;
269
- const cuaResult = r.schema === "humanish.cua-lab-result.v2";
277
+ const cuaResult = r.schema === STUDY_RESULT_SCHEMA && r.route === "computer-use";
270
278
  const diagnostics = cuaResult ? asRecord(r.diagnostics) : undefined;
271
279
  if (isCuaDiagnosticCategory(diagnostics?.category))
272
280
  facts.diagnosticCategory = diagnostics.category;
package/dist/cli.js CHANGED
@@ -2,6 +2,6 @@
2
2
  import { preflightObserverArtifact } from "./observer/artifact.js";
3
3
  import { createProgram, normalizeCliArgv } from "./cli/program.js";
4
4
  // Resolve (and in a repo checkout, build) the Observer artifact up front, so a
5
- // problem surfaces before any run does work — never after a completed session.
5
+ // problem surfaces before any run does work, never after a completed session.
6
6
  preflightObserverArtifact();
7
7
  await createProgram().parseAsync(normalizeCliArgv(process.argv));