next-theme-figma 0.7.0 / next-theme-dev 1.14.0: tokens.json manifest so Figma variables become theme settings - #58
Merged
Merged
Conversation
…so Figma variables become theme settings Implements #56. next-theme-figma 0.7.0 - tokens.json (schema next-theme-figma/tokens/v1, source figma-variables) is the eleventh handoff file, named in figma-handoff.json.manifests.tokens. Required by strict validation in implementation-handoff mode, a warning elsewhere, legacy v0 exempt. new-package writes the skeleton and pointer. - validate-package checks source and schema, unique ids, typed value parsing (hex and functional colours by grammar, dimensions with units), target shape (theme-setting needs setting_id, css-custom-property needs css_var), and for Spark packages that a value landing on a Spark select setting is one of its options (setting_value carries the option). PASS line appends the tokens counts by target kind and the canonical/alias/unknown name counts. - Negative control: the same figma_name carrying two values, across entries or between the two Figma extraction sources, is a hard error in strict and non-strict mode reported as designer-input-needed with both values. The validator never picks, averages, or drops a value. - references/tokens-manifest.md documents the schema, the canonical Figma variable namespace with aliases, the pinned Spark Style setting ids (NextCommerceCo/spark#57), value rules, and the two-source extraction. figma-contract.md carries the namespace; handoff-manifest.md and the designer checklist are updated. Fixtures gain a tokens manifest. next-theme-dev 1.14.0 - Entry contract: tokens.json is reading-order row 9. "Design Tokens From tokens.json" routes by target.kind: theme-setting -> schema field + seed + :root line using {% if settings.x %}--var: {{ settings.x }};{% endif %} (never settings.* as a filter argument); existing Spark ids get the seed only; css-custom-property -> literal :root line; one-off -> section CSS; unmapped -> handback. Handback lines: Tokens mapped to settings / Tokens as custom properties / Unmapped tokens. - Step 3 takes its inputs from the manifest in implementation-handoff mode; the Change Colors or Fonts recipe no longer passes settings.* through a filter. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
next-devin
marked this pull request as ready for review
September 7, 2026 15:25
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Files Reviewed (3 files in incremental diff)
Previous Review Summaries (2 snapshots, latest commit 9f43b98)Current summary above is authoritative. Previous snapshots are kept for context only. Previous review (commit 9f43b98)Status: 1 Issue Found | Recommendation: Address before merge Overview
Issue Details (click to expand)SUGGESTION
Previously reported, resolved in this push
Files Reviewed (4 files in incremental diff)
Fix these issues in Kilo Cloud Previous review (commit cf82e7d)Status: 3 Issues Found | Recommendation: Address before merge Overview
Issue Details (click to expand)CRITICAL
WARNING
SUGGESTION
Files Reviewed (19 files)
Reviewed by minimax-m3 · Input: 21.9K · Output: 1.9K · Cached: 92.8K |
… setting_value only on theme-setting, :root rule read in one place Review follow-ups on the draft PR: - normalizeTokenValue canonicalises functional colours (rgba->rgb, comma or space separation, percentage alpha) so CSS-equivalent spellings from the two Figma sources never raise a false designer-input-needed conflict; a genuinely different component still does. - target.setting_value is now an error on any target kind other than theme-setting, so a misrouted token is visible instead of silently ignored. - next-theme-dev: the existing-Spark-id exception sits in the same bullet as the :root DTL literal. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
rgb(255,255,255) and rgba(255,255,255,1) are the same opaque colour and must not raise a designer-input-needed conflict; a real alpha difference still does. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #56
What this adds
next-theme-figma0.7.0tokens.json(schemanext-theme-figma/tokens/v1,source: "figma-variables"), named infigma-handoff.json.manifests.tokens. Required by strict validation inimplementation-handoffmode, a warning elsewhere, legacy v0 packages exempt: the same shape asgeometry.jsonandcopy.json.new-packagewrites the skeleton and pointer.token_id,figma_name,type(color | dimension | font-size | radius | font-family),value, optionalmodes, both extraction sources inobserved[](variable_defs,design_context), and atargetof kindtheme-setting | css-custom-property | one-off | unmapped.theme-settingneeds asetting_id;css-custom-propertyneeds acss_var; an optionalsetting_valuecarries the option a select-typed setting receives.validate-packagerefuses a wrong source or schema, duplicate ids, unparseable values (hex and functional colours by grammar, dimensions with units), malformed targets, and, for Spark packages, a value that is not an option of a Spark select setting. The PASS line appendstokens: N total, n theme-setting, n css-custom-property, n one-off, n unmapped; names: n canonical, n alias, n unknown.figma_namecarrying two different values, whether across entries or between the two Figma sources, is a hard error in strict and non-strict mode:designer-input-needed: <name> carries two values (...). The validator never picks, averages, or drops a value.references/figma-contract.mdand the newreferences/tokens-manifest.md, which also pins the Spark setting ids, types, options, and custom properties each token lands on (from Style settings for radius, spacing, border, page background and type scale (#56) spark#57).handoff-manifest.mdlists the eleventh file; the designer checklist asks for variables, not detached hex.next-theme-dev1.14.0tokens.jsonis reading-order row 9. New "Design Tokens From tokens.json" section routes bytarget.kind:theme-setting→settings_schema.jsonfield +settings_data.jsonseed + a:rootline using exactly{% if settings.x %}--var: {{ settings.x }};{% endif %}(neversettings.*as a filter argument);css-custom-property→ literal:rootline;one-off→ section CSS;unmapped→ handback. Handback linesTokens mapped to settings:,Tokens as custom properties:,Unmapped tokens:.settings.*through a filter.Proof
Fixture package, strict, and the negative controls (director-run against the final tree):
A
tokens.jsonwhose entire content isnullnow fails withtokens.json: manifest must be an object(a round-2 challenge finding). Dry Step 3 pass over the fixture, applying the dev-side contract mechanically: five tokens seed existing Spark settings (body_text_color,border_color,body_bg_color,section_padding=roomy,radius_control=8px), one lands as--primary-color(dashboard Branding wins), one is listed underUnmapped tokens:.Verification
Built with the Fable → Codex build loop: each slice built by Codex, gate-reviewed by an independent Codex seat, and the validator slice challenged with a refusal-coverage packet (one real accept-that-should-refuse found and fixed: malformed functional colours; coverage gaps closed and re-reviewed). Full CI parity run locally: public-safety scan, catalog and version checks, syntax checks, and all unit suites green.
Follow-up
readJsonreturnsnullfor a file whose JSON is literallynull, and the geometry and copy validators then return silently the way the tokens validator did before round 2. Pre-existing, shared helper, not widened here; worth its own small issue.Spark setting ids
Pinned at run time from the merged NextCommerceCo/spark#57 (
configs/settings_schema.jsonandlayouts/base.htmlon main), not assumed. Note the custom-property names differ from the original issue text:--control-radius,--card-radius,--heading-scale(a factor),--container-max.🤖 Generated with Claude Code