Progress Bar Is Not an API: Separating CLI UI from Events
Co-op Translator v0.20.0 separates its Rich CLI UI from a structured event stream, freeing integrations from parsing fragile console text.
Co-op Translator v0.20.0 addresses a subtle but common CLI trap: human-friendly output like a progress bar can quietly become an accidental integration contract. The fix was to split one internal state into two distinct surfaces — a Rich-powered UI meant for people, and a structured event stream (run_started, stage_progress, file_completed, run_completed) meant for machines. This means CLI display text can keep improving without silently breaking anything that depends on it.
Central to this design is the split between stage_label and stage_key: labels are free to change for clarity, while keys remain the stable values integrations should rely on. The same event contract is exposed consistently across surfaces — as NDJSON in the CLI, via a progress_callback in the Python API, and as payload data in MCP tool results — so one internal state powers multiple interfaces without divergence.
For a product like Localizeflow, this turns fragile text-scraping into durable, structured facts that can be written straight to a database, while logs remain useful context rather than the source of truth. It's a useful reference for engineers designing CLIs that need to serve both human users and programmatic consumers without one breaking the other.