@my-life-buddies/cli 0.24.1-dev.0 → 0.24.1-dev.1
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 +2 -2
- package/dist/bin/core.js +188 -187
- package/dist/bin/core.js.map +4 -4
- package/package.json +3 -3
- package/resources/agent-template/package-lock.json +0 -1702
- package/resources/agent-template/package.json +0 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
这份说明按一次开发过程展开:登记搭子,准备工程,在本地预览,然后上传程序包。所有搭子统一使用 `@my-life-buddies/buddy-runtime`,业务能力通过 Prompt、`src/buddy-options.mjs` 和 Tool 实现。
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
空白工程模板不预置 Runtime 依赖或版本。新建工程统一查询公共 npm dev 最新 Runtime,并写入准确版本与锁文件,不提供版本选择;查询或锁文件生成失败时停止,不回退旧版本。版本策略与联调范围见 [Runtime 集成说明](../../docs/runtime-integration.md)。
|
|
8
8
|
|
|
9
9
|
## 准备 CLI 和平台地址
|
|
10
10
|
|
|
@@ -90,7 +90,7 @@ npm run release -- --publish # 显式发布当前 dev 分支到 npm dev
|
|
|
90
90
|
|
|
91
91
|
`dev` 构建 `@my-life-buddies/cli@dev`,只包含 `buddy-cli-sit` 命令。版本必须是 `x.y.z-dev.N`;发布校验拒绝 latest 标签。main 用同一个包名发布 `latest` 正式版本,提供 `buddy-cli`;两个版本必须分目录安装才能共存,同一目录中安装会互相替换。Core 和 Preview 保留 monorepo 开发边界并标记为 `private`,构建时合入 CLI 的内部模块;Preview 页面和工程模板资源进入 CLI 包;Creator 与 Avatar Skill 使用时独立加载。安装不会请求 `@buddy/cli-core` 或 `@buddy/preview`。第三方运行依赖按正常 npm dependencies 安装,构建工具 esbuild 不进入安装依赖。根工作区标记为 `private`。
|
|
92
92
|
|
|
93
|
-
版本维护:每批修改 CLI 发布内容时递增一次版本,默认 patch;根包和内部工作区版本、依赖引用、锁文件一起更新。Agent
|
|
93
|
+
版本维护:每批修改 CLI 发布内容时递增一次版本,默认 patch;根包和内部工作区版本、依赖引用、锁文件一起更新。Agent 工程自己的项目版本独立。Runtime 版本由创建时动态查询并锁定;发布前验证真实 Runtime 的动态解析和独立安装,不向空白模板写入基准版本。
|
|
94
94
|
|
|
95
95
|
SIT CLI 固定连接 SIT `https://buddies.sit.dots.chat`,无需配置地址:
|
|
96
96
|
|
package/dist/bin/core.js
CHANGED
|
@@ -179,8 +179,8 @@ async function validateRuntimeDatasets(projectRoot, requirements = []) {
|
|
|
179
179
|
}
|
|
180
180
|
|
|
181
181
|
// packages/cli-core/src/init/scaffold.ts
|
|
182
|
-
import { lstat as lstat6, mkdir as mkdir6, open as open3, readFile as
|
|
183
|
-
import { resolve as
|
|
182
|
+
import { lstat as lstat6, mkdir as mkdir6, open as open3, readFile as readFile10, rename as rename6, rmdir as rmdir2, unlink as unlink4 } from "node:fs/promises";
|
|
183
|
+
import { resolve as resolve5 } from "node:path";
|
|
184
184
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
185
185
|
|
|
186
186
|
// packages/cli-core/src/config/index.ts
|
|
@@ -1248,52 +1248,175 @@ var MODEL_IDS = Object.freeze([
|
|
|
1248
1248
|
]);
|
|
1249
1249
|
var DEFAULT_MODEL_ID = "kimi-k2.6";
|
|
1250
1250
|
|
|
1251
|
+
// packages/cli-core/src/config/runtime-policy.ts
|
|
1252
|
+
import { readFile as readFile8, realpath as realpath3 } from "node:fs/promises";
|
|
1253
|
+
import { createRequire as createRequire2 } from "node:module";
|
|
1254
|
+
import { resolve as resolve4 } from "node:path";
|
|
1255
|
+
|
|
1256
|
+
// packages/cli-core/src/config/runtime-update.ts
|
|
1257
|
+
import { readFile as readFile7 } from "node:fs/promises";
|
|
1258
|
+
import { join as join7 } from "node:path";
|
|
1259
|
+
async function projectRuntimeVersion(root) {
|
|
1260
|
+
try {
|
|
1261
|
+
return runtimeDependencyVersion(JSON.parse(await readFile7(join7(root, "package.json"), "utf8")));
|
|
1262
|
+
} catch (cause) {
|
|
1263
|
+
if (cause.code === "ENOENT") return void 0;
|
|
1264
|
+
throw cause;
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1267
|
+
function compareVersions(left, right) {
|
|
1268
|
+
const parts = (value) => {
|
|
1269
|
+
const [core, ...suffix] = value.split("-");
|
|
1270
|
+
return { core: core.split(".").map(BigInt), pre: suffix.length ? suffix.join("-").split(".") : [] };
|
|
1271
|
+
};
|
|
1272
|
+
const a = parts(left), b = parts(right);
|
|
1273
|
+
for (let i = 0; i < 3; i++) if (a.core[i] !== b.core[i]) return a.core[i] < b.core[i] ? -1 : 1;
|
|
1274
|
+
if (!a.pre.length || !b.pre.length) return a.pre.length === b.pre.length ? 0 : a.pre.length ? -1 : 1;
|
|
1275
|
+
for (let i = 0; i < Math.max(a.pre.length, b.pre.length); i++) {
|
|
1276
|
+
const x = a.pre[i], y = b.pre[i];
|
|
1277
|
+
if (x === y) continue;
|
|
1278
|
+
if (x === void 0 || y === void 0) return x === void 0 ? -1 : 1;
|
|
1279
|
+
const nx = /^\d+$/.test(x), ny = /^\d+$/.test(y);
|
|
1280
|
+
if (nx && ny) return BigInt(x) < BigInt(y) ? -1 : 1;
|
|
1281
|
+
if (nx !== ny) return nx ? -1 : 1;
|
|
1282
|
+
return x < y ? -1 : 1;
|
|
1283
|
+
}
|
|
1284
|
+
return 0;
|
|
1285
|
+
}
|
|
1286
|
+
async function runtimeVersionStatus(project, latest) {
|
|
1287
|
+
const current = project ? await projectRuntimeVersion(project) : void 0;
|
|
1288
|
+
let versionStatus;
|
|
1289
|
+
if (!project) versionStatus = "no_project";
|
|
1290
|
+
else if (!current) versionStatus = "unconfigured";
|
|
1291
|
+
else if (current === latest) versionStatus = "current";
|
|
1292
|
+
else versionStatus = compareVersions(current, latest) < 0 ? "update_available" : "project_ahead";
|
|
1293
|
+
return {
|
|
1294
|
+
projectRuntimeVersion: current ?? null,
|
|
1295
|
+
latestRuntimeVersion: latest,
|
|
1296
|
+
versionStatus,
|
|
1297
|
+
adaptationRequired: versionStatus !== "no_project" && versionStatus !== "current"
|
|
1298
|
+
};
|
|
1299
|
+
}
|
|
1300
|
+
function reportRuntimeVersion(status, report) {
|
|
1301
|
+
if (status.versionStatus === "no_project") return;
|
|
1302
|
+
report(`Runtime \u7248\u672C\uFF1A\u5DE5\u7A0B ${status.projectRuntimeVersion ?? "\u672A\u9501\u5B9A\u51C6\u786E\u7248\u672C"}\uFF0Cnpm dev \u6700\u65B0 ${status.latestRuntimeVersion}\u3002`);
|
|
1303
|
+
if (status.adaptationRequired) {
|
|
1304
|
+
report("\u8BF7\u7531\u4F60\u6216\u5F00\u53D1 Agent \u66F4\u65B0\u4F9D\u8D56\u5E76\u9002\u914D\uFF1A\u68C0\u67E5\u65B0\u7248 Runtime \u7684\u542F\u52A8\u53C2\u6570\u3001\u6A21\u578B\u3001datasets\u3001\u5DE5\u5177\u53CA Hook\uFF0C\u5B8C\u6210\u9002\u914D\u540E\u9A8C\u8BC1 DEV\u3002CLI \u672A\u4FEE\u6539\u5DE5\u7A0B\u4F9D\u8D56\u6216\u914D\u7F6E\uFF1BDEV \u542F\u52A8\u3001\u81EA\u52A8\u91CD\u8F7D\u548C push \u5FC5\u987B\u901A\u8FC7\u6700\u65B0 Runtime \u68C0\u67E5\u3002");
|
|
1305
|
+
report(`\u5728\u5DE5\u7A0B\u6839\u76EE\u5F55\u6267\u884C\uFF1Anpm install --save-exact ${BUDDY_RUNTIME_PACKAGE}@${status.latestRuntimeVersion} --registry=${RUNTIME_REGISTRY} --@my-life-buddies:registry=${RUNTIME_REGISTRY}`);
|
|
1306
|
+
}
|
|
1307
|
+
}
|
|
1308
|
+
async function checkRuntimeUpdate(root, report, options = {}) {
|
|
1309
|
+
options.signal?.throwIfAborted();
|
|
1310
|
+
try {
|
|
1311
|
+
const latest = await latestRuntimeVersion(options);
|
|
1312
|
+
reportRuntimeVersion(await runtimeVersionStatus(root, latest), report);
|
|
1313
|
+
options.signal?.throwIfAborted();
|
|
1314
|
+
return;
|
|
1315
|
+
} catch (cause) {
|
|
1316
|
+
options.signal?.throwIfAborted();
|
|
1317
|
+
report(`\u65E0\u6CD5\u68C0\u67E5 Runtime \u66F4\u65B0\uFF1A${cause instanceof Error ? cause.message : String(cause)}\u3002\u672C\u6B21\u672A\u786E\u8BA4 npm dev \u6700\u65B0\u7248\u672C\uFF1B\u53EF\u7EE7\u7EED\u67E5\u770B\u6216\u4FEE\u6539\u5DE5\u7A0B\uFF0CDEV \u542F\u52A8\u548C push \u4F1A\u53E6\u884C\u4E25\u683C\u68C0\u67E5\u3002`);
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1320
|
+
|
|
1321
|
+
// packages/cli-core/src/config/runtime-policy.ts
|
|
1322
|
+
var RuntimeRequirementError = class extends Error {
|
|
1323
|
+
constructor(code2, message, options) {
|
|
1324
|
+
super(message, options);
|
|
1325
|
+
this.code = code2;
|
|
1326
|
+
this.name = "RuntimeRequirementError";
|
|
1327
|
+
}
|
|
1328
|
+
code;
|
|
1329
|
+
};
|
|
1330
|
+
function assertRequiredRuntime(actual, expected) {
|
|
1331
|
+
if (actual === expected) return;
|
|
1332
|
+
throw new RuntimeRequirementError(
|
|
1333
|
+
"RUNTIME_VERSION_MISMATCH",
|
|
1334
|
+
`\u5DF2\u963B\u6B62\u8FD0\u884C\u6216\u4E0A\u4F20\uFF1A\u5DE5\u7A0B Runtime ${actual ?? "\u672A\u9501\u5B9A\u51C6\u786E\u7248\u672C"}\uFF0Cnpm dev \u6700\u65B0\u7248\u672C ${expected}\u3002\u5FC5\u987B\u4F7F\u7528\u5B8C\u5168\u4E00\u81F4\u7684\u7248\u672C\u3002
|
|
1335
|
+
\u8BF7\u7531\u4F60\u6216\u5F00\u53D1 Agent \u66F4\u65B0\u4F9D\u8D56\u548C\u9501\u6587\u4EF6\uFF0C\u9002\u914D\u542F\u52A8\u53C2\u6570\u3001\u6A21\u578B\u3001datasets\u3001\u5DE5\u5177\u53CA Hook \u540E\u91CD\u8BD5\u3002
|
|
1336
|
+
npm install --save-exact ${BUDDY_RUNTIME_PACKAGE}@${expected} --registry=${RUNTIME_REGISTRY} --@my-life-buddies:registry=${RUNTIME_REGISTRY}`
|
|
1337
|
+
);
|
|
1338
|
+
}
|
|
1339
|
+
function assertNpmRuntimeLock(contents, expected) {
|
|
1340
|
+
const lock = JSON.parse(contents);
|
|
1341
|
+
const installed2 = lock.lockfileVersion === 1 ? lock.dependencies?.[BUDDY_RUNTIME_PACKAGE] : lock.packages?.[`node_modules/${BUDDY_RUNTIME_PACKAGE}`];
|
|
1342
|
+
if (installed2?.version !== expected || lock.lockfileVersion !== 1 && runtimeDependencyVersion(lock.packages?.[""]) !== expected) {
|
|
1343
|
+
throw new RuntimeRequirementError("RUNTIME_DEPENDENCY_INVALID", `package-lock.json \u7684 Runtime \u4E0E\u8981\u6C42\u7684 ${expected} \u4E0D\u4E00\u81F4\u3002\u8BF7\u66F4\u65B0\u9501\u6587\u4EF6\u5E76\u91CD\u65B0\u5B89\u88C5\u4F9D\u8D56\u540E\u91CD\u8BD5\u3002`);
|
|
1344
|
+
}
|
|
1345
|
+
}
|
|
1346
|
+
async function requireProjectRuntime(root, options = {}) {
|
|
1347
|
+
const declared = await projectRuntimeVersion(root);
|
|
1348
|
+
if (!declared) throw new RuntimeRequirementError("RUNTIME_DEPENDENCY_INVALID", "\u5DE5\u7A0B\u5FC5\u987B\u5728 package.json \u58F0\u660E npm dev \u6700\u65B0 Runtime \u7684\u51C6\u786E\u7248\u672C\uFF0C\u5E76\u5B89\u88C5\u4F9D\u8D56\u548C\u9501\u6587\u4EF6\uFF1B\u4E0D\u80FD\u4F7F\u7528 dev\u3001latest \u6216\u7248\u672C\u8303\u56F4\u4F5C\u4E3A\u5DE5\u7A0B\u4F9D\u8D56\u3002");
|
|
1349
|
+
let expected;
|
|
1350
|
+
try {
|
|
1351
|
+
expected = await latestRuntimeVersion(options);
|
|
1352
|
+
} catch (cause) {
|
|
1353
|
+
options.signal?.throwIfAborted();
|
|
1354
|
+
throw new RuntimeRequirementError("RUNTIME_CHECK_FAILED", `\u65E0\u6CD5\u786E\u8BA4 npm dev \u6700\u65B0 Runtime\uFF0C\u5DF2\u963B\u6B62\u8FD0\u884C\u6216\u4E0A\u4F20\uFF1A${cause instanceof Error ? cause.message : String(cause)}\u3002\u8BF7\u6062\u590D\u8FDE\u63A5\u540E\u91CD\u8BD5\u3002`, { cause });
|
|
1355
|
+
}
|
|
1356
|
+
try {
|
|
1357
|
+
assertRequiredRuntime(await projectRuntimeVersion(root), expected);
|
|
1358
|
+
const installedPath = await realpath3(resolve4(root, "node_modules", BUDDY_RUNTIME_PACKAGE, "package.json"));
|
|
1359
|
+
const fromProject = createRequire2(resolve4(root, "package.json")).resolve(`${BUDDY_RUNTIME_PACKAGE}/package.json`);
|
|
1360
|
+
if (await realpath3(fromProject) !== installedPath) throw new Error("Runtime \u5FC5\u987B\u5B89\u88C5\u5728\u5F53\u524D\u5DE5\u7A0B\u4E2D");
|
|
1361
|
+
const installed2 = JSON.parse(await readFile8(installedPath, "utf8"));
|
|
1362
|
+
if (installed2.version !== expected) throw new Error(`Runtime \u5B9E\u9645\u5B89\u88C5 ${installed2.version}\uFF0C\u8981\u6C42 ${expected}`);
|
|
1363
|
+
let lock;
|
|
1364
|
+
try {
|
|
1365
|
+
lock = await readFile8(resolve4(root, "package-lock.json"), "utf8");
|
|
1366
|
+
} catch (cause) {
|
|
1367
|
+
if (cause.code !== "ENOENT") throw cause;
|
|
1368
|
+
}
|
|
1369
|
+
if (lock !== void 0) assertNpmRuntimeLock(lock, expected);
|
|
1370
|
+
options.signal?.throwIfAborted();
|
|
1371
|
+
return expected;
|
|
1372
|
+
} catch (cause) {
|
|
1373
|
+
options.signal?.throwIfAborted();
|
|
1374
|
+
if (cause instanceof RuntimeRequirementError) throw cause;
|
|
1375
|
+
throw new RuntimeRequirementError("RUNTIME_DEPENDENCY_INVALID", `Runtime \u4F9D\u8D56\u6821\u9A8C\u5931\u8D25\uFF1A${cause instanceof Error ? cause.message : String(cause)}\u3002\u8BF7\u66F4\u65B0\u4F9D\u8D56\u53CA\u9501\u6587\u4EF6\u5E76\u5B89\u88C5\uFF1Bnpm \u5DE5\u7A0B\u53EF\u8FD0\u884C npm ci\u3002`, { cause });
|
|
1376
|
+
}
|
|
1377
|
+
}
|
|
1378
|
+
|
|
1251
1379
|
// packages/cli-core/src/init/runtime-template.ts
|
|
1252
1380
|
import { execFile as execFile3 } from "node:child_process";
|
|
1253
|
-
import { mkdtemp as mkdtemp3, readFile as
|
|
1381
|
+
import { mkdtemp as mkdtemp3, readFile as readFile9, rm as rm3, writeFile as writeFile5 } from "node:fs/promises";
|
|
1254
1382
|
import { tmpdir } from "node:os";
|
|
1255
|
-
import { join as
|
|
1383
|
+
import { join as join8 } from "node:path";
|
|
1256
1384
|
import { promisify as promisify3 } from "node:util";
|
|
1257
1385
|
var execute3 = promisify3(execFile3);
|
|
1258
1386
|
async function latestRuntimeTemplate(template, options) {
|
|
1259
|
-
const bundledVersion = runtimeDependencyVersion(JSON.parse(template.packageJson));
|
|
1260
|
-
if (!bundledVersion) throw new Error("CLI \u5DE5\u7A0B\u6A21\u677F\u7F3A\u5C11 Runtime \u7684\u51C6\u786E\u7248\u672C");
|
|
1261
1387
|
let temporaryRoot;
|
|
1262
1388
|
try {
|
|
1263
1389
|
options.signal?.throwIfAborted();
|
|
1264
1390
|
options.report("\u6B63\u5728\u67E5\u8BE2\u516C\u5171 npm dev \u7684\u6700\u65B0 Runtime\u2026");
|
|
1265
1391
|
const version = await latestRuntimeVersion(options);
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
const userConfig = join7(temporaryRoot, ".npmrc");
|
|
1272
|
-
await writeFile5(userConfig, `registry=${RUNTIME_REGISTRY}
|
|
1392
|
+
temporaryRoot = await mkdtemp3(join8(tmpdir(), "buddy-runtime-template-"));
|
|
1393
|
+
await writeFile5(join8(temporaryRoot, "package.json"), template.packageJson);
|
|
1394
|
+
await writeFile5(join8(temporaryRoot, "package-lock.json"), template.packageLock);
|
|
1395
|
+
const userConfig = join8(temporaryRoot, ".npmrc");
|
|
1396
|
+
await writeFile5(userConfig, `registry=${RUNTIME_REGISTRY}
|
|
1273
1397
|
`);
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
}
|
|
1398
|
+
options.report(`\u6B63\u5728\u4E3A Runtime ${version} \u751F\u6210\u4F9D\u8D56\u9501\u6587\u4EF6\u2026`);
|
|
1399
|
+
const runNpm = options.runNpm ?? ((args, settings) => execute3("npm", args, { ...settings, encoding: "utf8", maxBuffer: 4 * 1024 * 1024 }));
|
|
1400
|
+
await runNpm([
|
|
1401
|
+
"install",
|
|
1402
|
+
"--package-lock-only",
|
|
1403
|
+
"--save-exact",
|
|
1404
|
+
`${BUDDY_RUNTIME_PACKAGE}@${version}`,
|
|
1405
|
+
"--ignore-scripts",
|
|
1406
|
+
"--no-audit",
|
|
1407
|
+
"--no-fund",
|
|
1408
|
+
"--engine-strict",
|
|
1409
|
+
`--registry=${RUNTIME_REGISTRY}`,
|
|
1410
|
+
`--@my-life-buddies:registry=${RUNTIME_REGISTRY}`,
|
|
1411
|
+
`--userconfig=${userConfig}`,
|
|
1412
|
+
"--prefer-online",
|
|
1413
|
+
"--fetch-retries=0",
|
|
1414
|
+
"--fetch-timeout=20000"
|
|
1415
|
+
], { cwd: temporaryRoot, signal: options.signal, timeout: 6e4 });
|
|
1416
|
+
const result = {
|
|
1417
|
+
packageJson: await readFile9(join8(temporaryRoot, "package.json"), "utf8"),
|
|
1418
|
+
packageLock: await readFile9(join8(temporaryRoot, "package-lock.json"), "utf8")
|
|
1419
|
+
};
|
|
1297
1420
|
const pkg = JSON.parse(result.packageJson);
|
|
1298
1421
|
const lock = JSON.parse(result.packageLock);
|
|
1299
1422
|
const locked = lock.packages?.[`node_modules/${BUDDY_RUNTIME_PACKAGE}`];
|
|
@@ -1306,7 +1429,7 @@ async function latestRuntimeTemplate(template, options) {
|
|
|
1306
1429
|
} catch (cause) {
|
|
1307
1430
|
if (options.signal?.aborted) throw new Error("Runtime \u7248\u672C\u67E5\u8BE2\u5DF2\u53D6\u6D88");
|
|
1308
1431
|
const reason = cause instanceof Error && !cause.message.includes("Command failed") ? cause.message : "npm \u672A\u5B8C\u6210\u9501\u6587\u4EF6\u751F\u6210";
|
|
1309
|
-
throw new Error(`\u672A\u80FD\u9501\u5B9A\u6700\u65B0 dev Runtime\uFF1A${reason}\u3002\u5DF2\u505C\u6B62\u751F\u6210\u5DE5\u7A0B\u4F9D\u8D56\uFF0C\u8BF7\u4FEE\u590D\u540E\u91CD\u8BD5\uFF1B\u4E0D\u4F1A\
|
|
1432
|
+
throw new Error(`\u672A\u80FD\u9501\u5B9A\u6700\u65B0 dev Runtime\uFF1A${reason}\u3002\u5DF2\u505C\u6B62\u751F\u6210\u5DE5\u7A0B\u4F9D\u8D56\uFF0C\u8BF7\u4FEE\u590D\u540E\u91CD\u8BD5\uFF1B\u4E0D\u4F1A\u4F7F\u7528\u9884\u7F6E\u6216\u7F13\u5B58\u7684\u65E7\u7248\u672C\u3002`, { cause });
|
|
1310
1433
|
} finally {
|
|
1311
1434
|
if (temporaryRoot) await rm3(temporaryRoot, { recursive: true, force: true });
|
|
1312
1435
|
}
|
|
@@ -1398,15 +1521,15 @@ try {
|
|
|
1398
1521
|
`;
|
|
1399
1522
|
}
|
|
1400
1523
|
async function scaffoldPlatformAgent(projectRoot, name, options = {}) {
|
|
1401
|
-
const path =
|
|
1402
|
-
const packagePath =
|
|
1524
|
+
const path = resolve5(projectRoot, BUDDY_PLATFORM_AGENT_ENTRY);
|
|
1525
|
+
const packagePath = resolve5(projectRoot, BUDDY_PLATFORM_PACKAGE_JSON);
|
|
1403
1526
|
if (!(await lstat6(packagePath)).isFile()) throw new Error("package.json \u5FC5\u987B\u662F\u666E\u901A\u6587\u4EF6");
|
|
1404
|
-
const originalPackage = await
|
|
1527
|
+
const originalPackage = await readFile10(packagePath, "utf8");
|
|
1405
1528
|
const projectPackage = parseBuddyProjectManifest(originalPackage);
|
|
1406
1529
|
const isIdentityDraft = Object.keys(projectPackage).every((key) => key === "buddyId");
|
|
1407
1530
|
const hasAlternateLockfile = (await Promise.all(["pnpm-lock.yaml", "yarn.lock"].map(async (name2) => {
|
|
1408
1531
|
try {
|
|
1409
|
-
if (!(await lstat6(
|
|
1532
|
+
if (!(await lstat6(resolve5(projectRoot, name2))).isFile()) {
|
|
1410
1533
|
throw new TypeError(`\u4F9D\u8D56\u9501\u6587\u4EF6\u5FC5\u987B\u662F\u666E\u901A\u6587\u4EF6\uFF1A${name2}`);
|
|
1411
1534
|
}
|
|
1412
1535
|
return true;
|
|
@@ -1417,19 +1540,19 @@ async function scaffoldPlatformAgent(projectRoot, name, options = {}) {
|
|
|
1417
1540
|
}))).some(Boolean);
|
|
1418
1541
|
const files = [
|
|
1419
1542
|
{ path, content: platformAgentTemplate(name) },
|
|
1420
|
-
{ path:
|
|
1421
|
-
{ path:
|
|
1422
|
-
...hasAlternateLockfile ? [] : [{ path:
|
|
1423
|
-
{ path:
|
|
1424
|
-
{ path:
|
|
1425
|
-
{ path:
|
|
1426
|
-
{ path:
|
|
1543
|
+
{ path: resolve5(projectRoot, BUDDY_PLATFORM_FACTORY_ENTRY), content: platformFactoryTemplate(options.model) },
|
|
1544
|
+
{ path: resolve5(projectRoot, BUDDY_PLATFORM_PACKAGE_JSON), content: await readFile10(new URL("../../resources/agent-template/package.json", import.meta.url), "utf8") },
|
|
1545
|
+
...hasAlternateLockfile ? [] : [{ path: resolve5(projectRoot, BUDDY_PLATFORM_PACKAGE_LOCK), content: await readFile10(new URL("../../resources/agent-template/package-lock.json", import.meta.url), "utf8") }],
|
|
1546
|
+
{ path: resolve5(projectRoot, BUDDY_PLATFORM_START_ENTRY), content: platformStartTemplate() },
|
|
1547
|
+
{ path: resolve5(projectRoot, "data-access.json"), content: '{\n "requirements": []\n}\n' },
|
|
1548
|
+
{ path: resolve5(projectRoot, ".gitignore"), content: "node_modules/\n/.env\n" },
|
|
1549
|
+
{ path: resolve5(projectRoot, ".env.example"), content: "# \u642D\u5B50\u8EAB\u4EFD\u7531 package.json \u9876\u5C42\u7684 buddyId \u63D0\u4F9B\u3002\n# \u9996\u6B21\u8FD0\u884C buddy-cli-sit dev \u6216\u5728\u540E\u53F0\u542F\u52A8 DEV \u65F6\uFF0CCLI \u4F1A\u51C6\u5907 .env\u3002\nBUDDY_TOKEN=\n# CLI \u81EA\u52A8\u5199\u5165 SIT \u7684 MLB_GATEWAY_URL\uFF0C\u4F9B Runtime \u4F7F\u7528\uFF1B\u65E0\u9700\u624B\u52A8\u8BBE\u7F6E\u3002\n# SIT CLI \u4E0D\u652F\u6301\u901A\u8FC7\u73AF\u5883\u53D8\u91CF\u6216 .env \u5207\u6362\u5E73\u53F0\u3002\n" }
|
|
1427
1550
|
];
|
|
1428
1551
|
const handles = [];
|
|
1429
1552
|
const createdDirectories = [];
|
|
1430
1553
|
try {
|
|
1431
1554
|
for (const directory of PLATFORM_DIRECTORIES) {
|
|
1432
|
-
const directoryPath =
|
|
1555
|
+
const directoryPath = resolve5(projectRoot, directory);
|
|
1433
1556
|
try {
|
|
1434
1557
|
await mkdir6(directoryPath, { mode: 448 });
|
|
1435
1558
|
createdDirectories.push(directoryPath);
|
|
@@ -1450,20 +1573,28 @@ async function scaffoldPlatformAgent(projectRoot, name, options = {}) {
|
|
|
1450
1573
|
}
|
|
1451
1574
|
}
|
|
1452
1575
|
}
|
|
1453
|
-
const packageFile = files.find((file) => file.path ===
|
|
1454
|
-
const lockFile = files.find((file) => file.path ===
|
|
1576
|
+
const packageFile = files.find((file) => file.path === resolve5(projectRoot, BUDDY_PLATFORM_PACKAGE_JSON));
|
|
1577
|
+
const lockFile = files.find((file) => file.path === resolve5(projectRoot, BUDDY_PLATFORM_PACKAGE_LOCK));
|
|
1455
1578
|
packageFile.content = JSON.stringify({ ...JSON.parse(packageFile.content), buddyId: projectPackage.buddyId }, null, 2) + "\n";
|
|
1456
|
-
if (
|
|
1457
|
-
const
|
|
1579
|
+
if (isIdentityDraft) {
|
|
1580
|
+
const resolveDependencies = options.resolveDependencies ?? ((template2) => latestRuntimeTemplate(template2, { report() {
|
|
1581
|
+
} }));
|
|
1582
|
+
const template = await resolveDependencies({
|
|
1583
|
+
packageJson: packageFile.content,
|
|
1584
|
+
packageLock: lockFile?.content ?? await readFile10(new URL("../../resources/agent-template/package-lock.json", import.meta.url), "utf8")
|
|
1585
|
+
});
|
|
1458
1586
|
if (parseBuddyProjectManifest(template.packageJson).buddyId !== projectPackage.buddyId) {
|
|
1459
1587
|
throw new Error("\u4F9D\u8D56\u89E3\u6790\u6539\u53D8\u4E86 package.json.buddyId\uFF0C\u5DF2\u505C\u6B62\u8865\u9F50\u5DE5\u7A0B");
|
|
1460
1588
|
}
|
|
1589
|
+
const version = runtimeDependencyVersion(JSON.parse(template.packageJson));
|
|
1590
|
+
if (!version) throw new Error("\u4F9D\u8D56\u89E3\u6790\u672A\u8FD4\u56DE Runtime \u7684\u51C6\u786E\u7248\u672C\uFF0C\u5DF2\u505C\u6B62\u8865\u9F50\u5DE5\u7A0B");
|
|
1591
|
+
assertNpmRuntimeLock(template.packageLock, version);
|
|
1461
1592
|
packageFile.content = template.packageJson;
|
|
1462
|
-
lockFile.content = template.packageLock;
|
|
1593
|
+
if (lockFile) lockFile.content = template.packageLock;
|
|
1463
1594
|
}
|
|
1464
1595
|
if (lockFile && (isIdentityDraft || handles.some((file) => file.path === lockFile.path))) {
|
|
1465
|
-
const packageContents = isIdentityDraft ? packageFile.content : await
|
|
1466
|
-
const lockContents = handles.some((file) => file.path === lockFile.path) ? lockFile.content : await
|
|
1596
|
+
const packageContents = isIdentityDraft ? packageFile.content : await readFile10(packageFile.path, "utf8");
|
|
1597
|
+
const lockContents = handles.some((file) => file.path === lockFile.path) ? lockFile.content : await readFile10(lockFile.path, "utf8");
|
|
1467
1598
|
const declared = JSON.parse(packageContents).dependencies ?? {};
|
|
1468
1599
|
const locked = JSON.parse(lockContents).packages?.[""]?.dependencies ?? {};
|
|
1469
1600
|
if (JSON.stringify(Object.entries(declared).sort()) !== JSON.stringify(Object.entries(locked).sort())) {
|
|
@@ -1482,7 +1613,7 @@ async function scaffoldPlatformAgent(projectRoot, name, options = {}) {
|
|
|
1482
1613
|
await handle.writeFile(packageFile.content, "utf8");
|
|
1483
1614
|
await handle.sync();
|
|
1484
1615
|
await handle.close();
|
|
1485
|
-
if (!(await lstat6(packagePath)).isFile() || await
|
|
1616
|
+
if (!(await lstat6(packagePath)).isFile() || await readFile10(packagePath, "utf8") !== originalPackage) {
|
|
1486
1617
|
throw new Error("\u8865\u9F50\u5DE5\u7A0B\u65F6 package.json \u5DF2\u6539\u53D8\uFF0C\u8BF7\u91CD\u8BD5");
|
|
1487
1618
|
}
|
|
1488
1619
|
await rename6(temporary, packagePath);
|
|
@@ -1509,136 +1640,6 @@ async function scaffoldPlatformAgent(projectRoot, name, options = {}) {
|
|
|
1509
1640
|
// packages/cli-core/src/init/runtime-version.ts
|
|
1510
1641
|
import { readFile as readFile11 } from "node:fs/promises";
|
|
1511
1642
|
import { join as join9 } from "node:path";
|
|
1512
|
-
|
|
1513
|
-
// packages/cli-core/src/config/runtime-policy.ts
|
|
1514
|
-
import { readFile as readFile10, realpath as realpath3 } from "node:fs/promises";
|
|
1515
|
-
import { createRequire as createRequire2 } from "node:module";
|
|
1516
|
-
import { resolve as resolve5 } from "node:path";
|
|
1517
|
-
|
|
1518
|
-
// packages/cli-core/src/config/runtime-update.ts
|
|
1519
|
-
import { readFile as readFile9 } from "node:fs/promises";
|
|
1520
|
-
import { join as join8 } from "node:path";
|
|
1521
|
-
async function projectRuntimeVersion(root) {
|
|
1522
|
-
try {
|
|
1523
|
-
return runtimeDependencyVersion(JSON.parse(await readFile9(join8(root, "package.json"), "utf8")));
|
|
1524
|
-
} catch (cause) {
|
|
1525
|
-
if (cause.code === "ENOENT") return void 0;
|
|
1526
|
-
throw cause;
|
|
1527
|
-
}
|
|
1528
|
-
}
|
|
1529
|
-
function compareVersions(left, right) {
|
|
1530
|
-
const parts = (value) => {
|
|
1531
|
-
const [core, ...suffix] = value.split("-");
|
|
1532
|
-
return { core: core.split(".").map(BigInt), pre: suffix.length ? suffix.join("-").split(".") : [] };
|
|
1533
|
-
};
|
|
1534
|
-
const a = parts(left), b = parts(right);
|
|
1535
|
-
for (let i = 0; i < 3; i++) if (a.core[i] !== b.core[i]) return a.core[i] < b.core[i] ? -1 : 1;
|
|
1536
|
-
if (!a.pre.length || !b.pre.length) return a.pre.length === b.pre.length ? 0 : a.pre.length ? -1 : 1;
|
|
1537
|
-
for (let i = 0; i < Math.max(a.pre.length, b.pre.length); i++) {
|
|
1538
|
-
const x = a.pre[i], y = b.pre[i];
|
|
1539
|
-
if (x === y) continue;
|
|
1540
|
-
if (x === void 0 || y === void 0) return x === void 0 ? -1 : 1;
|
|
1541
|
-
const nx = /^\d+$/.test(x), ny = /^\d+$/.test(y);
|
|
1542
|
-
if (nx && ny) return BigInt(x) < BigInt(y) ? -1 : 1;
|
|
1543
|
-
if (nx !== ny) return nx ? -1 : 1;
|
|
1544
|
-
return x < y ? -1 : 1;
|
|
1545
|
-
}
|
|
1546
|
-
return 0;
|
|
1547
|
-
}
|
|
1548
|
-
async function runtimeVersionStatus(project, latest) {
|
|
1549
|
-
const current = project ? await projectRuntimeVersion(project) : void 0;
|
|
1550
|
-
let versionStatus;
|
|
1551
|
-
if (!project) versionStatus = "no_project";
|
|
1552
|
-
else if (!current) versionStatus = "unconfigured";
|
|
1553
|
-
else if (current === latest) versionStatus = "current";
|
|
1554
|
-
else versionStatus = compareVersions(current, latest) < 0 ? "update_available" : "project_ahead";
|
|
1555
|
-
return {
|
|
1556
|
-
projectRuntimeVersion: current ?? null,
|
|
1557
|
-
latestRuntimeVersion: latest,
|
|
1558
|
-
versionStatus,
|
|
1559
|
-
adaptationRequired: versionStatus !== "no_project" && versionStatus !== "current"
|
|
1560
|
-
};
|
|
1561
|
-
}
|
|
1562
|
-
function reportRuntimeVersion(status, report) {
|
|
1563
|
-
if (status.versionStatus === "no_project") return;
|
|
1564
|
-
report(`Runtime \u7248\u672C\uFF1A\u5DE5\u7A0B ${status.projectRuntimeVersion ?? "\u672A\u9501\u5B9A\u51C6\u786E\u7248\u672C"}\uFF0Cnpm dev \u6700\u65B0 ${status.latestRuntimeVersion}\u3002`);
|
|
1565
|
-
if (status.adaptationRequired) {
|
|
1566
|
-
report("\u8BF7\u7531\u4F60\u6216\u5F00\u53D1 Agent \u66F4\u65B0\u4F9D\u8D56\u5E76\u9002\u914D\uFF1A\u68C0\u67E5\u65B0\u7248 Runtime \u7684\u542F\u52A8\u53C2\u6570\u3001\u6A21\u578B\u3001datasets\u3001\u5DE5\u5177\u53CA Hook\uFF0C\u5B8C\u6210\u9002\u914D\u540E\u9A8C\u8BC1 DEV\u3002CLI \u672A\u4FEE\u6539\u5DE5\u7A0B\u4F9D\u8D56\u6216\u914D\u7F6E\uFF1BDEV \u542F\u52A8\u3001\u81EA\u52A8\u91CD\u8F7D\u548C push \u5FC5\u987B\u901A\u8FC7\u6700\u65B0 Runtime \u68C0\u67E5\u3002");
|
|
1567
|
-
report(`\u5728\u5DE5\u7A0B\u6839\u76EE\u5F55\u6267\u884C\uFF1Anpm install --save-exact ${BUDDY_RUNTIME_PACKAGE}@${status.latestRuntimeVersion} --registry=${RUNTIME_REGISTRY} --@my-life-buddies:registry=${RUNTIME_REGISTRY}`);
|
|
1568
|
-
}
|
|
1569
|
-
}
|
|
1570
|
-
async function checkRuntimeUpdate(root, report, options = {}) {
|
|
1571
|
-
options.signal?.throwIfAborted();
|
|
1572
|
-
try {
|
|
1573
|
-
const latest = await latestRuntimeVersion(options);
|
|
1574
|
-
reportRuntimeVersion(await runtimeVersionStatus(root, latest), report);
|
|
1575
|
-
options.signal?.throwIfAborted();
|
|
1576
|
-
return;
|
|
1577
|
-
} catch (cause) {
|
|
1578
|
-
options.signal?.throwIfAborted();
|
|
1579
|
-
report(`\u65E0\u6CD5\u68C0\u67E5 Runtime \u66F4\u65B0\uFF1A${cause instanceof Error ? cause.message : String(cause)}\u3002\u672C\u6B21\u672A\u786E\u8BA4 npm dev \u6700\u65B0\u7248\u672C\uFF1B\u53EF\u7EE7\u7EED\u67E5\u770B\u6216\u4FEE\u6539\u5DE5\u7A0B\uFF0CDEV \u542F\u52A8\u548C push \u4F1A\u53E6\u884C\u4E25\u683C\u68C0\u67E5\u3002`);
|
|
1580
|
-
}
|
|
1581
|
-
}
|
|
1582
|
-
|
|
1583
|
-
// packages/cli-core/src/config/runtime-policy.ts
|
|
1584
|
-
var RuntimeRequirementError = class extends Error {
|
|
1585
|
-
constructor(code2, message, options) {
|
|
1586
|
-
super(message, options);
|
|
1587
|
-
this.code = code2;
|
|
1588
|
-
this.name = "RuntimeRequirementError";
|
|
1589
|
-
}
|
|
1590
|
-
code;
|
|
1591
|
-
};
|
|
1592
|
-
function assertRequiredRuntime(actual, expected) {
|
|
1593
|
-
if (actual === expected) return;
|
|
1594
|
-
throw new RuntimeRequirementError(
|
|
1595
|
-
"RUNTIME_VERSION_MISMATCH",
|
|
1596
|
-
`\u5DF2\u963B\u6B62\u8FD0\u884C\u6216\u4E0A\u4F20\uFF1A\u5DE5\u7A0B Runtime ${actual ?? "\u672A\u9501\u5B9A\u51C6\u786E\u7248\u672C"}\uFF0Cnpm dev \u6700\u65B0\u7248\u672C ${expected}\u3002\u5FC5\u987B\u4F7F\u7528\u5B8C\u5168\u4E00\u81F4\u7684\u7248\u672C\u3002
|
|
1597
|
-
\u8BF7\u7531\u4F60\u6216\u5F00\u53D1 Agent \u66F4\u65B0\u4F9D\u8D56\u548C\u9501\u6587\u4EF6\uFF0C\u9002\u914D\u542F\u52A8\u53C2\u6570\u3001\u6A21\u578B\u3001datasets\u3001\u5DE5\u5177\u53CA Hook \u540E\u91CD\u8BD5\u3002
|
|
1598
|
-
npm install --save-exact ${BUDDY_RUNTIME_PACKAGE}@${expected} --registry=${RUNTIME_REGISTRY} --@my-life-buddies:registry=${RUNTIME_REGISTRY}`
|
|
1599
|
-
);
|
|
1600
|
-
}
|
|
1601
|
-
function assertNpmRuntimeLock(contents, expected) {
|
|
1602
|
-
const lock = JSON.parse(contents);
|
|
1603
|
-
const installed2 = lock.lockfileVersion === 1 ? lock.dependencies?.[BUDDY_RUNTIME_PACKAGE] : lock.packages?.[`node_modules/${BUDDY_RUNTIME_PACKAGE}`];
|
|
1604
|
-
if (installed2?.version !== expected || lock.lockfileVersion !== 1 && runtimeDependencyVersion(lock.packages?.[""]) !== expected) {
|
|
1605
|
-
throw new RuntimeRequirementError("RUNTIME_DEPENDENCY_INVALID", `package-lock.json \u7684 Runtime \u4E0E\u8981\u6C42\u7684 ${expected} \u4E0D\u4E00\u81F4\u3002\u8BF7\u66F4\u65B0\u9501\u6587\u4EF6\u5E76\u91CD\u65B0\u5B89\u88C5\u4F9D\u8D56\u540E\u91CD\u8BD5\u3002`);
|
|
1606
|
-
}
|
|
1607
|
-
}
|
|
1608
|
-
async function requireProjectRuntime(root, options = {}) {
|
|
1609
|
-
const declared = await projectRuntimeVersion(root);
|
|
1610
|
-
if (!declared) throw new RuntimeRequirementError("RUNTIME_DEPENDENCY_INVALID", "\u5DE5\u7A0B\u5FC5\u987B\u5728 package.json \u58F0\u660E npm dev \u6700\u65B0 Runtime \u7684\u51C6\u786E\u7248\u672C\uFF0C\u5E76\u5B89\u88C5\u4F9D\u8D56\u548C\u9501\u6587\u4EF6\uFF1B\u4E0D\u80FD\u4F7F\u7528 dev\u3001latest \u6216\u7248\u672C\u8303\u56F4\u4F5C\u4E3A\u5DE5\u7A0B\u4F9D\u8D56\u3002");
|
|
1611
|
-
let expected;
|
|
1612
|
-
try {
|
|
1613
|
-
expected = await latestRuntimeVersion(options);
|
|
1614
|
-
} catch (cause) {
|
|
1615
|
-
options.signal?.throwIfAborted();
|
|
1616
|
-
throw new RuntimeRequirementError("RUNTIME_CHECK_FAILED", `\u65E0\u6CD5\u786E\u8BA4 npm dev \u6700\u65B0 Runtime\uFF0C\u5DF2\u963B\u6B62\u8FD0\u884C\u6216\u4E0A\u4F20\uFF1A${cause instanceof Error ? cause.message : String(cause)}\u3002\u8BF7\u6062\u590D\u8FDE\u63A5\u540E\u91CD\u8BD5\u3002`, { cause });
|
|
1617
|
-
}
|
|
1618
|
-
try {
|
|
1619
|
-
assertRequiredRuntime(await projectRuntimeVersion(root), expected);
|
|
1620
|
-
const installedPath = await realpath3(resolve5(root, "node_modules", BUDDY_RUNTIME_PACKAGE, "package.json"));
|
|
1621
|
-
const fromProject = createRequire2(resolve5(root, "package.json")).resolve(`${BUDDY_RUNTIME_PACKAGE}/package.json`);
|
|
1622
|
-
if (await realpath3(fromProject) !== installedPath) throw new Error("Runtime \u5FC5\u987B\u5B89\u88C5\u5728\u5F53\u524D\u5DE5\u7A0B\u4E2D");
|
|
1623
|
-
const installed2 = JSON.parse(await readFile10(installedPath, "utf8"));
|
|
1624
|
-
if (installed2.version !== expected) throw new Error(`Runtime \u5B9E\u9645\u5B89\u88C5 ${installed2.version}\uFF0C\u8981\u6C42 ${expected}`);
|
|
1625
|
-
let lock;
|
|
1626
|
-
try {
|
|
1627
|
-
lock = await readFile10(resolve5(root, "package-lock.json"), "utf8");
|
|
1628
|
-
} catch (cause) {
|
|
1629
|
-
if (cause.code !== "ENOENT") throw cause;
|
|
1630
|
-
}
|
|
1631
|
-
if (lock !== void 0) assertNpmRuntimeLock(lock, expected);
|
|
1632
|
-
options.signal?.throwIfAborted();
|
|
1633
|
-
return expected;
|
|
1634
|
-
} catch (cause) {
|
|
1635
|
-
options.signal?.throwIfAborted();
|
|
1636
|
-
if (cause instanceof RuntimeRequirementError) throw cause;
|
|
1637
|
-
throw new RuntimeRequirementError("RUNTIME_DEPENDENCY_INVALID", `Runtime \u4F9D\u8D56\u6821\u9A8C\u5931\u8D25\uFF1A${cause instanceof Error ? cause.message : String(cause)}\u3002\u8BF7\u66F4\u65B0\u4F9D\u8D56\u53CA\u9501\u6587\u4EF6\u5E76\u5B89\u88C5\uFF1Bnpm \u5DE5\u7A0B\u53EF\u8FD0\u884C npm ci\u3002`, { cause });
|
|
1638
|
-
}
|
|
1639
|
-
}
|
|
1640
|
-
|
|
1641
|
-
// packages/cli-core/src/init/runtime-version.ts
|
|
1642
1643
|
async function resolveInitRuntime(root, options = {}) {
|
|
1643
1644
|
let latest;
|
|
1644
1645
|
try {
|