@nodetool-ai/agents 0.7.0-rc.23 → 0.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1645) hide show
  1. package/README.md +35 -0
  2. package/dist/.nodetool-build-stamp +1 -0
  3. package/dist/analysis/audio-dsp.d.ts +224 -0
  4. package/dist/analysis/audio-dsp.d.ts.map +1 -0
  5. package/dist/analysis/audio-dsp.js +645 -0
  6. package/dist/analysis/audio-dsp.js.map +1 -0
  7. package/dist/analysis/media-decode.d.ts +98 -0
  8. package/dist/analysis/media-decode.d.ts.map +1 -0
  9. package/dist/analysis/media-decode.js +226 -0
  10. package/dist/analysis/media-decode.js.map +1 -0
  11. package/dist/analysis/mediabunny-runtime.d.ts +15 -0
  12. package/dist/analysis/mediabunny-runtime.d.ts.map +1 -0
  13. package/dist/analysis/mediabunny-runtime.js +30 -0
  14. package/dist/analysis/mediabunny-runtime.js.map +1 -0
  15. package/dist/analysis/video-frames.d.ts +120 -0
  16. package/dist/analysis/video-frames.d.ts.map +1 -0
  17. package/dist/analysis/video-frames.js +288 -0
  18. package/dist/analysis/video-frames.js.map +1 -0
  19. package/dist/apify/assets.d.ts +80 -0
  20. package/dist/apify/assets.d.ts.map +1 -0
  21. package/dist/apify/assets.js +192 -0
  22. package/dist/apify/assets.js.map +1 -0
  23. package/dist/apify/catalog.d.ts +44 -0
  24. package/dist/apify/catalog.d.ts.map +1 -0
  25. package/dist/apify/catalog.js +108 -0
  26. package/dist/apify/catalog.js.map +1 -0
  27. package/dist/apify/client.d.ts +137 -0
  28. package/dist/apify/client.d.ts.map +1 -0
  29. package/dist/apify/client.js +346 -0
  30. package/dist/apify/client.js.map +1 -0
  31. package/dist/apify/errors.d.ts +85 -0
  32. package/dist/apify/errors.d.ts.map +1 -0
  33. package/dist/apify/errors.js +90 -0
  34. package/dist/apify/errors.js.map +1 -0
  35. package/dist/apify/normalize.d.ts +131 -0
  36. package/dist/apify/normalize.d.ts.map +1 -0
  37. package/dist/apify/normalize.js +202 -0
  38. package/dist/apify/normalize.js.map +1 -0
  39. package/dist/apify/policy.d.ts +136 -0
  40. package/dist/apify/policy.d.ts.map +1 -0
  41. package/dist/apify/policy.js +223 -0
  42. package/dist/apify/policy.js.map +1 -0
  43. package/dist/apify/run.d.ts +86 -0
  44. package/dist/apify/run.d.ts.map +1 -0
  45. package/dist/apify/run.js +158 -0
  46. package/dist/apify/run.js.map +1 -0
  47. package/dist/app-build/author.d.ts +67 -0
  48. package/dist/app-build/author.d.ts.map +1 -0
  49. package/dist/app-build/author.js +231 -0
  50. package/dist/app-build/author.js.map +1 -0
  51. package/dist/app-build/bridge.d.ts +130 -0
  52. package/dist/app-build/bridge.d.ts.map +1 -0
  53. package/dist/app-build/bridge.js +647 -0
  54. package/dist/app-build/bridge.js.map +1 -0
  55. package/dist/app-build/build-service.d.ts +66 -0
  56. package/dist/app-build/build-service.d.ts.map +1 -0
  57. package/dist/app-build/build-service.js +249 -0
  58. package/dist/app-build/build-service.js.map +1 -0
  59. package/dist/app-build/build.d.ts +115 -0
  60. package/dist/app-build/build.d.ts.map +1 -0
  61. package/dist/app-build/build.js +901 -0
  62. package/dist/app-build/build.js.map +1 -0
  63. package/dist/app-build/interactions.d.ts +20 -0
  64. package/dist/app-build/interactions.d.ts.map +1 -0
  65. package/dist/app-build/interactions.js +121 -0
  66. package/dist/app-build/interactions.js.map +1 -0
  67. package/dist/app-build/judge.d.ts +113 -0
  68. package/dist/app-build/judge.d.ts.map +1 -0
  69. package/dist/app-build/judge.js +318 -0
  70. package/dist/app-build/judge.js.map +1 -0
  71. package/dist/app-build/markdown.d.ts +10 -0
  72. package/dist/app-build/markdown.d.ts.map +1 -0
  73. package/dist/app-build/markdown.js +65 -0
  74. package/dist/app-build/markdown.js.map +1 -0
  75. package/dist/app-build/spec.d.ts +228 -0
  76. package/dist/app-build/spec.d.ts.map +1 -0
  77. package/dist/app-build/spec.js +651 -0
  78. package/dist/app-build/spec.js.map +1 -0
  79. package/dist/app-build/tool-loop.d.ts +84 -0
  80. package/dist/app-build/tool-loop.d.ts.map +1 -0
  81. package/dist/app-build/tool-loop.js +113 -0
  82. package/dist/app-build/tool-loop.js.map +1 -0
  83. package/dist/app-build/types.d.ts +215 -0
  84. package/dist/app-build/types.d.ts.map +1 -0
  85. package/dist/app-build/types.js +28 -0
  86. package/dist/app-build/types.js.map +1 -0
  87. package/dist/author-graph.d.ts +90 -0
  88. package/dist/author-graph.d.ts.map +1 -0
  89. package/dist/author-graph.js +317 -0
  90. package/dist/author-graph.js.map +1 -0
  91. package/dist/background-subtasks.d.ts +79 -0
  92. package/dist/background-subtasks.d.ts.map +1 -0
  93. package/dist/background-subtasks.js +139 -0
  94. package/dist/background-subtasks.js.map +1 -0
  95. package/dist/blender-gate.d.ts +21 -0
  96. package/dist/blender-gate.d.ts.map +1 -0
  97. package/dist/blender-gate.js +27 -0
  98. package/dist/blender-gate.js.map +1 -0
  99. package/dist/browser-gate.d.ts +28 -0
  100. package/dist/browser-gate.d.ts.map +1 -0
  101. package/dist/browser-gate.js +34 -0
  102. package/dist/browser-gate.js.map +1 -0
  103. package/dist/capabilities/GamePublishRequest.d.ts +14 -0
  104. package/dist/capabilities/GamePublishRequest.d.ts.map +1 -0
  105. package/dist/capabilities/GamePublishRequest.js +2 -0
  106. package/dist/capabilities/GamePublishRequest.js.map +1 -0
  107. package/dist/capabilities/adapters.d.ts +27 -0
  108. package/dist/capabilities/adapters.d.ts.map +1 -0
  109. package/dist/capabilities/adapters.js +39 -0
  110. package/dist/capabilities/adapters.js.map +1 -0
  111. package/dist/capabilities/agent-activity.d.ts +27 -0
  112. package/dist/capabilities/agent-activity.d.ts.map +1 -0
  113. package/dist/capabilities/agent-activity.js +103 -0
  114. package/dist/capabilities/agent-activity.js.map +1 -0
  115. package/dist/capabilities/agentic-storyboard-finish.d.ts +67 -0
  116. package/dist/capabilities/agentic-storyboard-finish.d.ts.map +1 -0
  117. package/dist/capabilities/agentic-storyboard-finish.js +1321 -0
  118. package/dist/capabilities/agentic-storyboard-finish.js.map +1 -0
  119. package/dist/capabilities/agents.d.ts +81 -0
  120. package/dist/capabilities/agents.d.ts.map +1 -0
  121. package/dist/capabilities/agents.js +376 -0
  122. package/dist/capabilities/agents.js.map +1 -0
  123. package/dist/capabilities/agents.specs.d.ts +30 -0
  124. package/dist/capabilities/agents.specs.d.ts.map +1 -0
  125. package/dist/capabilities/agents.specs.js +313 -0
  126. package/dist/capabilities/agents.specs.js.map +1 -0
  127. package/dist/capabilities/analysis.d.ts +93 -0
  128. package/dist/capabilities/analysis.d.ts.map +1 -0
  129. package/dist/capabilities/analysis.js +823 -0
  130. package/dist/capabilities/analysis.js.map +1 -0
  131. package/dist/capabilities/analysis.specs.d.ts +39 -0
  132. package/dist/capabilities/analysis.specs.d.ts.map +1 -0
  133. package/dist/capabilities/analysis.specs.js +217 -0
  134. package/dist/capabilities/analysis.specs.js.map +1 -0
  135. package/dist/capabilities/apify.d.ts +34 -0
  136. package/dist/capabilities/apify.d.ts.map +1 -0
  137. package/dist/capabilities/apify.js +449 -0
  138. package/dist/capabilities/apify.js.map +1 -0
  139. package/dist/capabilities/apify.specs.d.ts +28 -0
  140. package/dist/capabilities/apify.specs.d.ts.map +1 -0
  141. package/dist/capabilities/apify.specs.js +232 -0
  142. package/dist/capabilities/apify.specs.js.map +1 -0
  143. package/dist/capabilities/apps.d.ts +40 -0
  144. package/dist/capabilities/apps.d.ts.map +1 -0
  145. package/dist/capabilities/apps.js +415 -0
  146. package/dist/capabilities/apps.js.map +1 -0
  147. package/dist/capabilities/apps.specs.d.ts +23 -0
  148. package/dist/capabilities/apps.specs.d.ts.map +1 -0
  149. package/dist/capabilities/apps.specs.js +236 -0
  150. package/dist/capabilities/apps.specs.js.map +1 -0
  151. package/dist/capabilities/args.d.ts +62 -0
  152. package/dist/capabilities/args.d.ts.map +1 -0
  153. package/dist/capabilities/args.js +215 -0
  154. package/dist/capabilities/args.js.map +1 -0
  155. package/dist/capabilities/assets.d.ts +45 -0
  156. package/dist/capabilities/assets.d.ts.map +1 -0
  157. package/dist/capabilities/assets.js +952 -0
  158. package/dist/capabilities/assets.js.map +1 -0
  159. package/dist/capabilities/assets.specs.d.ts +54 -0
  160. package/dist/capabilities/assets.specs.d.ts.map +1 -0
  161. package/dist/capabilities/assets.specs.js +291 -0
  162. package/dist/capabilities/assets.specs.js.map +1 -0
  163. package/dist/capabilities/background-generation.d.ts +14 -0
  164. package/dist/capabilities/background-generation.d.ts.map +1 -0
  165. package/dist/capabilities/background-generation.js +29 -0
  166. package/dist/capabilities/background-generation.js.map +1 -0
  167. package/dist/capabilities/browser.d.ts +30 -0
  168. package/dist/capabilities/browser.d.ts.map +1 -0
  169. package/dist/capabilities/browser.js +250 -0
  170. package/dist/capabilities/browser.js.map +1 -0
  171. package/dist/capabilities/browser.specs.d.ts +37 -0
  172. package/dist/capabilities/browser.specs.d.ts.map +1 -0
  173. package/dist/capabilities/browser.specs.js +173 -0
  174. package/dist/capabilities/browser.specs.js.map +1 -0
  175. package/dist/capabilities/code-grading.d.ts +68 -0
  176. package/dist/capabilities/code-grading.d.ts.map +1 -0
  177. package/dist/capabilities/code-grading.js +75 -0
  178. package/dist/capabilities/code-grading.js.map +1 -0
  179. package/dist/capabilities/code.d.ts +61 -0
  180. package/dist/capabilities/code.d.ts.map +1 -0
  181. package/dist/capabilities/code.js +366 -0
  182. package/dist/capabilities/code.js.map +1 -0
  183. package/dist/capabilities/code.specs.d.ts +22 -0
  184. package/dist/capabilities/code.specs.d.ts.map +1 -0
  185. package/dist/capabilities/code.specs.js +175 -0
  186. package/dist/capabilities/code.specs.js.map +1 -0
  187. package/dist/capabilities/collections.d.ts +44 -0
  188. package/dist/capabilities/collections.d.ts.map +1 -0
  189. package/dist/capabilities/collections.js +432 -0
  190. package/dist/capabilities/collections.js.map +1 -0
  191. package/dist/capabilities/collections.specs.d.ts +25 -0
  192. package/dist/capabilities/collections.specs.d.ts.map +1 -0
  193. package/dist/capabilities/collections.specs.js +299 -0
  194. package/dist/capabilities/collections.specs.js.map +1 -0
  195. package/dist/capabilities/compositions.d.ts +57 -0
  196. package/dist/capabilities/compositions.d.ts.map +1 -0
  197. package/dist/capabilities/compositions.js +384 -0
  198. package/dist/capabilities/compositions.js.map +1 -0
  199. package/dist/capabilities/compositions.specs.d.ts +22 -0
  200. package/dist/capabilities/compositions.specs.d.ts.map +1 -0
  201. package/dist/capabilities/compositions.specs.js +126 -0
  202. package/dist/capabilities/compositions.specs.js.map +1 -0
  203. package/dist/capabilities/concurrency.d.ts +12 -0
  204. package/dist/capabilities/concurrency.d.ts.map +1 -0
  205. package/dist/capabilities/concurrency.js +30 -0
  206. package/dist/capabilities/concurrency.js.map +1 -0
  207. package/dist/capabilities/costs.d.ts +20 -0
  208. package/dist/capabilities/costs.d.ts.map +1 -0
  209. package/dist/capabilities/costs.js +40 -0
  210. package/dist/capabilities/costs.js.map +1 -0
  211. package/dist/capabilities/costs.specs.d.ts +12 -0
  212. package/dist/capabilities/costs.specs.d.ts.map +1 -0
  213. package/dist/capabilities/costs.specs.js +35 -0
  214. package/dist/capabilities/costs.specs.js.map +1 -0
  215. package/dist/capabilities/dispatcher.d.ts +57 -0
  216. package/dist/capabilities/dispatcher.d.ts.map +1 -0
  217. package/dist/capabilities/dispatcher.js +117 -0
  218. package/dist/capabilities/dispatcher.js.map +1 -0
  219. package/dist/capabilities/documents.d.ts +25 -0
  220. package/dist/capabilities/documents.d.ts.map +1 -0
  221. package/dist/capabilities/documents.js +278 -0
  222. package/dist/capabilities/documents.js.map +1 -0
  223. package/dist/capabilities/documents.specs.d.ts +18 -0
  224. package/dist/capabilities/documents.specs.d.ts.map +1 -0
  225. package/dist/capabilities/documents.specs.js +201 -0
  226. package/dist/capabilities/documents.specs.js.map +1 -0
  227. package/dist/capabilities/email.d.ts +23 -0
  228. package/dist/capabilities/email.d.ts.map +1 -0
  229. package/dist/capabilities/email.js +226 -0
  230. package/dist/capabilities/email.js.map +1 -0
  231. package/dist/capabilities/email.specs.d.ts +16 -0
  232. package/dist/capabilities/email.specs.d.ts.map +1 -0
  233. package/dist/capabilities/email.specs.js +102 -0
  234. package/dist/capabilities/email.specs.js.map +1 -0
  235. package/dist/capabilities/entities.d.ts +52 -0
  236. package/dist/capabilities/entities.d.ts.map +1 -0
  237. package/dist/capabilities/entities.js +478 -0
  238. package/dist/capabilities/entities.js.map +1 -0
  239. package/dist/capabilities/entities.specs.d.ts +25 -0
  240. package/dist/capabilities/entities.specs.d.ts.map +1 -0
  241. package/dist/capabilities/entities.specs.js +247 -0
  242. package/dist/capabilities/entities.specs.js.map +1 -0
  243. package/dist/capabilities/errors.d.ts +19 -0
  244. package/dist/capabilities/errors.d.ts.map +1 -0
  245. package/dist/capabilities/errors.js +109 -0
  246. package/dist/capabilities/errors.js.map +1 -0
  247. package/dist/capabilities/errors.specs.d.ts +11 -0
  248. package/dist/capabilities/errors.specs.d.ts.map +1 -0
  249. package/dist/capabilities/errors.specs.js +100 -0
  250. package/dist/capabilities/errors.specs.js.map +1 -0
  251. package/dist/capabilities/example-timelines.d.ts +3 -0
  252. package/dist/capabilities/example-timelines.d.ts.map +1 -0
  253. package/dist/capabilities/example-timelines.js +233 -0
  254. package/dist/capabilities/example-timelines.js.map +1 -0
  255. package/dist/capabilities/example-timelines.specs.d.ts +6 -0
  256. package/dist/capabilities/example-timelines.specs.d.ts.map +1 -0
  257. package/dist/capabilities/example-timelines.specs.js +71 -0
  258. package/dist/capabilities/example-timelines.specs.js.map +1 -0
  259. package/dist/capabilities/files.d.ts +53 -0
  260. package/dist/capabilities/files.d.ts.map +1 -0
  261. package/dist/capabilities/files.js +1172 -0
  262. package/dist/capabilities/files.js.map +1 -0
  263. package/dist/capabilities/files.specs.d.ts +28 -0
  264. package/dist/capabilities/files.specs.d.ts.map +1 -0
  265. package/dist/capabilities/files.specs.js +259 -0
  266. package/dist/capabilities/files.specs.js.map +1 -0
  267. package/dist/capabilities/finish-storyboard.d.ts +5 -0
  268. package/dist/capabilities/finish-storyboard.d.ts.map +1 -0
  269. package/dist/capabilities/finish-storyboard.js +278 -0
  270. package/dist/capabilities/finish-storyboard.js.map +1 -0
  271. package/dist/capabilities/flow.d.ts +93 -0
  272. package/dist/capabilities/flow.d.ts.map +1 -0
  273. package/dist/capabilities/flow.js +285 -0
  274. package/dist/capabilities/flow.js.map +1 -0
  275. package/dist/capabilities/flow.specs.d.ts +25 -0
  276. package/dist/capabilities/flow.specs.d.ts.map +1 -0
  277. package/dist/capabilities/flow.specs.js +114 -0
  278. package/dist/capabilities/flow.specs.js.map +1 -0
  279. package/dist/capabilities/game-asset-source.d.ts +31 -0
  280. package/dist/capabilities/game-asset-source.d.ts.map +1 -0
  281. package/dist/capabilities/game-asset-source.js +81 -0
  282. package/dist/capabilities/game-asset-source.js.map +1 -0
  283. package/dist/capabilities/game.d.ts +24 -0
  284. package/dist/capabilities/game.d.ts.map +1 -0
  285. package/dist/capabilities/game.js +1432 -0
  286. package/dist/capabilities/game.js.map +1 -0
  287. package/dist/capabilities/game.specs.d.ts +5 -0
  288. package/dist/capabilities/game.specs.d.ts.map +1 -0
  289. package/dist/capabilities/game.specs.js +110 -0
  290. package/dist/capabilities/game.specs.js.map +1 -0
  291. package/dist/capabilities/game3d.d.ts +17 -0
  292. package/dist/capabilities/game3d.d.ts.map +1 -0
  293. package/dist/capabilities/game3d.js +433 -0
  294. package/dist/capabilities/game3d.js.map +1 -0
  295. package/dist/capabilities/gate-from-context.d.ts +39 -0
  296. package/dist/capabilities/gate-from-context.d.ts.map +1 -0
  297. package/dist/capabilities/gate-from-context.js +97 -0
  298. package/dist/capabilities/gate-from-context.js.map +1 -0
  299. package/dist/capabilities/generations.d.ts +81 -0
  300. package/dist/capabilities/generations.d.ts.map +1 -0
  301. package/dist/capabilities/generations.js +387 -0
  302. package/dist/capabilities/generations.js.map +1 -0
  303. package/dist/capabilities/generations.specs.d.ts +62 -0
  304. package/dist/capabilities/generations.specs.d.ts.map +1 -0
  305. package/dist/capabilities/generations.specs.js +230 -0
  306. package/dist/capabilities/generations.specs.js.map +1 -0
  307. package/dist/capabilities/google.d.ts +50 -0
  308. package/dist/capabilities/google.d.ts.map +1 -0
  309. package/dist/capabilities/google.js +246 -0
  310. package/dist/capabilities/google.js.map +1 -0
  311. package/dist/capabilities/google.specs.d.ts +52 -0
  312. package/dist/capabilities/google.specs.d.ts.map +1 -0
  313. package/dist/capabilities/google.specs.js +391 -0
  314. package/dist/capabilities/google.specs.js.map +1 -0
  315. package/dist/capabilities/html-text.d.ts +28 -0
  316. package/dist/capabilities/html-text.d.ts.map +1 -0
  317. package/dist/capabilities/html-text.js +76 -0
  318. package/dist/capabilities/html-text.js.map +1 -0
  319. package/dist/capabilities/index.d.ts +19 -0
  320. package/dist/capabilities/index.d.ts.map +1 -0
  321. package/dist/capabilities/index.js +14 -0
  322. package/dist/capabilities/index.js.map +1 -0
  323. package/dist/capabilities/invoke.d.ts +78 -0
  324. package/dist/capabilities/invoke.d.ts.map +1 -0
  325. package/dist/capabilities/invoke.js +251 -0
  326. package/dist/capabilities/invoke.js.map +1 -0
  327. package/dist/capabilities/jobs.d.ts +32 -0
  328. package/dist/capabilities/jobs.d.ts.map +1 -0
  329. package/dist/capabilities/jobs.js +167 -0
  330. package/dist/capabilities/jobs.js.map +1 -0
  331. package/dist/capabilities/jobs.specs.d.ts +20 -0
  332. package/dist/capabilities/jobs.specs.d.ts.map +1 -0
  333. package/dist/capabilities/jobs.specs.js +105 -0
  334. package/dist/capabilities/jobs.specs.js.map +1 -0
  335. package/dist/capabilities/js-scripts.d.ts +108 -0
  336. package/dist/capabilities/js-scripts.d.ts.map +1 -0
  337. package/dist/capabilities/js-scripts.js +807 -0
  338. package/dist/capabilities/js-scripts.js.map +1 -0
  339. package/dist/capabilities/js-scripts.specs.d.ts +52 -0
  340. package/dist/capabilities/js-scripts.specs.d.ts.map +1 -0
  341. package/dist/capabilities/js-scripts.specs.js +394 -0
  342. package/dist/capabilities/js-scripts.specs.js.map +1 -0
  343. package/dist/capabilities/lazy-tool.d.ts +41 -0
  344. package/dist/capabilities/lazy-tool.d.ts.map +1 -0
  345. package/dist/capabilities/lazy-tool.js +82 -0
  346. package/dist/capabilities/lazy-tool.js.map +1 -0
  347. package/dist/capabilities/legacy-tools.d.ts +15 -0
  348. package/dist/capabilities/legacy-tools.d.ts.map +1 -0
  349. package/dist/capabilities/legacy-tools.js +98 -0
  350. package/dist/capabilities/legacy-tools.js.map +1 -0
  351. package/dist/capabilities/local-browser.d.ts +24 -0
  352. package/dist/capabilities/local-browser.d.ts.map +1 -0
  353. package/dist/capabilities/local-browser.js +105 -0
  354. package/dist/capabilities/local-browser.js.map +1 -0
  355. package/dist/capabilities/media.d.ts +112 -0
  356. package/dist/capabilities/media.d.ts.map +1 -0
  357. package/dist/capabilities/media.js +2258 -0
  358. package/dist/capabilities/media.js.map +1 -0
  359. package/dist/capabilities/media.specs.d.ts +65 -0
  360. package/dist/capabilities/media.specs.d.ts.map +1 -0
  361. package/dist/capabilities/media.specs.js +779 -0
  362. package/dist/capabilities/media.specs.js.map +1 -0
  363. package/dist/capabilities/memory.d.ts +31 -0
  364. package/dist/capabilities/memory.d.ts.map +1 -0
  365. package/dist/capabilities/memory.js +403 -0
  366. package/dist/capabilities/memory.js.map +1 -0
  367. package/dist/capabilities/memory.specs.d.ts +55 -0
  368. package/dist/capabilities/memory.specs.d.ts.map +1 -0
  369. package/dist/capabilities/memory.specs.js +208 -0
  370. package/dist/capabilities/memory.specs.js.map +1 -0
  371. package/dist/capabilities/model3d.d.ts +29 -0
  372. package/dist/capabilities/model3d.d.ts.map +1 -0
  373. package/dist/capabilities/model3d.js +482 -0
  374. package/dist/capabilities/model3d.js.map +1 -0
  375. package/dist/capabilities/model3d.specs.d.ts +28 -0
  376. package/dist/capabilities/model3d.specs.d.ts.map +1 -0
  377. package/dist/capabilities/model3d.specs.js +305 -0
  378. package/dist/capabilities/model3d.specs.js.map +1 -0
  379. package/dist/capabilities/models.d.ts +138 -0
  380. package/dist/capabilities/models.d.ts.map +1 -0
  381. package/dist/capabilities/models.js +805 -0
  382. package/dist/capabilities/models.js.map +1 -0
  383. package/dist/capabilities/models.specs.d.ts +21 -0
  384. package/dist/capabilities/models.specs.d.ts.map +1 -0
  385. package/dist/capabilities/models.specs.js +141 -0
  386. package/dist/capabilities/models.specs.js.map +1 -0
  387. package/dist/capabilities/nodes.d.ts +26 -0
  388. package/dist/capabilities/nodes.d.ts.map +1 -0
  389. package/dist/capabilities/nodes.js +266 -0
  390. package/dist/capabilities/nodes.js.map +1 -0
  391. package/dist/capabilities/nodes.specs.d.ts +20 -0
  392. package/dist/capabilities/nodes.specs.d.ts.map +1 -0
  393. package/dist/capabilities/nodes.specs.js +106 -0
  394. package/dist/capabilities/nodes.specs.js.map +1 -0
  395. package/dist/capabilities/packs.d.ts +69 -0
  396. package/dist/capabilities/packs.d.ts.map +1 -0
  397. package/dist/capabilities/packs.js +246 -0
  398. package/dist/capabilities/packs.js.map +1 -0
  399. package/dist/capabilities/packs.specs.d.ts +27 -0
  400. package/dist/capabilities/packs.specs.d.ts.map +1 -0
  401. package/dist/capabilities/packs.specs.js +64 -0
  402. package/dist/capabilities/packs.specs.js.map +1 -0
  403. package/dist/capabilities/project-scope.d.ts +12 -0
  404. package/dist/capabilities/project-scope.d.ts.map +1 -0
  405. package/dist/capabilities/project-scope.js +19 -0
  406. package/dist/capabilities/project-scope.js.map +1 -0
  407. package/dist/capabilities/projects.d.ts +23 -0
  408. package/dist/capabilities/projects.d.ts.map +1 -0
  409. package/dist/capabilities/projects.js +206 -0
  410. package/dist/capabilities/projects.js.map +1 -0
  411. package/dist/capabilities/projects.specs.d.ts +23 -0
  412. package/dist/capabilities/projects.specs.d.ts.map +1 -0
  413. package/dist/capabilities/projects.specs.js +118 -0
  414. package/dist/capabilities/projects.specs.js.map +1 -0
  415. package/dist/capabilities/registry.d.ts +111 -0
  416. package/dist/capabilities/registry.d.ts.map +1 -0
  417. package/dist/capabilities/registry.js +473 -0
  418. package/dist/capabilities/registry.js.map +1 -0
  419. package/dist/capabilities/run-agent.d.ts +19 -0
  420. package/dist/capabilities/run-agent.d.ts.map +1 -0
  421. package/dist/capabilities/run-agent.js +183 -0
  422. package/dist/capabilities/run-agent.js.map +1 -0
  423. package/dist/capabilities/runs.d.ts +9 -0
  424. package/dist/capabilities/runs.d.ts.map +1 -0
  425. package/dist/capabilities/runs.js +46 -0
  426. package/dist/capabilities/runs.js.map +1 -0
  427. package/dist/capabilities/runs.specs.d.ts +39 -0
  428. package/dist/capabilities/runs.specs.d.ts.map +1 -0
  429. package/dist/capabilities/runs.specs.js +52 -0
  430. package/dist/capabilities/runs.specs.js.map +1 -0
  431. package/dist/capabilities/script-link.d.ts +22 -0
  432. package/dist/capabilities/script-link.d.ts.map +1 -0
  433. package/dist/capabilities/script-link.js +35 -0
  434. package/dist/capabilities/script-link.js.map +1 -0
  435. package/dist/capabilities/scripts.d.ts +43 -0
  436. package/dist/capabilities/scripts.d.ts.map +1 -0
  437. package/dist/capabilities/scripts.js +1795 -0
  438. package/dist/capabilities/scripts.js.map +1 -0
  439. package/dist/capabilities/scripts.specs.d.ts +40 -0
  440. package/dist/capabilities/scripts.specs.d.ts.map +1 -0
  441. package/dist/capabilities/scripts.specs.js +319 -0
  442. package/dist/capabilities/scripts.specs.js.map +1 -0
  443. package/dist/capabilities/serpapi.d.ts +42 -0
  444. package/dist/capabilities/serpapi.d.ts.map +1 -0
  445. package/dist/capabilities/serpapi.js +262 -0
  446. package/dist/capabilities/serpapi.js.map +1 -0
  447. package/dist/capabilities/serpapi.specs.d.ts +24 -0
  448. package/dist/capabilities/serpapi.specs.d.ts.map +1 -0
  449. package/dist/capabilities/serpapi.specs.js +174 -0
  450. package/dist/capabilities/serpapi.specs.js.map +1 -0
  451. package/dist/capabilities/settings.d.ts +48 -0
  452. package/dist/capabilities/settings.d.ts.map +1 -0
  453. package/dist/capabilities/settings.js +226 -0
  454. package/dist/capabilities/settings.js.map +1 -0
  455. package/dist/capabilities/settings.specs.d.ts +42 -0
  456. package/dist/capabilities/settings.specs.d.ts.map +1 -0
  457. package/dist/capabilities/settings.specs.js +126 -0
  458. package/dist/capabilities/settings.specs.js.map +1 -0
  459. package/dist/capabilities/shared.d.ts +35 -0
  460. package/dist/capabilities/shared.d.ts.map +1 -0
  461. package/dist/capabilities/shared.js +165 -0
  462. package/dist/capabilities/shared.js.map +1 -0
  463. package/dist/capabilities/shared.specs.d.ts +19 -0
  464. package/dist/capabilities/shared.specs.d.ts.map +1 -0
  465. package/dist/capabilities/shared.specs.js +134 -0
  466. package/dist/capabilities/shared.specs.js.map +1 -0
  467. package/dist/capabilities/sketches.d.ts +52 -0
  468. package/dist/capabilities/sketches.d.ts.map +1 -0
  469. package/dist/capabilities/sketches.js +1165 -0
  470. package/dist/capabilities/sketches.js.map +1 -0
  471. package/dist/capabilities/sketches.specs.d.ts +44 -0
  472. package/dist/capabilities/sketches.specs.d.ts.map +1 -0
  473. package/dist/capabilities/sketches.specs.js +392 -0
  474. package/dist/capabilities/sketches.specs.js.map +1 -0
  475. package/dist/capabilities/skills.d.ts +28 -0
  476. package/dist/capabilities/skills.d.ts.map +1 -0
  477. package/dist/capabilities/skills.js +289 -0
  478. package/dist/capabilities/skills.js.map +1 -0
  479. package/dist/capabilities/skills.specs.d.ts +17 -0
  480. package/dist/capabilities/skills.specs.d.ts.map +1 -0
  481. package/dist/capabilities/skills.specs.js +108 -0
  482. package/dist/capabilities/skills.specs.js.map +1 -0
  483. package/dist/capabilities/storyboard-layout-check.d.ts +33 -0
  484. package/dist/capabilities/storyboard-layout-check.d.ts.map +1 -0
  485. package/dist/capabilities/storyboard-layout-check.js +229 -0
  486. package/dist/capabilities/storyboard-layout-check.js.map +1 -0
  487. package/dist/capabilities/storyboard-measured-sources.d.ts +10 -0
  488. package/dist/capabilities/storyboard-measured-sources.d.ts.map +1 -0
  489. package/dist/capabilities/storyboard-measured-sources.js +67 -0
  490. package/dist/capabilities/storyboard-measured-sources.js.map +1 -0
  491. package/dist/capabilities/storyboard-review-times.d.ts +4 -0
  492. package/dist/capabilities/storyboard-review-times.d.ts.map +1 -0
  493. package/dist/capabilities/storyboard-review-times.js +39 -0
  494. package/dist/capabilities/storyboard-review-times.js.map +1 -0
  495. package/dist/capabilities/storyboards.d.ts +52 -0
  496. package/dist/capabilities/storyboards.d.ts.map +1 -0
  497. package/dist/capabilities/storyboards.js +2467 -0
  498. package/dist/capabilities/storyboards.js.map +1 -0
  499. package/dist/capabilities/storyboards.specs.d.ts +45 -0
  500. package/dist/capabilities/storyboards.specs.d.ts.map +1 -0
  501. package/dist/capabilities/storyboards.specs.js +457 -0
  502. package/dist/capabilities/storyboards.specs.js.map +1 -0
  503. package/dist/capabilities/threads.d.ts +25 -0
  504. package/dist/capabilities/threads.d.ts.map +1 -0
  505. package/dist/capabilities/threads.js +240 -0
  506. package/dist/capabilities/threads.js.map +1 -0
  507. package/dist/capabilities/threads.specs.d.ts +26 -0
  508. package/dist/capabilities/threads.specs.d.ts.map +1 -0
  509. package/dist/capabilities/threads.specs.js +108 -0
  510. package/dist/capabilities/threads.specs.js.map +1 -0
  511. package/dist/capabilities/timeline-audio-bake.d.ts +114 -0
  512. package/dist/capabilities/timeline-audio-bake.d.ts.map +1 -0
  513. package/dist/capabilities/timeline-audio-bake.js +188 -0
  514. package/dist/capabilities/timeline-audio-bake.js.map +1 -0
  515. package/dist/capabilities/timeline-bake.d.ts +21 -0
  516. package/dist/capabilities/timeline-bake.d.ts.map +1 -0
  517. package/dist/capabilities/timeline-bake.js +118 -0
  518. package/dist/capabilities/timeline-bake.js.map +1 -0
  519. package/dist/capabilities/timeline-bridge.d.ts +359 -0
  520. package/dist/capabilities/timeline-bridge.d.ts.map +1 -0
  521. package/dist/capabilities/timeline-bridge.js +1016 -0
  522. package/dist/capabilities/timeline-bridge.js.map +1 -0
  523. package/dist/capabilities/timeline-clip-frames.d.ts +17 -0
  524. package/dist/capabilities/timeline-clip-frames.d.ts.map +1 -0
  525. package/dist/capabilities/timeline-clip-frames.js +84 -0
  526. package/dist/capabilities/timeline-clip-frames.js.map +1 -0
  527. package/dist/capabilities/timeline-isolate-subject.d.ts +157 -0
  528. package/dist/capabilities/timeline-isolate-subject.d.ts.map +1 -0
  529. package/dist/capabilities/timeline-isolate-subject.js +293 -0
  530. package/dist/capabilities/timeline-isolate-subject.js.map +1 -0
  531. package/dist/capabilities/timeline-media-edit.d.ts +8 -0
  532. package/dist/capabilities/timeline-media-edit.d.ts.map +1 -0
  533. package/dist/capabilities/timeline-media-edit.js +94 -0
  534. package/dist/capabilities/timeline-media-edit.js.map +1 -0
  535. package/dist/capabilities/timeline-native-media.d.ts +4 -0
  536. package/dist/capabilities/timeline-native-media.d.ts.map +1 -0
  537. package/dist/capabilities/timeline-native-media.js +960 -0
  538. package/dist/capabilities/timeline-native-media.js.map +1 -0
  539. package/dist/capabilities/timeline-track-object.d.ts +83 -0
  540. package/dist/capabilities/timeline-track-object.d.ts.map +1 -0
  541. package/dist/capabilities/timeline-track-object.js +195 -0
  542. package/dist/capabilities/timeline-track-object.js.map +1 -0
  543. package/dist/capabilities/timelines.d.ts +250 -0
  544. package/dist/capabilities/timelines.d.ts.map +1 -0
  545. package/dist/capabilities/timelines.js +2825 -0
  546. package/dist/capabilities/timelines.js.map +1 -0
  547. package/dist/capabilities/timelines.specs.d.ts +142 -0
  548. package/dist/capabilities/timelines.specs.d.ts.map +1 -0
  549. package/dist/capabilities/timelines.specs.js +1527 -0
  550. package/dist/capabilities/timelines.specs.js.map +1 -0
  551. package/dist/capabilities/types.d.ts +199 -0
  552. package/dist/capabilities/types.d.ts.map +1 -0
  553. package/dist/capabilities/types.js +19 -0
  554. package/dist/capabilities/types.js.map +1 -0
  555. package/dist/capabilities/ui.d.ts +38 -0
  556. package/dist/capabilities/ui.d.ts.map +1 -0
  557. package/dist/capabilities/ui.js +150 -0
  558. package/dist/capabilities/ui.js.map +1 -0
  559. package/dist/capabilities/ui.specs.d.ts +22 -0
  560. package/dist/capabilities/ui.specs.d.ts.map +1 -0
  561. package/dist/capabilities/ui.specs.js +59 -0
  562. package/dist/capabilities/ui.specs.js.map +1 -0
  563. package/dist/capabilities/video-production-acceptance.d.ts +27 -0
  564. package/dist/capabilities/video-production-acceptance.d.ts.map +1 -0
  565. package/dist/capabilities/video-production-acceptance.js +41 -0
  566. package/dist/capabilities/video-production-acceptance.js.map +1 -0
  567. package/dist/capabilities/video-production.d.ts +179 -0
  568. package/dist/capabilities/video-production.d.ts.map +1 -0
  569. package/dist/capabilities/video-production.js +1492 -0
  570. package/dist/capabilities/video-production.js.map +1 -0
  571. package/dist/capabilities/video-production.specs.d.ts +13 -0
  572. package/dist/capabilities/video-production.specs.d.ts.map +1 -0
  573. package/dist/capabilities/video-production.specs.js +256 -0
  574. package/dist/capabilities/video-production.specs.js.map +1 -0
  575. package/dist/capabilities/web.d.ts +86 -0
  576. package/dist/capabilities/web.d.ts.map +1 -0
  577. package/dist/capabilities/web.js +850 -0
  578. package/dist/capabilities/web.js.map +1 -0
  579. package/dist/capabilities/web.specs.d.ts +33 -0
  580. package/dist/capabilities/web.specs.d.ts.map +1 -0
  581. package/dist/capabilities/web.specs.js +286 -0
  582. package/dist/capabilities/web.specs.js.map +1 -0
  583. package/dist/capabilities/workflows.d.ts +58 -0
  584. package/dist/capabilities/workflows.d.ts.map +1 -0
  585. package/dist/capabilities/workflows.js +1557 -0
  586. package/dist/capabilities/workflows.js.map +1 -0
  587. package/dist/capabilities/workflows.specs.d.ts +63 -0
  588. package/dist/capabilities/workflows.specs.d.ts.map +1 -0
  589. package/dist/capabilities/workflows.specs.js +858 -0
  590. package/dist/capabilities/workflows.specs.js.map +1 -0
  591. package/dist/code-gen/analyze.d.ts +26 -0
  592. package/dist/code-gen/analyze.d.ts.map +1 -0
  593. package/dist/code-gen/analyze.js +79 -0
  594. package/dist/code-gen/analyze.js.map +1 -0
  595. package/dist/code-gen/port-types.d.ts +58 -0
  596. package/dist/code-gen/port-types.d.ts.map +1 -0
  597. package/dist/code-gen/port-types.js +115 -0
  598. package/dist/code-gen/port-types.js.map +1 -0
  599. package/dist/code-gen/prompt.d.ts +37 -0
  600. package/dist/code-gen/prompt.d.ts.map +1 -0
  601. package/dist/code-gen/prompt.js +129 -0
  602. package/dist/code-gen/prompt.js.map +1 -0
  603. package/dist/code-gen/sandbox-manifest.d.ts +120 -0
  604. package/dist/code-gen/sandbox-manifest.d.ts.map +1 -0
  605. package/dist/code-gen/sandbox-manifest.js +1023 -0
  606. package/dist/code-gen/sandbox-manifest.js.map +1 -0
  607. package/dist/code-gen/sandbox-prompt.d.ts +26 -0
  608. package/dist/code-gen/sandbox-prompt.d.ts.map +1 -0
  609. package/dist/code-gen/sandbox-prompt.js +126 -0
  610. package/dist/code-gen/sandbox-prompt.js.map +1 -0
  611. package/dist/code-planner.d.ts +72 -0
  612. package/dist/code-planner.d.ts.map +1 -0
  613. package/dist/code-planner.js +271 -0
  614. package/dist/code-planner.js.map +1 -0
  615. package/dist/codeact/action-diagnostics.d.ts +35 -0
  616. package/dist/codeact/action-diagnostics.d.ts.map +1 -0
  617. package/dist/codeact/action-diagnostics.js +197 -0
  618. package/dist/codeact/action-diagnostics.js.map +1 -0
  619. package/dist/codeact/capability-modules.d.ts +66 -0
  620. package/dist/codeact/capability-modules.d.ts.map +1 -0
  621. package/dist/codeact/capability-modules.js +278 -0
  622. package/dist/codeact/capability-modules.js.map +1 -0
  623. package/dist/codeact/chat-codeact.d.ts +104 -0
  624. package/dist/codeact/chat-codeact.d.ts.map +1 -0
  625. package/dist/codeact/chat-codeact.js +424 -0
  626. package/dist/codeact/chat-codeact.js.map +1 -0
  627. package/dist/codeact/codeact-executor.d.ts +247 -0
  628. package/dist/codeact/codeact-executor.d.ts.map +1 -0
  629. package/dist/codeact/codeact-executor.js +1184 -0
  630. package/dist/codeact/codeact-executor.js.map +1 -0
  631. package/dist/codeact/compact-ids.d.ts +28 -0
  632. package/dist/codeact/compact-ids.d.ts.map +1 -0
  633. package/dist/codeact/compact-ids.js +81 -0
  634. package/dist/codeact/compact-ids.js.map +1 -0
  635. package/dist/codeact/execute-code-contract.d.ts +97 -0
  636. package/dist/codeact/execute-code-contract.d.ts.map +1 -0
  637. package/dist/codeact/execute-code-contract.js +225 -0
  638. package/dist/codeact/execute-code-contract.js.map +1 -0
  639. package/dist/codeact/fabric-package.d.ts +29 -0
  640. package/dist/codeact/fabric-package.d.ts.map +1 -0
  641. package/dist/codeact/fabric-package.js +62 -0
  642. package/dist/codeact/fabric-package.js.map +1 -0
  643. package/dist/codeact/flow-package.d.ts +31 -0
  644. package/dist/codeact/flow-package.d.ts.map +1 -0
  645. package/dist/codeact/flow-package.js +80 -0
  646. package/dist/codeact/flow-package.js.map +1 -0
  647. package/dist/codeact/graph-dsl-package.d.ts +42 -0
  648. package/dist/codeact/graph-dsl-package.d.ts.map +1 -0
  649. package/dist/codeact/graph-dsl-package.js +100 -0
  650. package/dist/codeact/graph-dsl-package.js.map +1 -0
  651. package/dist/codeact/graph-model.d.ts +30 -0
  652. package/dist/codeact/graph-model.d.ts.map +1 -0
  653. package/dist/codeact/graph-model.js +407 -0
  654. package/dist/codeact/graph-model.js.map +1 -0
  655. package/dist/codeact/mcp-guest-contract.d.ts +66 -0
  656. package/dist/codeact/mcp-guest-contract.d.ts.map +1 -0
  657. package/dist/codeact/mcp-guest-contract.js +108 -0
  658. package/dist/codeact/mcp-guest-contract.js.map +1 -0
  659. package/dist/codeact/nodetool-api.d.ts +60 -0
  660. package/dist/codeact/nodetool-api.d.ts.map +1 -0
  661. package/dist/codeact/nodetool-api.js +1974 -0
  662. package/dist/codeact/nodetool-api.js.map +1 -0
  663. package/dist/codeact/prompt.d.ts +88 -0
  664. package/dist/codeact/prompt.d.ts.map +1 -0
  665. package/dist/codeact/prompt.js +326 -0
  666. package/dist/codeact/prompt.js.map +1 -0
  667. package/dist/codeact/sandbox-package-docs.d.ts +48 -0
  668. package/dist/codeact/sandbox-package-docs.d.ts.map +1 -0
  669. package/dist/codeact/sandbox-package-docs.js +55 -0
  670. package/dist/codeact/sandbox-package-docs.js.map +1 -0
  671. package/dist/codeact/sandbox-package-listing.d.ts +81 -0
  672. package/dist/codeact/sandbox-package-listing.d.ts.map +1 -0
  673. package/dist/codeact/sandbox-package-listing.js +101 -0
  674. package/dist/codeact/sandbox-package-listing.js.map +1 -0
  675. package/dist/codeact/sandbox-packages.d.ts +72 -0
  676. package/dist/codeact/sandbox-packages.d.ts.map +1 -0
  677. package/dist/codeact/sandbox-packages.js +230 -0
  678. package/dist/codeact/sandbox-packages.js.map +1 -0
  679. package/dist/codeact/timeline-package.d.ts +5 -0
  680. package/dist/codeact/timeline-package.d.ts.map +1 -0
  681. package/dist/codeact/timeline-package.js +10 -0
  682. package/dist/codeact/timeline-package.js.map +1 -0
  683. package/dist/codeact/tool-api.d.ts +200 -0
  684. package/dist/codeact/tool-api.d.ts.map +1 -0
  685. package/dist/codeact/tool-api.js +452 -0
  686. package/dist/codeact/tool-api.js.map +1 -0
  687. package/dist/codeact/tools-prelude.d.ts +32 -0
  688. package/dist/codeact/tools-prelude.d.ts.map +1 -0
  689. package/dist/codeact/tools-prelude.js +65 -0
  690. package/dist/codeact/tools-prelude.js.map +1 -0
  691. package/dist/constants.d.ts +47 -2
  692. package/dist/constants.d.ts.map +1 -1
  693. package/dist/constants.js +64 -2
  694. package/dist/constants.js.map +1 -1
  695. package/dist/custom-animation-bake.d.ts +57 -0
  696. package/dist/custom-animation-bake.d.ts.map +1 -0
  697. package/dist/custom-animation-bake.js +88 -0
  698. package/dist/custom-animation-bake.js.map +1 -0
  699. package/dist/dynamic-slots.d.ts +72 -0
  700. package/dist/dynamic-slots.d.ts.map +1 -0
  701. package/dist/dynamic-slots.js +0 -0
  702. package/dist/dynamic-slots.js.map +1 -0
  703. package/dist/evals/app-build-cases.d.ts +35 -0
  704. package/dist/evals/app-build-cases.d.ts.map +1 -0
  705. package/dist/evals/app-build-cases.js +722 -0
  706. package/dist/evals/app-build-cases.js.map +1 -0
  707. package/dist/evals/app-build-eval.d.ts +208 -0
  708. package/dist/evals/app-build-eval.d.ts.map +1 -0
  709. package/dist/evals/app-build-eval.js +518 -0
  710. package/dist/evals/app-build-eval.js.map +1 -0
  711. package/dist/evals/app-build-plan.d.ts +76 -0
  712. package/dist/evals/app-build-plan.d.ts.map +1 -0
  713. package/dist/evals/app-build-plan.js +140 -0
  714. package/dist/evals/app-build-plan.js.map +1 -0
  715. package/dist/evals/code-gen-cases.d.ts +13 -0
  716. package/dist/evals/code-gen-cases.d.ts.map +1 -0
  717. package/dist/evals/code-gen-cases.js +124 -0
  718. package/dist/evals/code-gen-cases.js.map +1 -0
  719. package/dist/evals/code-gen-eval.d.ts +109 -0
  720. package/dist/evals/code-gen-eval.d.ts.map +1 -0
  721. package/dist/evals/code-gen-eval.js +299 -0
  722. package/dist/evals/code-gen-eval.js.map +1 -0
  723. package/dist/evals/codeact-api-cases.d.ts +14 -0
  724. package/dist/evals/codeact-api-cases.d.ts.map +1 -0
  725. package/dist/evals/codeact-api-cases.js +31 -0
  726. package/dist/evals/codeact-api-cases.js.map +1 -0
  727. package/dist/evals/codeact-api-core.d.ts +23 -0
  728. package/dist/evals/codeact-api-core.d.ts.map +1 -0
  729. package/dist/evals/codeact-api-core.js +1411 -0
  730. package/dist/evals/codeact-api-core.js.map +1 -0
  731. package/dist/evals/codeact-api-runs.d.ts +3 -0
  732. package/dist/evals/codeact-api-runs.d.ts.map +1 -0
  733. package/dist/evals/codeact-api-runs.js +33 -0
  734. package/dist/evals/codeact-api-runs.js.map +1 -0
  735. package/dist/evals/codeact-api-surfaces.d.ts +25 -0
  736. package/dist/evals/codeact-api-surfaces.d.ts.map +1 -0
  737. package/dist/evals/codeact-api-surfaces.js +2191 -0
  738. package/dist/evals/codeact-api-surfaces.js.map +1 -0
  739. package/dist/evals/codeact-cases.d.ts +76 -0
  740. package/dist/evals/codeact-cases.d.ts.map +1 -0
  741. package/dist/evals/codeact-cases.js +151 -0
  742. package/dist/evals/codeact-cases.js.map +1 -0
  743. package/dist/evals/codeact-eval.d.ts +66 -0
  744. package/dist/evals/codeact-eval.d.ts.map +1 -0
  745. package/dist/evals/codeact-eval.js +250 -0
  746. package/dist/evals/codeact-eval.js.map +1 -0
  747. package/dist/evals/codeact-sandbox-pack-cases.d.ts +31 -0
  748. package/dist/evals/codeact-sandbox-pack-cases.d.ts.map +1 -0
  749. package/dist/evals/codeact-sandbox-pack-cases.js +219 -0
  750. package/dist/evals/codeact-sandbox-pack-cases.js.map +1 -0
  751. package/dist/evals/escalation-cases.d.ts +22 -0
  752. package/dist/evals/escalation-cases.d.ts.map +1 -0
  753. package/dist/evals/escalation-cases.js +343 -0
  754. package/dist/evals/escalation-cases.js.map +1 -0
  755. package/dist/evals/escalation.d.ts +92 -0
  756. package/dist/evals/escalation.d.ts.map +1 -0
  757. package/dist/evals/escalation.js +152 -0
  758. package/dist/evals/escalation.js.map +1 -0
  759. package/dist/evals/goal-judge.d.ts +51 -0
  760. package/dist/evals/goal-judge.d.ts.map +1 -0
  761. package/dist/evals/goal-judge.js +152 -0
  762. package/dist/evals/goal-judge.js.map +1 -0
  763. package/dist/evals/graph-e2e-cases.d.ts +21 -0
  764. package/dist/evals/graph-e2e-cases.d.ts.map +1 -0
  765. package/dist/evals/graph-e2e-cases.js +262 -0
  766. package/dist/evals/graph-e2e-cases.js.map +1 -0
  767. package/dist/evals/graph-e2e-eval.d.ts +202 -0
  768. package/dist/evals/graph-e2e-eval.d.ts.map +1 -0
  769. package/dist/evals/graph-e2e-eval.js +438 -0
  770. package/dist/evals/graph-e2e-eval.js.map +1 -0
  771. package/dist/evals/graph-planner-cases.d.ts +12 -0
  772. package/dist/evals/graph-planner-cases.d.ts.map +1 -0
  773. package/dist/evals/graph-planner-cases.js +256 -0
  774. package/dist/evals/graph-planner-cases.js.map +1 -0
  775. package/dist/evals/graph-planner-eval.d.ts +178 -0
  776. package/dist/evals/graph-planner-eval.d.ts.map +1 -0
  777. package/dist/evals/graph-planner-eval.js +495 -0
  778. package/dist/evals/graph-planner-eval.js.map +1 -0
  779. package/dist/evals/planner-tools.d.ts +21 -0
  780. package/dist/evals/planner-tools.d.ts.map +1 -0
  781. package/dist/evals/planner-tools.js +66 -0
  782. package/dist/evals/planner-tools.js.map +1 -0
  783. package/dist/evals/subtask-cases.d.ts +88 -0
  784. package/dist/evals/subtask-cases.d.ts.map +1 -0
  785. package/dist/evals/subtask-cases.js +322 -0
  786. package/dist/evals/subtask-cases.js.map +1 -0
  787. package/dist/evals/subtask-eval.d.ts +129 -0
  788. package/dist/evals/subtask-eval.d.ts.map +1 -0
  789. package/dist/evals/subtask-eval.js +397 -0
  790. package/dist/evals/subtask-eval.js.map +1 -0
  791. package/dist/evals/surfaces/app.d.ts +19 -0
  792. package/dist/evals/surfaces/app.d.ts.map +1 -0
  793. package/dist/evals/surfaces/app.js +341 -0
  794. package/dist/evals/surfaces/app.js.map +1 -0
  795. package/dist/evals/surfaces/creative-pipeline.d.ts +203 -0
  796. package/dist/evals/surfaces/creative-pipeline.d.ts.map +1 -0
  797. package/dist/evals/surfaces/creative-pipeline.js +909 -0
  798. package/dist/evals/surfaces/creative-pipeline.js.map +1 -0
  799. package/dist/evals/surfaces/game.d.ts +5 -0
  800. package/dist/evals/surfaces/game.d.ts.map +1 -0
  801. package/dist/evals/surfaces/game.js +42 -0
  802. package/dist/evals/surfaces/game.js.map +1 -0
  803. package/dist/evals/surfaces/js-script.d.ts +66 -0
  804. package/dist/evals/surfaces/js-script.d.ts.map +1 -0
  805. package/dist/evals/surfaces/js-script.js +407 -0
  806. package/dist/evals/surfaces/js-script.js.map +1 -0
  807. package/dist/evals/surfaces/memory.d.ts +34 -0
  808. package/dist/evals/surfaces/memory.d.ts.map +1 -0
  809. package/dist/evals/surfaces/memory.js +264 -0
  810. package/dist/evals/surfaces/memory.js.map +1 -0
  811. package/dist/evals/surfaces/model3d.d.ts +45 -0
  812. package/dist/evals/surfaces/model3d.d.ts.map +1 -0
  813. package/dist/evals/surfaces/model3d.js +346 -0
  814. package/dist/evals/surfaces/model3d.js.map +1 -0
  815. package/dist/evals/surfaces/script.d.ts +96 -0
  816. package/dist/evals/surfaces/script.d.ts.map +1 -0
  817. package/dist/evals/surfaces/script.js +709 -0
  818. package/dist/evals/surfaces/script.js.map +1 -0
  819. package/dist/evals/surfaces/sketch.d.ts +126 -0
  820. package/dist/evals/surfaces/sketch.d.ts.map +1 -0
  821. package/dist/evals/surfaces/sketch.js +1306 -0
  822. package/dist/evals/surfaces/sketch.js.map +1 -0
  823. package/dist/evals/surfaces/storyboard.d.ts +97 -0
  824. package/dist/evals/surfaces/storyboard.d.ts.map +1 -0
  825. package/dist/evals/surfaces/storyboard.js +693 -0
  826. package/dist/evals/surfaces/storyboard.js.map +1 -0
  827. package/dist/evals/surfaces/timeline.d.ts +63 -0
  828. package/dist/evals/surfaces/timeline.d.ts.map +1 -0
  829. package/dist/evals/surfaces/timeline.js +655 -0
  830. package/dist/evals/surfaces/timeline.js.map +1 -0
  831. package/dist/evals/task-planner-cases.d.ts +57 -0
  832. package/dist/evals/task-planner-cases.d.ts.map +1 -0
  833. package/dist/evals/task-planner-cases.js +117 -0
  834. package/dist/evals/task-planner-cases.js.map +1 -0
  835. package/dist/evals/task-planner-eval.d.ts +101 -0
  836. package/dist/evals/task-planner-eval.d.ts.map +1 -0
  837. package/dist/evals/task-planner-eval.js +380 -0
  838. package/dist/evals/task-planner-eval.js.map +1 -0
  839. package/dist/evals/tool-loop-bridge.d.ts +61 -0
  840. package/dist/evals/tool-loop-bridge.d.ts.map +1 -0
  841. package/dist/evals/tool-loop-bridge.js +129 -0
  842. package/dist/evals/tool-loop-bridge.js.map +1 -0
  843. package/dist/evals/tool-loop-cases.d.ts +21 -0
  844. package/dist/evals/tool-loop-cases.d.ts.map +1 -0
  845. package/dist/evals/tool-loop-cases.js +401 -0
  846. package/dist/evals/tool-loop-cases.js.map +1 -0
  847. package/dist/evals/tool-loop-eval.d.ts +236 -0
  848. package/dist/evals/tool-loop-eval.d.ts.map +1 -0
  849. package/dist/evals/tool-loop-eval.js +378 -0
  850. package/dist/evals/tool-loop-eval.js.map +1 -0
  851. package/dist/evals/tool-loop-permission.d.ts +29 -0
  852. package/dist/evals/tool-loop-permission.d.ts.map +1 -0
  853. package/dist/evals/tool-loop-permission.js +58 -0
  854. package/dist/evals/tool-loop-permission.js.map +1 -0
  855. package/dist/game-authoring.d.ts +4737 -0
  856. package/dist/game-authoring.d.ts.map +1 -0
  857. package/dist/game-authoring.js +146 -0
  858. package/dist/game-authoring.js.map +1 -0
  859. package/dist/game-code-bake.d.ts +26 -0
  860. package/dist/game-code-bake.d.ts.map +1 -0
  861. package/dist/game-code-bake.js +98 -0
  862. package/dist/game-code-bake.js.map +1 -0
  863. package/dist/game-examples.d.ts +1303 -0
  864. package/dist/game-examples.d.ts.map +1 -0
  865. package/dist/game-examples.js +188 -0
  866. package/dist/game-examples.js.map +1 -0
  867. package/dist/graph-builder.d.ts +55 -3
  868. package/dist/graph-builder.d.ts.map +1 -1
  869. package/dist/graph-builder.js +159 -4
  870. package/dist/graph-builder.js.map +1 -1
  871. package/dist/graph-dsl-core.d.ts +25 -0
  872. package/dist/graph-dsl-core.d.ts.map +1 -0
  873. package/dist/graph-dsl-core.js +312 -0
  874. package/dist/graph-dsl-core.js.map +1 -0
  875. package/dist/graph-dsl.d.ts +30 -0
  876. package/dist/graph-dsl.d.ts.map +1 -0
  877. package/dist/graph-dsl.js +116 -0
  878. package/dist/graph-dsl.js.map +1 -0
  879. package/dist/host-binaries.d.ts +6 -0
  880. package/dist/host-binaries.d.ts.map +1 -0
  881. package/dist/host-binaries.js +6 -0
  882. package/dist/host-binaries.js.map +1 -0
  883. package/dist/host-binary-guard.d.ts +100 -0
  884. package/dist/host-binary-guard.d.ts.map +1 -0
  885. package/dist/host-binary-guard.js +205 -0
  886. package/dist/host-binary-guard.js.map +1 -0
  887. package/dist/host-modules/aws.d.ts +57 -0
  888. package/dist/host-modules/aws.d.ts.map +1 -0
  889. package/dist/host-modules/aws.js +309 -0
  890. package/dist/host-modules/aws.js.map +1 -0
  891. package/dist/host-modules/chrono.d.ts +15 -0
  892. package/dist/host-modules/chrono.d.ts.map +1 -0
  893. package/dist/host-modules/chrono.js +35 -0
  894. package/dist/host-modules/chrono.js.map +1 -0
  895. package/dist/host-modules/csv.d.ts +17 -0
  896. package/dist/host-modules/csv.d.ts.map +1 -0
  897. package/dist/host-modules/csv.js +64 -0
  898. package/dist/host-modules/csv.js.map +1 -0
  899. package/dist/host-modules/diff.d.ts +9 -0
  900. package/dist/host-modules/diff.d.ts.map +1 -0
  901. package/dist/host-modules/diff.js +26 -0
  902. package/dist/host-modules/diff.js.map +1 -0
  903. package/dist/host-modules/dispatcher.d.ts +41 -0
  904. package/dist/host-modules/dispatcher.d.ts.map +1 -0
  905. package/dist/host-modules/dispatcher.js +99 -0
  906. package/dist/host-modules/dispatcher.js.map +1 -0
  907. package/dist/host-modules/docx.d.ts +19 -0
  908. package/dist/host-modules/docx.d.ts.map +1 -0
  909. package/dist/host-modules/docx.js +120 -0
  910. package/dist/host-modules/docx.js.map +1 -0
  911. package/dist/host-modules/epub.d.ts +48 -0
  912. package/dist/host-modules/epub.d.ts.map +1 -0
  913. package/dist/host-modules/epub.js +100 -0
  914. package/dist/host-modules/epub.js.map +1 -0
  915. package/dist/host-modules/exif.d.ts +8 -0
  916. package/dist/host-modules/exif.d.ts.map +1 -0
  917. package/dist/host-modules/exif.js +19 -0
  918. package/dist/host-modules/exif.js.map +1 -0
  919. package/dist/host-modules/expr.d.ts +16 -0
  920. package/dist/host-modules/expr.d.ts.map +1 -0
  921. package/dist/host-modules/expr.js +18 -0
  922. package/dist/host-modules/expr.js.map +1 -0
  923. package/dist/host-modules/fabric.d.ts +46 -0
  924. package/dist/host-modules/fabric.d.ts.map +1 -0
  925. package/dist/host-modules/fabric.js +178 -0
  926. package/dist/host-modules/fabric.js.map +1 -0
  927. package/dist/host-modules/html.d.ts +51 -0
  928. package/dist/host-modules/html.d.ts.map +1 -0
  929. package/dist/host-modules/html.js +198 -0
  930. package/dist/host-modules/html.js.map +1 -0
  931. package/dist/host-modules/ics.d.ts +9 -0
  932. package/dist/host-modules/ics.d.ts.map +1 -0
  933. package/dist/host-modules/ics.js +35 -0
  934. package/dist/host-modules/ics.js.map +1 -0
  935. package/dist/host-modules/limits.d.ts +41 -0
  936. package/dist/host-modules/limits.d.ts.map +1 -0
  937. package/dist/host-modules/limits.js +76 -0
  938. package/dist/host-modules/limits.js.map +1 -0
  939. package/dist/host-modules/mammoth.d.ts +11 -0
  940. package/dist/host-modules/mammoth.d.ts.map +1 -0
  941. package/dist/host-modules/mammoth.js +29 -0
  942. package/dist/host-modules/mammoth.js.map +1 -0
  943. package/dist/host-modules/notion.d.ts +45 -0
  944. package/dist/host-modules/notion.d.ts.map +1 -0
  945. package/dist/host-modules/notion.js +128 -0
  946. package/dist/host-modules/notion.js.map +1 -0
  947. package/dist/host-modules/ocr.d.ts +25 -0
  948. package/dist/host-modules/ocr.d.ts.map +1 -0
  949. package/dist/host-modules/ocr.js +74 -0
  950. package/dist/host-modules/ocr.js.map +1 -0
  951. package/dist/host-modules/pdf.d.ts +21 -0
  952. package/dist/host-modules/pdf.d.ts.map +1 -0
  953. package/dist/host-modules/pdf.js +53 -0
  954. package/dist/host-modules/pdf.js.map +1 -0
  955. package/dist/host-modules/pdflib.d.ts +17 -0
  956. package/dist/host-modules/pdflib.d.ts.map +1 -0
  957. package/dist/host-modules/pdflib.js +138 -0
  958. package/dist/host-modules/pdflib.js.map +1 -0
  959. package/dist/host-modules/pptx.d.ts +19 -0
  960. package/dist/host-modules/pptx.d.ts.map +1 -0
  961. package/dist/host-modules/pptx.js +67 -0
  962. package/dist/host-modules/pptx.js.map +1 -0
  963. package/dist/host-modules/pptxgen.d.ts +13 -0
  964. package/dist/host-modules/pptxgen.d.ts.map +1 -0
  965. package/dist/host-modules/pptxgen.js +98 -0
  966. package/dist/host-modules/pptxgen.js.map +1 -0
  967. package/dist/host-modules/prepared-request.d.ts +41 -0
  968. package/dist/host-modules/prepared-request.d.ts.map +1 -0
  969. package/dist/host-modules/prepared-request.js +104 -0
  970. package/dist/host-modules/prepared-request.js.map +1 -0
  971. package/dist/host-modules/registry.d.ts +31 -0
  972. package/dist/host-modules/registry.d.ts.map +1 -0
  973. package/dist/host-modules/registry.js +193 -0
  974. package/dist/host-modules/registry.js.map +1 -0
  975. package/dist/host-modules/subtitle.d.ts +15 -0
  976. package/dist/host-modules/subtitle.d.ts.map +1 -0
  977. package/dist/host-modules/subtitle.js +45 -0
  978. package/dist/host-modules/subtitle.js.map +1 -0
  979. package/dist/host-modules/supabase.d.ts +42 -0
  980. package/dist/host-modules/supabase.d.ts.map +1 -0
  981. package/dist/host-modules/supabase.js +141 -0
  982. package/dist/host-modules/supabase.js.map +1 -0
  983. package/dist/host-modules/tfjs.d.ts +42 -0
  984. package/dist/host-modules/tfjs.d.ts.map +1 -0
  985. package/dist/host-modules/tfjs.js +186 -0
  986. package/dist/host-modules/tfjs.js.map +1 -0
  987. package/dist/host-modules/tokens.d.ts +17 -0
  988. package/dist/host-modules/tokens.d.ts.map +1 -0
  989. package/dist/host-modules/tokens.js +74 -0
  990. package/dist/host-modules/tokens.js.map +1 -0
  991. package/dist/host-modules/twilio.d.ts +34 -0
  992. package/dist/host-modules/twilio.d.ts.map +1 -0
  993. package/dist/host-modules/twilio.js +67 -0
  994. package/dist/host-modules/twilio.js.map +1 -0
  995. package/dist/host-modules/xlsx.d.ts +26 -0
  996. package/dist/host-modules/xlsx.d.ts.map +1 -0
  997. package/dist/host-modules/xlsx.js +323 -0
  998. package/dist/host-modules/xlsx.js.map +1 -0
  999. package/dist/host-modules/xml.d.ts +23 -0
  1000. package/dist/host-modules/xml.d.ts.map +1 -0
  1001. package/dist/host-modules/xml.js +38 -0
  1002. package/dist/host-modules/xml.js.map +1 -0
  1003. package/dist/host-modules/zip.d.ts +24 -0
  1004. package/dist/host-modules/zip.d.ts.map +1 -0
  1005. package/dist/host-modules/zip.js +70 -0
  1006. package/dist/host-modules/zip.js.map +1 -0
  1007. package/dist/index.d.ts +208 -60
  1008. package/dist/index.d.ts.map +1 -1
  1009. package/dist/index.js +163 -60
  1010. package/dist/index.js.map +1 -1
  1011. package/dist/js-sandbox-worker/engine.d.ts +4 -0
  1012. package/dist/js-sandbox-worker/engine.d.ts.map +1 -0
  1013. package/dist/js-sandbox-worker/engine.js +45 -0
  1014. package/dist/js-sandbox-worker/engine.js.map +1 -0
  1015. package/dist/js-sandbox-worker/host.d.ts +136 -0
  1016. package/dist/js-sandbox-worker/host.d.ts.map +1 -0
  1017. package/dist/js-sandbox-worker/host.js +482 -0
  1018. package/dist/js-sandbox-worker/host.js.map +1 -0
  1019. package/dist/js-sandbox-worker/interpreter.d.ts +276 -0
  1020. package/dist/js-sandbox-worker/interpreter.d.ts.map +1 -0
  1021. package/dist/js-sandbox-worker/interpreter.js +1293 -0
  1022. package/dist/js-sandbox-worker/interpreter.js.map +1 -0
  1023. package/dist/js-sandbox-worker/protocol.d.ts +168 -0
  1024. package/dist/js-sandbox-worker/protocol.d.ts.map +1 -0
  1025. package/dist/js-sandbox-worker/protocol.js +217 -0
  1026. package/dist/js-sandbox-worker/protocol.js.map +1 -0
  1027. package/dist/js-sandbox-worker/worker-entry.d.ts +26 -0
  1028. package/dist/js-sandbox-worker/worker-entry.d.ts.map +1 -0
  1029. package/dist/js-sandbox-worker/worker-entry.js +308 -0
  1030. package/dist/js-sandbox-worker/worker-entry.js.map +1 -0
  1031. package/dist/js-sandbox.d.ts +457 -15
  1032. package/dist/js-sandbox.d.ts.map +1 -1
  1033. package/dist/js-sandbox.js +2008 -311
  1034. package/dist/js-sandbox.js.map +1 -1
  1035. package/dist/js-script-app-runner.d.ts +11 -0
  1036. package/dist/js-script-app-runner.d.ts.map +1 -0
  1037. package/dist/js-script-app-runner.js +54 -0
  1038. package/dist/js-script-app-runner.js.map +1 -0
  1039. package/dist/js-script-sandbox.d.ts +27 -0
  1040. package/dist/js-script-sandbox.d.ts.map +1 -0
  1041. package/dist/js-script-sandbox.js +36 -0
  1042. package/dist/js-script-sandbox.js.map +1 -0
  1043. package/dist/jtbd/friction.d.ts +26 -0
  1044. package/dist/jtbd/friction.d.ts.map +1 -0
  1045. package/dist/jtbd/friction.js +169 -0
  1046. package/dist/jtbd/friction.js.map +1 -0
  1047. package/dist/jtbd/index.d.ts +6 -0
  1048. package/dist/jtbd/index.d.ts.map +1 -0
  1049. package/dist/jtbd/index.js +6 -0
  1050. package/dist/jtbd/index.js.map +1 -0
  1051. package/dist/jtbd/optimize.d.ts +71 -0
  1052. package/dist/jtbd/optimize.d.ts.map +1 -0
  1053. package/dist/jtbd/optimize.js +176 -0
  1054. package/dist/jtbd/optimize.js.map +1 -0
  1055. package/dist/jtbd/registry.d.ts +29 -0
  1056. package/dist/jtbd/registry.d.ts.map +1 -0
  1057. package/dist/jtbd/registry.js +451 -0
  1058. package/dist/jtbd/registry.js.map +1 -0
  1059. package/dist/jtbd/run.d.ts +70 -0
  1060. package/dist/jtbd/run.d.ts.map +1 -0
  1061. package/dist/jtbd/run.js +177 -0
  1062. package/dist/jtbd/run.js.map +1 -0
  1063. package/dist/jtbd/types.d.ts +141 -0
  1064. package/dist/jtbd/types.d.ts.map +1 -0
  1065. package/dist/jtbd/types.js +25 -0
  1066. package/dist/jtbd/types.js.map +1 -0
  1067. package/dist/model-prompting-skills.d.ts +45 -0
  1068. package/dist/model-prompting-skills.d.ts.map +1 -0
  1069. package/dist/model-prompting-skills.js +116 -0
  1070. package/dist/model-prompting-skills.js.map +1 -0
  1071. package/dist/network-guard.d.ts +50 -0
  1072. package/dist/network-guard.d.ts.map +1 -0
  1073. package/dist/network-guard.js +106 -0
  1074. package/dist/network-guard.js.map +1 -0
  1075. package/dist/normalize-model-properties.d.ts +26 -0
  1076. package/dist/normalize-model-properties.d.ts.map +1 -0
  1077. package/dist/normalize-model-properties.js +58 -0
  1078. package/dist/normalize-model-properties.js.map +1 -0
  1079. package/dist/output-format.d.ts +5 -1
  1080. package/dist/output-format.d.ts.map +1 -1
  1081. package/dist/output-format.js.map +1 -1
  1082. package/dist/parallel-task-executor.d.ts +68 -37
  1083. package/dist/parallel-task-executor.d.ts.map +1 -1
  1084. package/dist/parallel-task-executor.js +234 -203
  1085. package/dist/parallel-task-executor.js.map +1 -1
  1086. package/dist/prompts/background-subtask-prompt.d.ts +14 -0
  1087. package/dist/prompts/background-subtask-prompt.d.ts.map +1 -0
  1088. package/dist/prompts/background-subtask-prompt.js +64 -0
  1089. package/dist/prompts/background-subtask-prompt.js.map +1 -0
  1090. package/dist/prompts/product-knowledge.d.ts +3 -0
  1091. package/dist/prompts/product-knowledge.d.ts.map +1 -0
  1092. package/dist/prompts/product-knowledge.js +120 -0
  1093. package/dist/prompts/product-knowledge.js.map +1 -0
  1094. package/dist/prompts/read-only-search-prompt.d.ts +33 -0
  1095. package/dist/prompts/read-only-search-prompt.d.ts.map +1 -0
  1096. package/dist/prompts/read-only-search-prompt.js +109 -0
  1097. package/dist/prompts/read-only-search-prompt.js.map +1 -0
  1098. package/dist/prompts/sandbox-pack-catalog.d.ts +23 -0
  1099. package/dist/prompts/sandbox-pack-catalog.d.ts.map +1 -0
  1100. package/dist/prompts/sandbox-pack-catalog.js +40 -0
  1101. package/dist/prompts/sandbox-pack-catalog.js.map +1 -0
  1102. package/dist/prompts/security-monitor-prompt.d.ts +32 -0
  1103. package/dist/prompts/security-monitor-prompt.d.ts.map +1 -0
  1104. package/dist/prompts/security-monitor-prompt.js +99 -0
  1105. package/dist/prompts/security-monitor-prompt.js.map +1 -0
  1106. package/dist/prompts/workflow-authoring-knowledge.d.ts +77 -0
  1107. package/dist/prompts/workflow-authoring-knowledge.d.ts.map +1 -0
  1108. package/dist/prompts/workflow-authoring-knowledge.js +319 -0
  1109. package/dist/prompts/workflow-authoring-knowledge.js.map +1 -0
  1110. package/dist/run-policy.d.ts +25 -0
  1111. package/dist/run-policy.d.ts.map +1 -0
  1112. package/dist/run-policy.js +54 -0
  1113. package/dist/run-policy.js.map +1 -0
  1114. package/dist/sandbox-av-media.d.ts +33 -0
  1115. package/dist/sandbox-av-media.d.ts.map +1 -0
  1116. package/dist/sandbox-av-media.js +666 -0
  1117. package/dist/sandbox-av-media.js.map +1 -0
  1118. package/dist/sandbox-bootstrap-modules.d.ts +54 -0
  1119. package/dist/sandbox-bootstrap-modules.d.ts.map +1 -0
  1120. package/dist/sandbox-bootstrap-modules.js +104 -0
  1121. package/dist/sandbox-bootstrap-modules.js.map +1 -0
  1122. package/dist/sandbox-bytes.d.ts +43 -0
  1123. package/dist/sandbox-bytes.d.ts.map +1 -0
  1124. package/dist/sandbox-bytes.js +61 -0
  1125. package/dist/sandbox-bytes.js.map +1 -0
  1126. package/dist/sandbox-canvas-api.d.ts +30 -0
  1127. package/dist/sandbox-canvas-api.d.ts.map +1 -0
  1128. package/dist/sandbox-canvas-api.js +81 -0
  1129. package/dist/sandbox-canvas-api.js.map +1 -0
  1130. package/dist/sandbox-constants.d.ts +5 -0
  1131. package/dist/sandbox-constants.d.ts.map +1 -0
  1132. package/dist/sandbox-constants.js +13 -0
  1133. package/dist/sandbox-constants.js.map +1 -0
  1134. package/dist/sandbox-json-transport.d.ts +107 -0
  1135. package/dist/sandbox-json-transport.d.ts.map +1 -0
  1136. package/dist/sandbox-json-transport.js +324 -0
  1137. package/dist/sandbox-json-transport.js.map +1 -0
  1138. package/dist/sandbox-media-handle.d.ts +78 -0
  1139. package/dist/sandbox-media-handle.d.ts.map +1 -0
  1140. package/dist/sandbox-media-handle.js +114 -0
  1141. package/dist/sandbox-media-handle.js.map +1 -0
  1142. package/dist/sandbox-media-ref.d.ts +134 -0
  1143. package/dist/sandbox-media-ref.d.ts.map +1 -0
  1144. package/dist/sandbox-media-ref.js +442 -0
  1145. package/dist/sandbox-media-ref.js.map +1 -0
  1146. package/dist/sandbox-media.d.ts +177 -0
  1147. package/dist/sandbox-media.d.ts.map +1 -0
  1148. package/dist/sandbox-media.js +963 -0
  1149. package/dist/sandbox-media.js.map +1 -0
  1150. package/dist/sandbox-module-fixtures.d.ts +445 -0
  1151. package/dist/sandbox-module-fixtures.d.ts.map +1 -0
  1152. package/dist/sandbox-module-fixtures.js +214 -0
  1153. package/dist/sandbox-module-fixtures.js.map +1 -0
  1154. package/dist/sandbox-pack-resolution.d.ts +21 -0
  1155. package/dist/sandbox-pack-resolution.d.ts.map +1 -0
  1156. package/dist/sandbox-pack-resolution.js +42 -0
  1157. package/dist/sandbox-pack-resolution.js.map +1 -0
  1158. package/dist/sandbox-toolbelt.d.ts +15 -0
  1159. package/dist/sandbox-toolbelt.d.ts.map +1 -0
  1160. package/dist/sandbox-toolbelt.js +70 -0
  1161. package/dist/sandbox-toolbelt.js.map +1 -0
  1162. package/dist/security-monitor.d.ts +89 -0
  1163. package/dist/security-monitor.d.ts.map +1 -0
  1164. package/dist/security-monitor.js +307 -0
  1165. package/dist/security-monitor.js.map +1 -0
  1166. package/dist/serpapi/catalog.d.ts +101 -0
  1167. package/dist/serpapi/catalog.d.ts.map +1 -0
  1168. package/dist/serpapi/catalog.js +246 -0
  1169. package/dist/serpapi/catalog.js.map +1 -0
  1170. package/dist/serpapi/client.d.ts +81 -0
  1171. package/dist/serpapi/client.d.ts.map +1 -0
  1172. package/dist/serpapi/client.js +228 -0
  1173. package/dist/serpapi/client.js.map +1 -0
  1174. package/dist/serpapi/errors.d.ts +49 -0
  1175. package/dist/serpapi/errors.d.ts.map +1 -0
  1176. package/dist/serpapi/errors.js +64 -0
  1177. package/dist/serpapi/errors.js.map +1 -0
  1178. package/dist/serpapi/normalize.d.ts +58 -0
  1179. package/dist/serpapi/normalize.d.ts.map +1 -0
  1180. package/dist/serpapi/normalize.js +140 -0
  1181. package/dist/serpapi/normalize.js.map +1 -0
  1182. package/dist/skill-prompt.d.ts +37 -0
  1183. package/dist/skill-prompt.d.ts.map +1 -0
  1184. package/dist/skill-prompt.js +72 -0
  1185. package/dist/skill-prompt.js.map +1 -0
  1186. package/dist/step-executor.d.ts +90 -77
  1187. package/dist/step-executor.d.ts.map +1 -1
  1188. package/dist/step-executor.js +384 -690
  1189. package/dist/step-executor.js.map +1 -1
  1190. package/dist/subagent.d.ts +275 -0
  1191. package/dist/subagent.d.ts.map +1 -0
  1192. package/dist/subagent.js +444 -0
  1193. package/dist/subagent.js.map +1 -0
  1194. package/dist/supervisor/prompt.d.ts +12 -0
  1195. package/dist/supervisor/prompt.d.ts.map +1 -0
  1196. package/dist/supervisor/prompt.js +51 -0
  1197. package/dist/supervisor/prompt.js.map +1 -0
  1198. package/dist/supervisor/supervisor-agent.d.ts +72 -0
  1199. package/dist/supervisor/supervisor-agent.d.ts.map +1 -0
  1200. package/dist/supervisor/supervisor-agent.js +185 -0
  1201. package/dist/supervisor/supervisor-agent.js.map +1 -0
  1202. package/dist/supervisor/tools.d.ts +56 -0
  1203. package/dist/supervisor/tools.d.ts.map +1 -0
  1204. package/dist/supervisor/tools.js +83 -0
  1205. package/dist/supervisor/tools.js.map +1 -0
  1206. package/dist/supervisor/verdict-schema.d.ts +18 -0
  1207. package/dist/supervisor/verdict-schema.d.ts.map +1 -0
  1208. package/dist/supervisor/verdict-schema.js +58 -0
  1209. package/dist/supervisor/verdict-schema.js.map +1 -0
  1210. package/dist/system-skills.d.ts +74 -0
  1211. package/dist/system-skills.d.ts.map +1 -0
  1212. package/dist/system-skills.js +168 -0
  1213. package/dist/system-skills.js.map +1 -0
  1214. package/dist/task-executor.d.ts +90 -40
  1215. package/dist/task-executor.d.ts.map +1 -1
  1216. package/dist/task-executor.js +259 -282
  1217. package/dist/task-executor.js.map +1 -1
  1218. package/dist/task-planner.d.ts +18 -12
  1219. package/dist/task-planner.d.ts.map +1 -1
  1220. package/dist/task-planner.js +342 -328
  1221. package/dist/task-planner.js.map +1 -1
  1222. package/dist/timeline-capture.d.ts +21 -0
  1223. package/dist/timeline-capture.d.ts.map +1 -0
  1224. package/dist/timeline-capture.js +564 -0
  1225. package/dist/timeline-capture.js.map +1 -0
  1226. package/dist/timeline-code-bake.d.ts +75 -0
  1227. package/dist/timeline-code-bake.d.ts.map +1 -0
  1228. package/dist/timeline-code-bake.js +327 -0
  1229. package/dist/timeline-code-bake.js.map +1 -0
  1230. package/dist/timeline-preview/compare.d.ts +27 -0
  1231. package/dist/timeline-preview/compare.d.ts.map +1 -0
  1232. package/dist/timeline-preview/compare.js +71 -0
  1233. package/dist/timeline-preview/compare.js.map +1 -0
  1234. package/dist/timeline-preview/frames.d.ts +193 -0
  1235. package/dist/timeline-preview/frames.d.ts.map +1 -0
  1236. package/dist/timeline-preview/frames.js +731 -0
  1237. package/dist/timeline-preview/frames.js.map +1 -0
  1238. package/dist/timeline-preview/model3d.d.ts +67 -0
  1239. package/dist/timeline-preview/model3d.d.ts.map +1 -0
  1240. package/dist/timeline-preview/model3d.js +165 -0
  1241. package/dist/timeline-preview/model3d.js.map +1 -0
  1242. package/dist/timeline-preview/rasterize.d.ts +33 -0
  1243. package/dist/timeline-preview/rasterize.d.ts.map +1 -0
  1244. package/dist/timeline-preview/rasterize.js +83 -0
  1245. package/dist/timeline-preview/rasterize.js.map +1 -0
  1246. package/dist/timeline-preview/sheet.d.ts +38 -0
  1247. package/dist/timeline-preview/sheet.d.ts.map +1 -0
  1248. package/dist/timeline-preview/sheet.js +72 -0
  1249. package/dist/timeline-preview/sheet.js.map +1 -0
  1250. package/dist/tools/asset-persist.d.ts +29 -0
  1251. package/dist/tools/asset-persist.d.ts.map +1 -0
  1252. package/dist/tools/asset-persist.js +78 -0
  1253. package/dist/tools/asset-persist.js.map +1 -0
  1254. package/dist/tools/base-tool.d.ts +53 -5
  1255. package/dist/tools/base-tool.d.ts.map +1 -1
  1256. package/dist/tools/base-tool.js +180 -3
  1257. package/dist/tools/base-tool.js.map +1 -1
  1258. package/dist/tools/binary-output.d.ts +54 -0
  1259. package/dist/tools/binary-output.d.ts.map +1 -0
  1260. package/dist/tools/binary-output.js +127 -0
  1261. package/dist/tools/binary-output.js.map +1 -0
  1262. package/dist/tools/browser-tools.d.ts +5 -29
  1263. package/dist/tools/browser-tools.d.ts.map +1 -1
  1264. package/dist/tools/browser-tools.js +5 -205
  1265. package/dist/tools/browser-tools.js.map +1 -1
  1266. package/dist/tools/builtin-tools.d.ts +52 -0
  1267. package/dist/tools/builtin-tools.d.ts.map +1 -0
  1268. package/dist/tools/builtin-tools.js +289 -0
  1269. package/dist/tools/builtin-tools.js.map +1 -0
  1270. package/dist/tools/control-tool.d.ts +2 -5
  1271. package/dist/tools/control-tool.d.ts.map +1 -1
  1272. package/dist/tools/control-tool.js +18 -15
  1273. package/dist/tools/control-tool.js.map +1 -1
  1274. package/dist/tools/dataseo-tools.d.ts +34 -32
  1275. package/dist/tools/dataseo-tools.d.ts.map +1 -1
  1276. package/dist/tools/dataseo-tools.js +148 -233
  1277. package/dist/tools/dataseo-tools.js.map +1 -1
  1278. package/dist/tools/external-capability-tools.d.ts +36 -0
  1279. package/dist/tools/external-capability-tools.d.ts.map +1 -0
  1280. package/dist/tools/external-capability-tools.js +41 -0
  1281. package/dist/tools/external-capability-tools.js.map +1 -0
  1282. package/dist/tools/external-mcp-tools.d.ts +139 -0
  1283. package/dist/tools/external-mcp-tools.d.ts.map +1 -0
  1284. package/dist/tools/external-mcp-tools.js +552 -0
  1285. package/dist/tools/external-mcp-tools.js.map +1 -0
  1286. package/dist/tools/finish-step-tool.d.ts +1 -1
  1287. package/dist/tools/finish-step-tool.d.ts.map +1 -1
  1288. package/dist/tools/finish-step-tool.js +3 -3
  1289. package/dist/tools/finish-step-tool.js.map +1 -1
  1290. package/dist/tools/google-tools.d.ts +28 -39
  1291. package/dist/tools/google-tools.d.ts.map +1 -1
  1292. package/dist/tools/google-tools.js +51 -164
  1293. package/dist/tools/google-tools.js.map +1 -1
  1294. package/dist/tools/google-workspace-tools.d.ts +23 -0
  1295. package/dist/tools/google-workspace-tools.d.ts.map +1 -0
  1296. package/dist/tools/google-workspace-tools.js +26 -0
  1297. package/dist/tools/google-workspace-tools.js.map +1 -0
  1298. package/dist/tools/graph-validation-registry.d.ts +33 -0
  1299. package/dist/tools/graph-validation-registry.d.ts.map +1 -0
  1300. package/dist/tools/graph-validation-registry.js +54 -0
  1301. package/dist/tools/graph-validation-registry.js.map +1 -0
  1302. package/dist/tools/http-tools.d.ts +5 -53
  1303. package/dist/tools/http-tools.d.ts.map +1 -1
  1304. package/dist/tools/http-tools.js +5 -177
  1305. package/dist/tools/http-tools.js.map +1 -1
  1306. package/dist/tools/image-injection.d.ts +51 -0
  1307. package/dist/tools/image-injection.d.ts.map +1 -0
  1308. package/dist/tools/image-injection.js +85 -0
  1309. package/dist/tools/image-injection.js.map +1 -0
  1310. package/dist/tools/mcp-tool-support.d.ts +204 -0
  1311. package/dist/tools/mcp-tool-support.d.ts.map +1 -0
  1312. package/dist/tools/mcp-tool-support.js +537 -0
  1313. package/dist/tools/mcp-tool-support.js.map +1 -0
  1314. package/dist/tools/mcp-tools.d.ts +106 -390
  1315. package/dist/tools/mcp-tools.d.ts.map +1 -1
  1316. package/dist/tools/mcp-tools.js +132 -601
  1317. package/dist/tools/mcp-tools.js.map +1 -1
  1318. package/dist/tools/media-tools.d.ts +9 -272
  1319. package/dist/tools/media-tools.d.ts.map +1 -1
  1320. package/dist/tools/media-tools.js +11 -676
  1321. package/dist/tools/media-tools.js.map +1 -1
  1322. package/dist/tools/memory-tools.d.ts +36 -0
  1323. package/dist/tools/memory-tools.d.ts.map +1 -0
  1324. package/dist/tools/memory-tools.js +52 -0
  1325. package/dist/tools/memory-tools.js.map +1 -0
  1326. package/dist/tools/openai-tools.d.ts +28 -68
  1327. package/dist/tools/openai-tools.d.ts.map +1 -1
  1328. package/dist/tools/openai-tools.js +51 -181
  1329. package/dist/tools/openai-tools.js.map +1 -1
  1330. package/dist/tools/plan-builder-tools.d.ts +141 -7
  1331. package/dist/tools/plan-builder-tools.d.ts.map +1 -1
  1332. package/dist/tools/plan-builder-tools.js +159 -86
  1333. package/dist/tools/plan-builder-tools.js.map +1 -1
  1334. package/dist/tools/run-search-tool.d.ts +82 -0
  1335. package/dist/tools/run-search-tool.d.ts.map +1 -0
  1336. package/dist/tools/run-search-tool.js +121 -0
  1337. package/dist/tools/run-search-tool.js.map +1 -0
  1338. package/dist/tools/run-subtask-tool.d.ts +49 -0
  1339. package/dist/tools/run-subtask-tool.d.ts.map +1 -0
  1340. package/dist/tools/run-subtask-tool.js +88 -0
  1341. package/dist/tools/run-subtask-tool.js.map +1 -0
  1342. package/dist/tools/search-tools.d.ts +5 -36
  1343. package/dist/tools/search-tools.d.ts.map +1 -1
  1344. package/dist/tools/search-tools.js +5 -215
  1345. package/dist/tools/search-tools.js.map +1 -1
  1346. package/dist/tools/serp-providers/apify-provider.d.ts +18 -0
  1347. package/dist/tools/serp-providers/apify-provider.d.ts.map +1 -0
  1348. package/dist/tools/serp-providers/apify-provider.js +93 -0
  1349. package/dist/tools/serp-providers/apify-provider.js.map +1 -0
  1350. package/dist/tools/serp-providers/brave-provider.d.ts +34 -0
  1351. package/dist/tools/serp-providers/brave-provider.d.ts.map +1 -0
  1352. package/dist/tools/serp-providers/brave-provider.js +86 -0
  1353. package/dist/tools/serp-providers/brave-provider.js.map +1 -0
  1354. package/dist/tools/serp-providers/dataforseo-provider.d.ts +14 -1
  1355. package/dist/tools/serp-providers/dataforseo-provider.d.ts.map +1 -1
  1356. package/dist/tools/serp-providers/dataforseo-provider.js +0 -9
  1357. package/dist/tools/serp-providers/dataforseo-provider.js.map +1 -1
  1358. package/dist/tools/serp-providers/gemini-provider.d.ts +45 -0
  1359. package/dist/tools/serp-providers/gemini-provider.d.ts.map +1 -0
  1360. package/dist/tools/serp-providers/gemini-provider.js +148 -0
  1361. package/dist/tools/serp-providers/gemini-provider.js.map +1 -0
  1362. package/dist/tools/serp-providers/index.d.ts +61 -0
  1363. package/dist/tools/serp-providers/index.d.ts.map +1 -1
  1364. package/dist/tools/serp-providers/index.js +119 -3
  1365. package/dist/tools/serp-providers/index.js.map +1 -1
  1366. package/dist/tools/serp-providers/openai-provider.d.ts +58 -0
  1367. package/dist/tools/serp-providers/openai-provider.d.ts.map +1 -0
  1368. package/dist/tools/serp-providers/openai-provider.js +113 -0
  1369. package/dist/tools/serp-providers/openai-provider.js.map +1 -0
  1370. package/dist/tools/serp-providers/serpapi-provider.d.ts +9 -5
  1371. package/dist/tools/serp-providers/serpapi-provider.d.ts.map +1 -1
  1372. package/dist/tools/serp-providers/serpapi-provider.js +26 -44
  1373. package/dist/tools/serp-providers/serpapi-provider.js.map +1 -1
  1374. package/dist/tools/serp-tool-factory.d.ts +27 -0
  1375. package/dist/tools/serp-tool-factory.d.ts.map +1 -0
  1376. package/dist/tools/serp-tool-factory.js +56 -0
  1377. package/dist/tools/serp-tool-factory.js.map +1 -0
  1378. package/dist/tools/shared-tools.d.ts +33 -0
  1379. package/dist/tools/shared-tools.d.ts.map +1 -0
  1380. package/dist/tools/shared-tools.js +39 -0
  1381. package/dist/tools/shared-tools.js.map +1 -0
  1382. package/dist/tools/start-subtask-tool.d.ts +51 -0
  1383. package/dist/tools/start-subtask-tool.d.ts.map +1 -0
  1384. package/dist/tools/start-subtask-tool.js +189 -0
  1385. package/dist/tools/start-subtask-tool.js.map +1 -0
  1386. package/dist/tools/submit-code-tool.d.ts +159 -0
  1387. package/dist/tools/submit-code-tool.d.ts.map +1 -0
  1388. package/dist/tools/submit-code-tool.js +209 -0
  1389. package/dist/tools/submit-code-tool.js.map +1 -0
  1390. package/dist/tools/subtask-fields.d.ts +11 -0
  1391. package/dist/tools/subtask-fields.d.ts.map +1 -0
  1392. package/dist/tools/subtask-fields.js +11 -0
  1393. package/dist/tools/subtask-fields.js.map +1 -0
  1394. package/dist/tools/todo-tools.d.ts +15 -0
  1395. package/dist/tools/todo-tools.d.ts.map +1 -0
  1396. package/dist/tools/todo-tools.js +15 -0
  1397. package/dist/tools/todo-tools.js.map +1 -0
  1398. package/dist/tools/tool-permissions.d.ts +40 -0
  1399. package/dist/tools/tool-permissions.d.ts.map +1 -0
  1400. package/dist/tools/tool-permissions.js +52 -0
  1401. package/dist/tools/tool-permissions.js.map +1 -0
  1402. package/dist/tools/tool-search.d.ts +39 -0
  1403. package/dist/tools/tool-search.d.ts.map +1 -0
  1404. package/dist/tools/tool-search.js +108 -0
  1405. package/dist/tools/tool-search.js.map +1 -0
  1406. package/dist/tools/vector-tool-support.d.ts +15 -0
  1407. package/dist/tools/vector-tool-support.d.ts.map +1 -0
  1408. package/dist/tools/vector-tool-support.js +133 -0
  1409. package/dist/tools/vector-tool-support.js.map +1 -0
  1410. package/dist/tools/vector-tools.d.ts +13 -220
  1411. package/dist/tools/vector-tools.d.ts.map +1 -1
  1412. package/dist/tools/vector-tools.js +7 -578
  1413. package/dist/tools/vector-tools.js.map +1 -1
  1414. package/dist/tools/wait-subtasks-tool.d.ts +27 -0
  1415. package/dist/tools/wait-subtasks-tool.d.ts.map +1 -0
  1416. package/dist/tools/wait-subtasks-tool.js +66 -0
  1417. package/dist/tools/wait-subtasks-tool.js.map +1 -0
  1418. package/dist/types.d.ts +16 -31
  1419. package/dist/types.d.ts.map +1 -1
  1420. package/dist/types.js +8 -1
  1421. package/dist/types.js.map +1 -1
  1422. package/dist/utils/dag-scheduler.d.ts +85 -0
  1423. package/dist/utils/dag-scheduler.d.ts.map +1 -0
  1424. package/dist/utils/dag-scheduler.js +180 -0
  1425. package/dist/utils/dag-scheduler.js.map +1 -0
  1426. package/dist/utils/json-parser.d.ts +32 -1
  1427. package/dist/utils/json-parser.d.ts.map +1 -1
  1428. package/dist/utils/json-parser.js +145 -10
  1429. package/dist/utils/json-parser.js.map +1 -1
  1430. package/dist/utils/json-schema-validate.d.ts +29 -0
  1431. package/dist/utils/json-schema-validate.d.ts.map +1 -0
  1432. package/dist/utils/json-schema-validate.js +228 -0
  1433. package/dist/utils/json-schema-validate.js.map +1 -0
  1434. package/dist/utils/link-abort.d.ts +13 -0
  1435. package/dist/utils/link-abort.d.ts.map +1 -0
  1436. package/dist/utils/link-abort.js +23 -0
  1437. package/dist/utils/link-abort.js.map +1 -0
  1438. package/dist/utils/merge-generators.d.ts +58 -0
  1439. package/dist/utils/merge-generators.d.ts.map +1 -0
  1440. package/dist/utils/merge-generators.js +148 -0
  1441. package/dist/utils/merge-generators.js.map +1 -0
  1442. package/dist/utils/remove-base64-images.d.ts +0 -5
  1443. package/dist/utils/remove-base64-images.d.ts.map +1 -1
  1444. package/dist/utils/remove-base64-images.js.map +1 -1
  1445. package/dist/utils/step-failure.d.ts +20 -0
  1446. package/dist/utils/step-failure.d.ts.map +1 -0
  1447. package/dist/utils/step-failure.js +43 -0
  1448. package/dist/utils/step-failure.js.map +1 -0
  1449. package/dist/utils/think-tags.d.ts +16 -0
  1450. package/dist/utils/think-tags.d.ts.map +1 -0
  1451. package/dist/utils/think-tags.js +23 -0
  1452. package/dist/utils/think-tags.js.map +1 -0
  1453. package/dist/utils/type-guards.d.ts +26 -0
  1454. package/dist/utils/type-guards.d.ts.map +1 -0
  1455. package/dist/utils/type-guards.js +44 -0
  1456. package/dist/utils/type-guards.js.map +1 -0
  1457. package/dist/utils/ui-event-buffer.d.ts +18 -0
  1458. package/dist/utils/ui-event-buffer.d.ts.map +1 -0
  1459. package/dist/utils/ui-event-buffer.js +18 -0
  1460. package/dist/utils/ui-event-buffer.js.map +1 -0
  1461. package/dist/utils/wrap-generators-parallel.d.ts +0 -5
  1462. package/dist/utils/wrap-generators-parallel.d.ts.map +1 -1
  1463. package/dist/utils/wrap-generators-parallel.js +3 -6
  1464. package/dist/utils/wrap-generators-parallel.js.map +1 -1
  1465. package/dist/wasm-sandbox/host.d.ts +106 -0
  1466. package/dist/wasm-sandbox/host.d.ts.map +1 -0
  1467. package/dist/wasm-sandbox/host.js +409 -0
  1468. package/dist/wasm-sandbox/host.js.map +1 -0
  1469. package/dist/wasm-sandbox/workers.d.ts +43 -0
  1470. package/dist/wasm-sandbox/workers.d.ts.map +1 -0
  1471. package/dist/wasm-sandbox/workers.js +150 -0
  1472. package/dist/wasm-sandbox/workers.js.map +1 -0
  1473. package/dist/workspace-paths.d.ts +40 -0
  1474. package/dist/workspace-paths.d.ts.map +1 -0
  1475. package/dist/workspace-paths.js +102 -0
  1476. package/dist/workspace-paths.js.map +1 -0
  1477. package/dist/yt-dlp-gate.d.ts +19 -0
  1478. package/dist/yt-dlp-gate.d.ts.map +1 -0
  1479. package/dist/yt-dlp-gate.js +22 -0
  1480. package/dist/yt-dlp-gate.js.map +1 -0
  1481. package/package.json +114 -14
  1482. package/dist/agent-executor.d.ts +0 -62
  1483. package/dist/agent-executor.d.ts.map +0 -1
  1484. package/dist/agent-executor.js +0 -324
  1485. package/dist/agent-executor.js.map +0 -1
  1486. package/dist/agent-step-executor.d.ts +0 -28
  1487. package/dist/agent-step-executor.d.ts.map +0 -1
  1488. package/dist/agent-step-executor.js +0 -99
  1489. package/dist/agent-step-executor.js.map +0 -1
  1490. package/dist/agent-workflow-runner.d.ts +0 -31
  1491. package/dist/agent-workflow-runner.d.ts.map +0 -1
  1492. package/dist/agent-workflow-runner.js +0 -124
  1493. package/dist/agent-workflow-runner.js.map +0 -1
  1494. package/dist/agent.d.ts +0 -115
  1495. package/dist/agent.d.ts.map +0 -1
  1496. package/dist/agent.js +0 -587
  1497. package/dist/agent.js.map +0 -1
  1498. package/dist/base-agent.d.ts +0 -42
  1499. package/dist/base-agent.d.ts.map +0 -1
  1500. package/dist/base-agent.js +0 -29
  1501. package/dist/base-agent.js.map +0 -1
  1502. package/dist/graph-planner.d.ts +0 -56
  1503. package/dist/graph-planner.d.ts.map +0 -1
  1504. package/dist/graph-planner.js +0 -311
  1505. package/dist/graph-planner.js.map +0 -1
  1506. package/dist/multi-mode-agent.d.ts +0 -86
  1507. package/dist/multi-mode-agent.d.ts.map +0 -1
  1508. package/dist/multi-mode-agent.js +0 -476
  1509. package/dist/multi-mode-agent.js.map +0 -1
  1510. package/dist/prompts/graph-planner-prompt.d.ts +0 -48
  1511. package/dist/prompts/graph-planner-prompt.d.ts.map +0 -1
  1512. package/dist/prompts/graph-planner-prompt.js +0 -180
  1513. package/dist/prompts/graph-planner-prompt.js.map +0 -1
  1514. package/dist/reject-agentic-provider.d.ts +0 -21
  1515. package/dist/reject-agentic-provider.d.ts.map +0 -1
  1516. package/dist/reject-agentic-provider.js +0 -32
  1517. package/dist/reject-agentic-provider.js.map +0 -1
  1518. package/dist/simple-agent.d.ts +0 -29
  1519. package/dist/simple-agent.d.ts.map +0 -1
  1520. package/dist/simple-agent.js +0 -54
  1521. package/dist/simple-agent.js.map +0 -1
  1522. package/dist/sub-agent-planner.d.ts +0 -33
  1523. package/dist/sub-agent-planner.d.ts.map +0 -1
  1524. package/dist/sub-agent-planner.js +0 -203
  1525. package/dist/sub-agent-planner.js.map +0 -1
  1526. package/dist/team/db-task-board.d.ts +0 -54
  1527. package/dist/team/db-task-board.d.ts.map +0 -1
  1528. package/dist/team/db-task-board.js +0 -361
  1529. package/dist/team/db-task-board.js.map +0 -1
  1530. package/dist/team/edge-message-bus.d.ts +0 -51
  1531. package/dist/team/edge-message-bus.d.ts.map +0 -1
  1532. package/dist/team/edge-message-bus.js +0 -169
  1533. package/dist/team/edge-message-bus.js.map +0 -1
  1534. package/dist/team/edge-task-board.d.ts +0 -77
  1535. package/dist/team/edge-task-board.d.ts.map +0 -1
  1536. package/dist/team/edge-task-board.js +0 -140
  1537. package/dist/team/edge-task-board.js.map +0 -1
  1538. package/dist/team/index.d.ts +0 -16
  1539. package/dist/team/index.d.ts.map +0 -1
  1540. package/dist/team/index.js +0 -17
  1541. package/dist/team/index.js.map +0 -1
  1542. package/dist/team/message-bus.d.ts +0 -58
  1543. package/dist/team/message-bus.d.ts.map +0 -1
  1544. package/dist/team/message-bus.js +0 -151
  1545. package/dist/team/message-bus.js.map +0 -1
  1546. package/dist/team/task-board.d.ts +0 -106
  1547. package/dist/team/task-board.d.ts.map +0 -1
  1548. package/dist/team/task-board.js +0 -370
  1549. package/dist/team/task-board.js.map +0 -1
  1550. package/dist/team/team-executor.d.ts +0 -72
  1551. package/dist/team/team-executor.d.ts.map +0 -1
  1552. package/dist/team/team-executor.js +0 -466
  1553. package/dist/team/team-executor.js.map +0 -1
  1554. package/dist/team/team-tools.d.ts +0 -252
  1555. package/dist/team/team-tools.d.ts.map +0 -1
  1556. package/dist/team/team-tools.js +0 -412
  1557. package/dist/team/team-tools.js.map +0 -1
  1558. package/dist/team/types.d.ts +0 -198
  1559. package/dist/team/types.d.ts.map +0 -1
  1560. package/dist/team/types.js +0 -8
  1561. package/dist/team/types.js.map +0 -1
  1562. package/dist/tools/add-edge-tool.d.ts +0 -18
  1563. package/dist/tools/add-edge-tool.d.ts.map +0 -1
  1564. package/dist/tools/add-edge-tool.js +0 -92
  1565. package/dist/tools/add-edge-tool.js.map +0 -1
  1566. package/dist/tools/add-node-tool.d.ts +0 -22
  1567. package/dist/tools/add-node-tool.d.ts.map +0 -1
  1568. package/dist/tools/add-node-tool.js +0 -128
  1569. package/dist/tools/add-node-tool.js.map +0 -1
  1570. package/dist/tools/asset-tools.d.ts +0 -58
  1571. package/dist/tools/asset-tools.d.ts.map +0 -1
  1572. package/dist/tools/asset-tools.js +0 -191
  1573. package/dist/tools/asset-tools.js.map +0 -1
  1574. package/dist/tools/calculator-tool.d.ts +0 -24
  1575. package/dist/tools/calculator-tool.d.ts.map +0 -1
  1576. package/dist/tools/calculator-tool.js +0 -64
  1577. package/dist/tools/calculator-tool.js.map +0 -1
  1578. package/dist/tools/claude-code-tools.d.ts +0 -96
  1579. package/dist/tools/claude-code-tools.d.ts.map +0 -1
  1580. package/dist/tools/claude-code-tools.js +0 -463
  1581. package/dist/tools/claude-code-tools.js.map +0 -1
  1582. package/dist/tools/code-tools.d.ts +0 -26
  1583. package/dist/tools/code-tools.d.ts.map +0 -1
  1584. package/dist/tools/code-tools.js +0 -82
  1585. package/dist/tools/code-tools.js.map +0 -1
  1586. package/dist/tools/create-plan-tool.d.ts +0 -29
  1587. package/dist/tools/create-plan-tool.d.ts.map +0 -1
  1588. package/dist/tools/create-plan-tool.js +0 -355
  1589. package/dist/tools/create-plan-tool.js.map +0 -1
  1590. package/dist/tools/create-task-tool.d.ts +0 -28
  1591. package/dist/tools/create-task-tool.d.ts.map +0 -1
  1592. package/dist/tools/create-task-tool.js +0 -254
  1593. package/dist/tools/create-task-tool.js.map +0 -1
  1594. package/dist/tools/email-tools.d.ts +0 -76
  1595. package/dist/tools/email-tools.d.ts.map +0 -1
  1596. package/dist/tools/email-tools.js +0 -259
  1597. package/dist/tools/email-tools.js.map +0 -1
  1598. package/dist/tools/filesystem-tools.d.ts +0 -77
  1599. package/dist/tools/filesystem-tools.d.ts.map +0 -1
  1600. package/dist/tools/filesystem-tools.js +0 -334
  1601. package/dist/tools/filesystem-tools.js.map +0 -1
  1602. package/dist/tools/find-model-tool.d.ts +0 -25
  1603. package/dist/tools/find-model-tool.d.ts.map +0 -1
  1604. package/dist/tools/find-model-tool.js +0 -236
  1605. package/dist/tools/find-model-tool.js.map +0 -1
  1606. package/dist/tools/finish-graph-tool.d.ts +0 -23
  1607. package/dist/tools/finish-graph-tool.d.ts.map +0 -1
  1608. package/dist/tools/finish-graph-tool.js +0 -46
  1609. package/dist/tools/finish-graph-tool.js.map +0 -1
  1610. package/dist/tools/js-code-tool.d.ts +0 -30
  1611. package/dist/tools/js-code-tool.d.ts.map +0 -1
  1612. package/dist/tools/js-code-tool.js +0 -98
  1613. package/dist/tools/js-code-tool.js.map +0 -1
  1614. package/dist/tools/local-get-node-info-tool.d.ts +0 -19
  1615. package/dist/tools/local-get-node-info-tool.d.ts.map +0 -1
  1616. package/dist/tools/local-get-node-info-tool.js +0 -75
  1617. package/dist/tools/local-get-node-info-tool.js.map +0 -1
  1618. package/dist/tools/local-list-nodes-tool.d.ts +0 -19
  1619. package/dist/tools/local-list-nodes-tool.d.ts.map +0 -1
  1620. package/dist/tools/local-list-nodes-tool.js +0 -69
  1621. package/dist/tools/local-list-nodes-tool.js.map +0 -1
  1622. package/dist/tools/local-search-nodes-tool.d.ts +0 -21
  1623. package/dist/tools/local-search-nodes-tool.d.ts.map +0 -1
  1624. package/dist/tools/local-search-nodes-tool.js +0 -111
  1625. package/dist/tools/local-search-nodes-tool.js.map +0 -1
  1626. package/dist/tools/math-tools.d.ts +0 -156
  1627. package/dist/tools/math-tools.d.ts.map +0 -1
  1628. package/dist/tools/math-tools.js +0 -422
  1629. package/dist/tools/math-tools.js.map +0 -1
  1630. package/dist/tools/model-tools.d.ts +0 -25
  1631. package/dist/tools/model-tools.d.ts.map +0 -1
  1632. package/dist/tools/model-tools.js +0 -48
  1633. package/dist/tools/model-tools.js.map +0 -1
  1634. package/dist/tools/pdf-tools.d.ts +0 -152
  1635. package/dist/tools/pdf-tools.d.ts.map +0 -1
  1636. package/dist/tools/pdf-tools.js +0 -339
  1637. package/dist/tools/pdf-tools.js.map +0 -1
  1638. package/dist/tools/tool-registry.d.ts +0 -9
  1639. package/dist/tools/tool-registry.d.ts.map +0 -1
  1640. package/dist/tools/tool-registry.js +0 -17
  1641. package/dist/tools/tool-registry.js.map +0 -1
  1642. package/dist/tools/workspace-tools.d.ts +0 -58
  1643. package/dist/tools/workspace-tools.d.ts.map +0 -1
  1644. package/dist/tools/workspace-tools.js +0 -152
  1645. package/dist/tools/workspace-tools.js.map +0 -1
@@ -1,27 +1,79 @@
1
1
  /**
2
2
  * Shared sandboxed JavaScript execution engine.
3
3
  *
4
- * Used by both the MiniJSAgentTool (agent tool) and the CodeNode (workflow node).
4
+ * Used by the CodeAct executor (agent actions) and the CodeNode (workflow node).
5
5
  * Runs user code in an isolated QuickJS WebAssembly context — the guest has its
6
6
  * own heap inside the WASM instance, so there is a real memory/CPU boundary
7
7
  * between host and guest (unlike Node's `node:vm`, which shares the V8 heap).
8
8
  *
9
9
  * The exposed surface is a small curated one: vanilla JavaScript plus a handful
10
- * of bridge functions (`fetch`, `workspace`, `getSecret`, `uuid`, `sleep`,
11
- * `assetToSandbox`, `sandboxToAsset`, `console`). Library-powered helpers
12
- * (lodash, dayjs, cheerio, csv-parse,
13
- * validator) are intentionally NOT exposed here — use the dedicated workflow
14
- * nodes instead (lib.datetime.*, lib.html.*, lib.data.ParseCSV,
15
- * lib.validate.*, etc.). Keeping the sandbox lib-free makes snippet behaviour
16
- * identical between dev and packaged Electron, and avoids shipping those
17
- * packages into the user-code surface.
10
+ * of bridge functions (`fetch`, `workspace`, `getSecret`, `sleep`,
11
+ * `assetToSandbox`, `sandboxToAsset`, `crypto`, `console`, `progress`,
12
+ * `format`, `image`, `canvas`) and a few pure guest-side helpers
13
+ * (`toBase64`, `fromBase64`, `toHex`, `fromHex`,
14
+ * `parallelMap`, `createCanvas`). `crypto`
15
+ * covers `randomUUID`, `getRandomValues`, `digest`, and `hmac`
16
+ * (WebCrypto-backed); `workspace` covers text and binary reads/writes plus
17
+ * `stat`, `mkdir`, and `remove`; `progress` forwards a percentage and label to
18
+ * the host caller (rate-limited); `console.*` appends to the run's `logs`
19
+ * array and, when the caller set {@link RunSandboxOptions.onLog}, forwards
20
+ * each line live (capped); `format` exposes host `Intl` number, date,
21
+ * relative-time and list formatting, which QuickJS itself does not ship.
22
+ * Every quantitative limit (fetch calls, response body, output size,
23
+ * guest heap, stack, fetch timeout) is overridable per invocation through
24
+ * `RunSandboxOptions.limits`, clamped to hard ceilings.
25
+ *
26
+ * The guest imports nothing by default — without `RunSandboxOptions.modules`
27
+ * every specifier is denied by name, so user code cannot `import`/`require`
28
+ * anything. With it, the run's resolved sandbox packages and their intra-pack
29
+ * siblings are the only importable modules (see {@link createGuestModuleHost}),
30
+ * and dynamic `import()` stays denied.
31
+ *
32
+ * **Every library the sandbox offers is an importable module.** Some are guest
33
+ * modules the compiler admitted (js-yaml, date-fns); the rest are *host
34
+ * modules* — papaparse, cheerio, exceljs, fflate and friends — which run on the
35
+ * host behind a generated ESM facade over a per-run dispatcher
36
+ * (`host-modules/`), because they need Node builtins the guest lacks or carry a
37
+ * limit the guest could not enforce. Either way the guest writes `import`, and
38
+ * the pack has to be installed. The remaining globals — `fetch`,
39
+ * `workspace`, `getSecret`, the asset bridges, `format.*` (Intl), `crypto.*`
40
+ * (WebCrypto), `image.*`/`canvas.*` — are not libraries: they are the
41
+ * capabilities the node granted this run.
42
+ *
43
+ * The sandbox is fully asynchronous. Every host bridge call returns a real
44
+ * promise, and a bridge call starts its host-side work the moment it is
45
+ * invoked — not when it is awaited — so `Promise.all` (and `allSettled`,
46
+ * `race`, `any`) over bridge calls runs them in parallel on the host. Five
47
+ * fetches under `Promise.all` take one round trip, not five. `parallelMap`
48
+ * is the bounded form of that fan-out. `sleep` is the only timer: the
49
+ * timer globals (`setTimeout` and friends) are deleted inside the user-code
50
+ * module (see {@link wrapCode}), because timer callbacks would run outside
51
+ * the never-reject/abort-guard conventions every bridge follows.
18
52
  */
19
- import { addSerializer, expose, loadQuickJs } from "@sebastianwessel/quickjs";
20
- // The variant package uses a `default` export. With `esModuleInterop` this
21
- // typechecks as a namespace, so reach through `.default` explicitly.
53
+ import { SANDBOX_CAPABILITY_DISPATCH_GLOBAL, SANDBOX_WASM_DISPATCH_GLOBAL } from "@nodetool-ai/protocol";
54
+ import { createSandboxHostDispatcher } from "./host-modules/dispatcher.js";
55
+ import { EXPOSED_BRIDGE_NAMES, MAX_ENGINE_TIMEOUT_MS, NO_INPUT_STREAM_MESSAGE, registerTypedArraySerializers, runInterpreter, SANDBOX_CAPABILITY_BRIDGE_BINDING, SANDBOX_INPUT_TAKE_BINDING, SANDBOX_STREAM_OPEN_BINDING, SANDBOX_WASM_BRIDGE_BINDING } from "./js-sandbox-worker/interpreter.js";
56
+ import { SANDBOX_SERIALIZE_MAX_DEPTH, toGuestBytes, toGuestBytesDeep } from "./sandbox-bytes.js";
57
+ import { isBoolean, isFunction, isNonEmptyString, isNumber, isObjectLike, isRecord, isString } from "./utils/type-guards.js";
58
+ import { createSandboxMediaStore, isSandboxMediaHandle, MAX_RUN_MEDIA_BYTES } from "./sandbox-media-handle.js";
59
+ import { createMediaRefBridge, looksLikeMediaRef, mimeForRef, remapMediaRef, resolveRefBytes } from "./sandbox-media-ref.js";
60
+ import { createSandboxWasmDispatcher } from "./wasm-sandbox/host.js";
61
+ import { runInWorker } from "./js-sandbox-worker/host.js";
62
+ import { assertFetchUrlAllowed, assertResolvedHostAllowed } from "./network-guard.js";
63
+ import { GUEST_GLOBALS_JSON_BINDING, GUEST_GLOBALS_SIDECAR_BINDING, GUEST_MARSHAL_GLOBAL } from "./sandbox-json-transport.js";
64
+ import { MAX_RANDOM_BYTES } from "./sandbox-constants.js";
65
+ import { deriveBridgeShape, precheckCloneSafety, SANDBOX_DISPATCHER_BINDINGS } from "./js-sandbox-worker/protocol.js";
22
66
  import * as quickJsVariantModule from "@jitl/quickjs-ng-wasmfile-release-sync";
67
+ /**
68
+ * The variant package is CJS with a `default` export, so `ns.default` is the
69
+ * variant at runtime.
70
+ */
71
+ // SAFETY: TypeScript's CJS interop synthesizes `default` as the whole module
72
+ // object, contradicting the package's own `.d.ts`, which declares it as the
73
+ // `QuickJSSyncVariant` this reads.
23
74
  const quickJsVariant = quickJsVariantModule.default;
24
- import { Scope } from "quickjs-emscripten-core";
75
+ import { importNodeBuiltin } from "@nodetool-ai/config";
76
+ import { loadSandboxEngine } from "./js-sandbox-worker/engine.js";
25
77
  // ---------------------------------------------------------------------------
26
78
  // Constants
27
79
  // ---------------------------------------------------------------------------
@@ -34,77 +86,185 @@ export const MAX_RESPONSE_BODY_SIZE = 1_000_000;
34
86
  export const GUEST_MEMORY_LIMIT = 64 * 1024 * 1024;
35
87
  /** Guest stack cap — protects against deeply recursive code. */
36
88
  export const GUEST_STACK_LIMIT = 512 * 1024;
89
+ /** Per-request wall-clock cap for the fetch bridge. */
90
+ export const FETCH_TIMEOUT_MS = 15_000;
91
+ /** Redirect hops the fetch bridge follows before giving up. */
92
+ export const MAX_FETCH_REDIRECTS = 5;
93
+ /** Locale used by the `format` bridge when the caller names none. */
94
+ export const DEFAULT_FORMAT_LOCALE = "en-US";
95
+ export { MAX_RANDOM_BYTES };
96
+ /** Progress reports forwarded to the host per run; further calls are dropped. */
97
+ export const MAX_PROGRESS_CALLS = 1000;
98
+ /** Console lines forwarded to {@link RunSandboxOptions.onLog} per run. */
99
+ export const MAX_CONSOLE_LOGS = 1000;
100
+ /** Longest console line forwarded to the host. A collected line is not truncated on its own. */
101
+ export const MAX_CONSOLE_LOG_CHARS = 4000;
102
+ /**
103
+ * Console lines the run's `logs` array collects. Forwarding was capped and
104
+ * collection was not: guest strings are not charged to the QuickJS heap, so a
105
+ * `console.log` in a hot loop grew host memory for the length of the action.
106
+ */
107
+ export const MAX_COLLECTED_CONSOLE_LOGS = 5000;
108
+ /** Characters the run's `logs` array collects in total, across every line. */
109
+ export const MAX_COLLECTED_CONSOLE_CHARS = 512 * 1024;
110
+ /** The single line that closes a collected log the caps cut. */
111
+ export const CONSOLE_LOGS_CUT_NOTICE = `[console output cut: at most ${MAX_COLLECTED_CONSOLE_LOGS} lines / ` +
112
+ `${MAX_COLLECTED_CONSOLE_CHARS} characters are kept per run]`;
113
+ /**
114
+ * Emitted values a run may deliver. Unlike progress reports, emits are never
115
+ * dropped or rate-limited — every value reaches the host in call order — so the
116
+ * cap is enforced by throwing in the guest rather than by ignoring the call.
117
+ */
118
+ export const MAX_EMIT_CALLS = 10_000;
119
+ /** Minimum gap between two forwarded progress reports. */
120
+ export const PROGRESS_MIN_INTERVAL_MS = 100;
121
+ /** Longest progress message forwarded to the host. */
122
+ export const MAX_PROGRESS_MESSAGE_CHARS = 500;
123
+ /**
124
+ * Headroom added to the engine's own wall-clock abort when a {@link SandboxClock}
125
+ * is in play. The clock only stops the *guest's* budget; this bounds how long a
126
+ * run may stay suspended in total, so a prompt nobody ever answers still ends.
127
+ */
128
+ export const DEFAULT_SUSPEND_ALLOWANCE_MS = 30 * 60 * 1000;
129
+ /**
130
+ * Suspension allowance a run with an input stream gets by default.
131
+ *
132
+ * Effectively unbounded, deliberately: a streaming body legitimately lives as
133
+ * long as its upstream produces, and the run's own cancellation is the lifetime
134
+ * bound. A stream that never ends is the upstream's bug, surfaced by the
135
+ * runner — not a reason to kill a correct consumer. A caller that wants a
136
+ * shorter leash passes {@link RunSandboxOptions.suspendAllowanceMs}.
137
+ */
138
+ export const INPUT_STREAM_SUSPEND_ALLOWANCE_MS = MAX_ENGINE_TIMEOUT_MS;
139
+ /**
140
+ * What the guest is told when it calls `stream` in a run that has no input
141
+ * stream behind it. Shared by the host bridge and the guest prelude so both
142
+ * paths say the same thing — the prelude lives with the interpreter, so the
143
+ * message does too.
144
+ */
145
+ export { NO_INPUT_STREAM_MESSAGE } from "./js-sandbox-worker/interpreter.js";
146
+ /**
147
+ * Normalize a declared secret scope: a list of non-empty names, or `null` for
148
+ * an unscoped run. An empty declared list stays empty — it denies everything.
149
+ */
150
+ function resolveSecretScope(scope) {
151
+ if (!Array.isArray(scope))
152
+ return null;
153
+ return scope
154
+ .filter((name) => typeof name === "string" && name !== "")
155
+ .map((name) => name.trim())
156
+ .filter((name) => name !== "");
157
+ }
158
+ function clampLimit(value, fallback, min, max) {
159
+ if (value == null || !Number.isFinite(value))
160
+ return fallback;
161
+ return Math.min(Math.max(Math.floor(value), min), max);
162
+ }
163
+ /** Apply defaults and ceilings to a caller-supplied {@link SandboxLimits}. */
164
+ export function resolveSandboxLimits(limits) {
165
+ return {
166
+ maxFetchCalls: clampLimit(limits?.maxFetchCalls, MAX_FETCH_CALLS, 0, 100),
167
+ maxResponseBodyBytes: clampLimit(limits?.maxResponseBodyBytes, MAX_RESPONSE_BODY_SIZE, 1024, 50 * 1024 * 1024),
168
+ maxOutputSize: clampLimit(limits?.maxOutputSize, MAX_OUTPUT_SIZE, 1024, 10 * 1024 * 1024),
169
+ memoryLimitBytes: clampLimit(limits?.memoryLimitBytes, GUEST_MEMORY_LIMIT, 1024 * 1024, 512 * 1024 * 1024),
170
+ runMediaBytes: clampLimit(limits?.runMediaBytes, MAX_RUN_MEDIA_BYTES, 1024 * 1024, 2 * 1024 * 1024 * 1024),
171
+ stackLimitBytes: clampLimit(limits?.stackLimitBytes, GUEST_STACK_LIMIT, 16 * 1024, 8 * 1024 * 1024),
172
+ fetchTimeoutMs: clampLimit(limits?.fetchTimeoutMs, FETCH_TIMEOUT_MS, 100, 120_000),
173
+ // Not clamped — these are capability switches, not magnitudes. Both
174
+ // resolve to the restrictive value unless the host explicitly opts out.
175
+ allowPrivateNetwork: limits?.allowPrivateNetwork === true,
176
+ userAgent: limits?.userAgent ?? "",
177
+ filesystemAccess: limits?.filesystemAccess === "host" ? "host" : "workspace",
178
+ secretScope: resolveSecretScope(limits?.secretScope)
179
+ };
180
+ }
37
181
  // ---------------------------------------------------------------------------
38
182
  // Engine bootstrap — one WASM module shared by every invocation.
39
183
  // ---------------------------------------------------------------------------
40
184
  let enginePromise = null;
41
- let serializersRegistered = false;
42
- function registerTypedArraySerializers() {
43
- if (serializersRegistered)
44
- return;
45
- serializersRegistered = true;
46
- // Map every typed-array class to a native Uint8Array on the host side.
47
- // The guest returns `new Uint8Array([...])` (or friends); without this,
48
- // the library's generic object serializer produces a plain object with
49
- // numeric keys, which downstream code (CodeNode's normalizeOutput) would
50
- // miss when detecting binary values.
51
- const typedArrayNames = [
52
- "Uint8Array",
53
- "Int8Array",
54
- "Uint8ClampedArray",
55
- "Int16Array",
56
- "Uint16Array",
57
- "Int32Array",
58
- "Uint32Array",
59
- "Float32Array",
60
- "Float64Array"
61
- ];
62
- for (const name of typedArrayNames) {
63
- addSerializer(name, (ctx, handle) => {
64
- const bufferHandle = ctx.getProp(handle, "buffer");
65
- try {
66
- const ab = ctx.getArrayBuffer(bufferHandle);
67
- return Uint8Array.from(ab.value);
68
- }
69
- finally {
70
- bufferHandle.dispose();
71
- }
72
- });
73
- }
74
- }
75
185
  function getEngine() {
76
186
  registerTypedArraySerializers();
77
187
  if (!enginePromise) {
78
- enginePromise = loadQuickJs(quickJsVariant);
188
+ enginePromise = loadSandboxEngine(quickJsVariant);
79
189
  }
80
190
  return enginePromise;
81
191
  }
82
192
  /**
83
- * Marker key placed on an object to signal a sandboxed error. A host async
84
- * function that would normally `throw` instead resolves with one of these
85
- * objects; a prelude inside the guest rewraps them as real guest-side errors.
193
+ * The guest engine can fail in two ways that never reach `runInSandbox`'s own
194
+ * `await`, and both used to end the same way: the host process died, the tool
195
+ * call it was serving returned *nothing*, and the agent driving it saw a turn
196
+ * that simply stopped. A missing result is worse than any error — there is
197
+ * nothing to read and nothing to retry.
198
+ *
199
+ * 1. An Emscripten `abort()` (the `list_empty(&rt->gc_obj_list)` assertion in
200
+ * `JS_FreeRuntime`) surfaces as a `RuntimeError` from the WASM module.
201
+ * 2. A marshaling failure — most often guest OOM while a host return value is
202
+ * being written into the guest — throws inside a promise continuation the
203
+ * library created and never catches, so it lands as an unhandled rejection.
86
204
  *
87
- * This indirection exists because the current `@sebastianwessel/quickjs`
88
- * runtime leaks handles whenever a host-backed guest Promise is *rejected*,
89
- * tripping an internal assertion (`list_empty(&rt->gc_obj_list)`) in
90
- * quickjs-ng when the runtime is freed. Routing failures through a resolved
91
- * tagged value sidesteps the leak while preserving the guest-visible
92
- * behaviour (the user still gets a thrown Error with name + message).
205
+ * `guardHostProcess` races the run against those escapes. A rejection that
206
+ * looks like the engine's fails the run; anything else is re-thrown on the next
207
+ * tick so a genuine host bug still crashes the way it should.
93
208
  */
94
- const SANDBOX_ERROR_MARKER = "__nodetool_sandbox_error__";
95
- function neverReject(fn) {
96
- return async (...args) => {
97
- try {
98
- return await fn(...args);
99
- }
100
- catch (e) {
101
- return {
102
- [SANDBOX_ERROR_MARKER]: true,
103
- name: e instanceof Error ? e.name : "Error",
104
- message: e instanceof Error ? e.message : String(e)
105
- };
106
- }
107
- };
209
+ function isEngineFailure(error) {
210
+ const name = error?.constructor?.name ?? "";
211
+ const message = String(error?.message ?? error);
212
+ const stack = String(error?.stack ?? "");
213
+ return (name.startsWith("QuickJS") ||
214
+ message.includes("Assertion failed") ||
215
+ message.includes("gc_obj_list") ||
216
+ /\bAborted\(/.test(message) ||
217
+ stack.includes("quickjs"));
218
+ }
219
+ /** The agent-facing translation of an engine failure. */
220
+ export function describeEngineFailure(error) {
221
+ const message = String(error?.message ?? error);
222
+ if (/gc_obj_list|Assertion failed|\bAborted\(/.test(message)) {
223
+ return ("The JavaScript sandbox runtime aborted while cleaning up, so this " +
224
+ "action has no usable result. Host operations may already have completed. " +
225
+ "This is an internal sandbox cleanup failure. Inspect the execution " +
226
+ "before retrying any operation that writes data.");
227
+ }
228
+ if (/out of memory/i.test(message)) {
229
+ return ("The JavaScript sandbox ran out of guest memory, so this action " +
230
+ "produced no result. Retry with less data held live at once.");
231
+ }
232
+ return message;
233
+ }
234
+ async function guardHostProcess(run) {
235
+ // `process` is a Node global; the browser bundle (the in-process fallback
236
+ // path there) has none, and there is no host process to guard against an
237
+ // engine abort escaping as an unhandled rejection anyway.
238
+ const nodeProcess = globalThis.process;
239
+ if (!nodeProcess?.on || !nodeProcess?.off) {
240
+ return run;
241
+ }
242
+ let onRejection;
243
+ const escaped = new Promise((_resolve, reject) => {
244
+ onRejection = (reason) => {
245
+ if (isEngineFailure(reason)) {
246
+ reject(reason instanceof Error ? reason : new Error(String(reason)));
247
+ return;
248
+ }
249
+ // Not ours. Restore the default "unhandled rejection crashes the
250
+ // process" behaviour rather than silently swallowing someone's bug.
251
+ setImmediate(() => {
252
+ throw reason;
253
+ });
254
+ };
255
+ nodeProcess.on("unhandledRejection", onRejection);
256
+ });
257
+ try {
258
+ return await Promise.race([run, escaped]);
259
+ }
260
+ finally {
261
+ if (onRejection)
262
+ nodeProcess.off("unhandledRejection", onRejection);
263
+ // The loser of the race stays pending forever; make sure neither promise
264
+ // can later re-trigger the default handler.
265
+ void escaped.catch(() => { });
266
+ void run.then?.(() => { }, () => { });
267
+ }
108
268
  }
109
269
  // ---------------------------------------------------------------------------
110
270
  // Helpers
@@ -114,12 +274,157 @@ export function truncate(text, max) {
114
274
  return text;
115
275
  return text.slice(0, max) + "\n...[truncated]";
116
276
  }
277
+ /**
278
+ * Load `node:fs/promises` via a bundler-hidden import so a browser/edge bundle
279
+ * never tries to resolve it. The `workspace.*` bridge is wired only when a
280
+ * `ProcessingContext` is present, and these loaders run only when guest code
281
+ * actually calls `workspace.read/write/list` — off-Node that path throws
282
+ * (`importNodeBuiltin` resolves `null`), which `neverReject` surfaces to the
283
+ * guest as a normal error.
284
+ */
285
+ async function loadFsPromises() {
286
+ const fs = await importNodeBuiltin("node:fs/promises");
287
+ if (!fs)
288
+ throw new Error("workspace file access requires a Node.js runtime");
289
+ return fs;
290
+ }
291
+ async function loadNodePath() {
292
+ const nodePath = await importNodeBuiltin("node:path");
293
+ if (!nodePath) {
294
+ throw new Error("workspace file access requires a Node.js runtime");
295
+ }
296
+ return nodePath;
297
+ }
298
+ /**
299
+ * Verify a workspace path's real (symlink-resolved) location stays within the
300
+ * real workspace root before an fs operation. resolveWorkspacePath only checks
301
+ * containment lexically, so an in-workspace symlink pointing outside the root
302
+ * would otherwise be dereferenced (arbitrary host file read/write). For a write
303
+ * to a not-yet-existing file, the parent directory is checked instead. Throws
304
+ * on an escape.
305
+ *
306
+ * TOCTOU: the realpath check and the fs op that follows it are separate awaits,
307
+ * and guest bridge calls run concurrently (Promise.all), so an in-workspace
308
+ * symlink could be swapped to point outside between this check and the caller's
309
+ * read/write. Keeping this the last step before the op narrows the window but
310
+ * does not close it — a full fix needs fd-based ops (O_NOFOLLOW / openat), which
311
+ * node:fs/promises does not expose. Accepted as low-risk: it needs a local
312
+ * attacker racing a symlink swap inside the workspace, and both surfaces here
313
+ * (Code node, CodeAct actions) run first-party or already-trusted code.
314
+ */
315
+ async function assertWorkspaceContained(context, fs, nodePath, fullPath, isWrite) {
316
+ const within = async (root, candidate) => {
317
+ try {
318
+ const realRoot = await fs.realpath(root);
319
+ const realCandidate = await fs.realpath(candidate);
320
+ if (realRoot === realCandidate)
321
+ return true;
322
+ const rel = nodePath.relative(realRoot, realCandidate);
323
+ return rel !== "" && !rel.startsWith("..") && !nodePath.isAbsolute(rel);
324
+ }
325
+ catch {
326
+ return false;
327
+ }
328
+ };
329
+ const root = context.resolveWorkspacePath(".");
330
+ if (await within(root, fullPath))
331
+ return;
332
+ if (isWrite) {
333
+ // Target may not exist yet — lstat detects a dangling symlink entry, and
334
+ // otherwise the nearest existing ancestor must be inside the workspace.
335
+ // Walking up covers writes and mkdirs that create several levels at once;
336
+ // path segments that don't exist yet cannot be symlinks, so nothing along
337
+ // the way can redirect the write.
338
+ try {
339
+ await fs.lstat(fullPath);
340
+ // Exists (real file or symlink) but failed containment → outside root.
341
+ }
342
+ catch {
343
+ let dir = nodePath.dirname(fullPath);
344
+ for (;;) {
345
+ let exists = true;
346
+ try {
347
+ await fs.lstat(dir);
348
+ }
349
+ catch {
350
+ exists = false;
351
+ }
352
+ if (exists) {
353
+ if (await within(root, dir))
354
+ return;
355
+ break;
356
+ }
357
+ const parent = nodePath.dirname(dir);
358
+ if (parent === dir)
359
+ break;
360
+ dir = parent;
361
+ }
362
+ }
363
+ }
364
+ throw new Error(`workspace path resolves outside the workspace: ${fullPath}`);
365
+ }
366
+ /**
367
+ * The media engine behind the `image` and `canvas` bridges. Loaded on first
368
+ * use like the host modules, and for the same reasons — the canvas backend
369
+ * (Skia on Node) is heavy, and nothing that never draws should pay for it.
370
+ * Unlike those, the import is intra-package, so every bundler resolves it.
371
+ */
372
+ async function loadSandboxMedia() {
373
+ return import("./sandbox-media.js");
374
+ }
375
+ /** Audio/video adapters are loaded only when a run uses those namespaces. */
376
+ async function loadSandboxAvMedia() {
377
+ return import("./sandbox-av-media.js");
378
+ }
379
+ /**
380
+ * Read a fetch Response body into a Uint8Array bounded by `maxBytes`. Aborts the
381
+ * transfer via `controller` once the cap is exceeded so an oversized/fast
382
+ * response cannot buffer unbounded host memory.
383
+ */
384
+ async function readBodyCapped(response, controller, maxBytes) {
385
+ if (!response.body) {
386
+ // No stream (e.g. empty body) — fall back, then clamp.
387
+ const buf = new Uint8Array(await response.arrayBuffer());
388
+ return buf.length > maxBytes ? buf.slice(0, maxBytes) : buf;
389
+ }
390
+ const reader = response.body.getReader();
391
+ const chunks = [];
392
+ let total = 0;
393
+ try {
394
+ for (;;) {
395
+ const { done, value } = await reader.read();
396
+ if (done)
397
+ break;
398
+ if (!value)
399
+ continue;
400
+ chunks.push(value);
401
+ total += value.byteLength;
402
+ if (total >= maxBytes) {
403
+ controller.abort();
404
+ break;
405
+ }
406
+ }
407
+ }
408
+ catch {
409
+ // Aborted or network error mid-read — return what we have.
410
+ }
411
+ const out = new Uint8Array(Math.min(total, maxBytes));
412
+ let offset = 0;
413
+ for (const c of chunks) {
414
+ if (offset >= out.length)
415
+ break;
416
+ const take = Math.min(c.byteLength, out.length - offset);
417
+ out.set(c.subarray(0, take), offset);
418
+ offset += take;
419
+ }
420
+ return out;
421
+ }
117
422
  function formatArg(arg) {
118
423
  if (arg === null)
119
424
  return "null";
120
425
  if (arg === undefined)
121
426
  return "undefined";
122
- if (typeof arg === "string")
427
+ if (isString(arg))
123
428
  return arg;
124
429
  try {
125
430
  return JSON.stringify(arg, null, 2);
@@ -129,15 +434,20 @@ function formatArg(arg) {
129
434
  }
130
435
  }
131
436
  function isTypedArray(value) {
132
- if (!value || typeof value !== "object")
437
+ if (!isObjectLike(value))
133
438
  return false;
134
439
  const name = value.constructor?.name;
135
- return name === "Uint8Array" || name === "Buffer" ||
136
- name === "Int8Array" || name === "Uint8ClampedArray" ||
137
- name === "Int16Array" || name === "Uint16Array" ||
138
- name === "Int32Array" || name === "Uint32Array" ||
139
- name === "Float32Array" || name === "Float64Array" ||
140
- name === "ArrayBuffer";
440
+ return (name === "Uint8Array" ||
441
+ name === "Buffer" ||
442
+ name === "Int8Array" ||
443
+ name === "Uint8ClampedArray" ||
444
+ name === "Int16Array" ||
445
+ name === "Uint16Array" ||
446
+ name === "Int32Array" ||
447
+ name === "Uint32Array" ||
448
+ name === "Float32Array" ||
449
+ name === "Float64Array" ||
450
+ name === "ArrayBuffer");
141
451
  }
142
452
  function toNativeUint8Array(value) {
143
453
  const v = value;
@@ -147,54 +457,128 @@ function toNativeUint8Array(value) {
147
457
  arr[i] = v[i] ?? 0;
148
458
  return arr;
149
459
  }
460
+ const DIGEST_ALGORITHMS = {
461
+ "SHA-1": "SHA-1",
462
+ SHA1: "SHA-1",
463
+ "SHA-256": "SHA-256",
464
+ SHA256: "SHA-256",
465
+ "SHA-384": "SHA-384",
466
+ SHA384: "SHA-384",
467
+ "SHA-512": "SHA-512",
468
+ SHA512: "SHA-512"
469
+ };
470
+ function normalizeDigestAlgorithm(algorithm) {
471
+ const key = String(algorithm ?? "")
472
+ .trim()
473
+ .toUpperCase();
474
+ const resolved = DIGEST_ALGORITHMS[key];
475
+ if (!resolved) {
476
+ throw new Error(`crypto: unsupported algorithm "${String(algorithm)}" (use SHA-1, SHA-256, SHA-384 or SHA-512)`);
477
+ }
478
+ return resolved;
479
+ }
480
+ /** Accept a guest string or byte-like value as host bytes. */
481
+ function coerceBytesInput(value, label) {
482
+ if (isString(value))
483
+ return new TextEncoder().encode(value);
484
+ if (value instanceof Uint8Array)
485
+ return Uint8Array.from(value);
486
+ if (isTypedArray(value))
487
+ return toNativeUint8Array(value);
488
+ if (Array.isArray(value))
489
+ return Uint8Array.from(value.map(Number));
490
+ if (isObjectLike(value) && isNumber(value.length)) {
491
+ return toNativeUint8Array(value);
492
+ }
493
+ throw new Error(`crypto: ${label} must be a string or Uint8Array`);
494
+ }
495
+ function webCryptoSubtle() {
496
+ const subtle = globalThis.crypto?.subtle;
497
+ if (!subtle) {
498
+ throw new Error("crypto: WebCrypto (crypto.subtle) is not available");
499
+ }
500
+ return subtle;
501
+ }
502
+ /** Depth ceiling for the binary-preserving walk — guards pathological nesting. */
503
+ const SERIALIZE_MAX_DEPTH = 32;
504
+ /**
505
+ * True if a typed array sits anywhere inside `value`. Cycle-safe: a revisited
506
+ * object reports false, which drops the value onto the JSON path, where
507
+ * `JSON.stringify` throws on the cycle and the caller falls back to `String` —
508
+ * the behavior cyclic values already had.
509
+ */
510
+ function containsTypedArray(value, depth = 0, seen = new WeakSet()) {
511
+ if (isTypedArray(value))
512
+ return true;
513
+ if (!isObjectLike(value))
514
+ return false;
515
+ if (depth >= SERIALIZE_MAX_DEPTH)
516
+ return false;
517
+ const obj = value;
518
+ if (seen.has(obj))
519
+ return false;
520
+ seen.add(obj);
521
+ const values = Array.isArray(value)
522
+ ? value
523
+ : Object.values(value);
524
+ return values.some((v) => containsTypedArray(v, depth + 1, seen));
525
+ }
526
+ /**
527
+ * Rebuild `value`, converting every typed array at any depth to a native
528
+ * Uint8Array and leaving everything else structurally intact.
529
+ */
530
+ function convertTypedArraysDeep(value, depth = 0, seen = new WeakSet()) {
531
+ if (isTypedArray(value))
532
+ return toNativeUint8Array(value);
533
+ if (!isObjectLike(value))
534
+ return value;
535
+ if (depth >= SERIALIZE_MAX_DEPTH)
536
+ return value;
537
+ const obj = value;
538
+ if (seen.has(obj))
539
+ return null;
540
+ seen.add(obj);
541
+ if (Array.isArray(value)) {
542
+ return value.map((v) => convertTypedArraysDeep(v, depth + 1, seen));
543
+ }
544
+ const out = {};
545
+ for (const [k, v] of Object.entries(value)) {
546
+ out[k] = convertTypedArraysDeep(v, depth + 1, seen);
547
+ }
548
+ return out;
549
+ }
150
550
  /**
151
551
  * Recursively serialize a value returned from the sandbox, converting typed
152
552
  * arrays to native Uint8Array and enforcing output size limits.
153
553
  */
154
- export function serializeResult(result) {
554
+ export function serializeResult(result, maxOutputSize = MAX_OUTPUT_SIZE) {
155
555
  if (result === undefined)
156
556
  return null;
157
557
  if (result === null)
158
558
  return null;
159
- if (typeof result === "string" ||
160
- typeof result === "number" ||
161
- typeof result === "boolean") {
162
- if (typeof result === "string" && result.length > MAX_OUTPUT_SIZE) {
163
- return truncate(result, MAX_OUTPUT_SIZE);
559
+ if (isString(result) || isNumber(result) || isBoolean(result)) {
560
+ if (isString(result) && result.length > maxOutputSize) {
561
+ return truncate(result, maxOutputSize);
164
562
  }
165
563
  return result;
166
564
  }
167
565
  if (isTypedArray(result)) {
168
566
  return toNativeUint8Array(result);
169
567
  }
170
- if (typeof result === "object") {
171
- let hasBinary = false;
172
- if (Array.isArray(result)) {
173
- hasBinary = result.some(isTypedArray);
174
- }
175
- else {
176
- for (const v of Object.values(result)) {
177
- if (isTypedArray(v)) {
178
- hasBinary = true;
179
- break;
180
- }
181
- }
182
- }
183
- if (hasBinary) {
184
- if (Array.isArray(result)) {
185
- return result.map(v => isTypedArray(v) ? toNativeUint8Array(v) : v);
186
- }
187
- const obj = result;
188
- const out = {};
189
- for (const [k, v] of Object.entries(obj)) {
190
- out[k] = isTypedArray(v) ? toNativeUint8Array(v) : v;
191
- }
192
- return out;
568
+ if (isObjectLike(result)) {
569
+ // The scan and the rebuild are both deep. They used to look one level in,
570
+ // so a typed array nested any deeper fell through to the JSON path below —
571
+ // and `JSON.stringify(new Uint8Array([137, 80]))` is `{"0":137,"1":80}`,
572
+ // which is lossy and indistinguishable from a user's own integer map. The
573
+ // streaming path hit this every time: `genProcess` returns an array of
574
+ // yielded objects, so the bytes are always at depth 2.
575
+ if (containsTypedArray(result)) {
576
+ return convertTypedArraysDeep(result);
193
577
  }
194
578
  try {
195
579
  const json = JSON.stringify(result);
196
- if (json.length > MAX_OUTPUT_SIZE) {
197
- return truncate(json, MAX_OUTPUT_SIZE);
580
+ if (json.length > maxOutputSize) {
581
+ return truncate(json, maxOutputSize);
198
582
  }
199
583
  return JSON.parse(json);
200
584
  }
@@ -233,50 +617,253 @@ export function cleanStack(stack) {
233
617
  *
234
618
  * @param context Optional ProcessingContext — when provided, enables
235
619
  * `workspace.*` and `getSecret()` APIs.
620
+ * @param signal Optional external cancellation. Aborts in-flight host
621
+ * operations and makes `sleep` return immediately.
622
+ * @param limits Optional per-invocation limit overrides, clamped by
623
+ * {@link resolveSandboxLimits}.
624
+ * @param onProgress Optional sink for guest `progress()` calls. Without one the
625
+ * guest function is a no-op.
626
+ * @param onLog Optional sink for guest `console.*` calls. Without one the
627
+ * lines still land in {@link SandboxResult}'s `getLogs`.
628
+ * @param onEmit Optional sink for guest `emit()` calls. Without one the values
629
+ * are collected and handed back through `getEmitted`.
630
+ * @param streams Optional input bridges behind the guest `stream` global.
631
+ * Without an `onTakeInput` every `stream` call throws
632
+ * {@link NO_INPUT_STREAM_MESSAGE}.
633
+ * @param resolveMediaRef Optional host loader for media refs when this run
634
+ * has no ProcessingContext (chat). `image.*` uses it so a
635
+ * generation result can go straight into the next op.
236
636
  */
237
- export function buildSandbox(context) {
637
+ export function buildSandbox(context, signal, limits, onProgress, onLog, onEmit, streams, resolveMediaRef, promoteMedia, resolveHost) {
238
638
  const logs = [];
639
+ const resolvedLimits = resolveSandboxLimits(limits);
239
640
  let fetchCount = 0;
641
+ let forwardedLogs = 0;
642
+ let collectedChars = 0;
643
+ let collectionCut = false;
644
+ // Bounded by count and by bytes; the cut is noted once, then nothing more
645
+ // is kept. A line that does not fit whole keeps the head that does.
646
+ const collectLog = (entry) => {
647
+ if (collectionCut)
648
+ return;
649
+ const remaining = MAX_COLLECTED_CONSOLE_CHARS - collectedChars;
650
+ if (logs.length < MAX_COLLECTED_CONSOLE_LOGS && entry.length <= remaining) {
651
+ logs.push(entry);
652
+ collectedChars += entry.length;
653
+ return;
654
+ }
655
+ if (logs.length < MAX_COLLECTED_CONSOLE_LOGS && remaining > 0) {
656
+ logs.push(entry.slice(0, remaining));
657
+ }
658
+ collectionCut = true;
659
+ logs.push(CONSOLE_LOGS_CUT_NOTICE);
660
+ };
661
+ const pushConsole = (level, prefix, args) => {
662
+ const line = args.map(formatArg).join(" ");
663
+ collectLog(prefix + line);
664
+ if (!onLog || signal?.aborted)
665
+ return;
666
+ if (forwardedLogs >= MAX_CONSOLE_LOGS)
667
+ return;
668
+ forwardedLogs++;
669
+ const message = line.length > MAX_CONSOLE_LOG_CHARS
670
+ ? line.slice(0, MAX_CONSOLE_LOG_CHARS)
671
+ : line;
672
+ try {
673
+ onLog(level, message);
674
+ }
675
+ catch {
676
+ // A failing host sink must not take the guest run down with it.
677
+ }
678
+ };
240
679
  const console = {
241
680
  log: (...args) => {
242
- logs.push(args.map(formatArg).join(" "));
681
+ pushConsole("log", "", args);
243
682
  },
244
683
  warn: (...args) => {
245
- logs.push("[warn] " + args.map(formatArg).join(" "));
684
+ pushConsole("warn", "[warn] ", args);
246
685
  },
247
686
  error: (...args) => {
248
- logs.push("[error] " + args.map(formatArg).join(" "));
687
+ pushConsole("error", "[error] ", args);
249
688
  },
250
689
  info: (...args) => {
251
- logs.push("[info] " + args.map(formatArg).join(" "));
690
+ pushConsole("info", "[info] ", args);
691
+ }
692
+ };
693
+ // The literal check above answers a hostname with "not an IP"; this one
694
+ // resolves it, so `metadata.example.com` → 169.254.169.254 is refused
695
+ // before a socket opens, on the first request and on every redirect hop.
696
+ // Node only: off Node the default resolver has no `dns` and answers
697
+ // nothing, and the browser's own network layer is the boundary there. One
698
+ // lookup per hostname per run — the guard is a layer, not the boundary (the
699
+ // socket resolves again), so re-resolving every call buys no rebinding
700
+ // protection and would cost a round trip per parallel fetch.
701
+ const onNodeHost = isString(globalThis.process?.versions?.node);
702
+ const resolvedHosts = new Map();
703
+ const assertHostResolvesAllowed = async (target) => {
704
+ if (!onNodeHost || resolvedLimits.allowPrivateNetwork)
705
+ return;
706
+ const host = new URL(target).hostname;
707
+ let pending = resolvedHosts.get(host);
708
+ if (pending === undefined) {
709
+ pending =
710
+ resolveHost === undefined
711
+ ? assertResolvedHostAllowed(target, "fetch")
712
+ : assertResolvedHostAllowed(target, "fetch", resolveHost);
713
+ resolvedHosts.set(host, pending);
252
714
  }
715
+ await pending;
253
716
  };
254
717
  const sandboxedFetch = async (url, options) => {
255
718
  fetchCount++;
256
- if (fetchCount > MAX_FETCH_CALLS) {
257
- throw new Error(`Fetch limit exceeded (max ${MAX_FETCH_CALLS} requests per execution)`);
719
+ if (fetchCount > resolvedLimits.maxFetchCalls) {
720
+ throw new Error(`Fetch limit exceeded (max ${resolvedLimits.maxFetchCalls} requests per execution)`);
258
721
  }
259
- if (typeof url !== "string" || !url) {
722
+ if (!isNonEmptyString(url)) {
260
723
  throw new Error("fetch: url must be a non-empty string");
261
724
  }
725
+ // SSRF guard: untrusted guest code must not reach loopback, link-local
726
+ // (incl. cloud metadata 169.254.169.254), or private ranges, nor non-http
727
+ // schemes. This is the literal check; the resolved-address check follows.
728
+ // DNS rebinding between the check and the socket is out of scope.
729
+ // The host can waive the address check for a node that replaces a trusted
730
+ // `lib.http` node; the scheme check is never waived.
731
+ assertFetchUrlAllowed(url, resolvedLimits.allowPrivateNetwork);
732
+ await assertHostResolvesAllowed(url);
262
733
  const controller = new AbortController();
263
- const timer = setTimeout(() => controller.abort(), 15_000);
734
+ const timer = setTimeout(() => controller.abort(), resolvedLimits.fetchTimeoutMs);
735
+ // Cancelling the run kills an in-flight request rather than waiting out
736
+ // the per-request timeout.
737
+ const onExternalAbort = () => controller.abort();
738
+ if (signal?.aborted)
739
+ controller.abort();
740
+ else
741
+ signal?.addEventListener("abort", onExternalAbort, { once: true });
264
742
  try {
265
743
  const fetchOptions = {
266
744
  method: options?.method ?? "GET",
267
745
  signal: controller.signal
268
746
  };
269
- if (options?.headers && typeof options.headers === "object") {
270
- fetchOptions.headers = options.headers;
747
+ const requestHeaders = {};
748
+ // Host default first so a guest-set User-Agent still wins.
749
+ if (resolvedLimits.userAgent) {
750
+ requestHeaders["User-Agent"] = resolvedLimits.userAgent;
751
+ }
752
+ if (isObjectLike(options?.headers)) {
753
+ Object.assign(requestHeaders, options.headers);
754
+ }
755
+ if (Object.keys(requestHeaders).length > 0) {
756
+ fetchOptions.headers = requestHeaders;
271
757
  }
272
758
  if (options?.body !== undefined) {
273
- fetchOptions.body =
274
- typeof options.body === "string"
275
- ? options.body
276
- : JSON.stringify(options.body);
759
+ const body = options.body;
760
+ if (isString(body)) {
761
+ fetchOptions.body = body;
762
+ }
763
+ else if (isTypedArray(body)) {
764
+ // Binary request body. A guest Uint8Array reaches the host as a
765
+ // native one via the typed-array serializers, but normalize anyway
766
+ // so a numeric-keyed object is sent as raw bytes, not as JSON.
767
+ // SAFETY: `BodyInit`'s view member is pinned to a plain
768
+ // ArrayBuffer; these bytes are copied out of the guest heap by
769
+ // `toNativeUint8Array`, never off a SharedArrayBuffer.
770
+ fetchOptions.body = toNativeUint8Array(body);
771
+ }
772
+ else {
773
+ fetchOptions.body = JSON.stringify(body);
774
+ }
775
+ }
776
+ // Follow redirects manually on Node so the SSRF guard runs on every hop's
777
+ // resolved Location, not just the initial URL — otherwise an allowed
778
+ // public URL that 302s to http://169.254.169.254/ or an internal host
779
+ // bypasses the guard entirely. In a browser redirect:"manual" yields an
780
+ // opaque response whose Location is unreadable, and cross-origin bodies
781
+ // are CORS-blocked anyway, so the browser keeps the single redirect:
782
+ // "follow" call with only the already-run initial-URL check.
783
+ const onNode = isString(globalThis.process?.versions?.node);
784
+ let response;
785
+ if (!onNode) {
786
+ response = await fetch(url, { ...fetchOptions, redirect: "follow" });
787
+ }
788
+ else {
789
+ const dropContentHeaders = (h) => {
790
+ const out = {};
791
+ for (const [k, v] of Object.entries(h)) {
792
+ const lk = k.toLowerCase();
793
+ if (lk === "content-length" || lk === "content-type")
794
+ continue;
795
+ out[k] = v;
796
+ }
797
+ return out;
798
+ };
799
+ // Credential headers must not cross to a different origin — this
800
+ // mirrors Node's native redirect:"follow", which strips them per the
801
+ // fetch spec. Guest code sets headers from getSecret(...), so a
802
+ // redirect to an attacker origin would otherwise exfiltrate them.
803
+ const dropSensitiveHeaders = (h) => {
804
+ const out = {};
805
+ for (const [k, v] of Object.entries(h)) {
806
+ const lk = k.toLowerCase();
807
+ if (lk === "authorization" ||
808
+ lk === "cookie" ||
809
+ lk === "proxy-authorization") {
810
+ continue;
811
+ }
812
+ out[k] = v;
813
+ }
814
+ return out;
815
+ };
816
+ let currentUrl = url;
817
+ let method = fetchOptions.method ?? "GET";
818
+ let body = fetchOptions.body;
819
+ let headers = { ...requestHeaders };
820
+ let hops = 0;
821
+ for (;;) {
822
+ response = await fetch(currentUrl, {
823
+ ...fetchOptions,
824
+ method,
825
+ body,
826
+ headers: Object.keys(headers).length ? headers : undefined,
827
+ redirect: "manual"
828
+ });
829
+ const status = response.status;
830
+ if (status < 300 || status >= 400)
831
+ break;
832
+ const location = response.headers.get("location");
833
+ if (!location)
834
+ break; // 3xx without Location — treat as final.
835
+ if (hops++ >= MAX_FETCH_REDIRECTS) {
836
+ throw new Error("fetch: too many redirects");
837
+ }
838
+ const nextUrl = new URL(location, currentUrl).toString();
839
+ // Re-run the guard on the resolved target BEFORE the next request.
840
+ assertFetchUrlAllowed(nextUrl, resolvedLimits.allowPrivateNetwork);
841
+ await assertHostResolvesAllowed(nextUrl);
842
+ // Strip credential headers on a cross-origin hop (origin includes
843
+ // scheme, host and port); keep them on same-origin redirects.
844
+ if (new URL(nextUrl).origin !== new URL(currentUrl).origin) {
845
+ headers = dropSensitiveHeaders(headers);
846
+ }
847
+ // Method/body rewrite per the HTTP spec + browser behavior:
848
+ // 303 always → GET; 301/302 on a non-GET/HEAD → GET (what browsers
849
+ // do); 307/308 preserve method and body.
850
+ if (status === 303 ||
851
+ ((status === 301 || status === 302) &&
852
+ method !== "GET" &&
853
+ method !== "HEAD")) {
854
+ method = "GET";
855
+ body = undefined;
856
+ headers = dropContentHeaders(headers);
857
+ }
858
+ // Free the redirect response's socket before the next hop.
859
+ await response.body?.cancel().catch(() => { });
860
+ currentUrl = nextUrl;
861
+ }
277
862
  }
278
- const response = await fetch(url, fetchOptions);
279
- const rawBytes = new Uint8Array(await response.arrayBuffer());
863
+ // Read the body under a hard byte cap so a large/fast response can't OOM
864
+ // the shared host heap (the guest's 64MB WASM limit does not apply to
865
+ // these host-side bytes). Aborts the transfer once the cap is exceeded.
866
+ const rawBytes = await readBodyCapped(response, controller, resolvedLimits.maxResponseBodyBytes);
280
867
  const ok = response.ok;
281
868
  const status = response.status;
282
869
  const statusText = response.statusText;
@@ -286,8 +873,9 @@ export function buildSandbox(context) {
286
873
  if (cachedText === null) {
287
874
  const decoded = new TextDecoder().decode(rawBytes);
288
875
  cachedText =
289
- decoded.length > MAX_RESPONSE_BODY_SIZE
290
- ? decoded.slice(0, MAX_RESPONSE_BODY_SIZE) + "...[truncated]"
876
+ decoded.length > resolvedLimits.maxResponseBodyBytes
877
+ ? decoded.slice(0, resolvedLimits.maxResponseBodyBytes) +
878
+ "...[truncated]"
291
879
  : decoded;
292
880
  }
293
881
  return cachedText;
@@ -299,6 +887,11 @@ export function buildSandbox(context) {
299
887
  catch {
300
888
  parsedJson = undefined;
301
889
  }
890
+ // Plain data only — no methods. A function in a bridge result cannot
891
+ // cross the worker boundary (`postMessage` refuses it), so the guest
892
+ // prelude's fetch wrapper builds `text()`/`bytes()`/`arrayBuffer()` over
893
+ // these fields instead. The body is already fully buffered and capped
894
+ // here, so shipping it eagerly costs no extra read.
302
895
  return {
303
896
  ok,
304
897
  status,
@@ -306,57 +899,342 @@ export function buildSandbox(context) {
306
899
  headers,
307
900
  body: getText(),
308
901
  json: parsedJson,
309
- text: async () => getText(),
310
- arrayBuffer: async () => rawBytes.buffer.slice(rawBytes.byteOffset, rawBytes.byteOffset + rawBytes.byteLength),
311
- bytes: async () => rawBytes
902
+ bodyBytes: toGuestBytes(rawBytes)
312
903
  };
313
904
  }
314
905
  finally {
315
906
  clearTimeout(timer);
907
+ signal?.removeEventListener("abort", onExternalAbort);
316
908
  }
317
909
  };
318
- const uuid = () => crypto.randomUUID();
910
+ // WebCrypto exists in both Node >= 20 and browsers, so no node:crypto import
911
+ // is needed and the sandbox stays browser-safe. `getRandomValues` is the one
912
+ // synchronous member: it clamps instead of throwing, since a host throw does
913
+ // not go through the never-reject convention.
914
+ const sandboxCrypto = {
915
+ randomUUID: () => globalThis.crypto.randomUUID(),
916
+ getRandomValues: (length) => {
917
+ const requested = Number(length);
918
+ const size = Number.isFinite(requested)
919
+ ? Math.min(Math.max(Math.floor(requested), 0), MAX_RANDOM_BYTES)
920
+ : 0;
921
+ const bytes = new Uint8Array(size);
922
+ if (size > 0)
923
+ globalThis.crypto.getRandomValues(bytes);
924
+ return toGuestBytes(bytes);
925
+ },
926
+ digest: async (algorithm, data) => {
927
+ const algo = normalizeDigestAlgorithm(algorithm);
928
+ const bytes = coerceBytesInput(data, "data");
929
+ const digest = await webCryptoSubtle().digest(algo, bytes);
930
+ return toGuestBytes(new Uint8Array(digest));
931
+ },
932
+ hmac: async (algorithm, key, data) => {
933
+ const algo = normalizeDigestAlgorithm(algorithm);
934
+ const keyBytes = coerceBytesInput(key, "key");
935
+ const dataBytes = coerceBytesInput(data, "data");
936
+ const subtle = webCryptoSubtle();
937
+ const cryptoKey = await subtle.importKey("raw", keyBytes, { name: "HMAC", hash: algo }, false, ["sign"]);
938
+ const signature = await subtle.sign("HMAC", cryptoKey, dataBytes);
939
+ return toGuestBytes(new Uint8Array(signature));
940
+ }
941
+ };
942
+ /**
943
+ * The one place a secret leaves the host.
944
+ *
945
+ * The scope check sits here rather than in the guest prelude because a
946
+ * prelude is guest code: it can be shadowed, and a check the guest could
947
+ * remove is documentation, not a boundary. `nodetool.secrets.get` and the
948
+ * bare `getSecret` global both land here, so there is no second route.
949
+ */
950
+ const secretScope = resolvedLimits.secretScope;
951
+ const assertSecretInScope = (name) => {
952
+ if (secretScope === null)
953
+ return;
954
+ if (secretScope.includes(name))
955
+ return;
956
+ throw new Error(secretScope.length === 0
957
+ ? `getSecret("${name}"): this node declares no secrets, so it can read none`
958
+ : `getSecret("${name}"): this node may read only ${secretScope
959
+ .map((allowed) => `"${allowed}"`)
960
+ .join(", ")}`);
961
+ };
319
962
  const getSecret = context
320
963
  ? async (name) => {
964
+ assertSecretInScope(name);
321
965
  return (await context.getSecret(name)) ?? undefined;
322
966
  }
323
- : async (_name) => {
967
+ : async (name) => {
968
+ assertSecretInScope(name);
324
969
  return undefined;
325
970
  };
326
- const workspace = context
327
- ? {
328
- read: async (path) => {
329
- const fullPath = context.resolveWorkspacePath(path);
330
- const { readFile } = await import("node:fs/promises");
331
- return readFile(fullPath, "utf-8");
332
- },
333
- write: async (path, content) => {
334
- const fullPath = context.resolveWorkspacePath(path);
335
- const { writeFile, mkdir } = await import("node:fs/promises");
336
- const { dirname } = await import("node:path");
337
- await mkdir(dirname(fullPath), { recursive: true });
338
- await writeFile(fullPath, content, "utf-8");
339
- },
340
- list: async (path) => {
341
- const fullPath = context.resolveWorkspacePath(path);
342
- const { readdir } = await import("node:fs/promises");
343
- return readdir(fullPath);
344
- }
345
- }
346
- : {
347
- read: async (_path) => {
348
- throw new Error("workspace.read is not available without a context");
349
- },
350
- write: async (_path, _content) => {
351
- throw new Error("workspace.write is not available without a context");
352
- },
353
- list: async (_path) => {
354
- throw new Error("workspace.list is not available without a context");
971
+ /** What `workspace.stat` answers for a path that is not there. */
972
+ const MISSING_STAT = {
973
+ exists: false,
974
+ size: 0,
975
+ isDirectory: false,
976
+ isFile: false,
977
+ isSymlink: false,
978
+ modifiedMs: 0,
979
+ createdMs: 0,
980
+ accessedMs: 0
981
+ };
982
+ /**
983
+ * Resolve a guest path under the configured filesystem scope.
984
+ *
985
+ * `"workspace"` (the default) is the pre-existing behavior: resolve against
986
+ * the workspace root, then verify the symlink-resolved location is still
987
+ * inside it. `"host"` skips containment and expands `~`, matching what the
988
+ * `lib.os` nodes have always done. Host mode is reachable only when the host
989
+ * passes `filesystemAccess: "host"` — guest code cannot ask for it.
990
+ */
991
+ const resolveGuestPath = async (ctx, path, isWrite) => {
992
+ const nodePath = await loadNodePath();
993
+ if (resolvedLimits.filesystemAccess === "host") {
994
+ const os = await importNodeBuiltin("node:os");
995
+ if (!os) {
996
+ throw new Error("host filesystem access requires a Node.js runtime");
355
997
  }
356
- };
998
+ const expanded = path === "~"
999
+ ? os.homedir()
1000
+ : path.startsWith("~/")
1001
+ ? nodePath.join(os.homedir(), path.slice(2))
1002
+ : path;
1003
+ return nodePath.resolve(expanded);
1004
+ }
1005
+ const fullPath = ctx.resolveWorkspacePath(path);
1006
+ const fs = await loadFsPromises();
1007
+ await assertWorkspaceContained(ctx, fs, nodePath, fullPath, isWrite);
1008
+ return fullPath;
1009
+ };
1010
+ /**
1011
+ * The guest's `workspace.*` API.
1012
+ *
1013
+ * Three shapes, picked once: no context at all (every call explains itself),
1014
+ * `filesystemAccess: "host"` (the `lib.os` escape hatch — real paths, no
1015
+ * containment, host opt-in only), and the normal case, which goes through
1016
+ * `context.workspace` and therefore works the same whether the run's
1017
+ * workspace is a folder or a prefix in object storage.
1018
+ */
1019
+ const hostFsWorkspace = (ctx) => ({
1020
+ read: async (path) => {
1021
+ const fs = await loadFsPromises();
1022
+ return fs.readFile(await resolveGuestPath(ctx, path, false), "utf-8");
1023
+ },
1024
+ write: async (path, content) => {
1025
+ const fs = await loadFsPromises();
1026
+ const nodePath = await loadNodePath();
1027
+ const fullPath = await resolveGuestPath(ctx, path, true);
1028
+ await fs.mkdir(nodePath.dirname(fullPath), { recursive: true });
1029
+ await fs.writeFile(fullPath, content, "utf-8");
1030
+ },
1031
+ list: async (path) => {
1032
+ const fs = await loadFsPromises();
1033
+ return fs.readdir(await resolveGuestPath(ctx, path, false));
1034
+ },
1035
+ readBytes: async (path) => {
1036
+ const fs = await loadFsPromises();
1037
+ const fullPath = await resolveGuestPath(ctx, path, false);
1038
+ return toGuestBytes(new Uint8Array(await fs.readFile(fullPath)));
1039
+ },
1040
+ writeBytes: async (path, data) => {
1041
+ const bytes = data instanceof Uint8Array ? data : toNativeUint8Array(data);
1042
+ const fs = await loadFsPromises();
1043
+ const nodePath = await loadNodePath();
1044
+ const fullPath = await resolveGuestPath(ctx, path, true);
1045
+ await fs.mkdir(nodePath.dirname(fullPath), { recursive: true });
1046
+ await fs.writeFile(fullPath, bytes);
1047
+ },
1048
+ stat: async (path) => {
1049
+ const fs = await loadFsPromises();
1050
+ const fullPath = await resolveGuestPath(ctx, path, true);
1051
+ let info;
1052
+ try {
1053
+ info = await fs.lstat(fullPath);
1054
+ }
1055
+ catch {
1056
+ return MISSING_STAT;
1057
+ }
1058
+ return {
1059
+ exists: true,
1060
+ size: info.size,
1061
+ isDirectory: info.isDirectory(),
1062
+ isFile: info.isFile(),
1063
+ isSymlink: info.isSymbolicLink(),
1064
+ modifiedMs: info.mtimeMs,
1065
+ createdMs: info.birthtimeMs,
1066
+ accessedMs: info.atimeMs
1067
+ };
1068
+ },
1069
+ root: async () => ctx.resolveWorkspacePath("."),
1070
+ copy: async (src, dest) => {
1071
+ const fs = await loadFsPromises();
1072
+ const nodePath = await loadNodePath();
1073
+ const fullSrc = await resolveGuestPath(ctx, src, false);
1074
+ const fullDest = await resolveGuestPath(ctx, dest, true);
1075
+ await fs.mkdir(nodePath.dirname(fullDest), { recursive: true });
1076
+ await fs.copyFile(fullSrc, fullDest);
1077
+ },
1078
+ move: async (src, dest) => {
1079
+ const fs = await loadFsPromises();
1080
+ const nodePath = await loadNodePath();
1081
+ const fullSrc = await resolveGuestPath(ctx, src, true);
1082
+ const fullDest = await resolveGuestPath(ctx, dest, true);
1083
+ await fs.mkdir(nodePath.dirname(fullDest), { recursive: true });
1084
+ await fs.rename(fullSrc, fullDest);
1085
+ },
1086
+ mkdir: async (path) => {
1087
+ const fs = await loadFsPromises();
1088
+ await fs.mkdir(await resolveGuestPath(ctx, path, true), {
1089
+ recursive: true
1090
+ });
1091
+ },
1092
+ remove: async (path) => {
1093
+ const fs = await loadFsPromises();
1094
+ const fullPath = await resolveGuestPath(ctx, path, true);
1095
+ const info = await fs.lstat(fullPath);
1096
+ if (info.isDirectory()) {
1097
+ // rmdir refuses a non-empty directory, which is the point.
1098
+ await fs.rmdir(fullPath);
1099
+ }
1100
+ else {
1101
+ await fs.rm(fullPath, { recursive: false });
1102
+ }
1103
+ }
1104
+ });
1105
+ const backedWorkspace = (ws) => ({
1106
+ read: async (path) => {
1107
+ const text = await ws.readText(path);
1108
+ if (text === null)
1109
+ throw new Error(`ENOENT: no such file: ${path}`);
1110
+ return text;
1111
+ },
1112
+ write: async (path, content) => {
1113
+ await ws.write(path, content);
1114
+ },
1115
+ // Names only, like readdir — the guest joins them onto the path it asked
1116
+ // about, which is how the pre-existing scripts use this.
1117
+ list: async (path) => (await ws.list(path)).map((entry) => entry.name),
1118
+ readBytes: async (path) => {
1119
+ const bytes = await ws.read(path);
1120
+ if (bytes === null)
1121
+ throw new Error(`ENOENT: no such file: ${path}`);
1122
+ return toGuestBytes(bytes);
1123
+ },
1124
+ writeBytes: async (path, data) => {
1125
+ const bytes = data instanceof Uint8Array ? data : toNativeUint8Array(data);
1126
+ await ws.write(path, bytes);
1127
+ },
1128
+ // A missing path is an answer, not a failure: guest code asking
1129
+ // "does this exist?" should not have to wrap the call in try/catch.
1130
+ stat: async (path) => {
1131
+ let info;
1132
+ try {
1133
+ info = await ws.stat(path);
1134
+ }
1135
+ catch {
1136
+ return MISSING_STAT;
1137
+ }
1138
+ if (!info)
1139
+ return MISSING_STAT;
1140
+ return {
1141
+ exists: true,
1142
+ size: info.size,
1143
+ isDirectory: info.isDirectory,
1144
+ isFile: !info.isDirectory,
1145
+ // Nothing reachable through a workspace is a symlink: an object store
1146
+ // cannot hold one, and the local backend refuses to follow one out of
1147
+ // the root.
1148
+ isSymlink: false,
1149
+ modifiedMs: info.modifiedAt,
1150
+ createdMs: info.modifiedAt,
1151
+ accessedMs: info.modifiedAt
1152
+ };
1153
+ },
1154
+ /**
1155
+ * The base for relative paths. A real directory when the workspace has
1156
+ * one; otherwise `/workspace`, which every workspace path accepts as its
1157
+ * own root, so a script that joins onto it keeps working.
1158
+ */
1159
+ root: async () => ws.localDir ?? "/workspace",
1160
+ copy: async (src, dest) => {
1161
+ await ws.copy(src, dest);
1162
+ },
1163
+ move: async (src, dest) => {
1164
+ await ws.move(src, dest);
1165
+ },
1166
+ mkdir: async (path) => {
1167
+ await ws.mkdir(path);
1168
+ },
1169
+ remove: async (path) => {
1170
+ // One file or one empty directory — guest code cannot delete a whole
1171
+ // subtree in a single call, in any filesystem mode.
1172
+ const info = await ws.stat(path);
1173
+ if (info?.isDirectory) {
1174
+ const children = await ws.list(path);
1175
+ if (children.length > 0) {
1176
+ throw new Error(`ENOTEMPTY: directory not empty: ${path}`);
1177
+ }
1178
+ await ws.deleteAll(path);
1179
+ return;
1180
+ }
1181
+ if (!(await ws.delete(path))) {
1182
+ throw new Error(`ENOENT: no such file: ${path}`);
1183
+ }
1184
+ }
1185
+ });
1186
+ const unavailable = (api) => async () => {
1187
+ throw new Error(`workspace.${api} is not available without a context`);
1188
+ };
1189
+ const workspace = !context
1190
+ ? {
1191
+ read: unavailable("read"),
1192
+ write: unavailable("write"),
1193
+ list: unavailable("list"),
1194
+ readBytes: unavailable("readBytes"),
1195
+ writeBytes: unavailable("writeBytes"),
1196
+ stat: unavailable("stat"),
1197
+ root: unavailable("root"),
1198
+ copy: unavailable("copy"),
1199
+ move: unavailable("move"),
1200
+ mkdir: unavailable("mkdir"),
1201
+ remove: unavailable("remove")
1202
+ }
1203
+ : resolvedLimits.filesystemAccess === "host"
1204
+ ? hostFsWorkspace(context)
1205
+ : context.workspace
1206
+ ? backedWorkspace(context.workspace)
1207
+ : {
1208
+ read: unavailable("read"),
1209
+ write: unavailable("write"),
1210
+ list: unavailable("list"),
1211
+ readBytes: unavailable("readBytes"),
1212
+ writeBytes: unavailable("writeBytes"),
1213
+ stat: unavailable("stat"),
1214
+ root: unavailable("root"),
1215
+ copy: unavailable("copy"),
1216
+ move: unavailable("move"),
1217
+ mkdir: unavailable("mkdir"),
1218
+ remove: unavailable("remove")
1219
+ };
357
1220
  const sleep = (ms) => {
358
1221
  const capped = Math.min(ms, 5000);
359
- return new Promise((resolve) => setTimeout(resolve, capped));
1222
+ // Resolve immediately on cancellation: a sleeping script is the common
1223
+ // case for "still running after Stop", and waiting out the nap before the
1224
+ // next bridge call can reject it wastes up to 5s per sleep.
1225
+ return new Promise((resolve) => {
1226
+ if (signal?.aborted)
1227
+ return resolve();
1228
+ const timer = setTimeout(() => {
1229
+ signal?.removeEventListener("abort", onAbort);
1230
+ resolve();
1231
+ }, capped);
1232
+ function onAbort() {
1233
+ clearTimeout(timer);
1234
+ resolve();
1235
+ }
1236
+ signal?.addEventListener("abort", onAbort, { once: true });
1237
+ });
360
1238
  };
361
1239
  const assetToSandbox = context
362
1240
  ? async (assetId, path) => {
@@ -372,6 +1250,512 @@ export function buildSandbox(context) {
372
1250
  : async (_path) => {
373
1251
  throw new Error("sandboxToAsset is not available without a context");
374
1252
  };
1253
+ // Fire-and-forget progress reporting. Synchronous like console.log: it never
1254
+ // throws, so it needs no never-reject wrapper. A guest that spams it cannot
1255
+ // flood the host — reports closer together than PROGRESS_MIN_INTERVAL_MS are
1256
+ // dropped, and the run has a lifetime cap.
1257
+ let progressCalls = 0;
1258
+ let lastProgressAt = 0;
1259
+ const progress = (percent, message) => {
1260
+ if (!onProgress || signal?.aborted)
1261
+ return;
1262
+ if (progressCalls >= MAX_PROGRESS_CALLS)
1263
+ return;
1264
+ const now = Date.now();
1265
+ if (progressCalls > 0 && now - lastProgressAt < PROGRESS_MIN_INTERVAL_MS) {
1266
+ return;
1267
+ }
1268
+ const raw = Number(percent);
1269
+ const clamped = Number.isFinite(raw) ? Math.min(Math.max(raw, 0), 100) : 0;
1270
+ const text = message === undefined || message === null
1271
+ ? undefined
1272
+ : String(message).slice(0, MAX_PROGRESS_MESSAGE_CHARS);
1273
+ progressCalls++;
1274
+ lastProgressAt = now;
1275
+ try {
1276
+ onProgress(clamped, text);
1277
+ }
1278
+ catch {
1279
+ // A failing host sink must not take the guest run down with it.
1280
+ }
1281
+ };
1282
+ // Output delivery. The opposite of `progress` in every respect: awaitable, so
1283
+ // the guest gets backpressure from a slow consumer, and never rate-limited or
1284
+ // dropped — an output value the host silently discards is data loss, not a
1285
+ // missed progress tick. Both throw into the guest rather than failing quietly.
1286
+ let emitCalls = 0;
1287
+ const emitted = [];
1288
+ const outputs = new Map();
1289
+ const handleName = (fn, name) => {
1290
+ if (!isString(name)) {
1291
+ throw new TypeError(`${fn}: name must be a string`);
1292
+ }
1293
+ return name;
1294
+ };
1295
+ const emit = async (name, value) => {
1296
+ const handle = handleName("emit", name);
1297
+ if (emitCalls >= MAX_EMIT_CALLS) {
1298
+ throw new Error(`emit: this run may emit at most ${MAX_EMIT_CALLS} values (MAX_EMIT_CALLS)`);
1299
+ }
1300
+ emitCalls++;
1301
+ const marshaled = serializeResult(value, resolvedLimits.maxOutputSize);
1302
+ if (onEmit) {
1303
+ // Awaited, so the guest's promise resolves only once the host has taken
1304
+ // the value — and a sink that throws unwinds the guest's `emit` call.
1305
+ await onEmit(handle, marshaled);
1306
+ return;
1307
+ }
1308
+ emitted.push({ name: handle, value: marshaled });
1309
+ };
1310
+ const output = async (name, value) => {
1311
+ const handle = handleName("output", name);
1312
+ if (outputs.has(handle)) {
1313
+ throw new Error(`output "${handle}" was already set`);
1314
+ }
1315
+ outputs.set(handle, serializeResult(value, resolvedLimits.maxOutputSize));
1316
+ };
1317
+ // Input delivery, the mirror of `emit`: the guest pulls one value at a time
1318
+ // and the host answers from the inbox it owns. Backpressure is free — an item
1319
+ // nobody asked for stays upstream.
1320
+ const takeInput = async (name) => {
1321
+ if (!streams?.onTakeInput) {
1322
+ throw new Error(NO_INPUT_STREAM_MESSAGE);
1323
+ }
1324
+ if (name !== null && !isString(name)) {
1325
+ throw new TypeError("stream: name must be a string");
1326
+ }
1327
+ // Waiting on upstream is not the guest executing, so it must not spend the
1328
+ // guest's timeout budget. The clock stops until the value (or EOS) lands.
1329
+ const resume = streams.clock?.suspend();
1330
+ try {
1331
+ const take = await streams.onTakeInput(name);
1332
+ if (take.done)
1333
+ return { done: true };
1334
+ return {
1335
+ done: false,
1336
+ handle: take.handle,
1337
+ value: toGuestBytesDeep(take.value)
1338
+ };
1339
+ }
1340
+ finally {
1341
+ resume?.();
1342
+ }
1343
+ };
1344
+ // Synchronous and never throwing, which is what lets the guest read it as a
1345
+ // plain boolean: an awaitable answer would make `if (stream.open(h))` true on
1346
+ // a pending promise. `null` is the one non-answer — this run has no input
1347
+ // stream at all — and the prelude turns it into the thrown error.
1348
+ const streamOpen = (name) => {
1349
+ if (!streams?.onTakeInput)
1350
+ return null;
1351
+ if (!isString(name) || !streams.onStreamOpen)
1352
+ return false;
1353
+ try {
1354
+ return streams.onStreamOpen(name) === true;
1355
+ }
1356
+ catch {
1357
+ // A host probe that throws answers "closed" rather than taking the run
1358
+ // down: the take itself is where a broken inbox must surface.
1359
+ return false;
1360
+ }
1361
+ };
1362
+ // QuickJS ships no Intl, so locale-aware formatting has to come from the
1363
+ // host. Async + never-reject like the other bridges: a bad locale or option
1364
+ // surfaces in the guest as a thrown Error with Intl's own message.
1365
+ const format = {
1366
+ number: async (value, options) => {
1367
+ const num = Number(value);
1368
+ if (!Number.isFinite(num)) {
1369
+ throw new Error("format.number: value must be a finite number");
1370
+ }
1371
+ const opts = options ?? {};
1372
+ return new Intl.NumberFormat(opts.locale ?? DEFAULT_FORMAT_LOCALE, {
1373
+ style: opts.style,
1374
+ currency: opts.currency,
1375
+ minimumFractionDigits: opts.minimumFractionDigits,
1376
+ maximumFractionDigits: opts.maximumFractionDigits,
1377
+ useGrouping: opts.useGrouping
1378
+ }).format(num);
1379
+ },
1380
+ date: async (epochMs, options) => {
1381
+ const ms = Number(epochMs);
1382
+ if (!Number.isFinite(ms)) {
1383
+ throw new Error("format.date: epochMs must be a finite number of milliseconds");
1384
+ }
1385
+ const opts = options ?? {};
1386
+ const dateStyle = opts.dateStyle;
1387
+ const timeStyle = opts.timeStyle;
1388
+ return new Intl.DateTimeFormat(opts.locale ?? DEFAULT_FORMAT_LOCALE, {
1389
+ // Intl falls back to a date-only default when neither style is given.
1390
+ dateStyle: dateStyle ?? (timeStyle ? undefined : "medium"),
1391
+ timeStyle,
1392
+ timeZone: opts.timeZone
1393
+ }).format(new Date(ms));
1394
+ },
1395
+ relativeTime: async (value, unit, options) => {
1396
+ const num = Number(value);
1397
+ if (!Number.isFinite(num)) {
1398
+ throw new Error("format.relativeTime: value must be a finite number");
1399
+ }
1400
+ const opts = options ?? {};
1401
+ return new Intl.RelativeTimeFormat(opts.locale ?? DEFAULT_FORMAT_LOCALE).format(num, unit);
1402
+ },
1403
+ list: async (items, options) => {
1404
+ if (!Array.isArray(items)) {
1405
+ throw new Error("format.list: items must be an array of strings");
1406
+ }
1407
+ const opts = options ?? {};
1408
+ return new Intl.ListFormat(opts.locale ?? DEFAULT_FORMAT_LOCALE, { type: opts.type }).format(items.map((i) => String(i)));
1409
+ }
1410
+ };
1411
+ // Bytes media transforms produced and the guest only carries around. Lives for the
1412
+ // run, then goes; nothing here is durable until something promotes it.
1413
+ const mediaStore = createSandboxMediaStore(resolvedLimits.runMediaBytes);
1414
+ let runAvMediaPromise;
1415
+ const loadRunAvMedia = () => {
1416
+ runAvMediaPromise ??= loadSandboxAvMedia().then((media) => ({
1417
+ audioOps: media.createAudioBridge(signal, resolvedLimits.runMediaBytes),
1418
+ videoOps: media.createVideoBridge(signal, resolvedLimits.runMediaBytes)
1419
+ }));
1420
+ return runAvMediaPromise;
1421
+ };
1422
+ // Media bridges. The engine (`sandbox-media.ts`) is imported on first use
1423
+ // like every other library-backed bridge, and picks its canvas backend from
1424
+ // the runtime — `@napi-rs/canvas` on Node, `OffscreenCanvas` in the browser
1425
+ // runner. Bytes come back tagged for the guest prelude to revive, so the
1426
+ // guest-visible API is `Uint8Array` in and `Uint8Array` out.
1427
+ const withGuestBytes = (fn) => {
1428
+ return async (...args) => toGuestBytesDeep(await fn(...args));
1429
+ };
1430
+ const mediaMember = (pick) => withGuestBytes(async (...args) => pick(await loadSandboxMedia())(...args));
1431
+ // `image.*` trades in handles, not bytes. On the way in, every handle and
1432
+ // every media ref buried anywhere in the arguments is replaced by the bytes
1433
+ // it names — resolved host-side, so an `asset://` a generator produced goes
1434
+ // straight into the next operation without being pulled through the guest.
1435
+ // On the way out, encoded bytes become a handle instead of a base64 payload.
1436
+ // A chain (resize → adjust → composite) therefore moves nothing across the
1437
+ // boundary but small objects.
1438
+ //
1439
+ // `info` and `decode` are the deliberate exceptions: they exist to tell the
1440
+ // guest what is *in* an image, so their results stay plain data. `decode`
1441
+ // still hands over real pixels, which is the one call that has to.
1442
+ const loadMediaRef = async (where, value, maxBytes = resolvedLimits.runMediaBytes) => {
1443
+ const ref = remapMediaRef(value);
1444
+ if (context) {
1445
+ return resolveRefBytes(where, ref, context, (path) => resolveGuestPath(context, path, false), maxBytes);
1446
+ }
1447
+ if (resolveMediaRef) {
1448
+ const bytes = await resolveMediaRef(where, ref);
1449
+ if (bytes.length > maxBytes) {
1450
+ throw new Error(`${where}: media input is ${bytes.length} bytes, over the ` +
1451
+ `${maxBytes} byte remaining run media limit`);
1452
+ }
1453
+ return bytes;
1454
+ }
1455
+ const label = ref.uri || ref.asset_id || "this media ref";
1456
+ throw new Error(`${where}: cannot resolve ${label} in this run. Pass a media ` +
1457
+ `handle or a generation result (its asset_uri).`);
1458
+ };
1459
+ const resolveMediaArgs = async (where, value,
1460
+ // `image.*` wants a ref flattened to bytes it can operate on. `media.*`
1461
+ // takes refs *as* refs — that is its whole job — so it resolves handles
1462
+ // only, or `media.bytes(assetRef)` would be handed bytes and no longer
1463
+ // have a ref to read.
1464
+ resolveRefs, depth = 0, expectedType, budget = { used: 0 }) => {
1465
+ if (depth >= SANDBOX_SERIALIZE_MAX_DEPTH)
1466
+ return value;
1467
+ const accountBytes = (bytes) => {
1468
+ if (bytes.byteLength > resolvedLimits.runMediaBytes - budget.used) {
1469
+ throw new Error(`${where}: aggregate media input exceeds the ` +
1470
+ `${resolvedLimits.runMediaBytes} byte run media limit`);
1471
+ }
1472
+ budget.used += bytes.byteLength;
1473
+ return bytes;
1474
+ };
1475
+ // Matched on the marker, not on store membership: a handle from an
1476
+ // earlier run must report *that*, rather than falling through to the ref
1477
+ // path and blaming the uri it happens to carry.
1478
+ if (isSandboxMediaHandle(value)) {
1479
+ const bytes = mediaStore.resolve(value, expectedType);
1480
+ if (!bytes)
1481
+ throw new Error(`${where}: media handle has no bytes`);
1482
+ return accountBytes(bytes);
1483
+ }
1484
+ if (value instanceof Uint8Array || ArrayBuffer.isView(value)) {
1485
+ return accountBytes(value);
1486
+ }
1487
+ if (Array.isArray(value)) {
1488
+ const resolved = [];
1489
+ for (const item of value) {
1490
+ const result = await resolveMediaArgs(where, item, resolveRefs, depth + 1, expectedType, budget);
1491
+ resolved.push(result);
1492
+ }
1493
+ return resolved;
1494
+ }
1495
+ if (resolveRefs && looksLikeMediaRef(value)) {
1496
+ if (expectedType && isObjectLike(value)) {
1497
+ const declared = value.type;
1498
+ if ((declared === "image" ||
1499
+ declared === "audio" ||
1500
+ declared === "video") &&
1501
+ declared !== expectedType) {
1502
+ throw new Error(`${where}: expected ${expectedType} media, but received ${declared}`);
1503
+ }
1504
+ }
1505
+ const remainingBytes = resolvedLimits.runMediaBytes - budget.used;
1506
+ return accountBytes(await loadMediaRef(where, value, remainingBytes));
1507
+ }
1508
+ if (isObjectLike(value)) {
1509
+ const record = value;
1510
+ const out = {};
1511
+ for (const [k, v] of Object.entries(record)) {
1512
+ out[k] = await resolveMediaArgs(where, v, resolveRefs, depth + 1, expectedType, budget);
1513
+ }
1514
+ return out;
1515
+ }
1516
+ return value;
1517
+ };
1518
+ const defaultMediaMime = (type) => type === "image"
1519
+ ? "image/png"
1520
+ : type === "audio"
1521
+ ? "audio/wav"
1522
+ : "video/mp4";
1523
+ const mediaMimeForValue = (value, expectedType) => {
1524
+ if (isSandboxMediaHandle(value)) {
1525
+ return (mediaStore.entry(value, expectedType)?.mimeType ??
1526
+ defaultMediaMime(expectedType));
1527
+ }
1528
+ const record = isRecord(value) ? value : undefined;
1529
+ const declared = record?.mimeType ?? record?.mime_type;
1530
+ const ref = remapMediaRef(value);
1531
+ if (isString(declared))
1532
+ ref.mimeType = declared;
1533
+ return mimeForRef(ref, defaultMediaMime(expectedType));
1534
+ };
1535
+ const sniffMediaMime = (type, bytes, fallback) => {
1536
+ const ascii = (start, length) => String.fromCharCode(...bytes.subarray(start, start + length));
1537
+ if (type === "image") {
1538
+ if (bytes.length >= 8 && ascii(1, 3) === "PNG")
1539
+ return "image/png";
1540
+ if (bytes.length >= 3 && bytes[0] === 0xff && bytes[1] === 0xd8)
1541
+ return "image/jpeg";
1542
+ if (bytes.length >= 6 && ascii(0, 3) === "GIF")
1543
+ return "image/gif";
1544
+ if (bytes.length >= 12 &&
1545
+ ascii(0, 4) === "RIFF" &&
1546
+ ascii(8, 4) === "WEBP")
1547
+ return "image/webp";
1548
+ return fallback;
1549
+ }
1550
+ if (type === "audio") {
1551
+ if (bytes.length >= 12 &&
1552
+ ascii(0, 4) === "RIFF" &&
1553
+ ascii(8, 4) === "WAVE")
1554
+ return "audio/wav";
1555
+ if (bytes.length >= 4 && ascii(0, 4) === "fLaC")
1556
+ return "audio/flac";
1557
+ if (bytes.length >= 4 && ascii(0, 4) === "OggS")
1558
+ return "audio/ogg";
1559
+ if ((bytes.length >= 3 && ascii(0, 3) === "ID3") ||
1560
+ (bytes.length >= 2 && bytes[0] === 0xff && (bytes[1] & 0xe0) === 0xe0))
1561
+ return "audio/mpeg";
1562
+ if (bytes.length >= 12 && ascii(4, 4) === "ftyp")
1563
+ return "audio/mp4";
1564
+ return fallback;
1565
+ }
1566
+ if (bytes.length >= 12 && ascii(0, 4) === "RIFF" && ascii(8, 4) === "AVI ")
1567
+ return "video/x-msvideo";
1568
+ if (bytes.length >= 4 && bytes[0] === 0x1a && bytes[1] === 0x45) {
1569
+ return ascii(0, Math.min(bytes.length, 64)).includes("webm")
1570
+ ? "video/webm"
1571
+ : "video/x-matroska";
1572
+ }
1573
+ if (bytes.length >= 12 && ascii(4, 4) === "ftyp") {
1574
+ return ascii(8, 4) === "qt " ? "video/quicktime" : "video/mp4";
1575
+ }
1576
+ return fallback;
1577
+ };
1578
+ /** An `image.*` op: handles/refs in, a handle out. */
1579
+ const imageMember = (name, pick) => {
1580
+ const where = `image.${name}`;
1581
+ return async (...args) => {
1582
+ const resolved = (await resolveMediaArgs(where, args, true, 0, "image"));
1583
+ const result = await pick(await loadSandboxMedia())(...resolved);
1584
+ if (result instanceof Uint8Array) {
1585
+ const media = await loadSandboxMedia();
1586
+ const info = (await media.imageOps.info(result));
1587
+ const meta = {
1588
+ mimeType: info.format ? `image/${info.format}` : "image/png"
1589
+ };
1590
+ if (info.width !== undefined)
1591
+ meta.width = info.width;
1592
+ if (info.height !== undefined)
1593
+ meta.height = info.height;
1594
+ return mediaStore.put(result, meta);
1595
+ }
1596
+ return toGuestBytesDeep(result);
1597
+ };
1598
+ };
1599
+ const image = {
1600
+ /**
1601
+ * The one door from a handle back to real bytes, and deliberately the only
1602
+ * one. Every other op keeps the payload host-side, so a body that reaches
1603
+ * for this is saying it will read the bytes itself — the cost is explicit
1604
+ * at the call site instead of hidden in every hop. It needs no
1605
+ * ProcessingContext, so a Code node that really does parse an encoded image
1606
+ * works exactly as it did.
1607
+ */
1608
+ bytes: async (value) => {
1609
+ const resolved = await resolveMediaArgs("image.bytes", value, true, 0, "image");
1610
+ const media = await loadSandboxMedia();
1611
+ return toGuestBytes(media.asImageBytes(resolved, "image.bytes"));
1612
+ },
1613
+ /**
1614
+ * Handle → durable asset. Bytes stay on the host; the guest gets a ref.
1615
+ */
1616
+ toAsset: async (value, options) => {
1617
+ const sourceMime = mediaMimeForValue(value, "image");
1618
+ const resolved = await resolveMediaArgs("image.toAsset", value, true, 0, "image");
1619
+ const media = await loadSandboxMedia();
1620
+ const bytes = media.asImageBytes(resolved, "image.toAsset");
1621
+ const mimeType = sniffMediaMime("image", bytes, sourceMime);
1622
+ const assetOptions = { mimeType, ...options };
1623
+ if (promoteMedia) {
1624
+ return promoteMedia("image", bytes, assetOptions);
1625
+ }
1626
+ if (context) {
1627
+ return mediaRefBridge.toImage(bytes, assetOptions);
1628
+ }
1629
+ throw new Error("image.toAsset: cannot save an asset in this run. Use " +
1630
+ "nodetool.media.toImage from a chat action, or media.toImage " +
1631
+ "from a Code node.");
1632
+ },
1633
+ info: imageMember("info", (m) => m.imageOps.info),
1634
+ decode: imageMember("decode", (m) => m.imageOps.decode),
1635
+ stats: imageMember("stats", (m) => m.imageOps.stats),
1636
+ blank: imageMember("blank", (m) => m.imageOps.blank),
1637
+ pad: imageMember("pad", (m) => m.imageOps.pad),
1638
+ grid: imageMember("grid", (m) => m.imageOps.grid),
1639
+ resize: imageMember("resize", (m) => m.imageOps.resize),
1640
+ crop: imageMember("crop", (m) => m.imageOps.crop),
1641
+ rotate: imageMember("rotate", (m) => m.imageOps.rotate),
1642
+ flip: imageMember("flip", (m) => m.imageOps.flip),
1643
+ adjust: imageMember("adjust", (m) => m.imageOps.adjust),
1644
+ composite: imageMember("composite", (m) => m.imageOps.composite),
1645
+ convert: imageMember("convert", (m) => m.imageOps.convert)
1646
+ };
1647
+ const requireMediaBytes = (where, value) => {
1648
+ if (value instanceof Uint8Array)
1649
+ return value;
1650
+ if (ArrayBuffer.isView(value)) {
1651
+ return new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
1652
+ }
1653
+ throw new Error(`${where}: expected media bytes, a media handle, or a media ref`);
1654
+ };
1655
+ const avMember = (namespace, name, inputTypes, outputType, pick) => {
1656
+ const where = `${namespace}.${name}`;
1657
+ return async (...args) => {
1658
+ const budget = { used: 0 };
1659
+ const resolved = [];
1660
+ for (let index = 0; index < args.length; index += 1) {
1661
+ resolved.push(await resolveMediaArgs(where, args[index], true, 0, inputTypes[index], budget));
1662
+ }
1663
+ const result = await pick(await loadRunAvMedia())(...resolved);
1664
+ if (outputType && result instanceof Uint8Array) {
1665
+ const sourceType = inputTypes[0] ?? outputType;
1666
+ const sourceMime = mediaMimeForValue(args[0], sourceType);
1667
+ return mediaStore.put(result, {
1668
+ type: outputType,
1669
+ mimeType: sniffMediaMime(outputType, result, outputType === sourceType
1670
+ ? sourceMime
1671
+ : defaultMediaMime(outputType))
1672
+ });
1673
+ }
1674
+ return toGuestBytesDeep(result);
1675
+ };
1676
+ };
1677
+ const avBytes = (namespace) => async (value) => {
1678
+ const where = `${namespace}.bytes`;
1679
+ const resolved = await resolveMediaArgs(where, value, true, 0, namespace);
1680
+ return toGuestBytes(requireMediaBytes(where, resolved));
1681
+ };
1682
+ const avToAsset = (type) => async (value, options) => {
1683
+ const where = `${type}.toAsset`;
1684
+ const sourceMime = mediaMimeForValue(value, type);
1685
+ const resolved = await resolveMediaArgs(where, value, true, 0, type);
1686
+ const bytes = requireMediaBytes(where, resolved);
1687
+ const mimeType = sniffMediaMime(type, bytes, sourceMime);
1688
+ const assetOptions = { mimeType, ...options };
1689
+ if (promoteMedia) {
1690
+ return promoteMedia(type, bytes, assetOptions);
1691
+ }
1692
+ if (context) {
1693
+ return type === "audio"
1694
+ ? mediaRefBridge.toAudio(bytes, assetOptions)
1695
+ : mediaRefBridge.toVideo(bytes, assetOptions);
1696
+ }
1697
+ throw new Error(`${where}: cannot save an asset in this run. Use media.to${type === "audio" ? "Audio" : "Video"} from a Code node.`);
1698
+ };
1699
+ const audio = {
1700
+ bytes: avBytes("audio"),
1701
+ toAsset: avToAsset("audio"),
1702
+ info: avMember("audio", "info", ["audio"], undefined, (m) => m.audioOps.info),
1703
+ normalize: avMember("audio", "normalize", ["audio"], "audio", (m) => m.audioOps.normalize),
1704
+ trim: avMember("audio", "trim", ["audio"], "audio", (m) => m.audioOps.trim),
1705
+ concat: avMember("audio", "concat", ["audio"], "audio", (m) => m.audioOps.concat),
1706
+ mix: avMember("audio", "mix", ["audio"], "audio", (m) => m.audioOps.mix),
1707
+ reverse: avMember("audio", "reverse", ["audio"], "audio", (m) => m.audioOps.reverse),
1708
+ fadeIn: avMember("audio", "fadeIn", ["audio"], "audio", (m) => m.audioOps.fadeIn),
1709
+ fadeOut: avMember("audio", "fadeOut", ["audio"], "audio", (m) => m.audioOps.fadeOut),
1710
+ repeat: avMember("audio", "repeat", ["audio"], "audio", (m) => m.audioOps.repeat)
1711
+ };
1712
+ const video = {
1713
+ bytes: avBytes("video"),
1714
+ toAsset: avToAsset("video"),
1715
+ info: avMember("video", "info", ["video"], undefined, (m) => m.videoOps.info),
1716
+ trim: avMember("video", "trim", ["video"], "video", (m) => m.videoOps.trim),
1717
+ resize: avMember("video", "resize", ["video"], "video", (m) => m.videoOps.resize),
1718
+ rotate: avMember("video", "rotate", ["video"], "video", (m) => m.videoOps.rotate),
1719
+ addAudio: avMember("video", "addAudio", ["video", "audio"], "video", (m) => m.videoOps.addAudio),
1720
+ extractAudio: avMember("video", "extractAudio", ["video"], "audio", (m) => m.videoOps.extractAudio),
1721
+ extractFrame: avMember("video", "extractFrame", ["video"], "image", (m) => m.videoOps.extractFrame)
1722
+ };
1723
+ const canvas = {
1724
+ render: imageMember("render", (m) => m.renderCanvas),
1725
+ measureText: mediaMember((m) => m.measureCanvasText)
1726
+ };
1727
+ // Media refs in and out. Unlike the transform namespaces, this one needs a
1728
+ // ProcessingContext — it resolves `asset://`, storage keys and package assets
1729
+ // through the host's own resolver — so without one every member throws.
1730
+ // `media.*` reads files, so it resolves paths through the same
1731
+ // `resolveGuestPath` `workspace.*` uses — one containment rule, one
1732
+ // `filesystemAccess` scope, no second scheme to keep in step.
1733
+ const mediaRefBridge = createMediaRefBridge(context, context
1734
+ ? {
1735
+ resolvePath: (path) => resolveGuestPath(context, path, false)
1736
+ }
1737
+ : {});
1738
+ // A media handle is accepted wherever `media.*` takes a ref or bytes. The
1739
+ // last step of a chain promotes the result with the matching `media.to*`
1740
+ // call. Only this promotion writes to storage; intermediates never do. The
1741
+ // wrapped members share one signature, so they are held under that type and
1742
+ // only the assembled `media` object claims the bridge's shape.
1743
+ const mediaMembers = Object.fromEntries(Object.entries(mediaRefBridge).map(([name, fn]) => [
1744
+ name,
1745
+ async (...args) => fn(...(await resolveMediaArgs(`media.${name}`, args, false)))
1746
+ ]));
1747
+ const promoteTypedHandle = (name, promote) => async (value, options) => {
1748
+ if (isSandboxMediaHandle(value)) {
1749
+ return promote(value, options);
1750
+ }
1751
+ return mediaMembers[name](value, options);
1752
+ };
1753
+ const media = {
1754
+ ...mediaMembers,
1755
+ toImage: promoteTypedHandle("toImage", image.toAsset),
1756
+ toAudio: promoteTypedHandle("toAudio", audio.toAsset),
1757
+ toVideo: promoteTypedHandle("toVideo", video.toAsset)
1758
+ };
375
1759
  const sandbox = {
376
1760
  // Core JS globals are native in QuickJS; we still reflect them in the
377
1761
  // descriptor so callers that inspect `sandbox.JSON` / `sandbox.Math`
@@ -412,33 +1796,81 @@ export function buildSandbox(context) {
412
1796
  TextDecoder: globalThis.TextDecoder,
413
1797
  URL: globalThis.URL,
414
1798
  URLSearchParams: globalThis.URLSearchParams,
415
- // Async primitives blocked — use sleep() instead.
1799
+ // Timer globals blocked — use sleep() for delays and Promise.all /
1800
+ // parallelMap for concurrency. The engine re-installs host-backed timers
1801
+ // on every evaluation, so the real deletion happens in wrapCode; these
1802
+ // entries keep the manifest's blocked list truthful.
416
1803
  setTimeout: undefined,
1804
+ clearTimeout: undefined,
417
1805
  setInterval: undefined,
1806
+ clearInterval: undefined,
1807
+ setImmediate: undefined,
1808
+ clearImmediate: undefined,
418
1809
  // Bridge functions — the only non-native surface the sandbox exposes.
419
1810
  fetch: sandboxedFetch,
420
- uuid,
1811
+ crypto: sandboxCrypto,
421
1812
  sleep,
422
1813
  getSecret,
423
1814
  workspace,
424
1815
  assetToSandbox,
425
1816
  sandboxToAsset,
426
- __maxIter: MAX_LOOP_ITERATIONS
1817
+ progress,
1818
+ emit,
1819
+ output,
1820
+ // Behind the `stream` global the prelude builds; never reachable by name,
1821
+ // which is why they are not in EXPOSED_BRIDGE_NAMES.
1822
+ [SANDBOX_INPUT_TAKE_BINDING]: takeInput,
1823
+ [SANDBOX_STREAM_OPEN_BINDING]: streamOpen,
1824
+ format,
1825
+ image,
1826
+ audio,
1827
+ video,
1828
+ canvas,
1829
+ media,
1830
+ __maxIter: MAX_LOOP_ITERATIONS,
1831
+ // The run's declared secret scope, so `nodetool.secrets.list()` can answer
1832
+ // without a host call. Reading it is not the check — `getSecret` is.
1833
+ __secretScope: secretScope === null ? null : [...secretScope]
1834
+ };
1835
+ return {
1836
+ sandbox,
1837
+ getLogs: () => logs,
1838
+ getOutputs: () => outputs.size > 0 ? Object.fromEntries(outputs) : undefined,
1839
+ getEmitted: () => (emitted.length > 0 ? [...emitted] : undefined)
427
1840
  };
428
- return { sandbox, getLogs: () => logs };
429
1841
  }
430
1842
  // ---------------------------------------------------------------------------
431
1843
  // Code execution
432
1844
  // ---------------------------------------------------------------------------
433
1845
  /**
434
- * Wrap user code as the default export of an ES module with a top-level-awaited
435
- * async IIFE body, so `return <value>` inside the snippet becomes the module's
436
- * default export and `await` at the top level works.
1846
+ * User-code wrapping and the guest module loader live with the interpreter:
1847
+ * the worker path evaluates the same entry module and resolves through the
1848
+ * same loader, and a second copy of either would be a second security policy.
437
1849
  */
438
- export function wrapCode(code) {
439
- return `export default await (async () => {
440
- ${code}
441
- })();`;
1850
+ export { BLOCKED_TIMER_GLOBALS, buildEntryModule, createGuestModuleHost, DELETED_GUEST_GLOBALS, EXPOSED_BRIDGE_NAMES, SANDBOX_CAPABILITY_BRIDGE_BINDING, SANDBOX_HOST_BRIDGE_BINDING, SANDBOX_INPUT_TAKE_BINDING, SANDBOX_STREAM_OPEN_BINDING, SANDBOX_WASM_BRIDGE_BINDING, wrapCode } from "./js-sandbox-worker/interpreter.js";
1851
+ export function createSandboxClock() {
1852
+ let depth = 0;
1853
+ let openedAt = 0;
1854
+ let accumulated = 0;
1855
+ return {
1856
+ suspend() {
1857
+ if (depth === 0)
1858
+ openedAt = Date.now();
1859
+ depth++;
1860
+ let resumed = false;
1861
+ return () => {
1862
+ if (resumed)
1863
+ return;
1864
+ resumed = true;
1865
+ depth--;
1866
+ if (depth === 0)
1867
+ accumulated += Date.now() - openedAt;
1868
+ };
1869
+ },
1870
+ suspendedMs() {
1871
+ return depth > 0 ? accumulated + (Date.now() - openedAt) : accumulated;
1872
+ }
1873
+ };
442
1874
  }
443
1875
  const IDENTIFIER_RE = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
444
1876
  /** Overwrite the contents of `target` with the contents of `source` in place. */
@@ -451,47 +1883,77 @@ function replaceInPlace(target, source) {
451
1883
  }
452
1884
  return;
453
1885
  }
454
- if (target && typeof target === "object") {
1886
+ if (isObjectLike(target)) {
455
1887
  const t = target;
456
1888
  for (const key of Object.keys(t))
457
1889
  delete t[key];
458
- if (source && typeof source === "object" && !Array.isArray(source)) {
1890
+ if (isRecord(source)) {
459
1891
  const s = source;
460
1892
  for (const [k, v] of Object.entries(s))
461
1893
  t[k] = v;
462
1894
  }
463
1895
  }
464
1896
  }
1897
+ /**
1898
+ * Globals the guest prelude defines rather than the host marshals. All but
1899
+ * `stream` are pure — no host call behind them; `stream` is built here because
1900
+ * an async iterable cannot cross the bridge, so the prelude wraps the two
1901
+ * private input bindings into one.
1902
+ */
1903
+ export const GUEST_HELPER_NAMES = [
1904
+ "toBase64",
1905
+ "fromBase64",
1906
+ "toHex",
1907
+ "fromHex",
1908
+ "parallelMap",
1909
+ "createCanvas",
1910
+ "stream"
1911
+ ];
1912
+ /**
1913
+ * A dispatcher's entry point as a bare function, or nothing when the run
1914
+ * declared no such modules — which is what decides whether the guest gets the
1915
+ * binding at all.
1916
+ */
1917
+ function dispatchCallOf(dispatcher) {
1918
+ if (dispatcher === undefined)
1919
+ return undefined;
1920
+ return async (moduleKey, exportName, args) => dispatcher.call(moduleKey, exportName, args);
1921
+ }
465
1922
  /** Names that should never be reassigned via `globals` — core sandbox APIs. */
466
- const RESERVED_SANDBOX_NAMES = new Set([
467
- "console",
468
- "fetch",
469
- "uuid",
470
- "sleep",
471
- "getSecret",
472
- "workspace",
473
- "assetToSandbox",
474
- "sandboxToAsset",
475
- "__maxIter"
1923
+ export const RESERVED_SANDBOX_NAMES = new Set([
1924
+ ...EXPOSED_BRIDGE_NAMES,
1925
+ ...GUEST_HELPER_NAMES,
1926
+ SANDBOX_WASM_BRIDGE_BINDING,
1927
+ SANDBOX_WASM_DISPATCH_GLOBAL,
1928
+ SANDBOX_CAPABILITY_BRIDGE_BINDING,
1929
+ SANDBOX_CAPABILITY_DISPATCH_GLOBAL,
1930
+ SANDBOX_INPUT_TAKE_BINDING,
1931
+ SANDBOX_STREAM_OPEN_BINDING,
1932
+ GUEST_MARSHAL_GLOBAL,
1933
+ GUEST_GLOBALS_JSON_BINDING,
1934
+ GUEST_GLOBALS_SIDECAR_BINDING
476
1935
  ]);
477
1936
  /**
478
- * Names injected as bridge bindings into the QuickJS guest. The rest of the
479
- * `buildSandbox` record (JSON, Math, Date, URL, etc.) is deliberately NOT
480
- * marshaled — QuickJS already provides native implementations, and re-exposing
481
- * host versions creates thousands of handles that slow execution and leak on
482
- * teardown.
1937
+ * Combine a guest error's name and message the way the report reads best:
1938
+ * include the name when it carries signal (`ExecutionTimeout`), drop it when
1939
+ * it is `Error` or already inside the message.
483
1940
  */
484
- const EXPOSED_BRIDGE_NAMES = [
485
- "console",
486
- "fetch",
487
- "uuid",
488
- "sleep",
489
- "getSecret",
490
- "workspace",
491
- "assetToSandbox",
492
- "sandboxToAsset",
493
- "__maxIter"
494
- ];
1941
+ function combineGuestError(name, message) {
1942
+ return name &&
1943
+ name !== "Error" &&
1944
+ !message.toLowerCase().includes(name.toLowerCase())
1945
+ ? `${name}: ${message}`
1946
+ : message || name;
1947
+ }
1948
+ /** Warn once per process when the worker path silently falls back in-process. */
1949
+ let warnedWorkerFallback = false;
1950
+ function noteWorkerFallback(reason) {
1951
+ if (warnedWorkerFallback)
1952
+ return;
1953
+ warnedWorkerFallback = true;
1954
+ console.warn(`sandbox: running in-process (${reason}); a CPU-bound guest will block ` +
1955
+ "this thread until its timeout");
1956
+ }
495
1957
  /**
496
1958
  * Execute JavaScript code inside a QuickJS WebAssembly sandbox.
497
1959
  *
@@ -499,11 +1961,85 @@ const EXPOSED_BRIDGE_NAMES = [
499
1961
  * handler / memory limiter, so runaway user code can't exhaust host resources.
500
1962
  */
501
1963
  export async function runInSandbox(options) {
502
- const { code, context, timeoutMs = DEFAULT_TIMEOUT_MS, globals } = options;
1964
+ const { code, context, timeoutMs = DEFAULT_TIMEOUT_MS, globals, signal, limits, onProgress, onLog, onEmit, onTakeInput, onStreamOpen, clock, modules, capabilities, wasmPool, resolveMediaRef, promoteMedia, resolveHost } = options;
1965
+ if (options.hermetic && (capabilities || (globals && Object.keys(globals).length) ||
1966
+ modules?.modules.some((module) => module.kind !== "js"))) {
1967
+ return { success: false, error: "Hermetic execution accepts only guest JavaScript modules and literal program inputs", logs: [] };
1968
+ }
1969
+ const resolvedLimits = resolveSandboxLimits(limits);
1970
+ // A streaming run needs a clock whether or not the caller brought one: the
1971
+ // time it spends parked on upstream is not its own execution.
1972
+ const activeClock = clock ?? (onTakeInput ? createSandboxClock() : undefined);
1973
+ const suspendAllowanceMs = options.suspendAllowanceMs ??
1974
+ (onTakeInput
1975
+ ? INPUT_STREAM_SUSPEND_ALLOWANCE_MS
1976
+ : DEFAULT_SUSPEND_ALLOWANCE_MS);
503
1977
  if (!code.trim()) {
504
1978
  return { success: false, error: "No code provided", logs: [] };
505
1979
  }
506
- const { sandbox, getLogs } = buildSandbox(context);
1980
+ // The dispatcher is built first: it reads every declared WASM binary, so a
1981
+ // module the catalog could not honour is reported here rather than as a
1982
+ // broken facade the guest imports.
1983
+ let wasm;
1984
+ let hostModules;
1985
+ const wasmOptions = {};
1986
+ if (wasmPool !== undefined)
1987
+ wasmOptions.pool = wasmPool;
1988
+ if (signal !== undefined)
1989
+ wasmOptions.signal = signal;
1990
+ const hostOptions = {};
1991
+ if (signal !== undefined)
1992
+ hostOptions.signal = signal;
1993
+ try {
1994
+ wasm = modules && !options.hermetic
1995
+ ? createSandboxWasmDispatcher(modules.modules, wasmOptions)
1996
+ : undefined;
1997
+ hostModules = modules && !options.hermetic
1998
+ ? createSandboxHostDispatcher(modules.modules, hostOptions)
1999
+ : undefined;
2000
+ }
2001
+ catch (error) {
2002
+ return {
2003
+ success: false,
2004
+ error: error instanceof Error ? error.message : String(error),
2005
+ logs: []
2006
+ };
2007
+ }
2008
+ if (signal?.aborted) {
2009
+ return { success: false, error: "Execution cancelled", logs: [] };
2010
+ }
2011
+ const streams = {};
2012
+ if (onTakeInput !== undefined)
2013
+ streams.onTakeInput = onTakeInput;
2014
+ if (onStreamOpen !== undefined)
2015
+ streams.onStreamOpen = onStreamOpen;
2016
+ if (activeClock !== undefined)
2017
+ streams.clock = activeClock;
2018
+ const { sandbox, getLogs, getOutputs, getEmitted } = buildSandbox(options.hermetic ? undefined : context, signal, resolvedLimits, options.hermetic ? undefined : onProgress, options.hermetic ? undefined : onLog, options.hermetic ? undefined : onEmit, options.hermetic ? {} : streams, options.hermetic ? undefined : resolveMediaRef, options.hermetic ? undefined : promoteMedia, options.hermetic ? undefined : resolveHost);
2019
+ if (options.hermetic) {
2020
+ // Deny host bridge functions before either interpreter receives them.
2021
+ // Only console collection survives. Native guest arithmetic is not a bridge.
2022
+ const refuse = (path) => async () => {
2023
+ throw new Error(`${path} is unavailable during hermetic construction`);
2024
+ };
2025
+ const restrict = (value, path) => {
2026
+ if (typeof value === "function") {
2027
+ return refuse(path);
2028
+ }
2029
+ if (value && typeof value === "object") {
2030
+ return Object.fromEntries(Object.entries(value).map(([key, member]) => [key, restrict(member, `${path}.${key}`)]));
2031
+ }
2032
+ return value;
2033
+ };
2034
+ const hostBindings = sandbox;
2035
+ for (const name of EXPOSED_BRIDGE_NAMES) {
2036
+ if (name !== "console") {
2037
+ hostBindings[name] = restrict(hostBindings[name], name);
2038
+ }
2039
+ }
2040
+ hostBindings[SANDBOX_INPUT_TAKE_BINDING] = refuse("stream");
2041
+ hostBindings[SANDBOX_STREAM_OPEN_BINDING] = () => false;
2042
+ }
507
2043
  // User-supplied globals (dynamic inputs from CodeNode etc.) layer on top of
508
2044
  // the core surface, but must not clobber the bridge functions themselves.
509
2045
  const userGlobals = {};
@@ -517,138 +2053,299 @@ export async function runInSandbox(options) {
517
2053
  }
518
2054
  }
519
2055
  // Identify object-typed globals whose contents should be synced back to the
520
- // host after the guest runs. Primitives are passed by value and need no sync.
2056
+ // host after the guest runs. Primitives are passed by value and need no
2057
+ // sync. A global holding a function anywhere inside it — a hermetic bake's
2058
+ // `{ nodetool: { timelines: { edit() {...} } } }` stub — is excluded even
2059
+ // though it is object-typed: nothing reads a synced-back copy of a stub
2060
+ // (CodeNode's `state` object is the only real consumer, and it never holds
2061
+ // functions), and extracting the guest's current value asks the engine to
2062
+ // marshal a live function back out on every successful run, on top of the
2063
+ // one it already crossed in as. That is reach the sync-back exists to
2064
+ // avoid, not a capability it needs.
2065
+ const objectGlobalHasFunction = (value, seen = new Set()) => {
2066
+ if (typeof value === "function")
2067
+ return true;
2068
+ if (value === null || typeof value !== "object")
2069
+ return false;
2070
+ if (seen.has(value))
2071
+ return false;
2072
+ seen.add(value);
2073
+ return Object.values(value).some((entry) => objectGlobalHasFunction(entry, seen));
2074
+ };
521
2075
  const syncTargetNames = Object.entries(userGlobals)
522
- .filter(([, v]) => v !== null && typeof v === "object")
2076
+ .filter(([, v]) => isObjectLike(v) && !objectGlobalHasFunction(v))
523
2077
  .map(([k]) => k);
2078
+ // Write the extracted object-global snapshots back into the caller's own
2079
+ // objects. Both paths end here: node:vm shared the host heap, QuickJS does
2080
+ // not, and a worker makes the separation literal. CodeNode relies on this to
2081
+ // make its `state` object persist across invocations.
2082
+ const writeBackGlobals = (extracted) => {
2083
+ if (!extracted)
2084
+ return;
2085
+ for (const name of syncTargetNames) {
2086
+ const hostValue = userGlobals[name];
2087
+ const guestValue = extracted[name];
2088
+ if (isObjectLike(hostValue) && isObjectLike(guestValue)) {
2089
+ replaceInPlace(hostValue, guestValue);
2090
+ }
2091
+ }
2092
+ };
2093
+ // Off the main thread whenever possible. A CPU-bound guest blocks whichever
2094
+ // thread runs it; on the server's main thread that freeze takes the whole
2095
+ // event loop — including the websocket `stop` frame that would have
2096
+ // cancelled the run — down with it. On a worker, abort is `terminate()`,
2097
+ // immediate for spinning and parked guests alike; the logs and emitted
2098
+ // values survive because they accumulate on this side of the port.
2099
+ //
2100
+ // Streaming runs stay in-process: the synchronous `stream.open` probe is
2101
+ // served from a worker-local mirror that must be seeded with the handle
2102
+ // names, which this signature does not carry. Those runs park on takes and
2103
+ // yield the thread constantly, so the freeze this path exists for cannot
2104
+ // build up there.
2105
+ const env = typeof globalThis.process?.env === "object"
2106
+ ? globalThis.process.env
2107
+ : undefined;
2108
+ const workerRequired = env?.NODETOOL_SANDBOX_WORKER === "require";
2109
+ let workerUnavailable = null;
2110
+ // A chosen or designed fallback is quiet; an environmental one warns once.
2111
+ let fallbackByDesign = false;
2112
+ if (env?.NODETOOL_SANDBOX_INPROC === "1") {
2113
+ workerUnavailable = "NODETOOL_SANDBOX_INPROC=1";
2114
+ fallbackByDesign = true;
2115
+ }
2116
+ else if (onTakeInput !== undefined || onStreamOpen !== undefined) {
2117
+ workerUnavailable = "the run streams inputs";
2118
+ fallbackByDesign = true;
2119
+ }
2120
+ else {
2121
+ const safety = precheckCloneSafety(userGlobals);
2122
+ if (!safety.ok) {
2123
+ workerUnavailable = safety.reason;
2124
+ }
2125
+ }
2126
+ if (workerUnavailable === null) {
2127
+ const dispatcherKinds = [];
2128
+ const dispatch = { ...sandbox };
2129
+ const bindDispatcher = (kind, call) => {
2130
+ if (call === undefined)
2131
+ return;
2132
+ dispatch[SANDBOX_DISPATCHER_BINDINGS[kind]] = call;
2133
+ dispatcherKinds.push(kind);
2134
+ };
2135
+ bindDispatcher("wasm", dispatchCallOf(wasm));
2136
+ bindDispatcher("host", dispatchCallOf(hostModules));
2137
+ bindDispatcher("capability", dispatchCallOf(capabilities));
2138
+ for (const [name, value] of Object.entries(userGlobals)) {
2139
+ if (isFunction(value))
2140
+ dispatch[name] = value;
2141
+ }
2142
+ const workerRun = {
2143
+ runId: globalThis.crypto.randomUUID(),
2144
+ code,
2145
+ timeoutMs,
2146
+ limits: resolvedLimits,
2147
+ suspendAllowanceMs,
2148
+ hasClock: activeClock !== undefined,
2149
+ engineTimeoutMs: activeClock !== undefined
2150
+ ? Math.min(timeoutMs + suspendAllowanceMs, MAX_ENGINE_TIMEOUT_MS)
2151
+ : timeoutMs,
2152
+ streamOpenSeed: null,
2153
+ bridgeShape: deriveBridgeShape({
2154
+ bridges: sandbox,
2155
+ dispatchers: dispatcherKinds,
2156
+ globals: userGlobals
2157
+ })
2158
+ };
2159
+ if (modules !== undefined)
2160
+ workerRun.modules = modules;
2161
+ if (capabilities?.facades !== undefined) {
2162
+ workerRun.capabilityFacades = capabilities.facades;
2163
+ }
2164
+ const workerOptions = {
2165
+ run: workerRun,
2166
+ dispatch,
2167
+ // Console and progress already reach their accumulators through the
2168
+ // RPC'd bridges; the push channel exists for a worker that has nothing
2169
+ // else to say, which this integration does not use.
2170
+ onLog: () => { },
2171
+ onProgress: () => { }
2172
+ };
2173
+ if (signal !== undefined)
2174
+ workerOptions.signal = signal;
2175
+ if (activeClock !== undefined) {
2176
+ workerOptions.suspendedMs = () => activeClock.suspendedMs();
2177
+ }
2178
+ const message = await runInWorker(workerOptions);
2179
+ if (message === null) {
2180
+ workerUnavailable = "no sandbox worker could be started here";
2181
+ }
2182
+ else {
2183
+ writeBackGlobals(message.syncedGlobals);
2184
+ const logs = getLogs();
2185
+ // Cancellation wins over whatever the guest was doing when the interrupt
2186
+ // handler cut it — the in-process race has the same rule. The interrupted
2187
+ // guest's own error (`InternalError: interrupted`) is an implementation
2188
+ // detail, not a result.
2189
+ if (signal?.aborted === true) {
2190
+ return {
2191
+ success: false,
2192
+ error: "Execution cancelled",
2193
+ logs,
2194
+ emitted: getEmitted()
2195
+ };
2196
+ }
2197
+ if (message.failure === "cancelled") {
2198
+ return {
2199
+ success: false,
2200
+ error: "Execution cancelled",
2201
+ logs,
2202
+ emitted: getEmitted()
2203
+ };
2204
+ }
2205
+ if (message.failure === "worker") {
2206
+ return {
2207
+ success: false,
2208
+ error: describeEngineFailure(new Error(message.errorMessage ?? "the sandbox worker failed")),
2209
+ logs: logs.length > 0 ? logs : undefined,
2210
+ emitted: getEmitted()
2211
+ };
2212
+ }
2213
+ if (!message.evalOk) {
2214
+ return {
2215
+ success: false,
2216
+ error: combineGuestError(message.errorName ?? "", message.errorMessage ?? ""),
2217
+ stack: message.errorStack
2218
+ ? cleanStack(message.errorStack)
2219
+ : undefined,
2220
+ logs: logs.length > 0 ? logs : undefined,
2221
+ emitted: getEmitted()
2222
+ };
2223
+ }
2224
+ return {
2225
+ success: true,
2226
+ result: serializeResult(message.data, resolvedLimits.maxOutputSize),
2227
+ logs: logs.length > 0 ? logs : undefined,
2228
+ outputs: getOutputs(),
2229
+ emitted: getEmitted()
2230
+ };
2231
+ }
2232
+ }
2233
+ if (workerRequired) {
2234
+ return {
2235
+ success: false,
2236
+ error: `the sandbox worker path is required (NODETOOL_SANDBOX_WORKER=require) but unavailable: ${workerUnavailable}`,
2237
+ logs: []
2238
+ };
2239
+ }
2240
+ if (!fallbackByDesign) {
2241
+ noteWorkerFallback(workerUnavailable);
2242
+ }
524
2243
  try {
525
2244
  const { runSandboxed } = await getEngine();
526
- const evalResponse = await runSandboxed(async ({ ctx, evalCode }) => {
527
- const bridges = {};
528
- for (const name of EXPOSED_BRIDGE_NAMES) {
529
- bridges[name] = sandbox[name];
530
- }
531
- // Wrap every async bridge in a never-reject adapter (see
532
- // SANDBOX_ERROR_MARKER above). The guest prelude rewraps them back into
533
- // throwing functions before user code runs.
534
- bridges.fetch = neverReject(bridges.fetch);
535
- bridges.sleep = neverReject(bridges.sleep);
536
- bridges.getSecret = neverReject(bridges.getSecret);
537
- bridges.assetToSandbox = neverReject(bridges.assetToSandbox);
538
- bridges.sandboxToAsset = neverReject(bridges.sandboxToAsset);
539
- const ws = bridges.workspace;
540
- bridges.workspace = {
541
- read: neverReject(ws.read),
542
- write: neverReject(ws.write),
543
- list: neverReject(ws.list)
544
- };
545
- Object.assign(bridges, userGlobals);
546
- // `expose` manages its own internal Scope; the second arg is unused.
547
- const disposable = new Scope();
548
- try {
549
- expose(ctx, disposable, bridges);
550
- }
551
- finally {
552
- disposable.dispose();
553
- }
554
- // Block dynamic code generation and re-wrap the never-reject bridges as
555
- // throwing guest-side functions. Direct eval in QuickJS can't be neutered
556
- // by overwriting `globalThis.eval` (QuickJS still resolves the builtin),
557
- // but a plain `delete` removes the binding entirely so any reference
558
- // throws ReferenceError — same for `Function`.
559
- await evalCode(`const __marker = "${SANDBOX_ERROR_MARKER}";
560
- const __wrap = (fn) => async (...args) => {
561
- const r = await fn(...args);
562
- if (r && r[__marker]) {
563
- const e = new Error(r.message);
564
- e.name = r.name;
565
- throw e;
566
- }
567
- return r;
568
- };
569
- globalThis.fetch = __wrap(globalThis.fetch);
570
- globalThis.sleep = __wrap(globalThis.sleep);
571
- globalThis.getSecret = __wrap(globalThis.getSecret);
572
- globalThis.assetToSandbox = __wrap(globalThis.assetToSandbox);
573
- globalThis.sandboxToAsset = __wrap(globalThis.sandboxToAsset);
574
- const __ws = globalThis.workspace;
575
- globalThis.workspace = {
576
- read: __wrap(__ws.read),
577
- write: __wrap(__ws.write),
578
- list: __wrap(__ws.list)
579
- };
580
- delete globalThis.eval;
581
- delete globalThis.Function;
582
- export default true;`, "sandbox-init");
583
- const userResult = await evalCode(wrapCode(code), "user-code");
584
- // Sync mutable globals back to the host. node:vm shared the host heap,
585
- // so `state.counter++` in user code mutated the caller's object directly.
586
- // With QuickJS the guest heap is isolated, so after user code runs we
587
- // extract the current values of the object-typed user globals and
588
- // replace the contents of the host-side objects in place. CodeNode
589
- // relies on this to make its `state` object persist across invocations.
590
- if (userResult.ok && syncTargetNames.length > 0) {
591
- const extractor = `export default {${syncTargetNames
592
- .map((n) => `${n}: (typeof ${n} !== 'undefined' && ${n} !== null) ? ${n} : null`)
593
- .join(", ")}};`;
594
- const syncResp = await evalCode(extractor, "sandbox-sync");
595
- if (syncResp.ok && syncResp.data && typeof syncResp.data === "object") {
596
- const extracted = syncResp.data;
597
- for (const name of syncTargetNames) {
598
- const hostValue = userGlobals[name];
599
- const guestValue = extracted[name];
600
- if (hostValue !== null &&
601
- typeof hostValue === "object" &&
602
- guestValue !== null &&
603
- typeof guestValue === "object") {
604
- replaceInPlace(hostValue, guestValue);
605
- }
606
- }
607
- }
608
- }
609
- return userResult;
610
- }, {
611
- executionTimeout: timeoutMs,
612
- memoryLimit: GUEST_MEMORY_LIMIT,
613
- maxStackSize: GUEST_STACK_LIMIT
2245
+ // The dispatchers stay on this side of the boundary — the interpreter only
2246
+ // ever sees a call function, which is as true of a worker's RPC proxy as it
2247
+ // is of the real dispatcher here.
2248
+ const interpreterParams = {
2249
+ runSandboxed,
2250
+ code,
2251
+ sandbox,
2252
+ globals: userGlobals,
2253
+ syncTargetNames,
2254
+ timeoutMs,
2255
+ limits: resolvedLimits,
2256
+ suspendAllowanceMs,
2257
+ hasClock: activeClock !== undefined,
2258
+ wasmCall: dispatchCallOf(wasm),
2259
+ hostCall: dispatchCallOf(hostModules),
2260
+ capabilityCall: dispatchCallOf(capabilities),
2261
+ modules,
2262
+ capabilityFacades: capabilities?.facades
2263
+ };
2264
+ // The interpreter cannot hold either host object: neither an AbortSignal
2265
+ // nor a clock survives a thread boundary, so both arrive as a probe.
2266
+ if (signal !== undefined) {
2267
+ interpreterParams.isAborted = () => signal.aborted;
2268
+ }
2269
+ if (activeClock !== undefined) {
2270
+ interpreterParams.suspendedMs = () => activeClock.suspendedMs();
2271
+ }
2272
+ const sandboxRun = runInterpreter(interpreterParams).then((outcome) => {
2273
+ // The write-back runs as soon as the guest is done, even when
2274
+ // cancellation already won the race below — an orphaned run still owns
2275
+ // the answer it computed.
2276
+ writeBackGlobals(outcome.syncedGlobals);
2277
+ return outcome;
2278
+ });
2279
+ // Return as soon as cancellation lands. The bridges above make a guest that
2280
+ // awaits anything unwind almost immediately; this race additionally covers
2281
+ // a CPU-bound guest, which QuickJS gives us no way to interrupt early — the
2282
+ // orphaned run still winds down on its own execution timeout.
2283
+ const cancellation = new Promise((resolve) => {
2284
+ if (!signal)
2285
+ return;
2286
+ signal.addEventListener("abort", () => resolve(null), { once: true });
614
2287
  });
2288
+ const raced = await guardHostProcess(Promise.race([sandboxRun, cancellation]));
2289
+ if (raced === null) {
2290
+ return {
2291
+ success: false,
2292
+ error: "Execution cancelled",
2293
+ logs: getLogs(),
2294
+ emitted: getEmitted()
2295
+ };
2296
+ }
2297
+ const evalResponse = raced;
615
2298
  const logs = getLogs();
616
2299
  if (!evalResponse.ok) {
617
- // Include the error name alongside the message when the name carries
618
- // useful signal (e.g. `ExecutionTimeout` for the library's wall-clock
619
- // abort). `Error` is redundant, so omit it.
620
- const name = evalResponse.error.name;
621
- const message = evalResponse.error.message;
622
- const combined = name && name !== "Error" && !message.toLowerCase().includes(name.toLowerCase())
623
- ? `${name}: ${message}`
624
- : message || name;
2300
+ const combined = combineGuestError(evalResponse.error.name, evalResponse.error.message);
625
2301
  return {
626
2302
  success: false,
627
2303
  error: combined,
628
2304
  stack: evalResponse.error.stack
629
2305
  ? cleanStack(evalResponse.error.stack)
630
2306
  : undefined,
631
- logs: logs.length > 0 ? logs : undefined
2307
+ logs: logs.length > 0 ? logs : undefined,
2308
+ // Emitted values were delivered while the guest still ran, so they
2309
+ // stand. Recorded `output` finals do not: the run has no answer.
2310
+ emitted: getEmitted()
632
2311
  };
633
2312
  }
634
2313
  return {
635
2314
  success: true,
636
- result: serializeResult(evalResponse.data),
637
- logs: logs.length > 0 ? logs : undefined
2315
+ result: serializeResult(evalResponse.data, resolvedLimits.maxOutputSize),
2316
+ logs: logs.length > 0 ? logs : undefined,
2317
+ outputs: getOutputs(),
2318
+ emitted: getEmitted()
638
2319
  };
639
2320
  }
640
2321
  catch (e) {
641
- // Host-side failures (engine load error, marshaling bug, etc.). Guest-side
642
- // errors go through evalResponse.ok=false above.
2322
+ // Host-side failures (engine load error, marshaling bug, an aborted
2323
+ // runtime). Guest-side errors go through evalResponse.ok=false above.
2324
+ // An engine failure is reported in terms the caller can act on: the raw
2325
+ // Emscripten assertion text tells an agent nothing it can retry against.
643
2326
  const logs = getLogs();
644
- const errorMessage = e instanceof Error ? e.message : String(e);
2327
+ const errorMessage = describeEngineFailure(e);
645
2328
  const errorStack = e instanceof Error ? cleanStack(e.stack ?? "") : undefined;
646
2329
  return {
647
2330
  success: false,
648
2331
  error: errorMessage,
649
2332
  stack: errorStack,
650
- logs: logs.length > 0 ? logs : undefined
2333
+ logs: logs.length > 0 ? logs : undefined,
2334
+ emitted: getEmitted()
651
2335
  };
652
2336
  }
653
2337
  }
2338
+ // ---------------------------------------------------------------------------
2339
+ // Guest preludes for tool-bridged hosts
2340
+ // ---------------------------------------------------------------------------
2341
+ /**
2342
+ * Re-exported here because `./js-sandbox` is the one browser-safe subpath
2343
+ * export of this package: `nodetool.code.Code` (packages/code-nodes) is
2344
+ * bundled for the in-browser runner and must reach these prelude strings
2345
+ * without importing the package index, which drags the whole toolbelt —
2346
+ * native canvas, IMAP, execution — into a web build. Both modules are pure
2347
+ * strings over leaf imports.
2348
+ */
2349
+ export { TOOLS_PRELUDE } from "./codeact/tools-prelude.js";
2350
+ export { NODETOOL_API_PRELUDE_FULL } from "./codeact/nodetool-api.js";
654
2351
  //# sourceMappingURL=js-sandbox.js.map