> For the complete documentation index, see [llms.txt](https://ascribed-dev.com/docs/llms.txt). This documentation describes Ascribe 0.4.4. Anything marked in main, not yet released isn't in that release yet.

# Command reference

> Reference · The ascribe commands: their options, outputs, and exit codes.

The `ascribe` command checks, builds, and formats an Ascribe project, and runs the language server the editor uses. Its `explain`, `model`, `outline`, `link`, `refs`, `resolve`, and `search` commands answer questions about a project, for writers and for agents, without changing anything, and `ascribe mcp` offers them to agents as the tools of an MCP server.

Install it in a project with `npm install --save-dev @ascribed/cli` (see [Install](https://ascribed-dev.com/docs/install.md#in-a-project-with-npm)) and run it with `npx ascribe`, or from a script in `package.json`. Where there's no Node, install it on your path with Homebrew or the install script ([Install](https://ascribed-dev.com/docs/install.md#on-your-path-without-node)) and run it as `ascribe`.

## Commands

Each command links to its section, with its options, output, and exit codes, on the page for its kind of work.

| Command | What it does |
| --- | --- |
| [`ascribe addresses`](https://ascribed-dev.com/docs/publishing/redirects.md#ascribe-addresses) | Keeps `ascribe.addresses`, the record of where the addresses you published went: makes it, records a move or a retired address, and lists the redirects each build writes. |
| [`ascribe agents`](https://ascribed-dev.com/docs/agents/commands.md#ascribe-agents) | Sets a repository up for agents: writes the project's rules and the skill where agents read them, indexes the docs for a product's agents, and runs an agent's hook. |
| [`ascribe baseline`](https://ascribed-dev.com/docs/checks/baseline.md#ascribe-baseline) | Puts a project's existing advice off for now, so `ascribe check` reports only what's new. |
| [`ascribe build`](https://ascribed-dev.com/docs/checks/check.md#ascribe-build) | Checks the project, then writes each build's outputs. |
| [`ascribe check`](https://ascribed-dev.com/docs/checks/check.md#ascribe-check) | Checks every source file for problems, without building anything. |
| [`ascribe diff`](https://ascribed-dev.com/docs/review/diff.md#ascribe-diff) | Shows what changed between a git revision and the working tree, as readers will see it. |
| [`ascribe drift`](https://ascribed-dev.com/docs/review/diff.md#ascribe-drift) | Lists the pages whose code examples changed, and whether the words around them changed too. |
| [`ascribe explain`](https://ascribed-dev.com/docs/command/questions.md#ascribe-explain) | Says what a diagnostic means, and how to fix it. |
| [`ascribe fmt`](https://ascribed-dev.com/docs/checks/check.md#ascribe-fmt) | Rewrites Ascribe constructs into canonical form. |
| [`ascribe init`](https://ascribed-dev.com/docs/install.md#ascribe-init) | Starts a project: writes its first `ascribe.toml`, and makes the folder its pages go in. |
| [`ascribe link`](https://ascribed-dev.com/docs/command/questions.md#ascribe-link) | Says whether a link works, written on a given page, and the destination to write there. |
| [`ascribe lsp`](https://ascribed-dev.com/docs/editor/language-server.md#ascribe-lsp) | Runs the language server, for an editor. |
| [`ascribe mcp`](https://ascribed-dev.com/docs/agents/commands.md#ascribe-mcp) | Runs an MCP server, for an agent that has no shell, or a host that approves tools one by one. |
| [`ascribe model`](https://ascribed-dev.com/docs/command/questions.md#ascribe-model) | Shows the [content model](https://ascribed-dev.com/docs/glossary.md#content-model) as `ascribe` reads it, with the defaults filled in. |
| [`ascribe new`](https://ascribed-dev.com/docs/templates.md#ascribe-new) | Starts a page from its type's template, with its type and title set. |
| [`ascribe observe`](https://ascribed-dev.com/docs/examples/sources.md#ascribe-observe) | Runs the test of a folder of tested examples, and records what it passed with. |
| [`ascribe outline`](https://ascribed-dev.com/docs/command/questions.md#ascribe-outline) | Shows a page's title and type, and the headings a link to it can name. |
| [`ascribe permalinks`](https://ascribed-dev.com/docs/permalinks/command.md#ascribe-permalinks-1) | Keeps the list of [permalinks](https://ascribed-dev.com/docs/glossary.md#permalink), checks a product's names against it, and retires a permalink. |
| [`ascribe preview`](https://ascribed-dev.com/docs/checks/check.md#ascribe-preview) | Renders a build's pages as a site, serves it on this computer, and renders it again as you edit. |
| [`ascribe refs`](https://ascribed-dev.com/docs/command/questions.md#ascribe-refs) | Lists the places that use a page, a [fragment](https://ascribed-dev.com/docs/glossary.md#fragment), a heading, an image, or an entry of the content model. |
| [`ascribe rename`](https://ascribed-dev.com/docs/command/questions.md#ascribe-rename) | Renames a phrase, a [dimension](https://ascribed-dev.com/docs/glossary.md#dimension)'s value, a heading's id, or a page, and changes everything that uses it. |
| [`ascribe report`](https://ascribed-dev.com/docs/checks/report-command.md#ascribe-report-1) | Reports what state a project is in, section by section. |
| [`ascribe resolve`](https://ascribed-dev.com/docs/command/questions.md#ascribe-resolve) | Resolves a page for one build and writes it as a reader of that build sees it. [A page in the site output](https://ascribed-dev.com/docs/command/site-output.md) says what `--emit site` writes. |
| [`ascribe search`](https://ascribed-dev.com/docs/command/questions.md#ascribe-search) | Finds where the pages say something, as their readers read it, and names the line to edit. |
| [`ascribe sources`](https://ascribed-dev.com/docs/examples/sources.md#ascribe-sources) | Copies code from other repositories, pins it in `ascribe.lock`, and says what changed when the pin moves. |
| [`ascribe templates`](https://ascribed-dev.com/docs/templates/command.md#ascribe-templates-1) | Writes the page templates into a project, and says what's changed in them. |
| [`ascribe vale`](https://ascribed-dev.com/docs/checks/vale.md#ascribe-vale) | Writes Vale's preset out as the project's own configuration. |
| [`ascribe versions`](https://ascribed-dev.com/docs/versions/release.md#ascribe-versions-1) | Lists a project's [release lines](https://ascribed-dev.com/docs/glossary.md#release-line), says what differs between two, and releases, archives, or retires one. |

### Every command's synopsis

```text
ascribe init              [DIR] [--templates] [--content-root <DIR>] [--dry-run] [--force] [--format text|json]
ascribe new               TYPE PATH [--title <TITLE>] [--dry-run] [--force] [--format text|json]
ascribe check             [PATHS]... [--stdin] [--path <PATH>] [--build <NAME>]... [--editor-build] [--code <CODE>]... [--summary] [--format text|concise|json|github|prompt] [--limit <N>] [--exit-code[=error|warning]] [--deny-warnings] [--base <REV>] [--base-exact] [--fix] [--dry-run] [--force] [--vale] [--no-baseline]
ascribe fmt               [--check] [--dry-run] [--force] [PATHS]... [--format text|json|github]
ascribe build             [--build <NAME>]... [--emit site,plain,json] [--format text|json] [--anchors] [--no-baseline]
ascribe preview           [--build <NAME>] [--port <PORT>]
ascribe diff              [PAGE] [--base <REV>] [--base-exact] [--build <NAME>]... [--format text|json|html|prompt] [--exit-code] [--pages-only]
ascribe drift             [--base <REV>] [--build <NAME>]... [--format text|json|markdown] [--exit-code]
ascribe report            [SECTION]... [--format text|markdown|json|prompt] [--build <NAME>]... [--not-listed] [--site <URL>] [--limit <N>] [--recheck] [--no-history] [--no-baseline] [--exit-code[=advice|warning|error]]

ascribe explain           [CODE] [--list] [--format text|json]
ascribe model             [PATH] [--section types|frontmatter|fragments|dimensions|lifecycle|phrases|features|notes|glossary|images|widgets|releases|builds|sources|apis|from|intended|project|versions|consumer|editor|checks|crawlers|listing] [--format text|json]
ascribe outline           PAGE [--build <NAME>] [--format text|json]
ascribe link              TARGET --from <PAGE> [--format text|json]
ascribe refs              TARGET [--limit <N>] [--format text|json]
ascribe search            QUERY [PATHS]... [--type <NAME>] [--case] [--word] [--summary] [--build <NAME>]... [--limit <N>] [--format text|json]
ascribe resolve           PAGE [--build <NAME>] [--emit plain|site] [--frontmatter] [--format text|json]
ascribe rename            TARGET NEW [--dry-run] [--force] [--format text|json]

ascribe baseline write    [--dry-run] [--force] [--format text|json]
ascribe baseline prune    [--dry-run] [--force] [--format text|json]
ascribe versions list     [--format text|json]
ascribe versions changes  FROM TO [--format text|json|markdown]
ascribe versions release  LINE [--next <LINE>] [--dry-run] [--force] [--format text|json]
ascribe versions export   LINE --to <DIR> [--build <NAME>] [--current <URL>] [--format text|json]
ascribe versions retire   LINE [--url <URL>] [--dry-run] [--force] [--show-unused] [--remove-unused] [--format text|json]
ascribe permalinks sync   [--check] [--dry-run] [--force] [--format text|json]
ascribe permalinks list   [--format text|json]
ascribe permalinks verify [NAME]... [--from <FILE>] [--against <PATH>] [--format text|json]
ascribe permalinks retire [NAME]... [--reason <TEXT>] [--to <PAGE>] [--page <PAGE>] [--under <FOLDER>] [--dry-run] [--force] [--format text|json]
ascribe addresses init    [--dry-run] [--force] [--format text|json]
ascribe addresses move    [OLD] [NEW] [--from-git] [--base <REV>] [--base-exact] [--dry-run] [--force] [--format text|json]
ascribe addresses retire  OLD --reason <TEXT> [--dry-run] [--force] [--format text|json]
ascribe addresses list    [--build <NAME>] [--format text|json]
ascribe sources fetch     [NAME]... [--dry-run] [--force] [--format text|json]
ascribe sources update    [NAME]... [--to <REV>] [--dry-run] [--force] [--format text|json|markdown]
ascribe sources status    [--format text|json]
ascribe observe           [--name <NAME>] [--check] [--dry-run] [--force] [--yes] [--format text|json]
ascribe templates list    [--format text|json]
ascribe templates eject   [NAME]... [--to <DIR>] [--keep-type] [--dry-run] [--force] [--format text|json]
ascribe templates status  [--format text|json] [--exit-code] [--diff <NAME>]
ascribe vale eject        [--dry-run] [--force] [--format text|json]

ascribe agents sync       [--check] [--dry-run] [--force] [--target agents-md|skills|claude|claude-rules|copilot|codex]... [--with-hook] [--cloud] [--agent] [--command <COMMAND>] [--format text|json]
ascribe agents rules      [PATH]
ascribe agents index      [--build <NAME>] [--into <FILE>] [--pages <DIR>] [--dry-run] [--force] [--format text|json]
ascribe agents skill      [FILE]
ascribe agents prompt     [NAME] [--arg <KEY=VALUE>]... [--list] [--format text|json]
ascribe agents hook       HARNESS [--event edit|stop] [--command <COMMAND>]
ascribe mcp
ascribe lsp
ascribe --version
```

### Output formats

Available: Ascribe (in main, not yet released, 0.4.5)

`--format` takes the same words on every command that has it. Every command that takes `text` takes `concise` too: `ascribe check` lists one line a problem, and a command with no one-line form writes its text.

### Commands that write

Available: Ascribe (in main, not yet released, 0.4.5)

Every command that changes a file you commit, such as `ascribe fmt`, `ascribe check --fix`, `ascribe rename`, `ascribe init`, `ascribe sources update`, `ascribe templates eject`, `ascribe vale eject`, `ascribe agents sync`, or `ascribe observe`, takes `--dry-run`, which says what it would change and changes nothing. It also refuses to change a file git couldn't put back as it was: one with changes not committed, one git doesn't track, or one in no repository. The error names the files; commit or stash them, or pass `--force` to write them anyway. A file that isn't there yet is only added, so it's never refused.

```console
$ ascribe addresses move guides/old.md guides/new.md
error: this would change files git can't put back as they are: ascribe.addresses; commit or stash them, or pass --force
```

One that takes `--check`, such as `ascribe fmt`, `ascribe permalinks sync`, `ascribe agents sync`, or `ascribe observe`, changes nothing with it either, and is for CI: it prints each change as a unified diff, and exits with `1` when something would change.

## Options every command accepts

- `--config <PATH>`: The content model, `ascribe.toml`, or a directory that holds one. By default, the nearest `ascribe.toml` in the current directory or a parent, so the commands work from anywhere inside a project. Not for `lsp`, whose project comes from the editor, `init`, which starts one, or `observe`, which runs in a folder of code.
- `--color <WHEN>`: When to color text output.
  - `auto` (the default): When writing to a terminal, unless `NO_COLOR` is set.
  - `always`: Always.
  - `never`: Never.

Without `--config`, a command's project is the nearest `ascribe.toml` at or above the current directory, or at or above the path it's given.

When there's none, and the folder holds projects in its subfolders, as a repository with several does at its root, the error names their folders, so you can run the command in one, or pass `--config` with its folder: `the projects below it are in docs, handbook: run ascribe in one of them, or pass --config with its folder`. `ascribe agents sync` is the exception: there, it syncs each of them.
