@my-life-buddies/cli 0.22.0 → 0.23.0-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/dist/bin/buddy.js CHANGED
@@ -5,7 +5,7 @@ import { execFile as execFile3 } from "node:child_process";
5
5
  import { promisify as promisify3 } from "node:util";
6
6
  import { stdin, stderr, stdout } from "node:process";
7
7
  import { createRequire } from "node:module";
8
- import { dirname as dirname2 } from "node:path";
8
+ import { dirname as dirname3 } from "node:path";
9
9
  import { createInterface } from "node:readline/promises";
10
10
  import {
11
11
  PromptCancelledError,
@@ -95,8 +95,8 @@ import {
95
95
  connectPreviewBridge
96
96
  } from "./preview.js";
97
97
  var PREVIEW_COMMAND_HELP = `\u7528\u6CD5:
98
- buddy-cli preview [--directory <\u9879\u76EE\u76EE\u5F55>] [--buddy-id <\u642D\u5B50 ID>] [--developer-web <\u540E\u53F0 URL>] [--app-server <App Server URL>] [--no-open]
99
- buddy-cli preview --local [--directory <\u9879\u76EE\u76EE\u5F55>] [--port <\u672C\u5730\u7AEF\u53E3>]
98
+ buddy-cli-sit preview [--directory <\u9879\u76EE\u76EE\u5F55>] [--buddy-id <\u642D\u5B50 ID>] [--developer-web <\u540E\u53F0 URL>] [--app-server <App Server URL>] [--no-open]
99
+ buddy-cli-sit preview --local [--directory <\u9879\u76EE\u76EE\u5F55>] [--port <\u672C\u5730\u7AEF\u53E3>]
100
100
 
101
101
  \u8BF4\u660E:
102
102
  \u9ED8\u8BA4\u6253\u5F00\u5F53\u524D\u642D\u5B50\u7684\u521B\u9020\u8005\u540E\u53F0\u300C\u5F00\u53D1\u8C03\u8BD5\u300D\uFF0C\u8FDE\u63A5\u672C\u5730\u5DE5\u7A0B\uFF1B\u5728\u540E\u53F0\u542F\u52A8/\u505C\u6B62 DEV\u3001\u8BD5\u804A\u3001\u67E5\u770B Widget\u3001\u65F6\u95F4\u7EBF\u4E0E\u534F\u8BAE\u65E5\u5FD7\u3001\u771F\u673A\u9884\u89C8\u3002
@@ -106,12 +106,12 @@ var PREVIEW_COMMAND_HELP = `\u7528\u6CD5:
106
106
  --local \u662F\u540E\u53F0\u4E0D\u53EF\u7528\u65F6\u7684\u72EC\u7ACB\u672C\u5730\u9884\u89C8\u5907\u7528\u5165\u53E3\uFF0C--port \u4EC5\u4E0E --local \u4E00\u8D77\u4F7F\u7528\u3002
107
107
  \u4FDD\u6301\u7EC8\u7AEF\u8FD0\u884C\uFF1BCtrl+C \u6216\u5173\u95ED\u7EC8\u7AEF\u4F1A\u505C\u6B62 DEV \u5E76\u65AD\u5F00\u8FDE\u63A5\uFF0C\u5237\u65B0\u540E\u53F0\u4E0D\u4F1A\u81EA\u52A8\u542F\u52A8 DEV\u3002
108
108
  DEV \u5931\u8D25\u5148\u67E5\u770B\u5177\u4F53\u9519\u8BEF\u548C\u8FD0\u884C\u65E5\u5FD7\uFF1B\u5347\u7EA7 CLI \u540E\u9000\u51FA\u65E7 preview \u8FDB\u7A0B\u5E76\u91CD\u65B0\u8FDE\u63A5\uFF0C\u518D\u542F\u52A8 DEV\u3002
109
- \u540E\u53F0\u53EF\u5F3A\u5236\u65AD\u8FDE\uFF1B\u672C\u673A\u505C\u6B62\u672A\u786E\u8BA4\u65F6\uFF0C\u5728\u539F\u5DE5\u7A0B\u76EE\u5F55\u6267\u884C buddy-cli dev stop\u3002\u8BE5\u547D\u4EE4\u4E0D\u91CD\u8FDE\u3001\u4E0D\u91CD\u542F\u3002
109
+ \u540E\u53F0\u53EF\u5F3A\u5236\u65AD\u8FDE\uFF1B\u672C\u673A\u505C\u6B62\u672A\u786E\u8BA4\u65F6\uFF0C\u5728\u539F\u5DE5\u7A0B\u76EE\u5F55\u6267\u884C buddy-cli-sit dev stop\u3002\u8BE5\u547D\u4EE4\u4E0D\u91CD\u8FDE\u3001\u4E0D\u91CD\u542F\u3002
110
110
  \u672A\u914D\u7F6E\u5730\u5740\u65F6\u8FDE\u63A5 MLB \u6D4B\u8BD5\u73AF\u5883 ${DEFAULT_MLB_TEST_URL}\uFF08HTTPS\uFF09\u3002
111
- \u6B63\u5F0F\u7248\u56FA\u5B9A\u8FDE\u63A5 ECS Test\uFF1B\u5730\u5740\u53C2\u6570\u53EA\u6821\u9A8C\u56FA\u5B9A\u76EE\u6807\uFF0C\u4E0D\u80FD\u5207\u6362\u5E73\u53F0\u3002Runtime \u7F51\u5173\u7531 CLI \u6CE8\u5165\u3002
112
- CLI \u7EDF\u4E00\u542F\u52A8\u5E76\u7BA1\u7406\u5DE5\u7A0B\u4E2D\u7684\u5B98\u65B9 Runtime\uFF1B\u6BCF\u6B21\u542F\u52A8\u6216\u91CD\u8F7D\u5FC5\u987B\u901A\u8FC7 npm \u6700\u65B0\u7A33\u5B9A\u7248\u68C0\u67E5\u3002
111
+ SIT \u5305\u56FA\u5B9A\u8FDE\u63A5 SIT\uFF1B\u5730\u5740\u53C2\u6570\u53EA\u6821\u9A8C\u56FA\u5B9A\u76EE\u6807\uFF0C\u4E0D\u80FD\u5207\u6362\u5E73\u53F0\u3002Runtime \u7F51\u5173\u7531 CLI \u6CE8\u5165\u3002
112
+ CLI \u7EDF\u4E00\u542F\u52A8\u5E76\u7BA1\u7406\u5DE5\u7A0B\u4E2D\u7684\u5B98\u65B9 Runtime\uFF1B\u6BCF\u6B21\u542F\u52A8\u6216\u91CD\u8F7D\u68C0\u67E5\u5DE5\u7A0B\u9009\u5B9A Runtime \u7684\u51C6\u786E\u7248\u672C\u3001\u5B89\u88C5\u548C\u9501\u6587\u4EF6\u3002
113
113
  \u8EAB\u4EFD\u8BFB\u53D6 package.json.buddyId\uFF1B.env \u4FDD\u5B58 Token\uFF0C\u542F\u52A8\u524D\u5411 Server \u6821\u9A8C\u6240\u5C5E\u642D\u5B50\u3002
114
- \u8FDE\u63A5\u524D\u81EA\u68C0 .env \u7F51\u5173\uFF1B\u5DF2\u77E5\u65E7 ECS \u5730\u5740\u5728\u542F\u52A8 DEV \u65F6\u6821\u9A8C\u5F52\u5C5E\u5E76\u81EA\u52A8\u66F4\u65B0\uFF0C\u4E0D\u540C\u5E73\u53F0\u4ECD\u9700\u660E\u786E\u786E\u8BA4\u3002
114
+ \u8FDE\u63A5\u524D\u81EA\u68C0 .env \u7F51\u5173\uFF1B\u53D1\u73B0\u5176\u4ED6\u73AF\u5883\u5730\u5740\u65F6\u505C\u6B62\uFF1B\u8BF7\u4F7F\u7528\u5BF9\u5E94 CLI\uFF0C\u8FC1\u79FB\u65F6\u65B0\u5EFA\u8EAB\u4EFD\u4E14\u4E0D\u590D\u5236\u51ED\u636E\u3002
115
115
  --refresh-token \u91CD\u65B0\u9886\u53D6\u5DF2\u6709\u5F00\u53D1 Token\uFF0C\u66F4\u65B0\u540C\u4E00\u73AF\u5883\u7684\u5DE5\u7A0B .env\uFF1B\u4E0D\u80FD\u5207\u6362\u5E73\u53F0\uFF0C\u4E0D\u4F1A\u751F\u6210\u65B0\u5BC6\u94A5\u3002
116
116
  Widget \u6D88\u606F\u5361\u7247\u4FDD\u7559\u6307\u5B9A\u8BB0\u5F55\u7684\u6253\u5F00\u76EE\u6807\uFF0C\u5C0F\u6302\u4EF6\u5217\u8868\u6253\u5F00\u9ED8\u8BA4\u89C6\u56FE\u3002
117
117
  \u6A21\u62DF\u5668\u4F7F\u7528\u5F53\u524D\u5F00\u53D1\u8005\u8D26\u53F7\u8BBF\u95EE <buddyId>-dev \u8C03\u8BD5\u5206\u8EAB\u3002`;
@@ -453,7 +453,7 @@ var BuddyPlatformHost = class {
453
453
  // apps/cli/src/platform-support.ts
454
454
  var UnsupportedDeveloperPlatformError = class extends Error {
455
455
  constructor(platform) {
456
- super(`buddy-cli V1 \u76EE\u524D\u53EA\u652F\u6301 macOS\uFF0C\u5F53\u524D\u7CFB\u7EDF\u662F ${platform}`);
456
+ super(`buddy-cli-sit V1 \u76EE\u524D\u53EA\u652F\u6301 macOS\uFF0C\u5F53\u524D\u7CFB\u7EDF\u662F ${platform}`);
457
457
  this.platform = platform;
458
458
  this.name = "UnsupportedDeveloperPlatformError";
459
459
  }
@@ -465,9 +465,9 @@ function assertSupportedDeveloperPlatform(platform = process.platform) {
465
465
 
466
466
  // apps/cli/src/self-update.ts
467
467
  import { execFile } from "node:child_process";
468
- import { lstat, readFile, realpath } from "node:fs/promises";
468
+ import { readFile } from "node:fs/promises";
469
469
  import { homedir as homedir2 } from "node:os";
470
- import { isAbsolute, join as join2 } from "node:path";
470
+ import { join as join3 } from "node:path";
471
471
  import { promisify } from "node:util";
472
472
 
473
473
  // apps/cli/src/update-lock.ts
@@ -476,7 +476,7 @@ import { dirname, join } from "node:path";
476
476
  import { homedir } from "node:os";
477
477
  import { createHash as createHash2 } from "node:crypto";
478
478
  import { setTimeout as delay } from "node:timers/promises";
479
- var defaultUpdateCache = () => join(homedir(), ".cache", "buddy-cli", "updates");
479
+ var defaultUpdateCache = () => join(homedir(), ".cache", "buddy-cli-sit", "updates");
480
480
  var globalUpdateLock = (cache, prefix) => join(cache, "locks", createHash2("sha256").update(prefix).digest("hex"));
481
481
  async function withUpdateLock(path, signal, action) {
482
482
  await mkdir(dirname(path), { recursive: true, mode: 448 });
@@ -545,25 +545,43 @@ async function installCliWithNpm(args, settings, runNpm) {
545
545
  }
546
546
  }
547
547
 
548
+ // apps/cli/src/install-location.ts
549
+ import { lstat, realpath } from "node:fs/promises";
550
+ import { dirname as dirname2, join as join2, resolve as resolve2 } from "node:path";
551
+ async function globalInstallation(packageRoot, packageName) {
552
+ try {
553
+ if ((await lstat(packageRoot)).isSymbolicLink()) return void 0;
554
+ const root = await realpath(packageRoot);
555
+ let prefix = root;
556
+ for (const _part of ["lib", "node_modules", ...packageName.split("/")]) prefix = dirname2(prefix);
557
+ if (root !== resolve2(prefix, "lib", "node_modules", packageName)) return void 0;
558
+ if ((await lstat(join2(prefix, "lib", "node_modules", packageName))).isSymbolicLink()) return void 0;
559
+ return { root, prefix };
560
+ } catch {
561
+ return void 0;
562
+ }
563
+ }
564
+
548
565
  // apps/cli/src/self-update.ts
549
566
  var PACKAGE = "@my-life-buddies/cli";
550
567
  var REGISTRY = "https://registry.npmjs.org/";
551
- var MANUAL_UPDATE = `npm install --global ${PACKAGE}@latest --registry=${REGISTRY} --prefer-online`;
568
+ var MANUAL_UPDATE = `npm install --global --prefix "$HOME/.local/share/buddy-cli/sit" ${PACKAGE}@dev --registry=${REGISTRY} --prefer-online`;
552
569
  var execute = promisify(execFile);
553
570
  var HELP = `\u7528\u6CD5:
554
- buddy-cli --version [--json]
555
- buddy-cli update --check [--json]
556
- buddy-cli update [--json]
571
+ buddy-cli-sit --version [--json]
572
+ buddy-cli-sit update --check [--json]
573
+ buddy-cli-sit update [--json]
557
574
 
558
575
  --version \u67E5\u770B\u5F53\u524D\u8FD0\u884C\u7684 CLI \u7248\u672C\uFF08\u65E0\u9700\u8054\u7F51\uFF09
559
- --check \u68C0\u67E5\u516C\u5171 npm \u7684 latest \u7248\u672C\uFF0C\u4E0D\u5B89\u88C5
576
+ --check \u68C0\u67E5\u516C\u5171 npm \u7684 dev \u7248\u672C\uFF0C\u4E0D\u5B89\u88C5
560
577
  --json \u8F93\u51FA JSON\uFF0C\u4F9B Coding Agent \u6216\u811A\u672C\u8BFB\u53D6
561
578
 
562
579
  \u65E0\u9700\u767B\u5F55\u642D\u642D\u8D26\u53F7\uFF0C\u4E5F\u65E0\u9700\u8FDB\u5165\u642D\u5B50\u5DE5\u7A0B\u3002
563
580
  \u6B63\u5E38\u547D\u4EE4\uFF08\u542B guide\uFF09\u4F1A\u5148\u8054\u7F51\u81EA\u68C0\uFF0C\u81EA\u52A8\u66F4\u65B0\u540E\u7531\u65B0\u7248\u7EE7\u7EED\u6267\u884C\uFF1B\u7B49\u5F85\u5B8C\u6210\u5373\u53EF\u3002
564
581
  \u5B89\u88C5\u4E3B\u52A8\u5237\u65B0 npm \u7248\u672C\u7F13\u5B58\uFF0C\u627E\u4E0D\u5230\u7248\u672C\uFF08ETARGET\uFF09\u65F6\u6700\u591A\u91CD\u8BD5\u4E00\u6B21\uFF1B\u5931\u8D25\u8BF4\u660E\u5177\u4F53\u539F\u56E0\u3002
565
582
  --help\u3001\u5404\u547D\u4EE4 --help \u4E0E --version \u79BB\u7EBF\u53EF\u7528\uFF1B\u67E5\u8BE2\u6216\u66F4\u65B0\u5931\u8D25\u65F6\u505C\u6B62\u4E1A\u52A1\u64CD\u4F5C\u3002
566
- update \u7528\u4E8E\u5355\u72EC\u66F4\u65B0\u5F53\u524D npm \u5168\u5C40\u5B89\u88C5\u7684 CLI\uFF0C\u4E0D\u4FEE\u6539\u642D\u5B50\u5DE5\u7A0B\u7684 Runtime \u4F9D\u8D56\u3002
583
+ update \u66F4\u65B0\u5F53\u524D CLI \u6240\u5728\u7684 npm \u5B89\u88C5\u76EE\u5F55\uFF08\u542B --global --prefix \u81EA\u5B9A\u4E49\u76EE\u5F55\uFF09\uFF0C\u4E0D\u4FEE\u6539\u5176\u4ED6\u5B89\u88C5\u6216\u5DE5\u7A0B Runtime \u4F9D\u8D56\u3002
584
+ \u540C\u4E00\u5305 latest/dev \u9700\u5206\u76EE\u5F55\u5B89\u88C5\u624D\u80FD\u5171\u5B58\uFF1BSIT \u547D\u4EE4\u4E3A buddy-cli-sit\uFF0C\u6B63\u5F0F\u547D\u4EE4\u4E3A buddy-cli\u3002
567
585
  \u5DF2\u7ECF\u662F\u6700\u65B0\u7248\u6216\u5F53\u524D\u7248\u672C\u66F4\u9AD8\u65F6\u4E0D\u5B89\u88C5\u3001\u4E0D\u964D\u7EA7\u3002
568
586
  \u6E90\u7801\u3001npm link\u3001\u5C40\u90E8\u5B89\u88C5\u6216 npx \u7684\u6B63\u5E38\u547D\u4EE4\u4F7F\u7528\u7F13\u5B58\u7684\u65B0\u7248\u6267\u884C\uFF0C\u4E0D\u8986\u76D6\u6E90\u7801\u6216\u5DE5\u7A0B\u4F9D\u8D56\u3002
569
587
  \u4E0A\u8FF0\u5B89\u88C5\u65B9\u5F0F\u4E0D\u80FD\u7528 update \u5355\u72EC\u4FEE\u6539\u539F\u5B89\u88C5\uFF0C\u8BF7\u6CBF\u7528\u539F\u6765\u7684\u5B89\u88C5\u65B9\u5F0F\u66F4\u65B0\u3002
@@ -601,7 +619,7 @@ async function latestVersion(options) {
601
619
  const timeout = AbortSignal.timeout(1e4);
602
620
  const signal = options.signal ? AbortSignal.any([options.signal, timeout]) : timeout;
603
621
  try {
604
- const response = await (options.fetch ?? globalThis.fetch)(`${REGISTRY}${encodeURIComponent(PACKAGE)}/latest`, {
622
+ const response = await (options.fetch ?? globalThis.fetch)(`${REGISTRY}${encodeURIComponent(PACKAGE)}/dev`, {
605
623
  signal,
606
624
  headers: { Accept: "application/json" },
607
625
  redirect: "error"
@@ -609,7 +627,8 @@ async function latestVersion(options) {
609
627
  if (!response.ok) throw new Error(`npm \u8FD4\u56DE HTTP ${response.status}`);
610
628
  const metadata = await response.json();
611
629
  if (metadata?.name !== PACKAGE) throw new Error("npm \u8FD4\u56DE\u7684\u5305\u540D\u4E0D\u5339\u914D");
612
- if (parseVersion(metadata.version).length !== 3) throw new Error("npm latest \u6307\u5411\u4E86\u6D4B\u8BD5\u7248\uFF0C\u6B63\u5F0F CLI \u4E0D\u4F1A\u8DE8\u6E20\u9053\u66F4\u65B0\uFF1B\u8BF7\u8054\u7CFB\u53D1\u5E03\u8005\u4FEE\u6B63 latest \u6807\u7B7E");
630
+ parseVersion(metadata.version);
631
+ if (typeof metadata.version !== "string" || !/^\d+\.\d+\.\d+-dev\.\d+$/.test(metadata.version)) throw new Error("npm dev \u672A\u6307\u5411 x.y.z-dev.N \u7248\u672C\uFF1BSIT CLI \u4E0D\u4F1A\u8DE8\u6E20\u9053\u66F4\u65B0\uFF0C\u8BF7\u8054\u7CFB\u53D1\u5E03\u8005\u4FEE\u6B63 dev \u6807\u7B7E");
613
632
  return metadata.version;
614
633
  } catch (cause) {
615
634
  if (options.signal?.aborted) throw new Error("\u64CD\u4F5C\u5DF2\u53D6\u6D88\u3002");
@@ -618,22 +637,20 @@ async function latestVersion(options) {
618
637
  }
619
638
  }
620
639
  async function installUpdate(version, options) {
640
+ if (!/^\d+\.\d+\.\d+-dev\.\d+$/.test(version)) throw new Error("SIT CLI \u53EA\u80FD\u66F4\u65B0 x.y.z-dev.N \u7248\u672C\uFF0C\u4E0D\u4F1A\u8DE8\u6E20\u9053\u5B89\u88C5\u3002");
621
641
  const runNpm = options.runNpm ?? ((args, settings2) => execute("npm", args, { ...settings2, encoding: "utf8", maxBuffer: 4 * 1024 * 1024 }));
622
642
  const settings = { cwd: homedir2(), signal: options.signal, timeout: 1e4 };
623
- const { stdout: stdout2 } = await runNpm(["prefix", "--global"], settings);
624
- const prefix = stdout2.trim();
625
- if (!isAbsolute(prefix) || /[\r\n]/u.test(prefix)) throw new Error("\u65E0\u6CD5\u786E\u5B9A npm \u5168\u5C40\u5B89\u88C5\u76EE\u5F55\u3002");
626
- const installedRoot = join2(prefix, "lib", "node_modules", PACKAGE);
627
- let sameInstallation = false;
628
- try {
629
- sameInstallation = !(await lstat(installedRoot)).isSymbolicLink() && await realpath(installedRoot) === await realpath(options.packageRoot);
630
- } catch {
631
- }
632
- if (!sameInstallation) {
633
- 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");
643
+ const installation = await globalInstallation(options.packageRoot, PACKAGE);
644
+ if (!installation) {
645
+ throw new Error("\u5F53\u524D CLI \u662F\u6E90\u7801\u3001\u94FE\u63A5\u6216\u9879\u76EE\u5185\u5B89\u88C5\uFF0C\u4E0D\u80FD\u76F4\u63A5\u6539\u5199\u539F\u5B89\u88C5\u3002\u6B63\u5E38\u547D\u4EE4\u4F1A\u4ECE SIT \u72EC\u7ACB\u7F13\u5B58\u8FD0\u884C\u65B0\u7248\uFF1B\u5355\u72EC\u66F4\u65B0\u8BF7\u6CBF\u7528\u539F\u6765\u7684\u5B89\u88C5\u65B9\u5F0F\u3002");
634
646
  }
647
+ const { root: installedRoot, prefix } = installation;
648
+ const manualUpdate = `npm install --global --prefix '${prefix.replace(/'/gu, "'\\''")}' ${PACKAGE}@dev --registry=${REGISTRY} --prefer-online`;
635
649
  await withUpdateLock(globalUpdateLock(options.cacheDirectory ?? defaultUpdateCache(), prefix), options.signal, async () => {
636
- const current = JSON.parse(await readFile(join2(installedRoot, "package.json"), "utf8"));
650
+ const current = JSON.parse(await readFile(join3(installedRoot, "package.json"), "utf8"));
651
+ if (current.name !== PACKAGE || !/^\d+\.\d+\.\d+-dev\.\d+$/.test(current.version)) {
652
+ throw new Error("\u5F53\u524D\u5B89\u88C5\u76EE\u5F55\u5DF2\u88AB\u5176\u4ED6\u6E20\u9053\u66FF\u6362\uFF0C\u5DF2\u505C\u6B62\u66F4\u65B0\u3002\u8BF7\u5C06 latest \u548C dev \u5B89\u88C5\u5230\u4E0D\u540C\u76EE\u5F55\uFF0C\u518D\u91CD\u65B0\u8FD0\u884C buddy-cli-sit\u3002");
653
+ }
637
654
  if (current.name === PACKAGE && current.version === version) return;
638
655
  if (current.name === PACKAGE && compareVersions(current.version, version) > 0) throw new Error("\u53E6\u4E00\u4E2A\u8FDB\u7A0B\u5DF2\u5B89\u88C5\u66F4\u65B0\u7684 CLI\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C\u547D\u4EE4\u3002");
639
656
  try {
@@ -650,13 +667,13 @@ async function installUpdate(version, options) {
650
667
  "--no-fund"
651
668
  ], { ...settings, timeout: 18e4 }, runNpm);
652
669
  } catch (cause) {
653
- 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");
670
+ if (options.signal?.aborted) throw new Error("\u66F4\u65B0\u5DF2\u53D6\u6D88\uFF0C\u8BF7\u8FD0\u884C buddy-cli-sit --version \u68C0\u67E5\u5B89\u88C5\u72B6\u6001\u3002");
654
671
  throw new Error(`${cause instanceof Error ? cause.message : "npm \u5B89\u88C5\u672A\u5B8C\u6210\u3002"}
655
- \u4E5F\u53EF\u624B\u52A8\u5B89\u88C5\uFF1A${MANUAL_UPDATE}`);
672
+ \u4E5F\u53EF\u624B\u52A8\u5B89\u88C5\uFF1A${manualUpdate}`);
656
673
  }
657
- const installed = JSON.parse(await readFile(join2(installedRoot, "package.json"), "utf8"));
674
+ const installed = JSON.parse(await readFile(join3(installedRoot, "package.json"), "utf8"));
658
675
  if (installed.name !== PACKAGE || installed.version !== version) {
659
- 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}`);
676
+ throw new Error(`npm \u5DF2\u7ED3\u675F\uFF0C\u4F46\u672A\u786E\u8BA4\u5B89\u88C5\u5230 ${version}\u3002\u8BF7\u8FD0\u884C buddy-cli-sit --version \u68C0\u67E5\uFF0C\u5FC5\u8981\u65F6\u91CD\u8BD5\uFF1A${manualUpdate}`);
660
677
  }
661
678
  });
662
679
  }
@@ -666,13 +683,13 @@ async function runSelfUpdateCommand(args, io, options) {
666
683
  const json = args.includes("--json");
667
684
  const fail = (message, exitCode) => {
668
685
  if (json) io.write(JSON.stringify({ package: PACKAGE, currentVersion: options.version, error: message }));
669
- else io.writeError(`buddy-cli: ${message}`);
686
+ else io.writeError(`buddy-cli-sit: ${message}`);
670
687
  return { exitCode };
671
688
  };
672
689
  const flags = args.slice(1);
673
690
  const allowed = versionOnly ? ["--json", "--help", "-h"] : ["--check", "--json", "--help", "-h"];
674
691
  if (flags.some((flag) => !allowed.includes(flag)) || new Set(flags).size !== flags.length) {
675
- return fail("\u53C2\u6570\u65E0\u6548\uFF0C\u8BF7\u8FD0\u884C buddy-cli update --help \u67E5\u770B\u7528\u6CD5\u3002", 2);
692
+ return fail("\u53C2\u6570\u65E0\u6548\uFF0C\u8BF7\u8FD0\u884C buddy-cli-sit update --help \u67E5\u770B\u7528\u6CD5\u3002", 2);
676
693
  }
677
694
  if (flags.includes("--help") || flags.includes("-h")) {
678
695
  if (json) io.write(JSON.stringify({ help: HELP }));
@@ -685,6 +702,8 @@ async function runSelfUpdateCommand(args, io, options) {
685
702
  io.write(json ? JSON.stringify({ package: PACKAGE, version: options.version }) : options.version);
686
703
  return { exitCode: 0 };
687
704
  }
705
+ const pin = process.env.BUDDY_CLI_PIN_VERSION;
706
+ if (pin !== void 0) throw new Error("\u5F53\u524D\u5DF2\u7528 BUDDY_CLI_PIN_VERSION \u9501\u5B9A CLI\uFF1B\u5982\u9700\u66F4\u65B0\uFF0C\u8BF7\u5148 unset BUDDY_CLI_PIN_VERSION\u3002");
688
707
  const latest = await latestVersion(options);
689
708
  const comparison = compareVersions(latest, options.version);
690
709
  const check = flags.includes("--check");
@@ -704,8 +723,8 @@ async function runSelfUpdateCommand(args, io, options) {
704
723
  ...updated ? { installedVersion: latest } : {}
705
724
  }));
706
725
  } else if (updated) io.write(`CLI \u5DF2\u66F4\u65B0\uFF1A${options.version} \u2192 ${latest}\u3002`);
707
- 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`);
708
- else if (comparison < 0) io.write(`\u5F53\u524D\u7248\u672C ${options.version} \u9AD8\u4E8E npm latest ${latest}\uFF0C\u65E0\u9700\u66F4\u65B0\u3002`);
726
+ else if (comparison > 0) io.write(`\u53D1\u73B0\u65B0\u7248\u672C\uFF1A${options.version} \u2192 ${latest}\u3002\u8FD0\u884C buddy-cli-sit update \u66F4\u65B0\u3002`);
727
+ else if (comparison < 0) io.write(`\u5F53\u524D\u7248\u672C ${options.version} \u9AD8\u4E8E npm dev ${latest}\uFF0C\u65E0\u9700\u66F4\u65B0\u3002`);
709
728
  else io.write(`\u5F53\u524D\u5DF2\u662F\u6700\u65B0\u7248\uFF1A${options.version}\u3002`);
710
729
  return { exitCode: 0 };
711
730
  } catch (cause) {
@@ -731,16 +750,16 @@ function bindTerminationSignals(controller) {
731
750
  // apps/cli/src/auto-update.ts
732
751
  import { execFile as execFile2, spawn } from "node:child_process";
733
752
  import { lstat as lstat2, mkdir as mkdir2, mkdtemp, readFile as readFile2, realpath as realpath2, rename, rm as rm2, writeFile as writeFile2 } from "node:fs/promises";
734
- import { constants, homedir as homedir3 } from "node:os";
735
- import { isAbsolute as isAbsolute2, join as join3 } from "node:path";
753
+ import { constants } from "node:os";
754
+ import { join as join4 } from "node:path";
736
755
  import { promisify as promisify2 } from "node:util";
737
756
  var PACKAGE2 = "@my-life-buddies/cli";
738
757
  var REGISTRY2 = "https://registry.npmjs.org/";
739
758
  var execute2 = promisify2(execFile2);
740
- var HANDOFF_ENV = "BUDDY_CLI_UPDATE_HANDOFF";
759
+ var HANDOFF_ENV = "BUDDY_CLI_SIT_UPDATE_HANDOFF";
741
760
  async function installedVersion(root) {
742
761
  try {
743
- const pkg = JSON.parse(await readFile2(join3(root, "package.json"), "utf8"));
762
+ const pkg = JSON.parse(await readFile2(join4(root, "package.json"), "utf8"));
744
763
  return pkg.name === PACKAGE2 && typeof pkg.version === "string" ? pkg.version : void 0;
745
764
  } catch {
746
765
  return void 0;
@@ -748,38 +767,29 @@ async function installedVersion(root) {
748
767
  }
749
768
  async function checkedEntry(root, version) {
750
769
  if (await installedVersion(root) !== version) throw new Error(`CLI \u5B89\u88C5\u7ED3\u679C\u4E0E\u672C\u6B21\u8981\u6C42\u7684 ${version} \u4E0D\u4E00\u81F4\uFF0C\u8BF7\u91CD\u8BD5\u3002`);
751
- const entry = join3(root, "dist", "bin", "buddy.js");
770
+ const entry = join4(root, "dist", "bin", "buddy.js");
752
771
  if (!(await lstat2(entry)).isFile()) throw new Error("\u65B0\u7248 CLI \u7F3A\u5C11\u6709\u6548\u7684\u6267\u884C\u5165\u53E3\u3002");
753
772
  return entry;
754
773
  }
755
774
  async function prepareLatest(version, options) {
756
775
  const cache = options.cacheDirectory ?? defaultUpdateCache();
757
- const runNpm = options.runNpm ?? ((args, settings2) => execute2("npm", args, { ...settings2, encoding: "utf8", maxBuffer: 4 * 1024 * 1024 }));
758
- const settings = { cwd: homedir3(), signal: options.signal, timeout: 1e4 };
759
- const { stdout: stdout2 } = await runNpm(["prefix", "--global"], settings);
760
- const prefix = stdout2.trim();
761
- if (!isAbsolute2(prefix) || /[\r\n]/u.test(prefix)) throw new Error("\u65E0\u6CD5\u786E\u5B9A npm \u5168\u5C40\u5B89\u88C5\u76EE\u5F55\u3002");
762
- const globalRoot = join3(prefix, "lib", "node_modules", PACKAGE2);
763
- let isGlobal = false;
764
- try {
765
- isGlobal = !(await lstat2(globalRoot)).isSymbolicLink() && await realpath2(globalRoot) === await realpath2(options.packageRoot);
766
- } catch {
767
- }
768
- if (isGlobal) {
776
+ const runNpm = options.runNpm ?? ((args, settings) => execute2("npm", args, { ...settings, encoding: "utf8", maxBuffer: 4 * 1024 * 1024 }));
777
+ const installation = await globalInstallation(options.packageRoot, PACKAGE2);
778
+ if (installation) {
769
779
  await installUpdate(version, options);
770
- return checkedEntry(globalRoot, version);
780
+ return checkedEntry(installation.root, version);
771
781
  }
772
- const destination = join3(cache, "releases", version);
773
- return withUpdateLock(join3(cache, "locks", `release-${version}`), options.signal, async () => {
774
- const root = join3(destination, "node_modules", PACKAGE2);
782
+ const destination = join4(cache, "releases", version);
783
+ return withUpdateLock(join4(cache, "locks", `release-${version}`), options.signal, async () => {
784
+ const root = join4(destination, "node_modules", PACKAGE2);
775
785
  try {
776
786
  return await checkedEntry(root, version);
777
787
  } catch {
778
788
  }
779
- await mkdir2(join3(cache, "releases"), { recursive: true, mode: 448 });
780
- const temporary = await mkdtemp(join3(cache, "releases", ".install-"));
789
+ await mkdir2(join4(cache, "releases"), { recursive: true, mode: 448 });
790
+ const temporary = await mkdtemp(join4(cache, "releases", ".install-"));
781
791
  try {
782
- await writeFile2(join3(temporary, "package.json"), JSON.stringify({ private: true }));
792
+ await writeFile2(join4(temporary, "package.json"), JSON.stringify({ private: true }));
783
793
  await installCliWithNpm(
784
794
  [
785
795
  "install",
@@ -796,7 +806,7 @@ async function prepareLatest(version, options) {
796
806
  { cwd: temporary, signal: options.signal, timeout: 18e4 },
797
807
  runNpm
798
808
  );
799
- await checkedEntry(join3(temporary, "node_modules", PACKAGE2), version);
809
+ await checkedEntry(join4(temporary, "node_modules", PACKAGE2), version);
800
810
  options.signal?.throwIfAborted();
801
811
  await rm2(destination, { recursive: true, force: true });
802
812
  await rename(temporary, destination);
@@ -808,7 +818,7 @@ async function prepareLatest(version, options) {
808
818
  }
809
819
  async function runUpdatedCli(entry, args, options) {
810
820
  options.signal?.throwIfAborted();
811
- return new Promise((resolve2, reject) => {
821
+ return new Promise((resolve3, reject) => {
812
822
  const child = spawn(process.execPath, [entry, ...args], { cwd: options.cwd, env: options.env, stdio: "inherit" });
813
823
  let killTimer;
814
824
  const abort = () => {
@@ -828,7 +838,7 @@ async function runUpdatedCli(entry, args, options) {
828
838
  });
829
839
  child.once("exit", (code, signal) => {
830
840
  cleanup();
831
- resolve2({ exitCode: code ?? 128 + (signal ? constants.signals[signal] : 1) });
841
+ resolve3({ exitCode: code ?? 128 + (signal ? constants.signals[signal] : 1) });
832
842
  });
833
843
  options.signal?.addEventListener("abort", abort, { once: true });
834
844
  if (options.signal?.aborted) abort();
@@ -839,12 +849,19 @@ async function runAutoUpdate(args, io, options) {
839
849
  if (args[0] === "help" || args[0] === "update" || args[0] === "--version" || args[0] === "-v" || args.includes("--help") || args.includes("-h")) return void 0;
840
850
  try {
841
851
  const env = { ...options.env ?? process.env };
852
+ const pin = env.BUDDY_CLI_PIN_VERSION;
853
+ if (pin !== void 0) {
854
+ if (!/^\d+\.\d+\.\d+-dev\.\d+$/.test(pin) || pin !== options.version) {
855
+ throw new Error(`CLI \u7248\u672C\u9501\u5B9A\u4E0D\u5339\u914D\uFF1A\u8981\u6C42 ${pin}\uFF0C\u5F53\u524D ${options.version}\u3002\u8BF7\u5B89\u88C5 @my-life-buddies/cli@${pin} \u6216 unset BUDDY_CLI_PIN_VERSION\u3002`);
856
+ }
857
+ return void 0;
858
+ }
842
859
  const handoff = env[HANDOFF_ENV];
843
860
  if (handoff !== void 0) {
844
861
  delete env[HANDOFF_ENV];
845
862
  if (!options.env) delete process.env[HANDOFF_ENV];
846
863
  const expected = JSON.parse(handoff);
847
- const entry2 = await realpath2(join3(options.packageRoot, "dist", "bin", "buddy.js"));
864
+ const entry2 = await realpath2(join4(options.packageRoot, "dist", "bin", "buddy.js"));
848
865
  if (expected.parent !== process.ppid || expected.version !== options.version || expected.entry !== entry2 || JSON.stringify(expected.args) !== JSON.stringify(args)) throw new Error("CLI \u81EA\u52A8\u66F4\u65B0\u63A5\u7EED\u6821\u9A8C\u5931\u8D25\uFF0C\u8BF7\u91CD\u65B0\u8FD0\u884C\u547D\u4EE4\u3002");
849
866
  return void 0;
850
867
  }
@@ -952,7 +969,7 @@ try {
952
969
  const manifestPath = require2.resolve("@my-life-buddies/cli/package.json");
953
970
  const updateOptions = {
954
971
  version: require2(manifestPath).version,
955
- packageRoot: dirname2(manifestPath),
972
+ packageRoot: dirname3(manifestPath),
956
973
  signal: lifecycle.signal
957
974
  };
958
975
  const maintenance = await runSelfUpdateCommand(args, terminal, updateOptions) ?? await runAutoUpdate(args, terminal, updateOptions);
@@ -963,9 +980,10 @@ try {
963
980
  if (maintenance === void 0 && !offlineHelp) resolvePlatformUrl2();
964
981
  const result = maintenance ?? await runBuddyCli(args, terminal, {
965
982
  runtimeCatalog: { signal: lifecycle.signal },
966
- scaffoldPlatformAgent: (root, name) => scaffoldPlatformAgent(root, name, {
983
+ scaffoldPlatformAgent: (root, name, runtimeVersion) => scaffoldPlatformAgent(root, name, {
967
984
  resolveDependencies: (template) => latestRuntimeTemplate(template, {
968
985
  signal: lifecycle.signal,
986
+ runtimeVersion,
969
987
  report: (message) => terminal.write(message)
970
988
  })
971
989
  }),
@@ -979,7 +997,7 @@ try {
979
997
  process.exitCode = result.exitCode;
980
998
  } catch (cause) {
981
999
  const message = cause instanceof Error ? cause.message : String(cause);
982
- terminal.writeError(`buddy-cli: ${message}`);
1000
+ terminal.writeError(`buddy-cli-sit: ${message}`);
983
1001
  process.exitCode = 1;
984
1002
  } finally {
985
1003
  unbindTermination();