@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 CHANGED
@@ -2,13 +2,13 @@
2
2
 
3
3
  这份说明按一次开发过程展开:登记搭子,准备工程,在本地预览,然后上传程序包。所有搭子统一使用 `@my-life-buddies/buddy-runtime`,业务能力通过 Prompt、`src/buddy-options.mjs` 和 Tool 实现。
4
4
 
5
- 工程模板已锁定公共 npm 的 Runtime `0.11.0`,本批接口变化与联调范围见 [Runtime 集成说明](../../docs/runtime-integration.md)。
5
+ 工程模板已锁定公共 npm 的 Runtime `0.12.0`,本批接口变化与联调范围见 [Runtime 集成说明](../../docs/runtime-integration.md)。
6
6
 
7
7
  ## 准备 CLI 和平台地址
8
8
 
9
9
  目前只支持 macOS,要求 Node.js 24 或更新版本。
10
10
 
11
- 当前 CLI 工程版本为 `0.5.0`,发布到公共 Registry `https://registry.npmjs.org/`。已有仓库源码时,在仓库根目录运行:
11
+ 当前 CLI 工程版本为 `0.8.0`,发布目标为公共 Registry `https://registry.npmjs.org/`。已有仓库源码时,在仓库根目录运行:
12
12
 
13
13
  ```bash
14
14
  npm install
@@ -21,6 +21,28 @@ npm run buddy-cli -- --help
21
21
  npm install --global @my-life-buddies/cli@latest --registry=https://registry.npmjs.org/
22
22
  ```
23
23
 
24
+ ### 查看版本和更新 CLI
25
+
26
+ ```bash
27
+ buddy-cli --version
28
+ buddy-cli update --check
29
+ buddy-cli update
30
+ ```
31
+
32
+ `--version`(也可写作 `-v`)显示当前运行的 CLI 版本,无需联网。`update --check` 查询公共 npm 的 `latest` 版本,只检查、不安装;`update` 有新版本时安装检查到的准确版本,完成后核验安装结果。版本相同或本机版本更高时不安装、不降级。这三个用法均无需登录搭搭账号或进入搭子工程,从 CLI 0.8.0 开始支持。旧版用户先用上面的 npm 命令升级。
33
+
34
+ 自动更新支持 npm 全局安装。源码、`npm link`、局部安装和 `npx` 请沿用原来的安装方式更新;使用 nvm 时先切换到安装该 CLI 的 Node.js 环境。更新只针对 CLI,已有工程的 Runtime 依赖和锁文件需要另行修改与验证。
35
+
36
+ 可追加 `--json` 供 Coding Agent 或脚本读取,例如:
37
+
38
+ ```bash
39
+ buddy-cli update --check --json
40
+ ```
41
+
42
+ 检查结果包含 `package`、`currentVersion`、`latestVersion`、`updateAvailable` 和 `status`。`status` 为 `update_available`、`up_to_date` 或 `ahead`;更新成功时为 `updated`,另有 `installedVersion`,`updateAvailable` 为 `false`。失败时输出 `error`。检查成功(包括发现更新)返回退出码 0,查询或安装失败返回 1,参数错误返回 2。JSON 输出不会混入 npm 进度文字。
43
+
44
+ ### 发布与平台地址
45
+
24
46
  维护者需先登录公共 npm,拥有 `@my-life-buddies` scope 的发布权限,并完成 npm 要求的两步验证(2FA)。在仓库根目录完成验证,只发布 CLI:
25
47
 
26
48
  ```bash
@@ -50,11 +72,14 @@ CLI 会把换取到的会话保存到 macOS Keychain。有效会话会复用,
50
72
  | 命令 | 是否需要 Agent 目录 | 会发生什么 |
51
73
  | --- | --- | --- |
52
74
  | `help`、`--help` | 不需要,也不登录 | 显示参数说明 |
75
+ | `--version [--json]` | 不需要,也不登录 | 显示当前运行的 CLI 版本,无需联网 |
76
+ | `update [--check] [--json]` | 不需要,也不登录 | 检查公共 npm 最新版,或更新 npm 全局 CLI |
53
77
  | `login`、`logout` | 不需要 | 管理账号会话 |
54
78
  | `models [--json]` | 不需要,也不登录 | 离线读取 CLI 内置模型目录 |
55
79
  | `init` | 目标目录可以是空目录或已有官方工程 | 登记或恢复云端身份,准备本地文件 |
56
80
  | `dev`、`preview`、`push` | 需要有效清单和完整工程文件 | 运行、调试或打包该工程 |
57
81
  | `status` | 需要含 `buddyId` 的 `buddy.agent.json` | 查询该搭子的云端状态;创作尚未完成时也可使用 |
82
+ | `avatar` | 从工程读取身份,或用 `--buddy-id` 指定 | 上传本地图片或清除搭子头像,保留其他资料;无需 Runtime |
58
83
  | `datasets` | 需要工程和安装好的 Runtime,无需登录 | 读取 Runtime 的全部数据集;支持 `--directory`、`--json` |
59
84
 
60
85
  项目命令可从工程子目录向上定位配置,也可用 `--directory` 指定工程。普通目录不会被悄悄初始化;已有官方工程可用 `init --mode direct` 补齐缺失的模板文件,已有文件不会被覆盖。
@@ -134,7 +159,22 @@ widgets/
134
159
 
135
160
  CLI 将 HTML 和 Schema 随工程源码打包。工程安装的 Runtime 在 BuddyServer 启动时读取 `widgets/`,通过 `PUT /internal/v1/widget-types/:typeId` 一起上传 Schema 与 HTML;全部成功后才连接事件流。缺文件、无效 JSON 或平台拒绝上传会使启动失败,具体原因可在终端或 Preview 日志中查看。平台需要已部署该接口。
136
161
 
137
- 模型使用小挂件工具时,在 `src/buddy-options.mjs` 的 `initialState.tools` 中加入 `conversation.tools.widget_create`、`conversation.tools.widget_write` 等工具;业务代码也可直接调用 `conversation.widget`,主动服务回合禁止写操作。类型按上传进程的 Buddy 身份保存,DEV 分身与正式版隔离。修改文件后重启 Runtime;删除或改名目录不会删除平台上的旧类型。Preview 可展示小挂件卡片、会话列表与 H5 页面。
162
+ 模型使用小挂件工具时,在 `src/buddy-options.mjs` 的 `initialState.tools` 中加入 `conversation.tools.widget_create`、`conversation.tools.widget_write_record` 等工具;业务代码也可直接调用 `conversation.widget`,主动服务回合禁止写操作。类型按上传进程的 Buddy 身份保存,DEV 分身与正式版隔离。修改文件后重启 Runtime;删除或改名目录不会删除平台上的旧类型。Preview 可展示小挂件卡片、会话列表与 H5 页面。
163
+
164
+ Runtime 0.12.0 的小挂件工具按操作区分:
165
+
166
+ | 操作 | `conversation.tools` 工具 | 业务代码 API |
167
+ | --- | --- | --- |
168
+ | 创建 | `widget_create` | `conversation.widget.create(...)` |
169
+ | 读取整个小挂件 | `widget_read` | `conversation.widget.read(id)` |
170
+ | 读取一个模块 | `widget_read_module` | `conversation.widget.readModule(id, module)` |
171
+ | 修改标题 | `widget_rename` | `conversation.widget.rename(id, title)` |
172
+ | 写入或覆盖一条记录 | `widget_write_record` | `conversation.widget.writeRecord(id, input)` |
173
+ | 删除一条记录 | `widget_delete_record` | `conversation.widget.deleteRecord(id, module, recordId)` |
174
+ | 删除整个小挂件及其记录 | `widget_delete` | `conversation.widget.delete(id)` |
175
+ | 发送到聊天 | `widget_send` | `conversation.widget.send(id)` |
176
+
177
+ `widget_read`、`widget_delete` 只接收 `widgetId`;模块读取和单条记录删除使用各自的工具。只向模型注册业务需要的工具。
138
178
 
139
179
  先改 `agent.md`,决定这个搭子怎么与用户交流:
140
180
 
@@ -161,7 +201,7 @@ await BuddyServer.start({
161
201
  });
162
202
  ```
163
203
 
164
- 工程在 `package.json` 声明准确 Runtime 版本,锁文件固定依赖;上传不包含 `node_modules` 或 Runtime 打包副本,部署执行同一份 `npm start`。模板及锁文件使用 Runtime `0.11.0`,安装验收直接从公共 npm 安装,不替换依赖。
204
+ 工程在 `package.json` 声明准确 Runtime 版本,锁文件固定依赖;上传不包含 `node_modules` 或 Runtime 打包副本,部署执行同一份 `npm start`。模板及锁文件使用 Runtime `0.12.0`,安装验收直接从公共 npm 安装,不替换依赖。
165
205
 
166
206
  ## 想法还模糊时,先梳理需求
167
207
 
@@ -216,6 +256,27 @@ Creator 例外保留首次创作背景快照,用于接续同一作品;恢复
216
256
 
217
257
  这些规则通过 CLI 帮助、命令输出和 Creator 的 `HANDOFF.md` 交给 Coding Agent;CLI 不会在 `init` 内自动执行采访、编写业务代码或批量调用模型。重试创作时复用当前接续说明和作品,不覆盖开发者修改的文件。已有完整工程无需重新初始化,可从更新后的 CLI 帮助和 `preview` 输出读取交接规则。
218
258
 
259
+ ## 修改搭子的头像
260
+
261
+ 在搭子工程中上传本地生成或选择的图片:
262
+
263
+ ```bash
264
+ buddy-cli avatar --file ./avatar.png
265
+ buddy-cli avatar --clear
266
+ ```
267
+
268
+ `--file` 与 `--clear` 二选一。支持静态 PNG、JPEG、WebP,最大 5 MiB。Server 校验图片并裁剪成 512 × 512 WebP,生成头像地址;CLI 不再提供 `--url`。服务端处理失败时保留原头像。
269
+
270
+ 命令默认向上寻找 `buddy.agent.json`,可用 `--directory ./my-buddy` 指定工程;图片路径始终相对执行命令的当前目录。创作阶段只有身份清单时也能使用,无需安装 Runtime。工程外可直接指定平台 ID:
271
+
272
+ ```bash
273
+ buddy-cli avatar --buddy-id b_example --file ./avatar.png
274
+ ```
275
+
276
+ `--buddy-id` 和 `--directory` 不能同时使用。命令复用 CLI 登录态,由 Server 校验搭子归属;通过 `PUT /cli/buddies/:id/meta` 提交 multipart 图片,服务端保留其他资料。清除时 JSON 提交 `avatar: null`。云端头像立即保存,不写入本地工程配置,无需 `push`。`buddy-cli status` 可查看头像地址。
277
+
278
+ 头像固定保存为 `avatar-<buddyId>.webp`,更换时覆盖文件;返回地址带内容摘要查询参数,让客户端重新加载图片。此版本需要部署支持 multipart 头像的新 MLB Server。
279
+
219
280
  ## 为这个搭子选一个模型
220
281
 
221
282
  ```bash
@@ -255,7 +316,7 @@ CLI 本地列出 `kimi-k2.6`、`kimi-k3`、`deepseek-v4-flash`、`deepseek-v4-pr
255
316
  }
256
317
  ```
257
318
 
258
- 完整选项以工程目录运行 `buddy-cli datasets` 的输出为准;脚本可加 `--json`。目录由安装的 Runtime 提供,Runtime 0.11.0 包含 HealthKit 与小红书两类,共 10 项。
319
+ 完整选项以工程目录运行 `buddy-cli datasets` 的输出为准;脚本可加 `--json`。目录由安装的 Runtime 提供,Runtime 0.12.0 包含 HealthKit 与小红书两类,共 10 项。
259
320
 
260
321
  CLI 校验声明,并把清单原样放入源码包。服务端从包中解析申请清单、绑定版本,以及 App 展示和取得用户授权的流程仍需接入;当前 CLI 不会额外调用接口修改平台权限。工程中的声明不代表用户已经授权,也不会自动启用查询工具。
261
322
 
@@ -366,6 +427,6 @@ buddy-cli datasets --directory ./my-buddy --json
366
427
 
367
428
  目录直接来自当前工程 Runtime 的 `DATA_ACCESS_CAPABILITIES`,包括 ID、名称、来源和 Schema 版本。普通输出供开发者阅读,JSON 返回 `runtimeVersion` 和 `datasets` 数组供脚本处理。命令不登录、不启动搭子、不申请权限,也不修改配置;从子目录运行会向上找到工程。
368
429
 
369
- 开发者将实际选择的 ID 和用途写进 `buddy.agent.json.datasets`。JSON Schema 检查形状与用途;DEV 和非空数据声明的上传预检按工程安装的 Runtime 检查 ID。目录缺失、依赖未安装或版本不匹配时明确报错。Runtime 0.11.0 有 10 项,但单次数据查询仍最多 8 项。
430
+ 开发者将实际选择的 ID 和用途写进 `buddy.agent.json.datasets`。JSON Schema 检查形状与用途;DEV 和非空数据声明的上传预检按工程安装的 Runtime 检查 ID。目录缺失、依赖未安装或版本不匹配时明确报错。Runtime 0.12.0 有 10 项,但单次数据查询仍最多 8 项。
370
431
 
371
432
  Preview 文本发送采用 App WebSocket 的 `messages` 数组,并校验逐项回执。`ask_question` 的全部选项以文字显示,开发者直接回复选择;权限卡提示到搭搭 App 处理,浏览器不模拟系统授权。
package/dist/bin/buddy.js CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  // apps/cli/src/bin/buddy.ts
4
4
  import { stdin, stderr, stdout } from "node:process";
5
+ import { createRequire } from "node:module";
6
+ import { dirname } from "node:path";
5
7
  import { createInterface } from "node:readline/promises";
6
8
  import {
7
9
  PromptCancelledError,
@@ -350,6 +352,170 @@ function assertSupportedDeveloperPlatform(platform = process.platform) {
350
352
  if (platform !== "darwin") throw new UnsupportedDeveloperPlatformError(platform);
351
353
  }
352
354
 
355
+ // apps/cli/src/self-update.ts
356
+ import { execFile } from "node:child_process";
357
+ import { lstat, readFile, realpath } from "node:fs/promises";
358
+ import { homedir } from "node:os";
359
+ import { isAbsolute, join } from "node:path";
360
+ import { promisify } from "node:util";
361
+ var PACKAGE = "@my-life-buddies/cli";
362
+ var REGISTRY = "https://registry.npmjs.org/";
363
+ var MANUAL_UPDATE = `npm install --global ${PACKAGE}@latest --registry=${REGISTRY}`;
364
+ var execute = promisify(execFile);
365
+ var HELP = `\u7528\u6CD5:
366
+ buddy-cli --version [--json]
367
+ buddy-cli update --check [--json]
368
+ buddy-cli update [--json]
369
+
370
+ --version \u67E5\u770B\u5F53\u524D\u8FD0\u884C\u7684 CLI \u7248\u672C\uFF08\u65E0\u9700\u8054\u7F51\uFF09
371
+ --check \u68C0\u67E5\u516C\u5171 npm \u7684 latest \u7248\u672C\uFF0C\u4E0D\u5B89\u88C5
372
+ --json \u8F93\u51FA JSON\uFF0C\u4F9B Coding Agent \u6216\u811A\u672C\u8BFB\u53D6
373
+
374
+ \u65E0\u9700\u767B\u5F55\u642D\u642D\u8D26\u53F7\uFF0C\u4E5F\u65E0\u9700\u8FDB\u5165\u642D\u5B50\u5DE5\u7A0B\u3002
375
+ update \u66F4\u65B0\u5F53\u524D npm \u5168\u5C40\u5B89\u88C5\u7684 CLI\uFF0C\u4E0D\u4FEE\u6539\u642D\u5B50\u5DE5\u7A0B\u7684 Runtime \u4F9D\u8D56\u3002
376
+ \u5DF2\u7ECF\u662F\u6700\u65B0\u7248\u6216\u5F53\u524D\u7248\u672C\u66F4\u9AD8\u65F6\u4E0D\u5B89\u88C5\u3001\u4E0D\u964D\u7EA7\u3002
377
+ \u6E90\u7801\u3001npm link\u3001\u5C40\u90E8\u5B89\u88C5\u6216 npx \u8FD0\u884C\u65F6\uFF0C\u8BF7\u4F7F\u7528\u539F\u6765\u7684\u5B89\u88C5\u65B9\u5F0F\u66F4\u65B0\u3002
378
+ \u65E7\u7248 CLI \u5C1A\u65E0 update \u547D\u4EE4\u65F6\uFF0C\u8FD0\u884C\uFF1A
379
+ ${MANUAL_UPDATE}`;
380
+ function parseVersion(version) {
381
+ const numeric = "(?:0|[1-9][0-9]*)";
382
+ const identifier = `(?:${numeric}|[0-9]*[A-Za-z-][0-9A-Za-z-]*)`;
383
+ const pattern = new RegExp(`^(${numeric})\\.(${numeric})\\.(${numeric})(?:-(${identifier}(?:\\.${identifier})*))?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$`, "u");
384
+ const match = typeof version === "string" && version.length <= 256 ? pattern.exec(version) : null;
385
+ if (!match || match[0] !== version) throw new Error("\u7248\u672C\u4FE1\u606F\u4E0D\u662F\u6709\u6548\u7684 SemVer \u7248\u672C\u53F7\u3002");
386
+ return [match[1], match[2], match[3], ...match[4]?.split(".") ?? []];
387
+ }
388
+ function compareVersions(left, right) {
389
+ const a = parseVersion(left);
390
+ const b = parseVersion(right);
391
+ for (let i = 0; i < 3; i++) {
392
+ if (BigInt(a[i]) !== BigInt(b[i])) return BigInt(a[i]) > BigInt(b[i]) ? 1 : -1;
393
+ }
394
+ if (a.length === 3 || b.length === 3) return a.length === b.length ? 0 : a.length === 3 ? 1 : -1;
395
+ for (let i = 3; i < Math.max(a.length, b.length); i++) {
396
+ const x = a[i];
397
+ const y = b[i];
398
+ if (x === y) continue;
399
+ if (x === void 0 || y === void 0) return x === void 0 ? -1 : 1;
400
+ const xn = /^[0-9]+$/u.test(x);
401
+ const yn = /^[0-9]+$/u.test(y);
402
+ if (xn && yn) return BigInt(x) > BigInt(y) ? 1 : -1;
403
+ if (xn !== yn) return xn ? -1 : 1;
404
+ return x > y ? 1 : -1;
405
+ }
406
+ return 0;
407
+ }
408
+ async function latestVersion(options) {
409
+ const timeout = AbortSignal.timeout(1e4);
410
+ const signal = options.signal ? AbortSignal.any([options.signal, timeout]) : timeout;
411
+ try {
412
+ const response = await (options.fetch ?? globalThis.fetch)(`${REGISTRY}${encodeURIComponent(PACKAGE)}/latest`, {
413
+ signal,
414
+ headers: { Accept: "application/json" },
415
+ redirect: "error"
416
+ });
417
+ if (!response.ok) throw new Error(`npm \u8FD4\u56DE HTTP ${response.status}`);
418
+ const metadata = await response.json();
419
+ if (metadata?.name !== PACKAGE) throw new Error("npm \u8FD4\u56DE\u7684\u5305\u540D\u4E0D\u5339\u914D");
420
+ parseVersion(metadata.version);
421
+ return metadata.version;
422
+ } catch (cause) {
423
+ if (options.signal?.aborted) throw new Error("\u64CD\u4F5C\u5DF2\u53D6\u6D88\u3002");
424
+ if (timeout.aborted) throw new Error("\u68C0\u67E5\u66F4\u65B0\u8D85\u65F6\uFF0C\u8BF7\u68C0\u67E5\u7F51\u7EDC\u540E\u91CD\u8BD5\u3002");
425
+ throw new Error(`\u65E0\u6CD5\u68C0\u67E5 npm \u66F4\u65B0\uFF1A${cause instanceof Error ? cause.message : String(cause)}\u3002\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002`);
426
+ }
427
+ }
428
+ async function installUpdate(version, options) {
429
+ const runNpm = options.runNpm ?? ((args, settings2) => execute("npm", args, { ...settings2, encoding: "utf8", maxBuffer: 4 * 1024 * 1024 }));
430
+ const settings = { cwd: homedir(), signal: options.signal, timeout: 1e4 };
431
+ const { stdout: stdout2 } = await runNpm(["prefix", "--global"], settings);
432
+ const prefix = stdout2.trim();
433
+ if (!isAbsolute(prefix) || /[\r\n]/u.test(prefix)) throw new Error("\u65E0\u6CD5\u786E\u5B9A npm \u5168\u5C40\u5B89\u88C5\u76EE\u5F55\u3002");
434
+ const installedRoot = join(prefix, "lib", "node_modules", PACKAGE);
435
+ let sameInstallation = false;
436
+ try {
437
+ sameInstallation = !(await lstat(installedRoot)).isSymbolicLink() && await realpath(installedRoot) === await realpath(options.packageRoot);
438
+ } catch {
439
+ }
440
+ if (!sameInstallation) {
441
+ throw new Error("\u5F53\u524D CLI \u4E0D\u662F\u8FD9\u4E2A npm \u73AF\u5883\u7684\u5168\u5C40\u5B89\u88C5\uFF0C\u4E0D\u80FD\u76F4\u63A5\u66F4\u65B0\u3002\u8BF7\u7528\u539F\u6765\u7684\u5B89\u88C5\u65B9\u5F0F\u66F4\u65B0\uFF1B\u82E5\u4F7F\u7528 nvm\uFF0C\u8BF7\u5148\u5207\u6362\u5230\u5B89\u88C5\u8BE5 CLI \u7684 Node.js \u73AF\u5883\u3002");
442
+ }
443
+ try {
444
+ await runNpm([
445
+ "install",
446
+ "--global",
447
+ `${PACKAGE}@${version}`,
448
+ "--prefix",
449
+ prefix,
450
+ `--registry=${REGISTRY}`,
451
+ `--@my-life-buddies:registry=${REGISTRY}`,
452
+ "--engine-strict",
453
+ "--no-audit",
454
+ "--no-fund"
455
+ ], { ...settings, timeout: 18e4 });
456
+ } catch (cause) {
457
+ if (options.signal?.aborted) throw new Error("\u66F4\u65B0\u5DF2\u53D6\u6D88\uFF0C\u8BF7\u8FD0\u884C buddy-cli --version \u68C0\u67E5\u5B89\u88C5\u72B6\u6001\u3002");
458
+ const code = cause && typeof cause === "object" && "code" in cause ? String(cause.code) : "unknown";
459
+ throw new Error(`npm \u5B89\u88C5\u672A\u5B8C\u6210\uFF08${code}\uFF09\u3002\u8BF7\u68C0\u67E5\u7F51\u7EDC\u548C\u5168\u5C40\u76EE\u5F55\u6743\u9650\uFF0C\u7136\u540E\u91CD\u8BD5\uFF1A${MANUAL_UPDATE}`);
460
+ }
461
+ const installed = JSON.parse(await readFile(join(installedRoot, "package.json"), "utf8"));
462
+ if (installed.name !== PACKAGE || installed.version !== version) {
463
+ throw new Error(`npm \u5DF2\u7ED3\u675F\uFF0C\u4F46\u672A\u786E\u8BA4\u5B89\u88C5\u5230 ${version}\u3002\u8BF7\u8FD0\u884C buddy-cli --version \u68C0\u67E5\uFF0C\u5FC5\u8981\u65F6\u91CD\u8BD5\uFF1A${MANUAL_UPDATE}`);
464
+ }
465
+ }
466
+ async function runSelfUpdateCommand(args, io, options) {
467
+ const versionOnly = args[0] === "--version" || args[0] === "-v";
468
+ if (!versionOnly && args[0] !== "update") return void 0;
469
+ const json = args.includes("--json");
470
+ const fail = (message, exitCode) => {
471
+ if (json) io.write(JSON.stringify({ package: PACKAGE, currentVersion: options.version, error: message }));
472
+ else io.writeError(`buddy-cli: ${message}`);
473
+ return { exitCode };
474
+ };
475
+ const flags = args.slice(1);
476
+ const allowed = versionOnly ? ["--json", "--help", "-h"] : ["--check", "--json", "--help", "-h"];
477
+ if (flags.some((flag) => !allowed.includes(flag)) || new Set(flags).size !== flags.length) {
478
+ return fail("\u53C2\u6570\u65E0\u6548\uFF0C\u8BF7\u8FD0\u884C buddy-cli update --help \u67E5\u770B\u7528\u6CD5\u3002", 2);
479
+ }
480
+ if (flags.includes("--help") || flags.includes("-h")) {
481
+ if (json) io.write(JSON.stringify({ help: HELP }));
482
+ else io.write(HELP);
483
+ return { exitCode: 0 };
484
+ }
485
+ try {
486
+ parseVersion(options.version);
487
+ if (versionOnly) {
488
+ io.write(json ? JSON.stringify({ package: PACKAGE, version: options.version }) : options.version);
489
+ return { exitCode: 0 };
490
+ }
491
+ const latest = await latestVersion(options);
492
+ const comparison = compareVersions(latest, options.version);
493
+ const check = flags.includes("--check");
494
+ const status = comparison > 0 ? "update_available" : comparison < 0 ? "ahead" : "up_to_date";
495
+ if (!check && comparison > 0) {
496
+ if (!json) io.write(`\u6B63\u5728\u66F4\u65B0 CLI\uFF1A${options.version} \u2192 ${latest}\u2026`);
497
+ await installUpdate(latest, options);
498
+ }
499
+ const updated = !check && comparison > 0;
500
+ if (json) {
501
+ io.write(JSON.stringify({
502
+ package: PACKAGE,
503
+ currentVersion: options.version,
504
+ latestVersion: latest,
505
+ updateAvailable: comparison > 0 && !updated,
506
+ status: updated ? "updated" : status,
507
+ ...updated ? { installedVersion: latest } : {}
508
+ }));
509
+ } else if (updated) io.write(`CLI \u5DF2\u66F4\u65B0\uFF1A${options.version} \u2192 ${latest}\u3002`);
510
+ else if (comparison > 0) io.write(`\u53D1\u73B0\u65B0\u7248\u672C\uFF1A${options.version} \u2192 ${latest}\u3002\u8FD0\u884C buddy-cli update \u66F4\u65B0\u3002`);
511
+ else if (comparison < 0) io.write(`\u5F53\u524D\u7248\u672C ${options.version} \u9AD8\u4E8E npm latest ${latest}\uFF0C\u65E0\u9700\u66F4\u65B0\u3002`);
512
+ else io.write(`\u5F53\u524D\u5DF2\u662F\u6700\u65B0\u7248\uFF1A${options.version}\u3002`);
513
+ return { exitCode: 0 };
514
+ } catch (cause) {
515
+ return fail(cause instanceof Error ? cause.message : String(cause), 1);
516
+ }
517
+ }
518
+
353
519
  // apps/cli/src/bin/buddy.ts
354
520
  var TerminalIO = class {
355
521
  canPrompt = Boolean(stdin.isTTY && stdout.isTTY);
@@ -424,10 +590,17 @@ process.on("SIGTERM", onSigterm);
424
590
  try {
425
591
  assertSupportedDeveloperPlatform();
426
592
  const args = process.argv.slice(2);
593
+ const require2 = createRequire(import.meta.url);
594
+ const manifestPath = require2.resolve("@my-life-buddies/cli/package.json");
595
+ const maintenance = await runSelfUpdateCommand(args, terminal, {
596
+ version: require2(manifestPath).version,
597
+ packageRoot: dirname(manifestPath),
598
+ signal: lifecycle.signal
599
+ });
427
600
  const command = args[0];
428
601
  let platformHost;
429
602
  const host = () => platformHost ??= new BuddyPlatformHost({ signal: lifecycle.signal });
430
- const result = await runBuddyCli(args, terminal, {
603
+ const result = maintenance ?? await runBuddyCli(args, terminal, {
431
604
  ...command === "dev" ? { dev: host().devOptions() } : {},
432
605
  // Resolve credentials only when a supported command actually needs them.
433
606
  get cloud() {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../src/bin/buddy.ts", "../../src/platform-host.ts", "../../src/runtime-logs.ts", "../../src/platform-support.ts"],
4
- "sourcesContent": ["#!/usr/bin/env node\n\nimport { stdin, stderr, stdout } from \"node:process\";\nimport { createInterface, type Interface } from \"node:readline/promises\";\nimport {\n PromptCancelledError,\n runBuddyCli,\n type Choice,\n type CliIO,\n type InputOptions,\n type SelectOptions,\n} from \"@buddy/cli-core\";\nimport { BuddyPlatformHost } from \"../platform-host.js\";\nimport { assertSupportedDeveloperPlatform } from \"../platform-support.js\";\n\nclass TerminalIO implements CliIO {\n readonly canPrompt = Boolean(stdin.isTTY && stdout.isTTY);\n private readline: Interface | undefined;\n private activeQuestion: AbortController | undefined;\n private cancelled = false;\n\n write(message: string): void {\n stdout.write(`${message}\\n`);\n }\n\n writeError(message: string): void {\n stderr.write(`${message}\\n`);\n }\n\n async select<Value extends string>(\n question: string,\n choices: readonly Choice<Value>[],\n options: SelectOptions<Value> = {},\n ): Promise<Value> {\n while (true) {\n this.write(`\\n${question}`);\n choices.forEach((choice, index) => {\n this.write(` ${index + 1}. ${choice.label}`);\n if (choice.description) this.write(` ${choice.description}`);\n });\n\n const defaultIndex = options.defaultValue === undefined\n ? undefined\n : choices.findIndex((choice) => choice.value === options.defaultValue);\n const prompt = defaultIndex === undefined || defaultIndex < 0\n ? \"\u8BF7\u8F93\u5165\u5E8F\u53F7\uFF1A\"\n : `\u8BF7\u8F93\u5165\u5E8F\u53F7\uFF08\u9ED8\u8BA4\uFF1A${defaultIndex + 1}\uFF09\uFF1A`;\n const answer = (await this.question(prompt)).trim();\n if (!answer && defaultIndex !== undefined && defaultIndex >= 0) return choices[defaultIndex]!.value;\n const selected = Number(answer) - 1;\n const choice = choices[selected];\n if (choice) return choice.value;\n this.writeError(`\u8BF7\u8F93\u5165 1 \u5230 ${choices.length} \u4E4B\u95F4\u7684\u5E8F\u53F7\u3002`);\n }\n }\n\n async input(question: string, options: InputOptions = {}): Promise<string> {\n const defaultHint = options.defaultValue === undefined ? \"\" : `\uFF08\u9ED8\u8BA4\uFF1A${options.defaultValue}\uFF09`;\n const answer = (await this.question(`${question}${defaultHint}\uFF1A`)).trim();\n return answer || options.defaultValue || \"\";\n }\n\n close(): void {\n this.readline?.close();\n }\n\n private getReadline(): Interface {\n if (this.readline) return this.readline;\n this.readline = createInterface({ input: stdin, output: stdout });\n this.readline.on(\"SIGINT\", () => {\n this.cancelled = true;\n this.activeQuestion?.abort();\n });\n return this.readline;\n }\n\n private async question(prompt: string): Promise<string> {\n const controller = new AbortController();\n this.activeQuestion = controller;\n try {\n return await this.getReadline().question(prompt, { signal: controller.signal });\n } catch (cause) {\n if (this.cancelled) throw new PromptCancelledError();\n throw cause;\n } finally {\n if (this.activeQuestion === controller) this.activeQuestion = undefined;\n }\n }\n}\n\nconst terminal = new TerminalIO();\nconst lifecycle = new AbortController();\nconst abortFromSignal = (signal: NodeJS.Signals) => {\n if (!lifecycle.signal.aborted) lifecycle.abort(new Error(signal));\n};\nconst onSigint = () => abortFromSignal(\"SIGINT\");\nconst onSigterm = () => abortFromSignal(\"SIGTERM\");\nprocess.on(\"SIGINT\", onSigint);\nprocess.on(\"SIGTERM\", onSigterm);\n\ntry {\n assertSupportedDeveloperPlatform();\n const args = process.argv.slice(2);\n const command = args[0];\n let platformHost: BuddyPlatformHost | undefined;\n const host = () => platformHost ??= new BuddyPlatformHost({ signal: lifecycle.signal });\n const result = await runBuddyCli(args, terminal, {\n ...(command === \"dev\" ? { dev: host().devOptions() } : {}),\n // Resolve credentials only when a supported command actually needs them.\n get cloud() { return host().cloudOptions(); },\n preview: (previewArgs, io) => host().runPreview(previewArgs, io),\n });\n process.exitCode = result.exitCode;\n} catch (cause) {\n const message = cause instanceof Error ? cause.message : String(cause);\n terminal.writeError(`buddy-cli: ${message}`);\n process.exitCode = 1;\n} finally {\n process.off(\"SIGINT\", onSigint);\n process.off(\"SIGTERM\", onSigterm);\n terminal.close();\n}\n", "import { resolve } from \"node:path\";\nimport { createHash } from \"node:crypto\";\nimport { createRuntimeLogForwarder } from \"./runtime-logs.js\";\n\nimport {\n CloudAuthenticator,\n DEFAULT_MLB_TEST_URL,\n DEVELOPMENT_HANDOFF_SUMMARY,\n HttpDeveloperPlatformClient,\n LoopbackBrowserLoginAdapter,\n MlbDevRegistrationClient,\n MockDeveloperPlatformClient,\n SystemCloudTokenStore,\n createBuddyDevStarter,\n createPushPreflight,\n createPushSourceBundle,\n resolvePlatformUrl,\n openExternalUrl,\n requireBuddyAgentProjectRoot,\n type CliIO,\n type CredentialCommandRunner,\n type CliRunResult,\n type RunCloudCommandOptions,\n type RunDevCommandOptions,\n} from \"@buddy/cli-core\";\nimport {\n PreviewController,\n MlbSimulatorClient,\n createBuddyPreviewUrl,\n startPreviewControlServer,\n type PreviewBuddyDetails,\n type PreviewDevHandle,\n type PreviewDevStarter,\n} from \"@buddy/preview\";\n\nexport interface ParsedPreviewArguments {\n readonly directory: string;\n readonly appServer?: string;\n readonly port?: number;\n readonly help: boolean;\n}\n\nexport const PREVIEW_COMMAND_HELP = `\u7528\u6CD5:\n buddy-cli preview [--app-server <App Server URL>] [--directory <\u9879\u76EE\u76EE\u5F55>] [--port <\u672C\u5730\u7AEF\u53E3>]\n\n\u8BF4\u660E:\n \u672A\u914D\u7F6E\u5730\u5740\u65F6\u8FDE\u63A5 MLB \u6D4B\u8BD5\u73AF\u5883 ${DEFAULT_MLB_TEST_URL}\uFF08HTTP \u4EC5\u9650\u6D4B\u8BD5\uFF09\u3002\n CLI \u7EDF\u4E00\u542F\u52A8\u5E76\u7BA1\u7406\u5DE5\u7A0B\u4E2D\u7684\u5B98\u65B9 Runtime\u3002\n \u6A21\u62DF\u5668\u4F7F\u7528\u5F53\u524D\u5F00\u53D1\u8005\u8D26\u53F7\u8BBF\u95EE <buddyId>-dev \u8C03\u8BD5\u5206\u8EAB\u3002\n\n${DEVELOPMENT_HANDOFF_SUMMARY}`;\n\nfunction valueAfter(args: readonly string[], index: number, flag: string): string {\n const value = args[index + 1];\n if (value === undefined || !value.trim()) throw new Error(`${flag} \u7F3A\u5C11\u503C`);\n return value;\n}\n\nfunction setOnce(current: string | undefined, value: string, flag: string): string {\n if (current !== undefined) throw new Error(`${flag} \u4E0D\u80FD\u91CD\u590D`);\n return value;\n}\n\nexport function parsePreviewArguments(args: readonly string[]): ParsedPreviewArguments {\n let directory = \".\";\n let directorySet = false;\n let appServer: string | undefined;\n let port: number | undefined;\n let help = false;\n for (let index = 0; index < args.length; index += 1) {\n const flag = args[index];\n if (flag === \"--help\" || flag === \"-h\") {\n if (args.length !== 1) throw new Error(\"--help \u4E0D\u80FD\u548C\u5176\u4ED6 preview \u53C2\u6570\u4E00\u8D77\u4F7F\u7528\");\n help = true;\n continue;\n }\n const value = valueAfter(args, index, flag ?? \"\u53C2\u6570\");\n index += 1;\n switch (flag) {\n case \"--directory\":\n if (directorySet) throw new Error(\"--directory \u4E0D\u80FD\u91CD\u590D\");\n directory = value;\n directorySet = true;\n break;\n case \"--port\":\n if (port !== undefined || !/^\\d+$/u.test(value) || Number(value) < 1 || Number(value) > 65535) throw new Error(\"--port \u5FC5\u987B\u662F 1\u201365535 \u7684\u7AEF\u53E3\u4E14\u4E0D\u80FD\u91CD\u590D\");\n port = Number(value);\n break;\n case \"--app-server\":\n appServer = setOnce(appServer, value, flag);\n break;\n default:\n throw new Error(`\u672A\u77E5 preview \u53C2\u6570 ${flag ?? \"\"}`);\n }\n }\n return Object.freeze({ directory, appServer, help, ...(port === undefined ? {} : { port }) });\n}\n\nexport interface BuddyPlatformHostOptions {\n readonly env?: Readonly<NodeJS.ProcessEnv>;\n readonly signal?: AbortSignal;\n readonly openUrl?: (url: URL) => Promise<void>;\n readonly credentialCommandRunner?: CredentialCommandRunner;\n}\n\nfunction waitForAbort(signal: AbortSignal): Promise<void> {\n if (signal.aborted) return Promise.resolve();\n return new Promise((resolveWait) => {\n signal.addEventListener(\"abort\", () => resolveWait(), { once: true });\n });\n}\n\nfunction previewHandle(handle: Awaited<ReturnType<ReturnType<typeof createBuddyDevStarter>[\"start\"]>>): PreviewDevHandle {\n return Object.freeze({\n closed: handle.completion.then((completion) => {\n if (completion.state === \"failed\") throw completion.error ?? new Error(\"DEV \u4F1A\u8BDD\u5F02\u5E38\u7ED3\u675F\");\n }),\n close: () => handle.stop(),\n });\n}\n\nexport class BuddyPlatformHost {\n readonly #env: Readonly<NodeJS.ProcessEnv>;\n readonly #signal: AbortSignal | undefined;\n readonly #openUrl: (url: URL) => Promise<void>;\n readonly #sessions = new Map<string, CloudAuthenticator>();\n readonly #credentialCommandRunner: CredentialCommandRunner | undefined;\n readonly #mockClient = new MockDeveloperPlatformClient();\n\n constructor(options: BuddyPlatformHostOptions = {}) {\n this.#env = options.env ?? process.env;\n this.#signal = options.signal;\n this.#openUrl = options.openUrl ?? openExternalUrl;\n this.#credentialCommandRunner = options.credentialCommandRunner;\n }\n\n cloudOptions(): Omit<RunCloudCommandOptions, \"cwd\"> {\n const preparePush: NonNullable<RunCloudCommandOptions[\"preparePush\"]> = async (\n projectRoot,\n ) => {\n const plan = await createPushPreflight({ projectRoot });\n return createPushSourceBundle(plan);\n };\n if (this.#env.BUDDY_CLI_MOCK_CLOUD === \"1\") {\n const mockToken = {\n accessToken: \"local-mock-access-token\",\n subject: \"account_local_mock\",\n expiresAt: Date.now() + 60 * 60_000,\n };\n return {\n mode: \"local-mock\",\n signal: this.#signal,\n session: {\n async token() { return mockToken; },\n async currentToken() { return mockToken; },\n async clear() {},\n },\n client: this.#mockClient,\n preparePush,\n };\n }\n const baseUrl = this.#configuredServer();\n const session = this.#session(baseUrl);\n return {\n mode: \"cloud\",\n session,\n signal: this.#signal,\n client: new HttpDeveloperPlatformClient({\n baseUrl,\n token: async () => (await session.token({ signal: this.#signal })).accessToken,\n }),\n preparePush,\n };\n }\n\n devOptions(): Omit<RunDevCommandOptions, \"cwd\"> {\n return {\n signal: this.#signal,\n env: this.#env,\n authorize: async ({ appServerUrl: baseUrl }) => {\n await this.#session(baseUrl).token({ signal: this.#signal });\n },\n createRegistrationClient: async ({ appServerUrl: baseUrl }) => {\n const token = await this.#session(baseUrl).token({ signal: this.#signal });\n return new MlbDevRegistrationClient({\n baseUrl,\n developerToken: token.accessToken,\n });\n },\n };\n }\n\n async runPreview(args: readonly string[], io: CliIO): Promise<CliRunResult> {\n const parsed = parsePreviewArguments(args);\n if (parsed.help) {\n io.write(PREVIEW_COMMAND_HELP);\n return { exitCode: 0, route: \"preview\" };\n }\n\n const projectRoot = await requireBuddyAgentProjectRoot(resolve(process.cwd(), parsed.directory));\n const baseUrl = resolvePlatformUrl({ env: this.#env, override: parsed.appServer, development: true });\n const signal = this.#signal ?? new AbortController().signal;\n await this.#session(baseUrl).token({ signal });\n const starter = this.#previewStarter(baseUrl);\n const controller = new PreviewController({\n projectRoot,\n devStarter: starter,\n readBuddyDetails: async (buddyId) => {\n const token = await this.#session(baseUrl).token({ signal });\n return new MlbSimulatorClient({\n baseUrl,\n buddyId: `${buddyId}-dev`,\n auth: { developerAccessToken: token.accessToken },\n }).details({ signal });\n },\n });\n const serverHandle = await startPreviewControlServer({ controller, port: parsed.port });\n try {\n await this.#openUrl(serverHandle.bootstrapUrl);\n io.write(`\u642D\u642D\u9884\u89C8\u4E0E\u8C03\u8BD5\u9875\u9762\u5DF2\u6253\u5F00\uFF1A${serverHandle.origin.href}`);\n io.write(\"\u5728\u9875\u9762\u4E2D\u542F\u52A8 DEV\uFF1B\u6D88\u606F\u4F1A\u7ECF\u8FC7 DEV App Server\uFF0C\u4E0D\u4F1A\u4ECE\u6D4F\u89C8\u5668\u76F4\u8FDE Agent\u3002\");\n io.write(DEVELOPMENT_HANDOFF_SUMMARY);\n if (signal.aborted) return { exitCode: 130, route: \"preview\" };\n await waitForAbort(signal);\n return { exitCode: 130, route: \"preview\" };\n } finally {\n await controller.close().catch(() => undefined);\n await serverHandle.close();\n }\n }\n\n #previewStarter(baseUrl: URL): PreviewDevStarter {\n const starter = createBuddyDevStarter();\n return Object.freeze({\n start: async ({ projectRoot, signal, onLog }: Parameters<PreviewDevStarter[\"start\"]>[0]) => {\n const token = await this.#session(baseUrl).token({ signal });\n const secrets = new Set([token.accessToken]);\n const logs = createRuntimeLogForwarder(event => onLog?.(event), secrets);\n const registrationClient = new MlbDevRegistrationClient({\n baseUrl,\n developerToken: token.accessToken,\n });\n const handle = await starter.start({ projectRoot, signal,\n registrationClient: {\n async register(request, options) {\n const registered = await registrationClient.register(request, options);\n secrets.add(registered.agentToken);\n return registered;\n },\n listOnline: options => registrationClient.listOnline(options),\n },\n onLog: logs.write,\n }).catch(cause => { logs.flush(); throw cause; });\n const preview = previewHandle(handle);\n void preview.closed.then(() => logs.flush(), () => logs.flush());\n const devBuddyId = `${handle.devAgentId}-dev`;\n const simulator = new MlbSimulatorClient({\n baseUrl,\n buddyId: devBuddyId,\n auth: { developerAccessToken: token.accessToken },\n });\n let buddy: PreviewBuddyDetails;\n let previewUrl: string;\n try {\n buddy = await simulator.details({ signal });\n previewUrl = createBuddyPreviewUrl(devBuddyId);\n signal.throwIfAborted();\n } catch (cause) {\n // Do not leave an Agent running after a failed/unauthorized profile read.\n await handle.stop();\n throw cause;\n }\n return Object.freeze({\n handle: preview,\n ready: Object.freeze({\n agentId: devBuddyId,\n buddy,\n devicePairing: Object.freeze({ url: previewUrl }),\n simulatorUrl: baseUrl.href,\n }),\n simulator,\n });\n },\n });\n }\n\n #configuredServer(): URL {\n return resolvePlatformUrl({ env: this.#env });\n }\n\n #session(baseUrl: URL): CloudAuthenticator {\n const key = baseUrl.origin;\n let session = this.#sessions.get(key);\n if (!session) {\n session = new CloudAuthenticator(\n new LoopbackBrowserLoginAdapter({\n platformUrl: baseUrl,\n ...(this.#env.BUDDY_DEVELOPER_WEB_URL ? { developerWebUrl: this.#env.BUDDY_DEVELOPER_WEB_URL } : {}),\n openBrowser: this.#openUrl,\n }),\n new SystemCloudTokenStore({\n account: `developer-session:${createHash(\"sha256\").update(key).digest(\"hex\")}`,\n commandRunner: this.#credentialCommandRunner,\n }),\n );\n this.#sessions.set(key, session);\n }\n return session;\n }\n}\n", "import { stripVTControlCharacters } from \"node:util\";\nimport type { DevLogEvent } from \"@buddy/cli-core\";\n\nconst MAX_LOG_LINE = 8_192;\n\n/** Assemble process chunks before masking credentials, including tokens split across chunks. */\nexport function createRuntimeLogForwarder(\n onLog: (event: DevLogEvent) => void,\n secrets: ReadonlySet<string>,\n) {\n const streams = new Map<DevLogEvent[\"source\"], { text: string; truncated: boolean }>();\n const emit = (source: DevLogEvent[\"source\"]) => {\n const pending = streams.get(source);\n if (!pending) return;\n streams.delete(source);\n let text = stripVTControlCharacters(pending.text);\n for (const secret of secrets) if (secret) text = text.split(secret).join(\"[REDACTED]\");\n if (pending.truncated) {\n // ANSI removal can move a credential cut at the raw buffer boundary into\n // the visible prefix. Mask its trailing prefix too, before display truncation.\n for (const secret of secrets) {\n for (let size = Math.min(secret.length - 1, text.length); size > 0; size--) {\n if (text.endsWith(secret.slice(0, size))) {\n text = text.slice(0, -size) + \"[REDACTED]\";\n break;\n }\n }\n }\n }\n text = text.replace(/[\\u0000-\\u0008\\u000b-\\u001f\\u007f]/gu, \"\").trimEnd();\n if (!text) return;\n text = text.slice(0, MAX_LOG_LINE) + (pending.truncated ? \" \u2026[truncated]\" : \"\");\n try { onLog({ source, text }); } catch { /* Diagnostics must not break supervision. */ }\n };\n return {\n write({ source, text }: DevLogEvent) {\n const limit = MAX_LOG_LINE + Math.max(0, ...[...secrets].map(secret => secret.length));\n for (const part of text.split(/(?<=\\n)/u)) {\n const pending = streams.get(source) ?? { text: \"\", truncated: false };\n const available = Math.max(0, limit - pending.text.length);\n pending.text += part.slice(0, available);\n pending.truncated ||= part.length > available;\n streams.set(source, pending);\n if (part.endsWith(\"\\n\")) emit(source);\n }\n },\n flush() { for (const source of streams.keys()) emit(source); },\n };\n}\n", "export class UnsupportedDeveloperPlatformError extends Error {\n constructor(readonly platform: NodeJS.Platform) {\n super(`buddy-cli V1 \u76EE\u524D\u53EA\u652F\u6301 macOS\uFF0C\u5F53\u524D\u7CFB\u7EDF\u662F ${platform}`);\n this.name = \"UnsupportedDeveloperPlatformError\";\n }\n}\n\nexport function assertSupportedDeveloperPlatform(\n platform: NodeJS.Platform = process.platform,\n): void {\n if (platform !== \"darwin\") throw new UnsupportedDeveloperPlatformError(platform);\n}\n"],
5
- "mappings": "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",
6
- "names": ["choice"]
3
+ "sources": ["../../src/bin/buddy.ts", "../../src/platform-host.ts", "../../src/runtime-logs.ts", "../../src/platform-support.ts", "../../src/self-update.ts"],
4
+ "sourcesContent": ["#!/usr/bin/env node\n\nimport { stdin, stderr, stdout } from \"node:process\";\nimport { createRequire } from \"node:module\";\nimport { dirname } from \"node:path\";\nimport { createInterface, type Interface } from \"node:readline/promises\";\nimport {\n PromptCancelledError,\n runBuddyCli,\n type Choice,\n type CliIO,\n type InputOptions,\n type SelectOptions,\n} from \"@buddy/cli-core\";\nimport { BuddyPlatformHost } from \"../platform-host.js\";\nimport { assertSupportedDeveloperPlatform } from \"../platform-support.js\";\nimport { runSelfUpdateCommand } from \"../self-update.js\";\n\nclass TerminalIO implements CliIO {\n readonly canPrompt = Boolean(stdin.isTTY && stdout.isTTY);\n private readline: Interface | undefined;\n private activeQuestion: AbortController | undefined;\n private cancelled = false;\n\n write(message: string): void {\n stdout.write(`${message}\\n`);\n }\n\n writeError(message: string): void {\n stderr.write(`${message}\\n`);\n }\n\n async select<Value extends string>(\n question: string,\n choices: readonly Choice<Value>[],\n options: SelectOptions<Value> = {},\n ): Promise<Value> {\n while (true) {\n this.write(`\\n${question}`);\n choices.forEach((choice, index) => {\n this.write(` ${index + 1}. ${choice.label}`);\n if (choice.description) this.write(` ${choice.description}`);\n });\n\n const defaultIndex = options.defaultValue === undefined\n ? undefined\n : choices.findIndex((choice) => choice.value === options.defaultValue);\n const prompt = defaultIndex === undefined || defaultIndex < 0\n ? \"\u8BF7\u8F93\u5165\u5E8F\u53F7\uFF1A\"\n : `\u8BF7\u8F93\u5165\u5E8F\u53F7\uFF08\u9ED8\u8BA4\uFF1A${defaultIndex + 1}\uFF09\uFF1A`;\n const answer = (await this.question(prompt)).trim();\n if (!answer && defaultIndex !== undefined && defaultIndex >= 0) return choices[defaultIndex]!.value;\n const selected = Number(answer) - 1;\n const choice = choices[selected];\n if (choice) return choice.value;\n this.writeError(`\u8BF7\u8F93\u5165 1 \u5230 ${choices.length} \u4E4B\u95F4\u7684\u5E8F\u53F7\u3002`);\n }\n }\n\n async input(question: string, options: InputOptions = {}): Promise<string> {\n const defaultHint = options.defaultValue === undefined ? \"\" : `\uFF08\u9ED8\u8BA4\uFF1A${options.defaultValue}\uFF09`;\n const answer = (await this.question(`${question}${defaultHint}\uFF1A`)).trim();\n return answer || options.defaultValue || \"\";\n }\n\n close(): void {\n this.readline?.close();\n }\n\n private getReadline(): Interface {\n if (this.readline) return this.readline;\n this.readline = createInterface({ input: stdin, output: stdout });\n this.readline.on(\"SIGINT\", () => {\n this.cancelled = true;\n this.activeQuestion?.abort();\n });\n return this.readline;\n }\n\n private async question(prompt: string): Promise<string> {\n const controller = new AbortController();\n this.activeQuestion = controller;\n try {\n return await this.getReadline().question(prompt, { signal: controller.signal });\n } catch (cause) {\n if (this.cancelled) throw new PromptCancelledError();\n throw cause;\n } finally {\n if (this.activeQuestion === controller) this.activeQuestion = undefined;\n }\n }\n}\n\nconst terminal = new TerminalIO();\nconst lifecycle = new AbortController();\nconst abortFromSignal = (signal: NodeJS.Signals) => {\n if (!lifecycle.signal.aborted) lifecycle.abort(new Error(signal));\n};\nconst onSigint = () => abortFromSignal(\"SIGINT\");\nconst onSigterm = () => abortFromSignal(\"SIGTERM\");\nprocess.on(\"SIGINT\", onSigint);\nprocess.on(\"SIGTERM\", onSigterm);\n\ntry {\n assertSupportedDeveloperPlatform();\n const args = process.argv.slice(2);\n const require = createRequire(import.meta.url);\n const manifestPath = require.resolve(\"@my-life-buddies/cli/package.json\");\n const maintenance = await runSelfUpdateCommand(args, terminal, {\n version: require(manifestPath).version,\n packageRoot: dirname(manifestPath),\n signal: lifecycle.signal,\n });\n const command = args[0];\n let platformHost: BuddyPlatformHost | undefined;\n const host = () => platformHost ??= new BuddyPlatformHost({ signal: lifecycle.signal });\n const result = maintenance ?? await runBuddyCli(args, terminal, {\n ...(command === \"dev\" ? { dev: host().devOptions() } : {}),\n // Resolve credentials only when a supported command actually needs them.\n get cloud() { return host().cloudOptions(); },\n preview: (previewArgs, io) => host().runPreview(previewArgs, io),\n });\n process.exitCode = result.exitCode;\n} catch (cause) {\n const message = cause instanceof Error ? cause.message : String(cause);\n terminal.writeError(`buddy-cli: ${message}`);\n process.exitCode = 1;\n} finally {\n process.off(\"SIGINT\", onSigint);\n process.off(\"SIGTERM\", onSigterm);\n terminal.close();\n}\n", "import { resolve } from \"node:path\";\nimport { createHash } from \"node:crypto\";\nimport { createRuntimeLogForwarder } from \"./runtime-logs.js\";\n\nimport {\n CloudAuthenticator,\n DEFAULT_MLB_TEST_URL,\n DEVELOPMENT_HANDOFF_SUMMARY,\n HttpDeveloperPlatformClient,\n LoopbackBrowserLoginAdapter,\n MlbDevRegistrationClient,\n MockDeveloperPlatformClient,\n SystemCloudTokenStore,\n createBuddyDevStarter,\n createPushPreflight,\n createPushSourceBundle,\n resolvePlatformUrl,\n openExternalUrl,\n requireBuddyAgentProjectRoot,\n type CliIO,\n type CredentialCommandRunner,\n type CliRunResult,\n type RunCloudCommandOptions,\n type RunDevCommandOptions,\n} from \"@buddy/cli-core\";\nimport {\n PreviewController,\n MlbSimulatorClient,\n createBuddyPreviewUrl,\n startPreviewControlServer,\n type PreviewBuddyDetails,\n type PreviewDevHandle,\n type PreviewDevStarter,\n} from \"@buddy/preview\";\n\nexport interface ParsedPreviewArguments {\n readonly directory: string;\n readonly appServer?: string;\n readonly port?: number;\n readonly help: boolean;\n}\n\nexport const PREVIEW_COMMAND_HELP = `\u7528\u6CD5:\n buddy-cli preview [--app-server <App Server URL>] [--directory <\u9879\u76EE\u76EE\u5F55>] [--port <\u672C\u5730\u7AEF\u53E3>]\n\n\u8BF4\u660E:\n \u672A\u914D\u7F6E\u5730\u5740\u65F6\u8FDE\u63A5 MLB \u6D4B\u8BD5\u73AF\u5883 ${DEFAULT_MLB_TEST_URL}\uFF08HTTP \u4EC5\u9650\u6D4B\u8BD5\uFF09\u3002\n CLI \u7EDF\u4E00\u542F\u52A8\u5E76\u7BA1\u7406\u5DE5\u7A0B\u4E2D\u7684\u5B98\u65B9 Runtime\u3002\n \u6A21\u62DF\u5668\u4F7F\u7528\u5F53\u524D\u5F00\u53D1\u8005\u8D26\u53F7\u8BBF\u95EE <buddyId>-dev \u8C03\u8BD5\u5206\u8EAB\u3002\n\n${DEVELOPMENT_HANDOFF_SUMMARY}`;\n\nfunction valueAfter(args: readonly string[], index: number, flag: string): string {\n const value = args[index + 1];\n if (value === undefined || !value.trim()) throw new Error(`${flag} \u7F3A\u5C11\u503C`);\n return value;\n}\n\nfunction setOnce(current: string | undefined, value: string, flag: string): string {\n if (current !== undefined) throw new Error(`${flag} \u4E0D\u80FD\u91CD\u590D`);\n return value;\n}\n\nexport function parsePreviewArguments(args: readonly string[]): ParsedPreviewArguments {\n let directory = \".\";\n let directorySet = false;\n let appServer: string | undefined;\n let port: number | undefined;\n let help = false;\n for (let index = 0; index < args.length; index += 1) {\n const flag = args[index];\n if (flag === \"--help\" || flag === \"-h\") {\n if (args.length !== 1) throw new Error(\"--help \u4E0D\u80FD\u548C\u5176\u4ED6 preview \u53C2\u6570\u4E00\u8D77\u4F7F\u7528\");\n help = true;\n continue;\n }\n const value = valueAfter(args, index, flag ?? \"\u53C2\u6570\");\n index += 1;\n switch (flag) {\n case \"--directory\":\n if (directorySet) throw new Error(\"--directory \u4E0D\u80FD\u91CD\u590D\");\n directory = value;\n directorySet = true;\n break;\n case \"--port\":\n if (port !== undefined || !/^\\d+$/u.test(value) || Number(value) < 1 || Number(value) > 65535) throw new Error(\"--port \u5FC5\u987B\u662F 1\u201365535 \u7684\u7AEF\u53E3\u4E14\u4E0D\u80FD\u91CD\u590D\");\n port = Number(value);\n break;\n case \"--app-server\":\n appServer = setOnce(appServer, value, flag);\n break;\n default:\n throw new Error(`\u672A\u77E5 preview \u53C2\u6570 ${flag ?? \"\"}`);\n }\n }\n return Object.freeze({ directory, appServer, help, ...(port === undefined ? {} : { port }) });\n}\n\nexport interface BuddyPlatformHostOptions {\n readonly env?: Readonly<NodeJS.ProcessEnv>;\n readonly signal?: AbortSignal;\n readonly openUrl?: (url: URL) => Promise<void>;\n readonly credentialCommandRunner?: CredentialCommandRunner;\n}\n\nfunction waitForAbort(signal: AbortSignal): Promise<void> {\n if (signal.aborted) return Promise.resolve();\n return new Promise((resolveWait) => {\n signal.addEventListener(\"abort\", () => resolveWait(), { once: true });\n });\n}\n\nfunction previewHandle(handle: Awaited<ReturnType<ReturnType<typeof createBuddyDevStarter>[\"start\"]>>): PreviewDevHandle {\n return Object.freeze({\n closed: handle.completion.then((completion) => {\n if (completion.state === \"failed\") throw completion.error ?? new Error(\"DEV \u4F1A\u8BDD\u5F02\u5E38\u7ED3\u675F\");\n }),\n close: () => handle.stop(),\n });\n}\n\nexport class BuddyPlatformHost {\n readonly #env: Readonly<NodeJS.ProcessEnv>;\n readonly #signal: AbortSignal | undefined;\n readonly #openUrl: (url: URL) => Promise<void>;\n readonly #sessions = new Map<string, CloudAuthenticator>();\n readonly #credentialCommandRunner: CredentialCommandRunner | undefined;\n readonly #mockClient = new MockDeveloperPlatformClient();\n\n constructor(options: BuddyPlatformHostOptions = {}) {\n this.#env = options.env ?? process.env;\n this.#signal = options.signal;\n this.#openUrl = options.openUrl ?? openExternalUrl;\n this.#credentialCommandRunner = options.credentialCommandRunner;\n }\n\n cloudOptions(): Omit<RunCloudCommandOptions, \"cwd\"> {\n const preparePush: NonNullable<RunCloudCommandOptions[\"preparePush\"]> = async (\n projectRoot,\n ) => {\n const plan = await createPushPreflight({ projectRoot });\n return createPushSourceBundle(plan);\n };\n if (this.#env.BUDDY_CLI_MOCK_CLOUD === \"1\") {\n const mockToken = {\n accessToken: \"local-mock-access-token\",\n subject: \"account_local_mock\",\n expiresAt: Date.now() + 60 * 60_000,\n };\n return {\n mode: \"local-mock\",\n signal: this.#signal,\n session: {\n async token() { return mockToken; },\n async currentToken() { return mockToken; },\n async clear() {},\n },\n client: this.#mockClient,\n preparePush,\n };\n }\n const baseUrl = this.#configuredServer();\n const session = this.#session(baseUrl);\n return {\n mode: \"cloud\",\n session,\n signal: this.#signal,\n client: new HttpDeveloperPlatformClient({\n baseUrl,\n token: async () => (await session.token({ signal: this.#signal })).accessToken,\n }),\n preparePush,\n };\n }\n\n devOptions(): Omit<RunDevCommandOptions, \"cwd\"> {\n return {\n signal: this.#signal,\n env: this.#env,\n authorize: async ({ appServerUrl: baseUrl }) => {\n await this.#session(baseUrl).token({ signal: this.#signal });\n },\n createRegistrationClient: async ({ appServerUrl: baseUrl }) => {\n const token = await this.#session(baseUrl).token({ signal: this.#signal });\n return new MlbDevRegistrationClient({\n baseUrl,\n developerToken: token.accessToken,\n });\n },\n };\n }\n\n async runPreview(args: readonly string[], io: CliIO): Promise<CliRunResult> {\n const parsed = parsePreviewArguments(args);\n if (parsed.help) {\n io.write(PREVIEW_COMMAND_HELP);\n return { exitCode: 0, route: \"preview\" };\n }\n\n const projectRoot = await requireBuddyAgentProjectRoot(resolve(process.cwd(), parsed.directory));\n const baseUrl = resolvePlatformUrl({ env: this.#env, override: parsed.appServer, development: true });\n const signal = this.#signal ?? new AbortController().signal;\n await this.#session(baseUrl).token({ signal });\n const starter = this.#previewStarter(baseUrl);\n const controller = new PreviewController({\n projectRoot,\n devStarter: starter,\n readBuddyDetails: async (buddyId) => {\n const token = await this.#session(baseUrl).token({ signal });\n return new MlbSimulatorClient({\n baseUrl,\n buddyId: `${buddyId}-dev`,\n auth: { developerAccessToken: token.accessToken },\n }).details({ signal });\n },\n });\n const serverHandle = await startPreviewControlServer({ controller, port: parsed.port });\n try {\n await this.#openUrl(serverHandle.bootstrapUrl);\n io.write(`\u642D\u642D\u9884\u89C8\u4E0E\u8C03\u8BD5\u9875\u9762\u5DF2\u6253\u5F00\uFF1A${serverHandle.origin.href}`);\n io.write(\"\u5728\u9875\u9762\u4E2D\u542F\u52A8 DEV\uFF1B\u6D88\u606F\u4F1A\u7ECF\u8FC7 DEV App Server\uFF0C\u4E0D\u4F1A\u4ECE\u6D4F\u89C8\u5668\u76F4\u8FDE Agent\u3002\");\n io.write(DEVELOPMENT_HANDOFF_SUMMARY);\n if (signal.aborted) return { exitCode: 130, route: \"preview\" };\n await waitForAbort(signal);\n return { exitCode: 130, route: \"preview\" };\n } finally {\n await controller.close().catch(() => undefined);\n await serverHandle.close();\n }\n }\n\n #previewStarter(baseUrl: URL): PreviewDevStarter {\n const starter = createBuddyDevStarter();\n return Object.freeze({\n start: async ({ projectRoot, signal, onLog }: Parameters<PreviewDevStarter[\"start\"]>[0]) => {\n const token = await this.#session(baseUrl).token({ signal });\n const secrets = new Set([token.accessToken]);\n const logs = createRuntimeLogForwarder(event => onLog?.(event), secrets);\n const registrationClient = new MlbDevRegistrationClient({\n baseUrl,\n developerToken: token.accessToken,\n });\n const handle = await starter.start({ projectRoot, signal,\n registrationClient: {\n async register(request, options) {\n const registered = await registrationClient.register(request, options);\n secrets.add(registered.agentToken);\n return registered;\n },\n listOnline: options => registrationClient.listOnline(options),\n },\n onLog: logs.write,\n }).catch(cause => { logs.flush(); throw cause; });\n const preview = previewHandle(handle);\n void preview.closed.then(() => logs.flush(), () => logs.flush());\n const devBuddyId = `${handle.devAgentId}-dev`;\n const simulator = new MlbSimulatorClient({\n baseUrl,\n buddyId: devBuddyId,\n auth: { developerAccessToken: token.accessToken },\n });\n let buddy: PreviewBuddyDetails;\n let previewUrl: string;\n try {\n buddy = await simulator.details({ signal });\n previewUrl = createBuddyPreviewUrl(devBuddyId);\n signal.throwIfAborted();\n } catch (cause) {\n // Do not leave an Agent running after a failed/unauthorized profile read.\n await handle.stop();\n throw cause;\n }\n return Object.freeze({\n handle: preview,\n ready: Object.freeze({\n agentId: devBuddyId,\n buddy,\n devicePairing: Object.freeze({ url: previewUrl }),\n simulatorUrl: baseUrl.href,\n }),\n simulator,\n });\n },\n });\n }\n\n #configuredServer(): URL {\n return resolvePlatformUrl({ env: this.#env });\n }\n\n #session(baseUrl: URL): CloudAuthenticator {\n const key = baseUrl.origin;\n let session = this.#sessions.get(key);\n if (!session) {\n session = new CloudAuthenticator(\n new LoopbackBrowserLoginAdapter({\n platformUrl: baseUrl,\n ...(this.#env.BUDDY_DEVELOPER_WEB_URL ? { developerWebUrl: this.#env.BUDDY_DEVELOPER_WEB_URL } : {}),\n openBrowser: this.#openUrl,\n }),\n new SystemCloudTokenStore({\n account: `developer-session:${createHash(\"sha256\").update(key).digest(\"hex\")}`,\n commandRunner: this.#credentialCommandRunner,\n }),\n );\n this.#sessions.set(key, session);\n }\n return session;\n }\n}\n", "import { stripVTControlCharacters } from \"node:util\";\nimport type { DevLogEvent } from \"@buddy/cli-core\";\n\nconst MAX_LOG_LINE = 8_192;\n\n/** Assemble process chunks before masking credentials, including tokens split across chunks. */\nexport function createRuntimeLogForwarder(\n onLog: (event: DevLogEvent) => void,\n secrets: ReadonlySet<string>,\n) {\n const streams = new Map<DevLogEvent[\"source\"], { text: string; truncated: boolean }>();\n const emit = (source: DevLogEvent[\"source\"]) => {\n const pending = streams.get(source);\n if (!pending) return;\n streams.delete(source);\n let text = stripVTControlCharacters(pending.text);\n for (const secret of secrets) if (secret) text = text.split(secret).join(\"[REDACTED]\");\n if (pending.truncated) {\n // ANSI removal can move a credential cut at the raw buffer boundary into\n // the visible prefix. Mask its trailing prefix too, before display truncation.\n for (const secret of secrets) {\n for (let size = Math.min(secret.length - 1, text.length); size > 0; size--) {\n if (text.endsWith(secret.slice(0, size))) {\n text = text.slice(0, -size) + \"[REDACTED]\";\n break;\n }\n }\n }\n }\n text = text.replace(/[\\u0000-\\u0008\\u000b-\\u001f\\u007f]/gu, \"\").trimEnd();\n if (!text) return;\n text = text.slice(0, MAX_LOG_LINE) + (pending.truncated ? \" \u2026[truncated]\" : \"\");\n try { onLog({ source, text }); } catch { /* Diagnostics must not break supervision. */ }\n };\n return {\n write({ source, text }: DevLogEvent) {\n const limit = MAX_LOG_LINE + Math.max(0, ...[...secrets].map(secret => secret.length));\n for (const part of text.split(/(?<=\\n)/u)) {\n const pending = streams.get(source) ?? { text: \"\", truncated: false };\n const available = Math.max(0, limit - pending.text.length);\n pending.text += part.slice(0, available);\n pending.truncated ||= part.length > available;\n streams.set(source, pending);\n if (part.endsWith(\"\\n\")) emit(source);\n }\n },\n flush() { for (const source of streams.keys()) emit(source); },\n };\n}\n", "export class UnsupportedDeveloperPlatformError extends Error {\n constructor(readonly platform: NodeJS.Platform) {\n super(`buddy-cli V1 \u76EE\u524D\u53EA\u652F\u6301 macOS\uFF0C\u5F53\u524D\u7CFB\u7EDF\u662F ${platform}`);\n this.name = \"UnsupportedDeveloperPlatformError\";\n }\n}\n\nexport function assertSupportedDeveloperPlatform(\n platform: NodeJS.Platform = process.platform,\n): void {\n if (platform !== \"darwin\") throw new UnsupportedDeveloperPlatformError(platform);\n}\n", "import { execFile } from \"node:child_process\";\nimport { lstat, readFile, realpath } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { isAbsolute, join } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport type { CliIO, CliRunResult } from \"@buddy/cli-core\";\n\nconst PACKAGE = \"@my-life-buddies/cli\";\nconst REGISTRY = \"https://registry.npmjs.org/\";\nconst MANUAL_UPDATE = `npm install --global ${PACKAGE}@latest --registry=${REGISTRY}`;\nconst execute = promisify(execFile);\nconst HELP = `\u7528\u6CD5:\n buddy-cli --version [--json]\n buddy-cli update --check [--json]\n buddy-cli update [--json]\n\n--version \u67E5\u770B\u5F53\u524D\u8FD0\u884C\u7684 CLI \u7248\u672C\uFF08\u65E0\u9700\u8054\u7F51\uFF09\n--check \u68C0\u67E5\u516C\u5171 npm \u7684 latest \u7248\u672C\uFF0C\u4E0D\u5B89\u88C5\n--json \u8F93\u51FA JSON\uFF0C\u4F9B Coding Agent \u6216\u811A\u672C\u8BFB\u53D6\n\n\u65E0\u9700\u767B\u5F55\u642D\u642D\u8D26\u53F7\uFF0C\u4E5F\u65E0\u9700\u8FDB\u5165\u642D\u5B50\u5DE5\u7A0B\u3002\nupdate \u66F4\u65B0\u5F53\u524D npm \u5168\u5C40\u5B89\u88C5\u7684 CLI\uFF0C\u4E0D\u4FEE\u6539\u642D\u5B50\u5DE5\u7A0B\u7684 Runtime \u4F9D\u8D56\u3002\n\u5DF2\u7ECF\u662F\u6700\u65B0\u7248\u6216\u5F53\u524D\u7248\u672C\u66F4\u9AD8\u65F6\u4E0D\u5B89\u88C5\u3001\u4E0D\u964D\u7EA7\u3002\n\u6E90\u7801\u3001npm link\u3001\u5C40\u90E8\u5B89\u88C5\u6216 npx \u8FD0\u884C\u65F6\uFF0C\u8BF7\u4F7F\u7528\u539F\u6765\u7684\u5B89\u88C5\u65B9\u5F0F\u66F4\u65B0\u3002\n\u65E7\u7248 CLI \u5C1A\u65E0 update \u547D\u4EE4\u65F6\uFF0C\u8FD0\u884C\uFF1A\\n ${MANUAL_UPDATE}`;\n\ninterface NpmOptions { cwd: string; signal?: AbortSignal; timeout: number }\ninterface UpdateOptions {\n version: string;\n packageRoot: string;\n signal?: AbortSignal;\n fetch?: typeof globalThis.fetch;\n runNpm?: (args: string[], options: NpmOptions) => Promise<{ stdout: string; stderr: string }>;\n}\n\n// SemVer precedence ignores build metadata; numeric identifiers compare numerically.\nfunction parseVersion(version: unknown): string[] {\n const numeric = \"(?:0|[1-9][0-9]*)\";\n const identifier = `(?:${numeric}|[0-9]*[A-Za-z-][0-9A-Za-z-]*)`;\n const pattern = new RegExp(`^(${numeric})\\\\.(${numeric})\\\\.(${numeric})(?:-(${identifier}(?:\\\\.${identifier})*))?(?:\\\\+[0-9A-Za-z-]+(?:\\\\.[0-9A-Za-z-]+)*)?$`, \"u\");\n const match = typeof version === \"string\" && version.length <= 256 ? pattern.exec(version) : null;\n if (!match || match[0] !== version) throw new Error(\"\u7248\u672C\u4FE1\u606F\u4E0D\u662F\u6709\u6548\u7684 SemVer \u7248\u672C\u53F7\u3002\");\n return [match[1]!, match[2]!, match[3]!, ...(match[4]?.split(\".\") ?? [])];\n}\n\nfunction compareVersions(left: string, right: string): number {\n const a = parseVersion(left);\n const b = parseVersion(right);\n for (let i = 0; i < 3; i++) {\n if (BigInt(a[i]!) !== BigInt(b[i]!)) return BigInt(a[i]!) > BigInt(b[i]!) ? 1 : -1;\n }\n if (a.length === 3 || b.length === 3) return a.length === b.length ? 0 : a.length === 3 ? 1 : -1;\n for (let i = 3; i < Math.max(a.length, b.length); i++) {\n const x = a[i];\n const y = b[i];\n if (x === y) continue;\n if (x === undefined || y === undefined) return x === undefined ? -1 : 1;\n const xn = /^[0-9]+$/u.test(x);\n const yn = /^[0-9]+$/u.test(y);\n if (xn && yn) return BigInt(x) > BigInt(y) ? 1 : -1;\n if (xn !== yn) return xn ? -1 : 1;\n return x > y ? 1 : -1;\n }\n return 0;\n}\n\nasync function latestVersion(options: UpdateOptions): Promise<string> {\n const timeout = AbortSignal.timeout(10_000);\n const signal = options.signal ? AbortSignal.any([options.signal, timeout]) : timeout;\n try {\n const response = await (options.fetch ?? globalThis.fetch)(`${REGISTRY}${encodeURIComponent(PACKAGE)}/latest`, {\n signal, headers: { Accept: \"application/json\" }, redirect: \"error\",\n });\n if (!response.ok) throw new Error(`npm \u8FD4\u56DE HTTP ${response.status}`);\n const metadata = await response.json() as { name?: unknown; version?: unknown } | null;\n if (metadata?.name !== PACKAGE) throw new Error(\"npm \u8FD4\u56DE\u7684\u5305\u540D\u4E0D\u5339\u914D\");\n parseVersion(metadata.version);\n return metadata.version as string;\n } catch (cause) {\n if (options.signal?.aborted) throw new Error(\"\u64CD\u4F5C\u5DF2\u53D6\u6D88\u3002\");\n if (timeout.aborted) throw new Error(\"\u68C0\u67E5\u66F4\u65B0\u8D85\u65F6\uFF0C\u8BF7\u68C0\u67E5\u7F51\u7EDC\u540E\u91CD\u8BD5\u3002\");\n throw new Error(`\u65E0\u6CD5\u68C0\u67E5 npm \u66F4\u65B0\uFF1A${cause instanceof Error ? cause.message : String(cause)}\u3002\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002`);\n }\n}\n\nasync function installUpdate(version: string, options: UpdateOptions): Promise<void> {\n const runNpm = options.runNpm ?? ((args, settings) => execute(\"npm\", args, { ...settings, encoding: \"utf8\", maxBuffer: 4 * 1024 * 1024 }));\n const settings = { cwd: homedir(), signal: options.signal, timeout: 10_000 };\n const { stdout } = await runNpm([\"prefix\", \"--global\"], settings);\n const prefix = stdout.trim();\n if (!isAbsolute(prefix) || /[\\r\\n]/u.test(prefix)) throw new Error(\"\u65E0\u6CD5\u786E\u5B9A npm \u5168\u5C40\u5B89\u88C5\u76EE\u5F55\u3002\");\n // The CLI supports macOS, where global packages live under prefix/lib/node_modules.\n const installedRoot = join(prefix, \"lib\", \"node_modules\", PACKAGE);\n let sameInstallation = false;\n try {\n sameInstallation = !(await lstat(installedRoot)).isSymbolicLink()\n && await realpath(installedRoot) === await realpath(options.packageRoot);\n } catch { /* Missing global package means this CLI came from another installation. */ }\n if (!sameInstallation) {\n throw new Error(\"\u5F53\u524D CLI \u4E0D\u662F\u8FD9\u4E2A npm \u73AF\u5883\u7684\u5168\u5C40\u5B89\u88C5\uFF0C\u4E0D\u80FD\u76F4\u63A5\u66F4\u65B0\u3002\u8BF7\u7528\u539F\u6765\u7684\u5B89\u88C5\u65B9\u5F0F\u66F4\u65B0\uFF1B\u82E5\u4F7F\u7528 nvm\uFF0C\u8BF7\u5148\u5207\u6362\u5230\u5B89\u88C5\u8BE5 CLI \u7684 Node.js \u73AF\u5883\u3002\");\n }\n try {\n await runNpm([\n \"install\", \"--global\", `${PACKAGE}@${version}`, \"--prefix\", prefix,\n `--registry=${REGISTRY}`, `--@my-life-buddies:registry=${REGISTRY}`, \"--engine-strict\", \"--no-audit\", \"--no-fund\",\n ], { ...settings, timeout: 180_000 });\n } catch (cause) {\n if (options.signal?.aborted) throw new Error(\"\u66F4\u65B0\u5DF2\u53D6\u6D88\uFF0C\u8BF7\u8FD0\u884C buddy-cli --version \u68C0\u67E5\u5B89\u88C5\u72B6\u6001\u3002\");\n const code = cause && typeof cause === \"object\" && \"code\" in cause ? String(cause.code) : \"unknown\";\n throw new Error(`npm \u5B89\u88C5\u672A\u5B8C\u6210\uFF08${code}\uFF09\u3002\u8BF7\u68C0\u67E5\u7F51\u7EDC\u548C\u5168\u5C40\u76EE\u5F55\u6743\u9650\uFF0C\u7136\u540E\u91CD\u8BD5\uFF1A${MANUAL_UPDATE}`);\n }\n const installed = JSON.parse(await readFile(join(installedRoot, \"package.json\"), \"utf8\"));\n if (installed.name !== PACKAGE || installed.version !== version) {\n throw new Error(`npm \u5DF2\u7ED3\u675F\uFF0C\u4F46\u672A\u786E\u8BA4\u5B89\u88C5\u5230 ${version}\u3002\u8BF7\u8FD0\u884C buddy-cli --version \u68C0\u67E5\uFF0C\u5FC5\u8981\u65F6\u91CD\u8BD5\uFF1A${MANUAL_UPDATE}`);\n }\n}\n\n/** Public CLI maintenance runs before any project or platform credential handling. */\nexport async function runSelfUpdateCommand(\n args: readonly string[],\n io: Pick<CliIO, \"write\" | \"writeError\">,\n options: UpdateOptions,\n): Promise<CliRunResult | undefined> {\n const versionOnly = args[0] === \"--version\" || args[0] === \"-v\";\n if (!versionOnly && args[0] !== \"update\") return undefined;\n const json = args.includes(\"--json\");\n const fail = (message: string, exitCode: number) => {\n if (json) io.write(JSON.stringify({ package: PACKAGE, currentVersion: options.version, error: message }));\n else io.writeError(`buddy-cli: ${message}`);\n return { exitCode };\n };\n const flags = args.slice(1);\n const allowed = versionOnly ? [\"--json\", \"--help\", \"-h\"] : [\"--check\", \"--json\", \"--help\", \"-h\"];\n if (flags.some(flag => !allowed.includes(flag)) || new Set(flags).size !== flags.length) {\n return fail(\"\u53C2\u6570\u65E0\u6548\uFF0C\u8BF7\u8FD0\u884C buddy-cli update --help \u67E5\u770B\u7528\u6CD5\u3002\", 2);\n }\n if (flags.includes(\"--help\") || flags.includes(\"-h\")) {\n if (json) io.write(JSON.stringify({ help: HELP }));\n else io.write(HELP);\n return { exitCode: 0 };\n }\n try {\n parseVersion(options.version);\n if (versionOnly) {\n io.write(json ? JSON.stringify({ package: PACKAGE, version: options.version }) : options.version);\n return { exitCode: 0 };\n }\n const latest = await latestVersion(options);\n const comparison = compareVersions(latest, options.version);\n const check = flags.includes(\"--check\");\n const status = comparison > 0 ? \"update_available\" : comparison < 0 ? \"ahead\" : \"up_to_date\";\n if (!check && comparison > 0) {\n if (!json) io.write(`\u6B63\u5728\u66F4\u65B0 CLI\uFF1A${options.version} \u2192 ${latest}\u2026`);\n await installUpdate(latest, options);\n }\n const updated = !check && comparison > 0;\n if (json) {\n io.write(JSON.stringify({\n package: PACKAGE, currentVersion: options.version, latestVersion: latest,\n updateAvailable: comparison > 0 && !updated, status: updated ? \"updated\" : status,\n ...(updated ? { installedVersion: latest } : {}),\n }));\n } else if (updated) io.write(`CLI \u5DF2\u66F4\u65B0\uFF1A${options.version} \u2192 ${latest}\u3002`);\n else if (comparison > 0) io.write(`\u53D1\u73B0\u65B0\u7248\u672C\uFF1A${options.version} \u2192 ${latest}\u3002\u8FD0\u884C buddy-cli update \u66F4\u65B0\u3002`);\n else if (comparison < 0) io.write(`\u5F53\u524D\u7248\u672C ${options.version} \u9AD8\u4E8E npm latest ${latest}\uFF0C\u65E0\u9700\u66F4\u65B0\u3002`);\n else io.write(`\u5F53\u524D\u5DF2\u662F\u6700\u65B0\u7248\uFF1A${options.version}\u3002`);\n return { exitCode: 0 };\n } catch (cause) {\n return fail(cause instanceof Error ? cause.message : String(cause), 1);\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["settings", "stdout", "choice", "require"]
7
7
  }