
Desktop
Implement Lobe Chat Electron desktop features using main-process controllers, IPC, and renderer services without guessing the repo layout.
Overview
Desktop is an agent skill for the Build phase that guides Electron main/renderer IPC controller implementation for Lobe Chat desktop features.
Install
npx skills add https://github.com/lobehub/lobe-chat --skill desktopWhat is this skill?
- Documents Main Process ↔ Renderer IPC architecture with controller modules and a service layer
- Step-by-step pattern: create a Controller with @IpcMethod handlers and typed params from electron-client-ipc
- Example desktop notifications flow with Electron Notification API and structured success/error results
- Maps system APIs (fs, network) in main process vs UI state via store actions in renderer
Adoption & trust: 832 installs on skills.sh; 78.4k GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
You need to add a native desktop capability in Lobe Chat but do not know where controllers, IPC methods, and renderer services belong in the Electron split.
Who is it for?
Builders already in the Lobe Chat / Electron codebase who are implementing a new desktop notification, filesystem, or similar main-process feature.
Skip if: Greenfield Electron apps unrelated to Lobe Chat, or teams only shipping a web-only build with no desktop target.
When should I use this skill?
Implementing or extending Electron desktop features in the Lobe Chat repository using controllers and IPC.
What do I get? / Deliverables
After following the skill, you have a controller module with typed IPC handlers and a clear renderer integration path matching the repo’s desktop architecture.
- New or updated main-process controller with @IpcMethod handlers
- Renderer service wiring aligned with store actions
Recommended Skills
Journey fit
Desktop UI and Electron wiring are product construction work that happens while building the client, not while shipping or growing. The guide centers renderer services, store actions, and IPC to the UI layer—canonical shelf is frontend even though main-process controllers touch system APIs.
How it compares
Repo-specific implementation guide, not a generic Electron tutorial or a testing mock server.
Common Questions / FAQ
Who is desktop for?
Solo and indie developers (and small teams) extending the Lobe Chat Electron desktop app with new IPC-backed features.
When should I use desktop?
Use it during Build when you add or refactor main-process controllers, wire renderer services, or debug IPC between processes in apps/desktop.
Is desktop safe to install?
Treat it as procedural documentation; review the Security Audits panel on this Prism page before trusting the skill package in your agent environment.
SKILL.md
READMESKILL.md - Desktop
# Desktop Feature Implementation Guide ## Architecture Overview ```plaintext Main Process Renderer Process ┌──────────────────┐ ┌──────────────────┐ │ Controller │◄──IPC───►│ Service Layer │ │ (IPC Handler) │ │ │ └──────────────────┘ └──────────────────┘ │ │ ▼ ▼ ┌──────────────────┐ ┌──────────────────┐ │ System APIs │ │ Store Actions │ │ (fs, network) │ │ (UI State) │ └──────────────────┘ └──────────────────┘ ``` ## Step-by-Step Implementation ### 1. Create Controller ```typescript // apps/desktop/src/main/controllers/NotificationCtr.ts import type { ShowDesktopNotificationParams, DesktopNotificationResult, } from '@lobechat/electron-client-ipc'; import { Notification } from 'electron'; import { ControllerModule, IpcMethod } from '@/controllers'; export default class NotificationCtr extends ControllerModule { static override readonly groupName = 'notification'; @IpcMethod() async showDesktopNotification( params: ShowDesktopNotificationParams, ): Promise<DesktopNotificationResult> { if (!Notification.isSupported()) { return { error: 'Notifications not supported', success: false }; } try { const notification = new Notification({ body: params.body, title: params.title }); notification.show(); return { success: true }; } catch (error) { console.error('[NotificationCtr] Failed:', error); return { error: error instanceof Error ? error.message : 'Unknown error', success: false }; } } } ``` ### 2. Define IPC Types ```typescript // packages/electron-client-ipc/src/types.ts export interface ShowDesktopNotificationParams { title: string; body: string; } export interface DesktopNotificationResult { success: boolean; error?: string; } ``` ### 3. Create Service Layer ```typescript // src/services/electron/notificationService.ts import type { ShowDesktopNotificationParams } from '@lobechat/electron-client-ipc'; import { ensureElectronIpc } from '@/utils/electron/ipc'; const ipc = ensureElectronIpc(); export const notificationService = { show: (params: ShowDesktopNotificationParams) => ipc.notification.showDesktopNotification(params), }; ``` ### 4. Implement Store Action ```typescript // src/store/.../actions.ts showNotification: async (title: string, body: string) => { if (!isElectron) return; const result = await notificationService.show({ title, body }); if (!result.success) { console.error('Notification failed:', result.error); } }, ``` ## Best Practices 1. **Security**: Validate inputs, limit exposed APIs 2. **Performance**: Use async methods for heavy operations 3. **Error handling**: Always return structured results 4. **UX**: Provide loading states and error feedback # Desktop Local Tools Implementation ## Workflow Overview 1. Define tool interface (Manifest) 2. Define related types 3. Implement Store Action 4. Implement Service Layer 5. Implement Controller (IPC Handler) 6. Update Agent documentation ## Step 1: Define Tool Interface (Manifest) Location: `src/tools/[tool_category]/index.ts` ```typescript // src/tools/local-files/index.ts export const LocalFilesApiName = { RenameFile: 'renameFile', MoveFile: 'moveFile', } as const; export const LocalFilesManifest = { api: [ { name: LocalFilesApiName.RenameFile, description: 'Rename a local file', parameters: { type: 'object', properties: { oldPath: { type: 'string', description: 'Current file path' }, newName: { type: 'string', description: 'New file name' }, }, required: ['oldPath', 'newName'], }, }, ], }; ``` ## Step 2: Define Types ```typescript // packages/electron-client-ipc/src/types.ts export interface RenameLocalFileParams { oldPath: string; newName: str