@shvmgyl15/tsgraph 0.1.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.
Files changed (187) hide show
  1. package/AGENTS.md +64 -0
  2. package/README.md +128 -0
  3. package/TODOS.md +61 -0
  4. package/dist/analysis/analysis.test.d.ts +2 -0
  5. package/dist/analysis/analysis.test.d.ts.map +1 -0
  6. package/dist/analysis/analysis.test.js +359 -0
  7. package/dist/analysis/analysis.test.js.map +1 -0
  8. package/dist/analysis/complexity.d.ts +8 -0
  9. package/dist/analysis/complexity.d.ts.map +1 -0
  10. package/dist/analysis/complexity.js +88 -0
  11. package/dist/analysis/complexity.js.map +1 -0
  12. package/dist/analysis/coupling.d.ts +17 -0
  13. package/dist/analysis/coupling.d.ts.map +1 -0
  14. package/dist/analysis/coupling.js +71 -0
  15. package/dist/analysis/coupling.js.map +1 -0
  16. package/dist/analysis/hotspot.d.ts +10 -0
  17. package/dist/analysis/hotspot.d.ts.map +1 -0
  18. package/dist/analysis/hotspot.js +33 -0
  19. package/dist/analysis/hotspot.js.map +1 -0
  20. package/dist/analysis/index.d.ts +9 -0
  21. package/dist/analysis/index.d.ts.map +1 -0
  22. package/dist/analysis/index.js +5 -0
  23. package/dist/analysis/index.js.map +1 -0
  24. package/dist/boundaries/index.d.ts +25 -0
  25. package/dist/boundaries/index.d.ts.map +1 -0
  26. package/dist/boundaries/index.js +103 -0
  27. package/dist/boundaries/index.js.map +1 -0
  28. package/dist/boundaries/index.test.d.ts +2 -0
  29. package/dist/boundaries/index.test.d.ts.map +1 -0
  30. package/dist/boundaries/index.test.js +293 -0
  31. package/dist/boundaries/index.test.js.map +1 -0
  32. package/dist/changes/index.d.ts +28 -0
  33. package/dist/changes/index.d.ts.map +1 -0
  34. package/dist/changes/index.js +48 -0
  35. package/dist/changes/index.js.map +1 -0
  36. package/dist/changes/index.test.d.ts +2 -0
  37. package/dist/changes/index.test.d.ts.map +1 -0
  38. package/dist/changes/index.test.js +104 -0
  39. package/dist/changes/index.test.js.map +1 -0
  40. package/dist/cli/index.d.ts +3 -0
  41. package/dist/cli/index.d.ts.map +1 -0
  42. package/dist/cli/index.js +659 -0
  43. package/dist/cli/index.js.map +1 -0
  44. package/dist/git/index.d.ts +16 -0
  45. package/dist/git/index.d.ts.map +1 -0
  46. package/dist/git/index.js +73 -0
  47. package/dist/git/index.js.map +1 -0
  48. package/dist/git/index.test.d.ts +2 -0
  49. package/dist/git/index.test.d.ts.map +1 -0
  50. package/dist/git/index.test.js +78 -0
  51. package/dist/git/index.test.js.map +1 -0
  52. package/dist/graph/types.d.ts +156 -0
  53. package/dist/graph/types.d.ts.map +1 -0
  54. package/dist/graph/types.js +166 -0
  55. package/dist/graph/types.js.map +1 -0
  56. package/dist/graph/types.test.d.ts +2 -0
  57. package/dist/graph/types.test.d.ts.map +1 -0
  58. package/dist/graph/types.test.js +326 -0
  59. package/dist/graph/types.test.js.map +1 -0
  60. package/dist/mcp/mcp.test.d.ts +2 -0
  61. package/dist/mcp/mcp.test.d.ts.map +1 -0
  62. package/dist/mcp/mcp.test.js +151 -0
  63. package/dist/mcp/mcp.test.js.map +1 -0
  64. package/dist/mcp/server.d.ts +2 -0
  65. package/dist/mcp/server.d.ts.map +1 -0
  66. package/dist/mcp/server.js +209 -0
  67. package/dist/mcp/server.js.map +1 -0
  68. package/dist/nextjs/index.d.ts +8 -0
  69. package/dist/nextjs/index.d.ts.map +1 -0
  70. package/dist/nextjs/index.js +16 -0
  71. package/dist/nextjs/index.js.map +1 -0
  72. package/dist/nextjs/nextjs.test.d.ts +2 -0
  73. package/dist/nextjs/nextjs.test.d.ts.map +1 -0
  74. package/dist/nextjs/nextjs.test.js +190 -0
  75. package/dist/nextjs/nextjs.test.js.map +1 -0
  76. package/dist/nextjs/pages.d.ts +4 -0
  77. package/dist/nextjs/pages.d.ts.map +1 -0
  78. package/dist/nextjs/pages.js +36 -0
  79. package/dist/nextjs/pages.js.map +1 -0
  80. package/dist/nextjs/react.d.ts +3 -0
  81. package/dist/nextjs/react.d.ts.map +1 -0
  82. package/dist/nextjs/react.js +86 -0
  83. package/dist/nextjs/react.js.map +1 -0
  84. package/dist/nextjs/router.d.ts +4 -0
  85. package/dist/nextjs/router.d.ts.map +1 -0
  86. package/dist/nextjs/router.js +86 -0
  87. package/dist/nextjs/router.js.map +1 -0
  88. package/dist/nextjs/routes.d.ts +4 -0
  89. package/dist/nextjs/routes.d.ts.map +1 -0
  90. package/dist/nextjs/routes.js +58 -0
  91. package/dist/nextjs/routes.js.map +1 -0
  92. package/dist/opencode/index.d.ts +7 -0
  93. package/dist/opencode/index.d.ts.map +1 -0
  94. package/dist/opencode/index.js +71 -0
  95. package/dist/opencode/index.js.map +1 -0
  96. package/dist/opencode/index.test.d.ts +2 -0
  97. package/dist/opencode/index.test.d.ts.map +1 -0
  98. package/dist/opencode/index.test.js +71 -0
  99. package/dist/opencode/index.test.js.map +1 -0
  100. package/dist/parser/index.d.ts +4 -0
  101. package/dist/parser/index.d.ts.map +1 -0
  102. package/dist/parser/index.js +282 -0
  103. package/dist/parser/index.js.map +1 -0
  104. package/dist/parser/parser.test.d.ts +2 -0
  105. package/dist/parser/parser.test.d.ts.map +1 -0
  106. package/dist/parser/parser.test.js +225 -0
  107. package/dist/parser/parser.test.js.map +1 -0
  108. package/dist/plan/index.d.ts +32 -0
  109. package/dist/plan/index.d.ts.map +1 -0
  110. package/dist/plan/index.js +107 -0
  111. package/dist/plan/index.js.map +1 -0
  112. package/dist/plan/index.test.d.ts +2 -0
  113. package/dist/plan/index.test.d.ts.map +1 -0
  114. package/dist/plan/index.test.js +143 -0
  115. package/dist/plan/index.test.js.map +1 -0
  116. package/dist/report/index.d.ts +9 -0
  117. package/dist/report/index.d.ts.map +1 -0
  118. package/dist/report/index.js +108 -0
  119. package/dist/report/index.js.map +1 -0
  120. package/dist/scanner/index.d.ts +13 -0
  121. package/dist/scanner/index.d.ts.map +1 -0
  122. package/dist/scanner/index.js +78 -0
  123. package/dist/scanner/index.js.map +1 -0
  124. package/dist/scanner/scanner.test.d.ts +2 -0
  125. package/dist/scanner/scanner.test.d.ts.map +1 -0
  126. package/dist/scanner/scanner.test.js +113 -0
  127. package/dist/scanner/scanner.test.js.map +1 -0
  128. package/dist/search/index.d.ts +32 -0
  129. package/dist/search/index.d.ts.map +1 -0
  130. package/dist/search/index.js +97 -0
  131. package/dist/search/index.js.map +1 -0
  132. package/dist/search/search.test.d.ts +2 -0
  133. package/dist/search/search.test.d.ts.map +1 -0
  134. package/dist/search/search.test.js +446 -0
  135. package/dist/search/search.test.js.map +1 -0
  136. package/dist/traversal/index.d.ts +5 -0
  137. package/dist/traversal/index.d.ts.map +1 -0
  138. package/dist/traversal/index.js +3 -0
  139. package/dist/traversal/index.js.map +1 -0
  140. package/dist/traversal/traversal.d.ts +31 -0
  141. package/dist/traversal/traversal.d.ts.map +1 -0
  142. package/dist/traversal/traversal.js +130 -0
  143. package/dist/traversal/traversal.js.map +1 -0
  144. package/dist/traversal/traversal.test.d.ts +2 -0
  145. package/dist/traversal/traversal.test.d.ts.map +1 -0
  146. package/dist/traversal/traversal.test.js +224 -0
  147. package/dist/traversal/traversal.test.js.map +1 -0
  148. package/opencode.json +24 -0
  149. package/package.json +29 -0
  150. package/src/analysis/analysis.test.ts +405 -0
  151. package/src/analysis/complexity.ts +107 -0
  152. package/src/analysis/coupling.ts +106 -0
  153. package/src/analysis/hotspot.ts +52 -0
  154. package/src/analysis/index.ts +17 -0
  155. package/src/boundaries/index.test.ts +335 -0
  156. package/src/boundaries/index.ts +137 -0
  157. package/src/changes/index.test.ts +114 -0
  158. package/src/changes/index.ts +95 -0
  159. package/src/cli/index.ts +736 -0
  160. package/src/git/index.test.ts +92 -0
  161. package/src/git/index.ts +86 -0
  162. package/src/graph/types.test.ts +383 -0
  163. package/src/graph/types.ts +353 -0
  164. package/src/mcp/mcp.test.ts +176 -0
  165. package/src/mcp/server.ts +217 -0
  166. package/src/nextjs/index.ts +23 -0
  167. package/src/nextjs/nextjs.test.ts +233 -0
  168. package/src/nextjs/pages.ts +43 -0
  169. package/src/nextjs/react.ts +100 -0
  170. package/src/nextjs/router.ts +102 -0
  171. package/src/nextjs/routes.ts +69 -0
  172. package/src/opencode/index.test.ts +90 -0
  173. package/src/opencode/index.ts +83 -0
  174. package/src/parser/index.ts +339 -0
  175. package/src/parser/parser.test.ts +282 -0
  176. package/src/plan/index.test.ts +162 -0
  177. package/src/plan/index.ts +161 -0
  178. package/src/report/index.ts +128 -0
  179. package/src/scanner/index.ts +97 -0
  180. package/src/scanner/scanner.test.ts +135 -0
  181. package/src/search/index.ts +163 -0
  182. package/src/search/search.test.ts +512 -0
  183. package/src/traversal/index.ts +5 -0
  184. package/src/traversal/traversal.test.ts +266 -0
  185. package/src/traversal/traversal.ts +185 -0
  186. package/tsconfig.json +20 -0
  187. package/vitest.config.ts +7 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/nextjs/router.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAiB,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AA6FvD,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,WAAW,EAAE,GACrB,KAAK,CAGP"}
@@ -0,0 +1,86 @@
1
+ import path from "node:path";
2
+ const APP_ROUTER_FILES = new Set([
3
+ "page", "layout", "loading", "error", "not-found",
4
+ "route", "template", "default",
5
+ ]);
6
+ function classifyFile(fileName) {
7
+ const base = path.basename(fileName, path.extname(fileName));
8
+ if (APP_ROUTER_FILES.has(base))
9
+ return base;
10
+ return undefined;
11
+ }
12
+ function buildRouterTree(appDir, files) {
13
+ const dirMap = new Map();
14
+ for (const sf of files) {
15
+ const rel = sf.relativePath;
16
+ if (!rel.startsWith("app/") && !rel.startsWith("app\\"))
17
+ continue;
18
+ const afterApp = rel.replace(/^app[/\\]/, "");
19
+ const dir = path.dirname(afterApp);
20
+ const fileName = path.basename(afterApp);
21
+ const kind = classifyFile(fileName);
22
+ if (!kind)
23
+ continue;
24
+ let entry = dirMap.get(dir);
25
+ if (!entry) {
26
+ entry = {};
27
+ dirMap.set(dir, entry);
28
+ }
29
+ entry[kind] = rel;
30
+ }
31
+ if (dirMap.size === 0)
32
+ return undefined;
33
+ const segments = [...dirMap.keys()].filter((d) => d !== ".");
34
+ function nodeForDir(dirParts) {
35
+ const dirPath = dirParts.join("/");
36
+ const files = dirMap.get(dirPath) ?? {};
37
+ const childDirs = segments.filter((s) => {
38
+ const parts = s.split("/");
39
+ if (parts.length !== dirParts.length + 1)
40
+ return false;
41
+ return parts.slice(0, -1).join("/") === dirPath;
42
+ });
43
+ return {
44
+ path: "/" + dirParts.map((p) => p.replace(/^\(|\)$/g, "")).join("/"),
45
+ dir: dirPath === "." ? "app" : path.join("app", dirPath),
46
+ files: {
47
+ page: files.page,
48
+ layout: files.layout,
49
+ loading: files.loading,
50
+ error: files.error,
51
+ notFound: files["not-found"],
52
+ route: files.route,
53
+ template: files.template,
54
+ default: files.default,
55
+ },
56
+ children: childDirs.map((s) => {
57
+ const parts = s.split("/");
58
+ return nodeForDir(parts);
59
+ }),
60
+ };
61
+ }
62
+ const rootChildren = segments
63
+ .filter((s) => !s.includes("/"))
64
+ .map((s) => nodeForDir(s === "." ? [] : [s]));
65
+ const rootFiles = dirMap.get(".") ?? {};
66
+ return {
67
+ path: "/",
68
+ dir: "app",
69
+ files: {
70
+ page: rootFiles.page,
71
+ layout: rootFiles.layout,
72
+ loading: rootFiles.loading,
73
+ error: rootFiles.error,
74
+ notFound: rootFiles["not-found"],
75
+ route: rootFiles.route,
76
+ template: rootFiles.template,
77
+ default: rootFiles.default,
78
+ },
79
+ children: rootChildren,
80
+ };
81
+ }
82
+ export function extractAppRouter(graph, scanned) {
83
+ const tree = buildRouterTree(graph.root, scanned);
84
+ return { ...graph, appRouter: tree ?? undefined };
85
+ }
86
+ //# sourceMappingURL=router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/nextjs/router.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { Graph } from "../graph/types.js";
2
+ import type { ScannedFile } from "../scanner/index.js";
3
+ export declare function extractAPIRoutes(graph: Graph, scanned: ScannedFile[], rootDir: string): Graph;
4
+ //# sourceMappingURL=routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/nextjs/routes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAa,MAAM,mBAAmB,CAAC;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAiBvD,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,WAAW,EAAE,EACtB,OAAO,EAAE,MAAM,GACd,KAAK,CA4CP"}
@@ -0,0 +1,58 @@
1
+ import path from "node:path";
2
+ import { Project } from "ts-morph";
3
+ const HTTP_METHODS = new Set(["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"]);
4
+ function appRouteToHttpPath(relativePath) {
5
+ let p = relativePath
6
+ .replace(/^app[/\\]/, "")
7
+ .replace(/\/route\.[jt]sx?$/, "")
8
+ .replace(/\[\.\.\.(.+?)\]/g, "*$1")
9
+ .replace(/\[(.+?)\]/g, ":$1")
10
+ .replace(/^\(.+?\)\//, "")
11
+ .replace(/\/(\(.+?\))/g, "");
12
+ if (!p.startsWith("/"))
13
+ p = "/" + p;
14
+ return p === "/" ? "/" : p.replace(/\/$/, "");
15
+ }
16
+ export function extractAPIRoutes(graph, scanned, rootDir) {
17
+ const routeFiles = scanned.filter((sf) => {
18
+ const base = path.basename(sf.path, path.extname(sf.path));
19
+ return base === "route" && sf.relativePath.startsWith("app/");
20
+ });
21
+ if (routeFiles.length === 0)
22
+ return graph;
23
+ const project = new Project({ compilerOptions: { noEmit: true } });
24
+ const newRoutes = [...graph.routes];
25
+ for (const rf of routeFiles) {
26
+ try {
27
+ const sourceFile = project.addSourceFileAtPath(rf.path);
28
+ }
29
+ catch {
30
+ continue;
31
+ }
32
+ }
33
+ for (const rf of routeFiles) {
34
+ try {
35
+ const sourceFile = project.getSourceFile(rf.path);
36
+ if (!sourceFile)
37
+ continue;
38
+ const httpPath = appRouteToHttpPath(rf.relativePath);
39
+ for (const func of sourceFile.getFunctions()) {
40
+ const name = func.getName();
41
+ if (!name || !HTTP_METHODS.has(name.toUpperCase()))
42
+ continue;
43
+ newRoutes.push({
44
+ method: name.toUpperCase(),
45
+ path: httpPath,
46
+ handler: rf.relativePath,
47
+ file: rf.relativePath,
48
+ line: func.getStartLineNumber(),
49
+ });
50
+ }
51
+ }
52
+ catch {
53
+ continue;
54
+ }
55
+ }
56
+ return { ...graph, routes: newRoutes };
57
+ }
58
+ //# sourceMappingURL=routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/nextjs/routes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export interface AddPluginResult {
2
+ opencodeJsonUpdated: boolean;
3
+ agentCreated: boolean;
4
+ errors: string[];
5
+ }
6
+ export declare function addOpencodePlugin(rootDir: string): AddPluginResult;
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/opencode/index.ts"],"names":[],"mappings":"AAqCA,MAAM,WAAW,eAAe;IAC9B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,YAAY,EAAE,OAAO,CAAC;IACtB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,CAuClE"}
@@ -0,0 +1,71 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ const MCP_SERVER_CONFIG = {
4
+ command: "npx",
5
+ args: ["tsgraph", "mcp"],
6
+ };
7
+ const AGENT_CONFIG = {
8
+ name: "tsgraph",
9
+ description: "Query the tsgraph codebase index for symbols, imports, dependencies, and analysis",
10
+ tools: [
11
+ "tsgraph_callers",
12
+ "tsgraph_callees",
13
+ "tsgraph_node",
14
+ "tsgraph_source",
15
+ "tsgraph_query",
16
+ "tsgraph_imports",
17
+ "tsgraph_public",
18
+ "tsgraph_focus",
19
+ "tsgraph_context",
20
+ "tsgraph_complexity",
21
+ "tsgraph_hotspot",
22
+ "tsgraph_coupling",
23
+ "tsgraph_deps",
24
+ "tsgraph_impact",
25
+ "tsgraph_path",
26
+ "tsgraph_orphans",
27
+ "tsgraph_trace",
28
+ "tsgraph_boundaries",
29
+ "tsgraph_changes",
30
+ "tsgraph_stale",
31
+ "tsgraph_plan",
32
+ "tsgraph_review",
33
+ ],
34
+ };
35
+ export function addOpencodePlugin(rootDir) {
36
+ const errors = [];
37
+ let opencodeJsonUpdated = false;
38
+ let agentCreated = false;
39
+ const opencodeJsonPath = path.join(rootDir, "opencode.json");
40
+ try {
41
+ let config;
42
+ if (fs.existsSync(opencodeJsonPath)) {
43
+ const raw = fs.readFileSync(opencodeJsonPath, "utf-8");
44
+ config = JSON.parse(raw);
45
+ }
46
+ else {
47
+ config = {};
48
+ }
49
+ config["mcpServers"] = {
50
+ ...(config["mcpServers"] || {}),
51
+ tsgraph: MCP_SERVER_CONFIG,
52
+ };
53
+ fs.writeFileSync(opencodeJsonPath, JSON.stringify(config, null, 2) + "\n");
54
+ opencodeJsonUpdated = true;
55
+ }
56
+ catch (e) {
57
+ errors.push(`Failed to update opencode.json: ${String(e)}`);
58
+ }
59
+ try {
60
+ const agentsDir = path.join(rootDir, ".opencode", "agents");
61
+ fs.mkdirSync(agentsDir, { recursive: true });
62
+ const agentPath = path.join(agentsDir, "tsgraph.json");
63
+ fs.writeFileSync(agentPath, JSON.stringify(AGENT_CONFIG, null, 2) + "\n");
64
+ agentCreated = true;
65
+ }
66
+ catch (e) {
67
+ errors.push(`Failed to create tsgraph agent: ${String(e)}`);
68
+ }
69
+ return { opencodeJsonUpdated, agentCreated, errors };
70
+ }
71
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/opencode/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,iBAAiB,GAAG;IACxB,OAAO,EAAE,KAAK;IACd,IAAI,EAAE,CAAC,SAAS,EAAE,KAAK,CAAC;CACzB,CAAC;AAEF,MAAM,YAAY,GAAG;IACnB,IAAI,EAAE,SAAS;IACf,WAAW,EAAE,mFAAmF;IAChG,KAAK,EAAE;QACL,iBAAiB;QACjB,iBAAiB;QACjB,cAAc;QACd,gBAAgB;QAChB,eAAe;QACf,iBAAiB;QACjB,gBAAgB;QAChB,eAAe;QACf,iBAAiB;QACjB,oBAAoB;QACpB,iBAAiB;QACjB,kBAAkB;QAClB,cAAc;QACd,gBAAgB;QAChB,cAAc;QACd,iBAAiB;QACjB,eAAe;QACf,oBAAoB;QACpB,iBAAiB;QACjB,eAAe;QACf,cAAc;QACd,gBAAgB;KACjB;CACF,CAAC;AAQF,MAAM,UAAU,iBAAiB,CAAC,OAAe;IAC/C,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,mBAAmB,GAAG,KAAK,CAAC;IAChC,IAAI,YAAY,GAAG,KAAK,CAAC;IAEzB,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IAE7D,IAAI,CAAC;QACH,IAAI,MAA+B,CAAC;QACpC,IAAI,EAAE,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;YACpC,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;YACvD,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,EAAE,CAAC;QACd,CAAC;QAED,MAAM,CAAC,YAAY,CAAC,GAAG;YACrB,GAAG,CAAE,MAAM,CAAC,YAAY,CAA6B,IAAI,EAAE,CAAC;YAC5D,OAAO,EAAE,iBAAiB;SAC3B,CAAC;QAEF,EAAE,CAAC,aAAa,CAAC,gBAAgB,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QAC3E,mBAAmB,GAAG,IAAI,CAAC;IAC7B,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,CAAC,IAAI,CAAC,mCAAmC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;QAC5D,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE7C,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;QACvD,EAAE,CAAC,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QAC1E,YAAY,GAAG,IAAI,CAAC;IACtB,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,CAAC,IAAI,CAAC,mCAAmC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC;AACvD,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../../src/opencode/index.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,71 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import path from "node:path";
3
+ import fs from "node:fs";
4
+ import os from "node:os";
5
+ import { addOpencodePlugin } from "./index.js";
6
+ let tmpDir;
7
+ function setup() {
8
+ tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "tsgraph-opencode-"));
9
+ }
10
+ function teardown() {
11
+ fs.rmSync(tmpDir, { recursive: true });
12
+ }
13
+ function readJson(filePath) {
14
+ return JSON.parse(fs.readFileSync(filePath, "utf-8"));
15
+ }
16
+ describe("addOpencodePlugin", () => {
17
+ it("creates opencode.json when it does not exist", () => {
18
+ setup();
19
+ const result = addOpencodePlugin(tmpDir);
20
+ expect(result.opencodeJsonUpdated).toBe(true);
21
+ expect(result.errors).toHaveLength(0);
22
+ const configPath = path.join(tmpDir, "opencode.json");
23
+ expect(fs.existsSync(configPath)).toBe(true);
24
+ const config = readJson(configPath);
25
+ expect(config["mcpServers"]).toEqual({
26
+ tsgraph: { command: "npx", args: ["tsgraph", "mcp"] },
27
+ });
28
+ teardown();
29
+ });
30
+ it("updates existing opencode.json preserving other fields", () => {
31
+ setup();
32
+ const configPath = path.join(tmpDir, "opencode.json");
33
+ fs.writeFileSync(configPath, JSON.stringify({ existingKey: "keep-me", mcpServers: { other: { command: "other" } } }, null, 2) + "\n");
34
+ const result = addOpencodePlugin(tmpDir);
35
+ expect(result.opencodeJsonUpdated).toBe(true);
36
+ expect(result.errors).toHaveLength(0);
37
+ const config = readJson(configPath);
38
+ expect(config["existingKey"]).toBe("keep-me");
39
+ expect(config["mcpServers"]["other"]).toEqual({ command: "other" });
40
+ expect(config["mcpServers"]["tsgraph"]).toEqual({
41
+ command: "npx",
42
+ args: ["tsgraph", "mcp"],
43
+ });
44
+ teardown();
45
+ });
46
+ it("creates .opencode/agents/tsgraph.json", () => {
47
+ setup();
48
+ const result = addOpencodePlugin(tmpDir);
49
+ expect(result.agentCreated).toBe(true);
50
+ expect(result.errors).toHaveLength(0);
51
+ const agentPath = path.join(tmpDir, ".opencode", "agents", "tsgraph.json");
52
+ expect(fs.existsSync(agentPath)).toBe(true);
53
+ const agent = readJson(agentPath);
54
+ expect(agent["name"]).toBe("tsgraph");
55
+ expect(agent["description"]).toBe("Query the tsgraph codebase index for symbols, imports, dependencies, and analysis");
56
+ expect(agent["tools"]).toContain("tsgraph_query");
57
+ expect(agent["tools"]).toContain("tsgraph_plan");
58
+ teardown();
59
+ });
60
+ it("handles invalid existing opencode.json gracefully", () => {
61
+ setup();
62
+ const configPath = path.join(tmpDir, "opencode.json");
63
+ fs.writeFileSync(configPath, "not valid json");
64
+ const result = addOpencodePlugin(tmpDir);
65
+ expect(result.opencodeJsonUpdated).toBe(false);
66
+ expect(result.errors.length).toBeGreaterThan(0);
67
+ expect(result.errors[0]).toContain("Failed to update opencode.json");
68
+ teardown();
69
+ });
70
+ });
71
+ //# sourceMappingURL=index.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../../src/opencode/index.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { Graph } from "../graph/types.js";
2
+ import type { ScannedFile } from "../scanner/index.js";
3
+ export declare function parseProject(rootDir: string, scanned: ScannedFile[]): Graph;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/parser/index.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,KAAK,EAON,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AA4QvD,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,KAAK,CAoD3E"}
@@ -0,0 +1,282 @@
1
+ import path from "node:path";
2
+ import fs from "node:fs";
3
+ import { Project, Node, SyntaxKind, } from "ts-morph";
4
+ import { GRAPH_VERSION } from "../graph/types.js";
5
+ import { extractNextJs } from "../nextjs/index.js";
6
+ function symbolId(file, name) {
7
+ return `${file}::${name}`;
8
+ }
9
+ function countLines(filePath) {
10
+ try {
11
+ const content = fs.readFileSync(filePath, "utf-8");
12
+ return content.split("\n").length;
13
+ }
14
+ catch {
15
+ return 0;
16
+ }
17
+ }
18
+ function extractFileNodes(rootDir, scanned, pkg) {
19
+ return scanned.map((sf) => ({
20
+ id: sf.relativePath,
21
+ path: sf.relativePath,
22
+ packageName: pkg,
23
+ lines: countLines(sf.path),
24
+ generated: sf.isGenerated,
25
+ }));
26
+ }
27
+ function extractSymbols(sourceFile, filePath, pkgName) {
28
+ const symbols = [];
29
+ for (const func of sourceFile.getFunctions()) {
30
+ const name = func.getName();
31
+ if (!name)
32
+ continue;
33
+ symbols.push({
34
+ id: symbolId(filePath, name),
35
+ kind: "function",
36
+ name,
37
+ packageName: pkgName,
38
+ file: filePath,
39
+ line: func.getStartLineNumber(),
40
+ endLine: func.getEndLineNumber(),
41
+ isExported: func.isExported(),
42
+ arity: func.getParameters().length,
43
+ });
44
+ }
45
+ for (const cls of sourceFile.getClasses()) {
46
+ const name = cls.getName();
47
+ if (!name)
48
+ continue;
49
+ symbols.push({
50
+ id: symbolId(filePath, name),
51
+ kind: "class",
52
+ name,
53
+ packageName: pkgName,
54
+ file: filePath,
55
+ line: cls.getStartLineNumber(),
56
+ endLine: cls.getEndLineNumber(),
57
+ isExported: cls.isExported(),
58
+ });
59
+ for (const method of cls.getMethods()) {
60
+ const mName = method.getName();
61
+ if (!mName)
62
+ continue;
63
+ symbols.push({
64
+ id: symbolId(filePath, `${name}.${mName}`),
65
+ kind: "method",
66
+ name: mName,
67
+ receiver: name,
68
+ packageName: pkgName,
69
+ file: filePath,
70
+ line: method.getStartLineNumber(),
71
+ endLine: method.getEndLineNumber(),
72
+ isExported: true,
73
+ arity: method.getParameters().length,
74
+ });
75
+ }
76
+ }
77
+ for (const iface of sourceFile.getInterfaces()) {
78
+ const name = iface.getName();
79
+ symbols.push({
80
+ id: symbolId(filePath, name),
81
+ kind: "interface",
82
+ name,
83
+ packageName: pkgName,
84
+ file: filePath,
85
+ line: iface.getStartLineNumber(),
86
+ endLine: iface.getEndLineNumber(),
87
+ isExported: iface.isExported(),
88
+ });
89
+ }
90
+ for (const alias of sourceFile.getTypeAliases()) {
91
+ const name = alias.getName();
92
+ symbols.push({
93
+ id: symbolId(filePath, name),
94
+ kind: "type_alias",
95
+ name,
96
+ packageName: pkgName,
97
+ file: filePath,
98
+ line: alias.getStartLineNumber(),
99
+ endLine: alias.getEndLineNumber(),
100
+ isExported: alias.isExported(),
101
+ });
102
+ }
103
+ for (const enm of sourceFile.getEnums()) {
104
+ const name = enm.getName();
105
+ symbols.push({
106
+ id: symbolId(filePath, name),
107
+ kind: "enum",
108
+ name,
109
+ packageName: pkgName,
110
+ file: filePath,
111
+ line: enm.getStartLineNumber(),
112
+ endLine: enm.getEndLineNumber(),
113
+ isExported: enm.isExported(),
114
+ });
115
+ }
116
+ for (const vs of sourceFile.getVariableStatements()) {
117
+ const isExported = vs.isExported();
118
+ const isConst = vs
119
+ .getDeclarationList()
120
+ .getFirstChildByKind(SyntaxKind.ConstKeyword) !== undefined;
121
+ const varKind = isConst ? "const" : "var";
122
+ for (const decl of vs.getDeclarations()) {
123
+ const name = decl.getName();
124
+ symbols.push({
125
+ id: symbolId(filePath, name),
126
+ kind: varKind,
127
+ name,
128
+ packageName: pkgName,
129
+ file: filePath,
130
+ line: decl.getStartLineNumber(),
131
+ endLine: decl.getEndLineNumber(),
132
+ isExported,
133
+ });
134
+ }
135
+ }
136
+ return symbols;
137
+ }
138
+ function extractCalls(sourceFile, filePath) {
139
+ const calls = [];
140
+ for (const func of sourceFile.getFunctions()) {
141
+ const name = func.getName();
142
+ if (!name)
143
+ continue;
144
+ const funcId = symbolId(filePath, name);
145
+ func.forEachDescendant((node) => {
146
+ if (Node.isCallExpression(node)) {
147
+ const calleeRaw = node.getExpression().getText();
148
+ calls.push({
149
+ callerSymbolId: funcId,
150
+ callerName: name,
151
+ calleeRaw,
152
+ file: filePath,
153
+ line: node.getStartLineNumber(),
154
+ });
155
+ }
156
+ return false;
157
+ });
158
+ }
159
+ for (const cls of sourceFile.getClasses()) {
160
+ const clsName = cls.getName();
161
+ if (!clsName)
162
+ continue;
163
+ for (const method of cls.getMethods()) {
164
+ const mName = method.getName();
165
+ if (!mName)
166
+ continue;
167
+ const methodId = symbolId(filePath, `${clsName}.${mName}`);
168
+ method.forEachDescendant((node) => {
169
+ if (Node.isCallExpression(node)) {
170
+ const calleeRaw = node.getExpression().getText();
171
+ calls.push({
172
+ callerSymbolId: methodId,
173
+ callerName: mName,
174
+ calleeRaw,
175
+ file: filePath,
176
+ line: node.getStartLineNumber(),
177
+ });
178
+ }
179
+ return false;
180
+ });
181
+ }
182
+ }
183
+ return calls;
184
+ }
185
+ function extractImports(sourceFile, filePath, pkgName) {
186
+ const imports = [];
187
+ for (const imp of sourceFile.getImportDeclarations()) {
188
+ const importPath = imp.getModuleSpecifierValue();
189
+ const defaultImport = imp.getDefaultImport();
190
+ if (defaultImport) {
191
+ imports.push({
192
+ fromFile: filePath,
193
+ fromPackage: pkgName,
194
+ importPath,
195
+ alias: defaultImport.getText(),
196
+ isDefault: true,
197
+ });
198
+ }
199
+ for (const named of imp.getNamedImports()) {
200
+ imports.push({
201
+ fromFile: filePath,
202
+ fromPackage: pkgName,
203
+ importPath,
204
+ alias: named.getName(),
205
+ isDefault: false,
206
+ });
207
+ }
208
+ }
209
+ return imports;
210
+ }
211
+ function readDependencies(rootDir) {
212
+ const pkgPath = path.join(rootDir, "package.json");
213
+ try {
214
+ const raw = fs.readFileSync(pkgPath, "utf-8");
215
+ const pkg = JSON.parse(raw);
216
+ const deps = [];
217
+ const allDeps = {
218
+ ...pkg.dependencies,
219
+ ...pkg.devDependencies,
220
+ };
221
+ for (const [module, version] of Object.entries(allDeps)) {
222
+ deps.push({ module, version: String(version) });
223
+ }
224
+ return deps;
225
+ }
226
+ catch {
227
+ return [];
228
+ }
229
+ }
230
+ function computePackageName(rootDir) {
231
+ try {
232
+ const pkgPath = path.join(rootDir, "package.json");
233
+ const raw = fs.readFileSync(pkgPath, "utf-8");
234
+ const pkg = JSON.parse(raw);
235
+ return pkg.name ?? path.basename(rootDir);
236
+ }
237
+ catch {
238
+ return path.basename(rootDir);
239
+ }
240
+ }
241
+ export function parseProject(rootDir, scanned) {
242
+ const pkgName = computePackageName(rootDir);
243
+ const fileNodes = extractFileNodes(rootDir, scanned, pkgName);
244
+ const rootPackage = {
245
+ id: pkgName,
246
+ name: pkgName,
247
+ importPathBestEffort: pkgName,
248
+ dir: rootDir,
249
+ files: scanned.map((sf) => sf.relativePath),
250
+ };
251
+ const project = new Project({
252
+ compilerOptions: {
253
+ allowJs: true,
254
+ noEmit: true,
255
+ },
256
+ });
257
+ const parsable = scanned.filter((sf) => sf.kind === "ts" || sf.kind === "tsx" || sf.kind === "js" || sf.kind === "jsx");
258
+ for (const sf of parsable) {
259
+ try {
260
+ project.addSourceFileAtPath(sf.path);
261
+ }
262
+ catch {
263
+ // skip files that fail to parse
264
+ }
265
+ }
266
+ const allSymbols = [];
267
+ const allCalls = [];
268
+ const allImports = [];
269
+ for (const sourceFile of project.getSourceFiles()) {
270
+ const relPath = path.relative(rootDir, sourceFile.getFilePath());
271
+ const symbols = extractSymbols(sourceFile, relPath, pkgName);
272
+ const calls = extractCalls(sourceFile, relPath);
273
+ const imports = extractImports(sourceFile, relPath, pkgName);
274
+ allSymbols.push(...symbols);
275
+ allCalls.push(...calls);
276
+ allImports.push(...imports);
277
+ }
278
+ const dependencies = readDependencies(rootDir);
279
+ const baseGraph = { version: GRAPH_VERSION, generatedAt: new Date().toISOString(), root: rootDir, packages: [rootPackage], files: fileNodes, symbols: allSymbols, imports: allImports, calls: allCalls, envReads: [], dependencies, routes: [], concurrency: [], testEdges: [], implements: [], mutations: [], errors: [] };
280
+ return extractNextJs(baseGraph, rootDir, scanned);
281
+ }
282
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/parser/index.ts"],"names":[],"mappings":"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"}