Contributing
Relevant source files
The following files were used as context for generating this wiki page:
This document provides a guide for contributing to the voice-elevenlabs Claude Code plugin. The project's structure is based on declarative Markdown files for commands, skills, and agents, with shell scripts for automated hooks. Contributions typically involve adding or modifying these components to extend the voice capabilities powered by the ElevenLabs API.
The core architecture revolves around user-invoked commands that provide instructions to Claude, and event-driven hooks that trigger voice notifications automatically. The plugin leverages the claude-voice-notifications CLI tool and direct calls to the ElevenLabs API to generate speech.
Core Concepts
The plugin is composed of four main types of components: Commands, Agents, Skills, and Hooks. Understanding these is key to extending the plugin's functionality.
Plugin Architecture Overview
The following diagram illustrates the high-level interaction between the user, Claude Code, the plugin's components, and the ElevenLabs API.
Adding a New Command
Commands are user-invoked actions like /speak or /create-voice. To add a new command, create a new Markdown file in the commands/ directory.
Command File Structure
Each command file must contain two parts:
- YAML Frontmatter: A block at the top enclosed in
---that defines the command's metadata. - Markdown Body: A description and instructions for how Claude should execute the command.
---
description: A brief description of what the command does.
allowed-tools: ["Bash", "Read"] # Tools Claude is permitted to use.
---
# Command Title
Instructions for Claude on how to execute the command, including API calls, argument parsing, and expected output.
Argument: $ARGUMENTS.argument_name
Sources: commands/create-voice.md:1-4, commands/transcribe.md:1-4, commands/dialogue.md:29-30
Command Execution Flow
The diagram below shows the process from a user entering a command to the audio output.
Example: The /speak Command
The /speak command is implemented in commands/speak.md. It instructs Claude to use claude-voice-notifications or curl to the ElevenLabs API to convert text to speech. It also documents the available emotion tags.
Available Emotion Tags:
| Tag | Description |
|---|---|
[excited] | Enthusiastic |
[whispers] | Quiet, intimate |
[laughs] / [laughing] | Natural laughter |
[sighs] | Thoughtful pause |
[angry] | Intense |
[sad] | Melancholic |
[nervous] | Hesitant |
[shouting] | Loud |
[sarcastically] | Dry humor |
Sources: README.md:47-58, commands/speak.md:11-19
Adding a New Hook
Hooks provide automatic voice notifications for events within Claude Code, such as when a task is finished.
Hook Configuration
Hooks are defined in hooks/hooks.json. Each hook object specifies an event, a type (always "command"), and the command to run (a shell script).
{
"hooks": [
{
"event": "Stop",
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/scripts/stop-voice.sh",
"description": "Announce '[project]: done' when Claude finishes"
},
{
"event": "SubagentStop",
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/scripts/subagent-voice.sh",
"description": "Announce '[project]: [task]' when subagent completes"
},
{
"event": "Notification",
"type": "command",
"command": "claude-voice-notifications",
"description": "Announce when Claude needs permission or input"
}
]
}
Sources: hooks/hooks.json:1-18
Hook Execution Flow
The following sequence diagram shows how a SubagentStop event triggers a voice notification.
The script hooks/scripts/subagent-voice.sh is responsible for parsing the context provided by Claude (like the current working directory and transcript path) to create a concise, context-aware message. For example, it extracts the project name from the directory path.
Sources: hooks/scripts/subagent-voice.sh:6-11, hooks/scripts/stop-voice.sh:6-10
Adding Agents and Skills
While commands are direct actions, agents and skills define behaviors and capabilities for Claude.
- Agents: Define a persona for Claude, such as the
voice-assistant. The fileagents/voice-assistant.mdinstructs the agent to provide concise spoken summaries of its responses. - Skills: Define when and how Claude should use a capability. The
skills/voice-responses.mdskill tells Claude to activate text-to-speech when a user asks for a verbal explanation or uses phrases like "read aloud".
To contribute a new agent or skill, create a Markdown file in the agents/ or skills/ directory, respectively, following the existing format. These files guide Claude's behavior rather than executing a direct command.
Sources: agents/voice-assistant.md, skills/voice-responses.md
Voice Configuration and Management
Contributors may need to interact with voice settings. The /voice-config and /voices commands provide this functionality.
Available Voices
The plugin includes a set of default voices. New commands or features should ideally work with the configured voice.
| Voice | ID | Style |
|---|---|---|
| George | JBFqnCBsd6RMkjVDRZzb | Natural male (default) |
| Adam | pNInz6obpgDQGcFmaJgB | Deep male |
| Rachel | 21m00Tcm4TlvDq8ikWAM | Natural female |
| Domi | AZnzlk1XvdvUeBnXmlld | Young female |
Sources: README.md:81-88, commands/voices.md:9-16
The default voice can be changed by setting the ELEVENLABS_VOICE_ID environment variable. The /voice-config set-voice [voice_id] command is designed to manage this setting.
Sources: README.md:90, commands/voice-config.md:13-14
Creating a Demo
After adding a new feature, it is helpful to create a demonstration script. The demo-script.md file provides a template for recording a short video that showcases the functionality, including setup, a step-by-step script, and post-recording tips. This is a good practice for pull requests.
Sources: demo-script.md