@nijaru/tk 0.0.2 → 0.0.4
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 +8 -8
- package/package.json +1 -1
- package/src/cli.test.ts +83 -3
- package/src/cli.ts +102 -399
- package/src/db/storage.ts +137 -115
- package/src/lib/completions.ts +56 -56
- package/src/lib/format.test.ts +26 -12
- package/src/lib/format.ts +34 -34
- package/src/lib/help.ts +249 -0
- package/src/lib/time.ts +115 -0
package/README.md
CHANGED
|
@@ -33,9 +33,9 @@ myapp-x9k2
|
|
|
33
33
|
$ tk block x9k2 a7b3 # tests blocked by auth (just use ref)
|
|
34
34
|
|
|
35
35
|
$ tk ready # what can I work on?
|
|
36
|
-
ID | PRIO | STATUS
|
|
37
|
-
|
|
38
|
-
myapp-a7b3 | p1 | open
|
|
36
|
+
ID | PRIO | STATUS | TITLE
|
|
37
|
+
-----------------------------------------------------------------
|
|
38
|
+
myapp-a7b3 | p1 | open | Implement auth
|
|
39
39
|
|
|
40
40
|
$ tk start a7b3 # just the ref works everywhere
|
|
41
41
|
Started: myapp-a7b3
|
|
@@ -47,9 +47,9 @@ $ tk done a7b3
|
|
|
47
47
|
Completed: myapp-a7b3
|
|
48
48
|
|
|
49
49
|
$ tk ready # tests now unblocked
|
|
50
|
-
ID | PRIO | STATUS
|
|
51
|
-
|
|
52
|
-
myapp-x9k2 | p2 | open
|
|
50
|
+
ID | PRIO | STATUS | TITLE
|
|
51
|
+
-----------------------------------------------------------------
|
|
52
|
+
myapp-x9k2 | p2 | open | Write tests
|
|
53
53
|
```
|
|
54
54
|
|
|
55
55
|
## Commands
|
|
@@ -59,7 +59,7 @@ myapp-x9k2 | p2 | open | Write tests
|
|
|
59
59
|
| `tk init` | Initialize (project name from directory) |
|
|
60
60
|
| `tk add <title>` | Create task |
|
|
61
61
|
| `tk ls` / `tk list` | List tasks |
|
|
62
|
-
| `tk ready` | List open + unblocked tasks
|
|
62
|
+
| `tk ready` | List active/open + unblocked tasks |
|
|
63
63
|
| `tk show <id>` | Show task details |
|
|
64
64
|
| `tk start <id>` | Start working (open → active) |
|
|
65
65
|
| `tk done <id>` | Complete task |
|
|
@@ -130,7 +130,7 @@ tk clean --force # Force clean even if disabled in config
|
|
|
130
130
|
tk config # Show all config
|
|
131
131
|
tk config project # Show default project
|
|
132
132
|
tk config project api # Set default project
|
|
133
|
-
tk config project lsmvec --rename cloudlsmvec # Rename
|
|
133
|
+
tk config project lsmvec --rename cloudlsmvec # Rename cloudlsmvec-* → lsmvec-*
|
|
134
134
|
tk config alias # List aliases
|
|
135
135
|
tk config alias web src/web # Add alias
|
|
136
136
|
tk config alias --rm web # Remove alias
|
package/package.json
CHANGED
package/src/cli.test.ts
CHANGED
|
@@ -243,16 +243,96 @@ describe("tk CLI", () => {
|
|
|
243
243
|
const { stdout } = await run(["ls"], testDir);
|
|
244
244
|
expect(stdout).toContain("No tasks found");
|
|
245
245
|
});
|
|
246
|
+
|
|
247
|
+
test("sorts by status (active > open > done)", async () => {
|
|
248
|
+
const { stdout: idDone } = await run(["add", "Done task"], testDir);
|
|
249
|
+
await run(["done", idDone.trim()], testDir);
|
|
250
|
+
const { stdout: idActive } = await run(["add", "Active task"], testDir);
|
|
251
|
+
await run(["start", idActive.trim()], testDir);
|
|
252
|
+
await run(["add", "Open task"], testDir);
|
|
253
|
+
|
|
254
|
+
const { stdout } = await run(["ls"], testDir);
|
|
255
|
+
const lines = stdout
|
|
256
|
+
.trim()
|
|
257
|
+
.split("\n")
|
|
258
|
+
.filter((l) => l.includes("task"));
|
|
259
|
+
expect(lines[0]).toContain("Active task");
|
|
260
|
+
expect(lines[1]).toContain("Open task");
|
|
261
|
+
expect(lines[2]).toContain("Done task");
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
test("sorts by priority (p1-4, then p0/none)", async () => {
|
|
265
|
+
await run(["add", "Medium", "-p", "3"], testDir);
|
|
266
|
+
await run(["add", "Urgent", "-p", "1"], testDir);
|
|
267
|
+
await run(["add", "None", "-p", "0"], testDir);
|
|
268
|
+
await run(["add", "Low", "-p", "4"], testDir);
|
|
269
|
+
|
|
270
|
+
const { stdout } = await run(["ls"], testDir);
|
|
271
|
+
const lines = stdout
|
|
272
|
+
.trim()
|
|
273
|
+
.split("\n")
|
|
274
|
+
.filter((l) => /Medium|Urgent|None|Low/.test(l));
|
|
275
|
+
expect(lines[0]).toContain("Urgent");
|
|
276
|
+
expect(lines[1]).toContain("Medium");
|
|
277
|
+
expect(lines[2]).toContain("Low");
|
|
278
|
+
expect(lines[3]).toContain("None");
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
test("hoists overdue tasks to the top of their status group", async () => {
|
|
282
|
+
await run(["add", "Urgent Future", "-p", "1", "--due", "2099-01-01"], testDir);
|
|
283
|
+
await run(["add", "Low Overdue", "-p", "4", "--due", "2020-01-01"], testDir);
|
|
284
|
+
|
|
285
|
+
const { stdout } = await run(["ls"], testDir);
|
|
286
|
+
const lines = stdout
|
|
287
|
+
.trim()
|
|
288
|
+
.split("\n")
|
|
289
|
+
.filter((l) => /Future|Overdue/.test(l));
|
|
290
|
+
expect(lines[0]).toContain("Low Overdue");
|
|
291
|
+
expect(lines[1]).toContain("Urgent Future");
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
test("sorts by due date when priority is equal", async () => {
|
|
295
|
+
await run(["add", "Later", "-p", "3", "--due", "2099-01-02"], testDir);
|
|
296
|
+
await run(["add", "Earlier", "-p", "3", "--due", "2099-01-01"], testDir);
|
|
297
|
+
|
|
298
|
+
const { stdout } = await run(["ls"], testDir);
|
|
299
|
+
const lines = stdout
|
|
300
|
+
.trim()
|
|
301
|
+
.split("\n")
|
|
302
|
+
.filter((l) => /Earlier|Later/.test(l));
|
|
303
|
+
expect(lines[0]).toContain("Earlier");
|
|
304
|
+
expect(lines[1]).toContain("Later");
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
test("sorts done tasks by completion time (newest first)", async () => {
|
|
308
|
+
const { stdout: id1 } = await run(["add", "Done First"], testDir);
|
|
309
|
+
const { stdout: id2 } = await run(["add", "Done Second"], testDir);
|
|
310
|
+
await run(["done", id1.trim()], testDir);
|
|
311
|
+
// Ensure time difference
|
|
312
|
+
await new Promise((r) => setTimeout(r, 10));
|
|
313
|
+
await run(["done", id2.trim()], testDir);
|
|
314
|
+
|
|
315
|
+
const { stdout } = await run(["ls", "-s", "done"], testDir);
|
|
316
|
+
const lines = stdout
|
|
317
|
+
.trim()
|
|
318
|
+
.split("\n")
|
|
319
|
+
.filter((l) => l.includes("Done"));
|
|
320
|
+
expect(lines[0]).toContain("Done Second");
|
|
321
|
+
expect(lines[1]).toContain("Done First");
|
|
322
|
+
});
|
|
246
323
|
});
|
|
247
324
|
|
|
248
325
|
describe("ready", () => {
|
|
249
|
-
test("shows
|
|
250
|
-
const { stdout: id1 } = await run(["add", "
|
|
326
|
+
test("shows active and unblocked open tasks", async () => {
|
|
327
|
+
const { stdout: id1 } = await run(["add", "Active task"], testDir);
|
|
328
|
+
await run(["start", id1.trim()], testDir);
|
|
329
|
+
await run(["add", "Open task"], testDir);
|
|
251
330
|
const { stdout: id2 } = await run(["add", "Blocked task"], testDir);
|
|
252
331
|
await run(["block", id2.trim(), id1.trim()], testDir);
|
|
253
332
|
|
|
254
333
|
const { stdout } = await run(["ready"], testDir);
|
|
255
|
-
expect(stdout).toContain("
|
|
334
|
+
expect(stdout).toContain("Active task");
|
|
335
|
+
expect(stdout).toContain("Open task");
|
|
256
336
|
expect(stdout).not.toContain("Blocked task");
|
|
257
337
|
});
|
|
258
338
|
|