Files
excalidraw-mcp-sentinel/CHANGELOG.md
T
2026-03-30 21:32:28 +02:00

6.1 KiB

Changelog

All notable changes to this project are documented here. Format: Keep a Changelog

[Unreleased]

[1.0.2] - 2026-03-30

Added

  • frontend/src/utils/scenePreparation.ts — centralized scene-preparation utilities (expandLabelsToNative, prepareElementsForScene, convertElementsPreservingImageProps)
  • E2E regression suite: tests/e2e/phase2-regressions.spec.ts (4 tests: position stability, auto-title, two-tab sync, curved arrow deformability)
  • Backend tests: db-unit, mcp-contract, mcp-sanitization, security-unit, smoke-ws, tenant-authz-behavior
  • Frontend tests: scene-preparation, helpers, sync-logic

Changed

  • computeElementHash is now order-stable for equivalent element sets
  • frontend/src/App.tsx uses centralized scene-preparation utilities for label expansion and native-vs-converted routing
  • Rate limits raised: general 100→500 req/15min, write burst 10→30 req/min
  • MCP unknown tool calls now return JSON-RPC MethodNotFound (-32601) instead of generic error
  • Test count: 446/446

Fixed

  • Double WebSocket connection race — second WS created during CONNECTING state seeded knownContainerIdsRef prematurely, blocking title auto-injection; guard now also blocks CONNECTING state
  • Title/subtitle not injected for WS-delivered containersCaptureUpdateAction.NEVER suppresses onChange; handleCanvasChange() now called explicitly after element_created
  • Text alignment lost after syncElementSharedFieldsSchema did not declare textAlign, verticalAlign, containerId; Zod silently stripped these on every REST round-trip
  • Curved arrow deforms after sync — element replace strategy discarded Excalidraw-internal control point state; now merges incoming over existing
  • MCP import_scene prototype pollutionassertNoDangerousKeys() now called on all parsed JSON payloads (MCP stdio bypasses Express middleware)
  • FTS5 colon column-filter injection: added to blocked character set in sanitizeSearchQuery
  • Global state race in createProject/listProjects — explicit tenantId? param added; MCP callers pass captured ID at call time
  • Subtitle elements in MCP create_element now set textAlign: "center" and verticalAlign: "top"
  • ServerElement type updated with textAlign?, verticalAlign?, containerId?
  • pendingTitleTimerRef now cleaned up on component unmount (prevented stale closure after unmount)
  • localStorage JSON.parse for widget position wrapped in try/catch (malformed value no longer crashes component)
  • Docker LABEL org.opencontainers.image.source corrected to fork URL

[1.0.1] - 2026-03-29

Fixed

  • better-sqlite3 native module now rebuilt on install via postinstall script, fixing Node.js version mismatch errors (e.g. Node v22 vs v25) when installing via npx

[1.0.0] - 2026-03-29

Changed

  • Renamed project from @sanjibdevnath/mcp-excalidraw-local to excalidraw-mcp-sentinel
  • New npm package name: excalidraw-mcp-sentinel (unscoped)
  • GitHub repo: celstnblacc/excalidraw-mcp-sentinel
  • Docker images: celstnblacc/excalidraw-mcp-sentinel and celstnblacc/excalidraw-mcp-sentinel-canvas
  • CLI binary renamed: excalidraw-mcp-sentinel
  • Version reset to 1.0.0 for independent release track
  • Added "Why this fork?" section to README with full attribution

Removed

  • Superseded planning docs (PLAN.md, PLAN_v2.md, REVIEW.md, HANDOFF.md)

[1.6.3] - 2026-03-29

Security

  • Added security.ts middleware module: helmet headers, explicit CORS allowlist, API key auth with timing-safe comparison, prototype pollution guard, Mermaid input size limits
  • WebSocket authentication: challenge-response (auth_requiredhello + apiKey) with 5 s timeout and close code 4001 on failure; origin verification via verifyClient
  • Rate limiting on all /api/* routes: 100 req/15 min general, 10 req/min destructive, 10 req/min sync write burst
  • sanitizeSearchQuery now throws typed InvalidSearchQueryError instead of generic Error
  • Docker: added deploy.resources.limits (canvas 1 CPU/512M, mcp 0.5 CPU/256M) to docker-compose.yml; extended .dockerignore with tests/ and sensitive key file patterns

Fixed

  • POST /api/elements/sync: array validation now runs before logger access, preventing a TypeError crash (500) on null/non-array input — now returns 400
  • POST /api/elements/sync/v2: element type validated against EXCALIDRAW_ELEMENT_TYPES before write; invalid types return 400 instead of being persisted silently
  • Upgraded zod from 3.22.4 to 3.25.5 to resolve ERR_PACKAGE_PATH_NOT_EXPORTED crash at MCP server startup caused by zod-to-json-schema peer dependency mismatch

Changed

  • ElementSharedFieldsSchema extracted from CreateElementSchema/UpdateElementSchema to eliminate 25-field duplication; both schemas now use .extend()
  • VALID_ELEMENT_TYPES moved to module-level constant (was allocated per-request)
  • resolveHelloTenantAndProject parameter typed as HelloMessage (was any)
  • getAllFilesObject() helper extracted; sendFilesAdded() and GET /api/files share it
  • sendLegacyInitialWsMessages renamed to sendAuthlessInitialMessages
  • .project-hooks/pre-commit added to run vitest on every commit

[Unreleased] - 2026-03-30

Fixed

  • Bidirectional sync conflict: WS-applied updates no longer reverted by browser auto-sync (lastSyncedElementsRef now updated on element_updated, element_deleted, elements_batch_created)
  • Labeled container updates (rectangle, ellipse, diamond, arrow) now use convertToExcalidrawElements with ID transplant for correct text layout instead of in-place text patch that caused clipping
  • Standalone text element updates now write label.text into text/originalText fields so Excalidraw renders the new value
  • convertTextToLabel now maps text→label for arrows and empty strings (previously skipped falsy text)

Changed

  • Default theme set to dark

Fixed

  • Labels stored as label.text (e.g. from MCP updates) now survive page refresh — expandLabelsToNative pre-converts them to bound text before Excalidraw renders