tsk-todo 0.1.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.
@@ -0,0 +1,270 @@
1
+ Metadata-Version: 2.4
2
+ Name: tsk-todo
3
+ Version: 0.1.0
4
+ Summary: Minimal todo CLI for the terminal. Pure Python, zero dependencies.
5
+ Keywords: cli,todo,task,task-manager,productivity,terminal,gtd
6
+ Author: michaelrbarley
7
+ Author-email: michaelrbarley <301309661+michaelrbarley@users.noreply.github.com>
8
+ License-Expression: MIT
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Environment :: Console
11
+ Classifier: Intended Audience :: End Users/Desktop
12
+ Classifier: Operating System :: POSIX
13
+ Classifier: Programming Language :: Python :: 3 :: Only
14
+ Classifier: Topic :: Utilities
15
+ Requires-Python: >=3.11
16
+ Project-URL: Homepage, https://github.com/michaelrbarley/tsk-todo
17
+ Project-URL: Source, https://github.com/michaelrbarley/tsk-todo
18
+ Project-URL: Issues, https://github.com/michaelrbarley/tsk-todo/issues
19
+ Description-Content-Type: text/markdown
20
+
21
+ # tsk
22
+
23
+ A small task manager for the terminal.
24
+
25
+ ```
26
+ $ tsk add water the plants @home +garden due:tomorrow every:weekly
27
+ added 1: water the plants
28
+
29
+ $ tsk add fix the login bug @work +urgent due:yesterday p:h
30
+ added 2: fix the login bug
31
+
32
+ $ tsk
33
+ 2 H yesterday fix the login bug @work +urgent
34
+ 1 tomorrow water the plants @home +garden every:weekly
35
+ ```
36
+
37
+ No daemon, no config file, no dependencies. Your tasks live in one JSON file you can read.
38
+
39
+ ## Install
40
+
41
+ Needs Python 3.11 or newer.
42
+
43
+ ```
44
+ git clone https://github.com/michaelrbarley/tsk-todo
45
+ cd tsk-todo
46
+ uv tool install .
47
+ ```
48
+
49
+ The command is `tsk`. The package is `tsk-todo`, because `tsk` on PyPI belongs to something else.
50
+
51
+ Or run it from the clone without installing anything:
52
+
53
+ ```
54
+ uv run tsk
55
+ ```
56
+
57
+ ## The idea
58
+
59
+ You type what you mean and `tsk` works out which parts are metadata:
60
+
61
+ ```
62
+ tsk add renew the passport @admin +boring due:eom p:h
63
+ ```
64
+
65
+ `@admin` is the project, `+boring` is a tag, `due:eom` is the end of this month, `p:h` is high
66
+ priority. Everything left over is the task itself.
67
+
68
+ Only `due:`, `p:` and `every:` are read as attributes, so ordinary text stays ordinary:
69
+
70
+ ```
71
+ $ tsk add email bob@example.com about the invoice
72
+ $ tsk add fix the -v flag
73
+ $ tsk add ticket: replace the boiler
74
+ ```
75
+
76
+ None of those pick up a project, a tag or an attribute. If it is not a form `tsk` knows, it is
77
+ part of the description.
78
+
79
+ ## Commands
80
+
81
+ ```
82
+ tsk list pending tasks
83
+ tsk add <text> [attrs] add a task
84
+ tsk done <id>... complete tasks
85
+ tsk rm <id>... delete tasks
86
+ tsk edit <id> <attrs> change a task
87
+ tsk note <id> <text> attach a note
88
+ tsk show <id> show one task in full
89
+ tsk list [filters] list tasks
90
+ ```
91
+
92
+ `tsk 3` on its own is shorthand for `tsk show 3`.
93
+
94
+ `done` and `rm` take several ids at once: `tsk done 2 5 9`.
95
+
96
+ ## Attributes
97
+
98
+ Use these when adding or editing.
99
+
100
+ ```
101
+ @project set the project
102
+ +tag add a tag
103
+ -tag remove a tag, when editing
104
+ due:<when> set a due date
105
+ p:h|m|l set priority, high medium or low
106
+ every:<how> reschedule on completion
107
+ ```
108
+
109
+ Priority also accepts the full word, so `p:high` and `p:h` are the same.
110
+
111
+ Editing changes only what you name. Everything else is left alone.
112
+
113
+ ```
114
+ $ tsk edit 3 due:friday +urgent
115
+ updated 3: read the book
116
+ ```
117
+
118
+ To clear something, give it no value:
119
+
120
+ ```
121
+ $ tsk edit 3 due: p: every:
122
+ ```
123
+
124
+ A bare `@` clears the project. A leading `-` removes a tag.
125
+
126
+ ## Filters
127
+
128
+ ```
129
+ tsk +garden tagged garden
130
+ tsk -work not tagged work
131
+ tsk @home in the home project
132
+ tsk overdue past due
133
+ tsk due:friday due on or before friday
134
+ tsk done completed tasks
135
+ tsk all everything
136
+ tsk plants search descriptions and notes
137
+ ```
138
+
139
+ Filters combine, and `list` is optional:
140
+
141
+ ```
142
+ $ tsk @home +garden overdue
143
+ $ tsk list @work due:eow
144
+ ```
145
+
146
+ Bare words search. `tsk list dentist` finds anything with dentist in the description or in a note.
147
+
148
+ ## Dates
149
+
150
+ Anywhere a date is wanted:
151
+
152
+ ```
153
+ today, tomorrow, yesterday
154
+ monday .. sunday, or mon .. sun
155
+ 3d, 2w, 1m, 1y
156
+ eow, eom, eoy
157
+ 2026-08-01
158
+ ```
159
+
160
+ Weekday names mean the next one coming. On a Thursday, `due:thursday` is a week away, not today.
161
+
162
+ Month and year offsets land on a real date. `1m` from the 31st of January is the 28th of February,
163
+ not the 3rd of March.
164
+
165
+ Due dates are plain calendar dates. `due:friday` means Friday wherever you happen to be, and it
166
+ does not drift when you cross a timezone.
167
+
168
+ ## Repeats
169
+
170
+ ```
171
+ every:daily
172
+ every:weekdays
173
+ every:weekly
174
+ every:monthly
175
+ every:yearly
176
+ ```
177
+
178
+ A repeating task needs a due date. When you complete it, the next one is created for you:
179
+
180
+ ```
181
+ $ tsk done 1
182
+ done 1: water the plants
183
+ repeats as 5, due in 1 week
184
+ ```
185
+
186
+ The next date is worked out from the old due date, then rolled forward until it is in the future.
187
+ Finish a daily task five days late and the next one is due tomorrow, not last week. You never come
188
+ back to a pile of overdue copies.
189
+
190
+ Notes do not carry over. The completed task keeps them.
191
+
192
+ ## Notes
193
+
194
+ ```
195
+ $ tsk note 3 the ferns look worse than the rest
196
+ noted on 3: water the plants
197
+ ```
198
+
199
+ Tasks with notes are marked with a `*` in the list. `tsk show 3` prints them.
200
+
201
+ ## Ordering
202
+
203
+ Tasks sort by due date, then priority, then id. That is the whole rule. Nothing is scored or
204
+ weighted behind your back, so the order is always one you can predict and explain.
205
+
206
+ Undated tasks sort last. They are not urgent, they are just there.
207
+
208
+ ## Your data
209
+
210
+ One JSON file, at `~/.local/share/tsk/tasks.json` unless you say otherwise:
211
+
212
+ ```json
213
+ {
214
+ "version": 1,
215
+ "issued": 7,
216
+ "tasks": [
217
+ {
218
+ "id": 2,
219
+ "description": "fix the login bug",
220
+ "status": "pending",
221
+ "created": "2026-07-16T14:49:48+00:00",
222
+ "project": "work",
223
+ "tags": ["urgent"],
224
+ "due": "2026-07-15",
225
+ "priority": "high"
226
+ }
227
+ ]
228
+ }
229
+ ```
230
+
231
+ Set `TSK_DATA` to put it somewhere else, or `XDG_DATA_HOME` to move the lot. Keep it in a git repo
232
+ if you want history. Tags are written in a fixed order and absent fields are left out, so diffs
233
+ stay small.
234
+
235
+ Writes are atomic. The file is written beside itself and then moved into place, so an interrupted
236
+ write cannot leave you with half a file. Existing permissions are preserved.
237
+
238
+ Ids are never reused. Once id 3 has been handed out, no later task gets it, even if you delete task
239
+ 3 the same day. The id you read a minute ago is still the task you thought it was.
240
+
241
+ ## Colour
242
+
243
+ On when writing to a terminal, off when piped. Set `NO_COLOR` to turn it off entirely.
244
+
245
+ Overdue is red, due today is yellow, projects are cyan, tags are magenta.
246
+
247
+ ## What it does not do
248
+
249
+ There is no urgency score, no dependency graph, no user defined attributes, no hooks, no custom
250
+ report definitions and no sync. Each of those either failed the question "would I miss this" or
251
+ costs far more than it returns for a tool this size.
252
+
253
+ If you want a task on the calendar, `due:` is where it goes. If you want to find it later, tag it.
254
+ That is most of task management.
255
+
256
+ ## Development
257
+
258
+ ```
259
+ uv sync
260
+ uv run pytest
261
+ uv run ruff check .
262
+ uv run ruff format .
263
+ uv run mypy
264
+ ```
265
+
266
+ The suite runs in well under a second. It is worth keeping it that way.
267
+
268
+ ## Licence
269
+
270
+ MIT
@@ -0,0 +1,250 @@
1
+ # tsk
2
+
3
+ A small task manager for the terminal.
4
+
5
+ ```
6
+ $ tsk add water the plants @home +garden due:tomorrow every:weekly
7
+ added 1: water the plants
8
+
9
+ $ tsk add fix the login bug @work +urgent due:yesterday p:h
10
+ added 2: fix the login bug
11
+
12
+ $ tsk
13
+ 2 H yesterday fix the login bug @work +urgent
14
+ 1 tomorrow water the plants @home +garden every:weekly
15
+ ```
16
+
17
+ No daemon, no config file, no dependencies. Your tasks live in one JSON file you can read.
18
+
19
+ ## Install
20
+
21
+ Needs Python 3.11 or newer.
22
+
23
+ ```
24
+ git clone https://github.com/michaelrbarley/tsk-todo
25
+ cd tsk-todo
26
+ uv tool install .
27
+ ```
28
+
29
+ The command is `tsk`. The package is `tsk-todo`, because `tsk` on PyPI belongs to something else.
30
+
31
+ Or run it from the clone without installing anything:
32
+
33
+ ```
34
+ uv run tsk
35
+ ```
36
+
37
+ ## The idea
38
+
39
+ You type what you mean and `tsk` works out which parts are metadata:
40
+
41
+ ```
42
+ tsk add renew the passport @admin +boring due:eom p:h
43
+ ```
44
+
45
+ `@admin` is the project, `+boring` is a tag, `due:eom` is the end of this month, `p:h` is high
46
+ priority. Everything left over is the task itself.
47
+
48
+ Only `due:`, `p:` and `every:` are read as attributes, so ordinary text stays ordinary:
49
+
50
+ ```
51
+ $ tsk add email bob@example.com about the invoice
52
+ $ tsk add fix the -v flag
53
+ $ tsk add ticket: replace the boiler
54
+ ```
55
+
56
+ None of those pick up a project, a tag or an attribute. If it is not a form `tsk` knows, it is
57
+ part of the description.
58
+
59
+ ## Commands
60
+
61
+ ```
62
+ tsk list pending tasks
63
+ tsk add <text> [attrs] add a task
64
+ tsk done <id>... complete tasks
65
+ tsk rm <id>... delete tasks
66
+ tsk edit <id> <attrs> change a task
67
+ tsk note <id> <text> attach a note
68
+ tsk show <id> show one task in full
69
+ tsk list [filters] list tasks
70
+ ```
71
+
72
+ `tsk 3` on its own is shorthand for `tsk show 3`.
73
+
74
+ `done` and `rm` take several ids at once: `tsk done 2 5 9`.
75
+
76
+ ## Attributes
77
+
78
+ Use these when adding or editing.
79
+
80
+ ```
81
+ @project set the project
82
+ +tag add a tag
83
+ -tag remove a tag, when editing
84
+ due:<when> set a due date
85
+ p:h|m|l set priority, high medium or low
86
+ every:<how> reschedule on completion
87
+ ```
88
+
89
+ Priority also accepts the full word, so `p:high` and `p:h` are the same.
90
+
91
+ Editing changes only what you name. Everything else is left alone.
92
+
93
+ ```
94
+ $ tsk edit 3 due:friday +urgent
95
+ updated 3: read the book
96
+ ```
97
+
98
+ To clear something, give it no value:
99
+
100
+ ```
101
+ $ tsk edit 3 due: p: every:
102
+ ```
103
+
104
+ A bare `@` clears the project. A leading `-` removes a tag.
105
+
106
+ ## Filters
107
+
108
+ ```
109
+ tsk +garden tagged garden
110
+ tsk -work not tagged work
111
+ tsk @home in the home project
112
+ tsk overdue past due
113
+ tsk due:friday due on or before friday
114
+ tsk done completed tasks
115
+ tsk all everything
116
+ tsk plants search descriptions and notes
117
+ ```
118
+
119
+ Filters combine, and `list` is optional:
120
+
121
+ ```
122
+ $ tsk @home +garden overdue
123
+ $ tsk list @work due:eow
124
+ ```
125
+
126
+ Bare words search. `tsk list dentist` finds anything with dentist in the description or in a note.
127
+
128
+ ## Dates
129
+
130
+ Anywhere a date is wanted:
131
+
132
+ ```
133
+ today, tomorrow, yesterday
134
+ monday .. sunday, or mon .. sun
135
+ 3d, 2w, 1m, 1y
136
+ eow, eom, eoy
137
+ 2026-08-01
138
+ ```
139
+
140
+ Weekday names mean the next one coming. On a Thursday, `due:thursday` is a week away, not today.
141
+
142
+ Month and year offsets land on a real date. `1m` from the 31st of January is the 28th of February,
143
+ not the 3rd of March.
144
+
145
+ Due dates are plain calendar dates. `due:friday` means Friday wherever you happen to be, and it
146
+ does not drift when you cross a timezone.
147
+
148
+ ## Repeats
149
+
150
+ ```
151
+ every:daily
152
+ every:weekdays
153
+ every:weekly
154
+ every:monthly
155
+ every:yearly
156
+ ```
157
+
158
+ A repeating task needs a due date. When you complete it, the next one is created for you:
159
+
160
+ ```
161
+ $ tsk done 1
162
+ done 1: water the plants
163
+ repeats as 5, due in 1 week
164
+ ```
165
+
166
+ The next date is worked out from the old due date, then rolled forward until it is in the future.
167
+ Finish a daily task five days late and the next one is due tomorrow, not last week. You never come
168
+ back to a pile of overdue copies.
169
+
170
+ Notes do not carry over. The completed task keeps them.
171
+
172
+ ## Notes
173
+
174
+ ```
175
+ $ tsk note 3 the ferns look worse than the rest
176
+ noted on 3: water the plants
177
+ ```
178
+
179
+ Tasks with notes are marked with a `*` in the list. `tsk show 3` prints them.
180
+
181
+ ## Ordering
182
+
183
+ Tasks sort by due date, then priority, then id. That is the whole rule. Nothing is scored or
184
+ weighted behind your back, so the order is always one you can predict and explain.
185
+
186
+ Undated tasks sort last. They are not urgent, they are just there.
187
+
188
+ ## Your data
189
+
190
+ One JSON file, at `~/.local/share/tsk/tasks.json` unless you say otherwise:
191
+
192
+ ```json
193
+ {
194
+ "version": 1,
195
+ "issued": 7,
196
+ "tasks": [
197
+ {
198
+ "id": 2,
199
+ "description": "fix the login bug",
200
+ "status": "pending",
201
+ "created": "2026-07-16T14:49:48+00:00",
202
+ "project": "work",
203
+ "tags": ["urgent"],
204
+ "due": "2026-07-15",
205
+ "priority": "high"
206
+ }
207
+ ]
208
+ }
209
+ ```
210
+
211
+ Set `TSK_DATA` to put it somewhere else, or `XDG_DATA_HOME` to move the lot. Keep it in a git repo
212
+ if you want history. Tags are written in a fixed order and absent fields are left out, so diffs
213
+ stay small.
214
+
215
+ Writes are atomic. The file is written beside itself and then moved into place, so an interrupted
216
+ write cannot leave you with half a file. Existing permissions are preserved.
217
+
218
+ Ids are never reused. Once id 3 has been handed out, no later task gets it, even if you delete task
219
+ 3 the same day. The id you read a minute ago is still the task you thought it was.
220
+
221
+ ## Colour
222
+
223
+ On when writing to a terminal, off when piped. Set `NO_COLOR` to turn it off entirely.
224
+
225
+ Overdue is red, due today is yellow, projects are cyan, tags are magenta.
226
+
227
+ ## What it does not do
228
+
229
+ There is no urgency score, no dependency graph, no user defined attributes, no hooks, no custom
230
+ report definitions and no sync. Each of those either failed the question "would I miss this" or
231
+ costs far more than it returns for a tool this size.
232
+
233
+ If you want a task on the calendar, `due:` is where it goes. If you want to find it later, tag it.
234
+ That is most of task management.
235
+
236
+ ## Development
237
+
238
+ ```
239
+ uv sync
240
+ uv run pytest
241
+ uv run ruff check .
242
+ uv run ruff format .
243
+ uv run mypy
244
+ ```
245
+
246
+ The suite runs in well under a second. It is worth keeping it that way.
247
+
248
+ ## Licence
249
+
250
+ MIT
@@ -0,0 +1,57 @@
1
+ [project]
2
+ name = "tsk-todo"
3
+ version = "0.1.0"
4
+ description = "Minimal todo CLI for the terminal. Pure Python, zero dependencies."
5
+ readme = "README.md"
6
+ requires-python = ">=3.11"
7
+ license = "MIT"
8
+ authors = [
9
+ { name = "michaelrbarley", email = "301309661+michaelrbarley@users.noreply.github.com" }
10
+ ]
11
+ keywords = ["cli", "todo", "task", "task-manager", "productivity", "terminal", "gtd"]
12
+ classifiers = [
13
+ "Development Status :: 4 - Beta",
14
+ "Environment :: Console",
15
+ "Intended Audience :: End Users/Desktop",
16
+ "Operating System :: POSIX",
17
+ "Programming Language :: Python :: 3 :: Only",
18
+ "Topic :: Utilities",
19
+ ]
20
+ dependencies = []
21
+
22
+ [project.urls]
23
+ Homepage = "https://github.com/michaelrbarley/tsk-todo"
24
+ Source = "https://github.com/michaelrbarley/tsk-todo"
25
+ Issues = "https://github.com/michaelrbarley/tsk-todo/issues"
26
+
27
+ [project.scripts]
28
+ tsk = "tsk.cli:main"
29
+
30
+ [tool.uv.build-backend]
31
+ module-name = "tsk"
32
+
33
+ [build-system]
34
+ requires = ["uv_build>=0.11,<0.12"]
35
+ build-backend = "uv_build"
36
+
37
+ [dependency-groups]
38
+ dev = ["pytest>=9.1", "pytest-cov>=7.1", "ruff>=0.15,<0.16", "mypy>=2.3"]
39
+
40
+ [tool.ruff]
41
+ line-length = 88
42
+
43
+ [tool.ruff.lint]
44
+ select = ["E", "F", "I", "UP", "B", "SIM", "PTH", "RUF"]
45
+
46
+ [tool.pytest.ini_options]
47
+ testpaths = ["tests"]
48
+ addopts = "--strict-markers --strict-config -ra"
49
+ filterwarnings = ["error"]
50
+
51
+ [tool.mypy]
52
+ strict = true
53
+ files = ["src", "tests"]
54
+
55
+ [tool.coverage.run]
56
+ source = ["src"]
57
+ branch = true
File without changes