agentlint-cli 0.1.0

A fast, local-first linter for AI coding-agent configuration
Documentation
# Rule guide

All rules can be configured under `rules` with `off`, `info`, `warning`, or `error`.
For example, disable a rule with `rules: { AGL301: off }`. `agentlint explain AGLxxx`
prints the same core guidance in the terminal.

## Structure (AGL0xx and AGL1xx)

### AGL001 — invalid syntax

Detects JSON, YAML, and TOML that cannot be parsed. Broken syntax prevents agents
from loading configuration. Bad: `{ "servers":`. Good: `{ "servers": {} }`.

### AGL002 — invalid frontmatter

Detects unclosed delimiters, invalid YAML, non-mapping metadata, invalid field types,
and unsupported fields in Markdown/MDC frontmatter. Bad: `description: [`.
Good: `description: Backend rules` between complete `---` delimiters.

### AGL003 — duplicate key

Detects a repeated JSON key in the same object. Different parsers may choose different
values. Bad: two `command` keys in one server. Good: one authoritative `command`.

### AGL101 — invalid MCP

Detects non-object roots/servers, empty servers, absent `command`/`url`, and malformed
`args`, `env`, or `cwd`. Bad: `{ "mcpServers": { "fs": {} } }`. Good: provide a
non-empty command and string argument list.

### AGL102 — unknown field

Detects fields outside conservative known sets for MCP servers and frontmatter. This
often catches spelling errors. Bad: `commandd`. Good: `command`. Vendor extensions
can be allowed by setting this rule to `off` for repositories that need them.

### AGL103 — invalid URL

Detects malformed MCP endpoints and schemes other than HTTP(S). Bad: `ht!tp://host`.
Good: `https://mcp.example.com`.

### AGL104 — missing executable

Checks MCP commands against explicit paths or local `PATH` without executing them.
Bad: `command: npxx`. Good: an installed `npx` or a valid repository-relative binary.

### AGL105 — undocumented environment

Detects `${NAME}`/`$NAME` MCP environment references absent from `.env.example`,
`.env.sample`, or `.env.template`. Bad: require `API_TOKEN` without setup guidance.
Good: add an empty `API_TOKEN=` entry to `.env.example`—never the real value.

## References (AGL2xx)

### AGL201 — invalid glob

Compiles instruction frontmatter globs and reports invalid patterns. Bad: `[src/**`.
Good: `src/**`. agentlint does not guess the intended scope.

### AGL202 — missing path

Uses Markdown links, inline code, extensions, known repository prefixes, MCP args, and
MCP working directories to find plausible paths without treating arbitrary slash words
as paths. Bad: reference removed `src/api/auth.ts`. Good: update it to the current path.

### AGL203 — missing script

Reports missing `scripts/*.sh`, `.fish`, or `.py` references at error severity because
required workflows cannot run. Bad: `Run scripts/check.sh` after it was deleted. Good:
reference the existing validation script.

## Context (AGL3xx)

### AGL301 — large context

Warns at 6,000 approximate local tokens. Large durable prompts crowd out working
context. Bad: embed a complete handbook. Good: keep actionable policy and link to
on-demand documentation.

### AGL302 — duplicate instruction

Compares instructional sentences across files using normalized Jaccard and edit
similarity with a conservative threshold. Bad: repeat the same test rule in AGENTS.md
and CLAUDE.md. Good: keep one canonical rule. It does not use embeddings or cloud AI.

### AGL303 — verbose block

Reports non-code instruction blocks over 1,200 characters as informational. Bad: one
unbroken policy paragraph. Good: short sections with one action each.

## Security (AGL4xx)

### AGL401 — hardcoded secret

Detects credential assignments, bearer tokens, and high-confidence provider prefixes;
placeholders and environment expressions are excluded. Diagnostics reveal only a
masked prefix/suffix. Bad: a live-looking `sk-proj-…` value. Good: `${OPENAI_API_KEY}`.
If triggered, remove and rotate the credential even after deleting it from the file.

## Commands (AGL5xx)

### AGL501 — destructive command

Detects high-risk forms of recursive forced deletion, `git reset --hard`,
`git clean -fdx`, and downloaded scripts piped to a shell. Bad: instruct an agent to
run `git clean -fdx`. Good: inspect and remove explicit paths. Commands are never run.

### AGL502 — unknown command

Checks executables from explicit shell instructions against local `PATH` and suggests
close common-tool spellings. Bad: `nmp test`. Good: `npm test`. Disable or lower this
rule when a repository intentionally documents commands available only in CI.

### AGL503 — missing package script

Checks `npm`, `pnpm`, `yarn`, and `bun` run targets against `package.json`. Bad:
`npm run chek` when only `check` exists. Good: invoke a defined script.

## Consistency (AGL6xx)

### AGL601 — package-manager conflict

Infers npm, pnpm, Yarn, or Bun from lockfiles and `packageManager`, then checks clear
commands and “use …” instructions. Bad: require npm in a pnpm repository. Good: use
pnpm consistently. Ambiguous prose is ignored.

### AGL602 — contradictory instruction

Matches opposite polarity for normalized subjects in imperative forms such as always,
never, must, do not, avoid, forbidden, required, skip, and may freely edit. Bad:
“Always use npm” plus “Never use npm.” Good: retain one scoped policy. This rule is
deliberately not a general-purpose natural-language inference engine.

### AGL603 — tooling mismatch

Detects pytest without Python metadata, Cargo commands without `Cargo.toml`, and Go
tests without `go.mod`. Bad: stale `pytest` guidance in a non-Python repository. Good:
remove it or restore the relevant project metadata.