Pi Session Manager

贡献指南

如何为 Pi Session Manager 做贡献。

"预测未来的最好方式就是去实现它。" — David Heinemeier Hansson

我们欢迎对 Pi Session Manager 的贡献!以下是入门指南。

前置要求

  • Node.js 20+,需安装 pnpm
  • Rust stable(通过 rustup 安装)
  • Tauri CLI(cargo install tauri-cli

环境搭建

克隆仓库

git clone https://github.com/Dwsy/pi-session-manager.git
cd pi-session-manager

安装依赖

pnpm install

启动开发模式

pnpm run tauri:dev

这将同时启动 Vite 开发服务器(支持 HMR)和 Rust 后端。

项目结构

src/                          # 前端(React + TypeScript)
  components/                 #   UI 组件(172 个文件,按子目录组织)
  hooks/                      #   自定义 React Hooks(41 个)
  plugins/                    #   搜索插件系统
  contexts/                   #   React Contexts
  i18n/                       #   国际化(6 种语言)
src-tauri/                    # 后端(Rust + Tauri 2)
  src/
    commands/                 #   Tauri IPC 命令处理器(17 个模块)
    core/                     #   纯业务逻辑(扫描器、解析器等)
    data/
      sqlite/                 #   SQLite 数据访问层
      search/                 #   搜索引擎(FTS5 + Tantivy)
    server/
      http/                   #   HTTP/Axum 服务
      ws.rs                   #   独立 WebSocket 服务(旧版)
    dispatch.rs               #   共享命令路由
  tests/                      #   集成测试
src-tauri-cli/                # CLI 二进制(独立 Rust 程序)
website/                      # 文档站点(Next.js + Fumadocs)

开发工作流

代码风格

TypeScript/React:

  • 函数组件 + Hooks
  • TypeScript 严格模式(strict: true,禁止 any
  • 导入顺序:React → 第三方 → 内部组件 → Hooks → 工具 → 类型
  • 使用 @/* 路径别名(如 @/components/App

Rust:

  • cargo fmt 格式化(CI 强制执行)
  • cargo clippy -D warnings 检查(CI 强制执行)
  • 公共函数返回 Result<T, String>
  • 使用 /// 注释公共函数
  • 命令放在 commands/,业务逻辑放在 core/data/

添加新命令

添加后端命令时,需要更新以下位置:

  1. dispatch.rs — 在命令路由中添加 match 分支
  2. commands/mod.rs — 导出新的命令模块
  3. lib.rs — 如需要则为外部消费者重新导出
  4. WebSocket 和 HTTP 自动继承 dispatch() 的路由

示例:

// 在 dispatch() 中
"my_command" => {
    let result = my_module::do_something(&state, &payload).await?;
    Ok(serde_json::to_value(result).unwrap())
}

添加前端组件

// 每个文件一个组件,使用 PascalCase 命名
function MyComponent({ prop1, prop2 }: MyComponentProps) {
  const { t } = useTranslation()
  const [state, setState] = useState<string>('')

  return <div>{t('my.key')}</div>
}

export default MyComponent

测试

Rust 测试

cd src-tauri && cargo test
cd src-tauri && cargo test test_name -- --nocapture  # 特定测试 + 输出
cd src-tauri && cargo test --test full_text_search_integration_test    # 集成测试
cd src-tauri && cargo test --test migration_test    # 迁移测试

代码质量检查

cd src-tauri && cargo fmt --check
cd src-tauri && cargo clippy -- -D warnings
npx tsc --noEmit  # TypeScript 类型检查

提交规范

使用 Conventional Commits

feat: add session export to markdown
fix: resolve search not returning results
docs: update API documentation
refactor: simplify scanner logic
test: add unit tests for export module
chore: update dependencies

提交变更

创建分支

git checkout -b feature/my-feature

修改并测试

cd src-tauri && cargo fmt && cargo clippy -- -D warnings
cd src-tauri && cargo test

提交并推送

git commit -m "feat: add my feature"
git push origin feature/my-feature

提交 Pull Request

main 分支提交 PR,并附上清晰的变更说明。

所有 PR 必须通过 CI 检查(rustfmt、clippy、构建)后才能合并。CI 流水线还会构建 CLI 二进制文件作为健全性检查。

报告问题

提交 Issue 时,请包含:

  1. 操作系统和版本(如 macOS 15.0、Windows 11)
  2. 应用版本(从设置或 package.json 获取)
  3. 复现步骤
  4. 期望行为与实际行为的对比
  5. 相关日志或错误信息

许可证

贡献即表示你同意你的贡献将根据 MIT License 授权。

目录