@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.
- package/README.md +62 -0
- package/dist/analysis-bridge.d.ts +23 -0
- package/dist/analysis-bridge.d.ts.map +1 -0
- package/dist/analysis-bridge.js +83 -0
- package/dist/analysis-bridge.js.map +1 -0
- package/dist/connection-pool.d.ts +76 -0
- package/dist/connection-pool.d.ts.map +1 -0
- package/dist/connection-pool.js +179 -0
- package/dist/connection-pool.js.map +1 -0
- package/dist/error-envelope.d.ts +97 -0
- package/dist/error-envelope.d.ts.map +1 -0
- package/dist/error-envelope.js +75 -0
- package/dist/error-envelope.js.map +1 -0
- package/dist/group-resolver.d.ts +29 -0
- package/dist/group-resolver.d.ts.map +1 -0
- package/dist/group-resolver.js +100 -0
- package/dist/group-resolver.js.map +1 -0
- package/dist/index.d.ts +43 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +54 -0
- package/dist/index.js.map +1 -0
- package/dist/next-step-hints.d.ts +24 -0
- package/dist/next-step-hints.d.ts.map +1 -0
- package/dist/next-step-hints.js +41 -0
- package/dist/next-step-hints.js.map +1 -0
- package/dist/repo-resolver.d.ts +88 -0
- package/dist/repo-resolver.d.ts.map +1 -0
- package/dist/repo-resolver.js +211 -0
- package/dist/repo-resolver.js.map +1 -0
- package/dist/repo-uri-for-entry.d.ts +25 -0
- package/dist/repo-uri-for-entry.d.ts.map +1 -0
- package/dist/repo-uri-for-entry.js +64 -0
- package/dist/repo-uri-for-entry.js.map +1 -0
- package/dist/resources/repo-cluster.d.ts +19 -0
- package/dist/resources/repo-cluster.d.ts.map +1 -0
- package/dist/resources/repo-cluster.js +203 -0
- package/dist/resources/repo-cluster.js.map +1 -0
- package/dist/resources/repo-clusters.d.ts +14 -0
- package/dist/resources/repo-clusters.d.ts.map +1 -0
- package/dist/resources/repo-clusters.js +97 -0
- package/dist/resources/repo-clusters.js.map +1 -0
- package/dist/resources/repo-context.d.ts +12 -0
- package/dist/resources/repo-context.d.ts.map +1 -0
- package/dist/resources/repo-context.js +84 -0
- package/dist/resources/repo-context.js.map +1 -0
- package/dist/resources/repo-process.d.ts +19 -0
- package/dist/resources/repo-process.d.ts.map +1 -0
- package/dist/resources/repo-process.js +220 -0
- package/dist/resources/repo-process.js.map +1 -0
- package/dist/resources/repo-processes.d.ts +13 -0
- package/dist/resources/repo-processes.d.ts.map +1 -0
- package/dist/resources/repo-processes.js +99 -0
- package/dist/resources/repo-processes.js.map +1 -0
- package/dist/resources/repo-schema.d.ts +13 -0
- package/dist/resources/repo-schema.d.ts.map +1 -0
- package/dist/resources/repo-schema.js +99 -0
- package/dist/resources/repo-schema.js.map +1 -0
- package/dist/resources/repos.d.ts +20 -0
- package/dist/resources/repos.d.ts.map +1 -0
- package/dist/resources/repos.js +58 -0
- package/dist/resources/repos.js.map +1 -0
- package/dist/resources/store-helper.d.ts +28 -0
- package/dist/resources/store-helper.d.ts.map +1 -0
- package/dist/resources/store-helper.js +58 -0
- package/dist/resources/store-helper.js.map +1 -0
- package/dist/resources/yaml.d.ts +10 -0
- package/dist/resources/yaml.d.ts.map +1 -0
- package/dist/resources/yaml.js +16 -0
- package/dist/resources/yaml.js.map +1 -0
- package/dist/server.d.ts +46 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +194 -0
- package/dist/server.js.map +1 -0
- package/dist/staleness.d.ts +19 -0
- package/dist/staleness.d.ts.map +1 -0
- package/dist/staleness.js +40 -0
- package/dist/staleness.js.map +1 -0
- package/dist/test-utils.d.ts +170 -0
- package/dist/test-utils.d.ts.map +1 -0
- package/dist/test-utils.js +473 -0
- package/dist/test-utils.js.map +1 -0
- package/dist/tools/api-impact.d.ts +47 -0
- package/dist/tools/api-impact.d.ts.map +1 -0
- package/dist/tools/api-impact.js +199 -0
- package/dist/tools/api-impact.js.map +1 -0
- package/dist/tools/confidence.d.ts +39 -0
- package/dist/tools/confidence.d.ts.map +1 -0
- package/dist/tools/confidence.js +58 -0
- package/dist/tools/confidence.js.map +1 -0
- package/dist/tools/context.d.ts +47 -0
- package/dist/tools/context.d.ts.map +1 -0
- package/dist/tools/context.js +577 -0
- package/dist/tools/context.js.map +1 -0
- package/dist/tools/dependencies.d.ts +29 -0
- package/dist/tools/dependencies.d.ts.map +1 -0
- package/dist/tools/dependencies.js +110 -0
- package/dist/tools/dependencies.js.map +1 -0
- package/dist/tools/detect-changes.d.ts +15 -0
- package/dist/tools/detect-changes.d.ts.map +1 -0
- package/dist/tools/detect-changes.js +78 -0
- package/dist/tools/detect-changes.js.map +1 -0
- package/dist/tools/group-contracts.d.ts +26 -0
- package/dist/tools/group-contracts.d.ts.map +1 -0
- package/dist/tools/group-contracts.js +251 -0
- package/dist/tools/group-contracts.js.map +1 -0
- package/dist/tools/group-cross-repo-links.d.ts +28 -0
- package/dist/tools/group-cross-repo-links.d.ts.map +1 -0
- package/dist/tools/group-cross-repo-links.js +128 -0
- package/dist/tools/group-cross-repo-links.js.map +1 -0
- package/dist/tools/group-list.d.ts +10 -0
- package/dist/tools/group-list.d.ts.map +1 -0
- package/dist/tools/group-list.js +74 -0
- package/dist/tools/group-list.js.map +1 -0
- package/dist/tools/group-query.d.ts +40 -0
- package/dist/tools/group-query.d.ts.map +1 -0
- package/dist/tools/group-query.js +209 -0
- package/dist/tools/group-query.js.map +1 -0
- package/dist/tools/group-status.d.ts +21 -0
- package/dist/tools/group-status.d.ts.map +1 -0
- package/dist/tools/group-status.js +121 -0
- package/dist/tools/group-status.js.map +1 -0
- package/dist/tools/group-sync.d.ts +23 -0
- package/dist/tools/group-sync.d.ts.map +1 -0
- package/dist/tools/group-sync.js +112 -0
- package/dist/tools/group-sync.js.map +1 -0
- package/dist/tools/impact.d.ts +36 -0
- package/dist/tools/impact.d.ts.map +1 -0
- package/dist/tools/impact.js +232 -0
- package/dist/tools/impact.js.map +1 -0
- package/dist/tools/license-audit.d.ts +34 -0
- package/dist/tools/license-audit.d.ts.map +1 -0
- package/dist/tools/license-audit.js +108 -0
- package/dist/tools/license-audit.js.map +1 -0
- package/dist/tools/list-dead-code.d.ts +26 -0
- package/dist/tools/list-dead-code.d.ts.map +1 -0
- package/dist/tools/list-dead-code.js +110 -0
- package/dist/tools/list-dead-code.js.map +1 -0
- package/dist/tools/list-findings-delta.d.ts +36 -0
- package/dist/tools/list-findings-delta.d.ts.map +1 -0
- package/dist/tools/list-findings-delta.js +274 -0
- package/dist/tools/list-findings-delta.js.map +1 -0
- package/dist/tools/list-findings.d.ts +30 -0
- package/dist/tools/list-findings.d.ts.map +1 -0
- package/dist/tools/list-findings.js +129 -0
- package/dist/tools/list-findings.js.map +1 -0
- package/dist/tools/list-repos.d.ts +17 -0
- package/dist/tools/list-repos.d.ts.map +1 -0
- package/dist/tools/list-repos.js +63 -0
- package/dist/tools/list-repos.js.map +1 -0
- package/dist/tools/owners.d.ts +23 -0
- package/dist/tools/owners.d.ts.map +1 -0
- package/dist/tools/owners.js +103 -0
- package/dist/tools/owners.js.map +1 -0
- package/dist/tools/pack-codebase.d.ts +76 -0
- package/dist/tools/pack-codebase.d.ts.map +1 -0
- package/dist/tools/pack-codebase.js +289 -0
- package/dist/tools/pack-codebase.js.map +1 -0
- package/dist/tools/project-profile.d.ts +28 -0
- package/dist/tools/project-profile.d.ts.map +1 -0
- package/dist/tools/project-profile.js +109 -0
- package/dist/tools/project-profile.js.map +1 -0
- package/dist/tools/query.d.ts +63 -0
- package/dist/tools/query.d.ts.map +1 -0
- package/dist/tools/query.js +662 -0
- package/dist/tools/query.js.map +1 -0
- package/dist/tools/remove-dead-code.d.ts +47 -0
- package/dist/tools/remove-dead-code.d.ts.map +1 -0
- package/dist/tools/remove-dead-code.js +258 -0
- package/dist/tools/remove-dead-code.js.map +1 -0
- package/dist/tools/rename.d.ts +21 -0
- package/dist/tools/rename.d.ts.map +1 -0
- package/dist/tools/rename.js +116 -0
- package/dist/tools/rename.js.map +1 -0
- package/dist/tools/risk-trends.d.ts +19 -0
- package/dist/tools/risk-trends.d.ts.map +1 -0
- package/dist/tools/risk-trends.js +73 -0
- package/dist/tools/risk-trends.js.map +1 -0
- package/dist/tools/route-map.d.ts +27 -0
- package/dist/tools/route-map.d.ts.map +1 -0
- package/dist/tools/route-map.js +119 -0
- package/dist/tools/route-map.js.map +1 -0
- package/dist/tools/scan.d.ts +27 -0
- package/dist/tools/scan.d.ts.map +1 -0
- package/dist/tools/scan.js +136 -0
- package/dist/tools/scan.js.map +1 -0
- package/dist/tools/shape-check.d.ts +53 -0
- package/dist/tools/shape-check.d.ts.map +1 -0
- package/dist/tools/shape-check.js +161 -0
- package/dist/tools/shape-check.js.map +1 -0
- package/dist/tools/shared.d.ts +101 -0
- package/dist/tools/shared.d.ts.map +1 -0
- package/dist/tools/shared.js +114 -0
- package/dist/tools/shared.js.map +1 -0
- package/dist/tools/signature.d.ts +38 -0
- package/dist/tools/signature.d.ts.map +1 -0
- package/dist/tools/signature.js +332 -0
- package/dist/tools/signature.js.map +1 -0
- package/dist/tools/sql.d.ts +34 -0
- package/dist/tools/sql.d.ts.map +1 -0
- package/dist/tools/sql.js +222 -0
- package/dist/tools/sql.js.map +1 -0
- package/dist/tools/tool-map.d.ts +24 -0
- package/dist/tools/tool-map.d.ts.map +1 -0
- package/dist/tools/tool-map.js +97 -0
- package/dist/tools/tool-map.js.map +1 -0
- package/dist/tools/verdict.d.ts +33 -0
- package/dist/tools/verdict.d.ts.map +1 -0
- package/dist/tools/verdict.js +102 -0
- package/dist/tools/verdict.js.map +1 -0
- 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"}
|