@nanonets/graft 0.10.0 → 0.12.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 +34 -13
- package/dist/ai/crux.d.ts.map +1 -1
- package/dist/ai/crux.js +7 -6
- package/dist/ai/crux.js.map +1 -1
- package/dist/ai/failure.d.ts +49 -0
- package/dist/ai/failure.d.ts.map +1 -0
- package/dist/ai/failure.js +74 -0
- package/dist/ai/failure.js.map +1 -0
- package/dist/ai/llm/anthropic.d.ts.map +1 -1
- package/dist/ai/llm/anthropic.js +4 -1
- package/dist/ai/llm/anthropic.js.map +1 -1
- package/dist/ai/llm/claude-cli.d.ts +60 -0
- package/dist/ai/llm/claude-cli.d.ts.map +1 -0
- package/dist/ai/llm/claude-cli.js +417 -0
- package/dist/ai/llm/claude-cli.js.map +1 -0
- package/dist/ai/llm/openai.d.ts.map +1 -1
- package/dist/ai/llm/openai.js +2 -0
- package/dist/ai/llm/openai.js.map +1 -1
- package/dist/ai/llm/types.d.ts +9 -0
- package/dist/ai/llm/types.d.ts.map +1 -1
- package/dist/ai/llm/types.js +12 -1
- package/dist/ai/llm/types.js.map +1 -1
- package/dist/ask/ask.d.ts.map +1 -1
- package/dist/ask/ask.js +39 -45
- package/dist/ask/ask.js.map +1 -1
- package/dist/ask/fuse.d.ts +83 -46
- package/dist/ask/fuse.d.ts.map +1 -1
- package/dist/ask/fuse.js +165 -67
- package/dist/ask/fuse.js.map +1 -1
- package/dist/blast/blast-cli.d.ts +30 -0
- package/dist/blast/blast-cli.d.ts.map +1 -0
- package/dist/blast/blast-cli.js +163 -0
- package/dist/blast/blast-cli.js.map +1 -0
- package/dist/blast/blast.d.ts +119 -0
- package/dist/blast/blast.d.ts.map +1 -0
- package/dist/blast/blast.js +383 -0
- package/dist/blast/blast.js.map +1 -0
- package/dist/blast/diff.d.ts +53 -0
- package/dist/blast/diff.d.ts.map +1 -0
- package/dist/blast/diff.js +193 -0
- package/dist/blast/diff.js.map +1 -0
- package/dist/blast/modules.d.ts +33 -0
- package/dist/blast/modules.d.ts.map +1 -0
- package/dist/blast/modules.js +83 -0
- package/dist/blast/modules.js.map +1 -0
- package/dist/blast/name.d.ts +61 -0
- package/dist/blast/name.d.ts.map +1 -0
- package/dist/blast/name.js +233 -0
- package/dist/blast/name.js.map +1 -0
- package/dist/blast/render.d.ts +37 -0
- package/dist/blast/render.d.ts.map +1 -0
- package/dist/blast/render.js +300 -0
- package/dist/blast/render.js.map +1 -0
- package/dist/blast/viz.d.ts +17 -0
- package/dist/blast/viz.d.ts.map +1 -0
- package/dist/blast/viz.js +324 -0
- package/dist/blast/viz.js.map +1 -0
- package/dist/claude/hooks.d.ts +13 -0
- package/dist/claude/hooks.d.ts.map +1 -1
- package/dist/claude/hooks.js +44 -4
- package/dist/claude/hooks.js.map +1 -1
- package/dist/claude/shim-template.d.ts.map +1 -1
- package/dist/claude/shim-template.js +45 -15
- package/dist/claude/shim-template.js.map +1 -1
- package/dist/claude/state.d.ts +5 -0
- package/dist/claude/state.d.ts.map +1 -1
- package/dist/claude/state.js.map +1 -1
- package/dist/cli-picker.d.ts +44 -5
- package/dist/cli-picker.d.ts.map +1 -1
- package/dist/cli-picker.js +73 -26
- package/dist/cli-picker.js.map +1 -1
- package/dist/cli.js +270 -14
- package/dist/cli.js.map +1 -1
- package/dist/context/build.d.ts +8 -0
- package/dist/context/build.d.ts.map +1 -1
- package/dist/context/build.js +57 -9
- package/dist/context/build.js.map +1 -1
- package/dist/context/check.d.ts.map +1 -1
- package/dist/context/check.js +7 -6
- package/dist/context/check.js.map +1 -1
- package/dist/context/node-file.d.ts.map +1 -1
- package/dist/context/node-file.js +9 -2
- package/dist/context/node-file.js.map +1 -1
- package/dist/graph/bindings.d.ts.map +1 -1
- package/dist/graph/bindings.js +245 -2
- package/dist/graph/bindings.js.map +1 -1
- package/dist/graph/build.d.ts.map +1 -1
- package/dist/graph/build.js +36 -16
- package/dist/graph/build.js.map +1 -1
- package/dist/graph/check.d.ts +4 -0
- package/dist/graph/check.d.ts.map +1 -1
- package/dist/graph/check.js +8 -1
- package/dist/graph/check.js.map +1 -1
- package/dist/graph/container.d.ts +63 -0
- package/dist/graph/container.d.ts.map +1 -0
- package/dist/graph/container.js +185 -0
- package/dist/graph/container.js.map +1 -0
- package/dist/graph/enrich.d.ts +18 -0
- package/dist/graph/enrich.d.ts.map +1 -1
- package/dist/graph/enrich.js +55 -2
- package/dist/graph/enrich.js.map +1 -1
- package/dist/graph/extract.d.ts +8 -1
- package/dist/graph/extract.d.ts.map +1 -1
- package/dist/graph/extract.js +401 -12
- package/dist/graph/extract.js.map +1 -1
- package/dist/graph/generic.d.ts +34 -1
- package/dist/graph/generic.d.ts.map +1 -1
- package/dist/graph/generic.js +176 -6
- package/dist/graph/generic.js.map +1 -1
- package/dist/graph/invariants.d.ts +32 -0
- package/dist/graph/invariants.d.ts.map +1 -0
- package/dist/graph/invariants.js +49 -0
- package/dist/graph/invariants.js.map +1 -0
- package/dist/graph/queries/clojure.scm +58 -0
- package/dist/graph/resolve.d.ts.map +1 -1
- package/dist/graph/resolve.js +249 -23
- package/dist/graph/resolve.js.map +1 -1
- package/dist/graph/scopes.d.ts +2 -2
- package/dist/graph/scopes.d.ts.map +1 -1
- package/dist/graph/scopes.js +8 -6
- package/dist/graph/scopes.js.map +1 -1
- package/dist/graph/source-files.d.ts +13 -4
- package/dist/graph/source-files.d.ts.map +1 -1
- package/dist/graph/source-files.js +35 -12
- package/dist/graph/source-files.js.map +1 -1
- package/dist/graph/types.d.ts +3 -1
- package/dist/graph/types.d.ts.map +1 -1
- package/dist/graph/workspace-cli.d.ts +2 -0
- package/dist/graph/workspace-cli.d.ts.map +1 -1
- package/dist/graph/workspace-cli.js +10 -4
- package/dist/graph/workspace-cli.js.map +1 -1
- package/dist/graph/workspace.d.ts +11 -6
- package/dist/graph/workspace.d.ts.map +1 -1
- package/dist/graph/workspace.js +24 -13
- package/dist/graph/workspace.js.map +1 -1
- package/dist/graph/write.d.ts.map +1 -1
- package/dist/graph/write.js +25 -2
- package/dist/graph/write.js.map +1 -1
- package/dist/hosts/antigravity.d.ts +7 -0
- package/dist/hosts/antigravity.d.ts.map +1 -0
- package/dist/hosts/antigravity.js +42 -0
- package/dist/hosts/antigravity.js.map +1 -0
- package/dist/hosts/codex-hooks.d.ts +3 -3
- package/dist/hosts/codex-hooks.d.ts.map +1 -1
- package/dist/hosts/codex-hooks.js +27 -21
- package/dist/hosts/codex-hooks.js.map +1 -1
- package/dist/hosts/init.d.ts.map +1 -1
- package/dist/hosts/init.js +6 -1
- package/dist/hosts/init.js.map +1 -1
- package/dist/hosts/mcp-config.d.ts.map +1 -1
- package/dist/hosts/mcp-config.js +7 -0
- package/dist/hosts/mcp-config.js.map +1 -1
- package/dist/hosts/plan.d.ts +1 -1
- package/dist/hosts/plan.d.ts.map +1 -1
- package/dist/hosts/plan.js +2 -0
- package/dist/hosts/plan.js.map +1 -1
- package/dist/hosts/registry.d.ts.map +1 -1
- package/dist/hosts/registry.js +13 -0
- package/dist/hosts/registry.js.map +1 -1
- package/dist/ingest/fs.d.ts +9 -2
- package/dist/ingest/fs.d.ts.map +1 -1
- package/dist/ingest/fs.js +100 -16
- package/dist/ingest/fs.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +45 -2
- package/dist/mcp/server.js.map +1 -1
- package/dist/telemetry/contract.d.ts +90 -0
- package/dist/telemetry/contract.d.ts.map +1 -0
- package/dist/telemetry/contract.js +203 -0
- package/dist/telemetry/contract.js.map +1 -0
- package/dist/telemetry/flush.d.ts +21 -0
- package/dist/telemetry/flush.d.ts.map +1 -0
- package/dist/telemetry/flush.js +84 -0
- package/dist/telemetry/flush.js.map +1 -0
- package/dist/telemetry/gate.d.ts +16 -0
- package/dist/telemetry/gate.d.ts.map +1 -0
- package/dist/telemetry/gate.js +64 -0
- package/dist/telemetry/gate.js.map +1 -0
- package/dist/telemetry/identity.d.ts +33 -0
- package/dist/telemetry/identity.d.ts.map +1 -0
- package/dist/telemetry/identity.js +80 -0
- package/dist/telemetry/identity.js.map +1 -0
- package/dist/telemetry/index.d.ts +18 -0
- package/dist/telemetry/index.d.ts.map +1 -0
- package/dist/telemetry/index.js +16 -0
- package/dist/telemetry/index.js.map +1 -0
- package/dist/telemetry/key.d.ts +21 -0
- package/dist/telemetry/key.d.ts.map +1 -0
- package/dist/telemetry/key.js +49 -0
- package/dist/telemetry/key.js.map +1 -0
- package/dist/telemetry/notice.d.ts +19 -0
- package/dist/telemetry/notice.d.ts.map +1 -0
- package/dist/telemetry/notice.js +90 -0
- package/dist/telemetry/notice.js.map +1 -0
- package/dist/telemetry/queue.d.ts +35 -0
- package/dist/telemetry/queue.d.ts.map +1 -0
- package/dist/telemetry/queue.js +162 -0
- package/dist/telemetry/queue.js.map +1 -0
- package/dist/telemetry/send.d.ts +19 -0
- package/dist/telemetry/send.d.ts.map +1 -0
- package/dist/telemetry/send.js +84 -0
- package/dist/telemetry/send.js.map +1 -0
- package/dist/telemetry/sessions.d.ts +8 -0
- package/dist/telemetry/sessions.d.ts.map +1 -0
- package/dist/telemetry/sessions.js +81 -0
- package/dist/telemetry/sessions.js.map +1 -0
- package/dist/telemetry/track.d.ts +43 -0
- package/dist/telemetry/track.d.ts.map +1 -0
- package/dist/telemetry/track.js +108 -0
- package/dist/telemetry/track.js.map +1 -0
- package/dist/upkeep-run.d.ts +15 -0
- package/dist/upkeep-run.d.ts.map +1 -0
- package/dist/upkeep-run.js +60 -0
- package/dist/upkeep-run.js.map +1 -0
- package/dist/upkeep.d.ts +114 -0
- package/dist/upkeep.d.ts.map +1 -0
- package/dist/upkeep.js +232 -0
- package/dist/upkeep.js.map +1 -0
- package/dist/util/num.d.ts +3 -0
- package/dist/util/num.d.ts.map +1 -0
- package/dist/util/num.js +20 -0
- package/dist/util/num.js.map +1 -0
- package/dist/util/state.d.ts +11 -4
- package/dist/util/state.d.ts.map +1 -1
- package/dist/util/state.js +9 -0
- package/dist/util/state.js.map +1 -1
- package/dist/viewer/app.js +1 -1
- package/dist/viewer/index.html +1 -0
- package/dist/viewer/style.css +23 -2
- package/dist/viz/assemble.d.ts +33 -0
- package/dist/viz/assemble.d.ts.map +1 -1
- package/dist/viz/assemble.js.map +1 -1
- package/dist/viz/export.d.ts +39 -0
- package/dist/viz/export.d.ts.map +1 -0
- package/dist/viz/export.js +98 -0
- package/dist/viz/export.js.map +1 -0
- package/package.json +15 -5
- package/scripts/stamp-telemetry-key.mjs +53 -0
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a PR touched, read from git: changed files plus the *line ranges* inside
|
|
3
|
+
* them, which is what turns a diff into graph seeds (an enclosing-symbol lookup
|
|
4
|
+
* per changed line, see `blast.ts`).
|
|
5
|
+
*
|
|
6
|
+
* Git is shelled out to rather than parsed from a library because the CI job
|
|
7
|
+
* this feeds already has git — and `--unified=0` gives exactly the post-image
|
|
8
|
+
* line ranges we need, with no context lines to subtract back out.
|
|
9
|
+
*/
|
|
10
|
+
import { spawnSync } from "node:child_process";
|
|
11
|
+
import { resolve } from "node:path";
|
|
12
|
+
const HUNK_RE = /^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@/;
|
|
13
|
+
/** Text kept per hunk, and per file. A regenerated lockfile is one hunk of 40,000
|
|
14
|
+
* lines: the ranges still matter (they seed the graph), the text does not, and it
|
|
15
|
+
* would otherwise ride along in `--format json` and in every exported page. */
|
|
16
|
+
const MAX_HUNK_LINES = 24;
|
|
17
|
+
const MAX_FILE_LINES = 200;
|
|
18
|
+
/** Run git in `root`, or return null when git fails (not a repo, unknown ref). */
|
|
19
|
+
function git(root, args) {
|
|
20
|
+
const res = spawnSync("git", ["-c", "core.quotePath=false", ...args], {
|
|
21
|
+
cwd: root,
|
|
22
|
+
encoding: "utf8",
|
|
23
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
24
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
25
|
+
});
|
|
26
|
+
if (res.error || res.status !== 0 || typeof res.stdout !== "string")
|
|
27
|
+
return null;
|
|
28
|
+
return res.stdout;
|
|
29
|
+
}
|
|
30
|
+
/** True when `ref` names something git can resolve — checked before diffing so
|
|
31
|
+
* an unknown `--base` fails with a caller-facing message, not a git stack. */
|
|
32
|
+
export function refExists(root, ref) {
|
|
33
|
+
return git(resolve(root), ["rev-parse", "--verify", "--quiet", `${ref}^{commit}`]) !== null;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* The diff arguments for a base ref, and the label to show for it.
|
|
37
|
+
*
|
|
38
|
+
* `<base>...HEAD` (three dots) diffs against the MERGE BASE, not the tip of the
|
|
39
|
+
* base branch — the difference matters on every PR whose base branch moved after
|
|
40
|
+
* it was cut: two-dot would attribute other people's merges to this PR and
|
|
41
|
+
* inflate the blast radius with files the author never touched.
|
|
42
|
+
*/
|
|
43
|
+
function rangeArgs(base) {
|
|
44
|
+
return { args: [`${base}...HEAD`], basis: `${base}...HEAD` };
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Changed files + post-image line ranges.
|
|
48
|
+
*
|
|
49
|
+
* With no `base` this reports the working tree against HEAD (the local
|
|
50
|
+
* "what am I about to push" case), falling back to the last commit when the
|
|
51
|
+
* tree is clean — so the command answers something useful when run by hand,
|
|
52
|
+
* and CI passes `--base` for the real PR range.
|
|
53
|
+
*/
|
|
54
|
+
export function changedFiles(root, base) {
|
|
55
|
+
const dir = resolve(root);
|
|
56
|
+
if (base !== undefined) {
|
|
57
|
+
const { args, basis } = rangeArgs(base);
|
|
58
|
+
const files = diffFiles(dir, args);
|
|
59
|
+
return files === null ? null : { basis, files };
|
|
60
|
+
}
|
|
61
|
+
const working = diffFiles(dir, ["HEAD"]);
|
|
62
|
+
if (working === null)
|
|
63
|
+
return null;
|
|
64
|
+
if (working.length > 0)
|
|
65
|
+
return { basis: "working tree vs HEAD", files: working };
|
|
66
|
+
const last = diffFiles(dir, ["HEAD~1...HEAD"]);
|
|
67
|
+
if (last === null)
|
|
68
|
+
return { basis: "working tree vs HEAD", files: [] };
|
|
69
|
+
return { basis: "HEAD~1...HEAD", files: last };
|
|
70
|
+
}
|
|
71
|
+
/** Both git passes for one range: name-status (statuses, renames) then hunks. */
|
|
72
|
+
function diffFiles(dir, range) {
|
|
73
|
+
const status = git(dir, ["diff", "--name-status", "--find-renames", "-z", ...range, "--"]);
|
|
74
|
+
if (status === null)
|
|
75
|
+
return null;
|
|
76
|
+
const files = parseNameStatus(status);
|
|
77
|
+
if (files.length === 0)
|
|
78
|
+
return files;
|
|
79
|
+
const patch = git(dir, [
|
|
80
|
+
"diff",
|
|
81
|
+
"--unified=0",
|
|
82
|
+
"--no-color",
|
|
83
|
+
"--no-ext-diff",
|
|
84
|
+
"--find-renames",
|
|
85
|
+
...range,
|
|
86
|
+
"--",
|
|
87
|
+
]);
|
|
88
|
+
if (patch !== null)
|
|
89
|
+
applyHunks(files, patch);
|
|
90
|
+
return files;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* `--name-status -z` output: NUL-separated fields, where a rename spends THREE
|
|
94
|
+
* fields (`R096`, old, new) and everything else spends two. Splitting on NUL and
|
|
95
|
+
* walking with a cursor is the only way to read it — a line-oriented parse
|
|
96
|
+
* silently pairs a rename's old path with the next file's status.
|
|
97
|
+
*/
|
|
98
|
+
function parseNameStatus(out) {
|
|
99
|
+
const fields = out.split("\0").filter((f) => f !== "");
|
|
100
|
+
const files = [];
|
|
101
|
+
for (let i = 0; i < fields.length;) {
|
|
102
|
+
const code = fields[i++];
|
|
103
|
+
if (code.startsWith("R") || code.startsWith("C")) {
|
|
104
|
+
const oldPath = fields[i++];
|
|
105
|
+
const path = fields[i++];
|
|
106
|
+
if (path === undefined)
|
|
107
|
+
break;
|
|
108
|
+
files.push({ path, status: "renamed", oldPath, ranges: [], hunks: [] });
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
const path = fields[i++];
|
|
112
|
+
if (path === undefined)
|
|
113
|
+
break;
|
|
114
|
+
if (code.startsWith("A"))
|
|
115
|
+
files.push({ path, status: "added", ranges: [], hunks: [] });
|
|
116
|
+
else if (code.startsWith("D"))
|
|
117
|
+
files.push({ path, status: "deleted", ranges: [], hunks: [] });
|
|
118
|
+
else
|
|
119
|
+
files.push({ path, status: "modified", ranges: [], hunks: [] });
|
|
120
|
+
}
|
|
121
|
+
return files;
|
|
122
|
+
}
|
|
123
|
+
/** Attach each hunk's post-image range — and its text — to its file. */
|
|
124
|
+
function applyHunks(files, patch) {
|
|
125
|
+
const byPath = new Map(files.map((f) => [f.path, f]));
|
|
126
|
+
let current;
|
|
127
|
+
let hunk;
|
|
128
|
+
/** Post-image number for the next `+` line of the open hunk. */
|
|
129
|
+
let next = 0;
|
|
130
|
+
let kept = 0;
|
|
131
|
+
for (const line of patch.split("\n")) {
|
|
132
|
+
// Every file starts with this, and a content line cannot: a deleted one begins
|
|
133
|
+
// with `-`. Closing the open hunk here is what stops the NEXT file's `--- a/x`
|
|
134
|
+
// header being absorbed as a deleted line of the previous hunk.
|
|
135
|
+
if (line.startsWith("diff --git ")) {
|
|
136
|
+
current = undefined;
|
|
137
|
+
hunk = undefined;
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
if (line.startsWith("+++ ")) {
|
|
141
|
+
const raw = line.slice(4);
|
|
142
|
+
current = raw === "/dev/null" ? undefined : byPath.get(stripPrefix(raw));
|
|
143
|
+
hunk = undefined;
|
|
144
|
+
kept = 0;
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
if (line.startsWith("@@")) {
|
|
148
|
+
hunk = undefined;
|
|
149
|
+
if (!current)
|
|
150
|
+
continue;
|
|
151
|
+
const m = HUNK_RE.exec(line);
|
|
152
|
+
if (!m)
|
|
153
|
+
continue;
|
|
154
|
+
const start = Number(m[1]);
|
|
155
|
+
// `+N,0` is a pure deletion: nothing survives in the post-image, and git
|
|
156
|
+
// reports the line BEFORE the gap. Recording that single line is what keeps
|
|
157
|
+
// "the body of foo() lost 10 lines" attributable to foo() at all.
|
|
158
|
+
const count = m[2] === undefined ? 1 : Number(m[2]);
|
|
159
|
+
const range = count === 0 ? { start, end: start } : { start, end: start + count - 1 };
|
|
160
|
+
hunk = { ...range, lines: [], dropped: 0 };
|
|
161
|
+
current.ranges.push(range);
|
|
162
|
+
current.hunks.push(hunk);
|
|
163
|
+
next = start;
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
if (!hunk)
|
|
167
|
+
continue;
|
|
168
|
+
// With `--unified=0` every line inside a hunk is an edit, so there is no
|
|
169
|
+
// context to skip. `+++`/`---` headers are already consumed above; a bare
|
|
170
|
+
// `--- a/x` for the next file arrives before its `+++`, and the `!hunk`
|
|
171
|
+
// guard on a fresh file keeps it out.
|
|
172
|
+
if (line.startsWith("+")) {
|
|
173
|
+
pushLine(hunk, { n: next, sign: "+", text: line.slice(1) }, kept++ < MAX_FILE_LINES);
|
|
174
|
+
next += 1;
|
|
175
|
+
}
|
|
176
|
+
else if (line.startsWith("-")) {
|
|
177
|
+
pushLine(hunk, { n: null, sign: "-", text: line.slice(1) }, kept++ < MAX_FILE_LINES);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
function pushLine(hunk, line, withinFile) {
|
|
182
|
+
if (!withinFile || hunk.lines.length >= MAX_HUNK_LINES) {
|
|
183
|
+
hunk.dropped += 1;
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
hunk.lines.push(line);
|
|
187
|
+
}
|
|
188
|
+
/** `b/src/x.ts` → `src/x.ts`, minus any trailing tab-separated timestamp. */
|
|
189
|
+
function stripPrefix(raw) {
|
|
190
|
+
const untabbed = raw.split("\t")[0];
|
|
191
|
+
return untabbed.startsWith("b/") ? untabbed.slice(2) : untabbed;
|
|
192
|
+
}
|
|
193
|
+
//# sourceMappingURL=diff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/blast/diff.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export interface ModuleIndex {
|
|
2
|
+
/** Label for a repo-relative path — a concept name when one claims the file. */
|
|
3
|
+
labelOf(path: string): string;
|
|
4
|
+
/** The claiming concept's name, or null when only the directory fallback applies.
|
|
5
|
+
* Callers that group files need to tell the two apart: a shared concept is a real
|
|
6
|
+
* grouping signal, a shared directory is only a shared directory. */
|
|
7
|
+
conceptOf(path: string): string | null;
|
|
8
|
+
/** True when at least one concept node was read (i.e. a --deep graph). */
|
|
9
|
+
hasConcepts: boolean;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Build the path → module-label lookup for a context dir.
|
|
13
|
+
*
|
|
14
|
+
* A file can be cited by several concepts; the SMALLEST claiming concept wins.
|
|
15
|
+
* A concept grounded in three files says something specific about those three,
|
|
16
|
+
* while a forty-file concept is closer to "the codebase" — picking the tighter
|
|
17
|
+
* one keeps the diagram's boxes meaningful.
|
|
18
|
+
*/
|
|
19
|
+
export declare function moduleIndex(contextDir: string): ModuleIndex;
|
|
20
|
+
/**
|
|
21
|
+
* A concept name trimmed to fit a node.
|
|
22
|
+
*
|
|
23
|
+
* Concept names are written for a reader with the whole file in front of them, so
|
|
24
|
+
* they run long and some carry a `Concept: ` prefix from the synthesis prompt.
|
|
25
|
+
* "Reciprocal-Rank Fusion for Workspace Federation" is a fine node title in `graft
|
|
26
|
+
* viz` and unreadable inside a circle.
|
|
27
|
+
*/
|
|
28
|
+
export declare function shortLabel(label: string): string;
|
|
29
|
+
/** The parent directory of a directory label, or "" at the top level. */
|
|
30
|
+
export declare function parentDir(dir: string): string;
|
|
31
|
+
/** Fallback label: the file's directory, or `(root)` for a top-level file. */
|
|
32
|
+
export declare function dirLabel(path: string): string;
|
|
33
|
+
//# sourceMappingURL=modules.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"modules.d.ts","sourceRoot":"","sources":["../../src/blast/modules.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,WAAW;IAC1B,gFAAgF;IAChF,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAC9B;;yEAEqE;IACrE,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACvC,0EAA0E;IAC1E,WAAW,EAAE,OAAO,CAAC;CACtB;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,WAAW,CAiB3D;AAeD;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAWhD;AAED,yEAAyE;AACzE,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAI7C;AAED,8EAA8E;AAC9E,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG7C"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Module labels for the blast diagram — the "what part of the system is this?"
|
|
3
|
+
* layer, so a reviewer reads `Graph Extraction and Loading` instead of eleven
|
|
4
|
+
* file paths.
|
|
5
|
+
*
|
|
6
|
+
* Two sources, best first:
|
|
7
|
+
* 1. the deep tier's concept nodes (`graft/*.md`), whose frontmatter lists the
|
|
8
|
+
* source files each concept was synthesized from. This is why `blast` is
|
|
9
|
+
* worth running on a `build --deep` graph: the grouping is the product.
|
|
10
|
+
* 2. the file's directory, when no concept claims it (a breadth-tier graph, or
|
|
11
|
+
* a file added by this very PR and therefore absent from the concept layer).
|
|
12
|
+
*/
|
|
13
|
+
import { readNodes } from "../context/node-file.js";
|
|
14
|
+
/**
|
|
15
|
+
* Build the path → module-label lookup for a context dir.
|
|
16
|
+
*
|
|
17
|
+
* A file can be cited by several concepts; the SMALLEST claiming concept wins.
|
|
18
|
+
* A concept grounded in three files says something specific about those three,
|
|
19
|
+
* while a forty-file concept is closer to "the codebase" — picking the tighter
|
|
20
|
+
* one keeps the diagram's boxes meaningful.
|
|
21
|
+
*/
|
|
22
|
+
export function moduleIndex(contextDir) {
|
|
23
|
+
const claims = new Map();
|
|
24
|
+
const nodes = readNodes(contextDir);
|
|
25
|
+
for (const node of nodes) {
|
|
26
|
+
if (!node.name)
|
|
27
|
+
continue;
|
|
28
|
+
for (const src of node.sources) {
|
|
29
|
+
const prev = claims.get(src.path);
|
|
30
|
+
if (!prev || node.sources.length < prev.size) {
|
|
31
|
+
claims.set(src.path, { label: node.name, size: node.sources.length });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
hasConcepts: nodes.length > 0,
|
|
37
|
+
labelOf: (path) => shortLabel(claims.get(path)?.label ?? dirLabel(path)),
|
|
38
|
+
conceptOf: (path) => claims.get(path)?.label ?? null,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/** Longest label a circle can hold before the text overruns it. */
|
|
42
|
+
const MAX_LABEL = 30;
|
|
43
|
+
/**
|
|
44
|
+
* Clause breaks a long concept name can be cut at.
|
|
45
|
+
*
|
|
46
|
+
* A concept name is a sentence fragment, so it has real joints: everything after
|
|
47
|
+
* "via", "and", a colon or an opening parenthesis is elaboration. Cutting there
|
|
48
|
+
* leaves a phrase that still reads as a name — "Incremental Build" rather than
|
|
49
|
+
* "Incremental Build via…" — which is why these cuts take no ellipsis.
|
|
50
|
+
*/
|
|
51
|
+
const CLAUSE_BREAK = /\s(?:\(|—|-\s)|:\s|\s(?:via|and|for|with|using|in|across|over|from|of|by|to)\s/i;
|
|
52
|
+
/**
|
|
53
|
+
* A concept name trimmed to fit a node.
|
|
54
|
+
*
|
|
55
|
+
* Concept names are written for a reader with the whole file in front of them, so
|
|
56
|
+
* they run long and some carry a `Concept: ` prefix from the synthesis prompt.
|
|
57
|
+
* "Reciprocal-Rank Fusion for Workspace Federation" is a fine node title in `graft
|
|
58
|
+
* viz` and unreadable inside a circle.
|
|
59
|
+
*/
|
|
60
|
+
export function shortLabel(label) {
|
|
61
|
+
const bare = label.replace(/^concepts?:\s*/i, "").trim();
|
|
62
|
+
if (bare.length <= MAX_LABEL)
|
|
63
|
+
return bare;
|
|
64
|
+
const at = CLAUSE_BREAK.exec(bare);
|
|
65
|
+
if (at && at.index >= 8 && at.index <= MAX_LABEL)
|
|
66
|
+
return bare.slice(0, at.index).trimEnd();
|
|
67
|
+
// No usable joint: a word-boundary cut, marked, because this one really does stop
|
|
68
|
+
// mid-phrase and a reader must not take the fragment for the whole name.
|
|
69
|
+
const cut = bare.lastIndexOf(" ", MAX_LABEL);
|
|
70
|
+
return `${bare.slice(0, cut > MAX_LABEL / 2 ? cut : MAX_LABEL).trimEnd()}…`;
|
|
71
|
+
}
|
|
72
|
+
/** The parent directory of a directory label, or "" at the top level. */
|
|
73
|
+
export function parentDir(dir) {
|
|
74
|
+
const trimmed = dir.replace(/\/$/, "");
|
|
75
|
+
const cut = trimmed.lastIndexOf("/");
|
|
76
|
+
return cut === -1 ? "" : `${trimmed.slice(0, cut)}/`;
|
|
77
|
+
}
|
|
78
|
+
/** Fallback label: the file's directory, or `(root)` for a top-level file. */
|
|
79
|
+
export function dirLabel(path) {
|
|
80
|
+
const cut = path.lastIndexOf("/");
|
|
81
|
+
return cut === -1 ? "(root)" : path.slice(0, cut) + "/";
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=modules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"modules.js","sourceRoot":"","sources":["../../src/blast/modules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAapD;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CAAC,UAAkB;IAC5C,MAAM,MAAM,GAAG,IAAI,GAAG,EAA2C,CAAC;IAClE,MAAM,KAAK,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC;IACpC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,IAAI,CAAC,IAAI;YAAE,SAAS;QACzB,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAC/B,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAClC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;gBAC7C,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;YACxE,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO;QACL,WAAW,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC;QAC7B,OAAO,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,KAAK,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC;QAChF,SAAS,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,KAAK,IAAI,IAAI;KAC7D,CAAC;AACJ,CAAC;AAED,mEAAmE;AACnE,MAAM,SAAS,GAAG,EAAE,CAAC;AAErB;;;;;;;GAOG;AACH,MAAM,YAAY,GAAG,iFAAiF,CAAC;AAEvG;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACzD,IAAI,IAAI,CAAC,MAAM,IAAI,SAAS;QAAE,OAAO,IAAI,CAAC;IAE1C,MAAM,EAAE,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnC,IAAI,EAAE,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,SAAS;QAAE,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;IAE3F,kFAAkF;IAClF,yEAAyE;IACzE,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAC7C,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,GAAG,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,GAAG,CAAC;AAC9E,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,SAAS,CAAC,GAAW;IACnC,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACvC,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACrC,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC;AACvD,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,QAAQ,CAAC,IAAY;IACnC,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAClC,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC;AAC1D,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { ChatModel } from "../ai/llm/types.js";
|
|
2
|
+
import type { GraphV1 } from "../graph/types.js";
|
|
3
|
+
import type { BlastReport } from "./blast.js";
|
|
4
|
+
/** One cluster to name: its identity, its files and the symbols inside it. */
|
|
5
|
+
export interface Cluster {
|
|
6
|
+
key: string;
|
|
7
|
+
files: string[];
|
|
8
|
+
symbols: string[];
|
|
9
|
+
}
|
|
10
|
+
/** Anything that can turn clusters into names. A model in production, a stub in tests. */
|
|
11
|
+
export interface Namer {
|
|
12
|
+
/** Names by cluster key. A key the namer chose not to name is simply absent. */
|
|
13
|
+
name(clusters: Cluster[]): Promise<Map<string, string>>;
|
|
14
|
+
}
|
|
15
|
+
export interface NameStats {
|
|
16
|
+
/** Labels taken from the cache, and labels that cost a call. */
|
|
17
|
+
cached: number;
|
|
18
|
+
named: number;
|
|
19
|
+
/** Clusters the namer declined ("mixed") or could not answer for. */
|
|
20
|
+
declined: number;
|
|
21
|
+
/** Set when naming was attempted and failed outright; the reason, for one line
|
|
22
|
+
* in the report. Never thrown: a comment without names still beats no comment. */
|
|
23
|
+
error?: string;
|
|
24
|
+
}
|
|
25
|
+
/** The production namer: one forced-tool call for every cluster at once. */
|
|
26
|
+
export declare class ChatNamer implements Namer {
|
|
27
|
+
private readonly model;
|
|
28
|
+
constructor(model: ChatModel);
|
|
29
|
+
name(clusters: Cluster[]): Promise<Map<string, string>>;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* A model-written string on its way into a Mermaid label and a markdown table.
|
|
33
|
+
*
|
|
34
|
+
* Symbol names from a fork's diff reach the prompt, so the answer is untrusted
|
|
35
|
+
* input: anything that could close a label, open a tag or start a table cell is
|
|
36
|
+
* stripped here rather than at each render site.
|
|
37
|
+
*/
|
|
38
|
+
export declare function sanitize(raw: string): string;
|
|
39
|
+
/**
|
|
40
|
+
* The cache key for a cluster: what it contains, not what it is called.
|
|
41
|
+
*
|
|
42
|
+
* Member paths pin the shape and each member's `body_hash` pins the content, so a
|
|
43
|
+
* cluster is renamed only when the code in it actually changes. Without this the
|
|
44
|
+
* same area gets a slightly different name on every PR and two comments stop being
|
|
45
|
+
* comparable — the failure the cache exists to prevent.
|
|
46
|
+
*/
|
|
47
|
+
export declare function clusterHash(files: string[], hashes: Map<string, string>): string;
|
|
48
|
+
export declare function loadNameCache(contextDir: string): Record<string, string>;
|
|
49
|
+
export declare function saveNameCache(contextDir: string, names: Record<string, string>): void;
|
|
50
|
+
/**
|
|
51
|
+
* Fill in labels for every cluster still sitting on its symbol backstop.
|
|
52
|
+
*
|
|
53
|
+
* Clusters already named by a concept node are left alone: a concept was written
|
|
54
|
+
* from whole file bodies, which is strictly more than the paths and symbol names
|
|
55
|
+
* this pass can see.
|
|
56
|
+
*/
|
|
57
|
+
export declare function applyNames(graph: GraphV1, report: BlastReport, opts: {
|
|
58
|
+
namer?: Namer;
|
|
59
|
+
contextDir: string;
|
|
60
|
+
}): Promise<NameStats>;
|
|
61
|
+
//# sourceMappingURL=name.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"name.d.ts","sourceRoot":"","sources":["../../src/blast/name.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAA+B,MAAM,YAAY,CAAC;AAG3E,8EAA8E;AAC9E,MAAM,WAAW,OAAO;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,0FAA0F;AAC1F,MAAM,WAAW,KAAK;IACpB,gFAAgF;IAChF,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACzD;AAED,MAAM,WAAW,SAAS;IACxB,gEAAgE;IAChE,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,QAAQ,EAAE,MAAM,CAAC;IACjB;sFACkF;IAClF,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAqDD,4EAA4E;AAC5E,qBAAa,SAAU,YAAW,KAAK;IACzB,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,EAAE,SAAS;IAEvC,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAuB9D;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAG5C;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAGhF;AAMD,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CASxE;AAED,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAQrF;AAeD;;;;;;GAMG;AACH,wBAAsB,UAAU,CAC9B,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,WAAW,EACnB,IAAI,EAAE;IAAE,KAAK,CAAC,EAAE,KAAK,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAC1C,OAAO,CAAC,SAAS,CAAC,CAwDpB"}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Naming the clusters a diff reaches — the rung of the ladder between a concept
|
|
3
|
+
* node and the symbol backstop (see {@link LabelSource}).
|
|
4
|
+
*
|
|
5
|
+
* The point is scope. Getting labels from `build --deep` means summarising every
|
|
6
|
+
* file in the repo — 356 calls and thirteen minutes on graft's own repo — to put
|
|
7
|
+
* names on the six clusters a PR actually touches, and it still misses: only 40% of
|
|
8
|
+
* this repo's files are claimed by a concept, so the rest fall back to a path. Here
|
|
9
|
+
* the unit of work is the cluster, not the file: one request names all of them from
|
|
10
|
+
* data the graph already holds (paths and symbol names — no file reads), and the
|
|
11
|
+
* answer is cached by content hash so the next PR pays nothing for a cluster whose
|
|
12
|
+
* files did not change.
|
|
13
|
+
*
|
|
14
|
+
* Two rules keep it honest:
|
|
15
|
+
* - a cluster spanning unrelated features must come back "mixed", and then keeps
|
|
16
|
+
* its symbol backstop rather than a flattering name;
|
|
17
|
+
* - a failure of any kind — no key, spent quota, refused call, malformed answer —
|
|
18
|
+
* leaves every label exactly as it was and never fails the caller.
|
|
19
|
+
*/
|
|
20
|
+
import { createHash } from "node:crypto";
|
|
21
|
+
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
22
|
+
import { dirname, join } from "node:path";
|
|
23
|
+
import { CACHE_DIR } from "../context/node-file.js";
|
|
24
|
+
import { shortLabel } from "./modules.js";
|
|
25
|
+
const SYSTEM_PROMPT = `You name parts of a codebase for a pull-request reviewer.
|
|
26
|
+
|
|
27
|
+
You are given clusters of files that a change can affect. For each cluster, answer with the FEATURE or SUBSYSTEM those files implement, as a developer on the team would refer to it in conversation.
|
|
28
|
+
|
|
29
|
+
Rules:
|
|
30
|
+
- 2 to 4 words, Title Case. No trailing "Module", "System", "Layer", "Manager" or "Handler" unless the team would genuinely say it.
|
|
31
|
+
- Name the RESPONSIBILITY, not the mechanics: "Query Freshness Gate", "Workspace Federation", "Asset Bundling". Never restate a path or a directory name, and never name it after the language or the file type.
|
|
32
|
+
- If the files in a cluster serve two or more unrelated responsibilities, answer exactly "mixed" for that cluster. A wrong name is worse than no name, because a reviewer will trust it.
|
|
33
|
+
- Answer for every cluster key you are given, and invent no other keys.`;
|
|
34
|
+
const NAMES_SCHEMA = {
|
|
35
|
+
type: "object",
|
|
36
|
+
properties: {
|
|
37
|
+
names: {
|
|
38
|
+
type: "array",
|
|
39
|
+
items: {
|
|
40
|
+
type: "object",
|
|
41
|
+
properties: {
|
|
42
|
+
key: { type: "string", description: "the cluster key, copied verbatim" },
|
|
43
|
+
name: { type: "string", description: '2-4 word Title Case name, or "mixed"' },
|
|
44
|
+
},
|
|
45
|
+
required: ["key", "name"],
|
|
46
|
+
additionalProperties: false,
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
required: ["names"],
|
|
51
|
+
additionalProperties: false,
|
|
52
|
+
};
|
|
53
|
+
/** Symbols shown per cluster. Enough to characterise it; not a file listing. */
|
|
54
|
+
const SYMBOLS_PER_CLUSTER = 8;
|
|
55
|
+
/**
|
|
56
|
+
* Clusters per request. A PR's diagram needs six, so one batch covers it — the cap
|
|
57
|
+
* is for the cache-priming job, which deliberately walks a wide diff and can hand
|
|
58
|
+
* over fifty clusters at once. Past a dozen the prompt stops being a list and the
|
|
59
|
+
* model starts dropping keys.
|
|
60
|
+
*/
|
|
61
|
+
const CLUSTERS_PER_CALL = 12;
|
|
62
|
+
function clusterPrompt(clusters) {
|
|
63
|
+
return clusters
|
|
64
|
+
.map((c) => {
|
|
65
|
+
const files = c.files.slice(0, 10).join(", ");
|
|
66
|
+
const symbols = c.symbols.slice(0, SYMBOLS_PER_CLUSTER).join(", ");
|
|
67
|
+
return `key: ${c.key}\n files: ${files}\n symbols: ${symbols || "(none extracted)"}`;
|
|
68
|
+
})
|
|
69
|
+
.join("\n\n");
|
|
70
|
+
}
|
|
71
|
+
/** The production namer: one forced-tool call for every cluster at once. */
|
|
72
|
+
export class ChatNamer {
|
|
73
|
+
model;
|
|
74
|
+
constructor(model) {
|
|
75
|
+
this.model = model;
|
|
76
|
+
}
|
|
77
|
+
async name(clusters) {
|
|
78
|
+
const res = await this.model.create({
|
|
79
|
+
messages: [
|
|
80
|
+
{ role: "system", content: SYSTEM_PROMPT },
|
|
81
|
+
{ role: "user", content: clusterPrompt(clusters) },
|
|
82
|
+
],
|
|
83
|
+
tools: [{ name: "record_names", description: "Record one name per cluster.", parameters: NAMES_SCHEMA }],
|
|
84
|
+
responseFormat: { kind: "tool", name: "record_names" },
|
|
85
|
+
temperature: 0,
|
|
86
|
+
maxTokens: 1024,
|
|
87
|
+
});
|
|
88
|
+
const out = new Map();
|
|
89
|
+
const call = res.toolCalls[0]?.args;
|
|
90
|
+
for (const row of call?.names ?? []) {
|
|
91
|
+
if (!row?.key || !row?.name)
|
|
92
|
+
continue;
|
|
93
|
+
const clean = sanitize(row.name);
|
|
94
|
+
// "mixed" is an answer, not a name: the cluster keeps its backstop.
|
|
95
|
+
if (!clean || /^mixed$/i.test(clean))
|
|
96
|
+
continue;
|
|
97
|
+
out.set(row.key, clean);
|
|
98
|
+
}
|
|
99
|
+
return out;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* A model-written string on its way into a Mermaid label and a markdown table.
|
|
104
|
+
*
|
|
105
|
+
* Symbol names from a fork's diff reach the prompt, so the answer is untrusted
|
|
106
|
+
* input: anything that could close a label, open a tag or start a table cell is
|
|
107
|
+
* stripped here rather than at each render site.
|
|
108
|
+
*/
|
|
109
|
+
export function sanitize(raw) {
|
|
110
|
+
const flat = raw.replace(/[\r\n]+/g, " ").replace(/[<>"'`|(){}[\]#]/g, "").replace(/\s+/g, " ").trim();
|
|
111
|
+
return shortLabel(flat);
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* The cache key for a cluster: what it contains, not what it is called.
|
|
115
|
+
*
|
|
116
|
+
* Member paths pin the shape and each member's `body_hash` pins the content, so a
|
|
117
|
+
* cluster is renamed only when the code in it actually changes. Without this the
|
|
118
|
+
* same area gets a slightly different name on every PR and two comments stop being
|
|
119
|
+
* comparable — the failure the cache exists to prevent.
|
|
120
|
+
*/
|
|
121
|
+
export function clusterHash(files, hashes) {
|
|
122
|
+
const parts = [...files].sort().map((f) => `${f}:${hashes.get(f) ?? "?"}`);
|
|
123
|
+
return createHash("sha256").update(parts.join("\n")).digest("hex").slice(0, 16);
|
|
124
|
+
}
|
|
125
|
+
function cachePath(contextDir) {
|
|
126
|
+
return join(contextDir, CACHE_DIR, "areas.json");
|
|
127
|
+
}
|
|
128
|
+
export function loadNameCache(contextDir) {
|
|
129
|
+
try {
|
|
130
|
+
const raw = JSON.parse(readFileSync(cachePath(contextDir), "utf8"));
|
|
131
|
+
return raw && typeof raw === "object" ? raw : {};
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
// A missing or corrupt cache is a cache miss, never an error: the names are
|
|
135
|
+
// derivable again, and refusing to run because a cache file is bad is worse.
|
|
136
|
+
return {};
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
export function saveNameCache(contextDir, names) {
|
|
140
|
+
const path = cachePath(contextDir);
|
|
141
|
+
try {
|
|
142
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
143
|
+
writeFileSync(path, `${JSON.stringify(names, null, 2)}\n`);
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
// Best-effort: an unwritable cache costs a call next time, nothing more.
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/** File-node content hashes, which is what a cluster's identity is built from. */
|
|
150
|
+
function fileHashes(graph) {
|
|
151
|
+
const out = new Map();
|
|
152
|
+
for (const n of graph.nodes)
|
|
153
|
+
if (n.kind === "file")
|
|
154
|
+
out.set(n.path, n.body_hash ?? "");
|
|
155
|
+
return out;
|
|
156
|
+
}
|
|
157
|
+
function symbolsOf(c) {
|
|
158
|
+
return "symbols" in c ? c.symbols.map((s) => s.name) : c.seedNames;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Fill in labels for every cluster still sitting on its symbol backstop.
|
|
162
|
+
*
|
|
163
|
+
* Clusters already named by a concept node are left alone: a concept was written
|
|
164
|
+
* from whole file bodies, which is strictly more than the paths and symbol names
|
|
165
|
+
* this pass can see.
|
|
166
|
+
*/
|
|
167
|
+
export async function applyNames(graph, report, opts) {
|
|
168
|
+
const stats = { cached: 0, named: 0, declined: 0 };
|
|
169
|
+
// `testModules` are deliberately absent: the comment shows them as a file count in
|
|
170
|
+
// one collapsed line and nowhere else, so naming them buys nothing and can push a
|
|
171
|
+
// normal PR over CLUSTERS_PER_CALL into a second request.
|
|
172
|
+
const targets = [...report.modules, ...report.areas]
|
|
173
|
+
.filter((c) => c.labelSource === "symbol");
|
|
174
|
+
if (targets.length === 0)
|
|
175
|
+
return stats;
|
|
176
|
+
const hashes = fileHashes(graph);
|
|
177
|
+
const cache = loadNameCache(opts.contextDir);
|
|
178
|
+
const pending = [];
|
|
179
|
+
/** Clusters sharing a hash share a name — and one call, not several. */
|
|
180
|
+
const byHash = new Map();
|
|
181
|
+
for (const t of targets) {
|
|
182
|
+
const hash = clusterHash(t.files, hashes);
|
|
183
|
+
byHash.set(hash, [...(byHash.get(hash) ?? []), t]);
|
|
184
|
+
}
|
|
185
|
+
for (const [hash, group] of byHash) {
|
|
186
|
+
const hit = cache[hash];
|
|
187
|
+
if (hit) {
|
|
188
|
+
for (const t of group) {
|
|
189
|
+
t.label = hit;
|
|
190
|
+
t.labelSource = "named";
|
|
191
|
+
}
|
|
192
|
+
stats.cached++;
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
pending.push({
|
|
196
|
+
cluster: { key: hash, files: group[0].files, symbols: symbolsOf(group[0]) },
|
|
197
|
+
targets: group,
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
if (pending.length === 0 || !opts.namer)
|
|
201
|
+
return stats;
|
|
202
|
+
const named = new Map();
|
|
203
|
+
for (let i = 0; i < pending.length; i += CLUSTERS_PER_CALL) {
|
|
204
|
+
const batch = pending.slice(i, i + CLUSTERS_PER_CALL);
|
|
205
|
+
try {
|
|
206
|
+
for (const [k, v] of await opts.namer.name(batch.map((p) => p.cluster)))
|
|
207
|
+
named.set(k, v);
|
|
208
|
+
}
|
|
209
|
+
catch (err) {
|
|
210
|
+
// Every label already holds its backstop, so there is nothing to undo — and a
|
|
211
|
+
// later batch failing must not discard the names an earlier one returned.
|
|
212
|
+
stats.error = err instanceof Error ? err.message : String(err);
|
|
213
|
+
break;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
for (const p of pending) {
|
|
217
|
+
const name = named.get(p.cluster.key);
|
|
218
|
+
if (!name) {
|
|
219
|
+
stats.declined++;
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
for (const t of p.targets) {
|
|
223
|
+
t.label = name;
|
|
224
|
+
t.labelSource = "named";
|
|
225
|
+
}
|
|
226
|
+
cache[p.cluster.key] = name;
|
|
227
|
+
stats.named++;
|
|
228
|
+
}
|
|
229
|
+
if (stats.named > 0)
|
|
230
|
+
saveNameCache(opts.contextDir, cache);
|
|
231
|
+
return stats;
|
|
232
|
+
}
|
|
233
|
+
//# sourceMappingURL=name.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"name.js","sourceRoot":"","sources":["../../src/blast/name.ts"],"names":[],"mappings":"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"}
|