@contentful/experience-design-system-cli 2.35.1-dev-build-57c625cc.0 → 2.35.1-dev-build-35ec3f8d.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.
@@ -173,608 +173,291 @@ var init_agent_names = __esm({
173
173
  }
174
174
  });
175
175
 
176
- // packages/experience-design-system-generation/dist/src/agent-runner.js
177
- import { spawn } from "node:child_process";
178
- function findJsonObjectEnd(line) {
179
- let depth = 0;
180
- let inString = false;
181
- let escaped = false;
182
- for (let i = 0; i < line.length; i++) {
183
- const ch = line[i];
184
- if (escaped) {
185
- escaped = false;
186
- } else if (ch === "\\" && inString) {
187
- escaped = true;
188
- } else if (ch === '"') {
189
- inString = !inString;
190
- } else if (!inString && ch === "{") {
191
- depth++;
192
- } else if (!inString && ch === "}" && --depth === 0) {
193
- return i;
194
- }
176
+ // packages/experience-design-system-generation/dist/src/controller/helpers/validate-generation-request.js
177
+ function validateGenerationRequest(request2) {
178
+ if (request2 === null || typeof request2 !== "object") {
179
+ throw new TypeError("createGenerationEndpoint requires a request object");
195
180
  }
196
- return -1;
197
- }
198
- function readToolCallObjects(stdout) {
199
- const objects = [];
200
- const warnings = [];
201
- for (const raw of stdout.split("\n")) {
202
- const line = raw.trim();
203
- if (!line.startsWith("{"))
204
- continue;
205
- const end = findJsonObjectEnd(line);
206
- if (end === -1) {
207
- warnings.push(`unparseable line: ${line.slice(0, 120)}`);
208
- continue;
209
- }
210
- let parsed;
211
- try {
212
- parsed = JSON.parse(line.slice(0, end + 1));
213
- } catch {
214
- warnings.push(`unparseable line: ${line.slice(0, 120)}`);
215
- continue;
216
- }
217
- const trailing = line.slice(end + 1);
218
- if (trailing.trim()) {
219
- warnings.push(`ignored trailing content after JSON: ${trailing.trim().slice(0, 120)}`);
220
- }
221
- if (typeof parsed === "object" && parsed !== null && "tool" in parsed) {
222
- objects.push(parsed);
223
- }
181
+ if (!isAgentName(request2.agent)) {
182
+ throw new TypeError(`createGenerationEndpoint requires agent to be a valid agent name, got: ${String(request2.agent)}`);
224
183
  }
225
- return { objects, warnings };
226
- }
227
- function parseSelectToolCallLines(stdout) {
228
- const calls = [];
229
- const { objects, warnings } = readToolCallObjects(stdout);
230
- for (const rec of objects) {
231
- if (!VALID_SELECT_TOOL_NAMES.has(rec.tool))
232
- continue;
233
- if (typeof rec.name !== "string" || !rec.name) {
234
- warnings.push(`${String(rec.tool)} missing name \u2014 skipped`);
235
- continue;
236
- }
237
- const call = {
238
- tool: rec.tool,
239
- name: rec.name
240
- };
241
- if (typeof rec.reason === "string")
242
- call.reason = rec.reason;
243
- if (typeof rec.confidence === "number" && rec.confidence >= 1 && rec.confidence <= 5) {
244
- if (call.tool === "select_component") {
245
- call.confidence = rec.confidence;
246
- } else {
247
- call.confidence = rec.confidence;
248
- }
249
- }
250
- calls.push(call);
184
+ if (typeof request2.timeoutMs !== "number" || request2.timeoutMs <= 0) {
185
+ throw new TypeError("createGenerationEndpoint requires timeoutMs to be a positive number");
186
+ }
187
+ if (request2.promptOptions === null || typeof request2.promptOptions !== "object") {
188
+ throw new TypeError("createGenerationEndpoint requires promptOptions to be an object");
189
+ }
190
+ if (request2.onOutput !== void 0 && typeof request2.onOutput !== "function") {
191
+ throw new TypeError("createGenerationEndpoint requires onOutput to be a function when provided");
251
192
  }
252
- return { calls, warnings };
253
193
  }
254
- function parseToolCallLines(stdout) {
255
- const calls = [];
256
- const { objects, warnings } = readToolCallObjects(stdout);
257
- for (const rec of objects) {
258
- if (!VALID_TOOL_NAMES.has(rec.tool)) {
259
- warnings.push(`unknown tool: ${String(rec.tool)}`);
260
- continue;
261
- }
262
- const tool = rec.tool;
263
- if (tool === "classify_prop") {
264
- if (typeof rec.prop !== "string" || !rec.prop) {
265
- warnings.push("classify_prop missing prop name \u2014 skipped");
266
- continue;
267
- }
268
- if (typeof rec.cdf_type !== "string" || !VALID_CDF_TYPES.has(rec.cdf_type)) {
269
- warnings.push(`classify_prop '${rec.prop}': invalid cdf_type '${String(rec.cdf_type)}' \u2014 skipped`);
270
- continue;
271
- }
272
- if (typeof rec.cdf_category !== "string" || !VALID_CATEGORIES.has(rec.cdf_category)) {
273
- warnings.push(`classify_prop '${rec.prop}': invalid cdf_category '${String(rec.cdf_category)}' \u2014 skipped`);
274
- continue;
275
- }
276
- const call = {
277
- tool: "classify_prop",
278
- prop: rec.prop,
279
- cdf_type: rec.cdf_type,
280
- cdf_category: rec.cdf_category
281
- };
282
- if (Array.isArray(rec.values) && rec.values.every((v) => typeof v === "string")) {
283
- call.values = rec.values;
284
- }
285
- if (typeof rec.token_kind === "string")
286
- call.token_kind = rec.token_kind;
287
- if (typeof rec.required === "boolean")
288
- call.required = rec.required;
289
- if (typeof rec.description === "string")
290
- call.description = rec.description;
291
- if (typeof rec.default === "string" || typeof rec.default === "boolean")
292
- call.default = rec.default;
293
- if (typeof rec.reason === "string")
294
- call.reason = rec.reason;
295
- calls.push(call);
296
- } else if (tool === "exclude_prop") {
297
- if (typeof rec.prop !== "string" || !rec.prop) {
298
- warnings.push("exclude_prop missing prop name \u2014 skipped");
299
- continue;
300
- }
301
- calls.push({
302
- tool: "exclude_prop",
303
- prop: rec.prop,
304
- reason: typeof rec.reason === "string" ? rec.reason : ""
305
- });
306
- } else if (tool === "classify_component") {
307
- const call = { tool: "classify_component" };
308
- if (typeof rec.description === "string")
309
- call.description = rec.description;
310
- if (typeof rec.rationale === "object" && rec.rationale !== null) {
311
- const r = rec.rationale;
312
- const rationale = {};
313
- if (typeof r.description === "string")
314
- rationale.description = r.description;
315
- if (typeof r.props === "string")
316
- rationale.props = r.props;
317
- if (typeof r.slots === "string")
318
- rationale.slots = r.slots;
319
- if (Object.keys(rationale).length > 0)
320
- call.rationale = rationale;
321
- }
322
- calls.push(call);
323
- } else if (tool === "classify_slot") {
324
- if (typeof rec.slot !== "string" || !rec.slot) {
325
- warnings.push("classify_slot missing slot name \u2014 skipped");
326
- continue;
327
- }
328
- const call = { tool: "classify_slot", slot: rec.slot };
329
- if (typeof rec.required === "boolean")
330
- call.required = rec.required;
331
- if (Array.isArray(rec.allowed_components) && rec.allowed_components.every((v) => typeof v === "string")) {
332
- call.allowed_components = rec.allowed_components;
333
- }
334
- if (typeof rec.description === "string")
335
- call.description = rec.description;
336
- if (typeof rec.rationale === "string")
337
- call.rationale = rec.rationale;
338
- calls.push(call);
339
- }
194
+ var init_validate_generation_request = __esm({
195
+ "packages/experience-design-system-generation/dist/src/controller/helpers/validate-generation-request.js"() {
196
+ "use strict";
197
+ init_agent_names();
340
198
  }
341
- return { calls, warnings };
199
+ });
200
+
201
+ // packages/experience-design-system-generation/dist/src/services/prompts/helpers/format-token-candidates.js
202
+ import { flattenDTCG } from "@contentful/experience-design-system-types";
203
+ function inferFenceLang(filename) {
204
+ if (!filename)
205
+ return "json";
206
+ const ext = filename.split(".").pop()?.toLowerCase() ?? "";
207
+ const map = {
208
+ js: "js",
209
+ mjs: "js",
210
+ cjs: "js",
211
+ ts: "ts",
212
+ mts: "ts",
213
+ cts: "ts",
214
+ tsx: "tsx",
215
+ jsx: "jsx",
216
+ vue: "vue",
217
+ svelte: "svelte",
218
+ astro: "astro",
219
+ scss: "scss",
220
+ sass: "scss",
221
+ css: "css",
222
+ json: "json",
223
+ json5: "json"
224
+ };
225
+ return map[ext] ?? "text";
342
226
  }
343
- function parseTokenToolCallLines(stdout) {
344
- const calls = [];
345
- const { objects, warnings } = readToolCallObjects(stdout);
346
- for (const rec of objects) {
347
- if (!VALID_TOKEN_TOOL_NAMES.has(rec.tool))
227
+ function filterDesignTokenProps(cdf) {
228
+ const result = {};
229
+ const kinds = /* @__PURE__ */ new Set();
230
+ let hasUnscoped = false;
231
+ for (const [componentName, component] of Object.entries(cdf)) {
232
+ const properties = component.$properties;
233
+ if (!properties)
348
234
  continue;
349
- if (rec.tool === "set_token") {
350
- if (typeof rec.path !== "string" || !rec.path) {
351
- warnings.push("set_token missing path \u2014 skipped");
352
- continue;
353
- }
354
- if (typeof rec.type !== "string" || !rec.type) {
355
- warnings.push(`set_token '${rec.path}': missing type \u2014 skipped`);
356
- continue;
357
- }
358
- if (!("value" in rec)) {
359
- warnings.push(`set_token '${rec.path}': missing value \u2014 skipped`);
360
- continue;
361
- }
362
- const call = { tool: "set_token", path: rec.path, type: rec.type, value: rec.value };
363
- if (typeof rec.description === "string")
364
- call.description = rec.description;
365
- calls.push(call);
366
- } else if (rec.tool === "set_group") {
367
- if (typeof rec.path !== "string" || !rec.path) {
368
- warnings.push("set_group missing path \u2014 skipped");
369
- continue;
235
+ const filteredProps = {};
236
+ for (const [propName, prop] of Object.entries(properties)) {
237
+ if (prop.$type === "token" && prop.$category === "design") {
238
+ const { "$token.allowed": _tokenAllowed, ...rest } = prop;
239
+ filteredProps[propName] = rest;
240
+ const kind = prop["$token.kind"];
241
+ if (typeof kind === "string" && kind.length > 0) {
242
+ kinds.add(kind);
243
+ } else {
244
+ hasUnscoped = true;
245
+ }
370
246
  }
371
- const call = { tool: "set_group", path: rec.path };
372
- if (typeof rec.description === "string")
373
- call.description = rec.description;
374
- calls.push(call);
247
+ }
248
+ if (Object.keys(filteredProps).length > 0) {
249
+ result[componentName] = { ...component, $properties: filteredProps };
375
250
  }
376
251
  }
377
- return { calls, warnings };
252
+ return { filtered: result, kinds: [...kinds].sort(), hasUnscoped };
378
253
  }
379
- function isStringArray(value) {
380
- return Array.isArray(value) && value.every((v) => typeof v === "string");
254
+ function buildTokenCandidateSections(tokenTree, filteredTokenProps) {
255
+ const index = flattenDTCG(tokenTree, "").sort((a, b) => a.path.localeCompare(b.path));
256
+ if (index.length === 0)
257
+ return [];
258
+ const sections = [];
259
+ const renderSection = (kind, entries) => {
260
+ const label = kind ? `Token path index \u2014 ${kind} candidates only` : "Token path index \u2014 full tree (no $token.kind to scope by)";
261
+ const lines = entries.map((e) => `${e.path} \xB7 ${e.$type}`).join("\n");
262
+ return `${label}, one leaf token per line as \`path \xB7 type\`, no \`$value\`:
263
+ ${lines}`;
264
+ };
265
+ if (filteredTokenProps) {
266
+ const { kinds, hasUnscoped } = filteredTokenProps;
267
+ for (const kind of kinds) {
268
+ const scoped = index.filter((e) => e.$type === kind);
269
+ if (scoped.length > 0)
270
+ sections.push(renderSection(kind, scoped));
271
+ }
272
+ if (hasUnscoped)
273
+ sections.push(renderSection(null, index));
274
+ } else {
275
+ sections.push(renderSection(null, index));
276
+ }
277
+ return sections;
381
278
  }
382
- function parseMapTokenPropToolCallLines(stdout) {
383
- const calls = [];
384
- const warnings = [];
385
- for (const raw of stdout.split("\n")) {
386
- const line = raw.trim();
387
- if (!line.startsWith("{"))
388
- continue;
389
- let obj;
390
- try {
391
- obj = JSON.parse(line);
392
- } catch {
393
- warnings.push(`unparseable line: ${line.slice(0, 120)}`);
394
- continue;
395
- }
396
- if (typeof obj !== "object" || obj === null || !("tool" in obj))
397
- continue;
398
- const rec = obj;
399
- if (rec.tool !== "map_token_prop")
400
- continue;
401
- if (typeof rec.component !== "string" || !rec.component) {
402
- warnings.push("map_token_prop missing component \u2014 skipped");
403
- continue;
404
- }
405
- if (typeof rec.prop !== "string" || !rec.prop) {
406
- warnings.push(`map_token_prop '${rec.component}': missing prop \u2014 skipped`);
407
- continue;
408
- }
409
- if (!isStringArray(rec.token_allowed) || rec.token_allowed.length === 0) {
410
- warnings.push(`map_token_prop '${rec.component}.${String(rec.prop)}': missing or empty token_allowed \u2014 skipped`);
411
- continue;
412
- }
413
- const call = {
414
- tool: "map_token_prop",
415
- component: rec.component,
416
- prop: rec.prop,
417
- token_allowed: rec.token_allowed
418
- };
419
- calls.push(call);
279
+ var init_format_token_candidates = __esm({
280
+ "packages/experience-design-system-generation/dist/src/services/prompts/helpers/format-token-candidates.js"() {
281
+ "use strict";
420
282
  }
421
- return { calls, warnings };
283
+ });
284
+
285
+ // packages/experience-design-system-generation/dist/src/services/prompts/helpers/build-skill-preambles.js
286
+ function buildComponentsAutonomousPreamble(inputBlock) {
287
+ return `You are running as part of the experience-design-system-cli generate pipeline in AUTONOMOUS mode. The developer is not present to answer questions.
288
+
289
+ Context: You are classifying a React component for **Contentful Experience Orchestration**. The result is a Component Type \u2014 a schema that tells Contentful what a marketer can configure. Properties fall into three categories:
290
+ - **design**: controls how the component looks (variant, size, color, layout toggles)
291
+ - **content**: the data a content editor fills in (text, images, URLs, rich text)
292
+ - **state**: runtime behavioral flags (disabled, loading, expanded, identifiers)
293
+
294
+ Your task: classify every prop and slot in the component below. Apply all judgment calls yourself \u2014 do not pause to ask for confirmation. Include a "description" field on each tool call to document your reasoning so the developer can review it afterward.
295
+
296
+ All input data is provided inline below \u2014 do not read any additional files.${inputBlock}
297
+
298
+ ## Output protocol
299
+
300
+ Do NOT write any files or emit any JSON blobs. Instead, emit one JSON object per line to stdout for each classification decision. The CLI reads your stdout line by line and writes each decision directly to the pipeline database.
301
+
302
+ The four tool calls you may emit are:
303
+
304
+ \`\`\`
305
+ {"tool":"classify_component","description":"<optional component-level description>","rationale":{"description":"<why this component is classified the way it is>","props":"<why these props were chosen>","slots":"<why these slots were chosen>"}}
306
+
307
+ {"tool":"classify_prop","prop":"<propName>","cdf_type":"<type>","cdf_category":"<category>","required":<bool>,"description":"<short customer-facing description>","reason":"<full internal rationale; not customer-facing>","values":["a","b"],"token_kind":"color","default":"<value>"}
308
+
309
+ {"tool":"exclude_prop","prop":"<propName>","reason":"<why excluded>"}
310
+
311
+ {"tool":"classify_slot","slot":"<slotName>","required":<bool>,"allowed_components":["ComponentName"],"description":"<reason>","rationale":"<why this slot was kept in the catalog>"}
312
+ \`\`\`
313
+
314
+ Rules:
315
+ - Emit exactly one JSON object per line. No multi-line JSON. No markdown fences around the lines.
316
+ - Every prop in the input must have exactly one call: either classify_prop or exclude_prop.
317
+ - Every slot in the input must have exactly one classify_slot call.
318
+ - Valid cdf_type values: string, richtext, media, enum, token, boolean
319
+ - Valid cdf_category values: content, design, state
320
+ - For enum type, always include \`values\` (non-empty string array of the variant names the prop accepts).
321
+ - For token type, always include \`token_kind\` (DTCG $type, e.g. "color"). **Never emit \`values\` for \`cdf_type: "token"\` props** \u2014 an enum prop's list holds variant names; a token prop's list holds design token paths, produced separately and never by you. Emitting \`values\` on a token prop makes the definition invalid.
322
+ - Never emit both "values" and "token_kind" on one prop.
323
+ - \`enum\` vs \`token\` is decided by three questions answered in order from the source shown \u2014 never from the TypeScript type. Q1: does the component look the value up, switch on it, or have a vocabulary for it (\`tokens[x]\`, \`switch (variant)\`, \`allowedValues\`)? yes \u2192 \`enum\`, stop.
324
+ - Q2: is the value written straight into a style or attribute (\`rx={radius}\`, \`padding: \${padding}\`)? no \u2192 not \`token\`, apply the type rules.
325
+ - Q3: is there a design-token reference at that use \u2014 a \`tokens.*\` parameter default, a \`tokenReference\`, an inline \`tokens.*\` / \`var(--*)\`? yes \u2192 \`token\` (cite both lines in "reason"); no \u2192 \`string\`. "Ambiguity resolves to \`enum\`" applies only when Q1\u2013Q3 cannot be answered from the source shown.
326
+ - CSS design props (className, style, styles, positional/geometric props: top, bottom, left, right, rotation, offset, etc.) \u2192 classify_prop, cdf_type: "string", cdf_category: "design".
327
+ - For \`classify_slot.allowed_components\`, use only exact names from the hard allowlist provided below. Never invent a child from an import, JSX element, type name, icon name, or implementation helper; if a child is not listed, omit it.
328
+ - On classify_component, "rationale" fields are operator-facing (read-only) but may surface in customer-facing exports. The "rationale.description" field is subject to the description content rules in the skill prompt (no internal initiative names). "rationale.props" and "rationale.slots" describe your reasoning about scope; "classify_slot.rationale" explains why each slot was kept.
329
+ - On classify_prop, "reason" is REQUIRED and is the LLM's internal rationale \u2014 shown to the developer reviewing the import, never to end-users. "description" is the customer-facing copy and is subject to the description content rules in the skill prompt. Keep them distinct: "description" is short and customer-facing; "reason" explains your reasoning in detail.
330
+ - You may emit prose lines (not starting with {) anywhere \u2014 they are ignored by the parser and serve as your reasoning log.`;
422
331
  }
423
- function resolveBinary(agent) {
424
- const envKey = `EDS_AGENT_BINARY_${agent.toUpperCase()}`;
425
- const override = process.env[envKey];
426
- if (override && override.trim())
427
- return override.trim();
428
- return AGENT_BINARIES[agent];
332
+ function buildSelectAutonomousPreamble(inputBlock) {
333
+ return `You are running as part of the experience-design-system-cli import pipeline in AUTONOMOUS mode. The developer is not present to answer questions.
334
+
335
+ Your task: review the components provided below and decide whether each belongs in Contentful Experience Orchestration as a Component Type. The input is a JSON array \u2014 you may receive 1\u2013N components in a single message. Emit one tool call per input component, named after the component. Apply all judgment calls yourself \u2014 do not pause to ask for confirmation. Include a brief "reason" to document your reasoning for each decision.
336
+
337
+ Key rule: accept any component that renders visible UI \u2014 atoms, molecules, and organisms are all valid Component Types in Contentful Experience Orchestration. Reject only components that produce zero visual output: React hooks, pure context providers, A/B testing or variant-routing wrappers, analytics trackers, and security utilities. Do NOT reject a component because it has few props, is low-level, or has some A/B testing or personalization-related props mixed in \u2014 those props are handled in the generate step.
338
+
339
+ All input data is provided inline below \u2014 do not read any additional files.${inputBlock}
340
+
341
+ ## Output protocol
342
+
343
+ Do NOT write any files or emit any JSON blobs. Instead, emit JSON tool calls one per line to stdout. The CLI reads your stdout line by line.
344
+
345
+ The two tool calls \u2014 emit exactly one per input component:
346
+
347
+ \`\`\`
348
+ {"tool":"select_component","name":"<ComponentName>","reason":"<brief reason>"}
349
+
350
+ {"tool":"reject_component","name":"<ComponentName>","reason":"<brief reason>"}
351
+ \`\`\`
352
+
353
+ Rules:
354
+ - Emit exactly one JSON object per line. No multi-line JSON. No markdown fences.
355
+ - Emit exactly one tool call per input component. The "name" field must match a component name from the input array exactly. Tool calls may appear in any order.
356
+ - You may emit prose lines (not starting with {) to reason before each tool call \u2014 they are ignored by the parser.`;
429
357
  }
430
- function agentSupportsBedrock(agent) {
431
- return BEDROCK_CAPABLE_AGENTS.has(agent);
358
+ function buildMapTokensAutonomousPreamble(inputBlock) {
359
+ return `You are running as part of the experience-design-system-cli generate pipeline in AUTONOMOUS mode. The developer is not present to answer questions.
360
+
361
+ Context: The components below already have design-category, token-typed props (\`$token.kind\` set). Your task is to decide, from source evidence, whether to narrow each one to a restricted subset (\`token_allowed\`) of the tokens matching its \`$token.kind\`. Apply all judgment calls yourself \u2014 do not pause to ask for confirmation.
362
+
363
+ All input data is provided inline below \u2014 do not read any additional files.${inputBlock}
364
+
365
+ ## Output protocol
366
+
367
+ Do NOT write any files or emit any JSON blobs. Instead, emit one JSON object per line to stdout for each prop you narrow. The CLI reads your stdout line by line and writes each decision directly to the pipeline database.
368
+
369
+ The one tool call you may emit:
370
+
371
+ \`\`\`
372
+ {"tool":"map_token_prop","component":"<ComponentName>","prop":"<propName>","token_allowed":["colors.brand.primary","colors.brand.secondary"]}
373
+ \`\`\`
374
+
375
+ Rules:
376
+ - Emit exactly one JSON object per line. No multi-line JSON. No markdown fences around the lines.
377
+ - Only emit a call for a prop that appears in the "Generated CDF so far" section.
378
+ - Each "Token path index" section below is already scoped to one \`$token.kind\` \u2014 a prop only draws candidates from the section matching its own \`$token.kind\` (or the "full tree" section, for a prop with no \`$token.kind\`). Never cross sections, never emit a group/prefix path, and never invent a path \u2014 every entry in \`token_allowed\` must exist verbatim in the matching section.
379
+ - \`token_allowed\` is required and must be non-empty when the call is emitted.
380
+ - For the judgment call of whether a prop should be narrowed at all, follow the decision tree in the map-tokens skill file: it explains defaults vs. restrictions, misclassified variant-name props, and when to emit nothing.
381
+ - You may emit prose lines (not starting with \`{\`) anywhere \u2014 they are ignored by the parser and serve as your reasoning log.`;
432
382
  }
433
- function resolveAgentModel(agent, explicit, bedrock = false) {
434
- if (explicit && explicit.trim())
435
- return explicit.trim();
436
- const override = process.env[`EDS_AGENT_MODEL_${agent.toUpperCase()}`];
437
- if (override && override.trim())
438
- return override.trim();
439
- if (bedrock && agent === "codex")
440
- return DEFAULT_CODEX_BEDROCK_MODEL;
441
- if (bedrock && agent === "opencode")
442
- return withBedrockProviderPrefix(DEFAULT_OPENCODE_MODEL);
443
- return DEFAULT_MODELS[agent];
383
+ function buildTokensAutonomousPreamble(inputBlock) {
384
+ return `You are running as part of the experience-design-system-cli generate pipeline in AUTONOMOUS mode. The developer is not present to answer questions.
385
+
386
+ Your task: classify every raw token from the input below into a DTCG token tree. Apply all judgment calls yourself \u2014 do not pause to ask for confirmation. Include a "description" field on each set_token call to document your reasoning.
387
+
388
+ All input data is provided inline below \u2014 do not read any additional files.${inputBlock}
389
+
390
+ ## Output protocol
391
+
392
+ Do NOT write any files or emit any JSON blobs. Instead, emit one JSON object per line to stdout for each token or group. The CLI reads your stdout line by line and writes each entry directly to the pipeline database.
393
+
394
+ The two tool calls you may emit are:
395
+
396
+ \`\`\`
397
+ {"tool":"set_group","path":"<dot.notation.path>","description":"<optional group description>"}
398
+
399
+ {"tool":"set_token","path":"<dot.notation.path>","type":"<DTCG type>","value":<value>,"description":"<reason>"}
400
+ \`\`\`
401
+
402
+ Rules:
403
+ - Emit exactly one JSON object per line. No multi-line JSON. No markdown fences.
404
+ - Emit a set_group call for every intermediate group node in the tree.
405
+ - Emit a set_token call for every leaf token.
406
+ - "path" is dot-notation, e.g. "colors.brand.primary" \u2014 no leading dots or slashes.
407
+ - "type" must be one of the 13 valid DTCG types: color, dimension, fontFamily, fontWeight, duration, cubicBezier, number, strokeStyle, border, transition, shadow, gradient, typography.
408
+ - "value" must be valid JSON (string, number, array, or object depending on the type). Do NOT wrap it in quotes if it is a complex type.
409
+ - Emit set_group calls before the set_token calls that fall under them.
410
+ - You may emit prose lines (not starting with {) anywhere \u2014 they are ignored by the parser and serve as your reasoning log.`;
444
411
  }
445
- function withBedrockProviderPrefix(model) {
446
- return model.includes("/") ? model : `amazon-bedrock/${model}`;
412
+ var init_build_skill_preambles = __esm({
413
+ "packages/experience-design-system-generation/dist/src/services/prompts/helpers/build-skill-preambles.js"() {
414
+ "use strict";
415
+ }
416
+ });
417
+
418
+ // packages/experience-design-system-generation/dist/src/services/prompts/build-prompt.js
419
+ import { existsSync } from "node:fs";
420
+ import { readFile as readFile2 } from "node:fs/promises";
421
+ import { dirname, join as join2, resolve } from "node:path";
422
+ import { fileURLToPath } from "node:url";
423
+ function resolveSkillPath(skill) {
424
+ if (!(skill in SKILL_FILES))
425
+ throw new Error(`Invalid skill: ${skill}`);
426
+ const thisDir = dirname(fileURLToPath(import.meta.url));
427
+ let dir = thisDir;
428
+ for (; ; ) {
429
+ const candidate = join2(dir, "skills");
430
+ if (existsSync(candidate))
431
+ return join2(candidate, SKILL_FILES[skill]);
432
+ const parent = resolve(dir, "..");
433
+ if (parent === dir) {
434
+ throw new Error(`skill file missing from CLI installation (could not locate skills/ directory from: ${thisDir})`);
435
+ }
436
+ dir = parent;
437
+ }
447
438
  }
448
- function codexBedrockConfigArgs() {
449
- const region = process.env.AWS_REGION?.trim() || process.env.AWS_DEFAULT_REGION?.trim() || DEFAULT_CODEX_BEDROCK_REGION;
450
- return ["-c", "model_provider=amazon-bedrock", "-c", `model_providers.amazon-bedrock.region=${region}`];
439
+ function formatCustomPromptBanner(skill, path) {
440
+ return `WARNING: Custom prompt active for ${skill}: ${path}
441
+ Bundled invariants (utility-wrapper rejection, description content rules) do NOT apply.
442
+ You are responsible for the prompt's correctness.
443
+ `;
451
444
  }
452
- function buildArgs(agent, prompt, model, promptViaStdin = false, bedrock = false) {
453
- const resolvedModel = resolveAgentModel(agent, model, bedrock);
454
- const modelArg = resolvedModel ? ["--model", resolvedModel] : [];
455
- const promptArg = promptViaStdin ? [] : [prompt];
456
- switch (agent) {
457
- case "claude":
458
- return ["--print", ...modelArg, ...promptArg];
459
- case "codex": {
460
- const bedrockArgs = bedrock ? codexBedrockConfigArgs() : [];
461
- return ["exec", ...bedrockArgs, ...modelArg, "--dangerously-bypass-approvals-and-sandbox", ...promptArg];
462
- }
463
- case "opencode":
464
- return ["run", ...modelArg, ...promptArg];
465
- case "cursor":
466
- return ["--print", ...modelArg, ...promptArg];
467
- case "copilot": {
468
- const copilotModel = resolveAgentModel("copilot", model);
469
- const copilotModelArg = !copilotModel || copilotModel === "Auto" ? [] : ["--model", copilotModel];
470
- return ["-p", ...promptArg, ...copilotModelArg, "--allow-all-tools"];
445
+ async function readSkillFile(skill, override) {
446
+ if (override) {
447
+ const skillPath2 = resolve(override);
448
+ try {
449
+ return await readFile2(skillPath2, "utf8");
450
+ } catch {
451
+ throw new Error(`custom prompt file not found (skill: ${skill}, path: ${skillPath2})`);
471
452
  }
472
453
  }
454
+ const skillPath = resolveSkillPath(skill);
455
+ try {
456
+ return await readFile2(skillPath, "utf8");
457
+ } catch {
458
+ throw new Error(`skill file missing from CLI installation \u2014 try reinstalling the CLI (looked for: ${skillPath})`);
459
+ }
473
460
  }
474
- async function runAgent(options) {
475
- const { agent, prompt, timeoutMs, model, onOutput, promptViaStdin, onDebugEvent } = options;
476
- const bedrock = options.bedrock ?? process.env.EDS_BEDROCK === "1";
477
- const binary = resolveBinary(agent);
478
- const useStdin2 = !!promptViaStdin;
479
- const args = buildArgs(agent, prompt, model, useStdin2, bedrock);
480
- const startedAt = Date.now();
481
- onDebugEvent?.("run.start", {
482
- agent,
483
- binary,
484
- model,
485
- bedrock: !!bedrock,
486
- timeoutMs,
487
- promptLen: prompt.length,
488
- promptHead: prompt.slice(0, 500)
489
- });
490
- return new Promise((resolve21) => {
491
- const bedrockEnv = bedrock ? BEDROCK_ENV_BY_AGENT[agent] : void 0;
492
- const child = spawn(binary, args, {
493
- stdio: ["pipe", "pipe", "pipe"],
494
- ...bedrockEnv ? { env: { ...process.env, ...bedrockEnv } } : {}
495
- });
496
- if (useStdin2 && child.stdin) {
497
- child.stdin.on("error", () => {
498
- });
499
- child.stdin.write(prompt, () => {
500
- child.stdin?.end();
501
- });
502
- } else {
503
- child.stdin?.end();
504
- }
505
- let stdout = "";
506
- let stderr = "";
507
- let timedOut = false;
508
- const timer = setTimeout(() => {
509
- timedOut = true;
510
- child.kill("SIGTERM");
511
- }, timeoutMs);
512
- child.stdout?.on("data", (chunk) => {
513
- const text = chunk.toString();
514
- stdout += text;
515
- onOutput?.(text);
516
- });
517
- child.stderr?.on("data", (chunk) => {
518
- stderr += chunk.toString();
519
- });
520
- child.on("close", (code, signal) => {
521
- clearTimeout(timer);
522
- const result = {
523
- exitCode: signal ? 1 : code ?? 1,
524
- stdout,
525
- stderr,
526
- timedOut
527
- };
528
- onDebugEvent?.("run.end", {
529
- agent,
530
- model,
531
- durationMs: Date.now() - startedAt,
532
- exitCode: result.exitCode,
533
- signal,
534
- timedOut,
535
- stdoutLen: stdout.length,
536
- stderrLen: stderr.length,
537
- stderrTail: stderr.slice(-1e3)
538
- });
539
- resolve21(result);
540
- });
541
- });
542
- }
543
- async function checkAgentAuth(agent) {
544
- const binary = resolveBinary(agent);
545
- const binaryExists2 = await new Promise((resolve21) => {
546
- if (binary.startsWith("/")) {
547
- import("node:fs/promises").then((fs2) => fs2.access(binary).then(() => resolve21(true), () => resolve21(false)));
548
- return;
549
- }
550
- const child = spawn(process.platform === "win32" ? "where" : "which", [binary], { stdio: "ignore" });
551
- child.on("close", (code) => resolve21(code === 0));
552
- });
553
- if (!binaryExists2)
554
- return "not-found";
555
- if (agent !== "claude")
556
- return "ok";
557
- return new Promise((resolve21) => {
558
- const child = spawn(binary, ["auth", "status", "--json"], {
559
- stdio: ["ignore", "pipe", "pipe"]
560
- });
561
- let stdout = "";
562
- let done = false;
563
- const timer = setTimeout(() => {
564
- if (!done) {
565
- done = true;
566
- child.kill("SIGTERM");
567
- resolve21("unauthenticated");
568
- }
569
- }, 5e3);
570
- child.stdout?.on("data", (chunk) => {
571
- stdout += chunk.toString();
572
- });
573
- child.on("close", (code) => {
574
- if (done)
575
- return;
576
- done = true;
577
- clearTimeout(timer);
578
- if (code !== 0) {
579
- resolve21("unauthenticated");
580
- return;
581
- }
582
- try {
583
- const status = JSON.parse(stdout);
584
- resolve21(status.loggedIn ? "ok" : "unauthenticated");
585
- } catch {
586
- resolve21("unauthenticated");
587
- }
588
- });
589
- });
590
- }
591
- function describeAgentFailure(result, maxDetail = 800) {
592
- const base = result.exitCode !== 0 ? `agent exited with code ${result.exitCode}` : "agent produced no tool calls";
593
- const detail = (result.stderr.trim() || result.stdout.trim()).slice(-maxDetail).trim();
594
- return detail ? `${base} \u2014 ${detail}` : base;
595
- }
596
- function extractSentinelOutput(stdout) {
597
- const START = "<<<EDS_OUTPUT_START>>>";
598
- const END = "<<<EDS_OUTPUT_END>>>";
599
- const startIdx = stdout.indexOf(START);
600
- const endIdx = stdout.indexOf(END);
601
- if (startIdx === -1 || endIdx === -1 || endIdx <= startIdx)
602
- return null;
603
- const secondStart = stdout.indexOf(START, startIdx + START.length);
604
- if (secondStart !== -1 && secondStart < endIdx)
605
- return "multiple";
606
- const afterStart = stdout.indexOf(END, startIdx);
607
- const secondEnd = stdout.indexOf(END, afterStart + END.length);
608
- if (secondEnd !== -1)
609
- return "multiple";
610
- return stdout.slice(startIdx + START.length, endIdx).trim();
611
- }
612
- var VALID_SELECT_TOOL_NAMES, VALID_TOOL_NAMES, VALID_TOKEN_TOOL_NAMES, VALID_CDF_TYPES, VALID_CATEGORIES, AGENT_BINARIES, BEDROCK_ENV_BY_AGENT, BEDROCK_CAPABLE_AGENTS, DEFAULT_CODEX_BEDROCK_REGION, DEFAULT_OPENCODE_MODEL, DEFAULT_MODELS, DEFAULT_CODEX_BEDROCK_MODEL;
613
- var init_agent_runner = __esm({
614
- "packages/experience-design-system-generation/dist/src/agent-runner.js"() {
615
- "use strict";
616
- init_agent_names();
617
- VALID_SELECT_TOOL_NAMES = /* @__PURE__ */ new Set(["select_component", "reject_component"]);
618
- VALID_TOOL_NAMES = /* @__PURE__ */ new Set(["classify_prop", "exclude_prop", "classify_component", "classify_slot"]);
619
- VALID_TOKEN_TOOL_NAMES = /* @__PURE__ */ new Set(["set_token", "set_group"]);
620
- VALID_CDF_TYPES = /* @__PURE__ */ new Set(["string", "richtext", "media", "enum", "token", "boolean"]);
621
- VALID_CATEGORIES = /* @__PURE__ */ new Set(["content", "design", "state"]);
622
- AGENT_BINARIES = {
623
- claude: "claude",
624
- codex: "codex",
625
- opencode: "opencode",
626
- cursor: "cursor-agent",
627
- copilot: "copilot"
628
- };
629
- BEDROCK_ENV_BY_AGENT = {
630
- claude: { CLAUDE_CODE_USE_BEDROCK: "1" }
631
- };
632
- BEDROCK_CAPABLE_AGENTS = /* @__PURE__ */ new Set(["claude", "codex", "opencode"]);
633
- DEFAULT_CODEX_BEDROCK_REGION = "us-east-1";
634
- DEFAULT_OPENCODE_MODEL = "claude-haiku-4-5";
635
- DEFAULT_MODELS = {
636
- claude: "haiku",
637
- opencode: DEFAULT_OPENCODE_MODEL,
638
- cursor: "gpt-mini",
639
- // cursor alias for gpt-5.4-mini-medium; haiku not in cursor's catalog
640
- copilot: "Auto"
641
- // the only model guaranteed on every Copilot plan (Free/Pro/Business/Enterprise); Pro+ users override via EDS_AGENT_MODEL_COPILOT
642
- };
643
- DEFAULT_CODEX_BEDROCK_MODEL = "openai.gpt-5.6-luna";
644
- }
645
- });
646
-
647
- // packages/experience-design-system-generation/dist/src/agent-invoker.js
648
- function createLocalCliAgentInvoker(options = {}) {
649
- const { onDebugEvent } = options;
650
- return {
651
- invoke(invokeOptions) {
652
- return runAgent({ ...invokeOptions, onDebugEvent });
653
- },
654
- checkAuth(agent) {
655
- return checkAgentAuth(agent);
656
- }
657
- };
658
- }
659
- var init_agent_invoker = __esm({
660
- "packages/experience-design-system-generation/dist/src/agent-invoker.js"() {
661
- "use strict";
662
- init_agent_runner();
663
- }
664
- });
665
-
666
- // packages/experience-design-system-generation/dist/src/prompt-builder.js
667
- import { existsSync } from "node:fs";
668
- import { readFile as readFile2 } from "node:fs/promises";
669
- import { dirname, join as join2, resolve } from "node:path";
670
- import { fileURLToPath } from "node:url";
671
- import { flattenDTCG } from "@contentful/experience-design-system-types";
672
- function formatCustomPromptBanner(skill, path) {
673
- return `WARNING: Custom prompt active for ${skill}: ${path}
674
- Bundled invariants (utility-wrapper rejection, description content rules) do NOT apply.
675
- You are responsible for the prompt's correctness.
676
- `;
677
- }
678
- async function buildPrompt(options) {
679
- const skillContent = options.skillContentOverride ?? await readSkillFile(options.skill, options.skillPathOverride);
680
- const preamble = buildPreamble(options);
681
- return `${preamble}
682
-
683
- Skill instructions follow:
684
- ---
685
- ${skillContent}`;
686
- }
687
- function resolveSkillPath(skill) {
688
- if (!(skill in SKILL_FILES))
689
- throw new Error(`Invalid skill: ${skill}`);
690
- const thisDir = dirname(fileURLToPath(import.meta.url));
691
- let dir = thisDir;
692
- for (; ; ) {
693
- const candidate = join2(dir, "skills");
694
- if (existsSync(candidate))
695
- return join2(candidate, SKILL_FILES[skill]);
696
- const parent = resolve(dir, "..");
697
- if (parent === dir) {
698
- throw new Error(`skill file missing from CLI installation (could not locate skills/ directory from: ${thisDir})`);
699
- }
700
- dir = parent;
701
- }
702
- }
703
- async function readSkillFile(skill, override) {
704
- if (override) {
705
- const skillPath2 = resolve(override);
706
- try {
707
- return await readFile2(skillPath2, "utf8");
708
- } catch {
709
- throw new Error(`custom prompt file not found (skill: ${skill}, path: ${skillPath2})`);
710
- }
711
- }
712
- const skillPath = resolveSkillPath(skill);
713
- try {
714
- return await readFile2(skillPath, "utf8");
715
- } catch {
716
- throw new Error(`skill file missing from CLI installation \u2014 try reinstalling the CLI (looked for: ${skillPath})`);
717
- }
718
- }
719
- function inferFenceLang(filename) {
720
- if (!filename)
721
- return "json";
722
- const ext = filename.split(".").pop()?.toLowerCase() ?? "";
723
- const map = {
724
- js: "js",
725
- mjs: "js",
726
- cjs: "js",
727
- ts: "ts",
728
- mts: "ts",
729
- cts: "ts",
730
- tsx: "tsx",
731
- jsx: "jsx",
732
- vue: "vue",
733
- svelte: "svelte",
734
- astro: "astro",
735
- scss: "scss",
736
- sass: "scss",
737
- css: "css",
738
- json: "json",
739
- json5: "json"
740
- };
741
- return map[ext] ?? "text";
742
- }
743
- function filterDesignTokenProps(cdf) {
744
- const result = {};
745
- const kinds = /* @__PURE__ */ new Set();
746
- let hasUnscoped = false;
747
- for (const [componentName, component] of Object.entries(cdf)) {
748
- const properties = component.$properties;
749
- if (!properties)
750
- continue;
751
- const filteredProps = {};
752
- for (const [propName, prop] of Object.entries(properties)) {
753
- if (prop.$type === "token" && prop.$category === "design") {
754
- const { "$token.allowed": _tokenAllowed, ...rest } = prop;
755
- filteredProps[propName] = rest;
756
- const kind = prop["$token.kind"];
757
- if (typeof kind === "string" && kind.length > 0) {
758
- kinds.add(kind);
759
- } else {
760
- hasUnscoped = true;
761
- }
762
- }
763
- }
764
- if (Object.keys(filteredProps).length > 0) {
765
- result[componentName] = { ...component, $properties: filteredProps };
766
- }
767
- }
768
- return { filtered: result, kinds: [...kinds].sort(), hasUnscoped };
769
- }
770
- function formatTokenCandidateLines(entries) {
771
- return entries.map((entry) => `${entry.path} \xB7 ${entry.$type}`).join("\n");
772
- }
773
- function renderTokenCandidateSection(kind, entries) {
774
- const label = kind ? `Token path index \u2014 ${kind} candidates only` : "Token path index \u2014 full tree (no $token.kind to scope by)";
775
- return `${label}, one leaf token per line as \`path \xB7 type\`, no \`$value\`:
776
- ${formatTokenCandidateLines(entries)}`;
777
- }
778
461
  function buildPreamble(options) {
779
462
  const { skill, rawComponentsInline, rawTokensInline, rawTokensFilename, tokensInline, tokenMapInline, generatedCdf, tokenTree, componentSourceRefs, existingComponentsInline, existingTokensInline, componentAllowlistInline } = options;
780
463
  const sections = [];
@@ -830,20 +513,8 @@ ${JSON.stringify(filteredTokenProps.filtered)}
830
513
  \`\`\``);
831
514
  }
832
515
  if (tokenTree) {
833
- const index = flattenDTCG(tokenTree, "").sort((a, b) => a.path.localeCompare(b.path));
834
- if (index.length > 0) {
835
- if (filteredTokenProps) {
836
- const { kinds, hasUnscoped } = filteredTokenProps;
837
- for (const kind of kinds) {
838
- const scoped = index.filter((entry) => entry.$type === kind);
839
- if (scoped.length > 0)
840
- sections.push(renderTokenCandidateSection(kind, scoped));
841
- }
842
- if (hasUnscoped)
843
- sections.push(renderTokenCandidateSection(null, index));
844
- } else {
845
- sections.push(renderTokenCandidateSection(null, index));
846
- }
516
+ for (const section2 of buildTokenCandidateSections(tokenTree, filteredTokenProps)) {
517
+ sections.push(section2);
847
518
  }
848
519
  }
849
520
  if (componentSourceRefs && componentSourceRefs.length > 0) {
@@ -884,153 +555,617 @@ ${JSON.stringify(withoutContent.map((ref) => ({ component: ref.component, source
884
555
  const inputBlock = sections.length > 0 ? `
885
556
 
886
557
  ${sections.join("\n\n")}` : "";
887
- if (skill === "components") {
558
+ if (skill === "components")
888
559
  return buildComponentsAutonomousPreamble(inputBlock);
889
- }
890
- if (skill === "select") {
560
+ if (skill === "select")
891
561
  return buildSelectAutonomousPreamble(inputBlock);
892
- }
893
- if (skill === "map-tokens") {
562
+ if (skill === "map-tokens")
894
563
  return buildMapTokensAutonomousPreamble(inputBlock);
895
- }
896
564
  return buildTokensAutonomousPreamble(inputBlock);
897
565
  }
898
- function buildComponentsAutonomousPreamble(inputBlock) {
899
- return `You are running as part of the experience-design-system-cli generate pipeline in AUTONOMOUS mode. The developer is not present to answer questions.
900
-
901
- Context: You are classifying a React component for **Contentful Experience Orchestration**. The result is a Component Type \u2014 a schema that tells Contentful what a marketer can configure. Properties fall into three categories:
902
- - **design**: controls how the component looks (variant, size, color, layout toggles)
903
- - **content**: the data a content editor fills in (text, images, URLs, rich text)
904
- - **state**: runtime behavioral flags (disabled, loading, expanded, identifiers)
905
-
906
- Your task: classify every prop and slot in the component below. Apply all judgment calls yourself \u2014 do not pause to ask for confirmation. Include a "description" field on each tool call to document your reasoning so the developer can review it afterward.
907
-
908
- All input data is provided inline below \u2014 do not read any additional files.${inputBlock}
909
-
910
- ## Output protocol
911
-
912
- Do NOT write any files or emit any JSON blobs. Instead, emit one JSON object per line to stdout for each classification decision. The CLI reads your stdout line by line and writes each decision directly to the pipeline database.
913
-
914
- The four tool calls you may emit are:
915
-
916
- \`\`\`
917
- {"tool":"classify_component","description":"<optional component-level description>","rationale":{"description":"<why this component is classified the way it is>","props":"<why these props were chosen>","slots":"<why these slots were chosen>"}}
918
-
919
- {"tool":"classify_prop","prop":"<propName>","cdf_type":"<type>","cdf_category":"<category>","required":<bool>,"description":"<short customer-facing description>","reason":"<full internal rationale; not customer-facing>","values":["a","b"],"token_kind":"color","default":"<value>"}
920
-
921
- {"tool":"exclude_prop","prop":"<propName>","reason":"<why excluded>"}
922
-
923
- {"tool":"classify_slot","slot":"<slotName>","required":<bool>,"allowed_components":["ComponentName"],"description":"<reason>","rationale":"<why this slot was kept in the catalog>"}
924
- \`\`\`
566
+ async function buildPrompt(options) {
567
+ const skillContent = options.skillContentOverride ?? await readSkillFile(options.skill, options.skillPathOverride);
568
+ const preamble = buildPreamble(options);
569
+ return `${preamble}
925
570
 
926
- Rules:
927
- - Emit exactly one JSON object per line. No multi-line JSON. No markdown fences around the lines.
928
- - Every prop in the input must have exactly one call: either classify_prop or exclude_prop.
929
- - Every slot in the input must have exactly one classify_slot call.
930
- - Valid cdf_type values: string, richtext, media, enum, token, boolean
931
- - Valid cdf_category values: content, design, state
932
- - For enum type, always include \`values\` (non-empty string array of the variant names the prop accepts).
933
- - For token type, always include \`token_kind\` (DTCG $type, e.g. "color"). **Never emit \`values\` for \`cdf_type: "token"\` props** \u2014 an enum prop's list holds variant names; a token prop's list holds design token paths, produced separately and never by you. Emitting \`values\` on a token prop makes the definition invalid.
934
- - Never emit both "values" and "token_kind" on one prop.
935
- - \`enum\` vs \`token\` is decided by three questions answered in order from the source shown \u2014 never from the TypeScript type. Q1: does the component look the value up, switch on it, or have a vocabulary for it (\`tokens[x]\`, \`switch (variant)\`, \`allowedValues\`)? yes \u2192 \`enum\`, stop.
936
- - Q2: is the value written straight into a style or attribute (\`rx={radius}\`, \`padding: \${padding}\`)? no \u2192 not \`token\`, apply the type rules.
937
- - Q3: is there a design-token reference at that use \u2014 a \`tokens.*\` parameter default, a \`tokenReference\`, an inline \`tokens.*\` / \`var(--*)\`? yes \u2192 \`token\` (cite both lines in "reason"); no \u2192 \`string\`. "Ambiguity resolves to \`enum\`" applies only when Q1\u2013Q3 cannot be answered from the source shown.
938
- - CSS design props (className, style, styles, positional/geometric props: top, bottom, left, right, rotation, offset, etc.) \u2192 classify_prop, cdf_type: "string", cdf_category: "design".
939
- - For \`classify_slot.allowed_components\`, use only exact names from the hard allowlist provided below. Never invent a child from an import, JSX element, type name, icon name, or implementation helper; if a child is not listed, omit it.
940
- - On classify_component, "rationale" fields are operator-facing (read-only) but may surface in customer-facing exports. The "rationale.description" field is subject to the description content rules in the skill prompt (no internal initiative names). "rationale.props" and "rationale.slots" describe your reasoning about scope; "classify_slot.rationale" explains why each slot was kept.
941
- - On classify_prop, "reason" is REQUIRED and is the LLM's internal rationale \u2014 shown to the developer reviewing the import, never to end-users. "description" is the customer-facing copy and is subject to the description content rules in the skill prompt. Keep them distinct: "description" is short and customer-facing; "reason" explains your reasoning in detail.
942
- - You may emit prose lines (not starting with {) anywhere \u2014 they are ignored by the parser and serve as your reasoning log.`;
571
+ Skill instructions follow:
572
+ ---
573
+ ${skillContent}`;
943
574
  }
944
- function buildSelectAutonomousPreamble(inputBlock) {
945
- return `You are running as part of the experience-design-system-cli import pipeline in AUTONOMOUS mode. The developer is not present to answer questions.
946
-
947
- Your task: review the components provided below and decide whether each belongs in Contentful Experience Orchestration as a Component Type. The input is a JSON array \u2014 you may receive 1\u2013N components in a single message. Emit one tool call per input component, named after the component. Apply all judgment calls yourself \u2014 do not pause to ask for confirmation. Include a brief "reason" to document your reasoning for each decision.
948
-
949
- Key rule: accept any component that renders visible UI \u2014 atoms, molecules, and organisms are all valid Component Types in Contentful Experience Orchestration. Reject only components that produce zero visual output: React hooks, pure context providers, A/B testing or variant-routing wrappers, analytics trackers, and security utilities. Do NOT reject a component because it has few props, is low-level, or has some A/B testing or personalization-related props mixed in \u2014 those props are handled in the generate step.
950
-
951
- All input data is provided inline below \u2014 do not read any additional files.${inputBlock}
952
-
953
- ## Output protocol
954
-
955
- Do NOT write any files or emit any JSON blobs. Instead, emit JSON tool calls one per line to stdout. The CLI reads your stdout line by line.
956
-
957
- The two tool calls \u2014 emit exactly one per input component:
958
-
959
- \`\`\`
960
- {"tool":"select_component","name":"<ComponentName>","reason":"<brief reason>"}
575
+ var SKILL_FILES;
576
+ var init_build_prompt = __esm({
577
+ "packages/experience-design-system-generation/dist/src/services/prompts/build-prompt.js"() {
578
+ "use strict";
579
+ init_format_token_candidates();
580
+ init_build_skill_preambles();
581
+ SKILL_FILES = {
582
+ components: "generate-components.md",
583
+ tokens: "generate-tokens.md",
584
+ select: "select-components.md",
585
+ "map-tokens": "map-tokens.md"
586
+ };
587
+ }
588
+ });
961
589
 
962
- {"tool":"reject_component","name":"<ComponentName>","reason":"<brief reason>"}
963
- \`\`\`
590
+ // packages/experience-design-system-generation/dist/src/orchestrator/execute-generation-orchestrator.js
591
+ async function executeGenerationOrchestrator(request2) {
592
+ const prompt = await buildPrompt(request2.promptOptions);
593
+ return request2.invoker.invoke({
594
+ agent: request2.agent,
595
+ model: request2.model,
596
+ bedrock: request2.bedrock,
597
+ prompt,
598
+ timeoutMs: request2.timeoutMs,
599
+ onOutput: request2.onOutput
600
+ });
601
+ }
602
+ var init_execute_generation_orchestrator = __esm({
603
+ "packages/experience-design-system-generation/dist/src/orchestrator/execute-generation-orchestrator.js"() {
604
+ "use strict";
605
+ init_build_prompt();
606
+ }
607
+ });
964
608
 
965
- Rules:
966
- - Emit exactly one JSON object per line. No multi-line JSON. No markdown fences.
967
- - Emit exactly one tool call per input component. The "name" field must match a component name from the input array exactly. Tool calls may appear in any order.
968
- - You may emit prose lines (not starting with {) to reason before each tool call \u2014 they are ignored by the parser.`;
609
+ // packages/experience-design-system-generation/dist/src/services/agent/helpers/resolve-agent-binary.js
610
+ function resolveAgentBinary(agent) {
611
+ const envKey = `EDS_AGENT_BINARY_${agent.toUpperCase()}`;
612
+ const override = process.env[envKey];
613
+ if (override && override.trim())
614
+ return override.trim();
615
+ return AGENT_BINARIES[agent];
969
616
  }
970
- function buildMapTokensAutonomousPreamble(inputBlock) {
971
- return `You are running as part of the experience-design-system-cli generate pipeline in AUTONOMOUS mode. The developer is not present to answer questions.
617
+ var AGENT_BINARIES;
618
+ var init_resolve_agent_binary = __esm({
619
+ "packages/experience-design-system-generation/dist/src/services/agent/helpers/resolve-agent-binary.js"() {
620
+ "use strict";
621
+ AGENT_BINARIES = {
622
+ claude: "claude",
623
+ codex: "codex",
624
+ opencode: "opencode",
625
+ cursor: "cursor-agent",
626
+ copilot: "copilot"
627
+ };
628
+ }
629
+ });
972
630
 
973
- Context: The components below already have design-category, token-typed props (\`$token.kind\` set). Your task is to decide, from source evidence, whether to narrow each one to a restricted subset (\`token_allowed\`) of the tokens matching its \`$token.kind\`. Apply all judgment calls yourself \u2014 do not pause to ask for confirmation.
631
+ // packages/experience-design-system-generation/dist/src/services/agent/helpers/build-agent-args.js
632
+ function agentSupportsBedrock(agent) {
633
+ return BEDROCK_CAPABLE_AGENTS.has(agent);
634
+ }
635
+ function withBedrockProviderPrefix(model) {
636
+ return model.includes("/") ? model : `amazon-bedrock/${model}`;
637
+ }
638
+ function resolveAgentModel(agent, explicit, bedrock = false) {
639
+ if (explicit && explicit.trim())
640
+ return explicit.trim();
641
+ const override = process.env[`EDS_AGENT_MODEL_${agent.toUpperCase()}`];
642
+ if (override && override.trim())
643
+ return override.trim();
644
+ if (bedrock && agent === "codex")
645
+ return DEFAULT_CODEX_BEDROCK_MODEL;
646
+ if (bedrock && agent === "opencode")
647
+ return withBedrockProviderPrefix(DEFAULT_OPENCODE_MODEL);
648
+ return DEFAULT_MODELS[agent];
649
+ }
650
+ function codexBedrockConfigArgs() {
651
+ const region = process.env.AWS_REGION?.trim() || process.env.AWS_DEFAULT_REGION?.trim() || DEFAULT_CODEX_BEDROCK_REGION;
652
+ return ["-c", "model_provider=amazon-bedrock", "-c", `model_providers.amazon-bedrock.region=${region}`];
653
+ }
654
+ function buildAgentArgs(agent, prompt, model, promptViaStdin = false, bedrock = false) {
655
+ const resolvedModel = resolveAgentModel(agent, model, bedrock);
656
+ const modelArg = resolvedModel ? ["--model", resolvedModel] : [];
657
+ const promptArg = promptViaStdin ? [] : [prompt];
658
+ switch (agent) {
659
+ case "claude":
660
+ return ["--print", ...modelArg, ...promptArg];
661
+ case "codex": {
662
+ const bedrockArgs = bedrock ? codexBedrockConfigArgs() : [];
663
+ return ["exec", ...bedrockArgs, ...modelArg, "--dangerously-bypass-approvals-and-sandbox", ...promptArg];
664
+ }
665
+ case "opencode":
666
+ return ["run", ...modelArg, ...promptArg];
667
+ case "cursor":
668
+ return ["--print", ...modelArg, ...promptArg];
669
+ case "copilot": {
670
+ const copilotModel = resolveAgentModel("copilot", model);
671
+ const copilotModelArg = !copilotModel || copilotModel === "Auto" ? [] : ["--model", copilotModel];
672
+ return ["-p", ...promptArg, ...copilotModelArg, "--allow-all-tools"];
673
+ }
674
+ }
675
+ }
676
+ var BEDROCK_ENV_BY_AGENT, BEDROCK_CAPABLE_AGENTS, DEFAULT_CODEX_BEDROCK_REGION, DEFAULT_OPENCODE_MODEL, DEFAULT_CODEX_BEDROCK_MODEL, DEFAULT_MODELS;
677
+ var init_build_agent_args = __esm({
678
+ "packages/experience-design-system-generation/dist/src/services/agent/helpers/build-agent-args.js"() {
679
+ "use strict";
680
+ BEDROCK_ENV_BY_AGENT = {
681
+ claude: { CLAUDE_CODE_USE_BEDROCK: "1" }
682
+ };
683
+ BEDROCK_CAPABLE_AGENTS = /* @__PURE__ */ new Set(["claude", "codex", "opencode"]);
684
+ DEFAULT_CODEX_BEDROCK_REGION = "us-east-1";
685
+ DEFAULT_OPENCODE_MODEL = "claude-haiku-4-5";
686
+ DEFAULT_CODEX_BEDROCK_MODEL = "openai.gpt-5.6-luna";
687
+ DEFAULT_MODELS = {
688
+ claude: "haiku",
689
+ opencode: DEFAULT_OPENCODE_MODEL,
690
+ cursor: "gpt-mini",
691
+ copilot: "Auto"
692
+ };
693
+ }
694
+ });
974
695
 
975
- All input data is provided inline below \u2014 do not read any additional files.${inputBlock}
696
+ // packages/experience-design-system-generation/dist/src/services/agent/run-agent.js
697
+ import { spawn } from "node:child_process";
698
+ function describeAgentFailure(result, maxDetail = 800) {
699
+ const base = result.exitCode !== 0 ? `agent exited with code ${result.exitCode}` : "agent produced no tool calls";
700
+ const detail = (result.stderr.trim() || result.stdout.trim()).slice(-maxDetail).trim();
701
+ return detail ? `${base} \u2014 ${detail}` : base;
702
+ }
703
+ function extractSentinelOutput(stdout) {
704
+ const START = "<<<EDS_OUTPUT_START>>>";
705
+ const END = "<<<EDS_OUTPUT_END>>>";
706
+ const startIdx = stdout.indexOf(START);
707
+ const endIdx = stdout.indexOf(END);
708
+ if (startIdx === -1 || endIdx === -1 || endIdx <= startIdx)
709
+ return null;
710
+ const secondStart = stdout.indexOf(START, startIdx + START.length);
711
+ if (secondStart !== -1 && secondStart < endIdx)
712
+ return "multiple";
713
+ const afterStart = stdout.indexOf(END, startIdx);
714
+ const secondEnd = stdout.indexOf(END, afterStart + END.length);
715
+ if (secondEnd !== -1)
716
+ return "multiple";
717
+ return stdout.slice(startIdx + START.length, endIdx).trim();
718
+ }
719
+ async function runAgent(options) {
720
+ const { agent, prompt, timeoutMs, model, onOutput, promptViaStdin, onDebugEvent } = options;
721
+ const bedrock = options.bedrock ?? process.env.EDS_BEDROCK === "1";
722
+ const binary = resolveAgentBinary(agent);
723
+ const useStdin2 = !!promptViaStdin;
724
+ const args = buildAgentArgs(agent, prompt, model, useStdin2, bedrock);
725
+ const startedAt = Date.now();
726
+ onDebugEvent?.("run.start", {
727
+ agent,
728
+ binary,
729
+ model,
730
+ bedrock: !!bedrock,
731
+ timeoutMs,
732
+ promptLen: prompt.length,
733
+ promptHead: prompt.slice(0, 500)
734
+ });
735
+ return new Promise((resolve21) => {
736
+ const bedrockEnv = bedrock ? BEDROCK_ENV_BY_AGENT[agent] : void 0;
737
+ const child = spawn(binary, args, {
738
+ stdio: ["pipe", "pipe", "pipe"],
739
+ ...bedrockEnv ? { env: { ...process.env, ...bedrockEnv } } : {}
740
+ });
741
+ if (useStdin2 && child.stdin) {
742
+ child.stdin.on("error", () => {
743
+ });
744
+ child.stdin.write(prompt, () => {
745
+ child.stdin?.end();
746
+ });
747
+ } else {
748
+ child.stdin?.end();
749
+ }
750
+ let stdout = "";
751
+ let stderr = "";
752
+ let timedOut = false;
753
+ const timer = setTimeout(() => {
754
+ timedOut = true;
755
+ child.kill("SIGTERM");
756
+ }, timeoutMs);
757
+ child.stdout?.on("data", (chunk) => {
758
+ const text = chunk.toString();
759
+ stdout += text;
760
+ onOutput?.(text);
761
+ });
762
+ child.stderr?.on("data", (chunk) => {
763
+ stderr += chunk.toString();
764
+ });
765
+ child.on("close", (code, signal) => {
766
+ clearTimeout(timer);
767
+ const result = {
768
+ exitCode: signal ? 1 : code ?? 1,
769
+ stdout,
770
+ stderr,
771
+ timedOut
772
+ };
773
+ onDebugEvent?.("run.end", {
774
+ agent,
775
+ model,
776
+ durationMs: Date.now() - startedAt,
777
+ exitCode: result.exitCode,
778
+ signal,
779
+ timedOut,
780
+ stdoutLen: stdout.length,
781
+ stderrLen: stderr.length,
782
+ stderrTail: stderr.slice(-1e3)
783
+ });
784
+ resolve21(result);
785
+ });
786
+ });
787
+ }
788
+ var init_run_agent = __esm({
789
+ "packages/experience-design-system-generation/dist/src/services/agent/run-agent.js"() {
790
+ "use strict";
791
+ init_resolve_agent_binary();
792
+ init_build_agent_args();
793
+ }
794
+ });
976
795
 
977
- ## Output protocol
796
+ // packages/experience-design-system-generation/dist/src/services/agent/helpers/check-agent-auth.js
797
+ import { spawn as spawn2 } from "node:child_process";
798
+ async function checkAgentAuth(agent) {
799
+ const binary = resolveAgentBinary(agent);
800
+ const binaryExists2 = await new Promise((resolve21) => {
801
+ if (binary.startsWith("/")) {
802
+ import("node:fs/promises").then((fs2) => fs2.access(binary).then(() => resolve21(true), () => resolve21(false)));
803
+ return;
804
+ }
805
+ const child = spawn2(process.platform === "win32" ? "where" : "which", [binary], { stdio: "ignore" });
806
+ child.on("close", (code) => resolve21(code === 0));
807
+ });
808
+ if (!binaryExists2)
809
+ return "not-found";
810
+ if (agent !== "claude")
811
+ return "ok";
812
+ return new Promise((resolve21) => {
813
+ const child = spawn2(binary, ["auth", "status", "--json"], {
814
+ stdio: ["ignore", "pipe", "pipe"]
815
+ });
816
+ let stdout = "";
817
+ let done = false;
818
+ const timer = setTimeout(() => {
819
+ if (!done) {
820
+ done = true;
821
+ child.kill("SIGTERM");
822
+ resolve21("unauthenticated");
823
+ }
824
+ }, 5e3);
825
+ child.stdout?.on("data", (chunk) => {
826
+ stdout += chunk.toString();
827
+ });
828
+ child.on("close", (code) => {
829
+ if (done)
830
+ return;
831
+ done = true;
832
+ clearTimeout(timer);
833
+ if (code !== 0) {
834
+ resolve21("unauthenticated");
835
+ return;
836
+ }
837
+ try {
838
+ const status = JSON.parse(stdout);
839
+ resolve21(status.loggedIn ? "ok" : "unauthenticated");
840
+ } catch {
841
+ resolve21("unauthenticated");
842
+ }
843
+ });
844
+ });
845
+ }
846
+ var init_check_agent_auth = __esm({
847
+ "packages/experience-design-system-generation/dist/src/services/agent/helpers/check-agent-auth.js"() {
848
+ "use strict";
849
+ init_resolve_agent_binary();
850
+ }
851
+ });
978
852
 
979
- Do NOT write any files or emit any JSON blobs. Instead, emit one JSON object per line to stdout for each prop you narrow. The CLI reads your stdout line by line and writes each decision directly to the pipeline database.
853
+ // packages/experience-design-system-generation/dist/src/services/agent/local-cli-agent-invoker.js
854
+ function createLocalCliAgentInvoker(options = {}) {
855
+ const { onDebugEvent } = options;
856
+ return {
857
+ invoke(invokeOptions) {
858
+ return runAgent({ ...invokeOptions, onDebugEvent });
859
+ },
860
+ checkAuth(agent) {
861
+ return checkAgentAuth(agent);
862
+ }
863
+ };
864
+ }
865
+ var init_local_cli_agent_invoker = __esm({
866
+ "packages/experience-design-system-generation/dist/src/services/agent/local-cli-agent-invoker.js"() {
867
+ "use strict";
868
+ init_run_agent();
869
+ init_check_agent_auth();
870
+ }
871
+ });
980
872
 
981
- The one tool call you may emit:
873
+ // packages/experience-design-system-generation/dist/src/controller/create-generation-endpoint.js
874
+ function createGenerationEndpoint(options = {}) {
875
+ const invoker2 = createLocalCliAgentInvoker({ onDebugEvent: options.onDebugEvent });
876
+ return {
877
+ async run(request2) {
878
+ validateGenerationRequest(request2);
879
+ return executeGenerationOrchestrator({ ...request2, invoker: invoker2 });
880
+ },
881
+ checkAuth(agent) {
882
+ return invoker2.checkAuth(agent);
883
+ }
884
+ };
885
+ }
886
+ var init_create_generation_endpoint = __esm({
887
+ "packages/experience-design-system-generation/dist/src/controller/create-generation-endpoint.js"() {
888
+ "use strict";
889
+ init_validate_generation_request();
890
+ init_execute_generation_orchestrator();
891
+ init_local_cli_agent_invoker();
892
+ }
893
+ });
982
894
 
983
- \`\`\`
984
- {"tool":"map_token_prop","component":"<ComponentName>","prop":"<propName>","token_allowed":["colors.brand.primary","colors.brand.secondary"]}
985
- \`\`\`
895
+ // packages/experience-design-system-generation/dist/src/services/parsing/helpers/read-tool-call-objects.js
896
+ function findJsonObjectEnd(line) {
897
+ let depth = 0;
898
+ let inString = false;
899
+ let escaped = false;
900
+ for (let i = 0; i < line.length; i++) {
901
+ const ch = line[i];
902
+ if (escaped) {
903
+ escaped = false;
904
+ } else if (ch === "\\" && inString) {
905
+ escaped = true;
906
+ } else if (ch === '"') {
907
+ inString = !inString;
908
+ } else if (!inString && ch === "{") {
909
+ depth++;
910
+ } else if (!inString && ch === "}" && --depth === 0) {
911
+ return i;
912
+ }
913
+ }
914
+ return -1;
915
+ }
916
+ function readToolCallObjects(stdout) {
917
+ const objects = [];
918
+ const warnings = [];
919
+ for (const raw of stdout.split("\n")) {
920
+ const line = raw.trim();
921
+ if (!line.startsWith("{"))
922
+ continue;
923
+ const end = findJsonObjectEnd(line);
924
+ if (end === -1) {
925
+ warnings.push(`unparseable line: ${line.slice(0, 120)}`);
926
+ continue;
927
+ }
928
+ let parsed;
929
+ try {
930
+ parsed = JSON.parse(line.slice(0, end + 1));
931
+ } catch {
932
+ warnings.push(`unparseable line: ${line.slice(0, 120)}`);
933
+ continue;
934
+ }
935
+ const trailing = line.slice(end + 1);
936
+ if (trailing.trim()) {
937
+ warnings.push(`ignored trailing content after JSON: ${trailing.trim().slice(0, 120)}`);
938
+ }
939
+ if (typeof parsed === "object" && parsed !== null && "tool" in parsed) {
940
+ objects.push(parsed);
941
+ }
942
+ }
943
+ return { objects, warnings };
944
+ }
945
+ var init_read_tool_call_objects = __esm({
946
+ "packages/experience-design-system-generation/dist/src/services/parsing/helpers/read-tool-call-objects.js"() {
947
+ "use strict";
948
+ }
949
+ });
986
950
 
987
- Rules:
988
- - Emit exactly one JSON object per line. No multi-line JSON. No markdown fences around the lines.
989
- - Only emit a call for a prop that appears in the "Generated CDF so far" section.
990
- - Each "Token path index" section below is already scoped to one \`$token.kind\` \u2014 a prop only draws candidates from the section matching its own \`$token.kind\` (or the "full tree" section, for a prop with no \`$token.kind\`). Never cross sections, never emit a group/prefix path, and never invent a path \u2014 every entry in \`token_allowed\` must exist verbatim in the matching section.
991
- - \`token_allowed\` is required and must be non-empty when the call is emitted.
992
- - For the judgment call of whether a prop should be narrowed at all, follow the decision tree in the map-tokens skill file: it explains defaults vs. restrictions, misclassified variant-name props, and when to emit nothing.
993
- - You may emit prose lines (not starting with \`{\`) anywhere \u2014 they are ignored by the parser and serve as your reasoning log.`;
951
+ // packages/experience-design-system-generation/dist/src/services/parsing/parse-prop-tool-calls.js
952
+ function parsePropToolCallLines(stdout) {
953
+ const calls = [];
954
+ const { objects, warnings } = readToolCallObjects(stdout);
955
+ for (const rec of objects) {
956
+ if (!VALID_TOOL_NAMES.has(rec.tool)) {
957
+ warnings.push(`unknown tool: ${String(rec.tool)}`);
958
+ continue;
959
+ }
960
+ const tool = rec.tool;
961
+ if (tool === "classify_prop") {
962
+ if (typeof rec.prop !== "string" || !rec.prop) {
963
+ warnings.push("classify_prop missing prop name \u2014 skipped");
964
+ continue;
965
+ }
966
+ if (typeof rec.cdf_type !== "string" || !VALID_CDF_TYPES.has(rec.cdf_type)) {
967
+ warnings.push(`classify_prop '${rec.prop}': invalid cdf_type '${String(rec.cdf_type)}' \u2014 skipped`);
968
+ continue;
969
+ }
970
+ if (typeof rec.cdf_category !== "string" || !VALID_CATEGORIES.has(rec.cdf_category)) {
971
+ warnings.push(`classify_prop '${rec.prop}': invalid cdf_category '${String(rec.cdf_category)}' \u2014 skipped`);
972
+ continue;
973
+ }
974
+ const call = {
975
+ tool: "classify_prop",
976
+ prop: rec.prop,
977
+ cdf_type: rec.cdf_type,
978
+ cdf_category: rec.cdf_category
979
+ };
980
+ if (Array.isArray(rec.values) && rec.values.every((v) => typeof v === "string"))
981
+ call.values = rec.values;
982
+ if (typeof rec.token_kind === "string")
983
+ call.token_kind = rec.token_kind;
984
+ if (typeof rec.required === "boolean")
985
+ call.required = rec.required;
986
+ if (typeof rec.description === "string")
987
+ call.description = rec.description;
988
+ if (typeof rec.default === "string" || typeof rec.default === "boolean")
989
+ call.default = rec.default;
990
+ if (typeof rec.reason === "string")
991
+ call.reason = rec.reason;
992
+ calls.push(call);
993
+ } else if (tool === "exclude_prop") {
994
+ if (typeof rec.prop !== "string" || !rec.prop) {
995
+ warnings.push("exclude_prop missing prop name \u2014 skipped");
996
+ continue;
997
+ }
998
+ calls.push({ tool: "exclude_prop", prop: rec.prop, reason: typeof rec.reason === "string" ? rec.reason : "" });
999
+ } else if (tool === "classify_component") {
1000
+ const call = { tool: "classify_component" };
1001
+ if (typeof rec.description === "string")
1002
+ call.description = rec.description;
1003
+ if (typeof rec.rationale === "object" && rec.rationale !== null) {
1004
+ const r = rec.rationale;
1005
+ const rationale = {};
1006
+ if (typeof r.description === "string")
1007
+ rationale.description = r.description;
1008
+ if (typeof r.props === "string")
1009
+ rationale.props = r.props;
1010
+ if (typeof r.slots === "string")
1011
+ rationale.slots = r.slots;
1012
+ if (Object.keys(rationale).length > 0)
1013
+ call.rationale = rationale;
1014
+ }
1015
+ calls.push(call);
1016
+ } else if (tool === "classify_slot") {
1017
+ if (typeof rec.slot !== "string" || !rec.slot) {
1018
+ warnings.push("classify_slot missing slot name \u2014 skipped");
1019
+ continue;
1020
+ }
1021
+ const call = { tool: "classify_slot", slot: rec.slot };
1022
+ if (typeof rec.required === "boolean")
1023
+ call.required = rec.required;
1024
+ if (Array.isArray(rec.allowed_components) && rec.allowed_components.every((v) => typeof v === "string")) {
1025
+ call.allowed_components = rec.allowed_components;
1026
+ }
1027
+ if (typeof rec.description === "string")
1028
+ call.description = rec.description;
1029
+ if (typeof rec.rationale === "string")
1030
+ call.rationale = rec.rationale;
1031
+ calls.push(call);
1032
+ }
1033
+ }
1034
+ return { calls, warnings };
994
1035
  }
995
- function buildTokensAutonomousPreamble(inputBlock) {
996
- return `You are running as part of the experience-design-system-cli generate pipeline in AUTONOMOUS mode. The developer is not present to answer questions.
997
-
998
- Your task: classify every raw token from the input below into a DTCG token tree. Apply all judgment calls yourself \u2014 do not pause to ask for confirmation. Include a "description" field on each set_token call to document your reasoning.
999
-
1000
- All input data is provided inline below \u2014 do not read any additional files.${inputBlock}
1001
-
1002
- ## Output protocol
1003
-
1004
- Do NOT write any files or emit any JSON blobs. Instead, emit one JSON object per line to stdout for each token or group. The CLI reads your stdout line by line and writes each entry directly to the pipeline database.
1005
-
1006
- The two tool calls you may emit are:
1036
+ var VALID_TOOL_NAMES, VALID_CDF_TYPES, VALID_CATEGORIES;
1037
+ var init_parse_prop_tool_calls = __esm({
1038
+ "packages/experience-design-system-generation/dist/src/services/parsing/parse-prop-tool-calls.js"() {
1039
+ "use strict";
1040
+ init_read_tool_call_objects();
1041
+ VALID_TOOL_NAMES = /* @__PURE__ */ new Set(["classify_prop", "exclude_prop", "classify_component", "classify_slot"]);
1042
+ VALID_CDF_TYPES = /* @__PURE__ */ new Set(["string", "richtext", "media", "enum", "token", "boolean"]);
1043
+ VALID_CATEGORIES = /* @__PURE__ */ new Set(["content", "design", "state"]);
1044
+ }
1045
+ });
1007
1046
 
1008
- \`\`\`
1009
- {"tool":"set_group","path":"<dot.notation.path>","description":"<optional group description>"}
1047
+ // packages/experience-design-system-generation/dist/src/services/parsing/parse-select-tool-calls.js
1048
+ function parseSelectToolCallLines(stdout) {
1049
+ const calls = [];
1050
+ const { objects, warnings } = readToolCallObjects(stdout);
1051
+ for (const rec of objects) {
1052
+ if (!VALID_SELECT_TOOL_NAMES.has(rec.tool))
1053
+ continue;
1054
+ if (typeof rec.name !== "string" || !rec.name) {
1055
+ warnings.push(`${String(rec.tool)} missing name \u2014 skipped`);
1056
+ continue;
1057
+ }
1058
+ const call = { tool: rec.tool, name: rec.name };
1059
+ if (typeof rec.reason === "string")
1060
+ call.reason = rec.reason;
1061
+ if (typeof rec.confidence === "number" && rec.confidence >= 1 && rec.confidence <= 5) {
1062
+ if (call.tool === "select_component") {
1063
+ call.confidence = rec.confidence;
1064
+ } else {
1065
+ call.confidence = rec.confidence;
1066
+ }
1067
+ }
1068
+ calls.push(call);
1069
+ }
1070
+ return { calls, warnings };
1071
+ }
1072
+ var VALID_SELECT_TOOL_NAMES;
1073
+ var init_parse_select_tool_calls = __esm({
1074
+ "packages/experience-design-system-generation/dist/src/services/parsing/parse-select-tool-calls.js"() {
1075
+ "use strict";
1076
+ init_read_tool_call_objects();
1077
+ VALID_SELECT_TOOL_NAMES = /* @__PURE__ */ new Set(["select_component", "reject_component"]);
1078
+ }
1079
+ });
1010
1080
 
1011
- {"tool":"set_token","path":"<dot.notation.path>","type":"<DTCG type>","value":<value>,"description":"<reason>"}
1012
- \`\`\`
1081
+ // packages/experience-design-system-generation/dist/src/services/parsing/parse-token-tool-calls.js
1082
+ function parseTokenToolCallLines(stdout) {
1083
+ const calls = [];
1084
+ const { objects, warnings } = readToolCallObjects(stdout);
1085
+ for (const rec of objects) {
1086
+ if (!VALID_TOKEN_TOOL_NAMES.has(rec.tool))
1087
+ continue;
1088
+ if (rec.tool === "set_token") {
1089
+ if (typeof rec.path !== "string" || !rec.path) {
1090
+ warnings.push("set_token missing path \u2014 skipped");
1091
+ continue;
1092
+ }
1093
+ if (typeof rec.type !== "string" || !rec.type) {
1094
+ warnings.push(`set_token '${rec.path}': missing type \u2014 skipped`);
1095
+ continue;
1096
+ }
1097
+ if (!("value" in rec)) {
1098
+ warnings.push(`set_token '${rec.path}': missing value \u2014 skipped`);
1099
+ continue;
1100
+ }
1101
+ const call = { tool: "set_token", path: rec.path, type: rec.type, value: rec.value };
1102
+ if (typeof rec.description === "string")
1103
+ call.description = rec.description;
1104
+ calls.push(call);
1105
+ } else if (rec.tool === "set_group") {
1106
+ if (typeof rec.path !== "string" || !rec.path) {
1107
+ warnings.push("set_group missing path \u2014 skipped");
1108
+ continue;
1109
+ }
1110
+ const call = { tool: "set_group", path: rec.path };
1111
+ if (typeof rec.description === "string")
1112
+ call.description = rec.description;
1113
+ calls.push(call);
1114
+ }
1115
+ }
1116
+ return { calls, warnings };
1117
+ }
1118
+ var VALID_TOKEN_TOOL_NAMES;
1119
+ var init_parse_token_tool_calls = __esm({
1120
+ "packages/experience-design-system-generation/dist/src/services/parsing/parse-token-tool-calls.js"() {
1121
+ "use strict";
1122
+ init_read_tool_call_objects();
1123
+ VALID_TOKEN_TOOL_NAMES = /* @__PURE__ */ new Set(["set_token", "set_group"]);
1124
+ }
1125
+ });
1013
1126
 
1014
- Rules:
1015
- - Emit exactly one JSON object per line. No multi-line JSON. No markdown fences.
1016
- - Emit a set_group call for every intermediate group node in the tree.
1017
- - Emit a set_token call for every leaf token.
1018
- - "path" is dot-notation, e.g. "colors.brand.primary" \u2014 no leading dots or slashes.
1019
- - "type" must be one of the 13 valid DTCG types: color, dimension, fontFamily, fontWeight, duration, cubicBezier, number, strokeStyle, border, transition, shadow, gradient, typography.
1020
- - "value" must be valid JSON (string, number, array, or object depending on the type). Do NOT wrap it in quotes if it is a complex type.
1021
- - Emit set_group calls before the set_token calls that fall under them.
1022
- - You may emit prose lines (not starting with {) anywhere \u2014 they are ignored by the parser and serve as your reasoning log.`;
1127
+ // packages/experience-design-system-generation/dist/src/services/parsing/parse-map-token-tool-calls.js
1128
+ function isStringArray(value) {
1129
+ return Array.isArray(value) && value.every((v) => typeof v === "string");
1023
1130
  }
1024
- var SKILL_FILES;
1025
- var init_prompt_builder = __esm({
1026
- "packages/experience-design-system-generation/dist/src/prompt-builder.js"() {
1131
+ function parseMapTokenPropToolCallLines(stdout) {
1132
+ const calls = [];
1133
+ const warnings = [];
1134
+ for (const raw of stdout.split("\n")) {
1135
+ const line = raw.trim();
1136
+ if (!line.startsWith("{"))
1137
+ continue;
1138
+ let obj;
1139
+ try {
1140
+ obj = JSON.parse(line);
1141
+ } catch {
1142
+ warnings.push(`unparseable line: ${line.slice(0, 120)}`);
1143
+ continue;
1144
+ }
1145
+ if (typeof obj !== "object" || obj === null || !("tool" in obj))
1146
+ continue;
1147
+ const rec = obj;
1148
+ if (rec.tool !== "map_token_prop")
1149
+ continue;
1150
+ if (typeof rec.component !== "string" || !rec.component) {
1151
+ warnings.push("map_token_prop missing component \u2014 skipped");
1152
+ continue;
1153
+ }
1154
+ if (typeof rec.prop !== "string" || !rec.prop) {
1155
+ warnings.push(`map_token_prop '${rec.component}': missing prop \u2014 skipped`);
1156
+ continue;
1157
+ }
1158
+ if (!isStringArray(rec.token_allowed) || rec.token_allowed.length === 0) {
1159
+ warnings.push(`map_token_prop '${rec.component}.${String(rec.prop)}': missing or empty token_allowed \u2014 skipped`);
1160
+ continue;
1161
+ }
1162
+ calls.push({ tool: "map_token_prop", component: rec.component, prop: rec.prop, token_allowed: rec.token_allowed });
1163
+ }
1164
+ return { calls, warnings };
1165
+ }
1166
+ var init_parse_map_token_tool_calls = __esm({
1167
+ "packages/experience-design-system-generation/dist/src/services/parsing/parse-map-token-tool-calls.js"() {
1027
1168
  "use strict";
1028
- SKILL_FILES = {
1029
- components: "generate-components.md",
1030
- tokens: "generate-tokens.md",
1031
- select: "select-components.md",
1032
- "map-tokens": "map-tokens.md"
1033
- };
1034
1169
  }
1035
1170
  });
1036
1171
 
@@ -1050,11 +1185,13 @@ __export(src_exports, {
1050
1185
  AGENT_NAMES: () => AGENT_NAMES,
1051
1186
  DEFAULT_AGENT_NAME: () => DEFAULT_AGENT_NAME,
1052
1187
  agentSupportsBedrock: () => agentSupportsBedrock,
1053
- buildArgs: () => buildArgs,
1188
+ buildArgs: () => buildAgentArgs,
1054
1189
  buildPrompt: () => buildPrompt,
1055
1190
  checkAgentAuth: () => checkAgentAuth,
1191
+ createGenerationEndpoint: () => createGenerationEndpoint,
1056
1192
  createLocalCliAgentInvoker: () => createLocalCliAgentInvoker,
1057
1193
  describeAgentFailure: () => describeAgentFailure,
1194
+ executeGenerationOrchestrator: () => executeGenerationOrchestrator,
1058
1195
  extractSentinelOutput: () => extractSentinelOutput,
1059
1196
  formatCustomPromptBanner: () => formatCustomPromptBanner,
1060
1197
  formatGenerateProgressLine: () => formatGenerateProgressLine,
@@ -1062,9 +1199,9 @@ __export(src_exports, {
1062
1199
  parseMapTokenPropToolCallLines: () => parseMapTokenPropToolCallLines,
1063
1200
  parseSelectToolCallLines: () => parseSelectToolCallLines,
1064
1201
  parseTokenToolCallLines: () => parseTokenToolCallLines,
1065
- parseToolCallLines: () => parseToolCallLines,
1202
+ parseToolCallLines: () => parsePropToolCallLines,
1066
1203
  resolveAgentModel: () => resolveAgentModel,
1067
- resolveBinary: () => resolveBinary,
1204
+ resolveBinary: () => resolveAgentBinary,
1068
1205
  resolveSkillPath: () => resolveSkillPath,
1069
1206
  runAgent: () => runAgent
1070
1207
  });
@@ -1072,10 +1209,19 @@ var init_src = __esm({
1072
1209
  "packages/experience-design-system-generation/dist/src/index.js"() {
1073
1210
  "use strict";
1074
1211
  init_agent_names();
1075
- init_agent_runner();
1076
- init_agent_invoker();
1077
- init_prompt_builder();
1212
+ init_create_generation_endpoint();
1213
+ init_execute_generation_orchestrator();
1214
+ init_build_agent_args();
1215
+ init_resolve_agent_binary();
1216
+ init_check_agent_auth();
1217
+ init_run_agent();
1218
+ init_parse_prop_tool_calls();
1219
+ init_parse_select_tool_calls();
1220
+ init_parse_token_tool_calls();
1221
+ init_parse_map_token_tool_calls();
1222
+ init_build_prompt();
1078
1223
  init_progress();
1224
+ init_local_cli_agent_invoker();
1079
1225
  }
1080
1226
  });
1081
1227
 
@@ -1213,8 +1359,8 @@ function makeSessionTimestamp() {
1213
1359
  const override = process.env["EDSI_DEBUG_TS"];
1214
1360
  if (override) return override;
1215
1361
  const now = /* @__PURE__ */ new Date();
1216
- const pad3 = (n, w = 2) => n.toString().padStart(w, "0");
1217
- return `${now.getUTCFullYear()}${pad3(now.getUTCMonth() + 1)}${pad3(now.getUTCDate())}T${pad3(now.getUTCHours())}${pad3(now.getUTCMinutes())}${pad3(now.getUTCSeconds())}Z`;
1362
+ const pad = (n, w = 2) => n.toString().padStart(w, "0");
1363
+ return `${now.getUTCFullYear()}${pad(now.getUTCMonth() + 1)}${pad(now.getUTCDate())}T${pad(now.getUTCHours())}${pad(now.getUTCMinutes())}${pad(now.getUTCSeconds())}Z`;
1218
1364
  }
1219
1365
  function initDebugLogger(opts) {
1220
1366
  if (singleton) return singleton;
@@ -2011,8 +2157,8 @@ function deleteRawTokensForSession(db, sessionId2) {
2011
2157
  }
2012
2158
  function createRawTokenGroups(db, sessionId2, groups) {
2013
2159
  const insertGroup = db.prepare(`INSERT INTO raw_token_groups (session_id, path, description) VALUES (?, ?, ?)`);
2014
- for (const group2 of groups) {
2015
- insertGroup.run(sessionId2, group2.path, group2.$description ?? null);
2160
+ for (const group of groups) {
2161
+ insertGroup.run(sessionId2, group.path, group.$description ?? null);
2016
2162
  }
2017
2163
  }
2018
2164
  function createRawTokens(db, sessionId2, tokens) {
@@ -4910,7 +5056,7 @@ async function readFileInline(path) {
4910
5056
  return parts.filter(Boolean).join("\n\n");
4911
5057
  }
4912
5058
  function printFallbackInstructions(options) {
4913
- const binary = resolveBinary(options.agent);
5059
+ const binary = resolveAgentBinary(options.agent);
4914
5060
  const skillPath = resolveSkillPath(options.skill);
4915
5061
  const lines = [
4916
5062
  `Error: agent '${options.agent}' not found in $PATH (looked for binary: ${binary}).`,
@@ -5125,7 +5271,7 @@ ${outputBuf}`);
5125
5271
  lastError = describeAgentFailure(result);
5126
5272
  continue;
5127
5273
  }
5128
- const { calls, warnings } = parseToolCallLines(result.stdout);
5274
+ const { calls, warnings } = parsePropToolCallLines(result.stdout);
5129
5275
  if (calls.length === 0) {
5130
5276
  lastError = describeAgentFailure(result);
5131
5277
  continue;
@@ -5371,7 +5517,7 @@ async function runGenerateSkill(skill, opts, verbose = false) {
5371
5517
  process.stdout.write(prompt + "\n");
5372
5518
  await exitWithAnalytics(0);
5373
5519
  }
5374
- const binary = resolveBinary(agent);
5520
+ const binary = resolveAgentBinary(agent);
5375
5521
  if (!await assertBinaryInPath(binary)) {
5376
5522
  printFallbackInstructions({
5377
5523
  agent,
@@ -6891,24 +7037,24 @@ function parseEdsiError(rawInput) {
6891
7037
  }
6892
7038
  }
6893
7039
  const cleaned = stripLambdaLogPrefix(body);
6894
- const json2 = parseJsonBody(cleaned) ?? parseJsonBody(body);
6895
- const bindingFromJson = typeof json2?.message === "string" ? parseBindingDiagnostics(json2.message) : null;
7040
+ const json = parseJsonBody(cleaned) ?? parseJsonBody(body);
7041
+ const bindingFromJson = typeof json?.message === "string" ? parseBindingDiagnostics(json.message) : null;
6896
7042
  if (bindingFromJson) {
6897
7043
  return {
6898
- code: bindingFromJson.code ?? json2?.code ?? null,
7044
+ code: bindingFromJson.code ?? json?.code ?? null,
6899
7045
  message: bindingFromJson.message ?? cleaned,
6900
7046
  cycle: null,
6901
7047
  raw: false,
6902
7048
  ...bindingFromJson.diagnostics ? { diagnostics: bindingFromJson.diagnostics } : {}
6903
7049
  };
6904
7050
  }
6905
- if (json2 && (json2.code || json2.message || json2.cycle)) {
7051
+ if (json && (json.code || json.message || json.cycle)) {
6906
7052
  return {
6907
- code: json2.code ?? null,
6908
- message: json2.message ?? (cleaned || prefix),
6909
- cycle: json2.cycle ?? null,
7053
+ code: json.code ?? null,
7054
+ message: json.message ?? (cleaned || prefix),
7055
+ cycle: json.cycle ?? null,
6910
7056
  raw: false,
6911
- ...json2.diagnostics ? { diagnostics: json2.diagnostics } : {}
7057
+ ...json.diagnostics ? { diagnostics: json.diagnostics } : {}
6912
7058
  };
6913
7059
  }
6914
7060
  const binding = parseBindingDiagnostics(cleaned);
@@ -8448,8 +8594,8 @@ async function resolveSession(sessionFlag, command) {
8448
8594
  }
8449
8595
  function rebuildDTCGTree(groups, tokens) {
8450
8596
  const root = {};
8451
- for (const group2 of groups) {
8452
- const segments = group2.path.split(".");
8597
+ for (const group of groups) {
8598
+ const segments = group.path.split(".");
8453
8599
  let node = root;
8454
8600
  for (const seg of segments) {
8455
8601
  if (typeof node[seg] !== "object" || node[seg] === null) {
@@ -8457,8 +8603,8 @@ function rebuildDTCGTree(groups, tokens) {
8457
8603
  }
8458
8604
  node = node[seg];
8459
8605
  }
8460
- if (group2.$description) {
8461
- node["$description"] = group2.$description;
8606
+ if (group.$description) {
8607
+ node["$description"] = group.$description;
8462
8608
  }
8463
8609
  }
8464
8610
  for (const token of tokens) {
@@ -9032,7 +9178,7 @@ ${defaultDiagnostics.map((diagnostic) => ` ${diagnostic}`).join("\n")}
9032
9178
  return;
9033
9179
  }
9034
9180
  }
9035
- const binary = resolveBinary(agent);
9181
+ const binary = resolveAgentBinary(agent);
9036
9182
  if (!await assertBinaryInPath(binary)) {
9037
9183
  die(
9038
9184
  `Error: agent '${agent}' not found in $PATH (looked for binary: ${binary}).
@@ -9201,214 +9347,6 @@ var init_run_teaser = __esm({
9201
9347
  }
9202
9348
  });
9203
9349
 
9204
- // packages/experience-design-system-cli-legacy/src/lib/push-debug-log.ts
9205
- import { existsSync as existsSync3, mkdirSync as mkdirSync3, readdirSync, writeFileSync } from "node:fs";
9206
- import { join as join10 } from "node:path";
9207
- function scrub(key, value) {
9208
- if (/^cma_?token$/i.test(key)) {
9209
- return typeof value === "string" && value ? `[present, ${value.length} chars]` : "[not set]";
9210
- }
9211
- if (typeof value === "string" && SECRET_VALUE.test(value)) return "[redacted]";
9212
- return value;
9213
- }
9214
- function json(value) {
9215
- const text = JSON.stringify(value, scrub, 2) ?? "null";
9216
- return text.length > MAX_BLOCK_CHARS ? `${text.slice(0, MAX_BLOCK_CHARS)}
9217
- \u2026 truncated, ${text.length - MAX_BLOCK_CHARS} more characters` : text;
9218
- }
9219
- function pad(n, width = 2) {
9220
- return String(n).padStart(width, "0");
9221
- }
9222
- function datePrefix(now) {
9223
- return `${pad(now.getMonth() + 1)}-${pad(now.getDate())}-${now.getFullYear()}`;
9224
- }
9225
- function clock(now) {
9226
- return `${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}.${pad(now.getMilliseconds(), 3)}`;
9227
- }
9228
- function nextFilename(dir, now) {
9229
- const today = datePrefix(now);
9230
- const pattern = new RegExp(`^${today}-push-attempt-(\\d+)\\.md$`);
9231
- const existing = existsSync3(dir) ? readdirSync(dir) : [];
9232
- const max = existing.reduce((acc, entry) => {
9233
- const match2 = pattern.exec(entry);
9234
- return match2 ? Math.max(acc, Number(match2[1])) : acc;
9235
- }, 0);
9236
- return `${today}-push-attempt-${max + 1}.md`;
9237
- }
9238
- function entityName(entry) {
9239
- if (typeof entry === "string") return entry;
9240
- if (entry && typeof entry === "object") {
9241
- const record = entry;
9242
- for (const field of ["key", "name", "$name", "id"]) {
9243
- if (typeof record[field] === "string") return record[field];
9244
- }
9245
- const current = record["current"];
9246
- if (current && typeof current === "object" && typeof current["name"] === "string") {
9247
- return current["name"];
9248
- }
9249
- }
9250
- return "unknown";
9251
- }
9252
- function group(diff) {
9253
- return {
9254
- new: diff.new.map(entityName),
9255
- changed: diff.changed.map((entry) => {
9256
- const breaking = entry && typeof entry === "object" && entry.changeClassification?.classification === "breaking";
9257
- return breaking ? `${entityName(entry)} (breaking)` : entityName(entry);
9258
- }),
9259
- unchanged: diff.unchanged,
9260
- removed: diff.removed.map(entityName)
9261
- };
9262
- }
9263
- function summarizePreview(preview) {
9264
- return { components: group(preview.components), tokens: group(preview.tokens) };
9265
- }
9266
- function summarizeCdf(cdf) {
9267
- return Object.entries(cdf).filter(([key]) => !key.startsWith("$") && key !== "allowDeletions").map(([key, value]) => {
9268
- const entry = value ?? {};
9269
- const properties = entry["$properties"];
9270
- const slots = entry["$slots"];
9271
- return {
9272
- name: key,
9273
- type: entry["$type"],
9274
- properties: properties && typeof properties === "object" ? Object.keys(properties) : [],
9275
- slots: slots && typeof slots === "object" ? Object.keys(slots) : []
9276
- };
9277
- });
9278
- }
9279
- function renderEvents(events) {
9280
- if (events.length === 0) return "_Nothing recorded yet._";
9281
- return events.map((event, index) => {
9282
- const note = event.note ? ` \u2014 ${event.note}` : "";
9283
- const request2 = event.requestId ? ` _(request ${event.requestId})_` : "";
9284
- return `${index + 1}. \`${clock(event.at)}\` (+${event.sinceStartMs}ms) **${event.title}**${note}${request2}`;
9285
- }).join("\n");
9286
- }
9287
- function renderDetails(events) {
9288
- const withData = events.map((event, index) => ({ event, index })).filter(({ event }) => event.data && Object.keys(event.data).length > 0);
9289
- if (withData.length === 0) return "";
9290
- return withData.map(
9291
- ({ event, index }) => `<details>
9292
- <summary>${index + 1}. ${event.title}</summary>
9293
-
9294
- \`\`\`json
9295
- ${json(event.data)}
9296
- \`\`\`
9297
-
9298
- </details>`
9299
- ).join("\n\n");
9300
- }
9301
- function render2(runId, inputs, events, startedAt, result, durationMs) {
9302
- const requestIds = [...new Set(events.map((event) => event.requestId).filter(Boolean))];
9303
- const text = (field) => String(inputs[field] ?? "\u2014");
9304
- const details = renderDetails(events);
9305
- return `# Push to Contentful \u2014 debug log
9306
-
9307
- ## Summary
9308
-
9309
- | | |
9310
- |---|---|
9311
- | **Result** | ${OUTCOME_LABEL[result.outcome]} |
9312
- | **What happened** | ${result.summary} |
9313
- | **Space / environment** | \`${text("space_id")}\` / \`${text("environment_id")}\` |
9314
- | **Host** | ${text("host")} |
9315
- | **Started** | ${startedAt.toISOString()} |
9316
- | **Duration** | ${durationMs}ms |
9317
- | **Request IDs** | ${requestIds.length > 0 ? requestIds.map((id) => `\`${id}\``).join(", ") : "\u2014"} |
9318
- | **CLI / runtime** | ${cliVersion()} \xB7 ${process.platform} \xB7 Node ${process.version} |
9319
- | **Run ID** | ${runId} |
9320
-
9321
- ## Timeline
9322
-
9323
- ${renderEvents(events)}
9324
-
9325
- ## Inputs
9326
-
9327
- \`\`\`json
9328
- ${json(inputs)}
9329
- \`\`\`
9330
-
9331
- ## Result
9332
-
9333
- \`\`\`json
9334
- ${json({ outcome: result.outcome, summary: result.summary, ...result.details ?? {} })}
9335
- \`\`\`
9336
- ${details ? `
9337
- ## Details
9338
-
9339
- ${details}
9340
- ` : ""}`;
9341
- }
9342
- function startPushDebugRun(inputs) {
9343
- const sessionDir = process.env[DEBUG_SESSION_DIR_ENV];
9344
- if (!sessionDir) return NOOP_RUN;
9345
- const startedAt = /* @__PURE__ */ new Date();
9346
- const runId = `${startedAt.getFullYear()}${pad(startedAt.getMonth() + 1)}${pad(startedAt.getDate())}-${pad(startedAt.getHours())}${pad(startedAt.getMinutes())}${pad(startedAt.getSeconds())}`;
9347
- const events = [];
9348
- let result = {
9349
- outcome: "in-progress",
9350
- summary: "The push started but no final result was recorded."
9351
- };
9352
- let finished = false;
9353
- let path;
9354
- const flush = () => {
9355
- try {
9356
- if (!path) {
9357
- const dir = join10(sessionDir, "import");
9358
- mkdirSync3(dir, { recursive: true });
9359
- path = join10(dir, nextFilename(dir, startedAt));
9360
- }
9361
- writeFileSync(path, render2(runId, inputs, events, startedAt, result, Date.now() - startedAt.getTime()), {
9362
- mode: 384
9363
- });
9364
- } catch {
9365
- }
9366
- };
9367
- flush();
9368
- return {
9369
- event(title, options = {}) {
9370
- if (finished) return;
9371
- const at = /* @__PURE__ */ new Date();
9372
- events.push({ at, sinceStartMs: at.getTime() - startedAt.getTime(), title, ...options });
9373
- flush();
9374
- },
9375
- finish(final) {
9376
- if (finished) return;
9377
- finished = true;
9378
- result = final;
9379
- const at = /* @__PURE__ */ new Date();
9380
- events.push({
9381
- at,
9382
- sinceStartMs: at.getTime() - startedAt.getTime(),
9383
- title: OUTCOME_LABEL[final.outcome].replace(/^\S+\s/, ""),
9384
- note: final.summary
9385
- });
9386
- flush();
9387
- }
9388
- };
9389
- }
9390
- var DEBUG_SESSION_DIR_ENV, NOOP_RUN, OUTCOME_LABEL, MAX_BLOCK_CHARS, SECRET_VALUE;
9391
- var init_push_debug_log = __esm({
9392
- "packages/experience-design-system-cli-legacy/src/lib/push-debug-log.ts"() {
9393
- "use strict";
9394
- init_client();
9395
- DEBUG_SESSION_DIR_ENV = "EDS_DEBUG_SESSION_DIR";
9396
- NOOP_RUN = { event: () => void 0, finish: () => void 0 };
9397
- OUTCOME_LABEL = {
9398
- "in-progress": "\u23F3 In progress (the process ended before the push finished)",
9399
- pushed: "\u2705 Pushed",
9400
- partial: "\u26A0\uFE0F Partly pushed (some items failed)",
9401
- failed: "\u274C Push failed",
9402
- "preview-failed": "\u274C Preview failed (nothing was sent to apply)",
9403
- "nothing-to-push": "\u2139\uFE0F Nothing to push (the server says the space already matches)",
9404
- skipped: "\u23ED\uFE0F Skipped",
9405
- superseded: "\u21A9\uFE0F Superseded by a newer attempt"
9406
- };
9407
- MAX_BLOCK_CHARS = 1e5;
9408
- SECRET_VALUE = /CFPAT-[A-Za-z0-9_-]{20,}|^Bearer\s+\S+/;
9409
- }
9410
- });
9411
-
9412
9350
  // packages/experience-design-system-cli-legacy/src/tui/use-blinking-cursor.ts
9413
9351
  import { useEffect as useEffect2, useState as useState3 } from "react";
9414
9352
  function useBlinkingCursor() {
@@ -9428,8 +9366,8 @@ var init_use_blinking_cursor = __esm({
9428
9366
  // packages/experience-design-system-cli-legacy/src/runs/path-prompt.tsx
9429
9367
  import { useState as useState4 } from "react";
9430
9368
  import { Box as Box6, Text as Text7 } from "ink";
9431
- import { readdirSync as readdirSync2 } from "node:fs";
9432
- import { dirname as dirname5, basename as basename2, join as join11 } from "node:path";
9369
+ import { readdirSync } from "node:fs";
9370
+ import { dirname as dirname5, basename as basename2, join as join10 } from "node:path";
9433
9371
  import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
9434
9372
  function autocomplete(partial) {
9435
9373
  if (!partial) return null;
@@ -9438,19 +9376,19 @@ function autocomplete(partial) {
9438
9376
  const base = basename2(normalized);
9439
9377
  let entries;
9440
9378
  try {
9441
- entries = readdirSync2(dir);
9379
+ entries = readdirSync(dir);
9442
9380
  } catch {
9443
9381
  return null;
9444
9382
  }
9445
9383
  const matches = entries.filter((e) => e.startsWith(base));
9446
9384
  if (matches.length === 0) return null;
9447
- if (matches.length === 1) return join11(dir, matches[0]);
9385
+ if (matches.length === 1) return join10(dir, matches[0]);
9448
9386
  let prefix = matches[0];
9449
9387
  for (const m of matches) {
9450
9388
  while (!m.startsWith(prefix)) prefix = prefix.slice(0, -1);
9451
9389
  if (!prefix) break;
9452
9390
  }
9453
- return prefix.length > base.length ? join11(dir, prefix) : null;
9391
+ return prefix.length > base.length ? join10(dir, prefix) : null;
9454
9392
  }
9455
9393
  function PathPrompt({
9456
9394
  defaultPath,
@@ -9515,12 +9453,12 @@ var init_path_prompt = __esm({
9515
9453
 
9516
9454
  // packages/experience-design-system-cli-legacy/src/runs/save-path-resolver.ts
9517
9455
  import { access as access4 } from "node:fs/promises";
9518
- import { join as join12 } from "node:path";
9456
+ import { join as join11 } from "node:path";
9519
9457
  async function listConflictingFiles(path) {
9520
9458
  const conflicts = [];
9521
9459
  for (const name of SAVE_FILES) {
9522
9460
  try {
9523
- await access4(join12(path, name));
9461
+ await access4(join11(path, name));
9524
9462
  conflicts.push(name);
9525
9463
  } catch {
9526
9464
  }
@@ -9540,7 +9478,7 @@ function buildTimestampedSubdir(base, now = /* @__PURE__ */ new Date()) {
9540
9478
  const hh = pad2(now.getHours());
9541
9479
  const mm = pad2(now.getMinutes());
9542
9480
  const ss = pad2(now.getSeconds());
9543
- return join12(base, `dsi-${y}${m}${d}-${hh}${mm}${ss}`);
9481
+ return join11(base, `dsi-${y}${m}${d}-${hh}${mm}${ss}`);
9544
9482
  }
9545
9483
  var SAVE_FILES;
9546
9484
  var init_save_path_resolver = __esm({
@@ -9552,7 +9490,7 @@ var init_save_path_resolver = __esm({
9552
9490
 
9553
9491
  // packages/experience-design-system-cli-legacy/src/runs/store.ts
9554
9492
  import { readFile as readFile12, writeFile as writeFile4, mkdir as mkdir4, rename } from "node:fs/promises";
9555
- import { join as join13 } from "node:path";
9493
+ import { join as join12 } from "node:path";
9556
9494
  import { homedir as homedir6 } from "node:os";
9557
9495
  import { randomBytes as randomBytes2 } from "node:crypto";
9558
9496
  function encodeBase32(bytes, length) {
@@ -9648,8 +9586,8 @@ var init_store = __esm({
9648
9586
  RUNS_FILE_VERSION = 3;
9649
9587
  RUNS_FILE_CAP = 200;
9650
9588
  READABLE_VERSIONS = /* @__PURE__ */ new Set([1, 2, 3]);
9651
- RUNS_DIR = join13(homedir6(), ".config", "experiences");
9652
- RUNS_PATH = join13(RUNS_DIR, "runs.json");
9589
+ RUNS_DIR = join12(homedir6(), ".config", "experiences");
9590
+ RUNS_PATH = join12(RUNS_DIR, "runs.json");
9653
9591
  CROCKFORD = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
9654
9592
  }
9655
9593
  });
@@ -9806,7 +9744,7 @@ var init_WelcomeStep = __esm({
9806
9744
  import { useState as useState6, useEffect as useEffect3 } from "react";
9807
9745
  import { Box as Box9, Text as Text10 } from "ink";
9808
9746
  import { promises as fs } from "node:fs";
9809
- import { join as join14 } from "node:path";
9747
+ import { join as join13 } from "node:path";
9810
9748
  import { jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
9811
9749
  async function countFiles(dir) {
9812
9750
  const counts = {
@@ -9830,7 +9768,7 @@ async function countFiles(dir) {
9830
9768
  await Promise.all(
9831
9769
  entries.map(async (entry) => {
9832
9770
  if (IGNORE_DIRS.has(entry)) return;
9833
- const full = join14(current, entry);
9771
+ const full = join13(current, entry);
9834
9772
  let stat7;
9835
9773
  try {
9836
9774
  stat7 = await fs.stat(full);
@@ -11515,8 +11453,8 @@ var init_types = __esm({
11515
11453
  });
11516
11454
 
11517
11455
  // packages/experience-design-system-extraction/dist/src/extract/tsx-shared.js
11518
- import { existsSync as existsSync4, readFileSync as readFileSync5 } from "node:fs";
11519
- import { dirname as dirname6, join as join15, resolve as resolve12 } from "node:path";
11456
+ import { existsSync as existsSync3, readFileSync as readFileSync5 } from "node:fs";
11457
+ import { dirname as dirname6, join as join14, resolve as resolve12 } from "node:path";
11520
11458
  import { Node, Project, SyntaxKind } from "ts-morph";
11521
11459
  import ts from "typescript";
11522
11460
  function createTsxProject(filePaths) {
@@ -11715,8 +11653,8 @@ function findNearestTsConfigPath(filePath) {
11715
11653
  let currentDir = dirname6(filePath);
11716
11654
  while (true) {
11717
11655
  for (const candidateName of ["tsconfig.json", "jsconfig.json"]) {
11718
- const candidatePath = join15(currentDir, candidateName);
11719
- if (existsSync4(candidatePath)) {
11656
+ const candidatePath = join14(currentDir, candidateName);
11657
+ if (existsSync3(candidatePath)) {
11720
11658
  nearestTsConfigPathCache.set(filePath, candidatePath);
11721
11659
  return candidatePath;
11722
11660
  }
@@ -11772,12 +11710,12 @@ function resolveImportSourcePath(basePath) {
11772
11710
  `${basePath}.tsx`,
11773
11711
  `${basePath}.js`,
11774
11712
  `${basePath}.jsx`,
11775
- join15(basePath, "index.ts"),
11776
- join15(basePath, "index.tsx"),
11777
- join15(basePath, "index.js"),
11778
- join15(basePath, "index.jsx")
11713
+ join14(basePath, "index.ts"),
11714
+ join14(basePath, "index.tsx"),
11715
+ join14(basePath, "index.js"),
11716
+ join14(basePath, "index.jsx")
11779
11717
  ];
11780
- return candidates.find((candidatePath) => existsSync4(candidatePath));
11718
+ return candidates.find((candidatePath) => existsSync3(candidatePath));
11781
11719
  }
11782
11720
  function findProjectSourceFileByImportPath(project, resolvedPath) {
11783
11721
  const candidatePaths = [
@@ -11786,10 +11724,10 @@ function findProjectSourceFileByImportPath(project, resolvedPath) {
11786
11724
  `${resolvedPath}.tsx`,
11787
11725
  `${resolvedPath}.js`,
11788
11726
  `${resolvedPath}.jsx`,
11789
- join15(resolvedPath, "index.ts"),
11790
- join15(resolvedPath, "index.tsx"),
11791
- join15(resolvedPath, "index.js"),
11792
- join15(resolvedPath, "index.jsx")
11727
+ join14(resolvedPath, "index.ts"),
11728
+ join14(resolvedPath, "index.tsx"),
11729
+ join14(resolvedPath, "index.js"),
11730
+ join14(resolvedPath, "index.jsx")
11793
11731
  ];
11794
11732
  for (const candidatePath of candidatePaths) {
11795
11733
  const sourceFile = project.getSourceFile(candidatePath);
@@ -11810,10 +11748,10 @@ function findWorkspacePackageEntrySourceFile(originSourceFile, moduleSpecifier)
11810
11748
  if (!packageRootDir)
11811
11749
  return void 0;
11812
11750
  const preferredEntryPaths = [
11813
- join15(packageRootDir, "src/index.ts"),
11814
- join15(packageRootDir, "src/index.tsx"),
11815
- join15(packageRootDir, "index.ts"),
11816
- join15(packageRootDir, "index.tsx")
11751
+ join14(packageRootDir, "src/index.ts"),
11752
+ join14(packageRootDir, "src/index.tsx"),
11753
+ join14(packageRootDir, "index.ts"),
11754
+ join14(packageRootDir, "index.tsx")
11817
11755
  ];
11818
11756
  for (const entryPath of preferredEntryPaths) {
11819
11757
  const entrySourceFile = project.getSourceFile(entryPath);
@@ -11821,7 +11759,7 @@ function findWorkspacePackageEntrySourceFile(originSourceFile, moduleSpecifier)
11821
11759
  return entrySourceFile;
11822
11760
  }
11823
11761
  }
11824
- return candidateSourceFiles.find((sourceFile) => sourceFile.getDirectoryPath() === join15(packageRootDir, "src"));
11762
+ return candidateSourceFiles.find((sourceFile) => sourceFile.getDirectoryPath() === join14(packageRootDir, "src"));
11825
11763
  }
11826
11764
  function getWorkspacePackageManifestForSourceFile(sourceFile) {
11827
11765
  const packageRootDir = findNearestPackageRootDir(sourceFile.getFilePath());
@@ -11830,7 +11768,7 @@ function getWorkspacePackageManifestForSourceFile(sourceFile) {
11830
11768
  if (workspacePackageManifestCache.has(packageRootDir)) {
11831
11769
  return workspacePackageManifestCache.get(packageRootDir) ?? void 0;
11832
11770
  }
11833
- const packageJsonPath = join15(packageRootDir, "package.json");
11771
+ const packageJsonPath = join14(packageRootDir, "package.json");
11834
11772
  try {
11835
11773
  const packageJson = JSON.parse(readFileSync5(packageJsonPath, "utf8"));
11836
11774
  const manifest = typeof packageJson.name === "string" ? { name: packageJson.name, rootDir: packageRootDir } : null;
@@ -11847,7 +11785,7 @@ function findNearestPackageRootDir(filePath) {
11847
11785
  }
11848
11786
  let currentDir = dirname6(filePath);
11849
11787
  while (true) {
11850
- if (existsSync4(join15(currentDir, "package.json"))) {
11788
+ if (existsSync3(join14(currentDir, "package.json"))) {
11851
11789
  packageRootByFilePathCache.set(filePath, currentDir);
11852
11790
  return currentDir;
11853
11791
  }
@@ -14909,8 +14847,8 @@ var init_vue_tsx = __esm({
14909
14847
  });
14910
14848
 
14911
14849
  // packages/experience-design-system-extraction/dist/src/extract/resolve-local-module.js
14912
- import { existsSync as existsSync5, statSync as statSync2 } from "node:fs";
14913
- import { dirname as dirname7, join as join16, resolve as resolve13 } from "node:path";
14850
+ import { existsSync as existsSync4, statSync as statSync2 } from "node:fs";
14851
+ import { dirname as dirname7, join as join15, resolve as resolve13 } from "node:path";
14914
14852
  function resolveLocalModule(importingFilePath, specifier, options = {}) {
14915
14853
  const basePath = resolve13(dirname7(importingFilePath), specifier);
14916
14854
  const candidates = [
@@ -14919,18 +14857,18 @@ function resolveLocalModule(importingFilePath, specifier, options = {}) {
14919
14857
  `${basePath}.ts`,
14920
14858
  `${basePath}.mjs`,
14921
14859
  `${basePath}.cjs`,
14922
- join16(basePath, "index.js"),
14923
- join16(basePath, "index.ts"),
14924
- join16(basePath, "index.mjs"),
14925
- join16(basePath, "index.cjs")
14860
+ join15(basePath, "index.js"),
14861
+ join15(basePath, "index.ts"),
14862
+ join15(basePath, "index.mjs"),
14863
+ join15(basePath, "index.cjs")
14926
14864
  ];
14927
14865
  for (const candidate of candidates) {
14928
- if (existsSync5(candidate) && statSync2(candidate).isFile())
14866
+ if (existsSync4(candidate) && statSync2(candidate).isFile())
14929
14867
  return candidate;
14930
14868
  }
14931
14869
  if (options.allowJavaScriptExtensionFallback && basePath.endsWith(".js")) {
14932
14870
  const tsPath = `${basePath.slice(0, -".js".length)}.ts`;
14933
- if (existsSync5(tsPath) && statSync2(tsPath).isFile())
14871
+ if (existsSync4(tsPath) && statSync2(tsPath).isFile())
14934
14872
  return tsPath;
14935
14873
  }
14936
14874
  return null;
@@ -14961,9 +14899,9 @@ var init_resolve_type_property = __esm({
14961
14899
 
14962
14900
  // packages/experience-design-system-extraction/dist/src/extract/vue.js
14963
14901
  import os from "node:os";
14964
- import { basename as basename3, dirname as dirname8, resolve as resolve14, join as join17 } from "node:path";
14902
+ import { basename as basename3, dirname as dirname8, resolve as resolve14, join as join16 } from "node:path";
14965
14903
  import { readFile as readFile15 } from "node:fs/promises";
14966
- import { existsSync as existsSync6, readFileSync as readFileSync6, readdirSync as readdirSync3, statSync as statSync3 } from "node:fs";
14904
+ import { existsSync as existsSync5, readFileSync as readFileSync6, readdirSync as readdirSync2, statSync as statSync3 } from "node:fs";
14967
14905
  import { parse as parseSFC } from "@vue/compiler-sfc";
14968
14906
  import { Project as Project3, Node as Node6 } from "ts-morph";
14969
14907
  async function extractVueComponents(filePaths, onProgress) {
@@ -15176,11 +15114,11 @@ function findWorkspaceRoot(startDir) {
15176
15114
  return workspaceRootCache.get(startDir);
15177
15115
  let dir = startDir;
15178
15116
  while (true) {
15179
- const pkgJsonPath = join17(dir, "package.json");
15180
- if (existsSync6(pkgJsonPath)) {
15117
+ const pkgJsonPath = join16(dir, "package.json");
15118
+ if (existsSync5(pkgJsonPath)) {
15181
15119
  try {
15182
15120
  const pkg4 = JSON.parse(readFileSync6(pkgJsonPath, "utf8"));
15183
- if (pkg4.workspaces || existsSync6(join17(dir, "pnpm-workspace.yaml"))) {
15121
+ if (pkg4.workspaces || existsSync5(join16(dir, "pnpm-workspace.yaml"))) {
15184
15122
  workspaceRootCache.set(startDir, dir);
15185
15123
  return dir;
15186
15124
  }
@@ -15200,8 +15138,8 @@ function getWorkspacePackageDirs(workspaceRoot) {
15200
15138
  return workspacePackageDirsCache.get(workspaceRoot);
15201
15139
  }
15202
15140
  const packageMap = /* @__PURE__ */ new Map();
15203
- const packagesDir = join17(workspaceRoot, "packages");
15204
- if (!existsSync6(packagesDir)) {
15141
+ const packagesDir = join16(workspaceRoot, "packages");
15142
+ if (!existsSync5(packagesDir)) {
15205
15143
  workspacePackageDirsCache.set(workspaceRoot, packageMap);
15206
15144
  return packageMap;
15207
15145
  }
@@ -15210,12 +15148,12 @@ function getWorkspacePackageDirs(workspaceRoot) {
15210
15148
  return;
15211
15149
  let entries;
15212
15150
  try {
15213
- entries = readdirSync3(dir);
15151
+ entries = readdirSync2(dir);
15214
15152
  } catch {
15215
15153
  return;
15216
15154
  }
15217
- const pkgJsonPath = join17(dir, "package.json");
15218
- if (existsSync6(pkgJsonPath)) {
15155
+ const pkgJsonPath = join16(dir, "package.json");
15156
+ if (existsSync5(pkgJsonPath)) {
15219
15157
  try {
15220
15158
  const pkg4 = JSON.parse(readFileSync6(pkgJsonPath, "utf8"));
15221
15159
  if (typeof pkg4.name === "string") {
@@ -15227,7 +15165,7 @@ function getWorkspacePackageDirs(workspaceRoot) {
15227
15165
  for (const entry of entries) {
15228
15166
  if (entry === "node_modules" || entry === ".git" || entry.startsWith("."))
15229
15167
  continue;
15230
- const entryPath = join17(dir, entry);
15168
+ const entryPath = join16(dir, entry);
15231
15169
  try {
15232
15170
  const stat7 = statSync3(entryPath);
15233
15171
  if (stat7.isDirectory()) {
@@ -15267,28 +15205,28 @@ function resolveWorkspaceVueImport(specifier, importingFilePath) {
15267
15205
  const packageDir = packageDirs.get(packageName);
15268
15206
  if (!packageDir)
15269
15207
  return null;
15270
- const pkgJsonPath = join17(packageDir, "package.json");
15208
+ const pkgJsonPath = join16(packageDir, "package.json");
15271
15209
  try {
15272
15210
  const pkg4 = JSON.parse(readFileSync6(pkgJsonPath, "utf8"));
15273
15211
  if (pkg4.exports && subpath !== ".") {
15274
15212
  const exportValue = pkg4.exports[subpath];
15275
15213
  if (typeof exportValue === "string" && exportValue.endsWith(".vue")) {
15276
15214
  const resolved = resolve14(packageDir, exportValue);
15277
- if (existsSync6(resolved))
15215
+ if (existsSync5(resolved))
15278
15216
  return resolved;
15279
15217
  }
15280
15218
  }
15281
15219
  if (subpath !== ".") {
15282
15220
  const subDir = resolve14(packageDir, subpath.replace(/^\.\//, ""));
15283
- for (const base of [join17(packageDir, "src", subpath.replace(/^\.\//, "")), subDir]) {
15284
- const subPkgPath = join17(base, "package.json");
15285
- if (existsSync6(subPkgPath)) {
15221
+ for (const base of [join16(packageDir, "src", subpath.replace(/^\.\//, "")), subDir]) {
15222
+ const subPkgPath = join16(base, "package.json");
15223
+ if (existsSync5(subPkgPath)) {
15286
15224
  try {
15287
15225
  const subPkg = JSON.parse(readFileSync6(subPkgPath, "utf8"));
15288
15226
  const main = subPkg.main || subPkg.module;
15289
15227
  if (typeof main === "string" && main.endsWith(".vue")) {
15290
15228
  const resolved = resolve14(base, main);
15291
- if (existsSync6(resolved))
15229
+ if (existsSync5(resolved))
15292
15230
  return resolved;
15293
15231
  }
15294
15232
  } catch {
@@ -15300,7 +15238,7 @@ function resolveWorkspaceVueImport(specifier, importingFilePath) {
15300
15238
  const main = pkg4.main || pkg4.module;
15301
15239
  if (typeof main === "string" && main.endsWith(".vue")) {
15302
15240
  const resolved = resolve14(packageDir, main);
15303
- if (existsSync6(resolved))
15241
+ if (existsSync5(resolved))
15304
15242
  return resolved;
15305
15243
  }
15306
15244
  }
@@ -15742,7 +15680,7 @@ var init_astro = __esm({
15742
15680
  });
15743
15681
 
15744
15682
  // packages/experience-design-system-extraction/dist/src/extract/web-components.js
15745
- import { basename as basename5, dirname as dirname9, join as join18, resolve as resolve15 } from "node:path";
15683
+ import { basename as basename5, dirname as dirname9, join as join17, resolve as resolve15 } from "node:path";
15746
15684
  import { Project as Project5, Node as Node8, SyntaxKind as SyntaxKind6 } from "ts-morph";
15747
15685
  function normalizeComponentName(input) {
15748
15686
  return input.replace(/[^a-zA-Z0-9]/g, "").toLowerCase();
@@ -16395,14 +16333,14 @@ function resolveImportSourcePath2(fromFilePath, specifier) {
16395
16333
  if (!specifier.startsWith(spectrumPrefix)) {
16396
16334
  return null;
16397
16335
  }
16398
- const packagesMarker = `${join18("2nd-gen", "packages")}${fromFilePath.includes("\\") ? "\\" : "/"}`;
16336
+ const packagesMarker = `${join17("2nd-gen", "packages")}${fromFilePath.includes("\\") ? "\\" : "/"}`;
16399
16337
  const markerIndex = fromFilePath.lastIndexOf(packagesMarker);
16400
16338
  if (markerIndex === -1) {
16401
16339
  return null;
16402
16340
  }
16403
16341
  const packagesRoot = fromFilePath.slice(0, markerIndex + packagesMarker.length - 1);
16404
16342
  const componentPath = specifier.slice(spectrumPrefix.length);
16405
- return join18(packagesRoot, "core", "components", componentPath, "index.ts");
16343
+ return join17(packagesRoot, "core", "components", componentPath, "index.ts");
16406
16344
  }
16407
16345
  function getImportedBaseClass(classDecl, project, visitedFiles) {
16408
16346
  const extendsClause = classDecl.getHeritageClauses().find((clause) => clause.getToken() === SyntaxKind6.ExtendsKeyword);
@@ -16669,8 +16607,8 @@ var init_scoring = __esm({
16669
16607
 
16670
16608
  // packages/experience-design-system-extraction/dist/src/extract/svelte.js
16671
16609
  import os3 from "node:os";
16672
- import { basename as basename6, dirname as dirname10, resolve as resolve16, join as join19 } from "node:path";
16673
- import { existsSync as existsSync7, readFileSync as readFileSync7 } from "node:fs";
16610
+ import { basename as basename6, dirname as dirname10, resolve as resolve16, join as join18 } from "node:path";
16611
+ import { existsSync as existsSync6, readFileSync as readFileSync7 } from "node:fs";
16674
16612
  import { createRequire } from "node:module";
16675
16613
  import { parse as parseSvelte } from "svelte/compiler";
16676
16614
  import { Project as Project6, Node as Node9, ScriptTarget, ModuleKind, ts as ts2 } from "ts-morph";
@@ -16803,8 +16741,8 @@ async function maybeRunResolveUnreachableRetry(components, warnings, retryContex
16803
16741
  function findNearestTsconfig(startDir) {
16804
16742
  let dir = startDir;
16805
16743
  for (let i = 0; i < 16; i++) {
16806
- const candidate = join19(dir, "tsconfig.json");
16807
- if (existsSync7(candidate))
16744
+ const candidate = join18(dir, "tsconfig.json");
16745
+ if (existsSync6(candidate))
16808
16746
  return candidate;
16809
16747
  const parent = dirname10(dir);
16810
16748
  if (!parent || parent === dir)
@@ -16939,29 +16877,29 @@ function locateDtsForSpecifier(req, specifier, parentFile) {
16939
16877
  const seedDir = resolvedJs ? dirname10(resolvedJs) : dirname10(parentFile);
16940
16878
  const pkgRoot = findPackageRootForSpecifier(seedDir, specifier);
16941
16879
  if (pkgRoot) {
16942
- const pkgJsonPath = join19(pkgRoot, "package.json");
16943
- if (existsSync7(pkgJsonPath)) {
16880
+ const pkgJsonPath = join18(pkgRoot, "package.json");
16881
+ if (existsSync6(pkgJsonPath)) {
16944
16882
  try {
16945
16883
  const pkgRaw = readFileSync7(pkgJsonPath, "utf-8");
16946
16884
  const pkg4 = JSON.parse(pkgRaw);
16947
16885
  const typesField = pkg4.types ?? pkg4.typings;
16948
16886
  if (typeof typesField === "string") {
16949
16887
  const candidate = resolve16(pkgRoot, typesField);
16950
- if (existsSync7(candidate))
16888
+ if (existsSync6(candidate))
16951
16889
  return candidate;
16952
16890
  }
16953
16891
  const exportsTypes = extractTypesFromExports(pkg4.exports);
16954
16892
  if (exportsTypes) {
16955
16893
  const candidate = resolve16(pkgRoot, exportsTypes);
16956
- if (existsSync7(candidate))
16894
+ if (existsSync6(candidate))
16957
16895
  return candidate;
16958
16896
  }
16959
16897
  } catch {
16960
16898
  }
16961
16899
  }
16962
16900
  for (const entry of ["index.d.ts", "index.d.mts"]) {
16963
- const candidate = join19(pkgRoot, entry);
16964
- if (existsSync7(candidate))
16901
+ const candidate = join18(pkgRoot, entry);
16902
+ if (existsSync6(candidate))
16965
16903
  return candidate;
16966
16904
  }
16967
16905
  }
@@ -16969,7 +16907,7 @@ function locateDtsForSpecifier(req, specifier, parentFile) {
16969
16907
  const noExt = resolvedJs.replace(/\.(m?js|cjs)$/, "");
16970
16908
  for (const ext of [".d.ts", ".d.mts"]) {
16971
16909
  const candidate = `${noExt}${ext}`;
16972
- if (existsSync7(candidate))
16910
+ if (existsSync6(candidate))
16973
16911
  return candidate;
16974
16912
  }
16975
16913
  }
@@ -16978,9 +16916,9 @@ function locateDtsForSpecifier(req, specifier, parentFile) {
16978
16916
  function findPackageRootForSpecifier(seedDir, specifier) {
16979
16917
  let dir = seedDir;
16980
16918
  for (let i = 0; i < 32; i++) {
16981
- if (existsSync7(join19(dir, "package.json"))) {
16919
+ if (existsSync6(join18(dir, "package.json"))) {
16982
16920
  try {
16983
- const pkgRaw = readFileSync7(join19(dir, "package.json"), "utf-8");
16921
+ const pkgRaw = readFileSync7(join18(dir, "package.json"), "utf-8");
16984
16922
  const pkg4 = JSON.parse(pkgRaw);
16985
16923
  if (pkg4.name === specifier)
16986
16924
  return dir;
@@ -18952,9 +18890,9 @@ var init_wizard_generate_progress = __esm({
18952
18890
  });
18953
18891
 
18954
18892
  // packages/experience-design-system-cli-legacy/src/import/tui/spawn-generate.ts
18955
- import { spawn as spawn2 } from "node:child_process";
18893
+ import { spawn as spawn3 } from "node:child_process";
18956
18894
  function spawnGenerateChild(opts) {
18957
- const child = spawn2(opts.command, opts.args);
18895
+ const child = spawn3(opts.command, opts.args);
18958
18896
  let stdout = "";
18959
18897
  let stderr = "";
18960
18898
  child.stdout?.on("data", (d) => {
@@ -20334,17 +20272,17 @@ function buildCycleUnits(slotCycles) {
20334
20272
  const groups = /* @__PURE__ */ new Map();
20335
20273
  for (const node of parent.keys()) {
20336
20274
  const root = find(node);
20337
- let group2 = groups.get(root);
20338
- if (!group2) {
20339
- group2 = /* @__PURE__ */ new Set();
20340
- groups.set(root, group2);
20275
+ let group = groups.get(root);
20276
+ if (!group) {
20277
+ group = /* @__PURE__ */ new Set();
20278
+ groups.set(root, group);
20341
20279
  }
20342
- group2.add(node);
20280
+ group.add(node);
20343
20281
  }
20344
20282
  const out = /* @__PURE__ */ new Map();
20345
- for (const group2 of groups.values()) {
20346
- for (const node of group2) {
20347
- out.set(node, group2);
20283
+ for (const group of groups.values()) {
20284
+ for (const node of group) {
20285
+ out.set(node, group);
20348
20286
  }
20349
20287
  }
20350
20288
  return out;
@@ -21838,10 +21776,10 @@ function swapValues(values, firstIndex, secondIndex) {
21838
21776
  [next[firstIndex], next[secondIndex]] = [next[secondIndex], next[firstIndex]];
21839
21777
  return next;
21840
21778
  }
21841
- function parseToState(json2) {
21779
+ function parseToState(json) {
21842
21780
  let parsed;
21843
21781
  try {
21844
- parsed = JSON.parse(json2);
21782
+ parsed = JSON.parse(json);
21845
21783
  } catch (e) {
21846
21784
  return {
21847
21785
  state: { componentDescription: "", props: [], slots: [] },
@@ -22694,11 +22632,11 @@ function FieldEditor({
22694
22632
  setEditorState(next);
22695
22633
  onChange(serializeState(next, value));
22696
22634
  };
22697
- const canonicalize = React14.useCallback((json2) => {
22635
+ const canonicalize = React14.useCallback((json) => {
22698
22636
  try {
22699
- return JSON.stringify(JSON.parse(json2));
22637
+ return JSON.stringify(JSON.parse(json));
22700
22638
  } catch {
22701
- return `__unparseable__:${json2}`;
22639
+ return `__unparseable__:${json}`;
22702
22640
  }
22703
22641
  }, []);
22704
22642
  const initialStateRef = React14.useRef(initialState);
@@ -23272,14 +23210,14 @@ function FieldEditor({
23272
23210
  })();
23273
23211
  const rows = [];
23274
23212
  rows.push({ kind: "component-description" });
23275
- for (const group2 of propGroups.filter((candidate) => candidate.kind !== "hidden")) {
23276
- if (group2.indexes.length === 0) continue;
23213
+ for (const group of propGroups.filter((candidate) => candidate.kind !== "hidden")) {
23214
+ if (group.indexes.length === 0) continue;
23277
23215
  rows.push({
23278
23216
  kind: "header",
23279
- label: `${group2.label} (${group2.indexes.length}) `,
23280
- section: group2.kind
23217
+ label: `${group.label} (${group.indexes.length}) `,
23218
+ section: group.kind
23281
23219
  });
23282
- group2.indexes.forEach((idx) => rows.push({ kind: "prop", idx }));
23220
+ group.indexes.forEach((idx) => rows.push({ kind: "prop", idx }));
23283
23221
  }
23284
23222
  if (slots.length > 0) {
23285
23223
  rows.push({
@@ -23289,7 +23227,7 @@ function FieldEditor({
23289
23227
  });
23290
23228
  slots.forEach((_, i) => rows.push({ kind: "slot", idx: i }));
23291
23229
  }
23292
- const hiddenGroup = propGroups.find((group2) => group2.kind === "hidden");
23230
+ const hiddenGroup = propGroups.find((group) => group.kind === "hidden");
23293
23231
  if (hiddenGroup && hiddenGroup.indexes.length > 0) {
23294
23232
  rows.push({
23295
23233
  kind: "header",
@@ -27074,7 +27012,7 @@ var init_fetch_existing_contentful_entities = __esm({
27074
27012
 
27075
27013
  // packages/experience-design-system-cli-legacy/src/helpers/fetch-and-persist-existing-contentful-entities.ts
27076
27014
  import { writeFile as writeFile5 } from "node:fs/promises";
27077
- import { join as join20 } from "node:path";
27015
+ import { join as join19 } from "node:path";
27078
27016
  async function fetchAndPersistExistingContentfulEntities(params) {
27079
27017
  const t0 = Date.now();
27080
27018
  try {
@@ -27086,7 +27024,7 @@ async function fetchAndPersistExistingContentfulEntities(params) {
27086
27024
  spaceId: params.spaceId,
27087
27025
  environmentId: params.environmentId
27088
27026
  });
27089
- const path = join20(params.outDir, ".existing-entities.json");
27027
+ const path = join19(params.outDir, ".existing-entities.json");
27090
27028
  await writeFile5(path, JSON.stringify(entities, null, 2), "utf8");
27091
27029
  return { ok: true, path, durationMs: Date.now() - t0, entities };
27092
27030
  } catch (error) {
@@ -27263,11 +27201,11 @@ __export(WizardApp_exports, {
27263
27201
  });
27264
27202
  import { useEffect as useEffect15, useRef as useRef10, useState as useState23 } from "react";
27265
27203
  import { Box as Box42, Text as Text46 } from "ink";
27266
- import { join as join21, resolve as resolve17 } from "node:path";
27267
- import { appendFileSync as appendFileSync2, writeFileSync as writeFileSync2 } from "node:fs";
27204
+ import { join as join20, resolve as resolve17 } from "node:path";
27205
+ import { appendFileSync as appendFileSync2, writeFileSync } from "node:fs";
27268
27206
  import { access as access7, stat as stat5, writeFile as writeFile6 } from "node:fs/promises";
27269
27207
  import { tmpdir } from "node:os";
27270
- import { execFile as execFile2, spawn as spawn3 } from "node:child_process";
27208
+ import { execFile as execFile2, spawn as spawn4 } from "node:child_process";
27271
27209
  import { mkdir as mkdir5 } from "node:fs/promises";
27272
27210
  import { buildCDF as buildCDF3, validateCDF as validateCDF3, validateSlotReferences as validateSlotReferences2 } from "@contentful/experience-design-system-types";
27273
27211
  import { jsx as jsx50, jsxs as jsxs43 } from "react/jsx-runtime";
@@ -27329,7 +27267,7 @@ function runCli(args) {
27329
27267
  }
27330
27268
  function runSpawnedCli(args, onStderr, onStdout) {
27331
27269
  return new Promise((res) => {
27332
- const child = spawn3("node", args);
27270
+ const child = spawn4("node", args);
27333
27271
  let stdout = "";
27334
27272
  let stderr = "";
27335
27273
  child.stdout.on("data", (d) => {
@@ -27404,7 +27342,7 @@ function WizardApp({
27404
27342
  const logInit = useRef10(false);
27405
27343
  const initialAgentAuthRef = useRef10(initialAgentAuth ?? null);
27406
27344
  if (!logInit.current) {
27407
- writeFileSync2(WIZARD_LOG, `--- experiences import session ${(/* @__PURE__ */ new Date()).toISOString()} ---
27345
+ writeFileSync(WIZARD_LOG, `--- experiences import session ${(/* @__PURE__ */ new Date()).toISOString()} ---
27408
27346
  `);
27409
27347
  logInit.current = true;
27410
27348
  }
@@ -27413,7 +27351,6 @@ function WizardApp({
27413
27351
  tokensPath: ""
27414
27352
  });
27415
27353
  const allowEmptyDeleteAllRef = useRef10(false);
27416
- const pushDebugRef = useRef10(null);
27417
27354
  const generateChildRef = useRef10(null);
27418
27355
  const generationCachePreflightRef = useRef10(null);
27419
27356
  const selectionToReviewStartedAtRef = useRef10(null);
@@ -27432,7 +27369,7 @@ function WizardApp({
27432
27369
  const rawTokensEntryReady = !!initialRawTokensPath;
27433
27370
  const effectiveNoCache = resolveNoCacheForGenerate({ cliNoCache: noCache });
27434
27371
  const initialStepResolved = rawTokensEntryReady ? initialProjectPath ? "path-validation" : "credentials" : initialProjectPath ? "token-input" : "welcome";
27435
- const initialOutDir = initialProjectPath ? join21(resolve17(initialProjectPath), ".contentful") : "";
27372
+ const initialOutDir = initialProjectPath ? join20(resolve17(initialProjectPath), ".contentful") : "";
27436
27373
  const [state, setState] = useState23({
27437
27374
  step: initialStepResolved,
27438
27375
  agent: initialAgent ?? "claude",
@@ -27630,7 +27567,7 @@ If you are using AWS Bedrock, run:
27630
27567
  }
27631
27568
  const sessionMatch = /^session=(.+)$/m.exec(result.stdout);
27632
27569
  const tokenSessionId = sessionMatch ? sessionMatch[1].trim() : null;
27633
- const tokensPath = join21(outDir, "tokens.json");
27570
+ const tokensPath = join20(outDir, "tokens.json");
27634
27571
  const printArgs = ["print", "tokens", "--out", tokensPath];
27635
27572
  if (tokenSessionId) printArgs.push("--session", tokenSessionId);
27636
27573
  const r = await runCli(printArgs);
@@ -27652,7 +27589,7 @@ If you are using AWS Bedrock, run:
27652
27589
  tokenGenerationStatus: "complete",
27653
27590
  skipComponents: true,
27654
27591
  acceptedCount: 0,
27655
- outDir: state.outDir || join21(process.cwd(), ".contentful")
27592
+ outDir: state.outDir || join20(process.cwd(), ".contentful")
27656
27593
  });
27657
27594
  update({ step: "credentials" });
27658
27595
  return true;
@@ -27793,7 +27730,7 @@ If you are using AWS Bedrock, run:
27793
27730
  return promise;
27794
27731
  };
27795
27732
  const runExtract = async (projectPath, showProgress = true) => {
27796
- const outDir = join21(resolve17(projectPath), ".contentful");
27733
+ const outDir = join20(resolve17(projectPath), ".contentful");
27797
27734
  const existingEntitiesExpected = !state.credentialsSkipped && Boolean(state.spaceId && state.environmentId && state.cmaToken && projectPath);
27798
27735
  update({
27799
27736
  ...showProgress ? { step: "extracting" } : {},
@@ -28468,30 +28405,12 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
28468
28405
  void runSaveAndPush();
28469
28406
  };
28470
28407
  const runPreview = async (extractSessionId, tokensPath, spaceId, environmentId, cmaToken, host2) => {
28471
- const resolvedHost = resolveWizardHost(host2);
28472
- pushDebugRef.current?.finish({
28473
- outcome: "superseded",
28474
- summary: "A new push attempt started before this one finished."
28475
- });
28476
- const pushDebug = startPushDebugRun({
28477
- space_id: spaceId,
28478
- environment_id: environmentId,
28479
- host: resolvedHost,
28480
- cma_token: cmaToken,
28481
- extract_session_id: extractSessionId,
28482
- tokens_file: tokensPath || null,
28483
- delete_everything_not_listed: allowEmptyDeleteAllRef.current
28484
- });
28485
- pushDebugRef.current = pushDebug;
28486
28408
  if (shouldBypassPreview(state)) {
28487
- pushDebug.finish({
28488
- outcome: "skipped",
28489
- summary: "Credentials were skipped, so nothing is previewed or pushed. Files were saved only."
28490
- });
28491
28409
  update(buildSkippedPreviewTransition());
28492
28410
  return;
28493
28411
  }
28494
28412
  update({ step: "previewing" });
28413
+ const resolvedHost = resolveWizardHost(host2);
28495
28414
  try {
28496
28415
  const client2 = new ImportApiClient({
28497
28416
  cmaToken,
@@ -28499,7 +28418,6 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
28499
28418
  environmentId,
28500
28419
  host: resolvedHost
28501
28420
  });
28502
- pushDebug.event("Preview started", { note: `POST ${resolvedHost}/\u2026/design_systems/imports/preview` });
28503
28421
  let components = [];
28504
28422
  if (extractSessionId) {
28505
28423
  const db = openPipelineDb();
@@ -28515,16 +28433,7 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
28515
28433
  tokens = await readTokensFromPath("tokens", tokensPath);
28516
28434
  }
28517
28435
  let cdf = buildCDF3(components, toCDFTokens(tokens), { deleteAll: allowEmptyDeleteAllRef.current });
28518
- pushDebug.event("Built the CDF to send", {
28519
- note: `${summarizeCdf(cdf).length} entries`,
28520
- data: { entries: summarizeCdf(cdf), tokens_loaded: tokens.length }
28521
- });
28522
28436
  let preview = await client2.previewImport(cdf);
28523
- pushDebug.event("Server previewed the CDF", {
28524
- note: "what the server would create, change, leave alone or remove",
28525
- data: summarizePreview(preview),
28526
- requestId: client2.getLastRequestId()
28527
- });
28528
28437
  if (extractSessionId) {
28529
28438
  let needsRepreview = false;
28530
28439
  const db = openPipelineDb();
@@ -28544,27 +28453,15 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
28544
28453
  if (seededDefaults > 0) needsRepreview = true;
28545
28454
  }
28546
28455
  if (needsRepreview) {
28547
- pushDebug.event("Re-previewing", {
28548
- note: "the server listed components as removed or changed that exist locally, so defaults were filled in"
28549
- });
28550
28456
  components = loadCDFComponents(db, extractSessionId);
28551
28457
  cdf = buildCDF3(components, toCDFTokens(tokens), { deleteAll: allowEmptyDeleteAllRef.current });
28552
28458
  preview = await client2.previewImport(cdf);
28553
- pushDebug.event("Server previewed the updated CDF", {
28554
- data: summarizePreview(preview),
28555
- requestId: client2.getLastRequestId()
28556
- });
28557
28459
  }
28558
28460
  } finally {
28559
28461
  db.close();
28560
28462
  }
28561
28463
  }
28562
28464
  if (isEmptyPreview(preview)) {
28563
- pushDebug.finish({
28564
- outcome: "nothing-to-push",
28565
- summary: "The server says every component and token in the CDF already matches what is in this space, so no apply request was sent. If the space looks empty, check that this is the space and environment you are viewing.",
28566
- details: { preview: summarizePreview(preview), request_id: client2.getLastRequestId() }
28567
- });
28568
28465
  update({
28569
28466
  step: "done",
28570
28467
  serverPreview: preview,
@@ -28576,9 +28473,6 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
28576
28473
  });
28577
28474
  return;
28578
28475
  }
28579
- pushDebug.event("Waiting for confirmation", {
28580
- note: "the preview shows changes, so the wizard asks before pushing"
28581
- });
28582
28476
  update({
28583
28477
  step: "preview-gate",
28584
28478
  serverPreview: preview,
@@ -28587,11 +28481,6 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
28587
28481
  ...clearedValidationErrorState()
28588
28482
  });
28589
28483
  } catch (e) {
28590
- pushDebug.finish({
28591
- outcome: "preview-failed",
28592
- summary: e instanceof ApiError ? `The preview request was rejected with HTTP ${e.status}.` : `The preview failed before the server answered: ${e instanceof Error ? e.message : String(e)}`,
28593
- details: e instanceof ApiError ? { status: e.status, body: (e.body ?? "").slice(0, 4e3) } : { error: e instanceof Error ? e.message : String(e) }
28594
- });
28595
28484
  if (e instanceof ApiError) {
28596
28485
  if (e.status === 401 || e.status === 403) {
28597
28486
  let bodyMsg = "";
@@ -28654,18 +28543,7 @@ If using a custom host configuration, make sure the space exists on that host.`
28654
28543
  }
28655
28544
  };
28656
28545
  const runPush = async (cdf, spaceId, environmentId, cmaToken, host2, acknowledgeBreakingChanges, preview) => {
28657
- const pushDebug = pushDebugRef.current ?? startPushDebugRun({
28658
- space_id: spaceId,
28659
- environment_id: environmentId,
28660
- host: resolveWizardHost(host2),
28661
- cma_token: cmaToken
28662
- });
28663
- pushDebugRef.current = pushDebug;
28664
28546
  if (shouldRefusePush(state)) {
28665
- pushDebug.finish({
28666
- outcome: "skipped",
28667
- summary: "Credentials were skipped, so the push was refused. Files were saved only."
28668
- });
28669
28547
  update(buildSkippedPushTransition());
28670
28548
  return;
28671
28549
  }
@@ -28673,11 +28551,6 @@ If using a custom host configuration, make sure the space exists on that host.`
28673
28551
  const hasComponentChanges = preview.components.new.length > 0 || preview.components.changed.length > 0 || preview.components.removed.length > 0;
28674
28552
  const hasTokenChanges = preview.tokens.new.length > 0 || preview.tokens.changed.length > 0 || preview.tokens.removed.length > 0;
28675
28553
  if (!hasComponentChanges && !hasTokenChanges) {
28676
- pushDebug.finish({
28677
- outcome: "nothing-to-push",
28678
- summary: "The preview had no new, changed or removed items, so no apply request was sent.",
28679
- details: { preview: summarizePreview(preview) }
28680
- });
28681
28554
  update({
28682
28555
  step: "done",
28683
28556
  pushResult: {
@@ -28690,11 +28563,6 @@ If using a custom host configuration, make sure the space exists on that host.`
28690
28563
  }
28691
28564
  const cycles = detectSlotCycles(extractComponents(cdf));
28692
28565
  if (cycles.length > 0) {
28693
- pushDebug.finish({
28694
- outcome: "failed",
28695
- summary: "The push was blocked locally because components slot each other in a cycle.",
28696
- details: { cycles: formatSlotCycleReport(cycles) }
28697
- });
28698
28566
  update({
28699
28567
  step: "error",
28700
28568
  errorStep: "apply",
@@ -28705,11 +28573,6 @@ If using a custom host configuration, make sure the space exists on that host.`
28705
28573
  }
28706
28574
  const unresolvedSlotReferences = validateSlotReferences2(extractComponents(cdf));
28707
28575
  if (unresolvedSlotReferences.length > 0) {
28708
- pushDebug.finish({
28709
- outcome: "failed",
28710
- summary: "The push was blocked locally because a slot refers to a component that is not in the CDF.",
28711
- details: { unresolved: formatUnresolvedSlotReferences(unresolvedSlotReferences) }
28712
- });
28713
28576
  update({
28714
28577
  step: "error",
28715
28578
  errorStep: "apply",
@@ -28719,14 +28582,6 @@ If using a custom host configuration, make sure the space exists on that host.`
28719
28582
  return;
28720
28583
  }
28721
28584
  update({ step: "pushing", pushProgress: null, errorAllowBreakingChangeAcknowledgment: false });
28722
- pushDebug.event("Apply started", {
28723
- note: `POST ${resolveWizardHost(host2)}/\u2026/design_systems/imports/apply`,
28724
- data: {
28725
- acknowledge_breaking_changes: acknowledgeBreakingChanges,
28726
- sending: summarizeCdf(cdf),
28727
- expected: preview ? summarizePreview(preview) : null
28728
- }
28729
- });
28730
28585
  try {
28731
28586
  const resolvedHost = resolveWizardHost(host2);
28732
28587
  const client2 = new ImportApiClient({
@@ -28736,11 +28591,6 @@ If using a custom host configuration, make sure the space exists on that host.`
28736
28591
  host: resolvedHost
28737
28592
  });
28738
28593
  let operation = await client2.applyImport(cdf, { acknowledgeBreakingChanges });
28739
- pushDebug.event("Server accepted the apply request", {
28740
- note: `operation ${operation.sys.id} is ${operation.sys.status}`,
28741
- data: { operation_id: operation.sys.id, status: operation.sys.status, summary: operation.summary },
28742
- requestId: client2.getLastRequestId()
28743
- });
28744
28594
  try {
28745
28595
  logStep({
28746
28596
  applyResponse: {
@@ -28757,15 +28607,9 @@ If using a custom host configuration, make sure the space exists on that host.`
28757
28607
  pushProgress: { kind: "queued", operationId: operation.sys.id }
28758
28608
  });
28759
28609
  let pollCount = 0;
28760
- let lastPolledStatus = "";
28761
28610
  operation = await client2.pollOperation(operation.sys.id, {
28762
28611
  onProgress: (op) => {
28763
28612
  pollCount++;
28764
- const polled = `${op.sys.status} ${op.summary ? `${op.summary.total - op.summary.pending}/${op.summary.total}` : ""}`;
28765
- if (polled !== lastPolledStatus) {
28766
- lastPolledStatus = polled;
28767
- pushDebug.event("Operation status changed", { note: polled.trim(), requestId: client2.getLastRequestId() });
28768
- }
28769
28613
  const s = op.summary;
28770
28614
  if (s) {
28771
28615
  const done = s.total - s.pending;
@@ -28870,29 +28714,6 @@ If using a custom host configuration, make sure the space exists on that host.`
28870
28714
  );
28871
28715
  }
28872
28716
  }
28873
- const failedItems = items.filter((item) => item.status === "failed");
28874
- const pushedCount = items.filter((item) => item.status === "succeeded").length;
28875
- pushDebug.finish({
28876
- outcome: pushSucceeded ? "pushed" : pushedCount > 0 ? "partial" : "failed",
28877
- summary: pushSucceeded ? items.length > 0 ? `The server reports ${pushedCount} of ${items.length} items applied.` : `The operation finished as ${operation.sys.status}, but the server returned no per-item results, so the counts come from the preview.` : `The operation finished as ${operation.sys.status}; ${failedItems.length} item(s) failed.`,
28878
- details: {
28879
- operation_id: operation.sys.id,
28880
- operation_status: operation.sys.status,
28881
- server_summary: operation.summary,
28882
- items: items.map((item) => ({
28883
- type: item.entityType,
28884
- id: item.id,
28885
- action: item.action,
28886
- status: item.status,
28887
- ...item.error ? { error: formatEdsiError(item.error) } : {}
28888
- })),
28889
- shown_to_user: {
28890
- component_types: pushResult.componentTypes,
28891
- design_tokens: pushResult.designTokens
28892
- },
28893
- request_id: client2.getLastRequestId()
28894
- }
28895
- });
28896
28717
  update({ step: "done", pushResult });
28897
28718
  } catch (e) {
28898
28719
  let msg;
@@ -28903,14 +28724,6 @@ If using a custom host configuration, make sure the space exists on that host.`
28903
28724
  } else {
28904
28725
  msg = "Push failed";
28905
28726
  }
28906
- pushDebug.finish({
28907
- outcome: "failed",
28908
- summary: e instanceof ApiError ? `The apply request failed with HTTP ${e.status}.` : `The apply request failed before the server answered: ${msg}`,
28909
- details: {
28910
- message: msg,
28911
- ...e instanceof ApiError ? { status: e.status, body: (e.body ?? "").slice(0, 4e3) } : {}
28912
- }
28913
- });
28914
28727
  update({
28915
28728
  step: "error",
28916
28729
  errorStep: "apply",
@@ -28922,7 +28735,7 @@ If using a custom host configuration, make sure the space exists on that host.`
28922
28735
  };
28923
28736
  const runPrintFiles = async (extractSessionId, outDir, opts = {}) => {
28924
28737
  update({ step: "printing" });
28925
- const componentsPath = join21(outDir, "components.json");
28738
+ const componentsPath = join20(outDir, "components.json");
28926
28739
  try {
28927
28740
  const db = openPipelineDb();
28928
28741
  let components = [];
@@ -29025,7 +28838,7 @@ If using a custom host configuration, make sure the space exists on that host.`
29025
28838
  if (tokenReuseChecked.current) return;
29026
28839
  tokenReuseChecked.current = true;
29027
28840
  const tokenNextStep = state.projectPath ? "path-validation" : "credentials";
29028
- const existingTokensPath = join21(state.outDir, "tokens.json");
28841
+ const existingTokensPath = join20(state.outDir, "tokens.json");
29029
28842
  if (effectiveNoCache) {
29030
28843
  tokenGenerationPromiseRef.current = runAgentAuthCheck(tokenNextStep).then(
29031
28844
  (ok2) => ok2 ? runGenerateTokens(state.rawTokensPath, state.outDir) : false
@@ -29076,7 +28889,7 @@ If using a custom host configuration, make sure the space exists on that host.`
29076
28889
  {
29077
28890
  onContinue: (path) => {
29078
28891
  const projectPath = normalizePath(path);
29079
- const outDir = join21(projectPath, ".contentful");
28892
+ const outDir = join20(projectPath, ".contentful");
29080
28893
  update({ step: "token-input", projectPath, outDir });
29081
28894
  },
29082
28895
  onQuit: () => process.exit(0)
@@ -29574,7 +29387,6 @@ var init_WizardApp = __esm({
29574
29387
  init_theme();
29575
29388
  init_run_teaser();
29576
29389
  init_debug_logger();
29577
- init_push_debug_log();
29578
29390
  init_credentials_store();
29579
29391
  init_path_prompt();
29580
29392
  init_save_path_resolver();
@@ -29619,7 +29431,7 @@ var init_WizardApp = __esm({
29619
29431
  init_use_terminal_size();
29620
29432
  init_render_with_goodbye();
29621
29433
  SAVE_CONFIRMATION_DELAY_MS = 1e3;
29622
- WIZARD_LOG = join21(tmpdir(), "experiences-import-wizard.log");
29434
+ WIZARD_LOG = join20(tmpdir(), "experiences-import-wizard.log");
29623
29435
  }
29624
29436
  });
29625
29437
 
@@ -29750,7 +29562,7 @@ var init_agent_definitions = __esm({
29750
29562
  });
29751
29563
 
29752
29564
  // packages/experience-design-system-cli-legacy/src/setup/lib/shell.ts
29753
- import { execFile as execFile3, spawn as spawn4 } from "node:child_process";
29565
+ import { execFile as execFile3, spawn as spawn5 } from "node:child_process";
29754
29566
  import { access as access8 } from "node:fs/promises";
29755
29567
  import { promisify as promisify2 } from "node:util";
29756
29568
  async function binaryExists(name) {
@@ -29766,7 +29578,7 @@ async function pathExists3(path) {
29766
29578
  }
29767
29579
  function runSpawn(cmd, args, opts = {}) {
29768
29580
  return new Promise((resolve21) => {
29769
- const child = spawn4(cmd, args, {
29581
+ const child = spawn5(cmd, args, {
29770
29582
  cwd: opts.cwd,
29771
29583
  env: opts.env ?? process.env,
29772
29584
  stdio: ["ignore", "pipe", "pipe"]
@@ -29799,7 +29611,7 @@ var init_shell = __esm({
29799
29611
  });
29800
29612
 
29801
29613
  // packages/experience-design-system-cli-legacy/src/setup/lib/checks.ts
29802
- import { join as join22 } from "node:path";
29614
+ import { join as join21 } from "node:path";
29803
29615
  function checkNodeVersion(nodeVersion = process.versions.node) {
29804
29616
  const major = Number.parseInt(nodeVersion.split(".")[0], 10);
29805
29617
  return {
@@ -29813,7 +29625,7 @@ async function detectNodeVersionManagers(homeDir, deps = {
29813
29625
  binaryExists,
29814
29626
  pathExists: pathExists3
29815
29627
  }) {
29816
- const nvmScript = join22(homeDir, ".nvm", "nvm.sh");
29628
+ const nvmScript = join21(homeDir, ".nvm", "nvm.sh");
29817
29629
  return {
29818
29630
  nvm: await deps.binaryExists("nvm") || await deps.pathExists(nvmScript),
29819
29631
  fnm: await deps.binaryExists("fnm"),
@@ -29892,7 +29704,7 @@ var init_report = __esm({
29892
29704
 
29893
29705
  // packages/experience-design-system-cli-legacy/src/doctor/checks.ts
29894
29706
  import { homedir as homedir7 } from "node:os";
29895
- import { join as join23 } from "node:path";
29707
+ import { join as join22 } from "node:path";
29896
29708
  async function reportNode() {
29897
29709
  section("Checking Node.js version");
29898
29710
  const check = checkNodeVersion();
@@ -29943,12 +29755,12 @@ async function reportPnpm(pkgRoot) {
29943
29755
  }
29944
29756
  async function reportDependencies(pkgRoot) {
29945
29757
  section("Checking dependencies (pnpm install)");
29946
- if (!await pathExists3(join23(pkgRoot, "node_modules"))) {
29758
+ if (!await pathExists3(join22(pkgRoot, "node_modules"))) {
29947
29759
  info("node_modules not found \u2014 running pnpm install...");
29948
29760
  } else {
29949
29761
  info("Running pnpm install to ensure dependencies are up to date...");
29950
29762
  }
29951
- const check = await installDependencies(join23(pkgRoot, "..", ".."));
29763
+ const check = await installDependencies(join22(pkgRoot, "..", ".."));
29952
29764
  if (!check.passed) {
29953
29765
  fail("pnpm install failed");
29954
29766
  info("");
@@ -29965,7 +29777,7 @@ async function reportDependencies(pkgRoot) {
29965
29777
  async function reportBuild(pkgRoot) {
29966
29778
  section("Building CLI");
29967
29779
  info("Running pnpm build...");
29968
- const check = await buildCli(join23(pkgRoot, "..", ".."));
29780
+ const check = await buildCli(join22(pkgRoot, "..", ".."));
29969
29781
  if (!check.passed) {
29970
29782
  fail("Build failed");
29971
29783
  info("");
@@ -31180,9 +30992,9 @@ var init_SetupScreen = __esm({
31180
30992
 
31181
30993
  // packages/experience-design-system-cli-legacy/src/setup/command.ts
31182
30994
  import { readFileSync as readFileSync8 } from "node:fs";
31183
- import { join as join24 } from "node:path";
30995
+ import { join as join23 } from "node:path";
31184
30996
  function getCliVersion() {
31185
- const pkg4 = JSON.parse(readFileSync8(join24(findPkgRoot(), "package.json"), "utf8"));
30997
+ const pkg4 = JSON.parse(readFileSync8(join23(findPkgRoot(), "package.json"), "utf8"));
31186
30998
  return pkg4.version;
31187
30999
  }
31188
31000
  async function runSetup(opts) {
@@ -31194,7 +31006,7 @@ async function runSetup(opts) {
31194
31006
  const { renderWithGoodbye: renderWithGoodbye2 } = await Promise.resolve().then(() => (init_render_with_goodbye(), render_with_goodbye_exports));
31195
31007
  const { createElement: createElement6 } = await import("react");
31196
31008
  const { SetupScreen: SetupScreen2 } = await Promise.resolve().then(() => (init_SetupScreen(), SetupScreen_exports));
31197
- const repoRoot = join24(findPkgRoot(), "..", "..");
31009
+ const repoRoot = join23(findPkgRoot(), "..", "..");
31198
31010
  const completion = { outcome: null };
31199
31011
  let unmountInk = null;
31200
31012
  const { waitUntilExit, unmount } = renderWithGoodbye2(
@@ -31395,15 +31207,15 @@ var init_apply_mapping = __esm({
31395
31207
  });
31396
31208
 
31397
31209
  // packages/experience-design-system-cli-legacy/src/analyze/composition/prompt-loader.ts
31398
- import { existsSync as existsSync8, readFileSync as readFileSync9 } from "node:fs";
31399
- import { dirname as dirname11, join as join25, resolve as resolve18 } from "node:path";
31210
+ import { existsSync as existsSync7, readFileSync as readFileSync9 } from "node:fs";
31211
+ import { dirname as dirname11, join as join24, resolve as resolve18 } from "node:path";
31400
31212
  import { fileURLToPath as fileURLToPath3 } from "node:url";
31401
31213
  function resolvePromptPath(fileName) {
31402
31214
  const thisDir = dirname11(fileURLToPath3(import.meta.url));
31403
31215
  let dir = thisDir;
31404
31216
  for (; ; ) {
31405
- const candidate = join25(dir, "prompts");
31406
- if (existsSync8(candidate)) return join25(candidate, fileName);
31217
+ const candidate = join24(dir, "prompts");
31218
+ if (existsSync7(candidate)) return join24(candidate, fileName);
31407
31219
  const parent = resolve18(dir, "..");
31408
31220
  if (parent === dir) {
31409
31221
  throw new Error(
@@ -31671,7 +31483,7 @@ var init_manifest_doc_evidence = __esm({
31671
31483
 
31672
31484
  // packages/experience-design-system-cli-legacy/src/analyze/extract-command.ts
31673
31485
  import { mkdir as mkdir6, readdir as readdir3, readFile as readFile18, stat as stat6 } from "node:fs/promises";
31674
- import { isAbsolute as isAbsolute2, join as join26, relative as relative2, resolve as resolve19 } from "node:path";
31486
+ import { isAbsolute as isAbsolute2, join as join25, relative as relative2, resolve as resolve19 } from "node:path";
31675
31487
  function resolveExtractNoCache(opts) {
31676
31488
  return opts.noCache === true || opts.cache === false;
31677
31489
  }
@@ -31709,7 +31521,7 @@ async function collectSourceFiles(directory, onProgress) {
31709
31521
  const entries = await readdir3(currentDirectory, { withFileTypes: true });
31710
31522
  const subdirs = [];
31711
31523
  for (const entry of entries) {
31712
- const fullPath = join26(currentDirectory, entry.name);
31524
+ const fullPath = join25(currentDirectory, entry.name);
31713
31525
  if (entry.isDirectory()) {
31714
31526
  if (!IGNORED_DIRECTORY_NAMES.has(entry.name)) {
31715
31527
  subdirs.push(fullPath);
@@ -31793,7 +31605,7 @@ function registerInternalExtractCommand(program) {
31793
31605
  }
31794
31606
  }
31795
31607
  const projectRoot = resolve19(opts.project);
31796
- const outDir = join26(projectRoot, ".contentful");
31608
+ const outDir = join25(projectRoot, ".contentful");
31797
31609
  let sourceDirectory;
31798
31610
  if (opts.dir !== void 0) {
31799
31611
  sourceDirectory = resolveFromProjectRoot(projectRoot, opts.dir);
@@ -32196,9 +32008,9 @@ __export(program_exports, {
32196
32008
  resolveBedrockFromAncestors: () => resolveBedrockFromAncestors,
32197
32009
  runBuild: () => runBuild
32198
32010
  });
32199
- import { spawn as spawn5 } from "node:child_process";
32011
+ import { spawn as spawn6 } from "node:child_process";
32200
32012
  import { fileURLToPath as fileURLToPath4 } from "node:url";
32201
- import { dirname as dirname13, join as join27, resolve as resolve20 } from "node:path";
32013
+ import { dirname as dirname13, join as join26, resolve as resolve20 } from "node:path";
32202
32014
  import { readFileSync as readFileSync10 } from "node:fs";
32203
32015
  import { Command } from "commander";
32204
32016
  async function runBuild(opts) {
@@ -32231,7 +32043,7 @@ function registerBuildCommand(program) {
32231
32043
  const pkgRoot = resolve20(dirname13(fileURLToPath4(import.meta.url)), "..", "..");
32232
32044
  process.stderr.write("\u2699 Building from source...\n");
32233
32045
  const { exitCode } = await runBuild({
32234
- spawnFn: () => spawn5("pnpm", ["build"], { cwd: pkgRoot, stdio: "inherit" }),
32046
+ spawnFn: () => spawn6("pnpm", ["build"], { cwd: pkgRoot, stdio: "inherit" }),
32235
32047
  stderrWrite: (s) => process.stderr.write(s)
32236
32048
  });
32237
32049
  process.exit(exitCode);
@@ -32298,7 +32110,7 @@ var init_program = __esm({
32298
32110
  init_analytics();
32299
32111
  init_credentials_store();
32300
32112
  init_cli_path();
32301
- pkg3 = JSON.parse(readFileSync10(join27(findPkgRoot(), "package.json"), "utf8"));
32113
+ pkg3 = JSON.parse(readFileSync10(join26(findPkgRoot(), "package.json"), "utf8"));
32302
32114
  }
32303
32115
  });
32304
32116