@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,29 @@
1
+ /**
2
+ * Read-only accessors for `~/.codehub/groups/<name>.json`.
3
+ *
4
+ * The MCP package intentionally reimplements a tiny reader rather than
5
+ * depending on `@opencodehub/cli`: the CLI depends on `@opencodehub/mcp`
6
+ * (via the `mcp` command), and the reverse would be a cycle. The on-disk
7
+ * shape is stable — we parallel the invariants in
8
+ * `packages/cli/src/groups.ts` (`GROUPS_DIR_NAME`, name pattern, shape)
9
+ * and cover them in tests.
10
+ */
11
+ export declare const GROUP_NAME_PATTERN: RegExp;
12
+ export interface GroupRepo {
13
+ readonly name: string;
14
+ readonly path: string;
15
+ }
16
+ export interface GroupEntry {
17
+ readonly name: string;
18
+ readonly createdAt: string;
19
+ readonly repos: readonly GroupRepo[];
20
+ readonly description?: string;
21
+ }
22
+ export interface GroupsOptions {
23
+ readonly home?: string;
24
+ }
25
+ export declare function resolveGroupsDir(opts?: GroupsOptions): string;
26
+ export declare function resolveGroupFile(name: string, opts?: GroupsOptions): string;
27
+ export declare function readGroup(name: string, opts?: GroupsOptions): Promise<GroupEntry | null>;
28
+ export declare function listGroups(opts?: GroupsOptions): Promise<readonly GroupEntry[]>;
29
+ //# sourceMappingURL=group-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"group-resolver.d.ts","sourceRoot":"","sources":["../src/group-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AASH,eAAO,MAAM,kBAAkB,QAAkB,CAAC;AAElD,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,CAAC;IACrC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,gBAAgB,CAAC,IAAI,GAAE,aAAkB,GAAG,MAAM,CAGjE;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,aAAkB,GAAG,MAAM,CAK/E;AAED,wBAAsB,SAAS,CAC7B,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,aAAkB,GACvB,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAW5B;AAED,wBAAsB,UAAU,CAAC,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,SAAS,UAAU,EAAE,CAAC,CAwBzF"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Read-only accessors for `~/.codehub/groups/<name>.json`.
3
+ *
4
+ * The MCP package intentionally reimplements a tiny reader rather than
5
+ * depending on `@opencodehub/cli`: the CLI depends on `@opencodehub/mcp`
6
+ * (via the `mcp` command), and the reverse would be a cycle. The on-disk
7
+ * shape is stable — we parallel the invariants in
8
+ * `packages/cli/src/groups.ts` (`GROUPS_DIR_NAME`, name pattern, shape)
9
+ * and cover them in tests.
10
+ */
11
+ // biome-ignore-all lint/complexity/useLiteralKeys: dot-access disallowed on Record index signatures
12
+ import { readdir, readFile } from "node:fs/promises";
13
+ import { homedir } from "node:os";
14
+ import { basename, extname, join, resolve } from "node:path";
15
+ const CODEHUB_HOME_DIR = ".codehub";
16
+ const GROUPS_DIR_NAME = "groups";
17
+ export const GROUP_NAME_PATTERN = /^[a-z0-9_-]+$/;
18
+ export function resolveGroupsDir(opts = {}) {
19
+ const home = opts.home ?? homedir();
20
+ return resolve(home, CODEHUB_HOME_DIR, GROUPS_DIR_NAME);
21
+ }
22
+ export function resolveGroupFile(name, opts = {}) {
23
+ if (!GROUP_NAME_PATTERN.test(name)) {
24
+ throw new Error(`Invalid group name "${name}". Names must match ${GROUP_NAME_PATTERN}.`);
25
+ }
26
+ return join(resolveGroupsDir(opts), `${name}.json`);
27
+ }
28
+ export async function readGroup(name, opts = {}) {
29
+ if (!GROUP_NAME_PATTERN.test(name))
30
+ return null;
31
+ const file = resolveGroupFile(name, opts);
32
+ let raw;
33
+ try {
34
+ raw = await readFile(file, "utf8");
35
+ }
36
+ catch (err) {
37
+ if (err.code === "ENOENT")
38
+ return null;
39
+ throw err;
40
+ }
41
+ return normalizeGroup(JSON.parse(raw));
42
+ }
43
+ export async function listGroups(opts = {}) {
44
+ const dir = resolveGroupsDir(opts);
45
+ let dirents;
46
+ try {
47
+ dirents = await readdir(dir);
48
+ }
49
+ catch (err) {
50
+ if (err.code === "ENOENT")
51
+ return [];
52
+ throw err;
53
+ }
54
+ const names = dirents
55
+ .filter((f) => extname(f) === ".json")
56
+ .map((f) => basename(f, ".json"))
57
+ .filter((n) => GROUP_NAME_PATTERN.test(n))
58
+ .sort();
59
+ const out = [];
60
+ for (const name of names) {
61
+ try {
62
+ const group = await readGroup(name, opts);
63
+ if (group)
64
+ out.push(group);
65
+ }
66
+ catch {
67
+ // Skip unreadable files; callers surface them via empty returns.
68
+ }
69
+ }
70
+ return out;
71
+ }
72
+ function normalizeGroup(value) {
73
+ if (typeof value !== "object" || value === null || Array.isArray(value))
74
+ return null;
75
+ const raw = value;
76
+ if (typeof raw["name"] !== "string")
77
+ return null;
78
+ if (typeof raw["createdAt"] !== "string")
79
+ return null;
80
+ if (!Array.isArray(raw["repos"]))
81
+ return null;
82
+ const repos = [];
83
+ for (const entry of raw["repos"]) {
84
+ if (typeof entry !== "object" || entry === null)
85
+ continue;
86
+ const r = entry;
87
+ if (typeof r["name"] !== "string" || typeof r["path"] !== "string")
88
+ continue;
89
+ repos.push({ name: r["name"], path: r["path"] });
90
+ }
91
+ repos.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
92
+ const out = {
93
+ name: raw["name"],
94
+ createdAt: raw["createdAt"],
95
+ repos,
96
+ ...(typeof raw["description"] === "string" ? { description: raw["description"] } : {}),
97
+ };
98
+ return out;
99
+ }
100
+ //# sourceMappingURL=group-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"group-resolver.js","sourceRoot":"","sources":["../src/group-resolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Barrel for `@opencodehub/mcp`.
3
+ *
4
+ * The CLI's `codehub mcp` subcommand imports `startStdioServer` to host
5
+ * the server in-process. Tests import `buildServer` directly so they
6
+ * can drive tool handlers without a stdio transport.
7
+ */
8
+ export { ConnectionPool, type ConnectionPoolOptions, type StoreFactory, } from "./connection-pool.js";
9
+ export { type ErrorCode, type ErrorDetail, toolError, toolErrorFromUnknown, } from "./error-envelope.js";
10
+ export { withNextSteps } from "./next-step-hints.js";
11
+ export { type RegistryEntry, RepoResolveError, type ResolvedRepo, readRegistry, resolveRepo, } from "./repo-resolver.js";
12
+ export { buildServer, type RunningServer, type StartServerOptions, startStdioServer, } from "./server.js";
13
+ export { stalenessFromMeta } from "./staleness.js";
14
+ export { runApiImpact } from "./tools/api-impact.js";
15
+ export { runContext } from "./tools/context.js";
16
+ export { runDependencies } from "./tools/dependencies.js";
17
+ export { runDetectChanges } from "./tools/detect-changes.js";
18
+ export { runGroupContracts } from "./tools/group-contracts.js";
19
+ export { runGroupList } from "./tools/group-list.js";
20
+ export { runGroupQuery } from "./tools/group-query.js";
21
+ export { runGroupStatus } from "./tools/group-status.js";
22
+ export { runGroupSyncTool } from "./tools/group-sync.js";
23
+ export { runImpact } from "./tools/impact.js";
24
+ export { runLicenseAudit } from "./tools/license-audit.js";
25
+ export { runListDeadCode } from "./tools/list-dead-code.js";
26
+ export { runListFindings } from "./tools/list-findings.js";
27
+ export { runListFindingsDelta } from "./tools/list-findings-delta.js";
28
+ export { runListRepos } from "./tools/list-repos.js";
29
+ export { runOwners } from "./tools/owners.js";
30
+ export { runProjectProfile } from "./tools/project-profile.js";
31
+ export { runQuery } from "./tools/query.js";
32
+ export { runRemoveDeadCode } from "./tools/remove-dead-code.js";
33
+ export { runRename } from "./tools/rename.js";
34
+ export { runRiskTrends } from "./tools/risk-trends.js";
35
+ export { runRouteMap } from "./tools/route-map.js";
36
+ export { runScan } from "./tools/scan.js";
37
+ export { runShapeCheck } from "./tools/shape-check.js";
38
+ export { fromToolResult, type ToolContext, type ToolResult, toToolResult, } from "./tools/shared.js";
39
+ export { runSignature } from "./tools/signature.js";
40
+ export { runSql } from "./tools/sql.js";
41
+ export { runToolMap } from "./tools/tool-map.js";
42
+ export { runVerdict } from "./tools/verdict.js";
43
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,cAAc,EACd,KAAK,qBAAqB,EAC1B,KAAK,YAAY,GAClB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,SAAS,EACT,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EACL,KAAK,aAAa,EAClB,gBAAgB,EAChB,KAAK,YAAY,EACjB,YAAY,EACZ,WAAW,GACZ,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,WAAW,EACX,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,gBAAgB,GACjB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAIvD,OAAO,EACL,cAAc,EACd,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,YAAY,GACb,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Barrel for `@opencodehub/mcp`.
3
+ *
4
+ * The CLI's `codehub mcp` subcommand imports `startStdioServer` to host
5
+ * the server in-process. Tests import `buildServer` directly so they
6
+ * can drive tool handlers without a stdio transport.
7
+ */
8
+ export { ConnectionPool, } from "./connection-pool.js";
9
+ export { toolError, toolErrorFromUnknown, } from "./error-envelope.js";
10
+ export { withNextSteps } from "./next-step-hints.js";
11
+ export { RepoResolveError, readRegistry, resolveRepo, } from "./repo-resolver.js";
12
+ export { buildServer, startStdioServer, } from "./server.js";
13
+ export { stalenessFromMeta } from "./staleness.js";
14
+ export { runApiImpact } from "./tools/api-impact.js";
15
+ export { runContext } from "./tools/context.js";
16
+ export { runDependencies } from "./tools/dependencies.js";
17
+ export { runDetectChanges } from "./tools/detect-changes.js";
18
+ export { runGroupContracts } from "./tools/group-contracts.js";
19
+ export { runGroupList } from "./tools/group-list.js";
20
+ export { runGroupQuery } from "./tools/group-query.js";
21
+ export { runGroupStatus } from "./tools/group-status.js";
22
+ export { runGroupSyncTool } from "./tools/group-sync.js";
23
+ export { runImpact } from "./tools/impact.js";
24
+ export { runLicenseAudit } from "./tools/license-audit.js";
25
+ export { runListDeadCode } from "./tools/list-dead-code.js";
26
+ export { runListFindings } from "./tools/list-findings.js";
27
+ export { runListFindingsDelta } from "./tools/list-findings-delta.js";
28
+ export { runListRepos } from "./tools/list-repos.js";
29
+ export { runOwners } from "./tools/owners.js";
30
+ export { runProjectProfile } from "./tools/project-profile.js";
31
+ export { runQuery } from "./tools/query.js";
32
+ export { runRemoveDeadCode } from "./tools/remove-dead-code.js";
33
+ export { runRename } from "./tools/rename.js";
34
+ export { runRiskTrends } from "./tools/risk-trends.js";
35
+ export { runRouteMap } from "./tools/route-map.js";
36
+ export { runScan } from "./tools/scan.js";
37
+ export { runShapeCheck } from "./tools/shape-check.js";
38
+ // Pure tool handlers for non-SDK callers. Every run function takes a
39
+ // `ToolContext` and returns a transport-agnostic `ToolResult` with both
40
+ // `text` and `structuredContent`.
41
+ export { fromToolResult, toToolResult, } from "./tools/shared.js";
42
+ export { runSignature } from "./tools/signature.js";
43
+ export { runSql } from "./tools/sql.js";
44
+ export { runToolMap } from "./tools/tool-map.js";
45
+ export { runVerdict } from "./tools/verdict.js";
46
+ // Allow `node dist/index.js` to boot the stdio server directly. The CLI
47
+ // package's `codehub mcp` binary imports `startStdioServer` instead so
48
+ // it can pre-parse its own flags before handing off to us.
49
+ if (process.argv[1] &&
50
+ (process.argv[1].endsWith("/dist/index.js") || process.argv[1].endsWith("\\dist\\index.js"))) {
51
+ const { startStdioServer } = await import("./server.js");
52
+ await startStdioServer();
53
+ }
54
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,cAAc,GAGf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAGL,SAAS,EACT,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAEL,gBAAgB,EAEhB,YAAY,EACZ,WAAW,GACZ,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,WAAW,EAGX,gBAAgB,GACjB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,qEAAqE;AACrE,wEAAwE;AACxE,kCAAkC;AAClC,OAAO,EACL,cAAc,EAGd,YAAY,GACb,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,wEAAwE;AACxE,uEAAuE;AACvE,2DAA2D;AAC3D,IACE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACf,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC,EAC5F,CAAC;IACD,MAAM,EAAE,gBAAgB,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;IACzD,MAAM,gBAAgB,EAAE,CAAC;AAC3B,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Next-step hint helper.
3
+ *
4
+ * The MCP spec (rev 2025-06-18) does not carve out a first-class "suggest
5
+ * what tool to call next" field. Research-mcp.yaml captures the three
6
+ * in-spec options; we combine two:
7
+ * (a) a `next_steps: string[]` under `structuredContent` for clients that
8
+ * consume the output schema, and
9
+ * (b) a trailing "Suggested next tools:" text block in the primary
10
+ * `content` array for clients that only ingest text.
11
+ *
12
+ * The `_meta` map under structuredContent carries staleness under a stable
13
+ * `codehub/staleness` namespace so non-aware clients simply ignore it.
14
+ */
15
+ import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
16
+ import type { StalenessEnvelope } from "@opencodehub/core-types";
17
+ /**
18
+ * Wrap a tool's text + structured payload with next-step hints and an
19
+ * optional staleness envelope. `structured` must be a plain object; the
20
+ * result includes every key from `structured` plus `next_steps` and
21
+ * `_meta`.
22
+ */
23
+ export declare function withNextSteps<T extends Record<string, unknown>>(content: string, structured: T, nextSteps: readonly string[], staleness?: StalenessEnvelope): CallToolResult;
24
+ //# sourceMappingURL=next-step-hints.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"next-step-hints.d.ts","sourceRoot":"","sources":["../src/next-step-hints.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAIjE;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7D,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,CAAC,EACb,SAAS,EAAE,SAAS,MAAM,EAAE,EAC5B,SAAS,CAAC,EAAE,iBAAiB,GAC5B,cAAc,CAoBhB"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Next-step hint helper.
3
+ *
4
+ * The MCP spec (rev 2025-06-18) does not carve out a first-class "suggest
5
+ * what tool to call next" field. Research-mcp.yaml captures the three
6
+ * in-spec options; we combine two:
7
+ * (a) a `next_steps: string[]` under `structuredContent` for clients that
8
+ * consume the output schema, and
9
+ * (b) a trailing "Suggested next tools:" text block in the primary
10
+ * `content` array for clients that only ingest text.
11
+ *
12
+ * The `_meta` map under structuredContent carries staleness under a stable
13
+ * `codehub/staleness` namespace so non-aware clients simply ignore it.
14
+ */
15
+ const STALENESS_META_KEY = "codehub/staleness";
16
+ /**
17
+ * Wrap a tool's text + structured payload with next-step hints and an
18
+ * optional staleness envelope. `structured` must be a plain object; the
19
+ * result includes every key from `structured` plus `next_steps` and
20
+ * `_meta`.
21
+ */
22
+ export function withNextSteps(content, structured, nextSteps, staleness) {
23
+ const hintBlock = nextSteps.length > 0
24
+ ? `\n\nSuggested next tools:\n${nextSteps.map((s) => `- ${s}`).join("\n")}`
25
+ : "";
26
+ const meta = {};
27
+ if (staleness)
28
+ meta[STALENESS_META_KEY] = staleness;
29
+ const structuredContent = {
30
+ ...structured,
31
+ next_steps: [...nextSteps],
32
+ };
33
+ if (Object.keys(meta).length > 0) {
34
+ structuredContent["_meta"] = meta;
35
+ }
36
+ return {
37
+ content: [{ type: "text", text: content + hintBlock }],
38
+ structuredContent,
39
+ };
40
+ }
41
+ //# sourceMappingURL=next-step-hints.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"next-step-hints.js","sourceRoot":"","sources":["../src/next-step-hints.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,MAAM,kBAAkB,GAAG,mBAAmB,CAAC;AAE/C;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAC3B,OAAe,EACf,UAAa,EACb,SAA4B,EAC5B,SAA6B;IAE7B,MAAM,SAAS,GACb,SAAS,CAAC,MAAM,GAAG,CAAC;QAClB,CAAC,CAAC,8BAA8B,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QAC3E,CAAC,CAAC,EAAE,CAAC;IACT,MAAM,IAAI,GAA4B,EAAE,CAAC;IACzC,IAAI,SAAS;QAAE,IAAI,CAAC,kBAAkB,CAAC,GAAG,SAAS,CAAC;IAEpD,MAAM,iBAAiB,GAA4B;QACjD,GAAG,UAAU;QACb,UAAU,EAAE,CAAC,GAAG,SAAS,CAAC;KAC3B,CAAC;IACF,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjC,iBAAiB,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;IACpC,CAAC;IAED,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,OAAO,GAAG,SAAS,EAAE,CAAC;QAC/D,iBAAiB;KAClB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Resolve a user-supplied (or omitted) `repo` argument to a concrete repo
3
+ * path, DuckDB file path, and (optionally) cached store metadata.
4
+ *
5
+ * The authoritative mapping lives at `~/.codehub/registry.json`. Callers
6
+ * who pass a name look it up there. When `repo` is omitted:
7
+ * - Exactly one registered repo: return it (friendly single-repo case).
8
+ * - Zero registered repos: throw `NO_INDEX`.
9
+ * - Two or more registered repos: throw `AMBIGUOUS_REPO` so the caller
10
+ * picks explicitly. Silent alphabetical-first picks are a footgun
11
+ * across a stdio MCP session where the server has no reliable cwd.
12
+ */
13
+ import { type StoreMeta } from "@opencodehub/storage";
14
+ import type { RepoChoice } from "./error-envelope.js";
15
+ export interface RegistryEntry {
16
+ readonly name: string;
17
+ readonly path: string;
18
+ readonly lastCommit?: string;
19
+ readonly indexedAt: string;
20
+ readonly nodeCount: number;
21
+ readonly edgeCount: number;
22
+ }
23
+ export interface ResolvedRepo {
24
+ readonly name: string;
25
+ readonly repoPath: string;
26
+ readonly dbPath: string;
27
+ readonly entry: RegistryEntry;
28
+ readonly meta?: StoreMeta;
29
+ }
30
+ export type RepoResolveCode = "NO_INDEX" | "NOT_FOUND" | "AMBIGUOUS_REPO";
31
+ /**
32
+ * Auxiliary payload attached to `RepoResolveError` instances whose
33
+ * `code === "AMBIGUOUS_REPO"`. `choices` is the full list (not capped);
34
+ * the envelope builder at `error-envelope.ts` applies the 10-entry cap.
35
+ */
36
+ export interface AmbiguousRepoInfo {
37
+ readonly choices: readonly RepoChoice[];
38
+ readonly totalMatches: number;
39
+ }
40
+ export declare class RepoResolveError extends Error {
41
+ readonly code: RepoResolveCode;
42
+ readonly hint: string;
43
+ /** Populated only when `code === "AMBIGUOUS_REPO"`. */
44
+ readonly ambiguous?: AmbiguousRepoInfo;
45
+ constructor(code: RepoResolveCode, message: string, hint: string, ambiguous?: AmbiguousRepoInfo);
46
+ }
47
+ /**
48
+ * Inputs accepted by {@link resolveRepo}. Back-compat: a bare `string`
49
+ * (the registry name) or `undefined` (trigger single-repo fallback) still
50
+ * works. The object form allows callers to pass `repo_uri` as an alias —
51
+ * when both are provided, `repo_uri` wins.
52
+ *
53
+ * Fields permit explicit `undefined` so tool-handler arg types (which
54
+ * declare `?: T | undefined` under `exactOptionalPropertyTypes`) are
55
+ * structurally assignable without wrapping.
56
+ */
57
+ export type ResolveRepoArg = string | undefined | {
58
+ readonly repo?: string | undefined;
59
+ readonly repo_uri?: string | undefined;
60
+ };
61
+ export interface ResolveRepoOptions {
62
+ /** Override the home directory (used by tests). */
63
+ readonly home?: string;
64
+ /** Skip the meta.json read (saves a syscall when caller does not need it). */
65
+ readonly skipMeta?: boolean;
66
+ }
67
+ export declare function readRegistry(opts?: ResolveRepoOptions): Promise<Record<string, RegistryEntry>>;
68
+ export declare function resolveRepo(arg: ResolveRepoArg, opts?: ResolveRepoOptions): Promise<ResolvedRepo>;
69
+ /**
70
+ * Derive a stable `repo_uri` from a registry entry.
71
+ *
72
+ * - If `name` already looks URI-ish (contains `/`), use it as-is (e.g.
73
+ * `github.com/org/repo`). This matches Sourcegraph / GitHub convention.
74
+ * - Else, fall back to `local:<sha256(path)[:12]>` so two local repos
75
+ * with colliding short names still have distinct URIs.
76
+ *
77
+ * Future work will replace this with the registry-backed
78
+ * RepoNode.repo_uri. Kept deterministic so tests can assert exact
79
+ * values.
80
+ */
81
+ export declare function deriveRepoUri(entry: RegistryEntry): string;
82
+ /**
83
+ * Normalize a caller-supplied `repo_uri` so it matches what
84
+ * {@link deriveRepoUri} produces. Strips protocol and trailing `.git`,
85
+ * lowercases the host segment but keeps path case.
86
+ */
87
+ export declare function normalizeRepoUri(raw: string): string;
88
+ //# sourceMappingURL=repo-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repo-resolver.d.ts","sourceRoot":"","sources":["../src/repo-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,OAAO,EAIL,KAAK,SAAS,EACf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC;CAC3B;AAED,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,WAAW,GAAG,gBAAgB,CAAC;AAE1E;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,OAAO,EAAE,SAAS,UAAU,EAAE,CAAC;IACxC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,uDAAuD;IACvD,QAAQ,CAAC,SAAS,CAAC,EAAE,iBAAiB,CAAC;gBAC3B,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,iBAAiB;CAOhG;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,cAAc,GACtB,MAAM,GACN,SAAS,GACT;IAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AAEnF,MAAM,WAAW,kBAAkB;IACjC,mDAAmD;IACnD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,8EAA8E;IAC9E,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,wBAAsB,YAAY,CAChC,IAAI,GAAE,kBAAuB,GAC5B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAWxC;AAED,wBAAsB,WAAW,CAC/B,GAAG,EAAE,cAAc,EACnB,IAAI,GAAE,kBAAuB,GAC5B,OAAO,CAAC,YAAY,CAAC,CA+DvB;AAkDD;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAI1D;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAoBpD"}
@@ -0,0 +1,211 @@
1
+ /**
2
+ * Resolve a user-supplied (or omitted) `repo` argument to a concrete repo
3
+ * path, DuckDB file path, and (optionally) cached store metadata.
4
+ *
5
+ * The authoritative mapping lives at `~/.codehub/registry.json`. Callers
6
+ * who pass a name look it up there. When `repo` is omitted:
7
+ * - Exactly one registered repo: return it (friendly single-repo case).
8
+ * - Zero registered repos: throw `NO_INDEX`.
9
+ * - Two or more registered repos: throw `AMBIGUOUS_REPO` so the caller
10
+ * picks explicitly. Silent alphabetical-first picks are a footgun
11
+ * across a stdio MCP session where the server has no reliable cwd.
12
+ */
13
+ // biome-ignore-all lint/complexity/useLiteralKeys: dot-access disallowed on Record index signatures
14
+ import { createHash } from "node:crypto";
15
+ import { readFile } from "node:fs/promises";
16
+ import { resolve } from "node:path";
17
+ import { readStoreMeta, resolveDbPath, resolveRegistryPath, } from "@opencodehub/storage";
18
+ export class RepoResolveError extends Error {
19
+ code;
20
+ hint;
21
+ /** Populated only when `code === "AMBIGUOUS_REPO"`. */
22
+ ambiguous;
23
+ constructor(code, message, hint, ambiguous) {
24
+ super(message);
25
+ this.name = "RepoResolveError";
26
+ this.code = code;
27
+ this.hint = hint;
28
+ if (ambiguous !== undefined)
29
+ this.ambiguous = ambiguous;
30
+ }
31
+ }
32
+ export async function readRegistry(opts = {}) {
33
+ const path = opts.home ? resolveRegistryPath(opts.home) : resolveRegistryPath();
34
+ let raw;
35
+ try {
36
+ raw = await readFile(path, "utf8");
37
+ }
38
+ catch (err) {
39
+ if (err.code === "ENOENT")
40
+ return {};
41
+ throw err;
42
+ }
43
+ const parsed = JSON.parse(raw);
44
+ return normalizeRegistry(parsed);
45
+ }
46
+ export async function resolveRepo(arg, opts = {}) {
47
+ const { repo: repoName, repoUri } = normalizeResolveArg(arg);
48
+ const registry = await readRegistry(opts);
49
+ const names = Object.keys(registry).sort();
50
+ if (names.length === 0) {
51
+ throw new RepoResolveError("NO_INDEX", "No repos are indexed yet.", "Run `codehub analyze` in a repo root to create an index.");
52
+ }
53
+ let entry;
54
+ let resolvedName;
55
+ // `repo_uri` wins when both are provided.
56
+ if (repoUri !== undefined) {
57
+ const wanted = normalizeRepoUri(repoUri);
58
+ for (const key of names) {
59
+ const candidate = registry[key];
60
+ if (!candidate)
61
+ continue;
62
+ if (normalizeRepoUri(deriveRepoUri(candidate)) === wanted) {
63
+ entry = candidate;
64
+ resolvedName = key;
65
+ break;
66
+ }
67
+ }
68
+ }
69
+ else if (repoName !== undefined) {
70
+ entry = registry[repoName];
71
+ resolvedName = repoName;
72
+ }
73
+ else {
74
+ // Neither arg provided — single-repo defaulting, otherwise AMBIGUOUS.
75
+ if (names.length > 1) {
76
+ throw buildAmbiguousError(registry, names);
77
+ }
78
+ resolvedName = names[0];
79
+ entry = resolvedName ? registry[resolvedName] : undefined;
80
+ }
81
+ if (!entry || !resolvedName) {
82
+ const requested = repoUri ?? repoName ?? "<default>";
83
+ throw new RepoResolveError("NOT_FOUND", `Repo ${requested} is not in the registry.`, `Known repos: ${names.join(", ")}. Run \`codehub analyze\` in the target repo first.`);
84
+ }
85
+ const repoPath = resolve(entry.path);
86
+ const dbPath = resolveDbPath(repoPath);
87
+ let meta;
88
+ if (!opts.skipMeta) {
89
+ try {
90
+ meta = await readStoreMeta(repoPath);
91
+ }
92
+ catch {
93
+ meta = undefined;
94
+ }
95
+ }
96
+ return meta
97
+ ? { name: resolvedName, repoPath, dbPath, entry, meta }
98
+ : { name: resolvedName, repoPath, dbPath, entry };
99
+ }
100
+ /**
101
+ * Normalize a `ResolveRepoArg` to its object form so the resolver can key
102
+ * on both `repo` and `repo_uri` uniformly. Bare strings are treated as
103
+ * `{ repo: s }` for back-compat with pre-M6 callers.
104
+ */
105
+ function normalizeResolveArg(arg) {
106
+ if (arg === undefined)
107
+ return { repo: undefined, repoUri: undefined };
108
+ if (typeof arg === "string")
109
+ return { repo: arg, repoUri: undefined };
110
+ return { repo: arg.repo, repoUri: arg.repo_uri };
111
+ }
112
+ /**
113
+ * Build the structured AMBIGUOUS_REPO error with a `choices[]` payload
114
+ * derived from registry entries.
115
+ *
116
+ * Once the registry is reshaped to expose `default_branch` + `group`
117
+ * from the persisted RepoNode, switch this to pull those fields from
118
+ * the node instead of defaulting to `null`. For now they're
119
+ * placeholders so the wire shape is stable.
120
+ */
121
+ function buildAmbiguousError(registry, names) {
122
+ const choices = [];
123
+ for (const key of names) {
124
+ const entry = registry[key];
125
+ if (!entry)
126
+ continue;
127
+ choices.push({
128
+ repo_uri: deriveRepoUri(entry),
129
+ default_branch: null,
130
+ group: null,
131
+ });
132
+ }
133
+ const preview = names.slice(0, 5).join(", ");
134
+ const elided = names.length > 5 ? `, +${names.length - 5} more` : "";
135
+ const hint = `Pass \`repo_uri\` (or \`repo\`) to disambiguate. Registered repos: ${preview}${elided}.`;
136
+ return new RepoResolveError("AMBIGUOUS_REPO", `No \`repo\` argument provided but ${names.length} repos are registered.`, hint, { choices, totalMatches: names.length });
137
+ }
138
+ /**
139
+ * Derive a stable `repo_uri` from a registry entry.
140
+ *
141
+ * - If `name` already looks URI-ish (contains `/`), use it as-is (e.g.
142
+ * `github.com/org/repo`). This matches Sourcegraph / GitHub convention.
143
+ * - Else, fall back to `local:<sha256(path)[:12]>` so two local repos
144
+ * with colliding short names still have distinct URIs.
145
+ *
146
+ * Future work will replace this with the registry-backed
147
+ * RepoNode.repo_uri. Kept deterministic so tests can assert exact
148
+ * values.
149
+ */
150
+ export function deriveRepoUri(entry) {
151
+ if (entry.name.includes("/"))
152
+ return entry.name;
153
+ const digest = createHash("sha256").update(entry.path).digest("hex").slice(0, 12);
154
+ return `local:${digest}`;
155
+ }
156
+ /**
157
+ * Normalize a caller-supplied `repo_uri` so it matches what
158
+ * {@link deriveRepoUri} produces. Strips protocol and trailing `.git`,
159
+ * lowercases the host segment but keeps path case.
160
+ */
161
+ export function normalizeRepoUri(raw) {
162
+ let s = raw.trim();
163
+ // `git@host:org/repo.git` → `host/org/repo`
164
+ const scpMatch = /^git@([^:]+):(.+)$/.exec(s);
165
+ if (scpMatch) {
166
+ const host = (scpMatch[1] ?? "").toLowerCase();
167
+ s = `${host}/${scpMatch[2] ?? ""}`;
168
+ }
169
+ else if (/^https?:\/\//i.test(s)) {
170
+ // `https://host/path` → `host/path` (lowercase host, keep path case)
171
+ s = s.replace(/^https?:\/\//i, "");
172
+ const slash = s.indexOf("/");
173
+ if (slash !== -1) {
174
+ const host = s.slice(0, slash).toLowerCase();
175
+ s = `${host}${s.slice(slash)}`;
176
+ }
177
+ else {
178
+ s = s.toLowerCase();
179
+ }
180
+ }
181
+ if (s.endsWith(".git"))
182
+ s = s.slice(0, -".git".length);
183
+ return s;
184
+ }
185
+ function normalizeRegistry(value) {
186
+ if (typeof value !== "object" || value === null || Array.isArray(value))
187
+ return {};
188
+ const out = {};
189
+ for (const [key, raw] of Object.entries(value)) {
190
+ if (typeof raw !== "object" || raw === null)
191
+ continue;
192
+ const r = raw;
193
+ if (typeof r["name"] !== "string" || typeof r["path"] !== "string")
194
+ continue;
195
+ if (typeof r["indexedAt"] !== "string")
196
+ continue;
197
+ if (typeof r["nodeCount"] !== "number" || typeof r["edgeCount"] !== "number")
198
+ continue;
199
+ const entry = {
200
+ name: r["name"],
201
+ path: r["path"],
202
+ indexedAt: r["indexedAt"],
203
+ nodeCount: r["nodeCount"],
204
+ edgeCount: r["edgeCount"],
205
+ ...(typeof r["lastCommit"] === "string" ? { lastCommit: r["lastCommit"] } : {}),
206
+ };
207
+ out[key] = entry;
208
+ }
209
+ return out;
210
+ }
211
+ //# sourceMappingURL=repo-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repo-resolver.js","sourceRoot":"","sources":["../src/repo-resolver.ts"],"names":[],"mappings":"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"}