@contentful/experience-design-system-cli 2.35.1-dev-build-45d6c918.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 +1278 -1045
- 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
|
@@ -164,506 +164,272 @@ var init_render_with_goodbye = __esm({
|
|
|
164
164
|
function isAgentName(value) {
|
|
165
165
|
return AGENT_NAMES.includes(value);
|
|
166
166
|
}
|
|
167
|
-
var AGENT_NAMES, DEFAULT_AGENT_NAME
|
|
167
|
+
var AGENT_NAMES, DEFAULT_AGENT_NAME;
|
|
168
168
|
var init_agent_names = __esm({
|
|
169
169
|
"packages/experience-design-system-generation/dist/src/agent-names.js"() {
|
|
170
170
|
"use strict";
|
|
171
171
|
AGENT_NAMES = ["claude", "codex", "opencode", "cursor", "copilot"];
|
|
172
172
|
DEFAULT_AGENT_NAME = "claude";
|
|
173
|
-
AGENT_BINARIES = {
|
|
174
|
-
claude: "claude",
|
|
175
|
-
codex: "codex",
|
|
176
|
-
opencode: "opencode",
|
|
177
|
-
cursor: "cursor-agent",
|
|
178
|
-
copilot: "copilot"
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
// packages/experience-design-system-generation/dist/src/controller/helpers/validate-generation-request.js
|
|
184
|
-
function validateGenerationRequest(request2) {
|
|
185
|
-
if (request2 === null || typeof request2 !== "object") {
|
|
186
|
-
throw new TypeError("createGenerationEndpoint requires a request object");
|
|
187
|
-
}
|
|
188
|
-
if (!isAgentName(request2.agent)) {
|
|
189
|
-
throw new TypeError(`createGenerationEndpoint requires agent to be a valid agent name, got: ${String(request2.agent)}`);
|
|
190
|
-
}
|
|
191
|
-
if (typeof request2.timeoutMs !== "number" || request2.timeoutMs <= 0) {
|
|
192
|
-
throw new TypeError("createGenerationEndpoint requires timeoutMs to be a positive number");
|
|
193
|
-
}
|
|
194
|
-
if (request2.promptOptions === null || typeof request2.promptOptions !== "object") {
|
|
195
|
-
throw new TypeError("createGenerationEndpoint requires promptOptions to be an object");
|
|
196
|
-
}
|
|
197
|
-
if (request2.onOutput !== void 0 && typeof request2.onOutput !== "function") {
|
|
198
|
-
throw new TypeError("createGenerationEndpoint requires onOutput to be a function when provided");
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
var init_validate_generation_request = __esm({
|
|
202
|
-
"packages/experience-design-system-generation/dist/src/controller/helpers/validate-generation-request.js"() {
|
|
203
|
-
"use strict";
|
|
204
|
-
init_agent_names();
|
|
205
173
|
}
|
|
206
174
|
});
|
|
207
175
|
|
|
208
|
-
// packages/experience-design-system-generation/dist/src/
|
|
209
|
-
import {
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
if (
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
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;
|
|
225
194
|
}
|
|
226
|
-
dir = parent;
|
|
227
195
|
}
|
|
196
|
+
return -1;
|
|
228
197
|
}
|
|
229
|
-
function
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
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;
|
|
238
211
|
try {
|
|
239
|
-
|
|
212
|
+
parsed = JSON.parse(line.slice(0, end + 1));
|
|
240
213
|
} catch {
|
|
241
|
-
|
|
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);
|
|
242
223
|
}
|
|
243
224
|
}
|
|
244
|
-
|
|
245
|
-
try {
|
|
246
|
-
return await readFile2(skillPath, "utf8");
|
|
247
|
-
} catch {
|
|
248
|
-
throw new Error(`skill file missing from CLI installation \u2014 try reinstalling the CLI (looked for: ${skillPath})`);
|
|
249
|
-
}
|
|
225
|
+
return { objects, warnings };
|
|
250
226
|
}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
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
|
|
260
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);
|
|
261
251
|
}
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
// packages/experience-design-system-generation/dist/src/services/prompts/helpers/format-token-candidates.js
|
|
265
|
-
import { flattenDTCG } from "@contentful/experience-design-system-types";
|
|
266
|
-
function inferFenceLang(filename) {
|
|
267
|
-
if (!filename)
|
|
268
|
-
return "json";
|
|
269
|
-
const ext = filename.split(".").pop()?.toLowerCase() ?? "";
|
|
270
|
-
const map = {
|
|
271
|
-
js: "js",
|
|
272
|
-
mjs: "js",
|
|
273
|
-
cjs: "js",
|
|
274
|
-
ts: "ts",
|
|
275
|
-
mts: "ts",
|
|
276
|
-
cts: "ts",
|
|
277
|
-
tsx: "tsx",
|
|
278
|
-
jsx: "jsx",
|
|
279
|
-
vue: "vue",
|
|
280
|
-
svelte: "svelte",
|
|
281
|
-
astro: "astro",
|
|
282
|
-
scss: "scss",
|
|
283
|
-
sass: "scss",
|
|
284
|
-
css: "css",
|
|
285
|
-
json: "json",
|
|
286
|
-
json5: "json"
|
|
287
|
-
};
|
|
288
|
-
return map[ext] ?? "text";
|
|
252
|
+
return { calls, warnings };
|
|
289
253
|
}
|
|
290
|
-
function
|
|
291
|
-
const
|
|
292
|
-
const
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
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)}`);
|
|
297
260
|
continue;
|
|
298
|
-
const filteredProps = {};
|
|
299
|
-
for (const [propName, prop] of Object.entries(properties)) {
|
|
300
|
-
if (prop.$type === "token" && prop.$category === "design") {
|
|
301
|
-
const { "$token.allowed": _tokenAllowed, ...rest } = prop;
|
|
302
|
-
filteredProps[propName] = rest;
|
|
303
|
-
const kind = prop["$token.kind"];
|
|
304
|
-
if (typeof kind === "string" && kind.length > 0) {
|
|
305
|
-
kinds.add(kind);
|
|
306
|
-
} else {
|
|
307
|
-
hasUnscoped = true;
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
261
|
}
|
|
311
|
-
|
|
312
|
-
|
|
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);
|
|
313
339
|
}
|
|
314
340
|
}
|
|
315
|
-
return {
|
|
316
|
-
}
|
|
317
|
-
function buildTokenCandidateSections(tokenTree, filteredTokenProps) {
|
|
318
|
-
const index = flattenDTCG(tokenTree, "").sort((a, b) => a.path.localeCompare(b.path));
|
|
319
|
-
if (index.length === 0)
|
|
320
|
-
return [];
|
|
321
|
-
const sections = [];
|
|
322
|
-
const renderSection = (kind, entries) => {
|
|
323
|
-
const label = kind ? `Token path index \u2014 ${kind} candidates only` : "Token path index \u2014 full tree (no $token.kind to scope by)";
|
|
324
|
-
const lines = entries.map((e) => `${e.path} \xB7 ${e.$type}`).join("\n");
|
|
325
|
-
return `${label}, one leaf token per line as \`path \xB7 type\`, no \`$value\`:
|
|
326
|
-
${lines}`;
|
|
327
|
-
};
|
|
328
|
-
if (filteredTokenProps) {
|
|
329
|
-
const { kinds, hasUnscoped } = filteredTokenProps;
|
|
330
|
-
for (const kind of kinds) {
|
|
331
|
-
const scoped = index.filter((e) => e.$type === kind);
|
|
332
|
-
if (scoped.length > 0)
|
|
333
|
-
sections.push(renderSection(kind, scoped));
|
|
334
|
-
}
|
|
335
|
-
if (hasUnscoped)
|
|
336
|
-
sections.push(renderSection(null, index));
|
|
337
|
-
} else {
|
|
338
|
-
sections.push(renderSection(null, index));
|
|
339
|
-
}
|
|
340
|
-
return sections;
|
|
341
|
+
return { calls, warnings };
|
|
341
342
|
}
|
|
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
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
${withContent.map(formatSourceRefBlock).join("\n\n")}`);
|
|
376
|
-
}
|
|
377
|
-
if (withoutContent.length > 0) {
|
|
378
|
-
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";
|
|
379
|
-
sections.push(`Component source unavailable for (JSON) \u2014 ${guidance}:
|
|
380
|
-
\`\`\`json
|
|
381
|
-
${JSON.stringify(withoutContent.map((ref) => ({ component: ref.component, sourcePath: ref.sourcePath })))}
|
|
382
|
-
\`\`\``);
|
|
383
|
-
}
|
|
384
|
-
return sections;
|
|
385
|
-
}
|
|
386
|
-
var init_format_source_refs = __esm({
|
|
387
|
-
"packages/experience-design-system-generation/dist/src/services/prompts/helpers/format-source-refs.js"() {
|
|
388
|
-
"use strict";
|
|
389
|
-
init_format_token_candidates();
|
|
390
|
-
}
|
|
391
|
-
});
|
|
392
|
-
|
|
393
|
-
// packages/experience-design-system-generation/dist/src/services/prompts/helpers/build-skill-preambles.js
|
|
394
|
-
function buildComponentsAutonomousPreamble(inputBlock) {
|
|
395
|
-
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.
|
|
396
|
-
|
|
397
|
-
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:
|
|
398
|
-
- **design**: controls how the component looks (variant, size, color, layout toggles)
|
|
399
|
-
- **content**: the data a content editor fills in (text, images, URLs, rich text)
|
|
400
|
-
- **state**: runtime behavioral flags (disabled, loading, expanded, identifiers)
|
|
401
|
-
|
|
402
|
-
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.
|
|
403
|
-
|
|
404
|
-
All input data is provided inline below \u2014 do not read any additional files.${inputBlock}
|
|
405
|
-
|
|
406
|
-
## Output protocol
|
|
407
|
-
|
|
408
|
-
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.
|
|
409
|
-
|
|
410
|
-
The four tool calls you may emit are:
|
|
411
|
-
|
|
412
|
-
\`\`\`
|
|
413
|
-
{"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>"}}
|
|
414
|
-
|
|
415
|
-
{"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>"}
|
|
416
|
-
|
|
417
|
-
{"tool":"exclude_prop","prop":"<propName>","reason":"<why excluded>"}
|
|
418
|
-
|
|
419
|
-
{"tool":"classify_slot","slot":"<slotName>","required":<bool>,"allowed_components":["ComponentName"],"description":"<reason>","rationale":"<why this slot was kept in the catalog>"}
|
|
420
|
-
\`\`\`
|
|
421
|
-
|
|
422
|
-
Rules:
|
|
423
|
-
- Emit exactly one JSON object per line. No multi-line JSON. No markdown fences around the lines.
|
|
424
|
-
- Every prop in the input must have exactly one call: either classify_prop or exclude_prop.
|
|
425
|
-
- Every slot in the input must have exactly one classify_slot call.
|
|
426
|
-
- Valid cdf_type values: string, richtext, media, enum, token, boolean
|
|
427
|
-
- Valid cdf_category values: content, design, state
|
|
428
|
-
- For enum type, always include \`values\` (non-empty string array of the variant names the prop accepts).
|
|
429
|
-
- 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.
|
|
430
|
-
- Never emit both "values" and "token_kind" on one prop.
|
|
431
|
-
- \`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.
|
|
432
|
-
- Q2: is the value written straight into a style or attribute (\`rx={radius}\`, \`padding: \${padding}\`)? no \u2192 not \`token\`, apply the type rules.
|
|
433
|
-
- 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.
|
|
434
|
-
- 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".
|
|
435
|
-
- 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.
|
|
436
|
-
- 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.
|
|
437
|
-
- 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.
|
|
438
|
-
- You may emit prose lines (not starting with {) anywhere \u2014 they are ignored by the parser and serve as your reasoning log.`;
|
|
439
|
-
}
|
|
440
|
-
function buildSelectAutonomousPreamble(inputBlock) {
|
|
441
|
-
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.
|
|
442
|
-
|
|
443
|
-
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.
|
|
444
|
-
|
|
445
|
-
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.
|
|
446
|
-
|
|
447
|
-
All input data is provided inline below \u2014 do not read any additional files.${inputBlock}
|
|
448
|
-
|
|
449
|
-
## Output protocol
|
|
450
|
-
|
|
451
|
-
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.
|
|
452
|
-
|
|
453
|
-
The two tool calls \u2014 emit exactly one per input component:
|
|
454
|
-
|
|
455
|
-
\`\`\`
|
|
456
|
-
{"tool":"select_component","name":"<ComponentName>","reason":"<brief reason>"}
|
|
457
|
-
|
|
458
|
-
{"tool":"reject_component","name":"<ComponentName>","reason":"<brief reason>"}
|
|
459
|
-
\`\`\`
|
|
460
|
-
|
|
461
|
-
Rules:
|
|
462
|
-
- Emit exactly one JSON object per line. No multi-line JSON. No markdown fences.
|
|
463
|
-
- 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.
|
|
464
|
-
- You may emit prose lines (not starting with {) to reason before each tool call \u2014 they are ignored by the parser.`;
|
|
465
|
-
}
|
|
466
|
-
function buildMapTokensAutonomousPreamble(inputBlock) {
|
|
467
|
-
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.
|
|
468
|
-
|
|
469
|
-
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.
|
|
470
|
-
|
|
471
|
-
All input data is provided inline below \u2014 do not read any additional files.${inputBlock}
|
|
472
|
-
|
|
473
|
-
## Output protocol
|
|
474
|
-
|
|
475
|
-
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.
|
|
476
|
-
|
|
477
|
-
The one tool call you may emit:
|
|
478
|
-
|
|
479
|
-
\`\`\`
|
|
480
|
-
{"tool":"map_token_prop","component":"<ComponentName>","prop":"<propName>","token_allowed":["colors.brand.primary","colors.brand.secondary"]}
|
|
481
|
-
\`\`\`
|
|
482
|
-
|
|
483
|
-
Rules:
|
|
484
|
-
- Emit exactly one JSON object per line. No multi-line JSON. No markdown fences around the lines.
|
|
485
|
-
- Only emit a call for a prop that appears in the "Generated CDF so far" section.
|
|
486
|
-
- 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.
|
|
487
|
-
- \`token_allowed\` is required and must be non-empty when the call is emitted.
|
|
488
|
-
- 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.
|
|
489
|
-
- You may emit prose lines (not starting with \`{\`) anywhere \u2014 they are ignored by the parser and serve as your reasoning log.`;
|
|
490
|
-
}
|
|
491
|
-
function buildTokensAutonomousPreamble(inputBlock) {
|
|
492
|
-
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.
|
|
493
|
-
|
|
494
|
-
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.
|
|
495
|
-
|
|
496
|
-
All input data is provided inline below \u2014 do not read any additional files.${inputBlock}
|
|
497
|
-
|
|
498
|
-
## Output protocol
|
|
499
|
-
|
|
500
|
-
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.
|
|
501
|
-
|
|
502
|
-
The two tool calls you may emit are:
|
|
503
|
-
|
|
504
|
-
\`\`\`
|
|
505
|
-
{"tool":"set_group","path":"<dot.notation.path>","description":"<optional group description>"}
|
|
506
|
-
|
|
507
|
-
{"tool":"set_token","path":"<dot.notation.path>","type":"<DTCG type>","value":<value>,"description":"<reason>"}
|
|
508
|
-
\`\`\`
|
|
509
|
-
|
|
510
|
-
Rules:
|
|
511
|
-
- Emit exactly one JSON object per line. No multi-line JSON. No markdown fences.
|
|
512
|
-
- Emit a set_group call for every intermediate group node in the tree.
|
|
513
|
-
- Emit a set_token call for every leaf token.
|
|
514
|
-
- "path" is dot-notation, e.g. "colors.brand.primary" \u2014 no leading dots or slashes.
|
|
515
|
-
- "type" must be one of the 13 valid DTCG types: color, dimension, fontFamily, fontWeight, duration, cubicBezier, number, strokeStyle, border, transition, shadow, gradient, typography.
|
|
516
|
-
- "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.
|
|
517
|
-
- Emit set_group calls before the set_token calls that fall under them.
|
|
518
|
-
- You may emit prose lines (not starting with {) anywhere \u2014 they are ignored by the parser and serve as your reasoning log.`;
|
|
519
|
-
}
|
|
520
|
-
var init_build_skill_preambles = __esm({
|
|
521
|
-
"packages/experience-design-system-generation/dist/src/services/prompts/helpers/build-skill-preambles.js"() {
|
|
522
|
-
"use strict";
|
|
523
|
-
}
|
|
524
|
-
});
|
|
525
|
-
|
|
526
|
-
// packages/experience-design-system-generation/dist/src/services/prompts/helpers/build-preamble.js
|
|
527
|
-
function buildPreamble(options) {
|
|
528
|
-
const { skill, rawComponentsInline, rawTokensInline, rawTokensFilename, tokensInline, tokenMapInline, generatedCdf, tokenTree, componentSourceRefs, existingComponentsInline, existingTokensInline, componentAllowlistInline } = options;
|
|
529
|
-
const sections = [];
|
|
530
|
-
if (existingComponentsInline) {
|
|
531
|
-
sections.push(`Existing components in the target Contentful space (JSON) \u2014 use for alignment, not as a hard filter:
|
|
532
|
-
\`\`\`json
|
|
533
|
-
${existingComponentsInline}
|
|
534
|
-
\`\`\``);
|
|
535
|
-
}
|
|
536
|
-
if (existingTokensInline) {
|
|
537
|
-
sections.push(`Existing design tokens in the target Contentful space (JSON) \u2014 prefer binding to these paths over inventing new ones:
|
|
538
|
-
\`\`\`json
|
|
539
|
-
${existingTokensInline}
|
|
540
|
-
\`\`\``);
|
|
541
|
-
}
|
|
542
|
-
if (componentAllowlistInline) {
|
|
543
|
-
sections.push(`Known component names for slot allowed_components (hard allowlist; never use any other name):
|
|
544
|
-
\`\`\`json
|
|
545
|
-
${componentAllowlistInline}
|
|
546
|
-
\`\`\``);
|
|
547
|
-
}
|
|
548
|
-
if (rawComponentsInline) {
|
|
549
|
-
sections.push(`Raw component data (JSON):
|
|
550
|
-
\`\`\`json
|
|
551
|
-
${rawComponentsInline}
|
|
552
|
-
\`\`\``);
|
|
553
|
-
}
|
|
554
|
-
if (rawTokensInline) {
|
|
555
|
-
const lang = inferFenceLang(rawTokensFilename);
|
|
556
|
-
const label = rawTokensFilename ? `Raw token source (${rawTokensFilename})` : "Raw token source";
|
|
557
|
-
sections.push(`${label}:
|
|
558
|
-
\`\`\`${lang}
|
|
559
|
-
${rawTokensInline}
|
|
560
|
-
\`\`\``);
|
|
561
|
-
}
|
|
562
|
-
if (tokensInline) {
|
|
563
|
-
sections.push(`DTCG token data (for token kind lookups):
|
|
564
|
-
\`\`\`json
|
|
565
|
-
${tokensInline}
|
|
566
|
-
\`\`\``);
|
|
567
|
-
}
|
|
568
|
-
if (tokenMapInline) {
|
|
569
|
-
sections.push(`Token-name sidecar (raw name \u2192 DTCG path):
|
|
570
|
-
\`\`\`json
|
|
571
|
-
${tokenMapInline}
|
|
572
|
-
\`\`\``);
|
|
573
|
-
}
|
|
574
|
-
const filteredTokenProps = generatedCdf ? filterDesignTokenProps(generatedCdf) : void 0;
|
|
575
|
-
if (filteredTokenProps && Object.keys(filteredTokenProps.filtered).length > 0) {
|
|
576
|
-
sections.push(`Generated CDF so far \u2014 design-category token props only (JSON):
|
|
577
|
-
\`\`\`json
|
|
578
|
-
${JSON.stringify(filteredTokenProps.filtered)}
|
|
579
|
-
\`\`\``);
|
|
580
|
-
}
|
|
581
|
-
if (tokenTree) {
|
|
582
|
-
sections.push(...buildTokenCandidateSections(tokenTree, filteredTokenProps));
|
|
583
|
-
}
|
|
584
|
-
if (componentSourceRefs && componentSourceRefs.length > 0) {
|
|
585
|
-
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
|
+
}
|
|
586
376
|
}
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
${sections.join("\n\n")}` : "";
|
|
590
|
-
if (skill === "components")
|
|
591
|
-
return buildComponentsAutonomousPreamble(inputBlock);
|
|
592
|
-
if (skill === "select")
|
|
593
|
-
return buildSelectAutonomousPreamble(inputBlock);
|
|
594
|
-
if (skill === "map-tokens")
|
|
595
|
-
return buildMapTokensAutonomousPreamble(inputBlock);
|
|
596
|
-
return buildTokensAutonomousPreamble(inputBlock);
|
|
377
|
+
return { calls, warnings };
|
|
597
378
|
}
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
"use strict";
|
|
601
|
-
init_format_token_candidates();
|
|
602
|
-
init_format_source_refs();
|
|
603
|
-
init_build_skill_preambles();
|
|
604
|
-
}
|
|
605
|
-
});
|
|
606
|
-
|
|
607
|
-
// packages/experience-design-system-generation/dist/src/services/prompts/build-prompt.js
|
|
608
|
-
async function buildPrompt(options) {
|
|
609
|
-
const skillContent = options.skillContentOverride ?? await readSkillFile(options.skill, options.skillPathOverride);
|
|
610
|
-
const preamble = buildPreamble(options);
|
|
611
|
-
return `${preamble}
|
|
612
|
-
|
|
613
|
-
Skill instructions follow:
|
|
614
|
-
---
|
|
615
|
-
${skillContent}`;
|
|
379
|
+
function isStringArray(value) {
|
|
380
|
+
return Array.isArray(value) && value.every((v) => typeof v === "string");
|
|
616
381
|
}
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
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);
|
|
623
420
|
}
|
|
624
|
-
}
|
|
625
|
-
|
|
626
|
-
// packages/experience-design-system-generation/dist/src/orchestrator/execute-generation-orchestrator.js
|
|
627
|
-
async function executeGenerationOrchestrator(request2) {
|
|
628
|
-
const prompt = await buildPrompt(request2.promptOptions);
|
|
629
|
-
return request2.invoker.invoke({
|
|
630
|
-
agent: request2.agent,
|
|
631
|
-
model: request2.model,
|
|
632
|
-
bedrock: request2.bedrock,
|
|
633
|
-
prompt,
|
|
634
|
-
timeoutMs: request2.timeoutMs,
|
|
635
|
-
onOutput: request2.onOutput
|
|
636
|
-
});
|
|
421
|
+
return { calls, warnings };
|
|
637
422
|
}
|
|
638
|
-
|
|
639
|
-
"packages/experience-design-system-generation/dist/src/orchestrator/execute-generation-orchestrator.js"() {
|
|
640
|
-
"use strict";
|
|
641
|
-
init_build_prompt();
|
|
642
|
-
}
|
|
643
|
-
});
|
|
644
|
-
|
|
645
|
-
// packages/experience-design-system-generation/dist/src/services/agent/helpers/resolve-agent-binary.js
|
|
646
|
-
function resolveAgentBinary(agent) {
|
|
423
|
+
function resolveBinary(agent) {
|
|
647
424
|
const envKey = `EDS_AGENT_BINARY_${agent.toUpperCase()}`;
|
|
648
425
|
const override = process.env[envKey];
|
|
649
426
|
if (override && override.trim())
|
|
650
427
|
return override.trim();
|
|
651
428
|
return AGENT_BINARIES[agent];
|
|
652
429
|
}
|
|
653
|
-
var init_resolve_agent_binary = __esm({
|
|
654
|
-
"packages/experience-design-system-generation/dist/src/services/agent/helpers/resolve-agent-binary.js"() {
|
|
655
|
-
"use strict";
|
|
656
|
-
init_agent_names();
|
|
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];
|
|
@@ -702,69 +471,12 @@ function buildAgentArgs(agent, prompt, model, promptViaStdin = false, bedrock =
|
|
|
702
471
|
}
|
|
703
472
|
}
|
|
704
473
|
}
|
|
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/helpers/describe-agent-failure.js
|
|
726
|
-
function describeAgentFailure(result, maxDetail = 800) {
|
|
727
|
-
const base = result.exitCode !== 0 ? `agent exited with code ${result.exitCode}` : "agent produced no tool calls";
|
|
728
|
-
const detail = (result.stderr.trim() || result.stdout.trim()).slice(-maxDetail).trim();
|
|
729
|
-
return detail ? `${base} \u2014 ${detail}` : base;
|
|
730
|
-
}
|
|
731
|
-
var init_describe_agent_failure = __esm({
|
|
732
|
-
"packages/experience-design-system-generation/dist/src/services/agent/helpers/describe-agent-failure.js"() {
|
|
733
|
-
"use strict";
|
|
734
|
-
}
|
|
735
|
-
});
|
|
736
|
-
|
|
737
|
-
// packages/experience-design-system-generation/dist/src/services/agent/helpers/extract-sentinel-output.js
|
|
738
|
-
function extractSentinelOutput(stdout) {
|
|
739
|
-
const START = "<<<EDS_OUTPUT_START>>>";
|
|
740
|
-
const END = "<<<EDS_OUTPUT_END>>>";
|
|
741
|
-
const startIdx = stdout.indexOf(START);
|
|
742
|
-
const endIdx = stdout.indexOf(END);
|
|
743
|
-
if (startIdx === -1 || endIdx === -1 || endIdx <= startIdx)
|
|
744
|
-
return null;
|
|
745
|
-
const secondStart = stdout.indexOf(START, startIdx + START.length);
|
|
746
|
-
if (secondStart !== -1 && secondStart < endIdx)
|
|
747
|
-
return "multiple";
|
|
748
|
-
const afterStart = stdout.indexOf(END, startIdx);
|
|
749
|
-
const secondEnd = stdout.indexOf(END, afterStart + END.length);
|
|
750
|
-
if (secondEnd !== -1)
|
|
751
|
-
return "multiple";
|
|
752
|
-
return stdout.slice(startIdx + START.length, endIdx).trim();
|
|
753
|
-
}
|
|
754
|
-
var init_extract_sentinel_output = __esm({
|
|
755
|
-
"packages/experience-design-system-generation/dist/src/services/agent/helpers/extract-sentinel-output.js"() {
|
|
756
|
-
"use strict";
|
|
757
|
-
}
|
|
758
|
-
});
|
|
759
|
-
|
|
760
|
-
// packages/experience-design-system-generation/dist/src/services/agent/run-agent.js
|
|
761
|
-
import { spawn } from "node:child_process";
|
|
762
474
|
async function runAgent(options) {
|
|
763
475
|
const { agent, prompt, timeoutMs, model, onOutput, promptViaStdin, onDebugEvent } = options;
|
|
764
476
|
const bedrock = options.bedrock ?? process.env.EDS_BEDROCK === "1";
|
|
765
|
-
const binary =
|
|
477
|
+
const binary = resolveBinary(agent);
|
|
766
478
|
const useStdin2 = !!promptViaStdin;
|
|
767
|
-
const args =
|
|
479
|
+
const args = buildArgs(agent, prompt, model, useStdin2, bedrock);
|
|
768
480
|
const startedAt = Date.now();
|
|
769
481
|
onDebugEvent?.("run.start", {
|
|
770
482
|
agent,
|
|
@@ -807,7 +519,12 @@ async function runAgent(options) {
|
|
|
807
519
|
});
|
|
808
520
|
child.on("close", (code, signal) => {
|
|
809
521
|
clearTimeout(timer);
|
|
810
|
-
const result = {
|
|
522
|
+
const result = {
|
|
523
|
+
exitCode: signal ? 1 : code ?? 1,
|
|
524
|
+
stdout,
|
|
525
|
+
stderr,
|
|
526
|
+
timedOut
|
|
527
|
+
};
|
|
811
528
|
onDebugEvent?.("run.end", {
|
|
812
529
|
agent,
|
|
813
530
|
model,
|
|
@@ -823,21 +540,22 @@ async function runAgent(options) {
|
|
|
823
540
|
});
|
|
824
541
|
});
|
|
825
542
|
}
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
543
|
+
async function checkAgentAuth(agent) {
|
|
544
|
+
const binary = resolveBinary(agent);
|
|
545
|
+
const binaryExists2 = await new Promise((resolve21) => {
|
|
546
|
+
if (binary.startsWith("/")) {
|
|
547
|
+
import("node:fs/promises").then((fs2) => fs2.access(binary).then(() => resolve21(true), () => resolve21(false)));
|
|
548
|
+
return;
|
|
549
|
+
}
|
|
550
|
+
const child = spawn(process.platform === "win32" ? "where" : "which", [binary], { stdio: "ignore" });
|
|
551
|
+
child.on("close", (code) => resolve21(code === 0));
|
|
552
|
+
});
|
|
553
|
+
if (!binaryExists2)
|
|
554
|
+
return "not-found";
|
|
555
|
+
if (agent !== "claude")
|
|
556
|
+
return "ok";
|
|
839
557
|
return new Promise((resolve21) => {
|
|
840
|
-
const child =
|
|
558
|
+
const child = spawn(binary, ["auth", "status", "--json"], {
|
|
841
559
|
stdio: ["ignore", "pipe", "pipe"]
|
|
842
560
|
});
|
|
843
561
|
let stdout = "";
|
|
@@ -858,51 +576,75 @@ function checkClaudeAuth(binary) {
|
|
|
858
576
|
done = true;
|
|
859
577
|
clearTimeout(timer);
|
|
860
578
|
if (code !== 0) {
|
|
861
|
-
resolve21("unauthenticated");
|
|
862
|
-
return;
|
|
863
|
-
}
|
|
864
|
-
try {
|
|
865
|
-
const status = JSON.parse(stdout);
|
|
866
|
-
resolve21(status.loggedIn ? "ok" : "unauthenticated");
|
|
867
|
-
} catch {
|
|
868
|
-
resolve21("unauthenticated");
|
|
869
|
-
}
|
|
870
|
-
});
|
|
871
|
-
});
|
|
872
|
-
}
|
|
873
|
-
var init_check_claude_auth = __esm({
|
|
874
|
-
"packages/experience-design-system-generation/dist/src/services/agent/helpers/check-claude-auth.js"() {
|
|
875
|
-
"use strict";
|
|
876
|
-
}
|
|
877
|
-
});
|
|
878
|
-
|
|
879
|
-
// packages/experience-design-system-generation/dist/src/services/agent/helpers/check-agent-auth.js
|
|
880
|
-
import { spawn as spawn3 } from "node:child_process";
|
|
881
|
-
async function checkAgentAuth(agent) {
|
|
882
|
-
const binary = resolveAgentBinary(agent);
|
|
883
|
-
const binaryExists2 = await new Promise((resolve21) => {
|
|
884
|
-
if (binary.startsWith("/")) {
|
|
885
|
-
import("node:fs/promises").then((fs2) => fs2.access(binary).then(() => resolve21(true), () => resolve21(false)));
|
|
886
|
-
return;
|
|
887
|
-
}
|
|
888
|
-
const child = spawn3(process.platform === "win32" ? "where" : "which", [binary], { stdio: "ignore" });
|
|
889
|
-
child.on("close", (code) => resolve21(code === 0));
|
|
579
|
+
resolve21("unauthenticated");
|
|
580
|
+
return;
|
|
581
|
+
}
|
|
582
|
+
try {
|
|
583
|
+
const status = JSON.parse(stdout);
|
|
584
|
+
resolve21(status.loggedIn ? "ok" : "unauthenticated");
|
|
585
|
+
} catch {
|
|
586
|
+
resolve21("unauthenticated");
|
|
587
|
+
}
|
|
588
|
+
});
|
|
890
589
|
});
|
|
891
|
-
if (!binaryExists2)
|
|
892
|
-
return "not-found";
|
|
893
|
-
if (agent !== "claude")
|
|
894
|
-
return "ok";
|
|
895
|
-
return checkClaudeAuth(binary);
|
|
896
590
|
}
|
|
897
|
-
|
|
898
|
-
|
|
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"() {
|
|
899
615
|
"use strict";
|
|
900
|
-
|
|
901
|
-
|
|
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";
|
|
902
644
|
}
|
|
903
645
|
});
|
|
904
646
|
|
|
905
|
-
// packages/experience-design-system-generation/dist/src/
|
|
647
|
+
// packages/experience-design-system-generation/dist/src/agent-invoker.js
|
|
906
648
|
function createLocalCliAgentInvoker(options = {}) {
|
|
907
649
|
const { onDebugEvent } = options;
|
|
908
650
|
return {
|
|
@@ -914,310 +656,381 @@ function createLocalCliAgentInvoker(options = {}) {
|
|
|
914
656
|
}
|
|
915
657
|
};
|
|
916
658
|
}
|
|
917
|
-
var
|
|
918
|
-
"packages/experience-design-system-generation/dist/src/
|
|
659
|
+
var init_agent_invoker = __esm({
|
|
660
|
+
"packages/experience-design-system-generation/dist/src/agent-invoker.js"() {
|
|
919
661
|
"use strict";
|
|
920
|
-
|
|
921
|
-
init_check_agent_auth();
|
|
662
|
+
init_agent_runner();
|
|
922
663
|
}
|
|
923
664
|
});
|
|
924
665
|
|
|
925
|
-
// packages/experience-design-system-generation/dist/src/
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
};
|
|
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
|
+
`;
|
|
937
677
|
}
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
init_execute_generation_orchestrator();
|
|
943
|
-
init_local_cli_agent_invoker();
|
|
944
|
-
}
|
|
945
|
-
});
|
|
678
|
+
async function buildPrompt(options) {
|
|
679
|
+
const skillContent = options.skillContentOverride ?? await readSkillFile(options.skill, options.skillPathOverride);
|
|
680
|
+
const preamble = buildPreamble(options);
|
|
681
|
+
return `${preamble}
|
|
946
682
|
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
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})`);
|
|
964
699
|
}
|
|
700
|
+
dir = parent;
|
|
965
701
|
}
|
|
966
|
-
return -1;
|
|
967
702
|
}
|
|
968
|
-
function
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
for (const raw of stdout.split("\n")) {
|
|
972
|
-
const line = raw.trim();
|
|
973
|
-
if (!line.startsWith("{"))
|
|
974
|
-
continue;
|
|
975
|
-
const end = findJsonObjectEnd(line);
|
|
976
|
-
if (end === -1) {
|
|
977
|
-
warnings.push(`unparseable line: ${line.slice(0, 120)}`);
|
|
978
|
-
continue;
|
|
979
|
-
}
|
|
980
|
-
let parsed;
|
|
703
|
+
async function readSkillFile(skill, override) {
|
|
704
|
+
if (override) {
|
|
705
|
+
const skillPath2 = resolve(override);
|
|
981
706
|
try {
|
|
982
|
-
|
|
707
|
+
return await readFile2(skillPath2, "utf8");
|
|
983
708
|
} catch {
|
|
984
|
-
|
|
985
|
-
continue;
|
|
986
|
-
}
|
|
987
|
-
const trailing = line.slice(end + 1);
|
|
988
|
-
if (trailing.trim()) {
|
|
989
|
-
warnings.push(`ignored trailing content after JSON: ${trailing.trim().slice(0, 120)}`);
|
|
990
|
-
}
|
|
991
|
-
if (typeof parsed === "object" && parsed !== null && "tool" in parsed) {
|
|
992
|
-
objects.push(parsed);
|
|
709
|
+
throw new Error(`custom prompt file not found (skill: ${skill}, path: ${skillPath2})`);
|
|
993
710
|
}
|
|
994
711
|
}
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
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})`);
|
|
1000
717
|
}
|
|
1001
|
-
}
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
const
|
|
1006
|
-
const
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
if (
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
} else if (tool === "exclude_prop") {
|
|
1046
|
-
if (typeof rec.prop !== "string" || !rec.prop) {
|
|
1047
|
-
warnings.push("exclude_prop missing prop name \u2014 skipped");
|
|
1048
|
-
continue;
|
|
1049
|
-
}
|
|
1050
|
-
calls.push({ tool: "exclude_prop", prop: rec.prop, reason: typeof rec.reason === "string" ? rec.reason : "" });
|
|
1051
|
-
} else if (tool === "classify_component") {
|
|
1052
|
-
const call = { tool: "classify_component" };
|
|
1053
|
-
if (typeof rec.description === "string")
|
|
1054
|
-
call.description = rec.description;
|
|
1055
|
-
if (typeof rec.rationale === "object" && rec.rationale !== null) {
|
|
1056
|
-
const r = rec.rationale;
|
|
1057
|
-
const rationale = {};
|
|
1058
|
-
if (typeof r.description === "string")
|
|
1059
|
-
rationale.description = r.description;
|
|
1060
|
-
if (typeof r.props === "string")
|
|
1061
|
-
rationale.props = r.props;
|
|
1062
|
-
if (typeof r.slots === "string")
|
|
1063
|
-
rationale.slots = r.slots;
|
|
1064
|
-
if (Object.keys(rationale).length > 0)
|
|
1065
|
-
call.rationale = rationale;
|
|
1066
|
-
}
|
|
1067
|
-
calls.push(call);
|
|
1068
|
-
} else if (tool === "classify_slot") {
|
|
1069
|
-
if (typeof rec.slot !== "string" || !rec.slot) {
|
|
1070
|
-
warnings.push("classify_slot missing slot name \u2014 skipped");
|
|
1071
|
-
continue;
|
|
1072
|
-
}
|
|
1073
|
-
const call = { tool: "classify_slot", slot: rec.slot };
|
|
1074
|
-
if (typeof rec.required === "boolean")
|
|
1075
|
-
call.required = rec.required;
|
|
1076
|
-
if (Array.isArray(rec.allowed_components) && rec.allowed_components.every((v) => typeof v === "string")) {
|
|
1077
|
-
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
|
+
}
|
|
1078
762
|
}
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
call.rationale = rec.rationale;
|
|
1083
|
-
calls.push(call);
|
|
763
|
+
}
|
|
764
|
+
if (Object.keys(filteredProps).length > 0) {
|
|
765
|
+
result[componentName] = { ...component, $properties: filteredProps };
|
|
1084
766
|
}
|
|
1085
767
|
}
|
|
1086
|
-
return {
|
|
768
|
+
return { filtered: result, kinds: [...kinds].sort(), hasUnscoped };
|
|
1087
769
|
}
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
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
|
+
\`\`\``);
|
|
1096
786
|
}
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
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));
|
|
1116
844
|
} else {
|
|
1117
|
-
|
|
845
|
+
sections.push(renderTokenCandidateSection(null, index));
|
|
1118
846
|
}
|
|
1119
847
|
}
|
|
1120
|
-
calls.push(call);
|
|
1121
848
|
}
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
}
|
|
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(", ")}
|
|
1132
867
|
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
continue;
|
|
1148
|
-
}
|
|
1149
|
-
if (!("value" in rec)) {
|
|
1150
|
-
warnings.push(`set_token '${rec.path}': missing value \u2014 skipped`);
|
|
1151
|
-
continue;
|
|
1152
|
-
}
|
|
1153
|
-
const call = { tool: "set_token", path: rec.path, type: rec.type, value: rec.value };
|
|
1154
|
-
if (typeof rec.description === "string")
|
|
1155
|
-
call.description = rec.description;
|
|
1156
|
-
calls.push(call);
|
|
1157
|
-
} else if (rec.tool === "set_group") {
|
|
1158
|
-
if (typeof rec.path !== "string" || !rec.path) {
|
|
1159
|
-
warnings.push("set_group missing path \u2014 skipped");
|
|
1160
|
-
continue;
|
|
1161
|
-
}
|
|
1162
|
-
const call = { tool: "set_group", path: rec.path };
|
|
1163
|
-
if (typeof rec.description === "string")
|
|
1164
|
-
call.description = rec.description;
|
|
1165
|
-
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
|
+
\`\`\``);
|
|
1166
882
|
}
|
|
1167
883
|
}
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
"use strict";
|
|
1174
|
-
init_read_tool_call_objects();
|
|
1175
|
-
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);
|
|
1176
889
|
}
|
|
1177
|
-
|
|
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:
|
|
1178
982
|
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
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.`;
|
|
1182
994
|
}
|
|
1183
|
-
function
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
warnings.push(`map_token_prop '${rec.component}.${String(rec.prop)}': missing or empty token_allowed \u2014 skipped`);
|
|
1212
|
-
continue;
|
|
1213
|
-
}
|
|
1214
|
-
calls.push({ tool: "map_token_prop", component: rec.component, prop: rec.prop, token_allowed: rec.token_allowed });
|
|
1215
|
-
}
|
|
1216
|
-
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.`;
|
|
1217
1023
|
}
|
|
1218
|
-
var
|
|
1219
|
-
|
|
1024
|
+
var SKILL_FILES;
|
|
1025
|
+
var init_prompt_builder = __esm({
|
|
1026
|
+
"packages/experience-design-system-generation/dist/src/prompt-builder.js"() {
|
|
1220
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
|
+
};
|
|
1221
1034
|
}
|
|
1222
1035
|
});
|
|
1223
1036
|
|
|
@@ -1234,17 +1047,14 @@ var init_progress = __esm({
|
|
|
1234
1047
|
// packages/experience-design-system-generation/dist/src/index.js
|
|
1235
1048
|
var src_exports = {};
|
|
1236
1049
|
__export(src_exports, {
|
|
1237
|
-
AGENT_BINARIES: () => AGENT_BINARIES,
|
|
1238
1050
|
AGENT_NAMES: () => AGENT_NAMES,
|
|
1239
1051
|
DEFAULT_AGENT_NAME: () => DEFAULT_AGENT_NAME,
|
|
1240
1052
|
agentSupportsBedrock: () => agentSupportsBedrock,
|
|
1241
|
-
buildArgs: () =>
|
|
1053
|
+
buildArgs: () => buildArgs,
|
|
1242
1054
|
buildPrompt: () => buildPrompt,
|
|
1243
1055
|
checkAgentAuth: () => checkAgentAuth,
|
|
1244
|
-
createGenerationEndpoint: () => createGenerationEndpoint,
|
|
1245
1056
|
createLocalCliAgentInvoker: () => createLocalCliAgentInvoker,
|
|
1246
1057
|
describeAgentFailure: () => describeAgentFailure,
|
|
1247
|
-
executeGenerationOrchestrator: () => executeGenerationOrchestrator,
|
|
1248
1058
|
extractSentinelOutput: () => extractSentinelOutput,
|
|
1249
1059
|
formatCustomPromptBanner: () => formatCustomPromptBanner,
|
|
1250
1060
|
formatGenerateProgressLine: () => formatGenerateProgressLine,
|
|
@@ -1252,9 +1062,9 @@ __export(src_exports, {
|
|
|
1252
1062
|
parseMapTokenPropToolCallLines: () => parseMapTokenPropToolCallLines,
|
|
1253
1063
|
parseSelectToolCallLines: () => parseSelectToolCallLines,
|
|
1254
1064
|
parseTokenToolCallLines: () => parseTokenToolCallLines,
|
|
1255
|
-
parseToolCallLines: () =>
|
|
1065
|
+
parseToolCallLines: () => parseToolCallLines,
|
|
1256
1066
|
resolveAgentModel: () => resolveAgentModel,
|
|
1257
|
-
resolveBinary: () =>
|
|
1067
|
+
resolveBinary: () => resolveBinary,
|
|
1258
1068
|
resolveSkillPath: () => resolveSkillPath,
|
|
1259
1069
|
runAgent: () => runAgent
|
|
1260
1070
|
});
|
|
@@ -1262,19 +1072,10 @@ var init_src = __esm({
|
|
|
1262
1072
|
"packages/experience-design-system-generation/dist/src/index.js"() {
|
|
1263
1073
|
"use strict";
|
|
1264
1074
|
init_agent_names();
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
init_resolve_agent_binary();
|
|
1269
|
-
init_check_agent_auth();
|
|
1270
|
-
init_run_agent();
|
|
1271
|
-
init_parse_prop_tool_calls();
|
|
1272
|
-
init_parse_select_tool_calls();
|
|
1273
|
-
init_parse_token_tool_calls();
|
|
1274
|
-
init_parse_map_token_tool_calls();
|
|
1275
|
-
init_build_prompt();
|
|
1075
|
+
init_agent_runner();
|
|
1076
|
+
init_agent_invoker();
|
|
1077
|
+
init_prompt_builder();
|
|
1276
1078
|
init_progress();
|
|
1277
|
-
init_local_cli_agent_invoker();
|
|
1278
1079
|
}
|
|
1279
1080
|
});
|
|
1280
1081
|
|
|
@@ -1412,8 +1213,8 @@ function makeSessionTimestamp() {
|
|
|
1412
1213
|
const override = process.env["EDSI_DEBUG_TS"];
|
|
1413
1214
|
if (override) return override;
|
|
1414
1215
|
const now = /* @__PURE__ */ new Date();
|
|
1415
|
-
const
|
|
1416
|
-
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`;
|
|
1417
1218
|
}
|
|
1418
1219
|
function initDebugLogger(opts) {
|
|
1419
1220
|
if (singleton) return singleton;
|
|
@@ -2210,8 +2011,8 @@ function deleteRawTokensForSession(db, sessionId2) {
|
|
|
2210
2011
|
}
|
|
2211
2012
|
function createRawTokenGroups(db, sessionId2, groups) {
|
|
2212
2013
|
const insertGroup = db.prepare(`INSERT INTO raw_token_groups (session_id, path, description) VALUES (?, ?, ?)`);
|
|
2213
|
-
for (const
|
|
2214
|
-
insertGroup.run(sessionId2,
|
|
2014
|
+
for (const group2 of groups) {
|
|
2015
|
+
insertGroup.run(sessionId2, group2.path, group2.$description ?? null);
|
|
2215
2016
|
}
|
|
2216
2017
|
}
|
|
2217
2018
|
function createRawTokens(db, sessionId2, tokens) {
|
|
@@ -5109,7 +4910,7 @@ async function readFileInline(path) {
|
|
|
5109
4910
|
return parts.filter(Boolean).join("\n\n");
|
|
5110
4911
|
}
|
|
5111
4912
|
function printFallbackInstructions(options) {
|
|
5112
|
-
const binary =
|
|
4913
|
+
const binary = resolveBinary(options.agent);
|
|
5113
4914
|
const skillPath = resolveSkillPath(options.skill);
|
|
5114
4915
|
const lines = [
|
|
5115
4916
|
`Error: agent '${options.agent}' not found in $PATH (looked for binary: ${binary}).`,
|
|
@@ -5324,7 +5125,7 @@ ${outputBuf}`);
|
|
|
5324
5125
|
lastError = describeAgentFailure(result);
|
|
5325
5126
|
continue;
|
|
5326
5127
|
}
|
|
5327
|
-
const { calls, warnings } =
|
|
5128
|
+
const { calls, warnings } = parseToolCallLines(result.stdout);
|
|
5328
5129
|
if (calls.length === 0) {
|
|
5329
5130
|
lastError = describeAgentFailure(result);
|
|
5330
5131
|
continue;
|
|
@@ -5570,7 +5371,7 @@ async function runGenerateSkill(skill, opts, verbose = false) {
|
|
|
5570
5371
|
process.stdout.write(prompt + "\n");
|
|
5571
5372
|
await exitWithAnalytics(0);
|
|
5572
5373
|
}
|
|
5573
|
-
const binary =
|
|
5374
|
+
const binary = resolveBinary(agent);
|
|
5574
5375
|
if (!await assertBinaryInPath(binary)) {
|
|
5575
5376
|
printFallbackInstructions({
|
|
5576
5377
|
agent,
|
|
@@ -7090,24 +6891,24 @@ function parseEdsiError(rawInput) {
|
|
|
7090
6891
|
}
|
|
7091
6892
|
}
|
|
7092
6893
|
const cleaned = stripLambdaLogPrefix(body);
|
|
7093
|
-
const
|
|
7094
|
-
const bindingFromJson = typeof
|
|
6894
|
+
const json2 = parseJsonBody(cleaned) ?? parseJsonBody(body);
|
|
6895
|
+
const bindingFromJson = typeof json2?.message === "string" ? parseBindingDiagnostics(json2.message) : null;
|
|
7095
6896
|
if (bindingFromJson) {
|
|
7096
6897
|
return {
|
|
7097
|
-
code: bindingFromJson.code ??
|
|
6898
|
+
code: bindingFromJson.code ?? json2?.code ?? null,
|
|
7098
6899
|
message: bindingFromJson.message ?? cleaned,
|
|
7099
6900
|
cycle: null,
|
|
7100
6901
|
raw: false,
|
|
7101
6902
|
...bindingFromJson.diagnostics ? { diagnostics: bindingFromJson.diagnostics } : {}
|
|
7102
6903
|
};
|
|
7103
6904
|
}
|
|
7104
|
-
if (
|
|
6905
|
+
if (json2 && (json2.code || json2.message || json2.cycle)) {
|
|
7105
6906
|
return {
|
|
7106
|
-
code:
|
|
7107
|
-
message:
|
|
7108
|
-
cycle:
|
|
6907
|
+
code: json2.code ?? null,
|
|
6908
|
+
message: json2.message ?? (cleaned || prefix),
|
|
6909
|
+
cycle: json2.cycle ?? null,
|
|
7109
6910
|
raw: false,
|
|
7110
|
-
...
|
|
6911
|
+
...json2.diagnostics ? { diagnostics: json2.diagnostics } : {}
|
|
7111
6912
|
};
|
|
7112
6913
|
}
|
|
7113
6914
|
const binding = parseBindingDiagnostics(cleaned);
|
|
@@ -8647,8 +8448,8 @@ async function resolveSession(sessionFlag, command) {
|
|
|
8647
8448
|
}
|
|
8648
8449
|
function rebuildDTCGTree(groups, tokens) {
|
|
8649
8450
|
const root = {};
|
|
8650
|
-
for (const
|
|
8651
|
-
const segments =
|
|
8451
|
+
for (const group2 of groups) {
|
|
8452
|
+
const segments = group2.path.split(".");
|
|
8652
8453
|
let node = root;
|
|
8653
8454
|
for (const seg of segments) {
|
|
8654
8455
|
if (typeof node[seg] !== "object" || node[seg] === null) {
|
|
@@ -8656,8 +8457,8 @@ function rebuildDTCGTree(groups, tokens) {
|
|
|
8656
8457
|
}
|
|
8657
8458
|
node = node[seg];
|
|
8658
8459
|
}
|
|
8659
|
-
if (
|
|
8660
|
-
node["$description"] =
|
|
8460
|
+
if (group2.$description) {
|
|
8461
|
+
node["$description"] = group2.$description;
|
|
8661
8462
|
}
|
|
8662
8463
|
}
|
|
8663
8464
|
for (const token of tokens) {
|
|
@@ -9231,7 +9032,7 @@ ${defaultDiagnostics.map((diagnostic) => ` ${diagnostic}`).join("\n")}
|
|
|
9231
9032
|
return;
|
|
9232
9033
|
}
|
|
9233
9034
|
}
|
|
9234
|
-
const binary =
|
|
9035
|
+
const binary = resolveBinary(agent);
|
|
9235
9036
|
if (!await assertBinaryInPath(binary)) {
|
|
9236
9037
|
die(
|
|
9237
9038
|
`Error: agent '${agent}' not found in $PATH (looked for binary: ${binary}).
|
|
@@ -9400,6 +9201,214 @@ var init_run_teaser = __esm({
|
|
|
9400
9201
|
}
|
|
9401
9202
|
});
|
|
9402
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
|
+
|
|
9403
9412
|
// packages/experience-design-system-cli-legacy/src/tui/use-blinking-cursor.ts
|
|
9404
9413
|
import { useEffect as useEffect2, useState as useState3 } from "react";
|
|
9405
9414
|
function useBlinkingCursor() {
|
|
@@ -9419,8 +9428,8 @@ var init_use_blinking_cursor = __esm({
|
|
|
9419
9428
|
// packages/experience-design-system-cli-legacy/src/runs/path-prompt.tsx
|
|
9420
9429
|
import { useState as useState4 } from "react";
|
|
9421
9430
|
import { Box as Box6, Text as Text7 } from "ink";
|
|
9422
|
-
import { readdirSync } from "node:fs";
|
|
9423
|
-
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";
|
|
9424
9433
|
import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
9425
9434
|
function autocomplete(partial) {
|
|
9426
9435
|
if (!partial) return null;
|
|
@@ -9429,19 +9438,19 @@ function autocomplete(partial) {
|
|
|
9429
9438
|
const base = basename2(normalized);
|
|
9430
9439
|
let entries;
|
|
9431
9440
|
try {
|
|
9432
|
-
entries =
|
|
9441
|
+
entries = readdirSync2(dir);
|
|
9433
9442
|
} catch {
|
|
9434
9443
|
return null;
|
|
9435
9444
|
}
|
|
9436
9445
|
const matches = entries.filter((e) => e.startsWith(base));
|
|
9437
9446
|
if (matches.length === 0) return null;
|
|
9438
|
-
if (matches.length === 1) return
|
|
9447
|
+
if (matches.length === 1) return join11(dir, matches[0]);
|
|
9439
9448
|
let prefix = matches[0];
|
|
9440
9449
|
for (const m of matches) {
|
|
9441
9450
|
while (!m.startsWith(prefix)) prefix = prefix.slice(0, -1);
|
|
9442
9451
|
if (!prefix) break;
|
|
9443
9452
|
}
|
|
9444
|
-
return prefix.length > base.length ?
|
|
9453
|
+
return prefix.length > base.length ? join11(dir, prefix) : null;
|
|
9445
9454
|
}
|
|
9446
9455
|
function PathPrompt({
|
|
9447
9456
|
defaultPath,
|
|
@@ -9506,12 +9515,12 @@ var init_path_prompt = __esm({
|
|
|
9506
9515
|
|
|
9507
9516
|
// packages/experience-design-system-cli-legacy/src/runs/save-path-resolver.ts
|
|
9508
9517
|
import { access as access4 } from "node:fs/promises";
|
|
9509
|
-
import { join as
|
|
9518
|
+
import { join as join12 } from "node:path";
|
|
9510
9519
|
async function listConflictingFiles(path) {
|
|
9511
9520
|
const conflicts = [];
|
|
9512
9521
|
for (const name of SAVE_FILES) {
|
|
9513
9522
|
try {
|
|
9514
|
-
await access4(
|
|
9523
|
+
await access4(join12(path, name));
|
|
9515
9524
|
conflicts.push(name);
|
|
9516
9525
|
} catch {
|
|
9517
9526
|
}
|
|
@@ -9531,7 +9540,7 @@ function buildTimestampedSubdir(base, now = /* @__PURE__ */ new Date()) {
|
|
|
9531
9540
|
const hh = pad2(now.getHours());
|
|
9532
9541
|
const mm = pad2(now.getMinutes());
|
|
9533
9542
|
const ss = pad2(now.getSeconds());
|
|
9534
|
-
return
|
|
9543
|
+
return join12(base, `dsi-${y}${m}${d}-${hh}${mm}${ss}`);
|
|
9535
9544
|
}
|
|
9536
9545
|
var SAVE_FILES;
|
|
9537
9546
|
var init_save_path_resolver = __esm({
|
|
@@ -9543,7 +9552,7 @@ var init_save_path_resolver = __esm({
|
|
|
9543
9552
|
|
|
9544
9553
|
// packages/experience-design-system-cli-legacy/src/runs/store.ts
|
|
9545
9554
|
import { readFile as readFile12, writeFile as writeFile4, mkdir as mkdir4, rename } from "node:fs/promises";
|
|
9546
|
-
import { join as
|
|
9555
|
+
import { join as join13 } from "node:path";
|
|
9547
9556
|
import { homedir as homedir6 } from "node:os";
|
|
9548
9557
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
9549
9558
|
function encodeBase32(bytes, length) {
|
|
@@ -9639,8 +9648,8 @@ var init_store = __esm({
|
|
|
9639
9648
|
RUNS_FILE_VERSION = 3;
|
|
9640
9649
|
RUNS_FILE_CAP = 200;
|
|
9641
9650
|
READABLE_VERSIONS = /* @__PURE__ */ new Set([1, 2, 3]);
|
|
9642
|
-
RUNS_DIR =
|
|
9643
|
-
RUNS_PATH =
|
|
9651
|
+
RUNS_DIR = join13(homedir6(), ".config", "experiences");
|
|
9652
|
+
RUNS_PATH = join13(RUNS_DIR, "runs.json");
|
|
9644
9653
|
CROCKFORD = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
|
|
9645
9654
|
}
|
|
9646
9655
|
});
|
|
@@ -9797,7 +9806,7 @@ var init_WelcomeStep = __esm({
|
|
|
9797
9806
|
import { useState as useState6, useEffect as useEffect3 } from "react";
|
|
9798
9807
|
import { Box as Box9, Text as Text10 } from "ink";
|
|
9799
9808
|
import { promises as fs } from "node:fs";
|
|
9800
|
-
import { join as
|
|
9809
|
+
import { join as join14 } from "node:path";
|
|
9801
9810
|
import { jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
9802
9811
|
async function countFiles(dir) {
|
|
9803
9812
|
const counts = {
|
|
@@ -9821,7 +9830,7 @@ async function countFiles(dir) {
|
|
|
9821
9830
|
await Promise.all(
|
|
9822
9831
|
entries.map(async (entry) => {
|
|
9823
9832
|
if (IGNORE_DIRS.has(entry)) return;
|
|
9824
|
-
const full =
|
|
9833
|
+
const full = join14(current, entry);
|
|
9825
9834
|
let stat7;
|
|
9826
9835
|
try {
|
|
9827
9836
|
stat7 = await fs.stat(full);
|
|
@@ -10897,6 +10906,7 @@ function WizardPreviewStep({
|
|
|
10897
10906
|
environmentId,
|
|
10898
10907
|
stepNumber,
|
|
10899
10908
|
totalSteps,
|
|
10909
|
+
droppedTokenDefaults = [],
|
|
10900
10910
|
onConfirm,
|
|
10901
10911
|
onEdit,
|
|
10902
10912
|
onQuit
|
|
@@ -10989,6 +10999,13 @@ function WizardPreviewStep({
|
|
|
10989
10999
|
}
|
|
10990
11000
|
)
|
|
10991
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
|
+
] }),
|
|
10992
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." }) }),
|
|
10993
11010
|
/* @__PURE__ */ jsx19(SpaceEnvironment, { spaceId, environmentId }),
|
|
10994
11011
|
/* @__PURE__ */ jsxs16(Box16, { gap: 3, marginTop: 1, children: [
|
|
@@ -11040,7 +11057,7 @@ function DoneStep({
|
|
|
11040
11057
|
});
|
|
11041
11058
|
const totalFailed = componentTypes.failed + designTokens.failed;
|
|
11042
11059
|
const totalPushed = componentTypes.created + componentTypes.updated + componentTypes.removed + designTokens.created + designTokens.updated + designTokens.removed;
|
|
11043
|
-
const success = totalFailed === 0;
|
|
11060
|
+
const success = totalFailed === 0 && (summary?.failed ?? 0) === 0;
|
|
11044
11061
|
function EntityRows({ entity, label }) {
|
|
11045
11062
|
return /* @__PURE__ */ jsxs17(Fragment5, { children: [
|
|
11046
11063
|
entity.created > 0 && /* @__PURE__ */ jsxs17(Box17, { gap: 1, children: [
|
|
@@ -11086,7 +11103,7 @@ function DoneStep({
|
|
|
11086
11103
|
] });
|
|
11087
11104
|
}
|
|
11088
11105
|
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", gap: 1, paddingX: 2, paddingY: 1, children: [
|
|
11089
|
-
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" }),
|
|
11090
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: [
|
|
11091
11108
|
/* @__PURE__ */ jsx20(EntityRows, { entity: componentTypes, label: "Component Type" }),
|
|
11092
11109
|
/* @__PURE__ */ jsx20(EntityRows, { entity: designTokens, label: "Design Token" }),
|
|
@@ -11506,8 +11523,8 @@ var init_types = __esm({
|
|
|
11506
11523
|
});
|
|
11507
11524
|
|
|
11508
11525
|
// packages/experience-design-system-extraction/dist/src/extract/tsx-shared.js
|
|
11509
|
-
import { existsSync as
|
|
11510
|
-
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";
|
|
11511
11528
|
import { Node, Project, SyntaxKind } from "ts-morph";
|
|
11512
11529
|
import ts from "typescript";
|
|
11513
11530
|
function createTsxProject(filePaths) {
|
|
@@ -11706,8 +11723,8 @@ function findNearestTsConfigPath(filePath) {
|
|
|
11706
11723
|
let currentDir = dirname6(filePath);
|
|
11707
11724
|
while (true) {
|
|
11708
11725
|
for (const candidateName of ["tsconfig.json", "jsconfig.json"]) {
|
|
11709
|
-
const candidatePath =
|
|
11710
|
-
if (
|
|
11726
|
+
const candidatePath = join15(currentDir, candidateName);
|
|
11727
|
+
if (existsSync4(candidatePath)) {
|
|
11711
11728
|
nearestTsConfigPathCache.set(filePath, candidatePath);
|
|
11712
11729
|
return candidatePath;
|
|
11713
11730
|
}
|
|
@@ -11763,12 +11780,12 @@ function resolveImportSourcePath(basePath) {
|
|
|
11763
11780
|
`${basePath}.tsx`,
|
|
11764
11781
|
`${basePath}.js`,
|
|
11765
11782
|
`${basePath}.jsx`,
|
|
11766
|
-
|
|
11767
|
-
|
|
11768
|
-
|
|
11769
|
-
|
|
11783
|
+
join15(basePath, "index.ts"),
|
|
11784
|
+
join15(basePath, "index.tsx"),
|
|
11785
|
+
join15(basePath, "index.js"),
|
|
11786
|
+
join15(basePath, "index.jsx")
|
|
11770
11787
|
];
|
|
11771
|
-
return candidates.find((candidatePath) =>
|
|
11788
|
+
return candidates.find((candidatePath) => existsSync4(candidatePath));
|
|
11772
11789
|
}
|
|
11773
11790
|
function findProjectSourceFileByImportPath(project, resolvedPath) {
|
|
11774
11791
|
const candidatePaths = [
|
|
@@ -11777,10 +11794,10 @@ function findProjectSourceFileByImportPath(project, resolvedPath) {
|
|
|
11777
11794
|
`${resolvedPath}.tsx`,
|
|
11778
11795
|
`${resolvedPath}.js`,
|
|
11779
11796
|
`${resolvedPath}.jsx`,
|
|
11780
|
-
|
|
11781
|
-
|
|
11782
|
-
|
|
11783
|
-
|
|
11797
|
+
join15(resolvedPath, "index.ts"),
|
|
11798
|
+
join15(resolvedPath, "index.tsx"),
|
|
11799
|
+
join15(resolvedPath, "index.js"),
|
|
11800
|
+
join15(resolvedPath, "index.jsx")
|
|
11784
11801
|
];
|
|
11785
11802
|
for (const candidatePath of candidatePaths) {
|
|
11786
11803
|
const sourceFile = project.getSourceFile(candidatePath);
|
|
@@ -11801,10 +11818,10 @@ function findWorkspacePackageEntrySourceFile(originSourceFile, moduleSpecifier)
|
|
|
11801
11818
|
if (!packageRootDir)
|
|
11802
11819
|
return void 0;
|
|
11803
11820
|
const preferredEntryPaths = [
|
|
11804
|
-
|
|
11805
|
-
|
|
11806
|
-
|
|
11807
|
-
|
|
11821
|
+
join15(packageRootDir, "src/index.ts"),
|
|
11822
|
+
join15(packageRootDir, "src/index.tsx"),
|
|
11823
|
+
join15(packageRootDir, "index.ts"),
|
|
11824
|
+
join15(packageRootDir, "index.tsx")
|
|
11808
11825
|
];
|
|
11809
11826
|
for (const entryPath of preferredEntryPaths) {
|
|
11810
11827
|
const entrySourceFile = project.getSourceFile(entryPath);
|
|
@@ -11812,7 +11829,7 @@ function findWorkspacePackageEntrySourceFile(originSourceFile, moduleSpecifier)
|
|
|
11812
11829
|
return entrySourceFile;
|
|
11813
11830
|
}
|
|
11814
11831
|
}
|
|
11815
|
-
return candidateSourceFiles.find((sourceFile) => sourceFile.getDirectoryPath() ===
|
|
11832
|
+
return candidateSourceFiles.find((sourceFile) => sourceFile.getDirectoryPath() === join15(packageRootDir, "src"));
|
|
11816
11833
|
}
|
|
11817
11834
|
function getWorkspacePackageManifestForSourceFile(sourceFile) {
|
|
11818
11835
|
const packageRootDir = findNearestPackageRootDir(sourceFile.getFilePath());
|
|
@@ -11821,7 +11838,7 @@ function getWorkspacePackageManifestForSourceFile(sourceFile) {
|
|
|
11821
11838
|
if (workspacePackageManifestCache.has(packageRootDir)) {
|
|
11822
11839
|
return workspacePackageManifestCache.get(packageRootDir) ?? void 0;
|
|
11823
11840
|
}
|
|
11824
|
-
const packageJsonPath =
|
|
11841
|
+
const packageJsonPath = join15(packageRootDir, "package.json");
|
|
11825
11842
|
try {
|
|
11826
11843
|
const packageJson = JSON.parse(readFileSync5(packageJsonPath, "utf8"));
|
|
11827
11844
|
const manifest = typeof packageJson.name === "string" ? { name: packageJson.name, rootDir: packageRootDir } : null;
|
|
@@ -11838,7 +11855,7 @@ function findNearestPackageRootDir(filePath) {
|
|
|
11838
11855
|
}
|
|
11839
11856
|
let currentDir = dirname6(filePath);
|
|
11840
11857
|
while (true) {
|
|
11841
|
-
if (
|
|
11858
|
+
if (existsSync4(join15(currentDir, "package.json"))) {
|
|
11842
11859
|
packageRootByFilePathCache.set(filePath, currentDir);
|
|
11843
11860
|
return currentDir;
|
|
11844
11861
|
}
|
|
@@ -14900,8 +14917,8 @@ var init_vue_tsx = __esm({
|
|
|
14900
14917
|
});
|
|
14901
14918
|
|
|
14902
14919
|
// packages/experience-design-system-extraction/dist/src/extract/resolve-local-module.js
|
|
14903
|
-
import { existsSync as
|
|
14904
|
-
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";
|
|
14905
14922
|
function resolveLocalModule(importingFilePath, specifier, options = {}) {
|
|
14906
14923
|
const basePath = resolve13(dirname7(importingFilePath), specifier);
|
|
14907
14924
|
const candidates = [
|
|
@@ -14910,18 +14927,18 @@ function resolveLocalModule(importingFilePath, specifier, options = {}) {
|
|
|
14910
14927
|
`${basePath}.ts`,
|
|
14911
14928
|
`${basePath}.mjs`,
|
|
14912
14929
|
`${basePath}.cjs`,
|
|
14913
|
-
|
|
14914
|
-
|
|
14915
|
-
|
|
14916
|
-
|
|
14930
|
+
join16(basePath, "index.js"),
|
|
14931
|
+
join16(basePath, "index.ts"),
|
|
14932
|
+
join16(basePath, "index.mjs"),
|
|
14933
|
+
join16(basePath, "index.cjs")
|
|
14917
14934
|
];
|
|
14918
14935
|
for (const candidate of candidates) {
|
|
14919
|
-
if (
|
|
14936
|
+
if (existsSync5(candidate) && statSync2(candidate).isFile())
|
|
14920
14937
|
return candidate;
|
|
14921
14938
|
}
|
|
14922
14939
|
if (options.allowJavaScriptExtensionFallback && basePath.endsWith(".js")) {
|
|
14923
14940
|
const tsPath = `${basePath.slice(0, -".js".length)}.ts`;
|
|
14924
|
-
if (
|
|
14941
|
+
if (existsSync5(tsPath) && statSync2(tsPath).isFile())
|
|
14925
14942
|
return tsPath;
|
|
14926
14943
|
}
|
|
14927
14944
|
return null;
|
|
@@ -14952,9 +14969,9 @@ var init_resolve_type_property = __esm({
|
|
|
14952
14969
|
|
|
14953
14970
|
// packages/experience-design-system-extraction/dist/src/extract/vue.js
|
|
14954
14971
|
import os from "node:os";
|
|
14955
|
-
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";
|
|
14956
14973
|
import { readFile as readFile15 } from "node:fs/promises";
|
|
14957
|
-
import { existsSync as
|
|
14974
|
+
import { existsSync as existsSync6, readFileSync as readFileSync6, readdirSync as readdirSync3, statSync as statSync3 } from "node:fs";
|
|
14958
14975
|
import { parse as parseSFC } from "@vue/compiler-sfc";
|
|
14959
14976
|
import { Project as Project3, Node as Node6 } from "ts-morph";
|
|
14960
14977
|
async function extractVueComponents(filePaths, onProgress) {
|
|
@@ -15167,11 +15184,11 @@ function findWorkspaceRoot(startDir) {
|
|
|
15167
15184
|
return workspaceRootCache.get(startDir);
|
|
15168
15185
|
let dir = startDir;
|
|
15169
15186
|
while (true) {
|
|
15170
|
-
const pkgJsonPath =
|
|
15171
|
-
if (
|
|
15187
|
+
const pkgJsonPath = join17(dir, "package.json");
|
|
15188
|
+
if (existsSync6(pkgJsonPath)) {
|
|
15172
15189
|
try {
|
|
15173
15190
|
const pkg4 = JSON.parse(readFileSync6(pkgJsonPath, "utf8"));
|
|
15174
|
-
if (pkg4.workspaces ||
|
|
15191
|
+
if (pkg4.workspaces || existsSync6(join17(dir, "pnpm-workspace.yaml"))) {
|
|
15175
15192
|
workspaceRootCache.set(startDir, dir);
|
|
15176
15193
|
return dir;
|
|
15177
15194
|
}
|
|
@@ -15191,8 +15208,8 @@ function getWorkspacePackageDirs(workspaceRoot) {
|
|
|
15191
15208
|
return workspacePackageDirsCache.get(workspaceRoot);
|
|
15192
15209
|
}
|
|
15193
15210
|
const packageMap = /* @__PURE__ */ new Map();
|
|
15194
|
-
const packagesDir =
|
|
15195
|
-
if (!
|
|
15211
|
+
const packagesDir = join17(workspaceRoot, "packages");
|
|
15212
|
+
if (!existsSync6(packagesDir)) {
|
|
15196
15213
|
workspacePackageDirsCache.set(workspaceRoot, packageMap);
|
|
15197
15214
|
return packageMap;
|
|
15198
15215
|
}
|
|
@@ -15201,12 +15218,12 @@ function getWorkspacePackageDirs(workspaceRoot) {
|
|
|
15201
15218
|
return;
|
|
15202
15219
|
let entries;
|
|
15203
15220
|
try {
|
|
15204
|
-
entries =
|
|
15221
|
+
entries = readdirSync3(dir);
|
|
15205
15222
|
} catch {
|
|
15206
15223
|
return;
|
|
15207
15224
|
}
|
|
15208
|
-
const pkgJsonPath =
|
|
15209
|
-
if (
|
|
15225
|
+
const pkgJsonPath = join17(dir, "package.json");
|
|
15226
|
+
if (existsSync6(pkgJsonPath)) {
|
|
15210
15227
|
try {
|
|
15211
15228
|
const pkg4 = JSON.parse(readFileSync6(pkgJsonPath, "utf8"));
|
|
15212
15229
|
if (typeof pkg4.name === "string") {
|
|
@@ -15218,7 +15235,7 @@ function getWorkspacePackageDirs(workspaceRoot) {
|
|
|
15218
15235
|
for (const entry of entries) {
|
|
15219
15236
|
if (entry === "node_modules" || entry === ".git" || entry.startsWith("."))
|
|
15220
15237
|
continue;
|
|
15221
|
-
const entryPath =
|
|
15238
|
+
const entryPath = join17(dir, entry);
|
|
15222
15239
|
try {
|
|
15223
15240
|
const stat7 = statSync3(entryPath);
|
|
15224
15241
|
if (stat7.isDirectory()) {
|
|
@@ -15258,28 +15275,28 @@ function resolveWorkspaceVueImport(specifier, importingFilePath) {
|
|
|
15258
15275
|
const packageDir = packageDirs.get(packageName);
|
|
15259
15276
|
if (!packageDir)
|
|
15260
15277
|
return null;
|
|
15261
|
-
const pkgJsonPath =
|
|
15278
|
+
const pkgJsonPath = join17(packageDir, "package.json");
|
|
15262
15279
|
try {
|
|
15263
15280
|
const pkg4 = JSON.parse(readFileSync6(pkgJsonPath, "utf8"));
|
|
15264
15281
|
if (pkg4.exports && subpath !== ".") {
|
|
15265
15282
|
const exportValue = pkg4.exports[subpath];
|
|
15266
15283
|
if (typeof exportValue === "string" && exportValue.endsWith(".vue")) {
|
|
15267
15284
|
const resolved = resolve14(packageDir, exportValue);
|
|
15268
|
-
if (
|
|
15285
|
+
if (existsSync6(resolved))
|
|
15269
15286
|
return resolved;
|
|
15270
15287
|
}
|
|
15271
15288
|
}
|
|
15272
15289
|
if (subpath !== ".") {
|
|
15273
15290
|
const subDir = resolve14(packageDir, subpath.replace(/^\.\//, ""));
|
|
15274
|
-
for (const base of [
|
|
15275
|
-
const subPkgPath =
|
|
15276
|
-
if (
|
|
15291
|
+
for (const base of [join17(packageDir, "src", subpath.replace(/^\.\//, "")), subDir]) {
|
|
15292
|
+
const subPkgPath = join17(base, "package.json");
|
|
15293
|
+
if (existsSync6(subPkgPath)) {
|
|
15277
15294
|
try {
|
|
15278
15295
|
const subPkg = JSON.parse(readFileSync6(subPkgPath, "utf8"));
|
|
15279
15296
|
const main = subPkg.main || subPkg.module;
|
|
15280
15297
|
if (typeof main === "string" && main.endsWith(".vue")) {
|
|
15281
15298
|
const resolved = resolve14(base, main);
|
|
15282
|
-
if (
|
|
15299
|
+
if (existsSync6(resolved))
|
|
15283
15300
|
return resolved;
|
|
15284
15301
|
}
|
|
15285
15302
|
} catch {
|
|
@@ -15291,7 +15308,7 @@ function resolveWorkspaceVueImport(specifier, importingFilePath) {
|
|
|
15291
15308
|
const main = pkg4.main || pkg4.module;
|
|
15292
15309
|
if (typeof main === "string" && main.endsWith(".vue")) {
|
|
15293
15310
|
const resolved = resolve14(packageDir, main);
|
|
15294
|
-
if (
|
|
15311
|
+
if (existsSync6(resolved))
|
|
15295
15312
|
return resolved;
|
|
15296
15313
|
}
|
|
15297
15314
|
}
|
|
@@ -15733,7 +15750,7 @@ var init_astro = __esm({
|
|
|
15733
15750
|
});
|
|
15734
15751
|
|
|
15735
15752
|
// packages/experience-design-system-extraction/dist/src/extract/web-components.js
|
|
15736
|
-
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";
|
|
15737
15754
|
import { Project as Project5, Node as Node8, SyntaxKind as SyntaxKind6 } from "ts-morph";
|
|
15738
15755
|
function normalizeComponentName(input) {
|
|
15739
15756
|
return input.replace(/[^a-zA-Z0-9]/g, "").toLowerCase();
|
|
@@ -16386,14 +16403,14 @@ function resolveImportSourcePath2(fromFilePath, specifier) {
|
|
|
16386
16403
|
if (!specifier.startsWith(spectrumPrefix)) {
|
|
16387
16404
|
return null;
|
|
16388
16405
|
}
|
|
16389
|
-
const packagesMarker = `${
|
|
16406
|
+
const packagesMarker = `${join18("2nd-gen", "packages")}${fromFilePath.includes("\\") ? "\\" : "/"}`;
|
|
16390
16407
|
const markerIndex = fromFilePath.lastIndexOf(packagesMarker);
|
|
16391
16408
|
if (markerIndex === -1) {
|
|
16392
16409
|
return null;
|
|
16393
16410
|
}
|
|
16394
16411
|
const packagesRoot = fromFilePath.slice(0, markerIndex + packagesMarker.length - 1);
|
|
16395
16412
|
const componentPath = specifier.slice(spectrumPrefix.length);
|
|
16396
|
-
return
|
|
16413
|
+
return join18(packagesRoot, "core", "components", componentPath, "index.ts");
|
|
16397
16414
|
}
|
|
16398
16415
|
function getImportedBaseClass(classDecl, project, visitedFiles) {
|
|
16399
16416
|
const extendsClause = classDecl.getHeritageClauses().find((clause) => clause.getToken() === SyntaxKind6.ExtendsKeyword);
|
|
@@ -16660,8 +16677,8 @@ var init_scoring = __esm({
|
|
|
16660
16677
|
|
|
16661
16678
|
// packages/experience-design-system-extraction/dist/src/extract/svelte.js
|
|
16662
16679
|
import os3 from "node:os";
|
|
16663
|
-
import { basename as basename6, dirname as dirname10, resolve as resolve16, join as
|
|
16664
|
-
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";
|
|
16665
16682
|
import { createRequire } from "node:module";
|
|
16666
16683
|
import { parse as parseSvelte } from "svelte/compiler";
|
|
16667
16684
|
import { Project as Project6, Node as Node9, ScriptTarget, ModuleKind, ts as ts2 } from "ts-morph";
|
|
@@ -16794,8 +16811,8 @@ async function maybeRunResolveUnreachableRetry(components, warnings, retryContex
|
|
|
16794
16811
|
function findNearestTsconfig(startDir) {
|
|
16795
16812
|
let dir = startDir;
|
|
16796
16813
|
for (let i = 0; i < 16; i++) {
|
|
16797
|
-
const candidate =
|
|
16798
|
-
if (
|
|
16814
|
+
const candidate = join19(dir, "tsconfig.json");
|
|
16815
|
+
if (existsSync7(candidate))
|
|
16799
16816
|
return candidate;
|
|
16800
16817
|
const parent = dirname10(dir);
|
|
16801
16818
|
if (!parent || parent === dir)
|
|
@@ -16930,29 +16947,29 @@ function locateDtsForSpecifier(req, specifier, parentFile) {
|
|
|
16930
16947
|
const seedDir = resolvedJs ? dirname10(resolvedJs) : dirname10(parentFile);
|
|
16931
16948
|
const pkgRoot = findPackageRootForSpecifier(seedDir, specifier);
|
|
16932
16949
|
if (pkgRoot) {
|
|
16933
|
-
const pkgJsonPath =
|
|
16934
|
-
if (
|
|
16950
|
+
const pkgJsonPath = join19(pkgRoot, "package.json");
|
|
16951
|
+
if (existsSync7(pkgJsonPath)) {
|
|
16935
16952
|
try {
|
|
16936
16953
|
const pkgRaw = readFileSync7(pkgJsonPath, "utf-8");
|
|
16937
16954
|
const pkg4 = JSON.parse(pkgRaw);
|
|
16938
16955
|
const typesField = pkg4.types ?? pkg4.typings;
|
|
16939
16956
|
if (typeof typesField === "string") {
|
|
16940
16957
|
const candidate = resolve16(pkgRoot, typesField);
|
|
16941
|
-
if (
|
|
16958
|
+
if (existsSync7(candidate))
|
|
16942
16959
|
return candidate;
|
|
16943
16960
|
}
|
|
16944
16961
|
const exportsTypes = extractTypesFromExports(pkg4.exports);
|
|
16945
16962
|
if (exportsTypes) {
|
|
16946
16963
|
const candidate = resolve16(pkgRoot, exportsTypes);
|
|
16947
|
-
if (
|
|
16964
|
+
if (existsSync7(candidate))
|
|
16948
16965
|
return candidate;
|
|
16949
16966
|
}
|
|
16950
16967
|
} catch {
|
|
16951
16968
|
}
|
|
16952
16969
|
}
|
|
16953
16970
|
for (const entry of ["index.d.ts", "index.d.mts"]) {
|
|
16954
|
-
const candidate =
|
|
16955
|
-
if (
|
|
16971
|
+
const candidate = join19(pkgRoot, entry);
|
|
16972
|
+
if (existsSync7(candidate))
|
|
16956
16973
|
return candidate;
|
|
16957
16974
|
}
|
|
16958
16975
|
}
|
|
@@ -16960,7 +16977,7 @@ function locateDtsForSpecifier(req, specifier, parentFile) {
|
|
|
16960
16977
|
const noExt = resolvedJs.replace(/\.(m?js|cjs)$/, "");
|
|
16961
16978
|
for (const ext of [".d.ts", ".d.mts"]) {
|
|
16962
16979
|
const candidate = `${noExt}${ext}`;
|
|
16963
|
-
if (
|
|
16980
|
+
if (existsSync7(candidate))
|
|
16964
16981
|
return candidate;
|
|
16965
16982
|
}
|
|
16966
16983
|
}
|
|
@@ -16969,9 +16986,9 @@ function locateDtsForSpecifier(req, specifier, parentFile) {
|
|
|
16969
16986
|
function findPackageRootForSpecifier(seedDir, specifier) {
|
|
16970
16987
|
let dir = seedDir;
|
|
16971
16988
|
for (let i = 0; i < 32; i++) {
|
|
16972
|
-
if (
|
|
16989
|
+
if (existsSync7(join19(dir, "package.json"))) {
|
|
16973
16990
|
try {
|
|
16974
|
-
const pkgRaw = readFileSync7(
|
|
16991
|
+
const pkgRaw = readFileSync7(join19(dir, "package.json"), "utf-8");
|
|
16975
16992
|
const pkg4 = JSON.parse(pkgRaw);
|
|
16976
16993
|
if (pkg4.name === specifier)
|
|
16977
16994
|
return dir;
|
|
@@ -18943,9 +18960,9 @@ var init_wizard_generate_progress = __esm({
|
|
|
18943
18960
|
});
|
|
18944
18961
|
|
|
18945
18962
|
// packages/experience-design-system-cli-legacy/src/import/tui/spawn-generate.ts
|
|
18946
|
-
import { spawn as
|
|
18963
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
18947
18964
|
function spawnGenerateChild(opts) {
|
|
18948
|
-
const child =
|
|
18965
|
+
const child = spawn2(opts.command, opts.args);
|
|
18949
18966
|
let stdout = "";
|
|
18950
18967
|
let stderr = "";
|
|
18951
18968
|
child.stdout?.on("data", (d) => {
|
|
@@ -18984,6 +19001,88 @@ var init_spawn_generate = __esm({
|
|
|
18984
19001
|
}
|
|
18985
19002
|
});
|
|
18986
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
|
+
|
|
18987
19086
|
// packages/experience-design-system-cli-legacy/src/analyze/composite-closure.ts
|
|
18988
19087
|
function edgesFrom(component, known) {
|
|
18989
19088
|
if (!component) return [];
|
|
@@ -20325,17 +20424,17 @@ function buildCycleUnits(slotCycles) {
|
|
|
20325
20424
|
const groups = /* @__PURE__ */ new Map();
|
|
20326
20425
|
for (const node of parent.keys()) {
|
|
20327
20426
|
const root = find(node);
|
|
20328
|
-
let
|
|
20329
|
-
if (!
|
|
20330
|
-
|
|
20331
|
-
groups.set(root,
|
|
20427
|
+
let group2 = groups.get(root);
|
|
20428
|
+
if (!group2) {
|
|
20429
|
+
group2 = /* @__PURE__ */ new Set();
|
|
20430
|
+
groups.set(root, group2);
|
|
20332
20431
|
}
|
|
20333
|
-
|
|
20432
|
+
group2.add(node);
|
|
20334
20433
|
}
|
|
20335
20434
|
const out = /* @__PURE__ */ new Map();
|
|
20336
|
-
for (const
|
|
20337
|
-
for (const node of
|
|
20338
|
-
out.set(node,
|
|
20435
|
+
for (const group2 of groups.values()) {
|
|
20436
|
+
for (const node of group2) {
|
|
20437
|
+
out.set(node, group2);
|
|
20339
20438
|
}
|
|
20340
20439
|
}
|
|
20341
20440
|
return out;
|
|
@@ -21829,10 +21928,10 @@ function swapValues(values, firstIndex, secondIndex) {
|
|
|
21829
21928
|
[next[firstIndex], next[secondIndex]] = [next[secondIndex], next[firstIndex]];
|
|
21830
21929
|
return next;
|
|
21831
21930
|
}
|
|
21832
|
-
function parseToState(
|
|
21931
|
+
function parseToState(json2) {
|
|
21833
21932
|
let parsed;
|
|
21834
21933
|
try {
|
|
21835
|
-
parsed = JSON.parse(
|
|
21934
|
+
parsed = JSON.parse(json2);
|
|
21836
21935
|
} catch (e) {
|
|
21837
21936
|
return {
|
|
21838
21937
|
state: { componentDescription: "", props: [], slots: [] },
|
|
@@ -22685,11 +22784,11 @@ function FieldEditor({
|
|
|
22685
22784
|
setEditorState(next);
|
|
22686
22785
|
onChange(serializeState(next, value));
|
|
22687
22786
|
};
|
|
22688
|
-
const canonicalize = React14.useCallback((
|
|
22787
|
+
const canonicalize = React14.useCallback((json2) => {
|
|
22689
22788
|
try {
|
|
22690
|
-
return JSON.stringify(JSON.parse(
|
|
22789
|
+
return JSON.stringify(JSON.parse(json2));
|
|
22691
22790
|
} catch {
|
|
22692
|
-
return `__unparseable__:${
|
|
22791
|
+
return `__unparseable__:${json2}`;
|
|
22693
22792
|
}
|
|
22694
22793
|
}, []);
|
|
22695
22794
|
const initialStateRef = React14.useRef(initialState);
|
|
@@ -23263,14 +23362,14 @@ function FieldEditor({
|
|
|
23263
23362
|
})();
|
|
23264
23363
|
const rows = [];
|
|
23265
23364
|
rows.push({ kind: "component-description" });
|
|
23266
|
-
for (const
|
|
23267
|
-
if (
|
|
23365
|
+
for (const group2 of propGroups.filter((candidate) => candidate.kind !== "hidden")) {
|
|
23366
|
+
if (group2.indexes.length === 0) continue;
|
|
23268
23367
|
rows.push({
|
|
23269
23368
|
kind: "header",
|
|
23270
|
-
label: `${
|
|
23271
|
-
section:
|
|
23369
|
+
label: `${group2.label} (${group2.indexes.length}) `,
|
|
23370
|
+
section: group2.kind
|
|
23272
23371
|
});
|
|
23273
|
-
|
|
23372
|
+
group2.indexes.forEach((idx) => rows.push({ kind: "prop", idx }));
|
|
23274
23373
|
}
|
|
23275
23374
|
if (slots.length > 0) {
|
|
23276
23375
|
rows.push({
|
|
@@ -23280,7 +23379,7 @@ function FieldEditor({
|
|
|
23280
23379
|
});
|
|
23281
23380
|
slots.forEach((_, i) => rows.push({ kind: "slot", idx: i }));
|
|
23282
23381
|
}
|
|
23283
|
-
const hiddenGroup = propGroups.find((
|
|
23382
|
+
const hiddenGroup = propGroups.find((group2) => group2.kind === "hidden");
|
|
23284
23383
|
if (hiddenGroup && hiddenGroup.indexes.length > 0) {
|
|
23285
23384
|
rows.push({
|
|
23286
23385
|
kind: "header",
|
|
@@ -27022,26 +27121,8 @@ var init_runScopeGate = __esm({
|
|
|
27022
27121
|
}
|
|
27023
27122
|
});
|
|
27024
27123
|
|
|
27025
|
-
// packages/experience-design-system-cli-legacy/src/helpers/build-contentful-management-client.ts
|
|
27026
|
-
import { createClient as createClient2 } from "contentful-management";
|
|
27027
|
-
function buildContentfulManagementClient(opts) {
|
|
27028
|
-
return createClient2(
|
|
27029
|
-
{
|
|
27030
|
-
accessToken: opts.cmaToken,
|
|
27031
|
-
...opts.host ? { host: toConfiguredHost(opts.host) } : {}
|
|
27032
|
-
},
|
|
27033
|
-
{ type: "plain" }
|
|
27034
|
-
);
|
|
27035
|
-
}
|
|
27036
|
-
var init_build_contentful_management_client = __esm({
|
|
27037
|
-
"packages/experience-design-system-cli-legacy/src/helpers/build-contentful-management-client.ts"() {
|
|
27038
|
-
"use strict";
|
|
27039
|
-
init_host_utils();
|
|
27040
|
-
}
|
|
27041
|
-
});
|
|
27042
|
-
|
|
27043
27124
|
// packages/experience-design-system-cli-legacy/src/helpers/fetch-existing-contentful-entities.ts
|
|
27044
|
-
import { fetchAll } from "contentful-management";
|
|
27125
|
+
import { fetchAll as fetchAll2 } from "contentful-management";
|
|
27045
27126
|
async function fetchExistingContentfulEntitiesFromContentful(client2, params) {
|
|
27046
27127
|
const componentScope = {
|
|
27047
27128
|
spaceId: params.spaceId,
|
|
@@ -27053,8 +27134,8 @@ async function fetchExistingContentfulEntitiesFromContentful(client2, params) {
|
|
|
27053
27134
|
environmentId: params.environmentId,
|
|
27054
27135
|
query: { cursor: true, limit: 1e3 }
|
|
27055
27136
|
};
|
|
27056
|
-
const components = await
|
|
27057
|
-
const tokens = await
|
|
27137
|
+
const components = await fetchAll2(client2.component.getMany, componentScope);
|
|
27138
|
+
const tokens = await fetchAll2(client2.designToken.getMany, tokenScope);
|
|
27058
27139
|
return { components, tokens };
|
|
27059
27140
|
}
|
|
27060
27141
|
var init_fetch_existing_contentful_entities = __esm({
|
|
@@ -27065,7 +27146,7 @@ var init_fetch_existing_contentful_entities = __esm({
|
|
|
27065
27146
|
|
|
27066
27147
|
// packages/experience-design-system-cli-legacy/src/helpers/fetch-and-persist-existing-contentful-entities.ts
|
|
27067
27148
|
import { writeFile as writeFile5 } from "node:fs/promises";
|
|
27068
|
-
import { join as
|
|
27149
|
+
import { join as join20 } from "node:path";
|
|
27069
27150
|
async function fetchAndPersistExistingContentfulEntities(params) {
|
|
27070
27151
|
const t0 = Date.now();
|
|
27071
27152
|
try {
|
|
@@ -27077,7 +27158,7 @@ async function fetchAndPersistExistingContentfulEntities(params) {
|
|
|
27077
27158
|
spaceId: params.spaceId,
|
|
27078
27159
|
environmentId: params.environmentId
|
|
27079
27160
|
});
|
|
27080
|
-
const path =
|
|
27161
|
+
const path = join20(params.outDir, ".existing-entities.json");
|
|
27081
27162
|
await writeFile5(path, JSON.stringify(entities, null, 2), "utf8");
|
|
27082
27163
|
return { ok: true, path, durationMs: Date.now() - t0, entities };
|
|
27083
27164
|
} catch (error) {
|
|
@@ -27254,11 +27335,11 @@ __export(WizardApp_exports, {
|
|
|
27254
27335
|
});
|
|
27255
27336
|
import { useEffect as useEffect15, useRef as useRef10, useState as useState23 } from "react";
|
|
27256
27337
|
import { Box as Box42, Text as Text46 } from "ink";
|
|
27257
|
-
import { join as
|
|
27258
|
-
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";
|
|
27259
27340
|
import { access as access7, stat as stat5, writeFile as writeFile6 } from "node:fs/promises";
|
|
27260
27341
|
import { tmpdir } from "node:os";
|
|
27261
|
-
import { execFile as execFile2, spawn as
|
|
27342
|
+
import { execFile as execFile2, spawn as spawn3 } from "node:child_process";
|
|
27262
27343
|
import { mkdir as mkdir5 } from "node:fs/promises";
|
|
27263
27344
|
import { buildCDF as buildCDF3, validateCDF as validateCDF3, validateSlotReferences as validateSlotReferences2 } from "@contentful/experience-design-system-types";
|
|
27264
27345
|
import { jsx as jsx50, jsxs as jsxs43 } from "react/jsx-runtime";
|
|
@@ -27320,7 +27401,7 @@ function runCli(args) {
|
|
|
27320
27401
|
}
|
|
27321
27402
|
function runSpawnedCli(args, onStderr, onStdout) {
|
|
27322
27403
|
return new Promise((res) => {
|
|
27323
|
-
const child =
|
|
27404
|
+
const child = spawn3("node", args);
|
|
27324
27405
|
let stdout = "";
|
|
27325
27406
|
let stderr = "";
|
|
27326
27407
|
child.stdout.on("data", (d) => {
|
|
@@ -27395,7 +27476,7 @@ function WizardApp({
|
|
|
27395
27476
|
const logInit = useRef10(false);
|
|
27396
27477
|
const initialAgentAuthRef = useRef10(initialAgentAuth ?? null);
|
|
27397
27478
|
if (!logInit.current) {
|
|
27398
|
-
|
|
27479
|
+
writeFileSync2(WIZARD_LOG, `--- experiences import session ${(/* @__PURE__ */ new Date()).toISOString()} ---
|
|
27399
27480
|
`);
|
|
27400
27481
|
logInit.current = true;
|
|
27401
27482
|
}
|
|
@@ -27404,6 +27485,7 @@ function WizardApp({
|
|
|
27404
27485
|
tokensPath: ""
|
|
27405
27486
|
});
|
|
27406
27487
|
const allowEmptyDeleteAllRef = useRef10(false);
|
|
27488
|
+
const pushDebugRef = useRef10(null);
|
|
27407
27489
|
const generateChildRef = useRef10(null);
|
|
27408
27490
|
const generationCachePreflightRef = useRef10(null);
|
|
27409
27491
|
const selectionToReviewStartedAtRef = useRef10(null);
|
|
@@ -27422,7 +27504,7 @@ function WizardApp({
|
|
|
27422
27504
|
const rawTokensEntryReady = !!initialRawTokensPath;
|
|
27423
27505
|
const effectiveNoCache = resolveNoCacheForGenerate({ cliNoCache: noCache });
|
|
27424
27506
|
const initialStepResolved = rawTokensEntryReady ? initialProjectPath ? "path-validation" : "credentials" : initialProjectPath ? "token-input" : "welcome";
|
|
27425
|
-
const initialOutDir = initialProjectPath ?
|
|
27507
|
+
const initialOutDir = initialProjectPath ? join21(resolve17(initialProjectPath), ".contentful") : "";
|
|
27426
27508
|
const [state, setState] = useState23({
|
|
27427
27509
|
step: initialStepResolved,
|
|
27428
27510
|
agent: initialAgent ?? "claude",
|
|
@@ -27478,6 +27560,7 @@ function WizardApp({
|
|
|
27478
27560
|
existingEntitiesStatus: "idle",
|
|
27479
27561
|
lastRunId: null,
|
|
27480
27562
|
finalizeErrorBanner: null,
|
|
27563
|
+
droppedTokenDefaults: [],
|
|
27481
27564
|
finalReviewPassed: false
|
|
27482
27565
|
});
|
|
27483
27566
|
useEffect15(() => {
|
|
@@ -27620,7 +27703,7 @@ If you are using AWS Bedrock, run:
|
|
|
27620
27703
|
}
|
|
27621
27704
|
const sessionMatch = /^session=(.+)$/m.exec(result.stdout);
|
|
27622
27705
|
const tokenSessionId = sessionMatch ? sessionMatch[1].trim() : null;
|
|
27623
|
-
const tokensPath =
|
|
27706
|
+
const tokensPath = join21(outDir, "tokens.json");
|
|
27624
27707
|
const printArgs = ["print", "tokens", "--out", tokensPath];
|
|
27625
27708
|
if (tokenSessionId) printArgs.push("--session", tokenSessionId);
|
|
27626
27709
|
const r = await runCli(printArgs);
|
|
@@ -27642,7 +27725,7 @@ If you are using AWS Bedrock, run:
|
|
|
27642
27725
|
tokenGenerationStatus: "complete",
|
|
27643
27726
|
skipComponents: true,
|
|
27644
27727
|
acceptedCount: 0,
|
|
27645
|
-
outDir: state.outDir ||
|
|
27728
|
+
outDir: state.outDir || join21(process.cwd(), ".contentful")
|
|
27646
27729
|
});
|
|
27647
27730
|
update({ step: "credentials" });
|
|
27648
27731
|
return true;
|
|
@@ -27783,7 +27866,7 @@ If you are using AWS Bedrock, run:
|
|
|
27783
27866
|
return promise;
|
|
27784
27867
|
};
|
|
27785
27868
|
const runExtract = async (projectPath, showProgress = true) => {
|
|
27786
|
-
const outDir =
|
|
27869
|
+
const outDir = join21(resolve17(projectPath), ".contentful");
|
|
27787
27870
|
const existingEntitiesExpected = !state.credentialsSkipped && Boolean(state.spaceId && state.environmentId && state.cmaToken && projectPath);
|
|
27788
27871
|
update({
|
|
27789
27872
|
...showProgress ? { step: "extracting" } : {},
|
|
@@ -28458,12 +28541,30 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
|
|
|
28458
28541
|
void runSaveAndPush();
|
|
28459
28542
|
};
|
|
28460
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;
|
|
28461
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
|
+
});
|
|
28462
28564
|
update(buildSkippedPreviewTransition());
|
|
28463
28565
|
return;
|
|
28464
28566
|
}
|
|
28465
28567
|
update({ step: "previewing" });
|
|
28466
|
-
const resolvedHost = resolveWizardHost(host2);
|
|
28467
28568
|
try {
|
|
28468
28569
|
const client2 = new ImportApiClient({
|
|
28469
28570
|
cmaToken,
|
|
@@ -28471,6 +28572,7 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
|
|
|
28471
28572
|
environmentId,
|
|
28472
28573
|
host: resolvedHost
|
|
28473
28574
|
});
|
|
28575
|
+
pushDebug.event("Preview started", { note: `POST ${resolvedHost}/\u2026/design_systems/imports/preview` });
|
|
28474
28576
|
let components = [];
|
|
28475
28577
|
if (extractSessionId) {
|
|
28476
28578
|
const db = openPipelineDb();
|
|
@@ -28486,7 +28588,16 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
|
|
|
28486
28588
|
tokens = await readTokensFromPath("tokens", tokensPath);
|
|
28487
28589
|
}
|
|
28488
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
|
+
});
|
|
28489
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
|
+
});
|
|
28490
28601
|
if (extractSessionId) {
|
|
28491
28602
|
let needsRepreview = false;
|
|
28492
28603
|
const db = openPipelineDb();
|
|
@@ -28506,15 +28617,27 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
|
|
|
28506
28617
|
if (seededDefaults > 0) needsRepreview = true;
|
|
28507
28618
|
}
|
|
28508
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
|
+
});
|
|
28509
28623
|
components = loadCDFComponents(db, extractSessionId);
|
|
28510
28624
|
cdf = buildCDF3(components, toCDFTokens(tokens), { deleteAll: allowEmptyDeleteAllRef.current });
|
|
28511
28625
|
preview = await client2.previewImport(cdf);
|
|
28626
|
+
pushDebug.event("Server previewed the updated CDF", {
|
|
28627
|
+
data: summarizePreview(preview),
|
|
28628
|
+
requestId: client2.getLastRequestId()
|
|
28629
|
+
});
|
|
28512
28630
|
}
|
|
28513
28631
|
} finally {
|
|
28514
28632
|
db.close();
|
|
28515
28633
|
}
|
|
28516
28634
|
}
|
|
28517
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
|
+
});
|
|
28518
28641
|
update({
|
|
28519
28642
|
step: "done",
|
|
28520
28643
|
serverPreview: preview,
|
|
@@ -28526,14 +28649,44 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
|
|
|
28526
28649
|
});
|
|
28527
28650
|
return;
|
|
28528
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
|
+
});
|
|
28529
28676
|
update({
|
|
28530
28677
|
step: "preview-gate",
|
|
28531
28678
|
serverPreview: preview,
|
|
28532
|
-
cdf,
|
|
28679
|
+
cdf: cdfToPush,
|
|
28680
|
+
droppedTokenDefaults,
|
|
28533
28681
|
finalizeErrorBanner: null,
|
|
28534
28682
|
...clearedValidationErrorState()
|
|
28535
28683
|
});
|
|
28536
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
|
+
});
|
|
28537
28690
|
if (e instanceof ApiError) {
|
|
28538
28691
|
if (e.status === 401 || e.status === 403) {
|
|
28539
28692
|
let bodyMsg = "";
|
|
@@ -28596,7 +28749,18 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28596
28749
|
}
|
|
28597
28750
|
};
|
|
28598
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;
|
|
28599
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
|
+
});
|
|
28600
28764
|
update(buildSkippedPushTransition());
|
|
28601
28765
|
return;
|
|
28602
28766
|
}
|
|
@@ -28604,6 +28768,11 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28604
28768
|
const hasComponentChanges = preview.components.new.length > 0 || preview.components.changed.length > 0 || preview.components.removed.length > 0;
|
|
28605
28769
|
const hasTokenChanges = preview.tokens.new.length > 0 || preview.tokens.changed.length > 0 || preview.tokens.removed.length > 0;
|
|
28606
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
|
+
});
|
|
28607
28776
|
update({
|
|
28608
28777
|
step: "done",
|
|
28609
28778
|
pushResult: {
|
|
@@ -28616,6 +28785,11 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28616
28785
|
}
|
|
28617
28786
|
const cycles = detectSlotCycles(extractComponents(cdf));
|
|
28618
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
|
+
});
|
|
28619
28793
|
update({
|
|
28620
28794
|
step: "error",
|
|
28621
28795
|
errorStep: "apply",
|
|
@@ -28626,6 +28800,11 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28626
28800
|
}
|
|
28627
28801
|
const unresolvedSlotReferences = validateSlotReferences2(extractComponents(cdf));
|
|
28628
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
|
+
});
|
|
28629
28808
|
update({
|
|
28630
28809
|
step: "error",
|
|
28631
28810
|
errorStep: "apply",
|
|
@@ -28635,6 +28814,14 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28635
28814
|
return;
|
|
28636
28815
|
}
|
|
28637
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
|
+
});
|
|
28638
28825
|
try {
|
|
28639
28826
|
const resolvedHost = resolveWizardHost(host2);
|
|
28640
28827
|
const client2 = new ImportApiClient({
|
|
@@ -28644,6 +28831,11 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28644
28831
|
host: resolvedHost
|
|
28645
28832
|
});
|
|
28646
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
|
+
});
|
|
28647
28839
|
try {
|
|
28648
28840
|
logStep({
|
|
28649
28841
|
applyResponse: {
|
|
@@ -28660,9 +28852,15 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28660
28852
|
pushProgress: { kind: "queued", operationId: operation.sys.id }
|
|
28661
28853
|
});
|
|
28662
28854
|
let pollCount = 0;
|
|
28855
|
+
let lastPolledStatus = "";
|
|
28663
28856
|
operation = await client2.pollOperation(operation.sys.id, {
|
|
28664
28857
|
onProgress: (op) => {
|
|
28665
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
|
+
}
|
|
28666
28864
|
const s = op.summary;
|
|
28667
28865
|
if (s) {
|
|
28668
28866
|
const done = s.total - s.pending;
|
|
@@ -28767,6 +28965,29 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28767
28965
|
);
|
|
28768
28966
|
}
|
|
28769
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
|
+
});
|
|
28770
28991
|
update({ step: "done", pushResult });
|
|
28771
28992
|
} catch (e) {
|
|
28772
28993
|
let msg;
|
|
@@ -28777,6 +28998,14 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28777
28998
|
} else {
|
|
28778
28999
|
msg = "Push failed";
|
|
28779
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
|
+
});
|
|
28780
29009
|
update({
|
|
28781
29010
|
step: "error",
|
|
28782
29011
|
errorStep: "apply",
|
|
@@ -28788,7 +29017,7 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28788
29017
|
};
|
|
28789
29018
|
const runPrintFiles = async (extractSessionId, outDir, opts = {}) => {
|
|
28790
29019
|
update({ step: "printing" });
|
|
28791
|
-
const componentsPath =
|
|
29020
|
+
const componentsPath = join21(outDir, "components.json");
|
|
28792
29021
|
try {
|
|
28793
29022
|
const db = openPipelineDb();
|
|
28794
29023
|
let components = [];
|
|
@@ -28891,7 +29120,7 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28891
29120
|
if (tokenReuseChecked.current) return;
|
|
28892
29121
|
tokenReuseChecked.current = true;
|
|
28893
29122
|
const tokenNextStep = state.projectPath ? "path-validation" : "credentials";
|
|
28894
|
-
const existingTokensPath =
|
|
29123
|
+
const existingTokensPath = join21(state.outDir, "tokens.json");
|
|
28895
29124
|
if (effectiveNoCache) {
|
|
28896
29125
|
tokenGenerationPromiseRef.current = runAgentAuthCheck(tokenNextStep).then(
|
|
28897
29126
|
(ok2) => ok2 ? runGenerateTokens(state.rawTokensPath, state.outDir) : false
|
|
@@ -28942,7 +29171,7 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28942
29171
|
{
|
|
28943
29172
|
onContinue: (path) => {
|
|
28944
29173
|
const projectPath = normalizePath(path);
|
|
28945
|
-
const outDir =
|
|
29174
|
+
const outDir = join21(projectPath, ".contentful");
|
|
28946
29175
|
update({ step: "token-input", projectPath, outDir });
|
|
28947
29176
|
},
|
|
28948
29177
|
onQuit: () => process.exit(0)
|
|
@@ -29304,6 +29533,7 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
29304
29533
|
environmentId: state.environmentId,
|
|
29305
29534
|
stepNumber: totalSteps,
|
|
29306
29535
|
totalSteps,
|
|
29536
|
+
droppedTokenDefaults: state.droppedTokenDefaults,
|
|
29307
29537
|
onConfirm: (acknowledge) => {
|
|
29308
29538
|
void runPush(
|
|
29309
29539
|
state.cdf,
|
|
@@ -29440,6 +29670,7 @@ var init_WizardApp = __esm({
|
|
|
29440
29670
|
init_theme();
|
|
29441
29671
|
init_run_teaser();
|
|
29442
29672
|
init_debug_logger();
|
|
29673
|
+
init_push_debug_log();
|
|
29443
29674
|
init_credentials_store();
|
|
29444
29675
|
init_path_prompt();
|
|
29445
29676
|
init_save_path_resolver();
|
|
@@ -29468,6 +29699,8 @@ var init_WizardApp = __esm({
|
|
|
29468
29699
|
init_wizard_generate_progress();
|
|
29469
29700
|
init_spawn_generate();
|
|
29470
29701
|
init_tokens();
|
|
29702
|
+
init_dangling_token_defaults();
|
|
29703
|
+
init_fetch_existing_token_ids();
|
|
29471
29704
|
init_preview_utils();
|
|
29472
29705
|
init_db();
|
|
29473
29706
|
init_ScopeGateStep();
|
|
@@ -29484,7 +29717,7 @@ var init_WizardApp = __esm({
|
|
|
29484
29717
|
init_use_terminal_size();
|
|
29485
29718
|
init_render_with_goodbye();
|
|
29486
29719
|
SAVE_CONFIRMATION_DELAY_MS = 1e3;
|
|
29487
|
-
WIZARD_LOG =
|
|
29720
|
+
WIZARD_LOG = join21(tmpdir(), "experiences-import-wizard.log");
|
|
29488
29721
|
}
|
|
29489
29722
|
});
|
|
29490
29723
|
|
|
@@ -29615,7 +29848,7 @@ var init_agent_definitions = __esm({
|
|
|
29615
29848
|
});
|
|
29616
29849
|
|
|
29617
29850
|
// packages/experience-design-system-cli-legacy/src/setup/lib/shell.ts
|
|
29618
|
-
import { execFile as execFile3, spawn as
|
|
29851
|
+
import { execFile as execFile3, spawn as spawn4 } from "node:child_process";
|
|
29619
29852
|
import { access as access8 } from "node:fs/promises";
|
|
29620
29853
|
import { promisify as promisify2 } from "node:util";
|
|
29621
29854
|
async function binaryExists(name) {
|
|
@@ -29631,7 +29864,7 @@ async function pathExists3(path) {
|
|
|
29631
29864
|
}
|
|
29632
29865
|
function runSpawn(cmd, args, opts = {}) {
|
|
29633
29866
|
return new Promise((resolve21) => {
|
|
29634
|
-
const child =
|
|
29867
|
+
const child = spawn4(cmd, args, {
|
|
29635
29868
|
cwd: opts.cwd,
|
|
29636
29869
|
env: opts.env ?? process.env,
|
|
29637
29870
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -29664,7 +29897,7 @@ var init_shell = __esm({
|
|
|
29664
29897
|
});
|
|
29665
29898
|
|
|
29666
29899
|
// packages/experience-design-system-cli-legacy/src/setup/lib/checks.ts
|
|
29667
|
-
import { join as
|
|
29900
|
+
import { join as join22 } from "node:path";
|
|
29668
29901
|
function checkNodeVersion(nodeVersion = process.versions.node) {
|
|
29669
29902
|
const major = Number.parseInt(nodeVersion.split(".")[0], 10);
|
|
29670
29903
|
return {
|
|
@@ -29678,7 +29911,7 @@ async function detectNodeVersionManagers(homeDir, deps = {
|
|
|
29678
29911
|
binaryExists,
|
|
29679
29912
|
pathExists: pathExists3
|
|
29680
29913
|
}) {
|
|
29681
|
-
const nvmScript =
|
|
29914
|
+
const nvmScript = join22(homeDir, ".nvm", "nvm.sh");
|
|
29682
29915
|
return {
|
|
29683
29916
|
nvm: await deps.binaryExists("nvm") || await deps.pathExists(nvmScript),
|
|
29684
29917
|
fnm: await deps.binaryExists("fnm"),
|
|
@@ -29757,7 +29990,7 @@ var init_report = __esm({
|
|
|
29757
29990
|
|
|
29758
29991
|
// packages/experience-design-system-cli-legacy/src/doctor/checks.ts
|
|
29759
29992
|
import { homedir as homedir7 } from "node:os";
|
|
29760
|
-
import { join as
|
|
29993
|
+
import { join as join23 } from "node:path";
|
|
29761
29994
|
async function reportNode() {
|
|
29762
29995
|
section("Checking Node.js version");
|
|
29763
29996
|
const check = checkNodeVersion();
|
|
@@ -29808,12 +30041,12 @@ async function reportPnpm(pkgRoot) {
|
|
|
29808
30041
|
}
|
|
29809
30042
|
async function reportDependencies(pkgRoot) {
|
|
29810
30043
|
section("Checking dependencies (pnpm install)");
|
|
29811
|
-
if (!await pathExists3(
|
|
30044
|
+
if (!await pathExists3(join23(pkgRoot, "node_modules"))) {
|
|
29812
30045
|
info("node_modules not found \u2014 running pnpm install...");
|
|
29813
30046
|
} else {
|
|
29814
30047
|
info("Running pnpm install to ensure dependencies are up to date...");
|
|
29815
30048
|
}
|
|
29816
|
-
const check = await installDependencies(
|
|
30049
|
+
const check = await installDependencies(join23(pkgRoot, "..", ".."));
|
|
29817
30050
|
if (!check.passed) {
|
|
29818
30051
|
fail("pnpm install failed");
|
|
29819
30052
|
info("");
|
|
@@ -29830,7 +30063,7 @@ async function reportDependencies(pkgRoot) {
|
|
|
29830
30063
|
async function reportBuild(pkgRoot) {
|
|
29831
30064
|
section("Building CLI");
|
|
29832
30065
|
info("Running pnpm build...");
|
|
29833
|
-
const check = await buildCli(
|
|
30066
|
+
const check = await buildCli(join23(pkgRoot, "..", ".."));
|
|
29834
30067
|
if (!check.passed) {
|
|
29835
30068
|
fail("Build failed");
|
|
29836
30069
|
info("");
|
|
@@ -31045,9 +31278,9 @@ var init_SetupScreen = __esm({
|
|
|
31045
31278
|
|
|
31046
31279
|
// packages/experience-design-system-cli-legacy/src/setup/command.ts
|
|
31047
31280
|
import { readFileSync as readFileSync8 } from "node:fs";
|
|
31048
|
-
import { join as
|
|
31281
|
+
import { join as join24 } from "node:path";
|
|
31049
31282
|
function getCliVersion() {
|
|
31050
|
-
const pkg4 = JSON.parse(readFileSync8(
|
|
31283
|
+
const pkg4 = JSON.parse(readFileSync8(join24(findPkgRoot(), "package.json"), "utf8"));
|
|
31051
31284
|
return pkg4.version;
|
|
31052
31285
|
}
|
|
31053
31286
|
async function runSetup(opts) {
|
|
@@ -31059,7 +31292,7 @@ async function runSetup(opts) {
|
|
|
31059
31292
|
const { renderWithGoodbye: renderWithGoodbye2 } = await Promise.resolve().then(() => (init_render_with_goodbye(), render_with_goodbye_exports));
|
|
31060
31293
|
const { createElement: createElement6 } = await import("react");
|
|
31061
31294
|
const { SetupScreen: SetupScreen2 } = await Promise.resolve().then(() => (init_SetupScreen(), SetupScreen_exports));
|
|
31062
|
-
const repoRoot =
|
|
31295
|
+
const repoRoot = join24(findPkgRoot(), "..", "..");
|
|
31063
31296
|
const completion = { outcome: null };
|
|
31064
31297
|
let unmountInk = null;
|
|
31065
31298
|
const { waitUntilExit, unmount } = renderWithGoodbye2(
|
|
@@ -31260,15 +31493,15 @@ var init_apply_mapping = __esm({
|
|
|
31260
31493
|
});
|
|
31261
31494
|
|
|
31262
31495
|
// packages/experience-design-system-cli-legacy/src/analyze/composition/prompt-loader.ts
|
|
31263
|
-
import { existsSync as
|
|
31264
|
-
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";
|
|
31265
31498
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
31266
31499
|
function resolvePromptPath(fileName) {
|
|
31267
31500
|
const thisDir = dirname11(fileURLToPath3(import.meta.url));
|
|
31268
31501
|
let dir = thisDir;
|
|
31269
31502
|
for (; ; ) {
|
|
31270
|
-
const candidate =
|
|
31271
|
-
if (
|
|
31503
|
+
const candidate = join25(dir, "prompts");
|
|
31504
|
+
if (existsSync8(candidate)) return join25(candidate, fileName);
|
|
31272
31505
|
const parent = resolve18(dir, "..");
|
|
31273
31506
|
if (parent === dir) {
|
|
31274
31507
|
throw new Error(
|
|
@@ -31536,7 +31769,7 @@ var init_manifest_doc_evidence = __esm({
|
|
|
31536
31769
|
|
|
31537
31770
|
// packages/experience-design-system-cli-legacy/src/analyze/extract-command.ts
|
|
31538
31771
|
import { mkdir as mkdir6, readdir as readdir3, readFile as readFile18, stat as stat6 } from "node:fs/promises";
|
|
31539
|
-
import { isAbsolute as isAbsolute2, join as
|
|
31772
|
+
import { isAbsolute as isAbsolute2, join as join26, relative as relative2, resolve as resolve19 } from "node:path";
|
|
31540
31773
|
function resolveExtractNoCache(opts) {
|
|
31541
31774
|
return opts.noCache === true || opts.cache === false;
|
|
31542
31775
|
}
|
|
@@ -31574,7 +31807,7 @@ async function collectSourceFiles(directory, onProgress) {
|
|
|
31574
31807
|
const entries = await readdir3(currentDirectory, { withFileTypes: true });
|
|
31575
31808
|
const subdirs = [];
|
|
31576
31809
|
for (const entry of entries) {
|
|
31577
|
-
const fullPath =
|
|
31810
|
+
const fullPath = join26(currentDirectory, entry.name);
|
|
31578
31811
|
if (entry.isDirectory()) {
|
|
31579
31812
|
if (!IGNORED_DIRECTORY_NAMES.has(entry.name)) {
|
|
31580
31813
|
subdirs.push(fullPath);
|
|
@@ -31658,7 +31891,7 @@ function registerInternalExtractCommand(program) {
|
|
|
31658
31891
|
}
|
|
31659
31892
|
}
|
|
31660
31893
|
const projectRoot = resolve19(opts.project);
|
|
31661
|
-
const outDir =
|
|
31894
|
+
const outDir = join26(projectRoot, ".contentful");
|
|
31662
31895
|
let sourceDirectory;
|
|
31663
31896
|
if (opts.dir !== void 0) {
|
|
31664
31897
|
sourceDirectory = resolveFromProjectRoot(projectRoot, opts.dir);
|
|
@@ -32061,9 +32294,9 @@ __export(program_exports, {
|
|
|
32061
32294
|
resolveBedrockFromAncestors: () => resolveBedrockFromAncestors,
|
|
32062
32295
|
runBuild: () => runBuild
|
|
32063
32296
|
});
|
|
32064
|
-
import { spawn as
|
|
32297
|
+
import { spawn as spawn5 } from "node:child_process";
|
|
32065
32298
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
32066
|
-
import { dirname as dirname13, join as
|
|
32299
|
+
import { dirname as dirname13, join as join27, resolve as resolve20 } from "node:path";
|
|
32067
32300
|
import { readFileSync as readFileSync10 } from "node:fs";
|
|
32068
32301
|
import { Command } from "commander";
|
|
32069
32302
|
async function runBuild(opts) {
|
|
@@ -32096,7 +32329,7 @@ function registerBuildCommand(program) {
|
|
|
32096
32329
|
const pkgRoot = resolve20(dirname13(fileURLToPath4(import.meta.url)), "..", "..");
|
|
32097
32330
|
process.stderr.write("\u2699 Building from source...\n");
|
|
32098
32331
|
const { exitCode } = await runBuild({
|
|
32099
|
-
spawnFn: () =>
|
|
32332
|
+
spawnFn: () => spawn5("pnpm", ["build"], { cwd: pkgRoot, stdio: "inherit" }),
|
|
32100
32333
|
stderrWrite: (s) => process.stderr.write(s)
|
|
32101
32334
|
});
|
|
32102
32335
|
process.exit(exitCode);
|
|
@@ -32163,7 +32396,7 @@ var init_program = __esm({
|
|
|
32163
32396
|
init_analytics();
|
|
32164
32397
|
init_credentials_store();
|
|
32165
32398
|
init_cli_path();
|
|
32166
|
-
pkg3 = JSON.parse(readFileSync10(
|
|
32399
|
+
pkg3 = JSON.parse(readFileSync10(join27(findPkgRoot(), "package.json"), "utf8"));
|
|
32167
32400
|
}
|
|
32168
32401
|
});
|
|
32169
32402
|
|