@my-life-buddies/cli 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin/core.js CHANGED
@@ -459,26 +459,26 @@ async function scaffoldPlatformAgent(projectRoot, name, options = {}) {
459
459
  throw new TypeError(`\u5B98\u65B9\u5DE5\u7A0B\u76EE\u5F55\u5FC5\u987B\u662F\u666E\u901A\u76EE\u5F55\uFF0C\u4E0D\u80FD\u4F7F\u7528\u6587\u4EF6\u6216\u7B26\u53F7\u94FE\u63A5\uFF1A${directoryPath}`);
460
460
  }
461
461
  }
462
- for (const file2 of files) {
462
+ for (const file of files) {
463
463
  try {
464
- handles.push({ path: file2.path, handle: await open(file2.path, "wx", 384) });
464
+ handles.push({ path: file.path, handle: await open(file.path, "wx", 384) });
465
465
  } catch (cause) {
466
466
  if (cause.code !== "EEXIST") throw cause;
467
- if (!(await lstat2(file2.path)).isFile()) {
468
- throw new TypeError(`\u5B98\u65B9\u5DE5\u7A0B\u6587\u4EF6\u5FC5\u987B\u662F\u666E\u901A\u6587\u4EF6\uFF0C\u4E0D\u80FD\u4F7F\u7528\u76EE\u5F55\u6216\u7B26\u53F7\u94FE\u63A5\uFF1A${file2.path}`);
467
+ if (!(await lstat2(file.path)).isFile()) {
468
+ throw new TypeError(`\u5B98\u65B9\u5DE5\u7A0B\u6587\u4EF6\u5FC5\u987B\u662F\u666E\u901A\u6587\u4EF6\uFF0C\u4E0D\u80FD\u4F7F\u7528\u76EE\u5F55\u6216\u7B26\u53F7\u94FE\u63A5\uFF1A${file.path}`);
469
469
  }
470
470
  }
471
471
  }
472
- const packageFile = files.find((file2) => file2.path === resolve2(projectRoot, BUDDY_PLATFORM_PACKAGE_JSON));
473
- const lockFile = files.find((file2) => file2.path === resolve2(projectRoot, BUDDY_PLATFORM_PACKAGE_LOCK));
474
- if (options.resolveDependencies && lockFile && handles.some((file2) => file2.path === packageFile.path) && handles.some((file2) => file2.path === lockFile.path)) {
472
+ const packageFile = files.find((file) => file.path === resolve2(projectRoot, BUDDY_PLATFORM_PACKAGE_JSON));
473
+ const lockFile = files.find((file) => file.path === resolve2(projectRoot, BUDDY_PLATFORM_PACKAGE_LOCK));
474
+ if (options.resolveDependencies && lockFile && handles.some((file) => file.path === packageFile.path) && handles.some((file) => file.path === lockFile.path)) {
475
475
  const template = await options.resolveDependencies({ packageJson: packageFile.content, packageLock: lockFile.content });
476
476
  packageFile.content = template.packageJson;
477
477
  lockFile.content = template.packageLock;
478
478
  }
479
- if (lockFile && (handles.some((file2) => file2.path === packageFile.path) || handles.some((file2) => file2.path === lockFile.path))) {
480
- const packageContents = handles.some((file2) => file2.path === packageFile.path) ? packageFile.content : await readFile4(packageFile.path, "utf8");
481
- const lockContents = handles.some((file2) => file2.path === lockFile.path) ? lockFile.content : await readFile4(lockFile.path, "utf8");
479
+ if (lockFile && (handles.some((file) => file.path === packageFile.path) || handles.some((file) => file.path === lockFile.path))) {
480
+ const packageContents = handles.some((file) => file.path === packageFile.path) ? packageFile.content : await readFile4(packageFile.path, "utf8");
481
+ const lockContents = handles.some((file) => file.path === lockFile.path) ? lockFile.content : await readFile4(lockFile.path, "utf8");
482
482
  const declared = JSON.parse(packageContents).dependencies ?? {};
483
483
  const locked = JSON.parse(lockContents).packages?.[""]?.dependencies ?? {};
484
484
  if (JSON.stringify(Object.entries(declared).sort()) !== JSON.stringify(Object.entries(locked).sort())) {
@@ -486,8 +486,8 @@ async function scaffoldPlatformAgent(projectRoot, name, options = {}) {
486
486
  }
487
487
  }
488
488
  for (const { path: filePath, handle } of handles) {
489
- const file2 = files.find((candidate) => candidate.path === filePath);
490
- await handle.writeFile(file2.content, "utf8");
489
+ const file = files.find((candidate) => candidate.path === filePath);
490
+ await handle.writeFile(file.content, "utf8");
491
491
  await handle.sync();
492
492
  }
493
493
  return Object.freeze({ path, created: handles.length > 0 || createdDirectories.length > 0 });
@@ -1233,333 +1233,11 @@ ${MODELS_COMMAND_HELP}`);
1233
1233
  }
1234
1234
  }
1235
1235
 
1236
- // packages/cli-core/src/commands/widgets.ts
1237
- import { resolve as resolve7 } from "node:path";
1238
-
1239
- // packages/cli-core/src/widget-delivery.ts
1240
- import { createHash } from "node:crypto";
1241
- import { lstat as lstat6, readFile as readFile6, realpath as realpath3, readdir as readdir2, mkdir as mkdir4, writeFile as writeFile3, rename as rename3 } from "node:fs/promises";
1242
- import { join as join6, resolve as resolve6 } from "node:path";
1243
- var LOCK = "widget-design.lock.json";
1244
- var IMPLEMENTATION = "widget-implementation.json";
1245
- var RECEIPTS = ".buddy/widget-verification.json";
1246
- var idPattern = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/u;
1247
- var hashPattern = /^[a-f0-9]{64}$/u;
1248
- var sha = (raw) => createHash("sha256").update(raw).digest("hex");
1249
- var object = (value) => value && typeof value === "object" && !Array.isArray(value);
1250
- var text = (value) => typeof value === "string" && value.trim().length > 0;
1251
- var WIDGET_REVIEW_CHECKS = ["visual", "interactions", "data-update", "trigger", "read-only"];
1252
- var WIDGET_REVIEW_STATES = ["initial", "partial", "updated"];
1253
- var NOTICE = "\u7ED3\u6784\u68C0\u67E5\u4E0E\u9884\u89C8\u6838\u5BF9\u8BB0\u5F55\u5206\u522B\u5C55\u793A\uFF1B\u6838\u5BF9\u8BB0\u5F55\u7531\u6267\u884C\u6838\u5BF9\u8005\u63D0\u4F9B\uFF0C\u5DE5\u5177\u4E0D\u81EA\u52A8\u5224\u65AD\u89C6\u89C9\u4E00\u81F4\uFF0C\u4E5F\u4E0D\u4EE3\u8868\u5F00\u53D1\u8005\u4F53\u9A8C\u9A8C\u6536\u6216\u53D1\u5E03\u6210\u529F\u3002";
1254
- function portable(path) {
1255
- if (!text(path) || path.startsWith("/") || path.includes("\\") || /[\x00-\x1f:]/u.test(path) || path.split("/").some((p) => !p || p === "." || p === "..")) throw new Error("\u5C0F\u6302\u4EF6\u8DEF\u5F84\u5FC5\u987B\u662F\u9879\u76EE\u5185\u76F8\u5BF9\u8DEF\u5F84");
1256
- return path;
1257
- }
1258
- async function file(root, path, optional = false) {
1259
- portable(path);
1260
- const base = await realpath3(root);
1261
- let cursor = base;
1262
- const parts = path.split("/");
1263
- for (const [index, part] of parts.entries()) {
1264
- cursor = join6(cursor, part);
1265
- const stat2 = await lstat6(cursor).catch((e) => {
1266
- if (e.code === "ENOENT") return void 0;
1267
- throw e;
1268
- });
1269
- if (!stat2) {
1270
- if (optional) return void 0;
1271
- throw new Error(`\u7F3A\u5C11\u6587\u4EF6\uFF1A${path}`);
1272
- }
1273
- if (stat2.isSymbolicLink() || (index < parts.length - 1 ? !stat2.isDirectory() : !stat2.isFile())) throw new Error(`\u4E0D\u63A5\u53D7\u7B26\u53F7\u94FE\u63A5\u6216\u7279\u6B8A\u6587\u4EF6\uFF1A${path}`);
1274
- if (index === parts.length - 1 && stat2.size > 8 * 1024 * 1024) throw new Error(`\u6587\u4EF6\u8D85\u8FC7 8 MB\uFF1A${path}`);
1275
- }
1276
- return readFile6(cursor);
1277
- }
1278
- async function jsonFile(root, path, optional = false) {
1279
- const bytes = await file(root, path, optional);
1280
- if (!bytes) return void 0;
1281
- try {
1282
- return JSON.parse(bytes.toString("utf8"));
1283
- } catch {
1284
- throw new Error(`JSON \u65E0\u6548\uFF1A${path}`);
1285
- }
1286
- }
1287
- async function save(root, path, value) {
1288
- portable(path);
1289
- let cursor = resolve6(root);
1290
- for (const segment of path.split("/").slice(0, -1)) {
1291
- cursor = join6(cursor, segment);
1292
- await mkdir4(cursor).catch((e) => {
1293
- if (e.code !== "EEXIST") throw e;
1294
- });
1295
- const stat2 = await lstat6(cursor);
1296
- if (!stat2.isDirectory() || stat2.isSymbolicLink()) throw new Error("\u5199\u5165\u76EE\u5F55\u4E0D\u5B89\u5168");
1297
- }
1298
- await file(root, path, true);
1299
- const target = join6(root, path), temp = `${target}.${process.pid}.${Date.now()}.tmp`;
1300
- await writeFile3(temp, JSON.stringify(value, null, 2) + "\n", { flag: "wx", mode: 384 });
1301
- await rename3(temp, target);
1302
- }
1303
- function validateLock(value) {
1304
- if (!object(value) || value.schemaVersion !== 1 || !text(value.buddyId) || !text(value.revision) || !hashPattern.test(value.catalogHash) || !Array.isArray(value.items) || value.items.length > 100) throw new Error("\u8BBE\u8BA1\u7ED1\u5B9A\u6587\u4EF6\u65E0\u6548\uFF0C\u8BF7\u8FD0\u884C buddy-cli widgets sync");
1305
- const seen = /* @__PURE__ */ new Set();
1306
- for (const item of value.items) {
1307
- if (!object(item) || typeof item.id !== "string" || item.id.length > 64 || !idPattern.test(item.id) || seen.has(item.id) || !text(item.name) || !hashPattern.test(item.prototypeHash) || !Array.isArray(item.fields) || !item.fields.every(text) || new Set(item.fields).size !== item.fields.length) throw new Error("\u8BBE\u8BA1\u6E05\u5355\u5305\u542B\u65E0\u6548\u6216\u91CD\u590D\u7684\u5C0F\u6302\u4EF6");
1308
- seen.add(item.id);
1309
- }
1310
- }
1311
- async function creatorDesign(root) {
1312
- const session = await jsonFile(root, ".buddy/creator/session.json", true);
1313
- if (!session) return void 0;
1314
- if (session.schemaVersion !== 1 || !text(session.platformBuddyId) || !/^[a-f0-9-]{36}$/u.test(session.creationKey)) throw new Error("Creator \u9879\u76EE\u8EAB\u4EFD\u65E0\u6548");
1315
- const workspace = `.buddy/creator/workspaces/${session.creationKey}`;
1316
- const state2 = await jsonFile(root, `${workspace}/state.json`);
1317
- if (!state2.artifacts?.["widget.catalog"]) return void 0;
1318
- const completion = await jsonFile(root, `${workspace}/completion.json`);
1319
- if (completion.status !== "ready" || completion.revision !== state2.revision || state2.paused || state2.pendingTurnId || !/^[a-zA-Z0-9_-]+$/u.test(state2.revision)) throw new Error("\u5C0F\u6302\u4EF6\u8BBE\u8BA1\u4EA4\u4ED8\u672A\u5B8C\u6210\u6216\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u5148\u6062\u590D Creator \u5F53\u524D\u8BBE\u8BA1\u9A8C\u6536");
1320
- const directory = `${workspace}/deliverables/${state2.revision}`;
1321
- const manifest = await jsonFile(root, `${directory}/MANIFEST.json`);
1322
- if (state2.buddyId !== session.creationKey || manifest.buddyId !== state2.buddyId) throw new Error("Creator \u4F5C\u54C1\u4E0E\u4EA4\u4ED8\u8EAB\u4EFD\u4E0D\u4E00\u81F4");
1323
- if (manifest.complete !== true || manifest.revision !== state2.revision || !Array.isArray(manifest.files)) throw new Error("\u8BBE\u8BA1\u4EA4\u4ED8\u6E05\u5355\u65E0\u6548");
1324
- const artifact = async (path) => {
1325
- const bytes = await file(root, `${directory}/${path}`);
1326
- const entry = manifest.files.find((e) => e.path === path);
1327
- if (!entry || entry.sha256 !== sha(bytes) || entry.bytes !== bytes.length) throw new Error(`\u8BBE\u8BA1\u6210\u679C\u88AB\u4FEE\u6539\uFF1A${path}\uFF1B\u5148\u6062\u590D\u4EA4\u4ED8`);
1328
- return bytes;
1329
- };
1330
- const confirmed = (id, hash) => state2.artifacts?.[id]?.hash === hash && state2.confirmations?.some((c) => c.objectId === id && c.hash === hash && c.decision === "confirmed" && !c.invalidatedBy);
1331
- const catalog = JSON.parse((await artifact("widgets/catalog.json")).toString());
1332
- if (!confirmed("widget.catalog", catalog.hash) || !Array.isArray(catalog.data?.widgets)) throw new Error("\u5C0F\u6302\u4EF6\u6E05\u5355\u4E0D\u662F\u5F53\u524D\u5DF2\u786E\u8BA4\u7248\u672C");
1333
- const items = [];
1334
- for (const item of catalog.data.widgets) {
1335
- if (!text(item.id) || item.id.length > 64 || !idPattern.test(item.id)) throw new Error("\u8BBE\u8BA1\u7C7B\u578B ID \u65E0\u6548");
1336
- const prefix = `widgets/${item.id}`;
1337
- const prototype = JSON.parse((await artifact(`${prefix}/prototype.json`)).toString());
1338
- const acceptance = JSON.parse((await artifact(`${prefix}/acceptance.json`)).toString()).artifact;
1339
- if (!confirmed(`widget.${item.id}.prototype`, prototype.hash) || !confirmed(`widget.${item.id}.acceptance`, acceptance.hash) || acceptance.data?.prototypeHash !== prototype.hash) throw new Error(`\u8BBE\u8BA1\u5C1A\u672A\u6709\u6548\u9A8C\u6536\uFF1A${item.id}`);
1340
- for (const asset of ["index.html", "style.css", "app.js"]) await artifact(`${prefix}/${asset}`);
1341
- items.push({ id: item.id, name: item.name, prototypeHash: prototype.hash, fields: item.fields.map((f) => f.key) });
1342
- }
1343
- const result = { schemaVersion: 1, buddyId: session.platformBuddyId, revision: state2.revision, catalogHash: catalog.hash, items };
1344
- validateLock(result);
1345
- return result;
1346
- }
1347
- async function syncWidgetDesign(root) {
1348
- const design = await creatorDesign(root);
1349
- if (!design) throw new Error("\u5F53\u524D\u9879\u76EE\u6CA1\u6709\u5DF2\u9A8C\u6536\u7684\u5C0F\u6302\u4EF6\u8BBE\u8BA1\uFF1B\u76F4\u63A5\u5F00\u53D1\u9879\u76EE\u53EF\u7EE7\u7EED\u4F7F\u7528\u539F\u6D41\u7A0B");
1350
- const config = await jsonFile(root, "buddy.agent.json");
1351
- if (config.buddyId !== design.buddyId) throw new Error("\u8BBE\u8BA1\u4E0E\u642D\u5B50\u8EAB\u4EFD\u4E0D\u4E00\u81F4");
1352
- const old = await jsonFile(root, IMPLEMENTATION, true);
1353
- if (old && (!object(old) || old.schemaVersion !== 1 || !Array.isArray(old.widgets))) throw new Error("\u5DF2\u6709\u5B9E\u73B0\u6620\u5C04\u635F\u574F\uFF0C\u4FDD\u7559\u539F\u6587\u4EF6\uFF0C\u8BF7\u4FEE\u590D\u540E\u518D\u540C\u6B65");
1354
- const mappings = design.items.map((item) => old?.widgets.find((w) => w.designId === item.id) ?? {
1355
- designId: item.id,
1356
- typeId: item.id,
1357
- prototypeHash: item.prototypeHash,
1358
- fields: Object.fromEntries(item.fields.map((key) => [key, ""])),
1359
- lifecycle: { create: [], update: [], present: [] }
1360
- });
1361
- const next = { schemaVersion: 1, widgets: mappings };
1362
- if (JSON.stringify(old) !== JSON.stringify(next)) await save(root, IMPLEMENTATION, next);
1363
- await save(root, LOCK, design);
1364
- }
1365
- async function sourceSnapshot(root) {
1366
- const result = [];
1367
- const visit = async (path, depth = 0) => {
1368
- if (depth > 32 || result.length > 1e4) throw new Error("\u5B9E\u73B0\u6E90\u7801\u8D85\u51FA\u68C0\u67E5\u8303\u56F4");
1369
- const stat2 = await lstat6(join6(root, path)).catch((e) => {
1370
- if (e.code === "ENOENT") return void 0;
1371
- throw e;
1372
- });
1373
- if (!stat2) return;
1374
- if (stat2.isSymbolicLink()) throw new Error(`\u5B9E\u73B0\u4E0D\u80FD\u4F7F\u7528\u7B26\u53F7\u94FE\u63A5\uFF1A${path}`);
1375
- if (stat2.isDirectory()) {
1376
- for (const name of (await readdir2(join6(root, path))).sort()) await visit(`${path}/${name}`, depth + 1);
1377
- } else result.push([path, sha(await file(root, path))]);
1378
- };
1379
- for (const name of ["src", "resources", "widgets", "start.mjs", "agent.md", "buddy.agent.json", "package.json", "package-lock.json", "pnpm-lock.yaml", "yarn.lock"]) await visit(name);
1380
- return result;
1381
- }
1382
- async function checkWidgetDelivery(root) {
1383
- const report = { status: "not-configured", items: [], issues: [], notice: NOTICE };
1384
- try {
1385
- const current = await creatorDesign(root);
1386
- const lockBytes = await file(root, LOCK, true);
1387
- let lock = lockBytes ? JSON.parse(lockBytes.toString()) : void 0;
1388
- if (!current && !lock) {
1389
- if (await file(root, IMPLEMENTATION, true)) throw new Error("\u5B9E\u73B0\u6620\u5C04\u5B58\u5728\uFF0C\u4F46\u8BBE\u8BA1\u7ED1\u5B9A\u7F3A\u5931\uFF0C\u8BF7\u6062\u590D widget-design.lock.json");
1390
- return report;
1391
- }
1392
- report.status = "incomplete";
1393
- if (!lock) {
1394
- report.issues.push("\u5DF2\u9A8C\u6536\u8BBE\u8BA1\u5C1A\u672A\u7ED1\u5B9A\u5230\u5DE5\u7A0B\uFF0C\u8BF7\u8FD0\u884C buddy-cli widgets sync");
1395
- lock = current;
1396
- }
1397
- validateLock(lock);
1398
- report.designRevision = lock.revision;
1399
- const config = await jsonFile(root, "buddy.agent.json");
1400
- if (config.buddyId !== lock.buddyId) throw new Error("\u8BBE\u8BA1\u4E0E\u642D\u5B50\u8EAB\u4EFD\u4E0D\u4E00\u81F4");
1401
- if (current && JSON.stringify(current) !== JSON.stringify(lock)) report.issues.push("\u8BBE\u8BA1\u5DF2\u53D8\u5316\uFF0C\u8BF7\u8FD0\u884C buddy-cli widgets sync\uFF1B\u65E7\u5B9E\u73B0\u548C\u6838\u5BF9\u8BB0\u5F55\u4E0D\u80FD\u6CBF\u7528\u4E3A\u65B0\u7248\u9A8C\u6536");
1402
- const implementationBytes = await file(root, IMPLEMENTATION, true);
1403
- const implementation = implementationBytes ? JSON.parse(implementationBytes.toString()) : void 0;
1404
- const mappings = implementation?.schemaVersion === 1 && Array.isArray(implementation.widgets) ? implementation.widgets : [];
1405
- if (!implementation || mappings.length !== lock.items.length) report.issues.push("\u5B9E\u73B0\u6620\u5C04\u4E0E\u5DF2\u9A8C\u6536\u6E05\u5355\u6570\u91CF\u4E0D\u7B26");
1406
- const receipts = await jsonFile(root, RECEIPTS, true);
1407
- const snapshot = await sourceSnapshot(root);
1408
- report.files = snapshot.map(([path, digest2]) => ({ path, digest: `sha256:${digest2}` }));
1409
- if (lockBytes) report.files.push({ path: LOCK, digest: `sha256:${sha(lockBytes)}` });
1410
- if (implementationBytes) report.files.push({ path: IMPLEMENTATION, digest: `sha256:${sha(implementationBytes)}` });
1411
- const usedTypes = /* @__PURE__ */ new Set();
1412
- for (const mapping of mappings) if (!lock.items.some((item) => item.id === mapping.designId)) report.issues.push("\u5B58\u5728\u4E0D\u5C5E\u4E8E\u5F53\u524D\u8BBE\u8BA1\u7684\u5B9E\u73B0\u6620\u5C04\uFF0C\u8BF7\u8FD0\u884C widgets sync");
1413
- for (const item of lock.items) {
1414
- const row = { id: item.id, name: item.name, status: "missing", issues: [] };
1415
- report.items.push(row);
1416
- try {
1417
- const matches = mappings.filter((w) => w.designId === item.id);
1418
- if (matches.length !== 1) throw new Error("\u7F3A\u5C11\u6216\u91CD\u590D\u7684\u5B9E\u73B0\u6620\u5C04");
1419
- const m = matches[0];
1420
- if (!text(m.typeId) || m.typeId.length > 64 || !/^[\p{L}\p{N}][\p{L}\p{N}_-]*$/u.test(m.typeId) || usedTypes.has(m.typeId)) throw new Error("\u6BCF\u4E2A\u5DF2\u9A8C\u6536\u8BBE\u8BA1\u5FC5\u987B\u5BF9\u5E94\u4E00\u4E2A\u72EC\u7ACB\u3001\u6709\u6548\u7684\u7C7B\u578B ID\uFF0C\u4E0D\u80FD\u5408\u5E76\u6210\u540C\u4E00\u4E2A\u5DE5\u4F5C\u53F0");
1421
- usedTypes.add(m.typeId);
1422
- row.typeId = m.typeId;
1423
- if (m.prototypeHash !== item.prototypeHash) row.issues.push("\u5B9E\u73B0\u7ED1\u5B9A\u7684\u539F\u578B\u7248\u672C\u5DF2\u8FC7\u671F");
1424
- const html = (await file(root, `widgets/${m.typeId}/index.html`)).toString();
1425
- if (!html.trim()) throw new Error("\u9875\u9762\u4E3A\u7A7A");
1426
- const schema = await jsonFile(root, `widgets/${m.typeId}/schema.json`);
1427
- if (!object(schema.modules) || !Object.keys(schema.modules).length) throw new Error("\u7F3A\u5C11\u6709\u6548\u7684\u6570\u636E\u6A21\u5757");
1428
- for (const key of item.fields) {
1429
- const binding = m.fields?.[key];
1430
- if (!text(binding) || !object(schema.modules[binding.split(".")[0]]?.record)) row.issues.push(`\u5B57\u6BB5 ${key} \u672A\u6620\u5C04\u5230\u5B9E\u9645\u6570\u636E\u6A21\u5757`);
1431
- }
1432
- for (const phase of ["create", "update", "present"]) {
1433
- const paths = m.lifecycle?.[phase];
1434
- if (!Array.isArray(paths) || !paths.length || paths.length > 50 || !paths.every(text)) {
1435
- row.issues.push(`\u7F3A\u5C11${phase}\u4EE3\u7801\u8DEF\u5F84`);
1436
- continue;
1437
- }
1438
- for (const path of paths) {
1439
- if (!path.startsWith("src/") || !/\.(?:mjs|js|ts|cjs)$/u.test(path)) throw new Error("\u521B\u5EFA\u3001\u66F4\u65B0\u548C\u5C55\u793A\u5FC5\u987B\u6620\u5C04\u5230 src/ \u4E0B\u7684\u4EE3\u7801");
1440
- if (!(await file(root, path)).toString().trim()) throw new Error(`\u4EE3\u7801\u4E3A\u7A7A\uFF1A${path}`);
1441
- }
1442
- }
1443
- if (row.issues.length) continue;
1444
- row.status = "implemented";
1445
- row.implementationDigest = sha(JSON.stringify({ design: lock, mapping: m, snapshot }));
1446
- const receipt = receipts?.items?.[item.id];
1447
- if (receipt?.implementationDigest === row.implementationDigest) {
1448
- validateEvidence(receipt.evidence);
1449
- if (!Array.isArray(receipt.artifacts) || receipt.artifacts.length !== 3) throw new Error("\u6838\u5BF9\u8BC1\u636E\u8BB0\u5F55\u65E0\u6548");
1450
- for (const [index, artifact] of receipt.artifacts.entries()) {
1451
- if (artifact.path !== receipt.evidence.states[WIDGET_REVIEW_STATES[index]].artifact) throw new Error("\u6838\u5BF9\u8BC1\u636E\u8DEF\u5F84\u4E0D\u5339\u914D");
1452
- if (sha(await file(root, artifact.path)) !== artifact.digest) throw new Error("\u9884\u89C8\u6838\u5BF9\u8BC1\u636E\u5DF2\u53D8\u5316\uFF0C\u8BF7\u91CD\u65B0\u6838\u5BF9");
1453
- }
1454
- if (!receipt.artifacts.length) throw new Error("\u7F3A\u5C11\u9884\u89C8\u6838\u5BF9\u8BC1\u636E");
1455
- row.status = "verified";
1456
- } else row.issues.push("\u5C1A\u672A\u8BB0\u5F55\u5F53\u524D\u5B9E\u73B0\u7248\u672C\u7684\u771F\u5B9E\u9884\u89C8\u6838\u5BF9\uFF1B\u6587\u4EF6\u5B58\u5728\u4E0D\u7B49\u4E8E\u6837\u5F0F\u4E0E\u884C\u4E3A\u5DF2\u9A8C\u8BC1");
1457
- } catch (cause) {
1458
- row.issues.push(cause instanceof Error ? cause.message : String(cause));
1459
- }
1460
- }
1461
- if (!report.issues.length && report.items.every((item) => item.status === "verified" && !item.issues.length)) report.status = "ready";
1462
- } catch (cause) {
1463
- report.status = "incomplete";
1464
- report.issues.push(cause instanceof Error ? cause.message : String(cause));
1465
- }
1466
- return report;
1467
- }
1468
- function validateEvidence(value) {
1469
- if (!object(value) || !text(value.previewUrl) || !text(value.observedAt) || !Number.isFinite(Date.parse(value.observedAt)) || !text(value.reviewer) || !object(value.states) || !object(value.checks)) throw new Error("\u6838\u5BF9\u8BB0\u5F55\u9700\u5305\u542B previewUrl\u3001observedAt\u3001reviewer\u3001states \u548C checks");
1470
- const url = new URL(value.previewUrl);
1471
- if (!["http:", "https:"].includes(url.protocol) || url.username || url.password || url.pathname.includes("bootstrap") || url.search || url.hash) throw new Error("\u9884\u89C8\u5730\u5740\u9700\u4F7F\u7528\u4E0D\u542B\u767B\u5F55\u51ED\u636E\u7684\u9875\u9762\u5730\u5740");
1472
- for (const state2 of WIDGET_REVIEW_STATES) {
1473
- if (!text(value.states[state2]?.notes) || !text(value.states[state2]?.artifact)) throw new Error(`\u7F3A\u5C11 ${state2} \u7684\u89C2\u5BDF\u8BF4\u660E\u4E0E\u8BC1\u636E\u6587\u4EF6`);
1474
- portable(value.states[state2].artifact);
1475
- }
1476
- for (const check of WIDGET_REVIEW_CHECKS) if (!text(value.checks[check])) throw new Error(`\u7F3A\u5C11 ${check} \u7684\u5B9E\u9645\u89C2\u5BDF\u8BF4\u660E`);
1477
- }
1478
- async function recordWidgetVerification(root, designId, evidencePath) {
1479
- const report = await checkWidgetDelivery(root);
1480
- const row = report.items.find((item) => item.id === designId);
1481
- if (report.issues.length || !row?.implementationDigest) throw new Error("\u5148\u5B8C\u6210\u5F53\u524D\u8BBE\u8BA1\u4E0E\u5B9E\u73B0\u7684\u7ED3\u6784\u68C0\u67E5\uFF0C\u518D\u8BB0\u5F55\u9884\u89C8\u6838\u5BF9");
1482
- const evidence = await jsonFile(root, evidencePath);
1483
- validateEvidence(evidence);
1484
- if (evidence.implementationDigest !== row.implementationDigest) throw new Error("\u6838\u5BF9\u8BB0\u5F55\u7684 implementationDigest \u4E0E\u5F53\u524D\u4EE3\u7801\u4E0D\u4E00\u81F4\uFF0C\u8BF7\u5148\u6838\u5BF9\u5F53\u524D\u5B9E\u73B0");
1485
- const artifacts = [];
1486
- for (const state2 of WIDGET_REVIEW_STATES) {
1487
- const path = evidence.states[state2].artifact;
1488
- artifacts.push({ path, digest: sha(await file(root, path)) });
1489
- }
1490
- const old = await jsonFile(root, RECEIPTS, true);
1491
- if (old && (old.schemaVersion !== 1 || !object(old.items))) throw new Error("\u5DF2\u6709\u6838\u5BF9\u8BB0\u5F55\u635F\u574F\uFF0C\u4FDD\u7559\u6587\u4EF6\u8BF7\u5148\u4FEE\u590D");
1492
- await save(root, RECEIPTS, { schemaVersion: 1, items: { ...old?.items, [designId]: {
1493
- implementationDigest: row.implementationDigest,
1494
- evidence,
1495
- artifacts
1496
- } } });
1497
- }
1498
- function widgetDeliverySummary(report) {
1499
- if (report.status === "not-configured") return "\u5F53\u524D\u5DE5\u7A0B\u6CA1\u6709\u7ED1\u5B9A\u7684 Creator \u5C0F\u6302\u4EF6\u8BBE\u8BA1\uFF1B\u672A\u6267\u884C\u8BBE\u8BA1\u4E00\u81F4\u6027\u68C0\u67E5\u3002";
1500
- return [
1501
- report.status === "ready" ? "\u5C0F\u6302\u4EF6\u7ED3\u6784\u68C0\u67E5\u4E0E\u5F53\u524D\u7248\u672C\u9884\u89C8\u6838\u5BF9\u8BB0\u5F55\u9F50\u5168\u3002" : "\u5C0F\u6302\u4EF6\u4EA4\u4ED8\u672A\u5B8C\u6210\uFF1A",
1502
- ...report.issues,
1503
- ...report.items.map((item) => `${item.name}\uFF08${item.id}\uFF09\uFF1A${item.status === "verified" ? "\u6838\u5BF9\u5DF2\u8BB0\u5F55" : item.status === "implemented" ? "\u5DF2\u5B9E\u73B0\uFF0C\u5F85\u6838\u5BF9" : "\u5F85\u8865\u9F50\u5B9E\u73B0"}${item.issues.length ? "\uFF1B" + item.issues.join("\uFF1B") : ""}`),
1504
- report.notice
1505
- ].join("\n");
1506
- }
1507
-
1508
- // packages/cli-core/src/commands/widgets.ts
1509
- var WIDGET_COMMAND_HELP = `\u5C0F\u6302\u4EF6\u8BBE\u8BA1\u843D\u5730\u68C0\u67E5\uFF08\u672C\u5730\uFF0C\u4E0D\u4E0A\u4F20\u3001\u4E0D\u53D1\u5E03\uFF09
1510
- buddy-cli widgets sync [--directory <\u9879\u76EE\u76EE\u5F55>]
1511
- buddy-cli widgets check [--directory <\u9879\u76EE\u76EE\u5F55>] [--json]
1512
- buddy-cli widgets verify --id <\u8BBE\u8BA1ID> --evidence <\u9879\u76EE\u5185\u8BB0\u5F55.json> [--directory <\u9879\u76EE\u76EE\u5F55>]
1513
- sync \u4ECE\u5F53\u524D\u5DF2\u9A8C\u6536 Creator \u4EA4\u4ED8\u7ED1\u5B9A\u8BBE\u8BA1\uFF0C\u751F\u6210\u5B9E\u73B0\u6620\u5C04\uFF1B\u4FDD\u7559\u5DF2\u6709\u6620\u5C04\uFF0C\u8BBE\u8BA1\u53D8\u5316\u540E\u91CD\u65B0\u6838\u5BF9\u3002
1514
- check \u9010\u9879\u5217\u51FA\u9057\u6F0F\u3001\u8FC7\u671F\u7248\u672C\u548C\u5F85\u6838\u5BF9\u9879\uFF1B\u9000\u51FA\u7801 1 \u8868\u793A\u672A\u5B8C\u6210\u3002DEV \u53EF\u7EE7\u7EED\u8C03\u8BD5\uFF0Cpush \u4F1A\u62E6\u622A\u3002
1515
- verify \u8BB0\u5F55\u771F\u5B9E\u9884\u89C8\u7684\u4E09\u6001\u8BC1\u636E\u4E0E\u4E94\u9879\u89C2\u5BDF\uFF0C\u5E76\u7ED1\u5B9A\u5F53\u524D\u4EE3\u7801\u6458\u8981\uFF1B\u4E0D\u4F1A\u81EA\u52A8\u5224\u65AD\u89C6\u89C9\u4E00\u81F4\u3002`;
1516
- async function runWidgetsCommand(args, io, cwd) {
1517
- try {
1518
- const [action, ...rest] = args;
1519
- if (!action || action === "--help" || action === "help") {
1520
- io.write(WIDGET_COMMAND_HELP);
1521
- return { exitCode: 0 };
1522
- }
1523
- if (!["sync", "check", "verify"].includes(action)) throw new Error(WIDGET_COMMAND_HELP);
1524
- const flags = /* @__PURE__ */ new Map();
1525
- for (let i = 0; i < rest.length; i++) {
1526
- const key = rest[i];
1527
- if (!["--directory", "--id", "--evidence", "--json"].includes(key) || flags.has(key)) throw new Error(`\u4E0D\u652F\u6301\u6216\u91CD\u590D\u7684\u53C2\u6570\uFF1A${key}`);
1528
- if (key === "--json") flags.set(key, "true");
1529
- else {
1530
- const value = rest[++i];
1531
- if (!value || value.startsWith("--")) throw new Error(`\u7F3A\u5C11\u53C2\u6570\uFF1A${key}`);
1532
- flags.set(key, value);
1533
- }
1534
- }
1535
- if (action !== "verify" && (flags.has("--id") || flags.has("--evidence"))) throw new Error("--id / --evidence \u4EC5\u7528\u4E8E verify");
1536
- if (action !== "check" && flags.has("--json")) throw new Error("--json \u4EC5\u7528\u4E8E check");
1537
- const root = await findBuddyProjectRoot(resolve7(cwd, flags.get("--directory") ?? "."));
1538
- if (!root) throw new Error("\u8BF7\u5728\u642D\u5B50\u5DE5\u7A0B\u4E2D\u8FD0\u884C\uFF0C\u6216\u6307\u5B9A --directory");
1539
- if (action === "sync") {
1540
- await syncWidgetDesign(root);
1541
- io.write("\u5DF2\u540C\u6B65\u5F53\u524D\u9A8C\u6536\u8BBE\u8BA1\u5230 widget-design.lock.json\uFF0C\u5E76\u751F\u6210 widget-implementation.json\uFF1B\u8BF7\u9010\u9879\u586B\u5199\u5B57\u6BB5\u4E0E\u5B9E\u73B0\u8DEF\u5F84\uFF0C\u968F\u540E\u8FD0\u884C widgets check\u3002");
1542
- return { exitCode: 0 };
1543
- }
1544
- if (action === "verify") {
1545
- if (!flags.get("--id") || !flags.get("--evidence")) throw new Error("verify \u9700\u8981 --id \u4E0E --evidence");
1546
- await recordWidgetVerification(root, flags.get("--id"), flags.get("--evidence"));
1547
- io.write("\u5DF2\u4FDD\u5B58\u4E0E\u5F53\u524D\u4EE3\u7801\u7ED1\u5B9A\u7684\u9884\u89C8\u6838\u5BF9\u8BB0\u5F55\uFF1B\u8FD9\u4E0D\u4EE3\u8868\u5F00\u53D1\u8005\u4F53\u9A8C\u9A8C\u6536\u6216\u53D1\u5E03\u6210\u529F\u3002");
1548
- }
1549
- const report = await checkWidgetDelivery(root);
1550
- io.write(flags.has("--json") ? JSON.stringify(report, null, 2) : widgetDeliverySummary(report));
1551
- return { exitCode: report.status === "incomplete" ? 1 : 0 };
1552
- } catch (cause) {
1553
- io.writeError(cause instanceof Error ? cause.message : String(cause));
1554
- return { exitCode: 1 };
1555
- }
1556
- }
1557
-
1558
1236
  // packages/cli-core/src/index.ts
1559
- import { lstat as lstat11 } from "node:fs/promises";
1237
+ import { lstat as lstat10 } from "node:fs/promises";
1560
1238
 
1561
1239
  // packages/cli-core/src/commands/datasets.ts
1562
- import { resolve as resolve8 } from "node:path";
1240
+ import { resolve as resolve6 } from "node:path";
1563
1241
  var DATASETS_COMMAND_HELP = `\u7528\u6CD5: buddy-cli datasets [--directory <\u9879\u76EE\u76EE\u5F55>] [--json]
1564
1242
  \u5DE5\u7A0B\u5185\u8BFB\u53D6\u5DF2\u5B89\u88C5 Runtime \u7684 DATA_ACCESS_CAPABILITIES\uFF1B\u5DE5\u7A0B\u5916\u8054\u7F51\u8BFB\u53D6\u5E76\u7F13\u5B58\u516C\u5171 npm \u6700\u65B0 Runtime\u3002
1565
1243
  \u65E0\u9700\u767B\u5F55\u642D\u642D\u8D26\u53F7\u3002\u5C06\u6240\u9009 id \u4E0E\u7528\u9014 purpose \u5199\u5165 buddy.agent.json.datasets\uFF1B\u76EE\u5F55\u4E0D\u4EE3\u8868\u7528\u6237\u5DF2\u6388\u6743\u3002`;
@@ -1577,7 +1255,7 @@ async function runDatasetsCommand(args, io, cwd, options = {}) {
1577
1255
  else throw new Error(`datasets \u53C2\u6570\u65E0\u6548\uFF1A${args[i]}
1578
1256
  ${DATASETS_COMMAND_HELP}`);
1579
1257
  }
1580
- const { root, source } = await runtimeCatalogSource(resolve8(cwd, directory ?? "."), { report: (message) => io.writeError(message), ...options });
1258
+ const { root, source } = await runtimeCatalogSource(resolve6(cwd, directory ?? "."), { report: (message) => io.writeError(message), ...options });
1581
1259
  const catalog = await readRuntimeDataCatalog(root);
1582
1260
  if (json) io.write(JSON.stringify({ source, ...catalog }, null, 2));
1583
1261
  else {
@@ -1594,12 +1272,12 @@ ${DATASETS_COMMAND_HELP}`);
1594
1272
  }
1595
1273
 
1596
1274
  // packages/cli-core/src/index.ts
1597
- import { join as join13, resolve as resolve16 } from "node:path";
1275
+ import { join as join12, resolve as resolve14 } from "node:path";
1598
1276
 
1599
1277
  // packages/cli-core/src/init/creator.ts
1600
1278
  import { randomUUID as randomUUID2 } from "node:crypto";
1601
- import { link as link2, lstat as lstat7, mkdir as mkdir5, readFile as readFile7, unlink as unlink3, writeFile as writeFile4 } from "node:fs/promises";
1602
- import { join as join7 } from "node:path";
1279
+ import { link as link2, lstat as lstat6, mkdir as mkdir4, readFile as readFile6, unlink as unlink3, writeFile as writeFile3 } from "node:fs/promises";
1280
+ import { join as join6 } from "node:path";
1603
1281
  import { fileURLToPath } from "node:url";
1604
1282
 
1605
1283
  // packages/cli-core/src/init/development-handoff.ts
@@ -1609,7 +1287,7 @@ var DEVELOPMENT_HANDOFF = `## \u5F00\u53D1\u5B8C\u6210\u540E\u4EA4\u7ED9\u5F00\u
1609
1287
  ${DEVELOPMENT_HANDOFF_SUMMARY}
1610
1288
 
1611
1289
  1. \u6839\u636E\u5DF2\u786E\u8BA4\u7684\u9700\u6C42\u5B8C\u6210 Agent / Prompt / Tool \u4E0E\u56DE\u5408\u94A9\u5B50\uFF1B\u6709 Booklet \u65F6\u4EE5\u5DF2\u786E\u8BA4\u624B\u518C\u4E3A\u51C6\u3002\u6A21\u677F\u751F\u6210\u4E0D\u7B49\u4E8E\u4E1A\u52A1\u5DF2\u5B9E\u73B0\u3002
1612
- 2. \u6709\u5DF2\u9A8C\u6536\u5C0F\u6302\u4EF6\u8BBE\u8BA1\u65F6\u6309\u5B9E\u73B0\u6307\u5F15\u6267\u884C \`widgets sync \u2192 widgets check \u2192 \u771F\u5B9E\u9884\u89C8\u5BF9\u7167 \u2192 widgets verify\`\uFF0C\u9010\u9879\u62A5\u544A\u72B6\u6001\uFF1B\u68C0\u67E5\u672A\u5B8C\u6210\u65F6\u4E0D\u80FD\u5C06\u7B80\u5316\u7248\u79F0\u4E3A\u5DF2\u6309\u8BBE\u8BA1\u4EA4\u4ED8\u3002\u505A\u57FA\u7840\u6280\u672F\u81EA\u6D4B\uFF1A\u68C0\u67E5\u914D\u7F6E\u3001\u4F9D\u8D56\u3001\u6784\u5EFA\u548C\u542F\u52A8\u5165\u53E3\uFF0C\u6267\u884C\u5DF2\u6709\u81EA\u52A8\u5316\u6D4B\u8BD5\u53CA\u660E\u786E\u4E1A\u52A1\u89C4\u5219\u3001\u5B89\u5168\u8FB9\u754C\u7684\u57FA\u7840\u6D4B\u8BD5\u3002\u4E0D\u8981\u628A\u6280\u672F\u68C0\u67E5\u901A\u8FC7\u8BF4\u6210\u4EA7\u54C1\u4F53\u9A8C\u5DF2\u9A8C\u6536\u3002
1290
+ 2. \u6709 Creator \u5C0F\u6302\u4EF6\u8BBE\u8BA1\u65F6\uFF0C\u6309\u5DF2\u786E\u8BA4\u7684\u9700\u6C42\u3001\u539F\u578B\u548C\u8BBE\u8BA1\u8BF4\u660E\u5B9E\u73B0\u9875\u9762\u3001\u6570\u636E\u7ED3\u6784\u4E0E\u4E1A\u52A1\u4EA4\u4E92\uFF0C\u5E76\u8BF4\u660E\u672A\u5B8C\u6210\u9879\u3002\u505A\u57FA\u7840\u6280\u672F\u81EA\u6D4B\uFF1A\u68C0\u67E5\u914D\u7F6E\u3001\u4F9D\u8D56\u3001\u6784\u5EFA\u548C\u542F\u52A8\u5165\u53E3\uFF0C\u6267\u884C\u5DF2\u6709\u81EA\u52A8\u5316\u6D4B\u8BD5\u53CA\u660E\u786E\u4E1A\u52A1\u89C4\u5219\u3001\u5B89\u5168\u8FB9\u754C\u7684\u57FA\u7840\u6D4B\u8BD5\u3002\u4E0D\u8981\u628A\u6280\u672F\u68C0\u67E5\u901A\u8FC7\u8BF4\u6210\u4EA7\u54C1\u4F53\u9A8C\u5DF2\u9A8C\u6536\u3002
1613
1291
  3. \u4F7F\u7528 \`buddy-cli preview\` \u6253\u5F00\u5F53\u524D\u5DE5\u7A0B\uFF0C\u5728\u9875\u9762\u542F\u52A8 DEV\uFF1B\u5DF2\u6709\u53EF\u7528\u9884\u89C8\u5219\u590D\u7528\uFF0C\u4E0D\u540C\u65F6\u518D\u542F\u52A8\u4E00\u5957 \`dev\` \u8FDB\u7A0B\u3002\u786E\u8BA4\u540D\u79F0\u3001DEV \u72B6\u6001\u548C\u79C1\u804A\u6D88\u606F\u5F80\u8FD4\uFF1B\u82E5\u7F3A\u5C11\u5F80\u8FD4\u8BC1\u636E\uFF0C\u53EA\u53D1\u9001\u4E00\u6761\u4E0D\u542B\u4E2A\u4EBA\u654F\u611F\u4FE1\u606F\u7684\u8054\u8C03\u6D88\u606F\uFF0C\u5DF2\u6709\u5F80\u8FD4\u8BC1\u636E\u65F6\u4E0D\u91CD\u590D\u53D1\u9001\u3002\u5931\u8D25\u5148\u5B9A\u4F4D\u6280\u672F\u95EE\u9898\uFF1B\u4ECD\u672A\u89E3\u51B3\u65F6\u8BF4\u660E\u963B\u585E\uFF0C\u4E0D\u628A Mock\u3001\u9875\u9762\u6253\u5F00\u6216\u8FDB\u7A0B\u542F\u52A8\u5F53\u6210\u94FE\u8DEF\u5DF2\u901A\u3002
1614
1292
  4. \u53EF\u4F53\u9A8C\u540E\u4FDD\u7559\u9884\u89C8\u548C DEV\uFF0C\u63D0\u4F9B\u5B9E\u9645\u6253\u5F00\u7684\u9875\u9762\u5730\u5740\uFF0C\u544A\u8BC9\u5F00\u53D1\u8005\u201C\u73B0\u5728\u53EF\u4EE5\u5F00\u59CB\u8BD5\u804A\u4E86\u201D\uFF0C\u8BF4\u660E\u5DF2\u9A8C\u8BC1\u8303\u56F4\u548C\u5DF2\u77E5\u9650\u5236\uFF0C\u7136\u540E\u7B49\u5F85\u53CD\u9988\u3002\u4E0B\u4E00\u8F6E\u7531\u5F00\u53D1\u8005\u4F53\u9A8C\u540E\u53CD\u9988\uFF0C\u518D\u6309\u53CD\u9988\u4FEE\u6539\u548C\u9A8C\u8BC1\u3002
1615
1293
 
@@ -1697,17 +1375,13 @@ Tool \u548C Hook \u662F Runtime \u7684\u6269\u5C55\u70B9\uFF1BService \u53EA\u66
1697
1375
 
1698
1376
  \u9047\u5230\u771F\u6B63\u7684\u963B\u585E\u5C31\u8BF4\u660E\u5177\u4F53\u7F3A\u53E3\u5E76\u7B49\u5F85\u7B54\u590D\uFF1B\u4E0D\u53D7\u5F71\u54CD\u7684\u5DF2\u6388\u6743\u5DE5\u4F5C\u53EF\u4EE5\u7EE7\u7EED\u3002\u65E0\u6CD5\u5B9E\u73B0\u7684\u8981\u6C42\u5982\u5B9E\u8BF4\u660E\uFF0C\u4E0D\u6697\u4E2D\u5220\u53BB\uFF0C\u4E5F\u4E0D\u4F2A\u9020\u5F00\u53D1\u8005\u540C\u610F\u964D\u7EA7\u3002\u7528\u6237\u53EA\u8981\u8BBE\u8BA1\u3001\u521D\u59CB\u5316\u6216\u5C40\u90E8\u4FEE\u6539\u65F6\u9075\u5B88\u8BE5\u8303\u56F4\uFF0C\u4E0D\u56E0\u624B\u518C\u5B58\u5728\u5C31\u81EA\u52A8\u6269\u5C55\u4EFB\u52A1\u3002
1699
1377
 
1700
- ### \u5C0F\u6302\u4EF6\u8BBE\u8BA1\u843D\u5730\u68C0\u67E5
1701
-
1702
- \u6709 Creator \u5C0F\u6302\u4EF6\u8BBE\u8BA1\u65F6\uFF0C\u5728\u5F00\u53D1\u5F00\u59CB\u524D\u6267\u884C \`buddy-cli widgets sync\`\u3002\u5B83\u4ECE\u5F53\u524D\u6709\u6548\u9A8C\u6536\u4EA4\u4ED8\u751F\u6210 \`widget-design.lock.json\` \u548C \`widget-implementation.json\`\uFF1B\u9010\u9879\u4FDD\u7559\u72EC\u7ACB\u7C7B\u578B ID\uFF0C\u4E0D\u5F97\u628A\u591A\u7C7B\u8BBE\u8BA1\u9759\u9ED8\u5408\u5E76\u6210\u4E00\u4E2A\u901A\u7528\u5DE5\u4F5C\u53F0\u3002\u540C\u6B65\u4E0D\u662F\u5B9E\u73B0\u5B8C\u6210\u3002
1378
+ ### \u6309\u8BBE\u8BA1\u5F00\u53D1\u5C0F\u6302\u4EF6
1703
1379
 
1704
- \u6309\u6620\u5C04\u5B9E\u73B0\u6BCF\u7C7B\u7684\u9875\u9762\u548C Schema\uFF0C\u586B\u5199\u5404\u8BBE\u8BA1\u5B57\u6BB5\u7684\u6570\u636E\u6A21\u5757\u7ED1\u5B9A\uFF0C\u4EE5\u53CA create/update/present \u5BF9\u5E94\u7684\u771F\u5B9E src/ \u4EE3\u7801\u8DEF\u5F84\u3002\u6CBF\u7528\u9A8C\u6536\u539F\u578B\u5E03\u5C40\u548C\u9605\u8BFB\u4EA4\u4E92\uFF0C\u793A\u4F8B\u6570\u636E\u53EA\u7528\u4E8E\u9694\u79BB\u7684\u9884\u89C8\u6838\u5BF9\uFF0C\u4E0D\u5199\u5165\u771F\u5B9E\u7528\u6237\u4F1A\u8BDD\u3002
1380
+ \u6709 Creator \u8BBE\u8BA1\u4EA7\u7269\u65F6\uFF0C\u8BFB\u53D6\u5DF2\u786E\u8BA4\u7684\u9700\u6C42\u624B\u518C\u3001\u5C0F\u6302\u4EF6\u6E05\u5355\u3001\u539F\u578B\u548C\u8BBE\u8BA1\u8BF4\u660E\uFF0C\u6309\u7528\u9014\u5B9E\u73B0\u5404\u7C7B\u5C0F\u6302\u4EF6\u3002\u4FDD\u7559\u8BBE\u8BA1\u8981\u6C42\u7684\u5C55\u793A\u5185\u5BB9\u3001\u5E03\u5C40\u3001\u4EA4\u4E92\u548C\u51FA\u73B0\u65F6\u673A\uFF1B\u65E0\u6CD5\u5B8C\u6210\u65F6\u660E\u786E\u8BF4\u660E\u7F3A\u53E3\uFF0C\u4E0D\u9759\u9ED8\u7701\u7565\u6216\u5408\u5E76\u8BBE\u8BA1\u3002
1705
1381
 
1706
- \u6267\u884C \`buddy-cli widgets check --json\`\uFF0C\u5148\u4FEE\u590D\u7F3A\u5931\u7C7B\u578B\u3001\u5B57\u6BB5\u3001\u4EE3\u7801\u8DEF\u5F84\u6216\u8FC7\u671F\u539F\u578B\u3002DEV \u5141\u8BB8\u7EE7\u7EED\u8C03\u8BD5\uFF0C\u9884\u89C8\u9875\u9762\u4F1A\u5355\u72EC\u5C55\u793A\u672A\u5B8C\u6210\u9879\uFF1B\u4E0A\u4F20\u6210\u529F\u3001DEV \u5728\u7EBF\u5747\u4E0D\u80FD\u4EE3\u66FF\u8FD9\u4EFD\u68C0\u67E5\u3002
1382
+ \u5728\u5DE5\u7A0B\u7684 \`widgets/<type-id>/\` \u4E2D\u7F16\u5199 \`index.html\` \u548C \`schema.json\`\uFF0C\u5728\u4E1A\u52A1\u4EE3\u7801\u4E2D\u63A5\u5165\u521B\u5EFA\u3001\u8BFB\u53D6\u3001\u66F4\u65B0\u548C\u53D1\u9001\u80FD\u529B\u3002\u5F00\u53D1\u8005\u5728 \`buddy-cli preview\` \u4E2D\u67E5\u770B\u771F\u5B9E\u9875\u9762\u548C\u4EA4\u4E92\u6548\u679C\uFF0C\u4FEE\u6539\u540E\u91CD\u542F DEV\u3002\u51C6\u5907\u4E0A\u4F20\u65F6\u4F7F\u7528 \`buddy-cli push\`\uFF0C\u9875\u9762\u548C\u6570\u636E\u5B9A\u4E49\u968F\u5DE5\u7A0B\u6253\u5305\u3002
1707
1383
 
1708
- \u5B8C\u6210\u5B9E\u9645\u9875\u9762\u4E0E\u9A8C\u6536\u539F\u578B\u7684\u9996\u6B21/\u8865\u5145/\u66F4\u65B0\u4E09\u6001\u5BF9\u7167\uFF0C\u8BB0\u5F55 visual\u3001interactions\u3001data-update\u3001trigger\u3001read-only \u4E94\u9879\u5B9E\u9645\u89C2\u5BDF\uFF1B\u4F7F\u7528\u9694\u79BB\u6D4B\u8BD5\u6570\u636E\u9A8C\u8BC1\u672A\u89E6\u53D1\u65F6\u65E0\u5165\u53E3\u3001\u521B\u5EFA\u540E\u663E\u793A\u3001\u66F4\u65B0\u6CBF\u7528\u5B9E\u4F8B\u4E0E\u6458\u8981\u4E00\u81F4\u3002\u4FDD\u7559\u622A\u56FE\u6216\u53EF\u590D\u6838\u6D4B\u8BD5\u8F93\u51FA\u5230\u9879\u76EE .buddy/ \u4E0B\u3002\u8BB0\u5F55\u91CC\u586B\u5199 check \u8F93\u51FA\u7684\u5F53\u524D implementationDigest\u3001\u65E0\u51ED\u636E previewUrl\u3001observedAt\u3001reviewer\u3001states\uFF08\u5404\u6001 notes/artifact\uFF09\u548C checks\uFF08\u4E94\u9879\u8BF4\u660E\uFF09\uFF0C\u7136\u540E\u6267\u884C \`buddy-cli widgets verify --id <\u8BBE\u8BA1ID> --evidence <\u9879\u76EE\u5185\u8BB0\u5F55.json>\`\u3002\u547D\u4EE4\u8BA1\u7B97\u8BC1\u636E\u6458\u8981\u5E76\u7ED1\u5B9A\u5F53\u524D\u4EE3\u7801\uFF1B\u5B83\u4FDD\u5B58\u6838\u5BF9\u8005\u7684\u89C2\u5BDF\uFF0C\u4E0D\u81EA\u52A8\u8BC1\u660E\u89C6\u89C9\u76F8\u540C\uFF0C\u4E5F\u4E0D\u65B0\u589E\u4E00\u8F6E\u7528\u6237\u5BA1\u6279\u3002
1709
-
1710
- \u6240\u6709\u7C7B\u578B\u7ED3\u6784\u548C\u6838\u5BF9\u8BB0\u5F55\u9F50\u5168\u540E\u624D\u79F0\u201C\u5C0F\u6302\u4EF6\u5F00\u53D1\u6838\u5BF9\u5B8C\u6210\u201D\u3002\u4EE3\u7801\u3001\u9875\u9762\u3001\u4F9D\u8D56\u3001\u6570\u636E\u7ED1\u5B9A\u6216\u8BBE\u8BA1\u7248\u672C\u53D8\u5316\u4F1A\u8BA9\u65E7\u8BB0\u5F55\u5931\u6548\uFF0C\u5E94\u9488\u5BF9\u53D8\u5316\u91CD\u65B0\u6838\u5BF9\u3002\u6CA1\u6709\u5B8C\u6210\u5C31\u660E\u786E\u5217\u51FA\u7F3A\u9879\u3002push \u4F1A\u5728\u4E0A\u4F20\u524D\u62E6\u622A\u4E0D\u5B8C\u6574\u4EA4\u4ED8\uFF0C\u4F46\u4E0D\u4F1A\u66FF\u5F00\u53D1\u8005\u53D1\u8D77\u63D0\u5BA1\u3002\u76F4\u63A5\u5F00\u53D1\u4E14\u65E0 Creator \u8BBE\u8BA1\u7684\u9879\u76EE\u6CBF\u7528\u539F\u6D41\u7A0B\uFF0C\u68C0\u67E5\u7ED3\u679C\u660E\u786E\u4E3A\u201C\u672A\u914D\u7F6E\u8BBE\u8BA1\u6838\u5BF9\u201D\uFF0C\u4E0D\u5192\u5145\u901A\u8FC7\u3002
1384
+ \u6309\u9700\u6C42\u5B8C\u6210\u57FA\u7840\u6280\u672F\u81EA\u6D4B\uFF0C\u5411\u5F00\u53D1\u8005\u8BF4\u660E\u5DF2\u5B9E\u73B0\u5185\u5BB9\u548C\u4ECD\u5B58\u5728\u7684\u95EE\u9898\uFF0C\u518D\u4EA4\u7ED9\u5F00\u53D1\u8005\u4F53\u9A8C\u3002\u8BBE\u8BA1\u8BF4\u660E\u4F5C\u4E3A\u5F00\u53D1\u53C2\u8003\uFF0CCLI \u4E0D\u8981\u6C42\u989D\u5916\u586B\u5199\u8BBE\u8BA1\u6620\u5C04\u6216\u63D0\u4EA4\u9884\u89C8\u6838\u5BF9\u8BB0\u5F55\u3002
1711
1385
 
1712
1386
  ### \u6838\u5BF9\u5B9E\u73B0\uFF0C\u518D\u4EA4\u7ED9\u5F00\u53D1\u8005\u4F53\u9A8C
1713
1387
 
@@ -1759,16 +1433,16 @@ var REQUIRED = [
1759
1433
  var CreatorPreparationError = class extends Error {
1760
1434
  };
1761
1435
  async function state(path) {
1762
- return lstat7(path).catch((cause) => {
1436
+ return lstat6(path).catch((cause) => {
1763
1437
  if (cause.code === "ENOENT") return void 0;
1764
1438
  throw cause;
1765
1439
  });
1766
1440
  }
1767
1441
  async function safeDirectory(path) {
1768
- await mkdir5(path, { mode: 448 }).catch((cause) => {
1442
+ await mkdir4(path, { mode: 448 }).catch((cause) => {
1769
1443
  if (cause.code !== "EEXIST") throw cause;
1770
1444
  });
1771
- if (!(await lstat7(path)).isDirectory()) {
1445
+ if (!(await lstat6(path)).isDirectory()) {
1772
1446
  throw new CreatorPreparationError(`\u521B\u4F5C\u76EE\u5F55\u5FC5\u987B\u662F\u666E\u901A\u76EE\u5F55\uFF0C\u4E0D\u80FD\u4F7F\u7528\u7B26\u53F7\u94FE\u63A5\uFF1A${path}`);
1773
1447
  }
1774
1448
  }
@@ -1778,11 +1452,11 @@ async function safeRead(path) {
1778
1452
  if (!entry.isFile() || entry.size > MAX_LOCAL_FILE_BYTES) {
1779
1453
  throw new CreatorPreparationError(`\u521B\u4F5C\u6587\u4EF6\u4E0D\u662F\u666E\u901A\u6587\u4EF6\u6216\u8D85\u51FA\u5927\u5C0F\u9650\u5236\uFF1A${path}`);
1780
1454
  }
1781
- return readFile7(path);
1455
+ return readFile6(path);
1782
1456
  }
1783
1457
  async function writeOnce(path, bytes) {
1784
1458
  const temporary = `${path}.${randomUUID2()}.tmp`;
1785
- await writeFile4(temporary, bytes, { flag: "wx", mode: 384 });
1459
+ await writeFile3(temporary, bytes, { flag: "wx", mode: 384 });
1786
1460
  try {
1787
1461
  await link2(temporary, path).catch((cause) => {
1788
1462
  if (cause.code !== "EEXIST") throw cause;
@@ -1793,17 +1467,17 @@ async function writeOnce(path, bytes) {
1793
1467
  }
1794
1468
  async function bundledSkill(root) {
1795
1469
  for (const path of REQUIRED) {
1796
- if (!(await state(join7(root, path)))?.isFile()) {
1470
+ if (!(await state(join6(root, path)))?.isFile()) {
1797
1471
  throw new CreatorPreparationError(`CLI \u5185\u7F6E Creator Skill \u4E0D\u5B8C\u6574\uFF0C\u8BF7\u91CD\u65B0\u5B89\u88C5 CLI\uFF08\u7F3A\u5C11 ${path}\uFF09\u3002\u4E0D\u4F1A\u5C1D\u8BD5\u5728\u7EBF\u4E0B\u8F7D\u6216\u8986\u76D6\u9879\u76EE\u8D44\u6599\u3002`);
1798
1472
  }
1799
1473
  }
1800
1474
  return root;
1801
1475
  }
1802
1476
  function handoffMarkdown(context, skillRoot, session, workspacePath) {
1803
- const contextPath = join7(context.projectRoot, ".buddy", "creator", "initial-context.json");
1477
+ const contextPath = join6(context.projectRoot, ".buddy", "creator", "initial-context.json");
1804
1478
  const openArgs = [
1805
1479
  "-B",
1806
- join7(skillRoot, "scripts/buddy.py"),
1480
+ join6(skillRoot, "scripts/buddy.py"),
1807
1481
  "open",
1808
1482
  "--workspace",
1809
1483
  workspacePath,
@@ -1833,7 +1507,7 @@ function handoffMarkdown(context, skillRoot, session, workspacePath) {
1833
1507
 
1834
1508
  ## \u73B0\u5728\u7531 Coding Agent \u6267\u884C
1835
1509
 
1836
- 1. \u5B8C\u6574\u8BFB\u53D6 ${JSON.stringify(join7(skillRoot, "SKILL.md"))} \u53CA\u5176\u6307\u5B9A\u7684 references\u3002\u4FDD\u7559\u539F\u6709\u56DB\u9636\u6BB5\u89C4\u5219\uFF0C\u7531\u5F53\u524D\u4E3B\u5BF9\u8BDD\u5B8C\u6210\u91C7\u8BBF\uFF1B\u65E0\u9700\u53E6\u8D77 Sub-agent \u6216\u8FD0\u884C\u91C7\u8BBF\u6A21\u578B\u670D\u52A1\u3002
1510
+ 1. \u5B8C\u6574\u8BFB\u53D6 ${JSON.stringify(join6(skillRoot, "SKILL.md"))} \u53CA\u5176\u6307\u5B9A\u7684 references\u3002\u4FDD\u7559\u539F\u6709\u56DB\u9636\u6BB5\u89C4\u5219\uFF0C\u7531\u5F53\u524D\u4E3B\u5BF9\u8BDD\u5B8C\u6210\u91C7\u8BBF\uFF1B\u65E0\u9700\u53E6\u8D77 Sub-agent \u6216\u8FD0\u884C\u91C7\u8BBF\u6A21\u578B\u670D\u52A1\u3002
1837
1511
  2. \u67E5\u627E\u5BBF\u4E3B\u6216\u7CFB\u7EDF\u5B9E\u9645\u53EF\u7528\u7684 Python 3.9+\uFF0C\u68C0\u67E5\u7248\u672C\uFF0C\u4FDD\u5B58\u5176\u7EDD\u5BF9\u8DEF\u5F84\u3002\u4E0D\u8981\u5199\u6B7B\u672C\u673A\u8DEF\u5F84\uFF0C\u4E0D\u5B89\u88C5 pip/npm \u4F9D\u8D56\u3002\u6CA1\u6709 Python \u65F6\u62A5\u544A\u7F3A\u53E3\uFF0C\u4FDD\u7559\u672C\u5730\u9879\u76EE\u3002\u6240\u6709 Python \u8C03\u7528\u5747\u52A0 -B\uFF0C\u5E76\u8BBE\u7F6E\u8FDB\u7A0B\u73AF\u5883\u53D8\u91CF PYTHONDONTWRITEBYTECODE=1\uFF08\u7531\u9884\u89C8\u5B50\u8FDB\u7A0B\u7EE7\u627F\uFF09\uFF0C\u907F\u514D\u5411 CLI \u5B89\u88C5\u76EE\u5F55\u5199\u5165\u5B57\u8282\u7801\u7F13\u5B58\u3002
1838
1512
  3. \u4F7F\u7528\u5DE5\u5177\u4F20\u9012\u72EC\u7ACB\u53C2\u6570\uFF0C\u4E0D\u62FC\u63A5 shell \u5B57\u7B26\u4E32\u3002\u5DE5\u4F5C\u76EE\u5F55\u4E3A ${JSON.stringify(context.projectRoot)}\uFF1B\u4EE5\u5B9E\u9645 Python \u8DEF\u5F84\u4E3A executable\uFF0C\u9996\u6B21\u6253\u5F00\u7684 argv \u5982\u4E0B\uFF1A
1839
1513
 
@@ -1870,11 +1544,11 @@ ${DEVELOPMENT_HANDOFF}
1870
1544
  `;
1871
1545
  }
1872
1546
  async function prepareCreatorSkill(context, io, options = {}) {
1873
- const root = join7(context.projectRoot, ".buddy", "creator");
1547
+ const root = join6(context.projectRoot, ".buddy", "creator");
1874
1548
  try {
1875
- await safeDirectory(join7(context.projectRoot, ".buddy"));
1549
+ await safeDirectory(join6(context.projectRoot, ".buddy"));
1876
1550
  await safeDirectory(root);
1877
- const sessionPath = join7(root, "session.json");
1551
+ const sessionPath = join6(root, "session.json");
1878
1552
  await writeOnce(sessionPath, JSON.stringify({
1879
1553
  schemaVersion: 1,
1880
1554
  platformBuddyId: context.buddyId,
@@ -1886,11 +1560,11 @@ async function prepareCreatorSkill(context, io, options = {}) {
1886
1560
  }
1887
1561
  options.signal?.throwIfAborted();
1888
1562
  const skillRoot = await bundledSkill(options.bundledSkillRoot ?? BUNDLED_CREATOR_SKILL_ROOT);
1889
- await safeDirectory(join7(root, "workspaces"));
1890
- const workspacePath = join7(root, "workspaces", session.creationKey);
1563
+ await safeDirectory(join6(root, "workspaces"));
1564
+ const workspacePath = join6(root, "workspaces", session.creationKey);
1891
1565
  const workspace = await state(workspacePath);
1892
1566
  if (workspace && !workspace.isDirectory()) throw new CreatorPreparationError("\u5DF2\u6709\u521B\u4F5C\u5DE5\u4F5C\u533A\u4E0D\u662F\u666E\u901A\u76EE\u5F55\u3002");
1893
- const contextPath = join7(root, "initial-context.json");
1567
+ const contextPath = join6(root, "initial-context.json");
1894
1568
  await writeOnce(contextPath, JSON.stringify({
1895
1569
  source: "platform_meta",
1896
1570
  name: context.appName,
@@ -1906,7 +1580,7 @@ async function prepareCreatorSkill(context, io, options = {}) {
1906
1580
  } catch {
1907
1581
  throw new CreatorPreparationError(`\u5DF2\u6709\u521D\u59CB\u80CC\u666F\u65E0\u6548\uFF0C\u5DF2\u4FDD\u7559\u539F\u6587\u4EF6\uFF0C\u8BF7\u68C0\u67E5\uFF1A${contextPath}`);
1908
1582
  }
1909
- const handoffPath = join7(root, "HANDOFF.md");
1583
+ const handoffPath = join6(root, "HANDOFF.md");
1910
1584
  const handoff = handoffMarkdown({
1911
1585
  ...context,
1912
1586
  appName: initial.name,
@@ -1917,11 +1591,11 @@ async function prepareCreatorSkill(context, io, options = {}) {
1917
1591
  if ((await safeRead(handoffPath))?.toString("utf8") !== handoff) {
1918
1592
  throw new CreatorPreparationError(`\u5DF2\u6709\u63A5\u7EED\u8BF4\u660E\u88AB\u4FEE\u6539\u6216\u9879\u76EE\u8DEF\u5F84\u5DF2\u53D8\u5316\uFF0C\u5DF2\u4FDD\u7559\u539F\u6587\u4EF6\u3002\u8BF7\u5907\u4EFD\u79FB\u8D70\u8BE5\u8BF4\u660E\u540E\u91CD\u8BD5\uFF1A${handoffPath}`);
1919
1593
  }
1920
- io.write(`\u4F7F\u7528 CLI \u5185\u7F6E Creator Skill\uFF0C\u65E0\u9700\u989D\u5916\u4E0B\u8F7D\uFF1A${join7(skillRoot, "SKILL.md")}`);
1594
+ io.write(`\u4F7F\u7528 CLI \u5185\u7F6E Creator Skill\uFF0C\u65E0\u9700\u989D\u5916\u4E0B\u8F7D\uFF1A${join6(skillRoot, "SKILL.md")}`);
1921
1595
  io.write(`\u4E0B\u4E00\u6B65\u4EA4\u7ED9 Codex / Claude Code \u7B49 Coding Agent\uFF1A\u8BF7\u8BFB\u53D6 ${JSON.stringify(handoffPath)}\uFF0C\u6309\u5F53\u524D\u9636\u6BB5\u63A5\u7EED\uFF1BCreator \u5B8C\u6210\u540E\u8FD4\u56DE CLI \u5F00\u53D1\u6D41\u7A0B\u3002`);
1922
1596
  io.write(DEVELOPMENT_HANDOFF_SUMMARY);
1923
1597
  io.write("\u672C\u547D\u4EE4\u53EA\u8D1F\u8D23\u8EAB\u4EFD\u767B\u8BB0\u548C Skill \u51C6\u5907\uFF0C\u4E0D\u4EE3\u8868\u91C7\u8BBF\u3001Booklet \u6216 Agent \u5DF2\u5B8C\u6210\u3002\u8BF7\u6309\u5DF2\u6709\u4F5C\u54C1\u8FDB\u5EA6\u63A5\u7EED\uFF0C\u56DB\u518C\u53CA\u5C0F\u6302\u4EF6\u8BBE\u8BA1\u9A8C\u6536\u3001\u4EA4\u4ED8\u6821\u9A8C\u5B8C\u6210\u540E\u81EA\u52A8\u8FDB\u5165\u5B98\u65B9 Runtime \u5F00\u53D1\uFF1B\u91CD\u590D create \u4F1A\u590D\u7528\u540C\u4E00\u4F5C\u54C1\u3002");
1924
- return { exitCode: 0, creator: { skillPath: join7(skillRoot, "SKILL.md"), handoffPath, workspacePath } };
1598
+ return { exitCode: 0, creator: { skillPath: join6(skillRoot, "SKILL.md"), handoffPath, workspacePath } };
1925
1599
  } catch (cause) {
1926
1600
  const message = cause instanceof CreatorPreparationError ? cause.message : "\u5185\u7F6E\u8D44\u6E90\u8BFB\u53D6\u6216\u672C\u5730\u5199\u5165\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5 CLI \u5B89\u88C5\u548C\u76EE\u5F55\u6743\u9650\u3002";
1927
1601
  io.writeError(`Creator Skill \u51C6\u5907\u5931\u8D25\uFF1A${message}`);
@@ -1981,7 +1655,7 @@ function validateBuddyMetaUpdate(meta2) {
1981
1655
  }
1982
1656
 
1983
1657
  // packages/cli-core/src/commands/dev.ts
1984
- import { resolve as resolve12 } from "node:path";
1658
+ import { resolve as resolve10 } from "node:path";
1985
1659
 
1986
1660
  // packages/cli-core/src/platform-url.ts
1987
1661
  var DEFAULT_MLB_TEST_URL = "http://47.116.168.81:8788";
@@ -2042,7 +1716,7 @@ function safeCredential(value, name) {
2042
1716
  function endpoint(baseUrl, path) {
2043
1717
  return new URL(path.replace(/^\//u, ""), baseUrl);
2044
1718
  }
2045
- function object2(value) {
1719
+ function object(value) {
2046
1720
  return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
2047
1721
  }
2048
1722
  async function responseJson(response) {
@@ -2084,7 +1758,7 @@ async function responseJson(response) {
2084
1758
  }
2085
1759
  }
2086
1760
  function safeServerError(value, fallback) {
2087
- const candidate = object2(value)?.error;
1761
+ const candidate = object(value)?.error;
2088
1762
  if (typeof candidate !== "string" || !candidate.trim()) return fallback;
2089
1763
  return candidate.slice(0, 1024).replace(/[\u0000-\u001f\u007f]/gu, " ");
2090
1764
  }
@@ -2165,7 +1839,7 @@ var MlbDevRegistrationClient = class {
2165
1839
  message: "buddy.agent.json \u4E2D\u7684 buddyId \u65E0\u6548\u3002"
2166
1840
  });
2167
1841
  }
2168
- const body = object2(await this.#request(
1842
+ const body = object(await this.#request(
2169
1843
  `/cli/buddies/${encodeURIComponent(request.devAgentId)}`,
2170
1844
  {
2171
1845
  method: "GET",
@@ -2186,7 +1860,7 @@ var MlbDevRegistrationClient = class {
2186
1860
  });
2187
1861
  }
2188
1862
  async listOnline(options) {
2189
- const body = object2(await this.#request("/cli/fleet", {
1863
+ const body = object(await this.#request("/cli/fleet", {
2190
1864
  method: "GET",
2191
1865
  signal: options.signal
2192
1866
  }));
@@ -2278,16 +1952,16 @@ function buildAgentEnvironment(options) {
2278
1952
  }
2279
1953
 
2280
1954
  // packages/cli-core/src/dev/orchestrator.ts
2281
- import { createHash as createHash3 } from "node:crypto";
2282
- import { readFile as readFile9 } from "node:fs/promises";
2283
- import { join as join9, resolve as resolve10 } from "node:path";
1955
+ import { createHash as createHash2 } from "node:crypto";
1956
+ import { readFile as readFile8 } from "node:fs/promises";
1957
+ import { join as join8, resolve as resolve8 } from "node:path";
2284
1958
 
2285
1959
  // packages/cli-core/src/dev/launch.ts
2286
1960
  import { lstatSync, readFileSync } from "node:fs";
2287
1961
  import { createRequire as createRequire2 } from "node:module";
2288
- import { dirname as dirname2, resolve as resolve9 } from "node:path";
1962
+ import { dirname as dirname2, resolve as resolve7 } from "node:path";
2289
1963
  async function officialAgentLaunchPlan(input) {
2290
- const entry = resolve9(input.projectRoot, BUDDY_PLATFORM_START_ENTRY);
1964
+ const entry = resolve7(input.projectRoot, BUDDY_PLATFORM_START_ENTRY);
2291
1965
  for (const [filename, kind] of [
2292
1966
  [dirname2(BUDDY_PLATFORM_FACTORY_ENTRY), "directory"],
2293
1967
  [BUDDY_PLATFORM_START_ENTRY, "file"],
@@ -2295,7 +1969,7 @@ async function officialAgentLaunchPlan(input) {
2295
1969
  [BUDDY_PLATFORM_PACKAGE_JSON, "file"]
2296
1970
  ]) {
2297
1971
  try {
2298
- const entry2 = lstatSync(resolve9(input.projectRoot, filename));
1972
+ const entry2 = lstatSync(resolve7(input.projectRoot, filename));
2299
1973
  if (!(kind === "directory" ? entry2.isDirectory() : entry2.isFile())) {
2300
1974
  throw new Error(`${filename} must be a regular ${kind}`);
2301
1975
  }
@@ -2308,7 +1982,7 @@ async function officialAgentLaunchPlan(input) {
2308
1982
  });
2309
1983
  }
2310
1984
  }
2311
- const packagePath = resolve9(input.projectRoot, BUDDY_PLATFORM_PACKAGE_JSON);
1985
+ const packagePath = resolve7(input.projectRoot, BUDDY_PLATFORM_PACKAGE_JSON);
2312
1986
  try {
2313
1987
  const expected = runtimeDependencyVersion(JSON.parse(readFileSync(packagePath, "utf8")));
2314
1988
  if (!expected) throw new Error(`package.json \u7684 dependencies \u5FC5\u987B\u58F0\u660E ${BUDDY_RUNTIME_PACKAGE} \u7684\u51C6\u786E\u7248\u672C`);
@@ -2359,16 +2033,16 @@ var NodeAgentProcessLauncher = class {
2359
2033
  }
2360
2034
  let hasExited = false;
2361
2035
  let spawned = false;
2362
- const exit = new Promise((resolve17) => {
2036
+ const exit = new Promise((resolve15) => {
2363
2037
  child.once("error", (error2) => {
2364
2038
  if (!spawned) {
2365
2039
  hasExited = true;
2366
- resolve17({ code: null, signal: null, error: error2 });
2040
+ resolve15({ code: null, signal: null, error: error2 });
2367
2041
  }
2368
2042
  });
2369
2043
  child.once("exit", (code2, signal) => {
2370
2044
  hasExited = true;
2371
- resolve17({ code: code2, signal });
2045
+ resolve15({ code: code2, signal });
2372
2046
  });
2373
2047
  });
2374
2048
  child.stdout?.on("data", (chunk) => {
@@ -2384,11 +2058,11 @@ var NodeAgentProcessLauncher = class {
2384
2058
  }
2385
2059
  });
2386
2060
  try {
2387
- await new Promise((resolve17, reject) => {
2061
+ await new Promise((resolve15, reject) => {
2388
2062
  const onSpawn = () => {
2389
2063
  spawned = true;
2390
2064
  child.off("error", onError);
2391
- resolve17();
2065
+ resolve15();
2392
2066
  };
2393
2067
  const onError = (error2) => {
2394
2068
  child.off("spawn", onSpawn);
@@ -2427,11 +2101,11 @@ var NodeAgentProcessLauncher = class {
2427
2101
  };
2428
2102
  function waitForExit(process2, timeoutMs) {
2429
2103
  if (process2.hasExited()) return Promise.resolve(true);
2430
- return new Promise((resolve17) => {
2431
- const timeout = setTimeout(() => resolve17(false), timeoutMs);
2104
+ return new Promise((resolve15) => {
2105
+ const timeout = setTimeout(() => resolve15(false), timeoutMs);
2432
2106
  process2.exit.then(() => {
2433
2107
  clearTimeout(timeout);
2434
- resolve17(true);
2108
+ resolve15(true);
2435
2109
  });
2436
2110
  });
2437
2111
  }
@@ -2514,7 +2188,7 @@ async function waitForGroupExit(pid, isGroupAlive, timeoutMs) {
2514
2188
  while (isGroupAlive(pid)) {
2515
2189
  const remaining = deadline - Date.now();
2516
2190
  if (remaining <= 0) return false;
2517
- await new Promise((resolve17) => setTimeout(resolve17, Math.min(25, remaining)));
2191
+ await new Promise((resolve15) => setTimeout(resolve15, Math.min(25, remaining)));
2518
2192
  }
2519
2193
  return true;
2520
2194
  }
@@ -2528,10 +2202,10 @@ function processTreeControllerFor(platform) {
2528
2202
  }
2529
2203
 
2530
2204
  // packages/cli-core/src/dev/instance-lock.ts
2531
- import { createHash as createHash2, randomUUID as randomUUID3 } from "node:crypto";
2532
- import { mkdir as mkdir6, readFile as readFile8, readdir as readdir3, rename as rename4, rmdir as rmdir2, unlink as unlink4, writeFile as writeFile5 } from "node:fs/promises";
2205
+ import { createHash, randomUUID as randomUUID3 } from "node:crypto";
2206
+ import { mkdir as mkdir5, readFile as readFile7, readdir as readdir2, rename as rename3, rmdir as rmdir2, unlink as unlink4, writeFile as writeFile4 } from "node:fs/promises";
2533
2207
  import { homedir as homedir2 } from "node:os";
2534
- import { join as join8 } from "node:path";
2208
+ import { join as join7 } from "node:path";
2535
2209
  function alreadyRunningError() {
2536
2210
  const message = "\u8FD9\u4E2A\u642D\u5B50\u5DF2\u6709 DEV \u5B9E\u4F8B\u5728\u8FD0\u884C\u3002\u8BF7\u5148\u5728\u539F\u9884\u89C8\u9875\u70B9\u51FB\u300C\u505C\u6B62 DEV\u300D\uFF0C\u6216\u5728\u8FD0\u884C dev \u7684\u7EC8\u7AEF\u6309 Ctrl+C\uFF0C\u518D\u542F\u52A8\u3002";
2537
2211
  return Object.assign(new BuddyDevError({ code: "DEV_ALREADY_RUNNING", phase: "launch", message }), { publicMessage: message });
@@ -2551,20 +2225,20 @@ function code(error2) {
2551
2225
  return error2?.code;
2552
2226
  }
2553
2227
  async function acquireDevInstanceLock(options) {
2554
- const root = options.directory ?? join8(homedir2(), ".buddy", "dev-locks");
2555
- const key = createHash2("sha256").update(`${new URL(options.gatewayUrl).origin}
2228
+ const root = options.directory ?? join7(homedir2(), ".buddy", "dev-locks");
2229
+ const key = createHash("sha256").update(`${new URL(options.gatewayUrl).origin}
2556
2230
  ${options.devAgentId}`).digest("hex");
2557
- const path = join8(root, key);
2231
+ const path = join7(root, key);
2558
2232
  const ownerName = `owner-${randomUUID3()}.json`;
2559
- const candidate = join8(root, `.pending-${randomUUID3()}`);
2233
+ const candidate = join7(root, `.pending-${randomUUID3()}`);
2560
2234
  const owner = { pid: process.pid };
2561
- await mkdir6(root, { recursive: true, mode: 448 });
2562
- await mkdir6(candidate, { mode: 448 });
2563
- await writeFile5(join8(candidate, ownerName), JSON.stringify(owner), { mode: 384, flag: "wx" });
2235
+ await mkdir5(root, { recursive: true, mode: 448 });
2236
+ await mkdir5(candidate, { mode: 448 });
2237
+ await writeFile4(join7(candidate, ownerName), JSON.stringify(owner), { mode: 384, flag: "wx" });
2564
2238
  try {
2565
2239
  for (let attempt = 0; ; attempt++) {
2566
2240
  try {
2567
- await rename4(candidate, path);
2241
+ await rename3(candidate, path);
2568
2242
  break;
2569
2243
  } catch (error2) {
2570
2244
  if (!["EEXIST", "ENOTEMPTY"].includes(code(error2) ?? "")) throw error2;
@@ -2572,17 +2246,17 @@ ${options.devAgentId}`).digest("hex");
2572
2246
  }
2573
2247
  let names;
2574
2248
  try {
2575
- names = await readdir3(path);
2249
+ names = await readdir2(path);
2576
2250
  } catch (error2) {
2577
2251
  if (code(error2) === "ENOENT") continue;
2578
2252
  throw error2;
2579
2253
  }
2580
2254
  if (names.length === 0) continue;
2581
2255
  if (names.length !== 1 || !/^owner-[a-f0-9-]+\.json$/u.test(names[0])) throw alreadyRunningError();
2582
- const previousPath = join8(path, names[0]);
2256
+ const previousPath = join7(path, names[0]);
2583
2257
  let previous;
2584
2258
  try {
2585
- previous = JSON.parse(await readFile8(previousPath, "utf8"));
2259
+ previous = JSON.parse(await readFile7(previousPath, "utf8"));
2586
2260
  } catch (error2) {
2587
2261
  if (code(error2) === "ENOENT") continue;
2588
2262
  throw alreadyRunningError();
@@ -2599,17 +2273,17 @@ ${options.devAgentId}`).digest("hex");
2599
2273
  });
2600
2274
  }
2601
2275
  } finally {
2602
- await unlink4(join8(candidate, ownerName)).catch(() => void 0);
2276
+ await unlink4(join7(candidate, ownerName)).catch(() => void 0);
2603
2277
  await rmdir2(candidate).catch(() => void 0);
2604
2278
  }
2605
2279
  let released = false;
2606
2280
  return {
2607
2281
  async attachRuntime(pid) {
2608
2282
  if (!validPid(pid)) throw new TypeError("Runtime PID is invalid");
2609
- const temporary = join8(root, `.update-${randomUUID3()}`);
2283
+ const temporary = join7(root, `.update-${randomUUID3()}`);
2610
2284
  try {
2611
- await writeFile5(temporary, JSON.stringify({ ...owner, runtimePid: pid }), { mode: 384, flag: "wx" });
2612
- await rename4(temporary, join8(path, ownerName));
2285
+ await writeFile4(temporary, JSON.stringify({ ...owner, runtimePid: pid }), { mode: 384, flag: "wx" });
2286
+ await rename3(temporary, join7(path, ownerName));
2613
2287
  } finally {
2614
2288
  await unlink4(temporary).catch(() => void 0);
2615
2289
  }
@@ -2617,7 +2291,7 @@ ${options.devAgentId}`).digest("hex");
2617
2291
  async release() {
2618
2292
  if (released) return;
2619
2293
  released = true;
2620
- await unlink4(join8(path, ownerName)).catch((error2) => {
2294
+ await unlink4(join7(path, ownerName)).catch((error2) => {
2621
2295
  if (code(error2) !== "ENOENT") throw error2;
2622
2296
  });
2623
2297
  await rmdir2(path).catch((error2) => {
@@ -2861,7 +2535,7 @@ async function startBuddyDev(options) {
2861
2535
  const pollIntervalMs = positiveDuration(options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS, "pollIntervalMs");
2862
2536
  const stopGracePeriodMs = positiveDuration(options.stopGracePeriodMs ?? DEFAULT_STOP_GRACE_PERIOD_MS, "stopGracePeriodMs");
2863
2537
  const devAgentId = safeDevAgentId(options.devAgentId);
2864
- const projectRoot = resolve10(options.projectRoot);
2538
+ const projectRoot = resolve8(options.projectRoot);
2865
2539
  const lifecycle = new AbortController();
2866
2540
  const signal = options.signal === void 0 ? lifecycle.signal : AbortSignal.any([lifecycle.signal, options.signal]);
2867
2541
  let agentProcess;
@@ -2879,7 +2553,7 @@ async function startBuddyDev(options) {
2879
2553
  let config;
2880
2554
  let configSource;
2881
2555
  try {
2882
- configSource = await readFile9(join9(projectRoot, BUDDY_AGENT_FILENAME), "utf8");
2556
+ configSource = await readFile8(join8(projectRoot, BUDDY_AGENT_FILENAME), "utf8");
2883
2557
  config = combineBuddyProject(parseBuddyAgentConfig(configSource));
2884
2558
  } catch (cause) {
2885
2559
  throw new BuddyDevError({
@@ -2889,14 +2563,12 @@ async function startBuddyDev(options) {
2889
2563
  cause
2890
2564
  });
2891
2565
  }
2892
- const widgetDelivery = await checkWidgetDelivery(projectRoot);
2893
- if (widgetDelivery.status === "incomplete") options.onLog?.({ source: "agent.stderr", text: widgetDeliverySummary(widgetDelivery) + "\nDEV \u5141\u8BB8\u7EE7\u7EED\u8C03\u8BD5\uFF0C\u63D0\u5BA1\u524D\u987B\u8865\u9F50\u3002\n" });
2894
2566
  const launchPlan = await launchPlanFor(config, options, projectRoot, signal);
2895
2567
  const registration = await registerDevAgent({
2896
2568
  client: options.registrationClient,
2897
2569
  devAgentId,
2898
2570
  configSource,
2899
- configDigest: `sha256:${createHash3("sha256").update(configSource).digest("hex")}`,
2571
+ configDigest: `sha256:${createHash2("sha256").update(configSource).digest("hex")}`,
2900
2572
  signal
2901
2573
  });
2902
2574
  throwIfDevAborted(signal);
@@ -2926,8 +2598,8 @@ async function startBuddyDev(options) {
2926
2598
  shell: false,
2927
2599
  detached: platform === "darwin",
2928
2600
  ...options.onLog === void 0 ? {} : {
2929
- onStdout: (text2) => options.onLog?.({ source: "agent.stdout", text: text2 }),
2930
- onStderr: (text2) => options.onLog?.({ source: "agent.stderr", text: text2 })
2601
+ onStdout: (text) => options.onLog?.({ source: "agent.stdout", text }),
2602
+ onStderr: (text) => options.onLog?.({ source: "agent.stderr", text })
2931
2603
  }
2932
2604
  });
2933
2605
  await instanceLock.attachRuntime(agentProcess.pid);
@@ -2983,7 +2655,7 @@ async function startBuddyDev(options) {
2983
2655
  }
2984
2656
 
2985
2657
  // packages/cli-core/src/dev/starter.ts
2986
- import { resolve as resolve11 } from "node:path";
2658
+ import { resolve as resolve9 } from "node:path";
2987
2659
  function createBuddyDevStarter(options = {}) {
2988
2660
  const readManifest = options.readManifest ?? (async (projectRoot) => {
2989
2661
  const manifest = await readBuddyProjectManifest(projectRoot);
@@ -2992,7 +2664,7 @@ function createBuddyDevStarter(options = {}) {
2992
2664
  const startDev = options.startDev ?? startBuddyDev;
2993
2665
  return Object.freeze({
2994
2666
  async start(input) {
2995
- const projectRoot = resolve11(input.projectRoot);
2667
+ const projectRoot = resolve9(input.projectRoot);
2996
2668
  const manifest = await readManifest(projectRoot);
2997
2669
  return startDev({
2998
2670
  ...input,
@@ -3083,7 +2755,7 @@ async function runDevCommand(args, io, options = {}) {
3083
2755
  return { exitCode: 0 };
3084
2756
  }
3085
2757
  try {
3086
- const requestedRoot = resolve12(options.cwd ?? process.cwd(), parsed.directory);
2758
+ const requestedRoot = resolve10(options.cwd ?? process.cwd(), parsed.directory);
3087
2759
  const root = await (options.resolveProjectRoot ?? requireBuddyAgentProjectRoot)(requestedRoot);
3088
2760
  const environment = options.env ?? process.env;
3089
2761
  const url = appServerUrl(parsed.appServer, environment);
@@ -3136,22 +2808,22 @@ async function runDevCommand(args, io, options = {}) {
3136
2808
  }
3137
2809
 
3138
2810
  // packages/cli-core/src/commands/cloud.ts
3139
- import { resolve as resolve13 } from "node:path";
2811
+ import { resolve as resolve11 } from "node:path";
3140
2812
 
3141
2813
  // packages/cli-core/src/cloud/avatar.ts
3142
2814
  import { open as open3 } from "node:fs/promises";
3143
2815
  import { basename } from "node:path";
3144
2816
  var MAX_BUDDY_AVATAR_BYTES = 5 * 1024 * 1024;
3145
2817
  async function readBuddyAvatarFile(path) {
3146
- const file2 = await open3(path, "r");
2818
+ const file = await open3(path, "r");
3147
2819
  try {
3148
- const stat2 = await file2.stat();
2820
+ const stat2 = await file.stat();
3149
2821
  if (!stat2.isFile()) throw new Error("\u5934\u50CF\u5FC5\u987B\u662F\u666E\u901A\u56FE\u7247\u6587\u4EF6");
3150
2822
  if (!stat2.size || stat2.size > MAX_BUDDY_AVATAR_BYTES) throw new Error("\u5934\u50CF\u4E0D\u80FD\u4E3A\u7A7A\u4E14\u4E0D\u80FD\u8D85\u8FC7 5 MiB");
3151
2823
  const buffer = Buffer.alloc(MAX_BUDDY_AVATAR_BYTES + 1);
3152
2824
  let size = 0;
3153
2825
  while (size < buffer.length) {
3154
- const { bytesRead } = await file2.read(buffer, size, buffer.length - size, null);
2826
+ const { bytesRead } = await file.read(buffer, size, buffer.length - size, null);
3155
2827
  if (!bytesRead) break;
3156
2828
  size += bytesRead;
3157
2829
  }
@@ -3161,7 +2833,7 @@ async function readBuddyAvatarFile(path) {
3161
2833
  if (!mediaType) throw new Error("\u4EC5\u652F\u6301 PNG\u3001JPEG\u3001WebP \u56FE\u7247\u6587\u4EF6");
3162
2834
  return { bytes, fileName: basename(path), mediaType };
3163
2835
  } finally {
3164
- await file2.close();
2836
+ await file.close();
3165
2837
  }
3166
2838
  }
3167
2839
 
@@ -3334,7 +3006,7 @@ function positiveTimeout(value, fallback, name) {
3334
3006
  if (!Number.isSafeInteger(result) || result <= 0) throw new TypeError(`${name} must be a positive safe integer`);
3335
3007
  return result;
3336
3008
  }
3337
- function object3(value, path) {
3009
+ function object2(value, path) {
3338
3010
  if (typeof value !== "object" || value === null || Array.isArray(value)) {
3339
3011
  throw invalid(`${path} \u5FC5\u987B\u662F\u5BF9\u8C61`);
3340
3012
  }
@@ -3354,7 +3026,7 @@ function optionalText(value, path, allowNewlines = false) {
3354
3026
  }
3355
3027
  function meta(value, path) {
3356
3028
  if (value === null) return null;
3357
- const source = object3(value, path);
3029
+ const source = object2(value, path);
3358
3030
  const name = source.name === void 0 ? void 0 : safeText(source.name, `${path}.name`);
3359
3031
  const avatar = optionalText(source.avatar, `${path}.avatar`);
3360
3032
  const tagline = optionalText(source.tagline, `${path}.tagline`);
@@ -3389,7 +3061,7 @@ function auditStatus(value, path) {
3389
3061
  return value;
3390
3062
  }
3391
3063
  function packageVersion(value, path) {
3392
- const source = object3(value, path);
3064
+ const source = object2(value, path);
3393
3065
  const auditNote = source.auditNote === null ? null : safeText(source.auditNote, `${path}.auditNote`, true);
3394
3066
  return Object.freeze({
3395
3067
  version: safeText(source.version, `${path}.version`),
@@ -3407,7 +3079,7 @@ function positivePage(value, name) {
3407
3079
  return value;
3408
3080
  }
3409
3081
  function buddy(value, includeToken) {
3410
- const source = object3(value, "response");
3082
+ const source = object2(value, "response");
3411
3083
  const token = includeToken ? safeText(source.token, "response.token") : void 0;
3412
3084
  return Object.freeze({
3413
3085
  id: safeText(source.id, "response.id"),
@@ -3543,7 +3215,7 @@ var HttpDeveloperPlatformClient = class {
3543
3215
  }), true);
3544
3216
  }
3545
3217
  async listBuddies() {
3546
- const source = object3(await this.#request("/cli/buddies", "GET"), "response");
3218
+ const source = object2(await this.#request("/cli/buddies", "GET"), "response");
3547
3219
  if (!Array.isArray(source.buddies)) throw invalid("response.buddies \u5FC5\u987B\u662F\u6570\u7EC4");
3548
3220
  return Object.freeze({
3549
3221
  buddies: Object.freeze(source.buddies.map((item) => buddy(item, false)))
@@ -3560,7 +3232,7 @@ var HttpDeveloperPlatformClient = class {
3560
3232
  ...pageSize === void 0 ? {} : { pageSize: String(pageSize) }
3561
3233
  });
3562
3234
  const suffix = query.size === 0 ? "" : `?${query.toString()}`;
3563
- const source = object3(await this.#request(
3235
+ const source = object2(await this.#request(
3564
3236
  `/cli/buddies/${encodeURIComponent(request.id)}/packages${suffix}`,
3565
3237
  "GET"
3566
3238
  ), "response");
@@ -3582,7 +3254,7 @@ var HttpDeveloperPlatformClient = class {
3582
3254
  throw new CloudLifecycleError("INVALID_REQUEST", "\u63D0\u4EA4\u5305\u4E0D\u80FD\u4E3A\u7A7A");
3583
3255
  }
3584
3256
  const query = new URLSearchParams({ commit });
3585
- const source = object3(await this.#request(
3257
+ const source = object2(await this.#request(
3586
3258
  `/cli/buddies/${encodeURIComponent(request.id)}/packages/push?${query.toString()}`,
3587
3259
  "POST",
3588
3260
  {
@@ -3599,13 +3271,13 @@ var HttpDeveloperPlatformClient = class {
3599
3271
  });
3600
3272
  }
3601
3273
  async logout(accessToken) {
3602
- const source = object3(await this.#request("/cli/auth/logout", "POST", { accessToken }), "response");
3274
+ const source = object2(await this.#request("/cli/auth/logout", "POST", { accessToken }), "response");
3603
3275
  if (source.ok !== true) throw invalid("response.ok \u5FC5\u987B\u662F true");
3604
3276
  }
3605
3277
  };
3606
3278
 
3607
3279
  // packages/cli-core/src/cloud/browser-login.ts
3608
- import { createHash as createHash4, randomBytes } from "node:crypto";
3280
+ import { createHash as createHash3, randomBytes } from "node:crypto";
3609
3281
  import { spawn } from "node:child_process";
3610
3282
  import { createServer } from "node:http";
3611
3283
 
@@ -3665,10 +3337,10 @@ function browserCommand(url) {
3665
3337
  }
3666
3338
  async function openExternalUrl(url) {
3667
3339
  const launch = browserCommand(url);
3668
- await new Promise((resolve17, reject) => {
3340
+ await new Promise((resolve15, reject) => {
3669
3341
  const child = spawn(launch.command, launch.args, { shell: false, stdio: "ignore", windowsHide: true });
3670
3342
  child.once("error", reject);
3671
- child.once("exit", (code2) => code2 === 0 ? resolve17() : reject(new Error(`browser launcher exited with ${code2 ?? "unknown"}`)));
3343
+ child.once("exit", (code2) => code2 === 0 ? resolve15() : reject(new Error(`browser launcher exited with ${code2 ?? "unknown"}`)));
3672
3344
  });
3673
3345
  }
3674
3346
  async function write(res, status, title, message, webUrl, tone = "error") {
@@ -3680,10 +3352,10 @@ async function write(res, status, title, message, webUrl, tone = "error") {
3680
3352
  "referrer-policy": "no-referrer",
3681
3353
  "x-content-type-options": "nosniff"
3682
3354
  });
3683
- await new Promise((resolve17, reject) => {
3355
+ await new Promise((resolve15, reject) => {
3684
3356
  res.once("error", reject);
3685
- res.once("close", resolve17);
3686
- res.end(renderLoginResult(title, message, webUrl, tone), resolve17);
3357
+ res.once("close", resolve15);
3358
+ res.end(renderLoginResult(title, message, webUrl, tone), resolve15);
3687
3359
  });
3688
3360
  }
3689
3361
  async function readJson(response) {
@@ -3713,16 +3385,16 @@ var LoopbackBrowserLoginAdapter = class {
3713
3385
  if (request.signal?.aborted) throw request.signal.reason;
3714
3386
  const callbackSecret = randomBytes(24).toString("hex");
3715
3387
  const codeVerifier = randomBytes(32).toString("base64url");
3716
- const codeChallenge = createHash4("sha256").update(codeVerifier).digest("base64url");
3388
+ const codeChallenge = createHash3("sha256").update(codeVerifier).digest("base64url");
3717
3389
  let requestId = "";
3718
3390
  let settle;
3719
3391
  let reject;
3720
3392
  let settled = false;
3721
- const result = new Promise((resolve17, rejectResult) => {
3393
+ const result = new Promise((resolve15, rejectResult) => {
3722
3394
  settle = (value) => {
3723
3395
  if (!settled) {
3724
3396
  settled = true;
3725
- resolve17(value);
3397
+ resolve15(value);
3726
3398
  }
3727
3399
  };
3728
3400
  reject = (reason) => {
@@ -3741,9 +3413,9 @@ var LoopbackBrowserLoginAdapter = class {
3741
3413
  state: request.state
3742
3414
  }).then(settle, reject);
3743
3415
  });
3744
- await new Promise((resolve17, rejectListen) => {
3416
+ await new Promise((resolve15, rejectListen) => {
3745
3417
  server.once("error", rejectListen);
3746
- server.listen(0, "127.0.0.1", () => resolve17());
3418
+ server.listen(0, "127.0.0.1", () => resolve15());
3747
3419
  });
3748
3420
  const address = server.address();
3749
3421
  if (!address || typeof address === "string") {
@@ -3776,8 +3448,8 @@ var LoopbackBrowserLoginAdapter = class {
3776
3448
  } finally {
3777
3449
  clearTimeout(timer);
3778
3450
  request.signal?.removeEventListener("abort", abort);
3779
- await new Promise((resolve17) => {
3780
- server.close(() => resolve17());
3451
+ await new Promise((resolve15) => {
3452
+ server.close(() => resolve15());
3781
3453
  server.closeIdleConnections();
3782
3454
  server.closeAllConnections();
3783
3455
  });
@@ -3892,7 +3564,7 @@ function parse(source) {
3892
3564
  });
3893
3565
  }
3894
3566
  async function runCredentialCommand(input) {
3895
- return await new Promise((resolve17, reject) => {
3567
+ return await new Promise((resolve15, reject) => {
3896
3568
  const child = spawn2(input.command, [...input.args], {
3897
3569
  shell: false,
3898
3570
  windowsHide: true,
@@ -3908,7 +3580,7 @@ async function runCredentialCommand(input) {
3908
3580
  child.stdout.on("data", (chunk) => collect(stdout, chunk));
3909
3581
  child.stderr.on("data", (chunk) => collect(stderr, chunk));
3910
3582
  child.once("error", reject);
3911
- child.once("close", (code2) => resolve17({
3583
+ child.once("close", (code2) => resolve15({
3912
3584
  code: code2 ?? 1,
3913
3585
  stdout: Buffer.concat(stdout).toString("utf8"),
3914
3586
  stderr: Buffer.concat(stderr).toString("utf8")
@@ -3968,7 +3640,7 @@ var SystemCloudTokenStore = class {
3968
3640
  };
3969
3641
 
3970
3642
  // packages/cli-core/src/cloud/mock-client.ts
3971
- import { createHash as createHash5, randomBytes as randomBytes2 } from "node:crypto";
3643
+ import { createHash as createHash4, randomBytes as randomBytes2 } from "node:crypto";
3972
3644
  var MockDeveloperPlatformClient = class {
3973
3645
  #now;
3974
3646
  #buddies = /* @__PURE__ */ new Map();
@@ -3996,7 +3668,7 @@ var MockDeveloperPlatformClient = class {
3996
3668
  const current = this.#require(request.id);
3997
3669
  validateBuddyMetaUpdate(request.meta);
3998
3670
  const onlyAvatar = Object.keys(request.meta).every((key) => key === "avatar");
3999
- const avatar = request.avatar ? `/media/avatar-${request.id}.webp?v=${createHash5("sha256").update(request.avatar.bytes).digest("hex").slice(0, 16)}` : request.meta.avatar === null ? null : current.meta?.avatar ?? null;
3671
+ const avatar = request.avatar ? `/media/avatar-${request.id}.webp?v=${createHash4("sha256").update(request.avatar.bytes).digest("hex").slice(0, 16)}` : request.meta.avatar === null ? null : current.meta?.avatar ?? null;
4000
3672
  const next = this.#value({ ...current, meta: { ...onlyAvatar ? current.meta : request.meta, avatar }, updatedAt: this.#now() });
4001
3673
  this.#buddies.set(request.id, next);
4002
3674
  return structuredClone(next);
@@ -4140,7 +3812,7 @@ function dependencies(options) {
4140
3812
  return { session: options.session, client: options.client };
4141
3813
  }
4142
3814
  function requestedDirectory(options, parsed) {
4143
- return resolve13(options.cwd ?? process.cwd(), parsed.values.get("--directory") ?? ".");
3815
+ return resolve11(options.cwd ?? process.cwd(), parsed.values.get("--directory") ?? ".");
4144
3816
  }
4145
3817
  function auditLabel(status) {
4146
3818
  if (status === "auditing") return "\u5BA1\u6838\u4E2D";
@@ -4221,10 +3893,10 @@ async function runAvatar(parsed, io, options) {
4221
3893
  if (parsed.values.has("--buddy-id") && parsed.values.has("--directory")) {
4222
3894
  throw new CloudCommandUsageError("--buddy-id \u548C --directory \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528");
4223
3895
  }
4224
- const file2 = parsed.values.get("--file");
3896
+ const file = parsed.values.get("--file");
4225
3897
  let upload;
4226
3898
  try {
4227
- upload = file2 ? await readBuddyAvatarFile(resolve13(options.cwd ?? process.cwd(), file2)) : void 0;
3899
+ upload = file ? await readBuddyAvatarFile(resolve11(options.cwd ?? process.cwd(), file)) : void 0;
4228
3900
  } catch (error2) {
4229
3901
  throw new CloudCommandUsageError(error2 instanceof Error ? error2.message : "\u65E0\u6CD5\u8BFB\u53D6\u5934\u50CF\u56FE\u7247");
4230
3902
  }
@@ -4293,8 +3965,8 @@ async function runCloudCommand(command, args, io, options = {}) {
4293
3965
  var CLOUD_COMMAND_HELP = HELP;
4294
3966
 
4295
3967
  // packages/cli-core/src/migration/index.ts
4296
- import { lstat as lstat8, open as open4, readdir as readdir4, realpath as realpath4, stat } from "node:fs/promises";
4297
- import { extname, isAbsolute as isAbsolute2, join as join10, relative, resolve as resolve14, sep, win32 as win322 } from "node:path";
3968
+ import { lstat as lstat7, open as open4, readdir as readdir3, realpath as realpath3, stat } from "node:fs/promises";
3969
+ import { extname, isAbsolute as isAbsolute2, join as join9, relative, resolve as resolve12, sep, win32 as win322 } from "node:path";
4298
3970
  var DEFAULT_SKILL_SCAN_LIMITS = Object.freeze({
4299
3971
  maxFiles: 128,
4300
3972
  maxFileBytes: 256 * 1024,
@@ -4447,7 +4119,7 @@ async function existingProjectRoot(value) {
4447
4119
  return rejectScan("SKILL_PROJECT_ROOT_INVALID", ".", "projectRoot \u5FC5\u987B\u6307\u5411\u4E00\u4E2A\u5DF2\u6709\u9879\u76EE\u76EE\u5F55\u3002");
4448
4120
  }
4449
4121
  try {
4450
- const root = await realpath4(resolve14(value));
4122
+ const root = await realpath3(resolve12(value));
4451
4123
  if (!(await stat(root)).isDirectory()) {
4452
4124
  return rejectScan("SKILL_PROJECT_ROOT_INVALID", ".", "projectRoot \u5FC5\u987B\u6307\u5411\u4E00\u4E2A\u5DF2\u6709\u9879\u76EE\u76EE\u5F55\u3002");
4453
4125
  }
@@ -4463,9 +4135,9 @@ async function existingProjectRoot(value) {
4463
4135
  }
4464
4136
  }
4465
4137
  async function existingSkillRoot(projectRoot, skillPath) {
4466
- const candidate = skillPath === "." ? projectRoot : join10(projectRoot, ...skillPath.split("/"));
4138
+ const candidate = skillPath === "." ? projectRoot : join9(projectRoot, ...skillPath.split("/"));
4467
4139
  try {
4468
- await lstat8(candidate);
4140
+ await lstat7(candidate);
4469
4141
  } catch (cause) {
4470
4142
  if (filesystemCode(cause) === "ENOENT") {
4471
4143
  return rejectScan("SKILL_ROOT_NOT_FOUND", skillPath, "\u627E\u4E0D\u5230\u6307\u5B9A\u7684 Skill \u76EE\u5F55\u3002");
@@ -4474,7 +4146,7 @@ async function existingSkillRoot(projectRoot, skillPath) {
4474
4146
  }
4475
4147
  let root;
4476
4148
  try {
4477
- root = await realpath4(candidate);
4149
+ root = await realpath3(candidate);
4478
4150
  } catch (cause) {
4479
4151
  if (filesystemCode(cause) === "ELOOP") {
4480
4152
  return rejectScan("SKILL_SYMLINK_CYCLE", skillPath, "Skill \u8DEF\u5F84\u5305\u542B\u7B26\u53F7\u94FE\u63A5\u5FAA\u73AF\u3002", cause);
@@ -4500,10 +4172,10 @@ async function existingSkillRoot(projectRoot, skillPath) {
4500
4172
  }
4501
4173
  async function assertEntrypoint(context) {
4502
4174
  const entryPath = reportChild(context.skillPath, "SKILL.md");
4503
- const candidate = join10(context.skillRoot, "SKILL.md");
4175
+ const candidate = join9(context.skillRoot, "SKILL.md");
4504
4176
  try {
4505
- await lstat8(candidate);
4506
- const target = await realpath4(candidate);
4177
+ await lstat7(candidate);
4178
+ const target = await realpath3(candidate);
4507
4179
  if (!isWithin(context.projectRoot, target) || !isWithin(context.skillRoot, target)) {
4508
4180
  rejectScan(
4509
4181
  "SKILL_SYMLINK_ESCAPE",
@@ -4547,7 +4219,7 @@ async function walkDirectory(actualDirectory, reportDirectory, ancestors, contex
4547
4219
  }
4548
4220
  let directory;
4549
4221
  try {
4550
- directory = await realpath4(actualDirectory);
4222
+ directory = await realpath3(actualDirectory);
4551
4223
  } catch (cause) {
4552
4224
  if (filesystemCode(cause) === "ELOOP") {
4553
4225
  return rejectScan("SKILL_SYMLINK_CYCLE", reportDirectory, "Skill \u76EE\u5F55\u5305\u542B\u7B26\u53F7\u94FE\u63A5\u5FAA\u73AF\u3002", cause);
@@ -4567,7 +4239,7 @@ async function walkDirectory(actualDirectory, reportDirectory, ancestors, contex
4567
4239
  nextAncestors.add(directoryKey);
4568
4240
  let entries;
4569
4241
  try {
4570
- entries = await readdir4(directory, { withFileTypes: true, encoding: "utf8" });
4242
+ entries = await readdir3(directory, { withFileTypes: true, encoding: "utf8" });
4571
4243
  } catch (cause) {
4572
4244
  return rejectScan("SKILL_SCAN_IO_ERROR", reportDirectory, "\u65E0\u6CD5\u5217\u51FA Skill \u5B50\u76EE\u5F55\u3002", cause);
4573
4245
  }
@@ -4604,10 +4276,10 @@ async function walkDirectory(actualDirectory, reportDirectory, ancestors, contex
4604
4276
  }
4605
4277
  for (const entry of entries) {
4606
4278
  const childReportPath = reportChild(reportDirectory, entry.name);
4607
- const childPath = join10(directory, entry.name);
4279
+ const childPath = join9(directory, entry.name);
4608
4280
  let target;
4609
4281
  try {
4610
- target = await realpath4(childPath);
4282
+ target = await realpath3(childPath);
4611
4283
  } catch (cause) {
4612
4284
  if (filesystemCode(cause) === "ELOOP") {
4613
4285
  return rejectScan("SKILL_SYMLINK_CYCLE", childReportPath, "Skill \u5185\u5BB9\u5305\u542B\u7B26\u53F7\u94FE\u63A5\u5FAA\u73AF\u3002", cause);
@@ -5058,9 +4730,9 @@ async function scanExternalSkillPortability(options) {
5058
4730
  }
5059
4731
 
5060
4732
  // packages/cli-core/src/push/preflight.ts
5061
- import { createHash as createHash6 } from "node:crypto";
5062
- import { lstat as lstat9, open as open5, readdir as readdir5, realpath as realpath5 } from "node:fs/promises";
5063
- import { isAbsolute as isAbsolute3, join as join11, relative as relative2, resolve as resolve15, sep as sep2, win32 as win323 } from "node:path";
4733
+ import { createHash as createHash5 } from "node:crypto";
4734
+ import { lstat as lstat8, open as open5, readdir as readdir4, realpath as realpath4 } from "node:fs/promises";
4735
+ import { isAbsolute as isAbsolute3, join as join10, relative as relative2, resolve as resolve13, sep as sep2, win32 as win323 } from "node:path";
5064
4736
 
5065
4737
  // packages/cli-core/src/push/errors.ts
5066
4738
  var PushPreflightError = class extends Error {
@@ -5158,7 +4830,7 @@ function error(options) {
5158
4830
  throw new PushPreflightError(options);
5159
4831
  }
5160
4832
  function sha256(value) {
5161
- return `sha256:${createHash6("sha256").update(value).digest("hex")}`;
4833
+ return `sha256:${createHash5("sha256").update(value).digest("hex")}`;
5162
4834
  }
5163
4835
  function positiveLimit(value, name, hardMaximum) {
5164
4836
  if (!Number.isSafeInteger(value) || value < 1 || value > hardMaximum) {
@@ -5248,10 +4920,10 @@ function normalizeBookletPath(value) {
5248
4920
  return normalized;
5249
4921
  }
5250
4922
  async function canonicalProjectRoot(projectRoot) {
5251
- const absolute = resolve15(projectRoot);
4923
+ const absolute = resolve13(projectRoot);
5252
4924
  let entry;
5253
4925
  try {
5254
- entry = await lstat9(absolute);
4926
+ entry = await lstat8(absolute);
5255
4927
  } catch (cause) {
5256
4928
  error({
5257
4929
  code: "PUSH_PROJECT_INVALID",
@@ -5268,7 +4940,7 @@ async function canonicalProjectRoot(projectRoot) {
5268
4940
  });
5269
4941
  }
5270
4942
  try {
5271
- return await realpath5(absolute);
4943
+ return await realpath4(absolute);
5272
4944
  } catch (cause) {
5273
4945
  error({
5274
4946
  code: "PUSH_PROJECT_INVALID",
@@ -5279,10 +4951,10 @@ async function canonicalProjectRoot(projectRoot) {
5279
4951
  }
5280
4952
  }
5281
4953
  async function captureConfigWithinLimit(projectRoot, maxFileBytes, filename) {
5282
- const path = join11(projectRoot, filename);
4954
+ const path = join10(projectRoot, filename);
5283
4955
  let entry;
5284
4956
  try {
5285
- entry = await lstat9(path);
4957
+ entry = await lstat8(path);
5286
4958
  } catch (cause) {
5287
4959
  error({
5288
4960
  code: "PUSH_CONFIG_INVALID",
@@ -5313,22 +4985,22 @@ async function captureConfigWithinLimit(projectRoot, maxFileBytes, filename) {
5313
4985
  maxFileBytes
5314
4986
  });
5315
4987
  }
5316
- function decodeCapturedConfig(file2) {
5317
- if (file2.contents === void 0) {
4988
+ function decodeCapturedConfig(file) {
4989
+ if (file.contents === void 0) {
5318
4990
  error({
5319
4991
  code: "PUSH_CONFIG_INVALID",
5320
- path: file2.path,
5321
- message: `\u65E0\u6CD5\u8BFB\u53D6 ${file2.path} \u5185\u5BB9\u3002`
4992
+ path: file.path,
4993
+ message: `\u65E0\u6CD5\u8BFB\u53D6 ${file.path} \u5185\u5BB9\u3002`
5322
4994
  });
5323
4995
  }
5324
4996
  let source;
5325
4997
  try {
5326
- source = new TextDecoder("utf-8", { fatal: true }).decode(file2.contents);
4998
+ source = new TextDecoder("utf-8", { fatal: true }).decode(file.contents);
5327
4999
  } catch (cause) {
5328
5000
  error({
5329
5001
  code: "PUSH_CONFIG_INVALID",
5330
- path: file2.path,
5331
- message: `${file2.path} \u4E0D\u662F\u6709\u6548 UTF-8\u3002`,
5002
+ path: file.path,
5003
+ message: `${file.path} \u4E0D\u662F\u6709\u6548 UTF-8\u3002`,
5332
5004
  cause
5333
5005
  });
5334
5006
  }
@@ -5349,7 +5021,7 @@ function parseCapturedProject(agentFile) {
5349
5021
  async function selectLockfile(projectRoot) {
5350
5022
  let names;
5351
5023
  try {
5352
- names = await readdir5(projectRoot);
5024
+ names = await readdir4(projectRoot);
5353
5025
  } catch (cause) {
5354
5026
  error({
5355
5027
  code: "PUSH_PROJECT_INVALID",
@@ -5404,7 +5076,7 @@ async function hashRegularFile(options) {
5404
5076
  message: `\u751F\u6210\u6E05\u5355\u65F6\u6587\u4EF6\u53D1\u751F\u53D8\u5316\uFF1A${options.portablePath}`
5405
5077
  });
5406
5078
  }
5407
- const hash = createHash6("sha256");
5079
+ const hash = createHash5("sha256");
5408
5080
  const captured = [];
5409
5081
  const buffer = Buffer.allocUnsafe(READ_BUFFER_BYTES);
5410
5082
  let bytes = 0;
@@ -5458,7 +5130,7 @@ async function createManifest(options) {
5458
5130
  }
5459
5131
  let names;
5460
5132
  try {
5461
- names = await readdir5(directory);
5133
+ names = await readdir4(directory);
5462
5134
  } catch (cause) {
5463
5135
  error({
5464
5136
  code: "PUSH_PROJECT_INVALID",
@@ -5482,10 +5154,10 @@ async function createManifest(options) {
5482
5154
  sensitiveEntriesExcluded += 1;
5483
5155
  continue;
5484
5156
  }
5485
- const absolutePath = join11(directory, name);
5157
+ const absolutePath = join10(directory, name);
5486
5158
  let entry;
5487
5159
  try {
5488
- entry = await lstat9(absolutePath);
5160
+ entry = await lstat8(absolutePath);
5489
5161
  } catch (cause) {
5490
5162
  error({
5491
5163
  code: "PUSH_FILE_CHANGED",
@@ -5516,7 +5188,7 @@ async function createManifest(options) {
5516
5188
  }
5517
5189
  let canonicalPath;
5518
5190
  try {
5519
- canonicalPath = await realpath5(absolutePath);
5191
+ canonicalPath = await realpath4(absolutePath);
5520
5192
  } catch (cause) {
5521
5193
  error({
5522
5194
  code: "PUSH_FILE_CHANGED",
@@ -5575,15 +5247,15 @@ async function createManifest(options) {
5575
5247
  message: `\u63D0\u4EA4\u6587\u4EF6\u603B\u91CF\u8D85\u8FC7\u4E0A\u9650 ${options.limits.maxTotalBytes} bytes\u3002`
5576
5248
  });
5577
5249
  }
5578
- const file2 = await hashRegularFile({
5250
+ const file = await hashRegularFile({
5579
5251
  absolutePath,
5580
5252
  portablePath: path,
5581
5253
  expected: entry,
5582
5254
  captureContents: options.capturePaths.has(path),
5583
5255
  maxFileBytes: options.limits.maxFileBytes
5584
5256
  });
5585
- files.push(file2);
5586
- totalBytes += file2.bytes;
5257
+ files.push(file);
5258
+ totalBytes += file.bytes;
5587
5259
  }
5588
5260
  };
5589
5261
  await walk(options.projectRoot, []);
@@ -5664,10 +5336,10 @@ function validateLockfile(lockfile, contents) {
5664
5336
  function bundleDigest(files) {
5665
5337
  const descriptor = JSON.stringify({
5666
5338
  schemaVersion: "1",
5667
- files: files.map((file2) => ({
5668
- path: file2.path,
5669
- bytes: file2.bytes,
5670
- digest: file2.digest
5339
+ files: files.map((file) => ({
5340
+ path: file.path,
5341
+ bytes: file.bytes,
5342
+ digest: file.digest
5671
5343
  }))
5672
5344
  });
5673
5345
  return sha256(`buddy-push-bundle-v1\0${descriptor}`);
@@ -5677,8 +5349,8 @@ function warning(code2, message) {
5677
5349
  }
5678
5350
  function assertOfficialProjectIncluded(files) {
5679
5351
  for (const path of OFFICIAL_RUNTIME_INPUTS) {
5680
- const file2 = files.find((entry) => entry.path === path);
5681
- if (file2 === void 0 || file2.bytes === 0) {
5352
+ const file = files.find((entry) => entry.path === path);
5353
+ if (file === void 0 || file.bytes === 0) {
5682
5354
  error({
5683
5355
  code: "PUSH_PROJECT_INVALID",
5684
5356
  path,
@@ -5717,7 +5389,7 @@ function assertOfficialProjectIncluded(files) {
5717
5389
  }
5718
5390
  }
5719
5391
  async function assertCapturedConfigStable(options) {
5720
- const manifestEntry = options.manifestFiles.find((file2) => file2.path === options.filename);
5392
+ const manifestEntry = options.manifestFiles.find((file) => file.path === options.filename);
5721
5393
  if (manifestEntry === void 0) {
5722
5394
  error({
5723
5395
  code: "PUSH_CONFIG_INVALID",
@@ -5734,8 +5406,8 @@ async function assertCapturedConfigStable(options) {
5734
5406
  }
5735
5407
  let current;
5736
5408
  try {
5737
- const path = join11(options.projectRoot, options.filename);
5738
- const entry = await lstat9(path);
5409
+ const path = join10(options.projectRoot, options.filename);
5410
+ const entry = await lstat8(path);
5739
5411
  if (!entry.isFile() || entry.isSymbolicLink()) {
5740
5412
  error({
5741
5413
  code: "PUSH_FILE_CHANGED",
@@ -5778,8 +5450,6 @@ async function createPushPreflight(options) {
5778
5450
  BUDDY_AGENT_FILENAME
5779
5451
  );
5780
5452
  parseCapturedProject(initialAgentEntry);
5781
- const widgetDelivery = await checkWidgetDelivery(projectRoot);
5782
- if (widgetDelivery.status === "incomplete") error({ code: "PUSH_WIDGET_DELIVERY_INCOMPLETE", message: widgetDeliverySummary(widgetDelivery) });
5783
5453
  const lockfile = await selectLockfile(projectRoot);
5784
5454
  assertBookletIsNotRequiredInput(bookletPath, lockfile);
5785
5455
  const manifest = await createManifest({
@@ -5788,12 +5458,7 @@ async function createPushPreflight(options) {
5788
5458
  capturePaths: /* @__PURE__ */ new Set([BUDDY_AGENT_FILENAME, lockfile.path, BUDDY_PLATFORM_PACKAGE_JSON, BUDDY_PLATFORM_AGENT_ENTRY, BUDDY_PLATFORM_FACTORY_ENTRY]),
5789
5459
  ...bookletPath === void 0 ? {} : { bookletPath }
5790
5460
  });
5791
- for (const checked of widgetDelivery.files ?? []) {
5792
- if (manifest.files.find((file2) => file2.path === checked.path)?.digest !== checked.digest) {
5793
- error({ code: "PUSH_WIDGET_DELIVERY_INCOMPLETE", message: `\u5C0F\u6302\u4EF6\u6838\u5BF9\u540E\u6587\u4EF6\u53D8\u5316\u6216\u672A\u8FDB\u5165\u4E0A\u4F20\u5305\uFF1A${checked.path}\uFF1B\u8BF7\u91CD\u65B0\u68C0\u67E5\u3002` });
5794
- }
5795
- }
5796
- const lockEntry = manifest.files.find((file2) => file2.path === lockfile.path);
5461
+ const lockEntry = manifest.files.find((file) => file.path === lockfile.path);
5797
5462
  if (lockEntry?.contents === void 0) {
5798
5463
  error({
5799
5464
  code: "PUSH_LOCKFILE_INVALID",
@@ -5831,10 +5496,10 @@ async function createPushPreflight(options) {
5831
5496
  });
5832
5497
  }
5833
5498
  }
5834
- const files = Object.freeze(manifest.files.map((file2) => Object.freeze({
5835
- path: file2.path,
5836
- bytes: file2.bytes,
5837
- digest: file2.digest
5499
+ const files = Object.freeze(manifest.files.map((file) => Object.freeze({
5500
+ path: file.path,
5501
+ bytes: file.bytes,
5502
+ digest: file.digest
5838
5503
  })));
5839
5504
  const warnings = [warning(
5840
5505
  "PREFLIGHT_ONLY",
@@ -5870,16 +5535,16 @@ async function createPushPreflight(options) {
5870
5535
  }
5871
5536
 
5872
5537
  // packages/cli-core/src/push/bundle.ts
5873
- import { createHash as createHash7 } from "node:crypto";
5874
- import { lstat as lstat10, readFile as readFile10, realpath as realpath6 } from "node:fs/promises";
5875
- import { join as join12, relative as relative3, sep as sep3, win32 as win324 } from "node:path";
5538
+ import { createHash as createHash6 } from "node:crypto";
5539
+ import { lstat as lstat9, readFile as readFile9, realpath as realpath5 } from "node:fs/promises";
5540
+ import { join as join11, relative as relative3, sep as sep3, win32 as win324 } from "node:path";
5876
5541
  import { Writable } from "node:stream";
5877
5542
  import { pipeline } from "node:stream/promises";
5878
5543
  import { createGzip } from "node:zlib";
5879
5544
  import { pack } from "tar-stream";
5880
5545
  var MEDIA_TYPE = "application/gzip";
5881
5546
  function digest(bytes) {
5882
- return `sha256:${createHash7("sha256").update(bytes).digest("hex")}`;
5547
+ return `sha256:${createHash6("sha256").update(bytes).digest("hex")}`;
5883
5548
  }
5884
5549
  function changed(path, message, cause) {
5885
5550
  throw new PushPreflightError({
@@ -5893,42 +5558,42 @@ function inside(root, target) {
5893
5558
  const path = relative3(root, target);
5894
5559
  return path === "" || path !== ".." && !path.startsWith(`..${sep3}`) && !path.startsWith("/") && !win324.isAbsolute(path);
5895
5560
  }
5896
- async function capture(root, file2) {
5897
- const absolute = join12(root, ...file2.path.split("/"));
5561
+ async function capture(root, file) {
5562
+ const absolute = join11(root, ...file.path.split("/"));
5898
5563
  try {
5899
- const entry = await lstat10(absolute);
5900
- if (!entry.isFile() || entry.isSymbolicLink() || entry.size !== file2.bytes) {
5901
- changed(file2.path, `\u63D0\u4EA4\u524D\u6587\u4EF6\u53D1\u751F\u53D8\u5316\uFF1A${file2.path}`);
5564
+ const entry = await lstat9(absolute);
5565
+ if (!entry.isFile() || entry.isSymbolicLink() || entry.size !== file.bytes) {
5566
+ changed(file.path, `\u63D0\u4EA4\u524D\u6587\u4EF6\u53D1\u751F\u53D8\u5316\uFF1A${file.path}`);
5902
5567
  }
5903
- const canonical = await realpath6(absolute);
5904
- if (!inside(root, canonical)) changed(file2.path, `\u63D0\u4EA4\u6587\u4EF6\u8D8A\u8FC7\u9879\u76EE\u6839\u76EE\u5F55\uFF1A${file2.path}`);
5905
- const contents = await readFile10(absolute);
5906
- if (contents.byteLength !== file2.bytes || digest(contents) !== file2.digest) {
5907
- changed(file2.path, `\u63D0\u4EA4\u524D\u6587\u4EF6\u5185\u5BB9\u53D1\u751F\u53D8\u5316\uFF1A${file2.path}`);
5568
+ const canonical = await realpath5(absolute);
5569
+ if (!inside(root, canonical)) changed(file.path, `\u63D0\u4EA4\u6587\u4EF6\u8D8A\u8FC7\u9879\u76EE\u6839\u76EE\u5F55\uFF1A${file.path}`);
5570
+ const contents = await readFile9(absolute);
5571
+ if (contents.byteLength !== file.bytes || digest(contents) !== file.digest) {
5572
+ changed(file.path, `\u63D0\u4EA4\u524D\u6587\u4EF6\u5185\u5BB9\u53D1\u751F\u53D8\u5316\uFF1A${file.path}`);
5908
5573
  }
5909
5574
  return Object.freeze({
5910
- path: file2.path,
5911
- bytes: file2.bytes,
5912
- digest: file2.digest,
5575
+ path: file.path,
5576
+ bytes: file.bytes,
5577
+ digest: file.digest,
5913
5578
  content: contents
5914
5579
  });
5915
5580
  } catch (cause) {
5916
5581
  if (cause instanceof PushPreflightError) throw cause;
5917
- changed(file2.path, `\u63D0\u4EA4\u524D\u65E0\u6CD5\u518D\u6B21\u8BFB\u53D6\u6587\u4EF6\uFF1A${file2.path}`, cause);
5582
+ changed(file.path, `\u63D0\u4EA4\u524D\u65E0\u6CD5\u518D\u6B21\u8BFB\u53D6\u6587\u4EF6\uFF1A${file.path}`, cause);
5918
5583
  }
5919
5584
  }
5920
5585
  async function createPushSourceBundle(plan) {
5921
- const canonicalRoot = await realpath6(plan.projectRoot).catch((cause) => changed(plan.projectRoot, "\u63D0\u4EA4\u9879\u76EE\u76EE\u5F55\u5728\u6253\u5305\u524D\u5DF2\u4E0D\u53EF\u7528", cause));
5586
+ const canonicalRoot = await realpath5(plan.projectRoot).catch((cause) => changed(plan.projectRoot, "\u63D0\u4EA4\u9879\u76EE\u76EE\u5F55\u5728\u6253\u5305\u524D\u5DF2\u4E0D\u53EF\u7528", cause));
5922
5587
  if (canonicalRoot !== plan.projectRoot) {
5923
5588
  changed(plan.projectRoot, "\u63D0\u4EA4\u9879\u76EE\u6839\u76EE\u5F55\u5728\u9884\u68C0\u540E\u53D1\u751F\u53D8\u5316");
5924
5589
  }
5925
5590
  const files = [];
5926
- for (const file2 of plan.files) files.push(await capture(canonicalRoot, file2));
5591
+ for (const file of plan.files) files.push(await capture(canonicalRoot, file));
5927
5592
  const descriptor = JSON.stringify({
5928
5593
  schemaVersion: "1",
5929
- files: files.map((file2) => ({ path: file2.path, bytes: file2.bytes, digest: file2.digest }))
5594
+ files: files.map((file) => ({ path: file.path, bytes: file.bytes, digest: file.digest }))
5930
5595
  });
5931
- const calculatedBundleDigest = `sha256:${createHash7("sha256").update(`buddy-push-bundle-v1\0${descriptor}`).digest("hex")}`;
5596
+ const calculatedBundleDigest = `sha256:${createHash6("sha256").update(`buddy-push-bundle-v1\0${descriptor}`).digest("hex")}`;
5932
5597
  if (calculatedBundleDigest !== plan.bundleDigest) {
5933
5598
  changed(plan.projectRoot, "\u63D0\u4EA4\u6E05\u5355\u8EAB\u4EFD\u5728\u6253\u5305\u524D\u53D1\u751F\u53D8\u5316\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C push");
5934
5599
  }
@@ -5941,16 +5606,16 @@ async function createPushSourceBundle(plan) {
5941
5606
  }
5942
5607
  });
5943
5608
  const completed = pipeline(archive, createGzip({ level: 9 }), output);
5944
- for (const file2 of files) {
5609
+ for (const file of files) {
5945
5610
  await new Promise((resolveEntry, rejectEntry) => {
5946
5611
  archive.entry({
5947
- name: file2.path,
5948
- size: file2.content.byteLength,
5612
+ name: file.path,
5613
+ size: file.content.byteLength,
5949
5614
  mode: 420,
5950
5615
  uid: 0,
5951
5616
  gid: 0,
5952
5617
  mtime: /* @__PURE__ */ new Date(0)
5953
- }, file2.content, (cause) => cause ? rejectEntry(cause) : resolveEntry());
5618
+ }, file.content, (cause) => cause ? rejectEntry(cause) : resolveEntry());
5954
5619
  });
5955
5620
  }
5956
5621
  archive.finalize();
@@ -5992,7 +5657,6 @@ var HELP2 = `\u642D\u642D Developer Platform CLI
5992
5657
  buddy-cli login | logout | push | status
5993
5658
  buddy-cli avatar (--file <\u56FE\u7247\u6587\u4EF6> | --clear) [--directory <\u9879\u76EE\u76EE\u5F55> | --buddy-id <\u642D\u5B50 ID>]
5994
5659
  buddy-cli models [--directory <\u9879\u76EE\u76EE\u5F55>] [--json]
5995
- buddy-cli widgets sync | check | verify
5996
5660
  buddy-cli datasets [--directory <\u9879\u76EE\u76EE\u5F55>] [--json]
5997
5661
  buddy-cli preview [--app-server <URL>] [--directory <\u9879\u76EE\u76EE\u5F55>]
5998
5662
  buddy-cli help
@@ -6214,7 +5878,7 @@ function defaultProjectDirectory(name) {
6214
5878
  return `./${folder}`;
6215
5879
  }
6216
5880
  async function initializeProjectRoute(route, args, io, options, application) {
6217
- const cwd = resolve16(options.cwd ?? process.cwd());
5881
+ const cwd = resolve14(options.cwd ?? process.cwd());
6218
5882
  const { name, tagline, intro } = application;
6219
5883
  const directoryInput = await textAnswer(
6220
5884
  io,
@@ -6223,7 +5887,7 @@ async function initializeProjectRoute(route, args, io, options, application) {
6223
5887
  "\u9879\u76EE\u76EE\u5F55\uFF08\u7A7A\u76EE\u5F55\u6216\u5DF2\u6709\u642D\u642D\u5DE5\u7A0B\uFF09",
6224
5888
  defaultProjectDirectory(name)
6225
5889
  );
6226
- const rootDirectory = resolve16(cwd, directoryInput);
5890
+ const rootDirectory = resolve14(cwd, directoryInput);
6227
5891
  await assertInitializableBuddyTarget(rootDirectory);
6228
5892
  const initializationTarget = { directory: rootDirectory, kind: "new" };
6229
5893
  const initializationPlan = options.initializeProject ? void 0 : await planBuddyProjectInitialization(initializationTarget);
@@ -6267,7 +5931,7 @@ async function initializeProjectRoute(route, args, io, options, application) {
6267
5931
  }
6268
5932
  async function runRoute(route, args, io, options) {
6269
5933
  if (!io.canPrompt) assertNonInteractiveProjectArguments(route, args);
6270
- const cwd = resolve16(options.cwd ?? process.cwd());
5934
+ const cwd = resolve14(options.cwd ?? process.cwd());
6271
5935
  const name = await textAnswer(io, args.name, "--name", "\u642D\u5B50\u540D\u79F0", void 0, BUDDY_PROFILE_TEXT_LIMITS.name);
6272
5936
  const tagline = await textAnswer(
6273
5937
  io,
@@ -6295,7 +5959,7 @@ async function runRoute(route, args, io, options) {
6295
5959
  "\u9879\u76EE\u76EE\u5F55",
6296
5960
  defaultProjectDirectory(name)
6297
5961
  );
6298
- const rootDirectory = resolve16(cwd, directoryInput);
5962
+ const rootDirectory = resolve14(cwd, directoryInput);
6299
5963
  await assertInitializableBuddyTarget(rootDirectory);
6300
5964
  const plan = await planBuddyDraftInitialization(rootDirectory);
6301
5965
  const existingBuddyId = plan.existingManifest?.buddyId;
@@ -6329,11 +5993,11 @@ async function runRoute(route, args, io, options) {
6329
5993
  return { ...result, route: "create", draft, buddyId };
6330
5994
  }
6331
5995
  async function resumeProjectArguments(args, cwd, options) {
6332
- const root = resolve16(cwd, args.directory?.trim() || ".");
5996
+ const root = resolve14(cwd, args.directory?.trim() || ".");
6333
5997
  await assertInitializableBuddyTarget(root);
6334
5998
  let entry;
6335
5999
  try {
6336
- entry = await lstat11(join13(root, "buddy.agent.json"));
6000
+ entry = await lstat10(join12(root, "buddy.agent.json"));
6337
6001
  } catch (cause) {
6338
6002
  if (cause.code === "ENOENT") return;
6339
6003
  throw cause;
@@ -6362,7 +6026,7 @@ async function runBuddyCli(args, io, options = {}) {
6362
6026
  try {
6363
6027
  const [command, ...rest] = args;
6364
6028
  if (!command) {
6365
- const cwd = resolve16(options.cwd ?? process.cwd());
6029
+ const cwd = resolve14(options.cwd ?? process.cwd());
6366
6030
  let projectRoot;
6367
6031
  try {
6368
6032
  projectRoot = await findBuddyProjectRoot(cwd);
@@ -6391,7 +6055,6 @@ async function runBuddyCli(args, io, options = {}) {
6391
6055
  return { exitCode: 0 };
6392
6056
  }
6393
6057
  if (command === "models") return await runModelsCommand(rest, io, options.cwd ?? process.cwd(), options.runtimeCatalog);
6394
- if (command === "widgets") return await runWidgetsCommand(rest, io, options.cwd ?? process.cwd());
6395
6058
  if (command === "preview") {
6396
6059
  return options.preview?.(rest, io) ?? failure("preview \u5BBF\u4E3B\u672A\u914D\u7F6E", io, true);
6397
6060
  }
@@ -6418,11 +6081,11 @@ async function runBuddyCli(args, io, options = {}) {
6418
6081
  }
6419
6082
  let route = routeFromMode(parsed.mode);
6420
6083
  if (route === void 0 && !io.canPrompt) requireModeForNonInteractive();
6421
- const cwd = resolve16(options.cwd ?? process.cwd());
6084
+ const cwd = resolve14(options.cwd ?? process.cwd());
6422
6085
  await assertInitializableBuddyTarget(cwd);
6423
6086
  if (parsed.directory !== void 0) {
6424
6087
  if (!parsed.directory.trim()) throw new CliUsageError("--directory \u4E0D\u80FD\u4E3A\u7A7A");
6425
- await assertInitializableBuddyTarget(resolve16(cwd, parsed.directory));
6088
+ await assertInitializableBuddyTarget(resolve14(cwd, parsed.directory));
6426
6089
  }
6427
6090
  await authenticate(options);
6428
6091
  await resumeProjectArguments(parsed, cwd, options);
@@ -6564,7 +6227,6 @@ export {
6564
6227
  assertOutsideBuddyProject,
6565
6228
  buddyAgentConfig,
6566
6229
  buildAgentEnvironment,
6567
- checkWidgetDelivery,
6568
6230
  combineBuddyProject,
6569
6231
  createBuddyConfig,
6570
6232
  createBuddyDevStarter,
@@ -6603,7 +6265,6 @@ export {
6603
6265
  throwIfDevAborted,
6604
6266
  validateBuddyAgentConfig,
6605
6267
  validateBuddyConfig,
6606
- validateBuddyProjectManifest,
6607
- widgetDeliverySummary
6268
+ validateBuddyProjectManifest
6608
6269
  };
6609
6270
  //# sourceMappingURL=core.js.map