[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M7AE4BK7S6RW766S1TYADP09":3,"skill-same:01M7AE4BK7S6RW766S1TYADP09":50},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":18,"linkOnly":19,"markdownContent":20,"markdownBody":21,"frontMatter":22,"refName":23,"commitSha":24,"skillDirectory":25,"forksCount":26,"repositoryHtmlUrl":27,"repositoryHomepageUrl":6,"ownerHtmlUrl":28,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":29,"install":30,"resources":43},"01M7AE4BK7S6RW766S1TYADP09","sandbox-docx",null,"Build a Word document in a Code node or CodeAct action, with docx running on the host","hanchenhao\u002Fai-canvas","hanchenhao","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F15713703?v=4","01M7ADWCF5AE30N3MG7MDF3RV2","01M7ADWCFVJS4V8VD9KWJG22WR",1,"AGPL-3.0","https:\u002F\u002Fgithub.com\u002Fhanchenhao\u002Fai-canvas\u002Fblob\u002Fmain\u002Fpackages\u002Fsandbox-packs\u002Fsandbox-docx\u002FSKILL.md",[],[],"2026-11-15 14:19:17",false,"---\nname: sandbox-docx\ndescription: Build a Word document in a Code node or CodeAct action, with docx running on the host\n---\n\n# Word documents in the sandbox\n\nSpecifier: `@nodetool-ai\u002Fsandbox-docx`. Declare it in the node's `packages`\nproperty and import it at the top of the body.\n\n`docx` builds a document out of class instances (`Paragraph`, `TextRun`,\n`Table`, …) that cannot cross the guest boundary as plain data. This pack is a\n**host module**: you describe the document as a JSON element list and the host\nbuilds the real `.docx` bytes.\n\n## build — element list to `.docx` bytes\n\n```js\nimport { build } from \"@nodetool-ai\u002Fsandbox-docx\";\n\nconst bytes = await build({\n  properties: { title: \"Q3 Report\", author: \"NodeTool\" },\n  elements: [\n    { type: \"heading\", text: \"Q3 Report\", level: 1 },\n    { type: \"paragraph\", text: \"Revenue grew 12% quarter over quarter.\", bold: true },\n    { type: \"table\", rows: [[\"Month\", \"Revenue\"], [\"Jul\", \"120k\"], [\"Aug\", \"134k\"]] },\n    { type: \"pageBreak\" },\n    { type: \"paragraph\", text: \"See appendix for methodology.\", alignment: \"CENTER\" }\n  ]\n});\nawait workspace.writeBytes(\"report.docx\", bytes);\n```\n\nElement types:\n\n- `heading` — `text`, `level` (1–6, default 1)\n- `paragraph` — `text`, `alignment` (`LEFT`\u002F`CENTER`\u002F`RIGHT`\u002F`JUSTIFY`, default\n  `LEFT`), `bold`, `italic`, `fontSize` (points, default 12)\n- `table` — `rows`, a 2D array; every cell is stringified\n- `image` — `data` (a `Uint8Array`), `width`\u002F`height` in inches\n- `pageBreak` — no fields\n\n`properties.title`\u002F`author`\u002F`subject`\u002F`keywords` set the document's metadata.\n\n## Gotchas\n\n- **`build` is async** and returns a `Uint8Array`.\n- **Writing only.** To read an existing `.docx`, use\n  `@nodetool-ai\u002Fsandbox-mammoth` instead — these are two different libraries on\n  two different sides of the format.\n- **Images are inches, not pixels.** `width`\u002F`height` follow docx's own\n  convention; omit them and the image renders at a fixed placeholder size.\n- **10 MB per image.** The shared host-module input cap applies to each\n  `data` field.\n","# Word documents in the sandbox\n\nSpecifier: `@nodetool-ai\u002Fsandbox-docx`. Declare it in the node's `packages`\nproperty and import it at the top of the body.\n\n`docx` builds a document out of class instances (`Paragraph`, `TextRun`,\n`Table`, …) that cannot cross the guest boundary as plain data. This pack is a\n**host module**: you describe the document as a JSON element list and the host\nbuilds the real `.docx` bytes.\n\n## build — element list to `.docx` bytes\n\n```js\nimport { build } from \"@nodetool-ai\u002Fsandbox-docx\";\n\nconst bytes = await build({\n  properties: { title: \"Q3 Report\", author: \"NodeTool\" },\n  elements: [\n    { type: \"heading\", text: \"Q3 Report\", level: 1 },\n    { type: \"paragraph\", text: \"Revenue grew 12% quarter over quarter.\", bold: true },\n    { type: \"table\", rows: [[\"Month\", \"Revenue\"], [\"Jul\", \"120k\"], [\"Aug\", \"134k\"]] },\n    { type: \"pageBreak\" },\n    { type: \"paragraph\", text: \"See appendix for methodology.\", alignment: \"CENTER\" }\n  ]\n});\nawait workspace.writeBytes(\"report.docx\", bytes);\n```\n\nElement types:\n\n- `heading` — `text`, `level` (1–6, default 1)\n- `paragraph` — `text`, `alignment` (`LEFT`\u002F`CENTER`\u002F`RIGHT`\u002F`JUSTIFY`, default\n  `LEFT`), `bold`, `italic`, `fontSize` (points, default 12)\n- `table` — `rows`, a 2D array; every cell is stringified\n- `image` — `data` (a `Uint8Array`), `width`\u002F`height` in inches\n- `pageBreak` — no fields\n\n`properties.title`\u002F`author`\u002F`subject`\u002F`keywords` set the document's metadata.\n\n## Gotchas\n\n- **`build` is async** and returns a `Uint8Array`.\n- **Writing only.** To read an existing `.docx`, use\n  `@nodetool-ai\u002Fsandbox-mammoth` instead — these are two different libraries on\n  two different sides of the format.\n- **Images are inches, not pixels.** `width`\u002F`height` follow docx's own\n  convention; omit them and the image renders at a fixed placeholder size.\n- **10 MB per image.** The shared host-module input cap applies to each\n  `data` field.\n",{"name":5,"description":7},"main","4ef72a828b24c99c49109033c7ec504c34f3bd17","packages\u002Fsandbox-packs\u002Fsandbox-docx",0,"https:\u002F\u002Fgithub.com\u002Fhanchenhao\u002Fai-canvas","https:\u002F\u002Fgithub.com\u002Fhanchenhao","2026-08-18 16:41:12",{"source":8,"skillName":5,"commands":31,"prompt":41,"zipAvailable":42},[32,35,38],{"tool":33,"command":34},"npx","npx skills add hanchenhao\u002Fai-canvas --skill sandbox-docx",{"tool":36,"command":37},"bunx","bunx skills add hanchenhao\u002Fai-canvas --skill sandbox-docx",{"tool":39,"command":40},"pnpm","pnpm dlx skills add hanchenhao\u002Fai-canvas --skill sandbox-docx","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fhanchenhao\u002Fai-canvas\u002Fblob\u002Fmain\u002Fpackages\u002Fsandbox-packs\u002Fsandbox-docx\u002FSKILL.md",true,[44],{"path":45,"resourceType":46,"resourceTypeDesc":47,"sizeBytes":48,"sourceHtmlUrl":49},"package.json","REFERENCE","参考文档",842,"https:\u002F\u002Fgithub.com\u002Fhanchenhao\u002Fai-canvas\u002Fblob\u002Fmain\u002Fpackages\u002Fsandbox-packs\u002Fsandbox-docx\u002Fpackage.json",[51,58,65,72,79,86],{"skillNo":52,"name":53,"nameZh":6,"description":54,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":55,"categories":56,"keywords":57,"publishedAt":18},"01M7AE5NP5AWGV47WS3F37VPZ1","sandbox-zip","Read and write zip archives in a Code node or CodeAct action, with fflate running on the host under a 50 MB inflation cap","https:\u002F\u002Fgithub.com\u002Fhanchenhao\u002Fai-canvas\u002Fblob\u002Fmain\u002Fpackages\u002Fsandbox-packs\u002Fsandbox-zip\u002FSKILL.md",[],[],{"skillNo":59,"name":60,"nameZh":6,"description":61,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":62,"categories":63,"keywords":64,"publishedAt":18},"01M7AE5JP0CG2S114Q246RC6MH","sandbox-yaml","Read and write YAML inside a Code node or CodeAct action, with js-yaml running in the guest","https:\u002F\u002Fgithub.com\u002Fhanchenhao\u002Fai-canvas\u002Fblob\u002Fmain\u002Fpackages\u002Fsandbox-packs\u002Fsandbox-yaml\u002FSKILL.md",[],[],{"skillNo":66,"name":67,"nameZh":6,"description":68,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":69,"categories":70,"keywords":71,"publishedAt":18},"01M7AE5GJ9AV36WM1DPW1878VM","sandbox-xml","Parse XML feeds and sitemaps in a Code node or CodeAct action, with fast-xml-parser running on the host","https:\u002F\u002Fgithub.com\u002Fhanchenhao\u002Fai-canvas\u002Fblob\u002Fmain\u002Fpackages\u002Fsandbox-packs\u002Fsandbox-xml\u002FSKILL.md",[],[],{"skillNo":73,"name":74,"nameZh":6,"description":75,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":76,"categories":77,"keywords":78,"publishedAt":18},"01M7AE5DMYDAGJW27G8KKTZ2BN","sandbox-xlsx","Read and write Excel workbooks in a Code node or CodeAct action, with exceljs running on the host","https:\u002F\u002Fgithub.com\u002Fhanchenhao\u002Fai-canvas\u002Fblob\u002Fmain\u002Fpackages\u002Fsandbox-packs\u002Fsandbox-xlsx\u002FSKILL.md",[],[],{"skillNo":80,"name":81,"nameZh":6,"description":82,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":83,"categories":84,"keywords":85,"publishedAt":18},"01M7AE5BARJSFCT296SEMYDSJQ","sandbox-twilio","Send SMS and WhatsApp messages and look up numbers from a Code node or CodeAct action, with NodeTool's Twilio request builder running on the host","https:\u002F\u002Fgithub.com\u002Fhanchenhao\u002Fai-canvas\u002Fblob\u002Fmain\u002Fpackages\u002Fsandbox-packs\u002Fsandbox-twilio\u002FSKILL.md",[],[],{"skillNo":87,"name":88,"nameZh":6,"description":89,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":90,"categories":91,"keywords":92,"publishedAt":18},"01M7AE57C5APRDF96NB3G0WQMW","sandbox-tfjs","Classify and embed images, detect objects, and answer from a passage in a Code node or CodeAct action, with TensorFlow.js running on the host","https:\u002F\u002Fgithub.com\u002Fhanchenhao\u002Fai-canvas\u002Fblob\u002Fmain\u002Fpackages\u002Fsandbox-packs\u002Fsandbox-tfjs\u002FSKILL.md",[],[]]