@contentful/experience-design-system-cli 2.16.2-dev-build-ec5957c.0 → 2.16.2-dev-build-a6d3bd1.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/command.js +4 -4
- package/dist/src/analyze/select-agent/command.js +3 -4
- package/dist/src/apply/command.js +17 -45
- package/dist/src/credentials-store.d.ts +2 -1
- package/dist/src/credentials-store.js +3 -2
- package/dist/src/generate/agent-runner.d.ts +2 -1
- package/dist/src/generate/agent-runner.js +1 -0
- package/dist/src/generate/command.js +3 -4
- package/dist/src/import/command.js +6 -4
- package/dist/src/import/tui/WizardApp.d.ts +2 -2
- package/dist/src/import/tui/wizard-save-flow.d.ts +2 -2
- package/dist/src/lib/agent-model-options.d.ts +1 -1
- package/dist/src/lib/agent-model-options.js +2 -1
- package/dist/src/lib/agent-names.d.ts +4 -0
- package/dist/src/lib/agent-names.js +5 -0
- package/dist/src/lib/command-options.d.ts +5 -0
- package/dist/src/lib/command-options.js +27 -0
- package/dist/src/lib/composition-mode.d.ts +3 -1
- package/dist/src/lib/composition-mode.js +7 -5
- package/dist/src/runs/modify-launcher.d.ts +2 -1
- package/dist/src/runs/save-path-resolver.d.ts +4 -2
- package/dist/src/runs/save-path-resolver.js +4 -0
- package/dist/src/runs/store.d.ts +2 -1
- package/package.json +3 -3
package/dist/package.json
CHANGED
|
@@ -19,6 +19,7 @@ import { buildCompositionInputHash } from './composition/composition-cache-key.j
|
|
|
19
19
|
import { runParserInSandbox } from './composition/agent-parser/sandbox.js';
|
|
20
20
|
import { resolveViaAgentParser } from './composition/agent-parser/resolve-via-parser.js';
|
|
21
21
|
import { parsePromptOverrides, resolvePromptOverride } from '../lib/prompt-overrides.js';
|
|
22
|
+
import { DEFAULT_AGENT_NAME, isAgentName } from '../lib/agent-names.js';
|
|
22
23
|
import { runAgent } from '../generate/agent-runner.js';
|
|
23
24
|
import { readExperiencesCredentials } from '../credentials-store.js';
|
|
24
25
|
import { buildAnalyzeViewRows, partitionGlobalWarnings } from './build-analyze-view-rows.js';
|
|
@@ -132,13 +133,12 @@ export function componentsToInterchangeMap(components) {
|
|
|
132
133
|
}
|
|
133
134
|
/** Resolve which coding-agent runs mapping resolution: `--agent` flag > env > default. */
|
|
134
135
|
function resolveCompositionAgentName(flagValue) {
|
|
135
|
-
|
|
136
|
-
if (flagValue && valid.includes(flagValue))
|
|
136
|
+
if (flagValue && isAgentName(flagValue))
|
|
137
137
|
return flagValue;
|
|
138
138
|
const env = process.env['EDS_COMPOSITION_AGENT'];
|
|
139
|
-
if (env &&
|
|
139
|
+
if (env && isAgentName(env))
|
|
140
140
|
return env;
|
|
141
|
-
return
|
|
141
|
+
return DEFAULT_AGENT_NAME;
|
|
142
142
|
}
|
|
143
143
|
/**
|
|
144
144
|
* Read the source files of the extracted components plus nearby mapping/meta
|
|
@@ -5,7 +5,7 @@ import { appendReviewEvent, getRefineArtifactsRoot, ensureRefineSession, getRefi
|
|
|
5
5
|
import { loadReviewInput } from '../select/parser.js';
|
|
6
6
|
import { buildPrompt } from '../../generate/prompt-builder.js';
|
|
7
7
|
import { formatCustomPromptBanner } from '../../generate/command.js';
|
|
8
|
-
import { parseSelectToolCallLines, runAgent } from '../../generate/agent-runner.js';
|
|
8
|
+
import { AGENT_NAMES, isAgentName, parseSelectToolCallLines, runAgent } from '../../generate/agent-runner.js';
|
|
9
9
|
import { access } from 'node:fs/promises';
|
|
10
10
|
import { readExperiencesCredentials } from '../../credentials-store.js';
|
|
11
11
|
import { OutputFormatter, c } from '../../output/format.js';
|
|
@@ -13,7 +13,6 @@ import { buildRepoContextIndex, buildSelectionContext } from './context-builder.
|
|
|
13
13
|
import { runShowRationale } from './show-rationale.js';
|
|
14
14
|
import { isAbsolute, resolve } from 'node:path';
|
|
15
15
|
import { validateExtractedComponents, shouldExcludeDueToValidation, formatExclusionWarning, } from '@contentful/experience-design-system-extraction';
|
|
16
|
-
const VALID_AGENTS = new Set(['claude', 'codex', 'opencode', 'cursor']);
|
|
17
16
|
const DEFAULT_TIMEOUT_MS = Number(process.env.EDS_AGENT_TIMEOUT_MS ?? 3 * 60 * 1000);
|
|
18
17
|
export const DEFAULT_CONCURRENCY = 10;
|
|
19
18
|
export const DEFAULT_BATCH_SIZE = 5;
|
|
@@ -336,8 +335,8 @@ export function registerAnalyzeSelectAgentCommand(program) {
|
|
|
336
335
|
const savedCreds = await readExperiencesCredentials();
|
|
337
336
|
const agentName = opts.agent ?? savedCreds.agent;
|
|
338
337
|
const model = opts.model ?? savedCreds.agentModel;
|
|
339
|
-
if (!agentName || !
|
|
340
|
-
process.stderr.write(`Error: no agent configured. Pass --agent <name> or run experiences setup. Accepted values:
|
|
338
|
+
if (!agentName || !isAgentName(agentName)) {
|
|
339
|
+
process.stderr.write(`Error: no agent configured. Pass --agent <name> or run experiences setup. Accepted values: ${AGENT_NAMES.join(', ')}\n`);
|
|
341
340
|
process.exit(1);
|
|
342
341
|
return;
|
|
343
342
|
}
|
|
@@ -12,6 +12,7 @@ import { ServerPreviewApp, ServerPreviewConfirm, ServerApplyProgress, ServerAppl
|
|
|
12
12
|
import { SelectView, makeSelectKey } from './tui/SelectView.js';
|
|
13
13
|
import { buildPostPushUrl } from '../lib/contentful-urls.js';
|
|
14
14
|
import { resolveCompositionMode } from '../lib/composition-mode.js';
|
|
15
|
+
import { addArtifactInputOptions, addCompositionOptions, addContentfulTargetOptions, addSelectionOptions, } from '../lib/command-options.js';
|
|
15
16
|
import { stripAllowedComponents } from '../import/strip-allowed-components.js';
|
|
16
17
|
import { readExperiencesCredentials } from '../credentials-store.js';
|
|
17
18
|
import { getInteractiveTerminalSupport, requireInteractiveTerminal } from '../lib/terminal-capabilities.js';
|
|
@@ -411,26 +412,15 @@ function SelectApp({ entities, spaceId, environmentId, onApply }) {
|
|
|
411
412
|
importing,
|
|
412
413
|
});
|
|
413
414
|
}
|
|
414
|
-
function collect(val, prev) {
|
|
415
|
-
return [...prev, val];
|
|
416
|
-
}
|
|
417
415
|
export function registerApplyCommand(program) {
|
|
418
416
|
const applyCmd = program
|
|
419
417
|
.command('apply')
|
|
420
418
|
.description('Preview, select, or push design system entities to Contentful ExO');
|
|
421
|
-
applyCmd
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
.option('--session <id>', 'Pipeline session ID to load generated components from')
|
|
427
|
-
.requiredOption('--space-id <id>', 'Contentful space ID')
|
|
428
|
-
.requiredOption('--environment-id <id>', 'Contentful environment ID')
|
|
429
|
-
.option('--cma-token <token>', 'CMA personal access token (or set CONTENTFUL_MANAGEMENT_TOKEN)')
|
|
430
|
-
.option('--host <url>', 'Override API base URL')
|
|
431
|
-
.option('--composite', 'Import embedded-component hierarchy (opt in; default is atomic)')
|
|
432
|
-
.option('--atomic', 'Import flat components with no embedded-component hierarchy (default)')
|
|
433
|
-
.action(async (opts) => {
|
|
419
|
+
const previewCmd = applyCmd.command('preview').description('Show a read-only diff of what apply push would do');
|
|
420
|
+
addArtifactInputOptions(previewCmd);
|
|
421
|
+
addContentfulTargetOptions(previewCmd);
|
|
422
|
+
addCompositionOptions(previewCmd);
|
|
423
|
+
previewCmd.action(async (opts) => {
|
|
434
424
|
let inputs;
|
|
435
425
|
try {
|
|
436
426
|
inputs = await resolveSharedInputs(opts);
|
|
@@ -475,18 +465,11 @@ export function registerApplyCommand(program) {
|
|
|
475
465
|
process.exit(0);
|
|
476
466
|
}
|
|
477
467
|
});
|
|
478
|
-
applyCmd
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
.option('--session <id>', 'Pipeline session ID to load generated components from')
|
|
484
|
-
.requiredOption('--space-id <id>', 'Contentful space ID')
|
|
485
|
-
.requiredOption('--environment-id <id>', 'Contentful environment ID')
|
|
486
|
-
.option('--cma-token <token>', 'CMA personal access token (or set CONTENTFUL_MANAGEMENT_TOKEN)')
|
|
487
|
-
.option('--host <url>', 'Override API base URL')
|
|
488
|
-
.option('--composite', 'Import embedded-component hierarchy (opt in; default is atomic)')
|
|
489
|
-
.option('--atomic', 'Import flat components with no embedded-component hierarchy (default)')
|
|
468
|
+
const pushCmd = applyCmd.command('push').description('Write component types and design tokens to Contentful ExO');
|
|
469
|
+
addArtifactInputOptions(pushCmd);
|
|
470
|
+
addContentfulTargetOptions(pushCmd);
|
|
471
|
+
addCompositionOptions(pushCmd);
|
|
472
|
+
pushCmd
|
|
490
473
|
.option('--yes', 'Skip interactive confirmation')
|
|
491
474
|
.option('--verbose', 'Show all entity progress including skipped/unchanged')
|
|
492
475
|
.option('--force', 'Skip confirmation for breaking changes (for CI)')
|
|
@@ -652,23 +635,12 @@ export function registerApplyCommand(program) {
|
|
|
652
635
|
void instance.waitUntilExit().then(() => resolvePromise());
|
|
653
636
|
});
|
|
654
637
|
});
|
|
655
|
-
applyCmd
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
.requiredOption('--space-id <id>', 'Contentful space ID')
|
|
662
|
-
.requiredOption('--environment-id <id>', 'Contentful environment ID')
|
|
663
|
-
.option('--cma-token <token>', 'CMA personal access token (or set CONTENTFUL_MANAGEMENT_TOKEN)')
|
|
664
|
-
.option('--host <url>', 'Override API base URL')
|
|
665
|
-
.option('--composite', 'Import embedded-component hierarchy (opt in; default is atomic)')
|
|
666
|
-
.option('--atomic', 'Import flat components with no embedded-component hierarchy (default)')
|
|
667
|
-
.option('--select-all', 'Select all entities without launching TUI')
|
|
668
|
-
.option('--select <pattern>', 'Select entities by ID pattern (repeatable)', collect, [])
|
|
669
|
-
.option('--deselect <pattern>', 'Deselect entities by ID pattern (repeatable)', collect, [])
|
|
670
|
-
.option('--force', 'Skip confirmation for breaking changes')
|
|
671
|
-
.action(async (opts) => {
|
|
638
|
+
const selectCmd = applyCmd.command('select').description('Select a subset of entities and push to Contentful ExO');
|
|
639
|
+
addArtifactInputOptions(selectCmd);
|
|
640
|
+
addContentfulTargetOptions(selectCmd);
|
|
641
|
+
addCompositionOptions(selectCmd);
|
|
642
|
+
addSelectionOptions(selectCmd);
|
|
643
|
+
selectCmd.option('--force', 'Skip confirmation for breaking changes').action(async (opts) => {
|
|
672
644
|
const nonInteractive = opts.selectAll || (opts.select ?? []).length > 0 || (opts.deselect ?? []).length > 0;
|
|
673
645
|
if (!nonInteractive) {
|
|
674
646
|
requireInteractiveTerminal({
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type CompositionMode } from './lib/composition-mode.js';
|
|
1
2
|
export type ExperiencesCredentials = {
|
|
2
3
|
spaceId: string;
|
|
3
4
|
environmentId: string;
|
|
@@ -17,7 +18,7 @@ export type ExperiencesCredentials = {
|
|
|
17
18
|
* flat components with no embedded-component hierarchy; `composite` opts into
|
|
18
19
|
* the slot-graph machinery. Resolved `flag > env > this > default`.
|
|
19
20
|
*/
|
|
20
|
-
compositionMode?:
|
|
21
|
+
compositionMode?: CompositionMode;
|
|
21
22
|
};
|
|
22
23
|
/**
|
|
23
24
|
* Read persisted Contentful credentials.
|
|
@@ -2,6 +2,7 @@ import { readFile, writeFile, mkdir } from 'node:fs/promises';
|
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { homedir } from 'node:os';
|
|
4
4
|
import { toConfiguredHost } from './host-utils.js';
|
|
5
|
+
import { isCompositionMode } from './lib/composition-mode.js';
|
|
5
6
|
const CREDENTIALS_DIR = join(homedir(), '.config', 'experiences');
|
|
6
7
|
const CREDENTIALS_PATH = join(CREDENTIALS_DIR, 'credentials.json');
|
|
7
8
|
/**
|
|
@@ -35,7 +36,7 @@ export async function readExperiencesCredentials() {
|
|
|
35
36
|
...(parsed.generatePromptPath ? { generatePromptPath: parsed.generatePromptPath } : {}),
|
|
36
37
|
...(typeof parsed.autoFilter === 'boolean' ? { autoFilter: parsed.autoFilter } : {}),
|
|
37
38
|
...(typeof parsed.debug === 'boolean' ? { debug: parsed.debug } : {}),
|
|
38
|
-
...(parsed.compositionMode === '
|
|
39
|
+
...(typeof parsed.compositionMode === 'string' && isCompositionMode(parsed.compositionMode)
|
|
39
40
|
? { compositionMode: parsed.compositionMode }
|
|
40
41
|
: {}),
|
|
41
42
|
};
|
|
@@ -63,7 +64,7 @@ export async function writeExperiencesCredentials(creds) {
|
|
|
63
64
|
...(generatePromptPath ? { generatePromptPath } : {}),
|
|
64
65
|
...(typeof autoFilter === 'boolean' ? { autoFilter } : {}),
|
|
65
66
|
...(typeof debug === 'boolean' ? { debug } : {}),
|
|
66
|
-
...(compositionMode
|
|
67
|
+
...(compositionMode && isCompositionMode(compositionMode) ? { compositionMode } : {}),
|
|
67
68
|
}, null, 2) + '\n', { mode: 0o600 });
|
|
68
69
|
}
|
|
69
70
|
export function experiencesCredentialsPath() {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
import type { AgentName } from '../lib/agent-names.js';
|
|
2
|
+
export { AGENT_NAMES, isAgentName, type AgentName } from '../lib/agent-names.js';
|
|
2
3
|
export interface AgentRunResult {
|
|
3
4
|
exitCode: number;
|
|
4
5
|
stdout: string;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process';
|
|
2
2
|
import { getDebugLogger } from '../lib/debug-logger.js';
|
|
3
|
+
export { AGENT_NAMES, isAgentName } from '../lib/agent-names.js';
|
|
3
4
|
const VALID_SELECT_TOOL_NAMES = new Set(['select_component', 'reject_component']);
|
|
4
5
|
export function parseSelectToolCallLines(stdout) {
|
|
5
6
|
const calls = [];
|
|
@@ -4,7 +4,7 @@ import { access, readFile, readdir, stat } from 'node:fs/promises';
|
|
|
4
4
|
import { join, resolve } from 'node:path';
|
|
5
5
|
import { execFile } from 'node:child_process';
|
|
6
6
|
import { promisify } from 'node:util';
|
|
7
|
-
import { describeAgentFailure, parseToolCallLines, parseTokenToolCallLines, resolveBinary, runAgent, } from './agent-runner.js';
|
|
7
|
+
import { AGENT_NAMES, describeAgentFailure, isAgentName, parseToolCallLines, parseTokenToolCallLines, resolveBinary, runAgent, } from './agent-runner.js';
|
|
8
8
|
import { OutputFormatter, c } from '../output/format.js';
|
|
9
9
|
import { formatGenerateProgressLine } from './progress.js';
|
|
10
10
|
import { buildPrompt, resolveSkillPath } from './prompt-builder.js';
|
|
@@ -16,7 +16,6 @@ import { getRefineArtifactsRoot, getRefineSessionPaths } from '../analyze/select
|
|
|
16
16
|
import { readExperiencesCredentials } from '../credentials-store.js';
|
|
17
17
|
import { addAgentModelOptions } from '../lib/agent-model-options.js';
|
|
18
18
|
const execFileAsync = promisify(execFile);
|
|
19
|
-
const VALID_AGENTS = new Set(['claude', 'codex', 'opencode', 'cursor']);
|
|
20
19
|
const DEFAULT_TIMEOUT_MS = Number(process.env.EDS_AGENT_TIMEOUT_MS ?? 3 * 60 * 1000);
|
|
21
20
|
const DEFAULT_COMPONENT_CONCURRENCY = 10;
|
|
22
21
|
const RETRY_BACKOFF_MS = Number(process.env.EDS_RETRY_BACKOFF_MS ?? 5_000);
|
|
@@ -313,8 +312,8 @@ async function runGenerateSkill(skill, opts, verbose = false) {
|
|
|
313
312
|
const savedCreds = await readExperiencesCredentials();
|
|
314
313
|
const agentName = opts.agent ?? savedCreds.agent;
|
|
315
314
|
const model = opts.model ?? savedCreds.agentModel;
|
|
316
|
-
if (!agentName || !
|
|
317
|
-
die(`Error: no agent configured. Pass --agent <name> or run experiences setup. Accepted values:
|
|
315
|
+
if (!agentName || !isAgentName(agentName)) {
|
|
316
|
+
die(`Error: no agent configured. Pass --agent <name> or run experiences setup. Accepted values: ${AGENT_NAMES.join(', ')}`);
|
|
318
317
|
}
|
|
319
318
|
const agent = agentName;
|
|
320
319
|
// Feature 8: resolve custom-prompt path for `components` (flag wins over
|
|
@@ -4,6 +4,8 @@ import { resolveAutoFilter } from './auto-filter-resolve.js';
|
|
|
4
4
|
import { resolveAgent, resolveModel } from './agent-model-resolve.js';
|
|
5
5
|
import { addAgentModelOptions } from '../lib/agent-model-options.js';
|
|
6
6
|
import { resolveCompositionMode } from '../lib/composition-mode.js';
|
|
7
|
+
import { addCompositionOptions } from '../lib/command-options.js';
|
|
8
|
+
import { isConflictMode } from '../runs/save-path-resolver.js';
|
|
7
9
|
import { readExperiencesCredentials } from '../credentials-store.js';
|
|
8
10
|
import { DEFAULT_CONFIGURED_HOST, toConfiguredHost } from '../host-utils.js';
|
|
9
11
|
import { replayRun, modifyRun } from '../runs/replay-helpers.js';
|
|
@@ -42,9 +44,9 @@ export function registerImportCommand(program) {
|
|
|
42
44
|
.option('--host <url>', 'Override API base URL (passed to apply push)')
|
|
43
45
|
.option('--dry-run', "(deprecated, will change semantics in a future release) Print generate components prompt without invoking the agent. Use --print-prompt for the same behaviour explicitly, or '--dry-run --no-push' for the upcoming manifest-preview semantics.")
|
|
44
46
|
.option('--print-prompt', 'Print the generate components prompt without invoking the agent. Replaces the legacy --dry-run prompt-print behaviour on this command.')
|
|
45
|
-
.option('--auto-accept-scope', 'Accept all extracted components without prompting (for scripted/non-TTY callers)')
|
|
46
|
-
|
|
47
|
-
|
|
47
|
+
.option('--auto-accept-scope', 'Accept all extracted components without prompting (for scripted/non-TTY callers)');
|
|
48
|
+
addCompositionOptions(cmd);
|
|
49
|
+
cmd
|
|
48
50
|
.option('--composition-map <path>', 'Consume a hand-authored parent→children interchange map (implies --composite)')
|
|
49
51
|
.option('--composition-agent', 'Opt into agentic mapping resolution when deterministic sources find no groups (implies --composite)')
|
|
50
52
|
.option('--composition-refresh', 'Bypass the composition cache and re-resolve from scratch, forcing the agent to run (implies --composite)')
|
|
@@ -59,7 +61,7 @@ export function registerImportCommand(program) {
|
|
|
59
61
|
.option('--no-save', 'Push without writing components.json / tokens.json to disk (default: save AND push)')
|
|
60
62
|
.option('--out-dir <path>', 'Save components.json / tokens.json to this directory; bypasses the inline save-path prompt')
|
|
61
63
|
.option('--on-conflict <mode>', "How to handle existing components.json / tokens.json at the save path: 'overwrite' replaces files, 'skip' writes to a timestamped subdirectory, 'fail' exits non-zero. Skips the wizard's interactive conflict gate when set.", (value) => {
|
|
62
|
-
if (value
|
|
64
|
+
if (!isConflictMode(value)) {
|
|
63
65
|
process.stderr.write(`Error: invalid --on-conflict value '${value}'. Use one of: overwrite, skip, fail.\n`);
|
|
64
66
|
process.exit(1);
|
|
65
67
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { type RunPickerSelection } from '../../runs/run-picker.js';
|
|
3
3
|
import type { RunRecord } from '../../runs/store.js';
|
|
4
|
-
import { type
|
|
4
|
+
import { type ConflictMode } from '../../runs/save-path-resolver.js';
|
|
5
5
|
import type { CompositionMode } from '../../lib/composition-mode.js';
|
|
6
6
|
export declare function buildSelectAgentArgs(opts: {
|
|
7
7
|
sessionId: string;
|
|
@@ -55,7 +55,7 @@ export type WizardAppProps = {
|
|
|
55
55
|
noPush?: boolean;
|
|
56
56
|
noSave?: boolean;
|
|
57
57
|
outDirOverride?: string;
|
|
58
|
-
onConflictMode?:
|
|
58
|
+
onConflictMode?: ConflictMode;
|
|
59
59
|
selectPromptPath?: string;
|
|
60
60
|
generatePromptPath?: string;
|
|
61
61
|
seedExtractSessionId?: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type RunRecord } from '../../runs/store.js';
|
|
2
|
-
import { type
|
|
2
|
+
import { type ConflictMode } from '../../runs/save-path-resolver.js';
|
|
3
3
|
/**
|
|
4
4
|
* Wizard save-flow orchestration helpers (Task 4 / spec part 1+2).
|
|
5
5
|
*
|
|
@@ -17,7 +17,7 @@ export type PlanSaveFlowInput = {
|
|
|
17
17
|
* path interactively. When provided alongside an override, the conflict
|
|
18
18
|
* gate is bypassed and the mode is applied via `resolveSavePath`.
|
|
19
19
|
*/
|
|
20
|
-
onConflict?:
|
|
20
|
+
onConflict?: ConflictMode | undefined;
|
|
21
21
|
};
|
|
22
22
|
export type PlanSaveFlowOutput = {
|
|
23
23
|
kind: 'write';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Command } from 'commander';
|
|
2
|
-
export declare const AGENT_DESCRIPTION
|
|
2
|
+
export declare const AGENT_DESCRIPTION: string;
|
|
3
3
|
export declare const MODEL_DESCRIPTION = "Model to use (defaults to a lightweight per-agent model; override with EDS_AGENT_MODEL_<AGENT>)";
|
|
4
4
|
export interface AgentModelOptionsConfig {
|
|
5
5
|
agentDescription?: string;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
import { AGENT_NAMES } from './agent-names.js';
|
|
2
|
+
export const AGENT_DESCRIPTION = `Agent to use: ${AGENT_NAMES.join(', ')} (defaults to value saved by experiences setup)`;
|
|
2
3
|
export const MODEL_DESCRIPTION = 'Model to use (defaults to a lightweight per-agent model; override with EDS_AGENT_MODEL_<AGENT>)';
|
|
3
4
|
/**
|
|
4
5
|
* Register --agent and optionally --model flags to a Commander command, with customizable descriptions.
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
export declare function addArtifactInputOptions(cmd: Command): Command;
|
|
3
|
+
export declare function addContentfulTargetOptions(cmd: Command): Command;
|
|
4
|
+
export declare function addCompositionOptions(cmd: Command): Command;
|
|
5
|
+
export declare function addSelectionOptions(cmd: Command): Command;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export function addArtifactInputOptions(cmd) {
|
|
2
|
+
return cmd
|
|
3
|
+
.option('--components <path>', 'Path to components.json (CDF)')
|
|
4
|
+
.option('--tokens <path>', 'Path to tokens.json (DTCG)')
|
|
5
|
+
.option('--session <id>', 'Pipeline session ID to load generated components from');
|
|
6
|
+
}
|
|
7
|
+
export function addContentfulTargetOptions(cmd) {
|
|
8
|
+
return cmd
|
|
9
|
+
.requiredOption('--space-id <id>', 'Contentful space ID')
|
|
10
|
+
.requiredOption('--environment-id <id>', 'Contentful environment ID')
|
|
11
|
+
.option('--cma-token <token>', 'CMA personal access token (or set CONTENTFUL_MANAGEMENT_TOKEN)')
|
|
12
|
+
.option('--host <url>', 'Override API base URL');
|
|
13
|
+
}
|
|
14
|
+
export function addCompositionOptions(cmd) {
|
|
15
|
+
return cmd
|
|
16
|
+
.option('--composite', 'Import embedded-component hierarchy (opt in; default is atomic)')
|
|
17
|
+
.option('--atomic', 'Import flat components with no embedded-component hierarchy (default)');
|
|
18
|
+
}
|
|
19
|
+
function collectOptionValue(value, previous) {
|
|
20
|
+
return [...previous, value];
|
|
21
|
+
}
|
|
22
|
+
export function addSelectionOptions(cmd) {
|
|
23
|
+
return cmd
|
|
24
|
+
.option('--select-all', 'Select all entities without launching TUI')
|
|
25
|
+
.option('--select <pattern>', 'Select entities by ID pattern (repeatable)', collectOptionValue, [])
|
|
26
|
+
.option('--deselect <pattern>', 'Deselect entities by ID pattern (repeatable)', collectOptionValue, []);
|
|
27
|
+
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
export
|
|
1
|
+
export declare const COMPOSITION_MODES: readonly ["composite", "atomic"];
|
|
2
|
+
export type CompositionMode = (typeof COMPOSITION_MODES)[number];
|
|
3
|
+
export declare function isCompositionMode(value: string): value is CompositionMode;
|
|
2
4
|
/**
|
|
3
5
|
* Options that, when present, IMPLY composite mode — passing any of them is a
|
|
4
6
|
* clear opt-in, so requiring an explicit `--composite` alongside is redundant.
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
export const COMPOSITION_MODES = ['composite', 'atomic'];
|
|
2
|
+
export function isCompositionMode(value) {
|
|
3
|
+
return COMPOSITION_MODES.includes(value);
|
|
4
|
+
}
|
|
1
5
|
function hasCompositionSource(opts) {
|
|
2
6
|
return !!opts.compositionMap || !!opts.compositionAgent || !!opts.compositionRefresh || !!opts.generateMap;
|
|
3
7
|
}
|
|
@@ -26,12 +30,10 @@ export function resolveCompositionMode(opts, configMode) {
|
|
|
26
30
|
const env = process.env['EXPERIENCES_COMPOSITION_MODE'];
|
|
27
31
|
if (env !== undefined && env !== '') {
|
|
28
32
|
const v = env.toLowerCase();
|
|
29
|
-
if (v
|
|
30
|
-
return
|
|
31
|
-
if (v === 'atomic')
|
|
32
|
-
return 'atomic';
|
|
33
|
+
if (isCompositionMode(v))
|
|
34
|
+
return v;
|
|
33
35
|
}
|
|
34
|
-
if (configMode
|
|
36
|
+
if (configMode && isCompositionMode(configMode))
|
|
35
37
|
return configMode;
|
|
36
38
|
return 'atomic';
|
|
37
39
|
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Thin indirection so `runModifyCommand` can be unit-tested without spinning
|
|
3
3
|
* up the real Ink wizard. The production implementation lives here.
|
|
4
4
|
*/
|
|
5
|
+
import type { CompositionMode } from '../lib/composition-mode.js';
|
|
5
6
|
export type ModifyLauncherInput = {
|
|
6
7
|
extractSessionId: string;
|
|
7
8
|
generateSessionId: string | null;
|
|
@@ -15,7 +16,7 @@ export type ModifyLauncherInput = {
|
|
|
15
16
|
saveMode: 'overwrite' | 'new' | 'prompt';
|
|
16
17
|
/** Composition mode from the run record, so the modify wizard resumes in the
|
|
17
18
|
* same mode. Omitted → the wizard's default (`atomic`). */
|
|
18
|
-
compositionMode?:
|
|
19
|
+
compositionMode?: CompositionMode;
|
|
19
20
|
outDirOverride?: string;
|
|
20
21
|
/** Pre-fill space id (from the run record's pushedTo). */
|
|
21
22
|
initialSpaceId?: string;
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
export declare const CONFLICT_MODES: readonly ["overwrite", "skip", "fail"];
|
|
2
|
+
export type ConflictMode = (typeof CONFLICT_MODES)[number];
|
|
3
|
+
export declare function isConflictMode(value: string): value is ConflictMode;
|
|
1
4
|
/**
|
|
2
5
|
* Returns true if `components.json` or `tokens.json` already exists at `path`.
|
|
3
6
|
* Used by the wizard to decide whether to render the save-conflict gate before
|
|
@@ -16,10 +19,9 @@ export declare function buildTimestampedSubdir(base: string, now?: Date): string
|
|
|
16
19
|
* - `skip` — write to a timestamped subdir under the requested path.
|
|
17
20
|
* - `fail` — refuse to write; surface the conflicting filenames.
|
|
18
21
|
*/
|
|
19
|
-
export type OnConflictMode = 'overwrite' | 'skip' | 'fail';
|
|
20
22
|
export type ResolveSavePathOptions = {
|
|
21
23
|
/** When provided, applies the chosen mode automatically (no interactive gate). */
|
|
22
|
-
onConflict?:
|
|
24
|
+
onConflict?: ConflictMode;
|
|
23
25
|
/** Injected for deterministic tests; falls back to `new Date()`. */
|
|
24
26
|
now?: Date;
|
|
25
27
|
};
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { access } from 'node:fs/promises';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
|
+
export const CONFLICT_MODES = ['overwrite', 'skip', 'fail'];
|
|
4
|
+
export function isConflictMode(value) {
|
|
5
|
+
return CONFLICT_MODES.includes(value);
|
|
6
|
+
}
|
|
3
7
|
/**
|
|
4
8
|
* The set of files the wizard / CLI may overwrite in the save directory.
|
|
5
9
|
* Centralised so conflict detection and conflict reporting stay in lock-step.
|
package/dist/src/runs/store.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { CompositionMode } from '../lib/composition-mode.js';
|
|
1
2
|
export declare const RUNS_FILE_VERSION: 3;
|
|
2
3
|
export declare const RUNS_FILE_CAP = 200;
|
|
3
4
|
/** Versions this CLI can read. v1 / v2 files are auto-migrated in memory;
|
|
@@ -58,7 +59,7 @@ export type RunRecord = {
|
|
|
58
59
|
/** Composition mode the run was produced in, so modify/replay resumes in the
|
|
59
60
|
* same mode (`composite` vs `atomic`). Absent on records written before this
|
|
60
61
|
* field existed; callers treat a missing value as `atomic` (the default). */
|
|
61
|
-
compositionMode?:
|
|
62
|
+
compositionMode?: CompositionMode;
|
|
62
63
|
notes?: string;
|
|
63
64
|
};
|
|
64
65
|
export type RunsFile = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentful/experience-design-system-cli",
|
|
3
|
-
"version": "2.16.2-dev-build-
|
|
3
|
+
"version": "2.16.2-dev-build-a6d3bd1.0",
|
|
4
4
|
"description": "Contentful Experiences design system import CLI",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
"react": "^18.3.1",
|
|
35
35
|
"react-devtools-core": "^4.19.1",
|
|
36
36
|
"react-dom": "^18.3.1",
|
|
37
|
-
"@contentful/experience-design-system-extraction": "2.16.2-dev-build-
|
|
38
|
-
"@contentful/experience-design-system-types": "2.16.2-dev-build-
|
|
37
|
+
"@contentful/experience-design-system-extraction": "2.16.2-dev-build-a6d3bd1.0",
|
|
38
|
+
"@contentful/experience-design-system-types": "2.16.2-dev-build-a6d3bd1.0"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@tsconfig/node24": "^24.0.3",
|