@contentful/experience-design-system-generation 2.28.1-dev-build-a917752.0 → 2.28.1-dev-build-2497ca0.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.
- package/dist/package.json +1 -1
- package/dist/src/agent-runner.d.ts +0 -2
- package/dist/src/agent-runner.js +5 -11
- package/package.json +2 -2
- package/skills/generate-components.md +10 -34
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentful/experience-design-system-generation",
|
|
3
|
-
"version": "2.28.1-dev-build-
|
|
3
|
+
"version": "2.28.1-dev-build-2497ca0.0",
|
|
4
4
|
"description": "Agent-invocation and skill-prompt engine for the Contentful Experience Design System SDK",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -86,8 +86,6 @@ export interface ParsedTokenToolCalls {
|
|
|
86
86
|
export interface ParsedToolCalls {
|
|
87
87
|
calls: ToolCall[];
|
|
88
88
|
warnings: string[];
|
|
89
|
-
/** True when a line was lost outright (unparseable, or no `tool` field) — a retry signal, distinct from a parsed-but-rejected call. */
|
|
90
|
-
hadDroppedLine: boolean;
|
|
91
89
|
}
|
|
92
90
|
export declare function parseToolCallLines(stdout: string): ParsedToolCalls;
|
|
93
91
|
export declare function parseTokenToolCallLines(stdout: string): ParsedTokenToolCalls;
|
package/dist/src/agent-runner.js
CHANGED
|
@@ -26,13 +26,12 @@ function findJsonObjectEnd(line) {
|
|
|
26
26
|
return -1;
|
|
27
27
|
}
|
|
28
28
|
/**
|
|
29
|
-
* Reads an agent's stdout into tool-call objects
|
|
30
|
-
* `
|
|
29
|
+
* Reads an agent's stdout into the tool-call objects it carries. Lines that do
|
|
30
|
+
* not start with `{` are the agent's prose and are skipped silently, as before.
|
|
31
31
|
*/
|
|
32
32
|
function readToolCallObjects(stdout) {
|
|
33
33
|
const objects = [];
|
|
34
34
|
const warnings = [];
|
|
35
|
-
let hadDroppedLine = false;
|
|
36
35
|
for (const raw of stdout.split('\n')) {
|
|
37
36
|
const line = raw.trim();
|
|
38
37
|
if (!line.startsWith('{'))
|
|
@@ -40,7 +39,6 @@ function readToolCallObjects(stdout) {
|
|
|
40
39
|
const end = findJsonObjectEnd(line);
|
|
41
40
|
if (end === -1) {
|
|
42
41
|
warnings.push(`unparseable line: ${line.slice(0, 120)}`);
|
|
43
|
-
hadDroppedLine = true;
|
|
44
42
|
continue;
|
|
45
43
|
}
|
|
46
44
|
let parsed;
|
|
@@ -49,7 +47,6 @@ function readToolCallObjects(stdout) {
|
|
|
49
47
|
}
|
|
50
48
|
catch {
|
|
51
49
|
warnings.push(`unparseable line: ${line.slice(0, 120)}`);
|
|
52
|
-
hadDroppedLine = true;
|
|
53
50
|
continue;
|
|
54
51
|
}
|
|
55
52
|
const trailing = line.slice(end + 1);
|
|
@@ -59,11 +56,8 @@ function readToolCallObjects(stdout) {
|
|
|
59
56
|
if (typeof parsed === 'object' && parsed !== null && 'tool' in parsed) {
|
|
60
57
|
objects.push(parsed);
|
|
61
58
|
}
|
|
62
|
-
else {
|
|
63
|
-
hadDroppedLine = true;
|
|
64
|
-
}
|
|
65
59
|
}
|
|
66
|
-
return { objects, warnings
|
|
60
|
+
return { objects, warnings };
|
|
67
61
|
}
|
|
68
62
|
export function parseSelectToolCallLines(stdout) {
|
|
69
63
|
const calls = [];
|
|
@@ -99,7 +93,7 @@ const VALID_CDF_TYPES = new Set(['string', 'richtext', 'media', 'enum', 'token',
|
|
|
99
93
|
const VALID_CATEGORIES = new Set(['content', 'design', 'state']);
|
|
100
94
|
export function parseToolCallLines(stdout) {
|
|
101
95
|
const calls = [];
|
|
102
|
-
const { objects, warnings
|
|
96
|
+
const { objects, warnings } = readToolCallObjects(stdout);
|
|
103
97
|
for (const rec of objects) {
|
|
104
98
|
if (!VALID_TOOL_NAMES.has(rec.tool)) {
|
|
105
99
|
warnings.push(`unknown tool: ${String(rec.tool)}`);
|
|
@@ -187,7 +181,7 @@ export function parseToolCallLines(stdout) {
|
|
|
187
181
|
calls.push(call);
|
|
188
182
|
}
|
|
189
183
|
}
|
|
190
|
-
return { calls, warnings
|
|
184
|
+
return { calls, warnings };
|
|
191
185
|
}
|
|
192
186
|
export function parseTokenToolCallLines(stdout) {
|
|
193
187
|
const calls = [];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentful/experience-design-system-generation",
|
|
3
|
-
"version": "2.28.1-dev-build-
|
|
3
|
+
"version": "2.28.1-dev-build-2497ca0.0",
|
|
4
4
|
"description": "Agent-invocation and skill-prompt engine for the Contentful Experience Design System SDK",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"skills/"
|
|
23
23
|
],
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@contentful/experience-design-system-types": "2.28.1-dev-build-
|
|
25
|
+
"@contentful/experience-design-system-types": "2.28.1-dev-build-2497ca0.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@tsconfig/node24": "^24.0.4",
|
|
@@ -91,7 +91,7 @@ Emit one JSON object per line. The CLI parses lines starting with `{`. Lines not
|
|
|
91
91
|
- Every prop in the input must produce exactly one call: `classify_prop` OR `exclude_prop`.
|
|
92
92
|
- Every slot must produce exactly one `classify_slot` call.
|
|
93
93
|
- Emit `classify_component` once at the start (required). The `description` field is **required** — always provide a brief description of the component's purpose.
|
|
94
|
-
- `values` is required for `cdf_type: "enum"` — must be a non-empty string array of the variant names the prop accepts.
|
|
94
|
+
- `values` is required for `cdf_type: "enum"` — must be a non-empty string array of the variant names the prop accepts.
|
|
95
95
|
- **Do NOT include `values` for `cdf_type: "token"`.** The two property types carry different kinds of list. An `enum` prop's list holds *variant names* the component accepts (`"primary"`, `"secondary"`). A `token` prop's list holds *design token paths* (`"color.brand.primary"`), produced by the separate token-mapping step (`$token.allowed`) — never by you. Emitting `values` on a token prop makes the definition invalid.
|
|
96
96
|
- `token_kind` is required for `cdf_type: "token"` — must be a DTCG `$type` string, e.g. `"color"`.
|
|
97
97
|
- `required` must be a JSON boolean (`true`/`false`), not a string.
|
|
@@ -364,7 +364,7 @@ as enum so the author picks "primary" and the component receives "primary".
|
|
|
364
364
|
|
|
365
365
|
---
|
|
366
366
|
|
|
367
|
-
## Category
|
|
367
|
+
## Category correction rules
|
|
368
368
|
|
|
369
369
|
The pre-classified `category` is wrong in predictable ways. Correct silently (document in `description`):
|
|
370
370
|
|
|
@@ -375,11 +375,6 @@ The pre-classified `category` is wrong in predictable ways. Correct silently (do
|
|
|
375
375
|
|
|
376
376
|
> **Key question for category**: "Who fills this in?" — A content editor fills in `content`. A designer configures `design`. Neither fills in `state` — it comes from routing, runtime behavior, or component infrastructure.
|
|
377
377
|
|
|
378
|
-
**`required` is also a hint, and it is also wrong.** Verify it against the declaration:
|
|
379
|
-
- A prop with a default value — a `$default`, a destructure default, or a `defaultVariants` entry — is **never** `required: true`. The two together are incoherent.
|
|
380
|
-
- A prop declared `foo?:` is `required: false`, whatever the hint says.
|
|
381
|
-
- Props reached through `VariantProps<typeof x>` or a Radix/`ComponentPropsWithoutRef` base are optional unless the component's own interface redeclares them as required.
|
|
382
|
-
|
|
383
378
|
---
|
|
384
379
|
|
|
385
380
|
## Slot classification
|
|
@@ -467,30 +462,14 @@ footer is supplementary and optional
|
|
|
467
462
|
{"tool":"classify_slot","slot":"footer","required":false,"description":"Optional footer area for actions or metadata","rationale":"Footer is a supplementary region typically used for actions or metadata. Optional because most cards do not need one and the card renders correctly without it."}
|
|
468
463
|
```
|
|
469
464
|
|
|
470
|
-
### Named type (HeadingSize, ButtonVariant, etc.)
|
|
471
|
-
|
|
472
|
-
When a prop has a named TypeScript type that is not inlined as a union literal,
|
|
473
|
-
the value set is whatever that type's declaration says. A type *name* is not
|
|
474
|
-
evidence of its members: `HeadingSize` could be `h1`–`h6`, `sm|md|lg`, or
|
|
475
|
-
`s|m|l|xl`. Guessing picks one design system's vocabulary and is wrong more
|
|
476
|
-
often than it is right, and a wrong name matches no style rule — the author's
|
|
477
|
-
setting silently does nothing.
|
|
478
|
-
|
|
479
|
-
So: look for the declaration in the source shown. If it is there, copy it. If it
|
|
480
|
-
is not, **emit `string`** — `string` is an unrestricted enum, so the author stays
|
|
481
|
-
unrestricted but correct.
|
|
465
|
+
### Named type (HeadingSize, ButtonVariant, etc.)
|
|
482
466
|
|
|
483
|
-
|
|
484
|
-
```
|
|
485
|
-
titleSize has type HeadingSize; HeadingSize is declared in the excerpt as 'sm' | 'md' | 'lg'
|
|
486
|
-
{"tool":"classify_prop","prop":"titleSize","cdf_type":"enum","cdf_category":"design","required":false,"values":["sm","md","lg"],"description":"Heading size","reason":"Copied from the HeadingSize declaration shown in the excerpt."}
|
|
487
|
-
```
|
|
467
|
+
When a prop has a named TypeScript type that is not inlined as a union literal, reason from the prop name and type name to infer the finite value set.
|
|
488
468
|
|
|
489
|
-
Members NOT visible in the source shown — degrade to `string`:
|
|
490
469
|
```
|
|
491
|
-
titleSize has type HeadingSize
|
|
492
|
-
|
|
493
|
-
{"tool":"classify_prop","prop":"titleSize","cdf_type":"
|
|
470
|
+
titleSize has type HeadingSize — this is a named enum controlling heading size
|
|
471
|
+
inferring likely values: ["h1", "h2", "h3", "h4", "h5", "h6"] — documenting inference
|
|
472
|
+
{"tool":"classify_prop","prop":"titleSize","cdf_type":"enum","cdf_category":"design","required":false,"values":["h1","h2","h3","h4","h5","h6"],"description":"Heading level — inferred from HeadingSize type name; actual values may be h1–h6 or sm/md/lg"}
|
|
494
473
|
```
|
|
495
474
|
|
|
496
475
|
### href prop
|
|
@@ -516,7 +495,7 @@ Before emitting any tool calls, verify:
|
|
|
516
495
|
1. Every prop in the input has exactly one `classify_prop` or `exclude_prop` call
|
|
517
496
|
2. Every slot has exactly one `classify_slot` call
|
|
518
497
|
3. `classify_component` is emitted exactly once
|
|
519
|
-
4. Every `cdf_type: "enum"` has a non-empty `values` array
|
|
498
|
+
4. Every `cdf_type: "enum"` has a non-empty `values` array
|
|
520
499
|
5. Every `cdf_type: "token"` has `token_kind` (or a warning in `description` if lookup failed) and does **not** have `values` set
|
|
521
500
|
6. No `cdf_type: "link"` — all href/url props use `string`
|
|
522
501
|
7. `required` values are JSON booleans, not strings
|
|
@@ -528,8 +507,7 @@ Before emitting any tool calls, verify:
|
|
|
528
507
|
13. `rationale.description` follows the same "Description content rules" as `description` — no internal initiative names (`INTEG-*`, `EDSI`, `DSI`, `M1`, `M2`, wave/phase references, etc.).
|
|
529
508
|
14. Every `cdf_type: "token"` prop cites a line that interpolates its value into a style **and** a token reference at that use (Q2 yes, Q3 yes), and carries no `values`. If you cannot cite both, it is `enum` or `string`; if you can, it is `token` — its type annotation is not a reason to emit `string`.
|
|
530
509
|
15. Every prop whose values are friendly names is `enum` with a non-empty `values` array, even when each name resolves to a design token internally; every prop for which Q1–Q3 could not be answered was emitted as `enum` (or `string`) with the ambiguity stated in `reason`, and no answerable prop was called ambiguous.
|
|
531
|
-
16. Every `enum`'s `values` array is copied from evidence in the
|
|
532
|
-
17. No prop has `required: true` alongside a default value (`$default`, a destructure default, or a `defaultVariants` entry) — the two are incoherent. A prop declared `foo?:`, or reached through `VariantProps<typeof x>` or a Radix/`ComponentPropsWithoutRef` base without its own required redeclaration, is `required: false`.
|
|
510
|
+
16. Every `enum`'s `values` array is copied from evidence in the source shown (a type declaration, lookup table, or default) — none of it was invented. Where no evidence exists for the values, the `description` states so (e.g. `"WARNING: values not visible in source"`), not just `reason`.
|
|
533
511
|
|
|
534
512
|
After the run completes, the developer can validate the pipeline output with:
|
|
535
513
|
|
|
@@ -550,6 +528,4 @@ properties — this is never acceptable.
|
|
|
550
528
|
If you are genuinely uncertain about every prop, classify each as:
|
|
551
529
|
{"tool":"classify_prop","prop":"<name>","cdf_type":"string","cdf_category":"content","required":false,"description":"Uncertain classification — review recommended"}
|
|
552
530
|
|
|
553
|
-
An imperfect classification is infinitely better than no classification.
|
|
554
|
-
about **classifying a prop rather than dropping it** — it is not a licence to
|
|
555
|
-
invent a `values` list. The uncertain answer is `cdf_type: "string"`, every time.
|
|
531
|
+
An imperfect classification is infinitely better than no classification.
|