Commit graph

89 commits

Author SHA1 Message Date
Danila Poyarkov b93ffea073
feat: add Figma-style variants and component libraries (#512)
Closes #239
2026-08-14 19:31:41 +03:00
Danila Poyarkov 7f91594d0c refactor: standardize acronym casing
- Rename first-party API, RPC, JSON, CORS, SVG, JSX, and related identifiers to preserve acronym casing
- Keep upstream and serialized boundary names unchanged
- Add a lint guardrail and migration notes for exported APIs
2026-08-10 15:48:16 +03:00
Danila Poyarkov 751195891f Release v0.14.0 2026-08-10 11:40:44 +03:00
tae.virus 679ee9f98f
feat(export): add editable PPTX export (#416)
- Export text and basic shapes as editable PowerPoint elements
- Rasterize unsupported geometry, effects, masks, and clipped content for fidelity
- Support app and CLI exports across multiple pages

Co-authored-by: TKman <102001532+greekr4@users.noreply.github.com>
2026-07-28 10:12:41 +03:00
Danila Poyarkov 1415640718 refactor(core): centralize Base64 encoding
- Add portable byte and Unicode Base64 helpers backed by js-base64

- Replace manual binary-string, Buffer, and unsupported typed-array conversions

- Cover binary, Unicode, URL-safe, malformed, and large inputs
2026-07-28 08:27:22 +03:00
Danila Poyarkov 2b32a8c7d3 feat(mcp): add local transport discovery
- Prefer private Unix sockets with TCP fallback for local MCP clients

- Unify HTTP and WebSocket lifecycle, authentication, and cleanup

- Discover transport details from an owner-only runtime file
2026-07-25 21:29:03 +03:00
Danila Poyarkov 7124d0045f fix(cli): populate lazy FIG pages
- Populate requested pages for scoped reads and all pages for document-wide operations

- Export whole FIG documents by default while keeping explicit page exports partial
2026-07-22 14:56:58 +03:00
Danila Poyarkov 7ac3ee035d fix(dom-css): compile standalone HTML exports 2026-07-04 19:37:58 +03:00
Danila Poyarkov b22a751f27 Revert "feat(cli): bundle standalone HTML exports"
This reverts commit 8330dda410.
2026-07-04 18:18:32 +03:00
Danila Poyarkov 8330dda410 feat(cli): bundle standalone HTML exports 2026-07-04 18:08:42 +03:00
Danila Poyarkov 3df6cc9bcd feat(cli): add standalone HTML export mode 2026-07-04 14:54:58 +03:00
Danila Poyarkov 8b1c452cc3 refactor(cli): replace DOM command with import and HTML export 2026-07-04 13:34:24 +03:00
Danila Poyarkov 13ef7ac941 feat(cli): export DOM HTML as Tailwind classes 2026-07-04 13:16:21 +03:00
Danila Poyarkov a4272a17bf fix(mcp): target live automation by document and page 2026-07-03 17:05:04 +03:00
Danila Poyarkov 9498dc203d chore(tools): harden package and dependency checks 2026-07-01 12:56:45 +03:00
Danila Poyarkov 898431e646 feat: split SceneGraph and Pen packages 2026-06-30 10:54:32 +03:00
Danila Poyarkov 3638fc11ba feat(cli): import DOM/CSS documents 2026-06-30 10:48:13 +03:00
Joseph Cumines f862beb08d Add heuristic overlap detection tool and CLI
Implement the analyze overlaps CLI command, RPC endpoint, and ToolDef
to enable heuristic detection of visual overlaps, parent overflows, and
overlay patterns. Geometry computation now uses world-matrix visual
bounds to handle nested ancestor rotations and clipping frames correctly.

Update file-backed CLI commands to use Node fs/promises instead of Bun
runtime file APIs. This is required for the published CLI to function
when installed and executed in a standard Node environment. Add the
package.json subpath export to the core package for metadata consumers.
2026-06-19 09:54:27 +10:00
Danila Poyarkov 2dc51375ad Release v0.13.2 2026-05-30 19:14:12 +03:00
Danila Poyarkov 2d4e2a7b10 Release v0.13.1 2026-05-30 01:12:58 +03:00
Danila Poyarkov 6de7cd3871 Release v0.13.0 2026-05-30 00:16:35 +03:00
Danila Poyarkov 883782846f docs(cli): use released openpencil command 2026-05-29 15:56:52 +03:00
Danila Poyarkov abd795bd9a chore: format codebase 2026-05-24 12:15:29 +03:00
Danila Poyarkov 3850be9512 build: publish node-compatible packages 2026-05-21 17:03:19 +03:00
Danila Poyarkov a48b23129f fix(fig): stabilize engine test suite 2026-05-21 14:54:17 +03:00
Danila Poyarkov 12d726eee1 Revert "fix(cli): export fig documents by default"
This reverts commit 682e5991a4bf76753ae22046e952070aaa242de9.
2026-05-21 14:54:16 +03:00
Danila Poyarkov 5830b9f976 fix(cli): export fig documents by default 2026-05-21 14:54:16 +03:00
Danila Poyarkov 7a433584cc Release v0.12.2 2026-05-19 18:10:25 +03:00
Danila Poyarkov 8fa34fb0b8 Release v0.12.1 2026-05-19 13:27:24 +03:00
Danila Poyarkov 682160b75b Release v0.12.0 2026-05-18 21:06:06 +03:00
Danila Poyarkov f3649550f2 chore: enable stricter oxlint rules 2026-05-18 18:58:30 +03:00
Danila Poyarkov c3f5189f8f style: tighten import grouping
- Configure oxfmt custom import groups for workspace, app, package, and test aliases
- Keep type imports grouped with their matching source category instead of one global tail group
- Expand the format script to cover formatter config, Vite files, and scripts
2026-05-06 02:22:08 +03:00
Danila Poyarkov 51eae14e4b chore(tests): remove targeted non-null assertions
- Add shared test helpers for required nodes and child ids
- Clean non-null assertions from noisy render, nudge, text undo, and fig roundtrip tests
- Enforce the non-null assertion ban for the cleaned test files
- Remove stale eslint disables around empty functions and broad mock transport typing
2026-05-06 01:14:50 +03:00
Danila Poyarkov ac15fb143b feat(io): add PDF export
Vector PDF output via jsPDF + svg2pdf.js (lazy-loaded, 124KB gzipped).
Reuses existing SVG export pipeline — text stays selectable, paths
stay sharp at any zoom.

- packages/core/src/io/formats/pdf/ — SVG→PDF conversion module
- export_pdf tool for MCP/AI
- PDF format in IO registry and app export panel
- CLI: bun open-pencil export file.fig --format pdf
2026-05-04 00:18:54 +03:00
Danila Poyarkov b85805e9c7 chore: format sources with oxfmt 2026-05-03 21:03:40 +03:00
Danila Poyarkov 6545f20c53
Refactor architecture boundaries across core, app, and packages (#234)
* refactor(core): decompose editor factory and action modules

Split the monolithic editor factory and large action modules into focused
domain helpers:

- create.ts assembles context through bridge modules (clipboard,
  components, structure, undo) and delegates to graph-reads, graph-events,
  layout-runner, component-sync, and state factory
- structure.ts delegates to group, container-wrap, auto-layout-wrap,
  reorder, and state-toggle helpers
- selection.ts delegates to hit-test, overlays, container navigation,
  and read helpers
- clipboard.ts delegates to subtree-history, images, export, copy,
  fonts, and placement helpers
- shapes.ts delegates to pen actions and section-adopt
- components.ts delegates to focus and instances helpers
- alignment.ts delegates to flip-rotate helper
- text.ts uses explicit TextEditSession for snapshot comparison

New focused modules: nudge, variable-bindings, layout-mode,
page-viewports, tool-registry, color-space

Undo: history/position and history/snapshot helpers, hardened
batch/rollback with nested batch support and configurable limit

* refactor(core): split tool definitions by domain

Split the monolithic tool registry into domain-specific modules:

- read/ — selection, find, pages, fonts, components, nodes, query, jsx
- create/ — basic shapes, components, vector, JSX render
- modify/ — paint, effects, geometry, layout, state, text, update
- structure/ — basic, arrange, batch, hierarchy, replace, tree
- variables/ — bindings, collections, read, values
- vector/ — boolean, path, export, viewport
- analyze/ — colors, typography, spacing, clusters, diff, eval
- describe/ — summaries, tree, roles, layout-issues
- stock-photo/ — providers, requests, apply
- codegen/ — component-map, tokens

Split registry into core/extended tiers; refine schema and AI adapter

* refactor(core): restructure kiwi codec and instance overrides

Reorganize the Kiwi .fig codec into domain subdirectories:

- binary/ — codec, schema, protocol
- fig/ — file, import, parse (core, worker, transfer)
- node-change/ — convert, export-node, serialize, plugin-data
- instance-overrides/ — constraints, dsd, populate, props, resolve,
  symbol-overrides, symbol-props, sync, types

Vendored kiwi-schema/ left isolated

* refactor(core): split profiler, icons, IO, and add subpath exports

Profiler: speedscope-export, capture-session, hud-controller
Icons: api, svg, types, render, create-icons tool
IO: format registry and subpath exports
Canvas/color/text/vector: targeted cleanup

Add deliberate subpath exports: random, xpath, vector, color, canvas,
scene-graph, kiwi, design-jsx, io, tools, editor, layout, canvaskit,
profiler, text, lint, rpc, figma-api, constants

* refactor(vue): decompose canvas input, surface lifecycle, and controls

Canvas surface: gl-surface, kit-loader, render-loop, resize-observer

Canvas input handlers:
- move: drop-target, move-snap, duplicate-drag
- select: select-move, select-hover, select-hit
- resize: resize-rect, resize-vector, resize-start
- transform: rotation, marquee, pan, text-selection
- text-edit: navigation, clipboard, textarea lifecycle
- Shared: click-count, space-key, pan, pan-zoom, draw, raf-scheduler

Editor composition:
- commands split: actions, context, metadata, edit, selection, view
- menu-model split: command-groups, builders, types
- Gradient stop composable reuse in primitive root

Controls: fill, layout, typography, appearance, effects, stroke,
okhcl, prop-scrub, node-props, undo-batch, color-variable-binding
Variables/i18n/document/export helpers

Organize canvas, primitives, controls, editor, and variables into
cohesive module directories with package-local import aliases

Expose MenuActionNode/MenuSeparatorNode from public API

* refactor(app): split document IO, editor session, and automation bridge

Document IO: source-state, naming, writer, reload-source, reload-state,
imported-document, watch-targets, save-targets

Editor session: create, modules, types, accessors, computed, refs
Editor canvas: loader-overlay, collaboration-awareness,
context-selection, menu-actions, menu-model

Automation bridge: eval, tools, exports, files, selection, RPC fallback

AI/ACP: transport, map-update, permission, debug, chat effects/storage
Collab: awareness, graph-bindings, yjs-sync, follow, session, types
Shell keyboard: actions, bindings, clipboard, focus, nudging,
raw-events, registry, reserved, shortcuts, space-tool
Shell menu: app-menu, document-name, entry, files

Demo: colors, effects, helpers, section builders (components,
app-preview, effects, standalone, variables) — document.ts reduced
from 981 to 32 lines as pure orchestrator

Move app modules under src/app/ with organized domain structure:
editor, document, ai, collab, shell, automation, demo, tabs

* refactor(app): decompose UI components with provide/inject context

Split monolithic components using Reka UI-inspired namespace folders
with scoped provide/inject context — no prop drilling:

- CollabPanel/ — context, avatars, share, connected, join
- ColorPickerPanel/ — context, area, format, field groups, sliders
- MobileHud/ — context, action toast, tool badge, file menu, presence
- ProviderSettings/ — context, API key/type, endpoint, tokens, photos
- Toolbar/ — actions, types, desktop, mobile, tool button, flyout
- LayoutSection/ — types, auto-layout, flex, grid, padding, size, clip

Properties helpers: fill-okhcl adapter, fill-label, color-style-row
Menu: entry helpers, document-name rename, stale type removal

* refactor(mcp): split server into focused modules

- browser-rpc — WebSocket client management
- mcp-sessions — session lifecycle
- tool-output — response formatting
- tool-schema — Zod schema generation from ToolDefs
- jsx-preprocess — JSX source transformation
- result — result helpers
- tool-registration — MCP tool wiring
- auth — API key validation
- http-options — CORS/request handling
- stdio-bridge — stdio transport adapter

* refactor(cli): split analyze subcommands and shared helpers

- Analyze subcommands: clusters, colors, spacing, typography
- RPC data loading helper
- Migrate imports to targeted core subpath exports

* refactor(docs): split VitePress config and shared table component

Config helpers: sdk-sidebar, seo, labels, sidebars, locale-theme,
root-theme, locales

Shared SdkDataTable component replaces duplicated table markup in
SdkPropsTable, SdkEventsTable, and SdkSlotsTable

Update contributing and testing docs

* refactor(tauri): decompose desktop entrypoint

Split lib.rs into focused service modules:

- fig_container.rs — .fig archive/compression commands
- fonts.rs — font cache and system font enumeration
- menu.rs — native menu construction
- menu_events.rs — menu event dispatch and devtools toggle
- window.rs — main window show/focus lifecycle

* test: share domain test factories and migrate fixtures

New shared helpers:
- tests/helpers/scene.ts — makeSceneGraph factory
- tests/helpers/vector-network.ts — vertex/segment/network builders
- tests/helpers/fig-traversal.ts — all-node collection, type counts
- tests/helpers/undo.ts — undo test utilities
- tests/helpers/editor-history.ts — editor history test helpers

Migrate render, vector, fig-roundtrip, and undo tests to use shared
factories instead of inline fixture construction

* build: add structural lint rules, split vite config, update docs

Structural lint (oxlint.structure.json + lint/plugin.js):
- 20+ custom rules enforcing package boundaries, lifecycle patterns,
  naming conventions, and import discipline

Vite config split: raw-markdown, canvaskit-assets, pwa, server,
aliases, automation plugins

Remove legacy shims and utils superseded by SDK/core modules
Update AGENTS.md, CONTRIBUTING.md, eval-command docs, tsconfig

* fix(vue): normalize canvas directory casing and remove duplicate export

- Rename Canvas/ to canvas/ in git index to match #vue/canvas/* imports
  (PascalCase was correct for component primitives but canvas/ is a
  non-component domain directory)
- Remove duplicate ./random subpath export in core package.json

* fix: add #vue and #core Vite resolve aliases for dev server

* refactor(core): reduce remaining large modules

Split the remaining large core hotspots into cohesive domain modules while preserving public facades and behavior.

- Extract scene graph types, variables, node defaults, and vector-network helpers
- Decompose canvas renderer orchestration, state, paints, colors, lifecycle, labels, and delegated domain methods into renderer/ and labels/ subfolders
- Split Kiwi node-change, binary variable binding, layout, RPC, vector, JSX export, clipboard, design JSX, and Figma proxy helpers
- Replace collision-driven *Fn import aliases with namespace imports and enforce the pattern in lint

Validation:
- bun run check
- bun --filter @open-pencil/vue build
- bun run test:dupes

* fix(app): forward color input attrs

* fix(app): cover section drawing errors

* fix(editor): undo option-drag duplicates

* docs: document domain subfolder convention

* fix(app): handle undo redo on keydown

* refactor(app): dispatch shortcuts from keydown

* refactor: group prefixed domain modules

* refactor(app): use tinykeys for shortcuts

* refactor(core): group symbol override modules

* refactor(core): group fig kiwi container helper

* refactor(canvas): split overlay rendering modules

* refactor(vue): remove unused internal barrels

* fix(app): lay out demo components before instancing

* fix(app): restore demo badge spacing

* perf(canvas): split scene and overlay rendering

* refactor(vue): wrap wheel gesture lifecycle

* fix(canvas): wait for fonts before hiding loader

* docs: update unreleased changelog
2026-04-30 15:14:19 +03:00
Danila Poyarkov ba414e1af7 Release v0.11.8 2026-04-23 16:15:37 +03:00
Danila Poyarkov f3dbf2c271 Release v0.11.7 2026-04-22 20:31:33 +03:00
Danila Poyarkov c2a43234a3 fix(cli): remove inline examples from query description
The multi-line description caused citty to pad every other command's
row to the same height, creating huge vertical gaps in --help output.

Fixes #219
2026-04-22 13:53:03 +03:00
Danila Poyarkov 714390b54b feat: copy node ID / XPath from context menu, CLI selection command
Add nodeToXPath() to core — builds a unique XPath selector for any node
by walking up the tree and using name predicates (or positional index
when names collide among same-type siblings). Properly escapes names
containing quotes using XPath concat() or double-quote delimiters.

UI: "Copy node ID" and "Copy XPath" items in the canvas right-click
"Copy/Paste as" submenu. Also i18n the entire submenu — all labels now
use menuMessages with translations for de, es, fr, it, pl, ru, zh-CN.

CLI: `open-pencil selection` command (app-mode only) returns selected
nodes with id, name, type, size, and xpath. Connects to the running
app via the automation WebSocket.

Automation: new `selection` RPC handler that returns selected nodes
with computed XPath selectors.
2026-04-15 10:09:52 +03:00
Danila Poyarkov f8f4af5937 Release v0.11.6 2026-04-08 22:04:22 +03:00
Danila Poyarkov 2c3191cf96 Release v0.11.5 2026-04-08 21:38:44 +03:00
Danila Poyarkov 26a7d2d454 Release v0.11.4 2026-04-08 20:52:09 +03:00
Danila Poyarkov a20d170956 Release v0.11.3 2026-04-08 16:06:37 +03:00
Danila Poyarkov 943995fb70 Fix MCP auth, collab state, and export bounds 2026-04-01 21:27:04 +03:00
Danila Poyarkov 33d293b221 Release v0.11.2 2026-03-30 18:38:36 +03:00
Danila Poyarkov 9be3514f2b Release v0.11.1 2026-03-30 17:24:00 +03:00
Danila Poyarkov 911bed3ede Release v0.11.0 2026-03-30 16:48:27 +03:00
Danila Poyarkov c57e636dcb Port design linter from figma-use 2026-03-28 16:33:40 +03:00
Danila Poyarkov 0001802dda Add shared IO format registry 2026-03-28 01:58:05 +03:00