clui-cc-claude-overlay

安装量: 1.1K
排名: #3893

安装

npx skills add https://github.com/aradotso/trending-skills --skill clui-cc-claude-overlay

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 Requirement Minimum Notes macOS 13+ Overlay is macOS-only Node.js 18+ LTS 20 or 22 recommended Python 3.10+ Needs setuptools on 3.12+ Claude Code CLI any Must be authenticated Whisper CLI any For voice input

1. Xcode CLI tools (native module compilation)

xcode-select --install

2. Node.js via Homebrew

brew install node node --version

confirm ≥18

3. Python setuptools (required on Python 3.12+)

python3 -m pip install --upgrade pip setuptools

4. Claude Code CLI

npm install -g @anthropic-ai/claude-code

5. Authenticate Claude Code

claude

6. Whisper for voice input

brew install whisper-cli Installation Recommended: App installer (non-developer) 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 git clone https://github.com/lcoutodemos/clui-cc.git cd clui-cc npm install npm run dev

Hot-reloads renderer; restart for main-process changes

Command scripts ./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 Shortcut Action ⌥ + Space Show / hide the overlay Cmd + Shift + K Fallback 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 Each tab spawns claude -p --output-format stream-json as a subprocess. RunManager parses NDJSON; EventNormalizer normalizes events. ControlPlane manages tab lifecycle: connecting → idle → running → completed/failed/dead . Tool permission requests arrive via HTTP hooks to PermissionServer (localhost only). Renderer polls backend health every 1.5 s and reconciles tab state. Sessions resume with --resume . 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: // Send a prompt to the active tab's claude process window . clui . sendPrompt ( tabId : string , text : string ) : Promise < void

// Approve or deny a pending tool-use permission window . 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 id window . clui . resumeSession ( tabId : string , sessionId : string ) : Promise < void

// Subscribe to normalized events from a tab window . clui . onTabEvent ( tabId : string , callback : ( event : NormalizedEvent ) => void ) : ( ) => void // Get conversation history list window . clui . getHistory ( ) : Promise < SessionMeta [ ]

Working with Tabs and Sessions Creating a tab and sending a prompt (renderer) 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 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. // Renderer: listen for permission requests window . 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 ) } ) // 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. // Triggered from InputBar component via IPC window . clui . startVoiceInput ( ) : Promise < void

window . clui . stopVoiceInput ( ) : Promise < { transcript : string }

Skills Marketplace Install skills (plugins) from Anthropic's GitHub repos without leaving the UI. // 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 skills const installed = await window . clui . marketplace . listInstalled ( ) Network calls made by the marketplace: Endpoint Purpose Required raw.githubusercontent.com/anthropics/ Skill catalog (5 min cache) No — graceful fallback api.github.com/repos/anthropics//tarball/* Skill tarball download No — skipped on failure Theme Configuration // 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: :root { --clui-bg : rgba ( 20 , 20 , 20 , 0.85 ) ; --clui-text :

f0f0f0

; --clui-accent :

7c5cfc

; --clui-pill-radius : 24 px ; } Adding a Custom Skill Skills are auto-loaded from ~/.clui/skills/ . A skill is a directory with a skill.js entry: // ~/.clui/skills/my-skill/skill.js module . 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 npm run doctor Common issues App blocked on first launch → System Settings → Privacy & Security → Open Anyway node-pty fails to compile xcode-select --install python3 -m pip install --upgrade pip setuptools npm install claude not found npm install -g @anthropic-ai/claude-code claude

authenticate

which claude

confirm it's on PATH

Whisper not found brew install whisper-cli which whisper-cli Port conflict on PermissionServer The HTTP hook server runs on localhost only. If another process occupies its port, restart with: ./commands/stop.command ./commands/start.command setuptools missing (Python 3.12+) 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 Component Version macOS 15.x Sequoia Node.js 20.x LTS, 22.x Python 3.12 (+ setuptools) Electron 33.x Claude Code CLI 2.1.71 References Claude Code docs Architecture deep-dive Troubleshooting guide MIT License

返回排行榜