Setup and configure cc-hooks plugin
Guides users through installing and configuring the cc-hooks plugin with shell aliases, API keys, and preferences.
/plugin marketplace add husniadil/cc-hooks/plugin install cc-hooks-plugin@cc-hooks-plugincheck|apikeys|testHelp the user set up and configure the cc-hooks plugin. Follow these steps:
Check if uv is installed:
uv --version
If not installed, guide the user to install it:
curl -LsSf https://astral.sh/uv/install.sh | shpowershell -c "irm https://astral.sh/uv/install.ps1 | iex"cld Alias AvailabilityCheck if cld command is available using BOTH methods:
# Detect user's shell
echo $SHELL
# Method 1: Test if cld works in current shell
type cld 2>/dev/null && echo "cld: available in current shell" || echo "cld: not found in current shell"
# Method 2: Check if cld is configured in shell config files
grep -h "alias cld=" ~/.zshrc ~/.bashrc ~/.bash_profile ~/.profile 2>/dev/null && echo "cld: found in shell config" || echo "cld: not found in shell config"
Decision logic:
cld → Skip to checking wrapper alias (Section 2.2)cld aliascld Alias (only if not found)If cld is not available in either current shell or config files, guide the user to add it:
For zsh users (~/.zshrc):
alias cld='~/.claude/plugins/marketplaces/cc-hooks-plugin/claude.sh'
For bash users (~/.bashrc or ~/.bash_profile):
alias cld='~/.claude/plugins/marketplaces/cc-hooks-plugin/claude.sh'
Ask the user if they would like to add the cld alias to their shell configuration for convenience.
If the user agrees, add the appropriate alias to their shell config file and remind them to run
source ~/.zshrc (or appropriate config file) or restart their terminal.
After confirming cld is available (either in current shell or config files), check if a wrapper
alias already exists:
# Check for any alias that wraps cld with arguments
grep -h "alias.*='cld " ~/.zshrc ~/.bashrc ~/.bash_profile ~/.profile 2>/dev/null | grep -v "^#"
If wrapper alias exists:
If no wrapper exists:
Inform the user that they can optionally create a convenient wrapper alias with their preferred default settings. Present the available preset configurations:
Preset configurations:
alias cc='cld' - Prerecorded audio onlyalias cc='cld --audio=gtts --ai=basic' - Google TTS with AI (requires OpenRouter)alias cc='cld --audio=gtts --ai=full' - Google TTS with all AI features (requires
OpenRouter)alias cc='cld --audio=elevenlabs --ai=full' - ElevenLabs with AI (requires both
API keys)alias cc='cld --silent' - No audio, visual onlyImplementation:
--language=id)source ~/.zshrc (or appropriate config file) or restart their terminalcld with different flags when neededExample:
# Enhanced preset with Indonesian language
alias cc='cld --audio=gtts --ai=basic --language=id'
Check if statusline is configured properly in ~/.claude/settings.json:
# Read the settings file
cat ~/.claude/settings.json | grep -A 2 '"statusLine"'
Expected configuration:
"statusLine": {
"type": "command",
"command": "uv run ~/.claude/plugins/marketplaces/cc-hooks-plugin/status-lines/status_line.py"
}
If not configured or pointing to wrong path, offer to update it automatically or guide the user to add/update the statusLine configuration.
IMPORTANT: Plugin updates will delete and redownload all plugin files. Therefore, API keys and
environment variables MUST be stored outside the plugin directory (e.g., in shell config files like
~/.zshrc or ~/.bashrc, or in separate files loaded by your shell).
First, check if API keys are available in the current environment:
# Check for API keys in current environment (DO NOT print values)
env | grep -E "OPENROUTER_API_KEY|ELEVENLABS_API_KEY" | sed 's/=.*/=[SET]/' || echo "No API keys found"
If API keys ARE available (regardless of how they're loaded):
If API keys ARE NOT available, check shell config files:
# Check for API keys in shell config (DO NOT print values)
grep -h "OPENROUTER_API_KEY\|ELEVENLABS_API_KEY" ~/.zshrc ~/.bashrc ~/.bash_profile ~/.profile 2>/dev/null | sed 's/=.*/=[REDACTED]/' || echo "No API keys found in shell config"
OpenRouter (for AI contextual messages):
OPENROUTER_API_KEY: Get from https://openrouter.ai/keys--ai=basic or --ai=fullcld --audio=gtts --ai=full (or --ai=basic)ElevenLabs (for premium TTS):
ELEVENLABS_API_KEY: Get from https://elevenlabs.io/--audio=elevenlabsOnly offer this if API keys are NOT available in the current environment.
Guide the user to add them to their shell config:
For zsh users (~/.zshrc):
# cc-hooks API Keys
export OPENROUTER_API_KEY="your-key-here"
export ELEVENLABS_API_KEY="your-key-here"
For bash users (~/.bashrc or ~/.bash_profile):
# cc-hooks API Keys
export OPENROUTER_API_KEY="your-key-here"
export ELEVENLABS_API_KEY="your-key-here"
After adding:
source ~/.zshrc (or appropriate config file) or restart their terminalsource ~/.api-keys in their shell
config)SECURITY NOTE: Never print actual API key values in output. Always redact or mask them.
This step is OPTIONAL but highly recommended - it provides a better experience for all users.
The config file (~/.claude/.cc-hooks/config.yaml) lets you set default preferences without using
CLI flags:
Benefits for Zed/Editor users:
Benefits for Terminal users:
cld or claude# Check if config file already exists
ls -la ~/.claude/.cc-hooks/config.yaml
If config exists:
If config doesn't exist:
If the user wants to create a config file:
Option 1: Create with default example (Recommended)
# Create example config with all options documented
uv run ~/.claude/plugins/marketplaces/cc-hooks-plugin/utils/config_loader.py --create-example
# Show the created file
cat ~/.claude/.cc-hooks/config.yaml
Option 2: Interactive configuration
Ask the user for their preferences:
Then create a customized config file based on their answers.
Example for Indonesian user with Google TTS:
audio:
providers: gtts,prerecorded
language: id
cache_enabled: true
openrouter:
enabled: false
Example for premium setup (requires API keys):
audio:
providers: elevenlabs,gtts,prerecorded
language: en
cache_enabled: true
elevenlabs:
voice_id: 21m00Tcm4TlvDq8ikWAM
model_id: eleven_flash_v2_5
openrouter:
enabled: true
model: openai/gpt-4o-mini
contextual_stop: true
contextual_pretooluse: false
After creating the config, explain to the user:
Configuration Priority (highest to lowest):
cld --language=es (terminal usage, session override)export CC_TTS_LANGUAGE=es (temporary override)~/.claude/.cc-hooks/config.yaml (your defaults) ← NEW!This means:
cld --flag when needed# Test that config is loaded (check with a simple session)
cld
# Or test config loading directly
cd ~/.claude/plugins/marketplaces/cc-hooks-plugin
uv run utils/config_loader.py
Users can configure cc-hooks using command-line arguments which override config file and environment variables:
cld --audio=gtts # Google TTS (free, internet required)
cld --audio=elevenlabs # Premium TTS (requires API key)
cld --audio=prerecorded # Built-in audio files (default)
cld --language=id # Language (id, es, en, etc.)
cld --silent # Disable all audio
cld --silent=announcements # Keep sound effects, disable TTS
cld --silent=sound-effects # Keep TTS, disable sound effects
cld --ai=basic # Contextual Stop messages only
cld --ai=full # All contextual messages (Stop + PreToolUse)
cld --audio=gtts --language=id --ai=full
cld --audio=elevenlabs --ai=basic
cld --silent=announcements
Note: CLI arguments override config file and environment variables for that session only.
If the user requests testing, run these verification checks:
cd ~/.claude/plugins/marketplaces/cc-hooks-plugin
uv run utils/sound_player.py --list
uv run utils/sound_player.py sound_effect_cetek.mp3
cd ~/.claude/plugins/marketplaces/cc-hooks-plugin
uv run utils/tts_announcer.py --list
uv run utils/tts_announcer.py SessionStart
Check if server can start:
cd ~/.claude/plugins/marketplaces/cc-hooks-plugin
timeout 5 uv run server.py --port 12299 || echo "Server test completed"
Show the user how to start Claude with different configurations:
With config file (Recommended for most users):
# Just run claude directly - uses your config file settings
claude
# Or if you set up the cld alias
cld
With CLI flags (Power users - per-session overrides):
If default alias was created (e.g., cc):
# Use your default configuration
cc
# Override with different settings
cld --audio=gtts --language=id
cld --silent
Using cld directly with various configurations:
# Basic usage with prerecorded audio (default)
cld
# Google TTS in Indonesian
cld --audio=gtts --language=id
# ElevenLabs TTS with AI features
cld --audio=elevenlabs --ai=full
# Silent mode (no audio)
cld --silent
# Silent announcements only (keep sound effects)
cld --silent=announcements
Common issues and solutions:
uv run utils/sound_player.pyuv pip list | grep pygamelsof -i :12222tail -f ~/.claude/.cc-hooks/logs/*.logCC_HOOKS_PORT=12223 ./claude.shenv | grep -E "OPENROUTER_API_KEY|ELEVENLABS_API_KEY" | sed 's/=.*/=[SET]/' || echo "No API keys found"uv run utils/tts_announcer.py --provider gtts SessionStartsource ~/.zshrcIf you encounter issues that prevent setup from completing, or you've found a bug:
Report the issue on GitHub: https://github.com/husniadil/cc-hooks/issues/new
Include in your report:
echo $SHELL)~/.claude/.cc-hooks/logs/If the user provides an argument:
If no argument provided, run the full interactive setup wizard.
.env files in the plugin directory (they will be deleted on updates)