AGENTS.md@toolkit/skillet · git:20260921.e8da9da · 2026-09-21 · sha256 24ff8ada34568580

AGENTS.md@toolkit/skillet git:20260921.e8da9daA

Immutable. This exact content never changes and is served at /api/v1/blob/24ff8ada34568580.

# ai-skillet contributor guidance

Keep the CLI synchronous and library-owned: `src/main.rs` parses process arguments and maps
errors to exit codes, while behavior belongs in `src/lib.rs` and focused modules.

The supported public surface is `map`, `doctor`, `doctor --dependencies-only`, and `--version`.
Preserve the documented exit codes and deterministic text, JSON, and DOT output contracts.

Use the nightly minimal Rust toolchain configured at the monorepo root. Before proposing a change,
run the narrowest relevant locked Cargo check. Keep macOS and Linux compatibility; do not add
runtime services, plugin systems, config files, shell hooks, or completion generation without an
explicit product decision.

From the monorepo root, `cargo test -p ai-skillet --locked` is the focused package gate and
`just rust-check` is the aggregate Rust gate. `just install-cli` installs every workspace binary
under `~/.local`; do not run it for ordinary verification.

## CLI reference

`ai-skillet` inspects and maintains catalogs of agent skills.

### Status

Version 1.0.0 provides synchronous, no-network `map` and `doctor` engines. JSON reports use the
clean Rust schema version 1. The schema preserves the Python tools' consumer contracts, but output
is not byte-compatible with the Python implementation.

### Commands

```text
ai-skillet map [OPTIONS]
ai-skillet doctor [OPTIONS]
ai-skillet --version
```

`doctor --dependencies-only` limits diagnostics to skill-dependency declarations. Repeatable
`doctor --skill <NAME>` filters diagnostics and safe fixes by canonical skill directory name.

A catalog root that exposes `skills/` must provide a `README.md` with an exact `## Skills`
section and a Markdown table. The required first column is `Skill` and lists every active skill
name; additional columns are optional and ignored by the inventory validator. Conventional
installed roots named `.agents`, `.claude`, or `.codex` do not require a catalog README inventory.

Skills in ordinary source-catalog `skills/<name>` paths must provide `agents/openai.yaml`.
Conventional installed exposures beneath `.agents/skills`, `.claude/skills`, or `.codex/skills`
may omit that file. When an installed exposure provides it, doctor still validates the extended
`policy.allow_implicit_invocation` contract and can safely update a mismatch.

### Doctor validation contract

`ai-skillet doctor --root <skill-or-catalog-root>` is the canonical deterministic, offline local
validator for the supported extended skill dialect. For an explicit targeted audit, pass a catalog
root with one or more filters:

```sh
ai-skillet doctor --root '.agents/skills' --skill 'land-search'
```

A direct `skills/<name>` root is shorthand for auditing only that directory while resolving bare
dependencies against sibling skills in the owning `skills` directory. This applies equally to
source catalogs and `.agents`, `.claude`, or `.codex` installed exposures, including directory
symlinks. A standalone skill outside a `skills/<name>` layout does not infer an owning catalog;
bare dependencies must still resolve from explicitly supplied roots. Targeted audits omit
catalog-wide README inventory diagnostics, and `--fix-safe` modifies only selected skills.

Doctor accepts this one top-level field union:

- Portable [Agent Skills](https://agentskills.io/specification): `name`, `description`, `license`,
  `compatibility`, `metadata`, and `allowed-tools`.
- [Claude Code extensions](https://code.claude.com/docs/en/skills#frontmatter-reference):
  `when_to_use`, `argument-hint`, `arguments`, `disable-model-invocation`, `user-invocable`,
  `disallowed-tools`, `model`, `effort`, `context`, `agent`, `background`, `hooks`, `paths`, and
  `shell`.
- Repository extensions: `coordination` and `skill-dependencies`.

Unknown top-level fields are errors. `metadata` must be a string-to-string mapping;
`metadata.install-targets` additionally accepts only `claude-code`, `codex`, or
`claude-code codex`. Tool, argument, and path fields accept a string or a list of strings, while
`hooks` must be a mapping. Claude Boolean fields accept `true`/`false`, `yes`/`no`, `on`/`off`,
or `1`/`0`; other YAML shapes are not coerced. `context` accepts only `fork`, `effort` accepts
`low`, `medium`, `high`, `xhigh`, or `max`, and `shell` accepts `bash` or `powershell`. `agent`
and `background` require `context: fork`.

`coordination: exempt` requires this exact sentence in ordinary Markdown body prose:

```text
This skill is coordination-exempt: skip the ai-coord gate for its declared work.
```

Inline code, fenced or indented code, blockquotes, and clearly headed `Example` or `Examples`
sections do not count as declarations and do not trigger missing-frontmatter errors.

New schema diagnostics use these stable codes:

- Unknown field: `FRONTMATTER_UNKNOWN_FIELD`.
- Invalid types: `LICENSE_INVALID_TYPE`, `ALLOWED_TOOLS_INVALID_TYPE`,
  `WHEN_TO_USE_INVALID_TYPE`, `ARGUMENTS_INVALID_TYPE`, `DISALLOWED_TOOLS_INVALID_TYPE`,
  `MODEL_INVALID_TYPE`, `EFFORT_INVALID_TYPE`, `BACKGROUND_INVALID_TYPE`,
  `HOOKS_INVALID_TYPE`, `PATHS_INVALID_TYPE`, `SHELL_INVALID_TYPE`, and
  `METADATA_VALUE_INVALID_TYPE`. Existing field-specific type codes remain unchanged.
- Invalid values: `EFFORT_INVALID_VALUE` and `SHELL_INVALID_VALUE`, alongside the retained
  compatibility, context, coordination, and install-target codes.
- Cross-field errors: `AGENT_CONTEXT_REQUIRED` and `BACKGROUND_CONTEXT_REQUIRED`.
- Explicit defaults: `disable-model-invocation: false` and `user-invocable: true` restate the
  effective defaults and are accepted without findings, so catalogs that require explicit
  booleans stay clean.

These diagnostics add findings without changing JSON schema version 1, deterministic finding
order, exit codes, or the existing `--fix-safe` boundary.

### Conformance contract

| Area         | Required contract                                                                                                                                          | Intentional version 1 behavior                                                                          |
| ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| CLI          | Usage and operational errors exit 2; doctor findings exit 1; safe-fix failures exit 3                                                                      | Operational errors are emitted once with no generic duplicate                                           |
| Map output   | Deterministic text, JSON, and DOT; skills, roots, edges, duplicates, unresolved references, hashes, and portfolio exposures remain available               | Declared and inferred evidence remain independent; missing filters warn while returning an empty report |
| Discovery    | Explicit roots, broad-root exclusions, portfolio roots, ignored entries requested directly, symlink exposures, and paths containing newlines are supported | Local dependencies resolve across every scanned root                                                    |
| Streaming    | Large files and newline-free lines are scanned with bounded buffers; snippets are bounded match text                                                       | No ripgrep child process or cancellation lifecycle is required                                          |
| Doctor       | The complete supported frontmatter union plus every metadata, dependency, coordination, resource, README, prompt-hygiene, and CLI-version finding family is validated | YAML and OpenAI policy diagnostics are structural; safe fixes are isolated and atomic                   |
| Dependencies | Bare and external identifiers, uniqueness, self-reference, resolution, and target-name ordering are validated                                              | External owner/repository case is preserved; repository names ending in `.git` are rejected             |

The integration tests in `tests/conformance.rs`, `tests/map.rs`, `tests/doctor.rs`, and
`tests/catalog.rs` are the executable contract. Python captures are migration evidence, not golden
output fixtures.

### Development

The monorepo selects nightly Rust with the minimal profile plus `clippy` and `rustfmt`.

```sh
cargo test -p ai-skillet --locked
just rust-check
```

From the monorepo root, `just install-cli` installs all five workspace binaries under `~/.local`.

### License

MIT. See [LICENSE.md](../LICENSE.md).