@contentful/experience-design-system-cli 2.37.1-dev-build-91b5f8aa.0 → 2.37.1-dev-build-fb8573b6.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 +4337 -500
- package/dist/index.js +5597 -1475
- package/dist/package.json +2 -1
- package/dist/src/tui/import/spawn-v1-import.d.ts +3 -3
- package/dist/src/tui/import/steps/04-credentials/logic.d.ts +0 -3
- package/dist/src/tui/import/steps/04-credentials/validate.d.ts +1 -1
- package/dist/src/tui/import/steps/05-token-reuse/logic.d.ts +1 -2
- package/dist/src/tui/import/steps/06-extraction/logic.d.ts +69 -0
- package/dist/src/tui/import/steps/06-extraction/processes.d.ts +45 -0
- package/dist/src/tui/import/steps/06-extraction/run.d.ts +24 -0
- package/dist/src/tui/import/steps/06-extraction/screen.d.ts +10 -0
- package/dist/src/tui/import/steps/06-extraction/selection.d.ts +18 -0
- package/dist/src/tui/import/steps/06-extraction/types.d.ts +44 -0
- package/dist/src/tui/import/steps/06-extraction/use-extraction.d.ts +14 -0
- package/dist/src/tui/import/steps/index.d.ts +1 -0
- package/legacy/dist/src/import/tui/WizardApp.d.ts +0 -8
- package/legacy/dist/src/import/tui/handoff.d.ts +26 -0
- package/legacy/dist/src/index.js +75 -628
- package/legacy/package.json +2 -1
- package/package.json +4 -3
- package/legacy/dist/src/import/tui/run-selection-agent.d.ts +0 -9
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentful/experience-design-system-cli",
|
|
3
|
-
"version": "2.37.1-dev-build-
|
|
3
|
+
"version": "2.37.1-dev-build-fb8573b6.0",
|
|
4
4
|
"description": "Contentful Experiences design system import CLI",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@contentful/experience-design-system-backend-pipeline": "workspace:*",
|
|
41
|
+
"@contentful/experience-design-system-generation": "workspace:*",
|
|
41
42
|
"@contentful/experience-design-system-types": "workspace:*",
|
|
42
43
|
"@inkjs/ui": "^2.0.0",
|
|
43
44
|
"@segment/analytics-node": "^3.0.0",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ImportOptions } from '../../commands/import-options.js';
|
|
2
|
-
import type
|
|
2
|
+
import { type ImportHandoff } from '@contentful/experience-design-system-types/handoff';
|
|
3
3
|
interface StepResult {
|
|
4
4
|
step: string;
|
|
5
5
|
status: 'complete' | 'failed' | 'skipped';
|
|
@@ -20,8 +20,8 @@ export interface SpawnV1ImportOptions extends Partial<ImportOptions> {
|
|
|
20
20
|
projectPath?: string;
|
|
21
21
|
tokens?: string;
|
|
22
22
|
filePaths?: string[];
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
/** What the CLI already settled and did; the legacy wizard starts from it. */
|
|
24
|
+
handoff?: ImportHandoff;
|
|
25
25
|
onProgress?: (line: string) => void;
|
|
26
26
|
}
|
|
27
27
|
export interface SpawnV1ImportResult {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
export declare const FIELDS: readonly ["spaceId", "environmentId", "cmaToken", "host"];
|
|
2
2
|
export type CredentialField = (typeof FIELDS)[number];
|
|
3
3
|
export type CredentialValues = Record<CredentialField, string>;
|
|
4
|
-
export declare const DEFAULT_HOST = "api.contentful.com";
|
|
5
4
|
interface Key {
|
|
6
5
|
escape: boolean;
|
|
7
6
|
tab: boolean;
|
|
@@ -10,8 +9,6 @@ interface Key {
|
|
|
10
9
|
export type KeyAction = 'back' | 'next-field' | 'skip' | null;
|
|
11
10
|
export declare function keyAction(input: string, key: Key): KeyAction;
|
|
12
11
|
export declare function nextField(field: CredentialField): CredentialField;
|
|
13
|
-
export declare function toConfiguredHost(host: string | undefined): string;
|
|
14
|
-
export declare function toApiHost(host: string): string;
|
|
15
12
|
export declare function normalize(values: CredentialValues): CredentialValues;
|
|
16
13
|
export declare function missingField(values: CredentialValues): boolean;
|
|
17
14
|
export declare function isUnchanged(current: CredentialValues, initial: CredentialValues): boolean;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type TokenStrategy
|
|
1
|
+
export type { TokenStrategy } from '../06-extraction/types.js';
|
|
2
2
|
export type TokensState = {
|
|
3
3
|
kind: 'none';
|
|
4
4
|
} | {
|
|
@@ -19,4 +19,3 @@ export declare function gateText({ tokensPath, sourceChanged }: {
|
|
|
19
19
|
summary: string;
|
|
20
20
|
context?: string;
|
|
21
21
|
};
|
|
22
|
-
export {};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { CompositionPhase, ExtractionProgress } from './types.js';
|
|
2
|
+
/** One line of the extract subprocess's stderr, decoded. Lines it does not recognise are ignored. */
|
|
3
|
+
export type ProgressEvent = {
|
|
4
|
+
kind: 'scan';
|
|
5
|
+
scanned: number;
|
|
6
|
+
} | {
|
|
7
|
+
kind: 'scan-done';
|
|
8
|
+
total: number;
|
|
9
|
+
} | {
|
|
10
|
+
kind: 'extract';
|
|
11
|
+
totalFiles: number;
|
|
12
|
+
} | {
|
|
13
|
+
kind: 'composition';
|
|
14
|
+
phase: CompositionPhase;
|
|
15
|
+
};
|
|
16
|
+
/** `progress=scan:12`, `progress=scan-done:40`, `progress=extract:3/40:7`, `progress=composition:cache-hit`. */
|
|
17
|
+
export declare function parseProgressLine(line: string): ProgressEvent | null;
|
|
18
|
+
/** `session=<id>` on the extract subprocess's stdout. It arrives before composition finishes, which is when selection starts. */
|
|
19
|
+
export declare function parseSessionLine(line: string): string | null;
|
|
20
|
+
/** The first `session=<id>` anywhere in a command's stdout. */
|
|
21
|
+
export declare function findSession(stdout: string): string | null;
|
|
22
|
+
/** `Extracted 7 components` in the extract command's stderr; 0 when it never printed one. */
|
|
23
|
+
export declare function parseExtractedCount(stderr: string): number;
|
|
24
|
+
/** `(12 tokens` in the output of `print tokens`. */
|
|
25
|
+
export declare function parsePrintTokensCount(stdout: string): number;
|
|
26
|
+
/**
|
|
27
|
+
* Every job the stage will run starts on the first frame, so no row appears later as a surprise. A job that does not
|
|
28
|
+
* apply stays 'idle' and has no row: existing entities need credentials, token definitions need a raw tokens file, and
|
|
29
|
+
* reused tokens are already complete.
|
|
30
|
+
*/
|
|
31
|
+
export declare function initialProgress(input: {
|
|
32
|
+
hasCredentials: boolean;
|
|
33
|
+
hasRawTokens: boolean;
|
|
34
|
+
reuseTokens: boolean;
|
|
35
|
+
}): ExtractionProgress;
|
|
36
|
+
export declare function applyProgressEvent(progress: ExtractionProgress, event: ProgressEvent): ExtractionProgress;
|
|
37
|
+
/** The rows the screen shows, in the order the wizard showed them. Rows that do not apply are left out. */
|
|
38
|
+
export declare function progressRows(progress: ExtractionProgress, agent: string): Array<{
|
|
39
|
+
text: string;
|
|
40
|
+
complete: boolean;
|
|
41
|
+
}>;
|
|
42
|
+
/** True when every job is already done, so the screen would only flash. The wizard shows nothing in this case. */
|
|
43
|
+
export declare function isFullCacheHit(progress: ExtractionProgress): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* The wizard's step counts: three fixed steps, one more when there is a token stage, two more when components are
|
|
46
|
+
* imported, and one more when the tokens can be mapped (not known yet at this stage, so it adds nothing here).
|
|
47
|
+
* Extraction is step 2 when there is a token stage, otherwise step 1.
|
|
48
|
+
*/
|
|
49
|
+
export declare function stepNumbers(input: {
|
|
50
|
+
hasRawTokens: boolean;
|
|
51
|
+
skipComponents?: boolean;
|
|
52
|
+
mapTokensEligible?: boolean | null;
|
|
53
|
+
}): {
|
|
54
|
+
stepNumber: number;
|
|
55
|
+
totalSteps: number;
|
|
56
|
+
};
|
|
57
|
+
export declare function noComponentsMessage(projectPath: string): string;
|
|
58
|
+
export declare function agentAuthMessage(agent: string, status: 'not-found' | 'unauthenticated'): string;
|
|
59
|
+
/**
|
|
60
|
+
* The agent and model the import runs with: what was typed after `--agent` (either `agent` or `agent:model`), else
|
|
61
|
+
* what `experiences setup` saved, else Claude with no model. Same chain the legacy import command uses.
|
|
62
|
+
*/
|
|
63
|
+
export declare function resolveAgentChoice(flag: string | undefined, stored: {
|
|
64
|
+
agent?: unknown;
|
|
65
|
+
agentModel?: unknown;
|
|
66
|
+
}): {
|
|
67
|
+
agent: string;
|
|
68
|
+
agentModel?: string;
|
|
69
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/** The legacy commands the stage drives, started the way the wizard starts them. */
|
|
2
|
+
export interface SpawnedResult {
|
|
3
|
+
exitCode: number;
|
|
4
|
+
stdout: string;
|
|
5
|
+
stderr: string;
|
|
6
|
+
}
|
|
7
|
+
export interface ExtractCommand {
|
|
8
|
+
projectPath: string;
|
|
9
|
+
agent: string;
|
|
10
|
+
promptOverrides: string[];
|
|
11
|
+
noCache: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface TokenGenerationInput {
|
|
14
|
+
rawTokensPath: string;
|
|
15
|
+
outDir: string;
|
|
16
|
+
agent: string;
|
|
17
|
+
agentModel?: string;
|
|
18
|
+
promptOverrides: string[];
|
|
19
|
+
noCache: boolean;
|
|
20
|
+
}
|
|
21
|
+
export type TokenGenerationResult = {
|
|
22
|
+
ok: true;
|
|
23
|
+
tokensPath: string;
|
|
24
|
+
tokenSessionId: string | null;
|
|
25
|
+
tokenCount: number;
|
|
26
|
+
} | {
|
|
27
|
+
ok: false;
|
|
28
|
+
step: 'generate tokens' | 'print tokens';
|
|
29
|
+
message: string;
|
|
30
|
+
};
|
|
31
|
+
/** Splits a stream into lines as chunks arrive, holding back a trailing partial line until the next chunk completes it. */
|
|
32
|
+
export declare function lineSplitter(onLine: (line: string) => void): (chunk: string) => void;
|
|
33
|
+
/** Arguments for `__extract`, in the order the wizard passes them. The extract command takes an agent but no model. */
|
|
34
|
+
export declare function buildExtractArgs(cliPath: string, command: ExtractCommand): string[];
|
|
35
|
+
/** Arguments for `__generate tokens`, in the order the wizard passes them. */
|
|
36
|
+
export declare function buildGenerateTokensArgs(cliPath: string, input: TokenGenerationInput): string[];
|
|
37
|
+
/** Arguments for `print tokens`, which writes the generated catalog next to the project. */
|
|
38
|
+
export declare function buildPrintTokensArgs(tokensPath: string, tokenSessionId: string | null): string[];
|
|
39
|
+
/** `node <legacy cli> __extract …`, with stderr and stdout delivered line by line while it runs. */
|
|
40
|
+
export declare function spawnExtract(command: ExtractCommand, handlers: {
|
|
41
|
+
onStderrLine: (line: string) => void;
|
|
42
|
+
onStdoutLine: (line: string) => void;
|
|
43
|
+
}): Promise<SpawnedResult>;
|
|
44
|
+
/** `__generate tokens`, then `print tokens` to write `<outDir>/tokens.json`. */
|
|
45
|
+
export declare function runTokenGeneration(input: TokenGenerationInput): Promise<TokenGenerationResult>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { checkAgentAuth } from '@contentful/experience-design-system-generation';
|
|
2
|
+
import { runTokenGeneration, spawnExtract } from './processes.js';
|
|
3
|
+
import { runSelection } from './selection.js';
|
|
4
|
+
import type { ExtractionInput, ExtractionProgress, ExtractionResult } from './types.js';
|
|
5
|
+
/** The outside world the stage talks to, so the order of events can be tested without a network, an agent or a CLI. */
|
|
6
|
+
export interface ExtractionDeps {
|
|
7
|
+
checkAgentAuth: typeof checkAgentAuth;
|
|
8
|
+
fetchEntities: (credentials: NonNullable<ExtractionInput['credentials']>, outDir: string) => Promise<string | null>;
|
|
9
|
+
spawnExtract: typeof spawnExtract;
|
|
10
|
+
runTokenGeneration: typeof runTokenGeneration;
|
|
11
|
+
runSelection: typeof runSelection;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Runs the stage. The jobs overlap exactly as they do in the legacy wizard:
|
|
15
|
+
*
|
|
16
|
+
* entities fetch ───────┐
|
|
17
|
+
* __extract ── session= ┴─ selection agent (waits for the fetch) ──┐
|
|
18
|
+
* └──────────────────────────────── exits (composition done) ─┴─ result
|
|
19
|
+
* __generate tokens → print tokens (only when the tokens are not being reused)
|
|
20
|
+
*
|
|
21
|
+
* Selection starts the moment the session id is printed, so it overlaps with composition. When more than one job
|
|
22
|
+
* fails, the error reported is the first of: extract, no components, selection, token generation.
|
|
23
|
+
*/
|
|
24
|
+
export declare function runExtraction(input: ExtractionInput, onProgress: (progress: ExtractionProgress) => void, deps?: ExtractionDeps): Promise<ExtractionResult>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { ExtractionProgress } from './types.js';
|
|
3
|
+
interface ExtractionScreenProps {
|
|
4
|
+
progress: ExtractionProgress;
|
|
5
|
+
agent: string;
|
|
6
|
+
stepNumber: number;
|
|
7
|
+
totalSteps: number;
|
|
8
|
+
}
|
|
9
|
+
export declare function ExtractionScreen({ progress, agent, stepNumber, totalSteps, }: ExtractionScreenProps): React.ReactElement;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type AgentName } from '@contentful/experience-design-system-generation';
|
|
2
|
+
export interface SelectionOptions {
|
|
3
|
+
sessionId: string;
|
|
4
|
+
agent: AgentName;
|
|
5
|
+
model?: string;
|
|
6
|
+
promptText?: string;
|
|
7
|
+
promptPath?: string;
|
|
8
|
+
noCache: boolean;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* The selection agent run, as the legacy wizard ran it.
|
|
12
|
+
*
|
|
13
|
+
* Reads the extracted components from the session database and skips the ones already decided (cache keyed by
|
|
14
|
+
* component hash, prompt hash and CLI version). It asks the agent about the rest, then writes accepted or rejected to
|
|
15
|
+
* raw_components and stores the new decisions in the cache in one transaction. Throws on a timeout, a non-zero exit,
|
|
16
|
+
* or a database error.
|
|
17
|
+
*/
|
|
18
|
+
export declare function runSelection(options: SelectionOptions): Promise<void>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { ExtractionHandoff, ImportHandoff } from '@contentful/experience-design-system-types/handoff';
|
|
2
|
+
export type TokenStrategy = ImportHandoff['tokens']['strategy'];
|
|
3
|
+
export interface ExtractionInput {
|
|
4
|
+
projectPath: string;
|
|
5
|
+
/** Raw tokens file the user pointed at (always set: v2 asks for one). */
|
|
6
|
+
rawTokensPath: string;
|
|
7
|
+
/** From the token reuse step. 'reuse' skips token generation entirely. */
|
|
8
|
+
tokenStrategy: TokenStrategy;
|
|
9
|
+
/** Null when the user skipped credentials: no existing-entities fetch happens. */
|
|
10
|
+
credentials: {
|
|
11
|
+
spaceId: string;
|
|
12
|
+
environmentId: string;
|
|
13
|
+
cmaToken: string;
|
|
14
|
+
host: string;
|
|
15
|
+
} | null;
|
|
16
|
+
agent: string;
|
|
17
|
+
agentModel?: string;
|
|
18
|
+
promptOverrides: string[];
|
|
19
|
+
noCache: boolean;
|
|
20
|
+
}
|
|
21
|
+
export type CompositionPhase = 'resolving' | 'cache-hit' | 'done' | `agent:${string}`;
|
|
22
|
+
type JobStatus = 'idle' | 'running' | 'complete' | 'failed';
|
|
23
|
+
/** Everything the extracting screen shows. One field per row. */
|
|
24
|
+
export interface ExtractionProgress {
|
|
25
|
+
scan: {
|
|
26
|
+
scanned: number;
|
|
27
|
+
total: number | null;
|
|
28
|
+
} | null;
|
|
29
|
+
composition: CompositionPhase;
|
|
30
|
+
selection: 'running' | 'complete';
|
|
31
|
+
existingEntities: JobStatus;
|
|
32
|
+
tokens: JobStatus;
|
|
33
|
+
}
|
|
34
|
+
/** The label the error screen shows, as the wizard labelled it. */
|
|
35
|
+
type ExtractionStepName = 'analyze extract' | 'selection agent' | 'generate tokens' | 'print tokens' | `${string} auth check`;
|
|
36
|
+
export type ExtractionResult = {
|
|
37
|
+
ok: true;
|
|
38
|
+
extraction: ExtractionHandoff;
|
|
39
|
+
} | {
|
|
40
|
+
ok: false;
|
|
41
|
+
step: ExtractionStepName;
|
|
42
|
+
message: string;
|
|
43
|
+
};
|
|
44
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ExtractionInput, ExtractionProgress, ExtractionResult } from './types.js';
|
|
2
|
+
export type ExtractionState = {
|
|
3
|
+
status: 'running';
|
|
4
|
+
progress: ExtractionProgress;
|
|
5
|
+
} | {
|
|
6
|
+
status: 'done';
|
|
7
|
+
result: ExtractionResult;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Runs the extraction stage once for the given input and reports its progress. Passing a different input starts a new
|
|
11
|
+
* run; passing nothing leaves the stage idle. A run that finishes after the input changed or the screen went away is
|
|
12
|
+
* ignored.
|
|
13
|
+
*/
|
|
14
|
+
export declare function useExtraction(input: ExtractionInput | undefined): ExtractionState | undefined;
|
|
@@ -3,3 +3,4 @@ export { TokenInputScreen } from './02-token-input/screen.js';
|
|
|
3
3
|
export { PathValidationScreen } from './03-path-validation/screen.js';
|
|
4
4
|
export { CredentialsScreen } from './04-credentials/screen.js';
|
|
5
5
|
export { TokenReuseScreen } from './05-token-reuse/screen.js';
|
|
6
|
+
export { ExtractionScreen } from './06-extraction/screen.js';
|
|
@@ -14,14 +14,6 @@ export declare function buildGenerateComponentsArgs(opts: {
|
|
|
14
14
|
restoreCache?: boolean;
|
|
15
15
|
cachedComponents?: string[];
|
|
16
16
|
}): string[];
|
|
17
|
-
export declare function buildGenerateTokensArgs(opts: {
|
|
18
|
-
rawTokensPath: string;
|
|
19
|
-
agent: string;
|
|
20
|
-
model?: string;
|
|
21
|
-
bedrock?: boolean;
|
|
22
|
-
noCache?: boolean;
|
|
23
|
-
promptOverrides?: string[];
|
|
24
|
-
}): string[];
|
|
25
17
|
export declare function buildMapTokensArgs(opts: {
|
|
26
18
|
sessionId: string;
|
|
27
19
|
agent: string;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type ImportHandoff } from '@contentful/experience-design-system-types/handoff';
|
|
2
|
+
/** The wizard state the early stages produce. Every field is one the stage used to write. */
|
|
3
|
+
export interface HandoffState {
|
|
4
|
+
credentialsSkipped: boolean;
|
|
5
|
+
tokensPath?: string;
|
|
6
|
+
tokenSessionId?: string | null;
|
|
7
|
+
tokenCount?: number;
|
|
8
|
+
tokenGenerationStatus?: 'complete';
|
|
9
|
+
outDir?: string;
|
|
10
|
+
extractSessionId?: string;
|
|
11
|
+
compositionPhase?: 'done' | 'cache-hit';
|
|
12
|
+
selectionAgentStatus?: 'complete';
|
|
13
|
+
existingEntitiesStatus?: 'idle' | 'complete' | 'failed';
|
|
14
|
+
existingEntitiesPath?: string | null;
|
|
15
|
+
}
|
|
16
|
+
export declare function stateFromHandoff(handoff: ImportHandoff): HandoffState;
|
|
17
|
+
export type StartFromHandoff = {
|
|
18
|
+
ok: true;
|
|
19
|
+
handoff: ImportHandoff;
|
|
20
|
+
state: HandoffState;
|
|
21
|
+
} | {
|
|
22
|
+
ok: false;
|
|
23
|
+
error: string;
|
|
24
|
+
};
|
|
25
|
+
/** Reads the handoff the CLI passed. A missing or broken one is an error to show, never a guess at a start. */
|
|
26
|
+
export declare function readHandoff(env?: NodeJS.ProcessEnv): StartFromHandoff;
|