manni lint
manni meta checks what a page says it is. manni lint checks whether it is
shaped like one. A page that declares type: how-to is supposed to carry an
overview, the prerequisites, the steps, and somewhere to go next. Nothing
enforces that but a reviewer’s eye, and a reviewer’s eye is the thing that runs
out first.
npx @hawkeyexl/manni lint check docs/Checked: structure.✗ docs/rotate-key.md 5:1 manni:lint/structure/missing-section Rotate an API key: Missing section "See also"
1 file checked, 0 passed, 1 failed, 0 skippedExit 1, with a line and a rule id. The command you run locally is the one
that gates the pull request.
Jobs, not tools
Section titled “Jobs, not tools”manni lint has one verb per kind of check, and one that runs them all:
| Command | Runs |
|---|---|
manni lint check [paths...] | Every configured job |
manni lint structure [paths...] | Document structure against doctype templates |
manni lint templates | The templates that could route a page, and the doctypes each serves |
manni lint templates infer <page> | A first template, written from a page that already has the shape you want |
manni lint tools | Each job, the tool that performs it, what it reads, and which content kinds each format reports |
A job is what is being checked. The tool that answers it is an
implementation you can swap. structure is the job, and this package’s own
engine, named manni, answers it. Naming the verbs after the jobs
means swapping the tool underneath does not change the command anyone types.
It also means running exactly one kind of check is one word rather than a flag.
There is no default subcommand. manni lint docs/ is a usage error that lists
the verbs, because a domain with one verb still spells the verb.
What a template is
Section titled “What a template is”A template describes the shape a doctype promises. That is which sections a page of that kind has, in what order, and what has to be inside each one. Inside can mean paragraphs, code blocks, lists, tables, admonitions, images, block quotes, definition lists, or a named component.
Seven ship, derived from The Good Docs
Project at v1.6.0, covering how-to,
tutorial, reference, concept and explanation, troubleshooting,
release-notes and readme. A page routes to one by its own type:
frontmatter, the same key manni meta already validates. A repository that
declares doctypes gets structure checking with no per-page change at all.
Your own templates are one config entry away, and they outrank the built-ins
for the doctypes they claim. manni lint templates infer writes the first one
from a page you already have, and
Write a template takes it from there.
Deterministic, by design
Section titled “Deterministic, by design”There is no language model here, and no network call except fetching a template you pointed at yourself. Two runs over the same bytes give the same findings, so a red check is reproducible and a green one means something.
That line is load-bearing rather than decorative. The template format used to
carry an instructions: key a model evaluated; it is refused now, with a
message pointing at where that question belongs. Judgement about prose is a
different tool’s job.
Where things live
Section titled “Where things live”One config file, manni.config.yaml, shared with every other manni tool. The
document set is the family’s collections: list, so manni meta validate and
manni lint check run over exactly the same pages without being told twice.
Everything else is under lint:.
collections: - name: guides paths: ["docs/**/*.md"] exclude: ["**/drafts/**"]
lint: templates: - ./templates.yamlWith that, both gates are a bare command:
manni meta validatemanni lint checkComing from doc-structure-lint?
Section titled “Coming from doc-structure-lint?”This is that package, folded into the manni bin and given a family surface. The
command is manni lint check, the config moves under lint: in
manni.config.yaml, and paths: / exclude: become a collection. The template
format is a grammar now rather than a map of section rules. A template written
against the old package is refused, with the new spelling of each key.
The
migration table
has every change.