Use the CLI¶
Overview¶
The axiom-graph command indexes your project, checks its docs for drift, and lets you explore and publish what it indexed. If you are setting up an AI agent, use the MCP server instead; most commands here have an MCP tool that does the same thing (connect your agent).
Most commands take the project directory as their last argument, usually .:
axiom-graph <command> [options] PROJECT_ROOT
The index is stored at .axiom_graph/graph.db in the project unless db_path in axiom-graph.toml points elsewhere (configuration). axiom-graph <command> --help lists every option of a command.
Install¶
axiom-graph needs Python 3.10 or later:
pip install axiom-graph
This installs the axiom-graph CLI and the axiom-graph-mcp server. Two extras add optional features:
Extra |
Adds |
|---|---|
|
The |
|
JavaScript and TypeScript indexing; also list the files under |
pip install "axiom-graph[viz,js]"
Index your project: init and build¶
Run init once to create the index. It scans your code and docs, records each module, function, test and doc section as a node, links them, and stores the baseline that later drift checks compare against:
axiom-graph init .
--id <prefix> sets the project id, the part before :: in every node id. It defaults to the id of the index being replaced, else the directory name, and init records the id as project_id in axiom-graph.toml. Every later build must use the same id, or it stops with an error naming both. To change the id, edit project_id and run init again.
Running init on a project that already has an index asks for confirmation, then deletes the index and starts over. Every verification and the whole change history are lost, so use init only to start fresh. It resets only the index: your axiom-graph.toml settings and your agent policy stay as they are.
When the build finishes, init also writes axiom-graph’s default agent policy as an editable doc named agent-policy in your docs folder, unless the project already has one, and tells you where it wrote it. The policy is the rules your agents follow in this project, and the axiom_graph_info tool shows it to them. Edit the doc to change the rules. init never overwrites a policy you already have.
Three flags reset one thing each:
axiom-graph init . --policy # restore the shipped agent policy
axiom-graph init . --settings # reset axiom-graph.toml to the defaults
axiom-graph init . --all # reset the index, the settings and the policy
--policy and --settings never touch the index. --settings lists each setting that differs from its default and asks before it rewrites the file; project_id is kept. --policy asks before it overwrites an existing policy doc, and needs an index. Pass both together if you want both, and add --yes to answer yes to their questions (without a terminal the answer is no). --all asks once, listing everything it will reset, and --yes never skips that question.
After that, run build whenever code or docs change:
axiom-graph build .
build adds new nodes, refreshes edges, removes the nodes of deleted files, detects renames and validates your annotations. Nodes already in the index keep their baselines, so drift stays flagged until you clear it. When a function changed, the docs and tests linked to it are marked LINKED_STALE in the same build. The report ends with the counts check would print:
Done.
staleness : own: 1 CONTENT_UPDATED / 0 DESC_UPDATED / 0 RENAMED / 0 NOT_FOUND · link: 2 LINKED_STALE / 0 BROKEN_LINK · 412 VERIFIED
If your @workflow, @task, Step or AutoStep markers have problems, the report also prints Annotation findings: N (X new, Y resolved) and lists the new ones (annotations).
Explore the index: list, render, graph¶
list prints one line per node with its id and summary. Filter with --type (atomic_process or composite_process; see the ontology) or --tag:
axiom-graph list .
axiom-graph list --type atomic_process .
axiom-graph list --tag consumer .
render prints nodes at the detail set by --level, which is required: 0 ids only, 1 one-line summaries, 2 the full docstring or section text and the file location, steps the numbered steps of annotated workflows (annotations). --id renders one node and --type filters by node type:
axiom-graph render --level 2 --id myproject::pkg.payments::charge .
graph prints a node’s edges. --direction out (the default) shows what the node depends on; in shows what points at it, such as the doc sections that document it and the tests that validate it; both shows both. --depth (default 1) sets how many hops to follow:
axiom-graph graph myproject::pkg.payments::charge --direction in .
[atomic_process] myproject::pkg.payments::charge @ pkg/payments.py#L40-L72
incoming:
<--[documents]-- myproject::docs/payments::charging
<--[validates]-- myproject::tests.test_payments::test_charge
link adds an edge the scanners cannot find, such as a test that validates a function:
axiom-graph link myproject::tests.test_payments::test_charge --edge-type validates --to myproject::pkg.payments::charge .
The ontology must allow that edge type between the two nodes. Links from a doc section to code usually go in the section’s links list instead (DocJSON).
Check for drift¶
check brings every node’s status up to date, stores it, then prints a summary line and the nodes that need attention. It re-checks only the files that changed since the last check:
axiom-graph check .
own: 1 CONTENT_UPDATED / 0 DESC_UPDATED / 0 RENAMED / 0 NOT_FOUND · link: 1 LINKED_STALE / 0 BROKEN_LINK · 41 VERIFIED
NODE OWN_STATUS LINK_STATUS
--------------------------------------------------------------------------
myproject::pkg.payments::charge CONTENT_UPDATED VERIFIED
myproject::docs/payments::charging VERIFIED LINKED_STALE via myproject::pkg.payments::charge
own statuses compare a node with its last verified state; link statuses cover the nodes it links to.
Status |
Meaning |
What to do |
|---|---|---|
|
Its body changed. |
Review it, then |
|
Its docstring or heading changed. |
Review it, then |
|
It was matched as a renamed node. |
Review it, then |
|
It is no longer on disk. |
|
|
Something it documents or tests changed since it was verified. |
Update the doc or test, then |
|
A link points at a node that no longer exists. |
Fix or remove the link. |
A doc or test is compared with the version of the code it was last verified against. If the code goes back to that version, LINKED_STALE clears on the next check.
Editing a doc does not clear LINKED_STALE. Saving it through an axiom_graph_* doc write tool does not clear it either; the tool verifies the doc’s own text only. mark-clean clears it, and so does an agent that names the changed code in addresses when it saves the section with axiom_graph_update_section or axiom_graph_patch_section. Staleness explains each status.
Option |
Effect |
|---|---|
|
Also list |
|
Print every node’s statuses, the counts, the files that need a |
|
Exit 1 if problems remain, for CI or a pre-push hook: |
|
Exit 1 if there is any annotation finding. |
|
Re-check every file, not only the ones that changed. It gives the same statuses as a plain |
check also prints the annotation findings line that build prints. A finding introduced since the last build shows as new on every check until the next build records it.
check never adds nodes. When a file has functions or sections the index does not have yet, it prints a line such as utils.py has 2 new functions — run build; run build to add them.
Resolve drift: mark-clean, purge and renames¶
mark-clean records that you reviewed a node and it is still correct. The node returns to VERIFIED, and --reason is stored with the verification:
axiom-graph mark-clean myproject::docs/payments::charging . --reason "Prose still matches the new rounding rule"
It clears CONTENT_UPDATED, DESC_UPDATED, RENAMED and LINKED_STALE on the node you name, and records you, not an agent, as the verifier. If you name a whole doc whose LINKED_STALE comes from its sections, it lists those sections for you to mark instead.
build drops deleted files, but a function deleted from a file that still exists stays NOT_FOUND until you purge it:
axiom-graph purge myproject::pkg.payments::old_charge .
axiom-graph purge --all-not-found .
purge removes only NOT_FOUND nodes and refuses anything else. --all-not-found lists the nodes and asks before purging (--yes skips the question), and --reason is saved in each node’s history. A module that reads NOT_FOUND only because a function inside it was deleted is kept; purge the function and the module clears on the next check. A syntax error makes functions read NOT_FOUND too: every function in a Python file, or the broken function in a JavaScript or TypeScript file. purge never removes any node of such a file: it names the file and tells you to fix it and run check again. build --purge only repeats the deleted-file pass that every build already runs.
build detects most renames itself and marks the new node RENAMED (rename settings). When it misses one, the old id shows NOT_FOUND and the new id appears as a new node. Join them by hand before you purge the old node:
axiom-graph rename apply myproject::pkg.old::charge myproject::pkg.payments::charge .
This moves the old node’s history, verifications and edges to the new id and marks it RENAMED. The old node must be NOT_FOUND and the new one newly created. Doc links to the old id are changed to the new id. A linked doc stays verified if the code still matches the version the doc was checked against, and goes LINKED_STALE if the body changed too. If a doc file was busy with another write or could not be read, the command prints a warning that names it; point its links at the new id yourself. To undo it:
axiom-graph rename revert myproject::pkg.payments::charge .
Accept hand-edited docs: stamps accept¶
A DocJSON section edited by hand, rather than through the doc tools, is indexed but not verified, and the next build warns about it. To keep the edit as it stands, accept it with stamps accept. This command takes the project directory first:
axiom-graph stamps accept . --list
axiom-graph stamps accept . myproject::docs/payments::charging
axiom-graph stamps accept . --all
--list shows the flagged sections and changes nothing; --all accepts every flagged section. mark-clean does not clear this flag. See DocJSON.
Inspect change history¶
axiom-graph keeps a history of each node’s changes, tagged with the git commit (history).
history checkpoint records the current commit as a reference point on every node of the types in --node-types (default atomic_process,composite_process, every node). --message (-m) labels it. report starts from the latest checkpoint by default:
axiom-graph history checkpoint -m "v2.1 release" .
report lists what changed since a reference point:
axiom-graph report .
axiom-graph report --since-sha a1b2c3d --format condensed .
axiom-graph report --list-refs .
Option |
Effect |
|---|---|
|
Start at this commit (4 or more characters). An unknown SHA is an error. |
|
Start at this ISO-8601 time. |
|
|
|
Only these change types, such as |
|
Only, or never, these node ids. |
|
Only |
|
List the checkpoints and commits you can start from. |
The reporting pipeline walks through a change and its report.
diff prints, as JSON, how nodes changed since a commit. Without --baseline, a stale node is compared with the last commit recorded before it went stale (or, if that commit doesn’t hold the node yet, the newest commit that holds it as it was before the change), and any other node with its last verification or checkpoint; --summary prints only the line counts:
axiom-graph diff myproject::pkg.payments::charge . --baseline HEAD~3 --summary
The node is found by its identity, so a function nobody touched shows no changes even when code above it moved. Several ids print one result each, separated by ---, and the command exits 1 if any of them could not be diffed.
history agent-verified lists nodes whose latest history entry is a verification recorded by an agent, so a person can review them. Running mark-clean on a node takes it off the list:
axiom-graph history agent-verified .
Export workflows: workflows export¶
workflows export writes workflows, and every source file their steps reach, to one HTML page. The page opens in any browser, offline, without axiom-graph or your repository. It is the same page the dashboard’s export button produces:
axiom-graph workflows export build_report .
axiom-graph workflows export --file reporting/pipeline.py -o pipeline.html .
axiom-graph workflows export build_report load_records --format json .
Option |
What it does |
|---|---|
|
The workflows and tasks to export, by function name or node id. Workflows and tasks can be mixed. |
|
Also export every workflow and task defined in that file. Repeat it for more files. |
|
|
|
The file to write. Default: |
The command prints the file it wrote and what it holds, such as Wrote workflow-export.html: 1 workflow · 2 files. A name or file that matches nothing is an error that names it, and nothing is written. The viz extra isn’t needed; without it the code on the page is shown without syntax colouring. An agent writes the same page with the axiom_graph_workflow_export MCP tool.
Share a workflow and its code walks through an export and what the page shows.
Launch the dashboard¶
viz starts the dashboard at http://127.0.0.1:8080 and opens it in your browser. It needs the viz extra:
axiom-graph viz .
axiom-graph viz --port 9090 --no-browser .
See the dashboard guide.
Publish the docs site: render-site¶
render-site renders DocJSON docs to Markdown pages: a Sphinx site, a README, or any other target listed under [[axiom_graph.site.targets]] in axiom-graph.toml. With no targets configured, it renders the docs listed in site-nav.yml to userdocs/guide:
axiom-graph render-site .
axiom-graph render-site --target readme .
--target NAME renders only that target and can be repeated. --build also runs sphinx-build. --nav PATH and --output DIR render a single Sphinx tree from a nav file, ignoring the configured targets. Targets are described in configuration; multi-target rendering walks through an example.
Next steps¶
Connect your agent: the MCP tools that match these commands.
Configuration: what gets indexed, the project id, rename and staleness settings, site targets.
Staleness: how each status is detected and cleared.
The docs-honesty loop: keeping published docs in step with the code.