Project-oriented CLI templates for TypeScript, Python, Rust, and Go.
Rootward defines a cross-language contract for developer CLIs that need a project context before they run business logic: initialize a hidden tool directory, discover the project root from the current working directory, load project-local TOML configuration, expand source globs, respect .gitignore, dispatch scanner registries, and expose stable human and JSON command output.
Rootward is not a general CLI framework and not an application scaffold. It is a contract for project-oriented CLI templates.
The contract fixes the behavior that long-lived project tools repeatedly need:
initcreates a tool-owned project context.--project <path>selects an explicit project root.- Commands without
--projectdiscover the project root from CWD upward. .foo/config.tomlis the only default project configuration source.[[sources]]declares file sets byid,root,include,exclude, andscanner.- Discovery produces project-root-relative POSIX paths.
discoverprojects the tool's file view.scandispatches discovered source groups to a scanner registry.doctorreports project-context health.- JSON output, error codes, and exit codes are stable public contracts.
| Language | Contract status | Template role |
|---|---|---|
| TypeScript | Specified reference implementation | Node 24, Commander, Zod, smol-toml, globby, Vitest, Biome |
| Python | Specified implementation | uv, Typer, Pydantic v2, tomlkit, wcmatch, pathspec, pytest, Ruff, ty |
| Rust | Specified implementation | clap derive, serde, toml, ignore, globset, thiserror, camino, assert_cmd, assert_fs |
| Go | Specified implementation | Cobra, go-toml/v2, gobwas/glob, go-git gitignore, standard testing |
Create a TypeScript Rootward CLI:
pnpm create rootward typescript my-tool --cli-name my-tool --package-name my-toolCreate a Rust Rootward CLI:
pnpm create rootward rust my-tool --cli-name my-tool --crate-name my_tool_core --bin-name my-toolEquivalent npm entry points:
npm create rootward typescript my-tool -- --cli-name my-tool --package-name my-tool
npx create-rootward typescript my-tool --cli-name my-tool --package-name my-toolThen run the generated project:
cd my-tool
pnpm install
pnpm test
pnpm build
pnpm dev -- init
pnpm dev -- discover --jsonFor a generated Rust project:
cd my-tool
cargo test
cargo build
cargo run -- init
cargo run -- discover --jsonThe TypeScript and Rust templates are implemented. Python and Go template IDs are reserved and return TEMPLATE_NOT_IMPLEMENTED until their template sources satisfy the Rootward contract.
The primary document is the contract book:
- Source:
docs/books/06-rootward-project-cli-contract/book.adoc - Local build output:
docs/build/html/index.html - Published site:
https://michengliang.github.io/rootward/
Build the documentation locally:
cd docs
pnpm install
pnpm run test
pnpm run buildThe generated site entry is:
docs/build/html/index.html
The site root opens the contract book directly. The generated catalog remains available at:
docs/build/html/catalog.html
docs/
catalog.adoc
books/
06-rootward-project-cli-contract/
scripts/
test/
packages/
create-rootward/
templates/
typescript/
python/
rust/
go/
docs/ is an AsciiDoc book workspace. templates/ is the only maintainer-edited template source. packages/create-rootward is the npm Creator package; its build creates dist/templates from the repository template source for publishing.
pnpm install
pnpm checkUseful focused commands:
pnpm --filter create-rootward test
pnpm --filter create-rootward pack:check
pnpm templates:rust:check
pnpm --dir docs buildcreate-rootward is prepared for public npm publishing. Tag releases use v<package-version>, run the full check suite, publish the Creator package with npm provenance, and create a GitHub release from CHANGELOG.md.
Rootward keeps exactly one visible template source in templates/. Packaged template assets are generated into packages/create-rootward/dist/templates during build and are not maintained by hand.
See CHANGELOG.md.
Apache License 2.0. See LICENSE.