concept-atlas-dense-explain 0.2.2 → 0.3.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 +143 -0
- package/package.json +15 -2
- package/skill/SKILL.md +19 -92
- package/template/content/scroll-reading-demo.mdx +31 -0
- package/{skill/assets/template → template}/package.json +1 -1
- package/template/scripts/build.mjs +43 -0
- package/{skill/assets/template → template}/scripts/validate-content.mjs +48 -48
- package/template/scroll.html +12 -0
- package/{skill/assets/template → template}/src/components/MDXComponents.jsx +85 -47
- package/{skill/assets/template → template}/src/main.jsx +2 -2
- package/{skill/assets/template → template}/src/model/normalize-content.js +10 -4
- package/template/src/scroll-main.jsx +35 -0
- package/{skill/assets/template → template}/src/styles/concept-explain.css +3045 -2600
- package/{skill/assets/template → template}/src/views/NodeExplorer.jsx +668 -668
- package/{skill/assets/template → template}/src/views/RelationGraph.jsx +723 -723
- package/{skill/assets/template → template}/vite.config.js +6 -6
- package/bin/install.mjs +0 -17
- package/skill/assets/template/scripts/build.mjs +0 -37
- package/skill/references/components.md +0 -74
- package/skill/references/prompting.md +0 -90
- /package/{skill/assets/template → template}/content/compile-runtime.mdx +0 -0
- /package/{skill/assets/template → template}/index.html +0 -0
- /package/{skill/assets/template → template}/scripts/clean-temp.mjs +0 -0
- /package/{skill/assets/template → template}/src/app/App.jsx +0 -0
- /package/{skill/assets/template → template}/src/components/index.js +0 -0
- /package/{skill/assets/template → template}/src/model/concept-schema.js +0 -0
- /package/{skill/assets/template → template}/src/model/relation-types.js +0 -0
|
@@ -228,42 +228,43 @@ export function Timeline({ events = [], children }) {
|
|
|
228
228
|
}
|
|
229
229
|
return <div className="semantic-timeline">{children}</div>;
|
|
230
230
|
}
|
|
231
|
-
Timeline.displayName = 'Timeline';
|
|
232
|
-
|
|
233
|
-
export function FrameworkModel({ title = '结构化模型', type = 'elements', elements = [], question, children }) {
|
|
234
|
-
const labels = { elements: '要素', stages: '阶段', layers: '层级', cycle: '循环' };
|
|
235
|
-
return <section className={`semantic-framework-model model-${type}`}><div className="framework-model-head"><span className="semantic-tag">▦ {title}</span><span className="framework-model-type">{labels[type] || type}</span></div>{question && <div className="framework-model-question">{question}</div>}{elements.length > 0 ? <div className="framework-model-elements">{elements.map((element, index) => <div className="framework-model-element" key={index}><span className="framework-model-index">{String(index + 1).padStart(2, '0')}</span><strong>{element.title || element.label || element.name}</strong>{element.description && <span>{element.description}</span>}</div>)}</div> : children}</section>;
|
|
236
|
-
}
|
|
237
|
-
FrameworkModel.displayName = 'FrameworkModel';
|
|
238
|
-
|
|
239
|
-
export function MatrixModel({ title = '二维矩阵', xLabel = '横轴', yLabel = '纵轴', cells = [], children }) {
|
|
240
|
-
return <section className="semantic-model-matrix"><div className="framework-model-head"><span className="semantic-tag">▦ {title}</span></div>{cells.length > 0 ? <div className="model-matrix-grid"><div className="model-matrix-axis model-matrix-y">{yLabel}</div><div className="model-matrix-axis model-matrix-x">{xLabel}</div>{cells.map((cell, index) => <div className={`model-matrix-cell tone-${cell.tone || 'info'}`} key={index}><strong>{cell.title || cell.label}</strong>{cell.description && <span>{cell.description}</span>}</div>)}</div> : children}</section>;
|
|
241
|
-
}
|
|
242
|
-
MatrixModel.displayName = 'MatrixModel';
|
|
243
|
-
|
|
244
|
-
export function FormulaModel({ title = '公式模型', formula, variables = [], children }) {
|
|
245
|
-
return <section className="semantic-model-formula"><div className="framework-model-head"><span className="semantic-tag">∑ {title}</span></div>{formula && <div className="model-formula-expression"><code>{formula}</code></div>}{variables.length > 0 ? <dl className="model-formula-variables">{variables.map((variable, index) => <React.Fragment key={index}><dt>{variable.symbol || variable.name}</dt><dd>{variable.description || variable.value}</dd></React.Fragment>)}</dl> : children}</section>;
|
|
246
|
-
}
|
|
247
|
-
FormulaModel.displayName = 'FormulaModel';
|
|
248
|
-
|
|
249
|
-
export function PyramidModel({ title = '金字塔模型', levels = [], children }) {
|
|
250
|
-
return <section className="semantic-model-pyramid"><div className="framework-model-head"><span className="semantic-tag">△ {title}</span></div>{levels.length > 0 ? <div className="model-pyramid-levels">{levels.map((level, index) => <div className="model-pyramid-level" key={index} style={{ '--pyramid-width': `${Math.max(38, 100 - index * 12)}%` }}><strong>{level.title || level.label}</strong>{level.description && <span>{level.description}</span>}</div>)}</div> : children}</section>;
|
|
251
|
-
}
|
|
252
|
-
PyramidModel.displayName = 'PyramidModel';
|
|
253
|
-
|
|
254
|
-
export function FunnelModel({ title = '漏斗模型', steps = [], children }) {
|
|
255
|
-
return <section className="semantic-model-funnel"><div className="framework-model-head"><span className="semantic-tag">▽ {title}</span></div>{steps.length > 0 ? <div className="model-funnel-steps">{steps.map((step, index) => <div className="model-funnel-step" key={index} style={{ '--funnel-width': `${Math.max(40, 100 - index * 12)}%` }}><strong>{step.title || step.label}</strong>{step.description && <span>{step.description}</span>}</div>)}</div> : children}</section>;
|
|
256
|
-
}
|
|
257
|
-
FunnelModel.displayName = 'FunnelModel';
|
|
231
|
+
Timeline.displayName = 'Timeline';
|
|
258
232
|
|
|
259
|
-
export function
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
233
|
+
export function FrameworkModel({ title = '结构化模型', type = 'elements', elements = [], question, children }) {
|
|
234
|
+
const labels = { elements: '要素', stages: '阶段', layers: '层级', cycle: '循环' };
|
|
235
|
+
return <section className={`semantic-framework-model model-${type}`}><div className="framework-model-head"><span className="semantic-tag">▦ {title}</span><span className="framework-model-type">{labels[type] || type}</span></div>{question && <div className="framework-model-question">{question}</div>}{elements.length > 0 ? <div className="framework-model-elements">{elements.map((element, index) => <div className="framework-model-element" key={index}><span className="framework-model-index">{String(index + 1).padStart(2, '0')}</span><strong>{element.title || element.label || element.name}</strong>{element.description && <span>{element.description}</span>}</div>)}</div> : children}</section>;
|
|
236
|
+
}
|
|
237
|
+
FrameworkModel.displayName = 'FrameworkModel';
|
|
238
|
+
|
|
239
|
+
export function MatrixModel({ title = '二维矩阵', xLabel = '横轴', yLabel = '纵轴', cells = [], children }) {
|
|
240
|
+
return <section className="semantic-model-matrix"><div className="framework-model-head"><span className="semantic-tag">▦ {title}</span></div>{cells.length > 0 ? <div className="model-matrix-grid"><div className="model-matrix-axis model-matrix-y">{yLabel}</div><div className="model-matrix-axis model-matrix-x">{xLabel}</div>{cells.map((cell, index) => <div className={`model-matrix-cell tone-${cell.tone || 'info'}`} key={index}><strong>{cell.title || cell.label}</strong>{cell.description && <span>{cell.description}</span>}</div>)}</div> : children}</section>;
|
|
241
|
+
}
|
|
242
|
+
MatrixModel.displayName = 'MatrixModel';
|
|
243
|
+
|
|
244
|
+
export function FormulaModel({ title = '公式模型', formula, variables = [], children }) {
|
|
245
|
+
return <section className="semantic-model-formula"><div className="framework-model-head"><span className="semantic-tag">∑ {title}</span></div>{formula && <div className="model-formula-expression"><code>{formula}</code></div>}{variables.length > 0 ? <dl className="model-formula-variables">{variables.map((variable, index) => <React.Fragment key={index}><dt>{variable.symbol || variable.name}</dt><dd>{variable.description || variable.value}</dd></React.Fragment>)}</dl> : children}</section>;
|
|
246
|
+
}
|
|
247
|
+
FormulaModel.displayName = 'FormulaModel';
|
|
248
|
+
|
|
249
|
+
export function PyramidModel({ title = '金字塔模型', levels = [], children }) {
|
|
250
|
+
return <section className="semantic-model-pyramid"><div className="framework-model-head"><span className="semantic-tag">△ {title}</span></div>{levels.length > 0 ? <div className="model-pyramid-levels">{levels.map((level, index) => <div className="model-pyramid-level" key={index} style={{ '--pyramid-width': `${Math.max(38, 100 - index * 12)}%` }}><strong>{level.title || level.label}</strong>{level.description && <span>{level.description}</span>}</div>)}</div> : children}</section>;
|
|
251
|
+
}
|
|
252
|
+
PyramidModel.displayName = 'PyramidModel';
|
|
253
|
+
|
|
254
|
+
export function FunnelModel({ title = '漏斗模型', steps = [], children }) {
|
|
255
|
+
return <section className="semantic-model-funnel"><div className="framework-model-head"><span className="semantic-tag">▽ {title}</span></div>{steps.length > 0 ? <div className="model-funnel-steps">{steps.map((step, index) => <div className="model-funnel-step" key={index} style={{ '--funnel-width': `${Math.max(40, 100 - index * 12)}%` }}><strong>{step.title || step.label}</strong>{step.description && <span>{step.description}</span>}</div>)}</div> : children}</section>;
|
|
266
256
|
}
|
|
257
|
+
FunnelModel.displayName = 'FunnelModel';
|
|
258
|
+
|
|
259
|
+
export function Callout({ type = 'info', title, children }) {
|
|
260
|
+
const tone = ['info', 'success', 'warn', 'danger'].includes(type) ? type : 'info';
|
|
261
|
+
return (
|
|
262
|
+
<aside className={`semantic-callout callout-${tone}${title ? ' has-callout-title' : ''}`} data-tone={tone}>
|
|
263
|
+
{title && <div className="callout-title">{title}</div>}
|
|
264
|
+
<div className="callout-content">{children}</div>
|
|
265
|
+
</aside>
|
|
266
|
+
);
|
|
267
|
+
}
|
|
267
268
|
Callout.displayName = 'Callout';
|
|
268
269
|
|
|
269
270
|
export function Details({ summary = '详细展开', children }) {
|
|
@@ -351,13 +352,49 @@ export function Tradeoff({ title = '工程权衡', options = [], children }) {
|
|
|
351
352
|
}
|
|
352
353
|
Tradeoff.displayName = 'Tradeoff';
|
|
353
354
|
|
|
354
|
-
export function Columns({ children }) {
|
|
355
|
-
return <div className="semantic-columns">{children}</div>;
|
|
356
|
-
}
|
|
357
|
-
Columns.displayName = 'Columns';
|
|
355
|
+
export function Columns({ children }) {
|
|
356
|
+
return <div className="semantic-columns">{children}</div>;
|
|
357
|
+
}
|
|
358
|
+
Columns.displayName = 'Columns';
|
|
359
|
+
|
|
360
|
+
export function ScrollDocument({ children }) {
|
|
361
|
+
return <article className="continuous-document">{children}</article>;
|
|
362
|
+
}
|
|
363
|
+
ScrollDocument.displayName = 'ScrollDocument';
|
|
364
|
+
|
|
365
|
+
export function ScrollHeader({ label = '连续阅读', title, children }) {
|
|
366
|
+
return <header className="continuous-header"><p>{label}</p>{title && <h1>{title}</h1>}<div>{children}</div></header>;
|
|
367
|
+
}
|
|
368
|
+
ScrollHeader.displayName = 'ScrollHeader';
|
|
369
|
+
|
|
370
|
+
export function ScrollSection({ title, wide = false, children }) {
|
|
371
|
+
return (
|
|
372
|
+
<section className={`continuous-section${wide ? ' continuous-section-wide' : ''}`}>
|
|
373
|
+
{title && <h2>{title}</h2>}
|
|
374
|
+
{children}
|
|
375
|
+
</section>
|
|
376
|
+
);
|
|
377
|
+
}
|
|
378
|
+
ScrollSection.displayName = 'ScrollSection';
|
|
379
|
+
|
|
380
|
+
export function ScrollProse({ children }) {
|
|
381
|
+
return <div className="continuous-prose">{children}</div>;
|
|
382
|
+
}
|
|
383
|
+
ScrollProse.displayName = 'ScrollProse';
|
|
384
|
+
|
|
385
|
+
export function ScrollPair({ children }) {
|
|
386
|
+
return <section className="continuous-model-pair">{children}</section>;
|
|
387
|
+
}
|
|
388
|
+
ScrollPair.displayName = 'ScrollPair';
|
|
389
|
+
|
|
390
|
+
export function ScrollGrid({ columns = 3, children }) {
|
|
391
|
+
const count = [2, 3, 4].includes(Number(columns)) ? Number(columns) : 3;
|
|
392
|
+
return <div className={`continuous-grid continuous-grid-${count}`}>{children}</div>;
|
|
393
|
+
}
|
|
394
|
+
ScrollGrid.displayName = 'ScrollGrid';
|
|
358
395
|
|
|
359
396
|
/** Optional layout primitives. They express intent while the template owns the CSS. */
|
|
360
|
-
export function Stack({ gap = 'md', children }) {
|
|
397
|
+
export function Stack({ gap = 'md', children }) {
|
|
361
398
|
return <div className={`semantic-stack gap-${gap}`}>{children}</div>;
|
|
362
399
|
}
|
|
363
400
|
Stack.displayName = 'Stack';
|
|
@@ -462,14 +499,15 @@ export function RelationPath({ title = '关系链', steps = [], children }) {
|
|
|
462
499
|
}
|
|
463
500
|
RelationPath.displayName = 'RelationPath';
|
|
464
501
|
|
|
465
|
-
export function Insight({ title = '关键判断', tone = 'info', children, width = 'auto', height = 'auto', x = 0, y = 0, position = 'flow' }) {
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
<div className="insight-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
502
|
+
export function Insight({ title = '关键判断', tone = 'info', children, width = 'auto', height = 'auto', x = 0, y = 0, position = 'flow' }) {
|
|
503
|
+
const safeTone = ['info', 'success', 'warn', 'danger'].includes(tone) ? tone : 'info';
|
|
504
|
+
return (
|
|
505
|
+
<aside className={`semantic-insight insight-${safeTone} ${widgetClass(position)}`} data-tone={safeTone} style={widgetStyle({ width, height, x, y, position })}>
|
|
506
|
+
<div className="insight-kicker">{title}</div>
|
|
507
|
+
<div className="insight-body">{children}</div>
|
|
508
|
+
</aside>
|
|
509
|
+
);
|
|
510
|
+
}
|
|
473
511
|
Insight.displayName = 'Insight';
|
|
474
512
|
|
|
475
513
|
export function NoteGrid({ notes = [], children, width = 'auto', height = 'auto', x = 0, y = 0, position = 'flow' }) {
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import ReactDOM from 'react-dom/client';
|
|
3
3
|
import { App } from './app/App.jsx';
|
|
4
4
|
import * as Components from './components/index.js';
|
|
5
|
-
import
|
|
5
|
+
import UserDocument from '@concept-atlas/content';
|
|
6
6
|
|
|
7
7
|
// Mount MDX application to DOM
|
|
8
8
|
const rootElement = document.getElementById('root') || document.getElementById('app');
|
|
@@ -10,7 +10,7 @@ if (rootElement) {
|
|
|
10
10
|
const root = ReactDOM.createRoot(rootElement);
|
|
11
11
|
root.render(
|
|
12
12
|
<React.StrictMode>
|
|
13
|
-
<App mdxContent={<
|
|
13
|
+
<App mdxContent={<UserDocument components={Components} />} />
|
|
14
14
|
</React.StrictMode>
|
|
15
15
|
);
|
|
16
16
|
}
|
|
@@ -116,12 +116,18 @@ const SEMANTIC_COMPONENTS = new Set([
|
|
|
116
116
|
'Evidence',
|
|
117
117
|
'Invariant',
|
|
118
118
|
'FailureMode',
|
|
119
|
-
'Tradeoff',
|
|
120
|
-
'FrameworkModel',
|
|
121
|
-
'MatrixModel',
|
|
122
|
-
'FormulaModel',
|
|
119
|
+
'Tradeoff',
|
|
120
|
+
'FrameworkModel',
|
|
121
|
+
'MatrixModel',
|
|
122
|
+
'FormulaModel',
|
|
123
123
|
'PyramidModel',
|
|
124
124
|
'FunnelModel',
|
|
125
|
+
'ScrollDocument',
|
|
126
|
+
'ScrollHeader',
|
|
127
|
+
'ScrollSection',
|
|
128
|
+
'ScrollProse',
|
|
129
|
+
'ScrollPair',
|
|
130
|
+
'ScrollGrid',
|
|
125
131
|
]);
|
|
126
132
|
|
|
127
133
|
function isSemanticComponent(name) {
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
|
2
|
+
import ReactDOM from 'react-dom/client';
|
|
3
|
+
import { Moon, Sun } from 'lucide-react';
|
|
4
|
+
import * as Components from './components/index.js';
|
|
5
|
+
import UserDocument from '@concept-atlas/content';
|
|
6
|
+
import './styles/concept-explain.css';
|
|
7
|
+
|
|
8
|
+
const rootElement = document.getElementById('root');
|
|
9
|
+
if (rootElement) {
|
|
10
|
+
ReactDOM.createRoot(rootElement).render(
|
|
11
|
+
<React.StrictMode>
|
|
12
|
+
<ScrollApp />
|
|
13
|
+
</React.StrictMode>
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function ScrollApp() {
|
|
18
|
+
const [theme, setTheme] = useState(() => localStorage.getItem('concept_atlas_scroll_theme') || (window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark'));
|
|
19
|
+
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
document.documentElement.setAttribute('data-theme', theme);
|
|
22
|
+
localStorage.setItem('concept_atlas_scroll_theme', theme);
|
|
23
|
+
}, [theme]);
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<main className="continuous-page">
|
|
27
|
+
<div className="continuous-toolbar">
|
|
28
|
+
<button type="button" onClick={() => setTheme(value => value === 'dark' ? 'light' : 'dark')} aria-label="切换主题" title="切换主题">
|
|
29
|
+
{theme === 'dark' ? <Sun size={16} /> : <Moon size={16} />}
|
|
30
|
+
</button>
|
|
31
|
+
</div>
|
|
32
|
+
<UserDocument components={Components} />
|
|
33
|
+
</main>
|
|
34
|
+
);
|
|
35
|
+
}
|