@monoes/monomindcli 1.6.4 → 1.6.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.
Files changed (116) hide show
  1. package/.claude/helpers/graphify-freshen.cjs +10 -1
  2. package/bundled-graph/dist/src/analyze.d.ts +32 -0
  3. package/bundled-graph/dist/src/analyze.d.ts.map +1 -0
  4. package/bundled-graph/dist/src/analyze.js +297 -0
  5. package/bundled-graph/dist/src/analyze.js.map +1 -0
  6. package/bundled-graph/dist/src/build.d.ts +8 -0
  7. package/bundled-graph/dist/src/build.d.ts.map +1 -0
  8. package/bundled-graph/dist/src/build.js +73 -0
  9. package/bundled-graph/dist/src/build.js.map +1 -0
  10. package/bundled-graph/dist/src/cache.d.ts +12 -0
  11. package/bundled-graph/dist/src/cache.d.ts.map +1 -0
  12. package/bundled-graph/dist/src/cache.js +43 -0
  13. package/bundled-graph/dist/src/cache.js.map +1 -0
  14. package/bundled-graph/dist/src/cluster.d.ts +5 -0
  15. package/bundled-graph/dist/src/cluster.d.ts.map +1 -0
  16. package/bundled-graph/dist/src/cluster.js +120 -0
  17. package/bundled-graph/dist/src/cluster.js.map +1 -0
  18. package/bundled-graph/dist/src/detect.d.ts +21 -0
  19. package/bundled-graph/dist/src/detect.d.ts.map +1 -0
  20. package/bundled-graph/dist/src/detect.js +195 -0
  21. package/bundled-graph/dist/src/detect.js.map +1 -0
  22. package/bundled-graph/dist/src/export.d.ts +21 -0
  23. package/bundled-graph/dist/src/export.d.ts.map +1 -0
  24. package/bundled-graph/dist/src/export.js +68 -0
  25. package/bundled-graph/dist/src/export.js.map +1 -0
  26. package/bundled-graph/dist/src/extract/index.d.ts +20 -0
  27. package/bundled-graph/dist/src/extract/index.d.ts.map +1 -0
  28. package/bundled-graph/dist/src/extract/index.js +158 -0
  29. package/bundled-graph/dist/src/extract/index.js.map +1 -0
  30. package/bundled-graph/dist/src/extract/languages/c.d.ts +3 -0
  31. package/bundled-graph/dist/src/extract/languages/c.d.ts.map +1 -0
  32. package/bundled-graph/dist/src/extract/languages/c.js +88 -0
  33. package/bundled-graph/dist/src/extract/languages/c.js.map +1 -0
  34. package/bundled-graph/dist/src/extract/languages/cpp.d.ts +3 -0
  35. package/bundled-graph/dist/src/extract/languages/cpp.d.ts.map +1 -0
  36. package/bundled-graph/dist/src/extract/languages/cpp.js +121 -0
  37. package/bundled-graph/dist/src/extract/languages/cpp.js.map +1 -0
  38. package/bundled-graph/dist/src/extract/languages/csharp.d.ts +3 -0
  39. package/bundled-graph/dist/src/extract/languages/csharp.d.ts.map +1 -0
  40. package/bundled-graph/dist/src/extract/languages/csharp.js +121 -0
  41. package/bundled-graph/dist/src/extract/languages/csharp.js.map +1 -0
  42. package/bundled-graph/dist/src/extract/languages/go.d.ts +3 -0
  43. package/bundled-graph/dist/src/extract/languages/go.d.ts.map +1 -0
  44. package/bundled-graph/dist/src/extract/languages/go.js +181 -0
  45. package/bundled-graph/dist/src/extract/languages/go.js.map +1 -0
  46. package/bundled-graph/dist/src/extract/languages/java.d.ts +3 -0
  47. package/bundled-graph/dist/src/extract/languages/java.d.ts.map +1 -0
  48. package/bundled-graph/dist/src/extract/languages/java.js +117 -0
  49. package/bundled-graph/dist/src/extract/languages/java.js.map +1 -0
  50. package/bundled-graph/dist/src/extract/languages/kotlin.d.ts +3 -0
  51. package/bundled-graph/dist/src/extract/languages/kotlin.d.ts.map +1 -0
  52. package/bundled-graph/dist/src/extract/languages/kotlin.js +112 -0
  53. package/bundled-graph/dist/src/extract/languages/kotlin.js.map +1 -0
  54. package/bundled-graph/dist/src/extract/languages/php.d.ts +3 -0
  55. package/bundled-graph/dist/src/extract/languages/php.d.ts.map +1 -0
  56. package/bundled-graph/dist/src/extract/languages/php.js +130 -0
  57. package/bundled-graph/dist/src/extract/languages/php.js.map +1 -0
  58. package/bundled-graph/dist/src/extract/languages/python.d.ts +3 -0
  59. package/bundled-graph/dist/src/extract/languages/python.d.ts.map +1 -0
  60. package/bundled-graph/dist/src/extract/languages/python.js +230 -0
  61. package/bundled-graph/dist/src/extract/languages/python.js.map +1 -0
  62. package/bundled-graph/dist/src/extract/languages/ruby.d.ts +3 -0
  63. package/bundled-graph/dist/src/extract/languages/ruby.d.ts.map +1 -0
  64. package/bundled-graph/dist/src/extract/languages/ruby.js +120 -0
  65. package/bundled-graph/dist/src/extract/languages/ruby.js.map +1 -0
  66. package/bundled-graph/dist/src/extract/languages/rust.d.ts +3 -0
  67. package/bundled-graph/dist/src/extract/languages/rust.d.ts.map +1 -0
  68. package/bundled-graph/dist/src/extract/languages/rust.js +195 -0
  69. package/bundled-graph/dist/src/extract/languages/rust.js.map +1 -0
  70. package/bundled-graph/dist/src/extract/languages/scala.d.ts +3 -0
  71. package/bundled-graph/dist/src/extract/languages/scala.d.ts.map +1 -0
  72. package/bundled-graph/dist/src/extract/languages/scala.js +110 -0
  73. package/bundled-graph/dist/src/extract/languages/scala.js.map +1 -0
  74. package/bundled-graph/dist/src/extract/languages/swift.d.ts +3 -0
  75. package/bundled-graph/dist/src/extract/languages/swift.d.ts.map +1 -0
  76. package/bundled-graph/dist/src/extract/languages/swift.js +122 -0
  77. package/bundled-graph/dist/src/extract/languages/swift.js.map +1 -0
  78. package/bundled-graph/dist/src/extract/languages/typescript.d.ts +3 -0
  79. package/bundled-graph/dist/src/extract/languages/typescript.d.ts.map +1 -0
  80. package/bundled-graph/dist/src/extract/languages/typescript.js +295 -0
  81. package/bundled-graph/dist/src/extract/languages/typescript.js.map +1 -0
  82. package/bundled-graph/dist/src/extract/semantic.d.ts +38 -0
  83. package/bundled-graph/dist/src/extract/semantic.d.ts.map +1 -0
  84. package/bundled-graph/dist/src/extract/semantic.js +242 -0
  85. package/bundled-graph/dist/src/extract/semantic.js.map +1 -0
  86. package/bundled-graph/dist/src/extract/tree-sitter-runner.d.ts +48 -0
  87. package/bundled-graph/dist/src/extract/tree-sitter-runner.d.ts.map +1 -0
  88. package/bundled-graph/dist/src/extract/tree-sitter-runner.js +137 -0
  89. package/bundled-graph/dist/src/extract/tree-sitter-runner.js.map +1 -0
  90. package/bundled-graph/dist/src/extract/types.d.ts +7 -0
  91. package/bundled-graph/dist/src/extract/types.d.ts.map +1 -0
  92. package/bundled-graph/dist/src/extract/types.js +2 -0
  93. package/bundled-graph/dist/src/extract/types.js.map +1 -0
  94. package/bundled-graph/dist/src/index.d.ts +28 -0
  95. package/bundled-graph/dist/src/index.d.ts.map +1 -0
  96. package/bundled-graph/dist/src/index.js +26 -0
  97. package/bundled-graph/dist/src/index.js.map +1 -0
  98. package/bundled-graph/dist/src/pipeline.d.ts +27 -0
  99. package/bundled-graph/dist/src/pipeline.d.ts.map +1 -0
  100. package/bundled-graph/dist/src/pipeline.js +269 -0
  101. package/bundled-graph/dist/src/pipeline.js.map +1 -0
  102. package/bundled-graph/dist/src/report.d.ts +26 -0
  103. package/bundled-graph/dist/src/report.d.ts.map +1 -0
  104. package/bundled-graph/dist/src/report.js +214 -0
  105. package/bundled-graph/dist/src/report.js.map +1 -0
  106. package/bundled-graph/dist/src/types.d.ts +124 -0
  107. package/bundled-graph/dist/src/types.d.ts.map +1 -0
  108. package/bundled-graph/dist/src/types.js +2 -0
  109. package/bundled-graph/dist/src/types.js.map +1 -0
  110. package/bundled-graph/dist/src/visualize.d.ts +4 -0
  111. package/bundled-graph/dist/src/visualize.d.ts.map +1 -0
  112. package/bundled-graph/dist/src/visualize.js +574 -0
  113. package/bundled-graph/dist/src/visualize.js.map +1 -0
  114. package/bundled-graph/dist/tsconfig.tsbuildinfo +1 -0
  115. package/bundled-graph/package.json +57 -0
  116. package/package.json +9 -2
@@ -0,0 +1,574 @@
1
+ import { writeFileSync } from 'fs';
2
+ import { join } from 'path';
3
+ const PALETTE = [
4
+ '#4E79A7', '#F28E2B', '#E15759', '#76B7B2', '#59A14F',
5
+ '#EDC948', '#B07AA1', '#FF9DA7', '#9C755F', '#BAB0AC',
6
+ '#6366f1', '#f59e0b', '#10b981', '#ef4444', '#3b82f6',
7
+ '#8b5cf6', '#ec4899', '#14b8a6', '#f97316', '#06b6d4',
8
+ '#a3e635', '#fb923c', '#e879f9', '#34d399', '#60a5fa',
9
+ ];
10
+ const MAX_VISUAL_NODES = 2000;
11
+ function esc(s) {
12
+ return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#39;');
13
+ }
14
+ function jsSafe(obj) {
15
+ return JSON.stringify(obj).replace(/<\//g, '<\\/');
16
+ }
17
+ /** Export a rich, self-contained HTML knowledge graph explorer using vis-network. */
18
+ export function exportHTML(serialized, outputDir) {
19
+ const htmlPath = join(outputDir, 'graph.html');
20
+ const totalNodes = serialized.nodes.length;
21
+ const totalEdges = serialized.links.length;
22
+ const projectName = serialized.projectPath.split('/').filter(Boolean).pop() ?? serialized.projectPath;
23
+ // Compute degree
24
+ const degMap = {};
25
+ for (const l of serialized.links) {
26
+ degMap[l.source] = (degMap[l.source] ?? 0) + 1;
27
+ degMap[l.target] = (degMap[l.target] ?? 0) + 1;
28
+ }
29
+ // Sample if too large
30
+ let vizNodes = serialized.nodes;
31
+ let vizLinks = serialized.links;
32
+ const sampled = totalNodes > MAX_VISUAL_NODES;
33
+ if (sampled) {
34
+ const sorted = [...serialized.nodes].sort((a, b) => (degMap[b.id] ?? 0) - (degMap[a.id] ?? 0));
35
+ vizNodes = sorted.slice(0, MAX_VISUAL_NODES);
36
+ const kept = new Set(vizNodes.map(n => n.id));
37
+ vizLinks = serialized.links.filter(l => kept.has(l.source) && kept.has(l.target));
38
+ }
39
+ const nodeCount = vizNodes.length;
40
+ const edgeCount = vizLinks.length;
41
+ // Rebuild degree for sampled graph
42
+ const deg = {};
43
+ for (const l of vizLinks) {
44
+ deg[l.source] = (deg[l.source] ?? 0) + 1;
45
+ deg[l.target] = (deg[l.target] ?? 0) + 1;
46
+ }
47
+ const maxDeg = Math.max(1, ...Object.values(deg));
48
+ // Community map
49
+ const communityNodes = {};
50
+ for (const n of vizNodes) {
51
+ const c = n['community'] ?? -1;
52
+ communityNodes[c] = (communityNodes[c] ?? 0) + 1;
53
+ }
54
+ const communityIds = Object.keys(communityNodes).map(Number).sort((a, b) => (communityNodes[b] ?? 0) - (communityNodes[a] ?? 0));
55
+ // Relation types
56
+ const relCounts = {};
57
+ for (const l of vizLinks) {
58
+ const r = String(l['relation'] ?? 'ref');
59
+ relCounts[r] = (relCounts[r] ?? 0) + 1;
60
+ }
61
+ const relTypes = Object.entries(relCounts).sort((a, b) => b[1] - a[1]);
62
+ // God nodes — top 25 by degree
63
+ const godNodes = [...vizNodes]
64
+ .sort((a, b) => (deg[b.id] ?? 0) - (deg[a.id] ?? 0))
65
+ .slice(0, 25)
66
+ .map(n => ({
67
+ id: n.id,
68
+ label: n['label'] || n.id,
69
+ degree: deg[n.id] ?? 0,
70
+ community: n['community'] ?? -1,
71
+ }));
72
+ // Build vis.js nodes
73
+ const visNodes = vizNodes.map(n => {
74
+ const attrs = n;
75
+ const cid = attrs['community'] ?? -1;
76
+ const color = cid >= 0 ? PALETTE[cid % PALETTE.length] : '#64748b';
77
+ const label = attrs['label'] || n.id;
78
+ const d = deg[n.id] ?? 0;
79
+ const size = 10 + 30 * (d / maxDeg);
80
+ const fontSize = d >= maxDeg * 0.1 ? 12 : 0;
81
+ return {
82
+ id: n.id, label: esc(label),
83
+ color: { background: color, border: color, highlight: { background: '#ffffff', border: color } },
84
+ size: Math.round(size * 10) / 10,
85
+ font: { size: fontSize, color: '#ffffff' },
86
+ title: esc(label), community: cid,
87
+ community_name: `Community ${cid}`,
88
+ source_file: esc(String(attrs['source_file'] ?? attrs['sourceFile'] ?? '')),
89
+ file_type: String(attrs['file_type'] ?? attrs['fileType'] ?? 'code'),
90
+ degree: d,
91
+ };
92
+ });
93
+ // Build vis.js edges
94
+ const visEdges = vizLinks.map(l => {
95
+ const attrs = l;
96
+ const confidence = String(attrs['confidence'] ?? 'EXTRACTED');
97
+ const relation = String(attrs['relation'] ?? 'ref');
98
+ return {
99
+ from: l.source, to: l.target, relation,
100
+ title: esc(`${relation} [${confidence}]`),
101
+ dashes: confidence !== 'EXTRACTED',
102
+ width: confidence === 'EXTRACTED' ? 2 : 1,
103
+ color: { opacity: confidence === 'EXTRACTED' ? 0.7 : 0.35 },
104
+ };
105
+ });
106
+ // Legend data
107
+ const legendData = communityIds.map(cid => ({
108
+ cid, color: cid >= 0 ? PALETTE[cid % PALETTE.length] : '#64748b',
109
+ label: `Community ${cid}`, count: communityNodes[cid] ?? 0,
110
+ }));
111
+ const sampledNote = sampled ? ` (top ${MAX_VISUAL_NODES} of ${totalNodes})` : '';
112
+ const html = `<!DOCTYPE html>
113
+ <html lang="en">
114
+ <head>
115
+ <meta charset="UTF-8">
116
+ <title>Knowledge Graph — ${esc(projectName)}</title>
117
+ <script src="https://unpkg.com/vis-network/standalone/umd/vis-network.min.js"><\/script>
118
+ <style>
119
+ *{box-sizing:border-box;margin:0;padding:0}
120
+ :root{--bg:#0f0f1a;--bg2:#1a1a2e;--bg3:#242446;--border:#2a2a4e;--text:#e0e0e0;--muted:#888;--dim:#555;--accent:#4E79A7}
121
+ body{background:var(--bg);color:var(--text);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;height:100vh;overflow:hidden}
122
+
123
+ /* Layout */
124
+ #app{display:flex;height:100vh}
125
+ #graph-area{flex:1;position:relative;overflow:hidden}
126
+ #graph{width:100%;height:100%}
127
+ #sidebar{width:320px;background:var(--bg2);border-left:1px solid var(--border);display:flex;flex-direction:column;overflow:hidden;flex-shrink:0}
128
+
129
+ /* Loading overlay */
130
+ #loading{position:absolute;top:0;left:0;right:0;bottom:0;background:rgba(15,15,26,.92);display:flex;flex-direction:column;align-items:center;justify-content:center;z-index:100;transition:opacity .5s}
131
+ #loading.hidden{opacity:0;pointer-events:none}
132
+ #loading h2{color:var(--accent);font-size:16px;margin-bottom:12px}
133
+ #load-bar{width:240px;height:4px;background:#1a1a2e;border-radius:4px;overflow:hidden}
134
+ #load-fill{height:100%;background:var(--accent);width:0%;transition:width .3s}
135
+ #load-text{margin-top:8px;font-size:12px;color:var(--muted)}
136
+
137
+ /* Top bar */
138
+ #topbar{position:absolute;top:0;left:0;right:0;height:42px;background:rgba(26,26,46,.88);backdrop-filter:blur(8px);border-bottom:1px solid var(--border);display:flex;align-items:center;padding:0 14px;gap:10px;z-index:10}
139
+ #topbar .title{font-size:13px;font-weight:700;color:#f1f5f9}
140
+ #topbar .title span{color:var(--accent)}
141
+ .pill{background:var(--bg);border:1px solid var(--border);border-radius:999px;padding:2px 10px;font-size:11px;color:var(--muted)}
142
+ .pill b{color:#c7d2fe}
143
+ .pill.warn{color:#f59e0b;border-color:#f59e0b44}
144
+ #topbar .spacer{flex:1}
145
+ .tbtn{background:var(--bg3);border:1px solid var(--border);color:var(--text);border-radius:6px;padding:4px 10px;font-size:11px;cursor:pointer;white-space:nowrap;transition:.15s}
146
+ .tbtn:hover{background:#2f2f5a}
147
+ .tbtn.active{background:var(--accent);border-color:var(--accent);color:#fff}
148
+
149
+ /* Sidebar: tabs */
150
+ #tabs{display:flex;border-bottom:1px solid var(--border);flex-shrink:0}
151
+ .tab{flex:1;padding:10px 4px;font-size:11px;text-align:center;cursor:pointer;color:var(--muted);border-bottom:2px solid transparent;transition:.15s;text-transform:uppercase;letter-spacing:.04em}
152
+ .tab:hover{color:var(--text)}
153
+ .tab.active{color:var(--accent);border-bottom-color:var(--accent)}
154
+ .tab-panel{display:none;flex:1;overflow-y:auto;padding:14px}
155
+ .tab-panel.active{display:block}
156
+
157
+ /* Search */
158
+ #search-box{padding:10px 14px;border-bottom:1px solid var(--border);flex-shrink:0}
159
+ #search{width:100%;background:var(--bg);border:1px solid #3a3a5e;color:var(--text);padding:7px 10px 7px 32px;border-radius:6px;font-size:13px;outline:none}
160
+ #search:focus{border-color:var(--accent)}
161
+ #search-box{position:relative}
162
+ #search-icon{position:absolute;left:24px;top:50%;transform:translateY(-50%);color:var(--muted);pointer-events:none;font-size:14px}
163
+ #search-results{max-height:200px;overflow-y:auto;margin-top:6px;display:none}
164
+ .sr-item{display:flex;align-items:center;gap:8px;padding:5px 8px;cursor:pointer;border-radius:5px;font-size:12px}
165
+ .sr-item:hover{background:var(--bg3)}
166
+ .sr-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}
167
+ .sr-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
168
+ .sr-deg{color:var(--dim);font-size:10px;flex-shrink:0}
169
+
170
+ /* Node card */
171
+ #node-card{display:none}
172
+ .nc-label{font-size:14px;font-weight:600;color:#f1f5f9;margin-bottom:10px;word-break:break-all}
173
+ .nc-row{display:flex;justify-content:space-between;padding:4px 0;border-bottom:1px solid var(--border);font-size:12px}
174
+ .nc-row:last-child{border:none}
175
+ .nk{color:var(--muted)}.nv{color:#c7d2fe;text-align:right;max-width:170px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
176
+ .nbr-title{margin-top:12px;font-size:11px;color:var(--muted);text-transform:uppercase;letter-spacing:.05em}
177
+ #neighbors-list{max-height:220px;overflow-y:auto;margin-top:4px}
178
+ .nbr-item{display:flex;align-items:center;gap:6px;padding:4px 6px;border-radius:5px;cursor:pointer;font-size:12px}
179
+ .nbr-item:hover{background:var(--bg3)}
180
+ .nbr-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}
181
+ .nbr-lbl{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
182
+ .nbr-rel{color:var(--muted);font-size:10px;flex-shrink:0}
183
+
184
+ /* Overview stats */
185
+ .stat-grid{display:grid;grid-template-columns:1fr 1fr;gap:6px;margin-bottom:14px}
186
+ .stat-box{background:var(--bg);border:1px solid var(--border);border-radius:8px;padding:10px;text-align:center}
187
+ .sv{font-size:20px;font-weight:700;color:#f1f5f9}.sk{font-size:10px;color:var(--muted);margin-top:2px}
188
+ .section{margin-bottom:16px}
189
+ .sec-title{font-size:11px;font-weight:600;color:var(--muted);text-transform:uppercase;letter-spacing:.05em;margin-bottom:8px}
190
+
191
+ /* Community / Legend */
192
+ .com-row{display:flex;align-items:center;gap:8px;padding:5px 6px;cursor:pointer;border-radius:5px;font-size:12px;transition:.15s}
193
+ .com-row:hover{background:var(--bg3)}
194
+ .com-row.dimmed{opacity:.25}
195
+ .com-dot{width:10px;height:10px;border-radius:50%;flex-shrink:0}
196
+ .com-name{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
197
+ .com-count{color:var(--dim);font-size:11px}
198
+
199
+ /* God nodes */
200
+ .god-item{display:flex;align-items:center;gap:8px;padding:5px 6px;cursor:pointer;border-radius:5px;font-size:12px;transition:.15s}
201
+ .god-item:hover{background:var(--bg3)}
202
+ .god-rank{width:20px;text-align:right;color:var(--muted);font-size:11px;flex-shrink:0}
203
+ .god-dot{width:10px;height:10px;border-radius:50%;flex-shrink:0}
204
+ .god-lbl{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
205
+ .god-deg{font-size:11px;color:var(--muted);flex-shrink:0}
206
+
207
+ /* Relation legend */
208
+ .rel-row{display:flex;align-items:center;gap:8px;padding:3px 0;font-size:12px}
209
+ .rel-line{width:20px;height:2px;border-radius:2px;flex-shrink:0;background:var(--muted)}
210
+ .rel-count{color:var(--dim);font-size:10px;margin-left:auto}
211
+
212
+ /* Path finder */
213
+ #pathfinder{margin-top:12px;padding-top:12px;border-top:1px solid var(--border)}
214
+ #pathfinder input{width:100%;background:var(--bg);border:1px solid #3a3a5e;color:var(--text);padding:6px 10px;border-radius:5px;font-size:12px;outline:none;margin-bottom:6px}
215
+ #pathfinder input:focus{border-color:var(--accent)}
216
+ #path-btn{width:100%;background:var(--accent);border:none;color:#fff;padding:7px;border-radius:5px;font-size:12px;cursor:pointer;transition:.15s}
217
+ #path-btn:hover{opacity:.85}
218
+ #path-result{margin-top:8px;font-size:12px;color:var(--muted);line-height:1.5}
219
+
220
+ /* Bottom controls */
221
+ #floatctrl{position:absolute;bottom:12px;left:12px;display:flex;gap:5px;z-index:10}
222
+ .fc{background:rgba(36,36,70,.85);backdrop-filter:blur(6px);border:1px solid var(--border);color:var(--text);border-radius:6px;padding:5px 10px;font-size:11px;cursor:pointer;transition:.15s}
223
+ .fc:hover{background:rgba(47,47,90,.9)}
224
+
225
+ /* Keyboard hints */
226
+ #kbd-hint{position:absolute;bottom:12px;right:332px;font-size:10px;color:#444;z-index:10}
227
+ kbd{background:var(--bg3);border:1px solid var(--border);border-radius:3px;padding:1px 5px;font-size:10px;color:var(--muted)}
228
+ </style>
229
+ </head>
230
+ <body>
231
+ <div id="app">
232
+ <div id="graph-area">
233
+ <div id="graph"></div>
234
+
235
+ <!-- Loading overlay -->
236
+ <div id="loading">
237
+ <h2>Stabilizing graph layout…</h2>
238
+ <div id="load-bar"><div id="load-fill"></div></div>
239
+ <div id="load-text">0%</div>
240
+ </div>
241
+
242
+ <!-- Top bar -->
243
+ <div id="topbar">
244
+ <div class="title"><span>monomind</span> graph</div>
245
+ <div class="pill"><b>${nodeCount}</b> nodes${sampled ? ` <span style="color:#f59e0b" title="Sampled top ${MAX_VISUAL_NODES} of ${totalNodes} by degree">▲</span>` : ''}</div>
246
+ <div class="pill"><b>${edgeCount}</b> edges</div>
247
+ <div class="pill"><b>${communityIds.length}</b> groups</div>
248
+ ${sampled ? `<div class="pill warn" title="Showing top ${MAX_VISUAL_NODES} of ${totalNodes} total nodes by connection count">sampled</div>` : ''}
249
+ <div class="spacer"></div>
250
+ <button class="tbtn" id="btn-labels" title="Toggle all labels (L)">Labels</button>
251
+ <button class="tbtn" id="btn-physics" title="Toggle physics (P)">Physics</button>
252
+ <button class="tbtn" id="btn-screenshot" title="Download PNG (S)">PNG</button>
253
+ </div>
254
+
255
+ <!-- Float controls -->
256
+ <div id="floatctrl">
257
+ <button class="fc" id="btn-fit" title="Fit to screen (F)">Fit</button>
258
+ <button class="fc" id="btn-zoom-in">+</button>
259
+ <button class="fc" id="btn-zoom-out">−</button>
260
+ </div>
261
+ <div id="kbd-hint"><kbd>/</kbd> search &nbsp; <kbd>F</kbd> fit &nbsp; <kbd>L</kbd> labels &nbsp; <kbd>P</kbd> physics &nbsp; <kbd>S</kbd> png &nbsp; <kbd>Esc</kbd> deselect</div>
262
+ </div>
263
+
264
+ <div id="sidebar">
265
+ <div id="search-box">
266
+ <span id="search-icon">⌕</span>
267
+ <input id="search" type="text" placeholder="Search nodes…" autocomplete="off">
268
+ <div id="search-results"></div>
269
+ </div>
270
+
271
+ <div id="tabs">
272
+ <div class="tab active" data-tab="overview">Overview</div>
273
+ <div class="tab" data-tab="node">Node</div>
274
+ <div class="tab" data-tab="groups">Groups</div>
275
+ <div class="tab" data-tab="gods">Top Nodes</div>
276
+ </div>
277
+
278
+ <!-- Overview tab -->
279
+ <div class="tab-panel active" id="panel-overview">
280
+ <div class="stat-grid">
281
+ <div class="stat-box"><div class="sv">${nodeCount}</div><div class="sk">Nodes${sampled ? ' (sampled)' : ''}</div></div>
282
+ <div class="stat-box"><div class="sv">${edgeCount}</div><div class="sk">Edges</div></div>
283
+ <div class="stat-box"><div class="sv">${communityIds.length}</div><div class="sk">Communities</div></div>
284
+ <div class="stat-box"><div class="sv">${maxDeg}</div><div class="sk">Max Degree</div></div>
285
+ </div>
286
+ <div class="section">
287
+ <div class="sec-title">Edge Types</div>
288
+ ${relTypes.map(([r, c]) => `<div class="rel-row"><div class="rel-line"></div><span>${esc(r)}</span><span class="rel-count">${c}</span></div>`).join('\n ')}
289
+ </div>
290
+ <div class="section">
291
+ <div class="sec-title">Node Sizes</div>
292
+ <div style="font-size:12px;color:var(--muted);line-height:1.6">Larger nodes = more connections. Top hub has ${maxDeg} edges. Labels auto-show for high-degree nodes.</div>
293
+ </div>
294
+ <div id="pathfinder">
295
+ <div class="sec-title">Find Path</div>
296
+ <input id="path-from" type="text" placeholder="From node…" autocomplete="off">
297
+ <input id="path-to" type="text" placeholder="To node…" autocomplete="off">
298
+ <button id="path-btn">Find shortest path</button>
299
+ <div id="path-result"></div>
300
+ </div>
301
+ </div>
302
+
303
+ <!-- Node tab -->
304
+ <div class="tab-panel" id="panel-node">
305
+ <div id="node-card">
306
+ <div class="nc-label" id="nc-label"></div>
307
+ <div id="nc-fields"></div>
308
+ <div class="nbr-title">Neighbors (<span id="nbr-count">0</span>)</div>
309
+ <div id="neighbors-list"></div>
310
+ </div>
311
+ <div id="node-empty" style="color:var(--dim);font-size:13px;padding-top:20px;text-align:center">Click a node to inspect it</div>
312
+ </div>
313
+
314
+ <!-- Groups tab -->
315
+ <div class="tab-panel" id="panel-groups">
316
+ <div style="font-size:11px;color:var(--dim);margin-bottom:10px">Click to toggle visibility</div>
317
+ <div id="groups-list"></div>
318
+ </div>
319
+
320
+ <!-- God nodes tab -->
321
+ <div class="tab-panel" id="panel-gods">
322
+ <div style="font-size:11px;color:var(--dim);margin-bottom:10px">Most connected nodes — click to fly</div>
323
+ <div id="gods-list"></div>
324
+ </div>
325
+ </div>
326
+ </div>
327
+
328
+ <script>
329
+ var RAW_NODES = ${jsSafe(visNodes)};
330
+ var RAW_EDGES = ${jsSafe(visEdges)};
331
+ var LEGEND = ${jsSafe(legendData)};
332
+ var GOD_NODES = ${jsSafe(godNodes)};
333
+ var PALETTE = ${jsSafe(PALETTE)};
334
+
335
+ function esc(s){return String(s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');}
336
+
337
+ /* ── Build vis datasets ── */
338
+ var nodesDS = new vis.DataSet(RAW_NODES.map(function(n){return {
339
+ id:n.id, label:n.label, color:n.color, size:n.size,
340
+ font:n.font, title:n.title,
341
+ _community:n.community, _community_name:n.community_name,
342
+ _source_file:n.source_file, _file_type:n.file_type, _degree:n.degree
343
+ }}));
344
+
345
+ var edgesDS = new vis.DataSet(RAW_EDGES.map(function(e,i){return {
346
+ id:i, from:e.from, to:e.to, _relation:e.relation,
347
+ title:e.title, dashes:e.dashes, width:e.width, color:e.color,
348
+ arrows:{to:{enabled:true,scaleFactor:0.5}}
349
+ }}));
350
+
351
+ /* ── Network ── */
352
+ var container = document.getElementById('graph');
353
+ var network = new vis.Network(container, {nodes:nodesDS, edges:edgesDS}, {
354
+ physics: {
355
+ enabled:true,
356
+ solver:'forceAtlas2Based',
357
+ forceAtlas2Based:{gravitationalConstant:-60,centralGravity:0.005,springLength:120,springConstant:0.08,damping:0.4,avoidOverlap:0.8},
358
+ stabilization:{iterations:200,fit:true}
359
+ },
360
+ interaction:{hover:true,tooltipDelay:100,hideEdgesOnDrag:true,navigationButtons:false,keyboard:false},
361
+ nodes:{shape:'dot',borderWidth:1.5},
362
+ edges:{smooth:{type:'continuous',roundness:0.2},selectionWidth:3}
363
+ });
364
+
365
+ /* ── Loading progress ── */
366
+ var loadEl=document.getElementById('loading'), loadFill=document.getElementById('load-fill'), loadText=document.getElementById('load-text');
367
+ network.on('stabilizationProgress',function(p){
368
+ var pct=Math.round(p.iterations/p.total*100);
369
+ loadFill.style.width=pct+'%';
370
+ loadText.textContent=pct+'%';
371
+ });
372
+ network.once('stabilizationIterationsDone',function(){
373
+ loadFill.style.width='100%';loadText.textContent='Done';
374
+ setTimeout(function(){loadEl.classList.add('hidden');},400);
375
+ network.setOptions({physics:{enabled:false}});
376
+ });
377
+
378
+ /* ── State ── */
379
+ var labelsOn=false, physicsOn=false;
380
+ var hiddenCommunities=new Set();
381
+ var selectedNodeId=null;
382
+
383
+ /* ── Tabs ── */
384
+ document.querySelectorAll('.tab').forEach(function(tab){
385
+ tab.addEventListener('click',function(){
386
+ document.querySelectorAll('.tab').forEach(function(t){t.classList.remove('active')});
387
+ document.querySelectorAll('.tab-panel').forEach(function(p){p.classList.remove('active')});
388
+ tab.classList.add('active');
389
+ document.getElementById('panel-'+tab.dataset.tab).classList.add('active');
390
+ });
391
+ });
392
+ function switchTab(name){
393
+ document.querySelectorAll('.tab').forEach(function(t){t.classList.toggle('active',t.dataset.tab===name)});
394
+ document.querySelectorAll('.tab-panel').forEach(function(p){p.classList.toggle('active',p.id==='panel-'+name)});
395
+ }
396
+
397
+ /* ── Node info ── */
398
+ function showInfo(nodeId){
399
+ selectedNodeId=nodeId;
400
+ var n=nodesDS.get(nodeId);if(!n)return;
401
+ switchTab('node');
402
+ document.getElementById('node-card').style.display='block';
403
+ document.getElementById('node-empty').style.display='none';
404
+ document.getElementById('nc-label').textContent=n.label;
405
+ document.getElementById('nc-fields').innerHTML=[
406
+ ['Type',n._file_type||'unknown'],
407
+ ['Community',n._community_name],
408
+ ['Source',n._source_file||'—'],
409
+ ['Degree',n._degree]
410
+ ].map(function(r){return '<div class="nc-row"><span class="nk">'+r[0]+'</span><span class="nv">'+esc(String(r[1]))+'</span></div>';}).join('');
411
+
412
+ var neighborIds=network.getConnectedNodes(nodeId);
413
+ document.getElementById('nbr-count').textContent=neighborIds.length;
414
+ var list=document.getElementById('neighbors-list');list.innerHTML='';
415
+ neighborIds.forEach(function(nid){
416
+ var nb=nodesDS.get(nid);if(!nb)return;
417
+ var color=nb.color.background||'#555';
418
+ // Find edge relation
419
+ var edges=network.getConnectedEdges(nodeId);
420
+ var rel='';
421
+ edges.forEach(function(eid){var e=edgesDS.get(eid);if(e&&(e.from===nid||e.to===nid))rel=e._relation||'';});
422
+ var el=document.createElement('div');el.className='nbr-item';
423
+ el.innerHTML='<div class="nbr-dot" style="background:'+esc(color)+'"></div><span class="nbr-lbl">'+esc(nb.label)+'</span><span class="nbr-rel">'+esc(rel)+'</span>';
424
+ el.onclick=function(){focusNode(nid);};
425
+ list.appendChild(el);
426
+ });
427
+ }
428
+
429
+ function focusNode(nodeId){
430
+ network.focus(nodeId,{scale:1.4,animation:true});
431
+ network.selectNodes([nodeId]);
432
+ showInfo(nodeId);
433
+ }
434
+
435
+ /* ── Click/hover ── */
436
+ var hoveredNodeId=null;
437
+ network.on('hoverNode',function(p){hoveredNodeId=p.node;container.style.cursor='pointer';});
438
+ network.on('blurNode',function(){hoveredNodeId=null;container.style.cursor='default';});
439
+ container.addEventListener('click',function(){
440
+ if(hoveredNodeId!==null){showInfo(hoveredNodeId);network.selectNodes([hoveredNodeId]);}
441
+ });
442
+ network.on('click',function(p){
443
+ if(p.nodes.length>0)showInfo(p.nodes[0]);
444
+ });
445
+ network.on('doubleClick',function(p){
446
+ if(p.nodes.length>0) network.focus(p.nodes[0],{scale:2,animation:true});
447
+ });
448
+
449
+ /* ── Search ── */
450
+ var searchInput=document.getElementById('search');
451
+ var searchResults=document.getElementById('search-results');
452
+ searchInput.addEventListener('input',function(){
453
+ var q=searchInput.value.toLowerCase().trim();
454
+ searchResults.innerHTML='';
455
+ if(!q){searchResults.style.display='none';return;}
456
+ var matches=RAW_NODES.filter(function(n){return n.label.toLowerCase().includes(q);}).slice(0,25);
457
+ if(!matches.length){searchResults.style.display='none';return;}
458
+ searchResults.style.display='block';
459
+ matches.forEach(function(n){
460
+ var el=document.createElement('div');el.className='sr-item';
461
+ el.innerHTML='<div class="sr-dot" style="background:'+n.color.background+'"></div><span class="sr-label">'+esc(n.label)+'</span><span class="sr-deg">'+n.degree+'</span>';
462
+ el.onclick=function(){
463
+ focusNode(n.id);
464
+ searchResults.style.display='none';searchInput.value='';
465
+ };
466
+ searchResults.appendChild(el);
467
+ });
468
+ });
469
+ document.addEventListener('click',function(e){
470
+ if(!searchResults.contains(e.target)&&e.target!==searchInput)searchResults.style.display='none';
471
+ });
472
+
473
+ /* ── Groups / community toggle ── */
474
+ var groupsList=document.getElementById('groups-list');
475
+ LEGEND.forEach(function(c){
476
+ var row=document.createElement('div');row.className='com-row';
477
+ row.innerHTML='<div class="com-dot" style="background:'+c.color+'"></div><span class="com-name">'+esc(c.label)+'</span><span class="com-count">'+c.count+'</span>';
478
+ row.onclick=function(){
479
+ if(hiddenCommunities.has(c.cid)){hiddenCommunities.delete(c.cid);row.classList.remove('dimmed');}
480
+ else{hiddenCommunities.add(c.cid);row.classList.add('dimmed');}
481
+ nodesDS.update(RAW_NODES.filter(function(n){return n.community===c.cid;}).map(function(n){return{id:n.id,hidden:hiddenCommunities.has(c.cid)};}));
482
+ };
483
+ groupsList.appendChild(row);
484
+ });
485
+
486
+ /* ── God nodes ── */
487
+ var godsList=document.getElementById('gods-list');
488
+ GOD_NODES.forEach(function(g,i){
489
+ var c=g.community>=0?PALETTE[g.community%PALETTE.length]:'#64748b';
490
+ var el=document.createElement('div');el.className='god-item';
491
+ el.innerHTML='<span class="god-rank">#'+(i+1)+'</span><div class="god-dot" style="background:'+c+'"></div><span class="god-lbl">'+esc(g.label)+'</span><span class="god-deg">'+g.degree+' edges</span>';
492
+ el.onclick=function(){focusNode(g.id);};
493
+ godsList.appendChild(el);
494
+ });
495
+
496
+ /* ── Path finder (BFS) ── */
497
+ document.getElementById('path-btn').addEventListener('click',function(){
498
+ var fromQ=document.getElementById('path-from').value.toLowerCase().trim();
499
+ var toQ=document.getElementById('path-to').value.toLowerCase().trim();
500
+ var resultEl=document.getElementById('path-result');
501
+ if(!fromQ||!toQ){resultEl.textContent='Enter both node names.';return;}
502
+ var fromN=RAW_NODES.find(function(n){return n.label.toLowerCase().includes(fromQ);});
503
+ var toN=RAW_NODES.find(function(n){return n.label.toLowerCase().includes(toQ);});
504
+ if(!fromN){resultEl.textContent='Source "'+fromQ+'" not found.';return;}
505
+ if(!toN){resultEl.textContent='Target "'+toQ+'" not found.';return;}
506
+
507
+ // BFS
508
+ var adj={};
509
+ RAW_EDGES.forEach(function(e){
510
+ if(!adj[e.from])adj[e.from]=[];adj[e.from].push(e.to);
511
+ if(!adj[e.to])adj[e.to]=[];adj[e.to].push(e.from);
512
+ });
513
+ var visited={};var queue=[[fromN.id]];visited[fromN.id]=true;var found=null;
514
+ while(queue.length>0&&!found){
515
+ var path=queue.shift();var last=path[path.length-1];
516
+ if(last===toN.id){found=path;break;}
517
+ if(path.length>10)continue;
518
+ (adj[last]||[]).forEach(function(nb){
519
+ if(!visited[nb]){visited[nb]=true;queue.push(path.concat(nb));}
520
+ });
521
+ }
522
+ if(!found){resultEl.textContent='No path found (max 10 hops).';return;}
523
+
524
+ // Highlight
525
+ network.selectNodes(found);
526
+ var pathEdgeIds=[];
527
+ for(var i=0;i<found.length-1;i++){
528
+ var a=found[i],b=found[i+1];
529
+ edgesDS.forEach(function(e){if((e.from===a&&e.to===b)||(e.from===b&&e.to===a))pathEdgeIds.push(e.id);});
530
+ }
531
+ network.setSelection({nodes:found,edges:pathEdgeIds});
532
+ network.fit({nodes:found,animation:true});
533
+
534
+ var labels=found.map(function(nid){var n=nodesDS.get(nid);return n?n.label:nid;});
535
+ resultEl.innerHTML='<b>'+found.length+' nodes, '+(found.length-1)+' hops:</b><br>'+labels.map(function(l){return esc(l);}).join(' → ');
536
+ });
537
+
538
+ /* ── Toolbar buttons ── */
539
+ document.getElementById('btn-fit').onclick=function(){network.fit({animation:true});};
540
+ document.getElementById('btn-zoom-in').onclick=function(){var s=network.getScale();network.moveTo({scale:s*1.3,animation:true});};
541
+ document.getElementById('btn-zoom-out').onclick=function(){var s=network.getScale();network.moveTo({scale:s/1.3,animation:true});};
542
+ document.getElementById('btn-labels').onclick=function(){
543
+ labelsOn=!labelsOn;
544
+ this.classList.toggle('active',labelsOn);
545
+ nodesDS.update(RAW_NODES.map(function(n){return{id:n.id,font:{size:labelsOn?11:n.font.size,color:'#ffffff'}};}));
546
+ };
547
+ document.getElementById('btn-physics').onclick=function(){
548
+ physicsOn=!physicsOn;
549
+ this.classList.toggle('active',physicsOn);
550
+ network.setOptions({physics:{enabled:physicsOn}});
551
+ };
552
+ document.getElementById('btn-screenshot').onclick=function(){
553
+ var canvas=container.getElementsByTagName('canvas')[0];
554
+ if(!canvas)return;
555
+ var link=document.createElement('a');link.download='graph.png';link.href=canvas.toDataURL('image/png');link.click();
556
+ };
557
+
558
+ /* ── Keyboard shortcuts ── */
559
+ document.addEventListener('keydown',function(e){
560
+ if(e.target.tagName==='INPUT')return;
561
+ if(e.key==='f'||e.key==='F')network.fit({animation:true});
562
+ if(e.key==='l'||e.key==='L')document.getElementById('btn-labels').click();
563
+ if(e.key==='p'||e.key==='P')document.getElementById('btn-physics').click();
564
+ if(e.key==='s'||e.key==='S')document.getElementById('btn-screenshot').click();
565
+ if(e.key==='/'){{e.preventDefault();searchInput.focus();}}
566
+ if(e.key==='Escape'){network.unselectAll();searchInput.blur();}
567
+ });
568
+ <\/script>
569
+ </body>
570
+ </html>`;
571
+ writeFileSync(htmlPath, html, 'utf-8');
572
+ return htmlPath;
573
+ }
574
+ //# sourceMappingURL=visualize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"visualize.js","sourceRoot":"","sources":["../../src/visualize.ts"],"names":[],"mappings":"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"}