@bitfun-vsl/plugin 0.0.2 → 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 +9 -9
- package/assets/build.json +2 -2
- package/assets/claude-code/.claude-plugin/plugin.json +1 -1
- package/assets/claude-code/scripts/mcp-server.js +3 -3
- package/assets/install-manifest.json +12 -12
- package/dist/cli/index.js +136 -114
- package/dist/hosts/bitfun-kernel/plugin.js +2 -2
- package/dist/hosts/claude-code/index.js +3 -3
- package/dist/hosts/deveco/plugin.js +2 -2
- package/dist/index.js +2 -2
- package/dist/install/index.d.ts +11 -8
- package/dist/plugin/index.js +2 -2
- package/docs/init-installation.md +15 -4
- package/package.json +1 -1
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
|
|
26
|
-
|
|
25
|
+
npm install -g @bitfun-vsl/plugin
|
|
26
|
+
vsl init
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
|
|
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
|
|
33
|
-
|
|
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
|
@@ -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.
|
|
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.
|
|
563
|
-
buildId: "
|
|
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.
|
|
4
|
-
"buildId": "
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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": "
|
|
29
|
+
"dist/index.js": "af01bbe8591b963dbb07389c80e5b8f3420959e9c4be703c781b028726becc25",
|
|
30
30
|
"dist/install/config.d.ts": "860d7a129abc8605ec66793a18ae40f343beac2eb7d70702099acbe110173611",
|
|
31
|
-
"dist/install/index.d.ts": "
|
|
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": "
|
|
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": "
|
|
47
|
-
"assets/claude-code/.claude-plugin/plugin.json": "
|
|
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": "
|
|
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
|
|
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(
|
|
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) =>
|
|
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 =
|
|
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 =
|
|
379
|
-
const stderrFile =
|
|
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
|
|
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.
|
|
3533
|
-
buildId: "
|
|
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
|
|
3533
|
+
import { join as join3, resolve as resolve3 } from "path";
|
|
3554
3534
|
|
|
3555
3535
|
// src/install/resources.ts
|
|
3556
|
-
import { join as
|
|
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 =
|
|
3816
|
-
const part = relative(
|
|
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: ${
|
|
3804
|
+
throw new Error(`Symlink not allowed in managed resources: ${join2(root, entry.name)}`);
|
|
3825
3805
|
if (entry.isDirectory())
|
|
3826
|
-
return (await filesUnder(
|
|
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(
|
|
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" ?
|
|
3851
|
-
const configDirectory =
|
|
3852
|
-
const stateDirectory =
|
|
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 =
|
|
3855
|
-
const commandDirectory =
|
|
3856
|
-
return { commandDirectory, configDirectory, stateDirectory, installationId, instance, receiptPath:
|
|
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 ?
|
|
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) :
|
|
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 =
|
|
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 =
|
|
3915
|
-
if (!previous && options.host !== "claude-code" && await Bun.file(
|
|
3916
|
-
if (!await Bun.file(
|
|
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(
|
|
3921
|
-
const pkg = await Bun.file(
|
|
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(
|
|
3927
|
-
const releaseRoot =
|
|
3928
|
-
const marketplaceBefore = await textOrUndefined(
|
|
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
|
-
|
|
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(
|
|
3944
|
+
await writeJson(join4(stagedRoot, "assets/runtime.json"), runtime);
|
|
3965
3945
|
const marketplace = `vsl-${paths.installationId}`;
|
|
3966
|
-
const marketplacePath =
|
|
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 =
|
|
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(
|
|
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(
|
|
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(
|
|
3982
|
-
await mkdir3(
|
|
3983
|
-
await Bun.write(
|
|
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(
|
|
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([
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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:") ?
|
|
4154
|
+
receipt.originalDependency.startsWith("file:") ? resolve4(receipt.configDirectory, receipt.originalDependency.slice(5)) : `@bitfun-vsl/plugin@${receipt.originalDependency}`
|
|
4164
4155
|
]);
|
|
4165
|
-
await patchJson(
|
|
4156
|
+
await patchJson(join4(receipt.configDirectory, "package.json"), ["dependencies", "@bitfun-vsl/plugin"], receipt.originalDependency);
|
|
4166
4157
|
if (receipt.originalRuntime)
|
|
4167
|
-
await Bun.write(
|
|
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,
|
|
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(
|
|
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:") ?
|
|
4208
|
-
await patchJson(
|
|
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(
|
|
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(
|
|
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",
|
|
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(
|
|
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(
|
|
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 =
|
|
4270
|
-
const npmCli =
|
|
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(
|
|
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] ??
|
|
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(
|
|
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(
|
|
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 =
|
|
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(
|
|
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(
|
|
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 ===
|
|
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 ? "\
|
|
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 ${
|
|
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
|
-
|
|
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(
|
|
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.
|
|
12
|
-
buildId: "
|
|
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.
|
|
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.
|
|
563
|
-
buildId: "
|
|
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.
|
|
12
|
-
buildId: "
|
|
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.
|
|
12
|
-
buildId: "
|
|
11
|
+
version: "0.0.3",
|
|
12
|
+
buildId: "ef337ee398fc256793104c4499ace48c18f0fafa0cbcc08b37bab00956293888"
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
// src/runtime.ts
|
package/dist/install/index.d.ts
CHANGED
|
@@ -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;
|
package/dist/plugin/index.js
CHANGED
|
@@ -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.
|
|
486
|
-
buildId: "
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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
|
|
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
|
|