Commit graph

2328 commits

Author SHA1 Message Date
Danila Poyarkov 4a5e7d5570
Merge pull request #470 from open-pencil/gold-preview-current-audit
fix(fig): preserve imported text and clone geometry
2026-08-07 09:27:26 +03:00
Danila Poyarkov 9829669f85 refactor(fig): name divider position result 2026-08-07 09:14:48 +03:00
Danila Poyarkov 82ac131dfe fix(fig): preserve divider main-axis position
Restore only the centered cross-axis coordinate when carrying effective derived divider geometry through clone recreation.
2026-08-07 09:08:57 +03:00
Danila Poyarkov 7b091723a2 style: format FIG compatibility fixes 2026-08-07 08:50:40 +03:00
Danila Poyarkov c446524ce2 fix(scene-graph): validate text invalidation patches
- Ignore undefined values before cache invalidation and preview mutation\n- Treat text direction as a glyph-shaping input\n- Cover the corrected invalidation contract
2026-08-07 08:50:39 +03:00
Danila Poyarkov f9701ef855 fix(fig): preserve effective clone geometry
- Restore authoritative image-leaf bounds after final component swaps\n- Preserve derived cross-axis positions for thin divider clones\n- Add synthetic and Gold Preview regression coverage
2026-08-07 08:50:39 +03:00
Danila Poyarkov eb55cb1025 fix(text): preserve imported FIG glyph outlines
Keep authoritative derived glyphs through layout, alignment, fill, and decoration changes while still invalidating them for actual shaping edits.

Add scene-graph invalidation coverage and a Gold Preview fixture regression test.

Co-authored-by: Joseph Cumines <joeycumines@gmail.com>
2026-08-07 08:50:39 +03:00
Danila Poyarkov a703a48926
Merge pull request #469 from open-pencil/fix-canvas-backing-limit
fix(canvas): bound retained backing allocations
2026-08-07 08:50:16 +03:00
Danila Poyarkov afc5305e8c fix(canvas): report retained backing failures
- Warn once with the rejected surface dimensions and original CanvasKit error
- Disable repeated cache allocation attempts until the renderer surface is replaced
- Keep direct scene rendering as the visible fallback
2026-08-05 19:10:41 +03:00
Danila Poyarkov c4df0c0257 Merge remote-tracking branch 'origin/master' into fix-canvas-backing-limit
# Conflicts:
#	CHANGELOG.md
2026-08-05 18:56:29 +03:00
Danila Poyarkov 82ef49aa9e fix(canvas): bound retained backing allocations
- Scale retained margins to a fixed device-pixel budget on large viewports
- Fall back to direct scene rendering when CanvasKit rejects an offscreen surface
- Cover the reported wide HiDPI geometry without coupling rendering to a WebGL context
2026-08-05 18:54:18 +03:00
Danila Poyarkov e6ba419ed1
Merge pull request #465 from zackarychapple/codex/scale-target-aspect-ratio-instances
fix(fig): scale target-aspect instance subtrees
2026-08-05 18:16:59 +03:00
Danila Poyarkov 77263c1d48 fix(fig): limit target-aspect scaling
- Traverse fixed wrappers only to reach descendants with SCALE constraints

- Preserve fixed siblings and use component geometry as the scale basis

- Cover target-aspect icons without changing the Preline geometry baseline
2026-08-05 18:00:52 +03:00
Zack Chapple fcfe259f26 fix(fig): scale target-aspect instance subtrees
- Use preserved targetAspectRatio metadata as the instance scale basis

- Scale nested geometry through fixed wrapper layers

- Cover proportion-constrained logo imports with a regression test
2026-08-05 17:18:34 +03:00
Danila Poyarkov 85abfd5d21
Merge pull request #468 from open-pencil/polish-pr-455
feat(chat): switch saved model profiles from chat
2026-08-05 17:16:16 +03:00
Danila Poyarkov 005f1bcdfa
Merge branch 'master' into polish-pr-455 2026-08-05 17:03:52 +03:00
Danila Poyarkov 3353c747af fix(ai): preserve valid design assignment
- Reject removing the active Design profile when no tools-capable fallback exists

- Cover text-only fallback handling
2026-08-05 17:03:37 +03:00
Danila Poyarkov a0283fda40
Merge pull request #464 from open-pencil/polish-pr-437
docs(ai): publish polished BYOK compatibility reference
2026-08-05 17:00:58 +03:00
Danila Poyarkov a63de8caaf
Merge branch 'master' into polish-pr-437 2026-08-05 16:47:58 +03:00
Danila Poyarkov 9f8ae33d84
Merge pull request #467 from open-pencil/fig-effective-text-shaping
fix(fig): shape generated text and preserve transforms
2026-08-05 16:38:46 +03:00
Danila Poyarkov 2a4beb83ae
Merge branch 'master' into fig-effective-text-shaping 2026-08-05 16:23:42 +03:00
Danila Poyarkov 53fae9e245 docs(ai): tighten BYOK compatibility probes
- Scope recipes to OpenAI-compatible endpoints and enforce CORS status and header values
- Record unavailable ID coverage, output budgets, stream HTTP status, finish reasons, and zero-call failures
- Repair the repository README link to the published compatibility reference
2026-08-05 16:23:23 +03:00
Danila Poyarkov ea7ca7ec7a fix(layout): refresh effective text flow
- Recompute Yoga positions after shaped text changes effective geometry

- Resolve inherited stretch and skip hidden or absolute children

- Share and normalize Plugin API transform matrices
2026-08-05 16:07:11 +03:00
Danila Poyarkov ec419df8a3
Merge pull request #463 from open-pencil/adapt-pr-443-menu
feat(app): open storage workspace from the File menu
2026-08-05 16:00:24 +03:00
Danila Poyarkov 7a3a8bf53f refactor(chat): polish model profile switching
- 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
2026-08-05 15:44:27 +03:00
Rob Coenen 4bdaeb6d6e feat(chat): switch models from the chat panel
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>
2026-08-05 15:28:31 +03:00
Danila Poyarkov fb3dc932b8
Merge branch 'master' into adapt-pr-443-menu 2026-08-05 15:27:44 +03:00
Danila Poyarkov 0982ac513d fix(i18n): clarify Russian workspace menu label 2026-08-03 20:41:26 +03:00
Danila Poyarkov eeefd069e6 fix(figma-api): expose node transforms
- Return rotation and reflection matrices for relative and absolute transforms

- Preserve authoritative imported FIG transforms until geometry is edited

- Cover nested rotation and reflected vector behavior
2026-08-03 20:17:32 +03:00
Danila Poyarkov 2ec58ae3eb fix(layout): shape generated FIG text
- Reconcile stale generated text widths with CanvasKit measurements

- Propagate effective widths through HUG containers while preserving fixed geometry

- Cover component-lineage and stretched-text safeguards
2026-08-03 20:08:56 +03:00
Danila Poyarkov 0036d762e2 docs(ai): polish BYOK compatibility guidance
- Publish the compatibility reference in the VitePress site and link localized AI guides to the canonical English page
- Correct current Anthropic and credential-storage behavior
- Make CORS, streaming, pricing, context, and reasoning measurements reproducible and security-safe
2026-08-03 19:19:38 +03:00
Rob Coenen 1ebaac7be2 docs(ai): re-measure at a realistic token budget, document reasoning starvation
The probe behind this page used max_tokens 2000, which starves reasoning
models: they spend the whole budget thinking and emit no tool calls, with
finish_reason length and no error. That looks identical to a model that
cannot call tools, and two models were wrongly marked "avoid" because of it.

Re-ran every Scaleway model at 16384. All five are clean -- qwen3.6-35b-a3b
goes from 1/3 to 3/3, mistral-small-3.2-24b from 2/3 to 3/3. Tool calling no
longer separates them, so the recommendation now follows price, vision and
context: mistral-small-3.2-24b is cheapest with vision, gemma-4-26b-a4b-it
for double the context.

Document the failure mode, the reasoning_effort lever (only "none" had any
effect on Scaleway; "low" did nothing), and ask contributors to record the
token budget alongside results. Nebius and TensorX rows are marked as
measured at 2000 so they are not read as comparable.

Refs #454

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-03 19:08:31 +03:00
Rob Coenen ac73b0d91f docs(ai): track model capabilities, add models.dev auto-lookup
Add measured Vision and context-window columns alongside the tool-calling
metrics, and four more Scaleway models. gemma-4-26b-a4b-it becomes the
recommendation: the only model tested that is clean on cost, tool calling
and vision at once, with 2x the context of gpt-oss-120b.

Document models.dev as a prefill source for new rows, with the caveat that
it describes nominal capabilities rather than deployment behaviour. It was
wrong on two of seven models checked here -- it marks scaleway/gpt-oss-120b
as vision-capable when the model refuses images, marks
scaleway/mistral-small-3.2-24b as text-only when it reads them, and reports
tool_call: true for models that emit no tool calls in practice.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-03 19:08:31 +03:00
Rob Coenen ab93025541 docs(ai): correct TensorX CORS finding, add Scaleway results
TensorX was marked browser-broken based on unauthenticated probes. With a
valid key it returns Access-Control-Allow-Origin on 200 responses; only
errors (401/403/500) omit it. Downgrade to a warning and document the
methodology error, since an unauthenticated probe cannot distinguish a
gateway-rejected error from a genuinely broken provider.

Scaleway behaves the same way and is added with the same caveat.

Add four Scaleway model results. gpt-oss-120b streams cleanly there
(0 violations / 135 deltas) despite misrouting on Nebius, so the vLLM
tool-call bug is a deployment issue rather than a model one, and the
client-side shim is avoidable by switching provider. That makes
gpt-oss-120b the cost-effective recommendation at EUR 0.15/0.60.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-03 19:08:31 +03:00
Rob Coenen 897fcdfa2f docs(ai): add model pricing to the BYOK compatibility table
The table ranked models on tool-calling correctness alone, which recommended
Kimi-K3 at $3/$15 per 1M tokens. The chat panel runs up to 50 agent steps and
resends tool schemas each step, so price compounds and that was the wrong
default.

Add a cost column, move the recommendation to Kimi-K2.7-Code (same clean
behaviour, ~1/4 the price), and note that gpt-oss-120b is ~25x cheaper than
K3 and would be the obvious default once the vLLM shim exists.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-03 19:08:31 +03:00
Rob Coenen efd02c88ea docs(ai): add BYOK provider & model compatibility reference
Whether a provider works in the web build depends on CORS headers being set
on the response (not just the preflight), and whether a model is usable in
the AI chat panel depends on its streaming tool calls being well-formed.
Neither is documented by providers, so record what has been measured.

Covers 11 providers and 5 models, each row dated. Documents two recurring
failure modes: vLLM misrouting the final tool-call argument chunk to
index + 1 without an id, and reasoning models returning null content under
the connection test's maxOutputTokens: 1.

Includes copy-paste curl recipes so others can add rows.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-03 19:08:31 +03:00
Danila Poyarkov bbeffc54cb
Merge pull request #462 from open-pencil/shadcn-compat-gaps
fix(fig): improve imported component layout parity
2026-08-03 19:06:25 +03:00
Danila Poyarkov 75dd86d0ad fix(fig): improve imported component layout parity
- Preserve Figma min/max constraints, scalar variable bindings, and direct text bounds
- Reflow only authoritative generated instance geometry and pinned descendants
- Avoid double-applying auto spacing and unsafe lone-child normalization
2026-08-03 18:00:15 +03:00
Danila Poyarkov 79aa6ba5dd refactor(app): move storage workspace navigation into File menu
- Replace the full-width editor header action with a shared browser and native menu command
- Localize the destination and cover menu schema and browser navigation
2026-08-03 17:42:39 +03:00
Rob Coenen d85e2ec5e1 feat(app): add a Back to workspace button to the editor header
Once a document is opened from the storage workspace there is no way back
to it: the only in-app route is Settings -> Cloud storage -> Open workspace,
and the desktop shell has no browser back at all.

Add an explicit button in the shared header row (rendered on both web and
Tauri, unlike the File/Edit menubar below it) that routes to /storage. It is
a fixed destination rather than history navigation, so it behaves the same
on both platforms.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-03 17:18:16 +03:00
Danila Poyarkov 9be70db9f9 docs: polish unreleased changelog
- Reframe entries around user-visible outcomes and consolidate related changes
- Document missing features, fixes, performance improvements, and SDK migrations
2026-08-03 12:08:58 +03:00
Danila Poyarkov de8578c435
feat(app): expand Figma menu and selection parity (#459)
- Add Figma-style object, component, selection, view, settings, and browser Move to Page actions
- Add undoable z-order, transformed distribution, inverse selection, and single/bulk rename behavior
- Keep browser and native menus, shortcuts, generated schema, localization, and documentation aligned
2026-08-03 00:23:05 +03:00
rcoenen 2949bd648f
fix(figma-api): match Figma vector editing (#444)
- Support vectorPaths, vectorNetwork, and async network assignment
- Normalize geometry bounds and preserve winding and region paint semantics
- Validate network topology and expose handle mirroring only on vectors

Co-authored-by: Rob Coenen <753704+rcoenen@users.noreply.github.com>
2026-08-02 22:32:16 +03:00
rcoenen db15d8d583
fix(tools): create vectors from SVG paths (#440)
- Accept SVG path data with tight curve-aware node bounds
- Validate complete VectorNetwork topology while preserving JSON input
- Reject empty and malformed paths before creating blank layers

Co-authored-by: Danila Poyarkov <dev@dannote.net>
2026-08-01 20:17:42 +03:00
Danila Poyarkov 80a3cd8bd3
ci: update GitHub Actions to Node 24 (#460)
* ci: update GitHub Actions to Node 24

* ci: skip privileged previews for forks

* ci: isolate preview deployment secrets
2026-08-01 19:50:08 +03:00
Danila Poyarkov 5f13dc2e9a
ci: move Git LFS to provider-neutral gateway
Replace the broken R2-backed LFS URL with lfs.openpencil.dev and keep storage credentials behind the gateway. Fixes #457.
2026-08-01 17:52:08 +03:00
rcoenen 9f80c35838
fix(tools): describe visible strokes (#447)
- Include stroke color and rounded weight in node and child summaries
- Select the first visible stroke when hidden paints precede it
- Cover both describe output paths with mixed stroke visibility

Co-authored-by: Rob Coenen <753704+rcoenen@users.noreply.github.com>
2026-08-01 17:40:30 +03:00
rcoenen 90d1d37113
fix(design-jsx): accept inline SVG attributes (#445)
- Validate inline SVG roots against their supported root props
- Leave descendant SVG markup to the SVG renderer instead of Design JSX validation
- Keep warnings for unsupported root props and cover both paths

Co-authored-by: Rob Coenen <753704+rcoenen@users.noreply.github.com>
2026-08-01 16:57:32 +03:00
rcoenen bffd53d349
fix(tools): describe every supported shape (#448)
- Name every create_shape node type in the tool description
- Direct arbitrary geometry requests to SVG-backed create_vector input
- Keep the prose synchronized with the declared type enum

Co-authored-by: Rob Coenen <753704+rcoenen@users.noreply.github.com>
2026-08-01 16:39:57 +03:00
Danila Poyarkov f047b0bcb4 fix(svg): preserve explicit none paints
- Normalize SVG paint sentinels before creating icon vector nodes
- Keep inline outline artwork transparent instead of falling back to black
- Cover fill and stroke none values through the Design JSX renderer

Co-authored-by: Rob Coenen <753704+rcoenen@users.noreply.github.com>
2026-08-01 15:42:46 +03:00