add-ipc-command
Pattern for adding a new Tauri IPC command (request/response or push event) in the deep-cuts monorepo
Skill by robertolupi
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/robertolupi-add-ipc-command
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/add-ipc-command
What's inside
- Skill name
add-ipc-command- Description
- Pattern for adding a new Tauri IPC command (request/response or push event) in the deep-cuts monorepo
- License
- AGPL-3.0
- Instructions
- 209 lines in SKILL.md · view on GitHub
Files (1)
- SKILL.md
SKILL.md (first lines)
# Adding a New Tauri IPC Command
IPC is the only channel between the Svelte frontend and the Rust backend. There are two patterns: **request/response** (`invoke`) and **push events** (`emit`/`listen`). Most commands use request/response; push events are used for long-running background work (scan updates, analysis progress).
---
## Pattern A — Request/response (`invoke`)
### 1. Write the command handler
Commands live in `src-tauri/src/commands/` (one file per domain — `library.rs`, `playlists.rs`, `analysis.rs`, etc.). Add your handler to the appropriate file or create a new one and expose it via `commands/mod.rs`.
```rust
#[tauri::command]
pub fn my_command(
conn_state: tauri::State<'_, Mutex<Connection>>,
some_arg: String,
) -> Result<MyReturnType, String> {
let conn = conn_state.lock().map_err(|e| e.to_string())?;
// ... do work ...
Ok(result)
}
```
- Return `Result<T, String>` — the `Err` string surfaces as a rejected Promise in the frontend.
- Access the DB via `conn_state: tauri::State<'_, Mutex<Connection>>` (registered at startup as `app.manage(Mutex::new(conn))`).
- Access the app handle (for emitting events) via `app: tauri::AppHandle`.
- Keep handlers thin; push heavy logic into helper functions so they're testable.
### 2. Register the command
Find the `tauri::generate_handler![]` macro in `lib.rs` and add your command:
```rust
.invoke_handler(tauri::generate_handler![
// ... existing commands ...
my_command,
])
```
Forgetting this step compiles cleanly but the frontend call will throw at runtime.
### 3. Update `src/lib/ipc.ts`
**This step is required for every new command.** `$lib/ipc` is the single import point for all frontend IPC — it owns local-debug mocks and the command type boundary.
#### 3a. Add a mock response
The mock system has two files:
- **`src/lib/mock-data.ts`** — typed fixture data exported as constants (`MOCK_TRACKS`, `MOCK_PLAYLISTS`, etc.). Add new entity arrays or objects here when the command introduces a new return type.
- **`src/lib/ipc.ts`** — the `MOCK_RESPONSES` map wires command names to handlers that use data from `mock-data.ts`.
For a simple query command:
```typescript
// In src/lib/mock-data.ts — add fixture data if introducing a new type
export const MOCK_MY_THINGS: MyThing[] = [
{ id: 1, name: "Example Thing", value: 42 },
];
// In src/lib/ipc.ts — wire the command
import { MOCK_MY_THINGS } from "$lib/mock-data";
const MOCK_RESPONSES: Record<string, (args?: any) => unknown> = {
// ... existing entries ...
get_my_things: () => MOCK_MY_THINGS,
get_my_thing: ({ id }: { id: number }) => MOCK_MY_THINGS.find(t => t.id === id) ?? null,
save_my_thing: () => null, // side-effect only — still add entry to suppress warning
};
```
Rules:
- If the command returns data that affects visible UI, provide a realistic mock value so `?local_debug=1` dev mode works without Tauri. Reference the `ui-debug` skill for how to verify this.
- If the command is a side-effect only (e.g. `save_*`, `delete_*`), return `null` or `undefined` — still add the entry so the console warning for unhandled commands is suppressed.
- If the command result depends on args (e.g. `get_track`), pattern-match on `args` to return something plausible.
- Rich structured data (new entity types, lists of items) belongs in `mock-data.ts`; inline lambdas in `ipc.ts` are for simple derivations from that data.
#### 3b. Keep the import boundary clean
```typescript
// ✓ correct
import { invoke, listen } from "$lib/ipc";
// ✗ wrong — bypasses mocks and type map
import { invoke } from "@tauri-apps/api/core";
```
Never import `invoke` or `listen` directly from `@tauri-apps/api` in app code. Only `$lib/ipc.ts` itself imports from the Tauri package.
### 4. Call it from the frontend
```typescript
import { invoke } from "$lib/ipc";
const result = await invoke<MyReturnType>('my_command', { someArg: 'value' });
```
Argument names are converted from camelCase (TypeScript) to snake_case (Rust) automatically by Tauri. The return type generic is optional but recommended for type safety.
---
## Pattern B — Push events from a background thread
Use this when the Rust side needs to notify the frontend proactively (e.g. scan progress, analysis completion).
### Rust side — emit from a spawned thread
```rust
#[tauri::command]
fn start_long_task(app: tauri::AppHandle) -> Result<(), String> {
std::thread::spawn(move || {
for i in 0..100 {
// ... do work ...
app.emit("my-task-progress", serde_json::json!({ "percent": i })).ok();
}
app.emit("my-task-complete", ()).ok();
});
Ok(())From robertolupi/deep-cuts, AGPL-3.0.
More from robertolupi/deep-cuts
- 0.534score
how-to-experiment
robertolupi
Experimental protocol for Deep Cuts research, prototypes, model evaluations, threshold tuning, ablations, metric comparisons, and claims about accuracy or…
SkillCFreshness: C★ 7Claude Code +9 - 0.534score
write-blog-post
robertolupi
Draft, structure, and finalize a Deep Cuts blog-series post so it conforms to the post template, house voice, and cross-post link rules.
SkillCFreshness: C★ 7Claude Code +9 - 0.534score
ui-debug
robertolupi
Inspect, debug, and compare the Deep Cuts UI using an available browser tool.
SkillCFreshness: C★ 7Claude Code +9 - 0.531score
dev-guidelines
robertolupi
Guidelines to prevent development false starts, environment mismatches, and incorrect commands in the deep-cuts monorepo
SkillCFreshness: C★ 7Claude Code +9 - 0.531score
add-tauri-sidecar
robertolupi
How to bundle an external binary and its dylib dependencies with the Tauri app, patch rpaths, sign everything, and resolve the path at runtime
SkillCFreshness: C★ 7Claude Code +9 - 0.531score
ui-design
robertolupi
Guidelines for the Sonic Glitch design system, theme variables, and multi-theme readability (dark, light, high-contrast)
SkillCFreshness: C★ 7Claude Code +9 - 0.531score
git-commits
robertolupi
Rules for writing commit messages in the deep-cuts repository — subject line format, body content, scope naming, and what to omit
SkillCFreshness: C★ 7Claude Code +9 - 0.531score
release-build
robertolupi
End-to-end checklist for building a signed macOS release — bump manifest min_app_version, verify sidecars, build, and inspect the .app
SkillCFreshness: C★ 7Claude Code +9 - 0.528score
add-analysis-pass
robertolupi
Checklist and guide for adding a new analysis pass to the trait-based modular pipeline
SkillCFreshness: C★ 7Claude Code +9 - 0.528score
bump-dev-version
robertolupi
Bump the app version in Cargo.toml after a release to start the next dev cycle
SkillCFreshness: C★ 7Claude Code +9 - 0.528score
db-migration
robertolupi
Safe pattern for adding SQLite schema migrations in the deep-cuts Rust/rusqlite_migration stack
SkillCFreshness: C★ 7Claude Code +9 - 0.528score
query-db
robertolupi
How to locate and query the deep-cuts production SQLite database
SkillCFreshness: C★ 7Claude Code +9
Signals
- Stars
- 7
- Forks
- 1
- Open issues
- 0
- Last commit (this folder)
- Jun 7, 2026 (4 months ago)
- Last release
- Jun 8, 2026 (4 months ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- AGPL-3.0
- Repository
- github.com/robertolupi/deep-cuts
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from robertolupi
- 0.534score
write-blog-post
robertolupi
Draft, structure, and finalize a Deep Cuts blog-series post so it conforms to the post template, house voice, and cross-post link rules.
SkillCFreshness: C★ 7Claude Code +9 - 0.534score
ui-debug
robertolupi
Inspect, debug, and compare the Deep Cuts UI using an available browser tool.
SkillCFreshness: C★ 7Claude Code +9 - 0.534score
how-to-experiment
robertolupi
Experimental protocol for Deep Cuts research, prototypes, model evaluations, threshold tuning, ablations, metric comparisons, and claims about accuracy or…
SkillCFreshness: C★ 7Claude Code +9 - 0.531score
release-build
robertolupi
End-to-end checklist for building a signed macOS release — bump manifest min_app_version, verify sidecars, build, and inspect the .app
SkillCFreshness: C★ 7Claude Code +9 - 0.531score
dev-guidelines
robertolupi
Guidelines to prevent development false starts, environment mismatches, and incorrect commands in the deep-cuts monorepo
SkillCFreshness: C★ 7Claude Code +9 - 0.531score
git-commits
robertolupi
Rules for writing commit messages in the deep-cuts repository — subject line format, body content, scope naming, and what to omit
SkillCFreshness: C★ 7Claude Code +9
Cite this page
add-ipc-command skill. Agent Mart. https://agentmart.dev/skills/robertolupi-add-ipc-command (last updated 2026-10-24)