4.2 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
Sprout Launcher (萌芽桌面启动器) is a Windows desktop application launcher built with Tauri 2 + React 18 + TypeScript. Users add apps to a categorized grid, launch them from a single window, and manage shortcuts/icons.
Commands
npm install # Install JS dependencies
npm run tauri dev # Start Vite dev server + Tauri (hot reload)
npm run lint # ESLint — must pass with zero warnings
npm run tauri build # tsc && vite build && Tauri bundler → src-tauri/target/release/bundle/
No automated test framework is configured. Manual smoke testing: add/edit/delete apps, category CRUD, config persistence across restart, icon extraction, window controls.
Architecture
The app uses Tauri 2's two-process model:
Renderer (React UI in src/)
↕ invoke() / listen() via @tauri-apps/api
Rust backend (src-tauri/src/lib.rs)
↕ Native APIs
Windows OS (filesystem, registry, shell, PowerShell)
Key source files:
| File | Role |
|---|---|
src/App.tsx |
Master state container — config, drag-drop, dialog orchestration |
src/types.ts |
Shared TypeScript interfaces (App, Config, Category) |
src/components/AppCard.tsx |
Memoized app tile |
src/components/AddAppDialog.tsx |
Add/edit app modal — calls invoke() for file pickers |
src/components/GridWithFill.tsx |
Responsive grid using ResizeObserver |
src-tauri/src/lib.rs |
All Tauri commands + tray + protocol + setup |
src-tauri/tauri.conf.json |
Window config, bundle targets, CSP |
src-tauri/capabilities/default.json |
Plugin permission grants |
IPC Communication
The frontend calls Rust via invoke(command_name, args) from @tauri-apps/api/core. Events from Rust to frontend use listen() from @tauri-apps/api/event.
Key commands in src-tauri/src/lib.rs:
| Command | Purpose |
|---|---|
launch_app |
Execute app via cmd /C start |
select_target / select_folder / select_single_executable |
Native file/folder dialogs |
select_executables |
Multi-select executables |
create_shortcut |
Create Windows .lnk via PowerShell COM |
ensure_icon |
Extract icon from EXE/folder via PowerShell + .NET, cache as PNG |
delete_app_artifacts |
Clean up shortcut + cached icon |
show_app_context_menu |
Show native right-click menu; emits app-context-action event |
load_config / save_config |
Read/write %APPDATA%/com.smyhub.sprout-launcher/launcher-config.json |
export_config / import_config |
File dialog + JSON backup/restore |
get_auto_launch / set_auto_launch |
Windows boot startup via tauri-plugin-autostart |
minimize_window / maximize_window / close_window |
Window controls (close → hide to tray) |
refresh_icons |
Re-extract all icons to disk; returns sprout-icon:// URLs |
Data & File Locations
- Config:
%APPDATA%/com.smyhub.sprout-launcher/launcher-config.json - Cached icons:
%APPDATA%/com.smyhub.sprout-launcher/data/icons/(PNG files) - Shortcuts:
%APPDATA%/com.smyhub.sprout-launcher/data/shortcuts/(.lnkfiles) - Icons are served via a custom
sprout-icon://URI scheme registered inlib.rs
If you change the config schema, add a migration path in src/App.tsx inside migrateAndMaybeSaveConfig() (existing exePath → targetPath migration is the pattern to follow).
Tauri Plugins Used
| Plugin | Purpose |
|---|---|
tauri-plugin-dialog |
File open/save dialogs (Rust side) |
tauri-plugin-autostart |
Windows login-item / startup registry |
tauri-plugin-single-instance |
Prevent duplicate instances; focus existing window |
tauri-plugin-log |
Structured logging |
Coding Conventions
- TypeScript strict mode; all changes must be type-safe
- ESM (
"type": "module") throughout - 2-space indentation
- React components:
PascalCase.tsxinsrc/components/; shared types insrc/types.ts - Rust: standard
snake_case, all commands registered ininvoke_handler!at bottom oflib.rs - Commits: Conventional Commits (
feat:,fix:,chore:, etc.) dist/,src-tauri/target/are build artifacts — do not edit