# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview **EzVibeR+** is a desktop Live2D mascot application (desktop pet) built with Tauri v2. It displays interactive Live2D models on a transparent, always-on-top window with a system tray interface. ## Key Commands ```bash npm run dev # Start Vite frontend dev server (port 1420) npm run build # TypeScript check + Vite production build npm run tauri:dev # Full Tauri development (RUST_BACKTRACE=full) npm run tauri # Run Tauri CLI directly ``` ## Architecture ### Frontend (`src/`) | File | Purpose | |------|---------| | `live2d/index.vue` | Main mascot view: PixiJS + pixi-live2d-display, model loading, dragging, toolbars | | `components/Config.vue` | Settings panel for model selection, paths, and remote model management | | `hooks/useBackendEvents.ts` | Listens to Tauri events from Rust backend | | `hooks/useListenEvent.ts` | Generic event listener hook | | `hooks/useUpdate.ts` | Version update checker | | `plugins/index.ts` | Bridges Rust commands (via `modelserve`) to frontend | | `plugins/modelserve.ts` | Exposes `model_list` command to frontend | | `plugins/autostart.ts` | Autostart plugin binding | | `plugins/checkupdate.ts` | Update checker plugin binding | | `util/index.ts` | Config read/write, throttle utility | ### Dual Window Model - **live2d.html** — The mascot display window using PIXI.js + pixi-live2d-display - **index.html** — Configuration/settings window using Vue 3 + NaiveUI Both are built into the Vite rollup via `vite.config.ts` multi-entry setup. ### Rust Backend (`src-tauri/src/`) | Module | Purpose | |--------|---------| | `main.rs` | App entry, 60-second background loop, tray setup | | `app/commands.rs` | Tauri command handlers: read_file, write_file, model_list, read_config, write_config, get_emotion, get_scheduler_status, get_memory_count, search_memories, interact, chat, trigger_reminder | | `app/config.rs` | AppConf struct for persisting user settings | | `app/menu.rs` | Menu utilities | | `app/mstruct.rs` | Misc structs | | `modules/brain.rs` | LLM integration with RAG; currently `NoopLLMProvider` (no LLM configured) | | `modules/emotion.rs` | EmotionEngine tracks emotional state and transitions | | `modules/scheduler.rs` | TaskScheduler fires timed behaviors based on uptime | | `modules/memory.rs` | MemorySystem provides vector search over conversation history | | `plugins/autostart.rs` | Tauri plugin for auto-start on login | | `plugins/checkupdate.rs` | Tauri plugin for version checking | | `utils.rs` | Utility functions | ### Web Server (`src-tauri/web_server/`) Separate Cargo workspace member (axum-based) that serves local Live2D model files on a configurable port. ### Database `ezvibe_memory.db` — SQLite database for the MemorySystem (vector storage via rusqlite). Initialized with a `DummyEmbedder` (384-dim zero vectors), not a real embedding model. ### Communication Flow Frontend ↔ Tauri IPC → Rust commands (`commands.rs`) ↔ Subsystems (`emotion`, `scheduler`, `brain`, `memory`) ↔ `web_server` serves model files ### System Tray Tray icon with menu items: 显示桌宠, 隐藏桌宠, 配置中心, 关闭软件. Window management done via `get_webview_window("main")` and `get_webview_window("config")`. ### Backend Events (emitted to frontend) - `ezvibe:heartbeat` — 60s tick with emotion state, tick count, uptime - `ezvibe:reminder` — Fired scheduled behaviors with action details - `ezvibe:action` — General action events - `ezvibe:emotion` — Emotion state changes ### 60-Second Background Loop (main.rs:51) Coordinates all subsystems: 1. `scheduler.on_timer_tick()` fires scheduled behaviors 2. `brain.think()` generates responses via LLM (or Noop fallback) 3. Emits `ezvibe:heartbeat` event to frontend with emotion state