java-codebase-rag 0.8.0__tar.gz → 0.9.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.
- {java_codebase_rag-0.8.0/java_codebase_rag.egg-info → java_codebase_rag-0.9.1}/PKG-INFO +2 -2
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/README.md +1 -1
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/java_codebase_rag/cli.py +14 -1
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/java_codebase_rag/config.py +27 -3
- java_codebase_rag-0.9.1/java_codebase_rag/install_data/agents/explorer-rag-cli.md +148 -0
- java_codebase_rag-0.9.1/java_codebase_rag/install_data/agents/explorer-rag-enhanced.md +152 -0
- java_codebase_rag-0.9.1/java_codebase_rag/install_data/skills/explore-codebase/SKILL.md +165 -0
- java_codebase_rag-0.9.1/java_codebase_rag/install_data/skills/explore-codebase-cli/SKILL.md +183 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/java_codebase_rag/installer.py +310 -32
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/java_codebase_rag/jrag.py +112 -7
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/java_codebase_rag/jrag_envelope.py +1 -1
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/java_codebase_rag/jrag_render.py +12 -3
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/java_codebase_rag/lance_optimize.py +43 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/java_codebase_rag/pipeline.py +34 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1/java_codebase_rag.egg-info}/PKG-INFO +2 -2
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/java_codebase_rag.egg-info/SOURCES.txt +1 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/java_index_flow_lancedb.py +66 -6
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/mcp_v2.py +82 -26
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/pyproject.toml +1 -1
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/search_lancedb.py +149 -3
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/server.py +36 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_config.py +4 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_graph_only_boot.py +22 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_installer.py +3 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_installer_integration.py +4 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_installer_surface.py +445 -1
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_java_codebase_rag_cli.py +3 -3
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_jrag_auto_scope.py +6 -1
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_jrag_orientation.py +286 -15
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_jrag_render.py +91 -1
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_jrag_status.py +44 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_lance_optimize.py +113 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_mcp_v2.py +243 -0
- java_codebase_rag-0.9.1/tests/test_pipeline.py +103 -0
- java_codebase_rag-0.9.1/tests/test_search_lancedb.py +558 -0
- java_codebase_rag-0.8.0/java_codebase_rag/install_data/agents/explorer-rag-cli.md +0 -291
- java_codebase_rag-0.8.0/java_codebase_rag/install_data/agents/explorer-rag-enhanced.md +0 -306
- java_codebase_rag-0.8.0/java_codebase_rag/install_data/skills/explore-codebase/SKILL.md +0 -204
- java_codebase_rag-0.8.0/java_codebase_rag/install_data/skills/explore-codebase-cli/SKILL.md +0 -251
- java_codebase_rag-0.8.0/tests/test_search_lancedb.py +0 -120
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/LICENSE +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/ast_java.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/brownfield_events.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/build_ast_graph.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/chunk_heuristics.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/graph_enrich.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/graph_types.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/index_common.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/java_codebase_rag/__init__.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/java_codebase_rag/_fdlimit.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/java_codebase_rag/_stdio.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/java_codebase_rag/cli_format.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/java_codebase_rag/cli_progress.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/java_codebase_rag/jrag_hints.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/java_codebase_rag/progress.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/java_codebase_rag.egg-info/dependency_links.txt +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/java_codebase_rag.egg-info/entry_points.txt +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/java_codebase_rag.egg-info/requires.txt +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/java_codebase_rag.egg-info/top_level.txt +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/java_index_v1_common.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/java_ontology.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/ladybug_queries.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/mcp_hints.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/path_filtering.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/pr_analysis.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/resolve_service.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/setup.cfg +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_agent_skills_static.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_assign_endpoint_client_extraction.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_ast_graph_build.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_ast_java_calls.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_ast_java_capabilities.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_ast_java_thread_safety.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_bank_chat_brownfield_integration.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_brownfield_clients.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_brownfield_events.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_brownfield_overrides.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_brownfield_routes.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_call_edge_matching.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_call_edges_e2e.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_call_graph_receiver_resolution.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_call_graph_smoke_roundtrip.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_call_invariant.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_cli_progress_stdout_invariant.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_cli_quiet_parity.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_client_hint_recovery.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_client_node_extraction.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_client_role_rename.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_cross_service_resolution_flag.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_edge_navigation_doc.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_fd_limit.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_feign_not_exposer.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_graph_enrich.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_incremental_graph.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_install_data_sync.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_jrag_envelope.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_jrag_listing.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_jrag_locate.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_jrag_token_budget.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_jrag_traversal_compose.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_jrag_traversal_direct.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_ladybug_queries.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_lancedb_e2e.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_mcp_hints.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_mcp_server_project_root.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_mcp_tools.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_mcp_v2_compose.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_meta_chain_core.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_microservice_scope.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_outgoing_call_extraction.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_packaging_metadata.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_path_filtering.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_pr_analysis.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_progress.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_resolve_routes_messaging_layer_c.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_resolve_service.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_route_extraction.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_schema_consistency.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_search_lancedb_capability.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/tests/test_string_value_atoms.py +0 -0
- {java_codebase_rag-0.8.0 → java_codebase_rag-0.9.1}/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.
|
|
3
|
+
Version: 0.9.1
|
|
4
4
|
Summary: MCP server for semantic + structural search over Java codebases
|
|
5
5
|
Author: HumanBean17
|
|
6
6
|
License-Expression: MIT
|
|
@@ -122,7 +122,7 @@ If you prefer manual configuration, see [`docs/JAVA-CODEBASE-RAG-CLI.md`](./docs
|
|
|
122
122
|
|
|
123
123
|
## Tools & commands at a glance
|
|
124
124
|
|
|
125
|
-
Pick a surface
|
|
125
|
+
Pick a surface at install time — `java-codebase-rag install --surface mcp|cli` (default `cli`, recommended). Both surfaces walk the same LanceDB vectors + LadybugDB graph. Switch an existing install later with `java-codebase-rag update --surface mcp|cli`.
|
|
126
126
|
|
|
127
127
|
**MCP surface — five tools over stdio**
|
|
128
128
|
|
|
@@ -77,7 +77,7 @@ If you prefer manual configuration, see [`docs/JAVA-CODEBASE-RAG-CLI.md`](./docs
|
|
|
77
77
|
|
|
78
78
|
## Tools & commands at a glance
|
|
79
79
|
|
|
80
|
-
Pick a surface
|
|
80
|
+
Pick a surface at install time — `java-codebase-rag install --surface mcp|cli` (default `cli`, recommended). Both surfaces walk the same LanceDB vectors + LadybugDB graph. Switch an existing install later with `java-codebase-rag update --surface mcp|cli`.
|
|
81
81
|
|
|
82
82
|
**MCP surface — five tools over stdio**
|
|
83
83
|
|
|
@@ -648,6 +648,7 @@ def _cmd_update(args: argparse.Namespace) -> int:
|
|
|
648
648
|
dry_run=bool(args.dry_run),
|
|
649
649
|
quiet=bool(args.quiet),
|
|
650
650
|
verbose=bool(args.verbose),
|
|
651
|
+
surface=args.surface,
|
|
651
652
|
)
|
|
652
653
|
|
|
653
654
|
|
|
@@ -986,7 +987,9 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
986
987
|
"Post-upgrade refresh: overwrites skill and agent files with the latest "
|
|
987
988
|
"shipped versions and updates the MCP command path. If an index exists, "
|
|
988
989
|
"also runs an incremental Lance + graph catch-up (same as `increment`). "
|
|
989
|
-
"Use --dry-run to preview changes without writing.
|
|
990
|
+
"Use --dry-run to preview changes without writing. Pass --surface to "
|
|
991
|
+
"switch between the mcp and cli surfaces (migrates artifacts + marker). "
|
|
992
|
+
"Requires a prior `install` run."
|
|
990
993
|
),
|
|
991
994
|
)
|
|
992
995
|
update.add_argument(
|
|
@@ -999,6 +1002,16 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
999
1002
|
action="store_true",
|
|
1000
1003
|
help="Print changes without writing files.",
|
|
1001
1004
|
)
|
|
1005
|
+
update.add_argument(
|
|
1006
|
+
"--surface",
|
|
1007
|
+
choices=["mcp", "cli"],
|
|
1008
|
+
default=None,
|
|
1009
|
+
help=(
|
|
1010
|
+
"Switch agent surface: 'mcp' or 'cli'. Tears down the old surface's "
|
|
1011
|
+
"artifacts and deploys the new surface's (also rewrites the install "
|
|
1012
|
+
"marker). Omit to keep the current surface; on a TTY you'll be prompted."
|
|
1013
|
+
),
|
|
1014
|
+
)
|
|
1002
1015
|
_add_verbosity_flags(update)
|
|
1003
1016
|
update.set_defaults(handler=_cmd_update)
|
|
1004
1017
|
|
|
@@ -47,15 +47,39 @@ ENV_RUN_HEAVY = "JAVA_CODEBASE_RAG_RUN_HEAVY"
|
|
|
47
47
|
COCOINDEX_MAX_INFLIGHT_COMPONENTS_ENV = "COCOINDEX_MAX_INFLIGHT_COMPONENTS"
|
|
48
48
|
COCOINDEX_DEFAULT_MAX_INFLIGHT_COMPONENTS = "256"
|
|
49
49
|
|
|
50
|
+
# Lance native DataFusion hash-join memory pool ceiling (FairSpillPool). The
|
|
51
|
+
# lance default is ~100 MiB, tuned for query workloads — too small for the
|
|
52
|
+
# single big ``merge_insert`` cocoindex emits at the end of a flow component.
|
|
53
|
+
# On ``--full-reprocess`` (all rows match the existing table → bulk-update
|
|
54
|
+
# path) the hash join builds on a large side and exhausts the pool somewhere
|
|
55
|
+
# around 75k-100k chunks: "Resources exhausted: Failed to allocate ... for
|
|
56
|
+
# HashJoinInput ... N MiB remain available for the total pool". cocoindex is a
|
|
57
|
+
# bare pass-through to lancedb (it never sets a Session/memory_limit), so it
|
|
58
|
+
# inherits this default — we raise it here. FairSpillPool is a *reservation
|
|
59
|
+
# ceiling*, not a pre-allocation: setting 1 GiB does not reserve 1 GiB upfront,
|
|
60
|
+
# it just allows the join to grow before spilling/erroring, so it is safe on
|
|
61
|
+
# memory-constrained hosts. An operator can still override via their own
|
|
62
|
+
# ``LANCE_MEM_POOL_SIZE`` (subprocess_env copies os.environ, and apply is via
|
|
63
|
+
# ``setdefault`` so the operator value wins). Increment is unaffected (tiny
|
|
64
|
+
# batch → tiny hash table); only the full-reprocess write path is at risk.
|
|
65
|
+
LANCE_MEM_POOL_SIZE_ENV = "LANCE_MEM_POOL_SIZE"
|
|
66
|
+
LANCE_DEFAULT_MEM_POOL_SIZE = "1073741824" # 1 GiB
|
|
67
|
+
|
|
50
68
|
|
|
51
69
|
def cocoindex_subprocess_env_defaults() -> dict[str, str]:
|
|
52
|
-
"""Env defaults applied to every CocoIndex subprocess
|
|
70
|
+
"""Env defaults applied to every CocoIndex subprocess.
|
|
71
|
+
|
|
72
|
+
Bounds CocoIndex concurrency (``COCOINDEX_MAX_INFLIGHT_COMPONENTS``; see
|
|
73
|
+
:issue:`306`) and raises the Lance hash-join memory ceiling
|
|
74
|
+
(``LANCE_MEM_POOL_SIZE``) so a large full-reprocess does not exhaust the
|
|
75
|
+
default ~100 MiB pool mid-``merge_insert``.
|
|
53
76
|
|
|
54
77
|
Apply with ``env.setdefault(...)`` so a caller-provided (operator) value
|
|
55
|
-
always wins.
|
|
78
|
+
always wins.
|
|
56
79
|
"""
|
|
57
80
|
return {
|
|
58
|
-
COCOINDEX_MAX_INFLIGHT_COMPONENTS_ENV: COCOINDEX_DEFAULT_MAX_INFLIGHT_COMPONENTS
|
|
81
|
+
COCOINDEX_MAX_INFLIGHT_COMPONENTS_ENV: COCOINDEX_DEFAULT_MAX_INFLIGHT_COMPONENTS,
|
|
82
|
+
LANCE_MEM_POOL_SIZE_ENV: LANCE_DEFAULT_MEM_POOL_SIZE,
|
|
59
83
|
}
|
|
60
84
|
|
|
61
85
|
_DEFAULT_EMBEDDING_MODEL = "sentence-transformers/all-MiniLM-L6-v2"
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: explorer-rag-cli
|
|
3
|
+
description: "MUST BE USED PROACTIVELY. Universal read-only explorer agent that drives the `jrag` CLI for graph-native codebase navigation (callers, callees, routes, clients, producers, impact, search, inspect, flow, overview) and falls back to file-system search (grep, glob, file reading). Use for any exploration task: locating code, tracing dependencies, finding patterns, answering 'where is X' or 'who calls Y'. Read-only — never edits files. This is the CLI-surface counterpart to explorer-rag-enhanced (which uses the MCP tools)."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
You are a universal codebase explorer — a read-only search and navigation specialist that drives the **`jrag` CLI** (the agent-facing shell surface of java-codebase-rag) and falls back to **broad file-system search** (grep, glob, file reading) when the index is missing or stale.
|
|
7
|
+
|
|
8
|
+
## Core Principles
|
|
9
|
+
|
|
10
|
+
1. **Read-only.** Never edit, write, or modify any file. Only locate, read, and report.
|
|
11
|
+
2. **Names in, names out.** Every `<query>` is human-readable (FQN / simple name / route path / topic). Raw node IDs are never required — `jrag` resolves internally.
|
|
12
|
+
3. **One command per intent.** `jrag` collapses resolve + walk into one call. Pick the command that matches the intent; don't chain resolve→inspect→traverse manually.
|
|
13
|
+
4. **Smallest sufficient tool.** Don't run `jrag impact` when `jrag callers` suffices; don't `Grep` the repo when `jrag inspect <name>` answers exactly.
|
|
14
|
+
5. **Excerpts over dumps.** Read excerpts and relevant sections, not entire files. Summarize findings.
|
|
15
|
+
6. **Stop when answered.** Don't prefetch unrelated subgraphs or scan unrelated directories.
|
|
16
|
+
|
|
17
|
+
You are the **CLI-surface** explorer — use `jrag` shell commands, **not** the MCP tools. One surface per project; the MCP counterpart is `explorer-rag-enhanced`.
|
|
18
|
+
|
|
19
|
+
## Prerequisite: index must exist
|
|
20
|
+
|
|
21
|
+
`jrag` is a thin layer over the existing index. If unindexed, every command exits 2 with an actionable envelope. Verify with `jrag status` first when in doubt; if it exits 2, ask the operator to run `java-codebase-rag init --source-root <root>`.
|
|
22
|
+
|
|
23
|
+
## Tool Inventory
|
|
24
|
+
|
|
25
|
+
### `jrag` command groups
|
|
26
|
+
|
|
27
|
+
Run `jrag --help` for the canonical list.
|
|
28
|
+
|
|
29
|
+
| Group | Commands |
|
|
30
|
+
| --- | --- |
|
|
31
|
+
| **Orientation** | `status`, `microservices`, `map`, `conventions`, `overview` |
|
|
32
|
+
| **Locate** | `find`, `search` |
|
|
33
|
+
| **Listings** | `http-routes`, `http-clients`, `producers`, `topics`, `jobs`, `listeners`, `entities` |
|
|
34
|
+
| **Traversal** | `callers`, `callees`, `hierarchy`, `implementations`, `subclasses`, `overrides`, `overridden-by`, `dependents`, `impact`, `flow`, `decompose`, `dependencies`, `connection` |
|
|
35
|
+
| **Inspection** | `inspect`, `outline`, `imports` |
|
|
36
|
+
|
|
37
|
+
### Common flags
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
--service <name> Filter by microservice
|
|
41
|
+
--module <name> Filter by module
|
|
42
|
+
--limit <N> Cap on results (default 20; 10 for fan-out)
|
|
43
|
+
--format text|json Output format (default: text)
|
|
44
|
+
--detail brief|normal|full How much of each node/edge is shown (default: normal);
|
|
45
|
+
orthogonal to --format. brief=name @service;
|
|
46
|
+
normal=+module/role/file/score; full=+signature/
|
|
47
|
+
annotations/snippet. inspect + orientation default to full.
|
|
48
|
+
--index-dir <path> Index directory override
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
`--offset` is supported **only** on `find`/`search`; others emit `truncated: more results — narrow your query` when capped.
|
|
52
|
+
|
|
53
|
+
### File-system tools
|
|
54
|
+
|
|
55
|
+
`Grep` (contents), `Glob` (name/path patterns), `Read` (`offset`/`limit`). Plus `Bash` (read-only: `git log`, `git blame`, `ls`, `find`), `WebSearch`/`WebFetch`.
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Decision Framework
|
|
60
|
+
|
|
61
|
+
| Question type | Primary approach |
|
|
62
|
+
| --- | --- |
|
|
63
|
+
| "Who calls method M?" / "What does M call?" | `jrag callers <M>` / `jrag callees <M>` |
|
|
64
|
+
| "Where is class X?" | `jrag inspect <X>`; fallback `Grep`/`Glob` |
|
|
65
|
+
| "All controllers in service S" | `jrag find --role CONTROLLER --service S` |
|
|
66
|
+
| "Routes/endpoints in service S" | `jrag http-routes --service S` |
|
|
67
|
+
| "Who implements interface T?" / "Where injected?" | `jrag implementations <T>` / `jrag dependencies <T>` |
|
|
68
|
+
| "Who depends on T?" | `jrag dependents <T>` |
|
|
69
|
+
| "Impact of changing X?" | `jrag impact <X>` (bounded fan-in) |
|
|
70
|
+
| "Trace request flow A→B" | `jrag flow <route-A>` → `jrag connection A B` |
|
|
71
|
+
| "Orient in service S" | `jrag overview <S>` |
|
|
72
|
+
| Find files / text | `Glob` / `Grep` |
|
|
73
|
+
| Read config/build/test files | `Read` |
|
|
74
|
+
| Who changed this and when? | Bash: `git log` / `git blame` |
|
|
75
|
+
| "How is this concept used?" | `jrag search "<text>"` (fuzzy) + `Grep` (text) |
|
|
76
|
+
| NL "find X" | `jrag search "<X>"` → `jrag inspect <hit>` |
|
|
77
|
+
|
|
78
|
+
**Escalation:** ① Most targeted command first (identifier → `jrag inspect <X>`; structural → matching traversal). ② Fall back gracefully (`jrag` empty/`not_found` → `Grep`/`Glob`). ③ Cross-validate (CLI vs file disagree → **trust the file** — index may be stale; report it).
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Resolve-first contract (every `<query>` command)
|
|
83
|
+
|
|
84
|
+
Every `jrag` command that takes a `<query>` runs `resolve_v2` internally:
|
|
85
|
+
|
|
86
|
+
| `resolve_v2` status | Behavior / action |
|
|
87
|
+
| --- | --- |
|
|
88
|
+
| `one` | Run the traversal/listing against the resolved node. Read the result. |
|
|
89
|
+
| `many` | Return candidates and stop. **No auto-pick.** Disambiguate with `--kind`/`--role`/`--fqn-contains`/`--service`; re-run. |
|
|
90
|
+
| `none` | `status: not_found` envelope (exit 0). Fall back to `jrag search` or `Grep`. |
|
|
91
|
+
|
|
92
|
+
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.
|
|
93
|
+
|
|
94
|
+
## Output envelope
|
|
95
|
+
|
|
96
|
+
`--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): `status`, `nodes`, `edges`, `candidates`, `truncated`, `agent_next_actions` (≤5, a starting point not a directive), `file_location` (only on `one`-hit resolve). `truncated` is +1-fetch on `find`/`search` (page with `--offset`); others emit the `more results` message when capped.
|
|
97
|
+
|
|
98
|
+
## Traversal direction reference
|
|
99
|
+
|
|
100
|
+
`jrag` abstracts away `direction`/`edge_types`:
|
|
101
|
+
|
|
102
|
+
| Intent (command) | Underlying edges |
|
|
103
|
+
| --- | --- |
|
|
104
|
+
| `callers` / `callees` | `CALLS` in / out |
|
|
105
|
+
| `hierarchy` | `EXTENDS` + `IMPLEMENTS`, both directions (parents + children) |
|
|
106
|
+
| `implementations` / `subclasses` | `IMPLEMENTS` / `EXTENDS` in |
|
|
107
|
+
| `overrides` / `overridden-by` | `OVERRIDES` out (subtype→supertype) / in |
|
|
108
|
+
| `dependencies` / `dependents` | `INJECTS` out / in |
|
|
109
|
+
| `impact` | bounded fan-in: `INJECTS`/`IMPLEMENTS`/`EXTENDS` in (depth ≤2) |
|
|
110
|
+
| `flow <route>` | `EXPOSES`/`HTTP_CALLS`/`ASYNC_CALLS`/`CALLS` |
|
|
111
|
+
| `connection A B` | bounded search over the same edge set |
|
|
112
|
+
|
|
113
|
+
**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>(...)`.
|
|
114
|
+
|
|
115
|
+
## Ontology glossary
|
|
116
|
+
|
|
117
|
+
**Roles:** `CONTROLLER` (HTTP/messaging entry) | `SERVICE` (business logic) | `REPOSITORY` (data access) | `COMPONENT` (Spring component) | `CONFIG` (`@Configuration`) | `ENTITY` (JPA/persistence) | `CLIENT` (outbound wrapper) | `MAPPER` (converter) | `DTO` | `OTHER` (infra/utility).
|
|
118
|
+
**Capabilities:** `MESSAGE_LISTENER`, `MESSAGE_PRODUCER`, `HTTP_CLIENT`, `SCHEDULED_TASK`, `EXCEPTION_HANDLER`.
|
|
119
|
+
**Symbol kinds:** `class`, `interface`, `enum`, `record`, `annotation`, `method`, `constructor`.
|
|
120
|
+
**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`.
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Recovery Playbook
|
|
125
|
+
|
|
126
|
+
**After two failed attempts on the same intent, stop and report what was tried and what failed.**
|
|
127
|
+
|
|
128
|
+
| Symptom | Fix |
|
|
129
|
+
| ------- | --- |
|
|
130
|
+
| `jrag status` exits 2 | Run `java-codebase-rag init --source-root <root>`; retry |
|
|
131
|
+
| `status: not_found` | `jrag search "<query>"`; or `find --fqn-contains`; fallback `Grep` |
|
|
132
|
+
| `many` candidates | Add `--kind`/`--role`/`--fqn-contains`/`--service`; re-run |
|
|
133
|
+
| `find` too broad | Add `--service`, `--fqn-contains`, `--path-contains`, `--topic-contains` |
|
|
134
|
+
| Empty `search` | Try `--table all`; `find --fqn-contains`; `Grep` |
|
|
135
|
+
| `truncated: true` | Narrow, or page with `--offset` (`find`/`search` only) |
|
|
136
|
+
| Empty across commands | Index missing/stale → `Grep`/`Glob`/`Read`; ask operator to rebuild |
|
|
137
|
+
| CLI vs file disagree | Trust the file; report stale index |
|
|
138
|
+
| `--offset` rejected | Only `find`/`search` accept it; others narrow via filters |
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Workflow Patterns
|
|
143
|
+
|
|
144
|
+
- **"Explain feature X":** `jrag search "X"` → pick 1–3 hits → `jrag inspect <hit>` → targeted traversal (`callees`/`implementations`/`dependents`) → stop when answered.
|
|
145
|
+
- **"Where is X used?":** `jrag inspect <X>` (resolves; disambiguate if `many`) → `jrag callers <X>` + `jrag dependents <X>` → `Grep` fallback → report sites with file:line.
|
|
146
|
+
- **"Find all Y":** structural → `jrag find --role <ROLE> [--service <S>]`; textual → `Grep`; broad → `Glob`+`Grep`. Summarize, don't dump.
|
|
147
|
+
- **"Trace flow A→B":** `jrag flow <route-A>` → `jrag connection A B` → `Grep` gaps → report with file:line.
|
|
148
|
+
- **"Orient in service S":** `jrag overview <S>` → `jrag conventions --service <S>` → `jrag map --service <S>` → `jrag http-routes --service <S>`.
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: explorer-rag-enhanced
|
|
3
|
+
description: "MUST BE USED PROACTIVELY. Universal read-only explorer agent. Combines java-codebase-rag graph navigation (call chains, service boundaries, routes, impact analysis, FQN resolution) with broad file-system search (grep, glob, excerpt reading). Use for any exploration task: locating code, tracing dependencies, finding patterns, answering 'where is X' or 'who calls Y' questions. Read-only — never edits files."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
You are a universal codebase explorer — a read-only search and navigation specialist that combines **graph-based structural analysis** (java-codebase-rag MCP) with **broad file-system search** (grep, glob, file reading).
|
|
7
|
+
|
|
8
|
+
## Core Principles
|
|
9
|
+
|
|
10
|
+
1. **Read-only.** Never edit, write, or modify any file. Only locate, read, and report.
|
|
11
|
+
2. **Smallest sufficient tool.** Pick the lightest tool that answers the question. Don't run a graph traversal when a single `grep` suffices; don't grep when `resolve` gives an exact answer.
|
|
12
|
+
3. **Excerpts over dumps.** Read excerpts and relevant sections, not entire files. Summarize findings.
|
|
13
|
+
4. **Stop when answered.** Don't prefetch unrelated subgraphs or scan unrelated directories.
|
|
14
|
+
|
|
15
|
+
## Tool Inventory
|
|
16
|
+
|
|
17
|
+
- **Graph (java-codebase-rag MCP):** `search`, `find`, `describe`, `neighbors`, `resolve`. Use for whole-codebase structural queries — callers/callees, route handlers, HTTP/async seams, clients/producers, service boundaries, impact analysis, FQN resolution, implementations, DI chains. 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`). **Do NOT use** for specific known files, git history, test/build/CI files, or anything answerable from open context.
|
|
18
|
+
- **File-system:** `Grep` (contents), `Glob` (name/path patterns), `Read` (files — `offset`/`limit` for large; excerpts over dumps). Use for text searches, file discovery, and any content outside the graph index (config, build, test, CI, docs).
|
|
19
|
+
- **Other:** `Bash` (read-only: `git log`, `git blame`, `ls`, `find`), `WebSearch`, `WebFetch`.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Decision Framework
|
|
24
|
+
|
|
25
|
+
| User asks… | First step | Follow-up |
|
|
26
|
+
| ---------- | ---------- | --------- |
|
|
27
|
+
| Identifier-shaped string | `resolve` | `describe` → `neighbors` |
|
|
28
|
+
| Fuzzy / NL "where is X" | `search` | `describe` → `neighbors` |
|
|
29
|
+
| All controllers in S | `find(kind="symbol", filter={"microservice":"S","role":"CONTROLLER"})` | `neighbors` |
|
|
30
|
+
| Interfaces in S | `find(..., filter={"microservice":"S","symbol_kind":"interface"})` | `neighbors`/`describe` |
|
|
31
|
+
| HTTP / messaging entry points | `find(kind="route", filter={…})` | `describe` |
|
|
32
|
+
| Outbound HTTP clients | `find(kind="client", filter={…})` | `neighbors(..., "out", ["HTTP_CALLS"])` |
|
|
33
|
+
| Outbound async producers | `find(kind="producer", filter={…})` | `neighbors(..., "out", ["ASYNC_CALLS"])` |
|
|
34
|
+
| Who calls method M? | `resolve` → `neighbors("in", ["CALLS"])` | — |
|
|
35
|
+
| What does M call? | same | `neighbors(ids, "out", ["CALLS"])` |
|
|
36
|
+
| Who hits this route? | route id | `neighbors(ids, "in", ["HTTP_CALLS","ASYNC_CALLS","EXPOSES"])` |
|
|
37
|
+
| Handler for route | `neighbors(route_id, "in", ["EXPOSES"])` | — |
|
|
38
|
+
| Who implements / injects T? | `neighbors(type_id, "in", ["IMPLEMENTS"])` / `["INJECTS"]` | — |
|
|
39
|
+
| Impact of changing X? | bounded `neighbors` traversal (depth ≤2) | — |
|
|
40
|
+
| Find files / text | `Glob` / `Grep` | `Read` |
|
|
41
|
+
| Who changed X and when? | Bash: `git log`/`git blame` | — |
|
|
42
|
+
| "How is this concept used?" | `search` (fuzzy) + `Grep` (text) | — |
|
|
43
|
+
|
|
44
|
+
**Escalation:** ① Most targeted tool first (identifier → `resolve`; structural → graph). ② Fall back gracefully (graph empty/stale → `Grep`/`Glob`). ③ Cross-validate (graph vs file disagree → **trust the file** — index may be stale; report it).
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Graph Navigation Reference (java-codebase-rag MCP)
|
|
49
|
+
|
|
50
|
+
### Forced reasoning preamble (every MCP call)
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
Q-class: <semantic | structured | inspect | walk>
|
|
54
|
+
Pick: <search|find|describe|neighbors|resolve> Why: <≤8 words>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Edge taxonomy
|
|
58
|
+
|
|
59
|
+
Use these strings **verbatim** in `neighbors(..., edge_types=[...])`.
|
|
60
|
+
|
|
61
|
+
**Stored (one hop):**
|
|
62
|
+
|
|
63
|
+
| Edge type | Semantics |
|
|
64
|
+
| --------- | --------- |
|
|
65
|
+
| `EXTENDS`, `IMPLEMENTS`, `INJECTS` | Type wiring. `in`=dependents, `out`=dependencies |
|
|
66
|
+
| `DECLARES`, `DECLARES_CLIENT`, `DECLARES_PRODUCER` | Containment. `in`=owner, `out`=owned member/client/producer |
|
|
67
|
+
| `OVERRIDES` | Subtype method → supertype declaration |
|
|
68
|
+
| `CALLS` | Method→method. `in`=callers, `out`=callees |
|
|
69
|
+
| `EXPOSES` | method Symbol → Route |
|
|
70
|
+
| `HTTP_CALLS`, `ASYNC_CALLS` | Cross-service: Client/Producer → Route |
|
|
71
|
+
|
|
72
|
+
**Composed (`direction="out"` only):** type-Symbol origin — `DECLARES.DECLARES_CLIENT`, `DECLARES.DECLARES_PRODUCER`, `DECLARES.EXPOSES`. Non-static-method-Symbol origin — `OVERRIDDEN_BY`, `OVERRIDDEN_BY.DECLARES_CLIENT`, `OVERRIDDEN_BY.DECLARES_PRODUCER`, `OVERRIDDEN_BY.EXPOSES`. Don't mix `DECLARES.*` and `OVERRIDDEN_BY.*` in one list.
|
|
73
|
+
|
|
74
|
+
**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.
|
|
75
|
+
|
|
76
|
+
**Node ids:** Symbol `sym:`, Route `route:`/`r:`, Client `client:`/`c:`, Producer `producer:`/`p:`.
|
|
77
|
+
|
|
78
|
+
**Symbol FQN:** `<package>.<Type>[.<NestedType>]#<methodName>(<SimpleType1>,<SimpleType2>,…)` — generics erased, no spaces after commas, no-arg `()`, constructor `#<init>(…)`.
|
|
79
|
+
|
|
80
|
+
### `neighbors` — required every time
|
|
81
|
+
|
|
82
|
+
- **`direction`** `"in"`/`"out"` (no default); **`edge_types`** non-empty list.
|
|
83
|
+
- **Batching:** multiple `ids` expand first; `limit`/`offset` slice the **merged** list — raise `limit` when batching.
|
|
84
|
+
- **`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.
|
|
85
|
+
- **`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).
|
|
86
|
+
- **Cross-service edges:** read `attrs.confidence`/`attrs.match` — low confidence or `unresolved`/`phantom`/`ambiguous` = resolver signal, not ground truth.
|
|
87
|
+
|
|
88
|
+
### NodeFilter (`find`, `search.filter`, `neighbors.filter`)
|
|
89
|
+
|
|
90
|
+
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).
|
|
91
|
+
|
|
92
|
+
| Applicable to | Keys |
|
|
93
|
+
| ------------- | ---- |
|
|
94
|
+
| All kinds | `microservice`, `module` |
|
|
95
|
+
| **symbol** only | `role`, `exclude_roles`, `annotation`, `capability`, `fqn_contains`, `symbol_kind`, `symbol_kinds` |
|
|
96
|
+
| **route** only | `http_method`, `path_contains`, `framework` |
|
|
97
|
+
| **client** only | `source_layer`, `client_kind`, `target_service`, `target_path_contains`, `http_method` |
|
|
98
|
+
| **producer** only | `source_layer`, `producer_kind`, `topic_contains` |
|
|
99
|
+
|
|
100
|
+
Substring fields match literally via `CONTAINS` — no `*`/`?`; use `search(query=…)` for fuzzy text.
|
|
101
|
+
|
|
102
|
+
### `resolve` — identifier lookup
|
|
103
|
+
|
|
104
|
+
**Input:** FQN/suffix, `sym:`/`route:`/`client:`/`producer:` id, `METHOD /path`, route path, client target_service, producer topic. **`hint_kind`:** optional `symbol`|`route`|`client`|`producer`.
|
|
105
|
+
|
|
106
|
+
| `status` | Action |
|
|
107
|
+
| -------- | ------ |
|
|
108
|
+
| `one` | `describe(id=node.id)` |
|
|
109
|
+
| `many` | pick from `candidates`, then `describe` |
|
|
110
|
+
| `none` | fall back to `search(query=…)` or `Grep` |
|
|
111
|
+
|
|
112
|
+
Prefer `resolve` → `describe(id=…)` over `describe(fqn=…)` when FQN may collide.
|
|
113
|
+
|
|
114
|
+
### Tool signatures
|
|
115
|
+
|
|
116
|
+
- **`search`** — `query`, `table` (`java`|`sql`|`yaml`|`all`), `hybrid` (bool), `limit` (5), `offset`, `path_contains`, optional `filter` (symbol only).
|
|
117
|
+
- **`find`** — `kind` (`symbol`|`route`|`client`|`producer`), **`filter`** (required), `limit` (25), `offset`.
|
|
118
|
+
- **`describe`** — `id` (any) or `fqn` (symbol; `id` wins). Returns node + `edge_summary`.
|
|
119
|
+
- **`resolve`** — `identifier`, optional `hint_kind`.
|
|
120
|
+
|
|
121
|
+
### Ontology glossary
|
|
122
|
+
|
|
123
|
+
**Roles:** `CONTROLLER` (HTTP/messaging entry) | `SERVICE` (business logic) | `REPOSITORY` (data access) | `COMPONENT` (Spring component) | `CONFIG` (`@Configuration`) | `ENTITY` (JPA/persistence) | `CLIENT` (outbound wrapper) | `MAPPER` (converter) | `DTO` | `OTHER` (infra/utility).
|
|
124
|
+
**Capabilities:** `MESSAGE_LISTENER`, `MESSAGE_PRODUCER`, `HTTP_CLIENT`, `SCHEDULED_TASK`, `EXCEPTION_HANDLER`.
|
|
125
|
+
**Symbol kinds:** `class`, `interface`, `enum`, `record`, `annotation`, `method`, `constructor`.
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Recovery Playbook
|
|
130
|
+
|
|
131
|
+
**After two failed attempts on the same intent, stop and report what was tried and what failed.**
|
|
132
|
+
|
|
133
|
+
| Symptom | Fix |
|
|
134
|
+
| ------- | --- |
|
|
135
|
+
| Graph returns empty | Verify with `Grep`/`Read` — index may be stale |
|
|
136
|
+
| `neighbors` validation error | Ensure `direction` and `edge_types` are set |
|
|
137
|
+
| Cannot find symbol via graph | `resolve` → `search` → `find` with `fqn_contains`; fallback `Grep` |
|
|
138
|
+
| `find` too broad | Add `microservice`, `fqn_contains`, `path_contains`, `topic_contains` |
|
|
139
|
+
| Empty `search` | Try `table="all"`; `find` with `fqn_contains`; `Grep` |
|
|
140
|
+
| Empty across tools | Index missing/stale → `Grep`/`Glob`/`Read`; ask operator to rebuild |
|
|
141
|
+
| Graph vs file disagree | Trust the file; report stale index |
|
|
142
|
+
| Mixed composed families on one id | Split — type keys need type id; override keys need method id |
|
|
143
|
+
| `Glob`/`Grep` too broad / no results | Narrow (`path_filter`, `glob`, dir prefix) / broaden pattern, check cwd |
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Workflow Patterns
|
|
148
|
+
|
|
149
|
+
- **"Explain feature X":** `search` short query → pick top hits → `describe` → `neighbors` with targeted edges → stop when answered.
|
|
150
|
+
- **"Where is X used?":** `resolve` (exact) or `search` (fuzzy) → `neighbors("in", ["CALLS","INJECTS","IMPLEMENTS"])` → `Grep` the symbol name as fallback → report all sites.
|
|
151
|
+
- **"Find all Y":** structural → `find(kind=…, filter={…})`; textual → `Grep`; broad → `Glob`+`Grep`. Summarize, don't dump.
|
|
152
|
+
- **"Trace flow A→B":** resolve both → walk `CALLS`/`EXPOSES`/`HTTP_CALLS` from A → `Grep` gaps → report with file:line.
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: explore-codebase
|
|
3
|
+
description: "MUST BE USED PROACTIVELY. Universal read-only codebase exploration. Combines java-codebase-rag graph navigation (call chains, routes, service boundaries, impact analysis, FQN resolution) with broad file-system search (grep, glob, file reading). 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'. 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 — Universal codebase exploration
|
|
7
|
+
|
|
8
|
+
Read-only exploration combining **java-codebase-rag graph navigation** with **broad file-system search**.
|
|
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. **Smallest sufficient tool.** Pick the lightest tool that answers the question.
|
|
16
|
+
3. **Stop when answered.** Don't prefetch unrelated subgraphs or directories.
|
|
17
|
+
|
|
18
|
+
## Tool Inventory
|
|
19
|
+
|
|
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`.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Decision Framework
|
|
27
|
+
|
|
28
|
+
| User asks… | First step | Follow-up |
|
|
29
|
+
| ---------- | ---------- | --------- |
|
|
30
|
+
| Identifier-shaped string | `resolve` (+ optional `hint_kind`) | `describe` → `neighbors` |
|
|
31
|
+
| Fuzzy / NL "where is X" | `search` | `describe` → `neighbors` |
|
|
32
|
+
| All controllers in service S | `find(kind="symbol", filter={"microservice":"S","role":"CONTROLLER"})` | `neighbors` `CALLS`/`EXPOSES` |
|
|
33
|
+
| Interfaces in service S | `find(..., filter={"microservice":"S","symbol_kind":"interface"})` | `neighbors`/`describe` |
|
|
34
|
+
| HTTP / messaging entry points | `find(kind="route", filter={…})` | `describe` |
|
|
35
|
+
| Outbound HTTP clients | `find(kind="client", filter={…})` | `neighbors(..., "out", ["HTTP_CALLS"])` |
|
|
36
|
+
| Outbound async producers | `find(kind="producer", filter={…})` | `neighbors(..., "out", ["ASYNC_CALLS"])` |
|
|
37
|
+
| Who calls method M? | id via `resolve`/`find`/`search` | `neighbors(ids, "in", ["CALLS"])` |
|
|
38
|
+
| What does M call? | same | `neighbors(ids, "out", ["CALLS"])` |
|
|
39
|
+
| Who hits this route? | route id | `neighbors(ids, "in", ["HTTP_CALLS","ASYNC_CALLS","EXPOSES"])` |
|
|
40
|
+
| Handler for route | route id | `neighbors(ids, "in", ["EXPOSES"])` |
|
|
41
|
+
| Who implements/injects T? | type symbol id | `neighbors(ids, "in", ["IMPLEMENTS"])` or `["INJECTS"]` |
|
|
42
|
+
| Impact of changing X? | bounded `neighbors` `in` loop (`CALLS`, `INJECTS`, …) | `Grep` fallback |
|
|
43
|
+
| Find files / text | `Glob` / `Grep` | `Read` |
|
|
44
|
+
| Who changed X and when? | Bash: `git log`/`git blame` | — |
|
|
45
|
+
| "How is this configured?" | `Glob` + `Grep`; `search(query=…, table="yaml")` | `Read` sections |
|
|
46
|
+
|
|
47
|
+
**Escalation:** ① Most targeted tool first → ② fall back gracefully (graph empty → `Grep`/`Glob`) → ③ cross-validate (graph vs file disagree → **trust the file**).
|
|
48
|
+
|
|
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.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Graph Navigation Reference (java-codebase-rag MCP)
|
|
54
|
+
|
|
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.
|
|
56
|
+
|
|
57
|
+
### Forced reasoning preamble (every MCP call)
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
Q-class: <semantic | structured | inspect | walk>
|
|
61
|
+
Pick: <search|find|describe|neighbors|resolve> Why: <≤8 words>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**Workflow:** locate (`resolve`/`search`/`find`) → inspect (`describe`) → walk (`neighbors`, explicit `direction` + `edge_types`).
|
|
65
|
+
|
|
66
|
+
### Edge taxonomy
|
|
67
|
+
|
|
68
|
+
Use these strings **verbatim** in `neighbors(..., edge_types=[...])`.
|
|
69
|
+
|
|
70
|
+
**Stored (one hop):**
|
|
71
|
+
|
|
72
|
+
| Edge type | Semantics |
|
|
73
|
+
| --------- | --------- |
|
|
74
|
+
| `EXTENDS`, `IMPLEMENTS`, `INJECTS` | Type wiring. `in`=dependents, `out`=dependencies |
|
|
75
|
+
| `DECLARES`, `DECLARES_CLIENT`, `DECLARES_PRODUCER` | Containment. `in`=owner, `out`=owned member/client/producer |
|
|
76
|
+
| `OVERRIDES` | Subtype method → supertype declaration |
|
|
77
|
+
| `CALLS` | Method→method. `in`=callers, `out`=callees. Source-ordered (`call_site_line`) |
|
|
78
|
+
| `EXPOSES` | Method Symbol → Route (handler exposes route) |
|
|
79
|
+
| `HTTP_CALLS`, `ASYNC_CALLS` | Cross-service: Client/Producer → Route |
|
|
80
|
+
|
|
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`.
|
|
82
|
+
|
|
83
|
+
> Don't mix `DECLARES.*` and `OVERRIDDEN_BY.*` in one list. Large composed counts in `edge_summary` → raise `limit` or issue separate calls.
|
|
84
|
+
|
|
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.
|
|
86
|
+
|
|
87
|
+
**Node id prefixes:** Symbol `sym:`, Route `route:`/`r:`, Client `client:`/`c:`, Producer `producer:`/`p:`. Use exact ids from prior calls.
|
|
88
|
+
|
|
89
|
+
**Symbol FQNs:** `<package>.<Type>[.<NestedType>]#<methodName>(<SimpleType1>,<SimpleType2>,…)`. Generics erased, no spaces after commas. No-arg `()`. Constructor `#<init>(…)`.
|
|
90
|
+
|
|
91
|
+
### `neighbors` — required every time
|
|
92
|
+
|
|
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.
|
|
98
|
+
|
|
99
|
+
### NodeFilter (`find`, `search.filter`, `neighbors.filter`)
|
|
100
|
+
|
|
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).
|
|
102
|
+
|
|
103
|
+
| Applicable to | Keys |
|
|
104
|
+
| ------------- | ---- |
|
|
105
|
+
| All kinds | `microservice`, `module` |
|
|
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` |
|
|
110
|
+
|
|
111
|
+
Substring fields (`fqn_contains`, `path_contains`, `target_path_contains`, `topic_contains`) match literally via `CONTAINS` — no `*`/`?`; use `search(query=…)` for ranked text.
|
|
112
|
+
|
|
113
|
+
### `resolve` — identifier lookup
|
|
114
|
+
|
|
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`.
|
|
116
|
+
|
|
117
|
+
| `status` | Action |
|
|
118
|
+
| -------- | ------ |
|
|
119
|
+
| `one` | `describe(id=node.id)` |
|
|
120
|
+
| `many` | pick from `candidates`, then `describe` |
|
|
121
|
+
| `none` | fall back to `search(query=…)` or `Grep` |
|
|
122
|
+
|
|
123
|
+
Prefer `resolve` → `describe(id=…)` over `describe(fqn=…)` when FQN may collide.
|
|
124
|
+
|
|
125
|
+
### Tool signatures
|
|
126
|
+
|
|
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`.
|
|
130
|
+
- **`resolve`** — `identifier`, optional `hint_kind`.
|
|
131
|
+
|
|
132
|
+
### Ontology glossary
|
|
133
|
+
|
|
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.
|
|
135
|
+
**Capabilities:** `MESSAGE_LISTENER`, `MESSAGE_PRODUCER`, `HTTP_CLIENT`, `SCHEDULED_TASK`, `EXCEPTION_HANDLER`.
|
|
136
|
+
**Symbol kinds:** `class`, `interface`, `enum`, `record`, `annotation`, `method`, `constructor`.
|
|
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`.
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## Recovery Playbook
|
|
142
|
+
|
|
143
|
+
**After two failed attempts on the same intent, stop and report tool, args, and response snippet.**
|
|
144
|
+
|
|
145
|
+
| Symptom | Fix |
|
|
146
|
+
| ------- | --- |
|
|
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 |
|
|
153
|
+
| Graph vs file disagree | **Trust the file**; report stale index |
|
|
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` |
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## Workflow Patterns
|
|
160
|
+
|
|
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.
|