skills/tauri/SKILL.md
Tauri-specific development patterns for NEXUS. Use when building desktop app features, handling IPC, or working with Rust backend.
npx skillsauth add ComputerConnection/zach-pack tauriInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Tauri patterns for NEXUS desktop app development.
~/nexus/
├── src/ # React frontend
├── src-tauri/
│ ├── src/
│ │ ├── main.rs # Entry point
│ │ ├── lib.rs # Command handlers
│ │ └── [modules]/ # Feature modules
│ ├── Cargo.toml # Rust dependencies
│ ├── tauri.conf.json # Tauri config
│ └── capabilities/ # Permissions
Rust side (src-tauri/src/lib.rs):
#[tauri::command]
fn my_command(arg: String) -> Result<String, String> {
// Do something
Ok(format!("Result: {}", arg))
}
// Register in builder:
.invoke_handler(tauri::generate_handler![my_command])
Frontend side:
import { invoke } from '@tauri-apps/api/core';
const result = await invoke<string>('my_command', { arg: 'value' });
#[tauri::command]
async fn async_command() -> Result<Data, String> {
// Async work
tokio::time::sleep(Duration::from_secs(1)).await;
Ok(Data::default())
}
struct AppState {
db: Mutex<Database>,
}
#[tauri::command]
fn with_state(state: State<AppState>) -> Result<(), String> {
let db = state.db.lock().unwrap();
// Use db
Ok(())
}
// In main:
.manage(AppState { db: Mutex::new(Database::new()) })
Emit from Rust:
#[tauri::command]
fn start_process(window: Window) {
window.emit("progress", Payload { percent: 50 }).unwrap();
}
Listen in React:
import { listen } from '@tauri-apps/api/event';
useEffect(() => {
const unlisten = listen('progress', (event) => {
console.log(event.payload);
});
return () => { unlisten.then(f => f()); };
}, []);
use std::fs;
use tauri::api::path::app_data_dir;
#[tauri::command]
fn read_config(app: AppHandle) -> Result<String, String> {
let path = app_data_dir(&app.config())
.ok_or("No app data dir")?
.join("config.json");
fs::read_to_string(path).map_err(|e| e.to_string())
}
#[tauri::command]
fn open_settings(app: AppHandle) {
tauri::WindowBuilder::new(
&app,
"settings",
tauri::WindowUrl::App("settings.html".into())
)
.title("Settings")
.build()
.unwrap();
}
NEXUS uses xterm.js. Backend PTY handling:
use portable_pty::{CommandBuilder, PtySize, native_pty_system};
#[tauri::command]
async fn spawn_terminal() -> Result<TerminalId, String> {
let pty_system = native_pty_system();
let pair = pty_system.openpty(PtySize {
rows: 24,
cols: 80,
..Default::default()
}).map_err(|e| e.to_string())?;
// Store and return ID
}
NEXUS uses WebSockets for agent communication:
// Consider using tauri-plugin-websocket or custom implementation
Persist graph state:
#[tauri::command]
fn save_graph(graph: GraphState, app: AppHandle) -> Result<(), String> {
let path = app_data_dir(&app.config())
.ok_or("No dir")?
.join("graphs")
.join(format!("{}.json", graph.id));
let json = serde_json::to_string_pretty(&graph)
.map_err(|e| e.to_string())?;
std::fs::write(path, json).map_err(|e| e.to_string())
}
# Dev mode (hot reload)
cd ~/nexus && npm run tauri:dev
# Build for production
npm run tauri:build
# Check Rust errors without full build
cd src-tauri && cargo check
# Add Rust dependency
cd src-tauri && cargo add [package]
# Update Tauri
cd src-tauri && cargo update
// Add to commands for debugging
println!("Debug: {:?}", value);
dbg!(&value);
// Or use tracing
tracing::info!("Something happened");
View logs:
# Logs appear in terminal where you ran tauri:dev
// Wrap invoke calls to debug
const safeInvoke = async (cmd: string, args?: object) => {
console.log(`Invoking ${cmd}`, args);
try {
const result = await invoke(cmd, args);
console.log(`Result:`, result);
return result;
} catch (e) {
console.error(`Error in ${cmd}:`, e);
throw e;
}
};
generate_handler![]?Serialize/Deserializecapabilities/ for required permissionsasync commands + tokio::spawnnotify crate, emit on changesBased on $ARGUMENTS:
data-ai
Inject Zach's full identity, business context, and working preferences. Use at session start to eliminate cold starts. Lightweight context load — not a full agent like Vision, just who Zach is and how to work with him.
tools
--- name: vision description: "Zach's personal AI — his Jarvis. NOT a store agent. This is the owner's private command center that sits above everything else. Handles anything Zach needs — business, personal, technical, strategic, creative. High-systems AI: precise, anticipatory, authoritative. Invoke for ANY task." context: fork allowed-tools: Read, Grep, Glob, Bash, Edit, Write, Task, TodoWrite argument-hint: [what-do-you-need] — freeform. Vision figures out the rest. --- # VISION — Zach's Ja
development
Document Computer Connection store processes in AI-queryable format. Use to capture SOPs for the store AI server POC.
development
Orchestrates the full product strategy pipeline: product audit → roadmap → sprint plan with PM decision gates. This skill reads ACTUAL source code, cross-references git history, and produces three deliverables — a brutally honest product audit, a thesis-driven roadmap, and a sprint plan with PM decision gates between every phase. Use this skill whenever someone mentions: "sprint plan", "product roadmap", "plan the sprints", "PM questions", "product strategy", "audit this app", "roadmap this feature", "plan development", "break this into sprints", "phase this work", "create a development plan", "quarter planning", "what should we build next", "evaluate this app", "feature audit", "product review", "development roadmap", or any request for deliberate, methodical planning of software work. Also trigger when users want to evaluate whether features earn their place, when they reference PM decision gates or go/no-go checkpoints, or when they want to understand what's worth keeping in a codebase before planning new work. Even if the user only asks for one stage (just an audit, just a sprint plan), use this skill — it will guide them through the appropriate subset.