This file is the source of truth for AI agents working in this repository. Use it to keep changes consistent with the current architecture and UI patterns.
Stroke is a Tauri desktop app for database work:
- connect to PostgreSQL, SQLite, Cloudflare D1, and MySQL flows in UI
- browse schemas/tables and row counts
- view/edit table data with filters/sort/pagination
- run SQL in Monaco editor with history/saved queries
- use AI features (chat, SQL suggestions, visual outputs)
- run a built-in MCP server for external AI tools
- Shell/runtime: Tauri 2 (
src-tauri) - Frontend: Svelte 5 + Vite
- Styling: Tailwind CSS v4
- UI primitives: bits-ui + shadcn-svelte style wrappers in
src/lib/components/ui/* - Icons:
@lucide/svelte - Editor:
monaco-editor - Hotkeys:
@tanstack/svelte-hotkeys - Toasts:
svelte-sonner - Backend DB layer: Rust + SQLx (and engine-specific integrations under
src-tauri/src/db)
- App root:
src/App.svelte->src/lib/components/StudioShell.svelte - Main orchestration happens in
StudioShell.svelte:- connection lifecycle
- tab routing/state (
table,sql,ai,schema,orm,security,logs) - hotkeys
- data fetch/update flows
- Frontend API boundary:
src/lib/api.js(Tauri invoke wrappers) - Backend command boundary:
- Rust logic in
src-tauri/src/db/* - exposed via
src-tauri/src/commands.rsandsrc-tauri/src/lib.rs
- Rust logic in
Use Svelte 5 runes and existing style:
- state:
$state(...) - derived values:
$derived(...)/$derived.by(...) - effects:
$effect(...) - props:
$props()/$bindable(...)
Keep code style consistent with the repo:
- prefer small focused helpers over big inline blocks
- JSDoc typedefs in Svelte files are common and encouraged
- avoid over-abstracting unless repetition is meaningful
DESIGN_SYSTEM.md (repo root) is the source of truth for all UI. It defines the
type scale, color tokens, spacing, radius, control heights, icon sizing, and the
shared component patterns. Follow it exactly; when a component disagrees, fix the
component. Key hard rules:
- Font size:
text-ui-*scale only (text-ui-3xl/2xl/xl/lg/ui/-sm/-xs/-2xs/-3xs). Nevertext-[Npx]or Tailwindtext-sm/xs/base— those bypass the 14px base. - Control heights are fixed:
h-7compact ·h-8default ·h-9field. - Icons:
size-3.5default;size-4in list rows/headers. Alwaysshrink-0in flex. - Always prefer components from
src/lib/components/ui/*instead of ad hoc primitives. - Use semantic utility classes (
bg-background,text-muted-foreground,border-border, etc.). - Prefer Tailwind utilities and
cn()fromsrc/lib/utils.js. - Use
size-*for square icon sizing. - Use
gap-*with flex/grid; keep spacing visually consistent with nearby components. - Use
@lucide/svelteicons only (no custom SVG systems unless required).
For Command UI (src/lib/components/ui/command/*):
- Items are full-width flex rows (
w-full,min-w-0) with internal horizontal padding. - Label content uses
data-slot="command-label"so text truncation and flex behavior are consistent. - Right-side metadata uses
data-slot="command-trailing"orCommand.Shortcutwithml-auto. - Do not reintroduce hidden absolute indicators that reserve right-side space.
- Keep one active dialog at a time when opening command palette from global hotkey flow.
- Persisted user settings/states live in
src/lib/stores/*:settings.js,connections.js,layout.js,query-history.js, etc.
- Store local persistence in
localStoragewith defensivetry/catch. - Keep async transitions explicit:
- loading booleans (
loadingRows,savingCell,insertingRow, etc.) - clear error strings for user-facing failures
- loading booleans (
- Prefer optimistic-feeling UI only when failure handling is clear and reversible.
- Keep command handlers thin; place real logic in
src-tauri/src/db/*. - Use parameterized queries for values.
- Quote/validate SQL identifiers correctly when needed.
- Return clear error messages that UI can display directly.
- Avoid holding mutex/locks across
.await.
When adding or changing a data-backed feature:
- Add/extend Rust DB logic in
src-tauri/src/db/*. - Expose command in
commands.rsand register inlib.rs. - Add frontend wrapper in
src/lib/api.js. - Wire UI from
StudioShell.svelteand focused components. - Update stores/types/helpers as needed.
- Verify keyboard shortcuts and command palette integration when relevant.
- Run build/lint checks before finishing.
- Install:
npm install - Frontend only:
npm run dev - Full desktop app:
npm run tauri - Build frontend:
npm run build - Build desktop app:
npm run tauri:build
Note: npm run dev does not provide full Tauri backend behavior.
Do:
- make focused, surgical diffs
- preserve existing UX behavior unless task explicitly changes it
- keep accessibility in mind (labels, keyboard behavior, focus flow)
Do not:
- add large custom CSS blocks when utilities/components already solve it
- bypass established wrappers in
ui/*without strong reason - introduce unrelated refactors in task-focused changes
- commit or rewrite git history unless explicitly requested
src/lib/components/StudioShell.svelte- main app controllersrc/lib/components/CommandPalette.svelte- global command dialogsrc/lib/components/SqlConsole.svelte- SQL execution/resultssrc/lib/components/OrmRunner.svelte- ORM query runnersrc/lib/components/SchemaPage.svelte- schema explorer pagessrc/lib/components/Sidebar.svelte- tables/schemas navigationsrc/lib/api.js- frontend -> Tauri command bridgesrc/lib/stores/*- persisted local app statesrc-tauri/src/db/*- backend DB logic