@ggui-ai/preview-a2ui 0.1.0-rc.1

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.
@@ -0,0 +1,177 @@
1
+ /**
2
+ * A2UI component shapes for ggui's V1 provisional subset.
3
+ *
4
+ * Each component has:
5
+ * - `id`: stable string identifier. Replace-by-id is the state model;
6
+ * re-emitting a component with the same id replaces it.
7
+ * - `component`: discriminator naming the catalog type.
8
+ * - Type-specific fields per the A2UI Basic Catalog.
9
+ *
10
+ * Schema discipline:
11
+ * - Unknown component names reject (discriminated union).
12
+ * - Unknown fields on a known component are stripped silently
13
+ * (Zod default). Tolerant because A2UI Basic Catalog evolves
14
+ * upstream and Haiku may emit extra hints we simply don't need.
15
+ * - Children references are plain strings — A2UI's "flat adjacency
16
+ * list" model. We don't enforce reference integrity at parse time;
17
+ * that's a renderer concern.
18
+ */
19
+ import { z } from 'zod';
20
+ /** Shared base: every component carries a stable string id. */
21
+ const ComponentBase = z.object({
22
+ id: z.string().min(1),
23
+ });
24
+ /**
25
+ * Stable-id string reference to another component.
26
+ * Narrow alias so consumers can spot refs in the schema.
27
+ */
28
+ const ComponentRef = z.string().min(1);
29
+ /** Shared layout hints accepted by container components. */
30
+ const Align = z.enum(['start', 'center', 'end', 'stretch']);
31
+ const Justify = z.enum([
32
+ 'start',
33
+ 'center',
34
+ 'end',
35
+ 'between',
36
+ 'around',
37
+ 'evenly',
38
+ ]);
39
+ /**
40
+ * Horizontal container. Children are referenced by id, in order.
41
+ * Non-interactive in V1 — a provisional Row visually mirrors the real
42
+ * final layout without wiring interaction.
43
+ */
44
+ const RowComponent = ComponentBase.extend({
45
+ component: z.literal('Row'),
46
+ children: z.array(ComponentRef).optional(),
47
+ gap: z.string().optional(),
48
+ align: Align.optional(),
49
+ justify: Justify.optional(),
50
+ });
51
+ /** Vertical container. Same shape as Row, different axis. */
52
+ const ColumnComponent = ComponentBase.extend({
53
+ component: z.literal('Column'),
54
+ children: z.array(ComponentRef).optional(),
55
+ gap: z.string().optional(),
56
+ align: Align.optional(),
57
+ justify: Justify.optional(),
58
+ });
59
+ /**
60
+ * Card — single-child container with surface treatment. A2UI's
61
+ * canonical example uses a singular `child` key (not `children`)
62
+ * for Card; we honor that shape.
63
+ */
64
+ const CardComponent = ComponentBase.extend({
65
+ component: z.literal('Card'),
66
+ child: ComponentRef.optional(),
67
+ });
68
+ /** Generic ordered list of components referenced by id. */
69
+ const ListComponent = ComponentBase.extend({
70
+ component: z.literal('List'),
71
+ children: z.array(ComponentRef).optional(),
72
+ });
73
+ /** Visual separator. No children, no payload. */
74
+ const DividerComponent = ComponentBase.extend({
75
+ component: z.literal('Divider'),
76
+ orientation: z.enum(['horizontal', 'vertical']).optional(),
77
+ });
78
+ /**
79
+ * Text block. A2UI supports Markdown inside `text` and uses `variant`
80
+ * to carry semantic level (`h1`..`h6`, `body`, `caption`, `label`).
81
+ * We accept any variant string since Haiku may produce variants we
82
+ * hadn't anticipated — unknown variants degrade to default body text
83
+ * in the renderer, not a parse failure.
84
+ */
85
+ const TextComponent = ComponentBase.extend({
86
+ component: z.literal('Text'),
87
+ text: z.string(),
88
+ variant: z.string().optional(),
89
+ });
90
+ /** Image. `alt` is recommended; not required for non-interactive preview. */
91
+ const ImageComponent = ComponentBase.extend({
92
+ component: z.literal('Image'),
93
+ src: z.string().min(1),
94
+ alt: z.string().optional(),
95
+ });
96
+ /**
97
+ * Icon. `name` targets the upstream icon set (Material / Lucide
98
+ * family); the renderer maps it to its own icon registry.
99
+ */
100
+ const IconComponent = ComponentBase.extend({
101
+ component: z.literal('Icon'),
102
+ name: z.string().min(1),
103
+ });
104
+ /**
105
+ * Button shell — always disabled/non-interactive in V1. The `label`
106
+ * is rendered; `action` (if any A2UI emits) is intentionally dropped
107
+ * at the renderer since we don't process interactions on the
108
+ * provisional surface.
109
+ */
110
+ const ButtonComponent = ComponentBase.extend({
111
+ component: z.literal('Button'),
112
+ label: z.string(),
113
+ });
114
+ /** Text input shell. Non-interactive in V1. */
115
+ const TextFieldComponent = ComponentBase.extend({
116
+ component: z.literal('TextField'),
117
+ label: z.string().optional(),
118
+ placeholder: z.string().optional(),
119
+ value: z.string().optional(),
120
+ });
121
+ /** Checkbox shell. Non-interactive in V1. */
122
+ const CheckBoxComponent = ComponentBase.extend({
123
+ component: z.literal('CheckBox'),
124
+ label: z.string().optional(),
125
+ checked: z.boolean().optional(),
126
+ });
127
+ /**
128
+ * Single-choice picker shell. Options are tuples of label + value.
129
+ * Non-interactive in V1 — rendered as a disabled select affordance.
130
+ */
131
+ const ChoicePickerOption = z.object({
132
+ label: z.string(),
133
+ value: z.string(),
134
+ });
135
+ const ChoicePickerComponent = ComponentBase.extend({
136
+ component: z.literal('ChoicePicker'),
137
+ label: z.string().optional(),
138
+ options: z.array(ChoicePickerOption).optional(),
139
+ value: z.string().optional(),
140
+ });
141
+ /**
142
+ * Component schema — discriminated union over `component`. Unknown
143
+ * discriminator values reject at parse time. This is the catalog
144
+ * gate.
145
+ */
146
+ export const ComponentSchema = z.discriminatedUnion('component', [
147
+ RowComponent,
148
+ ColumnComponent,
149
+ CardComponent,
150
+ ListComponent,
151
+ DividerComponent,
152
+ TextComponent,
153
+ ImageComponent,
154
+ IconComponent,
155
+ ButtonComponent,
156
+ TextFieldComponent,
157
+ CheckBoxComponent,
158
+ ChoicePickerComponent,
159
+ ]);
160
+ /**
161
+ * Safe-parse a single component. Returns a discriminated result so
162
+ * callers don't have to choose between throwing and inspecting
163
+ * `ZodError`. Kept narrow on purpose — we don't re-export Zod's
164
+ * internals.
165
+ */
166
+ export function parseComponent(input) {
167
+ const result = ComponentSchema.safeParse(input);
168
+ if (result.success)
169
+ return { ok: true, value: result.data };
170
+ return {
171
+ ok: false,
172
+ issues: result.error.issues.map((issue) => ({
173
+ path: issue.path,
174
+ message: issue.message,
175
+ })),
176
+ };
177
+ }
@@ -0,0 +1,94 @@
1
+ /**
2
+ * JSON-safe payload shape. Mirrors `@ggui-ai/protocol.JsonValue`
3
+ * structurally (mutable arrays, optional-undefined index entries)
4
+ * without importing it — keeps this package's zero cross-package
5
+ * dep boundary intact. The producer's A2UI frames are plain
6
+ * objects with string/number/boolean/null leaves, so every
7
+ * concrete emission satisfies this shape AND assigns into the
8
+ * orchestrator's `JsonValue`-typed `emit` sink.
9
+ */
10
+ interface JsonPayloadObject {
11
+ [key: string]: JsonPayload | undefined;
12
+ }
13
+ type JsonPayload = string | number | boolean | null | JsonPayload[] | JsonPayloadObject;
14
+ /**
15
+ * Minimum fields the producer reads from the orchestrator's context.
16
+ * Structurally compatible with `ProvisionalPreviewContext` so callers
17
+ * wrap with a one-line `{run: (ctx) => produceDeterministicPreview(ctx)}`.
18
+ */
19
+ export interface DeterministicPreviewContext {
20
+ /**
21
+ * A2UI surface id. Defaults to `ctx.stackItemId` when
22
+ * {@link DeterministicPreviewOptions.surfaceId} is absent.
23
+ */
24
+ readonly stackItemId: string;
25
+ /**
26
+ * Push story. `intent` is the primary signal the producer reads;
27
+ * additional fields are accepted but ignored.
28
+ */
29
+ readonly story: {
30
+ readonly intent: string;
31
+ } & Record<string, unknown>;
32
+ /**
33
+ * Emit sink from the orchestrator. Declared over {@link JsonPayload}
34
+ * so callers whose `emit` narrows to `@ggui-ai/protocol.JsonValue`
35
+ * (the handler's `ProvisionalPreviewEmit` shape) assign in without
36
+ * a cast — `JsonPayload` is the same value-space. Return value is
37
+ * the wrapped `{seq?}`; the producer ignores it.
38
+ */
39
+ readonly emit: (payload: JsonPayload) => Promise<unknown>;
40
+ /**
41
+ * Cancellation signal from the orchestrator. Checked between
42
+ * frames; on aborted the producer returns without further emits.
43
+ */
44
+ readonly signal: AbortSignal;
45
+ }
46
+ export interface DeterministicPreviewOptions {
47
+ /**
48
+ * Override the surface id. Defaults to `ctx.stackItemId` — keeping the
49
+ * surface id aligned with the stackItemId makes the registry's
50
+ * stackItemId-keyed cancellation reach the right client surface when
51
+ * the renderer buffers on `createSurface.surfaceId`.
52
+ */
53
+ readonly surfaceId?: string;
54
+ /**
55
+ * Override the catalog id referenced in `createSurface`. Defaults
56
+ * to `ggui.preview.v1` — the published manifest this package's
57
+ * subset targets. Only override if the caller is pointing at a
58
+ * different deployed catalog.
59
+ */
60
+ readonly catalogId?: string;
61
+ }
62
+ /**
63
+ * Produce a provisional preview for the supplied story. Emits 3
64
+ * frames on the happy path; returns early on cancellation.
65
+ *
66
+ * **No `deleteSurface` on happy path.** The provisional preview is
67
+ * meant to stay visible until the authoritative final UI replaces
68
+ * it. Tearing down the surface in the producer would clear the
69
+ * rendered fragments and leave the viewer blank between
70
+ * "preview-done" and "final-code-arrives" — the wrong UX.
71
+ *
72
+ * Authoritative handoff is the cancellation site: when real
73
+ * component code lands, the orchestrator's
74
+ * `finalizeProvisionalPreview` aborts the runner with reason
75
+ * `'handoff'` and the renderer swaps in the real component. Until
76
+ * then (e.g. on OSS today, where final generation isn't wired),
77
+ * the assembled surface stays painted as the user-facing preview.
78
+ *
79
+ * The orchestrator still owns the channel-level close
80
+ * (`{payload: null, complete: true}`); that just latches the
81
+ * channel as drained without affecting the rendered surface.
82
+ */
83
+ export declare function produceDeterministicPreview(ctx: DeterministicPreviewContext, options?: DeterministicPreviewOptions): Promise<void>;
84
+ /**
85
+ * Default export as a factory that adapts the producer into the
86
+ * orchestrator's `ProvisionalPreviewEmitter` shape without forcing
87
+ * consumers to write the one-line wrapper. Typed structurally so no
88
+ * import from `@ggui-ai/mcp-server-handlers` is required.
89
+ */
90
+ export declare function createDeterministicPreviewEmitter(options?: DeterministicPreviewOptions): {
91
+ run: (ctx: DeterministicPreviewContext) => Promise<void>;
92
+ };
93
+ export {};
94
+ //# sourceMappingURL=deterministic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deterministic.d.ts","sourceRoot":"","sources":["../../src/emitters/deterministic.ts"],"names":[],"mappings":"AAuCA;;;;;;;;GAQG;AACH,UAAU,iBAAiB;IACzB,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAAC;CACxC;AACD,KAAK,WAAW,GACZ,MAAM,GACN,MAAM,GACN,OAAO,GACP,IAAI,GACJ,WAAW,EAAE,GACb,iBAAiB,CAAC;AAEtB;;;;GAIG;AACH,MAAM,WAAW,2BAA2B;IAC1C;;;OAGG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtE;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1D;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;CAC9B;AAED,MAAM,WAAW,2BAA2B;IAC1C;;;;;OAKG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;OAKG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAmBD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,2BAA2B,CAC/C,GAAG,EAAE,2BAA2B,EAChC,OAAO,CAAC,EAAE,2BAA2B,GACpC,OAAO,CAAC,IAAI,CAAC,CAqEf;AAED;;;;;GAKG;AACH,wBAAgB,iCAAiC,CAC/C,OAAO,CAAC,EAAE,2BAA2B,GACpC;IAAE,GAAG,EAAE,CAAC,GAAG,EAAE,2BAA2B,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAI9D"}
@@ -0,0 +1,184 @@
1
+ /**
2
+ * Canonical catalog id for the V1 ggui preview subset. Kept in
3
+ * alignment with {@link GGUI_PREVIEW_CATALOG_V1_ID} via a type-level
4
+ * parity assertion below so a rename in one place can't silently
5
+ * desync.
6
+ */
7
+ const DEFAULT_CATALOG_ID = 'ggui.preview.v1';
8
+ /**
9
+ * Compile-time parity guard: the producer's default catalog id
10
+ * matches the canonical catalog manifest id. If the manifest id
11
+ * ever changes, this assignment fails to typecheck — the producer
12
+ * must be updated in lockstep.
13
+ */
14
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
15
+ const _CATALOG_ID_PARITY = DEFAULT_CATALOG_ID;
16
+ /**
17
+ * Produce a provisional preview for the supplied story. Emits 3
18
+ * frames on the happy path; returns early on cancellation.
19
+ *
20
+ * **No `deleteSurface` on happy path.** The provisional preview is
21
+ * meant to stay visible until the authoritative final UI replaces
22
+ * it. Tearing down the surface in the producer would clear the
23
+ * rendered fragments and leave the viewer blank between
24
+ * "preview-done" and "final-code-arrives" — the wrong UX.
25
+ *
26
+ * Authoritative handoff is the cancellation site: when real
27
+ * component code lands, the orchestrator's
28
+ * `finalizeProvisionalPreview` aborts the runner with reason
29
+ * `'handoff'` and the renderer swaps in the real component. Until
30
+ * then (e.g. on OSS today, where final generation isn't wired),
31
+ * the assembled surface stays painted as the user-facing preview.
32
+ *
33
+ * The orchestrator still owns the channel-level close
34
+ * (`{payload: null, complete: true}`); that just latches the
35
+ * channel as drained without affecting the rendered surface.
36
+ */
37
+ export async function produceDeterministicPreview(ctx, options) {
38
+ const surfaceId = options?.surfaceId ?? ctx.stackItemId;
39
+ const catalogId = options?.catalogId ?? DEFAULT_CATALOG_ID;
40
+ // Frame 1 — surface creation.
41
+ await ctx.emit({
42
+ version: 'v0.9',
43
+ createSurface: { surfaceId, catalogId },
44
+ });
45
+ if (ctx.signal.aborted)
46
+ return;
47
+ // Frame 2 — root skeleton. Shows a heading derived from the
48
+ // intent so the user sees "what is being built" before the body
49
+ // + shells fill in.
50
+ const heading = deriveHeading(ctx.story.intent);
51
+ await ctx.emit({
52
+ version: 'v0.9',
53
+ updateComponents: {
54
+ surfaceId,
55
+ components: [
56
+ {
57
+ id: 'root',
58
+ component: 'Column',
59
+ children: ['heading'],
60
+ gap: '12',
61
+ align: 'stretch',
62
+ },
63
+ {
64
+ id: 'heading',
65
+ component: 'Text',
66
+ variant: 'h2',
67
+ text: heading,
68
+ },
69
+ ],
70
+ },
71
+ });
72
+ if (ctx.signal.aborted)
73
+ return;
74
+ // Frame 3 — enriched layout. Adds a body caption + keyword-driven
75
+ // shells (form / list / …) so the surface reads as the rough
76
+ // outline of the final UI rather than a lone heading. This is
77
+ // the terminal frame on the happy path; the surface stays
78
+ // painted in the viewer until authoritative handoff aborts the
79
+ // runner (or the user navigates away).
80
+ const body = deriveBody(ctx.story.intent);
81
+ const shell = pickShell(ctx.story.intent);
82
+ const rootChildren = ['heading', 'body', ...shell.ids];
83
+ await ctx.emit({
84
+ version: 'v0.9',
85
+ updateComponents: {
86
+ surfaceId,
87
+ components: [
88
+ {
89
+ id: 'root',
90
+ component: 'Column',
91
+ children: rootChildren,
92
+ gap: '12',
93
+ align: 'stretch',
94
+ },
95
+ {
96
+ id: 'body',
97
+ component: 'Text',
98
+ variant: 'caption',
99
+ text: body,
100
+ },
101
+ ...shell.fragments,
102
+ ],
103
+ },
104
+ });
105
+ }
106
+ /**
107
+ * Default export as a factory that adapts the producer into the
108
+ * orchestrator's `ProvisionalPreviewEmitter` shape without forcing
109
+ * consumers to write the one-line wrapper. Typed structurally so no
110
+ * import from `@ggui-ai/mcp-server-handlers` is required.
111
+ */
112
+ export function createDeterministicPreviewEmitter(options) {
113
+ return {
114
+ run: (ctx) => produceDeterministicPreview(ctx, options),
115
+ };
116
+ }
117
+ // ─── Heuristics ────────────────────────────────────────────────────────
118
+ /**
119
+ * First-sentence heading derivation. Takes the first
120
+ * sentence-terminating punctuation as the boundary, falls back to
121
+ * the first ~80 chars. Capitalizes the leading character so
122
+ * lowercase intents ("build a chat app") render as titles.
123
+ */
124
+ function deriveHeading(intent) {
125
+ const trimmed = intent.trim();
126
+ if (trimmed.length === 0)
127
+ return 'Preparing your view…';
128
+ const firstSentence = trimmed.split(/[.!?\n]/)[0]?.trim() ?? trimmed;
129
+ const clipped = firstSentence.length <= 80 ? firstSentence : firstSentence.slice(0, 80);
130
+ const leading = clipped.charAt(0).toUpperCase();
131
+ return leading + clipped.slice(1);
132
+ }
133
+ /**
134
+ * Body caption. Tight clip so the provisional surface doesn't try
135
+ * to render the full intent — the final UI handles rich content;
136
+ * the preview just sets expectations.
137
+ */
138
+ function deriveBody(intent) {
139
+ const trimmed = intent.trim();
140
+ if (trimmed.length === 0)
141
+ return '';
142
+ if (trimmed.length <= 120)
143
+ return trimmed;
144
+ return trimmed.slice(0, 117) + '…';
145
+ }
146
+ /**
147
+ * Keyword-driven shell selection. Tiny heuristics — not an NLP
148
+ * pass. The goal is "provisional looks broadly right for common
149
+ * intents", not "provisional is 95% accurate". When the heuristics
150
+ * miss, the rendered surface degrades to heading + caption, which
151
+ * is still honest about what's coming.
152
+ */
153
+ function pickShell(intent) {
154
+ const lower = intent.toLowerCase();
155
+ if (/\b(form|input|sign\s?up|log\s?in|register|submit|feedback)\b/.test(lower)) {
156
+ return {
157
+ ids: ['form-card'],
158
+ fragments: [
159
+ { id: 'form-card', component: 'Card', child: 'form-col' },
160
+ {
161
+ id: 'form-col',
162
+ component: 'Column',
163
+ children: ['tf', 'btn'],
164
+ gap: '8',
165
+ },
166
+ { id: 'tf', component: 'TextField', label: 'Input' },
167
+ { id: 'btn', component: 'Button', label: 'Submit' },
168
+ ],
169
+ };
170
+ }
171
+ if (/\b(list|items|todos?|feed|posts?|grid|dashboard|table)\b/.test(lower)) {
172
+ return {
173
+ ids: ['list-card'],
174
+ fragments: [
175
+ { id: 'list-card', component: 'Card', child: 'list' },
176
+ { id: 'list', component: 'List', children: ['l1', 'l2', 'l3'] },
177
+ { id: 'l1', component: 'Text', variant: 'body', text: '—' },
178
+ { id: 'l2', component: 'Text', variant: 'body', text: '—' },
179
+ { id: 'l3', component: 'Text', variant: 'body', text: '—' },
180
+ ],
181
+ };
182
+ }
183
+ return { ids: [], fragments: [] };
184
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * `@ggui-ai/preview-a2ui/emitters` — reference producers for the
3
+ * provisional preview pipeline.
4
+ *
5
+ * V1 ships a deterministic producer (`produceDeterministicPreview`
6
+ * + `createDeterministicPreviewEmitter`) that makes the server
7
+ * orchestration path real without requiring a fast-model LLM. A
8
+ * future fast-model-backed producer can layer onto the same contract.
9
+ *
10
+ * Keeping producers in a dedicated subpath lets consumers import
11
+ * exactly the bundle they need — hosted pods pulling a Haiku
12
+ * producer don't pay for the deterministic one, and vice-versa.
13
+ */
14
+ export { createDeterministicPreviewEmitter, produceDeterministicPreview, type DeterministicPreviewContext, type DeterministicPreviewOptions, } from './deterministic';
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/emitters/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EACL,iCAAiC,EACjC,2BAA2B,EAC3B,KAAK,2BAA2B,EAChC,KAAK,2BAA2B,GACjC,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * `@ggui-ai/preview-a2ui/emitters` — reference producers for the
3
+ * provisional preview pipeline.
4
+ *
5
+ * V1 ships a deterministic producer (`produceDeterministicPreview`
6
+ * + `createDeterministicPreviewEmitter`) that makes the server
7
+ * orchestration path real without requiring a fast-model LLM. A
8
+ * future fast-model-backed producer can layer onto the same contract.
9
+ *
10
+ * Keeping producers in a dedicated subpath lets consumers import
11
+ * exactly the bundle they need — hosted pods pulling a Haiku
12
+ * producer don't pay for the deterministic one, and vice-versa.
13
+ */
14
+ export { createDeterministicPreviewEmitter, produceDeterministicPreview, } from './deterministic.js';
@@ -0,0 +1,25 @@
1
+ /**
2
+ * `@ggui-ai/preview-a2ui` — A2UI boundary for ggui's provisional
3
+ * assembly channel.
4
+ *
5
+ * V1 scope:
6
+ * - Server → client write path only
7
+ * - Three messages: createSurface / updateComponents / deleteSurface
8
+ * - Narrow catalog (12 Basic Catalog components — see `./catalog`)
9
+ * - Non-interactive provisional rendering
10
+ *
11
+ * Anything outside this scope (data model, interactive actions,
12
+ * broader catalog coverage) is deliberately deferred. Widen the
13
+ * surface intentionally, not accidentally.
14
+ *
15
+ * Deps: `zod` only. No React, no React Native, no `@ggui-ai/protocol`
16
+ * import — this package is framework-neutral and protocol-neutral.
17
+ * The reserved `_ggui:preview` channel constant lives in
18
+ * `@ggui-ai/protocol/validation/reserved-channels`; this package is
19
+ * the other side of the boundary and must not couple to the protocol
20
+ * root.
21
+ */
22
+ export * from './catalog';
23
+ export * from './components';
24
+ export * from './messages';
25
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,24 @@
1
+ /**
2
+ * `@ggui-ai/preview-a2ui` — A2UI boundary for ggui's provisional
3
+ * assembly channel.
4
+ *
5
+ * V1 scope:
6
+ * - Server → client write path only
7
+ * - Three messages: createSurface / updateComponents / deleteSurface
8
+ * - Narrow catalog (12 Basic Catalog components — see `./catalog`)
9
+ * - Non-interactive provisional rendering
10
+ *
11
+ * Anything outside this scope (data model, interactive actions,
12
+ * broader catalog coverage) is deliberately deferred. Widen the
13
+ * surface intentionally, not accidentally.
14
+ *
15
+ * Deps: `zod` only. No React, no React Native, no `@ggui-ai/protocol`
16
+ * import — this package is framework-neutral and protocol-neutral.
17
+ * The reserved `_ggui:preview` channel constant lives in
18
+ * `@ggui-ai/protocol/validation/reserved-channels`; this package is
19
+ * the other side of the boundary and must not couple to the protocol
20
+ * root.
21
+ */
22
+ export * from './catalog.js';
23
+ export * from './components.js';
24
+ export * from './messages.js';