Problem
Sessions often work best with eyes closed (pre-sleep, low vision, face-down phone/laptop). Today the product is TUI-first: phase labels and progress bars carry the pacing. Audio exists (afplay system sounds, mute toggle) but is thin for eyes-closed use — easy to lose the inhale/exhale boundary without looking, and easy to react late when the only cue is the phase-change itself.
Scope
In:
- An opt-in eyes-closed / audio-first mode for the CLI (flag and/or preset hook — exact surface TBD in implementation).
- Stronger phase cues so inhale ↔ exhale is unmistakable by ear: distinct inhale vs exhale sounds, and/or opt-in spoken IN/OUT via macOS
say (same non-blocking Popen pattern as afplay / caffeinate).
- An anticipatory pre-beep shortly before the actual IN/OUT cue (lead time TBD; short enough not to feel like a third phase). Pre-beep = “get ready”; phase cue = “now.” That split is the load-bearing UX for eyes-closed pacing.
- Keep the same safety envelope (no retention, cycle ≥ 8s, continuous in–out). Pre-beeps must not introduce a hold, pause phase, or any retention prompt.
- Document how to enable it;
q / Ctrl+C / finally terminal restore unchanged.
Out:
- Session-end “reward” chime — #36.
- Rewriting the TUI into a second visual chrome.
- Night quieter defaults (#18) and night dimmer TUI (#17) — coordinate volume defaults but don’t merge scope.
- iPhone app (#34) — separate product; this issue is CLI-only.
- Non-macOS TTS stacks as a hard requirement (Linux/Windows remain soft-fail / community).
Proposal (starting point)
- Opt-in flag (name TBD, e.g.
--eyes-closed / --audio-first) that assumes the user is not watching the screen.
- Optionally suppress or simplify visual urgency (dimmer labels, less progress chrome) while keeping enough state for sighted debugging.
- Cue stack per phase boundary: pre-beep → (brief gap) → distinct IN or OUT cue (sound and/or
say); non-blocking; must not stretch wall-clock phase timing into an unintended hold.
- Interact cleanly with
s mute and --no-sound (pre-beep and phase cues both silenced).
Acceptance
Constraints
Single-file, stdlib, macOS primary; no threading; audio must not block the render loop.
Related
- Session completion chime: #36
- iPhone idea: #34
- Night quieter audio: #18
- Night dimmer TUI: #17
- Spec safety: no retention, cycle ≥ 8s, graceful exit (
breathe-cli-spec.md §2).
Problem
Sessions often work best with eyes closed (pre-sleep, low vision, face-down phone/laptop). Today the product is TUI-first: phase labels and progress bars carry the pacing. Audio exists (
afplaysystem sounds, mute toggle) but is thin for eyes-closed use — easy to lose the inhale/exhale boundary without looking, and easy to react late when the only cue is the phase-change itself.Scope
In:
say(same non-blockingPopenpattern asafplay/caffeinate).q/ Ctrl+C /finallyterminal restore unchanged.Out:
Proposal (starting point)
--eyes-closed/--audio-first) that assumes the user is not watching the screen.say); non-blocking; must not stretch wall-clock phase timing into an unintended hold.smute and--no-sound(pre-beep and phase cues both silenced).Acceptance
--presetbehaviour unchanged when not enabled.--no-soundsilence pre-beep and phase cues; spoken path (if shipped) respects mute.Constraints
Single-file, stdlib, macOS primary; no threading; audio must not block the render loop.
Related
breathe-cli-spec.md§2).