klok-cli 1.0.0__tar.gz → 1.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 (35) hide show
  1. klok_cli-1.2.0/PKG-INFO +222 -0
  2. klok_cli-1.2.0/README.md +196 -0
  3. {klok_cli-1.0.0 → klok_cli-1.2.0}/klok/__init__.py +1 -1
  4. {klok_cli-1.0.0 → klok_cli-1.2.0}/klok/cli.py +229 -10
  5. {klok_cli-1.0.0 → klok_cli-1.2.0}/klok/config.py +10 -2
  6. klok_cli-1.2.0/klok/dashboard.html +1063 -0
  7. klok_cli-1.2.0/klok/dashboard.py +105 -0
  8. {klok_cli-1.0.0 → klok_cli-1.2.0}/klok/focus.py +3 -2
  9. {klok_cli-1.0.0 → klok_cli-1.2.0}/klok/formats.py +6 -2
  10. klok_cli-1.2.0/klok/insights.py +107 -0
  11. {klok_cli-1.0.0 → klok_cli-1.2.0}/klok/mindful.py +37 -0
  12. klok_cli-1.2.0/klok/pairing.py +39 -0
  13. {klok_cli-1.0.0 → klok_cli-1.2.0}/klok/storage.py +85 -32
  14. klok_cli-1.2.0/klok_cli.egg-info/PKG-INFO +222 -0
  15. {klok_cli-1.0.0 → klok_cli-1.2.0}/klok_cli.egg-info/SOURCES.txt +6 -0
  16. {klok_cli-1.0.0 → klok_cli-1.2.0}/pyproject.toml +5 -1
  17. {klok_cli-1.0.0 → klok_cli-1.2.0}/tests/test_cli.py +356 -2
  18. klok_cli-1.2.0/tests/test_insights.py +144 -0
  19. klok_cli-1.2.0/tests/test_pairing.py +91 -0
  20. klok_cli-1.0.0/PKG-INFO +0 -466
  21. klok_cli-1.0.0/README.md +0 -440
  22. klok_cli-1.0.0/klok_cli.egg-info/PKG-INFO +0 -466
  23. {klok_cli-1.0.0 → klok_cli-1.2.0}/LICENSE +0 -0
  24. {klok_cli-1.0.0 → klok_cli-1.2.0}/klok/__main__.py +0 -0
  25. {klok_cli-1.0.0 → klok_cli-1.2.0}/klok/model.py +0 -0
  26. {klok_cli-1.0.0 → klok_cli-1.2.0}/klok/report.py +0 -0
  27. {klok_cli-1.0.0 → klok_cli-1.2.0}/klok/timeparse.py +0 -0
  28. {klok_cli-1.0.0 → klok_cli-1.2.0}/klok/utils.py +0 -0
  29. {klok_cli-1.0.0 → klok_cli-1.2.0}/klok_cli.egg-info/dependency_links.txt +0 -0
  30. {klok_cli-1.0.0 → klok_cli-1.2.0}/klok_cli.egg-info/entry_points.txt +0 -0
  31. {klok_cli-1.0.0 → klok_cli-1.2.0}/klok_cli.egg-info/top_level.txt +0 -0
  32. {klok_cli-1.0.0 → klok_cli-1.2.0}/setup.cfg +0 -0
  33. {klok_cli-1.0.0 → klok_cli-1.2.0}/tests/test_mindful.py +0 -0
  34. {klok_cli-1.0.0 → klok_cli-1.2.0}/tests/test_storage.py +0 -0
  35. {klok_cli-1.0.0 → klok_cli-1.2.0}/tests/test_timeparse.py +0 -0
@@ -0,0 +1,222 @@
1
+ Metadata-Version: 2.4
2
+ Name: klok-cli
3
+ Version: 1.2.0
4
+ Summary: A batteries-included command-line time tracker with a plaintext backend.
5
+ Author: Rajat Singh
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/technomad641/klok
8
+ Project-URL: Repository, https://github.com/technomad641/klok
9
+ Project-URL: Issues, https://github.com/technomad641/klok/issues
10
+ Keywords: time-tracking,cli,timesheet,pomodoro,productivity
11
+ Classifier: Environment :: Console
12
+ Classifier: Intended Audience :: End Users/Desktop
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Office/Business
21
+ Classifier: Topic :: Utilities
22
+ Requires-Python: >=3.9
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Dynamic: license-file
26
+
27
+ # klok
28
+
29
+ [![CI](https://github.com/technomad641/klok/actions/workflows/ci.yml/badge.svg)](https://github.com/technomad641/klok/actions/workflows/ci.yml)
30
+ [![PyPI](https://img.shields.io/pypi/v/klok-cli.svg)](https://pypi.org/project/klok-cli/)
31
+ [![Python versions](https://img.shields.io/pypi/pyversions/klok-cli.svg)](https://pypi.org/project/klok-cli/)
32
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
33
+
34
+ **A command-line time tracker with a plaintext backend and zero dependencies —
35
+ that tracks not just where your time went, but how it felt.**
36
+
37
+ <p align="center">
38
+ <img src="docs/images/terminal-demo.gif" alt="Animated: klok start writing +deep, check status, stop, and a report for today, typed in a terminal" width="680">
39
+ </p>
40
+
41
+ klok brings together the features people actually use from Timetrap, Timewarrior,
42
+ Watson, utt, Bartib and friends — tags, timesheets, interval surgery, pomodoro,
43
+ exports — and adds a mindful side most trackers don't have: guided breathing,
44
+ sitting timers, and mood check-ins. It stores everything in one hand-editable
45
+ JSONL file and depends on nothing but the Python standard library.
46
+
47
+ ## Highlights
48
+
49
+ - **Zero runtime dependencies.** Pure standard library, Python 3.9+. Nothing to
50
+ audit, nothing to break.
51
+ - **One plaintext file is the whole database.** `frames.jsonl` diffs cleanly in
52
+ git, syncs with any file tool, and can be edited by hand.
53
+ - **A CLI built for humans.** ~70 commands behind grouped help, "did you mean?"
54
+ typo suggestions, and time parsing that takes `9am`, `-15m`, `since monday` or
55
+ `2 hours ago`.
56
+ - **Correct under pressure.** Atomic writes, cross-platform advisory file
57
+ locking, and 100 levels of `undo`.
58
+ - **Tested and portable.** 170 tests; CI runs the full suite on Linux, macOS and
59
+ Windows across Python 3.9–3.13.
60
+ - **A point of view.** Mood/energy/stress check-ins, breathing and meditation
61
+ are first-class — because how time felt is worth as much as where it went.
62
+
63
+ ## Quick start
64
+
65
+ ```sh
66
+ pip install klok-cli # or: pipx install klok-cli
67
+ ```
68
+
69
+ ```sh
70
+ klok start acme +api -n "auth endpoint" # begin, with a project, a tag, a note
71
+ klok status # what's running right now
72
+ klok stop # stop the clock
73
+ klok report :week # where the week went
74
+ klok breathe # sixty seconds, box breathing
75
+ ```
76
+
77
+ The package is `klok-cli` on PyPI; the installed command is plain `klok`. It also
78
+ runs straight from a checkout: `PYTHONPATH=. python3 -m klok status`.
79
+
80
+ ## What it does
81
+
82
+ A curated taste — see the **[full reference](docs/reference.md)** for every
83
+ command, or run `klok --help`.
84
+
85
+ **Track time the way you work.** Start and stop with projects and `+tags`, record
86
+ intervals after the fact, or fix them later — `move`, `split`, `join`, `fill`,
87
+ and `undo` are all there.
88
+
89
+ ```sh
90
+ klok track 09:00 to 11:30 acme +api # log a finished interval
91
+ klok add internal +email # name what you just did, after the fact
92
+ klok edit @1 --set-project acme # @1 is the newest entry
93
+ ```
94
+
95
+ **See where it went.** Summaries, per-project/tag breakdowns, bar charts, a
96
+ weekday × hour punchcard, and gap-finding.
97
+
98
+ <p align="center">
99
+ <img src="docs/images/report.png" alt="klok report :week broken down by project and tag, with a per-day bar chart" width="690">
100
+ </p>
101
+
102
+ ```sh
103
+ klok report :month --entries # totals per project, broken down by tag
104
+ klok chart :month --by day # a bar chart per calendar day
105
+ klok export :month -f csv # also: ical, ledger, timeclock, md, json, tsv
106
+ ```
107
+
108
+ **Keep contexts apart.** Separate timesheets keep a client's hours out of your
109
+ own, and focus timers double as trackers.
110
+
111
+ ```sh
112
+ klok sheet client-x # switch timesheets
113
+ klok pomodoro acme +deep --rounds 4 # recorded as real entries
114
+ ```
115
+
116
+ ## The mindful side
117
+
118
+ Practice is tracked like everything else, but on its own sheet — so a month of
119
+ sitting never lands in a client's invoice. Guided breathing follows named
120
+ patterns (box, 4-7-8, coherent), meditation rings bells on a schedule, and
121
+ check-ins capture mood, energy and stress on a 1–5 scale.
122
+
123
+ <p align="center">
124
+ <img src="docs/images/box-breathing.gif" alt="Animated box-breathing guide: a marker traces a square through inhale, hold, exhale and rest while a circle expands and contracts" width="340">
125
+ </p>
126
+
127
+ ```sh
128
+ klok breathe 4-7-8 # a named pattern, or custom counts
129
+ klok meditate 20m --interval-bell 5m
130
+ klok checkin --mood 4 --energy 3 --stress 2
131
+ klok mindful :month # sessions, time, averages, streaks
132
+ ```
133
+
134
+ ## What drains you, what lifts you
135
+
136
+ The thing no other tracker does: klok joins *how you felt* to *what you were
137
+ doing*. Rate a day's blocks in about twenty seconds, then let klok tell you which
138
+ work costs you energy and which gives it back — from your own private, local data,
139
+ no cloud and no screen surveillance.
140
+
141
+ ```sh
142
+ klok review # walk today's blocks, rate each 1–5 (a digit, then Enter)
143
+ klok stop --felt 4 # or rate a block the moment you stop it
144
+ klok digest :week # what drained vs lifted you, in plain language
145
+ klok digest :month -o energy.txt # write a shareable copy
146
+ ```
147
+
148
+ `klok review` asks one quick energy rating per tracked block (blank skips, `b`
149
+ goes back, `q` quits), so the data stays cheap to keep. `klok digest` then reports
150
+ the projects and tags whose energy sits clearly above or below your average, and
151
+ only once there's enough rated data to trust it — the footer always says how many
152
+ blocks it's working from.
153
+
154
+ ```text
155
+ +reviews drains you
156
+ averages 1.3 points below your overall energy over 7 blocks
157
+ deep work lifts you
158
+ averages 0.9 points above your overall energy over 11 blocks
159
+
160
+ Based on 34 rated blocks across 12 days. Rate more with `klok review` for sharper results.
161
+ ```
162
+
163
+ ## A web dashboard
164
+
165
+ ```sh
166
+ klok dashboard # the last six weeks, opened in your browser
167
+ klok dashboard :month # any range the reports accept
168
+ klok dashboard --demo # try it with sample data first
169
+ ```
170
+
171
+ **Hours & Feelings** reads `frames.jsonl` and `checkins.jsonl` and shows not only
172
+ where time went but how it felt, joining each check-in to whatever you were
173
+ tracking at that moment. It has an energy–time map (every project placed by hours
174
+ and energy), a deep-work streak, a mood calendar, trend lines, and a box-breathing
175
+ pause built on the same patterns as `klok breathe`.
176
+
177
+ The page is a single offline HTML file written to your data directory: no server,
178
+ nothing fetched, no new dependencies. A copy with demo data lives at
179
+ **[`docs/dashboard/hours-and-feelings.html`](docs/dashboard/hours-and-feelings.html)**.
180
+
181
+ ## How it's built
182
+
183
+ A flat package in `klok/`, layered cleanly: a small dataclass model (`Frame`), a
184
+ lock-protected plaintext store with atomic writes and undo, pure helper modules
185
+ for time parsing / exports / reporting, and one command layer that wires them
186
+ together. The whole data model is a single record type; everything else —
187
+ reports, exports, interval surgery, focus timers, mood — operates on it.
188
+
189
+ - **Testable by design.** Timers take injected clocks, so the suite never
190
+ actually sleeps; commands run end-to-end in-process against a temp home.
191
+ - **Tolerant input, strict output.** The loader accepts hand-edited files and
192
+ imports from other trackers; writes are atomic and locked.
193
+ - **Shipped properly.** PyPI releases go out via GitHub Actions with Trusted
194
+ Publishing (OIDC) — no stored tokens.
195
+
196
+ ## Data format
197
+
198
+ Everything lives in one directory (`$KLOK_HOME`, else `$XDG_DATA_HOME/klok`, else
199
+ `~/.local/share/klok`). `frames.jsonl` is the database — one JSON object per line:
200
+
201
+ ```json
202
+ {"id": "7d2d3734", "start": "2026-08-31T09:00:00+02:00", "stop": "2026-08-31T10:30:00+02:00", "project": "acme", "tags": ["api"], "note": "auth endpoint", "sheet": "default"}
203
+ ```
204
+
205
+ ## Tests
206
+
207
+ ```sh
208
+ cd klok && PYTHONPATH=. python3 -m unittest discover -s tests -t .
209
+ ```
210
+
211
+ 170 tests cover the time parser, the store (undo, locking, overlaps, gaps), the
212
+ breathing and sitting timers, the exporters, and every command end to end.
213
+
214
+ ## Scope
215
+
216
+ klok records what you tell it and what its own timers observe — no screen-time
217
+ capture, no sync server (a synced `frames.jsonl` covers that ground), and no
218
+ health claims: the breathing patterns and bells are a pacer, not advice.
219
+
220
+ ## Licence
221
+
222
+ MIT. See [LICENSE](LICENSE).
@@ -0,0 +1,196 @@
1
+ # klok
2
+
3
+ [![CI](https://github.com/technomad641/klok/actions/workflows/ci.yml/badge.svg)](https://github.com/technomad641/klok/actions/workflows/ci.yml)
4
+ [![PyPI](https://img.shields.io/pypi/v/klok-cli.svg)](https://pypi.org/project/klok-cli/)
5
+ [![Python versions](https://img.shields.io/pypi/pyversions/klok-cli.svg)](https://pypi.org/project/klok-cli/)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
7
+
8
+ **A command-line time tracker with a plaintext backend and zero dependencies —
9
+ that tracks not just where your time went, but how it felt.**
10
+
11
+ <p align="center">
12
+ <img src="docs/images/terminal-demo.gif" alt="Animated: klok start writing +deep, check status, stop, and a report for today, typed in a terminal" width="680">
13
+ </p>
14
+
15
+ klok brings together the features people actually use from Timetrap, Timewarrior,
16
+ Watson, utt, Bartib and friends — tags, timesheets, interval surgery, pomodoro,
17
+ exports — and adds a mindful side most trackers don't have: guided breathing,
18
+ sitting timers, and mood check-ins. It stores everything in one hand-editable
19
+ JSONL file and depends on nothing but the Python standard library.
20
+
21
+ ## Highlights
22
+
23
+ - **Zero runtime dependencies.** Pure standard library, Python 3.9+. Nothing to
24
+ audit, nothing to break.
25
+ - **One plaintext file is the whole database.** `frames.jsonl` diffs cleanly in
26
+ git, syncs with any file tool, and can be edited by hand.
27
+ - **A CLI built for humans.** ~70 commands behind grouped help, "did you mean?"
28
+ typo suggestions, and time parsing that takes `9am`, `-15m`, `since monday` or
29
+ `2 hours ago`.
30
+ - **Correct under pressure.** Atomic writes, cross-platform advisory file
31
+ locking, and 100 levels of `undo`.
32
+ - **Tested and portable.** 170 tests; CI runs the full suite on Linux, macOS and
33
+ Windows across Python 3.9–3.13.
34
+ - **A point of view.** Mood/energy/stress check-ins, breathing and meditation
35
+ are first-class — because how time felt is worth as much as where it went.
36
+
37
+ ## Quick start
38
+
39
+ ```sh
40
+ pip install klok-cli # or: pipx install klok-cli
41
+ ```
42
+
43
+ ```sh
44
+ klok start acme +api -n "auth endpoint" # begin, with a project, a tag, a note
45
+ klok status # what's running right now
46
+ klok stop # stop the clock
47
+ klok report :week # where the week went
48
+ klok breathe # sixty seconds, box breathing
49
+ ```
50
+
51
+ The package is `klok-cli` on PyPI; the installed command is plain `klok`. It also
52
+ runs straight from a checkout: `PYTHONPATH=. python3 -m klok status`.
53
+
54
+ ## What it does
55
+
56
+ A curated taste — see the **[full reference](docs/reference.md)** for every
57
+ command, or run `klok --help`.
58
+
59
+ **Track time the way you work.** Start and stop with projects and `+tags`, record
60
+ intervals after the fact, or fix them later — `move`, `split`, `join`, `fill`,
61
+ and `undo` are all there.
62
+
63
+ ```sh
64
+ klok track 09:00 to 11:30 acme +api # log a finished interval
65
+ klok add internal +email # name what you just did, after the fact
66
+ klok edit @1 --set-project acme # @1 is the newest entry
67
+ ```
68
+
69
+ **See where it went.** Summaries, per-project/tag breakdowns, bar charts, a
70
+ weekday × hour punchcard, and gap-finding.
71
+
72
+ <p align="center">
73
+ <img src="docs/images/report.png" alt="klok report :week broken down by project and tag, with a per-day bar chart" width="690">
74
+ </p>
75
+
76
+ ```sh
77
+ klok report :month --entries # totals per project, broken down by tag
78
+ klok chart :month --by day # a bar chart per calendar day
79
+ klok export :month -f csv # also: ical, ledger, timeclock, md, json, tsv
80
+ ```
81
+
82
+ **Keep contexts apart.** Separate timesheets keep a client's hours out of your
83
+ own, and focus timers double as trackers.
84
+
85
+ ```sh
86
+ klok sheet client-x # switch timesheets
87
+ klok pomodoro acme +deep --rounds 4 # recorded as real entries
88
+ ```
89
+
90
+ ## The mindful side
91
+
92
+ Practice is tracked like everything else, but on its own sheet — so a month of
93
+ sitting never lands in a client's invoice. Guided breathing follows named
94
+ patterns (box, 4-7-8, coherent), meditation rings bells on a schedule, and
95
+ check-ins capture mood, energy and stress on a 1–5 scale.
96
+
97
+ <p align="center">
98
+ <img src="docs/images/box-breathing.gif" alt="Animated box-breathing guide: a marker traces a square through inhale, hold, exhale and rest while a circle expands and contracts" width="340">
99
+ </p>
100
+
101
+ ```sh
102
+ klok breathe 4-7-8 # a named pattern, or custom counts
103
+ klok meditate 20m --interval-bell 5m
104
+ klok checkin --mood 4 --energy 3 --stress 2
105
+ klok mindful :month # sessions, time, averages, streaks
106
+ ```
107
+
108
+ ## What drains you, what lifts you
109
+
110
+ The thing no other tracker does: klok joins *how you felt* to *what you were
111
+ doing*. Rate a day's blocks in about twenty seconds, then let klok tell you which
112
+ work costs you energy and which gives it back — from your own private, local data,
113
+ no cloud and no screen surveillance.
114
+
115
+ ```sh
116
+ klok review # walk today's blocks, rate each 1–5 (a digit, then Enter)
117
+ klok stop --felt 4 # or rate a block the moment you stop it
118
+ klok digest :week # what drained vs lifted you, in plain language
119
+ klok digest :month -o energy.txt # write a shareable copy
120
+ ```
121
+
122
+ `klok review` asks one quick energy rating per tracked block (blank skips, `b`
123
+ goes back, `q` quits), so the data stays cheap to keep. `klok digest` then reports
124
+ the projects and tags whose energy sits clearly above or below your average, and
125
+ only once there's enough rated data to trust it — the footer always says how many
126
+ blocks it's working from.
127
+
128
+ ```text
129
+ +reviews drains you
130
+ averages 1.3 points below your overall energy over 7 blocks
131
+ deep work lifts you
132
+ averages 0.9 points above your overall energy over 11 blocks
133
+
134
+ Based on 34 rated blocks across 12 days. Rate more with `klok review` for sharper results.
135
+ ```
136
+
137
+ ## A web dashboard
138
+
139
+ ```sh
140
+ klok dashboard # the last six weeks, opened in your browser
141
+ klok dashboard :month # any range the reports accept
142
+ klok dashboard --demo # try it with sample data first
143
+ ```
144
+
145
+ **Hours & Feelings** reads `frames.jsonl` and `checkins.jsonl` and shows not only
146
+ where time went but how it felt, joining each check-in to whatever you were
147
+ tracking at that moment. It has an energy–time map (every project placed by hours
148
+ and energy), a deep-work streak, a mood calendar, trend lines, and a box-breathing
149
+ pause built on the same patterns as `klok breathe`.
150
+
151
+ The page is a single offline HTML file written to your data directory: no server,
152
+ nothing fetched, no new dependencies. A copy with demo data lives at
153
+ **[`docs/dashboard/hours-and-feelings.html`](docs/dashboard/hours-and-feelings.html)**.
154
+
155
+ ## How it's built
156
+
157
+ A flat package in `klok/`, layered cleanly: a small dataclass model (`Frame`), a
158
+ lock-protected plaintext store with atomic writes and undo, pure helper modules
159
+ for time parsing / exports / reporting, and one command layer that wires them
160
+ together. The whole data model is a single record type; everything else —
161
+ reports, exports, interval surgery, focus timers, mood — operates on it.
162
+
163
+ - **Testable by design.** Timers take injected clocks, so the suite never
164
+ actually sleeps; commands run end-to-end in-process against a temp home.
165
+ - **Tolerant input, strict output.** The loader accepts hand-edited files and
166
+ imports from other trackers; writes are atomic and locked.
167
+ - **Shipped properly.** PyPI releases go out via GitHub Actions with Trusted
168
+ Publishing (OIDC) — no stored tokens.
169
+
170
+ ## Data format
171
+
172
+ Everything lives in one directory (`$KLOK_HOME`, else `$XDG_DATA_HOME/klok`, else
173
+ `~/.local/share/klok`). `frames.jsonl` is the database — one JSON object per line:
174
+
175
+ ```json
176
+ {"id": "7d2d3734", "start": "2026-08-31T09:00:00+02:00", "stop": "2026-08-31T10:30:00+02:00", "project": "acme", "tags": ["api"], "note": "auth endpoint", "sheet": "default"}
177
+ ```
178
+
179
+ ## Tests
180
+
181
+ ```sh
182
+ cd klok && PYTHONPATH=. python3 -m unittest discover -s tests -t .
183
+ ```
184
+
185
+ 170 tests cover the time parser, the store (undo, locking, overlaps, gaps), the
186
+ breathing and sitting timers, the exporters, and every command end to end.
187
+
188
+ ## Scope
189
+
190
+ klok records what you tell it and what its own timers observe — no screen-time
191
+ capture, no sync server (a synced `frames.jsonl` covers that ground), and no
192
+ health claims: the breathing patterns and bells are a pacer, not advice.
193
+
194
+ ## Licence
195
+
196
+ MIT. See [LICENSE](LICENSE).
@@ -1,3 +1,3 @@
1
1
  """klok - a command-line time tracker with a plaintext backend."""
2
2
 
3
- __version__ = "1.0.0"
3
+ __version__ = "1.2.0"