@nodetool-ai/node-sdk 0.8.4-a24.3 → 0.8.4

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 (256) hide show
  1. package/dist/.nodetool-build-stamp +1 -1
  2. package/dist/_sandbox/README.md +176 -0
  3. package/dist/_sandbox/sandbox-aws/SKILL.md +98 -0
  4. package/dist/_sandbox/sandbox-aws/package.json +40 -0
  5. package/dist/_sandbox/sandbox-chrono/SKILL.md +39 -0
  6. package/dist/_sandbox/sandbox-chrono/package.json +40 -0
  7. package/dist/_sandbox/sandbox-color/SKILL.md +35 -0
  8. package/dist/_sandbox/sandbox-color/package.json +43 -0
  9. package/dist/_sandbox/sandbox-csv/SKILL.md +50 -0
  10. package/dist/_sandbox/sandbox-csv/package.json +39 -0
  11. package/dist/_sandbox/sandbox-dates/SKILL.md +47 -0
  12. package/dist/_sandbox/sandbox-dates/package.json +41 -0
  13. package/dist/_sandbox/sandbox-decimal/SKILL.md +36 -0
  14. package/dist/_sandbox/sandbox-decimal/package.json +43 -0
  15. package/dist/_sandbox/sandbox-diff/SKILL.md +36 -0
  16. package/dist/_sandbox/sandbox-diff/package.json +39 -0
  17. package/dist/_sandbox/sandbox-docx/SKILL.md +53 -0
  18. package/dist/_sandbox/sandbox-docx/package.json +40 -0
  19. package/dist/_sandbox/sandbox-dsl/SKILL.md +137 -0
  20. package/dist/_sandbox/sandbox-dsl/package.json +413 -0
  21. package/dist/_sandbox/sandbox-dsl/sandbox/authoring.js +382 -0
  22. package/dist/_sandbox/sandbox-dsl/sandbox/core.js +382 -0
  23. package/dist/_sandbox/sandbox-dsl/sandbox/generated/gemini.audio.js +12 -0
  24. package/dist/_sandbox/sandbox-dsl/sandbox/generated/gemini.image.js +8 -0
  25. package/dist/_sandbox/sandbox-dsl/sandbox/generated/gemini.text.js +12 -0
  26. package/dist/_sandbox/sandbox-dsl/sandbox/generated/gemini.video.js +12 -0
  27. package/dist/_sandbox/sandbox-dsl/sandbox/generated/index.js +149 -0
  28. package/dist/_sandbox/sandbox-dsl/sandbox/generated/kie.dynamic_schema.js +8 -0
  29. package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.audio.js +68 -0
  30. package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.browser.js +8 -0
  31. package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.charts.js +8 -0
  32. package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.comfy.js +16 -0
  33. package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.grid.js +8 -0
  34. package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.image.channel.js +12 -0
  35. package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.image.color.js +32 -0
  36. package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.image.color_grading.js +44 -0
  37. package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.image.draw.js +36 -0
  38. package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.image.effects.js +24 -0
  39. package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.image.enhance.js +28 -0
  40. package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.image.filter.js +64 -0
  41. package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.image.js +8 -0
  42. package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.image.keyer.js +12 -0
  43. package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.image.mask.js +16 -0
  44. package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.image.warp.js +36 -0
  45. package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.pdf.js +32 -0
  46. package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.sqlite.js +8 -0
  47. package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.stable_diffusion_cpp.js +8 -0
  48. package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.svg.js +12 -0
  49. package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.video.download.js +8 -0
  50. package/dist/_sandbox/sandbox-dsl/sandbox/generated/messaging.discord.js +8 -0
  51. package/dist/_sandbox/sandbox-dsl/sandbox/generated/messaging.telegram.js +8 -0
  52. package/dist/_sandbox/sandbox-dsl/sandbox/generated/mistral.embeddings.js +8 -0
  53. package/dist/_sandbox/sandbox-dsl/sandbox/generated/mistral.text.js +12 -0
  54. package/dist/_sandbox/sandbox-dsl/sandbox/generated/mistral.vision.js +12 -0
  55. package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.agents.js +32 -0
  56. package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.audio.js +104 -0
  57. package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.audio.realtime.js +28 -0
  58. package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.audio.synth.js +40 -0
  59. package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.blender.js +28 -0
  60. package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.code.js +8 -0
  61. package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.compare.js +8 -0
  62. package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.constant.js +132 -0
  63. package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.control.js +96 -0
  64. package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.creative.js +24 -0
  65. package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.data.js +12 -0
  66. package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.document.js +16 -0
  67. package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.entity.js +16 -0
  68. package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.fake.js +12 -0
  69. package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.game.js +36 -0
  70. package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.generators.js +24 -0
  71. package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.image.js +120 -0
  72. package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.input.js +140 -0
  73. package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.manimgx.js +16 -0
  74. package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.model3d.js +76 -0
  75. package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.output.js +8 -0
  76. package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.script.js +28 -0
  77. package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.sketch.js +16 -0
  78. package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.storyboard.js +32 -0
  79. package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.text.js +56 -0
  80. package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.timeline.js +24 -0
  81. package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.triggers.js +24 -0
  82. package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.variable.js +12 -0
  83. package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.video.js +136 -0
  84. package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.workflows.app_node.js +8 -0
  85. package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.workflows.base_node.js +8 -0
  86. package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.workflows.subgraph.js +8 -0
  87. package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.workflows.workflow_node.js +8 -0
  88. package/dist/_sandbox/sandbox-dsl/sandbox/generated/openai.agents.js +16 -0
  89. package/dist/_sandbox/sandbox-dsl/sandbox/generated/openai.audio.js +16 -0
  90. package/dist/_sandbox/sandbox-dsl/sandbox/generated/openai.image.js +16 -0
  91. package/dist/_sandbox/sandbox-dsl/sandbox/generated/openai.text.js +16 -0
  92. package/dist/_sandbox/sandbox-dsl/sandbox/generated/vector.js +56 -0
  93. package/dist/_sandbox/sandbox-dsl/sandbox/generated/whisper_cpp.js +8 -0
  94. package/dist/_sandbox/sandbox-dsl/sandbox/generated/xai.image.js +8 -0
  95. package/dist/_sandbox/sandbox-dsl/sandbox/generated/xai.text.js +12 -0
  96. package/dist/_sandbox/sandbox-dsl/sandbox/generated/xai.vision.js +8 -0
  97. package/dist/_sandbox/sandbox-dsl/sandbox/index.js +13 -0
  98. package/dist/_sandbox/sandbox-dsl/scripts/build.mjs +116 -0
  99. package/dist/_sandbox/sandbox-epub/SKILL.md +61 -0
  100. package/dist/_sandbox/sandbox-epub/package.json +40 -0
  101. package/dist/_sandbox/sandbox-exif/SKILL.md +30 -0
  102. package/dist/_sandbox/sandbox-exif/package.json +40 -0
  103. package/dist/_sandbox/sandbox-expr/SKILL.md +28 -0
  104. package/dist/_sandbox/sandbox-expr/package.json +40 -0
  105. package/dist/_sandbox/sandbox-fabric/SKILL.md +113 -0
  106. package/dist/_sandbox/sandbox-fabric/package.json +40 -0
  107. package/dist/_sandbox/sandbox-flow/SKILL.md +131 -0
  108. package/dist/_sandbox/sandbox-flow/package.json +411 -0
  109. package/dist/_sandbox/sandbox-flow/sandbox/generated/gemini.audio.js +12 -0
  110. package/dist/_sandbox/sandbox-flow/sandbox/generated/gemini.image.js +8 -0
  111. package/dist/_sandbox/sandbox-flow/sandbox/generated/gemini.text.js +12 -0
  112. package/dist/_sandbox/sandbox-flow/sandbox/generated/gemini.video.js +12 -0
  113. package/dist/_sandbox/sandbox-flow/sandbox/generated/kie.dynamic_schema.js +8 -0
  114. package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.audio.js +68 -0
  115. package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.browser.js +8 -0
  116. package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.charts.js +8 -0
  117. package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.comfy.js +25 -0
  118. package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.grid.js +8 -0
  119. package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.image.channel.js +12 -0
  120. package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.image.color.js +32 -0
  121. package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.image.color_grading.js +44 -0
  122. package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.image.draw.js +36 -0
  123. package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.image.effects.js +24 -0
  124. package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.image.enhance.js +28 -0
  125. package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.image.filter.js +64 -0
  126. package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.image.js +8 -0
  127. package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.image.keyer.js +12 -0
  128. package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.image.mask.js +16 -0
  129. package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.image.warp.js +36 -0
  130. package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.pdf.js +32 -0
  131. package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.sqlite.js +8 -0
  132. package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.stable_diffusion_cpp.js +8 -0
  133. package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.svg.js +12 -0
  134. package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.video.download.js +8 -0
  135. package/dist/_sandbox/sandbox-flow/sandbox/generated/messaging.discord.js +11 -0
  136. package/dist/_sandbox/sandbox-flow/sandbox/generated/messaging.telegram.js +11 -0
  137. package/dist/_sandbox/sandbox-flow/sandbox/generated/mistral.embeddings.js +8 -0
  138. package/dist/_sandbox/sandbox-flow/sandbox/generated/mistral.text.js +12 -0
  139. package/dist/_sandbox/sandbox-flow/sandbox/generated/mistral.vision.js +12 -0
  140. package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.agents.js +41 -0
  141. package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.audio.js +110 -0
  142. package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.audio.realtime.js +46 -0
  143. package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.audio.synth.js +67 -0
  144. package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.blender.js +28 -0
  145. package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.code.js +11 -0
  146. package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.compare.js +8 -0
  147. package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.constant.js +132 -0
  148. package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.control.js +165 -0
  149. package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.creative.js +27 -0
  150. package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.data.js +18 -0
  151. package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.document.js +19 -0
  152. package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.entity.js +19 -0
  153. package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.fake.js +12 -0
  154. package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.game.js +39 -0
  155. package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.generators.js +30 -0
  156. package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.image.js +126 -0
  157. package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.input.js +143 -0
  158. package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.manimgx.js +16 -0
  159. package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.model3d.js +76 -0
  160. package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.output.js +11 -0
  161. package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.script.js +28 -0
  162. package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.sketch.js +16 -0
  163. package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.storyboard.js +35 -0
  164. package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.text.js +68 -0
  165. package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.timeline.js +24 -0
  166. package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.triggers.js +33 -0
  167. package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.variable.js +15 -0
  168. package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.video.js +145 -0
  169. package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.workflows.app_node.js +11 -0
  170. package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.workflows.base_node.js +8 -0
  171. package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.workflows.subgraph.js +11 -0
  172. package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.workflows.workflow_node.js +11 -0
  173. package/dist/_sandbox/sandbox-flow/sandbox/generated/openai.agents.js +25 -0
  174. package/dist/_sandbox/sandbox-flow/sandbox/generated/openai.audio.js +16 -0
  175. package/dist/_sandbox/sandbox-flow/sandbox/generated/openai.image.js +16 -0
  176. package/dist/_sandbox/sandbox-flow/sandbox/generated/openai.text.js +16 -0
  177. package/dist/_sandbox/sandbox-flow/sandbox/generated/vector.js +56 -0
  178. package/dist/_sandbox/sandbox-flow/sandbox/generated/whisper_cpp.js +11 -0
  179. package/dist/_sandbox/sandbox-flow/sandbox/generated/xai.image.js +8 -0
  180. package/dist/_sandbox/sandbox-flow/sandbox/generated/xai.text.js +12 -0
  181. package/dist/_sandbox/sandbox-flow/sandbox/generated/xai.vision.js +8 -0
  182. package/dist/_sandbox/sandbox-flow/sandbox/guest-core.js +35 -0
  183. package/dist/_sandbox/sandbox-flow/sandbox/index.js +10 -0
  184. package/dist/_sandbox/sandbox-flow/scripts/build.mjs +120 -0
  185. package/dist/_sandbox/sandbox-game/SKILL.md +116 -0
  186. package/dist/_sandbox/sandbox-game/package.json +36 -0
  187. package/dist/_sandbox/sandbox-game/sandbox/index.js +208 -0
  188. package/dist/_sandbox/sandbox-gif/SKILL.md +36 -0
  189. package/dist/_sandbox/sandbox-gif/package.json +43 -0
  190. package/dist/_sandbox/sandbox-html/SKILL.md +107 -0
  191. package/dist/_sandbox/sandbox-html/package.json +40 -0
  192. package/dist/_sandbox/sandbox-ics/SKILL.md +41 -0
  193. package/dist/_sandbox/sandbox-ics/package.json +40 -0
  194. package/dist/_sandbox/sandbox-jmespath/SKILL.md +26 -0
  195. package/dist/_sandbox/sandbox-jmespath/package.json +43 -0
  196. package/dist/_sandbox/sandbox-mammoth/SKILL.md +46 -0
  197. package/dist/_sandbox/sandbox-mammoth/package.json +41 -0
  198. package/dist/_sandbox/sandbox-markdown/SKILL.md +123 -0
  199. package/dist/_sandbox/sandbox-markdown/package.json +41 -0
  200. package/dist/_sandbox/sandbox-notion/SKILL.md +101 -0
  201. package/dist/_sandbox/sandbox-notion/package.json +38 -0
  202. package/dist/_sandbox/sandbox-ocr/SKILL.md +47 -0
  203. package/dist/_sandbox/sandbox-ocr/package.json +40 -0
  204. package/dist/_sandbox/sandbox-pdf/SKILL.md +47 -0
  205. package/dist/_sandbox/sandbox-pdf/package.json +39 -0
  206. package/dist/_sandbox/sandbox-pdflib/SKILL.md +56 -0
  207. package/dist/_sandbox/sandbox-pdflib/package.json +38 -0
  208. package/dist/_sandbox/sandbox-pptx/SKILL.md +42 -0
  209. package/dist/_sandbox/sandbox-pptx/package.json +40 -0
  210. package/dist/_sandbox/sandbox-pptxgen/SKILL.md +49 -0
  211. package/dist/_sandbox/sandbox-pptxgen/package.json +38 -0
  212. package/dist/_sandbox/sandbox-qr/SKILL.md +43 -0
  213. package/dist/_sandbox/sandbox-qr/package.json +42 -0
  214. package/dist/_sandbox/sandbox-rrule/SKILL.md +37 -0
  215. package/dist/_sandbox/sandbox-rrule/package.json +43 -0
  216. package/dist/_sandbox/sandbox-stats/SKILL.md +42 -0
  217. package/dist/_sandbox/sandbox-stats/package.json +43 -0
  218. package/dist/_sandbox/sandbox-subtitle/SKILL.md +38 -0
  219. package/dist/_sandbox/sandbox-subtitle/package.json +41 -0
  220. package/dist/_sandbox/sandbox-supabase/SKILL.md +108 -0
  221. package/dist/_sandbox/sandbox-supabase/package.json +39 -0
  222. package/dist/_sandbox/sandbox-tfjs/SKILL.md +76 -0
  223. package/dist/_sandbox/sandbox-tfjs/package.json +42 -0
  224. package/dist/_sandbox/sandbox-timeline/SKILL.md +647 -0
  225. package/dist/_sandbox/sandbox-timeline/package.json +46 -0
  226. package/dist/_sandbox/sandbox-timeline/sandbox/charts.js +356 -0
  227. package/dist/_sandbox/sandbox-timeline/sandbox/components.js +171 -0
  228. package/dist/_sandbox/sandbox-timeline/sandbox/index.d.ts +700 -0
  229. package/dist/_sandbox/sandbox-timeline/sandbox/index.js +1658 -0
  230. package/dist/_sandbox/sandbox-tokens/SKILL.md +46 -0
  231. package/dist/_sandbox/sandbox-tokens/package.json +40 -0
  232. package/dist/_sandbox/sandbox-twilio/SKILL.md +93 -0
  233. package/dist/_sandbox/sandbox-twilio/package.json +39 -0
  234. package/dist/_sandbox/sandbox-xlsx/SKILL.md +74 -0
  235. package/dist/_sandbox/sandbox-xlsx/package.json +40 -0
  236. package/dist/_sandbox/sandbox-xml/SKILL.md +36 -0
  237. package/dist/_sandbox/sandbox-xml/package.json +40 -0
  238. package/dist/_sandbox/sandbox-yaml/SKILL.md +48 -0
  239. package/dist/_sandbox/sandbox-yaml/package.json +41 -0
  240. package/dist/_sandbox/sandbox-zip/SKILL.md +54 -0
  241. package/dist/_sandbox/sandbox-zip/package.json +40 -0
  242. package/dist/code-node-validation.d.ts +2 -0
  243. package/dist/code-node-validation.d.ts.map +1 -1
  244. package/dist/code-node-validation.js +1 -1
  245. package/dist/code-node-validation.js.map +1 -1
  246. package/dist/pack-loader.d.ts +1 -0
  247. package/dist/pack-loader.d.ts.map +1 -1
  248. package/dist/pack-loader.js +1 -0
  249. package/dist/pack-loader.js.map +1 -1
  250. package/dist/sandbox-catalog-host.js +1 -1
  251. package/dist/sandbox-catalog-host.js.map +1 -1
  252. package/dist/sandbox-pack-discovery.d.ts +3 -0
  253. package/dist/sandbox-pack-discovery.d.ts.map +1 -1
  254. package/dist/sandbox-pack-discovery.js +7 -3
  255. package/dist/sandbox-pack-discovery.js.map +1 -1
  256. package/package.json +5 -5
@@ -1 +1 @@
1
- 2026-10-16T18:28:20.369Z
1
+ 2026-10-17T11:16:09.598Z
@@ -0,0 +1,176 @@
1
+ # Sandbox library packs
2
+
3
+ One npm package per library the sandbox offers. Library bridge packs contain
4
+ a config-only `nodetool.sandboxModules` manifest and a SKILL.md. Authoring packs
5
+ such as sandbox-game and sandbox-timeline also ship guest JavaScript.
6
+
7
+ There is one import surface and no second route: a library is reached with
8
+ `import`, from a pack that is installed and declared on the node. The `data.*`
9
+ guest globals are gone.
10
+
11
+ ## The packs
12
+
13
+ | Pack | Library | Runs | Why |
14
+ |---|---|---|---|
15
+ | `@nodetool-ai/sandbox-dates` | date-fns | guest | compiler admits it |
16
+ | `@nodetool-ai/sandbox-yaml` | js-yaml | guest | compiler admits it |
17
+ | `@nodetool-ai/sandbox-markdown` | marked | guest | compiler admits it |
18
+ | `@nodetool-ai/sandbox-qr` | uqr | guest | compiler admits it |
19
+ | `@nodetool-ai/sandbox-subtitle` | subtitle | host | stream internals |
20
+ | `@nodetool-ai/sandbox-tokens` | js-tiktoken | host | megabytes of BPE ranks |
21
+ | `@nodetool-ai/sandbox-color` | culori | guest | compiler admits it |
22
+ | `@nodetool-ai/sandbox-decimal` | decimal.js | guest | compiler admits it |
23
+ | `@nodetool-ai/sandbox-expr` | expr-eval | host | bundle uses Function |
24
+ | `@nodetool-ai/sandbox-jmespath` | jmespath | guest | compiler admits it |
25
+ | `@nodetool-ai/sandbox-chrono` | chrono-node | host | locale tables / Date internals |
26
+ | `@nodetool-ai/sandbox-exif` | exifr | host | workers / DOM-shaped globals |
27
+ | `@nodetool-ai/sandbox-stats` | simple-statistics | guest | compiler admits it |
28
+ | `@nodetool-ai/sandbox-rrule` | rrule | guest | compiler admits it |
29
+ | `@nodetool-ai/sandbox-ics` | ics | host | Node-shaped helpers |
30
+ | `@nodetool-ai/sandbox-gif` | gifenc | guest | compiler admits it |
31
+ | `@nodetool-ai/sandbox-game` | NodeTool's game builder | guest | creates complete game documents and saves drafts atomically |
32
+ | `@nodetool-ai/sandbox-csv` | papaparse | host | imports `node:stream` |
33
+ | `@nodetool-ai/sandbox-html` | cheerio + turndown | host | 25 Node builtins; turndown wants a DOM |
34
+ | `@nodetool-ai/sandbox-xml` | fast-xml-parser | host | reads a bare `window` |
35
+ | `@nodetool-ai/sandbox-xlsx` | exceljs | host | Node streams |
36
+ | `@nodetool-ai/sandbox-diff` | diff | host | schedules with `setTimeout` |
37
+ | `@nodetool-ai/sandbox-zip` | fflate | host | the 50 MB inflation cap (below) |
38
+ | `@nodetool-ai/sandbox-ocr` | tesseract.js | host | WASM engine, workers, downloads its language data |
39
+ | `@nodetool-ai/sandbox-tfjs` | TensorFlow.js + model zoo | host | model weights outlive a run and outsize the guest heap |
40
+ | `@nodetool-ai/sandbox-docx` | docx | host | builds from class instances, not data |
41
+ | `@nodetool-ai/sandbox-mammoth` | mammoth | host | Node's own zip/XML stack |
42
+ | `@nodetool-ai/sandbox-epub` | epub2 | host | reads from a file path, not a buffer |
43
+ | `@nodetool-ai/sandbox-fabric` | fabric | host | DOM/Canvas APIs, rasterization |
44
+ | `@nodetool-ai/sandbox-pdflib` | pdf-lib | host | builds from class instances, not data |
45
+ | `@nodetool-ai/sandbox-pptxgen` | pptxgenjs | host | builds from class instances, not data |
46
+ | `@nodetool-ai/sandbox-pptx` | office-text-extractor | host | Node's own zip/XML stack |
47
+ | `@nodetool-ai/sandbox-pdf` | pdf-parse | host | pdf.js wants Node builtins and a canvas |
48
+ | `@nodetool-ai/sandbox-aws` | NodeTool's SigV4 signer | host | signing chain the guest has no library for |
49
+ | `@nodetool-ai/sandbox-notion` | NodeTool's Notion helper | host | first-party, so a pack cannot bring it |
50
+ | `@nodetool-ai/sandbox-supabase` | NodeTool's PostgREST helper | host | first-party |
51
+ | `@nodetool-ai/sandbox-twilio` | NodeTool's Twilio helper | host | first-party |
52
+
53
+ **Guest** means the M3 compiler bundles the library into the QuickJS guest and
54
+ the pack ships that manifest entry (`{"kind": "js", "npm": "…"}`). **Host**
55
+ means the library runs where the sandbox itself runs and the guest reaches it
56
+ through a generated ESM facade over a per-run dispatcher; the pack's manifest
57
+ entry is `{"kind": "host", "host": "<id>"}` and the implementation lives in
58
+ `packages/agents/src/host-modules/`.
59
+
60
+ An authored guest pack declares `{"kind": "js", "file": "sandbox/index.js"}`.
61
+ Discovery reads that file directly. The game builder uses this form and runs
62
+ inside QuickJS with the same module admission rules as other guest code.
63
+
64
+ ### The service packs build requests; they never send one
65
+
66
+ The last four packs replace the S3, Notion, Supabase and Twilio nodes.
67
+ They are not libraries: each is a pure function that turns a description of a
68
+ request into `{url, method, headers, body}`, or in `-aws`'s case into signed
69
+ headers. The guest passes that to its own `fetch`, so the run's fetch cap, its
70
+ SSRF guard and its body limit still apply — moving the header math to the host
71
+ must not move the network call with it.
72
+
73
+ They run through the host registry of NodeTool's service helpers. SigV4 uses
74
+ an HMAC-SHA256 chain over the canonical request, which the guest cannot
75
+ compute with its own globals.
76
+
77
+ ### Why zip is a host pack
78
+
79
+ fflate is pure JavaScript and the compiler admits it — it shipped as a guest
80
+ pack once. It does not now, because of `MAX_UNZIP_TOTAL_BYTES`. A zip bomb is a
81
+ policy question, and a policy enforced inside the guest is enforced by code the
82
+ guest can decline to call; the 64 MB guest heap does not replicate it either,
83
+ because fflate inflates into host memory first. The library therefore runs on
84
+ the host, where the cap sits between the archive and the guest with nothing
85
+ around it.
86
+
87
+ ## A pack cannot bring a host module
88
+
89
+ `kind: "host"` carries an **id**, never an implementation. Discovery admits the
90
+ entry only when the id is in `SANDBOX_HOST_MODULES`
91
+ (`packages/protocol/src/sandbox-host.ts`) *and* the declaring package is the one
92
+ that table pins to the id — so `@evil/x` declaring `{"host": "csv"}` is refused,
93
+ and an unknown id is refused outright. The per-run dispatcher repeats both
94
+ checks on every call, because the boundary is enforcement, not declaration.
95
+
96
+ Adding a host module is a NodeTool change: a row in the protocol table and an
97
+ implementation in `packages/agents/src/host-modules/registry.ts`. A third-party
98
+ pack cannot reach host execution through this path.
99
+
100
+ ## Not workspaces, on purpose
101
+
102
+ The root `workspaces` array names every workspace by path — there is no
103
+ `packages/*` glob — and these directories are deliberately absent from it. A
104
+ pack is consumed the way any third-party pack is: discovered from disk and
105
+ mounted into the guest by the loader. Nothing in the repo may
106
+ `import "@nodetool-ai/sandbox-yaml"` in host code, and leaving them out of the
107
+ workspace list is what makes that impossible rather than merely discouraged —
108
+ npm links no symlink into `node_modules`, so the specifier does not resolve for
109
+ the host at all.
110
+
111
+ The compiler still finds a guest pack's dependency in this tree: esbuild
112
+ resolves from the pack directory upward, and js-yaml and date-fns are hoisted to
113
+ the repo root by the workspaces that already depend on them. A host pack has no
114
+ dependency of its own at all — the library is a dependency of
115
+ `@nodetool-ai/agents`, where the implementation lives.
116
+
117
+ ## Shipped, not installed
118
+
119
+ Being outside `node_modules` once meant being absent: a checkout, the desktop
120
+ app and the server image all discovered zero of these packs, so every library
121
+ NodeTool documents failed a Code node with "Sandbox module … is not installed".
122
+ Discovery now reads this directory directly. `shippedPackSearchPaths()` in
123
+ `packages/node-sdk/src/pack-loader.ts` returns it — found by walking up from the
124
+ loader module in a checkout, and read from `_sandbox/` beside `server.mjs` in
125
+ the packaged app and the Docker image, where `scripts/bundle-backend.mjs` stages
126
+ every pack here (manifest, declared files, SKILL.md) and
127
+ `scripts/verify-backend-bundle.mjs` fails a build that misses one. Both are
128
+ scans, so a pack added to this directory ships with no list to update.
129
+ `NODETOOL_SHIPPED_PACKS_DIR` overrides the root for a host that stages them
130
+ elsewhere.
131
+
132
+ The shipped root comes last in the search order. A pack installed from npm
133
+ through the Package Manager therefore shadows the copy that ships with the app,
134
+ with no duplicate-pack diagnostic: that name has an owner, and it is the one the
135
+ user installed.
136
+
137
+ Availability is not new authority. These packs declare modules; they register no
138
+ nodes and run no code at load, so the pack allowlist that gates node packs has
139
+ nothing to gate here. A host module still resolves only through
140
+ `SANDBOX_HOST_MODULES`, a Code node still has to declare the specifier, and the
141
+ credentials the service packs use still come from `nodetool.secrets.get`,
142
+ narrowed to the names that node declares.
143
+
144
+ ## Registry metadata
145
+
146
+ The package index lives in the external `nodetool-ai/nodetool-registry`
147
+ repository, so nothing in this repo writes an index entry. What the index reads
148
+ is here, in each pack's package.json: `name`, `description`, the
149
+ `nodetool-sandbox-pack` keyword, `nodetool.sandboxModules` (the specifier
150
+ summary the design asks index entries to carry), and `nodetool.recommended`.
151
+ Discovery ignores every key but `apiVersion`, `sandboxModules`, and `internal`,
152
+ so the extra metadata costs the host nothing.
153
+
154
+ ## Adding a pack
155
+
156
+ **Guest pack.** Compile the candidate first — a pack for a library the compiler
157
+ skips is a pack nobody can import; `nodetool packs compile --json` reports the
158
+ named skip. Then write the package.json with `{"kind": "js", "npm": "<dep>"}`
159
+ and the dependency pinned to a range this tree already resolves.
160
+
161
+ **Authored guest pack.** Write browser-safe JavaScript and declare it with
162
+ `{"kind": "js", "file": "sandbox/index.js"}`. Mark its bridge table row
163
+ `source: "authored"` and test importing it in QuickJS through discovery and
164
+ the module catalog. It needs no npm compilation.
165
+
166
+ **Host pack.** Add the row to `SANDBOX_HOST_MODULES` and the loader to
167
+ `packages/agents/src/host-modules/registry.ts`, with the implementation beside
168
+ it and every limit inside it. Then write the package.json with
169
+ `{"kind": "host", "host": "<id>"}`.
170
+
171
+ Either way: a `SKILL.md` with the specifier, each export with one example
172
+ written for the guest, and the gotchas that bite there; a row in
173
+ `packages/node-sdk/src/sandbox-bridge-packs.ts` so an uninstalled specifier gets
174
+ an "Install …" hint; and the pack directory added to
175
+ `packages/sandbox-compiler/tests/packs.test.ts`, which discovers, compiles, and
176
+ runs every pack in this directory.
@@ -0,0 +1,98 @@
1
+ ---
2
+ name: sandbox-aws
3
+ description: Sign AWS requests (S3 and every other SigV4 service) in a Code node or CodeAct action, with NodeTool's signer running on the host
4
+ ---
5
+
6
+ # AWS SigV4 in the sandbox
7
+
8
+ Specifier: `@nodetool-ai/sandbox-aws`. Import it at the top of the body.
9
+
10
+ S3 is an HTTP API, so `fetch` already reaches it. What the guest cannot do is
11
+ sign the request: SigV4 is an HMAC-SHA256 chain over a canonical form of the
12
+ request, and one wrong byte gives a signature mismatch that names nothing.
13
+ This pack is a **host module**: the chain runs on the host and hands back
14
+ headers.
15
+
16
+ **Nothing here sends a request.** Both exports are pure — they take a request
17
+ and return a signed one. The call goes out through the guest's own `fetch`, so
18
+ the run's fetch cap and its SSRF guard still apply.
19
+
20
+ ## sigv4 — sign a request
21
+
22
+ ```js
23
+ import { sigv4 } from "@nodetool-ai/sandbox-aws";
24
+
25
+ const accessKeyId = await nodetool.secrets.get("AWS_ACCESS_KEY_ID");
26
+ const secretAccessKey = await nodetool.secrets.get("AWS_SECRET_ACCESS_KEY");
27
+
28
+ const signed = await sigv4({
29
+ method: "GET",
30
+ url: "https://my-bucket.s3.us-east-1.amazonaws.com/?list-type=2&max-keys=100",
31
+ region: "us-east-1",
32
+ service: "s3",
33
+ accessKeyId,
34
+ secretAccessKey
35
+ });
36
+
37
+ const res = await fetch(signed.url, { method: signed.method, headers: signed.headers });
38
+ return { xml: await res.text() };
39
+ ```
40
+
41
+ Options: `method` (default `GET`), `url` (required, absolute), `region`
42
+ (default `us-east-1`), `service` (default `s3`), `accessKeyId` and
43
+ `secretAccessKey` (required), `sessionToken` (for temporary STS credentials),
44
+ `headers`, `body`, `payloadHash`.
45
+
46
+ Returns `{url, method, headers}` — never the body. Pass the same body value to
47
+ `fetch` yourself, so bytes make one trip, not two.
48
+
49
+ ### Writing an object
50
+
51
+ ```js
52
+ const body = JSON.stringify(inputs.record);
53
+ const signed = await sigv4({
54
+ method: "PUT",
55
+ url: `https://my-bucket.s3.us-east-1.amazonaws.com/${inputs.key}`,
56
+ region: "us-east-1", service: "s3",
57
+ accessKeyId, secretAccessKey,
58
+ headers: { "content-type": "application/json" },
59
+ body
60
+ });
61
+ await fetch(signed.url, { method: "PUT", headers: signed.headers, body });
62
+ ```
63
+
64
+ A `Uint8Array` body works the same way — from `workspace.readBytes` or a
65
+ previous `response.bytes()`.
66
+
67
+ ## presign — a URL that authorizes itself
68
+
69
+ ```js
70
+ import { presign } from "@nodetool-ai/sandbox-aws";
71
+
72
+ const url = await presign({
73
+ method: "GET",
74
+ url: "https://my-bucket.s3.us-east-1.amazonaws.com/report.pdf",
75
+ region: "us-east-1", service: "s3",
76
+ expiresIn: 3600,
77
+ accessKeyId, secretAccessKey
78
+ });
79
+ return { url };
80
+ ```
81
+
82
+ Returns the URL as a string. `expiresIn` is seconds, clamped to a week. The
83
+ payload is unsigned, which is what makes a presigned `PUT` usable — whoever
84
+ holds the URL supplies the body.
85
+
86
+ ## Gotchas
87
+
88
+ - **Every export is async.** A host call is a round trip.
89
+ - **It signs; it does not send.** Nothing reaches the network until you call
90
+ `fetch`.
91
+ - **The signature is time-bound.** It is stamped when you call `sigv4`, and AWS
92
+ rejects one more than 15 minutes old. Sign immediately before fetching, not
93
+ at the top of a long function.
94
+ - **Other services work too.** Set `service` and `region` — `dynamodb`,
95
+ `sqs`, `lambda`, `bedrock`. Only `s3` skips path normalization, because an
96
+ object key is a key.
97
+ - **10 MB of body per signature.** Hash a bigger upload yourself and pass
98
+ `payloadHash`, or use a presigned `PUT`.
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@nodetool-ai/sandbox-aws",
3
+ "version": "0.8.4",
4
+ "description": "Sign AWS requests with Signature V4 inside the NodeTool sandbox, from NodeTool's signer running on the host",
5
+ "license": "MIT",
6
+ "nodetool": {
7
+ "apiVersion": 1,
8
+ "recommended": true,
9
+ "sandboxModules": [
10
+ {
11
+ "name": ".",
12
+ "kind": "host",
13
+ "host": "aws"
14
+ }
15
+ ]
16
+ },
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "https://github.com/nodetool-ai/nodetool.git",
20
+ "directory": "packages/sandbox-packs/sandbox-aws"
21
+ },
22
+ "homepage": "https://nodetool.ai",
23
+ "bugs": {
24
+ "url": "https://github.com/nodetool-ai/nodetool/issues"
25
+ },
26
+ "publishConfig": {
27
+ "access": "public"
28
+ },
29
+ "files": [
30
+ "SKILL.md"
31
+ ],
32
+ "keywords": [
33
+ "nodetool",
34
+ "nodetool-sandbox-pack",
35
+ "sandbox",
36
+ "aws",
37
+ "s3",
38
+ "sigv4"
39
+ ]
40
+ }
@@ -0,0 +1,39 @@
1
+ ---
2
+ name: sandbox-chrono
3
+ description: Parse English dates such as next Tuesday in a Code node or CodeAct action, with chrono-node running on the host
4
+ ---
5
+
6
+ # Natural-language dates in the sandbox
7
+
8
+ Specifier: `@nodetool-ai/sandbox-chrono`. Import it at the top of the body.
9
+
10
+ chrono-node does not compile into QuickJS, so this pack is a **host module**.
11
+ You pass text; you get ISO strings back.
12
+
13
+ ## parseDate — first match
14
+
15
+ ```js
16
+ import { parseDate } from "@nodetool-ai/sandbox-chrono";
17
+
18
+ const iso = await parseDate(inputs.text, inputs.now);
19
+ return { iso };
20
+ ```
21
+
22
+ `inputs.now` is an optional reference timestamp (ISO string or epoch ms).
23
+
24
+ ## parse — every match
25
+
26
+ ```js
27
+ import { parse } from "@nodetool-ai/sandbox-chrono";
28
+
29
+ const hits = await parse(inputs.text, inputs.now);
30
+ return { hits };
31
+ ```
32
+
33
+ Each hit is `{ text, start, end }` with ISO strings (`end` may be `null`).
34
+
35
+ ## Gotchas
36
+
37
+ - **Async host calls.** Always `await`.
38
+ - **UTC.** The guest still has no time-zone database.
39
+ - **Pair with `@nodetool-ai/sandbox-dates`** to format the Date you parse.
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@nodetool-ai/sandbox-chrono",
3
+ "version": "0.8.4",
4
+ "description": "Parse natural-language dates inside the NodeTool sandbox, from chrono-node",
5
+ "license": "MIT",
6
+ "nodetool": {
7
+ "apiVersion": 1,
8
+ "recommended": true,
9
+ "sandboxModules": [
10
+ {
11
+ "name": ".",
12
+ "kind": "host",
13
+ "host": "chrono"
14
+ }
15
+ ]
16
+ },
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "https://github.com/nodetool-ai/nodetool.git",
20
+ "directory": "packages/sandbox-packs/sandbox-chrono"
21
+ },
22
+ "homepage": "https://nodetool.ai",
23
+ "bugs": {
24
+ "url": "https://github.com/nodetool-ai/nodetool/issues"
25
+ },
26
+ "publishConfig": {
27
+ "access": "public"
28
+ },
29
+ "files": [
30
+ "SKILL.md"
31
+ ],
32
+ "keywords": [
33
+ "nodetool",
34
+ "nodetool-sandbox-pack",
35
+ "sandbox",
36
+ "chrono",
37
+ "date",
38
+ "nlp"
39
+ ]
40
+ }
@@ -0,0 +1,35 @@
1
+ ---
2
+ name: sandbox-color
3
+ description: Convert, mix, and measure colors inside a Code node or CodeAct action, with culori running in the guest
4
+ ---
5
+
6
+ # Color in the sandbox
7
+
8
+ Specifier: `@nodetool-ai/sandbox-color`. One module, culori's root export.
9
+ Import it at the top of the body.
10
+
11
+ ## Parse and convert
12
+
13
+ ```js
14
+ import { parse, formatHex, converter } from "@nodetool-ai/sandbox-color";
15
+
16
+ const color = parse(inputs.hex);
17
+ const rgb = converter("rgb")(color);
18
+ return { hex: formatHex(color), rgb };
19
+ ```
20
+
21
+ ## Mix and difference
22
+
23
+ ```js
24
+ import { interpolate, formatHex, differenceCiede2000 } from "@nodetool-ai/sandbox-color";
25
+
26
+ const mix = interpolate(["#2563eb", "#f97316"]);
27
+ const mid = formatHex(mix(0.5));
28
+ const delta = differenceCiede2000()("#2563eb", "#f97316");
29
+ return { mid, delta };
30
+ ```
31
+
32
+ ## Gotchas
33
+
34
+ - **Objects, not CSS strings, after parse.** A parsed color is `{ mode, ...channels }`.
35
+ - **Named imports.** There is no useful default export.
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@nodetool-ai/sandbox-color",
3
+ "version": "0.8.4",
4
+ "description": "Color conversion, mixing, and difference (deltaE) inside the NodeTool sandbox, from culori",
5
+ "license": "MIT",
6
+ "dependencies": {
7
+ "culori": "^4.0.2"
8
+ },
9
+ "nodetool": {
10
+ "apiVersion": 1,
11
+ "recommended": true,
12
+ "sandboxModules": [
13
+ {
14
+ "name": ".",
15
+ "kind": "js",
16
+ "npm": "culori"
17
+ }
18
+ ]
19
+ },
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "https://github.com/nodetool-ai/nodetool.git",
23
+ "directory": "packages/sandbox-packs/sandbox-color"
24
+ },
25
+ "homepage": "https://nodetool.ai",
26
+ "bugs": {
27
+ "url": "https://github.com/nodetool-ai/nodetool/issues"
28
+ },
29
+ "publishConfig": {
30
+ "access": "public"
31
+ },
32
+ "files": [
33
+ "SKILL.md"
34
+ ],
35
+ "keywords": [
36
+ "nodetool",
37
+ "nodetool-sandbox-pack",
38
+ "sandbox",
39
+ "color",
40
+ "culori",
41
+ "deltae"
42
+ ]
43
+ }
@@ -0,0 +1,50 @@
1
+ ---
2
+ name: sandbox-csv
3
+ description: Parse and write CSV in a Code node or CodeAct action, with papaparse running on the host behind a generated facade
4
+ ---
5
+
6
+ # CSV in the sandbox
7
+
8
+ Specifier: `@nodetool-ai/sandbox-csv`. Import it at the top of the body.
9
+
10
+ papaparse imports `node:stream`, so it cannot be compiled into the guest. This
11
+ pack is a **host module**: the import resolves to a generated facade whose two
12
+ exports call NodeTool's own implementation. Both are `async` — a host call is a
13
+ round trip.
14
+
15
+ ## parse — CSV text to records
16
+
17
+ ```js
18
+ import { parse } from "@nodetool-ai/sandbox-csv";
19
+
20
+ const rows = await parse(inputs.csv); // records keyed by the header row
21
+ const raw = await parse(inputs.csv, { header: false }); // string[][]
22
+ return { count: rows.length, first: rows[0] ?? null };
23
+ ```
24
+
25
+ Options: `header` (default `true`), `delimiter` (one character; omit to
26
+ auto-detect).
27
+
28
+ Values stay **strings**. There is no `dynamicTyping`, so a column never changes
29
+ shape between runs — convert what you need with `Number()` or `new Date()`.
30
+
31
+ ## stringify — records back to CSV
32
+
33
+ ```js
34
+ import { stringify } from "@nodetool-ai/sandbox-csv";
35
+
36
+ const csv = await stringify(inputs.rows, { delimiter: ";" });
37
+ return { csv };
38
+ ```
39
+
40
+ Takes records or row arrays. Options: `header` (default `true`), `delimiter`
41
+ (exactly one character).
42
+
43
+ ## Gotchas
44
+
45
+ - **Every export is async.** `parse(...)` without `await` gives you a Promise.
46
+ - **5 MB of text per call.** Input over that is refused by name. Split a bigger
47
+ file, or read it in slices with `workspace.read`.
48
+ - **Bounded concurrency still helps.** Host calls start when invoked, so
49
+ `Promise.all` over several `parse` calls runs them together; `parallelMap`
50
+ is the bounded form.
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@nodetool-ai/sandbox-csv",
3
+ "version": "0.8.4",
4
+ "description": "Parse and write CSV inside the NodeTool sandbox, from papaparse running on the host",
5
+ "license": "MIT",
6
+ "nodetool": {
7
+ "apiVersion": 1,
8
+ "recommended": true,
9
+ "sandboxModules": [
10
+ {
11
+ "name": ".",
12
+ "kind": "host",
13
+ "host": "csv"
14
+ }
15
+ ]
16
+ },
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "https://github.com/nodetool-ai/nodetool.git",
20
+ "directory": "packages/sandbox-packs/sandbox-csv"
21
+ },
22
+ "homepage": "https://nodetool.ai",
23
+ "bugs": {
24
+ "url": "https://github.com/nodetool-ai/nodetool/issues"
25
+ },
26
+ "publishConfig": {
27
+ "access": "public"
28
+ },
29
+ "files": [
30
+ "SKILL.md"
31
+ ],
32
+ "keywords": [
33
+ "nodetool",
34
+ "nodetool-sandbox-pack",
35
+ "sandbox",
36
+ "csv",
37
+ "parse"
38
+ ]
39
+ }
@@ -0,0 +1,47 @@
1
+ ---
2
+ name: sandbox-dates
3
+ description: Date arithmetic, parsing and formatting inside a Code node or CodeAct action, with date-fns running in the guest
4
+ ---
5
+
6
+ # Dates in the sandbox
7
+
8
+ Specifier: `@nodetool-ai/sandbox-dates`. One module, date-fns's root export —
9
+ around 250 named functions. There is no default export, so import the names you
10
+ use.
11
+
12
+ ## Arithmetic and comparison
13
+
14
+ ```js
15
+ import { addDays, differenceInCalendarDays, isBefore } from "@nodetool-ai/sandbox-dates";
16
+
17
+ const due = addDays(new Date(inputs.startedAt), 30);
18
+ return { due: due.toISOString(), overdue: isBefore(due, new Date()), days: differenceInCalendarDays(due, new Date()) };
19
+ ```
20
+
21
+ ## Parsing and formatting
22
+
23
+ ```js
24
+ import { parseISO, format, isValid } from "@nodetool-ai/sandbox-dates";
25
+
26
+ const when = parseISO(inputs.timestamp);
27
+ if (!isValid(when)) return { label: "unknown" };
28
+ return { label: format(when, "EEEE, d MMMM yyyy") };
29
+ ```
30
+
31
+ `format` uses date-fns's own English locale tables, not `Intl` — which the
32
+ guest does not have. That is why formatting works here at all, and it is also
33
+ the limit: another language means another locale, and locales live at
34
+ `date-fns/locale`, a subpath this pack does not publish.
35
+
36
+ ## Gotchas
37
+
38
+ - **UTC only.** The guest runs with no time-zone database, so `new Date()` and
39
+ every conversion behave as UTC. Anything zone-aware — "9 am in Berlin" —
40
+ belongs on the host, not here.
41
+ - **Named imports only.** `import dates from "@nodetool-ai/sandbox-dates"` gets
42
+ you nothing; date-fns is pure ESM with no default export.
43
+ - **Import what you use.** The bundle is about 176 KB and loads as one module
44
+ per invocation, so a node that needs one comparison pays for all of it. For a
45
+ single `Date` subtraction, plain arithmetic is cheaper.
46
+ - **No timers.** `setTimeout` does not exist in the guest. date-fns needs none,
47
+ but code around it must not either.
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "@nodetool-ai/sandbox-dates",
3
+ "version": "0.8.4",
4
+ "description": "Date arithmetic, parsing and formatting inside the NodeTool sandbox, from date-fns",
5
+ "license": "MIT",
6
+ "dependencies": {
7
+ "date-fns": "^4.4.0"
8
+ },
9
+ "nodetool": {
10
+ "apiVersion": 1,
11
+ "recommended": true,
12
+ "sandboxModules": [
13
+ {
14
+ "name": ".",
15
+ "kind": "js",
16
+ "npm": "date-fns"
17
+ }
18
+ ]
19
+ },
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "https://github.com/nodetool-ai/nodetool.git",
23
+ "directory": "packages/sandbox-packs/sandbox-dates"
24
+ },
25
+ "homepage": "https://nodetool.ai",
26
+ "bugs": {
27
+ "url": "https://github.com/nodetool-ai/nodetool/issues"
28
+ },
29
+ "publishConfig": {
30
+ "access": "public"
31
+ },
32
+ "files": [
33
+ "SKILL.md"
34
+ ],
35
+ "keywords": [
36
+ "nodetool",
37
+ "nodetool-sandbox-pack",
38
+ "sandbox",
39
+ "date"
40
+ ]
41
+ }