Skip to content

cli reference

Ary Rabelo edited this page Jul 22, 2026 · 1 revision

CLI Reference

Relevant source files

  • src/repodocs/cli.py
  • src/repodocs/main.py
  • src/repodocs/_util.py

Overview

repodocs is a single console-script entry point that dispatches on its first positional argument to one of several subcommands implementing a documentation pipeline: scan, plan, generate, translate, html, publish, publish-wiki, render-diagrams, all, and setup. A second console script, repodocs-all, forwards all of its arguments to repodocs all. python -m repodocs invokes the same cli() function via __main__.py.

Sources: src/repodocs/cli.py:L1-L45, src/repodocs/main.py:L1-L4

Entry points

CLI Reference diagram

cli() (src/repodocs/cli.py:450-452) calls main(sys.argv[1:]). cli_all() (src/repodocs/cli.py:455-457) calls main(["all", *sys.argv[1:]]), so repodocs-all is exactly repodocs all with the same remaining arguments. __main__.py imports cli and calls it directly, giving python -m repodocs the same behavior as the installed script.

Sources: src/repodocs/cli.py:L417-L457, src/repodocs/main.py:L1-L4

Dispatch and top-level behavior

main(argv) (src/repodocs/cli.py:417-447) implements the dispatch:

  • No arguments: prints the module docstring (__doc__, which doubles as the usage text) and returns.
  • help, -h, --help: prints __doc__.
  • --version: prints VERSION (imported from repodocs.__init__).
  • Recognized subcommand names route to their cmd_* handler with the remaining args.
  • Any unrecognized subcommand calls die(f"unknown subcommand: {cmd}\n\n{__doc__}", 2), printing the error and usage to stderr and exiting with code 2.

die(msg, code=1) (src/repodocs/_util.py:36-38) is the shared error helper: it writes msg to stderr and calls sys.exit(code). Most subcommands use it for fatal errors (e.g. an invalid repo path, a missing backend, a missing vendored profile).

Sources: src/repodocs/cli.py:L417-L447, src/repodocs/_util.py:L36-L38

Shared argument parsing

Two helpers are shared across subcommands:

  • get_flag(args, name) (src/repodocs/cli.py:266-274) looks for --flag value (space-separated) or --flag=value form and returns the string value, or None if absent.
  • parse_repo_and_flags(args) (src/repodocs/cli.py:277-293) strips known value-bearing flags (--out, --pages, --lang, --branch, --remote) and their values, treats the first remaining non---prefixed token as the repo path (defaulting to Path(".")), and calls die(...) with exit code 1 if that path is not a directory.

Every subcommand handler checks for --help/-h first and prints its own help text (a module-level *_HELP string) instead of running.

Sources: src/repodocs/cli.py:L266-L293

Subcommands

Subcommand Handler Positional Flags
scan cmd_scan [repo] --json, --heuristic
plan cmd_plan [repo] --out DIR, --dry-run, --force
generate cmd_generate_cli [repo] --out DIR, --pages a,b, --dry-run, --force
translate cmd_translate_cli [repo] --lang pt, --out DIR, --pages a,b, --force
html cmd_html [repo] --out DIR, --vendor
publish cmd_publish_cli [repo] --out DIR, --branch gh-pages, --remote origin, --dry-run | --allow-public
publish-wiki cmd_publish_wiki_cli [repo] --out DIR, --remote origin, --dry-run | --allow-public
render-diagrams cmd_render_diagrams_cli [repo] --out DIR
all cmd_all [repo] --out DIR, --force, --no-graph
setup cmd_setup --force

[repo] defaults to the current directory in every subcommand that accepts it. --out DIR defaults to <repo>/repo-docs unless otherwise noted.

Sources: src/repodocs/cli.py:L196-L416

scan

cmd_scan (src/repodocs/cli.py:296-320) runs a deterministic repo inventory via scan_inventory(repo). With --json, prints the raw inventory dict; otherwise prints a human summary (source file count, manifests, README/CONTRIBUTING/CHANGELOG presence, CI config count, test file count). --heuristic instead runs plan_pages(repo, scan(repo)) and prints the deterministic fallback page list (as a table, or as JSON with --json).

Sources: src/repodocs/cli.py:L66-L71, src/repodocs/cli.py:L296-L320

plan

cmd_plan (src/repodocs/cli.py:323-336) calls require_backend(), then llm_plan(repo, out, force=...) to invoke the configured LLM planner over the scan inventory, validating and writing <out>/plan.json. --dry-run instead calls llm_plan(..., dry_run=True) to print the planner prompt without invoking the backend. Idempotent via <out>/.plan.hash; --force reruns the planner even if the inventory hash is unchanged. On planner failure/unparseable output, falls back to the heuristic plan and exits 0.

Sources: src/repodocs/cli.py:L74-L82, src/repodocs/cli.py:L323-L336

generate

cmd_generate_cli (src/repodocs/cli.py:339-348) calls require_backend(), reads --pages a,b into a set (or None for all pages), and calls sys.exit(cmd_generate(repo, out, only, dry_run, force)). Regenerates a page only if its .md is missing or a tracked source file's SHA-256 changed, tracked in <out>/.hashes.json; --force regenerates every page. Runs pages in parallel per REPODOCS_JOBS (default 4, clamped 1-16). Process exit code is nonzero if any backend call failed.

Sources: src/repodocs/cli.py:L85-L94, src/repodocs/cli.py:L339-L348

translate

cmd_translate_cli (src/repodocs/cli.py:364-374) calls require_backend(), reads --lang (default pt) and --pages, and calls sys.exit(cmd_translate(repo, out, lang, only, force)). Translated pages are written to <out>/<lang>/<slug>.md, preserving markdown structure, code, URLs, mermaid, and Sources: lines. Existing translated pages are skipped unless --force.

Sources: src/repodocs/cli.py:L113-L124, src/repodocs/cli.py:L364-L374

html

cmd_html (src/repodocs/cli.py:351-361) calls build_html(repo, out, vendor) where vendor = "--vendor" in args, then prints the destination path and page count. Without --vendor, JS/CSS assets load from a pinned CDN; with --vendor, they are downloaded into <out>/assets/ for offline use. Exits 1 if no .md pages exist yet.

Sources: src/repodocs/cli.py:L97-L110, src/repodocs/cli.py:L351-L361

publish and publish-wiki

cmd_publish_cli (src/repodocs/cli.py:377-387) reads --branch (default gh-pages) and --remote (default origin), then calls sys.exit(cmd_publish(repo, out, branch, remote, dry_run, allow_public)). Protected branches main/master/trunk are always refused; the staged wiki is scanned for private-key/token/API-key patterns before preview or push; a real push requires --allow-public and force-pushes an orphan commit via a detached worktree.

cmd_publish_wiki_cli (src/repodocs/cli.py:390-397) reads --remote (default origin) and calls sys.exit(cmd_publish_wiki(repo, out, remote, dry_run, allow_public)). Exports <out>/*.md into the repo's GitHub Wiki git repo, mapping overview.md (or index.md as fallback) to Home.md and generating _Sidebar.md from plan.json. Same secret-scan requirement; a real push clones the wiki, overwrites only exported filenames, and pushes normally (never force).

Sources: src/repodocs/cli.py:L135-L168, src/repodocs/cli.py:L377-L397

render-diagrams

cmd_render_diagrams_cli (src/repodocs/cli.py:409-415) calls sys.exit(cmd_render_diagrams(repo, out)). Renders every mermaid block in <out>/*.md to a committed pastel PNG and replaces the block with an image embed; blocks that fail to render keep their raw fence. This is optional and requires Bun + Playwright.

Sources: src/repodocs/cli.py:L399-L415

all

cmd_all (src/repodocs/cli.py:237-263) calls require_backend(), then, unless --no-graph is passed, requires graphify on PATH (die(...) with an install hint if missing) and runs graphify update <repo>, propagating its return code on failure. It then runs cmd_scan, llm_plan(..., force=...), prints the plan table, runs cmd_generate(...) (returning early on nonzero), and finally build_html(repo, out, vendor=True). This is the pipeline that repodocs-all (cli_all()) dispatches to.

Sources: src/repodocs/cli.py:L127-L132, src/repodocs/cli.py:L237-L263, src/repodocs/cli.py:L455-L457

setup

cmd_setup (src/repodocs/cli.py:219-234) calls require_backend(); if the backend is not omp, it prints setup not needed for REPODOCS_BACKEND=<backend> and returns. Otherwise it requires PROFILE_SOURCE to exist (die(...) if not) and calls setup_install(PROFILE_SOURCE, PROFILE_DEST, force), where PROFILE_DEST is ~/.omp/profiles/repo-docs/agent/ (src/repodocs/cli.py:193). setup_install (src/repodocs/cli.py:196-216) copies every file from the source tree, reporting per file whether it was installed, up to date, overwritten (only with --force), or left as differs, kept local (use --force to overwrite). If no agent.db exists at the destination afterward, it prints a reminder to authenticate via omp --profile=repo-docs and /login.

Sources: src/repodocs/cli.py:L171-L182, src/repodocs/cli.py:L193-L234

LLM backend configuration

Backend-invoking subcommands (plan, generate, translate, all, setup) call require_backend() (imported from repodocs.backend), which reads the REPODOCS_BACKEND environment variable. Documented environment variables (module docstring, src/repodocs/cli.py:32-40):

Variable Default Purpose
REPODOCS_BACKEND claude omp, claude, or codex
REPODOCS_MODEL backend default (claude-sonnet-5 for claude) Override model id for the selected CLI
REPODOCS_TIMEOUT 600 Per-call timeout in seconds
REPODOCS_JOBS 4 Parallel generate workers, clamped 1-16

BACKEND_HELP (src/repodocs/cli.py:185-190) is appended to the all subcommand's --help output and documents the same three backends.

Sources: src/repodocs/cli.py:L32-L44, src/repodocs/cli.py:L185-L190

Help and error behavior

Every subcommand handler checks "--help" in args or "-h" in args first and prints a dedicated help string (SCAN_HELP, PLAN_HELP, GEN_HELP, HTML_HELP, TRANSLATE_HELP, ALL_HELP + BACKEND_HELP, PUBLISH_HELP, PUBLISH_WIKI_HELP, SETUP_HELP, RENDER_DIAGRAMS_HELP) rather than executing. Running repodocs with no arguments, or repodocs help/-h/--help, prints the module docstring, which serves as the full usage synopsis. repodocs --version prints VERSION. An unrecognized subcommand is a hard error: die(f"unknown subcommand: {cmd}\n\n{__doc__}", 2) prints the message and full usage to stderr and exits with status 2. Fatal conditions inside subcommands (invalid repo path, missing backend CLI, missing vendored profile, missing graphify) all route through the same die() helper, printing to stderr and exiting nonzero (1 unless the call site passes another code).

Sources: src/repodocs/cli.py:L219-L447, src/repodocs/_util.py:L36-L38

Clone this wiki locally