Skip to content

Releases

OpenPencil v0.8.5 — Design on Desktop, Android, and iOS

Choose a tag to compare

@github-actions github-actions released this 27 Oct 11:27

v0.8.5 brings the Rust editor to Android and iOS, alongside a redesigned
Studio Home and a more complete path from a brief to an editable design and
exported code. This release also improves multi-screen generation, reference
images, interactive previews, and the tools available to external agents.

Highlights

  • Android and iOS editor shells. Touch editing, native file and account
    flows, and lifecycle-aware generation use the shared Rust engine.
  • Studio Home and design workspaces. Start from a prompt or reference,
    compare design directions, and inspect generation results and quality reports.
  • More faithful AI output. Planning and repair better preserve requested
    screens, supplied copy, image intent, and the geometry of repeated layouts.
  • Interactive previews. Preview authored interactions, scrolling, and motion
    alongside the editable canvas.
  • Websites and brands as starting points. Website import and brand
    extraction help turn existing visual material into editable design context.
  • Code export for agents. Deterministic code export is available through
    MCP and the CLI; a lean MCP profile exposes a focused design workflow.
  • Kimi Code integration. Desktop and daemon hosts can run text-only
    generation through the Kimi Code CLI, alongside existing provider integrations.

Android and iOS

The mobile shells share document rendering and editor logic with the desktop
app while using platform-native file pickers, sign-in screens, and lifecycle
handling. Touch selection, panning, pinch zoom, keyboard insets, and model-picker
gestures receive dedicated handling rather than relying on mouse input.

User-started generation can continue through supported background transitions:
Android uses a foreground service, and iOS uses the operating system's
background-processing allowance. Completion and cancellation are coordinated
with the engine lifecycle. These paths remain subject to system time limits,
power policy, and process termination; force-quitting does not preserve a
running generation task.

Android distribution uses a signed APK for direct installation and an AAB for a
later Play Console submission. Both are published with checksums in the GitHub
prerelease. The iOS release lane uploads to App Store Connect for TestFlight
processing. Neither lane automatically publishes an app to Google Play or
submits an App Store review.

AI Generation and Agent Workflows

  • Multi-screen fallback planning keeps declared screens separate instead of
    silently folding them into one composition. Image prompts carry more precise
    subject, aspect, and label intent.
  • Layout repair handles more repeated-row and calendar overflow cases, as well
    as text or glyphs hidden behind shapes. These checks supplement the model's
    output rather than treating a completed response as proof of a usable design.
  • Chat attachments follow provider capability checks. Unsupported attachments
    produce an actionable error while preserving the draft and its images.
  • Mobile chat work is bound to its document, page, tab, and account session, so
    late output from a replaced document or cancelled session is rejected.
  • Codex sessions can continue reconnecting after a stream interruption, and
    Kimi Code gains a dedicated generation transport.
  • MCP and CLI users can export code directly from the document. The lean MCP
    profile offers a smaller sequence for inspecting, generating, checking, and
    finalizing a design.

Editing and Reliability

The home screen's recent-file rows, mobile model picker, and touch cancellation
paths have been refined. Collaboration verification accepts valid signed
policy windows up to ninety days while retaining expiry and signature checks.
The release also updates runtime and TLS dependencies and tightens production
authentication archive verification.

Hosted Model Availability

The Hosted text-model runtime is shared by desktop, daemon, Android, and iOS,
including account-session checks and cancellation of stale requests. Publishing
v0.8.5 with Hosted enabled requires a reviewed, complete, signed ABI 4
authentication matrix and adoption of its release policy. Release and TestFlight
checks must verify that matrix and the ABI selected for each final link before
publication.

Hosted use also requires an active eligible plan, an available provider route,
and sufficient credits. An ABI 3 archive supports sign-in and collaboration but
cannot enable Hosted. Local Debug authentication overrides remain limited to
development builds. Hosted image input remains disabled under the current
billing capability contract.

Upgrade Notes

  • Android and iOS artifacts follow their respective GitHub Release and
    TestFlight channels; TestFlight availability follows Apple's processing.
  • Mobile builds use the same .op document model, but platform-specific export
    and background-execution limits still apply.
  • CLI-based agent integrations run on native desktop or daemon hosts; the
    mobile engine does not launch desktop CLI processes.
  • Source builds must use the adopted, signed authentication artifacts for
    production login and collaboration. Missing or mismatched release inputs
    fail validation rather than falling back to a local Debug archive.

Web Docker Image

  • Image: ghcr.io/zseven-w/openpencil-web:v0.8.5
  • Digest: sha256:cde598b84c61410991b4eae80e792f12780027905b755b96f2e70f5d76e1e514

Verify Your Download

Every asset is listed in SHA256SUMS.txt and carries a signed build-provenance attestation tying it to this repository, commit, and CI run:

gh attestation verify <downloaded-file> --repo ZSeven-W/openpencil

Some antivirus engines heuristically flag low-prevalence installers — see docs/security/antivirus-false-positives.md.

OpenPencil v0.8.4 — The Relay Works, and Agents Can Reach the Rest

Choose a tag to compare

@github-actions github-actions released this 11 Aug 17:15

v0.8.4 has two halves.

The first is corrective. v0.8.3 shipped collaboration end to end, but in the
published builds the public relay could never start: every attempt — China
region or Global, owner or guest — ended with "the public relay is temporarily
unavailable." The service was healthy the whole time. The binaries were not.
The cause was a single space character, and this release fixes it along with
the three separate reasons that one character was able to reach users and stay
invisible: a build that could not detect it, an error that lied about it, and a
diagnostic path that erased it.

The second half closes a gap of a different kind. v0.8.3's presentation
workflow, scene-template catalogue and asset centre were reachable only from
the desktop's own menus, so an agent driving OpenPencil over MCP — or a script
driving it through the CLI — could build a deck and then had no way to hand it
to anyone, could not start from a template, and could not see the style guides
the user had imported. Six tools close that, and the CLI grows the matching
commands.

A third, unrelated failure goes with them: the in-app update check reporting
"cannot reach the release server, check your network connection" on networks
that were working fine.

Highlights

  • Public relay works in published builds. The hub endpoints baked into the
    release binaries were malformed; corrected at the source.
  • A malformed hub endpoint now fails the build. It can no longer ship.
  • Relay errors tell the truth. A refused sign-in, a rate-limited hub, an
    unreachable network and a broken build are four different messages now.
  • Decks, templates and style assets reach MCP and the CLI. Export a deck to
    PowerPoint, HTML or PDF; start from any shipped scene template, including the
    16:9 decks; list the style guides the user imported; batch-export every frame
    on a page. The MCP catalogue grows from 123 tools to 129.
  • Update checks survive shared IP addresses. The probe falls back to the
    releases Atom feed when GitHub's anonymous API quota is exhausted.

The Relay Fix

What happened

The production hub URLs are deliberately absent from the open-source tree. The
release pipeline injects them at compile time from repository secrets, and
relay_bootstrap_select.rs reads them with option_env!.

Both secrets had been saved with a leading space:

" https://op.zseven.cn/api/v1/collaboration/bootstrap"
" https://op.zseven.tech/api/v1/collaboration/bootstrap"

option_env! bakes the value in exactly as stored, space and all. The runtime
endpoint policy is deliberately strict — it rejects any value where
value.trim() != value — so the injected endpoint parsed as no usable hub,
and every relay attempt failed before a single packet left the machine.

Because both secrets carried the space, switching regions changed nothing. And
because the bad character is invisible in every log, every dashboard, and every
strings dump of the binary, nothing pointed at it.

Why it shipped

A guard for exactly this already existed —
injected_bootstrap_urls_pass_the_endpoint_policy_or_stay_absent — and it
passed, vacuously. Repository secrets are not exposed to the CI test job, so
the assertion took its "no hubs injected, nothing to validate" branch on every
run. The release job is the one that receives the secrets, and it ran no
such assertion.

The fix moves the check where neither job can miss it: a build script on
op-collab-host validates the injected endpoints at compile time and fails the
build with an actionable message.

error: failed to run custom build command for `op-collab-host`
  OPENPENCIL_BUILD_COLLAB_BOOTSTRAP_URL_CN is not a usable collaboration hub URL
  (the value has leading or trailing whitespace). Expected exactly
  `https://<host>/api/v1/collaboration/bootstrap` with no surrounding
  whitespace; check the repository secret for a stray space or trailing newline.

An absent variable stays valid — open-source and fork builds legitimately carry
no production hub, and continue to build.

Honest Failure Reporting

The single space was hard to find because the code actively hid it. Three
changes fix that, and they outlive this particular bug.

  • A broken build no longer poses as an outage. An injected endpoint that
    fails the policy now reports as not configured rather than temporarily
    unavailable
    . The old copy invited the user to wait for a condition that could
    never resolve on its own.
  • Control-plane failures are classified. Every call to the relay locator —
    route publication, pairing-code publication, pairing-code claim — used to end
    in map_err(|_| RelayUnavailable). An expired collaboration ticket, a
    rate-limited hub, an unreachable network and a malformed response all reached
    the user as the same sentence. A refused ticket (HTTP 401/403) is now a
    sign-in problem, a rate-limited hub (HTTP 429) is now a retry-later problem,
    and only genuine transport and protocol faults remain "relay unavailable".
    This also gives collab.error.rateLimited, translated in all 15 locales since
    v0.8.3, its first real producer.
  • Stage diagnostics, without credentials. Control-plane failures write one
    line naming the stage and the failure class. Only the failure enum — which
    carries no payload — and a &'static str variant tag are ever formatted; the
    error's own Display is deliberately never used, so a future payload field
    cannot leak into a support log. A test enforces that every tag stays a bare
    variant name.

Decks, Templates and Assets for Agents

Everything below already existed in v0.8.3; none of it was reachable except
by hand, from the desktop app's own menus. An agent could build a deck and not
deliver it, or be told a template catalogue existed and be unable to open it.

Deck export. export_deck { format, outputPath } writes the active page's
boards as an editable PowerPoint, one self-contained HTML file, or a
slide-per-page PDF — op export-deck --output PATH [--format pptx|html|pdf]
from the CLI. It writes a file rather than returning base64: a deck is a
multi-megabyte artifact and the caller wants something shareable. The
destination argument is outputPath, because filePath means "the .op
document this call targets" everywhere in this API.

Scene templates. list_scene_templates and use_scene_template
(op templates, op use-template <id>) open the shipped catalogue, the six
16:9 deck templates included — which makes it the entry point to the
presentation workflow rather than a convenience. On an untouched starter page a
template takes the page over; anywhere else its boards are appended to the
right of what is already there.

Style assets. list_style_guides (op styles) merges the shipped corpus
with the DESIGN.md files the user imported, imports first, as the Asset
Centre paints them. The imports were the gap that mattered: get_style_guide
searches the shipped corpus only, so the user's own material was invisible to
MCP entirely. Passing id returns one guide with its markdown, which is what
closes the loop for an import.

Batch export and deck inspection. export_frames { outputDir, format }
(op export-frames --output-dir DIR) writes one image per top-level frame
using the editor's own file naming — collisions resolved, long AI-authored
names capped, hidden frames skipped — and reports per-frame failures instead of
discarding the files that did land. get_deck_boards lists the boards a deck
export will walk, so a deck can be verified before one is written.

Slideshow control is deliberately not part of this: entering preview is a host
mode transition rather than document state, and a file-backed MCP session has
no window to present in.

The three file-writing tools (export_deck, export_frames,
list_style_guides) are local-filesystem surfaces and are denied on the online
multi-tenant /mcp, for the same reason save_document is.

Update Check

The in-app update check reported "cannot reach the release server, check your
network connection" for users whose network was fine. GitHub's anonymous API
allows 60 requests per hour per source IP, so anyone behind a shared egress
— corporate NAT, a VPN, most China-region proxies — can find the quota already
spent by strangers:

403 {"message":"API rate limit exceeded for <shared-egress-ip>."}

The probe now falls back to the releases Atom feed, which is served by
github.com rather than api.github.com and is not on that quota. The JSON API
stays the first choice for its richer response; the feed only has to cover the
case where the API refuses to answer at all. Drafts never appear in the feed,
which is the same rule the API path already applied.

Fixed

  • Public relay unusable in all published v0.8.3 builds, in both service
    regions, for owners and guests alike.
  • Update check failing with a network error on shared egress IP addresses.
  • A misconfigured relay build reporting as a temporary service outage.
  • Expired collaboration tickets, rate-limited hubs and network faults sharing
    one indistinguishable relay error.
  • Deck export, the scene-template catalogue, imported style guides and batch
    frame export being unreachable from MCP and the CLI.

Upgrade Notes and Compatibility

  • Upgrade to restore the public relay. No server-side change is needed and
    no action is required from you beyond installing this release — the v0.8.3
    hubs, regions and pairing codes were correct throughout. Local-network
    collaboration was never affected.
  • Pairing codes and sessions are unchanged. The 10-character region-tagged
    pairing code, the wire protocol, and the bootstrap document format are
    identical to v0.8.3; a v0.8.4 peer and a v0.8.3 peer interoperate on any
    path a v0.8.3 peer could already reach.
  • Sign-in prompts may replace relay errors. With ticket rejection now
    cl...
Read more

OpenPencil v0.8.3 — Design Together, Present Anywhere

Choose a tag to compare

@github-actions github-actions released this 10 Aug 07:38

v0.8.3 is the release where OpenPencil stops being a single-seat tool. Real-time
collaboration arrives end to end — authenticated peer-to-peer sessions, a public
relay for peers that cannot reach each other directly, and built-in regional
hubs — joined alongside browser device login and an online multi-tenant web mode
authenticated against the op-hub. For the first time, two people (or a person and
an agent) can sit in the same document, see each other's cursors, and reconcile
divergent edits without leaving the canvas.

Around that foundation the release grows a full presentation workflow: six 16:9
deck templates, an AI planner that lays out one slide per screen at projector
size, a live slideshow presenter, and export to PDF, self-contained HTML,
editable PowerPoint, and a video composition. A new scene template center lets
you start from a real layout instead of a blank frame, the prompt and asset
centers mature into full-window surfaces, and an official Chrome web-capture
extension snapshots any live page into OpenPencil.

Under the surface the web bundle gets lighter by fetching templates, the icon
catalog, and preview art at runtime instead of embedding them; theme becomes a
per-device preference; and the account/collaboration stack ships prebuilt
op-auth libraries with safe production trust-root rotation. This document walks
through each area, what problem it solves, how to use it, and who benefits.

Highlights

  • Real-time collaboration — authenticated P2P with a public relay fallback
    and built-in regional hubs, joined with a 10-character region-tagged pairing
    code. Live remote cursors, cross-account sessions, and a conflict panel that
    replays discarded edits.
  • Online multi-tenant web mode — one --serve-web deployment can host many
    tenants, authenticated against the op-hub, with cross-account tenant sharing,
    eviction persistence, and a capability-scoped online /mcp surface.
  • Device login — sign in from the browser through the serve-web daemon, with
    a runtime account gate and authenticated profile avatars and usernames.
  • Presentation decks — six 16:9 templates and a picker, AI planning at
    projector size, a slideshow presenter, and PDF / HTML / PowerPoint / video
    export, backed by agent geometry validation of every board.
  • Scene template center — a browsable catalogue of 58 templates across six
    scenes, from File ▸ New from template, mounted in the browser host too.
  • Chrome web-capture extension — snapshot any webpage into OpenPencil with
    faithful HTML, icon, and layout capture, delivered to your account's snapshot
    inbox on the hub, or downloaded offline as a ready-to-open .op file.
  • Lighter web runtime — scene templates, the icon catalog, and preview assets
    are fetched at runtime instead of embedded in the wasm bundle.
  • Theme is now a device preference on the web host.

Real-Time Collaboration

Collaboration is the headline of this release, and it is built to work whether
your peers are across the desk or across the internet. The goal was a session you
can start in seconds, trust by default, and recover from cleanly when two people
edit the same thing at once.

Starting a session

A session can form three ways, and the client picks the best available path:

  • Direct peer-to-peer. When peers can reach each other, they establish an
    encrypted channel and talk directly — the lowest-latency path, ideal for a LAN
    or a well-connected pair.
  • Public relay. When a direct connection is not possible (NAT, firewalls,
    different networks), a public relay carries the encrypted traffic between peers.
    The client tolerates public-relay handshake latency and reports join failure by
    stage, so a slow or unreachable relay produces an actionable message instead of
    an opaque hang.
  • Regional hubs. Built-in regional collaboration hubs give sessions a nearby,
    known meeting point so peers do not have to discover each other manually.

Whichever path is used, joining is the same: a host shares a 10-character,
region-tagged pairing code
that replaces the older open-invite scheme. The
region tag routes participants to the right hub; the short code is easy to read
aloud or paste. On the desktop the join field lives on the unified text input —
paste-to-replace, selectable, and clearable — so entering a code feels like every
other field.

Presence and live editing

Once joined, every participant is present on the canvas. Remote cursors are
painted with the agent pointer so you can see where collaborators are working in
real time, and their avatars are proxied through the daemon rather than fetched
directly by the browser — the browser never talks to an avatar host on its own.
Edits stream between peers as they happen, and the browser host gained
session-safe sync recovery and SSE fan-in so a reconnect re-syncs cleanly rather
than forking the document.

Resolving conflicts

Concurrent editing means occasional divergence, and OpenPencil surfaces it
instead of silently picking a winner. A conflict panel shows per-node,
per-field detail for the edits that collided and can replay the edits that were
discarded
during a divergence, so a change that lost a race is recoverable
rather than lost. Queued actions are deferred until a gesture's capture closes, so
an in-flight drag on one side does not corrupt the other side's view of the scene.

Cross-account and hardening

Cross-account collaboration lets people signed in to different accounts share one
session — useful when a designer and a reviewer are on separate hub accounts. This
cycle also put substantial work into resilience: resource-exhaustion guards on the
p2p path, whole-second keepalive clamping, secure-relay transport-failure
classification, gesture-capture ordering fixes, an aligned reauthentication
budget, and — most importantly for a hosted deployment — safe rotation of
production trust roots
, so the set of keys a client will trust can change
without breaking live sessions.

Who benefits: designers get pair-design and live review; agent users get a
shared canvas an AI can drive while a human watches the cursor move; teams get a
session model that degrades gracefully across networks.

Accounts, Device Login, and Online Hosting

Collaboration needs identity, so v0.8.3 brings account sign-in out of the earlier
prereleases where it was intentionally hidden.

Signing in from the browser

Browser device login runs through the serve-web daemon: a runtime account gate
governs access to account-scoped features, and once you sign in the editor shows
your authenticated profile avatar and username. The flow reports the machine name
to SSO for device identification. The desktop build links a prebuilt op-auth
library
— shipped for Intel and Apple-silicon macOS, Linux, and Windows (MSVC
and arm64) — so the auth bridge is available without a separate build toolchain,
and it is linked to survive thin-LTO release builds.

Online multi-tenant mode

The --serve-web daemon can now run as a shared, multi-tenant host rather than a
single-user server. Tenants are authenticated against the op-hub, and the mode
supports cross-account tenant sharing whose membership persists across
evictions, plus session node creation, account-switch isolation, and tenant-aware
URLs so one deployment cleanly serves many accounts. The online /mcp surface
authenticates the live endpoint and enforces a capability profile and scope,
so a hosted MCP client only sees the tools and documents it is entitled to, and
the bootstrap cache degrades safely when the endpoint is unavailable.

Who benefits: developers and teams can stand up one hosted OpenPencil for a
group instead of one server per person, with per-tenant isolation and a scoped
automation surface.

Presentation Decks

Decks are a first-class document type in v0.8.3, closing the loop from "generate a
layout" to "stand up and present it."

Templates and planning

Start from one of six 16:9 deck templates through the template picker, or
describe a deck and let the AI plan it. The planning corpus learned that a
projector board differs from a page: the agent plans a deck at projector size
with one slide per screen, scaffolds the screen roots in a single insert, and
wraps multi-board templates onto rows on the canvas. Crucially, the agent now
judges each board by its geometry as well as its prompt — pinning boards to the
projector aspect, centering board content instead of stacking it at the top, and
reporting row overflow rather than clipping it — so generated decks come out
presentation-ready.

Presenting

A deck can be presented as a slideshow directly in preview, with presenter
controls to drive it forward and back. A dedicated slides rail is the deck's
single navigator, replacing ad-hoc scrolling with a predictable slide list.

Exporting

When a deck is done, export it to the format the audience needs:

  • PDF — one page per slide.
  • Self-contained slideshow HTML — a single file that plays anywhere a browser
    is available, no assets to ship alongside.
  • Editable PowerPoint (.pptx) — hand off to anyone who lives in PowerPoint.
  • Hyperframes video composition — emit the deck as a motion composition.

Who benefits: designers can produce a real deck without leaving the tool;
developers and PMs get portable output (PDF/HTML/PPTX) that drops into existing
workflows.

Scene Templates, Prompt Center, and Asset Center

Three surfaces matured this release to make starting and iterating faster.

  • Scene template center — a browsable catalogue that grew to 58 templates
    across six scenes
    , opened from File ▸ New from template, mounted in the
    browse...
Read more

OpenPencil v0.8.2 — Whole Apps, Faithful Imports

Choose a tag to compare

@github-actions github-actions released this 25 Jul 05:43

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 .op formats 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 .op output sits beside
    the imported .fig source instead of being kept only in a temporary
    directory.
  • If that sibling .op already 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 .op loading 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=1 prints frames over 32ms with blit, scroll, and build
    attribution for diagnosing future regressions.

.op Saving and Overwrite Safety

  • Desktop Save and Save As are seri...
Read more

v0.8.1-enhance

v0.8.1-enhance Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 16 Jul 14:35

OpenPencil v0.8.1

v0.8.1 is a pre-release update for the Rust OpenPencil stack. It expands native agent and MCP integrations, makes the AI-assisted design loop more reliable, adds richer preview and export workflows, improves editor responsiveness and web rendering clarity, hardens web credential handling and host-local configuration isolation, and centralizes product-version management.

Highlights

  • Antigravity and Grok Build are now first-class native CLI providers, with executable and authentication probes, model discovery, branded settings and model-picker entries, subprocess chat routing, and MCP configuration support.
  • The design agent now uses transactional batch updates, four bundled design systems, bounded geometry-aware repair, stronger image-slot handling, and progress-ring preservation to produce more reliable layouts without unbounded retries.
  • Desktop Preview adds Phone, Desktop, and Canvas presentation modes, scrolling inside fixed device frames, phone-only pinning for detected bottom navigation, and geometry-accurate painting and pointer mapping.
  • Desktop and web SVG export can tightly crop one selected node, while CLI and MCP export pages, arbitrary nodes, or the live selection as PNG, JPEG, WebP, or PDF.
  • CanvasKit caches, on-demand SDK animation frames, cached transcript and layer layouts, structurally shared undo history, and fewer document clones improve active and idle performance.
  • CanvasKit uses the browser's full display scale with a 2x quality floor, keeping small text and one-pixel UI details sharper when an embedded browser reports DPR 1.
  • Browser deployments keep web-entered credentials in same-origin storage by default, while trusted private deployments can explicitly opt into a server-persisted shared copy.
  • The web host no longer imports local ~/.zode provider configuration; native desktop startup retains Zode discovery for local workflows.
  • Rust crates, SDK packages, installers, bundled CLI metadata, and release publishing now derive from or are checked against the root Cargo workspace version.

Native Agents and MCP

Antigravity and Grok Build

  • Native Agent settings and the chat model picker now include Google Antigravity and xAI Grok Build with dedicated branding and provider identities.
  • OpenPencil resolves the agy and grok executables across supported platforms, probes installation and authentication state, and provides actionable setup guidance when a provider is unavailable.
  • Model discovery queries agy models and grok models with bounded execution, parses their supported text and JSON catalog shapes, and falls back to a provider default when an installed CLI does not expose a usable catalog.
  • Chat sessions route through hardened subprocess parsing and safety rules. Canvas-agent chat turns and tool-free orchestrator, subtask, and code-generation turns use separate subprocess policies, preventing canvas MCP permissions and automation guards from leaking into structured generation.
  • The MCP integration grid now includes Antigravity and Grok Build alongside Claude Code, Codex, Gemini, OpenCode, Kiro, and GitHub Copilot. Enabling or disabling OpenPencil updates the relevant client configuration while preserving unrelated servers and settings.

Generation Experience

  • Design-loop narration, thinking, and tool activity now appear chronologically in the transcript instead of being grouped out of order.
  • Streamed Markdown, clearer tool chips, stable agent identity, and unified generation feedback make native and CLI-backed runs easier to follow.
  • Canvas generation uses sequential placeholders, animated agent presence, and five selectable Pencil-style cursors to show which area is being produced without obscuring completed content.

Design Agent Quality

  • Transactional batch updates keep a failed design operation from leaving a partially applied document.
  • Four built-in shadcn-vocabulary design systems—Halo, Lunaris, Nitro, and shadcn—can install complete Light and Dark variable tables in one undoable step.
  • Repair is explicit and bounded. Geometry-aware passes handle overlaps, undersized content, radial stacks, image slots, and common scaffold defects without entering an unbounded retry loop.
  • Image repair keeps one image per intended slot, reconnects stray photos to their containers, and avoids stretching controls or treating oversized decorative plates as image intent.
  • Progress rings and other radial compositions retain their arc semantics and are recentered against final resolved geometry across platforms.

Preview, Canvas, and Editing

  • Desktop Preview provides Phone, Desktop, and Canvas modes with device-frame clipping, vertical scrolling, accurate hit mapping, and phone-only pinning for recognized bottom navigation.
  • Desktop clipboard paste accepts image data directly into the document.
  • Multiple fills can be reordered without rebuilding unrelated paint layers.
  • Component-instance child property edits are stored as overrides with undo-safe history.
  • Web text rasterization accounts for display scale, and the CanvasKit backing store now has a 2x minimum render scale for sharper text and chrome in browsers or webviews that report DPR 1.
  • Web startup no longer reads local Zode provider settings, preventing native-only model configuration from appearing as partially synchronized browser state.
  • Jian updates normalize text line-height semantics and treat designMd and conversion as known top-level schema fields.

Export and Automation

  • Desktop and web SVG export tightly crop exactly one selected node and otherwise export the full active page. SVG is also available in the property-panel export controls.
  • CLI and MCP export pages, arbitrary node IDs, or the live selection as PNG, JPEG, WebP, or PDF.
  • Headless MCP startup validates the target .op document before serving, so malformed or unsupported input fails early instead of creating a broken automation session.

Performance and Web SDK

  • CanvasKit paint objects and fonts are cached instead of being recreated across frames.
  • The web SDK requests animation frames only while work is pending, reducing idle CPU use.
  • Transcript and layer-panel layout caches avoid repeating text measurement and tree layout for unchanged content.
  • Undo snapshots share unchanged document structure, and editor mutation paths avoid several whole-document clones.
  • The React and Vue adapters ship with the base @zseven-w/op-web-sdk package family; the public SDK remains a read-only viewer surface.

Web Credential Persistence

Browser-entered built-in provider, image-generation, and Openverse credentials are stored separately from ordinary preferences in same-origin localStorage. By default, built-in provider credentials are attached only to AI requests that need them, and the daemon does not persist the browser credential snapshot to settings.json. At startup, browser-only mode removes browser-owned credentials left there by an earlier configuration.

Browser POSTs to credential and AI endpoints must pass an origin check, provider targets are validated, and upstream error bodies are not returned directly to browser clients. Public reverse proxies must list exact browser origins in the comma-delimited OPENPENCIL_WEB_ALLOWED_ORIGINS setting.

Trusted private deployments can enable server persistence with:

OPENPENCIL_PERSIST_WEB_CREDENTIALS_SERVER=true

This creates a deployment-wide shared credential copy and is intended for an access-controlled deployment with one active administrator profile. It does not permit unrestricted outbound requests. Internal provider origins must be listed separately in OPENPENCIL_WEB_AI_ENDPOINT_ALLOWLIST. Because same-origin scripts can read localStorage, deployments must also protect the web origin from untrusted scripts and XSS.

The web host continues to expose built-in API-key agents only. CLI and ACP agents, including Antigravity and Grok Build, remain native-only and are not exposed through web connect routes.

Web startup also does not import provider credentials or model entries from the host user's ~/.zode configuration. Zode discovery remains available to the native desktop host, where the configuration is local to the running application. This keeps browser and native provider catalogs intentionally separate instead of presenting unsynchronized local entries in the web model picker.

Release Engineering

  • Root Cargo.toml is the canonical product version source. Rust crates inherit it through workspace metadata, and release/installer paths consume the same value.
  • scripts/sync-version.sh refreshes managed version copies and runs the guard; tools/check-version-sync.sh rejects drift across Rust metadata, the bundled CLI, SDK packages, installers, and release publishing.
  • The explicit .op formatVersion and stable test-fixture versions remain independent of product releases and are intentionally excluded from product-version synchronization.
  • CI now runs native builds and tests on Linux, macOS, and Windows; cross-architecture compile checks for macOS and Windows; Android and iOS compile checks; plus wasm32 compile and real CanvasKit bundle guards.

Release Artifacts

  • Native desktop installers and standalone op CLI archives for macOS, Windows, and Linux.
  • ghcr.io/zseven-w/openpencil-web:v0.8.1 for the Rust web host.
  • @zseven-w/op-web-sdk, @zseven-w/op-web-sdk-react, and @zseven-w/op-web-sdk-vue under the npm next tag, with package tarballs attached to the GitHub prerelease.
  • Updated Homebrew and Scoop manifests after the prerelease is published.

Compatibility

  • The supported .op formatVersion remains 1.1, unchanged from v0.8.0.
  • The public web SDK remains a read-only viewer surface.
  • The retired TypeScript application workspace is not part of this release.

...

Read more

v0.8.0-Second Vow

v0.8.0-Second Vow Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 09 Jul 15:45

OpenPencil v0.8.0

v0.8.0 is a pre-release for the Rust OpenPencil stack. It marks the first release line where the Rust desktop, CLI, web host, and wasm-backed SDKs are the actively shipped OpenPencil product surface.

Highlights

  • Rust desktop app is now the primary OpenPencil experience, with installer artifacts for macOS, Windows, and Linux.
  • op CLI ships as standalone release artifacts for the same desktop target matrix.
  • Rust web host is published as a GHCR Docker image for tagged releases.
  • Web SDK packages are published to npm and attached as tarballs for @zseven-w/op-web-sdk, @zseven-w/op-web-sdk-react, and @zseven-w/op-web-sdk-vue.
  • Homebrew tap and Scoop bucket entries are updated after the GitHub pre-release is published.
  • Desktop update checks can discover pre-release GitHub releases, so v0.8.0 can be offered before it is promoted to a stable release.
  • Issue triage for this release reviewed 19 open GitHub issues: 5 are expected to close with v0.8.0, and 3 are partially covered but should remain open unless split into follow-ups.

What's New

Rust Editor

  • The Rust editor shell is the release target for the canvas, panels, toolbar, property inspector, AI chat surface, agent settings, and desktop/web hosts.
  • Canvas painting, hit-testing, and editor chrome now share the layout-resolved LayoutScene path, reducing stale scene lookups during hover, selection, pen editing, and reveal paint.
  • Rotated canvas elements now keep editor chrome aligned with rendered geometry:
    • hover outlines follow the hovered node's root-to-node flip/rotation chain;
    • single-selection and multi-selection outlines inherit rotated/flipped ancestor transforms;
    • selected path editor handles and arc-edit handles inherit the same transform chain;
    • fallback behavior still preserves direct node rotation for callers that do not have traversal-captured transforms.
  • Canvas interaction paths continue to support pan/zoom, selection, handle hit-testing, rotation handles, pen/path overlays, smart guide overlays, layer hover state, and reveal animation paint.
  • The widget layer remains platform-clean: native and web rendering go through the shared RenderBackend facade rather than Skia or browser APIs in widget code.

Desktop App

  • Desktop artifacts are built from the Rust native host for macOS, Windows, and Linux.
  • The desktop app can detect release availability from GitHub, including pre-release builds when the pre-release channel is enabled.
  • File opening, recent-file persistence, MCP/web-service integration, and editor chrome are shipped through the Rust app path.

CLI

  • The op command-line tool is distributed as a standalone binary alongside desktop artifacts.
  • Installer scripts support stable releases by default and can opt into the newest pre-release with OP_PRERELEASE=1.
  • Package manager manifests are updated for both desktop and CLI distribution channels after the GitHub pre-release is published.

Web And SDK

  • The Rust web host is published as a GHCR image tagged with the release version.
  • The web host agent settings expose built-in agent profiles only; desktop/CLI-oriented provider connect cards, ACP agent setup, and the MCP tab are hidden from the web UI.
  • The public web SDK remains focused on viewing .op files, backed by the Rust wasm bundle.
  • React and Vue adapters are published with the base SDK so host apps can embed .op viewers without depending on the retired TypeScript app workspace.

Rust vs. TypeScript v0.7.5

v0.8.0 is not a routine patch on top of the TypeScript app. It is the first release line where the Rust implementation replaces the retired TypeScript + Electron stack that ended at v0.7.5.

Feature Comparison

Area TypeScript + Electron (v0.7.5) Rust (v0.8.0)
Primary app React 19 + TanStack Start web app packaged with Electron 35. Rust editor shell shared by desktop, web host, and SDK-backed rendering paths.
Desktop runtime Electron app with bundled Chromium and Node.js runtime. Native winit + GPU Skia desktop binary; no embedded browser engine.
Canvas and editor UI CanvasKit/Skia canvas driven from React, Zustand stores, and pen-* packages. Layout, hit-testing, painting, overlays, and editor chrome run through Rust LayoutScene and RenderBackend.
CLI op CLI compiled from TypeScript and connected to the web/desktop server path. Standalone Rust op binary shipped for the same macOS, Windows, and Linux target matrix as desktop.
MCP pen-mcp Node/Bun package with Node.js fallback behavior. Built-in Rust op-mcp path; desktop can expose stdio and live HTTP MCP endpoints without requiring Node.js for the main app path.
AI runtime agent-native Zig NAPI plus TypeScript service wrappers for providers and agent orchestration. Rust agent runtime from vendor/agent, with provider integration in the Rust workspace.
SDK surface pen-engine, pen-react, and related pen-* packages exposed a broader TypeScript embedding/editing surface. Public npm SDKs are intentionally narrower: read-only .op viewing through the wasm-backed op-web-sdk, plus React and Vue adapters.
Code organization Root JavaScript/Bun monorepo with apps/* and packages/pen-*. Root Cargo workspace in crates/; JavaScript/Bun only remains under packages/ for web SDK publishing.

Performance And Footprint Comparison

Area TypeScript + Electron (v0.7.5) Rust (v0.8.0)
Desktop footprint Ships a full Chromium runtime and Node.js-backed desktop stack. Native desktop artifacts per target, with no embedded browser engine; exact binary and installer sizes vary by OS, architecture, and packaging format. Current raw desktop binaries are roughly in the mid-50 MB range.
Web payload JavaScript application plus CanvasKit/WASM payload. Rust web build measured at 8.2 MB wasm / 2.18 MB gzip over the wire after icon catalog splitting.
Rendering consistency Web and desktop behavior depended on the web app/Electron runtime boundary. Native and web targets share the Rust render path: skia-safe on native, CanvasKit on WebGL2.
Interaction hot paths React/store synchronization could put document serialization and state updates on interactive paths. Pan/zoom no longer re-serializes the document every frame; wheel-zoom CPU was reduced from about 69% to about 0% on the measured hot path.
Large documents No comparable large-document benchmark is published in this repository for v0.7.5. A 10,000-node nested auto-layout canvas writes, reads, and snapshots layout with no panics and about 0% idle CPU; a full layout snapshot returns in about 0.68 s.
Memory model JavaScript garbage collection can introduce latency variance. Rust ownership avoids GC pauses on editor-state and layout hot paths.

These numbers are release-note level measurements from the Rust release line and are intended to explain the migration impact. They are not a full benchmark suite across every v0.7.5 workflow, and artifact sizes should be checked against the final release assets for each platform.

Issues Addressed

As of 2026-07-09, the GitHub issues page has 19 open issues. Based on the v0.8.0 feature set and the Rust replacement scope, this release is expected to close 5 of them after final release validation:

  • #129 — completes the Rust rewrite tracked by the public planning issue.
  • #123 — replaces the @zseven-w/agent-native chat crash path with the Rust agent runtime.
  • #148 — ships OpenCode support through the Rust agent settings and chat provider path.
  • #163 — replaces the Docker image path that depended on a missing @zseven-w/agent-native runtime package.
  • #164 — adds SVG export through the Rust export pipeline, including desktop/web host export and web SDK active-page SVG export.

The release also partially covers several open issues, but they should stay open unless the remaining scope is split into follow-up issues:

  • #62 — Gemini support is present, but Stitch import is not covered by this release.
  • #120 — Linux native artifacts are included, but the remote-file workflow request is broader than packaging.
  • #162 — the Rust release addresses parts of the crash/export surface, but the issue also includes UI, clipboard, fill-layer, and text-quality requests.

Compatibility And Migration Notes

  • The retired TypeScript apps and pen-* packages are not included in this release line.
  • The repository root is now a Cargo workspace. JavaScript/Bun tooling for the SDK family lives under packages/.
  • Consumers that previously depended on the retired TypeScript app packages should migrate to the Rust desktop app, the op CLI, or the read-only web SDK depending on their use case.
  • npm packages for this pre-release are published under the next dist-tag rather than replacing the stable npm tag.

Release Artifacts

  • macOS: notarized OpenPencil-0.8.0-<arch>-mac.dmg for the desktop app, plus standalone op CLI archives.
  • Windows: OpenPencil-0.8.0-<arch>-win-setup.exe, plus portable desktop and op CLI archives.
  • Linux: OpenPencil-0.8.0-<arch>-linux.AppImage, OpenPencil-0.8.0-<arch>-linux.deb, plus raw desktop and op CLI archives.
  • Web SDK: published npm packages and attached npm tarballs for the base SDK, React adapter, and Vue adapter.
  • Pa...
Read more

v0.7.5 — Quiet bugs, loud now

Pre-release

Choose a tag to compare

@Kayshen-X Kayshen-X released this 26 Apr 11:23

A maintenance pre-release focused on three quietly broken behaviors. All three are user-reported issues from 0.7.4. Binaries for macOS, Windows, and Linux are attached below once the build matrix finishes.

🐛 Fixes

AI providers — fetch failed is now actionable (#121)

Custom OpenAI-compatible providers used to surface Node's opaque TypeError: fetch failed for every network failure — DNS lookup, TLS handshake, connection refused, timeout — all collapsed into one useless string. The real reason was already on error.cause but never reached the UI.

formatFetchError() now walks the cause chain (including the AggregateError undici emits when multiple A records all fail) and prefixes the SystemError code, so the AI Settings dialog and chat stream show:

ENOTFOUND: getaddrinfo ENOTFOUND api.example.com
ECONNREFUSED: connect ECONNREFUSED 127.0.0.1:8080
self-signed certificate in certificate chain

…instead of fetch failed.

Electron — agent-native binary now ships on every platform

The Zig NAPI provisioner had a silent failure mode that bit any matrix entry without a matching prebuilt release: the source-build fallback dropped agent_napi.node at zig-out/napi/…, but electron-builder only ships from packages/agent-native/napi/. Affected installs (commonly Windows) launched fine but died at the dynamic @zseven-w/agent-native import the moment chat was used.

  • Always source-build on the runner — mlugg/setup-zig is provisioned for every workflow
  • Always copy the built binary into napi/agent_napi.node so electron-builder packages it
  • Cross-compile per platform via `ZIG_TARGET` — `mac-x64` on arm64 runners now produces an x86_64 binary, not a wrong-arch arm64 one
  • Strict mode (`OPENPENCIL_REQUIRE_AGENT_NATIVE=1`) plus a dedicated Verify agent-native binary workflow step fails the build loudly if the binary is missing

📚 Docs

Issue What changed
#116 Removed obsolete `op export` references from 15 root READMEs, 15 `apps/cli/` READMEs, AGENTS.md, and CLAUDE.md. The export command was retired in favor of the multi-stage `codegen:plan / submit / assemble` pipeline.
#117 Rewrote `packages/pen-mcp/README.md`. The previous `npx @zseven-w/pen-mcp` quick-start never worked — the package ships TypeScript source against workspace-only deps with no `bin` entry. New section explains how to run the server from the monorepo and how external MCP clients connect over HTTP at `http://localhost:3100/mcp\`.

🧪 Verification

  • 1525 / 1525 unit tests passing (Vitest, 151 files)
  • 0 lint warnings (oxlint, 818 files)
  • 0 TypeScript errors (strict mode)
  • 14 new tests covering `formatFetchError` cause-chain unwrapping and AggregateError handling

⚠️ Pre-release notice

This build is published for early testing of the agent-native packaging fix — particularly on Windows where it most often regressed. If you're on a stable distribution channel and only want shipped releases, wait for v0.7.6 stable.

Full Changelog: v0.7.4...v0.7.5

v0.7.4-enhance

v0.7.4-enhance Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 17 Apr 11:27

Summary

OpenPencil v0.7.4 focuses on reliable AI design generation on dark themes, smarter incremental edits, and
a hardened native agent runtime (MiniMax tool_use, Windows, openai-compat streaming).

Changes

AI / Design generation

  • fix(ai): stop white section bands on dark-themed pages — skip fixSectionAlternation when parent
    fill luminance < 0.5, and strip stale SAFE_LIGHT_HEXES from earlier runs
  • feat(ai): design.md-driven background + sidebar color pipeline (orchestrator planning, sub-agent
    prompts, and MCP all share the palette policy)
  • feat(ai): append-intent detection — "continue"/"add more" prompts reuse the existing content root,
    and sub-agents get an APPEND MODE preamble listing existing siblings
  • feat(ai): snapshot_layout now emits an overlaps array; when the parent is layout: "none" the
    reason points at absolute x/y stacking so agents fix the parent instead of resizing children
  • docs(ai): horizontal scroll card-row pattern with full clipContent + nested fit_content example
  • chore(ai): enable incremental-add skill in the generation phase

Canvas / Editor

  • fix(canvas): require explicit role:'overlay' to escape auto-layout — badge/pill/tag are
    inline roles again and flow normally instead of collapsing to (0,0). isBadgeOverlayNode renamed to
    isOverlayNode; a deprecated re-export keeps external consumers of @zseven-w/pen-core building
  • fix(canvas): render synchronously on resize to prevent the one-frame white flash when flex layout
    shifts (e.g. right panel mount on first selection)
  • feat(editor): paste anchors to the selected container (or as sibling) instead of always landing at
    document root

Renderer

  • feat(renderer): enable local OS fonts with vector rendering and proper permission handling (#110)

Agent (native)

  • chore(agent): bump agent-native to v0.4.0 — absorbs upstream v0.2.0/v0.3.0 (openai-compat
    tool_calls streaming, HTTP error diagnostics), MiniMax tool_use 400 fix (placeholder text block when
    assistant turn is tool_use-only), auto-detected MiniMax Anthropic-compat quirk, and Windows N-API symbol
    export

MCP / Tooling

  • fix(mcp): run codex via shell on Windows so PATHEXT resolves .cmd/.bat shims (works around the
    Node CVE-2024-27980 execFileSync restriction)
  • ci(publish): check-before-publish; package names derived from each manifest so workflow/manifest
    drift is impossible — fixes the spurious CLI-step 404 on re-runs
  • style(lint): clear 22 oxlint warnings across repo
  • chore: ignore .omx/

Type

  • feat — New feature
  • fix — Bug fix
  • docs — Documentation
  • chore — Build / tooling / dependencies

Checklist

  • npx tsc --noEmit passes
  • bun --bun run test passes
  • No unrelated changes included
  • Commit messages follow Conventional Commits

v0.7.3-enhance

v0.7.3-enhance Pre-release
Pre-release

Choose a tag to compare

@Kayshen-X Kayshen-X released this 15 Apr 14:42

Summary

v0.7.3 introduces incremental "append mode" for AI design generation — when the user
asks the AI to add content to an existing canvas, the planner now detects append intent and
reuses the current content root instead of redrawing from scratch. Also ships local OS
font support via the Local Font Access API with vector rendering, a design.md-driven
background/sidebar theming pipeline, and a handful of editor, CLI, and cross-platform
fixes.

Changes

AI / design generation

  • feat(ai): append-mode detection before generate_design dispatch —
    detectAppendIntent parses continue/append prompts against the active page
  • feat(ai): sub-agent preamble describes existing sibling sections so added nodes
    integrate seamlessly
  • feat(ai): planner reuses existing content-root in append mode instead of creating a new
    root frame
  • feat(ai): applyAppendContextToPlan helper wires context into the orchestrator plan
  • feat(types): AppendContext + SubTask.existingSectionLabels
  • feat(ai): design.md-driven background + sidebar color pipeline; auto-derives neutral
    page background when design.md has no explicit background role
  • fix(ai): stop white section bands on dark-themed pages
  • docs(ai): horizontal scroll card-row pattern taught to the generation phase;
    overflow.md example fleshed out

Fonts

  • feat(renderer): enable local OS fonts with vector rendering via the Local Font Access
    API; includes permission handling (prompt / granted / denied / unavailable),
    canvas-width heuristic for unknown local fonts, and blob-based registration into CanvasKit
    (#110)

Editor

  • fix(canvas): render synchronously on resize to prevent a one-frame white flash when
    RightPanel mounts on the first selection after idle
  • feat(editor): Cmd/Ctrl+V now pastes into the selected container (if it can hold
    children) or immediately after the selected node as a sibling, falling back to the root
    when nothing is selected

CLI / cross-platform

  • fix(mcp): on Windows, run the Codex CLI through execSync so PATHEXT resolves
    .cmd/.exe/.ps1 shims (works around Node 18.20/20.12 execFileSync EINVAL from
    CVE-2024-27980)

Code hygiene

  • style: apply oxfmt formatting drift across web, renderer, and AI modules
  • style(lint): clear 22 oxlint warnings (useless spread fallbacks, useless spread into
    arrays, control-char regex → \P{ASCII}, unused catch params / imports, unnecessary
    escapes, new Array(n).fill) — repo now lints with 0 warnings, 0 errors
  • chore: ignore .omx/ build artifact directory

Related Issues

  • Merges #110 (local OS fonts with vector rendering and permission handling)

Type

  • feat — New feature
  • fix — Bug fix
  • refactor — Code refactoring (no behavior change)
  • docs — Documentation

Checklist

  • npx tsc --noEmit passes
  • bun --bun run test passes — 1515 tests in apps/web + 47 in packages/pen-mcp,
    all green
  • No unrelated changes included
  • Commit messages follow Conventional Commits
  • bun run lint — 0 warnings, 0 errors (added as a bonus of this rollup)

What's Changed

  • Enable local OS fonts with vector rendering and proper permission handling by @1MochaChan1 in #110

New Contributors

Full Changelog: v0.7.2...v0.7.3

v0.7.2-bugfix

v0.7.2-bugfix Pre-release
Pre-release

Choose a tag to compare

@Kayshen-X Kayshen-X released this 14 Apr 13:47

Summary

v0.7.2 is a stability release focused on multi-provider AI agent loops,
Mac CLI discovery across managed shells, and drag / reparent / clipping
correctness
on the canvas. It also ships bounded AI codegen handoff so chat
payloads stop hitting provider request-size limits silently.

Changes

AI agent loops — multi-provider correctness

  • OpenAI-compatible providers: fix the second turn. Before, the request
    builder forwarded the message store's Anthropic-style content blocks
    verbatim, so tool-result turns 400'd on GLM / dashscope / StepFun.
    @zseven-w/agent-native v0.3.0 now translates tool_use + tool_result
    blocks into OpenAI's tool_calls + role="tool" form, injects
    system_prompt, and drops unsupported thinking blocks.
  • Tool-call streaming for OpenAI-compat. The SSE parser now accepts
    delta.tool_calls and emits content_block_start / tool_use_delta /
    content_block_stop so tool invocations from GLM / DeepSeek / Qwen /
    dashscope flow through the same pipeline as Anthropic.
  • StepFun step_plan/v1 support. Accept delta.reasoning alongside
    reasoning_content so StepFun's reasoning-heavy stream renders instead of
    stalling the client-side first-text watchdog into an abort → std.http
    panic → Bun segfault cascade.
  • HTTP 451 / content-safety surfacing. Map StepFun's 451 to
    error.InvalidRequest with a specific "Content blocked by provider safety
    filter" message; /api/ai/chat now forwards result.errors[0] so users
    see the real reason instead of Provider error: error_server.
  • firstTextTimeout relaxes on thinking activity. When the model is
    streaming reasoning, the "no first text yet" watchdog stands down —
    noTextTimeout + hardTimeout still bound genuinely runaway reasoning.

Orchestrator sub-agent resilience

  • Minimal-skills fallback. After the full-skills attempt and its retry
    both produce zero nodes, the orchestrator re-runs just the failing subtask
    with a ~3KB kernel prompt (schema + jsonl-format only). Successful earlier
    subtasks are preserved; only the failing one retries.
  • Skip deterministic refusals. Responses matching HTTP 400/401/429/451,
    "content blocked", "censorship", or "authentication failed" short-circuit
    the retry ladder so users aren't charged a second 4-minute StepFun safety
    scan.

Local CLI discovery — Mac / managed-shell users

  • Login-shell probe. New probeViaLoginShell() asks $SHELL (or a zsh /
    bash / fish fallback) -ilc 'command -v <cli>' to source the user's
    real rc/profile. This catches nvm / fnm / pnpm / bun / mise / asdf / volta
    shims that Electron's scrubbed PATH hides.
  • Expanded candidate paths. posixUserBinDirs() now includes
    ~/.bun/bin, ~/.volta/bin, ~/Library/pnpm, ~/.pnpm-global/bin,
    ~/.local/share/mise/shims, ~/.asdf/shims, ~/.cargo/bin, plus
    dynamically enumerated ~/.nvm/versions/node/<ver>/bin and
    ~/.fnm/node-versions/<ver>/installation/bin.
  • Uniform ladder across every resolver. claude / codex / opencode /
    copilot / gemini all run the same PATH → login-shell → npm-prefix →
    user-bin candidates sequence, each step logged to
    ~/.openpencil/logs/server-YYYY-MM-DD.log for remote diagnosis.

Built-in providers

  • Add "StepFun Coding Plan" preset (https://api.stepfun.com/step_plan/v1).

Electron / dev-sync stability (#104)

  • Stabilize Electron dev startup after the upstream sync.
  • Keep localhost probing resilient without relying on proxy-friendly fetch
    behavior.
  • Unblock incomplete local workspaces and keep Codex-related env passthrough
    working.

Drag / reparenting / nested clipping (#104)

  • Preserve absolute/world position when layer moves change parent containers
    — nodes no longer jump visually after reparenting.
  • Stop nested frame / group / shape drags from auto-ejecting to root during
    canvas drags.
  • Promote previously root-only frame clipping to explicit clipContent when
    nested, so corner radius and clip visuals stay intact.

AI handoff / codegen context quality (#104)

  • Export bounded AI codegen asset bundles and structure bundles so chunk /
    assembly prompts reference stable ./assets paths instead of inline
    base64.
  • Enrich sanitized AI consumer views with reusable image / gradient / layout
    / component semantics.
  • Restore code-panel AI bundle and ZIP export affordances.
  • Preserve cropped image fill transform metadata alongside original image
    size through the Figma import path.
  • Guard oversized chat payloads with a client-side rejection before the
    request leaves the browser.

Server / sync plumbing (#104)

  • Harden MCP document sync behavior and related tests.
  • Keep the server-side handoff path consistent with the richer AI bundle
    payloads.

Type

  • feat — StepFun Coding Plan preset, login-shell CLI probe, consumer-view enrichment, minimal-skills fallback
  • fix — OpenAI-compat tool-call streaming, turn-2 request shape, StepFun reasoning + 451, drag reparent, firstTextTimeout, Electron dev sync
  • perf — Bounded AI chat payloads, retry short-circuit on deterministic refusals

Verification

  • npx tsc --noEmit -p apps/web ✓
  • bun --bun run test — 1492 / 1492 passed across 151 files
  • bun --bun run build ✓
  • bun run electron:build:mac-arm64 ✓ — produces signed DMG + zip +
    latest-mac-arm64.yml
  • Manual: GLM-5 via dashscope /chat/completions end-to-end design flow,
    StepFun step_plan/v1 reasoning stream, Mac login-shell CLI detection
    against nvm / fnm / pnpm / bun / mise / fish

Submodule

  • packages/agent-native 0.2.0 → 0.3.0
    (feat(openai-compat): tool_calls streaming, content-block translation, reasoning + 451)

Workspaces bumped

All 14 workspace package.json files bumped 0.7.1 → 0.7.2.

Breaking changes

None.

What's Changed

  • Stabilize synced main for AI handoff, drag nesting, and Electron dev by @raiscui in #104

New Contributors

Full Changelog: v0.7.1...v0.7.2