@namzu/sdk 49.0.0 → 50.0.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 (737) hide show
  1. package/CHANGELOG.md +507 -0
  2. package/README.md +137 -125
  3. package/dist/agents/QueryAgent.d.ts.map +1 -1
  4. package/dist/agents/QueryAgent.js +1 -0
  5. package/dist/agents/QueryAgent.js.map +1 -1
  6. package/dist/agents/examples/SupervisorAgent.d.ts.map +1 -1
  7. package/dist/agents/examples/SupervisorAgent.js +1 -0
  8. package/dist/agents/examples/SupervisorAgent.js.map +1 -1
  9. package/dist/agents/runAgent.d.ts +2 -0
  10. package/dist/agents/runAgent.d.ts.map +1 -1
  11. package/dist/agents/runAgent.js +1 -0
  12. package/dist/agents/runAgent.js.map +1 -1
  13. package/dist/authorization/shell-lexer.d.ts.map +1 -1
  14. package/dist/authorization/shell-lexer.js +16 -1
  15. package/dist/authorization/shell-lexer.js.map +1 -1
  16. package/dist/bridge/acp/permission.d.ts +8 -2
  17. package/dist/bridge/acp/permission.d.ts.map +1 -1
  18. package/dist/bridge/acp/permission.js +1 -0
  19. package/dist/bridge/acp/permission.js.map +1 -1
  20. package/dist/bridge/acp/server.d.ts +25 -1
  21. package/dist/bridge/acp/server.d.ts.map +1 -1
  22. package/dist/bridge/acp/server.js +205 -21
  23. package/dist/bridge/acp/server.js.map +1 -1
  24. package/dist/bridge/acp/tasks.d.ts +5 -0
  25. package/dist/bridge/acp/tasks.d.ts.map +1 -0
  26. package/dist/bridge/acp/tasks.js +19 -0
  27. package/dist/bridge/acp/tasks.js.map +1 -0
  28. package/dist/bridge/acp/update.d.ts.map +1 -1
  29. package/dist/bridge/acp/update.js +148 -13
  30. package/dist/bridge/acp/update.js.map +1 -1
  31. package/dist/config/runtime.d.ts +31 -31
  32. package/dist/connector/mcp/adapter.d.ts.map +1 -1
  33. package/dist/connector/mcp/adapter.js +11 -4
  34. package/dist/connector/mcp/adapter.js.map +1 -1
  35. package/dist/connector/mcp/client.d.ts.map +1 -1
  36. package/dist/connector/mcp/client.js +6 -3
  37. package/dist/connector/mcp/client.js.map +1 -1
  38. package/dist/constants/acp/index.d.ts +3 -0
  39. package/dist/constants/acp/index.d.ts.map +1 -1
  40. package/dist/constants/acp/index.js +3 -0
  41. package/dist/constants/acp/index.js.map +1 -1
  42. package/dist/contracts/a2a.d.ts +80 -80
  43. package/dist/contracts/schemas.d.ts +2 -2
  44. package/dist/contracts/session/schemas.d.ts +10 -10
  45. package/dist/manager/agent/lifecycle.d.ts +11 -0
  46. package/dist/manager/agent/lifecycle.d.ts.map +1 -1
  47. package/dist/manager/agent/lifecycle.js +178 -3
  48. package/dist/manager/agent/lifecycle.js.map +1 -1
  49. package/dist/manager/plan/lifecycle.d.ts +7 -8
  50. package/dist/manager/plan/lifecycle.d.ts.map +1 -1
  51. package/dist/manager/plan/lifecycle.js +7 -8
  52. package/dist/manager/plan/lifecycle.js.map +1 -1
  53. package/dist/manager/resident/consumption.d.ts +8 -8
  54. package/dist/manager/resident/learning-cycle.d.ts +2 -2
  55. package/dist/manager/resident/learning-observation.d.ts +12 -12
  56. package/dist/manager/resident/learning.d.ts +82 -82
  57. package/dist/manager/resident/outbox.d.ts +8 -8
  58. package/dist/manager/resident/proposal.d.ts +2 -2
  59. package/dist/manager/resident/store.d.ts +10 -10
  60. package/dist/manager/session/attribution.d.ts +1 -0
  61. package/dist/manager/session/attribution.d.ts.map +1 -1
  62. package/dist/manager/session/attribution.js +9 -1
  63. package/dist/manager/session/attribution.js.map +1 -1
  64. package/dist/manager/session/streamed-message-identity.d.ts +6 -0
  65. package/dist/manager/session/streamed-message-identity.d.ts.map +1 -0
  66. package/dist/manager/session/streamed-message-identity.js +14 -0
  67. package/dist/manager/session/streamed-message-identity.js.map +1 -0
  68. package/dist/manager/session/turn-recorder.d.ts.map +1 -1
  69. package/dist/manager/session/turn-recorder.js +4 -3
  70. package/dist/manager/session/turn-recorder.js.map +1 -1
  71. package/dist/pals/activity/causality.d.ts +23 -0
  72. package/dist/pals/activity/causality.d.ts.map +1 -0
  73. package/dist/pals/activity/causality.js +205 -0
  74. package/dist/pals/activity/causality.js.map +1 -0
  75. package/dist/pals/activity/projection.d.ts +5 -0
  76. package/dist/pals/activity/projection.d.ts.map +1 -0
  77. package/dist/pals/activity/projection.js +79 -0
  78. package/dist/pals/activity/projection.js.map +1 -0
  79. package/dist/pals/activity/source.d.ts +16 -0
  80. package/dist/pals/activity/source.d.ts.map +1 -0
  81. package/dist/pals/activity/source.js +235 -0
  82. package/dist/pals/activity/source.js.map +1 -0
  83. package/dist/pals/activity/subscription-policy.d.ts +38 -0
  84. package/dist/pals/activity/subscription-policy.d.ts.map +1 -0
  85. package/dist/pals/activity/subscription-policy.js +183 -0
  86. package/dist/pals/activity/subscription-policy.js.map +1 -0
  87. package/dist/pals/activity/subscription-schema.d.ts +353 -0
  88. package/dist/pals/activity/subscription-schema.d.ts.map +1 -0
  89. package/dist/pals/activity/subscription-schema.js +24 -0
  90. package/dist/pals/activity/subscription-schema.js.map +1 -0
  91. package/dist/pals/activity/subscription-store.d.ts +25 -0
  92. package/dist/pals/activity/subscription-store.d.ts.map +1 -0
  93. package/dist/pals/activity/subscription-store.js +152 -0
  94. package/dist/pals/activity/subscription-store.js.map +1 -0
  95. package/dist/pals/activity/subscription-types.d.ts +42 -0
  96. package/dist/pals/activity/subscription-types.d.ts.map +1 -0
  97. package/dist/pals/activity/subscription-types.js +2 -0
  98. package/dist/pals/activity/subscription-types.js.map +1 -0
  99. package/dist/pals/activity/subscriptions.d.ts +32 -0
  100. package/dist/pals/activity/subscriptions.d.ts.map +1 -0
  101. package/dist/pals/activity/subscriptions.js +151 -0
  102. package/dist/pals/activity/subscriptions.js.map +1 -0
  103. package/dist/pals/activity/types.d.ts +77 -0
  104. package/dist/pals/activity/types.d.ts.map +1 -0
  105. package/dist/pals/activity/types.js +2 -0
  106. package/dist/pals/activity/types.js.map +1 -0
  107. package/dist/pals/channels/ingress.d.ts +9 -0
  108. package/dist/pals/channels/ingress.d.ts.map +1 -0
  109. package/dist/pals/channels/ingress.js +131 -0
  110. package/dist/pals/channels/ingress.js.map +1 -0
  111. package/dist/pals/channels/routes.d.ts +20 -0
  112. package/dist/pals/channels/routes.d.ts.map +1 -0
  113. package/dist/pals/channels/routes.js +111 -0
  114. package/dist/pals/channels/routes.js.map +1 -0
  115. package/dist/pals/channels/routing.d.ts +37 -0
  116. package/dist/pals/channels/routing.d.ts.map +1 -0
  117. package/dist/pals/channels/routing.js +150 -0
  118. package/dist/pals/channels/routing.js.map +1 -0
  119. package/dist/pals/channels/schema.d.ts +234 -0
  120. package/dist/pals/channels/schema.d.ts.map +1 -0
  121. package/dist/pals/channels/schema.js +94 -0
  122. package/dist/pals/channels/schema.js.map +1 -0
  123. package/dist/pals/channels/types.d.ts +115 -0
  124. package/dist/pals/channels/types.d.ts.map +1 -0
  125. package/dist/pals/channels/types.js +2 -0
  126. package/dist/pals/channels/types.js.map +1 -0
  127. package/dist/pals/communication/broker.d.ts +8 -0
  128. package/dist/pals/communication/broker.d.ts.map +1 -0
  129. package/dist/pals/communication/broker.js +121 -0
  130. package/dist/pals/communication/broker.js.map +1 -0
  131. package/dist/pals/communication/dispatch.d.ts +4 -0
  132. package/dist/pals/communication/dispatch.d.ts.map +1 -0
  133. package/dist/pals/communication/dispatch.js +57 -0
  134. package/dist/pals/communication/dispatch.js.map +1 -0
  135. package/dist/pals/communication/inbound.d.ts +9 -0
  136. package/dist/pals/communication/inbound.d.ts.map +1 -0
  137. package/dist/pals/communication/inbound.js +155 -0
  138. package/dist/pals/communication/inbound.js.map +1 -0
  139. package/dist/pals/communication/ingress-dispatch.d.ts +5 -0
  140. package/dist/pals/communication/ingress-dispatch.d.ts.map +1 -0
  141. package/dist/pals/communication/ingress-dispatch.js +51 -0
  142. package/dist/pals/communication/ingress-dispatch.js.map +1 -0
  143. package/dist/pals/communication/ingress-inbound.d.ts +9 -0
  144. package/dist/pals/communication/ingress-inbound.d.ts.map +1 -0
  145. package/dist/pals/communication/ingress-inbound.js +222 -0
  146. package/dist/pals/communication/ingress-inbound.js.map +1 -0
  147. package/dist/pals/communication/ingress-schema.d.ts +7829 -0
  148. package/dist/pals/communication/ingress-schema.d.ts.map +1 -0
  149. package/dist/pals/communication/ingress-schema.js +479 -0
  150. package/dist/pals/communication/ingress-schema.js.map +1 -0
  151. package/dist/pals/communication/ingress-types.d.ts +187 -0
  152. package/dist/pals/communication/ingress-types.d.ts.map +1 -0
  153. package/dist/pals/communication/ingress-types.js +73 -0
  154. package/dist/pals/communication/ingress-types.js.map +1 -0
  155. package/dist/pals/communication/operator.d.ts +75 -0
  156. package/dist/pals/communication/operator.d.ts.map +1 -0
  157. package/dist/pals/communication/operator.js +217 -0
  158. package/dist/pals/communication/operator.js.map +1 -0
  159. package/dist/pals/communication/policy.d.ts +41 -0
  160. package/dist/pals/communication/policy.d.ts.map +1 -0
  161. package/dist/pals/communication/policy.js +138 -0
  162. package/dist/pals/communication/policy.js.map +1 -0
  163. package/dist/pals/communication/schema.d.ts +2000 -0
  164. package/dist/pals/communication/schema.d.ts.map +1 -0
  165. package/dist/pals/communication/schema.js +170 -0
  166. package/dist/pals/communication/schema.js.map +1 -0
  167. package/dist/pals/communication/store.d.ts +61 -0
  168. package/dist/pals/communication/store.d.ts.map +1 -0
  169. package/dist/pals/communication/store.js +450 -0
  170. package/dist/pals/communication/store.js.map +1 -0
  171. package/dist/pals/communication/tools.d.ts +23 -0
  172. package/dist/pals/communication/tools.d.ts.map +1 -0
  173. package/dist/pals/communication/tools.js +107 -0
  174. package/dist/pals/communication/tools.js.map +1 -0
  175. package/dist/pals/communication/types.d.ts +168 -0
  176. package/dist/pals/communication/types.d.ts.map +1 -0
  177. package/dist/pals/communication/types.js +24 -0
  178. package/dist/pals/communication/types.js.map +1 -0
  179. package/dist/pals/communication/verify.d.ts +22 -0
  180. package/dist/pals/communication/verify.d.ts.map +1 -0
  181. package/dist/pals/communication/verify.js +142 -0
  182. package/dist/pals/communication/verify.js.map +1 -0
  183. package/dist/pals/lifecycle.d.ts +37 -0
  184. package/dist/pals/lifecycle.d.ts.map +1 -0
  185. package/dist/pals/lifecycle.js +22 -0
  186. package/dist/pals/lifecycle.js.map +1 -0
  187. package/dist/pals/prompt.d.ts +30 -0
  188. package/dist/pals/prompt.d.ts.map +1 -0
  189. package/dist/pals/prompt.js +65 -0
  190. package/dist/pals/prompt.js.map +1 -0
  191. package/dist/pals/reference-images.d.ts +44 -0
  192. package/dist/pals/reference-images.d.ts.map +1 -0
  193. package/dist/pals/reference-images.js +248 -0
  194. package/dist/pals/reference-images.js.map +1 -0
  195. package/dist/pals/runtime.d.ts +46 -0
  196. package/dist/pals/runtime.d.ts.map +1 -0
  197. package/dist/pals/runtime.js +624 -0
  198. package/dist/pals/runtime.js.map +1 -0
  199. package/dist/pals/store.d.ts +26 -0
  200. package/dist/pals/store.d.ts.map +1 -0
  201. package/dist/pals/store.js +334 -0
  202. package/dist/pals/store.js.map +1 -0
  203. package/dist/pals/types.d.ts +145 -0
  204. package/dist/pals/types.d.ts.map +1 -0
  205. package/dist/pals/types.js +2 -0
  206. package/dist/pals/types.js.map +1 -0
  207. package/dist/peers/envelope.js +1 -1
  208. package/dist/peers/envelope.js.map +1 -1
  209. package/dist/peers/protocol.d.ts +83 -83
  210. package/dist/peers/record.d.ts +10 -10
  211. package/dist/plugin/shell-hook.d.ts.map +1 -1
  212. package/dist/plugin/shell-hook.js +7 -2
  213. package/dist/plugin/shell-hook.js.map +1 -1
  214. package/dist/process/kill-tree.d.ts.map +1 -1
  215. package/dist/process/kill-tree.js +9 -1
  216. package/dist/process/kill-tree.js.map +1 -1
  217. package/dist/provider/errors.d.ts +19 -0
  218. package/dist/provider/errors.d.ts.map +1 -1
  219. package/dist/provider/errors.js +123 -2
  220. package/dist/provider/errors.js.map +1 -1
  221. package/dist/public-runtime.d.ts +41 -13
  222. package/dist/public-runtime.d.ts.map +1 -1
  223. package/dist/public-runtime.js +35 -7
  224. package/dist/public-runtime.js.map +1 -1
  225. package/dist/public-tools.d.ts +8 -3
  226. package/dist/public-tools.d.ts.map +1 -1
  227. package/dist/public-tools.js +8 -3
  228. package/dist/public-tools.js.map +1 -1
  229. package/dist/public-types.d.ts +27 -7
  230. package/dist/public-types.d.ts.map +1 -1
  231. package/dist/registry/tool/presentation.d.ts +1 -0
  232. package/dist/registry/tool/presentation.d.ts.map +1 -1
  233. package/dist/registry/tool/presentation.js +9 -7
  234. package/dist/registry/tool/presentation.js.map +1 -1
  235. package/dist/runtime/harness-session/index.d.ts +5 -0
  236. package/dist/runtime/harness-session/index.d.ts.map +1 -0
  237. package/dist/runtime/harness-session/index.js +928 -0
  238. package/dist/runtime/harness-session/index.js.map +1 -0
  239. package/dist/runtime/harness-session/journal.d.ts +37 -0
  240. package/dist/runtime/harness-session/journal.d.ts.map +1 -0
  241. package/dist/runtime/harness-session/journal.js +177 -0
  242. package/dist/runtime/harness-session/journal.js.map +1 -0
  243. package/dist/runtime/harness-session/saved-view.d.ts +8 -0
  244. package/dist/runtime/harness-session/saved-view.d.ts.map +1 -0
  245. package/dist/runtime/harness-session/saved-view.js +112 -0
  246. package/dist/runtime/harness-session/saved-view.js.map +1 -0
  247. package/dist/runtime/jobs/awaited-jobs.d.ts +2 -1
  248. package/dist/runtime/jobs/awaited-jobs.d.ts.map +1 -1
  249. package/dist/runtime/jobs/awaited-jobs.js +2 -1
  250. package/dist/runtime/jobs/awaited-jobs.js.map +1 -1
  251. package/dist/runtime/jobs/registry.d.ts +56 -1
  252. package/dist/runtime/jobs/registry.d.ts.map +1 -1
  253. package/dist/runtime/jobs/registry.js +351 -34
  254. package/dist/runtime/jobs/registry.js.map +1 -1
  255. package/dist/runtime/query/abandon-turn.d.ts +12 -1
  256. package/dist/runtime/query/abandon-turn.d.ts.map +1 -1
  257. package/dist/runtime/query/abandon-turn.js +3 -1
  258. package/dist/runtime/query/abandon-turn.js.map +1 -1
  259. package/dist/runtime/query/checkpoint.d.ts +4 -0
  260. package/dist/runtime/query/checkpoint.d.ts.map +1 -1
  261. package/dist/runtime/query/checkpoint.js +10 -0
  262. package/dist/runtime/query/checkpoint.js.map +1 -1
  263. package/dist/runtime/query/durable-inbound.d.ts +5 -0
  264. package/dist/runtime/query/durable-inbound.d.ts.map +1 -0
  265. package/dist/runtime/query/durable-inbound.js +89 -0
  266. package/dist/runtime/query/durable-inbound.js.map +1 -0
  267. package/dist/runtime/query/events.d.ts +4 -0
  268. package/dist/runtime/query/events.d.ts.map +1 -1
  269. package/dist/runtime/query/events.js +22 -5
  270. package/dist/runtime/query/events.js.map +1 -1
  271. package/dist/runtime/query/executor/tool-call-admission.d.ts +5 -1
  272. package/dist/runtime/query/executor/tool-call-admission.d.ts.map +1 -1
  273. package/dist/runtime/query/executor/tool-call-admission.js +85 -13
  274. package/dist/runtime/query/executor/tool-call-admission.js.map +1 -1
  275. package/dist/runtime/query/executor.d.ts +41 -18
  276. package/dist/runtime/query/executor.d.ts.map +1 -1
  277. package/dist/runtime/query/executor.js +227 -114
  278. package/dist/runtime/query/executor.js.map +1 -1
  279. package/dist/runtime/query/index.d.ts +3 -0
  280. package/dist/runtime/query/index.d.ts.map +1 -1
  281. package/dist/runtime/query/index.js +21 -4
  282. package/dist/runtime/query/index.js.map +1 -1
  283. package/dist/runtime/query/iteration/index.d.ts +18 -6
  284. package/dist/runtime/query/iteration/index.d.ts.map +1 -1
  285. package/dist/runtime/query/iteration/index.js +144 -67
  286. package/dist/runtime/query/iteration/index.js.map +1 -1
  287. package/dist/runtime/query/iteration/outstanding-work.d.ts +9 -5
  288. package/dist/runtime/query/iteration/outstanding-work.d.ts.map +1 -1
  289. package/dist/runtime/query/iteration/outstanding-work.js +61 -6
  290. package/dist/runtime/query/iteration/outstanding-work.js.map +1 -1
  291. package/dist/runtime/query/iteration/phases/context.d.ts +4 -0
  292. package/dist/runtime/query/iteration/phases/context.d.ts.map +1 -1
  293. package/dist/runtime/query/iteration/phases/context.js.map +1 -1
  294. package/dist/runtime/query/iteration/phases/tool-review.d.ts.map +1 -1
  295. package/dist/runtime/query/iteration/phases/tool-review.js +99 -16
  296. package/dist/runtime/query/iteration/phases/tool-review.js.map +1 -1
  297. package/dist/runtime/query/observation-context.d.ts +2 -2
  298. package/dist/runtime/query/observation-context.d.ts.map +1 -1
  299. package/dist/runtime/query/observation-context.js +20 -13
  300. package/dist/runtime/query/observation-context.js.map +1 -1
  301. package/dist/runtime/query/prepare-turn.js +2 -2
  302. package/dist/runtime/query/prepare-turn.js.map +1 -1
  303. package/dist/runtime/query/prompt-cache.d.ts +1 -0
  304. package/dist/runtime/query/prompt-cache.d.ts.map +1 -1
  305. package/dist/runtime/query/prompt-cache.js +2 -0
  306. package/dist/runtime/query/prompt-cache.js.map +1 -1
  307. package/dist/runtime/query/prompt.d.ts +2 -0
  308. package/dist/runtime/query/prompt.d.ts.map +1 -1
  309. package/dist/runtime/query/prompt.js +23 -1
  310. package/dist/runtime/query/prompt.js.map +1 -1
  311. package/dist/runtime/query/repeat-call.d.ts +12 -3
  312. package/dist/runtime/query/repeat-call.d.ts.map +1 -1
  313. package/dist/runtime/query/repeat-call.js +33 -10
  314. package/dist/runtime/query/repeat-call.js.map +1 -1
  315. package/dist/runtime/query/resume-pending.d.ts +5 -6
  316. package/dist/runtime/query/resume-pending.d.ts.map +1 -1
  317. package/dist/runtime/query/resume-pending.js +30 -3
  318. package/dist/runtime/query/resume-pending.js.map +1 -1
  319. package/dist/runtime/query/resume-session.js +1 -1
  320. package/dist/runtime/query/resume-session.js.map +1 -1
  321. package/dist/runtime/query/review-policy.d.ts +8 -1
  322. package/dist/runtime/query/review-policy.d.ts.map +1 -1
  323. package/dist/runtime/query/review-policy.js +6 -0
  324. package/dist/runtime/query/review-policy.js.map +1 -1
  325. package/dist/runtime/query/saved-presentation.d.ts +13 -0
  326. package/dist/runtime/query/saved-presentation.d.ts.map +1 -0
  327. package/dist/runtime/query/saved-presentation.js +63 -0
  328. package/dist/runtime/query/saved-presentation.js.map +1 -0
  329. package/dist/runtime/query/steering.d.ts +6 -9
  330. package/dist/runtime/query/steering.d.ts.map +1 -1
  331. package/dist/runtime/query/steering.js.map +1 -1
  332. package/dist/runtime/query/tool-executions.d.ts +7 -3
  333. package/dist/runtime/query/tool-executions.d.ts.map +1 -1
  334. package/dist/runtime/query/tool-executions.js +89 -9
  335. package/dist/runtime/query/tool-executions.js.map +1 -1
  336. package/dist/runtime/query/tooling.d.ts +3 -1
  337. package/dist/runtime/query/tooling.d.ts.map +1 -1
  338. package/dist/runtime/query/tooling.js +3 -0
  339. package/dist/runtime/query/tooling.js.map +1 -1
  340. package/dist/scheduler/completion-inbox.d.ts +25 -1
  341. package/dist/scheduler/completion-inbox.d.ts.map +1 -1
  342. package/dist/scheduler/completion-inbox.js +102 -8
  343. package/dist/scheduler/completion-inbox.js.map +1 -1
  344. package/dist/scheduler/delegating.d.ts.map +1 -1
  345. package/dist/scheduler/delegating.js +5 -0
  346. package/dist/scheduler/delegating.js.map +1 -1
  347. package/dist/scheduler/local.d.ts.map +1 -1
  348. package/dist/scheduler/local.js +2 -0
  349. package/dist/scheduler/local.js.map +1 -1
  350. package/dist/session/summary/materialize.d.ts +10 -6
  351. package/dist/session/summary/materialize.d.ts.map +1 -1
  352. package/dist/session/summary/materialize.js +41 -8
  353. package/dist/session/summary/materialize.js.map +1 -1
  354. package/dist/store/budget/ledger.d.ts +9 -0
  355. package/dist/store/budget/ledger.d.ts.map +1 -1
  356. package/dist/store/budget/ledger.js +58 -6
  357. package/dist/store/budget/ledger.js.map +1 -1
  358. package/dist/store/evidence/index-page.d.ts +12 -12
  359. package/dist/store/evidence/source-text.d.ts +4 -4
  360. package/dist/store/session/disk.d.ts +9 -4
  361. package/dist/store/session/disk.d.ts.map +1 -1
  362. package/dist/store/session/disk.js +57 -11
  363. package/dist/store/session/disk.js.map +1 -1
  364. package/dist/store/session/memory.d.ts +5 -3
  365. package/dist/store/session/memory.d.ts.map +1 -1
  366. package/dist/store/session/memory.js +24 -7
  367. package/dist/store/session/memory.js.map +1 -1
  368. package/dist/store/session-log/core.d.ts +26 -6
  369. package/dist/store/session-log/core.d.ts.map +1 -1
  370. package/dist/store/session-log/core.js +61 -8
  371. package/dist/store/session-log/core.js.map +1 -1
  372. package/dist/store/session-log/disk.d.ts +2 -2
  373. package/dist/store/session-log/disk.d.ts.map +1 -1
  374. package/dist/store/session-log/disk.js +1 -0
  375. package/dist/store/session-log/disk.js.map +1 -1
  376. package/dist/store/session-log/fold.d.ts +7 -0
  377. package/dist/store/session-log/fold.d.ts.map +1 -1
  378. package/dist/store/session-log/fold.js +21 -0
  379. package/dist/store/session-log/fold.js.map +1 -1
  380. package/dist/store/session-log/index.d.ts +5 -3
  381. package/dist/store/session-log/index.d.ts.map +1 -1
  382. package/dist/store/session-log/index.js +3 -1
  383. package/dist/store/session-log/index.js.map +1 -1
  384. package/dist/store/session-log/memory.d.ts +1 -1
  385. package/dist/store/session-log/memory.d.ts.map +1 -1
  386. package/dist/store/session-log/memory.js +1 -0
  387. package/dist/store/session-log/memory.js.map +1 -1
  388. package/dist/store/session-log/spill.d.ts +10 -3
  389. package/dist/store/session-log/spill.d.ts.map +1 -1
  390. package/dist/store/session-log/spill.js +70 -5
  391. package/dist/store/session-log/spill.js.map +1 -1
  392. package/dist/store/session-log/structured-result.d.ts +21 -0
  393. package/dist/store/session-log/structured-result.d.ts.map +1 -0
  394. package/dist/store/session-log/structured-result.js +67 -0
  395. package/dist/store/session-log/structured-result.js.map +1 -0
  396. package/dist/store/task/disk.d.ts +11 -0
  397. package/dist/store/task/disk.d.ts.map +1 -1
  398. package/dist/store/task/disk.js +41 -2
  399. package/dist/store/task/disk.js.map +1 -1
  400. package/dist/store/task/memory.d.ts.map +1 -1
  401. package/dist/store/task/memory.js +15 -3
  402. package/dist/store/task/memory.js.map +1 -1
  403. package/dist/tools/admit-facts.d.ts +13 -0
  404. package/dist/tools/admit-facts.d.ts.map +1 -0
  405. package/dist/tools/admit-facts.js +142 -0
  406. package/dist/tools/admit-facts.js.map +1 -0
  407. package/dist/tools/builtins/bash.d.ts +4 -1
  408. package/dist/tools/builtins/bash.d.ts.map +1 -1
  409. package/dist/tools/builtins/bash.js +108 -22
  410. package/dist/tools/builtins/bash.js.map +1 -1
  411. package/dist/tools/builtins/browser.d.ts +10 -10
  412. package/dist/tools/builtins/computer-use.d.ts +90 -90
  413. package/dist/tools/builtins/edit.d.ts +17 -0
  414. package/dist/tools/builtins/edit.d.ts.map +1 -1
  415. package/dist/tools/builtins/edit.js +34 -0
  416. package/dist/tools/builtins/edit.js.map +1 -1
  417. package/dist/tools/builtins/file-write-result.d.ts.map +1 -1
  418. package/dist/tools/builtins/file-write-result.js +13 -0
  419. package/dist/tools/builtins/file-write-result.js.map +1 -1
  420. package/dist/tools/builtins/glob.d.ts.map +1 -1
  421. package/dist/tools/builtins/glob.js +12 -0
  422. package/dist/tools/builtins/glob.js.map +1 -1
  423. package/dist/tools/builtins/grep.d.ts.map +1 -1
  424. package/dist/tools/builtins/grep.js +14 -0
  425. package/dist/tools/builtins/grep.js.map +1 -1
  426. package/dist/tools/builtins/index.d.ts +2 -0
  427. package/dist/tools/builtins/index.d.ts.map +1 -1
  428. package/dist/tools/builtins/index.js +1 -0
  429. package/dist/tools/builtins/index.js.map +1 -1
  430. package/dist/tools/builtins/job.d.ts.map +1 -1
  431. package/dist/tools/builtins/job.js +4 -1
  432. package/dist/tools/builtins/job.js.map +1 -1
  433. package/dist/tools/builtins/lsp.d.ts +2 -2
  434. package/dist/tools/builtins/read-file.d.ts.map +1 -1
  435. package/dist/tools/builtins/read-file.js +49 -0
  436. package/dist/tools/builtins/read-file.js.map +1 -1
  437. package/dist/tools/builtins/view-image.d.ts +24 -0
  438. package/dist/tools/builtins/view-image.d.ts.map +1 -0
  439. package/dist/tools/builtins/view-image.js +385 -0
  440. package/dist/tools/builtins/view-image.js.map +1 -0
  441. package/dist/tools/builtins/wait-for-job-bounds.d.ts +2 -0
  442. package/dist/tools/builtins/wait-for-job-bounds.d.ts.map +1 -1
  443. package/dist/tools/builtins/wait-for-job-bounds.js +1 -0
  444. package/dist/tools/builtins/wait-for-job-bounds.js.map +1 -1
  445. package/dist/tools/builtins/wait-for-job.d.ts +2 -0
  446. package/dist/tools/builtins/wait-for-job.d.ts.map +1 -1
  447. package/dist/tools/builtins/wait-for-job.js +104 -6
  448. package/dist/tools/builtins/wait-for-job.js.map +1 -1
  449. package/dist/tools/builtins/write-file.d.ts.map +1 -1
  450. package/dist/tools/builtins/write-file.js +1 -0
  451. package/dist/tools/builtins/write-file.js.map +1 -1
  452. package/dist/tools/command-shell.d.ts +37 -2
  453. package/dist/tools/command-shell.d.ts.map +1 -1
  454. package/dist/tools/command-shell.js +100 -3
  455. package/dist/tools/command-shell.js.map +1 -1
  456. package/dist/tools/coordinator/agent.d.ts +9 -19
  457. package/dist/tools/coordinator/agent.d.ts.map +1 -1
  458. package/dist/tools/coordinator/agent.js.map +1 -1
  459. package/dist/tools/coordinator/index.d.ts.map +1 -1
  460. package/dist/tools/coordinator/index.js +127 -67
  461. package/dist/tools/coordinator/index.js.map +1 -1
  462. package/dist/tools/coordinator/wait-with-idle-bound.d.ts +2 -0
  463. package/dist/tools/coordinator/wait-with-idle-bound.d.ts.map +1 -1
  464. package/dist/tools/coordinator/wait-with-idle-bound.js +1 -1
  465. package/dist/tools/coordinator/wait-with-idle-bound.js.map +1 -1
  466. package/dist/tools/defineTool.d.ts.map +1 -1
  467. package/dist/tools/defineTool.js +4 -0
  468. package/dist/tools/defineTool.js.map +1 -1
  469. package/dist/tools/failure-facts.d.ts +8 -0
  470. package/dist/tools/failure-facts.d.ts.map +1 -0
  471. package/dist/tools/failure-facts.js +24 -0
  472. package/dist/tools/failure-facts.js.map +1 -0
  473. package/dist/tools/host-output.d.ts +24 -0
  474. package/dist/tools/host-output.d.ts.map +1 -0
  475. package/dist/tools/host-output.js +117 -0
  476. package/dist/tools/host-output.js.map +1 -0
  477. package/dist/tools/oem-code-pages.d.ts +8 -0
  478. package/dist/tools/oem-code-pages.d.ts.map +1 -0
  479. package/dist/tools/oem-code-pages.js +23 -0
  480. package/dist/tools/oem-code-pages.js.map +1 -0
  481. package/dist/tools/schedules/schedule-tool.d.ts.map +1 -1
  482. package/dist/tools/schedules/schedule-tool.js +35 -6
  483. package/dist/tools/schedules/schedule-tool.js.map +1 -1
  484. package/dist/tools/schedules/types.d.ts +23 -3
  485. package/dist/tools/schedules/types.d.ts.map +1 -1
  486. package/dist/tools/task/list.d.ts.map +1 -1
  487. package/dist/tools/task/list.js +14 -6
  488. package/dist/tools/task/list.js.map +1 -1
  489. package/dist/tools/task/present.d.ts.map +1 -1
  490. package/dist/tools/task/present.js +26 -6
  491. package/dist/tools/task/present.js.map +1 -1
  492. package/dist/tools/task/update.d.ts.map +1 -1
  493. package/dist/tools/task/update.js +12 -5
  494. package/dist/tools/task/update.js.map +1 -1
  495. package/dist/tools/text-window.d.ts +19 -0
  496. package/dist/tools/text-window.d.ts.map +1 -0
  497. package/dist/tools/text-window.js +83 -0
  498. package/dist/tools/text-window.js.map +1 -0
  499. package/dist/toolsets/manager.d.ts +11 -0
  500. package/dist/toolsets/manager.d.ts.map +1 -1
  501. package/dist/toolsets/manager.js +45 -1
  502. package/dist/toolsets/manager.js.map +1 -1
  503. package/dist/types/acp/index.d.ts +137 -1
  504. package/dist/types/acp/index.d.ts.map +1 -1
  505. package/dist/types/agent/base.d.ts +3 -0
  506. package/dist/types/agent/base.d.ts.map +1 -1
  507. package/dist/types/agent/manager.d.ts +8 -23
  508. package/dist/types/agent/manager.d.ts.map +1 -1
  509. package/dist/types/agent/scheduler.d.ts +10 -1
  510. package/dist/types/agent/scheduler.d.ts.map +1 -1
  511. package/dist/types/agent/task.d.ts +4 -0
  512. package/dist/types/agent/task.d.ts.map +1 -1
  513. package/dist/types/authorization/index.d.ts +30 -30
  514. package/dist/types/connector/mcp.d.ts +7 -0
  515. package/dist/types/connector/mcp.d.ts.map +1 -1
  516. package/dist/types/errors/catalog.d.ts.map +1 -1
  517. package/dist/types/errors/catalog.js +4 -2
  518. package/dist/types/errors/catalog.js.map +1 -1
  519. package/dist/types/harness/schema.d.ts +354 -0
  520. package/dist/types/harness/schema.d.ts.map +1 -0
  521. package/dist/types/harness/schema.js +203 -0
  522. package/dist/types/harness/schema.js.map +1 -0
  523. package/dist/types/harness/session.d.ts +278 -0
  524. package/dist/types/harness/session.d.ts.map +1 -0
  525. package/dist/types/harness/session.js +2 -0
  526. package/dist/types/harness/session.js.map +1 -0
  527. package/dist/types/hitl/index.d.ts +12 -0
  528. package/dist/types/hitl/index.d.ts.map +1 -1
  529. package/dist/types/hitl/index.js.map +1 -1
  530. package/dist/types/job/index.d.ts +47 -0
  531. package/dist/types/job/index.d.ts.map +1 -0
  532. package/dist/types/job/index.js +2 -0
  533. package/dist/types/job/index.js.map +1 -0
  534. package/dist/types/message/inbound-delivery.d.ts +44 -0
  535. package/dist/types/message/inbound-delivery.d.ts.map +1 -0
  536. package/dist/types/message/inbound-delivery.js +14 -0
  537. package/dist/types/message/inbound-delivery.js.map +1 -0
  538. package/dist/types/message/index.d.ts +4 -1
  539. package/dist/types/message/index.d.ts.map +1 -1
  540. package/dist/types/message/index.js +5 -1
  541. package/dist/types/message/index.js.map +1 -1
  542. package/dist/types/plugin/index.d.ts +6 -6
  543. package/dist/types/sandbox/index.d.ts +39 -2
  544. package/dist/types/sandbox/index.d.ts.map +1 -1
  545. package/dist/types/sandbox/index.js.map +1 -1
  546. package/dist/types/session/checkpoint.d.ts +24 -17
  547. package/dist/types/session/checkpoint.d.ts.map +1 -1
  548. package/dist/types/session/checkpoint.js +1 -0
  549. package/dist/types/session/checkpoint.js.map +1 -1
  550. package/dist/types/session/events.d.ts +23 -1
  551. package/dist/types/session/events.d.ts.map +1 -1
  552. package/dist/types/session/events.js.map +1 -1
  553. package/dist/types/session/records.d.ts +1514 -565
  554. package/dist/types/session/records.d.ts.map +1 -1
  555. package/dist/types/session/records.js +89 -1
  556. package/dist/types/session/records.js.map +1 -1
  557. package/dist/types/session/step.d.ts +2 -0
  558. package/dist/types/session/step.d.ts.map +1 -1
  559. package/dist/types/session/step.js.map +1 -1
  560. package/dist/types/session/store.d.ts +19 -10
  561. package/dist/types/session/store.d.ts.map +1 -1
  562. package/dist/types/session/tool-execution.d.ts +6 -0
  563. package/dist/types/session/tool-execution.d.ts.map +1 -1
  564. package/dist/types/structured-output/index.d.ts +12 -2
  565. package/dist/types/structured-output/index.d.ts.map +1 -1
  566. package/dist/types/summary/ref.d.ts +3 -1
  567. package/dist/types/summary/ref.d.ts.map +1 -1
  568. package/dist/types/tool/index.d.ts +32 -4
  569. package/dist/types/tool/index.d.ts.map +1 -1
  570. package/dist/types/tool/index.js.map +1 -1
  571. package/dist/types/tool/presentation.d.ts +106 -0
  572. package/dist/types/tool/presentation.d.ts.map +1 -1
  573. package/dist/utils/json-snapshot.d.ts +6 -2
  574. package/dist/utils/json-snapshot.d.ts.map +1 -1
  575. package/dist/utils/json-snapshot.js +19 -9
  576. package/dist/utils/json-snapshot.js.map +1 -1
  577. package/dist/utils/structured-result-json.d.ts +5 -0
  578. package/dist/utils/structured-result-json.d.ts.map +1 -0
  579. package/dist/utils/structured-result-json.js +10 -0
  580. package/dist/utils/structured-result-json.js.map +1 -0
  581. package/package.json +1 -1
  582. package/src/agents/QueryAgent.ts +1 -0
  583. package/src/agents/examples/SupervisorAgent.ts +1 -0
  584. package/src/agents/runAgent.ts +3 -0
  585. package/src/authorization/shell-lexer.ts +16 -1
  586. package/src/bridge/acp/permission.ts +17 -3
  587. package/src/bridge/acp/server.ts +271 -25
  588. package/src/bridge/acp/tasks.ts +23 -0
  589. package/src/bridge/acp/update.ts +167 -13
  590. package/src/connector/mcp/adapter.ts +16 -4
  591. package/src/connector/mcp/client.ts +6 -2
  592. package/src/constants/acp/index.ts +4 -0
  593. package/src/manager/agent/lifecycle.ts +230 -3
  594. package/src/manager/plan/lifecycle.ts +11 -9
  595. package/src/manager/session/attribution.ts +12 -2
  596. package/src/manager/session/streamed-message-identity.ts +21 -0
  597. package/src/manager/session/turn-recorder.ts +4 -3
  598. package/src/pals/activity/causality.ts +261 -0
  599. package/src/pals/activity/projection.ts +89 -0
  600. package/src/pals/activity/source.ts +240 -0
  601. package/src/pals/activity/subscription-policy.ts +230 -0
  602. package/src/pals/activity/subscription-schema.ts +27 -0
  603. package/src/pals/activity/subscription-store.ts +172 -0
  604. package/src/pals/activity/subscription-types.ts +48 -0
  605. package/src/pals/activity/subscriptions.ts +209 -0
  606. package/src/pals/activity/types.ts +108 -0
  607. package/src/pals/channels/ingress.ts +153 -0
  608. package/src/pals/channels/routes.ts +118 -0
  609. package/src/pals/channels/routing.ts +197 -0
  610. package/src/pals/channels/schema.ts +108 -0
  611. package/src/pals/channels/types.ts +156 -0
  612. package/src/pals/communication/broker.ts +131 -0
  613. package/src/pals/communication/dispatch.ts +66 -0
  614. package/src/pals/communication/inbound.ts +193 -0
  615. package/src/pals/communication/ingress-dispatch.ts +63 -0
  616. package/src/pals/communication/ingress-inbound.ts +269 -0
  617. package/src/pals/communication/ingress-schema.ts +526 -0
  618. package/src/pals/communication/ingress-types.ts +336 -0
  619. package/src/pals/communication/operator.ts +315 -0
  620. package/src/pals/communication/policy.ts +174 -0
  621. package/src/pals/communication/schema.ts +173 -0
  622. package/src/pals/communication/store.ts +577 -0
  623. package/src/pals/communication/tools.ts +139 -0
  624. package/src/pals/communication/types.ts +227 -0
  625. package/src/pals/communication/verify.ts +220 -0
  626. package/src/pals/lifecycle.ts +54 -0
  627. package/src/pals/prompt.ts +101 -0
  628. package/src/pals/reference-images.ts +322 -0
  629. package/src/pals/runtime.ts +670 -0
  630. package/src/pals/store.ts +369 -0
  631. package/src/pals/types.ts +157 -0
  632. package/src/peers/envelope.ts +1 -1
  633. package/src/plugin/shell-hook.ts +8 -2
  634. package/src/process/kill-tree.ts +10 -1
  635. package/src/provider/errors.ts +135 -2
  636. package/src/public-runtime.ts +117 -12
  637. package/src/public-tools.ts +13 -1
  638. package/src/public-types.ts +69 -7
  639. package/src/registry/tool/presentation.ts +9 -4
  640. package/src/runtime/harness-session/index.ts +1125 -0
  641. package/src/runtime/harness-session/journal.ts +209 -0
  642. package/src/runtime/harness-session/saved-view.ts +122 -0
  643. package/src/runtime/jobs/awaited-jobs.ts +2 -1
  644. package/src/runtime/jobs/registry.ts +397 -41
  645. package/src/runtime/query/abandon-turn.ts +18 -2
  646. package/src/runtime/query/checkpoint.ts +11 -0
  647. package/src/runtime/query/durable-inbound.ts +101 -0
  648. package/src/runtime/query/events.ts +22 -5
  649. package/src/runtime/query/executor/tool-call-admission.ts +125 -32
  650. package/src/runtime/query/executor.ts +316 -130
  651. package/src/runtime/query/index.ts +24 -4
  652. package/src/runtime/query/iteration/index.ts +218 -104
  653. package/src/runtime/query/iteration/outstanding-work.ts +55 -7
  654. package/src/runtime/query/iteration/phases/context.ts +4 -0
  655. package/src/runtime/query/iteration/phases/tool-review.ts +118 -21
  656. package/src/runtime/query/observation-context.ts +22 -16
  657. package/src/runtime/query/prepare-turn.ts +2 -2
  658. package/src/runtime/query/prompt-cache.ts +3 -0
  659. package/src/runtime/query/prompt.ts +32 -1
  660. package/src/runtime/query/repeat-call.ts +40 -10
  661. package/src/runtime/query/resume-pending.ts +60 -7
  662. package/src/runtime/query/resume-session.ts +1 -1
  663. package/src/runtime/query/review-policy.ts +23 -2
  664. package/src/runtime/query/saved-presentation.ts +70 -0
  665. package/src/runtime/query/steering.ts +6 -9
  666. package/src/runtime/query/tool-executions.ts +108 -9
  667. package/src/runtime/query/tooling.ts +6 -1
  668. package/src/scheduler/completion-inbox.ts +108 -7
  669. package/src/scheduler/delegating.ts +5 -0
  670. package/src/scheduler/local.ts +2 -0
  671. package/src/session/summary/materialize.ts +51 -9
  672. package/src/store/budget/ledger.ts +60 -5
  673. package/src/store/session/disk.ts +77 -10
  674. package/src/store/session/memory.ts +32 -7
  675. package/src/store/session-log/core.ts +118 -11
  676. package/src/store/session-log/disk.ts +9 -2
  677. package/src/store/session-log/fold.ts +22 -0
  678. package/src/store/session-log/index.ts +5 -0
  679. package/src/store/session-log/memory.ts +2 -1
  680. package/src/store/session-log/spill.ts +89 -6
  681. package/src/store/session-log/structured-result.ts +96 -0
  682. package/src/store/task/disk.ts +46 -2
  683. package/src/store/task/memory.ts +13 -3
  684. package/src/tools/admit-facts.ts +145 -0
  685. package/src/tools/builtins/bash.ts +132 -24
  686. package/src/tools/builtins/edit.ts +42 -0
  687. package/src/tools/builtins/file-write-result.ts +14 -0
  688. package/src/tools/builtins/glob.ts +12 -0
  689. package/src/tools/builtins/grep.ts +14 -0
  690. package/src/tools/builtins/index.ts +2 -0
  691. package/src/tools/builtins/job.ts +4 -1
  692. package/src/tools/builtins/read-file.ts +57 -0
  693. package/src/tools/builtins/view-image.ts +409 -0
  694. package/src/tools/builtins/wait-for-job-bounds.ts +3 -0
  695. package/src/tools/builtins/wait-for-job.ts +141 -32
  696. package/src/tools/builtins/write-file.ts +4 -2
  697. package/src/tools/command-shell.ts +132 -5
  698. package/src/tools/coordinator/agent.ts +9 -19
  699. package/src/tools/coordinator/index.ts +150 -75
  700. package/src/tools/coordinator/wait-with-idle-bound.ts +3 -1
  701. package/src/tools/defineTool.ts +4 -0
  702. package/src/tools/failure-facts.ts +24 -0
  703. package/src/tools/host-output.ts +136 -0
  704. package/src/tools/oem-code-pages.ts +22 -0
  705. package/src/tools/schedules/schedule-tool.ts +38 -5
  706. package/src/tools/schedules/types.ts +23 -3
  707. package/src/tools/task/list.ts +15 -7
  708. package/src/tools/task/present.ts +37 -7
  709. package/src/tools/task/update.ts +12 -5
  710. package/src/tools/text-window.ts +87 -0
  711. package/src/toolsets/manager.ts +58 -1
  712. package/src/types/acp/index.ts +150 -4
  713. package/src/types/agent/base.ts +3 -0
  714. package/src/types/agent/manager.ts +8 -23
  715. package/src/types/agent/scheduler.ts +10 -1
  716. package/src/types/agent/task.ts +4 -0
  717. package/src/types/connector/mcp.ts +7 -0
  718. package/src/types/errors/catalog.ts +4 -2
  719. package/src/types/harness/schema.ts +203 -0
  720. package/src/types/harness/session.ts +306 -0
  721. package/src/types/hitl/index.ts +17 -1
  722. package/src/types/job/index.ts +42 -0
  723. package/src/types/message/inbound-delivery.ts +63 -0
  724. package/src/types/message/index.ts +8 -1
  725. package/src/types/sandbox/index.ts +46 -0
  726. package/src/types/session/checkpoint.ts +4 -1
  727. package/src/types/session/events.ts +23 -1
  728. package/src/types/session/records.ts +114 -2
  729. package/src/types/session/step.ts +2 -0
  730. package/src/types/session/store.ts +23 -9
  731. package/src/types/session/tool-execution.ts +6 -0
  732. package/src/types/structured-output/index.ts +13 -2
  733. package/src/types/summary/ref.ts +3 -1
  734. package/src/types/tool/index.ts +39 -5
  735. package/src/types/tool/presentation.ts +121 -0
  736. package/src/utils/json-snapshot.ts +26 -9
  737. package/src/utils/structured-result-json.ts +10 -0
@@ -0,0 +1,96 @@
1
+ import type { SessionRecord } from '../../types/session/records.js'
2
+ import { SessionRecordSchema } from '../../types/session/records.js'
3
+ import { awaitWithAbort } from '../../utils/await-with-abort.js'
4
+ import { cloneJsonValue } from '../../utils/json-snapshot.js'
5
+ import {
6
+ STRUCTURED_RESULT_MAX_BYTES,
7
+ parseStructuredResultJson,
8
+ } from '../../utils/structured-result-json.js'
9
+ import type { SessionLog } from './core.js'
10
+ import { SpillIntegrityError, type SpillRef, sha256Hex } from './spill.js'
11
+
12
+ export interface StructuredResultReadOptions {
13
+ readonly signal?: AbortSignal
14
+ }
15
+
16
+ /** Internal checked hydration, also used by completed-call recovery. */
17
+ export async function readStructuredResultSpill(
18
+ log: SessionLog,
19
+ ref: SpillRef,
20
+ signal?: AbortSignal,
21
+ ): Promise<{ json: string; value: unknown }> {
22
+ signal?.throwIfAborted()
23
+ if (
24
+ !Number.isSafeInteger(ref.bytes) ||
25
+ ref.bytes <= 0 ||
26
+ ref.bytes > STRUCTURED_RESULT_MAX_BYTES ||
27
+ !/^tool-results\/[a-f0-9]{64}\.txt$/.test(ref.path) ||
28
+ ref.manifest !== `${ref.path}.manifest.json` ||
29
+ !/^[a-f0-9]{64}$/.test(ref.sha256)
30
+ )
31
+ throw new SpillIntegrityError(ref.path, 'Invalid or oversized structured result reference.')
32
+ const json = await awaitWithAbort(
33
+ log.readSpill(ref, { maxBytes: STRUCTURED_RESULT_MAX_BYTES, signal }),
34
+ signal,
35
+ )
36
+ signal?.throwIfAborted()
37
+ if (
38
+ typeof json !== 'string' ||
39
+ Buffer.byteLength(json, 'utf8') !== ref.bytes ||
40
+ sha256Hex(json) !== ref.sha256
41
+ ) {
42
+ throw new SpillIntegrityError(
43
+ ref.path,
44
+ 'Structured result bytes do not match their recorded length and SHA-256.',
45
+ )
46
+ }
47
+ let value: unknown
48
+ try {
49
+ value = parseStructuredResultJson(json)
50
+ } catch (error) {
51
+ throw new SpillIntegrityError(ref.path, 'Structured result body is not JSON-safe.', {
52
+ cause: error,
53
+ })
54
+ }
55
+ signal?.throwIfAborted()
56
+ return { json, value }
57
+ }
58
+
59
+ /**
60
+ * Decode accepted structured output from a completed record obtained by the
61
+ * caller from a verified log read. This helper does not walk the chain. Raw log
62
+ * reads keep references; this explicit read checks the body before decoding.
63
+ * No schema, tool or reviewer is rerun. Undefined means no accepted JSON.
64
+ */
65
+ export async function readStructuredOutput(
66
+ log: SessionLog,
67
+ record: Extract<SessionRecord, { type: 'turn_completed' }>,
68
+ options: StructuredResultReadOptions = {},
69
+ ): Promise<unknown> {
70
+ options.signal?.throwIfAborted()
71
+ if (record.type !== 'turn_completed' || record.sessionId !== log.sessionId) {
72
+ throw new TypeError('Structured output requires a completed record from this session.')
73
+ }
74
+ SessionRecordSchema.parse(record)
75
+ const ref = record.structuredOutputSpill
76
+ if (record.settlement.status !== 'completed') {
77
+ if (record.settlement.structuredOutput !== undefined || ref !== undefined) {
78
+ throw new TypeError('A cancelled turn cannot publish accepted structured output.')
79
+ }
80
+ return undefined
81
+ }
82
+ if (
83
+ (ref !== undefined || record.settlement.structuredOutput !== undefined) &&
84
+ record.settlement.resultSource !== 'structured_output'
85
+ ) {
86
+ throw new TypeError('Accepted structured output requires the structured_output result source.')
87
+ }
88
+ if (ref !== undefined) {
89
+ const { value } = await readStructuredResultSpill(log, ref, options.signal)
90
+ options.signal?.throwIfAborted()
91
+ return value
92
+ }
93
+ return record.settlement.structuredOutput === undefined
94
+ ? undefined
95
+ : cloneJsonValue(record.settlement.structuredOutput, false)
96
+ }
@@ -238,6 +238,12 @@ export class DiskTaskStore implements TaskStore {
238
238
  if (blocker && !blocker.blocks.includes(taskId)) {
239
239
  blocker.blocks.push(taskId)
240
240
  await records.write(this.taskPath(blockerId), blocker)
241
+ this.emit({
242
+ type: 'task.updated',
243
+ taskId: blockerId,
244
+ task: blocker,
245
+ timestamp: Date.now(),
246
+ })
241
247
  }
242
248
  // If blocker is missing, we still write the new task with its
243
249
  // blockedBy reference; the dangling reference is visible to
@@ -324,17 +330,33 @@ export class DiskTaskStore implements TaskStore {
324
330
  if (!task) return false
325
331
 
326
332
  for (const blockerId of task.blockedBy) {
333
+ if (blockerId === id) continue
327
334
  const blocker = await this.readTask(blockerId)
328
- if (blocker) {
335
+ if (blocker?.blocks.includes(id)) {
329
336
  blocker.blocks = blocker.blocks.filter((bid) => bid !== id)
330
337
  await records.write(this.taskPath(blockerId), blocker)
338
+ // Announce each confirmed write now: a later write or unlink
339
+ // may fail, leaving this real graph change in place.
340
+ this.emit({
341
+ type: 'task.updated',
342
+ taskId: blockerId,
343
+ task: blocker,
344
+ timestamp: Date.now(),
345
+ })
331
346
  }
332
347
  }
333
348
  for (const blockedId of task.blocks) {
349
+ if (blockedId === id) continue
334
350
  const blocked = await this.readTask(blockedId)
335
- if (blocked) {
351
+ if (blocked?.blockedBy.includes(id)) {
336
352
  blocked.blockedBy = blocked.blockedBy.filter((bid) => bid !== id)
337
353
  await records.write(this.taskPath(blockedId), blocked)
354
+ this.emit({
355
+ type: 'task.updated',
356
+ taskId: blockedId,
357
+ task: blocked,
358
+ timestamp: Date.now(),
359
+ })
338
360
  }
339
361
  }
340
362
 
@@ -368,6 +390,26 @@ export class DiskTaskStore implements TaskStore {
368
390
  async list(filter?: { status?: TaskStatus; owner?: string; sessionId?: SessionId }): Promise<
369
391
  Task[]
370
392
  > {
393
+ return this.readList(filter, false)
394
+ }
395
+
396
+ /**
397
+ * Read a complete list or reject an unreadable directory/record. Hosts
398
+ * replacing an authoritative projection must not mistake a partial read
399
+ * for task deletion. A not-yet-created directory remains an empty list.
400
+ */
401
+ async listStrict(filter?: {
402
+ status?: TaskStatus
403
+ owner?: string
404
+ sessionId?: SessionId
405
+ }): Promise<Task[]> {
406
+ return this.readList(filter, true)
407
+ }
408
+
409
+ private async readList(
410
+ filter: { status?: TaskStatus; owner?: string; sessionId?: SessionId } | undefined,
411
+ strict: boolean,
412
+ ): Promise<Task[]> {
371
413
  if (filter?.sessionId !== undefined && filter.sessionId !== this.session.sessionId) return []
372
414
  const dir = this.taskDir()
373
415
 
@@ -379,6 +421,7 @@ export class DiskTaskStore implements TaskStore {
379
421
  'namzu.store.dir': dir,
380
422
  'exception.message': err instanceof Error ? err.message : String(err),
381
423
  })
424
+ if (strict) throw err
382
425
  return []
383
426
  }
384
427
 
@@ -393,6 +436,7 @@ export class DiskTaskStore implements TaskStore {
393
436
  'namzu.store.file': file,
394
437
  'exception.message': err instanceof Error ? err.message : String(err),
395
438
  })
439
+ if (strict) throw err
396
440
  }
397
441
  }
398
442
 
@@ -68,8 +68,14 @@ export class InMemoryTaskStore implements TaskStore {
68
68
  if (params.blockedBy) {
69
69
  for (const blockerId of params.blockedBy) {
70
70
  const blocker = this.tasks.get(blockerId)
71
- if (blocker) {
71
+ if (blocker && !blocker.blocks.includes(task.id)) {
72
72
  blocker.blocks.push(task.id)
73
+ this.emit({
74
+ type: 'task.updated',
75
+ taskId: blockerId,
76
+ task: blocker,
77
+ timestamp: Date.now(),
78
+ })
73
79
  }
74
80
  }
75
81
  }
@@ -129,15 +135,19 @@ export class InMemoryTaskStore implements TaskStore {
129
135
  if (!task) return false
130
136
 
131
137
  for (const blockerId of task.blockedBy) {
138
+ if (blockerId === id) continue
132
139
  const blocker = this.tasks.get(blockerId)
133
- if (blocker) {
140
+ if (blocker?.blocks.includes(id)) {
134
141
  blocker.blocks = blocker.blocks.filter((bid) => bid !== id)
142
+ this.emit({ type: 'task.updated', taskId: blockerId, task: blocker, timestamp: Date.now() })
135
143
  }
136
144
  }
137
145
  for (const blockedId of task.blocks) {
146
+ if (blockedId === id) continue
138
147
  const blocked = this.tasks.get(blockedId)
139
- if (blocked) {
148
+ if (blocked?.blockedBy.includes(id)) {
140
149
  blocked.blockedBy = blocked.blockedBy.filter((bid) => bid !== id)
150
+ this.emit({ type: 'task.updated', taskId: blockedId, task: blocked, timestamp: Date.now() })
141
151
  }
142
152
  }
143
153
 
@@ -0,0 +1,145 @@
1
+ import type { ToolFacts, ToolFailureReason } from '../types/tool/presentation.js'
2
+
3
+ const FAILURE_REASONS: readonly ToolFailureReason[] = [
4
+ 'not_found',
5
+ 'permission_denied',
6
+ 'not_a_file',
7
+ 'already_exists',
8
+ 'blocked',
9
+ 'needs_administrator',
10
+ 'unknown_tool',
11
+ 'timed_out',
12
+ 'invalid_input',
13
+ ]
14
+
15
+ const WRITE_OPERATIONS = ['created', 'updated', 'unchanged', 'wrote'] as const
16
+
17
+ /** Bounds on what a saved record is allowed to hold. */
18
+ const MAX_TEXT = 2_000
19
+ const MAX_COUNT = Number.MAX_SAFE_INTEGER
20
+
21
+ function isRecord(value: unknown): value is Record<string, unknown> {
22
+ return typeof value === 'object' && value !== null && !Array.isArray(value)
23
+ }
24
+
25
+ function text(value: unknown): string | undefined {
26
+ return typeof value === 'string' && value.length <= MAX_TEXT ? value : undefined
27
+ }
28
+
29
+ function count(value: unknown): number | undefined {
30
+ return typeof value === 'number' &&
31
+ Number.isSafeInteger(value) &&
32
+ value >= 0 &&
33
+ value <= MAX_COUNT
34
+ ? value
35
+ : undefined
36
+ }
37
+
38
+ function flag(value: unknown): true | undefined {
39
+ return value === true ? true : undefined
40
+ }
41
+
42
+ function pick<T extends object>(entries: Record<string, unknown>): T {
43
+ const out: Record<string, unknown> = {}
44
+ for (const [key, value] of Object.entries(entries)) if (value !== undefined) out[key] = value
45
+ return out as T
46
+ }
47
+
48
+ /**
49
+ * Read a recorded `ToolFacts` back into the closed shape, or `undefined` when
50
+ * it is not one. A journal is read by hosts that did not write it, and an
51
+ * extension field must not travel on into a screen.
52
+ *
53
+ * The text of a command's streams is a live-only convenience and a saved
54
+ * conversation does not keep it, so it is dropped here: what remains is
55
+ * enough to headline the row ("Ran npm test, failed (exit 1)") and never the
56
+ * output itself.
57
+ */
58
+ export function admitToolFacts(value: unknown): ToolFacts | undefined {
59
+ if (!isRecord(value)) return undefined
60
+ switch (value.kind) {
61
+ case 'command':
62
+ return pick<ToolFacts>({
63
+ kind: 'command',
64
+ command: text(value.command),
65
+ exitCode:
66
+ typeof value.exitCode === 'number' && Number.isSafeInteger(value.exitCode)
67
+ ? value.exitCode
68
+ : undefined,
69
+ timedOut: flag(value.timedOut),
70
+ signal: text(value.signal),
71
+ binary:
72
+ isRecord(value.binary) && count(value.binary.bytes) !== undefined
73
+ ? { bytes: count(value.binary.bytes) }
74
+ : undefined,
75
+ background: flag(value.background),
76
+ })
77
+ case 'read': {
78
+ const path = text(value.path)
79
+ if (path === undefined) return undefined
80
+ return pick<ToolFacts>({
81
+ kind: 'read',
82
+ path,
83
+ binary: flag(value.binary),
84
+ bytes: count(value.bytes),
85
+ totalLines: count(value.totalLines),
86
+ returnedLines: count(value.returnedLines),
87
+ partial: flag(value.partial),
88
+ })
89
+ }
90
+ case 'search': {
91
+ const pattern = text(value.pattern)
92
+ if (pattern === undefined) return undefined
93
+ return pick<ToolFacts>({
94
+ kind: 'search',
95
+ pattern,
96
+ path: text(value.path),
97
+ matches: count(value.matches),
98
+ filesMatched: count(value.filesMatched),
99
+ filesSearched: count(value.filesSearched),
100
+ truncated: flag(value.truncated),
101
+ })
102
+ }
103
+ case 'list': {
104
+ const pattern = text(value.pattern)
105
+ if (pattern === undefined) return undefined
106
+ return pick<ToolFacts>({
107
+ kind: 'list',
108
+ pattern,
109
+ path: text(value.path),
110
+ count: count(value.count),
111
+ truncated: flag(value.truncated),
112
+ })
113
+ }
114
+ case 'edit':
115
+ return pick<ToolFacts>({
116
+ kind: 'edit',
117
+ path: text(value.path),
118
+ replacements: count(value.replacements),
119
+ })
120
+ case 'write': {
121
+ const path = text(value.path)
122
+ const operation = WRITE_OPERATIONS.find((candidate) => candidate === value.operation)
123
+ if (path === undefined || operation === undefined) return undefined
124
+ return pick<ToolFacts>({
125
+ kind: 'write',
126
+ path,
127
+ operation,
128
+ bytes: count(value.bytes),
129
+ added: count(value.added),
130
+ removed: count(value.removed),
131
+ })
132
+ }
133
+ case 'failure': {
134
+ const reason = FAILURE_REASONS.find((candidate) => candidate === value.reason)
135
+ if (reason === undefined) return undefined
136
+ return pick<ToolFacts>({
137
+ kind: 'failure',
138
+ reason,
139
+ subject: text(value.subject),
140
+ })
141
+ }
142
+ default:
143
+ return undefined
144
+ }
145
+ }
@@ -1,20 +1,23 @@
1
- import { spawn } from 'node:child_process'
2
- import { StringDecoder } from 'node:string_decoder'
3
1
  import { z } from 'zod'
4
2
  import { SANDBOX_KILL_GRACE_MS } from '../../constants/sandbox/index.js'
5
3
  import { DANGEROUS_PATTERNS } from '../../constants/tools/index.js'
6
4
  import { killTree } from '../../process/kill-tree.js'
5
+ import { genericLabel } from '../../registry/tool/presentation.js'
6
+ import type { ToolFacts } from '../../types/tool/presentation.js'
7
7
  import { subscribeToAbort } from '../../utils/abort.js'
8
8
  import { readPositiveIntEnv } from '../../utils/env.js'
9
9
  import {
10
10
  type CommandShell,
11
11
  bashToolDialect,
12
- hostShellSpawn,
12
+ describeSpawnFailure,
13
13
  sandboxShellSpawn,
14
+ spawnHostShell,
14
15
  withoutBashStartup,
15
16
  } from '../command-shell.js'
16
17
  import { defineTool } from '../defineTool.js'
17
18
  import { scrubInheritedEnv } from '../env-scrub.js'
19
+ import { createHostOutputDecoder } from '../host-output.js'
20
+ import { looksBinary, windowText } from '../text-window.js'
18
21
  import { jsonStringEscapes } from './json-string-hint.js'
19
22
 
20
23
  // Namzu owns its own bash timeout knob — `NAMZU_BASH_TIMEOUT_MS` — and
@@ -69,7 +72,7 @@ const inputSchema = z.object({
69
72
  .boolean()
70
73
  .optional()
71
74
  .describe(
72
- 'Start the command as a background job and return its id immediately, instead of waiting. The turn is not held open; await its completion with `wait_for_job` — one call, no waiting turns. Use `job` with action "read" only for incremental output while it keeps running, or to pick up after a `wait_for_job` call times out. Use for watchers, dev servers and long builds. Do NOT write `cmd &` yourself — under the sandbox the shell that backgrounds it exits immediately and takes the job with it.',
75
+ 'Start the command as a background job and return its id immediately. For a finite build, await completion with `wait_for_job`. For a persistent server, use `wait_for_job` with output_contains and optional output_stream to observe its literal readiness marker without waiting for exit; verify health separately. Use `job` action "read" for incremental output or after a wait times out. Do NOT use `cmd &` as a substitute for a registered job: strict execution ownership can retire the allocation when the launcher exits with live descendants. An interactive application may belong to a dedicated computer only when that computer explicitly supports application lifetime; its launch result is not a registered job or proof the application has finished.',
73
76
  ),
74
77
  dangerously_disable_sandbox: z
75
78
  .boolean()
@@ -158,35 +161,35 @@ export function execHostShell(
158
161
  signal?: AbortSignal
159
162
  onOutput?: ExecHostShellProgress
160
163
  },
161
- ): Promise<{ stdout: string; stderr: string }> {
164
+ ): Promise<{
165
+ stdout: string
166
+ stderr: string
167
+ /** Bytes captured on each stream, before decoding; absent from a runner that does not count them. */
168
+ stdoutBytes?: number
169
+ stderrBytes?: number
170
+ }> {
162
171
  options.signal?.throwIfAborted()
163
172
  return new Promise((resolve, reject) => {
164
173
  // bash where the host has it, `/bin/sh` where it does not; the
165
174
  // permission rules read the line in the matching dialect. See
166
175
  // `../command-shell.ts`.
167
- const shell = hostShellSpawn(command, options.env, options.shell)
168
- const spawnOptions = {
176
+ const child = spawnHostShell(command, {
169
177
  cwd: options.cwd,
170
- env: shell.env,
171
- // killTree's negative PID must never target the caller's own group.
172
- detached: process.platform !== 'win32',
173
- }
174
- const child =
175
- shell.file === undefined
176
- ? spawn(command, { ...spawnOptions, shell: true })
177
- : spawn(shell.file, [...shell.args], spawnOptions)
178
+ env: options.env,
179
+ ...(options.shell === undefined ? {} : { shell: options.shell }),
180
+ })
178
181
  const captures = {
179
182
  stdout: {
180
183
  chunks: [] as Buffer[],
181
184
  bytes: 0,
182
185
  truncated: false,
183
- decoder: new StringDecoder('utf8'),
186
+ decoder: createHostOutputDecoder(),
184
187
  },
185
188
  stderr: {
186
189
  chunks: [] as Buffer[],
187
190
  bytes: 0,
188
191
  truncated: false,
189
- decoder: new StringDecoder('utf8'),
192
+ decoder: createHostOutputDecoder(),
190
193
  },
191
194
  }
192
195
  let cause: 'caller' | 'timeout' | 'maxBuffer' | undefined
@@ -235,8 +238,18 @@ export function execHostShell(
235
238
  const onStderr = (chunk: Buffer) => capture('stderr', chunk)
236
239
  child.stdout?.on('data', onStdout)
237
240
  child.stderr?.on('data', onStderr)
241
+ let spawned = false
242
+ child.once('spawn', () => {
243
+ spawned = true
244
+ })
238
245
  child.once('error', (error: NodeJS.ErrnoException) => {
239
- failure ??= error
246
+ // Same words as a background job that cannot start.
247
+ failure ??= spawned
248
+ ? error
249
+ : Object.assign(
250
+ new Error(describeSpawnFailure(error, options.cwd), { cause: error }),
251
+ error.code === undefined ? {} : { code: error.code },
252
+ )
240
253
  })
241
254
  child.once('close', (code, signal) => {
242
255
  closed = true
@@ -257,13 +270,20 @@ export function execHostShell(
257
270
  const decodeCapture = (stream: 'stdout' | 'stderr') => {
258
271
  const state = captures[stream]
259
272
  const bytes = Buffer.concat(state.chunks, state.bytes)
260
- // Do not flush an incomplete UTF-8 character cut by our byte cap.
261
- return state.truncated ? new StringDecoder('utf8').write(bytes) : bytes.toString('utf8')
273
+ // Do not flush an incomplete character cut by our byte cap.
274
+ const decoder = createHostOutputDecoder()
275
+ const text = decoder.write(bytes)
276
+ return state.truncated ? text : text + decoder.end()
262
277
  }
263
278
  const stdout = decodeCapture('stdout')
264
279
  const stderr = decodeCapture('stderr')
265
280
  if (!failure && cause === undefined && code === 0 && signal === null) {
266
- resolve({ stdout, stderr })
281
+ resolve({
282
+ stdout,
283
+ stderr,
284
+ stdoutBytes: captures.stdout.bytes,
285
+ stderrBytes: captures.stderr.bytes,
286
+ })
267
287
  return
268
288
  }
269
289
  const error =
@@ -281,6 +301,8 @@ export function execHostShell(
281
301
  Object.assign(error, {
282
302
  stdout,
283
303
  stderr,
304
+ stdoutBytes: captures.stdout.bytes,
305
+ stderrBytes: captures.stderr.bytes,
284
306
  stdoutTruncated: captures.stdout.truncated,
285
307
  stderrTruncated: captures.stderr.truncated,
286
308
  code: failure?.code ?? (cause === 'caller' ? 'ABORT_ERR' : code),
@@ -317,7 +339,7 @@ export const SANDBOX_ESCAPE_NOT_APPROVED =
317
339
  export const BashTool = defineTool({
318
340
  name: 'bash',
319
341
  description:
320
- 'Executes a bash command and returns stdout/stderr output. Command timeout is configurable. The `command` parameter is required — never call this tool with empty arguments. For very long content (e.g. building a large file), prefer `write` for the opening and `edit` with insertLine: "end" for follow-up chunks over a heredoc to avoid hitting the output token limit mid-stream.',
342
+ 'Executes a command line using the execution shell disclosed in the system context and returns stdout/stderr output. Command timeout is configurable. The `command` parameter is required — never call this tool with empty arguments. For very long content (e.g. building a large file), prefer `write` for the opening and `edit` with insertLine: "end" for follow-up chunks over a heredoc to avoid hitting the output token limit mid-stream.',
321
343
  inputSchema,
322
344
  // A command carries quotes and backslashes of its own, and a heredoc
323
345
  // carries newlines: copied into the JSON string raw, they end it.
@@ -348,12 +370,24 @@ export const BashTool = defineTool({
348
370
  // and diverged the moment a model asked for longer.
349
371
  timeoutMs: MAX_BASH_TIMEOUT_MS + 30_000,
350
372
 
373
+ // The same one-line label every tool without an opinion gets, plus the
374
+ // command itself as a field so a host can headline and tooltip it whole.
375
+ presentCall(input) {
376
+ if (typeof input.command !== 'string') return undefined
377
+ return {
378
+ kind: 'generic',
379
+ label: genericLabel(input),
380
+ facts: { kind: 'command', command: input.command },
381
+ }
382
+ },
383
+
351
384
  async execute(input, context) {
352
385
  if (isDangerousCommand(input.command)) {
353
386
  return {
354
387
  success: false,
355
388
  output: '',
356
389
  error: `Dangerous command blocked: "${input.command}"`,
390
+ facts: { kind: 'failure', reason: 'blocked', subject: 'bash' },
357
391
  }
358
392
  }
359
393
 
@@ -411,10 +445,24 @@ export const BashTool = defineTool({
411
445
  command: input.command,
412
446
  workingDirectory: context.workingDirectory,
413
447
  })
448
+ // `start` returns before the process exists, and a spawn that
449
+ // fails (no such shell, bad directory) reports a tick later.
450
+ // Wait for that one event so "Started" is never said of a job
451
+ // that could not start. No timer: it settles on spawn or error.
452
+ const startup = await context.backgroundJobs.awaitStarted?.(job.id)
453
+ if (startup?.error !== undefined) {
454
+ return {
455
+ success: false,
456
+ output: '',
457
+ error: `${startup.error} (job ${job.id} did not run).`,
458
+ data: { jobId: job.id, background: true, startFailed: true },
459
+ }
460
+ }
414
461
  return {
415
462
  success: true,
416
- output: `Started background job ${job.id}. Await its completion with wait_for_job: {"id":"${job.id}"}. Use job with action "read" only for output while it keeps running.`,
463
+ output: `Started background job ${job.id}. For finite work, await completion with wait_for_job: {"id":"${job.id}"}. For a persistent server, observe its literal readiness marker with wait_for_job: {"id":"${job.id}","output_contains":"<expected marker>","output_stream":"stdout"}; this leaves it running and does not prove health. Use job with action "read" for incremental output.`,
417
464
  data: { jobId: job.id, background: true },
465
+ facts: { kind: 'command', command: input.command, background: true },
418
466
  }
419
467
  } catch (err) {
420
468
  // The per-owner cap, most likely. A refusal that names the limit
@@ -499,6 +547,13 @@ export const BashTool = defineTool({
499
547
  : result.exitCode !== 0
500
548
  ? `Command exited with code ${result.exitCode}`
501
549
  : undefined,
550
+ facts: commandFacts({
551
+ command: input.command,
552
+ exitCode: result.exitCode,
553
+ timedOut: result.timedOut,
554
+ stdout: result.stdout,
555
+ stderr: result.stderr,
556
+ }),
502
557
  }
503
558
  }
504
559
 
@@ -512,7 +567,7 @@ export const BashTool = defineTool({
512
567
  const inherited = scrubInheritedEnv()
513
568
 
514
569
  try {
515
- const { stdout, stderr } = await execHostShell(input.command, {
570
+ const { stdout, stderr, stdoutBytes, stderrBytes } = await execHostShell(input.command, {
516
571
  cwd: context.workingDirectory,
517
572
  timeout: input.timeout,
518
573
  env: { ...inherited.env, ...context.env },
@@ -524,11 +579,21 @@ export const BashTool = defineTool({
524
579
  success: true,
525
580
  output: formatShellOutput(stdout, stderr) || '(no output)',
526
581
  data: { exitCode: 0, ...(leaveSandbox ? { sandboxed: false, sandboxEscape: true } : {}) },
582
+ facts: commandFacts({
583
+ command: input.command,
584
+ exitCode: 0,
585
+ stdout,
586
+ stderr,
587
+ stdoutBytes,
588
+ stderrBytes,
589
+ }),
527
590
  }
528
591
  } catch (err) {
529
592
  const failure = err as NodeJS.ErrnoException & {
530
593
  stdout?: string
531
594
  stderr?: string
595
+ stdoutBytes?: number
596
+ stderrBytes?: number
532
597
  stdoutTruncated?: boolean
533
598
  stderrTruncated?: boolean
534
599
  code?: number | string
@@ -578,11 +643,54 @@ export const BashTool = defineTool({
578
643
  : exitCode !== undefined
579
644
  ? `Command exited with code ${exitCode}`
580
645
  : `Command failed: ${failure.message}`,
646
+ facts: commandFacts({
647
+ command: input.command,
648
+ ...(exitCode !== undefined ? { exitCode } : {}),
649
+ timedOut,
650
+ ...(failure.signal ? { signal: failure.signal } : {}),
651
+ stdout: failure.stdout ?? '',
652
+ stderr: failure.stderr ?? '',
653
+ ...(failure.stdoutBytes !== undefined ? { stdoutBytes: failure.stdoutBytes } : {}),
654
+ ...(failure.stderrBytes !== undefined ? { stderrBytes: failure.stderrBytes } : {}),
655
+ }),
581
656
  }
582
657
  }
583
658
  },
584
659
  })
585
660
 
661
+ /**
662
+ * What a finished command did, as typed fields for the person's view: the exit
663
+ * code, each stream on its own as a head-and-tail window, and whether the
664
+ * output was bytes rather than text. The model's text (labels, the withheld
665
+ * environment note) is not an input here and is never reproduced.
666
+ */
667
+ function commandFacts(input: {
668
+ command: string
669
+ exitCode?: number
670
+ timedOut?: boolean
671
+ signal?: string
672
+ stdout: string
673
+ stderr: string
674
+ stdoutBytes?: number
675
+ stderrBytes?: number
676
+ }): ToolFacts {
677
+ const outBinary = looksBinary(input.stdout)
678
+ const errBinary = looksBinary(input.stderr)
679
+ const outBytes = input.stdoutBytes ?? Buffer.byteLength(input.stdout, 'utf8')
680
+ const errBytes = input.stderrBytes ?? Buffer.byteLength(input.stderr, 'utf8')
681
+ const binaryBytes = (outBinary ? outBytes : 0) + (errBinary ? errBytes : 0)
682
+ return {
683
+ kind: 'command',
684
+ command: input.command,
685
+ ...(input.exitCode !== undefined ? { exitCode: input.exitCode } : {}),
686
+ ...(input.timedOut ? { timedOut: true } : {}),
687
+ ...(input.signal ? { signal: input.signal } : {}),
688
+ ...(input.stdout && !outBinary ? { stdout: windowText(input.stdout, outBytes) } : {}),
689
+ ...(input.stderr && !errBinary ? { stderr: windowText(input.stderr, errBytes) } : {}),
690
+ ...(outBinary || errBinary ? { binary: { bytes: binaryBytes } } : {}),
691
+ }
692
+ }
693
+
586
694
  /**
587
695
  * The two streams, labelled, with empty ones left out.
588
696
  *