Adds a new `plumb-codegen` workspace crate that walks a project tree
and infers a starter `plumb.toml` from the design-token sources it
finds: CSS custom properties under `:root`, Tailwind config files, and
DTCG token JSON files. Wired through `plumb init --from <path>`.
The walker is deterministic: directory entries are sorted before
recursion, scales are sorted ascending and deduplicated, and observable
output uses `IndexMap` insertion order. Two runs over the same tree
produce byte-identical output.
V0 inference sources:
- CSS custom properties via `plumb_config::scrape_css_properties`,
classified into color / spacing / radius / type-scale buckets by
property-name prefix and value type.
- Tailwind config presence at the project root (theme resolution stays
on the linter side via `plumb_config::merge_tailwind`).
- DTCG token JSON via `plumb_config::merge_dtcg`, picked up from
`*.tokens.json` files or any `*.json` under a `tokens/` directory.
Layer discipline upheld:
- `plumb-codegen` depends on `plumb-core` + `plumb-config` only.
- Depended on by `plumb-cli` only; never by `plumb-cdp` /
`plumb-format` / `plumb-mcp`.
Closes #82
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Closes #82.
Summary
plumb-codegenworkspace crate that walks a project tree and infers a starterplumb.tomlfrom the design-token sources it finds: CSS custom properties under:root, Tailwind config files, and DTCG token JSON files.plumb init --from <path>. The defaultplumb initflow is unchanged.IndexMapinsertion order. Two runs over the same tree produce byte-identical output.Architecture
plumb-codegendepends onplumb-core+plumb-configonly.plumb-clionly; never byplumb-cdp/plumb-format/plumb-mcp.#![forbid(unsafe_code)], nounwrap/expect/panic!, noprintln!/eprintln!, no wall-clock reads.V0 inference sources
plumb_config::scrape_css_properties+ a name-prefix classifier (--color-*,--space-*,--radius-*,--text-*, …) folded into the correspondingConfigslotplumb_config::merge_tailwindplumb_config::merge_dtcg, picked up from*.tokens.jsonfiles or any*.jsonunder atokens/directoryTest plan
cargo fmt --all -- --checkcargo clippy --workspace --all-targets --all-features -- -D warningscargo nextest run -p plumb-codegen -p plumb-cli— 95 tests pass (26 unit tests inplumb-codegen, 25 existing CLI integration tests, plus 3 newinit --fromintegration tests, MCP, etc.)just determinism-check— three lint runs produce byte-identical JSONcargo deny check— advisories ok, bans ok, licenses ok, sources okcargo run -p xtask -- pre-release— schema in sync, runbooks valid, release-readiness kits valid🤖 Generated with Claude Code