Skip to content

Update Versions - #59

Merged
owjs3901 merged 1 commit into
mainfrom
changepacks/main
Sep 14, 2026
Merged

owjs3901 merged 1 commit into
mainfrom
changepacks/main

Conversation

@github-actions

@github-actions github-actions Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Changepacks

devup-mcp@0.5.0 → 0.6.0 - crates/devup-mcp/Cargo.toml

Minor

  • The bridge is now tried before a login is demanded, and doctor reports it as a path. A collection asked the OAuth backend for a token before it asked anything whether a token was needed, and refused outright when there wasn't one. That inverted the two paths. The bridge spends no Figma allowance and needs no credential of any kind, so it is the path to reach for; direct is metered and a single screen costs several reads. Whoever had attached the plugin - precisely to stay off the metered path - was told to go and authorize the metered path first, and the export never started, on a file every read of which the plugin was sitting there ready to serve. After the previous change moved node-scoped metadata onto the bridge, nothing in a tsx export needs the remote path at all, so that refusal stood between an attached plugin and a finished screen for no remaining reason. FigmaUpstream::serves_without_credentials answers per file key rather than per process, because a plugin holding another file open says nothing about this one, and FallbackUpstream delegates it to the bridge. The login is now required only when no plugin is holding this file. A read inside the collection that the bridge genuinely cannot serve - a file-scope metadata read, or referencePng's get_screenshot - still refuses on its own, where the reason belongs to that read instead of condemning the whole export before it starts. Separately, devup_figma_auth doctor knew only about direct, which made the only instrument for diagnosing the connection one that could give exactly one answer - run login - to every question, including the ones whose real answer was 'run the plugin' or 'the listener never bound'. It now reports preferredPath: bridge and a paths.bridge block separating the three states that need three different repairs: not listening (the port was taken or switched off), listening with nothing attached (run the plugin, and the port is named), and attached (with the file keys, because a plugin open on the wrong file looks identical from the outside). Measured against the release binary with no token stored at all: a plugin attached over the real socket, doctor reporting available, and an export that reached the read instead of DEVUP_AUTH_REQUIRED.

devup-mcp-devup-ui@0.5.0 → 0.5.1 - crates/devup-mcp-devup-ui/Cargo.toml

Patch

  • A percentage line advance on a variable font size is now written as a percentage instead of refused. The guard was right that a pixel advance derived from a resolved size is only true in the mode that resolved it, and that emitting one for a size bound to a variable publishes a number that silently stops matching. It was wrong that the value could not be represented: a Figma PERCENT line height and a CSS percentage line-height mean the same thing - both scale with whatever font size applies - so leaving the ratio alone is exact under every mode rather than approximate under one. The conversion to pixels is kept for every text whose size is not bound, which is what the existing goldens contain and why none of them move. The refusal now fires only when the percentage itself is missing, which is the case that genuinely carries no value to emit. The separate theme path is untouched: publishing a typography token still refuses a bound size, because a token records one pair of numbers for all of its uses and cannot carry a ratio the way an element can. Measured on a 1920-wide screen from a design system that binds every type size to a variable: seventy-one texts keep their ratio and six unbound texts keep their pixel advance, where the screen previously produced no code at all.

devup-mcp-figma@0.5.0 → 0.6.0 - crates/devup-mcp-figma/Cargo.toml

Minor

  • The bridge is now tried before a login is demanded, and doctor reports it as a path. A collection asked the OAuth backend for a token before it asked anything whether a token was needed, and refused outright when there wasn't one. That inverted the two paths. The bridge spends no Figma allowance and needs no credential of any kind, so it is the path to reach for; direct is metered and a single screen costs several reads. Whoever had attached the plugin - precisely to stay off the metered path - was told to go and authorize the metered path first, and the export never started, on a file every read of which the plugin was sitting there ready to serve. After the previous change moved node-scoped metadata onto the bridge, nothing in a tsx export needs the remote path at all, so that refusal stood between an attached plugin and a finished screen for no remaining reason. FigmaUpstream::serves_without_credentials answers per file key rather than per process, because a plugin holding another file open says nothing about this one, and FallbackUpstream delegates it to the bridge. The login is now required only when no plugin is holding this file. A read inside the collection that the bridge genuinely cannot serve - a file-scope metadata read, or referencePng's get_screenshot - still refuses on its own, where the reason belongs to that read instead of condemning the whole export before it starts. Separately, devup_figma_auth doctor knew only about direct, which made the only instrument for diagnosing the connection one that could give exactly one answer - run login - to every question, including the ones whose real answer was 'run the plugin' or 'the listener never bound'. It now reports preferredPath: bridge and a paths.bridge block separating the three states that need three different repairs: not listening (the port was taken or switched off), listening with nothing attached (run the plugin, and the port is named), and attached (with the file keys, because a plugin open on the wrong file looks identical from the outside). Measured against the release binary with no token stored at all: a plugin attached over the real socket, doctor reporting available, and an export that reached the read instead of DEVUP_AUTH_REQUIRED.
  • A node-scoped export can now finish entirely on the bridge, and a split subtree no longer drops the node it was asked to convert. Two separate things stood between an attached plugin and a finished screen. The first is that get_metadata was excluded from the bridge on the ground that the plugin's answer has a different shape; measured against a View seat whose allowance was spent, that single call was the whole difference between an export and a refusal, because every other read in the path already had a script. The exclusion held only for the shape, not for the data: find_metadata deserialises a MetadataDocument in its first branch and reduces the official XML to that same type in the next, so a plugin that emits the canonical camelCase document is read by the same decoder rather than a parallel one. metadata.js emits exactly that document and nothing else - no geometry, which the decoder does not read and the snapshot already carries. A read with no node is left on the remote path: it answers with the top-level page list, which is a different contract and not worth imitating. The second is independent of transport. When a root has children and more than two hundred descendants, the legacy plan snapshots the children and, in node scope, never the root - so projection fails with DEVUP_FIGMA_NODE_NOT_FOUND on exactly the screen the caller named. That path is rarely reached because the fast envelope usually serves node scope; it is reached whenever the fast envelope falls back, and then it cannot succeed at all. The node to convert is now always among the snapshot targets. Measured on a 1920-wide screen whose fast envelope fell back: eight Figma calls, all served by the plugin, no metered call and no rate-limit refusal, where the same screen previously stopped at the metadata call. The descendant count a plugin reports is not the count the official XML reports - the official metadata collapses instances nested inside an instance and the Plugin API walk does not - so the split decision can differ between the two paths; that difference now costs one redundant bridged snapshot instead of a failure.

@owjs3901
owjs3901 merged commit 78cbe9e into main Sep 14, 2026
@owjs3901
owjs3901 deleted the changepacks/main branch September 14, 2026 07:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant