@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,58 @@
1
+ /**
2
+ * Shared repo-resolution + store-checkout helper for resource handlers.
3
+ *
4
+ * Mirrors the tool-side `withStore` but returns shape appropriate for
5
+ * resources: instead of `CallToolResult`, resource callbacks return
6
+ * `ReadResourceResult`, which carries a plain text body. Errors
7
+ * (missing pool, repo not found, DuckDB open failure) are surfaced as a
8
+ * YAML error envelope inside the resource body so the agent sees the
9
+ * problem inline rather than receiving a transport-level fault.
10
+ */
11
+ import { RepoResolveError, resolveRepo } from "../repo-resolver.js";
12
+ /**
13
+ * Acquire a read-only store handle for `repoName`, invoke `fn`, and
14
+ * release. When resolution fails, return a YAML error envelope the
15
+ * caller should pass straight through. The callback is responsible for
16
+ * building the happy-path result.
17
+ */
18
+ export async function withResourceStore(uriHref, repoName, opts, fn) {
19
+ if (!opts.pool) {
20
+ return yamlError(uriHref, "pool unavailable", "Server was built without a connection pool.");
21
+ }
22
+ const resolveOpts = opts.home !== undefined ? { home: opts.home } : {};
23
+ try {
24
+ const resolved = await resolveRepo(repoName, resolveOpts);
25
+ const store = await opts.pool.acquire(resolved.repoPath, resolved.dbPath);
26
+ try {
27
+ return await fn(store, resolved.name);
28
+ }
29
+ finally {
30
+ await opts.pool.release(resolved.repoPath);
31
+ }
32
+ }
33
+ catch (err) {
34
+ if (err instanceof RepoResolveError) {
35
+ return yamlError(uriHref, err.code, err.hint);
36
+ }
37
+ const msg = err instanceof Error ? err.message : String(err);
38
+ return yamlError(uriHref, "internal error", msg);
39
+ }
40
+ }
41
+ function yamlError(uri, error, hint) {
42
+ const body = [`error: ${quote(error)}`, `hint: ${quote(hint)}`, ""].join("\n");
43
+ return {
44
+ contents: [
45
+ {
46
+ uri,
47
+ mimeType: "text/yaml",
48
+ text: body,
49
+ },
50
+ ],
51
+ };
52
+ }
53
+ function quote(value) {
54
+ if (/^[A-Za-z0-9._\-/]+$/.test(value))
55
+ return value;
56
+ return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
57
+ }
58
+ //# sourceMappingURL=store-helper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store-helper.js","sourceRoot":"","sources":["../../src/resources/store-helper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAWpE;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,OAAe,EACf,QAA4B,EAC5B,IAA0B,EAC1B,EAAmE;IAEnE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACf,OAAO,SAAS,CAAC,OAAO,EAAE,kBAAkB,EAAE,6CAA6C,CAAC,CAAC;IAC/F,CAAC;IACD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACvE,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;QAC1D,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC1E,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;QACxC,CAAC;gBAAS,CAAC;YACT,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,gBAAgB,EAAE,CAAC;YACpC,OAAO,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;QAChD,CAAC;QACD,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,OAAO,SAAS,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG,CAAC,CAAC;IACnD,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,GAAW,EAAE,KAAa,EAAE,IAAY;IACzD,MAAM,IAAI,GAAG,CAAC,UAAU,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,SAAS,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/E,OAAO;QACL,QAAQ,EAAE;YACR;gBACE,GAAG;gBACH,QAAQ,EAAE,WAAW;gBACrB,IAAI,EAAE,IAAI;aACX;SACF;KACF,CAAC;AACJ,CAAC;AAED,SAAS,KAAK,CAAC,KAAa;IAC1B,IAAI,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACpD,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC;AAClE,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Minimal YAML scalar quoter shared across resource handlers.
3
+ *
4
+ * Resources emit YAML for agent readability (see `repo-context.ts`). The
5
+ * quoter is intentionally conservative: plain identifiers pass through
6
+ * unquoted, anything else is wrapped in double quotes with embedded
7
+ * quotes escaped. A loose parser will round-trip either form.
8
+ */
9
+ export declare function yamlScalar(value: string | number | boolean): string;
10
+ //# sourceMappingURL=yaml.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yaml.d.ts","sourceRoot":"","sources":["../../src/resources/yaml.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAInE"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Minimal YAML scalar quoter shared across resource handlers.
3
+ *
4
+ * Resources emit YAML for agent readability (see `repo-context.ts`). The
5
+ * quoter is intentionally conservative: plain identifiers pass through
6
+ * unquoted, anything else is wrapped in double quotes with embedded
7
+ * quotes escaped. A loose parser will round-trip either form.
8
+ */
9
+ export function yamlScalar(value) {
10
+ if (typeof value === "number" || typeof value === "boolean")
11
+ return String(value);
12
+ if (/^[A-Za-z0-9._\-/]+$/.test(value))
13
+ return value;
14
+ return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
15
+ }
16
+ //# sourceMappingURL=yaml.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yaml.js","sourceRoot":"","sources":["../../src/resources/yaml.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,UAAU,UAAU,CAAC,KAAgC;IACzD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IAClF,IAAI,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACpD,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC;AAClE,CAAC"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * stdio MCP server for OpenCodeHub.
3
+ *
4
+ * Wires together the tool and resource registrations against a single
5
+ * shared `ConnectionPool`. The stdio transport reads JSON-RPC from stdin
6
+ * and writes responses to stdout; anything else the process emits (the
7
+ * connection pool, tool handlers) should go to stderr so it does not
8
+ * corrupt the transport.
9
+ *
10
+ * The `instructions` field is prose the model sees at session start. We
11
+ * use it to nudge agents toward `list_repos` first, and we advertise the
12
+ * staleness envelope so clients are primed to surface it.
13
+ */
14
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
15
+ import { ConnectionPool } from "./connection-pool.js";
16
+ export interface StartServerOptions {
17
+ /** Override the home directory used to locate ~/.codehub/registry.json. */
18
+ readonly home?: string;
19
+ /** Override the connection-pool cap (default 8). */
20
+ readonly poolMax?: number;
21
+ /** Override the connection-pool idle TTL (default 15 minutes). */
22
+ readonly poolTtlMs?: number;
23
+ /**
24
+ * Suppress the one-time "embeddings weights not found" startup warning.
25
+ * Tests set this so stderr stays quiet; production callers should leave
26
+ * it unset.
27
+ */
28
+ readonly silentEmbedderProbe?: boolean;
29
+ }
30
+ export interface RunningServer {
31
+ readonly server: McpServer;
32
+ readonly pool: ConnectionPool;
33
+ shutdown(): Promise<void>;
34
+ }
35
+ /**
36
+ * Build a fully-wired `McpServer` (without connecting a transport). The
37
+ * CLI wrapper uses this to embed the server in-process; the stdio entry
38
+ * point in `index.ts` connects a stdio transport on top.
39
+ */
40
+ export declare function buildServer(opts?: StartServerOptions): RunningServer;
41
+ /**
42
+ * Entry point: build the server, connect stdio, and install a SIGINT /
43
+ * SIGTERM / stdin-close handler that drains the pool before exiting.
44
+ */
45
+ export declare function startStdioServer(opts?: StartServerOptions): Promise<void>;
46
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGpE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAmDtD,MAAM,WAAW,kBAAkB;IACjC,2EAA2E;IAC3E,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,oDAAoD;IACpD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,kEAAkE;IAClE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC;CACxC;AAiCD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,GAAE,kBAAuB,GAAG,aAAa,CAuExE;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,GAAE,kBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsBnF"}
package/dist/server.js ADDED
@@ -0,0 +1,194 @@
1
+ /**
2
+ * stdio MCP server for OpenCodeHub.
3
+ *
4
+ * Wires together the tool and resource registrations against a single
5
+ * shared `ConnectionPool`. The stdio transport reads JSON-RPC from stdin
6
+ * and writes responses to stdout; anything else the process emits (the
7
+ * connection pool, tool handlers) should go to stderr so it does not
8
+ * corrupt the transport.
9
+ *
10
+ * The `instructions` field is prose the model sees at session start. We
11
+ * use it to nudge agents toward `list_repos` first, and we advertise the
12
+ * staleness envelope so clients are primed to surface it.
13
+ */
14
+ import { access } from "node:fs/promises";
15
+ import { join } from "node:path";
16
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
17
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
18
+ import { getDefaultModelRoot, modelFileName, resolveModelDir } from "@opencodehub/embedder";
19
+ import { ConnectionPool } from "./connection-pool.js";
20
+ import { registerRepoClusterResource } from "./resources/repo-cluster.js";
21
+ import { registerRepoClustersResource } from "./resources/repo-clusters.js";
22
+ import { registerRepoContextResource } from "./resources/repo-context.js";
23
+ import { registerRepoProcessResource } from "./resources/repo-process.js";
24
+ import { registerRepoProcessesResource } from "./resources/repo-processes.js";
25
+ import { registerRepoSchemaResource } from "./resources/repo-schema.js";
26
+ import { registerReposResource } from "./resources/repos.js";
27
+ import { registerApiImpactTool } from "./tools/api-impact.js";
28
+ import { registerContextTool } from "./tools/context.js";
29
+ import { registerDependenciesTool } from "./tools/dependencies.js";
30
+ import { registerDetectChangesTool } from "./tools/detect-changes.js";
31
+ import { registerGroupContractsTool } from "./tools/group-contracts.js";
32
+ import { registerGroupCrossRepoLinksTool } from "./tools/group-cross-repo-links.js";
33
+ import { registerGroupListTool } from "./tools/group-list.js";
34
+ import { registerGroupQueryTool } from "./tools/group-query.js";
35
+ import { registerGroupStatusTool } from "./tools/group-status.js";
36
+ import { registerGroupSyncTool } from "./tools/group-sync.js";
37
+ import { registerImpactTool } from "./tools/impact.js";
38
+ import { registerLicenseAuditTool } from "./tools/license-audit.js";
39
+ import { registerListDeadCodeTool } from "./tools/list-dead-code.js";
40
+ import { registerListFindingsTool } from "./tools/list-findings.js";
41
+ import { registerListFindingsDeltaTool } from "./tools/list-findings-delta.js";
42
+ import { registerListReposTool } from "./tools/list-repos.js";
43
+ import { registerOwnersTool } from "./tools/owners.js";
44
+ import { registerPackCodebaseTool } from "./tools/pack-codebase.js";
45
+ import { registerProjectProfileTool } from "./tools/project-profile.js";
46
+ import { registerQueryTool } from "./tools/query.js";
47
+ import { registerRemoveDeadCodeTool } from "./tools/remove-dead-code.js";
48
+ import { registerRenameTool } from "./tools/rename.js";
49
+ import { registerRiskTrendsTool } from "./tools/risk-trends.js";
50
+ import { registerRouteMapTool } from "./tools/route-map.js";
51
+ import { registerScanTool } from "./tools/scan.js";
52
+ import { registerShapeCheckTool } from "./tools/shape-check.js";
53
+ import { registerSqlTool } from "./tools/sql.js";
54
+ import { registerToolMapTool } from "./tools/tool-map.js";
55
+ import { registerVerdictTool } from "./tools/verdict.js";
56
+ const SERVER_NAME = "opencodehub";
57
+ const SERVER_VERSION = "0.0.0";
58
+ const INSTRUCTIONS = [
59
+ "OpenCodeHub exposes indexed code graphs for MCP agents.",
60
+ "Typical flow: call `list_repos` first to discover indexed repos, then route subsequent calls through one of those repo names.",
61
+ "Every per-repo tool (`query`, `context`, `impact`, `detect_changes`, `rename`, `sql`, `scan`, `list_findings`, `list_findings_delta`, `list_dead_code`, `remove_dead_code`, `license_audit`, `project_profile`, `dependencies`, `owners`, `risk_trends`, `verdict`) accepts an optional `repo` argument (registry name) or a `repo_uri` alias (Sourcegraph-style URI like `github.com/org/repo`, or `local:<hash>` for unpublished repos; wins when both are provided). When exactly one repo is registered, both are optional and the tool defaults to that repo. When ≥ 2 repos are registered and neither is supplied, the tool returns `AMBIGUOUS_REPO` — the structured envelope carries `structuredContent.error.choices[]` (capped at 10, with `{repo_uri, default_branch, group}`) plus `total_matches`, so a caller can retry with one of `choices[].repo_uri`.",
62
+ "Every tool response includes a `next_steps` array under structuredContent and a `_meta.codehub/staleness` entry when the index may be behind HEAD.",
63
+ "Use `query` to locate symbols, `context` for a 360-degree view, `impact` for blast radius, `detect_changes` to map a diff to flows, `rename` for coordinated renames (dry-run by default), `dependencies` for the external package list, `license_audit` for a copyleft/unknown/proprietary tier check of dependencies, `list_findings` to browse SARIF findings, `list_findings_delta` to diff the latest scan against a frozen baseline (new/fixed/unchanged/updated buckets), `scan` to run Priority-1 scanners (openWorld — spawns processes), `verdict` for a 5-tier PR decision (exit codes 0/1/2), `risk_trends` for per-community trend lines and 30-day projections, and `sql` for bespoke queries.",
64
+ "For cross-repo work, call `group_list` to discover named repo groups, then `group_query`/`group_status` to fan out BM25 search and staleness across the group. `group_query` returns `{ group, query, results: [{ _repo, _rrf_score, ... }], per_repo, warnings }`; results are tagged with the source repo and per-repo errors surface in `per_repo[].error` + `warnings[]` (the fan-out never aborts on a single-repo failure). Use `group_sync` to materialize a cross-repo contract registry (HTTP / gRPC / topic) under `~/.codehub/groups/<name>/contracts.json`, then `group_contracts` to list the DuckDB-backed FETCHES↔Route edges together with the registry's signature-matched cross-links.",
65
+ ].join(" ");
66
+ /**
67
+ * Probe for gte-modernbert-base weights on disk. Runs once at server startup
68
+ * and logs a single structured warning when the weights are absent so
69
+ * agents see the BM25-only fallback reason. Never throws: a missing or
70
+ * unreadable model directory is a supported deployment mode.
71
+ */
72
+ async function probeEmbedderWeights(silent) {
73
+ if (silent)
74
+ return;
75
+ try {
76
+ for (const variant of ["fp32", "int8"]) {
77
+ const modelDir = resolveModelDir(undefined, variant);
78
+ const modelPath = join(modelDir, modelFileName(variant));
79
+ try {
80
+ await access(modelPath);
81
+ // At least one variant is installed — stay silent.
82
+ return;
83
+ }
84
+ catch {
85
+ // try the next variant
86
+ }
87
+ }
88
+ const root = getDefaultModelRoot();
89
+ console.warn(`[mcp] hybrid: embeddings weights not found at ${root}/models/gte-modernbert-base/; run \`codehub setup --embeddings\`. Falling back to BM25-only.`);
90
+ }
91
+ catch (err) {
92
+ // Probe failure is non-fatal; surface the reason but keep going.
93
+ const message = err instanceof Error ? err.message : String(err);
94
+ console.warn(`[mcp] hybrid: embedder probe failed: ${message}. Falling back to BM25-only.`);
95
+ }
96
+ }
97
+ /**
98
+ * Build a fully-wired `McpServer` (without connecting a transport). The
99
+ * CLI wrapper uses this to embed the server in-process; the stdio entry
100
+ * point in `index.ts` connects a stdio transport on top.
101
+ */
102
+ export function buildServer(opts = {}) {
103
+ const poolOpts = {};
104
+ if (opts.poolMax !== undefined)
105
+ poolOpts.max = opts.poolMax;
106
+ if (opts.poolTtlMs !== undefined)
107
+ poolOpts.ttlMs = opts.poolTtlMs;
108
+ const pool = new ConnectionPool(poolOpts);
109
+ const ctx = opts.home !== undefined ? { pool, home: opts.home } : { pool };
110
+ // Fire-and-forget embedder availability probe so the one-time warning is
111
+ // emitted before the first `query` call. Never blocks startup; never
112
+ // affects tool registration.
113
+ void probeEmbedderWeights(opts.silentEmbedderProbe === true);
114
+ const server = new McpServer({ name: SERVER_NAME, version: SERVER_VERSION }, {
115
+ capabilities: {
116
+ tools: { listChanged: false },
117
+ resources: { listChanged: false },
118
+ },
119
+ instructions: INSTRUCTIONS,
120
+ });
121
+ registerListReposTool(server, ctx);
122
+ registerPackCodebaseTool(server, ctx);
123
+ registerQueryTool(server, ctx);
124
+ registerContextTool(server, ctx);
125
+ registerImpactTool(server, ctx);
126
+ registerDetectChangesTool(server, ctx);
127
+ registerRenameTool(server, ctx);
128
+ registerSqlTool(server, ctx);
129
+ registerGroupListTool(server, ctx);
130
+ registerGroupQueryTool(server, ctx);
131
+ registerGroupStatusTool(server, ctx);
132
+ registerGroupContractsTool(server, ctx);
133
+ registerGroupCrossRepoLinksTool(server, ctx);
134
+ registerGroupSyncTool(server, ctx);
135
+ registerProjectProfileTool(server, ctx);
136
+ registerDependenciesTool(server, ctx);
137
+ registerLicenseAuditTool(server, ctx);
138
+ registerOwnersTool(server, ctx);
139
+ registerListFindingsTool(server, ctx);
140
+ registerListFindingsDeltaTool(server, ctx);
141
+ registerListDeadCodeTool(server, ctx);
142
+ registerRemoveDeadCodeTool(server, ctx);
143
+ registerScanTool(server, ctx);
144
+ registerVerdictTool(server, ctx);
145
+ registerRiskTrendsTool(server, ctx);
146
+ registerRouteMapTool(server, ctx);
147
+ registerApiImpactTool(server, ctx);
148
+ registerShapeCheckTool(server, ctx);
149
+ registerToolMapTool(server, ctx);
150
+ const resCtx = opts.home !== undefined ? { home: opts.home, pool } : { pool };
151
+ registerReposResource(server, resCtx);
152
+ registerRepoContextResource(server, resCtx);
153
+ registerRepoSchemaResource(server, resCtx);
154
+ registerRepoClustersResource(server, resCtx);
155
+ registerRepoClusterResource(server, resCtx);
156
+ registerRepoProcessesResource(server, resCtx);
157
+ registerRepoProcessResource(server, resCtx);
158
+ return {
159
+ server,
160
+ pool,
161
+ shutdown: async () => {
162
+ await server.close();
163
+ await pool.shutdown();
164
+ },
165
+ };
166
+ }
167
+ /**
168
+ * Entry point: build the server, connect stdio, and install a SIGINT /
169
+ * SIGTERM / stdin-close handler that drains the pool before exiting.
170
+ */
171
+ export async function startStdioServer(opts = {}) {
172
+ const running = buildServer(opts);
173
+ const transport = new StdioServerTransport();
174
+ await running.server.connect(transport);
175
+ const bail = async (code) => {
176
+ try {
177
+ await running.shutdown();
178
+ }
179
+ finally {
180
+ process.exit(code);
181
+ }
182
+ };
183
+ process.on("SIGINT", () => {
184
+ void bail(130);
185
+ });
186
+ process.on("SIGTERM", () => {
187
+ void bail(143);
188
+ });
189
+ // Some clients signal disconnect via stdin close rather than a signal.
190
+ process.stdin.on("close", () => {
191
+ void bail(0);
192
+ });
193
+ }
194
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Thin wrappers around `@opencodehub/analysis.computeStaleness`.
3
+ *
4
+ * Tool handlers want a simple `Promise<StalenessEnvelope | undefined>`;
5
+ * the analysis package returns a slightly wider shape. We adapt and, as
6
+ * a cheap optimization, fall back to a meta-only envelope when the
7
+ * caller explicitly asks to skip the git probe (resources/read, for
8
+ * example, fires many times and should not shell out each time).
9
+ */
10
+ import type { StalenessEnvelope } from "@opencodehub/core-types";
11
+ import type { StoreMeta } from "@opencodehub/storage";
12
+ export declare function stalenessFor(repoPath: string, meta: StoreMeta | undefined): Promise<StalenessEnvelope | undefined>;
13
+ /**
14
+ * Non-async fallback used in hot paths where we want to skip the git
15
+ * probe. Emits a 0-behind envelope carrying just the last-indexed commit
16
+ * from the sidecar.
17
+ */
18
+ export declare function stalenessFromMeta(meta: StoreMeta | undefined): StalenessEnvelope | undefined;
19
+ //# sourceMappingURL=staleness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"staleness.d.ts","sourceRoot":"","sources":["../src/staleness.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEtD,wBAAsB,YAAY,CAChC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,SAAS,GAAG,SAAS,GAC1B,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC,CAaxC;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS,GAAG,iBAAiB,GAAG,SAAS,CAO5F"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Thin wrappers around `@opencodehub/analysis.computeStaleness`.
3
+ *
4
+ * Tool handlers want a simple `Promise<StalenessEnvelope | undefined>`;
5
+ * the analysis package returns a slightly wider shape. We adapt and, as
6
+ * a cheap optimization, fall back to a meta-only envelope when the
7
+ * caller explicitly asks to skip the git probe (resources/read, for
8
+ * example, fires many times and should not shell out each time).
9
+ */
10
+ import { computeStaleness } from "@opencodehub/analysis";
11
+ export async function stalenessFor(repoPath, meta) {
12
+ if (!meta)
13
+ return undefined;
14
+ const result = await computeStaleness(repoPath, meta.lastCommit);
15
+ const envelope = {
16
+ isStale: result.isStale,
17
+ commitsBehind: result.commitsBehind,
18
+ ...(result.hint !== undefined ? { hint: result.hint } : {}),
19
+ ...(result.lastIndexedCommit !== undefined
20
+ ? { lastIndexedCommit: result.lastIndexedCommit }
21
+ : {}),
22
+ ...(result.currentCommit !== undefined ? { currentCommit: result.currentCommit } : {}),
23
+ };
24
+ return envelope;
25
+ }
26
+ /**
27
+ * Non-async fallback used in hot paths where we want to skip the git
28
+ * probe. Emits a 0-behind envelope carrying just the last-indexed commit
29
+ * from the sidecar.
30
+ */
31
+ export function stalenessFromMeta(meta) {
32
+ if (!meta)
33
+ return undefined;
34
+ return {
35
+ isStale: false,
36
+ commitsBehind: 0,
37
+ ...(meta.lastCommit !== undefined ? { lastIndexedCommit: meta.lastCommit } : {}),
38
+ };
39
+ }
40
+ //# sourceMappingURL=staleness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"staleness.js","sourceRoot":"","sources":["../src/staleness.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAIzD,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,QAAgB,EAChB,IAA2B;IAE3B,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC;IAC5B,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IACjE,MAAM,QAAQ,GAAsB;QAClC,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3D,GAAG,CAAC,MAAM,CAAC,iBAAiB,KAAK,SAAS;YACxC,CAAC,CAAC,EAAE,iBAAiB,EAAE,MAAM,CAAC,iBAAiB,EAAE;YACjD,CAAC,CAAC,EAAE,CAAC;QACP,GAAG,CAAC,MAAM,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACvF,CAAC;IACF,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAA2B;IAC3D,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC;IAC5B,OAAO;QACL,OAAO,EAAE,KAAK;QACd,aAAa,EAAE,CAAC;QAChB,GAAG,CAAC,IAAI,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACjF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,170 @@
1
+ /**
2
+ * Shared MCP test fixtures.
3
+ *
4
+ * The production tools/resources call typed finders on `IGraphStore`
5
+ * (`listNodes`, `listNodesByKind`, `listEdges`,
6
+ * `listEdgesByType`, `listFindings`, `listRoutes`, `getRepoNode`,
7
+ * `traverseAncestors`, `listEmbeddingHashes`, etc.) rather than raw
8
+ * `query(<sql>)`. This file gives every mcp test a small, composable
9
+ * in-memory backing store so each test only needs to seed the data it
10
+ * cares about — nodes, edges, findings, routes — and supply
11
+ * test-specific overrides as needed.
12
+ *
13
+ * The module is intentionally tolerant: every typed finder has a sane
14
+ * default that filters the seeded arrays exactly the way the real
15
+ * `DuckDbStore` does. Tests can override a single finder via the
16
+ * `overrides` parameter when they need bespoke behaviour (e.g. cochanges,
17
+ * BM25 search, traversal).
18
+ */
19
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
20
+ import type { CallToolResult, ReadResourceResult } from "@modelcontextprotocol/sdk/types.js";
21
+ import type { DuckDbStore, IGraphStore, ITemporalStore, Store } from "@opencodehub/storage";
22
+ import { ConnectionPool } from "./connection-pool.js";
23
+ /**
24
+ * Wrap an in-memory IGraphStore-shaped fake as the composed `Store`
25
+ * (`OpenStoreResult`) that the connection pool returns. The same
26
+ * instance backs both `graph` and `temporal` because DuckDbStore
27
+ * implements both interfaces over a single connection in production.
28
+ */
29
+ export declare function wrapAsStore(fake: unknown): Store;
30
+ export interface FakeNodeLike {
31
+ readonly id: string;
32
+ readonly kind: string;
33
+ readonly name?: string;
34
+ readonly filePath?: string;
35
+ readonly file_path?: string;
36
+ readonly [extra: string]: unknown;
37
+ }
38
+ export interface FakeEdgeLike {
39
+ readonly type: string;
40
+ readonly from?: string;
41
+ readonly to?: string;
42
+ readonly fromId?: string;
43
+ readonly toId?: string;
44
+ readonly from_id?: string;
45
+ readonly to_id?: string;
46
+ readonly confidence?: number;
47
+ readonly step?: number | null;
48
+ readonly reason?: string;
49
+ readonly [extra: string]: unknown;
50
+ }
51
+ /**
52
+ * Findings/routes/dependencies/repos are typed loosely on input — tests
53
+ * pass plain records and the helper coerces to the typed `*Node` shape on
54
+ * the way out of each finder. This sidesteps `NodeId`-branded ids while
55
+ * keeping the keys discoverable.
56
+ */
57
+ export type FakeFinding = {
58
+ readonly id: string;
59
+ readonly kind?: "Finding" | undefined;
60
+ readonly name?: string | undefined;
61
+ readonly filePath?: string | undefined;
62
+ readonly scannerId?: string | undefined;
63
+ readonly ruleId?: string | undefined;
64
+ readonly severity?: "note" | "warning" | "error" | "none" | undefined;
65
+ readonly message?: string | undefined;
66
+ readonly propertiesBag?: Record<string, unknown> | undefined;
67
+ readonly startLine?: number | undefined;
68
+ readonly endLine?: number | undefined;
69
+ readonly partialFingerprint?: string | undefined;
70
+ readonly baselineState?: "new" | "unchanged" | "updated" | "absent" | undefined;
71
+ readonly suppressedJson?: string | undefined;
72
+ };
73
+ export type FakeRoute = {
74
+ readonly id: string;
75
+ readonly kind?: "Route" | undefined;
76
+ readonly name?: string | undefined;
77
+ readonly filePath?: string | undefined;
78
+ readonly url?: string | undefined;
79
+ readonly method?: "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | string | undefined;
80
+ readonly responseKeys?: readonly string[] | undefined;
81
+ readonly httpMethod?: string | undefined;
82
+ readonly httpPath?: string | undefined;
83
+ readonly path?: string | undefined;
84
+ };
85
+ export type FakeDependency = {
86
+ readonly id: string;
87
+ readonly kind?: "Dependency" | undefined;
88
+ readonly name?: string | undefined;
89
+ readonly filePath?: string | undefined;
90
+ readonly ecosystem?: string | undefined;
91
+ readonly version?: string | undefined;
92
+ readonly license?: string | undefined;
93
+ readonly licenseTier?: "permissive" | "weak-copyleft" | "strong-copyleft" | "proprietary" | "unknown" | undefined;
94
+ };
95
+ export type FakeRepo = {
96
+ readonly id: string;
97
+ readonly kind?: "Repo" | undefined;
98
+ readonly name?: string | undefined;
99
+ readonly filePath?: string | undefined;
100
+ readonly originUrl?: string | null | undefined;
101
+ readonly defaultBranch?: string | null | undefined;
102
+ readonly group?: string | null | undefined;
103
+ readonly repoUri?: string | undefined;
104
+ };
105
+ export interface FakeData {
106
+ readonly nodes?: readonly FakeNodeLike[];
107
+ readonly edges?: readonly FakeEdgeLike[];
108
+ readonly findings?: readonly FakeFinding[];
109
+ readonly routes?: readonly FakeRoute[];
110
+ readonly dependencies?: readonly FakeDependency[];
111
+ readonly repoNodes?: readonly FakeRepo[];
112
+ readonly embeddingHashes?: ReadonlyMap<string, string>;
113
+ }
114
+ /**
115
+ * Per-finder override map. Any finder a test sets on this object replaces
116
+ * the default seed-filter implementation. Useful when a test needs custom
117
+ * BM25 results, cochange rows, or traversal output.
118
+ */
119
+ export type StoreOverrides = Partial<{
120
+ [K in keyof IGraphStore]: IGraphStore[K];
121
+ }> & Partial<{
122
+ lookupCochangesForFile: ITemporalStore["lookupCochangesForFile"];
123
+ lookupCochangesBetween: ITemporalStore["lookupCochangesBetween"];
124
+ lookupSymbolSummary: ITemporalStore["lookupSymbolSummary"];
125
+ lookupSymbolSummariesByNode: ITemporalStore["lookupSymbolSummariesByNode"];
126
+ bulkLoadCochanges: ITemporalStore["bulkLoadCochanges"];
127
+ bulkLoadSymbolSummaries: ITemporalStore["bulkLoadSymbolSummaries"];
128
+ exec: ITemporalStore["exec"];
129
+ execCypher: NonNullable<IGraphStore["execCypher"]>;
130
+ query: (sql: string, params?: readonly unknown[], opts?: {
131
+ readonly timeoutMs?: number;
132
+ }) => Promise<readonly Record<string, unknown>[]>;
133
+ }>;
134
+ export declare function makeFakeGraphStore(data?: FakeData, overrides?: StoreOverrides): DuckDbStore;
135
+ export interface FakeRegistryEntry {
136
+ readonly name: string;
137
+ readonly path?: string;
138
+ readonly indexedAt?: string;
139
+ readonly nodeCount?: number;
140
+ readonly edgeCount?: number;
141
+ readonly lastCommit?: string;
142
+ }
143
+ export interface McpHarness {
144
+ readonly home: string;
145
+ readonly pool: ConnectionPool;
146
+ readonly server: McpServer;
147
+ readonly repoPath: string;
148
+ readonly repoName: string;
149
+ }
150
+ export interface MakeHarnessOptions {
151
+ readonly repoName?: string;
152
+ readonly registry?: Readonly<Record<string, FakeRegistryEntry>>;
153
+ readonly storeFactory: () => DuckDbStore | Promise<DuckDbStore>;
154
+ readonly serverCapabilities?: {
155
+ tools?: object;
156
+ resources?: object;
157
+ };
158
+ readonly tmpPrefix?: string;
159
+ }
160
+ /**
161
+ * Spin up a temp `home/.codehub/registry.json`, a `ConnectionPool` whose
162
+ * factory returns the supplied fake store, and a fresh `McpServer`. Hands
163
+ * everything back to the caller's `fn` and tears down on exit.
164
+ */
165
+ export declare function withMcpHarness(opts: MakeHarnessOptions, fn: (h: McpHarness) => Promise<void>): Promise<void>;
166
+ export type ToolHandler = (args: unknown, extra: unknown) => Promise<CallToolResult>;
167
+ export declare function getToolHandler(server: McpServer, name: string): ToolHandler;
168
+ export type ResourceReadHandler = (uri: URL, vars: Record<string, string | string[]>, extra: unknown) => Promise<ReadResourceResult>;
169
+ export declare function getResourceHandler(server: McpServer, name: string): ResourceReadHandler;
170
+ //# sourceMappingURL=test-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-utils.d.ts","sourceRoot":"","sources":["../src/test-utils.ts"],"names":[],"mappings":"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"}