This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Agent Canvas — an interactive browser-based visual canvas for Claude Code. Users author JSX documents that get compiled and rendered in the browser with annotation, feedback, and file browsing capabilities.
Three components communicate via HTTP and WebSocket:
- CLI (
bin/agent-canvas.ts) — pushes JSX canvases to the daemon, waits for user feedback, manages daemon lifecycle - Daemon (
daemon/src/server.ts) — Bun HTTP+WS server on port 19400 (CANVAS_PORT). Compiles JSX, manages sessions, serves the browser UI - Browser UI (
daemon/client/) — React 18 app loaded via CDN UMD with ESM import maps. Handles annotations, revision history, feedback collection, file browsing
Data flow: CLI pushes JSX → daemon compiles via Bun.build() → browser loads compiled JS module → user annotates/responds → feedback sent back to CLI via WebSocket
Session model: Each canvas push creates/updates a session identified by CANVAS_SESSION_ID (set by hook). Sessions are stored on disk at ~/.claude/agent-canvas/sessions/{id}/ with a revision system (revisions/{rev}/plan.jsx, plan.compiled.js, feedback.md).
bun install
bun run build # builds client assets to daemon/dist/
bun daemon/build.ts --watch # watch mode with debounced rebuildThe build produces three bundles (runtime.js, components.js, client.js) plus Tailwind CSS. React is loaded from CDN, not bundled. Import maps route #canvas/components and #canvas/runtime to the local bundles.
bun run typecheck # runs tsc --noEmit on both root (bin/) and daemon (client/ + src/)Two separate tsconfig files: tsconfig.json (root, covers bin/) and daemon/tsconfig.json (covers daemon/src/ and daemon/client/). CI runs typecheck on every push and PR.
- Runtime is Bun only — no Node.js compatibility needed
- JSX compilation uses temp files because
Bun.build()doesn't supportstdin. Seedaemon/src/compiler.ts - Component imports are injected by the compiler — authored JSX can use
Section,Task,CodeBlock, etc. without imports - Adding a new component: create in
daemon/client/components/, export fromindex.ts, add toCOMPONENT_IMPORTSindaemon/src/compiler.ts, rebuild - Bun's
spawnthrows synchronously on missing executables — always check withwhichbefore spawning
A demo JSX file lives at example/plan.jsx in the project root. To test UI changes:
# 1. Start daemon (if not running)
bun bin/agent-canvas.ts daemon start
# 2. Build client assets (use --watch for live reload)
bun daemon/build.ts --watch
# 3. Push the demo plan
CANVAS_SESSION_ID=planner-demo bun bin/agent-canvas.ts push example/plan.jsx --label "Demo"
# 4. Open in browser
# http://localhost:19400/s/planner-demoThe CLI blocks waiting for feedback after push — press Ctrl+C to exit without submitting. Each push creates a new revision visible in the browser's revision selector.
To release a new version:
- Bump the version in
package.json - Commit the change and create a git tag:
git tag v<version> - Push both the commit and the tag:
git push && git push origin v<version>
The CI pipeline handles npm publish automatically when a new version tag is pushed. Do not run npm publish manually.
This package distributes a Claude Code skill in skills/canvas/. It teaches Claude Code how to use Agent Canvas — writing JSX canvases, pushing, waiting for feedback, iterating, and responding to user feedback. The skill is automatically available to users who install this package.
CANVAS_SESSION_ID— current session (set by SessionStart hook)CANVAS_PROJECT_ROOT— project directory for file servingCANVAS_PORT— daemon port (default: 19400)CANVAS_TIMEOUT— CLI feedback wait timeout (default: 1 hour)