refactor: switch the whole project to English

talk is going to be published. Code comments, CLI output, error messages,
daemon log lines, MCP descriptions and results, test names and assertions,
README, spec, skill, build scripts and flake are now English. Only the
spoken announcement texts stay bilingual: the wrap result and the test
sentence are German or English depending on the detected language.

Language fallback is now configurable: `lang = "en" | "de"` (env
TALK_LANG, default en) is used when detection cannot tell (numbers, single
words, ties) and for talk's own announcements. langdetect.Detect takes the
fallback as an argument instead of hard-coding German. `talk setup` asks for
it; `talk doctor` and `talk status` show it.

Vocabulary pinned across packages so the process-boundary tests observe
stable strings: chain log lines ("chain: tier X skipped (not available)",
"falling back to the next tier", "spoken via X"), queue lines ("discarded:
quiet hours ... active", "replaced by toast", "max_age"), CLI notes
("speaking directly", "daemon started at", "no daemon", "nothing to cancel"),
status block with aligned English labels, MCP messages, origin guard 403.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
m3ta-chironandClaude Fable 5.1 committed 2026-10-24 11:15:35 +02:00
1 parent 4d30bd95ad
commit 85fa64cfe6
95 files changed
+4707 -4854

No files matched your search

+16 -20
View File
@@ -7,31 +7,27 @@ import (
"strings"
)
// MuteFileName ist der Name der Mute-Datei im Config-Verzeichnis (bindender
// Vertrag: „persistenten Mute-State toggeln (Datei mute im Config-Dir)").
// MuteFileName is the mute file's name inside the config directory.
const MuteFileName = "mute"
// ErrNoMutePath meldet einen Set-Versuch ohne konfigurierten Datei-Pfad
// (Config-Dir nicht bestimmbar — der Daemon deaktiviert dann Mute mit einer
// Start-Warnung statt zu scheitern).
var ErrNoMutePath = errors.New("mute: kein Datei-Pfad konfiguriert (Config-Dir nicht bestimmbar)")
// ErrNoMutePath reports a Set attempt without a configured file path (config
// directory unknown; the daemon then runs without mute and warns at start).
var ErrNoMutePath = errors.New("mute: no file path configured (config directory unknown)")
// MuteStore verwaltet den persistenten Mute-State als Datei im
// Config-Verzeichnis: Inhalt „true" = stumm, alles andere (oder keine Datei)
// = nicht stumm.
// MuteStore manages the persistent mute state as a file in the config
// directory: content "true" = muted, anything else (or no file) = not muted.
//
// Der Daemon liest die Datei bei jeder /speak-Anfrage neu — dadurch wirkt
// auch ein im Degraded Mode (Daemon tot) von der CLI direkt geschriebener
// State sofort, und der Zustand überlebt Daemon-Restarts.
// The daemon re-reads the file on every /speak request, so a state written
// by the CLI while no daemon runs takes effect immediately, and the state
// survives daemon restarts.
type MuteStore struct {
// Path ist der vollständige Pfad der Mute-Datei. Leer (kein Config-Dir
// bestimmbar): Muted() ist immer false, Set ein Fehler.
// Path is the mute file's full path. Empty (no config directory): Muted
// is always false and Set an error.
Path string
}
// Muted meldet den persistenten Mute-State. Eine fehlende oder unlesbare
// Datei heißt: nicht stumm (Fehlstart ohne Config-Dir wird nie „stumm aus
// Versehen").
// Muted reports the persistent mute state. A missing or unreadable file
// means not muted: a broken setup must never be "accidentally silent".
func (s MuteStore) Muted() bool {
if s.Path == "" {
return false
@@ -43,9 +39,9 @@ func (s MuteStore) Muted() bool {
return strings.TrimSpace(string(b)) == "true"
}
// Set schreibt den Mute-State atomar (temporäre Datei + Rename, damit
// Daemon und CLI nie eine halb geschriebene Datei lesen) und legt das
// Config-Verzeichnis bei Bedarf an.
// Set writes the mute state atomically (temp file + rename, so daemon and
// CLI never read a half-written file) and creates the config directory if
// needed.
func (s MuteStore) Set(muted bool) error {
if s.Path == "" {
return ErrNoMutePath