@lynx-js/genui 0.0.1-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/README.md +170 -0
- package/a2ui/README.md +140 -0
- package/a2ui/dist/catalog/Button/catalog.json +156 -0
- package/a2ui/dist/catalog/Button/index.d.ts +35 -0
- package/a2ui/dist/catalog/Button/index.js +35 -0
- package/a2ui/dist/catalog/Button/index.js.map +1 -0
- package/a2ui/dist/catalog/Card/catalog.json +24 -0
- package/a2ui/dist/catalog/Card/index.d.ts +11 -0
- package/a2ui/dist/catalog/Card/index.js +19 -0
- package/a2ui/dist/catalog/Card/index.js.map +1 -0
- package/a2ui/dist/catalog/CheckBox/catalog.json +170 -0
- package/a2ui/dist/catalog/CheckBox/index.d.ts +32 -0
- package/a2ui/dist/catalog/CheckBox/index.js +24 -0
- package/a2ui/dist/catalog/CheckBox/index.js.map +1 -0
- package/a2ui/dist/catalog/Column/catalog.json +57 -0
- package/a2ui/dist/catalog/Column/index.d.ts +15 -0
- package/a2ui/dist/catalog/Column/index.js +55 -0
- package/a2ui/dist/catalog/Column/index.js.map +1 -0
- package/a2ui/dist/catalog/Divider/catalog.json +14 -0
- package/a2ui/dist/catalog/Divider/index.d.ts +9 -0
- package/a2ui/dist/catalog/Divider/index.js +8 -0
- package/a2ui/dist/catalog/Divider/index.js.map +1 -0
- package/a2ui/dist/catalog/Icon/catalog.json +45 -0
- package/a2ui/dist/catalog/Icon/index.d.ts +14 -0
- package/a2ui/dist/catalog/Icon/index.js +11 -0
- package/a2ui/dist/catalog/Icon/index.js.map +1 -0
- package/a2ui/dist/catalog/Image/catalog.json +62 -0
- package/a2ui/dist/catalog/Image/index.d.ts +16 -0
- package/a2ui/dist/catalog/Image/index.js +30 -0
- package/a2ui/dist/catalog/Image/index.js.map +1 -0
- package/a2ui/dist/catalog/LineChart/catalog.json +98 -0
- package/a2ui/dist/catalog/LineChart/index.d.ts +31 -0
- package/a2ui/dist/catalog/LineChart/index.js +195 -0
- package/a2ui/dist/catalog/LineChart/index.js.map +1 -0
- package/a2ui/dist/catalog/List/catalog.json +52 -0
- package/a2ui/dist/catalog/List/index.d.ts +15 -0
- package/a2ui/dist/catalog/List/index.js +53 -0
- package/a2ui/dist/catalog/List/index.js.map +1 -0
- package/a2ui/dist/catalog/Modal/catalog.json +18 -0
- package/a2ui/dist/catalog/Modal/index.d.ts +12 -0
- package/a2ui/dist/catalog/Modal/index.js +33 -0
- package/a2ui/dist/catalog/Modal/index.js.map +1 -0
- package/a2ui/dist/catalog/PieChart/catalog.json +87 -0
- package/a2ui/dist/catalog/PieChart/index.d.ts +37 -0
- package/a2ui/dist/catalog/PieChart/index.js +131 -0
- package/a2ui/dist/catalog/PieChart/index.js.map +1 -0
- package/a2ui/dist/catalog/RadioGroup/catalog.json +184 -0
- package/a2ui/dist/catalog/RadioGroup/index.d.ts +36 -0
- package/a2ui/dist/catalog/RadioGroup/index.js +36 -0
- package/a2ui/dist/catalog/RadioGroup/index.js.map +1 -0
- package/a2ui/dist/catalog/Row/catalog.json +57 -0
- package/a2ui/dist/catalog/Row/index.d.ts +15 -0
- package/a2ui/dist/catalog/Row/index.js +28 -0
- package/a2ui/dist/catalog/Row/index.js.map +1 -0
- package/a2ui/dist/catalog/Slider/catalog.json +183 -0
- package/a2ui/dist/catalog/Slider/index.d.ts +41 -0
- package/a2ui/dist/catalog/Slider/index.js +39 -0
- package/a2ui/dist/catalog/Slider/index.js.map +1 -0
- package/a2ui/dist/catalog/Slider/utils.d.ts +11 -0
- package/a2ui/dist/catalog/Slider/utils.js +58 -0
- package/a2ui/dist/catalog/Slider/utils.js.map +1 -0
- package/a2ui/dist/catalog/Tabs/catalog.json +28 -0
- package/a2ui/dist/catalog/Tabs/index.d.ts +12 -0
- package/a2ui/dist/catalog/Tabs/index.js +32 -0
- package/a2ui/dist/catalog/Tabs/index.js.map +1 -0
- package/a2ui/dist/catalog/Text/catalog.json +74 -0
- package/a2ui/dist/catalog/Text/index.d.ts +18 -0
- package/a2ui/dist/catalog/Text/index.js +27 -0
- package/a2ui/dist/catalog/Text/index.js.map +1 -0
- package/a2ui/dist/catalog/TextField/catalog.json +147 -0
- package/a2ui/dist/catalog/TextField/index.d.ts +35 -0
- package/a2ui/dist/catalog/TextField/index.js +43 -0
- package/a2ui/dist/catalog/TextField/index.js.map +1 -0
- package/a2ui/dist/catalog/TextField/utils.d.ts +7 -0
- package/a2ui/dist/catalog/TextField/utils.js +51 -0
- package/a2ui/dist/catalog/TextField/utils.js.map +1 -0
- package/a2ui/dist/catalog/defineCatalog.d.ts +119 -0
- package/a2ui/dist/catalog/defineCatalog.js +196 -0
- package/a2ui/dist/catalog/defineCatalog.js.map +1 -0
- package/a2ui/dist/catalog/index.d.ts +20 -0
- package/a2ui/dist/catalog/index.js +26 -0
- package/a2ui/dist/catalog/index.js.map +1 -0
- package/a2ui/dist/catalog/utils/chart.d.ts +3 -0
- package/a2ui/dist/catalog/utils/chart.js +28 -0
- package/a2ui/dist/catalog/utils/chart.js.map +1 -0
- package/a2ui/dist/functions/index.d.ts +19 -0
- package/a2ui/dist/functions/index.js +87 -0
- package/a2ui/dist/functions/index.js.map +1 -0
- package/a2ui/dist/index.d.ts +11 -0
- package/a2ui/dist/index.js +35 -0
- package/a2ui/dist/index.js.map +1 -0
- package/a2ui/dist/react/A2UI.d.ts +77 -0
- package/a2ui/dist/react/A2UI.js +159 -0
- package/a2ui/dist/react/A2UI.js.map +1 -0
- package/a2ui/dist/react/A2UIProvider.d.ts +25 -0
- package/a2ui/dist/react/A2UIProvider.js +20 -0
- package/a2ui/dist/react/A2UIProvider.js.map +1 -0
- package/a2ui/dist/react/A2UIRenderer.d.ts +34 -0
- package/a2ui/dist/react/A2UIRenderer.js +161 -0
- package/a2ui/dist/react/A2UIRenderer.js.map +1 -0
- package/a2ui/dist/react/FormContext.d.ts +10 -0
- package/a2ui/dist/react/FormContext.js +12 -0
- package/a2ui/dist/react/FormContext.js.map +1 -0
- package/a2ui/dist/react/index.d.ts +8 -0
- package/a2ui/dist/react/index.js +23 -0
- package/a2ui/dist/react/index.js.map +1 -0
- package/a2ui/dist/react/useA2UIContext.d.ts +7 -0
- package/a2ui/dist/react/useA2UIContext.js +19 -0
- package/a2ui/dist/react/useA2UIContext.js.map +1 -0
- package/a2ui/dist/react/useAction.d.ts +9 -0
- package/a2ui/dist/react/useAction.js +38 -0
- package/a2ui/dist/react/useAction.js.map +1 -0
- package/a2ui/dist/react/useCatalog.d.ts +7 -0
- package/a2ui/dist/react/useCatalog.js +13 -0
- package/a2ui/dist/react/useCatalog.js.map +1 -0
- package/a2ui/dist/react/useChecks.d.ts +27 -0
- package/a2ui/dist/react/useChecks.js +76 -0
- package/a2ui/dist/react/useChecks.js.map +1 -0
- package/a2ui/dist/react/useDataBinding.d.ts +10 -0
- package/a2ui/dist/react/useDataBinding.js +175 -0
- package/a2ui/dist/react/useDataBinding.js.map +1 -0
- package/a2ui/dist/store/FormController.d.ts +23 -0
- package/a2ui/dist/store/FormController.js +40 -0
- package/a2ui/dist/store/FormController.js.map +1 -0
- package/a2ui/dist/store/FunctionRegistry.d.ts +47 -0
- package/a2ui/dist/store/FunctionRegistry.js +23 -0
- package/a2ui/dist/store/FunctionRegistry.js.map +1 -0
- package/a2ui/dist/store/MessageProcessor.d.ts +28 -0
- package/a2ui/dist/store/MessageProcessor.js +408 -0
- package/a2ui/dist/store/MessageProcessor.js.map +1 -0
- package/a2ui/dist/store/MessageStore.d.ts +38 -0
- package/a2ui/dist/store/MessageStore.js +37 -0
- package/a2ui/dist/store/MessageStore.js.map +1 -0
- package/a2ui/dist/store/Resource.d.ts +45 -0
- package/a2ui/dist/store/Resource.js +80 -0
- package/a2ui/dist/store/Resource.js.map +1 -0
- package/a2ui/dist/store/SignalStore.d.ts +10 -0
- package/a2ui/dist/store/SignalStore.js +29 -0
- package/a2ui/dist/store/SignalStore.js.map +1 -0
- package/a2ui/dist/store/index.d.ts +14 -0
- package/a2ui/dist/store/index.js +15 -0
- package/a2ui/dist/store/index.js.map +1 -0
- package/a2ui/dist/store/payloadNormalizer.d.ts +27 -0
- package/a2ui/dist/store/payloadNormalizer.js +179 -0
- package/a2ui/dist/store/payloadNormalizer.js.map +1 -0
- package/a2ui/dist/store/resolveFunctionCall.d.ts +18 -0
- package/a2ui/dist/store/resolveFunctionCall.js +131 -0
- package/a2ui/dist/store/resolveFunctionCall.js.map +1 -0
- package/a2ui/dist/store/types.d.ts +68 -0
- package/a2ui/dist/store/types.js +2 -0
- package/a2ui/dist/store/types.js.map +1 -0
- package/a2ui/dist/tsconfig.build.tsbuildinfo +1 -0
- package/a2ui/styles/catalog/Button.css +83 -0
- package/a2ui/styles/catalog/Card.css +49 -0
- package/a2ui/styles/catalog/CheckBox.css +46 -0
- package/a2ui/styles/catalog/Column.css +89 -0
- package/a2ui/styles/catalog/Divider.css +20 -0
- package/a2ui/styles/catalog/Icon.css +39 -0
- package/a2ui/styles/catalog/Image.css +54 -0
- package/a2ui/styles/catalog/LineChart.css +116 -0
- package/a2ui/styles/catalog/List.css +38 -0
- package/a2ui/styles/catalog/Modal.css +60 -0
- package/a2ui/styles/catalog/PieChart.css +109 -0
- package/a2ui/styles/catalog/RadioGroup.css +123 -0
- package/a2ui/styles/catalog/Row.css +83 -0
- package/a2ui/styles/catalog/Slider.css +96 -0
- package/a2ui/styles/catalog/Tabs.css +46 -0
- package/a2ui/styles/catalog/Text.css +121 -0
- package/a2ui/styles/catalog/TextField.css +48 -0
- package/a2ui/styles/theme.css +62 -0
- package/a2ui-catalog-extractor/README.md +605 -0
- package/a2ui-catalog-extractor/bin/a2ui-catalog-extractor.js +6 -0
- package/a2ui-catalog-extractor/dist/cli.d.ts +12 -0
- package/a2ui-catalog-extractor/dist/cli.js +171 -0
- package/a2ui-catalog-extractor/dist/cli.js.map +1 -0
- package/a2ui-catalog-extractor/dist/index.d.ts +140 -0
- package/a2ui-catalog-extractor/dist/index.js +755 -0
- package/a2ui-catalog-extractor/dist/index.js.map +1 -0
- package/a2ui-catalog-extractor/dist/tsconfig.build.tsbuildinfo +1 -0
- package/a2ui-catalog-extractor/skills/a2ui-catalog-extractor/SKILL.md +30 -0
- package/a2ui-prompt/README.md +65 -0
- package/a2ui-prompt/dist/index.d.ts +91 -0
- package/a2ui-prompt/dist/index.js +767 -0
- package/cli/README.md +88 -0
- package/cli/bin/cli.js +271 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/index.ts +114 -0
- package/openui/README.md +211 -0
- package/openui/dist/catalog/Action/index.d.ts +20 -0
- package/openui/dist/catalog/Action/index.js +23 -0
- package/openui/dist/catalog/Action/index.js.map +1 -0
- package/openui/dist/catalog/Button/index.d.ts +64 -0
- package/openui/dist/catalog/Button/index.js +75 -0
- package/openui/dist/catalog/Button/index.js.map +1 -0
- package/openui/dist/catalog/Card/index.d.ts +34 -0
- package/openui/dist/catalog/Card/index.js +69 -0
- package/openui/dist/catalog/Card/index.js.map +1 -0
- package/openui/dist/catalog/CardHeader/index.d.ts +5 -0
- package/openui/dist/catalog/CardHeader/index.js +18 -0
- package/openui/dist/catalog/CardHeader/index.js.map +1 -0
- package/openui/dist/catalog/Separator/index.d.ts +2 -0
- package/openui/dist/catalog/Separator/index.js +13 -0
- package/openui/dist/catalog/Separator/index.js.map +1 -0
- package/openui/dist/catalog/Stack/index.d.ts +29 -0
- package/openui/dist/catalog/Stack/index.js +61 -0
- package/openui/dist/catalog/Stack/index.js.map +1 -0
- package/openui/dist/catalog/Tag/index.d.ts +4 -0
- package/openui/dist/catalog/Tag/index.js +15 -0
- package/openui/dist/catalog/Tag/index.js.map +1 -0
- package/openui/dist/catalog/TextContent/index.d.ts +11 -0
- package/openui/dist/catalog/TextContent/index.js +33 -0
- package/openui/dist/catalog/TextContent/index.js.map +1 -0
- package/openui/dist/catalog/index.d.ts +7 -0
- package/openui/dist/catalog/index.js +11 -0
- package/openui/dist/catalog/index.js.map +1 -0
- package/openui/dist/catalog/utils.d.ts +2 -0
- package/openui/dist/catalog/utils.js +17 -0
- package/openui/dist/catalog/utils.js.map +1 -0
- package/openui/dist/core/context.d.ts +112 -0
- package/openui/dist/core/context.js +99 -0
- package/openui/dist/core/context.js.map +1 -0
- package/openui/dist/core/createLibrary.d.ts +10 -0
- package/openui/dist/core/createLibrary.js +36 -0
- package/openui/dist/core/createLibrary.js.map +1 -0
- package/openui/dist/core/hooks/index.d.ts +4 -0
- package/openui/dist/core/hooks/index.js +6 -0
- package/openui/dist/core/hooks/index.js.map +1 -0
- package/openui/dist/core/hooks/useFormValidation.d.ts +13 -0
- package/openui/dist/core/hooks/useFormValidation.js +76 -0
- package/openui/dist/core/hooks/useFormValidation.js.map +1 -0
- package/openui/dist/core/hooks/useOpenUIState.d.ts +33 -0
- package/openui/dist/core/hooks/useOpenUIState.js +413 -0
- package/openui/dist/core/hooks/useOpenUIState.js.map +1 -0
- package/openui/dist/core/hooks/useStateField.d.ts +2 -0
- package/openui/dist/core/hooks/useStateField.js +11 -0
- package/openui/dist/core/hooks/useStateField.js.map +1 -0
- package/openui/dist/core/index.d.ts +7 -0
- package/openui/dist/core/index.js +8 -0
- package/openui/dist/core/index.js.map +1 -0
- package/openui/dist/core/library.d.ts +20 -0
- package/openui/dist/core/library.js +13 -0
- package/openui/dist/core/library.js.map +1 -0
- package/openui/dist/core/renderer.css +271 -0
- package/openui/dist/core/renderer.d.ts +9 -0
- package/openui/dist/core/renderer.js +139 -0
- package/openui/dist/core/renderer.js.map +1 -0
- package/openui/dist/core/utils.d.ts +1 -0
- package/openui/dist/core/utils.js +76 -0
- package/openui/dist/core/utils.js.map +1 -0
- package/package.json +120 -0
|
@@ -0,0 +1,605 @@
|
|
|
1
|
+
# A2UI Catalog Extractor
|
|
2
|
+
|
|
3
|
+
English | [简体中文](./readme.zh_cn.md)
|
|
4
|
+
|
|
5
|
+
`@lynx-js/genui/a2ui-catalog-extractor` turns TypeScript component
|
|
6
|
+
interfaces into A2UI component catalog JSON. You write the public
|
|
7
|
+
component contract once as a TypeScript `interface`, describe it with
|
|
8
|
+
normal TypeDoc comments, and let this package generate the JSON Schema
|
|
9
|
+
that an A2UI agent can read.
|
|
10
|
+
|
|
11
|
+
## What It Does
|
|
12
|
+
|
|
13
|
+
A2UI catalogs describe what components a renderer supports. For each
|
|
14
|
+
component, the catalog tells an agent which props are valid, which props
|
|
15
|
+
are required, which enum values are allowed, and what each field means.
|
|
16
|
+
|
|
17
|
+
This extractor generates the `components` part of an A2UI v0.9 catalog:
|
|
18
|
+
|
|
19
|
+
```json
|
|
20
|
+
{
|
|
21
|
+
"QuickStartCard": {
|
|
22
|
+
"properties": {
|
|
23
|
+
"title": { "type": "string" }
|
|
24
|
+
},
|
|
25
|
+
"required": ["title"]
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
It can also wrap those generated components with a `catalogId`,
|
|
31
|
+
`functions`, and `theme` through `createA2UICatalog`.
|
|
32
|
+
|
|
33
|
+
## What It Does Not Do
|
|
34
|
+
|
|
35
|
+
- It does not render A2UI UI.
|
|
36
|
+
- It does not parse TypeScript source text by hand.
|
|
37
|
+
- It does not use the TypeScript compiler API directly.
|
|
38
|
+
- It does not ask you to write JSON Schema in comments.
|
|
39
|
+
- It does not expand arbitrary imported type aliases or external
|
|
40
|
+
interfaces.
|
|
41
|
+
- It does not call an LLM or choose a model.
|
|
42
|
+
|
|
43
|
+
The package consumes TypeDoc reflection data. This keeps the implementation
|
|
44
|
+
small, but it also means catalog-facing shapes should be written inline in
|
|
45
|
+
the marked interface.
|
|
46
|
+
|
|
47
|
+
## Requirements
|
|
48
|
+
|
|
49
|
+
- Node.js 22 or newer.
|
|
50
|
+
- TypeScript or TSX source files that TypeDoc can read.
|
|
51
|
+
- One TypeScript `interface` per catalog-facing component contract.
|
|
52
|
+
|
|
53
|
+
## Installation
|
|
54
|
+
|
|
55
|
+
### Package manager
|
|
56
|
+
|
|
57
|
+
Install the extractor as a development dependency:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
pnpm add -D @lynx-js/genui
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Then add a script to your package:
|
|
64
|
+
|
|
65
|
+
```json
|
|
66
|
+
{
|
|
67
|
+
"scripts": {
|
|
68
|
+
"build:catalog": "a2ui-catalog-extractor --catalog-dir src/catalog --out-dir dist/catalog"
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Run it with:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
pnpm build:catalog
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Quick Start
|
|
80
|
+
|
|
81
|
+
This example walks through a complete component contract from TypeScript
|
|
82
|
+
interface to generated catalog JSON.
|
|
83
|
+
|
|
84
|
+
### 1. Create a catalog-facing interface
|
|
85
|
+
|
|
86
|
+
Create `src/catalog/QuickStartCard.tsx`:
|
|
87
|
+
|
|
88
|
+
```tsx
|
|
89
|
+
/**
|
|
90
|
+
* Quick start card.
|
|
91
|
+
*
|
|
92
|
+
* @remarks Use this contract as a compact card example.
|
|
93
|
+
* @a2uiCatalog QuickStartCard
|
|
94
|
+
*/
|
|
95
|
+
export interface QuickStartCardProps {
|
|
96
|
+
/** Card title text or data binding. */
|
|
97
|
+
title: string | { path: string };
|
|
98
|
+
/** Visual tone used by the renderer. */
|
|
99
|
+
tone?: 'neutral' | 'accent';
|
|
100
|
+
/**
|
|
101
|
+
* Tags shown below the title.
|
|
102
|
+
*
|
|
103
|
+
* @defaultValue `[]`
|
|
104
|
+
*/
|
|
105
|
+
tags?: string[];
|
|
106
|
+
/** Author metadata rendered in the card footer. */
|
|
107
|
+
author: {
|
|
108
|
+
/** Display name. */
|
|
109
|
+
name: string;
|
|
110
|
+
/** Optional profile URL. */
|
|
111
|
+
url?: string;
|
|
112
|
+
};
|
|
113
|
+
/**
|
|
114
|
+
* Extra analytics context sent with user actions.
|
|
115
|
+
*
|
|
116
|
+
* @defaultValue `{}`
|
|
117
|
+
*/
|
|
118
|
+
context?: Record<string, string | number | boolean>;
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
The important part is `@a2uiCatalog QuickStartCard`. It tells the
|
|
123
|
+
extractor that this interface should become a catalog component named
|
|
124
|
+
`QuickStartCard`.
|
|
125
|
+
|
|
126
|
+
### 2. Generate catalog files
|
|
127
|
+
|
|
128
|
+
Run:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
a2ui-catalog-extractor --catalog-dir src/catalog --out-dir dist/catalog
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
The extractor scans the catalog directory, finds interfaces marked with
|
|
135
|
+
`@a2uiCatalog`, and writes one file per component:
|
|
136
|
+
|
|
137
|
+
```text
|
|
138
|
+
dist/catalog/
|
|
139
|
+
QuickStartCard/
|
|
140
|
+
catalog.json
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### 3. Read the generated schema
|
|
144
|
+
|
|
145
|
+
`dist/catalog/QuickStartCard/catalog.json` will look like this:
|
|
146
|
+
|
|
147
|
+
```json
|
|
148
|
+
{
|
|
149
|
+
"QuickStartCard": {
|
|
150
|
+
"properties": {
|
|
151
|
+
"title": {
|
|
152
|
+
"oneOf": [
|
|
153
|
+
{
|
|
154
|
+
"type": "string"
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"type": "object",
|
|
158
|
+
"properties": {
|
|
159
|
+
"path": {
|
|
160
|
+
"type": "string"
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
"required": [
|
|
164
|
+
"path"
|
|
165
|
+
],
|
|
166
|
+
"additionalProperties": false
|
|
167
|
+
}
|
|
168
|
+
],
|
|
169
|
+
"description": "Card title text or data binding."
|
|
170
|
+
},
|
|
171
|
+
"tone": {
|
|
172
|
+
"type": "string",
|
|
173
|
+
"enum": [
|
|
174
|
+
"neutral",
|
|
175
|
+
"accent"
|
|
176
|
+
],
|
|
177
|
+
"description": "Visual tone used by the renderer."
|
|
178
|
+
},
|
|
179
|
+
"tags": {
|
|
180
|
+
"type": "array",
|
|
181
|
+
"items": {
|
|
182
|
+
"type": "string"
|
|
183
|
+
},
|
|
184
|
+
"description": "Tags shown below the title.",
|
|
185
|
+
"default": []
|
|
186
|
+
},
|
|
187
|
+
"author": {
|
|
188
|
+
"type": "object",
|
|
189
|
+
"properties": {
|
|
190
|
+
"name": {
|
|
191
|
+
"type": "string",
|
|
192
|
+
"description": "Display name."
|
|
193
|
+
},
|
|
194
|
+
"url": {
|
|
195
|
+
"type": "string",
|
|
196
|
+
"description": "Optional profile URL."
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
"required": [
|
|
200
|
+
"name"
|
|
201
|
+
],
|
|
202
|
+
"additionalProperties": false,
|
|
203
|
+
"description": "Author metadata rendered in the card footer."
|
|
204
|
+
},
|
|
205
|
+
"context": {
|
|
206
|
+
"type": "object",
|
|
207
|
+
"additionalProperties": {
|
|
208
|
+
"oneOf": [
|
|
209
|
+
{
|
|
210
|
+
"type": "string"
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
"type": "number"
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
"type": "boolean"
|
|
217
|
+
}
|
|
218
|
+
]
|
|
219
|
+
},
|
|
220
|
+
"description": "Extra analytics context sent with user actions.",
|
|
221
|
+
"default": {}
|
|
222
|
+
}
|
|
223
|
+
},
|
|
224
|
+
"required": [
|
|
225
|
+
"title",
|
|
226
|
+
"author"
|
|
227
|
+
],
|
|
228
|
+
"description": "Quick start card.\n\nUse this contract as a compact card example."
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
Notice the main conversions:
|
|
234
|
+
|
|
235
|
+
- `title` is required because it does not use `?`.
|
|
236
|
+
- `tone` becomes a string enum.
|
|
237
|
+
- `tags?: string[]` becomes an optional array of strings.
|
|
238
|
+
- `author` becomes a strict inline object with
|
|
239
|
+
`additionalProperties: false`.
|
|
240
|
+
- `context?: Record<string, string | number | boolean>` becomes an object
|
|
241
|
+
map with `additionalProperties`.
|
|
242
|
+
- TypeDoc comments become JSON Schema descriptions.
|
|
243
|
+
|
|
244
|
+
## Authoring Guide
|
|
245
|
+
|
|
246
|
+
### Mark only the catalog contract
|
|
247
|
+
|
|
248
|
+
Only TypeScript `interface` reflections are converted. Put
|
|
249
|
+
`@a2uiCatalog` on the interface that describes the props an agent is
|
|
250
|
+
allowed to send:
|
|
251
|
+
|
|
252
|
+
```tsx
|
|
253
|
+
/**
|
|
254
|
+
* @a2uiCatalog Text
|
|
255
|
+
*/
|
|
256
|
+
export interface TextProps {
|
|
257
|
+
text: string;
|
|
258
|
+
}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
Do not put the tag on the component function:
|
|
262
|
+
|
|
263
|
+
```tsx
|
|
264
|
+
export function Text(_props: TextProps) {
|
|
265
|
+
return null;
|
|
266
|
+
}
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### Component names
|
|
270
|
+
|
|
271
|
+
You can write the component name explicitly:
|
|
272
|
+
|
|
273
|
+
```tsx
|
|
274
|
+
/**
|
|
275
|
+
* @a2uiCatalog Text
|
|
276
|
+
*/
|
|
277
|
+
export interface TextProps {}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
If the tag is empty, the extractor infers the name from the interface by
|
|
281
|
+
removing a trailing `Props` or `ComponentProps`:
|
|
282
|
+
|
|
283
|
+
```tsx
|
|
284
|
+
/**
|
|
285
|
+
* @a2uiCatalog
|
|
286
|
+
*/
|
|
287
|
+
export interface DemoTextProps {}
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
This becomes `DemoText`.
|
|
291
|
+
|
|
292
|
+
### Comments become schema metadata
|
|
293
|
+
|
|
294
|
+
Use normal TypeDoc comments:
|
|
295
|
+
|
|
296
|
+
```tsx
|
|
297
|
+
/**
|
|
298
|
+
* User-facing card.
|
|
299
|
+
*
|
|
300
|
+
* @remarks Use this for compact summaries.
|
|
301
|
+
* @a2uiCatalog SummaryCard
|
|
302
|
+
*/
|
|
303
|
+
export interface SummaryCardProps {
|
|
304
|
+
/**
|
|
305
|
+
* Optional display density.
|
|
306
|
+
*
|
|
307
|
+
* @defaultValue `"comfortable"`
|
|
308
|
+
*/
|
|
309
|
+
density?: 'compact' | 'comfortable';
|
|
310
|
+
}
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
The extractor maps comments like this:
|
|
314
|
+
|
|
315
|
+
| TypeDoc comment | JSON Schema output |
|
|
316
|
+
| ----------------------------- | -------------------------------- |
|
|
317
|
+
| Summary text | `description` |
|
|
318
|
+
| `@remarks` | Appended to `description` |
|
|
319
|
+
| `@defaultValue` or `@default` | `default` |
|
|
320
|
+
| `@deprecated` | `deprecated: true` |
|
|
321
|
+
| Optional property `?` | Property omitted from `required` |
|
|
322
|
+
|
|
323
|
+
For object and array defaults, put JSON inside a code span:
|
|
324
|
+
|
|
325
|
+
```tsx
|
|
326
|
+
/**
|
|
327
|
+
* @defaultValue `{}`
|
|
328
|
+
*/
|
|
329
|
+
context?: Record<string, string>;
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
Without the code span, TypeDoc may pass formatted text instead of the raw
|
|
333
|
+
JSON value.
|
|
334
|
+
|
|
335
|
+
### Supported TypeScript shapes
|
|
336
|
+
|
|
337
|
+
| TypeScript shape | JSON Schema shape |
|
|
338
|
+
| ---------------------------- | ------------------------------------------------ |
|
|
339
|
+
| `string` | `{ "type": "string" }` |
|
|
340
|
+
| `number` | `{ "type": "number" }` |
|
|
341
|
+
| `boolean` | `{ "type": "boolean" }` |
|
|
342
|
+
| `'a' \| 'b'` | `{ "type": "string", "enum": ["a", "b"] }` |
|
|
343
|
+
| `string \| { path: string }` | `{ "oneOf": [...] }` |
|
|
344
|
+
| `T[]` | `{ "type": "array", "items": ... }` |
|
|
345
|
+
| `Array<T>` | `{ "type": "array", "items": ... }` |
|
|
346
|
+
| `ReadonlyArray<T>` | `{ "type": "array", "items": ... }` |
|
|
347
|
+
| `{ name: string }` | Strict object with `additionalProperties: false` |
|
|
348
|
+
| `Record<string, T>` | Object map with `additionalProperties: ...` |
|
|
349
|
+
|
|
350
|
+
### Unsupported or ambiguous types
|
|
351
|
+
|
|
352
|
+
These types intentionally fail:
|
|
353
|
+
|
|
354
|
+
- `any`
|
|
355
|
+
- `unknown`
|
|
356
|
+
- `null`
|
|
357
|
+
- `undefined`
|
|
358
|
+
- `never`
|
|
359
|
+
- `void`
|
|
360
|
+
- nullable unions such as `string | null`
|
|
361
|
+
- most imported aliases and referenced external interfaces
|
|
362
|
+
- `Record<number, T>` or other non-string record keys
|
|
363
|
+
|
|
364
|
+
Prefer explicit catalog contracts:
|
|
365
|
+
|
|
366
|
+
```tsx
|
|
367
|
+
// Avoid this in catalog-facing interfaces.
|
|
368
|
+
type ExternalCardData = {
|
|
369
|
+
title: string;
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
export interface CardProps {
|
|
373
|
+
data: ExternalCardData;
|
|
374
|
+
}
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
Write the shape inline instead:
|
|
378
|
+
|
|
379
|
+
```tsx
|
|
380
|
+
export interface CardProps {
|
|
381
|
+
data: {
|
|
382
|
+
title: string;
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
## CLI Reference
|
|
388
|
+
|
|
389
|
+
The package exposes the standalone `a2ui-catalog-extractor` binary. The
|
|
390
|
+
`@lynx-js/genui-cli` also exposes this flow as
|
|
391
|
+
`genui a2ui generate catalog`.
|
|
392
|
+
|
|
393
|
+
### Generate catalog artifacts
|
|
394
|
+
|
|
395
|
+
```bash
|
|
396
|
+
a2ui-catalog-extractor [options]
|
|
397
|
+
# or
|
|
398
|
+
genui a2ui generate catalog [options]
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
| Option | Description | Default |
|
|
402
|
+
| ----------------------- | ---------------------------------------------------------------------------- | -------------- |
|
|
403
|
+
| `--catalog-dir <dir>` | Directory to scan for source files. Repeatable. | `src/catalog` |
|
|
404
|
+
| `--source <path>` | Source file or directory to scan. Repeatable. | None |
|
|
405
|
+
| `--typedoc-json <file>` | Read an existing TypeDoc JSON project instead of running TypeDoc conversion. | None |
|
|
406
|
+
| `--out-dir <dir>` | Directory where component catalog files are written. | `dist/catalog` |
|
|
407
|
+
| `--version`, `-v` | Print the package version. | None |
|
|
408
|
+
| `--help`, `-h` | Print usage. | None |
|
|
409
|
+
|
|
410
|
+
`--source` and `--catalog-dir` can be used together. The extractor merges
|
|
411
|
+
all inputs, removes duplicates, sorts them, and then runs TypeDoc.
|
|
412
|
+
|
|
413
|
+
The scanner accepts `.ts`, `.tsx`, `.js`, `.jsx`, `.mts`, and `.cts`
|
|
414
|
+
files. It ignores `.d.ts`, `node_modules`, `dist`, and `.turbo`.
|
|
415
|
+
|
|
416
|
+
## Programmatic API
|
|
417
|
+
|
|
418
|
+
### Generate components from source files
|
|
419
|
+
|
|
420
|
+
```ts
|
|
421
|
+
import {
|
|
422
|
+
extractCatalogComponents,
|
|
423
|
+
writeComponentCatalogs,
|
|
424
|
+
} from '@lynx-js/genui/a2ui-catalog-extractor';
|
|
425
|
+
|
|
426
|
+
const components = await extractCatalogComponents({
|
|
427
|
+
sourceFiles: ['src/catalog/QuickStartCard.tsx'],
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
await writeComponentCatalogs({
|
|
431
|
+
sourceFiles: ['src/catalog/QuickStartCard.tsx'],
|
|
432
|
+
outDir: 'dist/catalog',
|
|
433
|
+
});
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
Use `cwd` when paths should be resolved relative to a specific project
|
|
437
|
+
directory:
|
|
438
|
+
|
|
439
|
+
```ts
|
|
440
|
+
await writeComponentCatalogs({
|
|
441
|
+
cwd: process.cwd(),
|
|
442
|
+
sourceFiles: ['src/catalog/QuickStartCard.tsx'],
|
|
443
|
+
outDir: 'dist/catalog',
|
|
444
|
+
});
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
Use `tsconfig` when the project needs a specific TypeScript config:
|
|
448
|
+
|
|
449
|
+
```ts
|
|
450
|
+
const components = await extractCatalogComponents({
|
|
451
|
+
cwd: process.cwd(),
|
|
452
|
+
sourceFiles: ['src/catalog/QuickStartCard.tsx'],
|
|
453
|
+
tsconfig: 'tsconfig.json',
|
|
454
|
+
});
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
### Generate components from TypeDoc JSON
|
|
458
|
+
|
|
459
|
+
If your build already produces a TypeDoc JSON project, reuse it:
|
|
460
|
+
|
|
461
|
+
```ts
|
|
462
|
+
import * as fs from 'node:fs';
|
|
463
|
+
|
|
464
|
+
import {
|
|
465
|
+
extractCatalogComponentsFromTypeDocJson,
|
|
466
|
+
writeCatalogComponents,
|
|
467
|
+
} from '@lynx-js/genui/a2ui-catalog-extractor';
|
|
468
|
+
|
|
469
|
+
const projectJson = JSON.parse(
|
|
470
|
+
await fs.promises.readFile('typedoc.json', 'utf8'),
|
|
471
|
+
);
|
|
472
|
+
const components = extractCatalogComponentsFromTypeDocJson(projectJson);
|
|
473
|
+
|
|
474
|
+
writeCatalogComponents(components, {
|
|
475
|
+
outDir: 'dist/catalog',
|
|
476
|
+
});
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
The equivalent CLI command is:
|
|
480
|
+
|
|
481
|
+
```bash
|
|
482
|
+
a2ui-catalog-extractor --typedoc-json typedoc.json --out-dir dist/catalog
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
### Create a full A2UI catalog object
|
|
486
|
+
|
|
487
|
+
`createA2UICatalog` is a small helper that wraps generated components with
|
|
488
|
+
the other top-level A2UI catalog fields:
|
|
489
|
+
|
|
490
|
+
```ts
|
|
491
|
+
import {
|
|
492
|
+
createA2UICatalog,
|
|
493
|
+
extractCatalogComponents,
|
|
494
|
+
} from '@lynx-js/genui/a2ui-catalog-extractor';
|
|
495
|
+
|
|
496
|
+
const components = await extractCatalogComponents({
|
|
497
|
+
sourceFiles: ['src/catalog/QuickStartCard.tsx'],
|
|
498
|
+
});
|
|
499
|
+
|
|
500
|
+
const catalog = createA2UICatalog({
|
|
501
|
+
catalogId: 'https://example.com/catalogs/basic/v1/catalog.json',
|
|
502
|
+
components,
|
|
503
|
+
functions: [
|
|
504
|
+
{
|
|
505
|
+
name: 'formatDisplayValue',
|
|
506
|
+
description: 'Format a raw value for display.',
|
|
507
|
+
parameters: {
|
|
508
|
+
type: 'object',
|
|
509
|
+
properties: {
|
|
510
|
+
value: { type: 'string' },
|
|
511
|
+
},
|
|
512
|
+
required: ['value'],
|
|
513
|
+
additionalProperties: false,
|
|
514
|
+
},
|
|
515
|
+
returnType: 'string',
|
|
516
|
+
},
|
|
517
|
+
],
|
|
518
|
+
theme: {
|
|
519
|
+
accentColor: { type: 'string' },
|
|
520
|
+
},
|
|
521
|
+
});
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
`functions` and `theme` are not extracted from TypeScript. Pass them
|
|
525
|
+
explicitly if your catalog needs them.
|
|
526
|
+
|
|
527
|
+
## Troubleshooting
|
|
528
|
+
|
|
529
|
+
### `Unsupported ambiguous intrinsic TypeDoc type "unknown"`
|
|
530
|
+
|
|
531
|
+
The catalog needs a concrete schema. Replace `unknown` or `any` with a
|
|
532
|
+
specific type:
|
|
533
|
+
|
|
534
|
+
```tsx
|
|
535
|
+
// Fails.
|
|
536
|
+
payload: unknown;
|
|
537
|
+
|
|
538
|
+
// Works.
|
|
539
|
+
payload: {
|
|
540
|
+
id: string;
|
|
541
|
+
count: number;
|
|
542
|
+
}
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
### `Unsupported nullable union`
|
|
546
|
+
|
|
547
|
+
Nullable unions are not accepted:
|
|
548
|
+
|
|
549
|
+
```tsx
|
|
550
|
+
// Fails.
|
|
551
|
+
label: string | null;
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
Make the property optional if it can be omitted:
|
|
555
|
+
|
|
556
|
+
```tsx
|
|
557
|
+
label?: string;
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
Or model the state explicitly:
|
|
561
|
+
|
|
562
|
+
```tsx
|
|
563
|
+
label: string | { path: string };
|
|
564
|
+
```
|
|
565
|
+
|
|
566
|
+
### `Unsupported TypeDoc reference`
|
|
567
|
+
|
|
568
|
+
The extractor only understands a small set of references:
|
|
569
|
+
`Array<T>`, `ReadonlyArray<T>`, and `Record<string, T>`. Inline object
|
|
570
|
+
shapes in the catalog-facing interface instead of importing aliases.
|
|
571
|
+
|
|
572
|
+
### My output directory is empty
|
|
573
|
+
|
|
574
|
+
Check these points:
|
|
575
|
+
|
|
576
|
+
- The scanned files contain an `interface`, not only a `type`.
|
|
577
|
+
- The interface has `@a2uiCatalog`.
|
|
578
|
+
- The path passed to `--catalog-dir` or `--source` exists.
|
|
579
|
+
- The files are not `.d.ts`.
|
|
580
|
+
- TypeDoc can parse the files with your `tsconfig`.
|
|
581
|
+
|
|
582
|
+
### The generated schema does not include inherited props
|
|
583
|
+
|
|
584
|
+
Inherited members are skipped. This is intentional because runtime-only
|
|
585
|
+
props such as renderer context should not be part of the agent-facing
|
|
586
|
+
catalog. Put every catalog-facing prop directly on the marked interface.
|
|
587
|
+
|
|
588
|
+
### Should I hand-write JSON Schema instead?
|
|
589
|
+
|
|
590
|
+
No. Keep the contract in TypeScript and comments. Hand-written schema tends
|
|
591
|
+
to drift away from component props, while this package makes the catalog a
|
|
592
|
+
repeatable build artifact.
|
|
593
|
+
|
|
594
|
+
### Does this replace TypeScript type checking?
|
|
595
|
+
|
|
596
|
+
No. TypeDoc conversion is used to read reflection data, not to validate
|
|
597
|
+
your full application. Continue running your normal TypeScript, lint, and
|
|
598
|
+
test commands.
|
|
599
|
+
|
|
600
|
+
## References
|
|
601
|
+
|
|
602
|
+
- [A2UI Catalogs](https://a2ui.org/concepts/catalogs/)
|
|
603
|
+
- [A2UI v0.9 protocol](https://a2ui.org/specification/v0.9-a2ui/)
|
|
604
|
+
- [TypeDoc custom tags](https://typedoc.org/documents/Tags.html)
|
|
605
|
+
- [TypeDoc JSON output](https://typedoc.org/documents/Options.Output.html)
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Copyright 2026 The Lynx Authors. All rights reserved.
|
|
3
|
+
// Licensed under the Apache License Version 2.0 that can be found in the
|
|
4
|
+
// LICENSE file in the root directory of this source tree.
|
|
5
|
+
// eslint-disable-next-line import/no-unresolved -- Generated by the package build.
|
|
6
|
+
import '../dist/cli.js';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
interface CliOptions {
|
|
3
|
+
catalogDirs: string[];
|
|
4
|
+
help: boolean;
|
|
5
|
+
outDir: string;
|
|
6
|
+
sourceInputs: string[];
|
|
7
|
+
typedocJson?: string;
|
|
8
|
+
version: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare function parseCliArgs(args: string[]): CliOptions;
|
|
11
|
+
export declare function runCli(args: string[], cwd?: string): Promise<number>;
|
|
12
|
+
export {};
|