@contentful/experience-design-system-cli 2.32.1-dev-build-a0479a6.0 → 2.32.1-dev-build-81eb804.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/api/clients/cma-client.d.ts +13 -0
- package/dist/src/api/clients/edsi-client.d.ts +47 -0
- package/dist/src/api/index.d.ts +10 -0
- package/dist/src/apply/api-client.d.ts +4 -68
- package/dist/src/errors/api-error.d.ts +6 -0
- package/dist/src/helpers/http.d.ts +4 -0
- package/dist/src/helpers/url.d.ts +4 -0
- package/dist/src/host-utils.d.ts +1 -4
- package/dist/src/import/orchestrator.d.ts +9 -0
- package/dist/src/index.js +227 -60
- package/dist/src/interfaces/clients/cma-client-options.d.ts +6 -0
- package/dist/src/interfaces/clients/edsi-client-options.d.ts +12 -0
- package/dist/src/interfaces/clients/poll-options.d.ts +7 -0
- package/dist/src/interfaces/responses/existing-component-entity.d.ts +8 -0
- package/dist/src/interfaces/responses/existing-entities-response.d.ts +6 -0
- package/dist/src/interfaces/responses/existing-token-entity.d.ts +6 -0
- package/dist/src/session/db.d.ts +1 -1
- package/dist/src/setup/command.d.ts +0 -6
- package/package.json +6 -6
package/dist/package.json
CHANGED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { CmaClientOptions } from '../../interfaces/clients/cma-client-options.js';
|
|
2
|
+
import type { ExistingEntitiesResponse } from '../../interfaces/responses/existing-entities-response.js';
|
|
3
|
+
export declare class CmaApiClient {
|
|
4
|
+
private host;
|
|
5
|
+
private token;
|
|
6
|
+
private spaceId;
|
|
7
|
+
private environmentId;
|
|
8
|
+
constructor(opts: CmaClientOptions);
|
|
9
|
+
private base;
|
|
10
|
+
validateToken(): Promise<void>;
|
|
11
|
+
listExistingEntities(): Promise<ExistingEntitiesResponse>;
|
|
12
|
+
private listAll;
|
|
13
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { ManifestPayload, ServerPreviewResponse, ApplyOperationResponse, BreakingChange } from '@contentful/experience-design-system-types';
|
|
2
|
+
import type { EdsiClientOptions } from '../../interfaces/clients/edsi-client-options.js';
|
|
3
|
+
import type { PollOptions } from '../../interfaces/clients/poll-options.js';
|
|
4
|
+
export declare const DEFAULT_HOST = "https://api.contentful.com";
|
|
5
|
+
export declare const PREVIEW_ERROR_PREFIX = "preview failed:";
|
|
6
|
+
export declare const APPLY_ERROR_PREFIX = "apply failed:";
|
|
7
|
+
export declare const VALIDATION_FAILED_CODE = "\"ValidationFailed\"";
|
|
8
|
+
export interface PreviewValidationError {
|
|
9
|
+
componentName: string;
|
|
10
|
+
path: string;
|
|
11
|
+
message: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Parse the JSON body of a 422 from `previewImport()` into structured
|
|
15
|
+
* per-component validation errors. Returns [] for any malformed input
|
|
16
|
+
* so callers can fall back to the generic error path without try/catch.
|
|
17
|
+
*
|
|
18
|
+
* Path shape: `manifest:components/<Name>/$slots/<key>` or
|
|
19
|
+
* `manifest:components/<Name>/$properties/<key>`. Only the component
|
|
20
|
+
* name is extracted today; `path` and `message` are kept verbatim so
|
|
21
|
+
* future surfaces (debug logging, headless retry in SP-4) can render
|
|
22
|
+
* the field-level detail.
|
|
23
|
+
*/
|
|
24
|
+
export declare function parsePreviewValidationErrors(body: string): PreviewValidationError[];
|
|
25
|
+
export declare function sanitizeBreakingChanges(raw: unknown): BreakingChange[];
|
|
26
|
+
export declare class EdsiApiClient {
|
|
27
|
+
private host;
|
|
28
|
+
private token;
|
|
29
|
+
private spaceId;
|
|
30
|
+
private environmentId;
|
|
31
|
+
private retry;
|
|
32
|
+
private lastRequestId?;
|
|
33
|
+
getLastRequestId(): string | undefined;
|
|
34
|
+
private noteRequestId;
|
|
35
|
+
constructor(opts: EdsiClientOptions);
|
|
36
|
+
private base;
|
|
37
|
+
private headers;
|
|
38
|
+
private requestWithRetry;
|
|
39
|
+
validateToken(): Promise<void>;
|
|
40
|
+
checkPreflight(): Promise<void>;
|
|
41
|
+
previewImport(manifest: ManifestPayload, allowDeletions?: boolean): Promise<ServerPreviewResponse>;
|
|
42
|
+
applyImport(manifest: ManifestPayload, options: {
|
|
43
|
+
acknowledgeBreakingChanges: boolean;
|
|
44
|
+
allowDeletions?: boolean;
|
|
45
|
+
}): Promise<ApplyOperationResponse>;
|
|
46
|
+
pollOperation(operationId: string, opts?: PollOptions): Promise<ApplyOperationResponse>;
|
|
47
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { CmaApiClient } from './clients/cma-client.js';
|
|
2
|
+
export { EdsiApiClient, DEFAULT_HOST, PREVIEW_ERROR_PREFIX, APPLY_ERROR_PREFIX, VALIDATION_FAILED_CODE, parsePreviewValidationErrors, sanitizeBreakingChanges, } from './clients/edsi-client.js';
|
|
3
|
+
export type { PreviewValidationError } from './clients/edsi-client.js';
|
|
4
|
+
export { ApiError } from '../errors/api-error.js';
|
|
5
|
+
export type { CmaClientOptions } from '../interfaces/clients/cma-client-options.js';
|
|
6
|
+
export type { EdsiClientOptions } from '../interfaces/clients/edsi-client-options.js';
|
|
7
|
+
export type { PollOptions } from '../interfaces/clients/poll-options.js';
|
|
8
|
+
export type { ExistingComponentEntity } from '../interfaces/responses/existing-component-entity.js';
|
|
9
|
+
export type { ExistingTokenEntity } from '../interfaces/responses/existing-token-entity.js';
|
|
10
|
+
export type { ExistingEntitiesResponse } from '../interfaces/responses/existing-entities-response.js';
|
|
@@ -1,68 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
3
|
-
export
|
|
4
|
-
export
|
|
5
|
-
export declare const VALIDATION_FAILED_CODE = "\"ValidationFailed\"";
|
|
6
|
-
export interface ApiClientOptions {
|
|
7
|
-
host?: string;
|
|
8
|
-
cmaToken: string;
|
|
9
|
-
spaceId: string;
|
|
10
|
-
environmentId: string;
|
|
11
|
-
retry?: {
|
|
12
|
-
maxAttempts?: number;
|
|
13
|
-
initialDelayMs?: number;
|
|
14
|
-
maxDelayMs?: number;
|
|
15
|
-
sleep?: (delayMs: number) => Promise<void>;
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
export declare class ApiError extends Error {
|
|
19
|
-
readonly status: number;
|
|
20
|
-
readonly body: string;
|
|
21
|
-
readonly guidance?: string | undefined;
|
|
22
|
-
constructor(message: string, status: number, body: string, guidance?: string | undefined);
|
|
23
|
-
}
|
|
24
|
-
export interface PreviewValidationError {
|
|
25
|
-
componentName: string;
|
|
26
|
-
path: string;
|
|
27
|
-
message: string;
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Parse the JSON body of a 422 from `previewImport()` into structured
|
|
31
|
-
* per-component validation errors. Returns [] for any malformed input
|
|
32
|
-
* so callers can fall back to the generic error path without try/catch.
|
|
33
|
-
*
|
|
34
|
-
* Path shape: `manifest:components/<Name>/$slots/<key>` or
|
|
35
|
-
* `manifest:components/<Name>/$properties/<key>`. Only the component
|
|
36
|
-
* name is extracted today; `path` and `message` are kept verbatim so
|
|
37
|
-
* future surfaces (debug logging, headless retry in SP-4) can render
|
|
38
|
-
* the field-level detail.
|
|
39
|
-
*/
|
|
40
|
-
export declare function parsePreviewValidationErrors(body: string): PreviewValidationError[];
|
|
41
|
-
export declare function sanitizeBreakingChanges(raw: unknown): BreakingChange[];
|
|
42
|
-
export declare class ImportApiClient {
|
|
43
|
-
private host;
|
|
44
|
-
private token;
|
|
45
|
-
private spaceId;
|
|
46
|
-
private environmentId;
|
|
47
|
-
private retry;
|
|
48
|
-
private lastRequestId?;
|
|
49
|
-
getLastRequestId(): string | undefined;
|
|
50
|
-
private noteRequestId;
|
|
51
|
-
constructor(opts: ApiClientOptions);
|
|
52
|
-
private base;
|
|
53
|
-
private headers;
|
|
54
|
-
private requestWithRetry;
|
|
55
|
-
validateToken(): Promise<void>;
|
|
56
|
-
checkPreflight(): Promise<void>;
|
|
57
|
-
previewImport(manifest: ManifestPayload, allowDeletions?: boolean): Promise<ServerPreviewResponse>;
|
|
58
|
-
applyImport(manifest: ManifestPayload, options: {
|
|
59
|
-
acknowledgeBreakingChanges: boolean;
|
|
60
|
-
allowDeletions?: boolean;
|
|
61
|
-
}): Promise<ApplyOperationResponse>;
|
|
62
|
-
pollOperation(operationId: string, opts?: {
|
|
63
|
-
intervalMs?: number;
|
|
64
|
-
maxIntervalMs?: number;
|
|
65
|
-
maxAttempts?: number;
|
|
66
|
-
onProgress?: (op: ApplyOperationResponse) => void;
|
|
67
|
-
}): Promise<ApplyOperationResponse>;
|
|
68
|
-
}
|
|
1
|
+
export { EdsiApiClient, EdsiApiClient as ImportApiClient, DEFAULT_HOST, PREVIEW_ERROR_PREFIX, APPLY_ERROR_PREFIX, VALIDATION_FAILED_CODE, parsePreviewValidationErrors, sanitizeBreakingChanges, } from '../api/clients/edsi-client.js';
|
|
2
|
+
export type { PreviewValidationError } from '../api/clients/edsi-client.js';
|
|
3
|
+
export { ApiError } from '../errors/api-error.js';
|
|
4
|
+
export type { EdsiClientOptions as ApiClientOptions } from '../interfaces/clients/edsi-client-options.js';
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare const DEFAULT_API_HOST = "https://api.contentful.com";
|
|
2
|
+
export declare const DEFAULT_CONFIGURED_HOST = "api.contentful.com";
|
|
3
|
+
export declare function toConfiguredHost(host?: string): string | undefined;
|
|
4
|
+
export declare function toApiHost(host?: string): string;
|
package/dist/src/host-utils.d.ts
CHANGED
|
@@ -1,4 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
export declare const DEFAULT_CONFIGURED_HOST = "api.contentful.com";
|
|
3
|
-
export declare function toConfiguredHost(host?: string): string | undefined;
|
|
4
|
-
export declare function toApiHost(host?: string): string;
|
|
1
|
+
export { DEFAULT_API_HOST, DEFAULT_CONFIGURED_HOST, toConfiguredHost, toApiHost } from './helpers/url.js';
|
|
@@ -27,6 +27,15 @@ export interface PipelineOptions {
|
|
|
27
27
|
/** When true, auto-reject cycle participants and retry push instead of surfacing an error. */
|
|
28
28
|
autoRejectCycles?: boolean;
|
|
29
29
|
allowDeletions?: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Fetch existing Components + DesignTokens from the target space+env
|
|
32
|
+
* and persist them under outDir/.existing-entities.json so downstream
|
|
33
|
+
* agent steps can consume them as context. Requires spaceId +
|
|
34
|
+
* environmentId + cmaToken; skipped with a warning otherwise. No-op
|
|
35
|
+
* for the agent flow in this PR — the file is written but nothing
|
|
36
|
+
* reads it yet.
|
|
37
|
+
*/
|
|
38
|
+
withSpaceContext?: boolean;
|
|
30
39
|
compositionMode?: CompositionMode;
|
|
31
40
|
compositionMap?: string;
|
|
32
41
|
compositionAgent?: boolean;
|
package/dist/src/index.js
CHANGED
|
@@ -284,8 +284,7 @@ function resolveAgentModel(agent, explicit) {
|
|
|
284
284
|
return DEFAULT_MODELS[agent];
|
|
285
285
|
}
|
|
286
286
|
function buildArgs(agent, prompt2, model, promptViaStdin = false) {
|
|
287
|
-
const
|
|
288
|
-
const modelArg = resolvedModel ? ["--model", resolvedModel] : [];
|
|
287
|
+
const modelArg = ["--model", resolveAgentModel(agent, model)];
|
|
289
288
|
const promptArg = promptViaStdin ? [] : [prompt2];
|
|
290
289
|
switch (agent) {
|
|
291
290
|
case "claude":
|
|
@@ -298,7 +297,7 @@ function buildArgs(agent, prompt2, model, promptViaStdin = false) {
|
|
|
298
297
|
return ["--print", ...modelArg, ...promptArg];
|
|
299
298
|
case "copilot": {
|
|
300
299
|
const copilotModel = resolveAgentModel("copilot", model);
|
|
301
|
-
const copilotModelArg =
|
|
300
|
+
const copilotModelArg = copilotModel === "Auto" ? [] : ["--model", copilotModel];
|
|
302
301
|
return ["-p", ...promptArg, ...copilotModelArg, "--allow-all-tools"];
|
|
303
302
|
}
|
|
304
303
|
}
|
|
@@ -456,6 +455,8 @@ var init_agent_runner = __esm({
|
|
|
456
455
|
};
|
|
457
456
|
DEFAULT_MODELS = {
|
|
458
457
|
claude: "haiku",
|
|
458
|
+
codex: "gpt-5.4-mini",
|
|
459
|
+
// requires OPENAI_API_KEY; ChatGPT account users must pass --model
|
|
459
460
|
opencode: "claude-haiku-4-5",
|
|
460
461
|
cursor: "gpt-mini",
|
|
461
462
|
// cursor alias for gpt-5.4-mini-medium; haiku not in cursor's catalog
|
|
@@ -12575,7 +12576,7 @@ var init_src3 = __esm({
|
|
|
12575
12576
|
}
|
|
12576
12577
|
});
|
|
12577
12578
|
|
|
12578
|
-
// packages/experience-design-system-cli/src/
|
|
12579
|
+
// packages/experience-design-system-cli/src/helpers/url.ts
|
|
12579
12580
|
function trimTrailingSlashes(value) {
|
|
12580
12581
|
return value.replace(/\/+$/, "");
|
|
12581
12582
|
}
|
|
@@ -12598,8 +12599,8 @@ function toApiHost(host) {
|
|
|
12598
12599
|
return `https://${normalized}`;
|
|
12599
12600
|
}
|
|
12600
12601
|
var DEFAULT_API_HOST, DEFAULT_CONFIGURED_HOST;
|
|
12601
|
-
var
|
|
12602
|
-
"packages/experience-design-system-cli/src/
|
|
12602
|
+
var init_url = __esm({
|
|
12603
|
+
"packages/experience-design-system-cli/src/helpers/url.ts"() {
|
|
12603
12604
|
"use strict";
|
|
12604
12605
|
DEFAULT_API_HOST = "https://api.contentful.com";
|
|
12605
12606
|
DEFAULT_CONFIGURED_HOST = "api.contentful.com";
|
|
@@ -12806,7 +12807,55 @@ var init_user_agent = __esm({
|
|
|
12806
12807
|
}
|
|
12807
12808
|
});
|
|
12808
12809
|
|
|
12809
|
-
// packages/experience-design-system-cli/src/
|
|
12810
|
+
// packages/experience-design-system-cli/src/helpers/http.ts
|
|
12811
|
+
function buildHeaders(token) {
|
|
12812
|
+
return {
|
|
12813
|
+
Authorization: `Bearer ${token}`,
|
|
12814
|
+
"Content-Type": "application/json",
|
|
12815
|
+
"X-Contentful-User-Agent": buildUserAgent()
|
|
12816
|
+
};
|
|
12817
|
+
}
|
|
12818
|
+
async function request(url, options) {
|
|
12819
|
+
const init = {
|
|
12820
|
+
method: options.method ?? "GET",
|
|
12821
|
+
headers: buildHeaders(options.token)
|
|
12822
|
+
};
|
|
12823
|
+
if (options.body) init.body = options.body;
|
|
12824
|
+
return fetch(url, init);
|
|
12825
|
+
}
|
|
12826
|
+
var init_http = __esm({
|
|
12827
|
+
"packages/experience-design-system-cli/src/helpers/http.ts"() {
|
|
12828
|
+
"use strict";
|
|
12829
|
+
init_user_agent();
|
|
12830
|
+
}
|
|
12831
|
+
});
|
|
12832
|
+
|
|
12833
|
+
// packages/experience-design-system-cli/src/errors/api-error.ts
|
|
12834
|
+
var ERROR_BODY_LOG_CAP, ApiError;
|
|
12835
|
+
var init_api_error = __esm({
|
|
12836
|
+
"packages/experience-design-system-cli/src/errors/api-error.ts"() {
|
|
12837
|
+
"use strict";
|
|
12838
|
+
ERROR_BODY_LOG_CAP = 16384;
|
|
12839
|
+
ApiError = class extends Error {
|
|
12840
|
+
constructor(message, status, body, guidance) {
|
|
12841
|
+
super(message);
|
|
12842
|
+
this.status = status;
|
|
12843
|
+
this.body = body;
|
|
12844
|
+
this.guidance = guidance;
|
|
12845
|
+
if (body) {
|
|
12846
|
+
const trimmed = body.length > ERROR_BODY_LOG_CAP ? body.slice(0, ERROR_BODY_LOG_CAP) + "\u2026" : body;
|
|
12847
|
+
this.message = `${message}
|
|
12848
|
+
${trimmed}`;
|
|
12849
|
+
}
|
|
12850
|
+
}
|
|
12851
|
+
status;
|
|
12852
|
+
body;
|
|
12853
|
+
guidance;
|
|
12854
|
+
};
|
|
12855
|
+
}
|
|
12856
|
+
});
|
|
12857
|
+
|
|
12858
|
+
// packages/experience-design-system-cli/src/api/clients/edsi-client.ts
|
|
12810
12859
|
function defaultSleep(delayMs) {
|
|
12811
12860
|
return new Promise((resolve27) => setTimeout(resolve27, delayMs));
|
|
12812
12861
|
}
|
|
@@ -12889,48 +12938,20 @@ function isApsDenialBody(body) {
|
|
|
12889
12938
|
return false;
|
|
12890
12939
|
}
|
|
12891
12940
|
}
|
|
12892
|
-
|
|
12893
|
-
|
|
12894
|
-
|
|
12895
|
-
"Content-Type": "application/json",
|
|
12896
|
-
"X-Contentful-User-Agent": buildUserAgent()
|
|
12897
|
-
};
|
|
12898
|
-
const init = {
|
|
12899
|
-
method: options.method ?? "GET",
|
|
12900
|
-
headers
|
|
12901
|
-
};
|
|
12902
|
-
if (options.body) init.body = options.body;
|
|
12903
|
-
return fetch(url, init);
|
|
12904
|
-
}
|
|
12905
|
-
var PREVIEW_ERROR_PREFIX, APPLY_ERROR_PREFIX, VALIDATION_FAILED_CODE, MAX_RETRY_AFTER_MS, ERROR_BODY_LOG_CAP, ApiError, COMPONENT_PATH_PREFIX, PROPERTY_BREAKING_REASONS, SLOT_BREAKING_REASONS, ImportApiClient;
|
|
12906
|
-
var init_api_client = __esm({
|
|
12907
|
-
"packages/experience-design-system-cli/src/apply/api-client.ts"() {
|
|
12941
|
+
var PREVIEW_ERROR_PREFIX, APPLY_ERROR_PREFIX, VALIDATION_FAILED_CODE, MAX_RETRY_AFTER_MS, COMPONENT_PATH_PREFIX, PROPERTY_BREAKING_REASONS, SLOT_BREAKING_REASONS, EdsiApiClient;
|
|
12942
|
+
var init_edsi_client = __esm({
|
|
12943
|
+
"packages/experience-design-system-cli/src/api/clients/edsi-client.ts"() {
|
|
12908
12944
|
"use strict";
|
|
12909
12945
|
init_src3();
|
|
12910
|
-
|
|
12946
|
+
init_url();
|
|
12911
12947
|
init_debug_logger();
|
|
12912
12948
|
init_user_agent();
|
|
12949
|
+
init_http();
|
|
12950
|
+
init_api_error();
|
|
12913
12951
|
PREVIEW_ERROR_PREFIX = "preview failed:";
|
|
12914
12952
|
APPLY_ERROR_PREFIX = "apply failed:";
|
|
12915
12953
|
VALIDATION_FAILED_CODE = '"ValidationFailed"';
|
|
12916
12954
|
MAX_RETRY_AFTER_MS = 6e4;
|
|
12917
|
-
ERROR_BODY_LOG_CAP = 16384;
|
|
12918
|
-
ApiError = class extends Error {
|
|
12919
|
-
constructor(message, status, body, guidance) {
|
|
12920
|
-
super(message);
|
|
12921
|
-
this.status = status;
|
|
12922
|
-
this.body = body;
|
|
12923
|
-
this.guidance = guidance;
|
|
12924
|
-
if (body) {
|
|
12925
|
-
const trimmed = body.length > ERROR_BODY_LOG_CAP ? body.slice(0, ERROR_BODY_LOG_CAP) + "\u2026" : body;
|
|
12926
|
-
this.message = `${message}
|
|
12927
|
-
${trimmed}`;
|
|
12928
|
-
}
|
|
12929
|
-
}
|
|
12930
|
-
status;
|
|
12931
|
-
body;
|
|
12932
|
-
guidance;
|
|
12933
|
-
};
|
|
12934
12955
|
COMPONENT_PATH_PREFIX = "manifest:components/";
|
|
12935
12956
|
PROPERTY_BREAKING_REASONS = /* @__PURE__ */ new Set([
|
|
12936
12957
|
"removed",
|
|
@@ -12939,7 +12960,7 @@ ${trimmed}`;
|
|
|
12939
12960
|
"validation_narrowed"
|
|
12940
12961
|
]);
|
|
12941
12962
|
SLOT_BREAKING_REASONS = /* @__PURE__ */ new Set(["slot_removed", "slot_allowed_components_narrowed"]);
|
|
12942
|
-
|
|
12963
|
+
EdsiApiClient = class {
|
|
12943
12964
|
host;
|
|
12944
12965
|
token;
|
|
12945
12966
|
spaceId;
|
|
@@ -13205,6 +13226,15 @@ ${trimmed}`;
|
|
|
13205
13226
|
}
|
|
13206
13227
|
});
|
|
13207
13228
|
|
|
13229
|
+
// packages/experience-design-system-cli/src/apply/api-client.ts
|
|
13230
|
+
var init_api_client = __esm({
|
|
13231
|
+
"packages/experience-design-system-cli/src/apply/api-client.ts"() {
|
|
13232
|
+
"use strict";
|
|
13233
|
+
init_edsi_client();
|
|
13234
|
+
init_api_error();
|
|
13235
|
+
}
|
|
13236
|
+
});
|
|
13237
|
+
|
|
13208
13238
|
// packages/experience-design-system-cli/src/lib/error-parser.ts
|
|
13209
13239
|
function stripLambdaLogPrefix(body) {
|
|
13210
13240
|
let out = body.replace(LAMBDA_LOG_PREFIX_RE, "");
|
|
@@ -14193,6 +14223,14 @@ var init_strip_allowed_components = __esm({
|
|
|
14193
14223
|
}
|
|
14194
14224
|
});
|
|
14195
14225
|
|
|
14226
|
+
// packages/experience-design-system-cli/src/host-utils.ts
|
|
14227
|
+
var init_host_utils = __esm({
|
|
14228
|
+
"packages/experience-design-system-cli/src/host-utils.ts"() {
|
|
14229
|
+
"use strict";
|
|
14230
|
+
init_url();
|
|
14231
|
+
}
|
|
14232
|
+
});
|
|
14233
|
+
|
|
14196
14234
|
// packages/experience-design-system-cli/src/credentials-store.ts
|
|
14197
14235
|
var credentials_store_exports = {};
|
|
14198
14236
|
__export(credentials_store_exports, {
|
|
@@ -14808,7 +14846,7 @@ async function resolveSharedInputs(opts) {
|
|
|
14808
14846
|
if (opts.tokens) {
|
|
14809
14847
|
tokens = await readTokensFromPath("--tokens", opts.tokens);
|
|
14810
14848
|
}
|
|
14811
|
-
const client2 = new
|
|
14849
|
+
const client2 = new EdsiApiClient({
|
|
14812
14850
|
host: opts.host,
|
|
14813
14851
|
cmaToken,
|
|
14814
14852
|
spaceId,
|
|
@@ -15548,7 +15586,7 @@ function App({ sessionId: sessionId2, artifactsRoot, reviewRoot }) {
|
|
|
15548
15586
|
tokens
|
|
15549
15587
|
);
|
|
15550
15588
|
if (!manifest.componentsManifest) manifest.componentsManifest = {};
|
|
15551
|
-
const client2 = new
|
|
15589
|
+
const client2 = new EdsiApiClient({ cmaToken, spaceId, environmentId });
|
|
15552
15590
|
const preview = await client2.previewImport(manifest, true);
|
|
15553
15591
|
const annotations = {};
|
|
15554
15592
|
for (const item of preview.components.new) {
|
|
@@ -16570,7 +16608,7 @@ var init_save_path_resolver = __esm({
|
|
|
16570
16608
|
});
|
|
16571
16609
|
|
|
16572
16610
|
// packages/experience-design-system-cli/src/runs/store.ts
|
|
16573
|
-
import { readFile as readFile22, writeFile as
|
|
16611
|
+
import { readFile as readFile22, writeFile as writeFile6, mkdir as mkdir6, rename } from "node:fs/promises";
|
|
16574
16612
|
import { join as join20 } from "node:path";
|
|
16575
16613
|
import { homedir as homedir7 } from "node:os";
|
|
16576
16614
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
@@ -16633,7 +16671,7 @@ async function writeAtomic(file) {
|
|
|
16633
16671
|
await mkdir6(RUNS_DIR, { recursive: true });
|
|
16634
16672
|
const body = JSON.stringify(file, null, 2) + "\n";
|
|
16635
16673
|
const tmp = `${RUNS_PATH}.${process.pid}.${Date.now()}.tmp`;
|
|
16636
|
-
await
|
|
16674
|
+
await writeFile6(tmp, body, { mode: 384 });
|
|
16637
16675
|
await rename(tmp, RUNS_PATH);
|
|
16638
16676
|
}
|
|
16639
16677
|
async function appendRun(input) {
|
|
@@ -24115,7 +24153,7 @@ async function runLivePreview(opts) {
|
|
|
24115
24153
|
tokens = await readTokensFromPath("tokens", tokensPath);
|
|
24116
24154
|
}
|
|
24117
24155
|
const manifest = buildManifest3(components, tokens, { deleteAllComponents: opts.deleteAllComponents === true });
|
|
24118
|
-
const client2 = new
|
|
24156
|
+
const client2 = new EdsiApiClient({ host, cmaToken, spaceId, environmentId });
|
|
24119
24157
|
const startedAt = Date.now();
|
|
24120
24158
|
let timeoutHandle;
|
|
24121
24159
|
const timeoutPromise = new Promise((_resolve, reject) => {
|
|
@@ -28326,7 +28364,7 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
|
|
|
28326
28364
|
update({ step: "credentials", credentialsValidating: true, credentialsError: "" });
|
|
28327
28365
|
try {
|
|
28328
28366
|
const resolvedHost = resolveWizardHost(host2);
|
|
28329
|
-
const client2 = new
|
|
28367
|
+
const client2 = new EdsiApiClient({
|
|
28330
28368
|
cmaToken,
|
|
28331
28369
|
spaceId,
|
|
28332
28370
|
environmentId,
|
|
@@ -28400,7 +28438,7 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
|
|
|
28400
28438
|
update({ step: "previewing" });
|
|
28401
28439
|
const resolvedHost = resolveWizardHost(host2);
|
|
28402
28440
|
try {
|
|
28403
|
-
const client2 = new
|
|
28441
|
+
const client2 = new EdsiApiClient({
|
|
28404
28442
|
cmaToken,
|
|
28405
28443
|
spaceId,
|
|
28406
28444
|
environmentId,
|
|
@@ -28562,7 +28600,7 @@ If using a custom --host, make sure the space exists on that host.`
|
|
|
28562
28600
|
update({ step: "pushing", pushProgress: null });
|
|
28563
28601
|
try {
|
|
28564
28602
|
const resolvedHost = resolveWizardHost(host2);
|
|
28565
|
-
const client2 = new
|
|
28603
|
+
const client2 = new EdsiApiClient({
|
|
28566
28604
|
cmaToken,
|
|
28567
28605
|
spaceId,
|
|
28568
28606
|
environmentId,
|
|
@@ -34307,14 +34345,72 @@ init_db();
|
|
|
34307
34345
|
init_command();
|
|
34308
34346
|
init_manifest();
|
|
34309
34347
|
init_api_client();
|
|
34348
|
+
import { mkdir as mkdir5, writeFile as writeFile5 } from "node:fs/promises";
|
|
34349
|
+
import { join as join18, resolve as resolve21 } from "node:path";
|
|
34350
|
+
import { execFile as execFile2 } from "node:child_process";
|
|
34351
|
+
|
|
34352
|
+
// packages/experience-design-system-cli/src/api/clients/cma-client.ts
|
|
34353
|
+
init_url();
|
|
34354
|
+
init_http();
|
|
34355
|
+
init_api_error();
|
|
34356
|
+
var CMA_PAGE_LIMIT = 100;
|
|
34357
|
+
var CmaApiClient = class {
|
|
34358
|
+
host;
|
|
34359
|
+
token;
|
|
34360
|
+
spaceId;
|
|
34361
|
+
environmentId;
|
|
34362
|
+
constructor(opts) {
|
|
34363
|
+
this.host = toApiHost(opts.host);
|
|
34364
|
+
this.token = opts.cmaToken;
|
|
34365
|
+
this.spaceId = opts.spaceId;
|
|
34366
|
+
this.environmentId = opts.environmentId;
|
|
34367
|
+
}
|
|
34368
|
+
base() {
|
|
34369
|
+
return `${this.host}/spaces/${this.spaceId}/environments/${this.environmentId}`;
|
|
34370
|
+
}
|
|
34371
|
+
async validateToken() {
|
|
34372
|
+
const url = `${this.host}/users/me`;
|
|
34373
|
+
const res = await request(url, { token: this.token });
|
|
34374
|
+
if (res.status === 401) {
|
|
34375
|
+
throw new ApiError("CMA token is invalid or revoked", res.status, await res.text());
|
|
34376
|
+
}
|
|
34377
|
+
if (!res.ok) {
|
|
34378
|
+
throw new ApiError(`unexpected error validating token: ${res.status}`, res.status, await res.text());
|
|
34379
|
+
}
|
|
34380
|
+
}
|
|
34381
|
+
async listExistingEntities() {
|
|
34382
|
+
const [components, tokens] = await Promise.all([
|
|
34383
|
+
this.listAll("component_types", "component_types"),
|
|
34384
|
+
this.listAll("design_tokens", "design_tokens")
|
|
34385
|
+
]);
|
|
34386
|
+
return { components, tokens };
|
|
34387
|
+
}
|
|
34388
|
+
async listAll(resourcePath, opName) {
|
|
34389
|
+
const items = [];
|
|
34390
|
+
let skip = 0;
|
|
34391
|
+
while (true) {
|
|
34392
|
+
const url = `${this.base()}/${resourcePath}?limit=${CMA_PAGE_LIMIT}&skip=${skip}`;
|
|
34393
|
+
const res = await request(url, { token: this.token });
|
|
34394
|
+
if (!res.ok) {
|
|
34395
|
+
throw new ApiError(`${opName} list failed: ${res.status}`, res.status, await res.text());
|
|
34396
|
+
}
|
|
34397
|
+
const page = await res.json();
|
|
34398
|
+
items.push(...page.items);
|
|
34399
|
+
const returned = page.items.length;
|
|
34400
|
+
const total = page.total ?? items.length;
|
|
34401
|
+
if (returned === 0 || items.length >= total) break;
|
|
34402
|
+
skip += returned;
|
|
34403
|
+
}
|
|
34404
|
+
return items;
|
|
34405
|
+
}
|
|
34406
|
+
};
|
|
34407
|
+
|
|
34408
|
+
// packages/experience-design-system-cli/src/import/orchestrator.ts
|
|
34310
34409
|
init_contentful_urls();
|
|
34311
34410
|
init_debug_logger();
|
|
34312
34411
|
init_analytics();
|
|
34313
34412
|
init_env();
|
|
34314
34413
|
init_cli_path();
|
|
34315
|
-
import { mkdir as mkdir5 } from "node:fs/promises";
|
|
34316
|
-
import { join as join18, resolve as resolve21 } from "node:path";
|
|
34317
|
-
import { execFile as execFile2 } from "node:child_process";
|
|
34318
34414
|
async function runStep(args, cliPath, analyticsSessionId, env = {}, streamStderr = false) {
|
|
34319
34415
|
const debug = getDebugLogger();
|
|
34320
34416
|
const startedAt = Date.now();
|
|
@@ -34422,11 +34518,66 @@ async function runPipeline(opts, progressWriter, cliPathOverride) {
|
|
|
34422
34518
|
await mkdir5(outDir, { recursive: true });
|
|
34423
34519
|
const steps = [];
|
|
34424
34520
|
let stepNum = 0;
|
|
34425
|
-
const
|
|
34521
|
+
const wantsSpaceContext = opts.withSpaceContext === true;
|
|
34522
|
+
const canFetchSpaceContext = wantsSpaceContext && !!opts.spaceId && !!opts.environmentId && !!opts.cmaToken;
|
|
34523
|
+
const totalSteps = 5 + (opts.print ? 1 : 0) + (canFetchSpaceContext ? 1 : 0);
|
|
34426
34524
|
function stepLabel(name) {
|
|
34427
34525
|
stepNum++;
|
|
34428
34526
|
return ` Step ${stepNum}/${totalSteps} ${name} `;
|
|
34429
34527
|
}
|
|
34528
|
+
if (wantsSpaceContext && !canFetchSpaceContext) {
|
|
34529
|
+
progressWriter(
|
|
34530
|
+
" Note: --with-space-context requires --space-id, --environment-id, and --cma-token; skipping context fetch."
|
|
34531
|
+
);
|
|
34532
|
+
}
|
|
34533
|
+
if (canFetchSpaceContext) {
|
|
34534
|
+
const fetchLabel = stepLabel("Fetching existing components + design tokens");
|
|
34535
|
+
const fetchStepId = createStep(db, sessionId2, "fetch existing entities", {
|
|
34536
|
+
spaceId: opts.spaceId,
|
|
34537
|
+
environmentId: opts.environmentId
|
|
34538
|
+
});
|
|
34539
|
+
const t0 = Date.now();
|
|
34540
|
+
try {
|
|
34541
|
+
const cma = new CmaApiClient({
|
|
34542
|
+
host: opts.host,
|
|
34543
|
+
cmaToken: opts.cmaToken,
|
|
34544
|
+
spaceId: opts.spaceId,
|
|
34545
|
+
environmentId: opts.environmentId
|
|
34546
|
+
});
|
|
34547
|
+
const result = await cma.listExistingEntities();
|
|
34548
|
+
const fetchDurationMs = Date.now() - t0;
|
|
34549
|
+
const existingEntitiesPath = join18(outDir, ".existing-entities.json");
|
|
34550
|
+
await writeFile5(existingEntitiesPath, JSON.stringify(result, null, 2), "utf8");
|
|
34551
|
+
updateStep(db, fetchStepId, "complete", {
|
|
34552
|
+
components: String(result.components.length),
|
|
34553
|
+
tokens: String(result.tokens.length),
|
|
34554
|
+
path: existingEntitiesPath
|
|
34555
|
+
});
|
|
34556
|
+
progressWriter(
|
|
34557
|
+
`${fetchLabel}\u2713 ${result.components.length} component${result.components.length === 1 ? "" : "s"}, ${result.tokens.length} token${result.tokens.length === 1 ? "" : "s"} (${(fetchDurationMs / 1e3).toFixed(1)}s)`
|
|
34558
|
+
);
|
|
34559
|
+
steps.push({
|
|
34560
|
+
step: "fetch existing entities",
|
|
34561
|
+
status: "complete",
|
|
34562
|
+
durationMs: fetchDurationMs,
|
|
34563
|
+
detail: { components: result.components.length, tokens: result.tokens.length }
|
|
34564
|
+
});
|
|
34565
|
+
} catch (error) {
|
|
34566
|
+
const fetchDurationMs = Date.now() - t0;
|
|
34567
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
34568
|
+
updateStep(db, fetchStepId, "failed", {}, message);
|
|
34569
|
+
progressWriter(
|
|
34570
|
+
`${fetchLabel}\u26A0 fetch failed, continuing without space context (${(fetchDurationMs / 1e3).toFixed(1)}s)`
|
|
34571
|
+
);
|
|
34572
|
+
progressWriter(` ${message.split("\n")[0]}`);
|
|
34573
|
+
steps.push({
|
|
34574
|
+
step: "fetch existing entities",
|
|
34575
|
+
status: "failed",
|
|
34576
|
+
durationMs: fetchDurationMs,
|
|
34577
|
+
error: message
|
|
34578
|
+
});
|
|
34579
|
+
}
|
|
34580
|
+
}
|
|
34430
34581
|
const analyzeLabel = stepLabel("Statically analyzing project");
|
|
34431
34582
|
const analyzeSkipped = !opts.noCache && opts.skipAnalyze;
|
|
34432
34583
|
let extractSessionId = null;
|
|
@@ -35378,7 +35529,10 @@ function registerImportCommand(program) {
|
|
|
35378
35529
|
"Override a stage prompt (repeatable). value is a file path or literal text, e.g. --prompt composition=./p.md",
|
|
35379
35530
|
(v, acc) => [...acc, v],
|
|
35380
35531
|
[]
|
|
35381
|
-
).option("--auto-reject-cycles", "Automatically reject components involved in slot cycles and retry").option(
|
|
35532
|
+
).option("--auto-reject-cycles", "Automatically reject components involved in slot cycles and retry").option(
|
|
35533
|
+
"--with-space-context",
|
|
35534
|
+
"Fetch existing Components + DesignTokens from the target space+env and persist them under <out>/.existing-entities.json for future agent-context enrichment. Requires --space-id, --environment-id, and --cma-token."
|
|
35535
|
+
).option("--auto-filter", "Force the AI auto-filter ON (overrides the credentials.json autoFilter preference)").option(
|
|
35382
35536
|
"--no-auto-filter",
|
|
35383
35537
|
"Skip the automatic AI pre-filter; jump straight to manual scope-gate (overrides the credentials.json autoFilter preference; no-op when paired with --auto-accept-scope)"
|
|
35384
35538
|
).option(
|
|
@@ -35713,6 +35867,7 @@ function registerImportCommand(program) {
|
|
|
35713
35867
|
dryRun: dryRunForward,
|
|
35714
35868
|
selectPromptPath: opts.selectPromptPath,
|
|
35715
35869
|
autoRejectCycles: opts.autoRejectCycles ?? false,
|
|
35870
|
+
withSpaceContext: opts.withSpaceContext ?? false,
|
|
35716
35871
|
allowDeletions: opts.allowDeletions ?? false,
|
|
35717
35872
|
compositionMode: headlessCompositionMode,
|
|
35718
35873
|
...opts.compositionMap ? { compositionMap: opts.compositionMap } : {},
|
|
@@ -36096,15 +36251,26 @@ function pick(items, defaultIdx = 0) {
|
|
|
36096
36251
|
process.stdout.write(` \x1B[2m[s] Skip\x1B[0m
|
|
36097
36252
|
`);
|
|
36098
36253
|
}
|
|
36099
|
-
async function promptCodexModel(
|
|
36254
|
+
async function promptCodexModel() {
|
|
36100
36255
|
if (process.env["OPENAI_API_KEY"]) return void 0;
|
|
36101
36256
|
info("");
|
|
36102
36257
|
process.stdout.write(` \x1B[33m\u26A0\x1B[0m No OPENAI_API_KEY \u2014 using ChatGPT account authentication.
|
|
36103
36258
|
`);
|
|
36104
|
-
info(" Tip: run \x1B[1mcodex\x1B[0m then type \x1B[1m/model\x1B[0m to browse
|
|
36105
|
-
|
|
36106
|
-
|
|
36107
|
-
|
|
36259
|
+
info(" Tip: run \x1B[1mcodex\x1B[0m then type \x1B[1m/model\x1B[0m to browse all available models.");
|
|
36260
|
+
info("");
|
|
36261
|
+
info(" Choose a model:");
|
|
36262
|
+
info("");
|
|
36263
|
+
pick([
|
|
36264
|
+
{ label: "gpt-5.4-mini", description: "fast, lower cost" },
|
|
36265
|
+
{ label: "gpt-5.5", description: "most capable" },
|
|
36266
|
+
{ label: "gpt-5.4" }
|
|
36267
|
+
]);
|
|
36268
|
+
info("");
|
|
36269
|
+
const choice = await prompt(" \x1B[2m\u203A\x1B[0m Your choice [1]: ");
|
|
36270
|
+
if (choice === "1" || choice === "") return "gpt-5.4-mini";
|
|
36271
|
+
if (choice === "2") return "gpt-5.5";
|
|
36272
|
+
if (choice === "3") return "gpt-5.4";
|
|
36273
|
+
return void 0;
|
|
36108
36274
|
}
|
|
36109
36275
|
async function setupAgent() {
|
|
36110
36276
|
section("Step 4: Coding agent (claude, codex, opencode, or copilot)", "[required]");
|
|
@@ -36131,6 +36297,7 @@ async function setupAgent() {
|
|
|
36131
36297
|
const parsed = choice2 === "" ? 1 : parseInt(choice2, 10);
|
|
36132
36298
|
const idx = Number.isNaN(parsed) || parsed < 1 || parsed > found.length ? 0 : parsed - 1;
|
|
36133
36299
|
const selected = found[idx];
|
|
36300
|
+
ok(`${selected.name} \x1B[2m(${selected.binary})\x1B[0m selected`);
|
|
36134
36301
|
const agentModel = selected.binary === "codex" ? await promptCodexModel() : void 0;
|
|
36135
36302
|
return { agent: selected.binary, agentModel };
|
|
36136
36303
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface EdsiClientOptions {
|
|
2
|
+
host?: string;
|
|
3
|
+
cmaToken: string;
|
|
4
|
+
spaceId: string;
|
|
5
|
+
environmentId: string;
|
|
6
|
+
retry?: {
|
|
7
|
+
maxAttempts?: number;
|
|
8
|
+
initialDelayMs?: number;
|
|
9
|
+
maxDelayMs?: number;
|
|
10
|
+
sleep?: (delayMs: number) => Promise<void>;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ExistingComponentEntity } from './existing-component-entity.js';
|
|
2
|
+
import type { ExistingTokenEntity } from './existing-token-entity.js';
|
|
3
|
+
export interface ExistingEntitiesResponse {
|
|
4
|
+
components: ExistingComponentEntity[];
|
|
5
|
+
tokens: ExistingTokenEntity[];
|
|
6
|
+
}
|
package/dist/src/session/db.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import type { ToolCall, TokenToolCall, ComponentSourceRef } from '@contentful/ex
|
|
|
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';
|
|
8
|
-
export type CommandName = 'analyze extract' | 'analyze select' | 'generate components' | 'generate tokens' | 'generate edit' | 'apply preview' | 'apply select' | 'apply push' | 'print components' | 'print tokens' | 'map tokens' | 'import';
|
|
8
|
+
export type CommandName = 'analyze extract' | 'analyze select' | 'generate components' | 'generate tokens' | 'generate edit' | 'apply preview' | 'apply select' | 'apply push' | 'print components' | 'print tokens' | 'map tokens' | 'fetch existing entities' | 'import';
|
|
9
9
|
export interface SessionRow {
|
|
10
10
|
id: string;
|
|
11
11
|
name: string | null;
|
|
@@ -1,10 +1,4 @@
|
|
|
1
1
|
import type { Command } from 'commander';
|
|
2
|
-
import type { AgentName } from '@contentful/experience-design-system-generation';
|
|
3
|
-
export declare function promptCodexModel(ask?: (q: string) => Promise<string>): Promise<string | undefined>;
|
|
4
|
-
export declare function setupAgent(): Promise<{
|
|
5
|
-
agent: AgentName | undefined;
|
|
6
|
-
agentModel: string | undefined;
|
|
7
|
-
}>;
|
|
8
2
|
export type SkillPromptKind = 'select' | 'generate';
|
|
9
3
|
/**
|
|
10
4
|
* Prompt the operator for a custom skill prompt path. Returns the resolved
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentful/experience-design-system-cli",
|
|
3
|
-
"version": "2.32.1-dev-build-
|
|
3
|
+
"version": "2.32.1-dev-build-81eb804.0",
|
|
4
4
|
"description": "Contentful Experiences design system import CLI",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -39,8 +39,8 @@
|
|
|
39
39
|
"svelte": "^5.56.4",
|
|
40
40
|
"ts-morph": "^27.0.2",
|
|
41
41
|
"typescript": "^5.9.3",
|
|
42
|
-
"@contentful/experience-design-system-
|
|
43
|
-
"@contentful/experience-design-system-
|
|
42
|
+
"@contentful/experience-design-system-cli-v2": "2.32.1-dev-build-81eb804.0",
|
|
43
|
+
"@contentful/experience-design-system-types": "2.32.1-dev-build-81eb804.0"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@tsconfig/node24": "^24.0.4",
|
|
@@ -52,9 +52,9 @@
|
|
|
52
52
|
"ink-testing-library": "^4.0.0",
|
|
53
53
|
"typescript-eslint": "^8.67.0",
|
|
54
54
|
"vitest": "^4.0.16",
|
|
55
|
-
"@contentful/experience-design-system-
|
|
56
|
-
"@contentful/experience-design-system-
|
|
57
|
-
"@contentful/experience-design-system-
|
|
55
|
+
"@contentful/experience-design-system-client": "2.32.1-dev-build-81eb804.0",
|
|
56
|
+
"@contentful/experience-design-system-generation": "2.32.1-dev-build-81eb804.0",
|
|
57
|
+
"@contentful/experience-design-system-extraction": "2.32.1-dev-build-81eb804.0"
|
|
58
58
|
},
|
|
59
59
|
"repository": {
|
|
60
60
|
"type": "git",
|