@comfanion/usethis_todo 0.1.5 → 0.1.7-dev.0
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.
- package/README.md +598 -9
- package/package.json +1 -1
- package/tools.ts +75 -8
package/README.md
CHANGED
|
@@ -1,16 +1,33 @@
|
|
|
1
|
-
# @comfanion/usethis_todo
|
|
1
|
+
# 📋 @comfanion/usethis_todo
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**Smart TODO management with dependency graphs and priority tracking**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Stop juggling tasks in your head — let the graph show you what to do next!
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
- `usethis_todo_read`
|
|
9
|
-
- `usethis_todo_read_five`
|
|
10
|
-
- `usethis_todo_read_by_id`
|
|
11
|
-
- `usethis_todo_update`
|
|
7
|
+
---
|
|
12
8
|
|
|
13
|
-
##
|
|
9
|
+
## ✨ What is this?
|
|
10
|
+
|
|
11
|
+
An OpenCode plugin that transforms TODO lists into **intelligent task graphs**:
|
|
12
|
+
|
|
13
|
+
- 🎯 **Dependency tracking** — tasks know what blocks them
|
|
14
|
+
- 📊 **Visual graph analysis** — see available, blocked, and parallel tasks
|
|
15
|
+
- 🔥 **Priority system** — CRIT | HIGH | MED | LOW with auto-sorting
|
|
16
|
+
- 🏗️ **Hierarchical IDs** — E01-S01-T01 (Epic → Story → Task)
|
|
17
|
+
- 💾 **Dual storage** — enhanced features + native TUI integration
|
|
18
|
+
- 🚀 **Smart transitions** — auto-promote tasks when conditions are met
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 🚀 Quick Start
|
|
23
|
+
|
|
24
|
+
### Installation
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm install @comfanion/usethis_todo
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Configuration
|
|
14
31
|
|
|
15
32
|
Add to `opencode.json`:
|
|
16
33
|
|
|
@@ -19,3 +36,575 @@ Add to `opencode.json`:
|
|
|
19
36
|
"plugin": ["@comfanion/usethis_todo"]
|
|
20
37
|
}
|
|
21
38
|
```
|
|
39
|
+
|
|
40
|
+
### First TODO
|
|
41
|
+
|
|
42
|
+
```javascript
|
|
43
|
+
usethis_todo_write({
|
|
44
|
+
todos: [
|
|
45
|
+
{
|
|
46
|
+
id: "E01-S01-T01",
|
|
47
|
+
content: "Setup database schema",
|
|
48
|
+
status: "todo",
|
|
49
|
+
priority: "HIGH"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
id: "E01-S01-T02",
|
|
53
|
+
content: "Create API endpoints",
|
|
54
|
+
status: "todo",
|
|
55
|
+
priority: "HIGH",
|
|
56
|
+
blockedBy: ["E01-S01-T01"] // Waits for T01
|
|
57
|
+
}
|
|
58
|
+
]
|
|
59
|
+
})
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**Output:**
|
|
63
|
+
```
|
|
64
|
+
TODO Graph [0/2 done, 0 in progress]
|
|
65
|
+
|
|
66
|
+
All Tasks:
|
|
67
|
+
- E01
|
|
68
|
+
- E01-S01
|
|
69
|
+
- ○ 🟠 E01-S01-T01: Setup database schema
|
|
70
|
+
- ⊗ 🟠 E01-S01-T02: Create API endpoints ← E01-S01-T01
|
|
71
|
+
|
|
72
|
+
Available Now:
|
|
73
|
+
- E01
|
|
74
|
+
- E01-S01
|
|
75
|
+
- ○ 🟠 E01-S01-T01: Setup database schema
|
|
76
|
+
|
|
77
|
+
Blocked:
|
|
78
|
+
- E01
|
|
79
|
+
- E01-S01
|
|
80
|
+
- ⊗ 🟠 E01-S01-T02: Create API endpoints ← E01-S01-T01
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## 🎯 Core Features
|
|
86
|
+
|
|
87
|
+
### 1. Dependency Graph
|
|
88
|
+
|
|
89
|
+
Tasks can depend on other tasks. The plugin automatically:
|
|
90
|
+
- ✅ Shows which tasks are **available** (no blockers)
|
|
91
|
+
- ⊗ Shows which tasks are **blocked** (waiting on others)
|
|
92
|
+
- 🔗 Resolves **transitive dependencies** (A → B → C)
|
|
93
|
+
- ⚡ Identifies **parallel tasks** (can work on simultaneously)
|
|
94
|
+
|
|
95
|
+
**Example:**
|
|
96
|
+
```javascript
|
|
97
|
+
usethis_todo_write({
|
|
98
|
+
todos: [
|
|
99
|
+
{ id: "T01", content: "Design API", status: "done", priority: "HIGH" },
|
|
100
|
+
{ id: "T02", content: "Implement API", status: "todo", priority: "HIGH", blockedBy: ["T01"] },
|
|
101
|
+
{ id: "T03", content: "Write tests", status: "todo", priority: "MED", blockedBy: ["T02"] },
|
|
102
|
+
{ id: "T04", content: "Setup CI/CD", status: "todo", priority: "MED" } // Parallel!
|
|
103
|
+
]
|
|
104
|
+
})
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**Graph shows:**
|
|
108
|
+
- **Available:** T02 (T01 done), T04 (no blockers)
|
|
109
|
+
- **Blocked:** T03 (waits for T02)
|
|
110
|
+
- **Parallel:** T02 and T04 can be done simultaneously
|
|
111
|
+
|
|
112
|
+
### 2. Priority System
|
|
113
|
+
|
|
114
|
+
Four priority levels with visual indicators:
|
|
115
|
+
|
|
116
|
+
| Priority | Icon | Use Case |
|
|
117
|
+
|----------|------|----------|
|
|
118
|
+
| `CRIT` | 🔴 | Production down, security issue |
|
|
119
|
+
| `HIGH` | 🟠 | Sprint goal, blocking others |
|
|
120
|
+
| `MED` | 🟡 | Normal work (default) |
|
|
121
|
+
| `LOW` | 🟢 | Nice to have, refactoring |
|
|
122
|
+
|
|
123
|
+
Tasks are **auto-sorted** by priority in all views.
|
|
124
|
+
|
|
125
|
+
### 3. Hierarchical IDs
|
|
126
|
+
|
|
127
|
+
Organize tasks in 3 levels:
|
|
128
|
+
|
|
129
|
+
```
|
|
130
|
+
E01-S01-T01
|
|
131
|
+
│ │ └── Task 01
|
|
132
|
+
│ └────── Story 01
|
|
133
|
+
└────────── Epic 01
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**Benefits:**
|
|
137
|
+
- 📁 Nested display (epics → stories → tasks)
|
|
138
|
+
- 🔍 Easy filtering (all tasks in E01-S01)
|
|
139
|
+
- 📊 Progress tracking per epic/story
|
|
140
|
+
|
|
141
|
+
### 4. Status Lifecycle
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
todo → in_progress → ready → done
|
|
145
|
+
↓ ↓ ↓ ↓
|
|
146
|
+
○ ⚙ ⏳ ✓
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
**Auto-transitions:**
|
|
150
|
+
- `ready` → `done` when `releases` field is set
|
|
151
|
+
- Blocked tasks show `⊗` icon (even if status is `todo`)
|
|
152
|
+
|
|
153
|
+
### 5. Release Tracking
|
|
154
|
+
|
|
155
|
+
Mark tasks as part of releases:
|
|
156
|
+
|
|
157
|
+
```javascript
|
|
158
|
+
usethis_todo_update({
|
|
159
|
+
todos: [{
|
|
160
|
+
id: "E01-S01-T01",
|
|
161
|
+
status: "ready",
|
|
162
|
+
releases: ["v1.2.0"] // Auto-promotes to "done"
|
|
163
|
+
}]
|
|
164
|
+
})
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## 🛠️ Tools Reference
|
|
170
|
+
|
|
171
|
+
### `usethis_todo_write`
|
|
172
|
+
|
|
173
|
+
Create or replace entire TODO list.
|
|
174
|
+
|
|
175
|
+
```javascript
|
|
176
|
+
usethis_todo_write({
|
|
177
|
+
todos: [
|
|
178
|
+
{
|
|
179
|
+
id: "E01-S01-T01", // Required: Hierarchical ID
|
|
180
|
+
content: "Task summary", // Required: Short description
|
|
181
|
+
description: "Full details...", // Optional: Long description
|
|
182
|
+
status: "todo", // Required: todo | in_progress | ready | done
|
|
183
|
+
priority: "HIGH", // Required: CRIT | HIGH | MED | LOW
|
|
184
|
+
blockedBy: ["E01-S01-T02"], // Optional: Dependency IDs
|
|
185
|
+
releases: ["v1.0.0"] // Optional: Release tags
|
|
186
|
+
}
|
|
187
|
+
]
|
|
188
|
+
})
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
**Returns:** Full graph analysis
|
|
192
|
+
|
|
193
|
+
### `usethis_todo_read`
|
|
194
|
+
|
|
195
|
+
Read all tasks with graph analysis.
|
|
196
|
+
|
|
197
|
+
```javascript
|
|
198
|
+
usethis_todo_read()
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
**Returns:**
|
|
202
|
+
- All tasks (nested by epic/story)
|
|
203
|
+
- Available tasks (ready to work on)
|
|
204
|
+
- Blocked tasks (waiting on dependencies)
|
|
205
|
+
- Progress stats (X/Y done, Z in progress)
|
|
206
|
+
|
|
207
|
+
### `usethis_todo_read_five`
|
|
208
|
+
|
|
209
|
+
Get next 5 available tasks (smart view).
|
|
210
|
+
|
|
211
|
+
```javascript
|
|
212
|
+
usethis_todo_read_five()
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
**Returns:**
|
|
216
|
+
- Top 5 tasks by priority
|
|
217
|
+
- Resolved blockers (what they depend on)
|
|
218
|
+
- Missing dependencies (if any)
|
|
219
|
+
|
|
220
|
+
**Perfect for:** "What should I work on next?"
|
|
221
|
+
|
|
222
|
+
### `usethis_todo_read_by_id`
|
|
223
|
+
|
|
224
|
+
Get details for specific task.
|
|
225
|
+
|
|
226
|
+
```javascript
|
|
227
|
+
usethis_todo_read_by_id({ id: "E01-S01-T01" })
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
**Returns:**
|
|
231
|
+
- Task details
|
|
232
|
+
- Full dependency chain
|
|
233
|
+
- Missing dependencies
|
|
234
|
+
|
|
235
|
+
### `usethis_todo_update`
|
|
236
|
+
|
|
237
|
+
Update one or more tasks (merge mode).
|
|
238
|
+
|
|
239
|
+
```javascript
|
|
240
|
+
usethis_todo_update({
|
|
241
|
+
todos: [
|
|
242
|
+
{
|
|
243
|
+
id: "E01-S01-T01",
|
|
244
|
+
status: "done" // Only update status, keep other fields
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
id: "E01-S01-T02",
|
|
248
|
+
status: "in_progress",
|
|
249
|
+
priority: "CRIT" // Update multiple fields
|
|
250
|
+
}
|
|
251
|
+
]
|
|
252
|
+
})
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
**Returns:** Updated graph
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## 🎨 Usage Examples
|
|
260
|
+
|
|
261
|
+
### Example 1: Sprint Planning
|
|
262
|
+
|
|
263
|
+
```javascript
|
|
264
|
+
// Create sprint tasks
|
|
265
|
+
usethis_todo_write({
|
|
266
|
+
todos: [
|
|
267
|
+
// Epic 01: User Authentication
|
|
268
|
+
{ id: "E01-S01-T01", content: "Design auth API", status: "done", priority: "HIGH" },
|
|
269
|
+
{ id: "E01-S01-T02", content: "Implement JWT", status: "in_progress", priority: "HIGH", blockedBy: ["E01-S01-T01"] },
|
|
270
|
+
{ id: "E01-S01-T03", content: "Add refresh tokens", status: "todo", priority: "MED", blockedBy: ["E01-S01-T02"] },
|
|
271
|
+
|
|
272
|
+
// Epic 02: User Profile (parallel work)
|
|
273
|
+
{ id: "E02-S01-T01", content: "Design profile schema", status: "todo", priority: "MED" },
|
|
274
|
+
{ id: "E02-S01-T02", content: "Create profile API", status: "todo", priority: "MED", blockedBy: ["E02-S01-T01"] }
|
|
275
|
+
]
|
|
276
|
+
})
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
**Graph shows:**
|
|
280
|
+
- **Available:** E01-S01-T02 (in progress), E02-S01-T01 (can start)
|
|
281
|
+
- **Blocked:** E01-S01-T03, E02-S01-T02
|
|
282
|
+
- **Parallel:** E01 and E02 can progress simultaneously
|
|
283
|
+
|
|
284
|
+
### Example 2: Daily Workflow
|
|
285
|
+
|
|
286
|
+
```javascript
|
|
287
|
+
// Morning: What's next?
|
|
288
|
+
usethis_todo_read_five()
|
|
289
|
+
// → Shows top 5 tasks by priority
|
|
290
|
+
|
|
291
|
+
// Start working
|
|
292
|
+
usethis_todo_update({
|
|
293
|
+
todos: [{ id: "E01-S01-T02", status: "in_progress" }]
|
|
294
|
+
})
|
|
295
|
+
|
|
296
|
+
// Finish task
|
|
297
|
+
usethis_todo_update({
|
|
298
|
+
todos: [{ id: "E01-S01-T02", status: "done" }]
|
|
299
|
+
})
|
|
300
|
+
|
|
301
|
+
// Check what unblocked
|
|
302
|
+
usethis_todo_read_five()
|
|
303
|
+
// → E01-S01-T03 now available!
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### Example 3: Bug Triage
|
|
307
|
+
|
|
308
|
+
```javascript
|
|
309
|
+
// Critical bug found!
|
|
310
|
+
usethis_todo_update({
|
|
311
|
+
todos: [{
|
|
312
|
+
id: "BUG-001",
|
|
313
|
+
content: "Fix login crash",
|
|
314
|
+
status: "todo",
|
|
315
|
+
priority: "CRIT" // Jumps to top of queue
|
|
316
|
+
}]
|
|
317
|
+
})
|
|
318
|
+
|
|
319
|
+
usethis_todo_read_five()
|
|
320
|
+
// → BUG-001 is first (CRIT priority)
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### Example 4: Release Management
|
|
324
|
+
|
|
325
|
+
```javascript
|
|
326
|
+
// Mark tasks for release
|
|
327
|
+
usethis_todo_update({
|
|
328
|
+
todos: [
|
|
329
|
+
{ id: "E01-S01-T01", status: "ready", releases: ["v1.0.0"] },
|
|
330
|
+
{ id: "E01-S01-T02", status: "ready", releases: ["v1.0.0"] }
|
|
331
|
+
]
|
|
332
|
+
})
|
|
333
|
+
// → Auto-promotes to "done" when releases set
|
|
334
|
+
|
|
335
|
+
// Check release progress
|
|
336
|
+
usethis_todo_read()
|
|
337
|
+
// → See all tasks tagged with v1.0.0
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
### Example 5: Complex Dependencies
|
|
341
|
+
|
|
342
|
+
```javascript
|
|
343
|
+
usethis_todo_write({
|
|
344
|
+
todos: [
|
|
345
|
+
{ id: "T01", content: "Database schema", status: "done", priority: "HIGH" },
|
|
346
|
+
{ id: "T02", content: "API layer", status: "done", priority: "HIGH", blockedBy: ["T01"] },
|
|
347
|
+
{ id: "T03", content: "Business logic", status: "todo", priority: "HIGH", blockedBy: ["T02"] },
|
|
348
|
+
{ id: "T04", content: "UI components", status: "todo", priority: "MED", blockedBy: ["T03"] },
|
|
349
|
+
{ id: "T05", content: "Integration tests", status: "todo", priority: "MED", blockedBy: ["T04"] }
|
|
350
|
+
]
|
|
351
|
+
})
|
|
352
|
+
|
|
353
|
+
// Check specific task
|
|
354
|
+
usethis_todo_read_by_id({ id: "T05" })
|
|
355
|
+
// → Shows full chain: T05 ← T04 ← T03 ← T02 ← T01
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
---
|
|
359
|
+
|
|
360
|
+
## 📦 Storage
|
|
361
|
+
|
|
362
|
+
### Dual Storage System
|
|
363
|
+
|
|
364
|
+
The plugin writes to **two locations**:
|
|
365
|
+
|
|
366
|
+
#### 1. Enhanced Storage (Project-local)
|
|
367
|
+
```
|
|
368
|
+
.opencode/
|
|
369
|
+
session-todo/
|
|
370
|
+
{session-id}.json # Full data with dependencies
|
|
371
|
+
todo.log # Action log
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
**Contains:**
|
|
375
|
+
- Full task data (description, blockedBy, releases)
|
|
376
|
+
- Timestamps (createdAt, updatedAt)
|
|
377
|
+
- All custom fields
|
|
378
|
+
|
|
379
|
+
#### 2. Native Storage (TUI Integration)
|
|
380
|
+
```
|
|
381
|
+
~/.local/share/opencode/storage/todo/{session-id}.json
|
|
382
|
+
# or
|
|
383
|
+
~/Library/Application Support/opencode/storage/todo/{session-id}.json
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
**Contains:**
|
|
387
|
+
- Simplified format for OpenCode TUI
|
|
388
|
+
- Status/priority mapped to native values
|
|
389
|
+
- Dependencies shown in content field
|
|
390
|
+
|
|
391
|
+
**Why dual storage?**
|
|
392
|
+
- ✅ Enhanced features (graph, dependencies)
|
|
393
|
+
- ✅ Native TUI display (sidebar integration)
|
|
394
|
+
- ✅ Best of both worlds!
|
|
395
|
+
|
|
396
|
+
---
|
|
397
|
+
|
|
398
|
+
## 🎨 Visual Indicators
|
|
399
|
+
|
|
400
|
+
### Status Icons
|
|
401
|
+
|
|
402
|
+
| Icon | Status | Meaning |
|
|
403
|
+
|------|--------|---------|
|
|
404
|
+
| ○ | `todo` | Not started |
|
|
405
|
+
| ⚙ | `in_progress` | Working on it |
|
|
406
|
+
| ⏳ | `ready` | Done, awaiting release |
|
|
407
|
+
| ✓ | `done` | Completed |
|
|
408
|
+
| ✗ | `cancelled` | Abandoned |
|
|
409
|
+
| ⊗ | (blocked) | Has active blockers |
|
|
410
|
+
|
|
411
|
+
### Priority Icons
|
|
412
|
+
|
|
413
|
+
| Icon | Priority | Color |
|
|
414
|
+
|------|----------|-------|
|
|
415
|
+
| 🔴 | CRIT | Red |
|
|
416
|
+
| 🟠 | HIGH | Orange |
|
|
417
|
+
| 🟡 | MED | Yellow |
|
|
418
|
+
| 🟢 | LOW | Green |
|
|
419
|
+
|
|
420
|
+
---
|
|
421
|
+
|
|
422
|
+
## 🧠 Smart Features
|
|
423
|
+
|
|
424
|
+
### 1. Auto-Promotion
|
|
425
|
+
|
|
426
|
+
Tasks automatically transition when conditions are met:
|
|
427
|
+
|
|
428
|
+
```javascript
|
|
429
|
+
// Task in "ready" status
|
|
430
|
+
{ id: "T01", status: "ready", releases: [] }
|
|
431
|
+
|
|
432
|
+
// Add release tag
|
|
433
|
+
usethis_todo_update({
|
|
434
|
+
todos: [{ id: "T01", releases: ["v1.0.0"] }]
|
|
435
|
+
})
|
|
436
|
+
|
|
437
|
+
// → Auto-promotes to "done"!
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
### 2. Transitive Dependencies
|
|
441
|
+
|
|
442
|
+
The plugin resolves entire dependency chains:
|
|
443
|
+
|
|
444
|
+
```javascript
|
|
445
|
+
// T03 depends on T02, T02 depends on T01
|
|
446
|
+
usethis_todo_read_by_id({ id: "T03" })
|
|
447
|
+
|
|
448
|
+
// Shows full chain:
|
|
449
|
+
// Blocked By (resolved):
|
|
450
|
+
// - T02 (in_progress)
|
|
451
|
+
// - T01 (done)
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
### 3. Parallel Detection
|
|
455
|
+
|
|
456
|
+
Identifies tasks that can be worked on simultaneously:
|
|
457
|
+
|
|
458
|
+
```javascript
|
|
459
|
+
// Graph analysis shows:
|
|
460
|
+
// Parallel groups:
|
|
461
|
+
// - [T02, T04, T05] ← Can all start now
|
|
462
|
+
// - [T03, T06] ← Can start after T02 done
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
### 4. Missing Dependency Detection
|
|
466
|
+
|
|
467
|
+
Warns about broken references:
|
|
468
|
+
|
|
469
|
+
```javascript
|
|
470
|
+
{ id: "T01", blockedBy: ["T99"] } // T99 doesn't exist
|
|
471
|
+
|
|
472
|
+
usethis_todo_read_by_id({ id: "T01" })
|
|
473
|
+
// → Blocked By missing: T99
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
---
|
|
477
|
+
|
|
478
|
+
## 🔧 Advanced Usage
|
|
479
|
+
|
|
480
|
+
### Custom ID Schemes
|
|
481
|
+
|
|
482
|
+
While hierarchical IDs are recommended, you can use any format:
|
|
483
|
+
|
|
484
|
+
```javascript
|
|
485
|
+
// Hierarchical (recommended)
|
|
486
|
+
{ id: "E01-S01-T01" } // Epic-Story-Task
|
|
487
|
+
|
|
488
|
+
// Flat
|
|
489
|
+
{ id: "TASK-001" }
|
|
490
|
+
|
|
491
|
+
// Custom
|
|
492
|
+
{ id: "AUTH-LOGIN-JWT" }
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
**Note:** Hierarchical IDs get nested display, others show flat.
|
|
496
|
+
|
|
497
|
+
### Filtering by Status
|
|
498
|
+
|
|
499
|
+
```javascript
|
|
500
|
+
// Get all in-progress tasks
|
|
501
|
+
const todos = await usethis_todo_read()
|
|
502
|
+
const wip = todos.filter(t => t.status === "in_progress")
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
### Progress Tracking
|
|
506
|
+
|
|
507
|
+
```javascript
|
|
508
|
+
// Track epic progress
|
|
509
|
+
const todos = await usethis_todo_read()
|
|
510
|
+
const epic01 = todos.filter(t => t.id.startsWith("E01-"))
|
|
511
|
+
const done = epic01.filter(t => t.status === "done").length
|
|
512
|
+
const total = epic01.length
|
|
513
|
+
console.log(`Epic 01: ${done}/${total} done`)
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
---
|
|
517
|
+
|
|
518
|
+
## 🐛 Debugging
|
|
519
|
+
|
|
520
|
+
### Enable Logging
|
|
521
|
+
|
|
522
|
+
All operations are logged to `.opencode/todo.log`:
|
|
523
|
+
|
|
524
|
+
```
|
|
525
|
+
[2024-01-15T10:30:00.000Z] WRITE: Created/Updated 5 tasks in session abc123
|
|
526
|
+
[2024-01-15T10:31:00.000Z] UPDATE: Updated 1 task(s) in session abc123
|
|
527
|
+
[2024-01-15T10:32:00.000Z] READ_FIVE: Read next 5 tasks (total ready: 12)
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
### Check Storage
|
|
531
|
+
|
|
532
|
+
```bash
|
|
533
|
+
# Enhanced storage
|
|
534
|
+
cat .opencode/session-todo/{session-id}.json
|
|
535
|
+
|
|
536
|
+
# Native storage (macOS)
|
|
537
|
+
cat ~/Library/Application\ Support/opencode/storage/todo/{session-id}.json
|
|
538
|
+
|
|
539
|
+
# Native storage (Linux)
|
|
540
|
+
cat ~/.local/share/opencode/storage/todo/{session-id}.json
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
### Validate Dependencies
|
|
544
|
+
|
|
545
|
+
```javascript
|
|
546
|
+
// Check for circular dependencies
|
|
547
|
+
usethis_todo_read()
|
|
548
|
+
// → Graph analysis will show if tasks are mutually blocked
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
---
|
|
552
|
+
|
|
553
|
+
## 🌟 Advantages
|
|
554
|
+
|
|
555
|
+
### Compared to Simple TODO Lists
|
|
556
|
+
|
|
557
|
+
| Feature | Simple TODO | usethis_todo |
|
|
558
|
+
|---------|-------------|--------------|
|
|
559
|
+
| Task list | ✅ | ✅ |
|
|
560
|
+
| Dependencies | ❌ | ✅ |
|
|
561
|
+
| Priority sorting | ❌ | ✅ |
|
|
562
|
+
| Graph analysis | ❌ | ✅ |
|
|
563
|
+
| Parallel detection | ❌ | ✅ |
|
|
564
|
+
| Hierarchical IDs | ❌ | ✅ |
|
|
565
|
+
| Auto-transitions | ❌ | ✅ |
|
|
566
|
+
| Release tracking | ❌ | ✅ |
|
|
567
|
+
|
|
568
|
+
### Compared to Project Management Tools
|
|
569
|
+
|
|
570
|
+
| Feature | Jira/Asana | usethis_todo |
|
|
571
|
+
|---------|------------|--------------|
|
|
572
|
+
| In your editor | ❌ | ✅ |
|
|
573
|
+
| Offline | ❌ | ✅ |
|
|
574
|
+
| Free | ❌ | ✅ |
|
|
575
|
+
| Fast | 🐌 | ⚡ |
|
|
576
|
+
| No context switch | ❌ | ✅ |
|
|
577
|
+
| Version controlled | ❌ | ✅ (project-local) |
|
|
578
|
+
|
|
579
|
+
---
|
|
580
|
+
|
|
581
|
+
## 📊 Technical Details
|
|
582
|
+
|
|
583
|
+
- **Storage format:** JSON
|
|
584
|
+
- **Session isolation:** Tasks are per-session (multi-session support)
|
|
585
|
+
- **Dependency resolution:** Recursive graph traversal
|
|
586
|
+
- **Priority sorting:** Stable sort (CRIT → HIGH → MED → LOW → ID)
|
|
587
|
+
- **Status normalization:** Backward-compatible with old formats
|
|
588
|
+
- **TUI integration:** Automatic sync to native storage
|
|
589
|
+
|
|
590
|
+
---
|
|
591
|
+
|
|
592
|
+
## 🤝 Contributing
|
|
593
|
+
|
|
594
|
+
Found a bug? Have an idea? Open an issue or PR!
|
|
595
|
+
|
|
596
|
+
---
|
|
597
|
+
|
|
598
|
+
## 📄 License
|
|
599
|
+
|
|
600
|
+
MIT
|
|
601
|
+
|
|
602
|
+
---
|
|
603
|
+
|
|
604
|
+
## 🎉 Authors
|
|
605
|
+
|
|
606
|
+
Made with ❤️ by the **Comfanion** team
|
|
607
|
+
|
|
608
|
+
---
|
|
609
|
+
|
|
610
|
+
**Work smart, not hard — let the graph guide you!** 🚀
|
package/package.json
CHANGED
package/tools.ts
CHANGED
|
@@ -29,6 +29,45 @@ import fs from "fs/promises"
|
|
|
29
29
|
// Types
|
|
30
30
|
// ============================================================================
|
|
31
31
|
|
|
32
|
+
interface TodoFile {
|
|
33
|
+
path: string // File path (relative to project root)
|
|
34
|
+
role: "input" | "output" | "test" | "doc" | "config" | "main" | "graph"
|
|
35
|
+
addedAt: string // ISO timestamp when linked
|
|
36
|
+
addedBy: "manual" | "auto" // How it was added
|
|
37
|
+
lastAccessed?: string // Last read/write timestamp
|
|
38
|
+
toolIds?: number[] // Tool call IDs that touched this file
|
|
39
|
+
preserve?: boolean // Don't prune even on TODO complete
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
interface TodoTool {
|
|
43
|
+
toolName: string // Tool name (read, write, search, etc.)
|
|
44
|
+
callId: number // Tool call ID in session history
|
|
45
|
+
timestamp: string // ISO timestamp
|
|
46
|
+
filePath?: string // If tool operated on file
|
|
47
|
+
status: "success" | "error" // Tool execution status
|
|
48
|
+
tokens?: number // Tokens used by this tool result
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
interface TodoSearch {
|
|
52
|
+
query: string // Search query text
|
|
53
|
+
toolId: number // search() tool call ID
|
|
54
|
+
resultsCount: number // Number of results returned
|
|
55
|
+
timestamp: string // ISO timestamp
|
|
56
|
+
topResults?: string[] // Top file paths found
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
interface TodoContext {
|
|
60
|
+
totalTokens: number // Total tokens in all linked tools
|
|
61
|
+
createdAt: string // Task creation timestamp
|
|
62
|
+
startedAt?: string // When status → in_progress
|
|
63
|
+
completedAt?: string // When status → completed
|
|
64
|
+
estimatedCleanup: number // Estimated tokens prunable on complete
|
|
65
|
+
|
|
66
|
+
// Tracking
|
|
67
|
+
activeTracking: boolean // Is Mind currently tracking this TODO?
|
|
68
|
+
lastSync: string // Last time Mind synced metadata
|
|
69
|
+
}
|
|
70
|
+
|
|
32
71
|
interface Todo {
|
|
33
72
|
id: string // E01-S01-T01
|
|
34
73
|
content: string // Short task summary
|
|
@@ -39,6 +78,19 @@ interface Todo {
|
|
|
39
78
|
blockedBy?: string[] // IDs of blocking tasks
|
|
40
79
|
createdAt?: number
|
|
41
80
|
updatedAt?: number
|
|
81
|
+
|
|
82
|
+
// Mind extensions (backward compatible - optional)
|
|
83
|
+
files?: TodoFile[] // Associated files
|
|
84
|
+
tools?: TodoTool[] // Associated tool calls
|
|
85
|
+
searches?: TodoSearch[] // Associated searches
|
|
86
|
+
context?: TodoContext // Context metadata
|
|
87
|
+
|
|
88
|
+
// Cleanup configuration (optional)
|
|
89
|
+
cleanup?: {
|
|
90
|
+
onComplete?: "auto" | "manual" | "extract"
|
|
91
|
+
preserveFiles?: string[] // Glob patterns to preserve
|
|
92
|
+
preserveTools?: string[] // Tool names to preserve
|
|
93
|
+
}
|
|
42
94
|
}
|
|
43
95
|
|
|
44
96
|
interface NativeTodo {
|
|
@@ -260,11 +312,21 @@ function normalizeTodo(input: any): Todo {
|
|
|
260
312
|
// Auto transition: ready -> done when releases exist
|
|
261
313
|
const promotedStatus = status === "ready" && releases?.length ? "done" : status
|
|
262
314
|
|
|
263
|
-
|
|
315
|
+
// Initialize Mind extensions if provided (backward compatible)
|
|
316
|
+
const normalized: Todo = {
|
|
264
317
|
...input,
|
|
265
318
|
status: promotedStatus,
|
|
266
319
|
releases,
|
|
267
320
|
}
|
|
321
|
+
|
|
322
|
+
// Preserve existing Mind extensions if they exist
|
|
323
|
+
if (input.files) normalized.files = input.files
|
|
324
|
+
if (input.tools) normalized.tools = input.tools
|
|
325
|
+
if (input.searches) normalized.searches = input.searches
|
|
326
|
+
if (input.context) normalized.context = input.context
|
|
327
|
+
if (input.cleanup) normalized.cleanup = input.cleanup
|
|
328
|
+
|
|
329
|
+
return normalized
|
|
268
330
|
}
|
|
269
331
|
|
|
270
332
|
function prioRank(p?: string): number {
|
|
@@ -294,9 +356,14 @@ function todoLine(todo: Todo, byId: Map<string, Todo>): string {
|
|
|
294
356
|
const desc = todo.description?.trim() ? ` — ${todo.description.trim()}` : ""
|
|
295
357
|
const rel = todo.releases?.length ? ` [rel: ${todo.releases.join(", ")}]` : ""
|
|
296
358
|
const deps = todo.blockedBy?.length ? ` ← ${todo.blockedBy.join(", ")}` : ""
|
|
359
|
+
|
|
360
|
+
// Mind extensions
|
|
361
|
+
const files = todo.files?.length ? ` 📄${todo.files.length}` : ""
|
|
362
|
+
const tokens = todo.context?.totalTokens ? ` (${todo.context.totalTokens}t)` : ""
|
|
363
|
+
|
|
297
364
|
const ns = normalizeStatus(todo.status)
|
|
298
365
|
const icon = isBlocked(todo, byId) ? "⊗" : SI(ns)
|
|
299
|
-
return `${icon} ${PE(todo.priority)} ${todo.id}: ${todo.content}${desc}${rel}${deps}`
|
|
366
|
+
return `${icon} ${PE(todo.priority)} ${todo.id}: ${todo.content}${desc}${rel}${files}${tokens}${deps}`
|
|
300
367
|
}
|
|
301
368
|
|
|
302
369
|
function renderNestedTodoList(todos: Todo[], allTodos?: Todo[]): string {
|
|
@@ -411,17 +478,17 @@ function formatGraph(graph: TodoGraph): string {
|
|
|
411
478
|
// ============================================================================
|
|
412
479
|
|
|
413
480
|
export const write = tool({
|
|
414
|
-
description: "Create or update TODO list.
|
|
481
|
+
description: "Create or update TODO list. Use this for TODO. For better performance use ID for task relation",
|
|
415
482
|
args: {
|
|
416
483
|
todos: tool.schema.array(
|
|
417
484
|
tool.schema.object({
|
|
418
|
-
id: tool.schema.string().describe("Task ID in concat format: E01-S01-T01"),
|
|
419
|
-
content: tool.schema.string().describe("Short task summary"),
|
|
420
|
-
description: tool.schema.string().optional().describe("Full task description"),
|
|
421
|
-
releases: tool.schema.array(tool.schema.string()).optional().describe("Release
|
|
485
|
+
id: tool.schema.string().describe("Task ID in concat format: E01-S01-T01(for graph dependency)"),
|
|
486
|
+
content: tool.schema.string().describe("Short task summary or title"),
|
|
487
|
+
description: tool.schema.string().optional().describe("Full task description. Helps to remember what should be done"),
|
|
488
|
+
releases: tool.schema.array(tool.schema.string()).optional().describe("Set IDs for AUTO Release task from ready -> done(after review)"),
|
|
422
489
|
status: tool.schema.string().describe("todo | in_progress | ready | done"),
|
|
423
490
|
priority: tool.schema.string().describe("CRIT | HIGH | MED | LOW"),
|
|
424
|
-
blockedBy: tool.schema.array(tool.schema.string()).optional().describe("IDs of blocking tasks"),
|
|
491
|
+
blockedBy: tool.schema.array(tool.schema.string()).optional().describe("IDs of blocking tasks. this help you understand scope better"),
|
|
425
492
|
}),
|
|
426
493
|
).describe("Array of todos"),
|
|
427
494
|
},
|