# LLM Wiki CLI
LLM Wiki CLI builds and maintains a repo-local architectural wiki for coding
agents. It scans source code into a compact structural inventory, generates
Markdown pages under a wiki directory, validates those pages against the live
codebase, and prepares or triggers wiki-sync prompts after commits. It can also
prepare an isolated, agent-driven documentation workspace from source or an
existing LLM-enriched wiki without installing instructions in the target; see
[Standalone documentation workspaces](docs/standalone-documentation.md).
The PyPI distribution is `agent-wiki-cli`. The installed console command remains
`llm-wiki`, and the Python import package remains `llm_wiki_cli`.
## What It Creates
The default wiki lives at `docs/llm_wiki/`. Its page taxonomy is defined by the
canonical wiki surface registry:
| Surface | Role | What belongs there |
|---|---|---|
| `index.md` | mixed | Registry-backed landing page with page-kind counts and navigation for generated pages. |
| `log.md` | generated / agent-appended | Append-only architectural change log. |
| `entities/` | semantic | Class, struct, interface, and type pages with generated structure and relationship summaries. |
| `modules/` | semantic | Source-file pages with generated imports, symbols, and local dependency maps. |
| `workflows/` | mixed | Detected or manually maintained cross-module flow pages. |
| `guides/` | semantic | Agent-authored navigation, operator, and contributor guides. |
| `flows/` | mixed | User-flow pages, one per detected entry point, with bounded generated Mermaid call and data-flow diagrams. |
| `infrastructure/` | mixed | Dockerfile, Compose, GitHub Actions, Kubernetes, and targeted runtime/config YAML pages. |
| `api-contracts.md` | mixed | Optional production HTTP contract inventory generated from static FastAPI declarations or an exported OpenAPI document; `## Notes` is semantic. |
| `dependencies.md` | mixed | Optional internal and external dependency architecture page. |
| `load-order.md` | mixed | Optional load-order, cycle, and startup-caveat architecture page. |
The wiki also contains `.llm-wiki-manifest.json`, the operational source,
evidence, and artifact-commit state used by incremental sync and strict
linting; `.llm-wiki-surface.json`, the deterministic machine-readable index of
canonical pages, source mappings, surface counts, flow metadata,
dependency-page presence, and internal wiki links; and the experimental
`.llm-wiki-knowledge.json`, a deterministic evidence-aware projection of those
canonical pages. Manifest v5 is the current writer format. All three JSON
artifacts are CLI-owned generated state and must not be edited by hand; the
manifest commits the surface and knowledge projections as one snapshot. The
experimental knowledge projection is evidence, not an editable authority. Its
observation-versus-freshness model,
availability states, strict-lint policy, context filters, API/MCP envelopes,
bounds, and no-execution rules are documented in
[Native knowledge reads][native-knowledge]. Projects that opt into durable
identity also version `.llm-wiki-governance.json`, the narrow authority for
stable UIDs, aliases, lifecycle events, and scoped human reviews. Generated
knowledge and manifest data only commit and project that ledger. Disposable
machine-check results live separately in `.llm-wiki-verification.json`. The
detailed authority,
load-state, commit, and compatibility decisions are recorded in
[ADR-0001](docs/architecture/0001-native-knowledge-authority-state-and-rollout.md).
Generated Mermaid diagrams, including bounded call-sequence, data-flow,
dependency, and relationship diagrams when present, plus generated tables,
links, headings, canonical filenames, and machine-readable artifacts are
CLI-owned and may be regenerated by `sync`. Agents should edit semantic prose
instead:
descriptions, workflow notes, guide prose, `flows/*` `## Behavior` sections,
architecture-page `## Notes` sections, custom `index.md` notes, and concise
`log.md` summaries.
Full bootstrap renders entity `## Relationships` sections with bounded Mermaid
diagrams and compact reference tables when relationship metadata exists. When
dependency analysis is enabled, module pages also get a generated
`## Local dependency map` section with a bounded Mermaid mini-map, neighbor
tables, cycle highlighting, external package counts, and concise empty-state
notes instead of blank diagram fences. Haskell declaration entity relationship
summaries use `Module | Declaration kind` instead of Python-oriented methods
and attributes columns.
Registry-backed surfaces are distributed through the available query and mirror
interfaces. The MCP server exposes read-only resources, search, and status
counts for the same surface kinds. The supported Python API exposes source
inventory, context payloads, registry-backed page metadata, and graph queries
through `extract_source(...)`, `build_context(...)`, `list_wiki_pages(...)`, and
the documentation query wrappers. `llm-wiki obsidian export` mirrors the canonical
Markdown wiki for Obsidian, and `llm-wiki site export|check` mirrors and validates
plain, MkDocs-compatible, or Docusaurus-compatible Markdown output without
invoking external builders. Static-site output is a derived artifact; it must
not become a second editable source of truth.
After normal Python signature binding succeeds, all functions exported by
`llm_wiki_cli.api` report operational and validation failures through
`LlmWikiApiError` and one of three stable subclasses:
| Exception | Failure mapping |
|---|---|
| `InvalidRequestError` | Invalid arguments, path policy, query/model policy, authentication input, or submitted schema |
| `WorkspaceStateError` | Extraction/bootstrap failure, missing or inaccessible ordinary source/input/documentation workspace storage, invalid lifecycle transition, or other unusable operational state |
| `ArtifactIntegrityError` | Missing or corrupt protected calibration/controller state, corrupt persisted documentation state, or adopted-input integrity failure, including invalid stored schemas, hash/metadata/native-artifact mismatch, and ambiguous protected-state recovery |
The original `PathPolicyError` name remains an alias for
`InvalidRequestError`; `ExtractionError` and `BootstrapError` remain aliases
for `WorkspaceStateError`. The original internal exception is available
through `__cause__`.
The package has a small required Python runtime footprint. `PyYAML>=6` parses
user-supplied OpenAPI YAML, and Python versions older than 3.11 use `tomli` for
TOML. FastAPI, Pydantic, and the target application are not runtime
dependencies and are never imported for contract extraction. Optional language
features use external tools when they are available on `PATH`.
## Supported Inputs
| Area | Implementation | Runtime requirement |
|---|---|---|
| Python | stdlib `ast` | Python 3.10+ |
| TypeScript / JavaScript / TSX / JSX | bundled Node script using `ts-morph` | prepared Node.js dependencies |
| Go | bundled Go extractor using `go/ast` | prepared helper binary |
| Rust | bundled Rust extractor using `syn` | prepared helper binary |
| Haskell | bundled GHC parser helper for syntax-only inventory | prepared helper binary |
| Docker / Compose | built-in parsers | none |
| Runtime/config YAML | targeted built-in parsers | none |
| OpenAPI 3.0/3.1 JSON / YAML | stdlib `json` / PyYAML safe loader | `PyYAML>=6` (installed with the package) |
| MCP server | official Python MCP SDK | `agent-wiki-cli[mcp]`, Python 3.10+ |
TypeScript/JavaScript, Go, Rust, and Haskell helper setup is explicit; prepare
helper dependencies and binaries with `llm-wiki prepare-extractors`. Lint, CI,
and extract never run `npm install`, `go build`, `go run`, `cargo build`,
`cargo run`, or `ghc` automatically.
Source discovery honors `.gitignore` before extractors run. Unescaped trailing
ASCII spaces in ignore entries are ignored, while `\ ` preserves a literal
final space. A root, unanchored `lib/` rule is treated as a generic build-output
pattern for TypeScript projects, so `.ts`, `.tsx`, `.js`, and `.jsx` files under
`src/lib/` remain first-party source; top-level `lib/`, excluded
dependency/build directories, and explicit nested `.gitignore` rules still stay
excluded. Generated agent
worktree copies such as `.claude/worktrees/**` are excluded from default
snapshots; pass an exact `--paths` entry if you intentionally want to inspect
one file there.
Haskell `.hs` and `.lhs` files are discovered as supported built-in source
files. Normal CLI extraction invokes the prepared Haskell helper to emit
syntax-only inventory for matching files. The helper does not typecheck the
target project or start Haskell Language Server. Haskell dependency
reconciliation is static: Cabal manifests are parsed without running Cabal,
Stack `extra-deps` and Nix package hints are advisory optional metadata, and
unknown imports are ignored rather than guessed. Haskell internal dependency
edges resolve through declared module names, so nested package roots can link
imports such as `HLSAnalysis.API` to the matching source entry.
Generated Haskell module pages display declared module names, import
qualification and aliases, top-level signatures and values, and type-oriented
declarations such as data, newtype, type alias, type class, and instance
entries.
GHC 9.6.x is the supported Haskell helper toolchain for this release. Newer GHC
9.x releases are best-effort, and helper preparation fails clearly when GHC
version output is malformed or older than 9.6.
## Agent Support
| Agent | Schema file | Sync mode |
|---|---|---|
| `claude` | `CLAUDE.md` | prompt hook; optional manual CLI trigger |
| `aider` | `.aider.conf.yml` | prompt hook; optional manual CLI trigger |
| `opencode` | `.opencode/instructions.md` | prompt hook; optional manual CLI trigger |
| `copilot` | `.github/copilot-instructions.md` | IDE prompt |
| `cursor` | `.cursorrules` | IDE prompt |
| `generic` | `AGENTS.md` | IDE prompt |
Installed hooks generate a reviewed prompt file for all agents. The explicit
`trigger-agent` command can still delegate to a CLI agent; for Claude, this uses
`claude -p` and leaves permission decisions to Claude's normal permission model.
Run manual CLI triggers only in repositories and execution environments you
trust.
The package also bundles agent skills — reusable `SKILL.md` workflow
directories (Claude Code-compatible) that encode the documentation and
analysis loops this tool is designed around. See [`skills`](#skills) in the
command reference.
### For autonomous agents
Agents that do not have a dedicated schema target can use the generic
instruction surface:
llm-wiki init --agent generic
llm-wiki skills export --dest exported-skills
`init --agent generic` writes `AGENTS.md` with the docs workflow order and
hard rules. `skills export --dest` writes the bundled skill directories into a
location any shell-capable autonomous agent can read, including
`usage-examples` for attaching validated screenshots or recordings.
## Installation
From PyPI:
pip install agent-wiki-cli
With MCP server support:
pip install "agent-wiki-cli[mcp]"
From source:
git clone https://github.com/Denissvgn/python-wiki-llm.git
cd python-wiki-llm
python3 -m venv .venv
.venv/bin/pip install -e ".[dev]"
The following extras are accepted for compatibility with documented workflows,
but they do not install external TypeScript/JavaScript, Go, Rust, or Haskell
toolchains:
pip install "agent-wiki-cli[typescript,go,rust]"
Uninstall the Python package with:
pip uninstall agent-wiki-cli
## Quick Start
Initialize the wiki structure and the agent instruction file:
llm-wiki init --agent claude
Generate the initial wiki from an existing codebase:
llm-wiki bootstrap --src-dir . --wiki-dir docs/llm_wiki
Validate the wiki:
llm-wiki lint --wiki-dir docs/llm_wiki --src-dir .
Install a post-commit hook:
llm-wiki install-hook
`init` writes the selected agent and instruction preferences to
`.git/.llm-wiki-agent` when the project is a Git repo. Outside Git, it falls
back to `/.llm-wiki-agent`. Tool-issue reporting guidance is omitted
by default; opt in when you want agents to create local bug-report files:
llm-wiki init --agent claude --issue-reporting
This only adds guidance to the generated agent instruction block. It does not
upload reports, submit issues, or enable telemetry.
### Standalone human documentation
Create a separate documentation workspace without changing the source
project's agent configuration:
llm-wiki docs prepare \
--workspace ./project-docs \
--baseline bootstrap-source \
--src-dir /path/to/project \
--allow-external-src \
--site-name "Project" \
--audience user,operator
llm-wiki docs packet \
--workspace ./project-docs \
--stage wiki-enrichment \
--format markdown
The deterministic core builds evidence and provider-neutral packets; the host
invokes an agent and returns its versioned result. The core calls no model,
installs no target instructions, and performs no deployment. It can instead
adopt a wiki already enriched by `llm-wiki` agent workflows. The complete
source/adoption, agent-result, low-cost model-routing, verification, and resume
workflow is in the
[standalone documentation guide](docs/standalone-documentation.md).
The workspace and any helper-cache or capture root must not overlap the source
project or adopted input wiki. The example assumes `./project-docs` is a
parent/sibling workspace, not a directory inside `/path/to/project`.
Protected calibration is a separate sibling lifecycle. It freezes evidence
from exactly two matching documentation controls in a new controller root and
does not alter their worklists, priorities, or resume state. The qualifying
local profile runs digest-pinned workers with no container network and records
live denial probes before any intake packet can be issued. The lifecycle stops
at a frozen pre-labeling intake; it does not create labels, candidate policy,
publication approval, or a new default.
## Automation
`llm-wiki install-hook` installs a `post-commit` hook that generates
`.git/llm-wiki-prompt.txt` with `llm-wiki generate-prompt` and prints a reminder
to paste that prompt into your agent chat. Generated hooks never launch CLI
agents automatically.
For advanced trusted workflows, `trigger-agent` remains available as an explicit
manual command:
llm-wiki trigger-agent --agent
The trigger command:
- takes `git diff HEAD~1..HEAD`;
- skips empty diffs and oversized diffs unless `--force` is used;
- uses a lock file to prevent concurrent syncs;
- opens a circuit breaker after repeated failures;
- builds deep source inventory and call-graph context;
- filters credential-like values from the generated prompt on a best-effort
basis, then writes `.git/llm-wiki-prompt.txt` with owner-only permissions
where supported;
- invokes the selected agent with a prompt that asks it to update, lint, and commit wiki changes.
Useful trigger options:
llm-wiki trigger-agent --agent claude --timeout 600 --max-diff-lines 2000
llm-wiki trigger-agent --agent claude --max-prompt-bytes 2000000
llm-wiki trigger-agent --agent claude --force
llm-wiki trigger-agent --reset-breaker
Set `LLM_WIKI_LOCK_WAIT` to a non-negative number of seconds when a trusted
automation runner should wait briefly for another sync to release the lock.
The circuit breaker permits one automatic recovery attempt after 3600 seconds
by default; set `LLM_WIKI_BREAKER_TTL_SECONDS` to another non-negative duration,
or to `0` to require `--reset-breaker`.
Optional strict pre-commit validation:
llm-wiki install-hook --enable-validation
Use `--force` when you intentionally want to replace an existing unrelated hook:
llm-wiki install-hook --force
### CI gate
The bundled composite GitHub Action runs the knowledge health check on a pull
request, writes its structured results as a job-summary table, and applies a
configurable failure threshold:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
- uses: Denissvgn/python-wiki-llm/integrations/github-action@main
with:
wiki-dir: docs/llm_wiki
src-dir: .
strict: "true"
fail-on: unhealthy
Use `fail-on: unhealthy` to allow degraded-but-usable knowledge while blocking
mixed snapshots, invalid governance, confirmed stale concepts, and invalid
verification receipts. Use `fail-on: degraded` when any degraded result must
block the job. `strict: "true"` also classifies indeterminate or nonsemantic
source drift as unhealthy. For a protected production workflow, replace the
branch reference with an immutable released commit.
The action installs `agent-wiki-cli` from the same action checkout, so pinning
the action reference also binds the CLI implementation. It invokes
`llm-wiki doctor --format json` and reads only the complete, versioned
`llm-wiki-doctor/v1` object. It rejects a report when its declared exit code
does not match the doctor process exit captured by the runner, and it does not
scrape human output. Within that schema major, required fields and documented
state values remain strict while additive object fields are ignored. A wiki
that has not been initialized is reported as `absent` and fails either
threshold.
## Command Reference
### Resource-aware execution
In an interactive IDE or whenever host capacity is unknown, run one heavy gate
at a time. Heavy gates include `context`, full tests, coverage, builds, browser
suites, `sync`, `lint`, and `ci-check`. The supervising agent owns that
schedule; subagents may inspect bounded files and diffs, but should not launch
heavy gates unless explicitly assigned.
Use `--jobs 1` for interactive source scans. `--jobs auto` remains an uncapped
opt-in for an isolated terminal or a controlled CI runner with reserved
capacity; do not combine it with nested heavy-gate fan-out. If ENOSPC, inotify,
file-descriptor, severe swapping, or editor-responsiveness failures occur, stop
launching work and do not retry the same burst. Recover capacity first, then
attempt at most one manual retry with `--jobs 1`; unfinished gates remain
inconclusive. Watcher-limit symptoms are host/IDE resource evidence, not proof
that `llm-wiki` leaked a watcher.
Before extraction, `sync`, `lint`, `ci-check`, and `context` write one flushed
plan line to stderr without contaminating stdout, for example:
Extractor plan: requested=auto resolved=20 eligible_parallel=2 effective_workers=2 parallel=python,typescript sequential=- cache_elided=-
### `init`
Scaffold the wiki structure and agent constraint file.
llm-wiki init --agent claude
llm-wiki init --agent copilot --wiki-dir .wiki
llm-wiki init --agent cursor --no-quality-hints
llm-wiki init --agent generic --issue-reporting
Supported agents are `claude`, `aider`, `opencode`, `copilot`, `cursor`, and
`generic`. `--issue-reporting` includes instructions that ask agents to record
`llm-wiki` tool failures under the local `llm-wiki-issues/` directory. The
instructions are off by default; use `--no-issue-reporting` to explicitly omit
them when refreshing an existing initialization. On a refresh, omitting
`--agent` reuses the stored agent; a project with no stored selection defaults
to `generic`.
### `bootstrap`
Generate the initial full wiki for an existing project.
llm-wiki bootstrap --src-dir . --wiki-dir docs/llm_wiki
llm-wiki bootstrap --depth shallow
llm-wiki bootstrap --skip-workflows
llm-wiki bootstrap --skip-flows
llm-wiki bootstrap --skip-data-flow
llm-wiki bootstrap --skip-dependencies
llm-wiki bootstrap --api-contracts
llm-wiki bootstrap --api-contracts --openapi-file openapi.yaml
llm-wiki bootstrap --include-tests go
llm-wiki bootstrap --helper-cache-dir .cache/llm-wiki-helpers
llm-wiki bootstrap --format json --source-adapter
`bootstrap` is first-use only. It accepts a nonexistent or empty target and the
exact untouched scaffold created by `llm-wiki init`. If the target already
contains a manifest, legacy or partial pages, custom prose, governance, or
verification state, it stops before source extraction or target writes. Use
`sync --jobs 1` for a maintained wiki and `migrate --dry-run` before migrating an
older or partial layout. The retained `--overwrite` compatibility option always
fails; neither that option nor a request phrased as “re-bootstrap” authorizes
replacement.
`bootstrap` writes entity, module, workflow, flow, infrastructure, index, log,
dependency architecture, and manifest files. User-flow pages under `flows/` are
generated from detected entry points with a call sequence, generated static
`## Data flow` section, boundary-effects table, and editable `## Behavior`; use
`--skip-flows` to omit them or `--skip-data-flow` to keep flow pages without the
generated data-flow section. Large generated call-sequence diagrams are capped
to the first 30 interactions and include an omitted-interaction note so Mermaid
output stays readable on large repositories.
Dependency architecture pages are generated as `dependencies.md` and
`load-order.md`; use `--skip-dependencies` for projects that do not want those
pages or lint diagnostics. Generated `index.md` is a registry-backed landing
page with a surface overview table, per-surface counts, grouped user-flow
entries, optional dependency architecture links, and a direct log link.
`--api-contracts` adds the optional `api-contracts.md` production HTTP
inventory and generated API-contract sections on matching HTTP flow pages.
Passing `--openapi-file` implies `--api-contracts`; the supplied OpenAPI 3.0 or
3.1 JSON/YAML document is authoritative for wire fields, while syntax-only
source analysis contributes handler, module, entity, and flow links. The target
application is never imported or executed.
`--depth full` is the default and includes
docstrings, imports, attributes, method signatures, generated relationship
sections, bounded per-module dependency mini-map summaries, and diagram data
where extractors provide it. Haskell module pages render declared module names,
qualified imports, aliases, signatures, values, and type declarations using the
same generated module/entity surfaces as other languages. Haskell declaration
entity relationship summaries show the declaration kind rather than methods and
attributes columns. Generated Mermaid diagrams and generated structure are
refreshed by the CLI; edit the semantic sections instead. Use
`--source-adapter` when callers need bootstrap to write only under `--wiki-dir`;
this skips agent constraint-file updates outside the generated wiki directory.
Use `--format json` to emit a machine-readable summary with created, updated,
and skipped files plus source counts and the manifest path.
Go `_test.go` files are excluded by default; pass `--include-tests go` when
behavior-spec or integration-test modules should be documented.
Use `--helper-cache-dir PATH` when prepared Go/Rust/Haskell helpers live in a
separate cache from the source repository.
### `sync`
Incrementally regenerate only pages whose source files changed since the last
manifest.
llm-wiki sync --src-dir . --wiki-dir docs/llm_wiki
llm-wiki sync --jobs 1 --cache-stats --src-dir . --wiki-dir docs/llm_wiki
llm-wiki sync --cache-dir .cache/llm-wiki-inventory --helper-cache-dir .cache/llm-wiki-helpers
llm-wiki sync --include-tests go --src-dir . --wiki-dir docs/llm_wiki
llm-wiki sync --src-dir . --wiki-dir docs/llm_wiki --dry-run
llm-wiki sync --initialize-surfaces flows,dependencies --flow-category http --exclude-tests --dry-run
llm-wiki sync --initialize-surfaces api-contracts --openapi-file openapi.yaml --dry-run
llm-wiki sync --src-dir /path/to/repo --wiki-dir docs/llm_wiki --allow-external-src
If an older wiki has `index.md` but no manifest, `sync` seeds
`.llm-wiki-manifest.json` without modifying pages. If neither a manifest nor an
existing wiki is present, run `bootstrap` first. Sync uses the same safe
persistent inventory cache as lint when a git directory is available. Use
`--no-cache`, `--rebuild-cache`, `--cache-dir PATH`, and `--cache-stats` to
control or inspect inventory cache behavior. Use `--helper-cache-dir PATH` to
point Go/Rust/Haskell extraction at prepared helpers in a separate cache. Use
The interactive default is `--jobs 1`. Use `--jobs N` or `--jobs auto` to opt
into parallel extraction for built-in languages and plugin extractors whose
manifests set `"parallel_safe": true`; reserve `auto` for an isolated terminal
or controlled CI runner with known capacity.
Sync repairs
manifests with invalid source hashes without touching pages, and stops unusually
broad diffs unless `--force` is used.
`--initialize-surfaces` enters a surface-only backfill mode for `flows`,
`dependencies`, and/or `api-contracts`: ordinary entity/module source changes
are reported but deferred. `--flow-category` is repeatable, `--exclude-tests`
uses a cross-platform test-path classifier for the selected flow/dependency
analysis. `--dry-run` previews ordinary source changes or optional-surface
initialization, including the surface/knowledge/manifest artifact actions,
without writing the wiki, manifest, log, index, projections, or cache.
Selected flow categories and test filtering are persisted in manifest v5 so a
later ordinary sync cannot silently expand an HTTP-only backfill to every flow.
Pass `--include-tests go` to include Go `_test.go` files in the synced
inventory and generated module pages; the default remains production Go source
only.
For trusted source trees outside the runner workspace, pass
`--allow-external-src`; same-owner or system-administrator-owned symlinks are
disclosed with a warning, symlinks owned by another user are rejected, and
`--wiki-dir` remains constrained to the current project root.
`sync` is deterministic: it updates AST/docstring-based page skeletons and does
not call an LLM. In agent workflows, treat sync as the first step, then inspect
created or updated pages and replace generic `_Auto-generated from ..._`,
copied-docstring-only, or knowable `—` placeholders with project-specific
semantic explanations.
For entity and module pages, `sync` also keeps generated `## Relationships` and
`## Local dependency map` sections current when another changed source file
alters relationship or dependency data, including Haskell imports resolved by
declared module name. Those generated sections are replaced without rewriting
human-authored semantic descriptions or table descriptions.
Older module pages that do not already have a local dependency map are left in
their existing shape.
When `dependencies.md` or `load-order.md` already exists, `sync` also
regenerates those architecture pages from the current dependency inventory and
keeps their human-authored `## Notes` sections unless `--no-preserve-semantic`
is set. Those notes are the agent's responsibility: document intentional cycles,
dynamic imports, side effects, and notable dependency rationale. Projects
bootstrapped with `--skip-dependencies`, or older wikis without those pages,
stay untouched.
When flow pages already exist, `sync` also refreshes generated call-sequence and
`## Data flow` content from the current inventory while preserving the
human-authored `## Behavior` section by default.
When `api-contracts.md` exists, sync refreshes its generated operation inventory
and matching flow-page contract sections while preserving `## Notes` and
`## Behavior`. A bootstrap/sync OpenAPI input is stored as a source-relative
path and hash; a specification-only change refreshes contracts even when source
files are unchanged. Use `--clear-openapi-file` to return deliberately to
static contract authority.
When `sync` rebuilds `index.md`, the generated landing-page overview and
per-surface link sections are replaced from the live registry and inventory.
With semantic preservation enabled, old custom top-level index sections are
kept at the end, and old free-form intro text is migrated under `## Notes`.
Use `--no-preserve-semantic` to regenerate a clean index without those custom
sections.
### `extract`
Print source inventory as JSON. All registered extractors run; missing optional
prepared helpers are skipped when there are no matching source files.
llm-wiki extract --src-dir .
llm-wiki extract --src-dir . --changed
llm-wiki extract --src-dir . --summary
llm-wiki extract --src-dir . --deep
llm-wiki extract --src-dir . --deep --openapi-file openapi.json
llm-wiki extract --src-dir . --paths src/foo.py src/bar.ts
llm-wiki extract --src-dir . --package llm_wiki_cli
llm-wiki extract --src-dir . --include-empty
llm-wiki extract --src-dir . --include-tests go
llm-wiki extract --src-dir . --summary --output sources/code.json --read-only
llm-wiki extract --src-dir /path/to/repo --allow-external-src --summary
The JSON output includes `schema_version: "llm-wiki-extract/v1"` plus
`inventory` and optional `docker` and `unsupported_sources` objects.
Go `_test.go` files are omitted unless `--include-tests go` is supplied; Python
test files remain part of normal Python extraction.
JavaScript `.js` and `.jsx` files are handled by the TypeScript extractor
family and use `language: "javascript"` in inventory output. Prepare the same
helper with `llm-wiki prepare-extractors --language typescript`.
Plain `.js` files include named top-level function declarations in the
`functions` list even when they are local CommonJS helpers. Those functions are
rendered on module pages; JavaScript function declarations do not create entity
pages, which remain class/type/declaration oriented. Raw Node
`http.createServer` and `https.createServer` calls in JavaScript create HTTP
entry points for `extract --deep`, flow pages, and data-flow summaries. Named
handler arguments resolve to the handler symbol when available; inline
callbacks fall back to the assigned server variable such as `server`. Lint and
CI keep the non-blocking `javascript_flow_unsupported` diagnostic only for
`createServer` patterns outside the supported raw Node `http`/`https` shape.
`unsupported_sources` reports known source extensions that are visible in the
tree but not handled by an active extractor. Haskell is registered as a
built-in language, so `.hs` and `.lhs` files no longer appear in this advisory
block. When Haskell files are present, extraction requires a prepared helper and
reports a clear `prepare-extractors --language haskell` message if it is
missing. Haskell internal dependency edges resolve through declared module
names from inventory entries rather than filepath stems.
Extractor helper processes use a 120-second runtime timeout by default. Set
`LLM_WIKI_EXTRACTOR_TIMEOUT` to an integer number of seconds (minimum `1`) for
larger repositories.
Haskell file entries are additive under `llm-wiki-extract/v1`. A Haskell entry
uses `language: "haskell"`, `imports`, `classes`, and `functions`, with `module`
present when the source declares one. Import records use `module`, `qualified`,
`alias`, and `line`. The `classes` bucket stores type-oriented declarations with
`kind` values such as `data`, `newtype`, `type`, `class`, and `instance`.
The `functions` bucket stores top-level signatures, functions, and values with
`kind` values such as `signature`, `function`, and `value`; signature entries
may include `signature`. Haskell-specific fields such as `language_pragmas`,
`exports`, and `deriving` are optional best-effort metadata and consumers must
tolerate their absence.
The Haskell helper emits syntax-only inventory without typechecking the target
project and does not start Haskell Language Server. Haskell dependency
reconciliation reads `*.cabal` `build-depends` statically, scopes nested Cabal
packages by nearest manifest directory, treats library/executable/common
dependencies as required, and treats test-suite, benchmark, setup, Stack
`extra-deps`, and Nix hints as optional.
With `--deep`, Python function entries may carry optional `data_effects` blocks
(inputs, selected global/attribute reads, writes, returns, and boundary effects
such as filesystem, environment, process, network, output, and logging calls)
and optional `calls` lists (in-body call targets, optionally with compact `args`
and `kwargs` expression summaries). Function `params` include reconstructable
parameter kinds for positional-only, positional-or-keyword, variadic,
keyword-only, and variadic-keyword declarations. Python model/type inventory
also carries optional required/nullable/default/factory, alias, constraint,
description/example, `Annotated`, validator/config, enum-member, literal, and
type-alias metadata without importing Pydantic or application modules.
The payload also gains an optional top-level
`entrypoints` array (detected user-reachable entry points: `{id, category, file,
symbol, label}`), a `data_flows` list for detected user flows, plus a top-level
`dependencies` object with internal `edges`, `cycles`, per-language external
dependency reconciliation, optional resolved-version metadata, and `load_order`.
Version metadata is best-effort and appears only when a supported lockfile or
exact pin is available: Go `go.sum`, Rust `Cargo.lock`, Python `poetry.lock`
and exact `requirements*.txt` pins, npm `package-lock.json`, and narrowly
supported `pnpm-lock.yaml` package entries. Haskell lockfile pinning is
intentionally out of scope for this metadata. When `--deep` is combined with
`--changed`, `--paths`, `--package`, or `--summary`, `data_flows` and
`dependencies` describe the emitted inventory before summary collapse. Inventory
keys are POSIX paths relative to `--src-dir`, never absolute paths. The v1
contract permits additive fields; incompatible shape changes require a new
schema version. The data-flow fields are therefore optional additions under
`llm-wiki-extract/v1`, not a schema bump.
Deep Python extraction also emits optional per-file `frameworks.fastapi`
declarations and a top-level `api_contracts` object. Static uncertainty is
reported through `unknowns` and diagnostics; test-source and
`include_in_schema=False` operations are excluded from the production operation
inventory by default. With `--openapi-file`, OpenAPI defines the operation set
and wire contract, external references are never fetched, and unmatched or
conflicting static declarations remain visible as diagnostics.
Installed `entrypoint_detector` plugin hooks also contribute to the same
`entrypoints` array in deep output. Detector failures are isolated: built-in
entry-point detection still runs, `extract` prints a warning to stderr, and the
JSON payload includes top-level `warnings` only when such diagnostics exist.
### `prepare-extractors`
Prepare TypeScript/JavaScript dependencies and cached Go/Rust/Haskell helper
binaries outside the lint/extract hot path.
llm-wiki prepare-extractors --src-dir .
llm-wiki prepare-extractors --language typescript --language go --language haskell
llm-wiki prepare-extractors --cache-dir .cache/llm-wiki-helpers
When `--language` is omitted, only helper languages detected in `--src-dir` are
prepared. Helper cache resolution follows `--cache-dir`, then
`LLM_WIKI_CACHE_DIR`, then `.git/llm-wiki-extractors/`. If Go is installed in a
nonstandard location or the `go` on `PATH` cannot run, set
`LLM_WIKI_GO=/path/to/go` before running `prepare-extractors`. If GHC is
installed in a nonstandard location, set `LLM_WIKI_GHC=/path/to/ghc` before
preparing Haskell helpers. GHC 9.6.x is the supported Haskell helper toolchain;
newer GHC 9.x releases are best-effort, and older or malformed GHC version
output fails during helper preparation.
Commands that consume prepared Go/Rust/Haskell helpers accept
`--helper-cache-dir PATH`.
This is separate from inventory-command `--cache-dir PATH`, which only controls
where `llm-wiki-inventory-cache.json` is read and written.
### `lint` and `ci-check`
Validate wiki links, orphan pages, entities, modules, workflows,
infrastructure, plugin lint rules, and team policy.
llm-wiki lint --wiki-dir docs/llm_wiki --src-dir .
llm-wiki lint --strict --wiki-dir docs/llm_wiki --src-dir .
llm-wiki lint --knowledge-drift-report --wiki-dir docs/llm_wiki --src-dir .
llm-wiki lint --profile --wiki-dir docs/llm_wiki --src-dir .
llm-wiki lint --cache-stats --wiki-dir docs/llm_wiki --src-dir .
llm-wiki lint --cache-dir .cache/llm-wiki-inventory --helper-cache-dir .cache/llm-wiki-helpers
llm-wiki lint --include-tests go --wiki-dir docs/llm_wiki --src-dir .
llm-wiki lint --jobs 1 --wiki-dir docs/llm_wiki --src-dir .
llm-wiki lint --wiki-dir docs/llm_wiki --src-dir /path/to/repo --allow-external-src
Strict mode also requires the core wiki structure and a fresh sync manifest.
For a knowledge-capable wiki, it validates the committed
surface/knowledge/manifest set, promised module/entity evidence, and live
concept freshness. Invalid or mixed projections and invalid promised evidence
are hard issues. Native freshness/drift reporting is disabled by default. Pass
`--knowledge-drift-report` to include `unknown`, `source-changed`,
`source-missing`, `basis-incompatible`, `nonsemantic-source-change`, and
inability to construct a live comparison as nonblocking warning diagnostics;
on `lint` the flag also enables strict mode. There is no blocking native-drift
mode. Required wiki structure, sync-manifest consistency,
projection/evidence integrity, governance, review, and verification checks
retain their normal blocking policy.
Legacy wikis with no declared knowledge projection continue in surface-only
mode. See [Native knowledge reads][native-knowledge-strict]
for the complete policy.
`--profile` suppresses the human-readable lint text and prints one JSON object
to stdout containing the normal lint report, diagnostics, and phase timings.
The JSON contract is preserved for extractor failures as well; lint still exits
nonzero, but stdout remains machine-readable.
`lint --profile` and `ci-check --format json` additionally include this shape:
{
"execution": {
"extractor_jobs": {
"requested_jobs": "auto",
"resolved_jobs": 20,
"eligible_parallel_plans": 2,
"effective_workers": 2,
"parallel_plan_ids": ["python", "typescript"],
"sequential_plan_ids": [],
"cache_elided_plan_ids": []
}
}
}
This metadata is additive only in those two JSON modes. Default lint report
serialization, MCP lint responses, CI text/Markdown output, sync state and
manifests, and the `llm-wiki-context/v1` protocol stay unchanged.
Lint uses a persistent deep-inventory cache by default when a git directory is
available, storing `.git/llm-wiki-inventory-cache.json`. Override the cache
directory with `LLM_WIKI_CACHE_DIR` or `--cache-dir PATH`; the CLI flag wins for
inventory caching. Use `--helper-cache-dir PATH` when prepared Go/Rust/Haskell
helpers live somewhere else. Use `--no-cache` to disable load/save,
`--rebuild-cache` to ignore and rewrite the cache, and `--cache-stats` to
include cache diagnostics.
Cache corruption or invalid fingerprints fall back to a full extraction without
reducing lint coverage. With `--profile --cache-stats`, the JSON payload includes a top-level
`cache` object. Use `--jobs N` or `--jobs auto` to opt into parallel extraction
for built-in languages and plugin extractors whose manifests set
`"parallel_safe": true`; the default and recommended interactive setting is
`--jobs 1`. Reserve `auto` for an isolated terminal or controlled CI runner
with known capacity. Plugin extractors without that opt-in remain sequential.
Use `--include-tests go` when a wiki intentionally documents Go `_test.go`
files; omit it to lint against the default production-source inventory.
For trusted source trees outside the runner workspace, pass
`--allow-external-src`; same-owner or system-administrator-owned symlinks are
disclosed with a warning, symlinks owned by another user are rejected, and
`--wiki-dir` remains constrained to the current project root.
When dependency architecture pages exist, lint reruns dependency analysis and
surfaces import cycles, undeclared dependencies, and unused declared
dependencies as warning diagnostics. These warnings are visible in human output
and profile JSON but do not make `lint`, `lint --strict`, or `ci-check` fail by
themselves. Stale architecture pages with no current source modules remain hard
issues.
Python dependency reconciliation reads `pyproject.toml` and `requirements*.txt`
manifests, including nested manifests scoped to their directory. TypeScript and
JavaScript reconciliation reads the nearest scoped `package.json` and resolves
first-party imports through the nearest `tsconfig.json` `baseUrl`/`paths`
aliases before reporting undeclared external packages. Generic internal import
matching is scoped by the importer's language before external dependency
reconciliation, so same-stem files in other languages do not consume external
imports. Dependency manifests inside generated agent worktree copies,
gitignored directories, and other paths outside the default source snapshot
boundary are ignored during reconciliation. Go
`// indirect` requirements are treated as optional transitive dependencies, so
they do not produce unused-dependency warnings by themselves. Haskell
reconciliation reads Cabal `build-depends` statically, records Stack
`extra-deps` and Nix package hints as optional only, scopes nested Cabal
packages by nearest manifest directory, and reports only explicit known
module-prefix mappings such as `Data.Text` -> `text`.
When supported lockfiles are present, reconciliation also exposes optional
resolved-version metadata under each language's `versions` mapping. Missing or
unparseable lockfiles fail open by omitting version records; they do not affect
lint pass/fail behavior or undeclared/unused package diagnostics.
When generated entity/module diagram sections exist, lint validates Mermaid
`click` links as hard broken-link issues and reports over-large generated
diagrams as warning diagnostics with page and section targets.
When guide or other semantic pages embed local media, lint treats image and
video targets separately from Markdown page links. It recognizes inline
Markdown images and media links, same-page reference-style images, and raw
``, `