@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,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `list_findings` — enumerate Finding nodes for an indexed repo.
|
|
3
|
+
*
|
|
4
|
+
* Finding nodes are produced by `codehub ingest-sarif` (or `codehub scan`
|
|
5
|
+
* via its built-in ingestion step). Every node carries `scanner_id`,
|
|
6
|
+
* `rule_id`, `severity`, and `message` plus a flat `properties_bag`
|
|
7
|
+
* JSON string for the scanner's custom properties.
|
|
8
|
+
*
|
|
9
|
+
* Filters (all optional):
|
|
10
|
+
* - `severity` — restrict to one SARIF level.
|
|
11
|
+
* - `scanner` — restrict to a single scanner id.
|
|
12
|
+
* - `ruleId` — restrict to a single rule id.
|
|
13
|
+
* - `filePath` — substring match against `file_path`.
|
|
14
|
+
* - `limit` — row cap (default 500, max 10_000).
|
|
15
|
+
*/
|
|
16
|
+
// biome-ignore-all lint/complexity/useLiteralKeys: dot-access disallowed on Record index signatures
|
|
17
|
+
import { z } from "zod";
|
|
18
|
+
import { toolErrorFromUnknown } from "../error-envelope.js";
|
|
19
|
+
import { withNextSteps } from "../next-step-hints.js";
|
|
20
|
+
import { stalenessFromMeta } from "../staleness.js";
|
|
21
|
+
import { fromToolResult, repoArgShape, toToolResult, withStore, } from "./shared.js";
|
|
22
|
+
const ListFindingsInput = {
|
|
23
|
+
...repoArgShape,
|
|
24
|
+
severity: z
|
|
25
|
+
.enum(["error", "warning", "note", "none"])
|
|
26
|
+
.optional()
|
|
27
|
+
.describe("Restrict results to a single SARIF severity level."),
|
|
28
|
+
scanner: z
|
|
29
|
+
.string()
|
|
30
|
+
.optional()
|
|
31
|
+
.describe("Restrict results to a single scanner id (e.g. 'semgrep', 'osv-scanner')."),
|
|
32
|
+
ruleId: z.string().optional().describe("Restrict results to a single rule id."),
|
|
33
|
+
filePath: z
|
|
34
|
+
.string()
|
|
35
|
+
.optional()
|
|
36
|
+
.describe("Substring filter on the source file path of the finding."),
|
|
37
|
+
limit: z
|
|
38
|
+
.number()
|
|
39
|
+
.int()
|
|
40
|
+
.positive()
|
|
41
|
+
.max(10_000)
|
|
42
|
+
.optional()
|
|
43
|
+
.describe("Maximum number of findings to return (default 500, max 10000)."),
|
|
44
|
+
};
|
|
45
|
+
export async function runListFindings(ctx, args) {
|
|
46
|
+
const limit = args.limit ?? 500;
|
|
47
|
+
const call = await withStore(ctx, args, async (store, resolved) => {
|
|
48
|
+
try {
|
|
49
|
+
// listFindings narrows by severity / ruleId at the storage tier.
|
|
50
|
+
// scanner / filePath substring are applied in TS post-finder.
|
|
51
|
+
const findingsOpts = { limit };
|
|
52
|
+
if (args.severity !== undefined &&
|
|
53
|
+
(args.severity === "note" || args.severity === "warning" || args.severity === "error")) {
|
|
54
|
+
findingsOpts.severity = [args.severity];
|
|
55
|
+
}
|
|
56
|
+
if (args.ruleId !== undefined)
|
|
57
|
+
findingsOpts.ruleId = args.ruleId;
|
|
58
|
+
const all = await store.graph.listFindings(findingsOpts);
|
|
59
|
+
const filtered = all.filter((f) => {
|
|
60
|
+
if (args.severity === "none" && f.severity !== "none")
|
|
61
|
+
return false;
|
|
62
|
+
if (args.scanner !== undefined && f.scannerId !== args.scanner)
|
|
63
|
+
return false;
|
|
64
|
+
if (args.filePath !== undefined && !f.filePath.includes(args.filePath))
|
|
65
|
+
return false;
|
|
66
|
+
return true;
|
|
67
|
+
});
|
|
68
|
+
const rows = filtered.map((f) => {
|
|
69
|
+
const base = {
|
|
70
|
+
id: f.id,
|
|
71
|
+
scanner: stringOr(f.scannerId, "unknown"),
|
|
72
|
+
ruleId: stringOr(f.ruleId, ""),
|
|
73
|
+
severity: stringOr(f.severity, "note"),
|
|
74
|
+
message: stringOr(f.message, ""),
|
|
75
|
+
filePath: stringOr(f.filePath, ""),
|
|
76
|
+
properties: f.propertiesBag,
|
|
77
|
+
...(typeof f.startLine === "number" && Number.isFinite(f.startLine)
|
|
78
|
+
? { startLine: f.startLine }
|
|
79
|
+
: {}),
|
|
80
|
+
...(typeof f.endLine === "number" && Number.isFinite(f.endLine)
|
|
81
|
+
? { endLine: f.endLine }
|
|
82
|
+
: {}),
|
|
83
|
+
};
|
|
84
|
+
return base;
|
|
85
|
+
});
|
|
86
|
+
const header = `Findings (${rows.length}) for ${resolved.name}${args.severity ? ` · severity=${args.severity}` : ""}${args.scanner ? ` · scanner=${args.scanner}` : ""}${args.ruleId ? ` · rule=${args.ruleId}` : ""}${args.filePath ? ` · filePath~${args.filePath}` : ""}:`;
|
|
87
|
+
const body = rows.length === 0
|
|
88
|
+
? "(no findings matched — run `codehub scan` or `codehub ingest-sarif <log>` to populate Finding nodes)"
|
|
89
|
+
: rows
|
|
90
|
+
.map((f) => `- [${f.severity}] ${f.scanner}:${f.ruleId} at ${f.filePath}${f.startLine !== undefined ? `:${f.startLine}` : ""}${f.message ? ` — ${f.message}` : ""}`)
|
|
91
|
+
.join("\n");
|
|
92
|
+
const next = rows.length === 0
|
|
93
|
+
? [
|
|
94
|
+
"run `codehub scan` in the target repo to generate findings",
|
|
95
|
+
"call `list_repos` to confirm the repo is indexed",
|
|
96
|
+
]
|
|
97
|
+
: [
|
|
98
|
+
"call `context` with a finding's file path for caller/callee neighbours",
|
|
99
|
+
"call `sql` with 'SELECT * FROM relations WHERE type = ''FOUND_IN''' for raw edges",
|
|
100
|
+
];
|
|
101
|
+
return withNextSteps(`${header}\n${body}`, { findings: rows, total: rows.length }, next, stalenessFromMeta(resolved.meta));
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
return toolErrorFromUnknown(err);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
return toToolResult(call);
|
|
108
|
+
}
|
|
109
|
+
export function registerListFindingsTool(server, ctx) {
|
|
110
|
+
server.registerTool("list_findings", {
|
|
111
|
+
title: "List SARIF findings",
|
|
112
|
+
description: "Enumerate static-analysis findings stored as Finding nodes, filtered by severity, scanner, rule id, or file path substring. Findings are populated by `codehub ingest-sarif` or `codehub scan`.",
|
|
113
|
+
inputSchema: ListFindingsInput,
|
|
114
|
+
annotations: {
|
|
115
|
+
readOnlyHint: true,
|
|
116
|
+
destructiveHint: false,
|
|
117
|
+
openWorldHint: false,
|
|
118
|
+
idempotentHint: true,
|
|
119
|
+
},
|
|
120
|
+
}, async (args) => fromToolResult(await runListFindings(ctx, args)));
|
|
121
|
+
}
|
|
122
|
+
function stringOr(v, fallback) {
|
|
123
|
+
if (typeof v === "string")
|
|
124
|
+
return v;
|
|
125
|
+
if (typeof v === "number" || typeof v === "boolean")
|
|
126
|
+
return String(v);
|
|
127
|
+
return fallback;
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=list-findings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-findings.js","sourceRoot":"","sources":["../../src/tools/list-findings.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `list_repos` — enumerate every repo registered under
|
|
3
|
+
* `~/.codehub/registry.json` with the stats recorded at index time.
|
|
4
|
+
*
|
|
5
|
+
* This is the discovery entry point: agents unfamiliar with the user's
|
|
6
|
+
* environment should call this first and then route every subsequent
|
|
7
|
+
* tool call through one of the returned `name` values.
|
|
8
|
+
*/
|
|
9
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
10
|
+
import { type ToolContext, type ToolResult } from "./shared.js";
|
|
11
|
+
/**
|
|
12
|
+
* Transport-agnostic implementation. The MCP-registered handler adapts
|
|
13
|
+
* the return value into the SDK's `CallToolResult`.
|
|
14
|
+
*/
|
|
15
|
+
export declare function runListRepos(ctx: ToolContext): Promise<ToolResult>;
|
|
16
|
+
export declare function registerListReposTool(server: McpServer, ctx: ToolContext): void;
|
|
17
|
+
//# sourceMappingURL=list-repos.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-repos.d.ts","sourceRoot":"","sources":["../../src/tools/list-repos.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIzE,OAAO,EAAkB,KAAK,WAAW,EAAE,KAAK,UAAU,EAAgB,MAAM,aAAa,CAAC;AAW9F;;;GAGG;AACH,wBAAsB,YAAY,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAuCxE;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,GAAG,IAAI,CAgB/E"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `list_repos` — enumerate every repo registered under
|
|
3
|
+
* `~/.codehub/registry.json` with the stats recorded at index time.
|
|
4
|
+
*
|
|
5
|
+
* This is the discovery entry point: agents unfamiliar with the user's
|
|
6
|
+
* environment should call this first and then route every subsequent
|
|
7
|
+
* tool call through one of the returned `name` values.
|
|
8
|
+
*/
|
|
9
|
+
import { toolErrorFromUnknown } from "../error-envelope.js";
|
|
10
|
+
import { withNextSteps } from "../next-step-hints.js";
|
|
11
|
+
import { readRegistry } from "../repo-resolver.js";
|
|
12
|
+
import { fromToolResult, toToolResult } from "./shared.js";
|
|
13
|
+
/**
|
|
14
|
+
* Transport-agnostic implementation. The MCP-registered handler adapts
|
|
15
|
+
* the return value into the SDK's `CallToolResult`.
|
|
16
|
+
*/
|
|
17
|
+
export async function runListRepos(ctx) {
|
|
18
|
+
try {
|
|
19
|
+
const opts = ctx.home !== undefined ? { home: ctx.home } : {};
|
|
20
|
+
const reg = await readRegistry(opts);
|
|
21
|
+
const repos = Object.keys(reg)
|
|
22
|
+
.sort()
|
|
23
|
+
.map((name) => {
|
|
24
|
+
const e = reg[name];
|
|
25
|
+
if (!e)
|
|
26
|
+
throw new Error(`missing entry for ${name}`);
|
|
27
|
+
return {
|
|
28
|
+
name: e.name,
|
|
29
|
+
path: e.path,
|
|
30
|
+
lastCommit: e.lastCommit ?? null,
|
|
31
|
+
indexedAt: e.indexedAt,
|
|
32
|
+
nodeCount: e.nodeCount,
|
|
33
|
+
edgeCount: e.edgeCount,
|
|
34
|
+
};
|
|
35
|
+
});
|
|
36
|
+
const header = `Indexed repos (${repos.length}):`;
|
|
37
|
+
const body = repos.length === 0
|
|
38
|
+
? "(none — run `codehub analyze` in a repo root to create an index)"
|
|
39
|
+
: repos
|
|
40
|
+
.map((r) => `- ${r.name}\n path: ${r.path}\n indexedAt: ${r.indexedAt}\n nodes: ${r.nodeCount}, edges: ${r.edgeCount}`)
|
|
41
|
+
.join("\n");
|
|
42
|
+
const next = repos.length === 0
|
|
43
|
+
? ["run `codehub analyze` on a git repo to index it"]
|
|
44
|
+
: [`call \`query\` with a search phrase (repo="${repos[0]?.name ?? ""}") to explore`];
|
|
45
|
+
return toToolResult(withNextSteps(`${header}\n${body}`, { repos }, next));
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
return toToolResult(toolErrorFromUnknown(err));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
export function registerListReposTool(server, ctx) {
|
|
52
|
+
server.registerTool("list_repos", {
|
|
53
|
+
title: "List indexed repos",
|
|
54
|
+
description: "Enumerate every repo that has been indexed by codehub on this machine. Returns name, on-disk path, last-seen commit, index timestamp, and node/edge counts per repo. Call this before any repo-scoped tool when you do not already know the repo name.",
|
|
55
|
+
annotations: {
|
|
56
|
+
readOnlyHint: true,
|
|
57
|
+
destructiveHint: false,
|
|
58
|
+
idempotentHint: true,
|
|
59
|
+
openWorldHint: false,
|
|
60
|
+
},
|
|
61
|
+
}, async () => fromToolResult(await runListRepos(ctx)));
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=list-repos.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-repos.js","sourceRoot":"","sources":["../../src/tools/list-repos.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAqC,YAAY,EAAE,MAAM,aAAa,CAAC;AAW9F;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAgB;IACjD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9D,MAAM,GAAG,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;QACrC,MAAM,KAAK,GAAkB,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;aAC1C,IAAI,EAAE;aACN,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YACZ,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;YACpB,IAAI,CAAC,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,IAAI,EAAE,CAAC,CAAC;YACrD,OAAO;gBACL,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,UAAU,EAAE,CAAC,CAAC,UAAU,IAAI,IAAI;gBAChC,SAAS,EAAE,CAAC,CAAC,SAAS;gBACtB,SAAS,EAAE,CAAC,CAAC,SAAS;gBACtB,SAAS,EAAE,CAAC,CAAC,SAAS;aACvB,CAAC;QACJ,CAAC,CAAC,CAAC;QAEL,MAAM,MAAM,GAAG,kBAAkB,KAAK,CAAC,MAAM,IAAI,CAAC;QAClD,MAAM,IAAI,GACR,KAAK,CAAC,MAAM,KAAK,CAAC;YAChB,CAAC,CAAC,kEAAkE;YACpE,CAAC,CAAC,KAAK;iBACF,GAAG,CACF,CAAC,CAAC,EAAE,EAAE,CACJ,KAAK,CAAC,CAAC,IAAI,aAAa,CAAC,CAAC,IAAI,kBAAkB,CAAC,CAAC,SAAS,cAAc,CAAC,CAAC,SAAS,YAAY,CAAC,CAAC,SAAS,EAAE,CAChH;iBACA,IAAI,CAAC,IAAI,CAAC,CAAC;QAEpB,MAAM,IAAI,GACR,KAAK,CAAC,MAAM,KAAK,CAAC;YAChB,CAAC,CAAC,CAAC,iDAAiD,CAAC;YACrD,CAAC,CAAC,CAAC,8CAA8C,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,EAAE,eAAe,CAAC,CAAC;QAE1F,OAAO,YAAY,CAAC,aAAa,CAAC,GAAG,MAAM,KAAK,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;IAC5E,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,YAAY,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC;IACjD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,MAAiB,EAAE,GAAgB;IACvE,MAAM,CAAC,YAAY,CACjB,YAAY,EACZ;QACE,KAAK,EAAE,oBAAoB;QAC3B,WAAW,EACT,wPAAwP;QAC1P,WAAW,EAAE;YACX,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,KAAK;SACrB;KACF,EACD,KAAK,IAAI,EAAE,CAAC,cAAc,CAAC,MAAM,YAAY,CAAC,GAAG,CAAC,CAAC,CACpD,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `owners` MCP tool — return ranked `OWNED_BY` contributors for a node.
|
|
3
|
+
*
|
|
4
|
+
* Accepts any node id (File, Symbol, Community) and walks the outgoing
|
|
5
|
+
* `OWNED_BY` edges in confidence-descending order. Each row includes the
|
|
6
|
+
* contributor's email hash, display name, the raw line share (`weight`),
|
|
7
|
+
* and, when present in the graph, the plain email (opt-in; hashed by
|
|
8
|
+
* default per the ownership phase's privacy rules).
|
|
9
|
+
*
|
|
10
|
+
* Read-only, idempotent, closed-world.
|
|
11
|
+
*/
|
|
12
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
13
|
+
import { type ToolContext, type ToolResult } from "./shared.js";
|
|
14
|
+
interface OwnersArgs {
|
|
15
|
+
readonly target: string;
|
|
16
|
+
readonly repo?: string | undefined;
|
|
17
|
+
readonly repo_uri?: string | undefined;
|
|
18
|
+
readonly limit?: number | undefined;
|
|
19
|
+
}
|
|
20
|
+
export declare function runOwners(ctx: ToolContext, args: OwnersArgs): Promise<ToolResult>;
|
|
21
|
+
export declare function registerOwnersTool(server: McpServer, ctx: ToolContext): void;
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=owners.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"owners.d.ts","sourceRoot":"","sources":["../../src/tools/owners.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKzE,OAAO,EAGL,KAAK,WAAW,EAChB,KAAK,UAAU,EAGhB,MAAM,aAAa,CAAC;AA0BrB,UAAU,UAAU;IAClB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,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;CACrC;AAED,wBAAsB,SAAS,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAgEvF;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,GAAG,IAAI,CAiB5E"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `owners` MCP tool — return ranked `OWNED_BY` contributors for a node.
|
|
3
|
+
*
|
|
4
|
+
* Accepts any node id (File, Symbol, Community) and walks the outgoing
|
|
5
|
+
* `OWNED_BY` edges in confidence-descending order. Each row includes the
|
|
6
|
+
* contributor's email hash, display name, the raw line share (`weight`),
|
|
7
|
+
* and, when present in the graph, the plain email (opt-in; hashed by
|
|
8
|
+
* default per the ownership phase's privacy rules).
|
|
9
|
+
*
|
|
10
|
+
* Read-only, idempotent, closed-world.
|
|
11
|
+
*/
|
|
12
|
+
// biome-ignore-all lint/complexity/useLiteralKeys: dot-access disallowed on Record index signatures
|
|
13
|
+
import { z } from "zod";
|
|
14
|
+
import { toolErrorFromUnknown } from "../error-envelope.js";
|
|
15
|
+
import { withNextSteps } from "../next-step-hints.js";
|
|
16
|
+
import { stalenessFromMeta } from "../staleness.js";
|
|
17
|
+
import { fromToolResult, repoArgShape, toToolResult, withStore, } from "./shared.js";
|
|
18
|
+
const OwnersInput = {
|
|
19
|
+
target: z
|
|
20
|
+
.string()
|
|
21
|
+
.min(1)
|
|
22
|
+
.describe("Node id of a File, Symbol, or Community to query for ownership. Must be a fully-qualified node id (e.g. 'File:src/app.ts:src/app.ts')."),
|
|
23
|
+
...repoArgShape,
|
|
24
|
+
limit: z
|
|
25
|
+
.number()
|
|
26
|
+
.int()
|
|
27
|
+
.positive()
|
|
28
|
+
.max(100)
|
|
29
|
+
.optional()
|
|
30
|
+
.describe("Maximum number of contributors to return (default 20, max 100)."),
|
|
31
|
+
};
|
|
32
|
+
export async function runOwners(ctx, args) {
|
|
33
|
+
const limit = args.limit ?? 20;
|
|
34
|
+
const call = await withStore(ctx, args, async (store, resolved) => {
|
|
35
|
+
try {
|
|
36
|
+
const graph = store.graph;
|
|
37
|
+
const ownedBy = await graph.listEdgesByType("OWNED_BY", { fromIds: [args.target] });
|
|
38
|
+
const sorted = [...ownedBy].sort((a, b) => {
|
|
39
|
+
const ac = a.confidence ?? 0;
|
|
40
|
+
const bc = b.confidence ?? 0;
|
|
41
|
+
if (ac !== bc)
|
|
42
|
+
return bc - ac;
|
|
43
|
+
return a.to < b.to ? -1 : a.to > b.to ? 1 : 0;
|
|
44
|
+
});
|
|
45
|
+
const sliced = sorted.slice(0, limit);
|
|
46
|
+
const contributors = await graph.listNodesByKind("Contributor");
|
|
47
|
+
const contribById = new Map();
|
|
48
|
+
for (const c of contributors)
|
|
49
|
+
contribById.set(c.id, c);
|
|
50
|
+
const owners = [];
|
|
51
|
+
for (const edge of sliced) {
|
|
52
|
+
const c = contribById.get(edge.to);
|
|
53
|
+
if (c === undefined)
|
|
54
|
+
continue;
|
|
55
|
+
const plain = typeof c.emailPlain === "string" ? c.emailPlain : "";
|
|
56
|
+
owners.push({
|
|
57
|
+
email: plain,
|
|
58
|
+
emailHash: c.emailHash,
|
|
59
|
+
name: c.name,
|
|
60
|
+
weight: edge.confidence ?? 0,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
const header = `Owners for ${args.target} in ${resolved.name} (${owners.length}):`;
|
|
64
|
+
const body = owners.length === 0
|
|
65
|
+
? "(no OWNED_BY edges for this target — either the target id is unknown or the ownership phase has not run. Re-index with `codehub analyze --force`.)"
|
|
66
|
+
: owners
|
|
67
|
+
.map((o) => {
|
|
68
|
+
const id = o.email.length > 0 ? o.email : `sha256:${o.emailHash.slice(0, 10)}…`;
|
|
69
|
+
const name = o.name.length > 0 ? o.name : "unknown";
|
|
70
|
+
return `- ${name} <${id}> weight=${o.weight.toFixed(3)}`;
|
|
71
|
+
})
|
|
72
|
+
.join("\n");
|
|
73
|
+
const next = owners.length === 0
|
|
74
|
+
? [
|
|
75
|
+
"call `query` with the target's name to check it is indexed",
|
|
76
|
+
"re-index with `codehub analyze --force` to emit OWNED_BY edges",
|
|
77
|
+
]
|
|
78
|
+
: [
|
|
79
|
+
"call `context` on the top owner to see what else they maintain",
|
|
80
|
+
"call `impact` on the target to correlate ownership with blast radius",
|
|
81
|
+
];
|
|
82
|
+
return withNextSteps(`${header}\n${body}`, { owners, total: owners.length }, next, stalenessFromMeta(resolved.meta));
|
|
83
|
+
}
|
|
84
|
+
catch (err) {
|
|
85
|
+
return toolErrorFromUnknown(err);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
return toToolResult(call);
|
|
89
|
+
}
|
|
90
|
+
export function registerOwnersTool(server, ctx) {
|
|
91
|
+
server.registerTool("owners", {
|
|
92
|
+
title: "List owners for a node",
|
|
93
|
+
description: "Enumerate the ranked set of Contributors linked to a node via OWNED_BY edges. Source is git blame; emails are SHA-256 hashed by default (plain emails only when ingestion ran with --plain-emails).",
|
|
94
|
+
inputSchema: OwnersInput,
|
|
95
|
+
annotations: {
|
|
96
|
+
readOnlyHint: true,
|
|
97
|
+
destructiveHint: false,
|
|
98
|
+
openWorldHint: false,
|
|
99
|
+
idempotentHint: true,
|
|
100
|
+
},
|
|
101
|
+
}, async (args) => fromToolResult(await runOwners(ctx, args)));
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=owners.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"owners.js","sourceRoot":"","sources":["../../src/tools/owners.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `pack_codebase` — produce a snapshot of a registered repo for an LLM
|
|
3
|
+
* to consume.
|
|
4
|
+
*
|
|
5
|
+
* Two engines are supported via the `engine` input field:
|
|
6
|
+
* - `pack` (DEFAULT) — `@opencodehub/pack`'s deterministic 9-item BOM
|
|
7
|
+
* written to `<repo>/.codehub/packs/<packHash>/`. The BOM is what
|
|
8
|
+
* downstream agents should consume — it carries skeleton + file-tree
|
|
9
|
+
* + deps + ast-chunks + xrefs + findings + licenses + readme +
|
|
10
|
+
* optional embeddings.parquet, all bound by a manifest with a
|
|
11
|
+
* content-addressed `pack_hash`.
|
|
12
|
+
* - `repomix` — the legacy single-file XML/Markdown snapshot under
|
|
13
|
+
* `<repo>/.codehub/pack/repo.<ext>`. Retained as an opt-in for one
|
|
14
|
+
* milestone (drop deferred to M7 per spec 005 Q-DELTA-6). Operators
|
|
15
|
+
* who relied on repomix for raw repo packing keep a stable path.
|
|
16
|
+
*
|
|
17
|
+
* For relational/structural questions about the repo, prefer
|
|
18
|
+
* `query`/`context`/`impact` — those are backed by the SCIP graph and
|
|
19
|
+
* give graph-aware answers without consuming context window.
|
|
20
|
+
*/
|
|
21
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
22
|
+
import { z } from "zod";
|
|
23
|
+
import { type ToolContext, type ToolResult } from "./shared.js";
|
|
24
|
+
/** Default token budget passed to the pack engine when `budget` is omitted. */
|
|
25
|
+
export declare const DEFAULT_PACK_BUDGET = 100000;
|
|
26
|
+
/** Default tokenizer identifier when `tokenizer` is omitted. */
|
|
27
|
+
export declare const DEFAULT_PACK_TOKENIZER = "openai:o200k_base@tiktoken-0.8.0";
|
|
28
|
+
declare const PackInput: z.ZodObject<{
|
|
29
|
+
repo: z.ZodOptional<z.ZodString>;
|
|
30
|
+
repo_uri: z.ZodOptional<z.ZodString>;
|
|
31
|
+
engine: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
|
|
32
|
+
pack: "pack";
|
|
33
|
+
repomix: "repomix";
|
|
34
|
+
}>>>;
|
|
35
|
+
budget: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
36
|
+
tokenizer: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
37
|
+
style: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
|
|
38
|
+
xml: "xml";
|
|
39
|
+
markdown: "markdown";
|
|
40
|
+
json: "json";
|
|
41
|
+
plain: "plain";
|
|
42
|
+
}>>>;
|
|
43
|
+
compress: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
44
|
+
removeComments: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
45
|
+
}, z.core.$strip>;
|
|
46
|
+
type PackInput = z.infer<typeof PackInput>;
|
|
47
|
+
/**
|
|
48
|
+
* Test seam — overrides for the engine implementations. Production
|
|
49
|
+
* callers leave these unset; tests inject `runCodePack` / `runRepomix`
|
|
50
|
+
* stubs to avoid native bindings + npx network calls.
|
|
51
|
+
*/
|
|
52
|
+
export interface PackCodebaseDeps {
|
|
53
|
+
readonly _runPackEngine?: (args: {
|
|
54
|
+
repo: string;
|
|
55
|
+
budget: number;
|
|
56
|
+
tokenizer: string;
|
|
57
|
+
}) => Promise<{
|
|
58
|
+
outDir: string;
|
|
59
|
+
packHash: string;
|
|
60
|
+
bomItemCount: number;
|
|
61
|
+
}>;
|
|
62
|
+
readonly _runRepomixEngine?: (args: {
|
|
63
|
+
repoPath: string;
|
|
64
|
+
style: "xml" | "markdown" | "json" | "plain";
|
|
65
|
+
compress: boolean;
|
|
66
|
+
removeComments: boolean;
|
|
67
|
+
}) => Promise<{
|
|
68
|
+
outputPath: string;
|
|
69
|
+
bytes: number;
|
|
70
|
+
durationMs: number;
|
|
71
|
+
}>;
|
|
72
|
+
}
|
|
73
|
+
export declare function runPackCodebase(ctx: ToolContext, input: PackInput, deps?: PackCodebaseDeps): Promise<ToolResult>;
|
|
74
|
+
export declare function registerPackCodebaseTool(server: McpServer, ctx: ToolContext): void;
|
|
75
|
+
export {};
|
|
76
|
+
//# sourceMappingURL=pack-codebase.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pack-codebase.d.ts","sourceRoot":"","sources":["../../src/tools/pack-codebase.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAMH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,EAAkB,KAAK,WAAW,EAAE,KAAK,UAAU,EAAgB,MAAM,aAAa,CAAC;AAI9F,+EAA+E;AAC/E,eAAO,MAAM,mBAAmB,SAAU,CAAC;AAE3C,gEAAgE;AAChE,eAAO,MAAM,sBAAsB,qCAAqC,CAAC;AAEzE,QAAA,MAAM,SAAS;;;;;;;;;;;;;;;;;iBAoDb,CAAC;AACH,KAAK,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAC;AAE3C;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC;QAC/F,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC,CAAC;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE;QAClC,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,KAAK,GAAG,UAAU,GAAG,MAAM,GAAG,OAAO,CAAC;QAC7C,QAAQ,EAAE,OAAO,CAAC;QAClB,cAAc,EAAE,OAAO,CAAC;KACzB,KAAK,OAAO,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC1E;AAED,wBAAsB,eAAe,CACnC,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,SAAS,EAChB,IAAI,GAAE,gBAAqB,GAC1B,OAAO,CAAC,UAAU,CAAC,CAoBrB;AA6MD,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,GAAG,IAAI,CAsBlF"}
|