Contributing
CAFleet is developed using its own CAFleet-orchestrated skills — the repository dogfoods the spec-driven-development flow it ships. This document covers the project layout, the local development loop, and the contribution path.
Project structure
Rust boundaries
Broker queries return typed records; CLI and HTTP presenters build wire JSON.
Shared diagnosis returns schema and asset facts. Keep process and notification
adapters in runtime/, and preserve command output and guard order when refactoring.
Use the existing CLI integration tests to check behavior across these boundaries.
Tech stack
Development
Clone the repo and run the first-time setup once:
After that, pick the task you need by name. Every cargo-invoking task first builds the WebUI dist (the cargo build embeds it and fails without it), so a fresh clone needs no manual prerequisite:
To change the WebUI's dependencies, edit admin/package.json and run plain
pnpm install --no-frozen-lockfile in admin/ to regenerate
admin/pnpm-lock.yaml — mise //admin:install installs with
--frozen-lockfile and cannot update the lockfile.
Installing the skills from your checkout
cafleet setup installs the assets embedded in the installed binary at its
build time, so it is the end-user (installed-CLI) path. Contributors
working from a clone install the skills from the working tree instead:
This runs gh skill install ./ --from-local --agent <backend> --force --scope user for each of the three backends (claude-code, codex, opencode),
placing the skills from your checkout (not a Release) into the three agent
homes.
Order matters: run cafleet setup first, then mise //:skill-install —
cafleet setup overwrites the agent-home skills with the binary's
build-time-embedded assets, so re-run mise //:skill-install after any
later cafleet setup to restore the working-tree skills.
Building docs locally
The docs site is an rspress project rooted at docs/,
a standalone pnpm package with its own lockfile. Build the documentation site
(this site) locally with:
These tasks are thin wrappers around pnpm install --frozen-lockfile and
pnpm build in docs/ (defined in docs/mise.toml) and are the same
commands the GitHub Actions workflow runs. For a live-reloading local
preview while editing pages, run mise //docs:dev.
Contributing changes
CAFleet uses its own design-doc-driven development skills to evolve the codebase. Each workflow's prompt, team, and output is in Spec Driven Dev § Prompts; run them in that order — create, then interview, then execute.
One detail matters to contributors specifically: the interview pass annotates
the doc with COMMENT(user-relay) markers that the create workflow's resume
mode absorbs.
See your coding-agent's skill documentation for the literal invocation syntax.
Existing design documents under design-docs/
are real examples produced by this loop.
Documentation style
When editing docs/ or README.md, follow these conventions:
- Audience split:
docs/is written for human developers and operators;skills/is written for coding agents. Do not mix the registers. - Voice: second person ("you"), active voice, present tense. Lead each page with what the reader accomplishes, not with architecture.
- Terms: link a term's first use on a page to the Core terms table in the concepts overview; do not re-define it.
- Examples: every CLI example is a runnable command using the standard
sample-id cast — fleet
1, root Director2, members3+ — followed by an expected-output block matching the output shapes in CLI options. Never use shell variables to hold ids. - SSOT: one fact, one home. When another page needs the fact, link; when a fact serves no install/configure/use/understand purpose, delete.
- Tables: state an enumeration of three or more parallel items carrying two or more shared attributes as a table; keep single items, ordered procedures, and rationale as prose. Every table has at least two data rows and cells of at most two sentences. An enumeration that belongs on more than one page gets one owning page carrying the table; every other mention is a link plus a one-clause summary.