trekoon 0.2.1 → 0.2.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/.agents/skills/trekoon/SKILL.md +95 -33
- package/README.md +74 -13
- package/package.json +1 -1
- package/src/commands/help.ts +47 -13
- package/src/commands/init.ts +104 -6
- package/src/commands/quickstart.ts +76 -30
- package/src/commands/session.ts +223 -0
- package/src/commands/skills.ts +100 -63
- package/src/commands/sync.ts +62 -21
- package/src/commands/task-readiness.ts +147 -0
- package/src/commands/task.ts +81 -143
- package/src/commands/wipe.ts +15 -5
- package/src/runtime/cli-shell.ts +83 -5
- package/src/storage/database.ts +86 -0
- package/src/storage/migrations.ts +48 -0
- package/src/storage/path.ts +70 -21
- package/src/storage/schema.ts +9 -2
- package/src/storage/worktree-recovery.ts +376 -0
- package/src/sync/branch-db.ts +87 -35
- package/src/sync/git-context.ts +7 -2
- package/src/sync/service.ts +89 -95
- package/src/sync/types.ts +2 -0
|
@@ -19,47 +19,58 @@ pick the right command with the fewest reads and mutations.
|
|
|
19
19
|
- Preview replace before `--apply`.
|
|
20
20
|
- Prefer `--ids` over `--all` for bulk updates.
|
|
21
21
|
- Never edit `.trekoon/trekoon.db` directly.
|
|
22
|
+
- Treat `.trekoon` as shared repo-scoped operational state in git worktrees.
|
|
23
|
+
- Keep `.trekoon` gitignored; do not commit the SQLite DB as a recovery fix.
|
|
22
24
|
- Never run `trekoon wipe --yes --toon` unless the user explicitly asks for it.
|
|
23
25
|
|
|
24
26
|
## Default agent loop
|
|
25
27
|
|
|
26
|
-
|
|
28
|
+
The primary loop is: **session → work → task done → repeat**.
|
|
27
29
|
|
|
28
|
-
1.
|
|
30
|
+
### 1. Orient with a single call
|
|
29
31
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
```bash
|
|
33
|
+
trekoon --toon session
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
`session` replaces the old five-call bootstrap sequence
|
|
37
|
+
(init + sync status + task next + dep list + task show) with a single DB open.
|
|
38
|
+
It returns diagnostics, sync status, the full next-task tree with subtasks, blocker
|
|
39
|
+
list, and readiness counts in one envelope.
|
|
33
40
|
|
|
34
|
-
|
|
35
|
-
|
|
41
|
+
Fail fast if the envelope reports `recoveryRequired`, a storage mismatch, or any
|
|
42
|
+
bootstrap error. In linked worktrees, `sharedStorageRoot` may differ from
|
|
43
|
+
`worktreeRoot`; that is expected because the repo shares one DB across checkouts.
|
|
36
44
|
|
|
37
|
-
2.
|
|
45
|
+
### 2. Claim work explicitly
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
trekoon --toon task update <task-id> --status in_progress
|
|
49
|
+
```
|
|
38
50
|
|
|
39
|
-
|
|
40
|
-
trekoon --toon task next
|
|
41
|
-
trekoon --toon task ready --limit 5
|
|
42
|
-
```
|
|
51
|
+
### 3. Finish or report a block
|
|
43
52
|
|
|
44
|
-
|
|
53
|
+
```bash
|
|
54
|
+
trekoon --toon task done <task-id>
|
|
55
|
+
trekoon --toon task update <task-id> --append "Blocked by <reason>" --status blocked
|
|
56
|
+
```
|
|
45
57
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
```
|
|
58
|
+
`task done` replaces the old three-call transition sequence
|
|
59
|
+
(mark done + get next + load deps + show task) with a single call that marks the
|
|
60
|
+
task done and returns the next ready candidate with its full tree and blockers.
|
|
50
61
|
|
|
51
|
-
|
|
62
|
+
Append a completion note before calling `task done` when useful:
|
|
52
63
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
64
|
+
```bash
|
|
65
|
+
trekoon --toon task update <task-id> --append "Completed implementation and checks"
|
|
66
|
+
trekoon --toon task done <task-id>
|
|
67
|
+
```
|
|
56
68
|
|
|
57
|
-
|
|
69
|
+
### 4. Repeat
|
|
58
70
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
```
|
|
71
|
+
Run `session` again at the start of each new session. After `task done`, the
|
|
72
|
+
returned next-task envelope is sufficient to continue; a fresh `session` call is
|
|
73
|
+
not required mid-loop unless you need updated diagnostics or sync status.
|
|
63
74
|
|
|
64
75
|
Recommended statuses for consistent workflows: `todo`, `in_progress`, `done`.
|
|
65
76
|
|
|
@@ -69,7 +80,8 @@ Use the narrowest command that answers the question.
|
|
|
69
80
|
|
|
70
81
|
| Need | Preferred command |
|
|
71
82
|
|---|---|
|
|
72
|
-
|
|
|
83
|
+
| Session startup (diagnostics + sync + next task) | `trekoon --toon session` |
|
|
84
|
+
| Next task only | `trekoon --toon task next` |
|
|
73
85
|
| A few ready options | `trekoon --toon task ready --limit 5` |
|
|
74
86
|
| Direct blockers for one task | `trekoon --toon dep list <task-id>` |
|
|
75
87
|
| What this item unblocks | `trekoon --toon dep reverse <task-or-subtask-id>` |
|
|
@@ -97,6 +109,28 @@ creates unless only one record is needed.
|
|
|
97
109
|
| Multiple dependency edges across existing IDs | `trekoon --toon dep add-many --dep ...` |
|
|
98
110
|
| One record only | `epic create`, `task create`, or `subtask create` |
|
|
99
111
|
|
|
112
|
+
### Compact spec escaping rules
|
|
113
|
+
|
|
114
|
+
Compact specs (pipe-delimited `--task`, `--subtask`, `--dep` values) use `\` as
|
|
115
|
+
the escape character. Only these sequences are valid:
|
|
116
|
+
|
|
117
|
+
| Sequence | Produces |
|
|
118
|
+
|---|---|
|
|
119
|
+
| `\|` | literal `|` (not a field separator) |
|
|
120
|
+
| `\\` | literal `\` |
|
|
121
|
+
| `\n` | newline |
|
|
122
|
+
| `\r` | carriage return |
|
|
123
|
+
| `\t` | tab |
|
|
124
|
+
|
|
125
|
+
Any other `\X` combination (e.g., `\!`, `\=`, `\$`) is rejected with
|
|
126
|
+
`Invalid escape sequence`. To avoid accidental escapes:
|
|
127
|
+
|
|
128
|
+
- Do not use `!=` or similar operators in description text; rephrase instead
|
|
129
|
+
(e.g., "null does not equal sourceBranch" instead of "null !== sourceBranch").
|
|
130
|
+
- If a literal backslash is needed, double it: `\\`.
|
|
131
|
+
- When using shell line continuations (`\` at end of line), ensure the next
|
|
132
|
+
line's first character is not one that forms an invalid escape with `\`.
|
|
133
|
+
|
|
100
134
|
### Critical temp-key rule
|
|
101
135
|
|
|
102
136
|
- Use plain temp keys when declaring records in compact specs, for example
|
|
@@ -229,20 +263,35 @@ Guardrails:
|
|
|
229
263
|
|
|
230
264
|
## Setup and fallback
|
|
231
265
|
|
|
232
|
-
If Trekoon is unavailable or
|
|
266
|
+
If Trekoon is unavailable or storage diagnostics require repair:
|
|
233
267
|
|
|
234
268
|
```bash
|
|
235
269
|
trekoon --toon init
|
|
270
|
+
trekoon --toon sync status
|
|
236
271
|
trekoon --toon quickstart
|
|
237
|
-
trekoon --help
|
|
272
|
+
trekoon --toon help sync
|
|
238
273
|
```
|
|
239
274
|
|
|
240
|
-
|
|
241
|
-
|
|
275
|
+
Rules:
|
|
276
|
+
|
|
277
|
+
- Re-bootstrap first, then re-read diagnostics.
|
|
278
|
+
- Stop if `recoveryRequired` stays true or diagnostics report storage mismatch.
|
|
279
|
+
- Do not continue with task selection after missing shared storage or broken
|
|
280
|
+
bootstrap.
|
|
281
|
+
- Do not commit `.trekoon/trekoon.db`; remove the tracked DB and keep
|
|
282
|
+
`.trekoon` ignored instead.
|
|
283
|
+
|
|
284
|
+
Use `quickstart` for the canonical execution loop. Use help when you need exact
|
|
285
|
+
syntax.
|
|
242
286
|
|
|
243
287
|
## Sync reminders
|
|
244
288
|
|
|
245
|
-
-
|
|
289
|
+
Same-branch sync is a no-op: `sync pull --from main` while on `main` produces
|
|
290
|
+
zero conflicts and simply advances the cursor. `sync status` returns `behind=0`
|
|
291
|
+
on the source branch. No action is needed.
|
|
292
|
+
|
|
293
|
+
Cross-branch sync matters before merging a feature branch back:
|
|
294
|
+
|
|
246
295
|
- Before merge, pull tracker events from the base branch:
|
|
247
296
|
|
|
248
297
|
```bash
|
|
@@ -257,5 +306,18 @@ need exact syntax.
|
|
|
257
306
|
trekoon --toon sync resolve <conflict-id> --use ours
|
|
258
307
|
```
|
|
259
308
|
|
|
309
|
+
## Worktree diagnostics and destructive scope
|
|
310
|
+
|
|
311
|
+
- Inspect machine-readable storage fields when debugging worktrees:
|
|
312
|
+
`storageMode`, `repoCommonDir`, `worktreeRoot`, `sharedStorageRoot`, and
|
|
313
|
+
`databaseFile`.
|
|
314
|
+
- `sharedStorageRoot` is the repo-scoped source of truth for `.trekoon` in git
|
|
315
|
+
worktrees.
|
|
316
|
+
- If `trekoon wipe --yes --toon` is explicitly requested, warn that it deletes
|
|
317
|
+
shared storage for the entire repository and every linked worktree.
|
|
318
|
+
- Wipe is destructive recovery only; it is never the right fix for a tracked DB
|
|
319
|
+
or gitignore mistake.
|
|
320
|
+
|
|
260
321
|
Trekoon stores local state in `.trekoon/trekoon.db`. In git repos and
|
|
261
|
-
worktrees, storage resolves from the repository root
|
|
322
|
+
worktrees, storage resolves from the shared repository root rather than each
|
|
323
|
+
worktree independently.
|
package/README.md
CHANGED
|
@@ -40,7 +40,7 @@ npm i -g trekoon
|
|
|
40
40
|
|
|
41
41
|
1. Make issue tracking fast enough for daily terminal use.
|
|
42
42
|
2. Make issue data deterministic and machine-readable for AI automation.
|
|
43
|
-
3. Keep
|
|
43
|
+
3. Keep one repo-scoped state store that every worktree can coordinate through safely.
|
|
44
44
|
4. Stay minimal in code size while preserving robustness and clear boundaries.
|
|
45
45
|
|
|
46
46
|
## Command surface
|
|
@@ -49,7 +49,8 @@ npm i -g trekoon
|
|
|
49
49
|
- `trekoon help [command]`
|
|
50
50
|
- `trekoon quickstart`
|
|
51
51
|
- `trekoon epic <create|expand|list|show|search|replace|update|delete>`
|
|
52
|
-
- `trekoon
|
|
52
|
+
- `trekoon session`
|
|
53
|
+
- `trekoon task <create|create-many|list|show|ready|next|done|search|replace|update|delete>`
|
|
53
54
|
- `trekoon subtask <create|create-many|list|search|replace|update|delete>`
|
|
54
55
|
- `trekoon dep <add|add-many|remove|list|reverse>`
|
|
55
56
|
- `trekoon events prune [--dry-run] [--archive] [--retention-days <n>]`
|
|
@@ -117,15 +118,23 @@ trekoon epic update --ids <epic-1>,<epic-2> --status done
|
|
|
117
118
|
|
|
118
119
|
## Quickstart
|
|
119
120
|
|
|
120
|
-
Trekoon is local-first
|
|
121
|
-
|
|
122
|
-
|
|
121
|
+
Trekoon is local-first, but in git repos and worktrees it is **repo-shared**:
|
|
122
|
+
every worktree for the same repository resolves to one shared `.trekoon`
|
|
123
|
+
directory and one shared `.trekoon/trekoon.db`.
|
|
124
|
+
|
|
125
|
+
- `worktreeRoot` identifies the current checkout.
|
|
126
|
+
- `sharedStorageRoot` identifies the repository root that owns `.trekoon`.
|
|
127
|
+
- `databaseFile` points at the shared SQLite database.
|
|
128
|
+
- `.trekoon` stays gitignored on purpose because the DB is operational state,
|
|
129
|
+
not source code.
|
|
130
|
+
- Committing `.trekoon/trekoon.db` is the wrong fix for drift because it bakes
|
|
131
|
+
machine-local state and stale snapshots into Git.
|
|
123
132
|
|
|
124
133
|
Outside git repos, Trekoon falls back to the invocation cwd.
|
|
125
134
|
|
|
126
135
|
When machine output is enabled (`--json`/`--toon`) and a command resolves
|
|
127
136
|
storage from a non-canonical cwd, Trekoon emits
|
|
128
|
-
`meta.storageRootDiagnostics`
|
|
137
|
+
`meta.storageRootDiagnostics` so automation can verify the storage contract.
|
|
129
138
|
|
|
130
139
|
### 1) Initialize
|
|
131
140
|
|
|
@@ -134,6 +143,15 @@ trekoon init
|
|
|
134
143
|
trekoon --version
|
|
135
144
|
```
|
|
136
145
|
|
|
146
|
+
Bootstrap expectations:
|
|
147
|
+
|
|
148
|
+
- Run `trekoon --toon init` once per repository to create or re-bootstrap the
|
|
149
|
+
shared storage root.
|
|
150
|
+
- Run `trekoon --toon sync status` before agent work to inspect diagnostics.
|
|
151
|
+
- If diagnostics report `recoveryRequired`, a tracked/ignored mismatch, or an
|
|
152
|
+
ambiguous recovery path, stop and repair setup before continuing.
|
|
153
|
+
- Do **not** continue with task selection after broken bootstrap warnings.
|
|
154
|
+
|
|
137
155
|
### 2) Create epic → task → subtask
|
|
138
156
|
|
|
139
157
|
```bash
|
|
@@ -366,23 +384,52 @@ When to choose which command:
|
|
|
366
384
|
|
|
367
385
|
### 4) AI execution loop for agents
|
|
368
386
|
|
|
369
|
-
|
|
387
|
+
The primary loop is: **session → work → task done → repeat**.
|
|
388
|
+
|
|
389
|
+
Orient with a single call that returns diagnostics, sync status, next ready
|
|
390
|
+
task with subtasks, blocker list, and readiness counts:
|
|
391
|
+
|
|
392
|
+
```bash
|
|
393
|
+
trekoon --toon session
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
Claim work, then finish or report a block:
|
|
370
397
|
|
|
371
398
|
```bash
|
|
372
|
-
trekoon --toon sync status
|
|
373
|
-
trekoon --toon task ready --limit 5
|
|
374
|
-
trekoon --toon task next
|
|
375
|
-
trekoon --toon dep reverse <task-or-subtask-id>
|
|
376
399
|
trekoon --toon task update <task-id> --status in_progress
|
|
400
|
+
trekoon --toon task done <task-id>
|
|
401
|
+
trekoon --toon task update <task-id> --append "Blocked by <reason>" --status blocked
|
|
377
402
|
```
|
|
378
403
|
|
|
379
|
-
|
|
404
|
+
`task done` marks the task done and returns the next ready task with
|
|
405
|
+
dependencies inline, replacing the old multi-step transition.
|
|
406
|
+
|
|
407
|
+
Fail-fast rules:
|
|
408
|
+
|
|
409
|
+
- Treat `meta.storageRootDiagnostics` as the source of truth for worktree
|
|
410
|
+
storage.
|
|
411
|
+
- In linked worktrees, `sharedStorageRoot` may differ from `worktreeRoot`; that
|
|
412
|
+
is expected.
|
|
413
|
+
- If `recoveryRequired` is `true`, stop and follow the reported bootstrap or
|
|
414
|
+
recovery action.
|
|
415
|
+
- Do not fall back to a separate per-worktree DB or continue after missing
|
|
416
|
+
shared storage.
|
|
417
|
+
|
|
418
|
+
<details>
|
|
419
|
+
<summary>Legacy manual bootstrap (use <code>session</code> instead)</summary>
|
|
380
420
|
|
|
381
421
|
```bash
|
|
422
|
+
trekoon --toon init
|
|
423
|
+
trekoon --toon sync status
|
|
424
|
+
trekoon --toon task ready --limit 5
|
|
425
|
+
trekoon --toon task next
|
|
426
|
+
trekoon --toon dep reverse <task-or-subtask-id>
|
|
427
|
+
trekoon --toon task update <task-id> --status in_progress
|
|
382
428
|
trekoon --toon task update <task-id> --append "Completed implementation and checks" --status done
|
|
383
|
-
trekoon --toon task update <task-id> --append "Blocked by <reason>" --status blocked
|
|
384
429
|
```
|
|
385
430
|
|
|
431
|
+
</details>
|
|
432
|
+
|
|
386
433
|
### 5) Use TOON output for agent workflows
|
|
387
434
|
|
|
388
435
|
```bash
|
|
@@ -501,6 +548,19 @@ react deterministically:
|
|
|
501
548
|
- `diagnostics.conflictEvents`
|
|
502
549
|
- `diagnostics.errorHints`
|
|
503
550
|
|
|
551
|
+
Worktree diagnostics and recovery:
|
|
552
|
+
|
|
553
|
+
- Inspect `storageMode`, `repoCommonDir`, `worktreeRoot`, `sharedStorageRoot`,
|
|
554
|
+
and `databaseFile` in machine output when debugging worktree behavior.
|
|
555
|
+
- If a worktree resolves shared storage outside its checkout, that is expected
|
|
556
|
+
for linked worktrees and should not be “fixed” by committing `.trekoon`.
|
|
557
|
+
- If Git contains a tracked `.trekoon/trekoon.db`, remove it from Git history or
|
|
558
|
+
the index as appropriate, keep `.trekoon` ignored, and re-run
|
|
559
|
+
`trekoon --toon init`.
|
|
560
|
+
- Use `trekoon wipe --yes` only for explicit destructive recovery; it deletes
|
|
561
|
+
the shared storage root for the entire repository, not just the current
|
|
562
|
+
worktree.
|
|
563
|
+
|
|
504
564
|
Compatibility mode for legacy sync command IDs:
|
|
505
565
|
|
|
506
566
|
```bash
|
|
@@ -590,6 +650,7 @@ Trekoon does not mutate global editor config directories.
|
|
|
590
650
|
- [ ] done tasks/subtasks are marked completed
|
|
591
651
|
- [ ] dependency graph has no stale blockers
|
|
592
652
|
- [ ] final AI check: `trekoon --toon epic show <epic-id>`
|
|
653
|
+
- [ ] no one tried to commit `.trekoon/trekoon.db` as a worktree fix
|
|
593
654
|
|
|
594
655
|
## Machine-contract recipes (--toon)
|
|
595
656
|
|
package/package.json
CHANGED
package/src/commands/help.ts
CHANGED
|
@@ -18,15 +18,16 @@ const ROOT_HELP = [
|
|
|
18
18
|
"",
|
|
19
19
|
"Commands:",
|
|
20
20
|
" help Show root or command help",
|
|
21
|
-
" init Initialize .trekoon storage and
|
|
22
|
-
" quickstart Show
|
|
23
|
-
" wipe Remove
|
|
21
|
+
" init Initialize repo-shared .trekoon storage and DB",
|
|
22
|
+
" quickstart Show shared-storage bootstrap + AI execution loop",
|
|
23
|
+
" wipe Remove repo-shared Trekoon state (requires --yes)",
|
|
24
24
|
" epic Epic lifecycle commands",
|
|
25
25
|
" task Task lifecycle commands",
|
|
26
26
|
" subtask Subtask lifecycle commands",
|
|
27
27
|
" dep Dependency graph commands",
|
|
28
28
|
" events Event retention and cleanup commands",
|
|
29
29
|
" migrate Migration status and rollback commands",
|
|
30
|
+
" session One-call agent orientation (diagnostics + sync + next task)",
|
|
30
31
|
" sync Cross-branch sync commands",
|
|
31
32
|
" skills Project-local skill install/update/link",
|
|
32
33
|
].join("\n");
|
|
@@ -35,7 +36,9 @@ const INIT_HELP = [
|
|
|
35
36
|
"Usage: trekoon init [--json|--toon]",
|
|
36
37
|
"",
|
|
37
38
|
"Purpose:",
|
|
38
|
-
" Initialize
|
|
39
|
+
" Initialize repo-scoped Trekoon storage (.trekoon) and database.",
|
|
40
|
+
" In git worktrees, every worktree shares the same repository DB.",
|
|
41
|
+
" Keep .trekoon gitignored; committing the SQLite DB is not a recovery path.",
|
|
39
42
|
"",
|
|
40
43
|
"Examples:",
|
|
41
44
|
" trekoon init",
|
|
@@ -46,14 +49,16 @@ const QUICKSTART_HELP = [
|
|
|
46
49
|
"Usage: trekoon quickstart [--json|--toon]",
|
|
47
50
|
"",
|
|
48
51
|
"Purpose:",
|
|
49
|
-
" Show the canonical
|
|
52
|
+
" Show shared-storage bootstrap, diagnostics, and the canonical AI loop.",
|
|
50
53
|
"",
|
|
51
54
|
"Flow:",
|
|
52
|
-
" 1) trekoon --toon
|
|
53
|
-
" 2) trekoon --toon
|
|
54
|
-
" 3)
|
|
55
|
-
" 4) trekoon --toon
|
|
56
|
-
" 5) trekoon --toon task
|
|
55
|
+
" 1) trekoon --toon init",
|
|
56
|
+
" 2) trekoon --toon sync status",
|
|
57
|
+
" 3) Fail fast on recoveryRequired or tracked/ignored mismatch diagnostics",
|
|
58
|
+
" 4) trekoon --toon task ready --limit 5",
|
|
59
|
+
" 5) trekoon --toon task next",
|
|
60
|
+
" 6) trekoon --toon dep reverse <task-or-subtask-id>",
|
|
61
|
+
" 7) trekoon --toon task update <task-id> --status in_progress",
|
|
57
62
|
"",
|
|
58
63
|
"Examples:",
|
|
59
64
|
" trekoon quickstart",
|
|
@@ -64,10 +69,15 @@ const WIPE_HELP = [
|
|
|
64
69
|
"Usage: trekoon wipe --yes [--json|--toon]",
|
|
65
70
|
"",
|
|
66
71
|
"Purpose:",
|
|
67
|
-
" Remove
|
|
72
|
+
" Remove the repository's shared Trekoon storage directory.",
|
|
73
|
+
" In git worktrees this erases the same .trekoon state for every linked worktree.",
|
|
68
74
|
"",
|
|
69
75
|
"Options:",
|
|
70
|
-
" --yes Required
|
|
76
|
+
" --yes Required confirmation for destructive repo-wide removal.",
|
|
77
|
+
"",
|
|
78
|
+
"Recovery guidance:",
|
|
79
|
+
" Use wipe only for explicit destructive recovery.",
|
|
80
|
+
" Do not use wipe to fix gitignore mistakes or to replace bootstrap diagnostics.",
|
|
71
81
|
"",
|
|
72
82
|
"Examples:",
|
|
73
83
|
" trekoon wipe --yes",
|
|
@@ -312,6 +322,28 @@ const SYNC_HELP = [
|
|
|
312
322
|
" trekoon sync resolve <conflict-id> --use ours",
|
|
313
323
|
].join("\n");
|
|
314
324
|
|
|
325
|
+
const SESSION_HELP = [
|
|
326
|
+
"Usage: trekoon session [--json|--toon]",
|
|
327
|
+
"",
|
|
328
|
+
"Purpose:",
|
|
329
|
+
" One-call agent orientation. Opens DB once and returns:",
|
|
330
|
+
" - diagnostics: storageMode, recoveryRequired, recoveryStatus",
|
|
331
|
+
" - sync: ahead/behind counts and pendingConflicts vs main",
|
|
332
|
+
" - next: full task tree with subtasks for the top ready candidate (null if none)",
|
|
333
|
+
" - nextDeps: blocker list with statuses for the next task (empty if none)",
|
|
334
|
+
" - readiness: readyCount and blockedCount across all open tasks",
|
|
335
|
+
"",
|
|
336
|
+
"Output modes:",
|
|
337
|
+
" human Multi-section summary (default in TTY)",
|
|
338
|
+
" toon Compact pipe-encoded envelope",
|
|
339
|
+
" json Full structured JSON envelope",
|
|
340
|
+
"",
|
|
341
|
+
"Examples:",
|
|
342
|
+
" trekoon session",
|
|
343
|
+
" trekoon --toon session",
|
|
344
|
+
" trekoon --json session",
|
|
345
|
+
].join("\n");
|
|
346
|
+
|
|
315
347
|
const SKILLS_HELP = [
|
|
316
348
|
"Usage:",
|
|
317
349
|
" trekoon skills install [--link --editor opencode|claude|pi] [--to <path>] [--allow-outside-repo]",
|
|
@@ -331,7 +363,8 @@ const SKILLS_HELP = [
|
|
|
331
363
|
"",
|
|
332
364
|
"Update behavior:",
|
|
333
365
|
" - Refreshes canonical SKILL file in the install path above.",
|
|
334
|
-
" -
|
|
366
|
+
" - Auto-creates or refreshes editor symlinks when editor config dir exists.",
|
|
367
|
+
" - Skips editors with no config dir or conflicting paths.",
|
|
335
368
|
"",
|
|
336
369
|
"Examples:",
|
|
337
370
|
" trekoon skills install",
|
|
@@ -344,6 +377,7 @@ const SKILLS_HELP = [
|
|
|
344
377
|
const COMMAND_HELP: Record<string, string> = {
|
|
345
378
|
init: INIT_HELP,
|
|
346
379
|
quickstart: QUICKSTART_HELP,
|
|
380
|
+
session: SESSION_HELP,
|
|
347
381
|
wipe: WIPE_HELP,
|
|
348
382
|
epic: EPIC_HELP,
|
|
349
383
|
task: TASK_HELP,
|
package/src/commands/init.ts
CHANGED
|
@@ -1,27 +1,125 @@
|
|
|
1
1
|
import { unexpectedFailureResult } from "./error-utils";
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { DomainError } from "../domain/types";
|
|
4
|
+
import { failResult, okResult } from "../io/output";
|
|
4
5
|
import { type CliContext, type CliResult } from "../runtime/command-types";
|
|
5
6
|
import { openTrekoonDatabase, type TrekoonDatabase } from "../storage/database";
|
|
6
7
|
|
|
8
|
+
function buildRecoverySummary(database: TrekoonDatabase): string[] {
|
|
9
|
+
const diagnostics = database.diagnostics;
|
|
10
|
+
const lines: string[] = [];
|
|
11
|
+
|
|
12
|
+
if (diagnostics.recoveryStatus === "no_legacy_state") {
|
|
13
|
+
lines.push("Recovery status: no legacy worktree-local state detected.");
|
|
14
|
+
return lines;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (diagnostics.recoveryStatus === "safe_auto_migrate") {
|
|
18
|
+
if (diagnostics.autoMigratedLegacyState) {
|
|
19
|
+
lines.push("Recovery status: safe auto-migrate completed.");
|
|
20
|
+
lines.push(`Imported from: ${diagnostics.importedFromLegacyDatabase}`);
|
|
21
|
+
lines.push(`Backups created: ${diagnostics.backupFiles.join(", ")}`);
|
|
22
|
+
} else {
|
|
23
|
+
lines.push("Recovery status: legacy worktree-local state detected.");
|
|
24
|
+
lines.push("Shared storage already exists; no import was required.");
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
lines.push(`Operator action: ${diagnostics.operatorAction}`);
|
|
28
|
+
return lines;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
lines.push(`Recovery status: ${diagnostics.recoveryStatus}`);
|
|
32
|
+
lines.push(`Operator action: ${diagnostics.operatorAction}`);
|
|
33
|
+
return lines;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function recoveryFailureResult(error: DomainError): CliResult | null {
|
|
37
|
+
if (error.code !== "ambiguous_legacy_state" && error.code !== "tracked_ignored_mismatch") {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const details = error.details ?? {};
|
|
42
|
+
const status = typeof details.status === "string" ? details.status : error.code;
|
|
43
|
+
const operatorAction = typeof details.operatorAction === "string" ? details.operatorAction : error.message;
|
|
44
|
+
const legacyDatabaseFiles = Array.isArray(details.legacyDatabaseFiles) ? details.legacyDatabaseFiles : [];
|
|
45
|
+
const trackedStorageFiles = Array.isArray(details.trackedStorageFiles) ? details.trackedStorageFiles : [];
|
|
46
|
+
const humanLines: string[] = [
|
|
47
|
+
"Trekoon init requires operator action.",
|
|
48
|
+
`Recovery status: ${status}`,
|
|
49
|
+
error.message,
|
|
50
|
+
`Operator action: ${operatorAction}`,
|
|
51
|
+
];
|
|
52
|
+
|
|
53
|
+
if (legacyDatabaseFiles.length > 0) {
|
|
54
|
+
humanLines.push(`Legacy databases: ${legacyDatabaseFiles.join(", ")}`);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (trackedStorageFiles.length > 0) {
|
|
58
|
+
humanLines.push(`Tracked storage files: ${trackedStorageFiles.join(", ")}`);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return failResult({
|
|
62
|
+
command: "init",
|
|
63
|
+
human: humanLines.join("\n"),
|
|
64
|
+
data: {
|
|
65
|
+
status,
|
|
66
|
+
legacyDatabaseFiles,
|
|
67
|
+
trackedStorageFiles,
|
|
68
|
+
operatorAction,
|
|
69
|
+
},
|
|
70
|
+
error: {
|
|
71
|
+
code: error.code,
|
|
72
|
+
message: error.message,
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
7
77
|
export async function runInit(context: CliContext): Promise<CliResult> {
|
|
8
78
|
let database: TrekoonDatabase | undefined;
|
|
9
79
|
|
|
10
80
|
try {
|
|
11
81
|
database = openTrekoonDatabase(context.cwd);
|
|
82
|
+
const diagnostics = database.diagnostics;
|
|
83
|
+
const humanLines: string[] = [
|
|
84
|
+
"Trekoon initialized.",
|
|
85
|
+
`Storage mode: ${diagnostics.storageMode}`,
|
|
86
|
+
`Worktree root: ${diagnostics.worktreeRoot}`,
|
|
87
|
+
`Shared storage root: ${diagnostics.sharedStorageRoot}`,
|
|
88
|
+
`Storage directory: ${database.paths.storageDir}`,
|
|
89
|
+
`Database file: ${database.paths.databaseFile}`,
|
|
90
|
+
...buildRecoverySummary(database),
|
|
91
|
+
];
|
|
92
|
+
|
|
12
93
|
return okResult({
|
|
13
94
|
command: "init",
|
|
14
|
-
human:
|
|
15
|
-
"Trekoon initialized.",
|
|
16
|
-
`Storage directory: ${database.paths.storageDir}`,
|
|
17
|
-
`Database file: ${database.paths.databaseFile}`,
|
|
18
|
-
].join("\n"),
|
|
95
|
+
human: humanLines.join("\n"),
|
|
19
96
|
data: {
|
|
97
|
+
invocationCwd: diagnostics.invocationCwd,
|
|
98
|
+
storageMode: diagnostics.storageMode,
|
|
99
|
+
repoCommonDir: diagnostics.repoCommonDir,
|
|
100
|
+
worktreeRoot: diagnostics.worktreeRoot,
|
|
101
|
+
sharedStorageRoot: diagnostics.sharedStorageRoot,
|
|
20
102
|
storageDir: database.paths.storageDir,
|
|
21
103
|
databaseFile: database.paths.databaseFile,
|
|
104
|
+
legacyStateDetected: diagnostics.legacyStateDetected,
|
|
105
|
+
recoveryRequired: diagnostics.recoveryRequired,
|
|
106
|
+
recoveryStatus: diagnostics.recoveryStatus,
|
|
107
|
+
legacyDatabaseFiles: diagnostics.legacyDatabaseFiles,
|
|
108
|
+
backupFiles: diagnostics.backupFiles,
|
|
109
|
+
trackedStorageFiles: diagnostics.trackedStorageFiles,
|
|
110
|
+
autoMigratedLegacyState: diagnostics.autoMigratedLegacyState,
|
|
111
|
+
importedFromLegacyDatabase: diagnostics.importedFromLegacyDatabase,
|
|
112
|
+
operatorAction: diagnostics.operatorAction,
|
|
22
113
|
},
|
|
23
114
|
});
|
|
24
115
|
} catch (error: unknown) {
|
|
116
|
+
if (error instanceof DomainError) {
|
|
117
|
+
const recoveryFailure = recoveryFailureResult(error);
|
|
118
|
+
if (recoveryFailure !== null) {
|
|
119
|
+
return recoveryFailure;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
25
123
|
return unexpectedFailureResult(error, {
|
|
26
124
|
command: "init",
|
|
27
125
|
human: "Unexpected init command failure",
|