Clui Cc Claude Overlay

作者 reason-machines2384a003145a無授權條款83 個星標收錄於 2026年10月8日更新於 2026年10月8日儲存庫3 個月前更新

Command Line User Interface for Claude Code — a floating macOS desktop overlay with multi-tab sessions, permission approval UI, voice input, and skills marketplace.

僅含說明AI & Agents
AI 產生的概覽

介紹並指導安裝 Clui CC——為 Claude Code CLI 提供多分頁、權限核准、語音與技能市場的 macOS 浮動視窗。

功能
此技能介紹 Clui CC:一個把 Claude Code CLI 包裝成 macOS 浮動視窗的桌面工具,支援多分頁工作階段、工具權限核准介面、本機 Whisper 語音輸入、對話歷史與技能市場。內容涵蓋前置需求、安裝步驟、快速鍵、架構說明、window.clui IPC 介面、佈景主題設定以及自訂技能撰寫。此外也提供疑難排解步驟與已測試的元件版本。
適用情境
適用於在 macOS 上安裝或設定 Clui CC,或使用其分頁、工作階段、權限掛鉤、語音輸入與技能市場時。也適合在 Clui 技能目錄下新增自訂技能。
執行需求
需要 macOS 13+、Node.js 18+、Python 3.10+(3.12+ 需 setuptools)、已驗證的 Claude Code CLI,以及用於語音輸入的 Whisper CLI。安裝過程使用 git、Homebrew 與 npm;技能市場可選用 GitHub 端點。此技能本身不附帶指令碼。

Clui CC — Claude Code Desktop Overlay

Skill by ara.so — Daily 2026 Skills collection.

Clui CC wraps the Claude Code CLI in a transparent, floating macOS overlay with multi-tab sessions, a permission approval UI (PreToolUse HTTP hooks), voice input via Whisper, conversation history, and a skills marketplace. It requires an authenticated claude CLI and runs entirely local — no telemetry or cloud dependency.


Prerequisites

RequirementMinimumNotes
macOS13+Overlay is macOS-only
Node.js18+LTS 20 or 22 recommended
Python3.10+Needs setuptools on 3.12+
Claude Code CLIanyMust be authenticated
Whisper CLIanyFor voice input
bash
# 1. Xcode CLI tools (native module compilation)xcode-select --install
# 2. Node.js via Homebrewbrew install nodenode --version   # confirm ≥18
# 3. Python setuptools (required on Python 3.12+)python3 -m pip install --upgrade pip setuptools
# 4. Claude Code CLInpm install -g @anthropic-ai/claude-code
# 5. Authenticate Claude Codeclaude
# 6. Whisper for voice inputbrew install whisper-cli

Installation

Recommended: App installer (non-developer)

bash
git clone https://github.com/lcoutodemos/clui-cc.git# Then open the clui-cc folder in Finder and double-click install-app.command

On first launch macOS may block the unsigned app — go to System Settings → Privacy & Security → Open Anyway.

Developer workflow

bash
git clone https://github.com/lcoutodemos/clui-cc.gitcd clui-ccnpm installnpm run dev       # Hot-reloads renderer; restart for main-process changes

Command scripts

bash
./commands/setup.command    # Environment check + install deps./commands/start.command    # Build and launch from source./commands/stop.command     # Stop all Clui CC processes
npm run build               # Production build (no packaging)npm run dist                # Package as macOS .app → release/npm run doctor              # Environment diagnostic

Key Shortcuts

ShortcutAction
⌥ + SpaceShow / hide the overlay
Cmd + Shift + KFallback toggle (if ⌥+Space is claimed)

Architecture

UI prompt → Main process spawns claude -p → NDJSON stream → live render                                         → tool call? → permission UI → approve/deny

Process flow

  1. Each tab spawns claude -p --output-format stream-json as a subprocess.
  2. RunManager parses NDJSON; EventNormalizer normalizes events.
  3. ControlPlane manages tab lifecycle: connecting → idle → running → completed/failed/dead.
  4. Tool permission requests arrive via HTTP hooks to PermissionServer (localhost only).
  5. Renderer polls backend health every 1.5 s and reconciles tab state.
  6. Sessions resume with --resume <session-id>.

Project structure

src/├── main/│   ├── claude/       # ControlPlane, RunManager, EventNormalizer│   ├── hooks/        # PermissionServer (PreToolUse HTTP hooks)│   ├── marketplace/  # Plugin catalog fetch + install│   ├── skills/       # Skill auto-installer│   └── index.ts      # Window creation, IPC handlers, tray├── renderer/│   ├── components/   # TabStrip, ConversationView, InputBar, …│   ├── stores/       # Zustand session store│   ├── hooks/        # Event listeners, health reconciliation│   └── theme.ts      # Dual palette + CSS custom properties├── preload/          # Secure IPC bridge (window.clui API)└── shared/           # Canonical types, IPC channel definitions

IPC API (window.clui)

The preload bridge exposes window.clui in the renderer. Key methods:

typescript
// Send a prompt to the active tab's claude processwindow.clui.sendPrompt(tabId: string, text: string): Promise<void>
// Approve or deny a pending tool-use permissionwindow.clui.resolvePermission(requestId: string, approved: boolean): Promise<void>
// Create a new tab (spawns a new claude -p process)window.clui.createTab(): Promise<{ tabId: string }>
// Resume a past session by idwindow.clui.resumeSession(tabId: string, sessionId: string): Promise<void>
// Subscribe to normalized events from a tabwindow.clui.onTabEvent(tabId: string, callback: (event: NormalizedEvent) => void): () => void
// Get conversation history listwindow.clui.getHistory(): Promise<SessionMeta[]>

Working with Tabs and Sessions

Creating a tab and sending a prompt (renderer)

typescript
import { useEffect, useState } from 'react'
export function useClaudeTab() {  const [tabId, setTabId] = useState<string | null>(null)  const [messages, setMessages] = useState<NormalizedEvent[]>([])
  useEffect(() => {    window.clui.createTab().then(({ tabId }) => {      setTabId(tabId)
      const unsubscribe = window.clui.onTabEvent(tabId, (event) => {        setMessages((prev) => [...prev, event])      })
      return unsubscribe    })  }, [])
  const send = (text: string) => {    if (!tabId) return    window.clui.sendPrompt(tabId, text)  }
  return { messages, send }}

Resuming a past session

typescript
async function resumeLastSession() {  const history = await window.clui.getHistory()  if (history.length === 0) return
  const { tabId } = await window.clui.createTab()  const lastSession = history[0] // most recent first  await window.clui.resumeSession(tabId, lastSession.sessionId)}

Permission Approval UI

Tool calls are intercepted by PermissionServer via PreToolUse HTTP hooks before execution. The renderer receives a permission_request event and must resolve it.

typescript
// Renderer: listen for permission requestswindow.clui.onTabEvent(tabId, async (event) => {  if (event.type !== 'permission_request') return
  const { requestId, toolName, toolInput } = event
  // Show your approval UI, then:  const approved = await showApprovalDialog({ toolName, toolInput })  await window.clui.resolvePermission(requestId, approved)})
typescript
// Main process: PermissionServer registers a hook with claude -p// The hook endpoint receives POST requests from Claude Code like:// { "tool": "bash", "input": { "command": "rm -rf dist/" }, "session_id": "..." }// It holds the request until the renderer resolves it.

Voice Input

Voice input uses Whisper locally. It is installed automatically by install-app.command or via brew install whisper-cli. No API key is needed — transcription runs entirely on-device.

typescript
// Triggered from InputBar component via IPCwindow.clui.startVoiceInput(): Promise<void>window.clui.stopVoiceInput(): Promise<{ transcript: string }>

Skills Marketplace

Install skills (plugins) from Anthropic's GitHub repos without leaving the UI.

typescript
// Fetch available skills (cached 5 min, fetched from raw.githubusercontent.com)const skills = await window.clui.marketplace.list()// [{ id, name, description, repoUrl, version }, ...]
// Install a skill (downloads tarball from api.github.com)await window.clui.marketplace.install(skillId: string)
// List installed skillsconst installed = await window.clui.marketplace.listInstalled()

Network calls made by the marketplace:

EndpointPurposeRequired
raw.githubusercontent.com/anthropics/*Skill catalog (5 min cache)No — graceful fallback
api.github.com/repos/anthropics/*/tarball/*Skill tarball downloadNo — skipped on failure

Theme Configuration

typescript
// src/renderer/theme.ts — dual palette with CSS custom properties// Toggle via the UI or programmatically:window.clui.setTheme('dark' | 'light' | 'system')

Custom CSS properties are applied to :root and can be overridden in renderer stylesheets:

css
:root {  --clui-bg: rgba(20, 20, 20, 0.85);  --clui-text: #f0f0f0;  --clui-accent: #7c5cfc;  --clui-pill-radius: 24px;}

Adding a Custom Skill

Skills are auto-loaded from ~/.clui/skills/. A skill is a directory with a skill.js entry:

typescript
// ~/.clui/skills/my-skill/skill.jsmodule.exports = {  name: 'my-skill',  version: '1.0.0',  description: 'Does something useful',
  // Called when the skill is activated by a matching prompt  async onPrompt(context) {    const { prompt, tabId, clui } = context    if (!prompt.includes('my trigger')) return false   // pass through
    await clui.sendMessage(tabId, `Handled by my-skill: ${prompt}`)    return true  // consumed — don't forward to claude  },}

Troubleshooting

Self-check

bash
npm run doctor

Common issues

App blocked on first launch → System Settings → Privacy & Security → Open Anyway

node-pty fails to compile

bash
xcode-select --installpython3 -m pip install --upgrade pip setuptoolsnpm install

claude not found

bash
npm install -g @anthropic-ai/claude-codeclaude   # authenticatewhich claude   # confirm it's on PATH

Whisper not found

bash
brew install whisper-cliwhich whisper-cli

Port conflict on PermissionServer The HTTP hook server runs on localhost only. If another process occupies its port, restart with:

bash
./commands/stop.command./commands/start.command

setuptools missing (Python 3.12+)

bash
python3 -m pip install --upgrade pip setuptools

Overlay not showing

  • Try the fallback shortcut: Cmd + Shift + K
  • Check that Clui CC has Accessibility permission: System Settings → Privacy & Security → Accessibility

Tested Versions

ComponentVersion
macOS15.x Sequoia
Node.js20.x LTS, 22.x
Python3.12 (+ setuptools)
Electron33.x
Claude Code CLI2.1.71

References

  • Claude Code docs
  • Architecture deep-dive [blocked]
  • Troubleshooting guide [blocked]
  • MIT License [blocked]

來源與署名

來源:reason-machines/trending-skills位於skills/clui-cc-claude-overlay提交2384a00

授權條款: 無授權條款

內容歸原作者所有。SourceWeft 從公開儲存庫中收錄這些內容。

檢舉或申請下架