This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Silo is an AI-powered desktop application for computer use — it lets AI models take screenshots, move the mouse, click, type, and scroll on the user's actual desktop. Built with SvelteKit 5 (frontend) + Tauri v2 (Rust backend), routed through OpenRouter or LM Studio.
bun install # Install dependencies
bun run dev # Start Vite dev server (port 1420) + Tauri dev mode
bun run build # Build frontend for production
bun run tauri build # Build the desktop app binary
bun run check # TypeScript type checking (svelte-check)
bun run check:watch # Type checking in watch modeNo test framework is currently configured.
- Frontend: SvelteKit 5 SPA (static adapter, no SSR) in
src/ - Backend: Tauri v2 Rust commands in
src-tauri/src/ - IPC bindings: Auto-generated via
tauri-spectaintosrc/lib/bindings.tson debug builds. All Rust commands must be registered increate_builder()insrc-tauri/src/lib.rsviacollect_commands![].
The core AI integration is a custom ChatTransport implementation:
src/lib/transports/computer-transport.ts—ComputerTransportclass implements the Vercel AI SDKChatTransportinterface. Manages model selection, middleware wrapping, image management in conversation history (keeps last 5 screenshots), and token usage tracking.src/lib/tools/index.ts— Defines thecomputertool with actions (screenshot, click, type, key, scroll, drag, wait, cursor_position). All coordinates are scaled between "computer use dimensions" (optimized for AI training, e.g. 1280x800) and real monitor dimensions.src/lib/middleware/uiTars.ts— Custom middleware for UI-TARS protocol format.
Models connect via two providers:
- OpenRouter (most models) — requires API key in settings
- LM Studio (local models) — connects to local server
Models that lack native tool calling use middleware wrappers (gemma, hermes, morphXml, uiTars) from @ai-sdk-tool/parser to convert tool schemas into prompt-formatted instructions.
- Persistent settings:
src/lib/runes/settings.svelte.ts— uses@tauri-store/svelteRuneStorewith debounced auto-save (stores API keys, default model, auto-screenshot toggle) - UI state: Svelte 5 runes (
$state,$derived,$effect) — no legacy stores
screenshot.rs— Screen capture viaxcap, resized to target dimensions viafast_image_resize, returned as base64 JPEGinput.rs— Mouse/keyboard control viaenigo(move, click, type, key press, drag, scroll)- All commands use
spectafor TypeScript type generation
- Base UI: shadcn-svelte components in
src/lib/components/ui/ - AI-specific:
src/lib/components/ai-elements/— prompt-input, conversation, message, context (token usage), reasoning, response, tool, artifact, loader - Styling: Tailwind CSS v4
src/lib/utils/scaling.ts handles bidirectional coordinate mapping between the AI model's "computer use" resolution and the actual monitor resolution. The ScalingSource enum indicates whether coordinates originate from the API or the real computer.
- Svelte 5 syntax: Use runes (
$state,$derived,$effect,$props,$bindable),onclick(noton:click), snippets with{@render}(not<slot>), callback props (notcreateEventDispatcher) - Tauri v2 patterns: Owned types in async commands (no
&str), all commands registered ingenerate_handler![], capabilities required for plugin features - Commits: Angular conventional commits (
feat,fix,docs, etc.) — semantic-release auto-bumps versions inpackage.json,tauri.conf.json, andCargo.toml - Package manager: Bun (not npm/yarn)
- Formatting: Prettier with svelte and tailwindcss plugins