@lynx-js/genui 0.0.2 → 0.0.3

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 (168) hide show
  1. package/README.md +5 -9
  2. package/a2ui/AGENTS.md +167 -0
  3. package/a2ui/README.md +76 -780
  4. package/a2ui/README_zh.md +103 -0
  5. package/a2ui/dist/catalog/DateTimeInput/index.jsx +1 -10
  6. package/a2ui/dist/catalog/DateTimeInput/index.jsx.map +1 -1
  7. package/a2ui/dist/catalog/DateTimeInput/utils.d.ts +0 -1
  8. package/a2ui/dist/catalog/DateTimeInput/utils.js +0 -3
  9. package/a2ui/dist/catalog/DateTimeInput/utils.js.map +1 -1
  10. package/a2ui/dist/catalog/Loading/catalog.json +15 -0
  11. package/a2ui/dist/catalog/Loading/index.d.ts +10 -0
  12. package/a2ui/dist/catalog/Loading/index.jsx +11 -0
  13. package/a2ui/dist/catalog/Loading/index.jsx.map +1 -0
  14. package/a2ui/dist/catalog/defineCatalog.d.ts +0 -4
  15. package/a2ui/dist/catalog/defineCatalog.js.map +1 -1
  16. package/a2ui/dist/catalog/index.d.ts +1 -0
  17. package/a2ui/dist/catalog/index.js +16 -0
  18. package/a2ui/dist/catalog/index.js.map +1 -1
  19. package/a2ui/dist/catalog.json +2548 -0
  20. package/a2ui/dist/index.d.ts +1 -1
  21. package/a2ui/dist/index.js +2 -2
  22. package/a2ui/dist/index.js.map +1 -1
  23. package/a2ui/dist/react/A2UIRenderer.jsx +3 -13
  24. package/a2ui/dist/react/A2UIRenderer.jsx.map +1 -1
  25. package/a2ui/dist/tsconfig.build.tsbuildinfo +1 -1
  26. package/a2ui/docs/catalog-guide.md +401 -0
  27. package/a2ui/docs/catalog-guide_zh.md +373 -0
  28. package/a2ui/docs/overview.md +312 -0
  29. package/a2ui/docs/overview_zh.md +289 -0
  30. package/a2ui/docs/system-prompts.md +187 -0
  31. package/a2ui/docs/system-prompts_zh.md +187 -0
  32. package/a2ui/src/catalog/README.md +12 -0
  33. package/a2ui/src/catalog/index.ts +51 -0
  34. package/a2ui/src/catalog/readme_zh.md +11 -0
  35. package/a2ui/src/index.ts +115 -0
  36. package/a2ui/styles/catalog/Button.css +5 -5
  37. package/a2ui/styles/catalog/DateTimeInput.css +22 -30
  38. package/a2ui/styles/catalog/Loading.css +61 -0
  39. package/a2ui-catalog-extractor/README.md +14 -7
  40. package/a2ui-catalog-extractor/dist/cli.d.ts +1 -0
  41. package/a2ui-catalog-extractor/dist/cli.js +15 -6
  42. package/a2ui-catalog-extractor/dist/cli.js.map +1 -1
  43. package/a2ui-catalog-extractor/dist/index.d.ts +9 -2
  44. package/a2ui-catalog-extractor/dist/index.js +52 -6
  45. package/a2ui-catalog-extractor/dist/index.js.map +1 -1
  46. package/a2ui-catalog-extractor/dist/tsconfig.build.tsbuildinfo +1 -1
  47. package/a2ui-catalog-extractor/skills/a2ui-catalog-extractor/SKILL.md +1 -1
  48. package/a2ui-prompt/README.md +3 -2
  49. package/a2ui-prompt/dist/index.d.ts +2 -0
  50. package/a2ui-prompt/dist/index.js +159 -84
  51. package/cli/README.md +26 -0
  52. package/cli/bin/cli.js +7 -265
  53. package/cli/dist/a2ui/create.d.ts +5 -0
  54. package/cli/dist/a2ui/create.js +178 -0
  55. package/cli/dist/a2ui/create.js.map +1 -0
  56. package/cli/dist/a2ui/index.d.ts +5 -0
  57. package/cli/dist/a2ui/index.js +170 -0
  58. package/cli/dist/a2ui/index.js.map +1 -0
  59. package/cli/dist/cli.d.ts +4 -0
  60. package/cli/dist/cli.js +40 -0
  61. package/cli/dist/cli.js.map +1 -0
  62. package/cli/dist/openui.d.ts +1 -0
  63. package/cli/dist/openui.js +21 -0
  64. package/cli/dist/openui.js.map +1 -0
  65. package/cli/dist/tsconfig.build.tsbuildinfo +1 -0
  66. package/cli/dist/utils.d.ts +2 -0
  67. package/cli/dist/utils.js +17 -0
  68. package/cli/dist/utils.js.map +1 -0
  69. package/cli/templates/default/lynx.config.ts +13 -0
  70. package/cli/templates/default/package.json +27 -0
  71. package/cli/templates/default/src/App.css +88 -0
  72. package/cli/templates/default/src/App.tsx +100 -0
  73. package/cli/templates/default/src/index.tsx +10 -0
  74. package/cli/templates/default/src/messages.ts +158 -0
  75. package/cli/templates/default/src/rspeedy-env.d.ts +14 -0
  76. package/cli/templates/default/src/tsconfig.json +17 -0
  77. package/cli/templates/default/tsconfig.json +15 -0
  78. package/cli/templates/default/tsconfig.node.json +16 -0
  79. package/dist/tsconfig.build.tsbuildinfo +1 -1
  80. package/openui/README.md +50 -46
  81. package/openui/dist/catalog/Action/{index.js → index.jsx} +1 -1
  82. package/openui/dist/catalog/Action/index.jsx.map +1 -0
  83. package/openui/dist/catalog/Button/index.d.ts +8 -8
  84. package/openui/dist/catalog/Button/{index.js → index.jsx} +28 -14
  85. package/openui/dist/catalog/Button/index.jsx.map +1 -0
  86. package/openui/dist/catalog/Card/index.d.ts +1 -1
  87. package/openui/dist/catalog/Card/{index.js → index.jsx} +5 -4
  88. package/openui/dist/catalog/Card/{index.js.map → index.jsx.map} +1 -1
  89. package/openui/dist/catalog/CardHeader/index.d.ts +1 -1
  90. package/openui/dist/catalog/CardHeader/index.jsx +20 -0
  91. package/openui/dist/catalog/CardHeader/index.jsx.map +1 -0
  92. package/openui/dist/catalog/CheckBox/index.d.ts +16 -0
  93. package/openui/dist/catalog/CheckBox/index.jsx +82 -0
  94. package/openui/dist/catalog/CheckBox/index.jsx.map +1 -0
  95. package/openui/dist/catalog/Icon/index.d.ts +44 -0
  96. package/openui/dist/catalog/Icon/index.jsx +66 -0
  97. package/openui/dist/catalog/Icon/index.jsx.map +1 -0
  98. package/openui/dist/catalog/Image/index.d.ts +19 -0
  99. package/openui/dist/catalog/Image/index.jsx +40 -0
  100. package/openui/dist/catalog/Image/index.jsx.map +1 -0
  101. package/openui/dist/catalog/Loading/index.d.ts +7 -0
  102. package/openui/dist/catalog/Loading/index.jsx +25 -0
  103. package/openui/dist/catalog/Loading/index.jsx.map +1 -0
  104. package/openui/dist/catalog/RadioGroup/index.d.ts +21 -0
  105. package/openui/dist/catalog/RadioGroup/index.jsx +99 -0
  106. package/openui/dist/catalog/RadioGroup/index.jsx.map +1 -0
  107. package/openui/dist/catalog/Separator/index.d.ts +1 -1
  108. package/openui/dist/catalog/Separator/{index.js → index.jsx} +3 -4
  109. package/openui/dist/catalog/Separator/index.jsx.map +1 -0
  110. package/openui/dist/catalog/Slider/index.d.ts +19 -0
  111. package/openui/dist/catalog/Slider/index.jsx +139 -0
  112. package/openui/dist/catalog/Slider/index.jsx.map +1 -0
  113. package/openui/dist/catalog/Stack/index.d.ts +1 -1
  114. package/openui/dist/catalog/Stack/{index.js → index.jsx} +3 -4
  115. package/openui/dist/catalog/Stack/{index.js.map → index.jsx.map} +1 -1
  116. package/openui/dist/catalog/Tag/index.d.ts +1 -1
  117. package/openui/dist/catalog/Tag/{index.js → index.jsx} +5 -4
  118. package/openui/dist/catalog/Tag/index.jsx.map +1 -0
  119. package/openui/dist/catalog/TextContent/index.d.ts +1 -1
  120. package/openui/dist/catalog/TextContent/{index.js → index.jsx} +5 -4
  121. package/openui/dist/catalog/TextContent/{index.js.map → index.jsx.map} +1 -1
  122. package/openui/dist/catalog/TextField/index.d.ts +23 -0
  123. package/openui/dist/catalog/TextField/index.jsx +132 -0
  124. package/openui/dist/catalog/TextField/index.jsx.map +1 -0
  125. package/openui/dist/catalog/index.d.ts +14 -7
  126. package/openui/dist/catalog/index.js +14 -7
  127. package/openui/dist/catalog/index.js.map +1 -1
  128. package/openui/dist/core/context.d.ts +17 -7
  129. package/openui/dist/core/{context.js → context.jsx} +8 -2
  130. package/openui/dist/core/context.jsx.map +1 -0
  131. package/openui/dist/core/createLibrary.d.ts +1 -1
  132. package/openui/dist/core/{createLibrary.js → createLibrary.jsx} +14 -3
  133. package/openui/dist/core/createLibrary.jsx.map +1 -0
  134. package/openui/dist/core/hooks/index.d.ts +1 -0
  135. package/openui/dist/core/hooks/index.js +1 -0
  136. package/openui/dist/core/hooks/index.js.map +1 -1
  137. package/openui/dist/core/hooks/useOpenUIState.d.ts +2 -2
  138. package/openui/dist/core/hooks/useOpenUIState.js +3 -1
  139. package/openui/dist/core/hooks/useOpenUIState.js.map +1 -1
  140. package/openui/dist/core/hooks/useStateField.js +1 -1
  141. package/openui/dist/core/hooks/useStateField.js.map +1 -1
  142. package/openui/dist/core/index.d.ts +13 -7
  143. package/openui/dist/core/index.js +7 -4
  144. package/openui/dist/core/index.js.map +1 -1
  145. package/openui/dist/core/{library.js → library.jsx} +1 -1
  146. package/openui/dist/core/library.jsx.map +1 -0
  147. package/openui/dist/core/renderer.css +527 -0
  148. package/openui/dist/core/renderer.d.ts +31 -4
  149. package/openui/dist/core/renderer.jsx +281 -0
  150. package/openui/dist/core/renderer.jsx.map +1 -0
  151. package/openui/dist/core/runtime/index.d.ts +1 -0
  152. package/openui/dist/core/runtime/index.js +5 -0
  153. package/openui/dist/core/runtime/index.js.map +1 -0
  154. package/openui/dist/core/runtime/reactive.d.ts +7 -0
  155. package/openui/dist/core/runtime/reactive.js +10 -0
  156. package/openui/dist/core/runtime/reactive.js.map +1 -0
  157. package/package.json +17 -7
  158. package/openui/dist/catalog/Action/index.js.map +0 -1
  159. package/openui/dist/catalog/Button/index.js.map +0 -1
  160. package/openui/dist/catalog/CardHeader/index.js +0 -18
  161. package/openui/dist/catalog/CardHeader/index.js.map +0 -1
  162. package/openui/dist/catalog/Separator/index.js.map +0 -1
  163. package/openui/dist/catalog/Tag/index.js.map +0 -1
  164. package/openui/dist/core/context.js.map +0 -1
  165. package/openui/dist/core/createLibrary.js.map +0 -1
  166. package/openui/dist/core/library.js.map +0 -1
  167. package/openui/dist/core/renderer.js +0 -139
  168. package/openui/dist/core/renderer.js.map +0 -1
@@ -0,0 +1,373 @@
1
+ # Catalogs、内置组件与自定义组件
2
+
3
+ **catalog** 是你的 Agent 和 client 之间的 contract:它列出 renderer 被允许
4
+ 实例化的 component、可以执行的 function,并携带 Agent 在 handshake 时读取的
5
+ 可选 JSON schema。这篇指南覆盖关于组合这份 contract 的一切——从一行的最小写法,
6
+ 到内置组件集合,再到发布你自己的组件并生成它们的 schema。
7
+
8
+ 如果你只想快速浏览一节,请看[内置组件](#内置组件)和[basic-catalog functions](#basic-catalog-functions):那是你的 Agent 能使用的「词汇表」。
9
+
10
+ ## catalog 是什么
11
+
12
+ 一个 catalog 有两类 entry:
13
+
14
+ - **Component**——把一个协议名(`"Text"`、`"Card"`、你的 `"MyChart"`)映射到
15
+ client 渲染的 ReactLynx 组件。
16
+ - **Function**——把一个协议 function 名(`"formatDate"`、`"required"`)映射到
17
+ 客户端实现,renderer 在解析 props、actions 和 validation checks 时调用它。
18
+
19
+ 你用 `defineCatalog` 构建它,然后要么把它(或一个原始 input 数组)传给
20
+ `<A2UI catalogs={…}>` 用于渲染,要么用 `serializeCatalog` 把这份 contract
21
+ 告知你的 Agent。
22
+
23
+ 一个组件的**协议名**来自 `displayName ?? component.name`,除非你把它和 manifest
24
+ 配对——这时 manifest 的顶层 key 是权威的。Agent 只引用这个名字,所以保持它稳定
25
+ 很重要(见下面的 minifier 警告)。
26
+
27
+ ## 从小开始:renderer-only components
28
+
29
+ 如果你的应用只需要渲染,直接传 bare components 即可。不需要 schema,也没有任何
30
+ 仪式感。
31
+
32
+ ```ts
33
+ import { defineCatalog, Text, Button } from '@lynx-js/genui/a2ui';
34
+
35
+ const catalog = defineCatalog([Text, Button]);
36
+ ```
37
+
38
+ 你也可以把同一个数组直接传给 `<A2UI>` 而不必自己调用 `defineCatalog`——组件会在
39
+ 内部组合它:
40
+
41
+ ```tsx
42
+ <A2UI messageStore={store} catalogs={[Text, Button]} onAction={…} />;
43
+ ```
44
+
45
+ 打包器会 tree-shake 掉未使用的组件:引入 `Text` **不会**把 `Button`、`Card` 或
46
+ 其他任何内置组件拖进你的 bundle。
47
+
48
+ > ⚠️ **生产环境 minifier 会改写 function 声明名**,这会破坏 `component.name`
49
+ > 这个回退。为了生产安全,请给每个自定义组件设置显式 `displayName`(字符串
50
+ > 字面量能在 minify 后保留),或用 tuple 形式把组件和它的 `catalog.json`
51
+ > manifest 配对——manifest 的 key 是权威的,也不受 minify 影响。
52
+
53
+ ## 内置组件
54
+
55
+ 这个包提供 20 个 A2UI v0.9 basic-catalog renderer。每个都是独立、可 tree-shake
56
+ 的导出,既可从根导入,也可从 `@lynx-js/genui/a2ui/catalog/<Name>` 导入。
57
+
58
+ **布局与容器**
59
+
60
+ | 组件 | 渲染什么 |
61
+ | --------- | ------------------------------------------------------ |
62
+ | `Row` | 一个用于 `children` 列表的水平布局容器。 |
63
+ | `Column` | 一个用于 `children` 列表的垂直布局容器。 |
64
+ | `Card` | 一个带 padding、有层次感的 surface,包裹单个 `child`。 |
65
+ | `List` | 一个可滚动的集合——通常是 templated children 的目标。 |
66
+ | `Tabs` | 在多个子视图之间切换的标签分区。 |
67
+ | `Modal` | 一个层叠在其余 UI 之上的 overlay/dialog surface。 |
68
+ | `Divider` | item 之间的一条细分隔线。 |
69
+
70
+ **内容**
71
+
72
+ | 组件 | 渲染什么 |
73
+ | ------- | --------------------------------------------- |
74
+ | `Text` | 一段文本,带 `variant`(如 `body`)控制样式。 |
75
+ | `Image` | 来自 source URL 的图片。 |
76
+ | `Icon` | 一个具名 icon 字形。 |
77
+
78
+ **输入与动作**
79
+
80
+ | 组件 | 渲染什么 |
81
+ | --------------- | -------------------------------------------- |
82
+ | `Button` | 一个可点击、会 dispatch 用户 action 的按钮。 |
83
+ | `TextField` | 一个绑定到 data model 的单行文本输入。 |
84
+ | `CheckBox` | 一个布尔开关。 |
85
+ | `RadioGroup` | 一组单选的 radio 选项。 |
86
+ | `ChoicePicker` | 一个在多个选项中选择的 picker/select。 |
87
+ | `Slider` | 在一个范围上选择的数值。 |
88
+ | `DateTimeInput` | 一个日期和/或时间输入。 |
89
+
90
+ **数据可视化**
91
+
92
+ | 组件 | 渲染什么 |
93
+ | ----------- | -------------------------- |
94
+ | `LineChart` | 基于一系列数据点的折线图。 |
95
+ | `PieChart` | 基于一组数值的饼图。 |
96
+
97
+ **反馈**
98
+
99
+ | 组件 | 渲染什么 |
100
+ | --------- | --------------------------------------------------------------------------------- |
101
+ | `Loading` | 一个加载指示器。也是 `<A2UI>` 在 surface 处于 pending 时的默认 `renderFallback`。 |
102
+
103
+ 要了解每个组件接受的确切 props,请阅读它的 manifest
104
+ `@lynx-js/genui/a2ui/catalog/<Name>/catalog.json`——那份 JSON 就是 Agent 看到的
105
+ 同一份 schema。
106
+
107
+ ## 为 Agent handshake 加入 manifests
108
+
109
+ 如果你希望 `serializeCatalog(...)` 为每个组件输出 JSON Schema(让 Agent 知道该
110
+ 发哪些 props),用 tuple 形式把每个组件和 `dist/catalog/<Name>/catalog.json`
111
+ 生成的 JSON 配对:
112
+
113
+ ```ts
114
+ import { Text, defineCatalog, serializeCatalog } from '@lynx-js/genui/a2ui';
115
+ import textManifest from '@lynx-js/genui/a2ui/catalog/Text/catalog.json'
116
+ with { type: 'json' };
117
+
118
+ const catalog = defineCatalog([[Text, textManifest]]);
119
+ agentChannel.handshake({ catalog: serializeCatalog(catalog) });
120
+ ```
121
+
122
+ 协议名作为顶层 key 存在 JSON 里,所以运行时从不重复它。没有 manifest 就注册的
123
+ 组件照样能渲染——它们只是序列化成 `{ name }`,告诉 Agent 该组件存在,但不描述
124
+ 它的 props。
125
+
126
+ ## basic-catalog functions
127
+
128
+ A2UI messages 可以在 dynamic props、action payload 和 validation checks 里内嵌
129
+ function call——例如 `{ call: 'formatDate', args: { … } }`。这些在**客户端的渲染
130
+ 时刻**运行。要让它们可用,把 `...basicFunctions` 展开进同一个 catalog input 列表:
131
+
132
+ ```ts
133
+ import { Text, basicFunctions, defineCatalog } from '@lynx-js/genui/a2ui';
134
+
135
+ const catalog = defineCatalog([Text, ...basicFunctions]);
136
+ ```
137
+
138
+ `basicFunctions` 是一组现成 entry 的数组,它们的实现直接来自上游
139
+ `@a2ui/web_core` basic catalog,所以 wire contract 能免费地与 A2UI v0.9 spec
140
+ 保持一致。它覆盖 25 个 function:
141
+
142
+ | 类别 | Functions(协议名) |
143
+ | ------ | --------------------------------------------------------------------------- |
144
+ | 算术 | `add`、`subtract`、`multiply`、`divide` |
145
+ | 比较 | `equals`、`not_equals`、`greater_than`、`less_than` |
146
+ | 逻辑 | `and`、`or`、`not` |
147
+ | 文本 | `contains`、`starts_with`、`ends_with`、`length` |
148
+ | 校验 | `required`、`regex`、`numeric`、`email` |
149
+ | 格式化 | `formatString`、`formatNumber`、`formatCurrency`、`formatDate`、`pluralize` |
150
+ | 动作 | `openUrl` |
151
+
152
+ > 注意大小写不统一——比较/文本类用 `snake_case`(`not_equals`、`starts_with`),
153
+ > 而格式化类用 `camelCase`(`formatDate`、`openUrl`)。这些是上游 A2UI v0.9 的
154
+ > 名称;在 message 里请原样使用。
155
+
156
+ 只要你的 Agent 可能发出其中任何一个,就加入 `...basicFunctions`。如果某条
157
+ message 引用了 catalog 里没有的 function,那次调用会解析为 `undefined` 而不是
158
+ 抛错。
159
+
160
+ 如果你构建自己的 renderer 而不用 `<A2UI>`,调用一次 `registerBasicFunctions()`
161
+ 就能把这些相同的实现注册进共享的 `functionRegistry`。
162
+
163
+ ## 为什么没有 `catalog/all`
164
+
165
+ 这个包刻意**不**提供 all-in-one 的 catalog 常量,也没有
166
+ `@lynx-js/genui/a2ui/catalog/all` 导出。一个引用所有内置组件的顶层数组会破坏
167
+ tree-shaking——任何用到这个聚合的消费者都会打包全部组件,即使它们从不渲染其中
168
+ 某些。组合是逐组件的,bundle 成本在 import 处保持可见。
169
+
170
+ ## 可粘贴的「全部内置」配方
171
+
172
+ 当你确实想要它们全部时,请把列表保留在接入点。下面这段组合了每个内置组件及其
173
+ manifest,外加 basic functions:
174
+
175
+ ```tsx
176
+ import {
177
+ basicFunctions,
178
+ defineCatalog,
179
+ Button,
180
+ Card,
181
+ CheckBox,
182
+ ChoicePicker,
183
+ Column,
184
+ DateTimeInput,
185
+ Divider,
186
+ Icon,
187
+ Image,
188
+ LineChart,
189
+ List,
190
+ Loading,
191
+ Modal,
192
+ PieChart,
193
+ RadioGroup,
194
+ Row,
195
+ Slider,
196
+ Tabs,
197
+ Text,
198
+ TextField,
199
+ } from '@lynx-js/genui/a2ui';
200
+ import buttonManifest from '@lynx-js/genui/a2ui/catalog/Button/catalog.json' with {
201
+ type: 'json',
202
+ };
203
+ import cardManifest from '@lynx-js/genui/a2ui/catalog/Card/catalog.json' with {
204
+ type: 'json',
205
+ };
206
+ import checkBoxManifest from '@lynx-js/genui/a2ui/catalog/CheckBox/catalog.json' with {
207
+ type: 'json',
208
+ };
209
+ import choicePickerManifest from '@lynx-js/genui/a2ui/catalog/ChoicePicker/catalog.json' with {
210
+ type: 'json',
211
+ };
212
+ import columnManifest from '@lynx-js/genui/a2ui/catalog/Column/catalog.json' with {
213
+ type: 'json',
214
+ };
215
+ import dateTimeInputManifest from '@lynx-js/genui/a2ui/catalog/DateTimeInput/catalog.json' with {
216
+ type: 'json',
217
+ };
218
+ import dividerManifest from '@lynx-js/genui/a2ui/catalog/Divider/catalog.json' with {
219
+ type: 'json',
220
+ };
221
+ import iconManifest from '@lynx-js/genui/a2ui/catalog/Icon/catalog.json' with {
222
+ type: 'json',
223
+ };
224
+ import imageManifest from '@lynx-js/genui/a2ui/catalog/Image/catalog.json' with {
225
+ type: 'json',
226
+ };
227
+ import lineChartManifest from '@lynx-js/genui/a2ui/catalog/LineChart/catalog.json' with {
228
+ type: 'json',
229
+ };
230
+ import listManifest from '@lynx-js/genui/a2ui/catalog/List/catalog.json' with {
231
+ type: 'json',
232
+ };
233
+ import loadingManifest from '@lynx-js/genui/a2ui/catalog/Loading/catalog.json' with {
234
+ type: 'json',
235
+ };
236
+ import modalManifest from '@lynx-js/genui/a2ui/catalog/Modal/catalog.json' with {
237
+ type: 'json',
238
+ };
239
+ import pieChartManifest from '@lynx-js/genui/a2ui/catalog/PieChart/catalog.json' with {
240
+ type: 'json',
241
+ };
242
+ import radioGroupManifest from '@lynx-js/genui/a2ui/catalog/RadioGroup/catalog.json' with {
243
+ type: 'json',
244
+ };
245
+ import rowManifest from '@lynx-js/genui/a2ui/catalog/Row/catalog.json' with {
246
+ type: 'json',
247
+ };
248
+ import sliderManifest from '@lynx-js/genui/a2ui/catalog/Slider/catalog.json' with {
249
+ type: 'json',
250
+ };
251
+ import tabsManifest from '@lynx-js/genui/a2ui/catalog/Tabs/catalog.json' with {
252
+ type: 'json',
253
+ };
254
+ import textManifest from '@lynx-js/genui/a2ui/catalog/Text/catalog.json' with {
255
+ type: 'json',
256
+ };
257
+ import textFieldManifest from '@lynx-js/genui/a2ui/catalog/TextField/catalog.json' with {
258
+ type: 'json',
259
+ };
260
+
261
+ export const allBuiltins = defineCatalog([
262
+ [Text, textManifest],
263
+ [Image, imageManifest],
264
+ [Row, rowManifest],
265
+ [Column, columnManifest],
266
+ [List, listManifest],
267
+ [Card, cardManifest],
268
+ [Modal, modalManifest],
269
+ [Button, buttonManifest],
270
+ [Divider, dividerManifest],
271
+ [LineChart, lineChartManifest],
272
+ [PieChart, pieChartManifest],
273
+ [TextField, textFieldManifest],
274
+ [CheckBox, checkBoxManifest],
275
+ [ChoicePicker, choicePickerManifest],
276
+ [DateTimeInput, dateTimeInputManifest],
277
+ [Icon, iconManifest],
278
+ [RadioGroup, radioGroupManifest],
279
+ [Slider, sliderManifest],
280
+ [Tabs, tabsManifest],
281
+ [Loading, loadingManifest],
282
+ ...basicFunctions,
283
+ ]);
284
+ ```
285
+
286
+ 对任何你不需要把 schema 发给 Agent 的组件,去掉它的 manifest 导入和 tuple
287
+ 形式即可——`defineCatalog([Text, Button])` 完全有效。如果你的 messages 用到
288
+ function call,就保留 `...basicFunctions`。
289
+
290
+ ## 自定义组件
291
+
292
+ catalog 组件可以是_任何_接收单个 props 对象并返回 `ReactNode` 的东西。它的
293
+ function 名——或它的 `displayName`——就是 Agent 会使用的协议名:
294
+
295
+ ```tsx
296
+ function MyChart(props: { data: number[] }) { /* … */ }
297
+ // 生产安全所必需:minifier 会改写 `function` 名,但 `displayName` 字符串
298
+ // 字面量会保留。
299
+ MyChart.displayName = 'MyChart';
300
+
301
+ <A2UI catalogs={[Text, Button, MyChart]} … />;
302
+ // Agent emits `{ component: 'MyChart', data: [...] }` → renders MyChart.
303
+ ```
304
+
305
+ 自定义组件从 protocol stream 收到运行时形状的 props。对于任何超出叶子组件的
306
+ 情况,请使用 `@lynx-js/genui/a2ui/react`——这是自定义组件接入的 contract:
307
+
308
+ - **`useDataBinding`**——把一个 bound 值(`{ path }`)针对 surface 的 data model
309
+ 求值,并拿回一个 setter,这样输入组件就能把用户编辑写回 model。
310
+ - **`useResolvedProps`**——一次性解析整个 prop 包,把 data binding 和 function
311
+ call 展开成具体值。
312
+ - **`useAction`**——把一个协议 action 变成你在点击/提交时触发的 `sendAction`
313
+ 回调;结果会通过 `<A2UI onAction>` 回流出去。
314
+ - **`useChecks`**——求值 validation checks(由 `required`/`email` 等 basic
315
+ function 构建),并以 pass/fail 加消息的形式报告。
316
+ - **`NodeRenderer`**——针对同一个 surface 渲染 child component id,方式和内置
317
+ 组件渲染自己的 children 完全一样。
318
+
319
+ ## 为自定义组件生成 manifest
320
+
321
+ 如果 Agent 需要知道某个自定义组件的 props,生成一个 manifest,并像内置组件那样
322
+ 把它配对。
323
+
324
+ 1. 把 props 描述为一个 TypeScript `interface`,并用 `@a2uiCatalog <ComponentName>`
325
+ JSDoc 标签标注它,让 extractor 能识别它。
326
+ 2. 运行公开 CLI 输出 JSON:
327
+
328
+ ```bash
329
+ npx @lynx-js/genui a2ui generate catalog --catalog-dir src/catalog --out-dir dist
330
+ ```
331
+
332
+ 3. 把生成的 JSON 与组件配对:
333
+
334
+ ```tsx
335
+ import myChartManifest from './dist/catalog/MyChart/catalog.json'
336
+ with { type: 'json' };
337
+
338
+ const catalog = defineCatalog([[MyChart, myChartManifest]]);
339
+ ```
340
+
341
+ `npx @lynx-js/genui a2ui generate catalog` 是面向用户的命令;
342
+ `@lynx-js/genui/a2ui-catalog-extractor` 是它背后由 TypeDoc 驱动的引擎。两条约束
343
+ 能让抽取顺利进行:组件文件夹名必须与导出的 function 名一致
344
+ (`src/catalog/MyChart/index.tsx` 导出 `function MyChart`),并且框架级 props
345
+ 会被排除在产出的 schema 之外。详情见
346
+ [extractor README](../../a2ui-catalog-extractor/readme.zh_cn.md)。
347
+
348
+ ## Catalog API 参考
349
+
350
+ 下面这些都从 `@lynx-js/genui/a2ui`(以及 `/catalog` subpath)导出。
351
+
352
+ - **`defineCatalog(inputs)`**——构建运行时 catalog。`inputs` 是一个数组,可以
353
+ 混合 bare components、`[component, manifest]` tuple、已解析的 entry(例如来自
354
+ `mergeCatalogs`),以及 function entries。同一类里的重名会被拒绝。function
355
+ entry 会立即把它的 impl 注册进 `functionRegistry`,所以 `defineCatalog` 之后
356
+ 的任何 `executeFunctionCall` 都能路由到它们。
357
+ - **`mergeCatalogs(...catalogs)`**——合并多个 catalog,重名时**后写覆盖前写**。
358
+ 适合分层:page catalog 覆盖 brand catalog,brand catalog 覆盖内置。
359
+ - **`serializeCatalog(catalog)`**——为 Agent handshake 输出 JSON manifest。没有
360
+ 附带 schema 的组件序列化成 `{ name }`;function 在有 schema 时带上其参数
361
+ schema 一起序列化。
362
+ - **`resolveCatalog(catalog)`**——返回一个 `name → component` 的 map。renderer
363
+ 内部用它来解析 `{ component: 'Text' }`;供高级场景暴露。
364
+ - **`defineFunction(impl, manifest?)`**——把一个 function 实现包装成 catalog
365
+ entry。带 manifest 时,名字来自 manifest 的 key,schema 会被告知 Agent;不带
366
+ 时,名字来自 `impl.displayName ?? impl.name`,Agent 就看不到参数 schema。
367
+
368
+ ## 下一步
369
+
370
+ - [概览与架构](./overview_zh.md)——一条 message 如何变成 UI、职责划分,以及
371
+ export 映射。
372
+ - [System Prompts](./system-prompts_zh.md)——生成让 Agent 与你的 catalog 配套的模型指令。
373
+ - [打开 A2UI playground](https://lynxjs.org/a2ui)——在线体验。