@llm4ts/flow 2.37.0 → 2.39.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/dist/Domains.d.ts +1 -1
- package/dist/Domains.d.ts.map +1 -1
- package/dist/Domains.js +7 -3
- package/dist/Domains.js.map +1 -1
- package/dist/Flow.d.ts +3 -1
- package/dist/Flow.d.ts.map +1 -1
- package/dist/Flow.js +1 -0
- package/dist/Flow.js.map +1 -1
- package/dist/GraphCache.d.ts +70 -0
- package/dist/GraphCache.d.ts.map +1 -0
- package/dist/GraphCache.js +111 -0
- package/dist/GraphCache.js.map +1 -0
- package/dist/GraphQuery.d.ts +67 -0
- package/dist/GraphQuery.d.ts.map +1 -0
- package/dist/GraphQuery.js +212 -0
- package/dist/GraphQuery.js.map +1 -0
- package/dist/GraphRender.d.ts +26 -0
- package/dist/GraphRender.d.ts.map +1 -0
- package/dist/GraphRender.js +154 -0
- package/dist/GraphRender.js.map +1 -0
- package/dist/GraphRules.d.ts +86 -0
- package/dist/GraphRules.d.ts.map +1 -0
- package/dist/GraphRules.js +246 -0
- package/dist/GraphRules.js.map +1 -0
- package/dist/GraphWorklist.d.ts +64 -0
- package/dist/GraphWorklist.d.ts.map +1 -0
- package/dist/GraphWorklist.js +283 -0
- package/dist/GraphWorklist.js.map +1 -0
- package/dist/Pack.d.ts +7 -0
- package/dist/Pack.d.ts.map +1 -1
- package/dist/Pack.js +9 -5
- package/dist/Pack.js.map +1 -1
- package/dist/Review.d.ts +12 -0
- package/dist/Review.d.ts.map +1 -1
- package/dist/Review.js +11 -1
- package/dist/Review.js.map +1 -1
- package/dist/Stories.d.ts +16 -0
- package/dist/Stories.d.ts.map +1 -1
- package/dist/Stories.js +42 -7
- package/dist/Stories.js.map +1 -1
- package/dist/Survey.d.ts +112 -3
- package/dist/Survey.d.ts.map +1 -1
- package/dist/Survey.js +644 -41
- package/dist/Survey.js.map +1 -1
- package/package.json +7 -2
- package/src/Domains.ts +7 -4
- package/src/Flow.ts +5 -1
- package/src/GraphCache.ts +191 -0
- package/src/GraphQuery.ts +315 -0
- package/src/GraphRender.ts +208 -0
- package/src/GraphRules.ts +293 -0
- package/src/GraphWorklist.ts +405 -0
- package/src/Pack.ts +15 -5
- package/src/Review.ts +25 -1
- package/src/Stories.ts +66 -12
- package/src/Survey.ts +846 -52
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { SurveyEdge, SurveyGraph, closureFor, edgeConfidence, edgeOrigin, nodeAttrs, nodeId, nodeKind, nodeLabel, projectToFiles, unitName } from "./Survey.js";
|
|
2
|
+
const lower = (text) => text.toLowerCase();
|
|
3
|
+
/** Substring search over id, name, label, path and attr values; file-mates of a strong hit get a small boost. */
|
|
4
|
+
export const searchNodes = (graph, text, options = {}) => {
|
|
5
|
+
const needle = lower(text.trim());
|
|
6
|
+
if (needle.length === 0) {
|
|
7
|
+
return [];
|
|
8
|
+
}
|
|
9
|
+
const base = graph.nodes.map((node) => {
|
|
10
|
+
let score = 0;
|
|
11
|
+
if (lower(node.name) === needle) {
|
|
12
|
+
score += 6;
|
|
13
|
+
}
|
|
14
|
+
else if (lower(node.name).includes(needle)) {
|
|
15
|
+
score += 3;
|
|
16
|
+
}
|
|
17
|
+
if (lower(nodeLabel(node)).includes(needle)) {
|
|
18
|
+
score += 2;
|
|
19
|
+
}
|
|
20
|
+
if (Object.values(nodeAttrs(node)).some((value) => lower(value).includes(needle))) {
|
|
21
|
+
score += 2;
|
|
22
|
+
}
|
|
23
|
+
if (lower(nodeId(node)).includes(needle) || lower(node.path).includes(needle)) {
|
|
24
|
+
score += 1;
|
|
25
|
+
}
|
|
26
|
+
return { node, score };
|
|
27
|
+
});
|
|
28
|
+
const strongFiles = new Set(base.filter((hit) => hit.score >= 2).map((hit) => hit.node.path));
|
|
29
|
+
return (base
|
|
30
|
+
.map((hit) => hit.score === 0 && strongFiles.has(hit.node.path) ? { ...hit, score: 0.5 } : hit)
|
|
31
|
+
// A co-located node (score 0.5) rides along an open search; an explicit
|
|
32
|
+
// kind asks for real matches of that kind only.
|
|
33
|
+
.filter((hit) => options.kind === undefined
|
|
34
|
+
? hit.score > 0
|
|
35
|
+
: hit.score >= 1 && nodeKind(hit.node) === options.kind)
|
|
36
|
+
.sort((left, right) => right.score - left.score || nodeId(left.node).localeCompare(nodeId(right.node)))
|
|
37
|
+
.slice(0, options.limit ?? 20));
|
|
38
|
+
};
|
|
39
|
+
const viewOf = (graph, ids) => ({
|
|
40
|
+
nodes: graph.nodes.filter((node) => ids.has(nodeId(node))),
|
|
41
|
+
edges: graph.edges.filter((edge) => ids.has(edge.from) && ids.has(edge.to))
|
|
42
|
+
});
|
|
43
|
+
export const neighborhood = (graph, ids, hops) => {
|
|
44
|
+
const seen = new Set(ids);
|
|
45
|
+
let frontier = ids;
|
|
46
|
+
for (let hop = 0; hop < hops && frontier.length > 0; hop += 1) {
|
|
47
|
+
const next = frontier
|
|
48
|
+
.flatMap((id) => [
|
|
49
|
+
...graph.outgoing(id).map((edge) => edge.to),
|
|
50
|
+
...graph.incoming(id).map((edge) => edge.from)
|
|
51
|
+
])
|
|
52
|
+
.filter((id) => !seen.has(id));
|
|
53
|
+
next.forEach((id) => seen.add(id));
|
|
54
|
+
frontier = [...new Set(next)];
|
|
55
|
+
}
|
|
56
|
+
return viewOf(graph, seen);
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Raw edges + projected file edges + file→sub-node containment: the graph
|
|
60
|
+
* probes and `--projected` paths walk, so a page reaches the servlet its form
|
|
61
|
+
* posts to and the servlet reaches the ESB call inside it.
|
|
62
|
+
*/
|
|
63
|
+
export const probeGraph = (graph) => {
|
|
64
|
+
const projected = projectToFiles(graph);
|
|
65
|
+
const containment = graph.nodes
|
|
66
|
+
.filter((node) => nodeKind(node) !== "file")
|
|
67
|
+
.map((node) => SurveyEdge.make({
|
|
68
|
+
from: unitName(node.path),
|
|
69
|
+
to: nodeId(node),
|
|
70
|
+
kind: "contains",
|
|
71
|
+
mechanism: "contraction"
|
|
72
|
+
}));
|
|
73
|
+
return SurveyGraph.make({
|
|
74
|
+
nodes: graph.nodes,
|
|
75
|
+
edges: [...graph.edges, ...projected.edges, ...containment],
|
|
76
|
+
unresolved: graph.unresolved,
|
|
77
|
+
fills: graph.fills
|
|
78
|
+
});
|
|
79
|
+
};
|
|
80
|
+
/** Bidirectional BFS over directed edges; the path as edges from `from` to `to`. */
|
|
81
|
+
export const shortestPath = (graph, from, to, maxHops = 12, options = {}) => {
|
|
82
|
+
const walk = options.projected === true ? probeGraph(graph) : graph;
|
|
83
|
+
if (from === to) {
|
|
84
|
+
return [];
|
|
85
|
+
}
|
|
86
|
+
const forward = new Map([[from, undefined]]);
|
|
87
|
+
const backward = new Map([[to, undefined]]);
|
|
88
|
+
let frontF = [from];
|
|
89
|
+
let frontB = [to];
|
|
90
|
+
const join = (meet) => {
|
|
91
|
+
const head = [];
|
|
92
|
+
for (let edge = forward.get(meet); edge !== undefined; edge = forward.get(edge.from)) {
|
|
93
|
+
head.unshift(edge);
|
|
94
|
+
}
|
|
95
|
+
const tail = [];
|
|
96
|
+
for (let edge = backward.get(meet); edge !== undefined; edge = backward.get(edge.to)) {
|
|
97
|
+
tail.push(edge);
|
|
98
|
+
}
|
|
99
|
+
return [...head, ...tail];
|
|
100
|
+
};
|
|
101
|
+
for (let hop = 0; hop < maxHops; hop += 1) {
|
|
102
|
+
if (frontF.length === 0 && frontB.length === 0) {
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
if (frontF.length > 0 && (frontF.length <= frontB.length || frontB.length === 0)) {
|
|
106
|
+
const next = [];
|
|
107
|
+
for (const id of frontF) {
|
|
108
|
+
for (const edge of walk.outgoing(id)) {
|
|
109
|
+
if (!forward.has(edge.to)) {
|
|
110
|
+
forward.set(edge.to, edge);
|
|
111
|
+
next.push(edge.to);
|
|
112
|
+
}
|
|
113
|
+
if (backward.has(edge.to)) {
|
|
114
|
+
return join(edge.to);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
frontF = next;
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
const next = [];
|
|
122
|
+
for (const id of frontB) {
|
|
123
|
+
for (const edge of walk.incoming(id)) {
|
|
124
|
+
if (!backward.has(edge.from)) {
|
|
125
|
+
backward.set(edge.from, edge);
|
|
126
|
+
next.push(edge.from);
|
|
127
|
+
}
|
|
128
|
+
if (forward.has(edge.from)) {
|
|
129
|
+
return join(edge.from);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
frontB = next;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return undefined;
|
|
137
|
+
};
|
|
138
|
+
export const pathBetween = (graph, a, b, maxHops = 12, options = {}) => {
|
|
139
|
+
const forward = shortestPath(graph, a, b, maxHops, options);
|
|
140
|
+
const backward = shortestPath(graph, b, a, maxHops, options);
|
|
141
|
+
return {
|
|
142
|
+
...(forward === undefined ? {} : { forward }),
|
|
143
|
+
...(backward === undefined ? {} : { backward })
|
|
144
|
+
};
|
|
145
|
+
};
|
|
146
|
+
export const viewOfPath = (graph, path) => {
|
|
147
|
+
const ids = new Set(path.flatMap((edge) => [edge.from, edge.to]));
|
|
148
|
+
return { nodes: graph.nodes.filter((node) => ids.has(nodeId(node))), edges: path };
|
|
149
|
+
};
|
|
150
|
+
/** The program and its bounded closure, on the file projection. */
|
|
151
|
+
export const closureView = (graph, program, maxFiles) => {
|
|
152
|
+
const projected = projectToFiles(graph);
|
|
153
|
+
const paths = new Set(closureFor(graph, program, maxFiles));
|
|
154
|
+
const ids = new Set(projected.nodes.filter((node) => node.name === program || paths.has(node.path)).map(nodeId));
|
|
155
|
+
return viewOf(projected, ids);
|
|
156
|
+
};
|
|
157
|
+
export const wholeView = (graph) => ({
|
|
158
|
+
nodes: graph.nodes,
|
|
159
|
+
edges: graph.edges
|
|
160
|
+
});
|
|
161
|
+
const tally = (keys) => {
|
|
162
|
+
const counts = {};
|
|
163
|
+
for (const key of keys) {
|
|
164
|
+
counts[key] = (counts[key] ?? 0) + 1;
|
|
165
|
+
}
|
|
166
|
+
return counts;
|
|
167
|
+
};
|
|
168
|
+
export const graphStats = (graph) => ({
|
|
169
|
+
nodes: tally(graph.nodes.map(nodeKind)),
|
|
170
|
+
edges: tally(graph.edges.map((edge) => edge.kind)),
|
|
171
|
+
origin: tally(graph.edges.map(edgeOrigin)),
|
|
172
|
+
mechanism: tally(graph.edges.map((edge) => edge.mechanism ?? "capture")),
|
|
173
|
+
confidence: tally(graph.edges.map(edgeConfidence)),
|
|
174
|
+
unresolved: tally(graph.unresolved.map((item) => item.reason)),
|
|
175
|
+
total: {
|
|
176
|
+
nodes: graph.nodes.length,
|
|
177
|
+
edges: graph.edges.length,
|
|
178
|
+
unresolved: graph.unresolved.length,
|
|
179
|
+
fills: graph.fills.length
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
/** An id, `<kind>:<name>` (first node of that kind with that name), or a bare file unit name. */
|
|
183
|
+
export const resolveNodeRef = (graph, ref) => {
|
|
184
|
+
const exact = graph.node(ref);
|
|
185
|
+
if (exact !== undefined) {
|
|
186
|
+
return exact;
|
|
187
|
+
}
|
|
188
|
+
const colon = ref.indexOf(":");
|
|
189
|
+
if (colon > 0 && !ref.includes("#")) {
|
|
190
|
+
const kind = ref.slice(0, colon);
|
|
191
|
+
const name = ref.slice(colon + 1);
|
|
192
|
+
return graph.nodes.find((node) => nodeKind(node) === kind && node.name === name);
|
|
193
|
+
}
|
|
194
|
+
return graph.nodes.find((node) => nodeKind(node) === "file" && node.name === ref);
|
|
195
|
+
};
|
|
196
|
+
/** Each probe's verdict on the union graph: connected, broken, or an endpoint nothing matches. */
|
|
197
|
+
export const probeResults = (graph, probes, maxHops = 12) => {
|
|
198
|
+
const walk = probeGraph(graph);
|
|
199
|
+
return probes.map((probe) => {
|
|
200
|
+
const from = resolveNodeRef(graph, probe.from);
|
|
201
|
+
const to = resolveNodeRef(graph, probe.to);
|
|
202
|
+
if (from === undefined) {
|
|
203
|
+
return { probe, status: "unknown-from" };
|
|
204
|
+
}
|
|
205
|
+
if (to === undefined) {
|
|
206
|
+
return { probe, status: "unknown-to" };
|
|
207
|
+
}
|
|
208
|
+
const path = shortestPath(walk, nodeId(from), nodeId(to), maxHops);
|
|
209
|
+
return path === undefined ? { probe, status: "broken" } : { probe, status: "ok", path };
|
|
210
|
+
});
|
|
211
|
+
};
|
|
212
|
+
//# sourceMappingURL=GraphQuery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GraphQuery.js","sourceRoot":"","sources":["../src/GraphQuery.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type ConsolidateRules } from "./Domains.ts";
|
|
2
|
+
import { type GraphView } from "./GraphQuery.ts";
|
|
3
|
+
import { type SurveyGraph } from "./Survey.ts";
|
|
4
|
+
/**
|
|
5
|
+
* Renders of a graph view (ADR 0030 decision 7): one view model, three
|
|
6
|
+
* emitters. Nodes group by file, edges carry their kind, inferred edges are
|
|
7
|
+
* dotted, unresolved nodes are red, and every node line ends with its id so a
|
|
8
|
+
* reader can paste it into `llm4ts graph path`.
|
|
9
|
+
*/
|
|
10
|
+
export declare const mermaidNodeCap = 150;
|
|
11
|
+
export declare const renderGraphText: (view: GraphView) => string;
|
|
12
|
+
export declare const renderGraphMermaid: (view: GraphView, graph: SurveyGraph, options?: {
|
|
13
|
+
readonly cap?: number;
|
|
14
|
+
readonly force?: boolean;
|
|
15
|
+
}) => string;
|
|
16
|
+
export declare const renderGraphDot: (view: GraphView, graph: SurveyGraph) => string;
|
|
17
|
+
/** From every projected node nothing points at, the chains it starts, depth-first, bounded. */
|
|
18
|
+
export declare const renderEntryPaths: (graph: SurveyGraph, options?: {
|
|
19
|
+
readonly maxDepth?: number;
|
|
20
|
+
readonly maxLines?: number;
|
|
21
|
+
}) => string;
|
|
22
|
+
/** One mermaid block per multi-program consolidate cluster, on the file projection. */
|
|
23
|
+
export declare const renderClusterDiagrams: (graph: SurveyGraph, consolidate: ConsolidateRules, programs: ReadonlyArray<string>, options?: {
|
|
24
|
+
readonly cap?: number;
|
|
25
|
+
}) => string;
|
|
26
|
+
//# sourceMappingURL=GraphRender.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GraphRender.d.ts","sourceRoot":"","sources":["../src/GraphRender.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,gBAAgB,EAAE,MAAM,cAAc,CAAA;AACrE,OAAO,EAAgB,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC9D,OAAO,EAML,KAAK,WAAW,EAEjB,MAAM,aAAa,CAAA;AAEpB;;;;;GAKG;AACH,eAAO,MAAM,cAAc,MAAM,CAAA;AA6CjC,eAAO,MAAM,eAAe,GAAI,MAAM,SAAS,KAAG,MAWpC,CAAA;AAEd,eAAO,MAAM,kBAAkB,GAC7B,MAAM,SAAS,EACf,OAAO,WAAW,EAClB,UAAS;IAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,KAChE,MA+BF,CAAA;AAED,eAAO,MAAM,cAAc,GAAI,MAAM,SAAS,EAAE,OAAO,WAAW,KAAG,MAuBpE,CAAA;AAED,+FAA+F;AAC/F,eAAO,MAAM,gBAAgB,GAC3B,OAAO,WAAW,EAClB,UAAS;IAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,KACvE,MAmCF,CAAA;AAED,uFAAuF;AACvF,eAAO,MAAM,qBAAqB,GAChC,OAAO,WAAW,EAClB,aAAa,gBAAgB,EAC7B,UAAU,aAAa,CAAC,MAAM,CAAC,EAC/B,UAAS;IAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,KACtC,MAsBF,CAAA"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { clusterPrograms } from "./Domains.js";
|
|
2
|
+
import { neighborhood } from "./GraphQuery.js";
|
|
3
|
+
import { edgeConfidence, nodeId, nodeKind, nodeLabel, projectToFiles } from "./Survey.js";
|
|
4
|
+
/**
|
|
5
|
+
* Renders of a graph view (ADR 0030 decision 7): one view model, three
|
|
6
|
+
* emitters. Nodes group by file, edges carry their kind, inferred edges are
|
|
7
|
+
* dotted, unresolved nodes are red, and every node line ends with its id so a
|
|
8
|
+
* reader can paste it into `llm4ts graph path`.
|
|
9
|
+
*/
|
|
10
|
+
export const mermaidNodeCap = 150;
|
|
11
|
+
/** Reserved kinds get a fixed look; any pack-defined kind falls back to `neutral`. */
|
|
12
|
+
const styles = {
|
|
13
|
+
file: { mermaid: "fill:#eef,stroke:#446,color:#000", shape: "box" },
|
|
14
|
+
page: { mermaid: "fill:#efe,stroke:#464,color:#000", shape: "note" },
|
|
15
|
+
"ajax-call": { mermaid: "fill:#ffe,stroke:#664,color:#000", shape: "ellipse" },
|
|
16
|
+
form: { mermaid: "fill:#ffe,stroke:#664,color:#000", shape: "ellipse" },
|
|
17
|
+
"servlet-mapping": { mermaid: "fill:#fee,stroke:#644,color:#000", shape: "hexagon" },
|
|
18
|
+
"servlet-decl": { mermaid: "fill:#fee,stroke:#644,color:#000", shape: "hexagon" },
|
|
19
|
+
"esb-call": { mermaid: "fill:#fdf,stroke:#646,color:#000", shape: "component" },
|
|
20
|
+
"cobol-section": { mermaid: "fill:#eff,stroke:#466,color:#000", shape: "folder" },
|
|
21
|
+
"cobol-paragraph": { mermaid: "fill:#eff,stroke:#466,color:#000", shape: "box" }
|
|
22
|
+
};
|
|
23
|
+
const neutral = { mermaid: "fill:#f4f4f4,stroke:#888,color:#000", shape: "box" };
|
|
24
|
+
const styleOf = (kind) => styles[kind] ?? neutral;
|
|
25
|
+
const escapeMermaid = (text) => text.replaceAll('"', "'").replaceAll("$", "$").replaceAll("{", "(").replaceAll("}", ")");
|
|
26
|
+
const escapeDot = (text) => text.replaceAll("\\", "\\\\").replaceAll('"', '\\"');
|
|
27
|
+
/** Mermaid class names may not contain `:` or `/`; kinds are kebab-case already. */
|
|
28
|
+
const mermaidClass = (kind) => kind.replace(/[^A-Za-z0-9_-]/g, "_");
|
|
29
|
+
const unresolvedIds = (graph) => new Set(graph.unresolved.map((item) => item.node));
|
|
30
|
+
const groupedByFile = (view) => {
|
|
31
|
+
const groups = new Map();
|
|
32
|
+
for (const node of [...view.nodes].sort((a, b) => nodeId(a).localeCompare(nodeId(b)))) {
|
|
33
|
+
groups.set(node.path, [...(groups.get(node.path) ?? []), node]);
|
|
34
|
+
}
|
|
35
|
+
return [...groups.entries()].sort(([a], [b]) => a.localeCompare(b));
|
|
36
|
+
};
|
|
37
|
+
export const renderGraphText = (view) => [
|
|
38
|
+
...groupedByFile(view).flatMap(([path, nodes]) => [
|
|
39
|
+
path,
|
|
40
|
+
...nodes.map((node) => ` ${nodeId(node)} [${nodeKind(node)}]`)
|
|
41
|
+
]),
|
|
42
|
+
"",
|
|
43
|
+
...view.edges.map((edge) => `${edge.from} -> ${edge.to} [${edge.kind}]${edgeConfidence(edge) === "inferred" ? " (inferred)" : ""}`)
|
|
44
|
+
].join("\n");
|
|
45
|
+
export const renderGraphMermaid = (view, graph, options = {}) => {
|
|
46
|
+
const cap = options.cap ?? mermaidNodeCap;
|
|
47
|
+
if (view.nodes.length > cap && options.force !== true) {
|
|
48
|
+
return [
|
|
49
|
+
`${view.nodes.length} nodes exceed the mermaid cap of ${cap}; pass --force to render anyway. Text view:`,
|
|
50
|
+
"",
|
|
51
|
+
renderGraphText(view)
|
|
52
|
+
].join("\n");
|
|
53
|
+
}
|
|
54
|
+
const ids = new Map(view.nodes.map((node, index) => [nodeId(node), `n${index}`]));
|
|
55
|
+
const flagged = unresolvedIds(graph);
|
|
56
|
+
const kinds = [...new Set(view.nodes.map(nodeKind))];
|
|
57
|
+
const lines = ["flowchart LR"];
|
|
58
|
+
groupedByFile(view).forEach(([path, nodes], index) => {
|
|
59
|
+
lines.push(` subgraph f${index}["${escapeMermaid(path)}"]`);
|
|
60
|
+
for (const node of nodes) {
|
|
61
|
+
const id = nodeId(node);
|
|
62
|
+
const cls = flagged.has(id) ? ":::unresolved" : `:::${mermaidClass(nodeKind(node))}`;
|
|
63
|
+
lines.push(` ${ids.get(id)}["${escapeMermaid(nodeLabel(node))}"]${cls} %% ${id}`);
|
|
64
|
+
}
|
|
65
|
+
lines.push(" end");
|
|
66
|
+
});
|
|
67
|
+
for (const edge of view.edges) {
|
|
68
|
+
const arrow = edgeConfidence(edge) === "inferred" ? "-.->" : "-->";
|
|
69
|
+
lines.push(` ${ids.get(edge.from)} ${arrow}|${escapeMermaid(edge.kind)}| ${ids.get(edge.to)}`);
|
|
70
|
+
}
|
|
71
|
+
for (const kind of kinds) {
|
|
72
|
+
lines.push(` classDef ${mermaidClass(kind)} ${styleOf(kind).mermaid};`);
|
|
73
|
+
}
|
|
74
|
+
lines.push(" classDef unresolved fill:#fdd,stroke:#c00,color:#900;");
|
|
75
|
+
return lines.join("\n");
|
|
76
|
+
};
|
|
77
|
+
export const renderGraphDot = (view, graph) => {
|
|
78
|
+
const ids = new Map(view.nodes.map((node, index) => [nodeId(node), `n${index}`]));
|
|
79
|
+
const flagged = unresolvedIds(graph);
|
|
80
|
+
const lines = ["digraph llm4ts {", " rankdir=LR;", " node [fontname=Helvetica];"];
|
|
81
|
+
groupedByFile(view).forEach(([path, nodes], index) => {
|
|
82
|
+
lines.push(` subgraph "cluster_${index}" {`, ` label="${escapeDot(path)}";`);
|
|
83
|
+
for (const node of nodes) {
|
|
84
|
+
const id = nodeId(node);
|
|
85
|
+
const color = flagged.has(id) ? " color=red fontcolor=red" : "";
|
|
86
|
+
lines.push(` ${ids.get(id)} [label="${escapeDot(nodeLabel(node))}" shape=${styleOf(nodeKind(node)).shape} tooltip="${escapeDot(id)}"${color}];`);
|
|
87
|
+
}
|
|
88
|
+
lines.push(" }");
|
|
89
|
+
});
|
|
90
|
+
for (const edge of view.edges) {
|
|
91
|
+
const style = edgeConfidence(edge) === "inferred" ? " style=dashed" : "";
|
|
92
|
+
lines.push(` ${ids.get(edge.from)} -> ${ids.get(edge.to)} [label="${escapeDot(edge.kind)}"${style}];`);
|
|
93
|
+
}
|
|
94
|
+
lines.push("}");
|
|
95
|
+
return lines.join("\n");
|
|
96
|
+
};
|
|
97
|
+
/** From every projected node nothing points at, the chains it starts, depth-first, bounded. */
|
|
98
|
+
export const renderEntryPaths = (graph, options = {}) => {
|
|
99
|
+
const maxDepth = options.maxDepth ?? 4;
|
|
100
|
+
const maxLines = options.maxLines ?? 200;
|
|
101
|
+
const projected = projectToFiles(graph);
|
|
102
|
+
const entries = projected.nodes.filter((node) => projected.incoming(node.name).length === 0 && projected.outgoing(node.name).length > 0);
|
|
103
|
+
const lines = [];
|
|
104
|
+
const walk = (id, trail, seen, depth) => {
|
|
105
|
+
if (lines.length >= maxLines) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const out = projected.outgoing(id);
|
|
109
|
+
if (out.length === 0 || depth === maxDepth) {
|
|
110
|
+
lines.push(trail);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
for (const edge of out) {
|
|
114
|
+
if (seen.has(edge.to)) {
|
|
115
|
+
lines.push(`${trail} → ${edge.to} (${edge.kind}) ↺`);
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
walk(edge.to, `${trail} → ${edge.to} (${edge.kind})`, new Set([...seen, edge.to]), depth + 1);
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
for (const entry of entries) {
|
|
122
|
+
walk(entry.name, entry.name, new Set([entry.name]), 0);
|
|
123
|
+
}
|
|
124
|
+
return [
|
|
125
|
+
"## Entry paths",
|
|
126
|
+
"",
|
|
127
|
+
...(lines.length === 0 ? ["(none)"] : lines.map((line) => `- ${line}`)),
|
|
128
|
+
...(lines.length >= maxLines ? [`- … truncated at ${maxLines} lines`] : []),
|
|
129
|
+
""
|
|
130
|
+
].join("\n");
|
|
131
|
+
};
|
|
132
|
+
/** One mermaid block per multi-program consolidate cluster, on the file projection. */
|
|
133
|
+
export const renderClusterDiagrams = (graph, consolidate, programs, options = {}) => {
|
|
134
|
+
const projected = projectToFiles(graph);
|
|
135
|
+
const clusters = clusterPrograms(graph, programs, consolidate).filter((cluster) => cluster.programs.length > 1);
|
|
136
|
+
if (clusters.length === 0) {
|
|
137
|
+
return "## Clusters\n\n(no multi-program cluster)\n";
|
|
138
|
+
}
|
|
139
|
+
return [
|
|
140
|
+
"## Clusters",
|
|
141
|
+
"",
|
|
142
|
+
...clusters.flatMap((cluster, index) => [
|
|
143
|
+
`### Cluster ${index + 1}: ${[...cluster.programs].sort().join(", ")}`,
|
|
144
|
+
"",
|
|
145
|
+
"```mermaid",
|
|
146
|
+
renderGraphMermaid(neighborhood(projected, cluster.programs, 1), projected, {
|
|
147
|
+
cap: options.cap ?? mermaidNodeCap
|
|
148
|
+
}),
|
|
149
|
+
"```",
|
|
150
|
+
""
|
|
151
|
+
])
|
|
152
|
+
].join("\n");
|
|
153
|
+
};
|
|
154
|
+
//# sourceMappingURL=GraphRender.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GraphRender.js","sourceRoot":"","sources":["../src/GraphRender.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import * as Schema from "effect/Schema";
|
|
3
|
+
import { PlanParseError } from "./FlowError.ts";
|
|
4
|
+
import type { CoverageRule } from "./SpecChecks.ts";
|
|
5
|
+
import type { JoinMatch } from "./Survey.ts";
|
|
6
|
+
declare const NodeRule_base: Schema.Class<NodeRule, Schema.Struct<{
|
|
7
|
+
readonly kind: Schema.String;
|
|
8
|
+
readonly files: Schema.String;
|
|
9
|
+
readonly pattern: Schema.String;
|
|
10
|
+
readonly descriptor: Schema.Boolean;
|
|
11
|
+
readonly anchor: Schema.optionalKey<Schema.String>;
|
|
12
|
+
/** `attr → named group` copies beyond the default "every group but name". */
|
|
13
|
+
readonly attrs: Schema.$Record<Schema.String, Schema.String>;
|
|
14
|
+
}>, {}>;
|
|
15
|
+
/**
|
|
16
|
+
* The pack's graph vocabulary (ADR 0030). A `## Node:` rule names a sub-file
|
|
17
|
+
* node kind, an `## Edge:` rule a captured link, a `## Join:` rule a link by
|
|
18
|
+
* attribute equality across files, a `## Probe:` a flow that must be
|
|
19
|
+
* connected end to end. `## Survey:` rules are folded in as file-to-file
|
|
20
|
+
* Edge rules so a pre-0030 pack produces the same graph.
|
|
21
|
+
*/
|
|
22
|
+
export declare class NodeRule extends NodeRule_base {
|
|
23
|
+
}
|
|
24
|
+
declare const EdgeRule_base: Schema.Class<EdgeRule, Schema.Struct<{
|
|
25
|
+
readonly kind: Schema.String;
|
|
26
|
+
readonly files: Schema.String;
|
|
27
|
+
readonly pattern: Schema.String;
|
|
28
|
+
readonly fromKind: Schema.String;
|
|
29
|
+
readonly toKind: Schema.String;
|
|
30
|
+
/** A folded `## Survey:` rule: the target is the first positional group (or the whole match), as before ADR 0030. */
|
|
31
|
+
readonly positional: Schema.optionalKey<Schema.Boolean>;
|
|
32
|
+
}>, {}>;
|
|
33
|
+
export declare class EdgeRule extends EdgeRule_base {
|
|
34
|
+
}
|
|
35
|
+
export declare const JoinMatchMode: Schema.Literals<readonly ["exact", "url"]>;
|
|
36
|
+
export type JoinMatchMode = typeof JoinMatchMode.Type;
|
|
37
|
+
export declare const JoinScope: Schema.Literals<readonly ["estate", "app", "file"]>;
|
|
38
|
+
export type JoinScope = typeof JoinScope.Type;
|
|
39
|
+
declare const JoinRule_base: Schema.Class<JoinRule, Schema.Struct<{
|
|
40
|
+
readonly kind: Schema.String;
|
|
41
|
+
readonly fromKind: Schema.String;
|
|
42
|
+
readonly fromAttr: Schema.String;
|
|
43
|
+
readonly toKind: Schema.String;
|
|
44
|
+
readonly toAttr: Schema.String;
|
|
45
|
+
readonly match: Schema.Literals<readonly ["exact", "url"]>;
|
|
46
|
+
readonly scope: Schema.Literals<readonly ["estate", "app", "file"]>;
|
|
47
|
+
}>, {}>;
|
|
48
|
+
export declare class JoinRule extends JoinRule_base {
|
|
49
|
+
}
|
|
50
|
+
declare const ProbeRule_base: Schema.Class<ProbeRule, Schema.Struct<{
|
|
51
|
+
readonly name: Schema.String;
|
|
52
|
+
readonly from: Schema.String;
|
|
53
|
+
readonly to: Schema.String;
|
|
54
|
+
}>, {}>;
|
|
55
|
+
export declare class ProbeRule extends ProbeRule_base {
|
|
56
|
+
}
|
|
57
|
+
export interface GraphRules {
|
|
58
|
+
readonly nodes: ReadonlyArray<NodeRule>;
|
|
59
|
+
readonly edges: ReadonlyArray<EdgeRule>;
|
|
60
|
+
readonly joins: ReadonlyArray<JoinRule>;
|
|
61
|
+
readonly probes: ReadonlyArray<ProbeRule>;
|
|
62
|
+
readonly worklistMax: number;
|
|
63
|
+
readonly batchSize: number;
|
|
64
|
+
}
|
|
65
|
+
export declare const emptyGraphRules: GraphRules;
|
|
66
|
+
/**
|
|
67
|
+
* `## Survey:` is an Edge rule between files whose first positional capture
|
|
68
|
+
* (or the whole match) is the target. The pattern is kept verbatim: rewriting
|
|
69
|
+
* its first `(` would break `(?:…)`, lookbehinds and escaped parens.
|
|
70
|
+
*/
|
|
71
|
+
export declare const edgeRuleOfSurvey: (rule: CoverageRule) => EdgeRule;
|
|
72
|
+
export declare const parseGraphRules: (sections: ReadonlyArray<string>, survey: ReadonlyArray<CoverageRule>) => Effect.Effect<GraphRules, PlanParseError>;
|
|
73
|
+
/** Every edge kind the rules can produce: captured kinds plus join kinds. */
|
|
74
|
+
export declare const edgeKindsOf: (rules: GraphRules) => ReadonlySet<string>;
|
|
75
|
+
/** Changes when any rule that shapes the graph changes; probes and budgets do not. */
|
|
76
|
+
export declare const graphRulesHash: (rules: GraphRules) => string;
|
|
77
|
+
/** `${ctx}/a/b?x=1` → `/a/b`; `salva.do` → `/salva.do`; scheme, host and fragment dropped. */
|
|
78
|
+
export declare const normalizeUrl: (raw: string) => string;
|
|
79
|
+
/**
|
|
80
|
+
* Servlet-spec matching of a normalised request against a `url-pattern`:
|
|
81
|
+
* exact, then a `/*` prefix, then a `*.ext` extension. The extension case
|
|
82
|
+
* reads the raw pattern, since normalising `*.do` would prefix a slash.
|
|
83
|
+
*/
|
|
84
|
+
export declare const matchUrl: (request: string, pattern: string) => JoinMatch | undefined;
|
|
85
|
+
export {};
|
|
86
|
+
//# sourceMappingURL=GraphRules.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GraphRules.d.ts","sourceRoot":"","sources":["../src/GraphRules.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAE/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;;;;;;;IAe1C,6EAA6E;;;AAb/E;;;;;;GAMG;AACH,qBAAa,QAAS,SAAQ,aAQ5B;CAAG;;;;;;;IAQH,qHAAqH;;;AANvH,qBAAa,QAAS,SAAQ,aAQ5B;CAAG;AAEL,eAAO,MAAM,aAAa,4CAAoC,CAAA;AAC9D,MAAM,MAAM,aAAa,GAAG,OAAO,aAAa,CAAC,IAAI,CAAA;AACrD,eAAO,MAAM,SAAS,qDAA6C,CAAA;AACnE,MAAM,MAAM,SAAS,GAAG,OAAO,SAAS,CAAC,IAAI,CAAA;;;;;;;;;;AAE7C,qBAAa,QAAS,SAAQ,aAQ5B;CAAG;;;;;;AAEL,qBAAa,SAAU,SAAQ,cAI7B;CAAG;AAEL,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAA;IACvC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAA;IACvC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAA;IACvC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,SAAS,CAAC,CAAA;IACzC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAC3B;AAED,eAAO,MAAM,eAAe,EAAE,UAO7B,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,MAAM,YAAY,KAAG,QAQlD,CAAA;AAgDJ,eAAO,MAAM,eAAe,GAC1B,UAAU,aAAa,CAAC,MAAM,CAAC,EAC/B,QAAQ,aAAa,CAAC,YAAY,CAAC,KAClC,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,cAAc,CA+GvC,CAAA;AAEJ,6EAA6E;AAC7E,eAAO,MAAM,WAAW,GAAI,OAAO,UAAU,KAAG,WAAW,CAAC,MAAM,CAC2B,CAAA;AAE7F,sFAAsF;AACtF,eAAO,MAAM,cAAc,GAAI,OAAO,UAAU,KAAG,MACkC,CAAA;AAErF,8FAA8F;AAC9F,eAAO,MAAM,YAAY,GAAI,KAAK,MAAM,KAAG,MAY1C,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,QAAQ,GAAI,SAAS,MAAM,EAAE,SAAS,MAAM,KAAG,SAAS,GAAG,SAcvE,CAAA"}
|