@contentful/experience-design-system-generation 2.26.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.
- package/LICENSE +21 -0
- package/dist/package.json +57 -0
- package/dist/src/agent-invoker.d.ts +24 -0
- package/dist/src/agent-invoker.js +13 -0
- package/dist/src/agent-names.d.ts +4 -0
- package/dist/src/agent-names.js +5 -0
- package/dist/src/agent-runner.d.ts +127 -0
- package/dist/src/agent-runner.js +420 -0
- package/dist/src/index.d.ts +9 -0
- package/dist/src/index.js +10 -0
- package/dist/src/progress.d.ts +9 -0
- package/dist/src/progress.js +11 -0
- package/dist/src/prompt-builder.d.ts +32 -0
- package/dist/src/prompt-builder.js +204 -0
- package/package.json +56 -0
- package/skills/generate-components.md +427 -0
- package/skills/generate-tokens.md +194 -0
- package/skills/select-components.md +224 -0
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
# Analyze Select — Agent Component Selection Skill
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Review the extracted React/Next.js component(s) provided below and decide whether each belongs in **Contentful Experience Orchestration** as a Component Type. The input is a JSON array — you may receive 1–N components in a single message. Output one JSON tool call per input component to stdout, named after the component. Tool calls may appear in any order.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## What is Contentful Experience Orchestration?
|
|
10
|
+
|
|
11
|
+
Contentful Experience Orchestration is a Contentful product that enables **designers, developers, and marketers** to compose and manage digital experiences in Contentful. Component Types are used at every layer of the design system:
|
|
12
|
+
|
|
13
|
+
- **Atoms** — low-level UI primitives: icons, buttons, inputs, badges
|
|
14
|
+
- **Molecules** — composed UI units: cards, search fields, modals, navigation items
|
|
15
|
+
- **Organisms** — larger sections: heroes, banners, footers, press release lists, parallax sections
|
|
16
|
+
|
|
17
|
+
All three levels are valid Component Types in Contentful Experience Orchestration. Designers and developers compose atoms into molecules, molecules into organisms. Marketers then configure content and design values on any of these.
|
|
18
|
+
|
|
19
|
+
The entity being defined — a **Component Type** — is the schema that tells Contentful what is configurable for this component. It defines design properties, content properties, and slots. Even a component with only a few configurable props is a valid Component Type.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## The one rule: is this the author-facing UI component?
|
|
24
|
+
|
|
25
|
+
**Accept** the component if it is the component that directly defines the author-facing UI surface — regardless of whether it is an atom, molecule, or organism, and regardless of whether it has many or few configurable props. A footer icon with two props (`icon`, `label`) is just as valid as a parallax hero with fifteen props.
|
|
26
|
+
|
|
27
|
+
**Reject** the component if its primary purpose is framework or data-loading infrastructure rather than the author-facing UI surface:
|
|
28
|
+
|
|
29
|
+
- It is a React hook (name starts `use` or `Use`)
|
|
30
|
+
- It is a pure context provider with no visual output
|
|
31
|
+
- It is a Ninetailed/personalization platform wrapper (its job is routing to variants, not rendering content)
|
|
32
|
+
- It is a data-fetch wrapper that loads data for a sibling renderer and then forwards that data into the sibling renderer
|
|
33
|
+
- It is an analytics/event-tracking component (fires events, renders nothing)
|
|
34
|
+
- It is a security or infrastructure utility (no UI at all)
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## What NOT to use as a rejection reason
|
|
39
|
+
|
|
40
|
+
These are **not** valid reasons to reject a component:
|
|
41
|
+
|
|
42
|
+
| Invalid reason | Why it is wrong |
|
|
43
|
+
| -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
|
|
44
|
+
| "Only atoms/low-level" | Atoms are first-class Component Types in Contentful Experience Orchestration |
|
|
45
|
+
| "Tightly coupled to a parent component" | Contentful Experience Orchestration handles composition at the experience layer |
|
|
46
|
+
| "Has A/B testing or personalization-related props" | These props are classified as `state` or excluded in the generate step — their presence does not disqualify the component |
|
|
47
|
+
| "Has no marketer-configurable props" | Marketers are not the only users; designers and developers configure components too |
|
|
48
|
+
| "Domain-specific or feature-level" | Press releases, newsrooms, search — all valid content components |
|
|
49
|
+
| "Server-side or SSR" | Server components that render visible UI are valid |
|
|
50
|
+
| "Few configurable props" | One or two props is fine |
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Reject only these categories
|
|
55
|
+
|
|
56
|
+
| Category | Why |
|
|
57
|
+
| ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
58
|
+
| **React hooks** | `useXxx` / `UseXxx` — functions, not renderable components. Zero visual output. |
|
|
59
|
+
| **Pure context providers** | Wrap children to pass context but render no UI themselves |
|
|
60
|
+
| **A/B testing or personalization wrappers** | Components whose _entire purpose_ is routing users to content variants or tracking experiment participation — they render no UI of their own |
|
|
61
|
+
| **Data-fetch wrappers** | Components whose job is to load or resolve data for a sibling renderer. Even if they eventually return visible UI, the sibling renderer is the real Component Type. |
|
|
62
|
+
| **Analytics and event tracking** | Components that only fire analytics events and render nothing visible |
|
|
63
|
+
| **Security utilities** | Non-visual security primitives with no rendered output |
|
|
64
|
+
|
|
65
|
+
> **Variant routing rule**: Reject a component if its entire purpose is deciding _which_ content variant to show — that is framework infrastructure, not a Component Type. Do **not** reject a component merely because it _contains_ some A/B testing or personalization-related props — those props are handled as `state` in the generate step.
|
|
66
|
+
|
|
67
|
+
> **Data-fetch wrapper rule**: Reject a component if it imports or calls a generated query hook, loads data, and then forwards that data into a sibling renderer. The sibling renderer is the Component Type; the data-loader wrapper is not.
|
|
68
|
+
|
|
69
|
+
> **Utility-wrapper rule**: Reject a component if **all three** of the following are true:
|
|
70
|
+
>
|
|
71
|
+
> 1. It has no props that meaningfully shape user-facing content (no text strings, headings, image URLs, links, body content, rich text, or media references).
|
|
72
|
+
> 2. The props it does have are purely structural or behavioral — e.g., `container`, `target`, `as`, `asChild`, render-prop callbacks, internal `ref` forwarding, focus/portal targets, debug toggles, or `children` only.
|
|
73
|
+
> 3. It is a utility wrapper rather than a composable content surface. Concrete examples to reject under this rule: `Portal`, `SrOnly` (screen-reader-only wrappers), `FocusTrap`, `ErrorBoundary`, `Suspense` fallbacks, debug-only wrappers, and provider-shaped components whose only job is to forward children.
|
|
74
|
+
>
|
|
75
|
+
> Use `reject_component` with a reason like `"Utility wrapper — no authorable content surface"` or `"Structural-only component — no user-shaping props"`. This rule is additive to the categories above; do **not** use it to reject a component that has even one author-shaping prop (e.g., a `label`, `title`, `text`, `href`, `src`, or `richText` prop) — those still belong as Component Types per the "one rule" above.
|
|
76
|
+
|
|
77
|
+
## Using `selectionContext`
|
|
78
|
+
|
|
79
|
+
If the input includes `selectionContext`, treat it as the only repo-level context you may use. It is already bounded to the customer-provided project files and may include:
|
|
80
|
+
|
|
81
|
+
- the component source file
|
|
82
|
+
- sibling files in the same folder
|
|
83
|
+
- import/export summaries
|
|
84
|
+
- resolver or registry references
|
|
85
|
+
- one likely parent usage site
|
|
86
|
+
|
|
87
|
+
Use that bounded context to distinguish the author-facing renderer from infrastructure wrappers. In particular:
|
|
88
|
+
|
|
89
|
+
- If the component imports a sibling renderer and mainly forwards fetched data into it, reject the wrapper and prefer the sibling renderer.
|
|
90
|
+
- If sibling files show a presentation-focused renderer with the real authoring props, that renderer is the Component Type.
|
|
91
|
+
- Resolver or parent-usage references help show how the repo treats the component, but they do not override the renderer-vs-wrapper rule.
|
|
92
|
+
- Do not assume access to any files outside `selectionContext`.
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Output protocol
|
|
97
|
+
|
|
98
|
+
Emit one JSON object on a single line. Lines not starting with `{` are ignored by the parser — use them freely for reasoning.
|
|
99
|
+
|
|
100
|
+
**Two tool calls — emit exactly one per input component:**
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
{"tool":"select_component","name":"<ComponentName>","reason":"<brief reason>","confidence":<1-5>}
|
|
104
|
+
|
|
105
|
+
{"tool":"reject_component","name":"<ComponentName>","reason":"<brief reason>","confidence":<1-5>}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**Rules:**
|
|
109
|
+
|
|
110
|
+
- Emit exactly one JSON object per line. No multi-line JSON. No markdown fences.
|
|
111
|
+
- Emit exactly one tool call per input component. Tool calls may appear in any order.
|
|
112
|
+
- The `name` must match a component name from the input array exactly.
|
|
113
|
+
- `reason` is a brief phrase documenting your decision.
|
|
114
|
+
- `confidence` is your certainty (1–5) that the decision is correct:
|
|
115
|
+
- **5** — obvious case, no doubt (clear UI atom, or clear infrastructure with no visual output)
|
|
116
|
+
- **4** — likely correct, minor ambiguity
|
|
117
|
+
- **3** — uncertain, borderline component (few props, ambiguous purpose, could go either way)
|
|
118
|
+
- **2** — low confidence, guessing
|
|
119
|
+
- **1** — very unsure, human review strongly recommended
|
|
120
|
+
- Emit prose lines (not starting with `{`) to log your reasoning before the final tool call.
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Examples
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
Analytics — fires analytics events, no visual output
|
|
128
|
+
{"tool":"reject_component","name":"Analytics","reason":"analytics tracker — no visual output"}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
CanaryToken — security utility, no visual output
|
|
133
|
+
{"tool":"reject_component","name":"CanaryToken","reason":"security utility — no visual output"}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
```
|
|
137
|
+
ClientExperience — personalization wrapper whose entire purpose is routing users to content variants
|
|
138
|
+
{"tool":"reject_component","name":"ClientExperience","reason":"variant routing wrapper — entire purpose is A/B routing, not rendering UI"}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
ComponentMarker — experimentation marker component, no visual output
|
|
143
|
+
{"tool":"reject_component","name":"ComponentMarker","reason":"experimentation marker — no visual output"}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
ComponentTracker — variant attribution tracker, no visual output
|
|
148
|
+
{"tool":"reject_component","name":"ComponentTracker","reason":"variant attribution tracker — no visual output"}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
Refresh — client-side route refresh utility for personalization platform, no visual output
|
|
153
|
+
{"tool":"reject_component","name":"Refresh","reason":"personalization route refresh utility — no visual output"}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
ServerExperience — server-side variant routing wrapper, no visual output
|
|
158
|
+
{"tool":"reject_component","name":"ServerExperience","reason":"server-side variant routing wrapper — no visual output"}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
UseHelpNavigation — React hook, not a renderable component
|
|
163
|
+
{"tool":"reject_component","name":"UseHelpNavigation","reason":"React hook — not a renderable component"}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
```
|
|
167
|
+
Providers — React context provider with no visual output
|
|
168
|
+
{"tool":"reject_component","name":"Providers","reason":"pure context provider — no visual output"}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
```
|
|
172
|
+
HeroBannerGql — fetch wrapper that loads data and forwards it into HeroBanner
|
|
173
|
+
It may eventually return visible UI, but the author-facing component is HeroBanner, not HeroBannerGql.
|
|
174
|
+
{"tool":"reject_component","name":"HeroBannerGql","reason":"data-fetch wrapper — loads data for a sibling renderer rather than defining the author-facing UI surface"}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
```
|
|
178
|
+
FooterIcon — atom: renders an icon with optional label in the footer
|
|
179
|
+
{"tool":"select_component","name":"FooterIcon","reason":"UI atom — renders icon with configurable icon and label"}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
```
|
|
183
|
+
FeedbackModal — modal dialog with visibility state
|
|
184
|
+
{"tool":"select_component","name":"FeedbackModal","reason":"modal UI component with configurable visibility and content"}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
```
|
|
188
|
+
ActiveFilters — renders active filter chips with remove controls
|
|
189
|
+
{"tool":"select_component","name":"ActiveFilters","reason":"filter UI component — renders visible filter chips"}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
```
|
|
193
|
+
FullSizeBarNoContent — full-width text bar with link; has some personalization state props
|
|
194
|
+
The personalization props (hideContentForPersonalization, componentId) are state props handled in the generate step.
|
|
195
|
+
The component renders real visual UI — a bar with text, chevron, and link.
|
|
196
|
+
{"tool":"select_component","name":"FullSizeBarNoContent","reason":"content bar UI — renders visible bar with configurable text, link, and design"}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
```
|
|
200
|
+
ParallaxComponent — parallax marketing section; has some A/B testing props alongside real content props
|
|
201
|
+
The A/B testing props (abmFallback, abmLinkedFromAccount) are state props, not the component's primary purpose.
|
|
202
|
+
The component renders a parallax section with title, subtitle, and visual effects.
|
|
203
|
+
{"tool":"select_component","name":"ParallaxComponent","reason":"marketing section UI — renders parallax content with configurable title, subtitle, and design"}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
```
|
|
207
|
+
NewsroomLandingPressReleases — press release list with pagination and locale
|
|
208
|
+
{"tool":"select_component","name":"NewsroomLandingPressReleases","reason":"content list UI — renders press releases with configurable locale and pagination"}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
```
|
|
212
|
+
ServerHelpNavigation — server-side navigation with configurable search visibility and locale
|
|
213
|
+
{"tool":"select_component","name":"ServerHelpNavigation","reason":"navigation UI — renders help navigation with configurable locale and search toggle"}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
```
|
|
217
|
+
TextImageCard — card with rich text and background image
|
|
218
|
+
{"tool":"select_component","name":"TextImageCard","reason":"content card UI — configurable rich text, image, and layout"}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
```
|
|
222
|
+
SearchInput — search field with dropdown
|
|
223
|
+
{"tool":"select_component","name":"SearchInput","reason":"search UI — configurable placeholder and state"}
|
|
224
|
+
```
|