scripts/main.js
scripts/main.jsBrowse 4 files
794 tokens
2,949 bytes
Token encoding: o200k_base
Snapshot 24fd22b
← Back to SKILL.md
1// tldraw offline — document script (script/main.js)2//3// A document script's default export receives a ctx object and runs whenever the4// document loads (and reruns when you save the script). Contract, verified against5// the app's bundled script-context.d.ts:6//7// export default function ({ editor, helpers, signal }) { ... }8//9// editor — the live tldraw Editor for this document10// helpers — editor-bound conveniences: createShapeIfMissing, createShapesIfMissing,11// createArrowBetweenShapes, translateShapes, onShapeTranslate,12// richTextToPlainText, boxShapes, getLints13// signal — an AbortSignal fired before the script reruns and when the board14// closes. Register ALL cleanup on it (this is how you avoid leaks).15//16// Pure tldraw primitives (createShapeId, toRichText, Vec, ...) are imported from17// the `tldraw` app module — NOT globals. react / react-dom are also importable.18// It is not a Node project; only those modules are available.19 20import { createShapeId, toRichText } from 'tldraw'21 22export default function ({ editor, helpers, signal }) {23 const { createShapeIfMissing, createArrowBetweenShapes } = helpers24 25 // --- 1. Build durable "furniture" idempotently (stable ids, create-if-missing).26 // Re-running the script must NOT duplicate or clobber user edits.27 const nodes = [28 { id: createShapeId('node-ui'), x: 0, y: 0, color: 'blue', label: 'CLI / Gateway' },29 { id: createShapeId('node-core'), x: 280, y: 0, color: 'violet', label: 'Agent Core' },30 { id: createShapeId('node-tools'), x: 560, y: 0, color: 'green', label: 'Tools' },31 ]32 33 editor.run(() => {34 for (const n of nodes) {35 createShapeIfMissing({36 id: n.id,37 type: 'geo',38 x: n.x,39 y: n.y,40 props: {41 geo: 'rectangle',42 w: 220,43 h: 110,44 color: n.color,45 fill: 'solid',46 richText: toRichText(n.label),47 },48 })49 }50 })51 52 // Connect them (arrows bind to the shapes, so they follow when moved).53 createArrowBetweenShapes(nodes[0].id, nodes[1].id, { arrowheadEnd: 'arrow' })54 createArrowBetweenShapes(nodes[1].id, nodes[2].id, { arrowheadEnd: 'arrow' })55 56 // --- 2. Add reactive behavior: recolor the last node based on arrow count.57 // store.listen fires on the tick AFTER a commit — never read state you just58 // wrote synchronously and expect the listener to have run yet.59 const targetId = nodes[2].id60 function update() {61 const hasArrows = editor.getCurrentPageShapes().some((s) => s.type === 'arrow')62 editor.run(63 () =>64 editor.updateShape({65 id: targetId,66 type: 'geo',67 props: { fill: hasArrows ? 'solid' : 'none' },68 }),69 { history: 'ignore' } // keep script-owned writes out of the user's undo stack70 )71 }72 73 const stop = editor.store.listen(update)74 signal.addEventListener('abort', () => stop()) // <-- the one required cleanup75 update() // run once on load76 77 editor.zoomToFit({ animation: { duration: 200 } })78}79 Referenced from SKILL.md
SKILL.mdView in source ↗
Source excerpt starting at line 84.SKILL.mdView in source ↗84 -H "Authorization: Bearer $TOKEN" # -> result.mainJsPath, result.isDefaultScript85# edit result.mainJsPath with read_file / patch / write_file (see scripts/main.js)86# then confirm the watcher applied it:
Source excerpt starting at line 90.90The ready-to-adapt document script is `scripts/main.js`.