java-codebase-rag 0.6.5__tar.gz → 0.6.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. {java_codebase_rag-0.6.5/java_codebase_rag.egg-info → java_codebase_rag-0.6.6}/PKG-INFO +1 -1
  2. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/java_codebase_rag/cli.py +32 -8
  3. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6/java_codebase_rag.egg-info}/PKG-INFO +1 -1
  4. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/pyproject.toml +1 -1
  5. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_java_codebase_rag_cli.py +44 -2
  6. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/LICENSE +0 -0
  7. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/README.md +0 -0
  8. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/ast_java.py +0 -0
  9. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/brownfield_events.py +0 -0
  10. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/build_ast_graph.py +0 -0
  11. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/chunk_heuristics.py +0 -0
  12. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/graph_enrich.py +0 -0
  13. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/index_common.py +0 -0
  14. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/java_codebase_rag/__init__.py +0 -0
  15. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/java_codebase_rag/_fdlimit.py +0 -0
  16. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/java_codebase_rag/cli_format.py +0 -0
  17. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/java_codebase_rag/cli_progress.py +0 -0
  18. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/java_codebase_rag/config.py +0 -0
  19. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/java_codebase_rag/install_data/agents/explorer-rag-enhanced.md +0 -0
  20. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/java_codebase_rag/install_data/skills/explore-codebase/SKILL.md +0 -0
  21. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/java_codebase_rag/installer.py +0 -0
  22. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/java_codebase_rag/lance_optimize.py +0 -0
  23. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/java_codebase_rag/pipeline.py +0 -0
  24. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/java_codebase_rag/progress.py +0 -0
  25. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/java_codebase_rag.egg-info/SOURCES.txt +0 -0
  26. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/java_codebase_rag.egg-info/dependency_links.txt +0 -0
  27. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/java_codebase_rag.egg-info/entry_points.txt +0 -0
  28. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/java_codebase_rag.egg-info/requires.txt +0 -0
  29. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/java_codebase_rag.egg-info/top_level.txt +0 -0
  30. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/java_index_flow_lancedb.py +0 -0
  31. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/java_index_v1_common.py +0 -0
  32. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/java_ontology.py +0 -0
  33. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/ladybug_queries.py +0 -0
  34. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/mcp_hints.py +0 -0
  35. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/mcp_v2.py +0 -0
  36. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/path_filtering.py +0 -0
  37. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/pr_analysis.py +0 -0
  38. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/search_lancedb.py +0 -0
  39. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/server.py +0 -0
  40. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/setup.cfg +0 -0
  41. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_agent_skills_static.py +0 -0
  42. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_assign_endpoint_client_extraction.py +0 -0
  43. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_ast_graph_build.py +0 -0
  44. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_ast_java_calls.py +0 -0
  45. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_ast_java_capabilities.py +0 -0
  46. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_ast_java_thread_safety.py +0 -0
  47. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_bank_chat_brownfield_integration.py +0 -0
  48. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_brownfield_clients.py +0 -0
  49. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_brownfield_events.py +0 -0
  50. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_brownfield_overrides.py +0 -0
  51. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_brownfield_routes.py +0 -0
  52. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_call_edge_matching.py +0 -0
  53. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_call_edges_e2e.py +0 -0
  54. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_call_graph_receiver_resolution.py +0 -0
  55. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_call_graph_smoke_roundtrip.py +0 -0
  56. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_call_invariant.py +0 -0
  57. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_cli_progress_stdout_invariant.py +0 -0
  58. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_cli_quiet_parity.py +0 -0
  59. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_client_hint_recovery.py +0 -0
  60. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_client_node_extraction.py +0 -0
  61. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_client_role_rename.py +0 -0
  62. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_config.py +0 -0
  63. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_cross_service_resolution_flag.py +0 -0
  64. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_edge_navigation_doc.py +0 -0
  65. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_fd_limit.py +0 -0
  66. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_feign_not_exposer.py +0 -0
  67. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_graph_enrich.py +0 -0
  68. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_incremental_graph.py +0 -0
  69. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_installer.py +0 -0
  70. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_installer_integration.py +0 -0
  71. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_ladybug_queries.py +0 -0
  72. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_lance_optimize.py +0 -0
  73. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_lancedb_e2e.py +0 -0
  74. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_mcp_hints.py +0 -0
  75. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_mcp_server_project_root.py +0 -0
  76. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_mcp_tools.py +0 -0
  77. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_mcp_v2.py +0 -0
  78. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_mcp_v2_compose.py +0 -0
  79. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_meta_chain_core.py +0 -0
  80. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_microservice_scope.py +0 -0
  81. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_outgoing_call_extraction.py +0 -0
  82. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_packaging_metadata.py +0 -0
  83. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_path_filtering.py +0 -0
  84. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_pr_analysis.py +0 -0
  85. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_progress.py +0 -0
  86. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_resolve_routes_messaging_layer_c.py +0 -0
  87. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_route_extraction.py +0 -0
  88. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_schema_consistency.py +0 -0
  89. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_search_lancedb.py +0 -0
  90. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_search_lancedb_capability.py +0 -0
  91. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_string_value_atoms.py +0 -0
  92. {java_codebase_rag-0.6.5 → java_codebase_rag-0.6.6}/tests/test_vectors_progress.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: java-codebase-rag
3
- Version: 0.6.5
3
+ Version: 0.6.6
4
4
  Summary: MCP server for semantic + structural search over Java codebases
5
5
  Author: HumanBean17
6
6
  License-Expression: MIT
@@ -580,11 +580,33 @@ def _cmd_update(args: argparse.Namespace) -> int:
580
580
  )
581
581
 
582
582
 
583
+ def _rm_any(path: Path) -> None:
584
+ """Remove ``path`` whether it is a regular file, directory, or symlink.
585
+
586
+ ``code_graph.lbug`` is a single regular file in this repo, but kuzu may lay
587
+ the graph out as a directory; ``cocoindex.db`` is always a directory.
588
+ ``shutil.rmtree`` is a silent no-op on a regular file and ``Path.unlink``
589
+ raises ``IsADirectoryError`` on a directory, so a type-blind delete left
590
+ index artifacts on disk (issue #346). A symlinked directory is unlinked, not
591
+ recursed into, so the link target is never followed. Failures are warned to
592
+ stderr rather than swallowed, so erase does not report success while leaving
593
+ an artifact behind (the exact failure mode issue #346 reported).
594
+ """
595
+ try:
596
+ if path.is_dir() and not path.is_symlink():
597
+ shutil.rmtree(path)
598
+ elif path.exists() or path.is_symlink():
599
+ path.unlink(missing_ok=True)
600
+ except OSError as exc:
601
+ print(f"warning: failed to remove {path}: {exc}", file=sys.stderr)
602
+
603
+
583
604
  def _cmd_erase(args: argparse.Namespace) -> int:
584
605
  cfg = _resolved_from_ns(args)
585
606
  _startup_hints(cfg)
586
607
  cfg.apply_to_os_environ()
587
- to_describe: list[Path] = [cfg.ladybug_path, cfg.cocoindex_db]
608
+ graph_hashes_path = cfg.ladybug_path.parent / ".graph_hashes.json"
609
+ to_describe: list[Path] = [cfg.ladybug_path, cfg.cocoindex_db, graph_hashes_path]
588
610
  if cfg.index_dir.is_dir():
589
611
  try:
590
612
  import lancedb
@@ -621,13 +643,15 @@ def _cmd_erase(args: argparse.Namespace) -> int:
621
643
  )
622
644
  elif drop.returncode != 0:
623
645
  print(clip(drop.stderr, 4000), file=sys.stderr)
624
- if cfg.ladybug_path.exists():
625
- shutil.rmtree(cfg.ladybug_path, ignore_errors=True)
626
- if cfg.cocoindex_db.exists():
627
- try:
628
- cfg.cocoindex_db.unlink()
629
- except OSError:
630
- pass
646
+ # Remove the LadybugDB graph, the cocoindex state store, and the graph
647
+ # builder's content-hash store. Each is removed by type (see _rm_any):
648
+ # code_graph.lbug is a file here but may be a dir under kuzu, while
649
+ # cocoindex.db is a directory — a type-blind delete silently no-oped on
650
+ # one or the other, and .graph_hashes.json was never targeted at all
651
+ # (issue #346).
652
+ _rm_any(cfg.ladybug_path)
653
+ _rm_any(cfg.cocoindex_db)
654
+ _rm_any(graph_hashes_path)
631
655
  if cfg.index_dir.is_dir():
632
656
  try:
633
657
  import lancedb
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: java-codebase-rag
3
- Version: 0.6.5
3
+ Version: 0.6.6
4
4
  Summary: MCP server for semantic + structural search over Java codebases
5
5
  Author: HumanBean17
6
6
  License-Expression: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "java-codebase-rag"
7
- version = "0.6.5"
7
+ version = "0.6.6"
8
8
  description = "MCP server for semantic + structural search over Java codebases"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -109,6 +109,35 @@ def test_cli_erase_succeeds_with_yes_flag(tmp_path: Path) -> None:
109
109
  assert proc.returncode == 0, proc.stderr + proc.stdout
110
110
 
111
111
 
112
+ def test_erase_removes_graph_file_cocoindex_dir_and_hash_store(tmp_path: Path) -> None:
113
+ """erase must delete code_graph.lbug (file), cocoindex.db (dir), .graph_hashes.json.
114
+
115
+ Regression for issue #346: a type-blind delete left both on disk.
116
+ shutil.rmtree is a silent no-op on a regular file (code_graph.lbug), and
117
+ Path.unlink raises IsADirectoryError on cocoindex.db (a directory) — both
118
+ swallowed — and .graph_hashes.json was never targeted. The follow-up init
119
+ then refused because code_graph.lbug survived.
120
+ """
121
+ idx = tmp_path / "erase_artifacts"
122
+ idx.mkdir()
123
+ # Real on-disk layout: graph is a single FILE, cocoindex state is a DIR.
124
+ (idx / "code_graph.lbug").write_bytes(b"fake-kuzu-db")
125
+ (idx / "cocoindex.db").mkdir()
126
+ (idx / "cocoindex.db" / "state.json").write_text("{}", encoding="utf-8")
127
+ (idx / ".graph_hashes.json").write_text("{}", encoding="utf-8")
128
+ env = os.environ.copy()
129
+ env["JAVA_CODEBASE_RAG_INDEX_DIR"] = str(idx)
130
+ env["JAVA_CODEBASE_RAG_SOURCE_ROOT"] = str(tmp_path)
131
+ proc = _run_cli(
132
+ ["erase", "--source-root", str(tmp_path), "--index-dir", str(idx), "--yes"],
133
+ env=env,
134
+ )
135
+ assert proc.returncode == 0, proc.stderr + proc.stdout
136
+ assert not (idx / "code_graph.lbug").exists(), "erase left code_graph.lbug on disk"
137
+ assert not (idx / "cocoindex.db").exists(), "erase left cocoindex.db/ on disk"
138
+ assert not (idx / ".graph_hashes.json").exists(), "erase left .graph_hashes.json on disk"
139
+
140
+
112
141
  def test_embedding_model_precedence_cli_over_env_over_yaml_over_default(
113
142
  tmp_path: Path, monkeypatch: pytest.MonkeyPatch
114
143
  ) -> None:
@@ -377,21 +406,34 @@ def test_legacy_env_var_set_emits_stderr_hint(monkeypatch: pytest.MonkeyPatch, t
377
406
 
378
407
  @pytest.mark.skipif(not _cocoindex_available(), reason="cocoindex not installed in venv")
379
408
  def test_init_after_erase_succeeds(corpus_root: Path, tmp_path: Path) -> None:
409
+ """Build a real index, erase it, then init again from a clean slate.
410
+
411
+ Regression for issue #346: the previous body erased an *empty* index dir and
412
+ then inited, so it never exercised "erase a real graph -> re-init" and stayed
413
+ green while erase silently left code_graph.lbug on disk.
414
+ """
380
415
  idx = tmp_path / "lifecycle_idx"
381
416
  idx.mkdir(parents=True)
382
417
  env = os.environ.copy()
383
418
  env["JAVA_CODEBASE_RAG_INDEX_DIR"] = str(idx)
384
419
  env["JAVA_CODEBASE_RAG_SOURCE_ROOT"] = str(corpus_root.resolve())
420
+ init1 = _run_cli(
421
+ ["init", "--source-root", str(corpus_root), "--index-dir", str(idx), "--quiet"],
422
+ env=env,
423
+ )
424
+ assert init1.returncode == 0, init1.stdout + init1.stderr
425
+ assert (idx / "code_graph.lbug").exists(), "init did not build code_graph.lbug"
385
426
  e1 = _run_cli(
386
427
  ["erase", "--source-root", str(corpus_root), "--index-dir", str(idx), "--yes"],
387
428
  env=env,
388
429
  )
389
430
  assert e1.returncode == 0, e1.stderr
390
- init = _run_cli(
431
+ assert not (idx / "code_graph.lbug").exists(), "erase left code_graph.lbug on disk"
432
+ init2 = _run_cli(
391
433
  ["init", "--source-root", str(corpus_root), "--index-dir", str(idx), "--quiet"],
392
434
  env=env,
393
435
  )
394
- assert init.returncode == 0, init.stdout + init.stderr
436
+ assert init2.returncode == 0, init2.stdout + init2.stderr
395
437
 
396
438
 
397
439
  @pytest.mark.skipif(not _cocoindex_available(), reason="cocoindex not installed in venv")