@my-life-buddies/cli 0.27.1-dev.2 → 0.28.0-dev.2

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/bin/core.js CHANGED
@@ -24,28 +24,40 @@ function runtimeUsesEnvironmentIdentity(pkg) {
24
24
  return major > 0 || minor >= 16;
25
25
  }
26
26
 
27
+ // packages/cli-core/src/npm-registry.ts
28
+ var REGISTRY = "https://registry.npmjs.org/";
29
+ async function npmPackageManifest(name, selector, options = {}) {
30
+ options.signal?.throwIfAborted();
31
+ const timeout = AbortSignal.timeout(options.timeoutMs ?? 1e4);
32
+ const signal = options.signal ? AbortSignal.any([options.signal, timeout]) : timeout;
33
+ const response = await (options.fetch ?? globalThis.fetch)(`${REGISTRY}${encodeURIComponent(name)}`, {
34
+ signal,
35
+ headers: { Accept: "application/json" },
36
+ redirect: "error"
37
+ });
38
+ if (!response.ok) throw new Error(`npm HTTP ${response.status}`);
39
+ const text2 = await response.text();
40
+ if (text2.length > 8 * 1024 * 1024) throw new Error("npm \u5143\u6570\u636E\u8FC7\u5927");
41
+ const metadata = JSON.parse(text2);
42
+ if (metadata?.name !== name) throw new Error("npm \u8FD4\u56DE\u7684\u5305\u540D\u4E0D\u5339\u914D");
43
+ const version = Object.hasOwn(metadata["dist-tags"] ?? {}, selector) ? metadata["dist-tags"][selector] : selector;
44
+ const manifest = typeof version === "string" && Object.hasOwn(metadata.versions ?? {}, version) ? metadata.versions[version] : void 0;
45
+ if (!manifest || manifest.name !== name || manifest.version !== version) {
46
+ throw new Error(`npm ${selector} \u672A\u8FD4\u56DE\u6B64\u5305\u7684\u51C6\u786E\u7248\u672C`);
47
+ }
48
+ return manifest;
49
+ }
50
+
27
51
  // packages/cli-core/src/config/runtime-package.ts
28
52
  var RUNTIME_REGISTRY = "https://registry.npmjs.org/";
29
53
  var execute = promisify(execFile);
30
54
  async function latestRuntimeVersion(options = {}) {
31
- const metadata = await runtimeMetadata("/dev", options);
55
+ const metadata = await npmPackageManifest(BUDDY_RUNTIME_PACKAGE, "dev", options);
32
56
  if (metadata?.name !== BUDDY_RUNTIME_PACKAGE || !isExactRuntimeVersion(metadata.version)) {
33
57
  throw new Error("npm dev \u672A\u8FD4\u56DE\u6B64 Runtime \u7684\u51C6\u786E\u7248\u672C");
34
58
  }
35
59
  return metadata.version;
36
60
  }
37
- async function runtimeMetadata(suffix, options) {
38
- options.signal?.throwIfAborted();
39
- const timeout = AbortSignal.timeout(1e4);
40
- const signal = options.signal ? AbortSignal.any([options.signal, timeout]) : timeout;
41
- const response = await (options.fetch ?? globalThis.fetch)(`${RUNTIME_REGISTRY}${encodeURIComponent(BUDDY_RUNTIME_PACKAGE)}${suffix}`, {
42
- signal,
43
- headers: { Accept: "application/json" },
44
- redirect: "error"
45
- });
46
- if (!response.ok) throw new Error(`npm \u8FD4\u56DE HTTP ${response.status}`);
47
- return response.json();
48
- }
49
61
  async function cachedRuntimeRoot(version, options = {}) {
50
62
  if (!isExactRuntimeVersion(version)) throw new Error("Runtime \u7F13\u5B58\u9700\u8981\u51C6\u786E\u7248\u672C");
51
63
  const cache = options.cacheDirectory ?? join(homedir(), ".cache", "buddy-cli-sit", "runtimes");
@@ -229,7 +241,7 @@ import { lstat as lstat2, mkdir as mkdir2, mkdtemp as mkdtemp2, readFile as read
229
241
  import { homedir as homedir2 } from "node:os";
230
242
  import { isAbsolute, join as join2 } from "node:path";
231
243
  import { promisify as promisify2 } from "node:util";
232
- var REGISTRY = "https://registry.npmjs.org/";
244
+ var REGISTRY2 = "https://registry.npmjs.org/";
233
245
  var execute2 = promisify2(execFile2);
234
246
  var VERSION = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/u;
235
247
  function validSkillLock(value, protocolVersions2 = [1]) {
@@ -301,21 +313,14 @@ async function resolveSkillPackage(definition3, previous, options = {}) {
301
313
  options.signal?.throwIfAborted();
302
314
  const version = options.version ?? pinned?.version ?? "latest";
303
315
  options.report?.(`\u6B63\u5728\u67E5\u8BE2 ${definition3.label} Skill ${version}\u2026`);
304
- let response;
316
+ let pkg;
305
317
  try {
306
- response = await (options.fetch ?? globalThis.fetch)(`${REGISTRY}${encodeURIComponent(definition3.name)}/${version}`, {
307
- headers: { Accept: "application/json" },
308
- redirect: "error",
309
- signal: options.signal ? AbortSignal.any([options.signal, AbortSignal.timeout(15e3)]) : AbortSignal.timeout(15e3)
310
- });
311
- } catch {
318
+ pkg = await npmPackageManifest(definition3.name, version, { ...options, timeoutMs: 15e3 });
319
+ } catch (cause) {
312
320
  options.signal?.throwIfAborted();
313
- throw new Error(`\u65E0\u6CD5\u67E5\u8BE2 ${definition3.label} Skill ${version}\uFF0C\u8BF7\u68C0\u67E5 npm \u7F51\u7EDC\u540E\u91CD\u8BD5\uFF1B\u672A\u4F7F\u7528\u65E7\u7248\u672C\uFF0C\u5DF2\u6709\u4F5C\u54C1\u4F1A\u4FDD\u7559\u3002`);
321
+ throw new Error(`\u65E0\u6CD5\u67E5\u8BE2 ${definition3.label} Skill ${version}\uFF08${cause instanceof Error ? cause.message : "npm \u8BF7\u6C42\u5931\u8D25"}\uFF09\uFF0C\u8BF7\u68C0\u67E5 npm \u7F51\u7EDC\u540E\u91CD\u8BD5\uFF1B\u672A\u4F7F\u7528\u65E7\u7248\u672C\uFF0C\u5DF2\u6709\u4F5C\u54C1\u4F1A\u4FDD\u7559\u3002`);
314
322
  }
315
- if (!response.ok) throw new Error(`\u65E0\u6CD5\u83B7\u53D6 ${definition3.label} Skill\uFF08npm HTTP ${response.status}\uFF09\u3002\u8BF7\u68C0\u67E5\u7F51\u7EDC\u540E\u91CD\u8BD5\uFF0C\u5DF2\u6709\u4F5C\u54C1\u4F1A\u4FDD\u7559\u3002`);
316
- const text2 = await response.text();
317
- if (text2.length > 512 * 1024) throw new Error(`${definition3.label} npm \u5143\u6570\u636E\u8FC7\u5927\u3002`);
318
- const pkg = JSON.parse(text2);
323
+ if (JSON.stringify(pkg).length > 512 * 1024) throw new Error(`${definition3.label} npm \u5143\u6570\u636E\u8FC7\u5927\u3002`);
319
324
  checkProtocol(definition3, pkg);
320
325
  if (version !== "latest" && pkg.version !== version) throw new Error(`npm \u8FD4\u56DE\u4E86\u4E0D\u540C\u7684 ${definition3.label} \u7248\u672C\u3002`);
321
326
  const lock = { source: "npm", version: pkg.version, integrity: pkg.dist?.integrity, protocolVersion: pkg.buddySkill.protocolVersion };
@@ -329,7 +334,7 @@ async function resolveSkillPackage(definition3, previous, options = {}) {
329
334
  try {
330
335
  await writeFile2(join2(temporary, "package.json"), JSON.stringify({ name: "buddy-skill-cache", private: true, dependencies: { [definition3.name]: lock.version } }));
331
336
  const config = join2(temporary, ".npmrc");
332
- await writeFile2(config, `registry=${REGISTRY}
337
+ await writeFile2(config, `registry=${REGISTRY2}
333
338
  `);
334
339
  options.report?.(`\u6B63\u5728\u4E0B\u8F7D ${definition3.label} Skill ${lock.version}\u2026`);
335
340
  const run = options.runNpm ?? ((args, settings) => execute2("npm", args, { ...settings, encoding: "utf8", maxBuffer: 2 * 1024 * 1024 }));
@@ -341,8 +346,8 @@ async function resolveSkillPackage(definition3, previous, options = {}) {
341
346
  "--omit=dev",
342
347
  "--no-audit",
343
348
  "--no-fund",
344
- `--registry=${REGISTRY}`,
345
- ...definition3.name.startsWith("@") ? [`--${definition3.name.split("/")[0]}:registry=${REGISTRY}`] : [],
349
+ `--registry=${REGISTRY2}`,
350
+ ...definition3.name.startsWith("@") ? [`--${definition3.name.split("/")[0]}:registry=${REGISTRY2}`] : [],
346
351
  `--userconfig=${config}`,
347
352
  "--fetch-retries=0",
348
353
  "--fetch-timeout=20000"
@@ -381,7 +386,8 @@ var resolveAvatarSkill = (previous, options = {}) => resolveSkillPackage(definit
381
386
 
382
387
  // packages/cli-core/src/cloud/avatar.ts
383
388
  import { open } from "node:fs/promises";
384
- import { basename } from "node:path";
389
+ import { basename, extname } from "node:path";
390
+ import sharp from "sharp";
385
391
  var MAX_BUDDY_AVATAR_BYTES = 5 * 1024 * 1024;
386
392
  async function readBuddyAvatarFile(path) {
387
393
  const file = await open(path, "r");
@@ -405,6 +411,33 @@ async function readBuddyAvatarFile(path) {
405
411
  await file.close();
406
412
  }
407
413
  }
414
+ async function prepareBuddyAvatarUpload(source) {
415
+ const input = Buffer.from(source.bytes);
416
+ if (!input.length || input.length > MAX_BUDDY_AVATAR_BYTES) throw new Error("\u5934\u50CF\u4E0D\u80FD\u4E3A\u7A7A\u4E14\u4E0D\u80FD\u8D85\u8FC7 5 MiB");
417
+ if (source.mediaType === "image/png") {
418
+ for (let at = 8; at + 12 <= input.length; ) {
419
+ const length = input.readUInt32BE(at);
420
+ if (input.toString("ascii", at + 4, at + 8) === "acTL") throw new Error("\u4EC5\u652F\u6301\u9759\u6001\u5934\u50CF\uFF0C\u4E0D\u652F\u6301\u52A8\u56FE");
421
+ at += length + 12;
422
+ }
423
+ }
424
+ const image = sharp(input, { failOn: "warning", limitInputPixels: 4096 * 4096 });
425
+ let meta2;
426
+ try {
427
+ meta2 = await image.metadata();
428
+ } catch {
429
+ throw new Error("\u56FE\u7247\u65E0\u6CD5\u89E3\u7801\u6216\u50CF\u7D20\u8FC7\u5927\uFF0C\u8BF7\u9009\u62E9\u5BBD\u9AD8\u4E0D\u8D85\u8FC7 4096 px \u7684\u9759\u6001 PNG\u3001JPEG\u3001WebP");
430
+ }
431
+ if (!["png", "jpeg", "webp"].includes(meta2.format ?? "")) throw new Error("\u4EC5\u652F\u6301 PNG\u3001JPEG\u3001WebP \u56FE\u7247\u6587\u4EF6");
432
+ if ((meta2.pages ?? 1) !== 1) throw new Error("\u4EC5\u652F\u6301\u9759\u6001\u5934\u50CF\uFF0C\u4E0D\u652F\u6301\u52A8\u56FE");
433
+ if (!meta2.width || !meta2.height || meta2.width > 4096 || meta2.height > 4096) throw new Error("\u5934\u50CF\u5BBD\u9AD8\u4E0D\u80FD\u8D85\u8FC7 4096 px");
434
+ try {
435
+ const bytes = await image.rotate().resize(512, 512, { fit: "cover", position: "centre" }).webp({ lossless: true }).timeout({ seconds: 10 }).toBuffer();
436
+ return { bytes, mediaType: "image/webp", fileName: `${basename(source.fileName, extname(source.fileName))}.webp` };
437
+ } catch {
438
+ throw new Error("\u5934\u50CF\u5904\u7406\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u56FE\u7247\u662F\u5426\u5B8C\u6574\uFF0C\u6216\u6362\u4E00\u5F20\u56FE\u7247\u91CD\u8BD5");
439
+ }
440
+ }
408
441
 
409
442
  // packages/cli-core/src/process-lock.ts
410
443
  import { randomUUID } from "node:crypto";
@@ -542,9 +575,10 @@ async function save(path, content) {
542
575
  });
543
576
  }
544
577
  }
545
- async function readImage(path) {
578
+ async function readImage(path, { forUpload = false } = {}) {
546
579
  try {
547
- return await readBuddyAvatarFile(path);
580
+ const source = await readBuddyAvatarFile(path);
581
+ return forUpload ? await prepareBuddyAvatarUpload(source) : source;
548
582
  } catch (error2) {
549
583
  throw new MetaPreparationError(`\u5934\u50CF\u672A\u5B8C\u6210\uFF1A${error2 instanceof Error ? error2.message : "\u65E0\u6CD5\u8BFB\u53D6\u56FE\u7247"}\u3002\u672C\u5730\u8D44\u6599\u5DF2\u4FDD\u7559\uFF0C\u5C1A\u672A\u63D0\u4EA4\u8FD9\u5F20\u5934\u50CF\u3002`);
550
584
  }
@@ -674,7 +708,7 @@ async function prepareLockedMeta(options) {
674
708
  io.write(`\u5934\u50CF\u672A\u5B8C\u6210\uFF0C\u5DF2\u4FDD\u5B58\u672C\u5730\u8D44\u6599\uFF0C\u5C1A\u672A\u521B\u5EFA\u4E91\u7AEF\u642D\u5B50\u3002\u8BF7\u8BA9 Coding Agent \u8BFB\u53D6 ${join4(folder(root), "HANDOFF.md")}\uFF1B\u6216\u4F7F\u7528 --avatar <\u56FE\u7247\u8DEF\u5F84> \u7EE7\u7EED\u3002`);
675
709
  return void 0;
676
710
  }
677
- const upload = await readImage(join4(folder(root), draft.avatarPath));
711
+ const upload = await readImage(join4(folder(root), draft.avatarPath), { forUpload: true });
678
712
  const confirmation = hash(JSON.stringify([profile.name, profile.tagline, profile.intro, hash(upload.bytes)]));
679
713
  const preview = join4(folder(root), "preview.html");
680
714
  await save(preview, `<!doctype html><html lang="zh-CN"><meta charset="utf-8"><title>\u786E\u8BA4\u642D\u5B50\u8D44\u6599\u4E0E\u5934\u50CF</title><style>body{font:18px system-ui;max-width:800px;margin:48px auto;padding:24px;color:#163342}p{white-space:pre-wrap}section{display:flex;gap:24px}figure{margin:0;padding:24px;background:#eef4f8;border-radius:12px}figure.dark{background:#183040}img{width:220px;height:220px;object-fit:contain;border-radius:50%}</style><h1>${escape(profile.name)}</h1><p>${escape(profile.tagline)}</p><p>${escape(profile.intro)}</p><section><figure><img alt="\u6D45\u8272\u80CC\u666F\u5934\u50CF" src="data:${upload.mediaType};base64,${Buffer.from(upload.bytes).toString("base64")}"></figure><figure class="dark"><img alt="\u6DF1\u8272\u80CC\u666F\u5934\u50CF" src="data:${upload.mediaType};base64,${Buffer.from(upload.bytes).toString("base64")}"></figure></section><p>\u67E5\u770B\u5934\u50CF\u548C\u8D44\u6599\u540E\uFF0C\u56DE\u5230\u7EC8\u7AEF\u786E\u8BA4\u3002\u6B64\u9875\u9762\u4E0D\u4F1A\u4E0A\u4F20\u4EFB\u4F55\u5185\u5BB9\u3002</p></html>`);
@@ -2546,7 +2580,7 @@ ${DEVELOPMENT_HANDOFF_SUMMARY}
2546
2580
 
2547
2581
  \u5F00\u53D1\u8005\u660E\u786E\u8981\u6C42\u81EA\u52A8\u4F53\u9A8C\u6216\u591A\u573A\u666F\u56DE\u5F52\u65F6\uFF0C\u6309\u6307\u5B9A\u8303\u56F4\u6267\u884C\uFF0C\u62A5\u544A\u7ED3\u679C\uFF0C\u4E0D\u628A\u6D4B\u8BD5\u6388\u6743\u6269\u5927\u4E3A\u6539\u9700\u6C42\u6216\u63D0\u5BA1\u6388\u6743\u3002push\u3001\u53D1\u5E03\u548C\u6536\u8D39\u64CD\u4F5C\u4E0D\u5C5E\u4E8E\u9ED8\u8BA4\u4EA4\u63A5\uFF0C\u9700\u8981\u53E6\u884C\u660E\u786E\u6388\u6743\u3002
2548
2582
 
2549
- \u9700\u8981\u91CD\u65B0\u6253\u5F00\u65F6\uFF0C\u4F7F\u7528 \`buddy-cli-sit preview\`\uFF0C\u6216\u4ECE\u540E\u53F0\u300C\u83B7\u53D6\u8FDE\u63A5\u6307\u4EE4\u300D\u53D6\u5F97\u5E26\u642D\u5B50 ID \u548C\u73AF\u5883\u7684\u5B8C\u6574\u547D\u4EE4\uFF0C\u5728\u6B63\u786E\u5DE5\u7A0B\u76EE\u5F55\u6267\u884C\u3002\u540E\u53F0\u590D\u5236\u7684\u547D\u4EE4\u5E26 \`--no-open\`\uFF0C\u6267\u884C\u540E\u8FD4\u56DE\u539F\u8C03\u8BD5\u9875\uFF0C\u4E0D\u91CD\u590D\u6253\u5F00\u7F51\u9875\uFF1B\u9875\u9762\u5DF2\u5173\u95ED\u65F6\u6253\u5F00\u7EC8\u7AEF\u6253\u5370\u7684\u5730\u5740\u3002\u540E\u53F0\u663E\u793A\u300C\u672A\u8FDE\u63A5\u672C\u5730\u5DE5\u7A0B\u300D\u300C\u5DF2\u8FDE\u63A5\u4F46 DEV \u672A\u542F\u52A8\u300D\u300CDEV \u8FD0\u884C\u4E2D\u300D\u3002\u5237\u65B0\u4E0D\u4F1A\u542F\u52A8 DEV\uFF1BCLI \u9000\u51FA\u4F1A\u505C\u6B62 DEV\u3002\u53EA\u6709\u540E\u53F0\u4E0D\u53EF\u7528\u65F6\u4F7F\u7528 \`buddy-cli-sit preview --local\` \u5907\u7528\u5165\u53E3\uFF0C\u5E76\u660E\u786E\u8BF4\u660E\u5907\u7528\u539F\u56E0\u3002
2583
+ \u9700\u8981\u91CD\u65B0\u6253\u5F00\u65F6\uFF0C\u4F7F\u7528 \`buddy-cli-sit preview\`\uFF0C\u6216\u4ECE\u540E\u53F0\u300C\u83B7\u53D6\u8FDE\u63A5\u6307\u4EE4\u300D\u53D6\u5F97\u5E26\u642D\u5B50 ID \u548C\u73AF\u5883\u7684\u5B8C\u6574\u547D\u4EE4\uFF0C\u5728\u6B63\u786E\u5DE5\u7A0B\u76EE\u5F55\u6267\u884C\u3002\u540E\u53F0\u590D\u5236\u7684\u547D\u4EE4\u5E26 \`--no-open\`\uFF0C\u6267\u884C\u540E\u8FD4\u56DE\u539F\u8C03\u8BD5\u9875\uFF0C\u4E0D\u91CD\u590D\u6253\u5F00\u7F51\u9875\uFF1B\u9875\u9762\u5DF2\u5173\u95ED\u65F6\u6253\u5F00\u7EC8\u7AEF\u6253\u5370\u7684\u5730\u5740\u3002\u540E\u53F0\u663E\u793A\u300C\u672A\u8FDE\u63A5\u672C\u5730\u5DE5\u7A0B\u300D\u300C\u5DF2\u8FDE\u63A5\u4F46 DEV \u672A\u542F\u52A8\u300D\u300CDEV \u8FD0\u884C\u4E2D\u300D\u3002\u5237\u65B0\u4E0D\u4F1A\u542F\u52A8 DEV\uFF1BCLI \u9000\u51FA\u4F1A\u505C\u6B62 DEV\u3002\u8C03\u8BD5\u9875\u9762\u7EDF\u4E00\u7531\u540E\u53F0\u63D0\u4F9B\uFF0C\u4E0D\u518D\u652F\u6301\u72EC\u7ACB\u672C\u5730\u7F51\u9875\uFF1B\u540E\u53F0\u4E0D\u53EF\u7528\u65F6\u4FDD\u7559\u5DE5\u7A0B\u4E0E\u73B0\u6709\u8FDE\u63A5\u4FE1\u606F\uFF0C\u4F7F\u7528\u7EC8\u7AEF DEV \u548C\u65E5\u5FD7\u6392\u67E5\u3002
2550
2584
 
2551
2585
  \u7528\u6237\u660E\u786E\u53EA\u505A\u8BBE\u8BA1\u3001\u521D\u59CB\u5316\u3001\u4EE3\u7801\u4FEE\u6539\u6216\u8981\u6C42\u6682\u505C\u65F6\uFF0C\u4EE5\u8BE5\u8303\u56F4\u4E3A\u51C6\uFF0C\u4E0D\u5F3A\u5236\u542F\u52A8\u9884\u89C8\u3002`;
2552
2586
 
@@ -3380,7 +3414,6 @@ var CLI_HELP = `\u642D\u642D Developer Platform CLI
3380
3414
  preview \u8FDE\u63A5\u5DE5\u7A0B\u5E76\u6253\u5F00\u540E\u53F0\u5F00\u53D1\u8C03\u8BD5
3381
3415
  push \u4E0A\u4F20\u7A0B\u5E8F\u5305\uFF0C\u53EF\u7528 --product \u540C\u6B65\u63D0\u4EA4\u5546\u54C1\u5BA1\u6838
3382
3416
  products \u4E3A\u5DF2\u6709\u7248\u672C\u8865\u63D0\u5546\u54C1\uFF0C\u6216\u6062\u590D\u539F\u63D0\u5BA1\u8BF7\u6C42
3383
- release \u4ECE\u660E\u786E\u56DE\u6267\u53D1\u5E03\uFF0C\u67E5\u8BE2\u3001\u6062\u590D\u3001\u91CD\u8BD5\u6216\u53D6\u6D88\u53D1\u5E03
3384
3417
  status \u67E5\u770B\u4E91\u7AEF\u7248\u672C\u3001\u8FD0\u884C\u3001\u5BA1\u6838\u548C\u6784\u5EFA\u72B6\u6001
3385
3418
  meta \u67E5\u770B\u4E91\u7AEF\u8D44\u6599\uFF1Bmeta update \u4FEE\u6539\u8D44\u6599\u6216\u66FF\u6362\u5934\u50CF
3386
3419
  avatar \u65E7\u5934\u50CF\u547D\u4EE4\u517C\u5BB9\u5165\u53E3\uFF0C\u63A8\u8350 meta update --avatar
@@ -3421,6 +3454,7 @@ direct \u751F\u6210\u65B0\u4E1A\u52A1\u5DE5\u5382\u524D\uFF0C\u6309\u6700\u65B0
3421
3454
  \u540C\u76EE\u5F55\u6062\u590D\u4FDD\u7559\u5DF2\u6709\u4E1A\u52A1\u6587\u4EF6\u3002create \u540E\u6309 .buddy/creator/HANDOFF.md \u7EE7\u7EED\uFF0Cdirect \u540E\u5B89\u88C5\u4F9D\u8D56\u5E76\u5B9E\u73B0\u4E1A\u52A1\u3002
3422
3455
  Creator \u6BCF\u6B21\u8FDB\u5165\u6216\u6062\u590D\u90FD\u67E5\u8BE2\u516C\u5171 npm latest\uFF1B\u6709 Creator \u8BB0\u5F55\u7684\u5B8C\u6574\u5DE5\u7A0B\u4E5F\u53EF\u6267\u884C create \u63A5\u7EED\u521B\u4F5C\uFF0C\u4E0D\u91CD\u5EFA\u4E1A\u52A1\u6587\u4EF6\u3002
3423
3456
  \u5DF2\u767B\u8BB0\u642D\u5B50\u7684\u540D\u79F0\u3001\u4ECB\u7ECD\u6216\u5934\u50CF\u7528 buddy-cli-sit meta update \u4FEE\u6539\uFF1Binit \u4E0D\u8986\u76D6\u4E91\u7AEF\u8D44\u6599\u3002
3457
+ \u5934\u50CF\u4E0A\u4F20\u8BF7\u6C42\u6700\u591A\u7B49\u5F85 5 \u5206\u949F\uFF0CCLI \u4E0A\u4F20\u524D\u5C45\u4E2D\u88C1\u5207\u81F3 512\xD7512 \u65E0\u635F WebP\uFF0C\u4FDD\u7559\u989C\u8272\u3001\u900F\u660E\u5EA6\u4E0E\u539F\u59CB\u6587\u4EF6\uFF1B\u666E\u901A\u8BF7\u6C42\u4ECD\u4E3A 30 \u79D2\u3002
3424
3458
 
3425
3459
  \u793A\u4F8B:
3426
3460
  buddy-cli-sit init --mode direct --directory ./my-buddy --name "\u505A\u996D\u642D\u5B50" --tagline "\u5E2E\u4F60\u5B89\u6392\u665A\u996D" --intro "\u6839\u636E\u73B0\u6709\u98DF\u6750\u63A8\u8350\u83DC\u8C31"
@@ -5393,21 +5427,12 @@ function parsePackagePush(value) {
5393
5427
  if (operationId(p.pushId) !== metadata.pushId) invalid2("\u4E0A\u4F20\u56DE\u6267 ID \u4E0E\u5143\u6570\u636E\u4E0D\u5339\u914D");
5394
5428
  return { pushId: metadata.pushId, uploadVersion: p.uploadVersion, status: p.status, metadata, reviewIds: selectedReviewIds(p.reviewIds), failure: p.failure ?? null };
5395
5429
  }
5396
- function parseProductRelease(value) {
5397
- const r = record(value);
5398
- if (r.mode !== "with_buddy" && r.mode !== "products_only") invalid2("\u53D1\u5E03\u6A21\u5F0F\u65E0\u6548");
5399
- if (!["accepted", "activating", "active", "failed", "cancelled"].includes(String(r.status))) invalid2("\u53D1\u5E03\u64CD\u4F5C\u72B6\u6001\u65E0\u6548");
5400
- if (typeof r.buddyVersion !== "string" || !r.buddyVersion.trim() || /[\u0000-\u001f\u007f]/u.test(r.buddyVersion)) invalid2("\u53D1\u5E03\u7248\u672C\u65E0\u6548");
5401
- return { releaseId: operationId(r.releaseId), mode: r.mode, buddyVersion: r.buddyVersion, reviewIds: selectedReviewIds(r.reviewIds), status: r.status, ...r.failure === void 0 ? {} : { failure: r.failure } };
5402
- }
5403
5430
  var CloudOperationError = class extends CloudLifecycleError {
5404
- constructor(code2, message, details, push, release) {
5431
+ constructor(code2, message, details, push) {
5405
5432
  super(code2, message, details);
5406
5433
  this.push = push;
5407
- this.release = release;
5408
5434
  }
5409
5435
  push;
5410
- release;
5411
5436
  };
5412
5437
  function sameReviewIds(a, b) {
5413
5438
  return [...a].sort().join("\0") === [...b].sort().join("\0");
@@ -5445,7 +5470,7 @@ var OperationStore = class {
5445
5470
  }
5446
5471
  async save(record3) {
5447
5472
  const prior = await this.read(record3.id, record3.kind);
5448
- const input = (r) => r.kind === "push" ? r.metadata : r.kind === "release" ? r.request : { version: r.version, reviews: r.reviews };
5473
+ const input = (r) => r.kind === "push" ? r.metadata : { version: r.version, reviews: r.reviews };
5449
5474
  if (JSON.stringify(input(prior)) !== JSON.stringify(input(record3))) throw new CloudLifecycleError("INVALID_REQUEST", "\u6062\u590D\u8BB0\u5F55\u7684\u539F\u59CB\u8BF7\u6C42\u4E0D\u80FD\u66F4\u6539");
5450
5475
  const temporary = this.path(`${record3.id}_${randomUUID8()}`);
5451
5476
  await writeFile8(temporary, JSON.stringify({ identity: this.identity, operation: record3 }), { flag: "wx", mode: 384 });
@@ -5461,11 +5486,6 @@ var OperationStore = class {
5461
5486
  if (r.metadata.pushId !== id) throw new Error("push mismatch");
5462
5487
  if (r.receipt) parsePackagePush(r.receipt);
5463
5488
  }
5464
- if (r.kind === "release") {
5465
- parseProductRelease({ ...r.request, status: "accepted" });
5466
- if (r.request.releaseId !== id) throw new Error("release mismatch");
5467
- if (r.receipt) parseProductRelease(r.receipt);
5468
- }
5469
5489
  if (r.kind === "submission") {
5470
5490
  if (typeof r.version !== "string" || !r.version.trim() || typeof r.confirmed !== "boolean" || r.reviews.length === 0) throw new Error("submission invalid");
5471
5491
  parsePushMetadata({ pushId: id, commit: "validate", sourceSha256: "0".repeat(64), productReviews: r.reviews });
@@ -5490,7 +5510,7 @@ var OperationStore = class {
5490
5510
  var PRODUCT_HELP = {
5491
5511
  push: `\u7528\u6CD5: buddy-cli-sit push --commit <\u6539\u52A8\u8BF4\u660E> [--product <\u5546\u54C1 ID> ...] [--directory <\u76EE\u5F55>]
5492
5512
  buddy-cli-sit push --resume <pushId> | --status <pushId> [--directory <\u76EE\u5F55>]
5493
- \u4E0A\u4F20\u4EE3\u7801\u5E76\u63D0\u4EA4\u660E\u786E\u9009\u4E2D\u7684\u5546\u54C1\uFF1B\u4E0D\u6307\u5B9A --product \u53EA\u4E0A\u4F20\u4EE3\u7801\u3002\u4E0D\u4F1A\u81EA\u52A8\u53D1\u5E03\u3002
5513
+ \u4E0A\u4F20\u4EE3\u7801\u5E76\u63D0\u4EA4\u660E\u786E\u9009\u4E2D\u7684\u5546\u54C1\uFF1B\u4E0D\u6307\u5B9A --product \u53EA\u4E0A\u4F20\u4EE3\u7801\u3002\u53D1\u5E03\u5728\u5F00\u53D1\u8005\u540E\u53F0\u64CD\u4F5C\u3002
5494
5514
  \u5546\u54C1 ID \u793A\u4F8B\uFF1Aprd_12345678\uFF1B\u5DF2\u6709 ps_ \u5546\u54C1 ID \u7EE7\u7EED\u517C\u5BB9\u3002
5495
5515
  \u9996\u6B21\u4E0A\u4F20\u5FC5\u987B\u5B89\u88C5 npm dev \u6700\u65B0 Runtime \u7684\u51C6\u786E\u7248\u672C\uFF1B\u91CD\u8BD5\u56FA\u5B9A\u4F7F\u7528\u539F\u59CB\u5305\u3001\u8349\u7A3F\u7248\u672C\u548C\u5BA1\u6838 ID\u3002
5496
5516
  \u7F51\u7EDC\u7ED3\u679C\u672A\u77E5\u65F6\u8BF7\u4F7F\u7528\u8F93\u51FA\u7684 --resume\uFF1B--status \u53EA\u67E5\u8BE2\u3002\u4E0D\u8981\u91CD\u65B0\u4E0A\u4F20\u3002`,
@@ -5498,13 +5518,7 @@ var PRODUCT_HELP = {
5498
5518
  buddy-cli-sit products submit --resume <submissionId> [--directory <\u76EE\u5F55>]
5499
5519
  \u7528\u4E8E\u5DF2\u4E0A\u4F20\u7248\u672C\u8865\u63D0\u5546\u54C1\uFF1B\u6B63\u5E38 push --product \u5DF2\u81EA\u52A8\u63D0\u5BA1\uFF0C\u65E0\u9700\u91CD\u590D\u6267\u884C\u3002
5500
5520
  \u5546\u54C1 ID \u793A\u4F8B\uFF1Aprd_12345678\uFF1B\u5DF2\u6709 ps_ \u5546\u54C1 ID \u7EE7\u7EED\u517C\u5BB9\u3002
5501
- \u6062\u590D\u4F7F\u7528\u9996\u6B21\u6301\u4E45\u4FDD\u5B58\u7684\u5546\u54C1\u96C6\u5408\u3001\u5BA1\u6838 ID \u548C\u8349\u7A3F\u7248\u672C\u3002`,
5502
- release: `\u7528\u6CD5: buddy-cli-sit release (--from-push <pushId> | --from-submission <submissionId>) [--products-only] [--directory <\u76EE\u5F55>]
5503
- buddy-cli-sit release --version <\u7248\u672C> --code-only [--directory <\u76EE\u5F55>]
5504
- buddy-cli-sit release (--resume | --status | --retry | --cancel) <releaseId> [--directory <\u76EE\u5F55>]
5505
- \u53D1\u5E03\u53EA\u91C7\u7528\u6307\u5B9A\u6210\u529F\u56DE\u6267\u4E2D\u7684\u5BA1\u6838\u96C6\u5408\uFF1B\u5546\u54C1\u5931\u8D25\u4E0D\u4F1A\u81EA\u52A8\u964D\u7EA7\u4E3A\u7EAF\u4EE3\u7801\u53D1\u5E03\u3002
5506
- \u9ED8\u8BA4\u968F\u642D\u5B50\u7248\u672C\u4E00\u8D77\u53D1\u5E03\uFF1B--products-only \u53EA\u6FC0\u6D3B\u5546\u54C1\u5E76\u6838\u5BF9\u5F53\u524D\u7EBF\u4E0A\u7248\u672C\u3002
5507
- \u4EC5 active \u8868\u793A\u5DF2\u751F\u6548\uFF1Baccepted/activating \u8BF7\u7528 --status \u67E5\u8BE2\u3002`
5521
+ \u6062\u590D\u4F7F\u7528\u9996\u6B21\u6301\u4E45\u4FDD\u5B58\u7684\u5546\u54C1\u96C6\u5408\u3001\u5BA1\u6838 ID \u548C\u8349\u7A3F\u7248\u672C\u3002\u5BA1\u6838\u901A\u8FC7\u540E\u5728\u5F00\u53D1\u8005\u540E\u53F0\u53D1\u5E03\u3002`
5508
5522
  };
5509
5523
  function parse2(command, args) {
5510
5524
  if (command === "products") {
@@ -5513,15 +5527,11 @@ function parse2(command, args) {
5513
5527
  }
5514
5528
  const values = /* @__PURE__ */ new Map();
5515
5529
  const products = [];
5516
- const allowed = command === "push" ? ["--commit", "--resume", "--status", "--product"] : command === "products" ? ["--version", "--resume", "--product"] : ["--from-push", "--from-submission", "--version", "--code-only", "--products-only", "--resume", "--status", "--retry", "--cancel"];
5530
+ const allowed = command === "push" ? ["--commit", "--resume", "--status", "--product"] : ["--version", "--resume", "--product"];
5517
5531
  for (let i = 0; i < args.length; i++) {
5518
5532
  const flag2 = args[i];
5519
5533
  if (flag2 !== "--directory" && !allowed.includes(flag2)) throw new CloudCommandUsageError(`\u672A\u77E5\u53C2\u6570 ${flag2}`);
5520
5534
  if (flag2 !== "--product" && values.has(flag2)) throw new CloudCommandUsageError(`${flag2} \u4E0D\u80FD\u91CD\u590D`);
5521
- if (["--code-only", "--products-only"].includes(flag2)) {
5522
- values.set(flag2, "true");
5523
- continue;
5524
- }
5525
5535
  const value = args[++i];
5526
5536
  if (!value?.trim() || value.startsWith("--") || /[\u0000-\u001f\u007f]/u.test(value)) throw new CloudCommandUsageError(`${flag2} \u7F3A\u5C11\u6709\u6548\u503C`);
5527
5537
  if (flag2 === "--product") {
@@ -5530,12 +5540,12 @@ function parse2(command, args) {
5530
5540
  } else values.set(flag2, value.trim());
5531
5541
  }
5532
5542
  if (products.length > 10) throw new CloudCommandUsageError("\u4E00\u6B21\u6700\u591A\u9009\u62E9 10 \u4E2A\u5546\u54C1");
5533
- const recovery = ["--resume", "--status", "--retry", "--cancel"].filter((f) => values.has(f));
5543
+ const recovery = ["--resume", "--status"].filter((f) => values.has(f));
5534
5544
  if (recovery.length && (recovery.length !== 1 || products.length || [...values.keys()].some((f) => f !== "--directory" && !recovery.includes(f)))) throw new CloudCommandUsageError("\u6062\u590D\u6216\u67E5\u8BE2\u547D\u4EE4\u4E0D\u80FD\u540C\u65F6\u66F4\u6539\u539F\u59CB\u8BF7\u6C42");
5535
5545
  return { values, products };
5536
5546
  }
5537
5547
  function required(value) {
5538
- if (!value) throw new CloudCommandUsageError("\u5E73\u53F0 Adapter \u5C1A\u672A\u652F\u6301\u5546\u54C1\u4E0A\u4F20\u548C\u53D1\u5E03\u534F\u8BAE\uFF0C\u8BF7\u5347\u7EA7 Adapter");
5548
+ if (!value) throw new CloudCommandUsageError("\u5E73\u53F0 Adapter \u5C1A\u672A\u652F\u6301\u5546\u54C1\u4E0A\u4F20\u548C\u63D0\u5BA1\u534F\u8BAE\uFF0C\u8BF7\u5347\u7EA7 Adapter");
5539
5549
  return value;
5540
5550
  }
5541
5551
  function responseError(message) {
@@ -5571,10 +5581,10 @@ function showPush(io, push) {
5571
5581
  if (failureMessage(push.failure)) io.writeError(`\u539F\u56E0\uFF1A${failureMessage(push.failure)}`);
5572
5582
  if (push.reviewIds.length) io.write(`\u5546\u54C1\u5BA1\u6838\u7F16\u53F7\uFF1A${push.reviewIds.join(", ")}`);
5573
5583
  if (push.status === "completed") {
5574
- io.write(`\u672C\u6B21 push \u4E0D\u4F1A\u53D1\u5E03\u642D\u5B50\uFF1B\u786E\u8BA4\u4EE3\u7801\u53CA\u6240\u9009\u5546\u54C1\u5BA1\u6838\u7ED3\u679C\u540E\u4F7F\u7528 buddy-cli-sit release --from-push ${push.pushId}\u3002`);
5584
+ io.write("\u672C\u6B21 push \u4E0D\u4F1A\u53D1\u5E03\u642D\u5B50\uFF1B\u6784\u5EFA\u6210\u529F\u540E\uFF0C\u8BF7\u5230\u5F00\u53D1\u8005\u540E\u53F0\u201C\u7248\u672C\u4E0E\u53D1\u5E03\u201D\u786E\u8BA4\u4EE3\u7801\u53CA\u6240\u9009\u5546\u54C1\u5BA1\u6838\u7ED3\u679C\u540E\u53D1\u5E03\u3002");
5575
5585
  return 0;
5576
5586
  }
5577
- if (push.status === "product_reviews_failed") io.writeError(`\u4EE3\u7801\u5305\u5DF2\u4FDD\u5B58\uFF0C\u5546\u54C1\u672A\u5B8C\u6574\u63D0\u5BA1\u3002\u4FEE\u6B63\u5546\u54C1\u540E\u4F7F\u7528 products submit --version ${push.uploadVersion} --product <\u5546\u54C1 ID> \u8865\u63D0\uFF1B\u7EAF\u4EE3\u7801\u53D1\u5E03\u987B\u660E\u786E --code-only\u3002`);
5587
+ if (push.status === "product_reviews_failed") io.writeError(`\u4EE3\u7801\u5305\u5DF2\u4FDD\u5B58\uFF0C\u5546\u54C1\u672A\u5B8C\u6574\u63D0\u5BA1\u3002\u4FEE\u6B63\u5546\u54C1\u540E\u4F7F\u7528 buddy-cli-sit products submit --version ${push.uploadVersion} --product <\u5546\u54C1 ID> \u8865\u63D0\uFF1B\u53D1\u5E03\u8BF7\u5230\u5F00\u53D1\u8005\u540E\u53F0\u201C\u7248\u672C\u4E0E\u53D1\u5E03\u201D\u64CD\u4F5C\u3002`);
5578
5588
  else io.writeError(`\u4E0A\u4F20\u672A\u5B8C\u6210\uFF0C\u4F7F\u7528 buddy-cli-sit push --resume ${push.pushId} \u6062\u590D\u539F\u8BF7\u6C42\u3002`);
5579
5589
  return 1;
5580
5590
  }
@@ -5614,23 +5624,6 @@ async function executePush(record3, sourceBundle, store, client, id, io, options
5614
5624
  throw cause;
5615
5625
  }
5616
5626
  }
5617
- function matchRelease(request, release) {
5618
- if (request.releaseId !== release.releaseId || request.mode !== release.mode || request.buddyVersion !== release.buddyVersion || !sameReviewIds(request.reviewIds, release.reviewIds)) responseError("\u53D1\u5E03\u56DE\u6267\u4E0E\u56FA\u5B9A\u8BF7\u6C42\u4E0D\u4E00\u81F4");
5619
- }
5620
- function showRelease(io, release) {
5621
- io.write(`\u53D1\u5E03\u7F16\u53F7\uFF1A${release.releaseId}`);
5622
- io.write(`\u53D1\u5E03\u72B6\u6001\uFF1A${release.status}`);
5623
- io.write(`\u76EE\u6807\u7248\u672C\uFF1A${release.buddyVersion}`);
5624
- if (failureMessage(release.failure)) io.writeError(`\u539F\u56E0\uFF1A${failureMessage(release.failure)}`);
5625
- if (release.status === "active") {
5626
- io.write("\u53D1\u5E03\u5DF2\u751F\u6548\u3002");
5627
- return 0;
5628
- }
5629
- if (release.status === "failed") io.writeError(`\u53D1\u5E03\u672A\u751F\u6548\u3002\u4FEE\u6B63\u539F\u56E0\u540E buddy-cli-sit release --retry ${release.releaseId}\uFF1B\u653E\u5F03\u5219 --cancel ${release.releaseId}\u3002`);
5630
- else if (release.status === "cancelled") io.write("\u8BE5\u53D1\u5E03\u5DF2\u53D6\u6D88\u3002");
5631
- else io.write(`\u53D1\u5E03\u4ECD\u5728\u5904\u7406\uFF0C\u8BF7\u8FD0\u884C buddy-cli-sit release --status ${release.releaseId} \u786E\u8BA4\u662F\u5426\u751F\u6548\u3002`);
5632
- return 1;
5633
- }
5634
5627
  async function runProductLifecycle(command, args, io, options) {
5635
5628
  if (args.length === 1 && ["--help", "-h"].includes(args[0]) || command === "products" && args.length === 2 && args[0] === "submit" && args[1] === "--help") {
5636
5629
  io.write(PRODUCT_HELP[command]);
@@ -5638,7 +5631,7 @@ async function runProductLifecycle(command, args, io, options) {
5638
5631
  }
5639
5632
  const p = parse2(command, args);
5640
5633
  const v = p.values;
5641
- if (options.mode === "local-mock") throw new CloudCommandUsageError("\u672C\u5730\u6A21\u62DF\u6A21\u5F0F\u4E0D\u4F1A\u4F2A\u9020\u6B63\u5F0F push \u6216\u53D1\u5E03\uFF0C\u8BF7\u8FDE\u63A5\u771F\u5B9E MLB Server");
5634
+ if (options.mode === "local-mock") throw new CloudCommandUsageError("\u672C\u5730\u6A21\u62DF\u6A21\u5F0F\u4E0D\u4F1A\u4F2A\u9020\u6B63\u5F0F push \u6216\u5546\u54C1\u63D0\u5BA1\uFF0C\u8BF7\u8FDE\u63A5\u771F\u5B9E MLB Server");
5642
5635
  const freshPush = command === "push" && !v.has("--resume") && !v.has("--status");
5643
5636
  const root = await (options.resolveProjectRoot ?? (freshPush ? requireBuddyAgentProjectRoot : requireBuddyProjectRoot))(resolve15(options.cwd ?? process.cwd(), v.get("--directory") ?? "."));
5644
5637
  const platform = resolvePlatformUrl({ env: options.runtimeUpdate?.env });
@@ -5679,83 +5672,25 @@ async function runProductLifecycle(command, args, io, options) {
5679
5672
  io.write(`\u6062\u590D\u7F16\u53F7\uFF1A${pushId}`);
5680
5673
  return executePush(record4, bundle, store, client, id, io, options);
5681
5674
  }
5682
- if (command === "products") {
5683
- let record4;
5684
- if (v.has("--resume")) record4 = await store.read(v.get("--resume"), "submission");
5685
- else {
5686
- const version = v.get("--version");
5687
- if (!version || !p.products.length) throw new CloudCommandUsageError(PRODUCT_HELP.products);
5688
- const chosen = await selection(client, id, p.products, io);
5689
- record4 = { kind: "submission", id: `sub_${randomUUID9()}`, version, reviews: chosen.reviews, confirmed: false };
5690
- await store.create(record4);
5691
- }
5692
- io.write(`\u5546\u54C1\u63D0\u4EA4\u7F16\u53F7\uFF1A${record4.id}`);
5693
- try {
5694
- const receipt = await required(client.submitPackageProducts).call(client, { id, version: record4.version, reviews: record4.reviews });
5695
- if (!sameReviewIds(receipt.reviewIds, record4.reviews.map((r) => r.reviewId))) responseError("\u5E73\u53F0\u672A\u786E\u8BA4\u5B8C\u6574\u5546\u54C1\u5BA1\u6838\u96C6\u5408");
5696
- await store.save({ ...record4, confirmed: true });
5697
- io.write(`\u5546\u54C1\u5DF2\u63D0\u4EA4\u5BA1\u6838\uFF1A${receipt.reviewIds.join(", ")}`);
5698
- io.write(`\u5BA1\u6838\u901A\u8FC7\u540E\uFF1Abuddy-cli-sit release --from-submission ${record4.id}`);
5699
- return { exitCode: 0, buddyId: id, version: record4.version };
5700
- } catch (cause) {
5701
- io.writeError(`\u4FDD\u7559\u539F\u8BF7\u6C42\u91CD\u8BD5\uFF1Abuddy-cli-sit products submit --resume ${record4.id}`);
5702
- throw cause;
5703
- }
5704
- }
5705
- const action = ["--resume", "--status", "--retry", "--cancel"].find((f) => v.has(f));
5706
5675
  let record3;
5707
- if (action) {
5708
- const releaseId = v.get(action);
5709
- if (action === "--status") {
5710
- const release = await required(client.getProductRelease).call(client, { id, releaseId });
5711
- if (release.releaseId !== releaseId) responseError("\u53D1\u5E03\u7F16\u53F7\u4E0D\u5339\u914D");
5712
- return { exitCode: showRelease(io, release), buddyId: id, version: release.buddyVersion };
5713
- }
5714
- record3 = await store.read(releaseId, "release");
5715
- } else {
5716
- const sources = ["--from-push", "--from-submission", "--version"].filter((f) => v.has(f));
5717
- if (sources.length !== 1 || v.has("--code-only") !== v.has("--version") || v.has("--code-only") && v.has("--products-only")) throw new CloudCommandUsageError(PRODUCT_HELP.release);
5718
- let version;
5719
- let reviewIds;
5720
- if (v.has("--from-push")) {
5721
- const pushRecord = await store.read(v.get("--from-push"), "push");
5722
- const receipt = await required(client.getPackagePush).call(client, { id, pushId: pushRecord.id });
5723
- confirmPush(pushRecord, receipt);
5724
- await store.save({ ...pushRecord, receipt });
5725
- if (receipt.status !== "completed" || !receipt.uploadVersion) throw new CloudCommandUsageError("\u6307\u5B9A\u4E0A\u4F20\u5C1A\u672A\u5B8C\u6574\u63D0\u5BA1\uFF0C\u4E0D\u80FD\u81EA\u52A8\u7701\u7565\u5931\u8D25\u5546\u54C1\uFF1B\u8BF7\u8865\u63D0\u6216\u660E\u786E --version <\u7248\u672C> --code-only");
5726
- version = receipt.uploadVersion;
5727
- reviewIds = receipt.reviewIds;
5728
- } else if (v.has("--from-submission")) {
5729
- const submission = await store.read(v.get("--from-submission"), "submission");
5730
- if (!submission.confirmed) throw new CloudCommandUsageError(`\u8865\u63D0\u7ED3\u679C\u5C1A\u672A\u786E\u8BA4\uFF0C\u8BF7\u5148 products submit --resume ${submission.id}`);
5731
- version = submission.version;
5732
- reviewIds = submission.reviews.map((r) => r.reviewId);
5733
- } else {
5734
- version = v.get("--version");
5735
- reviewIds = [];
5736
- }
5737
- if (v.has("--products-only")) {
5738
- if (!reviewIds.length) throw new CloudCommandUsageError("--products-only \u9700\u8981\u660E\u786E\u7684\u5546\u54C1\u5BA1\u6838\u96C6\u5408");
5739
- const buddy2 = await client.getBuddy({ id });
5740
- if (buddy2.id !== id || !buddy2.released || buddy2.version !== version) throw new CloudCommandUsageError("\u4EC5\u5546\u54C1\u53D1\u5E03\u8981\u6C42\u56DE\u6267\u7248\u672C\u4E0E\u5F53\u524D\u5DF2\u53D1\u5E03\u642D\u5B50\u7248\u672C\u4E00\u81F4");
5741
- }
5742
- const releaseId = `rel_${randomUUID9()}`;
5743
- record3 = { kind: "release", id: releaseId, request: { releaseId, mode: v.has("--products-only") ? "products_only" : "with_buddy", buddyVersion: version, reviewIds } };
5676
+ if (v.has("--resume")) record3 = await store.read(v.get("--resume"), "submission");
5677
+ else {
5678
+ const version = v.get("--version");
5679
+ if (!version || !p.products.length) throw new CloudCommandUsageError(PRODUCT_HELP.products);
5680
+ const chosen = await selection(client, id, p.products, io);
5681
+ record3 = { kind: "submission", id: `sub_${randomUUID9()}`, version, reviews: chosen.reviews, confirmed: false };
5744
5682
  await store.create(record3);
5745
5683
  }
5746
- io.write(`\u6062\u590D\u7F16\u53F7\uFF1A${record3.id}`);
5684
+ io.write(`\u5546\u54C1\u63D0\u4EA4\u7F16\u53F7\uFF1A${record3.id}`);
5747
5685
  try {
5748
- const receipt = action === "--retry" ? await required(client.retryProductRelease).call(client, { id, releaseId: record3.id }) : action === "--cancel" ? await required(client.cancelProductRelease).call(client, { id, releaseId: record3.id }) : await required(client.createProductRelease).call(client, { id, release: record3.request });
5749
- matchRelease(record3.request, receipt);
5750
- await store.save({ ...record3, receipt });
5751
- return { exitCode: showRelease(io, receipt), buddyId: id, version: receipt.buddyVersion };
5686
+ const receipt = await required(client.submitPackageProducts).call(client, { id, version: record3.version, reviews: record3.reviews });
5687
+ if (!sameReviewIds(receipt.reviewIds, record3.reviews.map((r) => r.reviewId))) responseError("\u5E73\u53F0\u672A\u786E\u8BA4\u5B8C\u6574\u5546\u54C1\u5BA1\u6838\u96C6\u5408");
5688
+ await store.save({ ...record3, confirmed: true });
5689
+ io.write(`\u5546\u54C1\u5DF2\u63D0\u4EA4\u5BA1\u6838\uFF1A${receipt.reviewIds.join(", ")}`);
5690
+ io.write("\u5BA1\u6838\u901A\u8FC7\u540E\uFF0C\u8BF7\u5230\u5F00\u53D1\u8005\u540E\u53F0\u786E\u8BA4\u5E76\u53D1\u5E03\u3002");
5691
+ return { exitCode: 0, buddyId: id, version: record3.version };
5752
5692
  } catch (cause) {
5753
- if (cause instanceof CloudOperationError && cause.release) {
5754
- matchRelease(record3.request, cause.release);
5755
- await store.save({ ...record3, receipt: cause.release });
5756
- showRelease(io, cause.release);
5757
- }
5758
- io.writeError(`\u53D1\u5E03\u7ED3\u679C\u9700\u786E\u8BA4\uFF1Abuddy-cli-sit release --status ${record3.id}\uFF1B\u539F\u8BF7\u6C42\u6062\u590D\uFF1Abuddy-cli-sit release --resume ${record3.id}`);
5693
+ io.writeError(`\u4FDD\u7559\u539F\u8BF7\u6C42\u91CD\u8BD5\uFF1Abuddy-cli-sit products submit --resume ${record3.id}`);
5759
5694
  throw cause;
5760
5695
  }
5761
5696
  }
@@ -6077,7 +6012,7 @@ function serverError(response, body) {
6077
6012
  return new CloudOperationError(code2, message, {
6078
6013
  httpStatus: response.status,
6079
6014
  retryable: response.status === 408 || response.status === 429 || response.status >= 500
6080
- }, source?.push === void 0 ? void 0 : parsePackagePush(source.push), source?.release === void 0 ? void 0 : parseProductRelease(source.release));
6015
+ }, source?.push === void 0 ? void 0 : parsePackagePush(source.push));
6081
6016
  }
6082
6017
  var HttpDeveloperPlatformClient = class {
6083
6018
  #baseUrl;
@@ -6155,7 +6090,10 @@ var HttpDeveloperPlatformClient = class {
6155
6090
  const form = new FormData();
6156
6091
  form.set("meta", JSON.stringify(request.meta));
6157
6092
  form.set("avatar", new Blob([new Uint8Array(request.avatar.bytes)], { type: request.avatar.mediaType }), request.avatar.fileName);
6158
- return buddy(await this.#request(`/cli/buddies/${encodeURIComponent(request.id)}/meta`, "PUT", { form }), true);
6093
+ return buddy(await this.#request(`/cli/buddies/${encodeURIComponent(request.id)}/meta`, "PUT", {
6094
+ form,
6095
+ timeoutMs: this.#uploadTimeoutMs
6096
+ }), true);
6159
6097
  }
6160
6098
  return buddy(await this.#request(`/cli/buddies/${encodeURIComponent(request.id)}/meta`, "PUT", {
6161
6099
  json: request.meta
@@ -6244,24 +6182,6 @@ var HttpDeveloperPlatformClient = class {
6244
6182
  const source = object3(await this.#request(`/cli/buddies/${encodeURIComponent(request.id)}/packages/${encodeURIComponent(request.version)}/product-reviews`, "POST", { json: { reviews: request.reviews } }), "response");
6245
6183
  return { reviewIds: selectedReviewIds(source.reviewIds) };
6246
6184
  }
6247
- async createProductRelease(request) {
6248
- const source = object3(await this.#request(`/cli/buddies/${encodeURIComponent(request.id)}/product-releases`, "POST", { json: request.release }), "response");
6249
- return parseProductRelease(source.release);
6250
- }
6251
- async getProductRelease(request) {
6252
- const source = object3(await this.#request(`/cli/buddies/${encodeURIComponent(request.id)}/product-releases/${encodeURIComponent(request.releaseId)}`, "GET"), "response");
6253
- const release = parseProductRelease(source.release);
6254
- if (release.releaseId !== request.releaseId) throw invalid3("\u53D1\u5E03\u56DE\u6267 ID \u4E0D\u5339\u914D");
6255
- return release;
6256
- }
6257
- async retryProductRelease(request) {
6258
- const source = object3(await this.#request(`/cli/buddies/${encodeURIComponent(request.id)}/product-releases/${encodeURIComponent(request.releaseId)}/retry`, "POST"), "response");
6259
- return parseProductRelease(source.release);
6260
- }
6261
- async cancelProductRelease(request) {
6262
- const source = object3(await this.#request(`/cli/buddies/${encodeURIComponent(request.id)}/product-releases/${encodeURIComponent(request.releaseId)}/cancel`, "POST"), "response");
6263
- return parseProductRelease(source.release);
6264
- }
6265
6185
  async getPackageBuild(request) {
6266
6186
  return parseBuild(await this.#request(`/cli/buddies/${encodeURIComponent(request.id)}/packages/${encodeURIComponent(request.version)}/build`, "GET"));
6267
6187
  }
@@ -6392,13 +6312,13 @@ var HELP = Object.freeze({
6392
6312
  logout: "\u7528\u6CD5: buddy-cli-sit logout",
6393
6313
  push: PRODUCT_HELP.push,
6394
6314
  products: PRODUCT_HELP.products,
6395
- release: PRODUCT_HELP.release,
6396
6315
  status: "\u7528\u6CD5: buddy-cli-sit status [--directory <\u9879\u76EE\u76EE\u5F55>]",
6397
6316
  meta: `\u7528\u6CD5: buddy-cli-sit meta [--directory <\u9879\u76EE\u76EE\u5F55> | --buddy-id <\u642D\u5B50 ID>]
6398
6317
  buddy-cli-sit meta update [--name <\u540D\u79F0>] [--tagline <\u4E00\u53E5\u8BDD\u4ECB\u7ECD>] [--intro <\u5B8C\u6574\u4ECB\u7ECD>] [--avatar <\u56FE\u7247\u6587\u4EF6>] [--directory <\u9879\u76EE\u76EE\u5F55> | --buddy-id <\u642D\u5B50 ID>]
6399
6318
  meta \u53EA\u67E5\u770B\u4E91\u7AEF\u8D44\u6599\uFF1Bmeta update \u81F3\u5C11\u63D0\u4F9B\u4E00\u4E2A\u4FEE\u6539\u5B57\u6BB5\uFF0C\u672A\u4F20\u5B57\u6BB5\u4FDD\u6301\u539F\u6837\u3002
6400
6319
  \u6587\u5B57\u5B57\u6BB5\u4E0D\u80FD\u4E3A\u7A7A\uFF1B\u540D\u79F0\u6700\u591A ${BUDDY_PROFILE_TEXT_LIMITS.name} \u5B57\uFF0C\u4E00\u53E5\u8BDD\u4ECB\u7ECD\u6700\u591A ${BUDDY_PROFILE_TEXT_LIMITS.tagline} \u5B57\uFF0C\u5B8C\u6574\u4ECB\u7ECD\u6700\u591A ${BUDDY_PROFILE_TEXT_LIMITS.intro} \u5B57\u3002
6401
6320
  --avatar \u4E0A\u4F20\u66FF\u6362\u5934\u50CF\uFF1A\u672C\u5730\u9759\u6001 PNG\u3001JPEG\u3001WebP\uFF0C\u6700\u5927 5 MiB\uFF1B\u4E0D\u63D0\u4F9B\u6E05\u9664\u5934\u50CF\u9009\u9879\u3002
6321
+ \u5934\u50CF\u4E0A\u4F20\u8BF7\u6C42\u6700\u591A\u7B49\u5F85 5 \u5206\u949F\uFF0CCLI \u4E0A\u4F20\u524D\u5C45\u4E2D\u88C1\u5207\u81F3 512\xD7512 \u65E0\u635F WebP\uFF0C\u4FDD\u7559\u989C\u8272\u3001\u900F\u660E\u5EA6\u4E0E\u539F\u59CB\u6587\u4EF6\uFF1B\u67E5\u8BE2\u548C\u4EC5\u6587\u5B57\u66F4\u65B0\u4ECD\u4E3A 30 \u79D2\u3002
6402
6322
  \u9ED8\u8BA4\u8BFB\u53D6\u5F53\u524D\u5DE5\u7A0B\u7684 package.json.buddyId\uFF1B--buddy-id \u4E0E --directory \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528\u3002\u56FE\u7247\u8DEF\u5F84\u76F8\u5BF9\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u3002
6403
6323
  \u9700\u8981\u5F53\u524D\u8D26\u53F7\u62E5\u6709\u8BE5\u642D\u5B50\uFF1B\u66F4\u65B0\u7ACB\u5373\u5F71\u54CD\u4E91\u7AEF\u5C55\u793A\u8D44\u6599\uFF0C\u65E0\u9700 Runtime\u3001push \u6216\u91CD\u65B0\u53D1\u5E03\u7A0B\u5E8F\u5305\u3002
6404
6324
  \u793A\u4F8B: buddy-cli-sit meta update --name "\u5DDD\u5927\u53A8" --tagline "\u5E2E\u4F60\u5B89\u6392\u6BCF\u5929\u5403\u4EC0\u4E48" --avatar ./avatar.png`,
@@ -6406,6 +6326,7 @@ meta \u53EA\u67E5\u770B\u4E91\u7AEF\u8D44\u6599\uFF1Bmeta update \u81F3\u5C11\u6
6406
6326
  \u65E7\u547D\u4EE4\u517C\u5BB9\u5165\u53E3\uFF1B\u66F4\u6362\u5934\u50CF\u63A8\u8350\u4F7F\u7528 buddy-cli-sit meta update --avatar <\u56FE\u7247\u6587\u4EF6>\u3002
6407
6327
  \u4FEE\u6539\u5F53\u524D\u9879\u76EE\u6216\u6307\u5B9A\u642D\u5B50\u7684\u4E91\u7AEF\u5934\u50CF\uFF0C\u4FDD\u7559\u5176\u4ED6\u8D44\u6599\uFF1B\u4E0D\u9700\u8981\u5B89\u88C5 Runtime \u6216\u4E0A\u4F20\u4EE3\u7801\u5305\u3002
6408
6328
  --file \u63A5\u53D7\u672C\u5730\u9759\u6001 PNG\u3001JPEG\u3001WebP \u56FE\u7247\uFF0C\u6700\u5927 5 MiB\uFF1BServer \u81EA\u52A8\u5904\u7406\u5E76\u751F\u6210\u5730\u5740\u3002
6329
+ \u5934\u50CF\u4E0A\u4F20\u8BF7\u6C42\u6700\u591A\u7B49\u5F85 5 \u5206\u949F\uFF0CCLI \u4E0A\u4F20\u524D\u5C45\u4E2D\u88C1\u5207\u81F3 512\xD7512 \u65E0\u635F WebP\uFF0C\u4FDD\u7559\u989C\u8272\u3001\u900F\u660E\u5EA6\u4E0E\u539F\u59CB\u6587\u4EF6\uFF1B\u6E05\u9664\u5934\u50CF\u4ECD\u4E3A 30 \u79D2\u3002
6409
6330
  \u9700\u8981\u5F53\u524D\u8D26\u53F7\u62E5\u6709\u8BE5\u642D\u5B50\uFF0C\u547D\u4EE4\u6267\u884C\u540E\u7ACB\u5373\u66F4\u65B0\u4E91\u7AEF\u8D44\u6599\u3002`
6410
6331
  });
6411
6332
  function parse3(args, command) {
@@ -6534,7 +6455,7 @@ async function runMeta(parsed, io, options, legacyAvatar = false) {
6534
6455
  }
6535
6456
  let upload;
6536
6457
  try {
6537
- upload = file ? await readBuddyAvatarFile(resolve16(options.cwd ?? process.cwd(), file)) : void 0;
6458
+ upload = file ? await prepareBuddyAvatarUpload(await readBuddyAvatarFile(resolve16(options.cwd ?? process.cwd(), file))) : void 0;
6538
6459
  } catch (error2) {
6539
6460
  throw new CloudCommandUsageError(error2 instanceof Error ? error2.message : "\u65E0\u6CD5\u8BFB\u53D6\u5934\u50CF\u56FE\u7247");
6540
6461
  }
@@ -6576,7 +6497,7 @@ async function runMeta(parsed, io, options, legacyAvatar = false) {
6576
6497
  }
6577
6498
  async function runCloudCommand(command, args, io, options = {}) {
6578
6499
  try {
6579
- if (command === "push" || command === "products" || command === "release") return await runProductLifecycle(command, args, io, options);
6500
+ if (command === "push" || command === "products") return await runProductLifecycle(command, args, io, options);
6580
6501
  const parsed = parse3(args, command);
6581
6502
  if (parsed.help) {
6582
6503
  io.write(HELP[command]);
@@ -6621,7 +6542,7 @@ async function runCloudCommand(command, args, io, options = {}) {
6621
6542
  exitCode: cause instanceof CloudCommandUsageError || cause instanceof BuddyProjectContextError ? 2 : 1
6622
6543
  };
6623
6544
  }
6624
- if (["push", "products", "release"].includes(command)) {
6545
+ if (["push", "products"].includes(command)) {
6625
6546
  io.writeError(`buddy-cli-sit: ${cause instanceof Error ? cause.message : "\u64CD\u4F5C\u672A\u5B8C\u6210\uFF0C\u8BF7\u6309\u8F93\u51FA\u7F16\u53F7\u67E5\u8BE2\u6216\u6062\u590D"}`);
6626
6547
  return { exitCode: 1 };
6627
6548
  }
@@ -6632,7 +6553,7 @@ var CLOUD_COMMAND_HELP = HELP;
6632
6553
 
6633
6554
  // packages/cli-core/src/migration/index.ts
6634
6555
  import { lstat as lstat12, open as open5, readdir as readdir6, realpath as realpath7, stat } from "node:fs/promises";
6635
- import { extname, isAbsolute as isAbsolute3, join as join22, relative, resolve as resolve17, sep, win32 as win322 } from "node:path";
6556
+ import { extname as extname2, isAbsolute as isAbsolute3, join as join22, relative, resolve as resolve17, sep, win32 as win322 } from "node:path";
6636
6557
  var DEFAULT_SKILL_SCAN_LIMITS = Object.freeze({
6637
6558
  maxFiles: 128,
6638
6559
  maxFileBytes: 256 * 1024,
@@ -7064,7 +6985,7 @@ function frontmatterEnd(lines) {
7064
6985
  return -1;
7065
6986
  }
7066
6987
  function shellLines(lines, path) {
7067
- const extension = extname(path).toLowerCase();
6988
+ const extension = extname2(path).toLowerCase();
7068
6989
  const shebang = lines[0] ?? "";
7069
6990
  if (SHELL_EXTENSIONS.has(extension) || /^#!.*(?:[/\s])(?:bash|fish|powershell|pwsh|sh|zsh)(?:\s|$)/u.test(shebang)) return lines.map(() => true);
7070
6991
  const result = lines.map(() => false);
@@ -7192,7 +7113,7 @@ function analyzeText(source, path, context) {
7192
7113
  const lines = source.split(/\r\n|\n|\r/u);
7193
7114
  const metadataEnd = frontmatterEnd(lines);
7194
7115
  const shellContext = shellLines(lines, path);
7195
- const extension = extname(path).toLowerCase();
7116
+ const extension = extname2(path).toLowerCase();
7196
7117
  const localShellVariables = /* @__PURE__ */ new Set();
7197
7118
  const localBatchVariables = /* @__PURE__ */ new Set();
7198
7119
  const localPowerShellEnvironment = /* @__PURE__ */ new Set();
@@ -8748,7 +8669,7 @@ async function runBuddyCli(args, io, options = {}) {
8748
8669
  ...options.dev
8749
8670
  });
8750
8671
  }
8751
- if (command === "login" || command === "logout" || command === "push" || command === "products" || command === "release" || command === "status" || command === "meta" || command === "avatar") {
8672
+ if (command === "login" || command === "logout" || command === "push" || command === "products" || command === "status" || command === "meta" || command === "avatar") {
8752
8673
  return await runCloudCommand(command, rest, io, {
8753
8674
  cwd: options.cwd,
8754
8675
  runtimeUpdate: options.runtimeCatalog,
@@ -8933,6 +8854,7 @@ export {
8933
8854
  isWindowsReservedPathSegment,
8934
8855
  latestRuntimeTemplate,
8935
8856
  normalizePlatformUrl,
8857
+ npmPackageManifest,
8936
8858
  openExternalUrl,
8937
8859
  parseBuddyAgentConfig,
8938
8860
  parseBuddyProjectManifest,