@yumiai/chat-widget 0.1.2 → 0.2.1

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 (107) hide show
  1. package/CHANGELOG.md +100 -0
  2. package/README.md +119 -22
  3. package/dist/ExcelCore-DJOIVQMI.js +11 -0
  4. package/dist/ExcelCore-DJOIVQMI.js.map +1 -0
  5. package/dist/ExcelViewer-3YLLYYIQ.js +65 -0
  6. package/dist/ExcelViewer-3YLLYYIQ.js.map +1 -0
  7. package/dist/GerberViewerA2UI-7CNT7HX4.css +693 -0
  8. package/dist/GerberViewerA2UI-7CNT7HX4.css.map +1 -0
  9. package/dist/GerberViewerA2UI-X5FWAD5M.js +57 -0
  10. package/dist/GerberViewerA2UI-X5FWAD5M.js.map +1 -0
  11. package/dist/GraphStatsLegend-D5bPeXB_.d.cts +607 -0
  12. package/dist/GraphStatsLegend-D5bPeXB_.d.ts +607 -0
  13. package/dist/JsonRenderStandalone-EIZM62JU.js +18 -0
  14. package/dist/JsonRenderStandalone-EIZM62JU.js.map +1 -0
  15. package/dist/JsonRenderStandalone-POB4Q3N3.css +2384 -0
  16. package/dist/JsonRenderStandalone-POB4Q3N3.css.map +1 -0
  17. package/dist/JsonRenderStandalone-UsTcST4G.d.cts +23 -0
  18. package/dist/JsonRenderStandalone-UsTcST4G.d.ts +23 -0
  19. package/dist/KicadViewer-GV6ZC4AQ.js +124 -0
  20. package/dist/KicadViewer-GV6ZC4AQ.js.map +1 -0
  21. package/dist/KicadViewerCore-U7BWZHKJ.js +11 -0
  22. package/dist/KicadViewerCore-U7BWZHKJ.js.map +1 -0
  23. package/dist/PdfViewer-CHPDRK46.js +51 -0
  24. package/dist/PdfViewer-CHPDRK46.js.map +1 -0
  25. package/dist/PdfViewer-LPYGQETK.css +1899 -0
  26. package/dist/PdfViewer-LPYGQETK.css.map +1 -0
  27. package/dist/PdfViewerCore-HJPEHSRA.js +364 -0
  28. package/dist/PdfViewerCore-HJPEHSRA.js.map +1 -0
  29. package/dist/PowerPointCore-FPDR2BL4.js +11 -0
  30. package/dist/PowerPointCore-FPDR2BL4.js.map +1 -0
  31. package/dist/PowerPointViewer-LQTO6UCU.js +61 -0
  32. package/dist/PowerPointViewer-LQTO6UCU.js.map +1 -0
  33. package/dist/StepViewerCore-7W3L3R4E.js +285 -0
  34. package/dist/StepViewerCore-7W3L3R4E.js.map +1 -0
  35. package/dist/ThreeViewerCore-N3QJD5QI.js +161 -0
  36. package/dist/ThreeViewerCore-N3QJD5QI.js.map +1 -0
  37. package/dist/WordCore-JKSXK2XD.js +11 -0
  38. package/dist/WordCore-JKSXK2XD.js.map +1 -0
  39. package/dist/WordViewer-ZHCQMHOH.js +61 -0
  40. package/dist/WordViewer-ZHCQMHOH.js.map +1 -0
  41. package/dist/chunk-2SKA3F5U.js +88 -0
  42. package/dist/chunk-2SKA3F5U.js.map +1 -0
  43. package/dist/chunk-2UC7YLVX.js +318 -0
  44. package/dist/chunk-2UC7YLVX.js.map +1 -0
  45. package/dist/chunk-3R6T3LBR.js +24 -0
  46. package/dist/chunk-3R6T3LBR.js.map +1 -0
  47. package/dist/chunk-56WRZM3R.js +398 -0
  48. package/dist/chunk-56WRZM3R.js.map +1 -0
  49. package/dist/chunk-7A4FY6FK.js +10226 -0
  50. package/dist/chunk-7A4FY6FK.js.map +1 -0
  51. package/dist/chunk-7D4SUZUM.js +38 -0
  52. package/dist/chunk-7D4SUZUM.js.map +1 -0
  53. package/dist/chunk-7S67DOHQ.js +436 -0
  54. package/dist/chunk-7S67DOHQ.js.map +1 -0
  55. package/dist/chunk-CFKGNAJM.js +14013 -0
  56. package/dist/chunk-CFKGNAJM.js.map +1 -0
  57. package/dist/chunk-GAMA3VA7.js +99 -0
  58. package/dist/chunk-GAMA3VA7.js.map +1 -0
  59. package/dist/chunk-GYXTSY22.js +639 -0
  60. package/dist/chunk-GYXTSY22.js.map +1 -0
  61. package/dist/chunk-K4KGNVL5.js +77 -0
  62. package/dist/chunk-K4KGNVL5.js.map +1 -0
  63. package/dist/chunk-KQV7IKET.js +1621 -0
  64. package/dist/chunk-KQV7IKET.js.map +1 -0
  65. package/dist/chunk-O3NXUM6C.js +1871 -0
  66. package/dist/chunk-O3NXUM6C.js.map +1 -0
  67. package/dist/chunk-PZXSASDY.js +83 -0
  68. package/dist/chunk-PZXSASDY.js.map +1 -0
  69. package/dist/chunk-QLVPIM6R.js +595 -0
  70. package/dist/chunk-QLVPIM6R.js.map +1 -0
  71. package/dist/chunk-VXJWGLZ7.js +21 -0
  72. package/dist/chunk-VXJWGLZ7.js.map +1 -0
  73. package/dist/chunk-XQ562W7I.js +116 -0
  74. package/dist/chunk-XQ562W7I.js.map +1 -0
  75. package/dist/components/JsonRender/standalone.cjs +39368 -0
  76. package/dist/components/JsonRender/standalone.cjs.map +1 -0
  77. package/dist/components/JsonRender/standalone.css +2384 -0
  78. package/dist/components/JsonRender/standalone.css.map +1 -0
  79. package/dist/components/JsonRender/standalone.d.cts +16 -0
  80. package/dist/components/JsonRender/standalone.d.ts +16 -0
  81. package/dist/components/JsonRender/standalone.js +38 -0
  82. package/dist/components/JsonRender/standalone.js.map +1 -0
  83. package/dist/gerber-2d-entry-OQ4SQRBY.js +3950 -0
  84. package/dist/gerber-2d-entry-OQ4SQRBY.js.map +1 -0
  85. package/dist/gerber-3d-entry-DEHDBOO2.js +3679 -0
  86. package/dist/gerber-3d-entry-DEHDBOO2.js.map +1 -0
  87. package/dist/gerber-simulation-entry-EBDX72XE.js +1801 -0
  88. package/dist/gerber-simulation-entry-EBDX72XE.js.map +1 -0
  89. package/dist/index.cjs +60113 -2970
  90. package/dist/index.cjs.map +1 -1
  91. package/dist/index.css +11342 -1708
  92. package/dist/index.css.map +1 -1
  93. package/dist/index.d.cts +3275 -77
  94. package/dist/index.d.ts +3275 -77
  95. package/dist/index.js +18078 -2540
  96. package/dist/index.js.map +1 -1
  97. package/dist/provenance/index.cjs +2248 -0
  98. package/dist/provenance/index.cjs.map +1 -0
  99. package/dist/provenance/index.css +52 -0
  100. package/dist/provenance/index.css.map +1 -0
  101. package/dist/provenance/index.d.cts +12 -0
  102. package/dist/provenance/index.d.ts +12 -0
  103. package/dist/provenance/index.js +27 -0
  104. package/dist/provenance/index.js.map +1 -0
  105. package/dist/resolveToArrayBuffer-AQIDZHSQ.js +23 -0
  106. package/dist/resolveToArrayBuffer-AQIDZHSQ.js.map +1 -0
  107. package/package.json +98 -17
package/CHANGELOG.md CHANGED
@@ -1,5 +1,105 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.2.1] - 2026-05-19
4
+
5
+ ### Fixed
6
+
7
+ - **完善 `peerDependencies`**:将 `@ant-design/icons` 和 `tailwindcss-scoped-preflight` 加入 `peerDependencies`。0.2.0 的 dist 直接以 bare import 引用这两者,但 package.json 既未声明 dep 也未声明 peerDep,导致下游消费者(如 JetForge frontend)`npm install` 后 vite/rollup 在 `Can't resolve 'tailwindcss-scoped-preflight'` 处崩。`@ant-design/icons` 同款问题,但消费侧若自己已装则巧合可过。
8
+ - `@ant-design/icons`: `^6.0.0 || ^7.0.0`,标记 `optional`(仅在使用相关 icon 时需要)。
9
+ - `tailwindcss-scoped-preflight`: `^4.0.0`,**必需**(chat-widget 的 CSS scoping 依赖它)。
10
+
11
+ ## [0.2.0] - 2026-05-19
12
+
13
+ 聚合自 0.1.2 以来 ~198 次提交,覆盖 **CWRF-001 → CWRF-013** 全部 Phase(P1 ~ P6)和若干 JETP 集成。重点是:a2ui / GenUI 渲染管线落地、shadcn × Tailwind v4 设计体系接入、DashboardLayout / RiskRegister / DataTable 三件套 Split 重构(已删除 legacy 但提供 transformer 自动迁移)、Phase 5 a11y 严格化(axe-core CI gate)、Phase 6 catalog 89 组件三件 contract 形式化。
14
+
15
+ ### Added
16
+
17
+ #### a2ui / GenUI / JsonRender (CWRF-013 P1–P2, JETP-033)
18
+
19
+ - **JETP-033 GenUI rendering pipeline**:`JsonRender` 组件 + page viewer + streaming 集成,把 agent 的 JSON 描述渲染为完整 UI。
20
+ - **`@json-render/{core,react}` 升级 0.14.1 → 0.19.0**(CWRF-013 PR-P1-#2)。
21
+ - **Tailwind v4 + scoped-preflight + `.ycw-shadcn` 接入**(PR-P1-#3),CSS 隔离不污染宿主样式。
22
+ - **shadcn × YCW 设计体系:36 primitives**——12 layout + 12 form + 12 feedback/overlay,全部 catalog spread + registry `defineRegistry` 接线、单测覆盖(PR-P1-#4a/#4b/#4c)。
23
+ - **JrSlot 命名插槽体系**:synthetic wrapper component + catalog/registry 注册 + `legacy.slots.named-children` transformer(PR-P1-#5)。
24
+ - **YCW 6 layout primitives + 设计 token**(PR-P2-#1)。
25
+ - **catalog 描述统一改写为 6-element prompt spec**:38 domain + 36 shadcn 组件(PR-P2-#2/#3)。
26
+ - **catalog description linter + fragment file snapshot**(PR-P2-#4),机器可验证地保证描述质量。
27
+ - **named-slots ADR + S6 Card-parent demo**(PR-P2-#6)。
28
+
29
+ #### Split refactors (CWRF-013 P3)
30
+
31
+ - **Split A · DashboardLayout** → `AppChrome` + `SideNav` + `SectionRouter` + normalize helpers + `legacy.dashboardlayout.split` transformer(PR-P3-#3)。
32
+ - **Split B · RiskRegister** → `RiskList` + `RiskHeatMatrix` + `legacy.riskregister.split` transformer(PR-P3-#2)。
33
+ - **Split C · DataTable modular** → `TableToolbar` + `ColumnFilter` + `RowGroup` banner wrapper + `filterPath` 读侧 + `legacy.datatable.split-toolbar` transformer + dotted filterPath translator(PR-P3-#1)。
34
+ - **PR-P3-#5**:multi-component E2E、migrator automation-rate gate、named-slot interop、`FormSection` passthrough alias、cross-component visual baseline。
35
+
36
+ #### Polish & micro-interactions (CWRF-013 P4)
37
+
38
+ - **Phase 4 a2ui UI polish & microinteraction proposal v1.1**。
39
+ - **Tier 2/3/4 落地**:Slice G 自适应基础设施、`ChecklistCard.compact` + `KPICluster` compact patterns、`SectionRouter` fade-slide、`RowGroup` caret rotate、`SideNav` icon/badge/disabled、`AppChrome.footer` destructive auto-wrap。
40
+ - **`useComponentState` + `StateView` + 五状态接线**:`DataTable` / `Chart` / `GanttChart` / `WaterfallChart` / `Timeline` / `AppChrome` / `RiskList` / `EvidenceChain` / `AssumptionRegister` 等 ~13 组件(Tier 4-4 A/B/C)。
41
+
42
+ #### Accessibility (CWRF-013 P5)
43
+
44
+ - **Tier 5-2 `:focus-visible` 第二波迁移**。
45
+ - **Tier 5-3 P0 keyboard parity**(4 个 pressable surface)。
46
+ - **Tier 5-4 dual encoding**:Heatmap / GanttChart / BudgetBar 色彩失败时仍可读。
47
+ - **`KPICard` variant icon dual-encoding**(AC-A11Y-008)+ **`ConfirmDialog` Radix description warning** 修复。
48
+ - **AC-A11Y-005 axe-core CI gate**:15 个 P0 组件 0 critical/serious 违规。
49
+
50
+ #### Catalog contracts (CWRF-013 P6)
51
+
52
+ - **Tier 6-1 RESPONSIVE contract**:扩展到 7 个 P1 container 组件。
53
+ - **Tier 6-2 anti-pattern contract**:全部 89 组件正式化。
54
+ - **Tier 6-3 Cross-ref contract**:全部 89 组件完成。
55
+ - **Tier 6-4**:从 catalog prompt payload 中剥离 engineering provenance,降低 LLM context 噪音。
56
+
57
+ #### File viewer / KiCad / Gerber (CWRF-001/002/003)
58
+
59
+ - **`extractKicadSexprByUuid`**:从 `.kicad_sch` / `.kicad_pcb` 正文按 `uuid` 截取外层 S 表达式块(Vitest 覆盖)。
60
+ - **KiCad 画布选中 → 引用**:监听 `kicanvas-embed` 的 `kicanvas:select`(需 **jp-kicanvas** 补丁产出 `detail.jp.uuid`);显示「问一下 / 复制片段」条。
61
+ - **`kicanvasScriptUrl` 配置项**:`ChatWidget` / `FileViewerPanel` 可传入自建脚本 URL,未传时 ESM 下可读 `VITE_KICANVAS_SCRIPT_URL`。
62
+ - **GerberViewer 嵌入渲染**:内层图层 SIG 处理 + 2D/3D entry + baseline 测试(PR-P1-#6);动态导入类型 `gerber-2d-entry.d.ts`。
63
+ - **沉浸式 workspace + session channel + JsonRender viewers**(KiCad/Gerber 全链路)。
64
+ - **Word / Excel / Step / Three viewers**:核心 viewer + 各自 lazy chunk。
65
+
66
+ #### SDK / API surface
67
+
68
+ - **JETP-032 skill selector**。
69
+ - **CWRF-007 design system + CSS token isolation**(`.ycw-*` 前缀隔离)。
70
+ - **CWRF-013 P2-T15.2 ModelPicker SDK extraction**、status banner、styling contracts。
71
+
72
+ #### Tooling / CI / Docs
73
+
74
+ - **GitLab CI pipeline + Dockerfile + publish script**。
75
+ - **`.size-limit.json` 重置**到 post-Tailwind+shadcn 基线(PR-P1-Gate)。
76
+ - **smoke 覆盖** 从 4 → 8(PR-P1-Gate)。
77
+ - **`tests/visual/gerber-baseline`** 脚手架。
78
+ - **大量 README v1.5 → v1.16 级联更新**、Phase 1/2 Gate checklist、kickoff checklist、ADR、jetagents handoff 文档。
79
+
80
+ ### Changed
81
+
82
+ - **子 Agent 卡片「已完成」判定**(继承自 0.1.1/0.1.2):基于后端 `agent_end` 通知 + `round.messages` 按 `agentInstanceId` 检查进行中工具,避免「顶上已完成、内部仍生成中」的不一致。
83
+ - **tailwindcss 包**从 devDependencies 移到 runtime dependencies(消费侧无需再装)。
84
+ - **Docker build**:移除 `npm install ./dist`,改用 vite alias;切回官方 npm registry 避免 mirror 同步 404;通过 `--build-arg` 注入 `VITE_API_TARGET`。
85
+
86
+ ### Removed (BREAKING)
87
+
88
+ > 0.x 阶段允许 minor 含 break;以下旧组件已删除,请用各自 transformer 迁移:
89
+
90
+ - ❌ **legacy `DashboardLayout`** —— 用 `legacy.dashboardlayout.split` transformer 拆为 `AppChrome` + `SideNav` + `SectionRouter`。
91
+ - ❌ **legacy `RiskRegister`** —— 用 `legacy.riskregister.split` transformer 拆为 `RiskList` + `RiskHeatMatrix`。
92
+ - ❌ **`DataTable` phantom field schemas** —— Split C 重构后已是 modular `TableToolbar` + `ColumnFilter` + `RowGroup`;幻影 schema 不再需要。
93
+ - ❌ **静态 prompt-fragment 脚本**(PR-P2-#5 obsolete)——改为 catalog 内联描述。
94
+
95
+ ### Fixed
96
+
97
+ - **`randomUUID` fallback**:非安全 HTTP context 下退回 polyfill,避免 widget 在 http:// 部署上崩。
98
+ - **`file-viewer` 生产构建样式丢失**:确保 panel styles 进 production bundle。
99
+ - **`file-viewer` 文本下载 URI malformed**:raw text content 先包成 Blob URL 再下载。
100
+ - **demo PostCSS 构建**:恢复 `@tailwindcss/postcss` + `tailwindcss` 依赖。
101
+ - **CWRF-013 P2-#4 linter 收尾**:补齐 6 个由新 linter 暴露的描述空缺。
102
+
3
103
  ## [0.1.2] - 2025-03-17
4
104
 
5
105
  ### Fixed
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
- # @yumiai/chat-widget
1
+ # @yumiai/chat-widget
2
2
 
3
- Agent 对话 UI 组件 — 为 AI Agent 系统提供开箱即用的聊天界面。
3
+ Agent 对话 UI 组件 — 为 AI Agent 系统提供开箱即用的聊天界面。
4
4
 
5
5
  ## 特性
6
6
 
@@ -11,9 +11,13 @@ Agent 对话 UI 组件 — 为 AI Agent 系统提供开箱即用的聊天界面
11
11
  - **工具调用卡片** — MCP 工具生命周期(生成 → 执行 → 完成),buffering 动画
12
12
  - **Todo/Checklist** — 实时任务进度面板,按 Phase → Group → Task 三级结构展示
13
13
  - **HITL 表单** — Human-in-the-Loop 交互,支持 JSON Schema / HTML Schema 动态表单
14
- - **产出物查看器**文件 Artifact 点击预览,支持文本/二进制类型识别
14
+ - **富文档查看器**PDF、图片、代码、3D/STEP、KiCad 原理图/PCB、Markdown、HTML 等 20+ 格式(CWRF-001/003)
15
+ - **溯源图谱** — 3D 推理图谱可视化,支持节点过滤、深度控制、详情面板(CWRF-004)
16
+ - **选区交互** — 文档选区工具条、Ask/Copy 拦截、上下文引用芯片(CWRF-002)
17
+ - **Headless Controller** — `useChatWidgetController` 将业务逻辑与 UI 分离,支持自定义渲染(CWRF-004)
18
+ - **国际化 (i18n)** — `locale` prop 支持 `zh-CN` / `en-US`,可自定义消息字典
15
19
  - **打字机效果** — 基于 `requestAnimationFrame` 的逐字展开,自动对齐 Markdown 安全边界
16
- - **主题支持**`light` / `dark` / `auto` 三种主题,CSS 变量驱动
20
+ - **CSS 隔离** 所有类名 `ycw-` 前缀,CSS 变量驱动主题,不污染宿主样式
17
21
  - **Adapter 模式** — 认证、API 地址、Token 刷新完全由消费方注入,零耦合
18
22
 
19
23
  ## 安装
@@ -22,7 +26,7 @@ Agent 对话 UI 组件 — 为 AI Agent 系统提供开箱即用的聊天界面
22
26
  npm install @yumiai/chat-widget
23
27
  ```
24
28
 
25
- **Peer Dependencies:**
29
+ **Peer Dependencies(必需):**
26
30
 
27
31
  ```json
28
32
  {
@@ -32,6 +36,16 @@ npm install @yumiai/chat-widget
32
36
  }
33
37
  ```
34
38
 
39
+ **可选 Peer Dependencies(溯源 3D 图谱):**
40
+
41
+ ```json
42
+ {
43
+ "three": ">=0.150.0",
44
+ "react-force-graph-3d": "^1.29.0",
45
+ "three-spritetext": "^1.10.0"
46
+ }
47
+ ```
48
+
35
49
  ## 快速开始
36
50
 
37
51
  ```tsx
@@ -99,7 +113,58 @@ class MyAdapter implements ChatWidgetAdapter {
99
113
  }
100
114
  ```
101
115
 
102
- 详细接口定义见 [docs/02-adapter-interface.md](docs/02-adapter-interface.md)。
116
+ 详细接口定义见 [docs/02-adapter-interface.md](docs/02-adapter-interface.md)。完整 API 文档见 [docs/11-api-reference.md](docs/11-api-reference.md)
117
+
118
+ ## Headless Controller(CWRF-004)
119
+
120
+ 如果需要完全自定义 UI,可直接使用 `useChatWidgetController` Hook:
121
+
122
+ ```tsx
123
+ import { useChatWidgetController } from '@yumiai/chat-widget'
124
+
125
+ function MyCustomChat({ adapter }) {
126
+ const {
127
+ executionStatus,
128
+ connectionStatus,
129
+ rounds,
130
+ sendMessage,
131
+ widgetAPI,
132
+ } = useChatWidgetController({
133
+ adapter,
134
+ sessionId: 123,
135
+ onStatusChange: (s) => console.log('status:', s),
136
+ onRoundChange: (r) => console.log('new round:', r),
137
+ onConnectionChange: (c) => console.log('connection:', c),
138
+ })
139
+
140
+ return (
141
+ <div>
142
+ {rounds.map((round) => (
143
+ <div key={round.id}>{/* 自定义轮次渲染 */}</div>
144
+ ))}
145
+ </div>
146
+ )
147
+ }
148
+ ```
149
+
150
+ ## 溯源图谱(CWRF-004)
151
+
152
+ 溯源组件可作为子路径单独导入(需安装 three.js 可选依赖):
153
+
154
+ ```tsx
155
+ import { ProvenanceGraphDrawerContent, useProvenanceGraph } from '@yumiai/chat-widget/provenance'
156
+
157
+ function ProvenancePanel({ sessionId }) {
158
+ const { graph, loading } = useProvenanceGraph({
159
+ sessionId,
160
+ enabled: !!sessionId,
161
+ fetcher: (sid, params) => myApi.getProvenanceGraph(sid, params),
162
+ })
163
+
164
+ if (loading) return <Spin />
165
+ return <ProvenanceGraphDrawerContent graph={graph} />
166
+ }
167
+ ```
103
168
 
104
169
  ## API 参考
105
170
 
@@ -117,6 +182,10 @@ class MyAdapter implements ChatWidgetAdapter {
117
182
  | `onHITLSubmit` | `(response) => Promise<void>` | — | HITL 表单提交回调 |
118
183
  | `onStatusChange` | `(status: ExecutionStatus) => void` | — | 执行状态变化回调 |
119
184
  | `onError` | `(error: Error) => void` | — | 错误回调 |
185
+ | `locale` | `'zh-CN' \| 'en-US'` | `'zh-CN'` | UI 语言 |
186
+ | `renderToolResult` | `(data: ToolCallData) => ReactNode` | — | 自定义工具结果渲染 |
187
+ | `onSelectionAsk` | `(ref: FileReference) => void` | — | 文档选区"提问"回调 |
188
+ | `onBeforeCopy` | `(ref: FileReference) => void` | — | 文档选区"复制"拦截 |
120
189
  | `height` | `number \| string` | `600` | 容器高度 |
121
190
  | `theme` | `'light' \| 'dark' \| 'auto'` | `'auto'` | 主题 |
122
191
 
@@ -157,31 +226,59 @@ chat-widget/
157
226
  │ ├── index.ts # 公共导出
158
227
  │ ├── types.ts # 类型定义
159
228
  │ ├── errors.ts # 错误类型
160
- │ ├── ChatWidget.tsx # 主组件
161
- │ ├── ChatWidget.css # 主样式
229
+ │ ├── ChatWidget.tsx # 主组件(thin shell)
230
+ │ ├── ChatWidget.css # 主样式(ycw- 前缀)
231
+ │ ├── controller/ # Headless Controller (CWRF-004)
232
+ │ │ ├── useChatWidgetController.ts
233
+ │ │ └── index.ts
162
234
  │ ├── hooks/
163
235
  │ │ ├── useSSE.ts # SSE 连接 Hook
164
- │ │ └── useMessageAggregator.ts # 消息聚合 Hook
236
+ │ │ ├── useMessageAggregator.ts # 消息聚合 Hook
237
+ │ │ └── useAttentionManager.ts # 注意力通知 Hook
165
238
  │ ├── adapters/
166
- │ │ ├── ChatWidgetAdapter.ts # Adapter 接口
167
239
  │ │ └── DefaultJetAgentsAdapter.ts # JetAgents 默认适配器
168
- └── components/
169
- ├── PinnedArea.tsx # 置顶区域
170
- ├── RoundHeader.tsx # 轮次标题
171
- ├── MessageContent.tsx # 消息内容渲染
172
- ├── ChildAgentCard.tsx # 子 Agent 卡片
173
- ├── ToolCardBuffering.tsx # 工具调用卡片
174
- ├── TodoCard.tsx # Todo 进度面板
175
- ├── PlanCard.tsx # 计划面板
176
- ├── SchemaFormRenderer.tsx # HITL 表单渲染器
177
- └── renderers/ # 工具结果渲染器
240
+ ├── provenance/ # 溯源图谱 (CWRF-004)
241
+ ├── api.ts # ProvenanceGraphFetcher
242
+ ├── GraphBuilder.ts # 图构建器
243
+ ├── components/ # 3D 图谱、面板、过滤器
244
+ │ └── hooks/ # useProvenanceGraph
245
+ ├── components/
246
+ ├── FileViewer/ # 富文档查看器 (CWRF-001/003)
247
+ ├── SplitPanel/ # 分屏面板 (CWRF-002)
248
+ ├── ContextBridge/ # 选区交互 (CWRF-002)
249
+ │ ├── PinnedArea.tsx
250
+ │ │ ├── MessageContent.tsx
251
+ │ │ ├── ChildAgentCard.tsx
252
+ │ │ ├── ToolCardBuffering.tsx
253
+ │ │ ├── TodoCard.tsx
254
+ │ │ ├── PlanCard.tsx
255
+ │ │ └── SchemaFormRenderer.tsx
256
+ │ └── i18n/ # 国际化字典
178
257
  ├── tests/ # 集成测试
179
258
  ├── docs/ # 设计文档
180
- ├── tsup.config.ts # 构建配置
259
+ ├── tsup.config.ts # 构建配置(双入口:main + provenance)
181
260
  ├── vitest.config.ts # 测试配置
182
261
  └── package.json
183
262
  ```
184
263
 
264
+ ## 文档目录
265
+
266
+ | 编号 | 文档 | 内容 |
267
+ |------|------|------|
268
+ | 01 | [架构设计](docs/01-architecture.md) | 整体架构、数据流、消息路由规则、滚动与置顶 |
269
+ | 02 | [Adapter 接口规范](docs/02-adapter-interface.md) | ChatWidgetAdapter 接口、DefaultJetAgentsAdapter |
270
+ | 03 | [SSE 协议规范](docs/03-sse-protocol.md) | SSEMessage 结构、NotificationType、控制消息 |
271
+ | 04 | [组件详解](docs/04-components.md) | 各组件职责、渲染逻辑、Props |
272
+ | 05 | [主题与样式](docs/05-theming-and-styling.md) | CSS 变量、Light/Dark 主题、动画 |
273
+ | 06 | [性能优化](docs/06-performance.md) | RAF 批量更新、Map 索引、延迟拼接、打字机 |
274
+ | 07 | [时序图与架构图](docs/07-sequence-diagrams.md) | Mermaid 时序图、状态机、组件关系图、消息路由流程图 |
275
+ | 08 | [错误处理与重连](docs/08-error-handling.md) | 错误类型、401 Token 刷新、自动重连、容错策略 |
276
+ | 09 | [消息聚合引擎深度解析](docs/09-message-aggregation-deep-dive.md) | 索引体系、分段策略、短残片回溯、MCP 聚合、chunk 去重 |
277
+ | 10 | [测试策略](docs/10-testing-strategy.md) | 测试分层、Mock 工厂、E2E 蓝图、覆盖率要求 |
278
+ | 11 | [API 参考文档](docs/11-api-reference.md) | 完整 Props/API/类型定义、导出清单 |
279
+ | 12 | [原始设计规范](docs/12-design-spec.md) | 原始设计背景、消息协议、验收标准(移植自 JetForge) |
280
+ | 13 | [UI 设计规范](docs/13-ui-design-spec.md) | 颜色、排版、间距、动画、响应式、无障碍(移植自 JetForge) |
281
+
185
282
  ## License
186
283
 
187
- Proprietary — YumiAI
284
+ Proprietary — YumiAI
@@ -0,0 +1,11 @@
1
+ import {
2
+ ExcelCore,
3
+ ExcelCore_default
4
+ } from "./chunk-56WRZM3R.js";
5
+ import "./chunk-VXJWGLZ7.js";
6
+ import "./chunk-7D4SUZUM.js";
7
+ export {
8
+ ExcelCore,
9
+ ExcelCore_default as default
10
+ };
11
+ //# sourceMappingURL=ExcelCore-DJOIVQMI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,65 @@
1
+ import {
2
+ injectStyles,
3
+ useResource,
4
+ useResourceContext
5
+ } from "./chunk-GAMA3VA7.js";
6
+ import "./chunk-7D4SUZUM.js";
7
+
8
+ // src/components/JsonRender/domain/ExcelViewer.tsx
9
+ import React, { useEffect } from "react";
10
+ import { jsx, jsxs } from "react/jsx-runtime";
11
+ var STYLE_ID = "jr-styles-excel-viewer";
12
+ var SHEET = `
13
+ .jr-excel-viewer { width: 100%; min-width: 0; max-width: 100%; min-height: 300px; }
14
+ .jr-excel-viewer--loading, .jr-excel-viewer--error {
15
+ padding: 1rem; font-family: var(--jr-font, system-ui, sans-serif);
16
+ color: var(--jr-text-muted, #64748b);
17
+ }
18
+ .jr-excel-viewer--error { color: var(--jr-danger, #ef4444); }
19
+ `;
20
+ var LazyExcelCore = React.lazy(() => import("./ExcelCore-DJOIVQMI.js"));
21
+ var ExcelViewer = ({ props, emit }) => {
22
+ injectStyles(STYLE_ID, SHEET);
23
+ const res = useResource({ resource_id: props.resource_id, url: props.url, content: props.content });
24
+ useEffect(() => {
25
+ if (res.loading) return;
26
+ if (res.error) {
27
+ emit?.("viewer:error", { resource_id: props.resource_id, error: res.error });
28
+ } else {
29
+ emit?.("viewer:loaded", { resource_id: props.resource_id, mimeType: res.mimeType, fileName: res.fileName });
30
+ }
31
+ }, [res.loading, res.error]);
32
+ const ctx = useResourceContext();
33
+ if (res.loading) return /* @__PURE__ */ jsx("div", { className: "jr-excel-viewer jr-excel-viewer--loading", children: "Loading\u2026" });
34
+ if (res.error) return /* @__PURE__ */ jsx("div", { className: "jr-excel-viewer jr-excel-viewer--error", children: res.error });
35
+ const textContent = res.content;
36
+ const src = res.url;
37
+ const isLegacy = res.fileName?.match(/\.xls$/i) && !res.fileName?.match(/\.xlsx$/i);
38
+ if (isLegacy && ctx?.resolvePreviewUrl && props.resource_id) {
39
+ return /* @__PURE__ */ jsx(LegacyFallback, { resourceId: props.resource_id, ctx });
40
+ }
41
+ if (textContent) {
42
+ return /* @__PURE__ */ jsx("div", { className: "jr-excel-viewer ycw-excel-viewer", children: /* @__PURE__ */ jsx(React.Suspense, { fallback: /* @__PURE__ */ jsx("div", { className: "jr-excel-viewer--loading", children: "Loading Excel viewer\u2026" }), children: /* @__PURE__ */ jsx(LazyExcelCore, { content: textContent, sheet: props.sheet }) }) });
43
+ }
44
+ if (!src) return /* @__PURE__ */ jsx("div", { className: "jr-excel-viewer jr-excel-viewer--error", children: "No spreadsheet source" });
45
+ return /* @__PURE__ */ jsx("div", { className: "jr-excel-viewer ycw-excel-viewer", children: /* @__PURE__ */ jsx(React.Suspense, { fallback: /* @__PURE__ */ jsx("div", { className: "jr-excel-viewer--loading", children: "Loading Excel viewer\u2026" }), children: /* @__PURE__ */ jsx(LazyExcelCore, { src, sheet: props.sheet }) }) });
46
+ };
47
+ var LegacyFallback = ({ resourceId, ctx }) => {
48
+ const [previewUrl, setPreviewUrl] = React.useState();
49
+ const [error, setError] = React.useState();
50
+ React.useEffect(() => {
51
+ ctx.resolvePreviewUrl?.(resourceId, "html").then((url) => setPreviewUrl(url)).catch((err) => setError(String(err?.message ?? err)));
52
+ }, [resourceId, ctx]);
53
+ if (error) return /* @__PURE__ */ jsxs("div", { className: "jr-excel-viewer jr-excel-viewer--error", children: [
54
+ ".xls preview failed: ",
55
+ error
56
+ ] });
57
+ if (!previewUrl) return /* @__PURE__ */ jsx("div", { className: "jr-excel-viewer jr-excel-viewer--loading", children: "Converting .xls\u2026" });
58
+ return /* @__PURE__ */ jsx("div", { className: "jr-excel-viewer", children: /* @__PURE__ */ jsx("iframe", { src: previewUrl, title: "Excel Preview", style: { width: "100%", height: 600, border: "none" } }) });
59
+ };
60
+ var ExcelViewer_default = ExcelViewer;
61
+ export {
62
+ ExcelViewer,
63
+ ExcelViewer_default as default
64
+ };
65
+ //# sourceMappingURL=ExcelViewer-3YLLYYIQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/JsonRender/domain/ExcelViewer.tsx"],"sourcesContent":["import React, { useEffect } from 'react'\nimport { useResource } from '../../../hooks/useResource.js'\nimport { useResourceContext } from '../../../contexts/ResourceContext.js'\nimport { injectStyles } from './injectStyles.js'\n\nconst STYLE_ID = 'jr-styles-excel-viewer'\nconst SHEET = `\n.jr-excel-viewer { width: 100%; min-width: 0; max-width: 100%; min-height: 300px; }\n.jr-excel-viewer--loading, .jr-excel-viewer--error {\n padding: 1rem; font-family: var(--jr-font, system-ui, sans-serif);\n color: var(--jr-text-muted, #64748b);\n}\n.jr-excel-viewer--error { color: var(--jr-danger, #ef4444); }\n`\n\ninterface Props {\n props: {\n resource_id?: string\n url?: string\n content?: string\n title?: string\n sheet?: string\n }\n emit?: (event: string, data?: unknown) => void\n}\n\nconst LazyExcelCore = React.lazy(() => import('../../ViewerCore/ExcelCore.js'))\n\nexport const ExcelViewer: React.FC<Props> = ({ props, emit }) => {\n injectStyles(STYLE_ID, SHEET)\n const res = useResource({ resource_id: props.resource_id, url: props.url, content: props.content })\n\n useEffect(() => {\n if (res.loading) return\n if (res.error) {\n emit?.('viewer:error', { resource_id: props.resource_id, error: res.error })\n } else {\n emit?.('viewer:loaded', { resource_id: props.resource_id, mimeType: res.mimeType, fileName: res.fileName })\n }\n }, [res.loading, res.error])\n\n const ctx = useResourceContext()\n\n if (res.loading) return <div className=\"jr-excel-viewer jr-excel-viewer--loading\">Loading…</div>\n if (res.error) return <div className=\"jr-excel-viewer jr-excel-viewer--error\">{res.error}</div>\n\n const textContent = res.content\n const src = res.url\n const isLegacy = res.fileName?.match(/\\.xls$/i) && !res.fileName?.match(/\\.xlsx$/i)\n\n if (isLegacy && ctx?.resolvePreviewUrl && props.resource_id) {\n return <LegacyFallback resourceId={props.resource_id} ctx={ctx} />\n }\n\n if (textContent) {\n return (\n <div className=\"jr-excel-viewer ycw-excel-viewer\">\n <React.Suspense fallback={<div className=\"jr-excel-viewer--loading\">Loading Excel viewer…</div>}>\n <LazyExcelCore content={textContent} sheet={props.sheet} />\n </React.Suspense>\n </div>\n )\n }\n\n if (!src) return <div className=\"jr-excel-viewer jr-excel-viewer--error\">No spreadsheet source</div>\n\n return (\n <div className=\"jr-excel-viewer ycw-excel-viewer\">\n <React.Suspense fallback={<div className=\"jr-excel-viewer--loading\">Loading Excel viewer…</div>}>\n <LazyExcelCore src={src} sheet={props.sheet} />\n </React.Suspense>\n </div>\n )\n}\n\nconst LegacyFallback: React.FC<{ resourceId: string; ctx: { resolvePreviewUrl?(id: string, fmt: 'html' | 'pdf'): Promise<string> } }> = ({ resourceId, ctx }) => {\n const [previewUrl, setPreviewUrl] = React.useState<string>()\n const [error, setError] = React.useState<string>()\n\n React.useEffect(() => {\n ctx.resolvePreviewUrl?.(resourceId, 'html')\n .then(url => setPreviewUrl(url))\n .catch(err => setError(String(err?.message ?? err)))\n }, [resourceId, ctx])\n\n if (error) return <div className=\"jr-excel-viewer jr-excel-viewer--error\">.xls preview failed: {error}</div>\n if (!previewUrl) return <div className=\"jr-excel-viewer jr-excel-viewer--loading\">Converting .xls…</div>\n\n return (\n <div className=\"jr-excel-viewer\">\n <iframe src={previewUrl} title=\"Excel Preview\" style={{ width: '100%', height: 600, border: 'none' }} />\n </div>\n )\n}\n\nexport default ExcelViewer\n"],"mappings":";;;;;;;;AAAA,OAAO,SAAS,iBAAiB;AA2CP,cA0CN,YA1CM;AAtC1B,IAAM,WAAW;AACjB,IAAM,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoBd,IAAM,gBAAgB,MAAM,KAAK,MAAM,OAAO,yBAA+B,CAAC;AAEvE,IAAM,cAA+B,CAAC,EAAE,OAAO,KAAK,MAAM;AAC/D,eAAa,UAAU,KAAK;AAC5B,QAAM,MAAM,YAAY,EAAE,aAAa,MAAM,aAAa,KAAK,MAAM,KAAK,SAAS,MAAM,QAAQ,CAAC;AAElG,YAAU,MAAM;AACd,QAAI,IAAI,QAAS;AACjB,QAAI,IAAI,OAAO;AACb,aAAO,gBAAgB,EAAE,aAAa,MAAM,aAAa,OAAO,IAAI,MAAM,CAAC;AAAA,IAC7E,OAAO;AACL,aAAO,iBAAiB,EAAE,aAAa,MAAM,aAAa,UAAU,IAAI,UAAU,UAAU,IAAI,SAAS,CAAC;AAAA,IAC5G;AAAA,EACF,GAAG,CAAC,IAAI,SAAS,IAAI,KAAK,CAAC;AAE3B,QAAM,MAAM,mBAAmB;AAE/B,MAAI,IAAI,QAAS,QAAO,oBAAC,SAAI,WAAU,4CAA2C,2BAAQ;AAC1F,MAAI,IAAI,MAAO,QAAO,oBAAC,SAAI,WAAU,0CAA0C,cAAI,OAAM;AAEzF,QAAM,cAAc,IAAI;AACxB,QAAM,MAAM,IAAI;AAChB,QAAM,WAAW,IAAI,UAAU,MAAM,SAAS,KAAK,CAAC,IAAI,UAAU,MAAM,UAAU;AAElF,MAAI,YAAY,KAAK,qBAAqB,MAAM,aAAa;AAC3D,WAAO,oBAAC,kBAAe,YAAY,MAAM,aAAa,KAAU;AAAA,EAClE;AAEA,MAAI,aAAa;AACf,WACE,oBAAC,SAAI,WAAU,oCACb,8BAAC,MAAM,UAAN,EAAe,UAAU,oBAAC,SAAI,WAAU,4BAA2B,wCAAqB,GACvF,8BAAC,iBAAc,SAAS,aAAa,OAAO,MAAM,OAAO,GAC3D,GACF;AAAA,EAEJ;AAEA,MAAI,CAAC,IAAK,QAAO,oBAAC,SAAI,WAAU,0CAAyC,mCAAqB;AAE9F,SACE,oBAAC,SAAI,WAAU,oCACb,8BAAC,MAAM,UAAN,EAAe,UAAU,oBAAC,SAAI,WAAU,4BAA2B,wCAAqB,GACvF,8BAAC,iBAAc,KAAU,OAAO,MAAM,OAAO,GAC/C,GACF;AAEJ;AAEA,IAAM,iBAAkI,CAAC,EAAE,YAAY,IAAI,MAAM;AAC/J,QAAM,CAAC,YAAY,aAAa,IAAI,MAAM,SAAiB;AAC3D,QAAM,CAAC,OAAO,QAAQ,IAAI,MAAM,SAAiB;AAEjD,QAAM,UAAU,MAAM;AACpB,QAAI,oBAAoB,YAAY,MAAM,EACvC,KAAK,SAAO,cAAc,GAAG,CAAC,EAC9B,MAAM,SAAO,SAAS,OAAO,KAAK,WAAW,GAAG,CAAC,CAAC;AAAA,EACvD,GAAG,CAAC,YAAY,GAAG,CAAC;AAEpB,MAAI,MAAO,QAAO,qBAAC,SAAI,WAAU,0CAAyC;AAAA;AAAA,IAAsB;AAAA,KAAM;AACtG,MAAI,CAAC,WAAY,QAAO,oBAAC,SAAI,WAAU,4CAA2C,mCAAgB;AAElG,SACE,oBAAC,SAAI,WAAU,mBACb,8BAAC,YAAO,KAAK,YAAY,OAAM,iBAAgB,OAAO,EAAE,OAAO,QAAQ,QAAQ,KAAK,QAAQ,OAAO,GAAG,GACxG;AAEJ;AAEA,IAAO,sBAAQ;","names":[]}