You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CLAUDE.md
+4-2Lines changed: 4 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -26,6 +26,7 @@ Repo-local notes for Claude and Codex.
26
26
- Prompt text is redacted and held in memory only. Restart recovery persists compact request intent, turn identity, transcript location, and the Git baseline in `.turns.json`.
27
27
- Spoken claims are checked against actual local test commands and outcomes found in Claude/Codex transcripts. Diagnostics shows intent and verification metadata, never prompt or transcript bodies.
28
28
- Attributable Git diffs are translated into behavioral facts. `.timeline.json` keeps only compact outcomes for session-arc narration and `./voice recap`; it stores no prompt, reply, or source text.
29
+
- Optional Voice Inbox mode persists prepared replies in `.voice-inbox.json` without speaking them. `I'm back` drains them into one local return briefing.
29
30
- Condensing is local-only through Ollama, with `none` as the deterministic fallback.
30
31
- Replies over `max_direct_chars` (default 400) get condensed by the configured summarizer; on failure it speaks the first sentence with a short note.
31
32
- Markdown-table replies send the raw full response to the summarizer first, so the voice gets a conversational table summary instead of row-by-row noise. If summarization fails, a mostly-table reply becomes a spoken invite to look.
@@ -37,13 +38,14 @@ Repo-local notes for Claude and Codex.
37
38
- Quiet hours (`quiet_hours` in config) accept speech but keep silent, logged as `quiet_skip`.
38
39
- Empty `last_assistant_message` falls back to parsing `transcript_path`.
39
40
- Playback via `afplay` honoring `rate` and `volume` config. The daemon exits after `idle_exit_s` idle.
40
-
- Optional ducking targets Spotify and Browser/YouTube independently. Browser/YouTube is controlled by the companion Chromium extension through `GET /browser/duck`.
41
+
- Optional ducking targets Spotify and Browser/YouTube independently. Browser/YouTube is controlled by the companion Chromium extension through `GET /browser/duck`. Spotify writes `.media-duck-lease.json` before fading so startup and the watchdog can restore interrupted playback state.
41
42
- Errors land in `.voice.log` as `event: "error"`. The log self-caps around 500 lines.
42
43
- Repo earcons, intent cues, build-result sonification, adaptive brevity, pronunciation dictionaries, and privacy redaction are local defaults. A repo can override speech using `.ltbv/pronounce.json`.
43
44
- When multiple projects finish together, the daemon can speak one radio bulletin naming each project. Backchannel commands are available through `/backchannel` and the CLI.
Copy file name to clipboardExpand all lines: build-packet.html
+1Lines changed: 1 addition & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -618,6 +618,7 @@ <h1>let-there-be-voice</h1>
618
618
<divclass="filter-row"><b>Config</b><span><code>GET/POST /config</code> backed by <code>config.json</code> in the repo root, hot-applied, no restart. Daemon constants become defaults.</span><spanclass="tag blue">Core</span></div>
619
619
<divclass="filter-row"><b>Voices</b><span><code>GET /voices</code> lists the catalog; <code>POST /audition</code> speaks one fixed sentence in a chosen voice. Voice states cached so switching stays cheap.</span><spanclass="tag blue">Core</span></div>
620
620
<divclass="filter-row"><b>Ducking</b><span>Optional Spotify fade via <code>osascript</code> plus Browser YouTube page-volume ducking through the companion Chromium extension. Each target saves its current level, fades to <code>duck_target_volume</code> before playback, and restores in <code>_finish()</code>. No global volume, no tab mute, no pause/resume.</span><spanclass="tag blue">Core</span></div>
621
+
<divclass="filter-row"><b>Voice inbox</b><span>Optional away mode prepares and persists agent replies without playback. <code>POST /inbox/return</code> drains the queue into one concise return briefing. Spotify ducking writes a restoration lease before fading and repairs interrupted state at startup or through the watchdog.</span><spanclass="tag">Shipped</span></div>
621
622
<divclass="filter-row"><b>Data</b><span><code>GET /log/tail</code> returns recent log entries for the histogram plus the last raw/cleaned pair for the inspector.</span><spanclass="tag blue">Core</span></div>
622
623
<divclass="filter-row"><b>Restart</b><span><code>POST /restart</code> (2026-07-10): daemon acks, logs <code>restart_requested</code>, spawns a detached shell that sleeps <spanclass="num">300ms</span> then execs a fresh <code>daemon.py</code>, and the handler calls <code>os._exit(0)</code>. Picks up any code or config change without a manual kill. Controller button polls <code>/health</code> and reloads once it answers.</span><spanclass="tag blue">Core</span></div>
623
624
<divclass="filter-row"><b>Rules</b><span>House skin: dark grey, radius 0, Inter + Share Tech Mono, compact. No framework, stdlib-only daemon side. The controller is a remote, not a brain. (Amended: controller v2 added an SSE live layer, see Locked Decisions.)</span><spanclass="tag red">Hard</span></div>
0 commit comments