Breathe CLI — Paced Resonance Breathing

Terminal app for vagal tone training. Single-file Python, no dependencies. Grounded in CHF clinical trials (Bernardi, Vaschillo, Lehrer). macOS.

View the Project on GitHub marekkowalczyk/breathe-cli

Breathing Pattern DSL — Version Plan

Status: Draft — not yet approved for implementation Date: 2026-06-07 Parent: TODO #14 · Spec: breathing-dsl-spec.md

Strategy: Python v1 freeze, Go v2

Python (breathe.py) = v1.x — feature-frozen, bugfixes only. The cardiac-safe resonance breathing pacer. Stays on PyPI. The code and tests serve as the living spec / reference implementation for the Go rewrite.

Go = v2.x — the universal breathing pacer with the DSL. Same repo (marekkowalczyk/breathe-cli). Ships as a single compiled binary.

Why Go:

Why same repo:

What the Python code provides for the Go rewrite:

Repo layout (after transition)

breathe-cli/
  cmd/breathe/          # Go main package
  internal/
    parser/             # DSL parser + well-formedness validation
    safety/             # safety rules (per-mode)
    config/             # session config, presets
    tui/                # terminal rendering, ANSI, state machine
    audio/              # platform audio (macOS/Windows/Linux)
  go.mod
  go.sum
  README.md
  LICENSE
  v1-python/            # archived Python v1
    breathe.py          # reference implementation (frozen)
    test_breathe.py     # reference tests
  dev/
    breathe-cli-spec.md
    breathing-dsl-spec.md
    breathing-dsl-versions.md  # this file
    TODO.md
    ...

Versions

v1.x — Python (current, feature-frozen)

Status: Stable. Bugfixes only. No new features.

The existing app: cardiac-safe resonance breathing pacer, single-file Python, stdlib only. Remains on PyPI as breathe-cli.


v2.0 — Go scaffold + parity with Python v1

User-visible change: Same app, now a Go binary. All v1 features work identically.

Work:

Why first: Feature parity before new features. If the Go version can’t pass all 25 manual acceptance tests, nothing else matters.

Release: v2.0.0 on GitHub Releases. Homebrew tap. Python v1 archived to v1-python/.


v2.1 — Internal four-phase model

User-visible change: None.

Work:

Why here: Foundation for everything that follows. Trivial in Go since we’re already building the data structures fresh.

Note: in practice this may be folded into v2.0 since we’re building from scratch anyway. Kept as a separate logical step for clarity.


v2.2 — --pattern flag and parser

User-visible change: New --pattern "4-0-6-0" flag. Holds must still be zero.

Work:

Why separate: Proves the parser in isolation. No state machine changes yet.


v2.3 — Hold phases in the state machine and TUI

User-visible change: --pattern "4-7-8-0" works. Hold phases are displayed and paced.

Work:

Risk: Largest single step. Consider sub-steps:


v2.4 — Named presets for new patterns

User-visible change: --preset box, --preset relaxation, etc.

Work:

Good candidate for the Show HN update (TODO #16).


v2.5 — Repetition counts

User-visible change: 10(4-0-6-0) runs exactly 10 cycles.

Work:


v2.6 — Chaining

User-visible change: 5(4-0-6-0)+10(5-5-5-5) runs two segments in sequence.

Work:


v2.7 — Phase modifiers (airway, depth)

User-visible change: 4m-0-6n-0 shows “IN (mouth)” / “OUT (nose)” in the TUI.

Work:

Lowest priority. DSL is fully functional without modifiers.


Dependency graph

v1.x  Python (frozen, bugfixes only)

v2.0  Go scaffold + feature parity with Python v1
  |
  v
v2.1  Internal four-phase model (may fold into v2.0)
  |
  v
v2.2  --pattern flag + parser
  |
  v
v2.3  Hold phases in state machine + TUI    <-- first new feature
  |
  v
v2.4  Named presets (box, relaxation, ...)   <-- Show HN moment
  |
  v
v2.5  Repetition counts  10(...)
  |
  v
v2.6  Chaining  ... + ...
  |
  v
v2.7  Modifiers  4m, 6n, 5nd

Open decisions before starting

  1. Go experience. Does the author have Go fluency, or is this also a learning project? Affects timeline estimates.
  2. Mode flag vs. implicit mode. Is --mode cardiac a flag, or is it implicit from the preset/pattern? Decide before v2.3.
  3. Hold TUI design. Colour, label, bar behaviour during holds. Decide before v2.3.
  4. Audio cues for holds. Silence, ticks, or a distinct tone. Decide before v2.3.
  5. PyPI deprecation. When v2.0 ships, does breathe-cli on PyPI get a deprecation notice pointing to the Go binary? Or does it stay as-is for Python users who prefer it?
  6. Homebrew formula. New formula for the Go binary, or update the existing tap?
  7. Linux support. Go makes Linux trivial. Add it in v2.0 or defer? Audio is the main question (PulseAudio? ALSA? No sound on Linux by default?).