@vyuhlabs/dxkit 2.6.0 → 2.7.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/CHANGELOG.md +54 -13
- package/README.md +208 -459
- package/dist/analyzers/bom/discovery.d.ts +3 -4
- package/dist/analyzers/bom/discovery.d.ts.map +1 -1
- package/dist/analyzers/bom/discovery.js +3 -4
- package/dist/analyzers/bom/discovery.js.map +1 -1
- package/dist/analyzers/bom/types.d.ts +1 -1
- package/dist/analyzers/dashboard/index.d.ts.map +1 -1
- package/dist/analyzers/dashboard/index.js +42 -5
- package/dist/analyzers/dashboard/index.js.map +1 -1
- package/dist/analyzers/quality/detailed.d.ts +8 -1
- package/dist/analyzers/quality/detailed.d.ts.map +1 -1
- package/dist/analyzers/quality/detailed.js +43 -10
- package/dist/analyzers/quality/detailed.js.map +1 -1
- package/dist/analyzers/security/detailed.d.ts +8 -1
- package/dist/analyzers/security/detailed.d.ts.map +1 -1
- package/dist/analyzers/security/detailed.js +14 -1
- package/dist/analyzers/security/detailed.js.map +1 -1
- package/dist/analyzers/tests/detailed.d.ts +8 -1
- package/dist/analyzers/tests/detailed.d.ts.map +1 -1
- package/dist/analyzers/tests/detailed.js +26 -7
- package/dist/analyzers/tests/detailed.js.map +1 -1
- package/dist/analyzers/tools/cloc.js +3 -3
- package/dist/analyzers/tools/cloc.js.map +1 -1
- package/dist/analyzers/tools/exclusions.d.ts +12 -12
- package/dist/analyzers/tools/exclusions.d.ts.map +1 -1
- package/dist/analyzers/tools/exclusions.js +27 -13
- package/dist/analyzers/tools/exclusions.js.map +1 -1
- package/dist/analyzers/tools/graphify.d.ts +39 -5
- package/dist/analyzers/tools/graphify.d.ts.map +1 -1
- package/dist/analyzers/tools/graphify.js +609 -45
- package/dist/analyzers/tools/graphify.js.map +1 -1
- package/dist/analyzers/tools/nuget-package-reference.d.ts +4 -4
- package/dist/analyzers/tools/nuget-package-reference.js +4 -4
- package/dist/analyzers/tools/osv-scanner-fix.d.ts +4 -5
- package/dist/analyzers/tools/osv-scanner-fix.d.ts.map +1 -1
- package/dist/analyzers/tools/osv-scanner-fix.js +4 -5
- package/dist/analyzers/tools/osv-scanner-fix.js.map +1 -1
- package/dist/analyzers/tools/parallel.d.ts.map +1 -1
- package/dist/analyzers/tools/parallel.js +7 -0
- package/dist/analyzers/tools/parallel.js.map +1 -1
- package/dist/analyzers/tools/vendored-advisor.d.ts.map +1 -1
- package/dist/analyzers/tools/vendored-advisor.js +3 -4
- package/dist/analyzers/tools/vendored-advisor.js.map +1 -1
- package/dist/analyzers/xlsx/licenses.d.ts +7 -7
- package/dist/analyzers/xlsx/licenses.js +7 -7
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +80 -3
- package/dist/cli.js.map +1 -1
- package/dist/dashboard/graph-adapter.d.ts +151 -0
- package/dist/dashboard/graph-adapter.d.ts.map +1 -0
- package/dist/dashboard/graph-adapter.js +415 -0
- package/dist/dashboard/graph-adapter.js.map +1 -0
- package/dist/dashboard/graph-tab.d.ts +109 -0
- package/dist/dashboard/graph-tab.d.ts.map +1 -0
- package/dist/dashboard/graph-tab.js +297 -0
- package/dist/dashboard/graph-tab.js.map +1 -0
- package/dist/dashboard/vendor/vis-network.min.js +34 -0
- package/dist/explore/cli/api-surface.d.ts +12 -0
- package/dist/explore/cli/api-surface.d.ts.map +1 -0
- package/dist/explore/cli/api-surface.js +57 -0
- package/dist/explore/cli/api-surface.js.map +1 -0
- package/dist/explore/cli/communities.d.ts +10 -0
- package/dist/explore/cli/communities.d.ts.map +1 -0
- package/dist/explore/cli/communities.js +47 -0
- package/dist/explore/cli/communities.js.map +1 -0
- package/dist/explore/cli/context.d.ts +16 -0
- package/dist/explore/cli/context.d.ts.map +1 -0
- package/dist/explore/cli/context.js +118 -0
- package/dist/explore/cli/context.js.map +1 -0
- package/dist/explore/cli/entry-points.d.ts +12 -0
- package/dist/explore/cli/entry-points.d.ts.map +1 -0
- package/dist/explore/cli/entry-points.js +85 -0
- package/dist/explore/cli/entry-points.js.map +1 -0
- package/dist/explore/cli/feature.d.ts +16 -0
- package/dist/explore/cli/feature.d.ts.map +1 -0
- package/dist/explore/cli/feature.js +89 -0
- package/dist/explore/cli/feature.js.map +1 -0
- package/dist/explore/cli/file.d.ts +12 -0
- package/dist/explore/cli/file.d.ts.map +1 -0
- package/dist/explore/cli/file.js +139 -0
- package/dist/explore/cli/file.js.map +1 -0
- package/dist/explore/cli/hot-files.d.ts +11 -0
- package/dist/explore/cli/hot-files.d.ts.map +1 -0
- package/dist/explore/cli/hot-files.js +63 -0
- package/dist/explore/cli/hot-files.js.map +1 -0
- package/dist/explore/context-hook.d.ts +42 -0
- package/dist/explore/context-hook.d.ts.map +1 -0
- package/dist/explore/context-hook.js +131 -0
- package/dist/explore/context-hook.js.map +1 -0
- package/dist/explore/finding-context.d.ts +69 -0
- package/dist/explore/finding-context.d.ts.map +1 -0
- package/dist/explore/finding-context.js +102 -0
- package/dist/explore/finding-context.js.map +1 -0
- package/dist/explore/format.d.ts +64 -0
- package/dist/explore/format.d.ts.map +1 -0
- package/dist/explore/format.js +99 -0
- package/dist/explore/format.js.map +1 -0
- package/dist/explore/load.d.ts +50 -0
- package/dist/explore/load.d.ts.map +1 -0
- package/dist/explore/load.js +197 -0
- package/dist/explore/load.js.map +1 -0
- package/dist/explore/queries.d.ts +413 -0
- package/dist/explore/queries.d.ts.map +1 -0
- package/dist/explore/queries.js +855 -0
- package/dist/explore/queries.js.map +1 -0
- package/dist/explore/types.d.ts +130 -0
- package/dist/explore/types.d.ts.map +1 -0
- package/dist/explore/types.js +28 -0
- package/dist/explore/types.js.map +1 -0
- package/dist/explore-cli.d.ts +45 -0
- package/dist/explore-cli.d.ts.map +1 -0
- package/dist/explore-cli.js +213 -0
- package/dist/explore-cli.js.map +1 -0
- package/dist/generator.d.ts.map +1 -1
- package/dist/generator.js +19 -0
- package/dist/generator.js.map +1 -1
- package/dist/languages/csharp.d.ts.map +1 -1
- package/dist/languages/csharp.js +31 -11
- package/dist/languages/csharp.js.map +1 -1
- package/dist/languages/go.d.ts.map +1 -1
- package/dist/languages/go.js +4 -0
- package/dist/languages/go.js.map +1 -1
- package/dist/languages/index.d.ts +27 -0
- package/dist/languages/index.d.ts.map +1 -1
- package/dist/languages/index.js +35 -0
- package/dist/languages/index.js.map +1 -1
- package/dist/languages/java.d.ts.map +1 -1
- package/dist/languages/java.js +4 -0
- package/dist/languages/java.js.map +1 -1
- package/dist/languages/kotlin.d.ts.map +1 -1
- package/dist/languages/kotlin.js +4 -0
- package/dist/languages/kotlin.js.map +1 -1
- package/dist/languages/python.d.ts.map +1 -1
- package/dist/languages/python.js +4 -0
- package/dist/languages/python.js.map +1 -1
- package/dist/languages/ruby.d.ts.map +1 -1
- package/dist/languages/ruby.js +4 -0
- package/dist/languages/ruby.js.map +1 -1
- package/dist/languages/rust.d.ts.map +1 -1
- package/dist/languages/rust.js +4 -0
- package/dist/languages/rust.js.map +1 -1
- package/dist/languages/types.d.ts +54 -0
- package/dist/languages/types.d.ts.map +1 -1
- package/dist/languages/typescript.d.ts.map +1 -1
- package/dist/languages/typescript.js +5 -1
- package/dist/languages/typescript.js.map +1 -1
- package/package.json +2 -1
- package/templates/.claude/skills/dxkit-action/SKILL.md +21 -1
- package/templates/.claude/skills/dxkit-reports/SKILL.md +3 -1
- package/templates/AGENTS.md.template +8 -1
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Dashboard graph-viz tab renderer — embeds graphify's vis.js viewer.
|
|
4
|
+
*
|
|
5
|
+
* Sprint 3 pivot (2026-05-27): rather than build a custom cytoscape
|
|
6
|
+
* tier drill-down, we embed the interactive viewer graphify itself
|
|
7
|
+
* ships. The upstream `graphify.export.to_html` writes a self-
|
|
8
|
+
* contained vis.js HTML page to `.dxkit/reports/graph.html` as a
|
|
9
|
+
* side-effect of `gatherGraphifyGraph` (see `analyzers/tools/
|
|
10
|
+
* graphify.ts`). This renderer:
|
|
11
|
+
*
|
|
12
|
+
* 1. reads that HTML
|
|
13
|
+
* 2. swaps graphify's unpkg.com `<script src=…vis-network…>` tag for
|
|
14
|
+
* an inline `<script>` containing the locally-bundled
|
|
15
|
+
* `vis-network.min.js` (offline-friendly per dxkit's posture —
|
|
16
|
+
* no third-party fetch when the user opens the dashboard)
|
|
17
|
+
* 3. emits the swapped HTML inside an `<iframe srcdoc>` so the
|
|
18
|
+
* embedded viewer's CSS + JS namespace stays isolated from the
|
|
19
|
+
* host dashboard
|
|
20
|
+
*
|
|
21
|
+
* Empty-state branches when `graph.html` is missing (gather never
|
|
22
|
+
* ran, graph exceeded the 5000-node viz cap, etc.). Vendor-missing
|
|
23
|
+
* branch when `dist/dashboard/vendor/vis-network.min.js` is absent
|
|
24
|
+
* (`npm run build` hasn't run).
|
|
25
|
+
*
|
|
26
|
+
* Per CLAUDE.md Rule 12, we still flow `graph.json` reads through
|
|
27
|
+
* `loadGraph` even though the renderer doesn't consume `graph.json`
|
|
28
|
+
* itself — the loader doubles as our existence check before we go
|
|
29
|
+
* read `graph.html` off disk.
|
|
30
|
+
*/
|
|
31
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
32
|
+
if (k2 === undefined) k2 = k;
|
|
33
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
34
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
35
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
36
|
+
}
|
|
37
|
+
Object.defineProperty(o, k2, desc);
|
|
38
|
+
}) : (function(o, m, k, k2) {
|
|
39
|
+
if (k2 === undefined) k2 = k;
|
|
40
|
+
o[k2] = m[k];
|
|
41
|
+
}));
|
|
42
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
43
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
44
|
+
}) : function(o, v) {
|
|
45
|
+
o["default"] = v;
|
|
46
|
+
});
|
|
47
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
48
|
+
var ownKeys = function(o) {
|
|
49
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
50
|
+
var ar = [];
|
|
51
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
52
|
+
return ar;
|
|
53
|
+
};
|
|
54
|
+
return ownKeys(o);
|
|
55
|
+
};
|
|
56
|
+
return function (mod) {
|
|
57
|
+
if (mod && mod.__esModule) return mod;
|
|
58
|
+
var result = {};
|
|
59
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
60
|
+
__setModuleDefault(result, mod);
|
|
61
|
+
return result;
|
|
62
|
+
};
|
|
63
|
+
})();
|
|
64
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
65
|
+
exports.GRAPH_TAB_CSS = void 0;
|
|
66
|
+
exports.renderGraphTab = renderGraphTab;
|
|
67
|
+
exports.injectAggregateBanner = injectAggregateBanner;
|
|
68
|
+
exports.inlineVisNetwork = inlineVisNetwork;
|
|
69
|
+
exports.encodeForSrcdoc = encodeForSrcdoc;
|
|
70
|
+
const fs = __importStar(require("fs"));
|
|
71
|
+
const path = __importStar(require("path"));
|
|
72
|
+
const load_1 = require("../explore/load");
|
|
73
|
+
/** Default vendor + report locations, relative to module + cwd. */
|
|
74
|
+
const VENDOR_DIR = path.join(__dirname, 'vendor');
|
|
75
|
+
const GRAPH_HTML_REL = path.join('.dxkit', 'reports', 'graph.html');
|
|
76
|
+
/**
|
|
77
|
+
* One-stop renderer. Returns:
|
|
78
|
+
* - `html`: the HTML fragment to splice into the dashboard body
|
|
79
|
+
* (the new "Graph" tab pane).
|
|
80
|
+
* - `navBadge`: the badge text the sidebar shows next to "Graph"
|
|
81
|
+
* (community count when ready; "—" otherwise).
|
|
82
|
+
* - `hasData`: convenience boolean — true when a viewable graph
|
|
83
|
+
* was found and the iframe will render.
|
|
84
|
+
*/
|
|
85
|
+
function renderGraphTab(opts) {
|
|
86
|
+
const cwd = opts.cwd;
|
|
87
|
+
const graphHtmlPath = opts.graphHtmlPath ?? (cwd ? path.join(cwd, GRAPH_HTML_REL) : '');
|
|
88
|
+
const vendorDir = opts.vendorDir ?? VENDOR_DIR;
|
|
89
|
+
// Rule-12-friendly existence check via the canonical loader. Failure
|
|
90
|
+
// = missing/corrupt graph.json = empty state regardless of whether
|
|
91
|
+
// graph.html happens to be on disk.
|
|
92
|
+
let communityCount = 0;
|
|
93
|
+
if (cwd) {
|
|
94
|
+
try {
|
|
95
|
+
const graph = (0, load_1.loadGraph)(cwd);
|
|
96
|
+
communityCount = graph.communities.length;
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
// fall through to empty-state
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (!cwd || communityCount === 0) {
|
|
103
|
+
return {
|
|
104
|
+
html: renderEmptyState('No graph data found.', emptyStateMessage()),
|
|
105
|
+
navBadge: '—',
|
|
106
|
+
hasData: false,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
if (!graphHtmlPath || !fs.existsSync(graphHtmlPath)) {
|
|
110
|
+
// Graph.json exists but graph.html doesn't — the gather ran but
|
|
111
|
+
// skipped the viz emission (most likely the 5000-node MAX_NODES_FOR_VIZ
|
|
112
|
+
// guard tripped, or graphify is too old to know about to_html). Tell
|
|
113
|
+
// the user what we know.
|
|
114
|
+
return {
|
|
115
|
+
html: renderEmptyState('Interactive viewer skipped.', `Graph data exists (\`.dxkit/reports/graph.json\`, ${communityCount} communities) but graphify's interactive viewer wasn't generated. Common causes: the graph exceeds graphify's 5000-node viewer cap, or the installed graphify is older than v0.5 (run \`npx vyuh-dxkit tools install\` to refresh).`),
|
|
116
|
+
navBadge: String(communityCount),
|
|
117
|
+
hasData: false,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
const visBundle = readVisNetworkBundle(vendorDir);
|
|
121
|
+
if (!visBundle) {
|
|
122
|
+
return {
|
|
123
|
+
html: renderEmptyState('vis-network bundle missing.', 'The dashboard ships an offline-friendly vis-network alongside the graphify viewer; the bundle at `dist/dashboard/vendor/vis-network.min.js` is not present. This typically means dxkit was built without `npm run build`. Run the build and regenerate the dashboard.'),
|
|
124
|
+
navBadge: String(communityCount),
|
|
125
|
+
hasData: false,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
let upstreamHtml;
|
|
129
|
+
try {
|
|
130
|
+
upstreamHtml = fs.readFileSync(graphHtmlPath, 'utf-8');
|
|
131
|
+
}
|
|
132
|
+
catch (err) {
|
|
133
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
134
|
+
return {
|
|
135
|
+
html: renderEmptyState('Failed to read graph.html.', `Error: ${msg}`),
|
|
136
|
+
navBadge: '—',
|
|
137
|
+
hasData: false,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
// Read the sidecar meta if present so we can surface "aggregated view"
|
|
141
|
+
// honestly to the user. Absent meta = older graphify run before the
|
|
142
|
+
// sidecar landed; treat as 'full' and skip the banner.
|
|
143
|
+
const meta = readGraphHtmlMeta(graphHtmlPath);
|
|
144
|
+
const annotatedHtml = meta?.mode === 'aggregated' ? injectAggregateBanner(upstreamHtml, meta) : upstreamHtml;
|
|
145
|
+
const offlineHtml = inlineVisNetwork(annotatedHtml, visBundle);
|
|
146
|
+
const iframe = buildSrcdocIframe(offlineHtml);
|
|
147
|
+
return {
|
|
148
|
+
html: `<div id="graph-tab-pane" class="graph-tab-pane" style="display:none">${iframe}</div>`,
|
|
149
|
+
navBadge: String(communityCount),
|
|
150
|
+
hasData: true,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
// ─── Vendor + HTML manipulation ──────────────────────────────────────────────
|
|
154
|
+
function readVisNetworkBundle(vendorDir) {
|
|
155
|
+
const file = path.join(vendorDir, 'vis-network.min.js');
|
|
156
|
+
if (!fs.existsSync(file))
|
|
157
|
+
return undefined;
|
|
158
|
+
return fs.readFileSync(file, 'utf-8');
|
|
159
|
+
}
|
|
160
|
+
function readGraphHtmlMeta(graphHtmlPath) {
|
|
161
|
+
const metaPath = `${graphHtmlPath}.meta.json`;
|
|
162
|
+
if (!fs.existsSync(metaPath))
|
|
163
|
+
return undefined;
|
|
164
|
+
try {
|
|
165
|
+
const parsed = JSON.parse(fs.readFileSync(metaPath, 'utf-8'));
|
|
166
|
+
if (parsed &&
|
|
167
|
+
typeof parsed === 'object' &&
|
|
168
|
+
'mode' in parsed &&
|
|
169
|
+
parsed.mode &&
|
|
170
|
+
typeof parsed.mode === 'string') {
|
|
171
|
+
return parsed;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
// ignore — absent/corrupt meta = no banner, viewer still works
|
|
176
|
+
}
|
|
177
|
+
return undefined;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Prepend a small banner inside graphify's `<body>` explaining that
|
|
181
|
+
* the visible view is community-aggregated. Surfaced for honesty —
|
|
182
|
+
* the user should understand each node is a cluster, not a symbol,
|
|
183
|
+
* when the full graph exceeded the 5000-node viz cap.
|
|
184
|
+
*
|
|
185
|
+
* Exported for tests.
|
|
186
|
+
*/
|
|
187
|
+
function injectAggregateBanner(html, meta) {
|
|
188
|
+
const banner = `
|
|
189
|
+
<div id="dxkit-aggregated-banner" style="position:fixed;top:8px;left:8px;right:300px;z-index:1000;padding:10px 14px;background:rgba(78,121,167,0.92);color:#fff;border-radius:6px;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;font-size:12px;line-height:1.45;box-shadow:0 2px 8px rgba(0,0,0,0.4);">
|
|
190
|
+
<strong>Community-aggregated view.</strong>
|
|
191
|
+
Each node is a Louvain cluster of related symbols, not an individual symbol — the full graph (${meta.totalNodes.toLocaleString()} symbols, ${meta.totalEdges.toLocaleString()} edges) exceeds vis.js's 5,000-node interactive cap.
|
|
192
|
+
Showing ${meta.communities.toLocaleString()} communities; node size = member count.
|
|
193
|
+
Use <code style="background:rgba(255,255,255,0.18);padding:1px 5px;border-radius:3px;">npx vyuh-dxkit explore</code> to drill into a specific community.
|
|
194
|
+
</div>`;
|
|
195
|
+
// Inject right after <body> so the banner sits above the canvas
|
|
196
|
+
// without disturbing graphify's existing flex layout.
|
|
197
|
+
const bodyIdx = html.indexOf('<body');
|
|
198
|
+
if (bodyIdx === -1)
|
|
199
|
+
return html;
|
|
200
|
+
const tagEnd = html.indexOf('>', bodyIdx);
|
|
201
|
+
if (tagEnd === -1)
|
|
202
|
+
return html;
|
|
203
|
+
return html.slice(0, tagEnd + 1) + banner + html.slice(tagEnd + 1);
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Replace graphify's `<script src="https://unpkg.com/vis-network/...">`
|
|
207
|
+
* with an inline `<script>` containing the bundled vis-network source.
|
|
208
|
+
* The replacement is conservative — we match the upstream tag exactly
|
|
209
|
+
* (with optional version pin + path variations) and bail to the
|
|
210
|
+
* untouched HTML if the pattern doesn't fit. That way an upstream
|
|
211
|
+
* graphify change to a different CDN URL is surfaced as "viewer works
|
|
212
|
+
* online only" rather than a corrupt swap.
|
|
213
|
+
*
|
|
214
|
+
* Exported for tests; downstream consumers should use `renderGraphTab`.
|
|
215
|
+
*/
|
|
216
|
+
function inlineVisNetwork(upstreamHtml, visBundle) {
|
|
217
|
+
// Conservative match for the upstream HTML's
|
|
218
|
+
// `<script ... src="...vis-network...">` tag. Inline-script body is
|
|
219
|
+
// JS, so a `<` inside the bundle would close the surrounding
|
|
220
|
+
// <script> tag prematurely if we naively concatenated —
|
|
221
|
+
// vis-network's minified UMD doesn't contain `</script>` substrings,
|
|
222
|
+
// but defensively escape just in case.
|
|
223
|
+
const safeBundle = visBundle.replace(/<\/script>/gi, '<\\/script>');
|
|
224
|
+
const inline = `<script>${safeBundle}</script>`;
|
|
225
|
+
const pattern = /<script\b[^>]*\bsrc=(["'])[^"']*vis-network[^"']*\1[^>]*><\/script>/i;
|
|
226
|
+
if (!pattern.test(upstreamHtml)) {
|
|
227
|
+
// No CDN script to swap. Return upstream verbatim — graphify either
|
|
228
|
+
// already bundles vis-network or the upstream format changed; in
|
|
229
|
+
// either case our offline-conversion is a no-op rather than a corruption.
|
|
230
|
+
return upstreamHtml;
|
|
231
|
+
}
|
|
232
|
+
// Use a function-form replacement so $1/$&/$' inside the bundle source
|
|
233
|
+
// are not interpreted as `replace`'s magic backreferences. vis-network's
|
|
234
|
+
// minified UMD contains `"$1"` (a regex capture-group reference inside
|
|
235
|
+
// a string literal); a bare string replacement would silently eat it
|
|
236
|
+
// and corrupt the bundle.
|
|
237
|
+
return upstreamHtml.replace(pattern, () => inline);
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* HTML-encode the supplied HTML so it can sit safely inside an
|
|
241
|
+
* `<iframe srcdoc="…">` attribute. Only the characters that
|
|
242
|
+
* specifically break the attribute boundary — `&`, `"`, and `<` — get
|
|
243
|
+
* escaped. (`<` would prematurely close the iframe's start tag in the
|
|
244
|
+
* outer document if naive UTF-8 left it unescaped.)
|
|
245
|
+
*/
|
|
246
|
+
function encodeForSrcdoc(html) {
|
|
247
|
+
return html.replace(/&/g, '&').replace(/"/g, '"').replace(/</g, '<');
|
|
248
|
+
}
|
|
249
|
+
function buildSrcdocIframe(html) {
|
|
250
|
+
const encoded = encodeForSrcdoc(html);
|
|
251
|
+
return `<iframe
|
|
252
|
+
id="graph-iframe"
|
|
253
|
+
class="graph-iframe"
|
|
254
|
+
title="Code graph — interactive viewer"
|
|
255
|
+
loading="lazy"
|
|
256
|
+
sandbox="allow-scripts allow-same-origin"
|
|
257
|
+
srcdoc="${encoded}"
|
|
258
|
+
></iframe>`;
|
|
259
|
+
}
|
|
260
|
+
// ─── Empty-state rendering ───────────────────────────────────────────────────
|
|
261
|
+
function emptyStateMessage() {
|
|
262
|
+
return 'Run `npx vyuh-dxkit health .` to generate the repo graph (graphify produces `.dxkit/reports/graph.json` + `graph.html` automatically), then reload this dashboard.';
|
|
263
|
+
}
|
|
264
|
+
function renderEmptyState(headline, body) {
|
|
265
|
+
return `<div id="graph-tab-pane" class="graph-tab-pane graph-tab-empty" style="display:none">
|
|
266
|
+
<div class="graph-empty-card">
|
|
267
|
+
<div class="graph-empty-icon">🗺️</div>
|
|
268
|
+
<h2>${escapeHtml(headline)}</h2>
|
|
269
|
+
<p>${body}</p>
|
|
270
|
+
</div>
|
|
271
|
+
</div>`;
|
|
272
|
+
}
|
|
273
|
+
function escapeHtml(s) {
|
|
274
|
+
return s
|
|
275
|
+
.replace(/&/g, '&')
|
|
276
|
+
.replace(/</g, '<')
|
|
277
|
+
.replace(/>/g, '>')
|
|
278
|
+
.replace(/"/g, '"');
|
|
279
|
+
}
|
|
280
|
+
// ─── Embedded CSS (spliced into the host dashboard's style block) ────────────
|
|
281
|
+
/**
|
|
282
|
+
* CSS for the graph tab. The host dashboard at
|
|
283
|
+
* `src/analyzers/dashboard/index.ts` splices this into its global
|
|
284
|
+
* `<style>` block via a sibling import. The iframe gets a fixed-height
|
|
285
|
+
* fill of the tab area; the empty-state card centers vertically.
|
|
286
|
+
*/
|
|
287
|
+
exports.GRAPH_TAB_CSS = `
|
|
288
|
+
.graph-tab-pane { flex: 1; flex-direction: column; padding: 24px 28px; overflow: hidden; }
|
|
289
|
+
.graph-tab-empty.graph-tab-pane { display: flex; align-items: center; justify-content: center; min-height: 400px; padding: 60px 32px; }
|
|
290
|
+
.graph-empty-card { text-align: center; padding: 48px 32px; background: var(--bg-card); border-radius: 12px; border: 1px solid var(--border); max-width: 640px; }
|
|
291
|
+
.graph-empty-icon { font-size: 56px; margin-bottom: 16px; }
|
|
292
|
+
.graph-empty-card h2 { font-size: 22px; color: var(--text-primary); margin-bottom: 12px; }
|
|
293
|
+
.graph-empty-card p { color: var(--text-secondary); line-height: 1.55; }
|
|
294
|
+
.graph-empty-card code { background: var(--bg-tertiary); padding: 2px 6px; border-radius: 4px; font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 0.92em; }
|
|
295
|
+
.graph-iframe { width: 100%; height: 100%; min-height: 600px; border: 1px solid var(--border); border-radius: 10px; background: var(--bg-primary); }
|
|
296
|
+
`;
|
|
297
|
+
//# sourceMappingURL=graph-tab.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph-tab.js","sourceRoot":"","sources":["../../src/dashboard/graph-tab.ts"],"names":[],"mappings":"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"}
|