docs: talk-Skill mit Opt-in-Etikette, AGENTS-Snippet, README Installation/Release/Toast
skills/talk/SKILL.md: wann sprechen (nur auf Trigger in der Session oder Standing-Order in der AGENTS.md, session-sticky bis Widerruf), wann nicht, was eine gute Ansage ist (Status · nächster Schritt · wofür der Nutzer gebraucht wird; Beispiele gut/schlecht), Umgang mit muted/discarded/ --now/Prioritäten, Pitfalls. AGENTS-snippet.md: der Block für Projekt- AGENTS.md. README: Installation (Release-Asset mit Prüfsumme, Nix-Flake, go install), Skill-Abschnitt, Toast als echte Desktop-Benachrichtigung, Release-Ablauf und nix build in „Entwicklung". Spec-Nachtrag: Release ohne GoReleaser, Notifications ohne beeep. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
423377bade
commit
2e2bc27acf
4 files changed
+152
-3
No files matched your search
@@ -29,6 +29,26 @@ Runtime-Abhängigkeiten.
|
|||||||
Say-Flags (gelten auch für `talk "Text"`): `--wait`, `--now`, `--priority`,
|
Say-Flags (gelten auch für `talk "Text"`): `--wait`, `--now`, `--priority`,
|
||||||
`--voice`, `--lang`, `--provider`.
|
`--voice`, `--lang`, `--provider`.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
**Release-Binary** (Linux, macOS, Windows; amd64/arm64): von den
|
||||||
|
[Releases](https://code.m3ta.dev/m3tam3re/talk/releases) das passende
|
||||||
|
`talk_<os>_<arch>` laden, Prüfsumme gegen `checksums.txt` vergleichen, als
|
||||||
|
`talk` in den PATH legen. Keine weiteren Abhängigkeiten.
|
||||||
|
|
||||||
|
```console
|
||||||
|
curl -LO https://code.m3ta.dev/m3tam3re/talk/releases/latest/download/talk_linux_amd64
|
||||||
|
sha256sum -c --ignore-missing <(curl -sL https://code.m3ta.dev/m3tam3re/talk/releases/latest/download/checksums.txt)
|
||||||
|
install -m 755 talk_linux_amd64 ~/.local/bin/talk
|
||||||
|
```
|
||||||
|
|
||||||
|
**Nix** (Flake): `nix run git+https://code.m3ta.dev/m3tam3re/talk -- doctor`
|
||||||
|
oder in der Konfiguration `inputs.talk.url = "git+https://code.m3ta.dev/m3tam3re/talk";`
|
||||||
|
und `inputs.talk.packages.${system}.talk` bzw. `inputs.talk.overlays.default`.
|
||||||
|
Das Paket bringt espeak-ng (OS-Stimme) und libnotify (Toast) mit.
|
||||||
|
|
||||||
|
**Aus dem Quelltext:** `go install code.m3ta.dev/m3tam3re/talk/cmd/talk@latest`.
|
||||||
|
|
||||||
## Erste Schritte
|
## Erste Schritte
|
||||||
|
|
||||||
```console
|
```console
|
||||||
@@ -150,9 +170,10 @@ sind Opt-in wie Mute). In der Ruhezeit verfällt Audio, auch für high
|
|||||||
(Burst ist ein Rate-Recht, kein Ruhe-Recht):
|
(Burst ist ein Rate-Recht, kein Ruhe-Recht):
|
||||||
|
|
||||||
- `quiet_mode = "discard"` (Default): still verwerfen.
|
- `quiet_mode = "discard"` (Default): still verwerfen.
|
||||||
- `quiet_mode = "toast"`: Benachrichtigung statt Audio — derzeit eine
|
- `quiet_mode = "toast"`: Desktop-Benachrichtigung statt Audio — über die
|
||||||
Protokoll-Zeile über den Notification-Pfad (OS-Toast folgt mit der
|
Bordmittel des Systems (Linux `notify-send`, macOS Notification Center,
|
||||||
Notification-Anbindung).
|
Windows Toast), best effort: fehlt das Werkzeug, bleibt es bei der
|
||||||
|
Protokoll-Zeile, `talk doctor` zeigt es unter „Toast".
|
||||||
- `now:true` **bricht auch die Ruhezeit** (bewusster Ausbruch).
|
- `now:true` **bricht auch die Ruhezeit** (bewusster Ausbruch).
|
||||||
|
|
||||||
**Länge und Alter:** Zwei weitere Gesetze gegen das, was Prompts gern tun
|
**Länge und Alter:** Zwei weitere Gesetze gegen das, was Prompts gern tun
|
||||||
@@ -350,6 +371,18 @@ talk wrap --wait -- make test
|
|||||||
label = "Deployment" # Ansage-Label statt Befehls-Basisname (TALK_WRAP_LABEL)
|
label = "Deployment" # Ansage-Label statt Befehls-Basisname (TALK_WRAP_LABEL)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Für Agenten: Skill und Standing-Order
|
||||||
|
|
||||||
|
[`skills/talk/SKILL.md`](skills/talk/SKILL.md) ist die Etikette als
|
||||||
|
Skill-Artefakt: **striktes Opt-in** (Sprechen nur auf Aufforderung in der
|
||||||
|
Session oder Standing-Order in der AGENTS.md, session-sticky bis Widerruf),
|
||||||
|
Inhalt = Status · nächster Schritt · wofür der Nutzer gebraucht wird, nie
|
||||||
|
die Langantwort, `muted`/`discarded` respektieren. Der Drei-Zeilen-Block
|
||||||
|
für Projekt-AGENTS.md steht in
|
||||||
|
[`skills/talk/AGENTS-snippet.md`](skills/talk/AGENTS-snippet.md). Der
|
||||||
|
Daemon erzwingt Rate-Limit, Längen- und Alters-Grenze, Mute und Ruhezeit
|
||||||
|
unabhängig davon, was im Prompt steht.
|
||||||
|
|
||||||
## Entwicklung
|
## Entwicklung
|
||||||
|
|
||||||
```console
|
```console
|
||||||
@@ -357,11 +390,21 @@ go build ./... # bauen
|
|||||||
go test ./... # Tests
|
go test ./... # Tests
|
||||||
go vet ./... # statische Analyse
|
go vet ./... # statische Analyse
|
||||||
gofmt -l . # Formatierung prüfen (leerer Output = ok)
|
gofmt -l . # Formatierung prüfen (leerer Output = ok)
|
||||||
|
nix develop # devShell mit go, gopls, espeak-ng, libnotify
|
||||||
```
|
```
|
||||||
|
|
||||||
CI: `.gitea/workflows/test.yml` (Gitea Actions) läuft vet, gofmt-Check, Tests
|
CI: `.gitea/workflows/test.yml` (Gitea Actions) läuft vet, gofmt-Check, Tests
|
||||||
und Build bei jedem Push und Pull Request.
|
und Build bei jedem Push und Pull Request.
|
||||||
|
|
||||||
|
**Release:** Tag `v*` pushen → `.gitea/workflows/release.yml` testet, baut
|
||||||
|
mit `scripts/release.sh` die sechs Targets (statisch, `CGO_ENABLED=0`,
|
||||||
|
Version per ldflags) und legt ein Gitea-Release mit `talk_<os>_<arch>[.exe]`
|
||||||
|
und `checksums.txt` an. Lokal: `scripts/release.sh 1.2.3` → `dist/`. Bewusst
|
||||||
|
ohne GoReleaser: ein Shell-Skript über `go build` ist dasselbe Artefakt,
|
||||||
|
lokal wie in CI, ohne zusätzliches Werkzeug. `nix build .#talk` baut das
|
||||||
|
Nix-Paket (nach Änderungen an go.mod den `vendorHash` in flake.nix
|
||||||
|
nachziehen — `nix build` nennt den erwarteten Wert).
|
||||||
|
|
||||||
## Lizenz
|
## Lizenz
|
||||||
|
|
||||||
MIT — siehe [LICENSE](LICENSE).
|
MIT — siehe [LICENSE](LICENSE).
|
||||||
@@ -124,3 +124,10 @@ Diese Punkte ersetzen die entsprechenden Aussagen oben (Grilling-Stand
|
|||||||
nutzbar sein. Oberstes Kriterium ist Usability für Nicht-Terminal-
|
nutzbar sein. Oberstes Kriterium ist Usability für Nicht-Terminal-
|
||||||
Nutzer; die Bubble-Tea-TUI ist kein Selbstzweck — einfache, klare
|
Nutzer; die Bubble-Tea-TUI ist kein Selbstzweck — einfache, klare
|
||||||
Befehle (`doctor`, `setup`, `test`, `voices`) haben Vorrang.
|
Befehle (`doctor`, `setup`, `test`, `voices`) haben Vorrang.
|
||||||
|
- **Release ohne GoReleaser:** `scripts/release.sh` baut die sechs Targets
|
||||||
|
mit `go build`; `.gitea/workflows/release.yml` legt bei Tag `v*` das
|
||||||
|
Gitea-Release an. Asset-Vertrag unverändert (`talk_<os>_<arch>[.exe]` +
|
||||||
|
`checksums.txt`). `flake.nix` liefert Paket, App, Overlay und devShell.
|
||||||
|
- **Notifications ohne beeep:** Desktop-Toast über die Bordmittel des OS
|
||||||
|
(notify-send / osascript / PowerShell), exec-basiert wie osbuiltin;
|
||||||
|
zunächst nur für `quiet_mode = "toast"`. Cancel-Button: später.
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
# Standing-Order für talk (in die AGENTS.md des Projekts kopieren)
|
||||||
|
|
||||||
|
```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.
|
||||||
|
```
|
||||||
|
|
||||||
|
Ohne diesen Block (und ohne Aufforderung in der Session) spricht ein Agent
|
||||||
|
nicht — talk ist striktes Opt-in.
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
---
|
||||||
|
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."
|
||||||
|
compatibility: opencode, claude-code, codex
|
||||||
|
---
|
||||||
|
|
||||||
|
# talk — Voice-Notifications für Agenten
|
||||||
|
|
||||||
|
`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.
|
||||||
|
|
||||||
|
## When to Use — striktes Opt-in
|
||||||
|
|
||||||
|
Sprich **nur**, wenn eines davon gilt:
|
||||||
|
|
||||||
|
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
|
||||||
|
`AGENTS-snippet.md`).
|
||||||
|
|
||||||
|
Dann sprich bei: Abschluss langer Aufgaben (> ~30 s), Blockern, die den
|
||||||
|
Nutzer brauchen (Entscheidung, Freigabe, Passwort), Fehlern, die sofort
|
||||||
|
zählen.
|
||||||
|
|
||||||
|
## 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.
|
||||||
|
|
||||||
|
## Was eine gute Ansage ist
|
||||||
|
|
||||||
|
**Status · nächster Schritt · wofür der Nutzer gebraucht wird.** Nie die
|
||||||
|
Antwort selbst.
|
||||||
|
|
||||||
|
| gut | schlecht |
|
||||||
|
| --- | --- |
|
||||||
|
| „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) |
|
||||||
|
|
||||||
|
Sprache: in der Sprache des Nutzers schreiben; talk erkennt de/en selbst
|
||||||
|
(`--lang` erzwingt).
|
||||||
|
|
||||||
|
## 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
|
||||||
|
```
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
## Etikette gegenüber dem 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.
|
||||||
|
|
||||||
|
## 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.
|
||||||
Reference in new issue
Block a user