@jayyuen66/dsh-ocr-review 0.1.4 → 0.1.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 +86 -53
- package/README.zh-CN.md +84 -49
- package/THIRD_PARTY_NOTICES.md +10 -8
- package/client.js +693 -123
- package/cordis.patch.yml +6 -5
- package/host.js +985 -359
- package/package.json +49 -52
- package/scripts/get-cred.mjs +27 -14
package/package.json
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jayyuen66/dsh-ocr-review",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "dsh 工作区代码审查插件:把 open-code-review(ocr CLI)封装为 5 个模型工具 +
|
|
3
|
+
"version": "0.1.6",
|
|
4
|
+
"description": "dsh 工作区代码审查插件:把 open-code-review(ocr CLI)封装为 5 个模型工具 + 设置卡片(从宿主设置服务的 provider 清单选 provider/model 应用到 OCR 配置)。",
|
|
5
5
|
"keywords": [
|
|
6
|
+
"AI code review",
|
|
7
|
+
"DeepSeek Harness",
|
|
6
8
|
"code-review",
|
|
9
|
+
"deepseek-harness",
|
|
7
10
|
"dsh",
|
|
8
11
|
"dsh-plugin",
|
|
9
12
|
"ocr",
|
|
@@ -44,71 +47,64 @@
|
|
|
44
47
|
"registry": "https://registry.npmjs.org"
|
|
45
48
|
},
|
|
46
49
|
"dependencies": {
|
|
47
|
-
"@jayyuen66/dsh-plugin-shared": "^0.1.
|
|
50
|
+
"@jayyuen66/dsh-plugin-shared": "^0.1.6",
|
|
48
51
|
"js-yaml": "^5.4.3"
|
|
49
52
|
},
|
|
50
53
|
"devDependencies": {
|
|
51
|
-
"@deepseek-ai/cordis": "4.0.5
|
|
52
|
-
"@deepseek-ai/dsh-agent": "0.2.1-
|
|
53
|
-
"@deepseek-ai/dsh-api-remotes": "0.2.1-
|
|
54
|
-
"@deepseek-ai/dsh-atomic-write": "0.2.1-
|
|
55
|
-
"@deepseek-ai/dsh-client-locale": "0.2.1-
|
|
56
|
-
"@deepseek-ai/dsh-client-store": "0.2.1-
|
|
57
|
-
"@deepseek-ai/dsh-client-ui-layout": "0.2.1-
|
|
58
|
-
"@deepseek-ai/dsh-client-ui-plugin-manager": "0.2.1-
|
|
59
|
-
"@deepseek-ai/dsh-client-ui-renderer": "0.2.1-
|
|
60
|
-
"@deepseek-ai/dsh-client-ui-settings": "0.2.1-
|
|
61
|
-
"@deepseek-ai/dsh-client-ui-slots": "0.2.1-
|
|
62
|
-
"@deepseek-ai/dsh-credentials": "0.2.1-
|
|
63
|
-
"@deepseek-ai/dsh-home-paths": "0.2.1-
|
|
64
|
-
"@deepseek-ai/dsh-host-webserver": "0.2.1-
|
|
65
|
-
"@deepseek-ai/dsh-jobs": "0.2.1-
|
|
66
|
-
"@deepseek-ai/dsh-jobs-local": "0.2.1-
|
|
67
|
-
"@deepseek-ai/dsh-output-retention": "0.2.1-
|
|
68
|
-
"@deepseek-ai/dsh-package-manifest": "0.2.1-
|
|
69
|
-
"@deepseek-ai/dsh-ptc-runtime": "0.2.1-
|
|
70
|
-
"@deepseek-ai/dsh-sandbox": "0.2.1-
|
|
71
|
-
"@deepseek-ai/dsh-scope": "0.2.1-
|
|
72
|
-
"@deepseek-ai/dsh-session": "0.2.1-
|
|
73
|
-
"@deepseek-ai/dsh-session-projection": "0.2.1-
|
|
74
|
-
"@deepseek-ai/dsh-settings": "0.2.1-
|
|
75
|
-
"@deepseek-ai/dsh-shell": "0.2.1-
|
|
76
|
-
"@deepseek-ai/dsh-subprocess": "0.2.1-
|
|
77
|
-
"@deepseek-ai/dsh-system-prompt": "0.2.1-
|
|
78
|
-
"@deepseek-ai/dsh-tools": "0.2.1-
|
|
79
|
-
"@deepseek-ai/dsh-
|
|
80
|
-
"@deepseek-ai/
|
|
54
|
+
"@deepseek-ai/cordis": "4.0.5",
|
|
55
|
+
"@deepseek-ai/dsh-agent": "0.2.1-rc.2",
|
|
56
|
+
"@deepseek-ai/dsh-api-remotes": "0.2.1-rc.2",
|
|
57
|
+
"@deepseek-ai/dsh-atomic-write": "0.2.1-rc.2",
|
|
58
|
+
"@deepseek-ai/dsh-client-locale": "0.2.1-rc.2",
|
|
59
|
+
"@deepseek-ai/dsh-client-store": "0.2.1-rc.2",
|
|
60
|
+
"@deepseek-ai/dsh-client-ui-layout": "0.2.1-rc.2",
|
|
61
|
+
"@deepseek-ai/dsh-client-ui-plugin-manager": "0.2.1-rc.2",
|
|
62
|
+
"@deepseek-ai/dsh-client-ui-renderer": "0.2.1-rc.2",
|
|
63
|
+
"@deepseek-ai/dsh-client-ui-settings": "0.2.1-rc.2",
|
|
64
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.2.1-rc.2",
|
|
65
|
+
"@deepseek-ai/dsh-credentials": "0.2.1-rc.2",
|
|
66
|
+
"@deepseek-ai/dsh-home-paths": "0.2.1-rc.2",
|
|
67
|
+
"@deepseek-ai/dsh-host-webserver": "0.2.1-rc.2",
|
|
68
|
+
"@deepseek-ai/dsh-jobs": "0.2.1-rc.2",
|
|
69
|
+
"@deepseek-ai/dsh-jobs-local": "0.2.1-rc.2",
|
|
70
|
+
"@deepseek-ai/dsh-output-retention": "0.2.1-rc.2",
|
|
71
|
+
"@deepseek-ai/dsh-package-manifest": "0.2.1-rc.2",
|
|
72
|
+
"@deepseek-ai/dsh-ptc-runtime": "0.2.1-rc.2",
|
|
73
|
+
"@deepseek-ai/dsh-sandbox": "0.2.1-rc.2",
|
|
74
|
+
"@deepseek-ai/dsh-scope": "0.2.1-rc.2",
|
|
75
|
+
"@deepseek-ai/dsh-session": "0.2.1-rc.2",
|
|
76
|
+
"@deepseek-ai/dsh-session-projection": "0.2.1-rc.2",
|
|
77
|
+
"@deepseek-ai/dsh-settings": "0.2.1-rc.2",
|
|
78
|
+
"@deepseek-ai/dsh-shell": "0.2.1-rc.2",
|
|
79
|
+
"@deepseek-ai/dsh-subprocess": "0.2.1-rc.2",
|
|
80
|
+
"@deepseek-ai/dsh-system-prompt": "0.2.1-rc.2",
|
|
81
|
+
"@deepseek-ai/dsh-tools": "0.2.1-rc.2",
|
|
82
|
+
"@deepseek-ai/dsh-typert-protocol": "0.2.1-rc.2",
|
|
83
|
+
"@deepseek-ai/dsh-user-approval": "0.2.1-rc.2",
|
|
84
|
+
"@deepseek-ai/schemastery": "3.18.5",
|
|
81
85
|
"@types/node": "26.6.5",
|
|
82
86
|
"@types/react": "19.3.0",
|
|
83
|
-
"@vitest/coverage-v8": "5.0.
|
|
87
|
+
"@vitest/coverage-v8": "5.0.5",
|
|
84
88
|
"eslint-plugin-sonarjs": "4.2.2",
|
|
85
|
-
"oxfmt": "0.
|
|
86
|
-
"oxlint": "1.
|
|
89
|
+
"oxfmt": "0.73.0",
|
|
90
|
+
"oxlint": "1.88.0",
|
|
87
91
|
"oxlint-tsgolint": "7.0.2004",
|
|
88
92
|
"react": "^19.3.0",
|
|
89
|
-
"rolldown": "1.2.
|
|
93
|
+
"rolldown": "1.2.14",
|
|
90
94
|
"typescript": "7.0.2",
|
|
91
95
|
"vite": "8.3.4",
|
|
92
|
-
"vitest": "5.0.
|
|
96
|
+
"vitest": "5.0.5"
|
|
93
97
|
},
|
|
94
98
|
"peerDependencies": {
|
|
95
|
-
"@deepseek-ai/dsh": "
|
|
96
|
-
"@deepseek-ai/dsh-
|
|
97
|
-
"@deepseek-ai/dsh-
|
|
98
|
-
"@deepseek-ai/dsh-
|
|
99
|
-
"@deepseek-ai/schemastery": "3.18.5
|
|
100
|
-
},
|
|
101
|
-
"peerDependenciesMeta": {
|
|
102
|
-
"@deepseek-ai/dsh": {
|
|
103
|
-
"optional": true
|
|
104
|
-
}
|
|
105
|
-
},
|
|
106
|
-
"optionalDependencies": {
|
|
107
|
-
"@alibaba-group/open-code-review": "^1.12.13"
|
|
99
|
+
"@deepseek-ai/dsh-atomic-write": "0.2.1-rc.2",
|
|
100
|
+
"@deepseek-ai/dsh-credentials": "0.2.1-rc.2",
|
|
101
|
+
"@deepseek-ai/dsh-home-paths": "0.2.1-rc.2",
|
|
102
|
+
"@deepseek-ai/dsh-typert-protocol": "0.2.1-rc.2",
|
|
103
|
+
"@deepseek-ai/schemastery": "3.18.5"
|
|
108
104
|
},
|
|
109
105
|
"icon": "icon.svg",
|
|
110
106
|
"engines": {
|
|
111
|
-
"dsh": "
|
|
107
|
+
"dsh": "^0.2.1-rc.2",
|
|
112
108
|
"node": ">=22.12.0"
|
|
113
109
|
},
|
|
114
110
|
"dsh": {
|
|
@@ -121,6 +117,7 @@
|
|
|
121
117
|
"immediately": true
|
|
122
118
|
}
|
|
123
119
|
},
|
|
120
|
+
"ocrCliVersion": "1.13.0",
|
|
124
121
|
"scripts": {
|
|
125
122
|
"build:client": "node build-client.mjs",
|
|
126
123
|
"build": "node build-host.mjs",
|
package/scripts/get-cred.mjs
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// get-cred.mjs —— open-code-review 的 api_key_cmd 入口(本包唯一还在读宿主凭据
|
|
4
4
|
// 文件的地方,且**只读不问服务**)。
|
|
5
5
|
//
|
|
6
|
-
//
|
|
6
|
+
// 为什么这个脚本必须存在:
|
|
7
7
|
// - dsh 侧的 provider 清单与 key 状态已经改走官方通道(ctx.settings.describe() /
|
|
8
8
|
// ctx.credentials),但 OCR 是**另一个进程树**里的外部 CLI:它只会按
|
|
9
9
|
// ~/.opencodereview/config.json 里的 api_key_cmd 起子进程取 key,够不到 cordis
|
|
@@ -24,15 +24,18 @@
|
|
|
24
24
|
// 本脚本的 homedir() 兜底随之读 X/.dsh 就跑偏了;部署若以非 env 方式指定 dsh home,
|
|
25
25
|
// env 档同样不可靠。
|
|
26
26
|
//
|
|
27
|
-
//
|
|
28
|
-
//
|
|
27
|
+
// 取值的层序必须与宿主**同源**:官方 credentials-local 的 LocalCredentialProvider
|
|
28
|
+
// 按「托管文件 > 继承环境 > .env」取值,本脚本只要排得不一样,同一 ref 在两处都有值
|
|
29
|
+
// 时 OCR 拿到的 key 就和宿主卡片认下的有效 key 分叉——两边都"成功",打的是不同账号。
|
|
30
|
+
// 照抄官方优先级里本脚本**够得到**的那三层:
|
|
31
|
+
// 1. `$DSH_HOME/.credentials.yaml` 的 `refs.<REF>`(version: 1 托管文档,格式来源
|
|
32
|
+
// packages/credentials/credentials-local 的 parseCredentialsDocument);
|
|
33
|
+
// 2. 继承来的进程环境。注意:dsh 起 shell 会经 scrubbedParentEnv 剥掉名字命中
|
|
29
34
|
// KEY/PASSWORD/SECRET/TOKEN 或 DSH_ 前缀的变量——凭据 ref 几乎全中招,所以对
|
|
30
35
|
// 经 dsh shell 起的 OCR,这一层对凭据 ref 实际常为空;它只在 ref 名不被净化
|
|
31
36
|
// 模式命中、或调用链不经 dsh shell(手工在终端跑 ocr)时才有值。宿主侧的
|
|
32
37
|
// select/migrate 已按同一事实加闸(keyReachableAtOcrRuntime):key 只存在于
|
|
33
38
|
// 环境层/项目 .env 的配置会在写盘前被拒绝,而不是等 OCR 401。
|
|
34
|
-
// 2. `$DSH_HOME/.credentials.yaml` 的 `refs.<REF>`(version: 1 托管文档,
|
|
35
|
-
// 格式来源 packages/credentials/credentials-local/src/index.ts:169-216);
|
|
36
39
|
// 3. `$DSH_HOME/.env`(用户级回退层)。
|
|
37
40
|
// **项目 .env 刻意不读**:本脚本的 cwd 是 OCR 当时所在的仓库,跟 dsh 的启动工作区
|
|
38
41
|
// 不是一回事,去读它等于把「被审查仓库」里的键当成用户的凭据。
|
|
@@ -107,12 +110,6 @@ function isNotFound(error) {
|
|
|
107
110
|
return isRecord(error) && error.code === "ENOENT";
|
|
108
111
|
}
|
|
109
112
|
|
|
110
|
-
/**
|
|
111
|
-
* 托管 YAML 文档里的 refs.<REF>(形状不合一律回 undefined,不抛)。
|
|
112
|
-
* @param {string} credPath
|
|
113
|
-
* @param {string} refName
|
|
114
|
-
* @returns {string | undefined}
|
|
115
|
-
*/
|
|
116
113
|
/**
|
|
117
114
|
* YAML 解析错误的**脱敏**描述:只留 reason + 行列定位,不带出错位置前后若干行的原文。
|
|
118
115
|
*
|
|
@@ -154,6 +151,13 @@ function yamlErrorDetail(error) {
|
|
|
154
151
|
return "";
|
|
155
152
|
}
|
|
156
153
|
|
|
154
|
+
/**
|
|
155
|
+
* 托管 YAML 文档里的 refs.<REF>(形状不合一律回 undefined,不抛)。
|
|
156
|
+
* 解析失败走 `yamlErrorDetail`,绝不把邻域原文带进 stderr。
|
|
157
|
+
* @param {string} credPath
|
|
158
|
+
* @param {string} refName
|
|
159
|
+
* @returns {string | undefined}
|
|
160
|
+
*/
|
|
157
161
|
function fromCredentialsDoc(credPath, refName) {
|
|
158
162
|
let text;
|
|
159
163
|
try {
|
|
@@ -207,6 +211,16 @@ function unquotedValue(raw) {
|
|
|
207
211
|
return trimmed;
|
|
208
212
|
}
|
|
209
213
|
|
|
214
|
+
/**
|
|
215
|
+
* 继承来的进程环境层:去首尾空白,空白按「这一层没有值」处理。
|
|
216
|
+
* @param {string | undefined} raw
|
|
217
|
+
* @returns {string | undefined}
|
|
218
|
+
*/
|
|
219
|
+
function fromInheritedEnv(raw) {
|
|
220
|
+
const value = typeof raw === "string" ? raw.trim() : "";
|
|
221
|
+
return value === "" ? undefined : value;
|
|
222
|
+
}
|
|
223
|
+
|
|
210
224
|
/**
|
|
211
225
|
* $DSH_HOME/.env 的 KEY=VALUE(去掉可选引号;文件不存在按「该层没有值」处理)。
|
|
212
226
|
* @param {string} envPath
|
|
@@ -243,11 +257,10 @@ if (!REF_PATTERN.test(refName)) {
|
|
|
243
257
|
process.exit(1);
|
|
244
258
|
}
|
|
245
259
|
|
|
246
|
-
const inherited = process.env[refName];
|
|
247
260
|
const home = dataDirFrom(process.argv[3]);
|
|
248
261
|
const found =
|
|
249
|
-
(typeof inherited === "string" && inherited.trim().length > 0 ? inherited.trim() : undefined) ??
|
|
250
262
|
fromCredentialsDoc(path.join(home, CREDENTIALS_FILENAME), refName) ??
|
|
263
|
+
fromInheritedEnv(process.env[refName]) ??
|
|
251
264
|
fromUserDotEnv(path.join(home, ".env"), refName);
|
|
252
265
|
|
|
253
266
|
if (found === undefined) {
|
|
@@ -255,7 +268,7 @@ if (found === undefined) {
|
|
|
255
268
|
// 各层的坏消息),否则用户只能看到「llm 请求 401」这种隔了一层的症状。
|
|
256
269
|
const notes = problems.length === 0 ? "" : `;${problems.join(";")}`;
|
|
257
270
|
process.stderr.write(
|
|
258
|
-
`[get-cred] 取不到 ${refName}
|
|
271
|
+
`[get-cred] 取不到 ${refName}:查过 ${path.join(home, CREDENTIALS_FILENAME)}、进程环境与 ${path.join(home, ".env")}${notes}\n`,
|
|
259
272
|
);
|
|
260
273
|
process.exit(1);
|
|
261
274
|
} else {
|