@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/README.md +37 -40
- package/dist/bin/core.js +247 -257
- package/dist/bin/core.js.map +4 -4
- package/dist/bin/preview.js +1 -3
- package/dist/bin/preview.js.map +2 -2
- package/dist/web/app.js +1 -1
- package/package.json +3 -3
- package/resources/README.md +2 -2
- package/resources/agent-template/package-lock.json +4 -6
- package/resources/agent-template/package.json +1 -2
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(
|
|
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
|
|
238
|
+
rename as rename6,
|
|
244
239
|
unlink as unlink4
|
|
245
240
|
} from "node:fs/promises";
|
|
246
|
-
import { randomUUID as
|
|
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.
|
|
252
|
-
var
|
|
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: "
|
|
255
|
-
description: "\
|
|
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,
|
|
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 =
|
|
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
|
|
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
|
-
|
|
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 && (
|
|
1067
|
-
const packageContents =
|
|
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
|
-
|
|
1085
|
-
|
|
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
|
|
1121
|
-
var
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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({
|
|
1145
|
+
return assertBuddyAgentConfig({ buddyId: config.buddyId });
|
|
1212
1146
|
}
|
|
1213
1147
|
function combineBuddyProject(config) {
|
|
1214
|
-
|
|
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
|
-
`${
|
|
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
|
-
`${
|
|
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 ${
|
|
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,
|
|
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,
|
|
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}.${
|
|
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}.${
|
|
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
|
|
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 ${
|
|
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 ${
|
|
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 ${
|
|
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 ${
|
|
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
|
-
`${
|
|
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 ${
|
|
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,
|
|
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,
|
|
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,
|
|
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 ${
|
|
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,
|
|
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
|
|
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,
|
|
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.
|
|
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.
|
|
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
|
|
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
|
|
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
|
|
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
|
|
1871
|
-
import { lstat as lstat8, mkdir as mkdir7, readFile as
|
|
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
|
|
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}.${
|
|
1941
|
-
await
|
|
1877
|
+
const temporary = `${full}.${randomUUID5()}.tmp`;
|
|
1878
|
+
await writeFile6(temporary, value, { flag: "wx", mode: 384 });
|
|
1942
1879
|
try {
|
|
1943
|
-
await
|
|
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/${
|
|
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
|
|
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
|
|
2187
|
-
import { link as link2, lstat as lstat9, mkdir as mkdir8, readFile as
|
|
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\
|
|
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(
|
|
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
|
-
| \`
|
|
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
|
|
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 \`
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
2377
|
+
return readFile12(path);
|
|
2440
2378
|
}
|
|
2441
2379
|
async function writeOnce(path, bytes) {
|
|
2442
|
-
const temporary = `${path}.${
|
|
2443
|
-
await
|
|
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}.${
|
|
2391
|
+
const temporary = `${path}.${randomUUID6()}.tmp`;
|
|
2454
2392
|
try {
|
|
2455
|
-
await
|
|
2456
|
-
await
|
|
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:
|
|
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(`
|
|
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
|
|
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
|
|
2752
|
-
import { randomUUID as
|
|
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
|
|
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}.${
|
|
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
|
|
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: "
|
|
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
|
|
3171
|
-
import { join as
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
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
|
|
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
|
|
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
|
|
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 ??
|
|
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
|
|
5549
|
-
import { extname, isAbsolute as isAbsolute3, join as
|
|
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 :
|
|
5694
|
+
const candidate = skillPath === "." ? projectRoot : join18(projectRoot, ...skillPath.split("/"));
|
|
5719
5695
|
try {
|
|
5720
|
-
await
|
|
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 =
|
|
5731
|
+
const candidate = join18(context.skillRoot, "SKILL.md");
|
|
5756
5732
|
try {
|
|
5757
|
-
await
|
|
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 =
|
|
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
|
|
6315
|
-
import { isAbsolute as isAbsolute4, join as
|
|
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
|
|
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 =
|
|
6496
|
+
const path = join19(projectRoot, filename);
|
|
6521
6497
|
let entry2;
|
|
6522
6498
|
try {
|
|
6523
|
-
entry2 = await
|
|
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: `${
|
|
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 ===
|
|
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 ${
|
|
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 =
|
|
6699
|
+
const absolutePath = join19(directory, name);
|
|
6724
6700
|
let entry2;
|
|
6725
6701
|
try {
|
|
6726
|
-
entry2 = await
|
|
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 =
|
|
6978
|
-
const entry2 = await
|
|
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
|
-
|
|
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([
|
|
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:
|
|
7034
|
+
filename: BUDDY_PACKAGE_FILENAME,
|
|
7052
7035
|
initial: initialAgentEntry,
|
|
7053
7036
|
manifestFiles: manifest.files,
|
|
7054
7037
|
maxFileBytes: limits.maxFileBytes
|
|
7055
7038
|
});
|
|
7056
|
-
|
|
7057
|
-
if (
|
|
7058
|
-
|
|
7059
|
-
|
|
7060
|
-
|
|
7061
|
-
|
|
7062
|
-
|
|
7063
|
-
|
|
7064
|
-
|
|
7065
|
-
|
|
7066
|
-
|
|
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
|
|
7111
|
-
import { join as
|
|
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 =
|
|
7124
|
+
const absolute = join20(root, ...file.path.split("/"));
|
|
7134
7125
|
try {
|
|
7135
|
-
const entry2 = await
|
|
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
|
|
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
|
|
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
|
|
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, {
|
|
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
|
|
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("
|
|
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
|
|
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
|
-
|
|
7758
|
-
|
|
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,
|