Contributing
How to contribute to Pi Session Manager.
"The best way to predict the future is to implement it." — David Heinemeier Hansson
We welcome contributions to Pi Session Manager! Here's how to get started.
Prerequisites
- Node.js 20+ with pnpm
- Rust stable (via rustup)
- Tauri CLI (
cargo install tauri-cli)
Setup
Clone the repository
git clone https://github.com/Dwsy/pi-session-manager.git
cd pi-session-managerInstall dependencies
pnpm installStart development
pnpm run tauri:devThis launches both the Vite dev server (with HMR) and the Rust backend.
Project Structure
src/ # Frontend (React + TypeScript)
components/ # UI components (99+ files)
hooks/ # Custom React hooks (19)
plugins/ # Search plugin system
contexts/ # React contexts
i18n/ # Internationalization (en-US, zh-CN)
src-tauri/ # Backend (Rust + Tauri 2)
src/
commands/ # Tauri IPC command handlers
scanner.rs # Session file scanner
search.rs # Search functionality
export.rs # Export functionality
tests/ # Integration tests
src-tauri-cli/ # CLI binary (standalone Rust)Development Workflow
Code Style
TypeScript/React:
- Functional components with hooks
- TypeScript strict mode (
strict: true, noany) - Import order: React → third-party → internal components → hooks → utils → types
Rust:
cargo fmtfor formatting (enforced in CI)cargo clippy -D warningsfor linting (enforced in CI)- All public functions return
Result<T, String> - Document public functions with
///comments
Adding a New Command
When adding a new backend command, update these locations:
ws_adapter.rs— add amatcharm indispatch()main.rs— register ininvoke_handlerfor Tauri IPC- WebSocket and HTTP automatically inherit from
dispatch()
Example:
// In dispatch()
"my_command" => {
let result = my_module::do_something(&state, &payload).await?;
Ok(serde_json::to_value(result).unwrap())
}Adding Frontend Components
// One component per file, PascalCase naming
function MyComponent({ prop1, prop2 }: MyComponentProps) {
const { t } = useTranslation()
const [state, setState] = useState<string>('')
return <div>{t('my.key')}</div>
}
export default MyComponentTesting
Rust Tests
cd src-tauri && cargo test
cd src-tauri && cargo test test_name -- --nocapture # specific test with output
cd src-tauri && cargo test --test integration_test # integration testsCode Quality Checks
cd src-tauri && cargo fmt --check
cd src-tauri && cargo clippy -- -D warnings
npx tsc --noEmit # TypeScript type checkingCommit Convention
Use 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 dependenciesSubmitting Changes
Fork and branch
git checkout -b feature/my-featureMake changes and test
cd src-tauri && cargo fmt && cargo clippy -- -D warnings
cd src-tauri && cargo testCommit and push
git commit -m "feat: add my feature"
git push origin feature/my-featureOpen a Pull Request
Submit a PR against the main branch with a clear description of your changes.
All PRs must pass CI checks (rustfmt, clippy, build) before merging. The CI pipeline also builds the CLI binary as a sanity check.
Reporting Issues
When filing an issue, include:
- OS and version (e.g., macOS 15.0, Windows 11)
- App version (from Settings or
package.json) - Steps to reproduce
- Expected vs. actual behavior
- Relevant logs or error messages
License
By contributing, you agree that your contributions will be licensed under the MIT License.