Commit graph

948 commits

Author SHA1 Message Date
Danila Poyarkov c2aec9bacb
fix(packages): make packed exports runtime-safe (#665)
* fix(packages): make packed exports runtime-safe

Make checked-in package manifests truthful for ordinary npm and Bun packing, and verify installed artifacts under both runtimes. Centralize package discovery, artifact inspection, and bounded process execution so CI and release publication share the same contracts.

* ci: build package dependencies before checks

Keep workspace jobs independent of ignored dist output now that public package exports consistently resolve built artifacts.

* ci: preserve source-first engine tests

Keep the broader dependency build for package and repository validation, but retain Core-only setup for engine shards so workspace tests continue exercising source modules.

* ci: build engine shard dependencies

Build the seven workspace packages imported by engine tests in dependency order. This preserves a single module instance per package and keeps each clean CI shard independent of ignored dist output.

* ci: restore established package build boundaries

Keep the original repository and engine job setup, and add installed artifact verification only after the existing package build. Avoid changing which module copies unrelated tests execute.

* fix(packages): preserve Bun source identity in tarballs

Retain source-first workspace resolution and ship complete source trees for Bun conditions. Verify clean installed consumers without overlaying archives, reuse consumer validation before release publication, and repair Bun 1.3.10 private source alias resolution.

* refactor(tooling): reuse package and process utilities

Use pkg-types for manifest I/O and types, tinyexec for subprocess lifecycle, and npm's pack listing for release staging. Preserve archive verification and project release invariants rather than reimplementing package-manager file selection.

* refactor(tooling): resolve workspace roots at CLI boundaries

Discover and validate the nearest workspace once, support explicit roots, and pass roots to reusable checks. Replace subprocess entrypoint dispatch with direct calls and preserve aggregate package diagnostics without adding arbitrary test timeout increases.

* fix(release): enforce publication boundaries

Use root version alignment and shared validated npm output parsing. Enforce the public npm registry policy and test verification-before-publication, mismatched artifacts, and partial retries without registry writes.

* refactor(tooling): validate package responses with Valibot

Express npm pack and manifest identity contracts as schemas, infer parsed output types, and preserve contextual failures and relative-path safety. Document Valibot as the first-party validation convention while retaining Zod at SDK boundaries.

* refactor(tooling): validate manifests at input boundaries

Share Valibot schemas for consumed manifest fields, recursive exports, supported workspace declarations, and npm registry responses. Infer domain types and reject malformed metadata instead of silently skipping it downstream.

* refactor(tooling): group package helpers by ownership

Colocate manifest and workspace contracts, separate npm response parsing from generic JSON handling, and split smoke packing, installation, and runtime checks. Remove the release tarball forwarding shim and consolidate its coverage in package-artifacts. Preserve public tooling exports and CLI commands.
2026-09-09 18:25:22 +03:00
Danila Poyarkov 904c90c329 refactor(settings): extract model profile workflows 2026-09-05 21:25:46 +03:00
Danila Poyarkov e851331c27 fix(ai): recommend latest Kimi and Fable models 2026-09-04 19:03:34 +03:00
Danila Poyarkov f674f8c99d feat(ai): modernize model picker 2026-09-04 18:45:03 +03:00
Danila Poyarkov f5db783797 fix(chat): align vision and model role UX
- Restore attachment inset spacing through the InputGroup theme slot\n- Mark curated multimodal models as Vision-capable and repair saved capability metadata\n- Default Vision to the Design profile when that profile accepts images\n- Use configured Design profiles in the composer instead of raw provider models\n- Surface missing Vision configuration directly in Settings\n\nCo-authored-by: Jason Kneen <jason.kneen@bouncingfish.com>
2026-09-03 19:58:09 +03:00
Danila Poyarkov 9a3d7ca702 fix(ai): require closed stock photo vectors
- Reject open vector networks before contacting the provider\n- Cover closed and open vector targets explicitly\n- Label the stock photo prompt example code fence
2026-09-03 08:46:10 +03:00
Danila Poyarkov 90b608863e fix(ai): validate stock photo targets
- Reject text, line, structural, and populated container targets before provider requests\n- Preserve closed shape and Boolean geometry support without mutating target bounds\n- Cover accepted and rejected node families with focused tests
2026-09-03 08:46:10 +03:00
Danila Poyarkov aa3285f2fc Merge master into shared-mutation-impact 2026-09-02 10:24:51 +03:00
Danila Poyarkov 45c401cbf5
fix(text): preserve cached font coverage and source offsets 2026-09-02 09:26:59 +03:00
Danila Poyarkov 75d555900f fix(editor): preserve mutation parents and font layout 2026-09-02 08:27:52 +03:00
Danila Poyarkov 8a5daa7472 fix(automation): load fonts before scoped layout 2026-09-02 02:09:05 +03:00
Danila Poyarkov 0f070f9f97 refactor(ai): share mutation layout reconciliation 2026-09-02 02:06:08 +03:00
Danila Poyarkov 9e2fd9b471 Merge remote-tracking branch 'origin/master' into shared-mutation-impact 2026-09-02 01:58:51 +03:00
Danila Poyarkov edb608e992 refactor(editor): centralize mutation layout reconciliation 2026-09-02 01:58:50 +03:00
Danila Poyarkov 3caf5c99d9 fix: resolve lint warnings 2026-09-02 01:49:37 +03:00
Danila Poyarkov 8a976c1a0f Merge master into fix/create-component-drops-bound-variables 2026-09-02 01:09:01 +03:00
Danila Poyarkov 270e3c1e57 fix(layout): preserve imported Figma line geometry 2026-09-01 23:10:21 +03:00
Danila Poyarkov 9bb9478833
refactor: replace complex conditional object spreads
- Add a typed, modular custom Oxlint rule package with direct regression coverage
- Replace complex conditional object spreads with explicit construction across the repository
- Preserve all existing custom rule registrations and diagnostic behavior
2026-09-01 19:49:57 +03:00
Danila Poyarkov 9726a4a711
Merge pull request #625 from open-pencil/cli-font-diagnostics
feat(cli): report document font availability
2026-09-01 16:57:03 +03:00
Danila Poyarkov 410d6171e4 fix: close structured override review gaps 2026-09-01 15:23:08 +03:00
Danila Poyarkov 5b074e967d fix: harden structured override decoding 2026-09-01 14:11:19 +03:00
Danila Poyarkov c32ff03d03 fix(cli): include all pages in font diagnostics 2026-09-01 13:41:05 +03:00
Danila Poyarkov e93d3ea6e1 fix: preserve structured overrides across JSON boundaries 2026-09-01 13:35:09 +03:00
Danila Poyarkov e414cf77ab fix(text): align font status with prepared roots 2026-09-01 13:24:35 +03:00
Danila Poyarkov 6d17b92a56 refactor(text): share graph font preparation 2026-09-01 13:24:35 +03:00
Danila Poyarkov 35972606a3 fix(cli): satisfy font diagnostics checks 2026-09-01 13:24:35 +03:00
Danila Poyarkov 7c67390707 fix(cli): prepare fonts across complete documents 2026-09-01 13:24:35 +03:00
Danila Poyarkov 41f445ebab fix(cli): prepare fonts for RPC diagnostics 2026-09-01 13:24:35 +03:00
Danila Poyarkov 73cb945cbc feat(cli): report document font availability 2026-09-01 13:24:35 +03:00
Danila Poyarkov 751be1198c feat(cli): report document font availability 2026-09-01 13:24:35 +03:00
Danila Poyarkov cd2809a6e7 fix: persist instance override mutations 2026-09-01 12:45:13 +03:00
Danila Poyarkov c6e3baa68c fix: repair structured override CI failures 2026-09-01 12:42:52 +03:00
Danila Poyarkov 1c8f802570 fix: restore structured override exports 2026-09-01 12:21:03 +03:00
Danila Poyarkov 1e1c38182d refactor(scene-graph): model instance overrides structurally 2026-09-01 11:44:46 +03:00
Danila Poyarkov 3e47b14e59 fix(fig): preserve text and stroke overrides 2026-09-01 04:57:43 +03:00
Danila Poyarkov f1ae826412 fix(fig): record applied instance override fields 2026-09-01 01:04:22 +03:00
Danila Poyarkov 01353e7ca7 fix(scene-graph): preserve text instance overrides 2026-09-01 01:04:22 +03:00
Danila Poyarkov 07e4cb2438 Merge remote-tracking branch 'origin/master' into consolidate-pr551-next 2026-09-01 01:02:35 +03:00
Danila Poyarkov 2e98ab04a8 fix(canvas): normalize imported dash patterns 2026-08-31 22:25:48 +03:00
Ed-Key 9b48e47329 feat(canvas): render arrow stroke caps on lines and open vectors
ARROW_LINES and ARROW_EQUILATERAL stroke caps were accepted by the schema
and round-tripped from .fig files, but the renderer mapped every cap to
Butt, so imported arrows lost their heads and arrows could not be drawn
locally.

Add a pure arrow-cap geometry module to scene-graph (open-endpoint
collection with per-vertex cap overrides, weight-scaled head geometry)
and draw heads in the stroke color for LINE nodes and open VECTOR
centerline strokes, including the dashed-centerline path. Fold the head
reach into strokeOverflow and the node picture margin so heads are not
cropped by visual bounds, caches, or culling. Round-trip per-vertex
stroke caps through the .fig vector style override table so one-ended
Figma arrows import correctly. Expose both caps in the stroke inspector
cap picker with localized labels, and cover the renderer with an
arrow-stroke-caps Playwright canvas snapshot.

Claude-Session: https://claude.ai/code/session_012zjEbyLSBYyPpJP4fu1XNB
2026-08-31 21:25:38 +03:00
Danila Poyarkov 716e40f0fa
Merge pull request #611 from open-pencil/figma-component-property-api
feat(figma-api): expose component property accessors
2026-08-31 15:05:51 +03:00
Danila Poyarkov 0b0d4f2774 test(figma-api): modernize type assertions 2026-08-31 14:54:03 +03:00
Danila Poyarkov b66d13c098 fix(figma-api): keep compatibility checks lintable 2026-08-31 14:36:18 +03:00
Danila Poyarkov 71423fb0f2 test(figma-api): assert component property types 2026-08-31 14:14:53 +03:00
Danila Poyarkov 379ef8b62d
perf(canvas): rebuild navigation rendering (#591)
* perf(canvas): add traced navigation benchmarks

- Record and replay timestamped pan and zoom gestures through DOM and CDP input paths\n- Correlate input, viewport, render, long-task, and retained-backing events in Chromium traces\n- Report frame pacing, latency, jump, anchor drift, and crisp-settlement metrics

* perf(canvas): stabilize navigation comparisons

- Separate low-overhead metric runs from optional CPU-profile traces\n- Warm scenarios before recording and use a consistent SwiftShader browser configuration\n- Add a canonical momentum-pan reversal gesture alongside pinch reversal

* fix(canvas): require hardware GPU navigation benchmarks

- Run macOS performance captures through Metal-backed ANGLE and reject accidental SwiftShader fallback\n- Record the GL renderer and reserve software GPU mode for portable correctness smoke runs

* perf(canvas): cache shadow rasters for crisp backing

- Rasterize local drop and inner shadows only while constructing retained scene backing\n- Bound native image memory and invalidate cached entries with node and renderer lifecycle changes\n- Quantize zoom-aware raster resolution and reuse nearby scales without lowering normal scene quality

* test(canvas): verify retained shadow raster fidelity

- Compare settled retained-backing shadow output with direct CanvasKit rendering\n- Keep backdrop blur on the picture fallback and exercise graph-driven cache invalidation\n- Cover updates, deletion, and reparenting through actual SceneGraph events

* perf(canvas): benchmark real FIG fixtures

- Serve exact local fixture bytes through an isolated Playwright route for production preview runs\n- Wait for document loading and page population before zooming to fit and recording navigation\n- Record the resolved fixture path in benchmark environment artifacts

* fix(canvas): preserve nested effect subtree pictures

- Keep deeply nested shadow documents on one retained subtree picture instead of exploding them into per-node image draws\n- Restrict shadow raster acceleration to effect-bearing page children\n- Cover nested shadow fallback and restore gold-preview FIG pinch performance to master levels

* refactor(canvas): share recorded wheel sample type

* perf(canvas): defer backing settlement across zoom reversals

- Track explicit navigation phases and gesture generations instead of inferring idle from viewport timing\n- Cancel or defer retained backing construction while pan, zoom, momentum, or tentative settlement is active\n- Add a repeated short-pause pinch reversal fixture based on the user trace

* perf(canvas): index bounded render chunks

- Split oversized painter subtrees into self-paint and bounded descendant chunks without dropping container visuals\n- Bulk-load chunk visual bounds into RBush for selective world-space queries\n- Cover bounded updates and gold-preview build/query complexity before tile rendering consumes the index

* refactor(canvas): namespace render chunk coverage

* perf(canvas): model chunk paint context

- Preserve ancestor transform and clip dependencies for independently renderable chunks\n- Keep opacity, blend, blur, and mask isolation subtrees atomic until command-level splitting exists\n- Report oversized atomic chunks and lock gold-preview to bounded painter units

* perf(canvas): record pixel-correct render chunks

- Record interruptible chunks in world coordinates with ancestor transforms, clips, and chunk-local culling bounds\n- Draw opacity, blend, blur, and mask isolation chunks directly into destination surfaces in painter order\n- Compare composited chunk output with direct CanvasKit rendering instead of relaxing visual thresholds

* perf(canvas): render selective world tiles

- Map world regions to fixed 256-device-pixel tile targets and quantized sharpness levels\n- Query only intersecting render chunks and preserve atomic destination compositing\n- Match multi-tile CanvasKit output against direct rendering and measure gold-preview tile cost

* perf(canvas): cache chunk pictures across tiles

- Reuse world-space chunk command pictures for every intersecting tile\n- Pool 256-pixel tile surfaces and expose allocation, draw, flush, and snapshot timings\n- Keep expensive atomic foreground blur visible as an over-budget scheduler constraint

* perf(canvas): schedule cached tile rendering

- Bound tile images with an LRU cache and reuse pooled CanvasKit surfaces\n- Plan mandatory holes, stale visible refreshes, and overscan by navigation and content generation\n- Stop jobs at a strict deadline while reporting fallbacks, stale work, overruns, and over-budget effects

* perf(canvas): integrate progressive tiled rendering

- Keep retained scene output as the interaction fallback while exact tiles refine only after navigation becomes idle
- Centralize runtime URL flags and pass renderer selection through the typed Vue canvas API
- Replace benchmark sleeps with explicit mode-aware renderer settlement and report exact tiled coverage
- Preserve bounded scheduler metrics, generation cancellation, native resource cleanup, and shared visual-bounds logic

* refactor(app): centralize runtime query configuration

- Parse collaboration, recent-files, benchmark, presentation, and renderer flags in one typed app module
- Remove ad hoc URL parsing from workspace and collaboration runtime consumers
- Cover supported values and production-safe defaults without adding a repository lint rule

* fix(canvas): replace fallback pixels with exact tiles

- Render opaque page-background tile cells and install them with source replacement instead of double-compositing translucent scene content
- Exercise the live progressive controller against direct rendering across masks, effects, blend isolation, images, fallback text, transforms, and clipping
- Preserve the bounded reversal path with zero Long Tasks and exact settlement near 128 ms on gold-preview.fig

* perf(canvas): invalidate tiled content selectively

- Index chunk dependencies across contained nodes and transform or clipping ancestors
- Re-record affected chunk pictures and invalidate tiles intersecting old or new visual bounds
- Advance unaffected cached tiles to the new scene generation instead of rebuilding the full chunk index and tile cache
- Keep structural graph mutations on the safe full-rebuild path and cover selective refresh end to end

* perf(canvas): bound atomic blur tile refresh

- Render atomic blur chunks with tile-local isolation bounds and blur halos instead of replaying full-subtree layers
- Keep content refresh behind the retained fallback, cap GPU submissions to four tile jobs per frame, and adapt estimates from measured work
- Preserve large-radius CPU over-budget visibility while preventing Metal-backed refresh bursts and deferred GPU overload
- Add deterministic node-mutation benchmarks and summarize scheduler throughput, job duration, overruns, and exact content settlement

* perf(canvas): cancel obsolete tile refresh generations

- Count and report queued jobs removed by content or navigation generation changes
- Add deterministic mutation-then-reversal benchmark support without sleeps
- Assert exact tile work remains suspended during navigation and resumes for the final viewport
- Summarize cancellation alongside scheduler throughput, overruns, and settlement metrics

* test(canvas): cover live tiled blur settlement

- Load gold-preview.fig through the real tiled canvas surface and wait on explicit renderer settlement
- Commit the settled radius-210 large-blur browser snapshot
- Replay the canonical zoom reversal during refresh and require byte-identical final canvas convergence

* fix(canvas): harden renderer resource lifecycle

- Release tiled surfaces, images, pictures, and queued work across surface, font, graph, page, structure, and renderer lifecycle boundaries
- Restore pooled canvas, viewport, and backing state through exception-safe native recording and raster paths
- Rebuild tiled chunk topology only when isolation requirements actually change, preserving selective blur mutation performance
- Document deterministic active-renderer settlement and add lifecycle, graph replacement, cache failure, and surface replacement regressions

* test(canvas): remove source-matching renderer claims

- Delete the autopsy suite that inferred runtime correctness from source text, regexes, line placement, and symbol counts
- Keep renderer ordering, cache cleanup, effect behavior, and pixel fidelity covered by executable behavioral and lifecycle tests

* perf(canvas): present retained backing during tiled navigation

- Profile production reversal traces and attribute tiled p95 cost to GPU command-buffer flushes from full-scene fallback replay and tile presentation
- Use the retained backing as the moving fallback while tile scheduling and cached lookup remain allocation-free
- Defer tile image presentation until idle and expose visible versus presented tile counts in navigation telemetry
- Reduce tiled reversal render p95 from about 8ms to 0.3ms while preserving exact idle replacement and visual parity

* perf(canvas): prioritize visible tile settlement

- Profile per-tile allocation, draw, flush, snapshot, and chunk costs through scheduler telemetry
- Defer overscan until all visible exact tiles are covered
- Replace the four-job idle cap with a higher safety ceiling while the measured five-millisecond deadline controls cheap work
- Reduce mutation-plus-reversal exact settlement from about 272ms to 160ms without Long Tasks, overruns, or over-budget jobs

* refactor(canvas): clarify renderer lifecycle boundaries

- Extract retained backing state types and navigation preview timing\n- Isolate tiled scheduler telemetry from frame orchestration\n- Document settlement and CanvasKit ownership invariants\n- Preserve hot drawing loops, budgets, cache limits, and rendering decisions

* fix(canvas): preserve current label rendering

Retain the merged paragraph-label cache lifecycle and substituted-font readiness while reconstructing the renderer stack on current master.

* test(canvas): keep tile benchmark assertions deterministic

Keep performance timing in benchmark telemetry while asserting structural tile selectivity and cache behavior in CI.

* feat(canvas): expose experimental tiled rendering

- Persist retained or tiled canvas mode in General settings\n- Keep retained rendering as the default and apply changes after reload\n- Preserve URL overrides for deterministic benchmarks and support reproduction

* refactor(app): centralize renderer preference state

Expose renderer override provenance from runtime configuration and keep the settings control's derived state separate from its explicit persistence action.

* refactor(app): share settings layout anatomy

Reuse slot-based section headers and bordered groups while keeping each settings control row explicit.

* fix(canvas): harden tiled renderer boundaries

- Bound low-zoom tile planning and handle failed tile surface allocation\n- Preserve effect raster dependencies, runtime-safe clocks, and navigation timing contracts\n- Keep benchmarks deterministic, backward compatible, and accurately localized

* fix(canvas): invalidate dependent node pictures

Track first-child shadow dependencies for retained node pictures so child geometry updates cannot leave stale parent shadows.
2026-08-31 13:39:40 +03:00
Danila Poyarkov 75c358b214 fix(figma-api): validate component property updates 2026-08-31 13:25:15 +03:00
Danila Poyarkov 4f9368f929 fix(figma-api): complete component property review 2026-08-31 12:34:39 +03:00
Danila Poyarkov cb361c4b11 fix(figma-api): preserve variant metadata immutably 2026-08-31 12:30:06 +03:00
Danila Poyarkov ac30791308 fix(figma-api): return immutable property metadata 2026-08-31 12:01:14 +03:00
Danila Poyarkov 0b49d57d05 fix(figma-api): preserve component property metadata 2026-08-31 11:46:19 +03:00