@bitfun-vsl/plugin 0.0.1 → 0.0.3

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
@@ -19,28 +19,28 @@ VSL 是一个面向 DevEco Code、Claude Code 和 BitFun 的精简插件包。
19
19
 
20
20
  需要 Bun、npm;选择 Claude Code 时还需要 Claude CLI。`vsl init` 按顺序显示两个复选列表:先选宿主(DevEco Code、Claude Code、BitFun,可多选),再选模块(默认全部勾选),最后只确认一次是否执行安装。方向键移动,空格勾选,`a` 全选,回车继续,Ctrl+C 取消。
21
21
 
22
- 本地包在本目录构建并启动向导:
22
+ 推荐方式:从 npm 官方源安装。先全局安装提供 CLI 的包,再运行同一个向导把官方包安装进宿主:
23
23
 
24
24
  ```powershell
25
- npm pack
26
- bun .\dist\cli\index.js init --package "$PWD\bitfun-vsl-plugin-0.0.1.tgz"
25
+ npm install -g @bitfun-vsl/plugin
26
+ vsl init
27
27
  ```
28
28
 
29
- 发布到 npm 后,用户先安装提供 CLI 的包,再运行同一个向导:
29
+ 默认安装来源是 npm 官方源的 `@bitfun-vsl/plugin@<CLI 版本>`,宿主依赖也锁定该官方版本。全局安装只提供 `vsl` 命令;init 负责更新宿主实际加载的依赖和注册。DevEco 安装到 `~/.config/deveco/node_modules/@bitfun-vsl/plugin`;BitFun 在 Windows 安装到 `%APPDATA%/bitfun/config/node_modules/@bitfun-vsl/plugin` 并注册 BitFun 专用入口,同时生成 `~/.config/opencode/command/vsl/*.md`;Claude 使用原生 marketplace/plugin 安装机制。宿主仍按原生插件方式加载资源。
30
+
31
+ 本地构建的包是开发验证用的辅助方式:在本目录打包后,用 `--package` 显式指定 tgz 运行同一个向导:
30
32
 
31
33
  ```powershell
32
- npm install -g @bitfun-vsl/plugin
33
- vsl init
34
+ npm pack
35
+ bun .\dist\cli\index.js init --package "$PWD\bitfun-vsl-plugin-0.0.2.tgz"
34
36
  ```
35
37
 
36
- 全局安装只提供 `vsl` 命令;init 负责更新宿主实际加载的依赖和注册。DevEco 安装到 `~/.config/deveco/node_modules/@bitfun-vsl/plugin`;BitFun 在 Windows 安装到 `%APPDATA%/bitfun/config/node_modules/@bitfun-vsl/plugin` 并注册 BitFun 专用入口,同时生成 `~/.config/opencode/command/vsl/*.md`;Claude 使用原生 marketplace/plugin 安装机制。宿主仍按原生插件方式加载资源。
37
-
38
38
  模块包括 `trajectory-analysis` 和 `code-review`。模块中的 Command、Agent、Skill、Tool 随模块一起启停;安装向导不按资源分类让用户选择。代码审查需要独立的 CR 原生程序,可设置 `VSL_CR_BIN` 或使用 `--cr-bin <绝对路径>`。
39
39
 
40
40
  自动化可明确选择一个或多个宿主并跳过交互:
41
41
 
42
42
  ```powershell
43
- vsl init --host deveco --host bitfun --modules trajectory-analysis,code-review --yes
43
+ vsl init --host deveco --host bitfun --modules "trajectory-analysis,code-review" --yes
44
44
  vsl doctor --host deveco --json
45
45
  vsl doctor --host bitfun --json
46
46
  ```
package/assets/build.json CHANGED
@@ -1,4 +1,4 @@
1
1
  {
2
- "version": "0.0.1",
3
- "buildId": "bbceff2246e5fb0e4b93bb05081457dbc113400b937c6148764573618d8534b5"
2
+ "version": "0.0.3",
3
+ "buildId": "ef337ee398fc256793104c4499ace48c18f0fafa0cbcc08b37bab00956293888"
4
4
  }
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "vsl",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "description": "VSL shared modules and tools"
5
5
  }
@@ -3,7 +3,7 @@
3
3
  var package_default = {
4
4
  $schema: "https://json.schemastore.org/package.json",
5
5
  name: "@bitfun-vsl/plugin",
6
- version: "0.0.1",
6
+ version: "0.0.3",
7
7
  main: "./dist/index.js",
8
8
  types: "./dist/index.d.ts",
9
9
  type: "module",
@@ -559,8 +559,8 @@ import { dirname, join as join2, resolve as resolve2 } from "path";
559
559
  import { fileURLToPath } from "url";
560
560
  // assets/build.json
561
561
  var build_default = {
562
- version: "0.0.1",
563
- buildId: "bbceff2246e5fb0e4b93bb05081457dbc113400b937c6148764573618d8534b5"
562
+ version: "0.0.3",
563
+ buildId: "ef337ee398fc256793104c4499ace48c18f0fafa0cbcc08b37bab00956293888"
564
564
  };
565
565
 
566
566
  // src/runtime.ts
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "version": "0.0.1",
4
- "buildId": "bbceff2246e5fb0e4b93bb05081457dbc113400b937c6148764573618d8534b5",
3
+ "version": "0.0.3",
4
+ "buildId": "ef337ee398fc256793104c4499ace48c18f0fafa0cbcc08b37bab00956293888",
5
5
  "modules": [
6
6
  {
7
7
  "id": "trajectory-analysis",
@@ -14,26 +14,26 @@
14
14
  ],
15
15
  "files": {
16
16
  "dist/cli/index.d.ts": "f3423a6dfe55290dafc908a46403976c9d7da2160d26b89ecff1bab6a80a9d86",
17
- "dist/cli/index.js": "1cbbb6c7beb1485f660b3dab2aef3f37e49678adc8f293464533bee0a781e60d",
17
+ "dist/cli/index.js": "889e024ff2ff1345893c8d0df09c9db1b31a3a14f26d0e749250cc3903364075",
18
18
  "dist/hosts/bitfun-kernel/commands.d.ts": "07e614ba39652230ad2347a946ba385b568a32ba93f4928e6eb51cce31355bcb",
19
19
  "dist/hosts/bitfun-kernel/plugin.d.ts": "804999c9467f3b8bc9cdbec2f9af61150ce57037357e3e45ac5cd3f5282232ec",
20
- "dist/hosts/bitfun-kernel/plugin.js": "e4726f0ca8b1fa5f3eba0e11e1f0f55df9334feba5d54245662a349e931b8483",
20
+ "dist/hosts/bitfun-kernel/plugin.js": "1349cb378106fdb5a883f64385368ce88de71b810b0b676f1f9e0ae77276816d",
21
21
  "dist/hosts/claude-code/index.d.ts": "9f7320bf122d3f14189e97c895ec2a31b305c6a6ad7f2d14ad86d7790bc85c4b",
22
- "dist/hosts/claude-code/index.js": "3c2474875e5343f2af66a6b8451344cce3369ad34cebdebbded6b0138a361b44",
22
+ "dist/hosts/claude-code/index.js": "3f660e6d9287d04784d65ce6985ffeb9dbc119e1e58be67e276bff1676f9da92",
23
23
  "dist/hosts/claude-code/mcp-server.d.ts": "a20783146e5c04090c1b0fedd4ef736c24d2bdf39f1c08baa23ad438b98b34ab",
24
24
  "dist/hosts/deveco/plugin.d.ts": "031ced638db5d56489b9f5d40a1c67f9ae131869faab66ca8f438f029516cad1",
25
- "dist/hosts/deveco/plugin.js": "c522ef844721d4d89da6b188f71b06af45de33d6e83099552563229124c55783",
25
+ "dist/hosts/deveco/plugin.js": "07f76e2b5549243350b60bf9c5cca4ea2b4e9da33e0a4ba190ee87ac3b25ed38",
26
26
  "dist/hosts/shared/opencode.d.ts": "70ede92462c55d7b24905303085275a1989cbbcd62faf0b6ea72cbacba6ef266",
27
27
  "dist/hosts/shared/schema.d.ts": "d2e820cb9a80931a7f7a484e3b53115a68fb496d6df8205e1bcb0415e0d04cea",
28
28
  "dist/index.d.ts": "d2b55570083bfc8cc661c3ca5d8f727ad2bb8589bcb30712ccb066bd442cfa35",
29
- "dist/index.js": "57bfe95f0fdf0089d21032e7b4e70a3f70ed1e47ca5ade2b635408e7833759f7",
29
+ "dist/index.js": "af01bbe8591b963dbb07389c80e5b8f3420959e9c4be703c781b028726becc25",
30
30
  "dist/install/config.d.ts": "860d7a129abc8605ec66793a18ae40f343beac2eb7d70702099acbe110173611",
31
- "dist/install/index.d.ts": "1d1b3c8c7c4c258c5c1b05745d5f519bad35b29e0095f42f8a93c47ccd1ce019",
31
+ "dist/install/index.d.ts": "3fa88e8b829beed966edf84eb9d93f3372a8ad8afebec8cfc33322e2e1b32652",
32
32
  "dist/install/resources.d.ts": "848b422ae05681572f464547842531cacf5099b45b3e89e24b9ed0d2dc1446d3",
33
33
  "dist/install/resources.js": "bb2062359843492b9eea62b0f1ed5a83d5ce392898fdd57fa949048cfd211fdb",
34
34
  "dist/plugin/contracts.d.ts": "9e7f8675396f443b5948e8e8f38e12dae35a14bbc271b1cc2739701c810f2873",
35
35
  "dist/plugin/index.d.ts": "61fccb54a34fc29059a1edb0bfd810dd829d0f697914697071d66e295edc18b2",
36
- "dist/plugin/index.js": "8a489f7009949c549d6dfbda799c722995fe1dbf325869bede6ec2fff5903155",
36
+ "dist/plugin/index.js": "0d15166a298a7dd3972b0b2a61f20c4c991d4e2698a49819045f62c56d93f14d",
37
37
  "dist/plugin/modules/code-review/index.d.ts": "59b0837709bf3adf14002ddd5528d9bb774d75ede3b6e56a0ef80a33d69b9cbe",
38
38
  "dist/plugin/modules/code-review/runtime.d.ts": "90cd157399c517b923aea4f1dce658666e25a163ae7cd0914e807174911fede0",
39
39
  "dist/plugin/modules/trajectory-analysis.d.ts": "bcf92d901eeaa573562ae6c2b5e151c961720a638b8acb1357e975a324c24830",
@@ -43,14 +43,14 @@
43
43
  "assets/bitfun/command/vsl/cr-health.md": "488fb54ee75e23301ad18c02dc7181145f102035cf9e5c469309fc9863514d63",
44
44
  "assets/bitfun/command/vsl/review.md": "d36e84b374ba7c5dc3ca0bdff2ef0ba096b4249e11ac0a3c10962ca9ac309d05",
45
45
  "assets/bitfun/command/vsl/trajectory.md": "844fd1ec1f027c70bc4c9c07fb9bad8984a4f575b20f02a042f5b7f69fe7930f",
46
- "assets/build.json": "fdb5338b120d65d674d24cc6d280e338d456a2cb76eb32ae7999138a7eff5a19",
47
- "assets/claude-code/.claude-plugin/plugin.json": "71b767aae98e501c8938497aa8568f1104cf74dd95b01bf3429dbe0e4dfd20b9",
46
+ "assets/build.json": "b3d9c21ac71d2d0be21d9ece69eb95c784903c5697c04d4590a178a2d7dae399",
47
+ "assets/claude-code/.claude-plugin/plugin.json": "9747c8c9ab18fc303dad26871361e00d2d33109133ad0e8896628ad8443d34d2",
48
48
  "assets/claude-code/.mcp.json": "7b48e397614f0acc95ee613e011cbed1373e152883bf8e1e13ffa288c01799ee",
49
49
  "assets/claude-code/agents/vsl-trajectory.md": "a1bf5a76ad60b604fc4eedc64f3bb06d6ccba0038eaddd24e3c2cc52b742c093",
50
50
  "assets/claude-code/commands/cr-health.md": "573bd218c873a2de2855c017a3206a259b93592396ad246f99206e7c52f18387",
51
51
  "assets/claude-code/commands/review.md": "ad8b57db645cd4fb122bdddb88f0dc627cf6f334d9fe72c9fedd40aef52d52c5",
52
52
  "assets/claude-code/commands/trajectory.md": "546bfa9f00fc5805427c2a5bdd4ee7f6ceb79fb9c73373b8424d2c607170762c",
53
- "assets/claude-code/scripts/mcp-server.js": "741daf225a918c15ae772acf1ce1bcc5a1763286d8c61bc5c2447233b68609b2",
53
+ "assets/claude-code/scripts/mcp-server.js": "1dbd06399f0ea6e10542d97b623cc0222bfa3b7805a137a46a89382b88033f15",
54
54
  "assets/claude-code/skills/vsl-trajectory-analysis/SKILL.md": "30262ad1adca7a9ea98bad771407a8a794e2a2327eae4cfb1bd1693f027bdaaa",
55
55
  "assets/deveco/skills/vsl-trajectory-analysis/SKILL.md": "30262ad1adca7a9ea98bad771407a8a794e2a2327eae4cfb1bd1693f027bdaaa",
56
56
  "assets/skills/vsl-trajectory-analysis/SKILL.md": "30262ad1adca7a9ea98bad771407a8a794e2a2327eae4cfb1bd1693f027bdaaa"
package/dist/cli/index.js CHANGED
@@ -222,7 +222,7 @@ import { spawn } from "child_process";
222
222
  import { createWriteStream } from "fs";
223
223
  import { access, mkdir, readFile, realpath, stat } from "fs/promises";
224
224
  import { homedir } from "os";
225
- import { delimiter, isAbsolute, join as join2, resolve as resolve2 } from "path";
225
+ import { delimiter, isAbsolute, join, resolve } from "path";
226
226
  import { pipeline } from "stream/promises";
227
227
  async function review(input, context, options) {
228
228
  if (Boolean(input.from) !== Boolean(input.to))
@@ -233,7 +233,7 @@ async function review(input, context, options) {
233
233
  throw new Error("preview cannot be combined with resume");
234
234
  if (input.resume && !input.commit && !input.from)
235
235
  throw new Error("resume requires commit or from/to; workspace resume is not supported");
236
- const directory = await realpath(resolve2(context.directory, input.repo ?? "."));
236
+ const directory = await realpath(resolve(context.directory, input.repo ?? "."));
237
237
  const args = ["review", "--repo", directory, "--audience", "agent", "--format", "json"];
238
238
  const flags = {
239
239
  commit: "commit",
@@ -362,7 +362,7 @@ async function resolveCr(binary = process.env.VSL_CR_BIN) {
362
362
  return realpath(binary);
363
363
  }
364
364
  const names = process.platform === "win32" ? ["cr.exe"] : ["cr"];
365
- const candidates = (process.env.PATH ?? "").split(delimiter).filter(Boolean).flatMap((directory) => names.map((name) => join2(directory, name)));
365
+ const candidates = (process.env.PATH ?? "").split(delimiter).filter(Boolean).flatMap((directory) => names.map((name) => join(directory, name)));
366
366
  const found = await Promise.all(candidates.map(async (path2) => await access(path2).then(() => path2, () => {
367
367
  return;
368
368
  })));
@@ -373,10 +373,10 @@ async function resolveCr(binary = process.env.VSL_CR_BIN) {
373
373
  }
374
374
  async function runCr(executable, args, options) {
375
375
  options.signal.throwIfAborted();
376
- const directory = join2(options.cacheDirectory ?? process.env.VSL_CR_CACHE_DIR ?? join2(process.env.LOCALAPPDATA ?? process.env.XDG_CACHE_HOME ?? join2(homedir(), ".cache"), "vsl", "cr"), crypto.randomUUID());
376
+ const directory = join(options.cacheDirectory ?? process.env.VSL_CR_CACHE_DIR ?? join(process.env.LOCALAPPDATA ?? process.env.XDG_CACHE_HOME ?? join(homedir(), ".cache"), "vsl", "cr"), crypto.randomUUID());
377
377
  await mkdir(directory, { recursive: true, mode: 448 });
378
- const resultFile = join2(directory, "result.json");
379
- const stderrFile = join2(directory, "stderr.log");
378
+ const resultFile = join(directory, "result.json");
379
+ const stderrFile = join(directory, "stderr.log");
380
380
  const child = spawn(executable, args, {
381
381
  cwd: options.directory,
382
382
  env: { ...process.env, CR_NO_UPDATE: "1" },
@@ -2197,7 +2197,7 @@ var dist_default5 = createPrompt((config, done) => {
2197
2197
  });
2198
2198
  // src/install/index.ts
2199
2199
  import { mkdir as mkdir3, rm, rename, lstat, open } from "fs/promises";
2200
- import { dirname as dirname3, join as join5, resolve as resolve5, isAbsolute as isAbsolute3 } from "path";
2200
+ import { dirname as dirname2, join as join4, resolve as resolve4, isAbsolute as isAbsolute3 } from "path";
2201
2201
  import { pathToFileURL } from "url";
2202
2202
 
2203
2203
  // node_modules/jsonc-parser/lib/esm/impl/scanner.js
@@ -3522,38 +3522,18 @@ function applyEdits(text, edits) {
3522
3522
  }
3523
3523
  return text;
3524
3524
  }
3525
-
3526
- // src/runtime.ts
3527
- import { readFileSync, existsSync } from "fs";
3528
- import { dirname, join, resolve } from "path";
3529
- import { fileURLToPath } from "url";
3530
3525
  // assets/build.json
3531
3526
  var build_default = {
3532
- version: "0.0.1",
3533
- buildId: "bbceff2246e5fb0e4b93bb05081457dbc113400b937c6148764573618d8534b5"
3527
+ version: "0.0.3",
3528
+ buildId: "ef337ee398fc256793104c4499ace48c18f0fafa0cbcc08b37bab00956293888"
3534
3529
  };
3535
3530
 
3536
- // src/runtime.ts
3537
- function packageRoot(url) {
3538
- const visit2 = (directory) => {
3539
- if (existsSync(join(directory, ".vsl-runtime.json")))
3540
- return directory;
3541
- const manifest = join(directory, "package.json");
3542
- if (existsSync(manifest) && JSON.parse(readFileSync(manifest, "utf8")).name === "@bitfun-vsl/plugin")
3543
- return directory;
3544
- if (dirname(directory) === directory)
3545
- throw new Error(`Cannot locate VSL package from ${url}`);
3546
- return visit2(dirname(directory));
3547
- };
3548
- return visit2(dirname(fileURLToPath(url)));
3549
- }
3550
-
3551
3531
  // src/install/config.ts
3552
3532
  import { homedir as homedir2 } from "os";
3553
- import { join as join4, resolve as resolve4 } from "path";
3533
+ import { join as join3, resolve as resolve3 } from "path";
3554
3534
 
3555
3535
  // src/install/resources.ts
3556
- import { join as join3, resolve as resolve3, relative, isAbsolute as isAbsolute2, dirname as dirname2 } from "path";
3536
+ import { join as join2, resolve as resolve2, relative, isAbsolute as isAbsolute2, dirname } from "path";
3557
3537
  import { mkdir as mkdir2, readdir } from "fs/promises";
3558
3538
 
3559
3539
  // src/plugin/modules/trajectory-analysis.ts
@@ -3812,8 +3792,8 @@ if (false) {}
3812
3792
  // src/install/resources.ts
3813
3793
  var digest = (content) => new Bun.CryptoHasher("sha256").update(content).digest("hex");
3814
3794
  function inside(root, path2) {
3815
- const target = resolve3(root, path2);
3816
- const part = relative(resolve3(root), target);
3795
+ const target = resolve2(root, path2);
3796
+ const part = relative(resolve2(root), target);
3817
3797
  if (part === ".." || part.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) || isAbsolute2(part))
3818
3798
  throw new Error(`Path escapes VSL root: ${path2}`);
3819
3799
  return target;
@@ -3821,9 +3801,9 @@ function inside(root, path2) {
3821
3801
  async function filesUnder(root) {
3822
3802
  return (await Promise.all((await readdir(root, { withFileTypes: true })).map(async (entry) => {
3823
3803
  if (entry.isSymbolicLink())
3824
- throw new Error(`Symlink not allowed in managed resources: ${join3(root, entry.name)}`);
3804
+ throw new Error(`Symlink not allowed in managed resources: ${join2(root, entry.name)}`);
3825
3805
  if (entry.isDirectory())
3826
- return (await filesUnder(join3(root, entry.name))).map((file) => `${entry.name}/${file}`);
3806
+ return (await filesUnder(join2(root, entry.name))).map((file) => `${entry.name}/${file}`);
3827
3807
  return entry.isFile() ? [entry.name] : [];
3828
3808
  }))).flat().sort();
3829
3809
  }
@@ -3839,7 +3819,7 @@ function selectResources(names) {
3839
3819
  async function writeResources(root, resources) {
3840
3820
  await Promise.all(Object.entries(resources).map(async ([path2, content]) => {
3841
3821
  const target = inside(root, path2);
3842
- await mkdir2(dirname2(target), { recursive: true });
3822
+ await mkdir2(dirname(target), { recursive: true });
3843
3823
  await Bun.write(target, content);
3844
3824
  }));
3845
3825
  }
@@ -3847,13 +3827,13 @@ async function writeResources(root, resources) {
3847
3827
  // src/install/config.ts
3848
3828
  function installationPaths(options) {
3849
3829
  const home = options.home ?? homedir2();
3850
- const bitfunUserRoot = process.env.BITFUN_USER_ROOT || process.env.BITFUN_E2E_USER_ROOT || (process.platform === "win32" ? join4(process.env.APPDATA ?? join4(home, "AppData", "Roaming"), "bitfun") : process.platform === "darwin" ? join4(home, "Library", "Application Support", "bitfun") : join4(process.env.XDG_CONFIG_HOME ?? join4(home, ".config"), "bitfun"));
3851
- const configDirectory = resolve4(options.configDirectory ?? (options.host === "deveco" ? process.env.DEVECO_CONFIG_DIR ?? join4(process.env.XDG_CONFIG_HOME ?? join4(home, ".config"), "deveco") : options.host === "bitfun" ? join4(bitfunUserRoot, "config") : process.env.CLAUDE_CONFIG_DIR ?? join4(home, ".claude")));
3852
- const stateDirectory = resolve4(options.stateDirectory ?? join4(home, ".vsl"));
3830
+ const bitfunUserRoot = process.env.BITFUN_USER_ROOT || process.env.BITFUN_E2E_USER_ROOT || (process.platform === "win32" ? join3(process.env.APPDATA ?? join3(home, "AppData", "Roaming"), "bitfun") : process.platform === "darwin" ? join3(home, "Library", "Application Support", "bitfun") : join3(process.env.XDG_CONFIG_HOME ?? join3(home, ".config"), "bitfun"));
3831
+ const configDirectory = resolve3(options.configDirectory ?? (options.host === "deveco" ? process.env.DEVECO_CONFIG_DIR ?? join3(process.env.XDG_CONFIG_HOME ?? join3(home, ".config"), "deveco") : options.host === "bitfun" ? join3(bitfunUserRoot, "config") : process.env.CLAUDE_CONFIG_DIR ?? join3(home, ".claude")));
3832
+ const stateDirectory = resolve3(options.stateDirectory ?? join3(home, ".vsl"));
3853
3833
  const installationId = digest(`${options.host}:${process.platform === "win32" ? configDirectory.toLowerCase() : configDirectory}`).slice(0, 16);
3854
- const instance = join4(stateDirectory, "installations", installationId);
3855
- const commandDirectory = resolve4(options.commandDirectory ?? process.env.OPENCODE_CONFIG_DIR ?? join4(process.env.XDG_CONFIG_HOME ?? join4(home, ".config"), "opencode"));
3856
- return { commandDirectory, configDirectory, stateDirectory, installationId, instance, receiptPath: join4(instance, "receipt.json"), journalPath: join4(instance, "transaction.json"), lockPath: join4(instance, "install.lock") };
3834
+ const instance = join3(stateDirectory, "installations", installationId);
3835
+ const commandDirectory = resolve3(options.commandDirectory ?? process.env.OPENCODE_CONFIG_DIR ?? join3(process.env.XDG_CONFIG_HOME ?? join3(home, ".config"), "opencode"));
3836
+ return { commandDirectory, configDirectory, stateDirectory, installationId, instance, receiptPath: join3(instance, "receipt.json"), journalPath: join3(instance, "transaction.json"), lockPath: join3(instance, "install.lock") };
3857
3837
  }
3858
3838
 
3859
3839
  // src/install/index.ts
@@ -3868,13 +3848,13 @@ async function planInstallation(options) {
3868
3848
  throw new Error("BitFun command directory changed; use the original --command-dir or uninstall first");
3869
3849
  if (options.crBinary && !isAbsolute3(options.crBinary))
3870
3850
  throw new Error("CR binary must be an absolute native executable path");
3871
- const source = options.source ? resolve5(options.source) : packageRoot(import.meta.url);
3872
- if (!await Bun.file(source).exists() && !await lstat(source).then((value) => value.isDirectory()).catch(() => false))
3851
+ const source = options.source ? resolve4(options.source) : `@bitfun-vsl/plugin@${build_default.version}`;
3852
+ if (options.source && !await Bun.file(source).exists() && !await lstat(source).then((value) => value.isDirectory()).catch(() => false))
3873
3853
  throw new Error(`Package source not found: ${source}`);
3874
- const configPath = options.host === "deveco" ? await devecoConfigPath(paths.configDirectory) : join5(paths.configDirectory, options.host === "bitfun" ? "app.json" : "settings.json");
3854
+ const configPath = options.host === "deveco" ? await devecoConfigPath(paths.configDirectory) : join4(paths.configDirectory, options.host === "bitfun" ? "app.json" : "settings.json");
3875
3855
  if (options.host !== "claude-code")
3876
3856
  validatePluginConfig(await readObject(configPath), previous);
3877
- const sourceIdentity = await Bun.file(source).exists() ? { sha256: digest(await Bun.file(source).bytes()) } : await verifyPackage(source).then((manifest) => ({ version: manifest.version, buildId: manifest.buildId }));
3857
+ const sourceIdentity = !options.source ? { version: build_default.version, buildId: build_default.buildId } : await Bun.file(source).exists() ? { sha256: digest(await Bun.file(source).bytes()) } : await verifyPackage(source).then((manifest) => ({ version: manifest.version, buildId: manifest.buildId }));
3878
3858
  return {
3879
3859
  action: previous ? "update" : "install",
3880
3860
  host: options.host,
@@ -3906,26 +3886,26 @@ async function install(options) {
3906
3886
  await assertOwnedFiles(previous);
3907
3887
  if (previous && !(await doctor(options)).configured)
3908
3888
  throw new Error("Managed host registration changed; resolve doctor diagnostics before update");
3909
- const packageJsonPath = join5(paths.configDirectory, "package.json");
3889
+ const packageJsonPath = join4(paths.configDirectory, "package.json");
3910
3890
  const configBefore = await textOrUndefined(plan.configPath);
3911
3891
  const packageBefore = await textOrUndefined(packageJsonPath);
3912
3892
  const dependencyBefore = dependencyOf(await readObject(packageJsonPath));
3913
3893
  const originalEntries = options.host !== "claude-code" ? validatePluginConfig(await readObject(plan.configPath), previous) : [];
3914
- const currentRoot = join5(paths.configDirectory, "node_modules/@bitfun-vsl/plugin");
3915
- if (!previous && options.host !== "claude-code" && await Bun.file(join5(currentRoot, "package.json")).exists()) {
3916
- if (!await Bun.file(join5(currentRoot, "assets/install-manifest.json")).exists())
3894
+ const currentRoot = join4(paths.configDirectory, "node_modules/@bitfun-vsl/plugin");
3895
+ if (!previous && options.host !== "claude-code" && await Bun.file(join4(currentRoot, "package.json")).exists()) {
3896
+ if (!await Bun.file(join4(currentRoot, "assets/install-manifest.json")).exists())
3917
3897
  throw new Error("Existing host VSL package has no ownership manifest. Back up and remove the legacy installation before init can take ownership.");
3918
3898
  await verifyPackage(currentRoot);
3919
3899
  const existing = await inventory(currentRoot);
3920
- const manifest2 = await Bun.file(join5(currentRoot, "assets/install-manifest.json")).json();
3921
- const pkg = await Bun.file(join5(currentRoot, "package.json")).json();
3900
+ const manifest2 = await Bun.file(join4(currentRoot, "assets/install-manifest.json")).json();
3901
+ const pkg = await Bun.file(join4(currentRoot, "package.json")).json();
3922
3902
  const unowned = Object.keys(existing).filter((path2) => !["package.json", "README.md", "LICENSE", "assets/install-manifest.json", "assets/runtime.json"].includes(path2) && !(path2 in manifest2.files) && !(pkg.files ?? []).some((file) => file.startsWith("docs/") && path2 === file));
3923
3903
  if (unowned.length)
3924
3904
  throw new Error(`Unowned files in existing VSL package: ${unowned.join(", ")}`);
3925
3905
  }
3926
- const originalRuntime = options.host !== "claude-code" ? await textOrUndefined(join5(currentRoot, "assets/runtime.json")) : undefined;
3927
- const releaseRoot = join5(paths.instance, "releases", crypto.randomUUID());
3928
- const marketplaceBefore = await textOrUndefined(join5(paths.instance, "marketplace/.claude-plugin/marketplace.json"));
3906
+ const originalRuntime = options.host !== "claude-code" ? await textOrUndefined(join4(currentRoot, "assets/runtime.json")) : undefined;
3907
+ const releaseRoot = join4(paths.instance, "releases", crypto.randomUUID());
3908
+ const marketplaceBefore = await textOrUndefined(join4(paths.instance, "marketplace/.claude-plugin/marketplace.json"));
3929
3909
  const state = {
3930
3910
  phase: "staging",
3931
3911
  host: options.host,
@@ -3940,10 +3920,10 @@ async function install(options) {
3940
3920
  originalEntries,
3941
3921
  originalRuntime
3942
3922
  };
3943
- await writeJson(paths.journalPath, state);
3944
3923
  await mkdir3(releaseRoot, { recursive: true });
3945
3924
  await command(["npm", "install", "--prefix", releaseRoot, "--ignore-scripts", "--install-links", "--no-audit", "--no-fund", plan.source]);
3946
- const stagedRoot = join5(releaseRoot, "node_modules/@bitfun-vsl/plugin");
3925
+ await writeJson(paths.journalPath, state);
3926
+ const stagedRoot = join4(releaseRoot, "node_modules/@bitfun-vsl/plugin");
3947
3927
  const manifest = await verifyPackage(stagedRoot);
3948
3928
  if (plan.modules.some((name) => !manifest.modules.some((module) => module.id === name)))
3949
3929
  throw new Error("Selected module is absent from source package");
@@ -3961,11 +3941,11 @@ async function install(options) {
3961
3941
  return { ...report2, recoveryRequired: false, unchanged: true };
3962
3942
  }
3963
3943
  }
3964
- await writeJson(join5(stagedRoot, "assets/runtime.json"), runtime);
3944
+ await writeJson(join4(stagedRoot, "assets/runtime.json"), runtime);
3965
3945
  const marketplace = `vsl-${paths.installationId}`;
3966
- const marketplacePath = join5(paths.instance, "marketplace");
3946
+ const marketplacePath = join4(paths.instance, "marketplace");
3967
3947
  const pluginVersion = `${manifest.version}+vsl.${manifest.buildId.slice(0, 8)}.${digest(JSON.stringify(runtime)).slice(0, 8)}.${crypto.randomUUID().slice(0, 8)}`;
3968
- const pluginRoot = join5(marketplacePath, "releases", pluginVersion, "plugin");
3948
+ const pluginRoot = join4(marketplacePath, "releases", pluginVersion, "plugin");
3969
3949
  if (options.host === "claude-code") {
3970
3950
  const existing = await command(["claude", "plugin", "list", "--json"], claudeEnvironment(paths.configDirectory));
3971
3951
  const plugins = JSON.parse(existing);
@@ -3973,17 +3953,17 @@ async function install(options) {
3973
3953
  throw new Error("Invalid Claude plugin inventory");
3974
3954
  if (plugins.some((item) => item && typeof item === "object" && ("id" in item) && typeof item.id === "string" && (item.id === "vsl" || item.id.startsWith("vsl@")) && item.id !== `vsl@${marketplace}`))
3975
3955
  throw new Error("Another VSL Claude plugin is registered; resolve it before adopting this installation");
3976
- const existingPlugin = await Bun.file(join5(pluginRoot, ".claude-plugin/plugin.json")).exists();
3956
+ const existingPlugin = await Bun.file(join4(pluginRoot, ".claude-plugin/plugin.json")).exists();
3977
3957
  if (existingPlugin)
3978
3958
  throw new Error(`Unowned Claude release already exists: ${pluginRoot}`);
3979
- const renderer2 = await import(pathToFileURL(join5(stagedRoot, "dist/install/resources.js")).href);
3959
+ const renderer2 = await import(pathToFileURL(join4(stagedRoot, "dist/install/resources.js")).href);
3980
3960
  await writeResources(pluginRoot, Object.fromEntries(Object.entries(renderer2.renderResources(renderer2.selectResources(plan.modules), pluginVersion)).filter(([path2]) => path2.startsWith("claude-code/")).map(([path2, content]) => [path2.slice("claude-code/".length), content])));
3981
- await writeJson(join5(pluginRoot, ".vsl-runtime.json"), runtime);
3982
- await mkdir3(join5(pluginRoot, "scripts"), { recursive: true });
3983
- await Bun.write(join5(pluginRoot, "scripts/mcp-server.js"), Bun.file(join5(stagedRoot, "assets/claude-code/scripts/mcp-server.js")));
3961
+ await writeJson(join4(pluginRoot, ".vsl-runtime.json"), runtime);
3962
+ await mkdir3(join4(pluginRoot, "scripts"), { recursive: true });
3963
+ await Bun.write(join4(pluginRoot, "scripts/mcp-server.js"), Bun.file(join4(stagedRoot, "assets/claude-code/scripts/mcp-server.js")));
3984
3964
  await command(["claude", "plugin", "validate", pluginRoot], claudeEnvironment(paths.configDirectory));
3985
3965
  }
3986
- const renderer = options.host === "bitfun" ? await import(pathToFileURL(join5(stagedRoot, "dist/install/resources.js")).href) : undefined;
3966
+ const renderer = options.host === "bitfun" ? await import(pathToFileURL(join4(stagedRoot, "dist/install/resources.js")).href) : undefined;
3987
3967
  const selectedCommandFiles = renderer ? Object.fromEntries(Object.entries(renderer.renderResources(renderer.selectResources(plan.modules), manifest.version)).filter(([path2]) => path2.startsWith("bitfun/command/")).map(([path2, content]) => [path2.slice("bitfun/".length), String(content)])) : undefined;
3988
3968
  const commandFilesBefore = selectedCommandFiles ? Object.fromEntries(await Promise.all([...new Set([
3989
3969
  ...Object.keys(previous?.commandFiles ?? {}),
@@ -4000,17 +3980,28 @@ async function install(options) {
4000
3980
  await writeJson(paths.journalPath, { ...state, phase: "registering", marketplace, marketplacePath, pluginRoot, commandFilesBefore, commandDirectory: paths.commandDirectory });
4001
3981
  if (options.host !== "claude-code") {
4002
3982
  await mkdir3(paths.configDirectory, { recursive: true });
4003
- await command(["npm", "install", "--prefix", paths.configDirectory, "--ignore-scripts", "--install-links", "--no-audit", "--no-fund", stagedRoot]);
3983
+ await command([
3984
+ "npm",
3985
+ "install",
3986
+ "--prefix",
3987
+ paths.configDirectory,
3988
+ "--ignore-scripts",
3989
+ "--no-audit",
3990
+ "--no-fund",
3991
+ ...options.source ? ["--install-links", stagedRoot] : ["--save-exact", `@bitfun-vsl/plugin@${manifest.version}`]
3992
+ ]);
4004
3993
  await verifyPackage(currentRoot);
3994
+ if (!options.source)
3995
+ await writeJson(join4(currentRoot, "assets/runtime.json"), runtime);
4005
3996
  if (await textOrUndefined(plan.configPath) !== configBefore)
4006
3997
  throw new Error("Host configuration changed during dependency installation");
4007
3998
  const parsed = await readObject(plan.configPath);
4008
3999
  const entries = Array.isArray(parsed.plugin) ? parsed.plugin : [];
4009
- const entry = pathToFileURL(join5(currentRoot, hostEntry(options.host))).href;
4000
+ const entry = pathToFileURL(join4(currentRoot, hostEntry(options.host))).href;
4010
4001
  await patchJson(plan.configPath, ["plugin"], [...entries.filter((item) => !isVslEntry(entrySpec(item))), entry]);
4011
4002
  }
4012
4003
  if (options.host === "claude-code") {
4013
- await writeJson(join5(marketplacePath, ".claude-plugin/marketplace.json"), {
4004
+ await writeJson(join4(marketplacePath, ".claude-plugin/marketplace.json"), {
4014
4005
  name: marketplace,
4015
4006
  owner: { name: "VSL" },
4016
4007
  plugins: [{
@@ -4050,7 +4041,7 @@ async function install(options) {
4050
4041
  crBinary: runtime.crBinary,
4051
4042
  files: await inventory(installedRoot),
4052
4043
  configPath: plan.configPath,
4053
- entry: options.host !== "claude-code" ? pathToFileURL(join5(currentRoot, hostEntry(options.host))).href : `vsl@${marketplace}`,
4044
+ entry: options.host !== "claude-code" ? pathToFileURL(join4(currentRoot, hostEntry(options.host))).href : `vsl@${marketplace}`,
4054
4045
  marketplace: options.host === "claude-code" ? marketplace : undefined,
4055
4046
  marketplacePath: options.host === "claude-code" ? marketplacePath : undefined,
4056
4047
  sourceFiles: await inventory(stagedRoot),
@@ -4091,7 +4082,7 @@ async function doctor(options) {
4091
4082
  };
4092
4083
  const changed = await changedFiles(receipt);
4093
4084
  const config = await readObject(receipt.configPath);
4094
- const dependency = options.host !== "claude-code" ? dependencyOf(await readObject(join5(paths.configDirectory, "package.json"))) : undefined;
4085
+ const dependency = options.host !== "claude-code" ? dependencyOf(await readObject(join4(paths.configDirectory, "package.json"))) : undefined;
4095
4086
  const commandChanges = receipt.commandDirectory ? (await Promise.all(Object.entries(receipt.commandFiles ?? {}).map(async ([path2, hash]) => digest(await textOrUndefined(inside(receipt.commandDirectory, path2)) ?? "") === hash ? undefined : `commands/${path2}`))).filter((path2) => !!path2) : [];
4096
4087
  changed.push(...commandChanges);
4097
4088
  const registration = options.host !== "claude-code" ? Array.isArray(config.plugin) && config.plugin.filter((item) => isVslEntry(entrySpec(item))).length === 1 && config.plugin.includes(receipt.entry) && dependency === receipt.dependency : await claudeInstalledRoot(paths.configDirectory, receipt.entry, receipt.pluginVersion).then((root) => root === receipt.packageRoot).catch(() => false);
@@ -4145,7 +4136,7 @@ async function uninstall(options, dryRun = false) {
4145
4136
  configPath: receipt.configPath,
4146
4137
  commandDirectory: receipt.commandDirectory,
4147
4138
  commandFilesBefore: receipt.commandDirectory ? Object.fromEntries(await Promise.all(Object.keys(receipt.commandFiles ?? {}).map(async (path2) => [path2, await textOrUndefined(inside(receipt.commandDirectory, path2)) ?? null]))) : undefined,
4148
- marketplaceBefore: receipt.marketplacePath ? await textOrUndefined(join5(receipt.marketplacePath, ".claude-plugin/marketplace.json")) : undefined
4139
+ marketplaceBefore: receipt.marketplacePath ? await textOrUndefined(join4(receipt.marketplacePath, ".claude-plugin/marketplace.json")) : undefined
4149
4140
  });
4150
4141
  if (receipt.host !== "claude-code") {
4151
4142
  const config = await readObject(receipt.configPath);
@@ -4160,11 +4151,11 @@ async function uninstall(options, dryRun = false) {
4160
4151
  "--install-links",
4161
4152
  "--no-audit",
4162
4153
  "--no-fund",
4163
- receipt.originalDependency.startsWith("file:") ? resolve5(receipt.configDirectory, receipt.originalDependency.slice(5)) : `@bitfun-vsl/plugin@${receipt.originalDependency}`
4154
+ receipt.originalDependency.startsWith("file:") ? resolve4(receipt.configDirectory, receipt.originalDependency.slice(5)) : `@bitfun-vsl/plugin@${receipt.originalDependency}`
4164
4155
  ]);
4165
- await patchJson(join5(receipt.configDirectory, "package.json"), ["dependencies", "@bitfun-vsl/plugin"], receipt.originalDependency);
4156
+ await patchJson(join4(receipt.configDirectory, "package.json"), ["dependencies", "@bitfun-vsl/plugin"], receipt.originalDependency);
4166
4157
  if (receipt.originalRuntime)
4167
- await Bun.write(join5(receipt.packageRoot, "assets/runtime.json"), receipt.originalRuntime);
4158
+ await Bun.write(join4(receipt.packageRoot, "assets/runtime.json"), receipt.originalRuntime);
4168
4159
  }
4169
4160
  if (!receipt.originalDependency)
4170
4161
  await command(["npm", "uninstall", "--prefix", receipt.configDirectory, "--ignore-scripts", "--no-audit", "--no-fund", "@bitfun-vsl/plugin"]);
@@ -4175,7 +4166,7 @@ async function uninstall(options, dryRun = false) {
4175
4166
  }
4176
4167
  if (receipt.commandDirectory)
4177
4168
  await restoreCommands(receipt.commandDirectory, Object.fromEntries(Object.keys(receipt.commandFiles ?? {}).map((path2) => [path2, receipt.originalCommandFiles?.[path2] ?? null])));
4178
- await rename(paths.receiptPath, join5(paths.instance, `uninstalled-${Date.now()}.json`));
4169
+ await rename(paths.receiptPath, join4(paths.instance, `uninstalled-${Date.now()}.json`));
4179
4170
  await rm(paths.journalPath);
4180
4171
  return { removed: true, host: receipt.host, restartRequired: true };
4181
4172
  } finally {
@@ -4199,15 +4190,15 @@ async function recover(options) {
4199
4190
  if (!Array.isArray(entries))
4200
4191
  throw new Error("Invalid host plugin configuration; manual recovery required");
4201
4192
  const restoredEntries = previous ? [previous.entry] : Array.isArray(journal.originalEntries) ? journal.originalEntries : [];
4202
- const foreign = entries.filter((entry) => isVslEntry(entrySpec(entry)) && !restoredEntries.includes(entry) && entry !== pathToFileURL(join5(paths.configDirectory, "node_modules/@bitfun-vsl/plugin", hostEntry(options.host))).href);
4193
+ const foreign = entries.filter((entry) => isVslEntry(entrySpec(entry)) && !restoredEntries.includes(entry) && entry !== pathToFileURL(join4(paths.configDirectory, "node_modules/@bitfun-vsl/plugin", hostEntry(options.host))).href);
4203
4194
  if (foreign.length)
4204
4195
  throw new Error("VSL registration changed externally; preserving recovery evidence");
4205
4196
  const dependency = previous?.dependency ?? (typeof journal.dependencyBefore === "string" ? journal.dependencyBefore : undefined);
4206
4197
  if (dependency) {
4207
- await command(["npm", "install", "--prefix", paths.configDirectory, "--ignore-scripts", "--install-links", "--no-audit", "--no-fund", dependency.startsWith("file:") ? resolve5(paths.configDirectory, dependency.slice(5)) : `@bitfun-vsl/plugin@${dependency}`]);
4208
- await patchJson(join5(paths.configDirectory, "package.json"), ["dependencies", "@bitfun-vsl/plugin"], dependency);
4198
+ await command(["npm", "install", "--prefix", paths.configDirectory, "--ignore-scripts", "--install-links", "--no-audit", "--no-fund", dependency.startsWith("file:") ? resolve4(paths.configDirectory, dependency.slice(5)) : `@bitfun-vsl/plugin@${dependency}`]);
4199
+ await patchJson(join4(paths.configDirectory, "package.json"), ["dependencies", "@bitfun-vsl/plugin"], dependency);
4209
4200
  if (!previous && typeof journal.originalRuntime === "string")
4210
- await Bun.write(join5(paths.configDirectory, "node_modules/@bitfun-vsl/plugin/assets/runtime.json"), journal.originalRuntime);
4201
+ await Bun.write(join4(paths.configDirectory, "node_modules/@bitfun-vsl/plugin/assets/runtime.json"), journal.originalRuntime);
4211
4202
  }
4212
4203
  if (!dependency)
4213
4204
  await command(["npm", "uninstall", "--prefix", paths.configDirectory, "--ignore-scripts", "--no-audit", "--no-fund", "@bitfun-vsl/plugin"]);
@@ -4219,9 +4210,9 @@ async function recover(options) {
4219
4210
  throw new Error("Missing marketplace recovery identity");
4220
4211
  const entry = `vsl@${marketplace}`;
4221
4212
  if (typeof journal.marketplaceBefore === "string") {
4222
- await Bun.write(join5(paths.instance, "marketplace/.claude-plugin/marketplace.json"), journal.marketplaceBefore);
4213
+ await Bun.write(join4(paths.instance, "marketplace/.claude-plugin/marketplace.json"), journal.marketplaceBefore);
4223
4214
  if (journal.phase === "uninstalling")
4224
- await command(["claude", "plugin", "marketplace", "add", join5(paths.instance, "marketplace"), "--scope", "user"], claudeEnvironment(paths.configDirectory));
4215
+ await command(["claude", "plugin", "marketplace", "add", join4(paths.instance, "marketplace"), "--scope", "user"], claudeEnvironment(paths.configDirectory));
4225
4216
  await command(["claude", "plugin", "marketplace", "update", marketplace], claudeEnvironment(paths.configDirectory));
4226
4217
  await command(["claude", "plugin", journal.phase === "uninstalling" ? "install" : "update", entry, "--scope", "user"], claudeEnvironment(paths.configDirectory));
4227
4218
  }
@@ -4247,10 +4238,10 @@ async function recover(options) {
4247
4238
  }
4248
4239
  }
4249
4240
  async function verifyPackage(root) {
4250
- const manifest = await Bun.file(join5(root, "assets/install-manifest.json")).json();
4241
+ const manifest = await Bun.file(join4(root, "assets/install-manifest.json")).json();
4251
4242
  if (manifest.schemaVersion !== 1 || !manifest.buildId || !manifest.files || !Array.isArray(manifest.modules))
4252
4243
  throw new Error("Invalid VSL install manifest");
4253
- const pkg = await Bun.file(join5(root, "package.json")).json();
4244
+ const pkg = await Bun.file(join4(root, "package.json")).json();
4254
4245
  if (pkg.name !== "@bitfun-vsl/plugin" || pkg.version !== manifest.version)
4255
4246
  throw new Error("VSL package identity differs from install manifest");
4256
4247
  for (const required of ["dist/hosts/deveco/plugin.js", "dist/hosts/bitfun-kernel/plugin.js", "dist/index.js", "dist/install/resources.js", "assets/claude-code/scripts/mcp-server.js", "assets/claude-code/.mcp.json", "assets/build.json"]) {
@@ -4266,8 +4257,8 @@ async function command(args, env = process.env) {
4266
4257
  const executable = Bun.which(args[0], { PATH: env.PATH });
4267
4258
  if (!executable)
4268
4259
  throw new Error(`Required command not found: ${args[0]}`);
4269
- const nativeClaude = join5(dirname3(executable), "node_modules/@anthropic-ai/claude-code/bin/claude.exe");
4270
- const npmCli = join5(dirname3(executable), "node_modules/npm/bin/npm-cli.js");
4260
+ const nativeClaude = join4(dirname2(executable), "node_modules/@anthropic-ai/claude-code/bin/claude.exe");
4261
+ const npmCli = join4(dirname2(executable), "node_modules/npm/bin/npm-cli.js");
4271
4262
  const invocation = process.platform === "win32" && /\.(cmd|bat)$/i.test(executable) ? args[0] === "npm" && await Bun.file(npmCli).exists() ? [Bun.which("node") ?? process.execPath, npmCli] : args[0] === "claude" && await Bun.file(nativeClaude).exists() ? [nativeClaude] : undefined : [executable];
4272
4263
  if (!invocation)
4273
4264
  throw new Error(`Cannot safely resolve command shim: ${executable}; use a native CLI installation`);
@@ -4296,11 +4287,11 @@ async function readReceipt(path2) {
4296
4287
  return value;
4297
4288
  }
4298
4289
  async function devecoConfigPath(root) {
4299
- const candidates = await Promise.all(["deveco.jsonc", "deveco.json"].map(async (name) => await Bun.file(join5(root, name)).exists() ? join5(root, name) : undefined));
4290
+ const candidates = await Promise.all(["deveco.jsonc", "deveco.json"].map(async (name) => await Bun.file(join4(root, name)).exists() ? join4(root, name) : undefined));
4300
4291
  const found = candidates.filter((path2) => !!path2);
4301
4292
  if (found.length > 1)
4302
4293
  throw new Error("Both deveco.json and deveco.jsonc exist; choose one effective configuration before installing");
4303
- return found[0] ?? join5(root, "deveco.jsonc");
4294
+ return found[0] ?? join4(root, "deveco.jsonc");
4304
4295
  }
4305
4296
  function isVslEntry(value) {
4306
4297
  return value === "@bitfun-vsl/plugin" || value.startsWith("@bitfun-vsl/plugin/") || value.startsWith("@bitfun-vsl/plugin@") || value.startsWith("file:") && /\/@bitfun-vsl\/plugin\/dist\/(?:index\.js|hosts\/(?:deveco|bitfun-kernel)\/plugin\.js)$/.test(decodeURI(value).replaceAll("\\", "/"));
@@ -4333,7 +4324,7 @@ async function restoreCommands(root, files) {
4333
4324
  await rm(target, { force: true });
4334
4325
  continue;
4335
4326
  }
4336
- await mkdir3(dirname3(target), { recursive: true });
4327
+ await mkdir3(dirname2(target), { recursive: true });
4337
4328
  await Bun.write(target, content);
4338
4329
  }
4339
4330
  }
@@ -4349,7 +4340,7 @@ function dependencyOf(config) {
4349
4340
  return value;
4350
4341
  }
4351
4342
  async function inventory(root) {
4352
- return Object.fromEntries(await Promise.all((await filesUnder(root)).map(async (path2) => [path2, digest(await Bun.file(join5(root, path2)).bytes())])));
4343
+ return Object.fromEntries(await Promise.all((await filesUnder(root)).map(async (path2) => [path2, digest(await Bun.file(join4(root, path2)).bytes())])));
4353
4344
  }
4354
4345
  async function changedFiles(receipt) {
4355
4346
  const current = await inventory(receipt.packageRoot).catch(() => ({}));
@@ -4365,7 +4356,7 @@ async function assertOwnedFiles(receipt) {
4365
4356
  throw new Error(`Managed files were modified; preserving them: ${path2}`);
4366
4357
  }
4367
4358
  }
4368
- const sourceRoot = join5(receipt.releaseRoot, "node_modules/@bitfun-vsl/plugin");
4359
+ const sourceRoot = join4(receipt.releaseRoot, "node_modules/@bitfun-vsl/plugin");
4369
4360
  const current = await inventory(sourceRoot);
4370
4361
  if (JSON.stringify(current) !== JSON.stringify(receipt.sourceFiles))
4371
4362
  throw new Error("Staged release was modified; preserving installation");
@@ -4386,7 +4377,7 @@ async function textOrUndefined(path2) {
4386
4377
  return await Bun.file(path2).exists() ? Bun.file(path2).text() : undefined;
4387
4378
  }
4388
4379
  async function writeJson(path2, value) {
4389
- await mkdir3(dirname3(path2), { recursive: true });
4380
+ await mkdir3(dirname2(path2), { recursive: true });
4390
4381
  const temporary = `${path2}.${crypto.randomUUID()}.tmp`;
4391
4382
  await Bun.write(temporary, `${JSON.stringify(value, null, 2)}
4392
4383
  `);
@@ -4396,7 +4387,7 @@ async function patchJson(path2, keys, value) {
4396
4387
  const raw = await textOrUndefined(path2) ?? `{}
4397
4388
  `;
4398
4389
  await readObject(path2);
4399
- await mkdir3(dirname3(path2), { recursive: true });
4390
+ await mkdir3(dirname2(path2), { recursive: true });
4400
4391
  await Bun.write(path2, applyEdits(raw, modify(raw, keys, value, { formattingOptions: { insertSpaces: true, tabSize: 2 } })));
4401
4392
  }
4402
4393
  async function acquireLock(path2) {
@@ -4421,7 +4412,7 @@ async function acquireLock(path2) {
4421
4412
  }
4422
4413
  async function safeRemove(root, target) {
4423
4414
  const checked = inside(root, target);
4424
- if (checked === resolve5(root))
4415
+ if (checked === resolve4(root))
4425
4416
  throw new Error("Refusing to remove installation root");
4426
4417
  await rm(checked, { recursive: true, force: true });
4427
4418
  }
@@ -4446,7 +4437,7 @@ async function main(args = process.argv.slice(2)) {
4446
4437
  console.log(`vsl <init|update|doctor|uninstall|recover> [--host deveco|claude-code|bitfun] [--modules id,id] [--package path] [--config-dir path] [--command-dir path] [--state-dir path] [--cr-bin path] [--dry-run] [--yes] [--json]
4447
4438
 
4448
4439
  vsl init: \u9009\u62E9\u5BBF\u4E3B \u2192 \u9009\u62E9\u6A21\u5757\uFF08\u9ED8\u8BA4\u5168\u9009\uFF09\u2192 \u786E\u8BA4\u5B89\u88C5\u3002
4449
- \u5BBF\u4E3B\u652F\u6301\u591A\u9009\uFF0C\u4E5F\u53EF\u91CD\u590D\u4F20\u5165 --host\u3002\u9700\u8981 Bun\u3001npm\uFF1BClaude \u5B89\u88C5\u8FD8\u9700\u8981 Claude CLI\u3002`);
4440
+ \u5BBF\u4E3B\u652F\u6301\u591A\u9009\uFF0C\u4E5F\u53EF\u91CD\u590D\u4F20\u5165 --host\u3002\u9ED8\u8BA4\u5B89\u88C5\u6765\u6E90\u4E3A npm \u5B98\u65B9\u6E90\u7684 @bitfun-vsl/plugin@<CLI \u7248\u672C>\uFF1B--package \u6307\u5B9A\u672C\u5730\u6784\u5EFA\u7684 tgz\uFF0C\u7528\u4E8E\u5F00\u53D1\u9A8C\u8BC1\u3002\u9700\u8981 Bun\u3001npm\uFF1BClaude \u5B89\u88C5\u8FD8\u9700\u8981 Claude CLI\u3002`);
4450
4441
  return;
4451
4442
  }
4452
4443
  const action = args[0];
@@ -4514,51 +4505,82 @@ VSL v${build_default.version} \u5B89\u88C5\u5411\u5BFC
4514
4505
  console.log(`
4515
4506
  \u5BBF\u4E3B\uFF1A${hosts.map((host) => hostChoices.find((choice) => choice.value === host).name).join("\u3001")}`);
4516
4507
  if (installing)
4517
- console.log(`\u6A21\u5757\uFF1A${(modules ?? selectResources().modules.map((module) => module.id)).join("\u3001")}
4518
- \u5B89\u88C5\u6765\u6E90\uFF1A${values.get("--package")?.[0] ?? "\u5F53\u524D VSL \u5305"}`);
4508
+ console.log(`\u6A21\u5757\uFF1A${(modules ?? selectResources().modules.map((module) => module.id)).join("\u3001")} \uFF5C \u6765\u6E90\uFF1A${values.get("--package")?.[0] ? "\u672C\u5730\u5305" : `npm @bitfun-vsl/plugin@${build_default.version}`}`);
4519
4509
  }
4520
4510
  if (!flags.has("--yes") && !interactive)
4521
4511
  throw new Error("Non-interactive changes require --yes");
4522
- if (!flags.has("--yes") && !await dist_default5({ message: installing ? "\u662F\u5426\u6267\u884C\u5B89\u88C5\uFF1F" : action === "uninstall" ? "\u662F\u5426\u6267\u884C\u5378\u8F7D\uFF1F" : "\u662F\u5426\u6062\u590D\u5B89\u88C5\uFF1F", default: true })) {
4512
+ if (!flags.has("--yes") && !await dist_default5({ message: installing ? "\u7B2C\u4E09\u6B65\uFF1A\u786E\u8BA4\u6309\u4EE5\u4E0A\u9009\u62E9\u5B89\u88C5\uFF1F" : action === "uninstall" ? "\u7B2C\u4E09\u6B65\uFF1A\u786E\u8BA4\u5378\u8F7D\uFF1F" : "\u7B2C\u4E09\u6B65\uFF1A\u786E\u8BA4\u6062\u590D\u5B89\u88C5\uFF1F", default: true })) {
4523
4513
  console.log("\u5DF2\u53D6\u6D88\uFF0C\u672A\u4FEE\u6539\u5BBF\u4E3B\u914D\u7F6E\u3002");
4524
4514
  return;
4525
4515
  }
4526
4516
  }
4527
4517
  const results = [];
4528
4518
  for (const option of options) {
4519
+ const label = hostChoices.find((choice) => choice.value === option.host).name;
4529
4520
  try {
4530
4521
  if (!flags.has("--json"))
4531
4522
  console.log(`
4532
- \u6B63\u5728\u5904\u7406 ${hostChoices.find((choice) => choice.value === option.host).name}\u2026`);
4523
+ \u6B63\u5728\u5904\u7406 ${label}\u2026`);
4533
4524
  const result = action === "doctor" ? await doctor(option) : action === "recover" ? await recover(option) : action === "uninstall" ? await uninstall(option) : await install(option);
4534
4525
  results.push(result);
4535
4526
  if ("configured" in result && !result.configured || "recoveryRequired" in result && result.recoveryRequired)
4536
4527
  process.exitCode = 1;
4537
- if (!flags.has("--json")) {
4538
- console.log("configured" in result ? result.configured ? "\u5B89\u88C5\u914D\u7F6E\u68C0\u67E5\u901A\u8FC7\u3002" : "\u5C1A\u672A\u6B63\u786E\u914D\u7F6E\uFF0C\u8BF7\u68C0\u67E5\u5B89\u88C5\u72B6\u6001\u3002" : JSON.stringify(result));
4539
- if ("packageRoot" in result)
4540
- console.log(`\u63D2\u4EF6\u4F4D\u7F6E\uFF1A${result.packageRoot}`);
4541
- if ("buildId" in result)
4542
- console.log(`\u7248\u672C\uFF1A${result.version}
4543
- \u6784\u5EFA\uFF1A${result.buildId}`);
4544
- if ("modules" in result && result.modules?.includes("code-review"))
4545
- console.log(result.crBinary ? `CR \u7A0B\u5E8F\uFF1A${result.crBinary}` : "\u672A\u68C0\u6D4B\u5230 CR \u539F\u751F\u7A0B\u5E8F\uFF1B\u8BF7\u5B89\u88C5\u540E\u91CD\u65B0\u8FD0\u884C init\uFF0C\u6216\u4F7F\u7528 --cr-bin \u6307\u5B9A\u5176\u7EDD\u5BF9\u8DEF\u5F84\u3002");
4546
- if ("configured" in result && result.configured)
4547
- console.log("\u8BF7\u91CD\u542F\u5BBF\u4E3B\uFF0C\u5728\u5BBF\u4E3B\u4E2D\u8C03\u7528 vsl_runtime_info \u6838\u5BF9\u6784\u5EFA\u4E0E\u6A21\u5757\uFF0C\u518D\u89E6\u53D1\u5BF9\u5E94 command\u3002");
4548
- if (option.host === "bitfun" && "configured" in result && result.configured)
4549
- console.log("BitFun \u8FD8\u9700\u542F\u7528 OpenCode \u517C\u5BB9\uFF1Abitfun config external set-enabled true --scope global\uFF1Bbitfun config external set-mode recommended --ecosystem opencode --scope global\u3002\u5728\u4F1A\u8BDD\u4E2D\u7528 /extensions \u68C0\u67E5\u6765\u6E90\u72B6\u6001\u3002");
4550
- }
4528
+ if (!flags.has("--json"))
4529
+ printOutcome(action, label, option.host, result);
4551
4530
  } catch (error) {
4552
4531
  const message = error instanceof Error ? error.message : String(error);
4553
4532
  results.push({ host: option.host, failed: true, error: message });
4554
4533
  process.exitCode = 1;
4555
4534
  if (!flags.has("--json"))
4556
- console.error(`${option.host} \u5931\u8D25\uFF1A${message}`);
4535
+ console.error(`\u2717 ${label} ${action === "doctor" ? "\u68C0\u67E5" : action === "uninstall" ? "\u5378\u8F7D" : action === "recover" ? "\u6062\u590D" : "\u5B89\u88C5"}\u5931\u8D25\uFF1A${message}`);
4557
4536
  }
4558
4537
  }
4559
4538
  if (flags.has("--json"))
4560
4539
  console.log(JSON.stringify(results, null, 2));
4561
4540
  }
4541
+ function printOutcome(action, label, host, result) {
4542
+ if (action === "doctor") {
4543
+ console.log("configured" in result && result.configured ? "\u5B89\u88C5\u914D\u7F6E\u68C0\u67E5\u901A\u8FC7\u3002" : "\u5C1A\u672A\u6B63\u786E\u914D\u7F6E\uFF0C\u8BF7\u68C0\u67E5\u5B89\u88C5\u72B6\u6001\u3002");
4544
+ if ("packageRoot" in result)
4545
+ console.log(`\u63D2\u4EF6\u4F4D\u7F6E\uFF1A${result.packageRoot}`);
4546
+ if ("buildId" in result)
4547
+ console.log(`\u7248\u672C\uFF1A${result.version}
4548
+ \u6784\u5EFA\uFF1A${result.buildId}`);
4549
+ if ("modules" in result && result.modules?.includes("code-review"))
4550
+ console.log(result.crBinary ? `CR \u7A0B\u5E8F\uFF1A${result.crBinary}` : "\u672A\u68C0\u6D4B\u5230 CR \u539F\u751F\u7A0B\u5E8F\uFF1B\u8BF7\u5B89\u88C5\u540E\u91CD\u65B0\u8FD0\u884C init\uFF0C\u6216\u4F7F\u7528 --cr-bin \u6307\u5B9A\u5176\u7EDD\u5BF9\u8DEF\u5F84\u3002");
4551
+ if ("recoveryRequired" in result && result.recoveryRequired)
4552
+ console.log("\u5B58\u5728\u672A\u5B8C\u6210\u7684\u5B89\u88C5\u4E8B\u52A1\uFF0C\u8BF7\u5148\u8FD0\u884C vsl recover\u3002");
4553
+ else if ("configured" in result && result.configured)
4554
+ console.log("\u91CD\u542F\u5BBF\u4E3B\u540E\u7528 vsl_runtime_info \u6838\u5BF9\u6784\u5EFA\u4E0E\u6A21\u5757\u3002");
4555
+ return;
4556
+ }
4557
+ if ("configured" in result) {
4558
+ const verb = action === "update" ? "\u66F4\u65B0" : "\u5B89\u88C5";
4559
+ if (!result.configured) {
4560
+ console.log(`\u2717 ${label} ${verb}\u672A\u901A\u8FC7\u9A8C\u8BC1\uFF0C\u7528 vsl doctor --host ${host} --json \u67E5\u770B\u8BCA\u65AD\u3002`);
4561
+ return;
4562
+ }
4563
+ if ("unchanged" in result && result.unchanged) {
4564
+ console.log(`\u2713 ${label} \u5DF2\u662F\u6700\u65B0\u5B89\u88C5\uFF08v${result.version}\uFF09\uFF0C\u65E0\u9700\u6539\u52A8\u3002`);
4565
+ return;
4566
+ }
4567
+ console.log(`\u2713 ${label} ${verb}\u6210\u529F\uFF08v${result.version}\uFF09\uFF0C\u91CD\u542F\u5BBF\u4E3B\u540E\u751F\u6548\u3002`);
4568
+ if (result.modules?.includes("code-review") && !result.crBinary)
4569
+ console.log("\u63D0\u793A\uFF1A\u672A\u68C0\u6D4B\u5230 CR \u539F\u751F\u7A0B\u5E8F\uFF0C\u53EF\u7528 --cr-bin \u6307\u5B9A\u7EDD\u5BF9\u8DEF\u5F84\u540E\u91CD\u65B0 init\u3002");
4570
+ if (host === "bitfun")
4571
+ console.log("\u63D0\u793A\uFF1ABitFun \u547D\u4EE4\u9700\u8981 OpenCode \u517C\u5BB9\u6765\u6E90\uFF0C\u5728\u4F1A\u8BDD\u4E2D\u7528 /extensions \u542F\u7528\u3002");
4572
+ return;
4573
+ }
4574
+ if ("removed" in result) {
4575
+ console.log(result.removed ? `\u2713 ${label} \u5DF2\u5378\u8F7D\uFF0C\u91CD\u542F\u5BBF\u4E3B\u540E\u751F\u6548\u3002` : `\xB7 ${label} \u6CA1\u6709\u53D7\u7BA1\u5B89\u88C5\uFF0C\u672A\u505A\u6539\u52A8\u3002`);
4576
+ return;
4577
+ }
4578
+ if ("recovered" in result) {
4579
+ console.log(result.recovered ? `\u2713 ${label} \u5DF2\u6062\u590D\u5230\u5B89\u88C5\u524D\u72B6\u6001\uFF0C\u53EF\u91CD\u65B0\u8FD0\u884C init\u3002` : `\xB7 ${label} \u6CA1\u6709\u672A\u5B8C\u6210\u7684\u5B89\u88C5\uFF0C\u672A\u505A\u6539\u52A8\u3002`);
4580
+ return;
4581
+ }
4582
+ console.log(JSON.stringify(result));
4583
+ }
4562
4584
  if (import.meta.main)
4563
4585
  await main().catch((error) => {
4564
4586
  if (error instanceof Error && error.name === "ExitPromptError") {
@@ -8,8 +8,8 @@ import { dirname, join, resolve } from "path";
8
8
  import { fileURLToPath } from "url";
9
9
  // assets/build.json
10
10
  var build_default = {
11
- version: "0.0.1",
12
- buildId: "bbceff2246e5fb0e4b93bb05081457dbc113400b937c6148764573618d8534b5"
11
+ version: "0.0.3",
12
+ buildId: "ef337ee398fc256793104c4499ace48c18f0fafa0cbcc08b37bab00956293888"
13
13
  };
14
14
 
15
15
  // src/runtime.ts
@@ -3,7 +3,7 @@
3
3
  var package_default = {
4
4
  $schema: "https://json.schemastore.org/package.json",
5
5
  name: "@bitfun-vsl/plugin",
6
- version: "0.0.1",
6
+ version: "0.0.3",
7
7
  main: "./dist/index.js",
8
8
  types: "./dist/index.d.ts",
9
9
  type: "module",
@@ -559,8 +559,8 @@ import { dirname, join as join2, resolve as resolve2 } from "path";
559
559
  import { fileURLToPath } from "url";
560
560
  // assets/build.json
561
561
  var build_default = {
562
- version: "0.0.1",
563
- buildId: "bbceff2246e5fb0e4b93bb05081457dbc113400b937c6148764573618d8534b5"
562
+ version: "0.0.3",
563
+ buildId: "ef337ee398fc256793104c4499ace48c18f0fafa0cbcc08b37bab00956293888"
564
564
  };
565
565
 
566
566
  // src/runtime.ts
@@ -8,8 +8,8 @@ import { dirname, join, resolve } from "path";
8
8
  import { fileURLToPath } from "url";
9
9
  // assets/build.json
10
10
  var build_default = {
11
- version: "0.0.1",
12
- buildId: "bbceff2246e5fb0e4b93bb05081457dbc113400b937c6148764573618d8534b5"
11
+ version: "0.0.3",
12
+ buildId: "ef337ee398fc256793104c4499ace48c18f0fafa0cbcc08b37bab00956293888"
13
13
  };
14
14
 
15
15
  // src/runtime.ts
package/dist/index.js CHANGED
@@ -8,8 +8,8 @@ import { dirname, join, resolve } from "path";
8
8
  import { fileURLToPath } from "url";
9
9
  // assets/build.json
10
10
  var build_default = {
11
- version: "0.0.1",
12
- buildId: "bbceff2246e5fb0e4b93bb05081457dbc113400b937c6148764573618d8534b5"
11
+ version: "0.0.3",
12
+ buildId: "ef337ee398fc256793104c4499ace48c18f0fafa0cbcc08b37bab00956293888"
13
13
  };
14
14
 
15
15
  // src/runtime.ts
@@ -16,10 +16,13 @@ export declare function planInstallation(options: InstallOptions): Promise<{
16
16
  modules: string[];
17
17
  configDirectory: string;
18
18
  sourceIdentity: {
19
- sha256: string;
20
- } | {
21
19
  version: string;
22
20
  buildId: string;
21
+ sha256?: undefined;
22
+ } | {
23
+ version?: undefined;
24
+ buildId?: undefined;
25
+ sha256: string;
23
26
  };
24
27
  commandDirectory: string | undefined;
25
28
  configPath: string;
@@ -32,6 +35,8 @@ export declare function planInstallation(options: InstallOptions): Promise<{
32
35
  verified: boolean;
33
36
  }>;
34
37
  export declare function install(options: InstallOptions): Promise<{
38
+ version?: undefined;
39
+ buildId?: undefined;
35
40
  recoveryRequired: boolean;
36
41
  unchanged: boolean;
37
42
  installed: boolean;
@@ -40,8 +45,6 @@ export declare function install(options: InstallOptions): Promise<{
40
45
  verified: boolean;
41
46
  configDirectory: string;
42
47
  host?: undefined;
43
- version?: undefined;
44
- buildId?: undefined;
45
48
  modules?: undefined;
46
49
  installationId?: undefined;
47
50
  crBinary?: undefined;
@@ -68,6 +71,8 @@ export declare function install(options: InstallOptions): Promise<{
68
71
  verified: boolean;
69
72
  runtimeProof: string;
70
73
  } | {
74
+ version?: undefined;
75
+ buildId?: undefined;
71
76
  recoveryRequired: boolean;
72
77
  installed: boolean;
73
78
  configured: boolean;
@@ -75,8 +80,6 @@ export declare function install(options: InstallOptions): Promise<{
75
80
  verified: boolean;
76
81
  configDirectory: string;
77
82
  host?: undefined;
78
- version?: undefined;
79
- buildId?: undefined;
80
83
  modules?: undefined;
81
84
  installationId?: undefined;
82
85
  crBinary?: undefined;
@@ -103,6 +106,8 @@ export declare function install(options: InstallOptions): Promise<{
103
106
  runtimeProof: string;
104
107
  }>;
105
108
  export declare function doctor(options: InstallOptions): Promise<{
109
+ version?: undefined;
110
+ buildId?: undefined;
106
111
  installed: boolean;
107
112
  configured: boolean;
108
113
  loaded: string;
@@ -110,8 +115,6 @@ export declare function doctor(options: InstallOptions): Promise<{
110
115
  configDirectory: string;
111
116
  recoveryRequired: boolean;
112
117
  host?: undefined;
113
- version?: undefined;
114
- buildId?: undefined;
115
118
  modules?: undefined;
116
119
  installationId?: undefined;
117
120
  crBinary?: undefined;
@@ -482,8 +482,8 @@ import { readFileSync, existsSync } from "fs";
482
482
  import { dirname, join as join2, resolve as resolve2 } from "path";
483
483
  // assets/build.json
484
484
  var build_default = {
485
- version: "0.0.1",
486
- buildId: "bbceff2246e5fb0e4b93bb05081457dbc113400b937c6148764573618d8534b5"
485
+ version: "0.0.3",
486
+ buildId: "ef337ee398fc256793104c4499ace48c18f0fafa0cbcc08b37bab00956293888"
487
487
  };
488
488
 
489
489
  // src/runtime.ts
@@ -1,17 +1,28 @@
1
1
  # init 安装与本地验证
2
2
 
3
- 在 `D:\code\spec\vsl\plugin\bitfun_horizon_verify` 执行:
3
+ 正式安装使用 npm 官方包:
4
+
5
+ ```powershell
6
+ npm install -g @bitfun-vsl/plugin
7
+ vsl init
8
+ ```
9
+
10
+ 默认安装来源是 npm 官方源的 `@bitfun-vsl/plugin@<CLI 版本>`,宿主依赖锁定官方版本。
11
+
12
+ 本地构建的开发验证包是辅助方式,在 `D:\code\spec\vsl\plugin\bitfun_horizon_verify` 执行:
4
13
 
5
14
  ```powershell
6
15
  npm pack
7
- bun .\dist\cli\index.js init --package "$PWD\bitfun-vsl-plugin-0.0.1.tgz"
16
+ bun .\dist\cli\index.js init --package "$PWD\bitfun-vsl-plugin-0.0.2.tgz"
8
17
  ```
9
18
 
10
19
  向导只有三个步骤:
11
20
 
12
21
  1. 多选宿主:DevEco Code、Claude Code、BitFun。空格勾选,方向键切换,`a` 全选。
13
22
  2. 多选模块:`trajectory-analysis`、`code-review` 默认全部勾选,可以取消不需要的模块。每个模块自带 Command、Agent、Skill、Tool,不单独选择资源。
14
- 3. 显示宿主、模块与来源摘要,最后确认一次“是否执行安装?”。取消或 Ctrl+C 不执行安装。
23
+ 3. 显示宿主、模块与来源摘要,最后确认一次“第三步:确认按以上选择安装?”。取消或 Ctrl+C 不执行安装。
24
+
25
+ 确认后每个宿主只给一行结论(`✓ BitFun 安装成功(v<版本>),重启宿主后生效。` 或 `✗ BitFun 安装失败:<原因>`),不再打印插件位置、构建号和加载状态。需要细节时执行 `vsl doctor --host <宿主> --json`。
15
26
 
16
27
  `--package` 预设本地包来源,仍显示宿主和模块选择。`--host` / `--modules` 可跳过对应选择。`--yes` 用于自动化,要求显式指定宿主;`--json` 输出诊断 JSON。`--dry-run` 只计算安装信息,不修改配置,也不要求确认。
17
28
 
@@ -37,7 +48,7 @@ bitfun config external status
37
48
 
38
49
  BitFun 命令默认不带 `agent` 前置字段,保持已有适配约束;插件工具对原生主 Agent 不可见,由主 Agent 使用 Task 委派。插件激活仅限本地工作区。
39
50
 
40
- 所有宿主读取同一次模块选择。未通过 init 安装的原生入口仍可使用,未配置模块选择时默认启用全部模块。全局 npm 安装仅提供 CLI,init 才会更新宿主真正读取的依赖。安装不会增加第二份 VSL 注册。
51
+ 所有宿主读取同一次模块选择。未通过 init 安装的原生入口仍可使用,未配置模块选择时默认启用全部模块。全局 npm 安装仅提供 CLI,init 才会更新宿主真正读取的依赖;init 默认从 npm 官方源安装 `@bitfun-vsl/plugin@<CLI 版本>`,`--package` 指定本地构建的 tgz,用于开发验证。安装不会增加第二份 VSL 注册。
41
52
 
42
53
  选择 `code-review` 时,init 自动检测本机原生 CR 并将绝对路径保存到安装运行时配置和收据,避免桌面宿主的 PATH 与终端不同导致 `cr-health` 找不到程序。`--cr-bin <绝对路径>` 可显式指定;检测不到时 CLI 会提示后续配置方法。更新后用 `doctor --json` 查看 `crBinary`,并完整重启宿主。
43
54
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@bitfun-vsl/plugin",
4
- "version": "0.0.1",
4
+ "version": "0.0.3",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
7
7
  "type": "module",