npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

universal-ast-mapper

v2.0.11

Published

MCP server that maps source files into a normalized code skeleton (JSON + HTML) using tree-sitter.

Readme

AST-MCP — Universal Code Skeleton & Dependency Graph

An MCP server + CLI tool that turns source code into structured, machine-readable skeletons and symbol-level dependency graphs — so AI agents can reason about large codebases without reading every file.

Built on tree-sitter WASM grammars. Zero regex guessing — real AST parsing.

44 MCP tools / 49 CLI commands / 5 MCP prompts spanning skeletons, dependency graphs, and deep analysis — dead code, cycles, change-impact, complexity, duplicates, unused params, type-flow, decorators, test-coverage mapping — plus monorepo support, an interactive graph explorer with a coupling overlay (ast-map explore), watch mode, a one-page health dashboard with test-coverage, coupling and SDP cards (ast-map report), a persistent parse cache + parallel parsing (warm re-scans skip parsing entirely), a CI quality gate (ast-map check, baseline ratchet), code smell + security scanning with AI-powered auto-patch (ast-map patch), AI test generation (ast-map testgen --ai), Mermaid diagram export (ast-map diagram), a full-featured web SPA (ast-map serve), custom lint plugins (ast-map plugins), and new in v2.0.0: persistent skeleton index, architecture import rules, TF-IDF re-ranking for semantic search, and API doc generation.

Supported languages: TypeScript · TSX · JavaScript (ESM/CJS) · Python · Go · Rust · Java · C# · C · C++ · Kotlin · Swift · Vue · Svelte (SFC <script>) · PHP · Ruby

| Capability | TS/JS | Python | Go | Rust | Java | C# | C | C++ | Kt | Swift | PHP | Ruby | |--------------------------|:-----:|:------:|:---:|:----:|:----:|:---:|:---:|:---:|:---:|:-----:|:---:|:----:| | Symbol extraction | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | Imports parsing | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | Graph imports edges | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | resolve_imports enrich | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | Call graph callee origin | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | — | — | ✅ | — | ✅ | — | | Reverse calledBy | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | — | — | ✅ | — | ✅ | ✅ |

As of v0.8.2, all four v0.8.0 languages have cross-file graph + resolver wiring: Kotlin (FQCN/package index), C/C++ (#include with header↔impl pairing), and Swift (module = directory under Sources/). Call-graph callee origin is resolved for Kotlin; for C/C++/Swift it stays limited because their imports don't name individual symbols. PHP & Ruby landed symbol extraction + imports in v1.22.0; cross-file graph + call-graph wiring landed after — PHP via a namespace-FQCN index (mirrors Java/Kotlin: namespace X; + class/interface/trait/enum name → file), Ruby via require_relative/require path resolution (Ruby's imports never name a symbol, so callee-origin resolution stays limited like C/C++/Swift, but reverse calledBy uses the same call-site-scan fallback as C#/Go).

Each language uses the resolution strategy that fits it:

  • TS/JS/Python — relative paths (./foo, ..mod) resolved against the importing file's directory, with TS-ESM .js → .ts rewriting. Path aliases (@/* etc.) resolve via the nearest tsconfig.json/jsconfig.json (paths + baseUrl, relative extends). Python also resolves absolute dotted imports (from pkg.mod import X) against the project root and a conventional src/ layout. (v1.24.0)
  • Go — go.mod ancestor lookup → module path prefix → package directory → all .go files (skips _test.go).
  • Rust — Cargo.toml ancestor → crate:: / self:: / super:: walks; supports mod.rs + Rust-2018 sibling-dir style.
  • Java — project-wide FQCN index (package + "." + className → file) built lazily on first cross-lang call; supports wildcard imports.
  • C# — namespace-to-files index plus a <ns>.<TypeName> index so using App.Models + new Inventory() resolves to the right file.
  • Kotlin — project-wide FQCN index (package + "." + ClassName → file), like Java; wildcard import pkg.* pulls every file in the package.
  • C / C++ — #include "..." resolved against the including file's directory; headers auto-paired with same-name .c/.cpp/.cc/.cxx impl files. <system> includes stay external.
  • PHP — project-wide namespace-FQCN index (namespace + "\\" + ClassName → file), like Java/Kotlin; use App\Models\User; resolves directly.
  • Ruby — require_relative './x' resolved as a relative path (.rb + no index-file convention); bare require 'foo/bar' tried against lib/, app/, and the project root (gem requires naturally miss and stay external).

For C#, Go, and Ruby (where imports don't name the called symbol), reverse calledBy falls back to call-site scanning of candidate files.


Quick Start

# Try it on any repo without installing
npx -p universal-ast-mapper ast-map report src/

# Or install the CLI
npm install -g universal-ast-mapper

# From a clone
npm install && npm run build

# CLI
ast-map --help
ast-map langs
ast-map dead src/
ast-map validate src/

# Or without installing globally
node dist/cli.js dead src/

Two Ways to Use

| Mode | Entry Point | When to Use | |------|-------------|-------------| | CLI (ast-map) | dist/cli.js | Terminal, CI scripts, quick checks | | MCP Server | dist/index.js | AI agents (Claude, Cursor, etc.) |


MCP Setup — Claude Desktop

Windows: %APPDATA%\Claude\claude_desktop_config.json
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

{
  "mcpServers": {
    "ast-mapper": {
      "command": "node",
      "args": ["C:\\path\\to\\AST-MCP\\dist\\index.js"],
      "env": {
        "AST_MAP_ROOT": "C:\\path\\to\\your\\project"
      }
    }
  }
}

AST_MAP_ROOT is the security boundary — the server only reads files inside this path.

Since v1.23.0 the boundary is configurable:

  • Multi-root — list several projects in AST_MAP_ROOT, separated by the OS path delimiter (; on Windows, : on macOS/Linux). The first root is the primary (relative paths resolve against it):
      "env": { "AST_MAP_ROOT": "C:\\proj\\app;C:\\proj\\chem_sc_su" }
  • Unlocked — set AST_MAP_UNLOCKED: "1" to let the server analyze any absolute path the client asks for (relative paths still resolve against the primary root). Use this for a personal "analyze anything" setup; keep it off for shared/untrusted environments:
      "env": { "AST_MAP_ROOT": "C:\\proj\\app", "AST_MAP_UNLOCKED": "1" }

CLI Reference

All commands default to cwd as root. Override with AST_MAP_ROOT=/path/to/project ast-map <cmd>.
Add --json to any command for machine-readable output.

ast-map langs
ast-map skeleton <path>            [-d outline|full] [--html] [--combine] [-o dir]
ast-map symbol   <file> <name>     [-k kind] [--related]
ast-map imports  <file>
ast-map graph    <dir>             [-o graph.json]
ast-map validate <path>            [--max-lines N] [--max-imports N] [--max-exports N]
ast-map dead     <dir>
ast-map cycles   <dir>
ast-map duplicates <dir>           [alias: dupes]
ast-map complexity <path>          [alias: cx] [--min N]
ast-map unused-params <path>       [alias: unused]
ast-map trace-type <type> [dir]    [alias: flow]
ast-map workspace [dir]            [alias: ws]
ast-map explore   [dir]            [-o out.html]
ast-map watch     [dir]            [-o out.html]
ast-map sourcemap <file>
ast-map report    [dir]            [-o report.html]
ast-map dashboard [dir]                          # audit KPI summary (dead/cycles/smells/risk)
ast-map history   [dir]                          # historical health trend chart
ast-map diff      [base]           [--dir <d>]   # git-aware changed symbols + impact
ast-map risk      [dir]            [-n N]        # churn × complexity
ast-map pack      <file> [symbol]  [--scan <d>] # minimal context pack
ast-map coupling  [dir]            [-n N]        # Ca / Ce / instability per file
ast-map layers    [dir]            [-g gap]      # SDP: stable→volatile violations
ast-map modules   [dir]                          # directory-level coupling + edges
ast-map cache     [stats|clear]                  # persistent parse cache (.ast-map/cache)
ast-map check     [dir]            [--update-baseline] [--min-score N] [--max-cycles N] ...
ast-map search   <pattern> [dir]   [-m contains|exact|regex] [-k kind] [-e]
ast-map find     <query> [dir]     [-l N] [-k kind] [-e] [--rerank] [--api-key KEY]
ast-map tests    [dir]             [alias: coverage] [-u] [--links] [-n N]
ast-map testgen  <path>            [--framework vitest|jest|mocha|node|pytest|gotest] [--ai]
ast-map smells   [path]            [--changed-since <ref>] [--json]
ast-map security [path]            [--min-severity critical|high|medium|low] [--changed-since <ref>]
ast-map diagram  [dir]             [--type class|deps|modules] [--max-nodes N]
ast-map fix      [dir]             [--ai] [--min-priority 1|2|3] [--api-key KEY]
ast-map init                       [--defaults]  # scaffold .ast-map.json + plugin example
ast-map deps     <file>            [--scan <dir>]
ast-map top      <dir>             [-n 10]
ast-map impact   <file> <symbol>   [--scan <dir>]
ast-map calls    <file> <fn>       [--scan <dir>]
ast-map explain  <file> <symbol>   [--scan <dir>] [--ai] [--api-key KEY]
ast-map similar  [dir]             [--kinds fn,class] [--min-group N]
ast-map serve    [dir]             [--port N] [--watch]   # web SPA + REST + SSE
ast-map covmerge <report>          [--format auto|istanbul|lcov|clover|cobertura]
ast-map plugins  [dir]                           # run .ast-map/plugins/*.mjs
ast-map index    [dir]             [--force]     # build .ast-map/index.json
ast-map arch     [dir]                           # check architecture import rules (CI-friendly)
ast-map patch    [dir]             [-y] [--severity error|warning] [--smells-only] [--security-only]
ast-map doc      [dir]             [-o file] [--html] [--exported-only] [--ai] [--api-key KEY]

Examples

# What does this file export?
ast-map skeleton src/lib/auth.ts

# Show source of validateSession + related types
ast-map symbol src/lib/auth.ts validateSession --related

# Find unused exports
ast-map dead src/

# Detect circular imports
ast-map cycles src/

# Check architecture + structural health
ast-map validate src/
ast-map validate src/ --max-lines 300 --max-imports 20

# Find all symbols named like "handler" across the project
ast-map search handler src/ --exported

# Don't know the name? Search by meaning
ast-map find "remove expired cache entries" src/

# Which source files have no tests at all?
ast-map tests . --untested

# What does this file import / what imports it?
ast-map deps src/lib/auth.ts --scan src/

# Top 10 most-imported symbols (God Node detector)
ast-map top src/

# Blast radius of changing sanitize()
ast-map impact src/utils.ts sanitize --scan src/

# Full call graph for a function
ast-map calls src/graph.ts buildSymbolGraph --scan src/

# Build symbol graph, write to file (large projects)
ast-map graph src/ -o graph.json

# Machine-readable output
ast-map dead src/ --json | jq '.deadExports[] | select(.kind == "function")'

MCP Tools Reference

list_supported_languages

Returns all supported languages and their file extensions.


get_skeleton_json

Parse a single source file → return normalized JSON skeleton (no HTML written).
Use when the AI needs file structure only.

{
  "schemaVersion": "1.1",
  "file": "src/lib/auth.ts",
  "language": "typescript",
  "directives": ["use server"],
  "imports": [
    { "symbol": "prisma", "from": "./prisma", "isDefault": true }
  ],
  "symbols": [
    { "name": "validateSession", "kind": "function", "exported": true,
      "range": { "startLine": 12, "endLine": 34 } }
  ]
}

Params: path, detail ("outline" | "full")


generate_skeleton

Map a file or directory → compact JSON + self-contained HTML views.

Params: path, detail, emitHtml (default true), combineHtml (single index.html with sidebar + search), outputDir


get_symbol_context

Extract exact source lines of a named symbol. Token-efficient: a 300-line file → ~40 lines.
Use includeRelated: true to also pull related types referenced in the signature.

Params: path, symbol, kind (optional), includeRelated


resolve_imports

Resolve every import in a file to its target symbol with kind, signature, and params.

{
  "resolved": [
    {
      "symbol": "validateSession", "from": "../../lib/auth",
      "resolvedRel": "src/lib/auth.ts", "kind": "function",
      "signature": "async function validateSession(token: string): Promise<Session>",
      "params": "(token: string)",
      "found": true, "importKind": "relative"
    }
  ]
}

Params: path


build_symbol_graph

Scan a directory → build a two-layer dependency graph.

  • Nodes: "file" (one per source file) and "symbol" (one per function/class/type/const)
  • Edges: "contains" (structural hierarchy) and "imports" (cross-file dependency)
{
  "stats": { "fileCount": 42, "symbolNodeCount": 380, "edgeCount": 712 },
  "edges": [
    { "from": "src/app/route.ts", "to": "src/lib/auth.ts::validateSession", "edgeType": "imports" }
  ]
}

Use outputFile to write the graph to disk for large projects.

Params: path, detail, outputFile


find_dead_code

Scan a directory → find exported symbols with zero incoming import edges.

Returns two confidence tiers:

  • "high" — functions, classes, consts (very likely unused)
  • "low" — interfaces, types, enums (may be used as type annotations only)

Note: framework entry-points (Next.js pages, route handlers) are technically "dead" inside the graph — review before deleting.

Params: path, detail


find_circular_deps

Detect circular import chains (A → B → C → A) using DFS.
Each cycle is canonicalised to avoid duplicates.

{
  "cycles": [
    { "cycle": ["src/a.ts", "src/b.ts", "src/c.ts", "src/a.ts"], "length": 3 }
  ]
}

Params: path


find_duplicate_symbols

Scan a directory → find symbol names exported from more than one file (accidental collisions / parallel implementations). Each result lists every file + kind that declares the name.

{
  "duplicates": [
    { "symbol": "validate", "count": 2, "locations": [
      { "file": "src/a.ts", "kind": "function" },
      { "file": "src/b.ts", "kind": "function" }
    ]}
  ]
}

Params: path


get_complexity

Compute AST-based cyclomatic complexity per function/method for a file or directory. Score = 1 + decision points (if / for / while / case / catch / ternary / && / ||), with a rating: low (≤5), moderate (≤10), high (≤20), very-high (>20). Directory scans also return the highest-complexity hotspots across all files.

{
  "file": "src/auth.ts",
  "maxComplexity": 12,
  "functions": [
    { "name": "validate", "complexity": 12, "rating": "high", "startLine": 8, "endLine": 40 }
  ]
}

Params: path


find_unused_params

Scan a file or directory for named functions/methods with parameters that are never used in the body. Skips _-prefixed params (conventionally intentional), anonymous callbacks, and destructured bindings — and correctly treats object-shorthand ({ id }) as a use — to keep false positives near zero.

{ "file": "src/x.ts", "functions": [ { "function": "greet", "line": 3, "unused": ["salutation"] } ] }

Params: path


trace_type

Scoped type-flow tracing. Find everywhere a named type flows through a directory — function parameters and return types, typed variables, and class fields. AST-based (no full type inference), so it tracks where a type is named in signatures; works best for TS/Python but resolves return/param types in any language that annotates them.

{
  "type": "Inventory",
  "byRole": { "param": 3, "return": 2, "variable": 1, "field": 1 },
  "refs": [ { "file": "src/svc.ts", "symbol": "make", "role": "return", "line": 4 } ]
}

Params: type, path


Monorepo note: once a workspace is detected, resolve_imports and build_symbol_graph resolve cross-package imports (@org/pkg) to real source files and draw cross-package edges.

analyze_workspace

Monorepo support. Discover the packages in a JS/TS monorepo (npm/yarn workspaces, pnpm-workspace.yaml, or lerna.json) and the dependency edges between them. Returns each package's name, directory, and workspace-internal dependencies, plus any circular dependencies between packages.

{
  "tool": "npm", "packageCount": 3,
  "packages": [ { "name": "@demo/a", "dir": "packages/a", "internalDeps": ["@demo/b"] } ],
  "edges": [ { "from": "@demo/a", "to": "@demo/b" } ],
  "packageCycles": []
}

Params: path (optional, defaults to root)


read_source_map

Given a compiled JS/CSS file with an inline (data:) or external sourceMappingURL, return the original source files it maps back to (honors sourceRoot; reports embedded sourcesContent).

{ "file": "dist/bundle.js", "mapKind": "inline", "sources": ["../src/app.ts", "../src/util.ts"], "hasContent": true }

Params: path


get_codebase_report

A one-shot codebase health summary: file/symbol counts, language breakdown, a health grade (A–F) + score, complexity hotspots, god nodes, dead exports, circular dependencies, module coupling (per-directory instability), and layer violations (SDP). Rendered as a premium HTML dashboard by ast-map report.

{ "grade": "B", "score": 82, "fileCount": 120, "symbolCount": 1400,
  "complexity": { "average": 4.1, "max": 22, "hotspots": [ … ] },
  "godNodes": [ … ], "dead": { "count": 3, "items": [ … ] }, "cycles": { "count": 0, "items": [] } }

Params: path (optional, defaults to root)


get_diff

Git-aware. Compare the working tree to a git ref (default HEAD) and return which symbols were added/removed/modified per file, which changes are potentially breaking (removed or signature-changed exports), and the blast radius — files that depend on those breaking changes. Untracked new files count as additions.

{ "summary": { "filesChanged": 2, "added": 1, "removed": 1, "modified": 1, "breaking": 2, "impactedFiles": 1 },
  "breaking": [ { "file": "src/a.ts", "symbol": "foo", "reason": "signature changed" } ],
  "impactedFiles": ["src/b.ts"] }

Params: base (optional), path (optional)


pack_context

Token-efficient. Assemble the minimal context to understand or change a symbol — its own source, the signatures of what it depends on (resolved imports), and the files that depend on it — instead of reading whole files. Returns a token estimate so you can see the savings.

{ "primary": { "symbol": "login", "startLine": 8, "endLine": 12, "source": "…" },
  "dependencies": [ { "file": "utils.ts", "symbols": [ { "name": "hashPassword", "signature": "…" } ] } ],
  "dependents": [ { "file": "router.ts" } ], "tokenEstimate": 56 }

Params: path, symbol (optional), scan (optional)


get_risk_map

Rank files by refactor risk = git churn × max complexity — the files that are both frequently changed and complex (the best refactor / test targets).

{ "files": [ { "file": "src/callgraph.ts", "churn": 7, "maxComplexity": 69, "risk": 483 } ] }

Params: path (optional)


get_coupling

Per-file coupling metrics (Robert C. Martin): afferent coupling Ca (fan-in), efferent coupling Ce (fan-out), and instability I = Ce/(Ca+Ce) (0 = stable / load-bearing, 1 = unstable / volatile).

{ "files": [ { "file": "src/types.ts", "afferent": 27, "efferent": 0, "instability": 0 } ] }

Params: path (optional)


get_layer_violations

Find dependencies that point the wrong way on the stability gradient — a stable file (low instability) importing a more volatile one (high instability), violating Martin's Stable Dependencies Principle. Sorted by severity (the instability gap crossed).

{ "violations": [ { "from": "src/skeleton.ts", "to": "src/registry.ts", "fromInstability": 0.36, "toInstability": 0.6, "severity": 0.24 } ] }

Params: path (optional), minGap (optional, 0–1)


get_module_coupling

Aggregate the import graph up to the directory/module level — per-module Ca / Ce / instability plus the weighted inter-module edges. Intra-module imports are ignored, so this is the architectural bird's-eye view above per-file coupling.

{
  "modules": [ { "module": "src/extractors", "files": 11, "afferent": 1, "efferent": 1, "instability": 0.5 } ],
  "edges": [ { "from": "src/extractors", "to": "src", "weight": 75 } ]
}

Params: path (optional)


get_change_impact

Given a file + symbol, reverse-traverse the import graph to compute blast radius.

{
  "targetNodeId": "src/lib/auth.ts::validateSession",
  "direct": [{ "file": "src/app/login/page.tsx", "symbol": "validateSession" }],
  "transitive": [{ "file": "src/middleware.ts" }],
  "totalFiles": 5
}

Params: path, symbol, scanDir


get_call_graph

Parse a function body → extract every call expression, resolve callees via the import map, find reverse importers.

{
  "calls": [
    { "callee": "prisma.session.findUnique", "line": 15, "calleeFileRel": "src/lib/prisma.ts" },
    { "callee": "jwt.verify", "line": 20, "isExternal": true, "calleeFileRel": "jsonwebtoken" }
  ],
  "calledBy": [
    { "file": "src/app/api/auth/route.ts" }
  ]
}

Supports all languages with per-language call extraction (TS/JS member_expression, Rust field_expression/scoped_identifier, Java method_invocation, C# invocation_expression, PHP member_call_expression/scoped_call_expression/function_call_expression, Ruby call via its receiver/method fields, etc.) and constructor calls (new Foo).
Handles TS/JS destructured aliases (const { sign } = jwt), Java FQCN imports, C# using namespaces (via project-wide type index), Rust use crate::path::Item, Go pkg.Func (via go.mod module path), Kotlin FQCN/package imports, C/C++ #include, Swift module imports (import <Module> → files under Sources/<Module>/), and PHP use App\Models\X (namespace-FQCN index). Reverse calledBy uses call-site scanning for C#, Go, and Ruby where import statements don't name the called symbol.

Params: path, function, scanDir


search_symbol

Find symbols by name across all source files in a directory.

Params: path, name, matchType ("contains" | "exact" | "regex"), kind, exportedOnly


semantic_search

Find symbols by meaning, not exact name — for when you know what the code does but not what it's called.

No embeddings, no network: identifier tokenization (camelCase / snake_case / acronyms), a built-in programming thesaurus (fetch≈get≈load, remove≈delete≈clear, unused≈dead, …), light stemming, fuzzy matching, and BM25-style IDF ranking over symbol names, doc comments, signatures and file paths. Results carry a normalized score and matchedTerms explaining why each symbol matched.

semantic_search("find unused exported code") →
  1.000  findDeadExports    (find, unused≈dead, export)
  0.557  DeadExport         (unused≈dead, export)

Params: path, query, limit (default 20), kind, exportedOnly


get_test_coverage

Structural test coverage: pair test files with the source files they exercise, and list source files no test touches — no instrumentation or test runner needed, works on a cold checkout.

Two signals: a test file importing a source file (definitive), and naming conventions (auth.test.ts → auth.ts, test_utils.py → utils.py, FooTest.java → Foo.java, test/<name>.* → <name>.*). Fixture/mock directories are excluded from both sides. Untested files are ranked by risk (fan-in, then symbol count); unmatched test files are reported as orphanTests (usually integration/e2e).

File-level coverage ("does anything test this file?"), not line coverage.

Params: path, untestedOnly


get_file_deps

For a single file, show what it imports and what imports it (with symbol names).
More focused than build_symbol_graph — use for quick dependency lookup.

Params: path, scanDir


validate_architecture

Scan for architecture violations across two rule sets.

Next.js App Router rules:

  • client-server-boundary — "use client" file importing a server-only module (error)
  • api-missing-try-catch — API route handler with no try/catch (warning)

General structural rules (any project):

  • large-file — file exceeds maxLines (default 500) (warning)
  • too-many-imports — file has more than maxImports imports (default 15) (warning)
  • god-export — file exports more than maxExports symbols (default 10) (warning)

Thresholds can be set per-call or in .ast-map.config.json.

Params: path, maxLines, maxImports, maxExports


check_quality_gate

Run the CI quality gate: absolute thresholds (from .ast-map.config.json → "check") plus a baseline ratchet against .ast-map.baseline.json — fails when cycles, dead exports, SDP violations, very-high-complexity functions rise, or the health score drops. Set updateBaseline to re-anchor at the current metrics. Same engine as ast-map check.

Params: path, baseline, updateBaseline


get_top_symbols

Return the N most-imported symbols — your codebase's "God Nodes" where a breaking change has maximum blast radius.

Params: path, limit (default 10)


detect_code_smells

Scan a file or directory for structural code smells: god classes (too many public methods/fields), long methods, long parameter lists, primitive obsession, and shallow wrappers. Returns per-file smell lists with file, line, symbol, severity, and message.

{ "path": "src/", "scanned": 42, "total": 7, "smells": [
  { "file": "src/auth.ts", "kind": "long-method", "symbol": "validate",
    "line": 8, "severity": "warning", "message": "Method exceeds 60 lines (82)" }
]}

Params: path, max_methods (default 10), max_fields (default 8), max_method_lines (default 60), max_params (default 4)


scan_security

Static security scan across 12 rules: eval, innerHTML, dangerouslySetInnerHTML, child_process, shell-exec, weak-crypto, hardcoded-secret, sql-injection, http-url, no-rate-limit, prototype-pollution. Returns issues with file, rule, severity, line, and snippet.

{ "path": "src/", "scanned": 42, "total": 2, "issues": [
  { "file": "src/db.ts", "rule": "sql-injection", "severity": "critical",
    "line": 14, "snippet": "db.query(`SELECT * FROM users WHERE id = ${id}`)" }
]}

Params: path, min_severity ("critical" | "high" | "medium" | "low")


generate_diagram

Generate a Mermaid diagram of the codebase.

  • type=class — classDiagram of classes, interfaces, enums and their relationships
  • type=deps — file dependency graph (graph TD)
  • type=modules — collapsed module-level graph (graph LR)

Returns a mermaid string you can paste into any Mermaid renderer or GitHub markdown.

Params: path, type ("class" | "deps" | "modules"), max_nodes (default 50)


get_fix_suggestions

Return actionable, prioritized fix suggestions derived from dead exports, code smells, and security issues. Each suggestion carries a kind, file, line, description, before/after snippet, and priority (1 = must fix, 2 = should fix, 3 = nice to have).

{ "path": "src/", "scanned": 42, "total": 5, "suggestions": [
  { "kind": "security", "priority": 1, "file": "src/db.ts", "line": 14,
    "description": "SQL injection via template literal",
    "before": "db.query(`SELECT * WHERE id=${id}`)",
    "after": "db.query('SELECT * WHERE id=?', [id])" }
]}

Params: path, min_priority (1–3, default 3 = all)


generate_tests

Generate test stubs for a source file using its AST skeleton. Supports vitest, jest, mocha, node:test, pytest, and gotest. Returns the generated test file content plus metadata: testCount, framework, testFilePath.

Params: path, framework ("vitest" | "jest" | "mocha" | "node" | "pytest" | "gotest"), exported_only (default true)


generate_tests_ai

Same as generate_tests but enhances stubs with real assertions via Claude — no more TODO placeholders. Falls back gracefully to stubs when the API key is absent. Requires ANTHROPIC_API_KEY or explicit api_key.

Params: path, framework, api_key, model


ai_refactor

Send the smells or security issues found in a file to Claude and receive concrete refactored code. Returns before/after code blocks plus an explanation for each issue. Requires ANTHROPIC_API_KEY or explicit api_key.

{ "path": "src/auth.ts", "total": 2, "results": [
  { "kind": "smell", "before": "function auth(u,p,t,r,o,c) {...}",
    "after": "function auth({ user, pass, token }: AuthParams) {...}",
    "explanation": "Replaced long parameter list with a typed options object." }
]}

Params: path, kind ("smell" | "security" | "both"), api_key, model, limit (default 3)


explain_symbol

Structural explanation of any named symbol: what it does, who calls it, what it depends on, detected smells, cyclomatic complexity rating, and estimated change risk. With ai: true, Claude writes a prose explanation using the structural data.

{ "symbol": "validateSession", "file": "src/auth.ts",
  "calledBy": [{ "file": "src/middleware.ts" }],
  "calls": [{ "callee": "prisma.session.findUnique" }],
  "smells": [], "complexity": "low", "changeRisk": "medium",
  "explanation": "Validates an incoming JWT, looks up the session …" }

Params: path, symbol, scanDir, ai (default false), api_key, model


find_similar

Find groups of functions, methods, or classes that share the same structural fingerprint (param count, async, return type, size, nesting) across a directory — duplication and consolidation candidates, no AI or text comparison needed.

{ "directory": "src/", "groupCount": 3, "groups": [
  { "fingerprint": "fn|2|async|void|small", "size": 3,
    "members": [
      { "file": "src/a.ts", "name": "fetchUser" },
      { "file": "src/b.ts", "name": "fetchPost" }
    ]}
]}

Params: path, kinds (default ["function","method","class"]), min_group_size (default 2)


merge_coverage

Enrich the structural test coverage map with actual line/branch percentages from a real coverage report. Supports Istanbul JSON, lcov, Clover XML, and Cobertura XML. Returns enriched per-file coverage, dead tests (tested but 0% actual coverage), and uncovered files.

Params: report (path to coverage file), path (project dir), format ("auto" | "istanbul" | "lcov" | "clover" | "cobertura")


run_plugins

Load and run all .mjs/.js plugins from <root>/.ast-map/plugins/ against the current skeletons. Each plugin exports an AstMapPlugin with an id and a run(ctx) function that returns violations. Returns per-plugin violation lists with file, line, symbol, severity, and message.

Params: path (optional, defaults to root)


build_index

Build or refresh the persistent skeleton index at .ast-map/index.json. Subsequent CLI commands and the check_arch_rules tool read from this index (SHA-1 hash verified) for 10–100× faster analysis on warm runs.

Params: dir (optional), force (ignore cached hashes and rebuild all)


check_arch_rules

Enforce forbidden/required import rules declared in .ast-map.json under arch.rules. Returns structured violations with file, rule name, and severity (error | warning). Uses the persistent index when available.

{ "ruleCount": 2, "violationCount": 1, "violations": [
  { "rule": "no-ui-in-domain", "severity": "error",
    "from": "src/domain/order.ts", "to": "src/ui/Button.tsx",
    "message": "Domain layer must not import UI layer" }
]}

Params: dir (optional)


generate_docs

Generate Markdown or HTML API documentation from the skeleton of a directory. Optionally enhance symbol descriptions with Claude (ai: true). When exportedOnly is true (default), only exported symbols are included.

Params: dir (optional), format ("markdown" | "html"), exportedOnly (default true), ai (default false), apiKey


Project Config — .ast-map.config.json

Place in your project root. All fields optional.

{
  "ignore": ["dist", "coverage", ".turbo"],
  "maxFileBytes": 500000,
  "outputDir": ".ast-map",
  "cache": true,
  "rules": {
    "large-file":       { "maxLines": 400 },
    "too-many-imports": { "maxImports": 20 },
    "god-export":       { "maxExports": 15 }
  },
  "check": {
    "maxCycles": 0,
    "maxSdpViolations": 10,
    "minScore": 70
  },
  "arch": {
    "rules": [
      {
        "name": "no-ui-in-domain",
        "from": "src/domain/**",
        "forbidImport": "src/ui/**",
        "severity": "error",
        "message": "Domain layer must not import UI layer"
      },
      {
        "name": "services-must-use-repo",
        "from": "src/services/**",
        "requireImport": "src/repositories/**",
        "severity": "warning"
      }
    ]
  }
}
  • cache — persistent parse cache in <root>/.ast-map/cache (default true; also disabled by AST_MAP_NO_CACHE=1). Inspect/clear with ast-map cache [stats|clear].
  • check — default thresholds for ast-map check / check_quality_gate; CLI flags override per run.
  • arch.rules — declarative import rules enforced by ast-map arch / check_arch_rules. Each rule has a from glob, a forbidImport or requireImport glob, optional name, severity ("error" | "warning"), and message. ast-map arch exits non-zero on errors (CI-friendly). Globs support ** (any depth), * (single segment), and ? (single char).

The config is read live — changes take effect on the next call without restarting the MCP server.


Performance — cache & parallel parsing

Since v1.20.0, bulk scans are fast twice over:

  • Persistent parse cache — every parsed file's skeleton is stored under <root>/.ast-map/cache, keyed by a SHA-1 of its content + detail + schema/grammar versions. A changed file hashes to a new key, so entries are never stale by construction, and the cache survives across processes — a re-run on an unchanged repo skips parsing entirely (warm hits on large files ≈ 60× faster).
  • Worker-thread parallel parsing — batches of ≥ 64 files are distributed over a pool sized from your CPU count (max 8); smaller batches stay sequential so there's no startup-cost penalty. Any worker failure falls back to sequential parsing.

| Env var | Effect | |---------|--------| | AST_MAP_NO_CACHE=1 | disable the disk cache for this run | | AST_MAP_WORKERS=0 | force sequential parsing | | AST_MAP_WORKERS=N | force a pool of N workers (bypasses the batch-size gate) |

ast-map cache shows entry count + size; ast-map cache clear wipes it. .ast-map/ is already in the default ignore list — add it to .gitignore if it isn't.


Power Prompts

Full Architecture Audit

Use build_symbol_graph on src/, then:
1. get_top_symbols — find the 5 God Nodes
2. find_circular_deps — any cycles?
3. validate_architecture — architecture violations + structural warnings
4. For the worst issue, show source with get_symbol_context

Safe Refactor Checklist

Before refactoring [functionName] in [file]:
1. get_change_impact — who depends on it?
2. get_call_graph — what does it call?
3. get_symbol_context with includeRelated=true — show me the full signature + types
4. Summarise what needs to change alongside the refactor

Dead Code Cleanup

Run find_dead_code on src/.
Show high-confidence results grouped by file.
For each candidate, use get_change_impact to confirm it's truly unreachable,
then show the source with get_symbol_context so I can verify before deleting.

Adding a Language

  1. Pick a grammar from tree-sitter-wasms (~36 bundled grammars).
  2. Write src/extractors/<lang>.ts — export extract() and extractImports().
  3. Add one entry to src/registry.ts.

No changes to the core pipeline or any MCP tool.


Schema Reference

SymbolNode

interface SymbolNode {
  name: string
  kind: "class" | "interface" | "struct" | "function" | "method"
       | "type" | "enum" | "const" | "var" | "field"
  visibility: "public" | "private"
  exported?: boolean
  signature?: string          // full detail only
  doc?: string                // full detail only
  range: { startLine: number; endLine: number }
  children: SymbolNode[]
}

ImportRef

interface ImportRef {
  symbol: string              // imported name, or "*"
  from: string                // module specifier as written in source
  alias?: string              // import { Foo as Bar } → "Bar"
  isTypeOnly?: boolean
  isNamespaceImport?: boolean
  isDefault?: boolean
  isSideEffect?: boolean
}

SkeletonFile (schema v1.1)

interface SkeletonFile {
  schemaVersion: "1.1"
  file: string                // relative path, forward-slashed
  language: string
  generatedAt: string
  parser: { engine: "tree-sitter"; grammar: string }
  symbolCount: number
  directives?: string[]       // e.g. ["use client"]
  imports?: ImportRef[]
  symbols: SymbolNode[]
}

Project Layout

src/
├── index.ts            — MCP server + 44 tool registrations
├── cli.ts              — ast-map CLI (49 commands)
├── lsp.ts              — JSON-RPC 2.0 LSP server (diagnostics + code lens)
├── types.ts            — SkeletonFile, SymbolNode, ImportRef
├── config.ts           — SkeletonOptions, resolveOptions(), loadProjectConfig() + arch rules type
├── registry.ts         — language detection + extractor registry
├── parser.ts           — tree-sitter WASM loader + AST node helpers
├── skeleton.ts         — buildSkeleton(), collectSourceFiles() + parse cache
├── resolver.ts         — resolveImportPath(), resolveFileImports() (TS/JS/Python relative)
├── tsconfig.ts         — TS/JS path-alias resolution via tsconfig.json / jsconfig.json
├── crosslang.ts        — Java FQCN / C# namespace / Rust crate / Go module resolvers
├── roots.ts            — multi-root + unlocked-mode boundary resolution
├── graph.ts            — buildSymbolGraph() (language-aware second pass)
├── graph-analysis.ts   — findDeadExports(), findCircularDeps(), getChangeImpact(), getTopSymbols()
├── callgraph.ts        — buildCallGraph() — AST-level call extraction
├── analysis.ts         — findSymbol(), validate helpers, checkGeneralRules()
├── html.ts             — renderHtml(), renderCombinedHtml()
├── search.ts           — searchSymbols()
├── semantic.ts         — semanticSearch(), identifier tokenization, programming thesaurus
├── diskcache.ts        — persistent parse cache (SHA-1 keyed, .ast-map/cache)
├── pool.ts             — worker-thread parallel parsing pool
├── worker.ts           — per-worker parse + skeleton build
├── coupling.ts         — computeCoupling() (Ca / Ce / instability)
├── layers.ts           — findLayerViolations() (SDP)
├── modulecoupling.ts   — computeModuleCoupling() (directory-level)
├── gitdiff.ts          — getChangedFiles(), computeRisk()
├── contextpack.ts      — packContext() — minimal context for a symbol
├── sourcemap.ts        — readSourceMap() — inline + external source map parsing
├── workspace.ts        — analyzeWorkspace() — monorepo package discovery
├── typeflow.ts         — traceType() — type-flow tracing across a directory
├── complexity.ts       — computeFileComplexity() — cyclomatic complexity
├── unused-params.ts    — findUnusedParams() — unused function parameters
├── graph-analysis.ts   — findDuplicateSymbols(), getFileDeps()
├── testmap.ts          — mapTestCoverage() — structural test coverage
├── check.ts            — runQualityGate() — baseline ratchet + absolute thresholds
├── report.ts           — generateReport() — premium HTML health dashboard
├── dashboard.ts        — buildDashboard() — audit KPI summary
├── history.ts          — buildHistory() — historical health trend
├── explorer.ts         — renderExplorer() — force-directed file graph HTML
├── sfc.ts              — Vue / Svelte SFC <script> block extraction
├── smells.ts           — detectSmells() — 6 structural smell patterns
├── security.ts         — scanFileForSecurityIssues() — 12 static security rules
├── diagram.ts          — buildClassDiagram(), buildDepsDiagram(), buildModulesDiagram()
├── fix.ts              — buildFixSuggestions() — prioritised fix list
├── testgen.ts          — generateTestFile() — test stubs (6 frameworks)
├── ai-testgen.ts       — tryAiEnhanceTests() — Claude-enhanced test assertions
├── ai-refactor.ts      — callClaude(), aiRefactorBatch() — AI refactoring
├── explain.ts          — buildExplainResult(), aiExplain() — symbol explanation
├── similar.ts          — findSimilar() — structural fingerprint groups
├── incremental.ts      — content-hash state, filterToGitChanged(), detectChanges()
├── covmerge.ts         — mergeCoverage() — 4-format coverage parser + structural merge
├── plugins.ts          — loadPlugins(), runPlugins() — custom lint plugin runner
├── serve.ts            — startServe() — HTTP server + REST endpoints + SSE /events
├── webapp.ts           — self-contained SPA template (D3.js, dark theme, 8 pages)
├── indexstore.ts       — buildIndex(), loadIndex(), isIndexFresh(), getSkeletons()
├── arch-rules.ts       — checkArchRules(), loadArchRules(), globToRegex()
├── patch.ts            — generatePatch(), interactivePatch(), colored unified diff
├── docgen.ts           — buildDocOutput(), renderMarkdown(), renderDocHtml(), aiEnhanceDocs()
├── embeddings.ts       — buildTfIdfVectors(), cosineSearch(), rerankWithClaude()
├── prompts.ts          — 5 MCP prompt definitions
└── extractors/
    ├── common.ts       — makeSymbol(), toOutline()
    ├── typescript.ts   — TS/JS/TSX: symbols + imports + re-exports + decorators
    ├── python.ts       — Python: symbols + relative import resolution + decorators
    ├── go.ts           — Go: symbols + imports
    ├── rust.ts         — Rust: struct/trait/enum/impl + `use` imports
    ├── java.ts         — Java: class/interface/enum/method/field + FQCN
    ├── csharp.ts       — C#: namespace recursion + class/struct/interface + `using`
    ├── kotlin.ts       — Kotlin: FQCN / package index
    ├── swift.ts        — Swift: module = directory under Sources/
    ├── c.ts            — C: functions + `#include` with header↔impl pairing
    ├── cpp.ts          — C++: classes + `#include`
    ├── php.ts          — PHP: classes/interfaces/traits/enums + `use` + require/include
    └── ruby.ts         — Ruby: classes/modules/methods + require/require_relative

MCP resources

Beyond tools, the server exposes the codebase as browseable MCP resources, so an agent (or MCP client UI) can list and read structure directly:

| URI | What | |-----|------| | ast://languages | supported languages + extensions | | ast://skeleton/{path} | the skeleton for one source file (templated; resources/list enumerates every file) | | ast://graph | the whole-root symbol dependency graph (guarded by file count) |


MCP prompts — one-call recipes

The server also registers prompts: named, parameterized workflows an MCP client can invoke directly (they show up in the client's prompt/slash menu). Each returns a ready-to-run instruction that chains the right tools, so you don't paste the recipe by hand.

| Prompt | Args | What it does | |--------|------|--------------| | architecture_audit | dir? | God Nodes → cycles → rule violations → module coupling → SDP breaks, then a prioritized summary | | safe_refactor | file, symbol | blast radius → call graph → minimal context before changing a symbol | | dead_code_cleanup | dir? | unused exports, each verified zero-impact before deletion | | health_check | dir? | grade A–F → risk map → layer violations, with the 3 files to fix first | | onboard_codebase | dir? | languages → structure → core symbols → module map, as a "start here" guide |


GitHub Action — architecture gate in CI

Use AST-MCP as a CI check with the bundled composite action (action.yml):

# .github/workflows/architecture.yml
name: Architecture
on: [pull_request]
jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: "20" }
      - uses: 6ixthxense/AST-MCP@v1
        with:
          path: src
          max-lines: "400"
          max-imports: "20"
          max-exports: "15"

The action runs ast-map validate and fails the job on threshold violations.

Since v1.21.0 the action can also run the quality gate (baseline ratchet + thresholds). Commit a baseline once (ast-map check src --update-baseline), then:

      - uses: 6ixthxense/AST-MCP@v1
        with:
          path: src
          mode: check                 # validate | check | both
          check-args: "--min-score 70 --max-cycles 0"

The job fails whenever cycles, dead exports, SDP violations, or complexity regress past the committed .ast-map.baseline.json. You can also call any CLI command directly with npx -p universal-ast-mapper ast-map <command>.


Stability (1.0)

As of v1.0.0, the public surface is stable across the 1.x line:

  • MCP tool names and input schemas — no breaking changes; new tools and new optional inputs may be added.
  • CLI commands and flags — stable; new commands/flags may be added.
  • Skeleton JSON — schemaVersion follows additive-compatible evolution; new optional fields (e.g. props, decorators) may appear without a major bump.

Not part of the public API: the internal src/ module layout and the generated HTML markup.


Changelog

| Version | What changed | |---------|--------------| | 2.0.0 | 6 major features — Persistent skeleton index (ast-map index, build_index): .ast-map/index.json hash-based incremental rebuild, 10–100× warm speed; SSE live reload (ast-map serve --watch, /events endpoint): EventSource client auto-refreshes the web SPA on file changes; TF-IDF re-ranking (ast-map find --rerank): cosine similarity pre-rank + optional Claude API re-ranking; Auto-patch (ast-map patch, generatePatch): colored unified diff with Claude-generated before/after, readline y/N prompt per issue; Architecture rules (ast-map arch, check_arch_rules): forbidden/required import rules in .ast-map.json arch.rules, glob patterns, CI exit code; Doc generation (ast-map doc, generate_docs): Markdown + HTML API reference, --ai flag for Claude descriptions. 44 MCP tools / 49 CLI commands. | | 1.35.0 | Web SPA + symbol explanation + similar + coverage merge + plugins — new ast-map serve [dir] launches a dark-theme web app at :7337 (D3 dependency graph, all analysis pages, 10 REST endpoints); new ast-map explain <file> <symbol> structural explanation with optional --ai prose (callers, deps, smells, complexity, risk); new ast-map similar [dir] AST fingerprint groups (7-component, no AI); new ast-map covmerge <report> merges Istanbul/lcov/Clover/Cobertura with the structural map; new ast-map plugins [dir] runs custom .mjs lint plugins from .ast-map/plugins/. New MCP tools: explain_symbol, find_similar, merge_coverage, run_plugins. 41 MCP tools / 45 CLI commands. | | 1.34.0 | Code intelligence suite + AI refactor + LSP + init — 7 new MCP tools: detect_code_smells (6 patterns), scan_security (12 rules), generate_diagram (Mermaid class/deps/modules), get_fix_suggestions (P1–P3 prioritized), generate_tests (6 frameworks), generate_tests_ai (Claude-enhanced assertions), ai_refactor (before/after patches from Claude). Full JSON-RPC 2.0 LSP server (ast-map-lsp): dead-export warnings, security-issue errors, complexity code lenses. ast-map init scaffolds .ast-map.json + plugin example. 37 MCP tools / 41 CLI commands. | | 1.33.0 | AI test generation + VS Code extension — ast-map testgen --ai sends source + stubs to Claude and returns tests with real assertions (graceful fallback to stubs). New VS Code extension: complexity code lens, dead-export diagnostics, security diagnostics, Issues Tree View, commands (Generate Tests, Scan Security, Show Diagram, Open Report), status-bar health score. | | 1.28.0 | Test coverage in the dashboard — ast-map report / get_codebase_report gain a Test coverage card (coverage bar + untested sources ranked by risk with Ca/symbols) and stat tile; structural coverage now factors into the health score (capped penalty). Reporting on src/ only? Test files are pulled in from the project root automatically. | | 1.27.0 | Test-coverage mapping — new MCP tool get_test_coverage + CLI ast-map tests (alias coverage): pairs test files with the sources they exercise (import edges + naming conventions) and lists untested sources ranked by risk (fan-in, then symbols). Fixture dirs excluded; orphan tests reported. File-level, zero instrumentation. (30 tools / 32 commands) | | 1.26.0 | Coupling overlay in the explorer — ast-map explore gains a color: coupling mode: nodes shaded by instability I = Ce/(Ca+Ce) on a green (stable) → red (volatile) scale, with a legend, and Ca / Ce / I readouts in the hover tooltip and detail sidebar. Spot load-bearing files and volatile hotspots at a glance. | | 1.25.0 | Semantic symbol search — new MCP tool semantic_search + CLI ast-map find <query>: find symbols by meaning ("remove expired sessions" → clearDiskCache). Identifier tokenization + 60-group programming thesaurus + stemming + fuzzy matching + BM25-style IDF ranking over names, docs, signatures and paths. No embeddings, no network. (29 tools / 31 commands) | | 1.24.0 | TS path-alias resolution — bare imports like @/components/Button now resolve via the nearest tsconfig.json/jsconfig.json (compilerOptions.paths + baseUrl, relative extends chains, longest-prefix matching, string-aware JSONC parser). Wired into resolve_imports, the symbol graph, and the call graph — on a real Next.js app this took the import graph from 31 to 324 edges and cut false dead-exports by ~30%. | | 1.23.0 | Configurable root boundary — AST_MAP_ROOT accepts multiple roots (path-delimiter separated) and AST_MAP_UNLOCKED=1 allows analyzing any absolute path on request (default stays locked). Analysis/graph/report rel-paths now computed against the matched root, so cross-root results are correct. New roots module + 13-check test suite. | | 1.22.0 | PHP & Ruby support — .php (classes, interfaces, traits, enums, methods with visibility, use imports incl. grouped, require/include) and .rb/.rake (classes, modules, methods, self. singleton methods, private section tracking, require/require_relative). Unblocked by upgrading web-tree-sitter 0.20.8 → 0.21.0 (all existing grammars re-verified). 16 languages. | | 1.21.0 | Quality gate — ast-map check fails CI when quality regresses: baseline ratchet vs .ast-map.baseline.json (cycles · dead exports · SDP · very-high complexity · score; --update-baseline re-anchors) + absolute thresholds (flags or config "check"). New MCP tool check_quality_gate (28 tools); GitHub Action gains mode: check. | | 1.20.0 | Incremental cache + parallel parsing — persistent content-hash parse cache in .ast-map/cache (on by default, never stale, warm hits ~60× faster on large files; ast-map cache stats|clear, AST_MAP_NO_CACHE, "cache": false) + worker-thread parallel parsing for bulk scans (auto-sized, AST_MAP_WORKERS override, sequential fallback). | | 1.19.0 | Dashboard: coupling + SDP — ast-map report / get_codebase_report now include module coupling (per-directory instability bars) and layer violations (stable→volatile, SDP) cards, plus an SDP stat; SDP inversions also factor into the health score. The v1.14–1.16 metrics are now visual. | | 1.18.0 | Vue & Svelte SFC support — .vue and .svelte single-file components are now parsed: the <script> / <script setup> block is lifted out (TS or JS) and its symbols + imports extracted, with cross-file graph edges into plain modules. Blank-padding keeps every symbol's line numbers pointing at the original SFC. 14 languages. | | 1.17.0 | MCP prompts — the server now registers 5 parameterized prompts (architecture_audit, safe_refactor, dead_code_cleanup, health_check, onboard_codebase): named workflows a client can invoke from its prompt menu, each chaining the right tools. The Cookbook recipes, one call away. | | 1.16.0 | Module coupling — new get_module_coupling MCP tool + ast-map modules (alias mods) CLI: aggregates the import graph to the directory/module level — per-module Ca / Ce / instability plus weighted inter-module edges (intra-module imports ignored). The bird's-eye view above per-file coupling. 27 MCP tools. | | 1.15.0 | Layer-violation detection — new get_layer_violations MCP tool + ast-map layers (alias sdp) CLI: flags dependencies that break Martin's Stable Dependencies Principle — a stable file (low instability) importing a more volatile one — sorted by the instability gap. Builds directly on the coupling metrics. 26 MCP tools. | | 1.14.0 | Coupling metrics — new get_coupling MCP tool + ast-map coupling [dir] CLI: per-file afferent (Ca) / efferent (Ce) coupling and instability I = Ce/(Ca+Ce), the way to spot load-bearing files (high Ca) vs. volatile ones (high I). 25 MCP tools. | | 1.13.0 | Context-pack — new pack_context MCP tool + ast-map pack <file> [symbol] CLI: the minimal context to work on a symbol (its source + the signatures it depends on + its dependents) with a token estimate, instead of reading whole files. 24 MCP tools. | | 1.12.0 | Git-aware analysis — ast-map diff [base] + get_diff tool: changed symbols since a ref, breaking changes (removed / signature-changed exports), and blast radius. ast-map risk + get_risk_map tool: rank files by churn × complexity. Brings a time/history dimension. 23 MCP tools. | | 1.11.0 | Code-health dashboard — new ast-map report CLI writes a premium self-contained HTML overview (grade A–F, stats, language breakdown, complexity hotspots, god nodes, dead code, cycles) + get_codebase_report MCP tool for the same as JSON. | | 1.10.0 | Source-map support — new read_source_map MCP tool + ast-map sourcemap <file> CLI: given a compiled JS/CSS file with an inline (data:) or external sourceMappingURL, returns the original source files it maps back to (honors sourceRoot). Traces dist/ output back to source. | | 1.9.0 | Watch mode — ast-map watch [dir] recomputes the dependency analysis (file count · dead exports · cycles) on every source-file change, debounced; -o file.html also regenerates the live explorer each time. Plus: the explorer debug readout is now hidden (toggle with d). | | 1.8.2 | Explorer stability fix — clamp the force layout (distance floor + velocity cap) so nodes that initialize close together can't be flung to huge coordinates, which was blowing up the bounding box and shrinking the whole graph into a corner. Now reliably centers and fills. | | 1.8.1 | Explorer self-heal sizing — the explorer now re-checks canvas size every frame and re-fits, so it always centers/fills even if the canvas reports zero size at load (and survives container resizes). | | 1.8.0 | Explorer detail sidebar — click a file in ast-map explore to open a side panel: language, symbol count, its symbols, the files it imports, and the files that import it — each clickable to jump to that file. | | 1.7.3 | Explorer layout overhaul — only connected files are force-laid (centered + filling the viewport); orphan files with no in-scope deps are parked in a tidy grid below instead of sprawling. Verified centered at any window size. | | 1.7.2 | Explorer fit, really this time — continuous auto-fit until you interact, robust canvas sizing, and centered node init, so the graph fills the viewport instead of bunching in a corner. | | 1.7.1 | Explorer fit fix — the ast-map explore graph now auto-fits the viewport (spreads to fill the screen instead of clustering in the centre); double-click re-fits. | | 1.7.0 | Web UI graph explorer — ast-map explore [dir] writes a self-contained, dependency-free interactive HTML: a force-directed file dependency graph (drag, zoom, click-to-highlight neighbours, filter by name). No build step, no external scripts — just open it in a browser. | | 1.6.0 | MCP resource endpoints — the server now exposes browseable resources: ast://languages, ast://skeleton/{path} (templated, one per source file via resources/list), and ast://graph. Agents can list and read codebase structure as resources, not just call tools. | | 1.5.0 | .d.ts / ambient declarations — declare function/const/class, declare module "x", and declare namespace (and plain namespace) are now extracted (previously a .d.ts yielded 0 symbols). Adds a namespace symbol kind; declared APIs surface as exported, nested under their module/namespace. | | 1.4.0 | Dynamic import tracking — dynamic import("...") and CommonJS require("...") calls (anywhere in a file) are now captured as imports with an isDynamic flag. Relative dynamic imports resolve and draw graph edges like static ones, so lazy-loaded routes/modules show up in the dependency graph. | | 1.3.0 | TS/JS decorators — class and method symbols now carry a decorators field (@Component({...}), @Injectable(), @Get("/x")), in skeletons and get_call_graph. Extends the Python decorator support (v0.8.7) to TypeScript/JavaScript — traces Angular/NestJS-style framework wiring to its class/handler. | | 1.2.0 | File-level cross-package resolution — in a monorepo, bare imports of a workspace package (@org/utils, @org/utils/sub) now resolve to the actual source file (preferring src/ over built dist/), so resolve_imports marks them in-project and build_symbol_graph draws cross-package edges. Builds on the v1.1.0 workspace discovery. | | 1.1.0 | Monorepo support — new analyze_workspace MCP tool + ast-map workspace (alias ws) CLI: discovers packages from npm/yarn workspaces, pnpm-workspace.yaml, or lerna.json, maps internal package dependencies, and flags circular package deps. 19 MCP tools. | | 1.0.0 | Stable release. Locks the public API (MCP tool names + schemas, CLI surface) for the 1.x line. Adds a GitHub Action (action.yml) to run ast-map validate as a CI architecture gate, plus a project CI workflow. Caps a 12-language engine with 18 MCP tools / 17 CLI commands spanning skeletons, dependency graphs, and deep analysis (dead code · cycles · impact · complexity · duplicates · unused params · decorators · type flow). | | 0.9.0 | Scoped type-flow tracing — new trace_type MCP tool + ast-map trace-type (alias flow) CLI: follow a named type through function params, return types, typed variables, and class fields across a directory. Completes the deeper-analysis suite (dead code · cycles · impact · complexity · duplicates · unused params · type flow). 18 MCP tools. | | 0.8.7 | Python decorators in the call graph — function/method symbols now carry a decorators field (@router.get("/x") → router.get("/x")), surfaced in skeletons (outline + full) and in get_call_graph. Traces framework wiring like FastAPI/Flask routes and @staticmethod/@property stacks to their handler. | | 0.8.6 | Unused parameter detection — new find_unused_params MCP tool + ast-map unused-params (alias unused) CLI: named functions whose params are never referenced. Skips _-prefixed/destructured/anonymous and treats object-shorthand as a use (low false-positive). Server now 17 tools. | | 0.8.5 | Cyclomatic complexity — new get_complexity MCP tool + ast-map complexity (alias cx) CLI: per-function cyclomatic complexity with low/moderate/high/very-high ratings, file or directory scope. | | 0.8.4 | Duplicate symbol detection — find_duplicate_symbols / ast-map duplicates (alias dupes): symbol names exported from more than one file. | | 0.8.1–0.8.3 | Kotlin + C/C++ cross-file wiring · Swift module resolution (Sources/<Module>/) · TSX/React component props (propsType + props[], React.FC<P> detection). | | 0.1.0–0.8.0 | Foundation: skeleton extraction (get_skeleton_json, generate_skeleton, get_symbol_context, validate_architecture) · import resolution + symbol graph · dead code / cycles / impact / call graph · CLI · 12 languages (+Rust · Java · C# · Go · C · C++ · Kotlin · Swift) · /ast-map skill auto-install · barrel re-exports · parse cache. |