Skip to content

feat(core,mcp): graph algorithms — PageRank, components, shortest path#19

Merged
prosdev merged 8 commits into
mainfrom
feat/mcp-phase1-pagerank-map
Mar 31, 2026
Merged

feat(core,mcp): graph algorithms — PageRank, components, shortest path#19
prosdev merged 8 commits into
mainfrom
feat/mcp-phase1-pagerank-map

Conversation

@prosdev

@prosdev prosdev commented Mar 31, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds graph algorithms over the file dependency graph to improve dev_map and dev_refs:

  • PageRank replaces simple ref counting for dev_map hot paths
  • Connected components identifies subsystems in dev_map output
  • Shortest path enables dependency chain tracing in dev_refs via traceTo

Completes MCP Phase 1 (Parts 1.1–1.6).

What it does

dev_map hot paths — Files are now ranked by graph centrality, not just incoming reference count. A file depended on by other important files ranks higher than a file with many direct but shallow references.

dev_map subsystems — Shows connected components: "Subsystems (3 connected): packages/core (45 files), packages/cli (12 files), ..."

dev_refs path tracing — New traceTo parameter:

dev_refs { name: "authenticate", traceTo: "src/database.ts" }
→ "src/auth.ts → src/user-service.ts → src/repository.ts → src/database.ts (3 hops)"

Changes

New files

  • packages/core/src/map/graph.ts — PageRank, buildDependencyGraph, connectedComponents, shortestPath (~230 lines)
  • packages/core/src/map/__tests__/graph.test.ts — 24 tests

Modified files

  • packages/core/src/map/index.ts — replace computeHotPaths, add components to output + formatter
  • packages/core/src/map/types.ts — add score to HotPath, components to CodebaseMap
  • packages/core/src/map/__tests__/map.test.ts — rewrite callers→callees tests
  • packages/mcp-server/src/adapters/built-in/refs-adapter.ts — add traceTo param + path tracing
  • packages/mcp-server/src/schemas/index.ts — add traceTo to RefsArgsSchema
  • packages/mcp-server/bin/dev-agent-mcp.ts — wire indexer into RefsAdapter

Key design decisions

  • Hand-rolled algorithms (~230 lines) — no graphology dependency. Upgrade path exists if we need more algorithms.
  • Weighted PageRank with sqrt dampening (from aider), dangling node handling, convergence check. Matches NetworkX defaults.
  • callers metadata is dead code — scanner stores only callees. Previous computeHotPaths had dead callers path. Fixed.
  • HotPath.incomingRefs is real incoming edge count (for display). HotPath.score is PageRank value (for sorting).

Test plan

  • 24 graph algorithm tests (PageRank 8, graph builder 5, components 5, shortest path 6)
  • 26 map tests pass (4 hot paths tests rewritten callers→callees)
  • 1651 total tests pass, 0 failures
  • PageRank: 2000 nodes, 10000 edges in 4ms
  • Build + typecheck pass

Commits

  1. feat(core): add graph algorithms — pure functions + tests
  2. feat(core): replace ref counting with PageRank in dev_map — wire + rewrite tests
  3. feat(core): wire connected components into dev_map output
  4. feat(mcp): add path tracing to dev_refs — traceTo parameter
  5. docs: complete MCP Phase 1

Inspired by aider's repo map (Apache 2.0).

Generated with Claude Code

prosdev and others added 7 commits March 31, 2026 12:58
Key findings:
- callers metadata is dead code (not stored in index) — callees-only is correct
- Keep incomingRefs as real count, add score field for PageRank
- Existing tests need callees data + relative ordering assertions
- Add performance test for 2k-node graph

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ortest path

Pure functions over the file dependency graph:
- pageRank: weighted with dangling node handling and convergence (4ms for 2k nodes)
- buildDependencyGraph: callees → weighted edges with sqrt dampening
- connectedComponents: BFS on undirected graph for subsystem identification
- shortestPath: BFS for call chain tracing (hop count)

24 tests covering ranking, cycles, dangling nodes, weights, components,
path finding, edge cases, and performance.

Inspired by aider's repo map (https://github.com/Aider-AI/aider).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace computeHotPaths simple reference counting with PageRank over
the weighted dependency graph. Files depended on by other important
files now rank higher.

- HotPath.score: PageRank value (used for sorting)
- HotPath.incomingRefs: real incoming edge count (used for display)
- Rewrite 4 hot paths tests from dead callers data to callees data
- Assert relative ordering, not exact counts

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add components field to CodebaseMap. Compute connected components from
the dependency graph and display as "Subsystems" section in formatted
output. Only shows multi-file components (singles filtered out).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New traceTo parameter on dev_refs: traces the dependency chain from
a function's file to a target file through the call graph.

Example: dev_refs { name: "authenticate", traceTo: "src/database.ts" }
→ "src/auth.ts → src/user-service.ts → src/repository.ts → src/database.ts (3 hops)"

Uses shortestPath BFS from graph.ts. Requires indexer for graph building
(optional — traceTo is ignored without it).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All 6 parts of MCP Phase 1 Tools Improvement are complete:
- 1.1: Pure pattern extractors
- 1.2: Index-based analysis (10-30x faster)
- 1.3: Dead code cleanup
- 1.4: Agent usability (merge health, rename params, JSON, suggestions)
- 1.5: AST pattern analysis (tree-sitter queries)
- 1.6: Graph algorithms (PageRank, components, shortest path)

File importance ranking inspired by aider's repo map
(https://github.com/Aider-AI/aider).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…aceTo error

- Build dependency graph once, pass to both computeHotPaths and connectedComponents
- Return explicit error when traceTo is set but indexer is missing
- Document directed-only limitation in traceTo description
- Switch BFS from queue.shift() (O(n)) to index-based (O(1))
- Require 2+ path segments for subsystem labels (avoid "packages" alone)
- Track traceTo adapter test gap in scratchpad

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@prosdev prosdev force-pushed the feat/mcp-phase1-pagerank-map branch 2 times, most recently from 059fed8 to 994c1d3 Compare March 31, 2026 21:04
- Rename traceTo → dependsOn (makes call direction unambiguous)
- Cache dependency graph on RefsAdapter (60s TTL, avoids rebuilding per request)
- Log warning when 10k doc limit is hit in both dev_map and dev_refs
- Remove overly strict shortestPath early return for unknown source nodes
- Update docs for dependsOn parameter name
- Track hub filtering, 10k scaling, and perf concerns in scratchpad

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@prosdev prosdev force-pushed the feat/mcp-phase1-pagerank-map branch from 994c1d3 to 8d56e25 Compare March 31, 2026 21:06
@prosdev prosdev merged commit 12d4845 into main Mar 31, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant