Development guidelines for Witsy - a cross-platform Electron-based desktop AI assistant with Vue 3, TypeScript, and multi-LLM integration
Development guidelines and best practices for contributing to Witsy, a cross-platform Electron-based desktop AI assistant that serves as a universal MCP (Model Context Protocol) client.
Witsy is built with Electron, TypeScript, Vue 3, and Vite. It integrates multiple LLM providers and supports chat completion, image generation, speech-to-text, text-to-speech, document search (RAG), and automation capabilities.
Uses Electron Forge + Vite:
1. **Break down tasks** into small, manageable pieces
2. **Code → Lint → Test** for each increment
3. **Keep tests passing** before moving to next task
4. **Confirm completion** with user before proceeding
5. **Never run** end-to-end tests, builds, or the app during development
```bash
npm run lint # Code linting + Vue type checking
npm run lint:css # CSS variable validation
```
Linting must produce no output before running tests. CSS linting validates that all `var(--...)` references use variables defined in `css/variables.css` and `css/index.css`.
```bash
npm run test:ai -- [test-name-or-path] # Run specific unit tests
npm run test:ci # Run with coverage
```
**Testing Best Practices:**
**Test Mocking:**
IPC methods are mocked in `tests/mocks/window.ts`:
```typescript
import { useWindowMock } from '@tests/mocks/window'
// Use windowMock in beforeAll or beforeEach
```
LLM providers are mocked via the `LlmMock` class.
Identify testing gaps by uncovered line count:
```bash
node tools/coverage_gaps.js # Top 20 files
node tools/coverage_gaps.js --limit 10 # Top 10 files
node tools/coverage_gaps.js --filter src/components # Specific directory
node tools/coverage_gaps.js --show-lines # Show uncovered line numbers
```
Shows files sorted by absolute uncovered lines (more impactful than percentage-based coverage).
Renderer state is managed via a reactive store object:
```typescript
import { store } from '@services/store'
```
Holds user preferences, conversation history, and application state.
Centralized configuration in `src/types/config.ts`:
```typescript
export type Configuration = {
engines: Record<string, EngineConfig>, // LLM provider configs
plugins: Record<string, PluginConfig>, // Plugin settings
// ... other sections
}
```
Includes backwards compatibility handling.
Organized constants in `src/ipc_consts.ts`:
```typescript
export const CHAT = {
STREAM: 'chat-stream',
CANCEL: 'chat-cancel'
} as const
```
**IPC Events (main→renderer):**
```typescript
import useIpcListener from '@composables/ipc_listener'
const { onIpcEvent } = useIpcListener()
onIpcEvent('docrepo-modified', (data) => { /* handle */ })
```
Handlers auto-clean on component unmount.
**Bus Events (renderer↔renderer):**
```typescript
import useEventBus from '@composables/event_bus'
const { onBusEvent, emitBusEvent } = useEventBus()
onBusEvent('fullscreen', (data) => { /* handle */ })
emitBusEvent('new-chat', payload)
```
Use for cross-branch communication. Prefer Vue's `emit`/`provide-inject` for parent-child communication.
Globally available CSS classes:
**Always use globally available CSS variables** from `css/variables.css` and `css/index.css`. Do not create custom styles or new variables without team discussion.
Uses `vue-i18n` with translations in `./locales/*.json`:
```typescript
import { t } from '@services/i18n' // In renderer process
```
Leave a review
No reviews yet. Be the first to review this skill!
# Download SKILL.md from killerskills.ai/api/skills/witsy-ai-assistant-development-th6zwx/raw