Skip to main content

docs-cli

A prescriptive, lightweight CLI (docs) for managing trees of structured markdown documentation.

Treats each Markdown file as a small, self-describing record. A short metadata block under the H1 captures the doc's status, role, and relationships; the docs CLI uses that metadata to derive an index, archive completed work, validate consistency, and answer queries — without forcing you to maintain cross-references by hand.

Why

Documentation directories rot. Hand-maintained INDEX.md files drift from reality. Descriptions get duplicated and lose sync. Plans pile up alongside completed work with no clear lifecycle.

docs makes each file self-describing and treats the index as a derived view. The doc itself is the source of truth; the index is generated.

Convention at a glance

# Title

Lifecycle: active
Role: spec
Project: docs
Updated: 2026-05-23

Related:
- pairs-with: convention.md
- implements: charter.md

## …
  • Plain Label: value lines under the H1; a bare-label list group (like Related:) may follow after a blank line.
  • Lifecycle and Role come from controlled vocabularies (extensible per-project, additive only).
  • Related: is followed by bullets in <verb>: <path> form.
  • No YAML frontmatter, no parser dependency, readable in any Markdown viewer.

See docs/convention.md for the full spec.

Commands

docs new <role> <slug> [--project NAME] [--body-from PATH|-]
                                          Scaffold a doc with the right metadata; --body-from writes the body atomically.
docs index [DIR] [--exclude PATTERN]      Regenerate INDEX.md from metadata in DIR.
docs archive <file> [--reason "…"] [--cascade-only GLOB] [--cascade-dry-run] [--json]
                                          Archive: edit Lifecycle, record Archived:, move to archive/<date>/,
                                          rebase stale body links, refresh index. Related docs need an explicit scope.
docs mv <old> <new> [--dry-run] [--json]  Move + rewrite Related: references AND stale body links across the tree.
docs relate add|remove SOURCE VERB TARGET Add or remove a reciprocal relationship pair across both endpoints.
docs list [filters] [--json] [--exclude PATTERN]
                                          Query view of the tree.
docs check [DIR] [--exclude PATTERN]      Validate metadata, refs, status/location drift, reciprocal edges,
                                          body links, and archive-date drift.
docs touch <file> [--check]               Bump Updated: to today; --check re-validates the tree afterwards.
docs stamp <file>                         Stamp a metadata block onto a file that was written by hand.
docs project rename <old> <new>           Rename a project across the tree.
docs project set <file> <name>            Reassign a single doc to another project.
docs migrate <dir> [--apply] [--summary] [--only ambiguous] [--exclude PATTERN]
                                          Adopt a foreign Markdown directory into the convention (dry-run by default).
docs install-skill [--dest DIR]           Materialise the bundled agent skill onto this host.

See docs/cli.md for full surface and exit codes.

What 2.0 enforces

The 2.0 train turned four classes of silent documentation rot into hard errors, and stopped the tool from causing two of them itself:

  • Reciprocal edges. precedes/follows, depends-on/required-by and blocks/blocked-by must point both ways. A one-sided edge is a missing-inverse error; docs relate add|remove writes or removes both ends in one call.
  • Body links. Local Markdown links in prose are validated. A destination that does not exist is broken-body-link; one that escapes the tree is outside-root-body-link.
  • Move-safe rewrites. docs mv and docs archive rebase the body-link destinations a move makes stale — not just Related: references — so an archive or rename no longer leaves a tree that fails docs check. Both verbs build and validate the whole plan before the first byte moves.
  • Archive dates. docs archive records an Archived: field on every document it moves, and docs check reports archive-date-drift when a document's recorded date disagrees with the dated directory it sits in. docs mv refuses a move between two different dated archive directories.
  • Explicit archive scope. Bare --cascade is retired: it refuses and writes nothing. Use --cascade-dry-run to preview, then --cascade-only GLOB to write an explicit scope.

Upgrading a 1.x tree surfaces pre-existing damage as errors on the first docs check. That is intentional, and the CHANGELOG's Upgrading from 1.x section carries the repair recipe for each rule.

Install

pip install docs-cli                      # lands `docs` on PATH
docs install-skill [--dest DIR]           # materialise the bundled agent skill (default: ~/.claude/skills/docs/)

Requires Python 3.11+ (for stdlib tomllib). No third-party runtime dependencies.

Adopting an existing tree

Have a directory of foreign Markdown specs? docs install-skill materialises an agent skill that walks an agent through docs migrate <dir> → triage → docs migrate --apply. See docs/archive/2026-05-25/m8-adoption-workflow.md for the full agent-driveable workflow, the bundled adoption playbook for the procedural deep-dive, or run docs migrate <dir> directly for a dry-run plan.

For development:

git clone https://github.com/ArtRichards/docs-cli.git ~/opt/docs-cli
cd ~/opt/docs-cli
python3 -m venv .venv
.venv/bin/pip install -e ".[dev]"
.venv/bin/python -m pytest -q

Status

Released on PyPI — pip install docs-cli. The on-disk Markdown convention is stable and backward-compatible: 2.0 adds the Archived: field but never rewrites existing files on upgrade, and the only breaking keyword change to date remains the one-time Status: → Lifecycle: rename (no backward-compat alias). What 2.0 breaks is automation, not data — new hard docs check rules and the retired bare --cascade.

For current state, see the canonical sources — kept in sync by the tooling rather than duplicated here:

License

MIT — see LICENSE.

Metadata

Release files for docs-cli 2.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for docs-cli 2.0.0
File Size Uploaded
docs_cli-2.0.0.tar.gz 1.6 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for docs-cli 2.0.0
File Interpreter ABI Platform
docs_cli-2.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 1.8 MB

Release files / docs_cli-2.0.0.tar.gz

Download URL docs_cli-2.0.0.tar.gz
Size 1.6 MB
Tags Source
SHA-256 checksum
How to use checksums
c62f22d35067cb42a8c241e1d36e161f60ac533b33658ab41f804a2a2c862b66
BLAKE2b-256 checksum
How to use checksums
d9064f0dc6ed8ec3e58129ad89c715a60e7d8ebafbe77f9a5da54cf9d4753a80
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release files / docs_cli-2.0.0-py3-none-any.whl

Download URL docs_cli-2.0.0-py3-none-any.whl
Size 217.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bcd8aa453415dfe66868f22830fce318c7149d6642935d6167d4de9b2cdaab23
BLAKE2b-256 checksum
How to use checksums
54fde1c831f55f439dcd4a38b1661bac6acb2b2b4c6d2a701894bf3eaa464455
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release history Release notifications | RSS feed

This release

2.0.0 This release

2 release files

1.8.0

2 release files

1.6.5

2 release files

1.6.0

2 release files

1.5.0

2 release files

1.4.0

2 release files

1.3.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page