java-codebase-rag 0.11.2__py3-none-any.whl → 0.12.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 (37) hide show
  1. java_codebase_rag/_deprecation.py +103 -0
  2. java_codebase_rag/_version.py +2 -2
  3. java_codebase_rag/ast/ast_java.py +22 -0
  4. java_codebase_rag/ast/ast_kotlin.py +1794 -0
  5. java_codebase_rag/ast/chunk_heuristics.py +26 -5
  6. java_codebase_rag/ast/language.py +117 -0
  7. java_codebase_rag/cli.py +17 -17
  8. java_codebase_rag/cli_dispatch.py +251 -0
  9. java_codebase_rag/config.py +8 -8
  10. java_codebase_rag/eval/runner.py +3 -3
  11. java_codebase_rag/graph/build_ast_graph.py +130 -8
  12. java_codebase_rag/graph/graph_enrich.py +8 -5
  13. java_codebase_rag/graph/ladybug_queries.py +1 -1
  14. java_codebase_rag/graph/path_filtering.py +39 -7
  15. java_codebase_rag/index/java_index_flow_lancedb.py +160 -15
  16. java_codebase_rag/install_data/agents/explorer-rag-cli.md +6 -4
  17. java_codebase_rag/install_data/agents/explorer-rag-enhanced.md +4 -4
  18. java_codebase_rag/install_data/skills/explore-codebase/SKILL.md +4 -4
  19. java_codebase_rag/install_data/skills/explore-codebase-cli/SKILL.md +5 -5
  20. java_codebase_rag/installer.py +15 -15
  21. java_codebase_rag/jrag.py +25 -11
  22. java_codebase_rag/lance_optimize.py +7 -7
  23. java_codebase_rag/mcp/mcp_v2.py +2 -2
  24. java_codebase_rag/mcp/server.py +6 -4
  25. java_codebase_rag/pipeline.py +4 -4
  26. java_codebase_rag/progress.py +1 -1
  27. java_codebase_rag/search/search_lexical.py +1 -1
  28. java_codebase_rag/search/search_scoring.py +19 -5
  29. java_codebase_rag/watch/lock.py +1 -1
  30. java_codebase_rag/watch/watcher.py +45 -21
  31. {java_codebase_rag-0.11.2.dist-info → java_codebase_rag-0.12.0.dist-info}/METADATA +31 -22
  32. {java_codebase_rag-0.11.2.dist-info → java_codebase_rag-0.12.0.dist-info}/RECORD +36 -32
  33. java_codebase_rag-0.12.0.dist-info/entry_points.txt +5 -0
  34. java_codebase_rag-0.11.2.dist-info/entry_points.txt +0 -4
  35. {java_codebase_rag-0.11.2.dist-info → java_codebase_rag-0.12.0.dist-info}/WHEEL +0 -0
  36. {java_codebase_rag-0.11.2.dist-info → java_codebase_rag-0.12.0.dist-info}/licenses/LICENSE +0 -0
  37. {java_codebase_rag-0.11.2.dist-info → java_codebase_rag-0.12.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,103 @@
1
+ """Legacy-alias deprecation notice for the ``jrag`` rename.
2
+
3
+ The tool is being renamed from ``java-codebase-rag`` to ``jrag``. The legacy
4
+ command aliases (``java-codebase-rag`` and ``java-codebase-rag-mcp``) continue
5
+ to work; when invoked through one of them in an interactive context, this
6
+ helper emits a single-line notice pointing the operator at the new name.
7
+
8
+ Suppression rule
9
+ ----------------
10
+ The notice is suppressed when **either** of the following holds:
11
+
12
+ * ``$JRAG_NO_DEPRECATION`` is present and non-empty — any non-empty value
13
+ suppresses (so ``"1"``, ``"0"``, ``"false"``, ``"yes"`` all suppress; the
14
+ empty string and an unset variable do not). The simpler "present and
15
+ non-empty" rule is preferred over parsing truthy values so that operators
16
+ can shut the notice up with whatever value is easiest to reach for.
17
+ * ``sys.stderr.isatty()`` is false (or ``sys.stderr`` lacks ``isatty``) — i.e.
18
+ non-interactive contexts: piped, redirected, or captured stderr. Under real
19
+ MCP use stderr is not a TTY, so the call is silent in production; it exists
20
+ for the rare human-debug case.
21
+
22
+ This module is stdlib-only and import-light: it runs at MCP-server startup and
23
+ before ``--help``, so it must not pull in any backend (cli, search, mcp) code.
24
+ """
25
+ from __future__ import annotations
26
+
27
+ import os
28
+ import sys
29
+
30
+ _LEGACY_ALIASES = frozenset({"java-codebase-rag", "java-codebase-rag-mcp"})
31
+
32
+ _DEPRECATION_LINE = (
33
+ "jrag: 'java-codebase-rag' is now 'jrag'; this alias continues to work. "
34
+ "Set JRAG_NO_DEPRECATION=1 to silence.\n"
35
+ )
36
+
37
+ #: Executable suffixes appended by Windows (and packaging tools like pip) to
38
+ #: console-script wrappers. All three are exactly 4 characters long (``.exe``,
39
+ #: ``.bat``, ``.cmd``) so a single ``b[:-4]`` slice strips any of them. Stripping
40
+ #: keeps routing decisions stable across POSIX and Windows installs:
41
+ #: ``C:\\Users\\foo\\Scripts\\jrag.exe`` → ``"jrag"``;
42
+ #: ``...\\java-codebase-rag.exe`` → ``"java-codebase-rag"``.
43
+ _WINDOWS_EXE_SUFFIXES: tuple[str, ...] = (".exe", ".bat", ".cmd")
44
+
45
+
46
+ def _invoked_program_name() -> str:
47
+ """Basename of ``sys.argv[0]`` with a Windows executable suffix stripped.
48
+
49
+ Returns the empty string when ``sys.argv`` is empty. Otherwise takes
50
+ ``os.path.basename(sys.argv[0])`` and, if it ends (case-insensitively) with
51
+ one of ``.exe`` / ``.bat`` / ``.cmd``, drops the 4-character suffix.
52
+
53
+ Shared with :mod:`java_codebase_rag.cli_dispatch` for identity-default
54
+ routing: both legacy-alias deprecation here and ``jrag``-vs-alias routing
55
+ there rely on the same canonicalized basename. Without this, Windows builds
56
+ would route ``jrag.exe --version`` through the wrong parser and never emit
57
+ the deprecation notice for ``java-codebase-rag.exe``.
58
+ """
59
+ argv = sys.argv
60
+ if not argv:
61
+ return ""
62
+ base = os.path.basename(argv[0])
63
+ if base.lower().endswith(_WINDOWS_EXE_SUFFIXES):
64
+ return base[:-4]
65
+ return base
66
+
67
+
68
+ def _stderr_is_tty() -> bool:
69
+ """True iff ``sys.stderr`` reports itself as a TTY.
70
+
71
+ Defensive against stderr replacements that omit ``isatty``.
72
+ """
73
+ stderr = sys.stderr
74
+ return hasattr(stderr, "isatty") and stderr.isatty()
75
+
76
+
77
+ def _suppressed() -> bool:
78
+ """True iff the notice should be suppressed."""
79
+ if os.environ.get("JRAG_NO_DEPRECATION"):
80
+ return True
81
+ return not _stderr_is_tty()
82
+
83
+
84
+ def maybe_warn_legacy_alias(stream=None) -> None:
85
+ """Emit a one-line legacy-alias deprecation notice when appropriate.
86
+
87
+ Detects a legacy invocation (``sys.argv[0]`` basename is exactly
88
+ ``java-codebase-rag`` or ``java-codebase-rag-mcp``) and, if not suppressed,
89
+ writes a single line to ``stream`` (defaulting to ``sys.stderr``). Never
90
+ raises: any error inside the write is swallowed so the rename helper can
91
+ never break tool startup.
92
+
93
+ See module docstring for the suppression rule.
94
+ """
95
+ if _invoked_program_name() not in _LEGACY_ALIASES:
96
+ return
97
+ if _suppressed():
98
+ return
99
+ target = stream if stream is not None else sys.stderr
100
+ try:
101
+ target.write(_DEPRECATION_LINE)
102
+ except Exception: # pragma: no cover - defensive: never break startup
103
+ return
@@ -1,7 +1,7 @@
1
1
  """Version string for the CLI ``--version`` flag.
2
2
 
3
3
  The single source of truth is the installed distribution metadata
4
- (``java-codebase-rag`` in pyproject.toml), read via :mod:`importlib.metadata`
4
+ (``jrag-cli`` in pyproject.toml), read via :mod:`importlib.metadata`
5
5
  so a pyproject bump propagates with no second hardcoded copy.
6
6
  :func:`version_string` appends the CPython version for the
7
7
  ``<prog> <version> (python <x.y.z>)`` format chosen for the ``--version`` flag.
@@ -15,7 +15,7 @@ import platform
15
15
  from importlib.metadata import PackageNotFoundError
16
16
  from importlib.metadata import version as _dist_version
17
17
 
18
- _PACKAGE = "java-codebase-rag"
18
+ _PACKAGE = "jrag-cli"
19
19
 
20
20
 
21
21
  def package_version() -> str:
@@ -249,6 +249,11 @@ class AnnotationRef:
249
249
  container_capability_values: tuple[str, ...] = field(default_factory=tuple)
250
250
  # Entry-aligned with `container_capability_values`; each value is "enum" | "string".
251
251
  container_capability_kinds: tuple[str, ...] = field(default_factory=tuple)
252
+ # Kotlin use-site target (one of "field"|"get"|"set"|"param"|"property"|"file") or
253
+ # None. Java ``parse_java`` always leaves this None — Java has no use-site targets.
254
+ # This is an AST-level field (not a persisted graph column); it drives Kotlin-only
255
+ # routing of an annotation to the FieldDecl / accessor MethodDecl / ParamDecl slot.
256
+ use_site_target: str | None = None
252
257
 
253
258
 
254
259
  @dataclass
@@ -394,11 +399,26 @@ class JavaFileAst:
394
399
  explicit_imports: dict[str, str] # "List" -> "java.util.List"
395
400
  top_level_types: list[TypeDecl]
396
401
  all_types: list[TypeDecl] # flat, includes nested
402
+ # Language-dispatch seam (Task 1). Required — no default — so every
403
+ # construction site names the language explicitly. Validated against the
404
+ # registry in ``language.KNOWN_LANGUAGE_IDS``. Lazily imported inside
405
+ # ``__post_init__`` to avoid a module-load cycle (``language`` imports
406
+ # ``JavaFileAst``/``parse_java`` from this module).
407
+ language: str
397
408
  parse_error: bool = False
398
409
  source_bytes: int = 0
399
410
  file_imports: FileImports = field(default_factory=FileImports)
400
411
  routes_skipped_unresolved: int = 0
401
412
 
413
+ def __post_init__(self) -> None:
414
+ from .language import KNOWN_LANGUAGE_IDS
415
+
416
+ if self.language not in KNOWN_LANGUAGE_IDS:
417
+ raise ValueError(
418
+ f"Unknown language id {self.language!r}; "
419
+ f"expected one of {sorted(KNOWN_LANGUAGE_IDS)}"
420
+ )
421
+
402
422
 
403
423
  @dataclass
404
424
  class _ParseCtx:
@@ -2625,6 +2645,7 @@ def parse_java(source: bytes | str, *, filename: str = "", verbose: bool = False
2625
2645
  explicit_imports={},
2626
2646
  top_level_types=[],
2627
2647
  all_types=[],
2648
+ language="java",
2628
2649
  parse_error=False,
2629
2650
  source_bytes=len(src),
2630
2651
  file_imports=FileImports(),
@@ -2710,6 +2731,7 @@ def parse_java(source: bytes | str, *, filename: str = "", verbose: bool = False
2710
2731
  explicit_imports=explicit_imports,
2711
2732
  top_level_types=top_types,
2712
2733
  all_types=all_types,
2734
+ language="java",
2713
2735
  parse_error=root.has_error,
2714
2736
  source_bytes=len(src),
2715
2737
  file_imports=file_imports,