Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 29 additions & 2 deletions src/java_codebase_rag/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,38 @@ def _emit_reprocess_selective_tty(*, mode: str) -> None:
print("Skipped: vectors (use `java-codebase-rag reprocess --vectors-only` or `reprocess` to refresh)")


def _reprocess_success_message(mode: str | None, payload: dict[str, Any]) -> str:
"""Concise message for a successful reprocess.

Prefers an explicit ``message`` set by the pipeline (e.g. the graph-only-
install note from ``run_refresh_pipeline``); otherwise derives from the
selective mode. Mirrors ``init``/``increment``, which emit a one-line
success payload rather than re-dumping captured subprocess logs.
"""
explicit = payload.get("message")
if isinstance(explicit, str) and explicit:
return explicit
if mode == "vectors":
return "reprocess completed (vectors only; graph not rebuilt)"
if mode == "graph":
return "reprocess completed (graph only; vectors not rebuilt)"
return "reprocess completed"


def _emit_reprocess_outcome(payload: dict[str, Any], *, selective_tty_mode: str | None = None) -> None:
if payload.get("success") and selective_tty_mode and sys.stdout.isatty():
if not payload.get("success"):
# Failure: emit the full payload so captured subprocess stdout/stderr
# (cocoindex/graph logs) survive for debugging.
_emit(payload)
return
# Success: the progress renderer / stderr already surfaced the phase logs,
# so emit a concise structured payload (matching init/increment) instead of
# re-dumping them as JSON noise. In a TTY the partial modes additionally
# print a one-line Rebuilt/Skipped summary.
if selective_tty_mode and sys.stdout.isatty():
_emit_reprocess_selective_tty(mode=selective_tty_mode)
return
_emit(payload)
_emit({"success": True, "message": _reprocess_success_message(selective_tty_mode, payload)})


_PIPELINE_SEP = "\u00b7"
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"exit_code": 0, "graph_exit_code": 0, "graph_stderr": "", "graph_stdout": "", "message": null, "optimize_error": null, "phases_run": ["vectors", "graph"], "stderr": "", "stdout": "", "success": true}
{"message": "reprocess completed", "success": true}
6 changes: 2 additions & 4 deletions tests/package/test_cli_progress_stdout_invariant.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ def test_cli_lifecycle_stdout_invariant_init_increment_reprocess_when_cocoindex(
inc_payload = json.loads(r_inc.stdout)
assert inc_payload == {
"success": True,
"message": "increment completed (Lance only; graph may be stale — see stderr)",
"message": "increment completed (Lance + graph updated)",
}

r_rep = _run_cli(
Expand All @@ -260,9 +260,7 @@ def test_cli_lifecycle_stdout_invariant_init_increment_reprocess_when_cocoindex(
)
assert r_rep.returncode == 0, r_rep.stderr + r_rep.stdout
rep_payload = json.loads(r_rep.stdout)
assert rep_payload.get("success") is True
assert isinstance(rep_payload.get("stdout"), str)
assert isinstance(rep_payload.get("graph_stderr"), str)
assert rep_payload == {"success": True, "message": "reprocess completed"}


def test_pipeline_footer_reflects_exception_before_propagate(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
Expand Down
4 changes: 2 additions & 2 deletions tests/package/test_java_codebase_rag_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -979,7 +979,7 @@ def isatty(self) -> bool:
)
assert rc == 0
payload = json.loads(nout.getvalue())
assert payload["phases_run"] == ["vectors"]
assert payload == {"success": True, "message": "reprocess completed (vectors only; graph not rebuilt)"}


def test_reprocess_graph_only_skips_vectors(
Expand Down Expand Up @@ -1009,7 +1009,7 @@ def fake_graph(**_kwargs: object) -> subprocess.CompletedProcess[str]:
["reprocess", "--source-root", str(tmp_path), "--index-dir", str(idx), "--graph-only"],
)
assert rc == 0
assert json.loads(out.getvalue())["phases_run"] == ["graph"]
assert json.loads(out.getvalue()) == {"success": True, "message": "reprocess completed (graph only; vectors not rebuilt)"}


def test_reprocess_mutually_exclusive_flags_rejected(tmp_path: Path) -> None:
Expand Down
Loading