@iyowei/sweep-node-modules 0.1.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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 iYoWei
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 ADDED
@@ -0,0 +1,88 @@
1
+ # sweep-node-modules
2
+
3
+ 工作区级 `node_modules` 清理工具: 一次扫描多个根目录, 跨项目列出各处 `node_modules` 与体积, 确认后批量删除, 回收磁盘空间。
4
+
5
+ > 分层说明: 单项目清理工具管「进入某个项目, 清它自己的产物」; 本工具管「站在工作区层面, 一次清理很多个项目」。两者分层共存, 见 [ADR 0001](docs/adrs/0001-workspace-level-cleaner.md)。
6
+
7
+ ## 要求
8
+
9
+ - 运行时二选一: **bun 或 node** 皆可 (双运行时, 装任一即可用)。
10
+ - 取最新一代运行时 API: bun 任意近期版本; node 需原生支持 TypeScript 直跑的版本 (版本快照与实测记录见 [ADR 0006](docs/adrs/0006-dual-runtime-bun-first.md))。
11
+ - 零第三方运行时依赖 (只用运行时内置能力)。
12
+ - 平台: Windows / macOS / Linux 三平台均可运行 (见 [ADR 0007](docs/adrs/0007-platform-portability.md))。
13
+
14
+ ## 安装
15
+
16
+ **npm** (推荐):
17
+
18
+ ```shell
19
+ npm install -g @iyowei/sweep-node-modules
20
+ ```
21
+
22
+ **从源码**:
23
+
24
+ ```shell
25
+ chmod +x bin/sweep-nm
26
+
27
+ # 软链进 ~/.local/bin, 启动器会挑选运行时 (Bun 优先, Node 回退)
28
+ ln -sf "$HOME/self/development/sweep-node-modules/bin/sweep-nm" ~/.local/bin/sweep-nm
29
+ ```
30
+
31
+ > 两种方式都支持 Bun / Node 双运行时 (装任一即可用); 从源码安装的 Windows 用户入口为 `bin\sweep-nm.cmd`。
32
+
33
+ ## 使用
34
+
35
+ ```shell
36
+ # 预览: 列出配置中各根目录下所有 node_modules 与体积, 不动手
37
+ sweep-nm
38
+
39
+ # 复核无误后执行删除
40
+ sweep-nm --yes
41
+
42
+ # 临时追加排除(可重复)
43
+ sweep-nm --exclude my-kits --exclude url-tool
44
+
45
+ # 初始化向导: 交互式生成配置文件
46
+ sweep-nm init
47
+ ```
48
+
49
+ ## 配置
50
+
51
+ 配置文件位置 (平台自适应): Windows 为 `%APPDATA%\sweep-node-modules\config.json`, 其余为 `~/.config/sweep-node-modules/config.json`; 可用 `--config` 或环境变量 `SWEEP_NM_CONFIG` 覆盖。
52
+
53
+ ```json
54
+ {
55
+ "roots": [
56
+ "/Users/iyowei/workspace/development",
57
+ "/Users/iyowei/self/development"
58
+ ],
59
+ "exclude": ["my-kits"]
60
+ }
61
+ ```
62
+
63
+ - `roots`: 扫描根目录, 任意多个; 重复或嵌套的根按真实路径去重。
64
+ - `exclude`: 排除名单; 从根到 `node_modules` 的任意一级目录名命中即跳过 (多排除 = 少删, 安全方向)。
65
+ - 首次运行且无配置: 交互终端下自动进入初始化向导; 非交互环境 (脚本等) 以当前工作目录为根并提示, 不询问; 随时可用 `sweep-nm init` 重进向导。
66
+
67
+ > 字段定义以[设计文档](docs/designs/config-and-initialization.md)为准。
68
+
69
+ ## 开发
70
+
71
+ ```shell
72
+ bun install # 安装 devDependencies, 并自动装好 git 钩子 (lefthook)
73
+
74
+ bun run typecheck # tsc --noEmit
75
+ bun run lint # oxlint
76
+ bun run format # prettier --write
77
+ bun test # bun test (243 条: 契约 / 鲁棒 / 压测 / 双载体 e2e / 伪终端冒烟)
78
+ bun run bench # 基准四组 (扫描 / 体积 / 真实工作区 / 压测)
79
+ bun run conformance -- --target "bun src/cli.ts" # 转写一致性验收 (40 条金样本, 见 docs/protocol/)
80
+ ```
81
+
82
+ 运行时双跑验证: `bun src/cli.ts` 与 `node src/cli.ts` 均可直接运行。
83
+
84
+ 提交与推送由 lefthook 把关: pre-commit 增量 (prettier 重暂存 + oxlint + 全量类型检查), pre-push 全量只读 (typecheck / test / oxlint / prettier `--check`)。
85
+
86
+ ## 文档
87
+
88
+ - [工程技术文档总索引](docs/README.md)
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * npm 安装场景的启动器: 挑选运行时 (Bun 优先, 其次 Node) 后启动真实入口。
4
+ * 与 bin/sweep-nm (sh) / bin/sweep-nm.cmd (cmd) 同逻辑, 三者的差异只在宿主:
5
+ * 本文件同时承担 Unix 与 Windows 的 npm shim 目标 (shebang 必须是 node, 否则
6
+ * npm 的 cmd-shim 会按 shebang 解释器生成 Windows 上不存在的调用)。
7
+ * 退出码原样透传; 两个运行时都缺席时给出可操作提示并非零退出。
8
+ */
9
+ import { spawnSync } from 'node:child_process';
10
+ import { existsSync } from 'node:fs';
11
+ import { dirname, join } from 'node:path';
12
+ import { fileURLToPath } from 'node:url';
13
+
14
+ /** 探测命令是否可执行 (以 --version 的实际退出码为准, 不依赖 shell 内建) */
15
+ const available = (command) =>
16
+ spawnSync(command, ['--version'], { stdio: 'ignore' }).status === 0;
17
+
18
+ /** 挑选运行时: Bun 优先, 其次 Node; 皆无则 null (由调用处报错退出) */
19
+ const pickRuntime = () => {
20
+ if (available('bun')) return 'bun';
21
+ if (available('node')) return 'node';
22
+ return null;
23
+ };
24
+
25
+ const root = dirname(dirname(fileURLToPath(import.meta.url)));
26
+ // npm 包内是编译产物 (node 拒绝对 node_modules 内的 TS 做类型剥离, 见 package.json 的 build 脚本);
27
+ // 仓库开发态无 dist, 回退直跑源码 (bun / node 皆可)
28
+ const built = join(root, 'dist', 'cli.js');
29
+ const entry = existsSync(built) ? built : join(root, 'src', 'cli.ts');
30
+ const runtime = pickRuntime();
31
+
32
+ if (runtime === null) {
33
+ process.stderr.write('sweep-nm: 未找到 bun 或 node, 请至少安装其一\n');
34
+ process.exit(1);
35
+ }
36
+
37
+ const { status } = spawnSync(runtime, [entry, ...process.argv.slice(2)], {
38
+ stdio: 'inherit',
39
+ });
40
+
41
+ process.exit(status ?? 1);