dsh-llm-codebuddy 1.3.4 → 1.3.6
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 +112 -98
- package/cli.js +78 -2
- package/client.js +547 -0
- package/codebuddy-auth.js +383 -0
- package/codebuddy-credits.js +441 -0
- package/codebuddy-web.js +420 -0
- package/index.js +123 -17
- package/package.json +14 -4
- /package/docs/{CodeBuddy → /345/217/215/345/220/221/344/273/243/347/220/206}/350/260/203/347/224/250WorkBuddy-API/345/274/200/345/217/221/346/226/207/346/241/243.md" +0 -0
package/README.md
CHANGED
|
@@ -1,108 +1,141 @@
|
|
|
1
1
|
# DSH CodeBuddy Provider
|
|
2
2
|
|
|
3
|
-
为 DeepSeek Harness(DSH)增加 `CodeBuddy 中国区` Provider
|
|
4
|
-
|
|
3
|
+
为 DeepSeek Harness(DSH)增加 `CodeBuddy 中国区` Provider。插件通过
|
|
4
|
+
WorkBuddy 提供的 API Key,或 CodeBuddy 中国站的网页登录令牌调用模型,并在
|
|
5
|
+
DSH WebUI 中管理模型和认证方式。
|
|
5
6
|
|
|
6
7
|
> [!IMPORTANT]
|
|
7
|
-
> API Key
|
|
8
|
-
>
|
|
9
|
-
> WorkBuddy、CodeBuddy 或 DSH 官方插件。
|
|
8
|
+
> API Key 来自 **WorkBuddy**,用于调用供 CodeBuddy 使用的模型服务。本插件是第三方
|
|
9
|
+
> 适配器,不属于 WorkBuddy、CodeBuddy 或 DSH 官方项目。
|
|
10
10
|
|
|
11
11
|
## 功能
|
|
12
12
|
|
|
13
|
-
- WebUI
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
13
|
+
- 在 DSH WebUI 中使用 `CodeBuddy 中国区`;
|
|
14
|
+
- 支持 WorkBuddy API Key 和 CodeBuddy 中国站账号令牌;
|
|
15
|
+
- 两种认证模式互相独立,可以随时切换;
|
|
16
|
+
- API Key 支持环境变量、多个 DSH 保存值,并可通过下拉列表切换;
|
|
17
|
+
- 令牌支持浏览器登录、多个账号持久化、账号名称展示和下拉切换;
|
|
18
|
+
- 令牌模式显示剩余积分、今日请求次数和今日积分用量;
|
|
19
|
+
- 自动从 CodeBuddy 获取当前账号可用模型;
|
|
20
|
+
- 支持编辑模型 ID、名称、上下文窗口、最大输出 Token 和模型思考档位;
|
|
21
|
+
- 支持添加、删除模型以及恢复在线模型目录;
|
|
22
|
+
- 不依赖本机 CodeBuddy CLI。
|
|
22
23
|
|
|
23
24
|
## 环境要求
|
|
24
25
|
|
|
25
|
-
- Windows、Linux 或 macOS;
|
|
26
|
-
- Node.js `>= 22.19.0`;
|
|
27
26
|
- 已安装 DSH;
|
|
28
|
-
-
|
|
29
|
-
|
|
30
|
-
安装器已自带 DSH 所需的 `pnpm`,无需全局安装。
|
|
31
|
-
|
|
32
|
-
> DSH 仍处于预发布阶段。未来版本如果调整插件接口,本插件可能需要同步升级;
|
|
33
|
-
> DSH 普通更新不会覆盖本插件。
|
|
27
|
+
- Node.js `>= 22.19.0`;
|
|
28
|
+
- Windows、Linux 或 macOS。
|
|
34
29
|
|
|
35
30
|
## 安装
|
|
36
31
|
|
|
37
|
-
|
|
32
|
+
在 PowerShell 或终端执行:
|
|
38
33
|
|
|
39
34
|
```powershell
|
|
40
35
|
npx --yes dsh-llm-codebuddy@latest install
|
|
41
36
|
```
|
|
42
37
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
也可以分别安装:
|
|
38
|
+
安装器会为 DSH 的 `web` 和 `headless` Profile 安装插件。安装完成后重启 DSH。
|
|
39
|
+
只使用 WebUI 时,也可以单独安装 Web Profile:
|
|
46
40
|
|
|
47
41
|
```powershell
|
|
48
42
|
dsh plugin --profile web add dsh-llm-codebuddy@latest
|
|
49
|
-
dsh plugin --profile headless add dsh-llm-codebuddy@latest
|
|
50
43
|
```
|
|
51
44
|
|
|
52
|
-
只使用 WebUI 时,仅执行第一条即可。
|
|
53
|
-
|
|
54
45
|
## WebUI 配置
|
|
55
46
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
47
|
+
打开 **设置 → 模型**,添加或编辑 `CodeBuddy 中国区`。认证区域有两个模式按钮:
|
|
48
|
+
|
|
49
|
+
- `API Key`:只显示 API Key 来源和新增 Key 功能;
|
|
50
|
+
- `令牌登录`:只显示令牌账号、登录、切换以及账号用量信息。
|
|
51
|
+
|
|
52
|
+
切换模式后,另一种模式的账号或 Key 控件会隐藏,不会同时占用页面空间。
|
|
53
|
+
|
|
54
|
+
### 方式一:WorkBuddy API Key
|
|
55
|
+
|
|
56
|
+
#### 使用环境变量中的 Key
|
|
57
|
+
|
|
58
|
+
插件会自动检测:
|
|
59
|
+
|
|
60
|
+
```text
|
|
61
|
+
CODEBUDDY_API_KEY
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
如果这个环境变量存在,API Key 来源下拉列表会显示“环境变量 CODEBUDDY_API_KEY”。
|
|
65
|
+
选择它即可使用;密钥值不会显示在页面中,也不会写入 `settings.yaml`。
|
|
66
|
+
|
|
67
|
+
#### 在 DSH 中保存新的 Key
|
|
68
|
+
|
|
69
|
+
1. 选择 `API Key` 模式;
|
|
70
|
+
2. 在“新增 API Key”输入框粘贴 WorkBuddy Key;
|
|
71
|
+
3. 可填写一个名称,例如“工作账号”或“测试账号”;
|
|
72
|
+
4. 点击“添加并使用”;
|
|
73
|
+
5. 新 Key 会出现在“当前 API Key”下拉列表中,并立即切换为当前 Key。
|
|
74
|
+
|
|
75
|
+
DSH 保存的 Key 存放在 DSH 凭据服务中。可以保存多个 Key 并随时切换;环境变量 Key
|
|
76
|
+
和 DSH 保存的 Key 互不覆盖。删除操作只允许删除 DSH 保存的 Key,不会删除环境变量。
|
|
63
77
|
|
|
64
|
-
|
|
78
|
+
### 方式二:CodeBuddy 账号令牌
|
|
65
79
|
|
|
66
|
-
|
|
80
|
+
1. 选择 `令牌登录` 模式;
|
|
81
|
+
2. 点击“登录 CodeBuddy”,插件会打开 CodeBuddy 中国站;
|
|
82
|
+
3. 在浏览器完成账号登录;
|
|
83
|
+
4. 返回 DSH 后,账号会保存到本地凭据并自动启用。
|
|
67
84
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
85
|
+
再次打开页面时,可以在“令牌账号”下拉列表中切换账号。点击“添加账号”可以登录
|
|
86
|
+
另一个账号,点击“删除账号”会移除当前账号的本地令牌。令牌登录不需要安装
|
|
87
|
+
`codebuddy` 命令行工具。
|
|
71
88
|
|
|
72
|
-
|
|
89
|
+
令牌模式下,插件会尝试显示:
|
|
73
90
|
|
|
74
|
-
|
|
91
|
+
- 剩余积分或企业账号的“不限量”;
|
|
92
|
+
- 今日请求次数;
|
|
93
|
+
- 今日请求消耗的积分。
|
|
75
94
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
- 已知模型字段留空:继承在线目录或内置目录中的值;
|
|
79
|
-
- 新模型缺少容量:上下文窗口默认 `262144`,最大输出默认 `32768`;
|
|
80
|
-
- 点击“恢复默认模型”:删除自定义目录并恢复适配器目录。
|
|
95
|
+
积分接口属于 CodeBuddy 中国站的账号服务,仅令牌模式使用;API Key 模式不会调用该
|
|
96
|
+
接口。如果服务暂时不可用,页面会保留账号登录状态并显示“暂不可用”。
|
|
81
97
|
|
|
82
|
-
|
|
98
|
+
## 获取和编辑模型
|
|
99
|
+
|
|
100
|
+
1. 在 `CodeBuddy 中国区` 的自定义设置中点击“获取可用模型”;
|
|
101
|
+
2. 插件会使用当前选中的 API Key 或令牌请求 CodeBuddy 模型目录;
|
|
102
|
+
3. 选择要使用的模型并保存;
|
|
103
|
+
4. 再次编辑时,可以直接修改模型 ID、显示名称、上下文窗口和最大输出 Token。
|
|
104
|
+
|
|
105
|
+
模型目录按当前账号权限返回。更换 API Key 或令牌账号后,建议重新点击“获取可用模型”。
|
|
106
|
+
如果在线目录暂时失败,插件会使用内置目录作为兜底。
|
|
83
107
|
|
|
84
108
|
## 思考程度
|
|
85
109
|
|
|
86
|
-
|
|
87
|
-
|
|
110
|
+
思考档位按模型分别决定,插件不会给所有模型强行使用同一套选项。在线模型目录会声明
|
|
111
|
+
每个模型是否支持思考、支持哪些档位以及默认档位,WebUI 会据此显示可用选项。
|
|
112
|
+
|
|
113
|
+
常见档位包括:
|
|
88
114
|
|
|
89
115
|
```text
|
|
90
116
|
off / minimal / low / medium / high / xhigh / max
|
|
91
117
|
```
|
|
92
118
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
119
|
+
实际选项可能因模型不同而不同。未手动指定时,使用 CodeBuddy 返回的默认档位;服务端
|
|
120
|
+
没有声明思考能力时,插件不会额外发送思考参数。
|
|
121
|
+
|
|
122
|
+
## 认证和请求说明
|
|
123
|
+
|
|
124
|
+
- API Key 请求使用 WorkBuddy/CodeBuddy 的 OpenAI-compatible 接口;
|
|
125
|
+
- 令牌请求使用 CodeBuddy 中国站的登录令牌,并在过期前自动刷新;
|
|
126
|
+
- DSH 负责 Agent 循环、上下文、工具调用和权限;
|
|
127
|
+
- CodeBuddy 负责模型推理并返回结果;
|
|
128
|
+
- 访问令牌、刷新令牌和 DSH 保存的 API Key 不会写入模型目录或 `settings.yaml`。
|
|
96
129
|
|
|
97
130
|
## 更新
|
|
98
131
|
|
|
99
|
-
|
|
132
|
+
重新执行安装命令即可更新:
|
|
100
133
|
|
|
101
134
|
```powershell
|
|
102
135
|
npx --yes dsh-llm-codebuddy@latest install
|
|
103
136
|
```
|
|
104
137
|
|
|
105
|
-
|
|
138
|
+
更新后重启 DSH。已有的模型配置、API Key 和登录令牌会保留。
|
|
106
139
|
|
|
107
140
|
## 卸载
|
|
108
141
|
|
|
@@ -110,67 +143,48 @@ npx --yes dsh-llm-codebuddy@latest install
|
|
|
110
143
|
npx --yes dsh-llm-codebuddy@latest uninstall
|
|
111
144
|
```
|
|
112
145
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
1. 备份 `~/.dsh/settings.yaml`;
|
|
116
|
-
2. 只删除 `llm-pi-ai.providers.codebuddy-cn` 配置;
|
|
117
|
-
3. 保留其他 Provider 和 DSH 设置;
|
|
118
|
-
4. 从 `web`、`headless` Profile 移除插件;
|
|
119
|
-
5. 保留 API Key 凭据,方便以后重新安装。
|
|
120
|
-
|
|
121
|
-
完成后重启 DSH。备份文件名类似:
|
|
122
|
-
|
|
123
|
-
```text
|
|
124
|
-
settings.yaml.codebuddy-backup-2026-08-14T12-00-00-000Z
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
源码仓库、本地安装包和 API Key 不会被删除。
|
|
146
|
+
卸载会移除 `CodeBuddy 中国区` 的 Provider 和插件包,并备份 DSH 设置文件。为方便以后
|
|
147
|
+
重新安装,API Key 和登录令牌默认保留在 DSH 凭据服务中。
|
|
128
148
|
|
|
129
149
|
## 常见问题
|
|
130
150
|
|
|
131
|
-
###
|
|
151
|
+
### 看不到 CodeBuddy Provider
|
|
132
152
|
|
|
133
|
-
|
|
153
|
+
重启 DSH 后重新打开 **设置 → 模型**。也可以检查:
|
|
134
154
|
|
|
135
155
|
```powershell
|
|
136
156
|
dsh plugin --profile web list --depth 0
|
|
137
157
|
```
|
|
138
158
|
|
|
139
|
-
###
|
|
159
|
+
### API Key 下拉列表只有环境变量
|
|
140
160
|
|
|
141
|
-
|
|
142
|
-
|
|
161
|
+
不要使用 DSH 原生的旧密钥输入框提交。选择 `API Key` 模式,在插件自己的“新增 API Key”
|
|
162
|
+
区域粘贴 Key 并点击“添加并使用”。成功后新 Key 会出现在“当前 API Key”下拉列表。
|
|
143
163
|
|
|
144
|
-
###
|
|
145
|
-
|
|
146
|
-
模型权限与 API Key 绑定。插件只导入 `/v3/config` 中 `agents[name=cli].models` 为
|
|
147
|
-
当前 Key 返回的模型;更换 Key 后请重新点击“获取可用模型”。插件不会强行显示
|
|
148
|
-
当前 Key 未授权的模型。
|
|
164
|
+
### 获取模型失败
|
|
149
165
|
|
|
150
|
-
|
|
166
|
+
确认当前选中的 Key 来自 WorkBuddy 且仍然有效,或确认令牌账号登录状态正常。更换认证
|
|
167
|
+
凭据后重新获取模型目录。
|
|
151
168
|
|
|
152
|
-
|
|
153
|
-
[CodeBuddy 调用 WorkBuddy API 开发文档](./docs/CodeBuddy调用WorkBuddy-API开发文档.md)。
|
|
169
|
+
### 令牌登录后没有积分
|
|
154
170
|
|
|
155
|
-
|
|
171
|
+
积分查询只支持令牌模式,并依赖 CodeBuddy 中国站 billing 接口。网络、账号类型或接口
|
|
172
|
+
暂时不可用时,页面会显示“暂不可用”,不影响模型调用。
|
|
156
173
|
|
|
157
|
-
|
|
174
|
+
### 调用时报 `500 status code (no body)`
|
|
158
175
|
|
|
159
|
-
|
|
176
|
+
先更新插件并重启 DSH:
|
|
160
177
|
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
↓
|
|
164
|
-
DSH Agent → 本插件 → CodeBuddy /v2/chat/completions
|
|
165
|
-
↘ CodeBuddy /v3/config(获取模型)
|
|
178
|
+
```powershell
|
|
179
|
+
npx --yes dsh-llm-codebuddy@latest install
|
|
166
180
|
```
|
|
167
181
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
- CodeBuddy:负责模型推理并返回结果。
|
|
172
|
-
<img width="1885" height="853" alt="image" src="https://github.com/user-attachments/assets/eda31b48-8412-414d-b552-1b7ce0a7c3a0" />
|
|
182
|
+
最新版会恢复 CodeBuddy 官方请求标识,兼容 API Key 和令牌模式。
|
|
183
|
+
|
|
184
|
+
### 修改后页面仍显示旧布局
|
|
173
185
|
|
|
174
|
-
|
|
186
|
+
浏览器执行 `Ctrl+F5` 强制刷新;如果 DSH 进程已经运行较久,再关闭并重新启动 DSH。
|
|
187
|
+
|
|
188
|
+
## License
|
|
175
189
|
|
|
176
190
|
[MIT](./LICENSE)
|
package/cli.js
CHANGED
|
@@ -6,6 +6,17 @@ import { createRequire } from "node:module";
|
|
|
6
6
|
import { delimiter, dirname, join, resolve } from "node:path";
|
|
7
7
|
import { spawnSync } from "node:child_process";
|
|
8
8
|
import { parseDocument } from "yaml";
|
|
9
|
+
import {
|
|
10
|
+
CODEBUDDY_SESSION_REF,
|
|
11
|
+
CODEBUDDY_SESSIONS_REF,
|
|
12
|
+
createCodeBuddySessionStore,
|
|
13
|
+
loginCodeBuddy,
|
|
14
|
+
parseCodeBuddySession,
|
|
15
|
+
parseCodeBuddySessions,
|
|
16
|
+
serializeCodeBuddySession,
|
|
17
|
+
serializeCodeBuddySessions,
|
|
18
|
+
upsertCodeBuddySession,
|
|
19
|
+
} from "./codebuddy-auth.js";
|
|
9
20
|
|
|
10
21
|
const PACKAGE = "dsh-llm-codebuddy";
|
|
11
22
|
const PACKAGE_VERSION = JSON.parse(readFileSync(new URL("./package.json", import.meta.url), "utf8")).version;
|
|
@@ -110,6 +121,47 @@ function cleanSettings(file) {
|
|
|
110
121
|
return backup;
|
|
111
122
|
}
|
|
112
123
|
|
|
124
|
+
function enableTokenLogin(home = dshHome()) {
|
|
125
|
+
const file = join(home, "settings.yaml");
|
|
126
|
+
const source = existsSync(file) ? readFileSync(file, "utf8") : "{}\n";
|
|
127
|
+
const document = parseDocument(source);
|
|
128
|
+
if (document.errors.length) throw new Error(`无法解析 ${file}:${document.errors[0].message}`);
|
|
129
|
+
if (document.hasIn(PROVIDER_PATH)) document.deleteIn([...PROVIDER_PATH, "apiKeyEnv"]);
|
|
130
|
+
else document.setIn(PROVIDER_PATH, {});
|
|
131
|
+
if (existsSync(file)) {
|
|
132
|
+
const stamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
133
|
+
copyFileSync(file, `${file}.codebuddy-backup-${stamp}`);
|
|
134
|
+
}
|
|
135
|
+
writeYamlDocument(file, document);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function storeLoginSession(session, home = dshHome()) {
|
|
139
|
+
const file = join(home, ".credentials.yaml");
|
|
140
|
+
const document = parseDocument(existsSync(file) ? readFileSync(file, "utf8") : "{}\n");
|
|
141
|
+
if (document.errors.length) throw new Error(`无法解析 ${file}:${document.errors[0].message}`);
|
|
142
|
+
const stored = document.get(CODEBUDDY_SESSIONS_REF) ?? document.get(CODEBUDDY_SESSION_REF);
|
|
143
|
+
const current = stored ? parseCodeBuddySessions(stored) : createCodeBuddySessionStore();
|
|
144
|
+
const next = upsertCodeBuddySession(current, session);
|
|
145
|
+
document.set(CODEBUDDY_SESSIONS_REF, serializeCodeBuddySessions(next));
|
|
146
|
+
document.set(CODEBUDDY_SESSION_REF, serializeCodeBuddySession(next.sessions.find((entry) => entry.id === next.activeId)));
|
|
147
|
+
if (existsSync(file)) {
|
|
148
|
+
const stamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
149
|
+
copyFileSync(file, `${file}.codebuddy-backup-${stamp}`);
|
|
150
|
+
}
|
|
151
|
+
writeYamlDocument(file, document);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
async function login() {
|
|
155
|
+
console.log("正在打开 CodeBuddy 中国站网页登录(无需安装 CodeBuddy CLI)……");
|
|
156
|
+
const session = await loginCodeBuddy((url, opened) => {
|
|
157
|
+
if (opened) console.log("浏览器登录页已打开,请在浏览器中完成登录。");
|
|
158
|
+
else console.log(`无法自动打开浏览器,请手动访问:${url}`);
|
|
159
|
+
});
|
|
160
|
+
storeLoginSession(session);
|
|
161
|
+
enableTokenLogin();
|
|
162
|
+
console.log("CodeBuddy 令牌登录成功,Provider 已切换为令牌模式。请重启 DSH。");
|
|
163
|
+
}
|
|
164
|
+
|
|
113
165
|
function install() {
|
|
114
166
|
for (const profile of ["web", "headless"]) {
|
|
115
167
|
runDsh(["plugin", "--profile", profile, "list", "--depth", "0"]);
|
|
@@ -129,7 +181,7 @@ function uninstall(home = dshHome()) {
|
|
|
129
181
|
cleanPnpmWorkspace(workspace);
|
|
130
182
|
}
|
|
131
183
|
console.log(backup ? `CodeBuddy 配置已清理,备份:${backup}` : "未发现 CodeBuddy Provider 配置。");
|
|
132
|
-
console.log("插件已卸载,API Key
|
|
184
|
+
console.log("插件已卸载,API Key 和登录令牌凭据保持不变。请重启 DSH。");
|
|
133
185
|
}
|
|
134
186
|
|
|
135
187
|
function selfTest() {
|
|
@@ -137,11 +189,34 @@ function selfTest() {
|
|
|
137
189
|
try {
|
|
138
190
|
const file = join(root, "settings.yaml");
|
|
139
191
|
writeFileSync(file, "llm-pi-ai:\n providers:\n opencode-go:\n apiKeyEnv: OPENCODE_GO_API_KEY\n codebuddy-cn:\n apiKeyEnv: CODEBUDDY_CN_API_KEY\n", "utf8");
|
|
192
|
+
enableTokenLogin(root);
|
|
193
|
+
const tokenMode = parseDocument(readFileSync(file, "utf8"));
|
|
194
|
+
if (tokenMode.hasIn([...PROVIDER_PATH, "apiKeyEnv"]) || !tokenMode.hasIn(PROVIDER_PATH)) {
|
|
195
|
+
throw new Error("token login settings self-test failed");
|
|
196
|
+
}
|
|
140
197
|
const backup = cleanSettings(file);
|
|
141
198
|
const result = parseDocument(readFileSync(file, "utf8"));
|
|
142
199
|
if (!backup || !existsSync(backup) || result.hasIn(PROVIDER_PATH) || !result.hasIn(["llm-pi-ai", "providers", "opencode-go"])) {
|
|
143
200
|
throw new Error("uninstall settings cleanup self-test failed");
|
|
144
201
|
}
|
|
202
|
+
enableTokenLogin(root);
|
|
203
|
+
if (!parseDocument(readFileSync(file, "utf8")).hasIn(PROVIDER_PATH)) {
|
|
204
|
+
throw new Error("token login provider creation self-test failed");
|
|
205
|
+
}
|
|
206
|
+
const sampleSession = {
|
|
207
|
+
auth: { accessToken: "test-access-token", refreshToken: "test-refresh-token", expiresAt: Date.now() + 60_000 },
|
|
208
|
+
account: { userId: "test-user" },
|
|
209
|
+
};
|
|
210
|
+
storeLoginSession(sampleSession, root);
|
|
211
|
+
const storedSession = parseDocument(readFileSync(join(root, ".credentials.yaml"), "utf8")).get(CODEBUDDY_SESSION_REF);
|
|
212
|
+
if (parseCodeBuddySession(storedSession).account.userId !== "test-user") {
|
|
213
|
+
throw new Error("token credential storage self-test failed");
|
|
214
|
+
}
|
|
215
|
+
const storedSessions = parseDocument(readFileSync(join(root, ".credentials.yaml"), "utf8")).get(CODEBUDDY_SESSIONS_REF);
|
|
216
|
+
const sessionStore = parseCodeBuddySessions(storedSessions);
|
|
217
|
+
if (sessionStore.sessions.length !== 1 || sessionStore.activeId !== sessionStore.sessions[0].id) {
|
|
218
|
+
throw new Error("token account list self-test failed");
|
|
219
|
+
}
|
|
145
220
|
const workspace = join(root, "pnpm-workspace.yaml");
|
|
146
221
|
writeFileSync(workspace, "packages:\n - .\nallowBuilds:\n '@google/genai': true\n protobufjs: pending\n", "utf8");
|
|
147
222
|
withPnpmBuildPolicy(workspace, () => {
|
|
@@ -172,8 +247,9 @@ function selfTest() {
|
|
|
172
247
|
const command = process.argv[2];
|
|
173
248
|
if (command === "install") install();
|
|
174
249
|
else if (command === "uninstall") uninstall();
|
|
250
|
+
else if (command === "login") await login();
|
|
175
251
|
else if (command === "--self-test") selfTest();
|
|
176
252
|
else {
|
|
177
|
-
console.log("用法:dsh-llm-codebuddy <install|uninstall>");
|
|
253
|
+
console.log("用法:dsh-llm-codebuddy <install|login|uninstall>");
|
|
178
254
|
process.exitCode = 1;
|
|
179
255
|
}
|