@snackbit/opendil 0.1.0 → 0.2.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.
Files changed (88) hide show
  1. package/README.md +74 -137
  2. package/bin/opendil.mjs +66 -11
  3. package/bin/publish-directory.d.mts +18 -0
  4. package/bin/publish-directory.mjs +173 -17
  5. package/dist/agent-spec.js +9 -0
  6. package/dist/chunk-RPZW4WVX.js +2 -0
  7. package/dist/chunk-ZSTXLIS6.js +2 -0
  8. package/dist/index.js +1 -10
  9. package/dist/runtime/frame.html +117 -44
  10. package/dist/runtime/frame.js +501 -505
  11. package/dist/spec/genui.agent.full.md +1927 -0
  12. package/dist/spec/genui.agent.md +479 -0
  13. package/dist/spec/genui.examples.md +836 -0
  14. package/dist/styled-renderer-PHI4MNPF.js +2441 -0
  15. package/dist/styles.css +115 -42
  16. package/dist/types/agent-spec.d.ts +12 -0
  17. package/dist/types/components/ui/controls/select.d.ts +14 -0
  18. package/dist/types/components/ui/controls/tabs.d.ts +7 -0
  19. package/dist/types/components/ui/controls/toggle-group.d.ts +3 -2
  20. package/dist/types/components/ui/display/chart.d.ts +6 -12
  21. package/dist/types/components/ui/media/carousel.d.ts +1 -1
  22. package/dist/types/components/ui/overlays/collapsible.d.ts +6 -0
  23. package/dist/types/components/ui/overlays/popover.d.ts +2 -1
  24. package/dist/types/components/ui/overlays/ui-scope.d.ts +16 -0
  25. package/dist/types/dil/custom-component.d.ts +1 -1
  26. package/dist/types/dil/dil-renderer.d.ts +58 -23
  27. package/dist/types/dil/isolation/frame-startup.d.ts +18 -0
  28. package/dist/types/dil/isolation/frame-theme.d.ts +14 -0
  29. package/dist/types/dil/isolation/frame-viewport.d.ts +30 -0
  30. package/dist/types/dil/isolation/isolated-renderer.d.ts +13 -7
  31. package/dist/types/dil/isolation/overlay-room.d.ts +29 -0
  32. package/dist/types/dil/isolation/viewport-scroll.d.ts +3 -2
  33. package/dist/types/dil/message-renderer.d.ts +6 -5
  34. package/dist/types/dil/parser/dil-parser.d.ts +44 -3
  35. package/dist/types/dil/parser/lexical.d.ts +13 -2
  36. package/dist/types/dil/parser/literal-tag.d.ts +16 -0
  37. package/dist/types/dil/parser/markdown-lexing.d.ts +41 -0
  38. package/dist/types/dil/parser/types.d.ts +22 -1
  39. package/dist/types/dil/parser/unfinished.d.ts +22 -0
  40. package/dist/types/dil/parser/vocabulary.d.ts +12 -0
  41. package/dist/types/dil/render-error.d.ts +47 -0
  42. package/dist/types/dil/renderer-environment.d.ts +19 -8
  43. package/dist/types/dil/runtime/document.d.ts +18 -6
  44. package/dist/types/dil/runtime/execution-queue.d.ts +2 -1
  45. package/dist/types/dil/runtime/expressions.d.ts +8 -5
  46. package/dist/types/dil/runtime/inline-worker.d.ts +33 -0
  47. package/dist/types/dil/runtime/view-cost.d.ts +2 -2
  48. package/dist/types/dil/styled-renderer.d.ts +39 -0
  49. package/dist/types/dil/view/conditional-view.d.ts +3 -3
  50. package/dist/types/dil/view/markdown-node.d.ts +3 -3
  51. package/dist/types/dil/view/node-children.d.ts +3 -3
  52. package/dist/types/dil/view/node-view.d.ts +2 -2
  53. package/dist/types/dil/view/progressive-reveal.d.ts +5 -4
  54. package/dist/types/dil/view/render-boundary.d.ts +13 -0
  55. package/dist/types/dil/view/render-limit.d.ts +1 -1
  56. package/dist/types/dil/view/repeated-nodes.d.ts +4 -4
  57. package/dist/types/dil/view/reveal/controller.d.ts +9 -2
  58. package/dist/types/dil/view/reveal/presentation.d.ts +1 -1
  59. package/dist/types/dil/view/scroll/controller.d.ts +16 -2
  60. package/dist/types/dil/view/scroll/host-viewport.d.ts +24 -0
  61. package/dist/types/dil/view/scroll/root-tracker.d.ts +17 -0
  62. package/dist/types/dil/view/scroll/scroll-root.d.ts +36 -0
  63. package/dist/types/dil/view/scroll-options.d.ts +15 -0
  64. package/dist/types/dil/view/stream-follow.d.ts +10 -3
  65. package/dist/types/dil/view/table-context.d.ts +1 -1
  66. package/dist/types/dil/view/virtual-flow.d.ts +3 -3
  67. package/dist/types/dil/widgets/action-feedback.d.ts +1 -1
  68. package/dist/types/dil/widgets/charts/chart-hover.d.ts +17 -0
  69. package/dist/types/dil/widgets/charts/chart-legend.d.ts +1 -1
  70. package/dist/types/dil/widgets/charts/chart-pie.d.ts +16 -0
  71. package/dist/types/dil/widgets/charts/chart-series.d.ts +10 -2
  72. package/dist/types/dil/widgets/charts/chart-snapping.d.ts +3 -5
  73. package/dist/types/dil/widgets/charts/snap-cursor.d.ts +3 -7
  74. package/dist/types/dil/widgets/charts/snap-tooltip.d.ts +6 -4
  75. package/dist/types/dil/widgets/code-block.d.ts +1 -1
  76. package/dist/types/dil/widgets/controls.d.ts +2 -2
  77. package/dist/types/dil/widgets/graphs/node-graph.d.ts +1 -1
  78. package/dist/types/dil/widgets/graphs/service-node.d.ts +1 -1
  79. package/dist/types/dil/widgets/primitives/primitive.d.ts +4 -4
  80. package/dist/types/index.d.ts +9 -8
  81. package/dist/types/ui.d.ts +11 -8
  82. package/dist/ui.js +1 -1
  83. package/package.json +13 -2
  84. package/styles/tailwind.css +53 -1
  85. package/styles/tokens.css +3 -0
  86. package/dist/chunk-ZWAN2JCV.js +0 -2
  87. package/dist/runtime/vm.js +0 -6
  88. package/dist/shadow-renderer-F25KL3C4.js +0 -2363
@@ -0,0 +1,479 @@
1
+ # GenUI Agent Specification
2
+
3
+ ## 1. Output format and safety
4
+
5
+ Generate OpenDIL markup: Markdown, supported component tags, expressions, and
6
+ directives. Mix prose and UI directly. Do not enclose the response in a code
7
+ fence unless asked to show source. Match component and property names exactly.
8
+ Close every tag and directive before finishing. Use self-closing tags for leaves.
9
+
10
+ Use only the APIs below. Do not emit arbitrary HTML, React JSX, imports,
11
+ TypeScript, CSS, spread attributes, DOM handlers, or injected HTML. Render supplied
12
+ facts faithfully; label invented example data. Do not imply that a label connects
13
+ a component to a service. Provide readable labels and visible validation messages.
14
+ Avoid nested interactive controls. Keep calculations and output bounded.
15
+
16
+ Expressions execute in an isolated QuickJS worker. Browser globals, DOM access,
17
+ network clients, storage, browser timers, Node APIs, and dynamic module loading
18
+ are unavailable as authoring APIs. Do not use `eval` or `Function`; this is an
19
+ authoring rule, not a claim that QuickJS removes those JavaScript primitives.
20
+ Do not probe VM internals or overwrite globals. Host operations require the
21
+ explicit API and invocation rules in section 6. Do not request weaker containment.
22
+
23
+ ## 2. Syntax and parsing
24
+
25
+ ### Markdown
26
+
27
+ Use headings, paragraphs, lists, emphasis, blockquotes, fenced code, and GFM
28
+ tables, strikethrough, and task lists. Markdown task lists are presentation, not
29
+ state-bound inputs. Links render their labels as inert text; Markdown images are
30
+ suppressed. Use a visible URL as text when the destination matters. No authored
31
+ HTML link or image tag is supported. Mermaid fences render diagrams.
32
+
33
+ Keep fences on separate lines with at most three leading spaces. Fences and
34
+ inline code spans protect their contents from DIL parsing: braces, tags, and
35
+ directives inside them display literally and never evaluate. A code span ends at
36
+ a blank line or at a line that starts a list item, heading, blockquote,
37
+ component tag, or block directive; an unmatched backtick protects nothing.
38
+ Lowercase HTML-like tags that are not DIL tags, such as `<div>` or `<br>`,
39
+ display as plain text; capitalized unknown tags are unsupported components. For
40
+ a literal brace in ordinary prose, use an expression such as `{"{"}`.
41
+
42
+ ### JavaScript expressions
43
+
44
+ Attributes accept `name="literal"`, `name='literal'`, `flag` (true), or
45
+ `name={expression}`. Use braces for numbers, booleans, arrays, objects, and
46
+ callbacks. Unquoted scalar values, spread attributes, and JSX children inside
47
+ JavaScript are unsupported. For a quote inside a string prop, use a JavaScript
48
+ string expression rather than escaped quoted-attribute syntax.
49
+
50
+ `{expression}` interpolates text; it never parses returned strings as markup.
51
+ Strings and numbers display directly; null/undefined display empty, booleans as
52
+ text, and objects/arrays as `[object Object]`. Select fields, join arrays, or
53
+ format explicitly. Expressions support JavaScript operators, property/computed
54
+ access, optional chaining, literals, template strings, functions, and array
55
+ methods. Use directives to create UI trees, not `.map()` returning JSX.
56
+
57
+ Do not put statements in interpolation. Callback function bodies may contain
58
+ bounded statements. Keep rendered expressions and derived bindings pure; perform
59
+ state changes only in callbacks. Use plain JSON-compatible data across bindings;
60
+ avoid cycles, class instances, BigInt, and non-finite numbers. Functions are
61
+ callback values, not data records. `Intl.NumberFormat` is a limited bridge that
62
+ formats en-US numbers with zero maximum fractional digits; locale/options are
63
+ not a general formatting API. Use explicit string formatting for other needs.
64
+
65
+ ### State declarations
66
+
67
+ Declare one binding per `{@body ...}` directive, before UI:
68
+
69
+ ```dil
70
+ {@body const [count,setCount] = DIL.useState(0)}
71
+ {@body const doubled = count * 2}
72
+ {@body const increment = () => setCount(previous => previous + 1)}
73
+ <button onClick={increment}>Increment</button>
74
+ <text>{doubled}</text>
75
+ ```
76
+
77
+ Supported declaration forms: `const [name,setName] = DIL.useState(initial)` and
78
+ `const name = expression`. An optional trailing semicolon is accepted. Use
79
+ unique document-wide names beginning with a letter or underscore and containing
80
+ letters, digits, or underscores. No `let`, `var`, function declarations, multiple
81
+ declarations in one directive, arbitrary destructuring, or other hooks exist.
82
+
83
+ State initializes once per document; a lazy initializer is supported. Ordinary
84
+ const bindings are getters evaluated on demand, not once-only snapshots. Keep
85
+ initializers and getters side-effect-free. Declarations are document-scoped even
86
+ when their source appears inside a conditional or loop. Declare them
87
+ unconditionally at the top level; they cannot capture iteration variables or
88
+ create item-local state.
89
+
90
+ ### Conditional rendering
91
+
92
+ ```dil
93
+ {@body const status = "ready"}
94
+ {#if status === "ready"}
95
+ <badge color="success">Ready</badge>
96
+ {:else if status === "waiting"}
97
+ <caption>Waiting</caption>
98
+ {:else}
99
+ <text>Unavailable</text>
100
+ {/if}
101
+ ```
102
+
103
+ Use JavaScript truthiness. The first matching branch renders. Else-if and else
104
+ are optional; close the enclosing if. Directives can produce required named
105
+ children without extra wrappers.
106
+
107
+ Repeat arrays with `{#each items as item,index}...{/each}`; index is optional
108
+ and zero-based. Non-arrays render no items; generate arrays deliberately. Give
109
+ repeated records stable unique string or number `id` values. Without such IDs,
110
+ identity falls back to position. There is no JSX `key` or keyed-each syntax.
111
+ Nested each scopes can read outer variables; declarations still cannot.
112
+
113
+ ```dil
114
+ {@body const items = [{id:"a",label:"Alpha"},{id:"b",label:"Beta"}]}
115
+ {#each items as item,index}
116
+ <text>{index + 1}. {item.label}</text>
117
+ {/each}
118
+ ```
119
+
120
+ Stream append-only source: keep the full previous prefix and append suffixes.
121
+ Incomplete tags, attributes, and directives wait for more input; complete them
122
+ before ending. Close useful children early. A repeated template waits for
123
+ `{/each}` before rendering. Streaming does not authorize actions. State survives
124
+ appends and virtualized unmounts within the document; a fresh document resets it.
125
+ Do not rewrite previous source to update state.
126
+
127
+ ## 3. Component API
128
+
129
+ Notation: `?` = optional; `=value` = default. Unmarked props must be supplied for
130
+ the intended output; the parser does not enforce a complete prop schema.
131
+ `callback` signatures are listed in section 6. Unknown props are not extensions.
132
+
133
+ Children categories:
134
+
135
+ - `inline`: text, inline Markdown, and inline components, including icons.
136
+ - `generic`: inline and block content.
137
+ - `raw`: unparsed source, with no expressions or component children.
138
+ - `none`: no children.
139
+ - Named children: only the listed direct component types; whitespace is allowed.
140
+ If/each directives may produce those children. `one` means exactly one.
141
+
142
+ These are generation contracts. The parser accepts a wider tree than valid UI
143
+ composition. Never nest buttons, pressables, inputs, or choice controls inside
144
+ another action control. Do not put block content inside inline text.
145
+
146
+ Shared layout props (only entries marked `layout`):
147
+ `padding?:number|{x?:number,y?:number}`, `gap?:number`,
148
+ `radius?:"sm"|"md"|"lg"|"xl"|"2xl"|"full"|string`,
149
+ `border?:boolean|{size?:number,color?:string}`, `background?:string`,
150
+ `clip?:boolean`, `width?:number|string`, `maxWidth?:number|string`,
151
+ `height?:number|string`, `flex?:number|string`, `columns?:number`,
152
+ `align?:string`, `justify?:string`, `wrap?:"wrap"`.
153
+
154
+ Numeric padding/gap use 4px units. Numeric width/maxWidth/height use pixels;
155
+ string dimensions use valid CSS lengths or percentages. Flex numbers are flex
156
+ values, not pixel dimensions. Named radii are 4/6/8/12/16px and full rounding.
157
+ Border defaults to 1px in the theme border color when enabled. Unspecified layout
158
+ props retain component styling. Prefer positive integer columns; grids reduce
159
+ columns responsively. `columns` has no useful grid effect on a row.
160
+
161
+ Prefer `align="start"|"center"|"end"|"stretch"` and
162
+ `justify="start"|"center"|"end"|"between"`. Use `wrap="wrap"` for wrapping rows.
163
+ Use `spacer` to consume remaining row space. Clipping may hide content; avoid it
164
+ around controls and long text unless deliberate.
165
+
166
+ Color values: `default`, `primary`, `secondary`, `tertiary`, `success`, `warning`,
167
+ `danger`, `surface-secondary`, `surface-tertiary`, `subtle`, `strong`, or a valid
168
+ CSS color shorter than 128 characters. Do not supply `url`, custom `var()`, CSS
169
+ declarations, or style objects as color values. Use semantic colors and readable
170
+ text; color alone must not communicate status.
171
+
172
+ ### Text components
173
+
174
+ - <text>: color?:string, size?:"xs"|"sm"|"md"|"lg"|"xl"|"2xl", weight?:"medium", tabularNums?:boolean; children: inline
175
+ - <title>: color?:string, size?:"xs"|"sm"|"md"|"lg"|"xl"|"2xl", weight?:"medium", tabularNums?:boolean; children: inline
176
+ - <caption>: color?:string, size?:"xs"|"sm"|"md"|"lg"|"xl"|"2xl", weight?:"medium", tabularNums?:boolean; children: inline
177
+ - <badge>: color?:string; children: inline
178
+ - <label>: no props; children: inline
179
+ - <CodeBlock>: language?:string="", editable?:boolean=false; children: raw
180
+
181
+ Text sizes xs/sm/md/lg/xl/2xl are 12/14/16/18/24/30px at the normal root size.
182
+ Title renders h3, defaults to 18px/600, and ignores weight overrides. Caption
183
+ defaults to secondary color and 12px. Use Markdown headings for document
184
+ hierarchy. `weight="medium"` means 500 on text/caption; use Markdown emphasis
185
+ for bold. `label` is visual text, not an input association; name inputs explicitly.
186
+
187
+ CodeBlock reads literal children until the exact `</CodeBlock>` delimiter.
188
+ No `source`, `value`, or `onChange` prop exists. Editable code is a local draft,
189
+ never executed and not readable from DIL state. Its copy/wrap controls are built
190
+ in. Avoid embedding its closing delimiter in its raw source; use fenced code
191
+ instead. Keep source below 131,072 characters and copyable content at 65,536 or
192
+ fewer characters. Fenced code is another display option, not a runnable program.
193
+
194
+ ### Media components
195
+
196
+ - <AsyncImage>: query:string; children: none
197
+
198
+ AsyncImage renders an offline placeholder illustration. Query is its alt text;
199
+ it is not an image URL, search request, or image-generation call. Provide a
200
+ descriptive query and do not claim the illustration depicts verified evidence.
201
+ No stock audio, video, file viewer, or external image-source prop exists.
202
+
203
+ ### Layout components
204
+
205
+ - <box>: layout; children: generic
206
+ - <row>: layout; children: generic
207
+ - <grid>: layout; children: generic
208
+ - <grid-item>: layout; children: generic
209
+ - <spacer>: no props; children: none
210
+ - <divider>: no props; children: none
211
+ - <table>: no props; children: table-row
212
+ - <table-row>: no props; children: table-cell
213
+ - <table-cell>: layout; children: generic
214
+ - <popover>: no props; children: popover-trigger | popover-content
215
+ - <popover-trigger>: no props; children: one button
216
+ - <popover-content>: side?:"top"|"bottom"="bottom", align?:"end"|"center"="center"; children: generic
217
+ - <carousel>: no props; children: carousel-item
218
+ - <carousel-item>: no props; children: generic
219
+
220
+ Use box for vertical content, row for horizontal groups, grid for responsive
221
+ columns, and grid-item for a grid child. Grid-item has no span/placement API.
222
+ Table supplies its own body; no table-section, header, colSpan, or rowSpan exists.
223
+ Use a first row of clear labels or a Markdown table when headers matter.
224
+
225
+ Composition contracts:
226
+
227
+ ```text
228
+ <table>
229
+ children: table-row
230
+ <table-row>
231
+ children: table-cell
232
+ <table-cell>
233
+ children: generic
234
+
235
+ <popover>
236
+ children: popover-trigger | popover-content
237
+ <popover-trigger>
238
+ children: one button
239
+ <popover-content>
240
+ children: generic
241
+
242
+ <carousel>
243
+ children: carousel-item
244
+ <carousel-item>
245
+ children: generic
246
+ ```
247
+
248
+ Use one trigger and one content region per popover. The trigger button opens it
249
+ without an authored handler; content may contain controls. Keep carousel items
250
+ direct children. Carousel navigation is built in; no authored active-index prop
251
+ or navigation callback exists. Avoid carousels for required sequential form steps.
252
+
253
+ ### Input components
254
+
255
+ - <button>: aria-label?:string, disabled?:boolean=false, variant?:"outline"|"ghost"|"default"="default", size?:"sm"|"xs"|"default"="default", block?:boolean=false, onClick?:callback; children: inline
256
+ - <pressable>: layout, color?:string, onClick?:callback; children: generic
257
+ - <input>: aria-label?:string, value?:string="", placeholder?:string="", disabled?:boolean=false, onChange?:callback; children: none
258
+ - <slider>: aria-label?:string, min?:number=0, max?:number=100, step?:number=1, value?:number=0, marks?:{label:string}[], disabled?:boolean=false, onChange?:callback; children: none
259
+ - <checkbox>: checked?:boolean=false, disabled?:boolean=false, lineThrough?:boolean=true, onChange?:callback; children: inline
260
+ - <radio-group>: aria-label?:string, value?:string="", direction?:"row", onChange?:callback; children: radio
261
+ - <radio>: value:string; children: inline
262
+ - <segmented-control>: aria-label?:string, value?:string="", options:{value:string,label:string}[], onChange?:callback; children: none
263
+
264
+ Give input, slider, radio-group, and segmented-control an explicit aria-label.
265
+ Checkbox/radio children supply visible labels. Name icon-only buttons with
266
+ aria-label. Pressable's noninteractive content must name its action. Only the
267
+ components listing `disabled` accept authored disabled state.
268
+
269
+ Bind controlled values and callbacks to state. Keep slider min < max, step > 0,
270
+ and value within range; marks are evenly distributed labels, not tick positions.
271
+ Use unique nonempty strings for choice values; keep selection among options.
272
+ Radio-group is vertical by default; direction="row" wraps horizontally.
273
+
274
+ ```text
275
+ <radio-group>
276
+ children: radio
277
+ <radio>
278
+ children: inline
279
+ ```
280
+
281
+ No defaultValue, loading, type, minLength, required, pattern, form, submit event,
282
+ select, textarea, or arbitrary DOM event prop exists. Validate using derived
283
+ values, visible messages, disabled buttons, and a guard inside the handler.
284
+
285
+ ## 4. Specialized components
286
+
287
+ ### Data-linked components
288
+
289
+ No stock remote-data, query, subscription, or provider component exists. Pass
290
+ supplied arrays/records to Chart and NodeGraph content or render them with each.
291
+ See Visualizations for their exact data shapes and section 6 for binding rules.
292
+ Labels such as "live" do not establish a connection or refresh behavior.
293
+
294
+ ### Links and citations
295
+
296
+ No link, citation, footnote lookup, source registry, or URL-opening action is
297
+ exposed. Markdown link labels display without navigation. Preserve source titles
298
+ and visible supplied URLs as text; do not invent reference IDs or destinations.
299
+ A button cannot open a URL through an undocumented browser operation.
300
+
301
+ ### Embedded application blocks
302
+
303
+ No iframe, app block, script, embed, or independently running application is
304
+ authorable. CodeBlock displays source only. Custom components require an explicit
305
+ host-supplied contract specifying names, props, children, and actions; absent that
306
+ contract, use stock components. Do not infer custom capabilities from site demos.
307
+
308
+ ## 5. Visualizations
309
+
310
+ ### Images
311
+
312
+ Use AsyncImage only with its documented placeholder semantics. Markdown images
313
+ do not display. For authored diagrams or illustrations, use presentation-only SVG:
314
+
315
+ - <svg>: svg props; children: SVG elements
316
+
317
+ SVG elements: svg, defs, marker, path, rect, circle, line, polyline, polygon, g,
318
+ ellipse, text, tspan, linearGradient, stop. Names are case-sensitive. SVG text is
319
+ SVG content inside an SVG subtree, not the DIL text component.
320
+
321
+ Shared SVG props: viewBox, width, height, x, y, cx, cy, r, rx, ry, d, fill, stroke,
322
+ strokeWidth, fontSize, fontWeight, opacity, id, markerWidth, markerHeight, refX,
323
+ refY, orient, markerEnd. Use suitable number/string values. Give the root a
324
+ viewBox and bounded dimensions. SVG has no layout-prop inheritance from DIL.
325
+
326
+ ```text
327
+ <svg>
328
+ children: SVG elements
329
+ <defs>
330
+ children: marker | linearGradient
331
+ <marker>
332
+ children: SVG shapes
333
+ <linearGradient>
334
+ children: stop
335
+ <g>
336
+ children: SVG shapes | g | text
337
+ <text>
338
+ children: text content | tspan
339
+ ```
340
+
341
+ These are useful SVG compositions, not a complete element-specific schema.
342
+ Use only local references such as `url(#arrow)`. No href, external image, script,
343
+ foreignObject, style, event handler, transform, points, offset, or stopColor prop
344
+ is exposed. In particular, polyline/polygon and gradient elements have a limited
345
+ attribute API; use path/rect/circle for reliable geometry. Do not invent missing
346
+ SVG attributes. Give diagrams a nearby text description; no SVG aria-label prop
347
+ is exposed. Never simulate interactive controls with SVG.
348
+
349
+ ### Charts
350
+
351
+ - <Chart>: content:object; children: none
352
+ - <NodeGraph>: content:object, selectedId?:string, onSelect?:callback; children: none
353
+ - <Mermaid>: source:string; children: none
354
+
355
+ Chart content for line/bar/scatter:
356
+ `{chartType:"line"|"bar"|"scatter",data:object[],xKey:string,
357
+ series:{dataKey:string,label?:string}[]}`.
358
+ For pie: `{chartType:"pie",data:object[],nameKey:string,valueKey:string}`.
359
+ Supply chartType explicitly; omission currently falls back to line. Series keys
360
+ must identify numeric fields. Scatter xKey is numeric; line/bar may use category
361
+ strings. Keep values finite, units consistent, and keys/labels distinct. Pie
362
+ values should be nonnegative and names unique. No axes, palette, size, tooltip,
363
+ legend, or callback customization props exist. Legend selection for multi-series
364
+ line/bar charts is internal; it is not DIL state. Supply a nearby textual summary.
365
+
366
+ NodeGraph content:
367
+ `{nodes:{id:string,label:string,sub?:string,x?:number,y?:number}[],
368
+ edges:{id?:string,source:string,target:string,label?:string}[]}`.
369
+ Use unique node IDs and valid edge endpoints. Coordinates are optional hints;
370
+ layout adjusts them to avoid overlap. Maximum 200 nodes and 400 edges; excess
371
+ entries are truncated and invalid endpoints filtered. Graph selection can bind
372
+ selectedId/onSelect; dragging and connecting are unavailable. Pan/zoom controls
373
+ are built in. No custom node types, styles, or edge handlers are authorable.
374
+
375
+ Mermaid accepts source text as a string, also through a fenced mermaid block.
376
+ Keep it within 8,192 characters and 100 edges. Do not include configuration
377
+ directives, frontmatter, authored CSS, HTML, click actions, or external links.
378
+ Output is sanitized. Mermaid is a diagram display, not an interaction surface.
379
+
380
+ ### Maps
381
+
382
+ No map, geocoding, tile, marker, or geographic layer API exists. Present supplied
383
+ locations as text/table data. Use a supplied URL as visible text; do not imply an
384
+ interactive map or fabricate geographic results.
385
+
386
+ ## 6. Interactivity
387
+
388
+ ### State management
389
+
390
+ Only `DIL.useState(initialValue)` exists. Pass a value or lazy initializer.
391
+ Setters accept a replacement or `(previous) => nextValue`. Replace arrays and
392
+ objects; never mutate them in place. Use functional setters for repeated updates
393
+ that depend on the previous value. Derive totals/filtering with const getters.
394
+ No useEffect, useMemo, useCallback, useRef, useId, lifecycle, or async data hook
395
+ is exposed. Do not perform work merely because a component renders.
396
+
397
+ State belongs to the mounted document, not the server, browser storage, or a
398
+ global app store. Keep state for repeated records in a top-level array/object
399
+ keyed by ID. Hiding a branch does not reset document state. Code editor drafts
400
+ and chart legend state are internal widget state, not author-visible bindings.
401
+
402
+ ### Event callbacks
403
+
404
+ | Component callback | Argument |
405
+ | ------------------------------------------------ | ----------------------------------- |
406
+ | button.onClick, pressable.onClick | none; ignore the undefined argument |
407
+ | input.onChange | value: string |
408
+ | slider.onChange | value: number |
409
+ | checkbox.onChange | checked: boolean |
410
+ | radio-group.onChange, segmented-control.onChange | value: string |
411
+ | NodeGraph.onSelect | id: string |
412
+
413
+ Callbacks receive values, never DOM events. Pass a setter directly or a function
414
+ expression; do not call it while assigning the prop. Keep handlers synchronous
415
+ and bounded. Input/slider/checkbox keep immediate local drafts while worker state
416
+ updates; bind state to update other views. Choice controls require upstream state
417
+ for persistent selection. NodeGraph selection likewise needs a binding. No
418
+ onSubmit, onBlur, onKeyDown, onInput, or propagation-control API exists.
419
+
420
+ ### Data bindings
421
+
422
+ Embed supplied JSON-compatible records in top-level const declarations; no
423
+ automatic external binding name exists. Read fields with dot or computed access,
424
+ derive filtered/mapped arrays using pure expressions, and pass them to props or
425
+ each. Treat supplied facts as read-only; use separate state for edits. Expressions
426
+ can read loop item/index names only within that loop's rendered subtree.
427
+
428
+ ```dil
429
+ {@body const records = [{id:"a",name:"Alpha",amount:12}]}
430
+ {@body const total = records.reduce((sum,item) => sum + item.amount,0)}
431
+ <text>Total: {total}</text>
432
+ {#each records as item}<text>{item["name"]}: {item.amount}</text>{/each}
433
+ ```
434
+
435
+ Bindings live only within the document. There is no host-data injection prop
436
+ visible to authored expressions, subscription, persistence, write-back channel,
437
+ or fetch operation. A displayed edit is not a saved server mutation.
438
+
439
+ ### Host actions
440
+
441
+ `GenUI.copy(text: string): undefined` requests a clipboard write, up to 65,536
442
+ characters. Call it synchronously from a button or pressable onClick following
443
+ explicit user activation. A value-change/selection callback, initialization,
444
+ derived getter, interpolation, or automatic execution cannot authorize copying.
445
+ Do not defer it through promises or timers, depend on a return value, or attempt
446
+ clipboard reads. Empty text does not produce a clipboard request.
447
+
448
+ ```dil
449
+ {@body const [name,setName] = DIL.useState("")}
450
+ {@body const valid = name.trim().length > 0}
451
+ <input aria-label="Name" value={name} onChange={setName}/>
452
+ {#if !valid}<caption>Enter a name.</caption>{/if}
453
+ <button disabled={!valid} onClick={() => { if (valid) GenUI.copy(name); }}>Copy name</button>
454
+ ```
455
+
456
+ The initiating control reports Copied or Copy failed. Do not set a success flag
457
+ before browser confirmation or add duplicate feedback. The platform may deny a
458
+ valid request. Make one copy request per action; multiple calls do not create a
459
+ batch. No openUrl, issueNewTurn, network, export, file creation, or storage action
460
+ exists. Runtime resource and display limits can stop oversized/runaway documents;
461
+ do not approach them deliberately. The default renderer uses an opaque-origin
462
+ frame; opt-in host/Shadow DOM modes differ in containment, and Shadow DOM is a
463
+ styling boundary. These modes do not grant generated source new APIs.
464
+
465
+ ## 7. Assets
466
+
467
+ ### Icons
468
+
469
+ - <icon>: name:string, size?:"xs"|"lg", color?:string; children: none
470
+
471
+ Names: chart-no-axes-combined, circle-check, check-circle-2, circle, wallet,
472
+ trending-up, users, rotate-ccw, copy, sliders-horizontal, ellipsis, sparkles,
473
+ mouse-pointer-click, x, git-merge, package-check, shield-check, settings-2, info,
474
+ code-2, alert-triangle.
475
+
476
+ Sizes: xs=13px, omitted=17px, lg=22px. Unknown names fall back to circle; choose
477
+ listed names instead. Icons are decorative and cannot carry authored accessible
478
+ labels. Pair them with visible text or name the containing button. No external
479
+ icon library, asset upload, or arbitrary icon URL exists.