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

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
@@ -632,10 +632,9 @@ ${JSON.stringify(argv, null, 2)}
632
632
 
633
633
  \u4E0A\u4F20\u5931\u8D25\u6CBF\u7528\u5DF2\u4FDD\u5B58\u7684 buddyId \u548C\u5019\u9009\u56FE\u7247\uFF0C\u5728\u539F\u76EE\u5F55\u91CD\u8BD5\uFF0C\u4E0D\u53E6\u5EFA\u642D\u5B50\u3002\u5DF2\u6709\u4E91\u7AEF\u5934\u50CF\u4FDD\u7559\uFF1B\u53EA\u6709\u7528\u6237\u660E\u786E\u8981\u6C42\u66FF\u6362\u65F6\u624D\u4F7F\u7528 buddy-cli-sit meta update --avatar\u3002\u5B8C\u6210\u540E\u8BFB\u53D6 CLI \u8FD4\u56DE\u7684 Creator HANDOFF \u6216 Runtime \u5F00\u53D1\u6307\u5F15\u7EE7\u7EED\u3002
634
634
 
635
- \u666E\u901A\u7EC8\u7AEF\u53EF\u901A\u8FC7 --avatar \u6307\u5B9A\u5DF2\u6709\u56FE\u7247\uFF0C\u9884\u89C8\u5E76\u786E\u8BA4\uFF0C\u65E0\u9700\u4F7F\u7528\u751F\u6210 Skill\u3002
635
+ \u5DF2\u6709\u56FE\u7247\u53EF\u901A\u8FC7 --avatar \u6307\u5B9A\uFF0C\u65E0\u9700\u4F7F\u7528\u751F\u6210 Skill\u3002\u8BF7\u5728 Agent \u5BF9\u8BDD\u4E2D\u5C55\u793A\u8D44\u6599\u548C\u56FE\u7247\u5E76\u53D6\u5F97\u786E\u8BA4\uFF1BCLI \u4E0D\u751F\u6210\u6216\u6253\u5F00\u672C\u5730\u9884\u89C8\u9875\u3002
636
636
  `;
637
637
  }
638
- var escape = (text2) => text2.replace(/[&<>"']/gu, (character) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" })[character]);
639
638
  async function prepareAndRegisterMeta(options) {
640
639
  const draft = await readMetaDraft(options.root);
641
640
  if (options.requestedBuddyId && (!draft || draft.status === "complete")) return options.requestedBuddyId;
@@ -710,8 +709,6 @@ async function prepareLockedMeta(options) {
710
709
  }
711
710
  const upload = await readImage(join4(folder(root), draft.avatarPath), { forUpload: true });
712
711
  const confirmation = hash(JSON.stringify([profile.name, profile.tagline, profile.intro, hash(upload.bytes)]));
713
- const preview = join4(folder(root), "preview.html");
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>`);
715
712
  if (draft.confirmed !== confirmation) {
716
713
  draft.status = "awaiting_confirmation";
717
714
  delete draft.confirmed;
@@ -719,16 +716,8 @@ async function prepareLockedMeta(options) {
719
716
  io.write(`\u5F85\u786E\u8BA4\u8D44\u6599\uFF1A${profile.name}
720
717
  ${profile.tagline}
721
718
  ${profile.intro}
722
- \u5934\u50CF\u9884\u89C8\uFF1A${preview}`);
723
- let confirmed = options.confirmMeta === true;
724
- if (!confirmed && io.canPrompt) {
725
- await io.openMetaPreview?.(preview);
726
- confirmed = await io.select("\u5DF2\u67E5\u770B\u5934\u50CF\uFF0C\u786E\u8BA4\u8FD9\u4EFD\u8D44\u6599\u548C\u5934\u50CF\u5E76\u767B\u8BB0\u5230\u5E73\u53F0\uFF1F", [
727
- { value: "later", label: "\u6682\u4E0D\u767B\u8BB0\uFF0C\u4FDD\u7559\u8349\u7A3F" },
728
- { value: "confirm", label: "\u786E\u8BA4\u5E76\u767B\u8BB0" }
729
- ], { defaultValue: "later" }) === "confirm";
730
- }
731
- if (!confirmed) {
719
+ \u5934\u50CF\u6587\u4EF6\uFF1A${join4(folder(root), draft.avatarPath)}`);
720
+ if (options.confirmMeta !== true) {
732
721
  io.write("\u5F85\u5F00\u53D1\u8005\u786E\u8BA4\uFF0C\u5C1A\u672A\u8C03\u7528 Meta \u5199\u63A5\u53E3\u3002Coding Agent \u5C55\u793A\u5934\u50CF\u5E76\u53D6\u5F97\u660E\u786E\u786E\u8BA4\u540E\uFF0C\u4F7F\u7528 --avatar <\u5DF2\u786E\u8BA4\u56FE\u7247> --confirm-meta \u7EE7\u7EED\u3002");
733
722
  return void 0;
734
723
  }
@@ -3167,38 +3156,6 @@ var IMPLEMENTATION_GUIDE = implementationGuide();
3167
3156
  import { createHash as createHash4, randomBytes } from "node:crypto";
3168
3157
  import { spawn } from "node:child_process";
3169
3158
  import { createServer } from "node:http";
3170
-
3171
- // packages/cli-core/src/cloud/login-result.ts
3172
- import { readFileSync } from "node:fs";
3173
- var brand = new URL("../../resources/brand/", import.meta.url);
3174
- var tokens = readFileSync(new URL("tokens.css", brand), "utf8");
3175
- var styles = readFileSync(new URL("login-result.css", brand), "utf8");
3176
- var logo = readFileSync(new URL("logo.png", brand)).toString("base64");
3177
- function escapeHtml(value) {
3178
- return value.replace(/[&<>"']/gu, (character) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#039;" })[character]);
3179
- }
3180
- function renderLoginResult(title, message, webUrl, tone) {
3181
- const label = { success: "\u5DF2\u6388\u6743", neutral: "\u5DF2\u53D6\u6D88", error: "\u672A\u5B8C\u6210" }[tone];
3182
- return `<!doctype html>
3183
- <html lang="zh-CN"><head>
3184
- <meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
3185
- <meta name="color-scheme" content="light dark"><title>${escapeHtml(title)} \xB7 \u642D\u642D\u521B\u4F5C\u8005\u5E73\u53F0</title>
3186
- <style>${tokens}
3187
- ${styles}</style></head>
3188
- <body><div class="result-shell">
3189
- <header class="result-brand"><img src="data:image/png;base64,${logo}" alt="" width="44" height="44"><span>\u642D\u642D\u521B\u4F5C\u8005\u5E73\u53F0</span></header>
3190
- <main class="result-card" aria-labelledby="result-title">
3191
- <div class="result-heading"><p class="result-eyebrow">buddy-cli-sit \u767B\u5F55</p><span class="result-status" data-tone="${tone}">${label}</span></div>
3192
- <h1 id="result-title">${escapeHtml(title)}</h1>
3193
- <p class="result-message">${escapeHtml(message)}</p>
3194
- <div class="result-next"><strong>${tone === "success" ? "\u56DE\u5230\u7EC8\u7AEF\uFF0C\u7EE7\u7EED\u521B\u4F5C" : "\u56DE\u5230\u7EC8\u7AEF\uFF0C\u91CD\u65B0\u5F00\u59CB"}</strong>
3195
- <p>${tone === "success" ? "\u67E5\u770B CLI \u7684\u767B\u5F55\u7ED3\u679C\uFF0C\u7EE7\u7EED\u521B\u5EFA\u3001\u5F00\u53D1\u548C\u9884\u89C8\u4F60\u7684\u642D\u5B50\u3002" : "\u9700\u8981\u7EE7\u7EED\u65F6\uFF0C\u5728\u7EC8\u7AEF\u91CD\u65B0\u8FD0\u884C\u767B\u5F55\u547D\u4EE4\u3002"}</p>
3196
- ${tone === "success" ? "" : "<code>buddy-cli-sit login</code>"}</div>
3197
- <a class="result-link" href="${escapeHtml(webUrl.href)}">\u8FD4\u56DE\u5F00\u653E\u5E73\u53F0</a>
3198
- </main><footer>\u642D\u642D\u521B\u4F5C\u8005\u5E73\u53F0</footer></div></body></html>`;
3199
- }
3200
-
3201
- // packages/cli-core/src/cloud/browser-login.ts
3202
3159
  var DEFAULT_LOGIN_TIMEOUT_MS = 5 * 6e4;
3203
3160
  var DEFAULT_EXCHANGE_TIMEOUT_MS = 15e3;
3204
3161
  var DEFAULT_DEVELOPER_WEB_URL = new URL("/developer/", DEFAULT_MLB_TEST_URL).href;
@@ -3221,19 +3178,23 @@ async function openExternalUrl(url) {
3221
3178
  child.once("exit", (code2) => code2 === 0 ? resolve20() : reject(new Error(`browser launcher exited with ${code2 ?? "unknown"}`)));
3222
3179
  });
3223
3180
  }
3224
- async function write(res, status, title, message, webUrl, tone = "error") {
3225
- res.writeHead(status, {
3181
+ async function redirectResult(res, webUrl, status) {
3182
+ const destination = new URL(webUrl);
3183
+ destination.search = "";
3184
+ destination.hash = `/cli-result?status=${status}`;
3185
+ res.writeHead(303, {
3186
+ location: destination.href,
3226
3187
  "cache-control": "no-store",
3227
3188
  "connection": "close",
3228
- "content-security-policy": "default-src 'none'; img-src data:; style-src 'unsafe-inline'; frame-ancestors 'none'; base-uri 'none'",
3229
- "content-type": "text/html; charset=utf-8",
3189
+ "content-security-policy": "default-src 'none'; frame-ancestors 'none'; base-uri 'none'",
3190
+ "content-length": "0",
3230
3191
  "referrer-policy": "no-referrer",
3231
3192
  "x-content-type-options": "nosniff"
3232
3193
  });
3233
3194
  await new Promise((resolve20, reject) => {
3234
3195
  res.once("error", reject);
3235
3196
  res.once("close", resolve20);
3236
- res.end(renderLoginResult(title, message, webUrl, tone), resolve20);
3197
+ res.end(resolve20);
3237
3198
  });
3238
3199
  }
3239
3200
  async function readJson(response) {
@@ -3337,20 +3298,20 @@ var LoopbackBrowserLoginAdapter = class {
3337
3298
  async #receiveCallback(req, res, expected) {
3338
3299
  const url = new URL(req.url ?? "/", "http://127.0.0.1");
3339
3300
  if (req.method !== "GET" || url.pathname !== `/callback/${expected.callbackSecret}`) {
3340
- await write(res, 404, "\u9875\u9762\u4E0D\u5B58\u5728", "\u8BF7\u56DE\u5230\u7EC8\u7AEF\u91CD\u65B0\u53D1\u8D77\u767B\u5F55\u3002", this.#developerWebUrl);
3301
+ await redirectResult(res, this.#developerWebUrl, "invalid");
3341
3302
  throw new CloudLifecycleError("AUTH_LOGIN_CANCELLED", "\u6D4F\u89C8\u5668\u56DE\u8C03\u65E0\u6548\uFF0C\u8BF7\u91CD\u8BD5");
3342
3303
  }
3343
3304
  if (url.searchParams.get("state") !== expected.state) {
3344
- await write(res, 400, "\u767B\u5F55\u6CA1\u6709\u5B8C\u6210", "\u6388\u6743\u6821\u9A8C\u5931\u8D25\uFF0C\u8BF7\u56DE\u5230\u7EC8\u7AEF\u91CD\u8BD5\u3002", this.#developerWebUrl);
3305
+ await redirectResult(res, this.#developerWebUrl, "invalid");
3345
3306
  throw new CloudLifecycleError("AUTH_STATE_MISMATCH", "\u6D4F\u89C8\u5668\u767B\u5F55\u8FD4\u56DE\u7684 state \u4E0D\u5339\u914D\uFF1B\u51ED\u636E\u672A\u4FDD\u5B58");
3346
3307
  }
3347
3308
  if (url.searchParams.get("error") === "access_denied") {
3348
- await write(res, 200, "\u5DF2\u53D6\u6D88\u6388\u6743", "\u6CA1\u6709\u5411 buddy-cli-sit \u63D0\u4F9B\u8D26\u53F7\u6743\u9650\uFF0C\u53EF\u4EE5\u5173\u95ED\u8FD9\u4E2A\u9875\u9762\u3002", this.#developerWebUrl, "neutral");
3309
+ await redirectResult(res, this.#developerWebUrl, "cancelled");
3349
3310
  throw new CloudLifecycleError("AUTH_LOGIN_CANCELLED", "\u7528\u6237\u53D6\u6D88\u4E86 CLI \u6388\u6743");
3350
3311
  }
3351
3312
  const code2 = url.searchParams.get("code");
3352
3313
  if (!code2 || !AUTH_CODE.test(code2) || !expected.requestId) {
3353
- await write(res, 400, "\u767B\u5F55\u6CA1\u6709\u5B8C\u6210", "\u6388\u6743\u7ED3\u679C\u65E0\u6548\uFF0C\u8BF7\u56DE\u5230\u7EC8\u7AEF\u91CD\u8BD5\u3002", this.#developerWebUrl);
3314
+ await redirectResult(res, this.#developerWebUrl, "invalid");
3354
3315
  throw new CloudLifecycleError("PLATFORM_RESPONSE_INVALID", "\u642D\u642D\u521B\u4F5C\u8005\u5E73\u53F0\u8FD4\u56DE\u4E86\u65E0\u6548\u6388\u6743\u7801");
3355
3316
  }
3356
3317
  try {
@@ -3362,7 +3323,7 @@ var LoopbackBrowserLoginAdapter = class {
3362
3323
  if (exchanged.platformOrigin !== this.#platformUrl.origin || typeof exchanged.token !== "string" || typeof exchanged.userId !== "string" || !Number.isSafeInteger(exchanged.expiresAt)) {
3363
3324
  throw new CloudLifecycleError("PLATFORM_RESPONSE_INVALID", "\u642D\u642D\u521B\u4F5C\u8005\u5E73\u53F0\u8FD4\u56DE\u7684\u8D26\u53F7\u51ED\u636E\u4E0D\u5B8C\u6574");
3364
3325
  }
3365
- await write(res, 200, "\u767B\u5F55\u6210\u529F", "buddy-cli-sit \u5DF2\u83B7\u5F97\u6388\u6743\uFF0C\u53EF\u4EE5\u5173\u95ED\u8FD9\u4E2A\u9875\u9762\u5E76\u8FD4\u56DE\u7EC8\u7AEF\u3002", this.#developerWebUrl, "success");
3326
+ await redirectResult(res, this.#developerWebUrl, "authorized");
3366
3327
  return {
3367
3328
  state: expected.state,
3368
3329
  token: {
@@ -3372,7 +3333,7 @@ var LoopbackBrowserLoginAdapter = class {
3372
3333
  }
3373
3334
  };
3374
3335
  } catch (error2) {
3375
- await write(res, 502, "\u767B\u5F55\u6CA1\u6709\u5B8C\u6210", "\u6388\u6743\u4EA4\u6362\u5931\u8D25\uFF0C\u8BF7\u56DE\u5230\u7EC8\u7AEF\u91CD\u8BD5\u3002", this.#developerWebUrl);
3336
+ if (!res.headersSent) await redirectResult(res, this.#developerWebUrl, "failed");
3376
3337
  throw error2;
3377
3338
  }
3378
3339
  }
@@ -3506,8 +3467,8 @@ Coding Agent \u5E94\u76F4\u63A5\u6CBF\u7528\u7528\u6237\u660E\u786E\u63D0\u4F9B\
3506
3467
  --buddy-id \u53EA\u7528\u4E8E\u6062\u590D\u5E73\u53F0\u5DF2\u7ECF\u751F\u6210\u4E14\u5C5E\u4E8E\u5F53\u524D\u8D26\u53F7\u7684\u642D\u5B50\u8EAB\u4EFD\uFF0C\u4E0D\u80FD\u81EA\u884C\u6307\u5B9A\u8EAB\u4EFD\u3002
3507
3468
  \u65B0\u5EFA\u65F6\u9700\u8981\u751F\u6210\u5934\u50CF\u624D\u6309\u9700\u52A0\u8F7D\u72EC\u7ACB @my-life-buddies/avatar-creator-skill\uFF0C\u7531 Coding Agent \u8BFB\u53D6 .buddy/meta/HANDOFF.md \u4E0E\u5176\u4E2D\u6307\u5411\u7684 Skill\uFF0C\u8C03\u7528\u5BBF\u4E3B\u56FE\u7247\u751F\u6210\u80FD\u529B\u5E76\u5C55\u793A\u5B9E\u9645\u5934\u50CF\u3002\u5DF2\u6709\u56FE\u7247\u786E\u8BA4\u548C\u4E0A\u4F20\u4E0D\u4F9D\u8D56\u751F\u6210 Skill\u3002
3508
3469
  \u5934\u50CF Skill \u7248\u672C\u8BB0\u5F55\u5728 .buddy/meta/skill-lock.json\uFF1B--avatar-skill-version <\u51C6\u786E\u7248\u672C> \u663E\u5F0F\u9009\u62E9\u7248\u672C\uFF0C\u672C\u5730\u8054\u8C03\u8BBE\u7F6E BUDDY_AVATAR_SKILL_PATH \u7EDD\u5BF9\u8DEF\u5F84\u3002
3509
- \u666E\u901A\u7EC8\u7AEF\u53EF\u9009\u62E9\u5DF2\u6709\u56FE\u7247\uFF1BCLI \u4E0D\u6267\u884C\u56FE\u7247\u751F\u6210\uFF0C\u4E5F\u4E0D\u8981\u6C42\u5B89\u88C5 Coding Agent\u3002\u4F7F\u7528 --avatar <\u56FE\u7247\u6587\u4EF6> \u6307\u5B9A\u5019\u9009\u5934\u50CF\uFF0C\u7EC8\u7AEF\u9884\u89C8\u5E76\u786E\u8BA4\u540E\u767B\u8BB0\u3002
3510
- \u975E\u4EA4\u4E92\u8C03\u7528\u987B\u5728\u5F00\u53D1\u8005\u660E\u786E\u786E\u8BA4\u5B9E\u9645\u5934\u50CF\u548C\u8D44\u6599\u540E\u4F20 --avatar <\u5DF2\u786E\u8BA4\u56FE\u7247> --confirm-meta\u3002\u672A\u786E\u8BA4\u4E0D\u5F97\u4F20\u8BE5\u6807\u5FD7\uFF1B\u7F3A\u5C11\u56FE\u7247\u6216\u786E\u8BA4\u65F6\u9000\u51FA\u7801\u4E3A 2\uFF0C\u8349\u7A3F\u4FDD\u7559\uFF0C\u53EF\u4EE5\u5728\u539F\u76EE\u5F55\u7EE7\u7EED\u3002
3470
+ \u4F7F\u7528 --avatar <\u56FE\u7247\u6587\u4EF6> \u6307\u5B9A\u5DF2\u6709\u5019\u9009\u5934\u50CF\uFF1BCLI \u4E0D\u6267\u884C\u56FE\u7247\u751F\u6210\uFF0C\u4E5F\u4E0D\u751F\u6210\u6216\u6253\u5F00\u672C\u5730\u9884\u89C8\u7F51\u9875\u3002\u8BF7\u8BA9 Coding Agent \u5728\u5BF9\u8BDD\u4E2D\u5C55\u793A\u5B9E\u9645\u56FE\u7247\u548C\u5B8C\u6574\u8D44\u6599\u3002
3471
+ \u53D6\u5F97\u5F00\u53D1\u8005\u5BF9\u5B9E\u9645\u5934\u50CF\u548C\u8D44\u6599\u7684\u660E\u786E\u786E\u8BA4\u540E\uFF0C\u624D\u53EF\u4F20 --avatar <\u5DF2\u786E\u8BA4\u56FE\u7247> --confirm-meta\u3002\u672A\u786E\u8BA4\u4E0D\u5F97\u4F20\u8BE5\u6807\u5FD7\uFF1B\u7F3A\u5C11\u56FE\u7247\u6216\u786E\u8BA4\u65F6\u9000\u51FA\u7801\u4E3A 2\uFF0C\u8349\u7A3F\u4FDD\u7559\uFF0C\u53EF\u4EE5\u5728\u539F\u76EE\u5F55\u7EE7\u7EED\u3002
3511
3472
  --mode create \u5B8C\u6210\u8D44\u6599\u548C\u5934\u50CF\u767B\u8BB0\u540E\uFF0C\u52A8\u6001\u83B7\u53D6\u72EC\u7ACB Creator Skill \u5E76\u751F\u6210\u63A5\u7EED\u8BF4\u660E\uFF0C\u652F\u6301 Creator \u63A5\u5165\u534F\u8BAE 1 \u548C 2\uFF1B\u9879\u76EE .buddy/creator/ \u4FDD\u5B58\u521B\u4F5C\u8D44\u6599\u4E0E skill-lock.json \u7248\u672C\u8BB0\u5F55\u3002\u6BCF\u6B21\u8FDB\u5165\u6216\u6062\u590D\u90FD\u67E5\u8BE2\u516C\u5171 npm latest\uFF0C\u786E\u8BA4\u662F\u6700\u65B0\u7248\u540E\u624D\u590D\u7528\u7F13\u5B58\uFF1Bskill-lock.json \u53EA\u8BB0\u5F55\u672C\u6B21\u7248\u672C\uFF0C\u4E0D\u56FA\u5B9A\u65E7\u7248\u672C\u3002\u67E5\u8BE2\u3001\u4E0B\u8F7D\u6216\u534F\u8BAE\u6821\u9A8C\u5931\u8D25\u65F6\u660E\u786E\u62A5\u9519\uFF0C\u4E0D\u9000\u56DE\u65E7\u7248\u3002\u672C\u5730\u8054\u8C03\u53EF\u663E\u5F0F\u8BBE\u7F6E BUDDY_CREATOR_SKILL_PATH \u7EDD\u5BF9\u8DEF\u5F84\uFF0C\u6E05\u9664\u540E\u6062\u590D\u67E5\u8BE2 latest\u3002
3512
3473
  \u7531\u5F53\u524D Coding Agent \u8BFB\u53D6 .buddy/creator/HANDOFF.md \u5E76\u6267\u884C\u5176\u4E2D\u6307\u5411\u7684 Skill\uFF1B\u9700\u8981 Python 3.9+\uFF0C\u4E0D\u542F\u52A8\u65E7\u91C7\u8BBF Web \u6216\u72EC\u7ACB\u6A21\u578B\u3002
3513
3474
  \u6309\u5F53\u524D\u4F5C\u54C1\u5DE5\u4F5C\u6D41\u5B8C\u6210\u9700\u6C42\u3001\u5C0F\u6302\u4EF6\u6E05\u5355\u3001\u539F\u578B\u548C\u8BBE\u8BA1\u9A8C\u6536\uFF1B\u53EA\u6709\u4EA4\u4ED8\u6821\u9A8C\u8FD4\u56DE creator_complete\u3001completion.status=ready \u4E14\u4EA4\u4ED8\u6709\u6548\u540E\uFF0C\u624D\u7531 Coding Agent \u81EA\u52A8\u8854\u63A5\u5F00\u53D1\u3002\u8BFB\u53D6\u5B9E\u9645 manifest\uFF0C\u4E0D\u786C\u7F16\u7801\u624B\u518C\u6570\u91CF\u6216\u6587\u4EF6\u540D\uFF1B\u65B0\u7248\u4E09\u518C\u8FD8\u6309\u80FD\u529B\u5951\u7EA6\u5B8C\u6210\u5B9E\u65BD\u62A5\u544A\u548C handoff-check\uFF0C\u7ED3\u6784\u6821\u9A8C\u4E0D\u7B49\u4E8E\u771F\u5B9E Runtime \u9A8C\u8BC1\u3002\u65E7\u56DB\u518C\u7531\u6700\u65B0\u7248 Creator \u4FDD\u5B58\u5386\u53F2\u540E\u8FC1\u79FB\u4E3A\u4E09\u518C\uFF0C\u590D\u7528\u8D44\u6599\u548C\u8FDB\u5EA6\uFF0C\u8865\u9F50\u7F3A\u53E3\u5E76\u91CD\u65B0\u786E\u8BA4\u53D8\u5316\u5185\u5BB9\uFF1B\u4E0D\u76F4\u63A5\u6CBF\u7528\u65E7\u4EA4\u4ED8\u7684\u5B8C\u6210\u6807\u8BB0\u3002\u9700\u8981\u521D\u59CB\u5316\u65F6\u6267\u884C init --mode direct \u751F\u6210\u5B98\u65B9 Runtime \u5DE5\u7A0B\u3002\u751F\u6210\u65B0\u5DE5\u5382\u524D\u5217\u51FA\u6700\u65B0 dev Runtime \u652F\u6301\u7684\u6A21\u578B\uFF0C\u5148\u8BF7\u5F00\u53D1\u8005\u660E\u786E\u9009\u62E9\uFF0C\u518D\u4F20 --model\uFF1B\u5DF2\u6709\u660E\u786E\u9009\u62E9\u4E0D\u91CD\u590D\u8BE2\u95EE\uFF0C\u4E0D\u80FD\u7531 Coding Agent \u81EA\u884C\u9ED8\u8BA4\u3002\u5DF2\u6709\u4E1A\u52A1\u5DE5\u5382\u6CBF\u7528\u539F\u6A21\u578B\uFF0C\u4E0D\u4F20 --model\u3002\u540C\u76EE\u5F55\u6062\u590D\u65F6\u4ECE package.json \u8BFB\u53D6 buddyId\uFF0C\u5E76\u4F7F\u7528\u5E73\u53F0\u6700\u65B0 Meta\u3002
@@ -4500,7 +4461,7 @@ function startReloadingDev(options, startProcess) {
4500
4461
  }
4501
4462
 
4502
4463
  // packages/cli-core/src/dev/launch.ts
4503
- import { lstatSync, readFileSync as readFileSync2 } from "node:fs";
4464
+ import { lstatSync, readFileSync } from "node:fs";
4504
4465
  import { createRequire as createRequire3 } from "node:module";
4505
4466
  import { dirname as dirname4, resolve as resolve11 } from "node:path";
4506
4467
 
@@ -4570,10 +4531,10 @@ async function officialAgentLaunchPlan(input) {
4570
4531
  const packagePath = resolve11(input.projectRoot, BUDDY_PLATFORM_PACKAGE_JSON);
4571
4532
  try {
4572
4533
  await requireProjectRuntime(input.projectRoot, input.runtimeUpdate);
4573
- const expected = runtimeDependencyVersion(JSON.parse(readFileSync2(packagePath, "utf8")));
4534
+ const expected = runtimeDependencyVersion(JSON.parse(readFileSync(packagePath, "utf8")));
4574
4535
  if (!expected) throw new Error(`package.json \u7684 dependencies \u5FC5\u987B\u58F0\u660E ${BUDDY_RUNTIME_PACKAGE} \u7684\u51C6\u786E\u7248\u672C`);
4575
4536
  const runtimePath = createRequire3(packagePath).resolve(`${BUDDY_RUNTIME_PACKAGE}/package.json`);
4576
- const installed2 = JSON.parse(readFileSync2(runtimePath, "utf8")).version;
4537
+ const installed2 = JSON.parse(readFileSync(runtimePath, "utf8")).version;
4577
4538
  if (installed2 !== expected) throw new Error(`Runtime \u5DF2\u5B89\u88C5 ${installed2}\uFF0C\u5DE5\u7A0B\u8981\u6C42 ${expected}`);
4578
4539
  await validateRuntimeDatasets(input.projectRoot, await readDataAccessRequirements(input.projectRoot));
4579
4540
  } catch (cause) {