trekoon 0.3.3 → 0.3.5
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/.agents/skills/trekoon/SKILL.md +93 -3
- package/README.md +152 -126
- package/docs/ai-agents.md +105 -104
- package/docs/commands.md +145 -167
- package/docs/machine-contracts.md +240 -68
- package/docs/quickstart.md +78 -148
- package/package.json +1 -1
- package/src/commands/help.ts +249 -253
- package/src/commands/quickstart.ts +73 -77
- package/src/commands/skills.ts +104 -19
- package/src/commands/sync.ts +188 -15
- package/src/domain/tracker-domain.ts +210 -37
- package/src/storage/events-retention.ts +72 -0
- package/src/storage/migrations.ts +28 -0
- package/src/sync/event-writes.ts +8 -6
- package/src/sync/service.ts +299 -64
- package/src/sync/types.ts +36 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# Machine contracts
|
|
2
2
|
|
|
3
|
-
Use `--toon` for
|
|
4
|
-
|
|
3
|
+
Use `--toon` for agent loops. Use `--json` only when an integration explicitly
|
|
4
|
+
requires JSON.
|
|
5
5
|
|
|
6
6
|
## Base envelope
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Every machine response uses the same top-level shape:
|
|
9
9
|
|
|
10
10
|
```text
|
|
11
11
|
ok: true|false
|
|
@@ -16,23 +16,20 @@ metadata:
|
|
|
16
16
|
requestId: req-<stable-id>
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
Most subcommand
|
|
20
|
-
|
|
21
|
-
`init`, `quickstart`, `wipe`, or `version`.
|
|
19
|
+
Most subcommand IDs are dot-namespaced (`task.list`, `sync.pull`). Root-level
|
|
20
|
+
commands use single tokens (`help`, `init`, `quickstart`, `wipe`, `version`).
|
|
22
21
|
|
|
23
|
-
Additional metadata
|
|
22
|
+
Additional metadata appears when relevant:
|
|
24
23
|
|
|
25
24
|
- `metadata.compatibility` when `--compat` mode is active
|
|
26
25
|
- `meta.storageRootDiagnostics` when storage resolves from a non-canonical cwd
|
|
27
26
|
|
|
28
|
-
## Ready queue
|
|
27
|
+
## Ready queue
|
|
29
28
|
|
|
30
29
|
```bash
|
|
31
30
|
trekoon --toon task ready --limit 3
|
|
32
31
|
```
|
|
33
32
|
|
|
34
|
-
Payload fields:
|
|
35
|
-
|
|
36
33
|
```text
|
|
37
34
|
ok: true
|
|
38
35
|
command: task.ready
|
|
@@ -58,8 +55,6 @@ data:
|
|
|
58
55
|
trekoon --toon dep reverse <task-or-subtask-id>
|
|
59
56
|
```
|
|
60
57
|
|
|
61
|
-
Payload fields:
|
|
62
|
-
|
|
63
58
|
```text
|
|
64
59
|
ok: true
|
|
65
60
|
command: dep.reverse
|
|
@@ -69,22 +64,19 @@ data:
|
|
|
69
64
|
blockedNodes[]: { id, kind, distance, isDirect }
|
|
70
65
|
```
|
|
71
66
|
|
|
72
|
-
## Pagination
|
|
67
|
+
## Pagination
|
|
73
68
|
|
|
74
69
|
```bash
|
|
75
70
|
trekoon --toon task list --status todo --limit 2
|
|
76
71
|
trekoon --toon task list --status todo --limit 2 --cursor 2
|
|
77
72
|
```
|
|
78
73
|
|
|
79
|
-
|
|
74
|
+
Rules:
|
|
80
75
|
|
|
81
76
|
- `--cursor <n>` is offset-like pagination for `epic list`, `task list`, and
|
|
82
77
|
`subtask list`
|
|
83
|
-
-
|
|
84
|
-
-
|
|
85
|
-
`meta.pagination.nextCursor`
|
|
86
|
-
|
|
87
|
-
Payload fields:
|
|
78
|
+
- Don't combine `--all` with `--cursor`
|
|
79
|
+
- Page using `meta.pagination.hasMore` and `meta.pagination.nextCursor`
|
|
88
80
|
|
|
89
81
|
```text
|
|
90
82
|
ok: true
|
|
@@ -98,14 +90,14 @@ meta:
|
|
|
98
90
|
pagination: { hasMore, nextCursor }
|
|
99
91
|
```
|
|
100
92
|
|
|
101
|
-
## Descendant cascade update
|
|
93
|
+
## Descendant cascade update
|
|
102
94
|
|
|
103
95
|
```bash
|
|
104
96
|
trekoon --toon epic update <epic-id> --all --status done
|
|
105
97
|
trekoon --toon task update <task-id> --all --status todo
|
|
106
98
|
```
|
|
107
99
|
|
|
108
|
-
Success
|
|
100
|
+
Success:
|
|
109
101
|
|
|
110
102
|
```text
|
|
111
103
|
ok: true
|
|
@@ -129,7 +121,7 @@ data:
|
|
|
129
121
|
changedSubtasks
|
|
130
122
|
```
|
|
131
123
|
|
|
132
|
-
Failure
|
|
124
|
+
Failure (blocked descendants):
|
|
133
125
|
|
|
134
126
|
```text
|
|
135
127
|
ok: false
|
|
@@ -157,16 +149,13 @@ data:
|
|
|
157
149
|
|
|
158
150
|
Notes:
|
|
159
151
|
|
|
160
|
-
- `subtask update <subtask-id> --all --status done|todo` is accepted
|
|
161
|
-
returns the normal single-subtask
|
|
162
|
-
|
|
163
|
-
- Cascade mode is reserved for status-only close/reopen operations; combine
|
|
164
|
-
append/title/description changes in separate commands
|
|
152
|
+
- `subtask update <subtask-id> --all --status done|todo` is accepted but
|
|
153
|
+
returns the normal single-subtask payload (no descendants to traverse)
|
|
154
|
+
- Cascade is status-only; use separate commands for append/title/description
|
|
165
155
|
|
|
166
|
-
## Batch create and expand
|
|
156
|
+
## Batch create and expand
|
|
167
157
|
|
|
168
|
-
|
|
169
|
-
creation commands.
|
|
158
|
+
Stable batch payloads for one-shot graph creation and sibling batch commands.
|
|
170
159
|
|
|
171
160
|
### `epic create` and `epic expand`
|
|
172
161
|
|
|
@@ -175,8 +164,6 @@ trekoon --toon epic create --title "..." --description "..." --task "..."
|
|
|
175
164
|
trekoon --toon epic expand <epic-id> --task "..."
|
|
176
165
|
```
|
|
177
166
|
|
|
178
|
-
Payload fields:
|
|
179
|
-
|
|
180
167
|
```text
|
|
181
168
|
ok: true
|
|
182
169
|
command: epic.create | epic.expand
|
|
@@ -197,8 +184,6 @@ data:
|
|
|
197
184
|
trekoon --toon task create-many --epic <epic-id> --task "..."
|
|
198
185
|
```
|
|
199
186
|
|
|
200
|
-
Payload fields:
|
|
201
|
-
|
|
202
187
|
```text
|
|
203
188
|
ok: true
|
|
204
189
|
command: task.create-many
|
|
@@ -215,8 +200,6 @@ data:
|
|
|
215
200
|
trekoon --toon subtask create-many --task <task-id> --subtask "..."
|
|
216
201
|
```
|
|
217
202
|
|
|
218
|
-
Payload fields:
|
|
219
|
-
|
|
220
203
|
```text
|
|
221
204
|
ok: true
|
|
222
205
|
command: subtask.create-many
|
|
@@ -229,57 +212,54 @@ data:
|
|
|
229
212
|
|
|
230
213
|
## Sync compatibility mode
|
|
231
214
|
|
|
232
|
-
|
|
233
|
-
command IDs:
|
|
215
|
+
For integrations that still use legacy sync command IDs:
|
|
234
216
|
|
|
235
217
|
```bash
|
|
236
218
|
trekoon --json --compat legacy-sync-command-ids sync status
|
|
237
219
|
trekoon --toon --compat legacy-sync-command-ids sync pull --from main
|
|
238
220
|
```
|
|
239
221
|
|
|
240
|
-
|
|
222
|
+
- Default output uses canonical dotted IDs (`sync.status`)
|
|
223
|
+
- Compat mode rewrites to legacy forms (`sync_status`)
|
|
224
|
+
- Machine-only, valid only for `sync` commands
|
|
225
|
+
- Output includes `metadata.compatibility` with migration guidance and removal
|
|
226
|
+
timing
|
|
241
227
|
|
|
242
|
-
|
|
243
|
-
- compatibility mode rewrites sync command IDs to legacy forms such as
|
|
244
|
-
`sync_status`
|
|
245
|
-
- compatibility mode is machine-only and valid only for `sync` commands
|
|
246
|
-
- machine output includes `metadata.compatibility` with migration guidance and
|
|
247
|
-
removal timing
|
|
248
|
-
|
|
249
|
-
## Compact envelope mode
|
|
228
|
+
## Compact envelope
|
|
250
229
|
|
|
251
230
|
```bash
|
|
252
231
|
trekoon --toon --compact task list
|
|
253
232
|
```
|
|
254
233
|
|
|
255
|
-
|
|
256
|
-
|
|
234
|
+
`--compact` omits the `metadata` key from the envelope. `ok`, `command`, `data`,
|
|
235
|
+
`error`, and `meta` are unaffected.
|
|
257
236
|
|
|
258
|
-
## Status transition
|
|
237
|
+
## Status transition errors
|
|
259
238
|
|
|
260
|
-
Invalid
|
|
239
|
+
Invalid transitions return:
|
|
261
240
|
|
|
262
241
|
```text
|
|
263
242
|
ok: false
|
|
264
243
|
error:
|
|
265
244
|
code: status_transition_invalid
|
|
266
245
|
message: "cannot transition <kind> <id> from '<from>' to '<to>'"
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
246
|
+
data:
|
|
247
|
+
entity: epic|task|subtask
|
|
248
|
+
id: <entity-id>
|
|
249
|
+
fromStatus: <current-status>
|
|
250
|
+
toStatus: <attempted-status>
|
|
251
|
+
allowedTransitions[]: <valid targets from current status>
|
|
273
252
|
```
|
|
274
253
|
|
|
275
|
-
|
|
254
|
+
Transition details are in `data`, not `error.details`. `error` only has `code`
|
|
255
|
+
and `message`.
|
|
256
|
+
|
|
257
|
+
## Epic progress
|
|
276
258
|
|
|
277
259
|
```bash
|
|
278
260
|
trekoon --toon epic progress <epic-id>
|
|
279
261
|
```
|
|
280
262
|
|
|
281
|
-
Payload fields:
|
|
282
|
-
|
|
283
263
|
```text
|
|
284
264
|
ok: true
|
|
285
265
|
command: epic.progress
|
|
@@ -295,14 +275,12 @@ data:
|
|
|
295
275
|
nextCandidate: { id, title } | null
|
|
296
276
|
```
|
|
297
277
|
|
|
298
|
-
## Task done enhanced
|
|
278
|
+
## Task done (enhanced)
|
|
299
279
|
|
|
300
280
|
```bash
|
|
301
281
|
trekoon --toon task done <task-id>
|
|
302
282
|
```
|
|
303
283
|
|
|
304
|
-
Payload fields:
|
|
305
|
-
|
|
306
284
|
```text
|
|
307
285
|
ok: true
|
|
308
286
|
command: task.done
|
|
@@ -324,14 +302,12 @@ data:
|
|
|
324
302
|
blockedCount
|
|
325
303
|
```
|
|
326
304
|
|
|
327
|
-
## Suggest
|
|
305
|
+
## Suggest
|
|
328
306
|
|
|
329
307
|
```bash
|
|
330
308
|
trekoon --toon suggest [--epic <epic-id>]
|
|
331
309
|
```
|
|
332
310
|
|
|
333
|
-
Payload fields:
|
|
334
|
-
|
|
335
311
|
```text
|
|
336
312
|
ok: true
|
|
337
313
|
command: suggest
|
|
@@ -352,9 +328,9 @@ data:
|
|
|
352
328
|
pendingConflicts
|
|
353
329
|
```
|
|
354
330
|
|
|
355
|
-
## Owner field in
|
|
331
|
+
## Owner field in updates
|
|
356
332
|
|
|
357
|
-
Task and subtask update payloads
|
|
333
|
+
Task and subtask update payloads include `owner`:
|
|
358
334
|
|
|
359
335
|
```text
|
|
360
336
|
data:
|
|
@@ -366,6 +342,202 @@ data:
|
|
|
366
342
|
The board API accepts `owner` on `PATCH /api/tasks/{id}` and
|
|
367
343
|
`PATCH /api/subtasks/{id}`.
|
|
368
344
|
|
|
345
|
+
## Sync resolve dry-run
|
|
346
|
+
|
|
347
|
+
```bash
|
|
348
|
+
trekoon --toon sync resolve <conflict-id> --use ours|theirs --dry-run
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
```text
|
|
352
|
+
ok: true
|
|
353
|
+
command: sync.resolve
|
|
354
|
+
data:
|
|
355
|
+
conflictId: <conflict-id>
|
|
356
|
+
resolution: ours|theirs
|
|
357
|
+
entityKind: epic|task|subtask
|
|
358
|
+
entityId: <entity-id>
|
|
359
|
+
fieldName: <conflicted field>
|
|
360
|
+
oursValue: <current DB value>
|
|
361
|
+
theirsValue: <source branch value>
|
|
362
|
+
wouldWrite: <value that would be written>
|
|
363
|
+
dryRun: true
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
No mutation occurs. The conflict stays pending.
|
|
367
|
+
|
|
368
|
+
## Sync batch resolve
|
|
369
|
+
|
|
370
|
+
```bash
|
|
371
|
+
trekoon --toon sync resolve --all --use ours|theirs [--entity <id>] [--field <name>]
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
```text
|
|
375
|
+
ok: true
|
|
376
|
+
command: sync.resolve
|
|
377
|
+
data:
|
|
378
|
+
resolution: ours|theirs
|
|
379
|
+
resolvedCount: <number>
|
|
380
|
+
resolvedIds: [<conflict-id>, ...]
|
|
381
|
+
filters:
|
|
382
|
+
entity: <entity-id> | null
|
|
383
|
+
field: <field-name> | null
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
Human-mode note: `sync resolve --all --use theirs` asks for confirmation before
|
|
387
|
+
execution. Cancellation returns `error.code: cancelled` with the requested
|
|
388
|
+
`resolution`, `cancelled: true`, and the normalized `filters`.
|
|
389
|
+
|
|
390
|
+
When confirmation is required, execution is bound to the previewed conflict ID
|
|
391
|
+
set. If another process resolves one of those conflicts before the confirmed
|
|
392
|
+
write happens, the command fails with `error.code: conflict_set_changed`
|
|
393
|
+
instead of partially resolving a drifted batch.
|
|
394
|
+
|
|
395
|
+
## Sync batch resolve dry-run
|
|
396
|
+
|
|
397
|
+
```bash
|
|
398
|
+
trekoon --toon sync resolve --all --use ours|theirs [--entity <id>] [--field <name>] --dry-run
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
```text
|
|
402
|
+
ok: true
|
|
403
|
+
command: sync.resolve
|
|
404
|
+
data:
|
|
405
|
+
resolution: ours|theirs
|
|
406
|
+
matchedCount: <number>
|
|
407
|
+
matchedIds: [<conflict-id>, ...]
|
|
408
|
+
filters:
|
|
409
|
+
entity: <entity-id> | null
|
|
410
|
+
field: <field-name> | null
|
|
411
|
+
dryRun: true
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
No mutation occurs. Returns `no_matching_conflicts` error when no pending
|
|
415
|
+
conflicts match the filters.
|
|
416
|
+
|
|
417
|
+
## Sync resolve hardening errors
|
|
418
|
+
|
|
419
|
+
Recent `sync.resolve` hardening added explicit machine-visible failure modes for
|
|
420
|
+
race conditions and invalid persisted conflict targets.
|
|
421
|
+
|
|
422
|
+
### Single resolve — cancelled
|
|
423
|
+
|
|
424
|
+
Returned in human mode when the user rejects or times out a confirmation prompt.
|
|
425
|
+
Single-conflict prompts only appear for `--use theirs`.
|
|
426
|
+
|
|
427
|
+
```text
|
|
428
|
+
ok: false
|
|
429
|
+
command: sync.resolve
|
|
430
|
+
data:
|
|
431
|
+
conflictId: <conflict-id>
|
|
432
|
+
resolution: ours|theirs
|
|
433
|
+
cancelled: true
|
|
434
|
+
error:
|
|
435
|
+
code: cancelled
|
|
436
|
+
message: "Resolution cancelled by user."
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
### Batch resolve — cancelled
|
|
440
|
+
|
|
441
|
+
Returned in human mode when the user rejects or times out the batch prompt.
|
|
442
|
+
|
|
443
|
+
```text
|
|
444
|
+
ok: false
|
|
445
|
+
command: sync.resolve
|
|
446
|
+
data:
|
|
447
|
+
resolution: ours|theirs
|
|
448
|
+
cancelled: true
|
|
449
|
+
filters:
|
|
450
|
+
entity: <entity-id> | null
|
|
451
|
+
field: <field-name> | null
|
|
452
|
+
error:
|
|
453
|
+
code: cancelled
|
|
454
|
+
message: "Batch resolution cancelled by user."
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
### Single resolve — already_resolved
|
|
458
|
+
|
|
459
|
+
Returned when a conflict is still pending at preview time but another process
|
|
460
|
+
resolves it before the confirmed write happens.
|
|
461
|
+
|
|
462
|
+
```text
|
|
463
|
+
ok: false
|
|
464
|
+
command: sync.resolve
|
|
465
|
+
data:
|
|
466
|
+
conflictId: <conflict-id>
|
|
467
|
+
resolution: ours|theirs
|
|
468
|
+
reason: already_resolved
|
|
469
|
+
error:
|
|
470
|
+
code: already_resolved
|
|
471
|
+
message: "Conflict '<conflict-id>' already resolved."
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
### Resolve write hardening errors
|
|
475
|
+
|
|
476
|
+
These surface as domain failures when persisted conflict metadata no longer maps
|
|
477
|
+
to a valid writable target.
|
|
478
|
+
|
|
479
|
+
```text
|
|
480
|
+
ok: false
|
|
481
|
+
command: sync.resolve
|
|
482
|
+
data:
|
|
483
|
+
reason: unsupported_entity_kind | disallowed_field | row_not_found
|
|
484
|
+
...details
|
|
485
|
+
error:
|
|
486
|
+
code: unsupported_entity_kind | disallowed_field | row_not_found
|
|
487
|
+
message: <stable human-readable message>
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
Per-code details:
|
|
491
|
+
|
|
492
|
+
- `unsupported_entity_kind`
|
|
493
|
+
- `data.entityKind`
|
|
494
|
+
- `disallowed_field`
|
|
495
|
+
- `data.tableName`
|
|
496
|
+
- `data.fieldName`
|
|
497
|
+
- `row_not_found`
|
|
498
|
+
- `data.tableName`
|
|
499
|
+
- `data.entityKind`
|
|
500
|
+
- `data.entityId`
|
|
501
|
+
|
|
502
|
+
## Sync batch resolve — no_matching_conflicts error
|
|
503
|
+
|
|
504
|
+
Applies to both the execute and dry-run variants of `sync resolve --all`.
|
|
505
|
+
Returned when the given filters match zero pending conflicts.
|
|
506
|
+
|
|
507
|
+
```text
|
|
508
|
+
ok: false
|
|
509
|
+
command: sync.resolve
|
|
510
|
+
data:
|
|
511
|
+
filters:
|
|
512
|
+
entity: <entity-id> | null
|
|
513
|
+
field: <field-name> | null
|
|
514
|
+
reason: no_matching_conflicts
|
|
515
|
+
error:
|
|
516
|
+
code: no_matching_conflicts
|
|
517
|
+
message: "No pending conflicts match the given filters."
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
## Sync batch resolve — conflict_set_changed error
|
|
521
|
+
|
|
522
|
+
Returned in human mode when batch confirmation was based on one pending conflict
|
|
523
|
+
set but one or more of those conflicts were resolved before the confirmed write
|
|
524
|
+
was applied.
|
|
525
|
+
|
|
526
|
+
```text
|
|
527
|
+
ok: false
|
|
528
|
+
command: sync.resolve
|
|
529
|
+
data:
|
|
530
|
+
filters:
|
|
531
|
+
entity: <entity-id> | null
|
|
532
|
+
field: <field-name> | null
|
|
533
|
+
expectedConflictIds: [<conflict-id>, ...]
|
|
534
|
+
availableConflictIds: [<conflict-id>, ...]
|
|
535
|
+
reason: conflict_set_changed
|
|
536
|
+
error:
|
|
537
|
+
code: conflict_set_changed
|
|
538
|
+
message: "Pending conflicts changed before batch resolution could be applied."
|
|
539
|
+
```
|
|
540
|
+
|
|
369
541
|
## Related docs
|
|
370
542
|
|
|
371
543
|
- [Quickstart](quickstart.md)
|