@servicetitan/json-render-react 0.3.1 → 0.3.2-anv-5204-4218c25
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/README.md +334 -0
- package/dist/catalog/core/catalog-prompt.md +10 -1
- package/dist/catalog/core/schema.json +2 -1
- package/dist/catalog/marketing/catalog-prompt.md +10 -1
- package/dist/catalog/marketing/schema.json +1 -0
- package/dist/core/catalog/catalog-def.d.ts +59 -0
- package/dist/core/catalog/guidance-card-column-width.d.ts +11 -0
- package/dist/core/catalog/guidance-card.catalog.d.ts +61 -0
- package/dist/core/catalog/guidance-card.css.d.ts +1 -0
- package/dist/core/catalog/guidance-card.d.ts +8 -0
- package/dist/core/catalog/schemas.d.ts +59 -0
- package/dist/index.js +535 -404
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/README.md
ADDED
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
# @servicetitan/json-render-react
|
|
2
|
+
|
|
3
|
+
Generative UI for ServiceTitan: Zod catalog schemas, React renderers, and LLM artifacts that turn JSON specs into live UI.
|
|
4
|
+
|
|
5
|
+
This package bridges [json-render](https://github.com/json-render/json-render) (spec format and React runtime) with ServiceTitan component libraries ([Anvil2](https://github.com/servicetitan/anvil2), [carto-react-kit](../carto-react-kit/)). Agents emit structured JSON; hosts render it with `SpecRenderer`.
|
|
6
|
+
|
|
7
|
+
> [!NOTE]
|
|
8
|
+
> **New here?** Read this file for architecture and concepts, then [CONTRIBUTING.md](./CONTRIBUTING.md) for workflows. Storybook [Guide](http://localhost:6007/?path=/docs/guide--docs) (`pnpm storybook`) is the interactive reference.
|
|
9
|
+
|
|
10
|
+
## What problem this solves
|
|
11
|
+
|
|
12
|
+
| Layer | Responsibility |
|
|
13
|
+
| --- | --- |
|
|
14
|
+
| **Agent backend** | Receives `catalog-prompt.md` + `schema.json`, emits a `Spec` JSON tree |
|
|
15
|
+
| **This package** | Validates catalog contracts, maps spec types to React, wires actions |
|
|
16
|
+
| **Host app (Atlas)** | Provides `SpecRenderer`, action handlers, theme providers |
|
|
17
|
+
| **End user** | Sees Anvil2 / Carto UI, submits forms, triggers navigation |
|
|
18
|
+
|
|
19
|
+
Without this package, every host would re-implement component schemas, renderers, prompt rules, and action wiring.
|
|
20
|
+
|
|
21
|
+
## Quick start
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
# From monorepo root
|
|
25
|
+
pnpm install
|
|
26
|
+
pnpm build --filter @servicetitan/json-render-react
|
|
27
|
+
pnpm storybook --filter @servicetitan/json-render-react # http://localhost:6007
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
```tsx
|
|
31
|
+
import { AnvilProvider } from "@servicetitan/anvil2";
|
|
32
|
+
import { CartoTheme } from "@servicetitan/carto-react-kit";
|
|
33
|
+
import "@servicetitan/carto-react-kit/styles.css";
|
|
34
|
+
import { getRegistry, SpecRenderer } from "@servicetitan/json-render-react";
|
|
35
|
+
|
|
36
|
+
const { registry, handlers } = getRegistry("chat");
|
|
37
|
+
|
|
38
|
+
<AnvilProvider themeData={{ mode: "light" }}>
|
|
39
|
+
<CartoTheme appearance="light">
|
|
40
|
+
<SpecRenderer
|
|
41
|
+
spec={spec}
|
|
42
|
+
registry={registry}
|
|
43
|
+
handlers={handlers}
|
|
44
|
+
actions={({ setState, getSnapshot }) => ({
|
|
45
|
+
"atlas.submitUserAction": (params) => handleSubmit(params, getSnapshot()),
|
|
46
|
+
"atlas.navigate": (params) => handleNavigate((params as { url: string }).url),
|
|
47
|
+
})}
|
|
48
|
+
/>
|
|
49
|
+
</CartoTheme>
|
|
50
|
+
</AnvilProvider>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
> [!IMPORTANT]
|
|
54
|
+
> Pin `appearance` to `"light"` or `"dark"` (not `"auto"`) and pass the same mode to `AnvilProvider` so Anvil2 and Carto resolve the same `light-dark()` branch.
|
|
55
|
+
|
|
56
|
+
## Architecture
|
|
57
|
+
|
|
58
|
+
### Three-layer model
|
|
59
|
+
|
|
60
|
+
```mermaid
|
|
61
|
+
flowchart TD
|
|
62
|
+
subgraph agent [Agent backend]
|
|
63
|
+
P[catalog-prompt.md]
|
|
64
|
+
S[schema.json]
|
|
65
|
+
LLM[LLM structured output]
|
|
66
|
+
P --> LLM
|
|
67
|
+
S --> LLM
|
|
68
|
+
LLM --> Spec[Spec JSON]
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
subgraph jrr ["@servicetitan/json-render-react"]
|
|
72
|
+
GR[getRegistry surface]
|
|
73
|
+
SR[SpecRenderer]
|
|
74
|
+
REG[Component registry]
|
|
75
|
+
Spec --> SR
|
|
76
|
+
GR --> REG
|
|
77
|
+
REG --> SR
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
subgraph ui [Component libraries]
|
|
81
|
+
A[Anvil2 - core catalog]
|
|
82
|
+
C[carto-react-kit - context panel]
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
SR --> A
|
|
86
|
+
SR --> C
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Two-layer public API
|
|
90
|
+
|
|
91
|
+
| API | Purpose |
|
|
92
|
+
| --- | --- |
|
|
93
|
+
| `getRegistry("chat" \| "context" \| "panel" \| "app")` | Select which catalog components and actions are available on a surface |
|
|
94
|
+
| `SpecRenderer` | Context-agnostic host; pass `spec` + `registry` + `handlers` from `getRegistry` |
|
|
95
|
+
|
|
96
|
+
Default exports (`registry`, `handlers`, `executeAction`) use the **chat** registry for ti-assist / Atlas parity.
|
|
97
|
+
|
|
98
|
+
### Data flow (chat surface)
|
|
99
|
+
|
|
100
|
+
1. Agent receives generated `catalog-prompt.md` and `schema.json` from `pnpm build`.
|
|
101
|
+
2. Agent emits a `Spec` (`root`, `elements`, optional `state`).
|
|
102
|
+
3. Host calls `getRegistry("chat")` and renders with `SpecRenderer`.
|
|
103
|
+
4. `SpecRenderer` enriches the spec (e.g. auto-wires `Button` press → `atlas.submitUserAction`), creates a state store, and mounts json-render's `Renderer`.
|
|
104
|
+
5. User interaction fires catalog actions; host `actions` factory handles `atlas.submitUserAction`, `atlas.navigate`, `atlas.toolCall`.
|
|
105
|
+
6. Backend returns an updated spec via `MessageUpdated` (Atlas).
|
|
106
|
+
|
|
107
|
+
See [Atlas gen-ui docs](https://atlas-docs.st.dev/#/gen-ui-docs) for host integration.
|
|
108
|
+
|
|
109
|
+
### Context panel flow
|
|
110
|
+
|
|
111
|
+
Context specs root at `ContextPanel` and render carto-react-kit components. Use `getRegistry("context")`, `ContextSpecRenderer`, or `SectionedContextRenderer` for streaming multi-section layouts.
|
|
112
|
+
|
|
113
|
+
Validation: `validateContextSpec`, `validateContextSpecDeep`. Rules: `src/context/prompt/rules.md`.
|
|
114
|
+
|
|
115
|
+
## Package layout
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
packages/json-render-react/
|
|
119
|
+
├── README.md ← you are here
|
|
120
|
+
├── CONTRIBUTING.md ← contributor workflows
|
|
121
|
+
├── CLAUDE.md ← agent quick reference (synced to .cursor/rules)
|
|
122
|
+
├── src/
|
|
123
|
+
│ ├── index.ts ← public exports
|
|
124
|
+
│ ├── registry.ts ← getRegistry, surface filtering
|
|
125
|
+
│ ├── scoped-catalog.ts ← team catalog composition API
|
|
126
|
+
│ ├── core/
|
|
127
|
+
│ │ ├── catalog/ ← 20 core components (*.catalog.ts + *.tsx)
|
|
128
|
+
│ │ ├── actions.ts ← atlas.* action catalog
|
|
129
|
+
│ │ └── prompt/rules.md ← LLM layout/form rules (core)
|
|
130
|
+
│ ├── context/
|
|
131
|
+
│ │ ├── catalog/ ← ContextPanel shell + content primitives
|
|
132
|
+
│ │ ├── components/ ← CollapsibleCard, AISummary, error boundary
|
|
133
|
+
│ │ └── prompt/rules.md ← context-specific LLM rules
|
|
134
|
+
│ ├── marketing/catalog/ ← scoped catalog example (prefix `mrk`)
|
|
135
|
+
│ ├── renderers/
|
|
136
|
+
│ │ ├── spec-renderer.tsx ← main host
|
|
137
|
+
│ │ ├── context-spec-renderer.tsx
|
|
138
|
+
│ │ └── sectioned-context-renderer.tsx
|
|
139
|
+
│ ├── storybook/ ← Storybook infra (not published)
|
|
140
|
+
│ └── stories/ ← all Storybook content (CSF + MDX)
|
|
141
|
+
├── scripts/
|
|
142
|
+
│ ├── generate-schema.ts ← dist/catalog/* artifacts
|
|
143
|
+
│ └── generate-catalog-docs.ts
|
|
144
|
+
└── dist/ ← build output (not committed)
|
|
145
|
+
└── catalog/
|
|
146
|
+
├── core/ ← schema.json, catalog-prompt.md
|
|
147
|
+
├── context/
|
|
148
|
+
└── marketing/ ← scoped team artifacts
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Key concepts
|
|
152
|
+
|
|
153
|
+
### Spec
|
|
154
|
+
|
|
155
|
+
JSON document with `root` (element key), `elements` (map of nodes), and optional `state` (reactive values).
|
|
156
|
+
|
|
157
|
+
```json
|
|
158
|
+
{
|
|
159
|
+
"root": "root",
|
|
160
|
+
"state": { "name": "" },
|
|
161
|
+
"elements": {
|
|
162
|
+
"root": { "type": "Card", "props": { "title": "Hello" }, "children": ["field"] },
|
|
163
|
+
"field": { "type": "Input", "props": { "label": "Name", "value": { "$bindState": "/name" } }, "children": [] }
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
| Expression | Purpose |
|
|
169
|
+
| --- | --- |
|
|
170
|
+
| `$bindState` | Two-way binding on interactive props (`value`, `checked`) |
|
|
171
|
+
| `$state` | Read-only state reference |
|
|
172
|
+
| `$item` | Field access inside `repeat` blocks |
|
|
173
|
+
| `$cond` / `$then` / `$else` | Inline conditional prop values |
|
|
174
|
+
| `$computed` | Calls registered functions (`computeTotal` in `SpecRenderer`) |
|
|
175
|
+
| `visible` | Conditional element rendering |
|
|
176
|
+
| `repeat` | List rendering from a state array |
|
|
177
|
+
| `on.press` | Button event handlers (action objects) |
|
|
178
|
+
|
|
179
|
+
Full reference: Storybook Guide, skill [authoring-json-render-specs](../../.claude/skills/authoring-json-render-specs/SKILL.md).
|
|
180
|
+
|
|
181
|
+
### Catalog
|
|
182
|
+
|
|
183
|
+
Per-component Zod schema + metadata for LLMs:
|
|
184
|
+
|
|
185
|
+
```ts
|
|
186
|
+
export const buttonCatalog = {
|
|
187
|
+
props: z.object({ label: z.string(), appearance: z.enum([...]).optional() }),
|
|
188
|
+
slots: [],
|
|
189
|
+
events: ["press"],
|
|
190
|
+
description: "Clickable button. ...",
|
|
191
|
+
};
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Paired with a **renderer** (`ButtonRenderer`) that maps props to Anvil2/Carto components.
|
|
195
|
+
|
|
196
|
+
### CatalogEntry and surfaces
|
|
197
|
+
|
|
198
|
+
```ts
|
|
199
|
+
interface CatalogEntry {
|
|
200
|
+
name: string;
|
|
201
|
+
catalog: ComponentCatalogDef;
|
|
202
|
+
renderer: unknown;
|
|
203
|
+
renderers: RendererContext[]; // "all" | "chat" | "context" | "panel" | "app"
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
`getRegistry(renderer)` filters entries by surface before calling `defineCatalog` + `defineRegistry`.
|
|
208
|
+
|
|
209
|
+
| Surface | Components |
|
|
210
|
+
| --- | --- |
|
|
211
|
+
| `chat` | Core (`renderers: ["all"]`) + team chat components (e.g. Marketing `RevenueCard`) |
|
|
212
|
+
| `context` | Context shell + content primitives + curated core subset |
|
|
213
|
+
| `panel`, `app` | Reserved for future surfaces |
|
|
214
|
+
|
|
215
|
+
### Actions
|
|
216
|
+
|
|
217
|
+
Global action catalog in `src/core/actions.ts`:
|
|
218
|
+
|
|
219
|
+
| Action | Params | Host responsibility |
|
|
220
|
+
| --- | --- | --- |
|
|
221
|
+
| `atlas.submitUserAction` | `actionId?`, `data?` | Submit form snapshot to agent backend |
|
|
222
|
+
| `atlas.navigate` | `url` | Route internally or open external URL |
|
|
223
|
+
| `atlas.toolCall` | `tool`, `args?` | Invoke MCP tool on artifact panel app |
|
|
224
|
+
| `setState` | `statePath`, `value` | Synchronous local state update (json-render built-in) |
|
|
225
|
+
|
|
226
|
+
`Button` elements without explicit `on.press` are auto-wired to `atlas.submitUserAction` using the element key as `actionId`.
|
|
227
|
+
|
|
228
|
+
### Build artifacts
|
|
229
|
+
|
|
230
|
+
`pnpm build` emits (not committed):
|
|
231
|
+
|
|
232
|
+
| Path | Content |
|
|
233
|
+
| --- | --- |
|
|
234
|
+
| `dist/catalog/core/schema.json` | JSON Schema for core chat catalog |
|
|
235
|
+
| `dist/catalog/core/catalog-prompt.md` | LLM prompt (catalog + `rules.md`) |
|
|
236
|
+
| `dist/catalog/context/*` | Context panel artifacts |
|
|
237
|
+
| `dist/catalog/<team>/*` | Per scoped catalog (e.g. `marketing`) |
|
|
238
|
+
|
|
239
|
+
Import: `@servicetitan/json-render-react/catalog/core/schema.json`
|
|
240
|
+
|
|
241
|
+
### UI library split
|
|
242
|
+
|
|
243
|
+
| Subsystem | Component library | Token source |
|
|
244
|
+
| --- | --- | --- |
|
|
245
|
+
| Core catalog (20 components) | Anvil2 + anvil2-ext-charts | Anvil2 theme |
|
|
246
|
+
| Context panel (9 components) | carto-react-kit | `@servicetitan/carto-tokens` via CartoTheme |
|
|
247
|
+
| Marketing example | Anvil2 + Carto tokens for accents | Mixed |
|
|
248
|
+
|
|
249
|
+
## Public exports
|
|
250
|
+
|
|
251
|
+
```ts
|
|
252
|
+
// Rendering
|
|
253
|
+
SpecRenderer, SpecRendererProps
|
|
254
|
+
ContextSpecRenderer, SectionedContextRenderer
|
|
255
|
+
|
|
256
|
+
// Registry
|
|
257
|
+
getRegistry, getContextRegistry, registry, handlers, executeAction, catalog
|
|
258
|
+
|
|
259
|
+
// Context validation
|
|
260
|
+
validateContextSpec, validateContextSpecDeep, postProcessContextSpec, ...
|
|
261
|
+
|
|
262
|
+
// Scoped catalogs (teams)
|
|
263
|
+
createScopedCatalog, mergeCatalogs, composeCatalogComponents
|
|
264
|
+
|
|
265
|
+
// Types
|
|
266
|
+
Spec, Catalog, RendererContext, CatalogEntry, ...
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
## Storybook
|
|
270
|
+
|
|
271
|
+
| Port | Package |
|
|
272
|
+
| --- | --- |
|
|
273
|
+
| 6007 | json-render-react (this package) |
|
|
274
|
+
| 6006 | carto-react-kit |
|
|
275
|
+
|
|
276
|
+
```sh
|
|
277
|
+
pnpm storybook --filter @servicetitan/json-render-react
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
| Sidebar group | Content |
|
|
281
|
+
| --- | --- |
|
|
282
|
+
| Guide | Package narrative, spec format, Atlas integration |
|
|
283
|
+
| Spec Playground | Live JSON editor |
|
|
284
|
+
| Core Catalog | One story file per core component |
|
|
285
|
+
| Scoped Catalogs | Team-specific components |
|
|
286
|
+
| Context | Context panel components |
|
|
287
|
+
| Examples | Composed demos, tool-call wiring |
|
|
288
|
+
|
|
289
|
+
Catalog stories export exactly **Default** (Spec panel) + **StickerSheet** (Chromatic baseline).
|
|
290
|
+
|
|
291
|
+
## Scripts
|
|
292
|
+
|
|
293
|
+
| Command | Purpose |
|
|
294
|
+
| --- | --- |
|
|
295
|
+
| `pnpm build` | Library dist + `dist/catalog/*` artifacts |
|
|
296
|
+
| `pnpm schema:gen` | Regenerate catalog artifacts only |
|
|
297
|
+
| `pnpm docs:gen` | Scaffold MDX for new catalog components |
|
|
298
|
+
| `pnpm storybook` | Dev server on port 6007 |
|
|
299
|
+
| `pnpm test` | Unit tests |
|
|
300
|
+
| `pnpm test-storybook` | Browser tests via Storybook |
|
|
301
|
+
| `pnpm typecheck` / `pnpm lint` | CI checks |
|
|
302
|
+
|
|
303
|
+
## Agent skills
|
|
304
|
+
|
|
305
|
+
Claude/Cursor skills in `.claude/skills/`:
|
|
306
|
+
|
|
307
|
+
| Skill | When to use |
|
|
308
|
+
| --- | --- |
|
|
309
|
+
| [authoring-json-render-specs](../../.claude/skills/authoring-json-render-specs/SKILL.md) | Writing or reviewing JSON specs |
|
|
310
|
+
| [authoring-json-render-catalog-components](../../.claude/skills/authoring-json-render-catalog-components/SKILL.md) | New catalog entries, renderers, actions |
|
|
311
|
+
| [authoring-json-render-scoped-catalogs](../../.claude/skills/authoring-json-render-scoped-catalogs/SKILL.md) | Team-scoped catalogs |
|
|
312
|
+
| [authoring-json-render-context-panel](../../.claude/skills/authoring-json-render-context-panel/SKILL.md) | Context panel specs and components |
|
|
313
|
+
| [authoring-json-render-react-storybook-stories](../../.claude/skills/authoring-json-render-react-storybook-stories/SKILL.md) | Stories, MDX, Spec panel, Chromatic |
|
|
314
|
+
|
|
315
|
+
## External references
|
|
316
|
+
|
|
317
|
+
| Resource | URL |
|
|
318
|
+
| --- | --- |
|
|
319
|
+
| json-render (upstream) | https://github.com/json-render/json-render |
|
|
320
|
+
| Atlas gen-ui integration | https://atlas-docs.st.dev/#/gen-ui-docs |
|
|
321
|
+
| Carto monorepo contributing | [CONTRIBUTING.md](../../CONTRIBUTING.md) |
|
|
322
|
+
| Carto repo scaffolding (Confluence) | https://servicetitan.atlassian.net/wiki/spaces/ADS/pages/4510026867/ANV-4906+-+Carto+Repo+Scaffolding |
|
|
323
|
+
|
|
324
|
+
## Peer dependencies
|
|
325
|
+
|
|
326
|
+
Consumers must install:
|
|
327
|
+
|
|
328
|
+
- `react`, `react-dom` (`>=18 <20`)
|
|
329
|
+
- `@servicetitan/anvil2`, `@servicetitan/anvil2-ext-charts`
|
|
330
|
+
- `@servicetitan/carto-react-kit`
|
|
331
|
+
- `@amcharts/amcharts5` (charts)
|
|
332
|
+
|
|
333
|
+
> [!WARNING]
|
|
334
|
+
> `@json-render/react@0.15` declares `react: ^19.2.3`; this package peers `>=18 <20` for Atlas/ti-assist compatibility. Hosts on React 18 may see upstream peer warnings until they upgrade or add `peerDependencyRules`.
|
|
@@ -46,7 +46,7 @@ For lists where users can add/remove items (todos, carts, etc.), use pushState a
|
|
|
46
46
|
|
|
47
47
|
IMPORTANT: State paths use RFC 6901 JSON Pointer syntax (e.g. "/todos/0/title"). Do NOT use JavaScript-style dot notation (e.g. "/todos.length" is WRONG). To generate unique IDs for new items, use "$id" instead of trying to read array length.
|
|
48
48
|
|
|
49
|
-
AVAILABLE COMPONENTS (
|
|
49
|
+
AVAILABLE COMPONENTS (21):
|
|
50
50
|
|
|
51
51
|
- Text: { content: string, variant?: "headline" | "body" | "eyebrow", size?: "small" | "medium" | "large" | "xlarge", subdued?: boolean } - Display text. variant: headline=bold title, eyebrow=small uppercase label, body=default (default variant). size: small | medium (default) | large | xlarge — applies to headline and body only (ignored for eyebrow). subdued: deemphasized secondary text (body only). Use eyebrow+headline pairs for KPI/stat labels above values.
|
|
52
52
|
- Card: { title?: string, description?: string, background?: "strong" | "stronger", padding?: "0" | "xsmall" | "small" | "medium" | "large" } - White surface that groups a logical section of related content. title: optional headline rendered at the top of the card. description: optional subdued line below the title. Children render below the header and are stacked vertically with consistent spacing — you do not need to wrap them in a Flex. Prefer the built-in title/description over standalone Text children for the heading. background: strong | stronger for nested/elevated surfaces. padding: 0 | xsmall | small | medium (default) | large. Do not nest a Card inside another Card. [accepts children]
|
|
@@ -68,6 +68,7 @@ AVAILABLE COMPONENTS (20):
|
|
|
68
68
|
- Listbox: { label: string, options: Array<{ value: string, label: string }>, value?: string, disabled?: boolean } - Single-select dropdown for choosing one value from a fixed list of known options. options: [{ value, label }] — value is stored in state, label is shown. Bind the selection with $bindState on value; emits a "change" event on selection. Use only when options are predefined; for free-text user input use Input, and for 2–7 visible mutually-exclusive choices prefer RadioGroup. disabled: true prevents selection. [events: change]
|
|
69
69
|
- RadioGroup: { label: string, options: Array<{ value: string, label: string }>, value?: string, disabled?: boolean } - Group of radio buttons for picking one option from 2–7 visible mutually-exclusive choices. options: [{ value, label }]. Bind the selection with $bindState on value; emits a "change" event on selection. For longer option lists use Listbox. disabled: true prevents selection. [events: change]
|
|
70
70
|
- Switch: { label: string, checked?: boolean, disabled?: boolean } - Toggle switch for a single binary on/off setting with immediate effect (no form submit). Prefer over Checkbox for enabling/disabling features. Bind state with $bindState on checked; emits a "change" event when toggled. disabled: true prevents toggling. [events: change]
|
|
71
|
+
- GuidanceCard: { state?: "default" | "accepted" | "rejected" | "skipped", referenceLabel: string, referenceHref?: string, changeSections: Array<{ type: undefined, changes: Array<{ id: string, label: string, from?: string, to?: string, reason?: string }> } | { type: undefined, label: string, changeTables: Array<{ label: string, columns: Array<{ key: string, header: string, minWidth?: "compact" | "standard" | "wide" }>, data: Array<unknown>, reason?: string }> }>, appliedChangeIds?: Array<string>, defaultExpanded?: boolean } - Suggested-change review card for Atlas agent chat. Use in the default state while the user can accept, edit, or dismiss AI-proposed updates to an estimate/invoice. state: default (selectable diffs + actions) | accepted (collapsible accepted summary) | rejected | skipped (collapsible read-only summaries). Bind state and appliedChangeIds with $bindState so apply/reject can update lifecycle state locally. Checkbox selection is managed internally and defaults to all single-change and table-row ids selected. changeSections[] defines ordered body content: type single (changes[] with label/from/to/reason) or type table (label + changeTables[] with editable labels, columns[{ key, header, minWidth? }], data, optional reason). Column minWidth presets: compact (codes/SKUs/quantities) | standard (names/dates) | wide (descriptions/diffs) — omit when flexible. Table cell rendering is defined per cell via string (plain text), { type: text | diff | addition, ... }, or legacy { from, to } diff shorthand. appliedChangeIds filters accepted-state content. referenceHref opens the linked record in a new tab. Emits apply, edit, and dismiss. [events: apply, edit, dismiss]
|
|
71
72
|
|
|
72
73
|
AVAILABLE ACTIONS:
|
|
73
74
|
|
|
@@ -295,3 +296,11 @@ LINECHART
|
|
|
295
296
|
- series optionally names which keys to plot (inferred from the data keys if omitted, max 6). theme: "monochrome" (1–2 series) | "categorical" (3–6 series). showLegend (default true for 2+ series); showDots toggles point markers; unit sets the tooltip suffix.
|
|
296
297
|
- Do NOT wrap in Card or Flex — use as the root element.
|
|
297
298
|
|
|
299
|
+
GUIDANCECARD
|
|
300
|
+
- Use when Atlas proposes suggested changes to an estimate or invoice inline in chat. GuidanceCard is a standalone root — do NOT wrap it in Card or Flex.
|
|
301
|
+
- state: default (selectable diffs + apply/edit/dismiss actions) | accepted (collapsible accepted summary) | rejected | skipped (collapsible read-only summaries). Default is default.
|
|
302
|
+
- Bind `state` and `appliedChangeIds` with $bindState (e.g. `/cardState`, `/appliedChangeIds`) so Storybook and local previews can flip lifecycle state on apply/reject. On apply, chain setState to `"accepted"` and set `/appliedChangeIds` to the ids being applied before atlas.submitUserAction.
|
|
303
|
+
- changeSections[] defines ordered body content: type single (changes[] with id, label, optional from/to/reason) or type table (label + changeTables[] with editable labels, columns, and data rows with id). Table cell rendering is defined per cell: plain string, `{ type: "text" | "diff" | "addition", ... }`, or legacy `{ from, to }` diff shorthand — not on the column.
|
|
304
|
+
- Table column `minWidth` presets (optional): **compact** — codes, SKUs, quantities, unit prices; **standard** — names, categories, dates, single-line labels; **wide** — descriptions, notes, scope text, or any column with diff/addition cells. Omit when the column can flex.
|
|
305
|
+
- Emits apply, edit, and dismiss. Wire actions via on.apply/on.edit/on.dismiss; use atlas.submitUserAction with descriptive actionIds.
|
|
306
|
+
|
|
@@ -46,7 +46,7 @@ For lists where users can add/remove items (todos, carts, etc.), use pushState a
|
|
|
46
46
|
|
|
47
47
|
IMPORTANT: State paths use RFC 6901 JSON Pointer syntax (e.g. "/todos/0/title"). Do NOT use JavaScript-style dot notation (e.g. "/todos.length" is WRONG). To generate unique IDs for new items, use "$id" instead of trying to read array length.
|
|
48
48
|
|
|
49
|
-
AVAILABLE COMPONENTS (
|
|
49
|
+
AVAILABLE COMPONENTS (22):
|
|
50
50
|
|
|
51
51
|
- Text: { content: string, variant?: "headline" | "body" | "eyebrow", size?: "small" | "medium" | "large" | "xlarge", subdued?: boolean } - Display text. variant: headline=bold title, eyebrow=small uppercase label, body=default (default variant). size: small | medium (default) | large | xlarge — applies to headline and body only (ignored for eyebrow). subdued: deemphasized secondary text (body only). Use eyebrow+headline pairs for KPI/stat labels above values.
|
|
52
52
|
- Card: { title?: string, description?: string, background?: "strong" | "stronger", padding?: "0" | "xsmall" | "small" | "medium" | "large" } - White surface that groups a logical section of related content. title: optional headline rendered at the top of the card. description: optional subdued line below the title. Children render below the header and are stacked vertically with consistent spacing — you do not need to wrap them in a Flex. Prefer the built-in title/description over standalone Text children for the heading. background: strong | stronger for nested/elevated surfaces. padding: 0 | xsmall | small | medium (default) | large. Do not nest a Card inside another Card. [accepts children]
|
|
@@ -68,6 +68,7 @@ AVAILABLE COMPONENTS (21):
|
|
|
68
68
|
- Listbox: { label: string, options: Array<{ value: string, label: string }>, value?: string, disabled?: boolean } - Single-select dropdown for choosing one value from a fixed list of known options. options: [{ value, label }] — value is stored in state, label is shown. Bind the selection with $bindState on value; emits a "change" event on selection. Use only when options are predefined; for free-text user input use Input, and for 2–7 visible mutually-exclusive choices prefer RadioGroup. disabled: true prevents selection. [events: change]
|
|
69
69
|
- RadioGroup: { label: string, options: Array<{ value: string, label: string }>, value?: string, disabled?: boolean } - Group of radio buttons for picking one option from 2–7 visible mutually-exclusive choices. options: [{ value, label }]. Bind the selection with $bindState on value; emits a "change" event on selection. For longer option lists use Listbox. disabled: true prevents selection. [events: change]
|
|
70
70
|
- Switch: { label: string, checked?: boolean, disabled?: boolean } - Toggle switch for a single binary on/off setting with immediate effect (no form submit). Prefer over Checkbox for enabling/disabling features. Bind state with $bindState on checked; emits a "change" event when toggled. disabled: true prevents toggling. [events: change]
|
|
71
|
+
- GuidanceCard: { state?: "default" | "accepted" | "rejected" | "skipped", referenceLabel: string, referenceHref?: string, changeSections: Array<{ type: undefined, changes: Array<{ id: string, label: string, from?: string, to?: string, reason?: string }> } | { type: undefined, label: string, changeTables: Array<{ label: string, columns: Array<{ key: string, header: string, minWidth?: "compact" | "standard" | "wide" }>, data: Array<unknown>, reason?: string }> }>, appliedChangeIds?: Array<string>, defaultExpanded?: boolean } - Suggested-change review card for Atlas agent chat. Use in the default state while the user can accept, edit, or dismiss AI-proposed updates to an estimate/invoice. state: default (selectable diffs + actions) | accepted (collapsible accepted summary) | rejected | skipped (collapsible read-only summaries). Bind state and appliedChangeIds with $bindState so apply/reject can update lifecycle state locally. Checkbox selection is managed internally and defaults to all single-change and table-row ids selected. changeSections[] defines ordered body content: type single (changes[] with label/from/to/reason) or type table (label + changeTables[] with editable labels, columns[{ key, header, minWidth? }], data, optional reason). Column minWidth presets: compact (codes/SKUs/quantities) | standard (names/dates) | wide (descriptions/diffs) — omit when flexible. Table cell rendering is defined per cell via string (plain text), { type: text | diff | addition, ... }, or legacy { from, to } diff shorthand. appliedChangeIds filters accepted-state content. referenceHref opens the linked record in a new tab. Emits apply, edit, and dismiss. [events: apply, edit, dismiss]
|
|
71
72
|
- RevenueCard: { title: string, value: string, trend?: "up" | "down" | "flat", delta?: string } - KPI metric card. trend: up=green↑ down=red↓ flat=grey→. delta e.g. "+12% vs last month". Leaf node — no children.
|
|
72
73
|
|
|
73
74
|
AVAILABLE ACTIONS:
|
|
@@ -296,3 +297,11 @@ LINECHART
|
|
|
296
297
|
- series optionally names which keys to plot (inferred from the data keys if omitted, max 6). theme: "monochrome" (1–2 series) | "categorical" (3–6 series). showLegend (default true for 2+ series); showDots toggles point markers; unit sets the tooltip suffix.
|
|
297
298
|
- Do NOT wrap in Card or Flex — use as the root element.
|
|
298
299
|
|
|
300
|
+
GUIDANCECARD
|
|
301
|
+
- Use when Atlas proposes suggested changes to an estimate or invoice inline in chat. GuidanceCard is a standalone root — do NOT wrap it in Card or Flex.
|
|
302
|
+
- state: default (selectable diffs + apply/edit/dismiss actions) | accepted (collapsible accepted summary) | rejected | skipped (collapsible read-only summaries). Default is default.
|
|
303
|
+
- Bind `state` and `appliedChangeIds` with $bindState (e.g. `/cardState`, `/appliedChangeIds`) so Storybook and local previews can flip lifecycle state on apply/reject. On apply, chain setState to `"accepted"` and set `/appliedChangeIds` to the ids being applied before atlas.submitUserAction.
|
|
304
|
+
- changeSections[] defines ordered body content: type single (changes[] with id, label, optional from/to/reason) or type table (label + changeTables[] with editable labels, columns, and data rows with id). Table cell rendering is defined per cell: plain string, `{ type: "text" | "diff" | "addition", ... }`, or legacy `{ from, to }` diff shorthand — not on the column.
|
|
305
|
+
- Table column `minWidth` presets (optional): **compact** — codes, SKUs, quantities, unit prices; **standard** — names, categories, dates, single-line labels; **wide** — descriptions, notes, scope text, or any column with diff/addition cells. Omit when the column can flex.
|
|
306
|
+
- Emits apply, edit, and dismiss. Wire actions via on.apply/on.edit/on.dismiss; use atlas.submitUserAction with descriptive actionIds.
|
|
307
|
+
|
|
@@ -402,6 +402,65 @@ export declare const catalog: import('@json-render/core').Catalog<{
|
|
|
402
402
|
events: string[];
|
|
403
403
|
description: string;
|
|
404
404
|
};
|
|
405
|
+
GuidanceCard: {
|
|
406
|
+
props: import('zod').ZodObject<{
|
|
407
|
+
state: import('zod').ZodOptional<import('zod').ZodEnum<{
|
|
408
|
+
default: "default";
|
|
409
|
+
accepted: "accepted";
|
|
410
|
+
rejected: "rejected";
|
|
411
|
+
skipped: "skipped";
|
|
412
|
+
}>>;
|
|
413
|
+
referenceLabel: import('zod').ZodString;
|
|
414
|
+
referenceHref: import('zod').ZodOptional<import('zod').ZodString>;
|
|
415
|
+
changeSections: import('zod').ZodArray<import('zod').ZodDiscriminatedUnion<[import('zod').ZodObject<{
|
|
416
|
+
type: import('zod').ZodLiteral<"single">;
|
|
417
|
+
changes: import('zod').ZodArray<import('zod').ZodObject<{
|
|
418
|
+
id: import('zod').ZodString;
|
|
419
|
+
label: import('zod').ZodString;
|
|
420
|
+
from: import('zod').ZodOptional<import('zod').ZodNullable<import('zod').ZodString>>;
|
|
421
|
+
to: import('zod').ZodOptional<import('zod').ZodNullable<import('zod').ZodString>>;
|
|
422
|
+
reason: import('zod').ZodOptional<import('zod').ZodString>;
|
|
423
|
+
}, import('zod/v4/core').$strip>>;
|
|
424
|
+
}, import('zod/v4/core').$strip>, import('zod').ZodObject<{
|
|
425
|
+
type: import('zod').ZodLiteral<"table">;
|
|
426
|
+
label: import('zod').ZodString;
|
|
427
|
+
changeTables: import('zod').ZodArray<import('zod').ZodObject<{
|
|
428
|
+
label: import('zod').ZodString;
|
|
429
|
+
columns: import('zod').ZodArray<import('zod').ZodObject<{
|
|
430
|
+
key: import('zod').ZodString;
|
|
431
|
+
header: import('zod').ZodString;
|
|
432
|
+
minWidth: import('zod').ZodOptional<import('zod').ZodEnum<{
|
|
433
|
+
compact: "compact";
|
|
434
|
+
standard: "standard";
|
|
435
|
+
wide: "wide";
|
|
436
|
+
}>>;
|
|
437
|
+
}, import('zod/v4/core').$strip>>;
|
|
438
|
+
data: import('zod').ZodArray<import('zod').ZodIntersection<import('zod').ZodRecord<import('zod').ZodString, import('zod').ZodUnion<readonly [import('zod').ZodString, import('zod').ZodDiscriminatedUnion<[import('zod').ZodObject<{
|
|
439
|
+
type: import('zod').ZodLiteral<"text">;
|
|
440
|
+
value: import('zod').ZodString;
|
|
441
|
+
}, import('zod/v4/core').$strip>, import('zod').ZodObject<{
|
|
442
|
+
type: import('zod').ZodLiteral<"diff">;
|
|
443
|
+
from: import('zod').ZodOptional<import('zod').ZodNullable<import('zod').ZodString>>;
|
|
444
|
+
to: import('zod').ZodOptional<import('zod').ZodNullable<import('zod').ZodString>>;
|
|
445
|
+
}, import('zod/v4/core').$strip>, import('zod').ZodObject<{
|
|
446
|
+
type: import('zod').ZodLiteral<"addition">;
|
|
447
|
+
value: import('zod').ZodString;
|
|
448
|
+
}, import('zod/v4/core').$strip>], "type">, import('zod').ZodObject<{
|
|
449
|
+
from: import('zod').ZodOptional<import('zod').ZodNullable<import('zod').ZodString>>;
|
|
450
|
+
to: import('zod').ZodOptional<import('zod').ZodNullable<import('zod').ZodString>>;
|
|
451
|
+
}, import('zod/v4/core').$strip>]>>, import('zod').ZodObject<{
|
|
452
|
+
id: import('zod').ZodString;
|
|
453
|
+
}, import('zod/v4/core').$strip>>>;
|
|
454
|
+
reason: import('zod').ZodOptional<import('zod').ZodString>;
|
|
455
|
+
}, import('zod/v4/core').$strip>>;
|
|
456
|
+
}, import('zod/v4/core').$strip>], "type">>;
|
|
457
|
+
appliedChangeIds: import('zod').ZodOptional<import('zod').ZodArray<import('zod').ZodString>>;
|
|
458
|
+
defaultExpanded: import('zod').ZodOptional<import('zod').ZodBoolean>;
|
|
459
|
+
}, import('zod/v4/core').$strip>;
|
|
460
|
+
slots: never[];
|
|
461
|
+
events: string[];
|
|
462
|
+
description: string;
|
|
463
|
+
};
|
|
405
464
|
};
|
|
406
465
|
actions: {
|
|
407
466
|
"atlas.submitUserAction": {
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const GUIDANCE_CARD_COLUMN_WIDTHS: {
|
|
2
|
+
/** Short codes, SKUs, quantities, unit prices, status values. */
|
|
3
|
+
readonly compact: 120;
|
|
4
|
+
/** Names, categories, dates, single-line labels. */
|
|
5
|
+
readonly standard: 180;
|
|
6
|
+
/** Descriptions, notes, scope text, diff/addition cells. */
|
|
7
|
+
readonly wide: 280;
|
|
8
|
+
};
|
|
9
|
+
export type GuidanceCardColumnWidth = keyof typeof GUIDANCE_CARD_COLUMN_WIDTHS;
|
|
10
|
+
export declare function resolveGuidanceCardColumnMinWidth(width: GuidanceCardColumnWidth): number;
|
|
11
|
+
export declare function resolveGuidanceCardColumnMinWidth(width: GuidanceCardColumnWidth | undefined): number | undefined;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const guidanceCardCatalog: {
|
|
3
|
+
props: z.ZodObject<{
|
|
4
|
+
state: z.ZodOptional<z.ZodEnum<{
|
|
5
|
+
default: "default";
|
|
6
|
+
accepted: "accepted";
|
|
7
|
+
rejected: "rejected";
|
|
8
|
+
skipped: "skipped";
|
|
9
|
+
}>>;
|
|
10
|
+
referenceLabel: z.ZodString;
|
|
11
|
+
referenceHref: z.ZodOptional<z.ZodString>;
|
|
12
|
+
changeSections: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
13
|
+
type: z.ZodLiteral<"single">;
|
|
14
|
+
changes: z.ZodArray<z.ZodObject<{
|
|
15
|
+
id: z.ZodString;
|
|
16
|
+
label: z.ZodString;
|
|
17
|
+
from: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
18
|
+
to: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
19
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
20
|
+
}, z.core.$strip>>;
|
|
21
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
22
|
+
type: z.ZodLiteral<"table">;
|
|
23
|
+
label: z.ZodString;
|
|
24
|
+
changeTables: z.ZodArray<z.ZodObject<{
|
|
25
|
+
label: z.ZodString;
|
|
26
|
+
columns: z.ZodArray<z.ZodObject<{
|
|
27
|
+
key: z.ZodString;
|
|
28
|
+
header: z.ZodString;
|
|
29
|
+
minWidth: z.ZodOptional<z.ZodEnum<{
|
|
30
|
+
compact: "compact";
|
|
31
|
+
standard: "standard";
|
|
32
|
+
wide: "wide";
|
|
33
|
+
}>>;
|
|
34
|
+
}, z.core.$strip>>;
|
|
35
|
+
data: z.ZodArray<z.ZodIntersection<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
36
|
+
type: z.ZodLiteral<"text">;
|
|
37
|
+
value: z.ZodString;
|
|
38
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
39
|
+
type: z.ZodLiteral<"diff">;
|
|
40
|
+
from: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
41
|
+
to: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
42
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
43
|
+
type: z.ZodLiteral<"addition">;
|
|
44
|
+
value: z.ZodString;
|
|
45
|
+
}, z.core.$strip>], "type">, z.ZodObject<{
|
|
46
|
+
from: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
47
|
+
to: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
48
|
+
}, z.core.$strip>]>>, z.ZodObject<{
|
|
49
|
+
id: z.ZodString;
|
|
50
|
+
}, z.core.$strip>>>;
|
|
51
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
52
|
+
}, z.core.$strip>>;
|
|
53
|
+
}, z.core.$strip>], "type">>;
|
|
54
|
+
appliedChangeIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
55
|
+
defaultExpanded: z.ZodOptional<z.ZodBoolean>;
|
|
56
|
+
}, z.core.$strip>;
|
|
57
|
+
slots: never[];
|
|
58
|
+
events: string[];
|
|
59
|
+
description: string;
|
|
60
|
+
};
|
|
61
|
+
export type GuidanceCardCatalogProps = z.infer<typeof guidanceCardCatalog.props>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const guidanceLineItemsTableWrap: string;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { guidanceCardCatalog } from './guidance-card.catalog';
|
|
3
|
+
export { guidanceCardCatalog };
|
|
4
|
+
export declare const GuidanceCardRenderer: ({ props, emit, bindings, }: {
|
|
5
|
+
props: z.infer<typeof guidanceCardCatalog.props>;
|
|
6
|
+
emit: (event: string) => void;
|
|
7
|
+
bindings?: Record<string, string>;
|
|
8
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -377,4 +377,63 @@ export declare const baseComponents: {
|
|
|
377
377
|
events: string[];
|
|
378
378
|
description: string;
|
|
379
379
|
};
|
|
380
|
+
GuidanceCard: {
|
|
381
|
+
props: import('zod').ZodObject<{
|
|
382
|
+
state: import('zod').ZodOptional<import('zod').ZodEnum<{
|
|
383
|
+
default: "default";
|
|
384
|
+
accepted: "accepted";
|
|
385
|
+
rejected: "rejected";
|
|
386
|
+
skipped: "skipped";
|
|
387
|
+
}>>;
|
|
388
|
+
referenceLabel: import('zod').ZodString;
|
|
389
|
+
referenceHref: import('zod').ZodOptional<import('zod').ZodString>;
|
|
390
|
+
changeSections: import('zod').ZodArray<import('zod').ZodDiscriminatedUnion<[import('zod').ZodObject<{
|
|
391
|
+
type: import('zod').ZodLiteral<"single">;
|
|
392
|
+
changes: import('zod').ZodArray<import('zod').ZodObject<{
|
|
393
|
+
id: import('zod').ZodString;
|
|
394
|
+
label: import('zod').ZodString;
|
|
395
|
+
from: import('zod').ZodOptional<import('zod').ZodNullable<import('zod').ZodString>>;
|
|
396
|
+
to: import('zod').ZodOptional<import('zod').ZodNullable<import('zod').ZodString>>;
|
|
397
|
+
reason: import('zod').ZodOptional<import('zod').ZodString>;
|
|
398
|
+
}, import('zod/v4/core').$strip>>;
|
|
399
|
+
}, import('zod/v4/core').$strip>, import('zod').ZodObject<{
|
|
400
|
+
type: import('zod').ZodLiteral<"table">;
|
|
401
|
+
label: import('zod').ZodString;
|
|
402
|
+
changeTables: import('zod').ZodArray<import('zod').ZodObject<{
|
|
403
|
+
label: import('zod').ZodString;
|
|
404
|
+
columns: import('zod').ZodArray<import('zod').ZodObject<{
|
|
405
|
+
key: import('zod').ZodString;
|
|
406
|
+
header: import('zod').ZodString;
|
|
407
|
+
minWidth: import('zod').ZodOptional<import('zod').ZodEnum<{
|
|
408
|
+
compact: "compact";
|
|
409
|
+
standard: "standard";
|
|
410
|
+
wide: "wide";
|
|
411
|
+
}>>;
|
|
412
|
+
}, import('zod/v4/core').$strip>>;
|
|
413
|
+
data: import('zod').ZodArray<import('zod').ZodIntersection<import('zod').ZodRecord<import('zod').ZodString, import('zod').ZodUnion<readonly [import('zod').ZodString, import('zod').ZodDiscriminatedUnion<[import('zod').ZodObject<{
|
|
414
|
+
type: import('zod').ZodLiteral<"text">;
|
|
415
|
+
value: import('zod').ZodString;
|
|
416
|
+
}, import('zod/v4/core').$strip>, import('zod').ZodObject<{
|
|
417
|
+
type: import('zod').ZodLiteral<"diff">;
|
|
418
|
+
from: import('zod').ZodOptional<import('zod').ZodNullable<import('zod').ZodString>>;
|
|
419
|
+
to: import('zod').ZodOptional<import('zod').ZodNullable<import('zod').ZodString>>;
|
|
420
|
+
}, import('zod/v4/core').$strip>, import('zod').ZodObject<{
|
|
421
|
+
type: import('zod').ZodLiteral<"addition">;
|
|
422
|
+
value: import('zod').ZodString;
|
|
423
|
+
}, import('zod/v4/core').$strip>], "type">, import('zod').ZodObject<{
|
|
424
|
+
from: import('zod').ZodOptional<import('zod').ZodNullable<import('zod').ZodString>>;
|
|
425
|
+
to: import('zod').ZodOptional<import('zod').ZodNullable<import('zod').ZodString>>;
|
|
426
|
+
}, import('zod/v4/core').$strip>]>>, import('zod').ZodObject<{
|
|
427
|
+
id: import('zod').ZodString;
|
|
428
|
+
}, import('zod/v4/core').$strip>>>;
|
|
429
|
+
reason: import('zod').ZodOptional<import('zod').ZodString>;
|
|
430
|
+
}, import('zod/v4/core').$strip>>;
|
|
431
|
+
}, import('zod/v4/core').$strip>], "type">>;
|
|
432
|
+
appliedChangeIds: import('zod').ZodOptional<import('zod').ZodArray<import('zod').ZodString>>;
|
|
433
|
+
defaultExpanded: import('zod').ZodOptional<import('zod').ZodBoolean>;
|
|
434
|
+
}, import('zod/v4/core').$strip>;
|
|
435
|
+
slots: never[];
|
|
436
|
+
events: string[];
|
|
437
|
+
description: string;
|
|
438
|
+
};
|
|
380
439
|
};
|