@namzu/sdk 49.0.0 → 50.1.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 (742) hide show
  1. package/CHANGELOG.md +541 -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/provider/strict-schema.d.ts +28 -0
  222. package/dist/provider/strict-schema.d.ts.map +1 -1
  223. package/dist/provider/strict-schema.js +86 -0
  224. package/dist/provider/strict-schema.js.map +1 -1
  225. package/dist/public-runtime.d.ts +42 -14
  226. package/dist/public-runtime.d.ts.map +1 -1
  227. package/dist/public-runtime.js +36 -8
  228. package/dist/public-runtime.js.map +1 -1
  229. package/dist/public-tools.d.ts +8 -3
  230. package/dist/public-tools.d.ts.map +1 -1
  231. package/dist/public-tools.js +8 -3
  232. package/dist/public-tools.js.map +1 -1
  233. package/dist/public-types.d.ts +27 -7
  234. package/dist/public-types.d.ts.map +1 -1
  235. package/dist/registry/tool/presentation.d.ts +1 -0
  236. package/dist/registry/tool/presentation.d.ts.map +1 -1
  237. package/dist/registry/tool/presentation.js +9 -7
  238. package/dist/registry/tool/presentation.js.map +1 -1
  239. package/dist/runtime/harness-session/index.d.ts +5 -0
  240. package/dist/runtime/harness-session/index.d.ts.map +1 -0
  241. package/dist/runtime/harness-session/index.js +928 -0
  242. package/dist/runtime/harness-session/index.js.map +1 -0
  243. package/dist/runtime/harness-session/journal.d.ts +37 -0
  244. package/dist/runtime/harness-session/journal.d.ts.map +1 -0
  245. package/dist/runtime/harness-session/journal.js +177 -0
  246. package/dist/runtime/harness-session/journal.js.map +1 -0
  247. package/dist/runtime/harness-session/saved-view.d.ts +8 -0
  248. package/dist/runtime/harness-session/saved-view.d.ts.map +1 -0
  249. package/dist/runtime/harness-session/saved-view.js +112 -0
  250. package/dist/runtime/harness-session/saved-view.js.map +1 -0
  251. package/dist/runtime/jobs/awaited-jobs.d.ts +2 -1
  252. package/dist/runtime/jobs/awaited-jobs.d.ts.map +1 -1
  253. package/dist/runtime/jobs/awaited-jobs.js +2 -1
  254. package/dist/runtime/jobs/awaited-jobs.js.map +1 -1
  255. package/dist/runtime/jobs/registry.d.ts +56 -1
  256. package/dist/runtime/jobs/registry.d.ts.map +1 -1
  257. package/dist/runtime/jobs/registry.js +351 -34
  258. package/dist/runtime/jobs/registry.js.map +1 -1
  259. package/dist/runtime/query/abandon-turn.d.ts +12 -1
  260. package/dist/runtime/query/abandon-turn.d.ts.map +1 -1
  261. package/dist/runtime/query/abandon-turn.js +3 -1
  262. package/dist/runtime/query/abandon-turn.js.map +1 -1
  263. package/dist/runtime/query/checkpoint.d.ts +4 -0
  264. package/dist/runtime/query/checkpoint.d.ts.map +1 -1
  265. package/dist/runtime/query/checkpoint.js +10 -0
  266. package/dist/runtime/query/checkpoint.js.map +1 -1
  267. package/dist/runtime/query/durable-inbound.d.ts +5 -0
  268. package/dist/runtime/query/durable-inbound.d.ts.map +1 -0
  269. package/dist/runtime/query/durable-inbound.js +89 -0
  270. package/dist/runtime/query/durable-inbound.js.map +1 -0
  271. package/dist/runtime/query/events.d.ts +4 -0
  272. package/dist/runtime/query/events.d.ts.map +1 -1
  273. package/dist/runtime/query/events.js +22 -5
  274. package/dist/runtime/query/events.js.map +1 -1
  275. package/dist/runtime/query/executor/tool-call-admission.d.ts +5 -1
  276. package/dist/runtime/query/executor/tool-call-admission.d.ts.map +1 -1
  277. package/dist/runtime/query/executor/tool-call-admission.js +85 -13
  278. package/dist/runtime/query/executor/tool-call-admission.js.map +1 -1
  279. package/dist/runtime/query/executor.d.ts +41 -18
  280. package/dist/runtime/query/executor.d.ts.map +1 -1
  281. package/dist/runtime/query/executor.js +227 -114
  282. package/dist/runtime/query/executor.js.map +1 -1
  283. package/dist/runtime/query/index.d.ts +3 -0
  284. package/dist/runtime/query/index.d.ts.map +1 -1
  285. package/dist/runtime/query/index.js +21 -4
  286. package/dist/runtime/query/index.js.map +1 -1
  287. package/dist/runtime/query/iteration/index.d.ts +18 -6
  288. package/dist/runtime/query/iteration/index.d.ts.map +1 -1
  289. package/dist/runtime/query/iteration/index.js +144 -67
  290. package/dist/runtime/query/iteration/index.js.map +1 -1
  291. package/dist/runtime/query/iteration/outstanding-work.d.ts +9 -5
  292. package/dist/runtime/query/iteration/outstanding-work.d.ts.map +1 -1
  293. package/dist/runtime/query/iteration/outstanding-work.js +61 -6
  294. package/dist/runtime/query/iteration/outstanding-work.js.map +1 -1
  295. package/dist/runtime/query/iteration/phases/context.d.ts +4 -0
  296. package/dist/runtime/query/iteration/phases/context.d.ts.map +1 -1
  297. package/dist/runtime/query/iteration/phases/context.js.map +1 -1
  298. package/dist/runtime/query/iteration/phases/tool-review.d.ts.map +1 -1
  299. package/dist/runtime/query/iteration/phases/tool-review.js +99 -16
  300. package/dist/runtime/query/iteration/phases/tool-review.js.map +1 -1
  301. package/dist/runtime/query/observation-context.d.ts +2 -2
  302. package/dist/runtime/query/observation-context.d.ts.map +1 -1
  303. package/dist/runtime/query/observation-context.js +20 -13
  304. package/dist/runtime/query/observation-context.js.map +1 -1
  305. package/dist/runtime/query/prepare-turn.js +2 -2
  306. package/dist/runtime/query/prepare-turn.js.map +1 -1
  307. package/dist/runtime/query/prompt-cache.d.ts +1 -0
  308. package/dist/runtime/query/prompt-cache.d.ts.map +1 -1
  309. package/dist/runtime/query/prompt-cache.js +2 -0
  310. package/dist/runtime/query/prompt-cache.js.map +1 -1
  311. package/dist/runtime/query/prompt.d.ts +2 -0
  312. package/dist/runtime/query/prompt.d.ts.map +1 -1
  313. package/dist/runtime/query/prompt.js +23 -1
  314. package/dist/runtime/query/prompt.js.map +1 -1
  315. package/dist/runtime/query/repeat-call.d.ts +12 -3
  316. package/dist/runtime/query/repeat-call.d.ts.map +1 -1
  317. package/dist/runtime/query/repeat-call.js +33 -10
  318. package/dist/runtime/query/repeat-call.js.map +1 -1
  319. package/dist/runtime/query/resume-pending.d.ts +5 -6
  320. package/dist/runtime/query/resume-pending.d.ts.map +1 -1
  321. package/dist/runtime/query/resume-pending.js +30 -3
  322. package/dist/runtime/query/resume-pending.js.map +1 -1
  323. package/dist/runtime/query/resume-session.js +1 -1
  324. package/dist/runtime/query/resume-session.js.map +1 -1
  325. package/dist/runtime/query/review-policy.d.ts +8 -1
  326. package/dist/runtime/query/review-policy.d.ts.map +1 -1
  327. package/dist/runtime/query/review-policy.js +6 -0
  328. package/dist/runtime/query/review-policy.js.map +1 -1
  329. package/dist/runtime/query/saved-presentation.d.ts +13 -0
  330. package/dist/runtime/query/saved-presentation.d.ts.map +1 -0
  331. package/dist/runtime/query/saved-presentation.js +63 -0
  332. package/dist/runtime/query/saved-presentation.js.map +1 -0
  333. package/dist/runtime/query/steering.d.ts +6 -9
  334. package/dist/runtime/query/steering.d.ts.map +1 -1
  335. package/dist/runtime/query/steering.js.map +1 -1
  336. package/dist/runtime/query/tool-executions.d.ts +7 -3
  337. package/dist/runtime/query/tool-executions.d.ts.map +1 -1
  338. package/dist/runtime/query/tool-executions.js +89 -9
  339. package/dist/runtime/query/tool-executions.js.map +1 -1
  340. package/dist/runtime/query/tooling.d.ts +3 -1
  341. package/dist/runtime/query/tooling.d.ts.map +1 -1
  342. package/dist/runtime/query/tooling.js +3 -0
  343. package/dist/runtime/query/tooling.js.map +1 -1
  344. package/dist/scheduler/completion-inbox.d.ts +25 -1
  345. package/dist/scheduler/completion-inbox.d.ts.map +1 -1
  346. package/dist/scheduler/completion-inbox.js +102 -8
  347. package/dist/scheduler/completion-inbox.js.map +1 -1
  348. package/dist/scheduler/delegating.d.ts.map +1 -1
  349. package/dist/scheduler/delegating.js +5 -0
  350. package/dist/scheduler/delegating.js.map +1 -1
  351. package/dist/scheduler/local.d.ts.map +1 -1
  352. package/dist/scheduler/local.js +2 -0
  353. package/dist/scheduler/local.js.map +1 -1
  354. package/dist/session/summary/materialize.d.ts +10 -6
  355. package/dist/session/summary/materialize.d.ts.map +1 -1
  356. package/dist/session/summary/materialize.js +41 -8
  357. package/dist/session/summary/materialize.js.map +1 -1
  358. package/dist/store/budget/ledger.d.ts +9 -0
  359. package/dist/store/budget/ledger.d.ts.map +1 -1
  360. package/dist/store/budget/ledger.js +58 -6
  361. package/dist/store/budget/ledger.js.map +1 -1
  362. package/dist/store/evidence/index-page.d.ts +12 -12
  363. package/dist/store/evidence/source-text.d.ts +4 -4
  364. package/dist/store/session/disk.d.ts +9 -4
  365. package/dist/store/session/disk.d.ts.map +1 -1
  366. package/dist/store/session/disk.js +57 -11
  367. package/dist/store/session/disk.js.map +1 -1
  368. package/dist/store/session/memory.d.ts +5 -3
  369. package/dist/store/session/memory.d.ts.map +1 -1
  370. package/dist/store/session/memory.js +24 -7
  371. package/dist/store/session/memory.js.map +1 -1
  372. package/dist/store/session-log/core.d.ts +26 -6
  373. package/dist/store/session-log/core.d.ts.map +1 -1
  374. package/dist/store/session-log/core.js +61 -8
  375. package/dist/store/session-log/core.js.map +1 -1
  376. package/dist/store/session-log/disk.d.ts +2 -2
  377. package/dist/store/session-log/disk.d.ts.map +1 -1
  378. package/dist/store/session-log/disk.js +1 -0
  379. package/dist/store/session-log/disk.js.map +1 -1
  380. package/dist/store/session-log/fold.d.ts +7 -0
  381. package/dist/store/session-log/fold.d.ts.map +1 -1
  382. package/dist/store/session-log/fold.js +21 -0
  383. package/dist/store/session-log/fold.js.map +1 -1
  384. package/dist/store/session-log/index.d.ts +5 -3
  385. package/dist/store/session-log/index.d.ts.map +1 -1
  386. package/dist/store/session-log/index.js +3 -1
  387. package/dist/store/session-log/index.js.map +1 -1
  388. package/dist/store/session-log/memory.d.ts +1 -1
  389. package/dist/store/session-log/memory.d.ts.map +1 -1
  390. package/dist/store/session-log/memory.js +1 -0
  391. package/dist/store/session-log/memory.js.map +1 -1
  392. package/dist/store/session-log/spill.d.ts +10 -3
  393. package/dist/store/session-log/spill.d.ts.map +1 -1
  394. package/dist/store/session-log/spill.js +70 -5
  395. package/dist/store/session-log/spill.js.map +1 -1
  396. package/dist/store/session-log/structured-result.d.ts +21 -0
  397. package/dist/store/session-log/structured-result.d.ts.map +1 -0
  398. package/dist/store/session-log/structured-result.js +67 -0
  399. package/dist/store/session-log/structured-result.js.map +1 -0
  400. package/dist/store/task/disk.d.ts +11 -0
  401. package/dist/store/task/disk.d.ts.map +1 -1
  402. package/dist/store/task/disk.js +41 -2
  403. package/dist/store/task/disk.js.map +1 -1
  404. package/dist/store/task/memory.d.ts.map +1 -1
  405. package/dist/store/task/memory.js +15 -3
  406. package/dist/store/task/memory.js.map +1 -1
  407. package/dist/tools/admit-facts.d.ts +13 -0
  408. package/dist/tools/admit-facts.d.ts.map +1 -0
  409. package/dist/tools/admit-facts.js +142 -0
  410. package/dist/tools/admit-facts.js.map +1 -0
  411. package/dist/tools/builtins/bash.d.ts +4 -1
  412. package/dist/tools/builtins/bash.d.ts.map +1 -1
  413. package/dist/tools/builtins/bash.js +108 -22
  414. package/dist/tools/builtins/bash.js.map +1 -1
  415. package/dist/tools/builtins/browser.d.ts +10 -10
  416. package/dist/tools/builtins/computer-use.d.ts +90 -90
  417. package/dist/tools/builtins/edit.d.ts +17 -0
  418. package/dist/tools/builtins/edit.d.ts.map +1 -1
  419. package/dist/tools/builtins/edit.js +46 -1
  420. package/dist/tools/builtins/edit.js.map +1 -1
  421. package/dist/tools/builtins/file-write-result.d.ts.map +1 -1
  422. package/dist/tools/builtins/file-write-result.js +13 -0
  423. package/dist/tools/builtins/file-write-result.js.map +1 -1
  424. package/dist/tools/builtins/glob.d.ts.map +1 -1
  425. package/dist/tools/builtins/glob.js +12 -0
  426. package/dist/tools/builtins/glob.js.map +1 -1
  427. package/dist/tools/builtins/grep.d.ts.map +1 -1
  428. package/dist/tools/builtins/grep.js +14 -0
  429. package/dist/tools/builtins/grep.js.map +1 -1
  430. package/dist/tools/builtins/index.d.ts +2 -0
  431. package/dist/tools/builtins/index.d.ts.map +1 -1
  432. package/dist/tools/builtins/index.js +1 -0
  433. package/dist/tools/builtins/index.js.map +1 -1
  434. package/dist/tools/builtins/job.d.ts.map +1 -1
  435. package/dist/tools/builtins/job.js +4 -1
  436. package/dist/tools/builtins/job.js.map +1 -1
  437. package/dist/tools/builtins/lsp.d.ts +2 -2
  438. package/dist/tools/builtins/read-file.d.ts.map +1 -1
  439. package/dist/tools/builtins/read-file.js +49 -0
  440. package/dist/tools/builtins/read-file.js.map +1 -1
  441. package/dist/tools/builtins/view-image.d.ts +24 -0
  442. package/dist/tools/builtins/view-image.d.ts.map +1 -0
  443. package/dist/tools/builtins/view-image.js +385 -0
  444. package/dist/tools/builtins/view-image.js.map +1 -0
  445. package/dist/tools/builtins/wait-for-job-bounds.d.ts +2 -0
  446. package/dist/tools/builtins/wait-for-job-bounds.d.ts.map +1 -1
  447. package/dist/tools/builtins/wait-for-job-bounds.js +1 -0
  448. package/dist/tools/builtins/wait-for-job-bounds.js.map +1 -1
  449. package/dist/tools/builtins/wait-for-job.d.ts +2 -0
  450. package/dist/tools/builtins/wait-for-job.d.ts.map +1 -1
  451. package/dist/tools/builtins/wait-for-job.js +104 -6
  452. package/dist/tools/builtins/wait-for-job.js.map +1 -1
  453. package/dist/tools/builtins/write-file.d.ts.map +1 -1
  454. package/dist/tools/builtins/write-file.js +1 -0
  455. package/dist/tools/builtins/write-file.js.map +1 -1
  456. package/dist/tools/command-shell.d.ts +37 -2
  457. package/dist/tools/command-shell.d.ts.map +1 -1
  458. package/dist/tools/command-shell.js +100 -3
  459. package/dist/tools/command-shell.js.map +1 -1
  460. package/dist/tools/coordinator/agent.d.ts +9 -19
  461. package/dist/tools/coordinator/agent.d.ts.map +1 -1
  462. package/dist/tools/coordinator/agent.js.map +1 -1
  463. package/dist/tools/coordinator/index.d.ts.map +1 -1
  464. package/dist/tools/coordinator/index.js +127 -67
  465. package/dist/tools/coordinator/index.js.map +1 -1
  466. package/dist/tools/coordinator/wait-with-idle-bound.d.ts +2 -0
  467. package/dist/tools/coordinator/wait-with-idle-bound.d.ts.map +1 -1
  468. package/dist/tools/coordinator/wait-with-idle-bound.js +1 -1
  469. package/dist/tools/coordinator/wait-with-idle-bound.js.map +1 -1
  470. package/dist/tools/defineTool.d.ts.map +1 -1
  471. package/dist/tools/defineTool.js +4 -0
  472. package/dist/tools/defineTool.js.map +1 -1
  473. package/dist/tools/failure-facts.d.ts +8 -0
  474. package/dist/tools/failure-facts.d.ts.map +1 -0
  475. package/dist/tools/failure-facts.js +24 -0
  476. package/dist/tools/failure-facts.js.map +1 -0
  477. package/dist/tools/host-output.d.ts +24 -0
  478. package/dist/tools/host-output.d.ts.map +1 -0
  479. package/dist/tools/host-output.js +117 -0
  480. package/dist/tools/host-output.js.map +1 -0
  481. package/dist/tools/oem-code-pages.d.ts +8 -0
  482. package/dist/tools/oem-code-pages.d.ts.map +1 -0
  483. package/dist/tools/oem-code-pages.js +23 -0
  484. package/dist/tools/oem-code-pages.js.map +1 -0
  485. package/dist/tools/schedules/schedule-tool.d.ts.map +1 -1
  486. package/dist/tools/schedules/schedule-tool.js +35 -6
  487. package/dist/tools/schedules/schedule-tool.js.map +1 -1
  488. package/dist/tools/schedules/types.d.ts +23 -3
  489. package/dist/tools/schedules/types.d.ts.map +1 -1
  490. package/dist/tools/task/list.d.ts.map +1 -1
  491. package/dist/tools/task/list.js +14 -6
  492. package/dist/tools/task/list.js.map +1 -1
  493. package/dist/tools/task/present.d.ts.map +1 -1
  494. package/dist/tools/task/present.js +26 -6
  495. package/dist/tools/task/present.js.map +1 -1
  496. package/dist/tools/task/update.d.ts.map +1 -1
  497. package/dist/tools/task/update.js +12 -5
  498. package/dist/tools/task/update.js.map +1 -1
  499. package/dist/tools/text-window.d.ts +19 -0
  500. package/dist/tools/text-window.d.ts.map +1 -0
  501. package/dist/tools/text-window.js +83 -0
  502. package/dist/tools/text-window.js.map +1 -0
  503. package/dist/toolsets/manager.d.ts +11 -0
  504. package/dist/toolsets/manager.d.ts.map +1 -1
  505. package/dist/toolsets/manager.js +45 -1
  506. package/dist/toolsets/manager.js.map +1 -1
  507. package/dist/types/acp/index.d.ts +137 -1
  508. package/dist/types/acp/index.d.ts.map +1 -1
  509. package/dist/types/agent/base.d.ts +3 -0
  510. package/dist/types/agent/base.d.ts.map +1 -1
  511. package/dist/types/agent/manager.d.ts +8 -23
  512. package/dist/types/agent/manager.d.ts.map +1 -1
  513. package/dist/types/agent/scheduler.d.ts +10 -1
  514. package/dist/types/agent/scheduler.d.ts.map +1 -1
  515. package/dist/types/agent/task.d.ts +4 -0
  516. package/dist/types/agent/task.d.ts.map +1 -1
  517. package/dist/types/authorization/index.d.ts +30 -30
  518. package/dist/types/connector/mcp.d.ts +7 -0
  519. package/dist/types/connector/mcp.d.ts.map +1 -1
  520. package/dist/types/errors/catalog.d.ts.map +1 -1
  521. package/dist/types/errors/catalog.js +4 -2
  522. package/dist/types/errors/catalog.js.map +1 -1
  523. package/dist/types/harness/schema.d.ts +354 -0
  524. package/dist/types/harness/schema.d.ts.map +1 -0
  525. package/dist/types/harness/schema.js +203 -0
  526. package/dist/types/harness/schema.js.map +1 -0
  527. package/dist/types/harness/session.d.ts +278 -0
  528. package/dist/types/harness/session.d.ts.map +1 -0
  529. package/dist/types/harness/session.js +2 -0
  530. package/dist/types/harness/session.js.map +1 -0
  531. package/dist/types/hitl/index.d.ts +12 -0
  532. package/dist/types/hitl/index.d.ts.map +1 -1
  533. package/dist/types/hitl/index.js.map +1 -1
  534. package/dist/types/job/index.d.ts +47 -0
  535. package/dist/types/job/index.d.ts.map +1 -0
  536. package/dist/types/job/index.js +2 -0
  537. package/dist/types/job/index.js.map +1 -0
  538. package/dist/types/message/inbound-delivery.d.ts +44 -0
  539. package/dist/types/message/inbound-delivery.d.ts.map +1 -0
  540. package/dist/types/message/inbound-delivery.js +14 -0
  541. package/dist/types/message/inbound-delivery.js.map +1 -0
  542. package/dist/types/message/index.d.ts +4 -1
  543. package/dist/types/message/index.d.ts.map +1 -1
  544. package/dist/types/message/index.js +5 -1
  545. package/dist/types/message/index.js.map +1 -1
  546. package/dist/types/plugin/index.d.ts +6 -6
  547. package/dist/types/sandbox/index.d.ts +39 -2
  548. package/dist/types/sandbox/index.d.ts.map +1 -1
  549. package/dist/types/sandbox/index.js.map +1 -1
  550. package/dist/types/session/checkpoint.d.ts +24 -17
  551. package/dist/types/session/checkpoint.d.ts.map +1 -1
  552. package/dist/types/session/checkpoint.js +1 -0
  553. package/dist/types/session/checkpoint.js.map +1 -1
  554. package/dist/types/session/events.d.ts +23 -1
  555. package/dist/types/session/events.d.ts.map +1 -1
  556. package/dist/types/session/events.js.map +1 -1
  557. package/dist/types/session/records.d.ts +1514 -565
  558. package/dist/types/session/records.d.ts.map +1 -1
  559. package/dist/types/session/records.js +89 -1
  560. package/dist/types/session/records.js.map +1 -1
  561. package/dist/types/session/step.d.ts +2 -0
  562. package/dist/types/session/step.d.ts.map +1 -1
  563. package/dist/types/session/step.js.map +1 -1
  564. package/dist/types/session/store.d.ts +19 -10
  565. package/dist/types/session/store.d.ts.map +1 -1
  566. package/dist/types/session/tool-execution.d.ts +6 -0
  567. package/dist/types/session/tool-execution.d.ts.map +1 -1
  568. package/dist/types/structured-output/index.d.ts +12 -2
  569. package/dist/types/structured-output/index.d.ts.map +1 -1
  570. package/dist/types/summary/ref.d.ts +3 -1
  571. package/dist/types/summary/ref.d.ts.map +1 -1
  572. package/dist/types/tool/index.d.ts +32 -4
  573. package/dist/types/tool/index.d.ts.map +1 -1
  574. package/dist/types/tool/index.js.map +1 -1
  575. package/dist/types/tool/presentation.d.ts +106 -0
  576. package/dist/types/tool/presentation.d.ts.map +1 -1
  577. package/dist/utils/json-snapshot.d.ts +6 -2
  578. package/dist/utils/json-snapshot.d.ts.map +1 -1
  579. package/dist/utils/json-snapshot.js +19 -9
  580. package/dist/utils/json-snapshot.js.map +1 -1
  581. package/dist/utils/structured-result-json.d.ts +5 -0
  582. package/dist/utils/structured-result-json.d.ts.map +1 -0
  583. package/dist/utils/structured-result-json.js +10 -0
  584. package/dist/utils/structured-result-json.js.map +1 -0
  585. package/package.json +1 -1
  586. package/src/agents/QueryAgent.ts +1 -0
  587. package/src/agents/examples/SupervisorAgent.ts +1 -0
  588. package/src/agents/runAgent.ts +3 -0
  589. package/src/authorization/shell-lexer.ts +16 -1
  590. package/src/bridge/acp/permission.ts +17 -3
  591. package/src/bridge/acp/server.ts +271 -25
  592. package/src/bridge/acp/tasks.ts +23 -0
  593. package/src/bridge/acp/update.ts +167 -13
  594. package/src/connector/mcp/adapter.ts +16 -4
  595. package/src/connector/mcp/client.ts +6 -2
  596. package/src/constants/acp/index.ts +4 -0
  597. package/src/manager/agent/lifecycle.ts +230 -3
  598. package/src/manager/plan/lifecycle.ts +11 -9
  599. package/src/manager/session/attribution.ts +12 -2
  600. package/src/manager/session/streamed-message-identity.ts +21 -0
  601. package/src/manager/session/turn-recorder.ts +4 -3
  602. package/src/pals/activity/causality.ts +261 -0
  603. package/src/pals/activity/projection.ts +89 -0
  604. package/src/pals/activity/source.ts +240 -0
  605. package/src/pals/activity/subscription-policy.ts +230 -0
  606. package/src/pals/activity/subscription-schema.ts +27 -0
  607. package/src/pals/activity/subscription-store.ts +172 -0
  608. package/src/pals/activity/subscription-types.ts +48 -0
  609. package/src/pals/activity/subscriptions.ts +209 -0
  610. package/src/pals/activity/types.ts +108 -0
  611. package/src/pals/channels/ingress.ts +153 -0
  612. package/src/pals/channels/routes.ts +118 -0
  613. package/src/pals/channels/routing.ts +197 -0
  614. package/src/pals/channels/schema.ts +108 -0
  615. package/src/pals/channels/types.ts +156 -0
  616. package/src/pals/communication/broker.ts +131 -0
  617. package/src/pals/communication/dispatch.ts +66 -0
  618. package/src/pals/communication/inbound.ts +193 -0
  619. package/src/pals/communication/ingress-dispatch.ts +63 -0
  620. package/src/pals/communication/ingress-inbound.ts +269 -0
  621. package/src/pals/communication/ingress-schema.ts +526 -0
  622. package/src/pals/communication/ingress-types.ts +336 -0
  623. package/src/pals/communication/operator.ts +315 -0
  624. package/src/pals/communication/policy.ts +174 -0
  625. package/src/pals/communication/schema.ts +173 -0
  626. package/src/pals/communication/store.ts +577 -0
  627. package/src/pals/communication/tools.ts +139 -0
  628. package/src/pals/communication/types.ts +227 -0
  629. package/src/pals/communication/verify.ts +220 -0
  630. package/src/pals/lifecycle.ts +54 -0
  631. package/src/pals/prompt.ts +101 -0
  632. package/src/pals/reference-images.ts +322 -0
  633. package/src/pals/runtime.ts +670 -0
  634. package/src/pals/store.ts +369 -0
  635. package/src/pals/types.ts +157 -0
  636. package/src/peers/envelope.ts +1 -1
  637. package/src/plugin/shell-hook.ts +8 -2
  638. package/src/process/kill-tree.ts +10 -1
  639. package/src/provider/errors.ts +135 -2
  640. package/src/provider/strict-schema.ts +90 -0
  641. package/src/public-runtime.ts +118 -12
  642. package/src/public-tools.ts +13 -1
  643. package/src/public-types.ts +69 -7
  644. package/src/registry/tool/presentation.ts +9 -4
  645. package/src/runtime/harness-session/index.ts +1125 -0
  646. package/src/runtime/harness-session/journal.ts +209 -0
  647. package/src/runtime/harness-session/saved-view.ts +122 -0
  648. package/src/runtime/jobs/awaited-jobs.ts +2 -1
  649. package/src/runtime/jobs/registry.ts +397 -41
  650. package/src/runtime/query/abandon-turn.ts +18 -2
  651. package/src/runtime/query/checkpoint.ts +11 -0
  652. package/src/runtime/query/durable-inbound.ts +101 -0
  653. package/src/runtime/query/events.ts +22 -5
  654. package/src/runtime/query/executor/tool-call-admission.ts +125 -32
  655. package/src/runtime/query/executor.ts +316 -130
  656. package/src/runtime/query/index.ts +24 -4
  657. package/src/runtime/query/iteration/index.ts +218 -104
  658. package/src/runtime/query/iteration/outstanding-work.ts +55 -7
  659. package/src/runtime/query/iteration/phases/context.ts +4 -0
  660. package/src/runtime/query/iteration/phases/tool-review.ts +118 -21
  661. package/src/runtime/query/observation-context.ts +22 -16
  662. package/src/runtime/query/prepare-turn.ts +2 -2
  663. package/src/runtime/query/prompt-cache.ts +3 -0
  664. package/src/runtime/query/prompt.ts +32 -1
  665. package/src/runtime/query/repeat-call.ts +40 -10
  666. package/src/runtime/query/resume-pending.ts +60 -7
  667. package/src/runtime/query/resume-session.ts +1 -1
  668. package/src/runtime/query/review-policy.ts +23 -2
  669. package/src/runtime/query/saved-presentation.ts +70 -0
  670. package/src/runtime/query/steering.ts +6 -9
  671. package/src/runtime/query/tool-executions.ts +108 -9
  672. package/src/runtime/query/tooling.ts +6 -1
  673. package/src/scheduler/completion-inbox.ts +108 -7
  674. package/src/scheduler/delegating.ts +5 -0
  675. package/src/scheduler/local.ts +2 -0
  676. package/src/session/summary/materialize.ts +51 -9
  677. package/src/store/budget/ledger.ts +60 -5
  678. package/src/store/session/disk.ts +77 -10
  679. package/src/store/session/memory.ts +32 -7
  680. package/src/store/session-log/core.ts +118 -11
  681. package/src/store/session-log/disk.ts +9 -2
  682. package/src/store/session-log/fold.ts +22 -0
  683. package/src/store/session-log/index.ts +5 -0
  684. package/src/store/session-log/memory.ts +2 -1
  685. package/src/store/session-log/spill.ts +89 -6
  686. package/src/store/session-log/structured-result.ts +96 -0
  687. package/src/store/task/disk.ts +46 -2
  688. package/src/store/task/memory.ts +13 -3
  689. package/src/tools/admit-facts.ts +145 -0
  690. package/src/tools/builtins/bash.ts +132 -24
  691. package/src/tools/builtins/edit.ts +54 -1
  692. package/src/tools/builtins/file-write-result.ts +14 -0
  693. package/src/tools/builtins/glob.ts +12 -0
  694. package/src/tools/builtins/grep.ts +14 -0
  695. package/src/tools/builtins/index.ts +2 -0
  696. package/src/tools/builtins/job.ts +4 -1
  697. package/src/tools/builtins/read-file.ts +57 -0
  698. package/src/tools/builtins/view-image.ts +409 -0
  699. package/src/tools/builtins/wait-for-job-bounds.ts +3 -0
  700. package/src/tools/builtins/wait-for-job.ts +141 -32
  701. package/src/tools/builtins/write-file.ts +4 -2
  702. package/src/tools/command-shell.ts +132 -5
  703. package/src/tools/coordinator/agent.ts +9 -19
  704. package/src/tools/coordinator/index.ts +150 -75
  705. package/src/tools/coordinator/wait-with-idle-bound.ts +3 -1
  706. package/src/tools/defineTool.ts +4 -0
  707. package/src/tools/failure-facts.ts +24 -0
  708. package/src/tools/host-output.ts +136 -0
  709. package/src/tools/oem-code-pages.ts +22 -0
  710. package/src/tools/schedules/schedule-tool.ts +38 -5
  711. package/src/tools/schedules/types.ts +23 -3
  712. package/src/tools/task/list.ts +15 -7
  713. package/src/tools/task/present.ts +37 -7
  714. package/src/tools/task/update.ts +12 -5
  715. package/src/tools/text-window.ts +87 -0
  716. package/src/toolsets/manager.ts +58 -1
  717. package/src/types/acp/index.ts +150 -4
  718. package/src/types/agent/base.ts +3 -0
  719. package/src/types/agent/manager.ts +8 -23
  720. package/src/types/agent/scheduler.ts +10 -1
  721. package/src/types/agent/task.ts +4 -0
  722. package/src/types/connector/mcp.ts +7 -0
  723. package/src/types/errors/catalog.ts +4 -2
  724. package/src/types/harness/schema.ts +203 -0
  725. package/src/types/harness/session.ts +306 -0
  726. package/src/types/hitl/index.ts +17 -1
  727. package/src/types/job/index.ts +42 -0
  728. package/src/types/message/inbound-delivery.ts +63 -0
  729. package/src/types/message/index.ts +8 -1
  730. package/src/types/sandbox/index.ts +46 -0
  731. package/src/types/session/checkpoint.ts +4 -1
  732. package/src/types/session/events.ts +23 -1
  733. package/src/types/session/records.ts +114 -2
  734. package/src/types/session/step.ts +2 -0
  735. package/src/types/session/store.ts +23 -9
  736. package/src/types/session/tool-execution.ts +6 -0
  737. package/src/types/structured-output/index.ts +13 -2
  738. package/src/types/summary/ref.ts +3 -1
  739. package/src/types/tool/index.ts +39 -5
  740. package/src/types/tool/presentation.ts +121 -0
  741. package/src/utils/json-snapshot.ts +26 -9
  742. package/src/utils/structured-result-json.ts +10 -0
@@ -34,7 +34,8 @@
34
34
  * `NAMZU_BASH_SHELL=/bin/sh` restores the old shell exactly.
35
35
  */
36
36
 
37
- import { constants, accessSync } from 'node:fs'
37
+ import { type ChildProcess, type SpawnOptions, spawn as nodeSpawn } from 'node:child_process'
38
+ import { constants, accessSync, existsSync } from 'node:fs'
38
39
  import { delimiter, isAbsolute, join } from 'node:path'
39
40
 
40
41
  import type { ShellDialect } from '../types/tool/index.js'
@@ -67,12 +68,19 @@ export function findCommandShell(probe: CommandShellProbe): CommandShell {
67
68
  if (override !== undefined && override !== '') {
68
69
  // Read as bash only when it is bash; anything else gets the reading
69
70
  // that holds for every POSIX shell.
70
- const name = override.slice(override.lastIndexOf('/') + 1)
71
+ const name =
72
+ probe.platform === 'win32'
73
+ ? override
74
+ .split(/[\\/]/)
75
+ .at(-1)
76
+ ?.toLowerCase()
77
+ .replace(/\.exe$/, '')
78
+ : override.slice(override.lastIndexOf('/') + 1)
71
79
  return { path: override, dialect: name === 'bash' ? 'bash' : 'sh', source: 'override' }
72
80
  }
73
81
  // Windows keeps Node's platform shell. Looking `bash` up on its PATH can
74
82
  // find WSL's launcher, which runs the command in another system.
75
- if (probe.platform === 'win32') return { path: undefined, dialect: 'sh', source: 'platform' }
83
+ if (probe.platform === 'win32') return { path: undefined, dialect: 'cmd', source: 'platform' }
76
84
  for (const directory of (probe.env.PATH ?? '').split(delimiter)) {
77
85
  if (directory === '' || !directory.startsWith('/')) continue
78
86
  const candidate = join(directory, 'bash')
@@ -94,7 +102,7 @@ export function findCommandShell(probe: CommandShellProbe): CommandShell {
94
102
  export function findCommandShellForDialect(
95
103
  dialect: 'bash' | 'sh',
96
104
  probe: CommandShellProbe,
97
- ): CommandShell | undefined {
105
+ ): (CommandShell & { readonly dialect: 'bash' | 'sh' }) | undefined {
98
106
  if (probe.platform === 'win32') return undefined
99
107
  const override = probe.env.NAMZU_BASH_SHELL
100
108
  if (override) {
@@ -142,7 +150,9 @@ export function hostCommandShell(): CommandShell {
142
150
  }
143
151
 
144
152
  /** Re-check the requested executable each time a job is confirmed or fired. */
145
- export function installedCommandShellForDialect(dialect: 'bash' | 'sh'): CommandShell | undefined {
153
+ export function installedCommandShellForDialect(
154
+ dialect: 'bash' | 'sh',
155
+ ): (CommandShell & { readonly dialect: 'bash' | 'sh' }) | undefined {
146
156
  return findCommandShellForDialect(dialect, {
147
157
  env: process.env,
148
158
  platform: process.platform,
@@ -173,6 +183,123 @@ export function hostShellSpawn(
173
183
  return { file: shell.path, args: ['-c', command], env: withoutBashStartup(env) }
174
184
  }
175
185
 
186
+ /** Why a command could not be started, in the words a model or operator reads. */
187
+ export function describeSpawnFailure(error: unknown, cwd?: string): string {
188
+ // Node reports a missing working directory as ENOENT on the shell's own
189
+ // path ("spawn C:\Windows\system32\cmd.exe ENOENT"), which sends the reader
190
+ // looking for a missing shell. Say what is actually missing.
191
+ if (
192
+ cwd !== undefined &&
193
+ (error as NodeJS.ErrnoException | undefined)?.code === 'ENOENT' &&
194
+ !existsSync(cwd)
195
+ ) {
196
+ return `Could not start the command: the working directory does not exist: ${cwd}`
197
+ }
198
+ const detail = error instanceof Error ? error.message : String(error)
199
+ return `Could not start the command: ${detail}`
200
+ }
201
+
202
+ /** Environment variable that carries the command line into the inner cmd. */
203
+ const WINDOWS_COMMAND_VARIABLE = 'NAMZU_HOST_COMMAND'
204
+ const WINDOWS_SHELL_VARIABLE = 'NAMZU_HOST_COMSPEC'
205
+
206
+ /**
207
+ * The spawn for one command line under cmd on Windows: the outer cmd's file,
208
+ * its arguments and the environment that carries the command.
209
+ *
210
+ * A bare `cmd /d /s /c <command>` converts the command line to the console's
211
+ * OEM code page before it runs anything, so letters that page lacks arrive
212
+ * as their nearest ASCII look-alike (g-breve as `g`, s-cedilla as `s` on
213
+ * CP850) and are gone before the command writes a byte. `chcp` inside the
214
+ * same line is too late: the line is already converted. So the outer cmd
215
+ * only switches the console to UTF-8 and starts a second cmd, and the
216
+ * command travels in the environment, which is Unicode and never converted.
217
+ * The outer cmd reads it with delayed expansion (`!NAME!`), which happens
218
+ * after its line is parsed, so quotes, `&`, `|` and `>` in the command are
219
+ * inert there and reach the second cmd as the line it was given: quoting,
220
+ * `%` and redirection mean what they meant before, and its exit code is the
221
+ * command's. Neither cmd is looked up on PATH, so a `cmd.exe` in the
222
+ * working directory is never picked up.
223
+ */
224
+ function windowsCmdSpawn(
225
+ command: string,
226
+ env: NodeJS.ProcessEnv,
227
+ ): {
228
+ readonly file: string
229
+ readonly args: readonly string[]
230
+ readonly env: NodeJS.ProcessEnv
231
+ } {
232
+ const lookup = (name: string): string | undefined => {
233
+ const key = Object.keys(env).find((k) => k.toLowerCase() === name.toLowerCase())
234
+ return key === undefined ? undefined : env[key]
235
+ }
236
+ const comspec =
237
+ lookup('ComSpec') ??
238
+ `${lookup('SystemRoot') ?? process.env.SystemRoot ?? 'C:\\Windows'}\\System32\\cmd.exe`
239
+ return {
240
+ file: comspec,
241
+ // Passed verbatim: Node must not re-quote the line, whose outer quotes
242
+ // `/s` strips.
243
+ args: [
244
+ '/d',
245
+ '/v:on',
246
+ '/s',
247
+ '/c',
248
+ `"chcp 65001>nul & "!${WINDOWS_SHELL_VARIABLE}!" /d /s /c "!${WINDOWS_COMMAND_VARIABLE}!""`,
249
+ ],
250
+ env: { ...env, [WINDOWS_SHELL_VARIABLE]: comspec, [WINDOWS_COMMAND_VARIABLE]: command },
251
+ }
252
+ }
253
+
254
+ /**
255
+ * Start one command on the host, in the shell {@link hostCommandShell} chose.
256
+ *
257
+ * The ONE place that knows what Windows needs: with no shell path (cmd), Node
258
+ * itself must run the line (`cmd.exe /d /s /c`, see `windowsCmdSpawn`);
259
+ * everywhere else it is `<shell> -c <command>`. The foreground `bash` tool,
260
+ * the background job registry and plugin hooks all spawn through here, so
261
+ * they cannot diverge: the registry once spawned `/bin/sh` on Windows while
262
+ * the foreground tool did not, and every background job died at once with no
263
+ * message.
264
+ *
265
+ * - On Windows the line runs under UTF-8 (see `windowsCmdSpawn`).
266
+ * - `detached` (own process group, for `killTree`) is POSIX only; on Windows
267
+ * it opens a new console window instead.
268
+ * - `windowsHide` keeps a GUI host from flashing a console per command.
269
+ */
270
+ export function spawnHostShell(
271
+ command: string,
272
+ options: {
273
+ readonly cwd: string
274
+ readonly env: NodeJS.ProcessEnv
275
+ readonly stdio?: SpawnOptions['stdio']
276
+ /** Default: true off Windows. */
277
+ readonly detached?: boolean
278
+ readonly shell?: CommandShell
279
+ /** For tests: the platform the options are shaped for. */
280
+ readonly platform?: NodeJS.Platform
281
+ /** For tests: the spawn that runs it. */
282
+ readonly spawnImpl?: typeof nodeSpawn
283
+ },
284
+ ): ChildProcess {
285
+ const spawnFn = options.spawnImpl ?? nodeSpawn
286
+ const resolved = hostShellSpawn(command, options.env, options.shell)
287
+ const common: SpawnOptions = {
288
+ cwd: options.cwd,
289
+ env: resolved.env,
290
+ detached: options.detached ?? (options.platform ?? process.platform) !== 'win32',
291
+ windowsHide: true,
292
+ ...(options.stdio === undefined ? {} : { stdio: options.stdio }),
293
+ }
294
+ if (resolved.file !== undefined) return spawnFn(resolved.file, [...resolved.args], common)
295
+ const windows = windowsCmdSpawn(command, resolved.env)
296
+ return spawnFn(windows.file, [...windows.args], {
297
+ ...common,
298
+ env: windows.env,
299
+ windowsVerbatimArguments: true,
300
+ })
301
+ }
302
+
176
303
  export function withoutBashStartup<T extends Readonly<Record<string, string | undefined>>>(
177
304
  env: T,
178
305
  ): T {
@@ -21,26 +21,16 @@ import type { TaskLaunchedCallback } from './index.js'
21
21
  * subagent tool calls are isolated — only the summary surfaces to
22
22
  * the parent.
23
23
  *
24
- * **How this relates to `create_task`.** This paragraph used to say the two
25
- * were different shapes — that `create_task` / `continue_task` /
26
- * `cancel_task` were a non-blocking trio driven by a `<task-notification>`
27
- * callback, and that the blocking `Agent` tool should be preferred. None of
28
- * that is true any more. `create_task` blocks and returns the worker's output
29
- * as its own `tool_result`, exactly like this tool; `continue_task` and
30
- * `cancel_task` are still defined in `./index.ts` but are deliberately not
31
- * registered, because a blocking launch leaves every worker terminal by the
32
- * time a later turn learns its id. So a reader following the old advice was
33
- * choosing between two tools on a distinction that no longer existed.
24
+ * `create_task` also returns the worker result inline by default. When a
25
+ * CompletionInbox is supplied it can instead launch in the background;
26
+ * `wait_for_task`, `continue_task` and `cancel_task` let the supervisor join,
27
+ * steer or stop its own launched work. Linked planning tasks and approved
28
+ * plan steps settle from the worker's actual outcome on either launch path.
34
29
  *
35
- * What actually separates them is the surface, not the timing:
36
- *
37
- * - `create_task` arrives with the rest of the coordinator surface —
38
- * `agent_task_list`, and `approve_plan` / `ask_user_question` when their
39
- * dependencies are wired. That is the supervisor's toolkit.
40
- * - This builds one tool and nothing else, for an agent whose only delegation
41
- * need is "hand this to a specialist". `terminal: true` additionally lets a
42
- * pure router settle on the specialist's answer instead of spending a turn
43
- * at full parent context to paraphrase it.
30
+ * `create_task` arrives with the coordinator toolkit, including task listing
31
+ * and optional plan approval/question tools. This builds one delegation tool.
32
+ * `terminal: true` additionally lets a pure router settle on the specialist's
33
+ * answer instead of spending a turn restating it.
44
34
  *
45
35
  * Neither is legacy. Pick by how much of the coordinator surface you want.
46
36
  */
@@ -3,7 +3,8 @@ import type { PlanManager } from '../../manager/plan/lifecycle.js'
3
3
  import type { PendingAnswers, QuestionParkRecorder } from '../../runtime/query/question-park.js'
4
4
  import type { CompletionInbox } from '../../scheduler/completion-inbox.js'
5
5
  import type { AgentRuntimeContext } from '../../types/agent/base.js'
6
- import type { TaskScheduler } from '../../types/agent/scheduler.js'
6
+ import type { TaskHandle, TaskScheduler } from '../../types/agent/scheduler.js'
7
+ import { isTerminalAgentTaskState } from '../../types/agent/task.js'
7
8
  import type { ResumeHandler } from '../../types/hitl/index.js'
8
9
  import type { SessionId, TaskId, TurnId } from '../../types/ids/index.js'
9
10
  import type { TaskStore } from '../../types/task/index.js'
@@ -402,6 +403,29 @@ function delegatedAnswer(
402
403
  return result?.result
403
404
  }
404
405
 
406
+ /** Keep an empty answer from hiding the worker's error on any result path. */
407
+ function delegatedResultText(completed: Pick<TaskHandle, 'state' | 'result'>): {
408
+ resultText: string
409
+ outputText: string
410
+ } {
411
+ const success = taskSucceeded(completed)
412
+ const answer = delegatedAnswer(completed.result)
413
+ const lastError = completed.result?.lastError
414
+ const outcomeText = `Task finished with outcome: ${failureLabel(completed)}`
415
+ const resultText =
416
+ (answer?.trim() ? answer : lastError) ||
417
+ (success ? `Task finished with state: ${completed.state}` : outcomeText)
418
+ const outputText =
419
+ success || resultText === outcomeText
420
+ ? resultText
421
+ : [
422
+ outcomeText,
423
+ ...(lastError && lastError !== resultText ? [`Error: ${lastError}`] : []),
424
+ resultText,
425
+ ].join('\n')
426
+ return { resultText, outputText }
427
+ }
428
+
405
429
  export function buildCoordinatorTools(opts: CoordinatorToolsOptions): ToolDefinition[] {
406
430
  const {
407
431
  gateway,
@@ -451,6 +475,7 @@ export function buildCoordinatorTools(opts: CoordinatorToolsOptions): ToolDefini
451
475
  * here. That is the same rule, not an exception to it.
452
476
  */
453
477
  const launchedHere = new Set<TaskId>()
478
+ const trackedCompletions = new Map<TaskId, Promise<TaskHandle>>()
454
479
  void opts.onTaskLaunched
455
480
 
456
481
  const agentIdEnum = delegateSchema(agentIds)
@@ -573,10 +598,12 @@ export function buildCoordinatorTools(opts: CoordinatorToolsOptions): ToolDefini
573
598
  // could report `failed` or stay `executing` forever but never
574
599
  // `completed`.
575
600
  const planStepId = plan_step_id
576
- const planId = planStepId ? getPlanManager?.()?.active?.id : undefined
601
+ const planManager = planStepId ? getPlanManager?.() : undefined
602
+ const planId = planManager?.active?.id
577
603
  const reportStep = (status: 'running' | 'completed' | 'failed', error?: string): void => {
578
- if (!planStepId) return
579
- getPlanManager?.()?.updateStepStatus(planStepId, status, error)
604
+ // A replacement plan may reuse step ids; it is not this worker's plan.
605
+ if (!planStepId || !planId || planManager?.active?.id !== planId) return
606
+ planManager.updateStepStatus(planStepId, status, error)
580
607
  }
581
608
  reportStep('running')
582
609
 
@@ -599,49 +626,6 @@ export function buildCoordinatorTools(opts: CoordinatorToolsOptions): ToolDefini
599
626
  }
600
627
  }
601
628
 
602
- const handle = await gateway.createTask({
603
- agentId: agent_id,
604
- prompt,
605
- workingDirectory: cwd,
606
- runtimeContext: opts.runtimeContext,
607
- ...(planStepId ? { planStepId } : {}),
608
- ...(planId ? { planId } : {}),
609
- // Hang the child session off THIS tool's span, so the delegation
610
- // shows up inside the turn that asked for it.
611
- ...(_context.parentSpan ? { parentSpan: _context.parentSpan } : {}),
612
- // Same as the `Agent` tool: a delegate inherits the environment
613
- // its parent was given, or it runs against different services
614
- // than the turn that asked for the work — and the turn's screens,
615
- // for the same reason: the child's executor installs the shipped
616
- // default unless the spawn says otherwise, so a parent that
617
- // turned them off had that decision revert behind every
618
- // delegation. One merged `configOverrides`, because a second
619
- // spread of the key would replace this one.
620
- ...(Object.keys(_context.env ?? {}).length > 0 || _context.toolResultGuardrails
621
- ? {
622
- configOverrides: {
623
- ...(_context.env && Object.keys(_context.env).length > 0
624
- ? { env: _context.env }
625
- : {}),
626
- ...(_context.toolResultGuardrails
627
- ? { toolResultGuardrails: _context.toolResultGuardrails }
628
- : {}),
629
- },
630
- }
631
- : {}),
632
- })
633
-
634
- // Whose task this is. The inbox ignores completions for anything it
635
- // was not told about, because `onTaskCompleted` is a broadcast and a
636
- // gateway shared between two supervisors would otherwise hand each
637
- // of them the other's worker output. Said on BOTH paths: the
638
- // blocking one needs it too, because the case the inbox exists for
639
- // is exactly the blocking launch whose wait was abandoned.
640
- completionInbox?.launched(handle.taskId)
641
-
642
- // ...and whose it is for the READ side too. See `launchedHere`.
643
- launchedHere.add(handle.taskId)
644
-
645
629
  // A background launch asked for with nowhere to deliver it is
646
630
  // REFUSED, not quietly turned into a blocking one.
647
631
  //
@@ -677,6 +661,111 @@ export function buildCoordinatorTools(opts: CoordinatorToolsOptions): ToolDefini
677
661
  }
678
662
  }
679
663
 
664
+ let handle: TaskHandle
665
+ try {
666
+ handle = await gateway.createTask({
667
+ agentId: agent_id,
668
+ prompt,
669
+ workingDirectory: cwd,
670
+ runtimeContext: opts.runtimeContext,
671
+ ...(planStepId ? { planStepId } : {}),
672
+ ...(planId ? { planId } : {}),
673
+ // Hang the child session off THIS tool's span, so the delegation
674
+ // shows up inside the turn that asked for it.
675
+ ...(_context.parentSpan ? { parentSpan: _context.parentSpan } : {}),
676
+ // Same as the `Agent` tool: a delegate inherits the environment
677
+ // its parent was given, or it runs against different services
678
+ // than the turn that asked for the work — and the turn's screens,
679
+ // for the same reason: the child's executor installs the shipped
680
+ // default unless the spawn says otherwise, so a parent that
681
+ // turned them off had that decision revert behind every
682
+ // delegation. One merged `configOverrides`, because a second
683
+ // spread of the key would replace this one.
684
+ ...(Object.keys(_context.env ?? {}).length > 0 || _context.toolResultGuardrails
685
+ ? {
686
+ configOverrides: {
687
+ ...(_context.env && Object.keys(_context.env).length > 0
688
+ ? { env: _context.env }
689
+ : {}),
690
+ ...(_context.toolResultGuardrails
691
+ ? { toolResultGuardrails: _context.toolResultGuardrails }
692
+ : {}),
693
+ },
694
+ }
695
+ : {}),
696
+ })
697
+ } catch (launchError) {
698
+ // No handle means admission failed from this caller's perspective.
699
+ // A host scheduler may have dispatched before losing its response;
700
+ // neither a missing worker nor a safe retry is established here.
701
+ const failure = `Delegation admission failed: ${toErrorMessage(launchError)}. No task handle was returned; the worker dispatch outcome is not established.`
702
+ reportStep('failed', failure)
703
+ if (resolvedPlanTaskId && taskStore) {
704
+ try {
705
+ const updated = await taskStore.update(asTaskId(resolvedPlanTaskId), {
706
+ status: 'failed',
707
+ description: failure,
708
+ })
709
+ if (!updated)
710
+ throw new Error(
711
+ `Planning task ${resolvedPlanTaskId} disappeared during failed admission`,
712
+ )
713
+ } catch (trackingError) {
714
+ throw new AggregateError(
715
+ [launchError, trackingError],
716
+ `${failure} Planning settlement failed: ${toErrorMessage(trackingError)}`,
717
+ { cause: launchError },
718
+ )
719
+ }
720
+ }
721
+ throw launchError
722
+ }
723
+
724
+ // Whose task this is. The inbox ignores completions for anything it
725
+ // was not told about, because `onTaskCompleted` is a broadcast and a
726
+ // gateway shared between two supervisors would otherwise hand each
727
+ // of them the other's worker output. Said on BOTH paths: the
728
+ // blocking one needs it too, because the case the inbox exists for
729
+ // is exactly the blocking launch whose wait was abandoned.
730
+ completionInbox?.launched(handle.taskId)
731
+
732
+ // ...and whose it is for the READ side too. See `launchedHere`.
733
+ launchedHere.add(handle.taskId)
734
+
735
+ // Own one completion for both delivery paths. Neither a background
736
+ // return nor an abandoned bounded wait discards these tracking writes.
737
+ if ((resolvedPlanTaskId && taskStore) || (planStepId && planId)) {
738
+ // A fast worker may already be terminal and forgotten by the gateway.
739
+ // The returned handle is the exact outcome; do not fetch it again.
740
+ const workerCompletion = isTerminalAgentTaskState(handle.state)
741
+ ? Promise.resolve(handle)
742
+ : gateway.waitForTask(handle.taskId)
743
+ const completion = workerCompletion.then(async (completed) => {
744
+ const success = taskSucceeded(completed)
745
+ const { outputText } = delegatedResultText(completed)
746
+ if (resolvedPlanTaskId && taskStore) {
747
+ const updated = await taskStore.update(asTaskId(resolvedPlanTaskId), {
748
+ status: success ? 'completed' : 'failed',
749
+ description: success ? undefined : `Failed: ${outputText.substring(0, 200)}`,
750
+ })
751
+ if (!updated)
752
+ throw new Error(
753
+ `Planning task ${resolvedPlanTaskId} disappeared before worker settlement`,
754
+ )
755
+ }
756
+ reportStep(
757
+ success ? 'completed' : 'failed',
758
+ success ? undefined : outputText.slice(0, 200),
759
+ )
760
+ return completed
761
+ })
762
+ trackedCompletions.set(handle.taskId, completion)
763
+ completionInbox?.deferDelivery(
764
+ handle.taskId,
765
+ completion.then(() => {}),
766
+ )
767
+ }
768
+
680
769
  if (background) {
681
770
  // Tell the inbox to hold the turn open for this. Without it the
682
771
  // supervisor could launch a worker, answer, and settle the turn
@@ -716,6 +805,7 @@ export function buildCoordinatorTools(opts: CoordinatorToolsOptions): ToolDefini
716
805
  const outcome = await waitForTaskWithBounds(gateway, handle.taskId, {
717
806
  wallMs: DELEGATION_TIMEOUT_MS,
718
807
  idleMs: DELEGATION_IDLE_MS,
808
+ completion: trackedCompletions.get(handle.taskId),
719
809
  })
720
810
  if (outcome.kind === 'timeout') {
721
811
  return {
@@ -752,27 +842,7 @@ export function buildCoordinatorTools(opts: CoordinatorToolsOptions): ToolDefini
752
842
  // `isError: false`, while writing the plan task closed as though
753
843
  // the work had been done.
754
844
  const success = taskSucceeded(completed)
755
- const resultText =
756
- delegatedAnswer(completed.result) ??
757
- completed.result?.lastError ??
758
- `Task finished with state: ${failureLabel(completed)}`
759
-
760
- if (resolvedPlanTaskId && taskStore) {
761
- // The status carries the outcome now, rather than `completed`
762
- // with the failure written into prose. A reader scanning
763
- // statuses saw work that had been done; only a reader of every
764
- // description saw otherwise — and a dependent unit had no way
765
- // to tell at all.
766
- await taskStore.update(asTaskId(resolvedPlanTaskId), {
767
- status: success ? 'completed' : 'failed',
768
- description: success ? undefined : `Failed: ${resultText.substring(0, 200)}`,
769
- })
770
- }
771
-
772
- // The step reports the same outcome, from the same two authorities.
773
- // This is the only point in a delegated launch where the answer is
774
- // actually known.
775
- reportStep(success ? 'completed' : 'failed', success ? undefined : resultText.slice(0, 200))
845
+ const { resultText, outputText } = delegatedResultText(completed)
776
846
 
777
847
  return {
778
848
  success,
@@ -797,7 +867,7 @@ export function buildCoordinatorTools(opts: CoordinatorToolsOptions): ToolDefini
797
867
  attributes: { agent: agent_id, task: handle.taskId },
798
868
  provenance: `This is the output of the delegated agent "${agent_id}", not this agent's own work.`,
799
869
  },
800
- resultText,
870
+ outputText,
801
871
  ),
802
872
  data: {
803
873
  task_id: handle.taskId,
@@ -870,6 +940,7 @@ export function buildCoordinatorTools(opts: CoordinatorToolsOptions): ToolDefini
870
940
  const outcome = await waitForTaskWithBounds(gateway, taskId, {
871
941
  wallMs: DELEGATION_TIMEOUT_MS,
872
942
  idleMs: DELEGATION_IDLE_MS,
943
+ completion: trackedCompletions.get(taskId),
873
944
  })
874
945
  if (outcome.kind === 'timeout') {
875
946
  return {
@@ -888,11 +959,11 @@ export function buildCoordinatorTools(opts: CoordinatorToolsOptions): ToolDefini
888
959
  }
889
960
  completionInbox?.claim(taskId)
890
961
 
891
- const success = completed.state === 'completed'
892
- const resultText =
893
- delegatedAnswer(completed.result) ??
894
- completed.result?.lastError ??
895
- `Task finished with state: ${completed.state}`
962
+ // Finishing the invocation does not prove the worker succeeded. Use
963
+ // the same two-authority check as the call that launched this task.
964
+ const success = taskSucceeded(completed)
965
+ const lastError = completed.result?.lastError
966
+ const { resultText, outputText } = delegatedResultText(completed)
896
967
  return {
897
968
  success,
898
969
  output: wrapUntrusted(
@@ -901,12 +972,16 @@ export function buildCoordinatorTools(opts: CoordinatorToolsOptions): ToolDefini
901
972
  attributes: { agent: completed.agentId, task: completed.taskId },
902
973
  provenance: `This is the output of the delegated agent "${completed.agentId}", not this agent's own work.`,
903
974
  },
904
- resultText,
975
+ outputText,
905
976
  ),
906
977
  data: {
907
978
  task_id,
908
979
  agent_id: completed.agentId,
909
980
  state: completed.state,
981
+ ...(completed.result?.status === undefined
982
+ ? {}
983
+ : { turn_status: completed.result.status }),
984
+ ...(lastError === undefined || lastError === null ? {} : { last_error: lastError }),
910
985
  result: resultText,
911
986
  },
912
987
  }
@@ -47,6 +47,8 @@ export interface WaitBounds {
47
47
  * Omit to bound by the turn clock alone.
48
48
  */
49
49
  readonly idleMs?: number
50
+ /** Reuse the launch's completion, including its tracking settlement. */
51
+ readonly completion?: Promise<TaskHandle>
50
52
  }
51
53
 
52
54
  /**
@@ -77,7 +79,7 @@ export async function waitForTaskWithBounds(
77
79
  const idleBoundArmed = detach !== undefined && bounds.idleMs !== undefined
78
80
 
79
81
  try {
80
- const completion = gateway.waitForTask(taskId).then(
82
+ const completion = (bounds.completion ?? gateway.waitForTask(taskId)).then(
81
83
  (handle): WaitOutcome => ({ kind: 'completed', handle }),
82
84
  // A gateway that rejects has answered the question; let it through
83
85
  // rather than reporting a timeout that did not happen.
@@ -7,6 +7,7 @@ import type {
7
7
  } from '../types/tool/index.js'
8
8
  import type { ToolPresentation } from '../types/tool/presentation.js'
9
9
  import { toErrorMessage } from '../utils/error.js'
10
+ import { failureFactsFromError } from './failure-facts.js'
10
11
 
11
12
  export interface DefineToolOptions<S extends z.ZodType> {
12
13
  name: string
@@ -183,10 +184,13 @@ export function defineTool<S extends z.ZodType>(
183
184
  return await options.execute(input, context)
184
185
  } catch (err) {
185
186
  const message = toErrorMessage(err)
187
+ const facts = failureFactsFromError(err)
186
188
  return {
187
189
  success: false,
188
190
  output: '',
189
191
  error: `${options.name} failed: ${message}`,
192
+ // The kind of failure, from the error's own code, for the person's view.
193
+ ...(facts ? { facts } : {}),
190
194
  }
191
195
  }
192
196
  },
@@ -0,0 +1,24 @@
1
+ import type { ToolFacts } from '../types/tool/presentation.js'
2
+
3
+ /**
4
+ * The kind of failure a thrown filesystem error is, as typed facts for the
5
+ * person's view. Read from the error's `code` and `path`, which Node sets
6
+ * structurally, and never from its message.
7
+ */
8
+ export function failureFactsFromError(err: unknown): ToolFacts | undefined {
9
+ if (!err || typeof err !== 'object') return undefined
10
+ const { code, path } = err as { code?: unknown; path?: unknown }
11
+ const subject = typeof path === 'string' ? path : undefined
12
+ const reason =
13
+ code === 'ENOENT'
14
+ ? 'not_found'
15
+ : code === 'EACCES' || code === 'EPERM'
16
+ ? 'permission_denied'
17
+ : code === 'EISDIR' || code === 'ENOTDIR'
18
+ ? 'not_a_file'
19
+ : code === 'EEXIST'
20
+ ? 'already_exists'
21
+ : undefined
22
+ if (!reason) return undefined
23
+ return { kind: 'failure', reason, ...(subject ? { subject } : {}) }
24
+ }