@contentful/experience-design-system-cli 2.32.1-dev-build-81eb804.0 → 2.32.1-dev-build-10912f6.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/apply/api-client.d.ts +68 -4
- package/dist/src/host-utils.d.ts +4 -1
- package/dist/src/import/orchestrator.d.ts +0 -9
- package/dist/src/index.js +60 -227
- package/dist/src/session/db.d.ts +1 -1
- package/dist/src/setup/command.d.ts +6 -0
- package/package.json +6 -6
- package/dist/src/api/clients/cma-client.d.ts +0 -13
- package/dist/src/api/clients/edsi-client.d.ts +0 -47
- package/dist/src/api/index.d.ts +0 -10
- package/dist/src/errors/api-error.d.ts +0 -6
- package/dist/src/helpers/http.d.ts +0 -4
- package/dist/src/helpers/url.d.ts +0 -4
- package/dist/src/interfaces/clients/cma-client-options.d.ts +0 -6
- package/dist/src/interfaces/clients/edsi-client-options.d.ts +0 -12
- package/dist/src/interfaces/clients/poll-options.d.ts +0 -7
- package/dist/src/interfaces/responses/existing-component-entity.d.ts +0 -8
- package/dist/src/interfaces/responses/existing-entities-response.d.ts +0 -6
- package/dist/src/interfaces/responses/existing-token-entity.d.ts +0 -6
package/dist/package.json
CHANGED
|
@@ -1,4 +1,68 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
3
|
-
export
|
|
4
|
-
export
|
|
1
|
+
import type { ManifestPayload, ServerPreviewResponse, ApplyOperationResponse, BreakingChange } from '@contentful/experience-design-system-types';
|
|
2
|
+
export declare const DEFAULT_HOST = "https://api.contentful.com";
|
|
3
|
+
export declare const PREVIEW_ERROR_PREFIX = "preview failed:";
|
|
4
|
+
export declare const APPLY_ERROR_PREFIX = "apply failed:";
|
|
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
|
+
}
|
package/dist/src/host-utils.d.ts
CHANGED
|
@@ -1 +1,4 @@
|
|
|
1
|
-
export
|
|
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;
|
|
@@ -27,15 +27,6 @@ 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;
|
|
39
30
|
compositionMode?: CompositionMode;
|
|
40
31
|
compositionMap?: string;
|
|
41
32
|
compositionAgent?: boolean;
|
package/dist/src/index.js
CHANGED
|
@@ -284,7 +284,8 @@ function resolveAgentModel(agent, explicit) {
|
|
|
284
284
|
return DEFAULT_MODELS[agent];
|
|
285
285
|
}
|
|
286
286
|
function buildArgs(agent, prompt2, model, promptViaStdin = false) {
|
|
287
|
-
const
|
|
287
|
+
const resolvedModel = resolveAgentModel(agent, model);
|
|
288
|
+
const modelArg = resolvedModel ? ["--model", resolvedModel] : [];
|
|
288
289
|
const promptArg = promptViaStdin ? [] : [prompt2];
|
|
289
290
|
switch (agent) {
|
|
290
291
|
case "claude":
|
|
@@ -297,7 +298,7 @@ function buildArgs(agent, prompt2, model, promptViaStdin = false) {
|
|
|
297
298
|
return ["--print", ...modelArg, ...promptArg];
|
|
298
299
|
case "copilot": {
|
|
299
300
|
const copilotModel = resolveAgentModel("copilot", model);
|
|
300
|
-
const copilotModelArg = copilotModel === "Auto" ? [] : ["--model", copilotModel];
|
|
301
|
+
const copilotModelArg = !copilotModel || copilotModel === "Auto" ? [] : ["--model", copilotModel];
|
|
301
302
|
return ["-p", ...promptArg, ...copilotModelArg, "--allow-all-tools"];
|
|
302
303
|
}
|
|
303
304
|
}
|
|
@@ -455,8 +456,6 @@ var init_agent_runner = __esm({
|
|
|
455
456
|
};
|
|
456
457
|
DEFAULT_MODELS = {
|
|
457
458
|
claude: "haiku",
|
|
458
|
-
codex: "gpt-5.4-mini",
|
|
459
|
-
// requires OPENAI_API_KEY; ChatGPT account users must pass --model
|
|
460
459
|
opencode: "claude-haiku-4-5",
|
|
461
460
|
cursor: "gpt-mini",
|
|
462
461
|
// cursor alias for gpt-5.4-mini-medium; haiku not in cursor's catalog
|
|
@@ -12576,7 +12575,7 @@ var init_src3 = __esm({
|
|
|
12576
12575
|
}
|
|
12577
12576
|
});
|
|
12578
12577
|
|
|
12579
|
-
// packages/experience-design-system-cli/src/
|
|
12578
|
+
// packages/experience-design-system-cli/src/host-utils.ts
|
|
12580
12579
|
function trimTrailingSlashes(value) {
|
|
12581
12580
|
return value.replace(/\/+$/, "");
|
|
12582
12581
|
}
|
|
@@ -12599,8 +12598,8 @@ function toApiHost(host) {
|
|
|
12599
12598
|
return `https://${normalized}`;
|
|
12600
12599
|
}
|
|
12601
12600
|
var DEFAULT_API_HOST, DEFAULT_CONFIGURED_HOST;
|
|
12602
|
-
var
|
|
12603
|
-
"packages/experience-design-system-cli/src/
|
|
12601
|
+
var init_host_utils = __esm({
|
|
12602
|
+
"packages/experience-design-system-cli/src/host-utils.ts"() {
|
|
12604
12603
|
"use strict";
|
|
12605
12604
|
DEFAULT_API_HOST = "https://api.contentful.com";
|
|
12606
12605
|
DEFAULT_CONFIGURED_HOST = "api.contentful.com";
|
|
@@ -12807,55 +12806,7 @@ var init_user_agent = __esm({
|
|
|
12807
12806
|
}
|
|
12808
12807
|
});
|
|
12809
12808
|
|
|
12810
|
-
// packages/experience-design-system-cli/src/
|
|
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
|
|
12809
|
+
// packages/experience-design-system-cli/src/apply/api-client.ts
|
|
12859
12810
|
function defaultSleep(delayMs) {
|
|
12860
12811
|
return new Promise((resolve27) => setTimeout(resolve27, delayMs));
|
|
12861
12812
|
}
|
|
@@ -12938,20 +12889,48 @@ function isApsDenialBody(body) {
|
|
|
12938
12889
|
return false;
|
|
12939
12890
|
}
|
|
12940
12891
|
}
|
|
12941
|
-
|
|
12942
|
-
|
|
12943
|
-
|
|
12892
|
+
async function request(url, options) {
|
|
12893
|
+
const headers = {
|
|
12894
|
+
Authorization: `Bearer ${options.token}`,
|
|
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"() {
|
|
12944
12908
|
"use strict";
|
|
12945
12909
|
init_src3();
|
|
12946
|
-
|
|
12910
|
+
init_host_utils();
|
|
12947
12911
|
init_debug_logger();
|
|
12948
12912
|
init_user_agent();
|
|
12949
|
-
init_http();
|
|
12950
|
-
init_api_error();
|
|
12951
12913
|
PREVIEW_ERROR_PREFIX = "preview failed:";
|
|
12952
12914
|
APPLY_ERROR_PREFIX = "apply failed:";
|
|
12953
12915
|
VALIDATION_FAILED_CODE = '"ValidationFailed"';
|
|
12954
12916
|
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
|
+
};
|
|
12955
12934
|
COMPONENT_PATH_PREFIX = "manifest:components/";
|
|
12956
12935
|
PROPERTY_BREAKING_REASONS = /* @__PURE__ */ new Set([
|
|
12957
12936
|
"removed",
|
|
@@ -12960,7 +12939,7 @@ var init_edsi_client = __esm({
|
|
|
12960
12939
|
"validation_narrowed"
|
|
12961
12940
|
]);
|
|
12962
12941
|
SLOT_BREAKING_REASONS = /* @__PURE__ */ new Set(["slot_removed", "slot_allowed_components_narrowed"]);
|
|
12963
|
-
|
|
12942
|
+
ImportApiClient = class {
|
|
12964
12943
|
host;
|
|
12965
12944
|
token;
|
|
12966
12945
|
spaceId;
|
|
@@ -13226,15 +13205,6 @@ var init_edsi_client = __esm({
|
|
|
13226
13205
|
}
|
|
13227
13206
|
});
|
|
13228
13207
|
|
|
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
|
-
|
|
13238
13208
|
// packages/experience-design-system-cli/src/lib/error-parser.ts
|
|
13239
13209
|
function stripLambdaLogPrefix(body) {
|
|
13240
13210
|
let out = body.replace(LAMBDA_LOG_PREFIX_RE, "");
|
|
@@ -14223,14 +14193,6 @@ var init_strip_allowed_components = __esm({
|
|
|
14223
14193
|
}
|
|
14224
14194
|
});
|
|
14225
14195
|
|
|
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
|
-
|
|
14234
14196
|
// packages/experience-design-system-cli/src/credentials-store.ts
|
|
14235
14197
|
var credentials_store_exports = {};
|
|
14236
14198
|
__export(credentials_store_exports, {
|
|
@@ -14846,7 +14808,7 @@ async function resolveSharedInputs(opts) {
|
|
|
14846
14808
|
if (opts.tokens) {
|
|
14847
14809
|
tokens = await readTokensFromPath("--tokens", opts.tokens);
|
|
14848
14810
|
}
|
|
14849
|
-
const client2 = new
|
|
14811
|
+
const client2 = new ImportApiClient({
|
|
14850
14812
|
host: opts.host,
|
|
14851
14813
|
cmaToken,
|
|
14852
14814
|
spaceId,
|
|
@@ -15586,7 +15548,7 @@ function App({ sessionId: sessionId2, artifactsRoot, reviewRoot }) {
|
|
|
15586
15548
|
tokens
|
|
15587
15549
|
);
|
|
15588
15550
|
if (!manifest.componentsManifest) manifest.componentsManifest = {};
|
|
15589
|
-
const client2 = new
|
|
15551
|
+
const client2 = new ImportApiClient({ cmaToken, spaceId, environmentId });
|
|
15590
15552
|
const preview = await client2.previewImport(manifest, true);
|
|
15591
15553
|
const annotations = {};
|
|
15592
15554
|
for (const item of preview.components.new) {
|
|
@@ -16608,7 +16570,7 @@ var init_save_path_resolver = __esm({
|
|
|
16608
16570
|
});
|
|
16609
16571
|
|
|
16610
16572
|
// packages/experience-design-system-cli/src/runs/store.ts
|
|
16611
|
-
import { readFile as readFile22, writeFile as
|
|
16573
|
+
import { readFile as readFile22, writeFile as writeFile5, mkdir as mkdir6, rename } from "node:fs/promises";
|
|
16612
16574
|
import { join as join20 } from "node:path";
|
|
16613
16575
|
import { homedir as homedir7 } from "node:os";
|
|
16614
16576
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
@@ -16671,7 +16633,7 @@ async function writeAtomic(file) {
|
|
|
16671
16633
|
await mkdir6(RUNS_DIR, { recursive: true });
|
|
16672
16634
|
const body = JSON.stringify(file, null, 2) + "\n";
|
|
16673
16635
|
const tmp = `${RUNS_PATH}.${process.pid}.${Date.now()}.tmp`;
|
|
16674
|
-
await
|
|
16636
|
+
await writeFile5(tmp, body, { mode: 384 });
|
|
16675
16637
|
await rename(tmp, RUNS_PATH);
|
|
16676
16638
|
}
|
|
16677
16639
|
async function appendRun(input) {
|
|
@@ -24153,7 +24115,7 @@ async function runLivePreview(opts) {
|
|
|
24153
24115
|
tokens = await readTokensFromPath("tokens", tokensPath);
|
|
24154
24116
|
}
|
|
24155
24117
|
const manifest = buildManifest3(components, tokens, { deleteAllComponents: opts.deleteAllComponents === true });
|
|
24156
|
-
const client2 = new
|
|
24118
|
+
const client2 = new ImportApiClient({ host, cmaToken, spaceId, environmentId });
|
|
24157
24119
|
const startedAt = Date.now();
|
|
24158
24120
|
let timeoutHandle;
|
|
24159
24121
|
const timeoutPromise = new Promise((_resolve, reject) => {
|
|
@@ -28364,7 +28326,7 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
|
|
|
28364
28326
|
update({ step: "credentials", credentialsValidating: true, credentialsError: "" });
|
|
28365
28327
|
try {
|
|
28366
28328
|
const resolvedHost = resolveWizardHost(host2);
|
|
28367
|
-
const client2 = new
|
|
28329
|
+
const client2 = new ImportApiClient({
|
|
28368
28330
|
cmaToken,
|
|
28369
28331
|
spaceId,
|
|
28370
28332
|
environmentId,
|
|
@@ -28438,7 +28400,7 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
|
|
|
28438
28400
|
update({ step: "previewing" });
|
|
28439
28401
|
const resolvedHost = resolveWizardHost(host2);
|
|
28440
28402
|
try {
|
|
28441
|
-
const client2 = new
|
|
28403
|
+
const client2 = new ImportApiClient({
|
|
28442
28404
|
cmaToken,
|
|
28443
28405
|
spaceId,
|
|
28444
28406
|
environmentId,
|
|
@@ -28600,7 +28562,7 @@ If using a custom --host, make sure the space exists on that host.`
|
|
|
28600
28562
|
update({ step: "pushing", pushProgress: null });
|
|
28601
28563
|
try {
|
|
28602
28564
|
const resolvedHost = resolveWizardHost(host2);
|
|
28603
|
-
const client2 = new
|
|
28565
|
+
const client2 = new ImportApiClient({
|
|
28604
28566
|
cmaToken,
|
|
28605
28567
|
spaceId,
|
|
28606
28568
|
environmentId,
|
|
@@ -34345,72 +34307,14 @@ init_db();
|
|
|
34345
34307
|
init_command();
|
|
34346
34308
|
init_manifest();
|
|
34347
34309
|
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
|
|
34409
34310
|
init_contentful_urls();
|
|
34410
34311
|
init_debug_logger();
|
|
34411
34312
|
init_analytics();
|
|
34412
34313
|
init_env();
|
|
34413
34314
|
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";
|
|
34414
34318
|
async function runStep(args, cliPath, analyticsSessionId, env = {}, streamStderr = false) {
|
|
34415
34319
|
const debug = getDebugLogger();
|
|
34416
34320
|
const startedAt = Date.now();
|
|
@@ -34518,66 +34422,11 @@ async function runPipeline(opts, progressWriter, cliPathOverride) {
|
|
|
34518
34422
|
await mkdir5(outDir, { recursive: true });
|
|
34519
34423
|
const steps = [];
|
|
34520
34424
|
let stepNum = 0;
|
|
34521
|
-
const
|
|
34522
|
-
const canFetchSpaceContext = wantsSpaceContext && !!opts.spaceId && !!opts.environmentId && !!opts.cmaToken;
|
|
34523
|
-
const totalSteps = 5 + (opts.print ? 1 : 0) + (canFetchSpaceContext ? 1 : 0);
|
|
34425
|
+
const totalSteps = 5 + (opts.print ? 1 : 0);
|
|
34524
34426
|
function stepLabel(name) {
|
|
34525
34427
|
stepNum++;
|
|
34526
34428
|
return ` Step ${stepNum}/${totalSteps} ${name} `;
|
|
34527
34429
|
}
|
|
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
|
-
}
|
|
34581
34430
|
const analyzeLabel = stepLabel("Statically analyzing project");
|
|
34582
34431
|
const analyzeSkipped = !opts.noCache && opts.skipAnalyze;
|
|
34583
34432
|
let extractSessionId = null;
|
|
@@ -35529,10 +35378,7 @@ function registerImportCommand(program) {
|
|
|
35529
35378
|
"Override a stage prompt (repeatable). value is a file path or literal text, e.g. --prompt composition=./p.md",
|
|
35530
35379
|
(v, acc) => [...acc, v],
|
|
35531
35380
|
[]
|
|
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(
|
|
35381
|
+
).option("--auto-reject-cycles", "Automatically reject components involved in slot cycles and retry").option("--auto-filter", "Force the AI auto-filter ON (overrides the credentials.json autoFilter preference)").option(
|
|
35536
35382
|
"--no-auto-filter",
|
|
35537
35383
|
"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)"
|
|
35538
35384
|
).option(
|
|
@@ -35867,7 +35713,6 @@ function registerImportCommand(program) {
|
|
|
35867
35713
|
dryRun: dryRunForward,
|
|
35868
35714
|
selectPromptPath: opts.selectPromptPath,
|
|
35869
35715
|
autoRejectCycles: opts.autoRejectCycles ?? false,
|
|
35870
|
-
withSpaceContext: opts.withSpaceContext ?? false,
|
|
35871
35716
|
allowDeletions: opts.allowDeletions ?? false,
|
|
35872
35717
|
compositionMode: headlessCompositionMode,
|
|
35873
35718
|
...opts.compositionMap ? { compositionMap: opts.compositionMap } : {},
|
|
@@ -36251,26 +36096,15 @@ function pick(items, defaultIdx = 0) {
|
|
|
36251
36096
|
process.stdout.write(` \x1B[2m[s] Skip\x1B[0m
|
|
36252
36097
|
`);
|
|
36253
36098
|
}
|
|
36254
|
-
async function promptCodexModel() {
|
|
36099
|
+
async function promptCodexModel(ask = prompt) {
|
|
36255
36100
|
if (process.env["OPENAI_API_KEY"]) return void 0;
|
|
36256
36101
|
info("");
|
|
36257
36102
|
process.stdout.write(` \x1B[33m\u26A0\x1B[0m No OPENAI_API_KEY \u2014 using ChatGPT account authentication.
|
|
36258
36103
|
`);
|
|
36259
|
-
info(" Tip: run \x1B[1mcodex\x1B[0m then type \x1B[1m/model\x1B[0m to browse
|
|
36260
|
-
|
|
36261
|
-
|
|
36262
|
-
|
|
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;
|
|
36104
|
+
info(" Tip: run \x1B[1mcodex\x1B[0m then type \x1B[1m/model\x1B[0m to browse the models available to your account.");
|
|
36105
|
+
const model = await ask(" Model name (optional - press Enter for Codex default): ");
|
|
36106
|
+
const trimmed = model.trim();
|
|
36107
|
+
return trimmed || void 0;
|
|
36274
36108
|
}
|
|
36275
36109
|
async function setupAgent() {
|
|
36276
36110
|
section("Step 4: Coding agent (claude, codex, opencode, or copilot)", "[required]");
|
|
@@ -36297,7 +36131,6 @@ async function setupAgent() {
|
|
|
36297
36131
|
const parsed = choice2 === "" ? 1 : parseInt(choice2, 10);
|
|
36298
36132
|
const idx = Number.isNaN(parsed) || parsed < 1 || parsed > found.length ? 0 : parsed - 1;
|
|
36299
36133
|
const selected = found[idx];
|
|
36300
|
-
ok(`${selected.name} \x1B[2m(${selected.binary})\x1B[0m selected`);
|
|
36301
36134
|
const agentModel = selected.binary === "codex" ? await promptCodexModel() : void 0;
|
|
36302
36135
|
return { agent: selected.binary, agentModel };
|
|
36303
36136
|
}
|
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' | '
|
|
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';
|
|
9
9
|
export interface SessionRow {
|
|
10
10
|
id: string;
|
|
11
11
|
name: string | null;
|
|
@@ -1,4 +1,10 @@
|
|
|
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
|
+
}>;
|
|
2
8
|
export type SkillPromptKind = 'select' | 'generate';
|
|
3
9
|
/**
|
|
4
10
|
* 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-10912f6.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-cli-v2": "2.32.1-dev-build-
|
|
43
|
-
"@contentful/experience-design-system-types": "2.32.1-dev-build-
|
|
42
|
+
"@contentful/experience-design-system-cli-v2": "2.32.1-dev-build-10912f6.0",
|
|
43
|
+
"@contentful/experience-design-system-types": "2.32.1-dev-build-10912f6.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-client": "2.32.1-dev-build-
|
|
56
|
-
"@contentful/experience-design-system-
|
|
57
|
-
"@contentful/experience-design-system-
|
|
55
|
+
"@contentful/experience-design-system-client": "2.32.1-dev-build-10912f6.0",
|
|
56
|
+
"@contentful/experience-design-system-extraction": "2.32.1-dev-build-10912f6.0",
|
|
57
|
+
"@contentful/experience-design-system-generation": "2.32.1-dev-build-10912f6.0"
|
|
58
58
|
},
|
|
59
59
|
"repository": {
|
|
60
60
|
"type": "git",
|
|
@@ -1,13 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,47 +0,0 @@
|
|
|
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
|
-
}
|
package/dist/src/api/index.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
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,4 +0,0 @@
|
|
|
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;
|
|
@@ -1,12 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,6 +0,0 @@
|
|
|
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
|
-
}
|