Commit Graph
2 Commits
Author SHA1 Message Date
3e1547bbe1 fix(mcp): bold labels instead of ATX headings in tool results (#778) (#951)
MCP tool results used Markdown ATX headings (##/###/####) for section
headers — the status summary, each search hit, every file section in an
exploration — which Markdown-rendering clients (e.g. the Claude Code
VSCode extension) blow up to H1–H4 font size, filling the transcript with
oversized lines (worst on search/explore, where the noise scales with
result count). Swap them all for bold labels, which render at body size
while keeping the same structure. CLI/TTY output (ContextBuilder) is
unchanged — the issue notes it's fine.

The format is parse-coupled, so kept in sync:
- The explore truncation boundary and the offload chunker
  (reasoning/reasoner.ts) both key off the per-file header, now a unique
  `**`-prefixed marker emitted via a shared fileSectionHeader() helper.
- Updated the offload strip regexes and switched the opt-in report-style
  prompt off ATX headings (same client, same rendering issue).
- Updated test helpers (sectionFor, sourcedFiles, the callers
  section-boundary scan) that scanned the old markers.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 12:06:35 -05:00
222af6b87c fix(mcp+resolution): stop conflating same-named symbols across monorepo apps (#764) (#813)
A NestJS-style monorepo has one UserService/UserModule/UserRepository per
app; with no package concept for TS they share one global name scope and
agents visibly warned that CodeGraph was mixing unrelated classes.

Two distinct problems, two fixes:

1. TOOL AGGREGATION. callers/callees returned one merged list across every
   same-named match, and impact merged all their blast radii into a single
   overstated subgraph. Now: matches group into DISTINCT DEFINITIONS
   (filePath + qualifiedName — same-file overloads still merge, that's the
   overload feature) and render one file-labeled section per definition;
   a new `file` argument (path or suffix, like codegraph_node's) narrows
   to one definition, suppressing the stale aggregation note; a
   non-matching `file` falls back to all definitions with a note.
   server-instructions documents the behavior.

2. RESOLUTION WRONG EDGES. Auditing a real monorepo (amplication, 54k
   nodes) found 1,036 cross-package `references` edges into duplicated
   names. Root cause: the React framework resolver ran PascalCase
   component resolution on refs from PLAIN .ts FILES (a GraphQL types
   file's own `Account` type alias lost to an arbitrary same-named CLASS
   in another package — the resolver's blind `components[0]` fallback at
   confidence 0.8 outranked the name-matcher's proximity-correct 0.7).
   Component resolution is now gated to JSX-capable refs (tsx/jsx) and
   never guesses among multiple candidates without a positional signal
   (same-dir / component-dir / unique). Cross-package wrong edges:
   1,036 -> 40 (-96%; the remainder are genuine shared-model imports and
   codegen template scaffolds), with the freed refs re-resolving to the
   correct same-file/same-package targets. excalidraw (a real React repo)
   is a zero-delta control — legitimate component refs all carry
   same-dir/component-dir signals.

Graph-level separation was verified correct on a fixture before any
changes (import + proximity resolution keeps apps apart) — the conflation
was tool-level plus the react-resolver edge class.

Tests: 6-test e2e suite (grouped callers/callees, per-definition impact
radii, file narrowing, fallback note, cross-app edge isolation) + react
resolver unit tests updated to production reality (tsx refs resolve,
plain-ts refs decline). Full suite 1398 passed. EXTRACTION_VERSION
23 -> 24 (re-index to drop the wrong cross-package edges).

Closes #764

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-11 16:24:22 -05:00