thurview 0.17.1 → 0.18.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 +43 -43
- package/dist/cli.js +23 -222
- package/dist/cli.js.map +1 -1
- package/dist/coverage.js +53 -148
- package/dist/coverage.js.map +1 -1
- package/dist/document/compile.js +51 -43
- package/dist/document/compile.js.map +1 -1
- package/dist/document/schema.js +25 -13
- package/dist/document/schema.js.map +1 -1
- package/dist/git.js +29 -0
- package/dist/git.js.map +1 -1
- package/dist/interfaces.js +7 -244
- package/dist/interfaces.js.map +1 -1
- package/dist/ui/app.css +29 -10
- package/dist/ui/app.js +169 -192
- package/dist/ui/app.js.map +3 -3
- package/package.json +1 -12
- package/skills/thurview/SKILL.md +32 -34
- package/skills/thurview/references/components.md +45 -22
- package/skills/thurview/references/document-authoring.md +22 -26
- package/skills/thurview/references/searching.md +74 -0
- package/skills/thurview-design/SKILL.md +17 -14
- package/skills/thurview-design/references/anchors-and-proposals.md +11 -9
- package/skills/thurview-explain/SKILL.md +44 -31
- package/skills/thurview-fix/SKILL.md +47 -42
- package/dist/graph.js +0 -568
- package/dist/graph.js.map +0 -1
package/dist/graph.js
DELETED
|
@@ -1,568 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The code graph: symbols and the references between them at a pinned commit.
|
|
3
|
-
*
|
|
4
|
-
* Every supported grammar ships tree-sitter's `tags.scm`, the definitions-and-
|
|
5
|
-
* references query GitHub maintains for code navigation. Running it is the
|
|
6
|
-
* whole per-language extraction; the rest is name resolution and graph walks.
|
|
7
|
-
*/
|
|
8
|
-
import { readFile } from "node:fs/promises";
|
|
9
|
-
import { createRequire } from "node:module";
|
|
10
|
-
import { join } from "node:path";
|
|
11
|
-
import { Parser, Language, Query } from "web-tree-sitter";
|
|
12
|
-
import { listFiles } from "./git.js";
|
|
13
|
-
import { languageFor } from "./highlight.js";
|
|
14
|
-
import { catFiles } from "./symbols.js";
|
|
15
|
-
import { readJson, writeJson } from "./store.js";
|
|
16
|
-
/**
|
|
17
|
-
* Bumped whenever a field is added to CodeGraph. `graphAt` caches a built graph
|
|
18
|
-
* on disk keyed only by commit, so without this a graph written by an older
|
|
19
|
-
* binary loads with a field missing and every count derived from it silently
|
|
20
|
-
* reads as zero - a wrong number rather than an error, which is exactly what a
|
|
21
|
-
* document that states derived facts must never do.
|
|
22
|
-
*/
|
|
23
|
-
export const GRAPH_SCHEMA = 3;
|
|
24
|
-
const MODULE = "<module>";
|
|
25
|
-
const require = createRequire(import.meta.url);
|
|
26
|
-
import { UndirectedGraph } from "graphology";
|
|
27
|
-
// CommonJS with `export =` typings; the default import is the module under NodeNext.
|
|
28
|
-
const louvain = require("graphology-communities-louvain");
|
|
29
|
-
const GRAMMARS = {
|
|
30
|
-
javascript: {
|
|
31
|
-
pkg: "tree-sitter-javascript",
|
|
32
|
-
wasm: "tree-sitter-javascript.wasm",
|
|
33
|
-
tags: ["tree-sitter-javascript"],
|
|
34
|
-
},
|
|
35
|
-
typescript: {
|
|
36
|
-
pkg: "tree-sitter-typescript",
|
|
37
|
-
wasm: "tree-sitter-typescript.wasm",
|
|
38
|
-
tags: ["tree-sitter-javascript", "tree-sitter-typescript"],
|
|
39
|
-
},
|
|
40
|
-
tsx: {
|
|
41
|
-
pkg: "tree-sitter-typescript",
|
|
42
|
-
wasm: "tree-sitter-tsx.wasm",
|
|
43
|
-
tags: ["tree-sitter-javascript", "tree-sitter-typescript"],
|
|
44
|
-
},
|
|
45
|
-
python: {
|
|
46
|
-
pkg: "tree-sitter-python",
|
|
47
|
-
wasm: "tree-sitter-python.wasm",
|
|
48
|
-
tags: ["tree-sitter-python"],
|
|
49
|
-
},
|
|
50
|
-
go: { pkg: "tree-sitter-go", wasm: "tree-sitter-go.wasm", tags: ["tree-sitter-go"] },
|
|
51
|
-
rust: { pkg: "tree-sitter-rust", wasm: "tree-sitter-rust.wasm", tags: ["tree-sitter-rust"] },
|
|
52
|
-
java: { pkg: "tree-sitter-java", wasm: "tree-sitter-java.wasm", tags: ["tree-sitter-java"] },
|
|
53
|
-
elixir: {
|
|
54
|
-
pkg: "tree-sitter-elixir",
|
|
55
|
-
wasm: "tree-sitter-elixir.wasm",
|
|
56
|
-
tags: ["tree-sitter-elixir"],
|
|
57
|
-
},
|
|
58
|
-
};
|
|
59
|
-
GRAMMARS["jsx"] = GRAMMARS["javascript"];
|
|
60
|
-
export const LANGUAGES = Object.keys(GRAMMARS);
|
|
61
|
-
function pkgDir(pkg) {
|
|
62
|
-
return require.resolve(`${pkg}/package.json`).replace(/package\.json$/, "");
|
|
63
|
-
}
|
|
64
|
-
let init = null;
|
|
65
|
-
const loaded = new Map();
|
|
66
|
-
function grammarFor(lang) {
|
|
67
|
-
let p = loaded.get(lang);
|
|
68
|
-
if (!p) {
|
|
69
|
-
p = (async () => {
|
|
70
|
-
const gr = GRAMMARS[lang];
|
|
71
|
-
if (!init)
|
|
72
|
-
init = Parser.init();
|
|
73
|
-
await init;
|
|
74
|
-
const language = await Language.load(join(pkgDir(gr.pkg), gr.wasm));
|
|
75
|
-
const scm = await Promise.all(gr.tags.map((t) => readFile(join(pkgDir(t), "queries", "tags.scm"), "utf8")));
|
|
76
|
-
const parser = new Parser();
|
|
77
|
-
parser.setLanguage(language);
|
|
78
|
-
return { parser, query: new Query(language, scm.join("\n")) };
|
|
79
|
-
})();
|
|
80
|
-
loaded.set(lang, p);
|
|
81
|
-
}
|
|
82
|
-
return p;
|
|
83
|
-
}
|
|
84
|
-
async function tagsOf(lang, text) {
|
|
85
|
-
const { parser, query } = await grammarFor(lang);
|
|
86
|
-
const tree = parser.parse(text);
|
|
87
|
-
if (!tree)
|
|
88
|
-
return [];
|
|
89
|
-
try {
|
|
90
|
-
const found = [];
|
|
91
|
-
// A pattern that claims a name but produces no tag is asking for that name to be left
|
|
92
|
-
// alone as a CALL - Elixir spends seven of them keeping `def`, `import` and the rest of
|
|
93
|
-
// the macros that parse as ordinary calls out of the reference set. It never speaks to
|
|
94
|
-
// definitions: `def import(path)` puts the very name the pattern lists on the node that
|
|
95
|
-
// defines a function, and dropping that would delete the function from the graph.
|
|
96
|
-
const leaveAlone = new Set();
|
|
97
|
-
// A name a definition claims is that definition, not a call to it: Elixir's `def f(x)`
|
|
98
|
-
// nests a real call node inside the macro, so without this every function references
|
|
99
|
-
// itself on the line that defines it.
|
|
100
|
-
const defined = new Set();
|
|
101
|
-
for (const m of query.matches(tree.rootNode)) {
|
|
102
|
-
const tag = m.captures.find((c) => /^(definition|reference)\./.test(c.name));
|
|
103
|
-
const name = m.captures.find((c) => c.name === "name");
|
|
104
|
-
if (!tag) {
|
|
105
|
-
for (const c of m.captures) {
|
|
106
|
-
if (c.name === "ignore")
|
|
107
|
-
leaveAlone.add(`${c.node.startIndex}:${c.node.endIndex}`);
|
|
108
|
-
}
|
|
109
|
-
continue;
|
|
110
|
-
}
|
|
111
|
-
if (!name)
|
|
112
|
-
continue;
|
|
113
|
-
const [role, kind] = tag.name.split(".");
|
|
114
|
-
const at = `${name.node.startIndex}:${name.node.endIndex}`;
|
|
115
|
-
if (role === "definition")
|
|
116
|
-
defined.add(at);
|
|
117
|
-
found.push({
|
|
118
|
-
at,
|
|
119
|
-
tag: {
|
|
120
|
-
name: name.node.text,
|
|
121
|
-
kind,
|
|
122
|
-
role,
|
|
123
|
-
line: tag.node.startPosition.row + 1,
|
|
124
|
-
end: tag.node.endPosition.row + 1,
|
|
125
|
-
},
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
return found
|
|
129
|
-
.filter(({ at, tag }) => tag.role === "definition" || !(leaveAlone.has(at) || defined.has(at)))
|
|
130
|
-
.map(({ tag }) => tag);
|
|
131
|
-
}
|
|
132
|
-
finally {
|
|
133
|
-
tree.delete();
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
const SKIP = /(^|\/)(node_modules|dist|build|vendor|target|\.git)\//;
|
|
137
|
-
/** Kinds that give their contents a name rather than hide them: a definition inside one is
|
|
138
|
-
* addressable from another file as `Parent.child`, one inside a callable is not. The
|
|
139
|
-
* enclosing kind is what decides this, never the nested one, because a grammar is free not
|
|
140
|
-
* to distinguish a method at all - Python and Elixir both tag one `function`, so a rule
|
|
141
|
-
* reading the nested kind would hide every method those two languages define. */
|
|
142
|
-
const NAMESPACE_KINDS = new Set(["class", "interface", "module"]);
|
|
143
|
-
export function isTestFile(path) {
|
|
144
|
-
const name = path.split("/").pop() ?? "";
|
|
145
|
-
return (/(^|\/)(test|tests|__tests__|spec|specs|e2e)\//.test(path) ||
|
|
146
|
-
/\.(test|spec)\.\w+$|_test\.\w+$|^test_.*\.py$|Tests?\.java$/.test(name));
|
|
147
|
-
}
|
|
148
|
-
const MAX_FILES = 4000;
|
|
149
|
-
/** Whether the graph can parse `path` at all - independent of the repo-wide MAX_FILES cap. */
|
|
150
|
-
export function isGraphLanguage(path) {
|
|
151
|
-
return Boolean(GRAMMARS[languageFor(path)]) && !SKIP.test(path);
|
|
152
|
-
}
|
|
153
|
-
/** Cap a file list at MAX_FILES, reporting whether it had to be truncated. */
|
|
154
|
-
export function capFiles(files) {
|
|
155
|
-
return files.length > MAX_FILES
|
|
156
|
-
? { files: files.slice(0, MAX_FILES), truncated: true }
|
|
157
|
-
: { files, truncated: false };
|
|
158
|
-
}
|
|
159
|
-
/** Parse every supported file at `commit` and resolve references to definitions by name. */
|
|
160
|
-
export async function buildGraph(cwd, commit) {
|
|
161
|
-
const { files, truncated } = capFiles((await listFiles(cwd, commit)).filter(isGraphLanguage));
|
|
162
|
-
const symbols = [];
|
|
163
|
-
const byName = new Map();
|
|
164
|
-
const pending = [];
|
|
165
|
-
const modules = new Map();
|
|
166
|
-
const define = (s) => {
|
|
167
|
-
symbols.push(s);
|
|
168
|
-
const list = byName.get(s.name) ?? [];
|
|
169
|
-
list.push(s);
|
|
170
|
-
byName.set(s.name, list);
|
|
171
|
-
};
|
|
172
|
-
for (let i = 0; i < files.length; i += 200) {
|
|
173
|
-
const contents = await catFiles(cwd, commit, files.slice(i, i + 200));
|
|
174
|
-
for (const [file, text] of contents) {
|
|
175
|
-
if (text.length > 400_000)
|
|
176
|
-
continue;
|
|
177
|
-
const tags = await tagsOf(languageFor(file), text);
|
|
178
|
-
// Qualify nested definitions by their enclosing ones (`Class.method`,
|
|
179
|
-
// `render.onclick`) so ids survive line shifts; a repeat gets an ordinal.
|
|
180
|
-
const defs = [];
|
|
181
|
-
const qualified = [];
|
|
182
|
-
const seen = new Map();
|
|
183
|
-
const ordered = tags
|
|
184
|
-
.filter((t) => t.role === "definition")
|
|
185
|
-
.sort((a, b) => a.line - b.line || b.end - a.end);
|
|
186
|
-
for (const t of ordered) {
|
|
187
|
-
let parent = "";
|
|
188
|
-
let enclosedBy;
|
|
189
|
-
for (let i = defs.length - 1; i >= 0; i--) {
|
|
190
|
-
const d = defs[i];
|
|
191
|
-
if (d.line <= t.line && t.end <= d.end && !(d.line === t.line && d.end === t.end)) {
|
|
192
|
-
parent = qualified[i];
|
|
193
|
-
enclosedBy = d;
|
|
194
|
-
break;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
const q = parent ? `${parent}.${t.name}` : t.name;
|
|
198
|
-
const n = (seen.get(q) ?? 0) + 1;
|
|
199
|
-
seen.set(q, n);
|
|
200
|
-
const id = `${file}:${q}${n > 1 ? `#${n}` : ""}`;
|
|
201
|
-
const s = { id, name: t.name, kind: t.kind, file, line: t.line, end: t.end };
|
|
202
|
-
// an enclosing definition that is itself unreachable takes its contents with it,
|
|
203
|
-
// so a namespace nested in a function does not make its members addressable
|
|
204
|
-
if (enclosedBy && (enclosedBy.fileScoped || !NAMESPACE_KINDS.has(enclosedBy.kind))) {
|
|
205
|
-
s.fileScoped = true;
|
|
206
|
-
}
|
|
207
|
-
defs.push(s);
|
|
208
|
-
qualified.push(q);
|
|
209
|
-
define(s);
|
|
210
|
-
}
|
|
211
|
-
pending.push({ file, defs, refs: tags.filter((t) => t.role === "reference") });
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
const edges = [];
|
|
215
|
-
const seenEdges = new Set();
|
|
216
|
-
let unresolved = 0;
|
|
217
|
-
const unresolvedByFile = {};
|
|
218
|
-
for (const { file, defs, refs } of pending) {
|
|
219
|
-
// innermost enclosing definition: the last one that starts at or before the line
|
|
220
|
-
const enclosing = (line) => {
|
|
221
|
-
let best = null;
|
|
222
|
-
for (const d of defs)
|
|
223
|
-
if (d.line <= line && line <= d.end)
|
|
224
|
-
best = d;
|
|
225
|
-
if (best)
|
|
226
|
-
return best;
|
|
227
|
-
let m = modules.get(file);
|
|
228
|
-
if (!m) {
|
|
229
|
-
m = { id: `${file}:${MODULE}`, name: MODULE, kind: "module", file, line: 1, end: 1 };
|
|
230
|
-
modules.set(file, m);
|
|
231
|
-
symbols.push(m);
|
|
232
|
-
}
|
|
233
|
-
return m;
|
|
234
|
-
};
|
|
235
|
-
for (const r of refs) {
|
|
236
|
-
const candidates = byName.get(r.name) ?? [];
|
|
237
|
-
const sole = candidates.length === 1 ? candidates[0] : undefined;
|
|
238
|
-
const target = candidates.find((c) => c.file === file) ?? (sole && !sole.fileScoped ? sole : undefined);
|
|
239
|
-
if (!target) {
|
|
240
|
-
unresolved++;
|
|
241
|
-
unresolvedByFile[file] = (unresolvedByFile[file] ?? 0) + 1;
|
|
242
|
-
continue;
|
|
243
|
-
}
|
|
244
|
-
const from = enclosing(r.line);
|
|
245
|
-
const key = `${from.id}>${target.id}@${r.line}`;
|
|
246
|
-
if (seenEdges.has(key))
|
|
247
|
-
continue;
|
|
248
|
-
seenEdges.add(key);
|
|
249
|
-
edges.push({ from: from.id, to: target.id, kind: r.kind, at: r.line });
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
return {
|
|
253
|
-
schema: GRAPH_SCHEMA,
|
|
254
|
-
commit,
|
|
255
|
-
files,
|
|
256
|
-
symbols,
|
|
257
|
-
edges,
|
|
258
|
-
unresolved,
|
|
259
|
-
unresolvedByFile,
|
|
260
|
-
truncated,
|
|
261
|
-
};
|
|
262
|
-
}
|
|
263
|
-
/** Build the graph, or reuse the one cached under `dir` for that commit. */
|
|
264
|
-
export async function graphAt(cwd, commit, dir) {
|
|
265
|
-
const path = join(dir, "graph", `${commit}.json`);
|
|
266
|
-
const cached = await readJson(path);
|
|
267
|
-
if (cached && cached.commit === commit && cached.schema === GRAPH_SCHEMA)
|
|
268
|
-
return cached;
|
|
269
|
-
const g = await buildGraph(cwd, commit);
|
|
270
|
-
await writeJson(path, g);
|
|
271
|
-
return g;
|
|
272
|
-
}
|
|
273
|
-
function index(g) {
|
|
274
|
-
const byId = new Map(g.symbols.map((s) => [s.id, s]));
|
|
275
|
-
const callersOf = new Map();
|
|
276
|
-
for (const e of g.edges) {
|
|
277
|
-
const list = callersOf.get(e.to) ?? [];
|
|
278
|
-
list.push(e);
|
|
279
|
-
callersOf.set(e.to, list);
|
|
280
|
-
}
|
|
281
|
-
return { byId, callersOf };
|
|
282
|
-
}
|
|
283
|
-
/** Every reference to a definition named `name`, with the symbol it sits in. */
|
|
284
|
-
export function callers(g, name) {
|
|
285
|
-
const { byId, callersOf } = index(g);
|
|
286
|
-
const out = [];
|
|
287
|
-
for (const def of g.symbols.filter((s) => s.name === name))
|
|
288
|
-
for (const e of callersOf.get(def.id) ?? []) {
|
|
289
|
-
const from = byId.get(e.from);
|
|
290
|
-
out.push({ symbol: from.name, file: from.file, line: from.line, at: e.at });
|
|
291
|
-
}
|
|
292
|
-
return out.sort((a, b) => a.file.localeCompare(b.file) || a.at - b.at);
|
|
293
|
-
}
|
|
294
|
-
/** Symbols that transitively reference any of `roots`, up to `depth` hops, nearest first. */
|
|
295
|
-
export function reach(g, roots, depth) {
|
|
296
|
-
const { byId, callersOf } = index(g);
|
|
297
|
-
const seen = new Set(roots);
|
|
298
|
-
let frontier = roots;
|
|
299
|
-
const out = [];
|
|
300
|
-
for (let d = 1; d <= depth && frontier.length; d++) {
|
|
301
|
-
const next = [];
|
|
302
|
-
for (const id of frontier)
|
|
303
|
-
for (const e of callersOf.get(id) ?? []) {
|
|
304
|
-
if (seen.has(e.from))
|
|
305
|
-
continue;
|
|
306
|
-
seen.add(e.from);
|
|
307
|
-
next.push(e.from);
|
|
308
|
-
const s = byId.get(e.from);
|
|
309
|
-
out.push({
|
|
310
|
-
id: e.from,
|
|
311
|
-
symbol: s.name,
|
|
312
|
-
file: s.file,
|
|
313
|
-
line: s.line,
|
|
314
|
-
depth: d,
|
|
315
|
-
via: id,
|
|
316
|
-
at: e.at,
|
|
317
|
-
});
|
|
318
|
-
}
|
|
319
|
-
frontier = next;
|
|
320
|
-
}
|
|
321
|
-
return out;
|
|
322
|
-
}
|
|
323
|
-
/** Test-file symbols that reach a definition named `name`. */
|
|
324
|
-
export function testsFor(g, name, depth) {
|
|
325
|
-
const roots = g.symbols.filter((s) => s.name === name).map((s) => s.id);
|
|
326
|
-
return reach(g, roots, depth)
|
|
327
|
-
.filter((r) => isTestFile(r.file))
|
|
328
|
-
.map((r) => ({ file: r.file, symbol: r.symbol, depth: r.depth }));
|
|
329
|
-
}
|
|
330
|
-
function edgeKey(e) {
|
|
331
|
-
return `${e.from} -> ${e.to}`;
|
|
332
|
-
}
|
|
333
|
-
function touches(s, lines) {
|
|
334
|
-
if (!lines)
|
|
335
|
-
return false;
|
|
336
|
-
for (let l = s.line; l <= s.end; l++)
|
|
337
|
-
if (lines.has(l))
|
|
338
|
-
return true;
|
|
339
|
-
return false;
|
|
340
|
-
}
|
|
341
|
-
/** What the diff changed in the graph, and what at head depends on it. */
|
|
342
|
-
export function impact(base, head, changes, depth) {
|
|
343
|
-
const baseIds = new Map(base.symbols.map((s) => [s.id, s]));
|
|
344
|
-
const headIds = new Map(head.symbols.map((s) => [s.id, s]));
|
|
345
|
-
const deletedByBasePath = new Map();
|
|
346
|
-
const renamedTo = new Map();
|
|
347
|
-
for (const [path, c] of changes) {
|
|
348
|
-
deletedByBasePath.set(c.oldPath ?? path, c.deleted);
|
|
349
|
-
if (c.oldPath)
|
|
350
|
-
renamedTo.set(c.oldPath, path);
|
|
351
|
-
}
|
|
352
|
-
// a rename qualifies every id in the file under the new path, so the id itself can't
|
|
353
|
-
// be compared across base/head; re-derive the counterpart id under the other path first.
|
|
354
|
-
const rebase = (id, file, otherPath) => `${otherPath}${id.slice(file.length)}`;
|
|
355
|
-
const changed = [];
|
|
356
|
-
const row = (s, change) => ({
|
|
357
|
-
id: s.id,
|
|
358
|
-
symbol: s.name,
|
|
359
|
-
file: s.file,
|
|
360
|
-
line: s.line,
|
|
361
|
-
kind: s.kind,
|
|
362
|
-
change,
|
|
363
|
-
});
|
|
364
|
-
for (const s of head.symbols) {
|
|
365
|
-
if (s.name === MODULE)
|
|
366
|
-
continue;
|
|
367
|
-
const change = changes.get(s.file);
|
|
368
|
-
const oldPath = change?.oldPath;
|
|
369
|
-
const baseSym = baseIds.get(oldPath ? rebase(s.id, s.file, oldPath) : s.id);
|
|
370
|
-
if (!baseSym) {
|
|
371
|
-
if (changes.has(s.file))
|
|
372
|
-
changed.push(row(s, "added"));
|
|
373
|
-
}
|
|
374
|
-
else if (touches(s, change?.added) ||
|
|
375
|
-
touches(baseSym, deletedByBasePath.get(oldPath ?? s.file)))
|
|
376
|
-
changed.push(row(s, "modified"));
|
|
377
|
-
}
|
|
378
|
-
for (const s of base.symbols) {
|
|
379
|
-
if (s.name === MODULE || !deletedByBasePath.has(s.file))
|
|
380
|
-
continue;
|
|
381
|
-
const newPath = renamedTo.get(s.file);
|
|
382
|
-
if (!headIds.has(newPath ? rebase(s.id, s.file, newPath) : s.id))
|
|
383
|
-
changed.push(row(s, "removed"));
|
|
384
|
-
}
|
|
385
|
-
const baseEdges = new Set(base.edges.map(edgeKey));
|
|
386
|
-
const headEdges = new Set(head.edges.map(edgeKey));
|
|
387
|
-
const added = [...headEdges].filter((k) => !baseEdges.has(k)).sort();
|
|
388
|
-
const removed = [...baseEdges].filter((k) => !headEdges.has(k)).sort();
|
|
389
|
-
const roots = changed.filter((c) => c.change !== "removed").map((c) => c.id);
|
|
390
|
-
const r = reach(head, roots, depth);
|
|
391
|
-
const covers = new Map();
|
|
392
|
-
const { callersOf } = index(head);
|
|
393
|
-
for (const root of roots) {
|
|
394
|
-
const seen = new Set([root]);
|
|
395
|
-
let frontier = [root];
|
|
396
|
-
for (let d = 0; d <= depth && frontier.length; d++) {
|
|
397
|
-
const next = [];
|
|
398
|
-
for (const id of frontier) {
|
|
399
|
-
const s = headIds.get(id);
|
|
400
|
-
if (isTestFile(s.file)) {
|
|
401
|
-
const set = covers.get(s.file) ?? new Set();
|
|
402
|
-
set.add(root);
|
|
403
|
-
covers.set(s.file, set);
|
|
404
|
-
}
|
|
405
|
-
for (const e of callersOf.get(id) ?? [])
|
|
406
|
-
if (!seen.has(e.from)) {
|
|
407
|
-
seen.add(e.from);
|
|
408
|
-
next.push(e.from);
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
frontier = next;
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
const tested = new Set([...covers.values()].flatMap((s) => [...s]));
|
|
415
|
-
// What the tests exercise within `depth` calls, walking forward from every test
|
|
416
|
-
// symbol: a caller no test reaches is where a regression ships unnoticed.
|
|
417
|
-
const calls = new Map();
|
|
418
|
-
for (const e of head.edges) {
|
|
419
|
-
const list = calls.get(e.from) ?? [];
|
|
420
|
-
list.push(e.to);
|
|
421
|
-
calls.set(e.from, list);
|
|
422
|
-
}
|
|
423
|
-
const exercised = new Set();
|
|
424
|
-
let front = head.symbols.filter((s) => isTestFile(s.file)).map((s) => s.id);
|
|
425
|
-
for (let d = 1; d <= depth && front.length; d++) {
|
|
426
|
-
const next = [];
|
|
427
|
-
for (const id of front)
|
|
428
|
-
for (const to of calls.get(id) ?? [])
|
|
429
|
-
if (!exercised.has(to)) {
|
|
430
|
-
exercised.add(to);
|
|
431
|
-
next.push(to);
|
|
432
|
-
}
|
|
433
|
-
front = next;
|
|
434
|
-
}
|
|
435
|
-
return {
|
|
436
|
-
changed,
|
|
437
|
-
edges: { added, removed },
|
|
438
|
-
reach: r
|
|
439
|
-
.filter((x) => !isTestFile(x.file))
|
|
440
|
-
.map(({ id, ...x }) => ({ ...x, tested: exercised.has(id) })),
|
|
441
|
-
tests: [...covers]
|
|
442
|
-
.map(([file, set]) => ({ file, covers: [...set].sort() }))
|
|
443
|
-
.sort((a, b) => a.file.localeCompare(b.file)),
|
|
444
|
-
untested: roots.filter((id) => !tested.has(id)).sort(),
|
|
445
|
-
unresolved: { base: base.unresolved, head: head.unresolved },
|
|
446
|
-
truncated: { base: base.truncated, head: head.truncated },
|
|
447
|
-
};
|
|
448
|
-
}
|
|
449
|
-
/** A fixed-seed PRNG, so a pinned commit always clusters the same way. */
|
|
450
|
-
function seeded(seed) {
|
|
451
|
-
let a = seed >>> 0;
|
|
452
|
-
return () => {
|
|
453
|
-
a = (a + 0x6d2b79f5) >>> 0;
|
|
454
|
-
let t = Math.imul(a ^ (a >>> 15), 1 | a);
|
|
455
|
-
t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
|
|
456
|
-
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
|
457
|
-
};
|
|
458
|
-
}
|
|
459
|
-
function fileEdges(g) {
|
|
460
|
-
const byId = new Map(g.symbols.map((s) => [s.id, s.file]));
|
|
461
|
-
const out = new Map();
|
|
462
|
-
for (const e of g.edges) {
|
|
463
|
-
const a = byId.get(e.from);
|
|
464
|
-
const b = byId.get(e.to);
|
|
465
|
-
if (a === b)
|
|
466
|
-
continue;
|
|
467
|
-
const k = `${a} -> ${b}`;
|
|
468
|
-
out.set(k, (out.get(k) ?? 0) + 1);
|
|
469
|
-
}
|
|
470
|
-
return out;
|
|
471
|
-
}
|
|
472
|
-
function mainDir(files) {
|
|
473
|
-
const count = new Map();
|
|
474
|
-
for (const f of files) {
|
|
475
|
-
const dir = f.split("/").slice(0, -1).join("/") || ".";
|
|
476
|
-
count.set(dir, (count.get(dir) ?? 0) + 1);
|
|
477
|
-
}
|
|
478
|
-
return [...count].sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))[0][0];
|
|
479
|
-
}
|
|
480
|
-
/** Files clustered by how they reference each other at head, and the file-level diff against base. */
|
|
481
|
-
export function architecture(base, head) {
|
|
482
|
-
const headEdges = fileEdges(head);
|
|
483
|
-
const baseEdges = fileEdges(base);
|
|
484
|
-
const g = new UndirectedGraph();
|
|
485
|
-
const withSymbols = new Set(head.symbols.map((s) => s.file));
|
|
486
|
-
for (const f of head.files)
|
|
487
|
-
if (withSymbols.has(f))
|
|
488
|
-
g.addNode(f);
|
|
489
|
-
for (const [k, w] of headEdges) {
|
|
490
|
-
const [a, b] = k.split(" -> ");
|
|
491
|
-
if (g.hasEdge(a, b))
|
|
492
|
-
g.updateEdgeAttribute(a, b, "weight", (x) => x + w);
|
|
493
|
-
else
|
|
494
|
-
g.addEdge(a, b, { weight: w });
|
|
495
|
-
}
|
|
496
|
-
// Louvain is randomised, and a partition that moves between runs would move
|
|
497
|
-
// every count derived from it at the same pinned commit. Seed it so the same
|
|
498
|
-
// commit always yields the same structure.
|
|
499
|
-
const membership = g.order
|
|
500
|
-
? louvain(g, { getEdgeWeight: "weight", rng: seeded(0x7c1f9e3d) })
|
|
501
|
-
: {};
|
|
502
|
-
const groups = new Map();
|
|
503
|
-
for (const [file, c] of Object.entries(membership)) {
|
|
504
|
-
const list = groups.get(c) ?? [];
|
|
505
|
-
list.push(file);
|
|
506
|
-
groups.set(c, list);
|
|
507
|
-
}
|
|
508
|
-
const symbolsPerFile = new Map();
|
|
509
|
-
for (const s of head.symbols)
|
|
510
|
-
symbolsPerFile.set(s.file, (symbolsPerFile.get(s.file) ?? 0) + 1);
|
|
511
|
-
const fanIn = new Map();
|
|
512
|
-
for (const e of head.edges)
|
|
513
|
-
fanIn.set(e.to, (fanIn.get(e.to) ?? 0) + 1);
|
|
514
|
-
const symbolsIn = new Map();
|
|
515
|
-
for (const s of head.symbols) {
|
|
516
|
-
const list = symbolsIn.get(s.file) ?? [];
|
|
517
|
-
list.push(s);
|
|
518
|
-
symbolsIn.set(s.file, list);
|
|
519
|
-
}
|
|
520
|
-
const communities = [...groups.values()]
|
|
521
|
-
.map((files) => files.sort())
|
|
522
|
-
.sort((a, b) => b.length - a.length || a[0].localeCompare(b[0]))
|
|
523
|
-
.map((files, i) => ({
|
|
524
|
-
id: `c${i + 1}`,
|
|
525
|
-
label: mainDir(files),
|
|
526
|
-
files,
|
|
527
|
-
symbols: files.reduce((n, f) => n + (symbolsPerFile.get(f) ?? 0), 0),
|
|
528
|
-
hubs: files
|
|
529
|
-
.flatMap((f) => symbolsIn.get(f) ?? [])
|
|
530
|
-
.filter((s) => s.name !== MODULE && fanIn.has(s.id))
|
|
531
|
-
.sort((a, b) => fanIn.get(b.id) - fanIn.get(a.id) || a.name.localeCompare(b.name))
|
|
532
|
-
.slice(0, 3)
|
|
533
|
-
.map((s) => s.name),
|
|
534
|
-
}));
|
|
535
|
-
const communityOf = new Map();
|
|
536
|
-
for (const c of communities)
|
|
537
|
-
for (const f of c.files)
|
|
538
|
-
communityOf.set(f, c.id);
|
|
539
|
-
const between = new Map();
|
|
540
|
-
for (const [k, w] of headEdges) {
|
|
541
|
-
const [a, b] = k.split(" -> ");
|
|
542
|
-
const ca = communityOf.get(a);
|
|
543
|
-
const cb = communityOf.get(b);
|
|
544
|
-
if (ca === cb)
|
|
545
|
-
continue;
|
|
546
|
-
const key = `${ca} -> ${cb}`;
|
|
547
|
-
between.set(key, (between.get(key) ?? 0) + w);
|
|
548
|
-
}
|
|
549
|
-
const headFiles = new Set(head.files);
|
|
550
|
-
const baseFiles = new Set(base.files);
|
|
551
|
-
return {
|
|
552
|
-
communities,
|
|
553
|
-
edges: [...between]
|
|
554
|
-
.map(([k, references]) => {
|
|
555
|
-
const [from, to] = k.split(" -> ");
|
|
556
|
-
return { from, to, references };
|
|
557
|
-
})
|
|
558
|
-
.sort((a, b) => b.references - a.references),
|
|
559
|
-
diff: {
|
|
560
|
-
added: [...headEdges.keys()].filter((k) => !baseEdges.has(k)).sort(),
|
|
561
|
-
removed: [...baseEdges.keys()].filter((k) => !headEdges.has(k)).sort(),
|
|
562
|
-
addedFiles: head.files.filter((f) => !baseFiles.has(f)),
|
|
563
|
-
removedFiles: base.files.filter((f) => !headFiles.has(f)),
|
|
564
|
-
},
|
|
565
|
-
truncated: { base: base.truncated, head: head.truncated },
|
|
566
|
-
};
|
|
567
|
-
}
|
|
568
|
-
//# sourceMappingURL=graph.js.map
|
package/dist/graph.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"graph.js","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"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"}
|