Commit graph

904 commits

Author SHA1 Message Date
xemc 7dc46bb993 feat(figma-api): add exposeInstanceSwap for real instance-swap component properties
Adds figma.exposeInstanceSwap(slots, candidates, propertyName), which
exposes one or more nested instances as an instance-swap slot — the
enclosing component (or component set, walking up past intermediate
variant members) gets an INSTANCE_SWAP property offering the given
candidates, and each slot instance is tagged to respond to it. Mirrors
Figma's "Create component property > Instance swap", letting a designer
pick which component fills a slot (e.g. an icon on a button) instead of
the slot being baked-in static content.

Exposed as the expose_instance_swap MCP/CLI/chat tool.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-29 16:30:42 +03:00
PAVEL TKACHEV d178a7fd70
feat(app): add language picker to General settings
* feat(app): add language picker to General settings

- Reuse the persisted locale setting in General settings
- Localize the setting description across supported languages
- Cover immediate switching and reload persistence

* test(app): verify persisted language selection

---------

Co-authored-by: Danila Poyarkov <dev@dannote.net>
2026-08-29 16:01:03 +03:00
Danila Poyarkov 33baf1eb7f style(figma-api): format component conversion test 2026-08-29 15:47:43 +03:00
Danila Poyarkov 7fdf3952a2 merge: sync component sizing fix with master 2026-08-29 15:42:24 +03:00
Danila Poyarkov cbfc93f9bc test(figma-api): cover padding after component conversion 2026-08-29 15:40:25 +03:00
Danila Poyarkov 38bee364e8
refactor(tools): organize internal CLI workflows (#600)
* refactor(tools): organize internal CLI workflows

- Group visual-oracle commands behind a Citty CLI and domain folders\n- Add imported-document visual comparison manifests and pixel-diff outputs\n- Consolidate package-quality checks behind stable check, smoke, and verify commands\n- Remove obsolete visual root aliases and compatibility scripts

* fix(tools): validate visual oracle target scope

- Validate manifest records, required strings, and optional field types\n- Reject explicit OpenPencil nodes outside the configured page

* fix(tools): validate packaged runtime exports
2026-08-29 14:42:44 +03:00
Danila Poyarkov 8408b56721
refactor(app): modernize browser clipboard adapter (#601)
* refactor(app): isolate system clipboard adapters

- Split browser and Tauri clipboard behavior into focused adapters\n- Inject browser clipboard capabilities into unit-testable operations\n- Remove navigator and document mutation from headless clipboard tests

* refactor(app): delegate browser clipboard fallbacks

- Use copy-to-clipboard for modern rich MIME writes and execCommand fallback\n- Keep OpenPencil-specific HTML and plain-text payload construction at the adapter boundary\n- Remove hand-rolled browser capability and selection handling

* test(clipboard): verify rich browser menu round-trip

- Exercise copy from the browser Edit menu under a user gesture\n- Verify text/html and text/plain ClipboardItem formats\n- Paste the system clipboard payload back into the canvas

* refactor(clipboard): reduce adapter surface

- Expose only command dispatch and the injectable system clipboard contract\n- Keep browser and Tauri copy/paste operations private to their adapters\n- Rename the in-memory DataTransfer fallback and share design HTML recognition

* fix(clipboard): harden format and fallback handling

- Require complete OpenPencil or Figma clipboard markers\n- Await browser writes so adapter failures resolve false\n- Write plain-only Tauri payloads as text and reject unrelated clipboard text

* fix(clipboard): reject unrelated current browser data

* fix(clipboard): bind fallbacks to copied selection

- Match cached rich HTML to the current Tauri plain-text fallback\n- Preserve nodes when selection changes during an asynchronous cut\n- Reject unrelated current browser HTML before consulting memory

* fix(clipboard): reuse the shared memory payload type

* fix(clipboard): scan design markers linearly

* fix(clipboard): distinguish unavailable and empty reads

* style(clipboard): use includes for marker closure

* test(clipboard): avoid wall-clock marker assertions
2026-08-28 14:37:42 +03:00
xemc 1fd7990cd9 fix(figma-api): preserve auto-layout sizing mode when converting a node to a component
createComponentFromNode copied only a hand-picked list of fields onto the
new COMPONENT node, omitting primaryAxisSizing/counterAxisSizing. A HUG-sized
auto-layout frame silently reverted to FIXED sizing on conversion, so later
padding changes no longer resized the frame (itemSpacing still worked since
it doesn't affect the frame's own size).
2026-08-26 10:17:07 +10:00
Mikel Cabezas 7a311677cc
fix(editor): harden clipboard fallbacks
Merges the contributor clipboard fallback fix with maintainer follow-ups for browser cut safety and isolated fallback tests. Selections are preserved when clipboard serialization fails, and clipboard fallback tests no longer depend on host APIs.
2026-08-24 19:16:16 +03:00
Sergio Bernal b65b1bd481
fix(chat): treat MCP results with optional isError correctly
Merges the contributor fix with maintainer follow-up coverage. MCP results now treat omitted isError as success, scope detection to mcp__ tools, and preserve generic tool error handling.
2026-08-24 18:18:02 +03:00
Danila Poyarkov 5f8a373b2b
feat(diagnostics): add local usage and diagnostics foundation
Supersedes #572. Adds local structured AI usage and diagnostics history, typed diagnostic events, localized Usage/Diagnostics settings, shared IndexedDB lifecycle, and consolidated button/dialog primitives.
2026-08-24 16:56:40 +03:00
Danila Poyarkov bb8c5c18d9
fix(editor): commit vector drags on pointer release (#586)
* fix(editor): commit vector drags on pointer release

- Commit vertex and Bézier handle edits immediately on release\n- Rebase active vector-edit state after graph commits\n- Use vector-specific input paths and cover Pen-created Bézier drags

* test: reduce visual snapshot scope

- Replace behavior screenshots with scene assertions\n- Capture renderer fixtures from bounded canvas regions\n- Remove obsolete full-viewport snapshots

* fix(vector): harden edit cancellation and endpoint remapping

- Restore temporary vector geometry on cancelled pointer drags\n- Commit Bézier handle releases consistently and guard stale handle state\n- Preserve valid endpoint indices when connecting vector vertices

* fix(vector): cancel bend drags and satisfy formatting

* fix(vector): guard stale handle references

* fix(vector): guard stale overlay handle indices

* fix(vector): validate overlay handle keys

* refactor(vector): use typed handle selection ids

* test(vector): align typed handle selection coverage
2026-08-24 16:02:27 +03:00
Danila Poyarkov f75d67ad4d
feat(app): make crash recovery configurable
* feat(app): make crash recovery configurable

- Add an enabled-by-default persisted recovery preference and General settings control
- Stop recovery writes and remove the active document snapshot when disabled
- Suppress startup recovery discovery while the preference is disabled
- Cover disabled persistence and re-enable behavior

* fix(i18n): translate recovery preferences

* fix(app): serialize recovery disable cleanup

- Block re-enabled persistence until pending snapshot removal completes
- Preserve disable generations so stale cleanup cannot reset newer recovery state
- Display runtime-overridden recovery state in Settings
- Deep-clone nested preferences before updating recovery
2026-08-21 18:58:27 +03:00
Danila Poyarkov 0f981ff2af fix(mcp): isolate Portless development routes
- Register the Vite-owned MCP child as a worktree-prefixed Portless sibling service\n- Inject HTTPS and WebSocket automation URLs into the browser instead of assuming port 7600\n- Isolate development socket and discovery files while preserving fixed-port non-Portless flows
2026-08-21 08:14:04 +03:00
Danila Poyarkov 22c98e28c8 Merge origin/master into agent/mcp-automation-settings
# Conflicts:
#	src/views/EditorView.vue
2026-08-20 18:48:44 +03:00
Danila Poyarkov 9c4d188ea4 refactor(mcp): keep disabled tools typed across boundaries
- Carry normalized tool-name arrays through app and development JSON configuration

- Serialize the legacy CSV format only at child-process environment boundaries

- Bound, validate, trim, and deduplicate development tool policy input
2026-08-20 18:44:44 +03:00
Danila Poyarkov d7000b6c43 fix(app): preserve browser editor entry flow
- Keep browser root routes compatible with existing editor workflows
- Open the files workspace explicitly from browser navigation while desktop still starts on New tab
- Show storage setup guidance when the unified workspace is not configured
2026-08-20 17:20:33 +03:00
Danila Poyarkov bb5960cd62 refactor(app): polish files workspace and New tabs
- Keep New tabs provisional so opening or creating a design reuses the active tab
- Separate recent document, storage, menu, worker, and workspace responsibilities
- Add source-aware recents, responsive files UI, loading states, and localized copy
- Preserve native local Open Recent behavior while supporting remote storage history
2026-08-20 17:20:33 +03:00
Danila Poyarkov 376447a5dd Merge remote-tracking branch 'origin/master' into pr-550-push-integration
# Conflicts:
#	CHANGELOG.md
2026-08-20 17:20:25 +03:00
Danila Poyarkov fad731b3e7 fix(mcp): align runtime metadata and restart errors
- Publish explicit effective tool state while retaining disabled tools for Settings

- Classify filesystem writes as side effects and localize category labels

- Stop failed restarts and return precise development control status codes
2026-08-20 16:27:11 +03:00
Danila Poyarkov 7955207146 Merge origin/master into agent/mcp-automation-settings 2026-08-20 16:02:26 +03:00
Danila Poyarkov b9bdc043f7 fix(app): harden MCP configuration controls
- Parse bounded UTF-8 development configuration and await forced child exits

- Keep native folder selection behind the Tauri boundary

- Align Settings controls with read and write effects
2026-08-20 15:55:48 +03:00
Danila Poyarkov 25d7889ab2 refactor(app): make MCP runtime lifecycle explicit
- Encapsulate app-global runtime state in a testable service

- Serialize health refresh, start, stop, and restart operations

- Validate health metadata and clean state after failures
2026-08-20 15:55:48 +03:00
Danila Poyarkov 4a8714377e refactor(mcp): model tool effects and capabilities
- Remove duplicated document-access declarations from core tools

- Replace the MCP catalog with typed descriptors, capabilities, and policy

- Emit standard MCP annotations through type-safe registration
2026-08-20 15:55:48 +03:00
Danila Poyarkov dc8367921b test(canvas): cover selected frame guide scope 2026-08-20 15:17:46 +03:00
Danila Poyarkov 47026f82a0 fix(canvas): preserve frame guide measurement ownership 2026-08-20 15:08:18 +03:00
Danila Poyarkov 2bc89c311d feat(canvas): add Figma guide feedback parity 2026-08-20 14:02:33 +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 5acc2235c6 fix(canvas): polish guide ruler interactions 2026-08-20 08:56:33 +03:00
Danila Poyarkov 3497aef818 refactor(canvas): normalize guide domain naming 2026-08-20 08:47:33 +03:00
Danila Poyarkov 27ad48b365 refactor(canvas): separate guide and overlay pipelines 2026-08-20 08:41:16 +03:00
Victor Wads 67b534609d
fix(mcp): apply Settings preferences in development
- Restart the Vite-managed MCP server with the current authentication, root, and tool settings
- Keep the development control endpoint protected by the local token
- Cover explicit no-auth and configured-root environment propagation
2026-08-20 00:56:57 -03:00
Victor Wads d3bbd29ac2
fix(mcp): address automation review feedback
- Serialize runtime lifecycle operations and connect only after health checks

- Identify externally managed servers and disable misleading restart controls

- Cover enable-all behavior and sync MCP settings locale keys
2026-08-20 00:33:39 -03:00
Victor Wads 4db24bd124
feat(mcp): allow disabling local authentication
- Persist whether the desktop MCP server requires a bearer token
- Start localhost MCP without a generated token when authentication is disabled
- Warn in Settings and require a server restart to apply the preference
2026-08-20 00:27:33 -03:00
Victor Wads 6a78da9eb0
refactor(mcp): derive catalog from registration
- Collect tool metadata through the existing registration wrapper
- Expose the runtime catalog to Settings without a parallel MCP-only list
- Keep disabled tools discoverable so they can be re-enabled
2026-08-20 00:27:13 -03:00
Victor Wads d807828270
feat(mcp): classify tool document access
- Declare inspection or modification access on every canonical tool definition
- Add bulk category controls while preserving individual disabled-tool storage
- Keep runtime availability separate from document access semantics
2026-08-20 00:26:53 -03:00
Victor Wads b43da1ecc3
feat(mcp): add automation settings controls 2026-08-20 00:26:34 -03:00
Victor Wads 51f8464621
Merge remote-tracking branch 'source/master' into victorwads/fast-pages-open-recent
# Conflicts:
#	CHANGELOG.md
#	desktop/src/lib.rs
#	desktop/src/menu.rs
2026-08-19 14:47:08 -03:00
Danila Poyarkov 103e4ac151 test(canvas): fix nested guide renderer coverage 2026-08-19 20:28:10 +03:00
Danila Poyarkov c141663291 fix(editor): address guide authoring review
- Dispose CanvasKit dash effects and render nested frame guides
- Validate imported guide GUIDs and invalidate stale raw guide metadata
- Resolve frame owners through nested hit ancestry and require primary-button ruler drags
- Share guide preview types through a neutral editor module
2026-08-19 20:13:57 +03:00
Danila Poyarkov c05a5596aa fix(tools): require sibling variant components
- Reject combine_as_variants inputs that span different parents\n- Preserve all source components when validation fails\n- Cover the tool-level error path
2026-08-19 20:05:54 +03:00
Danila Poyarkov 1db92c4603 fix(figma-api): align variant combination behavior
- Match the Figma parent and insertion-index API contract\n- Reject duplicate component references before graph mutation\n- Share slash-name variant derivation with editor actions\n- Add structural regression coverage and changelog entry
2026-08-19 20:05:54 +03:00
xemc b01ed830e8 feat(figma-api): add combineAsVariants for real component variant sets
figma.combineAsVariants() was unimplemented in the scripting/automation
layer (figma-api/proxy.ts's compatibility surface), even though the editor
UI already has a full equivalent — createComponentSetFromComponents()
(editor/components.ts) plus wrapSelectionInContainer()
(editor/structure/container-wrap.ts) — wired to the app's own "Create
component set" menu action.

This ports that logic down to FigmaAPI (the class MCP tools, the CLI, and
AI chat scripting all run against): wraps selected COMPONENT nodes sharing
a parent into a COMPONENT_SET, and derives variant property definitions from
"Category/Value" node-name segments, matching the editor behavior exactly.
Drops the undo-stack push and selection-state writes the editor path has,
since neither concept exists at the scripting layer — everything else is
the same primitives (SceneGraph.createNode/insertChildAt/reparentNode),
which FigmaAPI already had direct access to.

Also adds a matching combine_as_variants tool (packages/core/src/tools/
create/components.ts) registered in EXTENDED_TOOLS, so it's exposed
through MCP, the CLI, and AI chat alongside the existing create_component/
create_instance tools.
2026-08-19 20:05:54 +03:00
Danila Poyarkov 4b8bf021f6
Merge pull request #548 from 0xemc/fix/fig-component-property-roundtrip
fix(fig): component properties silently dropped on save
2026-08-19 20:04:57 +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 e86c4c9b9b Merge remote-tracking branch 'origin/master' into review-pr-548-head 2026-08-19 18:33:16 +03:00
Danila Poyarkov adaf6dacb9 fix(canvas): keep guide renderer fixtures complete 2026-08-19 18:10:36 +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 33962b764c fix(fig): harden component property round trips
- Allocate collision-safe property GUIDs across every export path
- Preserve instance-swap component keys and unresolved GUID targets
- Prefer edited assignments over imported raw metadata
- Cover recursive serialization, assignments, and key preservation
2026-08-19 18:05:25 +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