Commit Graph
160 Commits
Author SHA1 Message Date
newblaccandClaude Opus 4.6 15a5cfcc61 chore: add security tests and SECURITY.md (previously untracked)
- 9 backend security test files (auth, headers, rate-limit, middleware
  order, smoke, validation, WS auth, integration bootstrap)
- 1 e2e test (clear-preference)
- SECURITY.md policy doc

These files powered the 369-test suite but were never committed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 20:03:50 +02:00
newblaccandClaude Opus 4.6 9fb8ce34ec chore: rename project to excalidraw-mcp-sentinel
- Package name: @sanjibdevnath/mcp-excalidraw-local → excalidraw-mcp-sentinel
- GitHub repo: celstnblacc/mcp-excalidraw-local → celstnblacc/excalidraw-mcp-sentinel
- Docker images, CLI binary, CI workflows, docs all updated
- Version reset to 1.0.0 for independent release track
- Added "Why this fork?" section to README
- Removed superseded planning docs (PLAN.md, PLAN_v2.md, REVIEW.md, HANDOFF.md)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 20:00:27 +02:00
Maxime Roy (new.blacc)andGitHub 8f9fe3fa08 Merge pull request #2 from celstnblacc/feat/gauntlet-hardening
chore: add AGENTS.md and publish readiness checklist
2026-03-29 16:49:58 +02:00
newblaccandClaude Sonnet 4.6 f32a756434 chore: add AGENTS.md and publish readiness checklist to CLAUDE.md
- AGENTS.md: agent instructions covering commands, architecture, key
  constraints, security middleware map, env vars, testing rules, and
  pre-publish checklist
- CLAUDE.md: add Publish Readiness section with security posture summary
  and pre-publish checklist

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 16:36:32 +02:00
Maxime Roy (new.blacc)andGitHub 3a0dfea128 Merge pull request #1 from celstnblacc/feat/gauntlet-hardening
feat(security): harden canvas server with auth, rate-limiting, and validation
2026-03-29 16:18:27 +02:00
newblaccandClaude Sonnet 4.6 6c551f4cd0 fix(ci): update deprecated upload-artifact v3 SHA and missing docker/metadata-action SHA
- actions/upload-artifact: replace stale v3 SHA (pinned as v4.6.2) with @v4
- docker/metadata-action: replace non-existent SHA 902fa8ec7 with @v5

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 16:15:03 +02:00
newblaccandClaude Sonnet 4.6 5539235004 feat(security): harden canvas server with auth, rate-limiting, and validation
- Add security.ts: helmet, CORS allowlist, timing-safe API key auth, prototype
  pollution guard, Mermaid input limits, rate limiting (general/destructive/burst)
- WS auth challenge-response with 5 s timeout and close code 4001
- Fix sync crash: array check before logger access (500 → 400)
- Fix sync/v2: validate element type before write (invalid → 400)
- Upgrade zod 3.22.4 → 3.25.5 (fixes ERR_PACKAGE_PATH_NOT_EXPORTED on startup)
- Extract ElementSharedFieldsSchema; move VALID_ELEMENT_TYPES to module level
- Docker: resource limits, .dockerignore hardening
- Add .project-hooks/pre-commit; expand test coverage (369 tests)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 16:06:04 +02:00
sanjibdevnathlabs-release-bot[bot] a1977d86f9 chore(release): v1.6.2 v1.6.2 2026-03-18 04:39:37 +00:00
Sanjib DevnathandGitHub 2e743c1356 🐛 fix(sync): resolve delete persistence regression and harden data-safety invariants (#13)
Deletions made in the UI were silently lost on page reload because the sync
baseline (lastSyncedElementsRef) was never populated after initial load,
making the delta algorithm unable to detect removed elements. Additionally,
import_scene and restore_snapshot used a non-atomic clear+create pattern
that could permanently lose all canvas data if the batch create failed
after clearing, and duplicate_elements copied stale binding references
pointing to original element IDs instead of remapped duplicates.

🔧 Sync baseline restoration:
- Populate deletion-detection baseline on every server-to-client data path
  (page load, delta resync, hello handshake, initial elements broadcast)
- Establish sync version and hash baselines to prevent phantom re-syncs

🛡️ Data-loss prevention:
- Backup current scene before destructive clear in replace-mode operations
- Atomic restore from backup when subsequent batch create fails
- Remap all binding references (start/end IDs, boundElements, containerId)
  to new IDs during element duplication

 Comprehensive test coverage (154 new tests, 344 total):
- Delta sync flows including deletion persistence and bidirectional sync
- Multi-tenant element/sync/WebSocket isolation
- Arrow binding resolution across all shape types and edge cases
- MCP tool integration covering backup-restore and binding remapping
- Input validation and security boundary testing
- Frontend sync algorithm unit tests reproducing the exact regression

🎯 Eliminates the most critical data-integrity risks: deletions now
persist reliably, destructive operations are rollback-safe, and the
full test suite provides regression coverage for every sync path.
2026-03-18 10:07:07 +05:30
sanjibdevnathlabs-release-bot[bot] 459dbfdb3a chore(release): v1.6.1 v1.6.1 2026-03-18 03:00:11 +00:00
7c59972bb1 🐛 fix(mcp): resolve race conditions, sync failures, and preference regressions (#12)
Fix 6 bugs discovered during MCP tool usage:

1. syncToCanvas error handling: Distinguish network errors (return null)
   from API errors (re-throw with actual message). Fixes misleading
   "HTTP server unavailable" on batch_create_elements.

2. USER_PREFS fallbacks: create_element and batch_create_elements now
   apply fontFamily/roughness/fontSize/strokeWidth from preferences.json
   when not explicitly provided by the caller.

3. Hello handshake: Frontend sends `hello` on tenant_switched and handles
   `hello_ack`. Server resolves projectId from tenantId when absent.
   Fixes WS connections being registered under wrong scope.

4. Serialized broadcasts: Add serializedBroadcastWithAck() that queues
   broadcasts per tenant/project scope. Prevents race condition where
   parallel MCP create_element calls produce overlapping WS messages
   that clobber each other in the frontend.

5. Viewport screenshot: get_canvas_screenshot passes captureViewport=true,
   frontend captures DOM canvas via toDataURL() instead of exportToBlob()
   which always rendered the full scene bounding box.

6. Viewport animate:false: set_viewport uses animate:false for instant
   positioning, preventing mid-animation screenshot captures.

Tests: 14 new tests (8 API, 6 WS) + 9 E2E specs covering all fixes.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 08:28:00 +05:30
sanjibdevnathlabs-release-bot[bot] 670961ee73 chore(release): v1.6.0 v1.6.0 2026-03-17 18:16:39 +00:00
2cca18153f feat(sync): implement scoped sync architecture with ACK model and comprehensive tests (#11)
Implement a complete sync architecture overhaul (12 tasks) replacing the flat
WebSocket broadcast with scoped, acknowledged delivery:

**Backend (server.ts, db.ts, types.ts, index.ts):**
- Scoped connection registry: Map<tenant, Map<project, Set<ClientConnection>>>
- Hello handshake: WS clients identify tenant/project, server responds with scoped elements
- broadcastToScope() replaces global broadcast for element mutations
- broadcastWithAck() waits for browser ACK before returning syncedToCanvas status
- sync_version: monotonic counter per project, stamped on every mutation
- Delta sync v2: POST /api/elements/sync/v2 for incremental sync with version tracking
- GET /api/sync/version endpoint
- Honest syncedToCanvas + canvasStatus in all mutation responses
- Fixed silent try/catch in tenant switch verification

**Frontend (App.tsx):**
- ACK sending after every updateScene() with element verification
- Delta sync v2 integration in syncToBackend()
- Gap detection: triggers resync when sync_version gaps are detected
- lastSyncVersion tracking via refs + localStorage persistence

**Tests (40 new tests, 168 total):**
- db.test.ts: +11 tests for sync_version CRUD, scoping, getChangesSince
- ws.test.ts: +8 tests for hello handshake, scoped broadcast, ACK model
- api.test.ts: +10 tests for sync/v2, sync/version, canvasStatus responses
- helpers.test.ts: +11 tests for isImageElement, normalizeImageElement, restoreBindings
- canvas.spec.ts: +8 e2e tests including full ACK pipeline verification
- Fixed stale tenant state bug in api.test.ts beforeEach

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 23:44:17 +05:30
sanjibdevnathlabs-release-bot[bot] 4e410f1205 chore(release): v1.5.1 v1.5.1 2026-03-17 13:27:27 +00:00
sanjibdevnathlabsandClaude Opus 4.6 71b2a55231 ♻️ refactor(fonts): extract font families to shared JSON single source of truth
Font family IDs were duplicated across 5 files (types.ts, setup.ts,
index.ts, SKILL.md, preferences.example.json) with inconsistent
mappings — Comic Shanns was 4 in some places but actually 8 in
Excalidraw source. This caused wrong fonts to render on canvas.

Fix: create src/font-families.json as the canonical font data, import
it in types.ts, and derive all other references from it. Static docs
now point to the JSON file instead of duplicating the mapping.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 18:55:11 +05:30
sanjibdevnathlabs-release-bot[bot] 25767838fa chore(release): v1.5.0 v1.5.0 2026-03-17 12:12:15 +00:00
sanjibdevnathlabsandClaude Opus 4.6 493a20054b feat(setup): add interactive diagram preferences to setup and update flows
Users are now prompted to choose their preferred font family and roughness
style during both `setup` and `update`. Preferences are saved to
~/.claude/skills/excalidraw-skill/preferences.json, which the MCP server
already reads at startup via loadPreferences(). This ensures third-party
users who install via npx get preferences configured before first use.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 17:39:58 +05:30
sanjibdevnathlabs-release-bot[bot] aa29ddbf13 chore(release): v1.4.0 v1.4.0 2026-03-17 09:02:29 +00:00
sanjibdevnathlabsandClaude Opus 4.6 9114e81f02 feat(skill): add user-configurable diagram preferences system
Add a preference system that lets users configure default font, roughness,
fontSize, and strokeWidth — with three scopes (session/folder/global).

Skill layer (Step 1 in SKILL.md):
- Reads .claude/excalidraw-preferences.json (folder) then
  ~/.claude/skills/excalidraw-skill/preferences.json (global)
- If neither exists, prompts user interactively on first use
- Session-only scope keeps preferences in-memory without saving

Server layer (index.ts):
- loadPreferences() reads the same files at startup
- Replaces hardcoded fontFamily ?? 1 with USER_PREFS.fontFamily
- Folder-level preferences override global; user values override both

Also ships preferences.example.json as a template (preferences.json
is gitignored).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 14:27:34 +05:30
sanjibdevnathlabs-release-bot[bot] fac1c7a267 chore(release): v1.3.0 v1.3.0 2026-03-13 18:19:16 +00:00
sanjibdevnathlabs 9311561227 feat(skill): add auto-triggering for excalidraw-skill via CLAUDE.md directives
The excalidraw-skill was not being auto-invoked when users prompted
Claude to draw diagrams, despite being installed. Claude would call
Excalidraw MCP tools directly, bypassing the skill's critical sizing
formulas and verification workflow — producing broken diagrams with
invisible arrows, truncated text, and overlapping elements. The root
cause is that Claude Code's skill system is advisory: when direct MCP
tools or built-in Bash instructions are available, Claude skips skill
consultation entirely.

🔧 Skill description rewrite:
- Lead with "MANDATORY prerequisite" to assert priority over raw MCP tools
- Add user-intent trigger keywords (draw, visualize, sketch, diagram)
- Name specific consequences of skipping the skill
- List common diagram types for semantic matching

🏗️ Setup/update auto-directives:
- Write marked CLAUDE.md sections during skill install and update
- Write Cursor .mdc rules with alwaysApply for Cursor users
- Use HTML comment markers for idempotent append-or-replace on updates
- Non-fatal directive writing — skill installs even if directive fails

🎯 Two-layer defense ensures reliable skill triggering: the description
catches semantic matching, while the CLAUDE.md directive provides an
authoritative instruction that Claude cannot deprioritize in favor of
raw tool access.
2026-03-13 23:46:59 +05:30
sanjibdevnathlabs-release-bot[bot] 6db9227b59 chore(release): v1.2.1 v1.2.1 2026-03-13 17:26:09 +00:00
sanjibdevnathlabs 6791a4171f 🐛 fix(cli): resolve Claude Code re-registration failure and add @latest auto-update
The `claude mcp add` command fails with "already exists" when the server
is already registered. Additionally, configs written by setup/update used
a bare package name without @latest, causing npx to serve stale cached
versions indefinitely.

🔧 CLI registration:
- Remove existing entry before re-adding for Claude Code (both setup and update flows)
- Silently ignore removal errors when entry doesn't exist yet

 Auto-update via @latest:
- Write @latest suffix in JSON configs, CLI commands, and manual instructions
- Smart detection in update flow: skip if config already has @latest,
  offer migration if pinned, offer creation if missing

🎯 Users who run setup or update now get configs that always fetch the
newest version on MCP client restart, eliminating the stale-cache problem
without requiring manual npm cache clearing.
2026-03-13 22:53:39 +05:30
sanjibdevnathlabs-release-bot[bot] 956e33398c chore(release): v1.2.0 2026-03-13 17:09:58 +00:00
Sanjib DevnathandGitHub 86abe92fa2 feat(cli): add interactive update command for skill and config updates (#10)
Existing users who update the npm package often forget to update the agent
skill files, leaving their AI agent working with stale workflow guidance
(sizing rules, color palettes, anti-patterns). The new `update` subcommand
solves this by detecting and updating all skill installations automatically.

🔧 Interactive update wizard:
- Scan all agent directories (Cursor, Claude Code, Codex CLI) across global
  and local scopes for existing excalidraw-skill installations
- Batch-update found installations with a single Y/n confirmation
- Offer to install the skill for detected agents that don't have it yet
- Optionally re-apply MCP config (defaults to no for non-breaking updates)

📝 Documentation:
- Rewrite README "Updating" section to lead with the interactive command
- Add collapsible example session showing the update flow
- Retain manual update methods as fallback for each installation path

🎯 Ensures skill files stay in sync with MCP tools across releases,
preventing the subtle drift where new tool capabilities exist but the
agent's workflow guidance doesn't reference them.
2026-03-13 22:37:58 +05:30
sanjibdevnathlabs-release-bot[bot] c16e1f4cc3 chore(release): v1.1.5 v1.1.5 2026-03-13 16:05:31 +00:00
sanjibdevnathlabs 8144c7cd6e 📝 docs(skill): add geometric thinking principles and technique catalogs
Excalidraw skill lacked guidance on building complex visual shapes from
basic primitives, leading to flat single-shape attempts for structures
like roofs and walls. Adds coordinate geometry foundations so agents
produce realistic illustrative diagrams alongside technical ones.

🔧 Core geometric principles:
- Compose complex shapes from many small primitives with tessellation
- Eliminate gaps using interleaving offset rows at half-width spacing
- Parametric positioning formulas for centering, circular, triangular, and isometric layouts
- Scale primitive dimensions proportionally to container size

📦 Technique catalog reference:
- Illustrative elements (roofs, walls, clouds, trees, fences, windows)
- Sugiyama-inspired flow diagram layout algorithm
- Zone-grid architecture diagram layout
- Isometric 2.5D projection formulas
- Repeating pattern formulas with brick-pattern offsets

🧹 Consolidate tenants/projects/search into single compact table to
keep SKILL.md under the 500-line skill guideline
2026-03-13 21:33:21 +05:30
sanjibdevnathlabs-release-bot[bot] dcce55d469 chore(release): v1.1.4 v1.1.4 2026-03-13 13:36:27 +00:00
061fa82672 🐛 fix(pkg): remove broken postinstall that blocks npx installation (#9)
The postinstall ran prebuild-install and node-gyp in the wrong context
(our package instead of better-sqlite3), always failing with "binding.gyp
not found". better-sqlite3 handles its own native compilation via its
install script — the package-level postinstall was redundant.

Co-authored-by: sanjibdevnathlabs <devnath.sanjib@gmail.com>
2026-03-13 19:04:10 +05:30
sanjibdevnathlabs-release-bot[bot] ffc922b296 chore(release): v1.1.3 v1.1.3 2026-03-13 12:53:33 +00:00
Sanjib DevnathandGitHub 97d816df4a 🐛 fix(cli): robust npx entry point, Node 20 requirement, setup hardening (#8)
- Use fs.realpathSync for entry point detection to fix npx symlink failures
- Add --help and --version CLI flags with explicit process.exit(0)
- Add TTY detection in setup wizard to prevent non-interactive hangs
- Wrap JSON.parse in mergeJsonConfig with try/catch for malformed configs
- Update engines.node to >=20.0.0 to match better-sqlite3 requirements
- Update Dockerfiles from node:18-slim to node:20-slim
- Remove error-swallowing || true from postinstall script
- Replace deprecated windows-build-tools with VS Build Tools link
2026-03-13 18:21:19 +05:30
sanjibdevnathlabs-release-bot[bot] 6a69ac6761 chore(release): v1.1.2 v1.1.2 2026-03-13 10:10:06 +00:00
sanjibdevnathlabs ddfd3a73e8 perf(ci): single setup job with cache + artifact sharing, concurrency groups, fix badges 2026-03-13 15:37:50 +05:30
sanjibdevnathlabs 19ed8bd1fc perf(ci): single setup job with artifact sharing, caching, concurrency groups, fix badges 2026-03-13 15:32:22 +05:30
sanjibdevnathlabs-release-bot[bot] fcb0858165 chore(release): v1.1.1 v1.1.1 2026-03-13 09:18:28 +00:00
sanjibdevnathlabs ec41d30cd3 ♻️ refactor(ci): trigger release after CI passes instead of running redundant tests 2026-03-13 14:40:45 +05:30
sanjibdevnathlabs-release-bot[bot] d8f0f2b6fd chore(release): v1.1.0 v1.1.0 2026-03-13 09:06:36 +00:00
sanjibdevnathlabs ace834ea59 🐛 fix(ci): fix YAML parse error in release workflow changelog builder 2026-03-13 14:34:03 +05:30
Sanjib DevnathandGitHub f1e1f4cbab 🔧 fix(ci): use GitHub App bot for release and auto-pass Docker check (#7)
The release workflow pushes version bump commits directly to main, but
branch protection rules block the default GITHUB_TOKEN from bypassing
required status checks and PR requirements. Using a dedicated GitHub
App (sanjibdevnathlabs-release-bot) generates installation tokens that
are permitted through the ruleset bypass list, and keeps the bot
identity on release commits instead of a personal account.

The Docker Build workflow previously used a paths filter, causing it to
not trigger at all for non-Docker PRs — leaving the required
github/docker-build-check status permanently pending. Now the workflow
always triggers but checks for Docker-related file changes first,
skipping builds when unnecessary while still reporting the status check
as passed.
2026-03-13 14:29:36 +05:30
63209f9d5a feat: add test suite, CI/CD pipeline, setup wizard, and upstream feature ports (#6)
Establish comprehensive quality infrastructure for a project that previously
had zero tests, enabling confident refactoring and community contributions
with automated guardrails. Port upstream enhancements for font normalization,
image element support, and arrow binding preservation.

🏗️ Testing infrastructure:
- Unit tests for SQLite persistence layer and element validation helpers
- Integration tests for REST API, WebSocket broadcast, and arrow binding
- E2E tests with Playwright for canvas rendering and real-time sync
- Vitest + Playwright configuration with proper isolation

👷 CI/CD pipeline:
- Auto-versioning from conventional commits on push to main
- Auto-publish to NPM and Docker Hub on GitHub release
- Matrix testing across Node 18/20/22 with pinned dependencies
- Docker health check with diagnostic logging on failure
- Preserve rollup status checks for branch protection gates

📦 Developer experience:
- Interactive setup wizard for first-time configuration
- Canvas clear confirmation and scene description tools
- Frontend helpers extracted for testability

🔧 Upstream feature ports:
- Font family normalization (string names to numeric IDs)
- Image element support with file management API
- Arrow binding preservation through server round-trips
- Vite config fix for font subsetting worker chunk names
- Idempotent database initialization for standalone Docker mode

🐛 Docker fixes:
- Set EXCALIDRAW_DB_PATH in both Dockerfiles to writable /app/data/
- Make initDb() idempotent and closeDb() reset-safe for test isolation

🎯 Provides the safety net needed for rapid iteration — every PR is
validated across 120 test cases before merge, and releases are fully
automated from commit to published package.

Co-authored-by: sanjibdevnathlabs <devnath.sanjib@gmail.com>
2026-03-13 12:08:07 +05:30
sanjibdevnathlabs 4c50472ee4 Startup fixes 2026-03-13 08:53:20 +05:30
79e959ae45 🐛 fix(ci): grant contents:write permission for release asset upload (#5)
The npm-publish workflow needs write access to upload tarballs to
GitHub releases. Read-only caused "Resource not accessible by integration".

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-19 10:53:53 +05:30
a16f7821fb Chore/reset version to 1.0.0 (#4)
* 🔧 chore: reset version to 1.0.0 for independent NPM package

This is a new scoped package (@sanjibdevnath/mcp-excalidraw-local),
so versioning starts fresh at 1.0.0 rather than continuing upstream's
numbering.

Co-authored-by: Cursor <cursoragent@cursor.com>

* chore: trigger PR

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
v1.0.0
2026-02-19 10:49:36 +05:30
a1553891c4 📝 docs: replace ASCII architecture diagram with Excalidraw-generated PNG (#3)
Dogfood our own tool — the architecture diagram is now drawn in
Excalidraw and exported as PNG, replacing the ASCII art block.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-19 10:41:32 +05:30
7143b5e41e feat: add SQLite persistence, multi-tenancy, auto-sync, and CI/Docker improvements (#1)
Replace in-memory storage with SQLite (WAL mode), add workspace-based
multi-tenancy with auto-detection via server.listRoots(), and embed the
canvas server into the MCP process for single-process operation.

🔧 Core enhancements:
- SQLite persistence with versioning, element history, and search
- Multi-tenancy: isolated canvases per workspace (SHA-256 tenant IDs)
- Embedded canvas lifecycle (single node process starts MCP + canvas)
- Auto-sync with 3s debounce and manual override toggle
- Configurable canvas port via CANVAS_PORT env var
- 6 new MCP tools (search, history, tenants, projects)
- Workspace switcher UI with dropdown search
- Sync normalization to prevent bound-text breakage on reload

🐳 Docker & CI improvements:
- BuildKit cache mounts for faster npm installs across builds
- Skip native compilation in frontend-builder stage (--ignore-scripts)
- Build only linux/amd64 on PRs, multi-arch on push to main
- Docker Hub registry with proper build tools for better-sqlite3
- CI and Docker status check gates (github/ci-status-check, github/docker-build-check)

📦 Package & publishing:
- Renamed to @sanjibdevnath/mcp-excalidraw-local (v3.0.0)
- Updated npm-publish workflow for scoped package
- Updated bin entry, keywords, and files list

📝 Documentation:
- README with UI screenshots, architecture diagram, and full feature docs
- Updated agent skill with 32-tool cheatsheet and workflow playbooks
- Fork attribution and upstream comparison table

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-19 10:17:29 +05:30
yctimlin 9883dce220 add gif demo 2026-02-14 13:23:52 +08:00
yctimlinandGitHub db0c0a3dea docs: update arrow examples in SKILL.md (#44) 2026-02-13 15:51:22 +08:00
yctimlinandGitHub 913f9b89b7 Updates to Excalidraw MCP server and documentation (#43) 2026-02-13 00:20:01 +08:00
yctimlinandGitHub 4a17c47b54 Feat/canvas toolkit v2 (#41)
* feat: enhance Excalidraw MCP with advanced canvas toolkit features

- Rename skill to `excalidraw-skill` with expanded playbook and cheatsheet.
- Add new MCP tools for iterative refinement: `describe_scene` and `get_canvas_screenshot`.
- Implement layout tools (`align_elements`, `distribute_elements`) and `duplicate_elements`.
- Add file I/O support for `.excalidraw` JSON and image export (PNG/SVG).
- Introduce named snapshots for canvas state management.
- Add server-side element CRUD and WebSocket handlers for real-time sync.
- Normalize `points` format for arrows and lines.

* docs: update README with v2.0 features and official MCP comparison

* feat: implement arrow binding and edge-to-edge routing

* fix: enhance security with path sanitization and improve export error handling

* feat: add viewport control, design guide, and excalidraw.com URL export

* feat: enhance excalidraw.com export with proper scene formatting and labels
2026-02-12 18:09:56 +08:00
yctimlin 1359720f66 feat: Add Zod and OpenCode AI SDK dependencies and agent skill files. 2026-01-26 00:37:06 +08:00