dsh-request-doctor 0.11.0 → 0.12.0
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/client.js +16 -4
- package/docs/01-/350/275/257/344/273/266/351/234/200/346/261/202/350/247/204/346/240/274/350/257/264/346/230/216.md +2 -1
- package/docs/02-/350/275/257/344/273/266/350/256/276/350/256/241/350/257/264/346/230/216.md +1 -1
- package/docs/03-/350/275/257/344/273/266/346/265/213/350/257/225/346/212/245/345/221/212.md +10 -6
- package/docs/04-/345/256/211/350/243/205/351/203/250/347/275/262/350/257/264/346/230/216.md +1 -1
- package/docs/05-/347/224/250/346/210/267/346/211/213/345/206/214.md +34 -1
- package/docs/06-/350/275/257/344/273/266/350/264/250/351/207/217/345/272/246/351/207/217/346/212/245/345/221/212.md +9 -9
- package/docs/quality-report.json +10 -10
- package/index.js +484 -464
- package/lib/env-shape.js +13 -0
- package/lib/env-verify.js +248 -159
- package/lib/restart-notice.js +21 -0
- package/lib/verdict-report.js +37 -0
- package/lib/version-repair.js +499 -495
- package/package.json +1 -1
package/client.js
CHANGED
|
@@ -26,6 +26,7 @@ window.__ModuleLoader__.load({
|
|
|
26
26
|
done: '已装好,兼容环境会在后台补上',
|
|
27
27
|
failed: '没能装上',
|
|
28
28
|
rescan: '重新扫描',
|
|
29
|
+
restartTitle: '需要重启后生效',
|
|
29
30
|
offline: '连不上 Host 侧的安装路由,可以改用命令:',
|
|
30
31
|
}
|
|
31
32
|
|
|
@@ -58,11 +59,12 @@ window.__ModuleLoader__.load({
|
|
|
58
59
|
return response.json()
|
|
59
60
|
}
|
|
60
61
|
|
|
61
|
-
// 读一次被拒插件清单。Host
|
|
62
|
-
|
|
62
|
+
// 读一次被拒插件清单。Host 侧已经把不可用的行筛掉了,
|
|
63
|
+
// 顺带回一段「已经修好但需要重启」的提示。
|
|
64
|
+
async function loadPanel() {
|
|
63
65
|
const data = await requestJson('/doctor/incompatible', { headers: { accept: 'application/json' } })
|
|
64
66
|
if (data.ok !== true) throw new Error(data.reason || 'host declined')
|
|
65
|
-
return data.rows || []
|
|
67
|
+
return { rows: data.rows || [], restart: data.restart || [] }
|
|
66
68
|
}
|
|
67
69
|
|
|
68
70
|
// 装一个包。授权、重试、声明对齐都在 Host 侧完成,这里只拿结果。
|
|
@@ -86,10 +88,13 @@ window.__ModuleLoader__.load({
|
|
|
86
88
|
const [spec, setSpec] = React.useState('')
|
|
87
89
|
const [busy, setBusy] = React.useState(false)
|
|
88
90
|
const [note, setNote] = React.useState('')
|
|
91
|
+
const [restart, setRestart] = React.useState([])
|
|
89
92
|
|
|
90
93
|
const refresh = React.useCallback(async () => {
|
|
91
94
|
try {
|
|
92
|
-
|
|
95
|
+
const panel = await loadPanel()
|
|
96
|
+
setRows(panel.rows)
|
|
97
|
+
setRestart(panel.restart)
|
|
93
98
|
} catch (error) {
|
|
94
99
|
// 路由不通就把可用的替代办法说出来,不留空白。
|
|
95
100
|
setNote(`${TEXT.offline} /doctor install <包名>(${String((error && error.message) || error)})`)
|
|
@@ -150,6 +155,13 @@ window.__ModuleLoader__.load({
|
|
|
150
155
|
}, TEXT.install)))))
|
|
151
156
|
}
|
|
152
157
|
|
|
158
|
+
|
|
159
|
+
if (restart.length > 0) {
|
|
160
|
+
children.push(h('p', { key: 'restart-title', style: style.title }, TEXT.restartTitle))
|
|
161
|
+
for (const item of restart) {
|
|
162
|
+
children.push(h('p', { key: `restart-${item.name}`, style: style.hush }, item.hint))
|
|
163
|
+
}
|
|
164
|
+
}
|
|
153
165
|
// Host 的返回是多行文本(安装结果、位置、兼容环境),按原样保留换行。
|
|
154
166
|
if (note !== '') children.push(h('p', { key: 'note', style: { ...style.hush, whiteSpace: 'pre-wrap' } }, note))
|
|
155
167
|
return h('div', { style: style.column }, ...children)
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
**产品名称**:request-doctor(请求急救员)
|
|
4
4
|
**产品标识**:request-doctor
|
|
5
|
-
**版本**:0.
|
|
5
|
+
**版本**:0.12.0
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -113,6 +113,7 @@ DSH 是一个以 Cordis 插件框架组织的智能体运行时。插件通过
|
|
|
113
113
|
- FR-4.6 修复必须同时对齐插件自身 manifest 中的 DSH 依赖声明,因为 Loader 在组合前读取该文件。
|
|
114
114
|
- FR-4.7 **不得绕过版本检查**:修复后的声明必须真实满足当前运行时。
|
|
115
115
|
- FR-4.8 现行运行时不存在的符号**不得伪造**。必须为插件安装它期望的那份真实旧版本;旧版本也没有时如实报缺。
|
|
116
|
+
- FR-4.13 兼容环境装入真实旧版本后重载失败、且失败原因是缺少导出时,必须判定为「需要重启」,向用户给出明确提示,**不得**记为环境失败。
|
|
116
117
|
- FR-4.12 **不得使用占位实现**。缺符号只有两种出路:装真实旧版本,或如实拒绝。
|
|
117
118
|
- FR-4.9 环境建成后必须**逐条核对**插件所需符号是否真能提供;核对不通过不得计为已修复。
|
|
118
119
|
- FR-4.10 核对无法进行时(目标文件不可读)不得判为失败,应单独记录为未核对。
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# 软件测试报告
|
|
2
2
|
|
|
3
3
|
**产品名称**:request-doctor(请求急救员)
|
|
4
|
-
**版本**:0.
|
|
4
|
+
**版本**:0.12.0
|
|
5
5
|
**编制依据**:GB/T 8567-2006《计算机软件文档编制规范》6.6;GB/T 8566-2007 验证与确认过程
|
|
6
6
|
|
|
7
7
|
---
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
| `test/plugin.test.mjs` | 11 | 三类监听器行为、命令处理、插件生命周期 |
|
|
44
44
|
| `test/shim-default.test.mjs` | 3 | 两种默认导出写法的垫片转发 |
|
|
45
45
|
| `test/atomic-env.test.mjs` | 2 | 拒绝时不得破坏现有环境 |
|
|
46
|
-
| `test/env-verify.test.mjs` |
|
|
46
|
+
| `test/env-verify.test.mjs` | 11 | 环境核对:缺符号、缺 default、目标不可读、真实旧版本的入口核对 | |
|
|
47
47
|
| `test/verify-roundtrip.test.mjs` | 2 | 建完必须能验过;坏垫片能被发现 |
|
|
48
48
|
| `test/env-verify-cache.test.mjs` | 2 | 核对结果缓存,目标变化后失效 |
|
|
49
49
|
| `test/subpath-import.test.mjs` | 1 | 子路径导入不算独立包,且符号仍可取到 |
|
|
@@ -60,8 +60,10 @@
|
|
|
60
60
|
| `test/install-rescue.test.mjs` | 4 | 从失败里取出包名与版本,供授权使用 |
|
|
61
61
|
| `test/install-in-place.test.mjs` | 2 | 已装着的包就地修复,不再重复安装 |
|
|
62
62
|
| `test/client-half.test.mjs` | 5 | 客户端半:模块身份、注入声明、apply 注册、组件能渲染 |
|
|
63
|
-
| `test/diagnostics.test.mjs` | 3 | 快照可选写入:不配置不写盘、突发合并、坏路径不致命 |
|
|
64
|
-
|
|
|
63
|
+
| `test/diagnostics.test.mjs` | 3 | 快照可选写入:不配置不写盘、突发合并、坏路径不致命 |
|
|
64
|
+
| `test/restart-notice.test.mjs` | 3 |
|
|
65
|
+
| `test/verdict-report.test.mjs` | 5 | /doctor why:判定、理由、缺符号、环境、下一步 | 缺导出判为需要重启;其它失败不误判;多次累积不覆盖 |
|
|
66
|
+
| **合计** | **166** | **全部通过** |
|
|
65
67
|
|
|
66
68
|
执行结果:
|
|
67
69
|
|
|
@@ -106,6 +108,8 @@
|
|
|
106
108
|
| FR-4.9 建完必须核对 | `verify-roundtrip.test.mjs` — 建完必能验过 | 通过 |
|
|
107
109
|
| FR-4.10 不可核对不算失败 | `env-verify.test.mjs` — 目标不可读记为未核对 | 通过 |
|
|
108
110
|
| FR-4.11 坏垫片能被发现 | `verify-roundtrip.test.mjs` — 手工破坏的垫片验不过 | 通过 |
|
|
111
|
+
| FR-7.4 why 能解释判定 | `verdict-report.test.mjs` — 五种情形各有用例 | 通过 |
|
|
112
|
+
| FR-4.13 需要重启要说明 | `restart-notice.test.mjs` — 缺导出归入重启提示 | 通过 |
|
|
109
113
|
| FR-4.12 不用占位 | `compat-env.test.mjs` — 装真实旧版本;旧版本也没有则拒绝 | 通过 |
|
|
110
114
|
| FR-5.1 安装前预置 | `install-support.test.mjs` — 预置后检查通过 | 通过 |
|
|
111
115
|
| FR-5.2 失败回滚 | `install-support.test.mjs` — 目录恢复原状 | 通过 |
|
|
@@ -177,7 +181,7 @@
|
|
|
177
181
|
|
|
178
182
|
## 6 结论
|
|
179
183
|
|
|
180
|
-
全部
|
|
184
|
+
全部 160 个自动化用例通过,需求覆盖矩阵无空缺,实机验证完成关键路径。质量度量全部满足限值(见《软件质量度量报告》)。判定:**通过**。
|
|
181
185
|
|
|
182
186
|
## 7 全量回归检验记录
|
|
183
187
|
|
|
@@ -209,4 +213,4 @@
|
|
|
209
213
|
|
|
210
214
|
### 7.2 分文件执行结果
|
|
211
215
|
|
|
212
|
-
|
|
216
|
+
31 个测试文件逐个单独执行,每个都有用例且全部通过,不存在因导入失败而静默跳过的文件。用例数分布:compat.test.mjs 17、plugin.test.mjs 15、compat-env.test.mjs 14、classify.test.mjs 13,其余按职能分散,合计 166。
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# 软件用户手册
|
|
2
2
|
|
|
3
3
|
**产品名称**:request-doctor(请求急救员)
|
|
4
|
-
**版本**:0.
|
|
4
|
+
**版本**:0.12.0
|
|
5
5
|
**编制依据**:GB/T 8567-2006《计算机软件文档编制规范》6.5
|
|
6
6
|
|
|
7
7
|
---
|
|
@@ -179,3 +179,36 @@ Plugin xxx@1.0.0 is incompatible with dsh 0.2.1-rc.3
|
|
|
179
179
|
1. **同一处失败**同时只跑一个重试,不会越堆越多;
|
|
180
180
|
2. 压缩或修历史**连续两轮没进展**就放弃,不会无限循环;
|
|
181
181
|
3. 同名同参的工具调用**超过阈值**后不再重放,避免把宿主侧失效的循环检测放大。
|
|
182
|
+
## 7 什么时候需要重启
|
|
183
|
+
|
|
184
|
+
兼容环境有两种形态,后果不同:
|
|
185
|
+
|
|
186
|
+
- **薄垫片**:转发到现行实现,改完立刻有效,不用重启。
|
|
187
|
+
- **真实旧版本**:插件要用的导出在当前版本里已经被删掉了,插件会去装它声明的那个旧版本。文件虽然换好了,但当前进程多半已经缓存过那次失败的导入,**必须重启 DSH 才会重新解析**。
|
|
188
|
+
|
|
189
|
+
第二种情况 `/doctor` 会直接列出来:
|
|
190
|
+
|
|
191
|
+
```
|
|
192
|
+
需要重启后生效:
|
|
193
|
+
- dsh-hyper-tools 已经装好需要的旧版本,但这个进程不会重新解析
|
|
194
|
+
offloadRequestImagesWithPolicy,重启 DSH 后即可生效
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
看到这条说明修复本身已经完成,缺的只是一次重启——不要重复触发修复,那不会加快任何事。
|
|
198
|
+
## 8 查某个插件为什么装不上
|
|
199
|
+
|
|
200
|
+
```
|
|
201
|
+
/doctor why dsh-hyper-tools
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
输出示例:
|
|
205
|
+
|
|
206
|
+
```
|
|
207
|
+
dsh-hyper-tools@0.1.0:incompatible
|
|
208
|
+
declares @deepseek-ai/dsh-llm ^0.1.5-rc.1
|
|
209
|
+
缺符号:offloadRequestImagesWithPolicy
|
|
210
|
+
环境:真实旧版本 3 个(需重启):@deepseek-ai/dsh-llm, @deepseek-ai/schemastery, @deepseek-ai/cosmokit
|
|
211
|
+
结论:要修得先让它要的东西能被提供;缺符号时本插件会尝试装入插件声明的旧版本。
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
判定为兼容但界面里装不上时,它也会告诉你该走 `/doctor install`。查不到这个插件时会列出已经审计过的插件名。
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# 软件质量度量报告
|
|
2
2
|
|
|
3
3
|
**产品名称**:request-doctor(请求急救员)
|
|
4
|
-
**版本**:0.
|
|
4
|
+
**版本**:0.12.0
|
|
5
5
|
**度量标准**:GB/T 45717-2025《信息技术 软件测量 软件质量测量 自动化的源代码质量测度》
|
|
6
6
|
**度量工具**:`tools/quality-measure.mjs`(本仓库自带,可复现)
|
|
7
7
|
|
|
@@ -35,17 +35,17 @@
|
|
|
35
35
|
|
|
36
36
|
| 度量项 | 实测值 | 限值 | 判定 |
|
|
37
37
|
| --- | --- | --- | --- |
|
|
38
|
-
| 文件数 |
|
|
39
|
-
| 总行数 |
|
|
40
|
-
| 源代码行数 |
|
|
41
|
-
| 注释行数 |
|
|
42
|
-
| **注释密度** | **24.
|
|
43
|
-
| **重复率** | **4.
|
|
44
|
-
| 函数数 |
|
|
38
|
+
| 文件数 | 27 | — | — |
|
|
39
|
+
| 总行数 | 4955 | — | — |
|
|
40
|
+
| 源代码行数 | 3615 | — | — |
|
|
41
|
+
| 注释行数 | 888 | — | — |
|
|
42
|
+
| **注释密度** | **24.56%** | ≥ 10% | 满足 |
|
|
43
|
+
| **重复率** | **4.93%** | ≤ 5% | 满足 |
|
|
44
|
+
| 函数数 | 371 | — | — |
|
|
45
45
|
| 平均圈复杂度 | 3.91 | — | — |
|
|
46
46
|
| **最大圈复杂度** | **10** | ≤ 10 | 满足 |
|
|
47
47
|
| **最长函数** | **56 行** | ≤ 60 | 满足 |
|
|
48
|
-
| **最长文件** | **
|
|
48
|
+
| **最长文件** | **500 行** | ≤ 500 | 满足 |
|
|
49
49
|
|
|
50
50
|
结论:**全部度量项满足限值**。
|
|
51
51
|
|
package/docs/quality-report.json
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"standard": "GB/T 45717-2025 信息技术 软件测量 软件质量测量 自动化的源代码质量测度",
|
|
3
|
-
"generatedAt": "2026-10-
|
|
3
|
+
"generatedAt": "2026-10-29T13:23:48.300Z",
|
|
4
4
|
"scope": {
|
|
5
|
-
"files":
|
|
6
|
-
"totalLines":
|
|
7
|
-
"sourceLines":
|
|
8
|
-
"commentLines":
|
|
5
|
+
"files": 29,
|
|
6
|
+
"totalLines": 5029,
|
|
7
|
+
"sourceLines": 3663,
|
|
8
|
+
"commentLines": 910
|
|
9
9
|
},
|
|
10
10
|
"measures": {
|
|
11
|
-
"commentDensity": 24.
|
|
12
|
-
"duplicationPercent": 4.
|
|
13
|
-
"functionCount":
|
|
11
|
+
"commentDensity": 24.84,
|
|
12
|
+
"duplicationPercent": 4.91,
|
|
13
|
+
"functionCount": 378,
|
|
14
14
|
"maxComplexity": 10,
|
|
15
15
|
"maxFunctionLines": 59,
|
|
16
|
-
"maxFileLines":
|
|
17
|
-
"averageComplexity": 3.
|
|
16
|
+
"maxFileLines": 500,
|
|
17
|
+
"averageComplexity": 3.89
|
|
18
18
|
},
|
|
19
19
|
"limits": {
|
|
20
20
|
"maxComplexity": 10,
|