tldraw-offline
Operate the user's tldraw offline canvas app, including open .tldraw or .tldr files.
Skill by kwanpham2195
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/kwanpham2195-tldraw-offline
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: design, writing, productivity
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/tldraw-offline
What's inside
- Skill name
tldraw-offline- Description
- Operate the user's tldraw offline canvas app, including open .tldraw or .tldr files. Use whenever a task involves inspecting, editing, arranging, connecting, linting, or scripting a tldraw Desktop canvas.
- License
- MIT
- Instructions
- 226 lines in SKILL.md · view on GitHub
Before installing
- Instructions call the network
Files (1)
- SKILL.md
SKILL.md (first lines)
<!-- installed-by:tldraw-desktop-agent-skills -->
# tldraw canvas operator
Use this skill for tasks involving open tldraw Desktop files. The desktop app exposes a local HTTP server that can list documents, inspect canvas state, capture screenshots, execute JavaScript against a live editor, and expose live script files for durable behavior.
## Server
The default server is `http://localhost:7236`. If that port is not active, read the `port` from `$HOME/Library/Application Support/tldraw/server.json`.
A clean quit removes `server.json`; the next launch rewrites it. It also records `pid` and `startedAt`, so if the file is present but requests to its `port` fail, treat it as stale (the app quit uncleanly) — the app is not running.
Every request except `GET /` and `/readme` needs the per-launch `token` from that same `server.json`, sent as `-H "authorization: Bearer <token>"`.
**If the server's base URL and bearer token are already in your context** — the app injects them at subagent launch when its agent hook is installed — use those literal values directly, or just call the installed `tq` helper (below). The rest of this section is the fallback for when neither is in hand.
**Each Bash tool call runs in a fresh shell — exported env vars do NOT persist between calls.** A `TLDRAW_TOKEN` you `export` in one call is empty in the next, so the request sends `authorization: Bearer` with no token and 401s. "Export once and reuse" does not work here — re-establish the port and token on every call. Read them together at the top of each call (both stay fixed for the app's lifetime, so re-reading is cheap):
```bash
PORT=$(jq -r .port "$HOME/Library/Application Support/tldraw/server.json"); TOKEN=$(jq -r .token "$HOME/Library/Application Support/tldraw/server.json")
# use as: http://localhost:$PORT/... -H "authorization: Bearer $TOKEN"
```
### Helper: `tq`
A ready-made helper ships with this skill at `"$HOME/skills/tldraw-offline/tq"`. Invoke it as `sh "$HOME/skills/tldraw-offline/tq" <METHOD> <path> [body]` — it re-reads the port and token from `server.json` itself on every call, so you never handle the token or the fresh-shell env problem. A body starting with `{` is sent as JSON; anything else as raw `text/plain`:
```bash
sh "$HOME/skills/tldraw-offline/tq" POST /api/search '{"code":"return await api.getDocs()"}'
sh "$HOME/skills/tldraw-offline/tq" POST /api/doc/DOC_ID/exec 'return editor.getCurrentPageShapes().length'
sh "$HOME/skills/tldraw-offline/tq" GET /api/doc/DOC_ID/script-status
```
If `tq` is missing (an older install), fall back to raw `curl` with the `PORT`/`TOKEN` reads shown above. The raw-`curl` examples below stay in explicit form so each request is visible; translate any to `sh "$HOME/skills/tldraw-offline/tq" <METHOD> <path> [body]`.
```bash
curl -s http://localhost:7236/readme
```
## Core endpoints
- `POST /api/search`: run JavaScript with an `api` object. Use this to discover docs, read shapes and bindings, capture screenshots, and query the editor API reference.
- `POST /api/docs/create`: create a new named `.tldraw` file, open it in a new window, and save it to disk. Use this when the task needs a fresh document rather than an already-open one.
- `POST /api/doc/:id/exec`: run JavaScript with a live tldraw `editor` scoped to one document. Use this for canvas edits.
- `POST /api/doc/:id/script-workspace`: expose a locally owned document's live script paths for direct durable board-script and asset edits.
- `GET /api/doc/:id/script-status`: inspect a locally owned document's watcher state for `script/**` edits and find `errorLogPath`.
The code-taking POST endpoints accept raw JavaScript as the request body (`content-type: text/plain`) or a JSON body `{"code": "..."}`, and wrap the code in an async function so top-level `await` works. Prefer raw bodies for shell use.
## Use this first
Most tasks do not require searching `api.members`. Start with these calls and search the full Editor API only if a snippet fails or you truly need an unknown method. The object is `api`, not `spec`. Each block below is shown as raw `curl` so the request is visible; `sh "$HOME/skills/tldraw-offline/tq" <METHOD> <path> [body]` is the shorter equivalent that handles the port and token for you.
```bash
# Fresh shell per call: re-read port + token first (or use the values already in your context).
PORT=$(jq -r .port "$HOME/Library/Application Support/tldraw/server.json"); TOKEN=$(jq -r .token "$HOME/Library/Application Support/tldraw/server.json")
# Pick the target doc by focused window or filename.
curl -s -X POST http://localhost:$PORT/api/search \
-H 'content-type: application/json' \
-H "authorization: Bearer $TOKEN" \
-d '{"code":"return await api.getDocs({ name: \"NAME\" })"}'
# Read the current page's shapes with ids, bounds, text, and metadata.
curl -s -X POST http://localhost:$PORT/api/search \
-H 'content-type: application/json' \
-H "authorization: Bearer $TOKEN" \
-d '{"code":"const doc = await api.getFocusedDoc(); const page = doc ? await api.getShapes(doc.id) : null; return { doc, shapes: page?.shapes.map(s => ({ id: s.id, type: s.type, x: s.x, y: s.y, props: s.props, meta: s.meta })) ?? [] }"}'
# Read bindings only for connection-dependent behavior.
curl -s -X POST http://localhost:$PORT/api/search \
-H 'content-type: application/json' \
-H "authorization: Bearer $TOKEN" \
-d '{"code":"const doc = await api.getFocusedDoc(); return doc ? await api.getBindings(doc.id) : []"}'
```
Every listed doc has `ownership: 'local' | 'remote' | 'server'`. A remote or server doc's `id` (opaque connection id for remote; the server's board id for server) works with `/exec`, `api.getShapes()`, `api.getBindings()`, and screenshots, but its `documentId`, `filePath`, and `unsavedChanges` are `null`: only the host (or server) owns those facts, and `host` carries the `host:port` it came from. Remote edits sync into the host working copy; server edits sync into the server's durable storage on their own. Do not call `helpers.saveDoc()`, open `/script-workspace`, or claim an archive was saved for a remote or server doc.
A local doc also reports `shared`. True means the board is shared right now and other people are editing it as you work: read before you write, and never clear a page you did not create.
## Scripts on a shared board
Writing or editing a board script for a board that is (or may become) shared changes what the script may do, because **every participant's editor runs the whole bundle** — `config.js` before it mounts, `main.js` after — and nothing elects a writer:
- Registration and rendering (`config.js` utils, view-only reactions) must run on every client, identically. A client that doesn't register a script-defined shape type renders an inert placeholder instead.
- Writes happen once per client unless guarded. Gate them on `ctx.app.board.isHost` — true in the editor that owns the file, false in one that joined — and keep continuous work (`tick` handlers, timers, simulations) behind the same guard. A never-shared board has one editor and it is the host, so the guard is correct offline too.
- Create with stable ids via `helpers.createShapeIfMissing` / `createShapesIfMissing`; never clear-and-redraw a page other people are on.
- Keep per-client state (hover, selection, "which card is flipped for me") in module scope, not in shape props — writing it to the document broadcasts one person's UI to everyone.
Read the `scripts-on-a-shared-board` recipe from `api.recipes` before writing one.
## Creating documents
When the task needs a fresh document (not one of the open canvases), `POST /api/docs/create` with a JSON body `{"name": "..."}` creates `<name>.tldraw`, opens it in a new window, and saves it to disk immediately. The name takes a `.tldraw` extension or none — never legacy `.tldr`, which the app opens but does not create. Optional `"directory"` is an absolute path to an existing folder; the default is the user's Documents folder. It never overwrites — an existing file with that name is a `409`. The response returns the new doc's `id`, `documentId`, `filePath`, `name`, and `windowId` — use that `id` directly with `/api/doc/:id/exec` and the `api.*` reads, no `api.getDocs()` re-discovery needed. Do not create the file yourself with filesystem tools.
```bash
curl -s -X POST http://localhost:$PORT/api/docs/create \
-H 'content-type: application/json' \
-H "authorization: Bearer $TOKEN" \
-d '{"name":"Project Plan"}'
```
## Reference recipes
`api.recipes` (via `/api/search`) is an object keyed by recipe `id`; read one in full with `api.recipes['<id>']`. Query it when a task matches one of the worked recipes:
- `stack-existing-boxes` — Stack existing boxes
- `group-shapes-with-a-box` — Group shapes with a box
- `add-durable-behavior-with-a-board-script` — Add durable behavior with a board script
- `editable-furniture-with-anchored-internals` — Editable furniture with anchored internals
- `scripts-on-a-shared-board` — Scripts on a shared board
- `clickable-card-or-button-ui` — Clickable card or button UI
- `connection-dependent-behavior` — Connection-dependent behavior
- `animation-simulation-loop` — Animation / simulation loop
- `custom-shape-config-js` — Custom shape (config.js)
- `custom-binding-config-js` — Custom binding (config.js)
- `custom-overlay-config-js` — Custom overlay (config.js)
Fetch `/readme` when an endpoint fails or you need API details not covered here.From kwanpham2195/agent-stuff, MIT.
More from kwanpham2195/agent-stuff
- 0.563score
obsidian-vault-config
kwanpham2195
Manage the shared Obsidian config at ~/.obsidian-shared that every vault symlinks into.
SkillBFreshness: B★ 2Claude Code +9 - 0.563score
product-description
kwanpham2195
Create or extend feature-by-feature product behavior documentation from source code, tests, and live verification.
SkillBFreshness: B★ 2Claude Code +9 - 0.563score
delegated-execution
kwanpham2195
Use when delegating work, coordinating subagents, or consulting an advisor on a consequential decision.
SkillBFreshness: B★ 2Claude Code +9 - 0.563score
pi-skill-creator
kwanpham2195
Create, test, and improve Agent Skills for pi and opencode.
SkillBFreshness: B★ 2Claude Code +9 - 0.563score
config-manager
kwanpham2195
Manage local machine configuration through chezmoi and global config files.
SkillBFreshness: B★ 2Claude Code +9 - 0.559score
create-verification-skill
kwanpham2195
Generate a project-local Pi verification skill that drives your app the way a user does — any language, framework, or platform.
SkillBFreshness: B★ 2Claude Code +9 - 0.558score
orbstack
kwanpham2195
Control OrbStack and Docker readiness on macOS.
SkillBFreshness: B★ 2Claude Code +9 - 0.557score
clean-copy
kwanpham2195
Reimplement the current branch on a new branch with a clean, narrative-quality git commit history.
SkillBFreshness: B★ 2Claude Code +9 - 0.557score
librarian
kwanpham2195
Cache and refresh remote Git repositories for local source reference.
SkillBFreshness: B★ 2Claude Code +9 - 0.557score
pr
kwanpham2195
Create or update a pull request for the current branch.
SkillBFreshness: B★ 2Claude Code +9 - 0.554score
define-outcome
kwanpham2195
Clarify product intent and observable acceptance for a feature or change when the desired outcome, scope, or success criteria are ambiguous.
SkillBFreshness: B★ 2Claude Code +9 - 0.554score
issue
kwanpham2195
Capture a user request or hand off scoped implementation work to a local workspace issue or an authorized configured remote tracker.
SkillBFreshness: B★ 2Claude Code +9
Signals
- Stars
- 2
- Forks
- 0
- Open issues
- 0
- Last commit (this folder)
- Sep 14, 2026 (1 month ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/kwanpham2195/agent-stuff
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from kwanpham2195
- 0.563score
delegated-execution
kwanpham2195
Use when delegating work, coordinating subagents, or consulting an advisor on a consequential decision.
SkillBFreshness: B★ 2Claude Code +9 - 0.563score
product-description
kwanpham2195
Create or extend feature-by-feature product behavior documentation from source code, tests, and live verification.
SkillBFreshness: B★ 2Claude Code +9 - 0.563score
config-manager
kwanpham2195
Manage local machine configuration through chezmoi and global config files.
SkillBFreshness: B★ 2Claude Code +9 - 0.563score
pi-skill-creator
kwanpham2195
Create, test, and improve Agent Skills for pi and opencode.
SkillBFreshness: B★ 2Claude Code +9 - 0.563score
obsidian-vault-config
kwanpham2195
Manage the shared Obsidian config at ~/.obsidian-shared that every vault symlinks into.
SkillBFreshness: B★ 2Claude Code +9 - 0.559score
create-verification-skill
kwanpham2195
Generate a project-local Pi verification skill that drives your app the way a user does — any language, framework, or platform.
SkillBFreshness: B★ 2Claude Code +9
Cite this page
tldraw-offline skill. Agent Mart. https://agentmart.dev/skills/kwanpham2195-tldraw-offline (last updated 2026-10-24)