Claude
Skills
Sign in
Back

qclaw-openclaw-desktop

Included with Lifetime
$97 forever

```markdown

Writing & Docs

What this skill does

```markdown
---
name: qclaw-openclaw-desktop
description: GUI desktop client for OpenClaw — lets non-technical users run and configure OpenClaw AI gateway without the command line
triggers:
  - set up Qclaw desktop app
  - configure OpenClaw with GUI
  - add IM channel to Qclaw
  - develop Qclaw electron app
  - build Qclaw from source
  - connect feishu dingtalk to OpenClaw
  - manage OpenClaw models in Qclaw
  - Qclaw skill plugin management
---

# Qclaw OpenClaw Desktop

> Skill by [ara.so](https://ara.so) — Daily 2026 Skills collection.

Qclaw is an Electron-based desktop GUI for [OpenClaw](https://github.com/openclaw/openclaw), a self-hosted AI gateway. It removes the need for CLI configuration by providing visual wizards for model setup, IM channel integration (Feishu, DingTalk, QQ, WeCom), skill management, and gateway monitoring.

## What Qclaw Does

- **Environment auto-check** — detects and installs Node.js and OpenClaw CLI automatically
- **Model management** — configure any OpenClaw-supported model with OAuth or API key
- **IM integration** — scan QR codes to connect Feishu, DingTalk, QQ, WeCom, WeChat
- **Gateway dashboard** — real-time status, one-click restart/repair
- **Skills management** — install and manage OpenClaw skill plugins
- **Backup/restore** — auto and manual config backups
- **Auto-update** — keeps OpenClaw CLI up to date

## Installation (End Users)

Download from:
- **Official site**: https://qclawai.com/
- **GitHub Releases**: https://github.com/qiuzhi2046/Qclaw/releases

Supported platforms:
- macOS 11 (Big Sur)+
- Windows 10+ x64 (in development)
- Linux (planned)

## Development Setup

### Prerequisites

- Node.js 22+ (Node.js 24 recommended)
- macOS (primary dev platform)
- Git

### Clone and Run

```bash
git clone https://github.com/qiuzhi2046/Qclaw.git
cd Qclaw

npm install

# Start dev server (Electron + Vite hot reload)
npm run dev

# Type check
npm run typecheck

# Run tests
npm test

# Build production app
npm run build
```

### Key npm Scripts

| Command | Description |
|---|---|
| `npm run dev` | Start Electron dev server with HMR |
| `npm run build` | Build and package app with electron-builder |
| `npm test` | Run test suite |
| `npm run typecheck` | TypeScript type checking |

## Project Structure

```
electron/
  main/         # Main process: window, CLI calls, IPC handlers
  preload/      # Preload scripts (secure IPC bridge)
src/
  pages/        # React pages: wizard steps, Dashboard, Chat
  components/   # Shared UI components
  lib/          # Business logic: channel/provider registration
  shared/       # Config workflows, gateway diagnostics
  assets/       # Icons and static assets
docs/           # Architecture docs, changelogs
scripts/        # Build, signing, notarization, versioning, COS release
build/          # App icons and packaging resources
```

## Tech Stack

| Layer | Technology |
|---|---|
| Desktop | Electron |
| Frontend | React + TypeScript |
| Build | Vite + vite-plugin-electron |
| UI | Mantine + Tailwind CSS |
| Packaging | electron-builder |

## Architecture Overview

```
┌─────────────────────────────────────────────┐
│                    Qclaw                    │
│                                             │
│  Main Process (Node.js)  ◄─IPC─►  Renderer │
│  ┌──────────────────┐            (React)    │
│  │ cli.ts           │                       │
│  │ OpenClaw CLI     │    Wizard pages        │
│  │ invocation       │    Dashboard           │
│  ├──────────────────┤    Chat UI             │
│  │ File I/O         │                       │
│  │ Process mgmt     │                       │
│  │ System integration│                      │
│  └────────┬─────────┘                       │
│           │                                 │
│           ▼                                 │
│  OpenClaw CLI (~/.openclaw/)                │
└─────────────────────────────────────────────┘
```

## IPC Communication Pattern

Qclaw uses Electron's contextBridge for secure main ↔ renderer communication.

### Preload Bridge (electron/preload/index.ts)

```typescript
import { contextBridge, ipcRenderer } from 'electron'

contextBridge.exposeInMainWorld('electronAPI', {
  // Invoke main process handlers
  invoke: (channel: string, ...args: unknown[]) =>
    ipcRenderer.invoke(channel, ...args),
  // Subscribe to events from main
  on: (channel: string, callback: (...args: unknown[]) => void) => {
    ipcRenderer.on(channel, (_event, ...args) => callback(...args))
  },
  // Remove listeners
  removeAllListeners: (channel: string) => {
    ipcRenderer.removeAllListeners(channel)
  },
})
```

### Main Process IPC Handler (electron/main/index.ts)

```typescript
import { ipcMain } from 'electron'
import { runOpenClawCli } from './cli'

// Handle CLI invocation from renderer
ipcMain.handle('openclaw:start', async (_event, config) => {
  try {
    const result = await runOpenClawCli(['start', '--config', config])
    return { success: true, output: result }
  } catch (error) {
    return { success: false, error: (error as Error).message }
  }
})

ipcMain.handle('openclaw:status', async () => {
  return await runOpenClawCli(['status'])
})

ipcMain.handle('openclaw:restart', async () => {
  return await runOpenClawCli(['restart'])
})
```

### Renderer Usage

```typescript
// src/pages/Dashboard.tsx
const handleRestart = async () => {
  const result = await window.electronAPI.invoke('openclaw:restart')
  if (result.success) {
    notifications.show({ message: 'Gateway restarted', color: 'green' })
  }
}
```

## Adding a New IM Channel

Channels are registered in `src/lib/` following a provider pattern.

```typescript
// src/lib/channels/myChannel.ts
import type { IMChannel } from '../types'

export const myChannel: IMChannel = {
  id: 'my-channel',
  name: 'My Platform',
  icon: '/assets/my-channel-icon.png',
  pluginPackage: '@openclaw/plugin-my-channel',

  // Fields shown in the setup wizard
  configFields: [
    {
      key: 'appId',
      label: 'App ID',
      type: 'text',
      required: true,
      placeholder: 'Enter your App ID',
    },
    {
      key: 'appSecret',
      label: 'App Secret',
      type: 'password',
      required: true,
      placeholder: 'Enter your App Secret',
    },
  ],

  // Called when user saves the channel config
  async install(config: Record<string, string>) {
    // Install plugin via CLI
    await window.electronAPI.invoke('openclaw:install-plugin', this.pluginPackage)
    // Write config
    await window.electronAPI.invoke('openclaw:write-channel-config', {
      channel: this.id,
      config,
    })
  },
}
```

Register it in `src/lib/channels/index.ts`:

```typescript
import { myChannel } from './myChannel'

export const channels = [
  feishuChannel,
  dingtalkChannel,
  qqChannel,
  wecomChannel,
  myChannel, // add here
]
```

## Adding a New AI Provider/Model

```typescript
// src/lib/providers/myProvider.ts
import type { AIProvider } from '../types'

export const myProvider: AIProvider = {
  id: 'my-provider',
  name: 'My AI Provider',
  authType: 'api-key', // or 'oauth'

  models: [
    { id: 'my-model-v1', name: 'My Model V1', contextLength: 128000 },
    { id: 'my-model-v2', name: 'My Model V2', contextLength: 200000 },
  ],

  configFields: [
    {
      key: 'apiKey',
      label: 'API Key',
      type: 'password',
      required: true,
      envVar: 'MY_PROVIDER_API_KEY', // shown as hint to user
    },
    {
      key: 'baseUrl',
      label: 'Base URL',
      type: 'text',
      required: false,
      defaultValue: 'https://api.myprovider.com',
    },
  ],
}
```

## Gateway Diagnostics (src/shared/)

```typescript
// src/shared/gatewayDiagnostics.ts
import { ipcRenderer } from 'electron'

export async function diagnoseGateway(): Promise<DiagnosticResult> {
  const checks = await Promise.allSettled([
    checkNodeVersion(),
    checkOpenClawInstalled(),
    checkConfigFile(),
    checkGatewayProcess(),
  ])

  return {
    nodeOk: checks[0].status =

Related in Writing & Docs