Skip to content

fix(codegen): prefer light token exports - #312

Merged
aram-devdocs merged 1 commit into
mainfrom
codex/codegen-prefer-light-token-exports
Jun 21, 2026
Merged

fix(codegen): prefer light token exports#312
aram-devdocs merged 1 commit into
mainfrom
codex/codegen-prefer-light-token-exports

Conversation

@aram-devdocs

Copy link
Copy Markdown
Owner

Summary

  • prefer light/default token exports before generic theme exports when merging duplicate literal token keys
  • keep dark exports as fallback-only so plumb init --from emits light-mode defaults for real projects
  • add a regression test for duplicate light/dark color exports

Dogfood

  • IMR agent (/Users/aramhammoudeh/dev/vertice-labs/imr/imr-agent/apps/web) was generating dark theme defaults because dark sorted before light and duplicate color keys are first-write-wins.
  • After this change, plumb init --from apps/web emits light values such as background = "#faf7f7", foreground = "#3f5965", and primary = "#007068".

Validation

  • cargo fmt --all -- --check
  • cargo test -p plumb-codegen
  • cargo clippy -p plumb-codegen --all-targets --all-features -- -D warnings
  • cargo build -p plumb-cli
  • RUSTDOCFLAGS='-Dwarnings' cargo doc --workspace --no-deps
  • just validate
  • PLUMB_CHROME="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" scripts/noise-scoreboard.sh --live

Scoreboard

  • kitchen-sink: 24
  • example.com: 0
  • ui.shadcn.com: 299
  • news.ycombinator.com: 410

@aram-devdocs
aram-devdocs merged commit 8be27ec into main Jun 21, 2026
20 of 25 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

I have all the information I need. Here is the full review:


PR #312fix(codegen): prefer light token exports

Scope: crates/plumb-codegen/src/ts_tokens.rs (+40 / −2). Single crate, no new deps, no Cargo.toml changes.


1. Determinism

exports.sort_by on line 37 is stable. The three-key comparator is a total order (all exports in a TypeScript file have unique names, so the raw-name tiebreaker is never ambiguous). No wall-clock reads. Observable output uses IndexMap<String, String> for config.color.tokens (line 182 of plumb-core/src/config.rs) — unchanged, compliant.

Status: clear.


2. Workspace layering

Change is fully contained inside plumb-codegen. No new internal dep edges. plumb-codegen's Cargo.toml already has plumb-core and plumb-config only; this PR adds nothing.

Status: clear.


3. Error handling

No new unwrap/expect in library code. Test module retains the pre-existing #[allow(clippy::unwrap_used, clippy::expect_used)] — acceptable per convention.

Status: clear.


4. Test coverage

The new test (prefers_light_exports_before_dark_for_duplicate_color_keys) validates all four expected outcomes:

  • Light value wins on duplicate key (background, primary)
  • Dark-only key still propagates (onlyDark)
  • Neutral export survives (accent)
  • import.colors == 4 count is correct

Status: adequate for stated scope.


5. Punch list

ts_tokens.rs:72"default" arm is unreachable dead code.
export const default is a syntax error in TypeScript/JavaScript — default is a reserved word and cannot be a const identifier. split_hint on any valid identifier that contains "default" (e.g., defaultColors"defaultcolors") never produces exactly "default" after joining. The arm is harmless (maps to 0) but misleading, and the dead_code lint won't catch a string match arm. Remove it or add a comment explaining what concrete export name would reach it.

ts_tokens.rs:70–75export_priority is a partial fix only for multi-word theme variants.
lightTheme/darkTheme both receive priority 1 (generic). The secondary sort (token_sort_key) then orders them alphabetically: "darktheme" < "lighttheme", so dark still wins. This means export const darkTheme = { ... } / export const lightTheme = { ... } files retain the original bug. The PR description is accurate about scope (dogfood case used bare light/dark), so this is not a blocker — but it should be noted in a follow-up ticket or a comment in the function.

ts_tokens.rs:37–42 — export-level sort affects all token categories, not just colors.
Spacing, radius, and typography tokens also use first-write-wins (contains_key). A light export wins for spacing/radius too. No test covers this cross-category effect. Likely correct behaviour, but a brief test or comment would prevent future confusion.


Verdict: APPROVE

@aram-devdocs
aram-devdocs deleted the codex/codegen-prefer-light-token-exports branch June 21, 2026 01:49
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