concept-atlas-dense-explain 0.3.1 → 0.4.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/cli.mjs CHANGED
@@ -1,8 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import { access, constants, mkdir, readFile, rm, rename, writeFile } from 'node:fs/promises';
2
+ import { access, constants, copyFile, cp, mkdir, readFile, rm, rename, writeFile } from 'node:fs/promises';
3
+ import { existsSync } from 'node:fs';
3
4
  import path from 'node:path';
4
5
  import { build } from 'vite';
5
6
  import { fileURLToPath } from 'node:url';
7
+ import { validateMdxSource, countBySeverity } from '../template/src/model/validate-content.js';
6
8
 
7
9
  const packageRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
8
10
  const templateRoot = path.join(packageRoot, 'template');
@@ -10,9 +12,11 @@ const args = process.argv.slice(2);
10
12
 
11
13
  function usage() {
12
14
  console.log('Usage:');
13
- console.log(' npx concept-atlas-dense-explain <input.mdx> [--mode atlas|scroll] [-o output.html] [--force]');
15
+ console.log(' npx concept-atlas-dense-explain <input.mdx> [--mode atlas|scroll] [-o output.html] [--force] [--json] [--no-validate]');
14
16
  console.log(' npx concept-atlas-dense-explain render <input.mdx> [--mode atlas|scroll] [-o output.html] [--force]');
17
+ console.log(' npx concept-atlas-dense-explain validate <input.mdx> [--mode atlas|scroll] [--strict] [--json]');
15
18
  console.log(' npx concept-atlas-dense-explain create <output.mdx> [--mode atlas|scroll] [--force]');
19
+ console.log(' npx concept-atlas-dense-explain guide [--mode atlas|scroll] [-o output.mdx] [--force]');
16
20
  }
17
21
 
18
22
  async function exists(filePath) {
@@ -27,10 +31,62 @@ function flagValue(flags, names) {
27
31
  return null;
28
32
  }
29
33
 
30
- const command = ['help', 'create', 'new', 'render'].includes(args[0]) ? args.shift() : 'render';
34
+ function fail(message) {
35
+ console.error(message);
36
+ usage();
37
+ process.exit(1);
38
+ }
39
+
40
+ function printDiagnostics(source, options, { json }) {
41
+ const result = validateMdxSource(source, options);
42
+ if (json) {
43
+ process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
44
+ return result;
45
+ }
46
+ const { diagnostics, carrier, stats } = result;
47
+ for (const item of diagnostics) {
48
+ const label = item.severity === 'error' ? 'error' : 'warn ';
49
+ const where = `${item.line}:${item.column}`;
50
+ console.error(`${label} ${where} ${item.code} ${item.message}`);
51
+ }
52
+ const { error, warning } = countBySeverity(diagnostics);
53
+ const scope = carrier ? `${carrier} · ${stats.nodes} 节点 / ${stats.relations} 关系` : '未识别载体';
54
+ if (error) console.error(`校验失败:${error} 个错误,${warning} 个警告(${scope})`);
55
+ else if (warning) console.error(`校验通过:${warning} 个警告(${scope})`);
56
+ else console.error(`校验通过:无问题(${scope})`);
57
+ return result;
58
+ }
59
+
60
+ const command = ['help', 'create', 'new', 'render', 'validate', 'guide'].includes(args[0]) ? args.shift() : 'render';
31
61
 
32
62
  if (command === 'help') { usage(); process.exit(0); }
33
63
 
64
+ if (command === 'guide') {
65
+ const mode = flagValue(args, ['--mode']) || 'atlas';
66
+ if (!['atlas', 'scroll'].includes(mode)) fail(`Unknown mode: ${mode}`);
67
+ const output = path.resolve(flagValue(args, ['-o', '--output']) || `concept-atlas-${mode}-guide.mdx`);
68
+ if (await exists(output) && !args.includes('--force')) {
69
+ console.error(`Refusing to overwrite ${output}; pass --force to replace it.`);
70
+ process.exit(1);
71
+ }
72
+ const source = path.join(templateRoot, 'guides', `${mode}-guide.mdx`);
73
+ if (!(await exists(source))) {
74
+ console.error(`Guide for mode "${mode}" is missing from the package.`);
75
+ process.exit(1);
76
+ }
77
+ await mkdir(path.dirname(output), { recursive: true });
78
+ await copyFile(source, output);
79
+ const assetsSource = path.join(templateRoot, 'guides', 'assets');
80
+ const assetsTarget = path.join(path.dirname(output), 'assets');
81
+ if (await exists(assetsSource) && path.resolve(assetsSource) !== path.resolve(assetsTarget) && (args.includes('--force') || !(await exists(assetsTarget)))) {
82
+ await cp(assetsSource, assetsTarget, { recursive: true, force: true });
83
+ console.log(`Copied guide assets to ${assetsTarget}`);
84
+ }
85
+ console.log(`Wrote ${mode} component guide: ${output}`);
86
+ console.log('Read it to learn every component and its props, then write your own MDX.');
87
+ process.exit(0);
88
+ }
89
+
34
90
  if (command === 'create' || command === 'new') {
35
91
  const output = args[0] ? path.resolve(args[0]) : null;
36
92
  const mode = flagValue(args, ['--mode']) || 'atlas';
@@ -91,9 +147,30 @@ if (command === 'create' || command === 'new') {
91
147
  `;
92
148
  await writeFile(output, template, 'utf8');
93
149
  console.log(`Created ${mode} MDX template: ${output}`);
150
+ console.log(`Tip: run "npx concept-atlas-dense-explain guide --mode ${mode}" for a full component reference.`);
94
151
  process.exit(0);
95
152
  }
96
153
 
154
+ const json = args.includes('--json');
155
+ const strict = args.includes('--strict');
156
+ const skipValidate = args.includes('--no-validate');
157
+
158
+ if (command === 'validate') {
159
+ const target = args[0] ? path.resolve(args[0]) : null;
160
+ if (!target || path.extname(target).toLowerCase() !== '.mdx' || !(await exists(target))) {
161
+ fail('Provide an existing .mdx file to validate.');
162
+ }
163
+ const source = await readFile(target, 'utf8');
164
+ const modeFlag = flagValue(args, ['--mode']);
165
+ const result = printDiagnostics(source, {
166
+ filePath: target,
167
+ mode: modeFlag || null,
168
+ strict,
169
+ assetExists: spec => existsSync(path.resolve(path.dirname(target), spec)),
170
+ }, { json });
171
+ process.exit(countBySeverity(result.diagnostics).error ? 1 : 0);
172
+ }
173
+
97
174
  if (args[0] && args[0].toLowerCase() === 'render') args.shift();
98
175
  const input = args[0] ? path.resolve(args[0]) : null;
99
176
  const modeFlag = flagValue(args, ['--mode']);
@@ -107,7 +184,20 @@ if (!input || path.extname(input).toLowerCase() !== '.mdx' || !(await exists(inp
107
184
  }
108
185
 
109
186
  const source = await readFile(input, 'utf8');
110
- const mode = modeFlag || (/<ScrollDocument\b/.test(source) ? 'scroll' : /<ExplainPage\b|<ConceptGraph\b/.test(source) ? 'atlas' : null);
187
+ const validation = printDiagnostics(source, {
188
+ filePath: input,
189
+ mode: modeFlag || null,
190
+ strict,
191
+ assetExists: spec => existsSync(path.resolve(path.dirname(input), spec)),
192
+ }, { json });
193
+ const { error: errorCount } = countBySeverity(validation.diagnostics);
194
+
195
+ if (errorCount && !skipValidate) {
196
+ console.error('内容校验未通过,已停止构建。修复后重试,或用 --no-validate 强制构建。');
197
+ process.exit(1);
198
+ }
199
+
200
+ const mode = modeFlag || validation.carrier;
111
201
  if (!mode || !['atlas', 'scroll'].includes(mode)) {
112
202
  console.error('Could not detect the MDX carrier; choose --mode atlas or --mode scroll.');
113
203
  process.exit(1);
package/package.json CHANGED
@@ -1,11 +1,14 @@
1
1
  {
2
2
  "name": "concept-atlas-dense-explain",
3
- "version": "0.3.1",
3
+ "version": "0.4.0",
4
4
  "description": "Portable dense-explanation skill and MDX concept atlas template",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "concept-atlas-dense-explain": "bin/cli.mjs"
8
8
  },
9
+ "scripts": {
10
+ "prepack": "node ../../scripts/sync-template.mjs"
11
+ },
9
12
  "files": [
10
13
  "bin",
11
14
  "template",
@@ -16,6 +19,7 @@
16
19
  "@vitejs/plugin-react": "^4.3.4",
17
20
  "clsx": "^2.1.1",
18
21
  "d3": "^7.9.0",
22
+ "katex": "^0.16.47",
19
23
  "lucide-react": "^0.475.0",
20
24
  "mermaid": "^11.17.2",
21
25
  "react": "^18.3.1",
@@ -30,5 +34,8 @@
30
34
  "dense-explain",
31
35
  "concept-map"
32
36
  ],
37
+ "publishConfig": {
38
+ "access": "public"
39
+ },
33
40
  "license": "MIT"
34
41
  }
package/skill/SKILL.md CHANGED
@@ -9,21 +9,52 @@ Use the `concept-atlas-dense-explain` npm CLI. This skill is intentionally light
9
9
 
10
10
  ## Workflow
11
11
 
12
- 1. Choose the page shell before writing MDX. `atlas` uses a concept graph with node navigation; `scroll` uses a continuous document flow. The component library is shared: information-density components such as `Insight`, `Flow`, `FrameworkModel`, `MatrixModel`, `Mermaid`, `RelationMap`, `NoteGrid`, `Callout`, `Details`, `Columns`, `Grid`, `Stack`, and `Tabs` can be used wherever their meaning fits. Recommend `atlas` when the reader needs concept navigation or a relation graph; recommend `scroll` for a conventional reading flow.
13
- 2. When a starting point is useful, create a single MDX file with `npx concept-atlas-dense-explain create <file>.mdx --mode atlas|scroll`, then rewrite it with the AI.
14
- 3. For B, write semantic MDX to the user-selected `.mdx` file. Include one `L0`, multiple `L1` branches, useful depth, `Children`/`ConceptRef`, and labeled `Relation`s. This content renders through the interactive atlas entry.
15
- 4. For `scroll`, use `ScrollDocument`, `ScrollHeader`, `ScrollSection`, `ScrollProse`, and `ScrollGrid` as the document shell. Put shared information components inside sections as needed.
16
- 5. For `atlas`, use `ExplainPage`, `ConceptGraph`, `ConceptNode`, `Children`, `ConceptRef`, and `Relation` as the graph shell. Put shared information components inside nodes as needed.
17
- 6. Do not force one MDX file to be both page shells. This is a shell distinction, not a component-library distinction; convert only the outer structure when changing carriers.
18
- 7. Compile directly with `npx concept-atlas-dense-explain <file>.mdx --mode atlas|scroll`. The output is a standalone `.html` beside the MDX unless `-o` is provided. The mode can be detected from the top-level carrier, but specify it when the file is ambiguous.
19
- 8. Report the selected mode, output path, and limitations. Do not claim interactions that were not verified.
20
-
21
- ## Content rules
22
-
23
- - Keep MDX semantic; do not write CSS, coordinates, SVG, or replacement application code.
24
- - Give important nodes a claim-like title, a one-sentence summary, evidence, and meaningful components.
25
- - Treat the built-in component library as shared across carriers; choose components by the relationship they express, not by the page shell.
26
- - Keep the outer shell valid for the selected carrier and keep component props valid; the renderer does not convert arbitrary JSX or CSS into a semantic component automatically.
27
- - For array props, use the documented object shapes: `Flow.steps` accepts strings or `{ title, description }`, `Timeline.events` uses `{ label, content }`, table rows use `string[][]`, and model data uses arrays of named objects.
28
- - For continuous reading, configure spacing on the shell with `ScrollDocument spacing="compact|comfortable|airy"`; use `ScrollSection spacing="..."` only for a local override instead of adding manual margins.
29
- - If the CLI or npm registry is unavailable, report the blocker instead of copying the implementation into the skill.
12
+ 1. Choose the page shell before writing MDX. `atlas` uses a concept graph with node navigation; `scroll` uses a continuous document flow. Recommend `atlas` when the reader needs concept navigation or a relation graph; recommend `scroll` for a conventional reading flow. The component library is shared across both shells.
13
+ 2. **Learn the component library from the canonical guide before authoring.** Generate the guide for the chosen shell and read it:
14
+ ```bash
15
+ npx concept-atlas-dense-explain guide --mode atlas -o concept-atlas-atlas-guide.mdx
16
+ npx concept-atlas-dense-explain guide --mode scroll -o concept-atlas-scroll-guide.mdx
17
+ ```
18
+ Each guide is a real, compilable MDX file that demonstrates every component and its exact props. Copy prop shapes from the guide instead of guessing. Delete the guide file afterwards if it is only a reference.
19
+ 3. When a starting point is useful, create a starter with `npx concept-atlas-dense-explain create <file>.mdx --mode atlas|scroll`, then rewrite it.
20
+ 4. Write semantic MDX to the user-selected `.mdx` file (see Authoring rules below).
21
+ 5. Validate the content before rendering:
22
+ ```bash
23
+ npx concept-atlas-dense-explain validate <file>.mdx --mode atlas|scroll
24
+ npx concept-atlas-dense-explain validate <file>.mdx --json # machine-readable
25
+ ```
26
+ Read the diagnostics, fix the errors, and repeat. Warnings do not block the build.
27
+ 6. Compile with `npx concept-atlas-dense-explain <file>.mdx --mode atlas|scroll`. The output is a standalone `.html` beside the MDX unless `-o` is provided. Validation errors stop the build; use `--no-validate` only to force a build of knowingly broken content.
28
+ 7. Report the selected mode, output path, and limitations. Do not claim interactions that were not verified.
29
+
30
+ ## Carriers
31
+
32
+ - `atlas`: `ExplainPage` → `ConceptGraph` → `ConceptNode` (+ `Children`/`ConceptRef`, `Relation`). One `L0` root, several `L1` branches, useful depth down to `L3`/`L4`. Nodes hold shared components.
33
+ - `scroll`: `ScrollDocument` → `ScrollHeader` + `ScrollSection` (+ `ScrollProse`, `ScrollGrid`). Shared components go inside sections. The shell auto-builds a table of contents and reading progress from section titles.
34
+ - Never write one MDX file as both shells. Convert only the outer structure when switching carriers.
35
+
36
+ ## Component families
37
+
38
+ - Node semantics: `Overview`, `Definition`, `Mechanism`, `Implementation`, `Boundary`, `Example`, `Counterexample`, `Prerequisite`, `Input`, `Output`, `Glossary`
39
+ - Argument and evidence: `Evidence`, `Invariant`, `FailureMode`, `Tradeoff`, `LearningObjectives`, `KeyQuestion`
40
+ - Information models: `Flow`, `Timeline`, `Compare`, `DecisionMatrix`, `FrameworkModel`, `MatrixModel`, `FormulaModel`, `PyramidModel`, `FunnelModel`
41
+ - Reading and layout: `Insight`, `Callout`, `Details`, `NoteGrid`, `Tabs`, `Columns`, `Stack`, `Grid`, `Split`, `ScrollGrid`
42
+ - Graphics and extensions: `Mermaid`, `RelationMap`, `RelationPath`, `Math`, `MathBlock`, `Chart`, `Figure`, `Cite`, `References`
43
+
44
+ ## Authoring rules
45
+
46
+ - Keep MDX semantic; never write CSS, coordinates, SVG, or replacement application code.
47
+ - Give important nodes a claim-like title, a one-sentence `summary`, and substance (`Definition`, `Mechanism`, `Example`, `Boundary`, `Evidence`, a model, a chart, or math).
48
+ - Array props must be arrays of objects, e.g. `Flow steps={[{title, description}]}`, `Timeline events={[{label, content}]}`, `MatrixModel cells={[{title, description, tone}]}`, `Chart data={[{label, value}]}`, `References items={[{id, authors, year, title, url, source}]}`. The validator warns when an array prop receives a string or non-array.
49
+ - **Math**: because MDX parses `{ ... }` in children as expressions, pass LaTeX through the `formula` prop whenever it contains braces or backslashes: `<Math formula="r_{\text{ann}} = (1 + r)^{12} - 1" />` and `<MathBlock formula="I(x) = -\log_2 p(x)" variables={[...]} />`. Plain children are fine only for brace-free LaTeX such as `<Math>\log_2 N</Math>`.
50
+ - **Chart**: `type` is `bar` | `line` | `pie`; use `data` for bar/pie and `labels` + `series` for line. Charts follow the active theme colors.
51
+ - **Figure**: a relative `src` (`./assets/diagram.png`) is inlined as base64 at build time so the HTML stays standalone; remote `http(s)` URLs are left as links. Always give `alt`; add `label` and `caption` for a numbered caption.
52
+ - **Cite/References**: `<Cite id="..." />` renders `[n]` from the position of the matching item in `<References items={...} />`. In `scroll`, put `References` anywhere; in `atlas`, keep the cites and the `References` block inside the same node (node content renders only when the node is open).
53
+ - Continuous reading is configurable on the shell: `spacing="compact|comfortable|airy"` for rhythm and `fontSize="compact|normal|large|xlarge"` (or numeric `scale` / `lineHeight`) for text size. Do not add manual margins or font sizes.
54
+ - Prefer one component per information job; do not restate the same text across `Overview`, `Definition`, and `Insight`.
55
+
56
+ ## Validation diagnostics
57
+
58
+ `validate` and the build report `CODE line:column message` lines. Common error codes to fix before building: `UNKNOWN_COMPONENT`, `CARRIER_MISSING`, `CARRIER_CONFLICT`, `CARRIER_MODE_MISMATCH`, `NODE_MISSING_ID`, `DUPLICATE_NODE_ID`, `MISSING_PARENT`, `GRAPH_ROOT_UNRESOLVED`, `REF_UNRESOLVED`, `RELATION_FROM_UNRESOLVED`, `RELATION_TO_UNRESOLVED`, `ASSET_MISSING`. Warnings such as `NODE_MISSING_SUMMARY`, `UNKNOWN_LEVEL`, `PROP_EXPECTS_ARRAY`, `MATH_CHILDREN_BRACES`, and `RELATION_MISSING_LABEL` are quality signals.
59
+
60
+ If the CLI or npm registry is unavailable, report the blocker instead of copying the implementation into the skill.
@@ -0,0 +1,47 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 240" role="img" aria-label="Concept zoom levels">
3
+ <defs>
4
+ <linearGradient id="band" x1="0" y1="0" x2="1" y2="0">
5
+ <stop offset="0" stop-color="#6366f1" stop-opacity="0.9"/>
6
+ <stop offset="1" stop-color="#06b6d4" stop-opacity="0.75"/>
7
+ </linearGradient>
8
+ </defs>
9
+ <rect x="0" y="0" width="720" height="240" rx="14" fill="#0f172a"/>
10
+ <g fill="none" stroke="#334155" stroke-width="1">
11
+ <line x1="40" y1="176" x2="680" y2="176"/>
12
+ </g>
13
+ <g font-family="Segoe UI, Helvetica, Arial, sans-serif" fill="#e2e8f0" font-size="13">
14
+ <g>
15
+ <rect x="48" y="60" width="152" height="86" rx="8" fill="url(#band)"/>
16
+ <text x="124" y="96" text-anchor="middle" font-size="15" font-weight="700">L0</text>
17
+ <text x="124" y="118" text-anchor="middle" font-size="12">全局主题</text>
18
+ </g>
19
+ <g>
20
+ <rect x="236" y="76" width="152" height="70" rx="8" fill="#1e293b" stroke="#475569"/>
21
+ <text x="312" y="106" text-anchor="middle" font-size="15" font-weight="700">L1</text>
22
+ <text x="312" y="126" text-anchor="middle" font-size="12">主要分支</text>
23
+ </g>
24
+ <g>
25
+ <rect x="424" y="92" width="152" height="54" rx="8" fill="#1e293b" stroke="#475569"/>
26
+ <text x="500" y="115" text-anchor="middle" font-size="15" font-weight="700">L2</text>
27
+ <text x="500" y="134" text-anchor="middle" font-size="12">局部机制</text>
28
+ </g>
29
+ <g>
30
+ <rect x="612" y="96" width="0" height="0"/>
31
+ </g>
32
+ </g>
33
+ <g fill="#94a3b8" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="11">
34
+ <text x="48" y="200">L3 实现细节与 L4 边界反例继续向右下钻</text>
35
+ </g>
36
+ <g fill="none" stroke="#64748b" stroke-width="1.5" marker-end="url(#arrow)">
37
+ </g>
38
+ <defs>
39
+ <marker id="arrow" markerWidth="8" markerHeight="8" refX="6" refY="3" orient="auto">
40
+ <path d="M0,0 L6,3 L0,6 Z" fill="#64748b"/>
41
+ </marker>
42
+ </defs>
43
+ <g fill="none" stroke="#64748b" stroke-width="1.5">
44
+ <line x1="200" y1="103" x2="232" y2="111" marker-end="url(#arrow)"/>
45
+ <line x1="388" y1="111" x2="420" y2="119" marker-end="url(#arrow)"/>
46
+ </g>
47
+ </svg>
@@ -0,0 +1,158 @@
1
+ <ExplainPage id="components-demo" title="Concept Atlas 组件展厅" summary="一页看懂框架提供的全部组件:从知识结构、语义内容到公式、图表、配图与引用。" layout="editorial" density="reading">
2
+ <ConceptGraph root="showroom">
3
+ <ConceptNode id="showroom" title="组件展厅:每个组件只承担一种表达职责" level="L0" input="知识内容与结构意图" output="可导航的概念页面与关系图" summary="组件不是装饰卡片,而是把定义、证据、模型、关系和布局分别交给最合适的语义工具。">
4
+ <Overview>本页专门展示框架能力。点击左侧或下方节点逐组查看组件效果,再切换右下角关系图观察它们如何组织成一套知识系统。</Overview>
5
+ <Definition>Concept Atlas 将 MDX 组件分为知识结构、内容语义、验证判断、经典模型、展示布局、关系可视化和扩展能力七个家族。</Definition>
6
+ <Input>主题、关键元素、证据、关系和布局意图。</Input>
7
+ <Output>节点探索页、全局关系图、可缩放 Mermaid 图、公式与图表以及可复用的模型表达。</Output>
8
+ <LearningObjectives items={['认识全部组件家族', '理解组件之间的职责边界', '选择合适组件编写自己的 MDX']} />
9
+ <KeyQuestion>我需要表达的是一个事实、一种关系,还是一种组织信息的结构?</KeyQuestion>
10
+ <Callout type="success" title="展厅导航">先看“知识结构”,再看“内容语义”和“经典模型”;最后打开“可视化与布局”和“扩展能力”,就能覆盖完整能力。</Callout>
11
+ <Children><ConceptRef id="structure-family" /><ConceptRef id="content-family" /><ConceptRef id="verification-family" /><ConceptRef id="concept-models" /><ConceptRef id="presentation-family" /><ConceptRef id="visual-family" /><ConceptRef id="extension-family" /></Children>
12
+ </ConceptNode>
13
+
14
+ <ConceptNode id="structure-family" title="知识结构组件:搭出可下钻的概念树" level="L1" parent="showroom" summary="页面、图谱、节点、子节点和跨节点关系共同构成导航骨架。">
15
+ <Definition>结构组件负责“有什么节点、节点如何归属、哪些概念彼此关联”,不负责替代节点内部的知识内容。</Definition>
16
+ <FrameworkModel title="结构组件家族" type="layers" elements={[{title:'ExplainPage',description:'页面元信息'},{title:'ConceptGraph',description:'图谱容器与根节点'},{title:'ConceptNode',description:'可下钻概念节点'},{title:'Children / ConceptRef',description:'树层级入口'},{title:'Relation',description:'跨分支语义边'}]} />
17
+ <Children><ConceptRef id="node-anatomy" /><ConceptRef id="relation-anatomy" /></Children>
18
+ </ConceptNode>
19
+ <ConceptNode id="node-anatomy" title="ConceptNode:一个节点承载一个可命名概念" level="L2" parent="structure-family" summary="节点用 id、title、level、parent、summary 和语义子组件描述一个认知单元。">
20
+ <Definition>ConceptNode 是所有内容的承载边界;L0 到 L4 分别对应全局概览、子系统、机制、实现细节和边界反例。</Definition>
21
+ <Example title="最小节点">`<ConceptNode id="idea" title="一个判断" level="L2" parent="root" summary="一句话结论">…</ConceptNode>`</Example>
22
+ <Glossary term="L0–L4">概念缩放层级,不是视觉字号等级。</Glossary>
23
+ </ConceptNode>
24
+ <ConceptNode id="relation-anatomy" title="Relation:把跨分支意义显式画出来" level="L2" parent="structure-family" summary="Relation 不改变树层级,而是表达前置、因果、产出、依赖和对比。">
25
+ <Definition>关系边使用白名单类型:prerequisite、causes、produces、uses、implements、contrasts、depends-on、exception-of、precedes。</Definition>
26
+ <RelationMap title="关系类型示例" items={[{from:'Definition',type:'implements',to:'ConceptNode',note:'内容具体化节点'},{from:'Evidence',type:'supports',to:'Claim',note:'由证据支撑判断'}]} />
27
+ <Boundary>不要用 Relation 表达 parent-child;父子边由 parent 和 Children 自动生成。</Boundary>
28
+ </ConceptNode>
29
+
30
+ <ConceptNode id="content-family" title="内容语义组件:让节点内容有明确职责" level="L1" parent="showroom" summary="不同语义组件分别回答是什么、怎么做、输入输出是什么以及边界在哪里。">
31
+ <Definition>内容组件将长段落拆为可识别的信息类型,NodeExplorer 会按语义将它们放入对应区域。</Definition>
32
+ <Stack gap="sm"><Definition>Definition:严格定义。</Definition><Mechanism>Mechanism:过程与因果。</Mechanism><Boundary>Boundary:限制与失效条件。</Boundary></Stack>
33
+ <Children><ConceptRef id="meaning-blocks" /><ConceptRef id="context-blocks" /></Children>
34
+ </ConceptNode>
35
+ <ConceptNode id="meaning-blocks" title="定义与机制:先说清楚是什么,再说如何发生" level="L2" parent="content-family" summary="Overview 建立直觉,Definition 收紧边界,Mechanism 解释过程。">
36
+ <Overview>Overview 适合首屏快速认知。</Overview>
37
+ <Definition>Definition 给出概念的必要特征。</Definition>
38
+ <Mechanism>Mechanism 解释输入如何经过状态变化产生输出。</Mechanism>
39
+ <Implementation language="javascript" title="Implementation 示例">const result = input.map(transform);</Implementation>
40
+ </ConceptNode>
41
+ <ConceptNode id="context-blocks" title="上下文组件:输入、输出、示例和术语补足理解" level="L2" parent="content-family" summary="Input、Output、Example、Counterexample、Prerequisite 和 Glossary 负责补全概念上下文。">
42
+ <Prerequisite>需要先理解“节点”和“关系”。</Prerequisite>
43
+ <Input>原始材料、问题和约束。</Input>
44
+ <Output>可验证的结论或下一步行动。</Output>
45
+ <Example title="正例">用具体案例说明抽象概念如何落地。</Example>
46
+ <Counterexample title="反例">指出看似相同但不满足定义的情况。</Counterexample>
47
+ <Glossary term="semantic">让术语拥有局部定义。</Glossary>
48
+ </ConceptNode>
49
+
50
+ <ConceptNode id="verification-family" title="验证与判断组件:让结论不止是漂亮话" level="L1" parent="showroom" summary="证据、不变量、故障模式、权衡和学习目标把内容连接到行动。">
51
+ <Definition>这一组组件专门呈现可检查的依据、稳定约束、风险、取舍和阅读目标。</Definition>
52
+ <Evidence command="npm run validate" observes="确认 MDX 节点数量、层级、关系类型与必需字段。" />
53
+ <Invariant title="组件契约">语义组件表达知识,模板负责布局;内容不直接写 CSS、坐标或 SVG。</Invariant>
54
+ <FailureMode symptom="页面看似完整但难以使用" cause="节点缺少摘要、边界或关系" evidence="检查节点是否只有一段泛化说明" remedy="补充证据与下钻入口" />
55
+ <Tradeoff title="信息密度与可读性" options={[{name:'展开细节',benefit:'证据更完整',cost:'首屏更长',when:'复杂机制'}, {name:'压缩摘要',benefit:'扫描更快',cost:'上下文较少',when:'总览节点'}]} />
56
+ <LearningObjectives items={['识别证据', '发现边界', '做出取舍']} />
57
+ </ConceptNode>
58
+
59
+ <ConceptNode id="concept-models" title="概念模型组件:把推理结构变成可读的形状" level="L1" parent="showroom" summary="五个模型组件分别表达并列、二维定位、变量关系、论证层级与收敛过程。">
60
+ <Definition>概念模型不是装饰图形。选择模型时先判断信息的组织关系,再选择能够让这层关系一眼可见的组件。</Definition>
61
+ <FrameworkModel title="FrameworkModel:并列要素" type="elements" elements={[{title:'问题',description:'明确要解释的对象'},{title:'机制',description:'说明变化如何发生'},{title:'证据',description:'给出可验证依据'}]} />
62
+ <MatrixModel title="MatrixModel:影响 / 成本" xLabel="实施成本" yLabel="预期影响" cells={[{title:'优先投入',description:'高影响 / 低成本',tone:'success'},{title:'审慎评估',description:'高影响 / 高成本',tone:'warn'},{title:'快速验证',description:'低影响 / 低成本'},{title:'暂缓处理',description:'低影响 / 高成本',tone:'danger'}]} />
63
+ <FormulaModel title="FormulaModel:用户价值" formula="用户价值 = 新体验 - 旧体验 - 替换成本" variables={[{symbol:'新体验',description:'方案带来的增量收益'},{symbol:'旧体验',description:'现有替代方案的价值'},{symbol:'替换成本',description:'学习、迁移与风险'}]} />
64
+ <PyramidModel title="PyramidModel:论证层级" levels={[{title:'结论',description:'需要读者带走的判断'},{title:'理由',description:'支撑判断的关键分组'},{title:'证据',description:'事实、数据与案例'}]} />
65
+ <FunnelModel title="FunnelModel:从输入到行动" steps={[{title:'收集',description:'汇集候选信息'},{title:'筛选',description:'排除不满足约束的项'},{title:'验证',description:'检查关键假设'},{title:'行动',description:'形成下一步决策'}]} />
66
+ <Children><ConceptRef id="framework-demo" /><ConceptRef id="matrix-demo" /><ConceptRef id="formula-demo" /><ConceptRef id="pyramid-funnel-demo" /></Children>
67
+ </ConceptNode>
68
+ <ConceptNode id="framework-demo" title="FrameworkModel:承载并列、阶段、层级与循环" level="L2" parent="concept-models" summary="一个组件通过 type 区分要素、阶段、层级和循环。">
69
+ <FrameworkModel title="PDCA 循环" type="cycle" elements={[{title:'Plan',description:'计划'},{title:'Do',description:'执行'},{title:'Check',description:'检查'},{title:'Act',description:'改进'}]} />
70
+ <Details summary="何时使用">当结构重点是元素数量和组织方式,而不是具体节点之间的关系时使用。</Details>
71
+ </ConceptNode>
72
+ <ConceptNode id="matrix-demo" title="MatrixModel:二维象限让优先级一眼可见" level="L2" parent="concept-models" summary="用 xLabel、yLabel 和 cells 描述两个维度及其组合。">
73
+ <MatrixModel title="影响 / 成本矩阵" xLabel="实施成本" yLabel="预期影响" cells={[{title:'优先投资',description:'高影响 / 低成本',tone:'success'},{title:'谨慎评估',description:'高影响 / 高成本',tone:'warn'},{title:'快速试验',description:'低影响 / 低成本'},{title:'暂缓',description:'低影响 / 高成本',tone:'danger'}]} />
74
+ <DecisionMatrix title="参数契约" headers={['参数','用途','形态']} rows={[['title','模型标题','string'],['cells','象限内容','array'],['tone','视觉提示','info / warn / danger']]} />
75
+ </ConceptNode>
76
+ <ConceptNode id="formula-demo" title="FormulaModel:把多变量关系压缩成一个判断" level="L2" parent="concept-models" summary="公式适合表达变量之间明确的加减乘除关系。">
77
+ <FormulaModel title="用户价值" formula="用户价值 = 新体验 − 旧体验 − 替换成本" variables={[{symbol:'新体验',description:'新方案带来的增量收益'},{symbol:'旧体验',description:'用户现有替代方案'},{symbol:'替换成本',description:'迁移与学习付出'}]} />
78
+ <NoteGrid notes={[{title:'优点',content:'关系直接'}, {title:'边界',content:'不替代真实测量'}]} />
79
+ </ConceptNode>
80
+ <ConceptNode id="pyramid-funnel-demo" title="PyramidModel 与 FunnelModel:分层和收敛是两种不同逻辑" level="L2" parent="concept-models" summary="金字塔从基础归纳到结论,漏斗从大量输入逐步筛选到行动。">
81
+ <PyramidModel title="金字塔论证" levels={[{title:'结论',description:'核心判断'},{title:'理由',description:'关键分组'},{title:'证据',description:'事实与案例'}]} />
82
+ <FunnelModel title="AIDA 漏斗" steps={[{title:'Attention',description:'注意'},{title:'Interest',description:'兴趣'},{title:'Desire',description:'欲望'},{title:'Action',description:'行动'}]} />
83
+ </ConceptNode>
84
+
85
+ <ConceptNode id="presentation-family" title="展示与布局组件:组织复杂内容的阅读节奏" level="L1" parent="showroom" summary="Compare、Flow、Timeline、Tabs、Grid 等组件负责并列、时序、折叠和空间组织。">
86
+ <Compare items={[{label:'流式阅读',rows:['信息密度','适用场景'],values:['高','定义与论证']},{label:'分栏对比',rows:['信息密度','适用场景'],values:['中','方案比较']}]} />
87
+ <Flow steps={['输入', '组织', '渲染', '验证']} />
88
+ <Timeline events={[{label:'T0',content:'定义目标'}, {label:'T1',content:'选择模型'}, {label:'T2',content:'验证结果'}]} />
89
+ <Children><ConceptRef id="layout-demo" /><ConceptRef id="compact-demo" /></Children>
90
+ </ConceptNode>
91
+ <ConceptNode id="layout-demo" title="布局原语:Stack、Grid、Split、Columns 让信息有秩序" level="L2" parent="presentation-family" summary="布局组件只表达空间意图,具体样式由模板统一接管。">
92
+ <Columns><Split ratio="1fr 1fr"><Callout title="左列">结论与定义。</Callout><Callout title="右列">证据与边界。</Callout></Split></Columns>
93
+ <Grid columns="auto" gap="sm"><Insight title="局部判断">Grid 中的短信息。</Insight><Insight title="另一判断" tone="warn">不要混用职责。</Insight></Grid>
94
+ </ConceptNode>
95
+ <ConceptNode id="compact-demo" title="压缩阅读:Tabs、Details、Callout、Insight、NoteGrid" level="L2" parent="presentation-family" summary="这些组件适合把结论、提示、细节和短信息压缩在首屏。">
96
+ <Tabs items={[{label:'结论',content:'先展示最重要的判断。'},{label:'证据',content:'再展开可验证依据。'}]} />
97
+ <Details summary="展开更多">Details 将次要信息收起,避免首屏过载。</Details>
98
+ <Insight title="关键判断" tone="success">一个组件只承担一种信息组织方式。</Insight>
99
+ </ConceptNode>
100
+
101
+ <ConceptNode id="visual-family" title="关系与可视化组件:把结构变成可探索画布" level="L1" parent="showroom" summary="Mermaid、RelationMap、RelationPath、Insight 和 NoteGrid 让关系、路径和结论可视化。">
102
+ <Mermaid title="组件协作流" width="100%" height="220px" chart={`flowchart LR
103
+ A[MDX 内容] --> B[语义组件]
104
+ B --> C[数据模型]
105
+ C --> D[节点探索]
106
+ C --> E[关系图谱]
107
+ D --> F[可观察结论]
108
+ E --> F
109
+ style A fill:#172554,stroke:#38bdf8,color:#e0f2fe
110
+ style F fill:#14532d,stroke:#34d399,color:#ecfdf5`} />
111
+ <RelationPath title="阅读路径" steps={[{level:'L0',node:'组件展厅',note:'总览',tone:'info'},{level:'L1',node:'模型组件',note:'选择结构',tone:'success'},{level:'L2',node:'MatrixModel',note:'定位决策',tone:'warn'}]} />
112
+ <RelationMap title="可视化摘要" items={[{from:'MDX',type:'produces',to:'Graph',note:'生成关系图'},{from:'Node',type:'uses',to:'Mermaid',note:'展示局部流程'}]} />
113
+ </ConceptNode>
114
+
115
+ <ConceptNode id="extension-family" title="扩展能力:公式、图表、图片与引用" level="L1" parent="showroom" summary="数学公式、数据图表、配图题注和参考文献四项能力,让讲解可以带上推导、数据与出处。">
116
+ <Definition>扩展组件把文本之外的证据接进页面:Math/MathBlock 渲染数学、Chart 绘制数据、Figure 承载配图、Cite/References 保留出处。</Definition>
117
+ <Children><ConceptRef id="math-demo" /><ConceptRef id="chart-demo" /><ConceptRef id="figure-demo" /><ConceptRef id="citation-demo" /></Children>
118
+ </ConceptNode>
119
+
120
+ <ConceptNode id="math-demo" title="Math 与 MathBlock:把推导写进正文" level="L2" parent="extension-family" summary="Math 用于行内符号,MathBlock 用于独立公式并支持变量说明。">
121
+ <Definition>两者都用 KaTeX 渲染 LaTeX。行内用 Math,独立成块并需要解释变量时用 MathBlock。</Definition>
122
+ <Overview>例如信息量的定义 <Math>\log_2 N</Math> 表示 N 种等可能结果所需要的比特数。</Overview>
123
+ <MathBlock title="香农信息量" formula="I(x) = -\log_2 p(x)" variables={[{symbol:'p(x)',description:'事件 x 发生的概率'},{symbol:'I(x)',description:'观察 x 后获得的信息量,单位为比特'}]} />
124
+ <Boundary>公式是 LaTeX 字符串,不要在里面写 Markdown 或 HTML。</Boundary>
125
+ </ConceptNode>
126
+
127
+ <ConceptNode id="chart-demo" title="Chart:用同一数据切换三种图形" level="L2" parent="extension-family" summary="bar、line、pie 三种类型共享数据形状,按比较、趋势或占比选择。">
128
+ <Definition>Chart 接收 data({label, value} 数组)或 series + labels,在 SVG 中绘制并跟随主题色。</Definition>
129
+ <Chart title="各阶段耗时" type="bar" unit="小时" data={[{label:'收集',value:6},{label:'分析',value:14},{label:'验证',value:9},{label:'落地',value:4}]} />
130
+ <Chart title="留存趋势" type="line" labels={['第1周','第2周','第3周','第4周']} series={[{name:'留存率',values:[100,72,58,49]}]} />
131
+ </ConceptNode>
132
+
133
+ <ConceptNode id="figure-demo" title="Figure:图片与题注一起出现" level="L2" parent="extension-family" summary="Figure 把图片、题注编号和说明绑定,构建时把本地图片内联进单文件。">
134
+ <Definition>相对路径的图片会在构建时转成 base64 内联,远程 URL 保持不变;label 提供“图 1”这样的编号。</Definition>
135
+ <Figure src="./assets/sample-diagram.svg" alt="概念缩放示意" label="图 1" caption="概念缩放:同一主题可以从 L0 全局逐层下钻到 L4 边界反例。" />
136
+ <Boundary>大图会显著增大单文件 HTML;截图类内容建议控制尺寸。</Boundary>
137
+ </ConceptNode>
138
+
139
+ <ConceptNode id="citation-demo" title="Cite 与 References:让结论可以追溯" level="L2" parent="extension-family" summary="行内用 Cite 标记引用,文末用 References 列出完整出处,编号自动对应。">
140
+ <Definition>Cite 的 id 与 References 条目的 id 对应,渲染时显示条目在列表中的序号,并链接到该条目。</Definition>
141
+ <Overview>信息密度的价值在于可验证性<Cite id="shannon1948" />,而可验证性依赖清晰的出处<Cite id="tufte1983" />。</Overview>
142
+ <Boundary>在 atlas 中,把 Cite 和 References 放在同一个节点内,否则未访问的节点里引用编号无法解析。</Boundary>
143
+ <References title="本节点引用" items={[{id:'shannon1948',authors:'Shannon, C. E.',year:'1948',title:'A Mathematical Theory of Communication',source:'Bell System Technical Journal'},{id:'tufte1983',authors:'Tufte, E. R.',year:'1983',title:'The Visual Display of Quantitative Information',source:'Graphics Press'}]} />
144
+ </ConceptNode>
145
+
146
+ <Relation from="structure-family" to="content-family" type="precedes" label="先搭骨架" />
147
+ <Relation from="content-family" to="verification-family" type="uses" label="补充证据" />
148
+ <Relation from="concept-models" to="presentation-family" type="implements" label="结构落地" />
149
+ <Relation from="verification-family" to="visual-family" type="produces" label="形成可见结论" />
150
+ <Relation from="visual-family" to="structure-family" type="depends-on" label="依赖图谱数据" />
151
+ <Relation from="extension-family" to="content-family" type="uses" label="补充证据形态" />
152
+ <Relation from="extension-family" to="verification-family" type="produces" label="提供可追溯依据" />
153
+ <Relation from="matrix-demo" to="formula-demo" type="contrasts" label="维度 vs 公式" />
154
+ <Relation from="pyramid-funnel-demo" to="framework-demo" type="contrasts" label="分层 vs 循环" />
155
+ <Relation from="math-demo" to="formula-demo" type="contrasts" label="LaTeX vs 纯文本公式" />
156
+ <Relation from="chart-demo" to="matrix-demo" type="contrasts" label="连续数据 vs 二维定位" />
157
+ </ConceptGraph>
158
+ </ExplainPage>
@@ -0,0 +1,101 @@
1
+ ---
2
+ title: scroll-guide
3
+ ---
4
+
5
+ <ScrollDocument spacing="comfortable" fontSize="normal">
6
+ <ScrollHeader title="Concept Atlas 连续阅读指南" label="连续阅读 · 组件参考">同一套语义组件可以脱离图谱和节点面板,按传统文档流连续阅读。本页同时是一份可运行的组件参考:每一节演示一个组件家族,正文保持高信息密度,模型在需要比较、推导或收敛时占满可用宽度。</ScrollHeader>
7
+ <ScrollSection title="先识别推理结构">
8
+ <ScrollProse>模型不是内容的装饰。它们分别处理并列要素、二维定位、变量关系、论证层级和筛选过程。先确认关系形状,读者才能用最短路径验证结论。</ScrollProse>
9
+ <LearningObjectives items={['按关系形状选择组件', '把结论与证据分开表达', '让每个区块承担不同的认知任务']} />
10
+ <KeyQuestion>我这一节要表达的是一个事实、一种关系,还是一种组织信息的结构?</KeyQuestion>
11
+ <ScrollGrid columns="3">
12
+ <FrameworkModel title="对象" type="elements" elements={[{title:'系统',description:'明确正在判断什么'},{title:'边界',description:'确定讨论范围'}]} />
13
+ <FrameworkModel title="约束" type="elements" elements={[{title:'时间',description:'决策窗口与反馈周期'},{title:'资源',description:'人力、预算和技术限制'}]} />
14
+ <FrameworkModel title="证据" type="elements" elements={[{title:'行为',description:'真实使用与任务结果'},{title:'数据',description:'可重复检查的观察'}]} />
15
+ </ScrollGrid>
16
+ </ScrollSection>
17
+
18
+ <ScrollSection title="在二维关系中定位选择">
19
+ <ScrollProse>当候选方案同时受两个变量约束时,矩阵比线性列表更容易暴露优先级。</ScrollProse>
20
+ <ScrollGrid columns="2">
21
+ <MatrixModel title="影响 / 成本矩阵" xLabel="实施成本" yLabel="预期影响" cells={[{title:'优先投入',description:'高影响 / 低成本',tone:'success'},{title:'审慎评估',description:'高影响 / 高成本',tone:'warn'},{title:'快速验证',description:'低影响 / 低成本'},{title:'暂缓处理',description:'低影响 / 高成本',tone:'danger'}]} />
22
+ <Stack gap="md">
23
+ <Insight title="先做什么">优先验证高影响、低成本的选择,再为高成本方案准备证据。</Insight>
24
+ <Callout title="阅读判断">矩阵只帮助定位,不替代成本估算或影响验证。</Callout>
25
+ <NoteGrid notes={[{title:'输入',content:'候选方案与约束'},{title:'输出',content:'下一轮验证顺序'}]} />
26
+ </Stack>
27
+ </ScrollGrid>
28
+ </ScrollSection>
29
+
30
+ <ScrollSection title="把假设压缩为可讨论的关系">
31
+ <ScrollProse>公式适合表达变量之间明确的加减乘除关系;当关系涉及概率或增长时,用 MathBlock 保留推导。</ScrollProse>
32
+ <ScrollGrid columns="2">
33
+ <FormulaModel title="用户价值" formula="用户价值 = 新体验 - 旧体验 - 替换成本" variables={[{symbol:'新体验',description:'方案带来的增量收益'},{symbol:'旧体验',description:'现有替代方案的价值'},{symbol:'替换成本',description:'学习、迁移和风险'}]} />
34
+ <MathBlock title="复利增长" formula="V_t = V_0 \cdot (1 + r)^t" variables={[{symbol:'V_0',description:'初始价值'},{symbol:'r',description:'每期增长率'},{symbol:'t',description:'期数'}]} />
35
+ </ScrollGrid>
36
+ <ScrollProse>行内符号同样可用,例如年化收益约为 <Math formula="r_{\text{ann}} = (1 + r)^{12} - 1" />。</ScrollProse>
37
+ </ScrollSection>
38
+
39
+ <ScrollSection title="用图表观察趋势与占比">
40
+ <ScrollProse>当数据是连续的、有序的,图表比表格更快暴露趋势和分布。</ScrollProse>
41
+ <ScrollGrid columns="2">
42
+ <Chart title="各阶段耗时" type="bar" unit="小时" data={[{label:'收集',value:6},{label:'分析',value:14},{label:'验证',value:9},{label:'落地',value:4}]} />
43
+ <Chart title="时间去向" type="pie" data={[{label:'实现',value:45},{label:'调试',value:25},{label:'沟通',value:20},{label:'文档',value:10}]} />
44
+ </ScrollGrid>
45
+ <Chart title="四周留存趋势" type="line" labels={['第1周','第2周','第3周','第4周']} series={[{name:'留存率',values:[100,72,58,49]},{name:'活跃度',values:[100,64,52,40]}]} />
46
+ </ScrollSection>
47
+
48
+ <ScrollSection title="组织证据,再收敛到行动">
49
+ <ScrollGrid columns="3">
50
+ <PyramidModel title="论证层级" levels={[{title:'结论',description:'读者需要带走的判断'},{title:'理由',description:'支撑判断的关键分组'},{title:'证据',description:'事实、数据与案例'}]} />
51
+ <FunnelModel title="决策过程" steps={[{title:'收集',description:'汇集候选信息'},{title:'筛选',description:'排除不满足约束的项'},{title:'验证',description:'检查关键假设'},{title:'行动',description:'形成下一步决策'}]} />
52
+ <Tradeoff title="输出质量" options={[{name:'压缩结论',benefit:'阅读快',cost:'上下文少',when:'总览'},{name:'保留证据',benefit:'可追溯',cost:'阅读长',when:'关键决策'}]} />
53
+ </ScrollGrid>
54
+ </ScrollSection>
55
+
56
+ <ScrollSection title="补充配图与出处">
57
+ <ScrollProse>配图和引用让讲解从断言变成可追溯的论述<Cite id="tufte1983" />。相对路径的图片会在构建时内联,输出仍是可离线打开的单文件。</ScrollProse>
58
+ <Figure src="./assets/sample-diagram.svg" alt="概念缩放示意" label="图 1" caption="概念缩放:同一主题可以从 L0 全局逐层下钻到 L4 边界反例。" />
59
+ <ScrollGrid columns="2">
60
+ <DecisionMatrix title="需要确认" headers={['变量','检查']} rows={[['新体验','是否改善核心任务'],['旧体验','能否满足需求'],['替换成本','迁移是否可接受']]} />
61
+ <Compare items={[{label:'连续阅读',rows:['信息密度','适用场景'],values:['高','按章节论证']},{label:'概念图谱',rows:['信息密度','适用场景'],values:['中','概念下钻']}]} />
62
+ </ScrollGrid>
63
+ </ScrollSection>
64
+
65
+ <ScrollSection title="保留可追溯性与验证入口">
66
+ <Evidence command="npm run validate" observes="确认内容结构完整,再把关键结论连接回原始证据。" />
67
+ <Invariant title="组件契约">语义组件表达知识,模板负责布局;内容不直接写 CSS、坐标或 SVG。</Invariant>
68
+ <FailureMode symptom="页面看似完整但难以使用" cause="节点缺少摘要、边界或关系" evidence="检查是否只有一段泛化说明" remedy="补充证据与下钻入口" />
69
+ <Insight title="核心原则">选择组件是为了让关系更容易被检验,不是为了把阅读页面做成一组不同样式的卡片。</Insight>
70
+ </ScrollSection>
71
+
72
+ <ScrollSection title="附录:折叠、布局与关系可视化">
73
+ <Tabs items={[{label:'结论',content:'先展示最重要的判断。'},{label:'证据',content:'再展开可验证依据。'}]} />
74
+ <Details summary="展开更多">Details 将次要信息收起,避免首屏过载。</Details>
75
+ <ScrollGrid columns="2">
76
+ <Flow steps={['输入', '组织', '渲染', '验证']} />
77
+ <Timeline events={[{label:'T0',content:'定义目标'},{label:'T1',content:'选择模型'},{label:'T2',content:'验证结果'}]} />
78
+ </ScrollGrid>
79
+ <Columns>
80
+ <Split ratio="1fr 1fr">
81
+ <Callout title="左列">结论与定义。</Callout>
82
+ <Callout title="右列">证据与边界。</Callout>
83
+ </Split>
84
+ </Columns>
85
+ <ScrollGrid columns="2">
86
+ <Mermaid title="组件协作流" width="100%" height="220px" chart={`flowchart LR
87
+ A[MDX 内容] --> B[语义组件]
88
+ B --> C[数据模型]
89
+ C --> D[节点探索]
90
+ C --> E[关系图谱]
91
+ style A fill:#172554,stroke:#38bdf8,color:#e0f2fe
92
+ style E fill:#14532d,stroke:#34d399,color:#ecfdf5`} />
93
+ <RelationPath title="阅读路径" steps={[{level:'L0',node:'总览',note:'建立直觉',tone:'info'},{level:'L1',node:'机制',note:'理解过程',tone:'success'},{level:'L2',node:'边界',note:'检查反例',tone:'warn'}]} />
94
+ </ScrollGrid>
95
+ <RelationMap title="关系速览" items={[{from:'MDX',type:'produces',to:'Graph',note:'生成关系图'},{from:'Node',type:'uses',to:'Mermaid',note:'展示局部流程'}]} />
96
+ </ScrollSection>
97
+
98
+ <ScrollSection title="参考文献">
99
+ <References title="本页引用" items={[{id:'tufte1983',authors:'Tufte, E. R.',year:'1983',title:'The Visual Display of Quantitative Information',source:'Graphics Press',note:'关于以图形压缩与呈现证据的经典论述。'}]} />
100
+ </ScrollSection>
101
+ </ScrollDocument>
@@ -8,6 +8,7 @@
8
8
  "@mdx-js/rollup": "^3.0.1",
9
9
  "clsx": "^2.1.1",
10
10
  "d3": "^7.9.0",
11
+ "katex": "^0.16.47",
11
12
  "lucide-react": "^0.475.0",
12
13
  "mermaid": "^11.17.2",
13
14
  "react": "^18.3.1",