Commit Graph
18 Commits
Author SHA1 Message Date
9846e0ba0f feat(canvas): native field preservation, label materialization, batch workspace delete (#12)
* feat(canvas): native field preservation, label materialization, batch workspace delete

- fillNativeFields() + repairContainerBinding() in db layer ensure every
  element stored in SQLite is a complete, round-trippable Excalidraw element
  with correct containerId ↔ boundElements bidirectional binding
- materializeLabel() in server.ts: shapes with label.text/text produce a
  native bound text element at write time (create, update, batch) so text
  follows its container when moved — matches VSCode Excalidraw extension behavior
- Batch workspace UI: Select/Unselect All, per-row checkboxes, Delete N
  workspaces button with confirmation
- POST /api/tenants/batch-delete: delete up to 50 tenants in one request
- 42 new backend tests; 519 total passing
- Bump version 1.0.6 → 1.1.0

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(tests): update e2e assertions for label materialization

phase2-regressions: label is now a native bound text element
(id: pos-stable-1-label) — check bound text element text instead
of container.label?.text which is no longer stored.

sync-flows FTS: search now matches the bound text element (fts-el-label)
rather than the container — accept either id as valid match.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 21:12:01 +02:00
d14d767c75 feat(tenants): add workspace delete UI and fix project switch element loading (#11)
- Add DELETE /api/tenants/:id endpoint with cascade (projects, elements, snapshots)
- Add delete buttons with inline confirm in workspace switcher panel
- Fix project switch not loading elements: switchProjectUI now directly clears
  canvas and calls loadExistingElements() instead of relying on WS roundtrip

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 14:37:11 +02:00
Maxime Roy (new.blacc)andGitHub 1166ea5b3f chore: release v1.0.5 (#10)
feat(projects): project management UI, sync countdown, fix project switching
2026-04-06 13:18:03 +02:00
newblaccandClaude Sonnet 4.6 87e8a8e314 fix: preserve textAlign/verticalAlign/containerId through REST round-trip
ElementSharedFieldsSchema in server.ts was silently stripping textAlign,
verticalAlign, and containerId on every POST/PATCH, causing bound text
inside containers to lose centering after a sync round-trip.

- Add missing fields to ElementSharedFieldsSchema (server.ts)
- Add textAlign?, verticalAlign?, containerId? to ServerElement (types.ts)
- Set textAlign: "center", verticalAlign: "top" on MCP subtitle elements (index.ts)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 20:56:46 +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
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
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
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
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
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
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
Scott Friedmanandyctimlin fe4bf8e787 Fix: Batch endpoint now respects element IDs from MCP server
The batch creation endpoint was always generating new IDs, ignoring IDs
passed from the MCP server. This caused sync issues where the MCP server
would think elements were created with specific IDs, but the canvas had
different IDs.

This fix makes the batch endpoint behave like the single element endpoint:
it now respects passed IDs (for MCP sync) or generates new ones if not provided.

Fixes the 'MCP tool registration issues' mentioned in the roadmap.
2026-01-25 00:29:37 +08:00
francisco b8e2de76f1 feat: implement WebSocket-based Mermaid conversion with auto-sync
- Add WebSocket message handler for mermaid_convert type
- Make handleWebSocketMessage async to support conversion
- Add automatic backend sync after diagram generation
- Integrate convertMermaidToExcalidraw utility
- Remove test button and handleMermaidTest function
- Fix: Add missing Excalidraw CSS import for proper UI rendering
- Enhance server endpoint with WebSocket broadcast support
- Add mermaid_convert to WebSocketMessageType union
2025-11-01 13:58:23 -03:00
francisco c1cecf282c feat: add POST /api/elements/from-mermaid endpoint for Mermaid conversion 2025-11-01 13:58:22 -03:00
Gianluca Venturini 7411414e42 Fix group_elements and ungroup_elements operations 2025-10-12 22:30:08 -07:00
yctimlin 5043a67385 Refactor project structure and enhance TypeScript support
- Updated package.json to point to compiled TypeScript files in the dist directory.
- Improved TypeScript configuration with stricter type checks and removed JavaScript support.
- Migrated frontend entry point to TypeScript and added a new App component with enhanced functionality.
- Implemented a new server structure with TypeScript, including WebSocket support and improved element management.
- Updated README to reflect changes in architecture and usage instructions.
- Added comprehensive type definitions for Excalidraw elements and server responses.
2025-08-20 15:31:42 +00:00