AI Decision System
Replayable, offline-verifiable records for AI-assisted go/no-go decisions: experiment promotions, typed model answers and human-approved actions.
One command line for documentation that is meant to be checked. It validates metadata and page structure, checks citations against their source, runs evals over documentation pages, and checks sites f
Developer toolsTypeScript · JavaScriptGitHub @hawkeyexlOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
One command line for documentation that is meant to be checked. manni meta: front matter validation, formerly docmeta.
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
One command line for documentation that is meant to be checked. manni meta
validates the presence and format of document metadata against JSON
Schema, built for CI. It was published as docmeta up to 4.13.1; see
Coming from docmeta.Read the full README ↗One command line for documentation that is meant to be checked. manni meta
validates the presence and format of document metadata against JSON
Schema, built for CI. It was published as docmeta up to 4.13.1; see
Coming from docmeta.
manni meta checks the metadata in your documents (Markdown frontmatter and more)
against one or more JSON Schemas. It verifies that required fields are present
and correctly formatted: a type, an ISO 8601 timestamp, a URI resource. It
does not judge prose quality. It ships with 45 built-in
schemas. They
cover content vocabularies such as the Open Knowledge Format
(OKF),
Diátaxis, The Good Docs
Project, and the Seven-Action
model. They also cover the front matter
contracts of site generators such as
Docusaurus
3.10, Hugo, Jekyll, and MkDocs Material. Twenty-six are manni's own metadata
vocabularies and their strict overlays. Run manni meta schemas for the full
list. It follows clig.dev conventions and returns a nonzero
exit code (plus optional GitHub annotations) when validation fails.
It can also fill in the metadata that is missing, so adopting a standard on an existing docset is not a data-entry project.
npm install -g @hawkeyexl/manni
# or run it without installing:
npx @hawkeyexl/manni meta validate "**/*.md"
Requires Node.js 24 or later.
Once a repository sets up a few of the tools, manni status says which are in
play and manni check runs all of them as one gate. In Claude Code, the
manni plugin runs the same check after each edit an agent makes. Install it
with claude plugin marketplace add hawkeyexl/manni, then
claude plugin install manni@manni. See
Gate every check and
Keep an agent's docs green.
The metadata tool used to be the whole package. Three things changed:
docmeta validate … is now manni meta validate …. The
package still installs a docmeta bin that runs the same program, so
existing scripts keep working while you move them.manni.config.yaml, shared by every tool in the
family, with the metadata tool's keys under meta:. A docmeta.config.yaml
is still read, with a warning.uses: hawkeyexl/manni@v4 now runs manni check,
every check the repository has set up. Add command: meta validate to run
the metadata check alone, with the inputs it took before.The rename changed nothing else. The exit codes, the output formats and the
programmatic API carry over, and so do the built-in schemas and their published
URLs. The old …/docmeta/schemas/ URLs stay served and resolve offline.
Point manni meta validate at a file, a directory (walked recursively), or a glob. With no --schema, it validates against the default set of eleven built-in schemas. The OKF schema requires type, and the manni core vocabulary requires title and description. passo-uno:seven-action:1.0 and the other eight manni vocabularies check a field only when a page carries it.
manni meta validate docs/intro.md
✗ docs/intro.md
(root) must have required property 'type' [google:okf:0.1]
(root) must have required property 'description' [manni:core:1.0.0]
/timestamp must match format "date-time" (line 9) [google:okf:0.1]
1 file checked, 0 passed, 1 failed, 0 errors
A clean run exits 0; validation failures exit 1; operational errors (no input, unknown schema, parse error) exit 2.
A config's meta.schemas add to the default set, and meta.defaults: false makes them replace it. meta.register names your own schemas by their $id, and meta.strict: true stacks each strict version beside its base. The configuration reference has every key.
On GitHub Actions, use the packaged action. It sets up Node, pins the CLI, and
runs manni check, every check the repository has set up, as inline PR
annotations:
- uses: actions/checkout@v7
with:
fetch-depth: 0
- uses: hawkeyexl/manni@v4
command: runs any one manni command instead, such as meta validate. Every
input is in the Action
reference. Other
platforms run the CLI directly. The CI
recipes cover GitLab CI,
Jenkins, and the rest.
To catch problems before they reach CI, manni meta publishes a pre-commit hook. The whole configuration is three lines, and the file-matching pattern is derived from the extensions manni meta actually reads rather than hand-written:
repos:
- repo: https://github.com/hawkeyexl/manni
rev: v4.27.2
hooks:
- id: manni-meta
manni meta fill infers the metadata properties your schema asks for but a page
does not carry, and writes back the values it is confident about. It is the
fast way to clear the backlog on a repo that has never enforced metadata.
manni meta fill docs/ --dry-run # preview; writes nothing
manni meta fill docs/ # apply
✓ docs/intro.md
/description A tour of the CLI and its four commands. 0.91
below 0.7: /resource 0.38
anthropic/claude-sonnet-4-5 · Threshold 0.7 · 1 file · 1 field written · 1 skipped
Confidence is the last gate, not the only one. A proposal must first satisfy the
target property's own subschema. It must name a property your schema declares,
and it must leave the document still valid after the merge. Only then does
--confidence (default 0.7) apply. Values below it are skipped and reported
by name. They are never written with a caveat, and the score itself never
reaches your document.
fill writes in place by default, so run it on a clean tree and review the
diff.
It picks an LLM provider by detecting one. The order is ANTHROPIC_API_KEY,
then OPENAI_API_KEY, then a claude CLI that runs, then a local model that
needs no credentials at all. That means it works with whatever you have, and it
reports which provider it used. Pass --provider to pin one. That is worth
doing in CI. Left to detect, a runner that loses its key falls back to the local
model, and downloads it rather than failing the build.
Pass --local when the document must not leave the machine. It runs inference
on-device with llama-cpp and overrides any provider the config names,
saying which one it set aside. It never picks the claude CLI, which runs
locally while its inference does not. See the fill
reference for every
flag and for what the local fallback costs.
Markdown, MDX, AsciiDoc, reStructuredText, XML (including DITA topics and maps),
and HTML. Run manni meta schemas to list the built-in schemas, every supported
format, and which formats fill can write back to.
fill writes to all of them. It splices the exact character range of the value
rather than re-serializing the document. Comments, entity spellings, attribute
order, indentation, and a DOCTYPE all survive untouched.
Full guides, recipes, and reference live on the documentation site:
https://hawkeyexl.github.io/manni/meta/
| Track | What it covers |
|---|---|
| Get started | Install and run your first validation. |
| Set up validation | Stand up validation for a repo: manni.config.yaml, per-folder schema overrides. |
| Run it in CI | GitHub Actions and other CI recipes, exit codes, and PR annotations. |
| Define & evolve schemas | Author a schema, wire up resolution, and version it without breaking the build. |
| Reference | Every CLI flag, Action input, config key, the schema-resolution precedence chain, and output formats. |
Contributions are welcome. See CONTRIBUTING.md for dev setup, the test loop, and how to add support for a new input format.