@nodetool-ai/node-sdk 0.8.4-a24.2 → 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.
- package/dist/.nodetool-build-stamp +1 -1
- package/dist/_sandbox/README.md +176 -0
- package/dist/_sandbox/sandbox-aws/SKILL.md +98 -0
- package/dist/_sandbox/sandbox-aws/package.json +40 -0
- package/dist/_sandbox/sandbox-chrono/SKILL.md +39 -0
- package/dist/_sandbox/sandbox-chrono/package.json +40 -0
- package/dist/_sandbox/sandbox-color/SKILL.md +35 -0
- package/dist/_sandbox/sandbox-color/package.json +43 -0
- package/dist/_sandbox/sandbox-csv/SKILL.md +50 -0
- package/dist/_sandbox/sandbox-csv/package.json +39 -0
- package/dist/_sandbox/sandbox-dates/SKILL.md +47 -0
- package/dist/_sandbox/sandbox-dates/package.json +41 -0
- package/dist/_sandbox/sandbox-decimal/SKILL.md +36 -0
- package/dist/_sandbox/sandbox-decimal/package.json +43 -0
- package/dist/_sandbox/sandbox-diff/SKILL.md +36 -0
- package/dist/_sandbox/sandbox-diff/package.json +39 -0
- package/dist/_sandbox/sandbox-docx/SKILL.md +53 -0
- package/dist/_sandbox/sandbox-docx/package.json +40 -0
- package/dist/_sandbox/sandbox-dsl/SKILL.md +137 -0
- package/dist/_sandbox/sandbox-dsl/package.json +413 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/authoring.js +382 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/core.js +382 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/gemini.audio.js +12 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/gemini.image.js +8 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/gemini.text.js +12 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/gemini.video.js +12 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/index.js +149 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/kie.dynamic_schema.js +8 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.audio.js +68 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.browser.js +8 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.charts.js +8 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.comfy.js +16 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.grid.js +8 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.image.channel.js +12 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.image.color.js +32 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.image.color_grading.js +44 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.image.draw.js +36 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.image.effects.js +24 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.image.enhance.js +28 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.image.filter.js +64 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.image.js +8 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.image.keyer.js +12 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.image.mask.js +16 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.image.warp.js +36 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.pdf.js +32 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.sqlite.js +8 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.stable_diffusion_cpp.js +8 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.svg.js +12 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/lib.video.download.js +8 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/messaging.discord.js +8 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/messaging.telegram.js +8 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/mistral.embeddings.js +8 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/mistral.text.js +12 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/mistral.vision.js +12 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.agents.js +32 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.audio.js +104 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.audio.realtime.js +28 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.audio.synth.js +40 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.blender.js +28 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.code.js +8 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.compare.js +8 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.constant.js +132 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.control.js +96 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.creative.js +24 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.data.js +12 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.document.js +16 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.entity.js +16 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.fake.js +12 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.game.js +36 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.generators.js +24 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.image.js +120 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.input.js +140 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.manimgx.js +16 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.model3d.js +76 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.output.js +8 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.script.js +28 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.sketch.js +16 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.storyboard.js +32 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.text.js +56 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.timeline.js +24 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.triggers.js +24 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.variable.js +12 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.video.js +136 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.workflows.app_node.js +8 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.workflows.base_node.js +8 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.workflows.subgraph.js +8 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/nodetool.workflows.workflow_node.js +8 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/openai.agents.js +16 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/openai.audio.js +16 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/openai.image.js +16 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/openai.text.js +16 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/vector.js +56 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/whisper_cpp.js +8 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/xai.image.js +8 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/xai.text.js +12 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/generated/xai.vision.js +8 -0
- package/dist/_sandbox/sandbox-dsl/sandbox/index.js +13 -0
- package/dist/_sandbox/sandbox-dsl/scripts/build.mjs +116 -0
- package/dist/_sandbox/sandbox-epub/SKILL.md +61 -0
- package/dist/_sandbox/sandbox-epub/package.json +40 -0
- package/dist/_sandbox/sandbox-exif/SKILL.md +30 -0
- package/dist/_sandbox/sandbox-exif/package.json +40 -0
- package/dist/_sandbox/sandbox-expr/SKILL.md +28 -0
- package/dist/_sandbox/sandbox-expr/package.json +40 -0
- package/dist/_sandbox/sandbox-fabric/SKILL.md +113 -0
- package/dist/_sandbox/sandbox-fabric/package.json +40 -0
- package/dist/_sandbox/sandbox-flow/SKILL.md +131 -0
- package/dist/_sandbox/sandbox-flow/package.json +411 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/gemini.audio.js +12 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/gemini.image.js +8 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/gemini.text.js +12 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/gemini.video.js +12 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/kie.dynamic_schema.js +8 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.audio.js +68 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.browser.js +8 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.charts.js +8 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.comfy.js +25 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.grid.js +8 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.image.channel.js +12 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.image.color.js +32 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.image.color_grading.js +44 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.image.draw.js +36 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.image.effects.js +24 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.image.enhance.js +28 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.image.filter.js +64 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.image.js +8 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.image.keyer.js +12 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.image.mask.js +16 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.image.warp.js +36 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.pdf.js +32 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.sqlite.js +8 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.stable_diffusion_cpp.js +8 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.svg.js +12 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/lib.video.download.js +8 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/messaging.discord.js +11 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/messaging.telegram.js +11 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/mistral.embeddings.js +8 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/mistral.text.js +12 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/mistral.vision.js +12 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.agents.js +41 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.audio.js +110 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.audio.realtime.js +46 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.audio.synth.js +67 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.blender.js +28 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.code.js +11 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.compare.js +8 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.constant.js +132 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.control.js +165 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.creative.js +27 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.data.js +18 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.document.js +19 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.entity.js +19 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.fake.js +12 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.game.js +39 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.generators.js +30 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.image.js +126 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.input.js +143 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.manimgx.js +16 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.model3d.js +76 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.output.js +11 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.script.js +28 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.sketch.js +16 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.storyboard.js +35 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.text.js +68 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.timeline.js +24 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.triggers.js +33 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.variable.js +15 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.video.js +145 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.workflows.app_node.js +11 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.workflows.base_node.js +8 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.workflows.subgraph.js +11 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/nodetool.workflows.workflow_node.js +11 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/openai.agents.js +25 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/openai.audio.js +16 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/openai.image.js +16 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/openai.text.js +16 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/vector.js +56 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/whisper_cpp.js +11 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/xai.image.js +8 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/xai.text.js +12 -0
- package/dist/_sandbox/sandbox-flow/sandbox/generated/xai.vision.js +8 -0
- package/dist/_sandbox/sandbox-flow/sandbox/guest-core.js +35 -0
- package/dist/_sandbox/sandbox-flow/sandbox/index.js +10 -0
- package/dist/_sandbox/sandbox-flow/scripts/build.mjs +120 -0
- package/dist/_sandbox/sandbox-game/SKILL.md +116 -0
- package/dist/_sandbox/sandbox-game/package.json +36 -0
- package/dist/_sandbox/sandbox-game/sandbox/index.js +208 -0
- package/dist/_sandbox/sandbox-gif/SKILL.md +36 -0
- package/dist/_sandbox/sandbox-gif/package.json +43 -0
- package/dist/_sandbox/sandbox-html/SKILL.md +107 -0
- package/dist/_sandbox/sandbox-html/package.json +40 -0
- package/dist/_sandbox/sandbox-ics/SKILL.md +41 -0
- package/dist/_sandbox/sandbox-ics/package.json +40 -0
- package/dist/_sandbox/sandbox-jmespath/SKILL.md +26 -0
- package/dist/_sandbox/sandbox-jmespath/package.json +43 -0
- package/dist/_sandbox/sandbox-mammoth/SKILL.md +46 -0
- package/dist/_sandbox/sandbox-mammoth/package.json +41 -0
- package/dist/_sandbox/sandbox-markdown/SKILL.md +123 -0
- package/dist/_sandbox/sandbox-markdown/package.json +41 -0
- package/dist/_sandbox/sandbox-notion/SKILL.md +101 -0
- package/dist/_sandbox/sandbox-notion/package.json +38 -0
- package/dist/_sandbox/sandbox-ocr/SKILL.md +47 -0
- package/dist/_sandbox/sandbox-ocr/package.json +40 -0
- package/dist/_sandbox/sandbox-pdf/SKILL.md +47 -0
- package/dist/_sandbox/sandbox-pdf/package.json +39 -0
- package/dist/_sandbox/sandbox-pdflib/SKILL.md +56 -0
- package/dist/_sandbox/sandbox-pdflib/package.json +38 -0
- package/dist/_sandbox/sandbox-pptx/SKILL.md +42 -0
- package/dist/_sandbox/sandbox-pptx/package.json +40 -0
- package/dist/_sandbox/sandbox-pptxgen/SKILL.md +49 -0
- package/dist/_sandbox/sandbox-pptxgen/package.json +38 -0
- package/dist/_sandbox/sandbox-qr/SKILL.md +43 -0
- package/dist/_sandbox/sandbox-qr/package.json +42 -0
- package/dist/_sandbox/sandbox-rrule/SKILL.md +37 -0
- package/dist/_sandbox/sandbox-rrule/package.json +43 -0
- package/dist/_sandbox/sandbox-stats/SKILL.md +42 -0
- package/dist/_sandbox/sandbox-stats/package.json +43 -0
- package/dist/_sandbox/sandbox-subtitle/SKILL.md +38 -0
- package/dist/_sandbox/sandbox-subtitle/package.json +41 -0
- package/dist/_sandbox/sandbox-supabase/SKILL.md +108 -0
- package/dist/_sandbox/sandbox-supabase/package.json +39 -0
- package/dist/_sandbox/sandbox-tfjs/SKILL.md +76 -0
- package/dist/_sandbox/sandbox-tfjs/package.json +42 -0
- package/dist/_sandbox/sandbox-timeline/SKILL.md +647 -0
- package/dist/_sandbox/sandbox-timeline/package.json +46 -0
- package/dist/_sandbox/sandbox-timeline/sandbox/charts.js +356 -0
- package/dist/_sandbox/sandbox-timeline/sandbox/components.js +171 -0
- package/dist/_sandbox/sandbox-timeline/sandbox/index.d.ts +700 -0
- package/dist/_sandbox/sandbox-timeline/sandbox/index.js +1658 -0
- package/dist/_sandbox/sandbox-tokens/SKILL.md +46 -0
- package/dist/_sandbox/sandbox-tokens/package.json +40 -0
- package/dist/_sandbox/sandbox-twilio/SKILL.md +93 -0
- package/dist/_sandbox/sandbox-twilio/package.json +39 -0
- package/dist/_sandbox/sandbox-xlsx/SKILL.md +74 -0
- package/dist/_sandbox/sandbox-xlsx/package.json +40 -0
- package/dist/_sandbox/sandbox-xml/SKILL.md +36 -0
- package/dist/_sandbox/sandbox-xml/package.json +40 -0
- package/dist/_sandbox/sandbox-yaml/SKILL.md +48 -0
- package/dist/_sandbox/sandbox-yaml/package.json +41 -0
- package/dist/_sandbox/sandbox-zip/SKILL.md +54 -0
- package/dist/_sandbox/sandbox-zip/package.json +40 -0
- package/dist/code-node-validation.d.ts +2 -0
- package/dist/code-node-validation.d.ts.map +1 -1
- package/dist/code-node-validation.js +1 -1
- package/dist/code-node-validation.js.map +1 -1
- package/dist/pack-loader.d.ts +1 -0
- package/dist/pack-loader.d.ts.map +1 -1
- package/dist/pack-loader.js +1 -0
- package/dist/pack-loader.js.map +1 -1
- package/dist/sandbox-catalog-host.js +1 -1
- package/dist/sandbox-catalog-host.js.map +1 -1
- package/dist/sandbox-pack-discovery.d.ts +3 -0
- package/dist/sandbox-pack-discovery.d.ts.map +1 -1
- package/dist/sandbox-pack-discovery.js +7 -3
- package/dist/sandbox-pack-discovery.js.map +1 -1
- package/package.json +5 -5
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/** Plain-document helpers for the native engine. Positions use world units. */
|
|
2
|
+
export function game(options = {}) {
|
|
3
|
+
const scenes = options.scenes ?? [{ id: "level", name: "Level", entities: [] }];
|
|
4
|
+
return {
|
|
5
|
+
...options,
|
|
6
|
+
schemaVersion: options.schemaVersion ?? 2,
|
|
7
|
+
engineVersion: "1",
|
|
8
|
+
id: options.id ?? "game",
|
|
9
|
+
revision: options.revision ?? "draft",
|
|
10
|
+
entrySceneId: options.entrySceneId ?? scenes[0]?.id,
|
|
11
|
+
pixelsPerUnit: options.pixelsPerUnit ?? 32,
|
|
12
|
+
tickRate: 60,
|
|
13
|
+
inputActions: options.inputActions ?? ["left", "right", "up", "down", "space"],
|
|
14
|
+
assets: options.assets ?? {},
|
|
15
|
+
scenes
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function entity(id, x = 0, y = 0, options = {}) {
|
|
20
|
+
return {
|
|
21
|
+
...options,
|
|
22
|
+
id,
|
|
23
|
+
name: options.name ?? id,
|
|
24
|
+
templateOnly: options.templateOnly ?? false,
|
|
25
|
+
transform2d: { ...options.transform2d, x, y,
|
|
26
|
+
rotation: options.transform2d?.rotation ?? 0,
|
|
27
|
+
scaleX: options.transform2d?.scaleX ?? 1,
|
|
28
|
+
scaleY: options.transform2d?.scaleY ?? 1 },
|
|
29
|
+
behaviors: options.behaviors ?? []
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function script(source, options = {}) {
|
|
34
|
+
return { ...options, kind: "script", source: typeof source === "function" ? source.toString() : source,
|
|
35
|
+
maxCommands: options.maxCommands ?? 16, maxTickMs: options.maxTickMs ?? 8 };
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Bind installed assets. This does not install bytes or resolve asset IDs. */
|
|
39
|
+
export function registerAssets(document, bindings) {
|
|
40
|
+
for (const [slot, binding] of Object.entries(bindings)) {
|
|
41
|
+
const mediaKind = binding.mediaKind ?? "image";
|
|
42
|
+
document.assets[slot] = { ...binding, mediaKind,
|
|
43
|
+
...(mediaKind !== "image" ? { width: binding.width ?? 1, height: binding.height ?? 1 } : {}),
|
|
44
|
+
pivot: binding.pivot ?? { x: 0.5, y: 0.5 }, sampling: binding.sampling ?? "nearest" };
|
|
45
|
+
}
|
|
46
|
+
return document;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function positive(value, name) {
|
|
50
|
+
if (!Number.isFinite(value) || value <= 0) { throw new Error(`${name} must be positive and finite`); }
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function count(value, name) {
|
|
54
|
+
if (!Number.isSafeInteger(value) || value < 0) { throw new Error(`${name} must be a nonnegative integer`); }
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** Append a rectangular grid of tile centres, starting at (x, y). */
|
|
58
|
+
export function fill(tiles, x, y, cols, rows, options = {}) {
|
|
59
|
+
count(cols, "cols");
|
|
60
|
+
count(rows, "rows");
|
|
61
|
+
const { size = 1, width = size, height = size, ...tile } = options;
|
|
62
|
+
positive(width, "width");
|
|
63
|
+
positive(height, "height");
|
|
64
|
+
for (let row = 0; row < rows; row += 1) {
|
|
65
|
+
for (let col = 0; col < cols; col += 1) {
|
|
66
|
+
tiles.push({ ...tile, x: x + col * width, y: y + row * height, width, height });
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return tiles;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** Append one row. Pass {oneWay: true} for a platform crossed from below. */
|
|
73
|
+
export function plank(tiles, x, y, cols, options = {}) {
|
|
74
|
+
return fill(tiles, x, y, cols, 1, options);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** Elliptical arc positions, inclusive of its endpoints. Angles are radians. */
|
|
78
|
+
export function arc(x, y, radiusX, radiusY, points, from = 0, to = Math.PI) {
|
|
79
|
+
count(points, "points");
|
|
80
|
+
return Array.from({ length: points }, (_, index) => {
|
|
81
|
+
const angle = from + (to - from) * (points > 1 ? index / (points - 1) : 0);
|
|
82
|
+
return { x: x + Math.cos(angle) * radiusX, y: y + Math.sin(angle) * radiusY };
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** Save a complete mutable draft. Publishing remains an explicit tool call. */
|
|
87
|
+
export async function saveGame(bundle, { games, project_id, game_id, base_updated_at } = {}) {
|
|
88
|
+
if (!games) { throw new Error("saveGame(bundle, {games: nodetool.games, project_id}) requires the game's tool bridge"); }
|
|
89
|
+
let id = game_id;
|
|
90
|
+
if (!id) {
|
|
91
|
+
if (!project_id || !bundle.name) { throw new Error("A new game requires name and project_id"); }
|
|
92
|
+
const created = await games.create(bundle.name, { project_id });
|
|
93
|
+
if (created.error || !created.game?.id) { throw new Error(`create_native_game: ${JSON.stringify(created)}`); }
|
|
94
|
+
id = created.game.id;
|
|
95
|
+
}
|
|
96
|
+
if (bundle.program) {
|
|
97
|
+
const preview = await games.previewAuthoring(id, { program: bundle.program, expected_document: bundle.document, base_updated_at });
|
|
98
|
+
if (preview.error || !preview.candidate) { throw new Error(`preview_native_game_authoring: ${JSON.stringify(preview)}`); }
|
|
99
|
+
const applied = await games.applyAuthoring(id, preview.candidate);
|
|
100
|
+
if (applied.error || !applied.game) { throw new Error(`apply_native_game_authoring: ${JSON.stringify(applied)}`); }
|
|
101
|
+
return { game_id: applied.game.id, revision: applied.game.revision, draft_updated_at: applied.draft_updated_at };
|
|
102
|
+
}
|
|
103
|
+
const saved = await games.edit(id, [{ op: "set_document", document: bundle.document }],
|
|
104
|
+
base_updated_at === undefined ? {} : { base_updated_at });
|
|
105
|
+
if (saved.error || !saved.document || !saved.game?.id) {
|
|
106
|
+
throw new Error(`edit_native_game: ${JSON.stringify(saved)}`);
|
|
107
|
+
}
|
|
108
|
+
return { game_id: saved.game.id, revision: saved.game.revision, draft_updated_at: saved.draft_updated_at };
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** Explicit retained function body. All preparation results belong in inputs. */
|
|
112
|
+
export function constructGame(program, build) {
|
|
113
|
+
if (!program || typeof build !== "function" || !Number.isSafeInteger(program.seed)) {
|
|
114
|
+
throw new Error("A retained game needs source and an integer authoring seed");
|
|
115
|
+
}
|
|
116
|
+
const retainedInputs = JSON.parse(JSON.stringify(program.inputs ?? {}));
|
|
117
|
+
const inputs = JSON.parse(JSON.stringify(retainedInputs));
|
|
118
|
+
let state = program.seed >>> 0;
|
|
119
|
+
const definitions = new Map();
|
|
120
|
+
const parameters = {};
|
|
121
|
+
const instances = [];
|
|
122
|
+
const sceneKeys = new Map();
|
|
123
|
+
const builder = {
|
|
124
|
+
game, entity, script, registerAssets, fill, plank, arc,
|
|
125
|
+
random() {
|
|
126
|
+
state = (Math.imul(state, 1664525) + 1013904223) >>> 0;
|
|
127
|
+
return state / 4294967296;
|
|
128
|
+
},
|
|
129
|
+
parameter(name, spec) {
|
|
130
|
+
if (["__proto__", "prototype", "constructor"].includes(name)) { throw new Error(`Unsafe parameter key ${name}`); }
|
|
131
|
+
if (Object.hasOwn(parameters, name)) { throw new Error(`Duplicate parameter ${name}`); }
|
|
132
|
+
parameters[name] = JSON.parse(JSON.stringify(spec));
|
|
133
|
+
const value = inputs[name] ?? spec.default;
|
|
134
|
+
if (spec.type === "number" && (typeof value !== "number" || !Number.isFinite(value) ||
|
|
135
|
+
(spec.min !== undefined && value < spec.min) || (spec.max !== undefined && value > spec.max))) {
|
|
136
|
+
throw new Error(`Invalid number parameter ${name}`);
|
|
137
|
+
}
|
|
138
|
+
if ((spec.type === "string" || spec.type === "boolean") && typeof value !== spec.type) {
|
|
139
|
+
throw new Error(`Invalid ${spec.type} parameter ${name}`);
|
|
140
|
+
}
|
|
141
|
+
if (spec.type === "enum" && (!Array.isArray(spec.values) || !spec.values.includes(value))) { throw new Error(`Invalid enum parameter ${name}`); }
|
|
142
|
+
if ((spec.type === "vector2" || spec.type === "vector3") && (!Array.isArray(value) ||
|
|
143
|
+
value.length !== (spec.type === "vector2" ? 2 : 3) || value.some((part) => typeof part !== "number" || !Number.isFinite(part)))) {
|
|
144
|
+
throw new Error(`Invalid vector parameter ${name}`);
|
|
145
|
+
}
|
|
146
|
+
if (!["number", "string", "boolean", "enum", "vector2", "vector3"].includes(spec.type)) { throw new Error(`Unknown parameter type ${spec.type}`); }
|
|
147
|
+
return value;
|
|
148
|
+
},
|
|
149
|
+
prefab(key, definition) {
|
|
150
|
+
if (typeof key !== "string" || !key || definitions.has(key)) { throw new Error(`Duplicate or empty prefab key ${key}`); }
|
|
151
|
+
definitions.set(key, mergeConstructionProperties({}, definition));
|
|
152
|
+
return key;
|
|
153
|
+
},
|
|
154
|
+
instance(scene, key, prefab, overrides = {}) {
|
|
155
|
+
let keys = sceneKeys.get(scene);
|
|
156
|
+
if (!keys) { keys = new Set(scene.entities.map((item) => item.id)); sceneKeys.set(scene, keys); }
|
|
157
|
+
if (typeof key !== "string" || !key || keys.has(key)) {
|
|
158
|
+
throw new Error(`Duplicate or empty instance key ${key}`);
|
|
159
|
+
}
|
|
160
|
+
const definition = definitions.get(prefab);
|
|
161
|
+
if (!definition) { throw new Error(`Unknown prefab ${prefab}`); }
|
|
162
|
+
const instance = { ...mergeConstructionProperties(definition, overrides), id: key };
|
|
163
|
+
scene.entities.push(instance);
|
|
164
|
+
keys.add(key);
|
|
165
|
+
instances.push({ sceneId: scene.id, entityId: key, prefabId: prefab });
|
|
166
|
+
return instance;
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
const document = build(inputs, builder);
|
|
170
|
+
if (!document || typeof document !== "object" || !Array.isArray(document.scenes)) {
|
|
171
|
+
throw new Error("Retained construction must return a native document");
|
|
172
|
+
}
|
|
173
|
+
const scenes = new Set();
|
|
174
|
+
const entities = new Set();
|
|
175
|
+
for (const scene of document.scenes) {
|
|
176
|
+
if (typeof scene.id !== "string" || !scene.id || scenes.has(scene.id)) { throw new Error(`Duplicate or empty scene key ${scene.id}`); }
|
|
177
|
+
scenes.add(scene.id);
|
|
178
|
+
for (const item of scene.entities) {
|
|
179
|
+
if (typeof item.id !== "string" || !item.id || entities.has(item.id)) { throw new Error(`Duplicate or empty entity key ${item.id}`); }
|
|
180
|
+
entities.add(item.id);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return { document, program: { source: program.source ?? `return (${build.toString()})(inputs, builder);`, inputs: retainedInputs, seed: program.seed },
|
|
184
|
+
parameters, prefabs: Object.fromEntries(definitions), instances };
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/** Component fields inherit independently. Arrays are replaced as one value. */
|
|
188
|
+
function mergeConstructionProperties(base, override) {
|
|
189
|
+
const object = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
190
|
+
const checkKeys = (value) => {
|
|
191
|
+
if (value === null || typeof value !== "object") { return; }
|
|
192
|
+
for (const [key, item] of Object.entries(value)) {
|
|
193
|
+
if (["__proto__", "prototype", "constructor"].includes(key)) { throw new Error(`Unsafe construction property ${key}`); }
|
|
194
|
+
checkKeys(item);
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
checkKeys(base);
|
|
198
|
+
checkKeys(override);
|
|
199
|
+
const merge = (left, right) => {
|
|
200
|
+
if (!object(left) || !object(right)) { return JSON.parse(JSON.stringify(right)); }
|
|
201
|
+
const result = JSON.parse(JSON.stringify(left));
|
|
202
|
+
for (const [key, value] of Object.entries(right)) {
|
|
203
|
+
result[key] = object(result[key]) && object(value) ? merge(result[key], value) : JSON.parse(JSON.stringify(value));
|
|
204
|
+
}
|
|
205
|
+
return result;
|
|
206
|
+
};
|
|
207
|
+
return merge(base, override);
|
|
208
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sandbox-gif
|
|
3
|
+
description: Encode an animated GIF from RGBA frames inside a Code node or CodeAct action, with gifenc running in the guest
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# GIF encoding in the sandbox
|
|
7
|
+
|
|
8
|
+
Specifier: `@nodetool-ai/sandbox-gif`. One module, gifenc. Import it at the top of the body.
|
|
9
|
+
|
|
10
|
+
## Frames to a GIF
|
|
11
|
+
|
|
12
|
+
```js
|
|
13
|
+
import { GIFEncoder, quantize, applyPalette } from "@nodetool-ai/sandbox-gif";
|
|
14
|
+
|
|
15
|
+
const gif = GIFEncoder();
|
|
16
|
+
for (const frame of inputs.frames) {
|
|
17
|
+
const palette = quantize(frame.rgba, 256);
|
|
18
|
+
const index = applyPalette(frame.rgba, palette);
|
|
19
|
+
gif.writeFrame(index, inputs.width, inputs.height, {
|
|
20
|
+
palette,
|
|
21
|
+
delay: frame.delay ?? 100
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
gif.finish();
|
|
25
|
+
return { bytes: gif.bytes() };
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Each `frame.rgba` is a `Uint8Array` of length `width * height * 4`.
|
|
29
|
+
`delay` is milliseconds.
|
|
30
|
+
|
|
31
|
+
## Gotchas
|
|
32
|
+
|
|
33
|
+
- **You supply RGBA.** Decode a still with `image.bytes` / canvas, then
|
|
34
|
+
pack frames yourself.
|
|
35
|
+
- **`gif.bytes()` is a `Uint8Array`.** Write it with
|
|
36
|
+
`workspace.writeBytes`.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nodetool-ai/sandbox-gif",
|
|
3
|
+
"version": "0.8.4",
|
|
4
|
+
"description": "Encode an animated GIF from RGBA frames inside the NodeTool sandbox, from gifenc",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"dependencies": {
|
|
7
|
+
"gifenc": "^1.0.3"
|
|
8
|
+
},
|
|
9
|
+
"nodetool": {
|
|
10
|
+
"apiVersion": 1,
|
|
11
|
+
"recommended": true,
|
|
12
|
+
"sandboxModules": [
|
|
13
|
+
{
|
|
14
|
+
"name": ".",
|
|
15
|
+
"kind": "js",
|
|
16
|
+
"npm": "gifenc"
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
},
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "https://github.com/nodetool-ai/nodetool.git",
|
|
23
|
+
"directory": "packages/sandbox-packs/sandbox-gif"
|
|
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
|
+
"gif",
|
|
40
|
+
"animation",
|
|
41
|
+
"encode"
|
|
42
|
+
]
|
|
43
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sandbox-html
|
|
3
|
+
description: Select elements out of HTML and convert a page to markdown in a Code node or CodeAct action, with cheerio and turndown running on the host
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# HTML in the sandbox
|
|
7
|
+
|
|
8
|
+
Specifier: `@nodetool-ai/sandbox-html`. Import it at the top of the body.
|
|
9
|
+
|
|
10
|
+
cheerio imports 25 Node builtins and turndown wants a DOM, so neither compiles
|
|
11
|
+
into the guest. This pack is a **host module**: the import resolves to a
|
|
12
|
+
generated facade over NodeTool's own implementation. Both exports are `async`.
|
|
13
|
+
|
|
14
|
+
## select — CSS selection
|
|
15
|
+
|
|
16
|
+
```js
|
|
17
|
+
import { select } from "@nodetool-ai/sandbox-html";
|
|
18
|
+
|
|
19
|
+
const hrefs = await select(inputs.html, "a[href]", { attr: "href", limit: 500 });
|
|
20
|
+
const titles = await select(inputs.html, "h2"); // trimmed text of each match
|
|
21
|
+
return { hrefs, titles };
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Returns trimmed text per match, or the named attribute when `attr` is set.
|
|
25
|
+
`limit` defaults to **100** and is clamped to **1000** — the cap is in the host
|
|
26
|
+
implementation, so raising it in the call does nothing.
|
|
27
|
+
|
|
28
|
+
## toMarkdown — a whole page
|
|
29
|
+
|
|
30
|
+
```js
|
|
31
|
+
import { toMarkdown } from "@nodetool-ai/sandbox-html";
|
|
32
|
+
|
|
33
|
+
const markdown = await toMarkdown(inputs.html);
|
|
34
|
+
return { markdown };
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The usual first step before summarizing or indexing a fetched page. Pass
|
|
38
|
+
`{ turndown: {...} }` to override turndown's own options.
|
|
39
|
+
|
|
40
|
+
## toText — a whole page as plain text
|
|
41
|
+
|
|
42
|
+
```js
|
|
43
|
+
import { toText } from "@nodetool-ai/sandbox-html";
|
|
44
|
+
|
|
45
|
+
const text = await toText(inputs.html);
|
|
46
|
+
return { text };
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Strips `<script>`/`<style>` and every tag, then collapses whitespace.
|
|
50
|
+
|
|
51
|
+
## extractLinks / extractImages / extractAudio / extractVideos
|
|
52
|
+
|
|
53
|
+
```js
|
|
54
|
+
import {
|
|
55
|
+
extractLinks,
|
|
56
|
+
extractImages,
|
|
57
|
+
extractAudio,
|
|
58
|
+
extractVideos
|
|
59
|
+
} from "@nodetool-ai/sandbox-html";
|
|
60
|
+
|
|
61
|
+
const links = await extractLinks(inputs.html, inputs.baseUrl);
|
|
62
|
+
// [{ href, text, type: "internal" | "external" }, ...]
|
|
63
|
+
|
|
64
|
+
const images = await extractImages(inputs.html, inputs.baseUrl); // string[] of resolved URLs
|
|
65
|
+
const audio = await extractAudio(inputs.html, inputs.baseUrl);
|
|
66
|
+
const videos = await extractVideos(inputs.html, inputs.baseUrl);
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
`baseUrl` is optional. When set, relative `src`/`href` values resolve against
|
|
70
|
+
it and `extractLinks` classifies same-origin links as `internal`. Each
|
|
71
|
+
extractor returns at most 1000 items.
|
|
72
|
+
|
|
73
|
+
## extractMetadata — title, description, keywords
|
|
74
|
+
|
|
75
|
+
```js
|
|
76
|
+
import { extractMetadata } from "@nodetool-ai/sandbox-html";
|
|
77
|
+
|
|
78
|
+
const { title, description, keywords } = await extractMetadata(inputs.html);
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Any field the page doesn't set comes back `null`.
|
|
82
|
+
|
|
83
|
+
## extractReadableText — strip chrome, keep the article
|
|
84
|
+
|
|
85
|
+
```js
|
|
86
|
+
import { extractReadableText } from "@nodetool-ai/sandbox-html";
|
|
87
|
+
|
|
88
|
+
const article = await extractReadableText(inputs.html);
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Removes `script`/`style`/`nav`/`aside`/`footer`/`header`, then returns the
|
|
92
|
+
text of the first match among `article`, `main`, `[id*=content]`,
|
|
93
|
+
`[class*=content]`, or `body`. A page with none of those returns
|
|
94
|
+
`"No main content found"`.
|
|
95
|
+
|
|
96
|
+
## Getting a page's base URL
|
|
97
|
+
|
|
98
|
+
No import needed — `new URL(pageUrl).origin` gives the base URL to pass into
|
|
99
|
+
the extractors above.
|
|
100
|
+
|
|
101
|
+
## Gotchas
|
|
102
|
+
|
|
103
|
+
- **Every export is async.**
|
|
104
|
+
- **5 MB of HTML per call.** Larger input is refused by name.
|
|
105
|
+
- **A selector that matches nothing returns `[]`**, never `null`. An invalid
|
|
106
|
+
selector throws with cheerio's own message.
|
|
107
|
+
- **Extractors cap at 1000 items.** Anything past that is silently dropped.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nodetool-ai/sandbox-html",
|
|
3
|
+
"version": "0.8.4",
|
|
4
|
+
"description": "CSS selection, HTML-to-markdown/text, and link/media/metadata extraction inside the NodeTool sandbox, from cheerio and turndown 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": "html"
|
|
14
|
+
}
|
|
15
|
+
]
|
|
16
|
+
},
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "https://github.com/nodetool-ai/nodetool.git",
|
|
20
|
+
"directory": "packages/sandbox-packs/sandbox-html"
|
|
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
|
+
"html",
|
|
37
|
+
"scraping",
|
|
38
|
+
"markdown"
|
|
39
|
+
]
|
|
40
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sandbox-ics
|
|
3
|
+
description: Build .ics calendar files in a Code node or CodeAct action, with ics running on the host
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# iCalendar in the sandbox
|
|
7
|
+
|
|
8
|
+
Specifier: `@nodetool-ai/sandbox-ics`. Import it at the top of the body.
|
|
9
|
+
|
|
10
|
+
The published ics bundle does not compile into QuickJS, so this pack is a
|
|
11
|
+
**host module**.
|
|
12
|
+
|
|
13
|
+
## createEvent — one event
|
|
14
|
+
|
|
15
|
+
```js
|
|
16
|
+
import { createEvent } from "@nodetool-ai/sandbox-ics";
|
|
17
|
+
|
|
18
|
+
const ics = await createEvent({
|
|
19
|
+
title: inputs.title,
|
|
20
|
+
start: inputs.start,
|
|
21
|
+
duration: { hours: 1 },
|
|
22
|
+
location: inputs.location
|
|
23
|
+
});
|
|
24
|
+
return { ics };
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
`start` is `[year, month, day, hour, minute]`, e.g. `[2026, 8, 15, 10, 0]`.
|
|
28
|
+
|
|
29
|
+
## createEvents — many
|
|
30
|
+
|
|
31
|
+
```js
|
|
32
|
+
import { createEvents } from "@nodetool-ai/sandbox-ics";
|
|
33
|
+
|
|
34
|
+
const ics = await createEvents(inputs.events);
|
|
35
|
+
return { ics };
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Gotchas
|
|
39
|
+
|
|
40
|
+
- **Throws on a bad event.** The host unwraps ics's `{ error, value }` bag.
|
|
41
|
+
- **Pair with `@nodetool-ai/sandbox-rrule`** to expand a series first.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nodetool-ai/sandbox-ics",
|
|
3
|
+
"version": "0.8.4",
|
|
4
|
+
"description": "Build iCalendar (.ics) files inside the NodeTool sandbox",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"nodetool": {
|
|
7
|
+
"apiVersion": 1,
|
|
8
|
+
"recommended": true,
|
|
9
|
+
"sandboxModules": [
|
|
10
|
+
{
|
|
11
|
+
"name": ".",
|
|
12
|
+
"kind": "host",
|
|
13
|
+
"host": "ics"
|
|
14
|
+
}
|
|
15
|
+
]
|
|
16
|
+
},
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "https://github.com/nodetool-ai/nodetool.git",
|
|
20
|
+
"directory": "packages/sandbox-packs/sandbox-ics"
|
|
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
|
+
"ics",
|
|
37
|
+
"ical",
|
|
38
|
+
"calendar"
|
|
39
|
+
]
|
|
40
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sandbox-jmespath
|
|
3
|
+
description: Query a JSON document with JMESPath inside a Code node or CodeAct action
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# JMESPath in the sandbox
|
|
7
|
+
|
|
8
|
+
Specifier: `@nodetool-ai/sandbox-jmespath`. One module, the `jmespath`
|
|
9
|
+
root export. Import it at the top of the body.
|
|
10
|
+
|
|
11
|
+
## search — pick values out of JSON
|
|
12
|
+
|
|
13
|
+
```js
|
|
14
|
+
import jmespath from "@nodetool-ai/sandbox-jmespath";
|
|
15
|
+
|
|
16
|
+
const names = jmespath.search(inputs.data, "items[*].name");
|
|
17
|
+
const total = jmespath.search(inputs.data, "sum(items[*].amount)");
|
|
18
|
+
return { names, total };
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Gotchas
|
|
22
|
+
|
|
23
|
+
- **Default export.** `import jmespath from "@nodetool-ai/sandbox-jmespath"`.
|
|
24
|
+
- **Missing paths return `null`**, they do not throw.
|
|
25
|
+
- **The expression is a string.** Build it carefully; do not interpolate
|
|
26
|
+
untrusted input into it.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nodetool-ai/sandbox-jmespath",
|
|
3
|
+
"version": "0.8.4",
|
|
4
|
+
"description": "Query JSON with JMESPath inside the NodeTool sandbox",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"dependencies": {
|
|
7
|
+
"jmespath": "^0.16.0"
|
|
8
|
+
},
|
|
9
|
+
"nodetool": {
|
|
10
|
+
"apiVersion": 1,
|
|
11
|
+
"recommended": true,
|
|
12
|
+
"sandboxModules": [
|
|
13
|
+
{
|
|
14
|
+
"name": ".",
|
|
15
|
+
"kind": "js",
|
|
16
|
+
"npm": "jmespath"
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
},
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "https://github.com/nodetool-ai/nodetool.git",
|
|
23
|
+
"directory": "packages/sandbox-packs/sandbox-jmespath"
|
|
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
|
+
"jmespath",
|
|
40
|
+
"json",
|
|
41
|
+
"query"
|
|
42
|
+
]
|
|
43
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sandbox-mammoth
|
|
3
|
+
description: Read a Word document as text or HTML in a Code node or CodeAct action, with mammoth running on the host
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Word documents in the sandbox (reading)
|
|
7
|
+
|
|
8
|
+
Specifier: `@nodetool-ai/sandbox-mammoth`. Import it at the top of the body.
|
|
9
|
+
|
|
10
|
+
mammoth reads a `.docx` buffer through Node's own zip/XML stack; it will never
|
|
11
|
+
be a guest module. This pack is a **host module**: the import resolves to a
|
|
12
|
+
generated facade over NodeTool's own implementation.
|
|
13
|
+
|
|
14
|
+
## extractRawText — docx bytes to plain text
|
|
15
|
+
|
|
16
|
+
```js
|
|
17
|
+
import { extractRawText } from "@nodetool-ai/sandbox-mammoth";
|
|
18
|
+
|
|
19
|
+
const bytes = await workspace.readBytes("report.docx");
|
|
20
|
+
const text = await extractRawText(bytes);
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Formatting is discarded — this is the fast path when you only need the words.
|
|
24
|
+
|
|
25
|
+
## convertToHtml — docx bytes to HTML
|
|
26
|
+
|
|
27
|
+
```js
|
|
28
|
+
import { convertToHtml } from "@nodetool-ai/sandbox-mammoth";
|
|
29
|
+
|
|
30
|
+
const html = await convertToHtml(bytes);
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Headings, lists, tables, bold/italic runs, and embedded images (as base64 data
|
|
34
|
+
URIs) survive the conversion. Track changes, headers/footers, footnotes, and
|
|
35
|
+
exact visual layout do not — mammoth targets semantic HTML, not a pixel-exact
|
|
36
|
+
render.
|
|
37
|
+
|
|
38
|
+
Get the bytes from `workspace.readBytes`, or from a fetched body with
|
|
39
|
+
`await response.bytes()`.
|
|
40
|
+
|
|
41
|
+
## Gotchas
|
|
42
|
+
|
|
43
|
+
- **Both exports are async.**
|
|
44
|
+
- **10 MB per document.** Larger input is refused by name.
|
|
45
|
+
- **Reading only.** To build a `.docx`, use `@nodetool-ai/sandbox-docx`
|
|
46
|
+
instead.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nodetool-ai/sandbox-mammoth",
|
|
3
|
+
"version": "0.8.4",
|
|
4
|
+
"description": "Read Word documents inside the NodeTool sandbox, from mammoth 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": "mammoth"
|
|
14
|
+
}
|
|
15
|
+
]
|
|
16
|
+
},
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "https://github.com/nodetool-ai/nodetool.git",
|
|
20
|
+
"directory": "packages/sandbox-packs/sandbox-mammoth"
|
|
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
|
+
"mammoth",
|
|
37
|
+
"docx",
|
|
38
|
+
"word",
|
|
39
|
+
"document"
|
|
40
|
+
]
|
|
41
|
+
}
|