Use when adding, renaming, or changing the signature of a Tauri command in src-tauri — any new IPC surface between the Rust core and the React UI.
Instalação
Instalar com Codex ou Claude Copie este prompt, cole no Codex, Claude ou outro assistente e deixe que ele revise a página da skill e instale para você.
Use when adding, renaming, or changing the signature of a Tauri command in src-tauri — any new IPC surface between the Rust core and the React UI.
Add a Tauri command
End-to-end checklist. A command is not "done" until both sides are typed and tested.
Checklist (todo per item)
Domain module. Add the command to src-tauri/src/commands/<domain>.rs (create the domain file if new — never a catch-all module). Name: snake_case verb phrase, one command per user-facing action.
Signature.async fn if it does I/O; owned params; State<'_, AppState> for state; Channel<T> param if it streams. Returns Result<T, Error> (the app error enum — add a variant if no existing one fits; wrap engine errors via #[from]).
Thin shell. Body = unwrap args → call engine / db/ repository / jobs layer → map errors. If you're writing SQL or business logic inside the command, stop and move it down a layer.
Register. Add to the single generate_handler![...] list in lib.rs (and to tauri_specta::Builder command list). There is exactly one registration site.
Regenerate bindings. Run the specta export (see justfile: just bindings) so src/lib/ipc/bindings.gen.ts updates. Never hand-edit that file.
Typed wrapper. Expose it from src/lib/ipc/<domain>.ts re-exporting the generated function with any ergonomics (query-key helpers for TanStack Query). Feature code imports the wrapper, never the bindings file or raw invoke.
Tests, both sides. Rust: unit test for the layer the command delegates to (the command itself stays thin enough not to need one); if the command has branching, test it with a test AppState. TS: if a hook/component consumes it, mock via mockIPC in the colocated test.
Capabilities. If the command needs a plugin permission, add it to the relevant file in src-tauri/capabilities/ (per-concern files, minimum scope).
Gate.just check.
Common mistakes
Registering in a second invoke_handler call — Tauri silently keeps only the last one.
Returning String errors — the frontend loses the kind discriminant.
Streaming via events instead of Channel<T> — events are broadcast and unordered per docs; channels are the streaming path.
Forgetting clearMocks() in the TS test — IPC mocks leak across tests.