@contentful/experience-design-system-cli 2.11.0 → 2.11.1-dev-build-96af281.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/package.json +1 -1
- package/dist/src/analyze/select-agent/command.js +9 -5
- package/dist/src/credentials-store.d.ts +2 -0
- package/dist/src/credentials-store.js +5 -1
- package/dist/src/generate/agent-runner.js +5 -2
- package/dist/src/generate/command.js +10 -6
- package/dist/src/setup/command.js +105 -35
- package/package.json +2 -2
package/dist/package.json
CHANGED
|
@@ -3,6 +3,7 @@ import { appendReviewEvent, getRefineArtifactsRoot, ensureRefineSession, getRefi
|
|
|
3
3
|
import { loadReviewInput } from '../select/parser.js';
|
|
4
4
|
import { buildPrompt } from '../../generate/prompt-builder.js';
|
|
5
5
|
import { parseSelectToolCallLines, runAgent } from '../../generate/agent-runner.js';
|
|
6
|
+
import { readExperiencesCredentials } from '../../credentials-store.js';
|
|
6
7
|
import { OutputFormatter, c } from '../../output/format.js';
|
|
7
8
|
import { buildRepoContextIndex, buildSelectionContext } from './context-builder.js';
|
|
8
9
|
import { isAbsolute, resolve } from 'node:path';
|
|
@@ -174,18 +175,21 @@ export function registerAnalyzeSelectAgentCommand(program) {
|
|
|
174
175
|
.description('Use an AI agent to select components for Contentful Experience Orchestration')
|
|
175
176
|
.option('--session <id>', 'Session ID from analyze extract (defaults to most recent)')
|
|
176
177
|
.option('--project-root <path>', 'Project root for resolving component source files')
|
|
177
|
-
.
|
|
178
|
+
.option('--agent <name>', 'Agent to use: claude, codex, opencode, cursor (defaults to value saved by experiences setup)')
|
|
178
179
|
.option('--model <name>', 'Model to use (defaults to a small/fast model per agent)')
|
|
179
180
|
.option('--verbose', 'Show full agent output including reasoning text')
|
|
180
181
|
.option('--dry-run', 'Print the prompt for the first component without invoking the agent')
|
|
181
182
|
.option('--exclude-invalid', 'Auto-reject components with validation errors instead of failing loud (LLM cannot fix structural issues)')
|
|
182
183
|
.action(async (opts) => {
|
|
183
|
-
|
|
184
|
-
|
|
184
|
+
const savedCreds = await readExperiencesCredentials();
|
|
185
|
+
const agentName = opts.agent ?? savedCreds.agent;
|
|
186
|
+
const model = opts.model ?? savedCreds.agentModel;
|
|
187
|
+
if (!agentName || !VALID_AGENTS.has(agentName)) {
|
|
188
|
+
process.stderr.write(`Error: no agent configured. Pass --agent <name> or run experiences setup. Accepted values: claude, codex, opencode, cursor\n`);
|
|
185
189
|
process.exit(1);
|
|
186
190
|
return;
|
|
187
191
|
}
|
|
188
|
-
const agent =
|
|
192
|
+
const agent = agentName;
|
|
189
193
|
const sessionId = resolveSessionId(opts.session);
|
|
190
194
|
const selectionRoot = resolveProjectRoot(sessionId, opts.projectRoot);
|
|
191
195
|
const db = openPipelineDb();
|
|
@@ -266,7 +270,7 @@ export function registerAnalyzeSelectAgentCommand(program) {
|
|
|
266
270
|
process.exit(0);
|
|
267
271
|
return;
|
|
268
272
|
}
|
|
269
|
-
const selectResults = await selectAllComponents(agent,
|
|
273
|
+
const selectResults = await selectAllComponents(agent, model, selectionCandidates, opts.verbose ?? false);
|
|
270
274
|
// Build decision map from results. Seed auto-rejections from validation exclusions first.
|
|
271
275
|
const decisions = new Map();
|
|
272
276
|
for (const comp of invalidComponents) {
|
|
@@ -3,6 +3,8 @@ export type ExperiencesCredentials = {
|
|
|
3
3
|
environmentId: string;
|
|
4
4
|
cmaToken: string;
|
|
5
5
|
host?: string;
|
|
6
|
+
agent?: string;
|
|
7
|
+
agentModel?: string;
|
|
6
8
|
};
|
|
7
9
|
export declare function readExperiencesCredentials(): Promise<ExperiencesCredentials>;
|
|
8
10
|
export declare function writeExperiencesCredentials(creds: ExperiencesCredentials): Promise<void>;
|
|
@@ -14,6 +14,8 @@ export async function readExperiencesCredentials() {
|
|
|
14
14
|
environmentId: process.env['CONTENTFUL_ENVIRONMENT_ID'] ?? parsed.environmentId ?? '',
|
|
15
15
|
cmaToken: process.env['CONTENTFUL_MANAGEMENT_TOKEN'] ?? parsed.cmaToken ?? '',
|
|
16
16
|
...(host ? { host } : {}),
|
|
17
|
+
...(parsed.agent ? { agent: parsed.agent } : {}),
|
|
18
|
+
...(parsed.agentModel ? { agentModel: parsed.agentModel } : {}),
|
|
17
19
|
};
|
|
18
20
|
}
|
|
19
21
|
catch {
|
|
@@ -27,12 +29,14 @@ export async function readExperiencesCredentials() {
|
|
|
27
29
|
}
|
|
28
30
|
}
|
|
29
31
|
export async function writeExperiencesCredentials(creds) {
|
|
30
|
-
const { host: _host, ...rest } = creds;
|
|
32
|
+
const { host: _host, agent, agentModel, ...rest } = creds;
|
|
31
33
|
const host = toConfiguredHost(creds.host);
|
|
32
34
|
await mkdir(CREDENTIALS_DIR, { recursive: true });
|
|
33
35
|
await writeFile(CREDENTIALS_PATH, JSON.stringify({
|
|
34
36
|
...rest,
|
|
35
37
|
...(host ? { host } : {}),
|
|
38
|
+
...(agent ? { agent } : {}),
|
|
39
|
+
...(agentModel ? { agentModel } : {}),
|
|
36
40
|
}, null, 2) + '\n', { mode: 0o600 });
|
|
37
41
|
}
|
|
38
42
|
export function experiencesCredentialsPath() {
|
|
@@ -197,7 +197,7 @@ const AGENT_BINARIES = {
|
|
|
197
197
|
// Default to small/fast models for single-component classification — cheap and accurate enough.
|
|
198
198
|
const DEFAULT_MODELS = {
|
|
199
199
|
claude: 'haiku',
|
|
200
|
-
codex: 'gpt-4
|
|
200
|
+
codex: 'gpt-5.4-mini', // requires OPENAI_API_KEY; ChatGPT account users must pass --model
|
|
201
201
|
opencode: 'claude-haiku-4-5',
|
|
202
202
|
cursor: 'claude-3-5-haiku-20241022',
|
|
203
203
|
};
|
|
@@ -225,8 +225,11 @@ export async function runAgent(options) {
|
|
|
225
225
|
const args = buildArgs(agent, prompt, model);
|
|
226
226
|
return new Promise((resolve) => {
|
|
227
227
|
const child = spawn(binary, args, {
|
|
228
|
-
stdio: interactive ? 'inherit' : ['
|
|
228
|
+
stdio: interactive ? 'inherit' : ['pipe', 'pipe', 'pipe'],
|
|
229
229
|
});
|
|
230
|
+
if (!interactive) {
|
|
231
|
+
child.stdin?.end();
|
|
232
|
+
}
|
|
230
233
|
let stdout = '';
|
|
231
234
|
let stderr = '';
|
|
232
235
|
let timedOut = false;
|
|
@@ -11,6 +11,7 @@ import { GenerateView } from './tui/GenerateView.js';
|
|
|
11
11
|
import { registerGenerateEditCommand } from './edit/command.js';
|
|
12
12
|
import { openPipelineDb, loadRawComponents, applyToolCalls, applyTokenToolCalls, computeComponentInputHash, computeTokenInputHash, lookupCache, lookupCacheByEntity, storeCache, copyComponentFromCache, copyTokensFromCache, renameEmptySlots, } from '../session/db.js';
|
|
13
13
|
import { getRefineArtifactsRoot, getRefineSessionPaths } from '../analyze/select/persistence.js';
|
|
14
|
+
import { readExperiencesCredentials } from '../credentials-store.js';
|
|
14
15
|
const execFileAsync = promisify(execFile);
|
|
15
16
|
const VALID_AGENTS = new Set(['claude', 'codex', 'opencode', 'cursor']);
|
|
16
17
|
const DEFAULT_TIMEOUT_MS = Number(process.env.EDS_AGENT_TIMEOUT_MS ?? 3 * 60 * 1000);
|
|
@@ -292,10 +293,13 @@ async function loadAcceptedNames(sessionId) {
|
|
|
292
293
|
}
|
|
293
294
|
}
|
|
294
295
|
async function runGenerateSkill(skill, opts, verbose = false) {
|
|
295
|
-
|
|
296
|
-
|
|
296
|
+
const savedCreds = await readExperiencesCredentials();
|
|
297
|
+
const agentName = opts.agent ?? savedCreds.agent;
|
|
298
|
+
const model = opts.model ?? savedCreds.agentModel;
|
|
299
|
+
if (!agentName || !VALID_AGENTS.has(agentName)) {
|
|
300
|
+
die(`Error: no agent configured. Pass --agent <name> or run experiences setup. Accepted values: claude, codex, opencode, cursor`);
|
|
297
301
|
}
|
|
298
|
-
const agent =
|
|
302
|
+
const agent = agentName;
|
|
299
303
|
if (skill === 'tokens' && !opts.rawTokens) {
|
|
300
304
|
die('Error: --raw-tokens is required when using generate tokens');
|
|
301
305
|
}
|
|
@@ -386,7 +390,7 @@ async function runGenerateSkill(skill, opts, verbose = false) {
|
|
|
386
390
|
const db = openPipelineDb();
|
|
387
391
|
let componentResults;
|
|
388
392
|
try {
|
|
389
|
-
componentResults = await runAllComponents(agent,
|
|
393
|
+
componentResults = await runAllComponents(agent, model, db, sessionId, allComponents, tokensInline, tokenMapInline, verbose, opts.cache === false || process.env.EDS_NO_CACHE === '1');
|
|
390
394
|
}
|
|
391
395
|
finally {
|
|
392
396
|
db.close();
|
|
@@ -478,7 +482,7 @@ async function runGenerateSkill(skill, opts, verbose = false) {
|
|
|
478
482
|
});
|
|
479
483
|
const result = await runAgent({
|
|
480
484
|
agent,
|
|
481
|
-
model
|
|
485
|
+
model,
|
|
482
486
|
prompt,
|
|
483
487
|
interactive: false,
|
|
484
488
|
timeoutMs: DEFAULT_TIMEOUT_MS * 5,
|
|
@@ -533,7 +537,7 @@ async function runGenerateSkill(skill, opts, verbose = false) {
|
|
|
533
537
|
}
|
|
534
538
|
function addAgentFlags(cmd) {
|
|
535
539
|
return cmd
|
|
536
|
-
.
|
|
540
|
+
.option('--agent <name>', 'Agent to use: claude, codex, opencode, cursor (defaults to value saved by experiences setup)')
|
|
537
541
|
.option('--model <name>', 'Model to use (defaults to a small/fast model per agent)')
|
|
538
542
|
.option('--verbose', 'Show full agent output including reasoning text')
|
|
539
543
|
.option('--dry-run', 'Print the prompt without invoking the agent')
|
|
@@ -329,28 +329,80 @@ async function setupBuild(repoRoot) {
|
|
|
329
329
|
return true;
|
|
330
330
|
}
|
|
331
331
|
// ── Step 4: agent CLI ─────────────────────────────────────────────────────────
|
|
332
|
+
const AGENT_DEFS = [
|
|
333
|
+
{ name: 'Claude Code', binary: 'claude', installHint: 'npm install -g @anthropic-ai/claude-code && claude login' },
|
|
334
|
+
{ name: 'OpenAI Codex', binary: 'codex', installHint: 'npm install -g @openai/codex (requires OPENAI_API_KEY)' },
|
|
335
|
+
{ name: 'OpenCode', binary: 'opencode', installHint: 'npm install -g opencode-ai && opencode auth' },
|
|
336
|
+
];
|
|
337
|
+
function pick(items, defaultIdx = 0) {
|
|
338
|
+
items.forEach((item, i) => {
|
|
339
|
+
const num = `\x1b[1m[${i + 1}]\x1b[0m`;
|
|
340
|
+
const desc = item.description ? ` \x1b[2m${item.description}\x1b[0m` : '';
|
|
341
|
+
const def = i === defaultIdx ? ` \x1b[2m(default)\x1b[0m` : '';
|
|
342
|
+
process.stdout.write(` ${num} ${item.label}${desc}${def}\n`);
|
|
343
|
+
});
|
|
344
|
+
process.stdout.write(` \x1b[2m[s] Skip\x1b[0m\n`);
|
|
345
|
+
}
|
|
346
|
+
async function promptCodexModel() {
|
|
347
|
+
if (process.env['OPENAI_API_KEY'])
|
|
348
|
+
return undefined; // API key users get the default (gpt-4.1-nano)
|
|
349
|
+
info('');
|
|
350
|
+
process.stdout.write(` \x1b[33m⚠\x1b[0m No OPENAI_API_KEY — using ChatGPT account authentication.\n`);
|
|
351
|
+
info(' Tip: run \x1b[1mcodex\x1b[0m then type \x1b[1m/model\x1b[0m to browse all available models.');
|
|
352
|
+
info('');
|
|
353
|
+
info(' Choose a model:');
|
|
354
|
+
info('');
|
|
355
|
+
pick([
|
|
356
|
+
{ label: 'gpt-5.4-mini', description: 'fast, lower cost' },
|
|
357
|
+
{ label: 'gpt-5.5', description: 'most capable' },
|
|
358
|
+
{ label: 'gpt-5.4' },
|
|
359
|
+
]);
|
|
360
|
+
info('');
|
|
361
|
+
const choice = await prompt(' \x1b[2m›\x1b[0m Your choice [1]: ');
|
|
362
|
+
if (choice === '1' || choice === '')
|
|
363
|
+
return 'gpt-5.4-mini';
|
|
364
|
+
if (choice === '2')
|
|
365
|
+
return 'gpt-5.5';
|
|
366
|
+
if (choice === '3')
|
|
367
|
+
return 'gpt-5.4';
|
|
368
|
+
return undefined;
|
|
369
|
+
}
|
|
332
370
|
async function setupAgent() {
|
|
333
|
-
section('Step 4: Coding agent (claude, codex,
|
|
371
|
+
section('Step 4: Coding agent (claude, codex, or opencode)', '[required]');
|
|
334
372
|
info('experiences import uses a coding agent to generate component definitions.');
|
|
335
373
|
info('');
|
|
336
|
-
const
|
|
337
|
-
|
|
338
|
-
{
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
}
|
|
374
|
+
const found = (await Promise.all(AGENT_DEFS.map(async (a) => ((await binaryExists(a.binary)) ? a : null)))).filter((a) => a !== null);
|
|
375
|
+
if (found.length === 1) {
|
|
376
|
+
ok(`${found[0].name} (${found[0].binary}) found`);
|
|
377
|
+
const agentModel = found[0].binary === 'codex' ? await promptCodexModel() : undefined;
|
|
378
|
+
return { agent: found[0].binary, agentModel };
|
|
379
|
+
}
|
|
380
|
+
if (found.length > 1) {
|
|
381
|
+
info('Multiple coding agents found. Choose one to use as the default:');
|
|
382
|
+
info('');
|
|
383
|
+
pick(found.map((a) => ({ label: `${a.name}`, description: a.binary })));
|
|
384
|
+
info('');
|
|
385
|
+
const choice = await prompt(' \x1b[2m›\x1b[0m Your choice [1]: ');
|
|
386
|
+
if (choice.toLowerCase() === 's') {
|
|
387
|
+
warn('Skipped. Install a coding agent before running experiences import.');
|
|
388
|
+
return { agent: undefined, agentModel: undefined };
|
|
389
|
+
}
|
|
390
|
+
const parsed = choice === '' ? 1 : parseInt(choice, 10);
|
|
391
|
+
const idx = Number.isNaN(parsed) || parsed < 1 || parsed > found.length ? 0 : parsed - 1;
|
|
392
|
+
const selected = found[idx];
|
|
393
|
+
ok(`${selected.name} \x1b[2m(${selected.binary})\x1b[0m selected`);
|
|
394
|
+
const agentModel = selected.binary === 'codex' ? await promptCodexModel() : undefined;
|
|
395
|
+
return { agent: selected.binary, agentModel };
|
|
346
396
|
}
|
|
347
397
|
warn('No coding agent found on PATH');
|
|
348
398
|
info('');
|
|
349
399
|
info('Choose one to install:');
|
|
350
|
-
info('
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
400
|
+
info('');
|
|
401
|
+
pick([
|
|
402
|
+
{ label: 'Claude Code', description: 'npm install -g @anthropic-ai/claude-code' },
|
|
403
|
+
{ label: 'OpenAI Codex', description: 'npm install -g @openai/codex' },
|
|
404
|
+
{ label: 'OpenCode', description: 'npm install -g opencode-ai' },
|
|
405
|
+
]);
|
|
354
406
|
info('');
|
|
355
407
|
const choice = await prompt(' Your choice: ');
|
|
356
408
|
if (choice === '1' || choice === '') {
|
|
@@ -358,48 +410,48 @@ async function setupAgent() {
|
|
|
358
410
|
if (r.exitCode !== 0) {
|
|
359
411
|
fail('Install failed');
|
|
360
412
|
info(r.stderr.trim().split('\n').slice(0, 5).join('\n'));
|
|
361
|
-
return
|
|
413
|
+
return { agent: undefined, agentModel: undefined };
|
|
362
414
|
}
|
|
363
415
|
if (!(await binaryExists('claude'))) {
|
|
364
416
|
fail('claude binary not found on PATH after install — check your npm global bin directory');
|
|
365
|
-
return
|
|
417
|
+
return { agent: undefined, agentModel: undefined };
|
|
366
418
|
}
|
|
367
419
|
ok('Claude Code installed');
|
|
368
420
|
info('');
|
|
369
421
|
info('Next: run `claude login` to authenticate (browser OAuth).');
|
|
370
422
|
info('Or set ANTHROPIC_API_KEY in your shell profile.');
|
|
371
|
-
return
|
|
423
|
+
return { agent: 'claude', agentModel: undefined };
|
|
372
424
|
}
|
|
373
425
|
if (choice === '2') {
|
|
374
426
|
const r = await runSpawn('npm', ['install', '-g', '@openai/codex']);
|
|
375
427
|
if (r.exitCode !== 0) {
|
|
376
428
|
fail('Install failed');
|
|
377
|
-
return
|
|
429
|
+
return { agent: undefined, agentModel: undefined };
|
|
378
430
|
}
|
|
379
431
|
if (!(await binaryExists('codex'))) {
|
|
380
432
|
fail('codex binary not found on PATH after install — check your npm global bin directory');
|
|
381
|
-
return
|
|
433
|
+
return { agent: undefined, agentModel: undefined };
|
|
382
434
|
}
|
|
383
435
|
ok('OpenAI Codex installed');
|
|
384
|
-
|
|
385
|
-
return
|
|
436
|
+
const agentModel = await promptCodexModel();
|
|
437
|
+
return { agent: 'codex', agentModel };
|
|
386
438
|
}
|
|
387
439
|
if (choice === '3') {
|
|
388
440
|
const r = await runSpawn('npm', ['install', '-g', 'opencode-ai']);
|
|
389
441
|
if (r.exitCode !== 0) {
|
|
390
442
|
fail('Install failed');
|
|
391
|
-
return
|
|
443
|
+
return { agent: undefined, agentModel: undefined };
|
|
392
444
|
}
|
|
393
445
|
if (!(await binaryExists('opencode'))) {
|
|
394
446
|
fail('opencode binary not found on PATH after install — check your npm global bin directory');
|
|
395
|
-
return
|
|
447
|
+
return { agent: undefined, agentModel: undefined };
|
|
396
448
|
}
|
|
397
449
|
ok('OpenCode installed');
|
|
398
450
|
info('Run `opencode auth` to configure your provider.');
|
|
399
|
-
return
|
|
451
|
+
return { agent: 'opencode', agentModel: undefined };
|
|
400
452
|
}
|
|
401
453
|
warn('Skipped. Install a coding agent before running experiences import.');
|
|
402
|
-
return
|
|
454
|
+
return { agent: undefined, agentModel: undefined };
|
|
403
455
|
}
|
|
404
456
|
// ── Step 5: Contentful credentials ───────────────────────────────────────────
|
|
405
457
|
async function setupContentfulCredentials() {
|
|
@@ -462,7 +514,8 @@ async function setupContentfulCredentials() {
|
|
|
462
514
|
}
|
|
463
515
|
const hostInput = await prompt(` API host [${currentHost}]: `);
|
|
464
516
|
const host = toConfiguredHost(hostInput) ?? storedHost;
|
|
465
|
-
|
|
517
|
+
const existing = await readExperiencesCredentials();
|
|
518
|
+
await writeExperiencesCredentials({ ...existing, spaceId, environmentId, cmaToken, ...(host ? { host } : {}) });
|
|
466
519
|
ok(`Credentials saved to ${experiencesCredentialsPath()}`);
|
|
467
520
|
ok(`API host set to ${host ?? DEFAULT_CONFIGURED_HOST}`);
|
|
468
521
|
info('Run experiences import — credentials will be pre-filled automatically.');
|
|
@@ -612,14 +665,27 @@ async function checkBuild(pkgRoot) {
|
|
|
612
665
|
}
|
|
613
666
|
async function checkAgent() {
|
|
614
667
|
section('Checking coding agent');
|
|
615
|
-
const agents =
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
668
|
+
const agents = AGENT_DEFS;
|
|
669
|
+
const creds = await readExperiencesCredentials();
|
|
670
|
+
const savedAgent = creds.agent;
|
|
671
|
+
const savedModel = creds.agentModel;
|
|
672
|
+
if (savedAgent) {
|
|
673
|
+
const found = await binaryExists(savedAgent);
|
|
674
|
+
if (found) {
|
|
675
|
+
const modelStr = savedModel ? ` — model: ${savedModel}` : '';
|
|
676
|
+
ok(`${savedAgent}${modelStr} (saved preference)`);
|
|
677
|
+
return true;
|
|
678
|
+
}
|
|
679
|
+
else {
|
|
680
|
+
warn(`Saved agent '${savedAgent}' not found on PATH`);
|
|
681
|
+
info(`Re-run experiences setup to reconfigure.`);
|
|
682
|
+
return false;
|
|
683
|
+
}
|
|
684
|
+
}
|
|
620
685
|
for (const agent of agents) {
|
|
621
686
|
if (await binaryExists(agent.binary)) {
|
|
622
687
|
ok(`${agent.name} (${agent.binary}) found`);
|
|
688
|
+
info('Tip: run experiences setup to save a default agent and model.');
|
|
623
689
|
return true;
|
|
624
690
|
}
|
|
625
691
|
}
|
|
@@ -704,7 +770,6 @@ export function registerSetupCommand(program) {
|
|
|
704
770
|
.action(async (opts) => {
|
|
705
771
|
process.stdout.write('\n\x1b[1mexperiences setup\x1b[0m — interactive setup wizard\n');
|
|
706
772
|
process.stdout.write('Sets up everything you need to run \x1b[1mexperiences import\x1b[0m.\n');
|
|
707
|
-
process.stdout.write('Required steps are marked \x1b[31m[required]\x1b[0m, optional ones \x1b[2m[optional]\x1b[0m.\n');
|
|
708
773
|
const pkgRoot = join(dirname(fileURLToPath(import.meta.url)), '..', '..', '..');
|
|
709
774
|
const repoRoot = join(pkgRoot, '..', '..');
|
|
710
775
|
const profilePath = await detectShellProfile();
|
|
@@ -729,8 +794,13 @@ export function registerSetupCommand(program) {
|
|
|
729
794
|
}
|
|
730
795
|
// Step 4: agent
|
|
731
796
|
if (!opts.skipAgent) {
|
|
732
|
-
const
|
|
733
|
-
|
|
797
|
+
const { agent, agentModel } = await setupAgent();
|
|
798
|
+
if (agent) {
|
|
799
|
+
const stored = await readExperiencesCredentials();
|
|
800
|
+
const { agentModel: _staleModel, ...storedWithoutModel } = stored;
|
|
801
|
+
await writeExperiencesCredentials({ ...storedWithoutModel, agent, ...(agentModel ? { agentModel } : {}) });
|
|
802
|
+
}
|
|
803
|
+
results.push({ name: 'coding agent', passed: !!agent, required: true });
|
|
734
804
|
}
|
|
735
805
|
else {
|
|
736
806
|
info('\nSkipping agent check (--skip-agent)');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentful/experience-design-system-cli",
|
|
3
|
-
"version": "2.11.0",
|
|
3
|
+
"version": "2.11.1-dev-build-96af281.0",
|
|
4
4
|
"description": "Contentful Experiences design system import CLI",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"react-dom": "^18.3.1",
|
|
37
37
|
"ts-morph": "^27.0.2",
|
|
38
38
|
"typescript": "^5.9.3",
|
|
39
|
-
"@contentful/experience-design-system-types": "2.11.0"
|
|
39
|
+
"@contentful/experience-design-system-types": "2.11.1-dev-build-96af281.0"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@tsconfig/node24": "^24.0.3",
|