@my-life-buddies/cli 0.15.0 → 0.16.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
@@ -215,21 +215,16 @@ async function readRuntimeModelCatalog(projectRoot) {
215
215
  }
216
216
  return Object.freeze({ runtimeVersion, models: Object.freeze([...models]) });
217
217
  }
218
- async function validateRuntimeModel(projectRoot, model) {
219
- if (model === void 0) return;
220
- const catalog = await readRuntimeModelCatalog(projectRoot);
221
- if (!catalog.models.includes(model)) throw new Error(`/model\uFF1A\u5DE5\u7A0B Runtime ${catalog.runtimeVersion} \u4E0D\u652F\u6301 ${model}\uFF1B\u53EF\u9009 ${catalog.models.join("\u3001")}`);
222
- }
223
218
  async function validateRuntimeDatasets(projectRoot, requirements = []) {
224
219
  const catalog = await readRuntimeDataCatalog(projectRoot);
225
220
  const ids = new Set(catalog.datasets.map((item) => item.id));
226
221
  for (const [index, item] of requirements.entries()) {
227
- if (!ids.has(item.id)) throw new Error(`/datasets/${index}/id\uFF1A\u5DE5\u7A0B Runtime ${catalog.runtimeVersion} \u4E0D\u652F\u6301 ${item.id}`);
222
+ if (!ids.has(item.id)) throw new Error(`data-access.json/requirements/${index}/id\uFF1A\u5DE5\u7A0B Runtime ${catalog.runtimeVersion} \u4E0D\u652F\u6301 ${item.id}`);
228
223
  }
229
224
  }
230
225
 
231
226
  // packages/cli-core/src/project-context.ts
232
- import { lstat as lstat7, realpath as realpath3 } from "node:fs/promises";
227
+ import { lstat as lstat7, realpath as realpath3, readFile as readFile10 } from "node:fs/promises";
233
228
  import { dirname, join as join9, resolve as resolve5 } from "node:path";
234
229
 
235
230
  // packages/cli-core/src/config/index.ts
@@ -240,68 +235,29 @@ import {
240
235
  open as open3,
241
236
  readFile as readFile9,
242
237
  readdir as readdir3,
243
- rename as rename5,
238
+ rename as rename6,
244
239
  unlink as unlink4
245
240
  } from "node:fs/promises";
246
- import { randomUUID as randomUUID3 } from "node:crypto";
241
+ import { randomUUID as randomUUID4 } from "node:crypto";
247
242
  import { isAbsolute as isAbsolute2, join as join8, resolve as resolve4, win32 } from "node:path";
248
243
  import { isDeepStrictEqual } from "node:util";
249
244
  import { Ajv2020 } from "ajv/dist/2020.js";
250
245
 
251
- // packages/cli-core/src/config/buddy.agent.schema.json
252
- var buddy_agent_schema_default = {
246
+ // packages/cli-core/src/config/buddy.package.schema.json
247
+ var buddy_package_schema_default = {
253
248
  $schema: "https://json-schema.org/draft/2020-12/schema",
254
- title: "buddy.agent.json",
255
- description: "\u642D\u642D\u9879\u76EE\u8EAB\u4EFD\u3001\u6A21\u578B\u9009\u62E9\u4E0E\u6570\u636E\u8BBF\u95EE\u9700\u6C42\uFF1B\u5DE5\u7A0B\u662F\u5426\u53EF\u8FD0\u884C\u7531\u5B9E\u9645\u6587\u4EF6\u5224\u65AD",
249
+ title: "Buddy package.json",
250
+ description: "package.json \u9876\u5C42 buddyId \u6807\u8BC6\u5E73\u53F0\u642D\u5B50\uFF1B\u5176\u4F59 npm \u5DE5\u7A0B\u5B57\u6BB5\u4FDD\u7559",
256
251
  type: "object",
257
- additionalProperties: false,
258
252
  required: [
259
- "schemaVersion",
260
253
  "buddyId"
261
254
  ],
262
255
  properties: {
263
- schemaVersion: {
264
- const: 1
265
- },
266
256
  buddyId: {
267
257
  type: "string",
268
258
  minLength: 1,
269
259
  maxLength: 256,
270
- pattern: "^[^\\s\\u0000-\\u001f\\u007f]+$",
271
- description: "\u5E73\u53F0\u751F\u6210\u7684\u7A33\u5B9A\u642D\u5B50 ID"
272
- },
273
- model: {
274
- type: "string",
275
- minLength: 1,
276
- maxLength: 128,
277
- pattern: "^[^\\s\\u0000-\\u001f\\u007f]+$",
278
- description: "\u4ECE buddy-cli models \u67E5\u770B Runtime \u6A21\u578B\u76EE\u5F55\uFF1B\u5DE5\u7A0B\u5185\u8BFB\u53D6\u5B89\u88C5\u7248\u672C\uFF0C\u5DE5\u7A0B\u5916\u8BFB\u53D6 npm \u6700\u65B0\u7248\u3002\u8FD0\u884C\u4E0E\u4E0A\u4F20\u9884\u68C0\u6309\u5DE5\u7A0B Runtime \u6821\u9A8C\u3002"
279
- },
280
- datasets: {
281
- type: "array",
282
- description: "\u672C\u642D\u5B50\u7533\u8BF7\u7684\u6570\u636E\u96C6\u53CA\u7528\u9014\uFF1B\u7701\u7565\u6216\u7A7A\u6570\u7EC4\u8868\u793A\u4E0D\u7533\u8BF7\u6570\u636E\uFF0C\u58F0\u660E\u4E0D\u4EE3\u8868\u7528\u6237\u5DF2\u6388\u6743",
283
- default: [],
284
- items: {
285
- type: "object",
286
- additionalProperties: false,
287
- required: ["id", "purpose"],
288
- properties: {
289
- id: {
290
- type: "string",
291
- minLength: 1,
292
- maxLength: 128,
293
- pattern: "^[^\\s\\u0000-\\u001f\\u007f]+$",
294
- description: "\u53D6\u503C\u6765\u81EA\u5DE5\u7A0B Runtime \u5BFC\u51FA\u7684 DATA_ACCESS_CAPABILITIES\uFF0C\u7531\u8FD0\u884C\u4E0E\u4E0A\u4F20\u9884\u68C0\u6821\u9A8C\u3002\u58F0\u660E\u6570\u91CF\u4E0D\u7B49\u4E8E\u5355\u6B21\u67E5\u8BE2\u4E0A\u9650\u3002"
295
- },
296
- purpose: {
297
- type: "string",
298
- minLength: 1,
299
- maxLength: 200,
300
- pattern: "\\S",
301
- description: "\u5411\u7528\u6237\u8BF4\u660E\u8FD9\u53EA\u642D\u5B50\u4E3A\u4F55\u9700\u8981\u8BE5\u6570\u636E"
302
- }
303
- }
304
- }
260
+ pattern: "^[^\\s\\u0000-\\u001f\\u007f]+$"
305
261
  }
306
262
  }
307
263
  };
@@ -443,11 +399,11 @@ async function resolveSkillPackage(definition3, previous, options = {}) {
443
399
  }
444
400
 
445
401
  // packages/cli-core/src/init/avatar-package.ts
446
- var AVATAR_PACKAGE = "avatar-creator-skill";
402
+ var AVATAR_PACKAGE = "@my-life-buddies/avatar-creator-skill";
447
403
  var definition = {
448
404
  name: AVATAR_PACKAGE,
449
405
  label: "Avatar",
450
- cacheFolder: "avatar-skills",
406
+ cacheFolder: "avatar-skills/my-life-buddies",
451
407
  pathEnvironment: "BUDDY_AVATAR_SKILL_PATH",
452
408
  versionFlag: "--avatar-skill-version",
453
409
  protocol: { protocolVersion: 1, skill: "SKILL.md", workflow: "references/cli-workflow.md", workspaceFormat: "buddy-avatar-1" },
@@ -818,8 +774,9 @@ import { lstat as lstat5 } from "node:fs/promises";
818
774
  import { join as join7 } from "node:path";
819
775
 
820
776
  // packages/cli-core/src/init/scaffold.ts
821
- import { lstat as lstat4, mkdir as mkdir5, open as open2, readFile as readFile8, rmdir as rmdir2, unlink as unlink3, writeFile as writeFile6 } from "node:fs/promises";
777
+ import { lstat as lstat4, mkdir as mkdir5, open as open2, readFile as readFile8, rename as rename5, rmdir as rmdir2, unlink as unlink3 } from "node:fs/promises";
822
778
  import { resolve as resolve3 } from "node:path";
779
+ import { randomUUID as randomUUID3 } from "node:crypto";
823
780
 
824
781
  // packages/cli-core/src/config/models.ts
825
782
  var MODEL_IDS = Object.freeze([
@@ -909,14 +866,13 @@ function platformAgentTemplate(name) {
909
866
  return `${promptFor(name)}
910
867
  `;
911
868
  }
912
- function platformFactoryTemplate() {
869
+ function platformFactoryTemplate(model = DEFAULT_MODEL_ID) {
913
870
  return `import { readFileSync } from "node:fs";
914
871
 
915
872
  const systemPrompt = readFileSync(new URL("../agent.md", import.meta.url), "utf8").trim();
916
873
  if (!systemPrompt) throw new Error("agent.md must contain the Buddy system prompt");
917
- const config = JSON.parse(readFileSync(new URL("../buddy.agent.json", import.meta.url), "utf8"));
918
874
  /** @type {import("@my-life-buddies/buddy-runtime").ModelId} */
919
- const model = config.model ?? "${DEFAULT_MODEL_ID}";
875
+ const model = ${JSON.stringify(model)};
920
876
 
921
877
  /**
922
878
  * Builds BuddyOptions when the Runtime creates an agent for a conversation.
@@ -924,7 +880,7 @@ const model = config.model ?? "${DEFAULT_MODEL_ID}";
924
880
  * Shared business code can live in ./services/; directories do not enable capabilities.
925
881
  * Use conversation.memory / dataAccess / widget / resource / proactive for platform capabilities.
926
882
  * Add conversation.tools.data_access_query / data_access_request / data_access_read_result
927
- * to initialState.tools for model-driven data access; declarations come from buddy.agent.json.datasets.
883
+ * to initialState.tools for model-driven data access; declarations come from data-access.json.requirements.
928
884
  * Add conversation.tools.ask_question for multiple-choice questions.
929
885
  * Add conversation.tools.resource_list / resource_read to discover and read reference material.
930
886
  * Place widget assets in ../widgets/<type-id>/index.html and schema.json.
@@ -947,27 +903,16 @@ export default function createBuddyOptions(_conversation) {
947
903
  }
948
904
  function platformStartTemplate() {
949
905
  return `// Generated startup: local DEV and hosted execution use the same Buddy Runtime.
950
- import { readFileSync } from "node:fs";
951
906
  import { BuddyServer } from "@my-life-buddies/buddy-runtime";
952
907
  import createBuddyOptions from "./src/buddy-options.mjs";
953
908
 
954
- const config = JSON.parse(readFileSync(new URL("./buddy.agent.json", import.meta.url), "utf8"));
955
- if (!config || config.schemaVersion !== 1 || typeof config.buddyId !== "string" || !config.buddyId) {
956
- throw new Error("buddy.agent.json is not a complete Buddy project");
957
- }
958
- if (process.env.BUDDY_ID && process.env.BUDDY_ID !== config.buddyId) {
959
- throw new Error("BUDDY_ID does not match buddy.agent.json");
960
- }
961
909
  const lifecycle = new AbortController();
962
910
  const stop = () => lifecycle.abort();
963
911
  process.on("SIGINT", stop);
964
912
  process.on("SIGTERM", stop);
965
913
  let runtime;
966
914
  try {
967
- runtime = await BuddyServer.start({
968
- dataRequirements: config.datasets ?? [],
969
- buddy: createBuddyOptions,
970
- });
915
+ runtime = await BuddyServer.start(createBuddyOptions);
971
916
  if (!lifecycle.signal.aborted) {
972
917
  await new Promise((resolve) => lifecycle.signal.addEventListener("abort", resolve, { once: true }));
973
918
  }
@@ -983,34 +928,13 @@ try {
983
928
  }
984
929
  `;
985
930
  }
986
- function legacyPlatformStartTemplate() {
987
- return platformStartTemplate().replace(" dataRequirements: config.datasets ?? [],", " buddyId: process.env.BUDDY_ID,\n token: process.env.BUDDY_TOKEN,\n dataRequirements: config.datasets ?? [],");
988
- }
989
- async function migrateRuntimeStartup(projectRoot) {
990
- const packagePath = resolve3(projectRoot, BUDDY_PLATFORM_PACKAGE_JSON);
991
- const entryPath = resolve3(projectRoot, BUDDY_PLATFORM_START_ENTRY);
992
- for (const path of [packagePath, entryPath]) {
993
- if (!(await lstat4(path)).isFile()) throw new Error("\u542F\u52A8\u6587\u4EF6\u5FC5\u987B\u662F\u666E\u901A\u6587\u4EF6\uFF0C\u4E0D\u80FD\u4F7F\u7528\u7B26\u53F7\u94FE\u63A5");
994
- }
995
- const pkg = JSON.parse(await readFile8(packagePath, "utf8"));
996
- if (!runtimeUsesEnvironmentIdentity(pkg)) return false;
997
- const current = await readFile8(entryPath, "utf8");
998
- const latest = platformStartTemplate();
999
- const legacy = legacyPlatformStartTemplate();
1000
- let changed2 = false;
1001
- if (current.replace(/\r\n/gu, "\n") === legacy) {
1002
- await writeFile6(entryPath, latest, "utf8");
1003
- changed2 = true;
1004
- }
1005
- if (pkg.scripts?.start === "node start.mjs") {
1006
- pkg.scripts.start = "node --env-file-if-exists=.env start.mjs";
1007
- await writeFile6(packagePath, JSON.stringify(pkg, null, 2) + "\n", "utf8");
1008
- changed2 = true;
1009
- }
1010
- return changed2;
1011
- }
1012
931
  async function scaffoldPlatformAgent(projectRoot, name, options = {}) {
1013
932
  const path = resolve3(projectRoot, BUDDY_PLATFORM_AGENT_ENTRY);
933
+ const packagePath = resolve3(projectRoot, BUDDY_PLATFORM_PACKAGE_JSON);
934
+ if (!(await lstat4(packagePath)).isFile()) throw new Error("package.json \u5FC5\u987B\u662F\u666E\u901A\u6587\u4EF6");
935
+ const originalPackage = await readFile8(packagePath, "utf8");
936
+ const projectPackage = parseBuddyProjectManifest(originalPackage);
937
+ const isIdentityDraft = Object.keys(projectPackage).every((key) => key === "buddyId");
1014
938
  const hasAlternateLockfile = (await Promise.all(["pnpm-lock.yaml", "yarn.lock"].map(async (name2) => {
1015
939
  try {
1016
940
  if (!(await lstat4(resolve3(projectRoot, name2))).isFile()) {
@@ -1024,10 +948,11 @@ async function scaffoldPlatformAgent(projectRoot, name, options = {}) {
1024
948
  }))).some(Boolean);
1025
949
  const files = [
1026
950
  { path, content: platformAgentTemplate(name) },
1027
- { path: resolve3(projectRoot, BUDDY_PLATFORM_FACTORY_ENTRY), content: platformFactoryTemplate() },
951
+ { path: resolve3(projectRoot, BUDDY_PLATFORM_FACTORY_ENTRY), content: platformFactoryTemplate(options.model) },
1028
952
  { path: resolve3(projectRoot, BUDDY_PLATFORM_PACKAGE_JSON), content: await readFile8(new URL("../../resources/agent-template/package.json", import.meta.url), "utf8") },
1029
953
  ...hasAlternateLockfile ? [] : [{ path: resolve3(projectRoot, BUDDY_PLATFORM_PACKAGE_LOCK), content: await readFile8(new URL("../../resources/agent-template/package-lock.json", import.meta.url), "utf8") }],
1030
954
  { path: resolve3(projectRoot, BUDDY_PLATFORM_START_ENTRY), content: platformStartTemplate() },
955
+ { path: resolve3(projectRoot, "data-access.json"), content: '{\n "requirements": []\n}\n' },
1031
956
  { path: resolve3(projectRoot, ".gitignore"), content: "node_modules/\n/.env\n" },
1032
957
  { path: resolve3(projectRoot, ".env.example"), content: "# \u9996\u6B21\u8FD0\u884C buddy-cli dev \u6216\u5728\u540E\u53F0\u542F\u52A8 DEV \u65F6\uFF0CCLI \u4F1A\u51C6\u5907 .env\u3002\nBUDDY_ID=\nBUDDY_TOKEN=\n# \u53EF\u9009\uFF1A\u4F7F\u7528\u5176\u4ED6\u5E73\u53F0\u65F6\u8BBE\u7F6E MLB_GATEWAY_URL\u3002\n" }
1033
958
  ];
@@ -1058,13 +983,17 @@ async function scaffoldPlatformAgent(projectRoot, name, options = {}) {
1058
983
  }
1059
984
  const packageFile = files.find((file) => file.path === resolve3(projectRoot, BUDDY_PLATFORM_PACKAGE_JSON));
1060
985
  const lockFile = files.find((file) => file.path === resolve3(projectRoot, BUDDY_PLATFORM_PACKAGE_LOCK));
1061
- if (options.resolveDependencies && lockFile && handles.some((file) => file.path === packageFile.path) && handles.some((file) => file.path === lockFile.path)) {
986
+ packageFile.content = JSON.stringify({ ...JSON.parse(packageFile.content), buddyId: projectPackage.buddyId }, null, 2) + "\n";
987
+ if (options.resolveDependencies && isIdentityDraft && lockFile && handles.some((file) => file.path === lockFile.path)) {
1062
988
  const template = await options.resolveDependencies({ packageJson: packageFile.content, packageLock: lockFile.content });
989
+ if (parseBuddyProjectManifest(template.packageJson).buddyId !== projectPackage.buddyId) {
990
+ throw new Error("\u4F9D\u8D56\u89E3\u6790\u6539\u53D8\u4E86 package.json.buddyId\uFF0C\u5DF2\u505C\u6B62\u8865\u9F50\u5DE5\u7A0B");
991
+ }
1063
992
  packageFile.content = template.packageJson;
1064
993
  lockFile.content = template.packageLock;
1065
994
  }
1066
- if (lockFile && (handles.some((file) => file.path === packageFile.path) || handles.some((file) => file.path === lockFile.path))) {
1067
- const packageContents = handles.some((file) => file.path === packageFile.path) ? packageFile.content : await readFile8(packageFile.path, "utf8");
995
+ if (lockFile && (isIdentityDraft || handles.some((file) => file.path === lockFile.path))) {
996
+ const packageContents = isIdentityDraft ? packageFile.content : await readFile8(packageFile.path, "utf8");
1068
997
  const lockContents = handles.some((file) => file.path === lockFile.path) ? lockFile.content : await readFile8(lockFile.path, "utf8");
1069
998
  const declared = JSON.parse(packageContents).dependencies ?? {};
1070
999
  const locked = JSON.parse(lockContents).packages?.[""]?.dependencies ?? {};
@@ -1072,17 +1001,30 @@ async function scaffoldPlatformAgent(projectRoot, name, options = {}) {
1072
1001
  throw new Error("\u5DF2\u6709 package.json \u4E0E\u5F85\u8865\u9F50\u7684\u9501\u6587\u4EF6\u4E0D\u4E00\u81F4\uFF0C\u8BF7\u7528\u5DE5\u7A0B\u7684\u5305\u7BA1\u7406\u5668\u6062\u590D\u5339\u914D\u7684\u4F9D\u8D56\u6587\u4EF6\u540E\u91CD\u8BD5");
1073
1002
  }
1074
1003
  }
1075
- const effectivePackage = handles.some((file) => file.path === packageFile.path) ? packageFile.content : await readFile8(packageFile.path, "utf8");
1076
- if (!runtimeUsesEnvironmentIdentity(JSON.parse(effectivePackage))) {
1077
- files.find((file) => file.path === resolve3(projectRoot, BUDDY_PLATFORM_START_ENTRY)).content = legacyPlatformStartTemplate();
1078
- }
1079
1004
  for (const { path: filePath, handle } of handles) {
1080
1005
  const file = files.find((candidate) => candidate.path === filePath);
1081
1006
  await handle.writeFile(file.content, "utf8");
1082
1007
  await handle.sync();
1083
1008
  }
1084
- const migrated = await migrateRuntimeStartup(projectRoot);
1085
- return Object.freeze({ path, created: migrated || handles.length > 0 || createdDirectories.length > 0 });
1009
+ if (isIdentityDraft) {
1010
+ const temporary = `${packagePath}.${randomUUID3()}.tmp`;
1011
+ const handle = await open2(temporary, "wx", 384);
1012
+ try {
1013
+ await handle.writeFile(packageFile.content, "utf8");
1014
+ await handle.sync();
1015
+ await handle.close();
1016
+ if (!(await lstat4(packagePath)).isFile() || await readFile8(packagePath, "utf8") !== originalPackage) {
1017
+ throw new Error("\u8865\u9F50\u5DE5\u7A0B\u65F6 package.json \u5DF2\u6539\u53D8\uFF0C\u8BF7\u91CD\u8BD5");
1018
+ }
1019
+ await rename5(temporary, packagePath);
1020
+ } finally {
1021
+ await handle.close().catch(() => void 0);
1022
+ await unlink3(temporary).catch((cause) => {
1023
+ if (cause.code !== "ENOENT") throw cause;
1024
+ });
1025
+ }
1026
+ }
1027
+ return Object.freeze({ path, created: isIdentityDraft || handles.length > 0 || createdDirectories.length > 0 });
1086
1028
  } catch (cause) {
1087
1029
  await Promise.all(handles.map(({ handle }) => handle.close().catch(() => void 0)));
1088
1030
  await Promise.all(handles.map(({ path: createdPath }) => unlink3(createdPath).catch(() => void 0)));
@@ -1117,8 +1059,8 @@ async function missingBuddyAgentFiles(projectRoot) {
1117
1059
  }
1118
1060
 
1119
1061
  // packages/cli-core/src/config/index.ts
1120
- var BUDDY_AGENT_FILENAME = "buddy.agent.json";
1121
- var BUDDY_AGENT_SCHEMA = buddy_agent_schema_default;
1062
+ var BUDDY_PACKAGE_FILENAME = "package.json";
1063
+ var BUDDY_PACKAGE_SCHEMA = buddy_package_schema_default;
1122
1064
  var BuddyConfigValidationError = class extends Error {
1123
1065
  constructor(issues) {
1124
1066
  super(issues.map((issue2) => `${issue2.path}: ${issue2.message}`).join("\n"));
@@ -1128,7 +1070,7 @@ var BuddyConfigValidationError = class extends Error {
1128
1070
  issues;
1129
1071
  };
1130
1072
  var ajv = new Ajv2020({ allErrors: true, strict: true });
1131
- var validateAgentSchema = ajv.compile(buddy_agent_schema_default);
1073
+ var validateAgentSchema = ajv.compile(buddy_package_schema_default);
1132
1074
  function schemaIssues(errors) {
1133
1075
  return (errors ?? []).map((error2) => ({
1134
1076
  path: error2.instancePath || "/",
@@ -1154,7 +1096,7 @@ function validateBuddyConfig(value) {
1154
1096
  if (typeof value !== "object" || value === null || Array.isArray(value)) {
1155
1097
  return { ok: false, issues: [{ path: "/", message: "\u914D\u7F6E\u5FC5\u987B\u662F\u5BF9\u8C61" }] };
1156
1098
  }
1157
- const result = validateBuddyAgentConfig({ schemaVersion: 1, ...value });
1099
+ const result = validateBuddyAgentConfig(value);
1158
1100
  return result.ok ? { ok: true, value } : result;
1159
1101
  }
1160
1102
  function assertBuddyConfig(value) {
@@ -1174,15 +1116,7 @@ function validateBuddyProjectManifest(value) {
1174
1116
  if (!validateAgentSchema(value)) {
1175
1117
  return { ok: false, issues: schemaIssues(validateAgentSchema.errors) };
1176
1118
  }
1177
- const manifest = value;
1178
- const seen = /* @__PURE__ */ new Set();
1179
- for (const [index, dataset] of (manifest.datasets ?? []).entries()) {
1180
- if (seen.has(dataset.id)) {
1181
- return { ok: false, issues: [{ path: `/datasets/${index}/id`, message: `\u6570\u636E\u96C6\u4E0D\u80FD\u91CD\u590D\u58F0\u660E\uFF1A${dataset.id}` }] };
1182
- }
1183
- seen.add(dataset.id);
1184
- }
1185
- return { ok: true, value: manifest };
1119
+ return { ok: true, value };
1186
1120
  }
1187
1121
  function validateBuddyAgentConfig(value) {
1188
1122
  return validateBuddyProjectManifest(value);
@@ -1208,18 +1142,13 @@ function serializeBuddyAgentConfig(config) {
1208
1142
  `;
1209
1143
  }
1210
1144
  function buddyAgentConfig(config) {
1211
- return assertBuddyAgentConfig({ schemaVersion: 1, ...config });
1145
+ return assertBuddyAgentConfig({ buddyId: config.buddyId });
1212
1146
  }
1213
1147
  function combineBuddyProject(config) {
1214
- const { schemaVersion: _version, ...project } = assertBuddyAgentConfig(config);
1215
- return project;
1148
+ return { buddyId: assertBuddyAgentConfig(config).buddyId };
1216
1149
  }
1217
1150
  function createBuddyConfig(options) {
1218
- return assertBuddyConfig({
1219
- buddyId: options.buddyId,
1220
- ...options.model === void 0 ? {} : { model: options.model },
1221
- datasets: options.datasets ?? []
1222
- });
1151
+ return assertBuddyConfig({ buddyId: options.buddyId });
1223
1152
  }
1224
1153
  var ProjectInitializationError = class extends Error {
1225
1154
  constructor(code2, message, targetPath, options) {
@@ -1296,7 +1225,7 @@ async function readExistingManifest(agentConfigPath) {
1296
1225
  if (state2.kind !== "other") {
1297
1226
  throw new ProjectInitializationError(
1298
1227
  "TARGET_CHANGED",
1299
- `${BUDDY_AGENT_FILENAME} \u5FC5\u987B\u662F\u666E\u901A\u6587\u4EF6\uFF0C\u4E0D\u80FD\u662F\u76EE\u5F55\u3002`,
1228
+ `${BUDDY_PACKAGE_FILENAME} \u5FC5\u987B\u662F\u666E\u901A\u6587\u4EF6\uFF0C\u4E0D\u80FD\u662F\u76EE\u5F55\u3002`,
1300
1229
  agentConfigPath
1301
1230
  );
1302
1231
  }
@@ -1304,7 +1233,7 @@ async function readExistingManifest(agentConfigPath) {
1304
1233
  if (!entry2.isFile() || entry2.isSymbolicLink()) {
1305
1234
  throw new ProjectInitializationError(
1306
1235
  "TARGET_CHANGED",
1307
- `${BUDDY_AGENT_FILENAME} \u5FC5\u987B\u662F\u9879\u76EE\u5185\u7684\u666E\u901A\u6587\u4EF6\uFF0C\u4E0D\u80FD\u662F\u7B26\u53F7\u94FE\u63A5\u3002`,
1236
+ `${BUDDY_PACKAGE_FILENAME} \u5FC5\u987B\u662F\u9879\u76EE\u5185\u7684\u666E\u901A\u6587\u4EF6\uFF0C\u4E0D\u80FD\u662F\u7B26\u53F7\u94FE\u63A5\u3002`,
1308
1237
  agentConfigPath
1309
1238
  );
1310
1239
  }
@@ -1313,7 +1242,7 @@ async function readExistingManifest(agentConfigPath) {
1313
1242
  } catch (cause) {
1314
1243
  throw new ProjectInitializationError(
1315
1244
  "TARGET_CHANGED",
1316
- `\u65E0\u6CD5\u8BFB\u53D6\u6216\u6821\u9A8C\u5DF2\u6709 ${BUDDY_AGENT_FILENAME}\u3002`,
1245
+ `\u65E0\u6CD5\u8BFB\u53D6\u6216\u6821\u9A8C\u5DF2\u6709 ${BUDDY_PACKAGE_FILENAME}\u3002`,
1317
1246
  agentConfigPath,
1318
1247
  { cause }
1319
1248
  );
@@ -1321,7 +1250,7 @@ async function readExistingManifest(agentConfigPath) {
1321
1250
  }
1322
1251
  async function planBuddyDraftInitialization(directory) {
1323
1252
  const rootDirectory = resolve4(directory);
1324
- const agentConfigPath = join8(rootDirectory, BUDDY_AGENT_FILENAME);
1253
+ const agentConfigPath = join8(rootDirectory, BUDDY_PACKAGE_FILENAME);
1325
1254
  const state2 = await pathState(rootDirectory);
1326
1255
  if (state2.kind === "other") {
1327
1256
  throw new ProjectInitializationError(
@@ -1349,7 +1278,7 @@ async function planBuddyDraftInitialization(directory) {
1349
1278
  }
1350
1279
  async function planBuddyProjectInitialization(options) {
1351
1280
  const rootDirectory = resolve4(options.directory);
1352
- const agentConfigPath = resolve4(rootDirectory, BUDDY_AGENT_FILENAME);
1281
+ const agentConfigPath = resolve4(rootDirectory, BUDDY_PACKAGE_FILENAME);
1353
1282
  const state2 = await pathState(rootDirectory);
1354
1283
  if (state2.kind === "other") {
1355
1284
  throw new ProjectInitializationError(
@@ -1395,7 +1324,7 @@ async function publishNewFile(options) {
1395
1324
  let publishedHandle;
1396
1325
  const temporaryPath = join8(
1397
1326
  options.rootDirectory,
1398
- `.${options.temporaryLabel}.${process.pid}.${randomUUID3()}.tmp`
1327
+ `.${options.temporaryLabel}.${process.pid}.${randomUUID4()}.tmp`
1399
1328
  );
1400
1329
  let temporaryIdentity;
1401
1330
  let publishedIdentity;
@@ -1466,7 +1395,7 @@ async function publishNewFile(options) {
1466
1395
  async function replaceExistingFile(options) {
1467
1396
  const temporaryPath = join8(
1468
1397
  options.rootDirectory,
1469
- `.${options.temporaryLabel}.${process.pid}.${randomUUID3()}.tmp`
1398
+ `.${options.temporaryLabel}.${process.pid}.${randomUUID4()}.tmp`
1470
1399
  );
1471
1400
  const handle = await open3(temporaryPath, "wx", 384);
1472
1401
  try {
@@ -1478,7 +1407,7 @@ async function replaceExistingFile(options) {
1478
1407
  try {
1479
1408
  const root = await pathState(options.rootDirectory);
1480
1409
  if (root.kind !== "directory" || root.identity !== options.directoryIdentity || await fileIdentity(options.targetPath) !== options.expectedFileIdentity) throw targetChanged({ rootDirectory: options.rootDirectory });
1481
- await rename5(temporaryPath, options.targetPath);
1410
+ await rename6(temporaryPath, options.targetPath);
1482
1411
  if (await readFile9(options.targetPath, "utf8") !== options.contents) {
1483
1412
  throw targetChanged({ rootDirectory: options.rootDirectory });
1484
1413
  }
@@ -1496,7 +1425,7 @@ async function applyBuddyDraftInitialization(plan, draft) {
1496
1425
  if (current === void 0 || current.buddyId !== draft.buddyId || (await missingBuddyAgentFiles(plan.rootDirectory)).length === 0) {
1497
1426
  throw new ProjectInitializationError(
1498
1427
  "ALREADY_INITIALIZED",
1499
- `\u5DF2\u6709 ${BUDDY_AGENT_FILENAME} \u7ED1\u5B9A\u7684 buddyId \u4E0E\u672C\u6B21\u4E91\u7AEF\u642D\u5B50\u4E0D\u4E00\u81F4\u3002`,
1428
+ `\u5DF2\u6709 ${BUDDY_PACKAGE_FILENAME} \u7ED1\u5B9A\u7684 buddyId \u4E0E\u672C\u6B21\u4E91\u7AEF\u642D\u5B50\u4E0D\u4E00\u81F4\u3002`,
1500
1429
  plan.agentConfigPath
1501
1430
  );
1502
1431
  }
@@ -1520,7 +1449,7 @@ async function applyBuddyDraftInitialization(plan, draft) {
1520
1449
  if (cause.code === "EEXIST") {
1521
1450
  throw new ProjectInitializationError(
1522
1451
  "ALREADY_INITIALIZED",
1523
- `\u9879\u76EE\u5DF2\u7ECF\u5B58\u5728 ${BUDDY_AGENT_FILENAME}\uFF0C\u6CA1\u6709\u8986\u76D6\u4EFB\u4F55\u6587\u4EF6\u3002`,
1452
+ `\u9879\u76EE\u5DF2\u7ECF\u5B58\u5728 ${BUDDY_PACKAGE_FILENAME}\uFF0C\u6CA1\u6709\u8986\u76D6\u4EFB\u4F55\u6587\u4EF6\u3002`,
1524
1453
  plan.agentConfigPath,
1525
1454
  { cause }
1526
1455
  );
@@ -1528,7 +1457,7 @@ async function applyBuddyDraftInitialization(plan, draft) {
1528
1457
  if (cause instanceof ProjectInitializationError) throw cause;
1529
1458
  throw new ProjectInitializationError(
1530
1459
  "WRITE_FAILED",
1531
- `\u65E0\u6CD5\u5199\u5165 ${BUDDY_AGENT_FILENAME}\uFF0C\u9879\u76EE\u8EAB\u4EFD\u6CA1\u6709\u521D\u59CB\u5316\u5B8C\u6210\u3002`,
1460
+ `\u65E0\u6CD5\u5199\u5165 ${BUDDY_PACKAGE_FILENAME}\uFF0C\u9879\u76EE\u8EAB\u4EFD\u6CA1\u6709\u521D\u59CB\u5316\u5B8C\u6210\u3002`,
1532
1461
  plan.agentConfigPath,
1533
1462
  { cause }
1534
1463
  );
@@ -1539,7 +1468,7 @@ async function applyBuddyProjectInitialization(plan, config) {
1539
1468
  if (plan.existingManifest !== void 0 && plan.existingManifest.buddyId !== requestedConfig.buddyId) {
1540
1469
  throw new ProjectInitializationError(
1541
1470
  "ALREADY_INITIALIZED",
1542
- `\u5DF2\u6709 ${BUDDY_AGENT_FILENAME} \u7ED1\u5B9A\u7684\u662F ${plan.existingManifest.buddyId}\uFF0C\u4E0D\u80FD\u6539\u6210 ${requestedConfig.buddyId}\u3002`,
1471
+ `\u5DF2\u6709 ${BUDDY_PACKAGE_FILENAME} \u7ED1\u5B9A\u7684\u662F ${plan.existingManifest.buddyId}\uFF0C\u4E0D\u80FD\u6539\u6210 ${requestedConfig.buddyId}\u3002`,
1543
1472
  plan.agentConfigPath
1544
1473
  );
1545
1474
  }
@@ -1585,7 +1514,7 @@ async function applyBuddyProjectInitialization(plan, config) {
1585
1514
  if (cause.code === "EEXIST") {
1586
1515
  throw new ProjectInitializationError(
1587
1516
  "ALREADY_INITIALIZED",
1588
- `${BUDDY_AGENT_FILENAME} \u5DF2\u88AB\u5176\u4ED6\u64CD\u4F5C\u521B\u5EFA\uFF0C\u6CA1\u6709\u8986\u76D6\u4EFB\u4F55\u6587\u4EF6\u3002`,
1517
+ `${BUDDY_PACKAGE_FILENAME} \u5DF2\u88AB\u5176\u4ED6\u64CD\u4F5C\u521B\u5EFA\uFF0C\u6CA1\u6709\u8986\u76D6\u4EFB\u4F55\u6587\u4EF6\u3002`,
1589
1518
  plan.rootDirectory,
1590
1519
  { cause }
1591
1520
  );
@@ -1593,7 +1522,7 @@ async function applyBuddyProjectInitialization(plan, config) {
1593
1522
  if (cause instanceof ProjectInitializationError) throw cause;
1594
1523
  throw new ProjectInitializationError(
1595
1524
  "WRITE_FAILED",
1596
- `\u65E0\u6CD5\u5199\u5165 ${BUDDY_AGENT_FILENAME}\uFF0C\u9879\u76EE\u521D\u59CB\u5316\u6CA1\u6709\u5B8C\u6210\u3002`,
1525
+ `\u65E0\u6CD5\u5199\u5165 ${BUDDY_PACKAGE_FILENAME}\uFF0C\u9879\u76EE\u521D\u59CB\u5316\u6CA1\u6709\u5B8C\u6210\u3002`,
1597
1526
  plan.rootDirectory,
1598
1527
  { cause }
1599
1528
  );
@@ -1605,11 +1534,11 @@ async function initializeBuddyProject(options) {
1605
1534
  }
1606
1535
  async function readBuddyProjectManifest(projectRoot) {
1607
1536
  const rootDirectory = resolve4(projectRoot);
1608
- return parseBuddyProjectManifest(await readFile9(resolve4(rootDirectory, BUDDY_AGENT_FILENAME), "utf8"));
1537
+ return parseBuddyProjectManifest(await readFile9(resolve4(rootDirectory, BUDDY_PACKAGE_FILENAME), "utf8"));
1609
1538
  }
1610
1539
  async function readBuddyAgentConfig(projectRoot) {
1611
1540
  const rootDirectory = resolve4(projectRoot);
1612
- const source = await readFile9(resolve4(rootDirectory, BUDDY_AGENT_FILENAME), "utf8");
1541
+ const source = await readFile9(resolve4(rootDirectory, BUDDY_PACKAGE_FILENAME), "utf8");
1613
1542
  return parseBuddyAgentConfig(source);
1614
1543
  }
1615
1544
  async function readBuddyConfig(projectRoot) {
@@ -1673,7 +1602,15 @@ async function projectFileState(directory, filename) {
1673
1602
  async function searchUp(startDirectory) {
1674
1603
  let directory = startDirectory;
1675
1604
  while (true) {
1676
- if (await projectFileState(directory, BUDDY_AGENT_FILENAME) === "valid") return directory;
1605
+ if (await projectFileState(directory, BUDDY_PACKAGE_FILENAME) === "valid") {
1606
+ let pkg;
1607
+ try {
1608
+ pkg = JSON.parse(await readFile10(join9(directory, BUDDY_PACKAGE_FILENAME), "utf8"));
1609
+ } catch (cause) {
1610
+ throw new BuddyProjectContextError("PROJECT_CONFIG_INVALID", `\u65E0\u6CD5\u89E3\u6790 ${join9(directory, BUDDY_PACKAGE_FILENAME)}`, directory, { cause });
1611
+ }
1612
+ if (pkg && typeof pkg === "object" && Object.hasOwn(pkg, "buddyId")) return directory;
1613
+ }
1677
1614
  const parent = dirname(directory);
1678
1615
  if (parent === directory) return void 0;
1679
1616
  directory = parent;
@@ -1690,14 +1627,14 @@ async function requireBuddyProjectRoot(startDirectory) {
1690
1627
  "PROJECT_NOT_FOUND",
1691
1628
  [
1692
1629
  "\u5F53\u524D\u76EE\u5F55\u4E0D\u5C5E\u4E8E\u642D\u642D\u9879\u76EE\u3002",
1693
- `\u8BF7\u8FDB\u5165\u5305\u542B ${BUDDY_AGENT_FILENAME} \u7684\u9879\u76EE\u76EE\u5F55\u540E\u91CD\u8BD5\uFF0C\u6216\u8005\u8FD0\u884C buddy-cli init \u521B\u5EFA\u65B0\u9879\u76EE\u3002`
1630
+ `\u8BF7\u8FDB\u5165\u5305\u542B\u9876\u5C42 buddyId \u7684 ${BUDDY_PACKAGE_FILENAME} \u6240\u5728\u9879\u76EE\u76EE\u5F55\u540E\u91CD\u8BD5\uFF0C\u6216\u8005\u8FD0\u884C buddy-cli init \u521B\u5EFA\u65B0\u9879\u76EE\u3002`
1694
1631
  ].join("\n"),
1695
1632
  requested
1696
1633
  );
1697
1634
  }
1698
1635
  async function requireBuddyAgentProjectRoot(startDirectory) {
1699
1636
  const root = await requireBuddyProjectRoot(startDirectory);
1700
- const agentPath = join9(root, BUDDY_AGENT_FILENAME);
1637
+ const agentPath = join9(root, BUDDY_PACKAGE_FILENAME);
1701
1638
  try {
1702
1639
  await readBuddyAgentConfig(root);
1703
1640
  const missing2 = await missingBuddyAgentFiles(root);
@@ -1707,7 +1644,7 @@ async function requireBuddyAgentProjectRoot(startDirectory) {
1707
1644
  throw new BuddyProjectContextError(
1708
1645
  "PROJECT_NOT_FOUND",
1709
1646
  [
1710
- `\u5F53\u524D buddy.agent.json \u6240\u5728\u5DE5\u7A0B\u5C1A\u4E0D\u53EF\u8FD0\u884C\uFF1A${cause instanceof Error ? cause.message : "\u8BF7\u68C0\u67E5 buddy.agent.json \u4E0E\u5DE5\u7A0B\u6587\u4EF6"}`,
1647
+ `\u5F53\u524D package.json \u6240\u5728\u5DE5\u7A0B\u5C1A\u4E0D\u53EF\u8FD0\u884C\uFF1A${cause instanceof Error ? cause.message : "\u8BF7\u68C0\u67E5 package.json \u4E0E\u5DE5\u7A0B\u6587\u4EF6"}`,
1711
1648
  "\u8BF7\u5148\u8FD0\u884C buddy-cli init --mode direct \u8865\u9F50\u5B98\u65B9 Runtime \u5DE5\u7A0B\uFF0C\u518D\u8FD0\u884C dev\u3001preview \u6216 push\u3002"
1712
1649
  ].join("\n"),
1713
1650
  agentPath,
@@ -1768,7 +1705,7 @@ async function assertInitializableBuddyTarget(target) {
1768
1705
  } catch (cause) {
1769
1706
  throw new BuddyProjectContextError(
1770
1707
  "PROJECT_CONFIG_INVALID",
1771
- `${join9(projectRoot, BUDDY_AGENT_FILENAME)} \u4E0D\u662F\u6709\u6548\u7684\u9879\u76EE\u6E05\u5355\u3002`,
1708
+ `${join9(projectRoot, BUDDY_PACKAGE_FILENAME)} \u4E0D\u662F\u6709\u6548\u7684\u9879\u76EE\u6E05\u5355\u3002`,
1772
1709
  requested,
1773
1710
  { cause }
1774
1711
  );
@@ -1799,7 +1736,7 @@ async function runtimeCatalogSource(directory, options = {}) {
1799
1736
  var MODELS_COMMAND_HELP = `\u7528\u6CD5: buddy-cli models [--directory <\u9879\u76EE\u76EE\u5F55>] [--json]
1800
1737
  \u59CB\u7EC8\u8054\u7F51\u67E5\u8BE2\u516C\u5171 npm \u6700\u65B0 Runtime\uFF0C\u8BFB\u53D6\u5E76\u7F13\u5B58\u5176\u6A21\u578B\u76EE\u5F55\u3002
1801
1738
  \u65E0\u9700\u767B\u5F55\u642D\u642D\u8D26\u53F7\u3002\u8F93\u51FA\u5305\u542B\u5B9E\u9645 Runtime \u7248\u672C\u548C\u6765\u6E90\u3002
1802
- \u5C06\u6240\u9009 ID \u5199\u5165 buddy.agent.json.model\uFF1B\u6A21\u677F\u5728 initialState.model \u4E2D\u4F7F\u7528\u5B83\u3002`;
1739
+ \u5C06\u6240\u9009 ID \u5199\u5165 src/buddy-options.mjs \u7684 initialState.model\uFF1B\u6A21\u677F\u5728 initialState.model \u4E2D\u4F7F\u7528\u5B83\u3002`;
1803
1740
  async function runModelsCommand(args, io, cwd, options = {}) {
1804
1741
  try {
1805
1742
  if (args.length === 1 && (args[0] === "--help" || args[0] === "-h")) {
@@ -1820,7 +1757,7 @@ ${MODELS_COMMAND_HELP}`);
1820
1757
  else {
1821
1758
  io.write(`npm \u6700\u65B0 Runtime ${catalog.runtimeVersion} \u63D0\u4F9B ${catalog.models.length} \u4E2A\u6A21\u578B\uFF1A`);
1822
1759
  for (const id of catalog.models) io.write(`- ${id}`);
1823
- io.write("\u5C06\u6240\u9009 ID \u5199\u5165 buddy.agent.json.model\uFF1B\u81EA\u5B9A\u4E49\u4F1A\u8BDD\u5DE5\u5382\u4E5F\u53EF\u6309\u4F1A\u8BDD\u8BBE\u7F6E initialState.model\u3002");
1760
+ io.write("\u5C06\u6240\u9009 ID \u5199\u5165 src/buddy-options.mjs \u7684 initialState.model\uFF1B\u81EA\u5B9A\u4E49\u4F1A\u8BDD\u5DE5\u5382\u4E5F\u53EF\u6309\u4F1A\u8BDD\u8BBE\u7F6E initialState.model\u3002");
1824
1761
  }
1825
1762
  return { exitCode: 0 };
1826
1763
  } catch (cause) {
@@ -1830,13 +1767,13 @@ ${MODELS_COMMAND_HELP}`);
1830
1767
  }
1831
1768
 
1832
1769
  // packages/cli-core/src/index.ts
1833
- import { lstat as lstat13 } from "node:fs/promises";
1770
+ import { lstat as lstat14 } from "node:fs/promises";
1834
1771
 
1835
1772
  // packages/cli-core/src/commands/datasets.ts
1836
1773
  import { resolve as resolve7 } from "node:path";
1837
1774
  var DATASETS_COMMAND_HELP = `\u7528\u6CD5: buddy-cli datasets [--directory <\u9879\u76EE\u76EE\u5F55>] [--json]
1838
1775
  \u59CB\u7EC8\u8054\u7F51\u67E5\u8BE2\u516C\u5171 npm \u6700\u65B0 Runtime\uFF0C\u8BFB\u53D6\u5E76\u7F13\u5B58\u5176 DATA_ACCESS_CAPABILITIES\u3002
1839
- \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`;
1776
+ \u65E0\u9700\u767B\u5F55\u642D\u642D\u8D26\u53F7\u3002\u5C06\u6240\u9009 id \u4E0E\u7528\u9014 purpose \u5199\u5165 data-access.json.requirements\uFF1B\u76EE\u5F55\u4E0D\u4EE3\u8868\u7528\u6237\u5DF2\u6388\u6743\u3002`;
1840
1777
  async function runDatasetsCommand(args, io, cwd, options = {}) {
1841
1778
  try {
1842
1779
  if (args.length === 1 && (args[0] === "--help" || args[0] === "-h")) {
@@ -1857,7 +1794,7 @@ ${DATASETS_COMMAND_HELP}`);
1857
1794
  else {
1858
1795
  io.write(`npm \u6700\u65B0 Runtime ${catalog.runtimeVersion} \u63D0\u4F9B ${catalog.datasets.length} \u9879\u6570\u636E\u80FD\u529B\uFF1A`);
1859
1796
  for (const item of catalog.datasets) io.write(`- ${item.id} \u2014 ${item.title}\uFF08${item.source}\uFF0CSchema ${item.schemaVersion}\uFF09`);
1860
- io.write("\u5C06\u6240\u9009 id \u548C purpose \u5199\u5165 buddy.agent.json.datasets\uFF1B\u7528\u6237\u6388\u6743\u7531\u5E73\u53F0\u5904\u7406\u3002");
1797
+ io.write("\u5C06\u6240\u9009 id \u548C purpose \u5199\u5165 data-access.json.requirements\uFF1B\u7528\u6237\u6388\u6743\u7531\u5E73\u53F0\u5904\u7406\u3002");
1861
1798
  }
1862
1799
  return { exitCode: 0 };
1863
1800
  } catch (cause) {
@@ -1867,8 +1804,8 @@ ${DATASETS_COMMAND_HELP}`);
1867
1804
  }
1868
1805
 
1869
1806
  // packages/cli-core/src/commands/knowledge.ts
1870
- import { createHash as createHash2, randomUUID as randomUUID4 } from "node:crypto";
1871
- import { lstat as lstat8, mkdir as mkdir7, readFile as readFile10, rename as rename6, unlink as unlink5, writeFile as writeFile7 } from "node:fs/promises";
1807
+ import { createHash as createHash2, randomUUID as randomUUID5 } from "node:crypto";
1808
+ import { lstat as lstat8, mkdir as mkdir7, readFile as readFile11, rename as rename7, unlink as unlink5, writeFile as writeFile6 } from "node:fs/promises";
1872
1809
  import { dirname as dirname2, join as join10, resolve as resolve8 } from "node:path";
1873
1810
  var MANIFEST = "knowledge-manifest.json";
1874
1811
  var INDEX = "resources/knowledge/index.md";
@@ -1927,7 +1864,7 @@ async function read(root, path) {
1927
1864
  });
1928
1865
  if (!entry2) return void 0;
1929
1866
  if (!entry2.isFile() || entry2.size > MAX_BYTES) throw new Error(`\u6587\u4EF6\u5FC5\u987B\u662F\u666E\u901A\u6587\u4EF6\u4E14\u4E0D\u8D85\u8FC7 100 MiB\uFF1A${path}`);
1930
- return readFile10(full);
1867
+ return readFile11(full);
1931
1868
  }
1932
1869
  async function requiredRead(root, path) {
1933
1870
  const bytes = await read(root, path);
@@ -1937,10 +1874,10 @@ async function requiredRead(root, path) {
1937
1874
  async function atomicWrite(root, path, value) {
1938
1875
  const full = await safePath(root, path);
1939
1876
  await mkdir7(dirname2(full), { recursive: true });
1940
- const temporary = `${full}.${randomUUID4()}.tmp`;
1941
- await writeFile7(temporary, value, { flag: "wx", mode: 384 });
1877
+ const temporary = `${full}.${randomUUID5()}.tmp`;
1878
+ await writeFile6(temporary, value, { flag: "wx", mode: 384 });
1942
1879
  try {
1943
- await rename6(temporary, full);
1880
+ await rename7(temporary, full);
1944
1881
  } finally {
1945
1882
  await unlink5(temporary).catch((error2) => {
1946
1883
  if (!missing(error2)) throw error2;
@@ -2113,7 +2050,7 @@ async function syncKnowledge(root, planPath) {
2113
2050
  if (current && hash2(current) !== hash2(content) && hash2(current) !== expected.get(path)) conflicts.push(path);
2114
2051
  }
2115
2052
  if (conflicts.length) {
2116
- const directory = `.buddy/knowledge/conflicts/${randomUUID4()}`;
2053
+ const directory = `.buddy/knowledge/conflicts/${randomUUID5()}`;
2117
2054
  for (const [path, content] of files) await atomicWrite(root, `${directory}/${path}`, content);
2118
2055
  await atomicWrite(root, `${directory}/${MANIFEST}`, json(next));
2119
2056
  return { status: "conflict", conflicts, candidateDirectory: directory, written: [] };
@@ -2180,20 +2117,20 @@ ${KNOWLEDGE_HELP}`);
2180
2117
  }
2181
2118
 
2182
2119
  // packages/cli-core/src/index.ts
2183
- import { join as join20, resolve as resolve18 } from "node:path";
2120
+ import { join as join21, resolve as resolve18 } from "node:path";
2184
2121
 
2185
2122
  // packages/cli-core/src/init/creator.ts
2186
- import { createHash as createHash3, randomUUID as randomUUID5 } from "node:crypto";
2187
- import { link as link2, lstat as lstat9, mkdir as mkdir8, readFile as readFile11, rename as rename7, unlink as unlink6, writeFile as writeFile8 } from "node:fs/promises";
2123
+ import { createHash as createHash3, randomUUID as randomUUID6 } from "node:crypto";
2124
+ import { link as link2, lstat as lstat9, mkdir as mkdir8, readFile as readFile12, rename as rename8, unlink as unlink6, writeFile as writeFile7 } from "node:fs/promises";
2188
2125
  import { dirname as dirname3, join as join12 } from "node:path";
2189
2126
 
2190
2127
  // packages/cli-core/src/init/creator-package.ts
2191
- var CREATOR_PACKAGE = "@my-life-buddies/creator-skill";
2128
+ var CREATOR_PACKAGE = "@my-life-buddies/buddy-creator-skill";
2192
2129
  var validCreatorLock = validSkillLock;
2193
2130
  var definition2 = {
2194
2131
  name: CREATOR_PACKAGE,
2195
2132
  label: "Creator",
2196
- cacheFolder: "creator-skills",
2133
+ cacheFolder: "creator-skills/buddy-creator-skill",
2197
2134
  pathEnvironment: "BUDDY_CREATOR_SKILL_PATH",
2198
2135
  versionFlag: "--creator-version",
2199
2136
  protocol: { protocolVersion: 1, entrypoint: "scripts/buddy.py", skill: "SKILL.md", workflow: "references/cli-workflow.md", workspaceFormat: "buddy-creator-1" },
@@ -2269,18 +2206,19 @@ ${KNOWLEDGE_GUIDE}
2269
2206
  | \u5FC5\u987B\u9075\u5FAA\u7684\u5904\u7406\u987A\u5E8F\u6216\u9644\u52A0\u5904\u7406 | \u5148\u770B Runtime \u9ED8\u8BA4\u56DE\u5408\u662F\u5426\u6EE1\u8DB3\uFF1B\u5FC5\u987B\u7531\u7A0B\u5E8F\u4FDD\u8BC1\u7684\u987A\u5E8F\u53EF\u7528 Tool\uFF0C\u6216\u5728 \`src/buddy-options.mjs\` \u4F7F\u7528 \`beforeToolCall\`\u3001\`afterToolCall\`\u3001\`shouldStopAfterTurn\` \u7B49\u56DE\u5408\u94A9\u5B50\u3002 |
2270
2207
  | \u4EE5\u540E\u8FD8\u9700\u8981\u8BB0\u4F4F\u7684\u4FE1\u606F | \u901A\u8FC7 \`conversation.memory\` \u843D\u5B9E\u4FDD\u5B58\u3001\u8BFB\u53D6\u3001\u66F4\u65B0\u548C\u9057\u5FD8\uFF0C\u5E76\u6309\u9700\u8981\u5C01\u88C5\u4E3A\u6A21\u578B Tool\u3002\u65B0 Runtime \u4E0D\u4F1A\u81EA\u52A8\u67E5\u8BE2\u6216\u63D0\u70BC\u8BB0\u5FC6\uFF1B\u662F\u5426\u4FDD\u5B58\u3001\u4FDD\u5B58\u4EC0\u4E48\u5FC5\u987B\u7531\u4E1A\u52A1\u4EE3\u7801\u548C\u5DF2\u786E\u8BA4\u7684\u6570\u636E\u8FB9\u754C\u51B3\u5B9A\u3002 |
2271
2208
  | \u56DE\u7B54\u65F6\u9700\u8981\u53C2\u8003\u7684\u5386\u53F2\u3001\u8BA1\u5212\u548C\u72B6\u6001 | Runtime \u4F1A\u4ECE MLB \u91CD\u5EFA\u4F1A\u8BDD\u5386\u53F2\uFF1B\u957F\u671F\u8BA1\u5212\u548C\u7ED3\u6784\u5316\u72B6\u6001\u4E0D\u80FD\u53EA\u4F9D\u8D56\u5B83\u4E00\u76F4\u7559\u5728\u6700\u8FD1\u804A\u5929\u91CC\u3002\u6309\u9700\u6C42\u4F7F\u7528 Memory\u3001\u6388\u6743\u6570\u636E\u6216\u4E1A\u52A1 Tool\uFF0C\u4E0D\u8981\u627F\u8BFA\u9ED8\u8BA4\u914D\u7F6E\u5DF2\u7ECF\u8986\u76D6\u3002 |
2272
- | \u6A21\u578B\u548C\u5E73\u53F0\u8D44\u6E90 | \u5DF2\u786E\u5B9A\u7684\u6A21\u578B\u76F4\u63A5\u6CBF\u7528\uFF1B\u672A\u6307\u5B9A\u65F6\u67E5\u8BE2 \`buddy-cli models\`\uFF0C\u6838\u5BF9\u53EF\u7528\u6027\u5E76\u91C7\u7528\u6EE1\u8DB3\u9700\u6C42\u7684\u9009\u62E9\uFF0C\u4E0D\u9ED8\u8BA4\u518D\u95EE\u4E00\u8F6E\u9009\u578B\u95EE\u9898\uFF0C\u4E5F\u4E0D\u7F16\u9020\u4EF7\u683C\u6216\u80FD\u529B\u3002\u6A21\u677F\u628A\u914D\u7F6E\u4E2D\u7684\u6A21\u578B\u4EA4\u7ED9 \`initialState.model\`\uFF1B\u81EA\u5B9A\u4E49\u5DE5\u5382\u4E5F\u53EF\u6309\u4F1A\u8BDD\u9009\u62E9\u53D7\u652F\u6301\u6A21\u578B\uFF1B\u4F1A\u4EA7\u751F\u65B0\u7684\u8D39\u7528\u3001\u6570\u636E\u4F7F\u7528\u6216\u6743\u9650\u8FB9\u754C\u65F6\u5148\u786E\u8BA4\u3002 |
2209
+ | \u6A21\u578B\u548C\u5E73\u53F0\u8D44\u6E90 | \u5DF2\u786E\u5B9A\u7684\u6A21\u578B\u76F4\u63A5\u6CBF\u7528\uFF1B\u672A\u6307\u5B9A\u65F6\u67E5\u8BE2 \`buddy-cli models\`\uFF0C\u6838\u5BF9\u53EF\u7528\u6027\u5E76\u91C7\u7528\u6EE1\u8DB3\u9700\u6C42\u7684\u9009\u62E9\uFF0C\u4E0D\u9ED8\u8BA4\u518D\u95EE\u4E00\u8F6E\u9009\u578B\u95EE\u9898\uFF0C\u4E5F\u4E0D\u7F16\u9020\u4EF7\u683C\u6216\u80FD\u529B\u3002\u6A21\u578B\u76F4\u63A5\u5199\u5165\u4E1A\u52A1\u5DE5\u5382\u8FD4\u56DE\u7684 \`initialState.model\`\uFF1B\u81EA\u5B9A\u4E49\u5DE5\u5382\u4E5F\u53EF\u6309\u4F1A\u8BDD\u9009\u62E9\u53D7\u652F\u6301\u6A21\u578B\uFF1B\u4F1A\u4EA7\u751F\u65B0\u7684\u8D39\u7528\u3001\u6570\u636E\u4F7F\u7528\u6216\u6743\u9650\u8FB9\u754C\u65F6\u5148\u786E\u8BA4\u3002 |
2273
2210
 
2274
- \`src/buddy-options.mjs\` \u662F\u6BCF\u573A\u4F1A\u8BDD\u7684\u4E1A\u52A1\u88C5\u914D\u5165\u53E3\uFF0C\u5BFC\u51FA \`createBuddyOptions(conversation)\`\uFF0C\u8FD4\u56DE \`initialState\`\u3001\u5728 \`initialState.tools\` \u6CE8\u518C\u7684\u4E1A\u52A1\u53CA\u5E73\u53F0\u5DE5\u5177\u548C\u53EF\u9009\u56DE\u5408\u94A9\u5B50\u3002\`start.mjs\` \u4ECE \`./src/buddy-options.mjs\` \u5BFC\u5165\u5DE5\u5382\u5E76\u4F20\u7ED9 \`BuddyServer.start({ dataRequirements: config.datasets ?? [], buddy: createBuddyOptions })\`\uFF1B\u7EC4\u88C5\u5668\u8BFB\u53D6 \`buddy.agent.json.model\`\uFF0C\u7701\u7565\u65F6\u7528 \`kimi-k2.6\`\uFF0C\u653E\u5165 \`initialState.model\`\uFF1B\u7528 \`new URL("../agent.md", import.meta.url)\` \u8BFB\u53D6\u6839\u76EE\u5F55 Prompt\u3002\u9ED8\u8BA4\u6A21\u677F\u53EA\u662F\u8D77\u70B9\uFF0C\u53EA\u6539\u8BF4\u660E\u4E0D\u7B49\u4E8E\u6539\u53D8\u4E86\u4FDD\u5B58\u3001\u67E5\u8BE2\u6216\u5904\u7406\u903B\u8F91\u3002 Runtime 0.16.0 \u4ECE\u73AF\u5883\u53D8\u91CF\u8BFB\u53D6\u8EAB\u4EFD\u548C\u4EE4\u724C\uFF1B\u9996\u6B21\u542F\u52A8 DEV \u65F6 CLI \u51C6\u5907\u5DE5\u7A0B \`.env\`\uFF0CNode \u7528 \`--env-file-if-exists=.env\` \u52A0\u8F7D\u3002\u4E0D\u8981\u5C06 token \u5199\u5165\u4E1A\u52A1\u4EE3\u7801\u3002
2211
+ \`src/buddy-options.mjs\` \u662F\u6BCF\u573A\u4F1A\u8BDD\u7684\u4E1A\u52A1\u88C5\u914D\u5165\u53E3\uFF0C\u5BFC\u51FA \`createBuddyOptions(conversation)\`\uFF0C\u8FD4\u56DE \`initialState\`\u3001\u5728 \`initialState.tools\` \u6CE8\u518C\u7684\u4E1A\u52A1\u53CA\u5E73\u53F0\u5DE5\u5177\u548C\u53EF\u9009\u56DE\u5408\u94A9\u5B50\u3002\`start.mjs\` \u4ECE \`./src/buddy-options.mjs\` \u5BFC\u5165\u5DE5\u5382\u5E76\u4F20\u7ED9 \`BuddyServer.start(createBuddyOptions)\`\uFF1B\u6A21\u578B\u76F4\u63A5\u5199\u5728\u5DE5\u5382\u8FD4\u56DE\u7684 \`initialState.model\`\uFF0C\u6A21\u677F\u4E3A \`kimi-k2.6\`\uFF1B\u7528 \`new URL("../agent.md", import.meta.url)\` \u8BFB\u53D6\u6839\u76EE\u5F55 Prompt\u3002\u9ED8\u8BA4\u6A21\u677F\u53EA\u662F\u8D77\u70B9\uFF0C\u53EA\u6539\u8BF4\u660E\u4E0D\u7B49\u4E8E\u6539\u53D8\u4E86\u4FDD\u5B58\u3001\u67E5\u8BE2\u6216\u5904\u7406\u903B\u8F91\u3002 Runtime 0.17.0 \u4ECE\u73AF\u5883\u53D8\u91CF\u8BFB\u53D6\u8EAB\u4EFD\u548C\u4EE4\u724C\uFF1B\u9996\u6B21\u542F\u52A8 DEV \u65F6 CLI \u51C6\u5907\u5DE5\u7A0B \`.env\`\uFF0CNode \u7528 \`--env-file-if-exists=.env\` \u52A0\u8F7D\u3002\u4E0D\u8981\u5C06 token \u5199\u5165\u4E1A\u52A1\u4EE3\u7801\u3002
2275
2212
 
2276
2213
  ### \u6309\u76EE\u5F55\u804C\u8D23\u7EC4\u7EC7\u5B9E\u73B0
2277
2214
 
2278
2215
  | \u4F4D\u7F6E | \u804C\u8D23\u4E0E\u751F\u6210\u65F6\u673A |
2279
2216
  | --- | --- |
2280
- | \`buddy.agent.json\` | \u9ED8\u8BA4\u751F\u6210\uFF0C\u4FDD\u5B58\u5E73\u53F0\u8EAB\u4EFD\u3001\u53EF\u9009\u6A21\u578B\u548C\u6570\u636E\u9700\u6C42 datasets\uFF0C\u4E0D\u653E\u4E1A\u52A1\u51FD\u6570 |
2217
+ | \`package.json\` | \u9ED8\u8BA4\u751F\u6210\uFF0C\u4FDD\u5B58\u9876\u5C42 buddyId\u3001npm \u542F\u52A8\u547D\u4EE4\u548C\u4F9D\u8D56\uFF1B\u4E0D\u4FDD\u5B58 model\u3001datasets \u6216 schemaVersion |
2281
2218
  | \`agent.md\` | \u9ED8\u8BA4\u751F\u6210\uFF0C\u4FDD\u5B58\u7CFB\u7EDF Prompt |
2282
2219
  | \`start.mjs\` | \u9ED8\u8BA4\u751F\u6210\uFF0C\u8BFB\u53D6\u542F\u52A8\u914D\u7F6E\u3001\u542F\u52A8 Runtime \u5E76\u5904\u7406\u9000\u51FA |
2283
- | \`package.json\`\u3001\`package-lock.json\` | \u9ED8\u8BA4\u751F\u6210\uFF0C\u58F0\u660E\u542F\u52A8\u547D\u4EE4\u3001\u51C6\u786E Runtime \u7248\u672C\u5E76\u9501\u5B9A\u4F9D\u8D56 |
2220
+ | \`package-lock.json\` | \u9ED8\u8BA4\u751F\u6210\uFF0C\u9501\u5B9A\u4F9D\u8D56 |
2221
+ | \`data-access.json\` | \u9ED8\u8BA4\u751F\u6210\uFF0Crequirements \u6570\u7EC4\u58F0\u660E\u6570\u636E\u96C6 ID \u548C\u7528\u9014\uFF1B\u65E0\u9700\u6C42\u4E3A\u7A7A\u6570\u7EC4 |
2284
2222
  | \`src/buddy-options.mjs\` | \u9ED8\u8BA4\u751F\u6210\uFF0C\u7EC4\u88C5\u5E76\u6CE8\u518C\u4F1A\u8BDD\u4E2D\u7684\u80FD\u529B |
2285
2223
  | \`src/tools/\` | \u9ED8\u8BA4\u7A7A\u76EE\u5F55\uFF1B\u653E\u6A21\u578B\u53EF\u8C03\u7528\u7684\u5DE5\u5177\u540D\u79F0\u3001\u8BF4\u660E\u3001\u53C2\u6570 Schema \u548C\u6267\u884C\u51FD\u6570 |
2286
2224
  | \`src/hooks/\` | \u9ED8\u8BA4\u7A7A\u76EE\u5F55\uFF1B\u653E\u5DE5\u5177\u8C03\u7528\u524D\u540E\u3001\u505C\u6B62\u7B49\u94A9\u5B50 |
@@ -2301,9 +2239,9 @@ Tool \u548C Hook \u662F Runtime \u7684\u6269\u5C55\u70B9\uFF1BService \u53EA\u66
2301
2239
 
2302
2240
  \u5E73\u53F0\u80FD\u529B\u8981\u4EE5\u5B9E\u9645\u63A5\u5165\u4E3A\u51C6\u3002\u5F53\u524D Runtime \u63D0\u4F9B\u4F1A\u8BDD\u6D88\u606F\u3001Memory\u3001\u6388\u6743\u6570\u636E\u3001\u5C0F\u6302\u4EF6\u548C\u672C\u5730 Markdown \u8D44\u6599\u80FD\u529B\uFF1B\u6CA1\u6709\u63A5\u901A\u7684 Files\u3001Knowledge \u4E0D\u80FD\u56E0\u624B\u518C\u63D0\u5230\u5C31\u5BA3\u79F0\u53EF\u7528\u3002\u666E\u901A Tool \u4E5F\u4E0D\u4EE3\u8868\u5DF2\u7ECF\u63D0\u4F9B\u5B9A\u65F6\u3001\u957F\u671F\u4EFB\u52A1\u3001\u540E\u53F0\u8C03\u5EA6\u6216\u4E3B\u52A8\u89E6\u8FBE\u3002\u624B\u518C\u63CF\u8FF0\u7684\u4ED8\u8D39\u3001\u53D1\u5E03\u7B49\u670D\u52A1\u8BBE\u8BA1\u4E5F\u4E0D\u6784\u6210\u6267\u884C\u6536\u8D39\u6216\u53D1\u5E03\u52A8\u4F5C\u7684\u6388\u6743\u3002
2303
2241
 
2304
- \u9700\u8981\u7528\u6237\u6570\u636E\u65F6\uFF0C\u5148\u5728\u5DE5\u7A0B\u76EE\u5F55\u6267\u884C \`buddy-cli datasets\`\uFF08\u811A\u672C\u53EF\u7528 \`--json\`\uFF09\uFF0C\u4ECE npm \u6700\u65B0 Runtime \u5BFC\u51FA\u8BFB\u53D6\u5168\u90E8\u6570\u636E\u96C6\uFF1B\u4E0D\u8981\u6C42\u767B\u5F55\uFF0C\u4E0D\u4ECE Server \u62C9\u76EE\u5F55\u3002CLI \u6BCF\u6B21\u67E5\u8BE2 latest\uFF0C\u540C\u7248\u672C\u590D\u7528\u7F13\u5B58\uFF0C\u4E0D\u590D\u5236\u679A\u4E3E\u3002\u76EE\u5F55\u547D\u4EE4\u4F1A\u63D0\u793A\u5DE5\u7A0B\u7248\u672C\u5DEE\u5F02\uFF1B\u4F7F\u7528\u65B0\u7248\u80FD\u529B\u524D\uFF0C\u7531\u4F60\u6216\u5F00\u53D1 Agent \u6309\u63D0\u793A\u5347\u7EA7\u4F9D\u8D56\uFF0C\u68C0\u67E5\u542F\u52A8\u53C2\u6570\u3001\u6A21\u578B\u3001datasets\u3001\u5DE5\u5177\u53CA Hook \u7684\u9002\u914D\u5E76\u9A8C\u8BC1 DEV\u3002CLI \u4E0D\u81EA\u52A8\u4FEE\u6539\u5DE5\u7A0B\u4F9D\u8D56\u6216\u914D\u7F6E\u3002\u628A\u5B9E\u9645\u9700\u8981\u7684 \`id\` \u548C\u7528\u9014 \`purpose\` \u5199\u5165 \`buddy.agent.json.datasets\`\uFF0C\u540C\u4E00 ID \u53EA\u5199\u4E00\u6B21\uFF0C\u7528\u9014\u4E0D\u80FD\u4E3A\u7A7A\u4E14\u6700\u591A 200 \u5B57\uFF1B\u65E0\u9700\u6C42\u65F6\u4FDD\u7559\u7A7A\u6570\u7EC4\u3002DEV \u548C\u58F0\u660E\u975E\u7A7A\u65F6\u7684 push \u9884\u68C0\u7528\u8FD9\u4EFD\u5DE5\u7A0B\u4F9D\u8D56\u6821\u9A8C ID\uFF1B\u9700\u8981\u5148\u5B89\u88C5\u4E0E package.json \u51C6\u786E\u7248\u672C\u4E00\u81F4\u7684 Runtime\u3002\u6E05\u5355\u58F0\u660E\u6570\u91CF\u4E0D\u7B49\u4E8E\u5355\u6B21\u67E5\u8BE2\u4E0A\u9650\uFF0C\u5F53\u524D\u4E00\u6B21\u67E5\u8BE2\u6700\u591A 8 \u9879\u3002
2242
+ \u9700\u8981\u7528\u6237\u6570\u636E\u65F6\uFF0C\u5148\u5728\u5DE5\u7A0B\u76EE\u5F55\u6267\u884C \`buddy-cli datasets\`\uFF08\u811A\u672C\u53EF\u7528 \`--json\`\uFF09\uFF0C\u4ECE npm \u6700\u65B0 Runtime \u5BFC\u51FA\u8BFB\u53D6\u5168\u90E8\u6570\u636E\u96C6\uFF1B\u4E0D\u8981\u6C42\u767B\u5F55\uFF0C\u4E0D\u4ECE Server \u62C9\u76EE\u5F55\u3002CLI \u6BCF\u6B21\u67E5\u8BE2 latest\uFF0C\u540C\u7248\u672C\u590D\u7528\u7F13\u5B58\uFF0C\u4E0D\u590D\u5236\u679A\u4E3E\u3002\u76EE\u5F55\u547D\u4EE4\u4F1A\u63D0\u793A\u5DE5\u7A0B\u7248\u672C\u5DEE\u5F02\uFF1B\u4F7F\u7528\u65B0\u7248\u80FD\u529B\u524D\uFF0C\u7531\u4F60\u6216\u5F00\u53D1 Agent \u6309\u63D0\u793A\u5347\u7EA7\u4F9D\u8D56\uFF0C\u68C0\u67E5\u542F\u52A8\u53C2\u6570\u3001\u6A21\u578B\u3001datasets\u3001\u5DE5\u5177\u53CA Hook \u7684\u9002\u914D\u5E76\u9A8C\u8BC1 DEV\u3002CLI \u4E0D\u81EA\u52A8\u4FEE\u6539\u5DE5\u7A0B\u4F9D\u8D56\u6216\u914D\u7F6E\u3002\u628A\u5B9E\u9645\u9700\u8981\u7684 \`id\` \u548C\u7528\u9014 \`purpose\` \u5199\u5165 \`data-access.json.requirements\`\uFF0C\u6700\u591A 32 \u9879\uFF0C\u540C\u4E00 ID \u53EA\u5199\u4E00\u6B21\uFF0CID \u548C\u7528\u9014\u53BB\u9664\u9996\u5C3E\u7A7A\u767D\uFF0C\u7528\u9014\u4E3A 1\uFF5E200 \u5B57\uFF1B\u65E0\u9700\u6C42\u65F6\u4FDD\u7559\u7A7A\u6570\u7EC4\u3002DEV \u548C\u58F0\u660E\u975E\u7A7A\u65F6\u7684 push \u9884\u68C0\u7528\u8FD9\u4EFD\u5DE5\u7A0B\u4F9D\u8D56\u6821\u9A8C ID\uFF1B\u9700\u8981\u5148\u5B89\u88C5\u4E0E package.json \u51C6\u786E\u7248\u672C\u4E00\u81F4\u7684 Runtime\u3002\u6E05\u5355\u58F0\u660E\u6570\u91CF\u4E0D\u7B49\u4E8E\u5355\u6B21\u67E5\u8BE2\u4E0A\u9650\uFF0C\u5F53\u524D\u4E00\u6B21\u67E5\u8BE2\u6700\u591A 8 \u9879\u3002
2305
2243
 
2306
- \`start.mjs\` \u5C06\u58F0\u660E\u4EA4\u7ED9 \`StartOptions.dataRequirements\`\u3002Runtime \u5728\u5B9E\u9645\u6570\u636E\u67E5\u8BE2\u3001HealthKit \u6388\u6743\u548C\u4E3B\u52A8\u670D\u52A1\u8BF7\u6C42\u4E2D\u643A\u5E26\u5B8C\u6574\u58F0\u660E\uFF0C\u7531 Server \u6821\u9A8C\u8303\u56F4\u4E0E\u7528\u6237\u540C\u610F\uFF1B\u586B\u5199\u914D\u7F6E\u4E0D\u8868\u793A\u5DF2\u7ECF\u6388\u6743\u3002\u670D\u52A1\u7AEF\u4ECE\u4E0A\u4F20\u5305\u89E3\u6790\u5E76\u7ED1\u5B9A\u53D1\u5E03\u7248\u672C\u4ECD\u5F85\u5B9E\u73B0\u3002
2244
+ Runtime \u542F\u52A8\u65F6\u8BFB\u53D6\u6839\u76EE\u5F55 \`data-access.json\`\uFF0C\u901A\u8FC7 \`PUT /internal/v1/data-access/requirements\` \u767B\u8BB0\uFF0C\u6210\u529F\u540E\u518D\u8FDE\u63A5\u4E8B\u4EF6\u6D41\uFF1B\u767B\u8BB0\u5931\u8D25\u963B\u6B62\u542F\u52A8\u3002\u6587\u4EF6\u7F3A\u5931\u6216\u7A7A\u6570\u7EC4\u90FD\u4F1A\u4E0A\u4F20\u7A7A\u58F0\u660E\u5E76\u6E05\u9664\u65E7\u58F0\u660E\u3002DEV \u4FDD\u5B58\u8BE5\u6587\u4EF6\u540E\u81EA\u52A8\u91CD\u542F\u5E76\u91CD\u65B0\u767B\u8BB0\u3002\u58F0\u660E\u4E0D\u8868\u793A\u7528\u6237\u5DF2\u6388\u6743\uFF1B\u4F4D\u7F6E\u548C\u65E5\u5386\u4E0D\u653E\u5165\u6B64\u6587\u4EF6\u3002
2307
2245
 
2308
2246
  \u6A21\u578B\u9700\u8981\u67E5\u6570\u636E\u65F6\uFF0C\u5728 \`src/buddy-options.mjs\` \u7684 \`initialState.tools\` \u4E2D\u52A0\u5165 \`conversation.tools.data_access_query\`\uFF1B\u9700\u8981\u5411\u7528\u6237\u7533\u8BF7\u65F6\u52A0\u5165 \`conversation.tools.data_access_request\`\uFF0C\u4F4D\u7F6E\u3001\u65E5\u5386\u7684\u4E00\u6B21\u6027\u7ED3\u679C\u901A\u8FC7 \`data_access_read_result\` \u8BFB\u53D6\uFF0CHealthKit \u5219\u91CD\u65B0\u67E5\u8BE2 Dataset\u3002\u4E1A\u52A1\u4EE3\u7801\u5BF9\u5E94\u4F7F\u7528 \`conversation.dataAccess.query/request/readResult\`\u3002\u65B0\u5EFA\u5DE5\u7A0B\u52A8\u6001\u9009\u62E9\u516C\u5171 npm latest \u5E76\u9501\u5B9A\u51C6\u786E\u7248\u672C\uFF1B\u67E5\u8BE2\u6216\u9501\u6587\u4EF6\u751F\u6210\u5931\u8D25\u65F6\u505C\u6B62\uFF0C\u4E0D\u56DE\u9000\u5185\u7F6E\u65E7\u7248\u672C\u3002\u5DF2\u6709\u5DE5\u7A0B\u901A\u8FC7\u5305\u7BA1\u7406\u5668\u663E\u5F0F\u5347\u7EA7\u4F9D\u8D56\u3002CLI \u7684 DEV \u542F\u52A8\u3001\u81EA\u52A8\u91CD\u8F7D\u548C push \u5FC5\u987B\u4F7F\u7528\u672C\u6B21 npm \u6700\u65B0\u7A33\u5B9A\u7248\uFF0C\u58F0\u660E\u3001\u5B89\u88C5\u548C npm \u9501\u6587\u4EF6\u7248\u672C\u5FC5\u987B\u4E00\u81F4\uFF0C\u67E5\u8BE2\u5931\u8D25\u4F1A\u963B\u6B62\u64CD\u4F5C\u3002
2309
2247
 
@@ -2360,7 +2298,7 @@ function legacyHandoffMarkdown(context, skillRoot, session, workspacePath) {
2360
2298
  ## \u5DF2\u5B8C\u6210\u7684\u8EAB\u4EFD\u767B\u8BB0
2361
2299
 
2362
2300
  \u9879\u76EE\u6E05\u5355\uFF1A${JSON.stringify(context.manifestPath)}\u3002\u5176\u4E2D\u7684 buddyId \u7ED1\u5B9A\u5DF2\u7ECF\u767B\u8BB0\u7684\u4E91\u7AEF\u642D\u5B50\uFF1B\u540D\u79F0\u3001tagline \u548C intro \u4EE5\u5E73\u53F0 Meta \u4E3A\u51C6\uFF0C\u4E0D\u4FDD\u5B58\u5728\u672C\u5730\u6E05\u5355\u3002
2363
- \u5E73\u53F0 buddyId\uFF1A${JSON.stringify(context.buddyId)}\u3002Skill \u81EA\u5DF1\u7684 buddyId \u53EA\u6807\u8BC6\u672C\u5730\u4F5C\u54C1\uFF0C\u4E0D\u80FD\u66FF\u6362 buddy.agent.json.buddyId\uFF0C\u4E5F\u4E0D\u8981\u91CD\u65B0\u521B\u5EFA\u4E91\u7AEF\u642D\u5B50\u3002
2301
+ \u5E73\u53F0 buddyId\uFF1A${JSON.stringify(context.buddyId)}\u3002Skill \u81EA\u5DF1\u7684 buddyId \u53EA\u6807\u8BC6\u672C\u5730\u4F5C\u54C1\uFF0C\u4E0D\u80FD\u66FF\u6362 package.json.buddyId\uFF0C\u4E5F\u4E0D\u8981\u91CD\u65B0\u521B\u5EFA\u4E91\u7AEF\u642D\u5B50\u3002
2364
2302
 
2365
2303
  \u672C\u6B21\u5F00\u59CB\u521B\u4F5C\u65F6\u7684\u5E73\u53F0\u8D44\u6599\u5982\u4E0B\uFF1B\u5B83\u4EEC\u53EA\u662F\u91C7\u8BBF\u8D77\u70B9\uFF0C\u540E\u7EED\u4FEE\u6539\u4ECD\u4EE5\u5E73\u53F0 Meta \u4E3A\u51C6\uFF1A
2366
2304
 
@@ -2405,7 +2343,7 @@ ${IMPLEMENTATION_GUIDE}
2405
2343
  ${JSON.stringify(directArgs, null, 2)}
2406
2344
  \`\`\`
2407
2345
 
2408
- \u8BE5\u547D\u4EE4\u590D\u7528 buddy.agent.json \u4E2D\u7684 buddyId\uFF0C\u5E76\u4ECE\u5E73\u53F0\u8BFB\u53D6\u6700\u65B0 Meta\u3001\u91CD\u65B0\u9A8C\u8BC1\u5F52\u5C5E\uFF0C\u4E0D\u4F1A\u53E6\u5EFA\u642D\u5B50\u3002\u5DE5\u7A0B\u7EDF\u4E00\u4F7F\u7528\u5B98\u65B9 Runtime\uFF1B\u5168\u90E8\u8BBE\u8BA1\u9A8C\u6536\u53CA\u4EA4\u4ED8\u6821\u9A8C\u5B8C\u6210\u524D\u4E0D\u751F\u6210\u4E1A\u52A1\u4EE3\u7801\uFF0C\u4E5F\u4E0D\u8981\u628A\u9700\u6C42\u624B\u518C\u8BF4\u6210\u5DF2\u5B9E\u73B0\u4EE3\u7801\u3002
2346
+ \u8BE5\u547D\u4EE4\u590D\u7528 package.json \u4E2D\u7684 buddyId\uFF0C\u5E76\u4ECE\u5E73\u53F0\u8BFB\u53D6\u6700\u65B0 Meta\u3001\u91CD\u65B0\u9A8C\u8BC1\u5F52\u5C5E\uFF0C\u4E0D\u4F1A\u53E6\u5EFA\u642D\u5B50\u3002\u5DE5\u7A0B\u7EDF\u4E00\u4F7F\u7528\u5B98\u65B9 Runtime\uFF1B\u5168\u90E8\u8BBE\u8BA1\u9A8C\u6536\u53CA\u4EA4\u4ED8\u6821\u9A8C\u5B8C\u6210\u524D\u4E0D\u751F\u6210\u4E1A\u52A1\u4EE3\u7801\uFF0C\u4E5F\u4E0D\u8981\u628A\u9700\u6C42\u624B\u518C\u8BF4\u6210\u5DF2\u5B9E\u73B0\u4EE3\u7801\u3002
2409
2347
  \u5DF2\u6709\u5B8C\u6574 Agent \u5DE5\u7A0B\u65F6\u4E0D\u91CD\u590D init\uFF0C\u76F4\u63A5\u6309\u624B\u518C\u7EE7\u7EED\u5B9E\u73B0\u3002\u6821\u9A8C\u9879\u76EE\u8EAB\u4EFD\u4E0E Booklet \u6765\u6E90\uFF0C\u4E0D\u7528\u5176\u4ED6\u642D\u5B50\u7684\u624B\u518C\u6216\u76EE\u5F55\u3002
2410
2348
  ${DEVELOPMENT_HANDOFF}
2411
2349
  `;
@@ -2436,11 +2374,11 @@ async function safeRead(path) {
2436
2374
  if (!entry2.isFile() || entry2.size > MAX_LOCAL_FILE_BYTES) {
2437
2375
  throw new CreatorPreparationError(`\u521B\u4F5C\u6587\u4EF6\u4E0D\u662F\u666E\u901A\u6587\u4EF6\u6216\u8D85\u51FA\u5927\u5C0F\u9650\u5236\uFF1A${path}`);
2438
2376
  }
2439
- return readFile11(path);
2377
+ return readFile12(path);
2440
2378
  }
2441
2379
  async function writeOnce(path, bytes) {
2442
- const temporary = `${path}.${randomUUID5()}.tmp`;
2443
- await writeFile8(temporary, bytes, { flag: "wx", mode: 384 });
2380
+ const temporary = `${path}.${randomUUID6()}.tmp`;
2381
+ await writeFile7(temporary, bytes, { flag: "wx", mode: 384 });
2444
2382
  try {
2445
2383
  await link2(temporary, path).catch((cause) => {
2446
2384
  if (cause.code !== "EEXIST") throw cause;
@@ -2450,10 +2388,10 @@ async function writeOnce(path, bytes) {
2450
2388
  }
2451
2389
  }
2452
2390
  async function replaceFile(path, content) {
2453
- const temporary = `${path}.${randomUUID5()}.tmp`;
2391
+ const temporary = `${path}.${randomUUID6()}.tmp`;
2454
2392
  try {
2455
- await writeFile8(temporary, content, { flag: "wx", mode: 384 });
2456
- await rename7(temporary, path);
2393
+ await writeFile7(temporary, content, { flag: "wx", mode: 384 });
2394
+ await rename8(temporary, path);
2457
2395
  } finally {
2458
2396
  await unlink6(temporary).catch((error2) => {
2459
2397
  if (error2.code !== "ENOENT") throw error2;
@@ -2519,7 +2457,7 @@ async function prepareCreatorSkill(context, io, options = {}) {
2519
2457
  await writeOnce(sessionPath, JSON.stringify({
2520
2458
  schemaVersion: 1,
2521
2459
  platformBuddyId: context.buddyId,
2522
- creationKey: randomUUID5()
2460
+ creationKey: randomUUID6()
2523
2461
  }, null, 2) + "\n");
2524
2462
  const session = JSON.parse((await safeRead(sessionPath)).toString("utf8"));
2525
2463
  if (session.schemaVersion !== 1 || session.platformBuddyId !== context.buddyId || !/^[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}$/u.test(session.creationKey)) {
@@ -2589,7 +2527,7 @@ async function prepareCreatorSkill(context, io, options = {}) {
2589
2527
  } catch (cause) {
2590
2528
  const message = cause instanceof Error ? cause.message : "Creator \u4E0B\u8F7D\u6216\u672C\u5730\u5199\u5165\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u7F51\u7EDC\u548C\u76EE\u5F55\u6743\u9650\u3002";
2591
2529
  io.writeError(`Creator Skill \u51C6\u5907\u5931\u8D25\uFF1A${message}`);
2592
- io.writeError(`buddy.agent.json \u548C\u5DF2\u6709\u521B\u4F5C\u8D44\u6599\u5DF2\u4FDD\u7559\u3002\u91CD\u8BD5 buddy-cli init --mode create --directory ${JSON.stringify(context.projectRoot)}\uFF0C\u4E0D\u4F1A\u53E6\u5EFA\u4E91\u7AEF\u642D\u5B50\u3002`);
2530
+ io.writeError(`package.json \u548C\u5DF2\u6709\u521B\u4F5C\u8D44\u6599\u5DF2\u4FDD\u7559\u3002\u91CD\u8BD5 buddy-cli init --mode create --directory ${JSON.stringify(context.projectRoot)}\uFF0C\u4E0D\u4F1A\u53E6\u5EFA\u4E91\u7AEF\u642D\u5B50\u3002`);
2593
2531
  return { exitCode: 1 };
2594
2532
  }
2595
2533
  }
@@ -2708,13 +2646,13 @@ Coding Agent \u5E94\u76F4\u63A5\u6CBF\u7528\u7528\u6237\u660E\u786E\u63D0\u4F9B\
2708
2646
  \u751F\u6210\u5934\u50CF\u540E\uFF0C\u5728\u4E3B\u5BF9\u8BDD\u4E2D\u4E00\u8D77\u5C55\u793A\u5B8C\u6574\u8D44\u6599\u548C\u5B9E\u9645\u5934\u50CF\uFF0C\u53D6\u5F97\u5F00\u53D1\u8005\u5BF9\u8FD9\u4EFD\u5185\u5BB9\u7684\u660E\u786E\u786E\u8BA4\u3002\u786E\u8BA4\u8FC7\u7684\u540C\u4E00\u4EFD\u5185\u5BB9\u65E0\u9700\u91CD\u590D\u8BE2\u95EE\uFF1B\u4FEE\u6539\u540E\u987B\u91CD\u65B0\u786E\u8BA4\u3002
2709
2647
  \u7B3C\u7EDF\u6388\u6743\u521B\u5EFA\u642D\u5B50\u3001\u5141\u8BB8 Agent \u62DF\u7A3F\u6216 Creator \u624B\u518C\u786E\u8BA4\uFF0C\u5747\u4E0D\u80FD\u4EE3\u66FF\u8FD9\u6B21\u8D44\u6599\u4E0E\u5934\u50CF\u786E\u8BA4\uFF1B\u4E0D\u80FD\u7528\u201C\u5148\u767B\u8BB0\u3001\u4EE5\u540E\u53EF\u6539\u201D\u8DF3\u8FC7\u786E\u8BA4\u3002
2710
2648
  --buddy-id \u53EA\u7528\u4E8E\u6062\u590D\u5E73\u53F0\u5DF2\u7ECF\u751F\u6210\u4E14\u5C5E\u4E8E\u5F53\u524D\u8D26\u53F7\u7684\u642D\u5B50\u8EAB\u4EFD\uFF0C\u4E0D\u80FD\u81EA\u884C\u6307\u5B9A\u8EAB\u4EFD\u3002
2711
- \u65B0\u5EFA\u65F6\u9700\u8981\u751F\u6210\u5934\u50CF\u624D\u6309\u9700\u52A0\u8F7D\u72EC\u7ACB avatar-creator-skill\uFF0C\u7531 Coding Agent \u8BFB\u53D6 .buddy/meta/HANDOFF.md \u4E0E\u5176\u4E2D\u6307\u5411\u7684 Skill\uFF0C\u8C03\u7528\u5BBF\u4E3B\u56FE\u7247\u751F\u6210\u80FD\u529B\u5E76\u5C55\u793A\u5B9E\u9645\u5934\u50CF\u3002\u5DF2\u6709\u56FE\u7247\u786E\u8BA4\u548C\u4E0A\u4F20\u4E0D\u4F9D\u8D56\u751F\u6210 Skill\u3002
2649
+ \u65B0\u5EFA\u65F6\u9700\u8981\u751F\u6210\u5934\u50CF\u624D\u6309\u9700\u52A0\u8F7D\u72EC\u7ACB @my-life-buddies/avatar-creator-skill\uFF0C\u7531 Coding Agent \u8BFB\u53D6 .buddy/meta/HANDOFF.md \u4E0E\u5176\u4E2D\u6307\u5411\u7684 Skill\uFF0C\u8C03\u7528\u5BBF\u4E3B\u56FE\u7247\u751F\u6210\u80FD\u529B\u5E76\u5C55\u793A\u5B9E\u9645\u5934\u50CF\u3002\u5DF2\u6709\u56FE\u7247\u786E\u8BA4\u548C\u4E0A\u4F20\u4E0D\u4F9D\u8D56\u751F\u6210 Skill\u3002
2712
2650
  \u5934\u50CF Skill \u7248\u672C\u8BB0\u5F55\u5728 .buddy/meta/skill-lock.json\uFF1B--avatar-skill-version <\u51C6\u786E\u7248\u672C> \u663E\u5F0F\u9009\u62E9\u7248\u672C\uFF0C\u672C\u5730\u8054\u8C03\u8BBE\u7F6E BUDDY_AVATAR_SKILL_PATH \u7EDD\u5BF9\u8DEF\u5F84\u3002
2713
2651
  \u666E\u901A\u7EC8\u7AEF\u53EF\u9009\u62E9\u5DF2\u6709\u56FE\u7247\uFF1BCLI \u4E0D\u6267\u884C\u56FE\u7247\u751F\u6210\uFF0C\u4E5F\u4E0D\u8981\u6C42\u5B89\u88C5 Coding Agent\u3002\u4F7F\u7528 --avatar <\u56FE\u7247\u6587\u4EF6> \u6307\u5B9A\u5019\u9009\u5934\u50CF\uFF0C\u7EC8\u7AEF\u9884\u89C8\u5E76\u786E\u8BA4\u540E\u767B\u8BB0\u3002
2714
2652
  \u975E\u4EA4\u4E92\u8C03\u7528\u987B\u5728\u5F00\u53D1\u8005\u660E\u786E\u786E\u8BA4\u5B9E\u9645\u5934\u50CF\u548C\u8D44\u6599\u540E\u4F20 --avatar <\u5DF2\u786E\u8BA4\u56FE\u7247> --confirm-meta\u3002\u672A\u786E\u8BA4\u4E0D\u5F97\u4F20\u8BE5\u6807\u5FD7\uFF1B\u7F3A\u5C11\u56FE\u7247\u6216\u786E\u8BA4\u65F6\u9000\u51FA\u7801\u4E3A 2\uFF0C\u8349\u7A3F\u4FDD\u7559\uFF0C\u53EF\u4EE5\u5728\u539F\u76EE\u5F55\u7EE7\u7EED\u3002
2715
2653
  --mode create \u5B8C\u6210\u8D44\u6599\u548C\u5934\u50CF\u767B\u8BB0\u540E\uFF0C\u52A8\u6001\u83B7\u53D6\u72EC\u7ACB Creator Skill \u5E76\u751F\u6210\u63A5\u7EED\u8BF4\u660E\uFF0C\u9879\u76EE .buddy/creator/ \u4FDD\u5B58\u521B\u4F5C\u8D44\u6599\u4E0E skill-lock.json \u7248\u672C\u8BB0\u5F55\u3002\u4F7F\u7528 --creator-version <\u51C6\u786E\u7248\u672C> \u663E\u5F0F\u5347\u7EA7\uFF0C\u5DF2\u6709\u9879\u76EE\u9ED8\u8BA4\u590D\u7528\u56FA\u5B9A\u7248\u672C\uFF1B\u672C\u5730\u8054\u8C03\u53EF\u8BBE\u7F6E BUDDY_CREATOR_SKILL_PATH \u7EDD\u5BF9\u8DEF\u5F84\u3002
2716
2654
  \u7531\u5F53\u524D Coding Agent \u8BFB\u53D6 .buddy/creator/HANDOFF.md \u5E76\u6267\u884C\u5176\u4E2D\u6307\u5411\u7684 Skill\uFF1B\u9700\u8981 Python 3.9+\uFF0C\u4E0D\u542F\u52A8\u65E7\u91C7\u8BBF Web \u6216\u72EC\u7ACB\u6A21\u578B\u3002
2717
- \u56DB\u518C\u786E\u8BA4\u540E\u7EE7\u7EED\u5C0F\u6302\u4EF6\u6E05\u5355\u3001\u539F\u578B\u548C\u8BBE\u8BA1\u9A8C\u6536\uFF1B\u5168\u90E8\u786E\u8BA4\u5E76\u901A\u8FC7\u4EA4\u4ED8\u6821\u9A8C\u540E\uFF0C\u7531 Coding Agent \u81EA\u52A8\u8854\u63A5\u5F00\u53D1\uFF0C\u9700\u8981\u521D\u59CB\u5316\u65F6\u6267\u884C init --mode direct \u751F\u6210\u5B98\u65B9 Runtime \u5DE5\u7A0B\u3002\u540C\u76EE\u5F55\u6062\u590D\u65F6\u4ECE buddy.agent.json \u8BFB\u53D6 buddyId\uFF0C\u5E76\u4F7F\u7528\u5E73\u53F0\u6700\u65B0 Meta\u3002
2655
+ \u56DB\u518C\u786E\u8BA4\u540E\u7EE7\u7EED\u5C0F\u6302\u4EF6\u6E05\u5355\u3001\u539F\u578B\u548C\u8BBE\u8BA1\u9A8C\u6536\uFF1B\u5168\u90E8\u786E\u8BA4\u5E76\u901A\u8FC7\u4EA4\u4ED8\u6821\u9A8C\u540E\uFF0C\u7531 Coding Agent \u81EA\u52A8\u8854\u63A5\u5F00\u53D1\uFF0C\u9700\u8981\u521D\u59CB\u5316\u65F6\u6267\u884C init --mode direct \u751F\u6210\u5B98\u65B9 Runtime \u5DE5\u7A0B\u3002\u540C\u76EE\u5F55\u6062\u590D\u65F6\u4ECE package.json \u8BFB\u53D6 buddyId\uFF0C\u5E76\u4F7F\u7528\u5E73\u53F0\u6700\u65B0 Meta\u3002
2718
2656
  Coding Agent \u5E94\u4F20\u5165\u6309\u4E0A\u8FF0\u89C4\u5219\u786E\u5B9A\u7684\u8D44\u6599\uFF0C\u811A\u672C\u4F7F\u7528\u5F00\u53D1\u8005\u63D0\u4F9B\u7684\u53C2\u6570\uFF0C\u907F\u514D\u7B49\u5F85\u7EC8\u7AEF\u8F93\u5165\u3002CLI \u6821\u9A8C\u53C2\u6570\uFF0C\u4E0D\u5224\u65AD\u5BF9\u8BDD\u4E2D\u662F\u5426\u5DF2\u7ECF\u786E\u8BA4\uFF1B\u53C2\u6570\u9F50\u5168\u4E0D\u7B49\u4E8E\u7528\u6237\u786E\u8BA4\u3002
2719
2657
  Coding Agent \u6839\u636E\u5DF2\u786E\u8BA4\u624B\u518C\u6216\u9700\u6C42\u63A8\u8FDB\u5B9E\u73B0\uFF1B\u53EA\u4E3A\u5173\u952E\u7F3A\u53E3\u8BE2\u95EE\uFF0C\u4E0D\u56FA\u5B9A\u8FFD\u52A0\u7B56\u7565\u786E\u8BA4\u3002
2720
2658
  \u6240\u6709\u642D\u5B50\u7EDF\u4E00\u4F7F\u7528\u5B98\u65B9 Runtime\uFF1B\u9700\u6C42\u660E\u786E\u65F6\u4F7F\u7528 --mode direct\uFF0C\u9700\u8981\u68B3\u7406\u9700\u6C42\u65F6\u4F7F\u7528 --mode create\u3002
@@ -2748,8 +2686,8 @@ function resolvePlatformUrl(options = {}) {
2748
2686
 
2749
2687
  // packages/cli-core/src/dev/project-env.ts
2750
2688
  import { constants } from "node:fs";
2751
- import { open as open4, rename as rename8, unlink as unlink7 } from "node:fs/promises";
2752
- import { randomUUID as randomUUID6 } from "node:crypto";
2689
+ import { open as open4, rename as rename9, unlink as unlink7 } from "node:fs/promises";
2690
+ import { randomUUID as randomUUID7 } from "node:crypto";
2753
2691
  import { join as join13 } from "node:path";
2754
2692
  import { parseEnv } from "node:util";
2755
2693
 
@@ -2808,7 +2746,7 @@ async function readProjectEnvironment(projectRoot, buddyId) {
2808
2746
  } catch {
2809
2747
  throw invalid("\u5DE5\u7A0B .env \u683C\u5F0F\u65E0\u6548\uFF0C\u8BF7\u68C0\u67E5\u540E\u91CD\u8BD5\u3002");
2810
2748
  }
2811
- if (values.BUDDY_ID && values.BUDDY_ID !== buddyId) throw invalid(".env \u7684 BUDDY_ID \u4E0E buddy.agent.json \u4E0D\u4E00\u81F4\uFF0C\u8BF7\u5148\u4FEE\u6B63\u5DE5\u7A0B\u8EAB\u4EFD\u3002");
2749
+ if (values.BUDDY_ID && values.BUDDY_ID !== buddyId) throw invalid(".env \u7684 BUDDY_ID \u4E0E package.json \u4E0D\u4E00\u81F4\uFF0C\u8BF7\u5148\u4FEE\u6B63\u5DE5\u7A0B\u8EAB\u4EFD\u3002");
2812
2750
  return values;
2813
2751
  }
2814
2752
  async function projectBuddyToken(projectRoot, buddyId, gatewayUrl) {
@@ -2871,7 +2809,7 @@ function updateValues(source, values) {
2871
2809
  return output;
2872
2810
  }
2873
2811
  async function replaceFile2(path, contents, mode) {
2874
- const temporary = `${path}.${randomUUID6()}.tmp`;
2812
+ const temporary = `${path}.${randomUUID7()}.tmp`;
2875
2813
  let file;
2876
2814
  try {
2877
2815
  file = await open4(temporary, "wx", mode);
@@ -2879,7 +2817,7 @@ async function replaceFile2(path, contents, mode) {
2879
2817
  await file.sync();
2880
2818
  await file.close();
2881
2819
  file = void 0;
2882
- await rename8(temporary, path);
2820
+ await rename9(temporary, path);
2883
2821
  } finally {
2884
2822
  await file?.close();
2885
2823
  await unlink7(temporary).catch((cause) => {
@@ -3035,7 +2973,7 @@ var MlbDevRegistrationClient = class {
3035
2973
  throw new BuddyDevError({
3036
2974
  code: "DEV_AGENT_ID_INVALID",
3037
2975
  phase: "registration",
3038
- message: "buddy.agent.json \u4E2D\u7684 buddyId \u65E0\u6548\u3002"
2976
+ message: "package.json \u4E2D\u7684 buddyId \u65E0\u6548\u3002"
3039
2977
  });
3040
2978
  }
3041
2979
  options.signal.throwIfAborted();
@@ -3167,13 +3105,13 @@ function buildAgentEnvironment(options) {
3167
3105
 
3168
3106
  // packages/cli-core/src/dev/orchestrator.ts
3169
3107
  import { createHash as createHash6 } from "node:crypto";
3170
- import { readFile as readFile14 } from "node:fs/promises";
3171
- import { join as join16, resolve as resolve12 } from "node:path";
3108
+ import { readFile as readFile16 } from "node:fs/promises";
3109
+ import { join as join17, resolve as resolve12 } from "node:path";
3172
3110
 
3173
3111
  // packages/cli-core/src/dev/reload.ts
3174
3112
  import { watch } from "node:fs";
3175
3113
  import { createHash as createHash5 } from "node:crypto";
3176
- import { readFile as readFile12, readdir as readdir4 } from "node:fs/promises";
3114
+ import { readFile as readFile13, readdir as readdir4 } from "node:fs/promises";
3177
3115
  import { join as join15, resolve as resolve9 } from "node:path";
3178
3116
  import { setTimeout as sleep } from "node:timers/promises";
3179
3117
 
@@ -3202,7 +3140,7 @@ async function snapshot(root, prefix = "", result = /* @__PURE__ */ new Map()) {
3202
3140
  if (!relevant(path)) continue;
3203
3141
  try {
3204
3142
  if (entry2.isDirectory()) await snapshot(root, path, result);
3205
- else if (entry2.isFile()) result.set(path, digest2(await readFile12(join15(root, path))));
3143
+ else if (entry2.isFile()) result.set(path, digest2(await readFile13(join15(root, path))));
3206
3144
  } catch (cause) {
3207
3145
  if (cause.code !== "ENOENT") throw cause;
3208
3146
  }
@@ -3292,7 +3230,7 @@ var ReloadingDevSession = class {
3292
3230
  const path = String(name);
3293
3231
  if (!relevant(path)) return;
3294
3232
  if (path === ".env") {
3295
- void readFile12(join15(this.projectRoot, path), "utf8").then((contents) => {
3233
+ void readFile13(join15(this.projectRoot, path), "utf8").then((contents) => {
3296
3234
  if (contents !== this.#environment) {
3297
3235
  this.#environment = contents;
3298
3236
  this.#changed();
@@ -3470,7 +3408,7 @@ function startReloadingDev(options, startProcess) {
3470
3408
  }
3471
3409
 
3472
3410
  // packages/cli-core/src/config/runtime-policy.ts
3473
- import { readFile as readFile13, realpath as realpath4 } from "node:fs/promises";
3411
+ import { readFile as readFile14, realpath as realpath4 } from "node:fs/promises";
3474
3412
  import { createRequire as createRequire2 } from "node:module";
3475
3413
  import { resolve as resolve10 } from "node:path";
3476
3414
  var RuntimeRequirementError = class extends Error {
@@ -3510,11 +3448,11 @@ async function requireLatestRuntime(root, options = {}) {
3510
3448
  const installedPath = await realpath4(resolve10(root, "node_modules", BUDDY_RUNTIME_PACKAGE, "package.json"));
3511
3449
  const fromProject = createRequire2(resolve10(root, "package.json")).resolve(`${BUDDY_RUNTIME_PACKAGE}/package.json`);
3512
3450
  if (await realpath4(fromProject) !== installedPath) throw new Error("Runtime \u5FC5\u987B\u5B89\u88C5\u5728\u5F53\u524D\u5DE5\u7A0B\u4E2D");
3513
- const installed2 = JSON.parse(await readFile13(installedPath, "utf8"));
3451
+ const installed2 = JSON.parse(await readFile14(installedPath, "utf8"));
3514
3452
  if (installed2.version !== latest) throw new Error(`Runtime \u5B9E\u9645\u5B89\u88C5 ${installed2.version}\uFF0C\u8981\u6C42 ${latest}`);
3515
3453
  let lock;
3516
3454
  try {
3517
- lock = await readFile13(resolve10(root, "package-lock.json"), "utf8");
3455
+ lock = await readFile14(resolve10(root, "package-lock.json"), "utf8");
3518
3456
  } catch (cause) {
3519
3457
  if (cause.code !== "ENOENT") throw cause;
3520
3458
  }
@@ -3532,6 +3470,48 @@ async function requireLatestRuntime(root, options = {}) {
3532
3470
  import { lstatSync, readFileSync } from "node:fs";
3533
3471
  import { createRequire as createRequire3 } from "node:module";
3534
3472
  import { dirname as dirname4, resolve as resolve11 } from "node:path";
3473
+
3474
+ // packages/cli-core/src/config/data-access.ts
3475
+ import { lstat as lstat10, readFile as readFile15 } from "node:fs/promises";
3476
+ import { join as join16 } from "node:path";
3477
+ var DATA_ACCESS_FILENAME = "data-access.json";
3478
+ function parseDataAccessRequirements(source) {
3479
+ if (source === void 0) return [];
3480
+ const invalid3 = (reason) => {
3481
+ throw new Error(`${DATA_ACCESS_FILENAME}\uFF1A${reason}`);
3482
+ };
3483
+ let value;
3484
+ try {
3485
+ value = JSON.parse(source);
3486
+ } catch {
3487
+ return invalid3("\u4E0D\u662F\u6709\u6548 JSON");
3488
+ }
3489
+ if (!value || typeof value !== "object" || Array.isArray(value) || Object.keys(value).some((key) => key !== "requirements") || !Array.isArray(value.requirements) || value.requirements.length > 32) {
3490
+ return invalid3("\u5FC5\u987B\u662F\u4EC5\u5305\u542B requirements \u6570\u7EC4\u7684\u5BF9\u8C61\uFF0C\u6700\u591A\u58F0\u660E 32 \u9879");
3491
+ }
3492
+ const seen = /* @__PURE__ */ new Set();
3493
+ return value.requirements.map((item, index) => {
3494
+ if (!item || typeof item !== "object" || Array.isArray(item) || Object.keys(item).some((key) => key !== "id" && key !== "purpose") || !("id" in item) || typeof item.id !== "string" || !item.id.trim() || !("purpose" in item) || typeof item.purpose !== "string" || !item.purpose.trim() || item.purpose.trim().length > 200) {
3495
+ return invalid3(`requirements[${index}] \u5FC5\u987B\u5305\u542B\u975E\u7A7A id \u548C 1\u2013200 \u5B57\u7684 purpose`);
3496
+ }
3497
+ const id = item.id.trim(), purpose = item.purpose.trim();
3498
+ if (seen.has(id)) return invalid3(`\u6570\u636E\u96C6\u4E0D\u80FD\u91CD\u590D\u58F0\u660E\uFF1A${id}`);
3499
+ seen.add(id);
3500
+ return { id, purpose };
3501
+ });
3502
+ }
3503
+ async function readDataAccessRequirements(projectRoot) {
3504
+ const path = join16(projectRoot, DATA_ACCESS_FILENAME);
3505
+ try {
3506
+ if (!(await lstat10(path)).isFile()) throw new Error(`${DATA_ACCESS_FILENAME} \u5FC5\u987B\u662F\u666E\u901A\u6587\u4EF6`);
3507
+ return parseDataAccessRequirements(await readFile15(path, "utf8"));
3508
+ } catch (cause) {
3509
+ if (cause.code === "ENOENT") return [];
3510
+ throw cause;
3511
+ }
3512
+ }
3513
+
3514
+ // packages/cli-core/src/dev/launch.ts
3535
3515
  async function officialAgentLaunchPlan(input) {
3536
3516
  const entry2 = resolve11(input.projectRoot, BUDDY_PLATFORM_START_ENTRY);
3537
3517
  for (const [filename, kind] of [
@@ -3562,8 +3542,7 @@ async function officialAgentLaunchPlan(input) {
3562
3542
  const runtimePath = createRequire3(packagePath).resolve(`${BUDDY_RUNTIME_PACKAGE}/package.json`);
3563
3543
  const installed2 = JSON.parse(readFileSync(runtimePath, "utf8")).version;
3564
3544
  if (installed2 !== expected) throw new Error(`Runtime \u5DF2\u5B89\u88C5 ${installed2}\uFF0C\u5DE5\u7A0B\u8981\u6C42 ${expected}`);
3565
- await validateRuntimeDatasets(input.projectRoot, input.datasets);
3566
- await validateRuntimeModel(input.projectRoot, input.model);
3545
+ await validateRuntimeDatasets(input.projectRoot, await readDataAccessRequirements(input.projectRoot));
3567
3546
  } catch (cause) {
3568
3547
  throw new BuddyDevError({
3569
3548
  code: cause instanceof RuntimeRequirementError ? `DEV_${cause.code}` : "DEV_CONFIG_INVALID",
@@ -3572,7 +3551,6 @@ async function officialAgentLaunchPlan(input) {
3572
3551
  cause
3573
3552
  });
3574
3553
  }
3575
- await migrateRuntimeStartup(input.projectRoot);
3576
3554
  return Object.freeze({
3577
3555
  command: process.execPath,
3578
3556
  args: Object.freeze(["--env-file-if-exists=.env", entry2])
@@ -3818,8 +3796,6 @@ function validateLaunchPlan(value) {
3818
3796
  async function launchPlanFor(config, options, projectRoot, signal) {
3819
3797
  const provider = options.platformLaunchPlan ?? ((context) => officialAgentLaunchPlan({
3820
3798
  runtimeUpdate: { ...options.runtimeUpdate, signal },
3821
- datasets: config.datasets,
3822
- model: config.model,
3823
3799
  projectRoot: context.projectRoot
3824
3800
  }));
3825
3801
  try {
@@ -4047,13 +4023,13 @@ async function startBuddyDevProcess(options, hooks) {
4047
4023
  let config;
4048
4024
  let configSource;
4049
4025
  try {
4050
- configSource = await readFile14(join16(projectRoot, BUDDY_AGENT_FILENAME), "utf8");
4026
+ configSource = await readFile16(join17(projectRoot, BUDDY_PACKAGE_FILENAME), "utf8");
4051
4027
  config = combineBuddyProject(parseBuddyAgentConfig(configSource));
4052
4028
  } catch (cause) {
4053
4029
  throw new BuddyDevError({
4054
4030
  code: "DEV_CONFIG_INVALID",
4055
4031
  phase: "config",
4056
- message: `\u65E0\u6CD5\u8BFB\u53D6\u6216\u6821\u9A8C buddy.agent.json\uFF1A${cause instanceof Error ? cause.message : "\u642D\u5B50\u5DE5\u7A0B\u5C1A\u672A\u5B8C\u6210"}`,
4032
+ message: `\u65E0\u6CD5\u8BFB\u53D6\u6216\u6821\u9A8C package.json\uFF1A${cause instanceof Error ? cause.message : "\u642D\u5B50\u5DE5\u7A0B\u5C1A\u672A\u5B8C\u6210"}`,
4057
4033
  cause
4058
4034
  });
4059
4035
  }
@@ -4531,7 +4507,7 @@ var PushPreflightError = class extends Error {
4531
4507
  import { resolve as resolve15 } from "node:path";
4532
4508
 
4533
4509
  // packages/cli-core/src/cloud/auth.ts
4534
- import { randomUUID as randomUUID7 } from "node:crypto";
4510
+ import { randomUUID as randomUUID8 } from "node:crypto";
4535
4511
 
4536
4512
  // packages/cli-core/src/cloud/validation.ts
4537
4513
  function record(value, path = "request") {
@@ -4599,7 +4575,7 @@ var CloudAuthenticator = class {
4599
4575
  this.#adapter = adapter;
4600
4576
  this.#store = store;
4601
4577
  this.#now = options.now ?? Date.now;
4602
- this.#createState = options.createState ?? randomUUID7;
4578
+ this.#createState = options.createState ?? randomUUID8;
4603
4579
  this.#minimumValidityMs = options.minimumValidityMs ?? 3e4;
4604
4580
  if (!Number.isSafeInteger(this.#minimumValidityMs) || this.#minimumValidityMs < 0) {
4605
4581
  throw new TypeError("minimumValidityMs must be a non-negative safe integer");
@@ -5545,8 +5521,8 @@ async function runCloudCommand(command, args, io, options = {}) {
5545
5521
  var CLOUD_COMMAND_HELP = HELP;
5546
5522
 
5547
5523
  // packages/cli-core/src/migration/index.ts
5548
- import { lstat as lstat10, open as open5, readdir as readdir5, realpath as realpath5, stat } from "node:fs/promises";
5549
- import { extname, isAbsolute as isAbsolute3, join as join17, relative, resolve as resolve16, sep, win32 as win322 } from "node:path";
5524
+ import { lstat as lstat11, open as open5, readdir as readdir5, realpath as realpath5, stat } from "node:fs/promises";
5525
+ import { extname, isAbsolute as isAbsolute3, join as join18, relative, resolve as resolve16, sep, win32 as win322 } from "node:path";
5550
5526
  var DEFAULT_SKILL_SCAN_LIMITS = Object.freeze({
5551
5527
  maxFiles: 128,
5552
5528
  maxFileBytes: 256 * 1024,
@@ -5715,9 +5691,9 @@ async function existingProjectRoot(value) {
5715
5691
  }
5716
5692
  }
5717
5693
  async function existingSkillRoot(projectRoot, skillPath) {
5718
- const candidate = skillPath === "." ? projectRoot : join17(projectRoot, ...skillPath.split("/"));
5694
+ const candidate = skillPath === "." ? projectRoot : join18(projectRoot, ...skillPath.split("/"));
5719
5695
  try {
5720
- await lstat10(candidate);
5696
+ await lstat11(candidate);
5721
5697
  } catch (cause) {
5722
5698
  if (filesystemCode(cause) === "ENOENT") {
5723
5699
  return rejectScan("SKILL_ROOT_NOT_FOUND", skillPath, "\u627E\u4E0D\u5230\u6307\u5B9A\u7684 Skill \u76EE\u5F55\u3002");
@@ -5752,9 +5728,9 @@ async function existingSkillRoot(projectRoot, skillPath) {
5752
5728
  }
5753
5729
  async function assertEntrypoint(context) {
5754
5730
  const entryPath = reportChild(context.skillPath, "SKILL.md");
5755
- const candidate = join17(context.skillRoot, "SKILL.md");
5731
+ const candidate = join18(context.skillRoot, "SKILL.md");
5756
5732
  try {
5757
- await lstat10(candidate);
5733
+ await lstat11(candidate);
5758
5734
  const target = await realpath5(candidate);
5759
5735
  if (!isWithin(context.projectRoot, target) || !isWithin(context.skillRoot, target)) {
5760
5736
  rejectScan(
@@ -5856,7 +5832,7 @@ async function walkDirectory(actualDirectory, reportDirectory, ancestors, contex
5856
5832
  }
5857
5833
  for (const entry2 of entries) {
5858
5834
  const childReportPath = reportChild(reportDirectory, entry2.name);
5859
- const childPath = join17(directory, entry2.name);
5835
+ const childPath = join18(directory, entry2.name);
5860
5836
  let target;
5861
5837
  try {
5862
5838
  target = await realpath5(childPath);
@@ -6311,8 +6287,8 @@ async function scanExternalSkillPortability(options) {
6311
6287
 
6312
6288
  // packages/cli-core/src/push/preflight.ts
6313
6289
  import { createHash as createHash10 } from "node:crypto";
6314
- import { lstat as lstat11, open as open6, readdir as readdir6, realpath as realpath6 } from "node:fs/promises";
6315
- import { isAbsolute as isAbsolute4, join as join18, relative as relative2, resolve as resolve17, sep as sep2, win32 as win323 } from "node:path";
6290
+ import { lstat as lstat12, open as open6, readdir as readdir6, realpath as realpath6 } from "node:fs/promises";
6291
+ import { isAbsolute as isAbsolute4, join as join19, relative as relative2, resolve as resolve17, sep as sep2, win32 as win323 } from "node:path";
6316
6292
  var MEBIBYTE = 1024 * 1024;
6317
6293
  var DEFAULT_PUSH_MANIFEST_LIMITS = Object.freeze({
6318
6294
  maxFiles: 1e4,
@@ -6489,7 +6465,7 @@ async function canonicalProjectRoot(projectRoot) {
6489
6465
  const absolute = resolve17(projectRoot);
6490
6466
  let entry2;
6491
6467
  try {
6492
- entry2 = await lstat11(absolute);
6468
+ entry2 = await lstat12(absolute);
6493
6469
  } catch (cause) {
6494
6470
  error({
6495
6471
  code: "PUSH_PROJECT_INVALID",
@@ -6517,10 +6493,10 @@ async function canonicalProjectRoot(projectRoot) {
6517
6493
  }
6518
6494
  }
6519
6495
  async function captureConfigWithinLimit(projectRoot, maxFileBytes, filename) {
6520
- const path = join18(projectRoot, filename);
6496
+ const path = join19(projectRoot, filename);
6521
6497
  let entry2;
6522
6498
  try {
6523
- entry2 = await lstat11(path);
6499
+ entry2 = await lstat12(path);
6524
6500
  } catch (cause) {
6525
6501
  error({
6526
6502
  code: "PUSH_CONFIG_INVALID",
@@ -6579,7 +6555,7 @@ function parseCapturedProject(agentFile) {
6579
6555
  } catch (cause) {
6580
6556
  error({
6581
6557
  code: "PUSH_CONFIG_INVALID",
6582
- message: `${BUDDY_AGENT_FILENAME} \u65E0\u6548\u3001Agent \u5DE5\u7A0B\u5C1A\u672A\u5B8C\u6210\u3002`,
6558
+ message: `${BUDDY_PACKAGE_FILENAME} \u65E0\u6548\u3001Agent \u5DE5\u7A0B\u5C1A\u672A\u5B8C\u6210\u3002`,
6583
6559
  cause
6584
6560
  });
6585
6561
  }
@@ -6615,11 +6591,11 @@ async function selectLockfile(projectRoot) {
6615
6591
  }
6616
6592
  function assertBookletIsNotRequiredInput(bookletPath, lockfile) {
6617
6593
  if (bookletPath === void 0) return;
6618
- if (bookletPath === BUDDY_AGENT_FILENAME || bookletPath === lockfile.path || OFFICIAL_RUNTIME_INPUTS.some((path) => path === bookletPath)) {
6594
+ if (bookletPath === BUDDY_PACKAGE_FILENAME || bookletPath === DATA_ACCESS_FILENAME || bookletPath === lockfile.path || OFFICIAL_RUNTIME_INPUTS.some((path) => path === bookletPath)) {
6619
6595
  error({
6620
6596
  code: "PUSH_BOOKLET_INVALID",
6621
6597
  path: bookletPath,
6622
- message: `Booklet \u4E0D\u80FD\u4F2A\u88C5\u6210 ${BUDDY_AGENT_FILENAME}\u3001\u4F9D\u8D56\u9501\u6587\u4EF6\u3001Runtime \u542F\u52A8\u8F93\u5165\u3002`
6598
+ message: `Booklet \u4E0D\u80FD\u4F2A\u88C5\u6210 ${BUDDY_PACKAGE_FILENAME}\u3001\u4F9D\u8D56\u9501\u6587\u4EF6\u3001Runtime \u542F\u52A8\u8F93\u5165\u3002`
6623
6599
  });
6624
6600
  }
6625
6601
  }
@@ -6720,10 +6696,10 @@ async function createManifest(options) {
6720
6696
  sensitiveEntriesExcluded += 1;
6721
6697
  continue;
6722
6698
  }
6723
- const absolutePath = join18(directory, name);
6699
+ const absolutePath = join19(directory, name);
6724
6700
  let entry2;
6725
6701
  try {
6726
- entry2 = await lstat11(absolutePath);
6702
+ entry2 = await lstat12(absolutePath);
6727
6703
  } catch (cause) {
6728
6704
  error({
6729
6705
  code: "PUSH_FILE_CHANGED",
@@ -6974,8 +6950,8 @@ async function assertCapturedConfigStable(options) {
6974
6950
  }
6975
6951
  let current;
6976
6952
  try {
6977
- const path = join18(options.projectRoot, options.filename);
6978
- const entry2 = await lstat11(path);
6953
+ const path = join19(options.projectRoot, options.filename);
6954
+ const entry2 = await lstat12(path);
6979
6955
  if (!entry2.isFile() || entry2.isSymbolicLink()) {
6980
6956
  error({
6981
6957
  code: "PUSH_FILE_CHANGED",
@@ -7015,15 +6991,22 @@ async function createPushPreflight(options) {
7015
6991
  const initialAgentEntry = await captureConfigWithinLimit(
7016
6992
  projectRoot,
7017
6993
  limits.maxFileBytes,
7018
- BUDDY_AGENT_FILENAME
6994
+ BUDDY_PACKAGE_FILENAME
7019
6995
  );
7020
6996
  parseCapturedProject(initialAgentEntry);
6997
+ let initialDataEntry;
6998
+ try {
6999
+ await lstat12(join19(projectRoot, DATA_ACCESS_FILENAME));
7000
+ initialDataEntry = await captureConfigWithinLimit(projectRoot, limits.maxFileBytes, DATA_ACCESS_FILENAME);
7001
+ } catch (cause) {
7002
+ if (cause.code !== "ENOENT") throw cause;
7003
+ }
7021
7004
  const lockfile = await selectLockfile(projectRoot);
7022
7005
  assertBookletIsNotRequiredInput(bookletPath, lockfile);
7023
7006
  const manifest = await createManifest({
7024
7007
  projectRoot,
7025
7008
  limits,
7026
- capturePaths: /* @__PURE__ */ new Set([BUDDY_AGENT_FILENAME, lockfile.path, BUDDY_PLATFORM_PACKAGE_JSON, BUDDY_PLATFORM_AGENT_ENTRY, BUDDY_PLATFORM_FACTORY_ENTRY]),
7009
+ capturePaths: /* @__PURE__ */ new Set([DATA_ACCESS_FILENAME, BUDDY_PACKAGE_FILENAME, lockfile.path, BUDDY_PLATFORM_AGENT_ENTRY, BUDDY_PLATFORM_FACTORY_ENTRY]),
7027
7010
  ...bookletPath === void 0 ? {} : { bookletPath }
7028
7011
  });
7029
7012
  const lockEntry = manifest.files.find((file) => file.path === lockfile.path);
@@ -7048,24 +7031,32 @@ async function createPushPreflight(options) {
7048
7031
  }
7049
7032
  const agentEntry = await assertCapturedConfigStable({
7050
7033
  projectRoot,
7051
- filename: BUDDY_AGENT_FILENAME,
7034
+ filename: BUDDY_PACKAGE_FILENAME,
7052
7035
  initial: initialAgentEntry,
7053
7036
  manifestFiles: manifest.files,
7054
7037
  maxFileBytes: limits.maxFileBytes
7055
7038
  });
7056
- const config = parseCapturedProject(agentEntry);
7057
- if (config.datasets?.length || config.model !== void 0) {
7058
- try {
7059
- if (config.datasets?.length) await validateRuntimeDatasets(projectRoot, config.datasets);
7060
- await validateRuntimeModel(projectRoot, config.model);
7061
- } catch (cause) {
7062
- error({
7063
- code: "PUSH_CONFIG_INVALID",
7064
- path: BUDDY_AGENT_FILENAME,
7065
- message: `\u65E0\u6CD5\u6309\u5DE5\u7A0B Runtime \u6821\u9A8C\u6A21\u578B\u6216\u6570\u636E\u58F0\u660E\uFF1A${cause instanceof Error ? cause.message : String(cause)}`,
7066
- cause
7067
- });
7068
- }
7039
+ parseCapturedProject(agentEntry);
7040
+ if (initialDataEntry) {
7041
+ await assertCapturedConfigStable({
7042
+ projectRoot,
7043
+ filename: DATA_ACCESS_FILENAME,
7044
+ initial: initialDataEntry,
7045
+ manifestFiles: manifest.files,
7046
+ maxFileBytes: limits.maxFileBytes
7047
+ });
7048
+ }
7049
+ try {
7050
+ const dataEntry = manifest.files.find((file) => file.path === DATA_ACCESS_FILENAME);
7051
+ const requirements = parseDataAccessRequirements(dataEntry ? decodeCapturedConfig(dataEntry) : void 0);
7052
+ if (requirements.length) await validateRuntimeDatasets(projectRoot, requirements);
7053
+ } catch (cause) {
7054
+ error({
7055
+ code: "PUSH_CONFIG_INVALID",
7056
+ path: DATA_ACCESS_FILENAME,
7057
+ message: `\u65E0\u6CD5\u6309\u5DE5\u7A0B Runtime \u6821\u9A8C\u6570\u636E\u58F0\u660E\uFF1A${cause instanceof Error ? cause.message : String(cause)}`,
7058
+ cause
7059
+ });
7069
7060
  }
7070
7061
  const files = Object.freeze(manifest.files.map((file) => Object.freeze({
7071
7062
  path: file.path,
@@ -7107,8 +7098,8 @@ async function createPushPreflight(options) {
7107
7098
 
7108
7099
  // packages/cli-core/src/push/bundle.ts
7109
7100
  import { createHash as createHash11 } from "node:crypto";
7110
- import { lstat as lstat12, readFile as readFile15, realpath as realpath7 } from "node:fs/promises";
7111
- import { join as join19, relative as relative3, sep as sep3, win32 as win324 } from "node:path";
7101
+ import { lstat as lstat13, readFile as readFile17, realpath as realpath7 } from "node:fs/promises";
7102
+ import { join as join20, relative as relative3, sep as sep3, win32 as win324 } from "node:path";
7112
7103
  import { Writable } from "node:stream";
7113
7104
  import { pipeline } from "node:stream/promises";
7114
7105
  import { createGzip } from "node:zlib";
@@ -7130,15 +7121,15 @@ function inside(root, target) {
7130
7121
  return path === "" || path !== ".." && !path.startsWith(`..${sep3}`) && !path.startsWith("/") && !win324.isAbsolute(path);
7131
7122
  }
7132
7123
  async function capture(root, file) {
7133
- const absolute = join19(root, ...file.path.split("/"));
7124
+ const absolute = join20(root, ...file.path.split("/"));
7134
7125
  try {
7135
- const entry2 = await lstat12(absolute);
7126
+ const entry2 = await lstat13(absolute);
7136
7127
  if (!entry2.isFile() || entry2.isSymbolicLink() || entry2.size !== file.bytes) {
7137
7128
  changed(file.path, `\u63D0\u4EA4\u524D\u6587\u4EF6\u53D1\u751F\u53D8\u5316\uFF1A${file.path}`);
7138
7129
  }
7139
7130
  const canonical = await realpath7(absolute);
7140
7131
  if (!inside(root, canonical)) changed(file.path, `\u63D0\u4EA4\u6587\u4EF6\u8D8A\u8FC7\u9879\u76EE\u6839\u76EE\u5F55\uFF1A${file.path}`);
7141
- const contents = await readFile15(absolute);
7132
+ const contents = await readFile17(absolute);
7142
7133
  if (contents.byteLength !== file.bytes || digest3(contents) !== file.digest) {
7143
7134
  changed(file.path, `\u63D0\u4EA4\u524D\u6587\u4EF6\u5185\u5BB9\u53D1\u751F\u53D8\u5316\uFF1A${file.path}`);
7144
7135
  }
@@ -7439,7 +7430,7 @@ async function initializeProjectRoute(route, args, io, options, application) {
7439
7430
  const existingBuddyId = initializationPlan?.existingManifest?.buddyId;
7440
7431
  if (existingBuddyId !== void 0 && args.buddyId !== void 0 && existingBuddyId !== args.buddyId) {
7441
7432
  throw new CliUsageError(
7442
- `\u5DF2\u6709 buddy.agent.json \u7ED1\u5B9A\u7684\u662F ${existingBuddyId}\uFF0C\u4E0E --buddy-id ${args.buddyId} \u4E0D\u4E00\u81F4`
7433
+ `\u5DF2\u6709 package.json \u7ED1\u5B9A\u7684\u662F ${existingBuddyId}\uFF0C\u4E0E --buddy-id ${args.buddyId} \u4E0D\u4E00\u81F4`
7443
7434
  );
7444
7435
  }
7445
7436
  const requestedBuddyId = existingBuddyId ?? args.buddyId;
@@ -7511,7 +7502,7 @@ async function runRoute(route, args, io, options) {
7511
7502
  const existingBuddyId = plan.existingManifest?.buddyId;
7512
7503
  if (existingBuddyId !== void 0 && args.buddyId !== void 0 && existingBuddyId !== args.buddyId) {
7513
7504
  throw new CliUsageError(
7514
- `\u5DF2\u6709 buddy.agent.json \u7ED1\u5B9A\u7684\u662F ${existingBuddyId}\uFF0C\u4E0E --buddy-id ${args.buddyId} \u4E0D\u4E00\u81F4`
7505
+ `\u5DF2\u6709 package.json \u7ED1\u5B9A\u7684\u662F ${existingBuddyId}\uFF0C\u4E0E --buddy-id ${args.buddyId} \u4E0D\u4E00\u81F4`
7515
7506
  );
7516
7507
  }
7517
7508
  const requestedBuddyId = existingBuddyId ?? args.buddyId;
@@ -7521,7 +7512,7 @@ async function runRoute(route, args, io, options) {
7521
7512
  let draft;
7522
7513
  try {
7523
7514
  plan = await planBuddyDraftInitialization(rootDirectory);
7524
- draft = await applyBuddyDraftInitialization(plan, { schemaVersion: 1, buddyId });
7515
+ draft = await applyBuddyDraftInitialization(plan, { buddyId });
7525
7516
  } catch (cause) {
7526
7517
  io.writeError(
7527
7518
  `\u4E91\u7AEF\u642D\u5B50\u8EAB\u4EFD ${buddyId} \u5DF2\u51C6\u5907\u597D\uFF0C\u4F46\u672C\u5730 ${plan.agentConfigPath} \u5199\u5165\u5931\u8D25\u3002\u8BF7\u4F7F\u7528 --buddy-id ${buddyId} \u91CD\u8BD5\u3002`
@@ -7545,7 +7536,7 @@ async function resumeProjectArguments(args, cwd, options, io) {
7545
7536
  await assertInitializableBuddyTarget(root);
7546
7537
  let entry2;
7547
7538
  try {
7548
- entry2 = await lstat13(join20(root, "buddy.agent.json"));
7539
+ entry2 = await lstat14(join21(root, "package.json"));
7549
7540
  } catch (cause) {
7550
7541
  if (cause.code === "ENOENT") {
7551
7542
  const draft = await readMetaDraft(root);
@@ -7562,13 +7553,13 @@ async function resumeProjectArguments(args, cwd, options, io) {
7562
7553
  throw cause;
7563
7554
  }
7564
7555
  if (!entry2.isFile() || entry2.isSymbolicLink()) {
7565
- throw new CliUsageError("buddy.agent.json \u5FC5\u987B\u662F\u666E\u901A\u6587\u4EF6\uFF0C\u4E0D\u80FD\u4F7F\u7528\u7B26\u53F7\u94FE\u63A5");
7556
+ throw new CliUsageError("package.json \u5FC5\u987B\u662F\u666E\u901A\u6587\u4EF6\uFF0C\u4E0D\u80FD\u4F7F\u7528\u7B26\u53F7\u94FE\u63A5");
7566
7557
  }
7567
7558
  const manifest = await readBuddyProjectManifest(root);
7568
7559
  await checkRuntimeUpdate(root, (message) => io.writeError(message), options.runtimeCatalog);
7569
7560
  if (args.buddyId !== void 0 && args.buddyId !== manifest.buddyId) {
7570
7561
  throw new CliUsageError(
7571
- `\u5DF2\u6709 buddy.agent.json \u7ED1\u5B9A\u7684\u662F ${manifest.buddyId}\uFF0C\u4E0E --buddy-id ${args.buddyId} \u4E0D\u4E00\u81F4`
7562
+ `\u5DF2\u6709 package.json \u7ED1\u5B9A\u7684\u662F ${manifest.buddyId}\uFF0C\u4E0E --buddy-id ${args.buddyId} \u4E0D\u4E00\u81F4`
7572
7563
  );
7573
7564
  }
7574
7565
  const { client } = platformDependencies(options);
@@ -7754,8 +7745,8 @@ async function* parseServerSentEvents(body, options = {}) {
7754
7745
  }
7755
7746
  export {
7756
7747
  AGENT_INHERITED_ENV_ALLOWLIST,
7757
- BUDDY_AGENT_FILENAME,
7758
- BUDDY_AGENT_SCHEMA,
7748
+ BUDDY_PACKAGE_FILENAME,
7749
+ BUDDY_PACKAGE_SCHEMA,
7759
7750
  BUDDY_PLATFORM_AGENT_ENTRY,
7760
7751
  BUDDY_PLATFORM_FACTORY_ENTRY,
7761
7752
  BUDDY_PLATFORM_PACKAGE_JSON,
@@ -7810,7 +7801,6 @@ export {
7810
7801
  isSafeProjectRelativePath,
7811
7802
  isWindowsReservedPathSegment,
7812
7803
  latestRuntimeTemplate,
7813
- migrateRuntimeStartup,
7814
7804
  normalizePlatformUrl,
7815
7805
  openExternalUrl,
7816
7806
  parseBuddyAgentConfig,