OpenPencil v0.8.2 — Whole Apps, Faithful Imports
Pre-release
Pre-release
v0.8.2 is a prerelease focused on higher-fidelity Figma and HTML imports,
multi-screen AI design generation, lower transient memory use, smoother
large-document workflows, safer .op persistence, and backward-compatible
schema evolution.
This update expands both the data OpenPencil can preserve and the controls
available for editing that data. It also separates expensive conversion and
save work from the interactive UI, tightens overwrite behavior, and documents
where memory is reduced versus where the complete canonical document must
still remain available.
Highlights
- Figma imports preserve substantially more of the authored component,
geometry, compositing, image, text, and page data that previously required
flattening or approximation. - Component instances keep their backing component information, instance
properties, swap targets, overrides, authored geometry, and style
references. - Masks, layer and fill blend modes, image tiling, and page backgrounds now
round-trip through the schema, renderer, web host, and property inspector. - Desktop conversion runs outside the UI thread and reuses prepared values,
source text metrics, image lookups, instance assignments, and component
style references. - Large documents use an active-page editor scene. Native page switching drops
the previous scene before building the next; native and web both fit and
center the newly active page. - Desktop Save and Save As run as serialized background jobs, while native
publication uses atomic writes and source revalidation. - Known legacy
.opformats can be upgraded in place, saved as a numbered
copy, or opened without modifying the file on disk. - HTML import accepts complete pages, multi-file projects, and ZIP packages
with local resources, nested CSS imports, and common text encodings. - The design agent generates multi-screen apps: screen groups can run in
parallel, shared navigation is unified across screens, and app-mode screen
navigation is wired into the generated document. - Panning and zooming very large documents uses layer caching and
level-of-detail so gestures stay responsive instead of dropping to a few
frames per second.
Figma Import Fidelity
Components, Instances, and Swaps
- Component property definitions are retained as structured component backing
data instead of being reduced to only the visible instance result. - Instance property assignments and overrides keep their relationship to the
backing component so later edits can distinguish inherited and authored
values. - Instance-swap properties preserve the selected component target and filter
invalid candidates instead of silently substituting unrelated symbols. - Swapped subtrees retain their authored size, transform, paint, and style
references. Instance scaling is restricted to component-space branches so it
does not rescale ordinary descendants a second time. - Foreign and nested component sessions reuse resolved assignments and style
information, reducing differences between repeated instances of the same
source component. - The property inspector exposes component and swap configuration for imported
instances instead of leaving the imported metadata inaccessible.
Geometry, Layout, and Text
- Authored absolute positioning is preserved for layers that should not be
reflowed by an inferred container layout. - Child order and paint order follow the Figma source more closely, including
mixed container, vector, and mask content. - Boolean operations recover usable child geometry when the preferred result
stream is empty, while genuinely empty geometry stays invisible instead of
becoming a filled placeholder block. - Expanded strokes, open vector networks, fill rules, vector bounds, rounded
vertices, and squircle-like smoothing have more accurate fallbacks. - Image-fill transforms and crop geometry are applied when mapping source
images into their authored bounds. - Source text metrics and baselines are reused consistently, while temporary
glyph, baseline, and font-resolution caches are released after their import
stage. - Text, vectors, image fills, and layout positioning now share more of the same
resolved geometry between interactive rendering and export paths.
Masks, Compositing, Images, and Pages
- Alpha, vector, and luminance masks render through the shared native and web
paint model. - Layer blend modes and individual fill blend modes are represented separately
so compositing does not need to be flattened into a single approximation. - Page background color is preserved in the document and can be edited from
the page section of the property inspector. - Tiled image fills keep their tile scale, while cropped and transformed image
fills retain the source mapping needed for closer visual parity. - Image resolution deduplicates repeated references and transformed assets
instead of decoding or embedding the same source for every occurrence. - The property inspector adds the previously missing controls for masks,
compositing, image tiling, page backgrounds, and component-instance data. - New schema fields are optional, so v0.8.2 can continue reading older
documents and TypeScript object literals that omit them. This does not claim
that every older OpenPencil version can read every v0.8.2 document.
Figma Conversion Performance
- Import preparation decodes and normalizes reusable source values once before
node conversion begins. - Figma-provided text metrics are reused across the relevant conversion stage,
and glyph, baseline, and font-resolution scratch data is released when that
stage completes. - Image lookup and decoded-image work are shared across repeated image
references and instance subtrees. - Component resolution caches instance assignments, swap decisions, style
references, and prepared component data. - The component registry keeps shallow lookup metadata instead of cloning every
master subtree into a second document-sized registry. - Image caches are budgeted by decoded bytes rather than only by entry count,
preventing a handful of very large images from bypassing the cache limit. - Shared image assets are deduplicated into the document image table on save
paths instead of being repeated by each consumer. - Desktop conversion runs in a background import session while the UI
continues processing input and repaint work. Cancellation prevents later
stages and result installation; an already-running, non-interruptible decode
finishes before its worker exits. - Heavy conversion workers are serialized so cancelling and starting another
import does not intentionally overlap two peak conversion workloads. - Large conversion payloads use shared or indirect ownership where possible,
reducing queue copies and temporary allocation amplification. - After a successful desktop conversion, the proposed
.opoutput sits beside
the imported.figsource instead of being kept only in a temporary
directory. - If that sibling
.opalready exists, OpenPencil asks before replacing it.
Replacing, keeping both with a numbered copy, and cancelling the import are
separate user choices. A detected existing target is not replaced without
that decision.
Large Documents, Memory, and Page Switching
- Desktop
.oploading memory-maps the source instead of first copying the
complete file into a second byte buffer. - Preserve-authored documents use a fast loader after validating that the
current shape is safe, avoiding the generic full compatibility DOM on the
common path. - The interactive native and web editor scenes materialize the active page
rather than building render trees for every page at once. - On native page switches, the previous page scene is dropped before the next
scene is built. The web host rebuilds and replaces the active scene. - Switching to a different page automatically fits and centers that page.
Selecting the already active page does not unexpectedly reset the current
viewport. - Non-active pages remain available to the editor but do not keep a full
interactive render scene alive. - This is scene-level memory reduction, not document-level page streaming. The
canonical document still retains the data for every page while the file is
open. - Import, save, and clean-copy paths use streaming or indirection where
practical to reduce duplicated buffers, queue size, and peak transient
allocations.
Canvas Performance on Large Documents
- Pan and zoom on very large documents (tens of thousands of nodes viewed
zoomed out) are substantially smoother. Each change below was measured
against a live profiling session rather than inferred. - The SVG path cache is budgeted by bytes instead of entry count, so a working
set of many thousands of visible paths no longer re-parses its own contents
every frame. - Text below roughly three device pixels skips shaping and paints a
representative bar, and leaf content below sub-pixel size skips painting
entirely. - Shadows and blurs that would render below one pixel skip their save-layers,
avoiding render-pass breaks and forced command submits that were expensive on
GL-backed Metal. - Pan gestures blit a retained offscreen layer with in-place scroll strips and
an approximate scaled zoom. The layer survives across gestures, and the
gesture-end frame restores full quality progressively, one tile per frame. - The event loop places periodic wait deadlines on a fixed grid so elapsed
deadlines are not re-armed immediately, removing an idle timer spin. OP_SLOW_FRAME_LOG=1prints frames over 32ms with blit, scroll, and build
attribution for diagnosing future regressions.
.op Saving and Overwrite Safety
- Desktop Save and Save As are serialized background jobs, preventing
overlapping publications from blocking the UI or committing out of order. - A clean document already bound to a source can stream the original bytes and
rewrite only embedded editor metadata instead of cloning and serializing the
complete canonical document again. - Native writes use an atomic sibling temporary file and publish the
destination only after the new payload has been written successfully. - Desktop Figma sibling publication and legacy-upgrade replacement record the
relevant source or target identity before confirmation and revalidate it
before the final atomic replacement. - If those guarded paths detect an external change before that final check,
OpenPencil preserves the changed file and publishes a numbered copy instead.
The final atomic replacement prevents a partially written destination, but
it is not described as an operating-system-level compare-and-swap. - Generated desktop Figma sibling
.opfiles use the same explicit overwrite
decision and numbered-copy behavior as migrated desktop documents. - Failed serialization, migration, or publication does not bind stale
in-memory state to a path that was not successfully written. - Save completion is checked against the document generation and revision that
started the job, so a late acknowledgement cannot mark newer edits as clean. - Web saves use a queue and coalesce superseded work so an older serialization
cannot publish after a newer edit.
Legacy .op Upgrade and Compatibility
- The current
.opformat marker is1.2. - Desktop upgrade prompts are shown only after a document loads successfully
and needs a known wire-format repair, reliable editor-metadata inference, or
adoption of a legacy metadata sidecar. - A current-format document does not trigger migration merely because optional
editor metadata is absent. - The upgrade prompt provides three explicit outcomes:
- upgrade and replace the original;
- keep the original and write a numbered
.opcopy; - open the repaired in-memory document without changing the file on disk.
- Migration starts from the raw document representation so unknown top-level
and nested fields survive a successful rewrite. - Deeply nested documents use stack-protected decode and encode paths, avoiding
stack exhaustion during compatibility repair. - Successful migration writes the current format marker and embedded editor
metadata. Replacing the original removes its obsolete sidecar only after a
successful commit. - Writing a numbered copy leaves the original file and its sidecar unchanged;
the new copy contains embedded editor metadata and does not adopt a stale
sidecar for the copy path. - Malformed version markers, unsupported very old integer-version payloads,
and future incompatible format majors are rejected instead of being guessed,
normalized, or overwritten. - If migration cannot be published safely, OpenPencil does not install a
misleading saved state or bind the editor to the failed destination.
HTML Import and Code-to-Design
- HTML import accepts complete documents as well as fragments and maps the
result into editable OpenPencil nodes. - Multi-file projects can resolve local stylesheets, images, SVG content, form
controls, and relative resource URLs. - Nested CSS imports and
url(...)resources are resolved through the project
resource graph instead of being limited to one inline stylesheet. - The CSS pipeline applies its supported selector subset and cascade, including
inherited values, variables, common functions, external stylesheets, and
browser-style defaults. - Flex, Grid, absolute positioning, media-query branches, pseudo-elements,
layered backgrounds, blend modes, borders, radii, shadows, and rich text are
mapped into editable OpenPencil structures where a faithful representation is
available. - ZIP project import reads nested paths and Unicode filenames without requiring
users to unpack the project first. - ZIP import rejects path traversal, symbolic-link entries, encrypted or
unsupported compression modes, and packages that exceed bounded resource
limits. - HTML and CSS decoding recognizes common byte-order marks, charset
declarations, and non-UTF-8 text encodings. - Desktop can open or drop HTML projects through a background import session,
while the web host accepts supported file, directory, paste, and ZIP flows. - CLI and MCP routes support HTML import and browser-snapshot conversion for
automation workflows. Remote fetches retain bounded reads and SSRF
protections.
AI Design Agent
Multi-Screen App Generation
- Screen groups can run genuinely in parallel under the parallel-agents
setting, with live progress, per-group replay on completion, and distinct
per-group agent identities. Sequential runs announce their setting too, so
the active mode is always visible. - Multi-screen plans give each screen group its own root frame placed beside
the previous one, instead of collapsing every subtask onto a single root.
Plans with zero or one screen label keep the previous single-root behavior,
and append mode stays single-root. - Generated multi-screen documents carry screen markers and
onTapnavigation,
so app-mode preview navigates between screens instead of degrading to one
scrolling page. The wiring pass is deterministic, idempotent, and additive
only. - Shared navigation bars are unified across sibling screens and injected into
screens whose name matches a reference tab, so a failed navigation subtask
can no longer leave a screen bare. Authored navigation is never removed. - Active tabs are retargeted per screen even when a model draws every screen's
navigation identically, and push-in detail screens (those with a header back
control) no longer receive an injected tab bar. - Tab labels match brand-prefixed screen names by whole tokens, so a screen
named likeWander - Tripsbinds itsTripstab. - Screens the skeleton committed but never filled are detected by shape, retried
through a dedicated fill budget that does not consume the general turn cap,
and reported honestly in the transcript, the run summary, and an(unfilled)
canvas label when they still come up empty. - Design routing reads a canvas signal, so a continuation request in a language
the ASCII keyword gate did not match still reaches the design loop when the
canvas already holds a mobile-width screen. Explicit overrides still win.
Design Quality and Geometry Repair
- Geometry diagnostics detect cross-subtree text collisions, and loop completion
is gated on unresolved blockers rather than reported as done with known
defects outstanding. - A
fill_containercard that collapsed to a sliver beside a fixed-width
sibling in a horizontal rail is widened to the widest fixed reference, before
the overflow clip pass rather than after it. Evenly split and deliberately
mixed fixed rails are left untouched. - Mobile content and section rails are enforced and linted, including appended
subtrees and rail edge cases, and primary mobile screens are required to carry
navigation. - Badges, pills, avatars, status dots, and compact painted text capsules get the
corner radii the surrounding design already establishes, and mobile-app
guidance teaches that tappable CTAs carry a corner radius. - Decorative stack layers are exempt from the empty-shell blocker, which was
pushing models to stuff content into the back layers of a card deck, and a
transparent text-bearing front card gains a surface fill when a painted layer
bleeds through. - Nested card roles survive cleanup, near-full-bleed orphan cards are rescued,
rejected radial sections are recovered, status indicator dots are kept out of
stub cleanup, and clipped child strokes in fit-content rows are padded. - Logical text alignment values are accepted rather than rejected, and compact
status geometry is stabilized.
Providers, Models, and Skills
- The Gemini CLI provider is retired. Antigravity and Grok Build are available
as agent providers and as MCP CLI integrations; the Google Gemini API provider
is unaffected. - Antigravity slug model IDs are discovered correctly, and model capability
tiers were updated (MiniMax M3, Claude Fable, and Kimi K3 are treated as
full-tier). - When a CLI connect or model-discovery probe times out, OpenPencil keeps the
captured output instead of discarding it, recognizes authentication prompts,
and shows an actionable hint — a first-run CLI blocked on browser OAuth no
longer reports only a generic timeout. - Skill prompts are no longer silently truncated: five skills that had drifted
past their injection budgets were compressed, the generation budget is the
intended full-tier value, and both truncation paths now warn instead of
tail-cutting quietly. - Skill names are unique across the registry, so lookup by name is no longer
order-dependent. The publicget_guidelinestopic key is unchanged. - Failed subtasks keep their full spec for single-shot retry, the salvage pass
retries at minimal complexity instead of repeating the full ladder,
rate-limit exhaustion is classified as non-retryable, rolled-back design
batches are marked as errors, and screens committed before a turn cap are
salvaged rather than discarded. - Aborted design validation terminates instead of continuing to run, and the
desktop design terminal preserves its progress output.
Editing and Rendering
- Component swaps, masks, layer/fill compositing, image tile scale, and page
background color are configurable instead of being import-only metadata. - Fill-rule editing, per-corner radii, layer blur, and background blur now
reach the shared scene and paint paths. - Image fills can be cropped interactively, with the crop preview and controls
in the property inspector, and image upload is wired through the file menu
and the fill editor. - Container strokes paint above their children on canvas and in SVG export,
matching the expected stacking instead of being covered by child content. - Editing a property refreshes the affected scenes, so canvas output no longer
lags behind inspector changes. - The right rail is hidden when nothing is selected instead of showing an empty
inspector. - Missing-font prompts and font-management surfaces are available across native
and web hosts, with imported fonts invalidating affected layout scenes. - Native user fonts are persisted and rediscovered at startup; web user fonts
are restored into the browser renderer before affected scenes are rebuilt. - The missing-font dialog and Settings > Fonts share the same font inventory.
Users can import a source font or replace missing families across the
document with case-insensitive matching. - Font replacement is undoable, and importing or restoring a font invalidates
text measurement and CanvasKit family caches so the canvas updates without a
restart. - Image decoding moves off interactive paint paths where possible, with
placeholders and negative caching preventing repeated stalls for slow or
invalid assets. - Headless screenshot and export paths still perform the synchronous decode
work needed to produce a complete deterministic result. - Text baselines, per-corner fill geometry, even-odd shapes, image crop
transforms, and layered compositing are more consistent across canvas,
screenshot, and export rendering. - Property-panel inputs, popovers, hover states, and CJK-aware control widths
receive additional interaction and layout fixes.
Web Runtime and SDK
- Web Figma conversion uses a short-lived Worker with a separate WASM instance
and IndexedDB-backed temporary staging. - The worker stages the generated canonical JSON, terminates after conversion,
and allows the worker's conversion-only WASM memory to be released before the
main editor installs the result. - The main editor still reads and eagerly installs the complete canonical
document; this is not IndexedDB-backed page lazy loading. - If Worker creation, CSP rules, browser storage, or quota prevents the staging
path, import falls back to the compatible main-thread conversion path. - Web saves are queued and coalesced so stale work cannot overwrite a newer
document generation. - Page fitting, masks, blend and compositing data, image tiling, page
backgrounds, and editor metadata round-trip through the web host. - Generated TypeScript schema bindings keep the new properties optional for
v0.8.2 SDK consumers that receive older objects without those properties. @zseven-w/op-web-sdk,@zseven-w/op-web-sdk-react, and
@zseven-w/op-web-sdk-vueare synchronized at0.8.2.- The tag workflow is configured to publish SDK packages under the npm
next
tag and attach the matching package tarballs to the GitHub prerelease. - The public web SDK remains a read-only viewer surface.
VS Code and Automation
- The VS Code extension registers custom editors for
.opand.figfiles and
embeds OpenPencil inside the editor area rather than opening a separate
browser window. - Each managed editor session is backed by the matching local daemon and Rust
web assets, with parent-process and stale-session cleanup. - Offline
.figconversion is routed through the managed daemon and writes a
sibling.op; the source.figfile is never rewritten. - VS Code's implicit sibling save does not currently show the desktop
replace/copy/cancel prompt or select a numbered copy when that.opalready
exists. - VS Code Save, Save As, Revert, backup and hot-exit recovery, undo, redo, and
keyboard focus are relayed to the active OpenPencil document. - MCP routing follows the active custom editor and can keep the most recently
active document reachable while the MCP view owns focus. - Extension commands cover OpenPencil MCP configuration, bundled Skill
installation and removal, and React or Vue code generation. - Untrusted workspaces receive a restricted placeholder instead of starting the
native daemon or exposing editable document capabilities. - Platform-specific VSIX packages bundle the correct daemon architecture and
web assets for each supported target. - MCP document updates preserve responsive sizing keywords, and HTML/snapshot
import routes use the shared conversion and safety limits.
Desktop and Platform Reliability
- Windows desktop startup falls back safely when the preferred native OpenGL
configuration cannot be wrapped by the renderer. - Windows save commits are serialized, avoiding overlapping publications on the
platform where the replace step is least forgiving. - Image search, image generation, Figma conversion, HTML conversion, and save
sessions use bounded or cancellable background work instead of extending the
input event path. - Native and web page switches share fit-and-center behavior while preserving
the viewport when the current page is selected again. - OpenPencil account sign-in entry points are temporarily hidden for this
prerelease and are planned to return in a later version.
Release Artifacts and Distribution
- After the
v0.8.2tag workflow completes successfully, it will build native
desktop installers and standaloneopCLI archives for macOS, Windows, and
Linux. - The workflow will attach platform-specific VS Code extension packages to the
GitHub prerelease and publish them through Open VSX. - It will publish the Rust web host as
ghcr.io/zseven-w/openpencil-web:v0.8.2. - It will publish web SDK packages under the npm
nexttag and attach matching
package tarballs to the prerelease. - Post-release jobs are configured to update Homebrew and Scoop manifests after
the GitHub prerelease is available.
Compatibility Notes and Current Limitations
v0.8.2is a prerelease and uses.opformat marker1.2.- New schema properties and generated TypeScript fields are optional, allowing
v0.8.2 to read older documents and object literals that omit them. - Known legacy formats can be repaired, but future incompatible format majors
are rejected instead of rewritten. - Active-page scenes reduce renderer memory; they do not remove non-active page
data from the canonical document. - Web Figma staging reduces the overlap between conversion-only allocations and
the installed document in the main WASM runtime. Total browser-process peak
memory still depends on the document, Worker, storage implementation, and
browser, and the complete canonical document still enters the main runtime. - The Gemini CLI agent provider and its MCP CLI integration are removed.
Existing Gemini CLI connections no longer appear in Agent Settings; the Google
Gemini API provider is unaffected. - Account sign-in is intentionally unavailable in this prerelease.
- The public web SDK remains read-only.
- The retired TypeScript application workspace is not part of this release.
Acknowledgements
Thanks to the upstream maintainers behind the third-party forks documented in
the README.
Web Docker Image
- Image:
ghcr.io/zseven-w/openpencil-web:v0.8.2 - Digest:
sha256:e13982f18ba3f87ef422c84738be261a337ceccd877aff6ea69a16354fce9775