Commit graph

938 commits

Author SHA1 Message Date
Vitali sharp8n b7fda1d406 fix(automation): allow a configurable canvas endpoint and browser-only token
- connectAutomation accepts an explicit ws:// URL and a register token
- EditorView reads ?automationWs / ?automationToken so a served build (W4C Design
  Studio iframe) can reach the server MCP instead of the user's 127.0.0.1
- MCP accepts OPENPENCIL_MCP_BROWSER_TOKEN for canvas registration only, never
  for /mcp or /rpc, so a public canvas WebSocket does not expose the tool token
2026-09-18 03:37:20 +03:00
Vitali sharp8n a1b078b5e6 upgrade 2026-09-16 13:09:12 +03:00
Vitali sharp8n dc29f8393e open file feature 2026-09-10 22:57:45 +03:00
Vitali sharp8n e610d4e551 enchancements 2026-09-05 11:25:33 +03:00
Vitali sharp8n aa3a30b6ad add auto restore mode (embed) 2026-09-04 21:05:05 +03:00
Vitali sharp8n b9b04fb28d font-proxy 2026-08-27 01:42:41 +03:00
Vitali sharp8n c6a65c4878 feat(web): ship the Vue editor web build with online font providers
- Add Dockerfile.web-vue + docker/ container: static SPA on :3100 and the
  MCP Streamable-HTTP server on :7600 in one image, replacing the retired
  Rust web host used by the w4c iframe integration
- Allow online font providers (Google Fonts, Fontsource, Bunny, Fontshare)
  to load in the browser via native CORS-enabled fetch instead of gating
  them on the Tauri fetch proxy
- Rename webFontProvidersRequireDesktopApp to webFontLoadFailed and reword
  the toast for connection failures; drop the unconditional toast from the
  font family picker
- Support OPENPENCIL_MCP_HOST so the MCP server binds 0.0.0.0 in containers
2026-08-22 00:33:54 +03:00
Danila Poyarkov 9f7ce64bf6
Merge pull request #562 from open-pencil/guide-authoring
feat(editor): author canvas and frame guides from rulers
2026-08-20 09:39:19 +03:00
Danila Poyarkov 27ad48b365 refactor(canvas): separate guide and overlay pipelines 2026-08-20 08:41:16 +03:00
Danila Poyarkov 62ba072b26
refactor(ai): ship Harness as optional companion (#561)
* Revert "feat(ai): add HarnessAgent sidecar foundation (#560)"

This reverts commit 83a5ea1b42.

* Revert "Revert "feat(ai): add HarnessAgent sidecar foundation (#560)""

This reverts commit 0d8c03515888c62dc47186d4a3b0b7b04e78f8af.

* refactor(ai): ship Harness as optional companion

* fix(ai): support Harness companion on Windows

* test(ai): restore navigator after Harness Windows test
2026-08-19 20:04:35 +03:00
Danila Poyarkov f892cb583c feat(editor): add ruler guide authoring foundation
- Preserve page and frame guide GUIDs through .fig conversion
- Add undoable guide add, move, transfer, and remove actions
- Start page/frame guide previews from CanvasKit rulers
- Render warm guide previews with frame-scoped solid lines and dotted continuation
2026-08-19 18:08:48 +03:00
Danila Poyarkov 83a5ea1b42
feat(ai): add HarnessAgent sidecar foundation (#560)
* feat(ai): add HarnessAgent sidecar foundation

* feat(ai): integrate Pi as a Harness provider

* fix(ai): harden Harness provider integration

* fix(ai): address Harness integration review

* fix(ai): align Harness code with project conventions

* fix(ai): preserve Harness sessions on cancellation

* test(ai): cover Harness JSONL framing

* refactor(ai): generalize Harness sidecar adapters

* fix(ci): build Harness sidecar for native checks
2026-08-19 17:41:10 +03:00
Danila Poyarkov 42b1fa07f0 Merge origin/master into feat/configurable-snapping-guides 2026-08-18 22:05:51 +03:00
Danila Poyarkov 921cd702f8 fix(editor): address snapping review feedback
- Preserve parent-local movement during Control bypass
- Route native snapping menu actions through persisted preferences
- Harden guide alignment, lifecycle rendering, and transformed resize behavior
- Update preference descriptions and fractional position display
2026-08-18 22:03:53 +03:00
Danila Poyarkov 91e759d7fd feat(editor): add configurable snapping and guides
- Snap vector points, moved layers, and resized edges to geometry, objects, guides, and pixels
- Add persistent snapping preferences with browser and native menu controls
- Normalize canvas and layout guides across Scene Graph and .fig conversion
- Clear transient snapping feedback across interrupted interactions
2026-08-18 19:11:48 +03:00
Danila Poyarkov 211a4ea99c
fix(i18n): localize app notifications (#557)
- Add app-owned notification translations for every supported locale.\n- Localize common file, clipboard, collaboration, chat, vectorization, storage, recovery, and library toasts.\n- Preserve actionable runtime details inside localized messages.
2026-08-18 18:52:19 +03:00
Danila Poyarkov 4342fd3262
perf(chat): release completed streaming parser history (#553)
- Keep only the active assistant response in streaming Markdown mode.\n- Remount completed responses in static mode to release incremental AST caches.\n- Preserve final Markdown, code rendering, and theme behavior.
2026-08-18 17:43:49 +03:00
Victor Wads 4e48420ac1
feat(app): open multiple files from the Open dialog (#552)
- Open multiple selected design files in separate tabs.\n- Support desktop, File System Access, and fallback pickers.\n- Continue opening later selections when one file fails.
2026-08-18 11:30:36 +03:00
Danila Poyarkov 97e42e8102
test(collab): add deterministic browser sessions (#541)
* test(collab): add deterministic browser sessions

- Extract a typed room transport boundary around Trystero
- Add a development-only WebSocket relay transport for browser tests
- Cover two-peer edits, awareness, departure cleanup, and reconnect convergence without public network services

* fix(collab): harden browser test transport

- Scope collaboration controls to explicit development test hooks
- Validate bounded relay messages and reject duplicate action receivers
- Remove only awareness clients owned by a departing peer
- Guarantee relay and browser cleanup after setup failures

* fix(collab): strengthen browser session coverage

- Prevent remote awareness rebroadcast and track ownership by transport peer
- Guard and validate the development relay lifecycle
- Simulate a network partition with retained peers and concurrent offline edits
- Make browser and relay setup and teardown failure-safe

* test(collab): prove partitioned peer convergence

- Queue and assert traffic during a deterministic network partition
- Converge non-conflicting edits from retained host and guest sessions
- Reject relay startup failures and guard test-only browser APIs
2026-08-17 12:57:03 +03:00
Danila Poyarkov d29fe37fd5
fix(chat): match code blocks to the app theme (#542)
- Update vue-stream-markdown to 1.0.4.\n- Pass OpenPencil's resolved theme to Shiki rendering.\n- Keep code backgrounds and syntax colors readable in light and dark modes.
2026-08-17 12:18:58 +03:00
Danila Poyarkov d112bc9044
fix(chat): preserve native copying of selected text (#540)
- Allow native text selection in AI chat messages.\n- Leave active DOM text ranges to the platform clipboard.\n- Preserve canvas clipboard routing when no document text is selected.
2026-08-17 11:54:24 +03:00
Danila Poyarkov d7613f34ec
perf(scene-graph): accelerate axis-aligned hit tests (#534)
* perf(scene-graph): accelerate axis-aligned hit tests

- Reuse cached world positions for untransformed node chains
- Preserve exact matrix hit testing beneath rotated and flipped ancestors
- Profile pointer, hit-test, cached, overlay, and volatile rendering at 500 and 2,000 nodes

* fix(vue): restore layer drop indicators

- Forward reactive drag instructions through virtualized layer item slots
- Render above, below, and child feedback before the drop completes
- Add browser regressions for reorder lines and container highlights

* fix(scene-graph): harden hit-test performance coverage

- Cache transformed ancestry within each hit-test traversal
- Invalidate absolute positions after preview flips and reparenting
- Attach scale-relative browser profiles and correct auto-layout fixture geometry

* fix(scene-graph): reject cyclic layer reorder

- Prevent reorderChild from parenting a node beneath its descendant
- Cover graph preservation after a rejected cyclic reorder
2026-08-16 15:43:25 +03:00
Danila Poyarkov 97bc86fa70
fix(app): use callable fetch adapter type (#535) 2026-08-16 13:40:44 +03:00
Danila Poyarkov e7c408a28f
perf(app): coalesce overlapping autosaves (#531)
- Serialize writable-document autosaves and retain only the newest trailing version
- Preserve saves requested while export or persistence is in flight
- Cover file, storage, retry, and recovery scheduling invariants
2026-08-15 12:23:01 +03:00
Danila Poyarkov b0ebe91ed6
perf(collab): skip unchanged Yjs node fields (#529)
* perf(collab): skip unchanged Yjs node fields

- Compare encoded node fields before writing to Y.Map
- Cover unchanged sync, repeated drag-like updates, echo behavior, and concurrent convergence
- Reduce 100 unchanged syncs from 13,700 updates to zero

* test(collab): simulate queued Yjs convergence

- Use the official Yjs TestConnector for deterministic queued delivery
- Exercise offline concurrent edits, reconnect, random message flushing, and convergence
2026-08-15 11:40:27 +03:00
Danila Poyarkov 7a02ee2c62
feat(editor): model split canvas panes (#519)
* refactor(editor): separate canvas view state

- Classify shared and view-local editor state explicitly

- Let canvas surfaces render supplied view state and report their viewport

- Preserve the existing one-canvas behavior by default

* fix(canvas): preserve loading render state

* feat(editor): model split canvas panes

- Add pure recursive split-tree operations with validated sizes

- Add explicit pane registry and independent view-state cloning

- Cap visible panes and cover close and split behavior

* refactor(editor): group state ownership modules

- Move shared and view state into the editor state namespace

- Model the partition with explicit interfaces and default factories

- Derive runtime view keys from the default view object

* feat(editor): model split canvas panes

- Add pure recursive split-tree operations with validated sizes

- Add explicit pane registry and independent view-state cloning

- Cap visible panes and cover close and split behavior

* feat(editor): add split canvas views

- Render recursive pane layouts with Reka UI splitters and pane-local headers
- Route canvas input, selection, viewport state, and close actions to the active pane
- Repaint every canvas during shared document previews and cover split lifecycle in tests

* fix(editor): clean up inactive pane interactions

- Cancel drag, padding preview, and text editing state when pane focus changes
- Remove duplicate changelog entries introduced while updating master
2026-08-15 10:31:52 +03:00
Danila Poyarkov 6193b6da7e
feat(code): add live JSX and HTML/CSS editing (#525)
* feat(code): isolate Design JSX execution

- Transform JSX with the existing Sucrase dependency and execute it in a disposable opaque-origin iframe worker

- Block ambient network capabilities and enforce source, timeout, output, depth, and element limits

- Validate that only bounded plain structured data returns to the application

* feat(code): add editable Design JSX

- Add a lazy CodeMirror editor with JSX syntax support, completion, diagnostics, and bounded scrolling

- Convert validated sandbox output into trusted Design JSX helpers before rendering

- Apply or insert JSX as one undoable graph transaction while preserving dirty drafts

* feat(code): localize JSX editor actions

- Add translated-message fallbacks for editing, applying, inserting, and draft state

- Document the editable JSX workflow in the unreleased changelog

* fix(code): satisfy typed sandbox validation

- Keep the sandbox document terminator literal and preserve optional selection handling under type-aware lint

* test(code): resolve sandbox probes through app aliases

* fix(code): bound sandbox results before cloning

- Enforce string, array, object, depth, element, and byte limits inside the disposable worker

- Retain host-side validation as a second structured-data boundary

* fix(code): keep JSX and HTML editing modes separate

- Switch generated Tailwind output back to OpenPencil JSX before editing

- Close the JSX editor when opening HTML/CSS import and avoid stacking both editors

* feat(code): support authored Design JSX programs

- Allow local constants, function components, arrays, conditionals, fragments, and multiple roots

- Preserve replacement positions for multiple selected roots and reject mixed-parent or locked selections

- Cover multi-root undo, redo, and all-or-nothing rollback

* feat(code): add explicit JSX view mode

- Let authors leave CodeMirror without applying a draft

- Keep the editable surface and HTML/CSS importer mutually exclusive

* feat(code): diagnose unknown JSX vocabulary

- Warn on OpenPencil elements and properties that are absent from the canonical schema

- Surface diagnostics inline through CodeMirror lint markers

* test(code): accept WebKit isolation diagnostics

- Cover the sandbox architecture against Playwright WebKit

- Accept engine-specific wording while preserving the same unavailable-window assertion

* refactor(code): consolidate Design JSX vocabulary

- Drive renderer warnings, completion, and diagnostics from one supported-property schema

- Recognize locally declared components and add focused schema and transform tests

- Replace CodeMirror basicSetup with an explicit feature set and remove the umbrella package

* fix(code): support Design JSX variable helpers

* refactor(code): unify JSX sandbox validation

* fix(code): account for complete sandbox output

* fix(code): preserve locked JSX descendants

* fix(code): preserve JSX sibling order

* fix(code): recompute JSX parent layouts

* feat(code): add live code previews

* test(code): centralize graph assertions

* fix(code): harden live preview sessions

* docs: describe live code editing

* fix(code): update editor accessibility labels

* fix(code): use theme-aware error colors

* fix(dev): stop Vite disconnect error loops

* fix(code): clarify live preview status

* fix(ui): avoid tooltip attribute warnings

* test(code): assert semantic preview status

* refactor(code): remove obsolete editor messages

* fix(code): harden preview concurrency and isolation

* fix(code): cancel stale reset previews
2026-08-15 09:48:42 +03:00
Danila Poyarkov a29f609dd2
fix(settings): separate MCP connections from models (#522)
- Add a dedicated MCP connections destination to Settings navigation
- Keep ModelsPanel focused on model profiles and assignments
- Update documentation, changelog, and browser coverage for the new location
2026-08-14 20:39:29 +03:00
Danila Poyarkov 90f2498bcf
fix(collab): validate synchronized node data (#517)
* fix(collab): validate synchronized node data

- Exclude renderer-only text picture caches from Yjs payloads

- Normalize source metadata and geometry at the remote boundary

- Cover malformed payloads and typed geometry round trips

* fix(collab): reject malformed geometry fills

* fix(collab): validate nested fill metadata

* test(collab): preserve valid nested fill metadata
2026-08-14 20:38:46 +03:00
Danila Poyarkov 39bc4d2eb1
feat(acp): add reusable MCP connections (#516)
* feat(acp): add reusable MCP connections

- Store named Streamable HTTP connections separately from model providers
- Keep bearer tokens in the credential manager and resolve them per ACP session
- Add localized settings, validation, documentation, and focused coverage

* test(acp): harden MCP connection workflow

- Label credential inputs and confirm destructive connection removal
- Exercise MCP server delivery through an in-memory ACP session
- Extend the browser smoke test to cover accessible input and confirmation flows

* fix(acp): validate MCP connection lifecycle

- Keep non-browser storage initialization in memory and restore the German model copy
- Reject persisted name collisions and invalid draft IDs
- Preserve connections on credential failures and require credentials before enablement
2026-08-14 20:08:45 +03:00
Danila Poyarkov b93ffea073
feat: add Figma-style variants and component libraries (#512)
Closes #239
2026-08-14 19:31:41 +03:00
Danila Poyarkov 16e7707d7a Merge remote-tracking branch 'origin/master' into reference-image-chat 2026-08-14 14:47:03 +03:00
Danila Poyarkov 5f0b673a07 fix(ai): harden image attachment lifecycle
- Prevent overlapping submissions while image analysis is running

- Guard browser image APIs and object URL cleanup

- Restore compound-control and keyboard-focus styling
2026-08-14 14:31:59 +03:00
Danila Poyarkov d90e640e89
perf(app): defer inactive Code panel generation (#514)
* perf(app): defer inactive Code panel generation

- Skip JSX serialization and syntax highlighting while the Code tab is hidden

- Restore code generation when desktop or mobile users activate the tab

- Cover large Design-tab selections without hidden Code-panel work

* test(app): cover deferred Code panel updates

- Keep mobile JSX generation inactive while the drawer is closed

- Measure the complete two-frame inactive selection flow

- Verify mobile Code output refreshes when the drawer reopens
2026-08-14 14:24:10 +03:00
Danila Poyarkov 7b67bd8658 feat(ai): support multiple image attachments
- Show complete user messages with every image immediately after sending

- Analyze up to four bounded images without adding pixels to Design context

- Organize image handling under the extensible attachment domain
2026-08-14 13:44:57 +03:00
Danila Poyarkov 2f88ef4827 refactor(ui): unify chat composer controls
- Add a canonical 24, 28, and 32 pixel control scale

- Rebuild the AI prompt as a multiline compound input

- Keep property-panel icon actions at the explicit compact size
2026-08-14 13:21:29 +03:00
Danila Poyarkov 62f3594819 feat(ai): add visual reference attachments 2026-08-14 12:46:29 +03:00
Danila Poyarkov 631fc25ee6
fix(app): retain recovery after closing unsaved tabs (#505)
* fix(app): retain recovery after closing unsaved tabs

- Persist source-less tab snapshots before disposing editors

- Keep retained snapshots available for startup restore or explicit discard

- Cover close, reload, and restore behavior in Playwright

* fix(app): surface recovery persistence failures

- Propagate explicit close and reload snapshot failures

- Keep background debounce failures logged without unhandled rejections

- Exercise close-time persistence in recovery coverage

* test(app): cover recovery persistence retry

* docs: restore recovery retention note
2026-08-13 21:39:35 +03:00
Danila Poyarkov 6a44aecc24 refactor(ai): isolate reasoning options 2026-08-13 21:18:10 +03:00
Danila Poyarkov 96b030699c fix(ai): apply vision reasoning settings 2026-08-13 21:15:44 +03:00
Danila Poyarkov 8294e32f33 feat(ai): add isolated visual inspection
- Route bounded selection renders through the optional Vision model

- Return compact text findings without retaining image data in Design chat history

- Bound MCP and AI image exports by their longest pixel edge
2026-08-13 21:15:44 +03:00
Danila Poyarkov 6d81d53d1d fix(tauri): preserve HTTP timeout and response semantics
- Apply validated request timeouts without overriding the shared client default

- Preserve abort behavior and null-body response statuses

Co-authored-by: Joseph Cumines <joeycumines@gmail.com>
2026-08-13 20:33:10 +03:00
Danila Poyarkov 1eb1f38c78 feat(text): surface missing font substitutions
- Track loaded font provenance and aggregate page-level face fidelity, including synthesized styles and active Inter substitutions
- Add a localized warning banner with retry and affected-layer actions
- Expose get_font_status through the Figma API and MCP tool registry
2026-08-13 18:33:10 +03:00
Danila Poyarkov f22d2c9bad fix(app): serialize document recovery lifecycle
- Await IndexedDB writes and tab recovery cleanup

- Serialize recovery backend fallback and snapshot adoption

- Preserve queued snapshots when IndexedDB falls back to memory
2026-08-13 17:22:59 +03:00
Danila Poyarkov 7b8e5fbfbe fix(app): harden document recovery lifecycle
- Serialize recovery cleanup with active snapshot writes

- Preserve version ordering across autosave, restore, and cleanup

- Fall back to memory when IndexedDB operations fail
2026-08-13 17:22:59 +03:00
Danila Poyarkov 16b74a2087 refactor(app): standardize IndexedDB access
- Migrate the local canvas store and sync outbox to the typed idb dependency

- Remove the redundant raw IndexedDB promise helpers
2026-08-13 17:22:59 +03:00
Danila Poyarkov 37912d92a7 feat(app): recover unsaved documents
- Persist debounced FIG snapshots for source-less documents in IndexedDB

- Restore or discard orphaned snapshots from the editor startup dialog

- Clear recovery data after successful saves and explicit tab closure
2026-08-13 17:22:59 +03:00
Danila Poyarkov 3a2c8afc3e fix(ai): harden failure diagnostics
- Redact and bound provider error details in copied logs

- Avoid repeat toasts after locale changes

- Show reasoning effort only for supported providers
2026-08-13 15:03:12 +03:00
Danila Poyarkov 9e93884e7f fix(ai): surface silent provider failures
- Report credit and output-limit failures through localized toasts and debug logs

- Persist optional provider-specific reasoning effort on model profiles

- Classify insufficient-credit connection tests and cover failure diagnostics
2026-08-13 15:03:12 +03:00
Danila Poyarkov a8cf8eb412
fix(tauri): prevent Windows font loading crashes (#497)
* fix(tauri): prevent Windows font loading crashes

- Return native font files over binary Tauri IPC instead of JSON byte arrays

- Resolve desktop script fallbacks without parsing large system fonts in JavaScript

* fix(core): restore quality checks

- Use the shared Vector primitive for render-bound offsets

- Remove unsupported SLICE handling from SceneGraph rescaling

- Drop an unused generated-text test binding

* chore: address font fix review

- Place the release note under the Fixed heading

- Name fallback resolution options and use the shared Tauri constant
2026-08-12 20:09:04 +03:00