Danila Poyarkov
2a3e848e3b
Deduplicate AI tools: use FigmaAPI.toJSON() and core parseColor
...
- get_page_tree: replace hand-rolled nodeToJSON with FigmaAPI.wrapNode().toJSON()
- get_selection: same — use FigmaAPI proxy serialization
- resolveColor: delegate hex parsing to core parseColor() (culori) instead of manual parseInt
2026-03-01 13:20:01 +03:00
Danila Poyarkov
b6e792846f
Harden FigmaAPI: hide internals via symbols, freeze arrays, fix layoutSizing
...
- Replace _id/_graph/_api with Symbol-keyed properties so eval scripts
can't access SceneGraph internals directly
- fills/strokes/effects return frozen structuredClone copies
- Fix currentPage getter to define selection only once per proxy
- Fix layoutSizingHorizontal/Vertical: respect parent layout direction
even when the node itself is an auto-layout frame
- Add 6 new tests: layoutSizing, frozen arrays, internals not exposed
2026-03-01 13:12:26 +03:00
Danila Poyarkov
9a7d170887
Add 17 CLI integration tests for eval command
...
Tests cover: page name, primitives, findAll queries, node creation,
auto-layout, text, top-level await, stdin piping, JSON output,
syntax/runtime errors, no-code error, undefined output, --output write,
array serialization, getNodeById on real .fig files.
2026-03-01 13:07:06 +03:00
Anton A S
de048b4d21
Add User Guide section with 11 articles derived from OpenSpec specs
...
New docs/user-guide/ section covering: canvas navigation, selection &
manipulation, drawing shapes, text editing, pen tool, layers & pages,
context menu, exporting, auto-layout, components, and variables.
Each article includes Mac+Win/Linux shortcuts tables, cross-platform
note, cross-links between related articles, and consistent structure.
VitePress sidebar updated with User Guide as first group (12 entries).
2026-03-01 13:02:47 +03:00
Danila Poyarkov
b41424dd84
Add motivation to README: why OpenPencil exists
2026-03-01 12:58:13 +03:00
Anton A S
15abce330f
Sync specs & docs: AI chat, Code panel, JSX export
...
- Merge from master: 19 commits (AI chat + Code tab)
- Update specs: editor-ui (Properties panel → Design|Code|AI tabs,
AI chat panel, model selector, 10 AI tools, DirectChatTransport,
Code panel with JSX export), scene-graph (sceneNodeToJsx),
testing (AI chat Playwright, 14 JSX export tests)
- Update docs: features (AI Chat + Code Panel sections, Properties
Panel tabs), figma-comparison (AI tools 🟡 , Dev Mode 🟡 ,
Code snippets 🟡 , 83/150), roadmap (Phase 5 AI + Code),
keyboard-shortcuts (⌘J ✅ , ⌘B/I/U ✅ )
- Archive sync-ai-chat-code-tab change
2026-03-01 12:33:57 +03:00
Anton A S
fbb397ad45
Merge remote-tracking branch 'origin/master' into add-vitepress-docs
2026-03-01 12:26:10 +03:00
Danila Poyarkov
0cba4fb4b7
Add FigmaAPI + eval CLI command with 60 unit tests
...
FigmaAPI in @open-pencil/core provides a Figma Plugin API-compatible
interface backed by SceneGraph. Covers node creation, property access,
tree operations, auto-layout, text, traversal, grouping, components,
selection, and serialization.
CLI: bun open-pencil eval <file> --code 'figma.createFrame()'
2026-03-01 12:21:07 +03:00
Danila Poyarkov
63748ecee6
Plan: eval command with Figma-compatible plugin API
2026-03-01 12:13:31 +03:00
Danila Poyarkov
c59d5fc397
Add Code tab with JSX export and syntax highlighting
...
- sceneNodeToJsx() in @open-pencil/core: converts SceneNode subtree to JSX
- CodePanel.vue with Prism.js highlighting, line numbers, copy button
- Third tab in properties panel: Design | Code | AI
- 14 new tests covering shapes, text, layout, effects, multi-selection
2026-03-01 12:12:45 +03:00
Anton A S
5fbad7b092
Sync specs & docs: style runs, JSX renderer, CLI expansion, tests
...
- Merge from master: 22 commits (rich text, JSX renderer, CLI, dedup, tests)
- Update specs: text-editing (style runs, ⌘B/I/U, .fig roundtrip,
double/triple-click, selectLine), canvas-rendering (mixed-style
ParagraphBuilder), editor-ui (B/I/U/S buttons), cli (analyze, node,
pages, variables), tooling (jscpd, kiwi-serialize, test:coverage),
testing (.fig roundtrip, import perf, JSX tests), scene-graph
(StyleRun model, JSX renderer)
- Update docs: features (rich text formatting, JSX renderer, expanded
CLI, code quality), figma-comparison (Text styles 🔲 →🟡 , 80/150),
roadmap (Phase 4+5 delivered items)
- Archive sync-style-runs-jsx-cli-tests change
2026-03-01 12:09:41 +03:00
Anton A S
37e1ba1caa
Merge remote-tracking branch 'origin/master' into add-vitepress-docs
2026-03-01 11:56:06 +03:00
Danila Poyarkov
bf8636c677
Merge chat-panel: AI chat with OpenRouter, tool execution, model selector
2026-03-01 11:55:57 +03:00
Danila Poyarkov
91a6f599fa
Remove chat avatars
2026-03-01 11:54:04 +03:00
Danila Poyarkov
921a9cd261
Fix tool name extraction from UIMessage parts, add tool call e2e test
...
Tool part type is 'tool-create_shape' (name embedded in type field),
not a separate toolName property. Extract via part.type.replace('tool-', '').
Mock transport now emits proper UI message stream protocol:
tool-input-start → tool-input-delta → tool-input-available → tool-output-available.
2026-03-01 11:51:38 +03:00
Danila Poyarkov
873671baeb
Fix valibot transform incompatible with JSON Schema serialization
...
Move hex→RGBA conversion from v.transform() (which can't be serialized
to JSON Schema for the LLM) to a resolveColor() helper called in execute.
2026-03-01 11:46:52 +03:00
Danila Poyarkov
f06631489f
Wire AI tools to editor store with valibot schemas
...
10 tools: create_shape, set_fill, set_stroke, update_node, set_layout,
delete_node, select_nodes, get_page_tree, get_selection, rename_node.
Uses @ai-sdk/valibot for schema integration with ToolLoopAgent.
2026-03-01 11:45:27 +03:00
Danila Poyarkov
4032108be0
Move AI models to @open-pencil/core constants, add Kimi K2.5 (vision+code), benchmark-ranked tags
2026-03-01 11:38:40 +03:00
Danila Poyarkov
6268d8b119
Fix double/triple-click text selection
...
- Track click count with timing/proximity in onMouseDown
- Double-click in text: select word (was only handled in dblclick)
- Triple-click in text: select all
- Double-click to enter editing: select word at click position
- Add selectLine/selectLineAt to TextEditor
2026-03-01 11:36:49 +03:00
Danila Poyarkov
9b59d8e816
Update model list to current versions (Claude 4.6, Gemini 3.1, GPT-5.3, DeepSeek V3.2, Qwen 3.5)
2026-03-01 11:34:38 +03:00
Danila Poyarkov
299b668e7b
Show selected model name in selector trigger
2026-03-01 11:33:12 +03:00
Danila Poyarkov
f6434bc4f9
Fix chat reactivity (markRaw), add Playwright tests with mock transport
...
Use markRaw to prevent Vue from deep-proxying the Chat class
instance, which broke its internal Vue refs. Add dedent for
multiline prompts.
Tests use mock transport by default. Set TEST_REAL_LLM=1 and
OPENROUTER_API_KEY to run against real OpenRouter.
2026-03-01 11:30:30 +03:00
Danila Poyarkov
20827a27d3
Deduplicate fig-kiwi parsing, font weight mapping, layout, style runs, text editor
...
- Extract buildFigKiwi, parseFigKiwiChunks, decompressFigKiwiDataAsync to kiwi-serialize.ts
- Unify styleToWeight across fonts.ts, fig-import.ts, src/engine/fonts.ts
- Merge applyYogaLayout + applyYogaLayoutNested into single recursive fn
- Extract expandRuns helper in style-runs.ts
- Add prepareMove helper to TextEditor for selection extension boilerplate
jscpd: 18 → 9 clones, 1.7% → 0.62%
2026-03-01 11:29:26 +03:00
Danila Poyarkov
c18ced5dcf
Rename ApiKeySetup → APIKeySetup
2026-03-01 11:12:37 +03:00
Danila Poyarkov
c08cbe5c0f
Split ChatPanel into ChatMessage, ChatInput, ApiKeySetup
2026-03-01 11:11:46 +03:00
Danila Poyarkov
e3ae61e99d
Consolidate font weight mapping and FIG_KIWI_VERSION
2026-03-01 11:08:59 +03:00
Danila Poyarkov
f0c482ac5c
Add model selector with curated list (Claude, Gemini, GPT, DeepSeek, Llama)
2026-03-01 11:08:47 +03:00
Danila Poyarkov
61cd018353
Fix empty state vertical centering in chat panel
2026-03-01 11:05:09 +03:00
Danila Poyarkov
2145af5280
Use reka-ui Tabs/ScrollArea/Collapsible/Tooltip, tw-animate-css, vue-stream-markdown
2026-03-01 11:03:51 +03:00
Danila Poyarkov
f92a8835f4
Deduplicate kiwi and serialization code
...
Replace src/kiwi/ copies with re-exports from @open-pencil/core.
Extract shared sceneNodeToKiwi into kiwi-serialize.ts, used by
both fig-export.ts and clipboard.ts.
jscpd: 15.6% → 1.7% duplication (35 → 18 clones, -4459 lines)
2026-03-01 10:59:35 +03:00
Danila Poyarkov
9235a75e6f
Report app name to OpenRouter via X-OpenRouter-Title header
2026-03-01 10:58:22 +03:00
Danila Poyarkov
b10785fdee
Extract DesignPanel from PropertiesPanel
2026-03-01 10:55:52 +03:00
Danila Poyarkov
bf5c905134
Move AI chat to Design/AI tab in properties panel
2026-03-01 10:54:51 +03:00
Danila Poyarkov
46bb9230d3
Add jscpd for copy-paste detection
2026-03-01 10:49:09 +03:00
Danila Poyarkov
a32d80f448
Deduplicate render internals: shared resolveToTree, remove dead code
2026-03-01 10:45:39 +03:00
Danila Poyarkov
13f562adc6
JSX renderer in @open-pencil/core
...
TreeNode builder functions (Frame, Text, Rectangle, etc.) produce a
lightweight tree structure. Two rendering paths:
- renderTreeNode(): tree → scene graph (browser, no deps)
- renderJsx(): JSX string → esbuild → tree → scene graph (CLI/headless)
Tailwind-like shorthand props: w/h, bg, rounded, flex, gap, p/px/py,
justify, items, shadow, blur, etc.
27 tests covering all node types, layout props, effects, and nesting.
2026-03-01 10:42:06 +03:00
Danila Poyarkov
6bc3f7c50d
Use git push --no-verify for LFS, drop custom alias
2026-03-01 10:41:16 +03:00
Danila Poyarkov
dc602b0731
Document git qpush alias for fast LFS-skipping pushes
2026-03-01 10:39:57 +03:00
Danila Poyarkov
cae260c178
Document LFS skipverify setting
2026-03-01 10:36:00 +03:00
Danila Poyarkov
ca422147b4
Add .fig roundtrip tests: real file parsing, property invariants, encode/decode cycle
2026-03-01 10:33:58 +03:00
Danila Poyarkov
5d23c3e834
AI chat panel with ⌘J toggle, DirectChatTransport, OpenRouter
...
- ChatPanel.vue: message list, tool timeline, typing indicator, API key setup
- use-chat.ts: Chat + DirectChatTransport + ToolLoopAgent (no backend)
- App.vue: toggle between PropertiesPanel and ChatPanel in same splitter slot
- ⌘J keyboard shortcut to open/close chat
2026-03-01 10:31:57 +03:00
Danila Poyarkov
cc5dda29d9
AI chat: no backend, direct OpenRouter from browser, Stronghold for key storage
2026-03-01 10:23:53 +03:00
Danila Poyarkov
7dcc5822f8
Merge cli-commands: analyze, node, pages, variables commands
2026-03-01 10:19:46 +03:00
Danila Poyarkov
9873580a04
Reference plan.md from AGENTS.md
2026-03-01 10:19:38 +03:00
Danila Poyarkov
f1806f6f33
Add test:coverage script
2026-03-01 10:19:38 +03:00
Danila Poyarkov
36e3f14ac4
CLI: add analyze, node, pages, and variables commands
...
- analyze colors: color palette usage with clustering
- analyze typography: font/size/weight distribution
- analyze spacing: gap/padding values with grid check
- analyze clusters: repeated patterns (potential components)
- node: detailed properties by ID
- pages: list pages with node counts
- variables: list design variables and collections
2026-03-01 10:19:38 +03:00
Danila Poyarkov
9b97346aa2
Remove .env from tracking, add to .gitignore
2026-03-01 10:14:48 +03:00
Danila Poyarkov
017b0aa3c1
Move AI chat design into plan.md Phase 5
2026-03-01 10:14:40 +03:00
Danila Poyarkov
af6a98ca56
AI chat: JSX-first rendering, guardrail tools, workflow from figma-use
2026-03-01 10:12:01 +03:00
Danila Poyarkov
4fb929073a
AI chat design document
2026-03-01 10:09:09 +03:00