Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 34 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,46 @@ Wails v2 desktop app. Go backend embedded in a WebView2 (Chromium) renderer. Fra
- `Modal.svelte` — glassmorphism dialog (info/confirm modes)
- `SettingsPanel.svelte` — theme, startup toggles, saves via Go config API

## Model Strategy

- **Parent agent (this conversation):** `deepseek-v4-pro[1m]` — configured in `.claude/settings.json` as `"model"`
- **Sub-agents (Agent tool):** always use `model="sonnet"` in the Agent call, which maps to `deepseek-v4-flash[1m]`. Pro model reserved for thinking/planning; flash model for parallel exploration — high efficiency, low cost.

**Multi-agent patterns for this project:**

| Task | Agent type | Model | Example |
|------|-----------|-------|---------|
| Search Go code | Explore | sonnet (flash) | Find Win32 API patterns in `internal/service/` |
| Search Svelte/JS code | Explore | sonnet (flash) | Find component event handlers in `frontend/src/` |
| Cross-cutting search | 2× Explore (parallel) | sonnet (flash) | Search Go API + all JS callers simultaneously |
| Bug investigation | 2-3× Explore (parallel) | sonnet (flash) | Search Go backend + Svelte frontend + Wails bindings simultaneously |
| Pre-change audit | Explore (background) | sonnet (flash) | Before modifying Go API: find all frontend callers |
| Post-change verification | general-purpose (background) | sonnet (flash) | After edits: go vet, check bindings, verify callers |
| Debug hook/callback issues | general-purpose | sonnet (flash) | Investigate `hookProc` or Svelte event delegation conflicts |
| Plan architecture changes | Plan | default (pro) | Design a new data pipeline or UI feature |
| Build feature (full impl) | — | default (pro) | Complex cross-cutting changes (Go + Svelte + Wails bindings) |

**How to trigger multi-agent mode — say any of these:**

| You say | What happens |
|---------|-------------|
| `团队模式` or `team mode` | **Universal trigger.** All independent searches/checks run as parallel sub-agents. Use this before any non-trivial task. |
| `查一下 X 在哪些地方用了` | Spawns parallel Explore agents: Go side + Svelte side simultaneously. |
| `帮我修这个 bug` | Spawns 2-3 Explore agents in parallel to search Go, Svelte, and Wails bindings for root cause. |
| `改一下 Go 的 X 方法` | First spawns a background Explore agent to find all JS callers, then proceeds with the edit. |
| (nothing — implicit) | Post-change verification (`go vet`, binding checks) always runs as a background agent. |

**Key rule:** Pro model for decisions that require deep reasoning (architecture, debugging race conditions, build gotchas). Flash model for everything else — searches, file reads, formatting, simple edits. Send multiple flash agents in parallel to maximize throughput.

## Critical Patterns & Gotchas

**Plans always go to the project-level `.claude/plans/`, never global.** The global `~/.claude/plans/` is for user-wide plans. All plans for this project must be written to `key-stats\.claude\plans\`. After writing a plan, verify it's in the right directory.

**Event handling in frameless window:** The title bar `on:mousedown` calls `StartDrag()` (Win32 `SendMessage(WM_NCLBUTTONDOWN)`). This blocks until drag completes and **swallows all child click events**. Must guard with `if (!e.target.closest('button'))` to let buttons work.

**Do NOT use document-level event listeners:** Svelte 4 uses event delegation (single document-level listener for clicks). Adding `document.addEventListener('click', ...)` or using `EventsOn` from the Wails runtime causes conflicts with Svelte's event processing, making buttons unresponsive. Use Svelte's `on:click` handlers exclusively. For "click outside" patterns, use `on:click` on a parent element with target checking (see `handleMainClick` in App.svelte).

**Windows hook callback safety:** `hookProc` runs on a Windows callback thread. Never call `runtime.EventsEmit` or do blocking operations directly. Use non-blocking channel sends to `rtChan`; the `rtEmitter` goroutine handles emission.
**Windows hook callback safety:** `hookProc` runs on a Windows callback thread. Never call `runtime.EventsEmit` or do blocking operations directly. Use non-blocking channel sends to `rtChan`; the `rtEmitter` goroutine drains the channel to prevent backpressure. Frontend polls `GetLatestKeyPress()` at 100ms for real-time flash — polling avoids Svelte 4 event delegation conflicts entirely.

**SQLite:** Uses `modernc.org/sqlite` (pure Go, no CGO). WAL mode enabled. Data at `%APPDATA%\key-stats\data.db`.

Expand Down
Loading