agmd 0.4.0 → 1.0.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.
Files changed (83) hide show
  1. package/AGENTS.md +215 -0
  2. package/README.EN.md +106 -9
  3. package/README.md +374 -225
  4. package/agmd.js +55 -0
  5. package/bin/agmd-linux-arm64 +0 -0
  6. package/bin/agmd-linux-x64 +0 -0
  7. package/bin/agmd-windows-x64.exe +0 -0
  8. package/install.js +59 -0
  9. package/package.json +46 -91
  10. package/es6/package.json +0 -91
  11. package/es6/script/cli/handle.js +0 -26
  12. package/es6/script/cli/handle.js.map +0 -1
  13. package/es6/script/cli/index.js +0 -29
  14. package/es6/script/cli/index.js.map +0 -1
  15. package/es6/script/help/index.js +0 -23
  16. package/es6/script/help/index.js.map +0 -1
  17. package/es6/src/bin.js +0 -8
  18. package/es6/src/bin.js.map +0 -1
  19. package/es6/src/commands/agmd.js +0 -24
  20. package/es6/src/commands/agmd.js.map +0 -1
  21. package/es6/src/commands/change-path.js +0 -141
  22. package/es6/src/commands/change-path.js.map +0 -1
  23. package/es6/src/commands/command-actions.js +0 -114
  24. package/es6/src/commands/command-actions.js.map +0 -1
  25. package/es6/src/commands/command-handler.js +0 -132
  26. package/es6/src/commands/command-handler.js.map +0 -1
  27. package/es6/src/commands/get-file.js +0 -162
  28. package/es6/src/commands/get-file.js.map +0 -1
  29. package/es6/src/commands/get-router.js +0 -108
  30. package/es6/src/commands/get-router.js.map +0 -1
  31. package/es6/src/commands/mark-file.js +0 -148
  32. package/es6/src/commands/mark-file.js.map +0 -1
  33. package/es6/src/commands/mark-write-file.js +0 -58
  34. package/es6/src/commands/mark-write-file.js.map +0 -1
  35. package/es6/src/commands/rename-path.js +0 -252
  36. package/es6/src/commands/rename-path.js.map +0 -1
  37. package/es6/src/commands/wirte-md.js +0 -120
  38. package/es6/src/commands/wirte-md.js.map +0 -1
  39. package/es6/src/index.js +0 -4
  40. package/es6/src/index.js.map +0 -1
  41. package/es6/src/shared/constant.js +0 -16
  42. package/es6/src/shared/constant.js.map +0 -1
  43. package/es6/src/types.js +0 -2
  44. package/es6/src/types.js.map +0 -1
  45. package/es6/src/utils/router-utils.js +0 -37
  46. package/es6/src/utils/router-utils.js.map +0 -1
  47. package/lib/package.json +0 -91
  48. package/lib/script/cli/handle.js +0 -31
  49. package/lib/script/cli/handle.js.map +0 -1
  50. package/lib/script/cli/index.js +0 -34
  51. package/lib/script/cli/index.js.map +0 -1
  52. package/lib/script/help/index.js +0 -25
  53. package/lib/script/help/index.js.map +0 -1
  54. package/lib/src/bin.js +0 -10
  55. package/lib/src/bin.js.map +0 -1
  56. package/lib/src/commands/agmd.js +0 -29
  57. package/lib/src/commands/agmd.js.map +0 -1
  58. package/lib/src/commands/change-path.js +0 -153
  59. package/lib/src/commands/change-path.js.map +0 -1
  60. package/lib/src/commands/command-actions.js +0 -131
  61. package/lib/src/commands/command-actions.js.map +0 -1
  62. package/lib/src/commands/command-handler.js +0 -139
  63. package/lib/src/commands/command-handler.js.map +0 -1
  64. package/lib/src/commands/get-file.js +0 -172
  65. package/lib/src/commands/get-file.js.map +0 -1
  66. package/lib/src/commands/get-router.js +0 -150
  67. package/lib/src/commands/get-router.js.map +0 -1
  68. package/lib/src/commands/mark-file.js +0 -160
  69. package/lib/src/commands/mark-file.js.map +0 -1
  70. package/lib/src/commands/mark-write-file.js +0 -65
  71. package/lib/src/commands/mark-write-file.js.map +0 -1
  72. package/lib/src/commands/rename-path.js +0 -270
  73. package/lib/src/commands/rename-path.js.map +0 -1
  74. package/lib/src/commands/wirte-md.js +0 -130
  75. package/lib/src/commands/wirte-md.js.map +0 -1
  76. package/lib/src/index.js +0 -8
  77. package/lib/src/index.js.map +0 -1
  78. package/lib/src/shared/constant.js +0 -22
  79. package/lib/src/shared/constant.js.map +0 -1
  80. package/lib/src/types.js +0 -3
  81. package/lib/src/types.js.map +0 -1
  82. package/lib/src/utils/router-utils.js +0 -42
  83. package/lib/src/utils/router-utils.js.map +0 -1
package/AGENTS.md ADDED
@@ -0,0 +1,215 @@
1
+ # AGENTS.md — agmd (auto-generate-md)
2
+
3
+ > 本文件面向 AI 编程助手。若你对本项目一无所知,请先阅读本文档再修改代码。
4
+
5
+ ---
6
+
7
+ ## 项目概述
8
+
9
+ `agmd` 是一个用 **Rust** 编写的 CLI 工具兼库,用于扫描前端工程目录并自动生成 Markdown 文档、统计代码量、规范化 import 路径、批量重命名文件/文件夹,以及按路由对工程文件进行标记和拆分。
10
+
11
+ - **包名**: `agmd`
12
+ - **版本**: `0.4.0` (Rust crate) / `1.0.0` (npm 包)
13
+ - **协议**: MIT
14
+ - **仓库**: https://github.com/kakajun/auto-generate-md
15
+
16
+ > ⚠️ 当前 `Cargo.toml` (`0.4.0`) 与 `package.json` (`1.0.0`) 版本号不一致,发布前务必同步。
17
+
18
+ 本项目同时提供:
19
+ 1. **Rust 二进制** (`cargo run --bin agmd`) —— 独立可执行文件,零 Node.js 依赖。
20
+ 2. **Rust 库** (`src/lib.rs`) —— 暴露异步 API `get_file_nodes_api` 和 `get_md_api`。
21
+ 3. **npm 包** (根目录 `package.json`) —— 内含多平台预编译二进制,安装时自动匹配当前平台。
22
+
23
+ ---
24
+
25
+ ## 技术栈
26
+
27
+ | 层级 | 技术 |
28
+ |------|------|
29
+ | 语言 | Rust (Edition 2024) |
30
+ | 异步运行时 | Tokio (`features = ["full"]`) |
31
+ | CLI 解析 | clap (derive 宏) |
32
+ | 交互菜单 | dialoguer + console |
33
+ | 序列化 | serde + serde_json |
34
+ | 正则 | regex |
35
+ | 文件遍历 | walkdir |
36
+ | 路径差分 | pathdiff |
37
+ | 命名转换 | convert_case |
38
+ | 测试辅助 | tempfile (dev-dependency) |
39
+ | 分发 | npm 包包裹预编译二进制 |
40
+
41
+ ---
42
+
43
+ ## 项目结构
44
+
45
+ ```
46
+ ├── src/
47
+ │ ├── main.rs # 二进制入口:解析 CLI 参数 + 交互菜单
48
+ │ ├── lib.rs # 库入口:公开模块 + 两个公开 API
49
+ │ ├── cli.rs # clap 派生的 Args 结构体和帮助文本
50
+ │ ├── types.rs # 核心数据结构:FileNode, Options, Router, RouterItem, CountResult, RenameInfo
51
+ │ ├── commands.rs # 高层动作分发器(对应菜单每一项)
52
+ │ ├── utils.rs # 工具函数:正则解析、命名转换、默认忽略/包含列表
53
+ │ ├── get_file.rs # 递归扫描文件系统、提取注释/大小/行数/import
54
+ │ ├── write_md.rs # 生成 Markdown、统计输出、codeAndPrompt.md
55
+ │ ├── change_path.rs # 批量重写 import 路径(相对 ↔ @ 别名)
56
+ │ ├── rename_path.rs # 批量重命名文件/文件夹(kebab-case ↔ CamelCase)
57
+ │ ├── get_router.rs # 解析 router 配置或 classify.js
58
+ │ ├── mark_file.rs # 按路由给文件打标记(//markname)
59
+ │ ├── mark_write_file.rs # 按标记分类复制文件到路由目录
60
+ │ └── bin/ # 开发调试用的独立可执行脚本(硬编码本地路径)
61
+ ├── tests/ # 集成测试与单元测试
62
+ │ ├── integration_test.rs
63
+ │ ├── get_file_tests.rs
64
+ │ ├── router_tests.rs
65
+ │ ├── utils_tests.rs
66
+ │ ├── write_md_tests.rs
67
+ │ └── rename_path_tests.rs
68
+ ├── bin/ # 预编译二进制存放目录(多平台分发)
69
+ ├── imgs/ # 文档图片(README 引用)
70
+ ├── Cargo.toml # Rust 包配置
71
+ ├── package.json # npm 包配置(含 files、scripts、bin)
72
+ ├── agmd.js # Node 入口:检测平台并 spawn 二进制
73
+ ├── install.js # postinstall:复制对应平台二进制到 agmd / agmd.exe
74
+ ├── .cargo/config.toml # 交叉编译链接器配置
75
+ ├── .github/workflows/test.yml # CI(Rust 原生测试)
76
+ ├── classify.js # 路由分类配置示例(@/ 别名路径)
77
+ ├── README.md # 中文文档(主文档)
78
+ └── README.EN.md # 英文文档
79
+ ```
80
+
81
+ ---
82
+
83
+ ## 构建与测试命令
84
+
85
+ ### 日常开发
86
+
87
+ ```bash
88
+ # 编译调试版本
89
+ cargo build
90
+
91
+ # 编译 release 版本
92
+ cargo build --release
93
+
94
+ # 运行所有测试(36+ 个)
95
+ cargo test
96
+
97
+ # 运行单个测试并打印输出
98
+ cargo test <测试名> -- --nocapture
99
+
100
+ # 直接运行 CLI
101
+ cargo run --bin agmd
102
+ ```
103
+
104
+ ### 交叉编译 / 发布
105
+
106
+ 项目支持多平台二进制分发。参考 `.cargo/config.toml` 中已配置的交叉编译目标:
107
+
108
+ - `aarch64-unknown-linux-gnu`
109
+ - `x86_64-pc-windows-gnu`
110
+
111
+ 完整发布流程见 `README.md` 中「开发者打包发布说明」一节。发布前必须同步以下文件的版本号:
112
+ - `Cargo.toml`
113
+ - `package.json`
114
+
115
+ 编译后将二进制复制到 `bin/` 并执行 `npm publish`。
116
+
117
+ ### npm 脚本
118
+
119
+ ```bash
120
+ npm run build # => cargo build --release
121
+ npm run test # => cargo test
122
+ ```
123
+
124
+ ---
125
+
126
+ ## 代码组织与模块划分
127
+
128
+ ### 核心流程
129
+
130
+ 1. **扫描** (`get_file.rs`) —— 递归读取目录,构建 `FileNode` 树,提取文件元数据(大小、行数、首行注释、import 语句)。
131
+ 2. **输出** (`write_md.rs`) —— 将 `FileNode` 树渲染为 Markdown,或输出 `codeAndPrompt.md`(目录树 + 完整源码)。
132
+ 3. **路径操作** (`change_path.rs`) —— 根据 `FileNode` 中的 `imports`,批量替换文件内的 `from '...'` 路径:支持「相对路径 → `@` 别名」和「`@` 别名 → 相对路径」两种方向,以及仅补全后缀的模式。
133
+ 4. **重命名** (`rename_path.rs`) —— 对文件/文件夹在 `kebab-case` 与 `CamelCase`/`UpperCamelCase` 之间批量转换,并同步更新文件内的 import 路径。Windows 下对大小写不敏感文件系统采用“先临时重命名再最终重命名”的策略。
134
+ 5. **路由与标记** (`get_router.rs` → `mark_file.rs` → `mark_write_file.rs`) —— 解析路由配置,沿组件依赖链注入标记注释,最后按路由将文件复制到独立目录。
135
+
136
+ ### 数据结构中心
137
+
138
+ 所有跨模块传递的数据结构定义在 `src/types.rs`:
139
+ - `Options` —— 扫描/操作的全局选项(ignore, include, dry_run, silent)。
140
+ - `FileNode` —— 文件/目录树节点,含子节点、import 列表、所属路由等。
141
+ - `Router` / `RouterItem` —— 路由配置结构。
142
+ - `CountResult` —— 统计结果(总行数、总字符数、按后缀计数)。
143
+ - `RenameInfo` —— 重命名前后名称映射。
144
+
145
+ ### 交互入口
146
+
147
+ `main.rs` 使用 `dialoguer::Select` 提供中文交互菜单,共 14 个选项,对应 `commands.rs` 中的动作函数。
148
+
149
+ ---
150
+
151
+ ## 代码风格规范
152
+
153
+ 1. **注释语言**:代码注释和文档字符串以 **中文** 为主。新增注释请保持中文。
154
+ 2. **错误处理**:统一使用 `anyhow::Result` 进行错误传播,顶层 `main` 函数直接返回 `Result`。
155
+ 3. **异步**:IO 密集型操作使用 `tokio` 异步 API(如 `tokio::fs`),公开 API 均为 `async fn`。
156
+ 4. **命名**:
157
+ - 模块/函数:蛇形命名(`get_file_nodes`, `change_path_sync`)。
158
+ - 结构体:大驼峰(`FileNode`, `Options`)。
159
+ - 布尔标志字段:以动词或状态命名(`dry_run`, `is_dir`, `copyed`)。
160
+ 5. **序列化**:对外暴露的数据结构使用 `serde` 的 `Serialize`/`Deserialize` derive,可选字段配合 `skip_serializing_if = "Option::is_none"`。
161
+ 6. **不安全代码**:仅在 `mark_file.rs` 和 `mark_write_file.rs` 中使用 `unsafe` 指针技巧实现可变树遍历(`find_nodes_mut`)。修改此类代码需格外谨慎。
162
+ 7. **字符串处理**:路径和文本处理大量使用 `regex` 进行解析(如 `parse_router_path`, `parse_component_path`)。
163
+
164
+ ---
165
+
166
+ ## 测试策略
167
+
168
+ 测试全部位于 `tests/` 目录,按功能分文件:
169
+
170
+ | 测试文件 | 覆盖内容 |
171
+ |----------|----------|
172
+ | `integration_test.rs` | 端到端集成测试:临时目录构造真实文件,测试扫描、路径替换、后缀补全、两遍绝对路径操作等 |
173
+ | `get_file_tests.rs` | `resolve_alias_path`, `get_relative_path`, `change_import`, `set_md`, `get_note` |
174
+ | `router_tests.rs` | `parse_router_path`, `parse_component_path` 的正则解析 |
175
+ | `utils_tests.rs` | 命名转换、数字格式化、默认列表等工具函数 |
176
+ | `write_md_tests.rs` | `get_count_md`, `set_count_md` 统计与 Markdown 格式化 |
177
+ | `rename_path_tests.rs` | 路径转换、真实文件系统重命名(含嵌套目录和 Windows 大小写处理)|
178
+
179
+ ### 运行建议
180
+
181
+ ```bash
182
+ # 全量测试
183
+ cargo test
184
+
185
+ # 查看测试覆盖率(若已安装 cargo-tarpaulin)
186
+ cargo tarpaulin --out Html
187
+ ```
188
+
189
+ ### 新增功能的测试约定
190
+
191
+ - 凡涉及文件系统写入的操作,优先使用 `tempfile::TempDir` 构造隔离环境。
192
+ - `dry_run` 模式应在测试中被覆盖,确保不会实际修改文件系统。
193
+ - 涉及 import 路径替换的测试需覆盖:同级目录、兄弟目录、深层目录、`@` 别名互转、仅补全后缀等场景。
194
+
195
+ ---
196
+
197
+ ## 安全与注意事项
198
+
199
+ 1. **文件系统写入**:`dry_run` 模式仅用于预览,但代码中仍有多处直接 `fs::write` / `rename`。修改路径操作相关代码时,务必检查 `dry_run` 和 `silent` 标志是否正确传递。
200
+ 2. **Windows 大小写敏感**:`rename_path.rs` 对 Windows 文件系统做了特殊处理(临时重命名策略)。改动重命名逻辑时应在 Windows 环境验证。
201
+ 3. **npm 分发安全**:`bin/` 中的预编译二进制按惯例不纳入 Git 跟踪(`.gitignore` 已排除)。发布时需手动将可信构建产物放入该目录。
202
+ 4. **classify.js 路径格式**:路由分类功能要求配置中使用 `@/` 开头的别名路径。若扩展路由解析逻辑,需保持对该约定的兼容。
203
+ 5. **开发调试脚本**:`src/bin/` 下的多个测试二进制硬编码了本地路径(如 `E:\cwd\front1.5`)。这些文件仅供原作者本地调试,不应作为通用入口依赖。
204
+
205
+ ---
206
+
207
+ ## 快速参考
208
+
209
+ | 目标 | 命令 |
210
+ |------|------|
211
+ | 本地运行 CLI | `cargo run --bin agmd` |
212
+ | 运行全部测试 | `cargo test` |
213
+ | Release 构建 | `cargo build --release` |
214
+ | 构建 Windows GNU 目标 | `cargo build --release --target x86_64-pc-windows-gnu` |
215
+ | 发布 npm 包 | 同步版本号后 `npm publish` |
package/README.EN.md CHANGED
@@ -10,17 +10,22 @@
10
10
  - Classify files by routes and export JSON of nodes
11
11
  - Interactive CLI for all operations
12
12
  - Output the full tree as JSON
13
- - TypeScript implementation with extensive tests
14
- - Convert relative imports to absolute alias-based paths using `@` (new)
13
+ - Convert relative imports to absolute alias-based paths using `@`
14
+ - **v2 rewritten in Rust 10x faster, zero Node.js dependency**
15
15
 
16
16
  ## Usage
17
+
18
+ **v2 is built with Rust and distributed via npm as precompiled binaries. No Rust toolchain required.**
19
+
17
20
  - Global: `npm i agmd -g`
18
21
  - Local: `npm i agmd -D`
19
22
  - Run: `agmd` in the directory you want to document
20
23
 
21
24
  The generated Markdown (`readme-md.md`) contains:
22
- - A Directory Structure section
23
- - A Statistics section with totals per suffix, lines and characters
25
+ - A "Directory Structure" section
26
+ - A "Statistics" section with totals per suffix, lines and characters
27
+
28
+ When you install via npm, the `postinstall` script automatically downloads the correct precompiled binary for your platform (Linux x64/ARM64, macOS x64/ARM64, Windows x64).
24
29
 
25
30
  ## Scripts
26
31
  Add to `package.json`:
@@ -56,12 +61,104 @@ Example:
56
61
  ## Advanced
57
62
  Create `classify.js` at the project root to define route-based classification. Use `@` alias paths in the config. If missing, the tool scans `router/` automatically.
58
63
 
59
- ## API
60
- - `getFileNodes(option?)` Get detailed file info
61
- - `getMd(option?)` Get composed Markdown string and nodes
64
+ ## Rust Library API
65
+
66
+ ```rust
67
+ use agmd::{get_file_nodes_api, get_md_api, types::Options};
68
+ use std::path::Path;
62
69
 
63
- `option: { ignore?: string[]; include?: string[] }`
70
+ let option = Options {
71
+ ignore: Some(vec!["node_modules".to_string()]),
72
+ include: Some(vec![".rs".to_string()]),
73
+ ..Default::default()
74
+ };
75
+
76
+ // Get file node tree
77
+ let nodes = get_file_nodes_api(Path::new("./src"), Some(&option)).await?;
78
+
79
+ // Get Markdown output
80
+ let (md, nodes) = get_md_api(Some(&option), Path::new(".")).await?;
81
+ ```
64
82
 
65
83
  ## Notes
66
84
  - Prefer running path operations inside `src` due to alias resolution conventions
67
- - Dry-run and silent modes are supported across write operations
85
+ - Dry-run and silent modes are supported across write operations
86
+
87
+ ## Changelog
88
+
89
+ ### v2.0.0
90
+ - **Completely rewritten in Rust**
91
+ - 10x+ performance improvement for large projects
92
+ - Zero Node.js runtime dependency — single binary distribution
93
+ - Multi-platform support: Linux x64/ARM64, macOS x64/ARM64, Windows x64
94
+ - npm package includes all platform binaries, auto-selects on install
95
+ - Smaller install footprint
96
+
97
+ ## Developer Build & Publish Guide
98
+
99
+ v2 is written in Rust. The npm package distributes precompiled binaries for all platforms.
100
+
101
+ ### Build Steps
102
+
103
+ 1. **Compile binaries for each platform**
104
+
105
+ Run on each target platform (or cross-compile):
106
+
107
+ ```bash
108
+ # Linux x64
109
+ cargo build --release --target x86_64-unknown-linux-gnu
110
+ cp target/x86_64-unknown-linux-gnu/release/agmd bin/agmd-linux-x64
111
+
112
+ # Linux ARM64
113
+ cargo build --release --target aarch64-unknown-linux-gnu
114
+ cp target/aarch64-unknown-linux-gnu/release/agmd bin/agmd-linux-arm64
115
+
116
+ # macOS x64
117
+ cargo build --release --target x86_64-apple-darwin
118
+ cp target/x86_64-apple-darwin/release/agmd bin/agmd-macos-x64
119
+
120
+ # macOS ARM64
121
+ cargo build --release --target aarch64-apple-darwin
122
+ cp target/aarch64-apple-darwin/release/agmd bin/agmd-macos-arm64
123
+
124
+ # Windows x64
125
+ cargo build --release --target x86_64-pc-windows-msvc
126
+ cp target/x86_64-pc-windows-msvc/release/agmd.exe bin/agmd-windows-x64.exe
127
+ ```
128
+
129
+ 2. **Make binaries executable**
130
+
131
+ ```bash
132
+ chmod +x bin/agmd-linux-* bin/agmd-macos-*
133
+ ```
134
+
135
+ 3. **Bump version**
136
+
137
+ Update version in both:
138
+ - `Cargo.toml`
139
+ - `package.json`
140
+
141
+ 4. **Publish to npm**
142
+
143
+ ```bash
144
+ npm publish
145
+ ```
146
+
147
+ Make sure you are logged in: `npm login`
148
+
149
+ ### npm Package Structure
150
+
151
+ ```
152
+ ├── package.json # npm package config
153
+ ├── agmd.js # Entry script, detects platform and spawns binary
154
+ ├── install.js # postinstall, copies platform binary as 'agmd'
155
+ ├── bin/ # Precompiled binaries
156
+ │ ├── agmd-linux-x64
157
+ │ ├── agmd-linux-arm64
158
+ │ ├── agmd-macos-x64
159
+ │ ├── agmd-macos-arm64
160
+ │ └── agmd-windows-x64.exe
161
+ └── ...
162
+ ```
163
+
164
+ On install, the `postinstall` script detects the current platform, copies the matching binary from `bin/`, and renames it to `agmd`. No network download required.