Anthropic omits Access-Control-Allow-Origin unless the caller sends
anthropic-dangerous-direct-browser-access, so the web build failed with an
opaque "Could not reach this endpoint from the browser" for the anthropic
provider. @ai-sdk/anthropic does not send the header and neither did our
adapter.
Send it from the browser only. The desktop build routes through tauriFetch
and is not subject to CORS, so it does not need to advertise browser access.
Fixes#436
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
- Resolve the active graph at action time and map edit geometry through full world transforms
- Regenerate live path fills and discard stale imported stroke outlines after edits
- Preserve fill and stroke geometry through resize previews, undo, and redo
- Cover graph replacement, nested transforms, edit history, resizing, and CanvasKit output
Co-authored-by: Rob Coenen <753704+rcoenen@users.noreply.github.com>
- 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>
- 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
- Replace regex-based list and error parsing with xmldom
- Decode entities through the parser and support namespaced pagination responses
- Treat malformed listing documents as empty pages
- 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
- Show one centered setup action instead of simultaneous error and empty states
- Refresh configuration after closing Settings without requiring route remount
- Keep document creation and refresh unavailable until setup is complete
- Reuse one named source-state contract across save and source actions
- Keep storage bindings and local source identity typed without duplicated shapes
- 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>
- Track remote storage bindings without replacing local file identity
- Route saves and autosaves through the durable local cache before enqueueing uploads
- Clear storage bindings on Save As and cover ordering and identity behavior
Co-authored-by: Rob Coenen <753704+rcoenen@users.noreply.github.com>
- Drain local outbox jobs through the active registered storage adapter
- Preserve revision guards, retry backoff, tombstones, progress, and offline recovery
- Resolve the active adapter and credentials for each queued operation
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>
- Recover the IndexedDB and in-memory document cache behind the storage domain
- Add persistent outbox supersession, cache eviction, import validation, and naming helpers
- Keep the substrate provider-neutral and cover its pure behavior
Co-authored-by: Rob Coenen <753704+rcoenen@users.noreply.github.com>
- Define backend-neutral document storage and provider schema contracts
- Keep provider preferences separate from credential references
- Resolve declared secrets lazily through the shared credential service
- 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
- Move provider-specific model construction behind typed adapters
- Keep OpenAI- and Anthropic-compatible configuration reusable
- Verify every direct provider is registered while ACP agents stay separate
- Store desktop secrets in native OS credential services through a narrow Tauri bridge
- Provide session-only and encrypted remembered browser stores with explicit switching
- Migrate legacy plaintext keys only after verified writes and cover failure recovery
- 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
- Route npm-installed ACP and MCP launchers through cmd on Windows
- Preserve inherited agent environment and current MCP transport settings
- Cover Windows process resolution and document the user-facing fix
Co-authored-by: Damián Briones <insertnickname1@gmail.com>
- Match documents by desktop path or File System Access handle
- Share concurrent duplicate loads while allowing unrelated files to load in parallel
- Publish source identity only after successful opens and saves
Co-authored-by: Joseph Cumines <joeycumines@gmail.com>
- 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
Roll back the Pulse music-app demo to the prior standalone showcase
(Components / App Preview / Effects) which cleanly demonstrates gradients,
drop/inner shadows, blend modes, masks, and corner smoothing. Also removed the
Pulse JSX showcase file and restored the matching demo test.
Fill the three biggest gaps that blocked authoring real designs in JSX:
- mask prop on any node: <Ellipse mask> / mask="luminance" / mask="vector"
sets isMask + maskType so sibling content clips (Figma's mask model)
- <svg> element rendering inline SVG markup into vector nodes, reusing the
iconify path pipeline (extractPaths + parseSVGPath + scalePathInfos)
- Instance overrides: <Instance of="X" overrides={{ 'childName:prop': v }} />
applies child overrides by name and records them so component sync keeps them
Adds gap tests and the shared scalePathInfos/finishIconRender helpers to
avoid duplicating the iconify pipeline.
Apply success/accent/danger tones to the stat badges after layout with the
label fill recorded as an override, so component sync preserves them.
Badges now read +14% green, +8% blue, -3% red.
Replace the grab-bag demo (3 disconnected feature boxes) with a real product
screen that teaches the OpenPencil workflow by example:
- Component Library: Button (primary/secondary), Badge, Avatar, Nav item,
Toggle as actual COMPONENTs
- App — Analytics: a modern dashboard assembled from INSTANCEs of those
components, laid out with real auto-layout (sidebar, stat row, chart,
callout), themed via bound semantic variables
- Single restrained palette (one accent + surfaces/text/semantic tones)
- Instance text set with recorded overrides so component sync keeps labels
Editing a variable re-themes the screen; resizing frames demonstrates live
auto-layout reflow.
- 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.