universal-ast-mapper 1.5.0 → 1.6.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 +13 -0
- package/dist/index.js +66 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -562,6 +562,18 @@ src/
|
|
|
562
562
|
|
|
563
563
|
---
|
|
564
564
|
|
|
565
|
+
## MCP resources
|
|
566
|
+
|
|
567
|
+
Beyond tools, the server exposes the codebase as **browseable MCP resources**, so an agent (or MCP client UI) can list and read structure directly:
|
|
568
|
+
|
|
569
|
+
| URI | What |
|
|
570
|
+
|-----|------|
|
|
571
|
+
| `ast://languages` | supported languages + extensions |
|
|
572
|
+
| `ast://skeleton/{path}` | the skeleton for one source file (templated; `resources/list` enumerates every file) |
|
|
573
|
+
| `ast://graph` | the whole-root symbol dependency graph (guarded by file count) |
|
|
574
|
+
|
|
575
|
+
---
|
|
576
|
+
|
|
565
577
|
## GitHub Action — architecture gate in CI
|
|
566
578
|
|
|
567
579
|
Use AST-MCP as a CI check with the bundled composite action (`action.yml`):
|
|
@@ -605,6 +617,7 @@ Not part of the public API: the internal `src/` module layout and the generated
|
|
|
605
617
|
|
|
606
618
|
| Version | What changed |
|
|
607
619
|
|---------|--------------|
|
|
620
|
+
| **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. |
|
|
608
621
|
| **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. |
|
|
609
622
|
| **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. |
|
|
610
623
|
| **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. |
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
|
-
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
4
|
+
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
5
5
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
6
6
|
import { z } from "zod";
|
|
7
7
|
import { fileURLToPath } from "node:url";
|
|
@@ -983,6 +983,71 @@ function describeError(err) {
|
|
|
983
983
|
}
|
|
984
984
|
return err instanceof Error ? err.message : String(err);
|
|
985
985
|
}
|
|
986
|
+
/* ─────────────────── MCP resources (browseable structure) ──────────────── */
|
|
987
|
+
server.registerResource("languages", "ast://languages", {
|
|
988
|
+
title: "Supported languages",
|
|
989
|
+
description: "Languages and file extensions this server can map.",
|
|
990
|
+
mimeType: "application/json",
|
|
991
|
+
}, async (uri) => ({
|
|
992
|
+
contents: [{
|
|
993
|
+
uri: uri.href,
|
|
994
|
+
mimeType: "application/json",
|
|
995
|
+
text: JSON.stringify({ root: ROOT, languages: supportedLanguages() }, null, 2),
|
|
996
|
+
}],
|
|
997
|
+
}));
|
|
998
|
+
server.registerResource("skeleton", new ResourceTemplate("ast://skeleton/{+path}", {
|
|
999
|
+
list: async () => {
|
|
1000
|
+
const opts = resolveOptions({ detail: "outline", emitHtml: false });
|
|
1001
|
+
const files = collectSourceFiles(ROOT, opts);
|
|
1002
|
+
return {
|
|
1003
|
+
resources: files.map((f) => {
|
|
1004
|
+
const rel = path.relative(ROOT, f).split(path.sep).join("/");
|
|
1005
|
+
return { uri: `ast://skeleton/${rel}`, name: rel, mimeType: "application/json" };
|
|
1006
|
+
}),
|
|
1007
|
+
};
|
|
1008
|
+
},
|
|
1009
|
+
}), {
|
|
1010
|
+
title: "File skeleton",
|
|
1011
|
+
description: "Normalized code skeleton (symbols, imports, ranges) for one source file.",
|
|
1012
|
+
mimeType: "application/json",
|
|
1013
|
+
}, async (uri, variables) => {
|
|
1014
|
+
const rel = decodeURIComponent(String(variables.path)).split(path.sep).join("/");
|
|
1015
|
+
const { abs, rel: safeRel } = resolveInRoot(rel);
|
|
1016
|
+
const opts = resolveOptions({ detail: "outline", emitHtml: false });
|
|
1017
|
+
const skel = await buildSkeleton(abs, safeRel.split(path.sep).join("/"), opts);
|
|
1018
|
+
return {
|
|
1019
|
+
contents: [{ uri: uri.href, mimeType: "application/json", text: JSON.stringify(skel, null, 2) }],
|
|
1020
|
+
};
|
|
1021
|
+
});
|
|
1022
|
+
server.registerResource("graph", "ast://graph", {
|
|
1023
|
+
title: "Symbol dependency graph",
|
|
1024
|
+
description: "Symbol-level dependency graph for the whole root (guarded by node count).",
|
|
1025
|
+
mimeType: "application/json",
|
|
1026
|
+
}, async (uri) => {
|
|
1027
|
+
const opts = resolveOptions({ detail: "outline", emitHtml: false });
|
|
1028
|
+
const files = collectSourceFiles(ROOT, opts);
|
|
1029
|
+
if (files.length > 1500) {
|
|
1030
|
+
return {
|
|
1031
|
+
contents: [{
|
|
1032
|
+
uri: uri.href,
|
|
1033
|
+
mimeType: "application/json",
|
|
1034
|
+
text: JSON.stringify({ note: `Too large to inline (${files.length} files). Use build_symbol_graph on a subdirectory.`, files: files.length }, null, 2),
|
|
1035
|
+
}],
|
|
1036
|
+
};
|
|
1037
|
+
}
|
|
1038
|
+
const skels = [];
|
|
1039
|
+
for (const file of files) {
|
|
1040
|
+
const fileRel = path.relative(ROOT, file).split(path.sep).join("/");
|
|
1041
|
+
try {
|
|
1042
|
+
skels.push(await buildSkeleton(file, fileRel, opts));
|
|
1043
|
+
}
|
|
1044
|
+
catch { /* skip */ }
|
|
1045
|
+
}
|
|
1046
|
+
const graph = buildSymbolGraph(skels, ROOT);
|
|
1047
|
+
return {
|
|
1048
|
+
contents: [{ uri: uri.href, mimeType: "application/json", text: JSON.stringify(graph, null, 2) }],
|
|
1049
|
+
};
|
|
1050
|
+
});
|
|
986
1051
|
async function main() {
|
|
987
1052
|
const transport = new StdioServerTransport();
|
|
988
1053
|
await server.connect(transport);
|
package/package.json
CHANGED