codebase-analyzer-mcp 2.2.0 → 2.3.0

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.
package/README.md CHANGED
@@ -55,11 +55,30 @@ Results include expandable sections — you only pay for what you drill into.
55
55
  npx codebase-analyzer-mcp analyze . # Standard analysis
56
56
  npx codebase-analyzer-mcp analyze . -d surface # Fast, free overview
57
57
  npx codebase-analyzer-mcp analyze . -d deep -s # Full semantic analysis
58
+ npx codebase-analyzer-mcp analyze . -o analysis.md # Write structured markdown to file
59
+ npx codebase-analyzer-mcp analyze . -o analysis.json # Write JSON to file
58
60
  npx codebase-analyzer-mcp query . "how is auth handled?" # Ask a question
59
61
  npx codebase-analyzer-mcp patterns . # Find design patterns
60
62
  npx codebase-analyzer-mcp dataflow . "user login" # Trace data flow
61
63
  ```
62
64
 
65
+ ## Usage with Claude Code
66
+
67
+ Dump an analysis and reference it from your CLAUDE.md:
68
+
69
+ ```bash
70
+ npx codebase-analyzer-mcp analyze . -o docs/codebase-analysis.md
71
+ ```
72
+
73
+ Then add to your project's CLAUDE.md:
74
+
75
+ ```markdown
76
+ ## Codebase Analysis
77
+ See [docs/codebase-analysis.md](docs/codebase-analysis.md) for full analysis.
78
+ ```
79
+
80
+ Claude Code will read the summary (~50 lines) for context, then drill into specific module sections as needed using `Read` with offset/limit.
81
+
63
82
  ## Development
64
83
 
65
84
  ```bash
package/dist/cli/index.js CHANGED
@@ -44251,7 +44251,7 @@ var package_default;
44251
44251
  var init_package = __esm(() => {
44252
44252
  package_default = {
44253
44253
  name: "codebase-analyzer-mcp",
44254
- version: "2.2.0",
44254
+ version: "2.3.0",
44255
44255
  description: "Multi-layer codebase analysis MCP server with Gemini AI and progressive disclosure.",
44256
44256
  type: "module",
44257
44257
  main: "dist/mcp/server.js",
@@ -74129,7 +74129,7 @@ function extractSourceName3(source) {
74129
74129
  }
74130
74130
  var program2 = new Command;
74131
74131
  program2.name("cba").description("Codebase Analyzer - Multi-layer repository analysis with Gemini AI").version(package_default.version);
74132
- program2.command("analyze").description("Perform architectural analysis of a repository").argument("<source>", "Local path or GitHub URL").option("-d, --depth <depth>", "Analysis depth: surface, standard, deep", "standard").option("-f, --focus <areas...>", "Specific areas to focus on").option("-e, --exclude <patterns...>", "Glob patterns to exclude").option("-t, --token-budget <tokens>", "Maximum token budget", "800000").option("-s, --semantics", "Include deep semantic analysis (uses LLM)").option("-v, --verbose", "Show detailed progress and subagent activity").option("-q, --quiet", "Only output the final result (no progress)").option("--format <format>", "Output format (json or markdown)", "json").action(async (source, options) => {
74132
+ program2.command("analyze").description("Perform architectural analysis of a repository").argument("<source>", "Local path or GitHub URL").option("-d, --depth <depth>", "Analysis depth: surface, standard, deep", "standard").option("-f, --focus <areas...>", "Specific areas to focus on").option("-e, --exclude <patterns...>", "Glob patterns to exclude").option("-t, --token-budget <tokens>", "Maximum token budget", "800000").option("-s, --semantics", "Include deep semantic analysis (uses LLM)").option("-v, --verbose", "Show detailed progress and subagent activity").option("-q, --quiet", "Only output the final result (no progress)").option("--format <format>", "Output format (json or markdown)", "json").option("-o, --output <path>", "Write analysis to a file (markdown by default, .json for JSON)").action(async (source, options) => {
74133
74133
  try {
74134
74134
  if (options.verbose)
74135
74135
  logger.setVerbose(true);
@@ -74146,7 +74146,12 @@ program2.command("analyze").description("Perform architectural analysis of a rep
74146
74146
  includeSemantics: options.semantics,
74147
74147
  sourceName
74148
74148
  });
74149
- if (options.format === "markdown") {
74149
+ if (options.output) {
74150
+ const { writeFile: writeFile2 } = await import("fs/promises");
74151
+ const content = options.output.endsWith(".json") ? JSON.stringify(result, null, 2) : formatAnalysisAsMarkdown(result);
74152
+ await writeFile2(options.output, content, "utf-8");
74153
+ console.error(`Analysis written to ${options.output}`);
74154
+ } else if (options.format === "markdown") {
74150
74155
  console.log(formatAnalysisAsMarkdown(result));
74151
74156
  } else {
74152
74157
  console.log(JSON.stringify(result, null, 2));
@@ -74220,66 +74225,137 @@ program2.command("capabilities").description("Show available analysis capabiliti
74220
74225
  const { formatCapabilitiesResponse: formatCapabilitiesResponse2 } = await Promise.resolve().then(() => (init_capabilities(), exports_capabilities));
74221
74226
  console.log(JSON.stringify(formatCapabilitiesResponse2(), null, 2));
74222
74227
  });
74228
+ function renderTree(node, depth, maxDepth) {
74229
+ const SKIP_DIRS = new Set(["node_modules", ".git", "dist", ".next", "__pycache__", ".cache", "coverage"]);
74230
+ const lines = [];
74231
+ const indent = " ".repeat(depth);
74232
+ if (depth > 0) {
74233
+ lines.push(`${indent}${node.name}${node.type === "directory" ? "/" : ""}`);
74234
+ }
74235
+ if (node.type === "directory" && node.children && depth < maxDepth) {
74236
+ const dirs = node.children.filter((c) => c.type === "directory" && !SKIP_DIRS.has(c.name)).sort((a, b) => a.name.localeCompare(b.name));
74237
+ const files = node.children.filter((c) => c.type === "file").sort((a, b) => a.name.localeCompare(b.name));
74238
+ for (const dir of dirs) {
74239
+ lines.push(...renderTree(dir, depth + 1, maxDepth));
74240
+ }
74241
+ if (depth === 0 || files.length <= 5) {
74242
+ for (const file2 of files) {
74243
+ lines.push(`${" ".repeat(depth + 1)}${file2.name}`);
74244
+ }
74245
+ } else if (files.length > 5) {
74246
+ lines.push(`${" ".repeat(depth + 1)}... ${files.length} files`);
74247
+ }
74248
+ }
74249
+ return lines;
74250
+ }
74223
74251
  function formatAnalysisAsMarkdown(result) {
74224
74252
  const lines = [];
74225
- lines.push(`# ${result.repositoryMap?.name || "Repository"} Analysis`);
74253
+ const name = result.repositoryMap?.name || "Repository";
74254
+ const date6 = new Date().toISOString().split("T")[0];
74255
+ lines.push(`<!-- codebase-analyzer-mcp | ${date6} | depth: ${result.depth} | id: ${result.analysisId} -->`);
74226
74256
  lines.push("");
74227
- lines.push(`**Analysis ID:** \`${result.analysisId}\``);
74228
- lines.push(`**Depth:** ${result.depth}`);
74229
- lines.push(`**Duration:** ${result.durationMs}ms`);
74257
+ lines.push(`# ${name}`);
74230
74258
  lines.push("");
74231
- if (result.summary) {
74232
- lines.push("## Summary");
74233
- lines.push(`- **Architecture:** ${result.summary.architectureType}`);
74234
- lines.push(`- **Complexity:** ${result.summary.complexity}`);
74235
- if (result.summary.primaryPatterns?.length > 0) {
74236
- lines.push(`- **Patterns:** ${result.summary.primaryPatterns.join(", ")}`);
74259
+ if (result.forAgent?.quickSummary) {
74260
+ lines.push(result.forAgent.quickSummary);
74261
+ lines.push("");
74262
+ }
74263
+ const repoMap = result.repositoryMap;
74264
+ const summary = result.summary;
74265
+ if (repoMap || summary) {
74266
+ lines.push("## Overview");
74267
+ lines.push("");
74268
+ lines.push("| Metric | Value |");
74269
+ lines.push("|--------|-------|");
74270
+ if (repoMap?.fileCount != null) {
74271
+ lines.push(`| Files | ${repoMap.fileCount} |`);
74272
+ }
74273
+ if (repoMap?.languages?.length > 0) {
74274
+ const langs = repoMap.languages.map((l) => `${l.language} (${l.percentage}%)`).join(", ");
74275
+ lines.push(`| Languages | ${langs} |`);
74276
+ }
74277
+ if (summary?.architectureType) {
74278
+ lines.push(`| Architecture | ${summary.architectureType} |`);
74279
+ }
74280
+ if (summary?.complexity) {
74281
+ lines.push(`| Complexity | ${summary.complexity} |`);
74282
+ }
74283
+ if (repoMap?.entryPoints?.length > 0) {
74284
+ lines.push(`| Entry points | ${repoMap.entryPoints.slice(0, 5).join(", ")} |`);
74237
74285
  }
74238
- if (result.summary.techStack?.length > 0) {
74239
- lines.push(`- **Tech Stack:** ${result.summary.techStack.join(", ")}`);
74286
+ if (summary?.techStack?.length > 0) {
74287
+ lines.push(`| Tech stack | ${summary.techStack.join(", ")} |`);
74288
+ }
74289
+ if (summary?.primaryPatterns?.length > 0) {
74290
+ lines.push(`| Patterns | ${summary.primaryPatterns.join(", ")} |`);
74240
74291
  }
74241
74292
  lines.push("");
74242
74293
  }
74243
- if (result.repositoryMap) {
74244
- lines.push("## Repository Map");
74245
- lines.push(`- **Total Files:** ${result.repositoryMap.fileCount}`);
74246
- lines.push(`- **Estimated Tokens:** ${result.repositoryMap.estimatedTokens}`);
74247
- lines.push(`- **Languages:** ${result.repositoryMap.languages?.map((l) => `${l.language} (${l.percentage}%)`).join(", ")}`);
74248
- lines.push(`- **Entry Points:** ${result.repositoryMap.entryPoints?.slice(0, 5).join(", ")}`);
74294
+ if (result.forAgent?.keyInsights?.length > 0) {
74295
+ lines.push("## Key Insights");
74249
74296
  lines.push("");
74250
- }
74251
- if (result.sections?.length > 0) {
74252
- lines.push("## Sections");
74253
- for (const section of result.sections) {
74254
- lines.push(`### ${section.title}`);
74255
- lines.push(section.summary);
74256
- if (section.canExpand) {
74257
- lines.push(`*Expandable (detail: ~${section.expansionCost?.detail} tokens, full: ~${section.expansionCost?.full} tokens)*`);
74258
- }
74259
- lines.push("");
74297
+ for (const insight of result.forAgent.keyInsights) {
74298
+ lines.push(`- ${insight}`);
74260
74299
  }
74300
+ lines.push("");
74261
74301
  }
74262
- if (result.forAgent) {
74263
- lines.push("## Agent Hints");
74264
- lines.push(result.forAgent.quickSummary);
74302
+ if (repoMap?.structure) {
74303
+ lines.push("## Structure");
74265
74304
  lines.push("");
74266
- if (result.forAgent.keyInsights?.length > 0) {
74267
- lines.push("**Key Insights:**");
74268
- for (const insight of result.forAgent.keyInsights) {
74269
- lines.push(`- ${insight}`);
74270
- }
74305
+ lines.push("```");
74306
+ const treeLines = renderTree(repoMap.structure, 0, 3);
74307
+ lines.push(...treeLines);
74308
+ lines.push("```");
74309
+ lines.push("");
74310
+ }
74311
+ const moduleSections = result.sections?.filter((s2) => s2.type === "module") || [];
74312
+ if (moduleSections.length > 0) {
74313
+ lines.push("## Modules");
74314
+ lines.push("");
74315
+ for (const section of moduleSections) {
74316
+ const modulePath = section.id.replace("module_", "").replace(/_/g, "/");
74317
+ const detail = section.detail;
74318
+ let header = `### ${modulePath}`;
74319
+ const meta3 = [];
74320
+ if (section.summary)
74321
+ meta3.push(section.summary);
74322
+ if (meta3.length)
74323
+ header += ` — ${meta3.join(", ")}`;
74324
+ lines.push(header);
74271
74325
  lines.push("");
74272
- }
74273
- if (result.forAgent.suggestedNextSteps?.length > 0) {
74274
- lines.push("**Suggested Next Steps:**");
74275
- for (const step of result.forAgent.suggestedNextSteps) {
74276
- lines.push(`- ${step}`);
74326
+ if (detail) {
74327
+ if (detail.type === "documentation") {
74328
+ if (detail.headings?.length > 0) {
74329
+ lines.push(`Headings: ${detail.headings.map((h2) => h2.title).join(", ")}`);
74330
+ }
74331
+ } else {
74332
+ if (detail.exports?.length > 0) {
74333
+ lines.push(`Exports: ${detail.exports.slice(0, 10).join(", ")}${detail.exports.length > 10 ? ", ..." : ""}`);
74334
+ }
74335
+ const cx = detail.complexity;
74336
+ if (cx) {
74337
+ lines.push(`Complexity: ${cx.cyclomaticComplexity} cyclomatic | ${cx.linesOfCode} LOC | ${cx.functionCount} functions | ${cx.classCount} classes`);
74338
+ }
74339
+ if (detail.symbolCount != null || detail.importCount != null) {
74340
+ lines.push(`Symbols: ${detail.symbolCount ?? 0} | Imports: ${detail.importCount ?? 0}`);
74341
+ }
74342
+ }
74343
+ lines.push("");
74277
74344
  }
74345
+ }
74346
+ }
74347
+ const otherSections = result.sections?.filter((s2) => s2.type !== "module") || [];
74348
+ if (otherSections.length > 0) {
74349
+ for (const section of otherSections) {
74350
+ lines.push(`## ${section.title}`);
74351
+ lines.push("");
74352
+ lines.push(section.summary);
74278
74353
  lines.push("");
74279
74354
  }
74280
74355
  }
74281
74356
  if (result.warnings?.length > 0) {
74282
74357
  lines.push("## Warnings");
74358
+ lines.push("");
74283
74359
  for (const warning of result.warnings) {
74284
74360
  lines.push(`- ${warning}`);
74285
74361
  }
@@ -71136,7 +71136,7 @@ function buildFallbackAnswer(question, analysisId, cached2, scored, fileContents
71136
71136
  // package.json
71137
71137
  var package_default = {
71138
71138
  name: "codebase-analyzer-mcp",
71139
- version: "2.2.0",
71139
+ version: "2.3.0",
71140
71140
  description: "Multi-layer codebase analysis MCP server with Gemini AI and progressive disclosure.",
71141
71141
  type: "module",
71142
71142
  main: "dist/mcp/server.js",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codebase-analyzer-mcp",
3
- "version": "2.2.0",
3
+ "version": "2.3.0",
4
4
  "description": "Multi-layer codebase analysis MCP server with Gemini AI and progressive disclosure.",
5
5
  "type": "module",
6
6
  "main": "dist/mcp/server.js",