@gradial/aci 0.2.0-canary.730 → 0.2.0-canary.737

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 (23) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/README.md +4 -4
  3. package/dist/react/index.d.ts +1 -295
  4. package/dist/react/index.js +0 -7
  5. package/dist/types/image.d.ts +4 -0
  6. package/dist/types/image.js +10 -2
  7. package/package.json +7 -7
  8. package/src/types/image.test.ts +63 -0
  9. package/src/types/image.ts +10 -2
  10. package/templates/astro/starter-content/src/cms/contracts/components/button.contract.ts +8 -8
  11. package/templates/astro/starter-content/src/cms/contracts/components/homeHero.contract.ts +10 -8
  12. package/templates/common/.agents/skills/authoring/SKILL.md +47 -10
  13. package/templates/common/starter-content/.content/patterns/components/button.json +13 -5
  14. package/templates/common/starter-content/.content/patterns/components/container.json +2 -2
  15. package/templates/common/starter-content/.content/patterns/components/feature_card.json +2 -2
  16. package/templates/common/starter-content/.content/patterns/components/feature_grid.json +2 -2
  17. package/templates/common/starter-content/.content/patterns/components/home_hero.json +14 -8
  18. package/templates/common/starter-content/.content/patterns/components/personalization_choice.json +2 -2
  19. package/templates/common/starter-content/.content/patterns/components/site-footer.json +2 -2
  20. package/templates/common/starter-content/.content/patterns/components/site-navigation.json +2 -2
  21. package/templates/common/starter-content/.content/patterns/components/stats_bar.json +2 -2
  22. package/templates/nextjs/starter-content/src/cms/contracts/components/button.contract.ts +8 -8
  23. package/templates/nextjs/starter-content/src/cms/contracts/components/homeHero.contract.ts +10 -8
package/CHANGELOG.md CHANGED
@@ -188,6 +188,11 @@
188
188
 
189
189
  ### Changed
190
190
 
191
+ - Starter hero and button contracts describe component purpose and field meaning
192
+ in the component catalog. Authoring guidance uses those descriptions and
193
+ stable block IDs to identify the requested edit.
194
+ - The Next.js starter hero image is optional, matching Astro and the existing renderer.
195
+
191
196
  - Next production builds and error-artifact preparation are content-independent
192
197
  without `ACI_CODE_ARTIFACT_BUILD`. Local Next development still validates and
193
198
  previews authored error seats; production authored error pages belong to
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Agentic Content Infrastructure SDK
2
2
 
3
- `@gradial/aci` `0.2.0-canary.730` is a pre-1.0 public-surface reset for the ACI
3
+ `@gradial/aci` `0.2.0-canary.737` is a pre-1.0 public-surface reset for the ACI
4
4
  client SDK. Breaking changes from the old `0.1.x` accidental surface are
5
5
  intentional: the root import is framework-neutral, framework runtime behavior is
6
6
  behind explicit subpaths, and the first required customer path is React/Next.
@@ -8,7 +8,7 @@ behind explicit subpaths, and the first required customer path is React/Next.
8
8
  ## Install
9
9
 
10
10
  ```bash
11
- npm install @gradial/aci@0.2.0-canary.730 zod@^4
11
+ npm install @gradial/aci@0.2.0-canary.737 zod@^4
12
12
  ```
13
13
 
14
14
  ## Root Import
@@ -141,13 +141,13 @@ host bundles select and serve immutable release artifacts.
141
141
  The first RC scaffold path is Next:
142
142
 
143
143
  ```bash
144
- npx @gradial/aci@0.2.0-canary.730 init my-site --template next-starter
144
+ npx @gradial/aci@0.2.0-canary.737 init my-site --template next-starter
145
145
  ```
146
146
 
147
147
  List available templates:
148
148
 
149
149
  ```bash
150
- npx @gradial/aci@0.2.0-canary.730 init --list
150
+ npx @gradial/aci@0.2.0-canary.737 init --list
151
151
  ```
152
152
 
153
153
  ## Personalization: The One-Tag Install
@@ -11,301 +11,7 @@ export interface ImageProps extends Omit<ImgHTMLAttributes<HTMLImageElement>, 's
11
11
  image?: ImageData;
12
12
  value?: ImageData;
13
13
  }
14
- export declare function Image({ image, value, ...attrs }: ImageProps): import("react").DetailedReactHTMLElement<import("../types/image.js").ImageAttrs, HTMLElement> | import("react").DetailedReactHTMLElement<{
15
- id?: string | undefined | undefined;
16
- title?: string | undefined | undefined;
17
- role?: import("react").AriaRole | undefined;
18
- prefix?: string | undefined | undefined;
19
- width?: number | string | undefined | undefined;
20
- height?: number | string | undefined | undefined;
21
- sizes?: string | undefined | undefined;
22
- srcSet?: string | undefined | undefined;
23
- loading?: "eager" | "lazy" | undefined | undefined;
24
- decoding?: "async" | "auto" | "sync" | undefined | undefined;
25
- rel?: string | undefined | undefined;
26
- content?: string | undefined | undefined;
27
- referrerPolicy?: import("react").HTMLAttributeReferrerPolicy | undefined;
28
- slot?: string | undefined | undefined;
29
- style?: import("react").CSSProperties | undefined;
30
- dir?: string | undefined | undefined;
31
- hidden?: boolean | undefined | undefined;
32
- children?: ReactNode;
33
- dangerouslySetInnerHTML?: {
34
- __html: string | TrustedHTML;
35
- } | undefined | undefined;
36
- className?: string | undefined | undefined;
37
- crossOrigin?: "" | "anonymous" | "use-credentials" | undefined;
38
- fetchPriority?: "high" | "low" | "auto" | undefined | undefined;
39
- useMap?: string | undefined | undefined;
40
- defaultChecked?: boolean | undefined | undefined;
41
- defaultValue?: string | number | readonly string[] | undefined;
42
- suppressContentEditableWarning?: boolean | undefined | undefined;
43
- suppressHydrationWarning?: boolean | undefined | undefined;
44
- accessKey?: string | undefined | undefined;
45
- autoCapitalize?: "off" | "none" | "on" | "sentences" | "words" | "characters" | undefined | (string & {}) | undefined;
46
- autoFocus?: boolean | undefined | undefined;
47
- contentEditable?: "inherit" | (boolean | "true" | "false") | "plaintext-only" | undefined;
48
- contextMenu?: string | undefined | undefined;
49
- draggable?: (boolean | "true" | "false") | undefined;
50
- enterKeyHint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined | undefined;
51
- lang?: string | undefined | undefined;
52
- nonce?: string | undefined | undefined;
53
- spellCheck?: (boolean | "true" | "false") | undefined;
54
- tabIndex?: number | undefined | undefined;
55
- translate?: "yes" | "no" | undefined | undefined;
56
- radioGroup?: string | undefined | undefined;
57
- about?: string | undefined | undefined;
58
- datatype?: string | undefined | undefined;
59
- inlist?: any;
60
- property?: string | undefined | undefined;
61
- resource?: string | undefined | undefined;
62
- rev?: string | undefined | undefined;
63
- typeof?: string | undefined | undefined;
64
- vocab?: string | undefined | undefined;
65
- autoCorrect?: string | undefined | undefined;
66
- autoSave?: string | undefined | undefined;
67
- color?: string | undefined | undefined;
68
- itemProp?: string | undefined | undefined;
69
- itemScope?: boolean | undefined | undefined;
70
- itemType?: string | undefined | undefined;
71
- itemID?: string | undefined | undefined;
72
- itemRef?: string | undefined | undefined;
73
- results?: number | undefined | undefined;
74
- security?: string | undefined | undefined;
75
- unselectable?: "on" | "off" | undefined | undefined;
76
- popover?: "" | "auto" | "manual" | "hint" | undefined | undefined;
77
- popoverTargetAction?: "toggle" | "show" | "hide" | undefined | undefined;
78
- popoverTarget?: string | undefined | undefined;
79
- inert?: boolean | undefined | undefined;
80
- inputMode?: "none" | "text" | "tel" | "url" | "email" | "numeric" | "decimal" | "search" | undefined | undefined;
81
- is?: string | undefined | undefined;
82
- exportparts?: string | undefined | undefined;
83
- part?: string | undefined | undefined;
84
- tw?: string | undefined;
85
- "aria-activedescendant"?: string | undefined | undefined;
86
- "aria-atomic"?: (boolean | "true" | "false") | undefined;
87
- "aria-autocomplete"?: "none" | "inline" | "list" | "both" | undefined | undefined;
88
- "aria-braillelabel"?: string | undefined | undefined;
89
- "aria-brailleroledescription"?: string | undefined | undefined;
90
- "aria-busy"?: (boolean | "true" | "false") | undefined;
91
- "aria-checked"?: boolean | "false" | "mixed" | "true" | undefined | undefined;
92
- "aria-colcount"?: number | undefined | undefined;
93
- "aria-colindex"?: number | undefined | undefined;
94
- "aria-colindextext"?: string | undefined | undefined;
95
- "aria-colspan"?: number | undefined | undefined;
96
- "aria-controls"?: string | undefined | undefined;
97
- "aria-current"?: boolean | "false" | "true" | "page" | "step" | "location" | "date" | "time" | undefined | undefined;
98
- "aria-describedby"?: string | undefined | undefined;
99
- "aria-description"?: string | undefined | undefined;
100
- "aria-details"?: string | undefined | undefined;
101
- "aria-disabled"?: (boolean | "true" | "false") | undefined;
102
- "aria-dropeffect"?: "none" | "copy" | "execute" | "link" | "move" | "popup" | undefined | undefined;
103
- "aria-errormessage"?: string | undefined | undefined;
104
- "aria-expanded"?: (boolean | "true" | "false") | undefined;
105
- "aria-flowto"?: string | undefined | undefined;
106
- "aria-grabbed"?: (boolean | "true" | "false") | undefined;
107
- "aria-haspopup"?: boolean | "false" | "true" | "menu" | "listbox" | "tree" | "grid" | "dialog" | undefined | undefined;
108
- "aria-hidden"?: (boolean | "true" | "false") | undefined;
109
- "aria-invalid"?: boolean | "false" | "true" | "grammar" | "spelling" | undefined | undefined;
110
- "aria-keyshortcuts"?: string | undefined | undefined;
111
- "aria-label"?: string | undefined | undefined;
112
- "aria-labelledby"?: string | undefined | undefined;
113
- "aria-level"?: number | undefined | undefined;
114
- "aria-live"?: "off" | "assertive" | "polite" | undefined | undefined;
115
- "aria-modal"?: (boolean | "true" | "false") | undefined;
116
- "aria-multiline"?: (boolean | "true" | "false") | undefined;
117
- "aria-multiselectable"?: (boolean | "true" | "false") | undefined;
118
- "aria-orientation"?: "horizontal" | "vertical" | undefined | undefined;
119
- "aria-owns"?: string | undefined | undefined;
120
- "aria-placeholder"?: string | undefined | undefined;
121
- "aria-posinset"?: number | undefined | undefined;
122
- "aria-pressed"?: boolean | "false" | "mixed" | "true" | undefined | undefined;
123
- "aria-readonly"?: (boolean | "true" | "false") | undefined;
124
- "aria-relevant"?: "additions" | "additions removals" | "additions text" | "all" | "removals" | "removals additions" | "removals text" | "text" | "text additions" | "text removals" | undefined | undefined;
125
- "aria-required"?: (boolean | "true" | "false") | undefined;
126
- "aria-roledescription"?: string | undefined | undefined;
127
- "aria-rowcount"?: number | undefined | undefined;
128
- "aria-rowindex"?: number | undefined | undefined;
129
- "aria-rowindextext"?: string | undefined | undefined;
130
- "aria-rowspan"?: number | undefined | undefined;
131
- "aria-selected"?: (boolean | "true" | "false") | undefined;
132
- "aria-setsize"?: number | undefined | undefined;
133
- "aria-sort"?: "none" | "ascending" | "descending" | "other" | undefined | undefined;
134
- "aria-valuemax"?: number | undefined | undefined;
135
- "aria-valuemin"?: number | undefined | undefined;
136
- "aria-valuenow"?: number | undefined | undefined;
137
- "aria-valuetext"?: string | undefined | undefined;
138
- onCopy?: import("react").ClipboardEventHandler<HTMLImageElement> | undefined;
139
- onCopyCapture?: import("react").ClipboardEventHandler<HTMLImageElement> | undefined;
140
- onCut?: import("react").ClipboardEventHandler<HTMLImageElement> | undefined;
141
- onCutCapture?: import("react").ClipboardEventHandler<HTMLImageElement> | undefined;
142
- onPaste?: import("react").ClipboardEventHandler<HTMLImageElement> | undefined;
143
- onPasteCapture?: import("react").ClipboardEventHandler<HTMLImageElement> | undefined;
144
- onCompositionEnd?: import("react").CompositionEventHandler<HTMLImageElement> | undefined;
145
- onCompositionEndCapture?: import("react").CompositionEventHandler<HTMLImageElement> | undefined;
146
- onCompositionStart?: import("react").CompositionEventHandler<HTMLImageElement> | undefined;
147
- onCompositionStartCapture?: import("react").CompositionEventHandler<HTMLImageElement> | undefined;
148
- onCompositionUpdate?: import("react").CompositionEventHandler<HTMLImageElement> | undefined;
149
- onCompositionUpdateCapture?: import("react").CompositionEventHandler<HTMLImageElement> | undefined;
150
- onFocus?: import("react").FocusEventHandler<HTMLImageElement> | undefined;
151
- onFocusCapture?: import("react").FocusEventHandler<HTMLImageElement> | undefined;
152
- onBlur?: import("react").FocusEventHandler<HTMLImageElement> | undefined;
153
- onBlurCapture?: import("react").FocusEventHandler<HTMLImageElement> | undefined;
154
- onChange?: import("react").ChangeEventHandler<HTMLImageElement, Element> | undefined;
155
- onChangeCapture?: import("react").ChangeEventHandler<HTMLImageElement, Element> | undefined;
156
- onBeforeInput?: import("react").InputEventHandler<HTMLImageElement> | undefined;
157
- onBeforeInputCapture?: import("react").InputEventHandler<HTMLImageElement> | undefined;
158
- onInput?: import("react").InputEventHandler<HTMLImageElement> | undefined;
159
- onInputCapture?: import("react").InputEventHandler<HTMLImageElement> | undefined;
160
- onReset?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
161
- onResetCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
162
- onSubmit?: import("react").SubmitEventHandler<HTMLImageElement> | undefined;
163
- onSubmitCapture?: import("react").SubmitEventHandler<HTMLImageElement> | undefined;
164
- onInvalid?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
165
- onInvalidCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
166
- onLoad?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
167
- onLoadCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
168
- onError?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
169
- onErrorCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
170
- onKeyDown?: import("react").KeyboardEventHandler<HTMLImageElement> | undefined;
171
- onKeyDownCapture?: import("react").KeyboardEventHandler<HTMLImageElement> | undefined;
172
- onKeyPress?: import("react").KeyboardEventHandler<HTMLImageElement> | undefined;
173
- onKeyPressCapture?: import("react").KeyboardEventHandler<HTMLImageElement> | undefined;
174
- onKeyUp?: import("react").KeyboardEventHandler<HTMLImageElement> | undefined;
175
- onKeyUpCapture?: import("react").KeyboardEventHandler<HTMLImageElement> | undefined;
176
- onAbort?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
177
- onAbortCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
178
- onCanPlay?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
179
- onCanPlayCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
180
- onCanPlayThrough?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
181
- onCanPlayThroughCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
182
- onDurationChange?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
183
- onDurationChangeCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
184
- onEmptied?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
185
- onEmptiedCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
186
- onEncrypted?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
187
- onEncryptedCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
188
- onEnded?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
189
- onEndedCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
190
- onLoadedData?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
191
- onLoadedDataCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
192
- onLoadedMetadata?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
193
- onLoadedMetadataCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
194
- onLoadStart?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
195
- onLoadStartCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
196
- onPause?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
197
- onPauseCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
198
- onPlay?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
199
- onPlayCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
200
- onPlaying?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
201
- onPlayingCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
202
- onProgress?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
203
- onProgressCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
204
- onRateChange?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
205
- onRateChangeCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
206
- onSeeked?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
207
- onSeekedCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
208
- onSeeking?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
209
- onSeekingCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
210
- onStalled?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
211
- onStalledCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
212
- onSuspend?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
213
- onSuspendCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
214
- onTimeUpdate?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
215
- onTimeUpdateCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
216
- onVolumeChange?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
217
- onVolumeChangeCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
218
- onWaiting?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
219
- onWaitingCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
220
- onAuxClick?: import("react").MouseEventHandler<HTMLImageElement> | undefined;
221
- onAuxClickCapture?: import("react").MouseEventHandler<HTMLImageElement> | undefined;
222
- onClick?: import("react").MouseEventHandler<HTMLImageElement> | undefined;
223
- onClickCapture?: import("react").MouseEventHandler<HTMLImageElement> | undefined;
224
- onContextMenu?: import("react").MouseEventHandler<HTMLImageElement> | undefined;
225
- onContextMenuCapture?: import("react").MouseEventHandler<HTMLImageElement> | undefined;
226
- onDoubleClick?: import("react").MouseEventHandler<HTMLImageElement> | undefined;
227
- onDoubleClickCapture?: import("react").MouseEventHandler<HTMLImageElement> | undefined;
228
- onDrag?: import("react").DragEventHandler<HTMLImageElement> | undefined;
229
- onDragCapture?: import("react").DragEventHandler<HTMLImageElement> | undefined;
230
- onDragEnd?: import("react").DragEventHandler<HTMLImageElement> | undefined;
231
- onDragEndCapture?: import("react").DragEventHandler<HTMLImageElement> | undefined;
232
- onDragEnter?: import("react").DragEventHandler<HTMLImageElement> | undefined;
233
- onDragEnterCapture?: import("react").DragEventHandler<HTMLImageElement> | undefined;
234
- onDragExit?: import("react").DragEventHandler<HTMLImageElement> | undefined;
235
- onDragExitCapture?: import("react").DragEventHandler<HTMLImageElement> | undefined;
236
- onDragLeave?: import("react").DragEventHandler<HTMLImageElement> | undefined;
237
- onDragLeaveCapture?: import("react").DragEventHandler<HTMLImageElement> | undefined;
238
- onDragOver?: import("react").DragEventHandler<HTMLImageElement> | undefined;
239
- onDragOverCapture?: import("react").DragEventHandler<HTMLImageElement> | undefined;
240
- onDragStart?: import("react").DragEventHandler<HTMLImageElement> | undefined;
241
- onDragStartCapture?: import("react").DragEventHandler<HTMLImageElement> | undefined;
242
- onDrop?: import("react").DragEventHandler<HTMLImageElement> | undefined;
243
- onDropCapture?: import("react").DragEventHandler<HTMLImageElement> | undefined;
244
- onMouseDown?: import("react").MouseEventHandler<HTMLImageElement> | undefined;
245
- onMouseDownCapture?: import("react").MouseEventHandler<HTMLImageElement> | undefined;
246
- onMouseEnter?: import("react").MouseEventHandler<HTMLImageElement> | undefined;
247
- onMouseLeave?: import("react").MouseEventHandler<HTMLImageElement> | undefined;
248
- onMouseMove?: import("react").MouseEventHandler<HTMLImageElement> | undefined;
249
- onMouseMoveCapture?: import("react").MouseEventHandler<HTMLImageElement> | undefined;
250
- onMouseOut?: import("react").MouseEventHandler<HTMLImageElement> | undefined;
251
- onMouseOutCapture?: import("react").MouseEventHandler<HTMLImageElement> | undefined;
252
- onMouseOver?: import("react").MouseEventHandler<HTMLImageElement> | undefined;
253
- onMouseOverCapture?: import("react").MouseEventHandler<HTMLImageElement> | undefined;
254
- onMouseUp?: import("react").MouseEventHandler<HTMLImageElement> | undefined;
255
- onMouseUpCapture?: import("react").MouseEventHandler<HTMLImageElement> | undefined;
256
- onSelect?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
257
- onSelectCapture?: import("react").ReactEventHandler<HTMLImageElement> | undefined;
258
- onTouchCancel?: import("react").TouchEventHandler<HTMLImageElement> | undefined;
259
- onTouchCancelCapture?: import("react").TouchEventHandler<HTMLImageElement> | undefined;
260
- onTouchEnd?: import("react").TouchEventHandler<HTMLImageElement> | undefined;
261
- onTouchEndCapture?: import("react").TouchEventHandler<HTMLImageElement> | undefined;
262
- onTouchMove?: import("react").TouchEventHandler<HTMLImageElement> | undefined;
263
- onTouchMoveCapture?: import("react").TouchEventHandler<HTMLImageElement> | undefined;
264
- onTouchStart?: import("react").TouchEventHandler<HTMLImageElement> | undefined;
265
- onTouchStartCapture?: import("react").TouchEventHandler<HTMLImageElement> | undefined;
266
- onPointerDown?: import("react").PointerEventHandler<HTMLImageElement> | undefined;
267
- onPointerDownCapture?: import("react").PointerEventHandler<HTMLImageElement> | undefined;
268
- onPointerMove?: import("react").PointerEventHandler<HTMLImageElement> | undefined;
269
- onPointerMoveCapture?: import("react").PointerEventHandler<HTMLImageElement> | undefined;
270
- onPointerUp?: import("react").PointerEventHandler<HTMLImageElement> | undefined;
271
- onPointerUpCapture?: import("react").PointerEventHandler<HTMLImageElement> | undefined;
272
- onPointerCancel?: import("react").PointerEventHandler<HTMLImageElement> | undefined;
273
- onPointerCancelCapture?: import("react").PointerEventHandler<HTMLImageElement> | undefined;
274
- onPointerEnter?: import("react").PointerEventHandler<HTMLImageElement> | undefined;
275
- onPointerLeave?: import("react").PointerEventHandler<HTMLImageElement> | undefined;
276
- onPointerOver?: import("react").PointerEventHandler<HTMLImageElement> | undefined;
277
- onPointerOverCapture?: import("react").PointerEventHandler<HTMLImageElement> | undefined;
278
- onPointerOut?: import("react").PointerEventHandler<HTMLImageElement> | undefined;
279
- onPointerOutCapture?: import("react").PointerEventHandler<HTMLImageElement> | undefined;
280
- onGotPointerCapture?: import("react").PointerEventHandler<HTMLImageElement> | undefined;
281
- onGotPointerCaptureCapture?: import("react").PointerEventHandler<HTMLImageElement> | undefined;
282
- onLostPointerCapture?: import("react").PointerEventHandler<HTMLImageElement> | undefined;
283
- onLostPointerCaptureCapture?: import("react").PointerEventHandler<HTMLImageElement> | undefined;
284
- onScroll?: import("react").UIEventHandler<HTMLImageElement> | undefined;
285
- onScrollCapture?: import("react").UIEventHandler<HTMLImageElement> | undefined;
286
- onScrollEnd?: import("react").UIEventHandler<HTMLImageElement> | undefined;
287
- onScrollEndCapture?: import("react").UIEventHandler<HTMLImageElement> | undefined;
288
- onWheel?: import("react").WheelEventHandler<HTMLImageElement> | undefined;
289
- onWheelCapture?: import("react").WheelEventHandler<HTMLImageElement> | undefined;
290
- onAnimationStart?: import("react").AnimationEventHandler<HTMLImageElement> | undefined;
291
- onAnimationStartCapture?: import("react").AnimationEventHandler<HTMLImageElement> | undefined;
292
- onAnimationEnd?: import("react").AnimationEventHandler<HTMLImageElement> | undefined;
293
- onAnimationEndCapture?: import("react").AnimationEventHandler<HTMLImageElement> | undefined;
294
- onAnimationIteration?: import("react").AnimationEventHandler<HTMLImageElement> | undefined;
295
- onAnimationIterationCapture?: import("react").AnimationEventHandler<HTMLImageElement> | undefined;
296
- onToggle?: import("react").ToggleEventHandler<HTMLImageElement> | undefined;
297
- onBeforeToggle?: import("react").ToggleEventHandler<HTMLImageElement> | undefined;
298
- onTransitionCancel?: import("react").TransitionEventHandler<HTMLImageElement> | undefined;
299
- onTransitionCancelCapture?: import("react").TransitionEventHandler<HTMLImageElement> | undefined;
300
- onTransitionEnd?: import("react").TransitionEventHandler<HTMLImageElement> | undefined;
301
- onTransitionEndCapture?: import("react").TransitionEventHandler<HTMLImageElement> | undefined;
302
- onTransitionRun?: import("react").TransitionEventHandler<HTMLImageElement> | undefined;
303
- onTransitionRunCapture?: import("react").TransitionEventHandler<HTMLImageElement> | undefined;
304
- onTransitionStart?: import("react").TransitionEventHandler<HTMLImageElement> | undefined;
305
- onTransitionStartCapture?: import("react").TransitionEventHandler<HTMLImageElement> | undefined;
306
- src: string;
307
- alt: string;
308
- }, HTMLElement>;
14
+ export declare function Image({ image, value, ...attrs }: ImageProps): import("react").DetailedReactHTMLElement<import("../types/image.js").ImageAttrs, HTMLElement>;
309
15
  export interface LinkProps {
310
16
  link: LinkData;
311
17
  resolveLink?: (link: LinkData) => string | Promise<string>;
@@ -14,13 +14,6 @@ export function Image({ image, value, ...attrs }) {
14
14
  alt: '',
15
15
  sources: [],
16
16
  };
17
- if (!resolved.sources[0]?.src) {
18
- return createElement('img', {
19
- src: '',
20
- alt: resolved.alt,
21
- ...attrs,
22
- });
23
- }
24
17
  return createElement('img', imageAttrs(resolved, attrs));
25
18
  }
26
19
  export function Link({ link, resolveLink, children }) {
@@ -74,5 +74,9 @@ export declare function primaryImageSource(image: Image): ImageSource;
74
74
  * serialization. Media-scoped sources need a <picture> wrapper and are not
75
75
  * representable as plain <img> attributes, so srcset/sizes are taken from the
76
76
  * first unscoped source only.
77
+ *
78
+ * Runtime payloads with null, missing, or empty sources (malformed releases)
79
+ * render as a broken image that keeps its alt text instead of throwing and
80
+ * aborting SSR for the whole page.
77
81
  */
78
82
  export declare function imageAttrs(image: Image, overrides?: ImageAttrs): ImageAttrs;
@@ -32,10 +32,18 @@ export function primaryImageSource(image) {
32
32
  * serialization. Media-scoped sources need a <picture> wrapper and are not
33
33
  * representable as plain <img> attributes, so srcset/sizes are taken from the
34
34
  * first unscoped source only.
35
+ *
36
+ * Runtime payloads with null, missing, or empty sources (malformed releases)
37
+ * render as a broken image that keeps its alt text instead of throwing and
38
+ * aborting SSR for the whole page.
35
39
  */
36
40
  export function imageAttrs(image, overrides = {}) {
37
- const primary = image.sources[0];
38
- const unscoped = image.sources.find((s) => !s.media) ?? primary;
41
+ const sources = Array.isArray(image.sources) ? image.sources : [];
42
+ const primary = sources[0];
43
+ if (!primary?.src) {
44
+ return { src: '', alt: image.alt, ...overrides };
45
+ }
46
+ const unscoped = sources.find((s) => !s.media) ?? primary;
39
47
  return {
40
48
  src: primary.src,
41
49
  alt: image.alt,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gradial/aci",
3
- "version": "0.2.0-canary.730",
3
+ "version": "0.2.0-canary.737",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/gradial/bare-metal-go.git",
@@ -179,11 +179,11 @@
179
179
  "astro": "^6.4.8"
180
180
  },
181
181
  "optionalDependencies": {
182
- "@gradial/aci-cli-darwin-arm64": "0.2.0-canary.730",
183
- "@gradial/aci-cli-darwin-x64": "0.2.0-canary.730",
184
- "@gradial/aci-cli-linux-arm64": "0.2.0-canary.730",
185
- "@gradial/aci-cli-linux-x64": "0.2.0-canary.730",
186
- "@gradial/aci-cli-win32-arm64": "0.2.0-canary.730",
187
- "@gradial/aci-cli-win32-x64": "0.2.0-canary.730"
182
+ "@gradial/aci-cli-darwin-arm64": "0.2.0-canary.737",
183
+ "@gradial/aci-cli-darwin-x64": "0.2.0-canary.737",
184
+ "@gradial/aci-cli-linux-arm64": "0.2.0-canary.737",
185
+ "@gradial/aci-cli-linux-x64": "0.2.0-canary.737",
186
+ "@gradial/aci-cli-win32-arm64": "0.2.0-canary.737",
187
+ "@gradial/aci-cli-win32-x64": "0.2.0-canary.737"
188
188
  }
189
189
  }
@@ -0,0 +1,63 @@
1
+ import assert from 'node:assert/strict';
2
+ import test from 'node:test';
3
+ import { createElement } from 'react';
4
+ import { renderToStaticMarkup } from 'react-dom/server';
5
+
6
+ import { Image as ImageComponent, Picture } from '../react/index.js';
7
+ import { imageAttrs, type Image } from './image.js';
8
+
9
+ function image(sources: unknown): Image {
10
+ return {
11
+ $type: 'gradial.image',
12
+ assetId: 'ast_1',
13
+ versionId: 'v1',
14
+ alt: 'Hero',
15
+ sources,
16
+ } as Image;
17
+ }
18
+
19
+ test('imageAttrs derives attributes from the primary source', () => {
20
+ const attrs = imageAttrs(
21
+ image([{ src: '/hero.webp', width: 1200, height: 800, type: 'image/webp' }]),
22
+ { loading: 'eager' },
23
+ );
24
+
25
+ assert.deepEqual(attrs, {
26
+ src: '/hero.webp',
27
+ alt: 'Hero',
28
+ width: 1200,
29
+ height: 800,
30
+ srcSet: undefined,
31
+ sizes: undefined,
32
+ loading: 'eager',
33
+ decoding: 'async',
34
+ });
35
+ });
36
+
37
+ for (const [name, sources] of [
38
+ ['null', null],
39
+ ['missing', undefined],
40
+ ['empty', []],
41
+ ['srcless', [{ src: '' }]],
42
+ ] as const) {
43
+ test(`imageAttrs falls back to a broken image when sources are ${name}`, () => {
44
+ assert.deepEqual(imageAttrs(image(sources), { className: 'hero' }), {
45
+ src: '',
46
+ alt: 'Hero',
47
+ className: 'hero',
48
+ });
49
+ });
50
+ }
51
+
52
+ test('React image components render alt text instead of aborting SSR on null sources', () => {
53
+ const html = renderToStaticMarkup(
54
+ createElement(
55
+ 'main',
56
+ null,
57
+ createElement(Picture, { image: image(null) }),
58
+ createElement(ImageComponent, { image: image(null) }),
59
+ ),
60
+ );
61
+
62
+ assert.equal(html, '<main><img alt="Hero"/><img alt="Hero"/></main>');
63
+ });
@@ -104,10 +104,18 @@ export function primaryImageSource(image: Image): ImageSource {
104
104
  * serialization. Media-scoped sources need a <picture> wrapper and are not
105
105
  * representable as plain <img> attributes, so srcset/sizes are taken from the
106
106
  * first unscoped source only.
107
+ *
108
+ * Runtime payloads with null, missing, or empty sources (malformed releases)
109
+ * render as a broken image that keeps its alt text instead of throwing and
110
+ * aborting SSR for the whole page.
107
111
  */
108
112
  export function imageAttrs(image: Image, overrides: ImageAttrs = {}): ImageAttrs {
109
- const primary = image.sources[0];
110
- const unscoped = image.sources.find((s) => !s.media) ?? primary;
113
+ const sources: ImageSource[] = Array.isArray(image.sources) ? image.sources : [];
114
+ const primary = sources[0];
115
+ if (!primary?.src) {
116
+ return { src: '', alt: image.alt, ...overrides };
117
+ }
118
+ const unscoped = sources.find((s) => !s.media) ?? primary;
111
119
 
112
120
  return {
113
121
  src: primary.src,
@@ -2,14 +2,14 @@ import { defineComponentContract } from '@gradial/aci';
2
2
  import { z } from 'zod';
3
3
 
4
4
  export const schema = z.object({
5
- label: z.string().min(1),
6
- href: z.string().min(1),
7
- variant: z.enum(['primary', 'secondary', 'outline', 'tertiary']).optional(),
8
- newWindow: z.boolean().optional(),
9
- icon: z.string().optional(),
10
- iconPosition: z.enum(['before', 'after']).optional(),
11
- className: z.string().optional(),
12
- });
5
+ label: z.string().min(1).describe('Visible button text.'),
6
+ href: z.string().min(1).describe('Destination opened by the button.'),
7
+ variant: z.enum(['primary', 'secondary', 'outline', 'tertiary']).optional().describe('Visual emphasis of the button.'),
8
+ newWindow: z.boolean().optional().describe('Whether the destination opens in a new browser tab.'),
9
+ icon: z.string().optional().describe('Optional icon name displayed with the label.'),
10
+ iconPosition: z.enum(['before', 'after']).optional().describe('Place the icon before or after the visible label.'),
11
+ className: z.string().optional().describe('Additional presentation classes supplied by the site implementation.'),
12
+ }).describe('An inline call-to-action control for navigation or actions.');
13
13
 
14
14
  export type ContentProps = z.infer<typeof schema>;
15
15
 
@@ -1,14 +1,16 @@
1
1
  import { defineComponentContract, ImageSchema } from '@gradial/aci';
2
2
  import { z } from 'zod';
3
3
 
4
- export const schema = z.object({
5
- eyebrow: z.string().optional(),
6
- headline: z.string().min(1),
7
- description: z.string().optional(),
8
- ctaLabel: z.string().min(1),
9
- ctaHref: z.string().min(1),
10
- image: ImageSchema.optional(),
11
- });
4
+ export const schema = z
5
+ .object({
6
+ eyebrow: z.string().optional().describe('Short context shown above the main headline.'),
7
+ headline: z.string().min(1).describe('The large headline for this hero.'),
8
+ description: z.string().optional().describe('Supporting copy below the hero headline.'),
9
+ ctaLabel: z.string().min(1).describe('Visible label for the hero call to action.'),
10
+ ctaHref: z.string().min(1).describe('Destination for the hero call to action.'),
11
+ image: ImageSchema.optional().describe('Primary visual displayed in the hero.'),
12
+ })
13
+ .describe('A large page-leading hero with a headline, supporting copy, call to action, and image.');
12
14
 
13
15
  export type ContentProps = z.infer<typeof schema>;
14
16
 
@@ -314,6 +314,35 @@ template and republish.
314
314
  - `props` must validate against the contract's Zod schema.
315
315
  - `id` is unique within the page.
316
316
 
317
+ ### Resolve the Target Before Editing
318
+
319
+ When a request uses a visual term such as "hero", "banner", or "top card",
320
+ do not select a component from its name alone. Read the page document first
321
+ and identify the block using all available evidence:
322
+
323
+ 1. its order in the requested region (for example, the first block in `main`),
324
+ 2. its current visible copy or asset,
325
+ 3. its component description in the current site's schema, and
326
+ 4. its stable block `id`.
327
+
328
+ Use the schema for the site you are editing. For local authoring, run
329
+ `aci schemas compile` after changing contracts and read
330
+ `.aci/schemas/<component-id>.schema.json`. For a remote branch, read
331
+ `/patterns/components/<component-id>.json` from that branch; its `schema`
332
+ comes from the linked code build. Seeded `.content/patterns` files are starter
333
+ examples and can differ from the local framework's contracts.
334
+
335
+ After selecting the block, read `properties.<field>.description` in that
336
+ schema to identify which property controls the requested content. Follow
337
+ `properties` and `items` for nested fields. Use the same current schema for
338
+ types, required fields, and allowed enum values; descriptions explain what
339
+ those fields mean.
340
+
341
+ If two blocks still match, ask which current copy the user means before
342
+ writing. After the write, verify the selected block's props and its rendered
343
+ region. A successful page render alone does not prove that the requested block
344
+ changed.
345
+
317
346
  ### Nested Blocks
318
347
 
319
348
  Components that accept child blocks use `blockRef()` in their Zod schema
@@ -402,7 +431,7 @@ The `button` component is a common atomic block:
402
431
  ```
403
432
 
404
433
  - `label` and `href` are required.
405
- - `variant`: `primary` | `secondary` | `outline` | `tertiary`
434
+ - Read the current site's schema for the supported optional properties and values.
406
435
  - `icon`: a registered icon name.
407
436
  - `iconPosition`: `before` | `after`
408
437
  - `newWindow`: boolean for `target="_blank"`.
@@ -574,16 +603,16 @@ import { defineComponentContract, ImageSchema } from '@gradial/aci';
574
603
  import { z } from 'zod';
575
604
 
576
605
  export const schema = z.object({
577
- headline: z.string().min(1),
578
- description: z.string().optional(),
579
- image: ImageSchema,
606
+ headline: z.string().min(1).describe('The prominent heading shown in this section.'),
607
+ description: z.string().optional().describe('Supporting copy below the heading.'),
608
+ image: ImageSchema.describe('Primary visual for the feature section.'),
580
609
  features: z.array(z.object({
581
- title: z.string().min(1),
582
- description: z.string().min(1),
583
- })).optional(),
584
- ctaLabel: z.string().optional(),
585
- ctaHref: z.string().optional(),
586
- });
610
+ title: z.string().min(1).describe('Visible feature heading.'),
611
+ description: z.string().min(1).describe('Supporting copy for this feature.'),
612
+ })).optional().describe('Features in display order.'),
613
+ ctaLabel: z.string().optional().describe('Visible call-to-action text.'),
614
+ ctaHref: z.string().optional().describe('Call-to-action destination.'),
615
+ }).describe('A visual feature section with a heading, image, and optional call to action.');
587
616
 
588
617
  export type ContentProps = z.infer<typeof schema>;
589
618
 
@@ -602,6 +631,14 @@ export const featureShowcaseContract = defineComponentContract({
602
631
  });
603
632
  ```
604
633
 
634
+ Use `.describe()` on the root schema and authorable properties. Describe what
635
+ the component is for, not where one current page happens to place it. For enum
636
+ properties, explain the choices in the field's `.describe()` text just as
637
+ you describe a string or boolean field. Apply `.describe()` after wrappers
638
+ such as `.optional()`. The compiler preserves this text as the JSON Schema
639
+ `description` on that same node; there is no separate variant metadata
640
+ contract.
641
+
605
642
  #### 2. Export from the barrel
606
643
 
607
644
  ```ts
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$type": "componentPattern",
3
- "buildId": "codebuild_01a0d03d-1243-7f49-9ead-8599ed577882",
4
- "codeDigest": "sha256:44327370dc42bcabe39daf8b86fca1fe191e19dbd8dd39db71df2109c11b3635",
3
+ "buildId": "codebuild_01a152b2-8852-77b5-8f8e-10572e514e1b",
4
+ "codeDigest": "sha256:5d9649ecaf81a6e4fca7affb148db77419b602732acbb8985e98f52022f4e349",
5
5
  "name": "button",
6
6
  "schema": {
7
7
  "$schema": "https://json-schema.org/draft/2020-12/schema",
@@ -10,13 +10,16 @@
10
10
  "properties": {
11
11
  "label": {
12
12
  "type": "string",
13
- "minLength": 1
13
+ "minLength": 1,
14
+ "description": "Visible button text."
14
15
  },
15
16
  "href": {
16
17
  "type": "string",
17
- "minLength": 1
18
+ "minLength": 1,
19
+ "description": "Destination opened by the button."
18
20
  },
19
21
  "variant": {
22
+ "description": "Visual emphasis of the button.",
20
23
  "type": "string",
21
24
  "enum": [
22
25
  "primary",
@@ -27,12 +30,15 @@
27
30
  ]
28
31
  },
29
32
  "newWindow": {
33
+ "description": "Whether the destination opens in a new browser tab.",
30
34
  "type": "boolean"
31
35
  },
32
36
  "icon": {
37
+ "description": "Optional icon name displayed with the label.",
33
38
  "type": "string"
34
39
  },
35
40
  "iconPosition": {
41
+ "description": "Place the icon before or after the visible label.",
36
42
  "type": "string",
37
43
  "enum": [
38
44
  "before",
@@ -40,6 +46,7 @@
40
46
  ]
41
47
  },
42
48
  "className": {
49
+ "description": "Additional presentation classes supplied by the site implementation.",
43
50
  "type": "string"
44
51
  }
45
52
  },
@@ -47,7 +54,8 @@
47
54
  "label",
48
55
  "href"
49
56
  ],
50
- "additionalProperties": false
57
+ "additionalProperties": false,
58
+ "description": "An inline call-to-action control for navigation or actions."
51
59
  },
52
60
  "imageSlots": {},
53
61
  "notes": "",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$type": "componentPattern",
3
- "buildId": "codebuild_01a0d03d-1243-7f49-9ead-8599ed577882",
4
- "codeDigest": "sha256:44327370dc42bcabe39daf8b86fca1fe191e19dbd8dd39db71df2109c11b3635",
3
+ "buildId": "codebuild_01a152b2-8852-77b5-8f8e-10572e514e1b",
4
+ "codeDigest": "sha256:5d9649ecaf81a6e4fca7affb148db77419b602732acbb8985e98f52022f4e349",
5
5
  "name": "container",
6
6
  "schema": {
7
7
  "$schema": "https://json-schema.org/draft/2020-12/schema",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$type": "componentPattern",
3
- "buildId": "codebuild_01a0d03d-1243-7f49-9ead-8599ed577882",
4
- "codeDigest": "sha256:44327370dc42bcabe39daf8b86fca1fe191e19dbd8dd39db71df2109c11b3635",
3
+ "buildId": "codebuild_01a152b2-8852-77b5-8f8e-10572e514e1b",
4
+ "codeDigest": "sha256:5d9649ecaf81a6e4fca7affb148db77419b602732acbb8985e98f52022f4e349",
5
5
  "name": "feature_card",
6
6
  "schema": {
7
7
  "$schema": "https://json-schema.org/draft/2020-12/schema",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$type": "componentPattern",
3
- "buildId": "codebuild_01a0d03d-1243-7f49-9ead-8599ed577882",
4
- "codeDigest": "sha256:44327370dc42bcabe39daf8b86fca1fe191e19dbd8dd39db71df2109c11b3635",
3
+ "buildId": "codebuild_01a152b2-8852-77b5-8f8e-10572e514e1b",
4
+ "codeDigest": "sha256:5d9649ecaf81a6e4fca7affb148db77419b602732acbb8985e98f52022f4e349",
5
5
  "name": "feature_grid",
6
6
  "schema": {
7
7
  "$schema": "https://json-schema.org/draft/2020-12/schema",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$type": "componentPattern",
3
- "buildId": "codebuild_01a0d03d-1243-7f49-9ead-8599ed577882",
4
- "codeDigest": "sha256:44327370dc42bcabe39daf8b86fca1fe191e19dbd8dd39db71df2109c11b3635",
3
+ "buildId": "codebuild_01a152b2-8852-77b5-8f8e-10572e514e1b",
4
+ "codeDigest": "sha256:5d9649ecaf81a6e4fca7affb148db77419b602732acbb8985e98f52022f4e349",
5
5
  "name": "home_hero",
6
6
  "schema": {
7
7
  "$schema": "https://json-schema.org/draft/2020-12/schema",
@@ -9,24 +9,30 @@
9
9
  "type": "object",
10
10
  "properties": {
11
11
  "eyebrow": {
12
+ "description": "Short context shown above the main headline.",
12
13
  "type": "string"
13
14
  },
14
15
  "headline": {
15
16
  "type": "string",
16
- "minLength": 1
17
+ "minLength": 1,
18
+ "description": "The large headline for this hero."
17
19
  },
18
20
  "description": {
21
+ "description": "Supporting copy below the hero headline.",
19
22
  "type": "string"
20
23
  },
21
24
  "ctaLabel": {
22
25
  "type": "string",
23
- "minLength": 1
26
+ "minLength": 1,
27
+ "description": "Visible label for the hero call to action."
24
28
  },
25
29
  "ctaHref": {
26
30
  "type": "string",
27
- "minLength": 1
31
+ "minLength": 1,
32
+ "description": "Destination for the hero call to action."
28
33
  },
29
34
  "image": {
35
+ "description": "Primary visual displayed in the hero.",
30
36
  "type": "object",
31
37
  "properties": {
32
38
  "$type": {
@@ -102,10 +108,10 @@
102
108
  "required": [
103
109
  "headline",
104
110
  "ctaLabel",
105
- "ctaHref",
106
- "image"
111
+ "ctaHref"
107
112
  ],
108
- "additionalProperties": false
113
+ "additionalProperties": false,
114
+ "description": "A large page-leading hero with a headline, supporting copy, call to action, and image."
109
115
  },
110
116
  "imageSlots": {
111
117
  "image": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$type": "componentPattern",
3
- "buildId": "codebuild_01a0d03d-1243-7f49-9ead-8599ed577882",
4
- "codeDigest": "sha256:44327370dc42bcabe39daf8b86fca1fe191e19dbd8dd39db71df2109c11b3635",
3
+ "buildId": "codebuild_01a152b2-8852-77b5-8f8e-10572e514e1b",
4
+ "codeDigest": "sha256:5d9649ecaf81a6e4fca7affb148db77419b602732acbb8985e98f52022f4e349",
5
5
  "name": "personalization_choice",
6
6
  "schema": {
7
7
  "$schema": "https://json-schema.org/draft/2020-12/schema",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$type": "componentPattern",
3
- "buildId": "codebuild_01a0d03d-1243-7f49-9ead-8599ed577882",
4
- "codeDigest": "sha256:44327370dc42bcabe39daf8b86fca1fe191e19dbd8dd39db71df2109c11b3635",
3
+ "buildId": "codebuild_01a152b2-8852-77b5-8f8e-10572e514e1b",
4
+ "codeDigest": "sha256:5d9649ecaf81a6e4fca7affb148db77419b602732acbb8985e98f52022f4e349",
5
5
  "name": "site-footer",
6
6
  "schema": {
7
7
  "$schema": "https://json-schema.org/draft/2020-12/schema",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$type": "componentPattern",
3
- "buildId": "codebuild_01a0d03d-1243-7f49-9ead-8599ed577882",
4
- "codeDigest": "sha256:44327370dc42bcabe39daf8b86fca1fe191e19dbd8dd39db71df2109c11b3635",
3
+ "buildId": "codebuild_01a152b2-8852-77b5-8f8e-10572e514e1b",
4
+ "codeDigest": "sha256:5d9649ecaf81a6e4fca7affb148db77419b602732acbb8985e98f52022f4e349",
5
5
  "name": "site-navigation",
6
6
  "schema": {
7
7
  "$schema": "https://json-schema.org/draft/2020-12/schema",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$type": "componentPattern",
3
- "buildId": "codebuild_01a0d03d-1243-7f49-9ead-8599ed577882",
4
- "codeDigest": "sha256:44327370dc42bcabe39daf8b86fca1fe191e19dbd8dd39db71df2109c11b3635",
3
+ "buildId": "codebuild_01a152b2-8852-77b5-8f8e-10572e514e1b",
4
+ "codeDigest": "sha256:5d9649ecaf81a6e4fca7affb148db77419b602732acbb8985e98f52022f4e349",
5
5
  "name": "stats_bar",
6
6
  "schema": {
7
7
  "$schema": "https://json-schema.org/draft/2020-12/schema",
@@ -2,14 +2,14 @@ import { defineComponentContract } from '@gradial/aci';
2
2
  import { z } from 'zod';
3
3
 
4
4
  export const schema = z.object({
5
- label: z.string().min(1),
6
- href: z.string().min(1),
7
- variant: z.enum(['primary', 'secondary', 'tertiary', 'outline', 'ghost']).optional(),
8
- newWindow: z.boolean().optional(),
9
- icon: z.string().optional(),
10
- iconPosition: z.enum(['before', 'after']).optional(),
11
- className: z.string().optional(),
12
- });
5
+ label: z.string().min(1).describe('Visible button text.'),
6
+ href: z.string().min(1).describe('Destination opened by the button.'),
7
+ variant: z.enum(['primary', 'secondary', 'tertiary', 'outline', 'ghost']).optional().describe('Visual emphasis of the button.'),
8
+ newWindow: z.boolean().optional().describe('Whether the destination opens in a new browser tab.'),
9
+ icon: z.string().optional().describe('Optional icon name displayed with the label.'),
10
+ iconPosition: z.enum(['before', 'after']).optional().describe('Place the icon before or after the visible label.'),
11
+ className: z.string().optional().describe('Additional presentation classes supplied by the site implementation.'),
12
+ }).describe('An inline call-to-action control for navigation or actions.');
13
13
 
14
14
  export type ContentProps = z.infer<typeof schema>;
15
15
 
@@ -1,14 +1,16 @@
1
1
  import { defineComponentContract, ImageSchema } from '@gradial/aci';
2
2
  import { z } from 'zod';
3
3
 
4
- export const schema = z.object({
5
- eyebrow: z.string().optional(),
6
- headline: z.string().min(1),
7
- description: z.string().optional(),
8
- ctaLabel: z.string().min(1),
9
- ctaHref: z.string().min(1),
10
- image: ImageSchema,
11
- });
4
+ export const schema = z
5
+ .object({
6
+ eyebrow: z.string().optional().describe('Short context shown above the main headline.'),
7
+ headline: z.string().min(1).describe('The large headline for this hero.'),
8
+ description: z.string().optional().describe('Supporting copy below the hero headline.'),
9
+ ctaLabel: z.string().min(1).describe('Visible label for the hero call to action.'),
10
+ ctaHref: z.string().min(1).describe('Destination for the hero call to action.'),
11
+ image: ImageSchema.optional().describe('Primary visual displayed in the hero.'),
12
+ })
13
+ .describe('A large page-leading hero with a headline, supporting copy, call to action, and image.');
12
14
 
13
15
  export type ContentProps = z.infer<typeof schema>;
14
16