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
@@ -11,12 +11,12 @@ export function desktopScreenshotCleanupFailures(desktop) {
11
11
  /**
12
12
  * @e2b/desktop 2.3.3 screenshot() awaits capture and files.read(path), then discards the
13
13
  * files.remove(path) promise. A removal that races sandbox teardown can therefore crash Node
14
- * AFTER valid bytes were returned. Installed-SDK conformance tests pin that behavior (#662).
14
+ * after valid bytes were returned. Installed-SDK conformance tests pin that behavior.
15
15
  *
16
- * Observe only removal of a file successfully read within THIS screenshot invocation. The
16
+ * Observe only removal of a file successfully read within this screenshot invocation. The
17
17
  * exact path comes from the SDK, not a guessed filename pattern. AsyncLocalStorage isolates
18
18
  * concurrent screenshots and unrelated file operations without changing SDK method receivers.
19
- * The ORIGINAL removal promise is returned: an SDK version (or caller) that awaits it still
19
+ * The original removal promise is returned: an SDK version (or caller) that awaits it still
20
20
  * receives the original rejection. No process-wide rejection handler or filesystem retry.
21
21
  */
22
22
  export function protectDesktopScreenshotCleanup(desktop) {
@@ -89,7 +89,7 @@ export declare const TRANSIENT_RETRY_DELAY_MS = 3000;
89
89
  * describing, the same routing gap seen from the upload side.
90
90
  * - transport resets (`fetch failed`, `ECONNRESET`, `socket hang up`, 502/503/504).
91
91
  *
92
- * NOT retried: timeouts (the budget is spent), auth (401/403), quota and rate limits (429: a burst
92
+ * Not retried: timeouts (the budget is spent), auth (401/403), quota and rate limits (429: a burst
93
93
  * that hit the limit should be spaced, not repeated), and anything that names the request as wrong.
94
94
  */
95
95
  export declare function isTransientE2BError(error: unknown): boolean;
@@ -27,7 +27,7 @@ async function acquire(request, template) {
27
27
  if (request.receipt !== null) {
28
28
  const { root, participantId, now = Date.now } = request.receipt;
29
29
  // Best effort by contract: a failed write leaves the TTL as the only backstop and never
30
- // fails the lane.
30
+ // fails the participant.
31
31
  await appendSandboxReceipt(root, {
32
32
  at: new Date(now()).toISOString(),
33
33
  laneId: participantId,
@@ -181,7 +181,7 @@ export const TRANSIENT_RETRY_DELAY_MS = 3_000;
181
181
  * describing, the same routing gap seen from the upload side.
182
182
  * - transport resets (`fetch failed`, `ECONNRESET`, `socket hang up`, 502/503/504).
183
183
  *
184
- * NOT retried: timeouts (the budget is spent), auth (401/403), quota and rate limits (429: a burst
184
+ * Not retried: timeouts (the budget is spent), auth (401/403), quota and rate limits (429: a burst
185
185
  * that hit the limit should be spaced, not repeated), and anything that names the request as wrong.
186
186
  */
187
187
  export function isTransientE2BError(error) {
@@ -3,7 +3,7 @@ export interface E2BDesktopModule {
3
3
  /** The stock `desktop` template (no custom image). */
4
4
  create(options: E2BDesktopCreateOptions): Promise<E2BDesktopSandbox>;
5
5
  /**
6
- * Launch on a CUSTOM E2B desktop template (image) by NAME or ID — the SDK's
6
+ * Launch on a custom E2B desktop template (image) by name or ID: the SDK's
7
7
  * `Sandbox.create(template, opts)` overload. Lets a lab run on an adopter-maintained image
8
8
  * with extra runtimes baked in (e.g. node/bun/a local Postgres the stock `desktop` template
9
9
  * lacks), instead of the stock template. The base @e2b/desktop SDK implements this; the
@@ -11,17 +11,17 @@ export interface E2BDesktopModule {
11
11
  */
12
12
  create(template: string, options: E2BDesktopCreateOptions): Promise<E2BDesktopSandbox>;
13
13
  /**
14
- * Kill the sandbox specified by exact id. Returns true iff THAT sandbox was found and
15
- * killed, false otherwise (the SDK's own doc comment). This boolean is the PRIMARY by-id
14
+ * Kill the sandbox specified by exact id. Returns true iff that sandbox was found and
15
+ * killed, false otherwise (the SDK's own doc comment). This boolean is the primary by-id
16
16
  * cleanup proof: a caller never needs to re-list to confirm reclamation.
17
17
  */
18
18
  kill?(sandboxId: string, options?: {
19
19
  requestTimeoutMs?: number;
20
20
  }): Promise<boolean>;
21
21
  /**
22
- * Fetch ONE sandbox by its exact id (never account-wide). Throws a SandboxNotFoundError-
22
+ * Fetch one sandbox by its exact id (never account-wide). Throws a SandboxNotFoundError-
23
23
  * shaped error (see isSandboxNotFoundError below) when the id no longer exists; that thrown
24
- * error IS the by-id confirmation that a killed sandbox is gone. Optional: older SDKs may
24
+ * error is the by-id confirmation that a killed sandbox is gone. Optional: older SDKs may
25
25
  * lack it, so callers fall back to kill()'s own boolean rather than ever calling Sandbox.list.
26
26
  */
27
27
  getInfo?(sandboxId: string, options?: {
@@ -123,10 +123,10 @@ export interface E2BDesktopSandbox {
123
123
  /** Open a file or URL with the desktop's default application (present on @e2b/desktop >= 1.x). */
124
124
  open?(fileOrUrl: string): Promise<void>;
125
125
  /**
126
- * Map an in-sandbox port to a reachable host URL — `https://<port>-<sandboxId>.e2b.app`,
127
- * TOKENLESS (no authKey, unlike `stream.getUrl`). The base `e2b` SDK (v2.27.0) implements this;
128
- * the wrapper just exposes it. Used by the CONCURRENT shared-world topology (#164 phase 2) to
129
- * expose the ONE subject service plane to N actor sandboxes. Optional: older SDKs may lack it, so
126
+ * Map an in-sandbox port to a reachable host URL, `https://<port>-<sandboxId>.e2b.app`,
127
+ * tokenless (no authKey, unlike `stream.getUrl`). The base `e2b` SDK (v2.27.0) implements this;
128
+ * the wrapper just exposes it. Used by the concurrent shared-world topology to
129
+ * expose the one subject service plane to N actor sandboxes. Optional: older SDKs may lack it, so
130
130
  * the concurrent backend fails closed when it is absent rather than calling a missing method.
131
131
  */
132
132
  getHost?(port: number): string;
@@ -169,7 +169,7 @@ export declare class E2BDesktopStartupError extends Error {
169
169
  constructor(error: unknown, cleanup: DesktopCreateCleanup, cleanupDetail?: string | undefined);
170
170
  }
171
171
  /**
172
- * Preserve ownership before the desktop SDK starts Xvfb/XFCE (#581). Its public generic create
172
+ * Preserve ownership before the desktop SDK starts Xvfb/XFCE. Its public generic create
173
173
  * constructs `new this(...)` through the base SDK, then awaits desktop startup. Newer SDKs
174
174
  * attempt their own kill before rejecting create; older SDKs leave cleanup to the caller.
175
175
  * Both paths share one bounded cleanup result so an internal kill cannot delay our deadline
@@ -183,7 +183,7 @@ export declare class E2BDesktopStartupError extends Error {
183
183
  */
184
184
  export declare function guardDesktopSandboxCreate(module: E2BDesktopModule): E2BDesktopModule;
185
185
  /**
186
- * Detect a SandboxNotFoundError-shaped error from the real @e2b/desktop SDK, WITHOUT importing
186
+ * Detect a SandboxNotFoundError-shaped error from the real @e2b/desktop SDK, without importing
187
187
  * its class (this module stays optional-peer / lazily-loaded, same as everything else here).
188
188
  * The real SDK sets `this.name = "SandboxNotFoundError"` on the class (it extends the
189
189
  * deprecated NotFoundError), so checking `.name` is the stable, import-free detection contract.
@@ -2,8 +2,8 @@
2
2
  // real @e2b/desktop Sandbox. Every desktop route launches through this one seam; the peer dep is
3
3
  // optional and lazily loaded, so it stays out of the published tarball and CI.
4
4
  //
5
- // E2BDesktopSandbox is the command, file, stream, launch and input subset the lanes use; `open` is
6
- // optional because older SDKs lack it (the computer-use lane then falls back to launch). It
5
+ // E2BDesktopSandbox is the command, file, stream, launch and input subset the participants use; `open` is
6
+ // optional because older SDKs lack it (the computer-use route then falls back to launch). It
7
7
  // satisfies the executor's E2BDesktopLike port (src/substrates/e2b/desktop-executor.ts) as is.
8
8
  import { sep } from "node:path";
9
9
  import { fileURLToPath } from "node:url";
@@ -18,8 +18,8 @@ export async function loadE2BDesktopModule() {
18
18
  ? "Live E2B desktop launch requires the optional peer @e2b/desktop. Install it beside humanish " +
19
19
  "in this project: `npm i -D @e2b/desktop`."
20
20
  : "Live E2B desktop launch requires the optional peer @e2b/desktop, and humanish is running from an " +
21
- "npx cache rather than from this project — so installing the peer here cannot help, because Node " +
22
- "resolves it relative to humanish itself. Install BOTH into the project and run it from there: " +
21
+ "npx cache. Node resolves the peer relative to humanish itself, so a copy installed in this project " +
22
+ "is not found. Install both into the project and run it from there: " +
23
23
  "`npm i -D humanish @e2b/desktop` then `npx humanish run <lab>`.");
24
24
  }
25
25
  throw error;
@@ -44,7 +44,7 @@ export class E2BDesktopStartupError extends Error {
44
44
  }
45
45
  }
46
46
  /**
47
- * Preserve ownership before the desktop SDK starts Xvfb/XFCE (#581). Its public generic create
47
+ * Preserve ownership before the desktop SDK starts Xvfb/XFCE. Its public generic create
48
48
  * constructs `new this(...)` through the base SDK, then awaits desktop startup. Newer SDKs
49
49
  * attempt their own kill before rejecting create; older SDKs leave cleanup to the caller.
50
50
  * Both paths share one bounded cleanup result so an internal kill cannot delay our deadline
@@ -147,8 +147,8 @@ async function reclaimFailedDesktopCreate(kill, timeoutMs) {
147
147
  /**
148
148
  * Is humanish running from this project's node_modules, or from an npx cache?
149
149
  *
150
- * It decides which advice is TRUE. `npx humanish@latest` resolves its optional peer relative to
151
- * ITSELF, so "install @e2b/desktop in this project" is advice that cannot work there — and that
150
+ * It decides which advice is true. `npx humanish@latest` resolves its optional peer relative to
151
+ * itself, so "install @e2b/desktop in this project" is advice that cannot work there, and that
152
152
  * message cost two cold verification runs before the difference was noticed. A one-shot npx
153
153
  * invocation cannot do a live desktop run at all; humanish has to be installed alongside the peer.
154
154
  */
@@ -161,7 +161,7 @@ function isMissingE2BDesktopDependency(error) {
161
161
  return value.code === "ERR_MODULE_NOT_FOUND" && value.message?.includes("@e2b/desktop") === true;
162
162
  }
163
163
  /**
164
- * Detect a SandboxNotFoundError-shaped error from the real @e2b/desktop SDK, WITHOUT importing
164
+ * Detect a SandboxNotFoundError-shaped error from the real @e2b/desktop SDK, without importing
165
165
  * its class (this module stays optional-peer / lazily-loaded, same as everything else here).
166
166
  * The real SDK sets `this.name = "SandboxNotFoundError"` on the class (it extends the
167
167
  * deprecated NotFoundError), so checking `.name` is the stable, import-free detection contract.
@@ -16,6 +16,8 @@ export declare function runtimeExec(file: string, args: string[], options?: Runt
16
16
  stdout: string;
17
17
  stderr: string;
18
18
  }>;
19
+ /** The shell command an operator runs for `docker <args>` on this host, as runtimeDocker runs it. */
20
+ export declare function dockerCommandLine(args: string[], options?: RuntimeHostOptions): string;
19
21
  export declare function runtimeDocker(args: string[], options?: RuntimeHostOptions, timeout?: number): Promise<{
20
22
  stdout: string;
21
23
  stderr: string;
@@ -30,6 +30,12 @@ export async function runtimeExec(file, args, options = {}, timeout = 15_000) {
30
30
  ? hostExec("limactl", ["shell", "--workdir", "/", LIMA_INSTANCE, "--", file, ...args], options, timeout)
31
31
  : hostExec(file, args, options, timeout);
32
32
  }
33
+ /** The shell command an operator runs for `docker <args>` on this host, as runtimeDocker runs it. */
34
+ export function dockerCommandLine(args, options = {}) {
35
+ return usesLima(options)
36
+ ? `limactl shell ${LIMA_INSTANCE} -- sudo docker --host unix:///var/run/docker.sock ${args.join(" ")}`
37
+ : `docker ${args.join(" ")}`;
38
+ }
33
39
  export async function runtimeDocker(args, options = {}, timeout = 15_000) {
34
40
  return usesLima(options)
35
41
  ? runtimeExec("sudo", ["-n", "docker", "--host", "unix:///var/run/docker.sock", ...args], options, timeout)
@@ -25,15 +25,17 @@ export declare function createTuiObserverSession(cwdInput: string, options?: {
25
25
  * The counterpart to starting one: a study that is going nowhere costs money every turn, and until
26
26
  * now the only way to end it was to find the pid yourself.
27
27
  *
28
- * It signals the PROCESS GROUP, not the process. A run is spawned detached — its own group — and it
28
+ * It signals the process group, not the process. A run is spawned detached, in its own group, and it
29
29
  * has children: the CLI, and whatever it spawned to reach the sandbox. Signalling only the parent
30
30
  * leaves those orphaned and still working.
31
31
  *
32
- * SIGTERM, never SIGKILL: the run's own handlers get the chance to finalize its record and release
33
- * what it holds. A killed run leaves a `running` record to go stale, which reads as interrupted —
34
- * true, but strictly less informative than a run that was told to stop.
32
+ * SIGTERM, never SIGKILL, so the run's handler gets to act. Outside post-run analysis the run
33
+ * command (src/cli/commands/run-signals.ts) marks the run `interrupted` in status.json, kills the
34
+ * E2B sandboxes its receipts name, writes reclaim-receipt.json and exits; run.json keeps its last
35
+ * live flush. During analysis the signal cancels analysis instead. A local VM's container exits
36
+ * when the run's process goes.
35
37
  *
36
- * This stops the PROCESS. Sandboxes it created are a separate resource with their own receipts, and
37
- * `Reclaim` is what stops those — the run screen offers it as soon as this succeeds.
38
+ * `Reclaim` stays on offer: it retries by id any kill the handler could not confirm within its
39
+ * 10 s deadline. Each sandbox's create-time timeout is the backstop.
38
40
  */
39
41
  export declare function stopRun(cwd: string, runId: string, intent?: "run" | "analysis"): Promise<TuiActionResult>;
@@ -1,9 +1,9 @@
1
- import { requestAutomaticStudyAnalysisCancellation } from "../analysis/automatic.js";
2
- // The two things a run card can DO (#455 rev 8).
1
+ import { requestAutomaticAnalysisCancellation } from "../analysis/automatic.js";
2
+ // The two things a run card can do.
3
3
  //
4
- // The mock's run screen is an outcome CARD with actions, not a field list, and an action that does
5
- // nothing is worse than no action — so this ships the two that are genuinely implementable today
6
- // and nothing else. `Share…` waits for the export contract (#471) rather than appearing as a
4
+ // The mock's run screen is an outcome card with actions, not a field list, and an action that does
5
+ // nothing is worse than no action, so this ships the two that are genuinely implementable today
6
+ // and nothing else. `Share…` waits for the export contract rather than appearing as a
7
7
  // control that fails.
8
8
  import { readFile } from "node:fs/promises";
9
9
  import path from "node:path";
@@ -32,7 +32,7 @@ export function createTuiObserverSession(cwdInput, options = {}) {
32
32
  return {
33
33
  async open(targetCwd, observerPath) {
34
34
  if (closed)
35
- return result(false, "this terminal session has closed — reopen humanish tui to view the run");
35
+ return result(false, "this terminal session has closed; reopen `humanish tui` to view the run");
36
36
  if (path.resolve(targetCwd) !== cwd)
37
37
  return result(false, "Observer can only open runs from this terminal session's project");
38
38
  // The capability takes the run-card path, not an arbitrary file, URL, or second project.
@@ -58,7 +58,7 @@ export function createTuiObserverSession(cwdInput, options = {}) {
58
58
  return result(false, "this run's evidence directory is missing or unsafe to open");
59
59
  }
60
60
  if (closed)
61
- return result(false, "this terminal session has closed — reopen humanish tui to view the run");
61
+ return result(false, "this terminal session has closed; reopen `humanish tui` to view the run");
62
62
  try {
63
63
  // Share the pending start too: two quick selections must not create two listeners.
64
64
  serverPromise ??= serveObserverLibrary(cwd, {
@@ -78,13 +78,13 @@ export function createTuiObserverSession(cwdInput, options = {}) {
78
78
  });
79
79
  const server = await serverPromise;
80
80
  if (closed)
81
- return result(false, "this terminal session has closed — reopen humanish tui to view the run");
81
+ return result(false, "this terminal session has closed; reopen `humanish tui` to view the run");
82
82
  const url = new URL(`_humanish/runs/${encodeURIComponent(runId)}/observer/index.html`, server.url).href;
83
83
  const opened = open(url);
84
- return result(true, `${url} — follows saved captures; keep this TUI open.${opened.warning ? ` ${opened.warning}` : " If no browser appeared, open this URL on this machine or forward its port over SSH."}`);
84
+ return result(true, `${url} follows saved captures while you keep this TUI open.${opened.warning ? ` ${opened.warning}` : " If no browser appeared, open this URL on this machine or forward its port over SSH."}`);
85
85
  }
86
86
  catch {
87
- return result(false, "Observer could not start — try humanish observe --run with this run's id in another terminal");
87
+ return result(false, "Observer could not start; run `humanish observe --run <run id>` in another terminal");
88
88
  }
89
89
  },
90
90
  close() {
@@ -104,22 +104,24 @@ export function createTuiObserverSession(cwdInput, options = {}) {
104
104
  * The counterpart to starting one: a study that is going nowhere costs money every turn, and until
105
105
  * now the only way to end it was to find the pid yourself.
106
106
  *
107
- * It signals the PROCESS GROUP, not the process. A run is spawned detached — its own group — and it
107
+ * It signals the process group, not the process. A run is spawned detached, in its own group, and it
108
108
  * has children: the CLI, and whatever it spawned to reach the sandbox. Signalling only the parent
109
109
  * leaves those orphaned and still working.
110
110
  *
111
- * SIGTERM, never SIGKILL: the run's own handlers get the chance to finalize its record and release
112
- * what it holds. A killed run leaves a `running` record to go stale, which reads as interrupted —
113
- * true, but strictly less informative than a run that was told to stop.
111
+ * SIGTERM, never SIGKILL, so the run's handler gets to act. Outside post-run analysis the run
112
+ * command (src/cli/commands/run-signals.ts) marks the run `interrupted` in status.json, kills the
113
+ * E2B sandboxes its receipts name, writes reclaim-receipt.json and exits; run.json keeps its last
114
+ * live flush. During analysis the signal cancels analysis instead. A local VM's container exits
115
+ * when the run's process goes.
114
116
  *
115
- * This stops the PROCESS. Sandboxes it created are a separate resource with their own receipts, and
116
- * `Reclaim` is what stops those — the run screen offers it as soon as this succeeds.
117
+ * `Reclaim` stays on offer: it retries by id any kill the handler could not confirm within its
118
+ * 10 s deadline. Each sandbox's create-time timeout is the backstop.
117
119
  */
118
120
  export async function stopRun(cwd, runId, intent = "run") {
119
121
  // The selected action carries its authority. Never infer permission to signal a process from
120
122
  // mutable status metadata after the operator asked only to cancel analysis.
121
123
  if (intent === "analysis") {
122
- const analysis = await requestAutomaticStudyAnalysisCancellation(cwd, runId);
124
+ const analysis = await requestAutomaticAnalysisCancellation(cwd, runId);
123
125
  return {
124
126
  schema: TUI_ACTION_SCHEMA,
125
127
  ok: analysis.requested,
@@ -142,7 +144,7 @@ export async function stopRun(cwd, runId, intent = "run") {
142
144
  return {
143
145
  schema: TUI_ACTION_SCHEMA,
144
146
  ok: false,
145
- message: "this run has no status record, so there is no pid to stop — it predates the contract or never started",
147
+ message: "this run has no status record, so there is no pid to stop; it predates status records or never started",
146
148
  };
147
149
  }
148
150
  if (!isRunStatusRecord(record)) {
@@ -153,7 +155,7 @@ export async function stopRun(cwd, runId, intent = "run") {
153
155
  };
154
156
  }
155
157
  if (record.state === "finished") {
156
- const analysis = await requestAutomaticStudyAnalysisCancellation(cwd, runId);
158
+ const analysis = await requestAutomaticAnalysisCancellation(cwd, runId);
157
159
  if (analysis.requested)
158
160
  return {
159
161
  schema: TUI_ACTION_SCHEMA,
@@ -162,13 +164,20 @@ export async function stopRun(cwd, runId, intent = "run") {
162
164
  };
163
165
  return { schema: TUI_ACTION_SCHEMA, ok: false, message: "this run already finished" };
164
166
  }
167
+ if (record.state === "interrupted") {
168
+ return {
169
+ schema: TUI_ACTION_SCHEMA,
170
+ ok: false,
171
+ message: `this run already stopped (${record.signal ?? "interrupted"}); Reclaim releases any sandbox it left`,
172
+ };
173
+ }
165
174
  const pid = record.pid;
166
175
  if (typeof pid !== "number" || !Number.isInteger(pid) || pid <= 1) {
167
176
  // pid 1 and below are never a run of ours, and signalling them would be catastrophic.
168
177
  return { schema: TUI_ACTION_SCHEMA, ok: false, message: "this run recorded no usable pid" };
169
178
  }
170
179
  // Is it actually still there? A pid whose process is already gone means the run died without
171
- // finalizing — nothing to stop, and the record will read as interrupted on its own.
180
+ // finalizing: nothing to stop, and the record will read as interrupted on its own.
172
181
  try {
173
182
  process.kill(pid, 0);
174
183
  }
@@ -176,7 +185,7 @@ export async function stopRun(cwd, runId, intent = "run") {
176
185
  return {
177
186
  schema: TUI_ACTION_SCHEMA,
178
187
  ok: false,
179
- message: `nothing is running under pid ${pid} — it has already stopped, and its record will read as interrupted`,
188
+ message: `nothing is running under pid ${pid}; it has already stopped, and its record will read as interrupted`,
180
189
  };
181
190
  }
182
191
  try {
@@ -198,6 +207,6 @@ export async function stopRun(cwd, runId, intent = "run") {
198
207
  return {
199
208
  schema: TUI_ACTION_SCHEMA,
200
209
  ok: true,
201
- message: "asked the run to stop — its sandboxes are separate, so Reclaim them once it reports interrupted",
210
+ message: "asked the run to stop; it marks itself interrupted and kills its E2B sandboxes, and Reclaim retries any kill it could not confirm",
202
211
  };
203
212
  }
@@ -39,32 +39,32 @@ export interface TuiCapabilities {
39
39
  /** Read every run in the project, cheapest source first. */
40
40
  readRunIndex(cwd: string, options?: ReadRunIndexOptions): Promise<RunIndexResult>;
41
41
  /**
42
- * The labs DECLARED in this project. Listed separately from run history because neither side is
42
+ * The labs declared in this project. Listed separately from run history because neither side is
43
43
  * the whole truth: a fresh project has manifests and no runs, and a long-lived one has runs from
44
44
  * manifests since renamed or deleted.
45
45
  */
46
46
  listLabs(cwd: string): Promise<LabListResult>;
47
47
  /**
48
- * Start a run and return once it is running. The run is DETACHED: it outlives this surface, so
49
- * quitting the TUI — or losing the connection it runs over — does not kill a study that costs
48
+ * Start a run and return once it is running. The run is detached: it outlives this surface, so
49
+ * quitting the TUI (or losing the connection it runs over) does not kill a study that costs
50
50
  * real money. The surface then follows it through `status.json` like any other reader.
51
51
  */
52
52
  startRun(options: Omit<LaunchRunOptions, "spawn" | "cliPath" | "now">): Promise<LaunchRunResult>;
53
53
  /** The tail of a launch log: the only account of a run that died before writing evidence. */
54
54
  readLaunchLog(logPath: string): Promise<string>;
55
55
  /**
56
- * Who is in ONE run and what they are thinking. Opens that run's bundle, which the index
57
- * deliberately does not — affordable because it is asked only for the run being watched.
56
+ * Who is in one run and what they are thinking. Opens that run's bundle, which the index
57
+ * deliberately does not. That is affordable because it is asked only for the run being watched.
58
58
  * `null` when the run has not written a bundle yet.
59
59
  */
60
60
  readRunDetail(cwd: string, runId: string): Promise<RunDetail | null>;
61
61
  /**
62
- * What a lab IS — subject, participants, model, spend caps, and whether the keys a live run needs
62
+ * What a lab is: subject, participants, model, spend caps, and whether the keys a live run needs
63
63
  * resolve right now. Read for the lab being looked at, because it is what someone reads before
64
64
  * deciding to spend money.
65
65
  */
66
66
  readLabSummary(cwd: string, lab: string, options?: ReadLabSummaryOptions): Promise<LabSummary | null>;
67
- /** Whether this directory is a humanish project — an empty project and a wrong directory are
67
+ /** Whether this directory is a humanish project: an empty project and a wrong directory are
68
68
  * different problems and must not share a screen. */
69
69
  readProjectState(cwd: string): TuiProjectState;
70
70
  /** Open the selected run in the session-owned local evidence server; closes when the TUI exits. */
@@ -72,12 +72,12 @@ export interface TuiCapabilities {
72
72
  /** Stop the sandboxes an interrupted run left behind, keeping its evidence. */
73
73
  reclaimRun(cwd: string, runId: string): Promise<ReclaimResult>;
74
74
  /** End a run that is still going. "analysis" is marker-only regardless of the current status;
75
- * it MUST NOT probe or signal a process. The default "run" intent stops the participant process. */
75
+ * it must not probe or signal a process. The default "run" intent stops the participant process. */
76
76
  stopRun(cwd: string, runId: string, intent?: "run" | "analysis"): Promise<TuiActionResult>;
77
77
  /**
78
- * Set this directory up as a humanish project. The surface's only WRITING action outside of
79
- * starting runs — offered because "cd somewhere else and run init" is a dead end shown to
80
- * exactly the person who has just arrived (#505).
78
+ * Set this directory up as a humanish project. The surface's only writing action outside of
79
+ * starting runs, offered because "cd somewhere else and run init" is a dead end shown to
80
+ * exactly the person who has just arrived.
81
81
  */
82
82
  initProject(cwd: string): Promise<TuiActionResult>;
83
83
  }
@@ -100,7 +100,7 @@ export interface TuiOptions {
100
100
  exitAfterFirstFrame?: boolean;
101
101
  }
102
102
  /**
103
- * Start the surface. Resolves with the process exit code when the operator quits — the TUI owns the
103
+ * Start the surface. Resolves with the process exit code when the operator quits; the TUI owns the
104
104
  * screen until then, so the CLI must not write to stdout while this is pending.
105
105
  */
106
106
  export type TuiHandoff = {
@@ -125,14 +125,14 @@ export declare function nodeSupportsTui(versionString?: string): boolean;
125
125
  */
126
126
  export declare const TUI_BUNDLE_URL: import("url").URL;
127
127
  /**
128
- * What `doctor` says about the stakeholder surface — a pure function of the machine's state and,
129
- * crucially, of WHO IS READING.
128
+ * What `doctor` says about the stakeholder surface: a pure function of the machine's state and,
129
+ * crucially, of who is reading.
130
130
  *
131
131
  * A real first-contact study (labs/first-contact.yaml) is why the reader matters. An autonomous
132
132
  * agent evaluating humanish read "`humanish tui` is available in an interactive terminal",
133
- * correctly concluded it was not in one, and dropped it — then wrote a report FOR A HUMAN that
133
+ * correctly concluded it was not in one, and dropped it, then wrote a report for a human that
134
134
  * never mentioned the human surface at all. Discovery worked and handoff did not. A capability
135
- * described to a reader who cannot use it has to be phrased as something to PASS ON, or it reads
135
+ * described to a reader who cannot use it has to be phrased as something to pass on, or it reads
136
136
  * as "not for you" and dies in the transcript.
137
137
  */
138
138
  export declare function terminalSurfaceMessage(state: {
@@ -1,11 +1,11 @@
1
- // The boundary between the CLI and the terminal UI (#455).
1
+ // The boundary between the CLI and the terminal UI.
2
2
  //
3
- // `humanish tui` loads a PRE-BUILT bundle (dist/tui-app.js) that contains Ink, React and the
4
- // screens — and nothing else. Everything the surface needs to KNOW is passed across this interface
3
+ // `humanish tui` loads a pre-built bundle (dist/tui-app.js) that contains Ink, React and the
4
+ // screens, and nothing else. Everything the surface needs to know is passed across this interface
5
5
  // by the CLI, which imports it from the same modules every other command uses.
6
6
  //
7
7
  // The reason for the seam: a terminal UI that reads the filesystem itself would become a second
8
- // implementation of "what is a run, which lab does it belong to, is it alive" — one that ships
8
+ // implementation of "what is a run, which lab does it belong to, is it alive", one that ships
9
9
  // minified, is invisible to the root test suite, and drifts from `humanish runs` the first time
10
10
  // either side changes. Injection keeps exactly one implementation, already unit-tested, and leaves
11
11
  // the bundle a view layer that can be reasoned about as one.
@@ -29,14 +29,14 @@ export function nodeSupportsTui(versionString = process.version) {
29
29
  */
30
30
  export const TUI_BUNDLE_URL = new URL("../tui-app.js", import.meta.url);
31
31
  /**
32
- * What `doctor` says about the stakeholder surface — a pure function of the machine's state and,
33
- * crucially, of WHO IS READING.
32
+ * What `doctor` says about the stakeholder surface: a pure function of the machine's state and,
33
+ * crucially, of who is reading.
34
34
  *
35
35
  * A real first-contact study (labs/first-contact.yaml) is why the reader matters. An autonomous
36
36
  * agent evaluating humanish read "`humanish tui` is available in an interactive terminal",
37
- * correctly concluded it was not in one, and dropped it — then wrote a report FOR A HUMAN that
37
+ * correctly concluded it was not in one, and dropped it, then wrote a report for a human that
38
38
  * never mentioned the human surface at all. Discovery worked and handoff did not. A capability
39
- * described to a reader who cannot use it has to be phrased as something to PASS ON, or it reads
39
+ * described to a reader who cannot use it has to be phrased as something to pass on, or it reads
40
40
  * as "not for you" and dies in the transcript.
41
41
  */
42
42
  export function terminalSurfaceMessage(state) {
@@ -44,9 +44,9 @@ export function terminalSurfaceMessage(state) {
44
44
  return `\`humanish tui\` needs Node ${TUI_MIN_NODE_MAJOR}+ (this is ${state.nodeVersion}); every other command works here`;
45
45
  }
46
46
  if (!state.bundlePresent) {
47
- return "`humanish tui` bundle is not built in this checkout — run `pnpm build` (installed packages ship it prebuilt)";
47
+ return "`humanish tui` is not built in this checkout; run `pnpm build` (installed packages ship it prebuilt)";
48
48
  }
49
49
  return state.interactive
50
50
  ? "`humanish tui` opens the interactive surface for browsing labs and runs"
51
- : "`humanish tui` is the interactive surface a PERSON uses to watch and start runs here — this shell is not a terminal, so pass it on to whoever is";
51
+ : "`humanish tui` is the interactive screen a person uses to watch and start runs here. This shell is not a terminal, so pass it on to a person at one";
52
52
  }
@@ -2,7 +2,7 @@ import { spawn } from "node:child_process";
2
2
  export declare function isSafeLabHandle(value: string): boolean;
3
3
  export interface LaunchRunOptions {
4
4
  cwd: string;
5
- /** The manifest handle (filename stem), as `humanish lab run` takes it. */
5
+ /** The manifest handle (filename stem), as `humanish run` takes it. */
6
6
  lab: string;
7
7
  /** Exact selected manifest, avoiding a same-name committed lab shadowing a local copy. */
8
8
  manifestPath?: string;
@@ -19,7 +19,7 @@ export interface LaunchedRun {
19
19
  /** The spawned CLI's pid. The run's `status.json` stamps the same value. */
20
20
  pid: number;
21
21
  /**
22
- * When the launch happened. A pid ALONE cannot identify a run: pids are recycled by the OS and a
22
+ * When the launch happened. A pid alone cannot identify a run: pids are recycled by the OS and a
23
23
  * finished run keeps its pid in `status.json` forever, so a week-old record can carry the pid the
24
24
  * kernel just handed this child. Anything matching on pid must also require the record to be
25
25
  * newer than this.
@@ -40,11 +40,11 @@ export type LaunchRunResult = {
40
40
  message: string;
41
41
  };
42
42
  };
43
- export type LaunchErrorCode = "HUMANISH_LAUNCH_INVALID_LAB" | "HUMANISH_LAUNCH_FAILED";
43
+ export type LaunchErrorCode = "HUMANISH_LAUNCH_INVALID_STUDY" | "HUMANISH_LAUNCH_FAILED";
44
44
  /**
45
45
  * Start a run and return as soon as it is running. Never throws: a launch that cannot happen is a
46
46
  * result the surface can render, not an exception that would tear down the screen.
47
47
  */
48
48
  export declare function launchRun(options: LaunchRunOptions): Promise<LaunchRunResult>;
49
- /** Read the tail of a launch log — the only account of a run that died before writing evidence. */
49
+ /** Read the tail of a launch log: the only account of a run that died before writing evidence. */
50
50
  export declare function readLaunchLogTail(logPath: string, maxBytes?: number): Promise<string>;
@@ -1,14 +1,14 @@
1
- // Starting a run from the terminal surface (#455).
1
+ // Starting a run from the terminal surface.
2
2
  //
3
- // THE RUN MUST OUTLIVE THE SURFACE. A study can take minutes and costs real money, so a run
3
+ // The run must outlive the surface. A study can take minutes and costs real money, so a run
4
4
  // started from the TUI cannot be a child of the TUI's event loop: closing the surface, or losing
5
5
  // the SSH session it is running over, must not kill it. So this spawns the CLI the same way a
6
- // person would type it — detached, in its own process group, with its output going to a file
6
+ // person would type it: detached, in its own process group, with its output going to a file
7
7
  // rather than to a terminal that may be about to disappear.
8
8
  //
9
9
  // The surface then learns what happened the same way any other reader does: from `status.json`.
10
10
  // It does not hold a handle to the run, parse its stdout, or track it in memory. That is what
11
- // makes the surface restartable — quit the TUI mid-run, reopen it, and the run is still there,
11
+ // makes the surface restartable: quit the TUI mid-run, reopen it, and the run is still there,
12
12
  // because the filesystem was always the source of truth rather than a process handle.
13
13
  import { spawn } from "node:child_process";
14
14
  import { constants as fsConstants } from "node:fs";
@@ -18,14 +18,14 @@ import { fileURLToPath } from "node:url";
18
18
  import { resolveLabManifest } from "../lab/discover.js";
19
19
  import { prepareManagedHumanishOutputDirectory } from "../run/contained-output.js";
20
20
  /**
21
- * A lab handle is the manifest FILENAME, which is what `humanish lab run` resolves. Restricted to
22
- * characters a manifest name can actually contain, and — the part that matters — never allowed to
21
+ * A lab handle is the manifest filename, which is what `humanish run` resolves. Restricted to
22
+ * characters a manifest name can actually contain, and (the part that matters) never allowed to
23
23
  * begin with `-`, because argv is positional: a lab called `--json` would otherwise be handed to
24
24
  * the CLI as a flag. There is no shell involved, so this is the whole injection surface.
25
25
  *
26
- * A leading underscore IS allowed: `_wip.yaml` is an ordinary way to name a work-in-progress
27
- * manifest, `humanish lab run _wip` resolves it, and refusing it here would leave the surface
28
- * listing a lab it will not start. A leading dot stays out — that names a hidden file, not a lab.
26
+ * A leading underscore is allowed: `_wip.yaml` is an ordinary way to name a work-in-progress
27
+ * manifest, `humanish run _wip` resolves it, and refusing it here would leave the surface
28
+ * listing a lab it will not start. A leading dot stays out: that names a hidden file, not a lab.
29
29
  */
30
30
  const SAFE_LAB_HANDLE = /^[A-Za-z0-9_][A-Za-z0-9._:-]*$/;
31
31
  export function isSafeLabHandle(value) {
@@ -44,8 +44,8 @@ export async function launchRun(options) {
44
44
  return {
45
45
  ok: false,
46
46
  error: {
47
- code: "HUMANISH_LAUNCH_INVALID_LAB",
48
- message: `"${options.lab}" is not a usable lab handle. Run it by path with \`humanish lab run <path>\` instead.`,
47
+ code: "HUMANISH_LAUNCH_INVALID_STUDY",
48
+ message: `"${options.lab}" is not a usable lab handle. Run it by path with \`humanish run <path>\` instead.`,
49
49
  },
50
50
  };
51
51
  }
@@ -57,8 +57,8 @@ export async function launchRun(options) {
57
57
  return {
58
58
  ok: false,
59
59
  error: {
60
- code: "HUMANISH_LAUNCH_INVALID_LAB",
61
- message: "The selected lab path could not be read safely. Refresh the lab list.",
60
+ code: "HUMANISH_LAUNCH_INVALID_STUDY",
61
+ message: "The selected study path could not be read safely. Refresh the study list.",
62
62
  },
63
63
  };
64
64
  selectedLab = path.relative(cwd, path.resolve(cwd, resolved.path)).replace(/\\/g, "/");
@@ -74,8 +74,8 @@ export async function launchRun(options) {
74
74
  const logDir = await prepareManagedHumanishOutputDirectory(cwd, "launches");
75
75
  const stamp = launchedAt.replace(/[:.]/g, "-");
76
76
  logPath = path.join(logDir.physicalPath, `${stamp}-${options.lab}.log`);
77
- // O_NOFOLLOW so a symlink planted at this path cannot redirect a run's output — which may carry
78
- // provider error text — outside the project, and cannot defeat the 0600 mode by pointing at a
77
+ // O_NOFOLLOW so a symlink planted at this path cannot redirect a run's output (which may carry
78
+ // provider error text) outside the project, and cannot defeat the 0600 mode by pointing at a
79
79
  // file that already exists with looser permissions. O_CREAT|O_APPEND keeps ordinary reuse
80
80
  // working; only a symlink is refused (ELOOP).
81
81
  handle = await open(logPath, fsConstants.O_CREAT | fsConstants.O_WRONLY | fsConstants.O_APPEND | fsConstants.O_NOFOLLOW, 0o600);
@@ -93,7 +93,6 @@ export async function launchRun(options) {
93
93
  // the operator's attention and must not have a browser thrown over it.
94
94
  const args = [
95
95
  options.cliPath ?? defaultCliPath(),
96
- "lab",
97
96
  "run",
98
97
  "--cwd",
99
98
  cwd,
@@ -115,9 +114,9 @@ export async function launchRun(options) {
115
114
  };
116
115
  try {
117
116
  const child = spawnFn(process.execPath, args, spawnOptions);
118
- // A spawn failure is delivered ASYNCHRONOUSLY as an 'error' event (EAGAIN, EMFILE, ENOMEM, a
117
+ // A spawn failure is delivered asynchronously as an 'error' event (EAGAIN, EMFILE, ENOMEM, a
119
118
  // vanished node binary). An 'error' event with no listener is re-thrown by EventEmitter as an
120
- // uncaught exception — which would tear down the whole surface, the one thing this module
119
+ // uncaught exception, which would tear down the whole surface, the one thing this module
121
120
  // promises never to do. The run is already unref'd and unobserved, so recording it is all that
122
121
  // is available; the operator learns about it from the launch log and the missing record.
123
122
  child.on("error", () => {
@@ -151,7 +150,7 @@ export async function launchRun(options) {
151
150
  };
152
151
  }
153
152
  }
154
- /** Read the tail of a launch log — the only account of a run that died before writing evidence. */
153
+ /** Read the tail of a launch log: the only account of a run that died before writing evidence. */
155
154
  export async function readLaunchLogTail(logPath, maxBytes = 4_000) {
156
155
  try {
157
156
  const handle = await open(logPath, "r");