@contentful/experience-design-system-cli 2.18.1-dev-build-b4ecc99.0 → 2.18.1-dev-build-180092e.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/experience-design-system-cli",
3
- "version": "2.18.1-dev-build-b4ecc99.0",
3
+ "version": "2.18.1-dev-build-180092e.0",
4
4
  "description": "Contentful Experiences design system import CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -25,7 +25,6 @@
25
25
  "files": [
26
26
  "bin/",
27
27
  "dist/",
28
- "skills/",
29
28
  "prompts/"
30
29
  ],
31
30
  "scripts": {
@@ -40,6 +39,7 @@
40
39
  "dependencies": {
41
40
  "@contentful/experience-design-system-client": "workspace:*",
42
41
  "@contentful/experience-design-system-extraction": "workspace:*",
42
+ "@contentful/experience-design-system-generation": "workspace:*",
43
43
  "@contentful/experience-design-system-types": "workspace:*",
44
44
  "commander": "^13.1.0",
45
45
  "ink": "^4.4.1",
@@ -51,11 +51,11 @@
51
51
  "@tsconfig/node24": "^24.0.3",
52
52
  "@types/node": "^24.0.3",
53
53
  "@types/react": "^18.3.24",
54
- "eslint": "^9.39.5",
54
+ "eslint": "^9.39.2",
55
55
  "eslint-config-prettier": "^10.1.8",
56
- "eslint-plugin-prettier": "^5.5.6",
56
+ "eslint-plugin-prettier": "^5.5.4",
57
57
  "ink-testing-library": "^4.0.0",
58
- "typescript-eslint": "^8.66.0",
58
+ "typescript-eslint": "^8.52.0",
59
59
  "vitest": "^4.0.16"
60
60
  },
61
61
  "repository": {
@@ -19,11 +19,11 @@ 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';
23
- import { runAgent } from '../generate/agent-runner.js';
22
+ import { DEFAULT_AGENT_NAME, isAgentName, runAgent, } from '@contentful/experience-design-system-generation';
24
23
  import { readExperiencesCredentials } from '../credentials-store.js';
25
24
  import { buildAnalyzeViewRows, partitionGlobalWarnings } from './build-analyze-view-rows.js';
26
25
  import { getInteractiveTerminalSupport } from '../lib/terminal-capabilities.js';
26
+ import { getDebugLogger } from '../lib/debug-logger.js';
27
27
  const SCANNED_FILE_EXTENSIONS = new Set(['.astro', '.js', '.jsx', '.svelte', '.ts', '.tsx', '.vue']);
28
28
  const IGNORED_DIRECTORY_NAMES = new Set([
29
29
  '.git',
@@ -351,9 +351,9 @@ export function registerAnalyzeCommand(program) {
351
351
  const res = await runAgent({
352
352
  agent: resolverAgent,
353
353
  prompt,
354
- interactive: false,
355
354
  timeoutMs: 120_000,
356
355
  promptViaStdin: true,
356
+ onDebugEvent: (name, payload) => getDebugLogger().event('agent', name, payload),
357
357
  });
358
358
  lastAgentExitCode = res.exitCode;
359
359
  if (res.exitCode !== 0 && res.stderr.trim()) {
@@ -2,7 +2,7 @@ import type { CompositionEdge } from './interchange-schema.js';
2
2
  /**
3
3
  * Lenient JSONL parser for the composition-mapping agent's tool-call output
4
4
  * (spec T4). Mirrors `parseSelectToolCallLines` / `parseToolCallLines` in
5
- * `src/generate/agent-runner.ts`: one JSON object per line, each with a `tool`
5
+ * `@contentful/experience-design-system-generation`'s `agent-runner.ts`: one JSON object per line, each with a `tool`
6
6
  * field from a fixed allowlist. A line that fails JSON.parse or validation is
7
7
  * DROPPED into `warnings[]` (with a reason) and parsing CONTINUES — no retry,
8
8
  * no throw. Non-`{` prose and blank lines are skipped silently.
@@ -3,19 +3,21 @@ import { openPipelineDb, loadRawComponents, loadScannedFiles, createStep, update
3
3
  import { hashPromptForSkill } from '../../session/cache-keys.js';
4
4
  import { appendReviewEvent, getRefineArtifactsRoot, ensureRefineSession, getRefineSessionPaths, saveReviewState, } from '../select/persistence.js';
5
5
  import { loadReviewInput } from '../select/parser.js';
6
- import { buildPrompt } from '../../generate/prompt-builder.js';
7
- import { formatCustomPromptBanner } from '../../generate/command.js';
8
- import { AGENT_NAMES, isAgentName, parseSelectToolCallLines, runAgent } from '../../generate/agent-runner.js';
6
+ import { AGENT_NAMES, buildPrompt, createLocalCliAgentInvoker, formatCustomPromptBanner, isAgentName, parseSelectToolCallLines, } from '@contentful/experience-design-system-generation';
9
7
  import { access } from 'node:fs/promises';
10
8
  import { readExperiencesCredentials } from '../../credentials-store.js';
11
9
  import { OutputFormatter, c } from '../../output/format.js';
12
10
  import { buildRepoContextIndex, buildSelectionContext } from './context-builder.js';
13
11
  import { runShowRationale } from './show-rationale.js';
14
12
  import { isAbsolute, resolve } from 'node:path';
13
+ import { getDebugLogger } from '../../lib/debug-logger.js';
15
14
  import { validateExtractedComponents, shouldExcludeDueToValidation, formatExclusionWarning, } from '@contentful/experience-design-system-extraction';
16
15
  const DEFAULT_TIMEOUT_MS = Number(process.env.EDS_AGENT_TIMEOUT_MS ?? 3 * 60 * 1000);
17
16
  export const DEFAULT_CONCURRENCY = 10;
18
17
  export const DEFAULT_BATCH_SIZE = 5;
18
+ const invoker = createLocalCliAgentInvoker({
19
+ onDebugEvent: (name, payload) => getDebugLogger().event('agent', name, payload),
20
+ });
19
21
  function resolveBatchSize() {
20
22
  const raw = process.env.EDS_SELECT_BATCH_SIZE;
21
23
  if (!raw)
@@ -109,11 +111,10 @@ async function selectBatch(agent, model, batch, total, verbose, skillPathOverrid
109
111
  const formatter = new OutputFormatter(verbose, (s) => {
110
112
  outputBuf += s;
111
113
  });
112
- const result = await runAgent({
114
+ const result = await invoker.invoke({
113
115
  agent,
114
116
  model,
115
117
  prompt,
116
- interactive: false,
117
118
  timeoutMs: DEFAULT_TIMEOUT_MS,
118
119
  onOutput: (chunk) => formatter.push(chunk),
119
120
  });
@@ -1,8 +1,2 @@
1
1
  import type { Command } from 'commander';
2
- /**
3
- * Feature 8: render the warning banner shown when a custom skill prompt is
4
- * active. Always cites the bundled invariants that the override bypasses so
5
- * the operator cannot miss it.
6
- */
7
- export declare function formatCustomPromptBanner(skill: 'components' | 'select', path: string): string;
8
2
  export declare function registerGenerateCommand(program: Command): void;
@@ -4,10 +4,9 @@ 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 { AGENT_NAMES, describeAgentFailure, isAgentName, parseToolCallLines, parseTokenToolCallLines, resolveBinary, runAgent, } from './agent-runner.js';
7
+ import { AGENT_NAMES, createLocalCliAgentInvoker, describeAgentFailure, formatCustomPromptBanner, formatGenerateProgressLine, isAgentName, parseToolCallLines, parseTokenToolCallLines, resolveBinary, resolveSkillPath, buildPrompt, } from '@contentful/experience-design-system-generation';
8
8
  import { OutputFormatter, c } from '../output/format.js';
9
- import { formatGenerateProgressLine } from './progress.js';
10
- import { buildPrompt, resolveSkillPath } from './prompt-builder.js';
9
+ import { getDebugLogger } from '../lib/debug-logger.js';
11
10
  import { GenerateView } from './tui/GenerateView.js';
12
11
  import { registerGenerateEditCommand } from './edit/command.js';
13
12
  import { openPipelineDb, loadRawComponents, applyToolCalls, applyTokenToolCalls, computeComponentInputHash, computeTokenInputHash, lookupCache, lookupCacheByEntity, storeCache, copyComponentFromCache, copyTokensFromCache, renameEmptySlots, } from '../session/db.js';
@@ -19,16 +18,9 @@ const execFileAsync = promisify(execFile);
19
18
  const DEFAULT_TIMEOUT_MS = Number(process.env.EDS_AGENT_TIMEOUT_MS ?? 3 * 60 * 1000);
20
19
  const DEFAULT_COMPONENT_CONCURRENCY = 10;
21
20
  const RETRY_BACKOFF_MS = Number(process.env.EDS_RETRY_BACKOFF_MS ?? 5_000);
22
- /**
23
- * Feature 8: render the warning banner shown when a custom skill prompt is
24
- * active. Always cites the bundled invariants that the override bypasses so
25
- * the operator cannot miss it.
26
- */
27
- export function formatCustomPromptBanner(skill, path) {
28
- return (`WARNING: Custom prompt active for ${skill}: ${path}\n` +
29
- ` Bundled invariants (utility-wrapper rejection, description content rules) do NOT apply.\n` +
30
- ` You are responsible for the prompt's correctness.\n`);
31
- }
21
+ const invoker = createLocalCliAgentInvoker({
22
+ onDebugEvent: (name, payload) => getDebugLogger().event('agent', name, payload),
23
+ });
32
24
  function die(message) {
33
25
  process.stderr.write(`${message}\n`);
34
26
  process.exit(1);
@@ -191,11 +183,10 @@ async function runOneComponent(agent, model, db, sessionId, component, tokensInl
191
183
  const formatter = new OutputFormatter(verbose, (s) => {
192
184
  outputBuf += s;
193
185
  });
194
- const result = await runAgent({
186
+ const result = await invoker.invoke({
195
187
  agent,
196
188
  model,
197
189
  prompt,
198
- interactive: false,
199
190
  timeoutMs: DEFAULT_TIMEOUT_MS,
200
191
  onOutput: (chunk) => formatter.push(chunk),
201
192
  });
@@ -512,11 +503,10 @@ async function runGenerateSkill(skill, opts, verbose = false) {
512
503
  tokenMapInline,
513
504
  outDir: process.cwd(),
514
505
  });
515
- const result = await runAgent({
506
+ const result = await invoker.invoke({
516
507
  agent,
517
508
  model,
518
509
  prompt,
519
- interactive: false,
520
510
  timeoutMs: DEFAULT_TIMEOUT_MS * 5,
521
511
  });
522
512
  if (result.timedOut) {
@@ -50,7 +50,7 @@ import { mergeAiDecisions } from './merge-ai-decisions.js';
50
50
  import { FinalReviewHost } from './final-review-host.js';
51
51
  import { runScopeGate } from './runScopeGate.js';
52
52
  import { buildAutoFilterErrorTail } from './auto-filter-error.js';
53
- import { checkAgentAuth } from '../../generate/agent-runner.js';
53
+ import { checkAgentAuth } from '@contentful/experience-design-system-generation';
54
54
  import { normalizePath } from '../path-utils.js';
55
55
  import { DEFAULT_CONFIGURED_HOST, toConfiguredHost } from '../../host-utils.js';
56
56
  import { writeExperiencesCredentials } from '../../credentials-store.js';
@@ -1,4 +1,4 @@
1
- import { AGENT_NAMES } from './agent-names.js';
1
+ import { AGENT_NAMES } from '@contentful/experience-design-system-generation';
2
2
  export const AGENT_DESCRIPTION = `Agent to use: ${AGENT_NAMES.join(', ')} (defaults to value saved by experiences setup)`;
3
3
  export const MODEL_DESCRIPTION = 'Model to use (defaults to a lightweight per-agent model; override with EDS_AGENT_MODEL_<AGENT>)';
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { type Skill } from '../generate/prompt-builder.js';
1
+ import { type Skill } from '@contentful/experience-design-system-generation';
2
2
  /** sha256 hex of a string. Stable across runs. */
3
3
  export declare function hashContent(content: string): string;
4
4
  /** sha256 hex of a file's UTF-8 content. */
@@ -10,7 +10,7 @@
10
10
  import { createHash } from 'node:crypto';
11
11
  import { readFile } from 'node:fs/promises';
12
12
  import { resolve } from 'node:path';
13
- import { resolveSkillPath } from '../generate/prompt-builder.js';
13
+ import { resolveSkillPath } from '@contentful/experience-design-system-generation';
14
14
  /** sha256 hex of a string. Stable across runs. */
15
15
  export function hashContent(content) {
16
16
  return createHash('sha256').update(content).digest('hex');
@@ -1,7 +1,7 @@
1
1
  import { DatabaseSync } from 'node:sqlite';
2
2
  import type { RawComponentDefinition } from '../types.js';
3
3
  import type { CDFComponentEntry, DTCGTokenEntry, DTCGTokenGroup } from '@contentful/experience-design-system-types';
4
- import type { ToolCall, TokenToolCall } from '../generate/agent-runner.js';
4
+ import type { ToolCall, TokenToolCall } from '@contentful/experience-design-system-generation';
5
5
  import type { ComponentTypeSummary } from '@contentful/experience-design-system-types';
6
6
  import type { SlotCycle, SlotEdge } from '../analyze/cycle-detection.js';
7
7
  export type StepStatus = 'pending' | 'complete' | 'failed' | 'interrupted';
@@ -1433,7 +1433,7 @@ export async function getCliCacheVersion() {
1433
1433
  return _cliCacheVersionCache;
1434
1434
  try {
1435
1435
  const { hashContent } = await import('./cache-keys.js');
1436
- const { resolveSkillPath } = await import('../generate/prompt-builder.js');
1436
+ const { resolveSkillPath } = await import('@contentful/experience-design-system-generation');
1437
1437
  const skills = ['components', 'tokens', 'select'];
1438
1438
  const parts = [];
1439
1439
  for (const s of skills) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/experience-design-system-cli",
3
- "version": "2.18.1-dev-build-b4ecc99.0",
3
+ "version": "2.18.1-dev-build-180092e.0",
4
4
  "description": "Contentful Experiences design system import CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -25,7 +25,6 @@
25
25
  "files": [
26
26
  "bin/",
27
27
  "dist/",
28
- "skills/",
29
28
  "prompts/"
30
29
  ],
31
30
  "dependencies": {
@@ -34,19 +33,20 @@
34
33
  "react": "^18.3.1",
35
34
  "react-devtools-core": "^4.19.1",
36
35
  "react-dom": "^18.3.1",
37
- "@contentful/experience-design-system-client": "2.18.1-dev-build-b4ecc99.0",
38
- "@contentful/experience-design-system-extraction": "2.18.1-dev-build-b4ecc99.0",
39
- "@contentful/experience-design-system-types": "2.18.1-dev-build-b4ecc99.0"
36
+ "@contentful/experience-design-system-generation": "2.18.1-dev-build-180092e.0",
37
+ "@contentful/experience-design-system-extraction": "2.18.1-dev-build-180092e.0",
38
+ "@contentful/experience-design-system-types": "2.18.1-dev-build-180092e.0",
39
+ "@contentful/experience-design-system-client": "2.18.1-dev-build-180092e.0"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@tsconfig/node24": "^24.0.3",
43
43
  "@types/node": "^24.0.3",
44
44
  "@types/react": "^18.3.24",
45
- "eslint": "^9.39.5",
45
+ "eslint": "^9.39.2",
46
46
  "eslint-config-prettier": "^10.1.8",
47
- "eslint-plugin-prettier": "^5.5.6",
47
+ "eslint-plugin-prettier": "^5.5.4",
48
48
  "ink-testing-library": "^4.0.0",
49
- "typescript-eslint": "^8.66.0",
49
+ "typescript-eslint": "^8.52.0",
50
50
  "vitest": "^4.0.16"
51
51
  },
52
52
  "repository": {
@@ -1,125 +0,0 @@
1
- import type { AgentName } from '../lib/agent-names.js';
2
- export { AGENT_NAMES, isAgentName, type AgentName } from '../lib/agent-names.js';
3
- export interface AgentRunResult {
4
- exitCode: number;
5
- stdout: string;
6
- stderr: string;
7
- timedOut: boolean;
8
- }
9
- export interface ClassifyPropCall {
10
- tool: 'classify_prop';
11
- prop: string;
12
- cdf_type: string;
13
- cdf_category: 'content' | 'design' | 'state';
14
- values?: string[];
15
- token_kind?: string;
16
- required?: boolean;
17
- description?: string;
18
- default?: string | boolean;
19
- /** Internal LLM rationale; not customer-facing. Persisted to raw_props.rationale. */
20
- reason?: string;
21
- }
22
- export interface ExcludePropCall {
23
- tool: 'exclude_prop';
24
- prop: string;
25
- reason: string;
26
- }
27
- export interface ClassifyComponentCall {
28
- tool: 'classify_component';
29
- description?: string;
30
- /**
31
- * Component-level rationale strings. Surfaced by the `I` ComponentRationalePanel.
32
- * Each field is optional; missing fields leave existing DB values untouched
33
- * (sparse update semantics in applyToolCalls).
34
- */
35
- rationale?: {
36
- description?: string;
37
- props?: string;
38
- slots?: string;
39
- };
40
- }
41
- export interface ClassifySlotCall {
42
- tool: 'classify_slot';
43
- slot: string;
44
- required?: boolean;
45
- allowed_components?: string[];
46
- description?: string;
47
- /** Per-slot rationale; persisted to raw_slots.rationale. */
48
- rationale?: string;
49
- }
50
- export type ToolCall = ClassifyPropCall | ExcludePropCall | ClassifyComponentCall | ClassifySlotCall;
51
- export interface SelectComponentCall {
52
- tool: 'select_component';
53
- name: string;
54
- reason?: string;
55
- confidence?: number;
56
- }
57
- export interface RejectComponentCall {
58
- tool: 'reject_component';
59
- name: string;
60
- reason?: string;
61
- confidence?: number;
62
- }
63
- export type SelectToolCall = SelectComponentCall | RejectComponentCall;
64
- export interface ParsedSelectToolCalls {
65
- calls: SelectToolCall[];
66
- warnings: string[];
67
- }
68
- export declare function parseSelectToolCallLines(stdout: string): ParsedSelectToolCalls;
69
- export interface SetTokenCall {
70
- tool: 'set_token';
71
- path: string;
72
- type: string;
73
- value: unknown;
74
- description?: string;
75
- }
76
- export interface SetGroupCall {
77
- tool: 'set_group';
78
- path: string;
79
- description?: string;
80
- }
81
- export type TokenToolCall = SetTokenCall | SetGroupCall;
82
- export interface ParsedTokenToolCalls {
83
- calls: TokenToolCall[];
84
- warnings: string[];
85
- }
86
- export interface ParsedToolCalls {
87
- calls: ToolCall[];
88
- warnings: string[];
89
- }
90
- export declare function parseToolCallLines(stdout: string): ParsedToolCalls;
91
- export declare function parseTokenToolCallLines(stdout: string): ParsedTokenToolCalls;
92
- export declare function resolveBinary(agent: AgentName): string;
93
- /**
94
- * Resolve the model for an agent. Explicit flag/creds value wins, then a
95
- * per-agent `EDS_AGENT_MODEL_<AGENT>` env override (mirrors the
96
- * `EDS_AGENT_BINARY_<AGENT>` pattern), otherwise the lightweight default for
97
- * that agent.
98
- */
99
- export declare function resolveAgentModel(agent: AgentName, explicit?: string): string;
100
- export declare function buildArgs(agent: AgentName, prompt: string, model?: string, promptViaStdin?: boolean): string[];
101
- export declare function runAgent(options: {
102
- agent: AgentName;
103
- prompt: string;
104
- interactive: boolean;
105
- timeoutMs: number;
106
- model?: string;
107
- onOutput?: (chunk: string) => void;
108
- /**
109
- * Deliver the prompt on stdin instead of as an argv positional. Required for
110
- * large prompts (e.g. the composition resolver inlining candidate files),
111
- * which overflow ARG_MAX when passed as an argument. Non-interactive only.
112
- */
113
- promptViaStdin?: boolean;
114
- }): Promise<AgentRunResult>;
115
- export type AgentAuthStatus = 'ok' | 'unauthenticated' | 'not-found';
116
- export declare function checkAgentAuth(agent: AgentName): Promise<AgentAuthStatus>;
117
- /**
118
- * Build a diagnostic string from a failed agent run, surfacing the agent's own
119
- * stderr (or stdout, when stderr is empty) so callers never emit a context-free
120
- * "agent failed". Callers only invoke this on a failed run: either a non-zero
121
- * exit, or a zero exit that produced no tool calls. A non-zero exit is reported
122
- * as such; a zero exit is therefore the "produced no tool calls" case.
123
- */
124
- export declare function describeAgentFailure(result: AgentRunResult, maxDetail?: number): string;
125
- export declare function extractSentinelOutput(stdout: string): string | null | 'multiple';