@my-life-buddies/cli 0.22.0 → 0.23.0-dev.2

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,14 +106,15 @@ 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
+ SIT \u540E\u53F0\u652F\u6301\u6309 Schema \u7F16\u8F91 Widget \u8BB0\u5F55\u4E0E\u4E0A\u4F20\u56FE\u7247\uFF1B\u901A\u8FC7 window.dadaWidget \u8C03\u7528\uFF0C\u5173\u95ED\u540E\u805A\u5408\u53D8\u66F4\u901A\u77E5\u3002\u771F\u673A\u7F16\u8F91\u4ECD\u9700\u5BA2\u6237\u7AEF\u652F\u6301\u3002
117
118
  \u6A21\u62DF\u5668\u4F7F\u7528\u5F53\u524D\u5F00\u53D1\u8005\u8D26\u53F7\u8BBF\u95EE <buddyId>-dev \u8C03\u8BD5\u5206\u8EAB\u3002`;
118
119
  function valueAfter(args, index, flag) {
119
120
  const value = args[index + 1];
@@ -453,7 +454,7 @@ var BuddyPlatformHost = class {
453
454
  // apps/cli/src/platform-support.ts
454
455
  var UnsupportedDeveloperPlatformError = class extends Error {
455
456
  constructor(platform) {
456
- super(`buddy-cli V1 \u76EE\u524D\u53EA\u652F\u6301 macOS\uFF0C\u5F53\u524D\u7CFB\u7EDF\u662F ${platform}`);
457
+ super(`buddy-cli-sit V1 \u76EE\u524D\u53EA\u652F\u6301 macOS\uFF0C\u5F53\u524D\u7CFB\u7EDF\u662F ${platform}`);
457
458
  this.platform = platform;
458
459
  this.name = "UnsupportedDeveloperPlatformError";
459
460
  }
@@ -465,9 +466,9 @@ function assertSupportedDeveloperPlatform(platform = process.platform) {
465
466
 
466
467
  // apps/cli/src/self-update.ts
467
468
  import { execFile } from "node:child_process";
468
- import { lstat, readFile, realpath } from "node:fs/promises";
469
+ import { readFile } from "node:fs/promises";
469
470
  import { homedir as homedir2 } from "node:os";
470
- import { isAbsolute, join as join2 } from "node:path";
471
+ import { join as join3 } from "node:path";
471
472
  import { promisify } from "node:util";
472
473
 
473
474
  // apps/cli/src/update-lock.ts
@@ -476,7 +477,7 @@ import { dirname, join } from "node:path";
476
477
  import { homedir } from "node:os";
477
478
  import { createHash as createHash2 } from "node:crypto";
478
479
  import { setTimeout as delay } from "node:timers/promises";
479
- var defaultUpdateCache = () => join(homedir(), ".cache", "buddy-cli", "updates");
480
+ var defaultUpdateCache = () => join(homedir(), ".cache", "buddy-cli-sit", "updates");
480
481
  var globalUpdateLock = (cache, prefix) => join(cache, "locks", createHash2("sha256").update(prefix).digest("hex"));
481
482
  async function withUpdateLock(path, signal, action) {
482
483
  await mkdir(dirname(path), { recursive: true, mode: 448 });
@@ -545,25 +546,43 @@ async function installCliWithNpm(args, settings, runNpm) {
545
546
  }
546
547
  }
547
548
 
549
+ // apps/cli/src/install-location.ts
550
+ import { lstat, realpath } from "node:fs/promises";
551
+ import { dirname as dirname2, join as join2, resolve as resolve2 } from "node:path";
552
+ async function globalInstallation(packageRoot, packageName) {
553
+ try {
554
+ if ((await lstat(packageRoot)).isSymbolicLink()) return void 0;
555
+ const root = await realpath(packageRoot);
556
+ let prefix = root;
557
+ for (const _part of ["lib", "node_modules", ...packageName.split("/")]) prefix = dirname2(prefix);
558
+ if (root !== resolve2(prefix, "lib", "node_modules", packageName)) return void 0;
559
+ if ((await lstat(join2(prefix, "lib", "node_modules", packageName))).isSymbolicLink()) return void 0;
560
+ return { root, prefix };
561
+ } catch {
562
+ return void 0;
563
+ }
564
+ }
565
+
548
566
  // apps/cli/src/self-update.ts
549
567
  var PACKAGE = "@my-life-buddies/cli";
550
568
  var REGISTRY = "https://registry.npmjs.org/";
551
- var MANUAL_UPDATE = `npm install --global ${PACKAGE}@latest --registry=${REGISTRY} --prefer-online`;
569
+ var MANUAL_UPDATE = `npm install --global --prefix "$HOME/.local/share/buddy-cli/sit" ${PACKAGE}@dev --registry=${REGISTRY} --prefer-online`;
552
570
  var execute = promisify(execFile);
553
571
  var HELP = `\u7528\u6CD5:
554
- buddy-cli --version [--json]
555
- buddy-cli update --check [--json]
556
- buddy-cli update [--json]
572
+ buddy-cli-sit --version [--json]
573
+ buddy-cli-sit update --check [--json]
574
+ buddy-cli-sit update [--json]
557
575
 
558
576
  --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
577
+ --check \u68C0\u67E5\u516C\u5171 npm \u7684 dev \u7248\u672C\uFF0C\u4E0D\u5B89\u88C5
560
578
  --json \u8F93\u51FA JSON\uFF0C\u4F9B Coding Agent \u6216\u811A\u672C\u8BFB\u53D6
561
579
 
562
580
  \u65E0\u9700\u767B\u5F55\u642D\u642D\u8D26\u53F7\uFF0C\u4E5F\u65E0\u9700\u8FDB\u5165\u642D\u5B50\u5DE5\u7A0B\u3002
563
581
  \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
582
  \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
583
  --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
584
+ 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
585
+ \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
586
  \u5DF2\u7ECF\u662F\u6700\u65B0\u7248\u6216\u5F53\u524D\u7248\u672C\u66F4\u9AD8\u65F6\u4E0D\u5B89\u88C5\u3001\u4E0D\u964D\u7EA7\u3002
568
587
  \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
588
  \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 +620,7 @@ async function latestVersion(options) {
601
620
  const timeout = AbortSignal.timeout(1e4);
602
621
  const signal = options.signal ? AbortSignal.any([options.signal, timeout]) : timeout;
603
622
  try {
604
- const response = await (options.fetch ?? globalThis.fetch)(`${REGISTRY}${encodeURIComponent(PACKAGE)}/latest`, {
623
+ const response = await (options.fetch ?? globalThis.fetch)(`${REGISTRY}${encodeURIComponent(PACKAGE)}/dev`, {
605
624
  signal,
606
625
  headers: { Accept: "application/json" },
607
626
  redirect: "error"
@@ -609,7 +628,8 @@ async function latestVersion(options) {
609
628
  if (!response.ok) throw new Error(`npm \u8FD4\u56DE HTTP ${response.status}`);
610
629
  const metadata = await response.json();
611
630
  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");
631
+ parseVersion(metadata.version);
632
+ 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
633
  return metadata.version;
614
634
  } catch (cause) {
615
635
  if (options.signal?.aborted) throw new Error("\u64CD\u4F5C\u5DF2\u53D6\u6D88\u3002");
@@ -618,22 +638,20 @@ async function latestVersion(options) {
618
638
  }
619
639
  }
620
640
  async function installUpdate(version, options) {
641
+ 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
642
  const runNpm = options.runNpm ?? ((args, settings2) => execute("npm", args, { ...settings2, encoding: "utf8", maxBuffer: 4 * 1024 * 1024 }));
622
643
  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");
644
+ const installation = await globalInstallation(options.packageRoot, PACKAGE);
645
+ if (!installation) {
646
+ 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
647
  }
648
+ const { root: installedRoot, prefix } = installation;
649
+ const manualUpdate = `npm install --global --prefix '${prefix.replace(/'/gu, "'\\''")}' ${PACKAGE}@dev --registry=${REGISTRY} --prefer-online`;
635
650
  await withUpdateLock(globalUpdateLock(options.cacheDirectory ?? defaultUpdateCache(), prefix), options.signal, async () => {
636
- const current = JSON.parse(await readFile(join2(installedRoot, "package.json"), "utf8"));
651
+ const current = JSON.parse(await readFile(join3(installedRoot, "package.json"), "utf8"));
652
+ if (current.name !== PACKAGE || !/^\d+\.\d+\.\d+-dev\.\d+$/.test(current.version)) {
653
+ 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");
654
+ }
637
655
  if (current.name === PACKAGE && current.version === version) return;
638
656
  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
657
  try {
@@ -650,13 +668,13 @@ async function installUpdate(version, options) {
650
668
  "--no-fund"
651
669
  ], { ...settings, timeout: 18e4 }, runNpm);
652
670
  } 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");
671
+ 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
672
  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}`);
673
+ \u4E5F\u53EF\u624B\u52A8\u5B89\u88C5\uFF1A${manualUpdate}`);
656
674
  }
657
- const installed = JSON.parse(await readFile(join2(installedRoot, "package.json"), "utf8"));
675
+ const installed = JSON.parse(await readFile(join3(installedRoot, "package.json"), "utf8"));
658
676
  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}`);
677
+ 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
678
  }
661
679
  });
662
680
  }
@@ -666,13 +684,13 @@ async function runSelfUpdateCommand(args, io, options) {
666
684
  const json = args.includes("--json");
667
685
  const fail = (message, exitCode) => {
668
686
  if (json) io.write(JSON.stringify({ package: PACKAGE, currentVersion: options.version, error: message }));
669
- else io.writeError(`buddy-cli: ${message}`);
687
+ else io.writeError(`buddy-cli-sit: ${message}`);
670
688
  return { exitCode };
671
689
  };
672
690
  const flags = args.slice(1);
673
691
  const allowed = versionOnly ? ["--json", "--help", "-h"] : ["--check", "--json", "--help", "-h"];
674
692
  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);
693
+ return fail("\u53C2\u6570\u65E0\u6548\uFF0C\u8BF7\u8FD0\u884C buddy-cli-sit update --help \u67E5\u770B\u7528\u6CD5\u3002", 2);
676
694
  }
677
695
  if (flags.includes("--help") || flags.includes("-h")) {
678
696
  if (json) io.write(JSON.stringify({ help: HELP }));
@@ -685,6 +703,8 @@ async function runSelfUpdateCommand(args, io, options) {
685
703
  io.write(json ? JSON.stringify({ package: PACKAGE, version: options.version }) : options.version);
686
704
  return { exitCode: 0 };
687
705
  }
706
+ const pin = process.env.BUDDY_CLI_PIN_VERSION;
707
+ 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
708
  const latest = await latestVersion(options);
689
709
  const comparison = compareVersions(latest, options.version);
690
710
  const check = flags.includes("--check");
@@ -704,8 +724,8 @@ async function runSelfUpdateCommand(args, io, options) {
704
724
  ...updated ? { installedVersion: latest } : {}
705
725
  }));
706
726
  } 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`);
727
+ 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`);
728
+ else if (comparison < 0) io.write(`\u5F53\u524D\u7248\u672C ${options.version} \u9AD8\u4E8E npm dev ${latest}\uFF0C\u65E0\u9700\u66F4\u65B0\u3002`);
709
729
  else io.write(`\u5F53\u524D\u5DF2\u662F\u6700\u65B0\u7248\uFF1A${options.version}\u3002`);
710
730
  return { exitCode: 0 };
711
731
  } catch (cause) {
@@ -731,16 +751,16 @@ function bindTerminationSignals(controller) {
731
751
  // apps/cli/src/auto-update.ts
732
752
  import { execFile as execFile2, spawn } from "node:child_process";
733
753
  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";
754
+ import { constants } from "node:os";
755
+ import { join as join4 } from "node:path";
736
756
  import { promisify as promisify2 } from "node:util";
737
757
  var PACKAGE2 = "@my-life-buddies/cli";
738
758
  var REGISTRY2 = "https://registry.npmjs.org/";
739
759
  var execute2 = promisify2(execFile2);
740
- var HANDOFF_ENV = "BUDDY_CLI_UPDATE_HANDOFF";
760
+ var HANDOFF_ENV = "BUDDY_CLI_SIT_UPDATE_HANDOFF";
741
761
  async function installedVersion(root) {
742
762
  try {
743
- const pkg = JSON.parse(await readFile2(join3(root, "package.json"), "utf8"));
763
+ const pkg = JSON.parse(await readFile2(join4(root, "package.json"), "utf8"));
744
764
  return pkg.name === PACKAGE2 && typeof pkg.version === "string" ? pkg.version : void 0;
745
765
  } catch {
746
766
  return void 0;
@@ -748,38 +768,29 @@ async function installedVersion(root) {
748
768
  }
749
769
  async function checkedEntry(root, version) {
750
770
  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");
771
+ const entry = join4(root, "dist", "bin", "buddy.js");
752
772
  if (!(await lstat2(entry)).isFile()) throw new Error("\u65B0\u7248 CLI \u7F3A\u5C11\u6709\u6548\u7684\u6267\u884C\u5165\u53E3\u3002");
753
773
  return entry;
754
774
  }
755
775
  async function prepareLatest(version, options) {
756
776
  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) {
777
+ const runNpm = options.runNpm ?? ((args, settings) => execute2("npm", args, { ...settings, encoding: "utf8", maxBuffer: 4 * 1024 * 1024 }));
778
+ const installation = await globalInstallation(options.packageRoot, PACKAGE2);
779
+ if (installation) {
769
780
  await installUpdate(version, options);
770
- return checkedEntry(globalRoot, version);
781
+ return checkedEntry(installation.root, version);
771
782
  }
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);
783
+ const destination = join4(cache, "releases", version);
784
+ return withUpdateLock(join4(cache, "locks", `release-${version}`), options.signal, async () => {
785
+ const root = join4(destination, "node_modules", PACKAGE2);
775
786
  try {
776
787
  return await checkedEntry(root, version);
777
788
  } catch {
778
789
  }
779
- await mkdir2(join3(cache, "releases"), { recursive: true, mode: 448 });
780
- const temporary = await mkdtemp(join3(cache, "releases", ".install-"));
790
+ await mkdir2(join4(cache, "releases"), { recursive: true, mode: 448 });
791
+ const temporary = await mkdtemp(join4(cache, "releases", ".install-"));
781
792
  try {
782
- await writeFile2(join3(temporary, "package.json"), JSON.stringify({ private: true }));
793
+ await writeFile2(join4(temporary, "package.json"), JSON.stringify({ private: true }));
783
794
  await installCliWithNpm(
784
795
  [
785
796
  "install",
@@ -796,7 +807,7 @@ async function prepareLatest(version, options) {
796
807
  { cwd: temporary, signal: options.signal, timeout: 18e4 },
797
808
  runNpm
798
809
  );
799
- await checkedEntry(join3(temporary, "node_modules", PACKAGE2), version);
810
+ await checkedEntry(join4(temporary, "node_modules", PACKAGE2), version);
800
811
  options.signal?.throwIfAborted();
801
812
  await rm2(destination, { recursive: true, force: true });
802
813
  await rename(temporary, destination);
@@ -808,7 +819,7 @@ async function prepareLatest(version, options) {
808
819
  }
809
820
  async function runUpdatedCli(entry, args, options) {
810
821
  options.signal?.throwIfAborted();
811
- return new Promise((resolve2, reject) => {
822
+ return new Promise((resolve3, reject) => {
812
823
  const child = spawn(process.execPath, [entry, ...args], { cwd: options.cwd, env: options.env, stdio: "inherit" });
813
824
  let killTimer;
814
825
  const abort = () => {
@@ -828,7 +839,7 @@ async function runUpdatedCli(entry, args, options) {
828
839
  });
829
840
  child.once("exit", (code, signal) => {
830
841
  cleanup();
831
- resolve2({ exitCode: code ?? 128 + (signal ? constants.signals[signal] : 1) });
842
+ resolve3({ exitCode: code ?? 128 + (signal ? constants.signals[signal] : 1) });
832
843
  });
833
844
  options.signal?.addEventListener("abort", abort, { once: true });
834
845
  if (options.signal?.aborted) abort();
@@ -839,12 +850,19 @@ async function runAutoUpdate(args, io, options) {
839
850
  if (args[0] === "help" || args[0] === "update" || args[0] === "--version" || args[0] === "-v" || args.includes("--help") || args.includes("-h")) return void 0;
840
851
  try {
841
852
  const env = { ...options.env ?? process.env };
853
+ const pin = env.BUDDY_CLI_PIN_VERSION;
854
+ if (pin !== void 0) {
855
+ if (!/^\d+\.\d+\.\d+-dev\.\d+$/.test(pin) || pin !== options.version) {
856
+ 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`);
857
+ }
858
+ return void 0;
859
+ }
842
860
  const handoff = env[HANDOFF_ENV];
843
861
  if (handoff !== void 0) {
844
862
  delete env[HANDOFF_ENV];
845
863
  if (!options.env) delete process.env[HANDOFF_ENV];
846
864
  const expected = JSON.parse(handoff);
847
- const entry2 = await realpath2(join3(options.packageRoot, "dist", "bin", "buddy.js"));
865
+ const entry2 = await realpath2(join4(options.packageRoot, "dist", "bin", "buddy.js"));
848
866
  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
867
  return void 0;
850
868
  }
@@ -952,7 +970,7 @@ try {
952
970
  const manifestPath = require2.resolve("@my-life-buddies/cli/package.json");
953
971
  const updateOptions = {
954
972
  version: require2(manifestPath).version,
955
- packageRoot: dirname2(manifestPath),
973
+ packageRoot: dirname3(manifestPath),
956
974
  signal: lifecycle.signal
957
975
  };
958
976
  const maintenance = await runSelfUpdateCommand(args, terminal, updateOptions) ?? await runAutoUpdate(args, terminal, updateOptions);
@@ -963,9 +981,10 @@ try {
963
981
  if (maintenance === void 0 && !offlineHelp) resolvePlatformUrl2();
964
982
  const result = maintenance ?? await runBuddyCli(args, terminal, {
965
983
  runtimeCatalog: { signal: lifecycle.signal },
966
- scaffoldPlatformAgent: (root, name) => scaffoldPlatformAgent(root, name, {
984
+ scaffoldPlatformAgent: (root, name, runtimeVersion) => scaffoldPlatformAgent(root, name, {
967
985
  resolveDependencies: (template) => latestRuntimeTemplate(template, {
968
986
  signal: lifecycle.signal,
987
+ runtimeVersion,
969
988
  report: (message) => terminal.write(message)
970
989
  })
971
990
  }),
@@ -979,7 +998,7 @@ try {
979
998
  process.exitCode = result.exitCode;
980
999
  } catch (cause) {
981
1000
  const message = cause instanceof Error ? cause.message : String(cause);
982
- terminal.writeError(`buddy-cli: ${message}`);
1001
+ terminal.writeError(`buddy-cli-sit: ${message}`);
983
1002
  process.exitCode = 1;
984
1003
  } finally {
985
1004
  unbindTermination();