microsoft-todo-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.
- microsoft_todo_cli-1.0.0/CHANGES.txt +10 -0
- microsoft_todo_cli-1.0.0/LICENSE +22 -0
- microsoft_todo_cli-1.0.0/MANIFEST.in +4 -0
- microsoft_todo_cli-1.0.0/PKG-INFO +296 -0
- microsoft_todo_cli-1.0.0/README.md +258 -0
- microsoft_todo_cli-1.0.0/docs/setup-api.md +67 -0
- microsoft_todo_cli-1.0.0/microsoft_todo_cli.egg-info/PKG-INFO +296 -0
- microsoft_todo_cli-1.0.0/microsoft_todo_cli.egg-info/SOURCES.txt +43 -0
- microsoft_todo_cli-1.0.0/microsoft_todo_cli.egg-info/dependency_links.txt +1 -0
- microsoft_todo_cli-1.0.0/microsoft_todo_cli.egg-info/entry_points.txt +2 -0
- microsoft_todo_cli-1.0.0/microsoft_todo_cli.egg-info/requires.txt +3 -0
- microsoft_todo_cli-1.0.0/microsoft_todo_cli.egg-info/top_level.txt +2 -0
- microsoft_todo_cli-1.0.0/setup.cfg +4 -0
- microsoft_todo_cli-1.0.0/setup.py +42 -0
- microsoft_todo_cli-1.0.0/tests/__init__.py +0 -0
- microsoft_todo_cli-1.0.0/tests/run_tests.py +39 -0
- microsoft_todo_cli-1.0.0/tests/test_checklist_cli.py +118 -0
- microsoft_todo_cli-1.0.0/tests/test_checklist_item_model.py +108 -0
- microsoft_todo_cli-1.0.0/tests/test_checklist_wrapper.py +62 -0
- microsoft_todo_cli-1.0.0/tests/test_cli_commands.py +436 -0
- microsoft_todo_cli-1.0.0/tests/test_cli_output.py +169 -0
- microsoft_todo_cli-1.0.0/tests/test_cli_url_integration.py +136 -0
- microsoft_todo_cli-1.0.0/tests/test_datetime_parser.py +233 -0
- microsoft_todo_cli-1.0.0/tests/test_filters.py +120 -0
- microsoft_todo_cli-1.0.0/tests/test_json_output.py +223 -0
- microsoft_todo_cli-1.0.0/tests/test_lst_output.py +135 -0
- microsoft_todo_cli-1.0.0/tests/test_models.py +235 -0
- microsoft_todo_cli-1.0.0/tests/test_odata_escape.py +175 -0
- microsoft_todo_cli-1.0.0/tests/test_recurrence.py +159 -0
- microsoft_todo_cli-1.0.0/tests/test_update_command.py +192 -0
- microsoft_todo_cli-1.0.0/tests/test_utils.py +186 -0
- microsoft_todo_cli-1.0.0/tests/test_wrapper.py +191 -0
- microsoft_todo_cli-1.0.0/todocli/__init__.py +1 -0
- microsoft_todo_cli-1.0.0/todocli/cli.py +1356 -0
- microsoft_todo_cli-1.0.0/todocli/graphapi/__init__.py +0 -0
- microsoft_todo_cli-1.0.0/todocli/graphapi/oauth.py +136 -0
- microsoft_todo_cli-1.0.0/todocli/graphapi/wrapper.py +660 -0
- microsoft_todo_cli-1.0.0/todocli/models/__init__.py +0 -0
- microsoft_todo_cli-1.0.0/todocli/models/checklistitem.py +59 -0
- microsoft_todo_cli-1.0.0/todocli/models/todolist.py +27 -0
- microsoft_todo_cli-1.0.0/todocli/models/todotask.py +105 -0
- microsoft_todo_cli-1.0.0/todocli/utils/__init__.py +0 -0
- microsoft_todo_cli-1.0.0/todocli/utils/datetime_util.py +321 -0
- microsoft_todo_cli-1.0.0/todocli/utils/recurrence_util.py +122 -0
- microsoft_todo_cli-1.0.0/todocli/utils/update_checker.py +55 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
v1.0.0, 2026-02-04
|
|
2
|
+
- Fork from kiblee/tod0 with redesigned CLI
|
|
3
|
+
- Removed interactive TUI, CLI-only
|
|
4
|
+
- Added JSON output for all commands (--json flag)
|
|
5
|
+
- Added --id flag for stable task identification
|
|
6
|
+
- Added filters: --all, --completed, --due-today, --overdue, --important
|
|
7
|
+
- Added uncomplete/uncomplete-step commands
|
|
8
|
+
- Added inline step creation with -S flag
|
|
9
|
+
- Renamed commands: lists (was ls), tasks (was lst), new-list (was newl)
|
|
10
|
+
- Added command aliases: t, n, c, d
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2019 kiblee
|
|
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.
|
|
22
|
+
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: microsoft-todo-cli
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Fast, minimal command-line client for Microsoft To-Do
|
|
5
|
+
Home-page: https://github.com/underwear/microsoft-todo-cli
|
|
6
|
+
Author: underwear
|
|
7
|
+
Author-email:
|
|
8
|
+
License: MIT
|
|
9
|
+
Keywords: microsoft todo cli task management
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
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 :: Utilities
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: pyyaml
|
|
25
|
+
Requires-Dist: requests>=2.28.1
|
|
26
|
+
Requires-Dist: requests_oauthlib
|
|
27
|
+
Dynamic: author
|
|
28
|
+
Dynamic: classifier
|
|
29
|
+
Dynamic: description
|
|
30
|
+
Dynamic: description-content-type
|
|
31
|
+
Dynamic: home-page
|
|
32
|
+
Dynamic: keywords
|
|
33
|
+
Dynamic: license
|
|
34
|
+
Dynamic: license-file
|
|
35
|
+
Dynamic: requires-dist
|
|
36
|
+
Dynamic: requires-python
|
|
37
|
+
Dynamic: summary
|
|
38
|
+
|
|
39
|
+
# microsoft-todo-cli
|
|
40
|
+
|
|
41
|
+
Fast, minimal command-line client for Microsoft To-Do
|
|
42
|
+
|
|
43
|
+
[](https://www.python.org/downloads/)
|
|
44
|
+
[](https://github.com/psf/black)
|
|
45
|
+
[](https://opensource.org/licenses/MIT)
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
$ todo tasks
|
|
49
|
+
[0] Buy groceries
|
|
50
|
+
[1] Call mom ! (due: tomorrow)
|
|
51
|
+
[2] Review PR #42
|
|
52
|
+
[x] Check tests
|
|
53
|
+
[ ] Add documentation
|
|
54
|
+
|
|
55
|
+
$ todo new "Deploy v2.0" -d friday -r 9am -I
|
|
56
|
+
Created task 'Deploy v2.0' in 'Tasks'
|
|
57
|
+
|
|
58
|
+
$ todo complete 0
|
|
59
|
+
Completed task 'Buy groceries' in 'Tasks'
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Install
|
|
63
|
+
|
|
64
|
+
**Requirements:** Python 3.10+
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
pip install microsoft-todo-cli
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Or install from source:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
git clone https://github.com/underwear/microsoft-todo-cli.git
|
|
74
|
+
cd microsoft-todo-cli
|
|
75
|
+
pip install -e .
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Then configure Microsoft API access: **[Setup Guide](docs/setup-api.md)** (5 min)
|
|
79
|
+
|
|
80
|
+
## Quick Start
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
todo lists # Show all lists
|
|
84
|
+
todo tasks # Show tasks from default list
|
|
85
|
+
todo tasks Work # Show tasks from "Work" list
|
|
86
|
+
todo new "Buy milk" # Create task
|
|
87
|
+
todo complete "Buy milk" # Mark done (or: todo c "Buy milk")
|
|
88
|
+
todo rm "Old task" # Delete
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**Default list**: The first list returned by Microsoft To-Do API (usually "Tasks"). Specify a list explicitly with `-l ListName` or as a positional argument.
|
|
92
|
+
|
|
93
|
+
**Short aliases**: `t` (tasks), `n` (new), `c` (complete), `d` (rm) — see [Aliases](#aliases).
|
|
94
|
+
|
|
95
|
+
## Usage
|
|
96
|
+
|
|
97
|
+
### Tasks
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
# View
|
|
101
|
+
todo tasks # Default list
|
|
102
|
+
todo tasks Work # Specific list
|
|
103
|
+
todo tasks --due-today # Due today
|
|
104
|
+
todo tasks --overdue # Past due
|
|
105
|
+
todo tasks --important # High priority
|
|
106
|
+
todo tasks --completed # Done tasks
|
|
107
|
+
todo tasks --all # Everything
|
|
108
|
+
|
|
109
|
+
# Create
|
|
110
|
+
todo new "Task name" # Basic
|
|
111
|
+
todo new "Task" -l Work # In specific list
|
|
112
|
+
todo new "Task" -d tomorrow # With due date
|
|
113
|
+
todo new "Task" -r 2h # With reminder (in 2 hours)
|
|
114
|
+
todo new "Task" -d mon -r 9am # Due Monday, remind at 9am
|
|
115
|
+
todo new "Task" -I # Important
|
|
116
|
+
todo new "Task" -R daily # Recurring
|
|
117
|
+
todo new "Task" -R weekly:mon,fri # Recurring on specific days
|
|
118
|
+
todo new "Task" -S "Step 1" -S "Step 2" # With subtasks
|
|
119
|
+
|
|
120
|
+
# View single task
|
|
121
|
+
todo show "Task" # Show task details
|
|
122
|
+
todo show 0 # Show by index
|
|
123
|
+
|
|
124
|
+
# Manage
|
|
125
|
+
todo complete "Task" # Mark complete
|
|
126
|
+
todo complete 0 1 2 # Complete by index (batch)
|
|
127
|
+
todo uncomplete "Task" # Reopen task
|
|
128
|
+
todo update "Task" --title "New" # Rename
|
|
129
|
+
todo update "Task" -d friday -I # Change due date, make important
|
|
130
|
+
todo rm "Task" # Delete (asks confirmation)
|
|
131
|
+
todo rm "Task" -y # Delete (no confirmation)
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Subtasks (Steps)
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
todo new-step "Task" "Step text" # Add step
|
|
138
|
+
todo list-steps "Task" # List steps
|
|
139
|
+
todo complete-step "Task" "Step" # Check off
|
|
140
|
+
todo uncomplete-step "Task" "Step" # Uncheck
|
|
141
|
+
todo rm-step "Task" 0 # Remove by index
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Lists
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
todo lists # Show all lists
|
|
148
|
+
todo new-list "Project X" # Create list
|
|
149
|
+
todo rename-list "Old" "New" # Rename list
|
|
150
|
+
todo rm-list "Project X" # Delete list (asks confirmation)
|
|
151
|
+
todo rm-list "Project X" -y # Delete list (no confirmation)
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Date & Time Formats
|
|
155
|
+
|
|
156
|
+
| Type | Examples |
|
|
157
|
+
|------|----------|
|
|
158
|
+
| Relative | `1h`, `30m`, `2d`, `1h30m` |
|
|
159
|
+
| Time | `9:30`, `9am`, `17:00`, `5:30pm` |
|
|
160
|
+
| Days | `tomorrow`, `monday`, `fri` |
|
|
161
|
+
| Date | `2026-12-31`, `31.12.2026`, `12/31/2026` |
|
|
162
|
+
| Keywords | `morning` (7:00), `evening` (18:00) |
|
|
163
|
+
|
|
164
|
+
### Recurrence Patterns
|
|
165
|
+
|
|
166
|
+
| Pattern | Description |
|
|
167
|
+
|---------|-------------|
|
|
168
|
+
| `daily` | Every day |
|
|
169
|
+
| `weekly` | Every week |
|
|
170
|
+
| `monthly` | Every month |
|
|
171
|
+
| `yearly` | Every year |
|
|
172
|
+
| `weekdays` | Monday to Friday |
|
|
173
|
+
| `weekly:mon,wed,fri` | Specific days |
|
|
174
|
+
| `every 2 days` | Custom interval |
|
|
175
|
+
| `every 3 weeks` | Custom interval |
|
|
176
|
+
|
|
177
|
+
## Scripting & Automation
|
|
178
|
+
|
|
179
|
+
### JSON Output
|
|
180
|
+
|
|
181
|
+
Add `--json` to any command for machine-readable output:
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
todo tasks --json
|
|
185
|
+
todo lists --json
|
|
186
|
+
todo show "Task" --json
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
**Example: `todo tasks --json`**
|
|
190
|
+
```json
|
|
191
|
+
{
|
|
192
|
+
"list": "Tasks",
|
|
193
|
+
"tasks": [
|
|
194
|
+
{
|
|
195
|
+
"id": "AAMkADU3...",
|
|
196
|
+
"title": "Buy groceries",
|
|
197
|
+
"status": "notStarted",
|
|
198
|
+
"importance": "normal",
|
|
199
|
+
"due_date": null,
|
|
200
|
+
"reminder": null,
|
|
201
|
+
"recurrence": null,
|
|
202
|
+
"steps": []
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
"id": "AAMkADU4...",
|
|
206
|
+
"title": "Call mom",
|
|
207
|
+
"status": "notStarted",
|
|
208
|
+
"importance": "high",
|
|
209
|
+
"due_date": "2026-02-06",
|
|
210
|
+
"reminder": "2026-02-06T09:00:00",
|
|
211
|
+
"recurrence": null,
|
|
212
|
+
"steps": [
|
|
213
|
+
{"id": "step1", "name": "Check tests", "completed": true},
|
|
214
|
+
{"id": "step2", "name": "Add documentation", "completed": false}
|
|
215
|
+
]
|
|
216
|
+
}
|
|
217
|
+
]
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
**Write commands return action confirmation:**
|
|
222
|
+
```bash
|
|
223
|
+
todo new "Task" --json # {"action": "created", "id": "AAMk...", "title": "Task", "list": "Tasks"}
|
|
224
|
+
todo complete "Task" --json # {"action": "completed", "id": "AAMk...", "title": "Task", "list": "Tasks"}
|
|
225
|
+
todo rm "Task" -y --json # {"action": "removed", "id": "AAMk...", "title": "Task", "list": "Tasks"}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Task Identification
|
|
229
|
+
|
|
230
|
+
Tasks can be identified by **name**, **index**, or **ID**. Priority for reliable automation:
|
|
231
|
+
|
|
232
|
+
| Method | Stability | Use case |
|
|
233
|
+
|--------|-----------|----------|
|
|
234
|
+
| `--id "AAMk..."` | Stable | Scripts, automation, agents |
|
|
235
|
+
| Index (`0`, `1`) | Unstable | Interactive use only |
|
|
236
|
+
| Name (`"Task"`) | Unstable | Interactive use, unique names |
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
# Get task ID from JSON output
|
|
240
|
+
todo tasks --json | jq -r '.tasks[0].id'
|
|
241
|
+
|
|
242
|
+
# Show IDs inline (human-readable + IDs)
|
|
243
|
+
todo tasks --show-id
|
|
244
|
+
|
|
245
|
+
# Use ID in commands (requires -l for list context)
|
|
246
|
+
todo complete --id "AAMkADU3..." -l Tasks
|
|
247
|
+
todo update --id "AAMkADU3..." --title "New title"
|
|
248
|
+
todo rm --id "AAMkADU3..." -l Tasks -y
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
**Example: Create and complete a task by ID**
|
|
252
|
+
```bash
|
|
253
|
+
ID=$(todo new "Deploy v2.0" -l Work --json | jq -r '.id')
|
|
254
|
+
# ... later ...
|
|
255
|
+
todo complete --id "$ID" -l Work
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### Exit Codes
|
|
259
|
+
|
|
260
|
+
| Code | Meaning |
|
|
261
|
+
|------|---------|
|
|
262
|
+
| `0` | Success |
|
|
263
|
+
| `1` | General error (invalid arguments, task not found, API error) |
|
|
264
|
+
|
|
265
|
+
With `--json`: stdout contains only valid JSON on success. Errors go to stderr.
|
|
266
|
+
|
|
267
|
+
### Tips for Scripts and Agents
|
|
268
|
+
|
|
269
|
+
- **Prefer `--id` over names/indexes**: Names can have duplicates (first match wins). Indexes change as tasks are added/completed/reordered.
|
|
270
|
+
- **Always use `-l ListName`** with `--id` to specify list context.
|
|
271
|
+
- **Capture IDs on creation**: Store the ID from `todo new --json` for later operations.
|
|
272
|
+
- **Use `--json` for parsing**: Human-readable output format may change between versions.
|
|
273
|
+
- **Use `-y` flag** with `rm` commands to skip confirmation prompts.
|
|
274
|
+
|
|
275
|
+
## Aliases
|
|
276
|
+
|
|
277
|
+
| Alias | Command | Alias | Command |
|
|
278
|
+
|-------|---------|-------|---------|
|
|
279
|
+
| `t` | `tasks` | `d` | `rm` |
|
|
280
|
+
| `n` | `new` | `newl` | `new-list` |
|
|
281
|
+
| `c` | `complete` | `reopen` | `uncomplete` |
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
todo t # = todo tasks
|
|
285
|
+
todo n "Task" -d fri # = todo new "Task" -d fri
|
|
286
|
+
todo c 0 1 2 # = todo complete 0 1 2
|
|
287
|
+
todo d "Old" -y # = todo rm "Old" -y
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
## Credits
|
|
291
|
+
|
|
292
|
+
Forked from [kiblee/tod0](https://github.com/kiblee/tod0) with a redesigned CLI.
|
|
293
|
+
|
|
294
|
+
## License
|
|
295
|
+
|
|
296
|
+
MIT
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
# microsoft-todo-cli
|
|
2
|
+
|
|
3
|
+
Fast, minimal command-line client for Microsoft To-Do
|
|
4
|
+
|
|
5
|
+
[](https://www.python.org/downloads/)
|
|
6
|
+
[](https://github.com/psf/black)
|
|
7
|
+
[](https://opensource.org/licenses/MIT)
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
$ todo tasks
|
|
11
|
+
[0] Buy groceries
|
|
12
|
+
[1] Call mom ! (due: tomorrow)
|
|
13
|
+
[2] Review PR #42
|
|
14
|
+
[x] Check tests
|
|
15
|
+
[ ] Add documentation
|
|
16
|
+
|
|
17
|
+
$ todo new "Deploy v2.0" -d friday -r 9am -I
|
|
18
|
+
Created task 'Deploy v2.0' in 'Tasks'
|
|
19
|
+
|
|
20
|
+
$ todo complete 0
|
|
21
|
+
Completed task 'Buy groceries' in 'Tasks'
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Install
|
|
25
|
+
|
|
26
|
+
**Requirements:** Python 3.10+
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install microsoft-todo-cli
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Or install from source:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
git clone https://github.com/underwear/microsoft-todo-cli.git
|
|
36
|
+
cd microsoft-todo-cli
|
|
37
|
+
pip install -e .
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Then configure Microsoft API access: **[Setup Guide](docs/setup-api.md)** (5 min)
|
|
41
|
+
|
|
42
|
+
## Quick Start
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
todo lists # Show all lists
|
|
46
|
+
todo tasks # Show tasks from default list
|
|
47
|
+
todo tasks Work # Show tasks from "Work" list
|
|
48
|
+
todo new "Buy milk" # Create task
|
|
49
|
+
todo complete "Buy milk" # Mark done (or: todo c "Buy milk")
|
|
50
|
+
todo rm "Old task" # Delete
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**Default list**: The first list returned by Microsoft To-Do API (usually "Tasks"). Specify a list explicitly with `-l ListName` or as a positional argument.
|
|
54
|
+
|
|
55
|
+
**Short aliases**: `t` (tasks), `n` (new), `c` (complete), `d` (rm) — see [Aliases](#aliases).
|
|
56
|
+
|
|
57
|
+
## Usage
|
|
58
|
+
|
|
59
|
+
### Tasks
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
# View
|
|
63
|
+
todo tasks # Default list
|
|
64
|
+
todo tasks Work # Specific list
|
|
65
|
+
todo tasks --due-today # Due today
|
|
66
|
+
todo tasks --overdue # Past due
|
|
67
|
+
todo tasks --important # High priority
|
|
68
|
+
todo tasks --completed # Done tasks
|
|
69
|
+
todo tasks --all # Everything
|
|
70
|
+
|
|
71
|
+
# Create
|
|
72
|
+
todo new "Task name" # Basic
|
|
73
|
+
todo new "Task" -l Work # In specific list
|
|
74
|
+
todo new "Task" -d tomorrow # With due date
|
|
75
|
+
todo new "Task" -r 2h # With reminder (in 2 hours)
|
|
76
|
+
todo new "Task" -d mon -r 9am # Due Monday, remind at 9am
|
|
77
|
+
todo new "Task" -I # Important
|
|
78
|
+
todo new "Task" -R daily # Recurring
|
|
79
|
+
todo new "Task" -R weekly:mon,fri # Recurring on specific days
|
|
80
|
+
todo new "Task" -S "Step 1" -S "Step 2" # With subtasks
|
|
81
|
+
|
|
82
|
+
# View single task
|
|
83
|
+
todo show "Task" # Show task details
|
|
84
|
+
todo show 0 # Show by index
|
|
85
|
+
|
|
86
|
+
# Manage
|
|
87
|
+
todo complete "Task" # Mark complete
|
|
88
|
+
todo complete 0 1 2 # Complete by index (batch)
|
|
89
|
+
todo uncomplete "Task" # Reopen task
|
|
90
|
+
todo update "Task" --title "New" # Rename
|
|
91
|
+
todo update "Task" -d friday -I # Change due date, make important
|
|
92
|
+
todo rm "Task" # Delete (asks confirmation)
|
|
93
|
+
todo rm "Task" -y # Delete (no confirmation)
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Subtasks (Steps)
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
todo new-step "Task" "Step text" # Add step
|
|
100
|
+
todo list-steps "Task" # List steps
|
|
101
|
+
todo complete-step "Task" "Step" # Check off
|
|
102
|
+
todo uncomplete-step "Task" "Step" # Uncheck
|
|
103
|
+
todo rm-step "Task" 0 # Remove by index
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Lists
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
todo lists # Show all lists
|
|
110
|
+
todo new-list "Project X" # Create list
|
|
111
|
+
todo rename-list "Old" "New" # Rename list
|
|
112
|
+
todo rm-list "Project X" # Delete list (asks confirmation)
|
|
113
|
+
todo rm-list "Project X" -y # Delete list (no confirmation)
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Date & Time Formats
|
|
117
|
+
|
|
118
|
+
| Type | Examples |
|
|
119
|
+
|------|----------|
|
|
120
|
+
| Relative | `1h`, `30m`, `2d`, `1h30m` |
|
|
121
|
+
| Time | `9:30`, `9am`, `17:00`, `5:30pm` |
|
|
122
|
+
| Days | `tomorrow`, `monday`, `fri` |
|
|
123
|
+
| Date | `2026-12-31`, `31.12.2026`, `12/31/2026` |
|
|
124
|
+
| Keywords | `morning` (7:00), `evening` (18:00) |
|
|
125
|
+
|
|
126
|
+
### Recurrence Patterns
|
|
127
|
+
|
|
128
|
+
| Pattern | Description |
|
|
129
|
+
|---------|-------------|
|
|
130
|
+
| `daily` | Every day |
|
|
131
|
+
| `weekly` | Every week |
|
|
132
|
+
| `monthly` | Every month |
|
|
133
|
+
| `yearly` | Every year |
|
|
134
|
+
| `weekdays` | Monday to Friday |
|
|
135
|
+
| `weekly:mon,wed,fri` | Specific days |
|
|
136
|
+
| `every 2 days` | Custom interval |
|
|
137
|
+
| `every 3 weeks` | Custom interval |
|
|
138
|
+
|
|
139
|
+
## Scripting & Automation
|
|
140
|
+
|
|
141
|
+
### JSON Output
|
|
142
|
+
|
|
143
|
+
Add `--json` to any command for machine-readable output:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
todo tasks --json
|
|
147
|
+
todo lists --json
|
|
148
|
+
todo show "Task" --json
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
**Example: `todo tasks --json`**
|
|
152
|
+
```json
|
|
153
|
+
{
|
|
154
|
+
"list": "Tasks",
|
|
155
|
+
"tasks": [
|
|
156
|
+
{
|
|
157
|
+
"id": "AAMkADU3...",
|
|
158
|
+
"title": "Buy groceries",
|
|
159
|
+
"status": "notStarted",
|
|
160
|
+
"importance": "normal",
|
|
161
|
+
"due_date": null,
|
|
162
|
+
"reminder": null,
|
|
163
|
+
"recurrence": null,
|
|
164
|
+
"steps": []
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
"id": "AAMkADU4...",
|
|
168
|
+
"title": "Call mom",
|
|
169
|
+
"status": "notStarted",
|
|
170
|
+
"importance": "high",
|
|
171
|
+
"due_date": "2026-02-06",
|
|
172
|
+
"reminder": "2026-02-06T09:00:00",
|
|
173
|
+
"recurrence": null,
|
|
174
|
+
"steps": [
|
|
175
|
+
{"id": "step1", "name": "Check tests", "completed": true},
|
|
176
|
+
{"id": "step2", "name": "Add documentation", "completed": false}
|
|
177
|
+
]
|
|
178
|
+
}
|
|
179
|
+
]
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
**Write commands return action confirmation:**
|
|
184
|
+
```bash
|
|
185
|
+
todo new "Task" --json # {"action": "created", "id": "AAMk...", "title": "Task", "list": "Tasks"}
|
|
186
|
+
todo complete "Task" --json # {"action": "completed", "id": "AAMk...", "title": "Task", "list": "Tasks"}
|
|
187
|
+
todo rm "Task" -y --json # {"action": "removed", "id": "AAMk...", "title": "Task", "list": "Tasks"}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Task Identification
|
|
191
|
+
|
|
192
|
+
Tasks can be identified by **name**, **index**, or **ID**. Priority for reliable automation:
|
|
193
|
+
|
|
194
|
+
| Method | Stability | Use case |
|
|
195
|
+
|--------|-----------|----------|
|
|
196
|
+
| `--id "AAMk..."` | Stable | Scripts, automation, agents |
|
|
197
|
+
| Index (`0`, `1`) | Unstable | Interactive use only |
|
|
198
|
+
| Name (`"Task"`) | Unstable | Interactive use, unique names |
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
# Get task ID from JSON output
|
|
202
|
+
todo tasks --json | jq -r '.tasks[0].id'
|
|
203
|
+
|
|
204
|
+
# Show IDs inline (human-readable + IDs)
|
|
205
|
+
todo tasks --show-id
|
|
206
|
+
|
|
207
|
+
# Use ID in commands (requires -l for list context)
|
|
208
|
+
todo complete --id "AAMkADU3..." -l Tasks
|
|
209
|
+
todo update --id "AAMkADU3..." --title "New title"
|
|
210
|
+
todo rm --id "AAMkADU3..." -l Tasks -y
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
**Example: Create and complete a task by ID**
|
|
214
|
+
```bash
|
|
215
|
+
ID=$(todo new "Deploy v2.0" -l Work --json | jq -r '.id')
|
|
216
|
+
# ... later ...
|
|
217
|
+
todo complete --id "$ID" -l Work
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Exit Codes
|
|
221
|
+
|
|
222
|
+
| Code | Meaning |
|
|
223
|
+
|------|---------|
|
|
224
|
+
| `0` | Success |
|
|
225
|
+
| `1` | General error (invalid arguments, task not found, API error) |
|
|
226
|
+
|
|
227
|
+
With `--json`: stdout contains only valid JSON on success. Errors go to stderr.
|
|
228
|
+
|
|
229
|
+
### Tips for Scripts and Agents
|
|
230
|
+
|
|
231
|
+
- **Prefer `--id` over names/indexes**: Names can have duplicates (first match wins). Indexes change as tasks are added/completed/reordered.
|
|
232
|
+
- **Always use `-l ListName`** with `--id` to specify list context.
|
|
233
|
+
- **Capture IDs on creation**: Store the ID from `todo new --json` for later operations.
|
|
234
|
+
- **Use `--json` for parsing**: Human-readable output format may change between versions.
|
|
235
|
+
- **Use `-y` flag** with `rm` commands to skip confirmation prompts.
|
|
236
|
+
|
|
237
|
+
## Aliases
|
|
238
|
+
|
|
239
|
+
| Alias | Command | Alias | Command |
|
|
240
|
+
|-------|---------|-------|---------|
|
|
241
|
+
| `t` | `tasks` | `d` | `rm` |
|
|
242
|
+
| `n` | `new` | `newl` | `new-list` |
|
|
243
|
+
| `c` | `complete` | `reopen` | `uncomplete` |
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
todo t # = todo tasks
|
|
247
|
+
todo n "Task" -d fri # = todo new "Task" -d fri
|
|
248
|
+
todo c 0 1 2 # = todo complete 0 1 2
|
|
249
|
+
todo d "Old" -y # = todo rm "Old" -y
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
## Credits
|
|
253
|
+
|
|
254
|
+
Forked from [kiblee/tod0](https://github.com/kiblee/tod0) with a redesigned CLI.
|
|
255
|
+
|
|
256
|
+
## License
|
|
257
|
+
|
|
258
|
+
MIT
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Setting Up Microsoft API Access
|
|
2
|
+
|
|
3
|
+
To use `todo`, you need to register an application in Microsoft Azure to get API credentials.
|
|
4
|
+
|
|
5
|
+
## Step 1: Register an Application
|
|
6
|
+
|
|
7
|
+
1. Sign in to the [Azure Portal](https://portal.azure.com/)
|
|
8
|
+
2. Navigate to **Microsoft Entra ID** (formerly Azure Active Directory)
|
|
9
|
+
3. Click **Add** → **App registration**
|
|
10
|
+
|
|
11
|
+
## Step 2: Configure the Application
|
|
12
|
+
|
|
13
|
+
Fill in the registration form:
|
|
14
|
+
|
|
15
|
+
| Field | Value |
|
|
16
|
+
|-------|-------|
|
|
17
|
+
| **Name** | `todo-cli` (or any name you prefer) |
|
|
18
|
+
| **Supported account types** | Accounts in any organizational directory and personal Microsoft accounts |
|
|
19
|
+
| **Redirect URI** | Platform: `Web`, URI: `https://localhost/login/authorized` |
|
|
20
|
+
|
|
21
|
+
Click **Register**.
|
|
22
|
+
|
|
23
|
+
## Step 3: Note Your Client ID
|
|
24
|
+
|
|
25
|
+
After registration, you'll see the **Application (client) ID** on the overview page. Copy this value.
|
|
26
|
+
|
|
27
|
+
## Step 4: Create a Client Secret
|
|
28
|
+
|
|
29
|
+
1. In the left menu, click **Certificates & secrets**
|
|
30
|
+
2. Click **New client secret**
|
|
31
|
+
3. Add a description (e.g., "todo-cli") and choose an expiration
|
|
32
|
+
4. Click **Add**
|
|
33
|
+
5. **Important:** Copy the secret **Value** immediately (not the Secret ID). It won't be visible again.
|
|
34
|
+
|
|
35
|
+
## Step 5: Configure todo
|
|
36
|
+
|
|
37
|
+
Create the config file:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
mkdir -p ~/.config/tod0
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Add your credentials to `~/.config/tod0/keys.yml`:
|
|
44
|
+
|
|
45
|
+
```yaml
|
|
46
|
+
client_id: 'your-application-client-id'
|
|
47
|
+
client_secret: 'your-client-secret-value'
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Step 6: First Run
|
|
51
|
+
|
|
52
|
+
Run any command to trigger OAuth login:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
todo lists
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
A browser window will open for Microsoft authentication. After logging in, you're ready to use the CLI.
|
|
59
|
+
|
|
60
|
+
## Troubleshooting
|
|
61
|
+
|
|
62
|
+
**"AADSTS50011: The redirect URI specified in the request does not match"**
|
|
63
|
+
- Ensure the redirect URI is exactly `https://localhost/login/authorized`
|
|
64
|
+
- Check that platform is set to `Web`
|
|
65
|
+
|
|
66
|
+
**Token expired**
|
|
67
|
+
- Delete `~/.config/tod0/token.pkl` and run any command to re-authenticate
|