concept-atlas-dense-explain 0.1.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/bin/install.mjs +17 -0
- package/package.json +12 -0
- package/skill/SKILL.md +31 -0
- package/skill/assets/template/content/compile-runtime.mdx +158 -0
- package/skill/assets/template/index.html +16 -0
- package/skill/assets/template/package.json +21 -0
- package/skill/assets/template/scripts/build.mjs +37 -0
- package/skill/assets/template/scripts/clean-temp.mjs +27 -0
- package/skill/assets/template/src/app/App.jsx +239 -0
- package/skill/assets/template/src/components/MDXComponents.jsx +479 -0
- package/skill/assets/template/src/components/index.js +1 -0
- package/skill/assets/template/src/main.jsx +16 -0
- package/skill/assets/template/src/model/concept-schema.js +169 -0
- package/skill/assets/template/src/model/normalize-content.js +238 -0
- package/skill/assets/template/src/model/relation-types.js +90 -0
- package/skill/assets/template/src/styles/concept-explain.css +2425 -0
- package/skill/assets/template/src/views/NodeExplorer.jsx +629 -0
- package/skill/assets/template/src/views/RelationGraph.jsx +708 -0
- package/skill/assets/template/vite.config.js +21 -0
- package/skill/references/components.md +27 -0
- package/skill/references/prompting.md +38 -0
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import React, { Children, isValidElement } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Extracts structured node and relation data from MDX / React component elements
|
|
5
|
+
*/
|
|
6
|
+
export function extractConceptData(explainPageElement) {
|
|
7
|
+
// MDX exports a component rather than an already-expanded element.
|
|
8
|
+
// Resolve that wrapper before reading page metadata or its children.
|
|
9
|
+
explainPageElement = unwrapComponent(explainPageElement);
|
|
10
|
+
|
|
11
|
+
const result = {
|
|
12
|
+
meta: {
|
|
13
|
+
id: explainPageElement.props.id || 'explain-page',
|
|
14
|
+
title: explainPageElement.props.title || '',
|
|
15
|
+
summary: explainPageElement.props.summary || '',
|
|
16
|
+
rootId: null,
|
|
17
|
+
layout: explainPageElement.props.layout || 'editorial',
|
|
18
|
+
density: explainPageElement.props.density || 'reading',
|
|
19
|
+
},
|
|
20
|
+
nodes: [],
|
|
21
|
+
relations: []
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
function traverse(child) {
|
|
25
|
+
if (!child || !isValidElement(child)) return;
|
|
26
|
+
|
|
27
|
+
const componentName = getComponentName(child);
|
|
28
|
+
|
|
29
|
+
// MDX compiles to a component function. The element passed from main.jsx
|
|
30
|
+
// has no children until that function is evaluated, so unwrap non-semantic
|
|
31
|
+
// component wrappers before walking the semantic tree.
|
|
32
|
+
if (typeof child.type === 'function' && !isSemanticComponent(componentName)) {
|
|
33
|
+
traverse(child.type(child.props));
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (componentName === 'ConceptGraph') {
|
|
38
|
+
if (child.props.root) {
|
|
39
|
+
result.meta.rootId = child.props.root;
|
|
40
|
+
}
|
|
41
|
+
Children.forEach(child.props.children, traverse);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (componentName === 'ConceptNode') {
|
|
46
|
+
const nodeData = parseConceptNode(child);
|
|
47
|
+
result.nodes.push(nodeData);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (componentName === 'Relation') {
|
|
52
|
+
result.relations.push({
|
|
53
|
+
from: child.props.from,
|
|
54
|
+
to: child.props.to,
|
|
55
|
+
type: child.props.type || 'depends-on',
|
|
56
|
+
label: child.props.label,
|
|
57
|
+
description: child.props.description || child.props.children || ''
|
|
58
|
+
});
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (child.props && child.props.children) {
|
|
63
|
+
Children.forEach(child.props.children, traverse);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (explainPageElement.props && explainPageElement.props.children) {
|
|
68
|
+
Children.forEach(explainPageElement.props.children, traverse);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return result;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function unwrapComponent(element) {
|
|
75
|
+
let current = element;
|
|
76
|
+
while (
|
|
77
|
+
current &&
|
|
78
|
+
isValidElement(current) &&
|
|
79
|
+
typeof current.type === 'function' &&
|
|
80
|
+
!isSemanticComponent(getComponentName(current))
|
|
81
|
+
) {
|
|
82
|
+
current = current.type(current.props);
|
|
83
|
+
}
|
|
84
|
+
return current;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const SEMANTIC_COMPONENTS = new Set([
|
|
88
|
+
'ExplainPage',
|
|
89
|
+
'ConceptGraph',
|
|
90
|
+
'ConceptNode',
|
|
91
|
+
'ConceptRef',
|
|
92
|
+
'Children',
|
|
93
|
+
'Relation',
|
|
94
|
+
'Overview',
|
|
95
|
+
'Definition',
|
|
96
|
+
'Mechanism',
|
|
97
|
+
'Input',
|
|
98
|
+
'Output',
|
|
99
|
+
'Prerequisite',
|
|
100
|
+
'Implementation',
|
|
101
|
+
'Example',
|
|
102
|
+
'Counterexample',
|
|
103
|
+
'Boundary',
|
|
104
|
+
'Glossary',
|
|
105
|
+
'Mermaid',
|
|
106
|
+
'RelationMap',
|
|
107
|
+
'Insight',
|
|
108
|
+
'NoteGrid',
|
|
109
|
+
'Stack',
|
|
110
|
+
'Grid',
|
|
111
|
+
'Split',
|
|
112
|
+
'Tabs',
|
|
113
|
+
'RelationPath',
|
|
114
|
+
'LearningObjectives',
|
|
115
|
+
'KeyQuestion',
|
|
116
|
+
'Evidence',
|
|
117
|
+
'Invariant',
|
|
118
|
+
'FailureMode',
|
|
119
|
+
'Tradeoff',
|
|
120
|
+
]);
|
|
121
|
+
|
|
122
|
+
function isSemanticComponent(name) {
|
|
123
|
+
return SEMANTIC_COMPONENTS.has(name);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function getComponentName(element) {
|
|
127
|
+
if (!element || !element.type) return '';
|
|
128
|
+
if (typeof element.type === 'string') return element.type;
|
|
129
|
+
return element.type.displayName || element.type.name || '';
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function parseConceptNode(nodeElement) {
|
|
133
|
+
const props = nodeElement.props;
|
|
134
|
+
const node = {
|
|
135
|
+
id: props.id,
|
|
136
|
+
title: props.title || props.id,
|
|
137
|
+
level: props.level || 'L2',
|
|
138
|
+
parent: props.parent !== undefined ? props.parent : null,
|
|
139
|
+
children: [],
|
|
140
|
+
summary: props.summary || '',
|
|
141
|
+
overview: null,
|
|
142
|
+
definition: null,
|
|
143
|
+
mechanism: null,
|
|
144
|
+
input: props.input || null,
|
|
145
|
+
output: props.output || null,
|
|
146
|
+
prerequisites: [],
|
|
147
|
+
implementation: null,
|
|
148
|
+
examples: [],
|
|
149
|
+
counterexamples: [],
|
|
150
|
+
boundaries: [],
|
|
151
|
+
glossary: [],
|
|
152
|
+
customSections: []
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
Children.forEach(props.children, child => {
|
|
156
|
+
if (!child || !isValidElement(child)) return;
|
|
157
|
+
const name = getComponentName(child);
|
|
158
|
+
|
|
159
|
+
switch (name) {
|
|
160
|
+
case 'Overview':
|
|
161
|
+
node.overview = child.props.children;
|
|
162
|
+
if (!node.summary && typeof child.props.children === 'string') {
|
|
163
|
+
node.summary = child.props.children.trim();
|
|
164
|
+
}
|
|
165
|
+
break;
|
|
166
|
+
case 'Definition':
|
|
167
|
+
node.definition = child.props.children;
|
|
168
|
+
break;
|
|
169
|
+
case 'Mechanism':
|
|
170
|
+
node.mechanism = child.props.children;
|
|
171
|
+
break;
|
|
172
|
+
case 'Input':
|
|
173
|
+
node.input = child.props.children;
|
|
174
|
+
break;
|
|
175
|
+
case 'Output':
|
|
176
|
+
node.output = child.props.children;
|
|
177
|
+
break;
|
|
178
|
+
case 'Prerequisite':
|
|
179
|
+
if (typeof child.props.children === 'string') {
|
|
180
|
+
node.prerequisites.push(child.props.children);
|
|
181
|
+
} else if (Array.isArray(child.props.children)) {
|
|
182
|
+
node.prerequisites.push(...child.props.children);
|
|
183
|
+
} else {
|
|
184
|
+
node.prerequisites.push(child.props.children);
|
|
185
|
+
}
|
|
186
|
+
break;
|
|
187
|
+
case 'Implementation':
|
|
188
|
+
node.implementation = {
|
|
189
|
+
language: child.props.language || 'text',
|
|
190
|
+
title: child.props.title || '代码实现',
|
|
191
|
+
code: child.props.children
|
|
192
|
+
};
|
|
193
|
+
break;
|
|
194
|
+
case 'Example':
|
|
195
|
+
node.examples.push({
|
|
196
|
+
title: child.props.title || '典型示例',
|
|
197
|
+
content: child.props.children
|
|
198
|
+
});
|
|
199
|
+
break;
|
|
200
|
+
case 'Counterexample':
|
|
201
|
+
node.counterexamples.push({
|
|
202
|
+
title: child.props.title || '边界反例 / 常见误区',
|
|
203
|
+
content: child.props.children
|
|
204
|
+
});
|
|
205
|
+
break;
|
|
206
|
+
case 'Boundary':
|
|
207
|
+
node.boundaries.push({
|
|
208
|
+
title: child.props.title || '边界条件 / 约束',
|
|
209
|
+
content: child.props.children
|
|
210
|
+
});
|
|
211
|
+
break;
|
|
212
|
+
case 'Glossary':
|
|
213
|
+
node.glossary.push({
|
|
214
|
+
term: child.props.term,
|
|
215
|
+
definition: child.props.children
|
|
216
|
+
});
|
|
217
|
+
break;
|
|
218
|
+
case 'Children':
|
|
219
|
+
Children.forEach(child.props.children, ref => {
|
|
220
|
+
if (isValidElement(ref) && (getComponentName(ref) === 'ConceptRef' || ref.props.id)) {
|
|
221
|
+
node.children.push(ref.props.id);
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
break;
|
|
225
|
+
case 'ConceptRef':
|
|
226
|
+
if (child.props.id) {
|
|
227
|
+
node.children.push(child.props.id);
|
|
228
|
+
}
|
|
229
|
+
break;
|
|
230
|
+
default:
|
|
231
|
+
// Semantic presentation components inside node
|
|
232
|
+
node.customSections.push(child);
|
|
233
|
+
break;
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
return node;
|
|
238
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
export const RELATION_TYPES = {
|
|
2
|
+
'parent-child': {
|
|
3
|
+
label: '父子层级',
|
|
4
|
+
description: '表达概念归属与分解层级',
|
|
5
|
+
color: '#87a6ff',
|
|
6
|
+
strokeDasharray: 'none',
|
|
7
|
+
hasArrow: true,
|
|
8
|
+
isTree: true
|
|
9
|
+
},
|
|
10
|
+
'prerequisite': {
|
|
11
|
+
label: '前置知识',
|
|
12
|
+
description: '理解当前概念所需的前置基础',
|
|
13
|
+
color: '#f1bc74',
|
|
14
|
+
strokeDasharray: '4 4',
|
|
15
|
+
hasArrow: true,
|
|
16
|
+
isTree: false
|
|
17
|
+
},
|
|
18
|
+
'causes': {
|
|
19
|
+
label: '因果推动',
|
|
20
|
+
description: '引起或触发后续状态变化',
|
|
21
|
+
color: '#ef8585',
|
|
22
|
+
strokeDasharray: 'none',
|
|
23
|
+
hasArrow: true,
|
|
24
|
+
isTree: false
|
|
25
|
+
},
|
|
26
|
+
'produces': {
|
|
27
|
+
label: '产出生成',
|
|
28
|
+
description: '阶段处理后产出的产物或实体',
|
|
29
|
+
color: '#72d0a1',
|
|
30
|
+
strokeDasharray: 'none',
|
|
31
|
+
hasArrow: true,
|
|
32
|
+
isTree: false
|
|
33
|
+
},
|
|
34
|
+
'uses': {
|
|
35
|
+
label: '消费使用',
|
|
36
|
+
description: '调用或引用其他概念与数据',
|
|
37
|
+
color: '#38bdf8',
|
|
38
|
+
strokeDasharray: '6 3',
|
|
39
|
+
hasArrow: true,
|
|
40
|
+
isTree: false
|
|
41
|
+
},
|
|
42
|
+
'implements': {
|
|
43
|
+
label: '实现关系',
|
|
44
|
+
description: '具体机制或代码实现特定抽象',
|
|
45
|
+
color: '#c084fc',
|
|
46
|
+
strokeDasharray: 'none',
|
|
47
|
+
hasArrow: true,
|
|
48
|
+
isTree: false
|
|
49
|
+
},
|
|
50
|
+
'contrasts': {
|
|
51
|
+
label: '对比关系',
|
|
52
|
+
description: '概念间的异同对照或对立维度',
|
|
53
|
+
color: '#fb923c',
|
|
54
|
+
strokeDasharray: '2 2',
|
|
55
|
+
hasArrow: false,
|
|
56
|
+
isTree: false
|
|
57
|
+
},
|
|
58
|
+
'depends-on': {
|
|
59
|
+
label: '依赖关系',
|
|
60
|
+
description: '运行或生效依赖外部条件',
|
|
61
|
+
color: '#94a3b8',
|
|
62
|
+
strokeDasharray: '5 5',
|
|
63
|
+
hasArrow: true,
|
|
64
|
+
isTree: false
|
|
65
|
+
},
|
|
66
|
+
'exception-of': {
|
|
67
|
+
label: '异常/反例',
|
|
68
|
+
description: '特殊情况、破坏假定的边界或反例',
|
|
69
|
+
color: '#f43f5e',
|
|
70
|
+
strokeDasharray: '3 3',
|
|
71
|
+
hasArrow: true,
|
|
72
|
+
isTree: false
|
|
73
|
+
},
|
|
74
|
+
'precedes': {
|
|
75
|
+
label: '时序先后',
|
|
76
|
+
description: '时间或处理流水线的前后相继',
|
|
77
|
+
color: '#2dd4bf',
|
|
78
|
+
strokeDasharray: 'none',
|
|
79
|
+
hasArrow: true,
|
|
80
|
+
isTree: false
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
export const LEVEL_DEFS = {
|
|
85
|
+
L0: { name: '全局概览', tag: 'L0 · 全局概览', desc: '系统全貌与全局定位', color: '#818cf8' },
|
|
86
|
+
L1: { name: '主要阶段 / 子系统', tag: 'L1 · 子系统', desc: '主要生命周期阶段或子系统划分', color: '#38bdf8' },
|
|
87
|
+
L2: { name: '局部机制', tag: 'L2 · 局部机制', desc: '具体工作机制与逻辑流动', color: '#34d399' },
|
|
88
|
+
L3: { name: '实现细节', tag: 'L3 · 实现细节', desc: '算法、数据结构或代码实现', color: '#fbbf24' },
|
|
89
|
+
L4: { name: '边界与反例', tag: 'L4 · 边界反例', desc: '边界情况、异常分支与典型反例', color: '#f87171' }
|
|
90
|
+
};
|