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.
- klok_cli-1.2.0/PKG-INFO +222 -0
- klok_cli-1.2.0/README.md +196 -0
- {klok_cli-1.0.0 → klok_cli-1.2.0}/klok/__init__.py +1 -1
- {klok_cli-1.0.0 → klok_cli-1.2.0}/klok/cli.py +229 -10
- {klok_cli-1.0.0 → klok_cli-1.2.0}/klok/config.py +10 -2
- klok_cli-1.2.0/klok/dashboard.html +1063 -0
- klok_cli-1.2.0/klok/dashboard.py +105 -0
- {klok_cli-1.0.0 → klok_cli-1.2.0}/klok/focus.py +3 -2
- {klok_cli-1.0.0 → klok_cli-1.2.0}/klok/formats.py +6 -2
- klok_cli-1.2.0/klok/insights.py +107 -0
- {klok_cli-1.0.0 → klok_cli-1.2.0}/klok/mindful.py +37 -0
- klok_cli-1.2.0/klok/pairing.py +39 -0
- {klok_cli-1.0.0 → klok_cli-1.2.0}/klok/storage.py +85 -32
- klok_cli-1.2.0/klok_cli.egg-info/PKG-INFO +222 -0
- {klok_cli-1.0.0 → klok_cli-1.2.0}/klok_cli.egg-info/SOURCES.txt +6 -0
- {klok_cli-1.0.0 → klok_cli-1.2.0}/pyproject.toml +5 -1
- {klok_cli-1.0.0 → klok_cli-1.2.0}/tests/test_cli.py +356 -2
- klok_cli-1.2.0/tests/test_insights.py +144 -0
- klok_cli-1.2.0/tests/test_pairing.py +91 -0
- klok_cli-1.0.0/PKG-INFO +0 -466
- klok_cli-1.0.0/README.md +0 -440
- klok_cli-1.0.0/klok_cli.egg-info/PKG-INFO +0 -466
- {klok_cli-1.0.0 → klok_cli-1.2.0}/LICENSE +0 -0
- {klok_cli-1.0.0 → klok_cli-1.2.0}/klok/__main__.py +0 -0
- {klok_cli-1.0.0 → klok_cli-1.2.0}/klok/model.py +0 -0
- {klok_cli-1.0.0 → klok_cli-1.2.0}/klok/report.py +0 -0
- {klok_cli-1.0.0 → klok_cli-1.2.0}/klok/timeparse.py +0 -0
- {klok_cli-1.0.0 → klok_cli-1.2.0}/klok/utils.py +0 -0
- {klok_cli-1.0.0 → klok_cli-1.2.0}/klok_cli.egg-info/dependency_links.txt +0 -0
- {klok_cli-1.0.0 → klok_cli-1.2.0}/klok_cli.egg-info/entry_points.txt +0 -0
- {klok_cli-1.0.0 → klok_cli-1.2.0}/klok_cli.egg-info/top_level.txt +0 -0
- {klok_cli-1.0.0 → klok_cli-1.2.0}/setup.cfg +0 -0
- {klok_cli-1.0.0 → klok_cli-1.2.0}/tests/test_mindful.py +0 -0
- {klok_cli-1.0.0 → klok_cli-1.2.0}/tests/test_storage.py +0 -0
- {klok_cli-1.0.0 → klok_cli-1.2.0}/tests/test_timeparse.py +0 -0
klok_cli-1.2.0/PKG-INFO
ADDED
|
@@ -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
|
+
[](https://github.com/technomad641/klok/actions/workflows/ci.yml)
|
|
30
|
+
[](https://pypi.org/project/klok-cli/)
|
|
31
|
+
[](https://pypi.org/project/klok-cli/)
|
|
32
|
+
[](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).
|
klok_cli-1.2.0/README.md
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
# klok
|
|
2
|
+
|
|
3
|
+
[](https://github.com/technomad641/klok/actions/workflows/ci.yml)
|
|
4
|
+
[](https://pypi.org/project/klok-cli/)
|
|
5
|
+
[](https://pypi.org/project/klok-cli/)
|
|
6
|
+
[](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).
|