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:
1 parent
4d30bd95ad
commit
85fa64cfe6
95 files changed
+4707
-4854
No files matched your search
+19
-19
@@ -6,28 +6,28 @@ import (
|
||||
"io"
|
||||
)
|
||||
|
||||
// Sink-Namen (Teil des öffentlichen Vertrags; Spec: audio.sink = "oto"|"null").
|
||||
// Sink names (part of the public contract; spec: audio.sink = "oto"|"null").
|
||||
const (
|
||||
NameOto = "oto"
|
||||
NameNull = "null"
|
||||
)
|
||||
|
||||
// Sink gibt Audio-Bytes wieder. Die Bytes stammen aus Provider.Synthesize;
|
||||
// oto versteht RIFF/WAVE (PCM — das Lieferformat von osbuiltin) und MP3
|
||||
// (das Lieferformat der Cloud-Provider ElevenLabs/OpenAI/Edge).
|
||||
// Sink plays audio bytes. The bytes come from Provider.Synthesize; oto
|
||||
// understands RIFF/WAVE (PCM, the delivery format of osbuiltin) and MP3
|
||||
// (the delivery format of the cloud providers ElevenLabs/OpenAI/Edge).
|
||||
type Sink interface {
|
||||
// Play spielt die Daten blockierend ab (bis zum Ende oder bis ctx
|
||||
// abgebrochen wird).
|
||||
// Play plays the data and blocks until the end or until ctx is
|
||||
// cancelled.
|
||||
Play(ctx context.Context, data []byte) error
|
||||
|
||||
// Name liefert den Sink-Namen (audio.sink-Konfiguration).
|
||||
// Name returns the sink name (audio.sink configuration).
|
||||
Name() string
|
||||
}
|
||||
|
||||
// NewSink liefert den Sink zum konfigurierten Namen ("oto" oder "null").
|
||||
// log ist ein optionaler Log-Output — die CLI übergibt ihr stderr, über den
|
||||
// der null-Sink seine Verwurf-Zeile schreibt (nil = still verwerfen); der
|
||||
// oto-Sink braucht kein Log. Unbekannte Namen sind ein klarer Fehler.
|
||||
// NewSink returns the sink for the configured name ("oto" or "null"). log
|
||||
// is an optional log output: the CLI passes its stderr so the null sink can
|
||||
// write its discard line (nil = discard silently); the oto sink needs no
|
||||
// log. Unknown names are a clear error.
|
||||
func NewSink(name string, log io.Writer) (Sink, error) {
|
||||
switch name {
|
||||
case NameOto:
|
||||
@@ -35,24 +35,24 @@ func NewSink(name string, log io.Writer) (Sink, error) {
|
||||
case NameNull:
|
||||
return NullSink{W: log}, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unbekannter audio sink %q (erlaubt: %q, %q)", name, NameOto, NameNull)
|
||||
return nil, fmt.Errorf("unknown audio sink %q (allowed: %q, %q)", name, NameOto, NameNull)
|
||||
}
|
||||
}
|
||||
|
||||
// NullSink verwirft jede Ansage ohne Ton — für CI, Server und Tests. Wurde
|
||||
// ein W gesetzt (NewSink reicht dafür den Log-Output der CLI durch), loggt
|
||||
// Play eine Zeile darüber, damit „läuft ohne Ton durch" sichtbar bleibt.
|
||||
// NullSink discards every announcement without sound; for CI, servers and
|
||||
// tests. If W is set (NewSink passes the CLI's log output), Play logs one
|
||||
// line about it so "runs through silently" stays visible.
|
||||
type NullSink struct {
|
||||
W io.Writer // optionaler Log-Output; nil = still verwerfen
|
||||
W io.Writer // optional log output; nil = discard silently
|
||||
}
|
||||
|
||||
// Name implementiert Sink.
|
||||
// Name implements Sink.
|
||||
func (NullSink) Name() string { return NameNull }
|
||||
|
||||
// Play implementiert Sink: verwirft die Daten.
|
||||
// Play implements Sink: discards the data.
|
||||
func (n NullSink) Play(ctx context.Context, data []byte) error {
|
||||
if n.W != nil {
|
||||
fmt.Fprintf(n.W, "audio: %d Bytes verworfen (null sink)\n", len(data))
|
||||
fmt.Fprintf(n.W, "audio: %d bytes discarded (null sink)\n", len(data))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in new issue
Block a user