ts-knowledge-graph 0.1.4 → 0.1.6
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 +26 -8
- package/contribs/{web_visualisation → webview}/README.md +7 -7
- package/contribs/webview/web/css/style.css +310 -0
- package/contribs/{web_visualisation → webview}/web/index.html +40 -5
- package/contribs/{web_visualisation → webview}/web/js/app.js +378 -39
- package/contribs/{web_visualisation/web/data → webview/web/js_autogenerated}/kind_descriptions.js +2 -1
- package/contribs/{web_visualisation → webview}/web/types/app_globals.d.ts +11 -3
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +6 -2
- package/dist/cli.js.map +1 -1
- package/dist/cluster/cluster_weights.d.ts +20 -0
- package/dist/cluster/cluster_weights.d.ts.map +1 -0
- package/dist/cluster/cluster_weights.js +32 -0
- package/dist/cluster/cluster_weights.js.map +1 -0
- package/dist/cluster/community_detector.d.ts +61 -0
- package/dist/cluster/community_detector.d.ts.map +1 -0
- package/dist/cluster/community_detector.js +120 -0
- package/dist/cluster/community_detector.js.map +1 -0
- package/dist/cluster/community_labeler.d.ts +84 -0
- package/dist/cluster/community_labeler.d.ts.map +1 -0
- package/dist/cluster/community_labeler.js +194 -0
- package/dist/cluster/community_labeler.js.map +1 -0
- package/dist/cluster/graph_clusterer.d.ts +47 -0
- package/dist/cluster/graph_clusterer.d.ts.map +1 -0
- package/dist/cluster/graph_clusterer.js +126 -0
- package/dist/cluster/graph_clusterer.js.map +1 -0
- package/dist/commands/benchmark_command.d.ts.map +1 -1
- package/dist/commands/benchmark_command.js +13 -10
- package/dist/commands/benchmark_command.js.map +1 -1
- package/dist/commands/blast_radius_command.d.ts.map +1 -1
- package/dist/commands/blast_radius_command.js +6 -5
- package/dist/commands/blast_radius_command.js.map +1 -1
- package/dist/commands/cluster_command.d.ts +7 -0
- package/dist/commands/cluster_command.d.ts.map +1 -0
- package/dist/commands/cluster_command.js +55 -0
- package/dist/commands/cluster_command.js.map +1 -0
- package/dist/commands/command_helpers.d.ts +9 -4
- package/dist/commands/command_helpers.d.ts.map +1 -1
- package/dist/commands/command_helpers.js +13 -8
- package/dist/commands/command_helpers.js.map +1 -1
- package/dist/commands/cost_command.d.ts.map +1 -1
- package/dist/commands/cost_command.js +25 -8
- package/dist/commands/cost_command.js.map +1 -1
- package/dist/commands/enrich_command.d.ts.map +1 -1
- package/dist/commands/enrich_command.js +7 -5
- package/dist/commands/enrich_command.js.map +1 -1
- package/dist/commands/extract_command.d.ts.map +1 -1
- package/dist/commands/extract_command.js +12 -6
- package/dist/commands/extract_command.js.map +1 -1
- package/dist/commands/hotspots_command.d.ts.map +1 -1
- package/dist/commands/hotspots_command.js +6 -5
- package/dist/commands/hotspots_command.js.map +1 -1
- package/dist/commands/install_command.d.ts +15 -5
- package/dist/commands/install_command.d.ts.map +1 -1
- package/dist/commands/install_command.js +61 -23
- package/dist/commands/install_command.js.map +1 -1
- package/dist/commands/load_command.d.ts.map +1 -1
- package/dist/commands/load_command.js +18 -13
- package/dist/commands/load_command.js.map +1 -1
- package/dist/commands/neighbors_command.d.ts.map +1 -1
- package/dist/commands/neighbors_command.js +6 -5
- package/dist/commands/neighbors_command.js.map +1 -1
- package/dist/commands/references_command.d.ts.map +1 -1
- package/dist/commands/references_command.js +6 -5
- package/dist/commands/references_command.js.map +1 -1
- package/dist/commands/report_command.d.ts +16 -0
- package/dist/commands/report_command.d.ts.map +1 -0
- package/dist/commands/report_command.js +115 -0
- package/dist/commands/report_command.js.map +1 -0
- package/dist/commands/webview_command.d.ts +36 -0
- package/dist/commands/webview_command.d.ts.map +1 -0
- package/dist/commands/webview_command.js +186 -0
- package/dist/commands/webview_command.js.map +1 -0
- package/dist/enrich/cpu_profile.d.ts +33 -0
- package/dist/enrich/cpu_profile.d.ts.map +1 -1
- package/dist/enrich/cpu_profile.js +88 -0
- package/dist/enrich/cpu_profile.js.map +1 -1
- package/dist/enrich/runtime_enricher.d.ts +8 -0
- package/dist/enrich/runtime_enricher.d.ts.map +1 -1
- package/dist/enrich/runtime_enricher.js +18 -0
- package/dist/enrich/runtime_enricher.js.map +1 -1
- package/dist/enrich/runtime_join.d.ts +25 -1
- package/dist/enrich/runtime_join.d.ts.map +1 -1
- package/dist/enrich/runtime_join.js +43 -0
- package/dist/enrich/runtime_join.js.map +1 -1
- package/dist/extract/git_source.d.ts +23 -0
- package/dist/extract/git_source.d.ts.map +1 -0
- package/dist/extract/git_source.js +75 -0
- package/dist/extract/git_source.js.map +1 -0
- package/dist/query/graph_query.d.ts +36 -1
- package/dist/query/graph_query.d.ts.map +1 -1
- package/dist/query/graph_query.js +69 -6
- package/dist/query/graph_query.js.map +1 -1
- package/dist/report/graph_report.d.ts +51 -0
- package/dist/report/graph_report.d.ts.map +1 -0
- package/dist/report/graph_report.js +312 -0
- package/dist/report/graph_report.js.map +1 -0
- package/dist/report/pdf_renderer.d.ts +22 -0
- package/dist/report/pdf_renderer.d.ts.map +1 -0
- package/dist/report/pdf_renderer.js +54 -0
- package/dist/report/pdf_renderer.js.map +1 -0
- package/dist/report/report_data.d.ts +128 -0
- package/dist/report/report_data.d.ts.map +1 -0
- package/dist/report/report_data.js +191 -0
- package/dist/report/report_data.js.map +1 -0
- package/dist/schema/edge.d.ts +5 -5
- package/dist/schema/edge.d.ts.map +1 -1
- package/dist/schema/edge.js +3 -0
- package/dist/schema/edge.js.map +1 -1
- package/dist/schema/source_manifest.d.ts +30 -0
- package/dist/schema/source_manifest.d.ts.map +1 -0
- package/dist/schema/source_manifest.js +21 -0
- package/dist/schema/source_manifest.js.map +1 -0
- package/dist/store/jsonl_reader.d.ts +4 -0
- package/dist/store/jsonl_reader.d.ts.map +1 -1
- package/dist/store/jsonl_reader.js +13 -1
- package/dist/store/jsonl_reader.js.map +1 -1
- package/dist/store/jsonl_store.d.ts +2 -1
- package/dist/store/jsonl_store.d.ts.map +1 -1
- package/dist/store/jsonl_store.js +4 -1
- package/dist/store/jsonl_store.js.map +1 -1
- package/dist/store/kuzu_store.d.ts +13 -0
- package/dist/store/kuzu_store.d.ts.map +1 -1
- package/dist/store/kuzu_store.js +29 -0
- package/dist/store/kuzu_store.js.map +1 -1
- package/dist/store/output_folder.d.ts +43 -0
- package/dist/store/output_folder.d.ts.map +1 -0
- package/dist/store/output_folder.js +61 -0
- package/dist/store/output_folder.js.map +1 -0
- package/dotclaude_folder/commands/code-graph-interview.md +123 -0
- package/dotclaude_folder/commands/code-graph-optimize.md +65 -0
- package/dotclaude_folder/skills/code-graph-query/SKILL.md +4 -4
- package/package.json +72 -62
- package/contribs/web_visualisation/web/css/style.css +0 -219
- package/contribs/web_visualisation/web/tsconfig.json +0 -18
- /package/contribs/{web_visualisation/web/data → webview/web/js_autogenerated}/.gitignore +0 -0
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
/** The tool's own repository, linked from the report footer. */
|
|
2
|
+
const TOOL_REPO_URL = 'https://github.com/jeromeetienne/ts_knowledge_graph';
|
|
3
|
+
/**
|
|
4
|
+
* Renders a {@link GraphReportData} to a string. Pure: the same data object maps
|
|
5
|
+
* deterministically to markdown, JSON, or the self-contained visual HTML the PDF
|
|
6
|
+
* path is built from — no store access, no clock, no filesystem — which keeps
|
|
7
|
+
* every format unit-testable in isolation. Mirrors how {@link CommunityDetector}
|
|
8
|
+
* is the pure core that {@link GraphClusterer} wraps with I/O.
|
|
9
|
+
*/
|
|
10
|
+
export class GraphReport {
|
|
11
|
+
static render(data, format) {
|
|
12
|
+
if (format === 'json') {
|
|
13
|
+
return JSON.stringify(data, null, 2);
|
|
14
|
+
}
|
|
15
|
+
return GraphReport.renderMarkdown(data);
|
|
16
|
+
}
|
|
17
|
+
/** The GitHub permalink for a symbol, or null when the graph recorded no source provenance. */
|
|
18
|
+
static permalink(provenance, symbol) {
|
|
19
|
+
if (provenance === null) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
return `${provenance.baseUrl}/blob/${provenance.commit}/${provenance.prefix}${symbol.filePath}#L${symbol.startLine}`;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* A location cell: a markdown link to the symbol on GitHub when source
|
|
26
|
+
* provenance was recorded, falling back to a plain `path:line` code span.
|
|
27
|
+
*/
|
|
28
|
+
static location(provenance, symbol) {
|
|
29
|
+
const label = `\`${symbol.filePath}:${symbol.startLine}\``;
|
|
30
|
+
const link = GraphReport.permalink(provenance, symbol);
|
|
31
|
+
return link === null ? label : `[${label}](${link})`;
|
|
32
|
+
}
|
|
33
|
+
static renderMarkdown(data) {
|
|
34
|
+
const lines = [];
|
|
35
|
+
lines.push(`# Codebase brief — ${data.project}`, '');
|
|
36
|
+
lines.push(GraphReport.provenanceLine(data), '');
|
|
37
|
+
lines.push(GraphReport.banner(data), '');
|
|
38
|
+
lines.push(`> ${data.verdict}`, '');
|
|
39
|
+
lines.push('## Snapshot', '', GraphReport.snapshotLine(data), '');
|
|
40
|
+
lines.push('## Composition', '');
|
|
41
|
+
lines.push('**Symbols by kind**', '', ...GraphReport.kindTable(data.nodeKinds), '');
|
|
42
|
+
lines.push('**Relationships by kind**', '', ...GraphReport.kindTable(data.edgeKinds), '');
|
|
43
|
+
lines.push('## Load-bearing code', '');
|
|
44
|
+
lines.push('**Most depended-upon** — direct callers', '');
|
|
45
|
+
lines.push(...GraphReport.rankSection(data.hubsByCallers, 'Callers', 'No call edges — run `extract --semantic`.', data.provenance), '');
|
|
46
|
+
lines.push('**Largest blast radius** — symbols transitively affected by a change', '');
|
|
47
|
+
lines.push(...GraphReport.rankSection(data.hubsByBlastRadius, 'Impacted', 'No call edges — run `extract --semantic`.', data.provenance), '');
|
|
48
|
+
lines.push('## Communities', '');
|
|
49
|
+
lines.push(...GraphReport.communitySection(data), '');
|
|
50
|
+
lines.push('## Runtime', '');
|
|
51
|
+
lines.push(...GraphReport.runtimeSection(data), '');
|
|
52
|
+
if (data.enriched === true) {
|
|
53
|
+
lines.push('## Structure vs. runtime', '');
|
|
54
|
+
lines.push(...GraphReport.structureSection(data.structureVsRuntime), '');
|
|
55
|
+
}
|
|
56
|
+
lines.push('## Cycles', '');
|
|
57
|
+
lines.push(...GraphReport.cycleSection(data), '');
|
|
58
|
+
lines.push('## System boundary', '');
|
|
59
|
+
lines.push(...GraphReport.boundarySection(data), '');
|
|
60
|
+
lines.push('## Cleanup candidates', '');
|
|
61
|
+
lines.push(...GraphReport.deadExportSection(data), '');
|
|
62
|
+
lines.push('## Where to go next', '');
|
|
63
|
+
lines.push(...GraphReport.nextStepsSection(data), '');
|
|
64
|
+
lines.push(`*Generated by [ts-knowledge-graph](${TOOL_REPO_URL})*`, '');
|
|
65
|
+
return lines.join('\n');
|
|
66
|
+
}
|
|
67
|
+
static provenanceLine(data) {
|
|
68
|
+
const parts = [];
|
|
69
|
+
if (data.provenance !== null) {
|
|
70
|
+
if (data.provenance.prefix.length > 0) {
|
|
71
|
+
parts.push(`\`${data.provenance.prefix}\``);
|
|
72
|
+
}
|
|
73
|
+
parts.push(`commit \`${data.provenance.commit.slice(0, 7)}\``);
|
|
74
|
+
}
|
|
75
|
+
parts.push(`generated ${data.generatedAt}`);
|
|
76
|
+
return parts.join(' · ');
|
|
77
|
+
}
|
|
78
|
+
static banner(data) {
|
|
79
|
+
const semantic = `semantic ${data.semantic === true ? '✓' : '—'}`;
|
|
80
|
+
const enriched = `enriched ${data.enriched === true ? '✓' : '—'}`;
|
|
81
|
+
const coverage = data.coverage === null ? '' : ` · runtime coverage ${GraphReport.pct0(data.coverage)}`;
|
|
82
|
+
return `**${semantic} · ${enriched}${coverage}**`;
|
|
83
|
+
}
|
|
84
|
+
static snapshotLine(data) {
|
|
85
|
+
const quality = data.communityQuality === null ? '' : ` (quality ${data.communityQuality.toFixed(2)})`;
|
|
86
|
+
return [
|
|
87
|
+
`${data.totals.symbols} symbols`,
|
|
88
|
+
`${data.totals.files} files`,
|
|
89
|
+
`${data.totals.relationships} relationships`,
|
|
90
|
+
`${data.totals.communities} communities${quality}`,
|
|
91
|
+
`${data.totals.deadExports} dead exports`,
|
|
92
|
+
`${data.totals.cycles} cycles`,
|
|
93
|
+
].join(' · ');
|
|
94
|
+
}
|
|
95
|
+
static kindTable(kinds) {
|
|
96
|
+
if (kinds.length === 0) {
|
|
97
|
+
return ['_(none)_'];
|
|
98
|
+
}
|
|
99
|
+
return GraphReport.table(['Kind', 'Count'], kinds.map((entry) => [`\`${entry.kind}\``, String(entry.count)]), ['left', 'right']);
|
|
100
|
+
}
|
|
101
|
+
static rankSection(items, scoreHeader, empty, provenance) {
|
|
102
|
+
if (items.length === 0) {
|
|
103
|
+
return [`_${empty}_`];
|
|
104
|
+
}
|
|
105
|
+
return GraphReport.table(['Symbol', scoreHeader, 'Location'], items.map((item) => [`\`${item.name}\``, String(item.score), GraphReport.location(provenance, item)]), ['left', 'right', 'left']);
|
|
106
|
+
}
|
|
107
|
+
static communitySection(data) {
|
|
108
|
+
if (data.communities.length === 0) {
|
|
109
|
+
return ['_No communities assigned — run `cluster` to populate._'];
|
|
110
|
+
}
|
|
111
|
+
return GraphReport.table(['Community', 'Size'], data.communities.map((community) => [GraphReport.cell(community.label), String(community.size)]), ['left', 'right']);
|
|
112
|
+
}
|
|
113
|
+
static runtimeSection(data) {
|
|
114
|
+
if (data.enriched === false) {
|
|
115
|
+
return ['_Run `enrich` to populate the runtime sections (hotspots, cost, structure-vs-runtime)._'];
|
|
116
|
+
}
|
|
117
|
+
const lines = [];
|
|
118
|
+
lines.push('**Hotspots** — exclusive self-time', '');
|
|
119
|
+
lines.push(...GraphReport.table(['Symbol', 'Self-time (ms)', 'Location'], data.hotspots.map((hotspot) => [`\`${hotspot.name}\``, hotspot.score.toFixed(1), GraphReport.location(data.provenance, hotspot)]), ['left', 'right', 'left']), '');
|
|
120
|
+
lines.push('**Cost** — inclusive, share of total runtime', '');
|
|
121
|
+
lines.push(...GraphReport.table(['Symbol', 'Inclusive (ms)', 'Share', 'Location'], data.cost.map((node) => [
|
|
122
|
+
`\`${node.name}\`${node.cyclic === true ? ' ↺' : ''}`,
|
|
123
|
+
node.inclusiveCost.toFixed(1),
|
|
124
|
+
GraphReport.pct1(node.shareOfTotal),
|
|
125
|
+
GraphReport.location(data.provenance, node),
|
|
126
|
+
]), ['left', 'right', 'right', 'left']));
|
|
127
|
+
return lines;
|
|
128
|
+
}
|
|
129
|
+
static structureSection(structure) {
|
|
130
|
+
return [
|
|
131
|
+
GraphReport.groupLine('Orchestrators', 'high inclusive cost, ~0 self — optimize their callees', structure.orchestrators),
|
|
132
|
+
GraphReport.groupLine('Hidden hotspots', 'hot, but few callers — easy to miss in review', structure.hiddenHotspots),
|
|
133
|
+
GraphReport.groupLine('Aligned core', 'most depended-upon and hottest — genuine hotspots', structure.alignedCore),
|
|
134
|
+
];
|
|
135
|
+
}
|
|
136
|
+
static groupLine(title, description, members) {
|
|
137
|
+
const names = members.length === 0 ? '—' : members.map((member) => `\`${member.name}\``).join(', ');
|
|
138
|
+
return `- **${title}** (${description}): ${names}`;
|
|
139
|
+
}
|
|
140
|
+
static cycleSection(data) {
|
|
141
|
+
if (data.cycles.length === 0) {
|
|
142
|
+
return ['_No call cycles detected — the call graph is acyclic._'];
|
|
143
|
+
}
|
|
144
|
+
return data.cycles.map((cycle) => `- ${cycle.size}-symbol cycle: ${cycle.members.map((member) => `\`${member.name}\``).join(', ')}`);
|
|
145
|
+
}
|
|
146
|
+
static boundarySection(data) {
|
|
147
|
+
const { endpoints, configFlags, externalApis } = data.boundary;
|
|
148
|
+
if (endpoints.length === 0 && configFlags.length === 0 && externalApis.length === 0) {
|
|
149
|
+
return ['_No endpoints, configuration flags, or external API calls detected._'];
|
|
150
|
+
}
|
|
151
|
+
const lines = [];
|
|
152
|
+
const list = (label, items) => {
|
|
153
|
+
if (items.length > 0) {
|
|
154
|
+
lines.push(`- **${label}** (${items.length}): ${items.map((item) => `\`${item.name}\``).join(', ')}`);
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
list('Endpoints', endpoints);
|
|
158
|
+
list('Configuration flags', configFlags);
|
|
159
|
+
list('External APIs', externalApis);
|
|
160
|
+
return lines;
|
|
161
|
+
}
|
|
162
|
+
static deadExportSection(data) {
|
|
163
|
+
if (data.deadExports.length === 0) {
|
|
164
|
+
return ['_No dead exports._'];
|
|
165
|
+
}
|
|
166
|
+
return [
|
|
167
|
+
'Exported but never referenced:',
|
|
168
|
+
'',
|
|
169
|
+
...GraphReport.table(['Symbol', 'Kind', 'Location'], data.deadExports.map((symbol) => [`\`${symbol.name}\``, symbol.kind, GraphReport.location(data.provenance, symbol)])),
|
|
170
|
+
];
|
|
171
|
+
}
|
|
172
|
+
static nextStepsSection(data) {
|
|
173
|
+
const commands = [];
|
|
174
|
+
if (data.enriched === true) {
|
|
175
|
+
commands.push('# rank where runtime is spent, and who is responsible for it', `ts-knowledge-graph hotspots -o ${data.outputFolder}`, `ts-knowledge-graph cost -o ${data.outputFolder}`);
|
|
176
|
+
}
|
|
177
|
+
else if (data.hubsByBlastRadius.length > 0) {
|
|
178
|
+
commands.push('# the highest-impact symbols to change carefully', `ts-knowledge-graph hotspots --by blast-radius -o ${data.outputFolder}`);
|
|
179
|
+
}
|
|
180
|
+
if (data.deadExports.length > 0) {
|
|
181
|
+
commands.push('# confirm dead code before deleting', `ts-knowledge-graph dead-exports -o ${data.outputFolder}`);
|
|
182
|
+
}
|
|
183
|
+
commands.push('# explore the whole graph interactively', `ts-knowledge-graph webview -o ${data.outputFolder}`);
|
|
184
|
+
const lines = ['```sh', ...commands, '```'];
|
|
185
|
+
const focus = data.enriched === true && data.hotspots.length > 0 ? data.hotspots[0] : data.hubsByBlastRadius[0];
|
|
186
|
+
const link = focus === undefined ? null : GraphReport.permalink(data.provenance, focus);
|
|
187
|
+
if (link !== null) {
|
|
188
|
+
const label = data.enriched === true ? 'Hottest symbol' : 'Highest-impact symbol';
|
|
189
|
+
lines.push('', `${label} on GitHub: [\`${focus.name}\`](${link})`);
|
|
190
|
+
}
|
|
191
|
+
return lines;
|
|
192
|
+
}
|
|
193
|
+
static table(headers, rows, align = []) {
|
|
194
|
+
const head = `| ${headers.join(' | ')} |`;
|
|
195
|
+
const separator = `| ${headers.map((_, index) => (align[index] === 'right' ? '---:' : '---')).join(' | ')} |`;
|
|
196
|
+
const body = rows.map((row) => `| ${row.map(GraphReport.cell).join(' | ')} |`);
|
|
197
|
+
return [head, separator, ...body];
|
|
198
|
+
}
|
|
199
|
+
/** Escapes the pipe character so a symbol name never breaks a markdown table row. */
|
|
200
|
+
static cell(value) {
|
|
201
|
+
return value.replace(/\|/g, '\\|');
|
|
202
|
+
}
|
|
203
|
+
static pct0(value) {
|
|
204
|
+
return `${(value * 100).toFixed(0)}%`;
|
|
205
|
+
}
|
|
206
|
+
static pct1(value) {
|
|
207
|
+
return `${(value * 100).toFixed(1)}%`;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Renders a self-contained, print-ready HTML document for the same data — the
|
|
211
|
+
* substrate the `pdf` format is converted from, and a usable artifact on its own.
|
|
212
|
+
* Light theme, system fonts, inline styles, CSS-only bar charts: no external
|
|
213
|
+
* assets, so it renders identically offline and in a headless browser.
|
|
214
|
+
*/
|
|
215
|
+
static renderVisualHtml(data) {
|
|
216
|
+
const esc = GraphReport.escapeHtml;
|
|
217
|
+
const badge = (label, on) => `<span class="badge ${on === true ? 'ok' : 'off'}">${esc(label)} ${on === true ? '✓' : '—'}</span>`;
|
|
218
|
+
const coverageBadge = data.coverage === null ? '' : `<span class="badge info">coverage ${GraphReport.pct0(data.coverage)}</span>`;
|
|
219
|
+
const metric = (label, value) => `<div class="metric"><div class="metric-label">${esc(label)}</div><div class="metric-value">${esc(value)}</div></div>`;
|
|
220
|
+
const maxSelf = data.hotspots.reduce((max, hotspot) => Math.max(max, hotspot.score), 0);
|
|
221
|
+
const bar = (label, value, fraction, color) => `<div class="bar-row"><span class="bar-name">${esc(label)}</span>`
|
|
222
|
+
+ `<span class="bar-track"><span class="bar-fill" style="width:${Math.min(100, Math.max(0, fraction * 100)).toFixed(1)}%;background:${color}"></span></span>`
|
|
223
|
+
+ `<span class="bar-val">${esc(value)}</span></div>`;
|
|
224
|
+
const sections = [];
|
|
225
|
+
sections.push(`<header><h1>Codebase brief — ${esc(data.project)}</h1>`
|
|
226
|
+
+ `<p class="sub">${esc(GraphReport.htmlProvenance(data))}</p>`
|
|
227
|
+
+ `<p class="badges">${badge('semantic', data.semantic)} ${badge('enriched', data.enriched)} ${coverageBadge}</p>`
|
|
228
|
+
+ `<p class="verdict">${esc(data.verdict)}</p></header>`);
|
|
229
|
+
sections.push('<div class="metrics">'
|
|
230
|
+
+ metric('symbols', String(data.totals.symbols))
|
|
231
|
+
+ metric('files', String(data.totals.files))
|
|
232
|
+
+ metric('relationships', String(data.totals.relationships))
|
|
233
|
+
+ metric('communities', String(data.totals.communities))
|
|
234
|
+
+ metric('dead exports', String(data.totals.deadExports))
|
|
235
|
+
+ metric('cycles', String(data.totals.cycles))
|
|
236
|
+
+ '</div>');
|
|
237
|
+
if (data.enriched === true && data.cost.length > 0) {
|
|
238
|
+
const rows = data.cost.map((node) => bar(node.name, `${GraphReport.pct1(node.shareOfTotal)}`, node.shareOfTotal, '#185FA5')).join('');
|
|
239
|
+
sections.push(`<section><h2>Inclusive cost — share of total runtime</h2>${rows}</section>`);
|
|
240
|
+
}
|
|
241
|
+
if (data.enriched === true && data.hotspots.length > 0) {
|
|
242
|
+
const rows = data.hotspots.map((hotspot) => bar(hotspot.name, `${hotspot.score.toFixed(1)} ms`, maxSelf > 0 ? hotspot.score / maxSelf : 0, '#854F0B')).join('');
|
|
243
|
+
sections.push(`<section><h2>Self-time — exclusive milliseconds</h2>${rows}</section>`);
|
|
244
|
+
}
|
|
245
|
+
if (data.enriched === true) {
|
|
246
|
+
const card = (title, description, members, tone) => `<div class="svr ${tone}"><div class="svr-title">${esc(title)}</div>`
|
|
247
|
+
+ `<div class="svr-members">${members.length === 0 ? '—' : members.map((member) => esc(member.name)).join(' · ')}</div>`
|
|
248
|
+
+ `<div class="svr-note">${esc(description)}</div></div>`;
|
|
249
|
+
sections.push('<section><h2>Structure vs. runtime</h2><div class="svr-grid">'
|
|
250
|
+
+ card('Orchestrators', 'high inclusive cost, ~0 self — optimize their callees', data.structureVsRuntime.orchestrators, 'neutral')
|
|
251
|
+
+ card('Hidden hotspots', 'hot, but few callers — easy to miss', data.structureVsRuntime.hiddenHotspots, 'warn')
|
|
252
|
+
+ card('Aligned core', 'central and hot — genuine hotspots', data.structureVsRuntime.alignedCore, 'ok')
|
|
253
|
+
+ '</div></section>');
|
|
254
|
+
}
|
|
255
|
+
if (data.deadExports.length > 0) {
|
|
256
|
+
const rows = data.deadExports.map((symbol) => `<tr><td class="mono">${esc(symbol.name)}</td><td>${esc(symbol.kind)}</td><td class="mono dim">${esc(`${symbol.filePath}:${symbol.startLine}`)}</td></tr>`).join('');
|
|
257
|
+
sections.push(`<section><h2>Dead exports</h2><table><thead><tr><th>Symbol</th><th>Kind</th><th>Location</th></tr></thead><tbody>${rows}</tbody></table></section>`);
|
|
258
|
+
}
|
|
259
|
+
return GraphReport.htmlDocument(data.project, sections.join(''));
|
|
260
|
+
}
|
|
261
|
+
static htmlProvenance(data) {
|
|
262
|
+
const parts = [];
|
|
263
|
+
if (data.provenance !== null) {
|
|
264
|
+
parts.push(`${data.provenance.baseUrl.replace(/^https?:\/\//, '')}`);
|
|
265
|
+
parts.push(`commit ${data.provenance.commit.slice(0, 7)}`);
|
|
266
|
+
}
|
|
267
|
+
parts.push(`generated ${data.generatedAt}`);
|
|
268
|
+
return parts.join(' · ');
|
|
269
|
+
}
|
|
270
|
+
static htmlDocument(title, body) {
|
|
271
|
+
const style = [
|
|
272
|
+
'*{box-sizing:border-box}',
|
|
273
|
+
'body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif;color:#1b1b1a;background:#fff;max-width:820px;margin:0 auto;padding:40px 32px;line-height:1.5}',
|
|
274
|
+
'h1{font-size:24px;font-weight:600;margin:0}',
|
|
275
|
+
'h2{font-size:15px;font-weight:600;color:#5f5e5a;margin:28px 0 12px;text-transform:none}',
|
|
276
|
+
'.sub{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;color:#888780;margin:4px 0 12px}',
|
|
277
|
+
'.badges{margin:0 0 14px}',
|
|
278
|
+
'.badge{display:inline-block;font-size:12px;padding:3px 9px;border-radius:6px;margin-right:6px}',
|
|
279
|
+
'.badge.ok{background:#E1F5EE;color:#0F6E56}.badge.off{background:#F1EFE8;color:#5F5E5A}.badge.info{background:#E6F1FB;color:#185FA5}',
|
|
280
|
+
'.verdict{font-size:15px;background:#F1EFE8;border-radius:10px;padding:12px 14px;margin:0}',
|
|
281
|
+
'.metrics{display:flex;flex-wrap:wrap;gap:10px;margin:18px 0}',
|
|
282
|
+
'.metric{background:#F1EFE8;border-radius:8px;padding:10px 14px;min-width:96px}',
|
|
283
|
+
'.metric-label{font-size:12px;color:#5f5e5a}.metric-value{font-size:22px;font-weight:600}',
|
|
284
|
+
'.bar-row{display:flex;align-items:center;gap:10px;margin:6px 0}',
|
|
285
|
+
'.bar-name{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:13px;width:190px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}',
|
|
286
|
+
'.bar-track{flex:1;height:9px;background:#F1EFE8;border-radius:999px;overflow:hidden}',
|
|
287
|
+
'.bar-fill{display:block;height:100%}',
|
|
288
|
+
'.bar-val{font-size:12px;color:#5f5e5a;width:74px;text-align:right}',
|
|
289
|
+
'.svr-grid{display:flex;gap:10px;flex-wrap:wrap}',
|
|
290
|
+
'.svr{flex:1;min-width:200px;border-radius:10px;padding:12px}',
|
|
291
|
+
'.svr.neutral{background:#F1EFE8}.svr.warn{background:#FAEEDA}.svr.ok{background:#E1F5EE}',
|
|
292
|
+
'.svr-title{font-size:13px;font-weight:600;margin-bottom:6px}',
|
|
293
|
+
'.svr-members{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;margin-bottom:6px}',
|
|
294
|
+
'.svr-note{font-size:12px;color:#5f5e5a}',
|
|
295
|
+
'table{width:100%;border-collapse:collapse;font-size:13px}',
|
|
296
|
+
'th{text-align:left;color:#5f5e5a;font-weight:500;border-bottom:1px solid #D3D1C7;padding:6px 8px}',
|
|
297
|
+
'td{padding:6px 8px;border-bottom:1px solid #F1EFE8}',
|
|
298
|
+
'.mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.dim{color:#888780}',
|
|
299
|
+
'footer{margin-top:32px;font-size:12px;color:#888780}',
|
|
300
|
+
].join('');
|
|
301
|
+
return `<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><title>Codebase brief — ${GraphReport.escapeHtml(title)}</title><style>${style}</style></head>`
|
|
302
|
+
+ `<body>${body}<footer>Generated by <a href="${TOOL_REPO_URL}">ts-knowledge-graph</a></footer></body></html>`;
|
|
303
|
+
}
|
|
304
|
+
static escapeHtml(value) {
|
|
305
|
+
return value
|
|
306
|
+
.replace(/&/g, '&')
|
|
307
|
+
.replace(/</g, '<')
|
|
308
|
+
.replace(/>/g, '>')
|
|
309
|
+
.replace(/"/g, '"');
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
//# sourceMappingURL=graph_report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph_report.js","sourceRoot":"","sources":["../../src/report/graph_report.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** Thrown when no HTML-to-PDF engine is installed, so callers can fall back gracefully. */
|
|
2
|
+
export declare class PdfUnavailableError extends Error {
|
|
3
|
+
constructor(message: string);
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Converts the report's visual HTML to a PDF through an optional, lazily-loaded
|
|
7
|
+
* headless-browser engine (Puppeteer). The engine is never a hard dependency, so
|
|
8
|
+
* `markdown`/`json` users never pull it in; when it is absent this throws
|
|
9
|
+
* {@link PdfUnavailableError} for the command to handle (it falls back to writing
|
|
10
|
+
* the HTML). Keeping the conversion here leaves {@link GraphReport} pure.
|
|
11
|
+
*/
|
|
12
|
+
export declare class PdfRenderer {
|
|
13
|
+
static fromHtml(html: string): Promise<Uint8Array>;
|
|
14
|
+
/**
|
|
15
|
+
* Resolves the optional PDF engine by name at runtime. The specifier is a
|
|
16
|
+
* `string`-typed variable on purpose, so the type checker treats it as a dynamic
|
|
17
|
+
* import (`Promise<unknown>`) and does not require `puppeteer` to be installed
|
|
18
|
+
* to type-check the project.
|
|
19
|
+
*/
|
|
20
|
+
private static loadEngine;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=pdf_renderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pdf_renderer.d.ts","sourceRoot":"","sources":["../../src/report/pdf_renderer.ts"],"names":[],"mappings":"AAAA,2FAA2F;AAC3F,qBAAa,mBAAoB,SAAQ,KAAK;gBACjC,OAAO,EAAE,MAAM;CAI3B;AAgBD;;;;;;GAMG;AACH,qBAAa,WAAW;WACV,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAgBxD;;;;;OAKG;mBACkB,UAAU;CAc/B"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/** Thrown when no HTML-to-PDF engine is installed, so callers can fall back gracefully. */
|
|
2
|
+
export class PdfUnavailableError extends Error {
|
|
3
|
+
constructor(message) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.name = 'PdfUnavailableError';
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Converts the report's visual HTML to a PDF through an optional, lazily-loaded
|
|
10
|
+
* headless-browser engine (Puppeteer). The engine is never a hard dependency, so
|
|
11
|
+
* `markdown`/`json` users never pull it in; when it is absent this throws
|
|
12
|
+
* {@link PdfUnavailableError} for the command to handle (it falls back to writing
|
|
13
|
+
* the HTML). Keeping the conversion here leaves {@link GraphReport} pure.
|
|
14
|
+
*/
|
|
15
|
+
export class PdfRenderer {
|
|
16
|
+
static async fromHtml(html) {
|
|
17
|
+
const engine = await PdfRenderer.loadEngine();
|
|
18
|
+
const browser = await engine.launch({ headless: true });
|
|
19
|
+
try {
|
|
20
|
+
const page = await browser.newPage();
|
|
21
|
+
await page.setContent(html, { waitUntil: 'networkidle0' });
|
|
22
|
+
return await page.pdf({
|
|
23
|
+
format: 'A4',
|
|
24
|
+
printBackground: true,
|
|
25
|
+
margin: { top: '14mm', bottom: '14mm', left: '12mm', right: '12mm' },
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
finally {
|
|
29
|
+
await browser.close();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Resolves the optional PDF engine by name at runtime. The specifier is a
|
|
34
|
+
* `string`-typed variable on purpose, so the type checker treats it as a dynamic
|
|
35
|
+
* import (`Promise<unknown>`) and does not require `puppeteer` to be installed
|
|
36
|
+
* to type-check the project.
|
|
37
|
+
*/
|
|
38
|
+
static async loadEngine() {
|
|
39
|
+
const moduleName = 'puppeteer';
|
|
40
|
+
let imported;
|
|
41
|
+
try {
|
|
42
|
+
imported = (await import(moduleName));
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
throw new PdfUnavailableError('PDF output needs a headless-browser engine — install one with `npm i -D puppeteer`.');
|
|
46
|
+
}
|
|
47
|
+
const engine = imported.default ?? (imported.launch !== undefined ? imported : undefined);
|
|
48
|
+
if (engine === undefined) {
|
|
49
|
+
throw new PdfUnavailableError('the installed `puppeteer` does not expose a launch() entry point.');
|
|
50
|
+
}
|
|
51
|
+
return engine;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=pdf_renderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pdf_renderer.js","sourceRoot":"","sources":["../../src/report/pdf_renderer.ts"],"names":[],"mappings":"AAAA,2FAA2F;AAC3F,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAC7C,YAAY,OAAe;QAC1B,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACnC,CAAC;CACD;AAgBD;;;;;;GAMG;AACH,MAAM,OAAO,WAAW;IACvB,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAY;QACjC,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,UAAU,EAAE,CAAC;QAC9C,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QACxD,IAAI,CAAC;YACJ,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;YACrC,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,cAAc,EAAE,CAAC,CAAC;YAC3D,OAAO,MAAM,IAAI,CAAC,GAAG,CAAC;gBACrB,MAAM,EAAE,IAAI;gBACZ,eAAe,EAAE,IAAI;gBACrB,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE;aACpE,CAAC,CAAC;QACJ,CAAC;gBAAS,CAAC;YACV,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;QACvB,CAAC;IACF,CAAC;IAED;;;;;OAKG;IACK,MAAM,CAAC,KAAK,CAAC,UAAU;QAC9B,MAAM,UAAU,GAAW,WAAW,CAAC;QACvC,IAAI,QAAsD,CAAC;QAC3D,IAAI,CAAC;YACJ,QAAQ,GAAG,CAAC,MAAM,MAAM,CAAC,UAAU,CAAC,CAAiD,CAAC;QACvF,CAAC;QAAC,MAAM,CAAC;YACR,MAAM,IAAI,mBAAmB,CAAC,qFAAqF,CAAC,CAAC;QACtH,CAAC;QACD,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAE,QAAsB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QACzG,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YAC1B,MAAM,IAAI,mBAAmB,CAAC,mEAAmE,CAAC,CAAC;QACpG,CAAC;QACD,OAAO,MAAM,CAAC;IACf,CAAC;CACD"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { GraphQuery } from '../query/graph_query.js';
|
|
2
|
+
import { SourceManifest } from '../schema/source_manifest.js';
|
|
3
|
+
import { KuzuStore } from '../store/kuzu_store.js';
|
|
4
|
+
/** A graph symbol reduced to the fields every report section renders. */
|
|
5
|
+
export type ReportSymbol = {
|
|
6
|
+
name: string;
|
|
7
|
+
kind: string;
|
|
8
|
+
filePath: string;
|
|
9
|
+
startLine: number;
|
|
10
|
+
};
|
|
11
|
+
/** A {@link ReportSymbol} carrying the score it earned in a ranking. */
|
|
12
|
+
export type RankedSymbol = ReportSymbol & {
|
|
13
|
+
score: number;
|
|
14
|
+
};
|
|
15
|
+
/** A {@link ReportSymbol} carrying its propagated cost, for the runtime sections. */
|
|
16
|
+
export type ReportCostNode = ReportSymbol & {
|
|
17
|
+
selfCost: number;
|
|
18
|
+
inclusiveCost: number;
|
|
19
|
+
shareOfTotal: number;
|
|
20
|
+
cyclic: boolean;
|
|
21
|
+
cycleSize: number;
|
|
22
|
+
};
|
|
23
|
+
/** One row of the composition tables: a node or edge kind and how many carry it. */
|
|
24
|
+
export type KindCount = {
|
|
25
|
+
kind: string;
|
|
26
|
+
count: number;
|
|
27
|
+
};
|
|
28
|
+
/** A detected community, named by its label and sized by its membership. */
|
|
29
|
+
export type ReportCommunity = {
|
|
30
|
+
label: string;
|
|
31
|
+
size: number;
|
|
32
|
+
};
|
|
33
|
+
/** One call cycle: the strongly-connected component's size and its members. */
|
|
34
|
+
export type ReportCycle = {
|
|
35
|
+
size: number;
|
|
36
|
+
members: ReportSymbol[];
|
|
37
|
+
};
|
|
38
|
+
/** The system-level surface area: routes handled, configuration read, hosts called. */
|
|
39
|
+
export type ReportBoundary = {
|
|
40
|
+
endpoints: ReportSymbol[];
|
|
41
|
+
configFlags: ReportSymbol[];
|
|
42
|
+
externalApis: ReportSymbol[];
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* The static-call-graph view set against the runtime profile. `orchestrators`
|
|
46
|
+
* carry cost but spend ~none themselves; `hiddenHotspots` are hot yet have few
|
|
47
|
+
* callers; `alignedCore` are both central and hot. Empty on an un-enriched graph.
|
|
48
|
+
*/
|
|
49
|
+
export type StructureVsRuntime = {
|
|
50
|
+
orchestrators: ReportSymbol[];
|
|
51
|
+
hiddenHotspots: ReportSymbol[];
|
|
52
|
+
alignedCore: ReportSymbol[];
|
|
53
|
+
};
|
|
54
|
+
/** The complete, format-agnostic data a {@link GraphReport} renders. */
|
|
55
|
+
export type GraphReportData = {
|
|
56
|
+
generatedAt: string;
|
|
57
|
+
project: string;
|
|
58
|
+
outputFolder: string;
|
|
59
|
+
provenance: SourceManifest | null;
|
|
60
|
+
semantic: boolean;
|
|
61
|
+
enriched: boolean;
|
|
62
|
+
coverage: number | null;
|
|
63
|
+
totalSelf: number;
|
|
64
|
+
limit: number;
|
|
65
|
+
totals: {
|
|
66
|
+
symbols: number;
|
|
67
|
+
files: number;
|
|
68
|
+
relationships: number;
|
|
69
|
+
communities: number;
|
|
70
|
+
deadExports: number;
|
|
71
|
+
cycles: number;
|
|
72
|
+
};
|
|
73
|
+
verdict: string;
|
|
74
|
+
nodeKinds: KindCount[];
|
|
75
|
+
edgeKinds: KindCount[];
|
|
76
|
+
hubsByCallers: RankedSymbol[];
|
|
77
|
+
hubsByBlastRadius: RankedSymbol[];
|
|
78
|
+
communityQuality: number | null;
|
|
79
|
+
communities: ReportCommunity[];
|
|
80
|
+
hotspots: RankedSymbol[];
|
|
81
|
+
cost: ReportCostNode[];
|
|
82
|
+
structureVsRuntime: StructureVsRuntime;
|
|
83
|
+
cycles: ReportCycle[];
|
|
84
|
+
boundary: ReportBoundary;
|
|
85
|
+
deadExports: ReportSymbol[];
|
|
86
|
+
};
|
|
87
|
+
export type GatherOptions = {
|
|
88
|
+
/** ISO date (YYYY-MM-DD) the command stamps; passed in so gathering stays pure of the clock. */
|
|
89
|
+
generatedAt: string;
|
|
90
|
+
/** Fallback project label when the graph records no source provenance. */
|
|
91
|
+
project: string;
|
|
92
|
+
/** The output folder, echoed into the copy-pasteable "where to go next" commands. */
|
|
93
|
+
outputFolder: string;
|
|
94
|
+
/** Top-N kept per ranking. */
|
|
95
|
+
limit: number;
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* Gathers a {@link GraphReportData} from a loaded graph, reusing the existing
|
|
99
|
+
* query surface (`hotspots`, `costRanking`, `deadExports`, `strongCycles`) plus a
|
|
100
|
+
* few direct reads for composition and communities. Mirrors how the other
|
|
101
|
+
* commands lean on {@link GraphQuery}; the rendering is left entirely to
|
|
102
|
+
* {@link GraphReport}, so this stays presentation-free apart from the one-line
|
|
103
|
+
* verdict it synthesises.
|
|
104
|
+
*/
|
|
105
|
+
export declare class ReportData {
|
|
106
|
+
static gather(store: KuzuStore, query: GraphQuery, options: GatherOptions): Promise<GraphReportData>;
|
|
107
|
+
private static edgeKindCounts;
|
|
108
|
+
private static nodeKindCounts;
|
|
109
|
+
private static countBy;
|
|
110
|
+
/** Groups nodes by their assigned community index, labelled and sized, largest first. */
|
|
111
|
+
private static communitiesOf;
|
|
112
|
+
private static boundaryOf;
|
|
113
|
+
/**
|
|
114
|
+
* Splits the measured graph into three reads of the same symbols: pure
|
|
115
|
+
* orchestrators (cost flows through, ~no self cost), hidden hotspots (hot, few
|
|
116
|
+
* callers), and the aligned core (central and hot).
|
|
117
|
+
*/
|
|
118
|
+
private static synthesize;
|
|
119
|
+
private static readProvenance;
|
|
120
|
+
private static readCommunityQuality;
|
|
121
|
+
/** Derives `owner/repo` from the recorded GitHub base URL, falling back to the given label. */
|
|
122
|
+
private static projectName;
|
|
123
|
+
private static verdictOf;
|
|
124
|
+
private static toRanked;
|
|
125
|
+
private static toCostNode;
|
|
126
|
+
private static toSymbol;
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=report_data.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report_data.d.ts","sourceRoot":"","sources":["../../src/report/report_data.ts"],"names":[],"mappings":"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"}
|