ai-coding-agents
Comprehensive guide for using Codex CLI (OpenAI) and Claude Code CLI (Anthropic) - AI-powered…
Expert guidance for building cross-platform desktop applications with Tauri 2.0 and Rust. Use when developing Tauri apps including commands and IPC, file system operations, window management, state management, system tray, menus, plugin development, security configuration
$ npx -y skills add xiaolai/vmark --skill tauri-app-dev --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/tauri-app-devContext preview
The summary Claude sees to decide when to auto-load this skill.
Expert guidance for building cross-platform desktop applications with Tauri 2.0 and Rust. Use when developing Tauri apps including commands and IPC, file system operations, window management, state management, system tray, menus, plugin development, security configuration
name: tauri-app-dev description: Expert guidance for building cross-platform desktop applications with Tauri 2.0 and Rust. Use when developing Tauri apps including commands and IPC, file system operations, window management, state management, system tray, menus, plugin development, security configuration (capabilities/permissions), bundling/distribution, and auto-updates. Covers patterns for editor applications requiring file dialogs, native menus, and frontend-backend communication.
Tauri is a framework for building small, fast, secure desktop apps using web frontends and Rust backends.
┌─────────────────────────────────────────┐
│ Frontend (Webview) │
│ HTML/CSS/JS • React/Vue/Svelte │
└────────────────┬────────────────────────┘
│ IPC (invoke/events)
┌────────────────▼────────────────────────┐
│ Tauri Core (Rust) │
│ Commands • State • Plugins • Events │
└────────────────┬────────────────────────┘
│ TAO (windows) + WRY (webview)
┌────────────────▼────────────────────────┐
│ Operating System │
│ macOS • Windows • Linux • Mobile │
└─────────────────────────────────────────┘my-app/ ├── src/ # Frontend source ├── src-tauri/ │ ├── Cargo.toml # Rust dependencies │ ├── tauri.conf.json # Tauri configuration │ ├── capabilities/ # Security permissions (v2) │ │ └── default.json │ ├── src/ │ │ ├── main.rs # Desktop entry point │ │ └── lib.rs # Main app logic + mobile entry │ └── icons/ └── package.json
Define commands in Rust with `#[tauri::command]`:
// src-tauri/src/lib.rs
#[tauri::command]
fn greet(name: String) -> String {
format!("Hello, {}!", name)
}
#[tauri::command]
async fn read_file(path: String) -> Result<String, String> {
std::fs::read_to_string(&path).map_err(|e| e.to_string())
}
pub fn run() {
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![greet, read_file])
.run(tauri::generate_context!())
.expect("error running app");
}Call from frontend (direct):
import { invoke } from '@tauri-apps/api/core';
const greeting = await invoke<string>('greet', { name: 'World' });
const content = await invoke<string>('read_file', { path: '/tmp/test.txt' });**Project convention:** Wrap `invoke()` with TanStack Query for caching and state management:
import { useQuery, useMutation } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api/core';
// Query (read operations)
const { data: content } = useQuery({
queryKey: ['file', path],
queryFn: () => invoke<string>('read_file', { path }),
});
// Mutation (write operations)
const { mutate: saveFile } = useMutation({
mutationFn: (content: string) => invoke('write_file', { path, content }),
});**Key rules:**
Share state across commands:
use std::sync::Mutex;
use tauri::State;
struct AppState {
counter: Mutex<i32>,
db: Mutex<Option<Database>>,
}
#[tauri::command]
fn increment(state: State<'_, AppState>) -> i32 {
let mut counter = state.counter.lock().unwrap();
*counter += 1;
*counter
}
pub fn run() {
tauri::Builder::default()
.manage(AppState {
counter: Mutex::new(0),
db: Mutex::new(None),
})
.invoke_handler(tauri::generate_handler![increment])
.run(tauri::generate_context!())
.expect("error running app");
}**Access via AppHandle** (for background threads):
use tauri::Manager;
#[tauri::command]
async fn background_task(app: tauri::AppHandle) {
let state = app.state::<AppState>();
// use state...
}Emit events from Rust:
use tauri::Emitter;
#[tauri::command]
fn start_process(app: tauri::AppHandle) {
std::thread::spawn(move || {
for i in 0..100 {
app.emit("progress", i).unwrap();
std::thread::sleep(std::time::Duration::from_millis(50));
}
app.emit("complete", "Done!").unwrap();
});
}Listen in frontend:
import { listen } from '@tauri-apps/api/event';
const unlisten = await listen<number>('progress', (event) => {
console.log(`Progress: ${event.payload}%`);
});
// Clean up when done
unlisten();Install plugins: `cargo add <plugin>` in src-tauri, `pnpm add <package>` in frontend.
| Plugin | Cargo Crate | NPM Package | Purpose | |--------|-------------|-------------|---------| | File System | `tauri-plugin-fs` | `@tauri-apps/plugin-fs` | Read/write files | | Dialog | `tauri-plugin-dialog` | `@tauri-apps/plugin-dialog` | Open/save dialogs | | Clipboard | `tauri-plugin-clipboard-manager` | `@tauri-apps/plugin-clipboard-manager` | Copy/paste | | Shell | `tauri-plugin-shell` | `@tauri-apps/plugin-shell` | Run external commands | | Store | `tauri-plugin-store` | `@tauri-apps/plugin-store` | Key-value persistence | | Updater | `tauri-plugin-updater` | `@tauri-apps/plugin-updater` | Auto-updates |
Register in Rust:
pub fn run() {
tauri::Builder::default()
.plugin(tauri_plugin_fs::init())
.plugin(tauri_plugin_dialog::init())
.plugin(tauri_plugin_clipboard_manager::init())
.run(tauri::generate_context!())
.expect("error running app");
}Tauri 2.0 uses capabilities (in `src-tauri/capabilities/`) to control what APIs each window can access.
**src-tauri/capabilities/default.json:**
The Plain-Text Workspace Where Humans and AI Collaborate Free. Local-first. Format-aware. VMark is the plain-text workspace where humans and AI collaborate.
Repo: xiaolai/vmark
Comprehensive guide for using Codex CLI (OpenAI) and Claude Code CLI (Anthropic) - AI-powered…
Test-driven CSS design system modifications. Run checks before/after CSS changes to verify…
Build or update MCP server/client integrations for VMark. Use when configuring MCP servers,…
Discover, register, and verify MCP servers. Use when a user asks to…
Audit an implementation against a plan (dev-docs/plans/*). Use when a user asks to check for…
Verify a completed implementation against a plan by running gates and checking acceptance…