Cratis AI
cratis ai installs and maintains Cratis-owned AI guidance — rules, skills, agents, prompts, hooks, and harness integration — in a repository. The content comes from the Cratis AI corpus.
The idea is one shared corpus and many thin adapters. Guidance is installed once, into .cratis/ai/, and every coding agent you use is pointed at that same copy. Claude Code, Codex, Copilot, Cursor, OpenCode and pi each read guidance from their own conventional location, so each gets a native adapter that links back to the one corpus. Nothing is duplicated per tool, and updating the corpus updates every tool at once.
Commands
Section titled “Commands”cratis ai install # choose what this repository needs, and install itcratis ai update # re-synchronize the choice already recordedcratis ai status # what is configured, installed, available, and locally modifiedcratis ai uninstall # remove unchanged Cratis-managed contentRun install once per repository. Use update from then on.
cratis ai install
Section titled “cratis ai install”Installs the corpus into the current repository and records your selection in .cratis/ai.json.
What it writes
Section titled “What it writes”.cratis/├── ai.json your selection — commit this├── ai.manifest.json what Cratis installed, with hashes — commit this└── ai/ ├── rules/ always-on and path-scoped rules ├── skills/ on-demand skills ├── agents/ subagent definitions ├── prompts/ slash commands and prompts ├── hooks/ enforcement scripts └── harnesses/<name>/ harness-specific content, e.g. pi extensions, Cursor rules
AGENTS.md, CLAUDE.md links to the project instructions.claude/ .cursor/ .github/ native adapters, each linking into .cratis/ai/.opencode/ .pi/ .agents/Adapters are symbolic links into .cratis/ai/, not copies. A user-owned file already sitting at one of those paths is left exactly as it is — install never replaces your own content.
Commit all of it, including the installed .cratis/ai/ tree, so everyone on the team and every CI run gets identical guidance.
Choosing a selection
Section titled “Choosing a selection”Three dimensions decide what you receive. Only the first two normally matter.
| Dimension | What it selects | Required |
|---|---|---|
profiles | Which body of guidance applies — the important decision | Yes |
harnesses | Which coding agents get an adapter | Yes |
languages | Narrows the languages composed by the selected profiles | No |
Profiles are the choice worth thinking about, and the split is what you are building:
cratis/application/*— you are building an application on Cratis: vertical slices, commands and read models, Chronicle and Arc, a React frontend. Pick this for product repositories.cratis/engineering/*— you are contributing to a Cratis framework repository itself: libraries, source generators, the Chronicle kernel, client SDKs. The application architecture rules deliberately do not apply here.cratis/documentation— add alongside either when the repository contains documentation.
Getting this wrong is the most common mistake: an application repository configured with engineering profiles will not receive the slice guidance, and a framework repository configured with application profiles receives a manual that tells it not to apply.
Harnesses cost nothing to add. Selecting a tool you do not use only creates an unused adapter, so most repositories select all of them.
Languages is optional and narrowing, not additive. Omit it and no language constraint is applied, so every language a selected profile composes is installed. Name csharp,typescript and a Kotlin or Elixir rule composed by the same profile is skipped. Use it when a repository is genuinely single-language and you want less guidance loaded.
Interactive and non-interactive
Section titled “Interactive and non-interactive”In a terminal, each dimension is a multi-select prompt:
cratis ai installWhen input is redirected — CI, scripts, an agent — prompting is impossible, so --profiles and --harnesses must be passed. --languages may be omitted, which means unconstrained:
# An application repository, all harnessescratis ai install \ --harnesses claude,codex,copilot,cursor,opencode,pi \ --profiles cratis/application/csharp,cratis/documentation \ --languages csharp,typescript
# A framework repository, pi onlycratis ai install --harnesses pi --profiles cratis/engineering/csharp
# Deterministic and offline: read the corpus from a local checkoutcratis ai install --harnesses pi --profiles cratis/documentation --source ../AIOptions
Section titled “Options”| Option | Description |
|---|---|
--profiles <NAMES> | Comma-separated profiles. Required when input is redirected. |
--harnesses <NAMES> | Comma-separated harnesses: claude, codex, copilot, cursor, opencode, pi. Required when input is redirected. |
--languages <NAMES> | Comma-separated languages. Optional; omitting it applies no language constraint. |
--source <PATH> | Read the corpus from a local checkout of Cratis/AI instead of downloading the published one. Use it to pin a revision, work offline, or make a CI run deterministic. Falls back to CRATIS_AI_SOURCE, then to the published download. |
-f|--force | Replace or remove Cratis-managed files that were edited locally. Without it, a modified managed file is reported and nothing is written. |
--dry-run | Report the changes that would be made and write nothing. The output is the same shape as a real run, so --output json works unchanged. |
Templates come preconfigured
Section titled “Templates come preconfigured”The Cratis dotnet new templates ship a .cratis/ai.json with the right profiles, languages and harnesses already chosen, and dotnet new prints a reminder. If you scaffolded from a template, skip install — the selection exists already — and run:
cratis ai updatecratis ai update
Section titled “cratis ai update”Re-synchronizes using the selection already in .cratis/ai.json, so it takes no dimension options. Run it to pick up a newer corpus. To change the selection, run install again.
Update only touches files the manifest records as Cratis-managed, and never overwrites your edits: a modified managed file is reported as a conflict and nothing is changed until you pass --force or restore the file. Accepts --source, --force and --dry-run.
Seeing what an update will do first
Section titled “Seeing what an update will do first”The corpus is not pinned on this channel: an update takes whatever the source currently holds. --dry-run reports exactly what would change and writes nothing, so a run can be reviewed before it happens.
cratis ai update --dry-runThe report is the same actions and conflicts the real run produces, plus dryRun: true, so it can be diffed or piped:
cratis ai update --dry-run --output json | jq -r '.actions[]'It is available on install and uninstall too. On uninstall it lists what would be removed without removing it.
cratis ai status
Section titled “cratis ai status”Read-only. Shows the configured profiles, harnesses and languages, the revision installed here, the revision available from the source, whether an update is available, and any managed file modified locally. Exits non-zero when local modifications exist, which makes it usable as a CI check that guidance has not drifted.
cratis ai status --output jsoncratis ai uninstall
Section titled “cratis ai uninstall”Removes Cratis-managed files and the harness adapters Cratis created, preserving user-owned files. Modified managed files are reported as conflicts; --force removes them anyway. Use --dry-run to list what would be removed first.
How update and uninstall stay precise
Section titled “How update and uninstall stay precise”Every installed file carries a managed marker, and .cratis/ai.manifest.json records each file’s source and content hash. That is what lets update and uninstall distinguish their own files from yours, act only on Cratis-installed content, and detect a local edit rather than silently overwriting it.
Troubleshooting
Section titled “Troubleshooting”| Condition | Result |
|---|---|
No .cratis/ai.json exists from update or status | The repository has no selection yet — run cratis ai install. |
Unknown harness, profile or language passed to install | Validation error listing what the corpus offers. |
--profiles or --harnesses missing from install with input redirected | Validation error: the option is required when prompting is impossible. |
Modified managed files, or a user-owned path in the way, without --force | Conflict report, and no files are changed. |
status reports updateAvailable but update changes nothing | The corpus revision moved without changing any file this selection receives. |