java-codebase-rag 0.10.0__tar.gz → 0.10.1__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 (74) hide show
  1. {java_codebase_rag-0.10.0/src/java_codebase_rag.egg-info → java_codebase_rag-0.10.1}/PKG-INFO +1 -1
  2. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/pyproject.toml +1 -1
  3. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/search/search_lexical.py +20 -8
  4. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/search/search_scoring.py +26 -0
  5. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1/src/java_codebase_rag.egg-info}/PKG-INFO +1 -1
  6. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/LICENSE +0 -0
  7. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/README.md +0 -0
  8. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/setup.cfg +0 -0
  9. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/__init__.py +0 -0
  10. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/_fdlimit.py +0 -0
  11. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/_stdio.py +0 -0
  12. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/_version.py +0 -0
  13. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/absence/__init__.py +0 -0
  14. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/absence/absence_diagnosis.py +0 -0
  15. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/absence/absence_types.py +0 -0
  16. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/absence/absence_vocab.py +0 -0
  17. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/analysis/__init__.py +0 -0
  18. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/analysis/pr_analysis.py +0 -0
  19. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/analysis/resolve_service.py +0 -0
  20. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/ast/__init__.py +0 -0
  21. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/ast/ast_java.py +0 -0
  22. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/ast/brownfield_events.py +0 -0
  23. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/ast/chunk_heuristics.py +0 -0
  24. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/cli.py +0 -0
  25. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/cli_format.py +0 -0
  26. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/cli_progress.py +0 -0
  27. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/config.py +0 -0
  28. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/graph/__init__.py +0 -0
  29. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/graph/build_ast_graph.py +0 -0
  30. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/graph/graph_enrich.py +0 -0
  31. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/graph/graph_types.py +0 -0
  32. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/graph/java_ontology.py +0 -0
  33. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/graph/ladybug_queries.py +0 -0
  34. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/graph/path_filtering.py +0 -0
  35. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/index/__init__.py +0 -0
  36. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/index/java_index_flow_lancedb.py +0 -0
  37. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/index/java_index_v1_common.py +0 -0
  38. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/install_data/__init__.py +0 -0
  39. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/install_data/agents/explorer-rag-cli.md +0 -0
  40. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/install_data/agents/explorer-rag-enhanced.md +0 -0
  41. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/install_data/skills/explore-codebase/SKILL.md +0 -0
  42. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/install_data/skills/explore-codebase-cli/SKILL.md +0 -0
  43. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/installer.py +0 -0
  44. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/jrag.py +0 -0
  45. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/jrag_envelope.py +0 -0
  46. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/jrag_hints.py +0 -0
  47. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/jrag_render.py +0 -0
  48. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/lance_optimize.py +0 -0
  49. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/mcp/__init__.py +0 -0
  50. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/mcp/mcp_hints.py +0 -0
  51. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/mcp/mcp_v2.py +0 -0
  52. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/mcp/server.py +0 -0
  53. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/pipeline.py +0 -0
  54. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/progress.py +0 -0
  55. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/read_payloads.py +0 -0
  56. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/search/__init__.py +0 -0
  57. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/search/index_common.py +0 -0
  58. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/search/search_lancedb.py +0 -0
  59. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/watch/__init__.py +0 -0
  60. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/watch/client.py +0 -0
  61. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/watch/daemon.py +0 -0
  62. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/watch/lock.py +0 -0
  63. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/watch/paths.py +0 -0
  64. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/watch/protocol.py +0 -0
  65. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/watch/server.py +0 -0
  66. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/watch/warm.py +0 -0
  67. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag/watch/watcher.py +0 -0
  68. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag.egg-info/SOURCES.txt +0 -0
  69. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag.egg-info/dependency_links.txt +0 -0
  70. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag.egg-info/entry_points.txt +0 -0
  71. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag.egg-info/requires.txt +0 -0
  72. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/src/java_codebase_rag.egg-info/top_level.txt +0 -0
  73. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/tests/test_config_watch.py +0 -0
  74. {java_codebase_rag-0.10.0 → java_codebase_rag-0.10.1}/tests/test_docs_watch.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: java-codebase-rag
3
- Version: 0.10.0
3
+ Version: 0.10.1
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.10.0"
7
+ version = "0.10.1"
8
8
  description = "MCP server for semantic + structural search over Java codebases"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -32,6 +32,7 @@ from java_codebase_rag.search.search_scoring import (
32
32
  _dedup_by_fqn,
33
33
  _query_tokens,
34
34
  _split_identifier,
35
+ build_fts_query,
35
36
  )
36
37
 
37
38
  if TYPE_CHECKING:
@@ -272,8 +273,10 @@ def run_lexical_search(
272
273
  BM25-first (fork A): when the LadybugDB ``sym_fts`` index exists, candidates are
273
274
  fetched DB-side via Okapi BM25 over ``Symbol.search_text`` (killing the bounded
274
275
  Python scan that silently missed matches past the cap on large repos) and then
275
- re-ranked here by the name/type/fqn/role heuristic. Falls back to that heuristic
276
- scan when the FTS index or extension is unavailable (older graph, offline first run).
276
+ re-ranked here by the name/type/fqn/role heuristic. The query is pre-split with the
277
+ same tokenizer as ``search_text`` so pasted camelCase identifiers match. Falls back
278
+ to the heuristic scan when the FTS index or extension is unavailable (older graph,
279
+ offline first run), or when the query is degenerate / the BM25 result is empty.
277
280
 
278
281
  Raises ``RuntimeError`` (message contains "lexical search unavailable") if no
279
282
  symbol graph exists — the caller maps that to a clean failure envelope. Returns
@@ -292,14 +295,23 @@ def run_lexical_search(
292
295
  g = graph or LadybugGraph.get()
293
296
 
294
297
  # --- candidate fetch: BM25 (FTS) preferred, heuristic scan fallback ---
298
+ # FTS indexes Symbol.search_text (camelCase-split tokens); pre-split the query the
299
+ # same way (build_fts_query) so a pasted identifier like "DistributionChunkService"
300
+ # matches — LadybugDB FTS's own tokenizer does not split camelCase. An empty split
301
+ # (degenerate / stopword-only query), an unavailable FTS index, OR an empty BM25
302
+ # result all fall back to the heuristic scan, which yields role-ranked output for
303
+ # degenerate queries and covers selective filters where BM25's top-K thins to nil.
295
304
  bm25_scores: dict[str, float] = {}
296
305
  use_fts = False
297
- fts = _try_fts_candidates(g, query, filter, path_contains)
298
- if fts is not None:
299
- rows = fts["rows"]
300
- bm25_scores = fts["scores"]
301
- use_fts = True
302
- else:
306
+ rows: list[dict] | None = None
307
+ q_fts = build_fts_query(query)
308
+ if q_fts:
309
+ fts = _try_fts_candidates(g, q_fts, filter, path_contains)
310
+ if fts is not None and fts["rows"]:
311
+ rows = fts["rows"]
312
+ bm25_scores = fts["scores"]
313
+ use_fts = True
314
+ if rows is None:
303
315
  where, params = _lexical_where(filter, path_contains=path_contains)
304
316
  # Always exclude structural Symbol nodes. Files and packages are :Symbol-labeled
305
317
  # (kind='file'/'package') but aren't searchable code declarations — without this
@@ -136,6 +136,32 @@ def _split_identifier(name: str) -> list[str]:
136
136
  return [p for p in parts if p]
137
137
 
138
138
 
139
+ # Alphanumeric-word extractor for FTS query building (mirrors the index side, which
140
+ # runs the same regex over name/fqn/signature/annotations/capabilities/package fields).
141
+ _FTS_WORD_RE = re.compile(r"[A-Za-z][A-Za-z0-9]*")
142
+
143
+
144
+ def build_fts_query(text: str) -> str:
145
+ """Tokenize a search query into the ``Symbol.search_text`` token space (fork A).
146
+
147
+ ``search_text`` is indexed from ``_split_identifier`` tokens (camelCase / snake_case
148
+ split, lowercased). LadybugDB FTS's own tokenizer does NOT split camelCase, so a raw
149
+ pasted identifier like ``DistributionChunkService`` would match nothing — this
150
+ extracts alphanumeric words from the query and splits each via ``_split_identifier``
151
+ so the query lands in the index's token space. Tokens shorter than 2 chars are
152
+ dropped (mirrors the index side); duplicates collapse. Returns ``""`` for a query
153
+ with no usable tokens — the caller then falls back to the heuristic / role listing.
154
+ """
155
+ out: list[str] = []
156
+ seen: set[str] = set()
157
+ for word in _FTS_WORD_RE.findall(text or ""):
158
+ for tok in _split_identifier(word):
159
+ if len(tok) >= 2 and tok not in seen:
160
+ seen.add(tok)
161
+ out.append(tok)
162
+ return " ".join(out)
163
+
164
+
139
165
  def _symbol_bonus(r: dict, query_toks: set[str]) -> float:
140
166
  """Symbol-name overlap + action-verb bump for java chunks.
141
167
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: java-codebase-rag
3
- Version: 0.10.0
3
+ Version: 0.10.1
4
4
  Summary: MCP server for semantic + structural search over Java codebases
5
5
  Author: HumanBean17
6
6
  License-Expression: MIT