@grafema/mcp 0.2.11 → 0.3.0-beta

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 (158) hide show
  1. package/dist/analysis-worker.d.ts +4 -3
  2. package/dist/analysis-worker.d.ts.map +1 -1
  3. package/dist/analysis-worker.js +8 -203
  4. package/dist/analysis-worker.js.map +1 -1
  5. package/dist/analysis.d.ts +10 -3
  6. package/dist/analysis.d.ts.map +1 -1
  7. package/dist/analysis.js +130 -62
  8. package/dist/analysis.js.map +1 -1
  9. package/dist/config.d.ts +5 -11
  10. package/dist/config.d.ts.map +1 -1
  11. package/dist/config.js +6 -128
  12. package/dist/config.js.map +1 -1
  13. package/dist/definitions/analysis-tools.d.ts +6 -0
  14. package/dist/definitions/analysis-tools.d.ts.map +1 -0
  15. package/dist/definitions/analysis-tools.js +125 -0
  16. package/dist/definitions/analysis-tools.js.map +1 -0
  17. package/dist/definitions/context-tools.d.ts +6 -0
  18. package/dist/definitions/context-tools.d.ts.map +1 -0
  19. package/dist/definitions/context-tools.js +144 -0
  20. package/dist/definitions/context-tools.js.map +1 -0
  21. package/dist/definitions/graph-tools.d.ts +7 -0
  22. package/dist/definitions/graph-tools.d.ts.map +1 -0
  23. package/dist/definitions/graph-tools.js +124 -0
  24. package/dist/definitions/graph-tools.js.map +1 -0
  25. package/dist/definitions/graphql-tools.d.ts +6 -0
  26. package/dist/definitions/graphql-tools.d.ts.map +1 -0
  27. package/dist/definitions/graphql-tools.js +62 -0
  28. package/dist/definitions/graphql-tools.js.map +1 -0
  29. package/dist/definitions/guarantee-tools.d.ts +6 -0
  30. package/dist/definitions/guarantee-tools.d.ts.map +1 -0
  31. package/dist/definitions/guarantee-tools.js +136 -0
  32. package/dist/definitions/guarantee-tools.js.map +1 -0
  33. package/dist/definitions/index.d.ts +7 -0
  34. package/dist/definitions/index.d.ts.map +1 -0
  35. package/dist/definitions/index.js +24 -0
  36. package/dist/definitions/index.js.map +1 -0
  37. package/dist/definitions/knowledge-tools.d.ts +10 -0
  38. package/dist/definitions/knowledge-tools.d.ts.map +1 -0
  39. package/dist/definitions/knowledge-tools.js +300 -0
  40. package/dist/definitions/knowledge-tools.js.map +1 -0
  41. package/dist/definitions/notation-tools.d.ts +9 -0
  42. package/dist/definitions/notation-tools.d.ts.map +1 -0
  43. package/dist/definitions/notation-tools.js +62 -0
  44. package/dist/definitions/notation-tools.js.map +1 -0
  45. package/dist/definitions/project-tools.d.ts +6 -0
  46. package/dist/definitions/project-tools.d.ts.map +1 -0
  47. package/dist/definitions/project-tools.js +181 -0
  48. package/dist/definitions/project-tools.js.map +1 -0
  49. package/dist/definitions/query-tools.d.ts +6 -0
  50. package/dist/definitions/query-tools.d.ts.map +1 -0
  51. package/dist/definitions/query-tools.js +245 -0
  52. package/dist/definitions/query-tools.js.map +1 -0
  53. package/dist/definitions/types.d.ts +21 -0
  54. package/dist/definitions/types.d.ts.map +1 -0
  55. package/dist/definitions/types.js +5 -0
  56. package/dist/definitions/types.js.map +1 -0
  57. package/dist/dev-proxy.d.ts +29 -0
  58. package/dist/dev-proxy.d.ts.map +1 -0
  59. package/dist/dev-proxy.js +267 -0
  60. package/dist/dev-proxy.js.map +1 -0
  61. package/dist/handlers/analysis-handlers.d.ts.map +1 -1
  62. package/dist/handlers/analysis-handlers.js +34 -4
  63. package/dist/handlers/analysis-handlers.js.map +1 -1
  64. package/dist/handlers/context-handlers.d.ts +5 -6
  65. package/dist/handlers/context-handlers.d.ts.map +1 -1
  66. package/dist/handlers/context-handlers.js +19 -16
  67. package/dist/handlers/context-handlers.js.map +1 -1
  68. package/dist/handlers/coverage-handlers.js +1 -1
  69. package/dist/handlers/dataflow-handlers.d.ts +2 -0
  70. package/dist/handlers/dataflow-handlers.d.ts.map +1 -1
  71. package/dist/handlers/dataflow-handlers.js +68 -46
  72. package/dist/handlers/dataflow-handlers.js.map +1 -1
  73. package/dist/handlers/documentation-handlers.d.ts.map +1 -1
  74. package/dist/handlers/documentation-handlers.js +56 -2
  75. package/dist/handlers/documentation-handlers.js.map +1 -1
  76. package/dist/handlers/graph-handlers.d.ts +23 -0
  77. package/dist/handlers/graph-handlers.d.ts.map +1 -0
  78. package/dist/handlers/graph-handlers.js +155 -0
  79. package/dist/handlers/graph-handlers.js.map +1 -0
  80. package/dist/handlers/graphql-handlers.d.ts +9 -0
  81. package/dist/handlers/graphql-handlers.d.ts.map +1 -0
  82. package/dist/handlers/graphql-handlers.js +57 -0
  83. package/dist/handlers/graphql-handlers.js.map +1 -0
  84. package/dist/handlers/guarantee-handlers.js +1 -1
  85. package/dist/handlers/guard-handlers.d.ts.map +1 -1
  86. package/dist/handlers/guard-handlers.js +6 -3
  87. package/dist/handlers/guard-handlers.js.map +1 -1
  88. package/dist/handlers/index.d.ts +4 -0
  89. package/dist/handlers/index.d.ts.map +1 -1
  90. package/dist/handlers/index.js +6 -0
  91. package/dist/handlers/index.js.map +1 -1
  92. package/dist/handlers/issue-handlers.d.ts.map +1 -1
  93. package/dist/handlers/issue-handlers.js +10 -15
  94. package/dist/handlers/issue-handlers.js.map +1 -1
  95. package/dist/handlers/knowledge-handlers.d.ts +25 -0
  96. package/dist/handlers/knowledge-handlers.d.ts.map +1 -0
  97. package/dist/handlers/knowledge-handlers.js +208 -0
  98. package/dist/handlers/knowledge-handlers.js.map +1 -0
  99. package/dist/handlers/notation-handlers.d.ts +6 -0
  100. package/dist/handlers/notation-handlers.d.ts.map +1 -0
  101. package/dist/handlers/notation-handlers.js +53 -0
  102. package/dist/handlers/notation-handlers.js.map +1 -0
  103. package/dist/handlers/project-handlers.js +1 -1
  104. package/dist/handlers/query-handlers.d.ts.map +1 -1
  105. package/dist/handlers/query-handlers.js +166 -20
  106. package/dist/handlers/query-handlers.js.map +1 -1
  107. package/dist/prompts.js +1 -1
  108. package/dist/server.d.ts +19 -1
  109. package/dist/server.d.ts.map +1 -1
  110. package/dist/server.js +93 -3
  111. package/dist/server.js.map +1 -1
  112. package/dist/state.d.ts +10 -1
  113. package/dist/state.d.ts.map +1 -1
  114. package/dist/state.js +61 -8
  115. package/dist/state.js.map +1 -1
  116. package/dist/types.d.ts +75 -3
  117. package/dist/types.d.ts.map +1 -1
  118. package/dist/utils.d.ts +4 -0
  119. package/dist/utils.d.ts.map +1 -1
  120. package/dist/utils.js +18 -1
  121. package/dist/utils.js.map +1 -1
  122. package/package.json +4 -3
  123. package/src/analysis-worker.ts +9 -301
  124. package/src/analysis.ts +151 -77
  125. package/src/config.ts +6 -193
  126. package/src/definitions/analysis-tools.ts +127 -0
  127. package/src/definitions/context-tools.ts +147 -0
  128. package/src/definitions/graph-tools.ts +126 -0
  129. package/src/definitions/graphql-tools.ts +64 -0
  130. package/src/definitions/guarantee-tools.ts +138 -0
  131. package/src/definitions/index.ts +28 -0
  132. package/src/definitions/knowledge-tools.ts +302 -0
  133. package/src/definitions/notation-tools.ts +64 -0
  134. package/src/definitions/project-tools.ts +183 -0
  135. package/src/definitions/query-tools.ts +247 -0
  136. package/src/definitions/types.ts +22 -0
  137. package/src/dev-proxy.ts +336 -0
  138. package/src/handlers/analysis-handlers.ts +35 -4
  139. package/src/handlers/context-handlers.ts +19 -15
  140. package/src/handlers/coverage-handlers.ts +1 -1
  141. package/src/handlers/dataflow-handlers.ts +74 -56
  142. package/src/handlers/documentation-handlers.ts +56 -2
  143. package/src/handlers/graph-handlers.ts +212 -0
  144. package/src/handlers/graphql-handlers.ts +70 -0
  145. package/src/handlers/guarantee-handlers.ts +1 -1
  146. package/src/handlers/guard-handlers.ts +7 -3
  147. package/src/handlers/index.ts +6 -0
  148. package/src/handlers/issue-handlers.ts +10 -15
  149. package/src/handlers/knowledge-handlers.ts +242 -0
  150. package/src/handlers/notation-handlers.ts +71 -0
  151. package/src/handlers/project-handlers.ts +1 -1
  152. package/src/handlers/query-handlers.ts +186 -22
  153. package/src/prompts.ts +1 -1
  154. package/src/server.ts +126 -2
  155. package/src/state.ts +68 -8
  156. package/src/types.ts +98 -3
  157. package/src/utils.ts +22 -1
  158. package/src/definitions.ts +0 -665
package/src/server.ts CHANGED
@@ -2,7 +2,25 @@
2
2
  /**
3
3
  * Grafema MCP Server
4
4
  *
5
- * Provides code analysis tools via Model Context Protocol.
5
+ * Graph-driven code analysis for AI agents. Query the code graph instead of reading files.
6
+ *
7
+ * Use Grafema when you need to:
8
+ * - Navigate code structure (find callers, trace data flow, understand impact)
9
+ * - Answer "who calls this?", "where is this used?", "what does this affect?"
10
+ * - Analyze untyped/dynamic codebases where static analysis falls short
11
+ * - Track relationships across files without manual grep
12
+ *
13
+ * Core capabilities:
14
+ * - Datalog queries for pattern matching (query_graph)
15
+ * - Call graph navigation (find_calls, get_function_details)
16
+ * - Data flow tracing (trace_dataflow, trace_alias)
17
+ * - Graph traversal primitives (get_node, get_neighbors, traverse_graph)
18
+ * - Code guarantees/invariants (create_guarantee, check_guarantees)
19
+ *
20
+ * Workflow:
21
+ * 1. discover_services — identify project structure
22
+ * 2. analyze_project — build the graph
23
+ * 3. Use query tools to explore code relationships
6
24
  */
7
25
 
8
26
  import { Server } from '@modelcontextprotocol/sdk/server/index.js';
@@ -15,7 +33,7 @@ import {
15
33
  } from '@modelcontextprotocol/sdk/types.js';
16
34
  import { PROMPTS, getPrompt } from './prompts.js';
17
35
 
18
- import { TOOLS } from './definitions.js';
36
+ import { TOOLS } from './definitions/index.js';
19
37
  import { initializeFromArgs, setupLogging, getProjectPath } from './state.js';
20
38
  import { textResult, errorResult, log } from './utils.js';
21
39
  import { discoverServices } from './analysis.js';
@@ -43,6 +61,21 @@ import {
43
61
  handleReadProjectStructure,
44
62
  handleWriteConfig,
45
63
  handleGetFileOverview,
64
+ handleGetNode,
65
+ handleGetNeighbors,
66
+ handleTraverseGraph,
67
+ handleAddKnowledge,
68
+ handleQueryKnowledge,
69
+ handleQueryDecisions,
70
+ handleSupersedeFact,
71
+ handleGetKnowledgeStats,
72
+ // Disabled: requires git-ingest (US-17). See US-17 in AI-AGENT-STORIES.md
73
+ // handleGitChurn,
74
+ // handleGitCoChange,
75
+ // handleGitOwnership,
76
+ // handleGitArchaeology,
77
+ handleDescribe,
78
+ handleGraphQLQuery,
46
79
  } from './handlers/index.js';
47
80
  import type {
48
81
  ToolResult,
@@ -66,6 +99,20 @@ import type {
66
99
  ReadProjectStructureArgs,
67
100
  WriteConfigArgs,
68
101
  GetFileOverviewArgs,
102
+ GetNodeArgs,
103
+ GetNeighborsArgs,
104
+ TraverseGraphArgs,
105
+ AddKnowledgeArgs,
106
+ QueryKnowledgeArgs,
107
+ QueryDecisionsArgs,
108
+ SupersedeFactArgs,
109
+ // Disabled: requires git-ingest (US-17). See US-17 in AI-AGENT-STORIES.md
110
+ // GitChurnArgs,
111
+ // GitCoChangeArgs,
112
+ // GitOwnershipArgs,
113
+ // GitArchaeologyArgs,
114
+ DescribeArgs,
115
+ GraphQLQueryArgs,
69
116
  } from './types.js';
70
117
 
71
118
  /**
@@ -89,12 +136,32 @@ const server = new Server(
89
136
  {
90
137
  name: 'grafema-mcp',
91
138
  version: '0.1.0',
139
+ description: 'Graph-driven code analysis. Query the code graph instead of reading files. Navigate call graphs, trace data flow, verify guarantees. For AI agents working with untyped/dynamic codebases.',
92
140
  },
93
141
  {
94
142
  capabilities: {
95
143
  tools: {},
96
144
  prompts: {},
97
145
  },
146
+ instructions: `Grafema is a code graph — use it instead of reading files.
147
+
148
+ START HERE: call get_stats to check if the graph is loaded (nodeCount > 0).
149
+ If nodeCount is 0, call analyze_project first.
150
+
151
+ EXPLORATION WORKFLOW:
152
+ 1. To understand a file → get_file_overview (shows imports, exports, functions, classes with relationships)
153
+ 2. To find functions/classes/modules → find_nodes (filter by type, name, or file pattern)
154
+ 3. To find who calls a function → find_calls (returns call sites with resolution status)
155
+ 4. To understand data flow → trace_dataflow (forward: where does this value go? backward: where does it come from?)
156
+ 5. To understand full context of a node → get_context (shows surrounding code, scope chain, relationships)
157
+ 6. For complex pattern queries → query_graph with Datalog (call get_documentation topic="queries" for syntax)
158
+ 7. To query architectural decisions and facts → query_knowledge, query_decisions, get_knowledge_stats
159
+ 8. To get a compact visual summary → describe (renders DSL notation with archetype-grouped operators)
160
+ 9. For DSL syntax reference → get_documentation topic="notation"
161
+
162
+ KEY INSIGHT: find_nodes supports partial matching on name and file fields.
163
+ Example: find_nodes(file="auth/") returns all nodes in files matching "auth/".
164
+ Example: find_nodes(name="redis", type="CALL") finds all calls containing "redis".`,
98
165
  }
99
166
  );
100
167
 
@@ -223,6 +290,63 @@ server.setRequestHandler(CallToolRequestSchema, async (request, extra) => {
223
290
  result = await handleWriteConfig(asArgs<WriteConfigArgs>(args));
224
291
  break;
225
292
 
293
+ case 'get_node':
294
+ result = await handleGetNode(asArgs<GetNodeArgs>(args));
295
+ break;
296
+
297
+ case 'get_neighbors':
298
+ result = await handleGetNeighbors(asArgs<GetNeighborsArgs>(args));
299
+ break;
300
+
301
+ case 'traverse_graph':
302
+ result = await handleTraverseGraph(asArgs<TraverseGraphArgs>(args));
303
+ break;
304
+
305
+ case 'add_knowledge':
306
+ result = await handleAddKnowledge(asArgs<AddKnowledgeArgs>(args));
307
+ break;
308
+
309
+ case 'query_knowledge':
310
+ result = await handleQueryKnowledge(asArgs<QueryKnowledgeArgs>(args));
311
+ break;
312
+
313
+ case 'query_decisions':
314
+ result = await handleQueryDecisions(asArgs<QueryDecisionsArgs>(args));
315
+ break;
316
+
317
+ case 'supersede_fact':
318
+ result = await handleSupersedeFact(asArgs<SupersedeFactArgs>(args));
319
+ break;
320
+
321
+ case 'get_knowledge_stats':
322
+ result = await handleGetKnowledgeStats();
323
+ break;
324
+
325
+ // Disabled: requires git-ingest (US-17). See US-17 in AI-AGENT-STORIES.md
326
+ // case 'git_churn':
327
+ // result = await handleGitChurn(asArgs<GitChurnArgs>(args));
328
+ // break;
329
+ //
330
+ // case 'git_cochange':
331
+ // result = await handleGitCoChange(asArgs<GitCoChangeArgs>(args));
332
+ // break;
333
+ //
334
+ // case 'git_ownership':
335
+ // result = await handleGitOwnership(asArgs<GitOwnershipArgs>(args));
336
+ // break;
337
+ //
338
+ // case 'git_archaeology':
339
+ // result = await handleGitArchaeology(asArgs<GitArchaeologyArgs>(args));
340
+ // break;
341
+
342
+ case 'describe':
343
+ result = await handleDescribe(asArgs<DescribeArgs>(args));
344
+ break;
345
+
346
+ case 'query_graphql':
347
+ result = await handleGraphQLQuery(asArgs<GraphQLQueryArgs>(args));
348
+ break;
349
+
226
350
  default:
227
351
  result = errorResult(`Unknown tool: ${name}`);
228
352
  }
package/src/state.ts CHANGED
@@ -4,8 +4,8 @@
4
4
 
5
5
  import { join } from 'path';
6
6
  import { existsSync, mkdirSync } from 'fs';
7
- import { RFDBServerBackend, GuaranteeManager, GuaranteeAPI } from '@grafema/core';
8
- import type { GuaranteeGraphBackend, GuaranteeGraph } from '@grafema/core';
7
+ import { RFDBServerBackend, GuaranteeManager, GuaranteeAPI, KnowledgeBase } from '@grafema/util';
8
+ import type { GuaranteeGraphBackend, GuaranteeGraph, ResolverBackend } from '@grafema/util';
9
9
  import { loadConfig } from './config.js';
10
10
  import { log, initLogger } from './utils.js';
11
11
  import type { AnalysisStatus } from './types.js';
@@ -21,6 +21,9 @@ let backgroundPid: number | null = null;
21
21
  let guaranteeManager: GuaranteeManager | null = null;
22
22
  let guaranteeAPI: GuaranteeAPI | null = null;
23
23
 
24
+ // Knowledge base
25
+ let knowledgeBase: KnowledgeBase | null = null;
26
+
24
27
  let analysisStatus: AnalysisStatus = {
25
28
  running: false,
26
29
  phase: null,
@@ -112,6 +115,10 @@ export function getGuaranteeAPI(): GuaranteeAPI | null {
112
115
  return guaranteeAPI;
113
116
  }
114
117
 
118
+ export function getKnowledgeBase(): KnowledgeBase | null {
119
+ return knowledgeBase;
120
+ }
121
+
115
122
  // === SETTERS ===
116
123
  export function setProjectPath(path: string): void {
117
124
  projectPath = path;
@@ -213,9 +220,28 @@ export async function waitForAnalysis(): Promise<void> {
213
220
  }
214
221
  }
215
222
 
216
- // === BACKEND ===
223
+ // === RESET ===
224
+ export function resetBackend(): void {
225
+ backend = null;
226
+ isAnalyzed = false;
227
+ }
228
+
229
+ export function resetKnowledgeBase(): void {
230
+ knowledgeBase = null;
231
+ }
232
+
217
233
  export async function getOrCreateBackend(): Promise<GraphBackend> {
218
- if (backend) return backend;
234
+ // Check if existing backend is still connected
235
+ if (backend) {
236
+ const rfdb = backend as unknown as RFDBServerBackend;
237
+ if (rfdb.connected) return backend;
238
+ // Connection died — reset and recreate
239
+ log('[Grafema MCP] Backend disconnected, reconnecting...');
240
+ backend = null;
241
+ isAnalyzed = false;
242
+ guaranteeManager = null;
243
+ guaranteeAPI = null;
244
+ }
219
245
 
220
246
  const grafemaDir = join(projectPath, '.grafema');
221
247
  const dbPath = join(grafemaDir, 'graph.rfdb');
@@ -230,7 +256,7 @@ export async function getOrCreateBackend(): Promise<GraphBackend> {
230
256
 
231
257
  log(`[Grafema MCP] Using RFDB server backend: socket=${socketPath || 'auto'}, db=${dbPath}`);
232
258
 
233
- const rfdbBackend = new RFDBServerBackend({ socketPath, dbPath });
259
+ const rfdbBackend = new RFDBServerBackend({ socketPath, dbPath, clientName: 'mcp' });
234
260
  await rfdbBackend.connect();
235
261
  backend = rfdbBackend as unknown as GraphBackend;
236
262
 
@@ -243,21 +269,32 @@ export async function getOrCreateBackend(): Promise<GraphBackend> {
243
269
  }
244
270
 
245
271
  // Initialize guarantee managers
246
- initializeGuaranteeManagers(rfdbBackend);
272
+ await initializeGuaranteeManagers(rfdbBackend);
247
273
 
248
274
  return backend;
249
275
  }
250
276
 
251
277
  /**
252
- * Initialize GuaranteeManager (Datalog-based) and GuaranteeAPI (contract-based)
278
+ * Initialize GuaranteeManager (Datalog-based) and GuaranteeAPI (contract-based).
279
+ * Loads guarantees from .grafema/guarantees.yaml if the file exists.
253
280
  */
254
- function initializeGuaranteeManagers(rfdbBackend: RFDBServerBackend): void {
281
+ async function initializeGuaranteeManagers(rfdbBackend: RFDBServerBackend): Promise<void> {
255
282
  // GuaranteeManager for Datalog-based guarantees
256
283
  // Cast to GuaranteeGraph interface expected by GuaranteeManager
257
284
  const guaranteeGraph = rfdbBackend as unknown as GuaranteeGraph;
258
285
  guaranteeManager = new GuaranteeManager(guaranteeGraph, projectPath);
259
286
  log(`[Grafema MCP] GuaranteeManager initialized`);
260
287
 
288
+ // Load guarantees from YAML (idempotent, skips existing)
289
+ try {
290
+ const result = await guaranteeManager.loadFromYaml();
291
+ if (result.imported > 0 || result.skipped > 0) {
292
+ log(`[Grafema MCP] Guarantees loaded from YAML: ${result.imported} imported, ${result.skipped} skipped`);
293
+ }
294
+ } catch (err) {
295
+ log(`[Grafema MCP] Warning: failed to load guarantees from YAML: ${err instanceof Error ? err.message : String(err)}`);
296
+ }
297
+
261
298
  // GuaranteeAPI for contract-based guarantees
262
299
  const guaranteeGraphBackend = rfdbBackend as unknown as GuaranteeGraphBackend;
263
300
  guaranteeAPI = new GuaranteeAPI(guaranteeGraphBackend);
@@ -277,6 +314,29 @@ export function setupLogging(): void {
277
314
  initLogger(grafemaDir);
278
315
  }
279
316
 
317
+ // === KNOWLEDGE BASE ===
318
+ /**
319
+ * Get or create the KnowledgeBase singleton.
320
+ * Lazy-initializes from knowledge/ directory on first access.
321
+ * If a backend is available, wires up the SemanticAddressResolver.
322
+ */
323
+ export async function getOrCreateKnowledgeBase(): Promise<KnowledgeBase> {
324
+ if (knowledgeBase) return knowledgeBase;
325
+
326
+ const kbDir = join(projectPath, 'knowledge');
327
+ knowledgeBase = new KnowledgeBase(kbDir);
328
+ await knowledgeBase.load();
329
+ log(`[Grafema MCP] KnowledgeBase loaded from ${kbDir}`);
330
+
331
+ // Wire up resolver with backend if available (cast to ResolverBackend — RFDBServerBackend has getAllNodes)
332
+ if (backend) {
333
+ knowledgeBase.setBackend(backend as unknown as ResolverBackend);
334
+ log(`[Grafema MCP] KnowledgeBase resolver wired to backend`);
335
+ }
336
+
337
+ return knowledgeBase;
338
+ }
339
+
280
340
  // === INITIALIZATION ===
281
341
  export function initializeFromArgs(): void {
282
342
  const args = process.argv.slice(2);
package/src/types.ts CHANGED
@@ -36,20 +36,23 @@ export interface PaginationParams {
36
36
  }
37
37
 
38
38
  // === CONFIG ===
39
- export type { GrafemaConfig } from '@grafema/core';
39
+ export type { GrafemaConfig } from '@grafema/util';
40
40
  export type { MCPConfig } from './config.js';
41
41
 
42
42
  // === TOOL ARGUMENTS ===
43
43
  export interface QueryGraphArgs {
44
44
  query: string;
45
+ language?: 'datalog' | 'cypher';
45
46
  limit?: number;
46
47
  offset?: number;
47
48
  format?: 'table' | 'json' | 'tree';
48
49
  explain?: boolean;
50
+ /** When true, returns only the count of matching results instead of the full result list */
51
+ count?: boolean;
49
52
  }
50
53
 
51
54
  export interface FindCallsArgs {
52
- target: string;
55
+ name: string;
53
56
  limit?: number;
54
57
  offset?: number;
55
58
  include_indirect?: boolean;
@@ -68,6 +71,7 @@ export interface TraceDataFlowArgs {
68
71
  direction?: 'forward' | 'backward' | 'both';
69
72
  max_depth?: number;
70
73
  limit?: number;
74
+ detail?: 'summary' | 'normal' | 'full';
71
75
  }
72
76
 
73
77
  export interface CheckInvariantArgs {
@@ -265,7 +269,7 @@ export interface GetFunctionDetailsArgs {
265
269
  }
266
270
 
267
271
  // Re-export types from core for convenience
268
- export type { CallInfo, CallerInfo, FindCallsOptions } from '@grafema/core';
272
+ export type { CallInfo, CallerInfo, FindCallsOptions } from '@grafema/util';
269
273
 
270
274
  /**
271
275
  * Datalog query result binding
@@ -343,3 +347,94 @@ export interface WriteConfigArgs {
343
347
  roots?: string[];
344
348
  };
345
349
  }
350
+
351
+ // === Graph traversal tools (REG-521) ===
352
+
353
+ export interface GetNodeArgs {
354
+ semanticId: string;
355
+ }
356
+
357
+ export interface GetNeighborsArgs {
358
+ semanticId: string;
359
+ direction?: 'outgoing' | 'incoming' | 'both';
360
+ edgeTypes?: string[];
361
+ }
362
+
363
+ export interface TraverseGraphArgs {
364
+ startNodeIds: string[];
365
+ edgeTypes: string[];
366
+ maxDepth?: number;
367
+ direction?: 'outgoing' | 'incoming';
368
+ }
369
+
370
+ // === KNOWLEDGE ARGS (REG-626) ===
371
+
372
+ export interface AddKnowledgeArgs {
373
+ type: string;
374
+ content: string;
375
+ slug?: string;
376
+ subtype?: string;
377
+ scope?: string;
378
+ relates_to?: string[];
379
+ projections?: string[];
380
+ status?: string;
381
+ confidence?: string;
382
+ effective_from?: string;
383
+ applies_to?: string[];
384
+ task_id?: string;
385
+ }
386
+
387
+ export interface QueryKnowledgeArgs {
388
+ type?: string;
389
+ projection?: string;
390
+ relates_to?: string;
391
+ text?: string;
392
+ include_dangling_only?: boolean;
393
+ }
394
+
395
+ export interface QueryDecisionsArgs {
396
+ module?: string;
397
+ status?: string;
398
+ }
399
+
400
+ export interface SupersedeFactArgs {
401
+ old_id: string;
402
+ new_content: string;
403
+ new_slug?: string;
404
+ }
405
+
406
+ // === DESCRIBE ARGS (DSL notation) ===
407
+
408
+ export interface DescribeArgs {
409
+ target: string;
410
+ depth?: number;
411
+ perspective?: string;
412
+ }
413
+
414
+ // === GIT QUERY ARGS (REG-628) ===
415
+
416
+ export interface GitChurnArgs {
417
+ limit?: number;
418
+ since?: string;
419
+ }
420
+
421
+ export interface GitCoChangeArgs {
422
+ file: string;
423
+ min_support?: number;
424
+ }
425
+
426
+ export interface GitOwnershipArgs {
427
+ file: string;
428
+ }
429
+
430
+ export interface GitArchaeologyArgs {
431
+ file: string;
432
+ }
433
+
434
+ // === GRAPHQL ARGS (REG-666) ===
435
+
436
+ export interface GraphQLQueryArgs {
437
+ query: string;
438
+ variables?: Record<string, unknown>;
439
+ operationName?: string;
440
+ }
package/src/utils.ts CHANGED
@@ -108,7 +108,7 @@ export function findSimilarTypes(
108
108
 
109
109
  for (const type of availableTypes) {
110
110
  const dist = levenshtein(queriedLower, type.toLowerCase());
111
- if (dist > 0 && dist <= maxDistance) {
111
+ if (dist <= maxDistance && (dist > 0 || queriedType !== type)) {
112
112
  similar.push(type);
113
113
  }
114
114
  }
@@ -116,6 +116,27 @@ export function findSimilarTypes(
116
116
  return similar;
117
117
  }
118
118
 
119
+ export function extractQueriedTypes(query: string): { nodeTypes: string[]; edgeTypes: string[] } {
120
+ const nodeTypes: string[] = [];
121
+ const edgeTypes: string[] = [];
122
+
123
+ // Match node(VAR, "TYPE") and type(VAR, "TYPE") — both are valid node predicates.
124
+ // type() is an alias for node(), added in REG-518.
125
+ const nodeRegex = /\b(?:node|type)\([^,)]+,\s*"([^"]+)"\)/g;
126
+ let m: RegExpExecArray | null;
127
+ while ((m = nodeRegex.exec(query)) !== null) {
128
+ nodeTypes.push(m[1]);
129
+ }
130
+
131
+ // Match edge(SRC, DST, "TYPE") and incoming(DST, SRC, "TYPE")
132
+ const edgeRegex = /\b(?:edge|incoming)\([^,)]+,\s*[^,)]+,\s*"([^"]+)"\)/g;
133
+ while ((m = edgeRegex.exec(query)) !== null) {
134
+ edgeTypes.push(m[1]);
135
+ }
136
+
137
+ return { nodeTypes, edgeTypes };
138
+ }
139
+
119
140
  // Levenshtein distance implementation
120
141
  export function levenshtein(a: string, b: string): number {
121
142
  const m = a.length;