@mison/wecom-cleaner 1.1.0 → 1.2.1

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 CHANGED
@@ -27,6 +27,7 @@
27
27
  - [常用参数](#常用参数)
28
28
  - [数据与审计文件](#数据与审计文件)
29
29
  - [开发与质量门禁](#开发与质量门禁)
30
+ - [测试矩阵](#测试矩阵)
30
31
  - [发布与打包](#发布与打包)
31
32
  - [FAQ](#faq)
32
33
 
@@ -65,7 +66,7 @@
65
66
 
66
67
  - 支持默认路径、手动配置路径、自动探测路径。
67
68
  - 自动探测采用“结构 + 缓存特征”联合识别(如 `*/WXWork Files/Caches` + 企业微信缓存类别/月目录信号),不依赖目录名且降低误判。
68
- - 自动探测结果默认不预选,需用户确认后纳入处理。
69
+ - 自动探测结果默认预选,执行前可手动取消;同时保留确认提示,避免误纳入无关目录。
69
70
 
70
71
  3. 删除与恢复链路
71
72
 
@@ -158,12 +159,21 @@ GitHub 备选方式(无 npm 包依赖):
158
159
  curl -fsSL https://raw.githubusercontent.com/MisonL/wecom-cleaner/main/scripts/install-skill.sh | bash
159
160
  ```
160
161
 
161
- 若需安装指定版本标签(例如 `v1.1.0`):
162
+ 若需安装指定版本标签(例如 `v1.2.1`):
162
163
 
163
164
  ```bash
164
- curl -fsSL https://raw.githubusercontent.com/MisonL/wecom-cleaner/main/scripts/install-skill.sh | bash -s -- --ref v1.1.0
165
+ curl -fsSL https://raw.githubusercontent.com/MisonL/wecom-cleaner/main/scripts/install-skill.sh | bash -s -- --ref v1.2.1
165
166
  ```
166
167
 
168
+ Agent 侧统一任务入口脚本(位于 `skills/wecom-cleaner-agent/scripts/`):
169
+
170
+ - `cleanup_monthly_report.sh`:年月清理任务卡片(预演/执行/复核)
171
+ - `analysis_report.sh`:会话分析(只读)任务卡片
172
+ - `space_governance_report.sh`:全量空间治理任务卡片
173
+ - `restore_batch_report.sh`:批次恢复任务卡片
174
+ - `recycle_maintain_report.sh`:回收区治理任务卡片
175
+ - `doctor_report.sh`:系统自检任务卡片
176
+
167
177
  ## 常用参数
168
178
 
169
179
  运行方式:
@@ -228,6 +238,69 @@ wecom-cleaner --doctor
228
238
  - `--json`:兼容别名,等价于 `--output json`。
229
239
  - `--mode`:兼容参数,建议迁移到动作参数(如 `--cleanup-monthly`)。
230
240
  - `--save-config`:将本次全局配置参数写回 `config.json`。
241
+ - `--help` / `-h`:输出命令帮助并退出。
242
+ - `--version` / `-v`:输出版本号并退出。
243
+
244
+ ### 各动作关键统计字段(JSON)
245
+
246
+ #### `cleanup-monthly`
247
+
248
+ - `summary.matchedTargets`:命中目标数
249
+ - `summary.matchedBytes`:命中目标总字节
250
+ - `summary.hasWork` / `summary.noTarget`:是否存在可执行目标
251
+ - `summary.successCount` / `skippedCount` / `failedCount`
252
+ - `summary.reclaimedBytes`:预计或实际释放字节
253
+ - `summary.batchId`:真实执行批次号(dry-run 为预演批次)
254
+ - `summary.matchedMonthStart` / `matchedMonthEnd`:本次命中的月份区间
255
+ - `summary.rootPathCount`:涉及的清理根目录数量
256
+ - `summary.accountCount` / `monthCount` / `categoryCount` / `externalRootCount`
257
+ - `summary.cutoffMonth`:截止月份(当使用 `--cutoff-month` 时)
258
+
259
+ `cleanup-monthly` 还会在 `data.report` 中返回可展示明细:
260
+
261
+ - `data.report.matched.categoryStats`:按类别统计(条目数、体积)
262
+ - `data.report.matched.monthStats`:按月份统计(条目数、体积)
263
+ - `data.report.matched.rootStats`:按根目录统计(条目数、体积)
264
+ - `data.report.matched.topPaths`:按体积 Top 路径样例
265
+ - `data.report.executed.byCategory/byMonth/byRoot`:真实执行落地统计(成功/跳过/失败 + 体积)
266
+
267
+ #### `analysis-only`
268
+
269
+ - `summary.targetCount` / `totalBytes`:命中目录数与总体积
270
+ - `summary.accountCount` / `matchedAccountCount` / `categoryCount` / `monthBucketCount`:维度汇总(范围账号数 vs 实际命中账号数)
271
+ - `data.accountsSummary` / `categoriesSummary` / `monthsSummary`:分布统计
272
+ - `data.report.matched`:统一的类别/月份/根目录/路径样例统计结构
273
+
274
+ #### `space-governance`
275
+
276
+ - `summary.matchedTargets` / `matchedBytes`
277
+ - `summary.successCount` / `skippedCount` / `failedCount` / `reclaimedBytes`
278
+ - `summary.tierCount` / `targetTypeCount` / `rootPathCount`
279
+ - `data.report.matched.byTier/byTargetType/byAccount/byRoot/topPaths`
280
+ - `data.report.executed.byCategory/byMonth/byRoot/topPaths`(真实执行时)
281
+
282
+ #### `restore-batch`
283
+
284
+ - `summary.batchId` / `entryCount` / `matchedBytes`
285
+ - `summary.successCount` / `skippedCount` / `failedCount` / `restoredBytes`
286
+ - `summary.scopeCount` / `categoryCount` / `rootPathCount`
287
+ - `data.report.matched.byScope/byCategory/byMonth/byRoot/topEntries`
288
+ - `data.report.executed.byScope/byCategory/byMonth/byRoot/topEntries`(真实执行时)
289
+
290
+ #### `recycle-maintain`
291
+
292
+ - `summary.candidateCount` / `selectedByAge` / `selectedBySize`
293
+ - `summary.deletedBatches` / `deletedBytes` / `failedBatches`
294
+ - `summary.remainingBatches` / `remainingBytes`
295
+ - `data.report.before` / `after` / `thresholdBytes` / `overThreshold`
296
+ - `data.report.selectedCandidates` / `operations`
297
+
298
+ #### `doctor`
299
+
300
+ - `summary.overall` / `pass` / `warn` / `fail`
301
+ - `data.checks`:逐项体检结论(pass/warn/fail)
302
+ - `data.metrics`:账号数、回收区占用、外部存储等关键指标
303
+ - `data.runtime`:运行时环境信息
231
304
 
232
305
  ### 全局参数
233
306
 
@@ -236,7 +309,7 @@ wecom-cleaner --doctor
236
309
  - `--external-storage-root <path[,path...]>`:手动文件存储目录(配置层)
237
310
  - `--external-storage-auto-detect <true|false>`:外部存储自动探测总开关
238
311
  - `--external-roots <path[,path...]>`:本次动作临时覆盖的文件存储目录
239
- - `--external-roots-source <preset|configured|auto|all>`:按来源筛选探测目录(默认 `preset`)
312
+ - `--external-roots-source <preset|configured|auto|all>`:按来源筛选探测目录(默认 `all`,优先减少漏扫;可按需收窄)
240
313
  - `--theme <auto|light|dark>`:Logo 主题
241
314
  - `--interactive`:即使携带参数也进入交互流程(可配合 `--mode`)
242
315
  - `--force`:锁异常场景下强制清理并继续(兜底参数,通常无需)
@@ -312,19 +385,25 @@ npm run format:check
312
385
  发布前推荐全量门禁:
313
386
 
314
387
  ```bash
388
+ npm run format:check
315
389
  npm run check
316
390
  npm run test:coverage:check
317
- npm run format:check
391
+ npm run release:gate
318
392
  npm run e2e:smoke -- --keep
319
393
  npm run pack:tgz:dry-run
320
394
  ```
321
395
 
322
- 当前基线(`v1.1.0`):
396
+ 当前基线(主分支):
323
397
 
324
- - 单元测试:`68/68` 通过。
325
- - 覆盖率:`statements 86.57%`,`branches 73.96%`,`functions 93.25%`,`lines 86.57%`。
398
+ - 单元测试:`91/91` 通过。
399
+ - 覆盖率:`statements 88.49%`,`branches 75.01%`,`functions 95.02%`,`lines 88.49%`。
326
400
  - 全菜单 smoke:通过(含恢复冲突分支与 doctor JSON 分支)。
327
401
 
402
+ ## 测试矩阵
403
+
404
+ - 场景矩阵与断言模板见:[`docs/TEST_MATRIX.md`](./docs/TEST_MATRIX.md)
405
+ - 新增动作或输出字段时,需同步更新矩阵并补对应测试。
406
+
328
407
  ## 发布与打包
329
408
 
330
409
  `prepack` 会自动执行:
@@ -337,6 +416,8 @@ npm run pack:tgz:dry-run
337
416
  - `native/bin/darwin-x64/wecom-cleaner-core`
338
417
  - `native/bin/darwin-arm64/wecom-cleaner-core`
339
418
 
419
+ 说明:`native/bin/` 为构建产物目录,不纳入 Git 版本管理。
420
+
340
421
  本地交付包(无作用域前缀)建议:
341
422
 
342
423
  ```bash
@@ -349,22 +430,27 @@ npm run pack:tgz
349
430
 
350
431
  ```bash
351
432
  # 1) 发布前检查
433
+ npm run format:check
352
434
  npm run check
353
435
  npm run test:coverage:check
354
- npm run format:check
436
+ npm run release:gate
355
437
  npm run e2e:smoke
356
438
  npm run pack:tgz
439
+ npm run pack:release-assets
357
440
 
358
441
  # 2) 推送主分支与标签
359
442
  git push origin main
360
- git tag v1.1.0
361
- git push origin v1.1.0
362
-
363
- # 3) 发布 GitHub Release(附 tgz 包)
364
- gh release create v1.1.0 \
365
- --title "v1.1.0" \
366
- --notes-file docs/releases/v1.1.0.md \
367
- wecom-cleaner-1.1.0.tgz
443
+ git tag v1.2.1
444
+ git push origin v1.2.1
445
+
446
+ # 3) 发布 GitHub Release(附 npm 包 + 双架构核心附件)
447
+ gh release create v1.2.1 \
448
+ --title "v1.2.1" \
449
+ --notes-file docs/releases/v1.2.1.md \
450
+ wecom-cleaner-1.2.1.tgz \
451
+ dist/release/wecom-cleaner-core-v1.2.1-darwin-x64 \
452
+ dist/release/wecom-cleaner-core-v1.2.1-darwin-arm64 \
453
+ dist/release/wecom-cleaner-core-v1.2.1-SHA256SUMS.txt
368
454
 
369
455
  # 4) 发布 npm
370
456
  npm publish --access public
@@ -7,6 +7,8 @@
7
7
  - `wecom-cleaner`(不带参数):进入交互模式(TUI)。
8
8
  - `wecom-cleaner ...args`(带参数):进入无交互模式。
9
9
  - `wecom-cleaner ...args --interactive`:即使带参数也强制进入交互模式(常用于本地调试/脚本回放)。
10
+ - `wecom-cleaner --help` / `wecom-cleaner -h`:输出命令帮助并退出(`0`)。
11
+ - `wecom-cleaner --version` / `wecom-cleaner -v`:输出版本号并退出(`0`)。
10
12
 
11
13
  ## 2. 动作选择(必填且互斥)
12
14
 
@@ -33,7 +35,7 @@
33
35
 
34
36
  ## 4. 输出协议
35
37
 
36
- 无交互默认输出 JSON,可通过 `--output text` 切换文本。
38
+ 无交互默认输出 JSON,可通过 `--output text` 切换文本任务卡片(中文结论 + 范围 + 统计 + 风险提示)。
37
39
 
38
40
  - `--output json|text`(默认 `json`)
39
41
  - `--json` 为兼容别名(等价 `--output json`)
@@ -49,6 +51,119 @@ JSON 顶层字段:
49
51
  - `data`:动作明细数据
50
52
  - `meta`:元信息(版本、耗时、引擎、时间戳等)
51
53
 
54
+ `cleanup_monthly` 常见 `summary` 字段:
55
+
56
+ - `batchId`
57
+ - `hasWork`
58
+ - `noTarget`
59
+ - `matchedTargets`
60
+ - `matchedBytes`
61
+ - `successCount`
62
+ - `skippedCount`
63
+ - `failedCount`
64
+ - `reclaimedBytes`
65
+ - `accountCount`
66
+ - `monthCount`
67
+ - `categoryCount`
68
+ - `externalRootCount`
69
+ - `cutoffMonth`
70
+ - `matchedMonthStart`
71
+ - `matchedMonthEnd`
72
+ - `rootPathCount`
73
+
74
+ `cleanup_monthly` 的 `data.report`:
75
+
76
+ - `matched`:
77
+ - `totalTargets` / `totalBytes`
78
+ - `monthRange` / `matchedMonths`
79
+ - `categoryStats` / `monthStats` / `accountStats` / `rootStats`
80
+ - `topPaths`(按体积排序)
81
+ - `executed`:
82
+ - `byStatus`
83
+ - `byCategory` / `byMonth` / `byRoot`
84
+ - `topPaths`(按体积排序)
85
+
86
+ `analysis_only` 常见 `summary` 字段:
87
+
88
+ - `targetCount`
89
+ - `totalBytes`
90
+ - `accountCount`
91
+ - `matchedAccountCount`
92
+ - `categoryCount`
93
+ - `monthBucketCount`
94
+
95
+ `analysis_only` 的 `data.report`:
96
+
97
+ - `matched`:
98
+ - `totalTargets` / `totalBytes`
99
+ - `monthRange` / `matchedMonths`
100
+ - `categoryStats` / `monthStats` / `accountStats` / `rootStats`
101
+ - `topPaths`
102
+
103
+ `space_governance` 常见 `summary` 字段:
104
+
105
+ - `matchedTargets` / `matchedBytes`
106
+ - `successCount` / `skippedCount` / `failedCount` / `reclaimedBytes`
107
+ - `tierCount` / `targetTypeCount` / `rootPathCount`
108
+ - `allowRecentActive`
109
+
110
+ `space_governance` 的 `data.report`:
111
+
112
+ - `matched`:
113
+ - `totalTargets` / `totalBytes`
114
+ - `byTier` / `byTargetType` / `byAccount` / `byRoot`
115
+ - `topPaths`
116
+ - `executed`:
117
+ - `byStatus`
118
+ - `byCategory` / `byMonth` / `byRoot`
119
+ - `topPaths`
120
+
121
+ `restore` 常见 `summary` 字段:
122
+
123
+ - `batchId`
124
+ - `successCount` / `skippedCount` / `failedCount`
125
+ - `restoredBytes`
126
+ - `conflictStrategy`
127
+ - `entryCount` / `matchedBytes`
128
+ - `scopeCount` / `categoryCount` / `rootPathCount`
129
+
130
+ `restore` 的 `data.report`:
131
+
132
+ - `matched`:
133
+ - `totalEntries` / `totalBytes`
134
+ - `byScope` / `byCategory` / `byMonth` / `byRoot`
135
+ - `topEntries`
136
+ - `executed`:
137
+ - `byStatus`
138
+ - `byScope` / `byCategory` / `byMonth` / `byRoot`
139
+ - `topEntries`
140
+
141
+ `recycle_maintain` 常见 `summary` 字段:
142
+
143
+ - `status`
144
+ - `candidateCount`
145
+ - `selectedByAge` / `selectedBySize`
146
+ - `deletedBatches` / `deletedBytes` / `failedBatches`
147
+ - `remainingBatches` / `remainingBytes`
148
+
149
+ `recycle_maintain` 的 `data.report`:
150
+
151
+ - `before` / `after`
152
+ - `thresholdBytes` / `overThreshold`
153
+ - `selectedCandidates`
154
+ - `operations`
155
+
156
+ `doctor` 常见 `summary` 字段:
157
+
158
+ - `overall`
159
+ - `pass` / `warn` / `fail`
160
+
161
+ `doctor` 的 `data`:
162
+
163
+ - `checks`:体检项列表(pass/warn/fail)
164
+ - `metrics`:关键计数与容量
165
+ - `runtime`:平台与运行时信息
166
+
52
167
  ## 5. 退出码
53
168
 
54
169
  - `0`:执行成功(含 dry-run 成功)
@@ -63,7 +178,7 @@ JSON 顶层字段:
63
178
  - `--external-storage-root <path[,path...]>`:配置层手动文件存储目录
64
179
  - `--external-storage-auto-detect <true|false>`:自动探测开关
65
180
  - `--external-roots <path[,path...]>`:动作层临时覆盖文件存储目录
66
- - `--external-roots-source <preset|configured|auto|all>`:按来源筛选探测目录(默认 `preset`)
181
+ - `--external-roots-source <preset|configured|auto|all>`:按来源筛选探测目录(默认 `all`)
67
182
  - `--theme <auto|light|dark>`
68
183
  - `--interactive`:强制交互模式(与无交互动作参数互斥使用时,优先按交互模式执行)
69
184
  - `--force`:锁异常场景下强制清理并继续(兜底参数)
@@ -84,6 +199,10 @@ JSON 顶层字段:
84
199
  - `--accounts <all|current|id1,id2...>`
85
200
  - `--categories <all|key1,key2...>`
86
201
 
202
+ 说明:
203
+
204
+ - `analysis-only` 默认按 `external-roots-source=all` 读取外部目录来源(只读动作,避免漏扫)。
205
+
87
206
  ### 7.3 `--space-governance`
88
207
 
89
208
  - `--accounts <all|current|id1,id2...>`
@@ -93,6 +212,11 @@ JSON 顶层字段:
93
212
  - `--allow-recent-active <true|false>`
94
213
  - `--dry-run <true|false>`
95
214
 
215
+ 说明:
216
+
217
+ - `cleanup-monthly` / `space-governance` 默认 `external-roots-source=all`,优先减少漏扫。
218
+ - 若需更保守范围,可显式设置 `--external-roots-source preset`(仅默认+手动配置来源)。
219
+
96
220
  ### 7.4 `--restore-batch <batchId>`
97
221
 
98
222
  - `--conflict <skip|overwrite|rename>`(默认 `skip`)
@@ -0,0 +1,106 @@
1
+ # 测试矩阵(稳定性与极端场景)
2
+
3
+ 本文用于约束 `wecom-cleaner` 在复杂组合场景与极端输入下的行为一致性,避免“看似成功但语义错误”。
4
+
5
+ ## 目标
6
+
7
+ - 覆盖高风险动作:年月清理、全量空间治理、恢复、回收区治理。
8
+ - 锁定无交互契约:JSON 字段兼容、退出码语义稳定、text 卡片结论可读。
9
+ - 验证边界安全:路径越界、符号链接逃逸、索引异常、权限失败、并发竞争。
10
+
11
+ ## 维度定义
12
+
13
+ ### 维度 A:入口
14
+
15
+ - 交互模式(TUI)
16
+ - 无交互 CLI(`--output json|text`)
17
+ - Agent 脚本(`skills/wecom-cleaner-agent/scripts/*.sh`)
18
+
19
+ ### 维度 B:动作
20
+
21
+ - `cleanup_monthly`
22
+ - `analysis_only`
23
+ - `space_governance`
24
+ - `restore`
25
+ - `recycle_maintain`
26
+ - `doctor`
27
+
28
+ ### 维度 C:范围组合
29
+
30
+ - 账号:`current` / `all` / 指定 ID 集合
31
+ - 月份:显式 `--months` / `--cutoff-month` / 自动窗口
32
+ - 类别:默认 / 指定列表 / `all`
33
+ - 文件存储目录来源:`preset` / `configured` / `auto` / `all`
34
+
35
+ ### 维度 D:执行模式
36
+
37
+ - dry-run(预演)
38
+ - 真实执行(`--dry-run false --yes`)
39
+ - 真实执行后复核(同条件二次运行)
40
+
41
+ ### 维度 E:异常与边界
42
+
43
+ - 路径越界(`../`、绝对路径、非法根目录)
44
+ - 符号链接逃逸(raw 路径在根内,realpath 在根外)
45
+ - 索引异常(损坏行、批次根不一致、异常 `batchId`)
46
+ - 系统失败(`EACCES`、`ENOENT`、`ENOSPC`)
47
+ - 并发锁冲突与陈旧锁恢复
48
+
49
+ ### 维度 F:规模
50
+
51
+ - 小样本(< 50 目录)
52
+ - 中样本(50~500 目录)
53
+ - 大样本(> 500 目录,强调耗时与稳定性)
54
+
55
+ ## 关键断言模板(每个场景最少验证)
56
+
57
+ ### 1) 退出码
58
+
59
+ - `0`:动作完成(可含业务失败明细)
60
+ - `2`:参数/用法错误
61
+ - `3`:真实执行缺少 `--yes`
62
+
63
+ ### 2) JSON 契约(无交互)
64
+
65
+ 必须存在且类型稳定:
66
+
67
+ - `ok: boolean`
68
+ - `action: string`
69
+ - `dryRun: boolean | null`
70
+ - `summary: object`
71
+ - `warnings: array`
72
+ - `errors: array`
73
+ - `meta.durationMs: number`
74
+ - `meta.engine: string`
75
+
76
+ ### 3) 业务语义
77
+
78
+ - dry-run 不修改源目录
79
+ - 真实执行删除采用“移动到回收区”,可按批次恢复
80
+ - 无目标场景不得生成真实批次(或写入误导性“成功删除”)
81
+ - 部分失败时必须可见失败统计与错误明细
82
+
83
+ ### 4) 审计一致性
84
+
85
+ - `index.jsonl` 记录动作、状态、路径、错误类型
86
+ - 越界/异常路径必须落审计(`error_type=PATH_VALIDATION_FAILED`)
87
+ - 回收区治理异常批次不得触发越界删除
88
+
89
+ ## 最小必跑清单(回归基线)
90
+
91
+ 1. `cleanup_monthly`:`--cutoff-month` + `--output json` + dry-run(有目标 / 无目标)
92
+ 2. `cleanup_monthly`:真实执行 + 复核(复核命中应下降或归零)
93
+ 3. `space_governance`:`suggested-only` 与 `allow-recent-active` 组合
94
+ 4. `restore`:`skip/overwrite/rename` 三冲突策略
95
+ 5. `recycle_maintain`:`disabled` / `no_candidate` / `partial_failed`
96
+ 6. `doctor`:只读模式不创建状态目录
97
+ 7. Agent 报告脚本:成功、无目标、失败三态退出码与卡片完整性
98
+
99
+ ## 当前门禁(执行顺序)
100
+
101
+ 1. `npm run check`
102
+ 2. `npm run test:coverage:check`
103
+ 3. `shellcheck skills/wecom-cleaner-agent/scripts/*.sh`
104
+ 4. `npm run e2e:smoke`
105
+
106
+ 说明:若新增动作/字段,需先补此文档矩阵与断言,再提交实现。
@@ -0,0 +1,33 @@
1
+ # v1.2.0 发布说明
2
+
3
+ 发布日期:2026-02-26
4
+
5
+ ## 亮点
6
+
7
+ - 无交互 `--output text` 升级为中文任务卡片:
8
+ - 任务结论
9
+ - 处理范围(账号/月份/类别/路径)
10
+ - 结果统计(命中、释放、成功/跳过/失败、批次)
11
+ - 分类与月份分布
12
+ - 风险与运行状态
13
+ - `wecom-cleaner-agent` 升级为“脚本优先”执行模式,新增 6 个报告脚本,面向 Agent 输出更可读。
14
+ - 发布流程支持 GitHub Release 独立双架构核心附件(macOS x64 / arm64)。
15
+
16
+ ## 重要变更
17
+
18
+ - 非交互 `cleanup-monthly` / `space-governance` 默认外部目录来源改为 `all`(减少漏扫)。
19
+ - 交互模式外部目录默认预选自动探测路径,执行前可取消。
20
+ - `native/bin/` 改为构建产物目录,不再纳入 Git 版本管理。
21
+
22
+ ## 修复
23
+
24
+ - 修复 Zig 核心对目录体积的误统计问题(此前可能导致容量明显偏小)。
25
+ - 增强清理/恢复/回收区治理结果的分布统计能力,便于用户复核。
26
+
27
+ ## 资产
28
+
29
+ - npm 包:`wecom-cleaner-1.2.0.tgz`
30
+ - GitHub Release 附件:
31
+ - `wecom-cleaner-core-v1.2.0-darwin-x64`
32
+ - `wecom-cleaner-core-v1.2.0-darwin-arm64`
33
+ - `wecom-cleaner-core-v1.2.0-SHA256SUMS.txt`
@@ -0,0 +1,33 @@
1
+ # v1.2.1 发布说明
2
+
3
+ 发布日期:2026-02-26
4
+
5
+ ## 亮点
6
+
7
+ - 发布流程新增一键门禁:`npm run release:gate`,统一覆盖格式检查、语法检查、覆盖率门禁、Shell 脚本静态检查、E2E smoke 与打包预演。
8
+ - 回收区治理安全性进一步增强:新增 `realpath` 级边界校验,拦截符号链接越界路径。
9
+ - Agent 无交互脚本失败语义加固:失败时稳定返回非 0 退出码并输出可读错误原因,避免自动化误判成功。
10
+
11
+ ## 重要修复
12
+
13
+ - 修复回收区治理的符号链接逃逸风险(`recycle_path_symlink_escape` / `batch_root_symlink_escape` 等)。
14
+ - 修复 `recycle_maintain` 业务失败场景下无交互契约测试断言,确保“退出码 + JSON 输出”语义一致。
15
+ - 修复报告脚本在 `set -u` 下错误分支变量展开异常,避免失败被错误吞掉。
16
+
17
+ ## 质量状态
18
+
19
+ - 发布门禁:全部通过。
20
+ - 单元测试:`91/91` 通过。
21
+ - 覆盖率(门禁):
22
+ - statements:`88.49%`
23
+ - branches:`75.01%`
24
+ - functions:`95.02%`
25
+ - lines:`88.49%`
26
+
27
+ ## 资产
28
+
29
+ - npm 包:`wecom-cleaner-1.2.1.tgz`
30
+ - GitHub Release 附件:
31
+ - `wecom-cleaner-core-v1.2.1-darwin-x64`
32
+ - `wecom-cleaner-core-v1.2.1-darwin-arm64`
33
+ - `wecom-cleaner-core-v1.2.1-SHA256SUMS.txt`
@@ -1,15 +1,16 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "version": "1.1.0",
4
- "baseUrl": "https://raw.githubusercontent.com/MisonL/wecom-cleaner/v1.1.0/native/bin",
3
+ "version": "1.2.1",
5
4
  "targets": {
6
5
  "darwin-x64": {
7
6
  "binaryName": "wecom-cleaner-core",
8
- "sha256": "d6bc4b2a7b96010889fc11502fe6d76d6f8d395e6df12c44dfc79aa58b17d53c"
7
+ "sha256": "c703a8bdb6df39df776c6a3ab28b3553916d487cf7c38612989566b4ecea34c9",
8
+ "url": "https://github.com/MisonL/wecom-cleaner/releases/download/v1.2.1/wecom-cleaner-core-v1.2.1-darwin-x64"
9
9
  },
10
10
  "darwin-arm64": {
11
11
  "binaryName": "wecom-cleaner-core",
12
- "sha256": "f3babdfe69e83c2d0b99fe1ad525ea836e4f413c01ae2f31b569e35f2ba955f8"
12
+ "sha256": "8d0a15efcb70a266e15c752212f15570c006a931681249d6cd41a1c438941f72",
13
+ "url": "https://github.com/MisonL/wecom-cleaner/releases/download/v1.2.1/wecom-cleaner-core-v1.2.1-darwin-arm64"
13
14
  }
14
15
  }
15
16
  }
@@ -6,12 +6,13 @@ fn isAbsPath(path: []const u8) bool {
6
6
 
7
7
  fn pathSize(path: []const u8) !u64 {
8
8
  const cwd = std.fs.cwd();
9
-
10
9
  const file_res = if (isAbsPath(path)) std.fs.openFileAbsolute(path, .{}) else cwd.openFile(path, .{});
11
10
  if (file_res) |file| {
12
11
  defer file.close();
13
12
  const st = try file.stat();
14
- return st.size;
13
+ if (st.kind != .directory) {
14
+ return st.size;
15
+ }
15
16
  } else |err| {
16
17
  if (err != error.IsDir) {
17
18
  return err;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mison/wecom-cleaner",
3
- "version": "1.1.0",
3
+ "version": "1.2.1",
4
4
  "description": "企业微信本地聊天缓存清理工具(交互式 CLI/TUI)",
5
5
  "author": "MisonL",
6
6
  "license": "MIT",
@@ -43,9 +43,12 @@
43
43
  "format:check": "prettier --check .",
44
44
  "check": "node --check src/*.js",
45
45
  "e2e:smoke": "bash scripts/e2e-smoke.sh",
46
+ "release:gate": "bash scripts/release-gate.sh",
46
47
  "prepack": "npm run build:native:release && npm run check",
47
48
  "pack:tgz": "node scripts/pack-tgz.js",
48
49
  "pack:tgz:dry-run": "node scripts/pack-tgz.js --dry-run",
50
+ "pack:release-assets": "node scripts/pack-release-assets.js",
51
+ "pack:release-assets:dry-run": "node scripts/pack-release-assets.js --dry-run",
49
52
  "skill:install": "node src/skill-cli.js install",
50
53
  "skill:path": "node src/skill-cli.js path"
51
54
  },