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
@@ -7,9 +7,7 @@ description: "MUST BE USED PROACTIVELY. Universal read-only codebase exploration
7
7
 
8
8
  Read-only exploration combining **java-codebase-rag graph navigation** with **broad file-system search**.
9
9
 
10
- ## When to use
11
-
12
- Any time you need to search, locate, navigate, or explore the codebase. **Do NOT use when** the answer is already in open context or for a single known file — read that file directly.
10
+ Use any time you must search, locate, navigate, or explore. **Do NOT use when** the answer is already in context or for a single known file — read it directly.
13
11
 
14
12
  ## Core Principles
15
13
 
@@ -19,20 +17,9 @@ Any time you need to search, locate, navigate, or explore the codebase. **Do NOT
19
17
 
20
18
  ## Tool Inventory
21
19
 
22
- ### Graph tools (java-codebase-rag MCP)
23
-
24
- `search`, `find`, `describe`, `neighbors`, `resolve`.
25
-
26
- **Node kinds:** `Symbol` (types/methods), `Route` (HTTP/messaging entry points), `Client` (outbound HTTP), `Producer` (outbound async).
27
- **Indexed content:** Java sources + SQL + YAML (`table`: `java`, `sql`, `yaml`, or `all`).
28
-
29
- ### File-system tools
30
-
31
- - **Grep** — content search by pattern/regex
32
- - **Glob** — find files by name/path pattern (`**/*.java`, `**/*Controller*.java`, `**/application*.yml`)
33
- - **Read** — read files (`offset`/`limit` for large files)
34
-
35
- ### Other: **Bash** (read-only: `git log`, `git blame`, `ls`, `find`), **WebSearch**/**WebFetch** (external lookups)
20
+ - **Graph (java-codebase-rag MCP):** `search`, `find`, `describe`, `neighbors`, `resolve`. Node kinds: `Symbol` (types/methods), `Route` (HTTP/messaging entry points), `Client` (outbound HTTP), `Producer` (outbound async). Indexed content: Java + SQL + YAML (`table`: `java`, `sql`, `yaml`, `all`).
21
+ - **File-system:** `Grep` (content/regex), `Glob` (name/path patterns), `Read` (`offset`/`limit` for large files).
22
+ - **Other:** `Bash` (read-only: `git log`, `git blame`, `ls`, `find`), `WebSearch`/`WebFetch`.
36
23
 
37
24
  ---
38
25
 
@@ -52,22 +39,20 @@ Any time you need to search, locate, navigate, or explore the codebase. **Do NOT
52
39
  | Who hits this route? | route id | `neighbors(ids, "in", ["HTTP_CALLS","ASYNC_CALLS","EXPOSES"])` |
53
40
  | Handler for route | route id | `neighbors(ids, "in", ["EXPOSES"])` |
54
41
  | Who implements/injects T? | type symbol id | `neighbors(ids, "in", ["IMPLEMENTS"])` or `["INJECTS"]` |
55
- | Impact of changing X? | bounded `neighbors` `in` loop with `CALLS`, `INJECTS`, … | `Grep` fallback |
56
- | Find files matching pattern | `Glob` | `Read` |
57
- | Search for text in files | `Grep` | `Read` |
42
+ | Impact of changing X? | bounded `neighbors` `in` loop (`CALLS`, `INJECTS`, …) | `Grep` fallback |
43
+ | Find files / text | `Glob` / `Grep` | `Read` |
58
44
  | Who changed X and when? | Bash: `git log`/`git blame` | — |
59
- | "How is this configured?" | `Glob` + `Grep` for config keys; `search(query=…, table="yaml")` | `Read` sections |
45
+ | "How is this configured?" | `Glob` + `Grep`; `search(query=…, table="yaml")` | `Read` sections |
60
46
 
61
- **Escalation:** ① Most targeted tool first → ② Fall back gracefully (graph empty → `Grep`/`Glob`) → ③ Cross-validate (graph vs file disagree → **trust the file**).
47
+ **Escalation:** ① Most targeted tool first → ② fall back gracefully (graph empty → `Grep`/`Glob`) → ③ cross-validate (graph vs file disagree → **trust the file**).
62
48
 
63
- **Rules of thumb:** Structure beats vector for exact questions (`resolve`/`find`+`neighbors`); vector beats structure for fuzzy discovery (`search`); file-system beats stale index.
49
+ **Rules of thumb:** structure beats vector for exact questions (`resolve`/`find`+`neighbors`); vector beats structure for fuzzy discovery (`search`); file-system beats stale index.
64
50
 
65
51
  ---
66
52
 
67
53
  ## Graph Navigation Reference (java-codebase-rag MCP)
68
54
 
69
- **Ontology: 17** — if results look structurally wrong or empty across tools, the index may be missing or stale; ask the operator to rebuild.
70
- Responses may include `hints_structured` (suggested next calls) and `advisories` — advisory only; ignore when `success` is false.
55
+ **Ontology: 17.** If results look structurally wrong or empty across tools, the index may be missing/stale — ask the operator to rebuild. Responses may carry `hints_structured` (suggested next calls) and `advisories` — advisory only; ignore when `success` is false.
71
56
 
72
57
  ### Forced reasoning preamble (every MCP call)
73
58
 
@@ -76,17 +61,13 @@ Q-class: <semantic | structured | inspect | walk>
76
61
  Pick: <search|find|describe|neighbors|resolve> Why: <≤8 words>
77
62
  ```
78
63
 
79
- ### Workflow: locate → inspect → walk
80
-
81
- 1. **Locate** — `resolve` for identifier-shaped; `search` for NL/code fragments; `find` for structured `NodeFilter`.
82
- 2. **Inspect** — `describe(id)` for full record + `edge_summary`.
83
- 3. **Walk** — `neighbors` in a loop with explicit `direction` and `edge_types`.
64
+ **Workflow:** locate (`resolve`/`search`/`find`) → inspect (`describe`) → walk (`neighbors`, explicit `direction` + `edge_types`).
84
65
 
85
66
  ### Edge taxonomy
86
67
 
87
68
  Use these strings **verbatim** in `neighbors(..., edge_types=[...])`.
88
69
 
89
- **Stored edges (one hop):**
70
+ **Stored (one hop):**
90
71
 
91
72
  | Edge type | Semantics |
92
73
  | --------- | --------- |
@@ -97,50 +78,41 @@ Use these strings **verbatim** in `neighbors(..., edge_types=[...])`.
97
78
  | `EXPOSES` | Method Symbol → Route (handler exposes route) |
98
79
  | `HTTP_CALLS`, `ASYNC_CALLS` | Cross-service: Client/Producer → Route |
99
80
 
100
- **Composed edges — type Symbol origin (`direction="out"` only):**
101
-
102
- `DECLARES.DECLARES_CLIENT` — members' HTTP clients | `DECLARES.DECLARES_PRODUCER` — members' async producers | `DECLARES.EXPOSES` — members' exposed routes
103
-
104
- **Composed edges — non-static method Symbol origin (`direction="out"` only):**
81
+ **Composed (`direction="out"` only):** type-Symbol origin — `DECLARES.DECLARES_CLIENT` (members' HTTP clients), `DECLARES.DECLARES_PRODUCER` (async producers), `DECLARES.EXPOSES` (exposed routes). Non-static-method-Symbol origin — `OVERRIDDEN_BY`, `OVERRIDDEN_BY.DECLARES_CLIENT`, `OVERRIDDEN_BY.DECLARES_PRODUCER`, `OVERRIDDEN_BY.EXPOSES`.
105
82
 
106
- `OVERRIDDEN_BY` — concrete overrider methods | `OVERRIDDEN_BY.DECLARES_CLIENT` | `OVERRIDDEN_BY.DECLARES_PRODUCER` | `OVERRIDDEN_BY.EXPOSES`
83
+ > Don't mix `DECLARES.*` and `OVERRIDDEN_BY.*` in one list. Large composed counts in `edge_summary` → raise `limit` or issue separate calls.
107
84
 
108
- > Do not mix `DECLARES.*` and `OVERRIDDEN_BY.*` in one `edge_types` list. When `edge_summary` shows large composed counts, raise `limit` or issue separate calls per key.
85
+ **Argument shapes — JSON, not stringified:** `edge_types=["CALLS"]` not `"CALLS"`; `filter={"role":"CONTROLLER"}` not nested string; `ids=["sym:…","sym:…"]` not comma-joined. Omit unneeded keys. Empty `""` is often a real filter that matches nothing.
109
86
 
110
- ### Argument shapes
87
+ **Node id prefixes:** Symbol `sym:`, Route `route:`/`r:`, Client `client:`/`c:`, Producer `producer:`/`p:`. Use exact ids from prior calls.
111
88
 
112
- **JSON, not stringified JSON:** `edge_types=["CALLS"]` not `"CALLS"`; `filter={"role":"CONTROLLER"}` not nested string; `ids=["sym:…","sym:…"]` not comma-joined. Omit keys you don't need. Empty string `""` is a real filter that matches nothing.
113
-
114
- **Node id prefixes:** Symbol `sym:`, Route `route:`/`r:`, Client `client:`/`c:`, Producer `producer:`/`p:`. Use exact ids from previous calls.
115
-
116
- **Symbol FQNs:** `<package>.<Type>[.<NestedType>]#<methodName>(<SimpleType1>,<SimpleType2>,…)`. Generics erased, no spaces after commas. No-arg: `()`. Constructor: `#<init>(…)`.
89
+ **Symbol FQNs:** `<package>.<Type>[.<NestedType>]#<methodName>(<SimpleType1>,<SimpleType2>,…)`. Generics erased, no spaces after commas. No-arg `()`. Constructor `#<init>(…)`.
117
90
 
118
91
  ### `neighbors` — required every time
119
92
 
120
- - **`direction`**: `"in"` or `"out"` (no default). **`edge_types`**: non-empty list.
121
- - **Batching:** multiple `ids` expand first; `limit`/`offset` slice the **merged** edge list — raise `limit` when batching.
122
- - **`CALLS` edges:** `attrs.resolved=false` = external (JDK/Spring), not missing. **`include_unresolved=True`** (`out` only) interleaves unresolved call sites; mutually exclusive with `edge_filter`. **`dedup_calls=True`** collapses identical (origin, callee) pairs.
123
- - **`edge_filter`** (only with `edge_types=['CALLS']`): `min_confidence`; `include_strategies`/`exclude_strategies`; `callee_declaring_role`/`callee_declaring_roles`/`exclude_callee_declaring_roles`. Note: use `edge_filter.callee_declaring_role` for callee stereotype filtering, not `filter.role` which filters the neighbor node.
124
- - **Cross-service edges:** read `attrs.confidence` and `attrs.match` — low confidence or `unresolved`/`phantom`/`ambiguous` = resolver signal, not ground truth.
93
+ - **`direction`** `"in"`/`"out"` (no default); **`edge_types`** non-empty list.
94
+ - **Batching:** multiple `ids` expand first; `limit`/`offset` slice the **merged** list — raise `limit` when batching.
95
+ - **`CALLS`:** `attrs.resolved=false` = external (JDK/Spring), not missing. `include_unresolved=True` (`out` only) interleaves unresolved sites; exclusive with `edge_filter`. `dedup_calls=True` collapses identical (origin, callee) pairs.
96
+ - **`edge_filter`** (only with `edge_types=['CALLS']`): `min_confidence`; `include_strategies`/`exclude_strategies`; `callee_declaring_role`/`callee_declaring_roles`/`exclude_callee_declaring_roles` (callee stereotype filter — not `filter.role`, which filters the neighbor node).
97
+ - **Cross-service edges:** read `attrs.confidence`/`attrs.match` — low confidence or `unresolved`/`phantom`/`ambiguous` = resolver signal, not ground truth.
125
98
 
126
99
  ### NodeFilter (`find`, `search.filter`, `neighbors.filter`)
127
100
 
128
- For `find`, `filter` is required — `{}` means no predicates. **Strict frame:** unknown keys or inapplicable populated fields → `success=false`; invalid enum values (e.g. wrong case) are rejected earlier at the schema layer with the valid set listed.
101
+ For `find`, `filter` is required — `{}` = no predicates. **Strict frame:** unknown keys or inapplicable populated fields → `success=false`; invalid enums rejected at the schema layer (valid set listed).
129
102
 
130
103
  | Applicable to | Keys |
131
104
  | ------------- | ---- |
132
105
  | All kinds | `microservice`, `module` |
133
- | **symbol** only | `role`, `exclude_roles`, `annotation`, `capability`, `fqn_prefix`, `symbol_kind`, `symbol_kinds` |
134
- | **route** only | `http_method`, `path_prefix`, `framework` |
135
- | **client** only | `source_layer`, `client_kind`, `target_service`, `target_path_prefix`, `http_method` |
136
- | **producer** only | `source_layer`, `producer_kind`, `topic_prefix` |
106
+ | **symbol** only | `role`, `exclude_roles`, `annotation`, `capability`, `fqn_contains`, `symbol_kind`, `symbol_kinds` |
107
+ | **route** only | `http_method`, `path_contains`, `framework` |
108
+ | **client** only | `source_layer`, `client_kind`, `target_service`, `target_path_contains`, `http_method` |
109
+ | **producer** only | `source_layer`, `producer_kind`, `topic_contains` |
137
110
 
138
- No wildcards in prefix fields — use `search(query=…)` for ranked text.
111
+ Substring fields (`fqn_contains`, `path_contains`, `target_path_contains`, `topic_contains`) match literally via `CONTAINS` — no `*`/`?`; use `search(query=…)` for ranked text.
139
112
 
140
113
  ### `resolve` — identifier lookup
141
114
 
142
- **Input:** FQN/suffix, `sym:`/`route:`/`client:`/`producer:` id, `METHOD /path`, route path, client target_service, producer topic.
143
- **`hint_kind`:** optional `symbol`|`route`|`client`|`producer` (narrows generators).
115
+ **Input:** FQN/suffix, `sym:`/`route:`/`client:`/`producer:` id, `METHOD /path`, route path, client target_service, producer topic. **`hint_kind`:** optional `symbol`|`route`|`client`|`producer`.
144
116
 
145
117
  | `status` | Action |
146
118
  | -------- | ------ |
@@ -150,55 +122,44 @@ No wildcards in prefix fields — use `search(query=…)` for ranked text.
150
122
 
151
123
  Prefer `resolve` → `describe(id=…)` over `describe(fqn=…)` when FQN may collide.
152
124
 
153
- ### Tool signatures summary
125
+ ### Tool signatures
154
126
 
155
- - **`search`** — `query`, `table` (`java`|`sql`|`yaml`|`all`), `hybrid` (bool), `limit` (default 5), `offset`, `path_contains`, optional `filter` (symbol-applicable only).
156
- - **`find`** — `kind` (`symbol`|`route`|`client`|`producer`), **`filter`** (required object), `limit` (default 25), `offset`.
157
- - **`describe`** — `id` (any kind) or `fqn` (symbol only; `id` wins). Returns node + `edge_summary` (stored + composed keys).
127
+ - **`search`** — `query`, `table` (`java`|`sql`|`yaml`|`all`), `hybrid` (bool), `limit` (5), `offset`, `path_contains`, optional `filter` (symbol only).
128
+ - **`find`** — `kind` (`symbol`|`route`|`client`|`producer`), **`filter`** (required), `limit` (25), `offset`.
129
+ - **`describe`** — `id` (any) or `fqn` (symbol; `id` wins). Returns node + `edge_summary`.
158
130
  - **`resolve`** — `identifier`, optional `hint_kind`.
159
131
 
160
132
  ### Ontology glossary
161
133
 
162
- **Roles:** `CONTROLLER` | `SERVICE` | `REPOSITORY` | `COMPONENT` | `CONFIG` | `ENTITY` | `CLIENT` | `MAPPER` | `DTO` | `OTHER`.
163
- Exclude `DTO`, `OTHER`, `MAPPER` with `exclude_roles` when tracing business logic. On `CALLS` out: `edge_filter={"exclude_callee_declaring_roles":["OTHER"]}` drops framework calls.
164
-
134
+ **Roles:** `CONTROLLER` | `SERVICE` | `REPOSITORY` | `COMPONENT` | `CONFIG` | `ENTITY` | `CLIENT` | `MAPPER` | `DTO` | `OTHER`. Exclude `DTO`/`OTHER`/`MAPPER` via `exclude_roles` when tracing business logic; on `CALLS` out, `edge_filter={"exclude_callee_declaring_roles":["OTHER"]}` drops framework calls.
165
135
  **Capabilities:** `MESSAGE_LISTENER`, `MESSAGE_PRODUCER`, `HTTP_CLIENT`, `SCHEDULED_TASK`, `EXCEPTION_HANDLER`.
166
-
167
136
  **Symbol kinds:** `class`, `interface`, `enum`, `record`, `annotation`, `method`, `constructor`.
168
-
169
- **Route frameworks:** `spring_mvc`, `webflux`. (Route *kinds* are `http_endpoint`, `http_consumer`, `kafka_topic`, `rabbit_queue`, `jms_destination`, `stream_binding`.)
170
- **Client kinds:** `feign_method`, `rest_template`, `web_client`. **Producer kinds:** `kafka_send`, `stream_bridge_send`. **Source layers (client/producer):** `builtin`, `layer_a_meta`, `layer_b_ann`, `layer_b_fqn`, `layer_c_source`.
171
- **Match types:** `cross_service`, `intra_service`, `ambiguous`, `phantom`, `unresolved`.
137
+ **Route frameworks:** `spring_mvc`/`webflux` (HTTP), `kafka`/`rabbitmq`/`jms`/`stream` (messaging), `feign` (client mirrors). (Route *kinds*: `http_endpoint`, `http_consumer`, `kafka_topic`, `rabbit_queue`, `jms_destination`, `stream_binding`.) **Client kinds:** `feign_method`, `rest_template`, `web_client`. **Producer kinds:** `kafka_send`, `stream_bridge_send`. **Source layers (client/producer):** `builtin`, `layer_a_meta`, `layer_b_ann`, `layer_b_fqn`, `layer_c_source`. **Match types:** `cross_service`, `intra_service`, `ambiguous`, `phantom`, `unresolved`.
172
138
 
173
139
  ---
174
140
 
175
141
  ## Recovery Playbook
176
142
 
177
- **After two failed attempts on the same intent, stop and report tool name, args, and response snippet.**
143
+ **After two failed attempts on the same intent, stop and report tool, args, and response snippet.**
178
144
 
179
145
  | Symptom | Fix |
180
146
  | ------- | --- |
181
- | `neighbors` validation error | Add both `direction` and `edge_types` explicitly |
182
- | Empty `neighbors` | Read `describe.edge_summary`; check edge type and direction |
183
- | Cannot find symbol | `resolve`/`search`; `find` with `fqn_prefix`; fallback `Grep` |
184
- | `find` returns too much | Add `microservice`, `fqn_prefix`, `path_prefix`, `topic_prefix` |
185
- | Empty `search` | Try `table="all"`; `find` with `fqn_prefix`; `Grep` directly |
186
- | Empty results across tools | Index missing/stale → `Grep`/`Glob`/`Read`; ask operator to rebuild |
147
+ | `neighbors` validation error | Add both `direction` and `edge_types` |
148
+ | Empty `neighbors` | Read `describe.edge_summary`; check edge type + direction |
149
+ | Cannot find symbol | `resolve`/`search`; `find` with `fqn_contains`; fallback `Grep` |
150
+ | `find` too broad | Add `microservice`, `fqn_contains`, `path_contains`, `topic_contains` |
151
+ | Empty `search` | Try `table="all"`; `find` with `fqn_contains`; `Grep` |
152
+ | Empty across tools | Index missing/stale → `Grep`/`Glob`/`Read`; ask operator to rebuild |
187
153
  | Graph vs file disagree | **Trust the file**; report stale index |
188
- | Mixed composed families on one id | Split calls — type keys need type id; override keys need method id |
189
- | `Glob`/`Grep` too many results | Narrow pattern; add directory prefix or `path_filter` |
190
- | `Grep` no results | Broaden pattern; check working directory; try alternate terms |
154
+ | Mixed composed families on one id | Split — type keys need type id; override keys need method id |
155
+ | `Glob`/`Grep` too broad | Narrow pattern; add directory prefix / `path_filter` |
191
156
 
192
157
  ---
193
158
 
194
159
  ## Workflow Patterns
195
160
 
196
- **"Explain feature X":** `search` → pick 1–3 hits → `describe` → `neighbors` with targeted edges → stop when answered.
197
-
198
- **"Where is X used?":** `resolve`/`search` → `neighbors("in", ["CALLS","INJECTS","IMPLEMENTS"])` → `Grep` fallback → report all sites with file:line.
199
-
200
- **"Find all Y":** Structural → `find(kind=…, filter={…})`. Textual → `Grep`. Broad → `Glob` + `Grep`. Summarize, don't dump.
201
-
202
- **"Trace flow from A to B":** Resolve both → walk `CALLS`/`EXPOSES`/`HTTP_CALLS` from A → `Grep` gaps → report with file:line.
203
-
204
- **"How is this configured?":** `Glob` for `**/application*.yml` → `Grep` for key → `Read` sections → `search(query=…, table="yaml")` supplement.
161
+ - **"Explain feature X":** `search` → pick 1–3 hits → `describe` → `neighbors` with targeted edges → stop when answered.
162
+ - **"Where is X used?":** `resolve`/`search` → `neighbors("in", ["CALLS","INJECTS","IMPLEMENTS"])` → `Grep` fallback → report sites with file:line.
163
+ - **"Find all Y":** structural → `find(kind=…, filter={…})`; textual → `Grep`; broad → `Glob`+`Grep`. Summarize, don't dump.
164
+ - **"Trace flow A→B":** resolve both → walk `CALLS`/`EXPOSES`/`HTTP_CALLS` from A → `Grep` gaps → report with file:line.
165
+ - **"How is this configured?":** `Glob` `**/application*.yml` → `Grep` the key → `Read` sections → `search(query=…, table="yaml")` supplement.
@@ -0,0 +1,183 @@
1
+ ---
2
+ name: explore-codebase-cli
3
+ description: "MUST BE USED PROACTIVELY. Universal read-only codebase exploration via the `jrag` CLI — one command per engineering intent (callers, callees, routes, clients, producers, impact, search, inspect, flow, overview). Use for any exploration: locating code, tracing dependencies, finding patterns, 'where is X', 'who calls Y', 'find all controllers', 'trace the flow from A to B'. Combines graph navigation with file-system search (grep, glob, file reading). Do NOT use when the answer is already in open context or for a single known file — read that file directly."
4
+ ---
5
+
6
+ # /explore-codebase-cli — Universal codebase exploration via `jrag`
7
+
8
+ Read-only exploration combining **graph navigation through the `jrag` CLI** with **broad file-system search**. `jrag` loads the same index as the MCP server but exposes one shell command per intent instead of five MCP tools.
9
+
10
+ Use any time you must search, locate, navigate, or explore. **Do NOT use when** the answer is already in context or for a single known file — read it directly.
11
+
12
+ ## Core Principles
13
+
14
+ 1. **Read-only.** Never edit, write, or modify any file.
15
+ 2. **Names in, names out.** Every `<query>` is human-readable (FQN / simple name / route path / topic). Raw node IDs never required.
16
+ 3. **One command per intent.** `jrag` collapses resolve + walk into one call — don't chain resolve→describe→neighbors manually.
17
+ 4. **Stop when answered.** Don't prefetch unrelated subgraphs or directories.
18
+
19
+ **One surface per project.** This is the CLI surface; the MCP surface (`search`/`find`/`describe`/`neighbors`/`resolve`) is mutually exclusive — running both strands the agent in two vocabularies.
20
+
21
+ ## Prerequisite: index must exist
22
+
23
+ `jrag` is a thin layer over the existing index. If unindexed, every command exits 2:
24
+
25
+ ```
26
+ status: error
27
+ message: No index at <path>. Run: java-codebase-rag init --source-root <root>
28
+ ```
29
+
30
+ Verify with `jrag status` when in doubt.
31
+
32
+ ## Tool Inventory
33
+
34
+ ### `jrag` command groups
35
+
36
+ Run `jrag --help` for the canonical list.
37
+
38
+ | Group | Commands |
39
+ | --- | --- |
40
+ | **Orientation** | `status`, `microservices`, `map`, `conventions`, `overview` |
41
+ | **Locate** | `find`, `search` |
42
+ | **Listings** | `http-routes`, `http-clients`, `producers`, `topics`, `jobs`, `listeners`, `entities` |
43
+ | **Traversal** | `callers`, `callees`, `hierarchy`, `implementations`, `subclasses`, `overrides`, `overridden-by`, `dependents`, `impact`, `flow`, `decompose`, `dependencies`, `connection` |
44
+ | **Inspection** | `inspect`, `outline`, `imports` |
45
+
46
+ ### Common flags
47
+
48
+ ```
49
+ --service <name> Filter by microservice
50
+ --module <name> Filter by module
51
+ --limit <N> Cap on results (default 20; 10 for fan-out)
52
+ --format text|json Output format (default: text)
53
+ --detail brief|normal|full How much of each node/edge is shown (default: normal);
54
+ orthogonal to --format. brief=name @service;
55
+ normal=+module/role/file/score; full=+signature/
56
+ annotations/snippet. inspect + orientation default to full.
57
+ --index-dir <path> Index directory override (default: discovered from cwd)
58
+ ```
59
+
60
+ `--offset` is supported **only** on `find` and `search`. Other commands emit `truncated: more results — narrow your query` when capped.
61
+
62
+ ### File-system tools
63
+
64
+ `Grep` (content/regex), `Glob` (name/path patterns), `Read` (`offset`/`limit`). Plus `Bash` (read-only: `git log`, `git blame`, `ls`, `find`), `WebSearch`/`WebFetch`.
65
+
66
+ ---
67
+
68
+ ## Decision Framework
69
+
70
+ | User asks… | First `jrag` command | Follow-up |
71
+ | ---------- | -------------------- | --------- |
72
+ | "Is the index fresh?" | `jrag status` | — |
73
+ | Identifier (FQN / simple name) | `jrag inspect <query>` | `callers` / `callees` |
74
+ | Fuzzy / NL "where is X" | `jrag search "<text>"` | `inspect <hit>` |
75
+ | All controllers in S | `jrag find --role CONTROLLER --service S` | `callees` |
76
+ | Interfaces in S | `jrag find --java-kind interface --service S` | `implementations` |
77
+ | HTTP / messaging entry points | `jrag http-routes [--framework …] [--method …]` | `inspect <route>` |
78
+ | Outbound HTTP clients | `jrag http-clients [--calls-service …]` | `callees <client>` |
79
+ | Outbound async producers | `jrag producers [--topic-contains …]` | `callees <producer>` |
80
+ | Topics + consumers/producers | `jrag topics [--topic-contains …]` | — |
81
+ | Who calls / what does M call? | `jrag callers <M>` / `jrag callees <M>` | `inspect` |
82
+ | Who hits this route? | `jrag callers <route>` | — |
83
+ | Implementations / subtypes of T? | `jrag implementations <T>` / `jrag subclasses <T>` | — |
84
+ | Overriding / overridden methods? | `jrag overrides <method>` (UP) / `jrag overridden-by <method>` | — |
85
+ | Who injects / depends on T? | `jrag dependencies <T>` / `jrag dependents <T>` | — |
86
+ | Blast-radius of changing X? | `jrag impact <X>` (bounded fan-in) | `Grep` fallback |
87
+ | Trace request flow A→B | `jrag flow <route>` | `connection <A> <B>` |
88
+ | File outline / imports | `jrag outline <file>` / `jrag imports <file>` | `inspect <row>` |
89
+ | "Explain service S" | `jrag overview <service>` | `http-routes`/`http-clients`/`producers` |
90
+ | "Explain route /topic" | `jrag overview <subject>` | `flow` |
91
+ | Find files / text | `Glob` / `Grep` | `Read` |
92
+ | Who changed X and when? | Bash: `git log`/`git blame` | — |
93
+ | "How is this configured?" | `Glob` + `Grep`; `jrag search "<key>" --table yaml` | `Read` sections |
94
+
95
+ **Escalation:** ① Most targeted command first → ② fall back gracefully (`callers` empty → `Grep`) → ③ cross-validate (CLI vs file disagree → **trust the file** — index may be stale).
96
+
97
+ **Rules of thumb:** structure beats vector for exact questions (`find`/`inspect` + traversal); vector beats structure for fuzzy discovery (`search`); file-system beats stale index.
98
+
99
+ ---
100
+
101
+ ## Resolve-first contract (every `<query>` command)
102
+
103
+ Every `jrag` command that takes a `<query>` runs `resolve_v2` internally:
104
+
105
+ | `resolve_v2` status | `jrag` behavior |
106
+ | --- | --- |
107
+ | `one` | Run the traversal/listing against the resolved node. |
108
+ | `many` | Return the candidate list and stop. **No auto-pick.** Disambiguate with `--kind`/`--role`/`--fqn-contains`/`--service`; re-run. |
109
+ | `none` | `status: not_found` envelope (exit 0). Fall back to `search` or `Grep`. |
110
+
111
+ Never look up a raw node ID — pass an FQN, simple name, prior `sym:`/`route:`/`client:`/`producer:` id, route path, or topic. Only `--kind` is a true resolve input; `--role`/`--java-kind`/`--fqn-contains` post-filter client-side, while `--service`/`--module` are resolve-time filters on `inspect`/`callers` and result filters elsewhere.
112
+
113
+ ## Output envelope
114
+
115
+ `--format` (text|json) picks the representation; `--detail` (brief|normal|full) picks how much of each node/edge shows — **both honor the same detail level**. Default: `text` + `normal`. `inspect` and orientation commands default to `full`. `--format json` emits the projected envelope (empty fields dropped):
116
+
117
+ ```json
118
+ {
119
+ "status": "ok|not_found|error",
120
+ "nodes": {"<id>": {...}},
121
+ "edges": [{...}],
122
+ "candidates": [{...}],
123
+ "truncated": false,
124
+ "agent_next_actions": ["jrag callers <id>", "..."],
125
+ "file_location": {"filename": "...", "start_line": 123}
126
+ }
127
+ ```
128
+
129
+ `truncated` is computed via +1-fetch on `find`/`search` (use `--limit`, then `--offset`); other commands emit the `more results` message when capped. `agent_next_actions` (≤5) maps result edges to next commands — a starting point, not a directive. `file_location` populates only on `one`-hit resolve.
130
+
131
+ ## Traversal direction reference
132
+
133
+ `jrag` abstracts away `direction`/`edge_types` — you name the intent, it picks the edges:
134
+
135
+ | Intent (command) | Underlying edges |
136
+ | --- | --- |
137
+ | `callers` / `callees` | `CALLS` in / out |
138
+ | `hierarchy` | `EXTENDS` + `IMPLEMENTS`, both directions (parents + children) |
139
+ | `implementations` / `subclasses` | `IMPLEMENTS` / `EXTENDS` in |
140
+ | `overrides` / `overridden-by` | `OVERRIDES` out (subtype→supertype) / in |
141
+ | `dependencies` / `dependents` | `INJECTS` out / in |
142
+ | `impact` | bounded fan-in: `INJECTS`/`IMPLEMENTS`/`EXTENDS` in (depth ≤2) |
143
+ | `flow <route>` | `EXPOSES`/`HTTP_CALLS`/`ASYNC_CALLS`/`CALLS` |
144
+ | `connection A B` | bounded search over the same edge set |
145
+
146
+ **Node id prefixes (from prior results):** `sym:` (Symbol), `route:`/`r:` (Route), `client:`/`c:` (Client), `producer:`/`p:` (Producer). **Symbol FQN:** `<package>.<Type>[.<NestedType>]#<methodName>(<SimpleType1>,…)` — generics erased, no spaces after commas, no-arg `()`, constructor `#<init>(...)`.
147
+
148
+ ## Ontology glossary
149
+
150
+ **Roles:** `CONTROLLER` | `SERVICE` | `REPOSITORY` | `COMPONENT` | `CONFIG` | `ENTITY` | `CLIENT` | `MAPPER` | `DTO` | `OTHER`.
151
+ **Capabilities:** `MESSAGE_LISTENER`, `MESSAGE_PRODUCER`, `HTTP_CLIENT`, `SCHEDULED_TASK`, `EXCEPTION_HANDLER`.
152
+ **Symbol kinds:** `class`, `interface`, `enum`, `record`, `annotation`, `method`, `constructor`.
153
+ **Route frameworks:** `spring_mvc`/`webflux` (HTTP), `kafka`/`rabbitmq`/`jms`/`stream` (messaging), `feign` (client mirrors). Route *kinds*: `http_endpoint`, `http_consumer`, `kafka_topic`, `rabbit_queue`, `jms_destination`, `stream_binding`. **Client kinds:** `feign_method`, `rest_template`, `web_client`. **Producer kinds:** `kafka_send`, `stream_bridge_send`. **Source layers:** `builtin`, `layer_a_meta`, `layer_b_ann`, `layer_b_fqn`, `layer_c_source`.
154
+
155
+ ---
156
+
157
+ ## Recovery Playbook
158
+
159
+ **After two failed attempts on the same intent, stop and report command, args, and result snippet.**
160
+
161
+ | Symptom | Fix |
162
+ | ------- | --- |
163
+ | `status: error` "No index at …" | Run `java-codebase-rag init --source-root <root>`; retry |
164
+ | `status: not_found` | `jrag search "<query>"`; or `find --fqn-contains …`; fallback `Grep` |
165
+ | `many` candidates | Add `--kind`/`--role`/`--fqn-contains`/`--service`; re-run |
166
+ | `find` too broad | Add `--service`, `--fqn-contains`, `--path-contains`, `--topic-contains` |
167
+ | Empty `search` | Try `--table all`; `find --fqn-contains`; `Grep` |
168
+ | `truncated: true` | Narrow, or page with `--offset` (`find`/`search` only) |
169
+ | Empty across commands | Index missing/stale → `Grep`/`Glob`/`Read`; ask operator to rebuild (`java-codebase-rag reprocess`) |
170
+ | CLI vs file disagree | **Trust the file**; report stale index |
171
+ | `--offset` rejected | Only `find`/`search` accept it; others narrow via filters |
172
+ | Wrong node picked | Resolve ambiguous — pass `--kind` |
173
+
174
+ ---
175
+
176
+ ## Workflow Patterns
177
+
178
+ - **"Explain feature X":** `jrag search "X"` → pick 1–3 hits → `jrag inspect <hit>` → targeted traversal (`callees`/`implementations`) → stop when answered.
179
+ - **"Where is X used?":** `jrag inspect <X>` → `jrag callers <X>` + `jrag dependents <X>` → `Grep` fallback → report sites with file:line.
180
+ - **"Find all Y":** structural → `jrag find --role <ROLE> [--service <S>]`; textual → `Grep`; broad → `Glob`+`Grep`. Summarize, don't dump.
181
+ - **"Trace flow A→B":** `jrag flow <route-A>` → `jrag connection A B` → `Grep` gaps → report with file:line.
182
+ - **"How is this configured?":** `Glob` `**/application*.yml` → `Grep` the key → `Read` sections → `jrag search "<key>" --table yaml`.
183
+ - **"Orient in a new service":** `jrag overview <S>` → `jrag conventions --service <S>` → `jrag map --service <S>` → `jrag http-routes --service <S>`.