You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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".
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–75 — export_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.
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
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.
Summary
plumb init --fromemits light-mode defaults for real projectsDogfood
/Users/aramhammoudeh/dev/vertice-labs/imr/imr-agent/apps/web) was generating dark theme defaults becausedarksorted beforelightand duplicate color keys are first-write-wins.plumb init --from apps/webemits light values such asbackground = "#faf7f7",foreground = "#3f5965", andprimary = "#007068".Validation
cargo fmt --all -- --checkcargo test -p plumb-codegencargo clippy -p plumb-codegen --all-targets --all-features -- -D warningscargo build -p plumb-cliRUSTDOCFLAGS='-Dwarnings' cargo doc --workspace --no-depsjust validatePLUMB_CHROME="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" scripts/noise-scoreboard.sh --liveScoreboard