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
@@ -1,13 +1,13 @@
|
||||
# Standing-Order für talk (in die AGENTS.md des Projekts kopieren)
|
||||
# Standing order for talk (copy into the project's AGENTS.md)
|
||||
|
||||
```markdown
|
||||
## Voice notifications (talk)
|
||||
Sprich per `talk "<1–2 Sätze>"`, wenn eine Aufgabe länger als ~30 s lief und
|
||||
fertig ist, wenn du blockiert bist und mich brauchst (dann `talk --now`),
|
||||
oder wenn etwas fehlgeschlagen ist. Inhalt: Status, nächster Schritt, wofür
|
||||
du mich brauchst — nie die Antwort selbst. `muted` und `discarded` sind
|
||||
meine Entscheidung: respektieren, nicht umgehen.
|
||||
Speak via `talk "<1-2 sentences>"` when a task ran longer than ~30 s and is
|
||||
done, when you are blocked and need me (then `talk --now`), or when something
|
||||
failed. Content: status, next step, what you need me for; never the answer
|
||||
itself. `muted` and `discarded` are my decision: respect them, do not work
|
||||
around them.
|
||||
```
|
||||
|
||||
Ohne diesen Block (und ohne Aufforderung in der Session) spricht ein Agent
|
||||
nicht — talk ist striktes Opt-in.
|
||||
Without this block (and without a request in the session) an agent does not
|
||||
speak; talk is strict opt-in.
|
||||
+53
-56
@@ -1,86 +1,83 @@
|
||||
---
|
||||
name: talk
|
||||
description: "Use when the user has asked for voice notifications — explicitly in this session or as a standing order in the project's AGENTS.md — and (1) a long-running task finishes (build, tests, deploy, data job), (2) the agent is blocked and needs the user's decision or approval, (3) something failed that the user should know about now. Triggers: talk, say it, sag Bescheid, melde dich, notify me, let me know when done, voice, Ansage. Strict opt-in: never speak without the user's trigger or standing order."
|
||||
description: "Use when the user has asked for voice notifications, either explicitly in this session or as a standing order in the project's AGENTS.md, and (1) a long-running task finishes (build, tests, deploy, data job), (2) the agent is blocked and needs the user's decision or approval, or (3) something failed that the user should know about now. Triggers: talk, say it, sag Bescheid, melde dich, notify me, let me know when done, voice, Ansage. Strict opt-in: never speak without the user's trigger or standing order."
|
||||
compatibility: opencode, claude-code, codex
|
||||
---
|
||||
|
||||
# talk — Voice-Notifications für Agenten
|
||||
# talk: voice notifications for agents
|
||||
|
||||
`talk "Build fertig"` spricht eine kurze Ansage über den lokalen talk-Daemon
|
||||
(Queue, Rate-Limit, Mute, Ruhezeiten). Ein Binary, startet den Daemon beim
|
||||
ersten Aufruf selbst. Nichts zu installieren außer `talk` im PATH.
|
||||
`talk "Build done"` speaks a short announcement through the local talk daemon
|
||||
(queue, rate limit, mute, quiet hours). One binary; it starts the daemon
|
||||
itself on the first call. Nothing to install except `talk` in the PATH.
|
||||
|
||||
## When to Use — striktes Opt-in
|
||||
## When to Use: strict opt-in
|
||||
|
||||
Sprich **nur**, wenn eines davon gilt:
|
||||
Speak **only** if one of these holds:
|
||||
|
||||
1. Der Nutzer hat es in dieser Session verlangt („sag Bescheid, wenn der
|
||||
Build durch ist", „melde dich, wenn du mich brauchst"). Das gilt dann
|
||||
**session-sticky bis Widerruf** — nicht bei jeder Antwort neu fragen.
|
||||
2. Die AGENTS.md des Projekts enthält eine Standing-Order (siehe
|
||||
1. The user asked for it in this session ("let me know when the build is
|
||||
through", "tell me when you need me"). That then applies
|
||||
**session-sticky until revoked**; do not ask again with every reply.
|
||||
2. The project's AGENTS.md contains a standing order (see
|
||||
`AGENTS-snippet.md`).
|
||||
|
||||
Dann sprich bei: Abschluss langer Aufgaben (> ~30 s), Blockern, die den
|
||||
Nutzer brauchen (Entscheidung, Freigabe, Passwort), Fehlern, die sofort
|
||||
zählen.
|
||||
Then speak on: completion of long tasks (> ~30 s), blockers that need the
|
||||
user (decision, approval, password), failures that matter right now.
|
||||
|
||||
## When NOT to Use
|
||||
|
||||
- Ohne Trigger oder Standing-Order. Nie „von sich aus plappern".
|
||||
- Für kurze Antworten, Zwischenstände, jede Tool-Ausgabe.
|
||||
- Um die Langantwort vorzulesen. Der Daemon kürzt bei 400 Zeichen —
|
||||
aber Ziel sind 1–2 Sätze.
|
||||
- Wenn `talk` `muted` oder `discarded: quiet_hours` zurückgibt: Das ist
|
||||
die Entscheidung des Nutzers. Nicht umgehen, nicht `--now` nachschieben.
|
||||
- Without a trigger or standing order. Never chatter on your own.
|
||||
- For short replies, intermediate status, or any tool output.
|
||||
- To read the long answer aloud. The daemon truncates at 400 characters,
|
||||
but the goal is 1 to 2 sentences.
|
||||
- When `talk` returns `muted` or `discarded: quiet_hours`: that is the
|
||||
user's decision. Do not work around it, do not follow up with `--now`.
|
||||
|
||||
## Was eine gute Ansage ist
|
||||
## What makes a good announcement
|
||||
|
||||
**Status · nächster Schritt · wofür der Nutzer gebraucht wird.** Nie die
|
||||
Antwort selbst.
|
||||
**Status, next step, what the user is needed for.** Never the answer
|
||||
itself.
|
||||
|
||||
| gut | schlecht |
|
||||
| good | bad |
|
||||
| --- | --- |
|
||||
| „Tests grün, PR ist bereit zum Review." | „Ich habe die Tests ausgeführt und alle 247 Tests sind erfolgreich durchgelaufen, außerdem habe ich …" |
|
||||
| „Deploy fehlgeschlagen, Code 1. Ich brauche deine Entscheidung zur Migration." | „Fehler." |
|
||||
| „Brauche dein sudo-Passwort im Terminal." | (stumm warten) |
|
||||
| "Tests green, PR is ready for review." | "I ran the tests and all 247 tests passed successfully, and I also ..." |
|
||||
| "Deploy failed, code 1. I need your decision on the migration." | "Error." |
|
||||
| "I need your sudo password in the terminal." | (waiting silently) |
|
||||
|
||||
Sprache: in der Sprache des Nutzers schreiben; talk erkennt de/en selbst
|
||||
(`--lang` erzwingt).
|
||||
Language: write in the user's language. talk speaks English by default and
|
||||
German when the configured language is `de` or when detection says so
|
||||
(`--lang` forces it).
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
talk "Tests grün, PR bereit zum Review." # non-blocking, Item-ID auf stdout
|
||||
talk --wait "Deploy fertig." # erst zurückkehren, wenn gesprochen
|
||||
talk --priority high "Build rot, Code 2." # darf das Rate-Limit verletzen
|
||||
talk --now "Ich brauche dich: Freigabe im Terminal." # vor die Queue, auch in der Ruhezeit — nur für Blocker
|
||||
echo "Import fertig" | talk # stdin geht auch
|
||||
talk wrap -- make test # Befehl ausführen, Erfolg/Misserfolg + Dauer ansagen
|
||||
talk "Tests green, PR ready for review." # non-blocking, item ID on stdout
|
||||
talk --wait "Deploy finished." # return only once spoken
|
||||
talk --priority high "Build red, code 2." # may break the rate limit
|
||||
talk --now "I need you: approval in the terminal." # jumps the queue, also in quiet hours; blockers only
|
||||
echo "Import finished" | talk # stdin works too
|
||||
talk wrap -- make test # run a command, announce success/failure and duration
|
||||
```
|
||||
|
||||
Antworten auf stdout: eine Item-ID (angenommen), `muted`, oder
|
||||
`discarded: rate_limit|quiet_hours`. Exit 0 in allen drei Fällen — ein
|
||||
Verwurf ist kein Fehler. Exit ≠ 0 nur bei echten Problemen (kein Text,
|
||||
ungültige Flags, Config kaputt); dann nicht wiederholen, sondern dem
|
||||
Nutzer sagen.
|
||||
Replies on stdout: an item ID (accepted), `muted`, or
|
||||
`discarded: rate_limit|quiet_hours`. Exit 0 in all three cases; a discard
|
||||
is not an error. Non-zero exit only on real problems (no text, invalid
|
||||
flags, broken config); then do not retry, tell the user instead.
|
||||
|
||||
## Etikette gegenüber dem Daemon
|
||||
## Etiquette towards the daemon
|
||||
|
||||
- **Rate-Limit** (Default 1 Ansage / 30 s): `normal` parkt, `low` wird
|
||||
verworfen, `high` darf durch. Nicht alles ist `high`.
|
||||
- **`--now`** ist für Blocker, die den Nutzer brauchen — nicht für
|
||||
„fertig". Es bricht aus Ruhezeit und Rate-Limit aus; das ist eine
|
||||
bewusste Störung.
|
||||
- **Mute und Ruhezeit** sind Nutzerentscheidungen. Respektieren, nicht
|
||||
umgehen. Der Daemon erzwingt sie ohnehin.
|
||||
- Mehrere Dinge gleichzeitig? **Eine** Ansage, die zusammenfasst — nicht
|
||||
fünf.
|
||||
- **Rate limit** (default 1 announcement / 30 s): `normal` waits, `low` is
|
||||
discarded, `high` may pass. Not everything is `high`.
|
||||
- **`--now`** is for blockers that need the user, not for "done". It breaks
|
||||
out of quiet hours and the rate limit; that is a deliberate interruption.
|
||||
- **Mute and quiet hours** are user decisions. Respect them, do not work
|
||||
around them. The daemon enforces them anyway.
|
||||
- Several things at once? **One** announcement that summarises, not five.
|
||||
|
||||
## Pitfalls
|
||||
|
||||
- `talk` nicht gefunden → nicht improvisieren (kein `say`, `espeak`,
|
||||
`notify-send`). Dem Nutzer sagen, dass talk fehlt.
|
||||
- Kein Ton beim Nutzer → `talk doctor` schlagen vorschlagen; nicht selbst
|
||||
an Keys oder Config drehen.
|
||||
- Keys kommen aus `TALK_ELEVENLABS_KEY` / `TALK_OPENAI_KEY` (Env). Nie in
|
||||
Dateien schreiben, nie in Ansagen oder Logs ausgeben.
|
||||
- `talk` not found: do not improvise (no `say`, `espeak`, `notify-send`).
|
||||
Tell the user that talk is missing.
|
||||
- No sound on the user's side: suggest `talk doctor`; do not fiddle with
|
||||
keys or config yourself.
|
||||
- Keys come from `TALK_ELEVENLABS_KEY` / `TALK_OPENAI_KEY` (env). Never
|
||||
write them to files, never print them in announcements or logs.
|
||||
Reference in new issue
Block a user