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
@@ -0,0 +1,182 @@
1
+ import { formatAutomaticAnalysisBudget } from "../../analysis/automatic-config.js";
2
+ import { resolve } from "node:path";
3
+ import { Command, Option } from "commander";
4
+ import { inspectLabManifest, listLabManifests } from "../../lab/discover.js";
5
+ import { runLabPreflight, } from "../../lab/preflight.js";
6
+ import { addRunOptions, handleRun } from "./run-command.js";
7
+ import { deprecationMessage, warnAndQueue } from "../deprecations.js";
8
+ import { applyEnvFileOption, CWD_OPTION_DESCRIPTION, ENV_FILE_OPTION_DESCRIPTION, JSON_OPTION_DESCRIPTION, parsePositiveInteger, writeResult, humanError, } from "../io.js";
9
+ export function registerStudyCommands(parent, io) {
10
+ const study = parent
11
+ .command("study")
12
+ .description("List, show and check studies in humanish/studies/.");
13
+ listCommand(study.command("list"), io);
14
+ showCommand(study.command("show"), io);
15
+ checkCommand(study.command("check"), io);
16
+ // Removed in 0.109.0: the `lab` group stays one minor, hidden. Its list, inspect and preflight
17
+ // run as study list, show and check, and `lab run` runs as `run`, each after a warning.
18
+ const lab = parent
19
+ .command("lab", { hidden: true })
20
+ .description("Deprecated: use humanish study.");
21
+ listCommand(lab.command("list"), io, "humanish study list");
22
+ showCommand(lab.command("inspect"), io, "humanish study show <study>");
23
+ checkCommand(lab.command("preflight"), io, "humanish study check <study>");
24
+ addRunOptions(lab.command("run", { hidden: true }).argument("<study>", "Study id or .yaml path.")).action((name, options, command) => {
25
+ warnOldCommand(command, io, "humanish run <study>");
26
+ return handleRun(io, name, options, command);
27
+ });
28
+ }
29
+ /** The warning for a `lab` subcommand, naming its replacement. */
30
+ function warnOldCommand(command, io, replacement) {
31
+ warnAndQueue(command, io, deprecationMessage(`humanish lab ${command.name()}`, replacement));
32
+ }
33
+ function listCommand(command, io, replacement) {
34
+ command
35
+ .description("List the studies in this project, committed and local.")
36
+ .option("--cwd <path>", CWD_OPTION_DESCRIPTION, ".")
37
+ .option("--json", JSON_OPTION_DESCRIPTION)
38
+ .action((options, command) => {
39
+ if (replacement !== undefined)
40
+ warnOldCommand(command, io, replacement);
41
+ return handleStudyList(io, options, command);
42
+ });
43
+ if (replacement !== undefined)
44
+ command.description(`Deprecated: use ${replacement}.`);
45
+ }
46
+ function showCommand(command, io, replacement) {
47
+ command
48
+ .argument("<study>", "Study id or .yaml path.")
49
+ .description("Show a study's parsed file and its warnings without running it.")
50
+ .option("--cwd <path>", CWD_OPTION_DESCRIPTION, ".")
51
+ .option("--json", JSON_OPTION_DESCRIPTION)
52
+ .action((name, options, command) => {
53
+ if (replacement !== undefined)
54
+ warnOldCommand(command, io, replacement);
55
+ return handleStudyShow(io, name, options, command);
56
+ });
57
+ if (replacement !== undefined)
58
+ command.description(`Deprecated: use ${replacement}.`);
59
+ }
60
+ function checkCommand(command, io, replacement) {
61
+ command
62
+ .argument("<study>", "Study id or .yaml path.")
63
+ .description("Check the study file and, with --reachability, its named endpoints. humanish doctor --study <study> checks this machine.")
64
+ .option("--cwd <path>", CWD_OPTION_DESCRIPTION, ".")
65
+ .addOption(new Option("--reachability <mode>", "Reachability mode.")
66
+ .choices(["metadata", "public-preview", "sandbox-loopback", "prepared-host"])
67
+ .default("metadata"))
68
+ .option("--timeout-ms <ms>", "Target reachability timeout.", String(30_000))
69
+ .option("--env-file <path>", ENV_FILE_OPTION_DESCRIPTION)
70
+ .option("--json", JSON_OPTION_DESCRIPTION)
71
+ .action((name, options, command) => {
72
+ if (replacement !== undefined)
73
+ warnOldCommand(command, io, replacement);
74
+ return handleStudyCheck(io, name, options, command);
75
+ });
76
+ if (replacement !== undefined)
77
+ command.description(`Deprecated: use ${replacement}.`);
78
+ }
79
+ async function handleStudyList(io, options, command) {
80
+ const result = await listLabManifests(options.cwd);
81
+ writeResult(command, io, result, formatStudyListHuman);
82
+ io.setExitCode(0);
83
+ }
84
+ async function handleStudyShow(io, name, options, command) {
85
+ const result = await inspectLabManifest(options.cwd, name);
86
+ writeResult(command, io, result, formatStudyShowHuman);
87
+ io.setExitCode(result.ok ? 0 : 2);
88
+ }
89
+ async function handleStudyCheck(io, name, options, command) {
90
+ if (!(await applyEnvFileOption({
91
+ command,
92
+ cwd: options.cwd,
93
+ envFile: options.envFile,
94
+ io,
95
+ }))) {
96
+ return;
97
+ }
98
+ const timeoutMs = parsePositiveInteger(options.timeoutMs);
99
+ if (timeoutMs === null) {
100
+ const result = {
101
+ schema: "humanish.study-check.v1",
102
+ ok: false,
103
+ cwd: resolve(options.cwd),
104
+ study: name,
105
+ reachability: options.reachability,
106
+ checks: [{ name: "timeout", ok: false, message: "--timeout-ms must be a positive integer." }],
107
+ targets: [],
108
+ sandbox: { created: false },
109
+ spend: { e2bDesktop: false, model: false },
110
+ warnings: [],
111
+ error: {
112
+ code: "HUMANISH_STUDY_PREFLIGHT_INVALID_OPTION",
113
+ message: "--timeout-ms must be a positive integer.",
114
+ },
115
+ };
116
+ writeResult(command, io, result, formatStudyCheckHuman);
117
+ io.setExitCode(2);
118
+ return;
119
+ }
120
+ const result = await runLabPreflight({
121
+ cwd: options.cwd,
122
+ lab: name,
123
+ reachability: options.reachability,
124
+ timeoutMs,
125
+ });
126
+ writeResult(command, io, result, formatStudyCheckHuman);
127
+ io.setExitCode(result.ok ? 0 : 2);
128
+ }
129
+ function formatStudyListHuman(result) {
130
+ if (result.studies.length === 0) {
131
+ return ([
132
+ `No studies found in ${result.cwd}`,
133
+ "Create one under humanish/studies/*.yaml, or pass a .yaml path.",
134
+ ...result.warnings.map((warning) => `warning: ${warning}`),
135
+ ].join("\n") + "\n");
136
+ }
137
+ return ([
138
+ "humanish studies",
139
+ ...result.studies.map((lab) => `- ${lab.id} ${lab.source} ${lab.origin} ${lab.path}${lab.title ? ` (${lab.title})` : ""}${lab.error ? `\n error: ${lab.error}` : ""}`),
140
+ ...result.warnings.map((warning) => `warning: ${warning}`),
141
+ ].join("\n") + "\n");
142
+ }
143
+ function formatStudyShowHuman(result) {
144
+ if (!result.ok || !result.config)
145
+ return humanError(result.error);
146
+ const config = result.config;
147
+ return ([
148
+ "humanish study",
149
+ `id: ${config.id}`,
150
+ `subject: ${config.subject.source}`,
151
+ ...(config.execution?.target ? [`execution: ${config.execution.target}`] : []),
152
+ `actors: ${config.actors.map((actor) => actor.type).join(", ")}`,
153
+ ...(config.title ? [`title: ${config.title}`] : []),
154
+ ...(config.description ? [`description: ${config.description}`] : []),
155
+ ...(result.path ? [`path: ${result.path}`] : []),
156
+ ...(result.origin ? [`origin: ${result.origin}`] : []),
157
+ ...(config.subject.repos?.length ? [`repos: ${config.subject.repos.join(", ")}`] : []),
158
+ ...(result.personas ?? []).map((persona) => `persona ${persona.id}: ${persona.brief ? `authored context (before runtime additions)\n${persona.brief.text}` : "unresolved; id only"}`),
159
+ ...result.warnings.map((warning) => `warning: ${warning}`),
160
+ ].join("\n") + "\n");
161
+ }
162
+ function formatStudyCheckHuman(result) {
163
+ const checkedTargets = result.targets.filter((target) => target.checked);
164
+ const reachableTargets = checkedTargets.filter((target) => target.reachable === true);
165
+ const blockedTargets = result.targets.filter((target) => target.status === "blocked");
166
+ const stdout = [
167
+ `humanish study check ${result.ok ? "passed" : "failed"}`,
168
+ `study: ${result.studyId ?? result.study}`,
169
+ ...(result.route ? [`route: ${result.route}`] : []),
170
+ `reachability: ${result.reachability}`,
171
+ `targets: ${checkedTargets.length ? `${reachableTargets.length}/${checkedTargets.length} reachable` : `${result.targets.length} declared, not checked`}`,
172
+ ...(blockedTargets.length ? [`blocked-targets: ${blockedTargets.length}`] : []),
173
+ `spend: ${result.spend.e2bDesktop ? "one e2b desktop, no model calls" : "none"}`,
174
+ ...(result.analysis ? [formatAutomaticAnalysisBudget(result.analysis)] : []),
175
+ ...(result.sandbox.created
176
+ ? [`sandbox: created=yes killed=${result.sandbox.killed === true ? "yes" : "no"}`]
177
+ : []),
178
+ ...result.checks.map((check) => `- ${check.ok ? "ok" : "fail"} ${check.name}: ${check.message}`),
179
+ ...result.warnings.map((warning) => `warning: ${warning}`),
180
+ ].join("\n") + "\n";
181
+ return result.error === undefined ? stdout : { stdout, error: result.error };
182
+ }
@@ -5,7 +5,7 @@ import { type TuiModule } from "../../tui/contract.js";
5
5
  import { type CliIo } from "../io.js";
6
6
  /**
7
7
  * The pieces of the outside world the `tui` command touches. Injectable for the same reason
8
- * `keyDiscovery` is: the refusals ARE the behavior worth testing, and a test cannot make a real
8
+ * `keyDiscovery` is: the refusals are the behavior worth testing, and a test cannot make a real
9
9
  * TTY, an old Node, or a missing bundle appear.
10
10
  */
11
11
  export interface TuiRuntime {
@@ -21,12 +21,12 @@ export interface TuiRuntime {
21
21
  }
22
22
  export declare const defaultTuiRuntime: TuiRuntime;
23
23
  /**
24
- * The stakeholder surface (#455). Every other command is written so an agent can drive it; this one
25
- * is the opposite — it takes the screen and waits for a person.
24
+ * The stakeholder surface. Every other command is written so an agent can drive it; this one
25
+ * is the opposite: it takes the screen and waits for a person.
26
26
  *
27
27
  * That inversion is why it refuses rather than degrades. An agent that runs `humanish tui` with a
28
28
  * piped stdout has asked for something that cannot exist, and the useful answer is a structured
29
- * error naming the command that WOULD have answered the question. A TUI that quietly rendered
29
+ * error naming the command that would have answered the question. A TUI that quietly rendered
30
30
  * frames into a pipe would poison a transcript with escape codes and look like a hang.
31
31
  */
32
32
  export declare function registerTuiCommand(parent: Command, io: CliIo, runtime?: TuiRuntime): void;
@@ -19,7 +19,7 @@ import { readRunDetail } from "../../run/detail.js";
19
19
  import { launchRun, readLaunchLogTail } from "../../tui/launch.js";
20
20
  import { TUI_MIN_NODE_MAJOR, nodeSupportsTui, TUI_BUNDLE_URL, } from "../../tui/contract.js";
21
21
  import { detectAgentSession } from "../../actors/agent-session.js";
22
- import { applyEnvFileOption, CLI_VERSION, JSON_OPTION_DESCRIPTION, markInvocationEnvelopeWritten, wantsJson, } from "../io.js";
22
+ import { applyEnvFileOption, CLI_VERSION, CWD_OPTION_DESCRIPTION, ENV_FILE_OPTION_DESCRIPTION, JSON_OPTION_DESCRIPTION, markInvocationEnvelopeWritten, wantsJson, } from "../io.js";
23
23
  export const defaultTuiRuntime = {
24
24
  checkComms: checkCommsConnection,
25
25
  promptSecret,
@@ -45,21 +45,21 @@ function refuseTui(command, io, refusal) {
45
45
  io.setExitCode(2);
46
46
  }
47
47
  /**
48
- * The stakeholder surface (#455). Every other command is written so an agent can drive it; this one
49
- * is the opposite — it takes the screen and waits for a person.
48
+ * The stakeholder surface. Every other command is written so an agent can drive it; this one
49
+ * is the opposite: it takes the screen and waits for a person.
50
50
  *
51
51
  * That inversion is why it refuses rather than degrades. An agent that runs `humanish tui` with a
52
52
  * piped stdout has asked for something that cannot exist, and the useful answer is a structured
53
- * error naming the command that WOULD have answered the question. A TUI that quietly rendered
53
+ * error naming the command that would have answered the question. A TUI that quietly rendered
54
54
  * frames into a pipe would poison a transcript with escape codes and look like a hang.
55
55
  */
56
56
  export function registerTuiCommand(parent, io, runtime = defaultTuiRuntime) {
57
57
  parent
58
58
  .command("tui")
59
- .description("Open the interactive terminal surface for browsing labs and runs (humans only).")
60
- .summary("Human terminal for labs and runs; refuses detected agent sessions and non-TTY input/output. Agents: humanish lab list --json, humanish lab inspect <lab> --json, humanish runs --json.")
61
- .option("--cwd <path>", "Target project directory.", ".")
62
- .option("--env-file <path>", "Load a local env file for this terminal session and its runs without printing values.")
59
+ .description("Browse studies and runs in an interactive terminal UI. It refuses detected agent sessions and non-TTY input or output; agents use humanish study list --json, humanish study show <study> --json and humanish runs --json.")
60
+ .summary("Browse studies and runs in a terminal UI for people.")
61
+ .option("--cwd <path>", CWD_OPTION_DESCRIPTION, ".")
62
+ .option("--env-file <path>", ENV_FILE_OPTION_DESCRIPTION)
63
63
  .option("--force", "Open it anyway in a session that looks like an agent's.")
64
64
  .option("--json", JSON_OPTION_DESCRIPTION)
65
65
  .action((options, command) => handleTui(io, runtime, options, command));
@@ -70,7 +70,7 @@ async function handleTui(io, runtime, options, command) {
70
70
  refuseTui(command, io, refusal);
71
71
  return;
72
72
  }
73
- // The Ink app ships as a pre-built bundle beside the compiled CLI and is loaded ONLY here, so
73
+ // The Ink app ships as a pre-built bundle beside the compiled CLI and is loaded only here, so
74
74
  // no agent-facing command pays its parse cost.
75
75
  const bundle = TUI_BUNDLE_URL;
76
76
  const loaded = await runtime.loadTui(bundle);
@@ -80,7 +80,7 @@ async function handleTui(io, runtime, options, command) {
80
80
  ok: false,
81
81
  error: {
82
82
  code: "HUMANISH_TUI_BUNDLE_MISSING",
83
- message: `The terminal surface bundle is missing at ${bundle.pathname}. In a checkout, run \`pnpm build\`; in an install, this package is incomplete — please report it.`,
83
+ message: `The terminal surface bundle is missing at ${bundle.pathname}. In a checkout, run \`pnpm build\`; an installed package always ships it, so please report this as a bug.`,
84
84
  },
85
85
  });
86
86
  return;
@@ -102,12 +102,12 @@ async function handleTui(io, runtime, options, command) {
102
102
  }
103
103
  /** The refusal for a session the surface cannot serve, or undefined when it may open. */
104
104
  function checkTuiSession(runtime, force) {
105
- // An agent runner, even with a real terminal. `codex exec` allocates a PTY for the commands
106
- // it runs, so the TTY check below passes and the surface used to open: a study watched an
107
- // agent navigate the labs list and start a run it did not mean to start
108
- // (humanish/labs/handed-a-human-surface.yaml). A TTY says a terminal exists, not that anyone is
109
- // reading it. `--force` is the escape for the person who really is at this keyboard —
110
- // capturing frames from inside an agent session is exactly that case.
105
+ // An agent runner, even with a real terminal. `codex exec` allocates a PTY for the commands it
106
+ // runs, so the TTY check below passes for an agent too, and an agent in the surface can start a
107
+ // run it did not mean to start (humanish/studies/handed-a-human-surface.yaml records one). A TTY
108
+ // says a terminal exists, not that anyone is reading it. `--force` is the escape for the person
109
+ // who really is at this keyboard, and capturing frames from inside an agent session is exactly
110
+ // that case.
111
111
  const agent = force ? undefined : detectAgentSession(runtime.env);
112
112
  if (agent !== undefined) {
113
113
  return {
@@ -117,8 +117,8 @@ function checkTuiSession(runtime, force) {
117
117
  code: "HUMANISH_TUI_AGENT_SESSION",
118
118
  message: `humanish tui is a surface for a person, and ${agent.marker} says this session belongs to ${agent.runner}. ` +
119
119
  "It renders frames of escape codes into a transcript, and its keys can start runs. " +
120
- "`humanish runs --json` lists runs, `humanish lab list --json` lists the labs in this project, " +
121
- "and `humanish lab run <lab> --json` starts one. If you are a person at this keyboard, add --force.",
120
+ "`humanish runs --json` lists runs, `humanish study list --json` lists the studies in this project, " +
121
+ "and `humanish run <study> --json` starts one. If you are a person at this keyboard, add --force.",
122
122
  },
123
123
  };
124
124
  }
@@ -128,7 +128,7 @@ function checkTuiSession(runtime, force) {
128
128
  ok: false,
129
129
  error: {
130
130
  code: "HUMANISH_TUI_REQUIRES_TTY",
131
- message: "humanish tui needs an interactive terminal. For scripted or agent use, `humanish runs --json` lists the same runs and `humanish lab run --json` starts one.",
131
+ message: "humanish tui needs an interactive terminal. For scripted or agent use, `humanish runs --json` lists the same runs and `humanish run <lab> --json` starts one.",
132
132
  },
133
133
  };
134
134
  }
@@ -210,7 +210,7 @@ function tuiCapabilities(session) {
210
210
  });
211
211
  return session.connectionCheck;
212
212
  },
213
- labs: async () => (await listLabManifests(cwd)).labs.map((lab) => ({
213
+ labs: async () => (await listLabManifests(cwd)).studies.map((lab) => ({
214
214
  title: lab.title ?? lab.id,
215
215
  path: lab.path,
216
216
  })),
@@ -259,7 +259,7 @@ function tuiCapabilities(session) {
259
259
  ? {
260
260
  schema: TUI_ACTION_SCHEMA,
261
261
  ok: true,
262
- message: `set up humanish here — ${result.changes.filter((change) => change.action !== "skip").length} files written`,
262
+ message: `set up humanish here: ${result.changes.filter((change) => change.action !== "skip").length} files written`,
263
263
  }
264
264
  : {
265
265
  schema: TUI_ACTION_SCHEMA,
@@ -3,63 +3,63 @@ import { renderObserver, serveObserver } from "../../observer/render.js";
3
3
  import { WATCH_SAFE_NOT_APPLICABLE_MESSAGE } from "../../observer/exposure.js";
4
4
  import { runDryRun } from "../../run/dry-run.js";
5
5
  import { runLabCommand } from "./lab-run.js";
6
- import { applyEnvFileOption, collectRepeated, formatRunHuman, JSON_OPTION_DESCRIPTION, parseObserverPort, parsePositiveInteger, wantsJson, writeResult, } from "../io.js";
6
+ import { addRunOptions, studyOnlyFlags } from "./run-command.js";
7
+ import { deprecationMessage, oldStudyOption, studyOptionValue, warnAndQueue, } from "../deprecations.js";
8
+ import { applyEnvFileOption, collectRepeated, formatRunHuman, parseObserverPort, parsePositiveInteger, wantsJson, writeResult, } from "../io.js";
7
9
  import { followObserver, formatObserverHuman, watchExposeRequested } from "../observer-follow.js";
8
10
  export function registerWatchCommand(parent, io) {
9
- parent
11
+ // A run's flags come from addRunOptions, the helper `run` uses, so the two cannot drift.
12
+ addRunOptions(parent
10
13
  .command("watch")
11
- .argument("[lab]", "Optional lab id or .yaml path to run and observe.")
12
- .description("Run synthetic participants, open the observer, and keep the shell attached.")
13
- .summary("Run participants, open the observer, stay attached.")
14
- .option("--lab <id-or-path>", "Explicit lab id or .yaml path.")
15
- .option("--run <id>", "Watch an existing run id or latest pointer.")
16
- .option("--dry-run", "Lab only: render contract evidence without live provider spend.")
17
- .option("--sims <count>", "Start a fresh synthetic run with this many participants before rendering. Defaults to 4 when --run is omitted.")
18
- .option("--count <count>", "Lab only: override the headed desktop participant count.")
19
- .option("--scorer <path>", "Terminal/computer-use/shared-world labs only: repo-relative adopter scorer module (.mjs). Overrides review.scorer.ref. Executable code: review it as code.")
20
- .option("--run-id <id>", "Explicit run id for deterministic fixture tests; refused when that run already exists.")
21
- .option("--cwd <path>", "Target project directory.", ".")
22
- .option("--env-file <path>", "Load a local env file for this watch without persisting values.")
23
- .option("--open", "Open the observer in the default browser.")
24
- .option("--no-open", "Render without opening a browser.")
25
- .addOption(new Option("--follow", "Deprecated; human output follows by default.").hideHelp())
26
- .option("--detach", "Render/open once and exit without attached watch server.")
27
- .option("--port <port>", "Local observer server port when following.", "0")
28
- .option("--expose", "CUA lab only: expose the live run through an authenticated edge so you can watch from a phone. Requires edge auth.")
14
+ .argument("[study]", "Study id or .yaml path to run and observe.")
15
+ .description("Run a study, open its Observer and keep the shell attached.")
16
+ .summary("Run a study and follow it in the Observer.")
17
+ .option("--study <id-or-path>", "Study id or .yaml path, in place of the argument.")
18
+ .addOption(oldStudyOption("id-or-path"))
19
+ // Removed in 0.109.0: watch --run stays one minor, hidden; observe --run shows a saved run.
20
+ .addOption(new Option("--run <id>", "Deprecated: use humanish observe --run <id>.").hideHelp()))
21
+ .option("--expose", "Computer-use studies only: share the live run through an authenticated tunnel, to watch from a phone. Requires --oauth or --public-url.")
29
22
  .addOption(new Option("--tunnel <provider>", "Spawn the external tunnel binary against the loopback port.").choices(["ngrok"]))
30
23
  .option("--tunnel-domain <domain>", "Reserved domain passed to ngrok as --url (e.g. observer.example.com). Requires --tunnel.")
31
24
  .addOption(new Option("--oauth <provider>", "Turn on ngrok edge OAuth. Requires --tunnel.").choices([
32
25
  "google",
33
26
  ]))
34
- .option("--allow-email <addr>", "Edge OAuth allow rule: permit this email. Repeatable. Requires --oauth.", collectRepeated, [])
35
- .option("--allow-domain <domain>", "Edge OAuth allow rule: permit this domain. Repeatable. Requires --oauth.", collectRepeated, [])
27
+ .option("--allow-email <addr>", "Edge OAuth allow rule: permit this email. Repeatable. Requires --oauth.", collectRepeated)
28
+ .option("--allow-domain <domain>", "Edge OAuth allow rule: permit this domain. Repeatable. Requires --oauth.", collectRepeated)
36
29
  .option("--public-url <origin>", "Bring-your-own authed edge (Cloudflare Access/Tailscale/manual). Binds loopback and trusts your edge. Requires --expose.")
37
- .option("--safe", "Not applicable to watch: a live run is never share_ready, so --safe (a `serve` library filter) is rejected here. Restrict viewers with edge auth (--allow-email/--allow-domain).")
38
- .option("--json", JSON_OPTION_DESCRIPTION)
30
+ // Hidden: watch rejects --safe with a pointer to the library filter and to edge auth, which
31
+ // a bare "unknown option" would lose.
32
+ .addOption(new Option("--safe").hideHelp())
39
33
  .addHelpText("after", [
40
34
  "",
35
+ "Without a study or --run, watch starts a synthetic run of 4 participants; --count changes it.",
36
+ "",
41
37
  "Happy path:",
42
38
  " humanish watch",
43
39
  " humanish watch first-run",
44
- " humanish watch --lab .humanish/labs/local.yaml",
45
40
  "",
46
- "Watch a live CUA run from your phone (tunnel-edge auth):",
47
- " humanish watch my-cua-lab --expose --tunnel ngrok --oauth google --allow-email you@example.com",
41
+ "Watch a live computer-use run from your phone through an authenticated tunnel:",
42
+ " humanish watch my-browser-study --expose --tunnel ngrok --oauth google --allow-email you@example.com",
48
43
  "",
49
44
  "Agent/CI path:",
50
45
  " humanish watch --json --no-open",
51
46
  "",
52
- "Existing evidence:",
53
- " humanish watch --run latest --detach",
47
+ "Saved runs:",
48
+ " humanish observe --run latest",
54
49
  ].join("\n"))
55
- .action((labArg, options, command) => handleWatch(io, labArg, options, command));
50
+ .action((named, options, command) => handleWatch(io, named, options, command));
56
51
  }
57
- async function handleWatch(io, labArg, options, command) {
58
- const lab = options.lab ?? labArg;
59
- if (options.lab !== undefined && labArg !== undefined) {
52
+ async function handleWatch(io, named, parsed, command) {
53
+ const options = parsed;
54
+ if (options.run !== undefined) {
55
+ warnAndQueue(command, io, deprecationMessage("humanish watch --run", "humanish observe --run <id>"));
56
+ }
57
+ const option = studyOptionValue(command, io, options);
58
+ const study = option ?? named;
59
+ if (option !== undefined && named !== undefined) {
60
60
  refuseWatch(command, io, options.cwd, {
61
61
  code: "HUMANISH_WATCH_OPTION_CONFLICT",
62
- message: "Use either positional lab or --lab, not both.",
62
+ message: "Use either a study argument or --study, not both.",
63
63
  });
64
64
  return;
65
65
  }
@@ -73,21 +73,29 @@ async function handleWatch(io, labArg, options, command) {
73
73
  }))) {
74
74
  return;
75
75
  }
76
- if (lab) {
77
- await watchLab(io, command, lab, options);
76
+ if (study) {
77
+ await watchStudy(io, command, study, options);
78
+ return;
79
+ }
80
+ const studyOnly = studyOnlyFlags(options);
81
+ if (studyOnly.length > 0) {
82
+ refuseWatch(command, io, options.cwd, {
83
+ code: "HUMANISH_WATCH_OPTION_CONFLICT",
84
+ message: `${studyOnly.join(", ")} ${studyOnly.length === 1 ? "needs" : "need"} a study: humanish watch <study>.`,
85
+ });
78
86
  return;
79
87
  }
80
- // Exposure is only meaningful for a live CUA lab run (it serves the live desktop). The
88
+ // Exposure is only meaningful for a live computer-use study run (it serves the live desktop). The
81
89
  // non-lab watch path (existing evidence, or a fresh synthetic run) has no live desktop to
82
- // stream, so exposure flags there are refused rather than silently ignored — use `serve`.
90
+ // stream, so exposure flags there are refused rather than silently ignored; use `observe --all`.
83
91
  if (watchExposeRequested(options)) {
84
92
  refuseWatch(command, io, options.cwd, {
85
93
  code: "HUMANISH_WATCH_OPTION_CONFLICT",
86
- message: "--expose/--tunnel/--oauth apply only to a live CUA lab run; to expose finished evidence use `humanish serve --expose`.",
94
+ message: "--expose/--tunnel/--oauth apply only to a live computer-use run; to expose finished evidence use `humanish observe --all --expose`.",
87
95
  });
88
96
  return;
89
97
  }
90
- // --safe is a `serve` library filter; watch shows one run and has nothing it could filter.
98
+ // --safe is an `observe --all` library filter; watch shows one run and has nothing to filter.
91
99
  if (options.safe === true) {
92
100
  refuseWatch(command, io, options.cwd, {
93
101
  code: "HUMANISH_WATCH_SAFE_NOT_APPLICABLE",
@@ -106,7 +114,7 @@ async function handleWatch(io, labArg, options, command) {
106
114
  : options.open === true
107
115
  ? true
108
116
  : !wantsMachine && process.stdout.isTTY === true;
109
- const wantsFollow = !wantsMachine && options.detach !== true && options.follow !== false;
117
+ const wantsFollow = !wantsMachine && options.detach !== true;
110
118
  const staticOpen = wantsFollow ? false : shouldOpen;
111
119
  const rendered = await renderWatchEvidence(io, command, options, target.requestedParticipantCount, staticOpen);
112
120
  if (rendered === undefined)
@@ -128,57 +136,36 @@ function refuseWatch(command, io, cwd, refusal) {
128
136
  writeResult(command, io, result, formatRunHuman);
129
137
  io.setExitCode(2);
130
138
  }
131
- /** A lab argument starts that lab under watch; `--run` would name other evidence. */
132
- async function watchLab(io, command, lab, options) {
139
+ /** A study argument starts that study under watch; `--run` would name other evidence. */
140
+ async function watchStudy(io, command, study, options) {
133
141
  if (options.run !== undefined) {
134
142
  refuseWatch(command, io, options.cwd, {
135
143
  code: "HUMANISH_WATCH_OPTION_CONFLICT",
136
- message: "Use either a lab to start evidence or --run to watch existing evidence, not both.",
144
+ message: "Use either a study to start evidence or --run to watch existing evidence, not both.",
137
145
  });
138
146
  return;
139
147
  }
140
- await runLabCommand({
141
- command,
142
- io,
143
- lab,
144
- mode: "watch",
145
- options: {
146
- cwd: options.cwd,
147
- ...(options.count === undefined ? {} : { count: options.count }),
148
- ...(options.detach === undefined ? {} : { detach: options.detach }),
149
- ...(options.dryRun === undefined ? {} : { dryRun: options.dryRun }),
150
- ...(options.open === undefined ? {} : { open: options.open }),
151
- port: options.port,
152
- ...(options.runId === undefined ? {} : { runId: options.runId }),
153
- ...(options.scorer === undefined ? {} : { scorer: options.scorer }),
154
- ...(options.sims === undefined ? {} : { sims: options.sims }),
155
- ...(options.expose === undefined ? {} : { expose: options.expose }),
156
- ...(options.tunnel === undefined ? {} : { tunnel: options.tunnel }),
157
- ...(options.tunnelDomain === undefined ? {} : { tunnelDomain: options.tunnelDomain }),
158
- ...(options.oauth === undefined ? {} : { oauth: options.oauth }),
159
- allowEmail: options.allowEmail,
160
- allowDomain: options.allowDomain,
161
- ...(options.publicUrl === undefined ? {} : { publicUrl: options.publicUrl }),
162
- ...(options.safe === undefined ? {} : { safe: options.safe }),
163
- ...(options.json === undefined ? {} : { json: options.json }),
164
- },
165
- });
148
+ // Forwarded wholesale, as `run` forwards its options, so a run flag reaches the lab either way.
149
+ await runLabCommand({ command, io, lab: study, mode: "watch", options });
166
150
  }
167
- /** Without a lab, watch shows existing evidence (`--run`) or a fresh synthetic run (`--sims`). */
151
+ /** Without a study, watch shows existing evidence (`--run`) or a fresh synthetic run (`--count`). */
168
152
  function resolveWatchTarget(options, command) {
169
153
  const runOptionSource = typeof command.getOptionValueSource === "function"
170
154
  ? command.getOptionValueSource("run")
171
155
  : undefined;
172
156
  const runWasOmitted = runOptionSource === undefined || runOptionSource === "default";
173
- const participantCount = options.sims === undefined ? undefined : parsePositiveInteger(options.sims);
157
+ const participantCount = options.count === undefined ? undefined : parsePositiveInteger(options.count);
174
158
  const port = parseObserverPort(options.port);
175
- if (options.sims !== undefined && participantCount === null) {
176
- return { code: "HUMANISH_INVALID_SIM_COUNT", message: "--sims must be a positive integer." };
159
+ if (participantCount === null) {
160
+ return {
161
+ code: "HUMANISH_INVALID_PARTICIPANT_COUNT",
162
+ message: "--count must be a positive integer.",
163
+ };
177
164
  }
178
- if (!runWasOmitted && options.sims !== undefined) {
165
+ if (!runWasOmitted && participantCount !== undefined) {
179
166
  return {
180
167
  code: "HUMANISH_WATCH_OPTION_CONFLICT",
181
- message: "Use either --run to watch existing evidence or --sims to start a fresh run, not both.",
168
+ message: "Use either --run to watch existing evidence or --count to start a fresh run, not both.",
182
169
  };
183
170
  }
184
171
  if (!runWasOmitted && options.runId !== undefined) {
@@ -203,7 +190,7 @@ async function renderWatchEvidence(io, command, options, requestedParticipantCou
203
190
  const runResult = await runDryRun({
204
191
  cwd: options.cwd,
205
192
  dryRun: true,
206
- simCount: requestedParticipantCount,
193
+ participantCount: requestedParticipantCount,
207
194
  ...(options.runId === undefined ? {} : { runId: options.runId }),
208
195
  observer: { open: staticOpen },
209
196
  });
@@ -0,0 +1,18 @@
1
+ import { Option, type Command } from "commander";
2
+ import type { CliIo } from "./io.js";
3
+ /** `<old> is deprecated and is removed in the next minor. Use <replacement>.` */
4
+ export declare function deprecationMessage(old: string, replacement: string): string;
5
+ /** Print `warning: <message>` on stderr, and queue the message for the command's JSON result. */
6
+ export declare function warnAndQueue(command: Command, io: CliIo, message: string): void;
7
+ /** `output` with the command's queued warnings at the front of its `warnings`. */
8
+ export declare function withQueuedWarnings<T>(command: Command, output: T): T;
9
+ /**
10
+ * The 0.107 spelling of `--study`, hidden for one minor. Commander refuses it together with
11
+ * `--study`. Read the value with studyOptionValue.
12
+ */
13
+ export declare function oldStudyOption(valueName: string): Option;
14
+ /** The `--study` value, or the `--lab` value with its deprecation warning. */
15
+ export declare function studyOptionValue(command: Command, io: CliIo, options: {
16
+ study?: string | undefined;
17
+ lab?: string | undefined;
18
+ }): string | undefined;
@@ -0,0 +1,48 @@
1
+ // A warning a command prints, such as a deprecated spelling or a study file 0.109 stops reading,
2
+ // goes to stderr when it happens and into the `warnings` array of the command's JSON result, so a
3
+ // caller that reads only stdout sees it too. writeResult adds the queued warnings.
4
+ import { Option } from "commander";
5
+ const queued = new WeakMap();
6
+ /** `<old> is deprecated and is removed in the next minor. Use <replacement>.` */
7
+ export function deprecationMessage(old, replacement) {
8
+ return `${old} is deprecated and is removed in the next minor. Use ${replacement}.`;
9
+ }
10
+ /** Print `warning: <message>` on stderr, and queue the message for the command's JSON result. */
11
+ export function warnAndQueue(command, io, message) {
12
+ io.writeErr(`warning: ${message}\n`);
13
+ queued.set(command, [...(queued.get(command) ?? []), message]);
14
+ }
15
+ /** `output` with the command's queued warnings at the front of its `warnings`. */
16
+ export function withQueuedWarnings(command, output) {
17
+ const messages = queued.get(command);
18
+ if (messages === undefined || output === null || typeof output !== "object")
19
+ return output;
20
+ if (Array.isArray(output))
21
+ return output;
22
+ const existing = output.warnings;
23
+ if (existing !== undefined && !Array.isArray(existing))
24
+ return output;
25
+ return { ...output, warnings: [...messages, ...(existing ?? [])] };
26
+ }
27
+ /**
28
+ * The 0.107 spelling of `--study`, hidden for one minor. Commander refuses it together with
29
+ * `--study`. Read the value with studyOptionValue.
30
+ */
31
+ export function oldStudyOption(valueName) {
32
+ return new Option(`--lab <${valueName}>`).hideHelp().conflicts("study");
33
+ }
34
+ /** The `--study` value, or the `--lab` value with its deprecation warning. */
35
+ export function studyOptionValue(command, io, options) {
36
+ if (options.lab === undefined)
37
+ return options.study;
38
+ const path = commandPath(command);
39
+ warnAndQueue(command, io, deprecationMessage(`humanish ${path} --lab`, `humanish ${path} --study <study>`));
40
+ return options.lab;
41
+ }
42
+ /** The command's words after `humanish`, such as `comms check`. */
43
+ function commandPath(command) {
44
+ const words = [];
45
+ for (let at = command; at?.parent; at = at.parent)
46
+ words.unshift(at.name());
47
+ return words.join(" ");
48
+ }