@lynx-js/genui 0.0.1 → 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 (236) 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/Button/{index.js → index.jsx} +12 -8
  6. package/a2ui/dist/catalog/Button/index.jsx.map +1 -0
  7. package/a2ui/dist/catalog/Card/{index.js → index.jsx} +5 -4
  8. package/a2ui/dist/catalog/Card/index.jsx.map +1 -0
  9. package/a2ui/dist/catalog/CheckBox/{index.js → index.jsx} +11 -6
  10. package/a2ui/dist/catalog/CheckBox/index.jsx.map +1 -0
  11. package/a2ui/dist/catalog/ChoicePicker/index.jsx +98 -0
  12. package/a2ui/dist/catalog/ChoicePicker/index.jsx.map +1 -0
  13. package/a2ui/dist/catalog/Column/{index.js → index.jsx} +10 -7
  14. package/a2ui/dist/catalog/Column/{index.js.map → index.jsx.map} +1 -1
  15. package/a2ui/dist/catalog/DateTimeInput/index.jsx +249 -0
  16. package/a2ui/dist/catalog/DateTimeInput/index.jsx.map +1 -0
  17. package/a2ui/dist/catalog/DateTimeInput/utils.d.ts +0 -1
  18. package/a2ui/dist/catalog/DateTimeInput/utils.js +0 -3
  19. package/a2ui/dist/catalog/DateTimeInput/utils.js.map +1 -1
  20. package/a2ui/dist/catalog/Divider/index.jsx +7 -0
  21. package/a2ui/dist/catalog/Divider/index.jsx.map +1 -0
  22. package/a2ui/dist/catalog/Icon/{index.js → index.jsx} +4 -3
  23. package/a2ui/dist/catalog/Icon/{index.js.map → index.jsx.map} +1 -1
  24. package/a2ui/dist/catalog/Image/{index.js → index.jsx} +2 -3
  25. package/a2ui/dist/catalog/Image/{index.js.map → index.jsx.map} +1 -1
  26. package/a2ui/dist/catalog/LineChart/{index.js → index.jsx} +50 -13
  27. package/a2ui/dist/catalog/LineChart/{index.js.map → index.jsx.map} +1 -1
  28. package/a2ui/dist/catalog/List/{index.js → index.jsx} +9 -6
  29. package/a2ui/dist/catalog/List/{index.js.map → index.jsx.map} +1 -1
  30. package/a2ui/dist/catalog/Loading/catalog.json +15 -0
  31. package/a2ui/dist/catalog/Loading/index.d.ts +10 -0
  32. package/a2ui/dist/catalog/Loading/index.jsx +11 -0
  33. package/a2ui/dist/catalog/Loading/index.jsx.map +1 -0
  34. package/a2ui/dist/catalog/Modal/{index.js → index.jsx} +18 -9
  35. package/a2ui/dist/catalog/Modal/index.jsx.map +1 -0
  36. package/a2ui/dist/catalog/PieChart/{index.js → index.jsx} +41 -15
  37. package/a2ui/dist/catalog/PieChart/{index.js.map → index.jsx.map} +1 -1
  38. package/a2ui/dist/catalog/RadioGroup/{index.js → index.jsx} +18 -5
  39. package/a2ui/dist/catalog/RadioGroup/index.jsx.map +1 -0
  40. package/a2ui/dist/catalog/Row/{index.js → index.jsx} +10 -7
  41. package/a2ui/dist/catalog/Row/index.jsx.map +1 -0
  42. package/a2ui/dist/catalog/Slider/{index.js → index.jsx} +22 -7
  43. package/a2ui/dist/catalog/Slider/{index.js.map → index.jsx.map} +1 -1
  44. package/a2ui/dist/catalog/Tabs/index.jsx +40 -0
  45. package/a2ui/dist/catalog/Tabs/index.jsx.map +1 -0
  46. package/a2ui/dist/catalog/Text/catalog.json +6 -2
  47. package/a2ui/dist/catalog/Text/index.d.ts +1 -1
  48. package/a2ui/dist/catalog/Text/index.jsx +16 -0
  49. package/a2ui/dist/catalog/Text/index.jsx.map +1 -0
  50. package/a2ui/dist/catalog/TextField/{index.js → index.jsx} +8 -5
  51. package/a2ui/dist/catalog/TextField/{index.js.map → index.jsx.map} +1 -1
  52. package/a2ui/dist/catalog/defineCatalog.d.ts +0 -4
  53. package/a2ui/dist/catalog/defineCatalog.js.map +1 -1
  54. package/a2ui/dist/catalog/index.d.ts +20 -19
  55. package/a2ui/dist/catalog/index.js +41 -21
  56. package/a2ui/dist/catalog/index.js.map +1 -1
  57. package/a2ui/dist/catalog.json +2548 -0
  58. package/a2ui/dist/index.d.ts +1 -1
  59. package/a2ui/dist/index.js +2 -2
  60. package/a2ui/dist/index.js.map +1 -1
  61. package/a2ui/dist/react/A2UI.d.ts +1 -1
  62. package/a2ui/dist/react/{A2UI.js → A2UI.jsx} +6 -5
  63. package/a2ui/dist/react/{A2UI.js.map → A2UI.jsx.map} +1 -1
  64. package/a2ui/dist/react/{A2UIProvider.js → A2UIProvider.jsx} +2 -3
  65. package/a2ui/dist/react/{A2UIProvider.js.map → A2UIProvider.jsx.map} +1 -1
  66. package/a2ui/dist/react/{A2UIRenderer.js → A2UIRenderer.jsx} +32 -32
  67. package/a2ui/dist/react/A2UIRenderer.jsx.map +1 -0
  68. package/a2ui/dist/react/index.d.ts +3 -3
  69. package/a2ui/dist/react/index.js +2 -2
  70. package/a2ui/dist/react/index.js.map +1 -1
  71. package/a2ui/dist/react/useA2UIContext.d.ts +1 -1
  72. package/a2ui/dist/react/useA2UIContext.js +1 -1
  73. package/a2ui/dist/react/useA2UIContext.js.map +1 -1
  74. package/a2ui/dist/tsconfig.build.tsbuildinfo +1 -1
  75. package/a2ui/docs/catalog-guide.md +401 -0
  76. package/a2ui/docs/catalog-guide_zh.md +373 -0
  77. package/a2ui/docs/overview.md +312 -0
  78. package/a2ui/docs/overview_zh.md +289 -0
  79. package/a2ui/docs/system-prompts.md +187 -0
  80. package/a2ui/docs/system-prompts_zh.md +187 -0
  81. package/a2ui/src/catalog/README.md +12 -0
  82. package/a2ui/src/catalog/index.ts +51 -0
  83. package/a2ui/src/catalog/readme_zh.md +11 -0
  84. package/a2ui/src/index.ts +115 -0
  85. package/a2ui/styles/catalog/Button.css +5 -5
  86. package/a2ui/styles/catalog/DateTimeInput.css +22 -30
  87. package/a2ui/styles/catalog/Loading.css +61 -0
  88. package/a2ui/styles/catalog/Modal.css +1 -0
  89. package/a2ui/styles/catalog/Text.css +2 -6
  90. package/a2ui-catalog-extractor/README.md +14 -7
  91. package/a2ui-catalog-extractor/dist/cli.d.ts +1 -0
  92. package/a2ui-catalog-extractor/dist/cli.js +15 -6
  93. package/a2ui-catalog-extractor/dist/cli.js.map +1 -1
  94. package/a2ui-catalog-extractor/dist/index.d.ts +9 -2
  95. package/a2ui-catalog-extractor/dist/index.js +52 -6
  96. package/a2ui-catalog-extractor/dist/index.js.map +1 -1
  97. package/a2ui-catalog-extractor/dist/tsconfig.build.tsbuildinfo +1 -1
  98. package/a2ui-catalog-extractor/skills/a2ui-catalog-extractor/SKILL.md +1 -1
  99. package/a2ui-prompt/README.md +3 -2
  100. package/a2ui-prompt/dist/index.d.ts +2 -0
  101. package/a2ui-prompt/dist/index.js +259 -184
  102. package/cli/README.md +26 -0
  103. package/cli/bin/cli.js +7 -265
  104. package/cli/dist/a2ui/create.d.ts +5 -0
  105. package/cli/dist/a2ui/create.js +178 -0
  106. package/cli/dist/a2ui/create.js.map +1 -0
  107. package/cli/dist/a2ui/index.d.ts +5 -0
  108. package/cli/dist/a2ui/index.js +170 -0
  109. package/cli/dist/a2ui/index.js.map +1 -0
  110. package/cli/dist/cli.d.ts +4 -0
  111. package/cli/dist/cli.js +40 -0
  112. package/cli/dist/cli.js.map +1 -0
  113. package/cli/dist/openui.d.ts +1 -0
  114. package/cli/dist/openui.js +21 -0
  115. package/cli/dist/openui.js.map +1 -0
  116. package/cli/dist/tsconfig.build.tsbuildinfo +1 -0
  117. package/cli/dist/utils.d.ts +2 -0
  118. package/cli/dist/utils.js +17 -0
  119. package/cli/dist/utils.js.map +1 -0
  120. package/cli/templates/default/lynx.config.ts +13 -0
  121. package/cli/templates/default/package.json +27 -0
  122. package/cli/templates/default/src/App.css +88 -0
  123. package/cli/templates/default/src/App.tsx +100 -0
  124. package/cli/templates/default/src/index.tsx +10 -0
  125. package/cli/templates/default/src/messages.ts +158 -0
  126. package/cli/templates/default/src/rspeedy-env.d.ts +14 -0
  127. package/cli/templates/default/src/tsconfig.json +17 -0
  128. package/cli/templates/default/tsconfig.json +15 -0
  129. package/cli/templates/default/tsconfig.node.json +16 -0
  130. package/dist/tsconfig.build.tsbuildinfo +1 -1
  131. package/openui/README.md +50 -46
  132. package/openui/dist/catalog/Action/{index.js → index.jsx} +1 -1
  133. package/openui/dist/catalog/Action/index.jsx.map +1 -0
  134. package/openui/dist/catalog/Button/index.d.ts +8 -8
  135. package/openui/dist/catalog/Button/{index.js → index.jsx} +28 -14
  136. package/openui/dist/catalog/Button/index.jsx.map +1 -0
  137. package/openui/dist/catalog/Card/index.d.ts +1 -1
  138. package/openui/dist/catalog/Card/{index.js → index.jsx} +5 -4
  139. package/openui/dist/catalog/Card/{index.js.map → index.jsx.map} +1 -1
  140. package/openui/dist/catalog/CardHeader/index.d.ts +1 -1
  141. package/openui/dist/catalog/CardHeader/index.jsx +20 -0
  142. package/openui/dist/catalog/CardHeader/index.jsx.map +1 -0
  143. package/openui/dist/catalog/CheckBox/index.d.ts +16 -0
  144. package/openui/dist/catalog/CheckBox/index.jsx +82 -0
  145. package/openui/dist/catalog/CheckBox/index.jsx.map +1 -0
  146. package/openui/dist/catalog/Icon/index.d.ts +44 -0
  147. package/openui/dist/catalog/Icon/index.jsx +66 -0
  148. package/openui/dist/catalog/Icon/index.jsx.map +1 -0
  149. package/openui/dist/catalog/Image/index.d.ts +19 -0
  150. package/openui/dist/catalog/Image/index.jsx +40 -0
  151. package/openui/dist/catalog/Image/index.jsx.map +1 -0
  152. package/openui/dist/catalog/Loading/index.d.ts +7 -0
  153. package/openui/dist/catalog/Loading/index.jsx +25 -0
  154. package/openui/dist/catalog/Loading/index.jsx.map +1 -0
  155. package/openui/dist/catalog/RadioGroup/index.d.ts +21 -0
  156. package/openui/dist/catalog/RadioGroup/index.jsx +99 -0
  157. package/openui/dist/catalog/RadioGroup/index.jsx.map +1 -0
  158. package/openui/dist/catalog/Separator/index.d.ts +1 -1
  159. package/openui/dist/catalog/Separator/{index.js → index.jsx} +3 -4
  160. package/openui/dist/catalog/Separator/index.jsx.map +1 -0
  161. package/openui/dist/catalog/Slider/index.d.ts +19 -0
  162. package/openui/dist/catalog/Slider/index.jsx +139 -0
  163. package/openui/dist/catalog/Slider/index.jsx.map +1 -0
  164. package/openui/dist/catalog/Stack/index.d.ts +1 -1
  165. package/openui/dist/catalog/Stack/{index.js → index.jsx} +3 -4
  166. package/openui/dist/catalog/Stack/{index.js.map → index.jsx.map} +1 -1
  167. package/openui/dist/catalog/Tag/index.d.ts +1 -1
  168. package/openui/dist/catalog/Tag/{index.js → index.jsx} +5 -4
  169. package/openui/dist/catalog/Tag/index.jsx.map +1 -0
  170. package/openui/dist/catalog/TextContent/index.d.ts +1 -1
  171. package/openui/dist/catalog/TextContent/{index.js → index.jsx} +5 -4
  172. package/openui/dist/catalog/TextContent/{index.js.map → index.jsx.map} +1 -1
  173. package/openui/dist/catalog/TextField/index.d.ts +23 -0
  174. package/openui/dist/catalog/TextField/index.jsx +132 -0
  175. package/openui/dist/catalog/TextField/index.jsx.map +1 -0
  176. package/openui/dist/catalog/index.d.ts +14 -7
  177. package/openui/dist/catalog/index.js +14 -7
  178. package/openui/dist/catalog/index.js.map +1 -1
  179. package/openui/dist/core/context.d.ts +17 -7
  180. package/openui/dist/core/{context.js → context.jsx} +8 -2
  181. package/openui/dist/core/context.jsx.map +1 -0
  182. package/openui/dist/core/createLibrary.d.ts +1 -1
  183. package/openui/dist/core/{createLibrary.js → createLibrary.jsx} +14 -3
  184. package/openui/dist/core/createLibrary.jsx.map +1 -0
  185. package/openui/dist/core/hooks/index.d.ts +1 -0
  186. package/openui/dist/core/hooks/index.js +1 -0
  187. package/openui/dist/core/hooks/index.js.map +1 -1
  188. package/openui/dist/core/hooks/useOpenUIState.d.ts +2 -2
  189. package/openui/dist/core/hooks/useOpenUIState.js +3 -1
  190. package/openui/dist/core/hooks/useOpenUIState.js.map +1 -1
  191. package/openui/dist/core/hooks/useStateField.js +1 -1
  192. package/openui/dist/core/hooks/useStateField.js.map +1 -1
  193. package/openui/dist/core/index.d.ts +13 -7
  194. package/openui/dist/core/index.js +7 -4
  195. package/openui/dist/core/index.js.map +1 -1
  196. package/openui/dist/core/{library.js → library.jsx} +1 -1
  197. package/openui/dist/core/library.jsx.map +1 -0
  198. package/openui/dist/core/renderer.css +527 -0
  199. package/openui/dist/core/renderer.d.ts +31 -4
  200. package/openui/dist/core/renderer.jsx +281 -0
  201. package/openui/dist/core/renderer.jsx.map +1 -0
  202. package/openui/dist/core/runtime/index.d.ts +1 -0
  203. package/openui/dist/core/runtime/index.js +5 -0
  204. package/openui/dist/core/runtime/index.js.map +1 -0
  205. package/openui/dist/core/runtime/reactive.d.ts +7 -0
  206. package/openui/dist/core/runtime/reactive.js +10 -0
  207. package/openui/dist/core/runtime/reactive.js.map +1 -0
  208. package/package.json +18 -8
  209. package/a2ui/dist/catalog/Button/index.js.map +0 -1
  210. package/a2ui/dist/catalog/Card/index.js.map +0 -1
  211. package/a2ui/dist/catalog/CheckBox/index.js.map +0 -1
  212. package/a2ui/dist/catalog/ChoicePicker/index.js +0 -66
  213. package/a2ui/dist/catalog/ChoicePicker/index.js.map +0 -1
  214. package/a2ui/dist/catalog/DateTimeInput/index.js +0 -147
  215. package/a2ui/dist/catalog/DateTimeInput/index.js.map +0 -1
  216. package/a2ui/dist/catalog/Divider/index.js +0 -8
  217. package/a2ui/dist/catalog/Divider/index.js.map +0 -1
  218. package/a2ui/dist/catalog/Modal/index.js.map +0 -1
  219. package/a2ui/dist/catalog/RadioGroup/index.js.map +0 -1
  220. package/a2ui/dist/catalog/Row/index.js.map +0 -1
  221. package/a2ui/dist/catalog/Tabs/index.js +0 -32
  222. package/a2ui/dist/catalog/Tabs/index.js.map +0 -1
  223. package/a2ui/dist/catalog/Text/index.js +0 -27
  224. package/a2ui/dist/catalog/Text/index.js.map +0 -1
  225. package/a2ui/dist/react/A2UIRenderer.js.map +0 -1
  226. package/openui/dist/catalog/Action/index.js.map +0 -1
  227. package/openui/dist/catalog/Button/index.js.map +0 -1
  228. package/openui/dist/catalog/CardHeader/index.js +0 -18
  229. package/openui/dist/catalog/CardHeader/index.js.map +0 -1
  230. package/openui/dist/catalog/Separator/index.js.map +0 -1
  231. package/openui/dist/catalog/Tag/index.js.map +0 -1
  232. package/openui/dist/core/context.js.map +0 -1
  233. package/openui/dist/core/createLibrary.js.map +0 -1
  234. package/openui/dist/core/library.js.map +0 -1
  235. package/openui/dist/core/renderer.js +0 -139
  236. package/openui/dist/core/renderer.js.map +0 -1
@@ -0,0 +1,187 @@
1
+ # System prompts
2
+
3
+ Generate and customize the system instructions that teach an LLM to emit valid A2UI messages.
4
+
5
+ Generate a reusable prompt with the CLI for most deployments, or build one programmatically when the backend needs request-specific catalog or policy inputs. The prompt tells the model how to produce A2UI v0.9 JSON. It includes the protocol rules, the component catalog, function signatures, validated examples, and hard constraints that keep the renderer output safe and parseable.
6
+
7
+ ## 1. CLI
8
+
9
+ Use `npx @lynx-js/genui a2ui generate prompt` when the backend only needs a static prompt file.
10
+
11
+ Generate a prompt with the built-in A2UI basic catalog:
12
+
13
+ ```bash
14
+ npx @lynx-js/genui a2ui generate prompt --out dist/a2ui-system-prompt.txt
15
+ ```
16
+
17
+ Print the prompt to stdout:
18
+
19
+ ```bash
20
+ npx @lynx-js/genui a2ui generate prompt
21
+ ```
22
+
23
+ Append deployment-specific instructions:
24
+
25
+ ```bash
26
+ npx @lynx-js/genui a2ui generate prompt \
27
+ --appendix "Prefer compact mobile layouts for travel booking flows." \
28
+ --out dist/a2ui-system-prompt.txt
29
+ ```
30
+
31
+ `generate prompt` uses the built-in A2UI basic catalog by default. The generated prompt requires `createSurface.catalogId` to match the catalog id embedded in the prompt.
32
+
33
+ ### Custom catalogs
34
+
35
+ For custom components, first generate catalog artifacts:
36
+
37
+ ```bash
38
+ npx @lynx-js/genui a2ui generate catalog \
39
+ --catalog-dir src/catalog \
40
+ --source src/functions \
41
+ --out-dir dist
42
+ ```
43
+
44
+ Then generate the prompt from those artifacts:
45
+
46
+ ```bash
47
+ npx @lynx-js/genui a2ui generate prompt \
48
+ --catalog-dir dist \
49
+ --catalog-id https://example.com/catalogs/custom/v1/catalog.json \
50
+ --out dist/a2ui-system-prompt.txt
51
+ ```
52
+
53
+ `--catalog-dir` must point at the generated catalog root. The prompt generator prefers a full catalog file such as `dist/catalog.json`, and falls back to component files such as `catalog/<Component>/catalog.json`.
54
+
55
+ The package exposes the same commands through the `genui` binary after installation, so project scripts may use `genui a2ui ...` when `@lynx-js/genui` is already installed locally. Existing A2UI-only scripts may also use the `a2ui-cli` compatibility alias.
56
+
57
+ ## 2. Programmatic usage
58
+
59
+ Use `@lynx-js/genui/a2ui-prompt` when the backend needs to construct prompts in Node.js code.
60
+
61
+ Build the default prompt:
62
+
63
+ ```ts
64
+ import { buildA2UISystemPrompt } from '@lynx-js/genui/a2ui-prompt';
65
+
66
+ const systemPrompt = buildA2UISystemPrompt();
67
+ ```
68
+
69
+ Add request- or deployment-specific instructions:
70
+
71
+ ```ts
72
+ import { buildA2UISystemPrompt } from '@lynx-js/genui/a2ui-prompt';
73
+
74
+ const systemPrompt = buildA2UISystemPrompt({
75
+ appendix: [
76
+ 'Prefer concise mobile-first layouts.',
77
+ 'When the user asks for charts, use LineChart only when numeric series are available.',
78
+ ].join('\n'),
79
+ });
80
+ ```
81
+
82
+ Read a generated custom catalog and build a prompt for it:
83
+
84
+ ```ts
85
+ import {
86
+ buildA2UISystemPrompt,
87
+ readA2UICatalogFromDirectory,
88
+ } from '@lynx-js/genui/a2ui-prompt';
89
+
90
+ const catalog = readA2UICatalogFromDirectory({
91
+ catalogDir: 'dist/catalog',
92
+ catalogId: 'https://example.com/catalogs/custom/v1/catalog.json',
93
+ label: 'Example app catalog',
94
+ version: 'v1',
95
+ });
96
+
97
+ const systemPrompt = buildA2UISystemPrompt({ catalog });
98
+ ```
99
+
100
+ For fully in-memory catalog construction, use `createA2UICatalogFromManifests(...)` with component JSON schemas and optional function specs, then pass the resulting catalog to `buildA2UISystemPrompt`.
101
+
102
+ ## What gets generated
103
+
104
+ The generated prompt includes:
105
+
106
+ - A2UI v0.9 protocol overview and design principles.
107
+ - Required server-to-client message types: `createSurface`, `updateComponents`, `updateDataModel`, and `deleteSurface`.
108
+ - Required message ordering for a fresh response.
109
+ - Data binding rules for `{ "path": "/..." }` values and list children.
110
+ - Client action rules for events and function calls.
111
+ - A rendered catalog reference with component summaries, props, required fields, container shape, enum values, and function signatures.
112
+ - Hard rules for JSON-only output, catalog id matching, flat component trees, `root` component requirements, button labels/actions, modal confirmation flows, image query handling, and action-response patches.
113
+ - Validated examples from the catalog, when the catalog provides examples.
114
+ - Optional appendix text supplied by the CLI or programmatic API.
115
+
116
+ The model should return a JSON array of A2UI messages, not Markdown or prose:
117
+
118
+ ```json
119
+ [
120
+ {
121
+ "version": "v0.9",
122
+ "createSurface": {
123
+ "surfaceId": "main",
124
+ "catalogId": "https://a2ui.org/specification/v0_9/basic_catalog.json"
125
+ }
126
+ },
127
+ {
128
+ "version": "v0.9",
129
+ "updateComponents": {
130
+ "surfaceId": "main",
131
+ "components": [
132
+ {
133
+ "id": "root",
134
+ "component": "Text",
135
+ "text": "Hello A2UI"
136
+ }
137
+ ]
138
+ }
139
+ }
140
+ ]
141
+ ```
142
+
143
+ ## Backend usage example
144
+
145
+ The prompt can be used with any model provider that accepts a system message. The backend should send the system prompt before user messages and then parse or stream the model output as A2UI JSON.
146
+
147
+ ```ts
148
+ import OpenAI from 'openai';
149
+ import { buildA2UISystemPrompt } from '@lynx-js/genui/a2ui-prompt';
150
+
151
+ const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
152
+ const systemPrompt = buildA2UISystemPrompt();
153
+
154
+ export async function POST(req: Request) {
155
+ const { messages } = await req.json();
156
+ const completion = await client.chat.completions.create({
157
+ model: process.env.OPENAI_MODEL ?? 'your-model',
158
+ stream: true,
159
+ messages: [
160
+ { role: 'system', content: systemPrompt },
161
+ ...messages,
162
+ ],
163
+ });
164
+
165
+ return new Response(completion.toReadableStream(), {
166
+ headers: { 'Content-Type': 'text/event-stream' },
167
+ });
168
+ }
169
+ ```
170
+
171
+ If the backend supports interactive A2UI actions, preserve the conversation history and pass client action messages back to the model. Action responses should update the existing surface with `updateDataModel` and/or `updateComponents` instead of creating a new surface.
172
+
173
+ ## Choosing an approach
174
+
175
+ Use the CLI when:
176
+
177
+ - The catalog changes at build time.
178
+ - The backend can read a checked-in or generated prompt file.
179
+ - Multiple services should share exactly the same prompt text.
180
+
181
+ Use programmatic generation when:
182
+
183
+ - The catalog, appendix, or safety policy changes per deployment or request.
184
+ - The backend already loads generated catalog artifacts.
185
+ - You need to compose custom `A2UICatalog` objects in code.
186
+
187
+ For custom renderer catalogs and manifest generation, see [Catalogs and manifests](./catalog-guide.md).
@@ -0,0 +1,187 @@
1
+ # System Prompts
2
+
3
+ 生成和定制用于指导 LLM 输出合法 A2UI 消息的系统提示词。
4
+
5
+ 大多数部署场景可以用 CLI 生成一份可复用的 prompt 文件;如果后端需要按请求、环境或 catalog 动态拼装提示词,也可以在 Node.js 代码里通过 API 构建。生成的 prompt 会告诉模型如何输出 A2UI v0.9 JSON,内容包含协议规则、组件 catalog、函数签名、已验证示例,以及保证渲染输出安全、可解析的硬性约束。
6
+
7
+ ## 1. CLI
8
+
9
+ 如果后端只需要一份静态 prompt 文件,可以使用 `npx @lynx-js/genui a2ui generate prompt`。
10
+
11
+ 使用内置 A2UI basic catalog 生成 prompt:
12
+
13
+ ```bash
14
+ npx @lynx-js/genui a2ui generate prompt --out dist/a2ui-system-prompt.txt
15
+ ```
16
+
17
+ 输出到 stdout:
18
+
19
+ ```bash
20
+ npx @lynx-js/genui a2ui generate prompt
21
+ ```
22
+
23
+ 追加部署侧的额外指令:
24
+
25
+ ```bash
26
+ npx @lynx-js/genui a2ui generate prompt \
27
+ --appendix "Prefer compact mobile layouts for travel booking flows." \
28
+ --out dist/a2ui-system-prompt.txt
29
+ ```
30
+
31
+ 默认情况下,`generate prompt` 会使用内置 A2UI basic catalog。生成出的 prompt 会要求 `createSurface.catalogId` 与 prompt 中的 catalog id 一致。
32
+
33
+ ### 自定义 catalog
34
+
35
+ 如果使用自定义组件,需要先生成 catalog 产物:
36
+
37
+ ```bash
38
+ npx @lynx-js/genui a2ui generate catalog \
39
+ --catalog-dir src/catalog \
40
+ --source src/functions \
41
+ --out-dir dist
42
+ ```
43
+
44
+ 然后基于这些产物生成 prompt:
45
+
46
+ ```bash
47
+ npx @lynx-js/genui a2ui generate prompt \
48
+ --catalog-dir dist \
49
+ --catalog-id https://example.com/catalogs/custom/v1/catalog.json \
50
+ --out dist/a2ui-system-prompt.txt
51
+ ```
52
+
53
+ `--catalog-dir` 必须指向生成后的 catalog 根目录。prompt 生成器会优先读取完整 catalog 文件,例如 `dist/catalog.json`;如果不存在,再回退到 `catalog/<Component>/catalog.json`。
54
+
55
+ 安装 `@lynx-js/genui` 后,包内也会暴露同样的 `genui` 命令。因此项目脚本里可以使用 `genui a2ui ...`。已有的 A2UI-only 脚本也可以继续使用 `a2ui-cli` 兼容别名。
56
+
57
+ ## 2. 程序化用法
58
+
59
+ 当后端需要在 Node.js 代码中构建 prompt 时,可以使用 `@lynx-js/genui/a2ui-prompt`。
60
+
61
+ 构建默认 prompt:
62
+
63
+ ```ts
64
+ import { buildA2UISystemPrompt } from '@lynx-js/genui/a2ui-prompt';
65
+
66
+ const systemPrompt = buildA2UISystemPrompt();
67
+ ```
68
+
69
+ 追加请求级或部署级指令:
70
+
71
+ ```ts
72
+ import { buildA2UISystemPrompt } from '@lynx-js/genui/a2ui-prompt';
73
+
74
+ const systemPrompt = buildA2UISystemPrompt({
75
+ appendix: [
76
+ 'Prefer concise mobile-first layouts.',
77
+ 'When the user asks for charts, use LineChart only when numeric series are available.',
78
+ ].join('\n'),
79
+ });
80
+ ```
81
+
82
+ 读取已生成的自定义 catalog,并为它构建 prompt:
83
+
84
+ ```ts
85
+ import {
86
+ buildA2UISystemPrompt,
87
+ readA2UICatalogFromDirectory,
88
+ } from '@lynx-js/genui/a2ui-prompt';
89
+
90
+ const catalog = readA2UICatalogFromDirectory({
91
+ catalogDir: 'dist/catalog',
92
+ catalogId: 'https://example.com/catalogs/custom/v1/catalog.json',
93
+ label: 'Example app catalog',
94
+ version: 'v1',
95
+ });
96
+
97
+ const systemPrompt = buildA2UISystemPrompt({ catalog });
98
+ ```
99
+
100
+ 如果 catalog 已经在内存中,可以使用 `createA2UICatalogFromManifests(...)` 传入组件 JSON Schema 和可选函数定义,构建出 `A2UICatalog` 后再交给 `buildA2UISystemPrompt`。
101
+
102
+ ## 生成内容
103
+
104
+ 生成的 prompt 会包含:
105
+
106
+ - A2UI v0.9 协议概览和设计原则。
107
+ - 必需的服务端到客户端消息类型:`createSurface`、`updateComponents`、`updateDataModel` 和 `deleteSurface`。
108
+ - 新 UI 响应的消息顺序要求。
109
+ - `{ "path": "/..." }` 数据绑定和列表 children 的规则。
110
+ - 客户端 action、event 和 function call 的规则。
111
+ - catalog reference:组件摘要、props、必填字段、容器形态、枚举值和函数签名。
112
+ - 硬性规则:只能输出 JSON、catalog id 必须匹配、组件树必须扁平、必须有 `root` 组件、Button 标签和 action 规则、Modal 确认流程、图片查询处理,以及 action response 的 patch 规则。
113
+ - catalog 提供的已验证示例。
114
+ - CLI 或程序化 API 传入的可选 appendix。
115
+
116
+ 模型应该返回 A2UI 消息组成的 JSON 数组,而不是 Markdown 或自然语言说明:
117
+
118
+ ```json
119
+ [
120
+ {
121
+ "version": "v0.9",
122
+ "createSurface": {
123
+ "surfaceId": "main",
124
+ "catalogId": "https://a2ui.org/specification/v0_9/basic_catalog.json"
125
+ }
126
+ },
127
+ {
128
+ "version": "v0.9",
129
+ "updateComponents": {
130
+ "surfaceId": "main",
131
+ "components": [
132
+ {
133
+ "id": "root",
134
+ "component": "Text",
135
+ "text": "Hello A2UI"
136
+ }
137
+ ]
138
+ }
139
+ }
140
+ ]
141
+ ```
142
+
143
+ ## 后端接入示例
144
+
145
+ 只要模型服务支持 system message,就可以使用生成的 prompt。后端应当先发送 system prompt,再发送用户消息,然后解析或流式转发模型输出的 A2UI JSON。
146
+
147
+ ```ts
148
+ import OpenAI from 'openai';
149
+ import { buildA2UISystemPrompt } from '@lynx-js/genui/a2ui-prompt';
150
+
151
+ const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
152
+ const systemPrompt = buildA2UISystemPrompt();
153
+
154
+ export async function POST(req: Request) {
155
+ const { messages } = await req.json();
156
+ const completion = await client.chat.completions.create({
157
+ model: process.env.OPENAI_MODEL ?? 'your-model',
158
+ stream: true,
159
+ messages: [
160
+ { role: 'system', content: systemPrompt },
161
+ ...messages,
162
+ ],
163
+ });
164
+
165
+ return new Response(completion.toReadableStream(), {
166
+ headers: { 'Content-Type': 'text/event-stream' },
167
+ });
168
+ }
169
+ ```
170
+
171
+ 如果后端支持 A2UI 交互 action,需要保留会话历史,并把客户端 action 消息继续传回模型。action response 应该针对已有 surface 输出 `updateDataModel` 和/或 `updateComponents`,而不是重新创建一个新 surface。
172
+
173
+ ## 如何选择
174
+
175
+ 适合使用 CLI 的场景:
176
+
177
+ - catalog 在构建时确定。
178
+ - 后端可以读取一份已提交或已生成的 prompt 文件。
179
+ - 多个服务需要共享完全一致的 prompt 文本。
180
+
181
+ 适合程序化生成的场景:
182
+
183
+ - catalog、appendix 或安全策略会按环境或请求变化。
184
+ - 后端本来就会加载生成后的 catalog 产物。
185
+ - 需要在代码里组合自定义 `A2UICatalog`。
186
+
187
+ 自定义 renderer catalog 和 manifest 生成流程可继续阅读 [Catalogs and manifests](./catalog-guide_zh.md)。
@@ -0,0 +1,12 @@
1
+ # Catalog composition
2
+
3
+ The catalog documentation now lives in one place:
4
+
5
+ ➡️ **[docs/catalog-guide.md](../../docs/catalog-guide.md)**
6
+
7
+ It covers composing a catalog, the built-in components, adding manifests for
8
+ the Agent handshake, the basic-catalog functions, why there is no
9
+ `catalog/all` aggregate, the paste-able "every built-in" recipe, custom
10
+ components, and the full catalog API reference.
11
+
12
+ 中文版见 [docs/catalog-guide_zh.md](../../docs/catalog-guide_zh.md)。
@@ -0,0 +1,51 @@
1
+ // Copyright 2026 The Lynx Authors. All rights reserved.
2
+ // Licensed under the Apache License Version 2.0 that can be found in the
3
+ // LICENSE file in the root directory of this source tree.
4
+ import type { CatalogManifest } from './defineCatalog.js';
5
+
6
+ export {
7
+ defineCatalog,
8
+ defineFunction,
9
+ mergeCatalogs,
10
+ resolveCatalog,
11
+ serializeCatalog,
12
+ } from './defineCatalog.js';
13
+ export type {
14
+ Catalog,
15
+ CatalogComponent,
16
+ CatalogFunctionDefinition,
17
+ CatalogFunctionEntry,
18
+ CatalogInput,
19
+ CatalogManifest,
20
+ CatalogSchema,
21
+ FunctionManifest,
22
+ ResolvedCatalogEntry,
23
+ SerializedCatalog,
24
+ } from './defineCatalog.js';
25
+
26
+ export const catalogManifests: Record<string, CatalogManifest> = {};
27
+
28
+ // Per-component re-exports so consumers can pick exactly what they need.
29
+ // Each is an independently tree-shakeable ESM re-export — pulling `Text`
30
+ // does not drag `Button` into the bundle.
31
+ export { Button } from './Button/index.jsx';
32
+ export { Card } from './Card/index.jsx';
33
+ export { CheckBox } from './CheckBox/index.jsx';
34
+ export { ChoicePicker } from './ChoicePicker/index.jsx';
35
+ export { DateTimeInput } from './DateTimeInput/index.jsx';
36
+ export { LineChart } from './LineChart/index.jsx';
37
+ export { PieChart } from './PieChart/index.jsx';
38
+ export { Column } from './Column/index.jsx';
39
+ export { Divider } from './Divider/index.jsx';
40
+ export { Icon } from './Icon/index.jsx';
41
+ export { Image } from './Image/index.jsx';
42
+ export { List } from './List/index.jsx';
43
+ export { Loading } from './Loading/index.jsx';
44
+ export { Modal } from './Modal/index.jsx';
45
+ export { RadioGroup } from './RadioGroup/index.jsx';
46
+ export { Row } from './Row/index.jsx';
47
+ export { Slider } from './Slider/index.jsx';
48
+ export { Tabs } from './Tabs/index.jsx';
49
+ export { Text } from './Text/index.jsx';
50
+ export { TextField } from './TextField/index.jsx';
51
+ export { DEFAULT_CHART_COLORS, escapeXml, formatValue } from './utils/chart.js';
@@ -0,0 +1,11 @@
1
+ # Catalog 组合
2
+
3
+ catalog 文档现在统一收在一处:
4
+
5
+ ➡️ **[docs/catalog-guide_zh.md](../../docs/catalog-guide_zh.md)**
6
+
7
+ 它覆盖了组合 catalog、内置组件、为 Agent handshake 加入 manifest、basic-catalog
8
+ functions、为什么没有 `catalog/all` 聚合、可粘贴的「全部内置」配方、自定义组件,
9
+ 以及完整的 catalog API 参考。
10
+
11
+ English version: [docs/catalog-guide.md](../../docs/catalog-guide.md)。
@@ -0,0 +1,115 @@
1
+ // Copyright 2026 The Lynx Authors. All rights reserved.
2
+ // Licensed under the Apache License Version 2.0 that can be found in the
3
+ // LICENSE file in the root directory of this source tree.
4
+
5
+ // React surface — `<A2UI>` is the all-in-one entry point. The hooks +
6
+ // `NodeRenderer` are the contract for custom catalog components.
7
+ export {
8
+ A2UI,
9
+ NodeRenderer,
10
+ useAction,
11
+ useChecks,
12
+ useDataBinding,
13
+ useResolvedProps,
14
+ } from './react/index.js';
15
+ export type { A2UIProps, ActionProps, CheckLike } from './react/index.js';
16
+
17
+ // Store — a pure raw-message buffer. The developer's IO module pushes
18
+ // protocol messages into it; `<A2UI>` subscribes and processes them.
19
+ // `MessageProcessor` is exposed for protocol-aware consumers who want to
20
+ // build their own renderer instead of using `<A2UI>`.
21
+ export { createMessageStore, MessageProcessor } from './store/index.js';
22
+ export type {
23
+ A2UIClientEventMessage,
24
+ ComponentInstance,
25
+ GenericComponentProps,
26
+ MessageStore,
27
+ MessageStoreOptions,
28
+ Resource,
29
+ ResourceInfo,
30
+ ServerToClientMessage,
31
+ Surface,
32
+ SurfaceId,
33
+ UserActionPayload,
34
+ } from './store/index.js';
35
+ // Helpers for IO that returns free-form text instead of structured
36
+ // protocol messages.
37
+ export {
38
+ createFallbackMessagesFromPlainText,
39
+ createTextCardMessages,
40
+ normalizePayloadToMessages,
41
+ prepareMessagesForProcessing,
42
+ } from './store/index.js';
43
+ // Function registry primitives. Consumers building a custom renderer reach
44
+ // the impls through these; `<A2UI>` consumers usually just spread
45
+ // `basicFunctions` into `catalogs`.
46
+ export {
47
+ executeFunctionCall,
48
+ functionRegistry,
49
+ FunctionRegistry,
50
+ resolveDynamicValue,
51
+ } from './store/index.js';
52
+ export type {
53
+ FunctionCallContext,
54
+ FunctionEntry,
55
+ FunctionImpl,
56
+ ResolveFunctionOptions,
57
+ } from './store/index.js';
58
+
59
+ // Catalog — declarative composition.
60
+ export {
61
+ defineCatalog,
62
+ defineFunction,
63
+ mergeCatalogs,
64
+ resolveCatalog,
65
+ serializeCatalog,
66
+ } from './catalog/index.js';
67
+ export type {
68
+ Catalog,
69
+ CatalogComponent,
70
+ CatalogFunctionDefinition,
71
+ CatalogFunctionEntry,
72
+ CatalogInput,
73
+ CatalogManifest,
74
+ CatalogSchema,
75
+ FunctionManifest,
76
+ ResolvedCatalogEntry,
77
+ SerializedCatalog,
78
+ } from './catalog/index.js';
79
+
80
+ // Built-in components — re-exported individually so apps can pick exactly
81
+ // what they need:
82
+ //
83
+ // import { Text, Button } from '@lynx-js/genui/a2ui';
84
+ // <A2UI catalogs={[Text, Button]} ... />
85
+ //
86
+ // There is intentionally no all-in-one aggregate — see
87
+ // `packages/genui/a2ui/docs/catalog-guide.md`.
88
+ export {
89
+ Button,
90
+ Card,
91
+ CheckBox,
92
+ ChoicePicker,
93
+ DateTimeInput,
94
+ Column,
95
+ Divider,
96
+ Image,
97
+ LineChart,
98
+ PieChart,
99
+ List,
100
+ Loading,
101
+ Modal,
102
+ RadioGroup,
103
+ Row,
104
+ Slider,
105
+ Tabs,
106
+ Text,
107
+ TextField,
108
+ Icon,
109
+ } from './catalog/index.js';
110
+
111
+ // A2UI 0.9 basic-catalog functions — registered + announced when spread
112
+ // into `<A2UI catalogs={[..., ...basicFunctions]}>`. Impls come from
113
+ // `@a2ui/web_core` (the upstream basic-catalog package), so the wire
114
+ // contract stays aligned with the spec for free.
115
+ export { basicFunctions, registerBasicFunctions } from './functions/index.js';
@@ -28,12 +28,12 @@
28
28
  }
29
29
 
30
30
  .button-primary {
31
- background-color: var(--a2ui-color-primary);
32
- border-color: var(--a2ui-color-primary);
33
- color: var(--a2ui-color-on-primary);
31
+ background-color: var(--a2ui-color-surface-strong);
32
+ border-color: var(--a2ui-color-border-strong);
33
+ color: var(--a2ui-color-on-surface);
34
34
  box-shadow:
35
- 0 10px 24px rgba(0, 85, 217, 0.16),
36
- 0 1px 0 rgba(255, 255, 255, 0.22) inset;
35
+ 0 10px 24px var(--a2ui-color-overlay),
36
+ 0 1px 0 rgba(255, 255, 255, 0.4) inset;
37
37
  }
38
38
 
39
39
  .button-borderless {