covgate 0.0.0-stage → 0.2.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.
Files changed (44) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +502 -2
  3. package/bin/covgate-postinstall.js +13 -0
  4. package/bin/covgate.js +5 -0
  5. package/docs/ai-workflow.md +196 -0
  6. package/docs/design.md +327 -0
  7. package/docs/setup.md +163 -0
  8. package/package.json +48 -4
  9. package/schema/covgate.schema.json +295 -0
  10. package/src/annotations.js +224 -0
  11. package/src/args.js +189 -0
  12. package/src/cli.js +486 -0
  13. package/src/config.js +442 -0
  14. package/src/coverage/index.js +85 -0
  15. package/src/coverage/istanbul.js +215 -0
  16. package/src/coverage/lcov.js +234 -0
  17. package/src/coverage/model.js +316 -0
  18. package/src/coverage/paths.js +40 -0
  19. package/src/errors.js +34 -0
  20. package/src/gate.js +203 -0
  21. package/src/glob.js +242 -0
  22. package/src/index.js +28 -0
  23. package/src/process.js +170 -0
  24. package/src/reason.js +77 -0
  25. package/src/report/build.js +135 -0
  26. package/src/report/index.js +29 -0
  27. package/src/report/markdown.js +343 -0
  28. package/src/report/text.js +267 -0
  29. package/src/reports.js +113 -0
  30. package/src/runner.js +95 -0
  31. package/src/scope.js +440 -0
  32. package/src/setup/agent.js +327 -0
  33. package/src/setup/config.js +112 -0
  34. package/src/setup/index.js +242 -0
  35. package/src/setup/project.js +316 -0
  36. package/src/setup/prompt.js +43 -0
  37. package/src/util.js +163 -0
  38. package/src/version.js +8 -0
  39. package/templates/AGENTS.md.snippet.md +9 -0
  40. package/templates/agent-stop-hook.sh +7 -0
  41. package/templates/covgate.config.json +98 -0
  42. package/templates/github-actions-coverage.yml +41 -0
  43. package/templates/gitignore +5 -0
  44. package/templates/pre-commit +10 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 CovGate contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,503 @@
1
- # Temporary Holding Version
1
+ # CovGate
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ > 面向 AI 编码工作流的覆盖率门禁:**客户端必须 100%,服务端至少 95%;无法覆盖的代码必须写明原因才能豁免。**
4
+
5
+ CovGate 是一个零依赖的 Node.js CLI。它不产生覆盖率,而是把测试、覆盖率报告、源码范围、豁免说明和阈值合成一道**可机器执行、可审计、可进 CI 的门禁**。
6
+
7
+ ## 为什么需要它
8
+
9
+ “让 AI 写完后自动跑测试”通常会坏在几个地方:
10
+
11
+ | 常见问题 | CovGate 的处理 |
12
+ | --- | --- |
13
+ | AI 只运行了部分测试,没跑覆盖率 | 每个 scope 配置测试命令;非零退出码直接失败 |
14
+ | 客户端覆盖率 99.9% 也放过 | 客户端所有指标硬性 100%,比较精确计数,不做四舍五入 |
15
+ | 服务端统一写成 90% | 服务端底线 95%,配置不能低于底线 |
16
+ | 没被 import 的新文件完全不出现在报告里 | `sources.include` 是源码事实来源;缺报告即失败 |
17
+ | 用 `istanbul ignore next` 隐藏代码 | 原生忽略注释一律失败,必须换成带原因的 `covgate-ignore-*` |
18
+ | 加一个“TODO”注释就豁免 | 原因长度、占位词、owner、过期时间、失效区间都会被审计 |
19
+ | 测试没执行却读到上次的报告 | 按报告 mtime/size 检测陈旧产物 |
20
+ | 豁免散落在代码里,评审看不到 | 报告 JSON/Markdown 列出全部豁免、排除、原因和状态 |
21
+
22
+ ## 硬规则
23
+
24
+ 1. **profile = client**:行、语句、函数、分支覆盖率都必须 **100%**(LCOV 不提供语句指标时,该指标为 N/A,其余仍为 100%)。
25
+ 2. **profile = server**:行、语句、函数、分支覆盖率都必须 **≥ 95%**(LCOV 不提供语句指标时,该指标为 N/A)。
26
+ 3. 配置只能**提高**门槛,不能降低。客户端写 `99` 会在加载配置时直接报错。
27
+ 4. 每个 scope 必须声明 `sources.include`,且每个源码文件都必须出现在覆盖率报告中,或拥有一个带说明的文件级豁免。
28
+ 5. 覆盖不到的代码必须使用 `covgate-ignore-*` 指令,提供具体原因;可使用 `owner`、`expires`、`ticket` 元数据。
29
+ 6. 原生忽略注释(`istanbul ignore`、`c8 ignore`、`v8 ignore`、`node:coverage ignore`)一律失败。
30
+ 7. 豁免没有移除任何未覆盖代码时视为 stale;默认失败。
31
+ 8. 测试命令失败、报告缺失、报告陈旧、JSON 损坏都返回非零退出码。
32
+
33
+ ## 工作流
34
+
35
+ ```text
36
+ covgate run
37
+ ├─ 执行 scope 的测试命令(捕获输出,超时可控)
38
+ ├─ 检查覆盖率报告是否是本次新生成的
39
+ ├─ 载入报告:Istanbul JSON / LCOV
40
+ ├─ 枚举 sources.include 中的全部源码,找“漏报文件”
41
+ ├─ 扫描 covgate 豁免、原生忽略、配置排除
42
+ ├─ 按“声明起点行”从统计中移除已说明的代码段
43
+ ├─ 精确比较阈值(covered * 10000 >= thresholdBp * total)
44
+ └─ 输出文本 / JSON / Markdown,退出 0/1/2/3
45
+ ```
46
+
47
+ ## 安装
48
+
49
+ ### 在线安装(Gitee)
50
+
51
+ ```bash
52
+ npm install --save-dev git+https://gitee.com/wxzzhj/covgate.git
53
+ npx --no-install covgate setup
54
+ ```
55
+
56
+ 也可以使用 SSH:
57
+
58
+ ```bash
59
+ npm install --save-dev git+ssh://git@gitee.com/wxzzhj/covgate.git
60
+ ```
61
+
62
+ ### 从 npm registry 安装
63
+
64
+ 包名是 `covgate`。发布到 npm 后:
65
+
66
+ ```bash
67
+ npm install --save-dev covgate
68
+ npx --no-install covgate setup
69
+ ```
70
+
71
+ 发布需要 npm 登录:`npm login && npm publish`。
72
+
73
+ ### 本地目录安装
74
+
75
+ ```bash
76
+ npm install --save-dev file:D:/Projects/DSH默认工作区/covgate
77
+ npx --no-install covgate setup
78
+ ```
79
+
80
+ 如果不想安装,也可以直接调用:
81
+
82
+ ```bash
83
+ node D:/Projects/DSH默认工作区/covgate/bin/covgate.js run
84
+ ```
85
+
86
+ ### 安装后自动配置
87
+
88
+ 安装后运行:
89
+
90
+ ```bash
91
+ npx --no-install covgate setup
92
+ ```
93
+
94
+ setup 会:
95
+
96
+ - 检测 npm/pnpm/yarn/bun 和已有测试框架;
97
+ - **没有测试框架时询问是否安装 Vitest + @vitest/coverage-v8**,选择是则自动安装;
98
+ - 写入 `coverage:gate`、`test:coverage` 脚本和 `covgate.config.json` 起始配置;
99
+ - 生成 `AGENTS.md`、Agent 门禁脚本、GitHub Actions(如存在 `.github/`)和 `.gitignore` 条目。
100
+
101
+ `postinstall` 也会尝试同样的流程,但 **npm 11.19+ 默认不执行依赖安装脚本**。如果安装时没有弹出询问,直接运行 `npx covgate setup` 即可;详细说明见 [安装与自动配置](docs/setup.md)。
102
+
103
+ ### 在 CovGate 仓库中开发
104
+
105
+ ```bash
106
+ cd covgate
107
+ npm test
108
+ node bin/covgate.js --help
109
+ ```
110
+
111
+ 要求 Node.js **20.11+**。没有运行时依赖,不需要构建。
112
+
113
+ ## 快速开始
114
+
115
+ ### 1. 创建 `covgate.config.json`
116
+
117
+ 可以从 [templates/covgate.config.json](templates/covgate.config.json) 复制并修改。最小结构如下:
118
+
119
+ ```json
120
+ {
121
+ "$schema": "./node_modules/covgate/schema/covgate.schema.json",
122
+ "version": 1,
123
+ "scopes": {
124
+ "client": {
125
+ "profile": "client",
126
+ "label": "客户端",
127
+ "commands": [
128
+ {
129
+ "name": "客户端测试与覆盖率",
130
+ "run": "npm --prefix web run test -- --coverage"
131
+ }
132
+ ],
133
+ "coverage": {
134
+ "format": "istanbul",
135
+ "paths": ["web/coverage/coverage-final.json"]
136
+ },
137
+ "sources": {
138
+ "include": ["web/src/**/*.{ts,tsx,js,jsx}"]
139
+ },
140
+ "exclude": [
141
+ {
142
+ "pattern": "web/src/**/*.test.{ts,tsx,js,jsx}",
143
+ "reason": "测试文件,不是产品运行时代码",
144
+ "owner": "web-platform"
145
+ },
146
+ {
147
+ "pattern": "web/src/**/*.d.ts",
148
+ "reason": "类型声明文件,没有运行时代码",
149
+ "owner": "web-platform"
150
+ }
151
+ ]
152
+ },
153
+ "server": {
154
+ "profile": "server",
155
+ "label": "服务端",
156
+ "commands": [
157
+ {
158
+ "name": "服务端测试与覆盖率",
159
+ "run": "npm --prefix api run test -- --coverage"
160
+ }
161
+ ],
162
+ "coverage": {
163
+ "format": "lcov",
164
+ "paths": ["api/coverage/lcov.info"]
165
+ },
166
+ "sources": {
167
+ "include": ["api/src/**/*.{ts,js}"]
168
+ },
169
+ "exclude": [
170
+ {
171
+ "pattern": "api/src/**/*.test.{ts,js}",
172
+ "reason": "测试文件,不是产品运行时代码",
173
+ "owner": "api-platform"
174
+ }
175
+ ]
176
+ }
177
+ },
178
+ "waivers": {
179
+ "minReasonLength": 8,
180
+ "requireOwner": true,
181
+ "stale": "fail",
182
+ "expiry": "fail"
183
+ },
184
+ "reports": {
185
+ "dir": ".covgate",
186
+ "formats": ["json", "markdown"]
187
+ }
188
+ }
189
+ ```
190
+
191
+ 路径都相对于**配置文件所在目录**。测试命令默认也在该目录执行,可用每个命令的 `cwd` 覆盖。
192
+
193
+ ### 2. 让测试工具生成报告
194
+
195
+ CovGate 读取现成报告,不绑定测试框架。
196
+
197
+ | 生态 | 建议格式 | 产物 |
198
+ | --- | --- | --- |
199
+ | Jest | Istanbul JSON | `coverage/coverage-final.json` |
200
+ | Vitest + v8/istanbul | Istanbul JSON 或 LCOV | `coverage/coverage-final.json` / `coverage/lcov.info` |
201
+ | c8 / nyc | Istanbul JSON 或 LCOV | `coverage/coverage-final.json` / `coverage/lcov.info` |
202
+ | pytest-cov | LCOV | `coverage/lcov.info` |
203
+ | 生成 lcov 的其他语言工具 | LCOV | `lcov.info` |
204
+
205
+ 示例:
206
+
207
+ ```bash
208
+ # Jest
209
+ jest --coverage --coverageReporters=json --coverageReporters=lcov
210
+
211
+ # Vitest(在 vitest.config 中设置 coverage.reporter = ['json', 'lcov'])
212
+ vitest run --coverage
213
+
214
+ # pytest-cov
215
+ pytest --cov=app --cov-report=lcov:coverage/lcov.info
216
+ ```
217
+
218
+ 一个 scope 只能使用一种格式;不要在同一 scope 内混用 Istanbul 和 LCOV。
219
+
220
+ ### 3. 运行门禁
221
+
222
+ ```bash
223
+ npx --no-install covgate run
224
+ ```
225
+
226
+ 手动检查已有报告:
227
+
228
+ ```bash
229
+ npx --no-install covgate check --json
230
+ ```
231
+
232
+ 校验配置:
233
+
234
+ ```bash
235
+ npx --no-install covgate validate
236
+ ```
237
+
238
+ ## 命令与退出码
239
+
240
+ | 命令 / 选项 | 作用 |
241
+ | --- | --- |
242
+ | `covgate setup` | 检测/安装测试框架,生成配置和 AI 编码代理接入。 |
243
+ | `covgate run` | 执行测试命令,然后检查覆盖率。默认命令。 |
244
+ | `covgate check` | 不执行测试,只检查已有报告。 |
245
+ | `covgate validate` | 只校验配置和排除说明。 |
246
+ | `--config <path>` | 指定配置文件。 |
247
+ | `--scope <name>` | 只检查指定 scope,可重复或逗号分隔。 |
248
+ | `--json` | stdout 只输出 JSON;过程日志走 stderr。 |
249
+ | `--no-files` | 不写 `.covgate/report.json` / `report.md`。 |
250
+ | `--report-dir <path>` | 覆盖报告目录(相对当前目录)。 |
251
+ | `--verbose` | 实时转发测试命令输出。 |
252
+ | `--color` / `--no-color` | 控制彩色输出。 |
253
+
254
+ setup 的完整选项见 [安装与自动配置](docs/setup.md)。
255
+
256
+ | 退出码 | 含义 |
257
+ | --- | --- |
258
+ | `0` | 通过 |
259
+ | `1` | 覆盖率或审计不通过 |
260
+ | `2` | 配置 / 用法错误 |
261
+ | `3` | 测试失败、报告缺失/损坏/陈旧、覆盖率无法读取 |
262
+
263
+ `check` 不执行命令,也不检查报告是否新鲜,适合人工复查已有产物;CI 和 AI 代理应使用 `run`。
264
+
265
+ CI 只需要判断退出码是否为 0。
266
+
267
+ ## 配置参考
268
+
269
+ ### profile
270
+
271
+ `client` 和 `server`。scope 名称正好是 `client` / `server` 时可以省略;其他名称必须显式声明。
272
+
273
+ 门槛底线:
274
+
275
+ | profile | lines | statements | functions | branches |
276
+ | --- | --- | --- | --- | --- |
277
+ | `client` | 100 | 100 | 100 | 100 |
278
+ | `server` | 95 | 95 | 95 | 95 |
279
+
280
+ `thresholds` 可以省略(使用底线),也可以提高。降低会被配置校验拒绝。
281
+
282
+ ### coverage
283
+
284
+ - `format`:`auto`、`istanbul`、`lcov`。
285
+ - `paths`:报告文件、目录或 glob,相对于配置目录。目录模式只识别 `coverage-final.json`(Istanbul)和 `.info` / `.lcov`(LCOV);自定义文件名请用显式路径或 glob。
286
+
287
+ 同一 scope 内混用格式会失败。LCOV 不提供语句覆盖率,因此该指标显示为 N/A,不参与门禁(行、函数、分支仍会检查)。
288
+
289
+ ### sources.include
290
+
291
+ **必填。** 这是 CovGate 能找到“漏测文件”的关键。
292
+
293
+ - 必须覆盖所有要门禁的产品源码。
294
+ - 测试文件、生成代码、类型声明等不在统计范围内的文件,应在 `exclude` 中带原因排除。
295
+ - 如果覆盖率工具自己配置了 exclude,请同步到 CovGate 的 `exclude`;否则 CovGate 会认为文件漏报。
296
+ - 报告里出现、但不在 `sources.include` 中的文件会被忽略,并在报告中给出 warning。不要依赖这个 warning 代替正确的 include。
297
+
298
+ ### exclude
299
+
300
+ 文件级排除,每条都必须写 `reason`,可选 `owner`、`expires`、`ticket`。
301
+
302
+ ```json
303
+ {
304
+ "pattern": "web/src/generated/**",
305
+ "reason": "由 OpenAPI 生成,仓库不手工维护,生成器已有独立测试",
306
+ "owner": "api-platform",
307
+ "expires": "2027-03-31"
308
+ }
309
+ ```
310
+
311
+ - 没有匹配到任何源码文件的排除规则会失败(避免规则腐烂)。
312
+ - 说明同样受长度、占位词和过期策略约束。
313
+ - 排除文件会让它完全退出统计;这是高影响操作,建议在 CODEOWNERS 中保护配置文件。
314
+
315
+ ### waivers
316
+
317
+ | 字段 | 默认 | 说明 |
318
+ | --- | --- | --- |
319
+ | `minReasonLength` | 8 | 原因最少字符数 |
320
+ | `requireOwner` | false | 是否要求 owner |
321
+ | `stale` | `fail` | 豁免没有移除未覆盖代码时:`fail` / `warn` |
322
+ | `expiry` | `fail` | 过期豁免:`fail` / `warn` |
323
+
324
+ 原生忽略注释没有开关,始终失败。
325
+
326
+ ### reports
327
+
328
+ - `dir`:输出目录,默认 `.covgate`。
329
+ - `formats`:`json`、`markdown`。
330
+
331
+ ## 写豁免:不可达代码的唯一方式
332
+
333
+ ### 1. 下一行
334
+
335
+ ```js
336
+ // covgate-ignore-next-line: 平台灰度开关在 v1 永不开启,代码仅保留兼容路径 | owner=web-platform | expires=2027-06-30
337
+ export function legacyPath() {
338
+ // ...
339
+ }
340
+ ```
341
+
342
+ ### 2. 单行(注释和代码同一行)
343
+
344
+ ```js
345
+ const generatedPlaceholder = 1; // covgate-ignore-line: 由代码生成器插入的占位语句,运行时不执行 | owner=codegen
346
+ ```
347
+
348
+ ### 3. 代码块
349
+
350
+ ```js
351
+ // covgate-ignore-start: 桌面外壳专用桥接,Web 运行时不会进入 | owner=desktop
352
+ function nativeBridge() {
353
+ // ...
354
+ }
355
+ // covgate-ignore-end
356
+ ```
357
+
358
+ ### 4. 整文件
359
+
360
+ ```js
361
+ // covgate-ignore-file: OpenAPI 生成文件,仓库不手工维护,生成流程有独立测试 | owner=api-platform | expires=2027-01-31
362
+ ```
363
+
364
+ ### 原因怎么写
365
+
366
+ 可以写:
367
+
368
+ > 平台保证 `process.platform` 为 `win32` 时不会进入此分支;v1 只支持 Linux 服务端。
369
+
370
+ 不可以写:
371
+
372
+ > unreachable
373
+
374
+ > TODO
375
+
376
+ > 无法覆盖
377
+
378
+ 原因应说明**为什么这段代码无法被执行到**,而不是“我不想测”。占位词、过短说明、缺少 owner(如果启用)都会失败。
379
+
380
+ ### 豁免的生命周期
381
+
382
+ - 如果豁免区间没有移除任何未覆盖代码,默认失败。补了测试后请删除旧豁免。
383
+ - `expires` 到期默认失败。
384
+ - 覆盖区间重叠会失败,因为无法判断哪条说明对哪段代码负责。
385
+ - 文件级豁免与行级豁免不能混用。
386
+ - 所有豁免都会进入报告,供人工复核。
387
+ - `owner` 和 `expires` 不是装饰:推荐在团队配置中开启 `requireOwner`,并设置到期日。
388
+
389
+ ## 防止“假覆盖率”
390
+
391
+ CovGate 是流程门禁,不是魔法。它做了这些约束:
392
+
393
+ 1. **源码范围可枚举**:`sources.include` 没覆盖到的文件、没被测试加载的文件会失败。
394
+ 2. **报告必须新鲜**:不会拿上一次的覆盖率结果糊弄。
395
+ 3. **原生 ignore 被禁止**:不能绕过 CovGate 的说明检查。
396
+ 4. **豁免不可静默**:所有原因、状态、过期时间都在报告里。
397
+ 5. **门槛不可降低**:客户端 100、服务端 95 写死在代码里。
398
+ 6. **精确比较**:`19/20` 是 95%,`18/20` 是 90%,不会因为显示四舍五入而误判。
399
+
400
+ 仍然需要人类负责的部分:
401
+
402
+ - 原因是否真实;
403
+ - 测试断言是否有效(空测试也能产生覆盖率);
404
+ - `covgate.config.json` 是否被滥用(建议 CODEOWNERS 保护);
405
+ - 测试命令本身是否可信(配置里的命令会通过 shell 执行)。
406
+
407
+ ## AI 编码代理接入
408
+
409
+ 运行 `npx covgate setup` 会自动生成 AGENTS、Agent 脚本和 CI 工作流。CovGate 本身不会监听文件保存;它是一道可被代理、Git hook 和 CI 调用的门禁。推荐三层:
410
+
411
+ 1. **代理完成条件**:在 `AGENTS.md` 中要求任何代码修改后执行 `covgate run`,退出码 0 才能结束。
412
+ 2. **代理 Stop hook / pre-commit**:在代理停止前或提交前自动执行,把 stderr/JSON 反馈给代理。
413
+ 3. **CI required check**:最终阻止未通过门禁的合并。
414
+
415
+ 现成片段:
416
+
417
+ - [AGENTS.md 片段](templates/AGENTS.md.snippet.md)
418
+ - [代理 Stop hook 脚本](templates/agent-stop-hook.sh)
419
+ - [GitHub Actions 工作流](templates/github-actions-coverage.yml)
420
+ - [pre-commit 示例](templates/pre-commit)
421
+ - [.gitignore 片段](templates/gitignore)
422
+ - [AI 工作流说明](docs/ai-workflow.md)
423
+
424
+ 推荐给代理的命令:
425
+
426
+ ```bash
427
+ npx --no-install covgate run --json
428
+ ```
429
+
430
+ stdout 是纯 JSON,代理可以读取 `status`、`scopes[].failingFiles`、`issues` 和 `commands`;过程日志在 stderr,不会污染 JSON。
431
+
432
+ ## 报告
433
+
434
+ 每次运行默认写:
435
+
436
+ - `.covgate/report.json`:机器可读,包含 scope 指标、失败文件、逐行未覆盖、全部豁免、排除、命令、退出码。
437
+ - `.covgate/report.md`:人类/评审可读的审计报告。
438
+
439
+ 文本输出示例:
440
+
441
+ ```text
442
+ CovGate · 覆盖率门禁 v0.2.0
443
+ 模式 执行测试并检查 · 配置 covgate.config.json · 用时 12.4s
444
+
445
+ ✗ 客户端 [client/client] 未通过
446
+ 行 97.50% (39/40, 目标 100%) ✗ · 语句 97.50% ... · 函数 100.00% ... · 分支 100.00% ...
447
+ web/src/legacy.ts
448
+ 行: 42, 43
449
+
450
+ 结果: 未通过
451
+ JSON 报告: .covgate/report.json
452
+ ```
453
+
454
+ 建议把 `.covgate/` 加入 `.gitignore`。报告是本次运行的产物,不是源码。
455
+
456
+ ## 项目结构
457
+
458
+ ```text
459
+ covgate/
460
+ bin/covgate.js CLI 入口
461
+ bin/covgate-postinstall.js 安装时检测/配置
462
+ src/
463
+ cli.js 执行编排
464
+ setup/ 测试框架检测、自动安装、AI 接入生成
465
+ config.js 严格配置校验与产品底线
466
+ scope.js 源码范围、排除、豁免审计
467
+ annotations.js covgate-ignore 解析
468
+ reason.js 原因质量/过期检查
469
+ gate.js 精确阈值比较
470
+ coverage/ Istanbul JSON / LCOV 适配
471
+ report/ JSON / Markdown / 文本报告
472
+ process.js 子进程、超时、输出捕获
473
+ reports.js 报告发现与陈旧检测
474
+ schema/ 配置 JSON Schema
475
+ templates/ AI、CI、pre-commit、示例配置
476
+ docs/ 安装、设计与 AI 工作流
477
+ test/ Node.js 内置测试
478
+ ```
479
+
480
+ ## 限制
481
+
482
+ - 只内置 Istanbul JSON 和 LCOV 两种格式。其他格式可转换为 LCOV,或新增 adapter。
483
+ - 覆盖率不等于测试质量;CovGate 不能判断断言是否有效。
484
+ - 原因文本的“真实性”无法自动验证,只能通过 owner、到期日、stale 检查和人工评审约束。
485
+ - 配置文件可执行 shell 命令,必须视为代码来评审。
486
+ - 目前按整个 scope 统计,不支持“只看改动行”。大型遗留项目可以先通过带原因的排除规则缩小范围,再逐步扩大 `sources.include`。
487
+
488
+ ## 开发
489
+
490
+ ```bash
491
+ cd covgate
492
+ npm test
493
+ ```
494
+
495
+ 测试覆盖:配置底线、glob、Istanbul/LCOV 解析与合并、豁免语法与审计、精确阈值、命令执行、陈旧报告、漏报文件、JSON 纯度、Markdown 输出、setup 检测与自动配置等(56 个测试)。
496
+
497
+ ## 设计文档
498
+
499
+ 更完整的设计取舍、威胁模型和扩展方式见 [docs/design.md](docs/design.md)。
500
+
501
+ ## License
502
+
503
+ MIT
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ import { runPostinstall } from "../src/setup/index.js";
3
+
4
+ const root = process.env.INIT_CWD || process.cwd();
5
+ try {
6
+ await runPostinstall({ root });
7
+ } catch (error) {
8
+ process.stderr.write(
9
+ "[covgate] 安装后提示失败:" + (error instanceof Error ? error.message : String(error)) + String.fromCharCode(10)
10
+ );
11
+ process.stderr.write("[covgate] 可稍后运行 npx covgate setup。" + String.fromCharCode(10));
12
+ }
13
+ process.exitCode = 0;
package/bin/covgate.js ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+ import { main } from "../src/cli.js";
3
+
4
+ const exitCode = await main(process.argv.slice(2));
5
+ process.exitCode = exitCode;