pomban 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. pomban-0.2.0/LICENSE +21 -0
  2. pomban-0.2.0/PKG-INFO +305 -0
  3. pomban-0.2.0/README.md +263 -0
  4. pomban-0.2.0/pyproject.toml +102 -0
  5. pomban-0.2.0/setup.cfg +4 -0
  6. pomban-0.2.0/src/pomban/__init__.py +1 -0
  7. pomban-0.2.0/src/pomban/__main__.py +117 -0
  8. pomban-0.2.0/src/pomban/_migrate_xdg.py +39 -0
  9. pomban-0.2.0/src/pomban/app.py +959 -0
  10. pomban-0.2.0/src/pomban/core/__init__.py +0 -0
  11. pomban-0.2.0/src/pomban/core/colors.py +65 -0
  12. pomban-0.2.0/src/pomban/core/config.py +224 -0
  13. pomban-0.2.0/src/pomban/core/db.py +1064 -0
  14. pomban-0.2.0/src/pomban/core/engine.py +369 -0
  15. pomban-0.2.0/src/pomban/core/exporter.py +204 -0
  16. pomban-0.2.0/src/pomban/core/filter_state.py +87 -0
  17. pomban-0.2.0/src/pomban/core/filters.py +92 -0
  18. pomban-0.2.0/src/pomban/core/log.py +54 -0
  19. pomban-0.2.0/src/pomban/core/models.py +56 -0
  20. pomban-0.2.0/src/pomban/core/session_coordinator.py +68 -0
  21. pomban-0.2.0/src/pomban/core/session_service.py +50 -0
  22. pomban-0.2.0/src/pomban/core/task_input.py +58 -0
  23. pomban-0.2.0/src/pomban/core/timer_engine.py +197 -0
  24. pomban-0.2.0/src/pomban/notifications.py +94 -0
  25. pomban-0.2.0/src/pomban/plugins.py +97 -0
  26. pomban-0.2.0/src/pomban/screens/__init__.py +0 -0
  27. pomban-0.2.0/src/pomban/screens/base.py +70 -0
  28. pomban-0.2.0/src/pomban/screens/blocker.py +48 -0
  29. pomban-0.2.0/src/pomban/screens/card_detail.py +116 -0
  30. pomban-0.2.0/src/pomban/screens/dashboard.py +219 -0
  31. pomban-0.2.0/src/pomban/screens/edit_task.py +104 -0
  32. pomban-0.2.0/src/pomban/screens/first_run.py +50 -0
  33. pomban-0.2.0/src/pomban/screens/help.py +72 -0
  34. pomban-0.2.0/src/pomban/screens/history.py +69 -0
  35. pomban-0.2.0/src/pomban/screens/kanban.py +596 -0
  36. pomban-0.2.0/src/pomban/screens/presets.py +59 -0
  37. pomban-0.2.0/src/pomban/screens/project_picker.py +70 -0
  38. pomban-0.2.0/src/pomban/screens/projects.py +247 -0
  39. pomban-0.2.0/src/pomban/screens/resume.py +49 -0
  40. pomban-0.2.0/src/pomban/screens/session_end.py +275 -0
  41. pomban-0.2.0/src/pomban/screens/sprint_complete.py +63 -0
  42. pomban-0.2.0/src/pomban/screens/sprint_picker.py +75 -0
  43. pomban-0.2.0/src/pomban/screens/sprint_runner.py +207 -0
  44. pomban-0.2.0/src/pomban/screens/sprints.py +236 -0
  45. pomban-0.2.0/src/pomban/screens/stats.py +258 -0
  46. pomban-0.2.0/src/pomban/screens/today.py +136 -0
  47. pomban-0.2.0/src/pomban/widgets/__init__.py +0 -0
  48. pomban-0.2.0/src/pomban/widgets/bar_chart.py +74 -0
  49. pomban-0.2.0/src/pomban/widgets/card.py +145 -0
  50. pomban-0.2.0/src/pomban/widgets/context_header.py +91 -0
  51. pomban-0.2.0/src/pomban/widgets/heatmap.py +37 -0
  52. pomban-0.2.0/src/pomban/widgets/panel.py +36 -0
  53. pomban-0.2.0/src/pomban/widgets/sparkline.py +35 -0
  54. pomban-0.2.0/src/pomban/widgets/stats_strip.py +27 -0
  55. pomban-0.2.0/src/pomban/widgets/timer_display.py +70 -0
  56. pomban-0.2.0/src/pomban.egg-info/PKG-INFO +305 -0
  57. pomban-0.2.0/src/pomban.egg-info/SOURCES.txt +106 -0
  58. pomban-0.2.0/src/pomban.egg-info/dependency_links.txt +1 -0
  59. pomban-0.2.0/src/pomban.egg-info/entry_points.txt +2 -0
  60. pomban-0.2.0/src/pomban.egg-info/requires.txt +15 -0
  61. pomban-0.2.0/src/pomban.egg-info/top_level.txt +1 -0
  62. pomban-0.2.0/tests/test_app_blocker.py +70 -0
  63. pomban-0.2.0/tests/test_app_first_run.py +72 -0
  64. pomban-0.2.0/tests/test_app_kanban.py +189 -0
  65. pomban-0.2.0/tests/test_app_projects_sprint.py +71 -0
  66. pomban-0.2.0/tests/test_app_smoke.py +167 -0
  67. pomban-0.2.0/tests/test_app_sprint_complete.py +54 -0
  68. pomban-0.2.0/tests/test_app_sprint_runner.py +103 -0
  69. pomban-0.2.0/tests/test_app_stats.py +57 -0
  70. pomban-0.2.0/tests/test_app_stats_tags.py +67 -0
  71. pomban-0.2.0/tests/test_app_today.py +70 -0
  72. pomban-0.2.0/tests/test_charts.py +108 -0
  73. pomban-0.2.0/tests/test_config.py +62 -0
  74. pomban-0.2.0/tests/test_context_header.py +116 -0
  75. pomban-0.2.0/tests/test_dashboard_focus.py +31 -0
  76. pomban-0.2.0/tests/test_dashboard_sprint_chip.py +93 -0
  77. pomban-0.2.0/tests/test_db.py +128 -0
  78. pomban-0.2.0/tests/test_db_kanban.py +51 -0
  79. pomban-0.2.0/tests/test_db_progress_tags.py +154 -0
  80. pomban-0.2.0/tests/test_edit_task.py +52 -0
  81. pomban-0.2.0/tests/test_engine_sprint.py +133 -0
  82. pomban-0.2.0/tests/test_exporter.py +133 -0
  83. pomban-0.2.0/tests/test_filter_state.py +71 -0
  84. pomban-0.2.0/tests/test_filters.py +45 -0
  85. pomban-0.2.0/tests/test_help.py +37 -0
  86. pomban-0.2.0/tests/test_kanban_enhancements.py +274 -0
  87. pomban-0.2.0/tests/test_kanban_framing.py +88 -0
  88. pomban-0.2.0/tests/test_lunch.py +58 -0
  89. pomban-0.2.0/tests/test_markup_safety.py +41 -0
  90. pomban-0.2.0/tests/test_migrate_xdg.py +59 -0
  91. pomban-0.2.0/tests/test_migration_v10.py +50 -0
  92. pomban-0.2.0/tests/test_multitask.py +117 -0
  93. pomban-0.2.0/tests/test_phase12.py +63 -0
  94. pomban-0.2.0/tests/test_plugins_and_sync.py +82 -0
  95. pomban-0.2.0/tests/test_pomban_engine.py +209 -0
  96. pomban-0.2.0/tests/test_projects.py +129 -0
  97. pomban-0.2.0/tests/test_resume.py +115 -0
  98. pomban-0.2.0/tests/test_session_coordinator.py +61 -0
  99. pomban-0.2.0/tests/test_session_notes.py +108 -0
  100. pomban-0.2.0/tests/test_session_service.py +41 -0
  101. pomban-0.2.0/tests/test_sprints.py +75 -0
  102. pomban-0.2.0/tests/test_stats_and_migration.py +125 -0
  103. pomban-0.2.0/tests/test_submit_new_task.py +125 -0
  104. pomban-0.2.0/tests/test_tags.py +70 -0
  105. pomban-0.2.0/tests/test_task_defaults.py +49 -0
  106. pomban-0.2.0/tests/test_task_input.py +33 -0
  107. pomban-0.2.0/tests/test_timer_engine.py +242 -0
  108. pomban-0.2.0/tests/test_working_hours.py +79 -0
pomban-0.2.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Prajwal Mahajan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
pomban-0.2.0/PKG-INFO ADDED
@@ -0,0 +1,305 @@
1
+ Metadata-Version: 2.4
2
+ Name: pomban
3
+ Version: 0.2.0
4
+ Summary: Project-management TUI that runs on pomodoros
5
+ Author-email: Prajwal Mahajan <prajwal.mahajan101@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/prajwalmahajan101/pomban
8
+ Project-URL: Documentation, https://prajwalmahajan101.github.io/pomban/
9
+ Project-URL: Repository, https://github.com/prajwalmahajan101/pomban
10
+ Project-URL: Changelog, https://github.com/prajwalmahajan101/pomban/blob/main/CHANGELOG.md
11
+ Project-URL: Issues, https://github.com/prajwalmahajan101/pomban/issues
12
+ Keywords: tui,textual,pomodoro,kanban,sprint,project-management,productivity
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Environment :: Console :: Curses
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Operating System :: POSIX :: Linux
17
+ Classifier: Operating System :: MacOS
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Office/Business :: Scheduling
23
+ Classifier: Topic :: Terminals
24
+ Classifier: Typing :: Typed
25
+ Requires-Python: >=3.11
26
+ Description-Content-Type: text/markdown
27
+ License-File: LICENSE
28
+ Requires-Dist: textual>=0.79
29
+ Provides-Extra: dev
30
+ Requires-Dist: pytest>=8; extra == "dev"
31
+ Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
32
+ Requires-Dist: ruff==0.15.16; extra == "dev"
33
+ Requires-Dist: mypy>=1.11; extra == "dev"
34
+ Requires-Dist: pre-commit>=3.7; extra == "dev"
35
+ Requires-Dist: build>=1.2; extra == "dev"
36
+ Requires-Dist: twine>=5; extra == "dev"
37
+ Provides-Extra: docs
38
+ Requires-Dist: mkdocs>=1.6; extra == "docs"
39
+ Requires-Dist: mkdocs-material<2.0,>=9.5; extra == "docs"
40
+ Requires-Dist: pymdown-extensions>=10; extra == "docs"
41
+ Dynamic: license-file
42
+
43
+ # pomban
44
+
45
+ [![Python](https://img.shields.io/badge/python-%E2%89%A53.11-blue.svg)](https://www.python.org/)
46
+ [![License](https://img.shields.io/badge/license-MIT-green.svg)](./LICENSE)
47
+ [![test](https://github.com/prajwalmahajan101/pomban/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/prajwalmahajan101/pomban/actions/workflows/test.yml)
48
+
49
+ > A local-first personal productivity platform — projects, sprints,
50
+ > kanban, and focus sessions — that runs entirely in your terminal.
51
+
52
+ ![pomban dashboard](docs/screenshots/dashboard.svg)
53
+
54
+ ```bash
55
+ pipx install pomban && pomban
56
+ ```
57
+
58
+ ## What is pomban?
59
+
60
+ pomban is a single-binary planning, focus, and review platform built
61
+ around one SQLite library on your machine. It models work the way you
62
+ actually do it — projects own sprints, sprints own tasks, tasks
63
+ accumulate focus sessions — and gives every layer a keyboard-driven
64
+ screen:
65
+
66
+ - **Plan** at the project and sprint level. Move tasks across a
67
+ kanban with WIP limits, deadlines, and inline `@project` /
68
+ `!sprint` syntax.
69
+ - **Focus** with a Pomodoro engine that logs every session against a
70
+ task, captures mid-session blockers, and records a free-text note
71
+ when a session ends.
72
+ - **Review** with stats, per-tag analytics, a daily digest, exports
73
+ (CSV / JSON / grouped markdown), and a full session history.
74
+ - **Integrate** through phase-lifecycle shell hooks and in-process
75
+ Python plugins. The first-party `git_sync` plugin commits the
76
+ SQLite library on exit so the same database follows you across
77
+ machines via a personal git remote.
78
+
79
+ The terminal is the runtime — fast launch, zero chrome, every action
80
+ one keystroke — but the product is the platform underneath. Your
81
+ library never leaves your machine, no account, no telemetry, no cloud.
82
+
83
+ ### How it compares
84
+
85
+ - **vs CLI timers** — full task surface (kanban + projects + sprints
86
+ + digest + stats + history), not just a countdown.
87
+ - **vs phone Pomodoro apps** — keyboard-driven, distraction-free,
88
+ themed, runs in the terminal you already have open.
89
+ - **vs PM SaaS (Linear/Jira/Notion)** — local-first, single-file
90
+ library you own, no login, no rate limits, no migration anxiety.
91
+ - **vs a wall clock + sticky notes** — every session is logged. Per
92
+ task, per project, per sprint, per day, per week.
93
+
94
+ ## Features
95
+
96
+ ### Plan
97
+
98
+ - **Projects and Sprints** (`5` / `6`) — full CRUD with archiving,
99
+ completion states, and `@project` / `!sprint` inline task syntax.
100
+ One sprint per project can be active; sprint runner overlay
101
+ (`Shift+R`) keeps the current goal pinned regardless of screen.
102
+ - **Kanban board** (`2`) — three columns, priorities, due dates
103
+ (overdue render red), per-column WIP limits, board search (`/`),
104
+ visual-mode bulk actions (`v`), card-detail screen (`i`).
105
+ - **Context header** — every screen carries the active project /
106
+ sprint chip so you always know what work the next focus session
107
+ attaches to.
108
+ - **First-run flow** — empty DB launches a modal that seeds your
109
+ first project so the hierarchy is never empty.
110
+
111
+ ### Focus
112
+
113
+ - **Pomodoro engine** — focus / short-break / long-break / lunch
114
+ phases, configurable cycle length, auto-advance toggle (`Shift+T`),
115
+ resume-on-restart prompt, lunch-window suggestion.
116
+ - **Blocker capture** (`b`) — log a one-line blocker against the
117
+ current focus session without breaking the timer.
118
+ - **Session notes** — at session end, jot a freeform note; it
119
+ surfaces on the history screen against that row.
120
+ - **Working-hours quiet** — set a daily window in `[breaks]` and
121
+ outside it desktop popups + sound suppress automatically. A
122
+ header chip shows the current state.
123
+
124
+ ### Review
125
+
126
+ - **Stats** (`3`) — daily / weekly / monthly buckets, top tasks,
127
+ interruption counts, plus a **per-tag analytics panel** built on
128
+ `minutes_per_tag`.
129
+ - **Today digest** (`7`) — sessions, top tasks, interruptions for
130
+ the current day, one screenful.
131
+ - **History** (`4`) — every session with planned vs. actual
132
+ duration and the session note inline.
133
+ - **Exports** — `pomban export` ships CSV, JSON, and
134
+ grouped-markdown formats. `pomban sprint export …` produces a
135
+ per-sprint report.
136
+
137
+ ### Integrate
138
+
139
+ - **Hooks** — `[hooks].on_focus_start` / `on_focus_end` /
140
+ `on_break_start` / `on_break_end` shell commands invoked with
141
+ `POMODORO_PHASE` and `POMODORO_TASK_TITLE` env vars.
142
+ - **In-process plugins** — Python entry points discovered at
143
+ startup; exceptions are sandboxed and never crash the app.
144
+ - **`git_sync` plugin** — commits the SQLite library on exit so it
145
+ can sync across devices via a personal git remote.
146
+ - **Themes** — nord, gruvbox, dracula, catppuccin-mocha,
147
+ tokyo-night. Cycle with `t`; persisted to `config.toml`.
148
+
149
+ ## Install
150
+
151
+ ```bash
152
+ pipx install pomban
153
+ ```
154
+
155
+ `pipx` (or [`uv tool`](https://docs.astral.sh/uv/)) is the
156
+ recommended path for end-user CLI tools — it sandboxes pomban's
157
+ dependencies in their own venv and gives you a global `pomban`
158
+ command. On modern Linux distros it's also the only path that works
159
+ without virtualenv gymnastics, thanks to
160
+ [PEP 668](https://peps.python.org/pep-0668/).
161
+
162
+ ```bash
163
+ # uv tool — same idea, faster
164
+ uv tool install pomban
165
+
166
+ # pip (inside a venv)
167
+ python -m venv .venv && source .venv/bin/activate
168
+ pip install pomban
169
+
170
+ # From source
171
+ git clone https://github.com/prajwalmahajan101/pomban
172
+ cd pomban && pip install -e ".[dev]"
173
+ ```
174
+
175
+ ### Requirements
176
+
177
+ - Python ≥ 3.11
178
+ - A terminal with at least 80 columns. 100+ recommended.
179
+ - Linux desktop notifications need `notify-send`; sound needs
180
+ `paplay`, `aplay`, or `ffplay` on `$PATH`. Both degrade silently
181
+ if missing — the in-TUI bell still fires.
182
+
183
+ ## Quick start
184
+
185
+ ```bash
186
+ pomban # launch the TUI
187
+ ```
188
+
189
+ On an empty database the first-run modal walks you through creating
190
+ a project. From there: pick a sprint, add tasks (`n`, with inline
191
+ `@project` / `!sprint` / `#tag` / `~25` for a 25-minute estimate),
192
+ and hit `s` to start a focus session.
193
+
194
+ Press `?` at any time for a context-aware help overlay. The most
195
+ common keys:
196
+
197
+ | Key | Action |
198
+ |---|---|
199
+ | `s` / `Space` | Start / pause / resume the timer |
200
+ | `r` | Reset |
201
+ | `Shift+S` / `S` | Skip to the next phase |
202
+ | `n` | Focus the "new task" input |
203
+ | `b` | Log a blocker against the current focus session |
204
+ | `1`–`7` | Jump to Dashboard / Kanban / Stats / History / Projects / Sprints / Today |
205
+ | `Shift+R` | Sprint runner overlay |
206
+ | `t` | Cycle theme |
207
+ | `?` | Help overlay |
208
+ | `q` | Quit (persists pending focus session) |
209
+
210
+ Full reference: [docs/site/keybindings.md](docs/site/keybindings.md).
211
+
212
+ ### CLI
213
+
214
+ ```bash
215
+ pomban # launch the TUI
216
+ pomban export --since 7d # markdown review to stdout
217
+ pomban export --since 7d --format csv # CSV export
218
+ pomban export --since 7d --format json
219
+ pomban sprint export … # per-sprint reports (see `--help`)
220
+ ```
221
+
222
+ ## Configuration
223
+
224
+ pomban reads `~/.config/pomban/config.toml` (XDG-compliant). The
225
+ file is optional — sane defaults ship. Top-level sections:
226
+
227
+ | Section | What it controls |
228
+ |---|---|
229
+ | `[timer]` | Focus / break minutes, cycle count, warning seconds, auto-advance |
230
+ | `[notifications]` | Desktop / sound / bell |
231
+ | `[ui]` | Theme |
232
+ | `[hooks]` | Shell commands on phase start / end |
233
+ | `[sync]` | The `git_sync` plugin |
234
+ | `[breaks]` | Lunch-break window + working-hours quiet window |
235
+ | `[kanban]` | Per-column WIP limits |
236
+ | `[[preset]]` | One block per preset, switchable via `p` |
237
+
238
+ The working-hours window lives under `[breaks]` as
239
+ `working_hours_start` / `working_hours_end` (`"HH:MM"`); outside the
240
+ window, desktop popups and sound suppress (the in-TUI bell still
241
+ fires).
242
+
243
+ Full reference: [docs/site/configuration.md](docs/site/configuration.md).
244
+
245
+ ### XDG paths
246
+
247
+ | Purpose | Path |
248
+ |---|---|
249
+ | Config | `$XDG_CONFIG_HOME/pomban/config.toml`, default `~/.config/pomban/config.toml` |
250
+ | Library DB | `$XDG_DATA_HOME/pomban/pomban.db`, default `~/.local/share/pomban/pomban.db` |
251
+ | Log | `$XDG_STATE_HOME/pomban/pomban.log`, default `~/.local/state/pomban/pomban.log` |
252
+
253
+ ## Troubleshooting
254
+
255
+ **The bell rings but no desktop notification appears.**
256
+ On Linux, install a notification daemon and `notify-send` (`libnotify`
257
+ on most distros). On macOS, install `terminal-notifier`. The bell
258
+ itself always fires; the desktop notification is best-effort.
259
+
260
+ **Notifications stay quiet during the day.**
261
+ Check your `[breaks].working_hours_start` / `working_hours_end`. The
262
+ header chip reflects the current quiet state.
263
+
264
+ **`git_sync` complained "not a git repo".**
265
+ Run `git init && git remote add origin <your-url>` inside
266
+ `~/.local/share/pomban/`. pomban commits on exit but never
267
+ pushes — set up a `post-commit` hook or cron if you want auto-push.
268
+
269
+ **A focus session crashed mid-pomodoro; will I lose it?**
270
+ No. The session and remaining seconds are persisted at every phase
271
+ transition. On next launch you'll get a resume prompt.
272
+
273
+ **SQLite says "database is locked".**
274
+ pomban uses a single SQLite connection by design (see
275
+ [ADR-0002](docs/adr/0002-single-sqlite-connection.md)). If you opened
276
+ the DB in another tool while pomban was running, close that tool.
277
+
278
+ ## Development
279
+
280
+ ```bash
281
+ git clone https://github.com/prajwalmahajan101/pomban
282
+ cd pomban
283
+ python -m venv .venv && source .venv/bin/activate
284
+ pip install -e ".[dev]"
285
+ pre-commit install
286
+
287
+ pytest -q
288
+ ruff format --check . && ruff check src/ tests/
289
+ ```
290
+
291
+ See [CONTRIBUTING.md](./CONTRIBUTING.md) for the full convention list,
292
+ [ROADMAP.md](./ROADMAP.md) for what's coming, and
293
+ [RELEASE_PLAN.md](./RELEASE_PLAN.md) for how releases are cut.
294
+
295
+ ## Project background
296
+
297
+ pomban is a solo, phase-driven project. The phase plan and current
298
+ status are in [ROADMAP.md](./ROADMAP.md); architectural decisions are
299
+ recorded under [docs/adr/](docs/adr/); the cumulative change history
300
+ is in [CHANGELOG.md](./CHANGELOG.md). Active and resolved code-review
301
+ findings live under [`.code_review/`](.code_review/).
302
+
303
+ ## License
304
+
305
+ MIT — see [LICENSE](./LICENSE).
pomban-0.2.0/README.md ADDED
@@ -0,0 +1,263 @@
1
+ # pomban
2
+
3
+ [![Python](https://img.shields.io/badge/python-%E2%89%A53.11-blue.svg)](https://www.python.org/)
4
+ [![License](https://img.shields.io/badge/license-MIT-green.svg)](./LICENSE)
5
+ [![test](https://github.com/prajwalmahajan101/pomban/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/prajwalmahajan101/pomban/actions/workflows/test.yml)
6
+
7
+ > A local-first personal productivity platform — projects, sprints,
8
+ > kanban, and focus sessions — that runs entirely in your terminal.
9
+
10
+ ![pomban dashboard](docs/screenshots/dashboard.svg)
11
+
12
+ ```bash
13
+ pipx install pomban && pomban
14
+ ```
15
+
16
+ ## What is pomban?
17
+
18
+ pomban is a single-binary planning, focus, and review platform built
19
+ around one SQLite library on your machine. It models work the way you
20
+ actually do it — projects own sprints, sprints own tasks, tasks
21
+ accumulate focus sessions — and gives every layer a keyboard-driven
22
+ screen:
23
+
24
+ - **Plan** at the project and sprint level. Move tasks across a
25
+ kanban with WIP limits, deadlines, and inline `@project` /
26
+ `!sprint` syntax.
27
+ - **Focus** with a Pomodoro engine that logs every session against a
28
+ task, captures mid-session blockers, and records a free-text note
29
+ when a session ends.
30
+ - **Review** with stats, per-tag analytics, a daily digest, exports
31
+ (CSV / JSON / grouped markdown), and a full session history.
32
+ - **Integrate** through phase-lifecycle shell hooks and in-process
33
+ Python plugins. The first-party `git_sync` plugin commits the
34
+ SQLite library on exit so the same database follows you across
35
+ machines via a personal git remote.
36
+
37
+ The terminal is the runtime — fast launch, zero chrome, every action
38
+ one keystroke — but the product is the platform underneath. Your
39
+ library never leaves your machine, no account, no telemetry, no cloud.
40
+
41
+ ### How it compares
42
+
43
+ - **vs CLI timers** — full task surface (kanban + projects + sprints
44
+ + digest + stats + history), not just a countdown.
45
+ - **vs phone Pomodoro apps** — keyboard-driven, distraction-free,
46
+ themed, runs in the terminal you already have open.
47
+ - **vs PM SaaS (Linear/Jira/Notion)** — local-first, single-file
48
+ library you own, no login, no rate limits, no migration anxiety.
49
+ - **vs a wall clock + sticky notes** — every session is logged. Per
50
+ task, per project, per sprint, per day, per week.
51
+
52
+ ## Features
53
+
54
+ ### Plan
55
+
56
+ - **Projects and Sprints** (`5` / `6`) — full CRUD with archiving,
57
+ completion states, and `@project` / `!sprint` inline task syntax.
58
+ One sprint per project can be active; sprint runner overlay
59
+ (`Shift+R`) keeps the current goal pinned regardless of screen.
60
+ - **Kanban board** (`2`) — three columns, priorities, due dates
61
+ (overdue render red), per-column WIP limits, board search (`/`),
62
+ visual-mode bulk actions (`v`), card-detail screen (`i`).
63
+ - **Context header** — every screen carries the active project /
64
+ sprint chip so you always know what work the next focus session
65
+ attaches to.
66
+ - **First-run flow** — empty DB launches a modal that seeds your
67
+ first project so the hierarchy is never empty.
68
+
69
+ ### Focus
70
+
71
+ - **Pomodoro engine** — focus / short-break / long-break / lunch
72
+ phases, configurable cycle length, auto-advance toggle (`Shift+T`),
73
+ resume-on-restart prompt, lunch-window suggestion.
74
+ - **Blocker capture** (`b`) — log a one-line blocker against the
75
+ current focus session without breaking the timer.
76
+ - **Session notes** — at session end, jot a freeform note; it
77
+ surfaces on the history screen against that row.
78
+ - **Working-hours quiet** — set a daily window in `[breaks]` and
79
+ outside it desktop popups + sound suppress automatically. A
80
+ header chip shows the current state.
81
+
82
+ ### Review
83
+
84
+ - **Stats** (`3`) — daily / weekly / monthly buckets, top tasks,
85
+ interruption counts, plus a **per-tag analytics panel** built on
86
+ `minutes_per_tag`.
87
+ - **Today digest** (`7`) — sessions, top tasks, interruptions for
88
+ the current day, one screenful.
89
+ - **History** (`4`) — every session with planned vs. actual
90
+ duration and the session note inline.
91
+ - **Exports** — `pomban export` ships CSV, JSON, and
92
+ grouped-markdown formats. `pomban sprint export …` produces a
93
+ per-sprint report.
94
+
95
+ ### Integrate
96
+
97
+ - **Hooks** — `[hooks].on_focus_start` / `on_focus_end` /
98
+ `on_break_start` / `on_break_end` shell commands invoked with
99
+ `POMODORO_PHASE` and `POMODORO_TASK_TITLE` env vars.
100
+ - **In-process plugins** — Python entry points discovered at
101
+ startup; exceptions are sandboxed and never crash the app.
102
+ - **`git_sync` plugin** — commits the SQLite library on exit so it
103
+ can sync across devices via a personal git remote.
104
+ - **Themes** — nord, gruvbox, dracula, catppuccin-mocha,
105
+ tokyo-night. Cycle with `t`; persisted to `config.toml`.
106
+
107
+ ## Install
108
+
109
+ ```bash
110
+ pipx install pomban
111
+ ```
112
+
113
+ `pipx` (or [`uv tool`](https://docs.astral.sh/uv/)) is the
114
+ recommended path for end-user CLI tools — it sandboxes pomban's
115
+ dependencies in their own venv and gives you a global `pomban`
116
+ command. On modern Linux distros it's also the only path that works
117
+ without virtualenv gymnastics, thanks to
118
+ [PEP 668](https://peps.python.org/pep-0668/).
119
+
120
+ ```bash
121
+ # uv tool — same idea, faster
122
+ uv tool install pomban
123
+
124
+ # pip (inside a venv)
125
+ python -m venv .venv && source .venv/bin/activate
126
+ pip install pomban
127
+
128
+ # From source
129
+ git clone https://github.com/prajwalmahajan101/pomban
130
+ cd pomban && pip install -e ".[dev]"
131
+ ```
132
+
133
+ ### Requirements
134
+
135
+ - Python ≥ 3.11
136
+ - A terminal with at least 80 columns. 100+ recommended.
137
+ - Linux desktop notifications need `notify-send`; sound needs
138
+ `paplay`, `aplay`, or `ffplay` on `$PATH`. Both degrade silently
139
+ if missing — the in-TUI bell still fires.
140
+
141
+ ## Quick start
142
+
143
+ ```bash
144
+ pomban # launch the TUI
145
+ ```
146
+
147
+ On an empty database the first-run modal walks you through creating
148
+ a project. From there: pick a sprint, add tasks (`n`, with inline
149
+ `@project` / `!sprint` / `#tag` / `~25` for a 25-minute estimate),
150
+ and hit `s` to start a focus session.
151
+
152
+ Press `?` at any time for a context-aware help overlay. The most
153
+ common keys:
154
+
155
+ | Key | Action |
156
+ |---|---|
157
+ | `s` / `Space` | Start / pause / resume the timer |
158
+ | `r` | Reset |
159
+ | `Shift+S` / `S` | Skip to the next phase |
160
+ | `n` | Focus the "new task" input |
161
+ | `b` | Log a blocker against the current focus session |
162
+ | `1`–`7` | Jump to Dashboard / Kanban / Stats / History / Projects / Sprints / Today |
163
+ | `Shift+R` | Sprint runner overlay |
164
+ | `t` | Cycle theme |
165
+ | `?` | Help overlay |
166
+ | `q` | Quit (persists pending focus session) |
167
+
168
+ Full reference: [docs/site/keybindings.md](docs/site/keybindings.md).
169
+
170
+ ### CLI
171
+
172
+ ```bash
173
+ pomban # launch the TUI
174
+ pomban export --since 7d # markdown review to stdout
175
+ pomban export --since 7d --format csv # CSV export
176
+ pomban export --since 7d --format json
177
+ pomban sprint export … # per-sprint reports (see `--help`)
178
+ ```
179
+
180
+ ## Configuration
181
+
182
+ pomban reads `~/.config/pomban/config.toml` (XDG-compliant). The
183
+ file is optional — sane defaults ship. Top-level sections:
184
+
185
+ | Section | What it controls |
186
+ |---|---|
187
+ | `[timer]` | Focus / break minutes, cycle count, warning seconds, auto-advance |
188
+ | `[notifications]` | Desktop / sound / bell |
189
+ | `[ui]` | Theme |
190
+ | `[hooks]` | Shell commands on phase start / end |
191
+ | `[sync]` | The `git_sync` plugin |
192
+ | `[breaks]` | Lunch-break window + working-hours quiet window |
193
+ | `[kanban]` | Per-column WIP limits |
194
+ | `[[preset]]` | One block per preset, switchable via `p` |
195
+
196
+ The working-hours window lives under `[breaks]` as
197
+ `working_hours_start` / `working_hours_end` (`"HH:MM"`); outside the
198
+ window, desktop popups and sound suppress (the in-TUI bell still
199
+ fires).
200
+
201
+ Full reference: [docs/site/configuration.md](docs/site/configuration.md).
202
+
203
+ ### XDG paths
204
+
205
+ | Purpose | Path |
206
+ |---|---|
207
+ | Config | `$XDG_CONFIG_HOME/pomban/config.toml`, default `~/.config/pomban/config.toml` |
208
+ | Library DB | `$XDG_DATA_HOME/pomban/pomban.db`, default `~/.local/share/pomban/pomban.db` |
209
+ | Log | `$XDG_STATE_HOME/pomban/pomban.log`, default `~/.local/state/pomban/pomban.log` |
210
+
211
+ ## Troubleshooting
212
+
213
+ **The bell rings but no desktop notification appears.**
214
+ On Linux, install a notification daemon and `notify-send` (`libnotify`
215
+ on most distros). On macOS, install `terminal-notifier`. The bell
216
+ itself always fires; the desktop notification is best-effort.
217
+
218
+ **Notifications stay quiet during the day.**
219
+ Check your `[breaks].working_hours_start` / `working_hours_end`. The
220
+ header chip reflects the current quiet state.
221
+
222
+ **`git_sync` complained "not a git repo".**
223
+ Run `git init && git remote add origin <your-url>` inside
224
+ `~/.local/share/pomban/`. pomban commits on exit but never
225
+ pushes — set up a `post-commit` hook or cron if you want auto-push.
226
+
227
+ **A focus session crashed mid-pomodoro; will I lose it?**
228
+ No. The session and remaining seconds are persisted at every phase
229
+ transition. On next launch you'll get a resume prompt.
230
+
231
+ **SQLite says "database is locked".**
232
+ pomban uses a single SQLite connection by design (see
233
+ [ADR-0002](docs/adr/0002-single-sqlite-connection.md)). If you opened
234
+ the DB in another tool while pomban was running, close that tool.
235
+
236
+ ## Development
237
+
238
+ ```bash
239
+ git clone https://github.com/prajwalmahajan101/pomban
240
+ cd pomban
241
+ python -m venv .venv && source .venv/bin/activate
242
+ pip install -e ".[dev]"
243
+ pre-commit install
244
+
245
+ pytest -q
246
+ ruff format --check . && ruff check src/ tests/
247
+ ```
248
+
249
+ See [CONTRIBUTING.md](./CONTRIBUTING.md) for the full convention list,
250
+ [ROADMAP.md](./ROADMAP.md) for what's coming, and
251
+ [RELEASE_PLAN.md](./RELEASE_PLAN.md) for how releases are cut.
252
+
253
+ ## Project background
254
+
255
+ pomban is a solo, phase-driven project. The phase plan and current
256
+ status are in [ROADMAP.md](./ROADMAP.md); architectural decisions are
257
+ recorded under [docs/adr/](docs/adr/); the cumulative change history
258
+ is in [CHANGELOG.md](./CHANGELOG.md). Active and resolved code-review
259
+ findings live under [`.code_review/`](.code_review/).
260
+
261
+ ## License
262
+
263
+ MIT — see [LICENSE](./LICENSE).
@@ -0,0 +1,102 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "pomban"
7
+ version = "0.2.0"
8
+ description = "Project-management TUI that runs on pomodoros"
9
+ readme = "README.md"
10
+ keywords = ["tui", "textual", "pomodoro", "kanban", "sprint", "project-management", "productivity"]
11
+ requires-python = ">=3.11"
12
+ license = "MIT"
13
+ license-files = ["LICENSE"]
14
+ authors = [{ name = "Prajwal Mahajan", email = "prajwal.mahajan101@gmail.com" }]
15
+ classifiers = [
16
+ "Development Status :: 4 - Beta",
17
+ "Environment :: Console :: Curses",
18
+ "Intended Audience :: Developers",
19
+ "Operating System :: POSIX :: Linux",
20
+ "Operating System :: MacOS",
21
+ "Programming Language :: Python :: 3",
22
+ "Programming Language :: Python :: 3.11",
23
+ "Programming Language :: Python :: 3.12",
24
+ "Programming Language :: Python :: 3.13",
25
+ "Topic :: Office/Business :: Scheduling",
26
+ "Topic :: Terminals",
27
+ "Typing :: Typed",
28
+ ]
29
+ dependencies = [
30
+ "textual>=0.79",
31
+ ]
32
+
33
+ [project.urls]
34
+ Homepage = "https://github.com/prajwalmahajan101/pomban"
35
+ Documentation = "https://prajwalmahajan101.github.io/pomban/"
36
+ Repository = "https://github.com/prajwalmahajan101/pomban"
37
+ Changelog = "https://github.com/prajwalmahajan101/pomban/blob/main/CHANGELOG.md"
38
+ Issues = "https://github.com/prajwalmahajan101/pomban/issues"
39
+
40
+ [project.optional-dependencies]
41
+ dev = [
42
+ "pytest>=8",
43
+ "pytest-asyncio>=0.23",
44
+ "ruff==0.15.16",
45
+ "mypy>=1.11",
46
+ "pre-commit>=3.7",
47
+ "build>=1.2",
48
+ "twine>=5",
49
+ ]
50
+ docs = [
51
+ "mkdocs>=1.6",
52
+ "mkdocs-material>=9.5,<2.0",
53
+ "pymdown-extensions>=10",
54
+ ]
55
+
56
+ [project.scripts]
57
+ pomban = "pomban.__main__:main"
58
+
59
+ [tool.setuptools.packages.find]
60
+ where = ["src"]
61
+
62
+ [tool.pytest.ini_options]
63
+ testpaths = ["tests"]
64
+ pythonpath = ["src"]
65
+ asyncio_mode = "auto"
66
+
67
+ [tool.ruff]
68
+ line-length = 100
69
+ target-version = "py311"
70
+ extend-exclude = [".venv", "build", "dist"]
71
+
72
+ [tool.ruff.lint]
73
+ select = ["E", "F", "W", "I", "B", "UP", "SIM", "N", "RUF"]
74
+ ignore = [
75
+ "E501", # line length — formatter handles it
76
+ "RUF012", # ClassVar on Textual reactives — false-positive on the framework
77
+ "RUF001", # ambiguous unicode in strings — author's choice (× as "x times" etc.)
78
+ "RUF002", # ambiguous unicode in docstrings — author's choice
79
+ "RUF003", # ambiguous unicode in comments — author's choice
80
+ "UP045", # PEP-604 union — Optional[X] kept on Textual generic bases (runtime-evaluated)
81
+ "UP042", # str-mixin Enum — explicit (str, Enum) preferred over StrEnum here for clarity
82
+ "SIM117", # combine `with` — nested `with` matches the visual widget hierarchy in compose()
83
+ ]
84
+
85
+ [tool.ruff.lint.per-file-ignores]
86
+ "tests/*" = ["N802", "N803", "N806"]
87
+
88
+ [tool.ruff.format]
89
+ quote-style = "double"
90
+ indent-style = "space"
91
+ line-ending = "lf"
92
+
93
+ [tool.mypy]
94
+ python_version = "3.11"
95
+ files = ["src"]
96
+ warn_unused_ignores = true
97
+ warn_unreachable = true
98
+ show_error_codes = true
99
+
100
+ [[tool.mypy.overrides]]
101
+ module = ["textual.*"]
102
+ ignore_missing_imports = true
pomban-0.2.0/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+