Skip to content

πŸ“˜ reference β€” overview/guide, not tied to a code symbol

Validation by Beadloom doc_sync β€” same source as sync-check.

CLI Reference ​

Beadloom CLI is built on Click and provides a set of commands for managing the knowledge index.

Specification ​

Global Options ​

beadloom [--verbose|-v] [--quiet|-q] [--version] COMMAND
  • --verbose / -v -- verbose output
  • --quiet / -q -- errors only
  • --version -- show version

beadloom init ​

Project initialization. Three modes:

bash
# Generate graph from code structure (auto-detects architecture)
beadloom init --bootstrap [--preset {monolith,microservices,monorepo}] [--project DIR]

# Import existing documentation
beadloom init --import DOCS_DIR [--project DIR]

# Non-interactive mode (for CI/scripting)
beadloom init --yes [--mode {bootstrap,import,both}] [--force] [--project DIR]

# Interactive mode (default when no flags given)
beadloom init [--project DIR]

--bootstrap scans source directories (src, lib, app, services, packages), classifies subdirectories using architecture-aware preset rules, infers edges from directory nesting, and generates .beadloom/_graph/services.yml + .beadloom/config.yml.

--preset selects an architecture preset:

  • monolith -- top dirs are domains; subdirs map to features, entities, services
  • microservices -- top dirs are services; shared code becomes domains
  • monorepo -- packages/apps are services; manifest deps become edges

When --preset is omitted, Beadloom auto-detects: services/ or cmd/ -> microservices, packages/ or apps/ -> monorepo, otherwise -> monolith.

--import classifies .md files (ADR, feature, architecture, other) and generates .beadloom/_graph/imported.yml.

--yes / -y enables non-interactive mode: no prompts, uses defaults. Combined with --mode to select the initialization strategy:

  • bootstrap (default) -- generate graph from code
  • import -- classify existing docs
  • both -- bootstrap graph and import docs

--force overwrites an existing .beadloom/ directory. Without it, non-interactive init skips if .beadloom/ already exists.

Projects without a docs/ directory work fine -- Beadloom operates in zero-doc mode with code-only context (graph nodes, annotations, context oracle).

beadloom reindex ​

Full reindex: drops all tables and reloads from scratch.

bash
beadloom reindex [--full] [--docs-dir DIR] [--project DIR]
  • --full -- force full rebuild (drop all tables and re-create)
  • --docs-dir -- documentation directory (default: from config.yml or docs/)

Default mode is incremental (only changed files). Use --full to force complete rebuild.

Order: drop tables -> create schema -> load graph YAML -> index docs -> index code -> resolve imports -> load rules -> build sync state -> populate FTS5 -> take health snapshot.

When no changes are detected, displays current DB totals (nodes, edges, docs, symbols) instead of reindex counts. Warns about missing tree-sitter parsers when symbols == 0.

beadloom ctx ​

Get a context bundle for the specified ref_id(s).

bash
beadloom ctx REF_ID [REF_ID...] [--json|--markdown] [--depth N] [--max-nodes N] [--max-chunks N] [--project DIR]

Outputs Markdown by default. --json for machine-readable format.

beadloom graph ​

Architecture graph visualization. Supports Mermaid, C4-Mermaid, and C4-PlantUML output formats.

bash
# Full graph in Mermaid format (default)
beadloom graph [--project DIR]

# Subgraph from specified nodes
beadloom graph REF_ID [REF_ID...] [--depth N] [--json]

# C4 architecture diagram (Mermaid C4 syntax)
beadloom graph --format c4 [--level {context,container,component}] [--project DIR]

# C4 architecture diagram (PlantUML C4 syntax)
beadloom graph --format c4-plantuml [--level container] [--project DIR]

# C4 component diagram scoped to a specific container
beadloom graph --format c4 --level component --scope graph [--project DIR]
  • --format -- output format: mermaid (default), c4 (Mermaid C4 syntax), or c4-plantuml (C4-PlantUML syntax).
  • --level -- C4 diagram level (only used with --format=c4 or --format=c4-plantuml):
    • context -- System-level nodes only (highest abstraction)
    • container (default) -- System and Container nodes
    • component -- Children of a specific container (requires --scope)
  • --scope -- ref_id of the container to zoom into when --level=component. Required for component-level diagrams.

C4 level assignment uses part_of depth: root nodes become Systems, depth 1 becomes Containers, depth 2+ becomes Components. Nodes can override this by setting c4_level in their YAML extra field. Nodes tagged external render as _Ext variants; nodes tagged database or storage render as Db variants.

beadloom status ​

Index statistics with health trends.

bash
beadloom status [--json] [--project DIR]

Shows Rich-formatted dashboard with: node count (broken down by kind), edges, documents, symbols, per-kind documentation coverage, stale docs, isolated nodes, empty summaries. Includes trend indicators comparing current reindex with previous snapshot. Also displays context metrics: average bundle token size, largest bundle (ref_id + tokens), total indexed symbols.

--json -- structured JSON output.

status --debt-report ​

Architecture debt report mode. Aggregates health signals from lint, sync-check, doctor, git activity, and test mapper into a single 0-100 debt score with category breakdown and top offending nodes.

bash
beadloom status --debt-report [--json] [--fail-if=EXPR] [--category=NAME] [--project DIR]
  • --debt-report -- show architecture debt report instead of the standard status dashboard.
  • --json -- output the debt report as structured JSON (with --debt-report).
  • --fail-if=EXPR -- CI gate: exit 1 if condition is met. Requires --debt-report. Supported expressions:
    • score>N -- fail if overall debt score exceeds N.
    • errors>N -- fail if rule violation error count exceeds N.
  • --category=NAME -- filter the debt report to a single category. Accepted names: rules, docs, complexity, tests (short names) or rule_violations, doc_gaps, test_gaps (internal names).

The debt score formula combines four categories:

  • Rule Violations -- weighted count of lint rule errors and warnings.
  • Documentation Gaps -- undocumented nodes, stale docs, untracked files.
  • Complexity -- oversized domains (by symbol count), high fan-out nodes, dormant domains.
  • Test Gaps -- untested domains/features.

Severity classification: clean (0), low (1-10), medium (11-25), high (26-50), critical (51-100).

Examples:

bash
# Human-readable Rich output
beadloom status --debt-report

# Machine-readable JSON
beadloom status --debt-report --json

# CI gate: fail if score exceeds 30
beadloom status --debt-report --fail-if=score>30

# CI gate: fail if any lint errors
beadloom status --debt-report --fail-if=errors>0

# Filter to documentation gaps only
beadloom status --debt-report --category=docs

beadloom doctor ​

Architecture graph validation.

bash
beadloom doctor [--project DIR]

Checks:

  • Nodes with empty summary
  • Documents not linked to nodes
  • Nodes without documentation
  • Isolated nodes (no edges)

beadloom sync-check ​

Check doc-code synchronization.

bash
beadloom sync-check [--porcelain] [--json] [--report] [--ref REF_ID] [--since GIT_REF] [--project DIR]

Exit codes: 0 = all OK, 1 = error, 2 = stale pairs found.

  • --porcelain -- TAB-separated output for scripts. Format: status\tref_id\tdoc_path\tcode_path\treason.
  • --json -- structured JSON output with summary and pair details. Each pair includes status, ref_id, doc_path, code_path, reason, and optional details.
  • --report -- ready-to-post Markdown report for CI (GitHub/GitLab).
  • --ref -- filter results by ref_id.
  • --since GIT_REF -- compute drift against the code state at a git ref (e.g. the push's parent commit) instead of the stored sync_state baseline. Reports pairs whose code drifted since the ref while the doc was not correspondingly updated. This makes drift detection work on a fresh CI checkout: a clean clone reindexes from scratch and re-baselines sync_state to the just-pushed code, so without a ref baseline sync-check sees 0 stale even when the push left a doc behind. Mirrors beadloom diff --since. Used by the AI tech-writer harness (it passes the push parent β€” github.event.before / $CI_COMMIT_BEFORE_SHA, falling back to HEAD~1).

Human-readable output includes reason-aware formatting:

  • untracked_files reason: displays list of untracked files in details.
  • missing_modules reason: displays list of missing modules in details.
  • Other stale reasons (e.g. symbols_changed, content_changed): displays reason next to the code path.

Reference surface drift (advisory). A high-traffic overview doc can opt in to freshness against a coarse interface surface with an in-doc annotation near its top:

markdown
<!-- beadloom:watches=cli,graph,flow.yml -->

The watched surfaces are cli (the Click command + flag tree), graph (the node + edge identity set), and flow.yml (the normalized .beadloom/flow.yml). reindex baselines the aggregate hash of the declared surfaces; sync-check recomputes it and, when the surface changed, emits a pair with reason = surface_drift and severity warning. In --json, summary.surface_drift and a references[] array carry these pairs (stored-baseline mode only; the --since shape is unchanged). Surface drift is advisory β€” it never changes the exit code or fails beadloom ci; it asks a human to re-read the overview and clear it with sync-update.

beadloom sync-update ​

Review and update stale documentation.

bash
# Show sync status for a ref_id
beadloom sync-update REF_ID --check [--project DIR]

# Interactive: open stale docs in $EDITOR, mark synced after editing
beadloom sync-update REF_ID [--project DIR]

# Non-interactive: re-baseline freshness without an editor or prompt
beadloom sync-update REF_ID --yes [--project DIR]

# Non-interactive, fixpoint loop: re-baseline every currently-stale ref
beadloom sync-update --all --yes [--project DIR]

--yes (-y) records that the doc(s) for the ref match the code now (recomputes file hashes + symbols hash, sets status='ok'), prints a concise summary, and exits 0 β€” no editor, no prompt. This is the primitive a CI/script fixpoint loop uses to re-baseline freshness after a doc is rewritten; it is the same operation the interactive path performs after an edit. --all re-baselines every ref sync-check currently flags stale (deterministic; requires --yes).

REF_ID also accepts the path of a reference doc (one carrying a watches: annotation). In that case sync-update recomputes and stores the doc's aggregate surface hash, clearing a surface_drift warning β€” the same re-attestation as a symbol pair.

For automated doc updates, use your AI agent (Claude Code, Cursor, etc.) with Beadloom's MCP tools. See .beadloom/AGENTS.md for agent instructions.

beadloom install-hooks ​

Install (or remove) Beadloom's git hooks: a pre-commit hook (the lighter synchronization check) and a pre-push hook (the authoritative blocking Beadloom Gate). By default both are installed.

bash
# Install BOTH hooks (pre-commit warn mode + pre-push Gate)
beadloom install-hooks [--mode warn|block] [--project DIR]

# Install only one
beadloom install-hooks --pre-commit [--mode warn|block] [--project DIR]
beadloom install-hooks --pre-push [--project DIR]

# Remove (both, or the selected one)
beadloom install-hooks --remove [--pre-commit|--pre-push] [--project DIR]

Pre-commit hook runs, in order: ruff lint, mypy, beadloom sync-check (--mode warn reports stale docs; --mode block fails the commit on stale docs), and finally the ACTIVE / tracker coherence step. That last step is a guarded auto-fix: it runs only when BOTH bd and beadloom are on PATH, calls beadloom active-sync to reconcile each epic's ACTIVE.md bead-status table from bd and re-export .beads/issues.jsonl, then restages the touched .claude/development/docs/features/** files and .beads/issues.jsonl so the commit is coherent by construction. It never blocks the commit (it runs even in block mode without affecting the exit code), and in any repo without bd β€” or without ACTIVE tables β€” the block is a complete no-op (see active-sync).

Pre-push hook (Beadloom Gate) is the authoritative blocking enforcement of the hard invariant "no code in main without current docs." On every push it runs the full Gate (beadloom ci β€” incremental reindex β†’ lint --strict (module-coverage included) β†’ sync-check β†’ docs-audit β†’ config-check β†’ doctor) and exits non-zero to block the push on red, printing an actionable message ("Beadloom Gate failed … run the tech-writer (or /coordinator) then re-push; git push --no-verify to override"). It is fail-safe: in any repo without beadloom on PATH the hook is a safe no-op and never blocks. The full Gate lives in pre-push (not duplicated on every commit) because pushes are less frequent than commits; the pre-commit hook stays the lighter warn/block check. --no-verify is the documented (discouraged) escape hatch.

Both hooks are idempotent β€” re-running install-hooks overwrites cleanly.

beadloom active-sync ​

Reconcile each epic's ACTIVE.md bead-status table from bd β€” the source of truth β€” and re-export the tracked .beads/issues.jsonl.

bash
# Fix mode (default): rewrite drifted Status cells + bd export the jsonl
beadloom active-sync [--epic KEY] [--no-export] [--project DIR]

# Check mode: report drift without writing; exit 1 if any drift, 0 if clean
beadloom active-sync --check [--epic KEY] [--project DIR]

# Machine-readable JSON (works with --check or fix mode)
beadloom active-sync --json [--check] [--epic KEY] [--project DIR]

For every epic's ACTIVE.md, it finds the bead-status table and rewrites each Status cell to match the bead's current bd status (closed β†’ βœ“ done, in_progress β†’ in progress, open/ready β†’ ready, and blocked for an open bead with an open blocker). A richer coordinator note is preserved when its state already agrees (e.g. βœ“ done (PASS-WITH-FIXES) is left intact for a closed bead). Only Status cells change β€” prose, the Progress Log, and other columns are byte-preserved. The reconcile core (application/active_table.py, reconcile_active_tables / bd_status_to_cell) is the same one the MCP S4 process-tools (checkpoint / complete_bead) use.

This is the mechanism that keeps ACTIVE.md honest by construction β€” wired into the pre-commit hook (above), the coordinator no longer hand-edits bead-status rows; the table is reconciled from bd on every commit.

  • --epic KEY β€” reconcile only features/<KEY>/ACTIVE.md (default: every features/*/ACTIVE.md).
  • --check β€” report drift on a throwaway copy without writing; exit 1 if any row would change, exit 0 when clean. Never writes and never exports.
  • --json β€” machine-readable output: { "changed_files": [...], "drifted_rows": [ { "path", "bead_id", "old", "new" }, ... ] }.
  • --no-export β€” skip the bd export jsonl sync (fix mode only).
  • --project DIR β€” project root (default: current directory).

In fix mode (no --check), after rewriting it best-effort runs bd export -o .beads/issues.jsonl β€” but only when that file is already git-tracked β€” so the tracked tracker artifact stays honest across branch/squash-merge. --no-export skips that step.

No-op contract. active-sync exits 0 and writes nothing when there is no ACTIVE.md with a bead-status table, OR when bd is unavailable, OR when .beads/issues.jsonl is not tracked (the export is skipped). So a non-flow repo β€” or any adopter without the agentic flow β€” is never affected; the command (and the hook step that calls it) is a safe out-of-the-box no-op.

Manage external tracker links on graph nodes.

bash
# Add a link (label auto-detected from URL)
beadloom link REF_ID URL [--label LABEL] [--project DIR]

# List links for a node
beadloom link REF_ID [--project DIR]

# Remove a link
beadloom link REF_ID --remove URL [--project DIR]

Auto-detected labels: github, github-pr, jira, linear, link (fallback).

beadloom diff ​

Show graph changes since a git ref.

bash
beadloom diff [--since REF] [--json] [--project DIR]

Compares current graph YAML with state at the given ref (default: HEAD). Exit code 0 = no changes, 1 = changes detected.

beadloom export ​

Export the indexed graph as a deterministic cross-repo federation artifact (JSON).

bash
beadloom export [--out FILE] [--project DIR]

Reads the indexed graph from SQLite (read-only) and emits a self-describing JSON artifact (schema v1): repo, commit_sha, exported_at, generator, and the nodes / edges arrays (each carrying lifecycle; edges may carry AMQP contract meta). The edges array unions the local edges table and the cross-repo foreign_edges table so declared @repo: links survive. Output is byte-deterministic (sorted nodes/edges + sorted keys). --out writes to a file; otherwise prints to stdout. Exits 1 if the database is missing (run beadloom reindex first). See the federation SPEC.

beadloom federate ​

Aggregate β‰₯2 satellite export artifacts into one federated graph (hub).

bash
beadloom federate EXPORT1.json EXPORT2.json [...] [--project DIR]

Composes the namespaced node/edge union (@repo:ref_id identity), resolves @repo: foreign refs, assigns a three-valued intent-vs-reality verdict per edge (OK / DRIFT / EXPECTED / CLEANUP_CANDIDATE / UNDECLARED / DEAD), reconciles AMQP contracts (confirmed both-sides vs one-sided), and reports per-satellite staleness (commit_sha + age). Writes .beadloom/federated.json + .beadloom/federated.txt in the hub project root and echoes the report (with any DRIFT) to stdout. Requires at least two artifacts; exits 1 otherwise or if a file is not a JSON object. The --fail-on <csv> landscape gate (writes artifacts first, then exits 1 on matching verdicts) prints an agent-actionable fix: hint per failing verdict (BREAKING / ORPHANED_CONSUMER / UNDECLARED_PRODUCER / DRIFT). See the federation SPEC.

beadloom snapshot ​

Architecture snapshot management. Snapshots capture the current graph state (nodes, edges, symbols) for later comparison.

beadloom snapshot save ​

Save the current graph state as a snapshot.

bash
beadloom snapshot save [--label LABEL] [--project DIR]
  • --label -- optional label for the snapshot (e.g. pre-refactor).

beadloom snapshot list ​

List all saved architecture snapshots.

bash
beadloom snapshot list [--json] [--project DIR]

Shows snapshot ID, label, creation time, and counts (nodes, edges, symbols). --json for structured output.

beadloom snapshot compare ​

Compare two architecture snapshots to see what changed.

bash
beadloom snapshot compare OLD_ID NEW_ID [--json] [--project DIR]

Displays added/removed/changed nodes and added/removed edges between the two snapshots. Both OLD_ID and NEW_ID are required integer snapshot IDs.

Search nodes and documentation by keyword.

bash
beadloom search QUERY [--kind {domain,feature,service,entity,adr}] [--limit N] [--json] [--project DIR]

Uses FTS5 full-text search when available, falls back to SQL LIKE. Run beadloom reindex first to populate the search index.

beadloom why ​

Show impact analysis for a node -- upstream dependencies and downstream dependents.

bash
beadloom why REF_ID [--depth N] [--json] [--reverse] [--format {panel,tree}] [--project DIR]
  • --reverse -- focus on what this node depends on (upstream only) instead of the default full analysis.
  • --format -- output format: panel (Rich panels, default) or tree (plain text for CI/scripting).

beadloom lint ​

Run architecture lint rules against the project.

bash
beadloom lint [--format {rich,json,porcelain,github}] [--strict] [--fail-on-warn] [--no-reindex] [--project DIR]

Checks cross-boundary imports against rules defined in rules.yml. Format auto-detects: rich if TTY, porcelain if piped.

--format options:

  • rich -- human-readable text (default on a TTY).
  • json -- structured output: a backward-compatible violations array (now with an additive remediation key), a stable agent-actionable findings array ({kind, rule, severity, locations, why, remediation}), and a summary object. Deterministic (violations are pre-sorted).
  • porcelain -- one colon-separated line per violation (default when piped).
  • github -- GitHub Actions workflow commands (::error file=…,line=…::<rule>: <message> β€” <remediation>) so violations surface as inline PR annotations; warnings use ::warning.

Each violation carries an agent-actionable remediation hint derived per rule kind (deny/forbid β†’ remove/reroute the import or edge; cycle β†’ break the cycle at a named edge; layer β†’ invert the dependency or extract a shared abstraction; cardinality β†’ split the node; require β†’ add the required edge).

Exit codes: 0 = clean (or violations without --strict/--fail-on-warn), 1 = violations with --strict (errors only) or --fail-on-warn (any violation), 2 = configuration error.

beadloom tui ​

Launch interactive terminal dashboard (primary command).

bash
beadloom tui [--project DIR] [--no-watch]

Multi-screen architecture workstation with graph explorer, debt gauge, lint panel, doc status, and keyboard actions. Requires: pip install beadloom[tui].

  • --no-watch -- disable file watcher (for CI/testing)

beadloom ui ​

Launch interactive terminal dashboard (alias for tui).

bash
beadloom ui [--project DIR] [--no-watch]

Backward-compatible alias for beadloom tui. Requires: pip install beadloom[tui].

beadloom watch ​

Watch files and auto-reindex on changes.

bash
beadloom watch [--debounce MS] [--project DIR]

Monitors graph YAML, documentation, and source files. Graph changes trigger full reindex; other changes trigger incremental. Requires: pip install beadloom[watch].

beadloom docs generate ​

Generate documentation skeletons from the architecture graph.

bash
beadloom docs generate [--project DIR]

Creates docs/ tree: architecture.md, domain READMEs, service pages, feature SPECs. Never overwrites existing files. All generated files include <!-- enrich with: beadloom docs polish --> markers.

beadloom docs site ​

Generate a VitePress content tree from the architecture graph.

bash
beadloom docs site [--out DIR] [--federated FILE] [--project DIR]

Reads the indexed graph read-only and emits, under --out (default site/):

  • index.md -- architecture overview: domain/service/feature counts, the top-level C4/Mermaid diagram, and a health summary line (nodes/edges/docs/coverage/stale).
  • per-node pages (domains/<ref>.md, services/<ref>.md, features/<ref>.md) -- each with summary, source, public symbols, part_of/depends_on/uses edges rendered as Markdown links to the other node pages, linked hand-written docs, and an embedded scoped C4/Mermaid diagram.
  • dashboard.md + dashboard.data.json -- Showcase A, the AaC/DocAsCode metrics dashboard (lint count + severity, debt score + trend, doc coverage / sync-check freshness / stale count, doctor pass-fail, and an optional federated rollup). Every number comes from the SAME code path as its gate (lint / debt-report / sync-check / doctor / federate) -- honest by construction.
  • landscape.md -- Showcase B, the 🌟 cross-repo landscape map: a Mermaid diagram of the federated contract graph (with --federated) or the local graph (without), edges labelled by their verdict, a classDef health overlay, and clickable nodes linking to their intra-repo page.
  • docs/** + docs/index.md -- Showcase C, the published validated documentation: the REAL docs/** tree copied verbatim (the source of truth, rendered as-is) with a per-doc doc_sync freshness badge injected into the COPY only. The source docs/ is NEVER mutated.
  • .vitepress/config.generated.mjs -- the nav/sidebar config imported by the committed VitePress scaffold (site/.vitepress/config.mjs); sections: Dashboard / Architecture / Landscape / Documentation.

Beadloom produces, VitePress renders. Output is deterministic (sorted, stable frontmatter, no wall-clock in the diffed output) and is NEVER written into the source docs/ tree -- only under --out. --federated takes a federate hub artifact (federated.json) and drives the Showcase B landscape map. To render: cd site && npm install && npm run docs:build (preview with npm run docs:preview). See the VitePress Site guide.

beadloom docs audit ​

Detect stale numeric facts in project documentation.

bash
beadloom docs audit [--json] [--fail-if EXPR] [--stale-only] [--verbose] [--path GLOB]... [--project DIR]

Scans markdown documentation for numeric mentions (version strings, counts) and compares them against ground-truth facts collected from the project infrastructure (manifest files, graph DB, MCP tools, CLI commands). The audit is stable and runs as the docs-audit step inside beadloom ci, where it blocks the gate on stale>0.

  • --json -- structured JSON output with facts, findings, and unmatched mentions.
  • --fail-if -- CI gate expression. Supported format: stale>N or stale>=N. Exits with code 1 when condition is met.
  • --stale-only -- show only stale findings (omit fresh matches).
  • --verbose -- include extra detail (unmatched mentions, fact sources).
  • --path -- override default scan paths with custom glob patterns (can be specified multiple times).

Exit codes: 0 = no issues (or below threshold), 1 = --fail-if condition met.

Tuning false positives. The audit masks dates, hex, issue IDs, line refs, and version pins, and applies per-fact tolerances. Two .beadloom/config.yml keys handle the rest:

yaml
docs_audit:
  tolerances:
    node_count: 0.1          # accept counts within 10% of ground truth
  ignore:                    # suppress one {path, fact, value} false match each
    - path: docs/guides/vitepress-site.md
      fact: cli_command_count
      value: 404

docs_audit.ignore is a list of {path, fact, value} triples. Each suppresses exactly one keyword-proximity false positive β€” for example a subset count stated next to the correct total, or an HTTP status code matched as a command count β€” without rewording correct prose and without masking a genuine stale fact of the same type elsewhere. Use it only for confirmed false positives; genuine stale facts must be corrected in the doc.

Examples:

bash
# Human-readable Rich output
beadloom docs audit

# CI gate: fail if any stale docs
beadloom docs audit --fail-if=stale>0

# JSON output for scripting
beadloom docs audit --json --stale-only

# Scan only specific paths
beadloom docs audit --path "docs/**/*.md" --path "README.md"

beadloom docs polish ​

Generate structured data for AI-driven documentation enrichment.

bash
beadloom docs polish [--format {text,json}] [--ref-id REF_ID] [--project DIR]
  • text (default) -- human-readable summary with enrichment instructions
  • json -- structured JSON with nodes (symbols, dependencies, existing docs), Mermaid diagram, and AI prompt
  • --ref-id -- filter to a single node

beadloom prime ​

Output compact project context for AI agent injection.

bash
beadloom prime [--json] [--update] [--project DIR]
  • --json -- structured JSON output
  • --update -- regenerate .beadloom/AGENTS.md before outputting context

Returns architecture summary, health status (stale docs, lint violations), architecture rules, domain list, and agent instructions.

beadloom setup-rules ​

Create IDE rules files that reference .beadloom/AGENTS.md.

bash
# Auto-detect installed IDEs
beadloom setup-rules [--project DIR]

# Target a specific IDE
beadloom setup-rules --tool {cursor,windsurf,cline} [--project DIR]

Creates thin adapter files (.cursorrules, .windsurfrules, .clinerules) that instruct agents to read AGENTS.md.

beadloom config-check ​

AgentConfigAsCode freshness gate: verify that generated agent-config is in sync with the graph.

bash
beadloom config-check [--project DIR]   # exit 1 on drift, 0 when clean
beadloom config-check --fix [--project DIR]  # regenerate drifted artifacts, then re-check

Re-runs the same setup-rules --refresh generator in memory and diffs its output against on-disk content for .beadloom/AGENTS.md, the auto-managed sections of .claude/CLAUDE.md, and present IDE adapter files. Checks ONLY auto-managed regions β€” editing user-authored prose (the AGENTS.md custom block, CLAUDE.md content outside the auto-start/auto-end markers) never trips it. Prints which file drifted, why, and the remediation (beadloom setup-rules --refresh); absent target files are skipped. --fix regenerates via the refresh path and re-checks. Delegates to onboarding/config_sync.py:check_config_drift().

As of BDL-048, when a repo has the agentic flow scaffolded (beadloom setup-agentic-flow), config-check also drift-checks the scaffolded flow files: each vendored .claude/commands/* file is byte-compared against the shipped template. --fix re-drops the vendored flow files (config_sync.refresh_agentic_flow_files) alongside refreshing the CLAUDE.md auto-regions; the fix is gated on the flow already being scaffolded (it never forces the flow onto a repo that did not adopt it).

As of BDL-052 S3, when a valid .beadloom/flow.yml is present config-check also: (a) validates flow.yml itself (an invalid config is reported as drift; an absent one is not); and (b) byte-compares each composed role adapter (<tool>/agents/<role>.md for every tool the config names) against the freshly recomposed body (compose_role(...) for the configured architecture + stack overlays) β€” config_sync._composed_adapter_drifts. When a flow.yml is present the role agents are composer-owned, so the byte-vendor compare is skipped for agents (it would false-positive on a non-Python stack). --fix recomposes the per-tool adapter sets (config_sync.refresh_composed_adapters). Known limitation: the composed-adapter check iterates only the tools named in flow.yml, so adapters left behind by a tool dropped from a narrowed flow.yml (e.g. orphaned .cursor/agents/*) are neither flagged nor recomposed; a follow-up bead tracks an orphaned-adapter lint.

beadloom ci ​

The unified enforcement gate β€” the single CI convergence point (principle 7: identical for Cursor / Claude Code / human authors).

bash
beadloom ci [--hub EXPORT.json ...] [--fail-on CSV] [--format {rich,json,github}] [--no-reindex] [--project DIR]

Composes the existing checkers, in order, into ONE verdict with a single exit code (0 = all steps passed, 1 = any step failed):

  1. reindex (incremental) β€” unless --no-reindex.
  2. lint --strict β€” architecture boundary rules at error severity.
  3. sync-check β€” doc↔code freshness (stale pairs fail).
  4. config-check β€” AgentConfigAsCode drift.
  5. doctor β€” graph/data integrity; ONLY ERROR-severity checks fail the gate (WARNING/INFO advisories never block β€” no false gate).
  6. federate --fail-on β€” the cross-service landscape gate, only when --hub export(s) are given (safe-default fail-set breaking,drift,orphaned_consumer,undeclared_producer; no-false-gate verdicts rejected).

Honest gate (the Phase-0 lesson): the report names every step that ran and its outcome β€” PASS / FAIL / SKIP β€” never a green that silently skipped a step. No short-circuit: all steps run and ALL findings are collected even after an earlier failure, so one run surfaces every problem. --format applies uniformly across every step; findings share the agent-actionable {kind, rule, severity, locations, why, remediation} shape (github emits valid ::error file=<path>,line=<n>::<msg> workflow-command annotations, matching lint --format github; json emits {ok, steps[]}). The per-repo beadloom-aac-lint.yml reindex+lint+sync steps collapse into one beadloom ci call. Orchestration lives in application/gate.py:run_ci_gate(); the CLI only parses options and renders.

beadloom setup-mcp ​

Configure MCP server for your editor.

bash
beadloom setup-mcp [--tool {claude-code,cursor,windsurf}] [--project DIR]
beadloom setup-mcp --remove [--tool {claude-code,cursor,windsurf}] [--project DIR]
  • claude-code (default) -- .mcp.json in project root
  • cursor -- .cursor/mcp.json in project root
  • windsurf -- ~/.codeium/windsurf/mcp_config.json (global)

beadloom setup-ai-techwriter ​

Scaffold the AI tech-writer (BDL-047 / F4.1; harness packaged in BDL-051 / S2) into this repo for one-command, 3-step opt-in. In the setup-* family alongside setup-mcp / setup-rules.

bash
beadloom setup-ai-techwriter --platform {github,gitlab} [--project DIR]

Idempotently scaffolds (clean overwrite on re-run):

  • No Python vendoring. As of BDL-051 / S2 the harness ships inside the installed beadloom package as the beadloom.ai_agents.ai_techwriter domain, so adopters depend on beadloom and invoke it directly via python -m beadloom.ai_agents.ai_techwriter (the BDL-047/048 tools/ Python vendoring + drift-guard machinery is retired). Only the operator artifacts β€” the Goose recipe.yaml (a readable reference of the agent's blast radius) and provision-runner.sh β€” are copied (from package data via importlib.resources) into tools/ai_techwriter/ for operator convenience.
  • The chosen platform's CI wrapper: .github/workflows/ai-techwriter.yml (GitHub) or an ai-techwriter job in .gitlab-ci.yml (GitLab). As of BDL-049 both trigger on a PR to main/master β€” GitHub on: pull_request (opened/synchronize/reopened), GitLab merge_request_event β€” plus a manual fallback (workflow_dispatch). They call the same python -m beadloom.ai_agents.ai_techwriter entrypoint; the PR path passes --target pr-branch and --since $(git merge-base origin/<base> HEAD) so the agent commits its refresh into the PR branch; the manual path uses --target branch-pr. A loop-guard skips the agent's own [skip ai-techwriter] commit, and cancel-in-progress: true supersedes older runs. Only the trigger, the secret naming (QWEN_API_KEY repo secret vs CI/CD variable), and --platform differ. An existing .gitlab-ci.yml is appended to (job-only, stripping the standalone stages: header) β€” never blindly clobbered; an already-wired file is left as-is.
  • tools/ai_techwriter/provision-runner.sh β€” a hardened, idempotent, executable (0o755) self-hosted-runner provisioner (--platform/--repo/--token): guarantees swap before any apt/build (the OOM lesson), RAM (~2 GB min, ~4 GB recommended) + disk (~5 GB) prechecks, fail-hard on the critical steps (toolchain + runner register/start), and best-effort + verified Goose/beadloom/bd installs reported at the end.
  • docs/guides/ai-techwriter.md β€” the 3-step getting-started guide.

Delegates to onboarding/ai_techwriter_setup.py:scaffold().

beadloom setup-agentic-flow ​

Scaffold Beadloom's proven multi-agent dev flow into this repo (BDL-048 / 052). In the setup-* family alongside setup-rules / setup-mcp / setup-ai-techwriter.

bash
beadloom setup-agentic-flow [--project DIR] [--force] \
    [--tool claude|cursor]...        # repeatable; default: flow.yml or claude
    [--architecture ddd|fsd]         # default: flow.yml or ddd
    [--stack python,fastapi,javascript,typescript,vuejs]  # CSV; default: flow.yml or auto-detected

As of BDL-052 S3 the role subagents are composed (not byte-vendored) from CORE + the selected architecture overlay (ddd/fsd) + the selected stack overlays, then written as a per-tool adapter set for every configured tool: claude β†’ .claude/agents/{dev,test,review,tech-writer}.md; cursor β†’ .cursor/agents/* plus a .cursor/rules/beadloom-flow.md orchestrator pointer. Selection comes from .beadloom/flow.yml, overridden by the --tool/--architecture/--stack flags (defaults claude / ddd / auto-detected stack β€” flag β†’ flow.yml β†’ default precedence). An invalid selection raises a FlowConfigError naming the bad value + the allowed set. A drift-guard (config-check) keeps every generated adapter byte-identical to its composition.

The slash skills (.claude/commands/{coordinator,task-init,checkpoint,templates}.md) are still vendored byte-identical to Beadloom's own proven flow, plus a .claude/CLAUDE.md whose auto-regions are generated for THIS project (name / stack / version / packages) via the same refresh_claude_md machinery setup-rules --refresh uses (the CLAUDE.md version comes from Beadloom's own __version__, BDL-UX #92).

A vendored command that already matches is left alone; a hand-edited command is skipped (reported as such) so user edits are not silently clobbered; --force overwrites it. Composed role adapters are owned by the configurator (re-running recomposes them). User prose outside the CLAUDE.md auto-regions is never touched. Delegates to onboarding/role_adapters.py:generate_adapters() (the adapters) + onboarding/agentic_flow_setup.py:scaffold() (the commands + CLAUDE.md).

The command prints the honest boundary: the coordinator + Agent-spawn are Claude-Code-native (orchestration stays in the harness); the Beadloom MCP process-tools are the deterministic, tool-agnostic substrate the flow calls; and the single source of TRUE enforcement remains beadloom ci in CI (the in-flow gates are advisory-strong, not a substitute for CI). See the Agentic Dev Flow guide.

beadloom setup-branch-protection ​

Configure trunk-based branch protection on main via gh api (BDL-049), so the CI gate becomes true enforcement rather than advisory. GitHub only.

bash
beadloom setup-branch-protection --repo OWNER/NAME [--branch main] [--check CONTEXT]... [--dry-run]

Idempotently sets main (or --branch) protection with a declarative PUT repos/{owner}/{repo}/branches/{branch}/protection: a PR is required (no direct push), the consolidated ci.yml checks β€” gate, tests (3.10), tests (3.11), tests (3.12), tests (3.13), site-build, ai-techwriter (ci.yml's job names + matrix legs) β€” are required status checks (strict: true), and enforce_admins: true + 0 required reviews so the solo owner is never locked out (can self-merge). PUT .../protection is declarative, so re-running re-settles the same state.

  • --repo OWNER/NAME (required) β€” the GitHub repository (e.g. acme/widget).
  • --branch (default main) β€” the trunk to protect.
  • --check CONTEXT (repeatable) β€” overrides the default required-check contexts (the consolidated ci.yml job check-runs listed above) entirely. A context MUST match a real GitHub check-run name EXACTLY and must NOT be a path-filtered workflow's check: such a check does not run on PRs that miss the filter, so under strict: true the PR β€” and therefore main β€” would never become mergeable. BDL-050 dropped the tests paths: filter precisely so each matrix leg runs on every PR and is a reliable required check.
  • --dry-run β€” print the exact gh api call + JSON payload without touching GitHub.

Delegates to onboarding/branch_protection.py:apply_branch_protection() (the gh invocation is injected via a GhRunner seam for mockable tests).

beadloom mcp-serve ​

Launch MCP stdio server.

bash
beadloom mcp-serve [--project DIR]

API ​

As of BDL-059 S4, src/beadloom/services/cli.py is a thin registration shell: it imports each command module for its registration side effects and re-exports main (plus the private helpers tests import) so beadloom.services.cli.main stays the stable entry point. The command implementations live in the src/beadloom/services/commands/ package β€” one cohesive module per command group: _root (the main group + global options), query (ctx/search/why/graph/diff), index_ops (reindex/link), status (status + --debt-report rendering), docsync (sync-check/sync-update/install-hooks/active-sync/ci), federation (export/federate), docs (the docs group: generate/site/audit/polish), setup (the init/setup-*/mcp commands), dashboard (tui/ui/watch), and snapshot (the snapshot group). The status command's data-gathering was moved DOWN to the application layer (application/status.py: gather_status/compute_context_metrics/StatusData); the command keeps only the Rich/JSON presentation. The CLI surface (every command, option, help text, output, and exit code) is unchanged by the split.

Commands (re-exported from the package via the registration shell):

  • main -- Click group: beadloom [--verbose|-v] [--quiet|-q] [--version] COMMAND
  • reindex -- rebuild SQLite index (incremental by default, --full for complete rebuild)
  • ctx -- get context bundle for ref_id(s)
  • graph -- show architecture graph (Mermaid, C4-Mermaid, C4-PlantUML, or JSON) with --format, --level, --scope options
  • export -- export the indexed graph as a deterministic federation artifact (JSON, schema v1) with --out
  • federate -- aggregate >=2 satellite export artifacts into one federated graph (drift verdicts + staleness)
  • doctor -- run validation checks
  • status -- show index statistics with health trends and context metrics (data gathered by application/status.py:gather_status); --debt-report mode with --fail-if, --category flags
  • sync_check -- check doc-code sync with reason/details (reason-aware output for untracked_files, missing_modules, symbols_changed); --since GIT_REF measures drift against a git ref instead of the stored baseline (fresh-checkout / per-push drift detection)
  • sync_update -- review and update stale docs interactively; --check for status-only; --yes/-y for a non-interactive re-baseline; --all (with --yes) re-baselines every stale ref
  • install_hooks -- install/remove the pre-commit hook (lint -> mypy -> sync-check -> guarded ACTIVE/tracker-coherence auto-fix step) AND/OR the pre-push Beadloom Gate hook (beadloom ci, blocks the push on red; command -v beadloom guard -> safe no-op outside a flow repo); --pre-commit/--pre-push selectors (default both), --remove, idempotent
  • active_sync -- reconcile each epic's ACTIVE.md bead-status table from bd (--epic/--check/--json/--no-export); fix mode also bd exports the tracked .beads/issues.jsonl; safe no-op when no ACTIVE table or no bd; delegates to application/active_table.py:reconcile_active_tables()
  • link -- manage external tracker links
  • search -- FTS5 search with LIKE fallback
  • why -- impact analysis (upstream + downstream) with --reverse and --format {panel,tree}
  • diff_cmd -- graph changes since a git ref
  • snapshot -- Click group for snapshot commands (save, list, compare)
  • snapshot_save -- save current graph state as a snapshot
  • snapshot_list -- list all saved snapshots
  • snapshot_compare -- compare two snapshots (added/removed/changed nodes and edges)
  • lint -- architecture lint with --strict, --fail-on-warn, auto-format detection, agent-actionable remediation, and --format {rich,json,porcelain,github} (GitHub annotations)
  • prime -- compact project context for AI agents
  • setup_mcp -- configure MCP server for editor
  • setup_rules -- create IDE rules files
  • setup_ai_techwriter -- scaffold the AI tech-writer (vendored harness + recipe + chosen platform CI wrapper + getting-started guide) for one-command opt-in; delegates to onboarding/ai_techwriter_setup.py:scaffold()
  • setup_agentic_flow -- scaffold the packaged multi-agent dev flow (.claude/agents/* + commands/* vendored byte-identical + CLAUDE.md auto-regions per-project); idempotent, --force overwrites hand-edited flow files; delegates to onboarding/agentic_flow_setup.py:scaffold()
  • config_check -- AgentConfigAsCode drift gate (--fix regenerates); reuses the setup-rules --refresh generator; also drift-checks/restores the scaffolded agentic-flow files when the flow is present
  • ci -- unified enforcement gate composing reindex -> lint -> sync-check -> docs-audit -> config-check -> doctor -> (optional --hub) federate into one exit code; the docs-audit step blocks on stale facts (stale>0); honest per-step PASS/FAIL/SKIP; uniform --format {rich,json,github} (github = valid ::error file=,line= annotations); delegates to application/gate.py:run_ci_gate()
  • mcp_serve -- run MCP stdio server
  • docs -- Click group for doc commands (generate, polish, audit)
  • tui -- launch TUI dashboard (primary command, multi-screen with --no-watch)
  • ui -- launch TUI dashboard (alias for tui)
  • watch_cmd -- watch files and auto-reindex
  • init -- project initialization (bootstrap, import, interactive, non-interactive with --yes/--mode/--force)

All commands accept --project DIR to specify the project root. The current directory is used by default.

Testing ​

CLI is tested via click.testing.CliRunner. Each command has a corresponding test file in tests/test_cli_*.py: test_cli_reindex.py, test_cli_ctx.py, test_cli_graph.py, test_cli_status.py, test_cli_sync_check.py, test_cli_sync_update.py, test_cli_hooks.py, test_cli_link.py, test_cli_docs.py, test_cli_mcp.py, test_cli_watch.py, test_cli_diff.py, test_cli_why.py, test_cli_lint.py, test_cli_init.py, test_cli_snapshot.py, test_cli_config_check.py, test_cli_setup_agentic_flow.py, test_cli_active_sync.py (+ test_cli_active_sync_hardening.py).