Metadata-Version: 2.4
Name: crunk
Version: 0.1.1
License: MIT
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: typani>=0.0.3
Requires-Dist: pydantic>=2.12.0
Requires-Dist: python-dotenv>=1.0
Requires-Dist: tinycss2>=1.5.1
Dynamic: license-file

<p align="center">
  <img src="https://raw.githubusercontent.com/lognd/crunk/main/docs/assets/crunk-banner.svg" alt="crunk: declare your design system once; crunk exports it, lints against it, and fixes the drift." width="100%"/>
</p>

<p align="center">
  <a href="https://pypi.org/project/crunk/"><img src="https://img.shields.io/pypi/v/crunk.svg" alt="PyPI version"></a>
  <a href="https://pypi.org/project/crunk/"><img src="https://img.shields.io/badge/python-3.11%2B-blue.svg" alt="Python 3.11+"></a>
  <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License: MIT"></a>
  <a href="https://github.com/lognd/crunk/actions/workflows/ci.yml"><img src="https://github.com/lognd/crunk/actions/workflows/ci.yml/badge.svg" alt="CI status"></a>
</p>

# crunk

crunk brings Figma-style design discipline to front-end code: declare
your palette, scales, and file organization once in `crunk.toml`, and
crunk exports the tokens, lints your CSS against them, auto-fixes the
drift, and enforces the organization -- deterministically, in CI, with
no browser in the loop.

## Highlights

- **One source of truth.** Palette, type/spacing scales, and
  organization rules live in a single declarative `crunk.toml`; every
  other artifact (CSS custom properties, Tailwind theme, docs) is
  generated from it, never hand-maintained.
- **A linter, not a style guide.** `crunk check` fails on any color,
  size, or shadow that is not in the declared system -- including
  role-pair contrast ratios (`--contrast`) -- so drift is a red build,
  not a review-time opinion.
- **Deterministic autofix.** `crunk fix` applies the mechanical
  remediations `check` found (nearest-token rewrites, organization
  moves), with `--dry-run` to preview.
- **Reuse before rebuild.** `crunk query find button` asks the design
  system whether a component already exists before you write a second,
  slightly different one.
- **Terminal-native.** `crunk preview` prints the token sheet and
  `crunk diff` compares two token sets, both straight to the terminal.

## Install

```bash
uv tool install crunk
# or
pip install crunk
```

The package installs two equivalent binaries on PATH: `crunk` and the
short alias `crk`.

## Quickstart

```bash
crunk init --preset default   # scaffold crunk.toml + a skeleton project
crunk check                   # lint tracked CSS against crunk.toml
crunk tokens                  # export the declared tokens as CSS
crunk fix --dry-run           # preview the mechanical fixes check found
crunk map                     # print the organization inventory
crunk check --contrast        # print role-pair contrast ratios, PASS/FAIL
crunk query find button       # is there already a button component?
crunk preview                 # print the terminal token sheet
crunk diff ../other-project   # diff two crunk.toml token sets
```

Customize the design system by editing the scaffolded `crunk.toml`
(palette, scales, organization rules) -- see
[docs/design/02-specification.md](docs/design/02-specification.md) for
the full schema and rule catalog.

## Commands

<!-- frob:describes src/crunk/__main__.py::_build_parser -->

| Command | What it does |
| --- | --- |
| `crunk init` | scaffold `crunk.toml` + skeleton |
| `crunk check` | lint against the spec |
| `crunk tokens` | export/verify tokens |
| `crunk fix` | deterministic autofix |
| `crunk map` | organization inventory |
| `crunk query` | ask the design system: reuse before rebuild |
| `crunk preview` | terminal token sheet, no browser needed |
| `crunk diff OTHER` | token-set diff vs another spec |

8 commands. See `docs/commands/` for each one's flags and exit codes:
[init](docs/commands/init.md), [check](docs/commands/check.md),
[tokens](docs/commands/tokens.md), [fix](docs/commands/fix.md),
[map](docs/commands/map.md), [query](docs/commands/query.md),
[preview](docs/commands/preview.md) (also covers `diff`).
`check`/`fix`/`map`/`query` accept `--no-cache` to bypass the result
cache (see [docs/design/subsystems/cache.md](docs/design/subsystems/cache.md)).

## Tailwind integration

To expose a declared sizes scale as real utility classes
(`min-h-size-44` etc.) rather than one-off arbitrary values, adopt the
generated `tailwind.tokens.json` wholesale --
`theme: { extend: require("./tailwind.tokens.json") }` with
`namespace_keys` on -- instead of hand-wiring only some categories into
`theme.extend`: the generated file carries all six sizing categories,
and hand-picking a subset silently drops the rest. See
[docs/commands/tokens.md](docs/commands/tokens.md) for the full mapping.

## Documentation

The design docs are a waterfall under
[docs/design/](docs/design/): requirements, specification, system
design, subsystems, components -- each layer with its test plan.
Per-command references live under [docs/commands/](docs/commands/).

## Development

```bash
git clone https://github.com/lognd/crunk.git
cd crunk
make install     # stamp-guarded uv sync
```

This is a [frob](https://github.com/lognd/frob)-enabled project: `frob
<verb>` is the interface for everything past install, not a `make`
wrapper around it.

```bash
frob test        # select and run tests for the touched set (or --all)
frob format      # ruff check --fix + ruff format
frob coverage    # refresh coverage.xml / the coverage stamp
frob check       # the aggregate gate: ruff, ty, frob cycle/dup/arch/...
```

`make install`/`make clean`/`make upload` remain (bootstrap and
build/publish -- see the Makefile's own comment on this split). You do
not need frob installed to contribute; `uv run pytest -q` covers the
test suite and CONTRIBUTING.md covers the rest.

## Contributing

Contributions are welcome, from a typo fix to a new feature. Read
[CONTRIBUTING.md](CONTRIBUTING.md) before opening a pull request; it
covers the local dev setup, the commit format, and the
AI-assisted-contributions policy in particular. Everyone participating
in this project is expected to follow the
[Code of Conduct](CODE_OF_CONDUCT.md).

## Security

See [SECURITY.md](SECURITY.md) for how to report a vulnerability;
please do not file a public issue for one.

## License

MIT, see [LICENSE](LICENSE).
