<!-- Generated by scripts/ax-docs.mts from the JSDoc in registry/ouro/ax/. Do not edit; run `pnpm run docs`. -->

# ax-checks

A tool's checks, such as a doctor or a self-check, declared once: progress while they run, the verdict first and the results grouped for a person, the same facts as `--json` for an agent, the time taken and the exit code. A problem comes with its fix: the exact command, or the thing to do by hand, and never a developer command or a repository path (ax-dev-commands) unless the fix is marked `sourceCheckout: true`.

```sh
npx shadcn@latest add ourostack/ouro-ui/ax-checks#v1.3.10
```

It installs `lib/ouro/ax/checks.ts`, with `ax-dev-commands`, `ax-exit-codes`, `ax-outcome`, `ax-terminal`. Its tests are `ax-checks-tests`. Every item runs on Node 22.18 or later as it is copied: the files import each other as `./<file>.ts`. The [Ouro AX guide](ax.md) shows how they fit together.

## Exports

### `CheckDef`

```ts
interface CheckDef<C> {
  id: string;
  label: string;
  needs?: readonly string[];
  run(context: C): CheckResult | Promise<CheckResult>;
}
```

### `CheckFix`

A tool's checks, such as a doctor or a self-check, declared once: progress while they run, the verdict first and the results grouped for a person, the same facts as `--json` for an agent, the time taken and the exit code. A problem comes with its fix: the exact command, or the thing to do by hand, and never a developer command or a repository path (ax-dev-commands) unless the fix is marked `sourceCheckout: true`.

```ts
type CheckFix = NextStep | { byHand: string; sourceCheckout?: true };
```

### `CheckResult`

What a check found. A warning or a failure carries its fix; a check that was not run says why, and `kind` names what it waits on, read after a count ("waiting on something you name", "by hand"), so the not-run line groups them.

```ts
type CheckResult =
  | { state: "passed"; detail?: string }
  | { state: "warned" | "failed"; detail: string; fix: CheckFix }
  | { state: "skipped"; detail: string; kind?: string; fix?: CheckFix };
```

### `CheckRow`

```ts
interface CheckRow {
  id: string;
  label: string;
  state: CheckState;
  detail: string;
  fix: CheckFix | null;
  kind: string | null;
  durationMs: number;
}
```

### `Checks`

```ts
interface Checks<C> {
  readonly def: ChecksDef<C>;
  run(context: C, options?: ChecksRunOptions): Promise<ChecksReport>;
}
```

### `CHECKS_VERSION`

The version of the report's shape; `--json` carries it as `ax`, as an outcome or a wait does.

```ts
const CHECKS_VERSION: "checks/1"
```

### `ChecksDef`

```ts
interface ChecksDef<C> {
  command: string;
  noun?: readonly [string, string];
  checks: readonly CheckDef<C>[];
}
```

### `ChecksReport`

One run's facts, the same for the person's text and the agent's `--json`.

```ts
interface ChecksReport {
  ax: typeof CHECKS_VERSION;
  verdict: Verdict;
  summary: string;
  durationMs: number;
  counts: Record<CheckState, number>;
  rows: CheckRow[];
  next: NextStep[];
  exitCode: number;
}
```

### `ChecksRunOptions`

```ts
interface ChecksRunOptions {
  progress?: ProgressStream;
  env?: Readonly<Record<string, string | undefined>>;
  off?: boolean;
  timers?: Timers;
  next?: readonly NextStep[];
}
```

### `CheckState`

`errored` is a check that threw before finishing, so the tool broke rather than found something.

```ts
type CheckState = "passed" | "warned" | "failed" | "errored" | "skipped";
```

### `checksText`

The report for a person: the verdict on the first line, then the results grouped (what failed, what warned, what was not run, and what passed with `verbose`), each problem with its fix, then the next steps. On success it prints the verdict and what is left to act on, and with `verbose` every check and its time. Off a terminal the marks are words and there is no colour, so the first line reads `FAIL 1 of 12 checks failed: …`.

```ts
function checksText(report: ChecksReport, style: TerminalStyle, options?: { verbose?: boolean | undefined; command?: string | undefined; }): string
```

### `defineChecks`

Declares a tool's checks once: from this one definition come the progress while they run, the verdict and the grouped results for a person, the `--json` for an agent, the timing and the exit code. Throws at definition time on an empty list, a repeated id, an empty label or a `needs` that names no earlier check, and at run time when a warning or failure has no fix, or its fix is the command just run, so a tool's own tests catch both. A fix or a next step that asks for a developer command or a repository path throws too, so a doctor never tells a person to run a repository script.

```ts
function defineChecks<C>(def: ChecksDef<C>) => Checks<C>
```

Example:

```ts
const doctor = defineChecks({
  command: "notes doctor",
  checks: [
    { id: "store", label: "Notes file", run: () => ({ state: "passed" }) },
    { id: "sync", label: "Last sync", needs: ["store"], run: () => ({ state: "warned", detail: "last synced 3 days ago", fix: { command: "notes sync", why: "Sync now" } }) },
  ],
});
const report = await doctor.run(context, { progress: process.stderr, env: process.env });
```

### `isChecksReport`

Whether a value is a checks report: what the X-ray looks for in a read's `--json`.

```ts
function isChecksReport(value: unknown): value is ChecksReport
```

### `printChecks`

Prints a report the way the kit's commands print a result: `--json` as one JSON document, otherwise the text for the stream it goes to, each with one trailing newline. Returns the exit code.

```ts
function printChecks(report: ChecksReport, io: { stdout: { write(s: string): unknown; isTTY?: boolean | undefined; }; env: Readonly<Record<string, string | undefined>>; }, options?: { json?: boolean | undefined; verbose?: boolean | undefined; command?: string | undefined; }): number
```

### `Verdict`

```ts
type Verdict = "passed" | "warned" | "failed" | "errored";
```
