Changelog¶
All notable changes to pomban are documented in this file.
Format follows Keep a Changelog; the project adheres to Semantic Versioning.
Unreleased¶
0.3.0 — 2026-06-12¶
Minor release. Onboarding + planning UX polish: the help overlay now explains how each screen works, sprint creation gets a real modal, and new users get a one-shot walkthrough on first launch plus a rotating tip overlay on subsequent launches.
Added¶
- Context-aware
?help. EveryAppScreenmay declare aHELP_INTROstring explaining the screen's mental model (columns, modes, the gist of how to use it). The help overlay renders that intro above a "Keymap" heading and the per-screen bindings list; the title changes topomban — <Screen>so it's clear which surface you're reading help for. Dashboard, Kanban, Stats, History, Today, Projects, and Sprints all ship intros. SprintCreateModal— structured 4-field sprint creation (name, pomodoro target, duration days, goal). Replaces the inline-input parsing on the Sprints screen and the implicit 14-day shell that the Projects screen'ssbinding used to create.Ctrl+SorEnteron any field submits;Esccancels. The engine helperPombanEngine.create_sprint_for_projectgainspomodoro_targetandgoalkwargs to match.- First-launch
WelcomeModal+ rotatingStartupTipModal. On the first launch after the DB has at least one project, a full-page walkthrough modal explains the platform model and the main keymap. On every subsequent launch a short tip overlay rotates through 12 tips. Both gated by the new[ui].show_startup_tipsconfig flag (defaulttrue); set it tofalseto disable both surfaces.
Changed¶
- The
sbinding on the Projects screen now opens the newSprintCreateModalinstead of synchronously creating a 14-day shell sprint. Thenbinding on the Sprints screen does the same.
0.2.1 — 2026-06-12¶
Patch release. Two interaction bugs that made v0.2.0 hard to use on a fresh DB. v0.2.0 has been yanked from PyPI in favour of this release.
Fixed¶
- Project picker swallowed Enter. Submitting a task with no
@projectopened the project picker modal, but pressing Enter dismissed it withNoneinstead of selecting the highlighted row — the task was silently lost. The modal now listens forListView.Selected(which is what Textual'sListViewactually emits on Enter), focuses the list on mount, and seeds the highlighted index at 0 so the first keystroke isn't wasted. - Kanban task selection didn't work and the focused card never
highlighted. The docked Input grabbed initial focus so
j/k/h/lwere typed into it instead of moving the cursor; and_paint_cursor()ran beforebody.mount(TaskCard...)had landed in the DOM so even after focus was fixed the first paint missed every card. The Input now stays out of the focus chain until you pressn///g, and the cursor paints viacall_after_refreshso the newly-mounted cards are visible to it.
0.2.0 — 2026-06-12¶
The "personal productivity platform" release. Tasks now live inside sprints inside projects, every screen carries that context, and the focus loop grows blocker capture, session notes, a Today digest, and quiet-hours-aware notifications. Exports gain CSV / JSON / grouped markdown for downstream review.
Changed¶
- Renamed package from
pomodorotopomban. PyPI distribution, CLI binary, Python package, and XDG directories all migrate to thepombanname. On first launch, a one-shot migration shim renames the legacy~/.local/share/pomodoro/,~/.local/state/pomodoro/, and~/.config/pomodoro/directories (and thepomodoro.db/pomodoro.logfiles inside them) to theirpombanequivalents. No-op when the new paths already exist. - Schema v10 —
tasks.project_idbecomes NOT NULL (legacy rows migrate to an auto-seeded "Inbox" project);tasks.sprint_id/sprints.project_idFKs added; "one active sprint per project" enforced in code (see ADR-0005). - README + docs site reframed around the platform model (Plan / Focus / Review / Integrate) rather than "Pomodoro TUI".
- Notifications route through a single
notifications.notify(...)funnel that consults the working-hours gate before firing desktop popup / sound channels.
Added¶
- Project → sprint → task hierarchy as the platform's planning
model. Inline
@project/!sprint/#tag/~Nsyntax for keyboard-driven assignment (ADR-0005). - Context header on every screen — active project + sprint chip
- quiet-state chip, refreshed on every tick.
- Dashboard + Kanban sprint panels — current sprint progress pinned to the planning screens.
PombanEnginefacade (core/engine.py) owns timer + session orchestration end-to-end.app.pyloses ~200 lines of lifecycle plumbing (ADR-0006).FirstRunModal— empty-DB launches walk through creating the first project so the hierarchy is never empty.SprintRunnerScreen(Shift+R) — overlay with the current sprint goal pinned regardless of which screen is active.SprintCompleteScreen— fires whenpomodoro_targetis crossed; closes the sprint with a retro field.- Inline
sbinding on the Projects screen creates and activates a sprint for the focused project in one keystroke. - Blocker capture (
b) — log a one-line blocker against the live focus session without breaking the timer. - Session notes — session-end modal field surfaces inline on the History screen.
- Today digest (
7) — daily recap screen with sessions, top tasks, interruptions, and blocker list bound to the7digit. - Per-tag analytics panel on the Stats screen (
3), powered byminutes_per_tag. - Exports —
pomban export --format csv|json|markdown. The grouped-markdown format buckets sessions by project → sprint → task.pomban sprint export …for per-sprint reports. - Working-hours quiet —
[breaks].working_hours_start/working_hours_end("HH:MM") suppress desktop popup + sound outside the window; the in-TUI bell still fires; header chip reflects the current quiet state (ADR-0004). ROADMAP.mdandRELEASE_PLAN.mdat the repo root — forward-looking phase plan and the mechanics of cutting a release (tag-driven viarelease.yml).CHANGELOG.md,CONTRIBUTING.md,SECURITY.md, andCLAUDE.mdat the repo root — keep-a-changelog history, contributor onboarding, vulnerability-disclosure policy, and internal conventions spec.- mkdocs-material documentation site scaffolded under
docs/site/with index, install, quickstart, troubleshooting, ADR index, and changelog pages alongside the existing user-guide / keybindings / configuration / development pages. Auto-deployed via.github/workflows/docs.ymlon every push tomainthat touches the docs. - Architecture Decision Records under
docs/adr/. Seeded with three retrospective ADRs (stack choice, single-SQLite-connection policy, layered-screen architecture); v0.2.0 adds three more — ADR-0004 (working-hours quiet), ADR-0005 (PM hierarchy), and ADR-0006 (PombanEnginefacade). scripts/capture_screenshots.py— Textual pilot harness that drivesPomodoroAppagainst an in-memory DB and emits hero SVGs for the dashboard, kanban, and stats screens.docs/demo.tape— vhs script for an animated README hero. Render withvhs docs/demo.tape(requiresvhs/ffmpeg/ttyd)..pre-commit-config.yamlwith ruff, mypy, and the standard pre-commit-hooks (end-of-file-fixer, trailing-whitespace, yaml, large-files).requirements/base.in+requirements/dev.inmirroring thepyproject.tomldependency tables for pip-tools workflows.docsandmypyextras under[project.optional-dependencies]..github/workflows/release.ymlanddocs.yml— tag-driven PyPI publish via OIDC trusted publishing plus CHANGELOG-extracted GitHub Release notes; conditional docs deploy to GitHub Pages.
0.1.0 — 2026-06-11¶
Initial pre-release of the pomban dashboard TUI. Captures every
feature shipped on main to date.
Added¶
- Pomodoro timer engine (
core/timer_engine.py) with focus, short-break, long-break, lunch-pause, and idle phases; configurable cycle counts; auto-advance toggle;extend,skip, andrestorestate transitions. - Dashboard screen — timer, focused-task chip, stats strip,
task list, inline
#tag/@project/!sprint/~Ntask syntax. - Kanban board (
2) with priorities, due dates (overdue render red), per-column WIP limits ([kanban]config), board search (/), bulk visual-mode actions (vthenSpace/c/d/Shift+H,L), and a card detail screen (i). - Stats screen (
3) — daily / weekly / monthly bucket views, top tasks, interruption stats. - History screen (
4) — every session, paged, with planned vs. actual durations. - Projects screen (
5) and Sprints screen (6) — full CRUD, archiving, completion states; tasks released back to backlog on sprint delete. - Resume prompt — quit mid-focus, get a "resume? y/n" overlay on next launch.
- Lunch break —
Shift+Ltriggers a long pause anywhere; the session-end modal suggests it inside a configurable[breaks].lunch_window_*. - Presets —
[[preset]]blocks switchable viap; classic 25/5, deep-work 50/10, sprint 15/3 ship as defaults. - Themes —
nord,gruvbox,dracula,catppuccin-mocha,tokyo-night. Cycle witht; persisted toconfig.toml. - Auto-advance (
Shift+T) — skip the end-of-phase modal and roll straight into the next phase, classic-Pomodoro style. - Hooks —
[hooks].on_focus_start/on_focus_end/on_break_start/on_break_endshell commands invoked withPOMODORO_PHASEandPOMODORO_TASK_TITLEenv vars. - In-process plugins — Python entry points discovered at startup; exceptions are sandboxed and never crash the app.
git_syncplugin — commits the SQLite library on exit so it can sync across devices via a personal git remote.- btop-style panel hotkeys —
widgets/panel.py+AppScreen.action_focus_panegive each pane a highlighted-letter selector (Dashboard:iTimer,aTasks). - Structured logging via
core/log.py— file-only writes to~/.local/state/pomban/pomban.log; never touches stdout while the TUI owns the terminal.
Removed¶
- Music / cliamp subsystem — the entire
[music]config section, music controller, dashboard music panel, dedicated music screen, and--with-musicCLI flag. No DB impact (music state was read live from the external player and never persisted).
Fixed¶
- Six meaningful
except Exception: passsites inapp.pynow route tolog.exception(four DB reads, twosave_configcalls). Cosmetic notify/bell/animate sites are intentionally left silent.
Resolved code-review issues (cumulative)¶
Tracked in .code_review/code_review_issues.md.
- ISSUE-001 — DB writes on the tick path (won't-fix): mitigations stand (cached lunch SELECT, deferred modal push). A dedicated writer thread would conflict with the project's single-SQLite-connection design. Revisit only if real-world jank is observed. See ADR-0002.
- ISSUE-005 — slim
PomodoroApp(resolved):core/filter_state.py,core/session_coordinator.py, andcore/task_input.pyextractions all landed. Music removal trimmed the remaining UI-action surface. - ISSUE-012 — swallowed excepts (resolved): see Fixed above.