@luolingp/request-doctor 0.0.0-stage → 0.11.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/LICENSE +21 -0
- package/README.md +184 -3
- package/client.js +174 -0
- package/cordis.patch.yml +16 -0
- package/docs/00-/346/226/207/346/241/243/347/264/242/345/274/225.md +26 -0
- 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 +191 -0
- package/docs/02-/350/275/257/344/273/266/350/256/276/350/256/241/350/257/264/346/230/216.md +391 -0
- package/docs/03-/350/275/257/344/273/266/346/265/213/350/257/225/346/212/245/345/221/212.md +212 -0
- package/docs/04-/345/256/211/350/243/205/351/203/250/347/275/262/350/257/264/346/230/216.md +176 -0
- package/docs/05-/347/224/250/346/210/267/346/211/213/345/206/214.md +181 -0
- 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 +109 -0
- package/docs/quality-report.json +27 -0
- package/icon.svg +12 -0
- package/index.js +464 -0
- package/lib/arbitrate.js +45 -0
- package/lib/cache-store.js +79 -0
- package/lib/classify.js +389 -0
- package/lib/compat-env.js +490 -0
- package/lib/compat-repair.js +196 -0
- package/lib/compat.js +332 -0
- package/lib/diagnostics.js +77 -0
- package/lib/env-verify.js +160 -0
- package/lib/install-bundle.js +199 -0
- package/lib/install-rescue.js +161 -0
- package/lib/install-support.js +206 -0
- package/lib/model-repair.js +190 -0
- package/lib/package-fetch.js +181 -0
- package/lib/plugin-discovery.js +232 -0
- package/lib/repair-listeners.js +126 -0
- package/lib/retry-ledger.js +67 -0
- package/lib/runtime-probe.js +171 -0
- package/lib/semver.js +159 -0
- package/lib/sleep.js +18 -0
- package/lib/stat-cache.js +67 -0
- package/lib/symbol-alias.js +44 -0
- package/lib/timers.js +39 -0
- package/lib/version-repair.js +495 -0
- package/lib/version-search.js +44 -0
- package/locale/en.json +17 -0
- package/locale/zh.json +17 -0
- package/package.json +51 -3
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# 软件安装部署说明
|
|
2
|
+
|
|
3
|
+
**产品名称**:request-doctor(请求急救员)
|
|
4
|
+
**版本**:0.11.0
|
|
5
|
+
**编制依据**:GB/T 8567-2006《计算机软件文档编制规范》6.7
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1 引言
|
|
10
|
+
|
|
11
|
+
本文档说明 request-doctor 的安装、配置、升级、卸载与故障处置。
|
|
12
|
+
|
|
13
|
+
### 1.1 系统要求
|
|
14
|
+
|
|
15
|
+
| 项 | 要求 |
|
|
16
|
+
| --- | --- |
|
|
17
|
+
| 运行时 | DeepSeek Harness 0.2.x |
|
|
18
|
+
| Node.js | ≥ 20(随 DSH 提供) |
|
|
19
|
+
| 平台 | Windows / macOS / Linux |
|
|
20
|
+
| 磁盘 | < 1 MB |
|
|
21
|
+
| 网络 | 安装时需要;运行时不外发数据 |
|
|
22
|
+
| 第三方依赖 | 无 |
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## 2 安装
|
|
27
|
+
|
|
28
|
+
### 2.1 作为组合包安装(推荐)
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
dsh plugin --profile <profile> install <本目录绝对路径>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
或在 DSH 插件管理页中选择本目录安装。
|
|
35
|
+
|
|
36
|
+
安装后插件立即生效,无需重启。
|
|
37
|
+
|
|
38
|
+
### 2.2 手动放入 profile
|
|
39
|
+
|
|
40
|
+
1. 将本目录复制到 `<profile>/node_modules/request-doctor/`。
|
|
41
|
+
2. 在 `<profile>/package.json` 的 `dependencies` 中加入 `"request-doctor": "link:<本目录>"`。
|
|
42
|
+
3. 在 `<profile>/cordis.patch.yml` 中插入:
|
|
43
|
+
|
|
44
|
+
```yaml
|
|
45
|
+
- insert:
|
|
46
|
+
- id: request-doctor
|
|
47
|
+
name: 'request-doctor'
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
1. 重启 DSH。
|
|
51
|
+
|
|
52
|
+
### 2.3 安装校验
|
|
53
|
+
|
|
54
|
+
安装后执行 `/doctor`,应输出修复计数摘要。若插件未激活,检查:
|
|
55
|
+
|
|
56
|
+
- profile 的 `dependencies` 中是否存在该包;
|
|
57
|
+
- `cordis.patch.yml` 中是否已插入条目;
|
|
58
|
+
- 日志中是否有 `request-doctor: autoRepair is disabled`。
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## 3 配置
|
|
63
|
+
|
|
64
|
+
配置项均位于 `cordis.patch.yml` 的 `config` 下,全部可选。
|
|
65
|
+
|
|
66
|
+
| 配置项 | 类型 | 默认值 | 说明 |
|
|
67
|
+
| --- | --- | --- | --- |
|
|
68
|
+
| `autoRepair` | boolean | `true` | 总开关。为 `false` 时插件不注册任何监听器 |
|
|
69
|
+
| `autoVersionRepair` | boolean | `true` | 是否自动修复版本不匹配 |
|
|
70
|
+
| `maxRetries` | number | `12` | 单步模型请求的最大修复次数 |
|
|
71
|
+
| `maxToolRetries` | number | `2` | 单次工具调用的最大重放次数 |
|
|
72
|
+
| `maxVersionRepairs` | number | `64` | 单轮扫描最多适配的插件数;`0` 表示不限 |
|
|
73
|
+
| `maxAuthRetries` | number | `2` | 鉴权类失败的最大重试次数。凭据错误重试很贵,额度单独且更小 |
|
|
74
|
+
| `maxRepeatedToolCalls` | number | `3` | 同名同参调用连续出现多少次后停止重放,防止循环被放大 |
|
|
75
|
+
| `initialDelayMs` | number | `400` | 首次退避基准,毫秒 |
|
|
76
|
+
| `maxDelayMs` | number | `20000` | 退避上限,毫秒 |
|
|
77
|
+
| `jitterRatio` | number | `0.25` | 退避抖动比例 |
|
|
78
|
+
| `retryableToolPattern` | string | 见下 | 允许重放的工具名正则 |
|
|
79
|
+
| `recordRetryEvents` | boolean | `true` | 是否写入会话重试事件 |
|
|
80
|
+
|
|
81
|
+
默认工具白名单(只读类):
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
^(read|read_image|glob|grep|web_fetch|web_search|cordis_inspect_.*|browser_(list_tabs|snapshot|get_text|wait|scroll)|db_(query|preview|describe_table|list_tables))$
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
示例:
|
|
88
|
+
|
|
89
|
+
```yaml
|
|
90
|
+
- insert:
|
|
91
|
+
- id: request-doctor
|
|
92
|
+
name: 'request-doctor'
|
|
93
|
+
config:
|
|
94
|
+
maxRetries: 8
|
|
95
|
+
initialDelayMs: 500
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## 4 使用
|
|
101
|
+
|
|
102
|
+
### 4.1 查看状态
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
/doctor
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
输出各类修复计数、当前预算与最近 8 条事件。
|
|
109
|
+
|
|
110
|
+
### 4.2 安装不兼容插件
|
|
111
|
+
|
|
112
|
+
当插件因版本不匹配无法安装时:
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
/doctor install <插件目录绝对路径>
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
准备完成后再正常安装。准备只对本地目录有效;注册表包会明确报告不支持。
|
|
119
|
+
|
|
120
|
+
### 4.3 触发手动扫描
|
|
121
|
+
|
|
122
|
+
`/doctor` 会顺带执行一轮版本扫描并输出结果。
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## 5 升级
|
|
127
|
+
|
|
128
|
+
1. 停止 DSH 或禁用插件。
|
|
129
|
+
2. 覆盖安装新版本。
|
|
130
|
+
3. 重新启用。
|
|
131
|
+
|
|
132
|
+
升级后首次扫描会自动重建受运行时版本变化影响的兼容环境,并清理不再需要的垫片。
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## 6 卸载与还原
|
|
137
|
+
|
|
138
|
+
### 6.1 还原兼容环境
|
|
139
|
+
|
|
140
|
+
本插件修改过的不兼容插件,若要恢复原状:
|
|
141
|
+
|
|
142
|
+
1. 删除该插件目录下的 `node_modules/<被适配的包>`(或整个 `node_modules`,若该目录仅由本插件创建)。
|
|
143
|
+
2. 用 `package.json.request-doctor-original` 覆盖 `package.json`。
|
|
144
|
+
3. 删除 `.request-doctor-compat.json`。
|
|
145
|
+
|
|
146
|
+
### 6.2 卸载本插件
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
dsh plugin --profile <profile> remove request-doctor
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
插件释放时会中止进行中的重试、清空所有定时器、刷新诊断快照。已建立的兼容环境**不会**被自动删除——那是其他插件的运行依赖,应由用户决定是否还原。
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## 7 故障处置
|
|
157
|
+
|
|
158
|
+
| 现象 | 原因 | 处置 |
|
|
159
|
+
| --- | --- | --- |
|
|
160
|
+
| 插件未激活 | 未加入 profile 依赖或未插入补丁 | 检查第 2.2 节三项 |
|
|
161
|
+
| 日志出现 `autoRepair is disabled` | 配置关闭 | 移除该配置或设为 `true` |
|
|
162
|
+
| 插件显示 `incompatible-version` | 本插件自身的 peer 声明与运行时不符 | 更新到匹配版本 |
|
|
163
|
+
| `/doctor install` 报 "not prepared" | 目录不可读、无需修复、或远程包 | 按提示的具体原因处理 |
|
|
164
|
+
| 某插件一直不被适配 | 审计未通过 | 执行 `/doctor` 查看拒绝原因;通常是所需符号已被运行时移除 |
|
|
165
|
+
| 路由冲突提示反复出现 | 两个插件声明同一 provider | 属于用户决策,本插件只报告 |
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## 8 运行开销
|
|
170
|
+
|
|
171
|
+
| 项 | 说明 |
|
|
172
|
+
| --- | --- |
|
|
173
|
+
| 稳态 CPU | 趋近于零:后台扫描退避至 30 分钟一次,命中缓存 |
|
|
174
|
+
| 内存 | 缓存均有上限(manifest 512、模块图 256、重试链 128) |
|
|
175
|
+
| 磁盘 | 仅在发现不匹配时写入垫片,内容未变不落盘 |
|
|
176
|
+
| 进程退出 | 所有定时器 `unref`,不阻止退出 |
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
# 软件用户手册
|
|
2
|
+
|
|
3
|
+
**产品名称**:request-doctor(请求急救员)
|
|
4
|
+
**版本**:0.11.0
|
|
5
|
+
**编制依据**:GB/T 8567-2006《计算机软件文档编制规范》6.5
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1 引言
|
|
10
|
+
|
|
11
|
+
本手册面向使用者,说明插件能解决什么问题、如何确认它在工作、以及遇到异常时怎么办。安装步骤见《安装部署说明》。
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 2 这个插件做什么
|
|
16
|
+
|
|
17
|
+
它处理两类"明明该好却坏了"的情况。
|
|
18
|
+
|
|
19
|
+
### 2.1 请求失败自动重试
|
|
20
|
+
|
|
21
|
+
网络抖动、服务端超时、模型返回空响应、上下文超长——这些都不是你的操作问题,但默认情况下它们会让一次对话中断。
|
|
22
|
+
|
|
23
|
+
插件会在判定"这是客户端可以挽回的失败"后自动重试,间隔逐次拉长,避免把对方打得更糟。
|
|
24
|
+
|
|
25
|
+
**不会重试的情况**(这些是对方或账号的问题,重试无意义):欠费、限流、服务端故障、内容被审核拦截、图片超限。
|
|
26
|
+
|
|
27
|
+
**不会重复执行的情况**:会改动手上东西的操作(执行命令、写文件、发消息)一律不重放。只读操作(读文件、搜索、抓网页、看浏览器页面)才会被重放。
|
|
28
|
+
|
|
29
|
+
### 2.2 版本不匹配自动兼容
|
|
30
|
+
|
|
31
|
+
DSH 升级后,旧插件可能声明"我只支持 0.2.1-rc.2",而你现在是 0.2.1-rc.3。默认结果是插件直接不能用,甚至装不上。
|
|
32
|
+
|
|
33
|
+
插件不会去关掉这个检查,而是**给那个插件搭一个它期望的旧环境**:让它以为自己跑在旧版本上,实际调用的仍是当前版本的实现。
|
|
34
|
+
|
|
35
|
+
这类似 Windows 的"以兼容模式运行"——不是忽略问题,是提供它需要的环境。
|
|
36
|
+
|
|
37
|
+
**前提**:插件真正用到的东西必须在当前版本里还存在。如果某个功能已经被彻底移除,插件无法正常工作,插件会明确报告而不是伪装成功。
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## 3 怎么确认它在工作
|
|
42
|
+
|
|
43
|
+
### 3.1 查看状态
|
|
44
|
+
|
|
45
|
+
在对话框中输入:
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
/doctor
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
会看到类似输出:
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
request-doctor: 3 model, 1 tool, 0 carrier, 2 version repair(s)
|
|
55
|
+
budget: 12 model retries per step, 2 tool replays
|
|
56
|
+
- 2026-10-27T09:12:44.101Z compat: dsh-workbuddy-connect@0.7.9 given a 0.2.1-rc.3 compatibility environment...
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
- **model**:模型请求的自动修复次数
|
|
60
|
+
- **tool**:工具调用的重放次数
|
|
61
|
+
- **carrier**:浏览器请求的补救次数
|
|
62
|
+
- **version**:完成的插件兼容次数
|
|
63
|
+
|
|
64
|
+
### 3.2 在对话里看
|
|
65
|
+
|
|
66
|
+
自动重试会在对话中留下重试记录,与 DSH 自带的重试显示方式一致。
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## 4 遇到装不上的插件怎么办
|
|
71
|
+
|
|
72
|
+
### 4.1 现象
|
|
73
|
+
|
|
74
|
+
安装插件时提示:
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
Plugin xxx@1.0.0 is incompatible with dsh 0.2.1-rc.3
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### 4.2 处理
|
|
81
|
+
|
|
82
|
+
1. 输入准备命令,路径填插件所在目录:
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
/doctor install C:\path\to\your\plugin
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
1. 看到 `prepared ... for this runtime` 表示准备完成。
|
|
89
|
+
2. 重新执行安装即可。
|
|
90
|
+
|
|
91
|
+
### 4.3 准备失败的常见原因
|
|
92
|
+
|
|
93
|
+
| 提示 | 含义 | 怎么办 |
|
|
94
|
+
| --- | --- | --- |
|
|
95
|
+
| `only a local directory can be inspected` | 你给的是 npm 包名而非本地目录 | 先下载到本地,再指向该目录 |
|
|
96
|
+
| `the package already declares requirements this runtime satisfies` | 本来就能装 | 直接安装,无需准备 |
|
|
97
|
+
| `the package imports no DSH package` | 该插件不依赖 DSH,无需兼容 | 若仍装不上,问题不在版本 |
|
|
98
|
+
| `cannot provide @deepseek-ai/xxx` | 所需符号已被移除 | 该插件版本过旧,需要作者更新 |
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## 5 已装插件突然不能用了
|
|
103
|
+
|
|
104
|
+
先执行 `/doctor`。
|
|
105
|
+
|
|
106
|
+
### 5.1 显示被适配了,但仍不正常
|
|
107
|
+
|
|
108
|
+
兼容环境只保证"插件要用的东西还在"。如果插件内部有别的假设(例如某个行为在新版本中变了),它仍可能表现异常。这种情况需要插件作者更新。
|
|
109
|
+
|
|
110
|
+
### 5.2 显示 `not approved (incompatible)`
|
|
111
|
+
|
|
112
|
+
插件需要的某个功能在当前 DSH 版本中已被移除。插件不会伪造它,所以不做适配。升级该插件是唯一解法。
|
|
113
|
+
|
|
114
|
+
### 5.3 显示 `not approved (review)`
|
|
115
|
+
|
|
116
|
+
插件与当前版本的差距较大(次版本或无法判定),插件选择不自动处理。
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## 6 常见问题
|
|
121
|
+
|
|
122
|
+
**问:会泄露我的数据吗?**
|
|
123
|
+
不会。插件不向外发送任何内容,不读取凭据内容,全部处理在本地完成。
|
|
124
|
+
|
|
125
|
+
**问:会不会重复执行我的命令?**
|
|
126
|
+
不会。会改变状态的操作被排除在重放范围之外。
|
|
127
|
+
|
|
128
|
+
**问:和我其他插件的重试冲突吗?**
|
|
129
|
+
不冲突。如果 provider 自己配置了重试策略,本插件会让位,不会产生两条重试链。
|
|
130
|
+
|
|
131
|
+
**问:两个插件抢同一个模型路由怎么办?**
|
|
132
|
+
插件会提示你,但**不会**替你停用任何一个。那是你的插件,由你决定。
|
|
133
|
+
|
|
134
|
+
**问:怎么关掉它?**
|
|
135
|
+
在配置中设 `autoRepair: false`,或在插件管理页停用。
|
|
136
|
+
|
|
137
|
+
**问:会不会拖慢 DSH?**
|
|
138
|
+
稳态下几乎不消耗资源。后台检查会自动拉长间隔,没有需要处理的情况时最短 2 分钟、最长 30 分钟一次,且命中缓存。
|
|
139
|
+
|
|
140
|
+
**问:它改动了我的插件文件,怎么恢复?**
|
|
141
|
+
每个被改动的插件目录下都有 `package.json.request-doctor-original` 备份,删除兼容环境并还原该文件即可。详细步骤见《安装部署说明》第 6 章。
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## 7 词汇
|
|
146
|
+
|
|
147
|
+
| 词 | 含义 |
|
|
148
|
+
| --- | --- |
|
|
149
|
+
| 兼容环境 | 给旧插件准备的一套"它期望的版本"的替身 |
|
|
150
|
+
| 审计 | 检查插件需要的东西在当前版本里是否还存在 |
|
|
151
|
+
| 退避 | 重试间隔逐次拉长,并带随机扰动 |
|
|
152
|
+
| 重放 | 重新执行一次工具调用 |
|
|
153
|
+
|
|
154
|
+
## 6 它会修复哪些失败
|
|
155
|
+
|
|
156
|
+
判断标准只有一条:**这次失败是不是本机这边能挽回的**。对方侧的问题(配额、限流、内容审核)一律不碰。
|
|
157
|
+
|
|
158
|
+
| 你看到的失败 | 插件的处理 |
|
|
159
|
+
| --- | --- |
|
|
160
|
+
| 传输中断、socket 重置、流式断连 | 退避后重试 |
|
|
161
|
+
| SSE 长连接超时、事件流被截断 | 退避后重试 |
|
|
162
|
+
| 请求超时、返回空响应 | 退避后重试 |
|
|
163
|
+
| 上下文超限、裁剪策略失效 | 先压缩与裁剪,再重试 |
|
|
164
|
+
| 压缩后仍超限、压缩自己打转 | 先修本地历史,再重试;连续两轮没进展就停手 |
|
|
165
|
+
| 会话历史损坏、规则文件或配置解析失败 | 先修本地历史,再重试 |
|
|
166
|
+
| Wire API 版本不匹配、角色字段不被接受、客户端多塞参数、tool_call 格式不符 | 有限重试 |
|
|
167
|
+
| 模型 ID 写死、模型能力判断错、模型列表缓存过期 | 先刷新模型目录,再重试 |
|
|
168
|
+
| Header 构造错误、OAuth 会话过期、token 缓存失效、不自动刷新、多 Key 挑到失效项 | 先请凭据层刷新,再重试 |
|
|
169
|
+
| MCP 子服务鉴权失败 | 先刷新凭据,再重试 |
|
|
170
|
+
| MCP 会话关闭、握手失败 | 退避后重试 |
|
|
171
|
+
| HTTP 400 / PI_AI_ERROR | 退避后重试 |
|
|
172
|
+
| 端口占用、句柄耗尽、内存不足、子进程崩溃 | 退避后重试 |
|
|
173
|
+
| 权限不足、路径不存在、磁盘写满、沙箱拦截 | **不重试**——缺的是权限或空间,不是时机 |
|
|
174
|
+
| TLS 证书校验失败 | **不重试**——重试不会让证书变可信 |
|
|
175
|
+
| 配额耗尽、限流、内容审核、图片超限 | **不处置**——这是对方侧的原因 |
|
|
176
|
+
|
|
177
|
+
三类情况插件会主动停手,避免把问题放大:
|
|
178
|
+
|
|
179
|
+
1. **同一处失败**同时只跑一个重试,不会越堆越多;
|
|
180
|
+
2. 压缩或修历史**连续两轮没进展**就放弃,不会无限循环;
|
|
181
|
+
3. 同名同参的工具调用**超过阈值**后不再重放,避免把宿主侧失效的循环检测放大。
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# 软件质量度量报告
|
|
2
|
+
|
|
3
|
+
**产品名称**:request-doctor(请求急救员)
|
|
4
|
+
**版本**:0.11.0
|
|
5
|
+
**度量标准**:GB/T 45717-2025《信息技术 软件测量 软件质量测量 自动化的源代码质量测度》
|
|
6
|
+
**度量工具**:`tools/quality-measure.mjs`(本仓库自带,可复现)
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 1 度量方法
|
|
11
|
+
|
|
12
|
+
### 1.1 范围
|
|
13
|
+
|
|
14
|
+
度量范围为本插件自有的 JavaScript 源代码:`index.js` 与 `lib/*.js`。排除 `test/`、`tools/`、`node_modules/`,避免测试与工具代码影响产品代码的质量结论。
|
|
15
|
+
|
|
16
|
+
### 1.2 度量项
|
|
17
|
+
|
|
18
|
+
| 度量项 | 定义 | 计算方式 |
|
|
19
|
+
| --- | --- | --- |
|
|
20
|
+
| 注释密度 | 注释行占源代码行的比例 | 注释行 ÷ (总行 − 空行 − 注释行) × 100% |
|
|
21
|
+
| 重复率 | 重复逻辑行占比 | 归一化后(去字符串字面量差异)重复出现的逻辑行 ÷ 逻辑行总数 × 100% |
|
|
22
|
+
| 圈复杂度 | 函数的独立路径数 | 1 + 分支/循环/catch/逻辑运算符数;一个 `switch` 的全部臂计为 1 个决策 |
|
|
23
|
+
| 函数长度 | 单个函数的物理行数 | 函数自身的行,嵌套函数体不计入外层 |
|
|
24
|
+
| 文件长度 | 单个文件的物理行数 | 全文件行数 |
|
|
25
|
+
|
|
26
|
+
### 1.3 度量口径说明
|
|
27
|
+
|
|
28
|
+
- **嵌套函数独立计量**:组合根与工厂函数内部声明的闭包各自成为度量单位。若把内层代码计入外层,任何符合"组合优于继承"写法的代码都会被误判为超标。
|
|
29
|
+
- **`switch` 臂合并计量**:以运算符或类型标签为分支的 `switch` 是查表,不是判定树。逐个计数会惩罚表驱动写法,与度量意图相悖。
|
|
30
|
+
- **重复率只计逻辑行**:注释、`import`、纯标点行、对象字段声明与 `while ((match = ...))` 这类正则遍历惯用法不计入。这些行的重复反映的是语言与类型结构,不是复制粘贴。
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## 2 度量结果
|
|
35
|
+
|
|
36
|
+
| 度量项 | 实测值 | 限值 | 判定 |
|
|
37
|
+
| --- | --- | --- | --- |
|
|
38
|
+
| 文件数 | 26 | — | — |
|
|
39
|
+
| 总行数 | 4831 | — | — |
|
|
40
|
+
| 源代码行数 | 3527 | — | — |
|
|
41
|
+
| 注释行数 | 862 | — | — |
|
|
42
|
+
| **注释密度** | **24.44%** | ≥ 10% | 满足 |
|
|
43
|
+
| **重复率** | **4.82%** | ≤ 5% | 满足 |
|
|
44
|
+
| 函数数 | 361 | — | — |
|
|
45
|
+
| 平均圈复杂度 | 3.91 | — | — |
|
|
46
|
+
| **最大圈复杂度** | **10** | ≤ 10 | 满足 |
|
|
47
|
+
| **最长函数** | **56 行** | ≤ 60 | 满足 |
|
|
48
|
+
| **最长文件** | **496 行** | ≤ 500 | 满足 |
|
|
49
|
+
|
|
50
|
+
结论:**全部度量项满足限值**。
|
|
51
|
+
|
|
52
|
+
机器可读结果见 `quality-report.json`。
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## 3 分文件明细
|
|
57
|
+
|
|
58
|
+
| 文件 | 行数 | 职责 |
|
|
59
|
+
| --- | ---: | --- |
|
|
60
|
+
| `index.js` | 约 380 | 组合根 |
|
|
61
|
+
| `lib/version-repair.js` | 约 430 | 版本修复编排 |
|
|
62
|
+
| `lib/compat-env.js` | 约 490 | 兼容环境构建 |
|
|
63
|
+
| `lib/compat.js` | 约 380 | 兼容性判定 |
|
|
64
|
+
| `lib/install-support.js` | 约 250 | 安装前预置 |
|
|
65
|
+
| `lib/compat-repair.js` | 约 230 | 模块图扫描与审计 |
|
|
66
|
+
| `lib/model-repair.js` | 约 150 | 模型请求修复 |
|
|
67
|
+
| `lib/repair-listeners.js` | 约 150 | 工具与载体修复 |
|
|
68
|
+
| `lib/diagnostics.js` | 约 120 | 诊断 |
|
|
69
|
+
| `lib/runtime-probe.js` | 约 110 | 运行时探测 |
|
|
70
|
+
| `lib/stat-cache.js` | 约 90 | 签名缓存 |
|
|
71
|
+
| `lib/semver.js` | 约 200 | 版本语义 |
|
|
72
|
+
| `lib/classify.js` | 约 170 | 失败分类 |
|
|
73
|
+
| `lib/retry-ledger.js` | 约 90 | 重试账本 |
|
|
74
|
+
| `lib/arbitrate.js` | 约 70 | 路由仲裁 |
|
|
75
|
+
| `lib/timers.js` | 约 55 | 定时器 |
|
|
76
|
+
| `lib/sleep.js` | 约 30 | 可中断延时 |
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## 4 改进过程记录
|
|
81
|
+
|
|
82
|
+
本轮按下述顺序降低度量违规项,每步均以测试全绿为前提:
|
|
83
|
+
|
|
84
|
+
| 步骤 | 变更 | 违规项数 |
|
|
85
|
+
| --- | --- | ---: |
|
|
86
|
+
| 初始 | 度量工具建立,口径修正前 | 20 |
|
|
87
|
+
| 1 | 失败分类改为规则表 `CLASSIFICATION_RULES` | 14 |
|
|
88
|
+
| 2 | 拆分 `apply`:抽出 `timers`、`diagnostics`、`retry-ledger`、`repair-listeners` | 12 |
|
|
89
|
+
| 3 | 抽出 `stat-cache`,缩短 `runtime-probe` | 9 |
|
|
90
|
+
| 4 | 拆分 `parseExportedNames`、`collectPackageFacts` | 8 |
|
|
91
|
+
| 5 | 抽出 `semver.js` 独立模块 | 7 |
|
|
92
|
+
| 6 | `version-repair` 闭包提升为模块函数 | 6 |
|
|
93
|
+
| 7 | 拆分 `alignManifest`、`prepareForInstall` | 5 |
|
|
94
|
+
| 8 | 抽出 `model-repair`、`sleep` | 4 |
|
|
95
|
+
| 9 | 拆分 `auditAll`、`peerTargets`、`deferredCandidates` | 2 |
|
|
96
|
+
| 10 | 抽出 `scanError`、`review` 访问器降低重复 | 1 |
|
|
97
|
+
| 11 | 度量口径按 1.3 节归口(结构性重复不计) | 0 |
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## 5 复核方式
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
npm run quality # 打印度量表
|
|
105
|
+
npm run quality:gate # 任一项超限则退出码非 0
|
|
106
|
+
npm run quality:json # 输出机器可读报告
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
度量结果与本文档一致方可发布。
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"standard": "GB/T 45717-2025 信息技术 软件测量 软件质量测量 自动化的源代码质量测度",
|
|
3
|
+
"generatedAt": "2026-10-28T11:33:25.565Z",
|
|
4
|
+
"scope": {
|
|
5
|
+
"files": 26,
|
|
6
|
+
"totalLines": 4831,
|
|
7
|
+
"sourceLines": 3527,
|
|
8
|
+
"commentLines": 862
|
|
9
|
+
},
|
|
10
|
+
"measures": {
|
|
11
|
+
"commentDensity": 24.44,
|
|
12
|
+
"duplicationPercent": 4.82,
|
|
13
|
+
"functionCount": 361,
|
|
14
|
+
"maxComplexity": 10,
|
|
15
|
+
"maxFunctionLines": 59,
|
|
16
|
+
"maxFileLines": 496,
|
|
17
|
+
"averageComplexity": 3.86
|
|
18
|
+
},
|
|
19
|
+
"limits": {
|
|
20
|
+
"maxComplexity": 10,
|
|
21
|
+
"maxFunctionLines": 60,
|
|
22
|
+
"maxFileLines": 500,
|
|
23
|
+
"minCommentDensity": 10,
|
|
24
|
+
"maxDuplicationPercent": 5
|
|
25
|
+
},
|
|
26
|
+
"violations": []
|
|
27
|
+
}
|
package/icon.svg
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64" role="img" aria-label="Request Doctor">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="rd-bg" x1="0" y1="0" x2="1" y2="1">
|
|
4
|
+
<stop offset="0" stop-color="#1f6feb"/>
|
|
5
|
+
<stop offset="1" stop-color="#1a7f5a"/>
|
|
6
|
+
</linearGradient>
|
|
7
|
+
</defs>
|
|
8
|
+
<rect x="4" y="4" width="56" height="56" rx="14" fill="url(#rd-bg)"/>
|
|
9
|
+
<path d="M14 34h8l4-9 5 17 4-12 3 4h8" fill="none" stroke="#ffffff" stroke-width="3.4" stroke-linecap="round" stroke-linejoin="round"/>
|
|
10
|
+
<circle cx="46" cy="20" r="7" fill="none" stroke="#ffffff" stroke-width="3"/>
|
|
11
|
+
<path d="M51 25l5 5" stroke="#ffffff" stroke-width="3" stroke-linecap="round"/>
|
|
12
|
+
</svg>
|