- 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
- 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
- Serialize recovery cleanup with active snapshot writes
- Preserve version ordering across autosave, restore, and cleanup
- Fall back to memory when IndexedDB operations fail
- 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
- Redact and bound provider error details in copied logs
- Avoid repeat toasts after locale changes
- Show reasoning effort only for supported providers
- 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
* fix(storage): polish workspace and connection feedback
- Move Refresh into the Storage Workspace header and keep shell theme actions available outside the editor route
- Split native shell and editor menu listeners behind the app shell
- Replace permanent CORS controls and inline connection results with standard toasts and clearer browser guidance
* fix(app): harden native menu routing
- Dispose menu listeners that finish registering after their Vue scope closes
- Mark shell-owned actions in the shared menu schema instead of duplicating IDs
- Cover route-neutral shell action classification
- Localize import, collaboration, settings, color, font, and accessibility text across supported locales
- Synchronize the document language through reactive Unhead attributes
- Translate connection failures, browser fallbacks, notifications, and save prompts
- Load Prism JSX only after exposing the Prism runtime
- Treat unavailable MCP automation as optional during startup
- Connect the desktop automation bridge only after MCP is ready
- Cover UI identifiers in the acronym guardrail
- Preserve FIG thumbnail and metadata values through archive parsing
- Use Vue-compatible acronym prop attributes
- 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
- Separate model, connection, and advanced settings
- Resolve capabilities and output limits from provider catalogs
- Keep custom model compatibility declarations explicit
- Centralize design-profile eligibility for the selector, role assignment, fallback, and tests
- Keep built-in provider model selection intact while switching saved custom profiles
- Add localized accessible labeling and constrain long profile names
The chat model chip is a dropdown for built-in providers but a static label
for OpenAI-compatible and custom-model setups, so anyone using a custom
endpoint had to open Settings to change models -- even with several models
already configured.
Add a profile switcher that reassigns the design role from the chat panel.
It lists saved profiles that can use tools, shows the profile name rather
than the raw model ID, and badges the vision-capable ones. It writes the
same assignments.design field the Settings dropdown does, so the two stay in
sync.
Only renders when more than one tools-capable profile exists; a single
profile keeps the existing label. Built-in providers keep ProviderModelSelect
unchanged.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- Default fresh browser sessions to encrypted credential persistence with an explicit session-only opt-out
- Keep API-key links left-aligned, legible, and limited to their text click target
- Update credential guidance and browser coverage
- Add secure Recraft and fal.ai clients with centralized credentials and Media settings
- Replace image rectangles with editable vector frames in one undoable operation
- Bound desktop proxy responses, timeouts, and redirects for provider downloads
- Cover provider parsing, placement, settings, context-menu visibility, and undo
Co-authored-by: Rob Coenen <753704+rcoenen@users.noreply.github.com>
- Resume persisted outbox jobs at startup without dropping writes when credentials are unavailable
- Serialize IndexedDB revisions and guard sync completion against concurrent saves
- Reconcile tombstones without reviving deleted documents and bound S3 metadata requests
- Require explicit CORS configuration instead of overwriting bucket rules during connection tests
- Keep ACP agents exclusive to the Design role and normalize invalid model limits
- Separate provider connections, model profiles, capabilities, and role assignments
- Replace role-specific forms with a reusable model library and assignment table
- Resolve credentials lazily per connection and preserve existing Design settings
- Route Design chat through the assigned profile while exposing Review, Fast, and Vision runtimes
- Add one themed placeholder primitive for page, panel, dialog, and setup states
- Vertically center chat, code, assets, variables, and storage placeholders
- Let Vue replace the static boot splash instead of mutating global DOM from views
- List local and remote documents from an explicit storage workspace route
- Open remote .fig documents into deduplicated storage-bound editor tabs
- Create locally durable documents only after storage configuration is complete
- Cover unconfigured guidance and mocked S3 document opening end to end
Co-authored-by: Rob Coenen <753704+rcoenen@users.noreply.github.com>
- Add schema-driven S3 preferences and status-only credential controls to unified Settings
- Keep storage preferences persistent while secrets remain in the selected credential backend
- Include storage credentials when browser persistence changes and test session behavior
Co-authored-by: Rob Coenen <753704+rcoenen@users.noreply.github.com>
- Open one Settings dialog for AI providers, agents, and media credentials
- Resolve secrets only when requests start and keep settings on status-only credential APIs
- Make browser persistence explicit and default fresh web sessions to memory
- Move provider controls into the settings domain and cover setup, reload, and clearing
- Build typed Reka-based dialog and alert-dialog anatomy with shared theme slots
- Migrate variables, asset details, and ACP permissions to the common shell
- Add Storybook coverage for reusable dialog states
- Add a headless PropertyGrid primitive with themed app composition
- Keep composite paint details full-width and show remove actions consistently
- Tighten color picker and Design-panel field sizing without clipping values
- Let nested actions claim tooltip ownership from parent controls
- Keep only one tooltip visible across pointer and keyboard focus
- Cover composite property fields and preserve WebKit behavior
- Section titles are no longer collapsible triggers — they render as static
text like Figma, so clicking a section header no longer collapses it
- Drop the 'Font features' group title; ligature/kerning toggles sit
directly in the Typography flow
- Update panel specs and snapshots for always-expanded sections
The B/I/U/S toggle buttons were borderless ghosts while the alignment
controls used a filled segmented container. Wrap them in the same
bg-panel-field container so both toggle groups share one visual style.
The group header and the toggle rows under it shared the same muted 11px
style, flattening the hierarchy. The OpenType features label is now
semibold surface text while items stay muted.
- Layout: gap between the Resizing segmented control and the W/H size fields
- Typography: breathing room between OpenType feature toggle rows and above
the Text formatting toolbar
Within-group label→field stays 4px; between-group margin rises from 6px to
12px so each property reads as a distinct unit instead of merging into a
continuous column. Matches Figma's grouping structure without removing the
labels.
- Move the Auto layout add/remove button from the section body into the
section header actions, matching the Layout grid and every other section
- Drop leading-none on section titles so descenders ('g' in 'Layout grid')
are not clipped by the 32px header band
Add a Layout grid section for frames/components with pattern (columns/rows/
grid), count, gutter/section size, and margin, plus visibility and remove
actions. The canvas already rendered layout grids from imported files; this
wires creation and editing through the standard panel list pattern with
undo support and icon+tooltip pattern options.
Surface the engine's textAutoResize as a Resizing segmented control for
text nodes, mapping Figma's three modes: Auto width (WIDTH_AND_HEIGHT),
Auto height/wrap (HEIGHT), Fixed size (NONE). Icon + tooltip options match
the panel's segmented-control language. The engine already reflows text on
content changes; this wires the control to it with undo support.
Layer lock/visibility actions, toolbar tools, tool flyout triggers, and
the app UI toggle rendered icon-only buttons with no accessible name, so
screen readers and role-based selectors could not identify them. Each now
exposes an aria-label from the existing i18n/tool labels.
- Menubar items render in surface text instead of muted (looked disabled),
at the 11px UI scale
- Menu items, document tabs, and tooltips normalized to 11px to match the
panel type scale; menu items use the 5px control radius
- Share button uses the control radius and 11px; presence popover drops its
border for the floating shadow
- Section headers become full 32px bands (title + trailing actions
vertically centered) instead of an 11px line crammed against fields,
giving each section a clear structural band like Figma
- Select dropdowns adopt the floating-surface elevation (12px radius, no
border, deep shadow), 24px flush items, and scroll up/down buttons for
long lists (blend modes)
- Font-settings gear trigger drops its hardcoded dark bg+border for the
ghost icon-button recipe
- Segmented-control active state uses neutral hover fill instead of the
blue-grey selection color
- Menus, popovers, dialogs, tooltips, and the toolbar drop the hard 1px
border for the established deep floating shadow (0 8px 30px /40%) and a
unified rounded-xl, so overlays read as floating rather than outlined
- Appearance section pairs Blend mode with Opacity on a 7fr/5fr grid so
'Pass through' no longer truncates at the denser 24px control height
- Normalize AppSelect text to 11px to match the panel type scale