Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions crates/rpg-mcp/src/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,3 +210,19 @@ pub(crate) struct SliceBetweenParams {
/// Include entity metadata (name, file, features) in output
pub(crate) include_metadata: Option<bool>,
}

/// Parameters for the `analyze_health` tool.
#[derive(Debug, Deserialize, JsonSchema)]
pub(crate) struct AnalyzeHealthParams {
/// Instability threshold above which entities are flagged as highly unstable (default: 0.7).
pub(crate) instability_threshold: Option<f64>,
/// Minimum total degree for god object detection (default: 10).
pub(crate) god_object_threshold: Option<usize>,
/// Run Rabin-Karp token-based clone detection (reads source files from disk, slower). Default: false.
pub(crate) include_duplication: Option<bool>,
/// Run Jaccard feature-based semantic clone detection (in-memory, fast).
/// Requires entities to have been lifted. Default: false.
pub(crate) include_semantic_duplication: Option<bool>,
/// Jaccard similarity threshold for semantic clone detection (default: 0.6).
pub(crate) semantic_similarity_threshold: Option<f64>,
}
34 changes: 34 additions & 0 deletions crates/rpg-mcp/src/prompts/server_instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,39 @@ When using the RPG to understand or navigate a codebase (after lifting is comple
- Use `context_pack` instead of search→fetch→explore chains (1 call vs 3-5, ~44% fewer tokens)
- Use `impact_radius` for richer reachability analysis with edge paths (1 call vs multi-step explore)

## HEALTH ANALYSIS

Use `analyze_health` to assess architectural quality of the codebase. It computes
instability, centrality, coupling metrics, and optionally detects code duplication.

**When to use:** After lifting is complete, to identify refactoring targets, god objects,
unstable modules, and duplicated code.

**Parameters (all optional):**
- `instability_threshold` (default 0.7) — flag entities with instability above this
- `god_object_threshold` (default 10) — minimum degree to flag as god object
- `include_duplication` (default false) — run Rabin-Karp token-based clone detection (reads source files, slower)
- `include_semantic_duplication` (default false) — run Jaccard feature-based clone detection (in-memory, fast)
- `semantic_similarity_threshold` (default 0.6) — Jaccard threshold for semantic clones

**Output sections:**
- Summary: entity count, edges, avg instability/centrality, god objects, hubs
- God Object Candidates (degree ≥ threshold)
- Top Unstable Entities (I > 0.7)
- Hub Entities (high centrality)
- Duplication Hotspots (when `include_duplication=true`) — token-level Type-1/Type-2 clones
- Semantic Duplication (when `include_semantic_duplication=true`) — conceptual clones via lifted features
- Recommendations for refactoring

**Examples:**
```json
{} // baseline health (no duplication)
{"include_duplication": true} // + token-based clones
{"include_semantic_duplication": true} // + conceptual clones
{"include_duplication": true, "include_semantic_duplication": true} // both
{"god_object_threshold": 5, "instability_threshold": 0.5} // stricter thresholds
```

## TOOLS
- **lifting_status**: Dashboard — coverage, per-area progress, unlifted files, NEXT STEP
- **build_rpg**: Index the codebase (run once, instant)
Expand All @@ -148,6 +181,7 @@ When using the RPG to understand or navigate a codebase (after lifting is comple
- **context_pack**: Single-call search+fetch+explore. Searches, fetches source, expands neighbors, trims to token budget
- **impact_radius**: BFS reachability with edge paths. Answers "what depends on X?" in one call. Traverses DataFlow edges for data lineage analysis
- **plan_change**: Change planning — find relevant entities, dependency-safe modification order, impact radius, and related tests
- **analyze_health**: Architectural health analysis — instability, centrality, god objects, duplication detection (token + semantic)
- **rpg_info**: Get codebase overview, statistics, and inter-area connectivity
- **update_rpg**: Incrementally update after code changes
- **reload_rpg**: Reload graph from disk
33 changes: 33 additions & 0 deletions crates/rpg-mcp/src/tools.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2883,6 +2883,39 @@ impl RpgServer {

Ok(result)
}

#[tool(
description = "Analyze code health metrics including coupling, instability, centrality, and potential god objects. Returns entities with architectural issues and recommendations for refactoring. Set include_duplication=true to detect code clones via Rabin-Karp fingerprinting (reads source files, slower). Set include_semantic_duplication=true to detect conceptual duplicates via Jaccard similarity on lifted features (in-memory, fast; requires entities to be lifted)."
)]
async fn analyze_health(
&self,
Parameters(params): Parameters<AnalyzeHealthParams>,
) -> Result<String, String> {
self.ensure_graph().await?;
let notice = self.staleness_notice().await;
let guard = self.graph.read().await;
let graph = guard.as_ref().unwrap();

let config = rpg_nav::health::HealthConfig {
instability_threshold: params.instability_threshold.unwrap_or(0.7),
god_object_degree_threshold: params.god_object_threshold.unwrap_or(10),
include_duplication: params.include_duplication.unwrap_or(false),
include_semantic_duplication: params.include_semantic_duplication.unwrap_or(false),
semantic_duplication_config: rpg_nav::duplication::SemanticDuplicationConfig {
similarity_threshold: params.semantic_similarity_threshold.unwrap_or(0.6),
..Default::default()
},
..Default::default()
};

let report = rpg_nav::health::compute_health_full(graph, &self.project_root, &config);

Ok(format!(
"{}{}",
notice,
rpg_nav::toon::format_health_report(&report)
))
}
}

impl RpgServer {
Expand Down
1 change: 1 addition & 0 deletions crates/rpg-nav/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ strsim.workspace = true
toon-format.workspace = true
serde.workspace = true
serde_json.workspace = true
rayon.workspace = true
fastembed = { workspace = true, optional = true }

[dev-dependencies]
Expand Down
Loading