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.
Files changed (27) hide show
  1. package/bin/cli.mjs +143 -0
  2. package/package.json +15 -2
  3. package/skill/SKILL.md +19 -92
  4. package/template/content/scroll-reading-demo.mdx +31 -0
  5. package/{skill/assets/template → template}/package.json +1 -1
  6. package/template/scripts/build.mjs +43 -0
  7. package/{skill/assets/template → template}/scripts/validate-content.mjs +48 -48
  8. package/template/scroll.html +12 -0
  9. package/{skill/assets/template → template}/src/components/MDXComponents.jsx +85 -47
  10. package/{skill/assets/template → template}/src/main.jsx +2 -2
  11. package/{skill/assets/template → template}/src/model/normalize-content.js +10 -4
  12. package/template/src/scroll-main.jsx +35 -0
  13. package/{skill/assets/template → template}/src/styles/concept-explain.css +3045 -2600
  14. package/{skill/assets/template → template}/src/views/NodeExplorer.jsx +668 -668
  15. package/{skill/assets/template → template}/src/views/RelationGraph.jsx +723 -723
  16. package/{skill/assets/template → template}/vite.config.js +6 -6
  17. package/bin/install.mjs +0 -17
  18. package/skill/assets/template/scripts/build.mjs +0 -37
  19. package/skill/references/components.md +0 -74
  20. package/skill/references/prompting.md +0 -90
  21. /package/{skill/assets/template → template}/content/compile-runtime.mdx +0 -0
  22. /package/{skill/assets/template → template}/index.html +0 -0
  23. /package/{skill/assets/template → template}/scripts/clean-temp.mjs +0 -0
  24. /package/{skill/assets/template → template}/src/app/App.jsx +0 -0
  25. /package/{skill/assets/template → template}/src/components/index.js +0 -0
  26. /package/{skill/assets/template → template}/src/model/concept-schema.js +0 -0
  27. /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 Callout({ type = 'info', title, children }) {
260
- return (
261
- <div className={`semantic-callout callout-${type}`}>
262
- {title && <div className="callout-title">{title}</div>}
263
- <div className="callout-content">{children}</div>
264
- </div>
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
- return (
467
- <aside className={`semantic-insight insight-${tone} ${widgetClass(position)}`} style={widgetStyle({ width, height, x, y, position })}>
468
- <div className="insight-kicker">{tone === 'warn' ? '⚠' : tone === 'success' ? '✓' : '◆'} {title}</div>
469
- <div className="insight-body">{children}</div>
470
- </aside>
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 CompileRuntimeDoc from '../content/compile-runtime.mdx';
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={<CompileRuntimeDoc components={Components} />} />
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
+ }