Version
codebase-memory-mcp 0.11.0
Platform
Linux (x64)
Install channel
GitHub release archive / install.sh / install.ps1
Binary variant
standard (linux-amd64-portable)
What happened, and what did you expect?
index_repository(mode="cross-repo-intelligence") returns 0 for every cross-edge category (cross_http_calls, cross_async_calls, cross_channel, cross_grpc_calls, cross_graphql_calls, cross_trpc_calls) across a 5-project Spring Boot + TypeScript workspace, even for a call/route pair I'd expect to be the easy case this feature is meant to handle.
I checked the existing related reports first — this isn't #1916 (axios-wrapper baseURL indirection: my caller has no wrapper instance, the full literal is at the call site), isn't #706 (constant/variable caller URL: mine is a literal template, not a Name/constant), and isn't #523's root cause #3 (HTTP client dropped because it's an unindexed external dependency: my http() helper is a local function in the same indexed project, confirmed present in the graph — see below). It looks closest to #523's root cause #4 (string-level Route-QN mismatch), but the specific mismatch here is narrower and, I think, worth tracking separately: a JS/TS template-literal path param (${id}) is never normalized to match a Spring path-variable placeholder ({id}), so even a "textbook" literal call site with no indirection at all still produces zero edges.
Reproduction
Backend (Spring Boot, @RestController):
// CustomerController.java
@RestController
@RequestMapping("/api/customers")
class CustomerController {
@GetMapping("/{id}")
Customer get(@PathVariable UUID id) { ... }
}
get_architecture(project="backend", aspects=["routes"]) confirms this is extracted correctly, full path composed with the class-level prefix:
GET /api/customers/{id} -
Frontend (Orval-generated client calling a local http() helper — not axios, not a wrapper instance with baseURL):
// packages/api-client/src/generated/customer-controller/customer-controller.ts
export const get1 = (id: string, signal?: AbortSignal) => {
return http<Customer>({url: `/api/customers/${id}`, method: 'GET', signal});
};
// packages/api-client/src/http.ts
export const http = <T,>(config) => { /* wraps fetch */ };
search_graph(project="frontend", query="fetch", file_pattern="*api-client*") confirms http is indexed as a first-class local Function node (frontend.packages.api-client.src.http.http, packages/api-client/src/http.ts:23-24) — so this isn't #523's "external dependency never resolves" case; both the caller (get1) and the callee (http) are in the same indexed graph, in the same project.
Commands run, in this order, all returning 0 cross edges:
index_repository(repo_path=".../objektmanager-backend", name="backend") # nodes:6359 edges:28507, status: indexed
index_repository(repo_path=".../objektmanager-frontend", name="frontend") # nodes:3439 edges:11768, status: indexed
index_repository(repo_path=".../objektmanager-backend", mode="cross-repo-intelligence", target_projects=["*"])
=> {"cross_http_calls":0, ..., "total_cross_edges":0, "projects_scanned":4}
index_repository(repo_path=".../objektmanager-frontend", mode="cross-repo-intelligence", target_projects=["*"])
=> {"cross_http_calls":0, ..., "total_cross_edges":0, "projects_scanned":4}
index_repository(repo_path=".../objektmanager-frontend", mode="cross-repo-intelligence", target_projects=["backend"])
=> {"cross_http_calls":0, ..., "total_cross_edges":0, "projects_scanned":1}
index_status on both projects shows status: ready, parse_unusable_count: 0 — no coverage gap that would explain this by itself.
Expected
At least one HTTP_CALLS/cross-edge from get1 (frontend) to the GET /api/customers/{id} Route (backend), since the only difference between the caller's literal path and the provider's Route path is ${id} vs {id} — a mechanical, syntax-only difference (JS template-literal interpolation vs Spring's own path-variable placeholder syntax), not a semantic one.
Suggested root cause (unconfirmed — I don't have access to the extractor source)
Given #523's contributor comment describes the matcher rebuilding a Route QN as __route__<METHOD>__<url_path> and doing an exact string lookup with no path-param normalization, I'd guess the TS-side URL extractor either (a) doesn't resolve a template literal with an embedded expression to a "literal-enough" url_path at all (falls back the same way a Name/constant does, per #706), or (b) does resolve it, but preserves the raw ${id} substring instead of normalizing it to a wildcard/placeholder form comparable to {id}. Either way the fix likely needs to live on the caller-side URL extractor for TS/JS template literals specifically, independent of the matcher itself.
Logs
No cross_repo_intelligence log lines matched url pattern or similar in ~/.cache/codebase-memory-mcp/logs/{backend,frontend}-*.log for this run — happy to attach full logs if useful, redacted for path names.
Diagnostics trajectory (memory / performance / leak issues)
Project scale (if relevant)
5 projects indexed (backend: 6359 nodes/28507 edges, 20+ Spring routes; frontend: 3439 nodes/11768 edges, TS monorepo with an Orval-generated packages/api-client; 3 smaller non-code/infra projects not relevant to this repro).
Confirmations
Version
codebase-memory-mcp 0.11.0
Platform
Linux (x64)
Install channel
GitHub release archive / install.sh / install.ps1
Binary variant
standard (linux-amd64-portable)
What happened, and what did you expect?
index_repository(mode="cross-repo-intelligence")returns0for every cross-edge category (cross_http_calls,cross_async_calls,cross_channel,cross_grpc_calls,cross_graphql_calls,cross_trpc_calls) across a 5-project Spring Boot + TypeScript workspace, even for a call/route pair I'd expect to be the easy case this feature is meant to handle.I checked the existing related reports first — this isn't #1916 (axios-wrapper
baseURLindirection: my caller has no wrapper instance, the full literal is at the call site), isn't #706 (constant/variable caller URL: mine is a literal template, not aName/constant), and isn't #523's root cause #3 (HTTP client dropped because it's an unindexed external dependency: myhttp()helper is a local function in the same indexed project, confirmed present in the graph — see below). It looks closest to #523's root cause #4 (string-level Route-QN mismatch), but the specific mismatch here is narrower and, I think, worth tracking separately: a JS/TS template-literal path param (${id}) is never normalized to match a Spring path-variable placeholder ({id}), so even a "textbook" literal call site with no indirection at all still produces zero edges.Reproduction
Backend (Spring Boot,
@RestController):get_architecture(project="backend", aspects=["routes"])confirms this is extracted correctly, full path composed with the class-level prefix:Frontend (Orval-generated client calling a local
http()helper — not axios, not a wrapper instance withbaseURL):search_graph(project="frontend", query="fetch", file_pattern="*api-client*")confirmshttpis indexed as a first-class localFunctionnode (frontend.packages.api-client.src.http.http,packages/api-client/src/http.ts:23-24) — so this isn't #523's "external dependency never resolves" case; both the caller (get1) and the callee (http) are in the same indexed graph, in the same project.Commands run, in this order, all returning 0 cross edges:
index_statuson both projects showsstatus: ready,parse_unusable_count: 0— no coverage gap that would explain this by itself.Expected
At least one
HTTP_CALLS/cross-edge fromget1(frontend) to theGET /api/customers/{id}Route (backend), since the only difference between the caller's literal path and the provider's Route path is${id}vs{id}— a mechanical, syntax-only difference (JS template-literal interpolation vs Spring's own path-variable placeholder syntax), not a semantic one.Suggested root cause (unconfirmed — I don't have access to the extractor source)
Given #523's contributor comment describes the matcher rebuilding a Route QN as
__route__<METHOD>__<url_path>and doing an exact string lookup with no path-param normalization, I'd guess the TS-side URL extractor either (a) doesn't resolve a template literal with an embedded expression to a "literal-enough"url_pathat all (falls back the same way aName/constant does, per #706), or (b) does resolve it, but preserves the raw${id}substring instead of normalizing it to a wildcard/placeholder form comparable to{id}. Either way the fix likely needs to live on the caller-side URL extractor for TS/JS template literals specifically, independent of the matcher itself.Logs
No
cross_repo_intelligencelog lines matchedurl patternor similar in~/.cache/codebase-memory-mcp/logs/{backend,frontend}-*.logfor this run — happy to attach full logs if useful, redacted for path names.Diagnostics trajectory (memory / performance / leak issues)
Project scale (if relevant)
5 projects indexed (backend: 6359 nodes/28507 edges, 20+ Spring routes; frontend: 3439 nodes/11768 edges, TS monorepo with an Orval-generated
packages/api-client; 3 smaller non-code/infra projects not relevant to this repro).Confirmations