@deployxai/dxc 0.1.7 → 0.1.8

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/index.js CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  import {
7
7
  SourceCli,
8
8
  SourceCliError
9
- } from "./chunks/chunk-NAL5UOUZ.js";
9
+ } from "./chunks/chunk-QPHUHGHV.js";
10
10
  import {
11
11
  CONTENT_ARTIFACT_KINDS,
12
12
  CONTENT_STAGE_INPUTS,
@@ -81,7 +81,7 @@ import {
81
81
  wechatRenderResultSchema,
82
82
  writePrivateBuffer,
83
83
  writePrivateJson
84
- } from "./chunks/chunk-N4CMLINP.js";
84
+ } from "./chunks/chunk-UQRFCGHR.js";
85
85
 
86
86
  // node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/dist/nodes/identity.js
87
87
  var require_identity = __commonJS({
@@ -23295,7 +23295,7 @@ import os3 from "node:os";
23295
23295
  // apps/cli/package.json
23296
23296
  var package_default = {
23297
23297
  name: "@dxc/cli",
23298
- version: "0.1.7",
23298
+ version: "0.1.8",
23299
23299
  private: true,
23300
23300
  type: "module",
23301
23301
  bin: {
@@ -27207,13 +27207,13 @@ var ContentMemoryCli = class {
27207
27207
  // apps/cli/src/project.ts
27208
27208
  import { createHash as createHash4, randomUUID as randomUUID3 } from "node:crypto";
27209
27209
  import { createReadStream } from "node:fs";
27210
- import { lstat as lstat2, mkdir, readFile as readFile3, rename as rename3, unlink as unlink2, writeFile as writeFile2 } from "node:fs/promises";
27210
+ import { lstat as lstat3, mkdir, readFile as readFile3, rename as rename3, unlink as unlink2, writeFile as writeFile2 } from "node:fs/promises";
27211
27211
  import path4 from "node:path";
27212
27212
 
27213
27213
  // apps/cli/src/stage-artifact.ts
27214
27214
  import { createHash as createHash3, randomUUID as randomUUID2 } from "node:crypto";
27215
27215
  import { constants as fileConstants } from "node:fs";
27216
- import { open, readFile as readFile2, rename as rename2, unlink, writeFile } from "node:fs/promises";
27216
+ import { lstat as lstat2, open, readFile as readFile2, rename as rename2, unlink, writeFile } from "node:fs/promises";
27217
27217
  import path3 from "node:path";
27218
27218
 
27219
27219
  // packages/renderer-wechat/src/article.ts
@@ -29338,10 +29338,26 @@ var StageArtifactValidationError = class extends Error {
29338
29338
  issues;
29339
29339
  };
29340
29340
  function issuePaths2(issues) {
29341
- return issues.map((issue) => {
29342
- const location = issue.path.map(String).join(".");
29343
- return location.length === 0 ? issue.message : location;
29344
- });
29341
+ const flattened = issues.flatMap(
29342
+ (issue) => issue.code === "invalid_union" && issue.errors !== void 0 ? [...issue.errors].sort((left, right) => left.length - right.length)[0] ?? [] : [issue]
29343
+ );
29344
+ return [
29345
+ ...new Set(
29346
+ flattened.map((issue) => {
29347
+ const location = issue.path.map(String).join(".");
29348
+ if (location === "coverSource" || /^inlineAssets\.\d+\.source$/u.test(location)) {
29349
+ return `${location}: \u4EC5\u5141\u8BB8 agent-generated\uFF08\u672C\u6B21\u7531 Agent \u751F\u6210\uFF09\u6216 local-material\uFF08\u7528\u6237\u63D0\u4F9B\u7684\u672C\u5730\u7D20\u6750\uFF09\uFF1BSVG \u6216\u56FE\u8868\u7ECF\u5BFC\u51FA\u4E3A PNG/JPEG \u540E\uFF0C\u6309\u771F\u5B9E\u6765\u6E90\u9009\u62E9\u5176\u4E2D\u4E00\u4E2A\u503C`;
29350
+ }
29351
+ if (issue.code === "unrecognized_keys" && issue.keys?.includes("planned")) {
29352
+ return "planned: \u8BE5\u5B57\u6BB5\u4E0D\u5C5E\u4E8E\u5DF2\u5B8C\u6210\u89C6\u89C9\u4EA7\u7269\uFF1Bplanned=true \u53EA\u80FD\u4F7F\u7528\u751F\u6210\u524D\u6388\u6743\u5951\u7EA6\uFF0C\u751F\u6210\u7ED3\u675F\u540E\u5FC5\u987B\u79FB\u9664";
29353
+ }
29354
+ if (location === "generation") {
29355
+ return "generation: planned=true \u65F6\u5FC5\u987B\u58F0\u660E executionLocation\u3001dataTransit\u3001chargesQuota\u3001maxAttempts \u548C plannedAssets\uFF0C\u5E76\u8D70\u751F\u6210\u524D\u6388\u6743\u5951\u7EA6";
29356
+ }
29357
+ return location.length === 0 ? issue.message : `${location}: ${issue.message}`;
29358
+ })
29359
+ )
29360
+ ];
29345
29361
  }
29346
29362
  function insideProject(directory, relativePath) {
29347
29363
  const target = path3.resolve(directory, relativePath);
@@ -29351,11 +29367,16 @@ function insideProject(directory, relativePath) {
29351
29367
  }
29352
29368
  return target;
29353
29369
  }
29354
- async function readRegularFile(target, maximumBytes) {
29370
+ async function readRegularFile(target, maximumBytes, imageRole) {
29355
29371
  let handle;
29356
29372
  try {
29357
29373
  handle = await open(target, fileConstants.O_RDONLY | fileConstants.O_NOFOLLOW);
29358
29374
  const metadata = await handle.stat();
29375
+ if (metadata.isFile() && metadata.size > maximumBytes && imageRole !== void 0) {
29376
+ throw new StageArtifactValidationError([
29377
+ imageRole === "inline-image" ? `${path3.basename(target)} \u662F\u6B63\u6587\u56FE\u7247\uFF0C\u5B9E\u9645 ${metadata.size} bytes\uFF0C\u5FC5\u987B\u5C0F\u4E8E 1048576 bytes\uFF1B\u8BF7\u5BFC\u51FA JPEG \u6216\u964D\u4F4E\u5C3A\u5BF8/\u8D28\u91CF\u540E\u66F4\u65B0\u89C6\u89C9\u8BA1\u5212` : `${path3.basename(target)} \u662F\u5C01\u9762\uFF0C\u5B9E\u9645 ${metadata.size} bytes\uFF0C\u4E0A\u9650 ${maximumBytes} bytes\uFF1B\u8BF7\u964D\u4F4E\u5C3A\u5BF8\u6216\u8D28\u91CF\u540E\u66F4\u65B0\u89C6\u89C9\u8BA1\u5212`
29378
+ ]);
29379
+ }
29359
29380
  if (!metadata.isFile() || metadata.size <= 0 || metadata.size > maximumBytes) {
29360
29381
  throw new StageArtifactValidationError([path3.basename(target)]);
29361
29382
  }
@@ -29385,8 +29406,12 @@ function isSupportedImage(bytes, filePath) {
29385
29406
  function isInsideDirectory(filePath, directory) {
29386
29407
  return filePath.startsWith(`${directory}/`);
29387
29408
  }
29388
- async function validateImageAsset(directory, logicalPath, expectedSha256, maximumBytes) {
29389
- const bytes = await readRegularFile(insideProject(directory, logicalPath), maximumBytes);
29409
+ async function validateImageAsset(directory, logicalPath, expectedSha256, maximumBytes, imageRole) {
29410
+ const bytes = await readRegularFile(
29411
+ insideProject(directory, logicalPath),
29412
+ maximumBytes,
29413
+ imageRole
29414
+ );
29390
29415
  if (!isSupportedImage(bytes, logicalPath)) {
29391
29416
  throw new StageArtifactValidationError([`${logicalPath} \u4E0D\u662F\u771F\u5B9E PNG/JPEG \u6587\u4EF6`]);
29392
29417
  }
@@ -29468,6 +29493,30 @@ async function writeAtomically(target, bytes) {
29468
29493
  throw error;
29469
29494
  }
29470
29495
  }
29496
+ async function captureFile(target, logicalPath) {
29497
+ try {
29498
+ const metadata = await lstat2(target);
29499
+ if (!metadata.isFile() || metadata.isSymbolicLink()) {
29500
+ throw new StageArtifactValidationError([path3.basename(target)]);
29501
+ }
29502
+ return { bytes: await readFile2(target), logicalPath, target };
29503
+ } catch (error) {
29504
+ if (error.code === "ENOENT") {
29505
+ return { logicalPath, target };
29506
+ }
29507
+ throw error;
29508
+ }
29509
+ }
29510
+ async function assertFileUnchanged(candidate) {
29511
+ const current = await captureFile(candidate.target, candidate.logicalPath);
29512
+ const beforeHash = candidate.bytes === void 0 ? null : sha256(candidate.bytes);
29513
+ const currentHash = current.bytes === void 0 ? null : sha256(current.bytes);
29514
+ if (beforeHash !== currentHash) {
29515
+ throw new StageArtifactValidationError([
29516
+ `NORMALIZATION_CONFLICT: ${candidate.logicalPath} \u5728\u6821\u9A8C\u671F\u95F4\u88AB\u5176\u4ED6\u8FDB\u7A0B\u4FEE\u6539\uFF1BCLI \u672A\u8986\u76D6\u8BE5\u6587\u4EF6\uFF0C\u8BF7\u91CD\u65B0\u8BFB\u53D6\u540E\u91CD\u8BD5`
29517
+ ]);
29518
+ }
29519
+ }
29471
29520
  async function bindDeliveryApprovalArtifact(options) {
29472
29521
  const source = (await readRegularFile(options.target, MAXIMUM_ARTIFACT_BYTES)).toString("utf8");
29473
29522
  const frontmatter = parseFrontmatter2(source);
@@ -29500,19 +29549,35 @@ ${frontmatter.body}
29500
29549
  `
29501
29550
  );
29502
29551
  }
29552
+ async function readDeliveryDraftIdentity(target) {
29553
+ const source = (await readRegularFile(target, MAXIMUM_ARTIFACT_BYTES)).toString("utf8");
29554
+ const parsed = deliveryStageArtifactFrontmatterSchema.safeParse(parseFrontmatter2(source).value);
29555
+ if (!parsed.success) {
29556
+ throw new StageArtifactValidationError(issuePaths2(parsed.error.issues));
29557
+ }
29558
+ return {
29559
+ accountId: parsed.data.accountId,
29560
+ idempotencyKey: parsed.data.idempotencyKey,
29561
+ rootSnapshotHash: parsed.data.rootSnapshotHash,
29562
+ rootSnapshotId: parsed.data.rootSnapshotId
29563
+ };
29564
+ }
29503
29565
  async function normalizeGoldenLines(directory, body, logicalPath) {
29504
29566
  const target = insideProject(directory, logicalPath);
29567
+ const snapshot = await captureFile(target, logicalPath);
29505
29568
  let parsed;
29506
29569
  try {
29507
- const bytes2 = await readFile2(target);
29508
- if (bytes2.length === 0 || bytes2.length > 64 * 1024) {
29509
- throw new StageArtifactValidationError([`${logicalPath} \u4E0D\u662F\u5408\u6CD5\u91D1\u53E5\u4EA4\u63A5\u6587\u4EF6`]);
29570
+ const bytes2 = snapshot.bytes;
29571
+ if (bytes2 === void 0) {
29572
+ parsed = { lines: [], schemaVersion: "dxc-golden-lines@1" };
29573
+ } else {
29574
+ if (bytes2.length === 0 || bytes2.length > 64 * 1024) {
29575
+ throw new StageArtifactValidationError([`${logicalPath} \u4E0D\u662F\u5408\u6CD5\u91D1\u53E5\u4EA4\u63A5\u6587\u4EF6`]);
29576
+ }
29577
+ parsed = JSON.parse(bytes2.toString("utf8"));
29510
29578
  }
29511
- parsed = JSON.parse(bytes2.toString("utf8"));
29512
29579
  } catch (error) {
29513
- if (error.code === "ENOENT") {
29514
- parsed = { lines: [], schemaVersion: "dxc-golden-lines@1" };
29515
- } else if (error instanceof StageArtifactValidationError) {
29580
+ if (error instanceof StageArtifactValidationError) {
29516
29581
  throw error;
29517
29582
  } else {
29518
29583
  throw new StageArtifactValidationError([`${logicalPath} \u4E0D\u662F\u5408\u6CD5\u91D1\u53E5\u4EA4\u63A5\u6587\u4EF6`]);
@@ -29531,16 +29596,17 @@ async function normalizeGoldenLines(directory, body, logicalPath) {
29531
29596
  };
29532
29597
  const bytes = Buffer.from(`${JSON.stringify(normalized, void 0, 2)}
29533
29598
  `, "utf8");
29534
- await writeAtomically(target, bytes);
29535
- return sha256(bytes);
29599
+ return { bytes, snapshot };
29536
29600
  }
29537
29601
  async function normalizeStageArtifact(options) {
29538
29602
  const artifactPath = options.manifest.artifacts[options.stage];
29539
29603
  const target = insideProject(options.directory, artifactPath);
29540
- const source = (await readRegularFile(
29541
- target,
29542
- options.stage === "article" ? MAXIMUM_ARTICLE_BYTES : MAXIMUM_ARTIFACT_BYTES
29543
- )).toString("utf8");
29604
+ const sourceSnapshot = await captureFile(target, artifactPath);
29605
+ const maximumBytes = options.stage === "article" ? MAXIMUM_ARTICLE_BYTES : MAXIMUM_ARTIFACT_BYTES;
29606
+ if (sourceSnapshot.bytes === void 0 || sourceSnapshot.bytes.length === 0 || sourceSnapshot.bytes.length > maximumBytes) {
29607
+ throw new StageArtifactValidationError([path3.basename(target)]);
29608
+ }
29609
+ const source = sourceSnapshot.bytes.toString("utf8");
29544
29610
  const frontmatter = parseFrontmatter2(source);
29545
29611
  const value = recordValue(frontmatter.value);
29546
29612
  if (value === void 0) {
@@ -29549,6 +29615,8 @@ async function normalizeStageArtifact(options) {
29549
29615
  const previousDxc = recordValue(value["dxc"]) ?? {};
29550
29616
  const nextValue = { ...value };
29551
29617
  const rootQuoteSnapshots = nextValue["quoteSnapshots"];
29618
+ const candidateFiles = [];
29619
+ const sidecars = /* @__PURE__ */ new Map();
29552
29620
  delete nextValue["quoteSnapshots"];
29553
29621
  nextValue["dxc"] = {
29554
29622
  artifactStatus: options.artifactStatus,
@@ -29603,11 +29671,14 @@ async function normalizeStageArtifact(options) {
29603
29671
  const defaultGoldenLinesPath = artifactPath.replace(/\.md$/iu, ".golden-lines.json");
29604
29672
  const goldenLinesPath = typeof nextValue["goldenLinesPath"] === "string" && nextValue["goldenLinesPath"].trim().length > 0 ? nextValue["goldenLinesPath"].trim() : defaultGoldenLinesPath;
29605
29673
  nextValue["goldenLinesPath"] = goldenLinesPath;
29606
- nextValue["goldenLinesSha256"] = await normalizeGoldenLines(
29674
+ const goldenLines = await normalizeGoldenLines(
29607
29675
  options.directory,
29608
29676
  frontmatter.body,
29609
29677
  goldenLinesPath
29610
29678
  );
29679
+ nextValue["goldenLinesSha256"] = sha256(goldenLines.bytes);
29680
+ sidecars.set(goldenLinesPath, goldenLines.bytes);
29681
+ candidateFiles.push({ ...goldenLines.snapshot, afterBytes: goldenLines.bytes });
29611
29682
  }
29612
29683
  if (options.stage === "titles") {
29613
29684
  const articleInput = options.inputs.find((input) => input.kind === "article");
@@ -29618,16 +29689,20 @@ async function normalizeStageArtifact(options) {
29618
29689
  if (options.stage === "visual-plan") {
29619
29690
  nextValue["assetsDirectory"] ??= options.manifest.assetsDirectory;
29620
29691
  nextValue["inlineImagesSupported"] ??= true;
29621
- nextValue["inlineAssets"] ??= [];
29622
- if (typeof nextValue["coverAsset"] === "string") {
29692
+ const isGenerationProposal = nextValue["planned"] === true;
29693
+ if (!isGenerationProposal) {
29694
+ nextValue["inlineAssets"] ??= [];
29695
+ }
29696
+ if (!isGenerationProposal && typeof nextValue["coverAsset"] === "string") {
29623
29697
  nextValue["coverSha256"] = sha256(
29624
29698
  await readRegularFile(
29625
29699
  insideProject(options.directory, nextValue["coverAsset"]),
29626
- MAXIMUM_COVER_BYTES
29700
+ MAXIMUM_COVER_BYTES,
29701
+ "cover"
29627
29702
  )
29628
29703
  );
29629
29704
  }
29630
- if (Array.isArray(nextValue["inlineAssets"])) {
29705
+ if (!isGenerationProposal && Array.isArray(nextValue["inlineAssets"])) {
29631
29706
  nextValue["inlineAssets"] = await Promise.all(
29632
29707
  nextValue["inlineAssets"].map(async (asset) => {
29633
29708
  const value2 = recordValue(asset);
@@ -29639,7 +29714,8 @@ async function normalizeStageArtifact(options) {
29639
29714
  sha256: sha256(
29640
29715
  await readRegularFile(
29641
29716
  insideProject(options.directory, value2["path"]),
29642
- MAXIMUM_INLINE_IMAGE_BYTES
29717
+ MAXIMUM_INLINE_IMAGE_BYTES,
29718
+ "inline-image"
29643
29719
  )
29644
29720
  )
29645
29721
  };
@@ -29691,12 +29767,58 @@ ${(0, import_yaml2.stringify)(nextValue, { lineWidth: 0 }).trimEnd()}
29691
29767
 
29692
29768
  ${frontmatter.body}
29693
29769
  `;
29694
- if (normalizedSource !== source) {
29695
- await writeAtomically(target, normalizedSource);
29696
- }
29770
+ const normalizedBytes = Buffer.from(normalizedSource, "utf8");
29771
+ candidateFiles.push({ ...sourceSnapshot, afterBytes: normalizedBytes });
29772
+ const changedFiles = candidateFiles.filter(
29773
+ (candidate) => candidate.bytes === void 0 || !candidate.bytes.equals(candidate.afterBytes)
29774
+ );
29775
+ let committedFiles = [];
29776
+ const rollbackCommitted = async () => {
29777
+ for (const candidate of [...committedFiles].reverse()) {
29778
+ const current = await captureFile(candidate.target, candidate.logicalPath);
29779
+ if (current.bytes === void 0 || sha256(current.bytes) !== sha256(candidate.afterBytes)) {
29780
+ continue;
29781
+ }
29782
+ if (candidate.bytes === void 0) {
29783
+ await unlink(candidate.target);
29784
+ } else {
29785
+ await writeAtomically(candidate.target, candidate.bytes);
29786
+ }
29787
+ }
29788
+ committedFiles = [];
29789
+ };
29790
+ return {
29791
+ artifact: {
29792
+ bytes: normalizedBytes.length,
29793
+ path: artifactPath,
29794
+ sha256: sha256(normalizedBytes)
29795
+ },
29796
+ candidate: { sidecars, source: normalizedSource },
29797
+ commit: async () => {
29798
+ for (const candidate of candidateFiles) {
29799
+ await assertFileUnchanged(candidate);
29800
+ }
29801
+ try {
29802
+ for (const candidate of changedFiles) {
29803
+ await assertFileUnchanged(candidate);
29804
+ await writeAtomically(candidate.target, candidate.afterBytes);
29805
+ committedFiles.push(candidate);
29806
+ }
29807
+ } catch (error) {
29808
+ await rollbackCommitted();
29809
+ throw error;
29810
+ }
29811
+ },
29812
+ mutations: changedFiles.map((candidate) => ({
29813
+ afterSha256: sha256(candidate.afterBytes),
29814
+ beforeSha256: candidate.bytes === void 0 ? null : sha256(candidate.bytes),
29815
+ path: candidate.logicalPath
29816
+ })),
29817
+ rollbackCommitted
29818
+ };
29697
29819
  }
29698
- async function validateGoldenLinesSidecar(directory, articleBody, logicalPath, expectedSha256) {
29699
- const bytes = await readRegularFile(insideProject(directory, logicalPath), 64 * 1024);
29820
+ async function validateGoldenLinesSidecar(directory, articleBody, logicalPath, expectedSha256, candidateBytes) {
29821
+ const bytes = candidateBytes ?? await readRegularFile(insideProject(directory, logicalPath), 64 * 1024);
29700
29822
  if (sha256(bytes) !== expectedSha256) {
29701
29823
  throw new StageArtifactValidationError([`${logicalPath} \u54C8\u5E0C\u4E0D\u4E00\u81F4`]);
29702
29824
  }
@@ -29729,13 +29851,27 @@ function compareInputs(declared, actual) {
29729
29851
  }
29730
29852
  return issues;
29731
29853
  }
29854
+ function bindConfirmationInputs(contentHash, inputs) {
29855
+ return sha256(
29856
+ Buffer.from(
29857
+ JSON.stringify({
29858
+ contentHash,
29859
+ inputs: inputs.map((input) => ({
29860
+ kind: input.kind,
29861
+ path: input.path,
29862
+ sha256: input.sha256 ?? null
29863
+ }))
29864
+ }),
29865
+ "utf8"
29866
+ )
29867
+ );
29868
+ }
29732
29869
  async function validateStageArtifact(options) {
29733
29870
  const artifactPath = options.manifest.artifacts[options.stage];
29734
- const bytes = await readRegularFile(
29871
+ const source = options.candidate?.source ?? (await readRegularFile(
29735
29872
  insideProject(options.directory, artifactPath),
29736
29873
  options.stage === "article" ? MAXIMUM_ARTICLE_BYTES : MAXIMUM_ARTIFACT_BYTES
29737
- );
29738
- const source = bytes.toString("utf8");
29874
+ )).toString("utf8");
29739
29875
  const frontmatter = parseFrontmatter2(source);
29740
29876
  const parsed = contentStageArtifactFrontmatterSchema(options.stage).safeParse(frontmatter.value);
29741
29877
  if (!parsed.success) {
@@ -29775,7 +29911,8 @@ async function validateStageArtifact(options) {
29775
29911
  options.directory,
29776
29912
  frontmatter.body,
29777
29913
  article.goldenLinesPath,
29778
- article.goldenLinesSha256
29914
+ article.goldenLinesSha256,
29915
+ options.candidate?.sidecars.get(article.goldenLinesPath)
29779
29916
  );
29780
29917
  }
29781
29918
  }
@@ -29812,6 +29949,39 @@ async function validateStageArtifact(options) {
29812
29949
  }
29813
29950
  if (options.stage === "visual-plan") {
29814
29951
  const visual = visualPlanStageArtifactFrontmatterSchema.parse(frontmatter.value);
29952
+ if (!("coverAsset" in visual)) {
29953
+ if (options.checkpointStatus !== "awaiting-user") {
29954
+ throw new StageArtifactValidationError([
29955
+ "planned: \u751F\u6210\u8BA1\u5212\u53EA\u80FD\u7528\u4E8E\u7B49\u5F85\u56FE\u7247\u751F\u6210\u6388\u6743\uFF0C\u4E0D\u80FD\u4F5C\u4E3A\u5DF2\u5B8C\u6210\u89C6\u89C9\u4EA7\u7269"
29956
+ ]);
29957
+ }
29958
+ const semanticFrontmatter2 = { ...visual };
29959
+ delete semanticFrontmatter2["dxc"];
29960
+ const legacyConfirmationSnapshotHash2 = sha256(
29961
+ Buffer.from(
29962
+ JSON.stringify({ body: frontmatter.body, frontmatter: semanticFrontmatter2 }),
29963
+ "utf8"
29964
+ )
29965
+ );
29966
+ return {
29967
+ artifactPhase: "generation-proposal",
29968
+ authorizationPlan: {
29969
+ ...visual.generation,
29970
+ plannedAssets: visual.generation.plannedAssets.map((asset) => ({
29971
+ purpose: asset.purpose,
29972
+ role: asset.role,
29973
+ source: asset.source,
29974
+ ...asset.placementAnchor === void 0 ? {} : { placementAnchor: asset.placementAnchor }
29975
+ }))
29976
+ },
29977
+ confirmationSnapshotHash: bindConfirmationInputs(
29978
+ legacyConfirmationSnapshotHash2,
29979
+ options.inputs
29980
+ ),
29981
+ legacyConfirmationSnapshotHash: legacyConfirmationSnapshotHash2,
29982
+ snapshotType: "stage-artifact"
29983
+ };
29984
+ }
29815
29985
  if (visual.assetsDirectory !== options.manifest.assetsDirectory && !isInsideDirectory(visual.assetsDirectory, options.manifest.assetsDirectory)) {
29816
29986
  throw new StageArtifactValidationError(["assetsDirectory \u4E0D\u5728\u9879\u76EE\u7D20\u6750\u76EE\u5F55\u4E2D"]);
29817
29987
  }
@@ -29826,11 +29996,18 @@ async function validateStageArtifact(options) {
29826
29996
  options.directory,
29827
29997
  visual.coverAsset,
29828
29998
  visual.coverSha256,
29829
- MAXIMUM_COVER_BYTES
29999
+ MAXIMUM_COVER_BYTES,
30000
+ "cover"
29830
30001
  );
29831
30002
  await Promise.all(
29832
30003
  visual.inlineAssets.map(
29833
- (asset) => validateImageAsset(options.directory, asset.path, asset.sha256, MAXIMUM_INLINE_IMAGE_BYTES)
30004
+ (asset) => validateImageAsset(
30005
+ options.directory,
30006
+ asset.path,
30007
+ asset.sha256,
30008
+ MAXIMUM_INLINE_IMAGE_BYTES,
30009
+ "inline-image"
30010
+ )
29834
30011
  )
29835
30012
  );
29836
30013
  }
@@ -29842,29 +30019,40 @@ async function validateStageArtifact(options) {
29842
30019
  }
29843
30020
  if (options.stage === "titles") {
29844
30021
  const titles = titlesStageArtifactFrontmatterSchema.parse(frontmatter.value);
30022
+ const legacyConfirmationSnapshotHash2 = sha256(
30023
+ Buffer.from(
30024
+ JSON.stringify({
30025
+ articleSha256: titles.articleSha256,
30026
+ body: frontmatter.body,
30027
+ selectedTitle: titles.selectedTitle
30028
+ }),
30029
+ "utf8"
30030
+ )
30031
+ );
29845
30032
  return {
29846
- confirmationSnapshotHash: sha256(
29847
- Buffer.from(
29848
- JSON.stringify({
29849
- articleSha256: titles.articleSha256,
29850
- body: frontmatter.body,
29851
- selectedTitle: titles.selectedTitle
29852
- }),
29853
- "utf8"
29854
- )
30033
+ confirmationSnapshotHash: bindConfirmationInputs(
30034
+ legacyConfirmationSnapshotHash2,
30035
+ options.inputs
29855
30036
  ),
30037
+ legacyConfirmationSnapshotHash: legacyConfirmationSnapshotHash2,
29856
30038
  snapshotType: "stage-artifact"
29857
30039
  };
29858
30040
  }
29859
30041
  const semanticFrontmatter = { ...parsed.data };
29860
30042
  delete semanticFrontmatter["dxc"];
30043
+ const legacyConfirmationSnapshotHash = articleConfirmationSnapshotHash ?? sha256(
30044
+ Buffer.from(
30045
+ JSON.stringify({ body: frontmatter.body, frontmatter: semanticFrontmatter }),
30046
+ "utf8"
30047
+ )
30048
+ );
29861
30049
  return {
29862
- confirmationSnapshotHash: articleConfirmationSnapshotHash ?? sha256(
29863
- Buffer.from(
29864
- JSON.stringify({ body: frontmatter.body, frontmatter: semanticFrontmatter }),
29865
- "utf8"
29866
- )
30050
+ ...options.stage === "visual-plan" ? { artifactPhase: "materialized" } : {},
30051
+ confirmationSnapshotHash: bindConfirmationInputs(
30052
+ legacyConfirmationSnapshotHash,
30053
+ options.inputs
29867
30054
  ),
30055
+ legacyConfirmationSnapshotHash,
29868
30056
  snapshotType: "stage-artifact"
29869
30057
  };
29870
30058
  }
@@ -29879,6 +30067,17 @@ async function stageArtifactRequiresUserConfirmation(options) {
29879
30067
  const value = recordValue(parseFrontmatter2(source).value);
29880
30068
  return normalizedOrigin(value?.["origin"]) === "hotspot" && value?.["researchMode"] === "fact-only" && value?.["externalOpinionStatus"] === "user-skipped";
29881
30069
  }
30070
+ async function visualPlanArtifactPhase(options) {
30071
+ const source = (await readRegularFile(
30072
+ insideProject(options.directory, options.manifest.artifacts["visual-plan"]),
30073
+ MAXIMUM_ARTIFACT_BYTES
30074
+ )).toString("utf8");
30075
+ const parsed = visualPlanStageArtifactFrontmatterSchema.safeParse(parseFrontmatter2(source).value);
30076
+ if (!parsed.success) {
30077
+ throw new StageArtifactValidationError(issuePaths2(parsed.error.issues));
30078
+ }
30079
+ return "planned" in parsed.data && parsed.data.planned === true ? "generation-proposal" : "materialized";
30080
+ }
29882
30081
 
29883
30082
  // apps/cli/src/project.ts
29884
30083
  var MANIFEST_NAME = "dxc.project.json";
@@ -29908,12 +30107,14 @@ var DEFAULT_ARTIFACT_PATHS = {
29908
30107
  "visual-plan": "artifacts/06-visual-plan.md"
29909
30108
  };
29910
30109
  var ProjectCliError = class extends Error {
29911
- constructor(code, message) {
30110
+ constructor(code, message, details = {}) {
29912
30111
  super(message);
29913
30112
  this.code = code;
30113
+ this.details = details;
29914
30114
  this.name = "ProjectCliError";
29915
30115
  }
29916
30116
  code;
30117
+ details;
29917
30118
  };
29918
30119
  function migrateCheckpointInputKinds(required, optional, existing) {
29919
30120
  const allowedOptionalInputs = new Set(optional);
@@ -29938,7 +30139,7 @@ function errorCode(error) {
29938
30139
  }
29939
30140
  async function readJsonFile(target, maximumBytes, missingCode) {
29940
30141
  try {
29941
- const metadata = await lstat2(target);
30142
+ const metadata = await lstat3(target);
29942
30143
  if (!metadata.isFile() || metadata.isSymbolicLink() || metadata.size > maximumBytes) {
29943
30144
  throw new ProjectCliError("DXC_PROJECT_INVALID", "Project state file is invalid");
29944
30145
  }
@@ -30035,7 +30236,7 @@ async function inspectArtifact(directory, manifest, kind) {
30035
30236
  const relativePath = manifest.artifacts[kind];
30036
30237
  const target = insideProject2(directory, relativePath);
30037
30238
  try {
30038
- const metadata = await lstat2(target);
30239
+ const metadata = await lstat3(target);
30039
30240
  if (!metadata.isFile() || metadata.isSymbolicLink()) {
30040
30241
  throw new ProjectCliError("DXC_PROJECT_INVALID", "Project artifact is invalid");
30041
30242
  }
@@ -30119,16 +30320,26 @@ async function inspectCheckpoint(directory, manifest, stage, artifact, artifacts
30119
30320
  };
30120
30321
  }
30121
30322
  if (artifact.sha256 !== checkpoint.artifact.sha256 || artifact.bytes !== checkpoint.artifact.bytes) {
30122
- return {
30123
- checkpoint,
30124
- path: relativePath,
30125
- reason: "artifact-changed",
30126
- stage,
30127
- state: "stale"
30128
- };
30323
+ let authorizedMaterialization = false;
30324
+ if (checkpoint.checkpointVersion === "4" && checkpoint.stage === "visual-plan" && checkpoint.status === "running" && checkpoint.authorizations.length > 0) {
30325
+ try {
30326
+ authorizedMaterialization = await visualPlanArtifactPhase({ directory, manifest }) === "materialized";
30327
+ } catch {
30328
+ authorizedMaterialization = false;
30329
+ }
30330
+ }
30331
+ if (!authorizedMaterialization) {
30332
+ return {
30333
+ checkpoint,
30334
+ path: relativePath,
30335
+ reason: "artifact-changed",
30336
+ stage,
30337
+ state: "stale"
30338
+ };
30339
+ }
30129
30340
  }
30130
30341
  }
30131
- if (checkpoint.checkpointVersion === "2" || checkpoint.checkpointVersion === "3") {
30342
+ if (checkpoint.checkpointVersion === "2" || checkpoint.checkpointVersion === "3" || checkpoint.checkpointVersion === "4") {
30132
30343
  if (checkpoint.inputs.some((input) => input.path !== manifest.artifacts[input.kind]) || checkpoint.outputs.some((output) => output.path !== manifest.artifacts[output.kind])) {
30133
30344
  throw new ProjectCliError("DXC_PROJECT_INVALID", "Project checkpoint paths are invalid");
30134
30345
  }
@@ -30295,12 +30506,18 @@ var ProjectCli = class {
30295
30506
  });
30296
30507
  pendingCheckpoints.push({ checkpoint, stage });
30297
30508
  }
30298
- for (const { checkpoint, stage } of pendingCheckpoints) {
30299
- await writeJsonAtomically(
30300
- insideProject2(directory, checkpointRelativePath(manifest, stage)),
30301
- checkpoint
30302
- );
30509
+ const writtenTargets = [];
30510
+ try {
30511
+ for (const { checkpoint, stage } of pendingCheckpoints) {
30512
+ const target = insideProject2(directory, checkpointRelativePath(manifest, stage));
30513
+ await writeJsonAtomically(target, checkpoint);
30514
+ writtenTargets.push(target);
30515
+ }
30516
+ } catch (error) {
30517
+ await Promise.all(writtenTargets.map((target) => unlink2(target).catch(() => void 0)));
30518
+ throw error;
30303
30519
  }
30520
+ return writtenTargets;
30304
30521
  }
30305
30522
  async #rememberProject(directory, manifest, updatedAt) {
30306
30523
  const index = await loadProjectIndex(this.#projectIndexPath);
@@ -30329,7 +30546,7 @@ var ProjectCli = class {
30329
30546
  const directory = projectDirectory(this.#currentDirectory, this.#homeDirectory, directoryInput);
30330
30547
  const manifestTarget = path4.join(directory, MANIFEST_NAME);
30331
30548
  try {
30332
- await lstat2(manifestTarget);
30549
+ await lstat3(manifestTarget);
30333
30550
  throw new ProjectCliError("DXC_PROJECT_EXISTS", "A DxC project already exists");
30334
30551
  } catch (error) {
30335
30552
  if (error instanceof ProjectCliError) {
@@ -30409,9 +30626,18 @@ var ProjectCli = class {
30409
30626
  )
30410
30627
  );
30411
30628
  const summary = workflowSummary(checkpoints);
30629
+ const recoveryPlan = checkpoints.flatMap(
30630
+ (inspection) => inspection.state === "stale" ? [
30631
+ {
30632
+ action: "rerun-stage",
30633
+ reason: inspection.reason,
30634
+ stage: inspection.stage
30635
+ }
30636
+ ] : []
30637
+ );
30412
30638
  let assetsDirectoryReady = false;
30413
30639
  try {
30414
- const metadata = await lstat2(insideProject2(directory, manifest.assetsDirectory));
30640
+ const metadata = await lstat3(insideProject2(directory, manifest.assetsDirectory));
30415
30641
  assetsDirectoryReady = metadata.isDirectory() && !metadata.isSymbolicLink();
30416
30642
  } catch (error) {
30417
30643
  if (errorCode(error) !== "ENOENT") {
@@ -30428,6 +30654,7 @@ var ProjectCli = class {
30428
30654
  checkpointsDirectory: manifest.checkpointsDirectory,
30429
30655
  manifest,
30430
30656
  manifestPath: MANIFEST_NAME,
30657
+ recoveryPlan,
30431
30658
  ...summary
30432
30659
  },
30433
30660
  ok: true
@@ -30517,10 +30744,46 @@ var ProjectCli = class {
30517
30744
  const status = stepCheckpointStatusSchema.safeParse(options.status);
30518
30745
  const executionLocation = executionLocationSchema.safeParse(options.executionLocation);
30519
30746
  const dataTransit = dataTransitSchema.safeParse(options.dataTransit);
30520
- const summary = options.summary.trim();
30747
+ const summary = options.summary?.trim() ?? "";
30521
30748
  const requestedWaitingFor = options.waitingFor?.trim();
30522
30749
  if (!stage.success || !status.success || !executionLocation.success || !dataTransit.success || summary.length === 0) {
30523
- throw new ProjectCliError("DXC_PROJECT_STAGE_INVALID", "Checkpoint options are invalid");
30750
+ throw new ProjectCliError(
30751
+ "DXC_PROJECT_STAGE_INVALID",
30752
+ summary.length === 0 ? "\u9636\u6BB5\u68C0\u67E5\u70B9\u7F3A\u5C11\u6458\u8981\u3002" : "Checkpoint options are invalid",
30753
+ summary.length === 0 ? {
30754
+ fields: ["summary"],
30755
+ reason: "SUMMARY_REQUIRED",
30756
+ recovery: "\u8865\u5145 --summary <\u672C\u6B21\u9636\u6BB5\u72B6\u6001\u7684\u7B80\u77ED\u8BF4\u660E> \u540E\u91CD\u8BD5\uFF1BCLI \u4E0D\u4F1A\u5728\u7F3A\u5C11\u6458\u8981\u65F6\u4FEE\u6539\u4EFB\u4F55\u4EA7\u7269\u3002",
30757
+ ...stage.success ? { stage: stage.data } : {}
30758
+ } : { reason: "CHECKPOINT_OPTIONS_INVALID" }
30759
+ );
30760
+ }
30761
+ if (options.confirmationSnapshotHash !== void 0 && stage.data !== "delivery") {
30762
+ throw new ProjectCliError(
30763
+ "DXC_PROJECT_STAGE_INVALID",
30764
+ "--confirmation-snapshot \u4EC5\u7528\u4E8E delivery \u7684\u4E91\u7AEF\u6E32\u67D3\u5FEB\u7167\uFF1B\u5185\u5BB9\u9636\u6BB5\u7531 CLI \u81EA\u52A8\u8BA1\u7B97\u8BED\u4E49\u5FEB\u7167\u3002",
30765
+ {
30766
+ fields: ["confirmationSnapshot"],
30767
+ reason: "CONFIRMATION_SNAPSHOT_FLAG_NOT_ALLOWED",
30768
+ recovery: "\u79FB\u9664\u8BE5\u53C2\u6570\uFF1B\u82E5\u6B63\u6587\u6216\u6807\u9898\u5728\u5C55\u793A\u540E\u53D1\u751F\u53D8\u5316\uFF0C\u5148\u91CD\u65B0\u5199 awaiting-user \u68C0\u67E5\u70B9\u5E76\u518D\u6B21\u5C55\u793A\uFF0C\u518D\u4F7F\u7528 --confirm\u3002",
30769
+ stage: stage.data
30770
+ }
30771
+ );
30772
+ }
30773
+ const authorizationPurpose = options.authorizationPurpose?.trim();
30774
+ const requestingExternalAuthorization = authorizationPurpose === "image-generation" && stage.data === "visual-plan" && status.data === "awaiting-user" && options.confirmed !== true;
30775
+ const confirmingExternalAuthorization = authorizationPurpose === "image-generation" && stage.data === "visual-plan" && status.data === "running" && options.confirmed === true;
30776
+ if (authorizationPurpose !== void 0 && !requestingExternalAuthorization && !confirmingExternalAuthorization) {
30777
+ throw new ProjectCliError(
30778
+ "DXC_PROJECT_STAGE_INVALID",
30779
+ "\u56FE\u7247\u751F\u6210\u6388\u6743\u4EC5\u652F\u6301 visual-plan\uFF1A\u5148\u4EE5 awaiting-user \u8BF7\u6C42\uFF0C\u518D\u4EE5 running --confirm \u786E\u8BA4\u540E\u56DE\u5230\u540C\u4E00\u9636\u6BB5\u3002",
30780
+ {
30781
+ fields: ["authorizationPurpose"],
30782
+ reason: "EXTERNAL_AUTHORIZATION_OPTIONS_INVALID",
30783
+ recovery: "\u8BF7\u6C42\u6388\u6743\u65F6\u4F7F\u7528 --status awaiting-user --authorization-purpose image-generation\uFF1B\u7528\u6237\u786E\u8BA4\u540E\u4F7F\u7528 --status running --confirm \u548C\u76F8\u540C purpose\u3002",
30784
+ stage: stage.data
30785
+ }
30786
+ );
30524
30787
  }
30525
30788
  const expectedSkill = CONTENT_STAGE_SKILLS[stage.data];
30526
30789
  const effectiveSkill = options.skill ?? expectedSkill.name;
@@ -30556,12 +30819,12 @@ var ProjectCli = class {
30556
30819
  status: await inspectArtifact(directory, manifest, inputStage)
30557
30820
  }))
30558
30821
  )).filter((input) => input.status.status === "ready").map((input) => input.inputStage) : [];
30559
- const migratedExistingInputs = existing?.checkpointVersion === "2" || existing?.checkpointVersion === "3" ? migrateCheckpointInputKinds(
30822
+ const migratedExistingInputs = existing?.checkpointVersion === "2" || existing?.checkpointVersion === "3" || existing?.checkpointVersion === "4" ? migrateCheckpointInputKinds(
30560
30823
  stageInputs.required,
30561
30824
  stageInputs.optional,
30562
30825
  existing.inputs.map((input) => input.kind)
30563
30826
  ) : [];
30564
- const inputStageValues = options.inputStages !== void 0 ? [...stageInputs.required, ...options.inputStages] : existing?.checkpointVersion === "2" || existing?.checkpointVersion === "3" ? migratedExistingInputs : [...stageInputs.required, ...inferredOptionalInputs];
30827
+ const inputStageValues = options.inputStages !== void 0 ? [...stageInputs.required, ...options.inputStages] : existing?.checkpointVersion === "2" || existing?.checkpointVersion === "3" || existing?.checkpointVersion === "4" ? migratedExistingInputs : [...stageInputs.required, ...inferredOptionalInputs];
30565
30828
  const inputStages = inputStageValues.map(
30566
30829
  (inputStage) => contentArtifactKindSchema.safeParse(inputStage)
30567
30830
  );
@@ -30619,7 +30882,7 @@ var ProjectCli = class {
30619
30882
  );
30620
30883
  }
30621
30884
  const inputs = inputArtifactStatuses.map(artifactReference);
30622
- const requestedNeedsArtifact = status.data === "awaiting-user" || status.data === "completed";
30885
+ const requestedNeedsArtifact = status.data === "awaiting-user" || status.data === "completed" || confirmingExternalAuthorization;
30623
30886
  const artifactStatusBeforeNormalization = await inspectArtifact(
30624
30887
  directory,
30625
30888
  manifest,
@@ -30635,7 +30898,12 @@ var ProjectCli = class {
30635
30898
  });
30636
30899
  } catch (error) {
30637
30900
  if (error instanceof StageArtifactValidationError) {
30638
- throw new ProjectCliError("DXC_PROJECT_STAGE_INVALID", error.message);
30901
+ throw new ProjectCliError("DXC_PROJECT_STAGE_INVALID", error.message, {
30902
+ fields: error.issues.slice(0, 20).map((issue) => issue.slice(0, 200)),
30903
+ reason: "STAGE_ARTIFACT_INVALID",
30904
+ recovery: "\u6309 fields \u4E2D\u7684\u9996\u4E2A\u95EE\u9898\u4FEE\u6B63\u9636\u6BB5\u4EA7\u7269\u540E\u91CD\u8BD5\uFF1B\u5176\u4ED6\u95EE\u9898\u4F5C\u4E3A\u8865\u5145\u8BE6\u60C5\uFF0C\u4E0D\u4F1A\u906E\u4F4F\u4E3B\u539F\u56E0\u3002",
30905
+ stage: stage.data
30906
+ });
30639
30907
  }
30640
30908
  throw error;
30641
30909
  }
@@ -30656,11 +30924,12 @@ var ProjectCli = class {
30656
30924
  "Awaiting checkpoint needs one waiting-for prompt"
30657
30925
  );
30658
30926
  }
30659
- const needsArtifact = effectiveStatus === "awaiting-user" || effectiveStatus === "completed";
30927
+ const needsArtifact = effectiveStatus === "awaiting-user" || effectiveStatus === "completed" || confirmingExternalAuthorization;
30928
+ let artifactNormalization;
30660
30929
  if (needsArtifact) {
30661
30930
  try {
30662
- await normalizeStageArtifact({
30663
- artifactStatus: effectiveStatus === "completed" ? "complete" : "awaiting-user",
30931
+ artifactNormalization = await normalizeStageArtifact({
30932
+ artifactStatus: effectiveStatus === "completed" && !confirmingExternalAuthorization ? "complete" : "awaiting-user",
30664
30933
  createdAt: timestamp,
30665
30934
  directory,
30666
30935
  inputs,
@@ -30671,138 +30940,251 @@ var ProjectCli = class {
30671
30940
  });
30672
30941
  } catch (error) {
30673
30942
  if (error instanceof StageArtifactValidationError) {
30674
- throw new ProjectCliError("DXC_PROJECT_STAGE_INVALID", error.message);
30943
+ throw new ProjectCliError("DXC_PROJECT_STAGE_INVALID", error.message, {
30944
+ fields: error.issues.slice(0, 20).map((issue) => issue.slice(0, 200)),
30945
+ reason: "STAGE_ARTIFACT_INVALID",
30946
+ recovery: "\u6309 fields \u4E2D\u7684\u9996\u4E2A\u95EE\u9898\u4FEE\u6B63\u9636\u6BB5\u4EA7\u7269\u540E\u91CD\u8BD5\uFF1B\u6821\u9A8C\u5931\u8D25\u4E0D\u4F1A\u4FDD\u7559 CLI \u89C4\u8303\u5316\u6539\u5199\u3002",
30947
+ stage: stage.data
30948
+ });
30675
30949
  }
30676
30950
  throw error;
30677
30951
  }
30678
30952
  }
30679
- const artifactStatus = await inspectArtifact(directory, manifest, stage.data);
30680
- if (needsArtifact && artifactStatus.status !== "ready") {
30681
- throw new ProjectCliError(
30682
- "DXC_PROJECT_STAGE_INVALID",
30683
- "Checkpoint artifact must exist and be non-empty"
30684
- );
30685
- }
30686
- let artifactValidation;
30687
- if (needsArtifact) {
30953
+ {
30954
+ const artifactStatus = artifactNormalization === void 0 ? await inspectArtifact(directory, manifest, stage.data) : {
30955
+ ...artifactNormalization.artifact,
30956
+ kind: stage.data,
30957
+ status: "ready"
30958
+ };
30959
+ if (needsArtifact && artifactStatus.status !== "ready") {
30960
+ throw new ProjectCliError(
30961
+ "DXC_PROJECT_STAGE_INVALID",
30962
+ "Checkpoint artifact must exist and be non-empty"
30963
+ );
30964
+ }
30965
+ let artifactValidation;
30966
+ if (needsArtifact) {
30967
+ try {
30968
+ artifactValidation = await validateStageArtifact({
30969
+ ...artifactNormalization === void 0 ? {} : { candidate: artifactNormalization.candidate },
30970
+ checkpointStatus: confirmingExternalAuthorization ? "awaiting-user" : effectiveStatus,
30971
+ directory,
30972
+ inputs,
30973
+ manifest,
30974
+ skill: effectiveSkill,
30975
+ skillVersion: effectiveSkillVersion,
30976
+ stage: stage.data
30977
+ });
30978
+ } catch (error) {
30979
+ if (error instanceof StageArtifactValidationError) {
30980
+ throw new ProjectCliError("DXC_PROJECT_STAGE_INVALID", error.message, {
30981
+ fields: error.issues.slice(0, 20).map((issue) => issue.slice(0, 200)),
30982
+ reason: "STAGE_ARTIFACT_INVALID",
30983
+ recovery: "\u6309 fields \u4E2D\u7684\u9996\u4E2A\u95EE\u9898\u4FEE\u6B63\u9636\u6BB5\u4EA7\u7269\u540E\u91CD\u8BD5\uFF1B\u9700\u8981\u786E\u8BA4\u65F6\u5148\u91CD\u65B0\u5C55\u793A\u5F53\u524D\u8BED\u4E49\u5FEB\u7167\u3002",
30984
+ stage: stage.data
30985
+ });
30986
+ }
30987
+ throw error;
30988
+ }
30989
+ }
30990
+ if (artifactValidation?.artifactPhase === "generation-proposal" && !requestingExternalAuthorization && !confirmingExternalAuthorization) {
30991
+ throw new ProjectCliError(
30992
+ "DXC_PROJECT_STAGE_INVALID",
30993
+ "\u89C6\u89C9\u4EA7\u7269\u4ECD\u662F\u56FE\u7247\u751F\u6210\u8BA1\u5212\uFF0C\u5FC5\u987B\u5148\u5B8C\u6210\u751F\u6210\u524D\u6388\u6743\uFF0C\u4E0D\u80FD\u76F4\u63A5\u5B8C\u6210\u9636\u6BB5\u3002",
30994
+ {
30995
+ reason: "VISUAL_GENERATION_AUTHORIZATION_REQUIRED",
30996
+ recovery: "\u5148\u4EE5 awaiting-user --authorization-purpose image-generation \u4FDD\u5B58\u8BA1\u5212\uFF1B\u7528\u6237\u786E\u8BA4\u540E\u4EE5 running --confirm \u8FD4\u56DE\u540C\u4E00 visual-plan \u9636\u6BB5\u3002",
30997
+ stage: "visual-plan"
30998
+ }
30999
+ );
31000
+ }
31001
+ const output = artifactReference(artifactStatus);
31002
+ const confirmationSnapshotHash = options.confirmationSnapshotHash?.trim() ?? artifactValidation?.confirmationSnapshotHash;
31003
+ if (needsArtifact && (confirmationSnapshotHash === void 0 || !/^[a-f0-9]{64}$/u.test(confirmationSnapshotHash))) {
31004
+ throw new ProjectCliError(
31005
+ "DXC_PROJECT_STAGE_INVALID",
31006
+ "Confirmation snapshot hash is invalid"
31007
+ );
31008
+ }
31009
+ if (options.confirmationSnapshotHash !== void 0 && artifactValidation !== void 0 && options.confirmationSnapshotHash.trim() !== artifactValidation.confirmationSnapshotHash) {
31010
+ throw new ProjectCliError(
31011
+ "DXC_PROJECT_STAGE_INVALID",
31012
+ "\u786E\u8BA4\u5FEB\u7167\u4E0E\u5F53\u524D\u9636\u6BB5\u7ECF\u8FC7\u6821\u9A8C\u7684\u5185\u5BB9\u6216\u6E32\u67D3\u5FEB\u7167\u4E0D\u4E00\u81F4\u3002"
31013
+ );
31014
+ }
31015
+ const confirmationRelevant = effectiveStatus === "awaiting-user" || effectiveStatus === "completed" && requiresUserConfirmation && options.confirmed;
31016
+ const previousBinding = existing?.checkpointVersion === "3" || existing?.checkpointVersion === "4" ? existing.confirmationBinding : null;
31017
+ const confirmationSnapshotType = artifactValidation?.snapshotType ?? "stage-artifact";
31018
+ const previousInputsMatch = (existing?.checkpointVersion === "2" || existing?.checkpointVersion === "3" || existing?.checkpointVersion === "4") && existing.inputs.length === inputs.length && existing.inputs.every((input, index) => {
31019
+ const current = inputs[index];
31020
+ return current !== void 0 && input.kind === current.kind && input.path === current.path && input.sha256 === current.sha256 && input.bytes === current.bytes;
31021
+ });
31022
+ const legacyPendingSnapshotMatches = options.confirmed && previousInputsMatch && previousBinding?.snapshotType === "stage-artifact" && artifactStatusBeforeNormalization.status === "ready" && previousBinding.snapshotHash === artifactStatusBeforeNormalization.sha256;
31023
+ const legacySemanticSnapshotMatches = options.confirmed && previousInputsMatch && previousBinding?.snapshotType === "stage-artifact" && artifactValidation?.legacyConfirmationSnapshotHash !== void 0 && previousBinding.snapshotHash === artifactValidation.legacyConfirmationSnapshotHash;
31024
+ const previousSnapshotMatches = previousBinding?.snapshotHash === confirmationSnapshotHash || legacySemanticSnapshotMatches || legacyPendingSnapshotMatches;
31025
+ const completingConfirmedStage = effectiveStatus === "completed" && requiresUserConfirmation && options.confirmed;
31026
+ if ((completingConfirmedStage || confirmingExternalAuthorization) && (existing?.status !== "awaiting-user" || existing.confirmation !== "pending" || previousBinding?.status !== "pending" || !previousSnapshotMatches || previousBinding.snapshotType !== confirmationSnapshotType || confirmingExternalAuthorization && (existing.checkpointVersion !== "4" || existing.confirmationPurpose !== "external-action"))) {
31027
+ throw new ProjectCliError(
31028
+ "DXC_PROJECT_STAGE_INVALID",
31029
+ confirmingExternalAuthorization ? "\u5F53\u524D\u56FE\u7247\u751F\u6210\u8BA1\u5212\u4E0D\u662F\u521A\u624D\u7B49\u5F85\u6388\u6743\u7684\u7248\u672C\uFF1B\u8BF7\u91CD\u65B0\u5C55\u793A\u5F53\u524D\u8BA1\u5212\u5E76\u8BF7\u6C42\u6388\u6743\u3002" : "\u5F53\u524D\u5185\u5BB9\u6216\u6E32\u67D3\u5FEB\u7167\u4E0D\u662F\u521A\u624D\u7B49\u5F85\u786E\u8BA4\u7684\u7248\u672C\uFF1B\u8BF7\u5148\u91CD\u65B0\u5C55\u793A\u5E76\u5199\u5165 awaiting-user \u68C0\u67E5\u70B9\uFF0C\u518D\u6839\u636E\u7528\u6237\u660E\u786E\u56DE\u7B54\u786E\u8BA4\u3002",
31030
+ {
31031
+ reason: confirmingExternalAuthorization ? "EXTERNAL_AUTHORIZATION_STALE" : "CONFIRMATION_STALE",
31032
+ recovery: confirmingExternalAuthorization ? "\u7528\u5F53\u524D\u5F20\u6570\u3001\u7528\u9014\u3001\u6570\u636E\u53BB\u5411\u548C\u5C1D\u8BD5\u4E0A\u9650\u91CD\u5199\u751F\u6210\u8BA1\u5212\uFF0C\u5199 awaiting-user \u540E\u91CD\u65B0\u53D6\u5F97\u7528\u6237\u6388\u6743\u3002" : "\u91CD\u65B0\u751F\u6210\u6216\u89C4\u8303\u5316\u5F53\u524D\u4EA7\u7269\uFF0C\u5199 awaiting-user \u68C0\u67E5\u70B9\uFF0C\u5411\u7528\u6237\u5C55\u793A\u8BE5\u8BED\u4E49\u5FEB\u7167\u540E\u518D\u786E\u8BA4\u3002",
31033
+ stage: stage.data
31034
+ }
31035
+ );
31036
+ }
31037
+ const requestedAt = previousBinding !== null && previousSnapshotMatches && previousBinding.snapshotType === confirmationSnapshotType ? previousBinding.requestedAt : timestamp;
31038
+ const confirmedBy = options.confirmedBy?.trim() || "local-interactive-user";
31039
+ const authorizationPlan = artifactValidation?.authorizationPlan;
31040
+ if ((requestingExternalAuthorization || confirmingExternalAuthorization) && authorizationPlan === void 0) {
31041
+ throw new ProjectCliError(
31042
+ "DXC_PROJECT_STAGE_INVALID",
31043
+ "\u56FE\u7247\u751F\u6210\u6388\u6743\u5FC5\u987B\u7ED1\u5B9A planned=true \u7684\u5B8C\u6574\u751F\u6210\u8BA1\u5212\u3002",
31044
+ {
31045
+ reason: "VISUAL_GENERATION_PLAN_REQUIRED",
31046
+ recovery: "\u8865\u9F50 generation.executionLocation\u3001dataTransit\u3001chargesQuota\u3001maxAttempts \u548C plannedAssets \u540E\u91CD\u65B0\u8BF7\u6C42\u6388\u6743\u3002",
31047
+ stage: "visual-plan"
31048
+ }
31049
+ );
31050
+ }
31051
+ if (authorizationPlan !== void 0 && (authorizationPlan.dataTransit !== dataTransit.data || authorizationPlan.executionLocation !== executionLocation.data || confirmingExternalAuthorization && (existing?.execution.dataTransit !== dataTransit.data || existing.execution.location !== executionLocation.data))) {
31052
+ throw new ProjectCliError(
31053
+ "DXC_PROJECT_STAGE_INVALID",
31054
+ "\u56FE\u7247\u751F\u6210\u8BA1\u5212\u3001\u7B49\u5F85\u6388\u6743\u68C0\u67E5\u70B9\u548C\u672C\u6B21\u6267\u884C\u58F0\u660E\u7684\u6570\u636E\u53BB\u5411\u6216\u6267\u884C\u4F4D\u7F6E\u4E0D\u4E00\u81F4\u3002",
31055
+ {
31056
+ fields: ["generation.dataTransit", "generation.executionLocation", "execution"],
31057
+ reason: "EXTERNAL_AUTHORIZATION_EXECUTION_MISMATCH",
31058
+ recovery: "\u4FDD\u6301\u8BF7\u6C42\u6388\u6743\u4E0E\u786E\u8BA4\u547D\u4EE4\u7684 --data-transit\u3001--execution-location \u5B8C\u5168\u4E00\u81F4\uFF1B\u82E5\u6267\u884C\u73AF\u5883\u53D8\u5316\uFF0C\u91CD\u5199\u8BA1\u5212\u5E76\u91CD\u65B0\u53D6\u5F97\u6388\u6743\u3002",
31059
+ stage: "visual-plan"
31060
+ }
31061
+ );
31062
+ }
31063
+ const useCheckpointV4 = authorizationPurpose !== void 0 || existing?.checkpointVersion === "4";
31064
+ const existingAuthorizations = existing?.checkpointVersion === "4" ? existing.authorizations : [];
31065
+ const authorizations = confirmingExternalAuthorization ? [
31066
+ ...existingAuthorizations,
31067
+ {
31068
+ action: "image-generation",
31069
+ confirmedAt: timestamp,
31070
+ confirmedBy,
31071
+ plan: authorizationPlan,
31072
+ planSnapshotHash: confirmationSnapshotHash,
31073
+ requestedAt
31074
+ }
31075
+ ] : existingAuthorizations;
31076
+ const checkpointResult = stepCheckpointSchema.safeParse({
31077
+ ...(effectiveStatus === "awaiting-user" || effectiveStatus === "completed") && artifactStatus.status === "ready" ? {
31078
+ artifact: {
31079
+ bytes: artifactStatus.bytes,
31080
+ kind: stage.data,
31081
+ path: artifactStatus.path,
31082
+ sha256: artifactStatus.sha256
31083
+ }
31084
+ } : confirmingExternalAuthorization && artifactStatus.status === "ready" ? {
31085
+ artifact: {
31086
+ bytes: artifactStatus.bytes,
31087
+ kind: stage.data,
31088
+ path: artifactStatus.path,
31089
+ sha256: artifactStatus.sha256
31090
+ }
31091
+ } : {},
31092
+ ...useCheckpointV4 ? {
31093
+ authorizations,
31094
+ checkpointVersion: "4",
31095
+ confirmationPurpose: confirmationRelevant ? requestingExternalAuthorization ? "external-action" : "stage-completion" : null
31096
+ } : { checkpointVersion: "3" },
31097
+ ...TERMINAL_CHECKPOINT_STATUSES.has(effectiveStatus) ? { completedAt: timestamp } : {},
31098
+ confirmation: effectiveStatus === "awaiting-user" ? "pending" : effectiveStatus === "completed" && requiresUserConfirmation && options.confirmed ? "confirmed" : "not-required",
31099
+ confirmationBinding: confirmationRelevant && confirmationSnapshotHash !== void 0 ? {
31100
+ confirmedAt: effectiveStatus === "completed" ? timestamp : null,
31101
+ confirmedBy: effectiveStatus === "completed" ? confirmedBy : null,
31102
+ requestedAt,
31103
+ snapshotHash: confirmationSnapshotHash,
31104
+ snapshotType: confirmationSnapshotType,
31105
+ status: effectiveStatus === "completed" ? "confirmed" : "pending"
31106
+ } : null,
31107
+ ...effectiveStatus === "failed" ? { errorCode: options.errorCode } : {},
31108
+ execution: {
31109
+ dataTransit: dataTransit.data,
31110
+ location: executionLocation.data
31111
+ },
31112
+ inputs,
31113
+ metadata: {
31114
+ summary
31115
+ },
31116
+ outputs: [output],
31117
+ projectId: manifest.projectId,
31118
+ revision: (existing?.revision ?? 0) + 1,
31119
+ skill: {
31120
+ name: effectiveSkill,
31121
+ version: effectiveSkillVersion
31122
+ },
31123
+ stage: stage.data,
31124
+ startedAt: status.data === "running" && existing !== void 0 && TERMINAL_CHECKPOINT_STATUSES.has(existing.status) ? timestamp : existing?.startedAt ?? timestamp,
31125
+ status: effectiveStatus,
31126
+ updatedAt: timestamp,
31127
+ waitingFor: waitingFor ?? null,
31128
+ workflowId: manifest.workflowId
31129
+ });
31130
+ if (!checkpointResult.success) {
31131
+ throw new ProjectCliError("DXC_PROJECT_STAGE_INVALID", "Checkpoint options are invalid");
31132
+ }
31133
+ const checkpoint = checkpointResult.data;
31134
+ const relativePath = checkpointRelativePath(manifest, stage.data);
30688
31135
  try {
30689
- artifactValidation = await validateStageArtifact({
30690
- checkpointStatus: effectiveStatus,
30691
- directory,
30692
- inputs,
30693
- manifest,
30694
- skill: effectiveSkill,
30695
- skillVersion: effectiveSkillVersion,
30696
- stage: stage.data
30697
- });
31136
+ await artifactNormalization?.commit();
30698
31137
  } catch (error) {
30699
31138
  if (error instanceof StageArtifactValidationError) {
30700
- throw new ProjectCliError("DXC_PROJECT_STAGE_INVALID", error.message);
31139
+ throw new ProjectCliError("DXC_PROJECT_STAGE_INVALID", error.message, {
31140
+ fields: error.issues.slice(0, 20).map((issue) => issue.slice(0, 200)),
31141
+ reason: error.issues.some((issue) => issue.startsWith("NORMALIZATION_CONFLICT:")) ? "NORMALIZATION_CONFLICT" : "STAGE_ARTIFACT_INVALID",
31142
+ recovery: "\u91CD\u65B0\u8BFB\u53D6\u5F53\u524D\u9636\u6BB5\u4EA7\u7269\u53CA sidecar \u540E\u91CD\u8BD5\uFF1BCLI \u68C0\u6D4B\u5230\u5E76\u53D1\u6539\u52A8\u65F6\u4E0D\u4F1A\u8986\u76D6\u8F83\u65B0\u7684\u6587\u4EF6\u3002",
31143
+ stage: stage.data
31144
+ });
30701
31145
  }
30702
31146
  throw error;
30703
31147
  }
30704
- }
30705
- const output = artifactReference(artifactStatus);
30706
- const confirmationSnapshotHash = options.confirmationSnapshotHash?.trim() ?? artifactValidation?.confirmationSnapshotHash;
30707
- if (needsArtifact && (confirmationSnapshotHash === void 0 || !/^[a-f0-9]{64}$/u.test(confirmationSnapshotHash))) {
30708
- throw new ProjectCliError(
30709
- "DXC_PROJECT_STAGE_INVALID",
30710
- "Confirmation snapshot hash is invalid"
30711
- );
30712
- }
30713
- if (options.confirmationSnapshotHash !== void 0 && artifactValidation !== void 0 && options.confirmationSnapshotHash.trim() !== artifactValidation.confirmationSnapshotHash) {
30714
- throw new ProjectCliError(
30715
- "DXC_PROJECT_STAGE_INVALID",
30716
- "\u786E\u8BA4\u5FEB\u7167\u4E0E\u5F53\u524D\u9636\u6BB5\u7ECF\u8FC7\u6821\u9A8C\u7684\u5185\u5BB9\u6216\u6E32\u67D3\u5FEB\u7167\u4E0D\u4E00\u81F4\u3002"
30717
- );
30718
- }
30719
- const confirmationRelevant = effectiveStatus === "awaiting-user" || effectiveStatus === "completed" && requiresUserConfirmation && options.confirmed;
30720
- const previousBinding = existing?.checkpointVersion === "3" ? existing.confirmationBinding : null;
30721
- const confirmationSnapshotType = artifactValidation?.snapshotType ?? "stage-artifact";
30722
- const legacyPendingSnapshotMatches = options.confirmed && previousBinding?.snapshotType === "stage-artifact" && artifactStatusBeforeNormalization.status === "ready" && previousBinding.snapshotHash === artifactStatusBeforeNormalization.sha256;
30723
- const previousSnapshotMatches = previousBinding?.snapshotHash === confirmationSnapshotHash || legacyPendingSnapshotMatches;
30724
- if (effectiveStatus === "completed" && requiresUserConfirmation && options.confirmed && (existing?.status !== "awaiting-user" || existing.confirmation !== "pending" || previousBinding?.status !== "pending" || !previousSnapshotMatches || previousBinding.snapshotType !== confirmationSnapshotType)) {
30725
- throw new ProjectCliError(
30726
- "DXC_PROJECT_STAGE_INVALID",
30727
- "\u5F53\u524D\u5185\u5BB9\u6216\u6E32\u67D3\u5FEB\u7167\u4E0D\u662F\u521A\u624D\u7B49\u5F85\u786E\u8BA4\u7684\u7248\u672C\uFF1B\u8BF7\u5148\u91CD\u65B0\u5C55\u793A\u5E76\u5199\u5165 awaiting-user \u68C0\u67E5\u70B9\uFF0C\u518D\u6839\u636E\u7528\u6237\u660E\u786E\u56DE\u7B54\u786E\u8BA4\u3002"
30728
- );
30729
- }
30730
- const requestedAt = previousBinding !== null && previousSnapshotMatches && previousBinding.snapshotType === confirmationSnapshotType ? previousBinding.requestedAt : timestamp;
30731
- const confirmedBy = options.confirmedBy?.trim() || "local-interactive-user";
30732
- const checkpointResult = stepCheckpointSchema.safeParse({
30733
- ...needsArtifact && artifactStatus.status === "ready" ? {
30734
- artifact: {
30735
- bytes: artifactStatus.bytes,
30736
- kind: stage.data,
30737
- path: artifactStatus.path,
30738
- sha256: artifactStatus.sha256
30739
- }
30740
- } : {},
30741
- checkpointVersion: "3",
30742
- ...TERMINAL_CHECKPOINT_STATUSES.has(effectiveStatus) ? { completedAt: timestamp } : {},
30743
- confirmation: effectiveStatus === "awaiting-user" ? "pending" : effectiveStatus === "completed" && requiresUserConfirmation && options.confirmed ? "confirmed" : "not-required",
30744
- confirmationBinding: confirmationRelevant && confirmationSnapshotHash !== void 0 ? {
30745
- confirmedAt: effectiveStatus === "completed" ? timestamp : null,
30746
- confirmedBy: effectiveStatus === "completed" ? confirmedBy : null,
30747
- requestedAt,
30748
- snapshotHash: confirmationSnapshotHash,
30749
- snapshotType: confirmationSnapshotType,
30750
- status: effectiveStatus === "completed" ? "confirmed" : "pending"
30751
- } : null,
30752
- ...effectiveStatus === "failed" ? { errorCode: options.errorCode } : {},
30753
- execution: {
30754
- dataTransit: dataTransit.data,
30755
- location: executionLocation.data
30756
- },
30757
- inputs,
30758
- metadata: {
30759
- summary
30760
- },
30761
- outputs: [output],
30762
- projectId: manifest.projectId,
30763
- revision: (existing?.revision ?? 0) + 1,
30764
- skill: {
30765
- name: effectiveSkill,
30766
- version: effectiveSkillVersion
30767
- },
30768
- stage: stage.data,
30769
- startedAt: status.data === "running" && existing !== void 0 && TERMINAL_CHECKPOINT_STATUSES.has(existing.status) ? timestamp : existing?.startedAt ?? timestamp,
30770
- status: effectiveStatus,
30771
- updatedAt: timestamp,
30772
- waitingFor: waitingFor ?? null,
30773
- workflowId: manifest.workflowId
30774
- });
30775
- if (!checkpointResult.success) {
30776
- throw new ProjectCliError("DXC_PROJECT_STAGE_INVALID", "Checkpoint options are invalid");
30777
- }
30778
- const checkpoint = checkpointResult.data;
30779
- const relativePath = checkpointRelativePath(manifest, stage.data);
30780
- if (adoptsExistingArticle) {
30781
- await this.#skipArticleAdoptionPrerequisites(directory, manifest, timestamp, {
30782
- dataTransit: dataTransit.data,
30783
- location: executionLocation.data
31148
+ let adoptionTargets = [];
31149
+ try {
31150
+ if (adoptsExistingArticle) {
31151
+ adoptionTargets = await this.#skipArticleAdoptionPrerequisites(
31152
+ directory,
31153
+ manifest,
31154
+ timestamp,
31155
+ {
31156
+ dataTransit: dataTransit.data,
31157
+ location: executionLocation.data
31158
+ }
31159
+ );
31160
+ }
31161
+ await writeJsonAtomically(insideProject2(directory, relativePath), checkpoint);
31162
+ } catch (error) {
31163
+ await Promise.all(adoptionTargets.map((target) => unlink2(target).catch(() => void 0)));
31164
+ await artifactNormalization?.rollbackCommitted();
31165
+ throw error;
31166
+ }
31167
+ await this.#rememberProject(directory, manifest, timestamp).catch(() => void 0);
31168
+ return contentProjectCheckpointResultSchema.parse({
31169
+ command: "project.checkpoint",
31170
+ data: {
31171
+ artifactMutations: artifactNormalization?.mutations ?? [],
31172
+ checkpoint,
31173
+ checkpointPath: relativePath,
31174
+ guidance: effectiveStatus === "awaiting-user" ? {
31175
+ action: requestingExternalAuthorization ? "authorize-external-action" : "confirm-stage",
31176
+ message: waitingFor ?? "\u8BF7\u786E\u8BA4\u5F53\u524D\u9636\u6BB5\u5FEB\u7167\u3002",
31177
+ suggestedFlag: "--confirm"
31178
+ } : null
31179
+ },
31180
+ ok: true
30784
31181
  });
30785
31182
  }
30786
- await this.#rememberProject(directory, manifest, timestamp);
30787
- await writeJsonAtomically(insideProject2(directory, relativePath), checkpoint);
30788
- return contentProjectCheckpointResultSchema.parse({
30789
- command: "project.checkpoint",
30790
- data: {
30791
- checkpoint,
30792
- checkpointPath: relativePath,
30793
- guidance: confirmationRequired ? {
30794
- action: "confirm-stage",
30795
- message: waitingFor ?? "\u8BF7\u786E\u8BA4\u5F53\u524D\u9636\u6BB5\u5FEB\u7167\u3002",
30796
- suggestedFlag: "--confirm"
30797
- } : null
30798
- },
30799
- ok: true
30800
- });
30801
31183
  }
30802
31184
  };
30803
31185
 
30804
31186
  // apps/cli/src/skills.ts
30805
- import { cp, lstat as lstat3, mkdir as mkdir2, mkdtemp, readdir, rename as rename4, rm } from "node:fs/promises";
31187
+ import { cp, lstat as lstat4, mkdir as mkdir2, mkdtemp, readdir, rename as rename4, rm } from "node:fs/promises";
30806
31188
  import os from "node:os";
30807
31189
  import path5 from "node:path";
30808
31190
  import { fileURLToPath } from "node:url";
@@ -30831,7 +31213,7 @@ var SkillInstallerError = class extends Error {
30831
31213
  };
30832
31214
  async function isDirectory(directory) {
30833
31215
  try {
30834
- return (await lstat3(directory)).isDirectory();
31216
+ return (await lstat4(directory)).isDirectory();
30835
31217
  } catch {
30836
31218
  return false;
30837
31219
  }
@@ -30855,7 +31237,7 @@ async function findBundledSkills() {
30855
31237
  async function assertRegularSkillTree(directory) {
30856
31238
  for (const entry of await readdir(directory, { withFileTypes: true })) {
30857
31239
  const entryPath = path5.join(directory, entry.name);
30858
- const entryStat = await lstat3(entryPath);
31240
+ const entryStat = await lstat4(entryPath);
30859
31241
  if (entryStat.isSymbolicLink()) {
30860
31242
  throw new SkillInstallerError(
30861
31243
  "DXC_SKILL_SOURCE_UNSAFE",
@@ -31111,20 +31493,22 @@ var LOG_REDACTION_PATHS = Object.freeze([
31111
31493
  // apps/cli/src/publishing-assets.ts
31112
31494
  import { createHash as createHash6 } from "node:crypto";
31113
31495
  import { constants as fileConstants2 } from "node:fs";
31114
- import { lstat as lstat4, open as open2, readdir as readdir2, realpath } from "node:fs/promises";
31496
+ import { lstat as lstat5, open as open2, readdir as readdir2, realpath } from "node:fs/promises";
31115
31497
  import path6 from "node:path";
31116
31498
  var import_yaml3 = __toESM(require_dist(), 1);
31117
31499
 
31118
31500
  // apps/cli/src/wechat-error.ts
31119
31501
  var WechatCliError = class extends Error {
31120
- constructor(code, guidance) {
31502
+ constructor(code, guidance, retryable = false) {
31121
31503
  super(guidance ?? code);
31122
31504
  this.code = code;
31123
31505
  this.guidance = guidance;
31506
+ this.retryable = retryable;
31124
31507
  this.name = "WechatCliError";
31125
31508
  }
31126
31509
  code;
31127
31510
  guidance;
31511
+ retryable;
31128
31512
  };
31129
31513
 
31130
31514
  // apps/cli/src/publishing-assets.ts
@@ -31137,16 +31521,35 @@ var VISUAL_PLAN_MAXIMUM_BYTES = 128 * 1024;
31137
31521
  var ARTICLE_FRONTMATTER = /^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)([\s\S]*)$/u;
31138
31522
  var VISUAL_PLAN_FRONTMATTER = /^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/u;
31139
31523
  var LOCAL_WORKFLOW_FRONTMATTER_KEYS = ["dxc", "goldenLinesPath", "goldenLinesSha256"];
31140
- async function readPublishingInput(inputPath, maximumBytes) {
31524
+ async function readPublishingInput(inputPath, maximumBytes, role = "article") {
31141
31525
  const target = path6.resolve(inputPath);
31142
31526
  let handle;
31143
31527
  try {
31144
31528
  handle = await open2(target, fileConstants2.O_RDONLY | fileConstants2.O_NOFOLLOW);
31145
31529
  const metadata = await handle.stat();
31146
- if (!metadata.isFile() || metadata.size <= 0 || metadata.size > maximumBytes) {
31530
+ if (metadata.isFile() && metadata.size > maximumBytes) {
31531
+ const fileName = path6.basename(target);
31532
+ if (role === "inline-image") {
31533
+ throw new WechatCliError(
31534
+ "DXC_PUBLISHING_INLINE_IMAGE_TOO_LARGE",
31535
+ `\u6B63\u6587\u56FE\u7247 ${fileName} \u4E3A ${metadata.size} bytes\uFF1B\u5FC5\u987B\u5C0F\u4E8E 1048576 bytes\u3002\u8BF7\u5BFC\u51FA\u4E3A JPEG\u3001\u964D\u4F4E\u5C3A\u5BF8\u6216\u8D28\u91CF\uFF0C\u66F4\u65B0 visual-plan \u540E\u91CD\u65B0 checkpoint \u548C\u9884\u89C8\u3002`
31536
+ );
31537
+ }
31538
+ if (role === "cover") {
31539
+ throw new WechatCliError(
31540
+ "DXC_PUBLISHING_COVER_TOO_LARGE",
31541
+ `\u5C01\u9762 ${fileName} \u4E3A ${metadata.size} bytes\uFF1B\u4E0A\u9650\u4E3A ${maximumBytes} bytes\u3002\u8BF7\u964D\u4F4E\u5C3A\u5BF8\u6216\u8D28\u91CF\u540E\u91CD\u65B0 checkpoint \u548C\u9884\u89C8\u3002`
31542
+ );
31543
+ }
31147
31544
  throw new WechatCliError(
31148
31545
  "DXC_PUBLISHING_INPUT_INVALID",
31149
- `\u6587\u4EF6 ${path6.basename(target)} \u4E0D\u662F\u53EF\u8BFB\u53D6\u7684\u666E\u901A\u6587\u4EF6\uFF0C\u6216\u5927\u5C0F\u8D85\u51FA\u9650\u5236\u3002`
31546
+ `\u6587\u4EF6 ${fileName} \u4E3A ${metadata.size} bytes\uFF0C\u8D85\u8FC7 ${maximumBytes} bytes \u7684\u9650\u5236\u3002`
31547
+ );
31548
+ }
31549
+ if (!metadata.isFile() || metadata.size <= 0) {
31550
+ throw new WechatCliError(
31551
+ "DXC_PUBLISHING_INPUT_INVALID",
31552
+ `\u6587\u4EF6 ${path6.basename(target)} \u4E0D\u662F\u53EF\u8BFB\u53D6\u7684\u975E\u7A7A\u666E\u901A\u6587\u4EF6\u3002`
31150
31553
  );
31151
31554
  }
31152
31555
  return {
@@ -31165,7 +31568,7 @@ async function readPublishingInput(inputPath, maximumBytes) {
31165
31568
  await handle?.close();
31166
31569
  }
31167
31570
  }
31168
- async function readContainedPublishingInput(inputPath, maximumBytes, allowedDirectories) {
31571
+ async function readContainedPublishingInput(inputPath, maximumBytes, allowedDirectories, role) {
31169
31572
  try {
31170
31573
  const [target, ...directories] = await Promise.all([
31171
31574
  realpath(path6.resolve(inputPath)),
@@ -31189,7 +31592,7 @@ async function readContainedPublishingInput(inputPath, maximumBytes, allowedDire
31189
31592
  `\u65E0\u6CD5\u5B89\u5168\u89E3\u6790\u7D20\u6750 ${path6.basename(inputPath)}\u3002`
31190
31593
  );
31191
31594
  }
31192
- return readPublishingInput(inputPath, maximumBytes);
31595
+ return readPublishingInput(inputPath, maximumBytes, role);
31193
31596
  }
31194
31597
  function publishingImageMediaType(inputPath) {
31195
31598
  const extension = path6.extname(inputPath).toLowerCase();
@@ -31226,7 +31629,7 @@ async function collectedImages(directoryInput, articleDirectory) {
31226
31629
  const directory = path6.resolve(directoryInput);
31227
31630
  let entries;
31228
31631
  try {
31229
- const metadata = await lstat4(directory);
31632
+ const metadata = await lstat5(directory);
31230
31633
  if (!metadata.isDirectory() || metadata.isSymbolicLink()) {
31231
31634
  throw new WechatCliError(
31232
31635
  "DXC_PUBLISHING_ASSETS_DIRECTORY_INVALID",
@@ -31260,6 +31663,13 @@ async function collectedImages(directoryInput, articleDirectory) {
31260
31663
  ).map((entry) => path6.join(directory, entry.name)).sort((left, right) => left.localeCompare(right, "zh-CN"));
31261
31664
  }
31262
31665
  function injectCollectedImages(source, images) {
31666
+ const diagnosticText = (value, maximum = 120) => {
31667
+ const sanitized = [...value].map((character) => {
31668
+ const codePoint = character.codePointAt(0) ?? 0;
31669
+ return codePoint < 32 || codePoint >= 127 && codePoint <= 159 ? " " : character;
31670
+ }).join("").trim();
31671
+ return sanitized.length <= maximum ? sanitized : `${sanitized.slice(0, maximum)}\u2026`;
31672
+ };
31263
31673
  if (images.length === 0) {
31264
31674
  return source;
31265
31675
  }
@@ -31285,9 +31695,11 @@ function injectCollectedImages(source, images) {
31285
31695
  const match = /^after-heading:(.+)$/u.exec(image.placementAnchor);
31286
31696
  const matches = match === null ? void 0 : headingLineByText.get(match[1]?.trim() ?? "");
31287
31697
  if (matches === void 0 || matches.length !== 1) {
31698
+ const matchCount = matches?.length ?? 0;
31699
+ const availableHeadings = [...headingLineByText.keys()].slice(0, 10).map((heading) => diagnosticText(heading)).join("\u3001").slice(0, 600);
31288
31700
  throw new WechatCliError(
31289
31701
  "DXC_PUBLISHING_VISUAL_ANCHOR_INVALID",
31290
- "\u89C6\u89C9\u8BA1\u5212\u7684\u63D2\u56FE\u951A\u70B9\u5FC5\u987B\u552F\u4E00\u5339\u914D\u6B63\u6587\u4E2D\u7684\u4E00\u4E2A\u4E8C\u7EA7\u6807\u9898\u3002"
31702
+ `\u89C6\u89C9\u8BA1\u5212\u951A\u70B9 ${diagnosticText(image.placementAnchor, 180)} \u7684\u7CBE\u786E\u5339\u914D\u6570\u4E3A ${matchCount}\uFF1B\u5FC5\u987B\u552F\u4E00\u5339\u914D\u6B63\u6587\u4E2D\u7684\u4E00\u4E2A\u4E8C\u7EA7\u6807\u9898\u3002\u53EF\u7528\u6807\u9898\uFF1A${availableHeadings.length === 0 ? "\uFF08\u65E0\uFF09" : availableHeadings}\u3002\u8BF7\u590D\u5236\u6807\u9898\u539F\u6587\uFF08\u542B\u6807\u70B9\uFF09\u66F4\u65B0 placementAnchor\u3002`
31291
31703
  );
31292
31704
  }
31293
31705
  headingLine = matches[0];
@@ -31310,9 +31722,7 @@ function injectCollectedImages(source, images) {
31310
31722
  async function plannedInlineImages(visualPlanFile, availableByFileName) {
31311
31723
  let source;
31312
31724
  try {
31313
- source = (await readPublishingInput(visualPlanFile, VISUAL_PLAN_MAXIMUM_BYTES)).bytes.toString(
31314
- "utf8"
31315
- );
31725
+ source = (await readPublishingInput(visualPlanFile, VISUAL_PLAN_MAXIMUM_BYTES, "visual-plan")).bytes.toString("utf8");
31316
31726
  } catch {
31317
31727
  throw new WechatCliError("DXC_PUBLISHING_VISUAL_PLAN_INVALID");
31318
31728
  }
@@ -31330,6 +31740,12 @@ async function plannedInlineImages(visualPlanFile, availableByFileName) {
31330
31740
  if (!parsed.success) {
31331
31741
  throw new WechatCliError("DXC_PUBLISHING_VISUAL_PLAN_INVALID");
31332
31742
  }
31743
+ if (!("inlineAssets" in parsed.data)) {
31744
+ throw new WechatCliError(
31745
+ "DXC_PUBLISHING_VISUAL_PLAN_INVALID",
31746
+ "\u89C6\u89C9\u8BA1\u5212\u4ECD\u5904\u4E8E\u751F\u6210\u524D\u6388\u6743\u9636\u6BB5\uFF1B\u8BF7\u5148\u5B8C\u6210\u56FE\u7247\u751F\u6210\u5E76\u5199\u5165 coverAsset/inlineAssets \u540E\u518D\u9884\u89C8\u3002"
31747
+ );
31748
+ }
31333
31749
  return Promise.all(
31334
31750
  parsed.data.inlineAssets.map(async (asset) => {
31335
31751
  const absolutePath = availableByFileName.get(path6.posix.basename(asset.path));
@@ -31339,7 +31755,11 @@ async function plannedInlineImages(visualPlanFile, availableByFileName) {
31339
31755
  `\u89C6\u89C9\u8BA1\u5212\u58F0\u660E\u7684\u7D20\u6750 ${path6.posix.basename(asset.path)} \u4E0D\u5728\u6307\u5B9A\u7D20\u6750\u76EE\u5F55\u4E2D\u3002`
31340
31756
  );
31341
31757
  }
31342
- const input = await readPublishingInput(absolutePath, MAXIMUM_INLINE_IMAGE_BYTES2);
31758
+ const input = await readPublishingInput(
31759
+ absolutePath,
31760
+ MAXIMUM_INLINE_IMAGE_BYTES2,
31761
+ "inline-image"
31762
+ );
31343
31763
  if (createHash6("sha256").update(input.bytes).digest("hex") !== asset.sha256) {
31344
31764
  throw new WechatCliError(
31345
31765
  "DXC_PUBLISHING_VISUAL_PLAN_INVALID",
@@ -31456,7 +31876,8 @@ async function preparePublishingDraft(input) {
31456
31876
  const asset = await readContainedPublishingInput(
31457
31877
  target,
31458
31878
  MAXIMUM_INLINE_IMAGE_BYTES2,
31459
- automaticAssetDirectories
31879
+ automaticAssetDirectories,
31880
+ "inline-image"
31460
31881
  );
31461
31882
  return {
31462
31883
  ...asset,
@@ -31474,8 +31895,9 @@ async function preparePublishingDraft(input) {
31474
31895
  const cover = explicitCover === void 0 ? await readContainedPublishingInput(
31475
31896
  coverCandidate,
31476
31897
  MAXIMUM_IMAGE_BYTES,
31477
- automaticAssetDirectories
31478
- ) : await readPublishingInput(coverCandidate, MAXIMUM_IMAGE_BYTES);
31898
+ automaticAssetDirectories,
31899
+ "cover"
31900
+ ) : await readPublishingInput(coverCandidate, MAXIMUM_IMAGE_BYTES, "cover");
31479
31901
  publishingImageMediaType(cover.path);
31480
31902
  return {
31481
31903
  article: {
@@ -31788,9 +32210,11 @@ async function checkedJson(response) {
31788
32210
  const value = await responseJson(response);
31789
32211
  if (!response.ok) {
31790
32212
  const apiError = apiErrorResponseSchema.safeParse(value);
31791
- throw new WechatCliError(
31792
- apiError.success ? apiError.data.error.code : "DXC_API_REQUEST_FAILED"
31793
- );
32213
+ if (apiError.success) {
32214
+ const guidance = apiError.data.error.code === "PUBLISHING_PREVIEW_REQUIRED" ? "\u670D\u52A1\u7AEF\u5C1A\u672A\u8BB0\u5F55\u4F60\u5B9E\u9645\u67E5\u770B\u8FC7\u6700\u7EC8\u9884\u89C8\u3002\u8BF7\u5BF9\u540C\u4E00 root \u5FEB\u7167\u8FD0\u884C preview-refresh --browser system\uFF0C\u786E\u8BA4\u7CFB\u7EDF\u6D4F\u89C8\u5668\u5DF2\u6253\u5F00\u9875\u9762\u540E\u518D\u521B\u5EFA\u8349\u7A3F\u3002" : apiError.data.error.message;
32215
+ throw new WechatCliError(apiError.data.error.code, guidance, apiError.data.error.retryable);
32216
+ }
32217
+ throw new WechatCliError("DXC_API_REQUEST_FAILED");
31794
32218
  }
31795
32219
  return value;
31796
32220
  }
@@ -32120,8 +32544,6 @@ var WechatCli = class {
32120
32544
  );
32121
32545
  assertCompleteInlineAssets(prepared.inlineAssets, snapshot.inlineAssets);
32122
32546
  if (!snapshot.preflight.ok) {
32123
- output.writeStdout(`${JSON.stringify({ account, snapshot })}
32124
- `);
32125
32547
  throw new WechatCliError("DXC_PUBLISHING_CLOUD_PREFLIGHT_FAILED");
32126
32548
  }
32127
32549
  const previewResponse = await this.#authenticatedFetch(
@@ -32134,7 +32556,7 @@ var WechatCli = class {
32134
32556
  }
32135
32557
  );
32136
32558
  const preview = publishingPreviewLinkSchema.parse(await checkedJson(previewResponse.response));
32137
- const browserMode = options.browserMode ?? "agent";
32559
+ const browserMode = options.browserMode ?? "system";
32138
32560
  const result = {
32139
32561
  account,
32140
32562
  presentation: {
@@ -32181,7 +32603,7 @@ var WechatCli = class {
32181
32603
  const secondsRemaining = preview.expiresInSeconds ?? Math.max(0, Math.floor((Date.parse(preview.expiresAt) - Date.now()) / 1e3));
32182
32604
  output.writeStderr(`\u5DF2\u4E3A\u540C\u4E00\u4E2A\u4E0D\u53EF\u53D8\u5FEB\u7167\u91CD\u5EFA\u9884\u89C8\u94FE\u63A5\uFF0C\u5C06\u5728 ${secondsRemaining} \u79D2\u540E\u5931\u6548\u3002
32183
32605
  `);
32184
- await presentDraftPreview(output, this.#openExternal, preview, options.browserMode ?? "agent");
32606
+ await presentDraftPreview(output, this.#openExternal, preview, options.browserMode ?? "system");
32185
32607
  return preview;
32186
32608
  }
32187
32609
  async createDraft(options, output) {
@@ -32735,12 +33157,22 @@ function previewBrowserMode(value) {
32735
33157
  function collectValues(value, previous) {
32736
33158
  return [...previous, value];
32737
33159
  }
32738
- async function runWechatAction(context, action) {
33160
+ async function runWechatAction(context, action, json = false) {
32739
33161
  try {
32740
33162
  await action(new WechatCli(context.wechatDependencies));
32741
33163
  } catch (error) {
32742
33164
  const code = error instanceof WechatCliError ? error.code : "DXC_WECHAT_FAILED";
32743
33165
  const guidance = error instanceof WechatCliError ? error.guidance : void 0;
33166
+ const retryable = error instanceof WechatCliError ? error.retryable : false;
33167
+ if (json) {
33168
+ writeJson(context, {
33169
+ error: {
33170
+ code,
33171
+ message: guidance ?? code,
33172
+ retryable
33173
+ }
33174
+ });
33175
+ }
32744
33176
  context.writeStderr(`${code}${guidance === void 0 ? "" : `: ${guidance}`}
32745
33177
  `);
32746
33178
  context.setExitCode(1);
@@ -32768,7 +33200,7 @@ async function loadKnowledgeModule() {
32768
33200
  Reflect.apply(emitWarning, process, [warning2, ...arguments_]);
32769
33201
  });
32770
33202
  try {
32771
- return await import("./chunks/knowledge-PWFALFEC.js");
33203
+ return await import("./chunks/knowledge-5Y22MFAV.js");
32772
33204
  } finally {
32773
33205
  process.emitWarning = emitWarning;
32774
33206
  }
@@ -32782,7 +33214,7 @@ async function loadMonitorModule() {
32782
33214
  Reflect.apply(emitWarning, process, [warning2, ...arguments_]);
32783
33215
  });
32784
33216
  try {
32785
- return await import("./chunks/monitor-CL5UXEO2.js");
33217
+ return await import("./chunks/monitor-MZPF73LC.js");
32786
33218
  } finally {
32787
33219
  process.emitWarning = emitWarning;
32788
33220
  }
@@ -32850,7 +33282,8 @@ async function runMemoryAction(context, command, json, action) {
32850
33282
  error: { code, message },
32851
33283
  ok: false
32852
33284
  }),
32853
- code
33285
+ code,
33286
+ message
32854
33287
  );
32855
33288
  }
32856
33289
  }
@@ -32885,10 +33318,16 @@ async function runProjectAction(context, command, json, action) {
32885
33318
  json,
32886
33319
  contentProjectErrorResultSchema.parse({
32887
33320
  command,
32888
- error: { code, message },
33321
+ error: {
33322
+ code,
33323
+ message,
33324
+ ...error instanceof ProjectCliError ? error.details : {}
33325
+ },
32889
33326
  ok: false
32890
33327
  }),
32891
- code
33328
+ code,
33329
+ message,
33330
+ error instanceof ProjectCliError ? error.details.recovery : void 0
32892
33331
  );
32893
33332
  }
32894
33333
  }
@@ -33264,16 +33703,20 @@ ${hint}
33264
33703
  project.command("checkpoint").description("\u5199\u5165\u7EDF\u4E00\u7684\u9636\u6BB5 contract").argument("<stage>", "\u6B65\u9AA4\u540D\u79F0").requiredOption("--status <status>", "running / awaiting-user / completed / failed / skipped").option("--skill <name>", "\u7279\u6B8A\u63A5\u7BA1\u6D41\u7A0B\u4F7F\u7528\u7684 dxc-* Skill\uFF1B\u5E38\u89C4\u9636\u6BB5\u7531 catalog \u81EA\u52A8\u786E\u5B9A").option(
33265
33704
  "--skill-version <version>",
33266
33705
  "\u7279\u6B8A\u63A5\u7BA1\u6D41\u7A0B\u4F7F\u7528\u7684 Skill \u7248\u672C\uFF1B\u5E38\u89C4\u9636\u6BB5\u7531 catalog \u81EA\u52A8\u786E\u5B9A"
33267
- ).requiredOption("--summary <text>", "\u672C\u6B21\u9636\u6BB5\u72B6\u6001\u7684\u7B80\u77ED\u8BF4\u660E").option("--directory <path>", "\u9879\u76EE\u76EE\u5F55", ".").option("--inputs <stages>", "\u672C\u6B21\u989D\u5916\u8BFB\u53D6\u7684\u53EF\u9009\u8F93\u5165\uFF1B\u5FC5\u9700\u8F93\u5165\u7531 catalog \u81EA\u52A8\u8865\u9F50").option("--execution-location <location>", "local-device / agent-hosted / unknown", "unknown").option(
33706
+ ).option("--summary <text>", "\u672C\u6B21\u9636\u6BB5\u72B6\u6001\u7684\u7B80\u77ED\u8BF4\u660E").option("--directory <path>", "\u9879\u76EE\u76EE\u5F55", ".").option("--inputs <stages>", "\u672C\u6B21\u989D\u5916\u8BFB\u53D6\u7684\u53EF\u9009\u8F93\u5165\uFF1B\u5FC5\u9700\u8F93\u5165\u7531 catalog \u81EA\u52A8\u8865\u9F50").option("--execution-location <location>", "local-device / agent-hosted / unknown", "unknown").option(
33268
33707
  "--data-transit <transit>",
33269
33708
  "local-only / agent-provider / dxc-cloud / unknown",
33270
33709
  "unknown"
33271
- ).option("--error-code <code>", "\u5931\u8D25\u65F6\u7684\u7A33\u5B9A\u9519\u8BEF\u7801").option("--waiting-for <prompt>", "awaiting-user \u72B6\u6001\u7B49\u5F85\u7528\u6237\u56DE\u7B54\u7684\u95EE\u9898").option("--confirm", "\u8BB0\u5F55\u7528\u6237\u5DF2\u786E\u8BA4\u8BE5\u6B65\u9AA4\u4EA7\u7269").option("--confirmed-by <actor>", "\u786E\u8BA4\u4EBA\u6216\u7A33\u5B9A\u8EAB\u4EFD\u6807\u8BC6", "local-interactive-user").option("--confirmation-snapshot <sha256>", "\u786E\u8BA4\u6240\u7ED1\u5B9A\u7684\u5FEB\u7167 SHA-256").option("--json", "\u8F93\u51FA JSON").action(
33710
+ ).option("--error-code <code>", "\u5931\u8D25\u65F6\u7684\u7A33\u5B9A\u9519\u8BEF\u7801").option("--waiting-for <prompt>", "awaiting-user \u72B6\u6001\u7B49\u5F85\u7528\u6237\u56DE\u7B54\u7684\u95EE\u9898").option("--confirm", "\u8BB0\u5F55\u7528\u6237\u5DF2\u786E\u8BA4\u8BE5\u6B65\u9AA4\u4EA7\u7269").option(
33711
+ "--authorization-purpose <purpose>",
33712
+ "\u9636\u6BB5\u5185\u5916\u90E8\u52A8\u4F5C\u6388\u6743\uFF1B\u5F53\u524D\u4EC5 visual-plan \u652F\u6301 image-generation"
33713
+ ).option("--confirmed-by <actor>", "\u786E\u8BA4\u4EBA\u6216\u7A33\u5B9A\u8EAB\u4EFD\u6807\u8BC6", "local-interactive-user").option("--confirmation-snapshot <sha256>", "\u786E\u8BA4\u6240\u7ED1\u5B9A\u7684\u5FEB\u7167 SHA-256").option("--json", "\u8F93\u51FA JSON").action(
33272
33714
  async (stage, options) => runProjectAction(
33273
33715
  context,
33274
33716
  "project.checkpoint",
33275
33717
  options.json === true,
33276
33718
  async (projectCli) => projectCli.checkpoint({
33719
+ ...options.authorizationPurpose === void 0 ? {} : { authorizationPurpose: options.authorizationPurpose },
33277
33720
  confirmed: options.confirm === true,
33278
33721
  ...options.confirmedBy === void 0 ? {} : { confirmedBy: options.confirmedBy },
33279
33722
  ...options.confirmationSnapshot === void 0 ? {} : {
@@ -33294,7 +33737,7 @@ ${hint}
33294
33737
  ...options.skillVersion === void 0 ? {} : { skillVersion: options.skillVersion },
33295
33738
  stage,
33296
33739
  status: options.status,
33297
- summary: options.summary,
33740
+ ...options.summary === void 0 ? {} : { summary: options.summary },
33298
33741
  ...options.waitingFor === void 0 ? {} : { waitingFor: options.waitingFor }
33299
33742
  })
33300
33743
  )
@@ -33456,9 +33899,13 @@ ${hint}
33456
33899
  })
33457
33900
  );
33458
33901
  auth.command("status").description("\u663E\u793A\u5F53\u524D\u8BBE\u5907\u3001\u7528\u6237\u548C\u5185\u5BB9\u7A7A\u95F4").option("--json", "\u8F93\u51FA JSON").action(
33459
- async () => runWechatAction(context, async (wechatCli) => {
33460
- await wechatCli.status(context);
33461
- })
33902
+ async (options) => runWechatAction(
33903
+ context,
33904
+ async (wechatCli) => {
33905
+ await wechatCli.status(context);
33906
+ },
33907
+ options.json === true
33908
+ )
33462
33909
  );
33463
33910
  auth.command("logout").description("\u64A4\u9500\u5F53\u524D\u8BBE\u5907\u4F1A\u8BDD").action(
33464
33911
  async () => runWechatAction(context, async (wechatCli) => {
@@ -33479,149 +33926,195 @@ ${hint}
33479
33926
  })
33480
33927
  );
33481
33928
  wechat.command("accounts").description("\u5217\u51FA\u5DF2\u7ED1\u5B9A\u516C\u4F17\u53F7\u548C\u8349\u7A3F\u6743\u9650").option("--json", "\u8F93\u51FA JSON").action(
33482
- async (options) => runWechatAction(context, async (wechatCli) => {
33483
- await wechatCli.accounts(context, options.json === true);
33484
- })
33929
+ async (options) => runWechatAction(
33930
+ context,
33931
+ async (wechatCli) => {
33932
+ await wechatCli.accounts(context, options.json === true);
33933
+ },
33934
+ options.json === true
33935
+ )
33485
33936
  );
33486
33937
  const draft = wechat.command("draft").description("\u9884\u89C8\u5E76\u521B\u5EFA\u5FAE\u4FE1\u516C\u4F17\u53F7\u8349\u7A3F");
33487
- draft.command("preview").description("\u91C7\u96C6\u5DF2\u751F\u6210\u6216\u9009\u62E9\u7684\u56FE\u7247\uFF0C\u5E76\u751F\u6210\u4E0D\u53EF\u53D8\u4E91\u7AEF\u9884\u89C8").requiredOption("--article <path>", "Markdown \u6587\u7AE0\u6587\u4EF6").option("--cover <path-or-auto>", "PNG/JPEG \u5185\u5BB9\u5C01\u9762\uFF1Bauto \u4ECE\u6587\u7AE0\u6216\u7D20\u6750\u76EE\u5F55\u89E3\u6790", "auto").option("--assets-directory <path>", "\u91C7\u96C6\u5E76\u5185\u8054\u8BE5\u76EE\u5F55\u4E2D\u5DF2\u51C6\u5907\u597D\u7684 PNG/JPEG").option("--visual-plan <path>", "\u6309\u89C6\u89C9\u8BA1\u5212\u7684\u7CBE\u786E\u7AE0\u8282\u951A\u70B9\u63D2\u5165\u5DF2\u58F0\u660E\u7684\u6B63\u6587\u56FE\u7247").requiredOption("--account <uuid>", "\u76EE\u6807\u516C\u4F17\u53F7\u8D26\u53F7 ID").option("--title <title>", "\u4F7F\u7528\u5DF2\u786E\u8BA4\u6807\u9898\u8986\u76D6\u6587\u7AE0 frontmatter \u6807\u9898").option("--browser <agent|system>", "\u4F18\u5148\u5728 Agent \u53F3\u4FA7\u9884\u89C8\uFF1B\u4E0D\u652F\u6301\u65F6\u53EF\u6539\u7528\u7CFB\u7EDF\u6D4F\u89C8\u5668", "agent").action(
33488
- async (options) => runWechatAction(context, async (wechatCli) => {
33489
- await wechatCli.previewDraft(
33490
- {
33491
- accountId: validatedOption(
33492
- options.account,
33493
- /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/iu,
33494
- "account"
33495
- ),
33496
- browserMode: previewBrowserMode(options.browser),
33497
- articleFile: resolveUserPath({
33498
- currentDirectory: context.currentDirectory,
33499
- homeDirectory: context.homeDirectory,
33500
- input: options.article
33501
- }),
33502
- ...options.assetsDirectory === void 0 ? {} : {
33503
- assetsDirectory: resolveUserPath({
33504
- currentDirectory: context.currentDirectory,
33505
- homeDirectory: context.homeDirectory,
33506
- input: options.assetsDirectory
33507
- })
33508
- },
33509
- ...options.cover === void 0 ? {} : {
33510
- coverFile: options.cover === "auto" ? "auto" : resolveUserPath({
33938
+ draft.command("preview").description("\u91C7\u96C6\u5DF2\u751F\u6210\u6216\u9009\u62E9\u7684\u56FE\u7247\uFF0C\u5E76\u751F\u6210\u4E0D\u53EF\u53D8\u4E91\u7AEF\u9884\u89C8").requiredOption("--article <path>", "Markdown \u6587\u7AE0\u6587\u4EF6").option("--cover <path-or-auto>", "PNG/JPEG \u5185\u5BB9\u5C01\u9762\uFF1Bauto \u4ECE\u6587\u7AE0\u6216\u7D20\u6750\u76EE\u5F55\u89E3\u6790", "auto").option("--assets-directory <path>", "\u91C7\u96C6\u5E76\u5185\u8054\u8BE5\u76EE\u5F55\u4E2D\u5DF2\u51C6\u5907\u597D\u7684 PNG/JPEG").option("--visual-plan <path>", "\u6309\u89C6\u89C9\u8BA1\u5212\u7684\u7CBE\u786E\u7AE0\u8282\u951A\u70B9\u63D2\u5165\u5DF2\u58F0\u660E\u7684\u6B63\u6587\u56FE\u7247").requiredOption("--account <uuid>", "\u76EE\u6807\u516C\u4F17\u53F7\u8D26\u53F7 ID").option("--title <title>", "\u4F7F\u7528\u5DF2\u786E\u8BA4\u6807\u9898\u8986\u76D6\u6587\u7AE0 frontmatter \u6807\u9898").option(
33939
+ "--browser <agent|system>",
33940
+ "\u4F7F\u7528\u7CFB\u7EDF\u6D4F\u89C8\u5668\uFF1B\u5BBF\u4E3B\u5DF2\u8BC1\u660E\u652F\u6301\u53F3\u4FA7\u6D4F\u89C8\u5668\u65F6\u53EF\u663E\u5F0F\u4F7F\u7528 agent",
33941
+ "system"
33942
+ ).option("--json", "\u8F93\u51FA JSON\uFF1B\u5931\u8D25\u65F6\u4E5F\u5728 stdout \u8FD4\u56DE\u7ED3\u6784\u5316\u9519\u8BEF").action(
33943
+ async (options) => runWechatAction(
33944
+ context,
33945
+ async (wechatCli) => {
33946
+ await wechatCli.previewDraft(
33947
+ {
33948
+ accountId: validatedOption(
33949
+ options.account,
33950
+ /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/iu,
33951
+ "account"
33952
+ ),
33953
+ browserMode: previewBrowserMode(options.browser),
33954
+ articleFile: resolveUserPath({
33511
33955
  currentDirectory: context.currentDirectory,
33512
33956
  homeDirectory: context.homeDirectory,
33513
- input: options.cover
33514
- })
33957
+ input: options.article
33958
+ }),
33959
+ ...options.assetsDirectory === void 0 ? {} : {
33960
+ assetsDirectory: resolveUserPath({
33961
+ currentDirectory: context.currentDirectory,
33962
+ homeDirectory: context.homeDirectory,
33963
+ input: options.assetsDirectory
33964
+ })
33965
+ },
33966
+ ...options.cover === void 0 ? {} : {
33967
+ coverFile: options.cover === "auto" ? "auto" : resolveUserPath({
33968
+ currentDirectory: context.currentDirectory,
33969
+ homeDirectory: context.homeDirectory,
33970
+ input: options.cover
33971
+ })
33972
+ },
33973
+ ...options.title === void 0 ? {} : { title: options.title },
33974
+ ...options.visualPlan === void 0 ? {} : {
33975
+ visualPlanFile: resolveUserPath({
33976
+ currentDirectory: context.currentDirectory,
33977
+ homeDirectory: context.homeDirectory,
33978
+ input: options.visualPlan
33979
+ })
33980
+ }
33515
33981
  },
33516
- ...options.title === void 0 ? {} : { title: options.title },
33517
- ...options.visualPlan === void 0 ? {} : {
33518
- visualPlanFile: resolveUserPath({
33519
- currentDirectory: context.currentDirectory,
33520
- homeDirectory: context.homeDirectory,
33521
- input: options.visualPlan
33522
- })
33523
- }
33524
- },
33525
- context
33526
- );
33527
- })
33982
+ context
33983
+ );
33984
+ },
33985
+ options.json === true
33986
+ )
33528
33987
  );
33529
- draft.command("preview-refresh").description("\u4E3A\u540C\u4E00\u4E2A\u4E0D\u53EF\u53D8\u5FEB\u7167\u91CD\u5EFA\u77ED\u65F6\u9884\u89C8\u94FE\u63A5").option("--snapshot <uuid>", "\u4E0D\u53EF\u53D8\u5FEB\u7167 ID").option("--snapshot-hash <sha256>", "\u4E0D\u53EF\u53D8\u5FEB\u7167 SHA-256").option("--browser <agent|system>", "\u4F18\u5148\u5728 Agent \u53F3\u4FA7\u9884\u89C8\uFF1B\u4E0D\u652F\u6301\u65F6\u53EF\u6539\u7528\u7CFB\u7EDF\u6D4F\u89C8\u5668", "agent").action(
33530
- async (options) => runWechatAction(context, async (wechatCli) => {
33531
- const missing = [
33532
- ...options.snapshot === void 0 ? ["--snapshot"] : [],
33533
- ...options.snapshotHash === void 0 ? ["--snapshot-hash"] : []
33534
- ];
33535
- if (missing.length > 0) {
33536
- throw new WechatCliError(
33537
- "DXC_PREVIEW_REFRESH_OPTIONS_REQUIRED",
33538
- `\u7F3A\u5C11\u5FC5\u586B\u53C2\u6570\uFF1A${missing.join("\u3001")}\u3002`
33988
+ draft.command("preview-refresh").description("\u4E3A\u540C\u4E00\u4E2A\u4E0D\u53EF\u53D8\u5FEB\u7167\u91CD\u5EFA\u77ED\u65F6\u9884\u89C8\u94FE\u63A5").option("--snapshot <uuid>", "\u4E0D\u53EF\u53D8\u5FEB\u7167 ID").option("--snapshot-hash <sha256>", "\u4E0D\u53EF\u53D8\u5FEB\u7167 SHA-256").option(
33989
+ "--browser <agent|system>",
33990
+ "\u4F7F\u7528\u7CFB\u7EDF\u6D4F\u89C8\u5668\uFF1B\u5BBF\u4E3B\u5DF2\u8BC1\u660E\u652F\u6301\u53F3\u4FA7\u6D4F\u89C8\u5668\u65F6\u53EF\u663E\u5F0F\u4F7F\u7528 agent",
33991
+ "system"
33992
+ ).option("--json", "\u8F93\u51FA JSON\uFF1B\u5931\u8D25\u65F6\u4E5F\u5728 stdout \u8FD4\u56DE\u7ED3\u6784\u5316\u9519\u8BEF").action(
33993
+ async (options) => runWechatAction(
33994
+ context,
33995
+ async (wechatCli) => {
33996
+ const missing = [
33997
+ ...options.snapshot === void 0 ? ["--snapshot"] : [],
33998
+ ...options.snapshotHash === void 0 ? ["--snapshot-hash"] : []
33999
+ ];
34000
+ if (missing.length > 0) {
34001
+ throw new WechatCliError(
34002
+ "DXC_PREVIEW_REFRESH_OPTIONS_REQUIRED",
34003
+ `\u7F3A\u5C11\u5FC5\u586B\u53C2\u6570\uFF1A${missing.join("\u3001")}\u3002`
34004
+ );
34005
+ }
34006
+ if (options.snapshot === void 0 || options.snapshotHash === void 0) {
34007
+ throw new WechatCliError("DXC_PREVIEW_REFRESH_OPTIONS_REQUIRED");
34008
+ }
34009
+ await wechatCli.refreshDraftPreview(
34010
+ {
34011
+ browserMode: previewBrowserMode(options.browser),
34012
+ snapshotHash: validatedOption(
34013
+ options.snapshotHash,
34014
+ /^[a-f0-9]{64}$/u,
34015
+ "snapshot-hash"
34016
+ ),
34017
+ snapshotId: validatedOption(
34018
+ options.snapshot,
34019
+ /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/iu,
34020
+ "snapshot"
34021
+ )
34022
+ },
34023
+ context
33539
34024
  );
33540
- }
33541
- if (options.snapshot === void 0 || options.snapshotHash === void 0) {
33542
- throw new WechatCliError("DXC_PREVIEW_REFRESH_OPTIONS_REQUIRED");
33543
- }
33544
- await wechatCli.refreshDraftPreview(
33545
- {
33546
- browserMode: previewBrowserMode(options.browser),
33547
- snapshotHash: validatedOption(
33548
- options.snapshotHash,
33549
- /^[a-f0-9]{64}$/u,
33550
- "snapshot-hash"
33551
- ),
33552
- snapshotId: validatedOption(
33553
- options.snapshot,
33554
- /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/iu,
33555
- "snapshot"
33556
- )
33557
- },
33558
- context
33559
- );
33560
- })
34025
+ },
34026
+ options.json === true
34027
+ )
33561
34028
  );
33562
- draft.command("create").description("\u786E\u8BA4\u4E0D\u53EF\u53D8\u5FEB\u7167\u548C\u76EE\u6807\u516C\u4F17\u53F7\u540E\u521B\u5EFA\u8349\u7A3F\u610F\u56FE").option("--account <uuid>", "\u76EE\u6807\u516C\u4F17\u53F7\u8D26\u53F7 ID").option("--snapshot <uuid>", "\u4E0D\u53EF\u53D8\u5FEB\u7167 ID").option("--snapshot-hash <sha256>", "\u4E0D\u53EF\u53D8\u5FEB\u7167 SHA-256").option("--idempotency-key <key>", "\u672C\u6B21\u8349\u7A3F\u610F\u56FE\u7684\u5E42\u7B49\u952E").option("--delivery <path>", "\u5199\u56DE\u6700\u7EC8\u9009\u4E2D\u5FEB\u7167\u7684 delivery \u9636\u6BB5\u4EA7\u7269").option("--confirm", "\u786E\u8BA4\u9884\u89C8\u5FEB\u7167\u548C\u76EE\u6807\u516C\u4F17\u53F7").action(
33563
- async (options) => runWechatAction(context, async (wechatCli) => {
33564
- const missing = [
33565
- ...options.account === void 0 ? ["--account"] : [],
33566
- ...options.snapshot === void 0 ? ["--snapshot"] : [],
33567
- ...options.snapshotHash === void 0 ? ["--snapshot-hash"] : [],
33568
- ...options.idempotencyKey === void 0 ? ["--idempotency-key"] : []
33569
- ];
33570
- if (missing.length > 0) {
33571
- throw new WechatCliError(
33572
- "DXC_DRAFT_OPTIONS_REQUIRED",
33573
- `\u7F3A\u5C11\u5FC5\u586B\u53C2\u6570\uFF1A${missing.join("\u3001")}\u3002`
34029
+ draft.command("create").description("\u786E\u8BA4\u4E0D\u53EF\u53D8\u5FEB\u7167\u548C\u76EE\u6807\u516C\u4F17\u53F7\u540E\u521B\u5EFA\u8349\u7A3F\u610F\u56FE").option("--account <uuid>", "\u76EE\u6807\u516C\u4F17\u53F7\u8D26\u53F7 ID").option("--snapshot <uuid>", "\u4E0D\u53EF\u53D8\u5FEB\u7167 ID").option("--snapshot-hash <sha256>", "\u4E0D\u53EF\u53D8\u5FEB\u7167 SHA-256").option("--idempotency-key <key>", "\u672C\u6B21\u8349\u7A3F\u610F\u56FE\u7684\u5E42\u7B49\u952E").option("--delivery <path>", "\u5199\u56DE\u6700\u7EC8\u9009\u4E2D\u5FEB\u7167\u7684 delivery \u9636\u6BB5\u4EA7\u7269").option("--confirm", "\u786E\u8BA4\u9884\u89C8\u5FEB\u7167\u548C\u76EE\u6807\u516C\u4F17\u53F7").option("--json", "\u8F93\u51FA JSON\uFF1B\u5931\u8D25\u65F6\u4E5F\u5728 stdout \u8FD4\u56DE\u7ED3\u6784\u5316\u9519\u8BEF").action(
34030
+ async (options) => runWechatAction(
34031
+ context,
34032
+ async (wechatCli) => {
34033
+ const deliveryFile = options.delivery === void 0 ? void 0 : resolveUserPath({
34034
+ currentDirectory: context.currentDirectory,
34035
+ homeDirectory: context.homeDirectory,
34036
+ input: options.delivery
34037
+ });
34038
+ let deliveryIdentity;
34039
+ if (deliveryFile !== void 0) {
34040
+ try {
34041
+ deliveryIdentity = await readDeliveryDraftIdentity(deliveryFile);
34042
+ } catch (error) {
34043
+ throw new WechatCliError(
34044
+ "DXC_DRAFT_DELIVERY_INVALID",
34045
+ error instanceof StageArtifactValidationError ? error.message : "\u65E0\u6CD5\u8BFB\u53D6 delivery \u9636\u6BB5\u4EA7\u7269\u3002"
34046
+ );
34047
+ }
34048
+ }
34049
+ const missing = [
34050
+ ...options.account === void 0 ? ["--account"] : [],
34051
+ ...options.snapshot === void 0 ? ["--snapshot"] : [],
34052
+ ...options.snapshotHash === void 0 ? ["--snapshot-hash"] : [],
34053
+ ...options.idempotencyKey === void 0 && deliveryIdentity === void 0 ? ["--idempotency-key \u6216 --delivery"] : []
34054
+ ];
34055
+ if (missing.length > 0) {
34056
+ throw new WechatCliError(
34057
+ "DXC_DRAFT_OPTIONS_REQUIRED",
34058
+ `\u7F3A\u5C11\u5FC5\u586B\u53C2\u6570\uFF1A${missing.join("\u3001")}\u3002`
34059
+ );
34060
+ }
34061
+ const account = options.account;
34062
+ const snapshot = options.snapshot;
34063
+ const snapshotHash = options.snapshotHash;
34064
+ const idempotencyKey = options.idempotencyKey ?? deliveryIdentity?.idempotencyKey;
34065
+ if (account === void 0 || snapshot === void 0 || snapshotHash === void 0 || idempotencyKey === void 0) {
34066
+ throw new WechatCliError("DXC_DRAFT_OPTIONS_REQUIRED");
34067
+ }
34068
+ if (deliveryIdentity !== void 0 && (deliveryIdentity.accountId !== account || deliveryIdentity.rootSnapshotId !== snapshot || deliveryIdentity.rootSnapshotHash !== snapshotHash || options.idempotencyKey !== void 0 && options.idempotencyKey !== deliveryIdentity.idempotencyKey)) {
34069
+ throw new WechatCliError(
34070
+ "DXC_DRAFT_DELIVERY_MISMATCH",
34071
+ "\u547D\u4EE4\u4E2D\u7684\u516C\u4F17\u53F7\u3001root \u5FEB\u7167\u6216\u5E42\u7B49\u952E\u4E0E delivery \u9636\u6BB5\u4EA7\u7269\u4E0D\u4E00\u81F4\uFF1B\u5DF2\u5728\u4EFB\u4F55\u670D\u52A1\u7AEF\u8BF7\u6C42\u524D\u505C\u6B62\u3002"
34072
+ );
34073
+ }
34074
+ await wechatCli.createDraft(
34075
+ {
34076
+ accountId: validatedOption(
34077
+ account,
34078
+ /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/iu,
34079
+ "account"
34080
+ ),
34081
+ confirmed: options.confirm === true,
34082
+ ...deliveryFile === void 0 ? {} : {
34083
+ deliveryFile
34084
+ },
34085
+ idempotencyKey: validatedOption(
34086
+ idempotencyKey,
34087
+ /^[A-Za-z0-9._:-]{16,128}$/u,
34088
+ "idempotency-key"
34089
+ ),
34090
+ snapshotHash: validatedOption(snapshotHash, /^[a-f0-9]{64}$/u, "snapshot-hash"),
34091
+ snapshotId: validatedOption(
34092
+ snapshot,
34093
+ /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/iu,
34094
+ "snapshot"
34095
+ )
34096
+ },
34097
+ context
33574
34098
  );
33575
- }
33576
- const account = options.account;
33577
- const snapshot = options.snapshot;
33578
- const snapshotHash = options.snapshotHash;
33579
- const idempotencyKey = options.idempotencyKey;
33580
- if (account === void 0 || snapshot === void 0 || snapshotHash === void 0 || idempotencyKey === void 0) {
33581
- throw new WechatCliError("DXC_DRAFT_OPTIONS_REQUIRED");
33582
- }
33583
- await wechatCli.createDraft(
33584
- {
33585
- accountId: validatedOption(
33586
- account,
34099
+ },
34100
+ options.json === true
34101
+ )
34102
+ );
34103
+ draft.command("status").description("\u67E5\u8BE2\u8349\u7A3F\u610F\u56FE\u72B6\u6001\u548C\u5FAE\u4FE1\u56DE\u8BFB\u7ED3\u679C").argument("<intent-id>", "\u8349\u7A3F\u610F\u56FE ID").option("--json", "\u8F93\u51FA JSON\uFF1B\u5931\u8D25\u65F6\u4E5F\u5728 stdout \u8FD4\u56DE\u7ED3\u6784\u5316\u9519\u8BEF").action(
34104
+ async (intentId, options) => runWechatAction(
34105
+ context,
34106
+ async (wechatCli) => {
34107
+ await wechatCli.publishingDraftStatus(
34108
+ validatedOption(
34109
+ intentId,
33587
34110
  /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/iu,
33588
- "account"
34111
+ "intent-id"
33589
34112
  ),
33590
- confirmed: options.confirm === true,
33591
- ...options.delivery === void 0 ? {} : {
33592
- deliveryFile: resolveUserPath({
33593
- currentDirectory: context.currentDirectory,
33594
- homeDirectory: context.homeDirectory,
33595
- input: options.delivery
33596
- })
33597
- },
33598
- idempotencyKey: validatedOption(
33599
- idempotencyKey,
33600
- /^[A-Za-z0-9._:-]{16,128}$/u,
33601
- "idempotency-key"
33602
- ),
33603
- snapshotHash: validatedOption(snapshotHash, /^[a-f0-9]{64}$/u, "snapshot-hash"),
33604
- snapshotId: validatedOption(
33605
- snapshot,
33606
- /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/iu,
33607
- "snapshot"
33608
- )
33609
- },
33610
- context
33611
- );
33612
- })
33613
- );
33614
- draft.command("status").description("\u67E5\u8BE2\u8349\u7A3F\u610F\u56FE\u72B6\u6001\u548C\u5FAE\u4FE1\u56DE\u8BFB\u7ED3\u679C").argument("<intent-id>", "\u8349\u7A3F\u610F\u56FE ID").action(
33615
- async (intentId) => runWechatAction(context, async (wechatCli) => {
33616
- await wechatCli.publishingDraftStatus(
33617
- validatedOption(
33618
- intentId,
33619
- /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/iu,
33620
- "intent-id"
33621
- ),
33622
- context
33623
- );
33624
- })
34113
+ context
34114
+ );
34115
+ },
34116
+ options.json === true
34117
+ )
33625
34118
  );
33626
34119
  draft.command("smoke-preview").description("\u83B7\u53D6\u56FA\u5B9A\u6D4B\u8BD5\u8349\u7A3F\u7684\u4E0D\u53EF\u53D8\u9884\u89C8").requiredOption("--account <uuid>", "\u76EE\u6807\u516C\u4F17\u53F7\u8D26\u53F7 ID").action(
33627
34120
  async (options) => runWechatAction(context, async (wechatCli) => {
@@ -33676,6 +34169,15 @@ async function runCli(arguments_, context = processContext()) {
33676
34169
  await program2.parseAsync([...arguments_]);
33677
34170
  } catch (error) {
33678
34171
  if (error instanceof CommanderError) {
34172
+ if (arguments_.includes("--json")) {
34173
+ writeJson(context, {
34174
+ error: {
34175
+ code: error.code || "DXC_CLI_OPTIONS_INVALID",
34176
+ message: error.message,
34177
+ retryable: false
34178
+ }
34179
+ });
34180
+ }
33679
34181
  context.setExitCode(error.exitCode);
33680
34182
  return;
33681
34183
  }