quire-cli is a static command-line wrapper around
quire-rs. It gives agents and
humans one fast binary for parsing, extracting, looking up, editing,
validating, inspecting the input contract of Markdown artifacts, and exporting
source-grounded assurance facts.
The crate is intentionally a thin process boundary: Markdown parsing,
extraction, and structural validation live in quire-rs.
quire assurance --scope <DIR> --module <PATH> --repository <IDENTITY> \
--revision <FULL_SHA> --expect-module <NAME@VERSION> \
[--expect-schema <MODULE/ARCHETYPE@SHA256>]...
quire parse <DOC|->
quire lookup <DOC|-> (--heading <TEXT> [--level <1..6>] | --id <ID> | --block-id <BLOCK_ID>) [--content]
quire edit <DOC|-> (--heading <TEXT> | --block-id <BLOCK_ID>) --content <FILE|-> [--out <PATH>]
quire extract <DOC|-> --module <PATH> [--archetype <NAME>]
quire validate <DOC|GLOB|->... [--scope <DIR>] [--module <PATH>] [--archetype <NAME>]
quire validate --okf <BUNDLE_DIR> [--scope <DIR>] [--module <PATH>]
quire schema <ARCHETYPE> --module <PATH>Global flags:
| Flag | Default | Purpose |
|---|---|---|
--diagnostics-format <human|json> |
human |
stderr diagnostic encoding |
--pretty |
off | indented JSON output for JSON-emitting commands, including assurance |
Exit codes:
| Code | Meaning |
|---|---|
| 0 | success |
| 1 | user error: parse failure, schema violation, unknown archetype, I/O error, lookup miss |
| 2 | argv error: missing required flag, unknown flag, invalid flag combination |
| 134 | panic, never expected |
Published on the public npm registry as @agent-ix/quire-cli.
A per-platform optional dependency carries the prebuilt binary, so no Rust
toolchain and no quire-rs checkout is needed — just install:
npm install -g @agent-ix/quire-cli # or: npx @agent-ix/quire-cli --help
quire --helpPrebuilt targets: linux-x64, linux-arm64 (musl/static), darwin-arm64, win32-x64. Linux x64 covers Intel and AMD; win32-x64 covers Intel and AMD Windows.
Each release attaches a
quire-<version>-<target>.tar.gz (.zip on Windows) plus SHA256SUMS.txt.
Download, verify, and drop quire on your PATH.
quire-cli builds on quire-rs, fetched
from GitHub at build time, so configure cargo with net.git-fetch-with-cli = true.
cargo install --git https://github.com/agent-ix/quire-cli
# or, from a checkout:
cargo build --release && target/release/quire --helpDuring development, target/debug/quire is fine for local testing.
Parse a document into a QuireDocument JSON envelope:
quire --pretty parse spec/functional/FR-001.mdPrint a compact outline:
quire parse spec/functional/FR-001.md \
| jq -r '.. | objects | select(has("heading") and has("level")) | "\(.level) \(.heading) id=\(.id) block_id=\(.block_id // "-") lines=\(.start_line)-\(.end_line)"'Inspect frontmatter:
quire parse spec/functional/FR-001.md | jq '.frontmatter'Fetch one parsed section as JSON:
quire lookup spec/functional/FR-001.md --heading Behavior
quire lookup spec/functional/FR-001.md --heading "Document Title" --level 1
quire lookup spec/functional/FR-001.md --id behavior-L14
quire lookup spec/functional/FR-001.md --block-id blk-behaviorFetch only section body bytes:
quire lookup spec/functional/FR-001.md --heading Acceptance --content
quire lookup spec/functional/FR-001.md --block-id blk-behavior --content--id is generated as <slug>-L<line> and can change when lines move.
For stable machine addressing, author headings with Pandoc block IDs:
## Behavior {#blk-behavior}Then use:
quire lookup doc.md --block-id blk-behaviorReplace a single section's body (or a full block) without rewriting the rest of the document — frontmatter and every untouched section stay byte-identical:
# Replace the Acceptance Criteria body in place (new content from stdin)
quire lookup FR-001.md --heading "Acceptance Criteria" --content # read current
quire edit FR-001.md --heading "Acceptance Criteria" --content new-ac.md --out FR-001.md
# Replace a full stable block (heading line + body) from stdin
quire edit FR-001.md --block-id blk-behavior --content - < new-block.md--heading content is the section BODY (everything after the heading line);
--block-id content is the FULL block (heading line, with its {#blk-id}
attribute, plus the body). Omit --out to write the updated document to stdout.
Run an archetype's body_extraction DSL and collect edges:
quire extract spec/objects/EX-001.md --module ./extract-modOverride archetype inference when needed:
quire extract EX-001.md --module ./extract-mod --archetype ExtractSampleShow only harvested edges:
quire extract EX-001.md --module ./extract-mod | jq '.edges'extract does not auto-validate. Run validate separately for context
JSON schema checks.
Emit quire-rs's closed quire-assurance v1 envelope over a bounded repository:
quire assurance \
--scope . \
--module ./.ix/modules/spec-artifacts-process \
--repository agent-ix/example \
--revision 0123456789abcdef0123456789abcdef01234567 \
--expect-module spec-artifacts-process@0.1.0 \
--expect-schema spec-artifacts-process/FR@<64-lowercase-hex-digest>Documents come only from <scope>/spec; source symbols come from <scope>
with spec/ and module-declared source exclusions omitted. The module path,
repository identity, full revision, module version, and complete active-schema
digest set are explicit. A missing, extra, or mismatched premise exits non-zero
before stdout. A successful corpus may contain empty arrays; an unreadable
document remains explicit as an unknown observation with a reason.
The command performs static parsing and extraction only. It invokes no Git,
test, proof, solver, package manager, consumer, or network operation, adds no
verdict, and does not append the CLI's ordinary provenance object to the closed
upstream payload. Compact JSON is deterministic; global --pretty re-indents
the already validated compact bytes and changes whitespace only. Diagnostics
always use stderr.
Structurally validate an authored document against its archetype. The archetype
is resolved from the frontmatter type unless --archetype overrides
it. Relative document globs are resolved under --scope; in scoped mode Quire
loads modules from that scope, --scope ./.ix/modules style plugin roots, and
IX_SCHEMA_PATH. quire-rs runs the archetype's body_extraction asserts (required-section
presence, non-placeholder content, table columns/rows, list items, id patterns)
plus frontmatter-schema and per-level heading uniqueness:
quire validate --scope . "spec/**/*.md"
quire validate --scope . "spec/functional/*.md" "spec/usecase/*.md"
quire validate ./spec/functional/FR-001.md --module ./iso
quire validate ./FR-001.md --module ./iso --archetype FR
cat FR-001.md | quire validate - --module ./iso --archetype FROn success validate exits 0 with no output. On failure it exits 1 and writes
the line-numbered quire-rs diagnostics (naming the archetype, section/assert, and
reason: missing/empty/placeholder/assert/frontmatter/duplicate-heading)
to stderr — verbatim, the CLI adds no validation logic of its own.
Every document also satisfies the base concept contract before its archetype
runs: type is required and non-empty (the OKF discriminator), and the optional
OKF fields description (string) and tags (string array) are type-checked when
present.
--okf reads a foreign OKF bundle directory under a permissive posture for
portability. type is still required and non-empty, but unknown types, broken
ix:// links, and index.md completeness gaps (every sibling artifact must be
listed; the bundle-root index.md must carry okf_version) are reported as
warnings (exit 0) rather than hard errors. An untyped document is still a
hard error.
quire validate --okf path/to/bundle --module ./iso
quire validate --okf --scope path/to/repo # bundle root is path/to/repo/specWith no positional bundle the root is <scope>/spec, not --scope itself
(quire-rs CR-045 two roots): the corpus is walked from spec/ while the
module's path-bound declarations keep resolving against the scope. A --scope
with no spec/ directory is an error, never a silent repository-wide crawl —
pass the bundle as the positional argument when it is self-contained.
The two forms resolve a module's path-bound declarations differently on
purpose: --scope keeps them repository-relative, while a positional bundle
is treated as self-contained and resolves them against itself. Use --scope
when the module declares paths like document: spec/tests.md.
Without --okf, bundle directories validated via --scope "spec/**/*.md" keep
the strict per-file posture (archetype conformance, resolvable references,
complete indexes are all hard requirements).
Emit the archetype input contract — the frontmatter JSON Schema plus the
body_extraction asserts (required headings, table columns, id-patterns) that
validate enforces — as deterministic JSON. This is the same contract an
authoring agent fills; there is no template-variable list (templates were
removed):
quire schema FR --module ./iso
quire --pretty schema FR --module ./isoUnknown archetypes exit 1 with UnknownArchetype on stderr.
This repository ships Codex-style agent skills under skills/. They are
intended to be packaged with or installed from quire-cli so agents can use
the CLI consistently without relearning command patterns.
Available skills:
| Skill | Slash-style name | Purpose |
|---|---|---|
explore-markdown |
/explore-markdown |
Outline Markdown and fetch targeted sections with parse and lookup. |
write-markdown |
/write-markdown |
Author Markdown artifacts against an archetype's input contract via schema + validate. |
validate-markdown |
/validate-markdown |
Check authored Markdown structure with validate, parse, and lookup. |
link-markdown |
/link-markdown |
Inspect relationships, ix:// links, and blast radius with extract. |
Each skill has:
skills/<name>/SKILL.md
skills/<name>/agents/openai.yaml
When adding a new shipped skill, keep it general, command-oriented, and domain-neutral. Domain review guidance belongs in domain-specific skills, not here.
Validate skills with:
python3 path/to/quick_validate.py skills/explore-markdown
python3 path/to/quick_validate.py skills/write-markdown
python3 path/to/quick_validate.py skills/validate-markdown
python3 path/to/quick_validate.py skills/link-markdownPath safety is part of the CLI contract:
--module,--out,--content, and positional document paths reject..traversal where the command applies path safety.- Symlink escapes are rejected.
- A positional
-reads from stdin by design (path-safety-exempt). - The CLI makes no network calls in normal operation; tests audit this with
strace.
make build # release build
make test # cargo test, including integration tests and audits
make lint # clippy -D warnings
make fmt-check # rustfmt --check
make deny # cargo deny check licenses
make deny-bans # cargo deny check bans
make audit-unsafe # every unsafe block carries a // SAFETY: comment
make audit-thin-boundary # src/ stays a thin wrapper over quire-rs
make refresh-fixtures # re-sync tests/fixtures/iso from ../quire-rs
make ci # local CI gauntletThe release binary is audited to link only baseline system libraries on
Linux. See tests/audit_ldd.rs.
Requirements live in spec/; the implementation plan and task index live in
plan/. The traceability matrix in spec/tests.md maps acceptance criteria
to integration tests, benchmarks, or static audits.
AGPL-3.0-or-later
