speccore 8.3.349 → 8.3.366
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/.agents/skills/spec-unitize/SKILL.md +5 -1
- package/.agents/skills/spec-verify/SKILL.md +22 -1
- package/dist/cli.js +19 -2
- package/dist/cli.js.map +1 -1
- package/dist/commands/about.d.ts.map +1 -1
- package/dist/commands/about.js +36 -1
- package/dist/commands/about.js.map +1 -1
- package/dist/commands/analyze/add-platform.d.ts +3 -0
- package/dist/commands/analyze/add-platform.d.ts.map +1 -0
- package/dist/commands/analyze/add-platform.js +82 -0
- package/dist/commands/analyze/add-platform.js.map +1 -0
- package/dist/commands/analyze/audit-fix.d.ts +3 -0
- package/dist/commands/analyze/audit-fix.d.ts.map +1 -0
- package/dist/commands/analyze/audit-fix.js +73 -0
- package/dist/commands/analyze/audit-fix.js.map +1 -0
- package/dist/commands/analyze/context-guard.d.ts +3 -0
- package/dist/commands/analyze/context-guard.d.ts.map +1 -0
- package/dist/commands/analyze/context-guard.js +75 -0
- package/dist/commands/analyze/context-guard.js.map +1 -0
- package/dist/commands/analyze/doc.d.ts +3 -0
- package/dist/commands/analyze/doc.d.ts.map +1 -0
- package/dist/commands/analyze/doc.js +77 -0
- package/dist/commands/analyze/doc.js.map +1 -0
- package/dist/commands/analyze/feature.d.ts +3 -0
- package/dist/commands/analyze/feature.d.ts.map +1 -0
- package/dist/commands/analyze/feature.js +75 -0
- package/dist/commands/analyze/feature.js.map +1 -0
- package/dist/commands/analyze/from-code.d.ts +3 -0
- package/dist/commands/analyze/from-code.d.ts.map +1 -0
- package/dist/commands/analyze/from-code.js +94 -0
- package/dist/commands/analyze/from-code.js.map +1 -0
- package/dist/commands/analyze/incremental.d.ts +3 -0
- package/dist/commands/analyze/incremental.d.ts.map +1 -0
- package/dist/commands/analyze/incremental.js +90 -0
- package/dist/commands/analyze/incremental.js.map +1 -0
- package/dist/commands/analyze/modes.d.ts +13 -0
- package/dist/commands/analyze/modes.d.ts.map +1 -0
- package/dist/commands/analyze/modes.js +147 -0
- package/dist/commands/analyze/modes.js.map +1 -0
- package/dist/commands/analyze/module.d.ts +3 -0
- package/dist/commands/analyze/module.d.ts.map +1 -0
- package/dist/commands/analyze/module.js +95 -0
- package/dist/commands/analyze/module.js.map +1 -0
- package/dist/commands/analyze/overview.d.ts +3 -0
- package/dist/commands/analyze/overview.d.ts.map +1 -0
- package/dist/commands/analyze/overview.js +125 -0
- package/dist/commands/analyze/overview.js.map +1 -0
- package/dist/commands/analyze/shared.d.ts +53 -0
- package/dist/commands/analyze/shared.d.ts.map +1 -0
- package/dist/commands/analyze/shared.js +34 -0
- package/dist/commands/analyze/shared.js.map +1 -0
- package/dist/commands/analyze/units.d.ts +46 -0
- package/dist/commands/analyze/units.d.ts.map +1 -0
- package/dist/commands/analyze/units.js +950 -0
- package/dist/commands/analyze/units.js.map +1 -0
- package/dist/commands/analyze.d.ts +6 -88
- package/dist/commands/analyze.d.ts.map +1 -1
- package/dist/commands/analyze.js +167 -1419
- package/dist/commands/analyze.js.map +1 -1
- package/dist/commands/ask.d.ts.map +1 -1
- package/dist/commands/ask.js +4 -2
- package/dist/commands/ask.js.map +1 -1
- package/dist/commands/dashboard.d.ts.map +1 -1
- package/dist/commands/dashboard.js +36 -1
- package/dist/commands/dashboard.js.map +1 -1
- package/dist/commands/deploy.d.ts +6 -0
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +153 -0
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/doc2spec.d.ts +1 -1
- package/dist/commands/doc2spec.d.ts.map +1 -1
- package/dist/commands/doc2spec.js +39 -24
- package/dist/commands/doc2spec.js.map +1 -1
- package/dist/commands/doctor.js +60 -13
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/execute.d.ts.map +1 -1
- package/dist/commands/execute.js +22 -0
- package/dist/commands/execute.js.map +1 -1
- package/dist/commands/help.js +36 -1
- package/dist/commands/help.js.map +1 -1
- package/dist/commands/init.js +1 -1
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/pipeline.d.ts.map +1 -1
- package/dist/commands/pipeline.js +15 -0
- package/dist/commands/pipeline.js.map +1 -1
- package/dist/commands/plan.js +2 -0
- package/dist/commands/plan.js.map +1 -1
- package/dist/commands/pr.d.ts.map +1 -1
- package/dist/commands/pr.js +14 -3
- package/dist/commands/pr.js.map +1 -1
- package/dist/commands/prompts.d.ts +11 -1
- package/dist/commands/prompts.d.ts.map +1 -1
- package/dist/commands/prompts.js +197 -15
- package/dist/commands/prompts.js.map +1 -1
- package/dist/commands/reindex.d.ts.map +1 -1
- package/dist/commands/reindex.js +23 -0
- package/dist/commands/reindex.js.map +1 -1
- package/dist/commands/retro.d.ts.map +1 -1
- package/dist/commands/retro.js +3 -1
- package/dist/commands/retro.js.map +1 -1
- package/dist/commands/status-panel.d.ts.map +1 -1
- package/dist/commands/status-panel.js +9 -1
- package/dist/commands/status-panel.js.map +1 -1
- package/dist/commands/unitize.d.ts +3 -0
- package/dist/commands/unitize.d.ts.map +1 -1
- package/dist/commands/unitize.js +183 -6
- package/dist/commands/unitize.js.map +1 -1
- package/dist/commands/update-env-configs.d.ts.map +1 -1
- package/dist/commands/update-env-configs.js +10 -0
- package/dist/commands/update-env-configs.js.map +1 -1
- package/dist/commands/verify.d.ts +8 -0
- package/dist/commands/verify.d.ts.map +1 -1
- package/dist/commands/verify.js +383 -16
- package/dist/commands/verify.js.map +1 -1
- package/dist/commands/welcome.d.ts.map +1 -1
- package/dist/commands/welcome.js +3 -1
- package/dist/commands/welcome.js.map +1 -1
- package/dist/core/ai-context-generator.d.ts +21 -0
- package/dist/core/ai-context-generator.d.ts.map +1 -1
- package/dist/core/ai-context-generator.js +54 -1
- package/dist/core/ai-context-generator.js.map +1 -1
- package/dist/core/ai-verify/plan-generator.d.ts +94 -0
- package/dist/core/ai-verify/plan-generator.d.ts.map +1 -0
- package/dist/core/ai-verify/plan-generator.js +598 -0
- package/dist/core/ai-verify/plan-generator.js.map +1 -0
- package/dist/core/ai-verify/result-parser.d.ts +27 -0
- package/dist/core/ai-verify/result-parser.d.ts.map +1 -0
- package/dist/core/ai-verify/result-parser.js +212 -0
- package/dist/core/ai-verify/result-parser.js.map +1 -0
- package/dist/core/ai-verify/scope-resolver.d.ts +34 -0
- package/dist/core/ai-verify/scope-resolver.d.ts.map +1 -0
- package/dist/core/ai-verify/scope-resolver.js +183 -0
- package/dist/core/ai-verify/scope-resolver.js.map +1 -0
- package/dist/core/ai-verify/types.d.ts +171 -0
- package/dist/core/ai-verify/types.d.ts.map +1 -0
- package/dist/core/ai-verify/types.js +9 -0
- package/dist/core/ai-verify/types.js.map +1 -0
- package/dist/core/ai-verify/visual-judge.d.ts +33 -0
- package/dist/core/ai-verify/visual-judge.d.ts.map +1 -0
- package/dist/core/ai-verify/visual-judge.js +123 -0
- package/dist/core/ai-verify/visual-judge.js.map +1 -0
- package/dist/core/analyze-engine.d.ts.map +1 -1
- package/dist/core/analyze-engine.js +2 -1
- package/dist/core/analyze-engine.js.map +1 -1
- package/dist/core/ask-engine.d.ts +6 -0
- package/dist/core/ask-engine.d.ts.map +1 -1
- package/dist/core/ask-engine.js +83 -3
- package/dist/core/ask-engine.js.map +1 -1
- package/dist/core/code-graph/builder.d.ts.map +1 -1
- package/dist/core/code-graph/builder.js +93 -75
- package/dist/core/code-graph/builder.js.map +1 -1
- package/dist/core/code-graph/incremental-build.d.ts.map +1 -1
- package/dist/core/code-graph/incremental-build.js +13 -19
- package/dist/core/code-graph/incremental-build.js.map +1 -1
- package/dist/core/code-graph/index.d.ts +1 -1
- package/dist/core/code-graph/index.d.ts.map +1 -1
- package/dist/core/code-graph/index.js +15 -12
- package/dist/core/code-graph/index.js.map +1 -1
- package/dist/core/code-graph/multimodal.js +1 -1
- package/dist/core/code-graph/parser.js +1 -1
- package/dist/core/code-graph/query.d.ts +1 -1
- package/dist/core/code-graph/reporter.d.ts +1 -1
- package/dist/core/code-graph/reporter.d.ts.map +1 -1
- package/dist/core/code-graph/reporter.js +18 -10
- package/dist/core/code-graph/reporter.js.map +1 -1
- package/dist/core/code-graph/requirement-linker.d.ts.map +1 -1
- package/dist/core/code-graph/requirement-linker.js +24 -14
- package/dist/core/code-graph/requirement-linker.js.map +1 -1
- package/dist/core/code-graph/types.d.ts +1 -1
- package/dist/core/code-graph/types.js +1 -1
- package/dist/core/code-graph/visualizer.d.ts +1 -7
- package/dist/core/code-graph/visualizer.d.ts.map +1 -1
- package/dist/core/code-graph/visualizer.js +476 -49
- package/dist/core/code-graph/visualizer.js.map +1 -1
- package/dist/core/code-scanner.d.ts +2 -0
- package/dist/core/code-scanner.d.ts.map +1 -1
- package/dist/core/code-scanner.js +13 -1
- package/dist/core/code-scanner.js.map +1 -1
- package/dist/core/deploy/engine.d.ts +21 -0
- package/dist/core/deploy/engine.d.ts.map +1 -1
- package/dist/core/deploy/engine.js +276 -0
- package/dist/core/deploy/engine.js.map +1 -1
- package/dist/core/deploy-ledger.d.ts +12 -0
- package/dist/core/deploy-ledger.d.ts.map +1 -0
- package/dist/core/deploy-ledger.js +35 -0
- package/dist/core/deploy-ledger.js.map +1 -0
- package/dist/core/environment-config.d.ts +11 -0
- package/dist/core/environment-config.d.ts.map +1 -1
- package/dist/core/environment-config.js +4 -0
- package/dist/core/environment-config.js.map +1 -1
- package/dist/core/intent-cache.d.ts.map +1 -1
- package/dist/core/intent-cache.js +6 -0
- package/dist/core/intent-cache.js.map +1 -1
- package/dist/core/knowledge-visualizer.js +1 -1
- package/dist/core/page-bundle.d.ts +2 -0
- package/dist/core/page-bundle.d.ts.map +1 -1
- package/dist/core/page-bundle.js +18 -1
- package/dist/core/page-bundle.js.map +1 -1
- package/dist/core/plan-html.js +1 -1
- package/dist/core/platform-inference.d.ts +35 -0
- package/dist/core/platform-inference.d.ts.map +1 -1
- package/dist/core/platform-inference.js +92 -0
- package/dist/core/platform-inference.js.map +1 -1
- package/dist/core/prompt-plugins/analyze-graph-plugin.d.ts.map +1 -1
- package/dist/core/prompt-plugins/analyze-graph-plugin.js +16 -1
- package/dist/core/prompt-plugins/analyze-graph-plugin.js.map +1 -1
- package/dist/core/prompt-plugins/execute-graph-plugin.d.ts +2 -0
- package/dist/core/prompt-plugins/execute-graph-plugin.d.ts.map +1 -1
- package/dist/core/prompt-plugins/execute-graph-plugin.js +127 -27
- package/dist/core/prompt-plugins/execute-graph-plugin.js.map +1 -1
- package/dist/core/quality-audit.d.ts.map +1 -1
- package/dist/core/quality-audit.js +18 -0
- package/dist/core/quality-audit.js.map +1 -1
- package/dist/core/rag-engine.d.ts.map +1 -1
- package/dist/core/rag-engine.js +12 -243
- package/dist/core/rag-engine.js.map +1 -1
- package/dist/core/reindex-engine.d.ts +20 -0
- package/dist/core/reindex-engine.d.ts.map +1 -1
- package/dist/core/reindex-engine.js +142 -0
- package/dist/core/reindex-engine.js.map +1 -1
- package/dist/core/requirement-clarifier.d.ts.map +1 -1
- package/dist/core/requirement-clarifier.js +22 -6
- package/dist/core/requirement-clarifier.js.map +1 -1
- package/dist/core/reverse-requirement.d.ts +37 -0
- package/dist/core/reverse-requirement.d.ts.map +1 -1
- package/dist/core/reverse-requirement.js +84 -9
- package/dist/core/reverse-requirement.js.map +1 -1
- package/dist/core/spec-paths.d.ts +5 -0
- package/dist/core/spec-paths.d.ts.map +1 -1
- package/dist/core/spec-paths.js +1 -0
- package/dist/core/spec-paths.js.map +1 -1
- package/dist/core/test-config.d.ts +7 -1
- package/dist/core/test-config.d.ts.map +1 -1
- package/dist/core/test-config.js +59 -11
- package/dist/core/test-config.js.map +1 -1
- package/dist/core/ui-verify/index.d.ts +1 -1
- package/dist/core/ui-verify/index.d.ts.map +1 -1
- package/dist/core/ui-verify/index.js +2 -1
- package/dist/core/ui-verify/index.js.map +1 -1
- package/dist/core/ui-verify/smoke-engine.js +71 -15
- package/dist/core/ui-verify/smoke-engine.js.map +1 -1
- package/dist/core/ui-verify/spec-generator.d.ts +5 -9
- package/dist/core/ui-verify/spec-generator.d.ts.map +1 -1
- package/dist/core/ui-verify/spec-generator.js +66 -3
- package/dist/core/ui-verify/spec-generator.js.map +1 -1
- package/dist/core/ui-verify/types.d.ts +25 -0
- package/dist/core/ui-verify/types.d.ts.map +1 -1
- package/dist/core/ui-verify/visual-model-client.d.ts +2 -0
- package/dist/core/ui-verify/visual-model-client.d.ts.map +1 -1
- package/dist/core/ui-verify/visual-model-client.js +4 -4
- package/dist/core/ui-verify/visual-model-client.js.map +1 -1
- package/dist/core/unified-config.d.ts +27 -0
- package/dist/core/unified-config.d.ts.map +1 -1
- package/dist/core/unified-config.js +37 -0
- package/dist/core/unified-config.js.map +1 -1
- package/dist/core/unified-retrieval.d.ts +8 -0
- package/dist/core/unified-retrieval.d.ts.map +1 -1
- package/dist/core/unified-retrieval.js +18 -0
- package/dist/core/unified-retrieval.js.map +1 -1
- package/dist/utils/synonyms.d.ts.map +1 -1
- package/dist/utils/synonyms.js +4 -0
- package/dist/utils/synonyms.js.map +1 -1
- package/package.json +1 -1
- package/templates/accounts-example.yaml +49 -0
- package/templates/html/fonts/JetBrainsMono.woff2 +0 -0
- package/templates/html/fonts/Orbitron.woff2 +0 -0
- package/templates/html/speccore-ask-explain.html +1 -1
- package/templates/html/speccore-ask-guide.html +2 -2
- package/templates/html/speccore-ask-match.html +1 -1
- package/templates/html/speccore-ask-pipeline.html +1 -1
- package/templates/html/speccore-ask-result.html +2 -2
- package/templates/html/speccore-help.html +2 -2
- package/templates/html/speccore-setup-guide.html +16 -1
- package/templates/speccore-yml-example.yml +12 -0
|
@@ -1,48 +1,178 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.buildCodeGraphHtml = buildCodeGraphHtml;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Code Knowledge Graph — graph.html 可视化生成器
|
|
6
|
+
* v8.3.356: vis-network 单层全量渲染(节点过万成毛线球)
|
|
7
|
+
* v8.3.358: 双层视图重构 —— 社区总览(30 节点秒开)→ 双击钻入成员层;
|
|
8
|
+
* 需求↔代码联动侧栏 + 边类型/God 开关 + 节点详情面板;
|
|
9
|
+
* 连续色相调色板(30 社区各归其色,修复 %10 同色);
|
|
10
|
+
* 边字段压缩(f/t/ty/c)瘦身 + 桥接聚合边(跨社区边按社区对合并)。
|
|
11
|
+
*/
|
|
12
|
+
const fs_extra_1 = require("fs-extra");
|
|
13
|
+
const path_1 = require("path");
|
|
14
|
+
/**
|
|
15
|
+
* v8.3.360+: 把 vis-network UMD 落地到 .speccore/code-graph/(离线可开)。
|
|
16
|
+
* 本地缺失时尝试从 unpkg 下载一次(8s 超时),失败静默回退 CDN 引用。
|
|
17
|
+
*/
|
|
18
|
+
async function ensureVisNetworkLocal(root) {
|
|
19
|
+
const localJs = (0, path_1.join)(root, '.speccore', 'code-graph', 'vis-network.min.js');
|
|
20
|
+
if (await (0, fs_extra_1.pathExists)(localJs))
|
|
21
|
+
return true;
|
|
22
|
+
try {
|
|
23
|
+
const res = await fetch('https://unpkg.com/vis-network/standalone/umd/vis-network.min.js', {
|
|
24
|
+
signal: AbortSignal.timeout(8000),
|
|
25
|
+
});
|
|
26
|
+
if (!res.ok)
|
|
27
|
+
return false;
|
|
28
|
+
await (0, fs_extra_1.writeFile)(localJs, Buffer.from(await res.arrayBuffer()));
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
catch { /* 无网络时回退 CDN */
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
async function buildCodeGraphHtml(graph, projectRoot) {
|
|
36
|
+
const root = projectRoot || process.cwd();
|
|
37
|
+
await ensureVisNetworkLocal(root);
|
|
38
|
+
const idToNode = new Map(graph.nodes.map(n => [n.id, n]));
|
|
39
|
+
const godSet = new Set(graph.godNodes);
|
|
40
|
+
// ── 1. 连续色相调色板(30 社区各归其色,v8.3.358 修复 %10 同色)──
|
|
41
|
+
const orphanNodes = graph.nodes.filter(n => n.community === undefined);
|
|
42
|
+
const commCount = Math.max(graph.communities.length + (orphanNodes.length > 0 ? 1 : 0), 1);
|
|
43
|
+
const colorOf = (i) => `hsl(${(i * 360) / commCount + 15 % 360}, 65%, 55%)`;
|
|
44
|
+
// ── 2. 社区总览层:社区节点 + 桥接聚合边 ──
|
|
45
|
+
const communities = graph.communities.map((c, i) => {
|
|
46
|
+
const members = c.nodes
|
|
47
|
+
.map(id => idToNode.get(id))
|
|
48
|
+
.filter((n) => Boolean(n));
|
|
49
|
+
const godCount = c.nodes.filter(id => godSet.has(id)).length;
|
|
50
|
+
return {
|
|
51
|
+
id: c.id,
|
|
52
|
+
label: c.label,
|
|
53
|
+
memberCount: c.nodes.length,
|
|
54
|
+
godCount,
|
|
55
|
+
color: colorOf(i),
|
|
56
|
+
topMembers: members
|
|
57
|
+
.sort((a, b) => (b.degree || 0) - (a.degree || 0))
|
|
58
|
+
.slice(0, 5)
|
|
59
|
+
.map(n => n.name),
|
|
60
|
+
};
|
|
61
|
+
});
|
|
62
|
+
// 无社区节点(社区检测只聚类边连通节点,孤立节点 community 为 undefined)
|
|
63
|
+
// 归入「未分类」社区,保证成员层全量覆盖(v8.3.358)
|
|
64
|
+
if (orphanNodes.length > 0) {
|
|
65
|
+
communities.push({
|
|
66
|
+
id: -1,
|
|
67
|
+
label: '未分类',
|
|
68
|
+
memberCount: orphanNodes.length,
|
|
69
|
+
godCount: orphanNodes.filter(n => godSet.has(n.id)).length,
|
|
70
|
+
color: '#64748b',
|
|
71
|
+
topMembers: orphanNodes
|
|
72
|
+
.sort((a, b) => (b.degree || 0) - (a.degree || 0))
|
|
73
|
+
.slice(0, 5)
|
|
74
|
+
.map(n => n.name),
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
// 桥接聚合边:跨社区边按社区对合并(from/to 用社区 id,count 计边数)
|
|
78
|
+
// v8.3.358: community 为 undefined 的一端按「未分类(-1)」参与聚合
|
|
79
|
+
const commOf = (n) => n.community ?? -1;
|
|
80
|
+
const bridgeAgg = new Map();
|
|
81
|
+
for (const e of graph.edges) {
|
|
82
|
+
const s = idToNode.get(e.source);
|
|
83
|
+
const t = idToNode.get(e.target);
|
|
84
|
+
if (!s || !t)
|
|
85
|
+
continue;
|
|
86
|
+
const sc = commOf(s);
|
|
87
|
+
const tc = commOf(t);
|
|
88
|
+
if (sc === tc)
|
|
89
|
+
continue;
|
|
90
|
+
const key = sc < tc ? `${sc}-${tc}` : `${tc}-${sc}`;
|
|
91
|
+
const agg = bridgeAgg.get(key) || { from: Math.min(sc, tc), to: Math.max(sc, tc), count: 0, extracted: 0 };
|
|
92
|
+
agg.count++;
|
|
93
|
+
if (e.confidence === 'EXTRACTED')
|
|
94
|
+
agg.extracted++;
|
|
95
|
+
bridgeAgg.set(key, agg);
|
|
96
|
+
}
|
|
97
|
+
const bridgeEdges = [...bridgeAgg.values()].map(b => ({ ...b, type: b.extracted === b.count ? 'EXTRACTED' : 'MIXED' }));
|
|
98
|
+
// ── 3. 成员层:按社区分组节点与边(字段压缩)──
|
|
99
|
+
const nodeCommunity = new Map();
|
|
100
|
+
const members = {};
|
|
101
|
+
for (const n of graph.nodes) {
|
|
102
|
+
const c = commOf(n);
|
|
103
|
+
nodeCommunity.set(n.id, c);
|
|
104
|
+
const key = String(c);
|
|
105
|
+
if (!members[key])
|
|
106
|
+
members[key] = { nodes: [], internalEdges: [], crossEdges: [] };
|
|
107
|
+
members[key].nodes.push({
|
|
108
|
+
i: n.id,
|
|
109
|
+
l: n.name,
|
|
110
|
+
ty: n.type,
|
|
111
|
+
d: n.degree || 1,
|
|
112
|
+
f: n.filePath,
|
|
113
|
+
ln: n.line,
|
|
114
|
+
g: godSet.has(n.id),
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
for (const e of graph.edges) {
|
|
118
|
+
const s = idToNode.get(e.source);
|
|
119
|
+
const t = idToNode.get(e.target);
|
|
120
|
+
if (!s || !t)
|
|
121
|
+
continue;
|
|
122
|
+
const sc = commOf(s);
|
|
123
|
+
const tc = commOf(t);
|
|
124
|
+
const slim = { f: e.source, t: e.target, ty: e.type, c: e.confidence };
|
|
125
|
+
if (sc === tc) {
|
|
126
|
+
members[String(sc)]?.internalEdges.push(slim);
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
// 跨边两端进各自社区的 crossEdges,target 改指向对方社区节点
|
|
130
|
+
members[String(sc)]?.crossEdges.push({ ...slim, t: `comm-${tc}` });
|
|
131
|
+
members[String(tc)]?.crossEdges.push({ ...slim, f: `comm-${sc}` });
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
// ── 4. 需求↔代码联动(v8.3.358+: REQ_CODE_LINK 侧栏数据)──
|
|
135
|
+
const reqLinks = [];
|
|
136
|
+
try {
|
|
137
|
+
const linkPath = (0, path_1.join)(root, '.speccore', 'code-graph', 'REQ_CODE_LINK.json');
|
|
138
|
+
if (await (0, fs_extra_1.pathExists)(linkPath)) {
|
|
139
|
+
const report = JSON.parse(await (0, fs_extra_1.readFile)(linkPath, 'utf-8'));
|
|
140
|
+
for (const l of (report.links || [])) {
|
|
141
|
+
if (l.linkedNodeIds && l.linkedNodeIds.length > 0) {
|
|
142
|
+
reqLinks.push({ req: l.requirement, nodeIds: l.linkedNodeIds });
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
catch { /* 联动数据缺失时侧栏为空 */ }
|
|
148
|
+
// 节点 → 需求 反向索引(详情面板用)
|
|
149
|
+
const nodeReqs = new Map();
|
|
150
|
+
for (const l of reqLinks) {
|
|
151
|
+
for (const id of l.nodeIds) {
|
|
152
|
+
const arr = nodeReqs.get(id) || [];
|
|
153
|
+
if (arr.length < 3)
|
|
154
|
+
arr.push(l.req);
|
|
155
|
+
nodeReqs.set(id, arr);
|
|
32
156
|
}
|
|
33
157
|
}
|
|
34
158
|
const meta = graph.metadata;
|
|
159
|
+
// ── 5. HTML 渲染 ──
|
|
35
160
|
return `<!DOCTYPE html>
|
|
36
161
|
<html lang="zh-CN">
|
|
37
162
|
<head>
|
|
38
163
|
<meta charset="UTF-8">
|
|
39
164
|
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
|
40
165
|
<title>${meta.projectName} — Code Graph</title>
|
|
41
|
-
<script src="
|
|
166
|
+
<script src="vis-network.min.js"></script>
|
|
167
|
+
<script>
|
|
168
|
+
// v8.3.360+: 优先本地 UMD(离线可开),本地缺失时回退 unpkg CDN
|
|
169
|
+
// '<scr'+'ipt' 拆写避免解析器进入 double-escaped 状态,尾串转义为 '<\\/script>' 防闭合标签提前终止(注释也避字面序列)
|
|
170
|
+
if (!window.vis) document.write('<scr' + 'ipt src="https://unpkg.com/vis-network/standalone/umd/vis-network.min.js"><\\/script>');
|
|
171
|
+
</script>
|
|
42
172
|
<style>
|
|
43
173
|
body{margin:0;font-family:'Segoe UI',system-ui,sans-serif;background:#0b1929;color:#bae6fd;overflow:hidden}
|
|
44
174
|
#graph{position:fixed;inset:0}
|
|
45
|
-
.panel{position:fixed;top:12px;left:12px;background:rgba(13,31,56,.95);border:1px solid rgba(14,165,233,.2);border-radius:10px;padding:14px;max-width:
|
|
175
|
+
.panel{position:fixed;top:12px;left:12px;background:rgba(13,31,56,.95);border:1px solid rgba(14,165,233,.2);border-radius:10px;padding:14px;max-width:260px;z-index:10;font-size:12px}
|
|
46
176
|
.panel h2{margin:0 0 8px;font-size:14px;color:#0ea5e9}
|
|
47
177
|
.panel .stat{display:flex;justify-content:space-between;padding:3px 0;border-bottom:1px solid rgba(255,255,255,.05)}
|
|
48
178
|
.panel .stat span{color:#5b7fa5}
|
|
@@ -50,10 +180,24 @@ body{margin:0;font-family:'Segoe UI',system-ui,sans-serif;background:#0b1929;col
|
|
|
50
180
|
.panel .legend-item{display:flex;align-items:center;gap:6px;margin:4px 0}
|
|
51
181
|
.panel .dot{width:10px;height:10px;border-radius:50%}
|
|
52
182
|
.panel .line{width:20px;height:2px}
|
|
183
|
+
.panel label{display:flex;align-items:center;gap:6px;margin-top:6px;cursor:pointer}
|
|
53
184
|
.search{position:fixed;top:12px;right:12px;z-index:10;display:flex;gap:6px}
|
|
54
185
|
.search input{background:rgba(13,31,56,.95);border:1px solid rgba(14,165,233,.2);border-radius:6px;padding:6px 10px;color:#bae6fd;font-size:12px;outline:none;width:180px}
|
|
55
186
|
.search input::placeholder{color:#5b7fa5}
|
|
56
187
|
.search button{background:#0ea5e9;border:none;border-radius:6px;padding:6px 12px;color:#fff;font-size:12px;cursor:pointer}
|
|
188
|
+
.breadcrumb{position:fixed;bottom:12px;left:12px;z-index:10;display:none}
|
|
189
|
+
.breadcrumb button{background:rgba(13,31,56,.95);border:1px solid rgba(14,165,233,.4);border-radius:6px;padding:6px 12px;color:#0ea5e9;font-size:12px;cursor:pointer}
|
|
190
|
+
.detail{position:fixed;top:48px;right:12px;z-index:10;background:rgba(13,31,56,.97);border:1px solid rgba(14,165,233,.3);border-radius:10px;padding:12px;max-width:300px;font-size:12px;display:none}
|
|
191
|
+
.detail h3{margin:0 0 6px;font-size:13px;color:#0ea5e9;word-break:break-all}
|
|
192
|
+
.detail div{margin:2px 0;color:#7dd3fc}
|
|
193
|
+
.detail .req{color:#fbbf24}
|
|
194
|
+
.reqpanel{position:fixed;bottom:12px;right:12px;z-index:10;background:rgba(13,31,56,.95);border:1px solid rgba(14,165,233,.3);border-radius:10px;padding:10px;max-width:320px;max-height:45vh;overflow:auto;font-size:12px;display:none}
|
|
195
|
+
.reqpanel h3{margin:0 0 6px;font-size:13px;color:#0ea5e9}
|
|
196
|
+
.reqpanel input{background:rgba(13,31,56,.95);border:1px solid rgba(14,165,233,.2);border-radius:4px;padding:4px 8px;color:#bae6fd;font-size:11px;width:100%;box-sizing:border-box;margin-bottom:6px}
|
|
197
|
+
.reqpanel .req-item{padding:3px 6px;border-radius:4px;cursor:pointer;color:#7dd3fc}
|
|
198
|
+
.reqpanel .req-item:hover{background:rgba(14,165,233,.15)}
|
|
199
|
+
.reqpanel .req-item b{color:#fbbf24}
|
|
200
|
+
.req-toggle{position:fixed;bottom:12px;right:12px;z-index:11;background:#0ea5e9;border:none;border-radius:6px;padding:6px 12px;color:#fff;font-size:12px;cursor:pointer}
|
|
57
201
|
</style>
|
|
58
202
|
</head>
|
|
59
203
|
<body>
|
|
@@ -64,32 +208,315 @@ body{margin:0;font-family:'Segoe UI',system-ui,sans-serif;background:#0b1929;col
|
|
|
64
208
|
<div class="stat">Nodes <span>${meta.totalNodes}</span></div>
|
|
65
209
|
<div class="stat">Edges <span>${meta.totalEdges}</span></div>
|
|
66
210
|
<div class="stat">Communities <span>${graph.communities.length}</span></div>
|
|
67
|
-
<div class="stat"
|
|
68
|
-
<div class="stat">INFERRED <span>${meta.inferredEdges}</span></div>
|
|
211
|
+
<div class="stat">需求联动 <span>${reqLinks.length}</span></div>
|
|
69
212
|
<div class="legend">
|
|
70
|
-
<div class="legend-item"><span class="dot" style="background
|
|
71
|
-
<div class="legend-item"><span class="line" style="background:#
|
|
72
|
-
<div class="legend-item"><span class="
|
|
213
|
+
<div class="legend-item"><span class="dot" style="background:${colorOf(0)}"></span> 社区(双击钻入成员)</div>
|
|
214
|
+
<div class="legend-item"><span class="line" style="background:#0ea5e9"></span> EXTRACTED 边</div>
|
|
215
|
+
<div class="legend-item"><span class="line" style="background:#94a3b8;border-top:2px dashed #94a3b8"></span> INFERRED 边</div>
|
|
216
|
+
<div class="legend-item"><span class="line" style="background:#f59e0b"></span> MIXED 桥接边(总览层)</div>
|
|
217
|
+
<div class="legend-item"><span class="dot" style="background:#fff;border:2px solid #f97316"></span> God node / God 社区</div>
|
|
73
218
|
</div>
|
|
219
|
+
<label><input type="checkbox" id="showExtracted" checked> EXTRACTED 边</label>
|
|
220
|
+
<label><input type="checkbox" id="showInferred"> INFERRED 边</label>
|
|
221
|
+
<label><input type="checkbox" id="showGod" checked> God 高亮</label>
|
|
74
222
|
</div>
|
|
75
223
|
<div class="search">
|
|
76
|
-
<input type="text" id="searchInput" placeholder="
|
|
77
|
-
<button onclick="
|
|
224
|
+
<input type="text" id="searchInput" placeholder="搜索节点 / 社区...">
|
|
225
|
+
<button onclick="doSearch()">Find</button>
|
|
226
|
+
</div>
|
|
227
|
+
<div class="detail" id="detail"></div>
|
|
228
|
+
<div class="breadcrumb" id="breadcrumb"><button onclick="exitCommunity()">← 返回社区总览</button></div>
|
|
229
|
+
<button class="req-toggle" onclick="toggleReqPanel()">📋 需求联动 (${reqLinks.length})</button>
|
|
230
|
+
<div class="reqpanel" id="reqpanel">
|
|
231
|
+
<h3>需求 ↔ 代码联动</h3>
|
|
232
|
+
<input type="text" id="reqFilter" placeholder="过滤需求..." oninput="renderReqList()">
|
|
233
|
+
<div id="reqList"></div>
|
|
78
234
|
</div>
|
|
79
235
|
<script>
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
physics:{stabilization:false,barnesHut:{gravitationalConstant:-3000,springConstant:0.04,springLength:95}},
|
|
88
|
-
interaction:{hover:true,tooltipDelay:200,hideEdgesOnDrag:true}
|
|
236
|
+
const LAYERS = {
|
|
237
|
+
communities: ${JSON.stringify(communities)},
|
|
238
|
+
bridgeEdges: ${JSON.stringify(bridgeEdges)},
|
|
239
|
+
members: ${JSON.stringify(members)},
|
|
240
|
+
reqLinks: ${JSON.stringify(reqLinks)},
|
|
241
|
+
nodeReqs: ${JSON.stringify([...nodeReqs])},
|
|
242
|
+
nodeCommunity: ${JSON.stringify([...nodeCommunity])},
|
|
89
243
|
};
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
244
|
+
|
|
245
|
+
const commNodes = new vis.DataSet(LAYERS.communities.map(c => ({
|
|
246
|
+
id: 'comm-' + c.id,
|
|
247
|
+
label: c.label,
|
|
248
|
+
group: 'comm',
|
|
249
|
+
title: '<b>' + c.label + '</b><br>成员: ' + c.memberCount + '<br>God nodes: ' + c.godCount + '<br>代表: ' + c.topMembers.slice(0,3).join(', '),
|
|
250
|
+
value: Math.max(8, Math.min(40, Math.sqrt(c.memberCount) * 1.2)),
|
|
251
|
+
// v8.3.360+: vis-network 绘制边框读 color.border(顶层 borderColor 被忽略),God 社区橙边星标须走 color 对象
|
|
252
|
+
color: c.godCount > 0 ? { background: c.color, border: '#f97316' } : c.color,
|
|
253
|
+
shape: 'box',
|
|
254
|
+
font: { color: '#e0f2fe', size: 14 },
|
|
255
|
+
borderWidth: c.godCount > 0 ? 2 : 1,
|
|
256
|
+
})));
|
|
257
|
+
const allEdges = LAYERS.bridgeEdges.map(b => ({
|
|
258
|
+
id: 'be-' + b.from + '-' + b.to,
|
|
259
|
+
from: 'comm-' + b.from,
|
|
260
|
+
to: 'comm-' + b.to,
|
|
261
|
+
title: '跨社区边: ' + b.count + ' 条',
|
|
262
|
+
label: String(b.count),
|
|
263
|
+
width: Math.max(1, Math.min(6, b.count / 15)),
|
|
264
|
+
color: b.type === 'EXTRACTED' ? { color: '#0ea5e9', opacity: 0.7 } : { color: '#f59e0b', opacity: 0.7 },
|
|
265
|
+
arrows: { to: { enabled: true, scaleFactor: 0.6 } },
|
|
266
|
+
// 初始态与开关一致:EXTRACTED 显示(默认勾选),MIXED 隐藏(showInferred 默认未勾选)
|
|
267
|
+
hidden: b.type === 'MIXED',
|
|
268
|
+
}));
|
|
269
|
+
|
|
270
|
+
const nodes = new vis.DataSet(commNodes.get());
|
|
271
|
+
const edges = new vis.DataSet(allEdges);
|
|
272
|
+
const container = document.getElementById('graph');
|
|
273
|
+
const network = new vis.Network(container, { nodes, edges }, {
|
|
274
|
+
nodes: { shape: 'dot', font: { color: '#bae6fd', size: 12 }, borderWidth: 1, borderWidthSelected: 2 },
|
|
275
|
+
edges: { width: 1, smooth: { type: 'continuous' }, font: { color: '#7dd3fc', size: 10 } },
|
|
276
|
+
physics: {
|
|
277
|
+
barnesHut: { gravitationalConstant: -6000, springConstant: 0.04, springLength: 130, avoidOverlap: 0.6 },
|
|
278
|
+
// v8.3.358+: 限定稳定化迭代次数,完成后关闭物理引擎(否则节点永远漂移)
|
|
279
|
+
stabilization: { iterations: 250, updateInterval: 25 },
|
|
280
|
+
},
|
|
281
|
+
interaction: { hover: true, tooltipDelay: 150, hideEdgesOnDrag: true },
|
|
282
|
+
});
|
|
283
|
+
// stabilize 完成回调统一管理(初始 250 迭代 + 钻入局部布局共用),避免连续钻入时监听堆积
|
|
284
|
+
let stabilizeDone = null;
|
|
285
|
+
function bindStabilizeDone(fn) {
|
|
286
|
+
if (stabilizeDone) network.off('stabilizationIterationsDone', stabilizeDone);
|
|
287
|
+
stabilizeDone = fn;
|
|
288
|
+
network.once('stabilizationIterationsDone', fn);
|
|
289
|
+
}
|
|
290
|
+
bindStabilizeDone(function () {
|
|
291
|
+
network.setOptions({ physics: { enabled: false } });
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
let activeComm = null;
|
|
295
|
+
|
|
296
|
+
// —— 双层视图:社区总览 → 双击钻入成员层 ——
|
|
297
|
+
network.on('doubleClick', function (params) {
|
|
298
|
+
if (params.nodes.length === 0) return;
|
|
299
|
+
const id = params.nodes[0];
|
|
300
|
+
if (id.startsWith('comm-')) enterCommunity(id);
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
// —— 点击:社区→更新详情,成员→详情面板 ——
|
|
304
|
+
network.on('click', function (params) {
|
|
305
|
+
if (params.nodes.length === 0) { hideDetail(); return; }
|
|
306
|
+
const id = params.nodes[0];
|
|
307
|
+
if (id.startsWith('comm-')) { showCommDetail(id); return; }
|
|
308
|
+
showNodeDetail(id);
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
function enterCommunity(commId) {
|
|
312
|
+
if (activeComm) exitCommunity(true);
|
|
313
|
+
const cid = commId.replace('comm-', '');
|
|
314
|
+
const layer = LAYERS.members[cid];
|
|
315
|
+
if (!layer || layer.nodes.length === 0) return;
|
|
316
|
+
activeComm = commId;
|
|
317
|
+
const pos = network.getPosition(commId);
|
|
318
|
+
const baseColor = LAYERS.communities.find(c => 'comm-' + c.id === commId)?.color || '#94a3b8';
|
|
319
|
+
const add = layer.nodes.map(n => {
|
|
320
|
+
const nd = {
|
|
321
|
+
id: n.i,
|
|
322
|
+
label: n.l,
|
|
323
|
+
title: n.l + ' (' + n.ty + ')\\n' + n.f + ':' + n.ln + '\\ndegree: ' + n.d,
|
|
324
|
+
value: Math.max(3, Math.min(18, Math.sqrt(n.d) * 1.5)),
|
|
325
|
+
// God node 橙边星标(vis-network 读 color.border,顶层 borderColor 无效)
|
|
326
|
+
color: n.g ? { background: baseColor, border: '#f97316' } : baseColor,
|
|
327
|
+
x: pos.x + (Math.random() - 0.5) * 300,
|
|
328
|
+
y: pos.y + (Math.random() - 0.5) * 300,
|
|
329
|
+
font: { color: '#bae6fd', size: n.g ? 14 : 10 },
|
|
330
|
+
borderWidth: n.g ? 2 : 1,
|
|
331
|
+
};
|
|
332
|
+
return nd;
|
|
333
|
+
});
|
|
334
|
+
const existingIds = new Set(nodes.getIds());
|
|
335
|
+
const fresh = add.filter(n => !existingIds.has(n.id));
|
|
336
|
+
const shown = add.filter(n => existingIds.has(n.id));
|
|
337
|
+
nodes.add(fresh);
|
|
338
|
+
if (shown.length) nodes.update(shown.map(n => ({ id: n.id, hidden: false })));
|
|
339
|
+
const inner = layer.internalEdges.map((e, i) => ({
|
|
340
|
+
id: 'ie-' + cid + '-' + i, from: e.f, to: e.t, title: e.ty + ' (' + e.c + ')',
|
|
341
|
+
dashes: e.c === 'INFERRED', color: e.c === 'EXTRACTED' ? { color: '#0ea5e9', opacity: 0.5 } : { color: '#94a3b8', opacity: 0.3 },
|
|
342
|
+
hidden: !edgeVisible(e.c),
|
|
343
|
+
}));
|
|
344
|
+
const cross = layer.crossEdges.map((e, i) => ({
|
|
345
|
+
id: 'ce-' + cid + '-' + i, from: e.f, to: e.t, title: e.ty + ' (' + e.c + ') → 跨社区',
|
|
346
|
+
dashes: e.c === 'INFERRED', color: { color: '#f59e0b', opacity: 0.55 },
|
|
347
|
+
hidden: !edgeVisible(e.c),
|
|
348
|
+
}));
|
|
349
|
+
const existingEdgeIds = new Set(edges.getIds());
|
|
350
|
+
const freshEdges = [...inner, ...cross].filter(e => !existingEdgeIds.has(e.id));
|
|
351
|
+
const shownEdges = [...inner, ...cross].filter(e => existingEdgeIds.has(e.id));
|
|
352
|
+
edges.add(freshEdges);
|
|
353
|
+
if (shownEdges.length) edges.update(shownEdges.map(e => ({ id: e.id, hidden: e.hidden })));
|
|
354
|
+
document.getElementById('breadcrumb').style.display = 'block';
|
|
355
|
+
network.focus(commId, { scale: 1.1, animation: true });
|
|
356
|
+
// v8.3.360+: 钻入后局部布局一轮(固定社区节点,仅新成员参与 stabilize,避免成员随机散布重叠)
|
|
357
|
+
stabilizeMembers(commId, layer.nodes.map(n => n.i));
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
function stabilizeMembers(commId, newIds) {
|
|
361
|
+
const existing = nodes.getIds().filter(id => !newIds.includes(id));
|
|
362
|
+
nodes.update(existing.map(id => ({ id, fixed: { x: true, y: true } })));
|
|
363
|
+
network.setOptions({
|
|
364
|
+
physics: {
|
|
365
|
+
enabled: true,
|
|
366
|
+
barnesHut: { gravitationalConstant: -6000, springConstant: 0.04, springLength: 130, avoidOverlap: 0.6 },
|
|
367
|
+
stabilization: { enabled: true, iterations: 150, fit: false },
|
|
368
|
+
},
|
|
369
|
+
});
|
|
370
|
+
bindStabilizeDone(function () {
|
|
371
|
+
network.setOptions({ physics: { enabled: false } });
|
|
372
|
+
nodes.update(existing.map(id => ({ id, fixed: { x: false, y: false } })));
|
|
373
|
+
nodes.update(newIds.map(id => ({ id, fixed: { x: false, y: false } })));
|
|
374
|
+
network.focus(commId, { scale: 1.1, animation: true });
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
function exitCommunity(silent) {
|
|
379
|
+
if (!activeComm) return;
|
|
380
|
+
const cid = activeComm.replace('comm-', '');
|
|
381
|
+
const layer = LAYERS.members[cid];
|
|
382
|
+
if (layer) {
|
|
383
|
+
// v8.3.360+: 不 remove 而是 hidden——remove 成员节点会触发 vis-network 10.x 节点层渲染损坏
|
|
384
|
+
// (退出后社区方块颜色丢失),hidden 保留数据与样式,重新钻入时 update 恢复即可
|
|
385
|
+
nodes.update(layer.nodes.map(n => ({ id: n.i, hidden: true })));
|
|
386
|
+
const ids = layer.internalEdges.map((e, i) => 'ie-' + cid + '-' + i).concat(layer.crossEdges.map((e, i) => 'ce-' + cid + '-' + i));
|
|
387
|
+
edges.update(ids.map(id => ({ id, hidden: true })));
|
|
388
|
+
}
|
|
389
|
+
activeComm = null;
|
|
390
|
+
document.getElementById('breadcrumb').style.display = 'none';
|
|
391
|
+
hideDetail();
|
|
392
|
+
// v8.3.360+: 终止挂起的局部 stabilize(成员已隐藏,残留完成回调的 focus 会造成视角跳动)
|
|
393
|
+
if (stabilizeDone) { network.off('stabilizationIterationsDone', stabilizeDone); stabilizeDone = null; }
|
|
394
|
+
// 解除 fixed 残留并关闭物理
|
|
395
|
+
network.setOptions({ physics: { enabled: false } });
|
|
396
|
+
nodes.update(nodes.getIds().map(id => ({ id, fixed: { x: false, y: false } })));
|
|
397
|
+
if (!silent) network.fit();
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
function edgeVisible(conf) {
|
|
401
|
+
if (conf === 'EXTRACTED') return document.getElementById('showExtracted').checked;
|
|
402
|
+
return document.getElementById('showInferred').checked;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// —— 边/God 开关 ——
|
|
406
|
+
document.getElementById('showExtracted').addEventListener('change', refreshEdges);
|
|
407
|
+
document.getElementById('showInferred').addEventListener('change', refreshEdges);
|
|
408
|
+
document.getElementById('showGod').addEventListener('change', function () {
|
|
409
|
+
const on = this.checked;
|
|
410
|
+
// 总览层:God 社区橙边星标(color.border 驱动)
|
|
411
|
+
for (const c of LAYERS.communities) {
|
|
412
|
+
nodes.update({ id: 'comm-' + c.id, color: (c.godCount > 0 && on) ? { background: c.color, border: '#f97316' } : c.color, borderWidth: (c.godCount > 0 && on) ? 2 : 1 });
|
|
413
|
+
}
|
|
414
|
+
// 成员层:God node 高亮
|
|
415
|
+
if (!activeComm) return;
|
|
416
|
+
const cid = activeComm.replace('comm-', '');
|
|
417
|
+
const layer = LAYERS.members[cid];
|
|
418
|
+
if (!layer) return;
|
|
419
|
+
const base = LAYERS.communities.find(c => 'comm-' + c.id === cid)?.color || '#94a3b8';
|
|
420
|
+
for (const n of layer.nodes) {
|
|
421
|
+
nodes.update({ id: n.i, font: { color: '#bae6fd', size: (n.g && on) ? 14 : 10 }, color: (n.g && on) ? { background: base, border: '#f97316' } : base, borderWidth: (n.g && on) ? 2 : 1 });
|
|
422
|
+
}
|
|
423
|
+
});
|
|
424
|
+
function refreshEdges() {
|
|
425
|
+
if (!activeComm) {
|
|
426
|
+
// 总览层:桥接边按类型过滤(EXTRACTED ↔ showExtracted,MIXED ↔ showInferred)
|
|
427
|
+
for (const b of LAYERS.bridgeEdges) {
|
|
428
|
+
const on = b.type === 'EXTRACTED' ? document.getElementById('showExtracted').checked : document.getElementById('showInferred').checked;
|
|
429
|
+
edges.update({ id: 'be-' + b.from + '-' + b.to, hidden: !on });
|
|
430
|
+
}
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
433
|
+
const cid = activeComm.replace('comm-', '');
|
|
434
|
+
const layer = LAYERS.members[cid];
|
|
435
|
+
if (!layer) return;
|
|
436
|
+
layer.internalEdges.forEach((e, i) => edges.update({ id: 'ie-' + cid + '-' + i, hidden: !edgeVisible(e.c) }));
|
|
437
|
+
layer.crossEdges.forEach((e, i) => edges.update({ id: 'ce-' + cid + '-' + i, hidden: !edgeVisible(e.c) }));
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// —— 详情面板 ——
|
|
441
|
+
function showCommDetail(commId) {
|
|
442
|
+
const c = LAYERS.communities.find(x => 'comm-' + x.id === commId);
|
|
443
|
+
if (!c) return;
|
|
444
|
+
const el = document.getElementById('detail');
|
|
445
|
+
el.style.display = 'block';
|
|
446
|
+
el.innerHTML = '<h3>' + c.label + '</h3><div>成员节点: ' + c.memberCount + '</div><div>God nodes: ' + c.godCount + '</div><div>代表: ' + c.topMembers.join(', ') + '</div><div class="req">双击钻入成员层</div>';
|
|
447
|
+
}
|
|
448
|
+
function showNodeDetail(id) {
|
|
449
|
+
const nc = LAYERS.nodeCommunity.find(x => x[0] === id);
|
|
450
|
+
const commId = nc ? nc[1] : null;
|
|
451
|
+
const layer = commId !== null && commId !== undefined ? LAYERS.members[String(commId)] : null;
|
|
452
|
+
const node = layer ? layer.nodes.find(n => n.i === id) : null;
|
|
453
|
+
const el = document.getElementById('detail');
|
|
454
|
+
el.style.display = 'block';
|
|
455
|
+
const reqs = (LAYERS.nodeReqs.find(x => x[0] === id) || [])[1] || [];
|
|
456
|
+
if (node) {
|
|
457
|
+
el.innerHTML = '<h3>' + node.l + '</h3><div>类型: ' + node.ty + '</div><div>位置: ' + node.f + ':' + node.ln + '</div><div>度: ' + node.d + '</div>' + (node.g ? '<div class="req">⭐ God node</div>' : '') + (reqs.length ? '<div class="req">关联需求: ' + reqs.join('; ') + '</div>' : '');
|
|
458
|
+
} else {
|
|
459
|
+
el.innerHTML = '<h3>' + id + '</h3>';
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
function hideDetail() { document.getElementById('detail').style.display = 'none'; }
|
|
463
|
+
|
|
464
|
+
// —— 搜索:当前层成员 → 社区标签 → 未展开社区成员(自动钻入)——
|
|
465
|
+
function doSearch() {
|
|
466
|
+
const v = document.getElementById('searchInput').value.trim().toLowerCase();
|
|
467
|
+
if (!v) return;
|
|
468
|
+
// 1) 当前展开社区的成员
|
|
469
|
+
if (activeComm) {
|
|
470
|
+
const cid = activeComm.replace('comm-', '');
|
|
471
|
+
const layer = LAYERS.members[cid];
|
|
472
|
+
const hit = layer && layer.nodes.find(n => n.l.toLowerCase().includes(v));
|
|
473
|
+
if (hit) { selectNode(hit.i); return; }
|
|
474
|
+
}
|
|
475
|
+
// 2) 社区标签
|
|
476
|
+
const chit = LAYERS.communities.find(c => c.label.toLowerCase().includes(v));
|
|
477
|
+
if (chit) { network.focus('comm-' + chit.id, { scale: 1.2, animation: true }); network.selectNodes(['comm-' + chit.id]); return; }
|
|
478
|
+
// 3) 全量成员(自动钻入所在社区)
|
|
479
|
+
for (const cid of Object.keys(LAYERS.members)) {
|
|
480
|
+
const hit = LAYERS.members[cid].nodes.find(n => n.l.toLowerCase().includes(v));
|
|
481
|
+
if (hit) { enterCommunity('comm-' + cid); selectNode(hit.i); return; }
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
function selectNode(id) {
|
|
485
|
+
network.selectNodes([id]);
|
|
486
|
+
network.focus(id, { scale: 1.2, animation: true });
|
|
487
|
+
showNodeDetail(id);
|
|
488
|
+
}
|
|
489
|
+
document.getElementById('searchInput').addEventListener('keydown', e => { if (e.key === 'Enter') doSearch(); });
|
|
490
|
+
|
|
491
|
+
// —— 需求侧栏 ——
|
|
492
|
+
let reqPanelOpen = false;
|
|
493
|
+
function toggleReqPanel() {
|
|
494
|
+
reqPanelOpen = !reqPanelOpen;
|
|
495
|
+
document.getElementById('reqpanel').style.display = reqPanelOpen ? 'block' : 'none';
|
|
496
|
+
if (reqPanelOpen) renderReqList();
|
|
497
|
+
}
|
|
498
|
+
function renderReqList() {
|
|
499
|
+
const f = document.getElementById('reqFilter').value.trim().toLowerCase();
|
|
500
|
+
const list = LAYERS.reqLinks.filter(r => !f || r.req.toLowerCase().includes(f));
|
|
501
|
+
const el = document.getElementById('reqList');
|
|
502
|
+
el.innerHTML = list.slice(0, 100).map((r, idx) => {
|
|
503
|
+
const original = LAYERS.reqLinks.findIndex(x => x === r);
|
|
504
|
+
return '<div class="req-item" onclick="focusReq(' + original + ')"><b>' + (original + 1) + '.</b> ' + r.req + ' <span style="color:#5b7fa5">(' + r.nodeIds.length + ')</span></div>';
|
|
505
|
+
}).join('') || '<div style="color:#5b7fa5">无匹配需求</div>';
|
|
506
|
+
}
|
|
507
|
+
function focusReq(idx) {
|
|
508
|
+
const r = LAYERS.reqLinks[idx];
|
|
509
|
+
if (!r || r.nodeIds.length === 0) return;
|
|
510
|
+
const target = r.nodeIds[0];
|
|
511
|
+
const nc = LAYERS.nodeCommunity.find(x => x[0] === target);
|
|
512
|
+
if (nc) {
|
|
513
|
+
enterCommunity('comm-' + nc[1]);
|
|
514
|
+
selectNode(target);
|
|
515
|
+
// 高亮该需求的全部关联节点
|
|
516
|
+
const sel = r.nodeIds.filter(id => nodes.get(id));
|
|
517
|
+
network.selectNodes(sel);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
93
520
|
</script>
|
|
94
521
|
</body>
|
|
95
522
|
</html>`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"visualizer.js","sourceRoot":"","sources":["../../../src/core/code-graph/visualizer.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"visualizer.js","sourceRoot":"","sources":["../../../src/core/code-graph/visualizer.ts"],"names":[],"mappings":"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"}
|
|
@@ -111,6 +111,8 @@ export declare function checkCodeIndexFreshness(scope?: string[]): Promise<{
|
|
|
111
111
|
staleFiles: string[];
|
|
112
112
|
message: string;
|
|
113
113
|
}>;
|
|
114
|
+
export declare function expandKeywords(keywords: string[]): string[];
|
|
115
|
+
export declare function extractKeywords(text: string): string[];
|
|
114
116
|
/**
|
|
115
117
|
* v8.3.3xx+: 消费前兜底——索引缺失/过期时自动重建,并输出无索引告警
|
|
116
118
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code-scanner.d.ts","sourceRoot":"","sources":["../../src/core/code-scanner.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"code-scanner.d.ts","sourceRoot":"","sources":["../../src/core/code-scanner.ts"],"names":[],"mappings":"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"}
|