klok-cli 1.0.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.0.0/LICENSE +21 -0
- klok_cli-1.0.0/PKG-INFO +466 -0
- klok_cli-1.0.0/README.md +440 -0
- klok_cli-1.0.0/klok/__init__.py +3 -0
- klok_cli-1.0.0/klok/__main__.py +4 -0
- klok_cli-1.0.0/klok/cli.py +1816 -0
- klok_cli-1.0.0/klok/config.py +162 -0
- klok_cli-1.0.0/klok/focus.py +169 -0
- klok_cli-1.0.0/klok/formats.py +169 -0
- klok_cli-1.0.0/klok/mindful.py +434 -0
- klok_cli-1.0.0/klok/model.py +111 -0
- klok_cli-1.0.0/klok/report.py +308 -0
- klok_cli-1.0.0/klok/storage.py +327 -0
- klok_cli-1.0.0/klok/timeparse.py +417 -0
- klok_cli-1.0.0/klok/utils.py +115 -0
- klok_cli-1.0.0/klok_cli.egg-info/PKG-INFO +466 -0
- klok_cli-1.0.0/klok_cli.egg-info/SOURCES.txt +24 -0
- klok_cli-1.0.0/klok_cli.egg-info/dependency_links.txt +1 -0
- klok_cli-1.0.0/klok_cli.egg-info/entry_points.txt +2 -0
- klok_cli-1.0.0/klok_cli.egg-info/top_level.txt +1 -0
- klok_cli-1.0.0/pyproject.toml +41 -0
- klok_cli-1.0.0/setup.cfg +4 -0
- klok_cli-1.0.0/tests/test_cli.py +598 -0
- klok_cli-1.0.0/tests/test_mindful.py +218 -0
- klok_cli-1.0.0/tests/test_storage.py +190 -0
- klok_cli-1.0.0/tests/test_timeparse.py +136 -0
klok_cli-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Rajat Singh
|
|
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.
|
klok_cli-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,466 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: klok-cli
|
|
3
|
+
Version: 1.0.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
|
+
[](LICENSE)
|
|
32
|
+
|
|
33
|
+
A command-line time tracker that pulls together the features people actually
|
|
34
|
+
use from Timetrap, Timewarrior, Watson, utt, Bartib, Helm and friends — plus
|
|
35
|
+
breathing, sitting and mood check-ins — in one tool, with a plaintext backend
|
|
36
|
+
and no dependencies beyond Python 3.9.
|
|
37
|
+
|
|
38
|
+
```console
|
|
39
|
+
$ klok start acme +api -n "auth endpoint"
|
|
40
|
+
Starting acme +api at 2026-08-31 09:00 [7d2d3734]
|
|
41
|
+
|
|
42
|
+
$ klok status
|
|
43
|
+
acme +api 1h 30m (started 09:00, an hour ago)
|
|
44
|
+
sheet default | today 1h 30m | id 7d2d3734
|
|
45
|
+
|
|
46
|
+
$ klok stop
|
|
47
|
+
Stopped acme +api after 1h 30m [7d2d3734]
|
|
48
|
+
|
|
49
|
+
$ klok report :week
|
|
50
|
+
Mon 31 August 2026 -> Sun 06 September 2026
|
|
51
|
+
|
|
52
|
+
acme - 3h 00m
|
|
53
|
+
+api 1h 30m
|
|
54
|
+
+docs 45m
|
|
55
|
+
+review 45m
|
|
56
|
+
|
|
57
|
+
internal - 55m
|
|
58
|
+
+meeting 40m
|
|
59
|
+
+email 15m
|
|
60
|
+
|
|
61
|
+
Total: 3h 55m
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Install
|
|
65
|
+
|
|
66
|
+
```sh
|
|
67
|
+
pip install klok-cli # or: pipx install klok-cli
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
The PyPI package is `klok-cli` ("klok" itself is an unrelated, empty
|
|
71
|
+
placeholder someone else registered) but the installed command is plain
|
|
72
|
+
`klok`. No dependencies.
|
|
73
|
+
|
|
74
|
+
To install from a checkout instead of PyPI:
|
|
75
|
+
|
|
76
|
+
```sh
|
|
77
|
+
pip install --user . # or: pipx install .
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
It also runs straight from a checkout with no install at all:
|
|
81
|
+
|
|
82
|
+
```sh
|
|
83
|
+
PYTHONPATH=. python3 -m klok status
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Why this exists
|
|
87
|
+
|
|
88
|
+
Each of the well-loved terminal time trackers is missing one thing the others
|
|
89
|
+
have. Timewarrior has the best interval surgery (`join`, `split`, `fill`,
|
|
90
|
+
`gaps`) but no pomodoro. Watson has the nicest project/tag model but no
|
|
91
|
+
timesheets. Timetrap has sheets and a pile of export formats but no tags. utt
|
|
92
|
+
has the "log it after the fact" flow nobody else does. Helm and arttime are
|
|
93
|
+
lovely timers that record nothing.
|
|
94
|
+
|
|
95
|
+
klok takes the useful parts of each and keeps a single, boring data file.
|
|
96
|
+
|
|
97
|
+
### Feature map
|
|
98
|
+
|
|
99
|
+
| From | Feature | In klok |
|
|
100
|
+
| --- | --- | --- |
|
|
101
|
+
| **Timetrap** | `t in` / `t out` | `klok in` / `klok out` (aliases of `start`/`stop`) |
|
|
102
|
+
| | Timesheets you switch between | `klok sheet NAME`, `klok sheets`, `klok sheet -` |
|
|
103
|
+
| | `t archive` | `klok archive :lastmonth` |
|
|
104
|
+
| | Retroactive `--at` | `klok start --at 9am`, `klok stop --at -15m` |
|
|
105
|
+
| | Formatters (csv, ical, json, ledger) | `klok export -f csv\|ical\|json\|ledger\|timeclock\|md\|tsv` |
|
|
106
|
+
| | Rounding | `--round 15`, or `general.round` in config |
|
|
107
|
+
| **Timewarrior** | `start` / `stop` / `continue` | `klok start` / `stop` / `continue` |
|
|
108
|
+
| | Tags on intervals | `klok start acme +api +urgent`, `klok tag ID +x -y` |
|
|
109
|
+
| | `annotate` | `klok annotate ID "text"` |
|
|
110
|
+
| | `summary` with daily subtotals | `klok summary :week` |
|
|
111
|
+
| | Range hints (`:week`, `:lastmonth`) | same hints, plus `last 7 days`, `since monday` |
|
|
112
|
+
| | `join` / `split` / `lengthen` / `shorten` / `move` / `fill` | all present, same names |
|
|
113
|
+
| | `gaps` | `klok gaps :day --min 15m` |
|
|
114
|
+
| | Exclusions (working hours, days off) | `exclusions.hours`, `exclusions.days`, `exclusions.holidays` |
|
|
115
|
+
| | `undo` | `klok undo` (100 levels deep) |
|
|
116
|
+
| | Charts | `klok chart --by day\|project\|tag\|sheet\|punchcard` |
|
|
117
|
+
| **Watson** | `project +tag` model | same |
|
|
118
|
+
| | `status`, `cancel`, `restart`, `log`, `report` | same names |
|
|
119
|
+
| | `rename project\|tag OLD NEW` | `klok rename` (also renames sheets) |
|
|
120
|
+
| | `projects`, `tags` listings | `klok projects`, `klok tags` (with totals) |
|
|
121
|
+
| | `edit` in `$EDITOR` | `klok edit` — or change fields inline with flags |
|
|
122
|
+
| | `aggregate` daily totals | `klok chart --by day`, `klok stats` |
|
|
123
|
+
| **utt** | Name the activity *after* doing it | `klok add acme +api` closes the open stretch |
|
|
124
|
+
| | `utt stretch` | `klok stretch` |
|
|
125
|
+
| | Break activities | tag them and filter with `-T break` |
|
|
126
|
+
| **Bartib** | Plaintext, hand-editable backend | JSONL, one entry per line |
|
|
127
|
+
| | `continue`, `last`, `change` | `klok continue`, `klok log --limit`, `klok switch` |
|
|
128
|
+
| | `sanity` check | `klok check` (overlaps, negatives, runaway timers) |
|
|
129
|
+
| **Helm / arttime** | Minimal countdown timer | `klok timer 25m --big --art coffee` |
|
|
130
|
+
| | Desktop notification + bell | automatic; `focus.notify`, `focus.bell` |
|
|
131
|
+
| **Focusd** | Focus sessions | `klok pomodoro acme +deep --rounds 4` — recorded as real entries |
|
|
132
|
+
| **feeling** | Mood tracking over time | `klok checkin --mood 4 --energy 3`, `klok mood :month` |
|
|
133
|
+
| *(new)* | Guided breathing | `klok breathe box`, `klok breathe 4-7-8 --for 5m` |
|
|
134
|
+
| *(new)* | Timed sitting with bells | `klok meditate 20m --interval-bell 5m` |
|
|
135
|
+
| *(new)* | Practice streaks | `klok mindful :month` |
|
|
136
|
+
|
|
137
|
+
## Finding your way around
|
|
138
|
+
|
|
139
|
+
`klok --help` doesn't dump all 70-odd commands and aliases in one
|
|
140
|
+
alphabetical wall — it opens with a five-line quick start, then groups the
|
|
141
|
+
rest (Tracking, Fixing entries, Reporting, Sheets & config, Focus &
|
|
142
|
+
mindfulness) so the shape of the tool is visible at a glance. Each
|
|
143
|
+
command's own `--help` still has the full detail — `klok start --help`,
|
|
144
|
+
`klok breathe --help`, and so on.
|
|
145
|
+
|
|
146
|
+
```console
|
|
147
|
+
$ klok --help
|
|
148
|
+
Quick start:
|
|
149
|
+
klok start acme +api start tracking, tag it
|
|
150
|
+
klok stop stop the clock
|
|
151
|
+
klok status what's running right now
|
|
152
|
+
klok report :week where the week went
|
|
153
|
+
klok breathe sixty seconds, box breathing
|
|
154
|
+
|
|
155
|
+
Tracking:
|
|
156
|
+
start Start tracking a project now (or at a given time). (in, on)
|
|
157
|
+
stop Stop the running entry. (out, off)
|
|
158
|
+
...
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
A typo in a command name gets a one-line correction instead of the default
|
|
162
|
+
list of all seventy choices:
|
|
163
|
+
|
|
164
|
+
```console
|
|
165
|
+
$ klok statuss
|
|
166
|
+
klok: unknown command 'statuss' - did you mean 'status'?
|
|
167
|
+
Run `klok --help` for the full list.
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
And a brand new install says what to do next, rather than just "nothing
|
|
171
|
+
running":
|
|
172
|
+
|
|
173
|
+
```console
|
|
174
|
+
$ klok status
|
|
175
|
+
Nothing tracked yet.
|
|
176
|
+
Try `klok start acme +api` to begin, or `klok --help` for the full picture.
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Commands
|
|
180
|
+
|
|
181
|
+
### Tracking
|
|
182
|
+
|
|
183
|
+
```sh
|
|
184
|
+
klok start acme +api -n "auth endpoint" # aliases: in, on
|
|
185
|
+
klok start acme --at 9am # retroactive start
|
|
186
|
+
klok stop --at -15m # stopped a quarter hour ago
|
|
187
|
+
klok cancel # discard the running entry
|
|
188
|
+
klok status # aliases: now, current
|
|
189
|
+
klok switch internal +meeting # stop and start at one instant
|
|
190
|
+
klok continue # same project and tags as last time
|
|
191
|
+
klok track 09:00 to 11:30 acme +api # record a finished interval
|
|
192
|
+
klok track --from 09:00 -d 45m acme # ...or give a length
|
|
193
|
+
klok add internal +email # close the gap since the last entry
|
|
194
|
+
klok stretch # pull an entry back to the previous one
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
`start` stops whatever was running (set `general.autostop = false`, or pass
|
|
198
|
+
`--no-stop`, to make that an error instead).
|
|
199
|
+
|
|
200
|
+
### Fixing what you recorded
|
|
201
|
+
|
|
202
|
+
Entries are addressed by id prefix (`7d2d`), by position (`@1` is the newest,
|
|
203
|
+
`@2` the one before), or by `@` for "the running one, or the last one".
|
|
204
|
+
|
|
205
|
+
```sh
|
|
206
|
+
klok annotate @1 "sprint planning"
|
|
207
|
+
klok tag @1 +urgent -meeting # + adds, - removes
|
|
208
|
+
klok edit @1 --set-project acme --tags api docs
|
|
209
|
+
klok edit @1 # opens $EDITOR with the entry as JSON
|
|
210
|
+
klok edit --range :day # edit a whole day at once
|
|
211
|
+
klok move @1 08:00 # keep the length, change the start
|
|
212
|
+
klok lengthen @1 30m / klok shorten @1 15m
|
|
213
|
+
klok fill @1 # grow until it touches its neighbours
|
|
214
|
+
klok split @1 --at 10:15 / --into 3
|
|
215
|
+
klok join 7d2d e57b # merge entries, union their tags
|
|
216
|
+
klok delete @1 @2
|
|
217
|
+
klok undo # every change is undoable
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Reporting
|
|
221
|
+
|
|
222
|
+
```sh
|
|
223
|
+
klok log :week # entries day by day (aliases: display, list)
|
|
224
|
+
klok summary :day # dense table with daily subtotals
|
|
225
|
+
klok report :month --entries # totals per project, broken down by tag
|
|
226
|
+
klok chart :month --by day # bar chart per calendar day
|
|
227
|
+
klok chart :month --by punchcard # weekday x hour heat map
|
|
228
|
+
klok gaps :day --min 15m # untracked stretches
|
|
229
|
+
klok stats :month # totals, streak, busiest day
|
|
230
|
+
klok projects / klok tags # with totals
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
Every report takes the same filters:
|
|
234
|
+
|
|
235
|
+
```sh
|
|
236
|
+
-p, --project NAME repeatable; matches exactly, as a parent (acme matches acme.api), or as a glob
|
|
237
|
+
-t, --tag TAG repeatable; all listed tags must be present
|
|
238
|
+
-T, --exclude-tag TAG repeatable
|
|
239
|
+
--contains TEXT substring of project, tags or note
|
|
240
|
+
--sheet NAME a specific sheet
|
|
241
|
+
--all-sheets every sheet
|
|
242
|
+
-f, --format FMT text (default), json, csv, tsv, ical, ledger, timeclock, md
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### Time syntax
|
|
246
|
+
|
|
247
|
+
Anywhere klok takes a time: `now`, `noon`, `midnight`, `today`, `yesterday`,
|
|
248
|
+
`monday`, `last friday`, `9am`, `9:30pm`, `09:30`, `-15m`, `+1h30m`,
|
|
249
|
+
`2 hours ago`, `2026-08-31`, `2026-08-31 09:00`, `2026-08-31T09:00:00`, or a
|
|
250
|
+
unix timestamp.
|
|
251
|
+
|
|
252
|
+
Durations: `90` (minutes), `45s`, `25m`, `1h30m`, `1:30`, `2 hours`, `1w`.
|
|
253
|
+
|
|
254
|
+
Ranges: `:day` `:yesterday` `:week` `:lastweek` `:month` `:lastmonth`
|
|
255
|
+
`:quarter` `:year` `:lastyear` `:7d` `:30d` `:all`, plus `last 7 days`,
|
|
256
|
+
`since monday`, `2026-08-01 to 2026-08-31`, or a bare date for that one day.
|
|
257
|
+
`--from` / `--to` work too.
|
|
258
|
+
|
|
259
|
+
### Sheets
|
|
260
|
+
|
|
261
|
+
Separate timesheets, as in Timetrap — useful for keeping a client's hours apart
|
|
262
|
+
from your own.
|
|
263
|
+
|
|
264
|
+
```sh
|
|
265
|
+
klok sheet client-x # switch
|
|
266
|
+
klok sheet # print the active one
|
|
267
|
+
klok sheet - # back to the previous one
|
|
268
|
+
klok sheets # list, with totals
|
|
269
|
+
klok archive :lastmonth # move entries to _default so they leave reports
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Focus timers
|
|
273
|
+
|
|
274
|
+
```sh
|
|
275
|
+
klok timer 25m -m "Deep work" --big --art coffee
|
|
276
|
+
klok timer 10m -p acme -t review # also records the time
|
|
277
|
+
klok pomodoro acme +deep --rounds 4 # 4 x 25m work with breaks
|
|
278
|
+
klok pomodoro --work 50m --break 10m --no-prompt
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
Work rounds longer than a minute are recorded as ordinary entries, so they show
|
|
282
|
+
up in `report` alongside everything else. Notifications go through
|
|
283
|
+
`notify-send`, `terminal-notifier` or `osascript` when one is available, and
|
|
284
|
+
always ring the terminal bell.
|
|
285
|
+
|
|
286
|
+
### Mindfulness and meditation
|
|
287
|
+
|
|
288
|
+
Practice is tracked like everything else — but on its own sheet (`wellbeing`
|
|
289
|
+
by default), so a month of sitting never turns up in a client's invoice.
|
|
290
|
+
|
|
291
|
+
#### Breathing
|
|
292
|
+
|
|
293
|
+
```sh
|
|
294
|
+
klok breathe # the configured default, six rounds of box breathing
|
|
295
|
+
klok breathe 4-7-8 # any counts: in-hold-out, or in-hold-out-hold
|
|
296
|
+
klok breathe calm --for 5m # a named pattern, for a length instead of a round count
|
|
297
|
+
klok breathe --list # what the named patterns are
|
|
298
|
+
klok breathe box --plan # describe the session without running it
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
A pacer fills and empties a bar in time with the phase, naming each one and
|
|
302
|
+
counting it down. `Ctrl-C` stops it and still records what you did.
|
|
303
|
+
|
|
304
|
+
| Pattern | Counts | |
|
|
305
|
+
| --- | --- | --- |
|
|
306
|
+
| `box` | 4-4-4-4 | equal counts all round |
|
|
307
|
+
| `calm` | 4-0-6-0 | longer out-breath than in-breath |
|
|
308
|
+
| `coherent` | 5.5-0-5.5-0 | about five and a half breaths a minute |
|
|
309
|
+
| `relax` | 4-7-8-0 | the 4-7-8 count |
|
|
310
|
+
| `triangle` | 4-4-4-0 | no pause at the bottom |
|
|
311
|
+
| `even` | 5-0-5-0 | plain and symmetrical |
|
|
312
|
+
|
|
313
|
+
Custom counts work anywhere a name does: two counts are in and out
|
|
314
|
+
(`4-6`), three add the hold after the in-breath (`4-7-8`), four set every
|
|
315
|
+
phase (`5-2-7-2`).
|
|
316
|
+
|
|
317
|
+
#### Sitting
|
|
318
|
+
|
|
319
|
+
```sh
|
|
320
|
+
klok meditate # mindful.default_sit, ten minutes out of the box
|
|
321
|
+
klok meditate 20m --interval-bell 5m
|
|
322
|
+
klok meditate 30m --warmup 30s # a settling bell before the sit proper
|
|
323
|
+
klok meditate 15m --no-guidance # bells only, no prompts
|
|
324
|
+
klok meditate 20m --plan # when the bells will land
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
A progress line, a bell at the end (and at each interval), and — unless you
|
|
328
|
+
turn them off — a few short prompts along the way. Sits are recorded as
|
|
329
|
+
`mindfulness +meditation`; breathing as `mindfulness +breathing`.
|
|
330
|
+
|
|
331
|
+
#### Check-ins
|
|
332
|
+
|
|
333
|
+
```sh
|
|
334
|
+
klok checkin --mood 4 --energy 3 --stress 2 after standup
|
|
335
|
+
klok checkin --mood 2 --at 09:15 -t monday
|
|
336
|
+
klok checkin # prompts for the three scales when run in a terminal
|
|
337
|
+
klok mood :month # the entries, plus a trend line per scale
|
|
338
|
+
klok mood --json
|
|
339
|
+
klok checkin --delete @ # or by id prefix
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
Three optional 1–5 scales (mood, energy, stress) and a free-text note. `klok
|
|
343
|
+
mood` renders each scale as a sparkline with its average, and — once there are
|
|
344
|
+
enough days to compare — notes how mood sat on your busier days versus your
|
|
345
|
+
lighter ones. That is an observation about two averages, not a claim about
|
|
346
|
+
cause.
|
|
347
|
+
|
|
348
|
+
#### How the practice is going
|
|
349
|
+
|
|
350
|
+
```sh
|
|
351
|
+
klok mindful :month # sessions, time, averages, streaks, last practice
|
|
352
|
+
klok mindful :year --no-chart
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
#### Break nudge
|
|
356
|
+
|
|
357
|
+
Once a single unbroken stretch of work passes `mindful.break_after` (90
|
|
358
|
+
minutes by default), `klok status` says so and suggests a minute of breathing.
|
|
359
|
+
Set the key to empty to switch it off.
|
|
360
|
+
|
|
361
|
+
### Configuration
|
|
362
|
+
|
|
363
|
+
```sh
|
|
364
|
+
klok config list
|
|
365
|
+
klok config set general.round 15
|
|
366
|
+
klok config set exclusions.hours 09:00-18:00
|
|
367
|
+
klok config edit
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
| Key | Default | Meaning |
|
|
371
|
+
| --- | --- | --- |
|
|
372
|
+
| `general.default_project` | – | project for a bare `klok start` |
|
|
373
|
+
| `general.week_start` | `monday` | drives `:week` and the week charts |
|
|
374
|
+
| `general.round` | `0` | round durations up to N minutes in reports |
|
|
375
|
+
| `general.time_format` | `24` | `24` or `12` hour clock |
|
|
376
|
+
| `general.autostop` | `true` | `start` stops what was running |
|
|
377
|
+
| `general.color` | `auto` | `auto`, `always`, `never` (`NO_COLOR` is honoured) |
|
|
378
|
+
| `general.editor` | `$VISUAL`/`$EDITOR` | editor for `klok edit` |
|
|
379
|
+
| `general.confirm_new_project` | `false` | refuse unknown projects without `--force` |
|
|
380
|
+
| `exclusions.hours` | – | e.g. `09:00-18:00`; `gaps` ignores time outside |
|
|
381
|
+
| `exclusions.days` | – | e.g. `saturday,sunday` |
|
|
382
|
+
| `exclusions.holidays` | – | comma-separated `YYYY-MM-DD` dates |
|
|
383
|
+
| `focus.work` / `focus.break` / `focus.long_break` / `focus.rounds` | `25m` / `5m` / `15m` / `4` | pomodoro defaults |
|
|
384
|
+
| `focus.notify` / `focus.bell` / `focus.track` | `true` | timer behaviour |
|
|
385
|
+
| `mindful.project` | `mindfulness` | project practice is recorded against |
|
|
386
|
+
| `mindful.sheet` | `wellbeing` | sheet practice is recorded on |
|
|
387
|
+
| `mindful.track` | `true` | record practice at all |
|
|
388
|
+
| `mindful.pattern` | `box` | default breathing pattern |
|
|
389
|
+
| `mindful.breath_rounds` | `6` | default number of breaths |
|
|
390
|
+
| `mindful.default_sit` | `10m` | default length of `klok meditate` |
|
|
391
|
+
| `mindful.interval_bell` | – | default interval bell during a sit |
|
|
392
|
+
| `mindful.warmup` | – | default settling bell |
|
|
393
|
+
| `mindful.guidance` | `true` | show prompts during a sit |
|
|
394
|
+
| `mindful.break_after` | `90m` | when `klok status` suggests a pause (empty = never) |
|
|
395
|
+
|
|
396
|
+
### Where the data lives
|
|
397
|
+
|
|
398
|
+
```sh
|
|
399
|
+
klok where
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
Everything sits in one directory (`$KLOK_HOME`, else `$XDG_DATA_HOME/klok`,
|
|
403
|
+
else `~/.local/share/klok`):
|
|
404
|
+
|
|
405
|
+
```
|
|
406
|
+
frames.jsonl one JSON object per line, sorted by start time
|
|
407
|
+
checkins.jsonl mood/energy/stress check-ins, same shape
|
|
408
|
+
config.ini configuration
|
|
409
|
+
state.json which sheet is active
|
|
410
|
+
undo.jsonl the last 100 states, for klok undo
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
`frames.jsonl` is the whole database. It diffs well in git, syncs with any file
|
|
414
|
+
sync tool, and can be hand-edited:
|
|
415
|
+
|
|
416
|
+
```json
|
|
417
|
+
{"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"}
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
Writes are atomic and take a lock file, so a `klok stop` from a shell hook
|
|
421
|
+
cannot interleave with one from your prompt. Every mutation snapshots the
|
|
422
|
+
previous file first — `klok undo` walks back through them.
|
|
423
|
+
|
|
424
|
+
### Exports
|
|
425
|
+
|
|
426
|
+
```sh
|
|
427
|
+
klok export :month -f csv -o august.csv
|
|
428
|
+
klok export :month -f ical > august.ics
|
|
429
|
+
klok export :month -f timeclock | hledger -f - balance # ledger/hledger native
|
|
430
|
+
klok export :month -f md # paste into an invoice
|
|
431
|
+
klok import august.json # JSON, JSONL or CSV
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
### Shell completion
|
|
435
|
+
|
|
436
|
+
```sh
|
|
437
|
+
source <(klok completion bash) # or zsh
|
|
438
|
+
klok completion fish > ~/.config/fish/completions/klok.fish
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
## Tests
|
|
442
|
+
|
|
443
|
+
```sh
|
|
444
|
+
cd klok && PYTHONPATH=. python3 -m unittest discover -s tests -t .
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
170 tests covering the time parser, the store (including undo, locking,
|
|
448
|
+
overlaps and gaps), the breathing and sitting timers (driven by an injected
|
|
449
|
+
clock, so the suite stays fast), the exporters, and every command end to end.
|
|
450
|
+
|
|
451
|
+
## What it deliberately does not do
|
|
452
|
+
|
|
453
|
+
- **No automatic screen-time or app-usage capture.** Focusd-style monitoring
|
|
454
|
+
needs per-platform window hooks; klok records what you tell it, plus what its
|
|
455
|
+
own timers observe.
|
|
456
|
+
- **No sync server.** `export`/`import` and a synced `frames.jsonl` cover the
|
|
457
|
+
ground Watson's `sync` does, without a service to run.
|
|
458
|
+
- **No plugin/extension API.** The JSON and CSV exports are the extension
|
|
459
|
+
point.
|
|
460
|
+
- **No health claims.** The breathing patterns and sitting timers are a
|
|
461
|
+
pacer and a bell. klok is a tracker, not advice, and not a substitute for
|
|
462
|
+
care from someone qualified to give it.
|
|
463
|
+
|
|
464
|
+
## Licence
|
|
465
|
+
|
|
466
|
+
MIT. See [LICENSE](LICENSE).
|