java-codebase-rag 0.6.7__py3-none-any.whl → 0.9.0__py3-none-any.whl

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 (34) hide show
  1. ast_java.py +8 -3
  2. build_ast_graph.py +72 -16
  3. graph_enrich.py +2 -1
  4. graph_types.py +133 -0
  5. java_codebase_rag/_fdlimit.py +10 -2
  6. java_codebase_rag/_stdio.py +32 -0
  7. java_codebase_rag/cli.py +149 -25
  8. java_codebase_rag/config.py +128 -9
  9. java_codebase_rag/install_data/agents/explorer-rag-cli.md +148 -0
  10. java_codebase_rag/install_data/agents/explorer-rag-enhanced.md +78 -232
  11. java_codebase_rag/install_data/skills/explore-codebase/SKILL.md +49 -88
  12. java_codebase_rag/install_data/skills/explore-codebase-cli/SKILL.md +183 -0
  13. java_codebase_rag/installer.py +720 -107
  14. java_codebase_rag/jrag.py +4405 -0
  15. java_codebase_rag/jrag_envelope.py +1085 -0
  16. java_codebase_rag/jrag_hints.py +204 -0
  17. java_codebase_rag/jrag_render.py +697 -0
  18. java_codebase_rag/lance_optimize.py +18 -0
  19. java_codebase_rag/pipeline.py +34 -0
  20. {java_codebase_rag-0.6.7.dist-info → java_codebase_rag-0.9.0.dist-info}/METADATA +137 -94
  21. java_codebase_rag-0.9.0.dist-info/RECORD +43 -0
  22. {java_codebase_rag-0.6.7.dist-info → java_codebase_rag-0.9.0.dist-info}/WHEEL +1 -1
  23. {java_codebase_rag-0.6.7.dist-info → java_codebase_rag-0.9.0.dist-info}/entry_points.txt +1 -0
  24. {java_codebase_rag-0.6.7.dist-info → java_codebase_rag-0.9.0.dist-info}/top_level.txt +2 -0
  25. java_index_flow_lancedb.py +34 -19
  26. java_ontology.py +12 -0
  27. ladybug_queries.py +233 -52
  28. mcp_hints.py +6 -6
  29. mcp_v2.py +276 -632
  30. resolve_service.py +649 -0
  31. search_lancedb.py +159 -4
  32. server.py +31 -12
  33. java_codebase_rag-0.6.7.dist-info/RECORD +0 -34
  34. {java_codebase_rag-0.6.7.dist-info → java_codebase_rag-0.9.0.dist-info}/licenses/LICENSE +0 -0
search_lancedb.py CHANGED
@@ -41,6 +41,11 @@ JAVA_ENRICHED_COLUMNS: tuple[str, ...] = (
41
41
  "capabilities",
42
42
  )
43
43
 
44
+ # Over-fetch multiplier for dedup: fetch 4x to absorb per-FQN chunk multiplicity
45
+ # so that after collapsing by primary_type_fqn, a page stays full and the +1
46
+ # truncation sentinel survives. The formula: need = max((limit + offset) * 4, limit + offset + 1)
47
+ DEDUP_OVERFETCH = 4
48
+
44
49
  VECTOR_COLUMN = "embedding"
45
50
  _FTS_READY: set[tuple[str, str]] = set()
46
51
  _FTS_LOCK = threading.Lock()
@@ -201,6 +206,14 @@ _ROLE_SCORE_WEIGHTS: dict[str, float] = {
201
206
  "DTO": -0.08,
202
207
  }
203
208
 
209
+ # Theoretical maximum for hybrid composite score (used for display normalization).
210
+ # Hybrid sort metric: raw_rrf * (import_factor if import_heavy else 1)
211
+ # + role_weight + symbol_bonus
212
+ # where raw_rrf ≤ 2/(k+1) for 2-list RRF, role_weight ≤ max(_ROLE_SCORE_WEIGHTS),
213
+ # and symbol_bonus ≤ _SYMBOL_MATCH_BONUS_CAP + _TYPE_MATCH_BONUS_CAP + _ACTION_VERB_BONUS.
214
+ # The import factor is ≤ 1, so we use the raw max (2/61).
215
+ _HYBRID_SCORE_MAX = (2.0 / 61.0) + max(_ROLE_SCORE_WEIGHTS.values()) + _SYMBOL_MATCH_BONUS_CAP + _TYPE_MATCH_BONUS_CAP + _ACTION_VERB_BONUS
216
+
204
217
 
205
218
  def _query_tokens(query: str) -> set[str]:
206
219
  """Lowercased alpha-only tokens from the query, minus stopwords, len >= 3.
@@ -353,7 +366,7 @@ def _hybrid_sort_key(r: dict) -> float:
353
366
  comps["hybrid_rrf"] = s
354
367
  if r.get("_hints", {}).get("import_heavy"):
355
368
  s *= _IMPORT_HYBRID_SCORE_FACTOR
356
- comps["import_penalty"] = _IMPORT_HYBRID_SCORE_FACTOR
369
+ comps["import_penalty"] = 1.0 - _IMPORT_HYBRID_SCORE_FACTOR
357
370
  s += _role_weight(r)
358
371
  s += float(comps.get("symbol_bonus", 0.0))
359
372
  return -s
@@ -376,7 +389,8 @@ def explain_score_components(
376
389
  comps = {}
377
390
  parts: list[str] = []
378
391
  if hybrid:
379
- rrf = comps.get("hybrid_rrf")
392
+ # Prefer rrf_raw (added by PR-SEARCH-1a) for explanation
393
+ rrf = comps.get("rrf_raw") or comps.get("hybrid_rrf")
380
394
  if rrf is not None:
381
395
  parts.append(f"rrf={float(rrf):.3f}")
382
396
  else:
@@ -403,6 +417,46 @@ def l2_distance_to_score(distance: float) -> float:
403
417
  return 1.0 - distance * distance / 2.0
404
418
 
405
419
 
420
+ def _effective_distance(comps: dict[str, float]) -> float:
421
+ """Compute the adjusted distance used for sorting.
422
+
423
+ Matches _vector_sort_key logic: distance + import_penalty - role_weight - symbol_bonus.
424
+ """
425
+ d = comps.get("distance", 0.0)
426
+ d += comps.get("import_penalty", 0.0)
427
+ d -= comps.get("role_weight", 0.0)
428
+ d -= comps.get("symbol_bonus", 0.0)
429
+ return d
430
+
431
+
432
+ def _clamp01(x: float) -> float:
433
+ """Clamp a value to the [0.0, 1.0] range."""
434
+ if x < 0.0:
435
+ return 0.0
436
+ if x > 1.0:
437
+ return 1.0
438
+ return x
439
+
440
+
441
+ def _hybrid_post_sort_normalization(rows: list[dict]) -> None:
442
+ """Set honest displayed scores for hybrid search after sorting.
443
+
444
+ Reconstructs the composite score (raw_rrf * import_factor + role_weight + symbol_bonus)
445
+ and normalizes by _HYBRID_SCORE_MAX to ensure rank-monotonicity.
446
+
447
+ Mutates rows in-place, replacing _score with the normalized value.
448
+ """
449
+ for r in rows:
450
+ comps = r.setdefault("_score_components", {})
451
+ raw = comps.get("hybrid_rrf", 0.0)
452
+ comps["rrf_raw"] = raw # preserve raw RRF for --explain. NOTE: when graph_expand + hybrid combine (Phase 2), _rrf_merge below overwrites this with graph-RRF, so --explain would show graph-RRF not hybrid-RRF.
453
+ s = raw
454
+ if r.get("_hints", {}).get("import_heavy"):
455
+ s *= _IMPORT_HYBRID_SCORE_FACTOR
456
+ s += comps.get("role_weight", 0.0) + comps.get("symbol_bonus", 0.0)
457
+ r["_score"] = _clamp01(s / _HYBRID_SCORE_MAX)
458
+
459
+
406
460
  def _escape_like_fragment(s: str) -> str:
407
461
  return s.replace("'", "''")
408
462
 
@@ -534,6 +588,15 @@ def _search_one_table(
534
588
  for r in rows:
535
589
  r["_kind"] = kind
536
590
  r["_hybrid"] = False
591
+ # Populate `_score` from `_distance` so the SearchHit.score reflects
592
+ # relevance. The hybrid branch sets `_score` from `_relevance_score`
593
+ # above; without this, non-hybrid (default) search left `_score` unset
594
+ # and mcp_v2._row_to_search_hit fell back to 0.0 for EVERY hit —
595
+ # ranking still worked (the sort key uses `_distance` directly) but the
596
+ # exposed score was always 0.0, making results look unranked.
597
+ d = r.get("_distance")
598
+ if d is not None:
599
+ r["_score"] = l2_distance_to_score(float(d))
537
600
  r["start"] = coerce_position_field(r.get("start"))
538
601
  r["end"] = coerce_position_field(r.get("end"))
539
602
  return rows
@@ -781,9 +844,72 @@ def _rrf_merge(
781
844
  existing["_rrf_score"] = float(existing.get("_rrf_score", 0.0)) + contribution
782
845
  merged = list(pool.values())
783
846
  merged.sort(key=lambda r: -float(r.get("_rrf_score", 0.0)))
847
+ # Normalize displayed _rrf_score to [0,1] by theoretical max
848
+ # RRF max = Σ weight·1/(k+rank+1); theoretical max when all rows are rank 0
849
+ # with weight 1.0 = num_lists / (k + 1)
850
+ num_lists = len(lists)
851
+ max_rrf = num_lists / (k + 1)
852
+ for r in merged:
853
+ raw_score = float(r.get("_rrf_score", 0.0))
854
+ comps = r.setdefault("_score_components", {})
855
+ comps["rrf_raw"] = raw_score
856
+ r["_rrf_score"] = _clamp01(raw_score / max_rrf)
784
857
  return merged
785
858
 
786
859
 
860
+ def _dedup_by_fqn(rows: list[dict], dedup_by_fqn: bool = True) -> list[dict]:
861
+ """Deduplicate rows by primary_type_fqn (java table only).
862
+
863
+ When dedup_by_fqn is True, collapses multiple chunks of the same
864
+ primary_type_fqn into one row (first-seen-wins, since rows are pre-sorted
865
+ so the first is the best chunk). Each survivor gets a _chunks_collapsed
866
+ field (>=1) counting how many rows were collapsed into it.
867
+
868
+ Rows without primary_type_fqn (sql/yaml tables) get a unique __id:<id>
869
+ key so they pass through unchanged (each row is unique).
870
+
871
+ When dedup_by_fqn is False, returns rows unchanged (regression guard).
872
+ """
873
+ if not dedup_by_fqn:
874
+ # Non-dedup path: return unchanged, byte-identical to prior behavior
875
+ return rows
876
+
877
+ deduped: list[dict] = []
878
+ seen_keys: dict[str, dict] = {}
879
+ collapsed_counts: dict[str, int] = {}
880
+
881
+ for row in rows:
882
+ # Build dedup key: primary_type_fqn for java rows, unique __id:<id> for sql/yaml
883
+ fqn = row.get("primary_type_fqn")
884
+ if fqn:
885
+ key = str(fqn)
886
+ else:
887
+ # sql/yaml rows have no primary_type_fqn → unique key per row
888
+ row_id = row.get("id") or id(row)
889
+ key = f"__id:{row_id}"
890
+
891
+ if key not in seen_keys:
892
+ # First occurrence: keep it
893
+ seen_keys[key] = row
894
+ collapsed_counts[key] = 1
895
+ deduped.append(row)
896
+ else:
897
+ # Duplicate: increment collapse count, discard this row
898
+ collapsed_counts[key] += 1
899
+
900
+ # Annotate each survivor with _chunks_collapsed
901
+ for row in deduped:
902
+ fqn = row.get("primary_type_fqn")
903
+ if fqn:
904
+ key = str(fqn)
905
+ else:
906
+ row_id = row.get("id") or id(row)
907
+ key = f"__id:{row_id}"
908
+ row["_chunks_collapsed"] = collapsed_counts[key]
909
+
910
+ return deduped
911
+
912
+
787
913
  def run_search(
788
914
  query: str,
789
915
  *,
@@ -810,6 +936,7 @@ def run_search(
810
936
  exclude_roles: list[str] | None = None,
811
937
  capability: str | None = None,
812
938
  capability_in: list[str] | None = None,
939
+ dedup_by_fqn: bool = False,
813
940
  ) -> list[dict]:
814
941
  effective_hybrid = hybrid
815
942
  effective_fts = fts_text
@@ -843,7 +970,16 @@ def run_search(
843
970
  fts_for_hybrid = effective_fts if effective_fts is not None else query
844
971
 
845
972
  db = lancedb.connect(uri)
846
- need = max(limit + offset, 1)
973
+ if dedup_by_fqn:
974
+ # Over-fetch to absorb per-FQN chunk multiplicity: fetch 4x so that
975
+ # after collapsing, the page stays full and the +1 truncation sentinel survives.
976
+ # The 4× factor assumes typical per-FQN chunk multiplicity; a single type with
977
+ # many high-ranking chunks (e.g. generated/God classes) could starve the page or
978
+ # make the +1 truncation sentinel unreliable; Phase 1 may revisit adaptive over-fetch (plan risk #1).
979
+ need = max((limit + offset) * DEDUP_OVERFETCH, limit + offset + 1)
980
+ else:
981
+ # Non-dedup path: exact fetch as before
982
+ need = max(limit + offset, 1)
847
983
 
848
984
  extra_java = _build_extra_predicates(
849
985
  columns=_table_columns(uri, TABLES["java"], db),
@@ -853,7 +989,7 @@ def run_search(
853
989
  capability=capability, capability_in=capability_in,
854
990
  ) if "java" in table_keys else []
855
991
 
856
- skip_role_weight = bool(role or role_in)
992
+ skip_role_weight = bool(role or role_in or exclude_roles)
857
993
  query_toks = _query_tokens(query)
858
994
 
859
995
  if len(table_keys) == 1:
@@ -878,8 +1014,15 @@ def run_search(
878
1014
  _apply_symbol_bonus(rows, query_toks)
879
1015
  if effective_hybrid:
880
1016
  rows.sort(key=_hybrid_sort_key)
1017
+ # Hybrid: set honest displayed score from composite sort metric, clamped to [0,1]
1018
+ _hybrid_post_sort_normalization(rows)
881
1019
  else:
882
1020
  rows.sort(key=_vector_sort_key)
1021
+ # Vector: set honest displayed score from adjusted distance, clamped to [0,1]
1022
+ for r in rows:
1023
+ comps = r.setdefault("_score_components", {})
1024
+ effective_dist = _effective_distance(comps)
1025
+ r["_score"] = _clamp01(l2_distance_to_score(effective_dist))
883
1026
 
884
1027
  if graph_expand and key == "java" and expand_depth > 0:
885
1028
  rows = _graph_expand_merge(
@@ -893,6 +1036,9 @@ def run_search(
893
1036
  ladybug_path=ladybug_path,
894
1037
  )
895
1038
 
1039
+ # Dedup by primary_type_fqn after all sorting/merging, before windowing
1040
+ rows = _dedup_by_fqn(rows, dedup_by_fqn=dedup_by_fqn)
1041
+
896
1042
  window = rows[offset : offset + limit]
897
1043
  if context_neighbors > 0 and key == "java":
898
1044
  _attach_neighbor_context(window, db=db, neighbors=context_neighbors, uri=uri)
@@ -922,6 +1068,15 @@ def run_search(
922
1068
  r["_skip_role_weight"] = True
923
1069
  _apply_symbol_bonus(merged, query_toks)
924
1070
  merged.sort(key=_vector_sort_key)
1071
+ # Vector: set honest displayed score from adjusted distance, clamped to [0,1]
1072
+ for r in merged:
1073
+ comps = r.setdefault("_score_components", {})
1074
+ effective_dist = _effective_distance(comps)
1075
+ r["_score"] = _clamp01(l2_distance_to_score(effective_dist))
1076
+
1077
+ # Dedup by primary_type_fqn after all sorting/merging, before windowing
1078
+ merged = _dedup_by_fqn(merged, dedup_by_fqn=dedup_by_fqn)
1079
+
925
1080
  window = merged[offset : offset + limit]
926
1081
  if context_neighbors > 0:
927
1082
  _attach_neighbor_context(window, db=db, neighbors=context_neighbors, uri=uri)
server.py CHANGED
@@ -26,7 +26,8 @@ from java_codebase_rag.config import (
26
26
  from ladybug_queries import LadybugGraph, resolve_ladybug_path
27
27
  from mcp.server.fastmcp import FastMCP
28
28
  from pydantic import BaseModel, Field
29
- from search_lancedb import TABLES
29
+ # NOTE: search_lancedb.TABLES is imported lazily in list_code_index_tables_payload() — it
30
+ # pulls lancedb/torch and is unavailable on graph-only installs (macOS Intel).
30
31
 
31
32
  _COCOINDEX_TARGET = "java_index_flow_lancedb.py:JavaCodeIndexLance"
32
33
  _INSTRUCTIONS = (
@@ -296,12 +297,19 @@ def _graph_meta_output() -> GraphMetaOutput:
296
297
 
297
298
 
298
299
  def list_code_index_tables_payload() -> IndexInfoOutput:
300
+ try:
301
+ from search_lancedb import TABLES
302
+
303
+ tables = dict(TABLES)
304
+ except ImportError:
305
+ # Graph-only install (no lancedb): no Lance vector tables exist.
306
+ tables = {}
299
307
  return IndexInfoOutput(
300
308
  lancedb_uri=_resolve_lancedb_uri(),
301
309
  embedding_model=resolved_sbert_model_for_process_env(SBERT_MODEL),
302
310
  project_root=str(_project_root()),
303
311
  cocoindex_target=_COCOINDEX_TARGET,
304
- tables=dict(TABLES),
312
+ tables=tables,
305
313
  graph=_graph_meta_output(),
306
314
  )
307
315
 
@@ -499,11 +507,12 @@ def create_mcp_server() -> FastMCP:
499
507
  "Ranked chunk retrieval over content tables (java/sql/yaml); `query` is opaque text (natural language or code "
500
508
  "fragments) and results are score-ranked, not boolean-matched. For graph-structured listing "
501
509
  "(symbols/routes/clients/producers) use `find`, not `search`. Optional `filter` uses the same NodeFilter "
502
- "schema as `find` but only **symbol-applicable** fields apply — others return success=false. Wildcards "
503
- "(`*`, `?`) in prefix fields are rejected—use ranked `query` text instead. There is **no** "
510
+ "schema as `find` but only **symbol-applicable** fields apply — others return success=false. Substring "
511
+ "fields match literally (no `*`/`?` metacharacters)—use ranked `query` text for fuzzy discovery. There is **no** "
504
512
  "structured DSL inside `query`; structured predicates belong in `find`. "
505
- "For identifier-shaped lookups (FQN, id prefix, route/client identifiers, …), use `resolve` first; "
513
+ "For identifier-shaped lookups (FQN, id, route/client identifiers, …), use `resolve` first; "
506
514
  "use `search` for natural-language or ranked fuzzy discovery. "
515
+ "Set `explain=true` to include score breakdown per hit. "
507
516
  "Successful responses echo `limit`/`offset`."
508
517
  ),
509
518
  )
@@ -530,6 +539,14 @@ def create_mcp_server() -> FastMCP:
530
539
  "predicate. Unknown keys or populated fields not applicable to symbols return success=false."
531
540
  ),
532
541
  ),
542
+ explain: bool = Field(
543
+ default=False,
544
+ description="If true, include score_components in each SearchHit (breakdown of distance/rrf, role, symbol, import_penalty).",
545
+ ),
546
+ chunks: bool = Field(
547
+ default=False,
548
+ description="If true, show every chunk (default collapses to one row per symbol/type).",
549
+ ),
533
550
  ) -> mcp_v2.SearchOutput:
534
551
  scoped_filter = _scope_manager.apply_auto_scope(filter) if _scope_manager else filter
535
552
  return await asyncio.to_thread(
@@ -541,20 +558,22 @@ def create_mcp_server() -> FastMCP:
541
558
  offset,
542
559
  path_contains,
543
560
  scoped_filter,
561
+ explain,
544
562
  None,
563
+ not chunks, # dedup=True by default; chunks=True opts out
545
564
  )
546
565
 
547
566
  @mcp.tool(
548
567
  name="find",
549
568
  description=(
550
569
  "Exact structured listing for one node kind. Per-kind applicable fields: **symbol** — "
551
- "microservice, module, role, exclude_roles, annotation, capability, fqn_prefix, symbol_kind, symbol_kinds; "
552
- "**route** — microservice, module, http_method, path_prefix, framework; **client** — microservice, module, "
553
- "source_layer, client_kind, target_service, target_path_prefix, http_method; **producer** — microservice, "
554
- "module, source_layer, producer_kind, topic_prefix. "
570
+ "microservice, module, role, exclude_roles, annotation, capability, fqn_contains, symbol_kind, symbol_kinds; "
571
+ "**route** — microservice, module, http_method, path_contains, framework; **client** — microservice, module, "
572
+ "source_layer, client_kind, target_service, target_path_contains, http_method; **producer** — microservice, "
573
+ "module, source_layer, producer_kind, topic_contains. "
555
574
  "`role` is singular and `exclude_roles` plural; `capability` is a functional tag assigned during indexing. "
556
- "`fqn_prefix` is a prefix predicate — for exact FQN or id lookup use `resolve`/`describe`. "
557
- "Wildcards in prefix fields are rejected. An empty filter (`{}`) or `filter=None` means no predicate (all nodes of "
575
+ "`fqn_contains` is a substring predicate — for exact FQN or id lookup use `resolve`/`describe`. "
576
+ "Substring fields match literally (Cypher `CONTAINS`); no wildcard metacharacters. An empty filter (`{}`) or `filter=None` means no predicate (all nodes of "
558
577
  "that kind; use pagination). Unknown keys or inapplicable populated fields return success=false. "
559
578
  "Successful responses echo `limit`/`offset`."
560
579
  ),
@@ -620,7 +639,7 @@ def create_mcp_server() -> FastMCP:
620
639
  "`direction` and `edge_types` have no defaults; an empty `edge_types` fails. The CALLS-only features — "
621
640
  "`edge_filter`, `include_unresolved`, `dedup_calls` — each require `edge_types=['CALLS']`; `edge_filter` and "
622
641
  "`include_unresolved` are mutually exclusive. Violating a precondition (wrong CALLS context, composed/override "
623
- "keys on an ineligible origin or with `direction='in'`, wildcards in prefix fields, unknown filter keys) returns "
642
+ "keys on an ineligible origin or with `direction='in'`, unknown filter keys) returns "
624
643
  "success=false with a message; `dedup_calls` with other edge_types is a silent no-op. "
625
644
  "Optional `filter` applies to each neighbor endpoint row; populated fields must be applicable to that "
626
645
  "neighbor's kind—mixed-kind result sets fail on the first inapplicable neighbor (per-neighbor strict frame). "
@@ -1,34 +0,0 @@
1
- ast_java.py,sha256=Paee3ZV9G5iy8LqfkVq0Ah_1fV0k632oS5JPkiWzwB8,99206
2
- brownfield_events.py,sha256=yxXkKDgMb3VPtaiakGzncHM_EGnda8xIue6w90yYp8s,2055
3
- build_ast_graph.py,sha256=jubb9Ex_6B3ktsInqNkk-EksBtQjofoFhE92lmHr308,169659
4
- chunk_heuristics.py,sha256=aQk2NOKxzUdqoUAJUO3G3LE0MN_bYZWNLQ0tkmj5uts,1813
5
- graph_enrich.py,sha256=W_OQK7YRU1K8wi-vfrxZWUd-EErTqWx840UBrhVpNsM,62788
6
- index_common.py,sha256=HT6FKHFJ084eFvd3fR1j8z8gf4eWoPHVW8GXLpw464I,285
7
- java_index_flow_lancedb.py,sha256=JHdRWDZoZ3wnxi8NNG2ck8zEmSALHB2UVB1N8TSvlmg,24109
8
- java_index_v1_common.py,sha256=nF1KrSqboF_RRvWerG9knRRFmWwsrG_CvhgnsoZ8KqA,1154
9
- java_ontology.py,sha256=71bCLDNvMy0SpZPzSR5apJ0qJXNd6y5ggkLdBEw_PFo,16682
10
- ladybug_queries.py,sha256=7vSP7WsUKQYXHFenBMlCdpUFed39h3oul-WRkf55YVc,90330
11
- mcp_hints.py,sha256=3swh05LSiWur3tm3-yssndBsLxIxFhy501kBtJI8jJ0,42509
12
- mcp_v2.py,sha256=S8PiVGDlyI7cvTmeMdQobhKUxWqKoY2YxXXr4pu9lQI,80348
13
- path_filtering.py,sha256=R--XzI51LXBu5IBKMCnJWbkNr6I5d-SDmltyQQnWco0,17674
14
- pr_analysis.py,sha256=zrmZZD5yotJtM02Kif6_jgI_oeformOao793akp0N6Y,18394
15
- search_lancedb.py,sha256=ga_qySeCzA6hCibxUPXpCbTxW9mCjTdwirMhMhfNCz4,36801
16
- server.py,sha256=DcJwocSknBy0vwsUvYiC5hr-hrD_rRT-u9_DmuRTC9k,35035
17
- java_codebase_rag/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
18
- java_codebase_rag/_fdlimit.py,sha256=WroFdfSNbcriKok6q8znTf74dqlznxea_1Fd5bHl_3o,1930
19
- java_codebase_rag/cli.py,sha256=zMZcjVKRgfv7VpTb0h1vjGGzPXY4NT2Uqyz77uysc0c,40085
20
- java_codebase_rag/cli_format.py,sha256=CT7-xdwZ0bMCdP68_UOwkvm-mnLluU3LutlM-mDNk60,1839
21
- java_codebase_rag/cli_progress.py,sha256=q6Wh97yzLGs1B8UFk_WAKivfQu7Y5RnUUE-T2YHWkIs,3237
22
- java_codebase_rag/config.py,sha256=bfwYI4R8PU9YV_M4r8-03iaUZ_0TW-qN_NuhIsDXy2M,18769
23
- java_codebase_rag/installer.py,sha256=sXsHPo24aoDFoTr0D_vYLg0MFdGAV2wdL05FqRaul6E,52861
24
- java_codebase_rag/lance_optimize.py,sha256=25Rwj7HNO8F-35MxhFK6naqgbjd3H-T0zKb3pXB4H0s,9268
25
- java_codebase_rag/pipeline.py,sha256=ydNktEGL1YniAjJsr37yKBo_bGV4cN_LTGVTmmrsrZw,14688
26
- java_codebase_rag/progress.py,sha256=2IxdMALDM0wAQCyJrrfZ975zM_85C-4BfHxf4AtYifE,23212
27
- java_codebase_rag/install_data/agents/explorer-rag-enhanced.md,sha256=BkdQpBEWqSdvGHgbqMdRb5CWfEiFRJK4Dgqbyal3l6s,14551
28
- java_codebase_rag/install_data/skills/explore-codebase/SKILL.md,sha256=YkRnrM7Wh5E8raFjAW3RrN2V9-ov8upaGC3UdpSx6U8,12346
29
- java_codebase_rag-0.6.7.dist-info/licenses/LICENSE,sha256=gxvtiHtuviR_q8ZAjWw-QTcF3DyPzg6ZY-lQrr8OPpw,1068
30
- java_codebase_rag-0.6.7.dist-info/METADATA,sha256=Hnwc5Zpo53La7PXgldTTlVl87xRGG5KvDTky6ufxyQM,17239
31
- java_codebase_rag-0.6.7.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
32
- java_codebase_rag-0.6.7.dist-info/entry_points.txt,sha256=wsPZwot0Ui4JI3TIgW8LcbN8bNtKFbwQAlHAAJXfYgQ,117
33
- java_codebase_rag-0.6.7.dist-info/top_level.txt,sha256=syQgi8XPBwY2ws_NZ1uRCxTf_s41NpshwEHNdcdnk3A,245
34
- java_codebase_rag-0.6.7.dist-info/RECORD,,