Danila Poyarkov
9f8242bce5
Add download links to README, docs landing, and getting started
2026-03-01 16:32:45 +03:00
Danila Poyarkov
fb8891c431
Fix case-sensitive filename: ApiKeySetup.vue → APIKeySetup.vue
2026-03-01 16:29:54 +03:00
Danila Poyarkov
0acfd50a67
Add npm publish with trusted publishing to release workflow
2026-03-01 16:27:41 +03:00
Danila Poyarkov
1e873d64b1
Add repository field and provenance to package configs
2026-03-01 16:23:30 +03:00
Danila Poyarkov
c4e6514ea2
Update repo references to open-pencil/open-pencil
2026-03-01 16:18:11 +03:00
Danila Poyarkov
74d4b6862e
Use app favicon for docs site (symlink to public/favicon-32.png)
2026-03-01 16:14:06 +03:00
Danila Poyarkov
baee65e599
Add CHANGELOG.md, update build workflow for v0.1.0-alpha
...
- Add Linux x64 build target
- Add patchelf for Linux AppImage builds
- Release body links to CHANGELOG.md
- Release name includes 'OpenPencil' prefix
2026-03-01 16:09:25 +03:00
Danila Poyarkov
515c8125ed
Add app and docs links to README
2026-03-01 16:03:25 +03:00
Danila Poyarkov
10848d8319
Add app.openpencil.dev links to docs
2026-03-01 16:02:08 +03:00
Danila Poyarkov
268c4029e9
Add CI workflow for app.openpencil.dev deploy
2026-03-01 16:00:19 +03:00
Danila Poyarkov
0f0ca8db4b
Update screenshot, remove duplicate from repo root
...
Single screenshot lives in packages/docs/public/. README references it
from there. Custom VitePress layout places it between hero and features.
2026-03-01 15:57:01 +03:00
Danila Poyarkov
503a561753
Symlink favicons from desktop/icons, add all sizes for Safari/Chrome
...
.ico (any), 32px PNG, 128px PNG, apple-touch-icon (512px).
Symlinks instead of copies so icons stay in sync.
2026-03-01 15:46:31 +03:00
Danila Poyarkov
f8f85970e1
Add favicon, persist banner dismissal in localStorage
2026-03-01 15:44:25 +03:00
Danila Poyarkov
c8af1c35e7
Improve Save for browsers without File System Access API
...
- Save As prompts for filename via prompt() before downloading
- Save reuses the filename from last Save As (no repeated prompts)
- Banner in Safari/Firefox explaining the limitation with Chrome link
- Banner is dismissible
2026-03-01 15:41:27 +03:00
Danila Poyarkov
c886daded2
Fix .fig export: map COMPONENT/COMPONENT_SET to SYMBOL (Kiwi enum)
...
The Kiwi binary schema uses SYMBOL (15) for components, not COMPONENT.
Import already mapped SYMBOL→COMPONENT; export now reverses it.
2026-03-01 15:35:20 +03:00
Danila Poyarkov
1e1feb9cb0
Merge branch 'add-vitepress-docs'
2026-03-01 15:32:45 +03:00
Danila Poyarkov
22f8599408
Fix Save in Safari: append <a> to DOM, defer revokeObjectURL
...
Safari requires the <a> element to be in the document for .click()
downloads to work. Also defers URL.revokeObjectURL by 100ms so the
browser has time to start the download. Extracted shared downloadBlob
helper used by both file save and image export fallbacks.
2026-03-01 15:31:56 +03:00
Danila Poyarkov
ca20bfb2ac
Fix layers-panel tests: match current demo shapes (Components, App Preview)
2026-03-01 15:28:13 +03:00
Danila Poyarkov
20290f61b5
Add integration tests for app menu and autosave
...
9 app-menu tests: menu visibility, all 6 submenus content, Undo/Duplicate/
Zoom to fit via menu actions.
2 autosave tests: write triggers after scene change with mock file handle,
no write without file handle.
2026-03-01 15:26:10 +03:00
Danila Poyarkov
90e47e07ab
Add autosave: debounced write 3s after last scene change
...
Triggers only when a file handle (browser File System Access API) or
file path (Tauri) exists. Tracks savedVersion to skip redundant writes.
Silent failure — user can always save manually.
2026-03-01 15:17:03 +03:00
Danila Poyarkov
96d8ab5789
Move docs to packages/docs, add Cloudflare Pages deploy
...
- Move docs/ → packages/docs/ as @open-pencil/docs workspace package
- Add screenshot.png as hero image on landing page
- Add GitHub Actions workflow for Cloudflare Pages deploy (openpencil.dev)
- Remove vitepress from root devDependencies
- Root docs:* scripts delegate via bun --filter
2026-03-01 15:16:16 +03:00
Danila Poyarkov
7809fb60f9
Add app menu bar for browser mode (File, Edit, View, Object, Text, Arrange)
...
Reka-ui Menubar in the left panel header, hidden when running in Tauri
(native menu handles it). Includes Open, Save, Save As, Export, Undo/Redo,
Zoom, Group/Ungroup, Component creation, Bring to front/Send to back,
Auto layout, Text formatting, Alignment.
2026-03-01 15:09:08 +03:00
Danila Poyarkov
3849872b32
Unify tool definitions: define once, adapt for AI/CLI/MCP
...
Move tool logic to @open-pencil/core/tools/schema.ts as framework-agnostic
ToolDef objects. AI adapter generates valibot schemas + Vercel AI tool()
wrappers automatically.
26 tools (was 10): create_shape, render (JSX), set_fill, set_stroke,
set_effects, set_layout, set_constraints, update_node, delete, clone,
rename, reparent, group/ungroup, find_nodes, get_node, get_page_tree,
get_selection, select, list_pages, switch_page, list_variables,
list_collections, create_component, create_instance, eval.
src/ai/tools.ts: 269→28 lines (adapter only).
Tests for all 3 interfaces:
- 26 core tool tests (FigmaAPI directly)
- 11 AI adapter tests (valibot + Vercel AI SDK tool())
- 12 CLI integration tests (eval command on .fig fixture)
323 total, all passing.
2026-03-01 15:02:05 +03:00
Anton A S
5b7de9fe99
Sync docs with README motivation: landing, features, comparison, user guide
2026-03-01 13:58:54 +03:00
Danila Poyarkov
f22bd2e133
Merge eval-command: Figma Plugin API + eval CLI command
...
FigmaAPI wraps SceneGraph with Figma-compatible interface (Symbol-hidden internals).
CLI eval command runs Plugin API scripts headless on .fig files.
106 new tests (60 figma-api + 17 cli integration + 29 gap-filling).
2026-03-01 13:55:39 +03:00
Danila Poyarkov
123dbe491b
Extract DEFAULT_STROKE_MITER_LIMIT constant
2026-03-01 13:53:25 +03:00
Anton A S
2b5f6d58c0
Merge remote-tracking branch 'origin/master' into add-vitepress-docs
2026-03-01 13:51:56 +03:00
Anton A S
5eb1b30390
Separate User Guide sidebar scope, remove redundant shortcut notes
2026-03-01 13:51:31 +03:00
Danila Poyarkov
3e9cd236e9
Fix bogus fig-import mappings: expanded and strokeMiterLimit
...
expanded: was mapped from frameMaskDisabled (unrelated Kiwi field),
now defaults to true. strokeMiterLimit: was mapped from speculative
strokeMiterAngle field that doesn't exist in Kiwi codec, now uses
hardcoded default 4.
2026-03-01 13:48:48 +03:00
Danila Poyarkov
48219af2fb
Fill Figma Plugin API gaps: 29 new tests, 30+ new properties and methods
...
SceneNode: add minWidth/maxWidth/minHeight/maxHeight, isMask, maskType,
counterAxisAlignContent, itemReverseZIndex, strokesIncludedInLayout,
expanded, textTruncation, autoRename, strokeMiterLimit. All with defaults
and .fig import mapping.
FigmaNodeProxy: add clone(), strokeCap, strokeJoin, strokeMiterLimit,
strokeTopWeight/BottomWeight/LeftWeight/RightWeight, minWidth/maxWidth/
minHeight/maxHeight, isMask, maskType, expanded, textTruncation,
autoRename, insertCharacters, deleteCharacters, primaryAxisSizingMode,
counterAxisSizingMode, counterAxisAlignContent, itemReverseZIndex,
strokesIncludedInLayout, layoutAlign, findAllWithCriteria.
FigmaAPI: add createComponentFromNode, getVariableById, getLocalVariables,
getLocalVariableCollections, getVariableCollectionById.
Fix layoutSizingHorizontal/Vertical for self-framing auto-layout nodes
with no auto-layout parent — now checks the node's own layoutMode.
2026-03-01 13:35:02 +03:00
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