Canonical shared repo guidance is mirrored in agents/shared/repo.md.
This file provides guidance to AI agents (Claude, Factory Droid, etc.) when working with code in this repository.
tokmd uses Factory Droid for automated code review. Droid runs on all pull requests using the safe action configuration with MiniMax BYOK, and can be invoked manually with @droid review or @droid security comments.
- See
agents/shared/droid-migration.mdfor the rollout design - See
.factory/rules/droid-review.mdfor review standards and finding format - See
.github/workflows/droid-review.ymlfor auto-review configuration - See
.github/workflows/droid.ymlfor manual@droidcommand handling - See
.github/workflows/droid-security-scan.ymlfor scheduled security scanning
tokmd is a Rust CLI tool and library that wraps the tokei library to generate "inventory receipts" and derived analytics of code repositories. It produces human-readable summaries (Markdown/TSV) and machine-friendly datasets (JSON/JSONL/CSV) for AI-native workflows, LLM context generation, and code analysis pipelines.
cargo build # Debug build
cargo build --release # Release build with LTO
cargo test --verbose # Run all tests
cargo fmt-fix # Format code across the workspace
cargo fmt-check # Verify workspace formatting
cargo trim-target --check # Report reclaimable target/debug space
cargo sccache-check # Verify local sccache setup
cargo clippy -- -D warnings # Lint with strict warnings
cargo install --path crates/tokmd # Local installOn Windows, prefer cargo fmt-fix / cargo fmt-check over cargo fmt --all; the full workspace can exceed Cargo's formatter argv budget even when long paths are enabled.
Windows MSVC builds in this repo also default to line-table debuginfo to keep target/debug from being dominated by full PDBs.
If you need full local symbols for a debugging session, use $env:RUSTFLAGS='-C debuginfo=2'; cargo test ....
For opt-in local build caching, use cargo with-sccache ...; the wrapper sets RUSTC_WRAPPER=sccache and defaults CARGO_INCREMENTAL=0 unless you pass --keep-incremental.
For cross-worktree cache reuse, use cargo xtask sccache --basedir <PATH> -- <cargo args> so the wrapper can set SCCACHE_BASEDIRS explicitly.
The codebase follows a tiered crate-and-module architecture: types → scan/model → format/adapters → analysis/cockpit/gate → core → products. Public crates represent durable contracts, facades, adapters, or products. Implementation details that do not need an independent package live as single-responsibility owner modules inside those crates.
| Tier | Crate | Purpose |
|---|---|---|
| 0 | tokmd-types |
Core receipt data structures |
| 0 | tokmd-analysis-types |
Analysis receipt types |
| 0 | tokmd-settings |
Clap-free workflow settings |
| 0 | tokmd-envelope |
Shared sensor/FFI envelope contracts |
| 0 | tokmd-io-port |
Host-abstracted file access contracts |
| 1 | tokmd-scan |
tokei wrapper for code scanning |
| 1 | tokmd-model |
Aggregation logic (lang, module, file rows) |
| 1 | tokmd-sensor |
Sensor substrate and report builder |
| 2 | tokmd-format |
Output rendering, redaction, badges, export-tree, analysis rendering |
| 2 | tokmd-git |
Git history analysis |
| 3 | tokmd-analysis |
Analysis orchestration and enrichers |
| 3 | tokmd-cockpit |
PR cockpit metrics and review evidence |
| 3 | tokmd-gate |
Policy evaluation with JSON pointer rules |
| 4 | tokmd-core |
Library facade with FFI layer |
| 5 | tokmd |
CLI binary |
| 5 | tokmd-python |
PyO3 bindings for PyPI |
| 5 | tokmd-node |
napi-rs bindings for npm |
| 5 | tokmd-wasm |
wasm-bindgen bindings for browser/worker callers |
Former helper microcrates such as redaction, scan-args, badge rendering,
analysis rendering, progress, module-key, path/exclude/math, tokeignore,
context policy/git, fun renderers, content/import enrichers, and tool-schema now
live as owner modules inside tokmd-format, tokmd-scan, tokmd-model,
tokmd-analysis, tokmd-core, or tokmd.
tokmd/tokmd lang— Language summarytokmd module— Module breakdown by directorytokmd export— File-level inventory (JSONL/CSV/CycloneDX)tokmd run— Full scan with artifact outputtokmd analyze— Derived metrics and enrichmentstokmd badge— SVG badge generationtokmd diff— Compare two runs or receiptstokmd cockpit— PR metrics for code review with evidence gatestokmd gate— Policy-based quality gates with JSON pointer rulestokmd tools— Generate LLM tool definitions (OpenAI, Anthropic, JSON Schema)tokmd context— Pack files into LLM context window within token budgettokmd init— Generate.tokeignoretemplatetokmd check-ignore— Explain why files are being ignoredtokmd completions— Generate shell completions
The tokmd-core crate provides a clap-free library facade for embedding:
Workflow Functions (Rust):
lang_workflow(scan, lang) -> LangReceiptmodule_workflow(scan, module) -> ModuleReceiptexport_workflow(scan, export) -> ExportReceiptdiff_workflow(settings) -> DiffReceipt
FFI Layer (ffi::run_json):
- Single JSON entrypoint:
run_json(mode, args_json) -> String - Modes:
lang,module,export,analyze,diff,version - Response envelope:
{"ok": bool, "data": {...}, "error": {...}}
Python Bindings (tokmd-python):
tokmd.lang(),tokmd.module(),tokmd.export(),tokmd.analyze(),tokmd.diff()- Returns native Python dicts
- Releases GIL during long scans
Node.js Bindings (tokmd-node):
- All functions return Promises (async)
- Uses
tokio::task::spawn_blocking()for non-blocking event loop
| Preset | Includes |
|---|---|
receipt |
Core derived metrics (density, distribution, COCOMO) |
health |
+ TODO density |
risk |
+ Git hotspots, coupling, freshness |
supply |
+ Assets, dependency lockfiles |
architecture |
+ Import graph |
topics |
Semantic topic clouds |
security |
License radar, entropy profiling |
identity |
Archetype detection, corporate fingerprint |
git |
Predictive churn, advanced git metrics |
deep |
Everything (except fun) |
fun |
Eco-label, novelty outputs |
- Uses
BTreeMapinstead ofHashMapeverywhere for stable key ordering - Sorting: descending by code lines, then by name
- Essential for golden snapshot tests and reproducible receipts
- All paths normalized to forward slashes (
/) regardless of OS - Always use
normalize_path()before output - Module keys computed from normalized paths
ChildrenMode::Collapse: Merge embedded languages into parent totalsChildrenMode::Separate: Show as "(embedded)" rows- Applies consistently across all commands
- JSON outputs include envelope metadata with
schema_version - Increment schema_version when modifying JSON output structure
- Update
docs/schema.json(formal JSON Schema) when structures change - Schema versions are separate for each receipt family:
- Core receipts (
lang,module,export,diff,run):SCHEMA_VERSION = 2(intokmd-types) - Analysis receipts:
ANALYSIS_SCHEMA_VERSION = 9(intokmd-analysis-types) - Cockpit receipts:
COCKPIT_SCHEMA_VERSION = 3(intokmd-types) - Handoff manifests:
HANDOFF_SCHEMA_VERSION = 5(intokmd-types) - Context receipts:
CONTEXT_SCHEMA_VERSION = 4(intokmd-types) - Context bundles:
CONTEXT_BUNDLE_SCHEMA_VERSION = 2(intokmd-types)
- Core receipts (
git: Git history analysis (uses shellgit log)content: File content scanning (entropy, tags, hashing)walk: Filesystem traversal for assets
When invoking git diff or git log with range syntax:
| Syntax | Meaning | Use Case |
|---|---|---|
A..B |
Commits reachable from B but not A | Comparing tags/releases (cockpit, diff commands) |
A...B |
Symmetric difference from merge-base | CI workflows comparing PR branches |
Rule: Use .. (two dots) in cockpit/diff commands comparing releases or tags. Use ... (three dots) only in CI workflows where you want changes since branch divergence.
- Integration tests:
crates/tokmd/tests/usingassert_cmd+predicates - Golden snapshots: Using
instacrate (timestamps normalized) - Crate-level tests: Each crate has its own
tests/directory - Unit tests: In-module tests
- Property-based tests: Using
proptestacross 14 crates for invariant verification - Fuzz targets: 9 targets using
libfuzzer(seefuzz/directory) with seed corpus and dictionaries - Mutation testing: Using
cargo-mutantsfor test quality verification (configured in.cargo/mutants.toml)
Run a single test:
cargo test test_name --verboseUpdate snapshots:
cargo insta reviewRun property tests:
cargo test -p tokmd-scan propertiesRun mutation testing:
cargo mutants --file crates/tokmd-format/src/redact/mod.rsRun fuzz targets:
cargo +nightly fuzz run fuzz_entropy --features content
cargo +nightly fuzz list # List all targets| Crate | Purpose |
|---|---|
tokei |
Core LOC counting |
clap (derive) |
CLI parsing |
serde/serde_json |
JSON serialization |
blake3 |
Fast hashing for redaction and integrity |
anyhow |
Error handling |
ignore |
File walking with gitignore support |
pyo3 |
Python bindings (tokmd-python) |
napi-rs |
Node.js bindings (tokmd-node) |
docs/architecture.md: Crate hierarchy, data flow, dependency rulesdocs/design.md: Design principles, system context, data modeldocs/requirements.md: Requirements, interfaces, quality bardocs/implementation-plan.md: Phased roadmap for future work
docs/tutorial.md: Getting started guidedocs/recipes.md: Real-world usage examplesdocs/reference-cli.md: CLI flag referencedocs/troubleshooting.md: Common issues and solutions
docs/SCHEMA.md: Receipt format documentationdocs/schema.json: Formal JSON Schema Draft 7 definitiondocs/testing.md: Testing strategy and frameworks
docs/PRODUCT.md: Product contract and invariantsdocs/explanation.md: Philosophy and design principles
ROADMAP.md: Current status and future plansCHANGELOG.md: Version historyCONTRIBUTING.md: Development setup, testing, and publishing guide
Normal tokmd development starts from EffortlessMetrics/tokmd-swarm:main.
Create narrow PRs there, wait for Tokmd Rust Result, and squash-merge
aligned work into the swarm repo.
EffortlessMetrics/tokmd is the publication repository. Do not push feature
work, release tags, GitHub releases, crates.io publishes, Docker pushes,
signing changes, or v1 alias moves from swarm. Publication imports are
explicit merge-commit PRs in tokmd, followed by fast-forwarding
tokmd-swarm/main to the publication merge commit.
See docs/ci/swarm-routing.md for the shared-history topology and routing
rules.
.jules/**is Jules provenance and ambient suggestion state. Treat it as useful repo input, not Codex's primary active-lane controller.- Codex should use
AGENTS.md,docs/NEXT.md, accepted docs/plans/specs/ADRs, PR context, and.codex/**state where present for Codex lane selection. - Do not tell Jules to stop acting or remove Jules suggestions merely because Codex is working. Evaluate Jules suggestions like any other repo input.
- Treat
.jules/**logs, ledgers, envelopes, runbooks, and friction notes as intentional provenance unless a repo owner explicitly says otherwise. - Do not close, trim, or reject a PR merely because it includes
.jules/**files. - If a Jules PR is merge-worthy, keep the
.jules/**updates with it. - Do not split
.jules/**updates out into a second PR just to shrink the visible diff; keep the provenance attached to the substantive change. - If a Jules PR is not ready, the reason must be the actual code issue: correctness, scope, stacking, validation, or launch relevance.
- Do not close a Jules PR because it has provenance files.
- Close, defer, or restack only for substantive reasons such as:
- unrelated non-
.jules/**changes are stacked into the branch - the code is incorrect
- required validation fails
- the change is not worth merging in the current phase
- unrelated non-
- Never close a PR merely because a release is near.
- During prep or RC hardening, classify each open PR by substance: release blocker, safe aligned change, useful non-blocking work, duplicate of a merged keeper, invalid/incorrect work, stale branch needing restack, or explicitly declined work.
- Merge release blockers and safe aligned PRs after validation. Leave useful non-blocking PRs open, parked, labeled, or restacked for later.
- Close a PR only for an intrinsic reason: it is invalid, duplicated or superseded by a merged keeper, stale beyond practical restack, conflicts with accepted direction, or was explicitly declined.
- Queue cleanliness is not a release criterion. Release readiness is proven by preflight, release-record accuracy, and clean release-surface evidence.
For PR-bound work, Codex may create scoped branches, commit scoped changes, push branches, open PRs, update PR branches, and merge aligned PRs after validation without asking for additional user confirmation.
PR-bound work includes requests to implement, review, improve, merge, drain PRs, prepare release docs, update changelogs, fix tests, or otherwise carry a repo task through completion.
Do not ask for extra permission merely because a commit, push, PR update, or aligned merge is needed to finish that task.
Ask before committing, pushing, or merging only when:
- the user explicitly requested read-only or local-only work;
- the task is exploratory and no implementation was requested;
- the mutation would publish crates, create tags, create GitHub releases, move release aliases, push images, rotate secrets, or change external-service ownership;
- the diff is broad or ambiguous relative to the requested lane;
- the worktree contains unrelated user changes that cannot be isolated safely.