mirror of
https://github.com/LHY0125/PathEditor.git
synced 2026-06-30 02:25:55 +08:00
Compare commits
3 Commits
21af2683ac
..
v5.0.0
| Author | SHA1 | Date | |
|---|---|---|---|
| 44a4a4ccf3 | |||
| dc36d63302 | |||
| 6822ab9f3e |
@@ -0,0 +1,171 @@
|
||||
# CLAUDE.md
|
||||
|
||||
## 项目概述
|
||||
|
||||
PathEditor v5.0 — Windows 系统环境变量 (PATH) 编辑器,Tauri 2.x + React 19 + TypeScript + Rust workspace 构建。GUI + CLI 双模式。
|
||||
|
||||
## 构建命令
|
||||
|
||||
```bash
|
||||
# 安装前端依赖
|
||||
npm install
|
||||
|
||||
# 开发模式(GUI 热更新)
|
||||
npx tauri dev
|
||||
|
||||
# 仅前端(浏览器预览,无注册表功能)
|
||||
npm run dev
|
||||
|
||||
# 前端测试
|
||||
npm test
|
||||
npm run test:watch
|
||||
|
||||
# Rust workspace 全部检查
|
||||
cargo check
|
||||
|
||||
# 仅核心库检查
|
||||
cargo check -p path-editor-core
|
||||
|
||||
# CLI 构建
|
||||
cargo build --release -p patheditor-cli
|
||||
|
||||
# 生产构建(前端)
|
||||
npm run build
|
||||
|
||||
# 完整构建(生成 NSIS 安装包)
|
||||
npx tauri build
|
||||
```
|
||||
|
||||
## 架构
|
||||
|
||||
Cargo workspace 三层,前后端分离,通过 Tauri IPC 通信。
|
||||
|
||||
```
|
||||
PathEditor/
|
||||
├── core/ # Rust 库 crate(零 Tauri 依赖)
|
||||
│ └── src/
|
||||
│ ├── registry.rs # 注册表读写 + clean_paths
|
||||
│ ├── system.rs # check_admin、validate_path、expand_env_vars、broadcast
|
||||
│ ├── backup.rs # backup_registry、get_appdata_dir
|
||||
│ ├── disabled.rs # save/load_disabled_state
|
||||
│ ├── fs.rs # read_text_file、import_paths、export_paths
|
||||
│ ├── scanner.rs # scan_conflicts、scan_tools
|
||||
│ ├── profiles.rs # list/save/load/delete/rename_profile
|
||||
│ └── lib.rs
|
||||
├── gui/ # Tauri 桌面应用(依赖 core)
|
||||
│ └── src/commands/ # 薄包装:#[tauri::command] → 调用 core
|
||||
├── cli/ # CLI 命令行(依赖 core + clap)
|
||||
│ └── src/main.rs # 18 条命令
|
||||
├── src/ # React 前端 (TypeScript strict 模式)
|
||||
│ ├── core/ # 纯逻辑 — 零 React/零 Tauri 依赖
|
||||
│ ├── store/ # Zustand 状态管理
|
||||
│ ├── components/ # UI 组件
|
||||
│ │ ├── layout/ # AppShell、TitleBar、StatusBar、ErrorBoundary
|
||||
│ │ ├── path-list/ # PathTable、MergePreview
|
||||
│ │ ├── toolbar/ # ToolBar、ActionButtons、UndoRedoButtons
|
||||
│ │ ├── dialogs/ # PathEdit、Help、Import、Analyze、Profile
|
||||
│ │ └── ui/ # Modal、buttons
|
||||
│ ├── hooks/ # useAppActions、useKeyboard
|
||||
│ ├── i18n/ # zh-CN / en
|
||||
│ └── config/ # default.json
|
||||
├── tests/unit/ # Vitest 前端单元测试
|
||||
├── e2e/ # Playwright E2E 测试
|
||||
└── Cargo.toml # Workspace 根 + [workspace.package]
|
||||
```
|
||||
|
||||
## IPC 接口(Rust → Frontend)
|
||||
|
||||
| Command | 参数 | 返回值 | 功能 |
|
||||
|---------|------|--------|------|
|
||||
| `load_system_paths` | — | `Result<Vec<String>, String>` | 从 HKLM 读取系统 PATH |
|
||||
| `load_user_paths` | — | `Result<Vec<String>, String>` | 从 HKCU 读取用户 PATH |
|
||||
| `save_system_paths` | `paths: Vec<String>` | `Result<(), String>` | 保存系统 PATH(含 32767 字符上限) |
|
||||
| `save_user_paths` | `paths: Vec<String>` | `Result<(), String>` | 保存用户 PATH |
|
||||
| `check_admin` | — | `bool` | 检测管理员权限 |
|
||||
| `validate_path` | `path: &str` | `bool` | 检查目录是否存在 |
|
||||
| `expand_env_vars` | `path: &str` | `String` | 展开 `%VAR%` |
|
||||
| `broadcast_env_change` | — | `()` | 广播 `WM_SETTINGCHANGE` |
|
||||
| `backup_registry` | `custom_dir` | `Result<String, String>` | 备份注册表 |
|
||||
| `get_appdata_dir` | — | `String` | 备份目录路径 |
|
||||
| `save_disabled_state` | `system, user` | `Result<(), String>` | 持久化禁用状态 |
|
||||
| `load_disabled_state` | — | `Result<(Vec, Vec), String>` | 加载禁用状态 |
|
||||
| `read_text_file` | `path` | `Result<String, String>` | 读取文本文件 |
|
||||
| `scan_conflicts` | `paths` | `Result<Vec<ConflictEntry>, String>` | 可执行文件冲突检测 |
|
||||
| `scan_tools` | `paths, query` | `Result<Vec<ToolGroup>, String>` | 可执行文件清单 |
|
||||
| `list_profiles` | — | `Result<Vec<ProfileMeta>, String>` | 列出配置 |
|
||||
| `save_profile` | `name, sys, user` | `Result<(), String>` | 保存配置 |
|
||||
| `load_profile` | `name` | `Result<ProfileData, String>` | 加载配置 |
|
||||
| `delete_profile` | `name` | `Result<(), String>` | 删除配置 |
|
||||
| `rename_profile` | `old, new` | `Result<(), String>` | 重命名配置 |
|
||||
|
||||
## CLI 命令参考
|
||||
|
||||
```
|
||||
patheditor list [--system|--user] [--json]
|
||||
patheditor add <PATH> [--system|--user]
|
||||
patheditor remove <INDEX> [--system|--user]
|
||||
patheditor edit <INDEX> <NEW> [--system|--user]
|
||||
patheditor move-up <INDEX> [--steps N] [--system|--user]
|
||||
patheditor move-down <INDEX> [--steps N] [--system|--user]
|
||||
patheditor clean [--system|--user] [--dry-run] [--json]
|
||||
patheditor enable <INDEX> [--system|--user]
|
||||
patheditor disable <INDEX> [--system|--user]
|
||||
patheditor import <FILE> [--target system|user|both]
|
||||
patheditor export [--format json|csv|txt] [--output <FILE>]
|
||||
patheditor backup
|
||||
patheditor conflicts [--json]
|
||||
patheditor scan [--query <NAME>] [--json]
|
||||
patheditor check-admin [--json]
|
||||
patheditor profile {list|save|load|apply|delete|rename}
|
||||
```
|
||||
|
||||
所有修改操作在保存前重新读取注册表验证,防止覆盖其他进程的修改。
|
||||
|
||||
## 错误处理
|
||||
|
||||
### 前端
|
||||
|
||||
| 场景 | 处理 |
|
||||
|------|------|
|
||||
| IPC 调用失败 | `Promise.allSettled` 精确报告哪个 hive 保存失败 |
|
||||
| JSON 文件损坏 | `importFromJson` try/catch,返回空结果 |
|
||||
| 保存并发双击 | `isSaving` 守卫,第二次调用直接 return |
|
||||
| 备份创建失败 | `.catch()` 显示 warning_backup,保存继续 |
|
||||
| 渲染异常 | ErrorBoundary 捕获 + console.error + 重试按钮 |
|
||||
|
||||
### Rust / CLI
|
||||
|
||||
- 注册表操作:全部返回 `Result<T, String>`,中文错误消息
|
||||
- FFI 调用:失败时 `log::warn` + 返回安全回退值
|
||||
- PATH 长度:写入前检查 32767 字符上限
|
||||
- SAFETY 注释:所有 `unsafe` 块均有文档
|
||||
- CLI 原子性:保存前重新读取注册表与加载值对比,不一致报错退出
|
||||
|
||||
## 关键约束
|
||||
|
||||
- **TypeScript**:`strict: true`,零编译错误
|
||||
- **Rust 工具链**:`stable-x86_64-pc-windows-gnu`(项目已设 override)
|
||||
- **MinGW 兼容**:`.cargo/config.toml` 添加 `-lmcfgthread`(GCC 15.2.0 运行时)
|
||||
- **运行权限**:需要管理员权限才能编辑系统 PATH,非管理员自动进入只读模式
|
||||
- **构建产物**:NSIS 安装包,约 8MB
|
||||
|
||||
## 版本号升级清单
|
||||
|
||||
版本号需在 **4 个地方** 手动修改:
|
||||
|
||||
| 文件 | 字段 | 说明 |
|
||||
|------|------|------|
|
||||
| `Cargo.toml` | `[workspace.package] version` | Rust 全量自动继承(3 crate + `env!("CARGO_PKG_VERSION")`) |
|
||||
| `package.json` | `version` | 前端动态 import(TitleBar、import-export.ts 自动读取) |
|
||||
| `gui/tauri.conf.json` | `version` | 打包版本号 |
|
||||
| `gui/tauri.conf.json` | 窗口 `title` | 窗口标题栏显示 |
|
||||
| `README.md` | badges | 文档徽章 |
|
||||
|
||||
其他位置均从上述两源头动态读取,无需单独修改:
|
||||
- `core/src/fs.rs` / `cli/src/main.rs` → `env!("CARGO_PKG_VERSION")`
|
||||
- `src/components/layout/TitleBar.tsx` → `import { version } from '../../../package.json'`
|
||||
- `src/core/import-export.ts` → `import { version } from '../../package.json'`
|
||||
|
||||
Release 操作:
|
||||
- `gh release create vX.Y.Z` 创建新 Release
|
||||
- 安装包上传到新 Release,**不要**覆盖旧版本
|
||||
@@ -35,15 +35,21 @@ graph TB
|
||||
Store --> Core
|
||||
end
|
||||
|
||||
subgraph CLI["CLI 命令行"]
|
||||
Clap[clap 参数解析<br/>18 条命令]
|
||||
Atomic[原子性保护<br/>verify_and_save]
|
||||
end
|
||||
|
||||
subgraph IPC["Tauri IPC 桥接"]
|
||||
invoke[invoke / plugin-dialog]
|
||||
end
|
||||
|
||||
subgraph 后端["Rust 后端"]
|
||||
subgraph 后端["Rust core 库"]
|
||||
Registry[注册表读写<br/>HKLM / HKCU]
|
||||
System[系统操作<br/>权限检测 / 路径验证 / 环境变量展开]
|
||||
Files[文件操作<br/>备份 / 配置 / 导入读取]
|
||||
Files[文件操作<br/>备份 / 配置 / 导入导出]
|
||||
Scanner[分析引擎<br/>冲突检测 / 工具清单]
|
||||
Profiles[配置管理<br/>save/load/apply/rename]
|
||||
end
|
||||
|
||||
subgraph Windows["Windows 系统"]
|
||||
@@ -56,10 +62,18 @@ graph TB
|
||||
invoke --> System
|
||||
invoke --> Files
|
||||
invoke --> Scanner
|
||||
invoke --> Profiles
|
||||
Clap --> Atomic
|
||||
Atomic --> Registry
|
||||
Atomic --> System
|
||||
Atomic --> Files
|
||||
Atomic --> Scanner
|
||||
Atomic --> Profiles
|
||||
Registry --> Reg
|
||||
System --> FS
|
||||
Scanner --> FS
|
||||
Files --> FS
|
||||
Profiles --> FS
|
||||
```
|
||||
|
||||
### 组件树
|
||||
@@ -109,12 +123,39 @@ sequenceDiagram
|
||||
Z->>UI: isModified → false, statusMessage → '保存成功'
|
||||
```
|
||||
|
||||
### CLI 操作流程
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
actor U as 用户
|
||||
participant CLI as patheditor
|
||||
participant Core as Rust core 库
|
||||
participant Win as Windows
|
||||
|
||||
U->>CLI: patheditor add "D:\Tools" --system
|
||||
CLI->>Core: load_system_paths() → 旧列表
|
||||
CLI->>CLI: 执行操作 (push / splice / clean)
|
||||
CLI->>Core: load_system_paths() → 重新读取
|
||||
alt 注册表未修改
|
||||
CLI->>Core: save_system_paths(new_list)
|
||||
Core->>Win: RegSetValueEx()
|
||||
CLI->>Core: broadcast_env_change()
|
||||
Core->>Win: SendMessageTimeout(WM_SETTINGCHANGE)
|
||||
CLI-->>U: 已添加到系统 PATH
|
||||
else 注册表已被其他进程修改
|
||||
CLI-->>U: 错误: 注册表已被其他进程修改
|
||||
end
|
||||
```
|
||||
|
||||
## CLI 命令行
|
||||
|
||||
```bash
|
||||
# 安装
|
||||
cargo install --path cli
|
||||
|
||||
# 安装后可直接使用:
|
||||
patheditor --help
|
||||
|
||||
# 查看 PATH
|
||||
patheditor list --system --json
|
||||
|
||||
@@ -126,7 +167,7 @@ patheditor profile save "Python开发"
|
||||
patheditor profile apply "Python开发"
|
||||
```
|
||||
|
||||
完整 17 条命令:`patheditor --help`
|
||||
完整 18 条命令:`patheditor --help`
|
||||
|
||||
## 功能
|
||||
|
||||
@@ -230,7 +271,7 @@ core/ # Rust 核心库(零 Tauri 依赖)
|
||||
gui/ # Tauri 桌面应用
|
||||
└── src/commands/ # 薄包装 → 调用 core
|
||||
cli/ # 命令行工具
|
||||
└── src/main.rs # 17 条命令
|
||||
└── src/main.rs # 18 条命令
|
||||
src/ # React 前端
|
||||
├── core/ # 纯逻辑 — 零框架依赖
|
||||
├── store/ # Zustand 状态管理
|
||||
|
||||
@@ -6,6 +6,10 @@ edition.workspace = true
|
||||
license.workspace = true
|
||||
authors.workspace = true
|
||||
|
||||
[[bin]]
|
||||
name = "patheditor"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
path-editor-core = { path = "../core" }
|
||||
clap = { version = "4", features = ["derive"] }
|
||||
|
||||
Reference in New Issue
Block a user