CLI Reference
This page documents the current command surface exposed by claudio.
claudio [flags]
claudio [command]
Global flags:
| Flag | Meaning |
|---|---|
--config string |
Load a specific config file for this invocation. |
--volume string |
Override volume for this invocation. Must be 0.0 through 1.0. |
--soundpack string |
Override the active soundpack for this invocation. |
--silent |
Process the hook without audio playback. |
--version, -v |
Print version. |
--help, -h |
Print help. |
--volume, --soundpack, and --silent affect hook processing only. They are
never written to config.json.
claudio
With no subcommand, Claudio reads a hook JSON payload from stdin and processes it.
echo '{"session_id":"test","cwd":".","hook_event_name":"UserPromptSubmit","prompt":"hello"}' | claudio
Required payload fields are:
session_idcwdhook_event_name
Tool events can also include tool_name, tool_input, and tool_response.
A payload that is not valid JSON or lacks a required field exits with code 1.
claudio install
Installs hooks for Claude Code, Codex CLI, Gemini CLI, Qwen Code, GitHub Copilot CLI, or Command Code, or the OpenCode plugin.
claudio install [flags]
Flags:
| Flag | Default | Meaning |
|---|---|---|
--agent, -a |
auto |
auto, all, claude, codex, gemini, qwen, copilot, commandcode, or opencode. |
--scope, -s |
global |
global or project. |
--dry-run, -d |
false | Show what would happen without writing. |
--print, -p |
false | Print the mode, scope, target agent, and settings path. |
--quiet, -q |
false | Suppress progress messages. |
--agent auto installs for every agent that shows evidence of being present:
its executable is on PATH, its settings file or settings directory exists, or
Claudio hooks are already installed there. It fails if no agent is found.
--agent all targets all five agents whether or not they are installed.
Settings file locations for each agent and scope are listed on the
home page. Claude Code honors CLAUDE_CONFIG_DIR,
Codex honors CODEX_HOME, and GitHub Copilot CLI honors COPILOT_HOME.
Examples:
claudio install
claudio install --agent all --scope global
claudio install --agent claude --scope global
claudio install --agent codex --scope project
claudio install --agent gemini --scope global
claudio install --agent qwen --scope global
claudio install --agent copilot --scope global
claudio install --agent codex --scope global --dry-run
Codex users must trust the hook with /hooks after installation.
claudio uninstall
Removes Claudio hooks for Claude Code, Codex CLI, Gemini CLI, Qwen Code, GitHub Copilot CLI, or Command Code, or the OpenCode plugin.
claudio uninstall [flags]
Flags match install:
| Flag | Default | Meaning |
|---|---|---|
--agent, -a |
auto |
auto, all, claude, codex, gemini, qwen, copilot, commandcode, or opencode. |
--scope, -s |
global |
global or project. |
--dry-run, -d |
false | Show what would be removed. |
--print, -p |
false | Print the mode, scope, target agent, and settings path. |
--quiet, -q |
false | Suppress progress messages. |
Only Claudio’s own hook entries are removed. Other hooks in the same settings file are preserved.
claudio install-commands
Installs optional command artifacts for asking an agent to control Claudio.
claudio install-commands --agent claude
claudio install-commands --agent codex
claudio install-commands --agent antigravity
| Flag | Default | Meaning |
|---|---|---|
--agent, -a |
claude |
claude, codex, or antigravity. |
| Agent | Artifact |
|---|---|
claude |
~/.claude/commands/claudio.md |
codex |
$HOME/.agents/skills/claudio/SKILL.md |
antigravity |
~/.gemini/config/skills/claudio/SKILL.md and ~/.gemini/antigravity-cli/skills/claudio.md |
When CLAUDE_CONFIG_DIR is set, the Claude Code command goes to
$CLAUDE_CONFIG_DIR/commands/claudio.md instead.
If an artifact already exists and its content is not something Claudio wrote, the command refuses to touch it and exits with an error. Move or delete your customized file first.
claudio uninstall-commands
Removes artifacts created by install-commands. Takes the same --agent flag,
also defaulting to claude.
claudio uninstall-commands --agent claude
claudio uninstall-commands --agent codex
claudio uninstall-commands --agent antigravity
claudio status
Prints the effective configuration after file and environment overrides.
claudio status
Example output:
claudio status
config file: /home/me/.config/claudio/config.json
enabled: true
volume: 0.50 (from config.json)
soundpack: embedded:linux.json
log level: warn
audio backend: auto -> oto (available; playback not tested)
file logging: enabled (/home/me/.cache/claudio/logs/claudio.log)
tracking: enabled (/home/me/.cache/claudio/sounds.db)
forwarding: off
version: 1.15.0
The audio backend line shows what auto resolves to and whether that backend
is available. It does not play a sound.
When forwarding is set, the forwarding line reads
on, to <address> (token set) or (no token). The token is never printed.
That machine plays nothing itself, so its backend and tracking lines describe
settings it does not use.
When audio is disabled, the enabled line includes the literal word MUTED.
--config selects the file to report on. The transient --volume,
--soundpack, and --silent flags are not applied.
claudio volume
Gets or sets the persisted volume in config.json.
claudio volume
claudio volume 0.25
With no argument it prints the volume hooks will use, including a
CLAUDIO_VOLUME override if one is set. With an argument it writes the value
to the config file.
claudio volume, mute, unmute, and soundpack use write to the file named
by --config, or else to the user config path (see
Configuration). If that file does not exist yet,
they create it from the effective configuration, so the new file is complete.
Environment variable CLAUDIO_VOLUME and global flag --volume still override
the persisted value at runtime.
claudio mute And claudio unmute
Persistently toggles enabled in config.json.
claudio mute
claudio unmute
Environment variable CLAUDIO_ENABLED still overrides the persisted value at
runtime.
claudio listen
Plays sound events that arrive from somewhere else. Run it where the speakers
are; whatever sees the event can be another machine, a container or a cloud
session. Events arrive over HTTP, as OpenTelemetry logs, or with --stdin on
a pipe.
claudio listen
claudio listen --addr 0.0.0.0:19190 --max-age 10s
<command that prints events> | claudio listen --stdin
| Flag | Meaning |
|---|---|
--addr string |
Address to listen on. Default 127.0.0.1:19190. |
--token string |
Token every request must carry. |
--token-file string |
File holding that token. Surrounding whitespace is ignored. |
--max-age duration |
Drop events older than this. Default 30s; 0 plays every event. |
--stdin |
Read events from stdin instead of serving HTTP. Cannot be combined with --addr, --token or --token-file. |
The sound is chosen on the listening machine, from its soundpack, volume and
mute setting, and is recorded in its tracking database when tracking is on.
The global --volume, --soundpack, --silent and --config flags apply.
A Claudio hook on another machine sends its events when that machine has
forward.url set; see Forwarding.
Over HTTP
Without --stdin it prints listening on http://<address> and runs until
interrupted.
Without a token only a loopback address is accepted, because anyone who can
reach the port can play sounds. Prefer --token-file to --token: other
users of the machine can read a command line. The two cannot be combined, and
a token file that is missing or empty is an error.
Send one JSON event per POST /events:
curl -X POST http://127.0.0.1:19190/events \
-H "Authorization: Bearer <token>" \
-d '{"source":"claude","category":"completion","hint":"agent-complete","operation":"stop"}'
| Field | Meaning |
|---|---|
category |
Required. One of loading, success, error, interactive, completion, system, silent. |
hint |
Most specific sound name, tried first (git-commit-success). |
command, subcommand |
The command the event is about (git, commit). Leave both out for an event that is not about a command. |
phase |
start, success, error or unknown, for an event about a command. |
original_tool |
The tool that ran the command (Bash). |
operation |
Generic name tried after the specific ones (tool-complete, stop). |
source |
What produced the event (claude, github). Logged; not used to pick the sound. |
id |
The event’s id at its source. Logged. |
time |
RFC 3339 time of the event, used by --max-age. An event without one is always played. |
session |
Groups events in the tracking database. |
attributes |
Free-form object for source-specific values. Not used to pick the sound. |
These are the names the fallback chains are built from, so an event picks the same sound a local hook with the same values would.
| Status | Meaning |
|---|---|
202 |
Accepted, or dropped as stale (the body says which). The sound plays after the response. |
400 |
Not a JSON event, or no known category. |
401 |
Missing or wrong token. |
413 |
Body over 64 KiB. |
503 |
Eight sounds are already playing. |
Request bodies are never logged or echoed.
As OpenTelemetry Logs
The same web server is an OpenTelemetry (OTLP) logs receiver at
POST /v1/logs, so anything that already exports telemetry can be heard
without installing Claudio where it runs. Only the JSON encoding over HTTP is
accepted; gzip is fine. The token, --max-age and the limit of eight sounds
apply as they do to /events.
To hear Claude Code through its own telemetry, start it with:
export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_LOGS_EXPORTER=otlp
export OTEL_EXPORTER_OTLP_PROTOCOL=http/json
export OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:19190
export OTEL_LOGS_EXPORT_INTERVAL=1000
# only if the listener has a token:
export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer <token>"
Claude Code sends records in batches, every five seconds unless
OTEL_LOGS_EXPORT_INTERVAL says otherwise, so these sounds trail the action
by up to that long. Its records map onto the events its hooks produce, so one
soundpack serves both:
| Claude Code record | Plays as |
|---|---|
user_prompt |
The prompt sound (interactive/message-sent). |
tool_decision, accepted |
The tool’s start sound (loading/bash-start). |
tool_decision, rejected |
error/permission-denied. |
tool_result |
The tool’s success or error sound (success/bash-success). |
compaction |
system/post-compact. |
subagent_completed |
completion/subagent-complete. |
api_retries_exhausted |
error/stop-failure. |
| Anything else | Nothing. One session start sends dozens of hook_registered and plugin_loaded records. |
Telemetry says less than a hook does. A shell command is only “Bash” unless Claude Code is told to log tool details, and nothing reports a turn ending or Claude waiting for permission. Where Claudio’s hooks can be installed they are the better source; do not enable both for one session or every sound plays twice.
Records from any other service map by name and outcome:
- The sound hint is the record’s
eventName, else itsevent.nameattribute, else a body that is a single identifier such asdeploy.finished. A record with none of those is a log line and is skipped. - The category is
errorwhen asuccessattribute is false or the severity is ERROR or higher,successwhensuccessis true, andsystemotherwise. - The source is the resource’s
service.name.
So a record named deploy.finished with success true looks for
success/deploy-finished.wav and falls back to the category sound.
| Status | Meaning |
|---|---|
200 |
The export was received. Stale records and records past the sound limit are dropped, not reported. |
400 |
Not an OTLP/JSON logs export. |
401 |
Missing or wrong token. |
413 |
Export over 4 MiB, before or after decompression. |
415 |
Not JSON. Set the exporter’s protocol to http/json. |
On A Pipe
With --stdin no web server is started. Claudio reads stdin, one JSON event
per line in the same format as above, and plays each until stdin ends. What
carries the events to the pipe is up to you: an SSH session, a relay’s
client, a file being followed.
- Blank lines are skipped, so keep-alive lines from a streaming client are harmless.
- A line that is not an event, has no known
category, or is longer than 64 KiB is logged and skipped. The stream continues. --max-ageand the limit of eight sounds at once apply as they do over HTTP.- When stdin ends, the command exits
0. When reading it fails, the command exits1. Claudio does not reconnect: run it under a loop or a service if the source can drop.
There is no token on this path. Whoever can write to the source can play sounds, so protect the source.
claudio soundpack
Manages soundpacks.
claudio soundpack [command]
soundpack init
Creates a JSON soundpack template with all known mapping keys.
claudio soundpack init <name> [flags]
Flags:
| Flag | Default | Meaning |
|---|---|---|
--dir string |
. |
Output directory. |
--from-platform |
false | Pre-fill mappings from the current embedded platform soundpack. |
Examples:
claudio soundpack init my-pack
claudio soundpack init my-pack --dir ./soundpacks
claudio soundpack init my-pack --from-platform
soundpack list
Lists embedded, XDG, and config-discovered soundpacks with their type, sound count, and path.
claudio soundpack list
The embedded packs are windows, wsl, darwin, and linux.
soundpack validate
Validates a JSON file or directory soundpack and prints coverage.
claudio soundpack validate <path>
Validation checks JSON shape, missing referenced files, known-key coverage, and
supported extensions. WAV, MP3, and AIFF are supported. Broken references and
unsafe paths (absolute, or containing ..) cause a non-zero exit. Empty
mappings are informational.
soundpack audit
Decodes every sound in a JSON file or directory soundpack and reports what a listener would notice.
claudio soundpack audit <path> [flags]
Flags:
| Flag | Default | Meaning |
|---|---|---|
--target-lufs float |
-18 |
Loudness every sound should have, in LUFS. |
--tolerance float |
1 |
Allowed distance from the target, in LU. |
--peak-ceiling float |
-1 |
Highest allowed true peak, in dBTP. |
--max-duration cat=dur,... |
see below | Override the duration limit of one or more categories. |
--strict |
false | Exit non-zero on warnings as well as errors. |
--json |
false | Print the full report as JSON. |
Default duration limits: loading 1s, success 1.5s, default 1.5s,
error 2s, interactive 2.5s, completion 3s, system 6s.
Warnings: too-long, too-loud, too-quiet, peak-over-ceiling,
clipping, leading-silence, trailing-silence. Errors: undecodable,
silent. Notes, which never fail an audit: peak-limited, duplicate,
sample-rate, unreferenced.
For a JSON pack, audit covers every file the manifest references, regardless
of extension, and any unreferenced supported audio in the same directories.
Mapped content the playback decoders cannot read, such as Ogg Vorbis, is an
undecodable error and fails the audit even without --strict. See
Auditing And Mastering for what each
column and rule means.
soundpack master
Writes a mastered copy of a soundpack that passes soundpack audit.
claudio soundpack master <path> --out <dir> [flags]
Flags:
| Flag | Default | Meaning |
|---|---|---|
--out string |
required | Directory to write the mastered pack into. It must not be the source pack’s directory. |
--target-lufs float |
-18 |
Loudness to master to. |
--tolerance float |
1 |
Loudness tolerance in LU; also controls how close peak limiting brings a sound to the target. |
--peak-ceiling float |
-1 |
True-peak ceiling, in dBTP. |
--max-duration cat=dur,... |
as audit | Override duration limits. |
--json |
false | Print what was done to each sound as JSON. |
Each sound is trimmed of silence, cut to its category’s duration limit with a
fade, and brought to the loudness target. Output is 48 kHz 16-bit WAV. A
directory pack keeps its layout; a JSON pack becomes <out>/soundpack.json
with its sounds under <out>/sounds/. The source is never modified.
soundpack synth
Renders original sounds from a JSON recipe.
claudio soundpack synth <recipe.json> --out <dir>
Writes <out>/synth/<sound>.wav for every sound in the recipe and
<out>/soundpack.json, a JSON soundpack mapping the recipe’s keys to those
files. Master the result to get a pack at a consistent level. The recipe
format is described in
Synthesizing Sounds. A recipe with a
setting synth does not know, a mapping to a sound that is not defined, or a
sound no mapping uses is rejected.
soundpack search
Lists published soundpacks.
claudio soundpack search [words...] [--json]
Queries GitHub for repositories tagged with the topic claudio-soundpack,
most starred first, and prints each with the soundpack add command that
installs it. Extra words narrow the search. This is the only command that
contacts a server on its own. Set GITHUB_TOKEN to raise GitHub’s rate
limit.
soundpack install
Copies a local JSON file or directory into the XDG data directory and updates
soundpack_paths.
claudio soundpack install <path> [flags]
Flags:
| Flag | Default | Meaning |
|---|---|---|
--default |
false | Set the installed soundpack as default_soundpack. |
--skip-validate |
false | Skip validation before copying. |
JSON files and their referenced audio files install under
<XDG_DATA_HOME>/claudio/soundpacks/<name>/, with the installed manifest at
soundpack.json.
Directories install to <XDG_DATA_HOME>/claudio/soundpacks/<name>/.
soundpack use
Switches the active soundpack by name.
claudio soundpack use <name>
claudio soundpack use windows
This sets default_soundpack. The name must appear in
claudio soundpack list.
soundpack add
Clones a git-backed soundpack into
<XDG data home>/claudio/soundpack-repos/<name>/ and adds it to
soundpack_paths. Requires git on PATH.
claudio soundpack add <git-url> [flags]
Flags:
| Flag | Default | Meaning |
|---|---|---|
--name string |
derived from URL | Install name. |
--ref string |
default branch | Branch, tag, or commit to check out. |
--subdir string |
repository root | Directory or JSON file within the repository. |
--default |
false | Set as active soundpack. |
--skip-validate |
false | Skip validation. |
--replace |
false | Replace an existing managed git soundpack with the same name. |
GitHub shorthand is accepted:
claudio soundpack add gh:owner/repo --name my-pack --default
soundpack update
Updates managed git soundpacks.
claudio soundpack update <name>
claudio soundpack update --all
Flags:
| Flag | Meaning |
|---|---|
--all |
Update every managed git soundpack. |
--force |
Discard local clone changes before updating. |
soundpack remove
Removes a managed git soundpack.
claudio soundpack remove <name>
Flags:
| Flag | Meaning |
|---|---|
--keep-files |
Remove registry/config entries but leave the clone on disk. |
--force |
Remove registry/config entries even if clone deletion fails. |
soundpack status
Shows managed git soundpack status.
claudio soundpack status
claudio soundpack status <name>
claudio analyze
Reads the tracking database. Both subcommands fail if tracking is disabled.
claudio analyze usage [flags]
claudio analyze missing [flags]
missing lists fallback-chain candidates that were requested but not found,
most requested first. usage lists the sounds that actually played.
Shared flags:
| Flag | Default | Meaning |
|---|---|---|
--days int |
7 |
Number of days to analyze. 0 means all time. |
--preset string |
empty | today, yesterday, this-week, last-week, this-month, last-month, or all-time. Overrides --days. |
--tool string |
empty | Filter by tool name. |
--category string |
empty | loading, success, error, interactive, completion, or system. Other values are rejected. |
--limit int |
20 |
Maximum rows. |
usage also supports:
| Flag | Meaning |
|---|---|
--show-summary |
Print summary statistics. |
--show-chains |
Print chain-type stats and average fallback depth. |
Examples:
claudio analyze usage --show-summary --show-chains
claudio analyze usage --tool Bash --preset today
claudio analyze missing --preset all-time --limit 50
claudio analyze missing --category error
claudio completion
Generates a shell completion script for Bash, Fish, PowerShell, or Zsh.
claudio completion bash
claudio completion fish
claudio completion powershell
claudio completion zsh
Exit Codes
Subcommand failures return exit code 1.
In hook mode, Claudio exits 1 before playback for an unparseable payload, an
out-of-range CLAUDIO_VOLUME or --volume, and an audio backend that cannot
be resolved. A config file is never fatal: a missing or empty one means
defaults, and one that cannot be parsed or fails validation prints a single
Warning: line and Claudio continues with defaults. Once the payload is accepted, missing sounds and
playback errors are only logged.