purecontext-mcp 1.1.7 → 1.2.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 (182) hide show
  1. package/AGENT_INSTRUCTIONS.md +393 -0
  2. package/AGENT_INSTRUCTIONS_SHORT.md +53 -0
  3. package/AST-SEARCH.md +274 -0
  4. package/CHANGELOG.md +62 -0
  5. package/CODE-INTELLIGENCE.md +369 -0
  6. package/HEALTH-DASHBOARDS.md +241 -0
  7. package/README.md +7 -0
  8. package/REFACTORING-SAFELY.md +279 -0
  9. package/UNDERSTANDING-RELATIONSHIPS.md +240 -0
  10. package/USER-GUIDE.md +14 -0
  11. package/VISUALIZING-CODE.md +199 -0
  12. package/WORKFLOW-TECH-DEBT.md +286 -0
  13. package/dist/core/db/dep-store.d.ts +75 -0
  14. package/dist/core/db/dep-store.d.ts.map +1 -1
  15. package/dist/core/db/dep-store.js +277 -0
  16. package/dist/core/db/dep-store.js.map +1 -1
  17. package/dist/core/db/schema.d.ts.map +1 -1
  18. package/dist/core/db/schema.js +12 -0
  19. package/dist/core/db/schema.js.map +1 -1
  20. package/dist/core/index-manager.js +1 -1
  21. package/dist/core/index-manager.js.map +1 -1
  22. package/dist/core/token-tracker.d.ts +0 -9
  23. package/dist/core/token-tracker.d.ts.map +1 -1
  24. package/dist/core/token-tracker.js +0 -21
  25. package/dist/core/token-tracker.js.map +1 -1
  26. package/dist/core/types.d.ts +5 -0
  27. package/dist/core/types.d.ts.map +1 -1
  28. package/dist/graph/diagram-renderer.d.ts +83 -0
  29. package/dist/graph/diagram-renderer.d.ts.map +1 -0
  30. package/dist/graph/diagram-renderer.js +294 -0
  31. package/dist/graph/diagram-renderer.js.map +1 -0
  32. package/dist/graph/graph-traversal.d.ts +92 -0
  33. package/dist/graph/graph-traversal.d.ts.map +1 -1
  34. package/dist/graph/graph-traversal.js +440 -2
  35. package/dist/graph/graph-traversal.js.map +1 -1
  36. package/dist/server/http-server.d.ts.map +1 -1
  37. package/dist/server/http-server.js +30 -1
  38. package/dist/server/http-server.js.map +1 -1
  39. package/dist/server/mcp-server.d.ts.map +1 -1
  40. package/dist/server/mcp-server.js +145 -0
  41. package/dist/server/mcp-server.js.map +1 -1
  42. package/dist/server/tools/_meta.d.ts +0 -2
  43. package/dist/server/tools/_meta.d.ts.map +1 -1
  44. package/dist/server/tools/_meta.js +1 -4
  45. package/dist/server/tools/_meta.js.map +1 -1
  46. package/dist/server/tools/check-delete-safe.d.ts +50 -0
  47. package/dist/server/tools/check-delete-safe.d.ts.map +1 -0
  48. package/dist/server/tools/check-delete-safe.js +308 -0
  49. package/dist/server/tools/check-delete-safe.js.map +1 -0
  50. package/dist/server/tools/check-move-safe.d.ts +44 -0
  51. package/dist/server/tools/check-move-safe.d.ts.map +1 -0
  52. package/dist/server/tools/check-move-safe.js +266 -0
  53. package/dist/server/tools/check-move-safe.js.map +1 -0
  54. package/dist/server/tools/check-rename-safe.d.ts +48 -0
  55. package/dist/server/tools/check-rename-safe.d.ts.map +1 -0
  56. package/dist/server/tools/check-rename-safe.js +218 -0
  57. package/dist/server/tools/check-rename-safe.js.map +1 -0
  58. package/dist/server/tools/diff-health-radar.d.ts +44 -0
  59. package/dist/server/tools/diff-health-radar.d.ts.map +1 -0
  60. package/dist/server/tools/diff-health-radar.js +192 -0
  61. package/dist/server/tools/diff-health-radar.js.map +1 -0
  62. package/dist/server/tools/find-cycles.d.ts +31 -0
  63. package/dist/server/tools/find-cycles.d.ts.map +1 -0
  64. package/dist/server/tools/find-cycles.js +85 -0
  65. package/dist/server/tools/find-cycles.js.map +1 -0
  66. package/dist/server/tools/find-implementations.d.ts +47 -0
  67. package/dist/server/tools/find-implementations.d.ts.map +1 -0
  68. package/dist/server/tools/find-implementations.js +167 -0
  69. package/dist/server/tools/find-implementations.js.map +1 -0
  70. package/dist/server/tools/find-untested-symbols.d.ts +52 -0
  71. package/dist/server/tools/find-untested-symbols.d.ts.map +1 -0
  72. package/dist/server/tools/find-untested-symbols.js +308 -0
  73. package/dist/server/tools/find-untested-symbols.js.map +1 -0
  74. package/dist/server/tools/get-architecture-snapshot.d.ts +43 -0
  75. package/dist/server/tools/get-architecture-snapshot.d.ts.map +1 -0
  76. package/dist/server/tools/get-architecture-snapshot.js +292 -0
  77. package/dist/server/tools/get-architecture-snapshot.js.map +1 -0
  78. package/dist/server/tools/get-call-hierarchy.d.ts +43 -0
  79. package/dist/server/tools/get-call-hierarchy.d.ts.map +1 -0
  80. package/dist/server/tools/get-call-hierarchy.js +119 -0
  81. package/dist/server/tools/get-call-hierarchy.js.map +1 -0
  82. package/dist/server/tools/get-class-hierarchy.d.ts +36 -0
  83. package/dist/server/tools/get-class-hierarchy.d.ts.map +1 -0
  84. package/dist/server/tools/get-class-hierarchy.js +125 -0
  85. package/dist/server/tools/get-class-hierarchy.js.map +1 -0
  86. package/dist/server/tools/get-complexity-hotspots.d.ts +50 -0
  87. package/dist/server/tools/get-complexity-hotspots.d.ts.map +1 -0
  88. package/dist/server/tools/get-complexity-hotspots.js +282 -0
  89. package/dist/server/tools/get-complexity-hotspots.js.map +1 -0
  90. package/dist/server/tools/get-coupling-map.d.ts +39 -0
  91. package/dist/server/tools/get-coupling-map.d.ts.map +1 -0
  92. package/dist/server/tools/get-coupling-map.js +107 -0
  93. package/dist/server/tools/get-coupling-map.js.map +1 -0
  94. package/dist/server/tools/get-debt-report.d.ts +44 -0
  95. package/dist/server/tools/get-debt-report.d.ts.map +1 -0
  96. package/dist/server/tools/get-debt-report.js +606 -0
  97. package/dist/server/tools/get-debt-report.js.map +1 -0
  98. package/dist/server/tools/get-entry-points.d.ts +79 -0
  99. package/dist/server/tools/get-entry-points.d.ts.map +1 -0
  100. package/dist/server/tools/get-entry-points.js +362 -0
  101. package/dist/server/tools/get-entry-points.js.map +1 -0
  102. package/dist/server/tools/get-public-api.d.ts +53 -0
  103. package/dist/server/tools/get-public-api.d.ts.map +1 -0
  104. package/dist/server/tools/get-public-api.js +218 -0
  105. package/dist/server/tools/get-public-api.js.map +1 -0
  106. package/dist/server/tools/get-savings-stats.d.ts.map +1 -1
  107. package/dist/server/tools/get-savings-stats.js +1 -3
  108. package/dist/server/tools/get-savings-stats.js.map +1 -1
  109. package/dist/server/tools/get-test-coverage-map.d.ts +66 -0
  110. package/dist/server/tools/get-test-coverage-map.d.ts.map +1 -0
  111. package/dist/server/tools/get-test-coverage-map.js +588 -0
  112. package/dist/server/tools/get-test-coverage-map.js.map +1 -0
  113. package/dist/server/tools/get-todos.d.ts +51 -0
  114. package/dist/server/tools/get-todos.d.ts.map +1 -0
  115. package/dist/server/tools/get-todos.js +180 -0
  116. package/dist/server/tools/get-todos.js.map +1 -0
  117. package/dist/server/tools/get-type-graph.d.ts +73 -0
  118. package/dist/server/tools/get-type-graph.d.ts.map +1 -0
  119. package/dist/server/tools/get-type-graph.js +437 -0
  120. package/dist/server/tools/get-type-graph.js.map +1 -0
  121. package/dist/server/tools/health-radar.d.ts +50 -0
  122. package/dist/server/tools/health-radar.d.ts.map +1 -0
  123. package/dist/server/tools/health-radar.js +426 -0
  124. package/dist/server/tools/health-radar.js.map +1 -0
  125. package/dist/server/tools/plan-refactoring.d.ts +74 -0
  126. package/dist/server/tools/plan-refactoring.d.ts.map +1 -0
  127. package/dist/server/tools/plan-refactoring.js +644 -0
  128. package/dist/server/tools/plan-refactoring.js.map +1 -0
  129. package/dist/server/tools/render-call-graph.d.ts +40 -0
  130. package/dist/server/tools/render-call-graph.d.ts.map +1 -0
  131. package/dist/server/tools/render-call-graph.js +215 -0
  132. package/dist/server/tools/render-call-graph.js.map +1 -0
  133. package/dist/server/tools/render-class-hierarchy.d.ts +42 -0
  134. package/dist/server/tools/render-class-hierarchy.d.ts.map +1 -0
  135. package/dist/server/tools/render-class-hierarchy.js +265 -0
  136. package/dist/server/tools/render-class-hierarchy.js.map +1 -0
  137. package/dist/server/tools/render-dep-matrix.d.ts +38 -0
  138. package/dist/server/tools/render-dep-matrix.d.ts.map +1 -0
  139. package/dist/server/tools/render-dep-matrix.js +186 -0
  140. package/dist/server/tools/render-dep-matrix.js.map +1 -0
  141. package/dist/server/tools/render-diagram.d.ts +47 -0
  142. package/dist/server/tools/render-diagram.d.ts.map +1 -0
  143. package/dist/server/tools/render-diagram.js +266 -0
  144. package/dist/server/tools/render-diagram.js.map +1 -0
  145. package/dist/server/tools/render-import-graph.d.ts +41 -0
  146. package/dist/server/tools/render-import-graph.d.ts.map +1 -0
  147. package/dist/server/tools/render-import-graph.js +158 -0
  148. package/dist/server/tools/render-import-graph.js.map +1 -0
  149. package/dist/server/tools/search-ast.d.ts +55 -0
  150. package/dist/server/tools/search-ast.d.ts.map +1 -0
  151. package/dist/server/tools/search-ast.js +279 -0
  152. package/dist/server/tools/search-ast.js.map +1 -0
  153. package/dist/server/tools/search-by-complexity.d.ts +92 -0
  154. package/dist/server/tools/search-by-complexity.d.ts.map +1 -0
  155. package/dist/server/tools/search-by-complexity.js +268 -0
  156. package/dist/server/tools/search-by-complexity.js.map +1 -0
  157. package/dist/server/tools/search-by-decorator.d.ts +48 -0
  158. package/dist/server/tools/search-by-decorator.d.ts.map +1 -0
  159. package/dist/server/tools/search-by-decorator.js +518 -0
  160. package/dist/server/tools/search-by-decorator.js.map +1 -0
  161. package/dist/server/tools/search-by-signature.d.ts +56 -0
  162. package/dist/server/tools/search-by-signature.d.ts.map +1 -0
  163. package/dist/server/tools/search-by-signature.js +200 -0
  164. package/dist/server/tools/search-by-signature.js.map +1 -0
  165. package/dist/ui/assets/BlastRadius-QdgESOL8.js +1 -0
  166. package/dist/ui/assets/{DependencyGraph-CDtBHM0U.js → DependencyGraph-BSMhzwWV.js} +6 -6
  167. package/dist/ui/assets/{NotFound-Cdt6X8pl.js → NotFound-CipFP_s1.js} +1 -1
  168. package/dist/ui/assets/RepoDetail-Dfp5z5Kq.js +1 -0
  169. package/dist/ui/assets/{RepoList-B9LaZvob.js → RepoList-BKtST3hB.js} +1 -1
  170. package/dist/ui/assets/{Search-CLqv2KGV.js → Search-DzhGDViy.js} +1 -1
  171. package/dist/ui/assets/{SymbolView-BlbDR1DU.js → SymbolView-ryVEwAHG.js} +1 -1
  172. package/dist/ui/assets/{index-DADf5y_L.css → index-Ny8gn9F0.css} +1 -1
  173. package/dist/ui/assets/{index-i3Q1XbEh.js → index-nX2chMqi.js} +6 -6
  174. package/dist/ui/assets/{useSearch-mbMk6-M1.js → useSearch-BnBCRKui.js} +1 -1
  175. package/dist/ui/index.html +2 -2
  176. package/dist/version.d.ts +1 -1
  177. package/dist/version.js +1 -1
  178. package/docs/dev/jcodemunch-gap-analysis.md +198 -0
  179. package/package.json +9 -1
  180. package/user-manual.md +2466 -0
  181. package/dist/ui/assets/BlastRadius-BDZWhEk-.js +0 -1
  182. package/dist/ui/assets/RepoDetail-M6WaYbZ3.js +0 -1
@@ -0,0 +1,158 @@
1
+ /**
2
+ * render-import-graph.ts
3
+ *
4
+ * MCP tool: render_import_graph
5
+ *
6
+ * Render a file-level import graph for a directory as a Mermaid or DOT diagram.
7
+ *
8
+ * Node categories:
9
+ * - In-scope nodes — files whose path starts with `filePath` (no special style)
10
+ * - Boundary nodes — files OUTSIDE `filePath` that are imported by in-scope files
11
+ * (shown with a grey fill so the import boundary is visible)
12
+ * - External nodes — npm package specifiers (only when includeExternal: true;
13
+ * these are not stored in dep_edges so they are a no-op at
14
+ * the moment — the parameter is accepted for API stability)
15
+ *
16
+ * All dep_edges are internal file-to-file edges (external npm imports are dropped
17
+ * at graph-build time in graph-builder.ts). Boundary nodes are detected by
18
+ * comparing `targetFile` against the `filePath` scope prefix.
19
+ */
20
+ import { z } from 'zod';
21
+ import { openDatabase, getRepo } from '../../core/db/schema.js';
22
+ import { getAllDepEdges } from '../../core/db/dep-store.js';
23
+ import { sanitizeId, shortLabel, parentDir, pruneGraph, renderMermaidImportGraph, renderDot, } from '../../graph/diagram-renderer.js';
24
+ import { buildMeta } from './_meta.js';
25
+ export const name = 'render_import_graph';
26
+ export const description = 'Render a file-level import graph for a directory as a Mermaid or DOT diagram. ' +
27
+ 'Nodes = files, edges = import relationships. Files inside the directory are ' +
28
+ 'clustered by subdirectory using Mermaid subgraph blocks. Files outside the ' +
29
+ 'directory that are imported by in-scope files appear as grey boundary nodes. ' +
30
+ 'Use maxNodes (default 30) to keep large graphs readable. ' +
31
+ 'Mermaid output renders natively in GitHub, VS Code, and Claude.';
32
+ export const inputSchema = {
33
+ repoId: z.string().describe('Repo ID from index_folder or resolve_repo'),
34
+ filePath: z
35
+ .string()
36
+ .describe('Directory path to scope the graph to (relative to repo root). ' +
37
+ 'E.g. "src/core/" — only files under this directory are rendered as primary nodes. ' +
38
+ 'Files outside this directory that are imported by in-scope files appear as boundary nodes.'),
39
+ includeExternal: z
40
+ .boolean()
41
+ .optional()
42
+ .describe('When true, external npm imports appear as grey terminal nodes. ' +
43
+ 'Default false. Note: external imports are not stored in the dep graph, ' +
44
+ 'so this option currently has no effect (reserved for future use).'),
45
+ maxNodes: z
46
+ .number()
47
+ .int()
48
+ .min(1)
49
+ .max(200)
50
+ .optional()
51
+ .describe('Maximum number of nodes to include. Least-connected nodes are dropped first. Default 30.'),
52
+ format: z
53
+ .enum(['mermaid', 'dot'])
54
+ .optional()
55
+ .describe('Output format. Default "mermaid".'),
56
+ };
57
+ // ─── Handler ──────────────────────────────────────────────────────────────────
58
+ export async function handler(args) {
59
+ const t0 = Date.now();
60
+ const { repoId, filePath, includeExternal = false, maxNodes = 30, format = 'mermaid', } = args;
61
+ const db = openDatabase(repoId);
62
+ try {
63
+ const repo = getRepo(db, repoId);
64
+ if (!repo) {
65
+ return {
66
+ content: [
67
+ { type: 'text', text: JSON.stringify({ error: `Repo "${repoId}" not found. Run index_folder first.` }) },
68
+ ],
69
+ isError: true,
70
+ };
71
+ }
72
+ // Normalise scope prefix — always ends with '/'
73
+ const scopePrefix = filePath.endsWith('/') ? filePath : filePath + '/';
74
+ // Fetch all dep_edges for the repo and filter to edges whose source is in scope.
75
+ const allEdges = getAllDepEdges(db, repoId);
76
+ const sourceEdges = allEdges.filter((e) => e.sourceFile.startsWith(scopePrefix));
77
+ // Classify edges into internal (both endpoints in scope) and boundary
78
+ // (target is an internal file but outside the scope prefix).
79
+ const internalEdges = sourceEdges.filter((e) => e.targetFile.startsWith(scopePrefix));
80
+ const boundaryEdges = sourceEdges.filter((e) => !e.targetFile.startsWith(scopePrefix));
81
+ // Build node set: collect in-scope files from all source edges, then add
82
+ // boundary files from boundary edges.
83
+ const inScopeFiles = new Set();
84
+ for (const e of sourceEdges) {
85
+ inScopeFiles.add(e.sourceFile);
86
+ }
87
+ for (const e of internalEdges) {
88
+ inScopeFiles.add(e.targetFile);
89
+ }
90
+ const boundaryFiles = new Set();
91
+ for (const e of boundaryEdges) {
92
+ boundaryFiles.add(e.targetFile);
93
+ }
94
+ // Build GraphNode array: in-scope nodes clustered by subdirectory, boundary
95
+ // nodes placed in a synthetic 'external' group.
96
+ const nodes = [];
97
+ for (const fp of inScopeFiles) {
98
+ nodes.push({
99
+ id: sanitizeId(fp),
100
+ label: shortLabel(fp),
101
+ fullPath: fp,
102
+ group: parentDir(fp),
103
+ });
104
+ }
105
+ for (const fp of boundaryFiles) {
106
+ nodes.push({
107
+ id: sanitizeId(fp),
108
+ label: shortLabel(fp),
109
+ fullPath: fp,
110
+ group: parentDir(fp),
111
+ styleClass: 'boundary',
112
+ });
113
+ }
114
+ // includeExternal: external npm imports are not stored in dep_edges, so
115
+ // this branch intentionally has no effect until a future phase persists them.
116
+ void includeExternal;
117
+ // Deduplicate edges (same source→target pair may appear multiple times).
118
+ const seenEdges = new Set();
119
+ const edges = [];
120
+ for (const e of [...internalEdges, ...boundaryEdges]) {
121
+ const key = `${e.sourceFile}→${e.targetFile}`;
122
+ if (!seenEdges.has(key)) {
123
+ seenEdges.add(key);
124
+ edges.push({
125
+ source: sanitizeId(e.sourceFile),
126
+ target: sanitizeId(e.targetFile),
127
+ });
128
+ }
129
+ }
130
+ // Apply maxNodes pruning — drops least-connected nodes first.
131
+ const { nodes: prunedNodes, edges: prunedEdges, truncated } = pruneGraph(nodes, edges, maxNodes);
132
+ // Count in-scope files (boundary nodes don't count as "files in graph").
133
+ const fileCount = prunedNodes.filter((n) => !n.styleClass).length;
134
+ // Render.
135
+ let diagram;
136
+ if (format === 'dot') {
137
+ diagram = renderDot(prunedNodes, prunedEdges);
138
+ }
139
+ else {
140
+ diagram = renderMermaidImportGraph(prunedNodes, prunedEdges);
141
+ }
142
+ const output = {
143
+ diagram,
144
+ fileCount,
145
+ edgeCount: prunedEdges.length,
146
+ truncated,
147
+ _tokenEstimate: Math.ceil(diagram.length / 4),
148
+ _meta: buildMeta({ timingMs: Date.now() - t0 }),
149
+ };
150
+ return {
151
+ content: [{ type: 'text', text: JSON.stringify(output, null, 2) }],
152
+ };
153
+ }
154
+ finally {
155
+ db.close();
156
+ }
157
+ }
158
+ //# sourceMappingURL=render-import-graph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-import-graph.js","sourceRoot":"","sources":["../../../src/server/tools/render-import-graph.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * search-ast.ts
3
+ *
4
+ * MCP tool: search_ast
5
+ *
6
+ * Structural AST node-type search. Re-parses the raw file content stored in
7
+ * the index using the appropriate tree-sitter grammar and walks the resulting
8
+ * AST to find every node whose type matches `nodeType`.
9
+ *
10
+ * Only files backed by a WASM grammar are searched. Files handled by the
11
+ * regex-based fallback (Perl, Terraform, Nix, Protobuf, GraphQL, Groovy,
12
+ * Erlang, GDScript, XML, etc.) are silently skipped and noted in `skippedFiles`.
13
+ *
14
+ * Common node types (case-sensitive, tree-sitter names):
15
+ * TypeScript / JavaScript:
16
+ * arrow_function function_declaration class_declaration
17
+ * interface_declaration try_statement await_expression
18
+ * call_expression import_statement jsx_element
19
+ * template_string throw_statement type_alias_declaration
20
+ * Python:
21
+ * function_definition class_definition for_statement
22
+ * with_statement decorated_definition lambda
23
+ * Rust:
24
+ * function_item struct_item impl_item
25
+ * match_expression closure_expression trait_item
26
+ * Go:
27
+ * function_declaration method_declaration go_statement
28
+ * defer_statement type_declaration interface_type
29
+ * Java / Kotlin:
30
+ * method_declaration class_declaration try_statement
31
+ * lambda_expression annotation
32
+ */
33
+ import { z } from 'zod';
34
+ import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
35
+ export declare const name = "search_ast";
36
+ export declare const description: string;
37
+ export declare const inputSchema: {
38
+ repoId: z.ZodString;
39
+ nodeType: z.ZodString;
40
+ language: z.ZodOptional<z.ZodString>;
41
+ filePath: z.ZodOptional<z.ZodString>;
42
+ includeText: z.ZodOptional<z.ZodBoolean>;
43
+ maxTextLength: z.ZodOptional<z.ZodNumber>;
44
+ limit: z.ZodOptional<z.ZodNumber>;
45
+ };
46
+ export declare function handler(args: {
47
+ repoId: string;
48
+ nodeType: string;
49
+ language?: string;
50
+ filePath?: string;
51
+ includeText?: boolean;
52
+ maxTextLength?: number;
53
+ limit?: number;
54
+ }): Promise<CallToolResult>;
55
+ //# sourceMappingURL=search-ast.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-ast.d.ts","sourceRoot":"","sources":["../../../src/server/tools/search-ast.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAGzE,eAAO,MAAM,IAAI,eAAe,CAAC;AAEjC,eAAO,MAAM,WAAW,QAe2B,CAAC;AAEpD,eAAO,MAAM,WAAW;;;;;;;;CAwCvB,CAAC;AAiCF,wBAAsB,OAAO,CAAC,IAAI,EAAE;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,cAAc,CAAC,CAgN1B"}
@@ -0,0 +1,279 @@
1
+ /**
2
+ * search-ast.ts
3
+ *
4
+ * MCP tool: search_ast
5
+ *
6
+ * Structural AST node-type search. Re-parses the raw file content stored in
7
+ * the index using the appropriate tree-sitter grammar and walks the resulting
8
+ * AST to find every node whose type matches `nodeType`.
9
+ *
10
+ * Only files backed by a WASM grammar are searched. Files handled by the
11
+ * regex-based fallback (Perl, Terraform, Nix, Protobuf, GraphQL, Groovy,
12
+ * Erlang, GDScript, XML, etc.) are silently skipped and noted in `skippedFiles`.
13
+ *
14
+ * Common node types (case-sensitive, tree-sitter names):
15
+ * TypeScript / JavaScript:
16
+ * arrow_function function_declaration class_declaration
17
+ * interface_declaration try_statement await_expression
18
+ * call_expression import_statement jsx_element
19
+ * template_string throw_statement type_alias_declaration
20
+ * Python:
21
+ * function_definition class_definition for_statement
22
+ * with_statement decorated_definition lambda
23
+ * Rust:
24
+ * function_item struct_item impl_item
25
+ * match_expression closure_expression trait_item
26
+ * Go:
27
+ * function_declaration method_declaration go_statement
28
+ * defer_statement type_declaration interface_type
29
+ * Java / Kotlin:
30
+ * method_declaration class_declaration try_statement
31
+ * lambda_expression annotation
32
+ */
33
+ import { z } from 'zod';
34
+ import { openDatabase } from '../../core/db/schema.js';
35
+ import { buildMeta } from './_meta.js';
36
+ import { getHandler } from '../../handlers/handler-registry.js';
37
+ import { initParser, parseFile, isInitialized } from '../../core/parse-dispatcher.js';
38
+ export const name = 'search_ast';
39
+ export const description = 'Structural AST node-type search. Finds every occurrence of a specific ' +
40
+ 'tree-sitter node type across indexed files — e.g. all arrow functions, all ' +
41
+ 'try/catch blocks, all await expressions, all JSX elements — without reading ' +
42
+ 'files manually. Re-parses stored file content using the appropriate grammar. ' +
43
+ 'Only files backed by a WASM grammar (TypeScript, JavaScript, Python, Go, ' +
44
+ 'Rust, Java, C/C++, etc.) are searched; regex-only handlers are skipped.' +
45
+ '\n\nNode type is the exact tree-sitter internal name (case-sensitive):' +
46
+ '\n "arrow_function" — all arrow functions' +
47
+ '\n "try_statement" — all try/catch blocks' +
48
+ '\n "await_expression" — all awaited expressions' +
49
+ '\n "class_declaration" — all class declarations' +
50
+ '\n "interface_declaration"— all TypeScript interfaces' +
51
+ '\n "jsx_element" — all JSX elements' +
52
+ '\n "template_string" — all template literals' +
53
+ '\n "call_expression" — all function calls';
54
+ export const inputSchema = {
55
+ repoId: z.string().describe('Repository ID returned by index_folder or list_repos'),
56
+ nodeType: z
57
+ .string()
58
+ .min(1)
59
+ .describe('The tree-sitter AST node type to search for (e.g. "arrow_function", ' +
60
+ '"try_statement", "class_declaration"). Exact, case-sensitive match.'),
61
+ language: z
62
+ .string()
63
+ .optional()
64
+ .describe('Restrict search to files of a specific language ' +
65
+ '(e.g. "typescript", "javascript", "python", "go", "rust", "java"). ' +
66
+ 'When omitted, all WASM-backed grammar files in the repo are searched.'),
67
+ filePath: z
68
+ .string()
69
+ .optional()
70
+ .describe('Restrict search to a specific file path or directory prefix'),
71
+ includeText: z
72
+ .boolean()
73
+ .optional()
74
+ .describe('Whether to include the matched node\'s source text in each result ' +
75
+ '(default true). Set false to reduce response size when you only need locations.'),
76
+ maxTextLength: z
77
+ .number()
78
+ .int()
79
+ .positive()
80
+ .optional()
81
+ .describe('Maximum characters of matched node text to include (default 120)'),
82
+ limit: z
83
+ .number()
84
+ .int()
85
+ .positive()
86
+ .optional()
87
+ .describe('Maximum number of matches to return (default 50)'),
88
+ };
89
+ // ─── Internals ────────────────────────────────────────────────────────────────
90
+ /** Recursively walk the AST collecting nodes whose type === targetType. */
91
+ function collectNodes(node, targetType, results) {
92
+ if (node.type === targetType) {
93
+ results.push(node);
94
+ }
95
+ for (const child of node.children) {
96
+ collectNodes(child, targetType, results);
97
+ }
98
+ }
99
+ /** Count newlines in `buf` up to (not including) byte offset `byteOffset`. */
100
+ function byteOffsetToLine(buf, byteOffset) {
101
+ let line = 1;
102
+ const end = Math.min(byteOffset, buf.length);
103
+ for (let i = 0; i < end; i++) {
104
+ if (buf[i] === 0x0a)
105
+ line++;
106
+ }
107
+ return line;
108
+ }
109
+ // ─── Handler ──────────────────────────────────────────────────────────────────
110
+ export async function handler(args) {
111
+ const t0 = Date.now();
112
+ const { repoId, nodeType, language, filePath, includeText = true, maxTextLength = 120, limit = 50, } = args;
113
+ // ── Validate nodeType is a non-empty string ──────────────────────────────────
114
+ if (!nodeType || nodeType.trim().length === 0) {
115
+ return {
116
+ content: [{
117
+ type: 'text',
118
+ text: JSON.stringify({ error: 'nodeType must be a non-empty string' }),
119
+ }],
120
+ isError: true,
121
+ };
122
+ }
123
+ const db = openDatabase(repoId);
124
+ try {
125
+ // ── Verify repo exists ───────────────────────────────────────────────────
126
+ const repoRow = db.prepare('SELECT id FROM repos WHERE id = ?').get(repoId);
127
+ if (!repoRow) {
128
+ return {
129
+ content: [{
130
+ type: 'text',
131
+ text: JSON.stringify({ error: `Repository not found: ${repoId}` }),
132
+ }],
133
+ isError: true,
134
+ };
135
+ }
136
+ // ── Build file query ─────────────────────────────────────────────────────
137
+ // Resolve language → allowed extensions if language filter was specified
138
+ let allowedExtensions = null;
139
+ if (language) {
140
+ const h = getHandler(`.${language}`);
141
+ if (h) {
142
+ allowedExtensions = new Set(h.extensions());
143
+ }
144
+ else {
145
+ // Try by looking up a handler via getHandler with common patterns
146
+ // e.g. "typescript" → try ".ts"
147
+ const langToExt = {
148
+ typescript: ['.ts', '.tsx'],
149
+ javascript: ['.js', '.jsx', '.mjs', '.cjs'],
150
+ python: ['.py'],
151
+ go: ['.go'],
152
+ rust: ['.rs'],
153
+ java: ['.java'],
154
+ kotlin: ['.kt', '.kts'],
155
+ csharp: ['.cs'],
156
+ cpp: ['.cpp', '.cc', '.cxx', '.hpp', '.hxx', '.hh'],
157
+ c: ['.c', '.h'],
158
+ php: ['.php'],
159
+ ruby: ['.rb'],
160
+ lua: ['.lua'],
161
+ dart: ['.dart'],
162
+ swift: ['.swift'],
163
+ scala: ['.scala', '.sc'],
164
+ elixir: ['.ex', '.exs'],
165
+ haskell: ['.hs', '.lhs'],
166
+ r: ['.r'],
167
+ bash: ['.sh', '.bash'],
168
+ };
169
+ const exts = langToExt[language.toLowerCase()];
170
+ if (exts) {
171
+ allowedExtensions = new Set(exts);
172
+ }
173
+ // If language is unknown, proceed without extension filter — will just get 0 matches
174
+ }
175
+ }
176
+ const conditions = ['repo_id = @repoId', 'raw_content IS NOT NULL'];
177
+ const params = { repoId };
178
+ if (filePath) {
179
+ conditions.push('(path = @filePath OR path LIKE @filePathPrefix)');
180
+ params['filePath'] = filePath;
181
+ params['filePathPrefix'] = `${filePath}%`;
182
+ }
183
+ const sql = `
184
+ SELECT path, raw_content
185
+ FROM files
186
+ WHERE ${conditions.join(' AND ')}
187
+ ORDER BY path
188
+ `;
189
+ const fileRows = db.prepare(sql).all(params);
190
+ // ── Initialize tree-sitter parser (idempotent) ───────────────────────────
191
+ if (!isInitialized()) {
192
+ await initParser();
193
+ }
194
+ // ── Walk files and collect matches ───────────────────────────────────────
195
+ const matches = [];
196
+ const skippedFiles = [];
197
+ let totalMatchesBeforeLimit = 0;
198
+ let truncated = false;
199
+ for (const row of fileRows) {
200
+ if (!row.raw_content)
201
+ continue;
202
+ const filePath = row.path;
203
+ const content = row.raw_content;
204
+ // ── Extension filter ─────────────────────────────────────────────────
205
+ const ext = filePath.includes('.')
206
+ ? `.${filePath.split('.').pop().toLowerCase()}`
207
+ : '';
208
+ if (allowedExtensions && !allowedExtensions.has(ext)) {
209
+ continue;
210
+ }
211
+ // ── Get handler — skip files with no WASM grammar ───────────────────
212
+ const h = getHandler(filePath);
213
+ if (!h || h.grammarPath() === null) {
214
+ if (h)
215
+ skippedFiles.push(filePath); // has handler but regex-only
216
+ continue;
217
+ }
218
+ // ── Parse and walk AST ───────────────────────────────────────────────
219
+ let tree;
220
+ try {
221
+ tree = await parseFile(content, h);
222
+ }
223
+ catch {
224
+ skippedFiles.push(filePath);
225
+ continue;
226
+ }
227
+ const found = [];
228
+ collectNodes(tree.rootNode, nodeType, found);
229
+ totalMatchesBeforeLimit += found.length;
230
+ for (const node of found) {
231
+ if (matches.length >= limit) {
232
+ truncated = true;
233
+ break;
234
+ }
235
+ const startLine = byteOffsetToLine(content, node.startIndex);
236
+ const endLine = byteOffsetToLine(content, node.endIndex);
237
+ const rawText = content.toString('utf8', node.startIndex, node.endIndex);
238
+ const text = includeText
239
+ ? rawText.length > maxTextLength
240
+ ? rawText.slice(0, maxTextLength) + '…'
241
+ : rawText
242
+ : '';
243
+ matches.push({
244
+ filePath,
245
+ startLine,
246
+ endLine,
247
+ startByte: node.startIndex,
248
+ endByte: node.endIndex,
249
+ nodeType,
250
+ text,
251
+ });
252
+ }
253
+ if (truncated)
254
+ break;
255
+ }
256
+ // ── Token estimate ───────────────────────────────────────────────────────
257
+ const responseBytes = matches.reduce((sum, m) => sum + m.text.length + m.filePath.length + 60, 0);
258
+ const tokenEstimate = Math.ceil(responseBytes / 4);
259
+ return {
260
+ content: [{
261
+ type: 'text',
262
+ text: JSON.stringify({
263
+ matches,
264
+ totalFound: matches.length,
265
+ truncated,
266
+ nodeTypeSearched: nodeType,
267
+ filesSearched: fileRows.length - skippedFiles.length,
268
+ skippedFiles: skippedFiles.length > 0 ? skippedFiles : undefined,
269
+ _tokenEstimate: tokenEstimate,
270
+ _meta: buildMeta({ timingMs: Date.now() - t0 }),
271
+ }, null, 2),
272
+ }],
273
+ };
274
+ }
275
+ finally {
276
+ db.close();
277
+ }
278
+ }
279
+ //# sourceMappingURL=search-ast.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-ast.js","sourceRoot":"","sources":["../../../src/server/tools/search-ast.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * search-by-complexity.ts
3
+ *
4
+ * MCP tool: search_by_complexity
5
+ *
6
+ * Find all symbols whose complexity metrics match a set of min/max filters.
7
+ * Covers six dimensions stored at index time:
8
+ * cyclomatic_complexity, cognitive_complexity, line_count,
9
+ * nesting_depth, param_count, return_count
10
+ *
11
+ * All filters are optional and combined with AND. Omitting a filter means
12
+ * "no constraint on that dimension". The tool returns only symbols that have
13
+ * metrics (logic-carrying kinds: function, method, class, component, etc.).
14
+ *
15
+ * Designed for targeted queries like:
16
+ * "show me every function with ≥8 cyclomatic complexity"
17
+ * "find all methods with exactly 0–2 parameters"
18
+ * "list functions that are between 20 and 50 lines"
19
+ *
20
+ * Use get_quality_metrics when you want a ranked worst-offenders list with a
21
+ * composite score. Use search_by_complexity when you have a specific threshold
22
+ * or range in mind for one or more individual dimensions.
23
+ */
24
+ import { z } from 'zod';
25
+ import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
26
+ export declare const name = "search_by_complexity";
27
+ export declare const description: string;
28
+ export declare const inputSchema: {
29
+ repoId: z.ZodString;
30
+ minCyclomaticComplexity: z.ZodOptional<z.ZodNumber>;
31
+ maxCyclomaticComplexity: z.ZodOptional<z.ZodNumber>;
32
+ minCognitiveComplexity: z.ZodOptional<z.ZodNumber>;
33
+ maxCognitiveComplexity: z.ZodOptional<z.ZodNumber>;
34
+ minLineCount: z.ZodOptional<z.ZodNumber>;
35
+ maxLineCount: z.ZodOptional<z.ZodNumber>;
36
+ minNestingDepth: z.ZodOptional<z.ZodNumber>;
37
+ maxNestingDepth: z.ZodOptional<z.ZodNumber>;
38
+ minParamCount: z.ZodOptional<z.ZodNumber>;
39
+ maxParamCount: z.ZodOptional<z.ZodNumber>;
40
+ minReturnCount: z.ZodOptional<z.ZodNumber>;
41
+ maxReturnCount: z.ZodOptional<z.ZodNumber>;
42
+ sortBy: z.ZodOptional<z.ZodEnum<{
43
+ size: "size";
44
+ params: "params";
45
+ complexity: "complexity";
46
+ nesting: "nesting";
47
+ cognitive: "cognitive";
48
+ returns: "returns";
49
+ }>>;
50
+ sortOrder: z.ZodOptional<z.ZodEnum<{
51
+ asc: "asc";
52
+ desc: "desc";
53
+ }>>;
54
+ kind: z.ZodOptional<z.ZodEnum<{
55
+ function: "function";
56
+ method: "method";
57
+ class: "class";
58
+ const: "const";
59
+ type: "type";
60
+ interface: "interface";
61
+ enum: "enum";
62
+ component: "component";
63
+ composable: "composable";
64
+ hook: "hook";
65
+ route: "route";
66
+ decorator: "decorator";
67
+ middleware: "middleware";
68
+ }>>;
69
+ filePath: z.ZodOptional<z.ZodString>;
70
+ limit: z.ZodOptional<z.ZodNumber>;
71
+ };
72
+ export declare function handler(args: {
73
+ repoId: string;
74
+ minCyclomaticComplexity?: number;
75
+ maxCyclomaticComplexity?: number;
76
+ minCognitiveComplexity?: number;
77
+ maxCognitiveComplexity?: number;
78
+ minLineCount?: number;
79
+ maxLineCount?: number;
80
+ minNestingDepth?: number;
81
+ maxNestingDepth?: number;
82
+ minParamCount?: number;
83
+ maxParamCount?: number;
84
+ minReturnCount?: number;
85
+ maxReturnCount?: number;
86
+ sortBy?: 'complexity' | 'cognitive' | 'size' | 'nesting' | 'params' | 'returns';
87
+ sortOrder?: 'asc' | 'desc';
88
+ kind?: string;
89
+ filePath?: string;
90
+ limit?: number;
91
+ }): Promise<CallToolResult>;
92
+ //# sourceMappingURL=search-by-complexity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-by-complexity.d.ts","sourceRoot":"","sources":["../../../src/server/tools/search-by-complexity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAGzE,eAAO,MAAM,IAAI,yBAAyB,CAAC;AAE3C,eAAO,MAAM,WAAW,QAYyD,CAAC;AAElF,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuEvB,CAAC;AAiCF,wBAAsB,OAAO,CAAC,IAAI,EAAE;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,YAAY,GAAG,WAAW,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;IAChF,SAAS,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,cAAc,CAAC,CAyK1B"}