@namzu/sdk 0.6.0 → 1.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 (429) hide show
  1. package/CHANGELOG.md +529 -0
  2. package/dist/advisory/executor.d.ts.map +1 -1
  3. package/dist/advisory/executor.js +9 -2
  4. package/dist/advisory/executor.js.map +1 -1
  5. package/dist/advisory/executor.test.d.ts +2 -1
  6. package/dist/advisory/executor.test.d.ts.map +1 -1
  7. package/dist/advisory/executor.test.js +7 -4
  8. package/dist/advisory/executor.test.js.map +1 -1
  9. package/dist/agents/ReactiveAgent.d.ts.map +1 -1
  10. package/dist/agents/ReactiveAgent.js +7 -0
  11. package/dist/agents/ReactiveAgent.js.map +1 -1
  12. package/dist/agents/SupervisorAgent.d.ts +22 -1
  13. package/dist/agents/SupervisorAgent.d.ts.map +1 -1
  14. package/dist/agents/SupervisorAgent.js +54 -14
  15. package/dist/agents/SupervisorAgent.js.map +1 -1
  16. package/dist/agents/__tests__/supervisor-ledger.test.d.ts +2 -0
  17. package/dist/agents/__tests__/supervisor-ledger.test.d.ts.map +1 -0
  18. package/dist/agents/__tests__/supervisor-ledger.test.js +131 -0
  19. package/dist/agents/__tests__/supervisor-ledger.test.js.map +1 -0
  20. package/dist/bridge/sse/mapper.test.js +2 -2
  21. package/dist/config/runtime.d.ts +24 -0
  22. package/dist/config/runtime.d.ts.map +1 -1
  23. package/dist/config/runtime.js +9 -0
  24. package/dist/config/runtime.js.map +1 -1
  25. package/dist/connector/builtins/webhook.test.js +17 -0
  26. package/dist/connector/builtins/webhook.test.js.map +1 -1
  27. package/dist/connector/index.d.ts +1 -0
  28. package/dist/connector/index.d.ts.map +1 -1
  29. package/dist/connector/index.js +1 -0
  30. package/dist/connector/index.js.map +1 -1
  31. package/dist/connector/mcp/client.d.ts.map +1 -1
  32. package/dist/connector/mcp/client.js +4 -0
  33. package/dist/connector/mcp/client.js.map +1 -1
  34. package/dist/connector/mcp/index.d.ts +1 -0
  35. package/dist/connector/mcp/index.d.ts.map +1 -1
  36. package/dist/connector/mcp/index.js +1 -0
  37. package/dist/connector/mcp/index.js.map +1 -1
  38. package/dist/connector/mcp/streamable-http.d.ts +22 -0
  39. package/dist/connector/mcp/streamable-http.d.ts.map +1 -0
  40. package/dist/connector/mcp/streamable-http.js +128 -0
  41. package/dist/connector/mcp/streamable-http.js.map +1 -0
  42. package/dist/connector/mcp/streamable-http.test.d.ts +2 -0
  43. package/dist/connector/mcp/streamable-http.test.d.ts.map +1 -0
  44. package/dist/connector/mcp/streamable-http.test.js +132 -0
  45. package/dist/connector/mcp/streamable-http.test.js.map +1 -0
  46. package/dist/constants/compaction/index.d.ts.map +1 -1
  47. package/dist/constants/compaction/index.js +8 -3
  48. package/dist/constants/compaction/index.js.map +1 -1
  49. package/dist/constants/sandbox/index.d.ts +21 -0
  50. package/dist/constants/sandbox/index.d.ts.map +1 -1
  51. package/dist/constants/sandbox/index.js +30 -0
  52. package/dist/constants/sandbox/index.js.map +1 -1
  53. package/dist/constants/tools/index.d.ts.map +1 -1
  54. package/dist/constants/tools/index.js +33 -2
  55. package/dist/constants/tools/index.js.map +1 -1
  56. package/dist/manager/run/persistence.d.ts.map +1 -1
  57. package/dist/manager/run/persistence.js +35 -5
  58. package/dist/manager/run/persistence.js.map +1 -1
  59. package/dist/persona/assembler.d.ts +1 -0
  60. package/dist/persona/assembler.d.ts.map +1 -1
  61. package/dist/persona/assembler.js +37 -6
  62. package/dist/persona/assembler.js.map +1 -1
  63. package/dist/provider/collect.d.ts.map +1 -1
  64. package/dist/provider/collect.js +4 -1
  65. package/dist/provider/collect.js.map +1 -1
  66. package/dist/provider/collect.test.js +2 -2
  67. package/dist/public-runtime.d.ts +6 -5
  68. package/dist/public-runtime.d.ts.map +1 -1
  69. package/dist/public-runtime.js +6 -5
  70. package/dist/public-runtime.js.map +1 -1
  71. package/dist/public-tools.d.ts +2 -0
  72. package/dist/public-tools.d.ts.map +1 -1
  73. package/dist/public-tools.js +2 -0
  74. package/dist/public-tools.js.map +1 -1
  75. package/dist/public-types.d.ts +3 -0
  76. package/dist/public-types.d.ts.map +1 -1
  77. package/dist/registry/index.d.ts +2 -0
  78. package/dist/registry/index.d.ts.map +1 -1
  79. package/dist/registry/index.js +1 -0
  80. package/dist/registry/index.js.map +1 -1
  81. package/dist/registry/tool/execute.d.ts +27 -0
  82. package/dist/registry/tool/execute.d.ts.map +1 -1
  83. package/dist/registry/tool/execute.js +192 -7
  84. package/dist/registry/tool/execute.js.map +1 -1
  85. package/dist/registry/tool/execute.test.d.ts +9 -4
  86. package/dist/registry/tool/execute.test.d.ts.map +1 -1
  87. package/dist/registry/tool/execute.test.js +178 -7
  88. package/dist/registry/tool/execute.test.js.map +1 -1
  89. package/dist/registry/toolset/catalog.d.ts +42 -0
  90. package/dist/registry/toolset/catalog.d.ts.map +1 -0
  91. package/dist/registry/toolset/catalog.js +217 -0
  92. package/dist/registry/toolset/catalog.js.map +1 -0
  93. package/dist/registry/toolset/catalog.test.d.ts +2 -0
  94. package/dist/registry/toolset/catalog.test.d.ts.map +1 -0
  95. package/dist/registry/toolset/catalog.test.js +147 -0
  96. package/dist/registry/toolset/catalog.test.js.map +1 -0
  97. package/dist/runtime/query/__tests__/deferred-tools.test.d.ts +2 -0
  98. package/dist/runtime/query/__tests__/deferred-tools.test.d.ts.map +1 -0
  99. package/dist/runtime/query/__tests__/deferred-tools.test.js +185 -0
  100. package/dist/runtime/query/__tests__/deferred-tools.test.js.map +1 -0
  101. package/dist/runtime/query/__tests__/executor-concurrency.test.d.ts +2 -0
  102. package/dist/runtime/query/__tests__/executor-concurrency.test.d.ts.map +1 -0
  103. package/dist/runtime/query/__tests__/executor-concurrency.test.js +98 -0
  104. package/dist/runtime/query/__tests__/executor-concurrency.test.js.map +1 -0
  105. package/dist/runtime/query/__tests__/executor-plugin-hooks.test.js +38 -3
  106. package/dist/runtime/query/__tests__/executor-plugin-hooks.test.js.map +1 -1
  107. package/dist/runtime/query/__tests__/long-document-flow.test.d.ts +2 -0
  108. package/dist/runtime/query/__tests__/long-document-flow.test.d.ts.map +1 -0
  109. package/dist/runtime/query/__tests__/long-document-flow.test.js +154 -0
  110. package/dist/runtime/query/__tests__/long-document-flow.test.js.map +1 -0
  111. package/dist/runtime/query/__tests__/prompt.test.js +51 -2
  112. package/dist/runtime/query/__tests__/prompt.test.js.map +1 -1
  113. package/dist/runtime/query/__tests__/stream-recovery.test.d.ts +2 -0
  114. package/dist/runtime/query/__tests__/stream-recovery.test.d.ts.map +1 -0
  115. package/dist/runtime/query/__tests__/stream-recovery.test.js +126 -0
  116. package/dist/runtime/query/__tests__/stream-recovery.test.js.map +1 -0
  117. package/dist/runtime/query/continuation.d.ts +16 -0
  118. package/dist/runtime/query/continuation.d.ts.map +1 -0
  119. package/dist/runtime/query/continuation.js +16 -0
  120. package/dist/runtime/query/continuation.js.map +1 -0
  121. package/dist/runtime/query/executor.d.ts +3 -0
  122. package/dist/runtime/query/executor.d.ts.map +1 -1
  123. package/dist/runtime/query/executor.js +71 -3
  124. package/dist/runtime/query/executor.js.map +1 -1
  125. package/dist/runtime/query/index.d.ts +9 -0
  126. package/dist/runtime/query/index.d.ts.map +1 -1
  127. package/dist/runtime/query/index.js +42 -5
  128. package/dist/runtime/query/index.js.map +1 -1
  129. package/dist/runtime/query/iteration/index.d.ts +24 -0
  130. package/dist/runtime/query/iteration/index.d.ts.map +1 -1
  131. package/dist/runtime/query/iteration/index.js +326 -66
  132. package/dist/runtime/query/iteration/index.js.map +1 -1
  133. package/dist/runtime/query/iteration/phases/checkpoint.d.ts.map +1 -1
  134. package/dist/runtime/query/iteration/phases/checkpoint.js +2 -2
  135. package/dist/runtime/query/iteration/phases/checkpoint.js.map +1 -1
  136. package/dist/runtime/query/iteration/phases/compaction.d.ts +8 -0
  137. package/dist/runtime/query/iteration/phases/compaction.d.ts.map +1 -1
  138. package/dist/runtime/query/iteration/phases/compaction.js +84 -3
  139. package/dist/runtime/query/iteration/phases/compaction.js.map +1 -1
  140. package/dist/runtime/query/iteration/phases/context.d.ts +22 -0
  141. package/dist/runtime/query/iteration/phases/context.d.ts.map +1 -1
  142. package/dist/runtime/query/iteration/phases/context.js +53 -0
  143. package/dist/runtime/query/iteration/phases/context.js.map +1 -1
  144. package/dist/runtime/query/iteration/phases/hitl-abort-race.test.d.ts +2 -0
  145. package/dist/runtime/query/iteration/phases/hitl-abort-race.test.d.ts.map +1 -0
  146. package/dist/runtime/query/iteration/phases/hitl-abort-race.test.js +73 -0
  147. package/dist/runtime/query/iteration/phases/hitl-abort-race.test.js.map +1 -0
  148. package/dist/runtime/query/iteration/phases/hitl-answer-question.test.d.ts +2 -0
  149. package/dist/runtime/query/iteration/phases/hitl-answer-question.test.d.ts.map +1 -0
  150. package/dist/runtime/query/iteration/phases/hitl-answer-question.test.js +120 -0
  151. package/dist/runtime/query/iteration/phases/hitl-answer-question.test.js.map +1 -0
  152. package/dist/runtime/query/iteration/phases/tool-review.d.ts +1 -1
  153. package/dist/runtime/query/iteration/phases/tool-review.d.ts.map +1 -1
  154. package/dist/runtime/query/iteration/phases/tool-review.js +7 -2
  155. package/dist/runtime/query/iteration/phases/tool-review.js.map +1 -1
  156. package/dist/runtime/query/iteration/phases/working-memory-compaction.test.d.ts +19 -0
  157. package/dist/runtime/query/iteration/phases/working-memory-compaction.test.d.ts.map +1 -0
  158. package/dist/runtime/query/iteration/phases/working-memory-compaction.test.js +177 -0
  159. package/dist/runtime/query/iteration/phases/working-memory-compaction.test.js.map +1 -0
  160. package/dist/runtime/query/iteration/phases/working-memory.d.ts +31 -0
  161. package/dist/runtime/query/iteration/phases/working-memory.d.ts.map +1 -0
  162. package/dist/runtime/query/iteration/phases/working-memory.js +81 -0
  163. package/dist/runtime/query/iteration/phases/working-memory.js.map +1 -0
  164. package/dist/runtime/query/prompt.d.ts.map +1 -1
  165. package/dist/runtime/query/prompt.js +21 -1
  166. package/dist/runtime/query/prompt.js.map +1 -1
  167. package/dist/runtime/query/tooling.d.ts +1 -0
  168. package/dist/runtime/query/tooling.d.ts.map +1 -1
  169. package/dist/runtime/query/tooling.js +1 -0
  170. package/dist/runtime/query/tooling.js.map +1 -1
  171. package/dist/sandbox/provider/local.d.ts.map +1 -1
  172. package/dist/sandbox/provider/local.js +32 -1
  173. package/dist/sandbox/provider/local.js.map +1 -1
  174. package/dist/session/workspace/__tests__/shared-run.test.d.ts +2 -0
  175. package/dist/session/workspace/__tests__/shared-run.test.d.ts.map +1 -0
  176. package/dist/session/workspace/__tests__/shared-run.test.js +147 -0
  177. package/dist/session/workspace/__tests__/shared-run.test.js.map +1 -0
  178. package/dist/session/workspace/index.d.ts +2 -0
  179. package/dist/session/workspace/index.d.ts.map +1 -1
  180. package/dist/session/workspace/index.js +1 -0
  181. package/dist/session/workspace/index.js.map +1 -1
  182. package/dist/session/workspace/shared-run.d.ts +81 -0
  183. package/dist/session/workspace/shared-run.d.ts.map +1 -0
  184. package/dist/session/workspace/shared-run.js +252 -0
  185. package/dist/session/workspace/shared-run.js.map +1 -0
  186. package/dist/skills/loader.d.ts.map +1 -1
  187. package/dist/skills/loader.js +36 -6
  188. package/dist/skills/loader.js.map +1 -1
  189. package/dist/skills/loader.test.d.ts +2 -0
  190. package/dist/skills/loader.test.d.ts.map +1 -0
  191. package/dist/skills/loader.test.js +65 -0
  192. package/dist/skills/loader.test.js.map +1 -0
  193. package/dist/streaming/coalesce.test.js +1 -1
  194. package/dist/streaming/coalesce.test.js.map +1 -1
  195. package/dist/tools/builtins/__tests__/edit.test.d.ts +2 -0
  196. package/dist/tools/builtins/__tests__/edit.test.d.ts.map +1 -0
  197. package/dist/tools/builtins/__tests__/edit.test.js +38 -0
  198. package/dist/tools/builtins/__tests__/edit.test.js.map +1 -0
  199. package/dist/tools/builtins/__tests__/payload-budget.test.d.ts +2 -0
  200. package/dist/tools/builtins/__tests__/payload-budget.test.d.ts.map +1 -0
  201. package/dist/tools/builtins/__tests__/payload-budget.test.js +70 -0
  202. package/dist/tools/builtins/__tests__/payload-budget.test.js.map +1 -0
  203. package/dist/tools/builtins/__tests__/read-file.test.d.ts +2 -0
  204. package/dist/tools/builtins/__tests__/read-file.test.d.ts.map +1 -0
  205. package/dist/tools/builtins/__tests__/read-file.test.js +33 -0
  206. package/dist/tools/builtins/__tests__/read-file.test.js.map +1 -0
  207. package/dist/tools/builtins/__tests__/verify-outputs.test.d.ts +2 -0
  208. package/dist/tools/builtins/__tests__/verify-outputs.test.d.ts.map +1 -0
  209. package/dist/tools/builtins/__tests__/verify-outputs.test.js +52 -0
  210. package/dist/tools/builtins/__tests__/verify-outputs.test.js.map +1 -0
  211. package/dist/tools/builtins/__tests__/write-file.test.d.ts +2 -0
  212. package/dist/tools/builtins/__tests__/write-file.test.d.ts.map +1 -0
  213. package/dist/tools/builtins/__tests__/write-file.test.js +74 -0
  214. package/dist/tools/builtins/__tests__/write-file.test.js.map +1 -0
  215. package/dist/tools/builtins/bash.d.ts.map +1 -1
  216. package/dist/tools/builtins/bash.js +40 -7
  217. package/dist/tools/builtins/bash.js.map +1 -1
  218. package/dist/tools/builtins/edit.d.ts +5 -2
  219. package/dist/tools/builtins/edit.d.ts.map +1 -1
  220. package/dist/tools/builtins/edit.js +114 -18
  221. package/dist/tools/builtins/edit.js.map +1 -1
  222. package/dist/tools/builtins/index.d.ts +1 -0
  223. package/dist/tools/builtins/index.d.ts.map +1 -1
  224. package/dist/tools/builtins/index.js +13 -13
  225. package/dist/tools/builtins/index.js.map +1 -1
  226. package/dist/tools/builtins/read-file.d.ts +1 -0
  227. package/dist/tools/builtins/read-file.d.ts.map +1 -1
  228. package/dist/tools/builtins/read-file.js +73 -10
  229. package/dist/tools/builtins/read-file.js.map +1 -1
  230. package/dist/tools/builtins/search-tools.d.ts.map +1 -1
  231. package/dist/tools/builtins/search-tools.js +35 -7
  232. package/dist/tools/builtins/search-tools.js.map +1 -1
  233. package/dist/tools/builtins/verify-outputs.d.ts +5 -0
  234. package/dist/tools/builtins/verify-outputs.d.ts.map +1 -0
  235. package/dist/tools/builtins/verify-outputs.js +103 -0
  236. package/dist/tools/builtins/verify-outputs.js.map +1 -0
  237. package/dist/tools/builtins/write-file.d.ts +3 -2
  238. package/dist/tools/builtins/write-file.d.ts.map +1 -1
  239. package/dist/tools/builtins/write-file.js +72 -12
  240. package/dist/tools/builtins/write-file.js.map +1 -1
  241. package/dist/tools/coordinator/__tests__/agent.test.d.ts +15 -0
  242. package/dist/tools/coordinator/__tests__/agent.test.d.ts.map +1 -0
  243. package/dist/tools/coordinator/__tests__/agent.test.js +142 -0
  244. package/dist/tools/coordinator/__tests__/agent.test.js.map +1 -0
  245. package/dist/tools/coordinator/__tests__/approve-plan.test.d.ts +2 -0
  246. package/dist/tools/coordinator/__tests__/approve-plan.test.d.ts.map +1 -0
  247. package/dist/tools/coordinator/__tests__/approve-plan.test.js +114 -0
  248. package/dist/tools/coordinator/__tests__/approve-plan.test.js.map +1 -0
  249. package/dist/tools/coordinator/__tests__/ask-user-question.test.d.ts +2 -0
  250. package/dist/tools/coordinator/__tests__/ask-user-question.test.d.ts.map +1 -0
  251. package/dist/tools/coordinator/__tests__/ask-user-question.test.js +309 -0
  252. package/dist/tools/coordinator/__tests__/ask-user-question.test.js.map +1 -0
  253. package/dist/tools/coordinator/__tests__/task-list.test.d.ts +13 -0
  254. package/dist/tools/coordinator/__tests__/task-list.test.d.ts.map +1 -0
  255. package/dist/tools/coordinator/__tests__/task-list.test.js +162 -0
  256. package/dist/tools/coordinator/__tests__/task-list.test.js.map +1 -0
  257. package/dist/tools/coordinator/agent.d.ts +34 -0
  258. package/dist/tools/coordinator/agent.d.ts.map +1 -0
  259. package/dist/tools/coordinator/agent.js +107 -0
  260. package/dist/tools/coordinator/agent.js.map +1 -0
  261. package/dist/tools/coordinator/index.d.ts +15 -0
  262. package/dist/tools/coordinator/index.d.ts.map +1 -1
  263. package/dist/tools/coordinator/index.js +305 -35
  264. package/dist/tools/coordinator/index.js.map +1 -1
  265. package/dist/types/agent/base.d.ts +8 -0
  266. package/dist/types/agent/base.d.ts.map +1 -1
  267. package/dist/types/agent/index.d.ts +1 -0
  268. package/dist/types/agent/index.d.ts.map +1 -1
  269. package/dist/types/agent/index.js +1 -0
  270. package/dist/types/agent/index.js.map +1 -1
  271. package/dist/types/agent/reactive.d.ts +38 -0
  272. package/dist/types/agent/reactive.d.ts.map +1 -1
  273. package/dist/types/agent/supervisor.d.ts +32 -0
  274. package/dist/types/agent/supervisor.d.ts.map +1 -1
  275. package/dist/types/agent/working-memory.d.ts +29 -0
  276. package/dist/types/agent/working-memory.d.ts.map +1 -0
  277. package/dist/types/agent/working-memory.js +2 -0
  278. package/dist/types/agent/working-memory.js.map +1 -0
  279. package/dist/types/common/index.d.ts +10 -0
  280. package/dist/types/common/index.d.ts.map +1 -1
  281. package/dist/types/common/index.js +18 -0
  282. package/dist/types/common/index.js.map +1 -1
  283. package/dist/types/common/usage-merge.test.d.ts +2 -0
  284. package/dist/types/common/usage-merge.test.d.ts.map +1 -0
  285. package/dist/types/common/usage-merge.test.js +48 -0
  286. package/dist/types/common/usage-merge.test.js.map +1 -0
  287. package/dist/types/connector/mcp.d.ts +9 -2
  288. package/dist/types/connector/mcp.d.ts.map +1 -1
  289. package/dist/types/hitl/index.d.ts +42 -0
  290. package/dist/types/hitl/index.d.ts.map +1 -1
  291. package/dist/types/hitl/index.js +11 -0
  292. package/dist/types/hitl/index.js.map +1 -1
  293. package/dist/types/message/index.d.ts +22 -1
  294. package/dist/types/message/index.d.ts.map +1 -1
  295. package/dist/types/message/index.js +7 -2
  296. package/dist/types/message/index.js.map +1 -1
  297. package/dist/types/provider/chat.d.ts +11 -9
  298. package/dist/types/provider/chat.d.ts.map +1 -1
  299. package/dist/types/run/events.d.ts +6 -0
  300. package/dist/types/run/events.d.ts.map +1 -1
  301. package/dist/types/run/events.js.map +1 -1
  302. package/dist/types/sandbox/index.d.ts +193 -0
  303. package/dist/types/sandbox/index.d.ts.map +1 -1
  304. package/dist/types/sandbox/index.js.map +1 -1
  305. package/dist/types/skills/index.d.ts +2 -0
  306. package/dist/types/skills/index.d.ts.map +1 -1
  307. package/dist/types/tool/index.d.ts +22 -0
  308. package/dist/types/tool/index.d.ts.map +1 -1
  309. package/dist/types/toolset/index.d.ts +71 -0
  310. package/dist/types/toolset/index.d.ts.map +1 -0
  311. package/dist/types/toolset/index.js +2 -0
  312. package/dist/types/toolset/index.js.map +1 -0
  313. package/dist/types/workspace/index.d.ts +1 -0
  314. package/dist/types/workspace/index.d.ts.map +1 -1
  315. package/dist/types/workspace/shared-run.d.ts +61 -0
  316. package/dist/types/workspace/shared-run.d.ts.map +1 -0
  317. package/dist/types/workspace/shared-run.js +2 -0
  318. package/dist/types/workspace/shared-run.js.map +1 -0
  319. package/dist/verification/index.d.ts +1 -0
  320. package/dist/verification/index.d.ts.map +1 -1
  321. package/dist/verification/index.js +1 -0
  322. package/dist/verification/index.js.map +1 -1
  323. package/dist/verification/presets.d.ts +53 -0
  324. package/dist/verification/presets.d.ts.map +1 -0
  325. package/dist/verification/presets.js +70 -0
  326. package/dist/verification/presets.js.map +1 -0
  327. package/dist/verification/presets.test.d.ts +16 -0
  328. package/dist/verification/presets.test.d.ts.map +1 -0
  329. package/dist/verification/presets.test.js +79 -0
  330. package/dist/verification/presets.test.js.map +1 -0
  331. package/dist/version.d.ts.map +1 -1
  332. package/dist/version.js +25 -4
  333. package/dist/version.js.map +1 -1
  334. package/package.json +3 -2
  335. package/src/advisory/executor.test.ts +7 -4
  336. package/src/advisory/executor.ts +11 -2
  337. package/src/agents/ReactiveAgent.ts +7 -0
  338. package/src/agents/SupervisorAgent.ts +63 -16
  339. package/src/agents/__tests__/supervisor-ledger.test.ts +185 -0
  340. package/src/bridge/sse/mapper.test.ts +2 -2
  341. package/src/config/runtime.ts +9 -0
  342. package/src/connector/builtins/webhook.test.ts +21 -0
  343. package/src/connector/index.ts +1 -0
  344. package/src/connector/mcp/client.ts +4 -0
  345. package/src/connector/mcp/index.ts +1 -0
  346. package/src/connector/mcp/streamable-http.test.ts +169 -0
  347. package/src/connector/mcp/streamable-http.ts +152 -0
  348. package/src/constants/compaction/index.ts +8 -3
  349. package/src/constants/sandbox/index.ts +37 -0
  350. package/src/constants/tools/index.ts +33 -2
  351. package/src/manager/run/persistence.ts +34 -6
  352. package/src/persona/assembler.ts +43 -8
  353. package/src/provider/collect.test.ts +2 -2
  354. package/src/provider/collect.ts +4 -1
  355. package/src/public-runtime.ts +15 -1
  356. package/src/public-tools.ts +2 -0
  357. package/src/public-types.ts +7 -0
  358. package/src/registry/index.ts +7 -0
  359. package/src/registry/tool/execute.test.ts +211 -7
  360. package/src/registry/tool/execute.ts +199 -11
  361. package/src/registry/toolset/catalog.test.ts +165 -0
  362. package/src/registry/toolset/catalog.ts +283 -0
  363. package/src/runtime/query/__tests__/deferred-tools.test.ts +230 -0
  364. package/src/runtime/query/__tests__/executor-concurrency.test.ts +122 -0
  365. package/src/runtime/query/__tests__/executor-plugin-hooks.test.ts +48 -3
  366. package/src/runtime/query/__tests__/long-document-flow.test.ts +180 -0
  367. package/src/runtime/query/__tests__/prompt.test.ts +55 -2
  368. package/src/runtime/query/__tests__/stream-recovery.test.ts +156 -0
  369. package/src/runtime/query/continuation.ts +16 -0
  370. package/src/runtime/query/executor.ts +82 -13
  371. package/src/runtime/query/index.ts +58 -5
  372. package/src/runtime/query/iteration/index.ts +361 -74
  373. package/src/runtime/query/iteration/phases/checkpoint.ts +7 -2
  374. package/src/runtime/query/iteration/phases/compaction.ts +89 -3
  375. package/src/runtime/query/iteration/phases/context.ts +68 -0
  376. package/src/runtime/query/iteration/phases/hitl-abort-race.test.ts +86 -0
  377. package/src/runtime/query/iteration/phases/hitl-answer-question.test.ts +139 -0
  378. package/src/runtime/query/iteration/phases/tool-review.ts +7 -3
  379. package/src/runtime/query/iteration/phases/working-memory-compaction.test.ts +215 -0
  380. package/src/runtime/query/iteration/phases/working-memory.ts +86 -0
  381. package/src/runtime/query/prompt.ts +17 -1
  382. package/src/runtime/query/tooling.ts +2 -0
  383. package/src/sandbox/provider/local.ts +33 -0
  384. package/src/session/workspace/__tests__/shared-run.test.ts +181 -0
  385. package/src/session/workspace/index.ts +6 -0
  386. package/src/session/workspace/shared-run.ts +317 -0
  387. package/src/skills/loader.test.ts +89 -0
  388. package/src/skills/loader.ts +37 -6
  389. package/src/streaming/coalesce.test.ts +4 -4
  390. package/src/tools/builtins/__tests__/edit.test.ts +57 -0
  391. package/src/tools/builtins/__tests__/payload-budget.test.ts +92 -0
  392. package/src/tools/builtins/__tests__/read-file.test.ts +43 -0
  393. package/src/tools/builtins/__tests__/verify-outputs.test.ts +71 -0
  394. package/src/tools/builtins/__tests__/write-file.test.ts +97 -0
  395. package/src/tools/builtins/bash.ts +48 -7
  396. package/src/tools/builtins/edit.ts +162 -27
  397. package/src/tools/builtins/index.ts +13 -13
  398. package/src/tools/builtins/read-file.ts +81 -10
  399. package/src/tools/builtins/search-tools.ts +42 -7
  400. package/src/tools/builtins/verify-outputs.ts +126 -0
  401. package/src/tools/builtins/write-file.ts +83 -14
  402. package/src/tools/coordinator/__tests__/agent.test.ts +172 -0
  403. package/src/tools/coordinator/__tests__/approve-plan.test.ts +139 -0
  404. package/src/tools/coordinator/__tests__/ask-user-question.test.ts +370 -0
  405. package/src/tools/coordinator/__tests__/task-list.test.ts +182 -0
  406. package/src/tools/coordinator/agent.ts +157 -0
  407. package/src/tools/coordinator/index.ts +355 -39
  408. package/src/types/agent/base.ts +8 -0
  409. package/src/types/agent/index.ts +1 -0
  410. package/src/types/agent/reactive.ts +42 -0
  411. package/src/types/agent/supervisor.ts +36 -0
  412. package/src/types/agent/working-memory.ts +29 -0
  413. package/src/types/common/index.ts +19 -0
  414. package/src/types/common/usage-merge.test.ts +53 -0
  415. package/src/types/connector/mcp.ts +14 -2
  416. package/src/types/hitl/index.ts +52 -1
  417. package/src/types/message/index.ts +32 -2
  418. package/src/types/provider/chat.ts +12 -9
  419. package/src/types/run/events.ts +6 -0
  420. package/src/types/sandbox/index.ts +219 -0
  421. package/src/types/skills/index.ts +4 -0
  422. package/src/types/tool/index.ts +24 -0
  423. package/src/types/toolset/index.ts +86 -0
  424. package/src/types/workspace/index.ts +9 -0
  425. package/src/types/workspace/shared-run.ts +65 -0
  426. package/src/verification/index.ts +1 -0
  427. package/src/verification/presets.test.ts +112 -0
  428. package/src/verification/presets.ts +72 -0
  429. package/src/version.ts +26 -4
@@ -0,0 +1,215 @@
1
+ /**
2
+ * Regression test for the ses_055 Layer-B SDK seam (#104):
3
+ *
4
+ * 1. **Compaction FIRES** under a small `contextWindowTokens` even with the
5
+ * run-level `tokenBudget = 0` (UNLIMITED) — proving the F1 fix repointed
6
+ * BOTH the `<= 0` guard AND the divisor, closing the silent-no-op trap.
7
+ * 2. **The pinned working-memory slot SURVIVES** the compaction pass (it is a
8
+ * leading system message → preserved by header identity).
9
+ * 3. **No premature stop** from `tokenBudget = 0` alone: with NO
10
+ * `contextWindowTokens`, the same overflowing run does NOT compact (the
11
+ * legacy fallback), so consumers that never set the new field are
12
+ * byte-identical.
13
+ *
14
+ * The test drives `refreshWorkingMemory` (to pin the slot) then
15
+ * `runCompactionCheck` directly against a mock `IterationContext`, which is the
16
+ * exact sequence the iteration loop runs each turn.
17
+ */
18
+
19
+ import { describe, expect, it, vi } from 'vitest'
20
+
21
+ import { findDanglingMessages } from '../../../../compaction/dangling.js'
22
+ import { WorkingStateManager } from '../../../../compaction/manager.js'
23
+ import { CompactionConfigSchema } from '../../../../config/runtime.js'
24
+ import type { RunId } from '../../../../types/ids/index.js'
25
+ import {
26
+ type Message,
27
+ createAssistantMessage,
28
+ createSystemMessage,
29
+ createToolMessage,
30
+ createUserMessage,
31
+ } from '../../../../types/message/index.js'
32
+ import type { Logger } from '../../../../utils/logger.js'
33
+ import { runCompactionCheck } from './compaction.js'
34
+ import type { IterationContext } from './context.js'
35
+ import { WORKING_MEMORY_HEADER, refreshWorkingMemory } from './working-memory.js'
36
+
37
+ function makeLogger(): Logger {
38
+ const self = {
39
+ info: vi.fn(),
40
+ warn: vi.fn(),
41
+ error: vi.fn(),
42
+ debug: vi.fn(),
43
+ child: vi.fn(),
44
+ } as unknown as Logger
45
+ ;(self as { child: (ctx: unknown) => Logger }).child = vi.fn(() => self)
46
+ return self
47
+ }
48
+
49
+ /** A long string so a handful of messages overflow a small context window. */
50
+ const FILLER = 'x'.repeat(200)
51
+
52
+ function buildOverflowingMessages(): Message[] {
53
+ const msgs: Message[] = [createSystemMessage(`STATIC SYSTEM PROMPT ${FILLER}`, 'cache')]
54
+ for (let i = 0; i < 8; i++) {
55
+ msgs.push(createUserMessage(`user turn ${i} ${FILLER}`))
56
+ msgs.push(createAssistantMessage(`assistant turn ${i} ${FILLER}`))
57
+ }
58
+ return msgs
59
+ }
60
+
61
+ function makeCtx(opts: {
62
+ messages: Message[]
63
+ contextWindowTokens?: number
64
+ workingMemoryProvider?: IterationContext['workingMemoryProvider']
65
+ }): IterationContext {
66
+ const config = CompactionConfigSchema.parse({
67
+ strategy: 'structured',
68
+ llmVerification: false,
69
+ ...(opts.contextWindowTokens !== undefined
70
+ ? { contextWindowTokens: opts.contextWindowTokens }
71
+ : {}),
72
+ })
73
+ const manager = new WorkingStateManager(config)
74
+ // Seed a couple of slots so serializeState produces non-trivial output.
75
+ manager.addDecision('built the report as .docx')
76
+
77
+ return {
78
+ runConfig: { tokenBudget: 0 }, // UNLIMITED cumulative cost cap
79
+ compactionConfig: config,
80
+ workingStateManager: manager,
81
+ workingMemoryProvider: opts.workingMemoryProvider,
82
+ log: makeLogger(),
83
+ runMgr: {
84
+ id: 'run_1' as RunId,
85
+ currentIteration: 3,
86
+ messages: opts.messages,
87
+ },
88
+ } as unknown as IterationContext
89
+ }
90
+
91
+ const WM_BLOCK =
92
+ 'ARTIFACTS\n • report.docx · Word document · 48.2 KB · imp:H\n path: /mnt/user-data/outputs/report.docx'
93
+
94
+ describe('Layer-B compaction seam (ses_055 #104)', () => {
95
+ it('FIRES on small contextWindowTokens with tokenBudget=0 AND preserves the pinned WM slot', async () => {
96
+ const messages = buildOverflowingMessages()
97
+ const ctx = makeCtx({
98
+ messages,
99
+ contextWindowTokens: 100,
100
+ workingMemoryProvider: () => WM_BLOCK,
101
+ })
102
+
103
+ await refreshWorkingMemory(ctx)
104
+ // The slot is pinned as the last leading system message (index 1).
105
+ expect(messages[1]?.role).toBe('system')
106
+ expect(messages[1]?.content?.startsWith(WORKING_MEMORY_HEADER)).toBe(true)
107
+
108
+ const before = messages.length
109
+ await runCompactionCheck(ctx)
110
+
111
+ // (1) compaction fired: a [COMPACTED CONTEXT] message appeared and the
112
+ // transcript shrank.
113
+ expect(messages.length).toBeLessThan(before)
114
+ expect(messages.some((m) => m.content?.includes('[COMPACTED CONTEXT]'))).toBe(true)
115
+
116
+ // (2) the pinned working-memory slot survived by header identity.
117
+ const wm = messages.filter(
118
+ (m) => m.role === 'system' && m.content?.startsWith(WORKING_MEMORY_HEADER),
119
+ )
120
+ expect(wm).toHaveLength(1)
121
+ expect(wm[0]?.content).toContain('report.docx')
122
+ })
123
+
124
+ it('does NOT compact when contextWindowTokens is absent and tokenBudget=0 (byte-identical fallback)', async () => {
125
+ const messages = buildOverflowingMessages()
126
+ const ctx = makeCtx({ messages })
127
+
128
+ const before = messages.length
129
+ await runCompactionCheck(ctx)
130
+
131
+ // budget = tokenBudget = 0 → guard returns; no compaction, no mutation.
132
+ expect(messages.length).toBe(before)
133
+ expect(messages.some((m) => m.content?.includes('[COMPACTED CONTEXT]'))).toBe(false)
134
+ })
135
+
136
+ it('removes the slot when the provider returns an empty block', async () => {
137
+ const messages = buildOverflowingMessages()
138
+ const ctx = makeCtx({
139
+ messages,
140
+ contextWindowTokens: 100,
141
+ workingMemoryProvider: () => WM_BLOCK,
142
+ })
143
+ await refreshWorkingMemory(ctx)
144
+ expect(messages.some((m) => m.content?.startsWith(WORKING_MEMORY_HEADER))).toBe(true)
145
+
146
+ // Same transcript, provider now returns blank ⇒ the slot is removed.
147
+ const blankCtx = makeCtx({
148
+ messages,
149
+ contextWindowTokens: 100,
150
+ workingMemoryProvider: () => ' ',
151
+ })
152
+ await refreshWorkingMemory(blankCtx)
153
+ expect(messages.some((m) => m.content?.startsWith(WORKING_MEMORY_HEADER))).toBe(false)
154
+ })
155
+
156
+ it('keeps the prior slot when the provider throws (failure-isolated)', async () => {
157
+ const messages = buildOverflowingMessages()
158
+ const ctx = makeCtx({
159
+ messages,
160
+ contextWindowTokens: 100,
161
+ workingMemoryProvider: () => WM_BLOCK,
162
+ })
163
+ await refreshWorkingMemory(ctx)
164
+
165
+ const throwingCtx = makeCtx({
166
+ messages,
167
+ contextWindowTokens: 100,
168
+ workingMemoryProvider: () => {
169
+ throw new Error('provider boom')
170
+ },
171
+ })
172
+ await refreshWorkingMemory(throwingCtx)
173
+ // Prior slot retained; run not broken.
174
+ expect(messages.some((m) => m.content?.startsWith(WORKING_MEMORY_HEADER))).toBe(true)
175
+ })
176
+
177
+ it('does NOT orphan a tool_result when the recent-window cut splits a tool pair (C1)', async () => {
178
+ // keepRecentMessages defaults to 4. Lay the transcript out so the NAIVE
179
+ // cut (length - 4 = index 5) lands right AFTER the assistant-with-toolCall
180
+ // (index 4) but BEFORE... no — exactly ON its tool result (index 5), which
181
+ // a naive slice would keep in the recent window while dropping the
182
+ // assistant into the summarized older set → an orphaned tool_result at the
183
+ // head of the recent window → Anthropic 400. The fix snaps keepStart
184
+ // forward past the complete pair.
185
+ const toolCall = {
186
+ id: 't1',
187
+ type: 'function' as const,
188
+ function: { name: 'read', arguments: '{}' },
189
+ }
190
+ const messages: Message[] = [
191
+ createSystemMessage(`STATIC SYSTEM PROMPT ${FILLER}`, 'cache'),
192
+ createUserMessage(`user 0 ${FILLER}`),
193
+ createAssistantMessage(`assistant 0 ${FILLER}`),
194
+ createUserMessage(`user 1 ${FILLER}`),
195
+ createAssistantMessage(`calling a tool ${FILLER}`, [toolCall]), // idx 4
196
+ createToolMessage(`tool result ${FILLER}`, 't1'), // idx 5 — naive recent[0]
197
+ createAssistantMessage(`assistant 2 ${FILLER}`),
198
+ createUserMessage(`user 3 ${FILLER}`),
199
+ createAssistantMessage(`assistant 3 ${FILLER}`),
200
+ ]
201
+ const ctx = makeCtx({ messages, contextWindowTokens: 100 })
202
+
203
+ await runCompactionCheck(ctx)
204
+
205
+ // Compaction fired.
206
+ expect(messages.some((m) => m.content?.includes('[COMPACTED CONTEXT]'))).toBe(true)
207
+ // The surviving transcript has NO dangling tool pair — the tool result
208
+ // whose assistant was summarized away was moved into the older set too,
209
+ // so no orphaned tool_result remains to 400 the next provider turn.
210
+ expect(findDanglingMessages(messages).isValid).toBe(true)
211
+ // And a `tool` message never leads the recent window.
212
+ const firstNonSystem = messages.find((m) => m.role !== 'system')
213
+ expect(firstNonSystem?.role).not.toBe('tool')
214
+ })
215
+ })
@@ -0,0 +1,86 @@
1
+ import { createSystemMessage } from '../../../../types/message/index.js'
2
+ import type { IterationContext } from './context.js'
3
+
4
+ /**
5
+ * Sentinel header identifying the single PINNED working-memory system message.
6
+ *
7
+ * The SDK finds + replaces the slot by this header every turn and uses the same
8
+ * identity to re-pin it if compaction ever drops it (the OPAQUE survival guard
9
+ * in `compaction.ts` — no host-format knowledge required). The host's rendered
10
+ * block is stored verbatim AFTER this header; the SDK never parses it.
11
+ */
12
+ export const WORKING_MEMORY_HEADER =
13
+ '[WORKING MEMORY] Authoritative state for this conversation — you produced these.'
14
+
15
+ /**
16
+ * True when `content` is the pinned working-memory slot (header identity only).
17
+ * Shared with `compaction.ts` so the survival guard re-pins by the SAME rule.
18
+ */
19
+ export function isWorkingMemoryMessage(content: string | null | undefined): boolean {
20
+ return typeof content === 'string' && content.startsWith(WORKING_MEMORY_HEADER)
21
+ }
22
+
23
+ /**
24
+ * Resolve the host's working-memory string and rewrite a single PINNED leading
25
+ * system message in place. Insert-or-replace keyed by {@link WORKING_MEMORY_HEADER};
26
+ * an empty/blank string removes the slot.
27
+ *
28
+ * The slot is an EPHEMERAL system message placed as the LAST leading system
29
+ * message (after the cached static + dynamic system messages), so it never
30
+ * busts the prompt-cache prefix yet still rides inside the compaction-preserved
31
+ * leading-system run (the primacy edge Lost-in-the-Middle / Context-Rot need).
32
+ *
33
+ * Failure-isolated (the `web-search` seam rule): a throwing/slow provider
34
+ * degrades to "no refresh this turn" (keeps the prior slot), never breaks the
35
+ * run. Early-returns when no provider is configured ⇒ byte-identical run path.
36
+ */
37
+ export async function refreshWorkingMemory(ctx: IterationContext): Promise<void> {
38
+ const provider = ctx.workingMemoryProvider
39
+ if (!provider) return
40
+
41
+ let block: string
42
+ try {
43
+ block =
44
+ (await provider({
45
+ runId: ctx.runMgr.id,
46
+ iteration: ctx.runMgr.currentIteration,
47
+ })) ?? ''
48
+ } catch (err) {
49
+ ctx.log.warn('workingMemoryProvider failed; keeping prior slot', {
50
+ runId: ctx.runMgr.id,
51
+ error: err instanceof Error ? err.message : String(err),
52
+ })
53
+ return
54
+ }
55
+
56
+ const msgs = ctx.runMgr.messages
57
+
58
+ // Bound the search to the LEADING system run (the compaction-preserved
59
+ // region). A working-memory header appearing later in the transcript (e.g.
60
+ // echoed by a tool result) must not be mistaken for the pinned slot.
61
+ let leadEnd = 0
62
+ while (leadEnd < msgs.length && msgs[leadEnd]?.role === 'system') leadEnd++
63
+
64
+ let idx = -1
65
+ for (let i = 0; i < leadEnd; i++) {
66
+ const m = msgs[i]
67
+ if (m && m.role === 'system' && isWorkingMemoryMessage(m.content)) {
68
+ idx = i
69
+ break
70
+ }
71
+ }
72
+
73
+ if (!block.trim()) {
74
+ // Empty block ⇒ remove the slot (byte-identical-when-empty).
75
+ if (idx >= 0) msgs.splice(idx, 1)
76
+ return
77
+ }
78
+
79
+ const wm = createSystemMessage(`${WORKING_MEMORY_HEADER}\n\n${block}`, 'ephemeral')
80
+ if (idx >= 0) {
81
+ msgs[idx] = wm
82
+ } else {
83
+ // Insert as the LAST leading system message (after static + dynamic).
84
+ msgs.splice(leadEnd, 0, wm)
85
+ }
86
+ }
@@ -1,5 +1,5 @@
1
1
  import { FILESYSTEM_TOOLS } from '../../constants/tools/index.js'
2
- import { assembleSystemPrompt } from '../../persona/assembler.js'
2
+ import { assembleSystemPrompt, renderSkillsSection } from '../../persona/assembler.js'
3
3
  import type { AgentRuntimeContext } from '../../types/agent/base.js'
4
4
  import type { AgentContextLevel } from '../../types/agent/factory.js'
5
5
  import type { AgentPersona } from '../../types/persona/index.js'
@@ -83,6 +83,14 @@ export class PromptBuilder {
83
83
  parts.push(this.config.systemPrompt)
84
84
  } else if (this.config.persona) {
85
85
  parts.push(assembleSystemPrompt(this.config.persona, this.config.skills))
86
+ } else {
87
+ const skillSection = renderSkillsSection(this.config.skills)
88
+ if (skillSection) parts.push(skillSection)
89
+ }
90
+
91
+ if (this.config.systemPrompt) {
92
+ const skillSection = renderSkillsSection(this.config.skills)
93
+ if (skillSection) parts.push(skillSection)
86
94
  }
87
95
 
88
96
  if (contextLevel !== 'minimal') {
@@ -133,6 +141,14 @@ export class PromptBuilder {
133
141
  if (this.config.persona.sessionContext) {
134
142
  dynamicParts.push(`## Session Context\n${this.config.persona.sessionContext.trim()}`)
135
143
  }
144
+ } else {
145
+ const skillSection = renderSkillsSection(this.config.skills)
146
+ if (skillSection) staticParts.push(skillSection)
147
+ }
148
+
149
+ if (this.config.systemPrompt) {
150
+ const skillSection = renderSkillsSection(this.config.skills)
151
+ if (skillSection) staticParts.push(skillSection)
136
152
  }
137
153
 
138
154
  if (contextLevel !== 'minimal') {
@@ -17,6 +17,7 @@ export interface ToolingBootstrapConfig {
17
17
  permissionMode: PermissionMode
18
18
  env: Record<string, string>
19
19
  abortSignal: AbortSignal
20
+ allowedTools?: readonly string[]
20
21
  invocationState?: InvocationState
21
22
  pluginManager?: PluginLifecycleManager
22
23
  }
@@ -36,6 +37,7 @@ export class ToolingBootstrap {
36
37
  permissionMode: config.permissionMode,
37
38
  env: config.env,
38
39
  abortSignal: config.abortSignal,
40
+ allowedTools: config.allowedTools,
39
41
  invocationState: config.invocationState,
40
42
  pluginManager: config.pluginManager,
41
43
  },
@@ -4,8 +4,10 @@ import {
4
4
  readFile as fsReadFile,
5
5
  writeFile as fsWriteFile,
6
6
  mkdir,
7
+ readdir,
7
8
  rename,
8
9
  rm,
10
+ stat,
9
11
  } from 'node:fs/promises'
10
12
  import { tmpdir } from 'node:os'
11
13
  import { dirname, isAbsolute, join, relative, resolve } from 'node:path'
@@ -24,6 +26,7 @@ import type {
24
26
  SandboxEnvironment,
25
27
  SandboxExecOptions,
26
28
  SandboxExecResult,
29
+ SandboxFileEntry,
27
30
  SandboxProvider,
28
31
  SandboxStatus,
29
32
  } from '../../types/sandbox/index.js'
@@ -302,6 +305,36 @@ class LocalSandbox implements Sandbox {
302
305
  return fsReadFile(resolved)
303
306
  }
304
307
 
308
+ async listFiles(rootPath: string): Promise<readonly SandboxFileEntry[]> {
309
+ if (this._status === 'destroyed') {
310
+ throw new Error(`Sandbox ${this.id} is destroyed`)
311
+ }
312
+
313
+ const resolved = assertInsideSandbox(this.rootDir, rootPath)
314
+ const root = await stat(resolved).catch(() => null)
315
+ if (!root || !root.isDirectory()) return []
316
+
317
+ const entries: SandboxFileEntry[] = []
318
+ const stack: string[] = [resolved]
319
+ while (stack.length > 0) {
320
+ const dir = stack.pop()
321
+ if (!dir) break
322
+ const dirents = await readdir(dir, { withFileTypes: true }).catch(() => [])
323
+ for (const ent of dirents) {
324
+ const full = join(dir, ent.name)
325
+ if (ent.isDirectory()) {
326
+ stack.push(full)
327
+ continue
328
+ }
329
+ if (!ent.isFile()) continue
330
+ const info = await stat(full).catch(() => null)
331
+ if (!info) continue
332
+ entries.push({ path: full, size: info.size })
333
+ }
334
+ }
335
+ return entries
336
+ }
337
+
305
338
  async destroy(): Promise<void> {
306
339
  if (this._status === 'destroyed') {
307
340
  return
@@ -0,0 +1,181 @@
1
+ import { mkdtemp, readFile } from 'node:fs/promises'
2
+ import { tmpdir } from 'node:os'
3
+ import { join } from 'node:path'
4
+ import { describe, expect, it } from 'vitest'
5
+ import { SharedRunWorkspace } from '../shared-run.js'
6
+
7
+ describe('SharedRunWorkspace', () => {
8
+ it('creates a canonical workspace manifest with runtime-visible paths', async () => {
9
+ const hostRoot = await mkdtemp(join(tmpdir(), 'namzu-shared-workspace-'))
10
+ const workspace = await SharedRunWorkspace.create({
11
+ hostRoot,
12
+ runtimeRoot: '/mnt/user-data/outputs/_work',
13
+ label: 'Cowork task',
14
+ now: new Date('2026-05-08T10:00:00.000Z'),
15
+ })
16
+
17
+ const manifest = await workspace.readManifest()
18
+ expect(manifest.kind).toBe('shared-run-workspace')
19
+ expect(manifest.label).toBe('Cowork task')
20
+ expect(manifest.paths).toMatchObject({
21
+ root: '/mnt/user-data/outputs/_work',
22
+ manifest: '/mnt/user-data/outputs/_work/manifest.json',
23
+ sharedContext: '/mnt/user-data/outputs/_work/02_shared_context.md',
24
+ sources: '/mnt/user-data/outputs/_work/sources',
25
+ plans: '/mnt/user-data/outputs/_work/plans',
26
+ agents: '/mnt/user-data/outputs/_work/agents',
27
+ })
28
+ expect(workspace.refs().supervisorBriefPath).toBe(
29
+ '/mnt/user-data/outputs/_work/00_supervisor_brief.md',
30
+ )
31
+ expect(workspace.refs().sharedContextPath).toBe(
32
+ '/mnt/user-data/outputs/_work/02_shared_context.md',
33
+ )
34
+ })
35
+
36
+ it('records source inventory and seeded supervisor brief before workers launch', async () => {
37
+ const hostRoot = await mkdtemp(join(tmpdir(), 'namzu-shared-workspace-'))
38
+ const workspace = await SharedRunWorkspace.create({
39
+ hostRoot,
40
+ runtimeRoot: '/mnt/user-data/outputs/_work/',
41
+ })
42
+
43
+ await workspace.writeSourceInventory([
44
+ {
45
+ id: 'file_abc',
46
+ label: 'SBD.docx',
47
+ path: '/mnt/user-data/uploads/file_abc/SBD.docx',
48
+ kind: 'docx',
49
+ sizeBytes: 123,
50
+ },
51
+ ])
52
+ const briefPath = await workspace.seedSupervisorBrief({
53
+ briefText: 'Root task seed brief',
54
+ })
55
+ const agentPath = await workspace.registerAgentWork({
56
+ agentId: 'solution-architecture',
57
+ taskId: 'task_123',
58
+ })
59
+
60
+ expect(briefPath).toBe('/mnt/user-data/outputs/_work/00_supervisor_brief.md')
61
+ expect(agentPath).toBe('/mnt/user-data/outputs/_work/agents/solution-architecture/task_123')
62
+ const inventory = await readFile(join(hostRoot, 'sources', 'inventory.md'), 'utf8')
63
+ expect(inventory).toContain('SBD.docx')
64
+ expect(inventory).toContain('/mnt/user-data/uploads/file_abc/SBD.docx')
65
+ const manifest = await workspace.readManifest()
66
+ expect(manifest.sources).toHaveLength(1)
67
+ expect(manifest.plans[0]?.status).toBe('seeded')
68
+ expect(manifest.agents[0]?.workPath).toBe(agentPath)
69
+ })
70
+
71
+ it('preserves every agent record when workers register concurrently', async () => {
72
+ const hostRoot = await mkdtemp(join(tmpdir(), 'namzu-shared-workspace-'))
73
+ const workspace = await SharedRunWorkspace.create({
74
+ hostRoot,
75
+ runtimeRoot: '/mnt/user-data/outputs/_work',
76
+ })
77
+
78
+ await Promise.all(
79
+ Array.from({ length: 9 }, (_, index) =>
80
+ workspace.registerAgentWork({
81
+ agentId: `agent-${index + 1}`,
82
+ taskId: `task_${index + 1}`,
83
+ status: 'running',
84
+ }),
85
+ ),
86
+ )
87
+
88
+ const manifest = await workspace.readManifest()
89
+ expect(manifest.agents).toHaveLength(9)
90
+ expect(manifest.agents.map((agent) => agent.agentId).sort()).toEqual([
91
+ 'agent-1',
92
+ 'agent-2',
93
+ 'agent-3',
94
+ 'agent-4',
95
+ 'agent-5',
96
+ 'agent-6',
97
+ 'agent-7',
98
+ 'agent-8',
99
+ 'agent-9',
100
+ ])
101
+ })
102
+
103
+ it('writes and appends per-worker briefs without losing earlier sections', async () => {
104
+ const hostRoot = await mkdtemp(join(tmpdir(), 'namzu-shared-workspace-'))
105
+ const workspace = await SharedRunWorkspace.create({
106
+ hostRoot,
107
+ runtimeRoot: '/mnt/user-data/outputs/_work',
108
+ })
109
+
110
+ const briefPath = await workspace.writeAgentBrief({
111
+ agentId: 'solution-architecture',
112
+ taskId: 'task_abc',
113
+ briefText: '# Worker Brief\n\n## Assignment\n\nDraft the solution architecture section.',
114
+ })
115
+ expect(briefPath).toBe(
116
+ '/mnt/user-data/outputs/_work/agents/solution-architecture/task_abc/00_brief.md',
117
+ )
118
+
119
+ const appended = await workspace.appendAgentBrief({
120
+ agentId: 'solution-architecture',
121
+ taskId: 'task_abc',
122
+ sectionText:
123
+ '## Follow-up 2026-05-10T18:00:00.000Z\n\n### Follow-up message\n\nAdd a risks subsection.',
124
+ })
125
+ expect(appended).toBe(briefPath)
126
+
127
+ const hostBriefPath = join(
128
+ hostRoot,
129
+ 'agents',
130
+ 'solution-architecture',
131
+ 'task_abc',
132
+ '00_brief.md',
133
+ )
134
+ const content = await readFile(hostBriefPath, 'utf8')
135
+ expect(content).toContain('Draft the solution architecture section.')
136
+ expect(content).toContain('Add a risks subsection.')
137
+ // Initial seed must precede the appended section, not the other way around.
138
+ const seedIndex = content.indexOf('Draft the solution architecture')
139
+ const followIndex = content.indexOf('Add a risks subsection.')
140
+ expect(seedIndex).toBeGreaterThan(-1)
141
+ expect(followIndex).toBeGreaterThan(seedIndex)
142
+ })
143
+
144
+ it('writeTaskContext stores the user request verbatim under 01_task_context.md', async () => {
145
+ const hostRoot = await mkdtemp(join(tmpdir(), 'namzu-shared-workspace-'))
146
+ const workspace = await SharedRunWorkspace.create({
147
+ hostRoot,
148
+ runtimeRoot: '/mnt/user-data/outputs/_work',
149
+ })
150
+
151
+ const big = `# Task Context\n\n${'A'.repeat(40_000)}`
152
+ const path = await workspace.writeTaskContext(big)
153
+ expect(path).toBe('/mnt/user-data/outputs/_work/01_task_context.md')
154
+ expect(workspace.refs().taskContextPath).toBe(path)
155
+ const content = await readFile(join(hostRoot, '01_task_context.md'), 'utf8')
156
+ // Trailing newline added by the writer is OK; user content must not be truncated.
157
+ expect(content.length).toBeGreaterThanOrEqual(big.length)
158
+ expect(content).toContain('A'.repeat(40_000))
159
+ })
160
+
161
+ it('writeSharedContext stores the shared coordination packet under 02_shared_context.md', async () => {
162
+ const hostRoot = await mkdtemp(join(tmpdir(), 'namzu-shared-workspace-'))
163
+ const workspace = await SharedRunWorkspace.create({
164
+ hostRoot,
165
+ runtimeRoot: '/mnt/user-data/outputs/_work',
166
+ })
167
+
168
+ const path = await workspace.writeSharedContext('# Shared Context\n\nRead this first.')
169
+ expect(path).toBe('/mnt/user-data/outputs/_work/02_shared_context.md')
170
+ expect(workspace.refs().sharedContextPath).toBe(path)
171
+ const content = await readFile(join(hostRoot, '02_shared_context.md'), 'utf8')
172
+ expect(content).toContain('Read this first.')
173
+ })
174
+
175
+ it('rejects host paths that escape the shared workspace root', async () => {
176
+ const hostRoot = await mkdtemp(join(tmpdir(), 'namzu-shared-workspace-'))
177
+ const workspace = await SharedRunWorkspace.create({ hostRoot })
178
+
179
+ expect(() => workspace.hostPath('..', 'outside')).toThrow(/escapes root/)
180
+ })
181
+ })
@@ -24,3 +24,9 @@ export { WorkspaceBackendRegistry } from './registry.js'
24
24
 
25
25
  export { GitWorktreeDriver, parseWorktreeList } from './git-worktree.js'
26
26
  export type { ExecFile, ExecFileResult, GitWorktreeDriverConfig } from './git-worktree.js'
27
+
28
+ export { SharedRunWorkspace } from './shared-run.js'
29
+ export type {
30
+ RegisterSharedRunPlanInput,
31
+ SharedRunWorkspaceConfig,
32
+ } from './shared-run.js'