# IPC Handlers Module

Central communication bridge between main and renderer processes. 9 specialized handler files, 53 IPC channels total.

## File Structure

| File | Responsibility |
|------|---------------|
| `ipc-handlers.ts` | Main coordinator, delegates to specialized handlers |
| `paste-handler.ts` | Text/image paste with security validation |
| `history-draft-handler.ts` | History CRUD, draft management, @path caching |
| `window-handler.ts` | Window visibility and focus control |
| `system-handler.ts` | App info, config, settings retrieval, `run=` shortcut command execution |
| `custom-search-handler.ts` | Slash commands, agent selection, plugin hot reload, source file hot reload, shell command execution |
| `file-handler.ts` | File operations, external URL handling |
| `usage-history-handler.ts` | Usage tracking for files, symbols, agents |
| `code-search-handler.ts` | Symbol search with ripgrep integration |

## Non-obvious Patterns

### code-search-handler registers independently
- Does **NOT** go through the IPCHandlers coordinator
- Registered directly from `main.ts` via `codeSearchHandler.register()`
- Uses `initialized` flag to prevent double registration
- Implements stale-while-revalidate caching with background deduplication

### Security boundaries
- Paste text: 1MB byte-based limit via `Buffer.byteLength()`
- Config access: whitelist `['shortcuts', 'history', 'draft', 'timing', 'app', 'platform']`
- External URLs: only `http:` and `https:` protocols
- Image paths: traversal prevention + restrictive permissions (0o700/0o600)
- History IDs: lowercase alphanumeric only
- Command execution: allowlist check against loaded custom search items (prevents renderer command injection)

### custom-search-handler listens for hot reload events
- Subscribes to `plugins-changed` event from PluginManager
- Subscribes to `source-changed` event from CustomSearchLoader (JSONL/individual file changes)
- Both events invalidate cache and notify renderer via `custom-search-updated` push channel
