@opencodehub/mcp 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 (210) hide show
  1. package/README.md +62 -0
  2. package/dist/analysis-bridge.d.ts +23 -0
  3. package/dist/analysis-bridge.d.ts.map +1 -0
  4. package/dist/analysis-bridge.js +83 -0
  5. package/dist/analysis-bridge.js.map +1 -0
  6. package/dist/connection-pool.d.ts +76 -0
  7. package/dist/connection-pool.d.ts.map +1 -0
  8. package/dist/connection-pool.js +179 -0
  9. package/dist/connection-pool.js.map +1 -0
  10. package/dist/error-envelope.d.ts +97 -0
  11. package/dist/error-envelope.d.ts.map +1 -0
  12. package/dist/error-envelope.js +75 -0
  13. package/dist/error-envelope.js.map +1 -0
  14. package/dist/group-resolver.d.ts +29 -0
  15. package/dist/group-resolver.d.ts.map +1 -0
  16. package/dist/group-resolver.js +100 -0
  17. package/dist/group-resolver.js.map +1 -0
  18. package/dist/index.d.ts +43 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +54 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/next-step-hints.d.ts +24 -0
  23. package/dist/next-step-hints.d.ts.map +1 -0
  24. package/dist/next-step-hints.js +41 -0
  25. package/dist/next-step-hints.js.map +1 -0
  26. package/dist/repo-resolver.d.ts +88 -0
  27. package/dist/repo-resolver.d.ts.map +1 -0
  28. package/dist/repo-resolver.js +211 -0
  29. package/dist/repo-resolver.js.map +1 -0
  30. package/dist/repo-uri-for-entry.d.ts +25 -0
  31. package/dist/repo-uri-for-entry.d.ts.map +1 -0
  32. package/dist/repo-uri-for-entry.js +64 -0
  33. package/dist/repo-uri-for-entry.js.map +1 -0
  34. package/dist/resources/repo-cluster.d.ts +19 -0
  35. package/dist/resources/repo-cluster.d.ts.map +1 -0
  36. package/dist/resources/repo-cluster.js +203 -0
  37. package/dist/resources/repo-cluster.js.map +1 -0
  38. package/dist/resources/repo-clusters.d.ts +14 -0
  39. package/dist/resources/repo-clusters.d.ts.map +1 -0
  40. package/dist/resources/repo-clusters.js +97 -0
  41. package/dist/resources/repo-clusters.js.map +1 -0
  42. package/dist/resources/repo-context.d.ts +12 -0
  43. package/dist/resources/repo-context.d.ts.map +1 -0
  44. package/dist/resources/repo-context.js +84 -0
  45. package/dist/resources/repo-context.js.map +1 -0
  46. package/dist/resources/repo-process.d.ts +19 -0
  47. package/dist/resources/repo-process.d.ts.map +1 -0
  48. package/dist/resources/repo-process.js +220 -0
  49. package/dist/resources/repo-process.js.map +1 -0
  50. package/dist/resources/repo-processes.d.ts +13 -0
  51. package/dist/resources/repo-processes.d.ts.map +1 -0
  52. package/dist/resources/repo-processes.js +99 -0
  53. package/dist/resources/repo-processes.js.map +1 -0
  54. package/dist/resources/repo-schema.d.ts +13 -0
  55. package/dist/resources/repo-schema.d.ts.map +1 -0
  56. package/dist/resources/repo-schema.js +99 -0
  57. package/dist/resources/repo-schema.js.map +1 -0
  58. package/dist/resources/repos.d.ts +20 -0
  59. package/dist/resources/repos.d.ts.map +1 -0
  60. package/dist/resources/repos.js +58 -0
  61. package/dist/resources/repos.js.map +1 -0
  62. package/dist/resources/store-helper.d.ts +28 -0
  63. package/dist/resources/store-helper.d.ts.map +1 -0
  64. package/dist/resources/store-helper.js +58 -0
  65. package/dist/resources/store-helper.js.map +1 -0
  66. package/dist/resources/yaml.d.ts +10 -0
  67. package/dist/resources/yaml.d.ts.map +1 -0
  68. package/dist/resources/yaml.js +16 -0
  69. package/dist/resources/yaml.js.map +1 -0
  70. package/dist/server.d.ts +46 -0
  71. package/dist/server.d.ts.map +1 -0
  72. package/dist/server.js +194 -0
  73. package/dist/server.js.map +1 -0
  74. package/dist/staleness.d.ts +19 -0
  75. package/dist/staleness.d.ts.map +1 -0
  76. package/dist/staleness.js +40 -0
  77. package/dist/staleness.js.map +1 -0
  78. package/dist/test-utils.d.ts +170 -0
  79. package/dist/test-utils.d.ts.map +1 -0
  80. package/dist/test-utils.js +473 -0
  81. package/dist/test-utils.js.map +1 -0
  82. package/dist/tools/api-impact.d.ts +47 -0
  83. package/dist/tools/api-impact.d.ts.map +1 -0
  84. package/dist/tools/api-impact.js +199 -0
  85. package/dist/tools/api-impact.js.map +1 -0
  86. package/dist/tools/confidence.d.ts +39 -0
  87. package/dist/tools/confidence.d.ts.map +1 -0
  88. package/dist/tools/confidence.js +58 -0
  89. package/dist/tools/confidence.js.map +1 -0
  90. package/dist/tools/context.d.ts +47 -0
  91. package/dist/tools/context.d.ts.map +1 -0
  92. package/dist/tools/context.js +577 -0
  93. package/dist/tools/context.js.map +1 -0
  94. package/dist/tools/dependencies.d.ts +29 -0
  95. package/dist/tools/dependencies.d.ts.map +1 -0
  96. package/dist/tools/dependencies.js +110 -0
  97. package/dist/tools/dependencies.js.map +1 -0
  98. package/dist/tools/detect-changes.d.ts +15 -0
  99. package/dist/tools/detect-changes.d.ts.map +1 -0
  100. package/dist/tools/detect-changes.js +78 -0
  101. package/dist/tools/detect-changes.js.map +1 -0
  102. package/dist/tools/group-contracts.d.ts +26 -0
  103. package/dist/tools/group-contracts.d.ts.map +1 -0
  104. package/dist/tools/group-contracts.js +251 -0
  105. package/dist/tools/group-contracts.js.map +1 -0
  106. package/dist/tools/group-cross-repo-links.d.ts +28 -0
  107. package/dist/tools/group-cross-repo-links.d.ts.map +1 -0
  108. package/dist/tools/group-cross-repo-links.js +128 -0
  109. package/dist/tools/group-cross-repo-links.js.map +1 -0
  110. package/dist/tools/group-list.d.ts +10 -0
  111. package/dist/tools/group-list.d.ts.map +1 -0
  112. package/dist/tools/group-list.js +74 -0
  113. package/dist/tools/group-list.js.map +1 -0
  114. package/dist/tools/group-query.d.ts +40 -0
  115. package/dist/tools/group-query.d.ts.map +1 -0
  116. package/dist/tools/group-query.js +209 -0
  117. package/dist/tools/group-query.js.map +1 -0
  118. package/dist/tools/group-status.d.ts +21 -0
  119. package/dist/tools/group-status.d.ts.map +1 -0
  120. package/dist/tools/group-status.js +121 -0
  121. package/dist/tools/group-status.js.map +1 -0
  122. package/dist/tools/group-sync.d.ts +23 -0
  123. package/dist/tools/group-sync.d.ts.map +1 -0
  124. package/dist/tools/group-sync.js +112 -0
  125. package/dist/tools/group-sync.js.map +1 -0
  126. package/dist/tools/impact.d.ts +36 -0
  127. package/dist/tools/impact.d.ts.map +1 -0
  128. package/dist/tools/impact.js +232 -0
  129. package/dist/tools/impact.js.map +1 -0
  130. package/dist/tools/license-audit.d.ts +34 -0
  131. package/dist/tools/license-audit.d.ts.map +1 -0
  132. package/dist/tools/license-audit.js +108 -0
  133. package/dist/tools/license-audit.js.map +1 -0
  134. package/dist/tools/list-dead-code.d.ts +26 -0
  135. package/dist/tools/list-dead-code.d.ts.map +1 -0
  136. package/dist/tools/list-dead-code.js +110 -0
  137. package/dist/tools/list-dead-code.js.map +1 -0
  138. package/dist/tools/list-findings-delta.d.ts +36 -0
  139. package/dist/tools/list-findings-delta.d.ts.map +1 -0
  140. package/dist/tools/list-findings-delta.js +274 -0
  141. package/dist/tools/list-findings-delta.js.map +1 -0
  142. package/dist/tools/list-findings.d.ts +30 -0
  143. package/dist/tools/list-findings.d.ts.map +1 -0
  144. package/dist/tools/list-findings.js +129 -0
  145. package/dist/tools/list-findings.js.map +1 -0
  146. package/dist/tools/list-repos.d.ts +17 -0
  147. package/dist/tools/list-repos.d.ts.map +1 -0
  148. package/dist/tools/list-repos.js +63 -0
  149. package/dist/tools/list-repos.js.map +1 -0
  150. package/dist/tools/owners.d.ts +23 -0
  151. package/dist/tools/owners.d.ts.map +1 -0
  152. package/dist/tools/owners.js +103 -0
  153. package/dist/tools/owners.js.map +1 -0
  154. package/dist/tools/pack-codebase.d.ts +76 -0
  155. package/dist/tools/pack-codebase.d.ts.map +1 -0
  156. package/dist/tools/pack-codebase.js +289 -0
  157. package/dist/tools/pack-codebase.js.map +1 -0
  158. package/dist/tools/project-profile.d.ts +28 -0
  159. package/dist/tools/project-profile.d.ts.map +1 -0
  160. package/dist/tools/project-profile.js +109 -0
  161. package/dist/tools/project-profile.js.map +1 -0
  162. package/dist/tools/query.d.ts +63 -0
  163. package/dist/tools/query.d.ts.map +1 -0
  164. package/dist/tools/query.js +662 -0
  165. package/dist/tools/query.js.map +1 -0
  166. package/dist/tools/remove-dead-code.d.ts +47 -0
  167. package/dist/tools/remove-dead-code.d.ts.map +1 -0
  168. package/dist/tools/remove-dead-code.js +258 -0
  169. package/dist/tools/remove-dead-code.js.map +1 -0
  170. package/dist/tools/rename.d.ts +21 -0
  171. package/dist/tools/rename.d.ts.map +1 -0
  172. package/dist/tools/rename.js +116 -0
  173. package/dist/tools/rename.js.map +1 -0
  174. package/dist/tools/risk-trends.d.ts +19 -0
  175. package/dist/tools/risk-trends.d.ts.map +1 -0
  176. package/dist/tools/risk-trends.js +73 -0
  177. package/dist/tools/risk-trends.js.map +1 -0
  178. package/dist/tools/route-map.d.ts +27 -0
  179. package/dist/tools/route-map.d.ts.map +1 -0
  180. package/dist/tools/route-map.js +119 -0
  181. package/dist/tools/route-map.js.map +1 -0
  182. package/dist/tools/scan.d.ts +27 -0
  183. package/dist/tools/scan.d.ts.map +1 -0
  184. package/dist/tools/scan.js +136 -0
  185. package/dist/tools/scan.js.map +1 -0
  186. package/dist/tools/shape-check.d.ts +53 -0
  187. package/dist/tools/shape-check.d.ts.map +1 -0
  188. package/dist/tools/shape-check.js +161 -0
  189. package/dist/tools/shape-check.js.map +1 -0
  190. package/dist/tools/shared.d.ts +101 -0
  191. package/dist/tools/shared.d.ts.map +1 -0
  192. package/dist/tools/shared.js +114 -0
  193. package/dist/tools/shared.js.map +1 -0
  194. package/dist/tools/signature.d.ts +38 -0
  195. package/dist/tools/signature.d.ts.map +1 -0
  196. package/dist/tools/signature.js +332 -0
  197. package/dist/tools/signature.js.map +1 -0
  198. package/dist/tools/sql.d.ts +34 -0
  199. package/dist/tools/sql.d.ts.map +1 -0
  200. package/dist/tools/sql.js +222 -0
  201. package/dist/tools/sql.js.map +1 -0
  202. package/dist/tools/tool-map.d.ts +24 -0
  203. package/dist/tools/tool-map.d.ts.map +1 -0
  204. package/dist/tools/tool-map.js +97 -0
  205. package/dist/tools/tool-map.js.map +1 -0
  206. package/dist/tools/verdict.d.ts +33 -0
  207. package/dist/tools/verdict.d.ts.map +1 -0
  208. package/dist/tools/verdict.js +102 -0
  209. package/dist/tools/verdict.js.map +1 -0
  210. package/package.json +76 -0
@@ -0,0 +1,473 @@
1
+ // biome-ignore-all lint/complexity/useLiteralKeys: dot-access disallowed on Record index signatures
2
+ /**
3
+ * Shared MCP test fixtures.
4
+ *
5
+ * The production tools/resources call typed finders on `IGraphStore`
6
+ * (`listNodes`, `listNodesByKind`, `listEdges`,
7
+ * `listEdgesByType`, `listFindings`, `listRoutes`, `getRepoNode`,
8
+ * `traverseAncestors`, `listEmbeddingHashes`, etc.) rather than raw
9
+ * `query(<sql>)`. This file gives every mcp test a small, composable
10
+ * in-memory backing store so each test only needs to seed the data it
11
+ * cares about — nodes, edges, findings, routes — and supply
12
+ * test-specific overrides as needed.
13
+ *
14
+ * The module is intentionally tolerant: every typed finder has a sane
15
+ * default that filters the seeded arrays exactly the way the real
16
+ * `DuckDbStore` does. Tests can override a single finder via the
17
+ * `overrides` parameter when they need bespoke behaviour (e.g. cochanges,
18
+ * BM25 search, traversal).
19
+ */
20
+ import { strict as assert } from "node:assert";
21
+ import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
22
+ import { tmpdir } from "node:os";
23
+ import { resolve } from "node:path";
24
+ import { ConnectionPool } from "./connection-pool.js";
25
+ // ─────────────────────────────────────────────────────────────────────────────
26
+ // Store wrapper — composes the IGraphStore-shaped fake into the OpenStoreResult
27
+ // shape the connection pool returns.
28
+ // ─────────────────────────────────────────────────────────────────────────────
29
+ /**
30
+ * Wrap an in-memory IGraphStore-shaped fake as the composed `Store`
31
+ * (`OpenStoreResult`) that the connection pool returns. The same
32
+ * instance backs both `graph` and `temporal` because DuckDbStore
33
+ * implements both interfaces over a single connection in production.
34
+ */
35
+ export function wrapAsStore(fake) {
36
+ return {
37
+ backend: "duck",
38
+ graph: fake,
39
+ temporal: fake,
40
+ graphFile: "/in-memory/graph.duckdb",
41
+ temporalFile: "/in-memory/graph.duckdb",
42
+ close: async () => {
43
+ const closer = fake.close;
44
+ if (typeof closer === "function")
45
+ await closer.call(fake);
46
+ },
47
+ };
48
+ }
49
+ // ─────────────────────────────────────────────────────────────────────────────
50
+ // Node / edge field readers — be permissive about which casing the seed uses.
51
+ // ─────────────────────────────────────────────────────────────────────────────
52
+ function nodeFilePath(n) {
53
+ if (typeof n.filePath === "string")
54
+ return n.filePath;
55
+ if (typeof n.file_path === "string")
56
+ return n.file_path;
57
+ return "";
58
+ }
59
+ function nodeName(n) {
60
+ if (typeof n.name === "string")
61
+ return n.name;
62
+ return "";
63
+ }
64
+ function edgeFromId(e) {
65
+ return String(e.from ?? e.fromId ?? e.from_id ?? "");
66
+ }
67
+ function edgeToId(e) {
68
+ return String(e.to ?? e.toId ?? e.to_id ?? "");
69
+ }
70
+ /**
71
+ * Project a fake node into the GraphNode shape the production code expects.
72
+ * The fake seeds carry both casings (`filePath` / `file_path`,
73
+ * `start_line` / `startLine`); production reads the camelCase fields, so
74
+ * we map snake_case → camelCase here.
75
+ */
76
+ function projectNode(n) {
77
+ const out = { ...n };
78
+ if (out["filePath"] === undefined && typeof n["file_path"] === "string") {
79
+ out["filePath"] = n["file_path"];
80
+ }
81
+ if (out["startLine"] === undefined && n["start_line"] !== undefined) {
82
+ out["startLine"] = n["start_line"];
83
+ }
84
+ if (out["endLine"] === undefined && n["end_line"] !== undefined) {
85
+ out["endLine"] = n["end_line"];
86
+ }
87
+ if (out["isExported"] === undefined && n["is_exported"] !== undefined) {
88
+ out["isExported"] = n["is_exported"];
89
+ }
90
+ if (out["responseKeys"] === undefined && n["response_keys"] !== undefined) {
91
+ out["responseKeys"] = n["response_keys"];
92
+ }
93
+ if (out["httpMethod"] === undefined && n["http_method"] !== undefined) {
94
+ out["httpMethod"] = n["http_method"];
95
+ }
96
+ if (out["httpPath"] === undefined && n["http_path"] !== undefined) {
97
+ out["httpPath"] = n["http_path"];
98
+ }
99
+ if (out["entryPointId"] === undefined && n["entry_point_id"] !== undefined) {
100
+ out["entryPointId"] = n["entry_point_id"];
101
+ }
102
+ if (out["repoUri"] === undefined && n["repo_uri"] !== undefined) {
103
+ out["repoUri"] = n["repo_uri"];
104
+ }
105
+ if (out["inferredLabel"] === undefined && n["inferred_label"] !== undefined) {
106
+ out["inferredLabel"] = n["inferred_label"];
107
+ }
108
+ if (out["parameterCount"] === undefined && n["parameter_count"] !== undefined) {
109
+ out["parameterCount"] = n["parameter_count"];
110
+ }
111
+ if (out["returnType"] === undefined && n["return_type"] !== undefined) {
112
+ out["returnType"] = n["return_type"];
113
+ }
114
+ if (out["stepCount"] === undefined && n["step_count"] !== undefined) {
115
+ out["stepCount"] = n["step_count"];
116
+ }
117
+ if (out["symbolCount"] === undefined && n["symbol_count"] !== undefined) {
118
+ out["symbolCount"] = n["symbol_count"];
119
+ }
120
+ if (out["emailHash"] === undefined && n["email_hash"] !== undefined) {
121
+ out["emailHash"] = n["email_hash"];
122
+ }
123
+ if (out["emailPlain"] === undefined && n["email_plain"] !== undefined) {
124
+ out["emailPlain"] = n["email_plain"];
125
+ }
126
+ if (out["operationId"] === undefined && n["operation_id"] !== undefined) {
127
+ out["operationId"] = n["operation_id"];
128
+ }
129
+ return out;
130
+ }
131
+ function projectEdge(e) {
132
+ const fromId = edgeFromId(e);
133
+ const toId = edgeToId(e);
134
+ return {
135
+ id: typeof e["id"] === "string" ? e["id"] : `${fromId}->${e.type}->${toId}`,
136
+ from: fromId,
137
+ to: toId,
138
+ type: e.type,
139
+ confidence: typeof e.confidence === "number" ? e.confidence : 1,
140
+ ...(typeof e.reason === "string" ? { reason: e.reason } : {}),
141
+ ...(typeof e.step === "number" ? { step: e.step } : {}),
142
+ };
143
+ }
144
+ function applyLikeFilter(value, pattern) {
145
+ // Storage adapters wrap LIKE queries with `%x%`; here we just check
146
+ // substring containment after stripping the wildcard markers.
147
+ const trimmed = pattern.replace(/^%+|%+$/g, "");
148
+ if (trimmed.length === 0)
149
+ return true;
150
+ return value.includes(trimmed);
151
+ }
152
+ // ─────────────────────────────────────────────────────────────────────────────
153
+ // makeFakeGraphStore — the typed-finder-shaped DuckDbStore fake.
154
+ // ─────────────────────────────────────────────────────────────────────────────
155
+ export function makeFakeGraphStore(data = {}, overrides = {}) {
156
+ const nodes = data.nodes ?? [];
157
+ const edges = data.edges ?? [];
158
+ const findings = data.findings ?? [];
159
+ const routes = data.routes ?? [];
160
+ const dependencies = data.dependencies ?? [];
161
+ const repoNodes = data.repoNodes ?? [];
162
+ const filterNodes = (opts = {}) => {
163
+ if (opts.kinds !== undefined && opts.kinds.length === 0)
164
+ return [];
165
+ if (opts.ids !== undefined && opts.ids.length === 0)
166
+ return [];
167
+ const kindSet = opts.kinds !== undefined ? new Set(opts.kinds) : undefined;
168
+ const idSet = opts.ids !== undefined ? new Set(opts.ids) : undefined;
169
+ let out = nodes.filter((n) => {
170
+ if (kindSet !== undefined && !kindSet.has(n.kind))
171
+ return false;
172
+ if (idSet !== undefined && !idSet.has(n.id))
173
+ return false;
174
+ if (opts.filePath !== undefined && nodeFilePath(n) !== opts.filePath)
175
+ return false;
176
+ return true;
177
+ });
178
+ out = [...out].sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0));
179
+ if (opts.offset !== undefined && Number.isFinite(opts.offset) && opts.offset > 0) {
180
+ out = out.slice(Math.trunc(opts.offset));
181
+ }
182
+ if (opts.limit !== undefined && Number.isFinite(opts.limit) && opts.limit > 0) {
183
+ out = out.slice(0, Math.trunc(opts.limit));
184
+ }
185
+ return out.map(projectNode);
186
+ };
187
+ const filterEdges = (opts = {}) => {
188
+ const types = opts.types !== undefined ? new Set(opts.types) : undefined;
189
+ const fromIds = opts.fromIds !== undefined ? new Set(opts.fromIds) : undefined;
190
+ const toIds = opts.toIds !== undefined ? new Set(opts.toIds) : undefined;
191
+ let out = edges.filter((e) => {
192
+ if (types !== undefined && !types.has(e.type))
193
+ return false;
194
+ if (fromIds !== undefined && !fromIds.has(edgeFromId(e)))
195
+ return false;
196
+ if (toIds !== undefined && !toIds.has(edgeToId(e)))
197
+ return false;
198
+ if (opts.minConfidence !== undefined &&
199
+ Number.isFinite(opts.minConfidence) &&
200
+ typeof e.confidence === "number" &&
201
+ e.confidence < opts.minConfidence) {
202
+ return false;
203
+ }
204
+ return true;
205
+ });
206
+ out = [...out].sort((a, b) => {
207
+ const af = edgeFromId(a);
208
+ const bf = edgeFromId(b);
209
+ if (af !== bf)
210
+ return af < bf ? -1 : 1;
211
+ const at = edgeToId(a);
212
+ const bt = edgeToId(b);
213
+ if (at !== bt)
214
+ return at < bt ? -1 : 1;
215
+ if (a.type !== b.type)
216
+ return a.type < b.type ? -1 : 1;
217
+ return 0;
218
+ });
219
+ if (opts.offset !== undefined && Number.isFinite(opts.offset) && opts.offset > 0) {
220
+ out = out.slice(Math.trunc(opts.offset));
221
+ }
222
+ if (opts.limit !== undefined && Number.isFinite(opts.limit) && opts.limit > 0) {
223
+ out = out.slice(0, Math.trunc(opts.limit));
224
+ }
225
+ return out.map(projectEdge);
226
+ };
227
+ const filterEdgesByType = (type, opts = {}) => {
228
+ const merged = { types: [type] };
229
+ if (opts.fromIds !== undefined) {
230
+ Object.assign(merged, { fromIds: opts.fromIds });
231
+ }
232
+ if (opts.toIds !== undefined) {
233
+ Object.assign(merged, { toIds: opts.toIds });
234
+ }
235
+ if (opts.minConfidence !== undefined) {
236
+ Object.assign(merged, { minConfidence: opts.minConfidence });
237
+ }
238
+ if (opts.limit !== undefined) {
239
+ Object.assign(merged, { limit: opts.limit });
240
+ }
241
+ return filterEdges(merged);
242
+ };
243
+ const filterFindings = (opts = {}) => {
244
+ const sevSet = opts.severity !== undefined ? new Set(opts.severity) : undefined;
245
+ const baselineSet = opts.baselineState !== undefined ? new Set(opts.baselineState) : undefined;
246
+ let out = findings.filter((f) => {
247
+ if (sevSet !== undefined && !sevSet.has(f.severity))
248
+ return false;
249
+ if (opts.ruleId !== undefined && f.ruleId !== opts.ruleId)
250
+ return false;
251
+ if (baselineSet !== undefined) {
252
+ const b = f.baselineState;
253
+ if (b === undefined || !baselineSet.has(b))
254
+ return false;
255
+ }
256
+ if (opts.suppressed !== undefined) {
257
+ const isSuppressed = typeof f.suppressedJson === "string" && f.suppressedJson.length > 0;
258
+ if (opts.suppressed !== isSuppressed)
259
+ return false;
260
+ }
261
+ return true;
262
+ });
263
+ if (opts.limit !== undefined && Number.isFinite(opts.limit) && opts.limit > 0) {
264
+ out = out.slice(0, Math.trunc(opts.limit));
265
+ }
266
+ return out.map((f) => f);
267
+ };
268
+ const filterRoutes = (opts = {}) => {
269
+ const methodSet = opts.methods !== undefined ? new Set(opts.methods) : undefined;
270
+ let out = routes.filter((r) => {
271
+ if (methodSet !== undefined) {
272
+ const m = r.httpMethod ?? r.method;
273
+ if (m === undefined || !methodSet.has(m))
274
+ return false;
275
+ }
276
+ if (opts.pathLike !== undefined) {
277
+ const url = r.url ??
278
+ r.httpPath ??
279
+ r.path ??
280
+ "";
281
+ if (!applyLikeFilter(url, opts.pathLike))
282
+ return false;
283
+ }
284
+ return true;
285
+ });
286
+ if (opts.limit !== undefined && Number.isFinite(opts.limit) && opts.limit > 0) {
287
+ out = out.slice(0, Math.trunc(opts.limit));
288
+ }
289
+ return out.map((r) => r);
290
+ };
291
+ const filterDependencies = (opts = {}) => {
292
+ const ecoMatch = opts.ecosystem;
293
+ const tierSet = opts.licenseTier !== undefined ? new Set(opts.licenseTier) : undefined;
294
+ let out = dependencies.filter((d) => {
295
+ if (ecoMatch !== undefined && d.ecosystem !== ecoMatch)
296
+ return false;
297
+ if (tierSet !== undefined) {
298
+ const tier = d.licenseTier;
299
+ if (tier === undefined || !tierSet.has(tier))
300
+ return false;
301
+ }
302
+ return true;
303
+ });
304
+ if (opts.limit !== undefined && Number.isFinite(opts.limit) && opts.limit > 0) {
305
+ out = out.slice(0, Math.trunc(opts.limit));
306
+ }
307
+ return out.map((d) => d);
308
+ };
309
+ const defaults = {
310
+ dialect: "none",
311
+ open: async () => { },
312
+ close: async () => { },
313
+ createSchema: async () => { },
314
+ bulkLoad: async (_g) => ({
315
+ nodeCount: 0,
316
+ edgeCount: 0,
317
+ durationMs: 0,
318
+ }),
319
+ upsertEmbeddings: async (_r) => { },
320
+ listEmbeddingHashes: async () => new Map(data.embeddingHashes ?? []),
321
+ listEmbeddings: async function* () {
322
+ // No-op default. Tests that need this must override.
323
+ },
324
+ listNodes: async (opts = {}) => filterNodes(opts),
325
+ listNodesByKind: async (kind, opts = {}) => {
326
+ let out = nodes.filter((n) => n.kind === kind);
327
+ if (opts.filePath !== undefined) {
328
+ out = out.filter((n) => nodeFilePath(n) === opts.filePath);
329
+ }
330
+ if (opts.filePathLike !== undefined) {
331
+ out = out.filter((n) => applyLikeFilter(nodeFilePath(n), opts.filePathLike ?? ""));
332
+ }
333
+ out = [...out].sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0));
334
+ if (opts.offset !== undefined && Number.isFinite(opts.offset) && opts.offset > 0) {
335
+ out = out.slice(Math.trunc(opts.offset));
336
+ }
337
+ if (opts.limit !== undefined && Number.isFinite(opts.limit) && opts.limit > 0) {
338
+ out = out.slice(0, Math.trunc(opts.limit));
339
+ }
340
+ return out.map(projectNode);
341
+ },
342
+ listEdges: async (opts = {}) => filterEdges(opts),
343
+ listEdgesByType: async (type, opts = {}) => filterEdgesByType(type, opts),
344
+ listFindings: async (opts = {}) => filterFindings(opts),
345
+ listDependencies: async (opts = {}) => filterDependencies(opts),
346
+ listRoutes: async (opts = {}) => filterRoutes(opts),
347
+ getRepoNode: async (id) => {
348
+ const hit = repoNodes.find((r) => r.id === id);
349
+ return hit ? hit : undefined;
350
+ },
351
+ listNodesByEntryPoint: async (entryPointId) => {
352
+ const hits = nodes.filter((n) => n.entryPointId === entryPointId ||
353
+ n.entry_point_id === entryPointId);
354
+ return [...hits].sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0)).map(projectNode);
355
+ },
356
+ listNodesByName: async (name, opts = {}) => {
357
+ const kindSet = opts.kinds !== undefined ? new Set(opts.kinds) : undefined;
358
+ let out = nodes.filter((n) => {
359
+ if (nodeName(n) !== name)
360
+ return false;
361
+ if (kindSet !== undefined && !kindSet.has(n.kind))
362
+ return false;
363
+ if (opts.filePath !== undefined && nodeFilePath(n) !== opts.filePath)
364
+ return false;
365
+ return true;
366
+ });
367
+ out = [...out].sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0));
368
+ if (opts.limit !== undefined && Number.isFinite(opts.limit) && opts.limit > 0) {
369
+ out = out.slice(0, Math.trunc(opts.limit));
370
+ }
371
+ return out.map(projectNode);
372
+ },
373
+ countNodesByKind: async (kinds) => {
374
+ const out = new Map();
375
+ const allow = kinds !== undefined ? new Set(kinds) : undefined;
376
+ for (const n of nodes) {
377
+ if (allow !== undefined && !allow.has(n.kind))
378
+ continue;
379
+ const k = n.kind;
380
+ out.set(k, (out.get(k) ?? 0) + 1);
381
+ }
382
+ return out;
383
+ },
384
+ countEdgesByType: async (types) => {
385
+ const out = new Map();
386
+ const allow = types !== undefined ? new Set(types) : undefined;
387
+ for (const e of edges) {
388
+ if (allow !== undefined && !allow.has(e.type))
389
+ continue;
390
+ const t = e.type;
391
+ out.set(t, (out.get(t) ?? 0) + 1);
392
+ }
393
+ return out;
394
+ },
395
+ search: async (_q) => [],
396
+ vectorSearch: async (_q) => [],
397
+ traverse: async (_q) => [],
398
+ traverseAncestors: async (_opts) => [],
399
+ traverseDescendants: async (_opts) => [],
400
+ listConsumerProducerEdges: async () => [],
401
+ getMeta: async () => undefined,
402
+ setMeta: async (_m) => { },
403
+ healthCheck: async () => ({ ok: true }),
404
+ // ITemporalStore surfaces commonly stubbed.
405
+ bulkLoadCochanges: async (_rows) => { },
406
+ lookupCochangesForFile: async () => [],
407
+ lookupCochangesBetween: async () => undefined,
408
+ bulkLoadSymbolSummaries: async (_rows) => { },
409
+ lookupSymbolSummary: async () => undefined,
410
+ lookupSymbolSummariesByNode: async () => [],
411
+ exec: async () => [],
412
+ };
413
+ // Apply test-supplied overrides verbatim — they win over defaults.
414
+ const overrideEntries = Object.entries(overrides).filter(([, v]) => v !== undefined);
415
+ for (const [key, value] of overrideEntries) {
416
+ defaults[key] = value;
417
+ }
418
+ return defaults;
419
+ }
420
+ /**
421
+ * Spin up a temp `home/.codehub/registry.json`, a `ConnectionPool` whose
422
+ * factory returns the supplied fake store, and a fresh `McpServer`. Hands
423
+ * everything back to the caller's `fn` and tears down on exit.
424
+ */
425
+ export async function withMcpHarness(opts, fn) {
426
+ const { McpServer } = await import("@modelcontextprotocol/sdk/server/mcp.js");
427
+ const home = await mkdtemp(resolve(tmpdir(), opts.tmpPrefix ?? "codehub-mcp-test-"));
428
+ try {
429
+ const repoName = opts.repoName ?? "fakerepo";
430
+ const repoPath = resolve(home, repoName);
431
+ await mkdir(repoPath, { recursive: true });
432
+ const regDir = resolve(home, ".codehub");
433
+ await mkdir(regDir, { recursive: true });
434
+ const defaultRegistry = {
435
+ [repoName]: {
436
+ name: repoName,
437
+ path: repoPath,
438
+ indexedAt: "2026-04-18T00:00:00Z",
439
+ nodeCount: 0,
440
+ edgeCount: 0,
441
+ lastCommit: "abc123",
442
+ },
443
+ };
444
+ const registry = opts.registry ?? defaultRegistry;
445
+ await writeFile(resolve(regDir, "registry.json"), JSON.stringify(registry));
446
+ const pool = new ConnectionPool({ max: 4, ttlMs: 60_000 }, async () => wrapAsStore(await opts.storeFactory()));
447
+ const server = new McpServer({ name: "test", version: "0.0.0" }, { capabilities: opts.serverCapabilities ?? { tools: {} } });
448
+ try {
449
+ await fn({ home, pool, server, repoPath, repoName });
450
+ }
451
+ finally {
452
+ await pool.shutdown();
453
+ }
454
+ }
455
+ finally {
456
+ await rm(home, { recursive: true, force: true });
457
+ }
458
+ }
459
+ export function getToolHandler(server, name) {
460
+ // biome-ignore lint/suspicious/noExplicitAny: SDK internal field for test-only access
461
+ const map = server._registeredTools;
462
+ const entry = map[name];
463
+ assert.ok(entry, `tool not registered: ${name}`);
464
+ return entry.handler.bind(entry);
465
+ }
466
+ export function getResourceHandler(server, name) {
467
+ // biome-ignore lint/suspicious/noExplicitAny: SDK internal field for test-only access
468
+ const map = server._registeredResourceTemplates;
469
+ const entry = map[name];
470
+ assert.ok(entry, `resource template not registered: ${name}`);
471
+ return entry.readCallback.bind(entry);
472
+ }
473
+ //# sourceMappingURL=test-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-utils.js","sourceRoot":"","sources":["../src/test-utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * `api_impact` — score the blast radius of changing a Route's contract.
3
+ *
4
+ * For every Route matching the filter (`route` substring, or `file`
5
+ * substring against Route.filePath) we compute:
6
+ * - consumers = files with outgoing FETCHES → this Route.
7
+ * - middleware = handlers reached via HANDLES_ROUTE (typically
8
+ * File ids; Operation ids when the OpenAPI
9
+ * phase linked a spec).
10
+ * - mismatches = consumer files whose accessed keys are not a
11
+ * subset of Route.responseKeys (delegated to
12
+ * `classifyShape` from shape-check).
13
+ * - affectedProcesses = Process nodes whose PROCESS_STEP edges walk
14
+ * through any of the consumer symbols.
15
+ *
16
+ * Risk banding (deterministic):
17
+ * LOW — 0 consumers and 0 mismatches.
18
+ * MEDIUM — 1-4 consumers, 0 mismatches.
19
+ * HIGH — 5-19 consumers OR any mismatch.
20
+ * CRITICAL — ≥ 20 consumers.
21
+ */
22
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
23
+ import { type ToolContext, type ToolResult } from "./shared.js";
24
+ export type Risk = "LOW" | "MEDIUM" | "HIGH" | "CRITICAL";
25
+ export interface ApiImpactRow {
26
+ readonly route: {
27
+ readonly id: string;
28
+ readonly url: string;
29
+ readonly method: string;
30
+ readonly filePath: string;
31
+ };
32
+ readonly risk: Risk;
33
+ readonly consumers: readonly string[];
34
+ readonly middleware: readonly string[];
35
+ readonly mismatches: readonly string[];
36
+ readonly affectedProcesses: readonly string[];
37
+ }
38
+ interface ApiImpactArgs {
39
+ readonly repo?: string | undefined;
40
+ readonly repo_uri?: string | undefined;
41
+ readonly route?: string | undefined;
42
+ readonly file?: string | undefined;
43
+ }
44
+ export declare function runApiImpact(ctx: ToolContext, args: ApiImpactArgs): Promise<ToolResult>;
45
+ export declare function registerApiImpactTool(server: McpServer, ctx: ToolContext): void;
46
+ export {};
47
+ //# sourceMappingURL=api-impact.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-impact.d.ts","sourceRoot":"","sources":["../../src/tools/api-impact.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAQzE,OAAO,EAGL,KAAK,WAAW,EAChB,KAAK,UAAU,EAGhB,MAAM,aAAa,CAAC;AAQrB,MAAM,MAAM,IAAI,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;AAE1D,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE;QACd,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;KAC3B,CAAC;IACF,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/C;AAED,UAAU,aAAa;IACrB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACpC;AAED,wBAAsB,YAAY,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,UAAU,CAAC,CA2C7F;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,GAAG,IAAI,CAiB/E"}