The java-codebase-rag command is the operator surface for this bundle: index lifecycle (init / increment / reprocess / erase), graph and Lance health (meta, tables), ignore diagnostics, and PR diff analysis. It is not the MCP navigation surface (that is search / find / describe / neighbors / resolve on the MCP server — this CLI is lifecycle and introspection only). For agents driving the MCP server, see AGENT-GUIDE.md.
After installing the package (e.g. editable install from the repo root), the console script is on your PATH:
.venv/bin/pip install -e .
java-codebase-rag --helpIf java-codebase-rag is missing, run the module entrypoint:
.venv/bin/python -m java_codebase_rag.cli --helpInteractive setup wizard that walks users through Java source detection, embedding model selection, agent host configuration, artifact deployment, and YAML config generation. Use --non-interactive for CI/automation.
# Interactive mode
java-codebase-rag install
# Non-interactive mode (requires at least one --agent)
java-codebase-rag install --non-interactive --agent claude-code
java-codebase-rag install --non-interactive --agent claude-code --agent qwen-code
# With custom embedding model
java-codebase-rag install --model /path/to/model
# User-scope installation (available globally)
java-codebase-rag install --scope userFlags:
--non-interactive— Run without prompts (requires--agent).--agent {claude-code,qwen-code,gigacode}— Agent host to configure (can be passed multiple times).--scope {project,user}— Installation scope (default:project). Project scope writes to.<host>/in the project repo; user scope writes to~/.<host>/(globally available).--model MODEL— Embedding model path orauto(default:auto, downloadssentence-transformers/all-MiniLM-L6-v2on first run).--quiet/-q— Suppress the indexing progress stream on stderr (wizard prompts unchanged).--verbose/-v— Raw-relay subprocess output during the indexing sub-step (no progress bar).
Exit codes:
0— Success (all stages completed).1— Partial success (some stages failed). Re-runinstallto retry failed stages.2— Fatal error (no Java files found, required flag missing).
Stages:
- Java source detection — Maven/Gradle module roots.
- Embedding model selection — auto-download or local path.
- Agent host selection — Claude Code, Qwen Code, GigaCode (multi-select).
- Install scope — project or user.
- MCP entrypoint resolution + artifact deployment — config, skill, agent files.
- Index + finish — YAML generation,
.gitignoreupdate,init. Stage 6's indexing sub-step renders the unifiedVectors → Optimize → Graphprogress on stderr (see Indexing progress); the wizard's conversational stdout is unchanged.
Re-running install: If .java-codebase-rag.yml exists, the installer shows current values and offers "Update" (pre-filled) or "Start fresh". Existing MCP entries are updated in-place (merged, not duplicated). Skill/agent files trigger overwrite confirmation.
Post-upgrade refresh: overwrites skill and agent files with the latest shipped versions and updates the MCP command path. If an index exists, also runs an incremental Lance + graph catch-up (same as increment). Requires a prior install run.
# Refresh after pip upgrade
pip install --upgrade java-codebase-rag
java-codebase-rag update
# Preview changes without writing
java-codebase-rag update --dry-run
# Force overwrite all artifacts
java-codebase-rag update --forceFlags:
--force— Overwrite all artifacts even if content matches.--dry-run— Print changes without writing files.--quiet/-q— Suppress the indexing progress stream on stderr (wizard stdout unchanged).--verbose/-v— Raw-relay subprocess output during the indexing sub-step (no progress bar).
Behavior:
- Detects previously configured agent hosts (scans both project-level and user-level config files).
- Refreshes skill and agent files (versioned assets from the package).
- Updates MCP entrypoint path if
java-codebase-rag-mcphas moved. - Runs an incremental index update (Lance + graph) if an index exists — same as
java-codebase-rag increment. The indexing sub-step renders the unifiedVectors → Optimize → Graphprogress on stderr (see Indexing progress); it no longer runs silently.
Exit codes:
0— Success.1— Partial failure (some artifacts failed to write).2— No configured hosts found.
- TTY: human-readable
pprintof the payload on stdout (except successful selectivereprocesswith--vectors-only/--graph-only, which printsRebuilt:/Skipped:lines instead of dumping the full dict). - Piped / non-TTY: single JSON object per invocation on stdout (no trailing noise). Use this in scripts and CI.
- Lifecycle stderr:
init,increment,reprocess,install,update, anderasestream subprocess progress (and relayed child stdout) to stderr; pass--quietto suppress that stream. stdout stays the JSON/pprint payload (init/increment/reprocess) or the wizard conversational text (install/update) only.
Example:
java-codebase-rag meta --source-root /path/to/java/repo --index-dir /path/to/.java-codebase-rag | jq .ontology_versionAll five lifecycle commands that build the index (init, increment, reprocess, install, update) render the same unified progress on stderr during indexing: a header line, a three-phase list Vectors → Optimize → Graph, and a footer line. The phase list is the single source of truth for "what's happening right now":
- Vectors — the
cocoindex updateLance catch-up / full reprocess. - Optimize — the serialized Lance table compaction that runs after a successful vectors phase.
- Graph — the
build_ast_graph.pyLadybugDB/LadybugDB build (full or incremental).
Determinate vs indeterminate per command:
| Phase | Determinate? |
|---|---|
Vectors (full init / reprocess) |
Approximately determinate — a pre-walk estimates the file count; the bar clamps to 100% on completion (the pre-walk overstates by ignored/empty files). |
Vectors (incremental increment / update) |
Indeterminate — CocoIndex's memo=True cache only calls the per-file function for changed files, so no denominator is known up front. A pulsing bar plus a "files touched: N" counter. |
Optimize |
Always indeterminate (no item count exposed by Lance compaction). |
Graph (full init / reprocess) |
Determinate — pass 1 does a count-first filtered walk for an exact total; passes 2–6 are six known steps. |
Graph (incremental increment / update) |
Determinate when it runs; falls back to a full rebuild on schema change. |
Flags, TTY, and failure:
| Mode | Behaviour |
|---|---|
| TTY (default) | rich Live region — the multi-line phase display (spinner + bar + % + ETA). |
| Non-TTY / CI | rich auto-disables; concise throttled stderr lines (~every 5 s per phase + a terminal line) so CI logs still show progress. |
--quiet / -q |
Suppresses the entire progress stream (no header, phases, or footer). The stdout payload is unchanged. |
--verbose / -v |
Bypasses parsing; relays raw subprocess output verbatim (Lance warnings, brownfield events, the raw JCIRAG_PROGRESS protocol lines). No Live region. |
| Phase failure | The failing phase renders a red ✗; the footer carries (exit=N). The rich Live region is torn down cleanly so the error stays visible. |
Missing cocoindex / builder binary |
The pre-spawn stub emits a status=failed line; no phase is left hung at running. |
Behaviour change (this release).
installandupdatenow emit their indexing progress on stderr (previouslyinstallprinted indexing chatter to stdout, andupdateran the whole indexing step withquiet=True— completely silent). The wizard conversational stdout for both commands is otherwise unchanged.update's previously-ignored--quiet/--verboseflags, andinstall's previously-ignored--verboseflag, are now wired through (installalready honored--quiet).
| Variable | Role |
|---|---|
JAVA_CODEBASE_RAG_INDEX_DIR |
Root directory for Lance tables, the LadybugDB file code_graph.lbug, and default cocoindex state. Default: ./.java-codebase-rag/ under the resolved Java tree root. Overridden by --index-dir or YAML index_dir:. |
SBERT_MODEL / SBERT_DEVICE |
Embedding model and device; must match the index. Overridden by --embedding-model / --embedding-device or YAML embedding.model / embedding.device. |
JAVA_CODEBASE_RAG_DEBUG_CONTEXT |
Verbose stderr logging for context expansion (diagnostic). |
JAVA_CODEBASE_RAG_RUN_HEAVY |
Test-only gate for slow end-to-end indexer tests (pytest). |
Precedence (when a knob exists in more than one place): CLI flag > env var > YAML (.java-codebase-rag.yml) > built-in default.
Only the variable names in the table above are read as configuration.
Every subcommand accepts (all optional unless noted):
| Flag | Meaning |
|---|---|
--source-root DIR |
Java repository root (default: current working directory). |
--index-dir DIR |
Index directory (default: ./.java-codebase-rag under the resolved source root, or JAVA_CODEBASE_RAG_INDEX_DIR). |
--embedding-model / --embedding-device |
Override embedding resolution for subprocesses that honor env. |
LadybugDB always resolves to <index-dir>/code_graph.lbug.
Relative paths for diagnose-ignore <path> are resolved against the MCP/CLI project root helper (--source-root when given, else cwd semantics described in --help).
| Code | Typical meaning |
|---|---|
0 |
Success (payload may still report logical failures inside JSON for some commands — always parse stdout in scripts). |
1 |
Subcommand-specific failure (e.g. analyze-pr cannot read diff, graph missing, invalid path for diagnose-ignore). For reprocess, a requested phase subprocess ran and exited non-zero (see phases_run in stdout JSON). |
2 |
No subcommand / help printed; init refused because the index dir is non-empty; erase refused in non-TTY without --yes; meta when graph payload reports success: false; unhandled internal error in main. For reprocess, invalid flag combination (handled like other argparse errors), or a setup failure before any phase subprocess was spawned (phases_run: [] in the JSON payload — e.g. cocoindex binary missing next to this Python, flow file missing). |
Creates a new index (cocoindex catch-up from empty + full build_ast_graph.py). Refuses if code_graph.lbug or code_index_* Lance tables already exist under the resolved index dir (exit 2).
java-codebase-rag init --source-root /path/to/java/repo --index-dir /path/to/.java-codebase-rag --quietRuns cocoindex catch-up and incremental LadybugDB graph update. Only changed files and their single-hop dependents are re-parsed and re-written to the graph. Passes 5–6 (client/producer extraction and cross-service matching) run globally. Falls back to full reprocess if:
- No previous graph exists (first run)
- Graph schema is outdated (missing
source_fileon edges) - Previous incremental run crashed (crash marker detected)
- Dependent expansion exceeds 50 files
java-codebase-rag increment --source-root /path/to/java/repo --index-dir /path/to/.java-codebase-rag --quietFlags:
--vectors-only— runs only cocoindex catch-up; skips graph update and emits stale-graph warning. Use this when you want the old Lance-only behavior.
Migration note: After upgrading, run reprocess once to ensure edge tables have source_file columns (ontology version 17+).
Default (no extra flags): full Lance reprocess (cocoindex --full-reprocess) then full LadybugDB rebuild via build_ast_graph.py, in that order. This remains the recommended coherence operation when both stores might be out of date.
Selective flags (mutually exclusive):
--vectors-only— runs only the cocoindex full reprocess phase; does not invoke the graph builder.--graph-only— runs onlybuild_ast_graph.py; does not invoke cocoindex.
Passing both flags is rejected by argparse before any subprocess runs. The error is printed on stderr in this form (wording may vary slightly with Python/argparse version):
java-codebase-rag: argument --graph-only: not allowed with argument --vectors-only
Use java-codebase-rag reprocess --help for the live synopsis.
After a successful selective run, the CLI prints exactly one line to stderr naming the store that was not rebuilt. --quiet does not suppress this line (quiet only affects subprocess verbosity). There is no extra exit code for drift; scripts should treat stderr as informational.
The stdout JSON includes an additive list field phases_run: which phases actually spawned subprocesses, in order ("vectors", "graph"). Examples:
- Default success after both phases:
["vectors", "graph"] - Default run where cocoindex fails before the graph step:
["vectors"](graph never started) --vectors-onlysuccess:["vectors"]--graph-onlysuccess:["graph"]- Setup failure before any phase (missing cocoindex binary, missing bundled flow file, or pipeline preflight
126/127stubs):[]
Because exit_code and graph_exit_code can be null in multiple situations, prefer branching on phases_run first, then on the relevant per-phase exit field. Asymmetry: --vectors-only reports the cocoindex process in exit_code (and leaves graph_exit_code null); --graph-only leaves top-level exit_code null and reports the graph builder in graph_exit_code, so scripts that only read exit_code miss graph-only outcomes unless they branch on phases_run / graph_exit_code.
java-codebase-rag reprocess --source-root /path/to/java/repo --index-dir /path/to/.java-codebase-rag --quiet
java-codebase-rag reprocess --source-root /path/to/java/repo --index-dir /path/to/.java-codebase-rag --vectors-only --quiet
java-codebase-rag reprocess --source-root /path/to/java/repo --index-dir /path/to/.java-codebase-rag --graph-only --quietDeletes cocoindex state, the LadybugDB graph (code_graph.lbug), the graph builder's content-hash store (.graph_hashes.json), and Lance tables under the index dir. Requires --yes or interactive confirmation on a TTY. Non-TTY without --yes exits 2.
java-codebase-rag erase --source-root /path/to/java/repo --index-dir /path/to/.java-codebase-rag --yesHidden refresh alias
java-codebase-rag refresh runs reprocess. Prefer reprocess in scripts.
Graph metadata, ontology version, counts, edge_counts, plus resolved embedding fields and provenance (embedding_model_source, embedding_device_source, index_dir, ladybug_path, …).
java-codebase-rag meta --source-root /path/to/java/repo --index-dir /path/to/.java-codebase-ragLance table listing and embedding summary (same helper as the server’s table introspection).
java-codebase-rag tables --source-root /path/to/java/repo --index-dir /path/to/.java-codebase-ragExplains why a path is ignored or not ignored by the layered ignore rules (builtin + project .java-codebase-rag/ignore + nested ignore files + gitignore layers).
java-codebase-rag diagnose-ignore src/main/generated/Foo.java --source-root /path/to/java/repoLists or aggregates receiver-failure call sites stored as UnresolvedCallSite (not on CALLS after ontology 15 PR-3). Reasons: phantom_unresolved_receiver, chained_receiver.
java-codebase-rag unresolved-calls stats --by microservice --source-root /path/to/java/repo --index-dir /path/to/.java-codebase-rag
java-codebase-rag unresolved-calls list --method-id sym:... --limit 100 --source-root /path/to/java/repo --index-dir /path/to/.java-codebase-ragstats --by accepts reason, microservice, or caller_role (declaring type role of the caller method).
Maps a unified diff to changed symbols, blast radius, routes touched, and risk band. Requires a built LadybugDB graph at <index-dir>/code_graph.lbug.
Provide exactly one of:
--diff-file PATH--diff-stdin(read diff from stdin)
git diff > /tmp/pr.diff
java-codebase-rag analyze-pr --diff-file /tmp/pr.diff --source-root /path/to/java/repo --index-dir /path/to/.java-codebase-ragPaths in the diff should align with Symbol.filename layout in the graph (project-relative Java paths). Use this from PR-triage scripts or Cursor skills; PR mapping is CLI-only (the MCP exposes retrieval tools only).
java-codebase-rag meta --source-root /path/to/java/repo --index-dir /path/to/.java-codebase-rag | jq '{ontology_version, parse_errors, counts, edge_counts}'
java-codebase-rag tables --source-root /path/to/java/repo --index-dir /path/to/.java-codebase-rag | jq '.tables | keys'java-codebase-rag diagnose-ignore path/inside/repo/to/File.java --source-root /path/to/java/repojava-codebase-rag reprocess --source-root /path/to/java/repo --index-dir /path/to/.java-codebase-rag --quiet
java-codebase-rag meta --source-root /path/to/java/repo --index-dir /path/to/.java-codebase-rag | jq .ontology_versiongit diff origin/main...HEAD > /tmp/pr.diff
java-codebase-rag analyze-pr --diff-file /tmp/pr.diff --source-root /path/to/java/repo --index-dir /path/to/.java-codebase-rag | jq '{risk_score,risk_band,blast_radius_total}'Prefer java-codebase-rag reprocess --graph-only when you only need LadybugDB rebuilt from the current Lance snapshot. To run the graph builder without going through the CLI (advanced / scripting):
.venv/bin/python build_ast_graph.py --source-root /path/to/java/repo --ladybug-path /path/to/.java-codebase-rag/code_graph.lbug --verbose- README.md — env vars, MCP tool table, ignore layout.
- CODEBASE_REQUIREMENTS.md — repo layout, brownfield, when to rebuild.
- MANUAL-VERIFICATION-CHECKLIST.md — phased checks that mix CLI + MCP.