dsh-llm-codebuddy 1.3.1 → 1.3.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 +2 -0
- package/cli.js +94 -3
- package/package.json +3 -2
package/README.md
CHANGED
package/cli.js
CHANGED
|
@@ -2,12 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
import { copyFileSync, existsSync, mkdtempSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { homedir, tmpdir } from "node:os";
|
|
5
|
-
import {
|
|
5
|
+
import { createRequire } from "node:module";
|
|
6
|
+
import { delimiter, dirname, join, resolve } from "node:path";
|
|
6
7
|
import { spawnSync } from "node:child_process";
|
|
7
8
|
import { parseDocument } from "yaml";
|
|
8
9
|
|
|
9
10
|
const PACKAGE = "dsh-llm-codebuddy";
|
|
11
|
+
const PACKAGE_VERSION = JSON.parse(readFileSync(new URL("./package.json", import.meta.url), "utf8")).version;
|
|
12
|
+
const PACKAGE_SPEC = `${PACKAGE}@${PACKAGE_VERSION}`;
|
|
10
13
|
const PROVIDER_PATH = ["llm-pi-ai", "providers", "codebuddy-cn"];
|
|
14
|
+
const IGNORED_BUILDS = ["@google/genai", "protobufjs"];
|
|
15
|
+
const require = createRequire(import.meta.url);
|
|
11
16
|
|
|
12
17
|
function dshHome() {
|
|
13
18
|
return resolve(process.env.DSH_HOME || join(homedir(), ".dsh"));
|
|
@@ -20,15 +25,74 @@ function profileHasPlugin(home, profile) {
|
|
|
20
25
|
return Boolean(json.dependencies?.[PACKAGE] || json.devDependencies?.[PACKAGE]);
|
|
21
26
|
}
|
|
22
27
|
|
|
28
|
+
function dshEnv() {
|
|
29
|
+
const pnpmPackageDir = dirname(require.resolve("pnpm"));
|
|
30
|
+
const pnpmBinDir = join(dirname(pnpmPackageDir), ".bin");
|
|
31
|
+
const pathKey = Object.keys(process.env).find((key) => key.toLowerCase() === "path") || "PATH";
|
|
32
|
+
return {
|
|
33
|
+
...process.env,
|
|
34
|
+
[pathKey]: `${pnpmBinDir}${delimiter}${process.env[pathKey] || ""}`,
|
|
35
|
+
npm_config_ignore_workspace_root_check: "true",
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
23
39
|
function runDsh(args) {
|
|
24
40
|
const result = spawnSync(process.platform === "win32" ? "dsh.cmd" : "dsh", args, {
|
|
25
41
|
stdio: "inherit",
|
|
26
42
|
shell: process.platform === "win32",
|
|
43
|
+
env: dshEnv(),
|
|
27
44
|
});
|
|
28
45
|
if (result.error) throw result.error;
|
|
29
46
|
if (result.status !== 0) throw new Error(`dsh ${args.join(" ")} 执行失败(退出码 ${result.status})`);
|
|
30
47
|
}
|
|
31
48
|
|
|
49
|
+
function writeYamlDocument(file, document) {
|
|
50
|
+
const temporary = join(dirname(file), `.codebuddy-${process.pid}.tmp`);
|
|
51
|
+
writeFileSync(temporary, String(document), "utf8");
|
|
52
|
+
renameSync(temporary, file);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function withPnpmBuildPolicy(file, action) {
|
|
56
|
+
const document = parseDocument(readFileSync(file, "utf8"));
|
|
57
|
+
if (document.errors.length) throw new Error(`无法解析 ${file}:${document.errors[0].message}`);
|
|
58
|
+
const changes = [];
|
|
59
|
+
for (const packageName of IGNORED_BUILDS) {
|
|
60
|
+
const path = ["allowBuilds", packageName];
|
|
61
|
+
if (typeof document.getIn(path) !== "boolean") {
|
|
62
|
+
changes.push({ packageName, existed: document.hasIn(path), value: document.getIn(path) });
|
|
63
|
+
document.setIn(path, false);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (changes.length) writeYamlDocument(file, document);
|
|
67
|
+
try {
|
|
68
|
+
return action();
|
|
69
|
+
} finally {
|
|
70
|
+
if (changes.length) {
|
|
71
|
+
const current = parseDocument(readFileSync(file, "utf8"));
|
|
72
|
+
for (const change of changes) {
|
|
73
|
+
const path = ["allowBuilds", change.packageName];
|
|
74
|
+
if (change.existed) current.setIn(path, change.value);
|
|
75
|
+
else current.deleteIn(path);
|
|
76
|
+
}
|
|
77
|
+
if (current.getIn(["allowBuilds"])?.items?.length === 0) current.deleteIn(["allowBuilds"]);
|
|
78
|
+
writeYamlDocument(file, current);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function cleanPnpmWorkspace(file) {
|
|
84
|
+
if (!existsSync(file)) return;
|
|
85
|
+
const document = parseDocument(readFileSync(file, "utf8"));
|
|
86
|
+
if (document.errors.length) throw new Error(`无法解析 ${file}:${document.errors[0].message}`);
|
|
87
|
+
const entries = document.getIn(["minimumReleaseAgeExclude"])?.items;
|
|
88
|
+
if (!entries) return;
|
|
89
|
+
const remaining = entries.map((entry) => entry.value).filter((entry) => !String(entry).startsWith(`${PACKAGE}@`));
|
|
90
|
+
if (remaining.length === entries.length) return;
|
|
91
|
+
if (remaining.length) document.setIn(["minimumReleaseAgeExclude"], remaining);
|
|
92
|
+
else document.deleteIn(["minimumReleaseAgeExclude"]);
|
|
93
|
+
writeYamlDocument(file, document);
|
|
94
|
+
}
|
|
95
|
+
|
|
32
96
|
function cleanSettings(file) {
|
|
33
97
|
if (!existsSync(file)) return undefined;
|
|
34
98
|
const source = readFileSync(file, "utf8");
|
|
@@ -48,7 +112,9 @@ function cleanSettings(file) {
|
|
|
48
112
|
|
|
49
113
|
function install() {
|
|
50
114
|
for (const profile of ["web", "headless"]) {
|
|
51
|
-
runDsh(["plugin", "--profile", profile, "
|
|
115
|
+
runDsh(["plugin", "--profile", profile, "list", "--depth", "0"]);
|
|
116
|
+
const workspace = join(dshHome(), "profiles", profile, "pnpm-workspace.yaml");
|
|
117
|
+
withPnpmBuildPolicy(workspace, () => runDsh(["plugin", "--profile", profile, "add", PACKAGE_SPEC]));
|
|
52
118
|
}
|
|
53
119
|
console.log("CodeBuddy Provider 已安装。请重启 DSH 后进行配置。");
|
|
54
120
|
}
|
|
@@ -56,7 +122,11 @@ function install() {
|
|
|
56
122
|
function uninstall(home = dshHome()) {
|
|
57
123
|
const backup = cleanSettings(join(home, "settings.yaml"));
|
|
58
124
|
for (const profile of ["web", "headless"]) {
|
|
59
|
-
|
|
125
|
+
const workspace = join(home, "profiles", profile, "pnpm-workspace.yaml");
|
|
126
|
+
if (profileHasPlugin(home, profile)) {
|
|
127
|
+
withPnpmBuildPolicy(workspace, () => runDsh(["plugin", "--profile", profile, "remove", PACKAGE]));
|
|
128
|
+
}
|
|
129
|
+
cleanPnpmWorkspace(workspace);
|
|
60
130
|
}
|
|
61
131
|
console.log(backup ? `CodeBuddy 配置已清理,备份:${backup}` : "未发现 CodeBuddy Provider 配置。");
|
|
62
132
|
console.log("插件已卸载,API Key 凭据保持不变。请重启 DSH。");
|
|
@@ -72,6 +142,27 @@ function selfTest() {
|
|
|
72
142
|
if (!backup || !existsSync(backup) || result.hasIn(PROVIDER_PATH) || !result.hasIn(["llm-pi-ai", "providers", "opencode-go"])) {
|
|
73
143
|
throw new Error("uninstall settings cleanup self-test failed");
|
|
74
144
|
}
|
|
145
|
+
const workspace = join(root, "pnpm-workspace.yaml");
|
|
146
|
+
writeFileSync(workspace, "packages:\n - .\nallowBuilds:\n '@google/genai': true\n protobufjs: pending\n", "utf8");
|
|
147
|
+
withPnpmBuildPolicy(workspace, () => {
|
|
148
|
+
const active = parseDocument(readFileSync(workspace, "utf8"));
|
|
149
|
+
if (active.getIn(["allowBuilds", "@google/genai"]) !== true || active.getIn(["allowBuilds", "protobufjs"]) !== false) {
|
|
150
|
+
throw new Error("pnpm build policy activation self-test failed");
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
const restored = parseDocument(readFileSync(workspace, "utf8"));
|
|
154
|
+
if (restored.getIn(["allowBuilds", "@google/genai"]) !== true || restored.getIn(["allowBuilds", "protobufjs"]) !== "pending") {
|
|
155
|
+
throw new Error("pnpm build policy self-test failed");
|
|
156
|
+
}
|
|
157
|
+
restored.setIn(["minimumReleaseAgeExclude"], ["other@1.0.0", `${PACKAGE}@1.3.1`]);
|
|
158
|
+
writeYamlDocument(workspace, restored);
|
|
159
|
+
cleanPnpmWorkspace(workspace);
|
|
160
|
+
const cleaned = parseDocument(readFileSync(workspace, "utf8")).getIn(["minimumReleaseAgeExclude"])?.items?.map((entry) => entry.value);
|
|
161
|
+
if (cleaned?.join(",") !== "other@1.0.0") throw new Error("pnpm workspace cleanup self-test failed");
|
|
162
|
+
const pathKey = Object.keys(process.env).find((key) => key.toLowerCase() === "path") || "PATH";
|
|
163
|
+
if (!dshEnv()[pathKey].split(delimiter)[0].endsWith(join("node_modules", ".bin"))) {
|
|
164
|
+
throw new Error("bundled pnpm PATH self-test failed");
|
|
165
|
+
}
|
|
75
166
|
console.log("CLI-SELF-TEST-OK");
|
|
76
167
|
} finally {
|
|
77
168
|
rmSync(root, { recursive: true, force: true });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-llm-codebuddy",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.3",
|
|
4
4
|
"description": "使用 WorkBuddy API Key 为 DeepSeek Harness 接入 CodeBuddy 模型",
|
|
5
5
|
"author": "Axiaohungry",
|
|
6
6
|
"keywords": [
|
|
@@ -49,7 +49,8 @@
|
|
|
49
49
|
"@deepseek-ai/dsh-llm-pi-ai": "0.1.0-rc.6",
|
|
50
50
|
"@deepseek-ai/dsh-settings": "0.1.0-rc.6",
|
|
51
51
|
"@earendil-works/pi-ai": "0.82.1",
|
|
52
|
-
"
|
|
52
|
+
"pnpm": "11.19.0",
|
|
53
|
+
"yaml": "2.9.0"
|
|
53
54
|
},
|
|
54
55
|
"engines": {
|
|
55
56
|
"node": ">=22.19.0"
|