@obsfx/trekker 1.7.2 → 1.8.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 +30 -0
- package/dist/index.js +80 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -41,6 +41,7 @@ My concerns about the future and security of that project led me here. Trekker i
|
|
|
41
41
|
|
|
42
42
|
What you get:
|
|
43
43
|
- Task and epic tracking with dependencies
|
|
44
|
+
- Ready command to find unblocked tasks and see what they unblock
|
|
44
45
|
- Full-text search across tasks, epics, subtasks, and comments
|
|
45
46
|
- Unified list view with filtering by type, status, priority, and custom sorting
|
|
46
47
|
- Optional kanban board UI available as a [separate package](https://github.com/obsfx/trekker-dashboard)
|
|
@@ -78,6 +79,12 @@ trekker dep add TREK-2 TREK-1
|
|
|
78
79
|
trekker dep add TREK-3 TREK-1
|
|
79
80
|
```
|
|
80
81
|
|
|
82
|
+
See what is ready to work on:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
trekker ready
|
|
86
|
+
```
|
|
87
|
+
|
|
81
88
|
Update task status as you work:
|
|
82
89
|
|
|
83
90
|
```bash
|
|
@@ -142,6 +149,29 @@ trekker dep remove <task-id> <depends-on-id>
|
|
|
142
149
|
trekker dep list <task-id>
|
|
143
150
|
```
|
|
144
151
|
|
|
152
|
+
### Ready
|
|
153
|
+
|
|
154
|
+
Show tasks that are ready to work on — unblocked and in `todo` status. For each ready task, shows downstream dependents that will be unblocked once it is completed:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
trekker ready
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Example output:
|
|
161
|
+
```
|
|
162
|
+
2 ready task(s):
|
|
163
|
+
|
|
164
|
+
TREK-1 | P0 | Setup database
|
|
165
|
+
-> unblocks TREK-2 | todo | P1 | Build API layer
|
|
166
|
+
-> unblocks TREK-3 | todo | P1 | Build UI layer
|
|
167
|
+
TREK-4 | P2 | Write docs
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Tasks are sorted by priority (critical first). A task is considered ready when:
|
|
171
|
+
- Status is `todo`
|
|
172
|
+
- It is a top-level task (not a subtask)
|
|
173
|
+
- All its dependencies are resolved (`completed`, `wont_fix`, or `archived`)
|
|
174
|
+
|
|
145
175
|
### Search
|
|
146
176
|
|
|
147
177
|
Full-text search across epics, tasks, subtasks, and comments using FTS5:
|
package/dist/index.js
CHANGED
|
@@ -455,7 +455,7 @@ var require_customParseFormat = __commonJS((exports, module) => {
|
|
|
455
455
|
});
|
|
456
456
|
|
|
457
457
|
// src/index.ts
|
|
458
|
-
import { Command as
|
|
458
|
+
import { Command as Command14 } from "commander";
|
|
459
459
|
|
|
460
460
|
// src/commands/init.ts
|
|
461
461
|
import { Command } from "commander";
|
|
@@ -3369,10 +3369,86 @@ function formatItem(item) {
|
|
|
3369
3369
|
const parentLabel = item.parentId ? ` (${item.parentId})` : "";
|
|
3370
3370
|
return `${typeLabel} ${item.id} | ${statusLabel} | ${priorityLabel} | ${item.title}${parentLabel}`;
|
|
3371
3371
|
}
|
|
3372
|
+
|
|
3373
|
+
// src/commands/ready.ts
|
|
3374
|
+
import { Command as Command13 } from "commander";
|
|
3375
|
+
|
|
3376
|
+
// src/services/ready.ts
|
|
3377
|
+
function getReadyTasks() {
|
|
3378
|
+
const sqlite = requireSqliteInstance();
|
|
3379
|
+
const readyRows = sqlite.query(`
|
|
3380
|
+
SELECT t.id, t.title, t.description, t.priority, t.status,
|
|
3381
|
+
t.epic_id, t.tags, t.created_at, t.updated_at
|
|
3382
|
+
FROM tasks t
|
|
3383
|
+
WHERE t.status = 'todo'
|
|
3384
|
+
AND t.parent_task_id IS NULL
|
|
3385
|
+
AND NOT EXISTS (
|
|
3386
|
+
SELECT 1 FROM dependencies d
|
|
3387
|
+
JOIN tasks dt ON dt.id = d.depends_on_id
|
|
3388
|
+
WHERE d.task_id = t.id
|
|
3389
|
+
AND dt.status NOT IN ('completed', 'wont_fix', 'archived')
|
|
3390
|
+
)
|
|
3391
|
+
ORDER BY t.priority ASC, t.created_at ASC
|
|
3392
|
+
`).all();
|
|
3393
|
+
const dependentsQuery = sqlite.query(`
|
|
3394
|
+
SELECT t.id, t.title, t.status, t.priority
|
|
3395
|
+
FROM dependencies d
|
|
3396
|
+
JOIN tasks t ON t.id = d.task_id
|
|
3397
|
+
WHERE d.depends_on_id = ?
|
|
3398
|
+
ORDER BY t.priority ASC
|
|
3399
|
+
`);
|
|
3400
|
+
return readyRows.map((row) => ({
|
|
3401
|
+
id: row.id,
|
|
3402
|
+
title: row.title,
|
|
3403
|
+
description: row.description,
|
|
3404
|
+
priority: row.priority,
|
|
3405
|
+
status: row.status,
|
|
3406
|
+
epicId: row.epic_id,
|
|
3407
|
+
tags: row.tags,
|
|
3408
|
+
createdAt: new Date(row.created_at * 1000),
|
|
3409
|
+
updatedAt: new Date(row.updated_at * 1000),
|
|
3410
|
+
dependents: dependentsQuery.all(row.id).map((d) => ({
|
|
3411
|
+
id: d.id,
|
|
3412
|
+
title: d.title,
|
|
3413
|
+
status: d.status,
|
|
3414
|
+
priority: d.priority
|
|
3415
|
+
}))
|
|
3416
|
+
}));
|
|
3417
|
+
}
|
|
3418
|
+
|
|
3419
|
+
// src/commands/ready.ts
|
|
3420
|
+
var readyCommand = new Command13("ready").description("Show tasks that are ready to work on (unblocked, todo)").action(() => {
|
|
3421
|
+
try {
|
|
3422
|
+
const readyTasks = getReadyTasks();
|
|
3423
|
+
outputResult(readyTasks, formatReadyTasks);
|
|
3424
|
+
} catch (err) {
|
|
3425
|
+
handleCommandError(err);
|
|
3426
|
+
}
|
|
3427
|
+
});
|
|
3428
|
+
function formatReadyTasks(tasks2) {
|
|
3429
|
+
if (tasks2.length === 0) {
|
|
3430
|
+
return "No ready tasks found.";
|
|
3431
|
+
}
|
|
3432
|
+
const lines = [];
|
|
3433
|
+
lines.push(`${tasks2.length} ready task(s):
|
|
3434
|
+
`);
|
|
3435
|
+
for (const task of tasks2) {
|
|
3436
|
+
const epic = task.epicId ? ` (${task.epicId})` : "";
|
|
3437
|
+
const tags = task.tags ? ` [${task.tags}]` : "";
|
|
3438
|
+
lines.push(`${task.id} | P${task.priority} | ${task.title}${epic}${tags}`);
|
|
3439
|
+
if (task.dependents.length > 0) {
|
|
3440
|
+
for (const dep of task.dependents) {
|
|
3441
|
+
lines.push(` -> unblocks ${dep.id} | ${dep.status.padEnd(11)} | P${dep.priority} | ${dep.title}`);
|
|
3442
|
+
}
|
|
3443
|
+
}
|
|
3444
|
+
}
|
|
3445
|
+
return lines.join(`
|
|
3446
|
+
`);
|
|
3447
|
+
}
|
|
3372
3448
|
// package.json
|
|
3373
3449
|
var package_default = {
|
|
3374
3450
|
name: "@obsfx/trekker",
|
|
3375
|
-
version: "1.
|
|
3451
|
+
version: "1.8.0",
|
|
3376
3452
|
description: "A CLI-based issue tracker built for AI coding agents. Stores tasks, epics, and dependencies in a local SQLite database.",
|
|
3377
3453
|
type: "module",
|
|
3378
3454
|
main: "dist/index.js",
|
|
@@ -3434,7 +3510,7 @@ var package_default = {
|
|
|
3434
3510
|
};
|
|
3435
3511
|
|
|
3436
3512
|
// src/index.ts
|
|
3437
|
-
var program = new
|
|
3513
|
+
var program = new Command14;
|
|
3438
3514
|
program.name("trekker").description("CLI-based issue tracker for coding agents").version(package_default.version).option("--toon", "Output in TOON format").hook("preAction", (thisCommand) => {
|
|
3439
3515
|
const opts = thisCommand.opts();
|
|
3440
3516
|
if (opts.toon) {
|
|
@@ -3453,4 +3529,5 @@ program.addCommand(seedCommand);
|
|
|
3453
3529
|
program.addCommand(searchCommand);
|
|
3454
3530
|
program.addCommand(historyCommand);
|
|
3455
3531
|
program.addCommand(listCommand);
|
|
3532
|
+
program.addCommand(readyCommand);
|
|
3456
3533
|
program.parse();
|
package/package.json
CHANGED