Canvas is a small in-browser viewer with a programmable document model. It keeps blocks, inline text runs (with bold/italic), and inline object anchors stable so automated scripts or LLM agents can reason about and edit documents via a focused API.
- Node.js 18+ (recommended)
- npm (bundled with Node.js)
npm installnpm run dev— start Vite dev server with HMR.npm run build— type-check then build for production.npm run preview— preview the production build locally.
src/main.ts— document model, rendering layer, and Canvas API bootstrap.src/style.css— viewer styling and inline object visuals.public/— static assets served at the root (includesvite.svg).index.html— document shell that loadssrc/main.ts.
The app exposes a global window.canvasApi for scripting. Highlights:
addParagraph(kind, afterParagraphId)— insert aheading1|heading2|heading3|paragraphblock after a paragraph marker (use the knownDOCUMENT_END_MARKERto append without reading the document) and return its ID.deleteParagraph(id)— remove a paragraph block by ID.moveParagraph(id, afterParagraphId | DOCUMENT_END_MARKER)— reorder a paragraph after another or to the end.convertParagraphKind(id, kind)— change a paragraph kind; converting to a heading strips objects and formatting.addObject(object)— register an object (supportstype: 'box'andtype: 'mermaid') and returns its ID.removeObject(objectId)— delete an object and its anchor.getMarkdownFlow()— block-by-block markdown tokens with inline object anchors; styling is encoded as markdown; each block includes an inline{{paragraph:<id>}}marker.getMarkdownText()— full document markdown with{{object:ID}}markers and{{paragraph:<id>}}markers per paragraph (plus the{{paragraph:END_OF_DOCUMENT}}marker at the end).replaceParagraph(paragraphId, content)— replace an entire paragraph using structured inserts (text/object entries; no markdown in the input).getObjects()— metadata for registered objects.
Snapshot interop (kept separate from the core LLM API) lives in CanvasApiExt inside src/api-ext.ts:
exportSnapshot()/importSnapshot(snapshot)— roundtrip JSON representation of the document.
Default content is created at boot using the same API so you can inspect the structure immediately.