@with-logic/elwood 0.1.0 → 0.1.2

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 (777) hide show
  1. package/CHANGELOG.md +182 -3
  2. package/CONTRIBUTING.md +104 -0
  3. package/LICENSE +1 -1
  4. package/README.md +295 -26
  5. package/SECURITY.md +42 -0
  6. package/dist/claude/command.d.ts +9 -2
  7. package/dist/claude/command.d.ts.map +1 -1
  8. package/dist/claude/command.js +23 -16
  9. package/dist/claude/command.js.map +1 -1
  10. package/dist/claude/model-picker.d.ts.map +1 -1
  11. package/dist/claude/model-picker.js +4 -3
  12. package/dist/claude/model-picker.js.map +1 -1
  13. package/dist/claude/model-switch-confirmation.js +9 -1
  14. package/dist/claude/model-switch-confirmation.js.map +1 -1
  15. package/dist/claude/screen-table.js +1 -1
  16. package/dist/claude/screen-table.js.map +1 -1
  17. package/dist/claude/session/build.d.ts.map +1 -1
  18. package/dist/claude/session/build.js +3 -0
  19. package/dist/claude/session/build.js.map +1 -1
  20. package/dist/claude/session/index.d.ts.map +1 -1
  21. package/dist/claude/session/index.js +5 -2
  22. package/dist/claude/session/index.js.map +1 -1
  23. package/dist/claude/session/resume.d.ts +1 -1
  24. package/dist/claude/session/resume.d.ts.map +1 -1
  25. package/dist/claude/session/resume.js +5 -1
  26. package/dist/claude/session/resume.js.map +1 -1
  27. package/dist/claude/session/start-or-resume.js +1 -0
  28. package/dist/claude/session/start-or-resume.js.map +1 -1
  29. package/dist/claude/simple.d.ts.map +1 -1
  30. package/dist/claude/simple.js +4 -0
  31. package/dist/claude/simple.js.map +1 -1
  32. package/dist/cli/args/index.d.ts +3 -1
  33. package/dist/cli/args/index.d.ts.map +1 -1
  34. package/dist/cli/args/index.js +10 -2
  35. package/dist/cli/args/index.js.map +1 -1
  36. package/dist/cli/args/options.d.ts.map +1 -1
  37. package/dist/cli/args/options.js +2 -0
  38. package/dist/cli/args/options.js.map +1 -1
  39. package/dist/cli/args-commands.d.ts +10 -0
  40. package/dist/cli/args-commands.d.ts.map +1 -0
  41. package/dist/cli/args-commands.js +113 -0
  42. package/dist/cli/args-commands.js.map +1 -0
  43. package/dist/cli/command-types.d.ts +26 -0
  44. package/dist/cli/command-types.d.ts.map +1 -0
  45. package/dist/cli/command-types.js +9 -0
  46. package/dist/cli/command-types.js.map +1 -0
  47. package/dist/cli/config/codec-primitives.d.ts +20 -0
  48. package/dist/cli/config/codec-primitives.d.ts.map +1 -0
  49. package/dist/cli/config/codec-primitives.js +51 -0
  50. package/dist/cli/config/codec-primitives.js.map +1 -0
  51. package/dist/cli/config/codec.d.ts.map +1 -1
  52. package/dist/cli/config/codec.js +4 -46
  53. package/dist/cli/config/codec.js.map +1 -1
  54. package/dist/cli/config/effective.d.ts.map +1 -1
  55. package/dist/cli/config/effective.js +1 -0
  56. package/dist/cli/config/effective.js.map +1 -1
  57. package/dist/cli/config/keys.d.ts +1 -1
  58. package/dist/cli/config/keys.d.ts.map +1 -1
  59. package/dist/cli/config/keys.js +1 -0
  60. package/dist/cli/config/keys.js.map +1 -1
  61. package/dist/cli/entry.d.ts +4 -2
  62. package/dist/cli/entry.d.ts.map +1 -1
  63. package/dist/cli/entry.js +2 -1
  64. package/dist/cli/entry.js.map +1 -1
  65. package/dist/cli/help.d.ts +2 -2
  66. package/dist/cli/help.d.ts.map +1 -1
  67. package/dist/cli/help.js +40 -1
  68. package/dist/cli/help.js.map +1 -1
  69. package/dist/cli/interactive/index.d.ts +26 -0
  70. package/dist/cli/interactive/index.d.ts.map +1 -0
  71. package/dist/cli/interactive/index.js +33 -0
  72. package/dist/cli/interactive/index.js.map +1 -0
  73. package/dist/cli/interactive/launch.d.ts +14 -0
  74. package/dist/cli/interactive/launch.d.ts.map +1 -0
  75. package/dist/cli/interactive/launch.js +66 -0
  76. package/dist/cli/interactive/launch.js.map +1 -0
  77. package/dist/cli/interactive/spawn.d.ts +18 -0
  78. package/dist/cli/interactive/spawn.d.ts.map +1 -0
  79. package/dist/cli/interactive/spawn.js +53 -0
  80. package/dist/cli/interactive/spawn.js.map +1 -0
  81. package/dist/cli/main-failure.d.ts +28 -0
  82. package/dist/cli/main-failure.d.ts.map +1 -0
  83. package/dist/cli/main-failure.js +78 -0
  84. package/dist/cli/main-failure.js.map +1 -0
  85. package/dist/cli/main.d.ts +12 -4
  86. package/dist/cli/main.d.ts.map +1 -1
  87. package/dist/cli/main.js +27 -73
  88. package/dist/cli/main.js.map +1 -1
  89. package/dist/cli/models/index.d.ts +20 -0
  90. package/dist/cli/models/index.d.ts.map +1 -0
  91. package/dist/cli/models/index.js +63 -0
  92. package/dist/cli/models/index.js.map +1 -0
  93. package/dist/cli/models/render.d.ts +9 -0
  94. package/dist/cli/models/render.d.ts.map +1 -0
  95. package/dist/cli/models/render.js +33 -0
  96. package/dist/cli/models/render.js.map +1 -0
  97. package/dist/cli/request/index.d.ts.map +1 -1
  98. package/dist/cli/request/index.js +8 -2
  99. package/dist/cli/request/index.js.map +1 -1
  100. package/dist/cli/request/layers.d.ts +2 -0
  101. package/dist/cli/request/layers.d.ts.map +1 -1
  102. package/dist/cli/request/layers.js +9 -5
  103. package/dist/cli/request/layers.js.map +1 -1
  104. package/dist/cli/request/posture.d.ts +28 -0
  105. package/dist/cli/request/posture.d.ts.map +1 -0
  106. package/dist/cli/request/posture.js +70 -0
  107. package/dist/cli/request/posture.js.map +1 -0
  108. package/dist/cli/request/resolution-types.d.ts +1 -0
  109. package/dist/cli/request/resolution-types.d.ts.map +1 -1
  110. package/dist/cli/request/settings.d.ts +2 -12
  111. package/dist/cli/request/settings.d.ts.map +1 -1
  112. package/dist/cli/request/settings.js +2 -25
  113. package/dist/cli/request/settings.js.map +1 -1
  114. package/dist/cli/request/validation.d.ts +12 -0
  115. package/dist/cli/request/validation.d.ts.map +1 -1
  116. package/dist/cli/request/validation.js +30 -10
  117. package/dist/cli/request/validation.js.map +1 -1
  118. package/dist/cli/request/values.d.ts +1 -0
  119. package/dist/cli/request/values.d.ts.map +1 -1
  120. package/dist/cli/request/values.js +1 -0
  121. package/dist/cli/request/values.js.map +1 -1
  122. package/dist/cli/run/index.d.ts.map +1 -1
  123. package/dist/cli/run/index.js +5 -41
  124. package/dist/cli/run/index.js.map +1 -1
  125. package/dist/cli/run/subscribe.d.ts +19 -0
  126. package/dist/cli/run/subscribe.d.ts.map +1 -0
  127. package/dist/cli/run/subscribe.js +47 -0
  128. package/dist/cli/run/subscribe.js.map +1 -0
  129. package/dist/cli/session/launch.d.ts +3 -0
  130. package/dist/cli/session/launch.d.ts.map +1 -1
  131. package/dist/cli/session/launch.js +11 -0
  132. package/dist/cli/session/launch.js.map +1 -1
  133. package/dist/cli/sessions/index.d.ts +30 -0
  134. package/dist/cli/sessions/index.d.ts.map +1 -0
  135. package/dist/cli/sessions/index.js +61 -0
  136. package/dist/cli/sessions/index.js.map +1 -0
  137. package/dist/cli/sessions/list.d.ts +28 -0
  138. package/dist/cli/sessions/list.d.ts.map +1 -0
  139. package/dist/cli/sessions/list.js +63 -0
  140. package/dist/cli/sessions/list.js.map +1 -0
  141. package/dist/cli/sessions/settings.d.ts +11 -0
  142. package/dist/cli/sessions/settings.d.ts.map +1 -0
  143. package/dist/cli/sessions/settings.js +26 -0
  144. package/dist/cli/sessions/settings.js.map +1 -0
  145. package/dist/cli/table.d.ts +7 -0
  146. package/dist/cli/table.d.ts.map +1 -0
  147. package/dist/cli/table.js +14 -0
  148. package/dist/cli/table.js.map +1 -0
  149. package/dist/cli/types.d.ts +5 -1
  150. package/dist/cli/types.d.ts.map +1 -1
  151. package/dist/cli/types.js.map +1 -1
  152. package/dist/codex/command.d.ts +18 -2
  153. package/dist/codex/command.d.ts.map +1 -1
  154. package/dist/codex/command.js +39 -24
  155. package/dist/codex/command.js.map +1 -1
  156. package/dist/codex/model-picker.d.ts.map +1 -1
  157. package/dist/codex/model-picker.js +3 -2
  158. package/dist/codex/model-picker.js.map +1 -1
  159. package/dist/codex/session/build.d.ts.map +1 -1
  160. package/dist/codex/session/build.js +5 -7
  161. package/dist/codex/session/build.js.map +1 -1
  162. package/dist/codex/session/index.d.ts.map +1 -1
  163. package/dist/codex/session/index.js +5 -2
  164. package/dist/codex/session/index.js.map +1 -1
  165. package/dist/codex/session/resume.d.ts +1 -1
  166. package/dist/codex/session/resume.d.ts.map +1 -1
  167. package/dist/codex/session/resume.js +5 -1
  168. package/dist/codex/session/resume.js.map +1 -1
  169. package/dist/codex/session/start-or-resume.js +1 -0
  170. package/dist/codex/session/start-or-resume.js.map +1 -1
  171. package/dist/codex/session/types.d.ts +3 -0
  172. package/dist/codex/session/types.d.ts.map +1 -1
  173. package/dist/codex/simple.d.ts.map +1 -1
  174. package/dist/codex/simple.js +4 -0
  175. package/dist/codex/simple.js.map +1 -1
  176. package/dist/core/errors.d.ts +1 -1
  177. package/dist/core/errors.d.ts.map +1 -1
  178. package/dist/core/errors.js.map +1 -1
  179. package/dist/core/high-trust.d.ts +41 -0
  180. package/dist/core/high-trust.d.ts.map +1 -0
  181. package/dist/core/high-trust.js +50 -0
  182. package/dist/core/high-trust.js.map +1 -0
  183. package/dist/core/input/index.d.ts.map +1 -1
  184. package/dist/core/input/index.js +15 -3
  185. package/dist/core/input/index.js.map +1 -1
  186. package/dist/core/models/input.d.ts +3 -0
  187. package/dist/core/models/input.d.ts.map +1 -0
  188. package/dist/core/models/input.js +9 -0
  189. package/dist/core/models/input.js.map +1 -0
  190. package/dist/core/models/picker.d.ts +2 -1
  191. package/dist/core/models/picker.d.ts.map +1 -1
  192. package/dist/core/models/picker.js +6 -5
  193. package/dist/core/models/picker.js.map +1 -1
  194. package/dist/core/models/tui-screen.d.ts +1 -1
  195. package/dist/core/models/tui-screen.d.ts.map +1 -1
  196. package/dist/core/models/tui-screen.js +26 -3
  197. package/dist/core/models/tui-screen.js.map +1 -1
  198. package/dist/core/trust/allowlist.d.ts +56 -0
  199. package/dist/core/trust/allowlist.d.ts.map +1 -0
  200. package/dist/core/{trust-prompts.js → trust/allowlist.js} +21 -38
  201. package/dist/core/trust/allowlist.js.map +1 -0
  202. package/dist/core/trust/prompts.d.ts +4 -46
  203. package/dist/core/trust/prompts.d.ts.map +1 -1
  204. package/dist/core/trust/prompts.js +2 -73
  205. package/dist/core/trust/prompts.js.map +1 -1
  206. package/dist/core/trust/responder.d.ts +2 -0
  207. package/dist/core/trust/responder.d.ts.map +1 -1
  208. package/dist/core/trust/responder.js +4 -0
  209. package/dist/core/trust/responder.js.map +1 -1
  210. package/dist/core/types.d.ts +3 -0
  211. package/dist/core/types.d.ts.map +1 -1
  212. package/dist/runtime/launch-arguments.d.ts +12 -0
  213. package/dist/runtime/launch-arguments.d.ts.map +1 -0
  214. package/dist/runtime/launch-arguments.js +15 -0
  215. package/dist/runtime/launch-arguments.js.map +1 -0
  216. package/dist/runtime/session/base.d.ts.map +1 -1
  217. package/dist/runtime/session/base.js +4 -1
  218. package/dist/runtime/session/base.js.map +1 -1
  219. package/dist/runtime/session/commands.d.ts +2 -1
  220. package/dist/runtime/session/commands.d.ts.map +1 -1
  221. package/dist/runtime/session/commands.js +10 -4
  222. package/dist/runtime/session/commands.js.map +1 -1
  223. package/dist/runtime/session/lifecycle.d.ts +3 -4
  224. package/dist/runtime/session/lifecycle.d.ts.map +1 -1
  225. package/dist/runtime/session/lifecycle.js +6 -5
  226. package/dist/runtime/session/lifecycle.js.map +1 -1
  227. package/dist/state/directories.d.ts +4 -0
  228. package/dist/state/directories.d.ts.map +1 -0
  229. package/dist/state/directories.js +41 -0
  230. package/dist/state/directories.js.map +1 -0
  231. package/dist/state/files.d.ts.map +1 -1
  232. package/dist/state/files.js +25 -11
  233. package/dist/state/files.js.map +1 -1
  234. package/dist/state/private-session.d.ts.map +1 -1
  235. package/dist/state/private-session.js +2 -0
  236. package/dist/state/private-session.js.map +1 -1
  237. package/dist/state/store.d.ts.map +1 -1
  238. package/dist/state/store.js +7 -1
  239. package/dist/state/store.js.map +1 -1
  240. package/docs/cli-behavior.md +89 -1
  241. package/docs/cli-output.md +60 -0
  242. package/docs/cli.md +10 -2
  243. package/docs/codex/cli.md +57 -0
  244. package/docs/codex/config.md +47 -0
  245. package/docs/codex/hooks.md +70 -0
  246. package/examples/README.md +56 -0
  247. package/examples/full.ts +113 -0
  248. package/examples/minimal.ts +15 -0
  249. package/examples/stream.ts +39 -0
  250. package/examples/support.ts +71 -0
  251. package/package.json +17 -10
  252. package/prd/01-overview.md +21 -0
  253. package/prd/02-goals.md +47 -0
  254. package/prd/03-terminology.md +32 -0
  255. package/prd/04-architecture.md +121 -0
  256. package/prd/05-api/5.1-starting-claude.md +108 -0
  257. package/prd/05-api/5.2-resuming-claude.md +86 -0
  258. package/prd/05-api/5.3-claude-session-api.md +658 -0
  259. package/prd/05-api/5.4-events.md +145 -0
  260. package/prd/05-api/5.5-starting-codex.md +106 -0
  261. package/prd/05-api/5.6-resuming-codex.md +48 -0
  262. package/prd/05-api/5.7-codex-session-api.md +425 -0
  263. package/prd/05-api/5.8-session-api.md +122 -0
  264. package/prd/05-api/5.9-loops.md +170 -0
  265. package/prd/05-api/README.md +19 -0
  266. package/prd/06-claude-hook-bridge.md +164 -0
  267. package/prd/07-claude-policy.md +15 -0
  268. package/prd/07a-codex-hook-bridge.md +76 -0
  269. package/prd/08-state.md +127 -0
  270. package/prd/09-lifecycle.md +222 -0
  271. package/prd/10-errors.md +55 -0
  272. package/prd/11-test-app.md +53 -0
  273. package/prd/12-e2e.md +23 -0
  274. package/prd/12a-cli.md +375 -0
  275. package/prd/13-latitude.md +12 -0
  276. package/prd/14-conformance.md +333 -0
  277. package/prd/15-open-notes.md +8 -0
  278. package/prd/README.md +45 -0
  279. package/dist/claude/hook-dispatch.d.ts +0 -9
  280. package/dist/claude/hook-dispatch.d.ts.map +0 -1
  281. package/dist/claude/hook-dispatch.js +0 -12
  282. package/dist/claude/hook-dispatch.js.map +0 -1
  283. package/dist/claude/hook-events-extra.d.ts +0 -81
  284. package/dist/claude/hook-events-extra.d.ts.map +0 -1
  285. package/dist/claude/hook-events-extra.js +0 -6
  286. package/dist/claude/hook-events-extra.js.map +0 -1
  287. package/dist/claude/hook-events.d.ts +0 -101
  288. package/dist/claude/hook-events.d.ts.map +0 -1
  289. package/dist/claude/hook-events.js +0 -6
  290. package/dist/claude/hook-events.js.map +0 -1
  291. package/dist/claude/hook-names.d.ts +0 -24
  292. package/dist/claude/hook-names.d.ts.map +0 -1
  293. package/dist/claude/hook-names.js +0 -45
  294. package/dist/claude/hook-names.js.map +0 -1
  295. package/dist/claude/hooks.d.ts +0 -78
  296. package/dist/claude/hooks.d.ts.map +0 -1
  297. package/dist/claude/hooks.js +0 -6
  298. package/dist/claude/hooks.js.map +0 -1
  299. package/dist/claude/session-bridge.d.ts +0 -11
  300. package/dist/claude/session-bridge.d.ts.map +0 -1
  301. package/dist/claude/session-bridge.js +0 -18
  302. package/dist/claude/session-bridge.js.map +0 -1
  303. package/dist/claude/session-build.d.ts +0 -15
  304. package/dist/claude/session-build.d.ts.map +0 -1
  305. package/dist/claude/session-build.js +0 -147
  306. package/dist/claude/session-build.js.map +0 -1
  307. package/dist/claude/session-hook-handler.d.ts +0 -34
  308. package/dist/claude/session-hook-handler.d.ts.map +0 -1
  309. package/dist/claude/session-hook-handler.js +0 -42
  310. package/dist/claude/session-hook-handler.js.map +0 -1
  311. package/dist/claude/session-instance.d.ts +0 -42
  312. package/dist/claude/session-instance.d.ts.map +0 -1
  313. package/dist/claude/session-instance.js +0 -146
  314. package/dist/claude/session-instance.js.map +0 -1
  315. package/dist/claude/session-interface.d.ts +0 -49
  316. package/dist/claude/session-interface.d.ts.map +0 -1
  317. package/dist/claude/session-interface.js +0 -10
  318. package/dist/claude/session-interface.js.map +0 -1
  319. package/dist/claude/session-resume.d.ts +0 -8
  320. package/dist/claude/session-resume.d.ts.map +0 -1
  321. package/dist/claude/session-resume.js +0 -47
  322. package/dist/claude/session-resume.js.map +0 -1
  323. package/dist/claude/session-runtime.d.ts +0 -43
  324. package/dist/claude/session-runtime.d.ts.map +0 -1
  325. package/dist/claude/session-runtime.js +0 -105
  326. package/dist/claude/session-runtime.js.map +0 -1
  327. package/dist/claude/session-transcript.d.ts +0 -62
  328. package/dist/claude/session-transcript.d.ts.map +0 -1
  329. package/dist/claude/session-transcript.js +0 -88
  330. package/dist/claude/session-transcript.js.map +0 -1
  331. package/dist/claude/session.d.ts +0 -18
  332. package/dist/claude/session.d.ts.map +0 -1
  333. package/dist/claude/session.js +0 -58
  334. package/dist/claude/session.js.map +0 -1
  335. package/dist/claude/start-or-resume.d.ts +0 -12
  336. package/dist/claude/start-or-resume.d.ts.map +0 -1
  337. package/dist/claude/start-or-resume.js +0 -32
  338. package/dist/claude/start-or-resume.js.map +0 -1
  339. package/dist/claude/tool-hook-events.d.ts +0 -10
  340. package/dist/claude/tool-hook-events.d.ts.map +0 -1
  341. package/dist/claude/tool-hook-events.js +0 -18
  342. package/dist/claude/tool-hook-events.js.map +0 -1
  343. package/dist/claude/tool-types.d.ts +0 -158
  344. package/dist/claude/tool-types.d.ts.map +0 -1
  345. package/dist/claude/tool-types.js +0 -6
  346. package/dist/claude/tool-types.js.map +0 -1
  347. package/dist/claude/validate-input.d.ts +0 -8
  348. package/dist/claude/validate-input.d.ts.map +0 -1
  349. package/dist/claude/validate-input.js +0 -137
  350. package/dist/claude/validate-input.js.map +0 -1
  351. package/dist/claude/validate-permission-update.d.ts +0 -10
  352. package/dist/claude/validate-permission-update.d.ts.map +0 -1
  353. package/dist/claude/validate-permission-update.js +0 -72
  354. package/dist/claude/validate-permission-update.js.map +0 -1
  355. package/dist/claude/validate-result.d.ts +0 -7
  356. package/dist/claude/validate-result.d.ts.map +0 -1
  357. package/dist/claude/validate-result.js +0 -118
  358. package/dist/claude/validate-result.js.map +0 -1
  359. package/dist/claude/validate-shapes.d.ts +0 -22
  360. package/dist/claude/validate-shapes.d.ts.map +0 -1
  361. package/dist/claude/validate-shapes.js +0 -15
  362. package/dist/claude/validate-shapes.js.map +0 -1
  363. package/dist/claude/validate-tool-update.d.ts +0 -15
  364. package/dist/claude/validate-tool-update.d.ts.map +0 -1
  365. package/dist/claude/validate-tool-update.js +0 -122
  366. package/dist/claude/validate-tool-update.js.map +0 -1
  367. package/dist/cli/agent-detect.d.ts +0 -44
  368. package/dist/cli/agent-detect.d.ts.map +0 -1
  369. package/dist/cli/agent-detect.js +0 -66
  370. package/dist/cli/agent-detect.js.map +0 -1
  371. package/dist/cli/arg-errors.d.ts +0 -6
  372. package/dist/cli/arg-errors.d.ts.map +0 -1
  373. package/dist/cli/arg-errors.js +0 -44
  374. package/dist/cli/arg-errors.js.map +0 -1
  375. package/dist/cli/arg-options.d.ts +0 -26
  376. package/dist/cli/arg-options.d.ts.map +0 -1
  377. package/dist/cli/arg-options.js +0 -50
  378. package/dist/cli/arg-options.js.map +0 -1
  379. package/dist/cli/args.d.ts +0 -7
  380. package/dist/cli/args.d.ts.map +0 -1
  381. package/dist/cli/args.js +0 -70
  382. package/dist/cli/args.js.map +0 -1
  383. package/dist/cli/lifecycle-outcome.d.ts +0 -13
  384. package/dist/cli/lifecycle-outcome.d.ts.map +0 -1
  385. package/dist/cli/lifecycle-outcome.js +0 -20
  386. package/dist/cli/lifecycle-outcome.js.map +0 -1
  387. package/dist/cli/lifecycle.d.ts +0 -61
  388. package/dist/cli/lifecycle.d.ts.map +0 -1
  389. package/dist/cli/lifecycle.js +0 -152
  390. package/dist/cli/lifecycle.js.map +0 -1
  391. package/dist/cli/request-finalize.d.ts +0 -10
  392. package/dist/cli/request-finalize.d.ts.map +0 -1
  393. package/dist/cli/request-finalize.js +0 -135
  394. package/dist/cli/request-finalize.js.map +0 -1
  395. package/dist/cli/request-layers.d.ts +0 -30
  396. package/dist/cli/request-layers.d.ts.map +0 -1
  397. package/dist/cli/request-layers.js +0 -44
  398. package/dist/cli/request-layers.js.map +0 -1
  399. package/dist/cli/request-settings.d.ts +0 -34
  400. package/dist/cli/request-settings.d.ts.map +0 -1
  401. package/dist/cli/request-settings.js +0 -66
  402. package/dist/cli/request-settings.js.map +0 -1
  403. package/dist/cli/request-sources.d.ts +0 -13
  404. package/dist/cli/request-sources.d.ts.map +0 -1
  405. package/dist/cli/request-sources.js +0 -23
  406. package/dist/cli/request-sources.js.map +0 -1
  407. package/dist/cli/request-validation.d.ts +0 -18
  408. package/dist/cli/request-validation.d.ts.map +0 -1
  409. package/dist/cli/request-validation.js +0 -84
  410. package/dist/cli/request-validation.js.map +0 -1
  411. package/dist/cli/request-values.d.ts +0 -33
  412. package/dist/cli/request-values.d.ts.map +0 -1
  413. package/dist/cli/request-values.js +0 -73
  414. package/dist/cli/request-values.js.map +0 -1
  415. package/dist/cli/request.d.ts +0 -12
  416. package/dist/cli/request.d.ts.map +0 -1
  417. package/dist/cli/request.js +0 -103
  418. package/dist/cli/request.js.map +0 -1
  419. package/dist/cli/resolution-types.d.ts +0 -35
  420. package/dist/cli/resolution-types.d.ts.map +0 -1
  421. package/dist/cli/resolution-types.js +0 -6
  422. package/dist/cli/resolution-types.js.map +0 -1
  423. package/dist/cli/run-output-lines.d.ts +0 -14
  424. package/dist/cli/run-output-lines.d.ts.map +0 -1
  425. package/dist/cli/run-output-lines.js +0 -42
  426. package/dist/cli/run-output-lines.js.map +0 -1
  427. package/dist/cli/run-output.d.ts +0 -48
  428. package/dist/cli/run-output.d.ts.map +0 -1
  429. package/dist/cli/run-output.js +0 -150
  430. package/dist/cli/run-output.js.map +0 -1
  431. package/dist/cli/run.d.ts +0 -20
  432. package/dist/cli/run.d.ts.map +0 -1
  433. package/dist/cli/run.js +0 -126
  434. package/dist/cli/run.js.map +0 -1
  435. package/dist/cli/session-launch.d.ts +0 -23
  436. package/dist/cli/session-launch.d.ts.map +0 -1
  437. package/dist/cli/session-launch.js +0 -57
  438. package/dist/cli/session-launch.js.map +0 -1
  439. package/dist/cli/session.d.ts +0 -68
  440. package/dist/cli/session.d.ts.map +0 -1
  441. package/dist/cli/session.js +0 -124
  442. package/dist/cli/session.js.map +0 -1
  443. package/dist/codex/attach-images.d.ts +0 -20
  444. package/dist/codex/attach-images.d.ts.map +0 -1
  445. package/dist/codex/attach-images.js +0 -66
  446. package/dist/codex/attach-images.js.map +0 -1
  447. package/dist/codex/clipboard-lock.d.ts +0 -15
  448. package/dist/codex/clipboard-lock.d.ts.map +0 -1
  449. package/dist/codex/clipboard-lock.js +0 -16
  450. package/dist/codex/clipboard-lock.js.map +0 -1
  451. package/dist/codex/clipboard.d.ts +0 -32
  452. package/dist/codex/clipboard.d.ts.map +0 -1
  453. package/dist/codex/clipboard.js +0 -92
  454. package/dist/codex/clipboard.js.map +0 -1
  455. package/dist/codex/config-lock.d.ts +0 -21
  456. package/dist/codex/config-lock.d.ts.map +0 -1
  457. package/dist/codex/config-lock.js +0 -22
  458. package/dist/codex/config-lock.js.map +0 -1
  459. package/dist/codex/config-restore.d.ts +0 -33
  460. package/dist/codex/config-restore.d.ts.map +0 -1
  461. package/dist/codex/config-restore.js +0 -90
  462. package/dist/codex/config-restore.js.map +0 -1
  463. package/dist/codex/config-transaction.d.ts +0 -26
  464. package/dist/codex/config-transaction.d.ts.map +0 -1
  465. package/dist/codex/config-transaction.js +0 -47
  466. package/dist/codex/config-transaction.js.map +0 -1
  467. package/dist/codex/hook-dispatch.d.ts +0 -9
  468. package/dist/codex/hook-dispatch.d.ts.map +0 -1
  469. package/dist/codex/hook-dispatch.js +0 -14
  470. package/dist/codex/hook-dispatch.js.map +0 -1
  471. package/dist/codex/hook-names.d.ts +0 -19
  472. package/dist/codex/hook-names.d.ts.map +0 -1
  473. package/dist/codex/hook-names.js +0 -17
  474. package/dist/codex/hook-names.js.map +0 -1
  475. package/dist/codex/hooks.d.ts +0 -99
  476. package/dist/codex/hooks.d.ts.map +0 -1
  477. package/dist/codex/hooks.js +0 -6
  478. package/dist/codex/hooks.js.map +0 -1
  479. package/dist/codex/initial-ready.d.ts +0 -19
  480. package/dist/codex/initial-ready.d.ts.map +0 -1
  481. package/dist/codex/initial-ready.js +0 -19
  482. package/dist/codex/initial-ready.js.map +0 -1
  483. package/dist/codex/serialize.d.ts +0 -8
  484. package/dist/codex/serialize.d.ts.map +0 -1
  485. package/dist/codex/serialize.js +0 -48
  486. package/dist/codex/serialize.js.map +0 -1
  487. package/dist/codex/session-bridge.d.ts +0 -14
  488. package/dist/codex/session-bridge.d.ts.map +0 -1
  489. package/dist/codex/session-bridge.js +0 -20
  490. package/dist/codex/session-bridge.js.map +0 -1
  491. package/dist/codex/session-build.d.ts +0 -15
  492. package/dist/codex/session-build.d.ts.map +0 -1
  493. package/dist/codex/session-build.js +0 -144
  494. package/dist/codex/session-build.js.map +0 -1
  495. package/dist/codex/session-cleanup.d.ts +0 -12
  496. package/dist/codex/session-cleanup.d.ts.map +0 -1
  497. package/dist/codex/session-cleanup.js +0 -15
  498. package/dist/codex/session-cleanup.js.map +0 -1
  499. package/dist/codex/session-hooks.d.ts +0 -13
  500. package/dist/codex/session-hooks.d.ts.map +0 -1
  501. package/dist/codex/session-hooks.js +0 -54
  502. package/dist/codex/session-hooks.js.map +0 -1
  503. package/dist/codex/session-instance.d.ts +0 -50
  504. package/dist/codex/session-instance.d.ts.map +0 -1
  505. package/dist/codex/session-instance.js +0 -117
  506. package/dist/codex/session-instance.js.map +0 -1
  507. package/dist/codex/session-resume.d.ts +0 -7
  508. package/dist/codex/session-resume.d.ts.map +0 -1
  509. package/dist/codex/session-resume.js +0 -44
  510. package/dist/codex/session-resume.js.map +0 -1
  511. package/dist/codex/session-runtime.d.ts +0 -7
  512. package/dist/codex/session-runtime.d.ts.map +0 -1
  513. package/dist/codex/session-runtime.js +0 -10
  514. package/dist/codex/session-runtime.js.map +0 -1
  515. package/dist/codex/session-transcript.d.ts +0 -30
  516. package/dist/codex/session-transcript.d.ts.map +0 -1
  517. package/dist/codex/session-transcript.js +0 -53
  518. package/dist/codex/session-transcript.js.map +0 -1
  519. package/dist/codex/session-types.d.ts +0 -87
  520. package/dist/codex/session-types.d.ts.map +0 -1
  521. package/dist/codex/session-types.js +0 -6
  522. package/dist/codex/session-types.js.map +0 -1
  523. package/dist/codex/session-warnings.d.ts +0 -27
  524. package/dist/codex/session-warnings.d.ts.map +0 -1
  525. package/dist/codex/session-warnings.js +0 -54
  526. package/dist/codex/session-warnings.js.map +0 -1
  527. package/dist/codex/session.d.ts +0 -16
  528. package/dist/codex/session.d.ts.map +0 -1
  529. package/dist/codex/session.js +0 -61
  530. package/dist/codex/session.js.map +0 -1
  531. package/dist/codex/start-or-resume.d.ts +0 -12
  532. package/dist/codex/start-or-resume.d.ts.map +0 -1
  533. package/dist/codex/start-or-resume.js +0 -31
  534. package/dist/codex/start-or-resume.js.map +0 -1
  535. package/dist/codex/transcript/cursor-io.d.ts +0 -7
  536. package/dist/codex/transcript/cursor-io.d.ts.map +0 -1
  537. package/dist/codex/transcript/cursor-io.js +0 -7
  538. package/dist/codex/transcript/cursor-io.js.map +0 -1
  539. package/dist/codex/transcript/cursor.d.ts +0 -8
  540. package/dist/codex/transcript/cursor.d.ts.map +0 -1
  541. package/dist/codex/transcript/cursor.js +0 -8
  542. package/dist/codex/transcript/cursor.js.map +0 -1
  543. package/dist/codex/transcript/drops.d.ts +0 -9
  544. package/dist/codex/transcript/drops.d.ts.map +0 -1
  545. package/dist/codex/transcript/drops.js +0 -9
  546. package/dist/codex/transcript/drops.js.map +0 -1
  547. package/dist/codex/transcript.d.ts +0 -12
  548. package/dist/codex/transcript.d.ts.map +0 -1
  549. package/dist/codex/transcript.js +0 -10
  550. package/dist/codex/transcript.js.map +0 -1
  551. package/dist/codex/validate-result.d.ts +0 -7
  552. package/dist/codex/validate-result.d.ts.map +0 -1
  553. package/dist/codex/validate-result.js +0 -84
  554. package/dist/codex/validate-result.js.map +0 -1
  555. package/dist/codex/validate.d.ts +0 -11
  556. package/dist/codex/validate.d.ts.map +0 -1
  557. package/dist/codex/validate.js +0 -88
  558. package/dist/codex/validate.js.map +0 -1
  559. package/dist/core/activity-lifecycle.d.ts +0 -21
  560. package/dist/core/activity-lifecycle.d.ts.map +0 -1
  561. package/dist/core/activity-lifecycle.js +0 -45
  562. package/dist/core/activity-lifecycle.js.map +0 -1
  563. package/dist/core/activity-meta.d.ts +0 -13
  564. package/dist/core/activity-meta.d.ts.map +0 -1
  565. package/dist/core/activity-meta.js +0 -67
  566. package/dist/core/activity-meta.js.map +0 -1
  567. package/dist/core/activity-transcript.d.ts +0 -19
  568. package/dist/core/activity-transcript.d.ts.map +0 -1
  569. package/dist/core/activity-transcript.js +0 -60
  570. package/dist/core/activity-transcript.js.map +0 -1
  571. package/dist/core/activity.d.ts +0 -51
  572. package/dist/core/activity.d.ts.map +0 -1
  573. package/dist/core/activity.js +0 -81
  574. package/dist/core/activity.js.map +0 -1
  575. package/dist/core/control-queue-state.d.ts +0 -29
  576. package/dist/core/control-queue-state.d.ts.map +0 -1
  577. package/dist/core/control-queue-state.js +0 -95
  578. package/dist/core/control-queue-state.js.map +0 -1
  579. package/dist/core/control-queue-traits.d.ts +0 -54
  580. package/dist/core/control-queue-traits.d.ts.map +0 -1
  581. package/dist/core/control-queue-traits.js +0 -118
  582. package/dist/core/control-queue-traits.js.map +0 -1
  583. package/dist/core/control-queue-types.d.ts +0 -45
  584. package/dist/core/control-queue-types.d.ts.map +0 -1
  585. package/dist/core/control-queue-types.js +0 -7
  586. package/dist/core/control-queue-types.js.map +0 -1
  587. package/dist/core/control-queue.d.ts +0 -21
  588. package/dist/core/control-queue.d.ts.map +0 -1
  589. package/dist/core/control-queue.js +0 -98
  590. package/dist/core/control-queue.js.map +0 -1
  591. package/dist/core/list-models.d.ts +0 -44
  592. package/dist/core/list-models.d.ts.map +0 -1
  593. package/dist/core/list-models.js +0 -73
  594. package/dist/core/list-models.js.map +0 -1
  595. package/dist/core/model-picker.d.ts +0 -22
  596. package/dist/core/model-picker.d.ts.map +0 -1
  597. package/dist/core/model-picker.js +0 -58
  598. package/dist/core/model-picker.js.map +0 -1
  599. package/dist/core/model-rows.d.ts +0 -21
  600. package/dist/core/model-rows.d.ts.map +0 -1
  601. package/dist/core/model-rows.js +0 -57
  602. package/dist/core/model-rows.js.map +0 -1
  603. package/dist/core/probe-state.d.ts +0 -21
  604. package/dist/core/probe-state.d.ts.map +0 -1
  605. package/dist/core/probe-state.js +0 -39
  606. package/dist/core/probe-state.js.map +0 -1
  607. package/dist/core/session-input-abort.d.ts +0 -10
  608. package/dist/core/session-input-abort.d.ts.map +0 -1
  609. package/dist/core/session-input-abort.js +0 -44
  610. package/dist/core/session-input-abort.js.map +0 -1
  611. package/dist/core/session-input.d.ts +0 -37
  612. package/dist/core/session-input.d.ts.map +0 -1
  613. package/dist/core/session-input.js +0 -154
  614. package/dist/core/session-input.js.map +0 -1
  615. package/dist/core/session-warnings.d.ts +0 -20
  616. package/dist/core/session-warnings.d.ts.map +0 -1
  617. package/dist/core/session-warnings.js +0 -32
  618. package/dist/core/session-warnings.js.map +0 -1
  619. package/dist/core/simple/loop-controls.d.ts +0 -7
  620. package/dist/core/simple/loop-controls.d.ts.map +0 -1
  621. package/dist/core/simple/loop-controls.js +0 -7
  622. package/dist/core/simple/loop-controls.js.map +0 -1
  623. package/dist/core/startup-automation.d.ts +0 -54
  624. package/dist/core/startup-automation.d.ts.map +0 -1
  625. package/dist/core/startup-automation.js +0 -40
  626. package/dist/core/startup-automation.js.map +0 -1
  627. package/dist/core/startup-frame.d.ts +0 -39
  628. package/dist/core/startup-frame.d.ts.map +0 -1
  629. package/dist/core/startup-frame.js +0 -60
  630. package/dist/core/startup-frame.js.map +0 -1
  631. package/dist/core/startup-write.d.ts +0 -47
  632. package/dist/core/startup-write.d.ts.map +0 -1
  633. package/dist/core/startup-write.js +0 -73
  634. package/dist/core/startup-write.js.map +0 -1
  635. package/dist/core/trust-blocking.d.ts +0 -22
  636. package/dist/core/trust-blocking.d.ts.map +0 -1
  637. package/dist/core/trust-blocking.js +0 -38
  638. package/dist/core/trust-blocking.js.map +0 -1
  639. package/dist/core/trust-prompts.d.ts +0 -135
  640. package/dist/core/trust-prompts.d.ts.map +0 -1
  641. package/dist/core/trust-prompts.js.map +0 -1
  642. package/dist/core/trust-responder.d.ts +0 -48
  643. package/dist/core/trust-responder.d.ts.map +0 -1
  644. package/dist/core/trust-responder.js +0 -119
  645. package/dist/core/trust-responder.js.map +0 -1
  646. package/dist/core/tui-screen.d.ts +0 -21
  647. package/dist/core/tui-screen.d.ts.map +0 -1
  648. package/dist/core/tui-screen.js +0 -56
  649. package/dist/core/tui-screen.js.map +0 -1
  650. package/dist/core/update-warning.d.ts +0 -25
  651. package/dist/core/update-warning.d.ts.map +0 -1
  652. package/dist/core/update-warning.js +0 -33
  653. package/dist/core/update-warning.js.map +0 -1
  654. package/dist/core/warning-lifecycle.d.ts +0 -23
  655. package/dist/core/warning-lifecycle.d.ts.map +0 -1
  656. package/dist/core/warning-lifecycle.js +0 -6
  657. package/dist/core/warning-lifecycle.js.map +0 -1
  658. package/dist/core/warning-reasons.d.ts +0 -62
  659. package/dist/core/warning-reasons.d.ts.map +0 -1
  660. package/dist/core/warning-reasons.js +0 -121
  661. package/dist/core/warning-reasons.js.map +0 -1
  662. package/dist/core/warnings.d.ts +0 -145
  663. package/dist/core/warnings.d.ts.map +0 -1
  664. package/dist/core/warnings.js +0 -12
  665. package/dist/core/warnings.js.map +0 -1
  666. package/dist/runtime/cleanup-latch.d.ts +0 -27
  667. package/dist/runtime/cleanup-latch.d.ts.map +0 -1
  668. package/dist/runtime/cleanup-latch.js +0 -43
  669. package/dist/runtime/cleanup-latch.js.map +0 -1
  670. package/dist/runtime/initial-ready-advance.d.ts +0 -22
  671. package/dist/runtime/initial-ready-advance.d.ts.map +0 -1
  672. package/dist/runtime/initial-ready-advance.js +0 -39
  673. package/dist/runtime/initial-ready-advance.js.map +0 -1
  674. package/dist/runtime/initial-ready-fallback.d.ts +0 -12
  675. package/dist/runtime/initial-ready-fallback.d.ts.map +0 -1
  676. package/dist/runtime/initial-ready-fallback.js +0 -20
  677. package/dist/runtime/initial-ready-fallback.js.map +0 -1
  678. package/dist/runtime/initial-ready.d.ts +0 -49
  679. package/dist/runtime/initial-ready.d.ts.map +0 -1
  680. package/dist/runtime/initial-ready.js +0 -81
  681. package/dist/runtime/initial-ready.js.map +0 -1
  682. package/dist/runtime/reap-tree.d.ts +0 -62
  683. package/dist/runtime/reap-tree.d.ts.map +0 -1
  684. package/dist/runtime/reap-tree.js +0 -108
  685. package/dist/runtime/reap-tree.js.map +0 -1
  686. package/dist/runtime/session-base-types.d.ts +0 -36
  687. package/dist/runtime/session-base-types.d.ts.map +0 -1
  688. package/dist/runtime/session-base-types.js +0 -14
  689. package/dist/runtime/session-base-types.js.map +0 -1
  690. package/dist/runtime/session-base.d.ts +0 -48
  691. package/dist/runtime/session-base.d.ts.map +0 -1
  692. package/dist/runtime/session-base.js +0 -76
  693. package/dist/runtime/session-base.js.map +0 -1
  694. package/dist/runtime/session-commands.d.ts +0 -43
  695. package/dist/runtime/session-commands.d.ts.map +0 -1
  696. package/dist/runtime/session-commands.js +0 -52
  697. package/dist/runtime/session-commands.js.map +0 -1
  698. package/dist/runtime/session-exit.d.ts +0 -16
  699. package/dist/runtime/session-exit.d.ts.map +0 -1
  700. package/dist/runtime/session-exit.js +0 -32
  701. package/dist/runtime/session-exit.js.map +0 -1
  702. package/dist/runtime/session-image-attach.d.ts +0 -45
  703. package/dist/runtime/session-image-attach.d.ts.map +0 -1
  704. package/dist/runtime/session-image-attach.js +0 -82
  705. package/dist/runtime/session-image-attach.js.map +0 -1
  706. package/dist/runtime/session-lifecycle.d.ts +0 -61
  707. package/dist/runtime/session-lifecycle.d.ts.map +0 -1
  708. package/dist/runtime/session-lifecycle.js +0 -164
  709. package/dist/runtime/session-lifecycle.js.map +0 -1
  710. package/dist/runtime/session-loops.d.ts +0 -32
  711. package/dist/runtime/session-loops.d.ts.map +0 -1
  712. package/dist/runtime/session-loops.js +0 -62
  713. package/dist/runtime/session-loops.js.map +0 -1
  714. package/dist/runtime/session-readiness.d.ts +0 -18
  715. package/dist/runtime/session-readiness.d.ts.map +0 -1
  716. package/dist/runtime/session-readiness.js +0 -22
  717. package/dist/runtime/session-readiness.js.map +0 -1
  718. package/dist/runtime/session-reap.d.ts +0 -28
  719. package/dist/runtime/session-reap.d.ts.map +0 -1
  720. package/dist/runtime/session-reap.js +0 -51
  721. package/dist/runtime/session-reap.js.map +0 -1
  722. package/dist/runtime/session-resize.d.ts +0 -20
  723. package/dist/runtime/session-resize.d.ts.map +0 -1
  724. package/dist/runtime/session-resize.js +0 -26
  725. package/dist/runtime/session-resize.js.map +0 -1
  726. package/dist/runtime/session-shutdown-binding.d.ts +0 -30
  727. package/dist/runtime/session-shutdown-binding.d.ts.map +0 -1
  728. package/dist/runtime/session-shutdown-binding.js +0 -37
  729. package/dist/runtime/session-shutdown-binding.js.map +0 -1
  730. package/dist/runtime/session-shutdown.d.ts +0 -60
  731. package/dist/runtime/session-shutdown.d.ts.map +0 -1
  732. package/dist/runtime/session-shutdown.js +0 -140
  733. package/dist/runtime/session-shutdown.js.map +0 -1
  734. package/dist/runtime/session-status-wiring.d.ts +0 -38
  735. package/dist/runtime/session-status-wiring.d.ts.map +0 -1
  736. package/dist/runtime/session-status-wiring.js +0 -41
  737. package/dist/runtime/session-status-wiring.js.map +0 -1
  738. package/dist/runtime/session-status.d.ts +0 -7
  739. package/dist/runtime/session-status.d.ts.map +0 -1
  740. package/dist/runtime/session-status.js +0 -22
  741. package/dist/runtime/session-status.js.map +0 -1
  742. package/dist/runtime/shutdown-coordinator.d.ts +0 -57
  743. package/dist/runtime/shutdown-coordinator.d.ts.map +0 -1
  744. package/dist/runtime/shutdown-coordinator.js +0 -77
  745. package/dist/runtime/shutdown-coordinator.js.map +0 -1
  746. package/dist/runtime/startup-buffer.d.ts +0 -33
  747. package/dist/runtime/startup-buffer.d.ts.map +0 -1
  748. package/dist/runtime/startup-buffer.js +0 -53
  749. package/dist/runtime/startup-buffer.js.map +0 -1
  750. package/dist/runtime/startup-cleanup.d.ts +0 -43
  751. package/dist/runtime/startup-cleanup.d.ts.map +0 -1
  752. package/dist/runtime/startup-cleanup.js +0 -89
  753. package/dist/runtime/startup-cleanup.js.map +0 -1
  754. package/dist/runtime/startup.d.ts +0 -17
  755. package/dist/runtime/startup.d.ts.map +0 -1
  756. package/dist/runtime/startup.js +0 -47
  757. package/dist/runtime/startup.js.map +0 -1
  758. package/dist/runtime/status-emit.d.ts +0 -14
  759. package/dist/runtime/status-emit.d.ts.map +0 -1
  760. package/dist/runtime/status-emit.js +0 -15
  761. package/dist/runtime/status-emit.js.map +0 -1
  762. package/dist/runtime/teardown.d.ts +0 -15
  763. package/dist/runtime/teardown.d.ts.map +0 -1
  764. package/dist/runtime/teardown.js +0 -40
  765. package/dist/runtime/teardown.js.map +0 -1
  766. package/dist/runtime/terminate.d.ts +0 -22
  767. package/dist/runtime/terminate.d.ts.map +0 -1
  768. package/dist/runtime/terminate.js +0 -129
  769. package/dist/runtime/terminate.js.map +0 -1
  770. package/dist/runtime/update-lock.d.ts +0 -19
  771. package/dist/runtime/update-lock.d.ts.map +0 -1
  772. package/dist/runtime/update-lock.js +0 -183
  773. package/dist/runtime/update-lock.js.map +0 -1
  774. package/dist/runtime/update-once.d.ts +0 -40
  775. package/dist/runtime/update-once.d.ts.map +0 -1
  776. package/dist/runtime/update-once.js +0 -88
  777. package/dist/runtime/update-once.js.map +0 -1
@@ -0,0 +1,425 @@
1
+ ## 5.7 CodexSessionApi (the raw live session)
2
+
3
+ `CodexSessionApi` exposes the same control surface as `ClaudeSessionApi`: typed event
4
+ subscription, `statusDecisions`, `waitForStatus`, `waitForActivity`,
5
+ `sendPrompt`, `sendMessage`, `sendGuidance`, `sendKeys`, `resize`, `interrupt`,
6
+ `compact`, `listModels`, `setModel`, `createLoop`, `listLoops`, `cancelLoop`,
7
+ `stop`, `kill`, and `teardown`. Prompt
8
+ submission and raw input semantics are the same as Claude: Elwood writes to
9
+ the PTY as a human would. `sendGuidance` follows the state-aware intervention
10
+ contract in §5.3. `interrupt` follows the §5.3 contract — Codex also cancels a
11
+ running turn with a bare Escape keypress.
12
+ `compact` follows the §5.3 contract using Codex's `/compact` command and
13
+ `PostCompact` hook; `listModels`/`setModel` follow the §5.3 contract against
14
+ Codex's `Select Model and Effort` picker.
15
+
16
+ The package also exports `ElwoodAgentSession`, a structural supertype both
17
+ concrete session types satisfy, covering the shared identity/status
18
+ properties, the common event names (`terminal:data`, `terminal:exit`,
19
+ `status`, `activity`, `warning`, `loop`, `hookError`), the diagnostics and wait
20
+ helpers (`statusDecisions`, `waitForStatus`, `waitForActivity`), and the
21
+ shared io, command, and lifecycle methods. Parent-app code generic over "any
22
+ agent session" can be written once against this type; adapter-specific hooks
23
+ and events remain on the concrete types.
24
+
25
+ Both `ClaudeSession` and `CodexSession` deliver typed non-fatal issues observed
26
+ by Elwood through the `warning` event, projected into the adapter-neutral
27
+ `activity` stream. Warnings are LIVE-ONLY: there is no `warnings` snapshot
28
+ property — a warning is emitted once when observed and is never persisted,
29
+ replayed to a late subscriber, or accumulated (§5.7). Consumers collect warnings
30
+ by listening for the `warning` event. The MVP warning contract is:
31
+
32
+ ```ts
33
+ type ElwoodWarningEvent =
34
+ | {
35
+ readonly elwoodSessionId: string;
36
+ readonly agent: "claude" | "codex";
37
+ readonly source: "lifecycle";
38
+ readonly code: "version_unparseable";
39
+ readonly severity: "warning";
40
+ readonly message: string;
41
+ readonly raw: string;
42
+ }
43
+ | {
44
+ readonly elwoodSessionId: string;
45
+ readonly agent: "claude" | "codex";
46
+ readonly source: "lifecycle";
47
+ readonly code: "agent_update_failed";
48
+ readonly severity: "warning";
49
+ readonly message: string;
50
+ // Best-effort `claude update` / `codex update` failed, but the INSTALLED CLI
51
+ // still meets the minimum, so the session started from it. Safe diagnostics
52
+ // only: the installed version in use and an allowlisted error code (a probe
53
+ // timeout/`errno`); never terminal transcripts, prompts, tokens, or secrets.
54
+ readonly installedVersion: string;
55
+ readonly errorCode: string;
56
+ readonly raw: string;
57
+ }
58
+ | {
59
+ readonly elwoodSessionId: string;
60
+ readonly agent: "codex";
61
+ readonly source: "terminal";
62
+ readonly code: "mcp_server_not_logged_in";
63
+ readonly severity: "warning";
64
+ readonly message: string;
65
+ readonly mcpServerName: string;
66
+ readonly recoveryCommand: string;
67
+ readonly raw: string;
68
+ }
69
+ | {
70
+ // Claude's login lapsed AFTER the session was usable (C-CLAUDE-18). Content-
71
+ // free: the message and raw are FIXED canonical strings and the recovery
72
+ // command is the literal "/login"; no field carries banner or session text.
73
+ // Detection is edge-based: a banner persisting across many frames does not
74
+ // re-emit, so a session emits this live warning at most once for its login
75
+ // expiring. The session is left alive for in-place recovery via `login`.
76
+ readonly elwoodSessionId: string;
77
+ readonly agent: "claude";
78
+ readonly source: "terminal";
79
+ readonly code: "login_expired";
80
+ readonly severity: "warning";
81
+ readonly message: string;
82
+ readonly recoveryCommand: "/login";
83
+ readonly raw: string;
84
+ }
85
+ | {
86
+ readonly elwoodSessionId: string;
87
+ readonly agent: "codex";
88
+ readonly source: "terminal";
89
+ readonly code: "mcp_startup_incomplete";
90
+ readonly severity: "warning";
91
+ readonly message: string;
92
+ readonly failedServers: readonly string[];
93
+ readonly recoveryCommands: readonly string[];
94
+ readonly raw: string;
95
+ }
96
+ | {
97
+ readonly elwoodSessionId: string;
98
+ readonly agent: "codex";
99
+ readonly source: "lifecycle";
100
+ readonly code: "codex_default_model_persisted";
101
+ readonly severity: "warning";
102
+ readonly message: string;
103
+ readonly raw: string;
104
+ }
105
+ | {
106
+ readonly elwoodSessionId: string;
107
+ // Both adapters observe a committed JSONL transcript with a bounded cursor,
108
+ // so either can lose committed data the same three ways (unparseable,
109
+ // oversized, unread backlog) and surface it through this same warning.
110
+ readonly agent: "claude" | "codex";
111
+ readonly source: "terminal";
112
+ readonly code: "transcript_records_dropped";
113
+ readonly severity: "warning";
114
+ readonly message: string;
115
+ // Why data was lost: an unparseable committed record, an over-length record
116
+ // discarded through its next newline, or an unread teardown backlog. A bounded
117
+ // label only — no count and no byte magnitude (a live "something couldn't be
118
+ // displayed" signal, not a running tally).
119
+ readonly cause: "unparseable" | "oversized" | "unread_backlog";
120
+ readonly transcriptPath: string;
121
+ readonly raw: string;
122
+ }
123
+ | {
124
+ readonly elwoodSessionId: string;
125
+ // Shared: either adapter's bounded transcript cursor can hit a contained fs
126
+ // read error (a rotation/removal/permission race) and surface it here.
127
+ readonly agent: "claude" | "codex";
128
+ readonly source: "terminal";
129
+ readonly code: "transcript_read_error";
130
+ readonly severity: "warning";
131
+ readonly message: string;
132
+ // Last error code and path only — never a count, never raw transcript content.
133
+ readonly lastErrorCode: string;
134
+ readonly transcriptPath: string;
135
+ readonly raw: string;
136
+ }
137
+ | {
138
+ readonly elwoodSessionId: string;
139
+ readonly agent: "claude" | "codex";
140
+ readonly source: "terminal";
141
+ readonly code: "transcript_poll_stopped";
142
+ readonly severity: "warning";
143
+ readonly message: string;
144
+ // A short, allowlisted error reason only — never raw transcript content.
145
+ readonly reason: string;
146
+ // Which lifecycle phase failed: a live periodic poll, or the final flush at
147
+ // PTY exit. Lets an operator tell lost trailing activity during shutdown from
148
+ // a live-watcher poll failure without a distinct warning code.
149
+ readonly phase: "poll" | "final_flush";
150
+ readonly raw: string;
151
+ }
152
+ | {
153
+ readonly elwoodSessionId: string;
154
+ readonly agent: "claude" | "codex";
155
+ readonly source: "lifecycle";
156
+ readonly code: "reap_failed";
157
+ readonly severity: "warning";
158
+ readonly message: string;
159
+ // The leaked leader's process-group id and a normalized, allowlisted error
160
+ // code only (e.g. "EPERM") — enough to locate + explain the un-reaped group,
161
+ // never a raw system message or conversation content.
162
+ readonly processGroupId: number;
163
+ readonly errorCode: string;
164
+ readonly raw: string;
165
+ }
166
+ | {
167
+ readonly elwoodSessionId: string;
168
+ readonly agent: "claude";
169
+ readonly source: "lifecycle";
170
+ readonly code: "resize_restore_failed";
171
+ readonly severity: "warning";
172
+ readonly message: string;
173
+ // The size Elwood tried to restore after the narrow bootstrap and a
174
+ // normalized, allowlisted error code only — never a raw system message
175
+ // or conversation content.
176
+ readonly requestedCols: number;
177
+ readonly requestedRows: number;
178
+ readonly errorCode: string;
179
+ readonly raw: string;
180
+ }
181
+ | {
182
+ // Agent-discriminated: the LABEL is drawn only from THAT agent's own fixed
183
+ // startup-prompt labels (§5.4), so an impossible pairing (Claude + `update`,
184
+ // Codex + `browser_tools`) is unrepresentable. Never carries raw prompt or
185
+ // screen content; the prompt is left retryable so a later frame re-attempts.
186
+ readonly elwoodSessionId: string;
187
+ readonly agent: "claude";
188
+ readonly source: "terminal";
189
+ readonly code: "startup_prompt_write_failed";
190
+ readonly severity: "warning";
191
+ readonly message: string;
192
+ readonly label: StartupPromptLabelFor<"claude">;
193
+ readonly raw: string;
194
+ }
195
+ | {
196
+ readonly elwoodSessionId: string;
197
+ readonly agent: "codex";
198
+ readonly source: "terminal";
199
+ readonly code: "startup_prompt_write_failed";
200
+ readonly severity: "warning";
201
+ readonly message: string;
202
+ readonly label: StartupPromptLabelFor<"codex">;
203
+ readonly raw: string;
204
+ }
205
+ | {
206
+ // Codex-only: restoring the user's clipboard after an image paste failed. A
207
+ // fixed, content-free message and raw token only — never clipboard content.
208
+ readonly elwoodSessionId: string;
209
+ readonly agent: "codex";
210
+ readonly source: "lifecycle";
211
+ readonly code: "clipboard_restore_failed";
212
+ readonly severity: "warning";
213
+ readonly message: string;
214
+ readonly raw: string;
215
+ }
216
+ | {
217
+ // Recording the one-shot initial-ready transition threw (a lifecycle-event
218
+ // listener), so Elwood released the control queue directly (anti-starvation)
219
+ // while emitted lifecycle events may be stale. Content-free. Both adapters.
220
+ readonly elwoodSessionId: string;
221
+ readonly agent: "claude" | "codex";
222
+ readonly source: "lifecycle";
223
+ readonly code: "initial_ready_fallback";
224
+ readonly severity: "warning";
225
+ readonly message: string;
226
+ readonly raw: string;
227
+ }
228
+ };
229
+ ```
230
+
231
+ A startup prompt Elwood auto-answers is marked settled and emits its
232
+ `startup_prompt` activity ONLY after its PTY `sendInput` write actually fulfills.
233
+ If that write is rejected (for example, the terminal was disposed mid-startup),
234
+ Elwood emits NO `startup_prompt` activity for that attempt and instead surfaces a
235
+ bounded, content-free `startup_prompt_write_failed` warning carrying only the
236
+ prompt label; the prompt is left un-settled (retryable) so a later frame
237
+ re-attempts it. This prevents a failed write from being reported as an answered
238
+ prompt and from becoming permanently unanswerable (C-CLAUDE-16, C-CODEX-17).
239
+
240
+ When Elwood recognizes an allowlisted trust prompt but its affirmative option has
241
+ not rendered in the current frame yet, it emits a transient `attention` activity
242
+ (labelled with the prompt id) at most once. This is a TRANSIENT render-delay
243
+ state, not a wedge: under the say-yes policy Elwood keeps watching and answers the
244
+ prompt on a later frame once the option paints, so there is deliberately NO
245
+ warning emitted for it — a warning here would read as a "not auto-answered" signal
246
+ even after the prompt is successfully answered (C-CLAUDE-14).
247
+
248
+ The `transcript_records_dropped` warning is emitted when committed transcript
249
+ records cannot be parsed as JSON, when a single un-terminated record exceeds a
250
+ bounded size and is discarded through its next newline (so a pathological line
251
+ can neither exhaust memory nor cause quadratic processing), OR when a teardown
252
+ drain (subagent retirement or the final flush at PTY exit) reaches its bound with
253
+ an unread backlog still on disk: the backlog's size is accounted as a drop rather
254
+ than read in a single unbounded synchronous loop. A bounded `cause`
255
+ discriminator distinguishes these three sources — `"unparseable"` for a malformed
256
+ committed record, `"oversized"` for an over-length record discarded through its
257
+ next newline, and `"unread_backlog"` for a teardown backlog left unread when the
258
+ drain bound is spent — so the warning never mislabels a valid unread backlog as an
259
+ unparseable record. The warning carries no count and no byte magnitude: it is a
260
+ live, content-free signal that some committed activity could not be displayed,
261
+ cause-tagged, emitted when the loss occurs. Elwood keeps no running total of
262
+ dropped records and does not continue any such total across resume — a human at
263
+ the terminal has no loss odometer, and neither does Elwood. That drain is bounded
264
+ two ways.
265
+ First, a single chunk budget is shared across every subagent retirement AND the
266
+ final flush for a watcher's whole lifetime — a retirement never gets a fresh full
267
+ budget — so aggregate terminal read work is watcher-bounded, not per-retire.
268
+ Second, each individual drain call stops at a small wall-clock slice, so it
269
+ returns to the event loop promptly instead of monopolizing it grinding a
270
+ hundreds-of-MiB backlog; whatever is still unread when the shared budget or the
271
+ slice is spent is accounted as a content-free drop. Termination and retirement
272
+ therefore always complete in bounded-latency work — capped by both the shared
273
+ budget and the per-call slice — rather than an unbounded synchronous drain.
274
+
275
+ When the first hook to carry a transcript path is a turn-boundary hook, Elwood
276
+ recovers the current turn already committed on disk by scanning backward from the
277
+ file's end to the last user prompt. That scan is bounded: it reads in fixed
278
+ blocks, carries any UTF-8 code point split at a block boundary so recovered text
279
+ is byte-exact, and reaches back only a bounded distance. If the current turn is
280
+ larger than that bound, Elwood recovers the committed records that fall within
281
+ the bounded window rather than discarding the whole turn; only the portion beyond
282
+ the window (including the prompt boundary itself) is not recovered, and that
283
+ truncation is surfaced as a bounded, content-free `transcript_records_dropped`
284
+ drop (`cause: "unread_backlog"`, no count, no record text) so the observability
285
+ gap is closed rather than silent. A turn larger
286
+ than the recovery bound therefore never silently loses all of its committed
287
+ activity. The `transcript_read_error`
288
+ warning is emitted when a transcript filesystem read is contained (a
289
+ rotation/removal/permission race): the watcher never crashes the host, but also
290
+ does not swallow it silently. The `transcript_poll_stopped` warning is emitted
291
+ when a programming error escapes the periodic transcript poll OR the final flush
292
+ at PTY exit: the watcher stops itself and surfaces a bounded reason rather than
293
+ letting the failure become an unhandled rejection or abort the exit path. A
294
+ bounded `phase` discriminator records which of the two failed — `"poll"` for a
295
+ live periodic poll, `"final_flush"` for the final flush at PTY exit — so an
296
+ operator can tell lost trailing activity during shutdown from a live-watcher poll
297
+ failure without a distinct warning code. A
298
+ throwing activity listener during the final flush never prevents `terminal:exit`
299
+ emission, the live terminal-status transition, or the process-tree reap (C-LIFE-10): the
300
+ flush runs behind an error boundary and lifecycle completion is guaranteed. Like
301
+ every warning these carry no raw conversation content: only a bounded `cause` or
302
+ `phase` label, an error code or short reason, and the transcript path — no counts
303
+ and no byte magnitude. They are live-only: emitted as a `warning` + `activity`
304
+ event, never persisted, deduplicated across time, or replayed to a late
305
+ subscriber. To keep telemetry off the hot read path, drops are COALESCED per scan
306
+ pass: many malformed records in one bounded scan surface at most one
307
+ `transcript_records_dropped` warning per `(transcript path, cause)` for that pass,
308
+ rather than one synchronous fan-out per record — so pathological input cannot stall
309
+ the event loop with millions of listener calls (§5.7, C-CLAUDE-15).
310
+
311
+ The `reap_failed` warning is emitted when the best-effort survivor reap on an
312
+ unsolicited PTY exit fails (for example the group SIGKILL returns `EPERM`): the
313
+ session still reaches its terminal status, but the descendant process group may
314
+ have leaked, so the risk is surfaced instead of thrown out of the native exit
315
+ callback. This is a live lifecycle warning (`source: "lifecycle"`) carrying only
316
+ the leaked leader's process-group id and a normalized error code drawn from a
317
+ fixed allowlist (standard error names and common Node errnos; any unrecognized
318
+ value collapses to `UnknownError`) — never a raw system message or a
319
+ caller-controlled string — emitted once through the `warning`/`activity` contract
320
+ like every other warning, not persisted or replayed. A reap failure on an
321
+ *explicit* `stop()`/`kill()`/`teardown()` is NOT downgraded to this warning: it
322
+ rejects with a typed `termination_failed` error so the caller learns the group
323
+ was not confirmed reaped (C-LIFE-10, C-ERR-01).
324
+
325
+ The `resize_restore_failed` warning is emitted when the narrow-bootstrap restore
326
+ of the latest requested terminal size at the one-shot initial-ready transition
327
+ fails with a real (non-closed) native PTY resize error: the session stays at its
328
+ safe bootstrap width rather than reporting a resize it never applied, but the
329
+ queued persona or caller message is still released so a failed restore never
330
+ starves input. This is a lifecycle warning (`source: "lifecycle"`, Claude only)
331
+ carrying only the size Elwood tried to restore and a normalized error code drawn
332
+ from a fixed allowlist (standard error names and common native-resize errnos; any
333
+ unrecognized value collapses to `UnknownError`) — never a raw system message —
334
+ emitted once through the `warning`/`activity` contract like every other warning,
335
+ not persisted or replayed. A closed-fd resize at this transition is the ordinary
336
+ benign process-exit race and is a silent no-op, not a warning (C-API-39).
337
+
338
+ A stopped subagent's transcript (`agent_transcript_path` on a `SubagentStop`) is
339
+ a one-shot input for Claude: Elwood observes that path, flushes it once, and then
340
+ retires it from active polling, so a long-lived session with many subagents does
341
+ not accumulate an unbounded set of transcript files polled for the rest of its
342
+ lifetime. Codex subagent transcripts are NOT observed: the Codex watcher follows
343
+ only the session's own rollout file, so a Codex subagent's committed records
344
+ reach the host only insofar as the parent session's transcript carries them.
345
+ `agent_transcript_path` is still validated and delivered on the Codex
346
+ `SubagentStop` hook payload, so a host that wants those records can read the file
347
+ itself. Once the session's PTY
348
+ exits, the watcher becomes permanently terminal: no scan, emit, or observation
349
+ occurs after `finish()`, so no transcript activity is ever delivered past
350
+ `terminal:exit`.
351
+
352
+ Warnings are LIVE-ONLY. A warning is emitted once, when observed, as a `warning`
353
+ event and a projected `activity` event, and is never persisted, never replayed to
354
+ a subscriber that attaches later, and never accumulated into a session snapshot or
355
+ running tally. This matches what a human at the terminal experiences: a diagnostic
356
+ banner appears live and then scrolls away; reopening the session does not re-show
357
+ the banners from before. A subscriber receives whatever warnings are emitted after
358
+ it subscribes. Warning `raw` fields still carry only short environment diagnostics
359
+ (never prompts, terminal transcripts, hook payloads, or conversation content), but
360
+ they are live event fields, not persisted state.
361
+ For `mcp_startup_incomplete`, `recoveryCommands` are derived from the failed MCP
362
+ server names as `codex mcp login <server>`. If Codex later emits richer recovery
363
+ metadata, Elwood may prefer the CLI-provided command.
364
+
365
+ `CodexSession` also emits `codex:transcript` when it can observe new items from
366
+ Codex's own JSONL transcript. Parent apps may use this live-only event to render
367
+ thinking/status phases, assistant messages, web search calls, and other
368
+ transcript activity that is not currently represented as a Codex hook. Those
369
+ same observations are also projected into the adapter-neutral `activity` event
370
+ stream. `CodexTranscriptSummary.kind` values are `message`, `tool_call`,
371
+ `tool_result`, `reasoning`, `web_search`, and `other`.
372
+
373
+ The Codex transcript reader is bounded exactly as Claude's is. Each read pass
374
+ reads at most a fixed chunk (256 KiB) of new committed bytes rather than the whole
375
+ unread delta, decoding only to the last complete UTF-8 code point so a split
376
+ multibyte character is never corrupted, and a scan pass consumes at most a bounded
377
+ per-pass chunk budget so a large delta streams across poll ticks instead of
378
+ blocking the event loop in one synchronous read of a hundreds-of-MiB file. A
379
+ single un-terminated record may buffer only up to a bounded size (1 MiB); a record
380
+ that exceeds it is discarded through its next newline (so a pathological no-newline
381
+ line can neither exhaust memory nor cause quadratic re-concatenation) and its bytes
382
+ are accounted as an `"oversized"` drop. At teardown — the final flush at PTY exit —
383
+ the reader drains to end only within a bounded chunk budget and a small wall-clock
384
+ slice; whatever is still unread when that bound is spent is accounted as an
385
+ `"unread_backlog"` drop rather than read in a single unbounded synchronous loop, so
386
+ the flush returns to the event loop promptly. Codex data loss is surfaced through
387
+ the SAME content-free `transcript_records_dropped` warning as Claude's (now
388
+ `agent: "codex" | "claude"`), carrying only the bounded `cause` (`"unparseable"`,
389
+ `"oversized"`, or `"unread_backlog"`) and the transcript path — never a count and
390
+ never raw transcript content — as a live event, exactly like Claude's. A
391
+ scan that throws (for example a downstream activity listener that raises) MUST be
392
+ contained rather than escaping the poll timer as an uncaught exception: the Codex
393
+ watcher stops itself and surfaces the SAME content-free `transcript_poll_stopped`
394
+ warning as Claude's (now `agent: "codex" | "claude"`), carrying only an
395
+ allowlisted error `reason` and the `phase`. Drops and read errors are live-only
396
+ signals; Elwood keeps no running total and continues nothing across resume.
397
+
398
+ As with Claude, the Codex transcript is the single source of truth for committed
399
+ `assistant_message`, `tool_call`, and `tool_result` activity. The Codex `Stop`,
400
+ `PreToolUse`, and `PostToolUse` hooks MUST NOT also project those activities from
401
+ their hook payloads (`last_assistant_message`, `tool_name`/`tool_input`,
402
+ `tool_name`/`tool_output`); doing so would surface every reply and every tool
403
+ step twice — once from the hook and once from the transcript. Those hooks remain
404
+ turn-boundary and lifecycle signals, emitted as plain `hook` activity. The
405
+ `Stop` hook's `last_assistant_message` in particular can carry an un-submitted
406
+ ghost-text draft, so — exactly as for Claude — only the committed transcript
407
+ turn becomes an `assistant_message` (C-CODEX-16).
408
+
409
+ `ClaudeSession` likewise observes Claude's own JSONL transcript at the
410
+ `transcript_path` (and `agent_transcript_path`) the hook payloads carry, and is
411
+ the source of truth for committed Claude activity. A Claude `assistant_message`,
412
+ `tool_call`, or `tool_result` MUST be projected from the committed transcript
413
+ record — a Messages-API turn whose `content` blocks are `text`, `tool_use`, and
414
+ `tool_result` — and MUST NOT be projected from the `Stop` hook's
415
+ `last_assistant_message`. That hook field can carry an un-sent ghost-text or
416
+ autocomplete suggestion the user never submitted; sourcing the message from the
417
+ transcript ensures only a genuinely committed turn becomes a room message
418
+ (C-CLAUDE-15). The `Stop` hook remains a turn-boundary signal. As with Codex,
419
+ Elwood flushes readable transcript data and stops the watcher when the PTY exits.
420
+
421
+ When a Codex PTY exits, Elwood must flush readable live transcript data and stop
422
+ the transcript watcher before emitting `terminal:exit` or terminal lifecycle
423
+ status. Parent applications should not receive delayed transcript activity after
424
+ the session has already emitted `terminal:exit`, `exited`, `stopped`, or
425
+ `killed`.
@@ -0,0 +1,122 @@
1
+ ## 5.8 The session API — `ClaudeSession` / `CodexSession`
2
+
3
+ `ClaudeSession` and `CodexSession` are the primary public API: ONE class per
4
+ adapter that exposes BOTH the ergonomic `send`/`stream` convenience (for the common
5
+ "ask a question, get an answer" and "watch the work" shapes) AND the full low-level
6
+ control surface (`sendMessage`, `sendPrompt`, `sendGuidance`, `sendKeys`, `resize`,
7
+ `interrupt`, `compact`, `listModels`, `setModel`, `createLoop`, `listLoops`,
8
+ `cancelLoop`, `on`/`off`, `waitForStatus`, `waitForActivity`,
9
+ `stop`/`kill`/`teardown`, and Claude's `login`). Every method is
10
+ lazy-start-aware. The class is a thin wrapper over the same PTY-backed session the
11
+ `start*` factories build — it adds no new lifecycle or persistence behavior and reads
12
+ only public events. The `startClaude`/`startCodex` factories remain as the low-level
13
+ eager entry points but are DEPRECATED in favor of the class; they still return the
14
+ same live session object (typed `ClaudeSessionApi`/`CodexSessionApi`) the class wraps.
15
+
16
+ **Construction (lazy start).** `ClaudeSession` / `CodexSession` are constructed
17
+ synchronously with the same options as the factory, except `cwd` defaults to
18
+ `process.cwd()` so `new ClaudeSession()` is valid (the working directory and any
19
+ relative `stateDir` are snapshotted at construction, so a later `process.chdir()`
20
+ cannot move the target project). The underlying session is NOT started at
21
+ construction; it starts lazily on the first `send`/`stream` or OPERATIONAL control
22
+ call (or an explicit `start()`), so a caller never has to reason about start ordering.
23
+ The SHUTDOWN methods `stop`/`kill`/`teardown` are the exception — they do NOT start a
24
+ session, and are no-ops before start (so `close()` is safe in a `finally`). A
25
+ startup failure surfaces from that first call (or from `start()`), rejecting with the
26
+ same typed `ElwoodError` the factory would throw. `start()` is idempotent and
27
+ concurrent-safe (a second `start()`, or any lazy-starting call during startup, awaits
28
+ the same in-flight start). `on`/`off` may be called BEFORE start — subscriptions are
29
+ buffered and attached when the session starts, so subscribing never forces a start —
30
+ and `status` reads `starting` until the underlying session exists. The started
31
+ underlying session is reachable via a read-only `session` accessor (undefined until
32
+ started) for callers that need the raw object. Only `send`/`stream` turns serialize
33
+ with one another; control methods (`interrupt`, `sendKeys`, `createLoop`,
34
+ `listLoops`, `cancelLoop`, `stop`, `kill`, …) go
35
+ through immediately so an intervention reaches a running turn rather than queuing.
36
+
37
+ **Turn boundary.** A "turn" begins when a `send`/`stream` submits its prompt and
38
+ ends when its content is complete. A turn's assistant text is transcript-sourced
39
+ (C-CLAUDE-15) and the transcript is written ASYNCHRONOUSLY, so the text can arrive
40
+ shortly AFTER the `ready` status. The boundary is therefore a COMPLETENESS ORACLE,
41
+ not a timer: the turn-boundary `Stop` hook carries `last_assistant_message` — the
42
+ final assistant text of the just-completed turn — and Elwood uses it ONLY as a
43
+ completeness signal (never as displayed text, since it can be un-submitted ghost
44
+ text). Each adapter NORMALIZES its raw hook into that signal: a turn-boundary hook
45
+ yields an expected-text string (empty when the boundary carries no text), and any
46
+ other hook yields none and is IGNORED — a `Notification` or similar hook arriving
47
+ after `Stop` never clears an installed signal — so the adapter-neutral turn runner
48
+ reads the normalized signal, never raw provider hook field names. Once `ready` is
49
+ observed, the turn ends the instant the transcript-collected assistant text CONTAINS
50
+ that expected text, so it waits exactly as long as the transcript needs. When no completeness signal is available for a turn — a pure-tool
51
+ turn, or an empty/null `last_assistant_message` (e.g. `StopFailure`) — the turn falls
52
+ back to a bounded quiet-window settle after `ready` (no new content for a short
53
+ window). When a NON-EMPTY expected text IS present but never appears in the
54
+ transcript within `catchUpMs` of `ready`, the turn does NOT fall back to the quiet
55
+ window: it rejects with `wait_timeout` (a promised completion that never arrives is a
56
+ failure, not a quiet success). A terminal status ends the turn immediately (it is
57
+ final). A turn may legitimately run for HOURS (running a test
58
+ suite, polling a PR), so there is NO whole-turn timeout by default — a still-live turn
59
+ is never failed by a clock; a caller may pass an OPT-IN `timeoutMs` whole-turn
60
+ ceiling. The tight cap is `catchUpMs` (default 10000 ms), armed only ONCE `ready`
61
+ fires: the agent is done, so the transcript flush should be near-instant — if it
62
+ stalls past `catchUpMs`, the turn rejects with `wait_timeout` rather than leaving the
63
+ caller hanging. Turns
64
+ are serialized: overlapping `send`/`stream` calls queue and run one at a time in call
65
+ order, so a turn's activity never interleaves with another's. This serialization covers
66
+ the ergonomic `send`/`stream` turns only. The raw turn-producing control methods
67
+ (`sendMessage`, `sendPrompt`, `sendGuidance`) submit immediately and are NOT part of
68
+ the ergonomic turn queue, so calling one CONCURRENTLY with an in-flight `send`/`stream`
69
+ turn is unsupported — its produced turn can interleave with the ergonomic turn's
70
+ collection. Use one mode at a time: the ergonomic `send`/`stream`, or the raw
71
+ turn-producing methods, not both concurrently. Turn isolation rests on
72
+ that SERIALIZATION — the facade holds a turn's serialized slot until the AGENT reaches
73
+ its real boundary, NOT merely until the consumer stops reading. On a normal turn that
74
+ boundary is the turn's genuine completion (the transcript caught up / went quiet), which
75
+ lands shortly AFTER `ready` — never bare `ready`, since transcript activity arrives after
76
+ `ready`. On a consumer FAILURE (timeout / catch-up / backlog) the agent may still be
77
+ running — and a silent long-running tool is quiet, not done — so the slot is held until a
78
+ reliable "turn done" signal: a real `ready` (a busy agent is `running`, not ready) or a
79
+ terminal status, then a short transcript-drain settle. A hung agent holds the slot until
80
+ `close()`/`kill()` forces a terminal status. The facade subscribes to `activity` BEFORE
81
+ submitting so no early event of the turn is missed. Where the adapter tags activity with a
82
+ `turnId` (Codex), the facade additionally binds collection to the first turn's id as a
83
+ refinement; Claude transcript activity carries no `turnId`, so for Claude the
84
+ serialized-slot boundary is the sole isolation guarantee (which is why releasing the
85
+ slot on the real agent boundary, not on consumer cancellation, is load-bearing).
86
+ Because a turn has no default timeout, its buffered state is BOUNDED: the oracle
87
+ matches against a rolling window of recent assistant text (not the whole turn, and
88
+ capped even when the Stop hook's expected text is itself huge), and a turn whose
89
+ UNCONSUMED events exceed an internal cap — either in COUNT (many small events) or in
90
+ total BYTES (a few very large payloads) — fails with `wait_timeout` rather than
91
+ growing without limit. The byte cap is what actually bounds memory: the count cap
92
+ alone cannot, since a single agent-controlled event may carry an arbitrarily large
93
+ string.
94
+
95
+ **`stream(prompt, options?)`** returns an async iterable of SIMPLIFIED, typed
96
+ events for exactly one turn, yielded in arrival order and ending when the turn
97
+ settles:
98
+
99
+ - `{ type: "text"; text }` — an assistant message (`assistant_message`).
100
+ - `{ type: "thinking"; text }` — reasoning/thinking (`reasoning`).
101
+ - `{ type: "tool_call"; name; input? }` — a tool invocation (`tool_call`).
102
+ - `{ type: "tool_result"; name?; output? }` — a tool result (`tool_result`).
103
+
104
+ Other internal activity kinds (lifecycle, hook, warning, attention, status) are
105
+ NOT yielded — `stream` is the turn's content, not its telemetry (those remain on
106
+ the `activity`/`warning` events of the underlying `session`). The simplified union
107
+ is a stable public contract insulated from the richer internal
108
+ `ElwoodActivityEvent` shape. If the turn ends by terminal exit rather than
109
+ `ready`, the iterator ends without error; a `timeoutMs` breach throws
110
+ `wait_timeout` from the iterator.
111
+
112
+ **`send(prompt, options?): Promise<string>`** is defined AS `stream` drained for
113
+ text: it concatenates the `text` of every `type: "text"` event of the turn, in
114
+ order, joined by a blank line (`\n\n`) between distinct assistant messages, and
115
+ resolves with that string when the turn settles. It never includes thinking or
116
+ tool text. A turn that produces no assistant text resolves to the empty string.
117
+ `send` and `stream` share one turn-boundary definition, so their completion and
118
+ text-collection semantics are identical.
119
+
120
+ **Teardown.** `close()` stops the underlying session (falling back to `kill` on a
121
+ stop failure) and is a no-op if the session never started; it is the ergonomic
122
+ counterpart to `stop`/`kill`/`teardown` and safe to call in a `finally`.