@tfdesign/b-end 1.0.4

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 (176) hide show
  1. package/AI_READ_FIRST.md +131 -0
  2. package/LICENSE +21 -0
  3. package/README.md +353 -0
  4. package/package.json +67 -0
  5. package/scripts/check-tfds-contract.mjs +334 -0
  6. package/scripts/check-tfds-integration.mjs +263 -0
  7. package/scripts/postinstall-cursor-skill.mjs +382 -0
  8. package/scripts/setup.mjs +520 -0
  9. package/skills/tfds/CHECKLIST.md +205 -0
  10. package/skills/tfds/COMMON_FAILURES.md +238 -0
  11. package/skills/tfds/DESIGN_PRINCIPLES.md +477 -0
  12. package/skills/tfds/GLOBAL_DESIGN_RULES.md +636 -0
  13. package/skills/tfds/LAYOUT_RECIPES.md +140 -0
  14. package/skills/tfds/LAYOUT_RULES.md +1355 -0
  15. package/skills/tfds/PAGE_ARCHETYPES.md +201 -0
  16. package/skills/tfds/SKILL.md +188 -0
  17. package/skills/tfds/components.index.json +7305 -0
  18. package/skills/tfds/components.summary.json +1809 -0
  19. package/src/_b_end_runtime/components/AiSuggestionShared.jsx +166 -0
  20. package/src/_b_end_runtime/components/Avatar.jsx +325 -0
  21. package/src/_b_end_runtime/components/Avatar.tokens.js +76 -0
  22. package/src/_b_end_runtime/components/AvatarGridPreview.jsx +56 -0
  23. package/src/_b_end_runtime/components/AvatarGroup.jsx +80 -0
  24. package/src/_b_end_runtime/components/AvatarGroup.tokens.js +28 -0
  25. package/src/_b_end_runtime/components/Button.jsx +144 -0
  26. package/src/_b_end_runtime/components/Button.tokens.js +90 -0
  27. package/src/_b_end_runtime/components/Card.jsx +460 -0
  28. package/src/_b_end_runtime/components/Card.tokens.js +124 -0
  29. package/src/_b_end_runtime/components/CardPreview.jsx +51 -0
  30. package/src/_b_end_runtime/components/ChatBubble.jsx +384 -0
  31. package/src/_b_end_runtime/components/ChatBubble.tokens.js +60 -0
  32. package/src/_b_end_runtime/components/ChatBubblePreview.jsx +129 -0
  33. package/src/_b_end_runtime/components/ChatInput.jsx +1399 -0
  34. package/src/_b_end_runtime/components/ChatInput.tokens.js +75 -0
  35. package/src/_b_end_runtime/components/ChatMessage.jsx +2215 -0
  36. package/src/_b_end_runtime/components/ChatMessage.tokens.js +257 -0
  37. package/src/_b_end_runtime/components/ChatMessagePreview.jsx +388 -0
  38. package/src/_b_end_runtime/components/Checkbox.jsx +317 -0
  39. package/src/_b_end_runtime/components/Checkbox.tokens.js +59 -0
  40. package/src/_b_end_runtime/components/ConversationList.jsx +1264 -0
  41. package/src/_b_end_runtime/components/ConversationList.tokens.js +135 -0
  42. package/src/_b_end_runtime/components/ConversationListPreview.jsx +108 -0
  43. package/src/_b_end_runtime/components/CustomerServiceWorkspaceFrame.jsx +324 -0
  44. package/src/_b_end_runtime/components/CustomerServiceWorkspaceFrame.tokens.js +69 -0
  45. package/src/_b_end_runtime/components/DatePicker.jsx +739 -0
  46. package/src/_b_end_runtime/components/DatePicker.tokens.js +99 -0
  47. package/src/_b_end_runtime/components/Empty.jsx +141 -0
  48. package/src/_b_end_runtime/components/Empty.tokens.js +40 -0
  49. package/src/_b_end_runtime/components/Form.jsx +609 -0
  50. package/src/_b_end_runtime/components/Form.tokens.js +77 -0
  51. package/src/_b_end_runtime/components/FormFieldStack.jsx +123 -0
  52. package/src/_b_end_runtime/components/FormFieldStack.tokens.js +12 -0
  53. package/src/_b_end_runtime/components/FormTitle.jsx +119 -0
  54. package/src/_b_end_runtime/components/FormTitle.tokens.js +87 -0
  55. package/src/_b_end_runtime/components/FullScreenPage.jsx +97 -0
  56. package/src/_b_end_runtime/components/FullScreenPage.tokens.js +19 -0
  57. package/src/_b_end_runtime/components/Icon.jsx +172 -0
  58. package/src/_b_end_runtime/components/Icon.tokens.js +26 -0
  59. package/src/_b_end_runtime/components/IconGridPreview.jsx +277 -0
  60. package/src/_b_end_runtime/components/InfoDisplayPanel.jsx +620 -0
  61. package/src/_b_end_runtime/components/InfoDisplayPanel.tokens.js +71 -0
  62. package/src/_b_end_runtime/components/InfoDisplayPanelPreview.jsx +133 -0
  63. package/src/_b_end_runtime/components/Input.jsx +258 -0
  64. package/src/_b_end_runtime/components/Input.tokens.js +68 -0
  65. package/src/_b_end_runtime/components/InputNumber.jsx +242 -0
  66. package/src/_b_end_runtime/components/InputNumber.tokens.js +55 -0
  67. package/src/_b_end_runtime/components/Modal.jsx +155 -0
  68. package/src/_b_end_runtime/components/Modal.tokens.js +73 -0
  69. package/src/_b_end_runtime/components/NavBar.jsx +842 -0
  70. package/src/_b_end_runtime/components/NavBar.tokens.js +97 -0
  71. package/src/_b_end_runtime/components/NavBarPreview.jsx +11 -0
  72. package/src/_b_end_runtime/components/Radio.jsx +227 -0
  73. package/src/_b_end_runtime/components/Radio.tokens.js +59 -0
  74. package/src/_b_end_runtime/components/Select.jsx +766 -0
  75. package/src/_b_end_runtime/components/Select.tokens.js +99 -0
  76. package/src/_b_end_runtime/components/Sheet.jsx +132 -0
  77. package/src/_b_end_runtime/components/Sheet.tokens.js +61 -0
  78. package/src/_b_end_runtime/components/Slider.jsx +346 -0
  79. package/src/_b_end_runtime/components/Slider.tokens.js +47 -0
  80. package/src/_b_end_runtime/components/Switch.jsx +124 -0
  81. package/src/_b_end_runtime/components/Switch.tokens.js +38 -0
  82. package/src/_b_end_runtime/components/Table.jsx +1338 -0
  83. package/src/_b_end_runtime/components/Table.tokens.js +147 -0
  84. package/src/_b_end_runtime/components/TablePreview.jsx +599 -0
  85. package/src/_b_end_runtime/components/Tabs.jsx +149 -0
  86. package/src/_b_end_runtime/components/Tabs.tokens.js +102 -0
  87. package/src/_b_end_runtime/components/Tag.jsx +199 -0
  88. package/src/_b_end_runtime/components/Tag.tokens.js +171 -0
  89. package/src/_b_end_runtime/components/TagBar.jsx +1134 -0
  90. package/src/_b_end_runtime/components/TagBar.tokens.js +75 -0
  91. package/src/_b_end_runtime/components/TagGridPreview.jsx +23 -0
  92. package/src/_b_end_runtime/components/TagInput.jsx +382 -0
  93. package/src/_b_end_runtime/components/TagInput.tokens.js +52 -0
  94. package/src/_b_end_runtime/components/TextArea.jsx +363 -0
  95. package/src/_b_end_runtime/components/TextArea.tokens.js +65 -0
  96. package/src/_b_end_runtime/components/TimePicker.jsx +444 -0
  97. package/src/_b_end_runtime/components/TimePicker.tokens.js +77 -0
  98. package/src/_b_end_runtime/components/Toast.jsx +120 -0
  99. package/src/_b_end_runtime/components/Toast.tokens.js +146 -0
  100. package/src/_b_end_runtime/components/Tooltip.jsx +282 -0
  101. package/src/_b_end_runtime/components/Tooltip.tokens.js +48 -0
  102. package/src/_b_end_runtime/components/TooltipPreview.jsx +50 -0
  103. package/src/_b_end_runtime/components/Upload.jsx +455 -0
  104. package/src/_b_end_runtime/components/Upload.tokens.js +47 -0
  105. package/src/_b_end_runtime/components/avatar-assets/avatar-default.png +0 -0
  106. package/src/_b_end_runtime/components/avatar-group-assets/avatar-group-1.png +0 -0
  107. package/src/_b_end_runtime/components/avatar-group-assets/avatar-group-2.png +0 -0
  108. package/src/_b_end_runtime/components/avatar-group-assets/avatar-group-3.png +0 -0
  109. package/src/_b_end_runtime/components/avatar-group-assets/avatar-group-4.png +0 -0
  110. package/src/_b_end_runtime/components/avatar-group-assets/avatar-group-5.png +0 -0
  111. package/src/_b_end_runtime/components/empty-assets/administrator-1.svg +40 -0
  112. package/src/_b_end_runtime/components/empty-assets/administrator-2.svg +33 -0
  113. package/src/_b_end_runtime/components/empty-assets/construction.svg +33 -0
  114. package/src/_b_end_runtime/components/empty-assets/failure.svg +49 -0
  115. package/src/_b_end_runtime/components/empty-assets/idle.svg +34 -0
  116. package/src/_b_end_runtime/components/empty-assets/no-access.svg +36 -0
  117. package/src/_b_end_runtime/components/empty-assets/no-content.svg +77 -0
  118. package/src/_b_end_runtime/components/empty-assets/no-result.svg +61 -0
  119. package/src/_b_end_runtime/components/empty-assets/not-found.svg +46 -0
  120. package/src/_b_end_runtime/components/empty-assets/success.svg +38 -0
  121. package/src/_b_end_runtime/components/file-type-assets/batch-report.png +0 -0
  122. package/src/_b_end_runtime/components/file-type-assets/catcat.svg +21 -0
  123. package/src/_b_end_runtime/components/file-type-assets/code.png +0 -0
  124. package/src/_b_end_runtime/components/file-type-assets/conversation.png +0 -0
  125. package/src/_b_end_runtime/components/file-type-assets/document.png +0 -0
  126. package/src/_b_end_runtime/components/file-type-assets/feishu-card.png +0 -0
  127. package/src/_b_end_runtime/components/file-type-assets/feishu-sheet.png +0 -0
  128. package/src/_b_end_runtime/components/file-type-assets/feishu.png +0 -0
  129. package/src/_b_end_runtime/components/file-type-assets/image.png +0 -0
  130. package/src/_b_end_runtime/components/file-type-assets/index.js +105 -0
  131. package/src/_b_end_runtime/components/file-type-assets/knowledge.png +0 -0
  132. package/src/_b_end_runtime/components/file-type-assets/pdf.png +0 -0
  133. package/src/_b_end_runtime/components/file-type-assets/pe.png +0 -0
  134. package/src/_b_end_runtime/components/file-type-assets/strategy.png +0 -0
  135. package/src/_b_end_runtime/components/file-type-assets/table.png +0 -0
  136. package/src/_b_end_runtime/components/file-type-assets/webpage.png +0 -0
  137. package/src/_b_end_runtime/components/file-type-assets/xmind.png +0 -0
  138. package/src/_b_end_runtime/components/icons/icon-data.js +12496 -0
  139. package/src/_b_end_runtime/components/nav-bar-assets/bytehi-logo-mark.svg +21 -0
  140. package/src/_b_end_runtime/components/table-assets/avatar.png +0 -0
  141. package/src/_b_end_runtime/components/table-assets/button.png +0 -0
  142. package/src/_b_end_runtime/components/table-assets/icon-chevron-down.png +0 -0
  143. package/src/_b_end_runtime/components/table-cell-assets/avatar.png +0 -0
  144. package/src/_b_end_runtime/components/table-cell-assets/button.png +0 -0
  145. package/src/_b_end_runtime/components/table-cell-assets/checkbox.png +0 -0
  146. package/src/_b_end_runtime/components/table-cell-assets/icon-chevron-right.png +0 -0
  147. package/src/_b_end_runtime/components/table-cell-assets/icon.png +0 -0
  148. package/src/_b_end_runtime/components/table-cell-assets/semi-icons-handle.png +0 -0
  149. package/src/_b_end_runtime/components/table-cell-assets/semi-icons-tree-triangle-right.png +0 -0
  150. package/src/_b_end_runtime/components/table-cell-assets/switch.png +0 -0
  151. package/src/_b_end_runtime/components/tagShared.js +3 -0
  152. package/src/_b_end_runtime/components/team-avatar-assets/chengcheng-murphy.png +0 -0
  153. package/src/_b_end_runtime/components/team-avatar-assets/duan-ran.png +0 -0
  154. package/src/_b_end_runtime/components/team-avatar-assets/guo-zhezhi.png +0 -0
  155. package/src/_b_end_runtime/components/team-avatar-assets/li-siru.png +0 -0
  156. package/src/_b_end_runtime/components/team-avatar-assets/liu-delin.png +0 -0
  157. package/src/_b_end_runtime/components.js +3499 -0
  158. package/src/_b_end_runtime/index.js +9 -0
  159. package/src/_b_end_runtime/page-patterns/BasePageFramePattern.jsx +395 -0
  160. package/src/_b_end_runtime/page-patterns/ChatConversationPattern.jsx +989 -0
  161. package/src/_b_end_runtime/page-patterns/ChatHomePagePattern.jsx +281 -0
  162. package/src/_b_end_runtime/page-patterns/CopilotPagePattern.jsx +380 -0
  163. package/src/_b_end_runtime/page-patterns/CustomerServiceWorkspaceFramePattern.jsx +392 -0
  164. package/src/_b_end_runtime/page-patterns/IMConversationPattern.jsx +590 -0
  165. package/src/_b_end_runtime/page-patterns/McpManagementPage.jsx +237 -0
  166. package/src/_b_end_runtime/page-patterns/StrategyListPage.jsx +189 -0
  167. package/src/_b_end_runtime/page-patterns/TabTopBarListPage.jsx +594 -0
  168. package/src/_b_end_runtime/page-patterns/VariableManagementPage.jsx +87 -0
  169. package/src/_b_end_runtime/page-patterns/pageListShared.jsx +177 -0
  170. package/src/_b_end_runtime/patterns.js +428 -0
  171. package/src/_b_end_runtime/preview-registry.jsx +4719 -0
  172. package/src/_b_end_runtime/teamMembers.js +56 -0
  173. package/src/_b_end_runtime/tokens.js +500 -0
  174. package/src/index.d.ts +1073 -0
  175. package/src/index.js +52 -0
  176. package/theme.css +350 -0
@@ -0,0 +1,428 @@
1
+ // B端设计系统 — 页面模版
2
+ //
3
+ // 每个 pattern 代表一类完整页面的布局参考。
4
+ // 主要服务于两个对象:
5
+ // 1) 设计师/前端 — 在详情页查看 Preview 真实组件渲染,复用现成组件搭页
6
+ // 2) AI — 读取 description / components / rules / code,作为页面级布局规范
7
+ //
8
+ // 字段约定:
9
+ // id 唯一 id,用于路由
10
+ // name 中文名
11
+ // description 一句话说明
12
+ // Preview React 组件(可选);提供时详情页会渲染真实可交互预览
13
+ // components 本模版所引用的组件 id 列表
14
+ // rules 布局规范要点(数组)
15
+ // code 最小可运行的代码片段(字符串)
16
+
17
+ import BasePageFramePattern from './page-patterns/BasePageFramePattern';
18
+ import ChatHomePagePattern from './page-patterns/ChatHomePagePattern';
19
+ import CopilotPagePattern from './page-patterns/CopilotPagePattern';
20
+ import ChatConversationPattern from './page-patterns/ChatConversationPattern';
21
+ import IMConversationPattern from './page-patterns/IMConversationPattern';
22
+ import CustomerServiceWorkspaceFramePattern from './page-patterns/CustomerServiceWorkspaceFramePattern';
23
+
24
+ export const PATTERNS = [
25
+ {
26
+ id: 'customer-service-workspace-frame',
27
+ name: '客服工作台框架',
28
+ description:
29
+ '客服 / 在线 Agent 工作台页面框架:顶部在线状态、指标工具区、基础/托管模式切换、半透明工作区与右侧主白卡。适用于客服正在处理会话、工单、质检、托管等工作台页面。',
30
+ keywords: [
31
+ '客服工作台框架', '客服工作台', '客服框架', '在线Agent', '在线 Agent', 'Agent 工作台',
32
+ '客服名称', '在线状态', '在线时长', '基础模式', '托管模式',
33
+ '指标工具条', '客服顶部状态栏', '在线接待数', '已处理数',
34
+ '主工作区框架', '会话处理框架', 'IM 工作台框架', '工单处理框架',
35
+ 'CustomerServiceWorkspaceFrame', 'customer-service-workspace-frame',
36
+ ],
37
+ Preview: CustomerServiceWorkspaceFramePattern,
38
+ previewPadding: 0,
39
+ components: ['button', 'tabs', 'icon', 'conversation-list', 'chat-bubble', 'chat-input', 'tag', 'avatar', 'info-display-panel', 'table'],
40
+ rules: [
41
+ '【模板定位】本模板是客服 / 在线 Agent 工作台的页面级框架,用于“客服正在处理会话、工单、质检、托管”等工作台页面;它不是普通业务组件、不是 NavBar,也不是会话列表本体。',
42
+ '【Figma 对齐】默认视觉对齐 Figma 节点 8279:67909「在线Agent」:根容器浅灰底 `--color-blueGrey-200`、16px 内边距、顶部 24px 状态条、下方左侧半透明板块 + 右侧主白卡;6 个可见圆角统一为 16px:左侧板块左上 / 左下,右侧主白卡四角。',
43
+ '【结构】根节点必须直接作为页面主工作区或右侧主内容区的一级框架;内部顺序固定为 Header(客服名称 / 在线状态 / 指标工具 / 模式切换) + Workspace(左侧上下文占位 + 右侧主面板)。不要再用大白卡或 `bg-surface rounded-*` 包住整个模板。',
44
+ '【顶部栏】左侧显示客服名称与在线时长;中部数据栏必须默认按页面可用宽度动态居中,不随左侧客服名称或右侧模式切换偏移;指标容器使用 `bg-white/60 + border-white + radius-md + px-4 py-1`;在线状态胶囊与工具入口这类按钮化页面元素必须复用基础 `Button`;右侧基础模式 / 托管模式属于同页模式切换,必须复用基础 `Tabs`,默认使用 `variant="segment"`,不要手写 tab button 或用 NavBar 替代。',
45
+ '【工作区层级】Workspace 外层只负责横向布局、覆盖层级与拖拽,不承担可见圆角;左侧板块自身为 `bg-white/50 + border-white + rounded-xl`,右侧主面板自身为白色 `surface + border-white + rounded-xl`,两者高度一致、宽度不同,并通过主面板 `margin-left: -32px` 形成“右侧白板覆盖在左侧灰板上”的叠压视觉,而不是中间留缝的并排关系。',
46
+ '【可见圆角】最终可见的 6 个角统一为 16px:左侧板块左上 / 左下两个角露出;右侧主白卡四角露出;左侧板块右上 / 右下两个角必须被右侧主白卡完整覆盖。主面板覆盖量必须大于圆角半径(推荐 32px = 2 × 16px),防止主面板左上 / 左下圆角切角处露出左侧板块的右边界或描边,避免出现“残缺一块”的视觉。',
47
+ '【左右拖拽】左侧区域与右侧主白卡之间必须提供纵向拖拽热区,默认热区 8px;拖拽热区覆盖在主面板左边缘上,不占用布局宽度、不制造中间空隙;拖动时调整左侧区域宽度并让右侧主面板 `flex-1 min-w-0` 自动占满剩余空间;左侧默认宽度 432px(400px 可视会话列表 + 32px 主面板覆盖区);拖拽最小宽度优先由左侧业务组件最小可用宽度决定,例如 ConversationList 默认列表纯头像锁定 88px 时,左侧板块最小宽度为 `max(100px 框架兜底, 88px + 32px 覆盖区) = 120px`;ConversationList 卡片列表最小内容宽度为 333px,左侧板块最小宽度为 365px;右侧纯白主容器最小宽度 380px,左侧最大可拖宽度需按 `工作区宽度 + 32px 覆盖量 - 380px` 动态计算;拖拽条需支持键盘左右方向键微调。',
48
+ '【左侧插槽】左侧半透明容器默认承载平台业务组件 `ConversationList`,用于会话 / 工单 / 托管队列切换;左侧内容区必须扣除右侧 32px 覆盖安全区,避免被主白卡裁切;`ConversationList` 展开态四周内容间距固定 16px。嵌入时 `ConversationList` 必须设置 `resizable={false}`、保留 `collapsible` 与 `autoCollapseOnNarrow`、`style={{ width: "100%", height: "100%" }}`,并在外层框架接入 `onLayoutWidthRequest` 与 `onVariantChange`:默认列表传 `leftContentMinWidth={88}`,卡片列表切换为 `leftContentMinWidth={333}`。框架统一管理宽度拖拽,但拖拽下限跟随子组件能力;点击会话列表左上角收起按钮时,外层左侧半透明容器必须同步吸附缩窄到 120px,不允许只把 ConversationList 缩到头像列而外层仍保留大片空白。',
49
+ '【左侧选中项 = 右侧上下文源】客服工作台框架内左侧 `ConversationList` 默认必须存在一个当前选中项;它不是单纯的导航高亮,而是整个右侧主白卡的上下文源。切换左侧会话 / 工单 / 托管项时,右侧纯白容器里的 IM 对话区和 InfoDisplayPanel 信息区都必须同步切换到同一个当前处理对象,禁止出现“左侧已切到 B 会话,但右侧聊天仍是 A、信息区还是 C”的上下文错位。预览实现必须以 `activeConversationId` 作为单一事实源:左侧列表头像、标题、单号与右侧 IM Header 的头像、标题、会话 ID、渠道、沟通时长和消息脚本必须一一对应,不能只更新高亮而复用固定聊天剧本。',
50
+ '【左侧卡片列表】`ConversationList variant="card"` 嵌入左栏时,卡片列数必须基于左侧内容区实际宽度动态判断:`<=580px` 为 1 列,`>580px` 为 2 列,`>950px` 为 3 列;外层拖拽变宽 / 变窄时卡片栅格必须实时跟随,不能固定按默认 400px 宽度生成单列。',
51
+ '【右侧主白卡默认内容】右侧主白卡默认采用左右分栏:左侧嵌入 IMConversationPattern 作为当前会话处理区,右侧嵌入 InfoDisplayPanel 作为用户信息、历史工单、工单日志、视频信息等辅助信息区;外层主白卡只负责容器、裁切、间距和分栏,不再额外套大白卡。',
52
+ '【右侧布局规则】右侧主白卡内默认 `p-4 + gap-4`,左侧 IM 对话区使用 `flex-1 min-w-0` 吃剩余空间,右侧 InfoDisplayPanel 为独立信息栏;框架 mainMinWidth 建议不低于 720px,避免 IM 对话与信息面板互相挤压。IMConversationPattern 和 InfoDisplayPanel 都必须 `height: 100%` 填满主白卡高度,并由各自组件自管内部滚动。',
53
+ '【右侧纯白卡语义】右侧纯白色主卡定义的是“当前处理对象的完整工作区”,不是两个彼此独立的小组件容器。IMConversationPattern 负责当前线程消息往返,InfoDisplayPanel 负责同一对象的辅助信息、历史工单、日志、视频信息、用户信息等;两者必须共享同一个当前会话 / 工单 / 线程上下文。',
54
+ '【状态同步原则】当业务接真实数据、URL 或埋点时,应以左侧当前选中对象 id 作为单一事实源(single source of truth),再派生右侧聊天流和信息面板内容;不要让 IMConversationPattern 和 InfoDisplayPanel 各自维护独立当前对象状态。',
55
+ '【右侧信息栏整体拖拽】在客服工作台框架模版里,右侧 InfoDisplayPanel 必须支持整体宽度拖拽,拖拽热区位于信息栏左边界,默认热区 8px;拖拽时改变的是右侧信息栏整体宽度,左侧 IM 聊天区自动占满剩余空间,而不是改由 InfoDisplayPanel 本体处理页面级宽度。推荐默认宽度约 380px,最小宽度 320px,并保证左侧 IM 区至少保留 360px 可读宽度;同时保留 InfoDisplayPanel 内部相邻栏之间的原生拖拽能力。',
56
+ '【右侧插槽】如业务需要替换右侧主内容,可放 ChatConversationPattern、Table、表单详情或工单处理面板;但客服接待类页面优先保持“IM 对话 + InfoDisplayPanel”的组合,不要用多个普通 Card 临时拼出右侧信息区。',
57
+ '【AI 选型】当 prompt 出现“客服工作台框架 / 在线 Agent / Agent 工作台 / 基础模式 / 托管模式 / 客服名称在线状态 / 顶部指标工具条”等信号时,优先选本页面模板;如果只是全局左侧导航,选 NavBar;如果只是会话队列,选 ConversationList;如果只是单条消息,选 ChatMessage / ChatBubble。',
58
+ '【容器语义】本模板自身已经包含浅灰页面底与右侧主白卡,生成页面时不要外层再套 `Card color="grey"`、`bg-surface rounded-xl` 或大白卡 section,否则会形成“灰底 + 大白卡 + 框架”的错误嵌套。',
59
+ '【组件复用】统计图标、工具图标必须复用 `Icon`;在线状态胶囊与工具按钮必须复用 `Button`;右上角模式切换必须复用 `Tabs`;主面板内若有头像,继续遵守本地成员头像素材规则;不要手写 svg、tab button、button div 或随机外链头像。',
60
+ ],
61
+ code: `import CustomerServiceWorkspaceFramePattern from './page-patterns/CustomerServiceWorkspaceFramePattern';
62
+
63
+ export default function CustomerServicePage() {
64
+ return <CustomerServiceWorkspaceFramePattern />;
65
+ }`,
66
+ },
67
+ {
68
+ id: 'base-page-frame',
69
+ name: '基础页面框架',
70
+ description:
71
+ 'B 端列表页模板示例集:左侧 NavBar 业务侧导(5 个"列表示例"菜单),每项对应一个独立完整的列表页模板。每个模板自上而下:标题栏 + 筛选栏 + 表格,业务可直接复制单文件作为新页面起点。',
72
+ keywords: [
73
+ '基础页面框架', '页面框架', '列表页', '管理页', '后台页',
74
+ 'B 端管理后台', 'B端列表页', '白卡管理页', '左导航 + 右内容', 'NavBar 列表',
75
+ '变量管理', 'MCP 管理', '工具管理', '策略管理', '策略列表', '版本子行',
76
+ '知识库管理', 'QA 列表', '案例库', '审核配置', '数据资产管理',
77
+ '筛选栏', '搜索 + 表格', '标题栏 + 筛选栏 + 表格',
78
+ '单白卡', '双白卡', 'TagBar 分类树筛选', '左侧维度筛选',
79
+ // 错误信号词(用户描述触发场景)
80
+ '管理一批', '一批对象', '增删改查', 'CRUD 页面',
81
+ // 反向引导:Playground/多面板对照工作 → 不属于本 pattern,请改用 LAYOUT_RULES § 3.4 / § 12.7
82
+ 'Playground 反向引导', 'Prompt Editor 反向引导', 'IDE 多面板反向引导',
83
+ '调试器布局', '试验台布局', '多面板工作台', '输入+输出+参数 三栏对照',
84
+ ],
85
+ Preview: BasePageFramePattern,
86
+ /* 该模板本身贴浏览器边缘展示(无外圈圆角),预览容器无需再额外 padding */
87
+ previewPadding: 0,
88
+ components: [
89
+ 'nav-bar', 'form-title', 'tag-bar', 'tabs', 'button', 'icon', 'input', 'select',
90
+ 'date-picker', 'tag-input', 'checkbox', 'table', 'tag', 'modal', 'sheet', 'empty', 'full-screen-page',
91
+ ],
92
+ rules: [
93
+ '【框架不动】外框为“灰底整页背景容器”,贴浏览器边缘展示(不做外圈圆角、不做外圈描边);左侧 NavBar、右侧白卡分区均为系统约束,不允许修改侧导宽度/白卡圆角与节奏',
94
+ '【布局 Recipe】必须按 `LAYOUT_RECIPES.md` 选择 `base-management`:灰底 AppShell + `main p-4 gap-2` + 一张或多张白色 WorkSurface;页面 header / 顶部 Tabs / 主次操作直接坐灰底。',
95
+ '【五模板定位】本模板只解决“管理一批结构化对象”的 B 端工作区:变量、MCP、策略、知识库、数据资产、审核任务、配置列表等。用户第一步必须是筛选 / 搜索 / 浏览对象 / 批量操作 / 查看详情;如果第一步是“输入一句需求开始 AI 任务”,改用 `ChatHomePagePattern`;如果第一步是“继续追问 AI 任务”,改用 `ChatConversationPattern`;如果右侧主角是对象/产物编辑且 AI 只是侧助,改用 `CopilotPagePattern`;如果是真实客服/私信线程,改用 `IMConversationPattern`。',
96
+ '【组件选型门禁】白卡标题必须用 `FormTitle`;筛选字段按语义用 `Input` / `Select` / `DatePicker` / `TagInput` / `Checkbox`;结构化列表必须用 `Table`;状态/类型/数量徽标必须用 `Tag`;所有操作必须用 `Button`;左侧分类维度必须用 `TagBar`;弹层按复杂度用 `Modal` 或 `Sheet`;空状态用 `Empty`。禁止手写标题、状态徽标、表格、筛选胶囊或按钮。',
97
+ '【页面范式选型总则】TFDS 页面框架不只有一种白卡管理页范式。生成页面前必须先判断“用户当前要完成什么任务”,再在 `BasePageFramePattern`、`ChatHomePagePattern`、`ChatConversationPattern`(必要时 `CopilotPagePattern`)之间选最合适的页面模板,禁止把所有页面默认都生成成白卡单栏/双栏/多栏管理页。',
98
+ '【判断标准】用“用户进入页面后的第一步动作”决定布局:第一步是“发起一个 AI 任务 / 输入一句需求 / 从模板开始”→ 优先 `ChatHomePagePattern`(AI 入口页);第一步是“围绕一个已开始的任务持续追问、查看消息流、继续与 AI 协作”→ 优先 `ChatConversationPattern`(AI 对话页);第一步是“筛选、搜索、浏览对象列表、查看详情、批量操作结构化信息”→ 优先 `BasePageFramePattern`(白卡管理页)。',
99
+ '【AI入口页适用场景】当 `ChatInput` 本身就是页面的核心主功能,且页面目标是“帮助用户开始一件事”而不是“先管理一批对象”时,必须优先使用 `ChatHomePagePattern`。典型场景:AI 工作台首页、智能分析入口、模板广场、报告生成入口、用户尚未进入具体上下文的助手首页。此时核心输入区与推荐内容应直接坐落在浅灰大背景上,不要强行套成典型白卡后台页。',
100
+ '【AI对话页适用场景】当页面目标是“围绕单一任务持续协作推进”,核心信息是消息流、结果流、引用材料、追问与底部输入,而不是对象列表和字段筛选时,必须优先使用 `ChatConversationPattern`。典型场景:AI 对话详情、任务协作页、资料整理/策略分析/内容生成后的多轮追问页。此时顶导栏、消息区、ChatInput 三层直接坐灰底上,强调连续上下文,不要切成典型白卡管理结构。',
101
+ '【白卡管理页适用场景】当页面主要承载结构化信息管理时,必须优先使用 `BasePageFramePattern` 及其白卡单栏/双栏/多栏变体。典型场景:MCP 管理、变量管理、知识库管理、策略列表、审核配置、数据资产管理。只要页面核心动作是“筛选 → 浏览列表 → 查看详情 / 执行操作”,就应归入白卡管理页,而不是 AI 入口页或 AI 对话页。',
102
+ '【不要误判为白卡管理页】即使页面和 AI 能力有关,只要核心任务不是“管理对象”,就不要默认套白卡管理页:`AI 入口页` 解决的是“我现在想开始做什么”,`AI 对话页` 解决的是“我如何继续推进当前任务”,`白卡管理页` 解决的是“我要管理哪些结构化对象”。判断依据是任务性质,不是页面里是否出现 AI 组件。',
103
+ '【Playground/多面板工作台 反向引导】当页面是 Model Playground、Prompt Editor、API 调试器、规则编辑器、A/B 对比器,或者出现“输入区 + 输出区 + 参数区”三栏对照工作流时,**不要**套白卡管理页骨架,**也不要**套 Dashboard 网格首页骨架。多面板工作台必须遵守 `LAYOUT_RULES.md § 0.5 滚动决策树` + `§ 3.4 多面板工作台` + `§ 12.7 三栏 Playground 黄金骨架`:根容器 `h-dvh + overflow-hidden`、main `overflow-hidden`、每张面板 `flex-1 min-h-0 + overflow-hidden`、面板正文 `flex-1 min-h-0 overflow-y-auto`,**整页绝不滚动**,每个面板独立全高 + 独立内部滚动。⛔ 严禁让 main 写成 `overflow-y-auto`:会出现"调参数得滚下去看结果、写 prompt 得滚回去看输入"对照工作流断裂。',
104
+ '【卡片主内容控件撑满铁律】System Prompt、模型高级参数 JSON、请求参数、代码参数、JSON 编辑、代码、规则配置、长文本编辑、日志、运行结果等作为白卡/面板“主要工作区”时,标题区必须 `shrink-0` 固定,正文区必须 `flex-1 min-h-0 overflow-hidden`。若正文主控件是代码/Prompt 类 TextArea,必须写 `<TextArea variant="code" fillHeight resize="none" className="flex-1 min-h-0 w-full" />`,带行号并在组件内部滚动;若是普通长文本主编辑区,写 `<TextArea fillHeight resize="none" className="flex-1 min-h-0 w-full" />`。纯数值模型参数(Temperature / Top-P / Max Tokens)必须用 `<InputNumber />`。⛔ 严禁只写 `<TextArea minRows={5} />` 放在高卡片里——会出现控件不撑满、下方大片空白、长文本滚动关系错误。详见 LAYOUT_RULES §3.5。',
105
+ '【文字适配铁律】页面中任何文字都不允许被卡片或父容器静默裁切。字段说明、状态说明、错误原因、空状态说明、以及明确开启的白卡标题描述等核心说明必须完整展示并允许自动换行(`whitespace-normal break-words`);表格单元格、文件名、模型 ID、对象名等非核心长文本为了保持行高可单行省略或多行省略,但必须配 TFDS `<Tooltip content={fullText}>` 展示全文。所有横向 flex 标题行都要补 `min-w-0`,禁止用 `overflow-hidden whitespace-nowrap` 包住 FormTitle 描述。详见 GLOBAL_DESIGN_RULES §8。',
106
+ '【标题描述默认隐藏铁律】FormTitle 副标题/描述默认隐藏。普通白卡标题、面板标题、表单分组标题只写 `title`,不要自动补 `description`;只有用户明确要求显示副标题/描述,或板块确实需要介绍业务规则、使用方式、风险/空状态原因时,才写 `description="..." showDescription`。',
107
+ '【标题区防竖排铁律】白卡/面板标题是板块语义锚点,必须横向可读,⛔ 禁止出现“原始信息只读”这类一字一行的竖状标题。禁止 `writing-mode` / `text-orientation` / `break-all` / `w-[16px]` / `max-w-[24px]` 等压窄标题的写法。标题栏标准结构:左侧标题容器 `min-w-[120px] flex-1` + `<FormTitle />`,右侧 Tabs/按钮容器 `shrink-0 flex flex-wrap justify-end gap-2`;窄面板保持默认无描述,必要时把 Tabs/按钮移到下一行或正文顶部,不能挤压标题。详见 LAYOUT_RULES §3.4.1 / GLOBAL_DESIGN_RULES §8.4。',
108
+ '【标题状态 Tag 归位铁律】如果白卡/面板标题右侧有数量、状态、身份、分类 Tag(如 `0 条消息`、`Beta`、`只读`、`推荐`),它属于主标题语义,必须写进 `<FormTitle titleSuffix={<Tag ... />} />` 并紧跟主标题显示;⛔ 禁止把 Tag 放到 `justify-between` 的右侧操作区,也禁止 `<FormTitle ... /><Tag ... />` 让标签跟在整个标题组件后面。右侧操作区只放 Button、Tabs、筛选和更多菜单。',
109
+ '【页面 header 灰底裸放铁律】**页面级 header(标题 + 描述 + 返回 + 面包屑 + 页面级 Pill Tabs + 主次操作按钮)必须直接坐灰底,绝不包白卡**。白卡的语义是"工作区容器"——里面只装真正在做事的内容(列表 / 表格 / 对话流 / 参数表单 / 运行结果 / 编辑器主体);页面 header 是"页面元数据 / 切换位置 / 触发动作",必须直接坐 `var(--color-blueGrey-200)` 灰底上。⛔ 严禁把"标题 + 描述 + 操作按钮"包成 `<div bg=surface rounded-lg p-6>`——这会让顶部"标题白卡"和下方"内容白卡"形成同等大小的两张白卡,主从混乱、气息感丢失。参考样本:CopilotPagePattern 的 TopBar 是标杆(返回 + 标题 + Pill Tabs + 主次操作全部直接坐灰底)。详见 LAYOUT_RULES § 1.5。',
110
+ '【全宽撑满铁律(左右大空白专项)】**白卡必须撑满浏览器全宽,main 的 padding 只能是 p-4(16px)**:⛔ 严禁用 `p-2` / `px-6` / `px-8` 当 main 外框间距(常见误区:把白卡内部 padding p-6 错用到 main);⛔ 严禁在 main 内套 `<div className="max-w-* mx-auto">` 居中容器——这是左右大空白的主因;⛔ 严禁根容器 / main 加 `max-w-screen-xl` / `max-w-7xl` 等收窄值;白卡 div 自身不加 `mx-*` 外边距,靠 `flex-1` 或 `shrink-0 w-[Npx]` 控制宽度。三层间距金字塔:浏览器边→白卡边缘 16px(main p-4)、白卡间距 8px(gap-2)、白卡内 padding 24px(p-6)。详见 LAYOUT_RULES §1.2 / §6.1。',
111
+ '【白卡纯白无描边铁律】**最外层大白卡容器必须是"纯白底 + 12px 圆角 + 无 border + 无 shadow"**:⛔ 严禁在背景为 `var(--color-surface)` 的最外层 div / Card 上加 `border` / `outline` / `ring` / `borderColor` / `border-border-default` 等任何描边;白卡的层级感**唯一靠"灰底 vs 白卡的明度差 + 12px 圆角"**承担,加 border 会让明度差被划线覆盖、视觉权重变硬、气息感丢失。✅ **保留**:白卡**内部**所有 TFDS 组件自带的描边(Input / Select / TagInput / Tag / Tabs line / Table 行线 / 内嵌 grey Card 等——这些是控件功能边界,不是卡片层级边界)。判别口诀:背景色 `--color-surface`(白)→ **禁止** border;背景色 `--color-blueGrey-200`(灰,页面外框)→ **允许** border。详见 GLOBAL_DESIGN_RULES § 5.5。',
112
+ '【Copilot详情页补充】当页面既不是纯入口页,也不是纯消息流页,而是“左侧/中部展示上下文结果,右侧或顶部继续让 AI 协助处理”的混合协作场景,可使用 `CopilotPagePattern`。它适用于“带上下文结果面板的 AI 协同详情页”,但仍不应被误写成纯白卡列表管理页。',
113
+ '【Tabs 硬约束】主工作区内凡多块互斥内容的面板切换**必须**用基础组件 `<Tabs />`;**卡片内**小模块切换、**内容区顶部**布局级切换**默认优先** `variant="segment"`(分段器);所有 4 种 Tabs 变体在白卡/内容区/表单分段/筛选维度/Playground 面板内默认尺寸统一为 **SM**(省略 size 或 `size="sm"`),⛔ 禁止内容区默认 `size="md"` / `size="lg"`;只有平台顶部 header / 页面级顶导 Tabs 可按场景使用 MD/LG。禁止 `Button` 排一行或 `Tag` 冒充切换器',
114
+ '【模板独立】每个"列表示例"对应一个独立 .jsx 文件(如 VariableManagementPage / McpManagementPage),业务接入直接复制单文件即可',
115
+ '【示例映射(选型入口)】页面示例0=StrategyListPage(树形可展开列表+版本子行+分页);页面示例1=VariableManagementPage(单白卡:标题/筛选/表格);页面示例2=McpManagementPage(双白卡:左侧可拖拽辅助大卡 + 右侧弹性主白卡列表,是“横向大卡默认支持宽度拖拽”的标准示例);页面示例3=TabTopBarListPage(TopBar 胶囊场景切换 + 一级 Tab + 操作组;白卡内“列表+详情面板”联动);页面示例4=NoAccessPage(空状态+主行动:申请权限);页面示例5=ConstructionPage(空状态:功能建设中)',
116
+ '【关键词→示例】“策略管理/策略列表/版本子行/引用次数/渠道”→示例0;“变量管理/字段变量/流程引用”→示例1;“MCP/工具管理/分类树筛选/左侧标签树”→示例2;“知识库/QA对/文档知识/案例库/右侧详情面板/TopBar胶囊Tab”→示例3;“无权限/申请权限/无访问权限”→示例4;“建设中/敬请期待/开发中”→示例5',
117
+ '【NavBar】通过 navItems 自定义菜单项(id / label / iconName),通过 selectedItemId 高亮当前菜单;菜单 id 与右侧模板一一对应',
118
+ '【列表页结构】标题栏 → 筛选栏 → 表格,垂直 16px 间距,与白卡四边各 24px 边距',
119
+ '【标题栏·FormTitle】新写页面时白卡顶栏主标题必须用 `<FormTitle variant="level-1" title="…" />`(默认不显示副标题),标题旁状态/数量 Tag 用 `titleSuffix` 贴主标题;与右侧主按钮同一行用 `flex items-start justify-between gap-3` 组合;左侧标题区 `min-w-[120px] flex-1`,右侧操作区 `shrink-0 flex-wrap`,**禁止**再手写竖条 + `h2`,也禁止把标题挤成竖排。`pageListShared.jsx` 中的 `PageHeader` 仅为既有模板实现参考。',
120
+ '【筛选栏】搜索 Input 与筛选项同栏时不要撑满整行,默认使用约 240px 的中等宽度(空间不足再换行);后接多个 FilterPill(白底圆角胶囊 + 文字 + chevron)+ 末尾 Checkbox 胶囊"我创建的";项与项之间 8px、整体 36px 高、wrap 多行容错',
121
+ '【表单宽度判断】所有 form 类型组件都要按字段语义决定宽度,而不是统一 `w-full`:搜索/短关键词=中宽;枚举筛选/状态/时间范围=窄到中宽;名称/标题=中到宽;描述/备注/多行文本=宽或全宽;多值标签输入按内容与容器宽度决定',
122
+ '【双白卡变体】当列表需要左侧维度筛选(如按分类树过滤)时,在主白卡左侧再加一张**独立白圆角辅助大卡**包住 `TagBar`。该类“横向并列的大卡工作区”默认就要支持宽度拖拽:左卡用 `width + onWidthChange + minWidth + maxWidth + resizable`,外层保持 `overflow-visible` 以露出拖拽把手,右侧主卡保持 `flex-1 min-w-0` 弹性撑满;两白卡间距 8px。**勿**用 `tone="panel"` 代替白卡(panel 为浅灰侧条,不是白卡片)。参见 McpManagementPage',
123
+ '【多白卡分区(通用)】当页面右侧需要多个业务板块时,必须拆分为多个独立白卡(而不是一整张通栏白底背景)。推荐:灰底内容区外层统一用 `padding: 16px` 或等价 `margin: 16px` 外框节奏;框架层最外层白卡统一 `纯白背景 + 12px 圆角`,不加浅灰描边;白卡之间 `gap: 8px`;白卡内部布局用 `padding: 24px` + `gap: 16px`(参见 VariableManagementPage / McpManagementPage)。内部卡片、列表项、表单控件原有边框/描边保持不变。',
124
+ '【表格】使用 Table fixedColumnsMode="last" 让操作列固定在最右,pagination.total 与当前 dataSource.length 同步',
125
+ '【共享子组件】PageHeader / FilterBar / 列定义 / mock 工具集中在 pageListShared.jsx,避免每个模板重复实现',
126
+ '【撑满与防溢出】右侧 flex-col + min-h-0 + min-w-0;页面根容器 `w-full min-w-0 max-w-full overflow-hidden`;白卡 flex-1 撑满高度;列表 / 表格在白卡内部独立滚动,不挤压标题栏/筛选栏;禁止任何模块把页面撑出浏览器宽度后依赖横向滚动查看',
127
+ '【多栏卡片】若在该框架下新增多栏白卡区,优先使用 `repeat(auto-fit, minmax(min(320px, 100%), 1fr))` 或等价自适应列宽;卡片头部 `shrink-0`,正文 `flex-1 min-h-0 overflow-y-auto`,内容过高时在卡片内部滚动',
128
+ ],
129
+ code: `import NavBar from './components/NavBar';
130
+ import VariableManagementPage from './page-patterns/VariableManagementPage';
131
+ import McpManagementPage from './page-patterns/McpManagementPage';
132
+
133
+ /**
134
+ * 框架壳 = 外框 + 左侧 NavBar + 右侧根据菜单 id 路由到具体列表模板
135
+ * 业务接入:
136
+ * ① 改 NAV_ITEMS 自定义菜单 id / 文案 / icon
137
+ * ② 把 PAGE_BY_ITEM 里的模板换成你自己的列表页(直接复制 VariableManagementPage 或 McpManagementPage 改)
138
+ */
139
+
140
+ const NAV_ITEMS = [
141
+ { id: 'example-1', label: '列表示例 1', iconName: 'list-stroked' },
142
+ { id: 'example-2', label: '列表示例 2', iconName: 'list-stroked' },
143
+ ];
144
+
145
+ const PAGE_BY_ITEM = {
146
+ 'example-1': <VariableManagementPage />, // 单白卡:标题/筛选/表格
147
+ 'example-2': <McpManagementPage />, // 双白卡:左侧可拖拽辅助大卡 + 右主白卡
148
+ };
149
+
150
+ export default function MyPage({ defaultSelectedItemId = 'example-1' }) {
151
+ const [selectedItemId, setSelectedItemId] = useState(defaultSelectedItemId);
152
+
153
+ return (
154
+ <div
155
+ className="flex w-full items-stretch overflow-hidden"
156
+ style={{
157
+ flex: '1 0 auto', alignSelf: 'stretch', minHeight: '720px',
158
+ background: 'var(--color-blueGrey-200)',
159
+ /* 基础页面框架:贴浏览器边缘展示,不做外圈圆角/描边 */
160
+ borderRadius: 0,
161
+ }}
162
+ >
163
+ <div className="flex shrink-0">
164
+ <NavBar
165
+ platform="ola"
166
+ navItems={NAV_ITEMS}
167
+ selectedItemId={selectedItemId}
168
+ onSelect={(nextKey) => setSelectedItemId(nextKey)}
169
+ />
170
+ </div>
171
+
172
+ <div className="flex flex-1 min-w-0 flex-col">
173
+ {PAGE_BY_ITEM[selectedItemId]}
174
+ </div>
175
+ </div>
176
+ );
177
+ }`,
178
+ },
179
+ {
180
+ id: 'chat-home-page',
181
+ name: 'AI 入口页',
182
+ description:
183
+ 'AI 产品的入口首页模板:左侧 NavBar + 右侧内容区(顶部 Hero ChatInput + 筛选 Tab + 卡片列表网格)。适用于用户尚未进入具体上下文、第一步是输入需求 / 搜索助手 / 从模板开始的场景。',
184
+ keywords: [
185
+ 'AI 入口页', 'AI 首页', 'AI 工作台', 'AI 工作台首页', '智能分析入口',
186
+ '助手广场', '机器人广场', 'Agent 广场', '模板中心', '模板广场',
187
+ 'Hero ChatInput', 'Hero 区', '欢迎语 + 输入框', '欢迎页',
188
+ '搜索助手', '推荐机器人', '热门模板',
189
+ 'AI 产品首页', 'Copilot 首页', 'AI Hub',
190
+ '今天想做什么', '帮我快速搞定', '从模板开始',
191
+ // 错误信号词
192
+ '帮助用户开始一件事', '尚未进入具体上下文', 'AI 助手首页',
193
+ ],
194
+ Preview: ChatHomePagePattern,
195
+ /* 该模板本身包含灰底外框,预览容器无需再额外 padding */
196
+ previewPadding: 0,
197
+ components: ['nav-bar', 'chat-input', 'tabs', 'card', 'input', 'icon', 'empty'],
198
+ rules: [
199
+ '【五模板定位】本模板只用于“从 0 发起 AI 任务”的入口页:用户还没进入某个对象、会话或产物,第一步是输入一句需求、搜索助手、选择模板/案例/推荐 Agent。若用户要管理一批助手/模板/机器人列表,用 `BasePageFramePattern`;若用户已经在任务内持续追问,用 `ChatConversationPattern`;若右侧有主文档/主画布/主配置,AI 只是辅助,用 `CopilotPagePattern`;若是客服/私信线程,用 `IMConversationPattern`。',
200
+ '【布局 Recipe】必须按 `LAYOUT_RECIPES.md` 选择 `chat-home`:右侧主内容区是 gray-direct,不是白色 `WorkSurface`;Hero / ChatInput / Tabs / 搜索 / 模板卡网格直接坐 `var(--color-blueGrey-200)`。',
201
+ '【组件选型门禁】主输入必须用 `ChatInput`,不可用原生 textarea 或 Input 冒充 AI 输入;模板/助手/案例推荐必须用 `Card`;分类切换必须用 `Tabs`;搜索框用 `Input` + `Icon` 前缀;无结果用 `Empty`。禁止用 Button/Tag 排一行冒充 Tabs,禁止手写卡片。',
202
+ '【整体背景】页面以浅灰大背景(`--color-blueGrey-200`)为主:Hero、筛选行、卡片网格**直接坐灰底**,不要再额外包一整张“右侧白色大卡片容器”(白卡只用于推荐卡片本身)。',
203
+ '【反例扫描】如果同一右侧首页函数里同时出现 `ChatInput`、模板 `Card` 网格,并且外层存在 `background: var(--color-surface)` / `bg-surface rounded-*` 包住 Hero + 输入框 + Tabs + 网格,说明 AI 把入口页误生成成白卡管理页,必须拆掉这层 wrapper。',
204
+ '【框架不动】外框灰底 + 左侧 `NavBar` 固定不变;右侧内容区必须 `flex-1 min-w-0 min-h-0 overflow-hidden`,由内部区域控制滚动。',
205
+ '【Hero 区】居中欢迎标题 + 最大宽 680px 的 ChatInput 直接坐浅灰底;默认使用 `ChatInput variant="default"` 作为入口主输入;标准节奏为 `padding: 120px 40px 80px`。AI 渐变只用于输入框内部 / AI 标识,不作为整块 Hero 白底。',
206
+ '【筛选与分类】分类切换必须用 `Tabs size="sm"`;筛选行 `padding: 16px 40px`,左 Tabs、右搜索,搜索框约 240px,空间不足允许换行。',
207
+ '【卡片列表】使用自适应 grid(优先 `repeat(auto-fit, minmax(min(320px, 100%), 1fr))`),网格 `gap-4`,禁止固定列宽导致窄屏横向溢出;卡片使用 `Card color="white"`;列表区域 `flex-1 min-h-0 overflow-y-auto` 独立滚动,不挤压上方区域。',
208
+ '【内容可扩展】Tab 项数量和卡片数据替换为业务真实数据;卡片 stats/tags 按业务维度自定义',
209
+ ],
210
+ code: `import NavBar from './components/NavBar';
211
+ import Tabs from './components/Tabs';
212
+ import ChatInput from './components/ChatInput';
213
+ import Card from './components/Card';
214
+ import Icon from './components/Icon';
215
+ import Input from './components/Input';
216
+
217
+ const CATEGORY_TABS = [
218
+ { label: '全部' },
219
+ { label: '推荐', icon: <Icon name="star-01-stroked" /> },
220
+ { label: '对话助手', icon: <Icon name="message-chat-square-stroked" /> },
221
+ { label: '数据分析', icon: <Icon name="bar-chart-01-stroked" /> },
222
+ ];
223
+
224
+ export default function ChatHomePage() {
225
+ return (
226
+ <div
227
+ className="flex w-full items-stretch overflow-hidden"
228
+ style={{
229
+ flex: '1 0 auto', alignSelf: 'stretch', minHeight: '720px',
230
+ background: 'var(--color-blueGrey-200)',
231
+ borderRadius: 0,
232
+ }}
233
+ >
234
+ <div className="flex shrink-0">
235
+ <NavBar platform="ola" selectedItemId="knowledge" />
236
+ </div>
237
+
238
+ <div className="flex flex-1 min-w-0 min-h-0 flex-col overflow-hidden">
239
+ {/* Hero 区:欢迎语 + ChatInput */}
240
+ <div
241
+ className="flex flex-col items-center shrink-0"
242
+ style={{
243
+ padding: '120px 40px 80px',
244
+ }}
245
+ >
246
+ <div className="flex flex-col items-center gap-2 w-full text-center">
247
+ <h1 className="m-0 text-3xl [font-weight:var(--font-semibold)] leading-9" style={{ color: 'var(--foreground)' }}>
248
+ 今天想做什么?
249
+ </h1>
250
+ <p className="m-0 text-sm" style={{ color: 'var(--foreground-muted)' }}>
251
+ 从下方搜索助手,或直接输入你的需求,AI 帮你快速搞定
252
+ </p>
253
+ </div>
254
+ <div className="w-full" style={{ maxWidth: '680px' }}>
255
+ <ChatInput variant="default" placeholder="描述你想完成的任务…" />
256
+ </div>
257
+ </div>
258
+
259
+ {/* 筛选行:Tabs + 搜索,直接坐灰底 */}
260
+ <div
261
+ className="flex min-w-0 shrink-0 flex-wrap items-center justify-between gap-4"
262
+ style={{ padding: '16px 40px' }}
263
+ >
264
+ <Tabs variant="pill" size="sm" items={CATEGORY_TABS} defaultIndex={0} />
265
+ <Input
266
+ placeholder="搜索标题、描述"
267
+ prefix={<Icon name="search-md-stroked" size="sm" />}
268
+ allowClear
269
+ className="max-w-full"
270
+ style={{ flex: '0 1 240px', width: '240px', minWidth: '200px', '--size-input-width': '100%' }}
271
+ />
272
+ </div>
273
+
274
+ {/* 卡片列表(可滚动):卡片自身是白卡,外层不包白卡 */}
275
+ <div className="flex-1 min-h-0 overflow-y-auto" style={{ padding: '0 40px 40px' }}>
276
+ <div className="grid gap-4" style={{ gridTemplateColumns: 'repeat(auto-fit, minmax(min(320px, 100%), 1fr))' }}>
277
+ {/* 👉 替换为业务卡片数据 */}
278
+ <Card color="white" title="智能客服助手" description="基于大模型的全渠道客服对话助手" tags={['客服', '对话']} />
279
+ <Card color="white" title="数据洞察报告" description="上传数据,自动输出可视化洞察报告" tags={['数据', '分析']} />
280
+ <Card color="white" title="知识库 QA 问答" description="基于私有知识文档,快速搭建专属问答" tags={['知识库', 'RAG']} />
281
+ </div>
282
+ </div>
283
+ </div>
284
+ </div>
285
+ );
286
+ }`,
287
+ },
288
+ {
289
+ id: 'copilot-page',
290
+ name: 'Copilot 助手',
291
+ description: '适用于对象详情、产物预览、策略画布、配置编辑等“主工作区 + AI 侧助”的混合协作页。左侧 Copilot 面板可通过顶栏按钮一键展开/收起,右侧为主内容区。',
292
+ keywords: [
293
+ 'Copilot 页面', 'Copilot 助手', 'Copilot 协同页', 'Copilot 详情页', 'AI 协同详情页',
294
+ '左 Copilot 右内容', '左 AI 右画布', 'AI 辅助编辑',
295
+ '策略画布 + AI', '配置编辑 + AI', '流程画布 + Copilot', '编辑页 + AI 助手',
296
+ '展开 Copilot', '收起 Copilot', 'OLA AI 触发按钮',
297
+ '混合协作', '上下文结果面板', '右侧/顶部 AI 协助',
298
+ // 错误信号词
299
+ '边查看边追问', '左主内容右 AI', 'AI 侧边栏',
300
+ // 灰底裸顶导栏(页面级 header 不包白卡)的标杆样本——其他页面要学这个模式
301
+ '灰底裸顶导栏', '灰底裸放 header', '透明顶导栏', '页面级 header 不包白卡',
302
+ 'header 直接坐灰底', '返回+标题+操作直接坐灰底', '页面级 Pill Tabs',
303
+ ],
304
+ Preview: CopilotPagePattern,
305
+ /* 该模板本身包含完整工作台外壳,预览容器无需再额外 padding */
306
+ previewPadding: 0,
307
+ components: ['button', 'tabs', 'chat-input', 'switch', 'icon', 'form-title', 'textarea', 'input-number', 'select', 'tag'],
308
+ rules: [
309
+ '【五模板定位】本模板只用于“对象 / 产物 / 编辑器是主角,AI 是辅助”的页面:策略画布、Prompt/配置编辑、报告预览、文档产物、批测结果、运行数据等。若页面主角是 AI 消息流,改用 `ChatConversationPattern`;若用户尚未进入上下文只是从输入框开始,改用 `ChatHomePagePattern`;若第一步是管理一批对象,改用 `BasePageFramePattern`;若是真实 IM 往返,改用 `IMConversationPattern`。',
310
+ '【布局 Recipe】必须按 `LAYOUT_RECIPES.md` 选择 `copilot-workbench`:页面级 header 直接坐灰底;对象 / 产物 / 编辑器所在主工作区进入白色 WorkSurface;AI 面板只是辅助区,不改变主工作区优先级。',
311
+ '【组件选型门禁】页面级顶导栏动作必须用 `Button`,页面级切换用 `Tabs variant="pill"` 或内容区 `Tabs variant="line/segment"`;Copilot 输入用 `ChatInput`;编辑区标题用 `FormTitle`;Prompt/JSON/代码/长文本主编辑区用 `TextArea variant="code" fillHeight`;数值参数用 `InputNumber`;枚举用 `Select`;布尔即时开关用 `Switch`;状态用 `Tag`。禁止手写编辑器、参数输入、状态徽标或 AI 侧栏。',
312
+ '【整体风格】默认沿用基础页面框架:浅灰底(blueGrey-200)承载页面元信息和主工作区;内容区用纯白大卡片(12px 圆角、无浅灰描边)做区块分层;业务页面根容器贴浏览器边缘,不额外加外圈圆角或描边',
313
+ '【⭐ 灰底裸顶导栏样板(标杆,其他页面要学)】顶导栏的所有元素(返回按钮 + 主策略名称 + 居中 Pill Tabs + 版本徽章 + 主次操作)**全部直接坐灰底**,无任何白卡背景容器,仅有 `shrink-0 px-4 py-4` 的内边距。这是 TFDS 整个设计系统中页面级 header 的标杆模式:白卡承载"工作区内容",灰底承载"页面元数据 / 切换 / 触发动作"。⛔ 严禁把"标题 + 操作按钮"包成 `<div bg=surface rounded-lg>` 白卡——会让页面变成上下两张同等大小的白卡、主从混乱。无论是列表页 / 编辑器 / Playground / Dashboard,页面级 header 都要照此模式裸放灰底。详见 LAYOUT_RULES § 1.5 + SKILL.md § 3.6。',
314
+ '【顶导栏】左中右三段式:左侧返回+标题+OLA AI触发按钮,中间胶囊Tab绝对居中,右侧版本徽章+操作按钮组',
315
+ '【OLA AI按钮】渐变边框胶囊,点击切换 Copilot 展开/收起;展开时边框加深以示激活态',
316
+ '【Copilot面板】宽 280px,固定在内容区左侧;含标题栏(新会话文字+图标按钮组)、欢迎态(头像+OLA AI标题+欢迎语+快捷建议chips)、底部 ChatInput',
317
+ '【快捷建议 chips】白色半透明圆角卡片,右侧箭头图标,hover 加深背景',
318
+ '【主内容白卡】flex-1撑满,顶部二级Tab栏(灰底+border-bottom)含策略画布Tab+流程数据Switch+操作按钮',
319
+ '【布局防溢出】外层 `w-full min-w-0 max-w-full` + flex-col,内容区 `flex-wrap` / `min-w-0` 保证窄屏不横向溢出;Copilot shrink-0 且宽度可收缩,白卡 `flex-1 min-w-0`;仅框架层白卡保持纯白背景、不加浅灰描边,内部组件描边保持原样',
320
+ ],
321
+ code: `// 见 CopilotPagePattern.jsx`,
322
+ },
323
+ {
324
+ id: 'chat-conversation-page',
325
+ name: 'AI 对话页',
326
+ description:
327
+ '独立的 AI 助手会话详情页:顶导栏(返回 + 标题 + 操作按钮组)+ 800px 居中消息流 + 底部吸底 ChatInput。所有消息(用户 / AI)一律用 ChatMessage 渲染(用户走 role="user",AI 走 header=true)。支持 phase 切换:默认 chat 阶段展示端到端 mock 对话,点「新会话」清空回到 welcome 欢迎屏(CATCAT 头像 + 推荐 chip)。关键词驱动完整任务流:「整理 / 分析 / 生成」→ 任务规划卡 → 用户点开始 → 流式执行流(每 600ms 推一步) → 同条消息更新为总结+产物+追问。',
328
+ keywords: [
329
+ 'AI 对话页', 'AI 会话页', 'AI 对话详情页', 'AI 会话详情', 'AI 助手会话',
330
+ '任务协作页', '资料整理页', '策略分析页', '内容生成追问页', '多轮追问页',
331
+ '消息流', '对话流', '消息列表', '会话面板',
332
+ '吸底 ChatInput', '底部输入', '800px 居中消息流',
333
+ '欢迎屏 CATCAT', '推荐 chip', '新会话',
334
+ '流式执行', '任务规划卡', '执行流消息', '产物卡 + 追问',
335
+ // 错误信号词
336
+ '围绕单一任务持续协作', '持续推进', '消息为主',
337
+ '手搓 AI 对话页', '自制消息流', 'div 模拟聊天',
338
+ ],
339
+ Preview: ChatConversationPattern,
340
+ /* 该模板本身包含独立会话页外壳,预览容器无需再额外 padding */
341
+ previewPadding: 0,
342
+ components: ['chat-message', 'chat-input', 'icon', 'button', 'empty'],
343
+ rules: [
344
+ '【五模板定位】本模板只用于“AI 任务会话 / AI 助手会话”的持续协作页:用户第一步是继续追问、确认规划、查看流式执行、查看 AI 产物卡或 follow-up。若用户还没开始任务,用 `ChatHomePagePattern`;若右侧主产物/主编辑区才是页面主角,AI 只是侧助,用 `CopilotPagePattern`;若是真人客服/私信/站内信回复,用 `IMConversationPattern`;若是管理一批会话/任务列表,用 `BasePageFramePattern`。',
345
+ '【布局 Recipe】必须按 `LAYOUT_RECIPES.md` 选择 `chat-conversation`:消息流和底部输入是主工作流,滚动归属消息流;底部 `ChatInput` 固定吸底,不随消息滚动。',
346
+ '【组件选型门禁】所有消息必须用 `ChatMessage`:用户消息用 `role="user"`,AI 消息用 `header` 并按需要组合 `thinking` / `plan` / `taskGroups` / `resultText` / `resultArtifacts` / `followUps`;底部输入必须用 `ChatInput`;顶部和消息操作用 `Button` + `Icon`;欢迎/空会话态可用 `Empty` 或模板内欢迎屏。禁止用 `ChatBubble`、Card 或裸 div 模拟 AI 消息。',
347
+ '【整体框架】外框灰底(color-blueGrey-200);不带左侧 NavBar,整页就是一个独立会话工作区;不嵌中间白卡,顶导栏 / 消息区 / ChatInput 三层都直接坐灰底上;业务页面根容器不额外加外圈圆角或描边',
348
+ '【顶导栏】shrink-0,左侧 ghost-black 返回箭头 + 会话标题(truncate),右侧按权重递增:share-07 / 会话详情 outline-black / 更多 dots / 新会话 primary(主操作唯一固定最右)',
349
+ '【布局结构】flex h-full flex-col:① 顶导栏 shrink-0 ② 中部消息区 flex-1 + min-h-0 + overflow-y-auto 独立内滚 ③ ChatInput shrink-0 吸底;不要给中部加白卡背景',
350
+ '【宽度规格】对话流和 ChatInput 都用 800px + mx-auto 居中;对话流相对 ChatInput 左右各缩进 12px(消息区 padding "0 20px",ChatInput padding "0 8px"),让消息看起来比输入框窄一圈',
351
+ '【消息组件统一】所有消息(用户 / AI)一律用 ChatMessage 渲染。用户消息 role="user" + userContent / userAttachments;AI 消息 header=true + 任意组合 thinking / leadText / plan / taskGroups / resultText / resultArtifacts / followUps。禁止用 ChatBubble 渲染 AI 回复',
352
+ '【消息间距】flex-col gap-2(8px),符合现代 AI 对话的紧凑节奏',
353
+ '【操作栏 historyMode】只有最后一条消息 historyMode=false(常显),其余消息 historyMode=true(hover 才显示,占位高度始终保留);待用户处理的交互卡片(plan / confirms)未操作时整条消息不显示操作栏,处理后才变成历史消息走 historyMode 规则',
354
+ '【流式执行流】用 useStreamingTaskGroups(taskGroups, { intervalMs: 600 }) 把最终态 taskGroups 转成"按 600ms 节奏一步步推出"的切片:当前组 status=processing 带扫光,每过一格推一个 step,本组 step 出齐后切到下一组首步;流式期间整条 AI 消息不显示操作栏(actions=null)',
355
+ '【任务规划链路】关键词触发 → AI 推送 ai-task-plan 消息(leadText "我开始规划啦..." + 任务规划卡)→ 卡片有「取消」+「开始执行任务」两个按钮 → 用户点「开始执行任务」:1) 卡片变 confirmed 置灰 2) 追加用户消息「开始执行任务」3) 追加流式执行流消息(stream=true,无操作栏) 4) totalSteps×600ms 后更新同条消息:stream=false + taskGroups 全部 completed + 补上总结 resultText / resultArtifacts / followUps',
356
+ '【取消链路】用户点任务规划卡的「取消」:1) 卡片变 confirmed 置灰 2) 追加用户消息「取消」 3) 600ms 后追加 AI 短答寒暄("已取消任务,还有其他问题随时找我~")',
357
+ '【追问交互】followUps 字符串数组在父组件 wrap 成 { items, onSelect: onSend } 形式,点击 chip 必须等价于立即发送该文本:先追加一条右侧 user 气泡,再由 AI 追加对应的新答复 / 产物 / 下一组 followUps;不要只回填输入框等待用户二次发送',
358
+ '【自动滚底】用 ResizeObserver 监听消息列表 firstElementChild 的高度变化,任何高度增长都 scrollTo({ top: scrollHeight, behavior: smooth });覆盖新消息追加 / 流式 step / 折叠展开 三种触发场景,比单独 useEffect([messages]) 更稳',
359
+ '【欢迎屏】点「新会话」→ phase 切到 welcome:清空 messages,中部居中展示 CATCAT 头像(66px 渐变描边圆 + 蓝色投影 + 32px catcat.svg)+「OLA AI」标题 + 欢迎语 + 3 条推荐 chip(白底 0.6 透明 + inset 1px 白边 + 右箭头);ChatInput 仍 shrink-0 吸底(位置和 chat 阶段保持一致),placeholder 改成"需要我为你做什么…";用户在欢迎屏发送或点 chip → phase 自动切回 chat 走完整链路',
360
+ '【关键词路由】① 含「整理 / 分析 / 生成 / 梳理 / 输出 / 汇总」→ 任务规划卡链路(待用户点开始/取消) ② 含「停止 / 取消」→ AI 短答「已停止当前任务,需要时再叫我。」 ③ 其他 → AI 短答从备选句池随机一句,避免机械化',
361
+ '【任务规划卡 defaultConfirmed】历史消息(mock 中的已处理卡片)通过 plan.defaultConfirmed=true 让卡片初始就处于禁用置灰态;TaskPlanCard 内部用 useState(plan.defaultConfirmed === true) 初始化 confirmed,并用 useEffect 同步 props 变化',
362
+ ],
363
+ code: `// 见 ChatConversationPattern.jsx —— 完整可交互的会话页骨架(含欢迎屏 / 流式执行 / 取消链路)
364
+ // 关键拼装(全部消息走 ChatMessage,无 ChatBubble):
365
+ // 用户消息: <ChatMessage role="user" userContent={[{type:"text",value:"..."}, {type:"entity",label:"..."}]} userAttachments={[...]} />
366
+ // AI 思考+卡: <ChatMessage header thinking={...} leadText="我开始规划啦..." plan={{...DEFAULT_CHAT_PLAN, defaultConfirmed:true, onPrimaryAction, onSecondaryAction}} />
367
+ // AI 流式: <StreamingChatMessage taskGroups={DEFAULT_CHAT_TASK_GROUPS} /> // 内部 useStreamingTaskGroups
368
+ // AI 完整态: <ChatMessage header taskGroups={...} resultText={...} resultArtifacts={...} followUps={{items, onSelect:onSend}} actions={{historyMode:false}} />
369
+ // 底部输入: <ChatInput onSend={handleSend} /> // handleSend 路由:任务/停止/兜底短答
370
+ // phase 切换: 'chat'(默认)<-> 'welcome'(点新会话)
371
+ // 自动滚底: ResizeObserver 监听内容高度变化,任意增长 → scrollTo bottom smooth`,
372
+ },
373
+ {
374
+ id: 'im-conversation-page',
375
+ name: 'IM 对话',
376
+ description:
377
+ 'IM 对话片段:适用于客服接待、用户私信、站内信、履约沟通、社群协作等以连续消息往返为核心的即时通讯场景。单个白卡内默认包含当前线程顶部信息元素、消息流和底部组合输入框,并支持真实发送;若是 AI 协同型对话,可切换为 AI 输入框。',
378
+ keywords: [
379
+ 'IM 对话', 'IM 会话', 'IM 聊天', '即时通讯', '聊天对话', 'IM 工作台',
380
+ '客服会话', '客服接待', '用户私信', '站内信', '即时通讯场景', '人工客服',
381
+ '机器人接待', '机器人对话', '转人工', '客服跟进', '用户进线',
382
+ 'ChatBubble 气泡', '左气泡 右气泡', '聊天气泡组',
383
+ '系统提示', '已接入', '已读 receipt',
384
+ // 错误信号词
385
+ '手搓 IM 聊天', '自制聊天页', 'WhatsApp 风格', '微信风格',
386
+ 'div 模拟 IM', 'span + bg 当气泡',
387
+ ],
388
+ Preview: IMConversationPattern,
389
+ components: ['chat-bubble', 'chat-input', 'conversation-list', 'avatar', 'tag', 'button', 'icon'],
390
+ rules: [
391
+ '【五模板定位】本模板只用于“真实 IM / 客服 / 私信 / 站内信 / 履约沟通”的当前线程:用户第一步是看历史消息并回复。若消息主角是 AI 任务规划、执行流、产物追问,改用 `ChatConversationPattern`;若右侧对象/产物为主且 AI 只是辅助,改用 `CopilotPagePattern`;若是多个会话对象的结构化管理列表,外层应先用 `BasePageFramePattern` 再组合 `ConversationList + IMConversationPattern`。',
392
+ '【布局 Recipe】必须按 `LAYOUT_RECIPES.md` 选择 `im-thread`:线程列表 / 消息流 / 输入区职责分离,消息滚动只发生在会话流,输入区固定在底部。',
393
+ '【组件选型门禁】当前线程消息必须用 `ChatBubble`;多线程队列用 `ConversationList`;普通 IM 输入用 `ChatInput variant="im-basic"`;AI 协同输入才可改 `ChatInput variant="default"`;参与者身份用 `Avatar`,状态/标签用 `Tag`,线程操作用 `Button` + `Icon`。禁止用 `ChatMessage` 渲染普通客服气泡,禁止手写左右气泡、时间戳和已读态,禁止手写头像、标签、图标按钮或直接复制 Figma SVG。',
394
+ '【头像素材】IM 用户 / 人工客服 / 协作者头像默认使用包内本地成员头像素材;`ChatBubble avatarType="image"` 未传 avatarSrc 时会由 Avatar 自动随机取本地成员头像。生成模板时不要写 pravatar / Unsplash / placeholder 外链头像,除非业务接口真实返回用户头像 URL。',
395
+ '【触发条件】当页面核心任务是“围绕单一会话线程连续查看历史消息并继续发送消息”,且信息以时间顺序展开、交互重心在对话往返而不是结构化管理时,优先使用 `IMConversationPattern`。',
396
+ '【适用场景】适用于客服接待、售后沟通、订单履约跟进、用户私信、站内信回复、即时通讯协作等单线程聊天场景;客服工作台只是其中一种典型子场景,不是唯一适用范围。',
397
+ '【整体风格】本模板不嵌基础页面框架外框,但白卡的“圆角 + 边框 + 内边距”仍需与基础页面框架的卡片风格一致(大圆角白卡承载内容,灰底仅在宿主页面需要时由外层提供)',
398
+ '【默认自适应】`IMConversationPattern` 默认 **不限制宽度**、**不强制高度**、且 **不带边框**;应随外层容器自适应宽高。仅当把它作为“独立卡片”展示时,才由外层白卡(或 `asCard`)提供圆角与描边。',
399
+ '【容器(独立卡片模式)】若需要单独成卡:使用外层白卡(或 `<IMConversationPattern asCard maxWidth={680} />`)实现 max-w-680 + 居中 + 12px 圆角 + 纯白背景 + border-default;组件本身不自带内边距,外边距与留白统一由宿主模板框架控制。',
400
+ '【顶部信息元素】默认在消息滚动区上方固定展示当前 IM 线程信息:左侧 `Avatar size="s"`、标题、人数/身份 `Tag`、用户 ID / 渠道 / 会话时长元信息;右侧 4 个 `Button variant="ghost-black" size="md" iconOnly` 操作入口。标题区必须横向撑满并对齐 IM 对话内容区左右边界:头像本体左边贴齐左侧内容边界,按钮组最右侧贴齐右侧内容边界;标题区外层不额外加横向 padding,头像外层也不再额外加 padding。标题区元素上下间距默认为 12px(`py-3`);左侧头像与信息区 12px,标签/按钮间距 8px;颜色、字号、描边和图标必须来自 TFDS token 与基础组件,不使用 `semi-color-*` 或 Figma 导出的硬编码样式。副标题元信息 hover/focus 时必须通过平台 `Tooltip` 展示含义:用户 ID 为“会话ID”、渠道为“沟通渠道”、时长为“沟通时长”。右侧操作区可用宽度必须基于 Header 总宽减去左侧标题/副标题信息区总宽计算,而不是只看按钮容器自身宽度;宽度不足时自动折叠为 `Button + Icon(dots-horizontal-stroked)` 更多入口,被折叠的操作点击后在浮层中展示;右侧所有操作按钮(包含更多入口与浮层菜单项)hover/focus 时必须通过平台 `Tooltip` 展示对应按钮文案。更多入口与浮层菜单项仍必须复用平台 `Button` 和 `Icon`,禁止用原生 button/div/svg 临时模拟。',
401
+ '【底部输入区】默认底部必须搭配组合输入框,不要只放静态消息流。输入区固定在底部,消息区占剩余高度并独立滚动;输入区上方不额外加分割线。消息滑到底时,最后一个气泡底部与输入框之间必须保留 16px 安全间距,避免气泡紧贴输入框。',
402
+ '【发送交互】模板预览必须支持真实输入发送:用户在底部输入框输入文字后,点击发送或按 Enter,应追加为右侧当前服务方 / 协作者消息,并自动滚动到底部;Shift+Enter 保留换行能力。',
403
+ '【外部上下文】当 `IMConversationPattern` 嵌入客服工作台、私信队列或工单工作区时,应通过 `thread` 和 `messages` 由外层传入当前线程头像、标题、会话 ID、渠道、时长和消息脚本;未传入时才使用组件内置默认示例。不要让列表选中态和 IM 对话各自维护独立当前对象。',
404
+ '【同层同底色】IM 聊天气泡区和底部输入框同属一个会话层,背景色必须统一,视觉上要连续承接;禁止在消息区与输入框之间插入独立底色条、推荐回复条、AI 助手条、额外卡片层或中间分隔带,避免把单一会话层切裂成上下两块。',
405
+ '【滚动约束】IM 对话气泡区严禁横向滚动,只允许纵向滚动查看历史消息。消息滚动容器必须 `overflow-y-auto + overflow-x-hidden`,并为内部消息列补 `min-w-0`,避免气泡把页面撑出后出现左右滑动。',
406
+ '【输入框选型】根据页面场景判断输入框类型:常规 IM 对话 / 人工接待 / 站内私信 / 即时通讯回复,默认用 `ChatInput variant="im-basic"`;若底部承载的是 AI 协作、Prompt 追问、任务补充说明等 AI 型输入,则改用 `ChatInput variant="default"`。',
407
+ '【不要误判为标准 IM 模板】若页面在会话区内部还需要插入 AI 推荐回复、Prompt 辅助操作、推荐行动面板或额外智能分层,则它已经不是标准 `IMConversationPattern`,应按“IM + AI 协同”的混合场景单独定义结构,不要继续宣称符合标准 IM 对话模板。',
408
+ '【会话背景选型】常规 IM / 即时通讯 / 私信往返默认用白色会话背景;AI 问答、执行进度、Copilot、流程跟进等执行类对话优先用浅灰会话背景。先定背景,再定气泡色,不要反过来凭角色随意选色。',
409
+ '【背景 → 气泡映射】白色背景:用户左侧 `incomingTone="grey"`,人工服务方 / 协作者右侧 `outgoingTone="default"`,AI/机器人右侧 `outgoingTone="ai"`;浅灰背景:用户左侧 `incomingTone="grey"`,普通右侧回复 `outgoingTone="white"`,只有明确 AI 执行语义才使用 `outgoingTone="ai"`。',
410
+ '【角色 → 气泡映射(铁律)】用户 = ChatBubble variant="incoming" avatarType="image" incomingTone="grey";机器人 = ChatBubble variant="outgoing" avatarType="ai" outgoingTone="ai"(AI 渐变底 + AI头像);人工服务方 / 运营 / 客服 = ChatBubble variant="outgoing" avatarType="image" outgoingTone="default" receipt="read"。三种角色不可混用 tone。',
411
+ '【系统提示】"接入 / 转人工"等非对话事件用居中小字渲染(不是气泡,也不加背景胶囊),格式:「时间 · 文案」,foreground-muted 弱化色,让真正的对话内容更突出',
412
+ '【消息间距】消息组使用 flex-col gap-5(20px)作为默认上下间距;同侧连续消息需先分组后传给 ChatBubble,并保持组内连续气泡的紧凑间距',
413
+ '【示例剧本】当前预览默认使用“用户进线 → 机器人接待 → 转人工 → 人工跟进”演示多角色切换;业务接入时可替换为客服、私信、履约、社群或站内信等真实对话脚本,但必须保留清晰的参与者身份、时间顺序和消息归组。',
414
+ '【配套关系】若页面左侧还需要切换多个会话线程,应使用 `ConversationList + IMConversationPattern` 组合;`IMConversationPattern` 只负责当前线程的消息展示与发送,不承担多线程队列切换。',
415
+ '【生成后整页自检】TFDS 规范要求 AI 在生成完整页面代码后,再整体做一轮组件代码合规自检:检查是否优先复用现有 TFDS 组件、是否存在违反硬规则的结构、以及所有组件与布局的宽高自适应是否正常。凡出现内容截断、消息区/卡片区/表格区滚动关系错误、横向溢出、组件高度不对齐、控件宽度判断失真等问题,都必须先修正再交付。',
416
+ ],
417
+ code: `// 见 IMConversationPattern.jsx —— 单个白卡 + 初始剧本 + 可交互底部组合输入框
418
+ // 三种角色 → 三种气泡形态(铁律):
419
+ // 用户: <ChatBubble variant="incoming" avatarType="image" avatarSrc={getTeamAvatarBySeed("user")} incomingTone="grey" messages={group.messages} timestamps={group.timestamps} />
420
+ // 机器人: <ChatBubble variant="outgoing" avatarType="ai" outgoingTone="ai" messages={group.messages} timestamps={group.timestamps} />
421
+ // 人工: <ChatBubble variant="outgoing" avatarType="image" avatarSrc={getTeamAvatarBySeed("agent")} outgoingTone="default" receipt="read" messages={group.messages} timestamps={group.timestamps} />
422
+ // 系统提示(接入/转人工)→ 居中弱化小字:<SystemNote text="客服小语已接入" time="14:04" />
423
+ // 底部输入框按场景切换:
424
+ // 纯 IM 会话: <ChatInput variant="im-basic" placeholder="请输入消息…" />
425
+ // AI 协同会话: <ChatInput variant="default" placeholder="继续协同处理当前会话…" />
426
+ // 发送交互:ChatInput onSend 会把输入内容追加为右侧服务方消息,并滚动到底。`,
427
+ },
428
+ ];