From voice
Voice mode for Claude Code — automatically reads assistant replies aloud via TTS, with German/English auto-detection and optional summarization for long responses. Trigger when the user mentions voice, vorlesen, sprachausgabe, TTS, "speak", "say it out loud", or asks about /voice-* commands.
How this skill is triggered — by the user, by Claude, or both
Slash command
/voice:voiceThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Dieses Skill steuert das Vorlese-Verhalten von Claude Code. Es ergänzt
Dieses Skill steuert das Vorlese-Verhalten von Claude Code. Es ergänzt
das eingebaute STT (Spracheingabe via /voice und Hold-Space) um
Sprachausgabe der Assistant-Antworten.
enabled=true)./voice-mode).OPENAI_API_KEY gesetzt), sonst Piper (lokal) oder espeak-ng als
letzter Fallback./voice-on — automatisches Vorlesen aktivieren/voice-off — automatisches Vorlesen deaktivieren/voice-status — aktueller Status, Engine, Config/voice-test [de|en|both] — Audio-Pipeline testen/voice-speak <text> — Text manuell vorlesen/voice-lang auto|de|en — Sprach-Modus setzen/voice-mode auto|full|summary — Vorlese-Modus (Default-Verhalten)/voice-full — Shortcut für /voice-mode full/voice-summary — Shortcut für /voice-mode summary/voice-auto — Shortcut für /voice-mode auto/voice-config show|path|edit — Konfiguration anzeigen / PfadEgal welcher Default-Modus aktiv ist, Phrasen in deiner Frage kippen einmalig den Modus für genau diese Antwort:
full (kein Summarize) — "lies (mir) das vollständig | komplett |
wörtlich | im Ganzen vor", "voll vorlesen", "ohne Kürzung", "nicht
zusammenfassen"; EN: "read it in full / verbatim", "no summary".summary (immer zusammenfassen) — "fass das zusammen", "Kurzfassung",
"in kurz", "in Kürze"; EN: "summarize", "short version", "TL;DR".full schlägt summary, wenn beides matcht.
Wenn der Nutzer eines der folgenden Themen erwähnt:
Bei Fragen zu Spracheingabe (STT, Mikrofon, Diktat): Hinweis, dass
Claude Code dafür das eingebaute /voice (Hold-Space-Recording) hat.
Liegt in ~/.config/corvin-voice/config.json. Wichtige Felder:
| Feld | Default | Beschreibung |
|---|---|---|
enabled | true | Auto-TTS an/aus |
engine | auto | auto, openai, piper, espeak-ng, say |
lang_mode | auto | auto (detect), de, en |
lang_default | de | Fallback wenn auto-detect unsicher |
summarize | true | Lange Antworten kürzen lassen |
summarize_threshold | 2000 | Zeichen-Schwelle für Summarize |
summarize_max_chars | 10000 | Ziel-Länge der Zusammenfassung (Soft-Limit) |
voice_mode | auto | auto (threshold-basiert), full (immer komplett), summary (immer zusammenfassen) |
voice_de / voice_en | (unset → female) | OpenAI-Voice-Name; leer ⇒ Default ist eine weibliche Stimme (nova für de, sonst shimmer). Zum Ändern z.B. echo/onyx/fable (männlich) setzen. |
speed | 1.0 | Sprechgeschwindigkeit (OpenAI) |
openai_model | tts-1 | tts-1 oder tts-1-hd |
anthropic_model | claude-haiku-4-5 | Modell für Summarizer |
Phase I: jede zero_config: true Persona (coder, research, browser,
inbox, homeassistant, assistant) inheritet automatisch
mcp__forge__forge_tool + mcp__forge__forge_promote und kriegt einen
eigenen FORGE_ROOT-Namespace:
~/.config/corvin-voice/forge/personas/<persona>/
Audit-Events tragen details.persona — voice-audit tail zeigt wer
was geforgte hat. Cross-Persona-Sharing via forge_promote --target shared.
Opt-out: "forge_enabled": false in der persona JSON.
Geforgte Tools haben jetzt vier Lebenszeit-Scopes mit automatischer
Detection. Lookup-Reihenfolge: task ▸ session ▸ project ▸ user
(höherer Scope shadowed niedrigeren).
| Scope | Pfad | Default wenn... | Auto-Cleanup |
|---|---|---|---|
task | /tmp/.corvinOS/tasks/<id>/forge/ | nur explizit (--scope task) | forge_cleanup tasks (TTL 1h) |
session | ~/.corvinOS/sessions/<channel-id>/forge/ | aus Bridge gestartet | forge_cleanup sessions (TTL 30d) |
project | <repo>/.corvinOS/forge/ | cwd in git-repo | nie auto |
user | ~/.corvinOS/global/forge/ | sonst | nie auto |
Detection-Reihenfolge:
CORVIN_FORCE_SCOPE env (explizit, z.B. tests)CORVIN_DEFAULT_SCOPE env (Persona-Default, vom Resolver gesetzt)CORVIN_CHANNEL_ID gesetzt → sessionPersona-Defaults (in personas/<name>.json als forge_default_scope):
| Persona | Default | Begründung |
|---|---|---|
| coder | project | Coding-Projekte sind kontextual klar |
| research / browser / assistant | session | kurzlebige Bridge-Konversation |
| inbox / homeassistant | user | global verwendet über mehrere Sessions |
| forge | (kein Default) | folgt Caller-Kontext |
Override pro Aufruf: forge_tool({"name":..., "scope":"task|session|project|user"}).
Promotion: forge_promote({"name":..., "to":"session|project|user"}) —
verschiebt Tool zwischen Scopes.
<repo>/.corvinOS/Alle vom Plugin erzeugten User-Daten leben unter einem einzigen Root.
Default ist <repo>/.corvinOS/, override via CORVIN_HOME env.
.corvinOS/
├── voice/ config.json, sessions/, vault/, memory/, schedule.json, earcons/
├── cowork/ personas/, mcp-cache/
├── global/ forge/ (audit.jsonl + user-scope tools)
├── sessions/ <bridge>:<chat-id>/forge/ (session-scope tools)
└── forge/ tools/ (project-scope tools — wenn cwd in git-repo)
Audit-Chain ist unified — alle Bridge- und Forge-Events landen in
<root>/global/forge/audit.jsonl, nicht pro Scope. Damit ist
voice-audit verify weiter ein einziger Aufruf für alles.
python3 mit openai-SDK oder piper-Binary oder espeak-ngaplay (ALSA), paplay, ffplay, mpv, play oder mpg123OPENAI_API_KEY als Env-VariableANTHROPIC_API_KEY (sonst Fallback auf naive
Truncation — funktioniert weiter, einfach weniger elegant)Optional sister plugin operator/forge/ exposes a runtime tool factory:
the forge persona (in operator/cowork/personas/forge.json) lets a
chat register schema-bound Python/bash tools at runtime via the
mcp__forge__forge_tool MCP call. Generated tools execute in a bwrap
sandbox with no network, fresh /tmp, and POSIX rlimits — they never
inherit the owner's --dangerously-skip-permissions privileges,
because the forge persona itself runs with permission_mode: "default"
and explicitly disallows Bash, Edit, Write, MultiEdit.
Two ways to land in the forge persona:
chat_profiles[<chat>].persona = "forge" in the
channel's settings.jsonA persona JSON may carry allowed_forged_tools: ["csv.*", "stats.median"]
to gate which forged tools that persona is permitted to consume (the
forge persona itself can always forge new ones; consumer personas only
see what they're allowed). The cowork resolver expands the list into
the FORGE_ALLOWED_TOOLS env var via the {{ALLOWED_FORGED_TOOLS}}
template variable, and the forge MCP server filters both tools/list
and tools/call against it. Glob semantics are fnmatch — csv.*
matches csv.count and csv.median but NOT csv_count (the dot is
literal in fnmatch, not a regex wildcard). Absence of the field means
no restriction (legacy behaviour).
A blocked call is rejected with acl.persona_denied in the audit log,
not silently filtered.
Bridge events (login, whitelist deny, PIN failure, channel rate-limit,
message received, persona routed, tool use) plus all forge events land
in a single sha256 hash-chained file at
~/.config/corvin-voice/forge/audit.jsonl — override path via the
VOICE_AUDIT_PATH env var, or move the whole forge workspace via
FORGE_ROOT. Each record carries prev_hash and hash; tampering
with any field breaks the chain at that record's line. Cross-process
writes (voice adapter + forge MCP server are separate processes) are
serialized via filesystem flock, so concurrent events stay linked.
CLI (the script operator/voice/scripts/voice_audit.py is the
voice-audit command — symlink it into $PATH for the short form):
voice-audit verify (or python3 operator/voice/scripts/voice_audit.py verify)
— exit 0 on intact chain, exit 1 on integrity violation (lines +
issue type printed on stderr), exit 2 on IO error.voice-audit tail --limit 50 (or
python3 operator/voice/scripts/voice_audit.py tail --limit 50) —
prints the most recent N entries with timestamp, severity,
event_type, channel, chat_key, user, persona.When the forge plugin isn't installed, bridges/shared/audit.py is a
silent no-op — the bridge still runs, just without audit persistence.
The operator's safety envelope lives in ~/.config/corvin-voice/forge/policy.json
(override the workspace via FORGE_ROOT). The file controls:
| Field | What |
|---|---|
default_budget | Per-call default (CPU/wall/output/artifact bytes) |
max_budget | Per-call hard ceiling — meta.budget is clamped here |
forbidden_imports | AST-checked at forge-time (default: socket, subprocess, ctypes, multiprocessing) |
forbidden_tool_names | Glob deny-list at forge-time AND call-time |
allowed_namespaces | Optional positive allowlist for tool name prefixes |
rate_limit | Per-tool token-bucket (default + per-tool overrides) |
circuit_breaker | CLOSED/OPEN/HALF_OPEN thresholds + reset timeout |
audit.hash_chain | Whether new audit records carry prev_hash/hash |
Edits to policy.json hot-reload on the next tools/call —
operator can tighten the envelope without restart, matching the rest
of the voice repo's reload convention. Live circuit-breaker thresholds
and rate-limit capacities are updated in place; in-flight failure
counters are preserved. A malformed edit is rejected with a
policy.reload_failed event and the previous policy stays in effect.
Guides collaborative design exploration before implementation: explores context, asks clarifying questions, proposes approaches, and writes a design doc for user approval.
Creates structured, bite-sized implementation plans from specs or requirements before writing code. Useful for breaking down multi-step tasks into testable steps with file structure and task boundaries.
Synthesizes the current conversation into a structured spec (PRD) and publishes it to the project issue tracker with a ready-for-agent label, without interviewing the user.
npx claudepluginhub corvinlabs/corvinos --plugin voice