A lightweight AI chat app that runs entirely in your browser. No server. No installation. No data leaves your device.
- Multi-provider AI — Claude (Anthropic), Gemini (Google), Qwen, and DeepSeek via proxy + official APIs (laozhang.ai, bianxie.ai, lingyaai.cn, qnaigc.com, api.deepseek.com)
- Agent with tools — JS sandbox (
run_js) and persistent memory - Streaming responses — real-time token streaming with thinking block support
- Markdown rendering — full Markdown with syntax-highlighted code blocks (lazy-loaded hljs)
- Personas — built-in conversational roles (thinking partner, prompt explorer, etc.)
- Image generation — via Gemini image model (optional, per-conversation toggle)
- Local-only storage — conversations/messages/memories in IndexedDB, settings/soul in localStorage
- Dark / light / system theme
- Auto-titling — AI-generated conversation titles after a few rounds
git clone <repo>
cd thinclaw
bun install
just devOpen http://localhost:5173.
just buildOutput is in build/ — a directory of plain static files. See docs/deployment.md for hosting guides (nginx, Caddy, Cloudflare Pages, Docker).
All configuration is done in the Settings page (gear icon in the sidebar).
| Setting | Description |
|---|---|
| Provider API Keys | One key per provider (laozhang.ai, bianxie.ai, lingyaai.cn, qnaigc.com, api.deepseek.com). A single key unlocks multiple models. |
| Model Selection | Choose default and utility (auto-title) models from enabled providers. |
| Model Toggles | Enable/disable individual models per provider. |
| Theme | Light, dark, or follow system preference. |
| Custom Instructions | Extra text appended to the system prompt for all conversations. |
| Soul | The AI's persistent identity — editable by you or the AI itself. |
| Memory | Persistent facts about you, saved by the AI across conversations. |
- API keys, soul, and UI settings are stored in
localStoragein your browser only. - Conversations, messages, and memories are stored in
IndexedDBin your browser only. - No analytics, no telemetry, no external requests except to the configured AI provider APIs.
- Clearing your browser's site data for this origin deletes everything.
| Layer | Choice |
|---|---|
| Framework | SvelteKit 2 + Svelte 5 (runes) |
| Language | TypeScript (strict) |
| AI | @mariozechner/pi-ai + @mariozechner/pi-agent-core |
| Storage | idb (IndexedDB) + localStorage |
| Styling | Tailwind CSS v4 + CSS custom properties |
| Build | Vite 8 + Bun + just |
| Deploy | @sveltejs/adapter-static (pure SPA, ssr=false) |
Preferred:
just dev # start dev server (http://localhost:5173)
just build # production build → build/
just preview # preview production build locally
just check # TypeScript + Svelte type check
just format # Prettier formatDirect Bun equivalents:
bun run dev
bun run build
bun run preview
bun run check
bun run formatsrc/
├── app.css # Design tokens (CSS custom properties), light/dark theme
├── lib/
│ ├── agent/
│ │ ├── bailian-cache.ts # DashScope cache marker + thinking patches
│ │ ├── deepseek-payload.ts # DeepSeek payload patches
│ │ ├── image.ts # Image generation/editing tools
│ │ ├── models.ts # MODELS array + getModelByKey + DEFAULT_*_MODEL_KEY
│ │ ├── personas.ts # BUILTIN_PERSONAS + getPersonaById
│ │ ├── prompts.ts # buildSystemPrompt()
│ │ ├── soul.ts # AI identity stored in localStorage
│ │ ├── title.ts # AI auto-title generation
│ │ └── tools.ts # Agent tools: run_js, memory_save, memory_delete
│ ├── components/
│ │ ├── ChatInput.svelte # Textarea + image attach + send controls
│ │ ├── ChatMessage.svelte # Message bubble: Markdown, tool calls/results, thinking
│ │ ├── ModelSwitcher.svelte # Inline model picker
│ │ ├── PersonaPicker.svelte # Persona selector before first message
│ │ ├── SettingsMemory.svelte # Memory list section
│ │ ├── SettingsSoul.svelte # Soul editor section
│ │ ├── Sidebar.svelte # Conversation list: new / select / rename / delete
│ │ ├── Toast.svelte # Toast notifications
│ │ └── ToolCard.svelte # Tool call/result rendering
│ ├── db/
│ │ └── index.ts # IndexedDB schema + persistence helpers
│ ├── stores/
│ │ ├── chat.ts # Conversation state, Agent lifecycle, streaming
│ │ ├── memory.ts # Reactive memory store
│ │ ├── settings.ts # API keys, models, theme, instructions
│ │ └── toast.ts # Toast store
│ ├── themes.ts # Theme definitions
│ └── utils/
│ ├── markdown.ts # marked + highlight.js (hljs lazy-loaded)
│ └── nanoid.ts # crypto.getRandomValues ID generator
└── routes/
├── +layout.ts # ssr=false, prerender=true — pure SPA
├── +layout.svelte # imports app.css
├── +page.svelte # Main chat UI: sidebar + chat thread
└── settings/
└── +page.svelte # Settings page: providers, models, appearance, soul, memory
- Deployment Guide — nginx, Caddy, Cloudflare Pages, Docker
- Provider Details — proxy APIs, endpoints, per-provider notes
- Caching — prompt caching strategy, thinking blocks, provider notes
- Message Types — all message types, lifecycle, persistence
- Anthropic Prompt Caching Reference — upstream Anthropic docs, kept for offline reference
MIT