Contributing
How to land a TOML rule, a native compressor, an AI tool integration, or a bug fix. Repo conventions, CI gates, commit style.
tok0 is MIT-licensed and welcomes contributions. The repo is at github.com/prxm-labs/tok0. Most contributions land in one of four shapes:
- A new TOML compression rule.
- A native Rust compressor.
- A new AI tool integration.
- A bug fix or doc improvement.
Each has a recipe below. CI gates are the same across all four.
Repo layout
tok0/
├── apps/cli/ # the Rust binary (this is where most PRs go)
├── apps/api/ # Cloudflare Workers backend (api.tok0.dev)
├── apps/website/ # Astro site (this docs page lives here)
├── packages/
│ └── openclaw-plugin/ # IDE plugin
└── docs/superpowers/ # design specs and ongoing-work plans
For CLI work: cd apps/cli && cargo test. CLI conventions live in apps/cli/CLAUDE.md — read it before your first PR.
Quality gate (run before every commit)
cd apps/cli
cargo fmt --all
cargo clippy --all-targets -- -D warnings
cargo test
CI also runs the same with --features cloud. Both must pass.
Local toolchain: rustup update stable (1.95+).
Recipe — adding a TOML rule
This is the most common contribution and the easiest. Use it whenever pattern-stripping is enough.
- Capture a real fixture:
<command> 2>&1 > apps/cli/tests/fixtures/<eco>/<command>_raw.txt - Author the rule at
apps/cli/src/rules/<command>.toml. Schema: Writing TOML rules. - Add at least one assertion with
min_savings_pct. CI gates it. - Run:
cargo test --test rules— verifies your assertion passes. - PR.
Recipe — adding a native Rust compressor
Reserved for cases where TOML is not enough: multi-pass parsing, AST awareness, JSON reshaping.
- Capture a fixture:
<cmd> 2>&1 > apps/cli/tests/fixtures/<eco>/<cmd>_raw.txt - Create
apps/cli/src/compressors/<eco>/<cmd>_cmd.rswithpub fn run(args: <Args>) -> Result<()>. - All regex inside
lazy_static!. NeverRegex::new()in a function body. - Add
assert_snapshot!+ a token-savings test (≥60%). - Wire into
apps/cli/src/main.rsCommandsenum andapps/cli/src/engine/dispatcher.rsmatch. - PR.
Reference: apps/cli/.claude/skills/rust-dev/SKILL.md for the full conventions.
Recipe — adding an AI tool integration
- New variant in
ToolTarget(apps/cli/src/bridge/setup.rs). - Cases in
config_dir_for(),instructions_filename(),tool_slug(). - A signal in
detect_tools_in()(config dir orwhich_binary()). - Optional
post_install_hint()for manual steps. - A parametric test in
bridge::setup::tests::all_instruction_tools(). - PR with a screenshot of the tool config surface for reviewer context.
Non-negotiable rules
These override general Rust conventions; CI enforces all of them.
- No async runtime. Zero
tokio,async-std,futures. Single-threaded by design. .context()?on every?. anyhow with a static or dynamic context string. Bare?only insidelazy_static!or test code.- All regex via
lazy_static!. NeverRegex::new()in a function body. - No
unwrap()in production paths.lazy_static!init is fine;expect("reason")in tests. - Fallback pattern in compressors. Filter error → raw output passthrough. Never block the user.
- Exit-code propagation.
std::process::exit(code)when the wrapped command fails.
Commit style
Conventional prefixes: feat:, fix:, test:, docs:, chore:, perf:, refactor:, style:. Optional scope: fix(bridge): …. First line ≤ 72 chars. Body explains why. release-please drives changelog generation off these prefixes.
Releasing
Maintainers only:
- CLI is released via release-please: merging the bot’s release PR cuts a
vX.Y.Ztag → matrix builds 5 binaries +.deb→ updates Homebrew formula → publishes Docker image to GHCR. - API and website are continuously deployed: every merge to
mainships, every PR gets a preview deploy.
Code of conduct
The project follows the Contributor Covenant. Reports go to conduct@prxm-labs.dev.
First-time contributors: pick an issue tagged good-first-issue. Most are TOML rules with a captured fixture already attached — under an hour from clone to PR.