@my-life-buddies/cli 0.5.0 → 0.8.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 +67 -6
- package/dist/bin/buddy.js +174 -1
- package/dist/bin/buddy.js.map +4 -4
- package/dist/bin/core.js +123 -25
- package/dist/bin/core.js.map +4 -4
- package/package.json +3 -3
- package/resources/agent-template/package-lock.json +4 -4
- package/resources/agent-template/package.json +1 -1
package/dist/bin/core.js
CHANGED
|
@@ -17,7 +17,7 @@ function runModelsCommand(args, io) {
|
|
|
17
17
|
} else if (args.length === 1 && args[0] === "--json") {
|
|
18
18
|
io.write(JSON.stringify({ models: MODEL_IDS }, null, 2));
|
|
19
19
|
} else if (args.length === 0) {
|
|
20
|
-
io.write("CLI \u5185\u7F6E\u6A21\u578B\u76EE\u5F55\uFF08Runtime 0.
|
|
20
|
+
io.write("CLI \u5185\u7F6E\u6A21\u578B\u76EE\u5F55\uFF08Runtime 0.12.0\uFF09\uFF1A");
|
|
21
21
|
for (const id of MODEL_IDS) io.write(`- ${id}`);
|
|
22
22
|
io.write("\u5C06\u6240\u9009 ID \u5199\u5165 buddy.agent.json.model\uFF1B\u672A\u8BBE\u7F6E\u65F6\u6A21\u677F\u4F7F\u7528 kimi-k2.6\u3002\u81EA\u5B9A\u4E49\u4F1A\u8BDD\u5DE5\u5382\u4E5F\u53EF\u6309\u4F1A\u8BDD\u8BBE\u7F6E initialState.model\u3002");
|
|
23
23
|
} else {
|
|
@@ -1462,11 +1462,13 @@ Tool \u548C Hook \u662F Runtime \u7684\u6269\u5C55\u70B9\uFF1BService \u53EA\u66
|
|
|
1462
1462
|
|
|
1463
1463
|
\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
|
|
1464
1464
|
|
|
1465
|
-
\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\u5F53\u524D\u5B89\u88C5\u7684 Runtime \u5BFC\u51FA\u8BFB\u53D6\u5168\u90E8\u6570\u636E\u96C6\uFF1B\u4E0D\u8981\u6C42\u767B\u5F55\uFF0C\u4E0D\u4ECE Server \u62C9\u76EE\u5F55\u3002Runtime 0.
|
|
1465
|
+
\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\u5F53\u524D\u5B89\u88C5\u7684 Runtime \u5BFC\u51FA\u8BFB\u53D6\u5168\u90E8\u6570\u636E\u96C6\uFF1B\u4E0D\u8981\u6C42\u767B\u5F55\uFF0C\u4E0D\u4ECE Server \u62C9\u76EE\u5F55\u3002Runtime 0.12.0 \u542B 10 \u9879\uFF0CCLI \u4E0D\u590D\u5236\u679A\u4E3E\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
|
|
1466
1466
|
|
|
1467
1467
|
\`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
|
|
1468
1468
|
|
|
1469
|
-
\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\u5DE5\u7A0B\u6A21\u677F\u5DF2\u9501\u5B9A npm Runtime 0.
|
|
1469
|
+
\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\u5DE5\u7A0B\u6A21\u677F\u5DF2\u9501\u5B9A npm Runtime 0.12.0\u3002
|
|
1470
|
+
|
|
1471
|
+
\u5C0F\u6302\u4EF6\u7684\u6A21\u578B\u5DE5\u5177\u4E3A \`widget_create\`\u3001\`widget_read\`\uFF08\u6574\u4E2A\u5C0F\u6302\u4EF6\uFF09\u3001\`widget_read_module\`\uFF08\u4E00\u4E2A\u6A21\u5757\uFF09\u3001\`widget_rename\`\u3001\`widget_write_record\`\u3001\`widget_delete_record\`\u3001\`widget_delete\`\uFF08\u6574\u4E2A\u5C0F\u6302\u4EF6\u8FDE\u8BB0\u5F55\uFF09\u548C \`widget_send\`\uFF0C\u6309\u4E1A\u52A1\u9700\u8981\u6CE8\u518C\u5230 \`initialState.tools\`\u3002\u4FEE\u6539\u8BB0\u5F55\u7528 \`conversation.widget.writeRecord(id, input)\`\uFF1B\u5220\u4E00\u6761\u8BB0\u5F55\u7528 \`conversation.widget.deleteRecord(id, module, recordId)\`\uFF0C\u4E0D\u80FD\u7528\u5220\u9664\u6574\u4E2A\u5C0F\u6302\u4EF6\u7684 \`conversation.widget.delete(id)\` \u4EE3\u66FF\u3002\u4E24\u4E2A\u8BFB\u53D6\u5DE5\u5177\u53EF\u7528\u4E8E\u4E3B\u52A8\u56DE\u5408\uFF0C\u5176\u4F59\u516D\u4E2A\u5199\u5165\u5DE5\u5177\u7531 Runtime \u963B\u6B62\u5728\u4E3B\u52A8\u56DE\u5408\u6267\u884C\u3002
|
|
1470
1472
|
|
|
1471
1473
|
\u9700\u8981\u7528\u6237\u4ECE\u51E0\u4E2A\u9009\u9879\u4E2D\u9009\u62E9\u65F6\uFF0C\u5728 \`initialState.tools\` \u4E2D\u52A0\u5165 \`conversation.tools.ask_question\` \u5E76\u5728\u4EBA\u8BBE\u4E2D\u8BF4\u660E\u9002\u7528\u573A\u666F\u3002\u53D1\u9898\u5361\u6216\u6388\u6743\u5361\u540E\uFF0C\u672C\u8F6E\u7ED3\u675F\u5E76\u7B49\u5F85\u7528\u6237\uFF1BPreview \u80FD\u663E\u793A\u9009\u9879\u6587\u5B57\u5E76\u53D1\u9001\u7528\u6237\u7684\u6587\u5B57\u56DE\u7B54\uFF0C\u7CFB\u7EDF\u6570\u636E\u6388\u6743\u9700\u8981\u5728 App \u4E2D\u5B8C\u6210\u3002\u6A21\u677F\u7684 \`initialState.tools\` \u9ED8\u8BA4\u4E3A\u7A7A\u6570\u7EC4\uFF0C\u53EA\u52A0\u5165\u4E1A\u52A1\u5B9E\u9645\u9700\u8981\u7684\u5DE5\u5177\uFF1B\u8D44\u6599\u76EE\u5F55\u901A\u8FC7 \`resource_list\` \u53D1\u73B0\uFF0C\u4E0D\u81EA\u52A8\u6CE8\u5165\u7CFB\u7EDF\u63D0\u793A\u3002\u65B0\u4F1A\u8BDD\u7684\u95EE\u5019\u7531\u6A21\u578B\u6309\u4EBA\u8BBE\u751F\u6210\uFF0C\u4E0D\u53E6\u8BBE\u9759\u6001\u6B22\u8FCE\u8BED\u914D\u7F6E\u3002
|
|
1472
1474
|
|
|
@@ -1740,11 +1742,13 @@ function validateBuddyMeta(meta2) {
|
|
|
1740
1742
|
invalidRequest(`meta.${key} \u5FC5\u987B\u4E3A\u4E0D\u8D85\u8FC7 ${limit} \u5B57\u7684\u5B57\u7B26\u4E32\u6216 null`);
|
|
1741
1743
|
}
|
|
1742
1744
|
}
|
|
1743
|
-
if (meta2.avatar
|
|
1744
|
-
|
|
1745
|
+
if (meta2.avatar !== void 0) validateBuddyAvatar(meta2.avatar);
|
|
1746
|
+
}
|
|
1747
|
+
function validateBuddyAvatar(value) {
|
|
1748
|
+
if (value !== null) {
|
|
1745
1749
|
let valid = false;
|
|
1746
1750
|
if (typeof value === "string" && value.length > 0 && value.length <= 2048 && !/[\s\u0000-\u001f]/u.test(value)) {
|
|
1747
|
-
valid = /^\/media\/[A-Za-z0-9_.-]
|
|
1751
|
+
valid = /^\/media\/[A-Za-z0-9_.-]+(?:\?v=[a-f0-9]{16})?$/u.test(value);
|
|
1748
1752
|
if (!valid) {
|
|
1749
1753
|
try {
|
|
1750
1754
|
const url = new URL(value);
|
|
@@ -1753,9 +1757,13 @@ function validateBuddyMeta(meta2) {
|
|
|
1753
1757
|
}
|
|
1754
1758
|
}
|
|
1755
1759
|
}
|
|
1756
|
-
if (!valid) invalidRequest("
|
|
1760
|
+
if (!valid) invalidRequest("avatar \u5FC5\u987B\u4E3A\u5408\u6CD5\u56FE\u7247\u5730\u5740\u6216 null");
|
|
1757
1761
|
}
|
|
1758
1762
|
}
|
|
1763
|
+
function validateBuddyMetaUpdate(meta2) {
|
|
1764
|
+
if (meta2.avatar !== void 0 && meta2.avatar !== null) invalidRequest("\u5934\u50CF\u5730\u5740\u7531\u5E73\u53F0\u751F\u6210\uFF0C\u8BF7\u4E0A\u4F20\u56FE\u7247\u6587\u4EF6\u6216\u4F20 null \u6E05\u9664");
|
|
1765
|
+
if (Object.keys(meta2).some((key) => key !== "avatar")) validateBuddyMeta(meta2);
|
|
1766
|
+
}
|
|
1759
1767
|
|
|
1760
1768
|
// packages/cli-core/src/commands/dev.ts
|
|
1761
1769
|
import { resolve as resolve11 } from "node:path";
|
|
@@ -2913,6 +2921,33 @@ async function runDevCommand(args, io, options = {}) {
|
|
|
2913
2921
|
// packages/cli-core/src/commands/cloud.ts
|
|
2914
2922
|
import { resolve as resolve12 } from "node:path";
|
|
2915
2923
|
|
|
2924
|
+
// packages/cli-core/src/cloud/avatar.ts
|
|
2925
|
+
import { open as open3 } from "node:fs/promises";
|
|
2926
|
+
import { basename } from "node:path";
|
|
2927
|
+
var MAX_BUDDY_AVATAR_BYTES = 5 * 1024 * 1024;
|
|
2928
|
+
async function readBuddyAvatarFile(path) {
|
|
2929
|
+
const file2 = await open3(path, "r");
|
|
2930
|
+
try {
|
|
2931
|
+
const stat2 = await file2.stat();
|
|
2932
|
+
if (!stat2.isFile()) throw new Error("\u5934\u50CF\u5FC5\u987B\u662F\u666E\u901A\u56FE\u7247\u6587\u4EF6");
|
|
2933
|
+
if (!stat2.size || stat2.size > MAX_BUDDY_AVATAR_BYTES) throw new Error("\u5934\u50CF\u4E0D\u80FD\u4E3A\u7A7A\u4E14\u4E0D\u80FD\u8D85\u8FC7 5 MiB");
|
|
2934
|
+
const buffer = Buffer.alloc(MAX_BUDDY_AVATAR_BYTES + 1);
|
|
2935
|
+
let size = 0;
|
|
2936
|
+
while (size < buffer.length) {
|
|
2937
|
+
const { bytesRead } = await file2.read(buffer, size, buffer.length - size, null);
|
|
2938
|
+
if (!bytesRead) break;
|
|
2939
|
+
size += bytesRead;
|
|
2940
|
+
}
|
|
2941
|
+
if (!size || size > MAX_BUDDY_AVATAR_BYTES) throw new Error("\u5934\u50CF\u4E0D\u80FD\u4E3A\u7A7A\u4E14\u4E0D\u80FD\u8D85\u8FC7 5 MiB");
|
|
2942
|
+
const bytes = buffer.subarray(0, size);
|
|
2943
|
+
const mediaType = bytes.subarray(0, 8).equals(Buffer.from([137, 80, 78, 71, 13, 10, 26, 10])) ? "image/png" : bytes.subarray(0, 3).equals(Buffer.from([255, 216, 255])) ? "image/jpeg" : bytes.toString("ascii", 0, 4) === "RIFF" && bytes.toString("ascii", 8, 12) === "WEBP" ? "image/webp" : void 0;
|
|
2944
|
+
if (!mediaType) throw new Error("\u4EC5\u652F\u6301 PNG\u3001JPEG\u3001WebP \u56FE\u7247\u6587\u4EF6");
|
|
2945
|
+
return { bytes, fileName: basename(path), mediaType };
|
|
2946
|
+
} finally {
|
|
2947
|
+
await file2.close();
|
|
2948
|
+
}
|
|
2949
|
+
}
|
|
2950
|
+
|
|
2916
2951
|
// packages/cli-core/src/cloud/auth.ts
|
|
2917
2952
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
2918
2953
|
|
|
@@ -3108,6 +3143,7 @@ function meta(value, path) {
|
|
|
3108
3143
|
const tagline = optionalText(source.tagline, `${path}.tagline`);
|
|
3109
3144
|
const intro = optionalText(source.intro, `${path}.intro`, true);
|
|
3110
3145
|
return Object.freeze({
|
|
3146
|
+
...source,
|
|
3111
3147
|
...name === void 0 ? {} : { name },
|
|
3112
3148
|
...avatar === void 0 ? {} : { avatar },
|
|
3113
3149
|
...tagline === void 0 ? {} : { tagline },
|
|
@@ -3250,7 +3286,7 @@ var HttpDeveloperPlatformClient = class {
|
|
|
3250
3286
|
"Content-Length": String(binaryBody.byteLength)
|
|
3251
3287
|
}
|
|
3252
3288
|
},
|
|
3253
|
-
...options.json !== void 0 ? { body: JSON.stringify(options.json) } : binaryBody === void 0 ? {} : { body: binaryBody },
|
|
3289
|
+
...options.form !== void 0 ? { body: options.form } : options.json !== void 0 ? { body: JSON.stringify(options.json) } : binaryBody === void 0 ? {} : { body: binaryBody },
|
|
3254
3290
|
redirect: "error",
|
|
3255
3291
|
signal: controller.signal
|
|
3256
3292
|
});
|
|
@@ -3277,7 +3313,14 @@ var HttpDeveloperPlatformClient = class {
|
|
|
3277
3313
|
return buddy(await this.#request("/cli/buddies", "POST", { json: { meta: request.meta } }), true);
|
|
3278
3314
|
}
|
|
3279
3315
|
async updateBuddy(request) {
|
|
3280
|
-
|
|
3316
|
+
validateBuddyMetaUpdate(request.meta);
|
|
3317
|
+
if (request.avatar) {
|
|
3318
|
+
if (request.meta.avatar === null) throw new CloudLifecycleError("INVALID_REQUEST", "\u4E0D\u80FD\u540C\u65F6\u4E0A\u4F20\u548C\u6E05\u9664\u5934\u50CF");
|
|
3319
|
+
const form = new FormData();
|
|
3320
|
+
form.set("meta", JSON.stringify(request.meta));
|
|
3321
|
+
form.set("avatar", new Blob([new Uint8Array(request.avatar.bytes)], { type: request.avatar.mediaType }), request.avatar.fileName);
|
|
3322
|
+
return buddy(await this.#request(`/cli/buddies/${encodeURIComponent(request.id)}/meta`, "PUT", { form }), true);
|
|
3323
|
+
}
|
|
3281
3324
|
return buddy(await this.#request(`/cli/buddies/${encodeURIComponent(request.id)}/meta`, "PUT", {
|
|
3282
3325
|
json: request.meta
|
|
3283
3326
|
}), true);
|
|
@@ -3708,7 +3751,7 @@ var SystemCloudTokenStore = class {
|
|
|
3708
3751
|
};
|
|
3709
3752
|
|
|
3710
3753
|
// packages/cli-core/src/cloud/mock-client.ts
|
|
3711
|
-
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
3754
|
+
import { createHash as createHash5, randomBytes as randomBytes2 } from "node:crypto";
|
|
3712
3755
|
var MockDeveloperPlatformClient = class {
|
|
3713
3756
|
#now;
|
|
3714
3757
|
#buddies = /* @__PURE__ */ new Map();
|
|
@@ -3734,7 +3777,10 @@ var MockDeveloperPlatformClient = class {
|
|
|
3734
3777
|
}
|
|
3735
3778
|
async updateBuddy(request) {
|
|
3736
3779
|
const current = this.#require(request.id);
|
|
3737
|
-
|
|
3780
|
+
validateBuddyMetaUpdate(request.meta);
|
|
3781
|
+
const onlyAvatar = Object.keys(request.meta).every((key) => key === "avatar");
|
|
3782
|
+
const avatar = request.avatar ? `/media/avatar-${request.id}.webp?v=${createHash5("sha256").update(request.avatar.bytes).digest("hex").slice(0, 16)}` : request.meta.avatar === null ? null : current.meta?.avatar ?? null;
|
|
3783
|
+
const next = this.#value({ ...current, meta: { ...onlyAvatar ? current.meta : request.meta, avatar }, updatedAt: this.#now() });
|
|
3738
3784
|
this.#buddies.set(request.id, next);
|
|
3739
3785
|
return structuredClone(next);
|
|
3740
3786
|
}
|
|
@@ -3819,7 +3865,11 @@ var HELP = Object.freeze({
|
|
|
3819
3865
|
login: "\u7528\u6CD5: buddy-cli login",
|
|
3820
3866
|
logout: "\u7528\u6CD5: buddy-cli logout",
|
|
3821
3867
|
push: "\u7528\u6CD5: buddy-cli push [--directory <\u9879\u76EE\u76EE\u5F55>] [--commit <\u672C\u6B21\u6539\u52A8\u8BF4\u660E>]",
|
|
3822
|
-
status: "\u7528\u6CD5: buddy-cli status [--directory <\u9879\u76EE\u76EE\u5F55>]"
|
|
3868
|
+
status: "\u7528\u6CD5: buddy-cli status [--directory <\u9879\u76EE\u76EE\u5F55>]",
|
|
3869
|
+
avatar: `\u7528\u6CD5: buddy-cli avatar (--file <\u56FE\u7247\u6587\u4EF6> | --clear) [--directory <\u9879\u76EE\u76EE\u5F55> | --buddy-id <\u642D\u5B50 ID>]
|
|
3870
|
+
\u4FEE\u6539\u5F53\u524D\u9879\u76EE\u6216\u6307\u5B9A\u642D\u5B50\u7684\u4E91\u7AEF\u5934\u50CF\uFF0C\u4FDD\u7559\u5176\u4ED6\u8D44\u6599\uFF1B\u4E0D\u9700\u8981\u5B89\u88C5 Runtime \u6216\u4E0A\u4F20\u4EE3\u7801\u5305\u3002
|
|
3871
|
+
--file \u63A5\u53D7\u672C\u5730\u9759\u6001 PNG\u3001JPEG\u3001WebP \u56FE\u7247\uFF0C\u6700\u5927 5 MiB\uFF1BServer \u81EA\u52A8\u5904\u7406\u5E76\u751F\u6210\u5730\u5740\u3002
|
|
3872
|
+
\u9700\u8981\u5F53\u524D\u8D26\u53F7\u62E5\u6709\u8BE5\u642D\u5B50\uFF0C\u547D\u4EE4\u6267\u884C\u540E\u7ACB\u5373\u66F4\u65B0\u4E91\u7AEF\u8D44\u6599\u3002`
|
|
3823
3873
|
});
|
|
3824
3874
|
function parse2(args, command) {
|
|
3825
3875
|
const values = /* @__PURE__ */ new Map();
|
|
@@ -3831,10 +3881,15 @@ function parse2(args, command) {
|
|
|
3831
3881
|
help = true;
|
|
3832
3882
|
continue;
|
|
3833
3883
|
}
|
|
3834
|
-
|
|
3884
|
+
if (command === "avatar" && flag2 === "--clear") {
|
|
3885
|
+
if (values.has(flag2)) throw new CloudCommandUsageError(`${flag2} \u4E0D\u80FD\u91CD\u590D`);
|
|
3886
|
+
values.set(flag2, "");
|
|
3887
|
+
continue;
|
|
3888
|
+
}
|
|
3889
|
+
const allowed = command === "push" ? flag2 === "--directory" || flag2 === "--commit" : command === "avatar" ? ["--directory", "--buddy-id", "--file"].includes(flag2) : command === "status" && flag2 === "--directory";
|
|
3835
3890
|
if (!allowed) throw new CloudCommandUsageError(`\u672A\u77E5\u53C2\u6570 ${flag2}`);
|
|
3836
3891
|
const value = args[index + 1];
|
|
3837
|
-
if (value === void 0 || !value.trim()) throw new CloudCommandUsageError(`${flag2} \u7F3A\u5C11\u503C`);
|
|
3892
|
+
if (value === void 0 || !value.trim() || command === "avatar" && value.startsWith("--")) throw new CloudCommandUsageError(`${flag2} \u7F3A\u5C11\u503C`);
|
|
3838
3893
|
if (values.has(flag2)) throw new CloudCommandUsageError(`${flag2} \u4E0D\u80FD\u91CD\u590D`);
|
|
3839
3894
|
values.set(flag2, value);
|
|
3840
3895
|
index += 1;
|
|
@@ -3881,6 +3936,7 @@ function printStatus(io, buddy2, packages) {
|
|
|
3881
3936
|
io.write(`\u642D\u5B50\uFF1A${displayName}\uFF08${buddy2.id}\uFF09`);
|
|
3882
3937
|
if (buddy2.meta?.tagline) io.write(`\u4E00\u53E5\u8BDD\u4ECB\u7ECD\uFF1A${buddy2.meta.tagline}`);
|
|
3883
3938
|
if (buddy2.meta?.intro) io.write(`\u5B8C\u6574\u4ECB\u7ECD\uFF1A${buddy2.meta.intro}`);
|
|
3939
|
+
if (buddy2.meta?.avatar) io.write(`\u5934\u50CF\uFF1A${buddy2.meta.avatar}`);
|
|
3884
3940
|
io.write(`\u4EE3\u7801\uFF1A${buddy2.pushed ? "\u5DF2\u4E0A\u4F20" : "\u672A\u4E0A\u4F20"}`);
|
|
3885
3941
|
if (buddy2.version) io.write(`\u7EBF\u4E0A\u7248\u672C\uFF1A${buddy2.version}`);
|
|
3886
3942
|
io.write(`\u8FD0\u884C\uFF1A${buddy2.online ? "\u5728\u7EBF" : "\u79BB\u7EBF"}`);
|
|
@@ -3941,6 +3997,41 @@ async function runPush(parsed, io, options) {
|
|
|
3941
3997
|
io.write("\u672C\u6B21 push \u53EA\u63D0\u4EA4\u5BA1\u6838\uFF0C\u4E0D\u4F1A\u90E8\u7F72\u6216\u53D1\u5E03 Agent\u3002");
|
|
3942
3998
|
return { exitCode: 0, buddyId: config.buddyId, version: receipt.version };
|
|
3943
3999
|
}
|
|
4000
|
+
async function runAvatar(parsed, io, options) {
|
|
4001
|
+
if (parsed.values.has("--file") === parsed.values.has("--clear")) {
|
|
4002
|
+
throw new CloudCommandUsageError("\u5FC5\u987B\u9009\u62E9 --file <\u56FE\u7247\u6587\u4EF6> \u6216 --clear\uFF0C\u4E14\u4E0D\u80FD\u540C\u65F6\u4F7F\u7528");
|
|
4003
|
+
}
|
|
4004
|
+
if (parsed.values.has("--buddy-id") && parsed.values.has("--directory")) {
|
|
4005
|
+
throw new CloudCommandUsageError("--buddy-id \u548C --directory \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528");
|
|
4006
|
+
}
|
|
4007
|
+
const file2 = parsed.values.get("--file");
|
|
4008
|
+
let upload;
|
|
4009
|
+
try {
|
|
4010
|
+
upload = file2 ? await readBuddyAvatarFile(resolve12(options.cwd ?? process.cwd(), file2)) : void 0;
|
|
4011
|
+
} catch (error2) {
|
|
4012
|
+
throw new CloudCommandUsageError(error2 instanceof Error ? error2.message : "\u65E0\u6CD5\u8BFB\u53D6\u5934\u50CF\u56FE\u7247");
|
|
4013
|
+
}
|
|
4014
|
+
let id = parsed.values.get("--buddy-id");
|
|
4015
|
+
if (id !== void 0 && !/^[A-Za-z0-9_-]{1,128}$/u.test(id)) throw new CloudCommandUsageError("--buddy-id \u5FC5\u987B\u662F\u6709\u6548\u7684\u642D\u5B50 ID");
|
|
4016
|
+
if (id === void 0) {
|
|
4017
|
+
const root = await (options.resolveProjectRoot ?? requireBuddyProjectRoot)(requestedDirectory(options, parsed));
|
|
4018
|
+
id = (await (options.readManifest ?? readBuddyProjectManifest)(root)).buddyId;
|
|
4019
|
+
}
|
|
4020
|
+
if (options.mode === "local-mock") throw new CloudCommandUsageError("\u672C\u5730\u6A21\u62DF\u6A21\u5F0F\u4E0D\u4FEE\u6539\u4E91\u7AEF\u5934\u50CF\uFF0C\u8BF7\u8FDE\u63A5\u771F\u5B9E MLB Server");
|
|
4021
|
+
const { session, client } = dependencies(options);
|
|
4022
|
+
await session.token({ signal: options.signal });
|
|
4023
|
+
const current = await client.getBuddy({ id });
|
|
4024
|
+
if (current.id !== id) throw new CloudLifecycleError("PLATFORM_RESPONSE_INVALID", "\u5E73\u53F0\u8FD4\u56DE\u7684\u642D\u5B50\u8EAB\u4EFD\u4E0D\u5339\u914D");
|
|
4025
|
+
const updated = await client.updateBuddy({ id, meta: upload ? {} : { avatar: null }, ...upload ? { avatar: upload } : {} });
|
|
4026
|
+
const avatar = updated.meta?.avatar;
|
|
4027
|
+
if (updated.id !== id || (upload ? typeof avatar !== "string" || !avatar : avatar !== null)) {
|
|
4028
|
+
throw new CloudLifecycleError("PLATFORM_RESPONSE_INVALID", "\u5E73\u53F0\u672A\u786E\u8BA4\u5934\u50CF\u66F4\u65B0\uFF0C\u8BF7\u67E5\u8BE2\u642D\u5B50\u8D44\u6599\u786E\u8BA4\u7ED3\u679C");
|
|
4029
|
+
}
|
|
4030
|
+
io.write(`${avatar === null ? "\u5DF2\u6E05\u9664" : "\u5DF2\u66F4\u65B0"}\u642D\u5B50\u5934\u50CF\uFF1A${updated.meta?.name ?? id}\uFF08${id}\uFF09`);
|
|
4031
|
+
if (typeof avatar === "string") io.write(`\u5934\u50CF\uFF1A${avatar}`);
|
|
4032
|
+
io.write("\u4E91\u7AEF\u8D44\u6599\u5DF2\u66F4\u65B0\uFF0C\u65E0\u9700 push \u6216\u91CD\u65B0\u53D1\u5E03\u7A0B\u5E8F\u5305\u3002");
|
|
4033
|
+
return { exitCode: 0, buddyId: id };
|
|
4034
|
+
}
|
|
3944
4035
|
async function runCloudCommand(command, args, io, options = {}) {
|
|
3945
4036
|
try {
|
|
3946
4037
|
const parsed = parse2(args, command);
|
|
@@ -3957,6 +4048,7 @@ async function runCloudCommand(command, args, io, options = {}) {
|
|
|
3957
4048
|
}
|
|
3958
4049
|
if (command === "logout") return await runLogout(io, options);
|
|
3959
4050
|
if (command === "push") return await runPush(parsed, io, options);
|
|
4051
|
+
if (command === "avatar") return await runAvatar(parsed, io, options);
|
|
3960
4052
|
const root = await (options.resolveProjectRoot ?? requireBuddyProjectRoot)(requestedDirectory(options, parsed));
|
|
3961
4053
|
const manifest = await (options.readManifest ?? readBuddyProjectManifest)(root);
|
|
3962
4054
|
if (options.mode === "local-mock") {
|
|
@@ -3984,7 +4076,7 @@ async function runCloudCommand(command, args, io, options = {}) {
|
|
|
3984
4076
|
var CLOUD_COMMAND_HELP = HELP;
|
|
3985
4077
|
|
|
3986
4078
|
// packages/cli-core/src/migration/index.ts
|
|
3987
|
-
import { lstat as lstat7, open as
|
|
4079
|
+
import { lstat as lstat7, open as open4, readdir as readdir4, realpath as realpath4, stat } from "node:fs/promises";
|
|
3988
4080
|
import { extname, isAbsolute as isAbsolute2, join as join8, relative, resolve as resolve13, sep, win32 as win322 } from "node:path";
|
|
3989
4081
|
var DEFAULT_SKILL_SCAN_LIMITS = Object.freeze({
|
|
3990
4082
|
maxFiles: 128,
|
|
@@ -4337,7 +4429,7 @@ async function scanFile(actualPath, reportPath, context) {
|
|
|
4337
4429
|
}
|
|
4338
4430
|
let handle;
|
|
4339
4431
|
try {
|
|
4340
|
-
handle = await
|
|
4432
|
+
handle = await open4(actualPath, "r");
|
|
4341
4433
|
} catch (cause) {
|
|
4342
4434
|
return rejectScan("SKILL_SCAN_IO_ERROR", reportPath, "\u65E0\u6CD5\u6253\u5F00 Skill \u6587\u4EF6\u3002", cause);
|
|
4343
4435
|
}
|
|
@@ -4749,8 +4841,8 @@ async function scanExternalSkillPortability(options) {
|
|
|
4749
4841
|
}
|
|
4750
4842
|
|
|
4751
4843
|
// packages/cli-core/src/push/preflight.ts
|
|
4752
|
-
import { createHash as
|
|
4753
|
-
import { lstat as lstat8, open as
|
|
4844
|
+
import { createHash as createHash6 } from "node:crypto";
|
|
4845
|
+
import { lstat as lstat8, open as open5, readdir as readdir5, realpath as realpath5 } from "node:fs/promises";
|
|
4754
4846
|
import { isAbsolute as isAbsolute3, join as join9, relative as relative2, resolve as resolve14, sep as sep2, win32 as win323 } from "node:path";
|
|
4755
4847
|
|
|
4756
4848
|
// packages/cli-core/src/push/errors.ts
|
|
@@ -4849,7 +4941,7 @@ function error(options) {
|
|
|
4849
4941
|
throw new PushPreflightError(options);
|
|
4850
4942
|
}
|
|
4851
4943
|
function sha256(value) {
|
|
4852
|
-
return `sha256:${
|
|
4944
|
+
return `sha256:${createHash6("sha256").update(value).digest("hex")}`;
|
|
4853
4945
|
}
|
|
4854
4946
|
function positiveLimit(value, name, hardMaximum) {
|
|
4855
4947
|
if (!Number.isSafeInteger(value) || value < 1 || value > hardMaximum) {
|
|
@@ -5080,7 +5172,7 @@ function sameFileIdentity(left, right) {
|
|
|
5080
5172
|
return left.dev === right.dev && left.ino === right.ino && left.size === right.size && left.mtimeMs === right.mtimeMs;
|
|
5081
5173
|
}
|
|
5082
5174
|
async function hashRegularFile(options) {
|
|
5083
|
-
const handle = await
|
|
5175
|
+
const handle = await open5(options.absolutePath, "r").catch((cause) => error({
|
|
5084
5176
|
code: "PUSH_PROJECT_INVALID",
|
|
5085
5177
|
path: options.portablePath,
|
|
5086
5178
|
message: `\u65E0\u6CD5\u8BFB\u53D6\u63D0\u4EA4\u6587\u4EF6\uFF1A${options.portablePath}`,
|
|
@@ -5095,7 +5187,7 @@ async function hashRegularFile(options) {
|
|
|
5095
5187
|
message: `\u751F\u6210\u6E05\u5355\u65F6\u6587\u4EF6\u53D1\u751F\u53D8\u5316\uFF1A${options.portablePath}`
|
|
5096
5188
|
});
|
|
5097
5189
|
}
|
|
5098
|
-
const hash =
|
|
5190
|
+
const hash = createHash6("sha256");
|
|
5099
5191
|
const captured = [];
|
|
5100
5192
|
const buffer = Buffer.allocUnsafe(READ_BUFFER_BYTES);
|
|
5101
5193
|
let bytes = 0;
|
|
@@ -5560,7 +5652,7 @@ async function createPushPreflight(options) {
|
|
|
5560
5652
|
}
|
|
5561
5653
|
|
|
5562
5654
|
// packages/cli-core/src/push/bundle.ts
|
|
5563
|
-
import { createHash as
|
|
5655
|
+
import { createHash as createHash7 } from "node:crypto";
|
|
5564
5656
|
import { lstat as lstat9, readFile as readFile8, realpath as realpath6 } from "node:fs/promises";
|
|
5565
5657
|
import { join as join10, relative as relative3, sep as sep3, win32 as win324 } from "node:path";
|
|
5566
5658
|
import { Writable } from "node:stream";
|
|
@@ -5569,7 +5661,7 @@ import { createGzip } from "node:zlib";
|
|
|
5569
5661
|
import { pack } from "tar-stream";
|
|
5570
5662
|
var MEDIA_TYPE = "application/gzip";
|
|
5571
5663
|
function digest(bytes) {
|
|
5572
|
-
return `sha256:${
|
|
5664
|
+
return `sha256:${createHash7("sha256").update(bytes).digest("hex")}`;
|
|
5573
5665
|
}
|
|
5574
5666
|
function changed(path, message, cause) {
|
|
5575
5667
|
throw new PushPreflightError({
|
|
@@ -5618,7 +5710,7 @@ async function createPushSourceBundle(plan) {
|
|
|
5618
5710
|
schemaVersion: "1",
|
|
5619
5711
|
files: files.map((file2) => ({ path: file2.path, bytes: file2.bytes, digest: file2.digest }))
|
|
5620
5712
|
});
|
|
5621
|
-
const calculatedBundleDigest = `sha256:${
|
|
5713
|
+
const calculatedBundleDigest = `sha256:${createHash7("sha256").update(`buddy-push-bundle-v1\0${descriptor}`).digest("hex")}`;
|
|
5622
5714
|
if (calculatedBundleDigest !== plan.bundleDigest) {
|
|
5623
5715
|
changed(plan.projectRoot, "\u63D0\u4EA4\u6E05\u5355\u8EAB\u4EFD\u5728\u6253\u5305\u524D\u53D1\u751F\u53D8\u5316\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C push");
|
|
5624
5716
|
}
|
|
@@ -5673,11 +5765,14 @@ var HELP2 = `\u642D\u642D Developer Platform CLI
|
|
|
5673
5765
|
|
|
5674
5766
|
\u7528\u6CD5:
|
|
5675
5767
|
buddy-cli
|
|
5768
|
+
buddy-cli --version [--json]
|
|
5769
|
+
buddy-cli update [--check] [--json]
|
|
5676
5770
|
buddy-cli init
|
|
5677
5771
|
buddy-cli init --mode create --directory <\u9879\u76EE\u76EE\u5F55> --name <\u540D\u79F0> --tagline <\u4E00\u53E5\u8BDD\u4ECB\u7ECD> --intro <\u5B8C\u6574\u4ECB\u7ECD> [--buddy-id <\u5DF2\u6709\u642D\u5B50 ID>]
|
|
5678
5772
|
buddy-cli init --mode direct --directory <\u9879\u76EE\u76EE\u5F55> --name <\u540D\u79F0> --tagline <\u4E00\u53E5\u8BDD\u4ECB\u7ECD> --intro <\u5B8C\u6574\u4ECB\u7ECD> [--buddy-id <\u5DF2\u6709\u642D\u5B50 ID>]
|
|
5679
5773
|
buddy-cli dev [--app-server <URL>] [--directory <\u9879\u76EE\u76EE\u5F55>]
|
|
5680
5774
|
buddy-cli login | logout | push | status
|
|
5775
|
+
buddy-cli avatar (--file <\u56FE\u7247\u6587\u4EF6> | --clear) [--directory <\u9879\u76EE\u76EE\u5F55> | --buddy-id <\u642D\u5B50 ID>]
|
|
5681
5776
|
buddy-cli models [--json]
|
|
5682
5777
|
buddy-cli widgets sync | check | verify
|
|
5683
5778
|
buddy-cli datasets [--directory <\u9879\u76EE\u76EE\u5F55>] [--json]
|
|
@@ -5685,6 +5780,8 @@ var HELP2 = `\u642D\u642D Developer Platform CLI
|
|
|
5685
5780
|
buddy-cli help
|
|
5686
5781
|
|
|
5687
5782
|
\u547D\u4EE4:
|
|
5783
|
+
--version \u67E5\u770B\u5F53\u524D\u8FD0\u884C\u7684 CLI \u7248\u672C\uFF08\u65E0\u9700\u8054\u7F51\u6216\u767B\u5F55\uFF09
|
|
5784
|
+
update \u68C0\u67E5 npm \u6700\u65B0\u7248\u672C\u6216\u66F4\u65B0\u5168\u5C40 CLI\uFF08\u65E0\u9700\u767B\u5F55\u6216 Agent \u5DE5\u7A0B\uFF09
|
|
5688
5785
|
init \u521B\u5EFA\u6216\u6062\u590D\u642D\u5B50\uFF0C\u51C6\u5907\u5B98\u65B9 Runtime \u5DE5\u7A0B\u6216 Creator \u624B\u518C
|
|
5689
5786
|
dev \u542F\u52A8\u5B98\u65B9 Runtime \u5E76\u8FDE\u63A5 DEV App Server
|
|
5690
5787
|
login \u901A\u8FC7\u6D4F\u89C8\u5668\u767B\u5F55\u642D\u642D\u8D26\u53F7
|
|
@@ -5693,6 +5790,7 @@ var HELP2 = `\u642D\u642D Developer Platform CLI
|
|
|
5693
5790
|
datasets \u8BFB\u53D6\u5DE5\u7A0B Runtime \u63D0\u4F9B\u7684\u6570\u636E\u96C6\u76EE\u5F55\uFF08\u65E0\u9700\u767B\u5F55\uFF09
|
|
5694
5791
|
push \u4E0A\u4F20 Agent \u5DE5\u7A0B\u548C commit\uFF0C\u63D0\u4EA4\u5E73\u53F0\u5BA1\u6838
|
|
5695
5792
|
status \u67E5\u8BE2\u642D\u5B50\u7684\u8D44\u6599\u3001\u4EE3\u7801\u3001\u8FD0\u884C\u4E0E\u53D1\u5E03\u72B6\u6001
|
|
5793
|
+
avatar \u8BBE\u7F6E\u6216\u6E05\u9664\u642D\u5B50\u5934\u50CF\uFF0C\u4FDD\u7559\u5176\u4ED6\u4E91\u7AEF\u8D44\u6599
|
|
5696
5794
|
preview \u6253\u5F00\u642D\u642D App \u79C1\u804A\u6A21\u62DF\u5668\u4E0E\u8C03\u8BD5\u9875\u9762
|
|
5697
5795
|
help \u67E5\u770B\u5E2E\u52A9
|
|
5698
5796
|
|
|
@@ -6088,7 +6186,7 @@ async function runBuddyCli(args, io, options = {}) {
|
|
|
6088
6186
|
...options.dev
|
|
6089
6187
|
});
|
|
6090
6188
|
}
|
|
6091
|
-
if (command === "login" || command === "logout" || command === "push" || command === "status") {
|
|
6189
|
+
if (command === "login" || command === "logout" || command === "push" || command === "status" || command === "avatar") {
|
|
6092
6190
|
return await runCloudCommand(command, rest, io, {
|
|
6093
6191
|
cwd: options.cwd,
|
|
6094
6192
|
...options.cloud
|