@contentful/experience-design-system-cli 2.35.1-dev-build-9605c7ee.0 → 2.35.1-dev-build-3ab9e99e.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app.js +49 -46
- package/dist/index.js +60 -54
- package/dist/package.json +1 -1
- package/dist/src/tui/debug-store.d.ts +1 -0
- package/legacy/dist/src/apply/dangling-token-defaults.d.ts +17 -0
- package/legacy/dist/src/helpers/fetch-existing-token-ids.d.ts +11 -0
- package/legacy/dist/src/import/tui/steps/WizardPreviewStep.d.ts +2 -1
- package/legacy/dist/src/index.js +1258 -1001
- package/legacy/dist/src/lib/push-debug-log.d.ts +29 -0
- package/legacy/package.json +1 -1
- package/package.json +2 -2
package/legacy/dist/src/index.js
CHANGED
|
@@ -173,497 +173,263 @@ var init_agent_names = __esm({
|
|
|
173
173
|
}
|
|
174
174
|
});
|
|
175
175
|
|
|
176
|
-
// packages/experience-design-system-generation/dist/src/
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
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();
|
|
198
|
-
}
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
// packages/experience-design-system-generation/dist/src/services/prompts/helpers/resolve-skill-file.js
|
|
202
|
-
import { existsSync } from "node:fs";
|
|
203
|
-
import { readFile as readFile2 } from "node:fs/promises";
|
|
204
|
-
import { dirname, join as join2, resolve } from "node:path";
|
|
205
|
-
import { fileURLToPath } from "node:url";
|
|
206
|
-
function resolveSkillPath(skill) {
|
|
207
|
-
if (!(skill in SKILL_FILES))
|
|
208
|
-
throw new Error(`Invalid skill: ${skill}`);
|
|
209
|
-
const thisDir = dirname(fileURLToPath(import.meta.url));
|
|
210
|
-
let dir = thisDir;
|
|
211
|
-
for (; ; ) {
|
|
212
|
-
const candidate = join2(dir, "skills");
|
|
213
|
-
if (existsSync(candidate))
|
|
214
|
-
return join2(candidate, SKILL_FILES[skill]);
|
|
215
|
-
const parent = resolve(dir, "..");
|
|
216
|
-
if (parent === dir) {
|
|
217
|
-
throw new Error(`skill file missing from CLI installation (could not locate skills/ directory from: ${thisDir})`);
|
|
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;
|
|
218
194
|
}
|
|
219
|
-
dir = parent;
|
|
220
195
|
}
|
|
196
|
+
return -1;
|
|
221
197
|
}
|
|
222
|
-
function
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
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;
|
|
231
211
|
try {
|
|
232
|
-
|
|
212
|
+
parsed = JSON.parse(line.slice(0, end + 1));
|
|
233
213
|
} catch {
|
|
234
|
-
|
|
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);
|
|
235
223
|
}
|
|
236
224
|
}
|
|
237
|
-
|
|
238
|
-
try {
|
|
239
|
-
return await readFile2(skillPath, "utf8");
|
|
240
|
-
} catch {
|
|
241
|
-
throw new Error(`skill file missing from CLI installation \u2014 try reinstalling the CLI (looked for: ${skillPath})`);
|
|
242
|
-
}
|
|
225
|
+
return { objects, warnings };
|
|
243
226
|
}
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
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
|
|
253
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);
|
|
254
251
|
}
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
// packages/experience-design-system-generation/dist/src/services/prompts/helpers/format-token-candidates.js
|
|
258
|
-
import { flattenDTCG } from "@contentful/experience-design-system-types";
|
|
259
|
-
function inferFenceLang(filename) {
|
|
260
|
-
if (!filename)
|
|
261
|
-
return "json";
|
|
262
|
-
const ext = filename.split(".").pop()?.toLowerCase() ?? "";
|
|
263
|
-
const map = {
|
|
264
|
-
js: "js",
|
|
265
|
-
mjs: "js",
|
|
266
|
-
cjs: "js",
|
|
267
|
-
ts: "ts",
|
|
268
|
-
mts: "ts",
|
|
269
|
-
cts: "ts",
|
|
270
|
-
tsx: "tsx",
|
|
271
|
-
jsx: "jsx",
|
|
272
|
-
vue: "vue",
|
|
273
|
-
svelte: "svelte",
|
|
274
|
-
astro: "astro",
|
|
275
|
-
scss: "scss",
|
|
276
|
-
sass: "scss",
|
|
277
|
-
css: "css",
|
|
278
|
-
json: "json",
|
|
279
|
-
json5: "json"
|
|
280
|
-
};
|
|
281
|
-
return map[ext] ?? "text";
|
|
252
|
+
return { calls, warnings };
|
|
282
253
|
}
|
|
283
|
-
function
|
|
284
|
-
const
|
|
285
|
-
const
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
if (!properties)
|
|
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)}`);
|
|
290
260
|
continue;
|
|
291
|
-
const filteredProps = {};
|
|
292
|
-
for (const [propName, prop] of Object.entries(properties)) {
|
|
293
|
-
if (prop.$type === "token" && prop.$category === "design") {
|
|
294
|
-
const { "$token.allowed": _tokenAllowed, ...rest } = prop;
|
|
295
|
-
filteredProps[propName] = rest;
|
|
296
|
-
const kind = prop["$token.kind"];
|
|
297
|
-
if (typeof kind === "string" && kind.length > 0) {
|
|
298
|
-
kinds.add(kind);
|
|
299
|
-
} else {
|
|
300
|
-
hasUnscoped = true;
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
261
|
}
|
|
304
|
-
|
|
305
|
-
|
|
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);
|
|
306
339
|
}
|
|
307
340
|
}
|
|
308
|
-
return {
|
|
309
|
-
}
|
|
310
|
-
function buildTokenCandidateSections(tokenTree, filteredTokenProps) {
|
|
311
|
-
const index = flattenDTCG(tokenTree, "").sort((a, b) => a.path.localeCompare(b.path));
|
|
312
|
-
if (index.length === 0)
|
|
313
|
-
return [];
|
|
314
|
-
const sections = [];
|
|
315
|
-
const renderSection = (kind, entries) => {
|
|
316
|
-
const label = kind ? `Token path index \u2014 ${kind} candidates only` : "Token path index \u2014 full tree (no $token.kind to scope by)";
|
|
317
|
-
const lines = entries.map((e) => `${e.path} \xB7 ${e.$type}`).join("\n");
|
|
318
|
-
return `${label}, one leaf token per line as \`path \xB7 type\`, no \`$value\`:
|
|
319
|
-
${lines}`;
|
|
320
|
-
};
|
|
321
|
-
if (filteredTokenProps) {
|
|
322
|
-
const { kinds, hasUnscoped } = filteredTokenProps;
|
|
323
|
-
for (const kind of kinds) {
|
|
324
|
-
const scoped = index.filter((e) => e.$type === kind);
|
|
325
|
-
if (scoped.length > 0)
|
|
326
|
-
sections.push(renderSection(kind, scoped));
|
|
327
|
-
}
|
|
328
|
-
if (hasUnscoped)
|
|
329
|
-
sections.push(renderSection(null, index));
|
|
330
|
-
} else {
|
|
331
|
-
sections.push(renderSection(null, index));
|
|
332
|
-
}
|
|
333
|
-
return sections;
|
|
341
|
+
return { calls, warnings };
|
|
334
342
|
}
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
${withContent.map(formatSourceRefBlock).join("\n\n")}`);
|
|
369
|
-
}
|
|
370
|
-
if (withoutContent.length > 0) {
|
|
371
|
-
const guidance = skill === "components" ? "there is no consumption evidence for these, so `token` cannot be earned for any of their props \u2014 classify from the prop signature alone, and any prop that would otherwise be enum-versus-token is `enum` (or `string`)" : "there is no source evidence to narrow from \u2014 emit nothing for their props";
|
|
372
|
-
sections.push(`Component source unavailable for (JSON) \u2014 ${guidance}:
|
|
373
|
-
\`\`\`json
|
|
374
|
-
${JSON.stringify(withoutContent.map((ref) => ({ component: ref.component, sourcePath: ref.sourcePath })))}
|
|
375
|
-
\`\`\``);
|
|
376
|
-
}
|
|
377
|
-
return sections;
|
|
378
|
-
}
|
|
379
|
-
var init_format_source_refs = __esm({
|
|
380
|
-
"packages/experience-design-system-generation/dist/src/services/prompts/helpers/format-source-refs.js"() {
|
|
381
|
-
"use strict";
|
|
382
|
-
init_format_token_candidates();
|
|
383
|
-
}
|
|
384
|
-
});
|
|
385
|
-
|
|
386
|
-
// packages/experience-design-system-generation/dist/src/services/prompts/helpers/build-skill-preambles.js
|
|
387
|
-
function buildComponentsAutonomousPreamble(inputBlock) {
|
|
388
|
-
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.
|
|
389
|
-
|
|
390
|
-
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:
|
|
391
|
-
- **design**: controls how the component looks (variant, size, color, layout toggles)
|
|
392
|
-
- **content**: the data a content editor fills in (text, images, URLs, rich text)
|
|
393
|
-
- **state**: runtime behavioral flags (disabled, loading, expanded, identifiers)
|
|
394
|
-
|
|
395
|
-
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.
|
|
396
|
-
|
|
397
|
-
All input data is provided inline below \u2014 do not read any additional files.${inputBlock}
|
|
398
|
-
|
|
399
|
-
## Output protocol
|
|
400
|
-
|
|
401
|
-
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.
|
|
402
|
-
|
|
403
|
-
The four tool calls you may emit are:
|
|
404
|
-
|
|
405
|
-
\`\`\`
|
|
406
|
-
{"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>"}}
|
|
407
|
-
|
|
408
|
-
{"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>"}
|
|
409
|
-
|
|
410
|
-
{"tool":"exclude_prop","prop":"<propName>","reason":"<why excluded>"}
|
|
411
|
-
|
|
412
|
-
{"tool":"classify_slot","slot":"<slotName>","required":<bool>,"allowed_components":["ComponentName"],"description":"<reason>","rationale":"<why this slot was kept in the catalog>"}
|
|
413
|
-
\`\`\`
|
|
414
|
-
|
|
415
|
-
Rules:
|
|
416
|
-
- Emit exactly one JSON object per line. No multi-line JSON. No markdown fences around the lines.
|
|
417
|
-
- Every prop in the input must have exactly one call: either classify_prop or exclude_prop.
|
|
418
|
-
- Every slot in the input must have exactly one classify_slot call.
|
|
419
|
-
- Valid cdf_type values: string, richtext, media, enum, token, boolean
|
|
420
|
-
- Valid cdf_category values: content, design, state
|
|
421
|
-
- For enum type, always include \`values\` (non-empty string array of the variant names the prop accepts).
|
|
422
|
-
- 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.
|
|
423
|
-
- Never emit both "values" and "token_kind" on one prop.
|
|
424
|
-
- \`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.
|
|
425
|
-
- Q2: is the value written straight into a style or attribute (\`rx={radius}\`, \`padding: \${padding}\`)? no \u2192 not \`token\`, apply the type rules.
|
|
426
|
-
- 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.
|
|
427
|
-
- 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".
|
|
428
|
-
- 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.
|
|
429
|
-
- 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.
|
|
430
|
-
- 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.
|
|
431
|
-
- You may emit prose lines (not starting with {) anywhere \u2014 they are ignored by the parser and serve as your reasoning log.`;
|
|
432
|
-
}
|
|
433
|
-
function buildSelectAutonomousPreamble(inputBlock) {
|
|
434
|
-
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.
|
|
435
|
-
|
|
436
|
-
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.
|
|
437
|
-
|
|
438
|
-
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.
|
|
439
|
-
|
|
440
|
-
All input data is provided inline below \u2014 do not read any additional files.${inputBlock}
|
|
441
|
-
|
|
442
|
-
## Output protocol
|
|
443
|
-
|
|
444
|
-
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.
|
|
445
|
-
|
|
446
|
-
The two tool calls \u2014 emit exactly one per input component:
|
|
447
|
-
|
|
448
|
-
\`\`\`
|
|
449
|
-
{"tool":"select_component","name":"<ComponentName>","reason":"<brief reason>"}
|
|
450
|
-
|
|
451
|
-
{"tool":"reject_component","name":"<ComponentName>","reason":"<brief reason>"}
|
|
452
|
-
\`\`\`
|
|
453
|
-
|
|
454
|
-
Rules:
|
|
455
|
-
- Emit exactly one JSON object per line. No multi-line JSON. No markdown fences.
|
|
456
|
-
- 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.
|
|
457
|
-
- You may emit prose lines (not starting with {) to reason before each tool call \u2014 they are ignored by the parser.`;
|
|
458
|
-
}
|
|
459
|
-
function buildMapTokensAutonomousPreamble(inputBlock) {
|
|
460
|
-
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.
|
|
461
|
-
|
|
462
|
-
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.
|
|
463
|
-
|
|
464
|
-
All input data is provided inline below \u2014 do not read any additional files.${inputBlock}
|
|
465
|
-
|
|
466
|
-
## Output protocol
|
|
467
|
-
|
|
468
|
-
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.
|
|
469
|
-
|
|
470
|
-
The one tool call you may emit:
|
|
471
|
-
|
|
472
|
-
\`\`\`
|
|
473
|
-
{"tool":"map_token_prop","component":"<ComponentName>","prop":"<propName>","token_allowed":["colors.brand.primary","colors.brand.secondary"]}
|
|
474
|
-
\`\`\`
|
|
475
|
-
|
|
476
|
-
Rules:
|
|
477
|
-
- Emit exactly one JSON object per line. No multi-line JSON. No markdown fences around the lines.
|
|
478
|
-
- Only emit a call for a prop that appears in the "Generated CDF so far" section.
|
|
479
|
-
- 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.
|
|
480
|
-
- \`token_allowed\` is required and must be non-empty when the call is emitted.
|
|
481
|
-
- 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.
|
|
482
|
-
- You may emit prose lines (not starting with \`{\`) anywhere \u2014 they are ignored by the parser and serve as your reasoning log.`;
|
|
483
|
-
}
|
|
484
|
-
function buildTokensAutonomousPreamble(inputBlock) {
|
|
485
|
-
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.
|
|
486
|
-
|
|
487
|
-
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.
|
|
488
|
-
|
|
489
|
-
All input data is provided inline below \u2014 do not read any additional files.${inputBlock}
|
|
490
|
-
|
|
491
|
-
## Output protocol
|
|
492
|
-
|
|
493
|
-
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.
|
|
494
|
-
|
|
495
|
-
The two tool calls you may emit are:
|
|
496
|
-
|
|
497
|
-
\`\`\`
|
|
498
|
-
{"tool":"set_group","path":"<dot.notation.path>","description":"<optional group description>"}
|
|
499
|
-
|
|
500
|
-
{"tool":"set_token","path":"<dot.notation.path>","type":"<DTCG type>","value":<value>,"description":"<reason>"}
|
|
501
|
-
\`\`\`
|
|
502
|
-
|
|
503
|
-
Rules:
|
|
504
|
-
- Emit exactly one JSON object per line. No multi-line JSON. No markdown fences.
|
|
505
|
-
- Emit a set_group call for every intermediate group node in the tree.
|
|
506
|
-
- Emit a set_token call for every leaf token.
|
|
507
|
-
- "path" is dot-notation, e.g. "colors.brand.primary" \u2014 no leading dots or slashes.
|
|
508
|
-
- "type" must be one of the 13 valid DTCG types: color, dimension, fontFamily, fontWeight, duration, cubicBezier, number, strokeStyle, border, transition, shadow, gradient, typography.
|
|
509
|
-
- "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.
|
|
510
|
-
- Emit set_group calls before the set_token calls that fall under them.
|
|
511
|
-
- You may emit prose lines (not starting with {) anywhere \u2014 they are ignored by the parser and serve as your reasoning log.`;
|
|
512
|
-
}
|
|
513
|
-
var init_build_skill_preambles = __esm({
|
|
514
|
-
"packages/experience-design-system-generation/dist/src/services/prompts/helpers/build-skill-preambles.js"() {
|
|
515
|
-
"use strict";
|
|
516
|
-
}
|
|
517
|
-
});
|
|
518
|
-
|
|
519
|
-
// packages/experience-design-system-generation/dist/src/services/prompts/helpers/build-preamble.js
|
|
520
|
-
function buildPreamble(options) {
|
|
521
|
-
const { skill, rawComponentsInline, rawTokensInline, rawTokensFilename, tokensInline, tokenMapInline, generatedCdf, tokenTree, componentSourceRefs, existingComponentsInline, existingTokensInline, componentAllowlistInline } = options;
|
|
522
|
-
const sections = [];
|
|
523
|
-
if (existingComponentsInline) {
|
|
524
|
-
sections.push(`Existing components in the target Contentful space (JSON) \u2014 use for alignment, not as a hard filter:
|
|
525
|
-
\`\`\`json
|
|
526
|
-
${existingComponentsInline}
|
|
527
|
-
\`\`\``);
|
|
528
|
-
}
|
|
529
|
-
if (existingTokensInline) {
|
|
530
|
-
sections.push(`Existing design tokens in the target Contentful space (JSON) \u2014 prefer binding to these paths over inventing new ones:
|
|
531
|
-
\`\`\`json
|
|
532
|
-
${existingTokensInline}
|
|
533
|
-
\`\`\``);
|
|
534
|
-
}
|
|
535
|
-
if (componentAllowlistInline) {
|
|
536
|
-
sections.push(`Known component names for slot allowed_components (hard allowlist; never use any other name):
|
|
537
|
-
\`\`\`json
|
|
538
|
-
${componentAllowlistInline}
|
|
539
|
-
\`\`\``);
|
|
540
|
-
}
|
|
541
|
-
if (rawComponentsInline) {
|
|
542
|
-
sections.push(`Raw component data (JSON):
|
|
543
|
-
\`\`\`json
|
|
544
|
-
${rawComponentsInline}
|
|
545
|
-
\`\`\``);
|
|
546
|
-
}
|
|
547
|
-
if (rawTokensInline) {
|
|
548
|
-
const lang = inferFenceLang(rawTokensFilename);
|
|
549
|
-
const label = rawTokensFilename ? `Raw token source (${rawTokensFilename})` : "Raw token source";
|
|
550
|
-
sections.push(`${label}:
|
|
551
|
-
\`\`\`${lang}
|
|
552
|
-
${rawTokensInline}
|
|
553
|
-
\`\`\``);
|
|
554
|
-
}
|
|
555
|
-
if (tokensInline) {
|
|
556
|
-
sections.push(`DTCG token data (for token kind lookups):
|
|
557
|
-
\`\`\`json
|
|
558
|
-
${tokensInline}
|
|
559
|
-
\`\`\``);
|
|
560
|
-
}
|
|
561
|
-
if (tokenMapInline) {
|
|
562
|
-
sections.push(`Token-name sidecar (raw name \u2192 DTCG path):
|
|
563
|
-
\`\`\`json
|
|
564
|
-
${tokenMapInline}
|
|
565
|
-
\`\`\``);
|
|
566
|
-
}
|
|
567
|
-
const filteredTokenProps = generatedCdf ? filterDesignTokenProps(generatedCdf) : void 0;
|
|
568
|
-
if (filteredTokenProps && Object.keys(filteredTokenProps.filtered).length > 0) {
|
|
569
|
-
sections.push(`Generated CDF so far \u2014 design-category token props only (JSON):
|
|
570
|
-
\`\`\`json
|
|
571
|
-
${JSON.stringify(filteredTokenProps.filtered)}
|
|
572
|
-
\`\`\``);
|
|
573
|
-
}
|
|
574
|
-
if (tokenTree) {
|
|
575
|
-
sections.push(...buildTokenCandidateSections(tokenTree, filteredTokenProps));
|
|
576
|
-
}
|
|
577
|
-
if (componentSourceRefs && componentSourceRefs.length > 0) {
|
|
578
|
-
sections.push(...formatSourceRefsSection(componentSourceRefs, skill));
|
|
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))
|
|
348
|
+
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;
|
|
370
|
+
}
|
|
371
|
+
const call = { tool: "set_group", path: rec.path };
|
|
372
|
+
if (typeof rec.description === "string")
|
|
373
|
+
call.description = rec.description;
|
|
374
|
+
calls.push(call);
|
|
375
|
+
}
|
|
579
376
|
}
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
${sections.join("\n\n")}` : "";
|
|
583
|
-
if (skill === "components")
|
|
584
|
-
return buildComponentsAutonomousPreamble(inputBlock);
|
|
585
|
-
if (skill === "select")
|
|
586
|
-
return buildSelectAutonomousPreamble(inputBlock);
|
|
587
|
-
if (skill === "map-tokens")
|
|
588
|
-
return buildMapTokensAutonomousPreamble(inputBlock);
|
|
589
|
-
return buildTokensAutonomousPreamble(inputBlock);
|
|
377
|
+
return { calls, warnings };
|
|
590
378
|
}
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
"use strict";
|
|
594
|
-
init_format_token_candidates();
|
|
595
|
-
init_format_source_refs();
|
|
596
|
-
init_build_skill_preambles();
|
|
597
|
-
}
|
|
598
|
-
});
|
|
599
|
-
|
|
600
|
-
// packages/experience-design-system-generation/dist/src/services/prompts/build-prompt.js
|
|
601
|
-
async function buildPrompt(options) {
|
|
602
|
-
const skillContent = options.skillContentOverride ?? await readSkillFile(options.skill, options.skillPathOverride);
|
|
603
|
-
const preamble = buildPreamble(options);
|
|
604
|
-
return `${preamble}
|
|
605
|
-
|
|
606
|
-
Skill instructions follow:
|
|
607
|
-
---
|
|
608
|
-
${skillContent}`;
|
|
379
|
+
function isStringArray(value) {
|
|
380
|
+
return Array.isArray(value) && value.every((v) => typeof v === "string");
|
|
609
381
|
}
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
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);
|
|
616
420
|
}
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
// packages/experience-design-system-generation/dist/src/orchestrator/execute-generation-orchestrator.js
|
|
620
|
-
async function executeGenerationOrchestrator(request2) {
|
|
621
|
-
const prompt = await buildPrompt(request2.promptOptions);
|
|
622
|
-
return request2.invoker.invoke({
|
|
623
|
-
agent: request2.agent,
|
|
624
|
-
model: request2.model,
|
|
625
|
-
bedrock: request2.bedrock,
|
|
626
|
-
prompt,
|
|
627
|
-
timeoutMs: request2.timeoutMs,
|
|
628
|
-
onOutput: request2.onOutput
|
|
629
|
-
});
|
|
421
|
+
return { calls, warnings };
|
|
630
422
|
}
|
|
631
|
-
|
|
632
|
-
"packages/experience-design-system-generation/dist/src/orchestrator/execute-generation-orchestrator.js"() {
|
|
633
|
-
"use strict";
|
|
634
|
-
init_build_prompt();
|
|
635
|
-
}
|
|
636
|
-
});
|
|
637
|
-
|
|
638
|
-
// packages/experience-design-system-generation/dist/src/services/agent/helpers/resolve-agent-binary.js
|
|
639
|
-
function resolveAgentBinary(agent) {
|
|
423
|
+
function resolveBinary(agent) {
|
|
640
424
|
const envKey = `EDS_AGENT_BINARY_${agent.toUpperCase()}`;
|
|
641
425
|
const override = process.env[envKey];
|
|
642
426
|
if (override && override.trim())
|
|
643
427
|
return override.trim();
|
|
644
428
|
return AGENT_BINARIES[agent];
|
|
645
429
|
}
|
|
646
|
-
var AGENT_BINARIES;
|
|
647
|
-
var init_resolve_agent_binary = __esm({
|
|
648
|
-
"packages/experience-design-system-generation/dist/src/services/agent/helpers/resolve-agent-binary.js"() {
|
|
649
|
-
"use strict";
|
|
650
|
-
AGENT_BINARIES = {
|
|
651
|
-
claude: "claude",
|
|
652
|
-
codex: "codex",
|
|
653
|
-
opencode: "opencode",
|
|
654
|
-
cursor: "cursor-agent",
|
|
655
|
-
copilot: "copilot"
|
|
656
|
-
};
|
|
657
|
-
}
|
|
658
|
-
});
|
|
659
|
-
|
|
660
|
-
// packages/experience-design-system-generation/dist/src/services/agent/helpers/build-agent-args.js
|
|
661
430
|
function agentSupportsBedrock(agent) {
|
|
662
431
|
return BEDROCK_CAPABLE_AGENTS.has(agent);
|
|
663
432
|
}
|
|
664
|
-
function withBedrockProviderPrefix(model) {
|
|
665
|
-
return model.includes("/") ? model : `amazon-bedrock/${model}`;
|
|
666
|
-
}
|
|
667
433
|
function resolveAgentModel(agent, explicit, bedrock = false) {
|
|
668
434
|
if (explicit && explicit.trim())
|
|
669
435
|
return explicit.trim();
|
|
@@ -676,11 +442,14 @@ function resolveAgentModel(agent, explicit, bedrock = false) {
|
|
|
676
442
|
return withBedrockProviderPrefix(DEFAULT_OPENCODE_MODEL);
|
|
677
443
|
return DEFAULT_MODELS[agent];
|
|
678
444
|
}
|
|
445
|
+
function withBedrockProviderPrefix(model) {
|
|
446
|
+
return model.includes("/") ? model : `amazon-bedrock/${model}`;
|
|
447
|
+
}
|
|
679
448
|
function codexBedrockConfigArgs() {
|
|
680
449
|
const region = process.env.AWS_REGION?.trim() || process.env.AWS_DEFAULT_REGION?.trim() || DEFAULT_CODEX_BEDROCK_REGION;
|
|
681
450
|
return ["-c", "model_provider=amazon-bedrock", "-c", `model_providers.amazon-bedrock.region=${region}`];
|
|
682
451
|
}
|
|
683
|
-
function
|
|
452
|
+
function buildArgs(agent, prompt, model, promptViaStdin = false, bedrock = false) {
|
|
684
453
|
const resolvedModel = resolveAgentModel(agent, model, bedrock);
|
|
685
454
|
const modelArg = resolvedModel ? ["--model", resolvedModel] : [];
|
|
686
455
|
const promptArg = promptViaStdin ? [] : [prompt];
|
|
@@ -692,65 +461,22 @@ function buildAgentArgs(agent, prompt, model, promptViaStdin = false, bedrock =
|
|
|
692
461
|
return ["exec", ...bedrockArgs, ...modelArg, "--dangerously-bypass-approvals-and-sandbox", ...promptArg];
|
|
693
462
|
}
|
|
694
463
|
case "opencode":
|
|
695
|
-
return ["run", ...modelArg, ...promptArg];
|
|
696
|
-
case "cursor":
|
|
697
|
-
return ["--print", ...modelArg, ...promptArg];
|
|
698
|
-
case "copilot": {
|
|
699
|
-
const copilotModel = resolveAgentModel("copilot", model);
|
|
700
|
-
const copilotModelArg = !copilotModel || copilotModel === "Auto" ? [] : ["--model", copilotModel];
|
|
701
|
-
return ["-p", ...promptArg, ...copilotModelArg, "--allow-all-tools"];
|
|
702
|
-
}
|
|
703
|
-
}
|
|
704
|
-
}
|
|
705
|
-
var BEDROCK_ENV_BY_AGENT, BEDROCK_CAPABLE_AGENTS, DEFAULT_CODEX_BEDROCK_REGION, DEFAULT_OPENCODE_MODEL, DEFAULT_CODEX_BEDROCK_MODEL, DEFAULT_MODELS;
|
|
706
|
-
var init_build_agent_args = __esm({
|
|
707
|
-
"packages/experience-design-system-generation/dist/src/services/agent/helpers/build-agent-args.js"() {
|
|
708
|
-
"use strict";
|
|
709
|
-
BEDROCK_ENV_BY_AGENT = {
|
|
710
|
-
claude: { CLAUDE_CODE_USE_BEDROCK: "1" }
|
|
711
|
-
};
|
|
712
|
-
BEDROCK_CAPABLE_AGENTS = /* @__PURE__ */ new Set(["claude", "codex", "opencode"]);
|
|
713
|
-
DEFAULT_CODEX_BEDROCK_REGION = "us-east-1";
|
|
714
|
-
DEFAULT_OPENCODE_MODEL = "claude-haiku-4-5";
|
|
715
|
-
DEFAULT_CODEX_BEDROCK_MODEL = "openai.gpt-5.6-luna";
|
|
716
|
-
DEFAULT_MODELS = {
|
|
717
|
-
claude: "haiku",
|
|
718
|
-
opencode: DEFAULT_OPENCODE_MODEL,
|
|
719
|
-
cursor: "gpt-mini",
|
|
720
|
-
copilot: "Auto"
|
|
721
|
-
};
|
|
722
|
-
}
|
|
723
|
-
});
|
|
724
|
-
|
|
725
|
-
// packages/experience-design-system-generation/dist/src/services/agent/run-agent.js
|
|
726
|
-
import { spawn } from "node:child_process";
|
|
727
|
-
function describeAgentFailure(result, maxDetail = 800) {
|
|
728
|
-
const base = result.exitCode !== 0 ? `agent exited with code ${result.exitCode}` : "agent produced no tool calls";
|
|
729
|
-
const detail = (result.stderr.trim() || result.stdout.trim()).slice(-maxDetail).trim();
|
|
730
|
-
return detail ? `${base} \u2014 ${detail}` : base;
|
|
731
|
-
}
|
|
732
|
-
function extractSentinelOutput(stdout) {
|
|
733
|
-
const START = "<<<EDS_OUTPUT_START>>>";
|
|
734
|
-
const END = "<<<EDS_OUTPUT_END>>>";
|
|
735
|
-
const startIdx = stdout.indexOf(START);
|
|
736
|
-
const endIdx = stdout.indexOf(END);
|
|
737
|
-
if (startIdx === -1 || endIdx === -1 || endIdx <= startIdx)
|
|
738
|
-
return null;
|
|
739
|
-
const secondStart = stdout.indexOf(START, startIdx + START.length);
|
|
740
|
-
if (secondStart !== -1 && secondStart < endIdx)
|
|
741
|
-
return "multiple";
|
|
742
|
-
const afterStart = stdout.indexOf(END, startIdx);
|
|
743
|
-
const secondEnd = stdout.indexOf(END, afterStart + END.length);
|
|
744
|
-
if (secondEnd !== -1)
|
|
745
|
-
return "multiple";
|
|
746
|
-
return stdout.slice(startIdx + START.length, endIdx).trim();
|
|
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"];
|
|
471
|
+
}
|
|
472
|
+
}
|
|
747
473
|
}
|
|
748
474
|
async function runAgent(options) {
|
|
749
475
|
const { agent, prompt, timeoutMs, model, onOutput, promptViaStdin, onDebugEvent } = options;
|
|
750
476
|
const bedrock = options.bedrock ?? process.env.EDS_BEDROCK === "1";
|
|
751
|
-
const binary =
|
|
477
|
+
const binary = resolveBinary(agent);
|
|
752
478
|
const useStdin2 = !!promptViaStdin;
|
|
753
|
-
const args =
|
|
479
|
+
const args = buildArgs(agent, prompt, model, useStdin2, bedrock);
|
|
754
480
|
const startedAt = Date.now();
|
|
755
481
|
onDebugEvent?.("run.start", {
|
|
756
482
|
agent,
|
|
@@ -814,24 +540,14 @@ async function runAgent(options) {
|
|
|
814
540
|
});
|
|
815
541
|
});
|
|
816
542
|
}
|
|
817
|
-
var init_run_agent = __esm({
|
|
818
|
-
"packages/experience-design-system-generation/dist/src/services/agent/run-agent.js"() {
|
|
819
|
-
"use strict";
|
|
820
|
-
init_resolve_agent_binary();
|
|
821
|
-
init_build_agent_args();
|
|
822
|
-
}
|
|
823
|
-
});
|
|
824
|
-
|
|
825
|
-
// packages/experience-design-system-generation/dist/src/services/agent/helpers/check-agent-auth.js
|
|
826
|
-
import { spawn as spawn2 } from "node:child_process";
|
|
827
543
|
async function checkAgentAuth(agent) {
|
|
828
|
-
const binary =
|
|
544
|
+
const binary = resolveBinary(agent);
|
|
829
545
|
const binaryExists2 = await new Promise((resolve21) => {
|
|
830
546
|
if (binary.startsWith("/")) {
|
|
831
547
|
import("node:fs/promises").then((fs2) => fs2.access(binary).then(() => resolve21(true), () => resolve21(false)));
|
|
832
548
|
return;
|
|
833
549
|
}
|
|
834
|
-
const child =
|
|
550
|
+
const child = spawn(process.platform === "win32" ? "where" : "which", [binary], { stdio: "ignore" });
|
|
835
551
|
child.on("close", (code) => resolve21(code === 0));
|
|
836
552
|
});
|
|
837
553
|
if (!binaryExists2)
|
|
@@ -839,7 +555,7 @@ async function checkAgentAuth(agent) {
|
|
|
839
555
|
if (agent !== "claude")
|
|
840
556
|
return "ok";
|
|
841
557
|
return new Promise((resolve21) => {
|
|
842
|
-
const child =
|
|
558
|
+
const child = spawn(binary, ["auth", "status", "--json"], {
|
|
843
559
|
stdio: ["ignore", "pipe", "pipe"]
|
|
844
560
|
});
|
|
845
561
|
let stdout = "";
|
|
@@ -872,14 +588,63 @@ async function checkAgentAuth(agent) {
|
|
|
872
588
|
});
|
|
873
589
|
});
|
|
874
590
|
}
|
|
875
|
-
|
|
876
|
-
|
|
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"() {
|
|
877
615
|
"use strict";
|
|
878
|
-
|
|
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";
|
|
879
644
|
}
|
|
880
645
|
});
|
|
881
646
|
|
|
882
|
-
// packages/experience-design-system-generation/dist/src/
|
|
647
|
+
// packages/experience-design-system-generation/dist/src/agent-invoker.js
|
|
883
648
|
function createLocalCliAgentInvoker(options = {}) {
|
|
884
649
|
const { onDebugEvent } = options;
|
|
885
650
|
return {
|
|
@@ -891,310 +656,381 @@ function createLocalCliAgentInvoker(options = {}) {
|
|
|
891
656
|
}
|
|
892
657
|
};
|
|
893
658
|
}
|
|
894
|
-
var
|
|
895
|
-
"packages/experience-design-system-generation/dist/src/
|
|
659
|
+
var init_agent_invoker = __esm({
|
|
660
|
+
"packages/experience-design-system-generation/dist/src/agent-invoker.js"() {
|
|
896
661
|
"use strict";
|
|
897
|
-
|
|
898
|
-
init_check_agent_auth();
|
|
662
|
+
init_agent_runner();
|
|
899
663
|
}
|
|
900
664
|
});
|
|
901
665
|
|
|
902
|
-
// packages/experience-design-system-generation/dist/src/
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
};
|
|
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
|
+
`;
|
|
914
677
|
}
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
init_execute_generation_orchestrator();
|
|
920
|
-
init_local_cli_agent_invoker();
|
|
921
|
-
}
|
|
922
|
-
});
|
|
678
|
+
async function buildPrompt(options) {
|
|
679
|
+
const skillContent = options.skillContentOverride ?? await readSkillFile(options.skill, options.skillPathOverride);
|
|
680
|
+
const preamble = buildPreamble(options);
|
|
681
|
+
return `${preamble}
|
|
923
682
|
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
return i;
|
|
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})`);
|
|
941
699
|
}
|
|
700
|
+
dir = parent;
|
|
942
701
|
}
|
|
943
|
-
return -1;
|
|
944
702
|
}
|
|
945
|
-
function
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
for (const raw of stdout.split("\n")) {
|
|
949
|
-
const line = raw.trim();
|
|
950
|
-
if (!line.startsWith("{"))
|
|
951
|
-
continue;
|
|
952
|
-
const end = findJsonObjectEnd(line);
|
|
953
|
-
if (end === -1) {
|
|
954
|
-
warnings.push(`unparseable line: ${line.slice(0, 120)}`);
|
|
955
|
-
continue;
|
|
956
|
-
}
|
|
957
|
-
let parsed;
|
|
703
|
+
async function readSkillFile(skill, override) {
|
|
704
|
+
if (override) {
|
|
705
|
+
const skillPath2 = resolve(override);
|
|
958
706
|
try {
|
|
959
|
-
|
|
707
|
+
return await readFile2(skillPath2, "utf8");
|
|
960
708
|
} catch {
|
|
961
|
-
|
|
962
|
-
continue;
|
|
963
|
-
}
|
|
964
|
-
const trailing = line.slice(end + 1);
|
|
965
|
-
if (trailing.trim()) {
|
|
966
|
-
warnings.push(`ignored trailing content after JSON: ${trailing.trim().slice(0, 120)}`);
|
|
967
|
-
}
|
|
968
|
-
if (typeof parsed === "object" && parsed !== null && "tool" in parsed) {
|
|
969
|
-
objects.push(parsed);
|
|
709
|
+
throw new Error(`custom prompt file not found (skill: ${skill}, path: ${skillPath2})`);
|
|
970
710
|
}
|
|
971
711
|
}
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
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})`);
|
|
977
717
|
}
|
|
978
|
-
}
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
const
|
|
983
|
-
const
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
if (
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
} else if (tool === "exclude_prop") {
|
|
1023
|
-
if (typeof rec.prop !== "string" || !rec.prop) {
|
|
1024
|
-
warnings.push("exclude_prop missing prop name \u2014 skipped");
|
|
1025
|
-
continue;
|
|
1026
|
-
}
|
|
1027
|
-
calls.push({ tool: "exclude_prop", prop: rec.prop, reason: typeof rec.reason === "string" ? rec.reason : "" });
|
|
1028
|
-
} else if (tool === "classify_component") {
|
|
1029
|
-
const call = { tool: "classify_component" };
|
|
1030
|
-
if (typeof rec.description === "string")
|
|
1031
|
-
call.description = rec.description;
|
|
1032
|
-
if (typeof rec.rationale === "object" && rec.rationale !== null) {
|
|
1033
|
-
const r = rec.rationale;
|
|
1034
|
-
const rationale = {};
|
|
1035
|
-
if (typeof r.description === "string")
|
|
1036
|
-
rationale.description = r.description;
|
|
1037
|
-
if (typeof r.props === "string")
|
|
1038
|
-
rationale.props = r.props;
|
|
1039
|
-
if (typeof r.slots === "string")
|
|
1040
|
-
rationale.slots = r.slots;
|
|
1041
|
-
if (Object.keys(rationale).length > 0)
|
|
1042
|
-
call.rationale = rationale;
|
|
1043
|
-
}
|
|
1044
|
-
calls.push(call);
|
|
1045
|
-
} else if (tool === "classify_slot") {
|
|
1046
|
-
if (typeof rec.slot !== "string" || !rec.slot) {
|
|
1047
|
-
warnings.push("classify_slot missing slot name \u2014 skipped");
|
|
1048
|
-
continue;
|
|
1049
|
-
}
|
|
1050
|
-
const call = { tool: "classify_slot", slot: rec.slot };
|
|
1051
|
-
if (typeof rec.required === "boolean")
|
|
1052
|
-
call.required = rec.required;
|
|
1053
|
-
if (Array.isArray(rec.allowed_components) && rec.allowed_components.every((v) => typeof v === "string")) {
|
|
1054
|
-
call.allowed_components = rec.allowed_components;
|
|
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
|
+
}
|
|
1055
762
|
}
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
call.rationale = rec.rationale;
|
|
1060
|
-
calls.push(call);
|
|
763
|
+
}
|
|
764
|
+
if (Object.keys(filteredProps).length > 0) {
|
|
765
|
+
result[componentName] = { ...component, $properties: filteredProps };
|
|
1061
766
|
}
|
|
1062
767
|
}
|
|
1063
|
-
return {
|
|
768
|
+
return { filtered: result, kinds: [...kinds].sort(), hasUnscoped };
|
|
1064
769
|
}
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
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
|
+
function buildPreamble(options) {
|
|
779
|
+
const { skill, rawComponentsInline, rawTokensInline, rawTokensFilename, tokensInline, tokenMapInline, generatedCdf, tokenTree, componentSourceRefs, existingComponentsInline, existingTokensInline, componentAllowlistInline } = options;
|
|
780
|
+
const sections = [];
|
|
781
|
+
if (existingComponentsInline) {
|
|
782
|
+
sections.push(`Existing components in the target Contentful space (JSON) \u2014 use for alignment, not as a hard filter:
|
|
783
|
+
\`\`\`json
|
|
784
|
+
${existingComponentsInline}
|
|
785
|
+
\`\`\``);
|
|
1073
786
|
}
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
787
|
+
if (existingTokensInline) {
|
|
788
|
+
sections.push(`Existing design tokens in the target Contentful space (JSON) \u2014 prefer binding to these paths over inventing new ones:
|
|
789
|
+
\`\`\`json
|
|
790
|
+
${existingTokensInline}
|
|
791
|
+
\`\`\``);
|
|
792
|
+
}
|
|
793
|
+
if (componentAllowlistInline) {
|
|
794
|
+
sections.push(`Known component names for slot allowed_components (hard allowlist; never use any other name):
|
|
795
|
+
\`\`\`json
|
|
796
|
+
${componentAllowlistInline}
|
|
797
|
+
\`\`\``);
|
|
798
|
+
}
|
|
799
|
+
if (rawComponentsInline) {
|
|
800
|
+
sections.push(`Raw component data (JSON):
|
|
801
|
+
\`\`\`json
|
|
802
|
+
${rawComponentsInline}
|
|
803
|
+
\`\`\``);
|
|
804
|
+
}
|
|
805
|
+
if (rawTokensInline) {
|
|
806
|
+
const lang = inferFenceLang(rawTokensFilename);
|
|
807
|
+
const label = rawTokensFilename ? `Raw token source (${rawTokensFilename})` : "Raw token source";
|
|
808
|
+
sections.push(`${label}:
|
|
809
|
+
\`\`\`${lang}
|
|
810
|
+
${rawTokensInline}
|
|
811
|
+
\`\`\``);
|
|
812
|
+
}
|
|
813
|
+
if (tokensInline) {
|
|
814
|
+
sections.push(`DTCG token data (for token kind lookups):
|
|
815
|
+
\`\`\`json
|
|
816
|
+
${tokensInline}
|
|
817
|
+
\`\`\``);
|
|
818
|
+
}
|
|
819
|
+
if (tokenMapInline) {
|
|
820
|
+
sections.push(`Token-name sidecar (raw name \u2192 DTCG path):
|
|
821
|
+
\`\`\`json
|
|
822
|
+
${tokenMapInline}
|
|
823
|
+
\`\`\``);
|
|
824
|
+
}
|
|
825
|
+
const filteredTokenProps = generatedCdf ? filterDesignTokenProps(generatedCdf) : void 0;
|
|
826
|
+
if (filteredTokenProps && Object.keys(filteredTokenProps.filtered).length > 0) {
|
|
827
|
+
sections.push(`Generated CDF so far \u2014 design-category token props only (JSON):
|
|
828
|
+
\`\`\`json
|
|
829
|
+
${JSON.stringify(filteredTokenProps.filtered)}
|
|
830
|
+
\`\`\``);
|
|
831
|
+
}
|
|
832
|
+
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));
|
|
1093
844
|
} else {
|
|
1094
|
-
|
|
845
|
+
sections.push(renderTokenCandidateSection(null, index));
|
|
1095
846
|
}
|
|
1096
847
|
}
|
|
1097
|
-
calls.push(call);
|
|
1098
848
|
}
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
}
|
|
849
|
+
if (componentSourceRefs && componentSourceRefs.length > 0) {
|
|
850
|
+
const withContent = componentSourceRefs.filter((ref) => ref.content != null);
|
|
851
|
+
const withoutContent = componentSourceRefs.filter((ref) => ref.content == null);
|
|
852
|
+
if (withContent.length > 0) {
|
|
853
|
+
const blocks = withContent.map((ref) => {
|
|
854
|
+
const mainBlock = `#### ${ref.component} (\`${ref.sourcePath}\`)
|
|
855
|
+
\`\`\`${inferFenceLang(ref.sourcePath)}
|
|
856
|
+
${ref.content}
|
|
857
|
+
\`\`\``;
|
|
858
|
+
const siblingBlocks = (ref.siblingFiles ?? []).map((sibling) => `##### ${ref.component} \u2014 imported file \`${sibling.path}\`
|
|
859
|
+
\`\`\`${inferFenceLang(sibling.path)}
|
|
860
|
+
${sibling.content}
|
|
861
|
+
\`\`\``);
|
|
862
|
+
const truncationNote = ref.truncatedSiblingCount && ref.truncatedSiblingCount > 0 ? [
|
|
863
|
+
`##### ${ref.component} \u2014 +${ref.truncatedSiblingCount} more imported file${ref.truncatedSiblingCount === 1 ? "" : "s"} not shown (evidence may be incomplete)`
|
|
864
|
+
] : [];
|
|
865
|
+
const notShownNote = ref.usesNotShown && ref.usesNotShown.length > 0 ? [
|
|
866
|
+
`##### ${ref.component} \u2014 uses not shown: ${ref.usesNotShown.join(", ")}
|
|
1109
867
|
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
continue;
|
|
1125
|
-
}
|
|
1126
|
-
if (!("value" in rec)) {
|
|
1127
|
-
warnings.push(`set_token '${rec.path}': missing value \u2014 skipped`);
|
|
1128
|
-
continue;
|
|
1129
|
-
}
|
|
1130
|
-
const call = { tool: "set_token", path: rec.path, type: rec.type, value: rec.value };
|
|
1131
|
-
if (typeof rec.description === "string")
|
|
1132
|
-
call.description = rec.description;
|
|
1133
|
-
calls.push(call);
|
|
1134
|
-
} else if (rec.tool === "set_group") {
|
|
1135
|
-
if (typeof rec.path !== "string" || !rec.path) {
|
|
1136
|
-
warnings.push("set_group missing path \u2014 skipped");
|
|
1137
|
-
continue;
|
|
1138
|
-
}
|
|
1139
|
-
const call = { tool: "set_group", path: rec.path };
|
|
1140
|
-
if (typeof rec.description === "string")
|
|
1141
|
-
call.description = rec.description;
|
|
1142
|
-
calls.push(call);
|
|
868
|
+
The files above are excerpts, and each of these properties has at least one use that fell outside the excerpt budget. Treat their consumption as unknown, not absent: do not classify them \`token\` on what is shown, and do not conclude they are unread.`
|
|
869
|
+
] : [];
|
|
870
|
+
return [mainBlock, ...siblingBlocks, ...truncationNote, ...notShownNote].join("\n\n");
|
|
871
|
+
});
|
|
872
|
+
sections.push(`### Component source references
|
|
873
|
+
|
|
874
|
+
${blocks.join("\n\n")}`);
|
|
875
|
+
}
|
|
876
|
+
if (withoutContent.length > 0) {
|
|
877
|
+
const guidance = skill === "components" ? "there is no consumption evidence for these, so `token` cannot be earned for any of their props \u2014 classify from the prop signature alone, and any prop that would otherwise be enum-versus-token is `enum` (or `string`)" : "there is no source evidence to narrow from \u2014 emit nothing for their props";
|
|
878
|
+
sections.push(`Component source unavailable for (JSON) \u2014 ${guidance}:
|
|
879
|
+
\`\`\`json
|
|
880
|
+
${JSON.stringify(withoutContent.map((ref) => ({ component: ref.component, sourcePath: ref.sourcePath })))}
|
|
881
|
+
\`\`\``);
|
|
1143
882
|
}
|
|
1144
883
|
}
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
"use strict";
|
|
1151
|
-
init_read_tool_call_objects();
|
|
1152
|
-
VALID_TOKEN_TOOL_NAMES = /* @__PURE__ */ new Set(["set_token", "set_group"]);
|
|
884
|
+
const inputBlock = sections.length > 0 ? `
|
|
885
|
+
|
|
886
|
+
${sections.join("\n\n")}` : "";
|
|
887
|
+
if (skill === "components") {
|
|
888
|
+
return buildComponentsAutonomousPreamble(inputBlock);
|
|
1153
889
|
}
|
|
1154
|
-
|
|
890
|
+
if (skill === "select") {
|
|
891
|
+
return buildSelectAutonomousPreamble(inputBlock);
|
|
892
|
+
}
|
|
893
|
+
if (skill === "map-tokens") {
|
|
894
|
+
return buildMapTokensAutonomousPreamble(inputBlock);
|
|
895
|
+
}
|
|
896
|
+
return buildTokensAutonomousPreamble(inputBlock);
|
|
897
|
+
}
|
|
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
|
+
\`\`\`
|
|
925
|
+
|
|
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.`;
|
|
943
|
+
}
|
|
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>"}
|
|
961
|
+
|
|
962
|
+
{"tool":"reject_component","name":"<ComponentName>","reason":"<brief reason>"}
|
|
963
|
+
\`\`\`
|
|
964
|
+
|
|
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.`;
|
|
969
|
+
}
|
|
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.
|
|
972
|
+
|
|
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.
|
|
974
|
+
|
|
975
|
+
All input data is provided inline below \u2014 do not read any additional files.${inputBlock}
|
|
976
|
+
|
|
977
|
+
## Output protocol
|
|
978
|
+
|
|
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.
|
|
980
|
+
|
|
981
|
+
The one tool call you may emit:
|
|
1155
982
|
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
983
|
+
\`\`\`
|
|
984
|
+
{"tool":"map_token_prop","component":"<ComponentName>","prop":"<propName>","token_allowed":["colors.brand.primary","colors.brand.secondary"]}
|
|
985
|
+
\`\`\`
|
|
986
|
+
|
|
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.`;
|
|
1159
994
|
}
|
|
1160
|
-
function
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
warnings.push(`map_token_prop '${rec.component}.${String(rec.prop)}': missing or empty token_allowed \u2014 skipped`);
|
|
1189
|
-
continue;
|
|
1190
|
-
}
|
|
1191
|
-
calls.push({ tool: "map_token_prop", component: rec.component, prop: rec.prop, token_allowed: rec.token_allowed });
|
|
1192
|
-
}
|
|
1193
|
-
return { calls, warnings };
|
|
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:
|
|
1007
|
+
|
|
1008
|
+
\`\`\`
|
|
1009
|
+
{"tool":"set_group","path":"<dot.notation.path>","description":"<optional group description>"}
|
|
1010
|
+
|
|
1011
|
+
{"tool":"set_token","path":"<dot.notation.path>","type":"<DTCG type>","value":<value>,"description":"<reason>"}
|
|
1012
|
+
\`\`\`
|
|
1013
|
+
|
|
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.`;
|
|
1194
1023
|
}
|
|
1195
|
-
var
|
|
1196
|
-
|
|
1024
|
+
var SKILL_FILES;
|
|
1025
|
+
var init_prompt_builder = __esm({
|
|
1026
|
+
"packages/experience-design-system-generation/dist/src/prompt-builder.js"() {
|
|
1197
1027
|
"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
|
+
};
|
|
1198
1034
|
}
|
|
1199
1035
|
});
|
|
1200
1036
|
|
|
@@ -1214,13 +1050,11 @@ __export(src_exports, {
|
|
|
1214
1050
|
AGENT_NAMES: () => AGENT_NAMES,
|
|
1215
1051
|
DEFAULT_AGENT_NAME: () => DEFAULT_AGENT_NAME,
|
|
1216
1052
|
agentSupportsBedrock: () => agentSupportsBedrock,
|
|
1217
|
-
buildArgs: () =>
|
|
1053
|
+
buildArgs: () => buildArgs,
|
|
1218
1054
|
buildPrompt: () => buildPrompt,
|
|
1219
1055
|
checkAgentAuth: () => checkAgentAuth,
|
|
1220
|
-
createGenerationEndpoint: () => createGenerationEndpoint,
|
|
1221
1056
|
createLocalCliAgentInvoker: () => createLocalCliAgentInvoker,
|
|
1222
1057
|
describeAgentFailure: () => describeAgentFailure,
|
|
1223
|
-
executeGenerationOrchestrator: () => executeGenerationOrchestrator,
|
|
1224
1058
|
extractSentinelOutput: () => extractSentinelOutput,
|
|
1225
1059
|
formatCustomPromptBanner: () => formatCustomPromptBanner,
|
|
1226
1060
|
formatGenerateProgressLine: () => formatGenerateProgressLine,
|
|
@@ -1228,9 +1062,9 @@ __export(src_exports, {
|
|
|
1228
1062
|
parseMapTokenPropToolCallLines: () => parseMapTokenPropToolCallLines,
|
|
1229
1063
|
parseSelectToolCallLines: () => parseSelectToolCallLines,
|
|
1230
1064
|
parseTokenToolCallLines: () => parseTokenToolCallLines,
|
|
1231
|
-
parseToolCallLines: () =>
|
|
1065
|
+
parseToolCallLines: () => parseToolCallLines,
|
|
1232
1066
|
resolveAgentModel: () => resolveAgentModel,
|
|
1233
|
-
resolveBinary: () =>
|
|
1067
|
+
resolveBinary: () => resolveBinary,
|
|
1234
1068
|
resolveSkillPath: () => resolveSkillPath,
|
|
1235
1069
|
runAgent: () => runAgent
|
|
1236
1070
|
});
|
|
@@ -1238,19 +1072,10 @@ var init_src = __esm({
|
|
|
1238
1072
|
"packages/experience-design-system-generation/dist/src/index.js"() {
|
|
1239
1073
|
"use strict";
|
|
1240
1074
|
init_agent_names();
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
init_resolve_agent_binary();
|
|
1245
|
-
init_check_agent_auth();
|
|
1246
|
-
init_run_agent();
|
|
1247
|
-
init_parse_prop_tool_calls();
|
|
1248
|
-
init_parse_select_tool_calls();
|
|
1249
|
-
init_parse_token_tool_calls();
|
|
1250
|
-
init_parse_map_token_tool_calls();
|
|
1251
|
-
init_build_prompt();
|
|
1075
|
+
init_agent_runner();
|
|
1076
|
+
init_agent_invoker();
|
|
1077
|
+
init_prompt_builder();
|
|
1252
1078
|
init_progress();
|
|
1253
|
-
init_local_cli_agent_invoker();
|
|
1254
1079
|
}
|
|
1255
1080
|
});
|
|
1256
1081
|
|
|
@@ -1388,8 +1213,8 @@ function makeSessionTimestamp() {
|
|
|
1388
1213
|
const override = process.env["EDSI_DEBUG_TS"];
|
|
1389
1214
|
if (override) return override;
|
|
1390
1215
|
const now = /* @__PURE__ */ new Date();
|
|
1391
|
-
const
|
|
1392
|
-
return `${now.getUTCFullYear()}${
|
|
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`;
|
|
1393
1218
|
}
|
|
1394
1219
|
function initDebugLogger(opts) {
|
|
1395
1220
|
if (singleton) return singleton;
|
|
@@ -2186,8 +2011,8 @@ function deleteRawTokensForSession(db, sessionId2) {
|
|
|
2186
2011
|
}
|
|
2187
2012
|
function createRawTokenGroups(db, sessionId2, groups) {
|
|
2188
2013
|
const insertGroup = db.prepare(`INSERT INTO raw_token_groups (session_id, path, description) VALUES (?, ?, ?)`);
|
|
2189
|
-
for (const
|
|
2190
|
-
insertGroup.run(sessionId2,
|
|
2014
|
+
for (const group2 of groups) {
|
|
2015
|
+
insertGroup.run(sessionId2, group2.path, group2.$description ?? null);
|
|
2191
2016
|
}
|
|
2192
2017
|
}
|
|
2193
2018
|
function createRawTokens(db, sessionId2, tokens) {
|
|
@@ -5085,7 +4910,7 @@ async function readFileInline(path) {
|
|
|
5085
4910
|
return parts.filter(Boolean).join("\n\n");
|
|
5086
4911
|
}
|
|
5087
4912
|
function printFallbackInstructions(options) {
|
|
5088
|
-
const binary =
|
|
4913
|
+
const binary = resolveBinary(options.agent);
|
|
5089
4914
|
const skillPath = resolveSkillPath(options.skill);
|
|
5090
4915
|
const lines = [
|
|
5091
4916
|
`Error: agent '${options.agent}' not found in $PATH (looked for binary: ${binary}).`,
|
|
@@ -5300,7 +5125,7 @@ ${outputBuf}`);
|
|
|
5300
5125
|
lastError = describeAgentFailure(result);
|
|
5301
5126
|
continue;
|
|
5302
5127
|
}
|
|
5303
|
-
const { calls, warnings } =
|
|
5128
|
+
const { calls, warnings } = parseToolCallLines(result.stdout);
|
|
5304
5129
|
if (calls.length === 0) {
|
|
5305
5130
|
lastError = describeAgentFailure(result);
|
|
5306
5131
|
continue;
|
|
@@ -5546,7 +5371,7 @@ async function runGenerateSkill(skill, opts, verbose = false) {
|
|
|
5546
5371
|
process.stdout.write(prompt + "\n");
|
|
5547
5372
|
await exitWithAnalytics(0);
|
|
5548
5373
|
}
|
|
5549
|
-
const binary =
|
|
5374
|
+
const binary = resolveBinary(agent);
|
|
5550
5375
|
if (!await assertBinaryInPath(binary)) {
|
|
5551
5376
|
printFallbackInstructions({
|
|
5552
5377
|
agent,
|
|
@@ -7066,24 +6891,24 @@ function parseEdsiError(rawInput) {
|
|
|
7066
6891
|
}
|
|
7067
6892
|
}
|
|
7068
6893
|
const cleaned = stripLambdaLogPrefix(body);
|
|
7069
|
-
const
|
|
7070
|
-
const bindingFromJson = typeof
|
|
6894
|
+
const json2 = parseJsonBody(cleaned) ?? parseJsonBody(body);
|
|
6895
|
+
const bindingFromJson = typeof json2?.message === "string" ? parseBindingDiagnostics(json2.message) : null;
|
|
7071
6896
|
if (bindingFromJson) {
|
|
7072
6897
|
return {
|
|
7073
|
-
code: bindingFromJson.code ??
|
|
6898
|
+
code: bindingFromJson.code ?? json2?.code ?? null,
|
|
7074
6899
|
message: bindingFromJson.message ?? cleaned,
|
|
7075
6900
|
cycle: null,
|
|
7076
6901
|
raw: false,
|
|
7077
6902
|
...bindingFromJson.diagnostics ? { diagnostics: bindingFromJson.diagnostics } : {}
|
|
7078
6903
|
};
|
|
7079
6904
|
}
|
|
7080
|
-
if (
|
|
6905
|
+
if (json2 && (json2.code || json2.message || json2.cycle)) {
|
|
7081
6906
|
return {
|
|
7082
|
-
code:
|
|
7083
|
-
message:
|
|
7084
|
-
cycle:
|
|
6907
|
+
code: json2.code ?? null,
|
|
6908
|
+
message: json2.message ?? (cleaned || prefix),
|
|
6909
|
+
cycle: json2.cycle ?? null,
|
|
7085
6910
|
raw: false,
|
|
7086
|
-
...
|
|
6911
|
+
...json2.diagnostics ? { diagnostics: json2.diagnostics } : {}
|
|
7087
6912
|
};
|
|
7088
6913
|
}
|
|
7089
6914
|
const binding = parseBindingDiagnostics(cleaned);
|
|
@@ -8623,8 +8448,8 @@ async function resolveSession(sessionFlag, command) {
|
|
|
8623
8448
|
}
|
|
8624
8449
|
function rebuildDTCGTree(groups, tokens) {
|
|
8625
8450
|
const root = {};
|
|
8626
|
-
for (const
|
|
8627
|
-
const segments =
|
|
8451
|
+
for (const group2 of groups) {
|
|
8452
|
+
const segments = group2.path.split(".");
|
|
8628
8453
|
let node = root;
|
|
8629
8454
|
for (const seg of segments) {
|
|
8630
8455
|
if (typeof node[seg] !== "object" || node[seg] === null) {
|
|
@@ -8632,8 +8457,8 @@ function rebuildDTCGTree(groups, tokens) {
|
|
|
8632
8457
|
}
|
|
8633
8458
|
node = node[seg];
|
|
8634
8459
|
}
|
|
8635
|
-
if (
|
|
8636
|
-
node["$description"] =
|
|
8460
|
+
if (group2.$description) {
|
|
8461
|
+
node["$description"] = group2.$description;
|
|
8637
8462
|
}
|
|
8638
8463
|
}
|
|
8639
8464
|
for (const token of tokens) {
|
|
@@ -9207,7 +9032,7 @@ ${defaultDiagnostics.map((diagnostic) => ` ${diagnostic}`).join("\n")}
|
|
|
9207
9032
|
return;
|
|
9208
9033
|
}
|
|
9209
9034
|
}
|
|
9210
|
-
const binary =
|
|
9035
|
+
const binary = resolveBinary(agent);
|
|
9211
9036
|
if (!await assertBinaryInPath(binary)) {
|
|
9212
9037
|
die(
|
|
9213
9038
|
`Error: agent '${agent}' not found in $PATH (looked for binary: ${binary}).
|
|
@@ -9376,6 +9201,214 @@ var init_run_teaser = __esm({
|
|
|
9376
9201
|
}
|
|
9377
9202
|
});
|
|
9378
9203
|
|
|
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
|
+
|
|
9379
9412
|
// packages/experience-design-system-cli-legacy/src/tui/use-blinking-cursor.ts
|
|
9380
9413
|
import { useEffect as useEffect2, useState as useState3 } from "react";
|
|
9381
9414
|
function useBlinkingCursor() {
|
|
@@ -9395,8 +9428,8 @@ var init_use_blinking_cursor = __esm({
|
|
|
9395
9428
|
// packages/experience-design-system-cli-legacy/src/runs/path-prompt.tsx
|
|
9396
9429
|
import { useState as useState4 } from "react";
|
|
9397
9430
|
import { Box as Box6, Text as Text7 } from "ink";
|
|
9398
|
-
import { readdirSync } from "node:fs";
|
|
9399
|
-
import { dirname as dirname5, basename as basename2, join as
|
|
9431
|
+
import { readdirSync as readdirSync2 } from "node:fs";
|
|
9432
|
+
import { dirname as dirname5, basename as basename2, join as join11 } from "node:path";
|
|
9400
9433
|
import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
9401
9434
|
function autocomplete(partial) {
|
|
9402
9435
|
if (!partial) return null;
|
|
@@ -9405,19 +9438,19 @@ function autocomplete(partial) {
|
|
|
9405
9438
|
const base = basename2(normalized);
|
|
9406
9439
|
let entries;
|
|
9407
9440
|
try {
|
|
9408
|
-
entries =
|
|
9441
|
+
entries = readdirSync2(dir);
|
|
9409
9442
|
} catch {
|
|
9410
9443
|
return null;
|
|
9411
9444
|
}
|
|
9412
9445
|
const matches = entries.filter((e) => e.startsWith(base));
|
|
9413
9446
|
if (matches.length === 0) return null;
|
|
9414
|
-
if (matches.length === 1) return
|
|
9447
|
+
if (matches.length === 1) return join11(dir, matches[0]);
|
|
9415
9448
|
let prefix = matches[0];
|
|
9416
9449
|
for (const m of matches) {
|
|
9417
9450
|
while (!m.startsWith(prefix)) prefix = prefix.slice(0, -1);
|
|
9418
9451
|
if (!prefix) break;
|
|
9419
9452
|
}
|
|
9420
|
-
return prefix.length > base.length ?
|
|
9453
|
+
return prefix.length > base.length ? join11(dir, prefix) : null;
|
|
9421
9454
|
}
|
|
9422
9455
|
function PathPrompt({
|
|
9423
9456
|
defaultPath,
|
|
@@ -9482,12 +9515,12 @@ var init_path_prompt = __esm({
|
|
|
9482
9515
|
|
|
9483
9516
|
// packages/experience-design-system-cli-legacy/src/runs/save-path-resolver.ts
|
|
9484
9517
|
import { access as access4 } from "node:fs/promises";
|
|
9485
|
-
import { join as
|
|
9518
|
+
import { join as join12 } from "node:path";
|
|
9486
9519
|
async function listConflictingFiles(path) {
|
|
9487
9520
|
const conflicts = [];
|
|
9488
9521
|
for (const name of SAVE_FILES) {
|
|
9489
9522
|
try {
|
|
9490
|
-
await access4(
|
|
9523
|
+
await access4(join12(path, name));
|
|
9491
9524
|
conflicts.push(name);
|
|
9492
9525
|
} catch {
|
|
9493
9526
|
}
|
|
@@ -9507,7 +9540,7 @@ function buildTimestampedSubdir(base, now = /* @__PURE__ */ new Date()) {
|
|
|
9507
9540
|
const hh = pad2(now.getHours());
|
|
9508
9541
|
const mm = pad2(now.getMinutes());
|
|
9509
9542
|
const ss = pad2(now.getSeconds());
|
|
9510
|
-
return
|
|
9543
|
+
return join12(base, `dsi-${y}${m}${d}-${hh}${mm}${ss}`);
|
|
9511
9544
|
}
|
|
9512
9545
|
var SAVE_FILES;
|
|
9513
9546
|
var init_save_path_resolver = __esm({
|
|
@@ -9519,7 +9552,7 @@ var init_save_path_resolver = __esm({
|
|
|
9519
9552
|
|
|
9520
9553
|
// packages/experience-design-system-cli-legacy/src/runs/store.ts
|
|
9521
9554
|
import { readFile as readFile12, writeFile as writeFile4, mkdir as mkdir4, rename } from "node:fs/promises";
|
|
9522
|
-
import { join as
|
|
9555
|
+
import { join as join13 } from "node:path";
|
|
9523
9556
|
import { homedir as homedir6 } from "node:os";
|
|
9524
9557
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
9525
9558
|
function encodeBase32(bytes, length) {
|
|
@@ -9615,8 +9648,8 @@ var init_store = __esm({
|
|
|
9615
9648
|
RUNS_FILE_VERSION = 3;
|
|
9616
9649
|
RUNS_FILE_CAP = 200;
|
|
9617
9650
|
READABLE_VERSIONS = /* @__PURE__ */ new Set([1, 2, 3]);
|
|
9618
|
-
RUNS_DIR =
|
|
9619
|
-
RUNS_PATH =
|
|
9651
|
+
RUNS_DIR = join13(homedir6(), ".config", "experiences");
|
|
9652
|
+
RUNS_PATH = join13(RUNS_DIR, "runs.json");
|
|
9620
9653
|
CROCKFORD = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
|
|
9621
9654
|
}
|
|
9622
9655
|
});
|
|
@@ -9773,7 +9806,7 @@ var init_WelcomeStep = __esm({
|
|
|
9773
9806
|
import { useState as useState6, useEffect as useEffect3 } from "react";
|
|
9774
9807
|
import { Box as Box9, Text as Text10 } from "ink";
|
|
9775
9808
|
import { promises as fs } from "node:fs";
|
|
9776
|
-
import { join as
|
|
9809
|
+
import { join as join14 } from "node:path";
|
|
9777
9810
|
import { jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
9778
9811
|
async function countFiles(dir) {
|
|
9779
9812
|
const counts = {
|
|
@@ -9797,7 +9830,7 @@ async function countFiles(dir) {
|
|
|
9797
9830
|
await Promise.all(
|
|
9798
9831
|
entries.map(async (entry) => {
|
|
9799
9832
|
if (IGNORE_DIRS.has(entry)) return;
|
|
9800
|
-
const full =
|
|
9833
|
+
const full = join14(current, entry);
|
|
9801
9834
|
let stat7;
|
|
9802
9835
|
try {
|
|
9803
9836
|
stat7 = await fs.stat(full);
|
|
@@ -10873,6 +10906,7 @@ function WizardPreviewStep({
|
|
|
10873
10906
|
environmentId,
|
|
10874
10907
|
stepNumber,
|
|
10875
10908
|
totalSteps,
|
|
10909
|
+
droppedTokenDefaults = [],
|
|
10876
10910
|
onConfirm,
|
|
10877
10911
|
onEdit,
|
|
10878
10912
|
onQuit
|
|
@@ -10965,6 +10999,13 @@ function WizardPreviewStep({
|
|
|
10965
10999
|
}
|
|
10966
11000
|
)
|
|
10967
11001
|
] }) : /* @__PURE__ */ jsx19(Text17, { dimColor: true, children: "Nothing to push \u2014 everything is already up to date." }),
|
|
11002
|
+
droppedTokenDefaults.length > 0 && /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", children: [
|
|
11003
|
+
/* @__PURE__ */ jsx19(Text17, { color: PALETTE.warning, bold: true, children: "\u26A0 Some token defaults will be left out so the push can succeed:" }),
|
|
11004
|
+
droppedTokenDefaults.map((line) => /* @__PURE__ */ jsxs16(Text17, { color: PALETTE.warning, wrap: "truncate-end", children: [
|
|
11005
|
+
" ",
|
|
11006
|
+
line
|
|
11007
|
+
] }, line))
|
|
11008
|
+
] }),
|
|
10968
11009
|
breakingWithImpact && /* @__PURE__ */ jsx19(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx19(Text17, { color: PALETTE.error, bold: true, children: "\u26A0 Breaking changes will affect downstream entities. Press Enter to acknowledge and apply." }) }),
|
|
10969
11010
|
/* @__PURE__ */ jsx19(SpaceEnvironment, { spaceId, environmentId }),
|
|
10970
11011
|
/* @__PURE__ */ jsxs16(Box16, { gap: 3, marginTop: 1, children: [
|
|
@@ -11016,7 +11057,7 @@ function DoneStep({
|
|
|
11016
11057
|
});
|
|
11017
11058
|
const totalFailed = componentTypes.failed + designTokens.failed;
|
|
11018
11059
|
const totalPushed = componentTypes.created + componentTypes.updated + componentTypes.removed + designTokens.created + designTokens.updated + designTokens.removed;
|
|
11019
|
-
const success = totalFailed === 0;
|
|
11060
|
+
const success = totalFailed === 0 && (summary?.failed ?? 0) === 0;
|
|
11020
11061
|
function EntityRows({ entity, label }) {
|
|
11021
11062
|
return /* @__PURE__ */ jsxs17(Fragment5, { children: [
|
|
11022
11063
|
entity.created > 0 && /* @__PURE__ */ jsxs17(Box17, { gap: 1, children: [
|
|
@@ -11062,7 +11103,7 @@ function DoneStep({
|
|
|
11062
11103
|
] });
|
|
11063
11104
|
}
|
|
11064
11105
|
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", gap: 1, paddingX: 2, paddingY: 1, children: [
|
|
11065
|
-
success ? /* @__PURE__ */ jsx20(Text18, { bold: true, color: PALETTE.success, children: "Done!" }) : /* @__PURE__ */ jsx20(Text18, { bold: true, color: PALETTE.
|
|
11106
|
+
success ? /* @__PURE__ */ jsx20(Text18, { bold: true, color: PALETTE.success, children: "Done!" }) : /* @__PURE__ */ jsx20(Text18, { bold: true, color: PALETTE.error, children: "\u2717 Push failed \u2014 nothing was changed for the items below" }),
|
|
11066
11107
|
totalPushed === 0 && totalFailed === 0 && !summary ? /* @__PURE__ */ jsx20(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx20(Text18, { dimColor: true, children: "Nothing was pushed \u2014 everything was already up to date." }) }) : /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", gap: 0, marginTop: 1, children: [
|
|
11067
11108
|
/* @__PURE__ */ jsx20(EntityRows, { entity: componentTypes, label: "Component Type" }),
|
|
11068
11109
|
/* @__PURE__ */ jsx20(EntityRows, { entity: designTokens, label: "Design Token" }),
|
|
@@ -11482,8 +11523,8 @@ var init_types = __esm({
|
|
|
11482
11523
|
});
|
|
11483
11524
|
|
|
11484
11525
|
// packages/experience-design-system-extraction/dist/src/extract/tsx-shared.js
|
|
11485
|
-
import { existsSync as
|
|
11486
|
-
import { dirname as dirname6, join as
|
|
11526
|
+
import { existsSync as existsSync4, readFileSync as readFileSync5 } from "node:fs";
|
|
11527
|
+
import { dirname as dirname6, join as join15, resolve as resolve12 } from "node:path";
|
|
11487
11528
|
import { Node, Project, SyntaxKind } from "ts-morph";
|
|
11488
11529
|
import ts from "typescript";
|
|
11489
11530
|
function createTsxProject(filePaths) {
|
|
@@ -11682,8 +11723,8 @@ function findNearestTsConfigPath(filePath) {
|
|
|
11682
11723
|
let currentDir = dirname6(filePath);
|
|
11683
11724
|
while (true) {
|
|
11684
11725
|
for (const candidateName of ["tsconfig.json", "jsconfig.json"]) {
|
|
11685
|
-
const candidatePath =
|
|
11686
|
-
if (
|
|
11726
|
+
const candidatePath = join15(currentDir, candidateName);
|
|
11727
|
+
if (existsSync4(candidatePath)) {
|
|
11687
11728
|
nearestTsConfigPathCache.set(filePath, candidatePath);
|
|
11688
11729
|
return candidatePath;
|
|
11689
11730
|
}
|
|
@@ -11739,12 +11780,12 @@ function resolveImportSourcePath(basePath) {
|
|
|
11739
11780
|
`${basePath}.tsx`,
|
|
11740
11781
|
`${basePath}.js`,
|
|
11741
11782
|
`${basePath}.jsx`,
|
|
11742
|
-
|
|
11743
|
-
|
|
11744
|
-
|
|
11745
|
-
|
|
11783
|
+
join15(basePath, "index.ts"),
|
|
11784
|
+
join15(basePath, "index.tsx"),
|
|
11785
|
+
join15(basePath, "index.js"),
|
|
11786
|
+
join15(basePath, "index.jsx")
|
|
11746
11787
|
];
|
|
11747
|
-
return candidates.find((candidatePath) =>
|
|
11788
|
+
return candidates.find((candidatePath) => existsSync4(candidatePath));
|
|
11748
11789
|
}
|
|
11749
11790
|
function findProjectSourceFileByImportPath(project, resolvedPath) {
|
|
11750
11791
|
const candidatePaths = [
|
|
@@ -11753,10 +11794,10 @@ function findProjectSourceFileByImportPath(project, resolvedPath) {
|
|
|
11753
11794
|
`${resolvedPath}.tsx`,
|
|
11754
11795
|
`${resolvedPath}.js`,
|
|
11755
11796
|
`${resolvedPath}.jsx`,
|
|
11756
|
-
|
|
11757
|
-
|
|
11758
|
-
|
|
11759
|
-
|
|
11797
|
+
join15(resolvedPath, "index.ts"),
|
|
11798
|
+
join15(resolvedPath, "index.tsx"),
|
|
11799
|
+
join15(resolvedPath, "index.js"),
|
|
11800
|
+
join15(resolvedPath, "index.jsx")
|
|
11760
11801
|
];
|
|
11761
11802
|
for (const candidatePath of candidatePaths) {
|
|
11762
11803
|
const sourceFile = project.getSourceFile(candidatePath);
|
|
@@ -11777,10 +11818,10 @@ function findWorkspacePackageEntrySourceFile(originSourceFile, moduleSpecifier)
|
|
|
11777
11818
|
if (!packageRootDir)
|
|
11778
11819
|
return void 0;
|
|
11779
11820
|
const preferredEntryPaths = [
|
|
11780
|
-
|
|
11781
|
-
|
|
11782
|
-
|
|
11783
|
-
|
|
11821
|
+
join15(packageRootDir, "src/index.ts"),
|
|
11822
|
+
join15(packageRootDir, "src/index.tsx"),
|
|
11823
|
+
join15(packageRootDir, "index.ts"),
|
|
11824
|
+
join15(packageRootDir, "index.tsx")
|
|
11784
11825
|
];
|
|
11785
11826
|
for (const entryPath of preferredEntryPaths) {
|
|
11786
11827
|
const entrySourceFile = project.getSourceFile(entryPath);
|
|
@@ -11788,7 +11829,7 @@ function findWorkspacePackageEntrySourceFile(originSourceFile, moduleSpecifier)
|
|
|
11788
11829
|
return entrySourceFile;
|
|
11789
11830
|
}
|
|
11790
11831
|
}
|
|
11791
|
-
return candidateSourceFiles.find((sourceFile) => sourceFile.getDirectoryPath() ===
|
|
11832
|
+
return candidateSourceFiles.find((sourceFile) => sourceFile.getDirectoryPath() === join15(packageRootDir, "src"));
|
|
11792
11833
|
}
|
|
11793
11834
|
function getWorkspacePackageManifestForSourceFile(sourceFile) {
|
|
11794
11835
|
const packageRootDir = findNearestPackageRootDir(sourceFile.getFilePath());
|
|
@@ -11797,7 +11838,7 @@ function getWorkspacePackageManifestForSourceFile(sourceFile) {
|
|
|
11797
11838
|
if (workspacePackageManifestCache.has(packageRootDir)) {
|
|
11798
11839
|
return workspacePackageManifestCache.get(packageRootDir) ?? void 0;
|
|
11799
11840
|
}
|
|
11800
|
-
const packageJsonPath =
|
|
11841
|
+
const packageJsonPath = join15(packageRootDir, "package.json");
|
|
11801
11842
|
try {
|
|
11802
11843
|
const packageJson = JSON.parse(readFileSync5(packageJsonPath, "utf8"));
|
|
11803
11844
|
const manifest = typeof packageJson.name === "string" ? { name: packageJson.name, rootDir: packageRootDir } : null;
|
|
@@ -11814,7 +11855,7 @@ function findNearestPackageRootDir(filePath) {
|
|
|
11814
11855
|
}
|
|
11815
11856
|
let currentDir = dirname6(filePath);
|
|
11816
11857
|
while (true) {
|
|
11817
|
-
if (
|
|
11858
|
+
if (existsSync4(join15(currentDir, "package.json"))) {
|
|
11818
11859
|
packageRootByFilePathCache.set(filePath, currentDir);
|
|
11819
11860
|
return currentDir;
|
|
11820
11861
|
}
|
|
@@ -14876,8 +14917,8 @@ var init_vue_tsx = __esm({
|
|
|
14876
14917
|
});
|
|
14877
14918
|
|
|
14878
14919
|
// packages/experience-design-system-extraction/dist/src/extract/resolve-local-module.js
|
|
14879
|
-
import { existsSync as
|
|
14880
|
-
import { dirname as dirname7, join as
|
|
14920
|
+
import { existsSync as existsSync5, statSync as statSync2 } from "node:fs";
|
|
14921
|
+
import { dirname as dirname7, join as join16, resolve as resolve13 } from "node:path";
|
|
14881
14922
|
function resolveLocalModule(importingFilePath, specifier, options = {}) {
|
|
14882
14923
|
const basePath = resolve13(dirname7(importingFilePath), specifier);
|
|
14883
14924
|
const candidates = [
|
|
@@ -14886,18 +14927,18 @@ function resolveLocalModule(importingFilePath, specifier, options = {}) {
|
|
|
14886
14927
|
`${basePath}.ts`,
|
|
14887
14928
|
`${basePath}.mjs`,
|
|
14888
14929
|
`${basePath}.cjs`,
|
|
14889
|
-
|
|
14890
|
-
|
|
14891
|
-
|
|
14892
|
-
|
|
14930
|
+
join16(basePath, "index.js"),
|
|
14931
|
+
join16(basePath, "index.ts"),
|
|
14932
|
+
join16(basePath, "index.mjs"),
|
|
14933
|
+
join16(basePath, "index.cjs")
|
|
14893
14934
|
];
|
|
14894
14935
|
for (const candidate of candidates) {
|
|
14895
|
-
if (
|
|
14936
|
+
if (existsSync5(candidate) && statSync2(candidate).isFile())
|
|
14896
14937
|
return candidate;
|
|
14897
14938
|
}
|
|
14898
14939
|
if (options.allowJavaScriptExtensionFallback && basePath.endsWith(".js")) {
|
|
14899
14940
|
const tsPath = `${basePath.slice(0, -".js".length)}.ts`;
|
|
14900
|
-
if (
|
|
14941
|
+
if (existsSync5(tsPath) && statSync2(tsPath).isFile())
|
|
14901
14942
|
return tsPath;
|
|
14902
14943
|
}
|
|
14903
14944
|
return null;
|
|
@@ -14928,9 +14969,9 @@ var init_resolve_type_property = __esm({
|
|
|
14928
14969
|
|
|
14929
14970
|
// packages/experience-design-system-extraction/dist/src/extract/vue.js
|
|
14930
14971
|
import os from "node:os";
|
|
14931
|
-
import { basename as basename3, dirname as dirname8, resolve as resolve14, join as
|
|
14972
|
+
import { basename as basename3, dirname as dirname8, resolve as resolve14, join as join17 } from "node:path";
|
|
14932
14973
|
import { readFile as readFile15 } from "node:fs/promises";
|
|
14933
|
-
import { existsSync as
|
|
14974
|
+
import { existsSync as existsSync6, readFileSync as readFileSync6, readdirSync as readdirSync3, statSync as statSync3 } from "node:fs";
|
|
14934
14975
|
import { parse as parseSFC } from "@vue/compiler-sfc";
|
|
14935
14976
|
import { Project as Project3, Node as Node6 } from "ts-morph";
|
|
14936
14977
|
async function extractVueComponents(filePaths, onProgress) {
|
|
@@ -15143,11 +15184,11 @@ function findWorkspaceRoot(startDir) {
|
|
|
15143
15184
|
return workspaceRootCache.get(startDir);
|
|
15144
15185
|
let dir = startDir;
|
|
15145
15186
|
while (true) {
|
|
15146
|
-
const pkgJsonPath =
|
|
15147
|
-
if (
|
|
15187
|
+
const pkgJsonPath = join17(dir, "package.json");
|
|
15188
|
+
if (existsSync6(pkgJsonPath)) {
|
|
15148
15189
|
try {
|
|
15149
15190
|
const pkg4 = JSON.parse(readFileSync6(pkgJsonPath, "utf8"));
|
|
15150
|
-
if (pkg4.workspaces ||
|
|
15191
|
+
if (pkg4.workspaces || existsSync6(join17(dir, "pnpm-workspace.yaml"))) {
|
|
15151
15192
|
workspaceRootCache.set(startDir, dir);
|
|
15152
15193
|
return dir;
|
|
15153
15194
|
}
|
|
@@ -15167,8 +15208,8 @@ function getWorkspacePackageDirs(workspaceRoot) {
|
|
|
15167
15208
|
return workspacePackageDirsCache.get(workspaceRoot);
|
|
15168
15209
|
}
|
|
15169
15210
|
const packageMap = /* @__PURE__ */ new Map();
|
|
15170
|
-
const packagesDir =
|
|
15171
|
-
if (!
|
|
15211
|
+
const packagesDir = join17(workspaceRoot, "packages");
|
|
15212
|
+
if (!existsSync6(packagesDir)) {
|
|
15172
15213
|
workspacePackageDirsCache.set(workspaceRoot, packageMap);
|
|
15173
15214
|
return packageMap;
|
|
15174
15215
|
}
|
|
@@ -15177,12 +15218,12 @@ function getWorkspacePackageDirs(workspaceRoot) {
|
|
|
15177
15218
|
return;
|
|
15178
15219
|
let entries;
|
|
15179
15220
|
try {
|
|
15180
|
-
entries =
|
|
15221
|
+
entries = readdirSync3(dir);
|
|
15181
15222
|
} catch {
|
|
15182
15223
|
return;
|
|
15183
15224
|
}
|
|
15184
|
-
const pkgJsonPath =
|
|
15185
|
-
if (
|
|
15225
|
+
const pkgJsonPath = join17(dir, "package.json");
|
|
15226
|
+
if (existsSync6(pkgJsonPath)) {
|
|
15186
15227
|
try {
|
|
15187
15228
|
const pkg4 = JSON.parse(readFileSync6(pkgJsonPath, "utf8"));
|
|
15188
15229
|
if (typeof pkg4.name === "string") {
|
|
@@ -15194,7 +15235,7 @@ function getWorkspacePackageDirs(workspaceRoot) {
|
|
|
15194
15235
|
for (const entry of entries) {
|
|
15195
15236
|
if (entry === "node_modules" || entry === ".git" || entry.startsWith("."))
|
|
15196
15237
|
continue;
|
|
15197
|
-
const entryPath =
|
|
15238
|
+
const entryPath = join17(dir, entry);
|
|
15198
15239
|
try {
|
|
15199
15240
|
const stat7 = statSync3(entryPath);
|
|
15200
15241
|
if (stat7.isDirectory()) {
|
|
@@ -15234,28 +15275,28 @@ function resolveWorkspaceVueImport(specifier, importingFilePath) {
|
|
|
15234
15275
|
const packageDir = packageDirs.get(packageName);
|
|
15235
15276
|
if (!packageDir)
|
|
15236
15277
|
return null;
|
|
15237
|
-
const pkgJsonPath =
|
|
15278
|
+
const pkgJsonPath = join17(packageDir, "package.json");
|
|
15238
15279
|
try {
|
|
15239
15280
|
const pkg4 = JSON.parse(readFileSync6(pkgJsonPath, "utf8"));
|
|
15240
15281
|
if (pkg4.exports && subpath !== ".") {
|
|
15241
15282
|
const exportValue = pkg4.exports[subpath];
|
|
15242
15283
|
if (typeof exportValue === "string" && exportValue.endsWith(".vue")) {
|
|
15243
15284
|
const resolved = resolve14(packageDir, exportValue);
|
|
15244
|
-
if (
|
|
15285
|
+
if (existsSync6(resolved))
|
|
15245
15286
|
return resolved;
|
|
15246
15287
|
}
|
|
15247
15288
|
}
|
|
15248
15289
|
if (subpath !== ".") {
|
|
15249
15290
|
const subDir = resolve14(packageDir, subpath.replace(/^\.\//, ""));
|
|
15250
|
-
for (const base of [
|
|
15251
|
-
const subPkgPath =
|
|
15252
|
-
if (
|
|
15291
|
+
for (const base of [join17(packageDir, "src", subpath.replace(/^\.\//, "")), subDir]) {
|
|
15292
|
+
const subPkgPath = join17(base, "package.json");
|
|
15293
|
+
if (existsSync6(subPkgPath)) {
|
|
15253
15294
|
try {
|
|
15254
15295
|
const subPkg = JSON.parse(readFileSync6(subPkgPath, "utf8"));
|
|
15255
15296
|
const main = subPkg.main || subPkg.module;
|
|
15256
15297
|
if (typeof main === "string" && main.endsWith(".vue")) {
|
|
15257
15298
|
const resolved = resolve14(base, main);
|
|
15258
|
-
if (
|
|
15299
|
+
if (existsSync6(resolved))
|
|
15259
15300
|
return resolved;
|
|
15260
15301
|
}
|
|
15261
15302
|
} catch {
|
|
@@ -15267,7 +15308,7 @@ function resolveWorkspaceVueImport(specifier, importingFilePath) {
|
|
|
15267
15308
|
const main = pkg4.main || pkg4.module;
|
|
15268
15309
|
if (typeof main === "string" && main.endsWith(".vue")) {
|
|
15269
15310
|
const resolved = resolve14(packageDir, main);
|
|
15270
|
-
if (
|
|
15311
|
+
if (existsSync6(resolved))
|
|
15271
15312
|
return resolved;
|
|
15272
15313
|
}
|
|
15273
15314
|
}
|
|
@@ -15709,7 +15750,7 @@ var init_astro = __esm({
|
|
|
15709
15750
|
});
|
|
15710
15751
|
|
|
15711
15752
|
// packages/experience-design-system-extraction/dist/src/extract/web-components.js
|
|
15712
|
-
import { basename as basename5, dirname as dirname9, join as
|
|
15753
|
+
import { basename as basename5, dirname as dirname9, join as join18, resolve as resolve15 } from "node:path";
|
|
15713
15754
|
import { Project as Project5, Node as Node8, SyntaxKind as SyntaxKind6 } from "ts-morph";
|
|
15714
15755
|
function normalizeComponentName(input) {
|
|
15715
15756
|
return input.replace(/[^a-zA-Z0-9]/g, "").toLowerCase();
|
|
@@ -16362,14 +16403,14 @@ function resolveImportSourcePath2(fromFilePath, specifier) {
|
|
|
16362
16403
|
if (!specifier.startsWith(spectrumPrefix)) {
|
|
16363
16404
|
return null;
|
|
16364
16405
|
}
|
|
16365
|
-
const packagesMarker = `${
|
|
16406
|
+
const packagesMarker = `${join18("2nd-gen", "packages")}${fromFilePath.includes("\\") ? "\\" : "/"}`;
|
|
16366
16407
|
const markerIndex = fromFilePath.lastIndexOf(packagesMarker);
|
|
16367
16408
|
if (markerIndex === -1) {
|
|
16368
16409
|
return null;
|
|
16369
16410
|
}
|
|
16370
16411
|
const packagesRoot = fromFilePath.slice(0, markerIndex + packagesMarker.length - 1);
|
|
16371
16412
|
const componentPath = specifier.slice(spectrumPrefix.length);
|
|
16372
|
-
return
|
|
16413
|
+
return join18(packagesRoot, "core", "components", componentPath, "index.ts");
|
|
16373
16414
|
}
|
|
16374
16415
|
function getImportedBaseClass(classDecl, project, visitedFiles) {
|
|
16375
16416
|
const extendsClause = classDecl.getHeritageClauses().find((clause) => clause.getToken() === SyntaxKind6.ExtendsKeyword);
|
|
@@ -16636,8 +16677,8 @@ var init_scoring = __esm({
|
|
|
16636
16677
|
|
|
16637
16678
|
// packages/experience-design-system-extraction/dist/src/extract/svelte.js
|
|
16638
16679
|
import os3 from "node:os";
|
|
16639
|
-
import { basename as basename6, dirname as dirname10, resolve as resolve16, join as
|
|
16640
|
-
import { existsSync as
|
|
16680
|
+
import { basename as basename6, dirname as dirname10, resolve as resolve16, join as join19 } from "node:path";
|
|
16681
|
+
import { existsSync as existsSync7, readFileSync as readFileSync7 } from "node:fs";
|
|
16641
16682
|
import { createRequire } from "node:module";
|
|
16642
16683
|
import { parse as parseSvelte } from "svelte/compiler";
|
|
16643
16684
|
import { Project as Project6, Node as Node9, ScriptTarget, ModuleKind, ts as ts2 } from "ts-morph";
|
|
@@ -16770,8 +16811,8 @@ async function maybeRunResolveUnreachableRetry(components, warnings, retryContex
|
|
|
16770
16811
|
function findNearestTsconfig(startDir) {
|
|
16771
16812
|
let dir = startDir;
|
|
16772
16813
|
for (let i = 0; i < 16; i++) {
|
|
16773
|
-
const candidate =
|
|
16774
|
-
if (
|
|
16814
|
+
const candidate = join19(dir, "tsconfig.json");
|
|
16815
|
+
if (existsSync7(candidate))
|
|
16775
16816
|
return candidate;
|
|
16776
16817
|
const parent = dirname10(dir);
|
|
16777
16818
|
if (!parent || parent === dir)
|
|
@@ -16906,29 +16947,29 @@ function locateDtsForSpecifier(req, specifier, parentFile) {
|
|
|
16906
16947
|
const seedDir = resolvedJs ? dirname10(resolvedJs) : dirname10(parentFile);
|
|
16907
16948
|
const pkgRoot = findPackageRootForSpecifier(seedDir, specifier);
|
|
16908
16949
|
if (pkgRoot) {
|
|
16909
|
-
const pkgJsonPath =
|
|
16910
|
-
if (
|
|
16950
|
+
const pkgJsonPath = join19(pkgRoot, "package.json");
|
|
16951
|
+
if (existsSync7(pkgJsonPath)) {
|
|
16911
16952
|
try {
|
|
16912
16953
|
const pkgRaw = readFileSync7(pkgJsonPath, "utf-8");
|
|
16913
16954
|
const pkg4 = JSON.parse(pkgRaw);
|
|
16914
16955
|
const typesField = pkg4.types ?? pkg4.typings;
|
|
16915
16956
|
if (typeof typesField === "string") {
|
|
16916
16957
|
const candidate = resolve16(pkgRoot, typesField);
|
|
16917
|
-
if (
|
|
16958
|
+
if (existsSync7(candidate))
|
|
16918
16959
|
return candidate;
|
|
16919
16960
|
}
|
|
16920
16961
|
const exportsTypes = extractTypesFromExports(pkg4.exports);
|
|
16921
16962
|
if (exportsTypes) {
|
|
16922
16963
|
const candidate = resolve16(pkgRoot, exportsTypes);
|
|
16923
|
-
if (
|
|
16964
|
+
if (existsSync7(candidate))
|
|
16924
16965
|
return candidate;
|
|
16925
16966
|
}
|
|
16926
16967
|
} catch {
|
|
16927
16968
|
}
|
|
16928
16969
|
}
|
|
16929
16970
|
for (const entry of ["index.d.ts", "index.d.mts"]) {
|
|
16930
|
-
const candidate =
|
|
16931
|
-
if (
|
|
16971
|
+
const candidate = join19(pkgRoot, entry);
|
|
16972
|
+
if (existsSync7(candidate))
|
|
16932
16973
|
return candidate;
|
|
16933
16974
|
}
|
|
16934
16975
|
}
|
|
@@ -16936,7 +16977,7 @@ function locateDtsForSpecifier(req, specifier, parentFile) {
|
|
|
16936
16977
|
const noExt = resolvedJs.replace(/\.(m?js|cjs)$/, "");
|
|
16937
16978
|
for (const ext of [".d.ts", ".d.mts"]) {
|
|
16938
16979
|
const candidate = `${noExt}${ext}`;
|
|
16939
|
-
if (
|
|
16980
|
+
if (existsSync7(candidate))
|
|
16940
16981
|
return candidate;
|
|
16941
16982
|
}
|
|
16942
16983
|
}
|
|
@@ -16945,9 +16986,9 @@ function locateDtsForSpecifier(req, specifier, parentFile) {
|
|
|
16945
16986
|
function findPackageRootForSpecifier(seedDir, specifier) {
|
|
16946
16987
|
let dir = seedDir;
|
|
16947
16988
|
for (let i = 0; i < 32; i++) {
|
|
16948
|
-
if (
|
|
16989
|
+
if (existsSync7(join19(dir, "package.json"))) {
|
|
16949
16990
|
try {
|
|
16950
|
-
const pkgRaw = readFileSync7(
|
|
16991
|
+
const pkgRaw = readFileSync7(join19(dir, "package.json"), "utf-8");
|
|
16951
16992
|
const pkg4 = JSON.parse(pkgRaw);
|
|
16952
16993
|
if (pkg4.name === specifier)
|
|
16953
16994
|
return dir;
|
|
@@ -18919,9 +18960,9 @@ var init_wizard_generate_progress = __esm({
|
|
|
18919
18960
|
});
|
|
18920
18961
|
|
|
18921
18962
|
// packages/experience-design-system-cli-legacy/src/import/tui/spawn-generate.ts
|
|
18922
|
-
import { spawn as
|
|
18963
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
18923
18964
|
function spawnGenerateChild(opts) {
|
|
18924
|
-
const child =
|
|
18965
|
+
const child = spawn2(opts.command, opts.args);
|
|
18925
18966
|
let stdout = "";
|
|
18926
18967
|
let stderr = "";
|
|
18927
18968
|
child.stdout?.on("data", (d) => {
|
|
@@ -18960,6 +19001,88 @@ var init_spawn_generate = __esm({
|
|
|
18960
19001
|
}
|
|
18961
19002
|
});
|
|
18962
19003
|
|
|
19004
|
+
// packages/experience-design-system-cli-legacy/src/apply/dangling-token-defaults.ts
|
|
19005
|
+
import { parseCDFComponents as parseCDFComponents3 } from "@contentful/experience-design-system-types";
|
|
19006
|
+
function isRecord(value) {
|
|
19007
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
19008
|
+
}
|
|
19009
|
+
function dropDanglingTokenDefaults(cdf, existingTokenIds) {
|
|
19010
|
+
const known = new Set(existingTokenIds);
|
|
19011
|
+
for (const { path } of parseCDFComponents3(cdf).tokens) known.add(path);
|
|
19012
|
+
const copy = structuredClone(cdf);
|
|
19013
|
+
const dropped = [];
|
|
19014
|
+
const walk = (node, prefix) => {
|
|
19015
|
+
for (const [key, value] of Object.entries(node)) {
|
|
19016
|
+
if (key.startsWith("$") || !isRecord(value)) continue;
|
|
19017
|
+
const path = prefix ? `${prefix}.${key}` : key;
|
|
19018
|
+
const properties = value["$properties"];
|
|
19019
|
+
if (value["$type"] === "component" && isRecord(properties)) {
|
|
19020
|
+
for (const [name, property] of Object.entries(properties)) {
|
|
19021
|
+
if (!isRecord(property) || property["$type"] !== "token") continue;
|
|
19022
|
+
const reference = property["$default"];
|
|
19023
|
+
if (typeof reference === "string" && reference !== "" && !known.has(reference)) {
|
|
19024
|
+
delete property["$default"];
|
|
19025
|
+
dropped.push({ component: path, property: name, token: reference });
|
|
19026
|
+
}
|
|
19027
|
+
}
|
|
19028
|
+
} else {
|
|
19029
|
+
walk(value, path);
|
|
19030
|
+
}
|
|
19031
|
+
}
|
|
19032
|
+
};
|
|
19033
|
+
walk(copy, "");
|
|
19034
|
+
return { cdf: copy, dropped };
|
|
19035
|
+
}
|
|
19036
|
+
function describeDroppedTokenDefaults(dropped) {
|
|
19037
|
+
return dropped.map(
|
|
19038
|
+
({ component, property, token }) => `${component}.${property}: default "${token}" left out \u2014 that design token does not exist in this environment`
|
|
19039
|
+
);
|
|
19040
|
+
}
|
|
19041
|
+
var init_dangling_token_defaults = __esm({
|
|
19042
|
+
"packages/experience-design-system-cli-legacy/src/apply/dangling-token-defaults.ts"() {
|
|
19043
|
+
"use strict";
|
|
19044
|
+
}
|
|
19045
|
+
});
|
|
19046
|
+
|
|
19047
|
+
// packages/experience-design-system-cli-legacy/src/helpers/build-contentful-management-client.ts
|
|
19048
|
+
import { createClient as createClient2 } from "contentful-management";
|
|
19049
|
+
function buildContentfulManagementClient(opts) {
|
|
19050
|
+
return createClient2(
|
|
19051
|
+
{
|
|
19052
|
+
accessToken: opts.cmaToken,
|
|
19053
|
+
...opts.host ? { host: toConfiguredHost(opts.host) } : {}
|
|
19054
|
+
},
|
|
19055
|
+
{ type: "plain" }
|
|
19056
|
+
);
|
|
19057
|
+
}
|
|
19058
|
+
var init_build_contentful_management_client = __esm({
|
|
19059
|
+
"packages/experience-design-system-cli-legacy/src/helpers/build-contentful-management-client.ts"() {
|
|
19060
|
+
"use strict";
|
|
19061
|
+
init_host_utils();
|
|
19062
|
+
}
|
|
19063
|
+
});
|
|
19064
|
+
|
|
19065
|
+
// packages/experience-design-system-cli-legacy/src/helpers/fetch-existing-token-ids.ts
|
|
19066
|
+
import { fetchAll } from "contentful-management";
|
|
19067
|
+
async function fetchExistingTokenIds(params) {
|
|
19068
|
+
const client2 = buildContentfulManagementClient({
|
|
19069
|
+
cmaToken: params.cmaToken,
|
|
19070
|
+
...params.host ? { host: params.host } : {}
|
|
19071
|
+
});
|
|
19072
|
+
const tokens = await fetchAll(client2.designToken.getMany, {
|
|
19073
|
+
spaceId: params.spaceId,
|
|
19074
|
+
environmentId: params.environmentId,
|
|
19075
|
+
query: { cursor: true, limit: 1e3 }
|
|
19076
|
+
});
|
|
19077
|
+
return new Set(tokens.map((token) => token.sys.id));
|
|
19078
|
+
}
|
|
19079
|
+
var init_fetch_existing_token_ids = __esm({
|
|
19080
|
+
"packages/experience-design-system-cli-legacy/src/helpers/fetch-existing-token-ids.ts"() {
|
|
19081
|
+
"use strict";
|
|
19082
|
+
init_build_contentful_management_client();
|
|
19083
|
+
}
|
|
19084
|
+
});
|
|
19085
|
+
|
|
18963
19086
|
// packages/experience-design-system-cli-legacy/src/analyze/composite-closure.ts
|
|
18964
19087
|
function edgesFrom(component, known) {
|
|
18965
19088
|
if (!component) return [];
|
|
@@ -20301,17 +20424,17 @@ function buildCycleUnits(slotCycles) {
|
|
|
20301
20424
|
const groups = /* @__PURE__ */ new Map();
|
|
20302
20425
|
for (const node of parent.keys()) {
|
|
20303
20426
|
const root = find(node);
|
|
20304
|
-
let
|
|
20305
|
-
if (!
|
|
20306
|
-
|
|
20307
|
-
groups.set(root,
|
|
20427
|
+
let group2 = groups.get(root);
|
|
20428
|
+
if (!group2) {
|
|
20429
|
+
group2 = /* @__PURE__ */ new Set();
|
|
20430
|
+
groups.set(root, group2);
|
|
20308
20431
|
}
|
|
20309
|
-
|
|
20432
|
+
group2.add(node);
|
|
20310
20433
|
}
|
|
20311
20434
|
const out = /* @__PURE__ */ new Map();
|
|
20312
|
-
for (const
|
|
20313
|
-
for (const node of
|
|
20314
|
-
out.set(node,
|
|
20435
|
+
for (const group2 of groups.values()) {
|
|
20436
|
+
for (const node of group2) {
|
|
20437
|
+
out.set(node, group2);
|
|
20315
20438
|
}
|
|
20316
20439
|
}
|
|
20317
20440
|
return out;
|
|
@@ -21805,10 +21928,10 @@ function swapValues(values, firstIndex, secondIndex) {
|
|
|
21805
21928
|
[next[firstIndex], next[secondIndex]] = [next[secondIndex], next[firstIndex]];
|
|
21806
21929
|
return next;
|
|
21807
21930
|
}
|
|
21808
|
-
function parseToState(
|
|
21931
|
+
function parseToState(json2) {
|
|
21809
21932
|
let parsed;
|
|
21810
21933
|
try {
|
|
21811
|
-
parsed = JSON.parse(
|
|
21934
|
+
parsed = JSON.parse(json2);
|
|
21812
21935
|
} catch (e) {
|
|
21813
21936
|
return {
|
|
21814
21937
|
state: { componentDescription: "", props: [], slots: [] },
|
|
@@ -22661,11 +22784,11 @@ function FieldEditor({
|
|
|
22661
22784
|
setEditorState(next);
|
|
22662
22785
|
onChange(serializeState(next, value));
|
|
22663
22786
|
};
|
|
22664
|
-
const canonicalize = React14.useCallback((
|
|
22787
|
+
const canonicalize = React14.useCallback((json2) => {
|
|
22665
22788
|
try {
|
|
22666
|
-
return JSON.stringify(JSON.parse(
|
|
22789
|
+
return JSON.stringify(JSON.parse(json2));
|
|
22667
22790
|
} catch {
|
|
22668
|
-
return `__unparseable__:${
|
|
22791
|
+
return `__unparseable__:${json2}`;
|
|
22669
22792
|
}
|
|
22670
22793
|
}, []);
|
|
22671
22794
|
const initialStateRef = React14.useRef(initialState);
|
|
@@ -23239,14 +23362,14 @@ function FieldEditor({
|
|
|
23239
23362
|
})();
|
|
23240
23363
|
const rows = [];
|
|
23241
23364
|
rows.push({ kind: "component-description" });
|
|
23242
|
-
for (const
|
|
23243
|
-
if (
|
|
23365
|
+
for (const group2 of propGroups.filter((candidate) => candidate.kind !== "hidden")) {
|
|
23366
|
+
if (group2.indexes.length === 0) continue;
|
|
23244
23367
|
rows.push({
|
|
23245
23368
|
kind: "header",
|
|
23246
|
-
label: `${
|
|
23247
|
-
section:
|
|
23369
|
+
label: `${group2.label} (${group2.indexes.length}) `,
|
|
23370
|
+
section: group2.kind
|
|
23248
23371
|
});
|
|
23249
|
-
|
|
23372
|
+
group2.indexes.forEach((idx) => rows.push({ kind: "prop", idx }));
|
|
23250
23373
|
}
|
|
23251
23374
|
if (slots.length > 0) {
|
|
23252
23375
|
rows.push({
|
|
@@ -23256,7 +23379,7 @@ function FieldEditor({
|
|
|
23256
23379
|
});
|
|
23257
23380
|
slots.forEach((_, i) => rows.push({ kind: "slot", idx: i }));
|
|
23258
23381
|
}
|
|
23259
|
-
const hiddenGroup = propGroups.find((
|
|
23382
|
+
const hiddenGroup = propGroups.find((group2) => group2.kind === "hidden");
|
|
23260
23383
|
if (hiddenGroup && hiddenGroup.indexes.length > 0) {
|
|
23261
23384
|
rows.push({
|
|
23262
23385
|
kind: "header",
|
|
@@ -26998,26 +27121,8 @@ var init_runScopeGate = __esm({
|
|
|
26998
27121
|
}
|
|
26999
27122
|
});
|
|
27000
27123
|
|
|
27001
|
-
// packages/experience-design-system-cli-legacy/src/helpers/build-contentful-management-client.ts
|
|
27002
|
-
import { createClient as createClient2 } from "contentful-management";
|
|
27003
|
-
function buildContentfulManagementClient(opts) {
|
|
27004
|
-
return createClient2(
|
|
27005
|
-
{
|
|
27006
|
-
accessToken: opts.cmaToken,
|
|
27007
|
-
...opts.host ? { host: toConfiguredHost(opts.host) } : {}
|
|
27008
|
-
},
|
|
27009
|
-
{ type: "plain" }
|
|
27010
|
-
);
|
|
27011
|
-
}
|
|
27012
|
-
var init_build_contentful_management_client = __esm({
|
|
27013
|
-
"packages/experience-design-system-cli-legacy/src/helpers/build-contentful-management-client.ts"() {
|
|
27014
|
-
"use strict";
|
|
27015
|
-
init_host_utils();
|
|
27016
|
-
}
|
|
27017
|
-
});
|
|
27018
|
-
|
|
27019
27124
|
// packages/experience-design-system-cli-legacy/src/helpers/fetch-existing-contentful-entities.ts
|
|
27020
|
-
import { fetchAll } from "contentful-management";
|
|
27125
|
+
import { fetchAll as fetchAll2 } from "contentful-management";
|
|
27021
27126
|
async function fetchExistingContentfulEntitiesFromContentful(client2, params) {
|
|
27022
27127
|
const componentScope = {
|
|
27023
27128
|
spaceId: params.spaceId,
|
|
@@ -27029,8 +27134,8 @@ async function fetchExistingContentfulEntitiesFromContentful(client2, params) {
|
|
|
27029
27134
|
environmentId: params.environmentId,
|
|
27030
27135
|
query: { cursor: true, limit: 1e3 }
|
|
27031
27136
|
};
|
|
27032
|
-
const components = await
|
|
27033
|
-
const tokens = await
|
|
27137
|
+
const components = await fetchAll2(client2.component.getMany, componentScope);
|
|
27138
|
+
const tokens = await fetchAll2(client2.designToken.getMany, tokenScope);
|
|
27034
27139
|
return { components, tokens };
|
|
27035
27140
|
}
|
|
27036
27141
|
var init_fetch_existing_contentful_entities = __esm({
|
|
@@ -27041,7 +27146,7 @@ var init_fetch_existing_contentful_entities = __esm({
|
|
|
27041
27146
|
|
|
27042
27147
|
// packages/experience-design-system-cli-legacy/src/helpers/fetch-and-persist-existing-contentful-entities.ts
|
|
27043
27148
|
import { writeFile as writeFile5 } from "node:fs/promises";
|
|
27044
|
-
import { join as
|
|
27149
|
+
import { join as join20 } from "node:path";
|
|
27045
27150
|
async function fetchAndPersistExistingContentfulEntities(params) {
|
|
27046
27151
|
const t0 = Date.now();
|
|
27047
27152
|
try {
|
|
@@ -27053,7 +27158,7 @@ async function fetchAndPersistExistingContentfulEntities(params) {
|
|
|
27053
27158
|
spaceId: params.spaceId,
|
|
27054
27159
|
environmentId: params.environmentId
|
|
27055
27160
|
});
|
|
27056
|
-
const path =
|
|
27161
|
+
const path = join20(params.outDir, ".existing-entities.json");
|
|
27057
27162
|
await writeFile5(path, JSON.stringify(entities, null, 2), "utf8");
|
|
27058
27163
|
return { ok: true, path, durationMs: Date.now() - t0, entities };
|
|
27059
27164
|
} catch (error) {
|
|
@@ -27230,11 +27335,11 @@ __export(WizardApp_exports, {
|
|
|
27230
27335
|
});
|
|
27231
27336
|
import { useEffect as useEffect15, useRef as useRef10, useState as useState23 } from "react";
|
|
27232
27337
|
import { Box as Box42, Text as Text46 } from "ink";
|
|
27233
|
-
import { join as
|
|
27234
|
-
import { appendFileSync as appendFileSync2, writeFileSync } from "node:fs";
|
|
27338
|
+
import { join as join21, resolve as resolve17 } from "node:path";
|
|
27339
|
+
import { appendFileSync as appendFileSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
27235
27340
|
import { access as access7, stat as stat5, writeFile as writeFile6 } from "node:fs/promises";
|
|
27236
27341
|
import { tmpdir } from "node:os";
|
|
27237
|
-
import { execFile as execFile2, spawn as
|
|
27342
|
+
import { execFile as execFile2, spawn as spawn3 } from "node:child_process";
|
|
27238
27343
|
import { mkdir as mkdir5 } from "node:fs/promises";
|
|
27239
27344
|
import { buildCDF as buildCDF3, validateCDF as validateCDF3, validateSlotReferences as validateSlotReferences2 } from "@contentful/experience-design-system-types";
|
|
27240
27345
|
import { jsx as jsx50, jsxs as jsxs43 } from "react/jsx-runtime";
|
|
@@ -27296,7 +27401,7 @@ function runCli(args) {
|
|
|
27296
27401
|
}
|
|
27297
27402
|
function runSpawnedCli(args, onStderr, onStdout) {
|
|
27298
27403
|
return new Promise((res) => {
|
|
27299
|
-
const child =
|
|
27404
|
+
const child = spawn3("node", args);
|
|
27300
27405
|
let stdout = "";
|
|
27301
27406
|
let stderr = "";
|
|
27302
27407
|
child.stdout.on("data", (d) => {
|
|
@@ -27371,7 +27476,7 @@ function WizardApp({
|
|
|
27371
27476
|
const logInit = useRef10(false);
|
|
27372
27477
|
const initialAgentAuthRef = useRef10(initialAgentAuth ?? null);
|
|
27373
27478
|
if (!logInit.current) {
|
|
27374
|
-
|
|
27479
|
+
writeFileSync2(WIZARD_LOG, `--- experiences import session ${(/* @__PURE__ */ new Date()).toISOString()} ---
|
|
27375
27480
|
`);
|
|
27376
27481
|
logInit.current = true;
|
|
27377
27482
|
}
|
|
@@ -27380,6 +27485,7 @@ function WizardApp({
|
|
|
27380
27485
|
tokensPath: ""
|
|
27381
27486
|
});
|
|
27382
27487
|
const allowEmptyDeleteAllRef = useRef10(false);
|
|
27488
|
+
const pushDebugRef = useRef10(null);
|
|
27383
27489
|
const generateChildRef = useRef10(null);
|
|
27384
27490
|
const generationCachePreflightRef = useRef10(null);
|
|
27385
27491
|
const selectionToReviewStartedAtRef = useRef10(null);
|
|
@@ -27398,7 +27504,7 @@ function WizardApp({
|
|
|
27398
27504
|
const rawTokensEntryReady = !!initialRawTokensPath;
|
|
27399
27505
|
const effectiveNoCache = resolveNoCacheForGenerate({ cliNoCache: noCache });
|
|
27400
27506
|
const initialStepResolved = rawTokensEntryReady ? initialProjectPath ? "path-validation" : "credentials" : initialProjectPath ? "token-input" : "welcome";
|
|
27401
|
-
const initialOutDir = initialProjectPath ?
|
|
27507
|
+
const initialOutDir = initialProjectPath ? join21(resolve17(initialProjectPath), ".contentful") : "";
|
|
27402
27508
|
const [state, setState] = useState23({
|
|
27403
27509
|
step: initialStepResolved,
|
|
27404
27510
|
agent: initialAgent ?? "claude",
|
|
@@ -27454,6 +27560,7 @@ function WizardApp({
|
|
|
27454
27560
|
existingEntitiesStatus: "idle",
|
|
27455
27561
|
lastRunId: null,
|
|
27456
27562
|
finalizeErrorBanner: null,
|
|
27563
|
+
droppedTokenDefaults: [],
|
|
27457
27564
|
finalReviewPassed: false
|
|
27458
27565
|
});
|
|
27459
27566
|
useEffect15(() => {
|
|
@@ -27596,7 +27703,7 @@ If you are using AWS Bedrock, run:
|
|
|
27596
27703
|
}
|
|
27597
27704
|
const sessionMatch = /^session=(.+)$/m.exec(result.stdout);
|
|
27598
27705
|
const tokenSessionId = sessionMatch ? sessionMatch[1].trim() : null;
|
|
27599
|
-
const tokensPath =
|
|
27706
|
+
const tokensPath = join21(outDir, "tokens.json");
|
|
27600
27707
|
const printArgs = ["print", "tokens", "--out", tokensPath];
|
|
27601
27708
|
if (tokenSessionId) printArgs.push("--session", tokenSessionId);
|
|
27602
27709
|
const r = await runCli(printArgs);
|
|
@@ -27618,7 +27725,7 @@ If you are using AWS Bedrock, run:
|
|
|
27618
27725
|
tokenGenerationStatus: "complete",
|
|
27619
27726
|
skipComponents: true,
|
|
27620
27727
|
acceptedCount: 0,
|
|
27621
|
-
outDir: state.outDir ||
|
|
27728
|
+
outDir: state.outDir || join21(process.cwd(), ".contentful")
|
|
27622
27729
|
});
|
|
27623
27730
|
update({ step: "credentials" });
|
|
27624
27731
|
return true;
|
|
@@ -27759,7 +27866,7 @@ If you are using AWS Bedrock, run:
|
|
|
27759
27866
|
return promise;
|
|
27760
27867
|
};
|
|
27761
27868
|
const runExtract = async (projectPath, showProgress = true) => {
|
|
27762
|
-
const outDir =
|
|
27869
|
+
const outDir = join21(resolve17(projectPath), ".contentful");
|
|
27763
27870
|
const existingEntitiesExpected = !state.credentialsSkipped && Boolean(state.spaceId && state.environmentId && state.cmaToken && projectPath);
|
|
27764
27871
|
update({
|
|
27765
27872
|
...showProgress ? { step: "extracting" } : {},
|
|
@@ -28434,12 +28541,30 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
|
|
|
28434
28541
|
void runSaveAndPush();
|
|
28435
28542
|
};
|
|
28436
28543
|
const runPreview = async (extractSessionId, tokensPath, spaceId, environmentId, cmaToken, host2) => {
|
|
28544
|
+
const resolvedHost = resolveWizardHost(host2);
|
|
28545
|
+
pushDebugRef.current?.finish({
|
|
28546
|
+
outcome: "superseded",
|
|
28547
|
+
summary: "A new push attempt started before this one finished."
|
|
28548
|
+
});
|
|
28549
|
+
const pushDebug = startPushDebugRun({
|
|
28550
|
+
space_id: spaceId,
|
|
28551
|
+
environment_id: environmentId,
|
|
28552
|
+
host: resolvedHost,
|
|
28553
|
+
cma_token: cmaToken,
|
|
28554
|
+
extract_session_id: extractSessionId,
|
|
28555
|
+
tokens_file: tokensPath || null,
|
|
28556
|
+
delete_everything_not_listed: allowEmptyDeleteAllRef.current
|
|
28557
|
+
});
|
|
28558
|
+
pushDebugRef.current = pushDebug;
|
|
28437
28559
|
if (shouldBypassPreview(state)) {
|
|
28560
|
+
pushDebug.finish({
|
|
28561
|
+
outcome: "skipped",
|
|
28562
|
+
summary: "Credentials were skipped, so nothing is previewed or pushed. Files were saved only."
|
|
28563
|
+
});
|
|
28438
28564
|
update(buildSkippedPreviewTransition());
|
|
28439
28565
|
return;
|
|
28440
28566
|
}
|
|
28441
28567
|
update({ step: "previewing" });
|
|
28442
|
-
const resolvedHost = resolveWizardHost(host2);
|
|
28443
28568
|
try {
|
|
28444
28569
|
const client2 = new ImportApiClient({
|
|
28445
28570
|
cmaToken,
|
|
@@ -28447,6 +28572,7 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
|
|
|
28447
28572
|
environmentId,
|
|
28448
28573
|
host: resolvedHost
|
|
28449
28574
|
});
|
|
28575
|
+
pushDebug.event("Preview started", { note: `POST ${resolvedHost}/\u2026/design_systems/imports/preview` });
|
|
28450
28576
|
let components = [];
|
|
28451
28577
|
if (extractSessionId) {
|
|
28452
28578
|
const db = openPipelineDb();
|
|
@@ -28462,7 +28588,16 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
|
|
|
28462
28588
|
tokens = await readTokensFromPath("tokens", tokensPath);
|
|
28463
28589
|
}
|
|
28464
28590
|
let cdf = buildCDF3(components, toCDFTokens(tokens), { deleteAll: allowEmptyDeleteAllRef.current });
|
|
28591
|
+
pushDebug.event("Built the CDF to send", {
|
|
28592
|
+
note: `${summarizeCdf(cdf).length} entries`,
|
|
28593
|
+
data: { entries: summarizeCdf(cdf), tokens_loaded: tokens.length }
|
|
28594
|
+
});
|
|
28465
28595
|
let preview = await client2.previewImport(cdf);
|
|
28596
|
+
pushDebug.event("Server previewed the CDF", {
|
|
28597
|
+
note: "what the server would create, change, leave alone or remove",
|
|
28598
|
+
data: summarizePreview(preview),
|
|
28599
|
+
requestId: client2.getLastRequestId()
|
|
28600
|
+
});
|
|
28466
28601
|
if (extractSessionId) {
|
|
28467
28602
|
let needsRepreview = false;
|
|
28468
28603
|
const db = openPipelineDb();
|
|
@@ -28482,15 +28617,27 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
|
|
|
28482
28617
|
if (seededDefaults > 0) needsRepreview = true;
|
|
28483
28618
|
}
|
|
28484
28619
|
if (needsRepreview) {
|
|
28620
|
+
pushDebug.event("Re-previewing", {
|
|
28621
|
+
note: "the server listed components as removed or changed that exist locally, so defaults were filled in"
|
|
28622
|
+
});
|
|
28485
28623
|
components = loadCDFComponents(db, extractSessionId);
|
|
28486
28624
|
cdf = buildCDF3(components, toCDFTokens(tokens), { deleteAll: allowEmptyDeleteAllRef.current });
|
|
28487
28625
|
preview = await client2.previewImport(cdf);
|
|
28626
|
+
pushDebug.event("Server previewed the updated CDF", {
|
|
28627
|
+
data: summarizePreview(preview),
|
|
28628
|
+
requestId: client2.getLastRequestId()
|
|
28629
|
+
});
|
|
28488
28630
|
}
|
|
28489
28631
|
} finally {
|
|
28490
28632
|
db.close();
|
|
28491
28633
|
}
|
|
28492
28634
|
}
|
|
28493
28635
|
if (isEmptyPreview(preview)) {
|
|
28636
|
+
pushDebug.finish({
|
|
28637
|
+
outcome: "nothing-to-push",
|
|
28638
|
+
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.",
|
|
28639
|
+
details: { preview: summarizePreview(preview), request_id: client2.getLastRequestId() }
|
|
28640
|
+
});
|
|
28494
28641
|
update({
|
|
28495
28642
|
step: "done",
|
|
28496
28643
|
serverPreview: preview,
|
|
@@ -28502,14 +28649,44 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
|
|
|
28502
28649
|
});
|
|
28503
28650
|
return;
|
|
28504
28651
|
}
|
|
28652
|
+
let cdfToPush = cdf;
|
|
28653
|
+
let droppedTokenDefaults = [];
|
|
28654
|
+
try {
|
|
28655
|
+
const existingTokenIds = await fetchExistingTokenIds({
|
|
28656
|
+
spaceId,
|
|
28657
|
+
environmentId,
|
|
28658
|
+
cmaToken,
|
|
28659
|
+
...host2 ? { host: host2 } : {}
|
|
28660
|
+
});
|
|
28661
|
+
const checked = dropDanglingTokenDefaults(cdf, existingTokenIds);
|
|
28662
|
+
cdfToPush = checked.cdf;
|
|
28663
|
+
droppedTokenDefaults = describeDroppedTokenDefaults(checked.dropped);
|
|
28664
|
+
pushDebug.event("Checked token references", {
|
|
28665
|
+
note: checked.dropped.length === 0 ? `every token default exists (${existingTokenIds.size} tokens in this environment)` : `${checked.dropped.length} default(s) point at a token that does not exist and will be left out`,
|
|
28666
|
+
data: { tokens_in_environment: existingTokenIds.size, dropped: checked.dropped }
|
|
28667
|
+
});
|
|
28668
|
+
} catch (tokenCheckError) {
|
|
28669
|
+
pushDebug.event("Could not check token references", {
|
|
28670
|
+
note: tokenCheckError instanceof Error ? tokenCheckError.message : String(tokenCheckError)
|
|
28671
|
+
});
|
|
28672
|
+
}
|
|
28673
|
+
pushDebug.event("Waiting for confirmation", {
|
|
28674
|
+
note: "the preview shows changes, so the wizard asks before pushing"
|
|
28675
|
+
});
|
|
28505
28676
|
update({
|
|
28506
28677
|
step: "preview-gate",
|
|
28507
28678
|
serverPreview: preview,
|
|
28508
|
-
cdf,
|
|
28679
|
+
cdf: cdfToPush,
|
|
28680
|
+
droppedTokenDefaults,
|
|
28509
28681
|
finalizeErrorBanner: null,
|
|
28510
28682
|
...clearedValidationErrorState()
|
|
28511
28683
|
});
|
|
28512
28684
|
} catch (e) {
|
|
28685
|
+
pushDebug.finish({
|
|
28686
|
+
outcome: "preview-failed",
|
|
28687
|
+
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)}`,
|
|
28688
|
+
details: e instanceof ApiError ? { status: e.status, body: (e.body ?? "").slice(0, 4e3) } : { error: e instanceof Error ? e.message : String(e) }
|
|
28689
|
+
});
|
|
28513
28690
|
if (e instanceof ApiError) {
|
|
28514
28691
|
if (e.status === 401 || e.status === 403) {
|
|
28515
28692
|
let bodyMsg = "";
|
|
@@ -28572,7 +28749,18 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28572
28749
|
}
|
|
28573
28750
|
};
|
|
28574
28751
|
const runPush = async (cdf, spaceId, environmentId, cmaToken, host2, acknowledgeBreakingChanges, preview) => {
|
|
28752
|
+
const pushDebug = pushDebugRef.current ?? startPushDebugRun({
|
|
28753
|
+
space_id: spaceId,
|
|
28754
|
+
environment_id: environmentId,
|
|
28755
|
+
host: resolveWizardHost(host2),
|
|
28756
|
+
cma_token: cmaToken
|
|
28757
|
+
});
|
|
28758
|
+
pushDebugRef.current = pushDebug;
|
|
28575
28759
|
if (shouldRefusePush(state)) {
|
|
28760
|
+
pushDebug.finish({
|
|
28761
|
+
outcome: "skipped",
|
|
28762
|
+
summary: "Credentials were skipped, so the push was refused. Files were saved only."
|
|
28763
|
+
});
|
|
28576
28764
|
update(buildSkippedPushTransition());
|
|
28577
28765
|
return;
|
|
28578
28766
|
}
|
|
@@ -28580,6 +28768,11 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28580
28768
|
const hasComponentChanges = preview.components.new.length > 0 || preview.components.changed.length > 0 || preview.components.removed.length > 0;
|
|
28581
28769
|
const hasTokenChanges = preview.tokens.new.length > 0 || preview.tokens.changed.length > 0 || preview.tokens.removed.length > 0;
|
|
28582
28770
|
if (!hasComponentChanges && !hasTokenChanges) {
|
|
28771
|
+
pushDebug.finish({
|
|
28772
|
+
outcome: "nothing-to-push",
|
|
28773
|
+
summary: "The preview had no new, changed or removed items, so no apply request was sent.",
|
|
28774
|
+
details: { preview: summarizePreview(preview) }
|
|
28775
|
+
});
|
|
28583
28776
|
update({
|
|
28584
28777
|
step: "done",
|
|
28585
28778
|
pushResult: {
|
|
@@ -28592,6 +28785,11 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28592
28785
|
}
|
|
28593
28786
|
const cycles = detectSlotCycles(extractComponents(cdf));
|
|
28594
28787
|
if (cycles.length > 0) {
|
|
28788
|
+
pushDebug.finish({
|
|
28789
|
+
outcome: "failed",
|
|
28790
|
+
summary: "The push was blocked locally because components slot each other in a cycle.",
|
|
28791
|
+
details: { cycles: formatSlotCycleReport(cycles) }
|
|
28792
|
+
});
|
|
28595
28793
|
update({
|
|
28596
28794
|
step: "error",
|
|
28597
28795
|
errorStep: "apply",
|
|
@@ -28602,6 +28800,11 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28602
28800
|
}
|
|
28603
28801
|
const unresolvedSlotReferences = validateSlotReferences2(extractComponents(cdf));
|
|
28604
28802
|
if (unresolvedSlotReferences.length > 0) {
|
|
28803
|
+
pushDebug.finish({
|
|
28804
|
+
outcome: "failed",
|
|
28805
|
+
summary: "The push was blocked locally because a slot refers to a component that is not in the CDF.",
|
|
28806
|
+
details: { unresolved: formatUnresolvedSlotReferences(unresolvedSlotReferences) }
|
|
28807
|
+
});
|
|
28605
28808
|
update({
|
|
28606
28809
|
step: "error",
|
|
28607
28810
|
errorStep: "apply",
|
|
@@ -28611,6 +28814,14 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28611
28814
|
return;
|
|
28612
28815
|
}
|
|
28613
28816
|
update({ step: "pushing", pushProgress: null, errorAllowBreakingChangeAcknowledgment: false });
|
|
28817
|
+
pushDebug.event("Apply started", {
|
|
28818
|
+
note: `POST ${resolveWizardHost(host2)}/\u2026/design_systems/imports/apply`,
|
|
28819
|
+
data: {
|
|
28820
|
+
acknowledge_breaking_changes: acknowledgeBreakingChanges,
|
|
28821
|
+
sending: summarizeCdf(cdf),
|
|
28822
|
+
expected: preview ? summarizePreview(preview) : null
|
|
28823
|
+
}
|
|
28824
|
+
});
|
|
28614
28825
|
try {
|
|
28615
28826
|
const resolvedHost = resolveWizardHost(host2);
|
|
28616
28827
|
const client2 = new ImportApiClient({
|
|
@@ -28620,6 +28831,11 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28620
28831
|
host: resolvedHost
|
|
28621
28832
|
});
|
|
28622
28833
|
let operation = await client2.applyImport(cdf, { acknowledgeBreakingChanges });
|
|
28834
|
+
pushDebug.event("Server accepted the apply request", {
|
|
28835
|
+
note: `operation ${operation.sys.id} is ${operation.sys.status}`,
|
|
28836
|
+
data: { operation_id: operation.sys.id, status: operation.sys.status, summary: operation.summary },
|
|
28837
|
+
requestId: client2.getLastRequestId()
|
|
28838
|
+
});
|
|
28623
28839
|
try {
|
|
28624
28840
|
logStep({
|
|
28625
28841
|
applyResponse: {
|
|
@@ -28636,9 +28852,15 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28636
28852
|
pushProgress: { kind: "queued", operationId: operation.sys.id }
|
|
28637
28853
|
});
|
|
28638
28854
|
let pollCount = 0;
|
|
28855
|
+
let lastPolledStatus = "";
|
|
28639
28856
|
operation = await client2.pollOperation(operation.sys.id, {
|
|
28640
28857
|
onProgress: (op) => {
|
|
28641
28858
|
pollCount++;
|
|
28859
|
+
const polled = `${op.sys.status} ${op.summary ? `${op.summary.total - op.summary.pending}/${op.summary.total}` : ""}`;
|
|
28860
|
+
if (polled !== lastPolledStatus) {
|
|
28861
|
+
lastPolledStatus = polled;
|
|
28862
|
+
pushDebug.event("Operation status changed", { note: polled.trim(), requestId: client2.getLastRequestId() });
|
|
28863
|
+
}
|
|
28642
28864
|
const s = op.summary;
|
|
28643
28865
|
if (s) {
|
|
28644
28866
|
const done = s.total - s.pending;
|
|
@@ -28743,6 +28965,29 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28743
28965
|
);
|
|
28744
28966
|
}
|
|
28745
28967
|
}
|
|
28968
|
+
const failedItems = items.filter((item) => item.status === "failed");
|
|
28969
|
+
const pushedCount = items.filter((item) => item.status === "succeeded").length;
|
|
28970
|
+
pushDebug.finish({
|
|
28971
|
+
outcome: pushSucceeded ? "pushed" : pushedCount > 0 ? "partial" : "failed",
|
|
28972
|
+
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.`,
|
|
28973
|
+
details: {
|
|
28974
|
+
operation_id: operation.sys.id,
|
|
28975
|
+
operation_status: operation.sys.status,
|
|
28976
|
+
server_summary: operation.summary,
|
|
28977
|
+
items: items.map((item) => ({
|
|
28978
|
+
type: item.entityType,
|
|
28979
|
+
id: item.id,
|
|
28980
|
+
action: item.action,
|
|
28981
|
+
status: item.status,
|
|
28982
|
+
...item.error ? { error: formatEdsiError(item.error) } : {}
|
|
28983
|
+
})),
|
|
28984
|
+
shown_to_user: {
|
|
28985
|
+
component_types: pushResult.componentTypes,
|
|
28986
|
+
design_tokens: pushResult.designTokens
|
|
28987
|
+
},
|
|
28988
|
+
request_id: client2.getLastRequestId()
|
|
28989
|
+
}
|
|
28990
|
+
});
|
|
28746
28991
|
update({ step: "done", pushResult });
|
|
28747
28992
|
} catch (e) {
|
|
28748
28993
|
let msg;
|
|
@@ -28753,6 +28998,14 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28753
28998
|
} else {
|
|
28754
28999
|
msg = "Push failed";
|
|
28755
29000
|
}
|
|
29001
|
+
pushDebug.finish({
|
|
29002
|
+
outcome: "failed",
|
|
29003
|
+
summary: e instanceof ApiError ? `The apply request failed with HTTP ${e.status}.` : `The apply request failed before the server answered: ${msg}`,
|
|
29004
|
+
details: {
|
|
29005
|
+
message: msg,
|
|
29006
|
+
...e instanceof ApiError ? { status: e.status, body: (e.body ?? "").slice(0, 4e3) } : {}
|
|
29007
|
+
}
|
|
29008
|
+
});
|
|
28756
29009
|
update({
|
|
28757
29010
|
step: "error",
|
|
28758
29011
|
errorStep: "apply",
|
|
@@ -28764,7 +29017,7 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28764
29017
|
};
|
|
28765
29018
|
const runPrintFiles = async (extractSessionId, outDir, opts = {}) => {
|
|
28766
29019
|
update({ step: "printing" });
|
|
28767
|
-
const componentsPath =
|
|
29020
|
+
const componentsPath = join21(outDir, "components.json");
|
|
28768
29021
|
try {
|
|
28769
29022
|
const db = openPipelineDb();
|
|
28770
29023
|
let components = [];
|
|
@@ -28867,7 +29120,7 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28867
29120
|
if (tokenReuseChecked.current) return;
|
|
28868
29121
|
tokenReuseChecked.current = true;
|
|
28869
29122
|
const tokenNextStep = state.projectPath ? "path-validation" : "credentials";
|
|
28870
|
-
const existingTokensPath =
|
|
29123
|
+
const existingTokensPath = join21(state.outDir, "tokens.json");
|
|
28871
29124
|
if (effectiveNoCache) {
|
|
28872
29125
|
tokenGenerationPromiseRef.current = runAgentAuthCheck(tokenNextStep).then(
|
|
28873
29126
|
(ok2) => ok2 ? runGenerateTokens(state.rawTokensPath, state.outDir) : false
|
|
@@ -28918,7 +29171,7 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28918
29171
|
{
|
|
28919
29172
|
onContinue: (path) => {
|
|
28920
29173
|
const projectPath = normalizePath(path);
|
|
28921
|
-
const outDir =
|
|
29174
|
+
const outDir = join21(projectPath, ".contentful");
|
|
28922
29175
|
update({ step: "token-input", projectPath, outDir });
|
|
28923
29176
|
},
|
|
28924
29177
|
onQuit: () => process.exit(0)
|
|
@@ -29280,6 +29533,7 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
29280
29533
|
environmentId: state.environmentId,
|
|
29281
29534
|
stepNumber: totalSteps,
|
|
29282
29535
|
totalSteps,
|
|
29536
|
+
droppedTokenDefaults: state.droppedTokenDefaults,
|
|
29283
29537
|
onConfirm: (acknowledge) => {
|
|
29284
29538
|
void runPush(
|
|
29285
29539
|
state.cdf,
|
|
@@ -29416,6 +29670,7 @@ var init_WizardApp = __esm({
|
|
|
29416
29670
|
init_theme();
|
|
29417
29671
|
init_run_teaser();
|
|
29418
29672
|
init_debug_logger();
|
|
29673
|
+
init_push_debug_log();
|
|
29419
29674
|
init_credentials_store();
|
|
29420
29675
|
init_path_prompt();
|
|
29421
29676
|
init_save_path_resolver();
|
|
@@ -29444,6 +29699,8 @@ var init_WizardApp = __esm({
|
|
|
29444
29699
|
init_wizard_generate_progress();
|
|
29445
29700
|
init_spawn_generate();
|
|
29446
29701
|
init_tokens();
|
|
29702
|
+
init_dangling_token_defaults();
|
|
29703
|
+
init_fetch_existing_token_ids();
|
|
29447
29704
|
init_preview_utils();
|
|
29448
29705
|
init_db();
|
|
29449
29706
|
init_ScopeGateStep();
|
|
@@ -29460,7 +29717,7 @@ var init_WizardApp = __esm({
|
|
|
29460
29717
|
init_use_terminal_size();
|
|
29461
29718
|
init_render_with_goodbye();
|
|
29462
29719
|
SAVE_CONFIRMATION_DELAY_MS = 1e3;
|
|
29463
|
-
WIZARD_LOG =
|
|
29720
|
+
WIZARD_LOG = join21(tmpdir(), "experiences-import-wizard.log");
|
|
29464
29721
|
}
|
|
29465
29722
|
});
|
|
29466
29723
|
|
|
@@ -29591,7 +29848,7 @@ var init_agent_definitions = __esm({
|
|
|
29591
29848
|
});
|
|
29592
29849
|
|
|
29593
29850
|
// packages/experience-design-system-cli-legacy/src/setup/lib/shell.ts
|
|
29594
|
-
import { execFile as execFile3, spawn as
|
|
29851
|
+
import { execFile as execFile3, spawn as spawn4 } from "node:child_process";
|
|
29595
29852
|
import { access as access8 } from "node:fs/promises";
|
|
29596
29853
|
import { promisify as promisify2 } from "node:util";
|
|
29597
29854
|
async function binaryExists(name) {
|
|
@@ -29607,7 +29864,7 @@ async function pathExists3(path) {
|
|
|
29607
29864
|
}
|
|
29608
29865
|
function runSpawn(cmd, args, opts = {}) {
|
|
29609
29866
|
return new Promise((resolve21) => {
|
|
29610
|
-
const child =
|
|
29867
|
+
const child = spawn4(cmd, args, {
|
|
29611
29868
|
cwd: opts.cwd,
|
|
29612
29869
|
env: opts.env ?? process.env,
|
|
29613
29870
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -29640,7 +29897,7 @@ var init_shell = __esm({
|
|
|
29640
29897
|
});
|
|
29641
29898
|
|
|
29642
29899
|
// packages/experience-design-system-cli-legacy/src/setup/lib/checks.ts
|
|
29643
|
-
import { join as
|
|
29900
|
+
import { join as join22 } from "node:path";
|
|
29644
29901
|
function checkNodeVersion(nodeVersion = process.versions.node) {
|
|
29645
29902
|
const major = Number.parseInt(nodeVersion.split(".")[0], 10);
|
|
29646
29903
|
return {
|
|
@@ -29654,7 +29911,7 @@ async function detectNodeVersionManagers(homeDir, deps = {
|
|
|
29654
29911
|
binaryExists,
|
|
29655
29912
|
pathExists: pathExists3
|
|
29656
29913
|
}) {
|
|
29657
|
-
const nvmScript =
|
|
29914
|
+
const nvmScript = join22(homeDir, ".nvm", "nvm.sh");
|
|
29658
29915
|
return {
|
|
29659
29916
|
nvm: await deps.binaryExists("nvm") || await deps.pathExists(nvmScript),
|
|
29660
29917
|
fnm: await deps.binaryExists("fnm"),
|
|
@@ -29733,7 +29990,7 @@ var init_report = __esm({
|
|
|
29733
29990
|
|
|
29734
29991
|
// packages/experience-design-system-cli-legacy/src/doctor/checks.ts
|
|
29735
29992
|
import { homedir as homedir7 } from "node:os";
|
|
29736
|
-
import { join as
|
|
29993
|
+
import { join as join23 } from "node:path";
|
|
29737
29994
|
async function reportNode() {
|
|
29738
29995
|
section("Checking Node.js version");
|
|
29739
29996
|
const check = checkNodeVersion();
|
|
@@ -29784,12 +30041,12 @@ async function reportPnpm(pkgRoot) {
|
|
|
29784
30041
|
}
|
|
29785
30042
|
async function reportDependencies(pkgRoot) {
|
|
29786
30043
|
section("Checking dependencies (pnpm install)");
|
|
29787
|
-
if (!await pathExists3(
|
|
30044
|
+
if (!await pathExists3(join23(pkgRoot, "node_modules"))) {
|
|
29788
30045
|
info("node_modules not found \u2014 running pnpm install...");
|
|
29789
30046
|
} else {
|
|
29790
30047
|
info("Running pnpm install to ensure dependencies are up to date...");
|
|
29791
30048
|
}
|
|
29792
|
-
const check = await installDependencies(
|
|
30049
|
+
const check = await installDependencies(join23(pkgRoot, "..", ".."));
|
|
29793
30050
|
if (!check.passed) {
|
|
29794
30051
|
fail("pnpm install failed");
|
|
29795
30052
|
info("");
|
|
@@ -29806,7 +30063,7 @@ async function reportDependencies(pkgRoot) {
|
|
|
29806
30063
|
async function reportBuild(pkgRoot) {
|
|
29807
30064
|
section("Building CLI");
|
|
29808
30065
|
info("Running pnpm build...");
|
|
29809
|
-
const check = await buildCli(
|
|
30066
|
+
const check = await buildCli(join23(pkgRoot, "..", ".."));
|
|
29810
30067
|
if (!check.passed) {
|
|
29811
30068
|
fail("Build failed");
|
|
29812
30069
|
info("");
|
|
@@ -31021,9 +31278,9 @@ var init_SetupScreen = __esm({
|
|
|
31021
31278
|
|
|
31022
31279
|
// packages/experience-design-system-cli-legacy/src/setup/command.ts
|
|
31023
31280
|
import { readFileSync as readFileSync8 } from "node:fs";
|
|
31024
|
-
import { join as
|
|
31281
|
+
import { join as join24 } from "node:path";
|
|
31025
31282
|
function getCliVersion() {
|
|
31026
|
-
const pkg4 = JSON.parse(readFileSync8(
|
|
31283
|
+
const pkg4 = JSON.parse(readFileSync8(join24(findPkgRoot(), "package.json"), "utf8"));
|
|
31027
31284
|
return pkg4.version;
|
|
31028
31285
|
}
|
|
31029
31286
|
async function runSetup(opts) {
|
|
@@ -31035,7 +31292,7 @@ async function runSetup(opts) {
|
|
|
31035
31292
|
const { renderWithGoodbye: renderWithGoodbye2 } = await Promise.resolve().then(() => (init_render_with_goodbye(), render_with_goodbye_exports));
|
|
31036
31293
|
const { createElement: createElement6 } = await import("react");
|
|
31037
31294
|
const { SetupScreen: SetupScreen2 } = await Promise.resolve().then(() => (init_SetupScreen(), SetupScreen_exports));
|
|
31038
|
-
const repoRoot =
|
|
31295
|
+
const repoRoot = join24(findPkgRoot(), "..", "..");
|
|
31039
31296
|
const completion = { outcome: null };
|
|
31040
31297
|
let unmountInk = null;
|
|
31041
31298
|
const { waitUntilExit, unmount } = renderWithGoodbye2(
|
|
@@ -31236,15 +31493,15 @@ var init_apply_mapping = __esm({
|
|
|
31236
31493
|
});
|
|
31237
31494
|
|
|
31238
31495
|
// packages/experience-design-system-cli-legacy/src/analyze/composition/prompt-loader.ts
|
|
31239
|
-
import { existsSync as
|
|
31240
|
-
import { dirname as dirname11, join as
|
|
31496
|
+
import { existsSync as existsSync8, readFileSync as readFileSync9 } from "node:fs";
|
|
31497
|
+
import { dirname as dirname11, join as join25, resolve as resolve18 } from "node:path";
|
|
31241
31498
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
31242
31499
|
function resolvePromptPath(fileName) {
|
|
31243
31500
|
const thisDir = dirname11(fileURLToPath3(import.meta.url));
|
|
31244
31501
|
let dir = thisDir;
|
|
31245
31502
|
for (; ; ) {
|
|
31246
|
-
const candidate =
|
|
31247
|
-
if (
|
|
31503
|
+
const candidate = join25(dir, "prompts");
|
|
31504
|
+
if (existsSync8(candidate)) return join25(candidate, fileName);
|
|
31248
31505
|
const parent = resolve18(dir, "..");
|
|
31249
31506
|
if (parent === dir) {
|
|
31250
31507
|
throw new Error(
|
|
@@ -31512,7 +31769,7 @@ var init_manifest_doc_evidence = __esm({
|
|
|
31512
31769
|
|
|
31513
31770
|
// packages/experience-design-system-cli-legacy/src/analyze/extract-command.ts
|
|
31514
31771
|
import { mkdir as mkdir6, readdir as readdir3, readFile as readFile18, stat as stat6 } from "node:fs/promises";
|
|
31515
|
-
import { isAbsolute as isAbsolute2, join as
|
|
31772
|
+
import { isAbsolute as isAbsolute2, join as join26, relative as relative2, resolve as resolve19 } from "node:path";
|
|
31516
31773
|
function resolveExtractNoCache(opts) {
|
|
31517
31774
|
return opts.noCache === true || opts.cache === false;
|
|
31518
31775
|
}
|
|
@@ -31550,7 +31807,7 @@ async function collectSourceFiles(directory, onProgress) {
|
|
|
31550
31807
|
const entries = await readdir3(currentDirectory, { withFileTypes: true });
|
|
31551
31808
|
const subdirs = [];
|
|
31552
31809
|
for (const entry of entries) {
|
|
31553
|
-
const fullPath =
|
|
31810
|
+
const fullPath = join26(currentDirectory, entry.name);
|
|
31554
31811
|
if (entry.isDirectory()) {
|
|
31555
31812
|
if (!IGNORED_DIRECTORY_NAMES.has(entry.name)) {
|
|
31556
31813
|
subdirs.push(fullPath);
|
|
@@ -31634,7 +31891,7 @@ function registerInternalExtractCommand(program) {
|
|
|
31634
31891
|
}
|
|
31635
31892
|
}
|
|
31636
31893
|
const projectRoot = resolve19(opts.project);
|
|
31637
|
-
const outDir =
|
|
31894
|
+
const outDir = join26(projectRoot, ".contentful");
|
|
31638
31895
|
let sourceDirectory;
|
|
31639
31896
|
if (opts.dir !== void 0) {
|
|
31640
31897
|
sourceDirectory = resolveFromProjectRoot(projectRoot, opts.dir);
|
|
@@ -32037,9 +32294,9 @@ __export(program_exports, {
|
|
|
32037
32294
|
resolveBedrockFromAncestors: () => resolveBedrockFromAncestors,
|
|
32038
32295
|
runBuild: () => runBuild
|
|
32039
32296
|
});
|
|
32040
|
-
import { spawn as
|
|
32297
|
+
import { spawn as spawn5 } from "node:child_process";
|
|
32041
32298
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
32042
|
-
import { dirname as dirname13, join as
|
|
32299
|
+
import { dirname as dirname13, join as join27, resolve as resolve20 } from "node:path";
|
|
32043
32300
|
import { readFileSync as readFileSync10 } from "node:fs";
|
|
32044
32301
|
import { Command } from "commander";
|
|
32045
32302
|
async function runBuild(opts) {
|
|
@@ -32072,7 +32329,7 @@ function registerBuildCommand(program) {
|
|
|
32072
32329
|
const pkgRoot = resolve20(dirname13(fileURLToPath4(import.meta.url)), "..", "..");
|
|
32073
32330
|
process.stderr.write("\u2699 Building from source...\n");
|
|
32074
32331
|
const { exitCode } = await runBuild({
|
|
32075
|
-
spawnFn: () =>
|
|
32332
|
+
spawnFn: () => spawn5("pnpm", ["build"], { cwd: pkgRoot, stdio: "inherit" }),
|
|
32076
32333
|
stderrWrite: (s) => process.stderr.write(s)
|
|
32077
32334
|
});
|
|
32078
32335
|
process.exit(exitCode);
|
|
@@ -32139,7 +32396,7 @@ var init_program = __esm({
|
|
|
32139
32396
|
init_analytics();
|
|
32140
32397
|
init_credentials_store();
|
|
32141
32398
|
init_cli_path();
|
|
32142
|
-
pkg3 = JSON.parse(readFileSync10(
|
|
32399
|
+
pkg3 = JSON.parse(readFileSync10(join27(findPkgRoot(), "package.json"), "utf8"));
|
|
32143
32400
|
}
|
|
32144
32401
|
});
|
|
32145
32402
|
|