Skip to content
Merged
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
153 changes: 153 additions & 0 deletions .opencode/skills/codenomad-architecture-guide/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
---
name: codenomad-architecture-guide
description: |
Comprehensive architecture and SDK navigation guide for the CodeNomad codebase.

**When to use:** Load this skill when you need to navigate the CodeNomad monorepo, understand cross-package dependencies, work with the OpenCode SDK V2, or ensure you don't miss related code when implementing features or fixing bugs. This skill covers the 6 functional areas (ServerBackend, UserInterface, DesktopClient, SpeechAndAudio, BuildAndPackaging, CloudflareDeployment), OpenCode SDK V2 integration patterns, critical schema behaviors, and feature traces with decision branches.

**Trigger contexts:** Working on CodeNomad features, debugging cross-area issues, integrating OpenCode SDK APIs, adding UI components, implementing server routes, or navigating the monorepo structure.

**Permission required:** Agent must explicitly request or be granted permission to load this skill.
---

# CodeNomad Architecture & SDK Navigation Skill

## Quick Start (by contribution frequency)

- **UI component/feature (60%)** → Read `references/ui-conventions.md` → Check i18n
- **Server route/feature (25%)** → Read `references/server-conventions.md` → Check `references/feature-traces.md`
- **Bug fix (10%)** → Use Navigation Guide below → Check `references/feature-traces.md`
- **Desktop/Plugin (5%)** → Read `references/desktop-conventions.md`
- **Not covered?** → See "Escape Hatch" at bottom

## 1. Architecture Overview

CodeNomad is a multi-platform desktop application with a Fastify backend and SolidJS frontend.

### 6 Functional Areas (from RPG analysis)

| Area | Entities | Key Responsibility |
|------|----------|-------------------|
| **UserInterface** | 613 | SolidJS components, stores, hooks, i18n, API client |
| **ServerBackend** | 418 | Fastify routes, auth, workspaces, filesystem, speech |
| **SpeechAndAudio** | 74 | Speech synthesis, voice mode, conversation mode |
| **DesktopClient** | 59 | Electron main, Tauri Rust, preload, IPC |
| **BuildAndPackaging** | 28 | Build scripts, packaging, resource bundling |
| **CloudflareDeployment** | 3 | Edge deployment, asset serving |

### Package Map

- `packages/server/` — Fastify backend, workspaces, auth, speech, sidecars
- `packages/ui/` — SolidJS frontend, stores, components, i18n
- `packages/electron-app/` — Electron desktop wrapper
- `packages/tauri-app/` — Tauri desktop wrapper (Rust + webview)
- `packages/opencode-plugin/` — OpenCode plugin integration

### Key Entry Points

- **Server:** `packages/server/src/index.ts` (CLI entry)
- **UI:** `packages/ui/src/main.tsx` (app bootstrap)
- **Electron:** `packages/electron-app/electron/main/main.ts`
- **Tauri:** `packages/tauri-app/src-tauri/src/main.rs`

## 2. Navigation Guide

### Finding Code in the Codebase

Use grep and file search tools to navigate:

**Search by intent:**
- `grep "permission approval" packages/ui/src/components/`
- `grep "session list" packages/ui/src/stores/`
- `grep "workspace create" packages/server/src/server/routes/`

**Search by imports:**
- Find what uses a module: `grep "import.*from.*module-path" packages/`
- Find exports: `grep "^export" packages/server/src/api-types.ts`

**Cross-reference by feature:**
- Server API types: `packages/server/src/api-types.ts`
- UI type mirrors: `packages/ui/src/types/`
- SDK wrappers: `packages/ui/src/lib/sdk-manager.ts`

## 3. SDK Schema Verification (Mandatory)

**SDK Note:** The OpenCode SDK is an external package (`@opencode-ai/sdk/v2/client`). Its implementation lives outside this repository.

- After `npm install`, you can inspect types in `node_modules/@opencode-ai/sdk/v2/client.d.ts`
- **Fallback:** Read the actual usage patterns in CodeNomad code (see `references/sdk-api-reference.md` for file locations)
- When in doubt, check how the SDK is imported and used in existing CodeNomad files

This skill provides navigation and patterns, not definitive schemas.

## 4. Anti-Patterns

### Common Mistakes

| Mistake | Correct Approach | Reference |
|---------|-----------------|-----------|
| Import `enMessages` directly | Use `t()` or `tGlobal()` | `packages/ui/src/lib/i18n/index.tsx` |
| Set `metadata: { flag: true }` on assistant parts | Use client-side registry | `packages/ui/src/stores/session-compaction.ts` |
| Call `client.session.*` directly without worktree routing | Use `getOrCreateWorktreeClient()` | `packages/ui/src/stores/worktrees.ts` |
| Forget SSE disconnection handling | Add handlers | `packages/ui/src/lib/event-source-handlers.ts` |
| Add hardcoded strings without i18n | Add to English + all 7 locales | `packages/ui/src/lib/i18n/messages/` |
| Modify server route without checking UI API client | Trace full feature flow | `references/feature-traces.md` |
| Change API type without checking UI type matches | Check UI types mirror server types | `packages/ui/src/types/` vs `packages/server/src/api-types.ts` |

## 5. Platform Integration Checklist

### Desktop Platform Rules

- **Existing IPC/handlers (pre-Tauri):** MUST implement in both Electron + Tauri
- **New features:** Implement in Electron first, Tauri if time permits
- **Native APIs (dialogs, notifications):** Use `packages/ui/src/lib/native/` abstraction

### Checklist

- [ ] Electron main-process changes? (`packages/electron-app/electron/main/`)
- [ ] Tauri Rust changes? (`packages/tauri-app/src-tauri/src/`)
- [ ] Preload API exposure? (`packages/electron-app/electron/preload/`)
- [ ] Native abstraction? (`packages/ui/src/lib/native/`)

## 6. Implementation Checklist

Before submitting changes:

- [ ] Run impact analysis: `grep "YOUR_EXPORT_NAME" packages/` to find all usages
- [ ] Check i18n: Search for hardcoded strings in modified files
- [ ] Verify file length: Check line count (warn >500, reject >800 source; >1000 tests)
- [ ] Check DesktopClient: Does this need IPC/main-process changes?
- [ ] Verify SDK compatibility: Check types in `node_modules/@opencode-ai/sdk/v2/client.d.ts`
- [ ] Cross-area check: If modifying server routes, check UI stores and API clients
- [ ] Check anti-patterns: Review "Common Mistakes" section above
- [ ] API compatibility: If changing `api-types.ts`, check UI type matches

## 7. Escape Hatch + Update Criteria

### Not Covered?

If your change involves areas not documented here:

1. Read package entry points and scan directory structure
2. Ask the user before proceeding with unfamiliar code

### Update This Skill If

- You discover a new SDK gotcha not documented in `references/sdk-critical-behaviors.md`
- You add a new cross-area feature flow (add to `references/feature-traces.md`)
- File paths or conventions change significantly
- You find an anti-pattern occurring repeatedly
- SDK schemas change and examples become outdated

## Reference Files

| File | Purpose |
|------|---------|
| `references/architecture-overview.md` | Package structure, functional areas, entry points |
| `references/ui-conventions.md` | SolidJS, i18n, stores, components, testing |
| `references/server-conventions.md` | Fastify, API types, config, testing |
| `references/desktop-conventions.md` | Electron + Tauri parity, native abstractions |
| `references/sdk-api-reference.md` | OpenCode SDK V2 categories and signatures |
| `references/sdk-critical-behaviors.md` | Schema gotchas, limitations, decision matrix |
| `references/sdk-integration-patterns.md` | Client lifecycle, error handling, optimistic updates |
| `references/feature-traces.md` | End-to-end flows with decision branches |
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Architecture Overview

## Package Structure

| Package | Purpose | Key Subdirectories |
|---------|---------|-------------------|
| `packages/server/` | Fastify backend | `src/server/routes/`, `src/workspaces/`, `src/auth/`, `src/speech/` |
| `packages/ui/` | SolidJS frontend | `src/components/`, `src/stores/`, `src/lib/`, `src/types/` |
| `packages/electron-app/` | Electron desktop wrapper | `electron/main/`, `electron/preload/`, `electron/resources/` |
| `packages/tauri-app/` | Tauri desktop wrapper | `src-tauri/src/`, `src-tauri/capabilities/` |
| `packages/opencode-plugin/` | OpenCode plugin integration | `plugin/lib/`, `plugin/codenomad.ts` |
| `packages/cloudflare/` | Edge deployment | `src/`, `scripts/` |

## Functional Areas (from RPG)

### UserInterface (613 entities)
- **Components:** JSX components in `packages/ui/src/components/`
- **Stores:** Signal-based state in `packages/ui/src/stores/`
- **Hooks:** Reusable logic in `packages/ui/src/lib/hooks/`
- **i18n:** 7-locale translation system in `packages/ui/src/lib/i18n/`
- **API Client:** SDK wrapper in `packages/ui/src/lib/sdk-manager.ts`

### ServerBackend (418 entities)
- **API Routes:** Fastify route handlers in `packages/server/src/server/routes/`
- **Authentication:** Auth manager, session manager, token manager in `packages/server/src/auth/`
- **Background Processes:** Process spawn and management in `packages/server/src/background-processes/`
- **Configuration:** YAML-based settings in `packages/server/src/settings/`
- **Filesystem:** Restricted file browser in `packages/server/src/filesystem/`
- **Workspaces:** Git worktrees, runtime management in `packages/server/src/workspaces/`

### SpeechAndAudio (74 entities)
- **Speech Synthesis:** OpenAI-compatible provider in `packages/server/src/speech/`
- **Voice Mode:** Real-time voice state management in `packages/server/src/plugins/voice-mode.ts`
- **Conversation Mode:** Client-side speech queue in `packages/ui/src/stores/conversation-speech.ts`

### DesktopClient (59 entities)
- **Electron Main:** Process manager, menu, IPC in `packages/electron-app/electron/main/`
- **Tauri Rust:** CLI manager, certificate management in `packages/tauri-app/src-tauri/src/`
- **Preload:** API exposure layer in `packages/electron-app/electron/preload/`

### BuildAndPackaging (28 entities)
- **Build Scripts:** Version sync, icon generation, resource copying
- **Packaging:** Server resource bundling, node runtime preparation

### CloudflareDeployment (3 entities)
- **Edge Functions:** Asset serving with cache headers in `packages/cloudflare/src/index.ts`

## Key Entry Points

| Entry Point | File | Purpose |
|-------------|------|---------|
| Server CLI | `packages/server/src/index.ts` | Parses CLI options, starts HTTP server |
| UI Bootstrap | `packages/ui/src/main.tsx` | Initializes SolidJS app, mounts to DOM |
| Electron Main | `packages/electron-app/electron/main/main.ts` | Creates window, starts CLI process |
| Tauri Main | `packages/tauri-app/src-tauri/src/main.rs` | Rust entry, sets up window and CLI |
| Plugin Entry | `packages/opencode-plugin/plugin/codenomad.ts` | Initializes CodeNomad plugin tools |

## Inter-Area Dependencies

```
UserInterface → ServerBackend (via SDK HTTP calls)
UserInterface → SpeechAndAudio (via conversation-speech store)
DesktopClient → UserInterface (hosts the UI in a native window)
DesktopClient → ServerBackend (spawns and manages server process)
ServerBackend → SpeechAndAudio (delegates to speech providers)
ServerBackend → CloudflareDeployment (fetches remote assets)
```

## Finding Code by Area

| Area | Directory Patterns | Search Command |
|------|------------------|----------------|
| UserInterface | `packages/ui/src/components/`, `packages/ui/src/stores/` | `grep "query" packages/ui/src/` |
| ServerBackend | `packages/server/src/server/routes/`, `packages/server/src/workspaces/` | `grep "query" packages/server/src/` |
| DesktopClient | `packages/electron-app/electron/main/`, `packages/tauri-app/src-tauri/src/` | `grep "query" packages/*-app/` |
| SpeechAndAudio | `packages/server/src/speech/`, `packages/ui/src/stores/conversation-speech.ts` | `grep "query" packages/**/speech*` |
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
# Desktop Conventions

## Dual Platform: Electron + Tauri

CodeNomad supports two desktop platforms:
- **Electron** (primary, mature)
- **Tauri** (emerging, Rust-based)

## Electron

### Directory Structure

```
packages/electron-app/electron/
├── main/ # Main process code
│ ├── main.ts # Entry point, window management
│ ├── menu.ts # Application menu
│ ├── ipc.ts # IPC handlers
│ ├── storage.ts # File system storage
│ ├── permissions.ts # Media permissions
│ ├── user-shell.ts # Shell command execution
│ └── process-manager.ts # CLI process management
├── preload/ # Preload scripts
│ └── index.cjs # API exposure to renderer
└── resources/ # Bundled resources
└── cli-supervisor.cjs # Process supervisor
```

### Main Process Responsibilities

- Create and manage browser windows
- Spawn and monitor CLI server process
- Handle native APIs (file dialogs, notifications)
- Manage application lifecycle

### IPC Pattern

```typescript
// Main process handler
// packages/electron-app/electron/main/ipc.ts
function setupCliIPC() {
ipcMain.handle("dialog:open", async (_, options) => {
return dialog.showOpenDialog(options)
})
}

// Preload exposure
// packages/electron-app/electron/preload/index.cjs
contextBridge.exposeInMainWorld("electronAPI", {
openDialog: (options) => ipcRenderer.invoke("dialog:open", options)
})
```

## Tauri

### Directory Structure

```
packages/tauri-app/
├── src-tauri/
│ ├── src/ # Rust backend code
│ │ ├── main.rs # Entry point
│ │ ├── cli_manager.rs # CLI process management
│ │ ├── cert_manager.rs # TLS certificate management
│ │ └── linux_tls.rs # Linux TLS handling
│ └── capabilities/ # Permission capabilities
└── src/ # Frontend code (same as UI)
```

### Rust Backend

- Commands exposed to frontend via `#[tauri::command]`
- Process management similar to Electron's process-manager.ts
- Certificate management for HTTPS

### Command Pattern

```rust
// packages/tauri-app/src-tauri/src/main.rs
#[tauri::command]
fn open_dialog(options: DialogOptions) -> Result<DialogResult, String> {
// Implementation
}
```

## Parity Rules

| Scenario | Rule |
|----------|------|
| Existing IPC/handlers (pre-Tauri) | MUST implement in both Electron + Tauri |
| New features | Implement in Electron first, Tauri if time permits |
| Native APIs | Use `packages/ui/src/lib/native/` abstraction layer |

## Native Abstractions

CodeNomad abstracts native APIs to work across Electron, Tauri, and Web:

| Feature | Abstraction File |
|---------|-----------------|
| File dialogs | `packages/ui/src/lib/native/native-functions.ts` |
| Desktop file drop | `packages/ui/src/lib/native/desktop-file-drop.ts` |
| Electron-specific | `packages/ui/src/lib/native/electron/functions.ts` |
| Wake lock | `packages/ui/src/lib/native/wake-lock.ts` |
| Remote windows | `packages/ui/src/lib/native/remote-window.ts` |
| CLI restart | `packages/ui/src/lib/native/cli.ts` |

### Abstraction Pattern

```typescript
// packages/ui/src/lib/native/native-functions.ts
export type NativeDialogResult = string | string[] | null

export async function openNativeFileDialogs(
options?: Omit<NativeDialogOptions, "mode" | "multiple">
): Promise<string[]> {
const result = await openNativeDialog({ mode: "file", multiple: true, ...options })
// Platform-specific implementation
}
```

## Platform Detection

```typescript
// packages/ui/src/lib/runtime-env.ts
export function isElectronHost(): boolean { /* ... */ }
export function isTauriHost(): boolean { /* ... */ }
export function isWebHost(): boolean { /* ... */ }
```

## Checklist for Desktop Features

- [ ] Electron main-process changes? (`packages/electron-app/electron/main/`)
- [ ] Tauri Rust changes? (`packages/tauri-app/src-tauri/src/`)
- [ ] Preload API exposure? (`packages/electron-app/electron/preload/`)
- [ ] Native abstraction? (`packages/ui/src/lib/native/`)
- [ ] Cross-platform test (Electron + Tauri + Web)
Loading
Loading