Files
tusk/CLAUDE.md
2026-02-12 12:18:20 +03:00

3.1 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

Tusk is a PostgreSQL database management GUI built with Tauri 2 (Rust backend) and React (TypeScript frontend).

Development Commands

npm run tauri dev     # Start full app in dev mode (Vite HMR + Rust backend)
npm run dev           # Start only the Vite frontend dev server (port 5173)
npm run build         # Build frontend (tsc + vite build)
npm run tauri build   # Build production desktop executable
npm run lint          # ESLint

Rust backend builds automatically via Tauri when running npm run tauri dev/build. To check Rust compilation independently:

cd src-tauri && cargo check

Architecture

Frontend (React/TS) ──IPC invoke()──> Backend (Rust/Tauri) ──sqlx──> PostgreSQL

IPC Communication Pattern

All frontend-backend communication goes through Tauri's typed IPC. The full pipeline for adding a new backend-exposed feature:

  1. Rust command#[tauri::command] async fn in src-tauri/src/commands/<domain>.rs
  2. Register — add to invoke_handler in src-tauri/src/lib.rs
  3. TS wrapper — typed invoke() call in src/lib/tauri.ts
  4. React hook — TanStack React Query hook in src/hooks/use-<domain>.ts
  5. Types — shared interfaces in src/types/index.ts

Backend (src-tauri/src/)

  • state.rsAppState: holds RwLock<HashMap<connection_id, PgPool>>, read-only flags, config path. Connections default to read-only.
  • error.rsTuskError enum with thiserror, serialized as string for IPC. TuskResult<T> type alias.
  • utils.rsescape_ident() for safe SQL identifier quoting.
  • commands/ — one module per domain (connections, queries, schema, data, export, management, history, saved_queries). Each function takes State<'_, AppState> and returns TuskResult<T>.
  • models/ — serde-serializable structs matching TypeScript types.

SQL safety: identifiers use escape_ident(), data queries use sqlx parameterized queries. Read-only mode wraps queries in SET TRANSACTION READ ONLY + ROLLBACK.

Frontend (src/)

  • State: Zustand store (stores/app-store.ts) — connections, active connection/database, tabs, read-only flags, pg version.
  • Data fetching: TanStack React Query hooks in hooks/ — one hook per domain, wrapping src/lib/tauri.ts functions.
  • UI: shadcn/ui + Radix primitives, Tailwind CSS 4, dark mode via next-themes. SQL editor uses CodeMirror.
  • Layout: resizable panels (sidebar + main area with tab bar).

Stored Data

Connections are persisted to ~/.config/tusk/connections.json. History and saved queries are stored in similar JSON files in the same config directory.

Conventions

  • Frontend files: Components PascalCase.tsx, hooks use-kebab-case.ts, one feature per directory under components/
  • Path alias: @ maps to ./src
  • Rust errors: always use TuskError variants, never unwrap() in commands
  • New PG types: add conversion case in pg_value_to_json() in commands/queries.rs