@jafreck/lore 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/LICENSE +21 -0
- package/README.md +405 -0
- package/dist/cli.d.ts +19 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +345 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/indexer/call-graph.d.ts +39 -0
- package/dist/indexer/call-graph.d.ts.map +1 -0
- package/dist/indexer/call-graph.js +193 -0
- package/dist/indexer/call-graph.js.map +1 -0
- package/dist/indexer/complexity.d.ts +9 -0
- package/dist/indexer/complexity.d.ts.map +1 -0
- package/dist/indexer/complexity.js +66 -0
- package/dist/indexer/complexity.js.map +1 -0
- package/dist/indexer/config-parser.d.ts +16 -0
- package/dist/indexer/config-parser.d.ts.map +1 -0
- package/dist/indexer/config-parser.js +261 -0
- package/dist/indexer/config-parser.js.map +1 -0
- package/dist/indexer/coverage.d.ts +13 -0
- package/dist/indexer/coverage.d.ts.map +1 -0
- package/dist/indexer/coverage.js +84 -0
- package/dist/indexer/coverage.js.map +1 -0
- package/dist/indexer/db.d.ts +38 -0
- package/dist/indexer/db.d.ts.map +1 -0
- package/dist/indexer/db.js +275 -0
- package/dist/indexer/db.js.map +1 -0
- package/dist/indexer/embedder.d.ts +70 -0
- package/dist/indexer/embedder.d.ts.map +1 -0
- package/dist/indexer/embedder.js +186 -0
- package/dist/indexer/embedder.js.map +1 -0
- package/dist/indexer/ensure-python-deps.d.ts +22 -0
- package/dist/indexer/ensure-python-deps.d.ts.map +1 -0
- package/dist/indexer/ensure-python-deps.js +47 -0
- package/dist/indexer/ensure-python-deps.js.map +1 -0
- package/dist/indexer/extractors/bash.d.ts +12 -0
- package/dist/indexer/extractors/bash.d.ts.map +1 -0
- package/dist/indexer/extractors/bash.js +57 -0
- package/dist/indexer/extractors/bash.js.map +1 -0
- package/dist/indexer/extractors/c.d.ts +12 -0
- package/dist/indexer/extractors/c.d.ts.map +1 -0
- package/dist/indexer/extractors/c.js +106 -0
- package/dist/indexer/extractors/c.js.map +1 -0
- package/dist/indexer/extractors/cpp.d.ts +12 -0
- package/dist/indexer/extractors/cpp.d.ts.map +1 -0
- package/dist/indexer/extractors/cpp.js +84 -0
- package/dist/indexer/extractors/cpp.js.map +1 -0
- package/dist/indexer/extractors/csharp.d.ts +12 -0
- package/dist/indexer/extractors/csharp.d.ts.map +1 -0
- package/dist/indexer/extractors/csharp.js +79 -0
- package/dist/indexer/extractors/csharp.js.map +1 -0
- package/dist/indexer/extractors/dart.d.ts +12 -0
- package/dist/indexer/extractors/dart.d.ts.map +1 -0
- package/dist/indexer/extractors/dart.js +80 -0
- package/dist/indexer/extractors/dart.js.map +1 -0
- package/dist/indexer/extractors/elixir.d.ts +12 -0
- package/dist/indexer/extractors/elixir.d.ts.map +1 -0
- package/dist/indexer/extractors/elixir.js +87 -0
- package/dist/indexer/extractors/elixir.js.map +1 -0
- package/dist/indexer/extractors/elm.d.ts +12 -0
- package/dist/indexer/extractors/elm.d.ts.map +1 -0
- package/dist/indexer/extractors/elm.js +87 -0
- package/dist/indexer/extractors/elm.js.map +1 -0
- package/dist/indexer/extractors/go.d.ts +12 -0
- package/dist/indexer/extractors/go.d.ts.map +1 -0
- package/dist/indexer/extractors/go.js +158 -0
- package/dist/indexer/extractors/go.js.map +1 -0
- package/dist/indexer/extractors/haskell.d.ts +12 -0
- package/dist/indexer/extractors/haskell.d.ts.map +1 -0
- package/dist/indexer/extractors/haskell.js +104 -0
- package/dist/indexer/extractors/haskell.js.map +1 -0
- package/dist/indexer/extractors/java.d.ts +12 -0
- package/dist/indexer/extractors/java.d.ts.map +1 -0
- package/dist/indexer/extractors/java.js +68 -0
- package/dist/indexer/extractors/java.js.map +1 -0
- package/dist/indexer/extractors/javascript.d.ts +13 -0
- package/dist/indexer/extractors/javascript.d.ts.map +1 -0
- package/dist/indexer/extractors/javascript.js +180 -0
- package/dist/indexer/extractors/javascript.js.map +1 -0
- package/dist/indexer/extractors/julia.d.ts +12 -0
- package/dist/indexer/extractors/julia.d.ts.map +1 -0
- package/dist/indexer/extractors/julia.js +94 -0
- package/dist/indexer/extractors/julia.js.map +1 -0
- package/dist/indexer/extractors/kotlin.d.ts +12 -0
- package/dist/indexer/extractors/kotlin.d.ts.map +1 -0
- package/dist/indexer/extractors/kotlin.js +71 -0
- package/dist/indexer/extractors/kotlin.js.map +1 -0
- package/dist/indexer/extractors/lua.d.ts +12 -0
- package/dist/indexer/extractors/lua.d.ts.map +1 -0
- package/dist/indexer/extractors/lua.js +68 -0
- package/dist/indexer/extractors/lua.js.map +1 -0
- package/dist/indexer/extractors/objc.d.ts +12 -0
- package/dist/indexer/extractors/objc.d.ts.map +1 -0
- package/dist/indexer/extractors/objc.js +129 -0
- package/dist/indexer/extractors/objc.js.map +1 -0
- package/dist/indexer/extractors/ocaml.d.ts +12 -0
- package/dist/indexer/extractors/ocaml.d.ts.map +1 -0
- package/dist/indexer/extractors/ocaml.js +92 -0
- package/dist/indexer/extractors/ocaml.js.map +1 -0
- package/dist/indexer/extractors/php.d.ts +12 -0
- package/dist/indexer/extractors/php.d.ts.map +1 -0
- package/dist/indexer/extractors/php.js +99 -0
- package/dist/indexer/extractors/php.js.map +1 -0
- package/dist/indexer/extractors/python.d.ts +12 -0
- package/dist/indexer/extractors/python.d.ts.map +1 -0
- package/dist/indexer/extractors/python.js +129 -0
- package/dist/indexer/extractors/python.js.map +1 -0
- package/dist/indexer/extractors/ruby.d.ts +12 -0
- package/dist/indexer/extractors/ruby.d.ts.map +1 -0
- package/dist/indexer/extractors/ruby.js +100 -0
- package/dist/indexer/extractors/ruby.js.map +1 -0
- package/dist/indexer/extractors/rust.d.ts +12 -0
- package/dist/indexer/extractors/rust.d.ts.map +1 -0
- package/dist/indexer/extractors/rust.js +82 -0
- package/dist/indexer/extractors/rust.js.map +1 -0
- package/dist/indexer/extractors/scala.d.ts +12 -0
- package/dist/indexer/extractors/scala.d.ts.map +1 -0
- package/dist/indexer/extractors/scala.js +91 -0
- package/dist/indexer/extractors/scala.js.map +1 -0
- package/dist/indexer/extractors/swift.d.ts +12 -0
- package/dist/indexer/extractors/swift.d.ts.map +1 -0
- package/dist/indexer/extractors/swift.js +90 -0
- package/dist/indexer/extractors/swift.js.map +1 -0
- package/dist/indexer/extractors/types.d.ts +118 -0
- package/dist/indexer/extractors/types.d.ts.map +1 -0
- package/dist/indexer/extractors/types.js +43 -0
- package/dist/indexer/extractors/types.js.map +1 -0
- package/dist/indexer/extractors/typescript.d.ts +14 -0
- package/dist/indexer/extractors/typescript.d.ts.map +1 -0
- package/dist/indexer/extractors/typescript.js +172 -0
- package/dist/indexer/extractors/typescript.js.map +1 -0
- package/dist/indexer/extractors/zig.d.ts +12 -0
- package/dist/indexer/extractors/zig.d.ts.map +1 -0
- package/dist/indexer/extractors/zig.js +95 -0
- package/dist/indexer/extractors/zig.js.map +1 -0
- package/dist/indexer/git-history.d.ts +23 -0
- package/dist/indexer/git-history.d.ts.map +1 -0
- package/dist/indexer/git-history.js +144 -0
- package/dist/indexer/git-history.js.map +1 -0
- package/dist/indexer/git-hooks.d.ts +19 -0
- package/dist/indexer/git-hooks.d.ts.map +1 -0
- package/dist/indexer/git-hooks.js +74 -0
- package/dist/indexer/git-hooks.js.map +1 -0
- package/dist/indexer/index.d.ts +83 -0
- package/dist/indexer/index.d.ts.map +1 -0
- package/dist/indexer/index.js +431 -0
- package/dist/indexer/index.js.map +1 -0
- package/dist/indexer/parser.d.ts +30 -0
- package/dist/indexer/parser.d.ts.map +1 -0
- package/dist/indexer/parser.js +114 -0
- package/dist/indexer/parser.js.map +1 -0
- package/dist/indexer/poller.d.ts +50 -0
- package/dist/indexer/poller.d.ts.map +1 -0
- package/dist/indexer/poller.js +140 -0
- package/dist/indexer/poller.js.map +1 -0
- package/dist/indexer/resolver.d.ts +52 -0
- package/dist/indexer/resolver.d.ts.map +1 -0
- package/dist/indexer/resolver.js +271 -0
- package/dist/indexer/resolver.js.map +1 -0
- package/dist/indexer/test-mapper.d.ts +6 -0
- package/dist/indexer/test-mapper.d.ts.map +1 -0
- package/dist/indexer/test-mapper.js +48 -0
- package/dist/indexer/test-mapper.js.map +1 -0
- package/dist/indexer/walker.d.ts +51 -0
- package/dist/indexer/walker.d.ts.map +1 -0
- package/dist/indexer/walker.js +100 -0
- package/dist/indexer/walker.js.map +1 -0
- package/dist/indexer/watcher.d.ts +51 -0
- package/dist/indexer/watcher.d.ts.map +1 -0
- package/dist/indexer/watcher.js +107 -0
- package/dist/indexer/watcher.js.map +1 -0
- package/dist/kb-server/db.d.ts +241 -0
- package/dist/kb-server/db.d.ts.map +1 -0
- package/dist/kb-server/db.js +659 -0
- package/dist/kb-server/db.js.map +1 -0
- package/dist/kb-server/server.d.ts +35 -0
- package/dist/kb-server/server.d.ts.map +1 -0
- package/dist/kb-server/server.js +240 -0
- package/dist/kb-server/server.js.map +1 -0
- package/dist/kb-server/tools/annotations.d.ts +40 -0
- package/dist/kb-server/tools/annotations.d.ts.map +1 -0
- package/dist/kb-server/tools/annotations.js +35 -0
- package/dist/kb-server/tools/annotations.js.map +1 -0
- package/dist/kb-server/tools/architecture.d.ts +60 -0
- package/dist/kb-server/tools/architecture.d.ts.map +1 -0
- package/dist/kb-server/tools/architecture.js +174 -0
- package/dist/kb-server/tools/architecture.js.map +1 -0
- package/dist/kb-server/tools/blame.d.ts +67 -0
- package/dist/kb-server/tools/blame.d.ts.map +1 -0
- package/dist/kb-server/tools/blame.js +162 -0
- package/dist/kb-server/tools/blame.js.map +1 -0
- package/dist/kb-server/tools/coverage.d.ts +67 -0
- package/dist/kb-server/tools/coverage.d.ts.map +1 -0
- package/dist/kb-server/tools/coverage.js +74 -0
- package/dist/kb-server/tools/coverage.js.map +1 -0
- package/dist/kb-server/tools/graph.d.ts +56 -0
- package/dist/kb-server/tools/graph.d.ts.map +1 -0
- package/dist/kb-server/tools/graph.js +188 -0
- package/dist/kb-server/tools/graph.js.map +1 -0
- package/dist/kb-server/tools/history.d.ts +47 -0
- package/dist/kb-server/tools/history.d.ts.map +1 -0
- package/dist/kb-server/tools/history.js +91 -0
- package/dist/kb-server/tools/history.js.map +1 -0
- package/dist/kb-server/tools/lookup.d.ts +36 -0
- package/dist/kb-server/tools/lookup.d.ts.map +1 -0
- package/dist/kb-server/tools/lookup.js +45 -0
- package/dist/kb-server/tools/lookup.js.map +1 -0
- package/dist/kb-server/tools/metrics.d.ts +73 -0
- package/dist/kb-server/tools/metrics.d.ts.map +1 -0
- package/dist/kb-server/tools/metrics.js +79 -0
- package/dist/kb-server/tools/metrics.js.map +1 -0
- package/dist/kb-server/tools/notes.d.ts +165 -0
- package/dist/kb-server/tools/notes.d.ts.map +1 -0
- package/dist/kb-server/tools/notes.js +175 -0
- package/dist/kb-server/tools/notes.js.map +1 -0
- package/dist/kb-server/tools/routes.d.ts +38 -0
- package/dist/kb-server/tools/routes.d.ts.map +1 -0
- package/dist/kb-server/tools/routes.js +38 -0
- package/dist/kb-server/tools/routes.js.map +1 -0
- package/dist/kb-server/tools/search.d.ts +60 -0
- package/dist/kb-server/tools/search.d.ts.map +1 -0
- package/dist/kb-server/tools/search.js +170 -0
- package/dist/kb-server/tools/search.js.map +1 -0
- package/dist/kb-server/tools/snippet.d.ts +44 -0
- package/dist/kb-server/tools/snippet.d.ts.map +1 -0
- package/dist/kb-server/tools/snippet.js +49 -0
- package/dist/kb-server/tools/snippet.js.map +1 -0
- package/dist/kb-server/tools/test-map.d.ts +38 -0
- package/dist/kb-server/tools/test-map.d.ts.map +1 -0
- package/dist/kb-server/tools/test-map.js +32 -0
- package/dist/kb-server/tools/test-map.js.map +1 -0
- package/dist/kb-server/tools/writeback.d.ts +49 -0
- package/dist/kb-server/tools/writeback.d.ts.map +1 -0
- package/dist/kb-server/tools/writeback.js +68 -0
- package/dist/kb-server/tools/writeback.js.map +1 -0
- package/package.json +92 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module kb-server/tools/blame
|
|
3
|
+
*
|
|
4
|
+
* MCP tool: line-level git blame for indexed files.
|
|
5
|
+
*/
|
|
6
|
+
import type { Database } from '../db.js';
|
|
7
|
+
export declare const toolDef: {
|
|
8
|
+
readonly name: "kb_blame";
|
|
9
|
+
readonly description: string;
|
|
10
|
+
readonly inputSchema: {
|
|
11
|
+
readonly type: "object";
|
|
12
|
+
readonly properties: {
|
|
13
|
+
readonly path: {
|
|
14
|
+
readonly type: "string";
|
|
15
|
+
readonly description: "Absolute file path as stored in the knowledge-base index.";
|
|
16
|
+
};
|
|
17
|
+
readonly line: {
|
|
18
|
+
readonly type: "number";
|
|
19
|
+
readonly description: "Single line number to blame (1-based).";
|
|
20
|
+
};
|
|
21
|
+
readonly start_line: {
|
|
22
|
+
readonly type: "number";
|
|
23
|
+
readonly description: "Range start line (1-based, inclusive).";
|
|
24
|
+
};
|
|
25
|
+
readonly end_line: {
|
|
26
|
+
readonly type: "number";
|
|
27
|
+
readonly description: "Range end line (1-based, inclusive). Defaults to start_line.";
|
|
28
|
+
};
|
|
29
|
+
readonly ref: {
|
|
30
|
+
readonly type: "string";
|
|
31
|
+
readonly description: "Git ref to blame against (default: HEAD).";
|
|
32
|
+
};
|
|
33
|
+
readonly branch: {
|
|
34
|
+
readonly type: "string";
|
|
35
|
+
readonly description: "Optional indexed branch to disambiguate file lookup.";
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
readonly required: readonly ["path"];
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
export interface BlameArgs {
|
|
42
|
+
path: string;
|
|
43
|
+
line?: number;
|
|
44
|
+
start_line?: number;
|
|
45
|
+
end_line?: number;
|
|
46
|
+
ref?: string;
|
|
47
|
+
branch?: string;
|
|
48
|
+
}
|
|
49
|
+
export interface BlameLine {
|
|
50
|
+
line: number;
|
|
51
|
+
commit_sha: string;
|
|
52
|
+
author: string;
|
|
53
|
+
author_email: string;
|
|
54
|
+
timestamp: number;
|
|
55
|
+
summary: string;
|
|
56
|
+
text: string;
|
|
57
|
+
}
|
|
58
|
+
export interface BlameResult {
|
|
59
|
+
path: string;
|
|
60
|
+
ref: string;
|
|
61
|
+
start_line: number;
|
|
62
|
+
end_line: number;
|
|
63
|
+
lines: BlameLine[];
|
|
64
|
+
}
|
|
65
|
+
/** Resolve repository root and execute `git blame --line-porcelain` for the requested range. */
|
|
66
|
+
export declare function handler(db: Database.Database, args: BlameArgs): BlameResult;
|
|
67
|
+
//# sourceMappingURL=blame.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blame.d.ts","sourceRoot":"","sources":["../../../src/kb-server/tools/blame.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAKzC,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmCV,CAAC;AAIX,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,SAAS,EAAE,CAAC;CACpB;AA2FD,gGAAgG;AAChG,wBAAgB,OAAO,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,SAAS,GAAG,WAAW,CAsD3E"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module kb-server/tools/blame
|
|
3
|
+
*
|
|
4
|
+
* MCP tool: line-level git blame for indexed files.
|
|
5
|
+
*/
|
|
6
|
+
import { execFileSync } from 'node:child_process';
|
|
7
|
+
import { dirname, relative } from 'node:path';
|
|
8
|
+
import { getFileByPath } from '../db.js';
|
|
9
|
+
// ─── Tool definition ──────────────────────────────────────────────────────────
|
|
10
|
+
export const toolDef = {
|
|
11
|
+
name: 'kb_blame',
|
|
12
|
+
description: 'Return git blame metadata for a file and line (or line range). ' +
|
|
13
|
+
'The file path must exist in the indexed knowledge base.',
|
|
14
|
+
inputSchema: {
|
|
15
|
+
type: 'object',
|
|
16
|
+
properties: {
|
|
17
|
+
path: {
|
|
18
|
+
type: 'string',
|
|
19
|
+
description: 'Absolute file path as stored in the knowledge-base index.',
|
|
20
|
+
},
|
|
21
|
+
line: {
|
|
22
|
+
type: 'number',
|
|
23
|
+
description: 'Single line number to blame (1-based).',
|
|
24
|
+
},
|
|
25
|
+
start_line: {
|
|
26
|
+
type: 'number',
|
|
27
|
+
description: 'Range start line (1-based, inclusive).',
|
|
28
|
+
},
|
|
29
|
+
end_line: {
|
|
30
|
+
type: 'number',
|
|
31
|
+
description: 'Range end line (1-based, inclusive). Defaults to start_line.',
|
|
32
|
+
},
|
|
33
|
+
ref: {
|
|
34
|
+
type: 'string',
|
|
35
|
+
description: 'Git ref to blame against (default: HEAD).',
|
|
36
|
+
},
|
|
37
|
+
branch: {
|
|
38
|
+
type: 'string',
|
|
39
|
+
description: 'Optional indexed branch to disambiguate file lookup.',
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
required: ['path'],
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
function resolveRange(args) {
|
|
46
|
+
if (args.line != null) {
|
|
47
|
+
const line = Math.max(1, Math.floor(args.line));
|
|
48
|
+
return { start: line, end: line };
|
|
49
|
+
}
|
|
50
|
+
if (args.start_line != null || args.end_line != null) {
|
|
51
|
+
const start = Math.max(1, Math.floor(args.start_line ?? args.end_line ?? 1));
|
|
52
|
+
const end = Math.max(start, Math.floor(args.end_line ?? start));
|
|
53
|
+
return { start, end };
|
|
54
|
+
}
|
|
55
|
+
throw new Error('Provide either `line` or `start_line`/`end_line`.');
|
|
56
|
+
}
|
|
57
|
+
function parseBlamePorcelain(output) {
|
|
58
|
+
const lines = output.split('\n');
|
|
59
|
+
const results = [];
|
|
60
|
+
const metaBySha = new Map();
|
|
61
|
+
let currentSha = '';
|
|
62
|
+
let currentFinalLine = 0;
|
|
63
|
+
let remainingSourceLines = 0;
|
|
64
|
+
for (const rawLine of lines) {
|
|
65
|
+
const headerMatch = rawLine.match(/^([^\s]+)\s+\d+\s+(\d+)\s+(\d+)$/);
|
|
66
|
+
if (headerMatch) {
|
|
67
|
+
currentSha = headerMatch[1] ?? '';
|
|
68
|
+
currentFinalLine = parseInt(headerMatch[2] ?? '0', 10);
|
|
69
|
+
remainingSourceLines = parseInt(headerMatch[3] ?? '0', 10);
|
|
70
|
+
if (!metaBySha.has(currentSha))
|
|
71
|
+
metaBySha.set(currentSha, {});
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
if (!currentSha)
|
|
75
|
+
continue;
|
|
76
|
+
const meta = metaBySha.get(currentSha) ?? {};
|
|
77
|
+
if (rawLine.startsWith('author ')) {
|
|
78
|
+
meta.author = rawLine.slice('author '.length);
|
|
79
|
+
metaBySha.set(currentSha, meta);
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
if (rawLine.startsWith('author-mail ')) {
|
|
83
|
+
meta.author_email = rawLine.slice('author-mail '.length).replace(/^<|>$/g, '');
|
|
84
|
+
metaBySha.set(currentSha, meta);
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
if (rawLine.startsWith('author-time ')) {
|
|
88
|
+
const ts = parseInt(rawLine.slice('author-time '.length), 10);
|
|
89
|
+
if (Number.isFinite(ts))
|
|
90
|
+
meta.timestamp = ts;
|
|
91
|
+
metaBySha.set(currentSha, meta);
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
if (rawLine.startsWith('summary ')) {
|
|
95
|
+
meta.summary = rawLine.slice('summary '.length);
|
|
96
|
+
metaBySha.set(currentSha, meta);
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
if (rawLine.startsWith('\t') && remainingSourceLines > 0) {
|
|
100
|
+
results.push({
|
|
101
|
+
line: currentFinalLine,
|
|
102
|
+
commit_sha: currentSha,
|
|
103
|
+
author: meta.author ?? 'unknown',
|
|
104
|
+
author_email: meta.author_email ?? '',
|
|
105
|
+
timestamp: meta.timestamp ?? 0,
|
|
106
|
+
summary: meta.summary ?? '',
|
|
107
|
+
text: rawLine.slice(1),
|
|
108
|
+
});
|
|
109
|
+
currentFinalLine += 1;
|
|
110
|
+
remainingSourceLines -= 1;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return results;
|
|
114
|
+
}
|
|
115
|
+
/** Resolve repository root and execute `git blame --line-porcelain` for the requested range. */
|
|
116
|
+
export function handler(db, args) {
|
|
117
|
+
const fileRow = getFileByPath(db, args.path, args.branch);
|
|
118
|
+
if (!fileRow) {
|
|
119
|
+
throw new Error(`File not found in index: ${args.path}`);
|
|
120
|
+
}
|
|
121
|
+
const { start, end } = resolveRange(args);
|
|
122
|
+
const ref = args.ref?.trim() || 'HEAD';
|
|
123
|
+
let repoRoot = '';
|
|
124
|
+
try {
|
|
125
|
+
repoRoot = execFileSync('git', ['-C', dirname(args.path), 'rev-parse', '--show-toplevel'], {
|
|
126
|
+
encoding: 'utf8',
|
|
127
|
+
}).trim();
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
throw new Error(`Unable to resolve git repository root for path: ${args.path}`);
|
|
131
|
+
}
|
|
132
|
+
const relPath = relative(repoRoot, args.path);
|
|
133
|
+
if (relPath.startsWith('..')) {
|
|
134
|
+
throw new Error(`Path is outside git repository root: ${args.path}`);
|
|
135
|
+
}
|
|
136
|
+
let output = '';
|
|
137
|
+
try {
|
|
138
|
+
output = execFileSync('git', [
|
|
139
|
+
'-C',
|
|
140
|
+
repoRoot,
|
|
141
|
+
'blame',
|
|
142
|
+
'--line-porcelain',
|
|
143
|
+
'-L',
|
|
144
|
+
`${start},${end}`,
|
|
145
|
+
ref,
|
|
146
|
+
'--',
|
|
147
|
+
relPath,
|
|
148
|
+
], { encoding: 'utf8' });
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
throw new Error(`git blame failed for ${args.path}:${start}-${end} at ref ${ref}.`);
|
|
152
|
+
}
|
|
153
|
+
const parsed = parseBlamePorcelain(output);
|
|
154
|
+
return {
|
|
155
|
+
path: args.path,
|
|
156
|
+
ref,
|
|
157
|
+
start_line: start,
|
|
158
|
+
end_line: end,
|
|
159
|
+
lines: parsed,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=blame.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blame.js","sourceRoot":"","sources":["../../../src/kb-server/tools/blame.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module kb-server/tools/coverage
|
|
3
|
+
*
|
|
4
|
+
* MCP tool: query symbol-level coverage and coverage staleness metadata.
|
|
5
|
+
*/
|
|
6
|
+
import type { Database } from '../db.js';
|
|
7
|
+
export declare const toolDef: {
|
|
8
|
+
readonly name: "kb_coverage";
|
|
9
|
+
readonly description: string;
|
|
10
|
+
readonly inputSchema: {
|
|
11
|
+
readonly type: "object";
|
|
12
|
+
readonly properties: {
|
|
13
|
+
readonly symbol_id: {
|
|
14
|
+
readonly type: "number";
|
|
15
|
+
readonly description: "Optional symbol id to fetch exact coverage for.";
|
|
16
|
+
};
|
|
17
|
+
readonly symbol_name: {
|
|
18
|
+
readonly type: "string";
|
|
19
|
+
readonly description: "Optional symbol name filter (case-insensitive).";
|
|
20
|
+
};
|
|
21
|
+
readonly path: {
|
|
22
|
+
readonly type: "string";
|
|
23
|
+
readonly description: "Optional file path filter.";
|
|
24
|
+
};
|
|
25
|
+
readonly branch: {
|
|
26
|
+
readonly type: "string";
|
|
27
|
+
readonly description: "Optional branch filter.";
|
|
28
|
+
};
|
|
29
|
+
readonly limit: {
|
|
30
|
+
readonly type: "number";
|
|
31
|
+
readonly description: "Maximum symbols to return (default 50).";
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
readonly required: readonly [];
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
export interface CoverageArgs {
|
|
38
|
+
symbol_id?: number;
|
|
39
|
+
symbol_name?: string;
|
|
40
|
+
path?: string;
|
|
41
|
+
branch?: string;
|
|
42
|
+
limit?: number;
|
|
43
|
+
}
|
|
44
|
+
export interface CoverageSymbolResult {
|
|
45
|
+
symbol_id: number;
|
|
46
|
+
symbol_name: string;
|
|
47
|
+
file_path: string;
|
|
48
|
+
start_line: number;
|
|
49
|
+
end_line: number;
|
|
50
|
+
total_lines: number;
|
|
51
|
+
covered_lines: number;
|
|
52
|
+
uncovered_lines: number[];
|
|
53
|
+
coverage_percent: number | null;
|
|
54
|
+
}
|
|
55
|
+
export interface CoverageResult {
|
|
56
|
+
coverage_available: boolean;
|
|
57
|
+
coverage_commit: string | null;
|
|
58
|
+
current_commit: string | null;
|
|
59
|
+
commits_behind: number;
|
|
60
|
+
stale: boolean;
|
|
61
|
+
global_lines_found: number | null;
|
|
62
|
+
global_lines_hit: number | null;
|
|
63
|
+
global_coverage_percent: number | null;
|
|
64
|
+
symbols: CoverageSymbolResult[];
|
|
65
|
+
}
|
|
66
|
+
export declare function handler(db: Database.Database, args: CoverageArgs): CoverageResult;
|
|
67
|
+
//# sourceMappingURL=coverage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coverage.d.ts","sourceRoot":"","sources":["../../../src/kb-server/tools/coverage.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AASzC,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+BV,CAAC;AAEX,MAAM,WAAW,YAAY;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED,MAAM,WAAW,cAAc;IAC7B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,OAAO,CAAC;IACf,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,uBAAuB,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,OAAO,EAAE,oBAAoB,EAAE,CAAC;CACjC;AAID,wBAAgB,OAAO,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,cAAc,CAoCjF"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module kb-server/tools/coverage
|
|
3
|
+
*
|
|
4
|
+
* MCP tool: query symbol-level coverage and coverage staleness metadata.
|
|
5
|
+
*/
|
|
6
|
+
import { getCoverageStaleness, getLatestCoverageRun, getLatestCoverageTotals, getSymbolCoverageAggregates, getSymbolsByName, } from '../db.js';
|
|
7
|
+
export const toolDef = {
|
|
8
|
+
name: 'kb_coverage',
|
|
9
|
+
description: 'Return symbol-level coverage percentages, uncovered lines, and staleness metadata ' +
|
|
10
|
+
'for the latest ingested coverage run.',
|
|
11
|
+
inputSchema: {
|
|
12
|
+
type: 'object',
|
|
13
|
+
properties: {
|
|
14
|
+
symbol_id: {
|
|
15
|
+
type: 'number',
|
|
16
|
+
description: 'Optional symbol id to fetch exact coverage for.',
|
|
17
|
+
},
|
|
18
|
+
symbol_name: {
|
|
19
|
+
type: 'string',
|
|
20
|
+
description: 'Optional symbol name filter (case-insensitive).',
|
|
21
|
+
},
|
|
22
|
+
path: {
|
|
23
|
+
type: 'string',
|
|
24
|
+
description: 'Optional file path filter.',
|
|
25
|
+
},
|
|
26
|
+
branch: {
|
|
27
|
+
type: 'string',
|
|
28
|
+
description: 'Optional branch filter.',
|
|
29
|
+
},
|
|
30
|
+
limit: {
|
|
31
|
+
type: 'number',
|
|
32
|
+
description: 'Maximum symbols to return (default 50).',
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
required: [],
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
const DEFAULT_LIMIT = 50;
|
|
39
|
+
export function handler(db, args) {
|
|
40
|
+
const latestRun = getLatestCoverageRun(db);
|
|
41
|
+
const staleness = getCoverageStaleness(db);
|
|
42
|
+
const totals = getLatestCoverageTotals(db);
|
|
43
|
+
const limit = Math.max(1, Math.floor(args.limit ?? DEFAULT_LIMIT));
|
|
44
|
+
let symbolIds;
|
|
45
|
+
if (args.symbol_id !== undefined) {
|
|
46
|
+
symbolIds = [args.symbol_id];
|
|
47
|
+
}
|
|
48
|
+
else if (args.symbol_name !== undefined) {
|
|
49
|
+
symbolIds = getSymbolsByName(db, args.symbol_name, args.branch).map((symbol) => symbol.id);
|
|
50
|
+
if (symbolIds.length === 0) {
|
|
51
|
+
symbolIds = [-1];
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const symbols = latestRun
|
|
55
|
+
? getSymbolCoverageAggregates(db, {
|
|
56
|
+
symbolIds,
|
|
57
|
+
path: args.path,
|
|
58
|
+
branch: args.branch,
|
|
59
|
+
limit,
|
|
60
|
+
})
|
|
61
|
+
: [];
|
|
62
|
+
return {
|
|
63
|
+
coverage_available: latestRun !== undefined,
|
|
64
|
+
coverage_commit: staleness.coverage_commit,
|
|
65
|
+
current_commit: staleness.current_commit,
|
|
66
|
+
commits_behind: staleness.commits_behind,
|
|
67
|
+
stale: staleness.stale,
|
|
68
|
+
global_lines_found: totals?.lines_found ?? null,
|
|
69
|
+
global_lines_hit: totals?.lines_hit ?? null,
|
|
70
|
+
global_coverage_percent: totals?.coverage_percent ?? null,
|
|
71
|
+
symbols,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=coverage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coverage.js","sourceRoot":"","sources":["../../../src/kb-server/tools/coverage.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,uBAAuB,EACvB,2BAA2B,EAC3B,gBAAgB,GACjB,MAAM,UAAU,CAAC;AAElB,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB,IAAI,EAAE,aAAa;IACnB,WAAW,EACT,oFAAoF;QACpF,uCAAuC;IACzC,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,SAAS,EAAE;gBACT,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,iDAAiD;aAC/D;YACD,WAAW,EAAE;gBACX,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,iDAAiD;aAC/D;YACD,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,4BAA4B;aAC1C;YACD,MAAM,EAAE;gBACN,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,yBAAyB;aACvC;YACD,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,yCAAyC;aACvD;SACF;QACD,QAAQ,EAAE,EAAE;KACb;CACO,CAAC;AAkCX,MAAM,aAAa,GAAG,EAAE,CAAC;AAEzB,MAAM,UAAU,OAAO,CAAC,EAAqB,EAAE,IAAkB;IAC/D,MAAM,SAAS,GAAG,oBAAoB,CAAC,EAAE,CAAC,CAAC;IAC3C,MAAM,SAAS,GAAG,oBAAoB,CAAC,EAAE,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,uBAAuB,CAAC,EAAE,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,aAAa,CAAC,CAAC,CAAC;IAEnE,IAAI,SAA+B,CAAC;IACpC,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QACjC,SAAS,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC/B,CAAC;SAAM,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QAC1C,SAAS,GAAG,gBAAgB,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC3F,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,SAAS;QACvB,CAAC,CAAC,2BAA2B,CAAC,EAAE,EAAE;YAC9B,SAAS;YACT,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,KAAK;SACN,CAAC;QACJ,CAAC,CAAC,EAAE,CAAC;IAEP,OAAO;QACL,kBAAkB,EAAE,SAAS,KAAK,SAAS;QAC3C,eAAe,EAAE,SAAS,CAAC,eAAe;QAC1C,cAAc,EAAE,SAAS,CAAC,cAAc;QACxC,cAAc,EAAE,SAAS,CAAC,cAAc;QACxC,KAAK,EAAE,SAAS,CAAC,KAAK;QACtB,kBAAkB,EAAE,MAAM,EAAE,WAAW,IAAI,IAAI;QAC/C,gBAAgB,EAAE,MAAM,EAAE,SAAS,IAAI,IAAI;QAC3C,uBAAuB,EAAE,MAAM,EAAE,gBAAgB,IAAI,IAAI;QACzD,OAAO;KACR,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module kb-server/tools/graph
|
|
3
|
+
*
|
|
4
|
+
* MCP tool: query the call graph and import graph.
|
|
5
|
+
*
|
|
6
|
+
* Both queries return adjacency lists so callers can build their own
|
|
7
|
+
* traversals without additional round-trips.
|
|
8
|
+
*/
|
|
9
|
+
import type { Database } from '../db.js';
|
|
10
|
+
export declare const toolDef: {
|
|
11
|
+
readonly name: "kb_graph";
|
|
12
|
+
readonly description: string;
|
|
13
|
+
readonly inputSchema: {
|
|
14
|
+
readonly type: "object";
|
|
15
|
+
readonly properties: {
|
|
16
|
+
readonly kind: {
|
|
17
|
+
readonly type: "string";
|
|
18
|
+
readonly enum: readonly ["call", "import", "module", "inheritance"];
|
|
19
|
+
readonly description: string;
|
|
20
|
+
};
|
|
21
|
+
readonly source_id: {
|
|
22
|
+
readonly type: "number";
|
|
23
|
+
readonly description: "Optional. If provided, only edges whose source matches this id are returned.";
|
|
24
|
+
};
|
|
25
|
+
readonly limit: {
|
|
26
|
+
readonly type: "number";
|
|
27
|
+
readonly description: "Maximum number of edges to return (default 200).";
|
|
28
|
+
};
|
|
29
|
+
readonly branch: {
|
|
30
|
+
readonly type: "string";
|
|
31
|
+
readonly description: "Optional branch name to filter edges by source branch.";
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
readonly required: readonly ["kind"];
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
export interface GraphArgs {
|
|
38
|
+
kind: 'call' | 'import' | 'module' | 'inheritance';
|
|
39
|
+
source_id?: number;
|
|
40
|
+
limit?: number;
|
|
41
|
+
branch?: string;
|
|
42
|
+
}
|
|
43
|
+
export interface GraphEdge {
|
|
44
|
+
source_id: number;
|
|
45
|
+
source_name: string;
|
|
46
|
+
source_branch: string;
|
|
47
|
+
target_id: number | null;
|
|
48
|
+
target_name: string;
|
|
49
|
+
callee_coverage_percent?: number | null;
|
|
50
|
+
}
|
|
51
|
+
export interface GraphResult {
|
|
52
|
+
edges: GraphEdge[];
|
|
53
|
+
}
|
|
54
|
+
/** Return adjacency-list edges from the call graph or import graph. */
|
|
55
|
+
export declare function handler(db: Database.Database, args: GraphArgs): GraphResult;
|
|
56
|
+
//# sourceMappingURL=graph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../../src/kb-server/tools/graph.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAKzC,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;CAgCV,CAAC;AAIX,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,aAAa,CAAC;IACnD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,uBAAuB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzC;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,SAAS,EAAE,CAAC;CACpB;AAED,uEAAuE;AACvE,wBAAgB,OAAO,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,SAAS,GAAG,WAAW,CA0J3E"}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module kb-server/tools/graph
|
|
3
|
+
*
|
|
4
|
+
* MCP tool: query the call graph and import graph.
|
|
5
|
+
*
|
|
6
|
+
* Both queries return adjacency lists so callers can build their own
|
|
7
|
+
* traversals without additional round-trips.
|
|
8
|
+
*/
|
|
9
|
+
import { getCoveragePercentBySymbolIds } from '../db.js';
|
|
10
|
+
// ─── Tool definition ──────────────────────────────────────────────────────────
|
|
11
|
+
export const toolDef = {
|
|
12
|
+
name: 'kb_graph',
|
|
13
|
+
description: 'Query call, import, module, or inheritance graph edges stored in the knowledge-base index. ' +
|
|
14
|
+
'Set `kind` to "call", "import", "module", or "inheritance". ' +
|
|
15
|
+
'Optionally filter by a source node id.',
|
|
16
|
+
inputSchema: {
|
|
17
|
+
type: 'object',
|
|
18
|
+
properties: {
|
|
19
|
+
kind: {
|
|
20
|
+
type: 'string',
|
|
21
|
+
enum: ['call', 'import', 'module', 'inheritance'],
|
|
22
|
+
description: '"call" returns symbol → callee edges; "import" returns file → imported-file edges; ' +
|
|
23
|
+
'"module" returns module → imported-module edges; "inheritance" returns symbol → base-symbol edges.',
|
|
24
|
+
},
|
|
25
|
+
source_id: {
|
|
26
|
+
type: 'number',
|
|
27
|
+
description: 'Optional. If provided, only edges whose source matches this id are returned.',
|
|
28
|
+
},
|
|
29
|
+
limit: {
|
|
30
|
+
type: 'number',
|
|
31
|
+
description: 'Maximum number of edges to return (default 200).',
|
|
32
|
+
},
|
|
33
|
+
branch: {
|
|
34
|
+
type: 'string',
|
|
35
|
+
description: 'Optional branch name to filter edges by source branch.',
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
required: ['kind'],
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
/** Return adjacency-list edges from the call graph or import graph. */
|
|
42
|
+
export function handler(db, args) {
|
|
43
|
+
const limit = args.limit ?? 200;
|
|
44
|
+
if (args.kind === 'call') {
|
|
45
|
+
// Symbol-level: symbol_refs rows
|
|
46
|
+
const hasFilter = args.source_id !== undefined;
|
|
47
|
+
const branchClause = args.branch !== undefined ? ' AND f_caller.branch = ?' : '';
|
|
48
|
+
const sql = hasFilter
|
|
49
|
+
? `SELECT sr.caller_id AS source_id,
|
|
50
|
+
s_caller.name AS source_name,
|
|
51
|
+
f_caller.branch AS source_branch,
|
|
52
|
+
sr.callee_id AS target_id,
|
|
53
|
+
sr.callee_name AS target_name
|
|
54
|
+
FROM symbol_refs sr
|
|
55
|
+
JOIN symbols s_caller ON s_caller.id = sr.caller_id
|
|
56
|
+
JOIN files f_caller ON f_caller.id = s_caller.file_id
|
|
57
|
+
WHERE sr.caller_id = ?${branchClause}
|
|
58
|
+
LIMIT ?`
|
|
59
|
+
: `SELECT sr.caller_id AS source_id,
|
|
60
|
+
s_caller.name AS source_name,
|
|
61
|
+
f_caller.branch AS source_branch,
|
|
62
|
+
sr.callee_id AS target_id,
|
|
63
|
+
sr.callee_name AS target_name
|
|
64
|
+
FROM symbol_refs sr
|
|
65
|
+
JOIN symbols s_caller ON s_caller.id = sr.caller_id
|
|
66
|
+
JOIN files f_caller ON f_caller.id = s_caller.file_id
|
|
67
|
+
WHERE 1=1${branchClause}
|
|
68
|
+
LIMIT ?`;
|
|
69
|
+
const edgeParams = hasFilter
|
|
70
|
+
? (args.branch !== undefined ? [args.source_id, args.branch, limit] : [args.source_id, limit])
|
|
71
|
+
: (args.branch !== undefined ? [args.branch, limit] : [limit]);
|
|
72
|
+
const edges = db.prepare(sql).all(...edgeParams);
|
|
73
|
+
const calleeIds = Array.from(new Set(edges.map((edge) => edge.target_id).filter((id) => id !== null)));
|
|
74
|
+
const coverageBySymbolId = getCoveragePercentBySymbolIds(db, calleeIds, args.branch);
|
|
75
|
+
const edgesWithCoverage = edges.map((edge) => ({
|
|
76
|
+
...edge,
|
|
77
|
+
callee_coverage_percent: edge.target_id !== null ? (coverageBySymbolId.get(edge.target_id) ?? null) : null,
|
|
78
|
+
}));
|
|
79
|
+
return { edges: edgesWithCoverage };
|
|
80
|
+
}
|
|
81
|
+
else if (args.kind === 'import') {
|
|
82
|
+
// File-level: file_imports rows
|
|
83
|
+
const hasFilter = args.source_id !== undefined;
|
|
84
|
+
const branchClause = args.branch !== undefined ? ' AND f_src.branch = ?' : '';
|
|
85
|
+
const sql = hasFilter
|
|
86
|
+
? `SELECT fi.file_id AS source_id,
|
|
87
|
+
f_src.path AS source_name,
|
|
88
|
+
f_src.branch AS source_branch,
|
|
89
|
+
fi.resolved_id AS target_id,
|
|
90
|
+
COALESCE(f_dst.path, fi.raw_import) AS target_name
|
|
91
|
+
FROM file_imports fi
|
|
92
|
+
JOIN files f_src ON f_src.id = fi.file_id
|
|
93
|
+
LEFT JOIN files f_dst ON f_dst.id = fi.resolved_id
|
|
94
|
+
WHERE fi.file_id = ?${branchClause}
|
|
95
|
+
LIMIT ?`
|
|
96
|
+
: `SELECT fi.file_id AS source_id,
|
|
97
|
+
f_src.path AS source_name,
|
|
98
|
+
f_src.branch AS source_branch,
|
|
99
|
+
fi.resolved_id AS target_id,
|
|
100
|
+
COALESCE(f_dst.path, fi.raw_import) AS target_name
|
|
101
|
+
FROM file_imports fi
|
|
102
|
+
JOIN files f_src ON f_src.id = fi.file_id
|
|
103
|
+
LEFT JOIN files f_dst ON f_dst.id = fi.resolved_id
|
|
104
|
+
WHERE 1=1${branchClause}
|
|
105
|
+
LIMIT ?`;
|
|
106
|
+
const edgeParams = hasFilter
|
|
107
|
+
? (args.branch !== undefined ? [args.source_id, args.branch, limit] : [args.source_id, limit])
|
|
108
|
+
: (args.branch !== undefined ? [args.branch, limit] : [limit]);
|
|
109
|
+
const edges = db.prepare(sql).all(...edgeParams);
|
|
110
|
+
return { edges };
|
|
111
|
+
}
|
|
112
|
+
else if (args.kind === 'module') {
|
|
113
|
+
// Module-level: inferred from file_imports + file_modules
|
|
114
|
+
const hasFilter = args.source_id !== undefined;
|
|
115
|
+
const branchClause = args.branch !== undefined ? ' AND f_src.branch = ?' : '';
|
|
116
|
+
const sql = hasFilter
|
|
117
|
+
? `SELECT DISTINCT
|
|
118
|
+
m_src.id AS source_id,
|
|
119
|
+
m_src.name AS source_name,
|
|
120
|
+
f_src.branch AS source_branch,
|
|
121
|
+
m_dst.id AS target_id,
|
|
122
|
+
COALESCE(m_dst.name, fi.raw_import) AS target_name
|
|
123
|
+
FROM file_imports fi
|
|
124
|
+
JOIN files f_src ON f_src.id = fi.file_id
|
|
125
|
+
JOIN file_modules fm_src ON fm_src.file_id = f_src.id
|
|
126
|
+
JOIN modules m_src ON m_src.id = fm_src.module_id
|
|
127
|
+
LEFT JOIN files f_dst ON f_dst.id = fi.resolved_id
|
|
128
|
+
LEFT JOIN file_modules fm_dst ON fm_dst.file_id = f_dst.id
|
|
129
|
+
LEFT JOIN modules m_dst ON m_dst.id = fm_dst.module_id
|
|
130
|
+
WHERE m_src.id = ?${branchClause}
|
|
131
|
+
LIMIT ?`
|
|
132
|
+
: `SELECT DISTINCT
|
|
133
|
+
m_src.id AS source_id,
|
|
134
|
+
m_src.name AS source_name,
|
|
135
|
+
f_src.branch AS source_branch,
|
|
136
|
+
m_dst.id AS target_id,
|
|
137
|
+
COALESCE(m_dst.name, fi.raw_import) AS target_name
|
|
138
|
+
FROM file_imports fi
|
|
139
|
+
JOIN files f_src ON f_src.id = fi.file_id
|
|
140
|
+
JOIN file_modules fm_src ON fm_src.file_id = f_src.id
|
|
141
|
+
JOIN modules m_src ON m_src.id = fm_src.module_id
|
|
142
|
+
LEFT JOIN files f_dst ON f_dst.id = fi.resolved_id
|
|
143
|
+
LEFT JOIN file_modules fm_dst ON fm_dst.file_id = f_dst.id
|
|
144
|
+
LEFT JOIN modules m_dst ON m_dst.id = fm_dst.module_id
|
|
145
|
+
WHERE 1=1${branchClause}
|
|
146
|
+
LIMIT ?`;
|
|
147
|
+
const edgeParams = hasFilter
|
|
148
|
+
? (args.branch !== undefined ? [args.source_id, args.branch, limit] : [args.source_id, limit])
|
|
149
|
+
: (args.branch !== undefined ? [args.branch, limit] : [limit]);
|
|
150
|
+
const edges = db.prepare(sql).all(...edgeParams);
|
|
151
|
+
return { edges };
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
// Symbol-level inheritance edges (e.g., class extends)
|
|
155
|
+
const hasFilter = args.source_id !== undefined;
|
|
156
|
+
const branchClause = args.branch !== undefined ? ' AND f_src.branch = ?' : '';
|
|
157
|
+
const sql = hasFilter
|
|
158
|
+
? `SELECT rel.source_symbol_id AS source_id,
|
|
159
|
+
s_src.name AS source_name,
|
|
160
|
+
f_src.branch AS source_branch,
|
|
161
|
+
rel.target_symbol_id AS target_id,
|
|
162
|
+
COALESCE(s_dst.name, rel.target_symbol_name) AS target_name
|
|
163
|
+
FROM symbol_relationships rel
|
|
164
|
+
JOIN symbols s_src ON s_src.id = rel.source_symbol_id
|
|
165
|
+
JOIN files f_src ON f_src.id = s_src.file_id
|
|
166
|
+
LEFT JOIN symbols s_dst ON s_dst.id = rel.target_symbol_id
|
|
167
|
+
WHERE rel.relationship_type = 'extends'
|
|
168
|
+
AND rel.source_symbol_id = ?${branchClause}
|
|
169
|
+
LIMIT ?`
|
|
170
|
+
: `SELECT rel.source_symbol_id AS source_id,
|
|
171
|
+
s_src.name AS source_name,
|
|
172
|
+
f_src.branch AS source_branch,
|
|
173
|
+
rel.target_symbol_id AS target_id,
|
|
174
|
+
COALESCE(s_dst.name, rel.target_symbol_name) AS target_name
|
|
175
|
+
FROM symbol_relationships rel
|
|
176
|
+
JOIN symbols s_src ON s_src.id = rel.source_symbol_id
|
|
177
|
+
JOIN files f_src ON f_src.id = s_src.file_id
|
|
178
|
+
LEFT JOIN symbols s_dst ON s_dst.id = rel.target_symbol_id
|
|
179
|
+
WHERE rel.relationship_type = 'extends'${branchClause}
|
|
180
|
+
LIMIT ?`;
|
|
181
|
+
const edgeParams = hasFilter
|
|
182
|
+
? (args.branch !== undefined ? [args.source_id, args.branch, limit] : [args.source_id, limit])
|
|
183
|
+
: (args.branch !== undefined ? [args.branch, limit] : [limit]);
|
|
184
|
+
const edges = db.prepare(sql).all(...edgeParams);
|
|
185
|
+
return { edges };
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
//# sourceMappingURL=graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.js","sourceRoot":"","sources":["../../../src/kb-server/tools/graph.ts"],"names":[],"mappings":"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"}
|