trekoon 0.4.1 → 0.4.3
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 +97 -765
- package/.agents/skills/trekoon/reference/execution-with-team.md +91 -141
- package/.agents/skills/trekoon/reference/execution.md +188 -159
- package/.agents/skills/trekoon/reference/harness-primitives.md +77 -0
- package/.agents/skills/trekoon/reference/planning.md +213 -213
- package/.agents/skills/trekoon/reference/status-machine.md +21 -0
- package/.agents/skills/trekoon/reference/sync.md +82 -0
- package/README.md +29 -8
- package/docs/ai-agents.md +65 -6
- package/docs/commands.md +149 -5
- package/docs/machine-contracts.md +123 -0
- package/docs/quickstart.md +55 -3
- package/package.json +1 -1
- package/src/board/assets/app.js +47 -13
- package/src/board/assets/components/Component.js +20 -8
- package/src/board/assets/components/Workspace.js +9 -3
- package/src/board/assets/components/helpers.js +4 -0
- package/src/board/assets/runtime/delegation.js +8 -0
- package/src/board/assets/runtime/focus-trap.js +48 -0
- package/src/board/assets/state/actions.js +45 -4
- package/src/board/assets/state/api.js +304 -17
- package/src/board/assets/state/store.js +82 -11
- package/src/board/assets/state/url.js +10 -0
- package/src/board/assets/state/utils.js +2 -1
- package/src/board/event-bus.ts +81 -0
- package/src/board/routes.ts +430 -40
- package/src/board/server.ts +86 -10
- package/src/board/snapshot.ts +6 -0
- package/src/board/wal-watcher.ts +313 -0
- package/src/commands/board.ts +52 -17
- package/src/commands/epic.ts +7 -9
- package/src/commands/error-utils.ts +54 -1
- package/src/commands/help.ts +75 -10
- package/src/commands/migrate.ts +153 -24
- package/src/commands/quickstart.ts +7 -0
- package/src/commands/skills.ts +17 -5
- package/src/commands/subtask.ts +71 -10
- package/src/commands/suggest.ts +6 -13
- package/src/commands/task.ts +137 -88
- package/src/domain/batch-validation.ts +329 -0
- package/src/domain/cascade-planner.ts +412 -0
- package/src/domain/dependency-rules.ts +15 -0
- package/src/domain/mutation-service.ts +842 -187
- package/src/domain/search.ts +113 -0
- package/src/domain/tracker-domain.ts +167 -693
- package/src/domain/types.ts +56 -2
- package/src/export/render-markdown.ts +1 -2
- package/src/index.ts +37 -0
- package/src/runtime/cli-shell.ts +44 -0
- package/src/runtime/daemon.ts +700 -0
- package/src/storage/backup.ts +166 -0
- package/src/storage/database.ts +268 -4
- package/src/storage/migrations.ts +441 -22
- package/src/storage/path.ts +8 -0
- package/src/storage/schema.ts +5 -1
- package/src/sync/event-writes.ts +38 -11
- package/src/sync/git-context.ts +226 -8
- package/src/sync/service.ts +679 -156
package/README.md
CHANGED
|
@@ -90,8 +90,8 @@ What the agent does during execution:
|
|
|
90
90
|
calls `task done`
|
|
91
91
|
6. `task done` returns which downstream tasks just became unblocked, so the
|
|
92
92
|
orchestrator knows what to dispatch next
|
|
93
|
-
7. After all tasks complete:
|
|
94
|
-
the epic `done`
|
|
93
|
+
7. After all tasks complete: review agent or review skill for non-trivial
|
|
94
|
+
changes, tests, manual verification, then marks the epic `done`
|
|
95
95
|
|
|
96
96
|
The orchestrator uses `task done` responses to drive the whole loop. No polling,
|
|
97
97
|
no guessing. When a task finishes, Trekoon tells you exactly what's ready next.
|
|
@@ -110,13 +110,15 @@ agents don't know how to use Trekoon properly.
|
|
|
110
110
|
```bash
|
|
111
111
|
trekoon skills install # repo-local (.agents/skills/trekoon/)
|
|
112
112
|
trekoon skills install -g # global (~/.agents/skills/trekoon)
|
|
113
|
+
trekoon skills install --link --editor codex # editor link (.codex/skills/trekoon)
|
|
113
114
|
trekoon update # refresh all installed skills
|
|
114
115
|
```
|
|
115
116
|
|
|
116
|
-
The skill bundles
|
|
117
|
+
The skill bundles reference documents that agents load on demand:
|
|
117
118
|
|
|
118
119
|
| Agent needs to... | Skill reads | What it covers |
|
|
119
120
|
| --- | --- | --- |
|
|
121
|
+
| Coordinate across harnesses | `reference/harness-primitives.md` | Universal subagent, question, local task display, review, and evidence-recording guidance |
|
|
120
122
|
| Plan a feature | `reference/planning.md` | Decomposition, writing standard, dependency modeling, validation |
|
|
121
123
|
| Execute an epic | `reference/execution.md` | Graph building, lane grouping, sub-agent dispatch, verification (universal) |
|
|
122
124
|
| Execute with Agent Teams | `reference/execution-with-team.md` | TeamCreate/SendMessage, parallel Claude Code instances in tmux |
|
|
@@ -145,6 +147,16 @@ Execute only:
|
|
|
145
147
|
/trekoon <epic-id> execute
|
|
146
148
|
```
|
|
147
149
|
|
|
150
|
+
When you execute an epic, use subagents by default for any meaningful work that
|
|
151
|
+
can run independently. Keep small or tightly coupled tasks in the parent agent.
|
|
152
|
+
Use the main context for orchestration, dependency decisions, user
|
|
153
|
+
communication, and final synthesis while Trekoon remains the durable source of
|
|
154
|
+
truth.
|
|
155
|
+
|
|
156
|
+
If a harness has a higher-priority rule requiring explicit permission before
|
|
157
|
+
subagents, surface that immediately instead of silently doing broad work
|
|
158
|
+
yourself.
|
|
159
|
+
|
|
148
160
|
Plan and execute end to end:
|
|
149
161
|
|
|
150
162
|
```
|
|
@@ -154,9 +166,11 @@ dependency order until the epic is complete
|
|
|
154
166
|
|
|
155
167
|
## Agent Teams
|
|
156
168
|
|
|
157
|
-
For larger epics,
|
|
158
|
-
|
|
159
|
-
|
|
169
|
+
For larger epics, use the current harness's native subagent mechanism for
|
|
170
|
+
meaningful work that can run independently. Claude Code Agent Teams are one
|
|
171
|
+
runtime-specific option: instead of sequential sub-agents, you get real parallel
|
|
172
|
+
Claude Code instances coordinated through `TeamCreate` and `SendMessage`, each
|
|
173
|
+
running in its own tmux pane.
|
|
160
174
|
|
|
161
175
|
Requires Claude Code env variable `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=true`.
|
|
162
176
|
|
|
@@ -191,7 +205,9 @@ trekoon board update # refresh assets only
|
|
|
191
205
|
```
|
|
192
206
|
|
|
193
207
|
Binds to `127.0.0.1` only with a per-session token. Gives you an epics
|
|
194
|
-
overview, kanban workspace per epic, task detail modals, and search.
|
|
208
|
+
overview, kanban workspace per epic, task detail modals, and search. The board
|
|
209
|
+
client subscribes to `/api/snapshot/stream` (SSE), so mutations from another
|
|
210
|
+
shell, worktree, or browser tab show up live without a manual refresh.
|
|
195
211
|
|
|
196
212
|
## Commands
|
|
197
213
|
|
|
@@ -199,15 +215,20 @@ overview, kanban workspace per epic, task detail modals, and search.
|
|
|
199
215
|
| --- | --- |
|
|
200
216
|
| Set up a repo | `trekoon init` |
|
|
201
217
|
| Open the local board | `trekoon board open` |
|
|
202
|
-
| Plan work | `trekoon epic create ...`, `trekoon epic expand ...` |
|
|
218
|
+
| Plan work | `trekoon --toon epic create ...`, `trekoon --toon epic expand ...` |
|
|
203
219
|
| Create tasks in bulk | `trekoon task create-many ...` |
|
|
204
220
|
| Add dependencies | `trekoon dep add-many ...` |
|
|
205
221
|
| Start an agent session | `trekoon session --epic <id>` |
|
|
206
222
|
| Get next-action suggestions | `trekoon suggest --epic <id>` |
|
|
207
223
|
| Check epic progress | `trekoon epic progress <id>` |
|
|
208
224
|
| Export epic to Markdown | `trekoon epic export <id>` |
|
|
225
|
+
| Claim a task atomically | `trekoon task claim <id> --owner <owner>` |
|
|
226
|
+
| Claim a subtask atomically | `trekoon subtask claim <id> --owner <owner>` |
|
|
209
227
|
| Mark a task done | `trekoon task done <id>` |
|
|
210
228
|
| Sync across worktrees | `trekoon sync pull --from main` |
|
|
229
|
+
| Back up the DB before migrations | `trekoon migrate backup` |
|
|
230
|
+
| Reveal full board token | `trekoon board open --reveal-token` |
|
|
231
|
+
| Run experimental daemon | `trekoon serve` (experimental) |
|
|
211
232
|
| Get help | `trekoon [command] -h` |
|
|
212
233
|
|
|
213
234
|
Every command supports `--toon`, `--json`, `--compact` for structured output.
|
package/docs/ai-agents.md
CHANGED
|
@@ -14,22 +14,39 @@ agent to:
|
|
|
14
14
|
- append progress and blocker notes instead of rewriting descriptions
|
|
15
15
|
- preview scoped replace before `--apply`
|
|
16
16
|
- treat `.trekoon` as shared repo-scoped state
|
|
17
|
+
- use harness-local todo/task tools as a live progress display while keeping
|
|
18
|
+
Trekoon as the durable source of truth
|
|
19
|
+
- use subagents by default for meaningful work that can run independently when
|
|
20
|
+
the harness exposes them
|
|
21
|
+
- keep small or tightly coupled tasks in the parent agent so the main context
|
|
22
|
+
stays available for orchestration and decisions
|
|
17
23
|
|
|
18
24
|
The skill ships with reference guides so the agent can handle the full
|
|
19
25
|
plan-to-completion workflow from one install:
|
|
20
26
|
|
|
21
27
|
```
|
|
22
28
|
.agents/skills/trekoon/
|
|
23
|
-
SKILL.md <- command
|
|
29
|
+
SKILL.md <- command router and operating contract
|
|
24
30
|
reference/
|
|
31
|
+
harness-primitives.md <- universal agent/task/question/review primitives
|
|
25
32
|
planning.md <- decomposition, writing standard, validation
|
|
26
33
|
execution.md <- graph building, lane dispatch, verification
|
|
27
34
|
execution-with-team.md <- Agent Teams pattern (Claude Code only)
|
|
28
35
|
```
|
|
29
36
|
|
|
30
|
-
The
|
|
31
|
-
|
|
32
|
-
|
|
37
|
+
The command shape determines what the agent loads:
|
|
38
|
+
|
|
39
|
+
| User command | Required references |
|
|
40
|
+
| --- | --- |
|
|
41
|
+
| `/trekoon plan <goal>` | `harness-primitives.md`, then `planning.md` |
|
|
42
|
+
| `/trekoon <id>` | `SKILL.md` only, unless deeper analysis is needed |
|
|
43
|
+
| `/trekoon <id> analyze` | `SKILL.md` plus targeted Trekoon reads |
|
|
44
|
+
| `/trekoon <id> execute` | `harness-primitives.md`, then `execution.md` |
|
|
45
|
+
| `/trekoon <id> team execute` | `harness-primitives.md`, then `execution-with-team.md` |
|
|
46
|
+
|
|
47
|
+
`harness-primitives.md` is loaded before planning or execution because those
|
|
48
|
+
modes may need structured questions, local progress displays, subagent
|
|
49
|
+
delegation, review agents, and runtime-specific orchestration.
|
|
33
50
|
|
|
34
51
|
## Install the skill
|
|
35
52
|
|
|
@@ -42,6 +59,7 @@ Create a project-local editor link when your agent environment supports it:
|
|
|
42
59
|
```bash
|
|
43
60
|
trekoon skills install --link --editor opencode
|
|
44
61
|
trekoon skills install --link --editor claude
|
|
62
|
+
trekoon skills install --link --editor codex
|
|
45
63
|
trekoon skills install --link --editor pi
|
|
46
64
|
trekoon skills install --link --editor opencode --to ./.custom-editor/skills
|
|
47
65
|
trekoon skills update
|
|
@@ -52,6 +70,7 @@ Path behavior:
|
|
|
52
70
|
- Canonical install: `.agents/skills/trekoon/SKILL.md`
|
|
53
71
|
- OpenCode link: `.opencode/skills/trekoon`
|
|
54
72
|
- Claude link: `.claude/skills/trekoon`
|
|
73
|
+
- Codex link: `.codex/skills/trekoon`
|
|
55
74
|
- Pi link: `.pi/skills/trekoon`
|
|
56
75
|
- `--to <path>` changes only the editor link root
|
|
57
76
|
- `--allow-outside-repo` is for intentional external links
|
|
@@ -89,10 +108,25 @@ Typical flow:
|
|
|
89
108
|
4. Execute the plan (reads `reference/execution.md` internally)
|
|
90
109
|
5. Update progress, blockers, and completion state as you go
|
|
91
110
|
|
|
111
|
+
> **Experimental — not for routine agent use:** `trekoon serve` and the
|
|
112
|
+
> `--daemon` flag are experimental. Use the default one-shot CLI path for
|
|
113
|
+
> any production or automated agent workflow until daemon mode stabilizes.
|
|
114
|
+
|
|
92
115
|
## Default execution loop
|
|
93
116
|
|
|
94
117
|
The core loop: **session, work, task done, repeat**.
|
|
95
118
|
|
|
119
|
+
When you execute an epic, use subagents by default for any meaningful work that
|
|
120
|
+
can run independently. Keep small or tightly coupled tasks in the parent agent.
|
|
121
|
+
Build the Trekoon execution graph, group ready tasks into lanes, keep a local
|
|
122
|
+
todo/task display for the user, and synthesize the results. Use the parent
|
|
123
|
+
context for dependency decisions and finishing the epic.
|
|
124
|
+
|
|
125
|
+
Some harnesses have higher-priority rules that require explicit user permission
|
|
126
|
+
before spawning subagents. When that happens, say so immediately after
|
|
127
|
+
discovering independent lanes and ask for permission before broad execution. Do
|
|
128
|
+
not silently default to single-agent execution.
|
|
129
|
+
|
|
96
130
|
Start with a single orientation call, optionally scoped to an epic:
|
|
97
131
|
|
|
98
132
|
```bash
|
|
@@ -113,14 +147,24 @@ If the session shows you're behind, pull tracker events before claiming work:
|
|
|
113
147
|
trekoon --toon sync pull --from main
|
|
114
148
|
```
|
|
115
149
|
|
|
116
|
-
Claim work
|
|
150
|
+
Claim work atomically using SQL compare-and-swap (recommended for parallel
|
|
151
|
+
agents), then finish or report a block:
|
|
117
152
|
|
|
118
153
|
```bash
|
|
119
|
-
trekoon --toon task
|
|
154
|
+
trekoon --toon task claim <task-id> --owner "agent-1"
|
|
120
155
|
trekoon --toon task done <task-id>
|
|
121
156
|
trekoon --toon task update <task-id> --append "Blocked by <reason>" --status blocked
|
|
122
157
|
```
|
|
123
158
|
|
|
159
|
+
`task claim` is the safe primitive for parallel agents. Two concurrent calls on
|
|
160
|
+
the same task return exactly one `claimed: true`. Check `data.claimed` before
|
|
161
|
+
proceeding — if false, another agent won the race.
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
# Fallback: non-atomic claim (single-agent or sequential workflows only)
|
|
165
|
+
trekoon --toon task update <task-id> --status in_progress --owner "agent-1"
|
|
166
|
+
```
|
|
167
|
+
|
|
124
168
|
Use `task done` when the task is actually finished. It marks the task complete,
|
|
125
169
|
auto-transitions through `in_progress` if needed, reports newly unblocked
|
|
126
170
|
downstream tasks, warns about incomplete subtasks, and returns the next ready
|
|
@@ -179,6 +223,20 @@ notes, mark it done, and repeat until there are no ready tasks or you hit a
|
|
|
179
223
|
blocker.
|
|
180
224
|
```
|
|
181
225
|
|
|
226
|
+
### Execute with subagents where useful
|
|
227
|
+
|
|
228
|
+
```text
|
|
229
|
+
/trekoon <epic-id> execute -- use subagents by default for meaningful work that
|
|
230
|
+
can run independently, keep Trekoon as the source of truth, and use local task
|
|
231
|
+
tools to show live progress.
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Short form for harnesses that require explicit delegation wording:
|
|
235
|
+
|
|
236
|
+
```text
|
|
237
|
+
/trekoon <epic-id> execute with subagents
|
|
238
|
+
```
|
|
239
|
+
|
|
182
240
|
### Plan and execute end to end
|
|
183
241
|
|
|
184
242
|
```text
|
|
@@ -201,6 +259,7 @@ Use the narrowest command that answers the question:
|
|
|
201
259
|
| One task with subtasks | `trekoon --toon task show <task-id> --all` |
|
|
202
260
|
| One epic tree | `trekoon --toon epic show <epic-id> --all` |
|
|
203
261
|
| Export epic to Markdown | `trekoon --toon epic export <epic-id>` |
|
|
262
|
+
| Snapshot the DB before manual recovery | `trekoon --toon migrate backup [--retain <n>]` |
|
|
204
263
|
| Repeated text in one scope | `trekoon --toon epic|task|subtask search ...` |
|
|
205
264
|
|
|
206
265
|
For repeated text changes, use the safe replace loop:
|
package/docs/commands.md
CHANGED
|
@@ -12,20 +12,21 @@ the quickest way to get started, read [Quickstart](quickstart.md) first.
|
|
|
12
12
|
- `trekoon epic <create|expand|list|show|search|replace|update|delete|progress>`
|
|
13
13
|
- `trekoon session [--epic <epic-id>]`
|
|
14
14
|
- `trekoon suggest [--epic <epic-id>]`
|
|
15
|
-
- `trekoon task <create|create-many|list|show|ready|next|done|search|replace|update|delete>`
|
|
16
|
-
- `trekoon subtask <create|create-many|list|search|replace|update|delete>`
|
|
15
|
+
- `trekoon task <create|create-many|list|show|ready|next|done|search|replace|update|delete|claim>`
|
|
16
|
+
- `trekoon subtask <create|create-many|list|search|replace|update|delete|claim>`
|
|
17
17
|
- `trekoon dep <add|add-many|remove|list|reverse>`
|
|
18
18
|
- `trekoon events prune [--dry-run] [--archive] [--retention-days <n>]`
|
|
19
|
-
- `trekoon migrate <status|rollback> [--to-version <n>]`
|
|
19
|
+
- `trekoon migrate <status|rollback|backup> [--to-version <n>] [--retain <n>]`
|
|
20
20
|
- `trekoon sync status [--from <branch>]`
|
|
21
21
|
- `trekoon sync pull --from <branch>`
|
|
22
22
|
- `trekoon sync resolve <conflict-id> --use ours|theirs [--dry-run]`
|
|
23
23
|
- `trekoon sync resolve --all --use ours|theirs [--entity <id>] [--field <name>] [--dry-run]`
|
|
24
24
|
- `trekoon sync conflicts <list|show> [--mode pending|all]`
|
|
25
|
-
- `trekoon skills install [--link --editor opencode|claude|pi] [--to <path>] [--allow-outside-repo]`
|
|
26
|
-
- `trekoon skills install -g|--global [--editor opencode|claude|pi]`
|
|
25
|
+
- `trekoon skills install [--link --editor opencode|claude|codex|pi] [--to <path>] [--allow-outside-repo]`
|
|
26
|
+
- `trekoon skills install -g|--global [--editor opencode|claude|codex|pi]`
|
|
27
27
|
- `trekoon skills update`
|
|
28
28
|
- `trekoon wipe --yes`
|
|
29
|
+
- `trekoon serve` (experimental)
|
|
29
30
|
|
|
30
31
|
## Global options
|
|
31
32
|
|
|
@@ -33,6 +34,7 @@ the quickest way to get started, read [Quickstart](quickstart.md) first.
|
|
|
33
34
|
- `--toon` — TOON-encoded output (preferred for agent loops)
|
|
34
35
|
- `--compact` — strips contract metadata from TOON/JSON envelopes
|
|
35
36
|
- `--compat <mode>` — explicit machine compatibility behavior
|
|
37
|
+
- `--daemon` — (experimental) route the call through a running `trekoon serve` daemon over a Unix socket; transparently falls back to the in-process CLI when no daemon is reachable. Equivalent to `TREKOON_DAEMON=1`.
|
|
36
38
|
- `--help` — root and command help
|
|
37
39
|
- `--version` — CLI version
|
|
38
40
|
|
|
@@ -73,6 +75,7 @@ Board API endpoints (all require token authentication):
|
|
|
73
75
|
| Method | Endpoint | Purpose |
|
|
74
76
|
| --- | --- | --- |
|
|
75
77
|
| `GET` | `/api/snapshot` | Full board state (epics, tasks, subtasks, deps, counts) |
|
|
78
|
+
| `GET` | `/api/snapshot/stream` | Server-sent events stream of `snapshot` and `snapshotDelta` events for live updates |
|
|
76
79
|
| `PATCH` | `/api/epics/{id}` | Update epic title, description, or status |
|
|
77
80
|
| `PATCH` | `/api/tasks/{id}` | Update task title, description, status, or owner |
|
|
78
81
|
| `PATCH` | `/api/subtasks/{id}` | Update subtask title, description, status, or owner |
|
|
@@ -81,6 +84,19 @@ Board API endpoints (all require token authentication):
|
|
|
81
84
|
| `POST` | `/api/dependencies` | Add dependency edge (sourceId, dependsOnId) |
|
|
82
85
|
| `DELETE` | `/api/dependencies?sourceId=...&dependsOnId=...` | Remove dependency |
|
|
83
86
|
|
|
87
|
+
**Note:** the SSE auth token rides as a `?token=` query parameter on
|
|
88
|
+
`/api/snapshot/stream` (EventSource cannot set custom headers), so it may
|
|
89
|
+
appear in reverse-proxy access logs; treat access logs as sensitive if the
|
|
90
|
+
board is exposed beyond localhost.
|
|
91
|
+
|
|
92
|
+
Board mutations from any source — board UI, CLI in another shell, or another
|
|
93
|
+
worktree — propagate to every connected client through the SSE stream. The CLI
|
|
94
|
+
side is driven by a WAL-watcher that diffs the snapshot when
|
|
95
|
+
`.trekoon/trekoon.db-wal` changes; in-process mutations publish deltas
|
|
96
|
+
directly. PATCH endpoints accept `If-Match: <updatedAt-ms>` for optimistic
|
|
97
|
+
concurrency: a stale value returns `409` with `currentUpdatedAt`. Missing
|
|
98
|
+
`If-Match` is allowed for back-compat.
|
|
99
|
+
|
|
84
100
|
Board commands don't accept command-specific options yet. For tests and local
|
|
85
101
|
development, `TREKOON_BOARD_ASSET_ROOT` overrides the bundled asset source.
|
|
86
102
|
|
|
@@ -183,6 +199,41 @@ trekoon subtask update <subtask-id> --owner "agent-2"
|
|
|
183
199
|
|
|
184
200
|
Also accepted on `PATCH /api/tasks/{id}` and `PATCH /api/subtasks/{id}`.
|
|
185
201
|
|
|
202
|
+
## Task claim
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
trekoon task claim <task-id> --owner <owner>
|
|
206
|
+
trekoon subtask claim <subtask-id> --owner <owner>
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
Atomically claim a task (or subtask) using a SQL compare-and-swap. Sets
|
|
210
|
+
`status=in_progress` and `owner=<owner>` only when:
|
|
211
|
+
|
|
212
|
+
- The task is in `todo` or `blocked` status, **and**
|
|
213
|
+
- The `owner` column is `NULL` or already equal to `<owner>` (re-entrant claim)
|
|
214
|
+
|
|
215
|
+
Two concurrent `task claim` calls racing on the same task return exactly one
|
|
216
|
+
`claimed: true`. The loser gets `claimed: false` with `currentOwner` and
|
|
217
|
+
`currentStatus` reflecting the winner's write.
|
|
218
|
+
|
|
219
|
+
`--owner` is required.
|
|
220
|
+
|
|
221
|
+
Response envelope:
|
|
222
|
+
|
|
223
|
+
```text
|
|
224
|
+
ok: true
|
|
225
|
+
command: task.claim | subtask.claim
|
|
226
|
+
data:
|
|
227
|
+
claimed: true | false
|
|
228
|
+
currentOwner: <owner> | null
|
|
229
|
+
currentStatus: in_progress | todo | blocked | done
|
|
230
|
+
task | subtask: { ...full record... } # present only when claimed=true
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
When `claimed` is false, `task`/`subtask` is absent. `currentOwner` tells you
|
|
234
|
+
who holds the lock. `currentStatus` tells you why the claim failed (already
|
|
235
|
+
`done`, or `in_progress` by another owner).
|
|
236
|
+
|
|
186
237
|
## Task done
|
|
187
238
|
|
|
188
239
|
`trekoon task done <task-id>` marks a task complete and returns the next ready
|
|
@@ -289,6 +340,99 @@ trekoon --toon sync conflicts show <conflict-id>
|
|
|
289
340
|
`list` defaults to `--mode pending`. Use `--mode all` to include resolved
|
|
290
341
|
conflicts.
|
|
291
342
|
|
|
343
|
+
## Migrate commands
|
|
344
|
+
|
|
345
|
+
### `migrate status`
|
|
346
|
+
|
|
347
|
+
```bash
|
|
348
|
+
trekoon --toon migrate status
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
Reports `currentVersion`, `latestVersion`, and pending migration count.
|
|
352
|
+
|
|
353
|
+
### `migrate rollback`
|
|
354
|
+
|
|
355
|
+
```bash
|
|
356
|
+
trekoon --toon migrate rollback [--to-version <n>]
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
Rolls back schema migrations one version (default) or down to `--to-version`.
|
|
360
|
+
Migrations 0004, 0005, and 0006 are irreversible (ALTER TABLE plus dependency
|
|
361
|
+
data cleanup). Rolling back below those versions errors with code
|
|
362
|
+
`migration_down_unsupported`. Take a backup first; restore by copying the
|
|
363
|
+
backup over `.trekoon/trekoon.db`.
|
|
364
|
+
|
|
365
|
+
### `migrate backup`
|
|
366
|
+
|
|
367
|
+
```bash
|
|
368
|
+
trekoon --toon migrate backup
|
|
369
|
+
trekoon --toon migrate backup --retain 5
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
Snapshots `.trekoon/trekoon.db` to a timestamped sibling file
|
|
373
|
+
(`trekoon.db.backup-<ISO8601>`) using SQLite `VACUUM INTO`. The source database
|
|
374
|
+
is opened read-only, so a backup never mutates live state. Returns
|
|
375
|
+
`backupPath`, `bytes`, `migrationVersion`, and `latestVersion` for machine
|
|
376
|
+
consumers. Backups stay inside `.trekoon/` and are gitignored along with the
|
|
377
|
+
rest of the directory.
|
|
378
|
+
|
|
379
|
+
`--retain <n>` keeps the last `n` timestamped backups; older siblings are
|
|
380
|
+
pruned in the same call. Default is `10`. Backups created within the same
|
|
381
|
+
millisecond produce a deterministic collision error that names the existing
|
|
382
|
+
file so operators can identify it.
|
|
383
|
+
|
|
384
|
+
To restore from a backup: stop any process holding the DB, then copy the
|
|
385
|
+
backup file over `.trekoon/trekoon.db`.
|
|
386
|
+
|
|
387
|
+
## Daemon (experimental)
|
|
388
|
+
|
|
389
|
+
`trekoon serve` runs Trekoon as a long-lived process listening
|
|
390
|
+
on a Unix-domain socket inside `<storage-root>/.trekoon/daemon.sock`. The
|
|
391
|
+
daemon holds the SQLite connection in memory, so subsequent invocations skip
|
|
392
|
+
Bun startup, module load, migration probes, and database open.
|
|
393
|
+
|
|
394
|
+
Status: **experimental**. Not on by default. The default one-shot CLI behavior
|
|
395
|
+
is unchanged whether or not the daemon is running.
|
|
396
|
+
|
|
397
|
+
Activate the client with one of:
|
|
398
|
+
|
|
399
|
+
```bash
|
|
400
|
+
TREKOON_DAEMON=1 trekoon session
|
|
401
|
+
trekoon --daemon session
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
If no daemon is reachable, the client transparently falls back to the in-process
|
|
405
|
+
one-shot path. Calls run against the daemon return envelopes equivalent to the
|
|
406
|
+
in-process call modulo:
|
|
407
|
+
|
|
408
|
+
- The per-request `requestId` and `persistedAt` fields.
|
|
409
|
+
- Environment variables. The client's `process.env` is **not** forwarded over
|
|
410
|
+
the socket; the daemon process uses the environment captured at `trekoon
|
|
411
|
+
serve` startup. If a command's behavior depends on an env var (e.g. an
|
|
412
|
+
override flag), set it before launching the daemon — not on the client side.
|
|
413
|
+
|
|
414
|
+
The daemon request contract is `{argv, cwd}` only — there is no per-call env
|
|
415
|
+
channel. This narrows the secret-leak surface area and keeps the equivalence
|
|
416
|
+
claim crisp.
|
|
417
|
+
|
|
418
|
+
Security:
|
|
419
|
+
|
|
420
|
+
- Socket file mode `0o600`; parent `.trekoon/` directory forced to `0o700`.
|
|
421
|
+
- The umask is tightened to `0o077` around `server.listen()` so the socket
|
|
422
|
+
inode is created with restrictive perms (no TOCTOU window before chmod).
|
|
423
|
+
- Daemon error envelopes return a sanitized message only — no stack trace,
|
|
424
|
+
which would otherwise leak filesystem paths or secret-bearing error text.
|
|
425
|
+
Stacks are still routed to the daemon's local `console.error` for operator
|
|
426
|
+
debugging.
|
|
427
|
+
- Client env is not transmitted over the socket (see equivalence note above).
|
|
428
|
+
- Stale sockets from prior crashes are unlinked at startup.
|
|
429
|
+
- On `Ctrl-C` / `SIGTERM` the socket is unlinked and the cached database
|
|
430
|
+
connection is closed.
|
|
431
|
+
|
|
432
|
+
Performance (see `bench/daemon-session.ts`): daemon median < 10 ms,
|
|
433
|
+
cold one-shot median > 50 ms — roughly a 5–10× latency reduction for
|
|
434
|
+
repeated calls by reusing the held-open SQLite connection.
|
|
435
|
+
|
|
292
436
|
## Related docs
|
|
293
437
|
|
|
294
438
|
- [Quickstart](quickstart.md)
|
|
@@ -254,6 +254,12 @@ data:
|
|
|
254
254
|
Transition details are in `data`, not `error.details`. `error` only has `code`
|
|
255
255
|
and `message`.
|
|
256
256
|
|
|
257
|
+
**Allowed bypass:** `task done` performs an atomic single-transaction direct
|
|
258
|
+
write to `done` from any non-`done` status (`todo`, `blocked`, `in_progress`),
|
|
259
|
+
emitting one `task.updated` event — there is no intermediate `in_progress`
|
|
260
|
+
event when starting from `todo`/`blocked`. This is the only sanctioned
|
|
261
|
+
bypass of the status-machine checker.
|
|
262
|
+
|
|
257
263
|
## Epic progress
|
|
258
264
|
|
|
259
265
|
```bash
|
|
@@ -328,6 +334,69 @@ data:
|
|
|
328
334
|
pendingConflicts
|
|
329
335
|
```
|
|
330
336
|
|
|
337
|
+
## Task claim
|
|
338
|
+
|
|
339
|
+
```bash
|
|
340
|
+
trekoon --toon task claim <task-id> --owner <owner>
|
|
341
|
+
trekoon --toon subtask claim <subtask-id> --owner <owner>
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
Atomically claims a task or subtask using SQL compare-and-swap. The single
|
|
345
|
+
UPDATE predicate ensures exactly one concurrent caller gets `claimed: true`.
|
|
346
|
+
|
|
347
|
+
Success (claimed):
|
|
348
|
+
|
|
349
|
+
```text
|
|
350
|
+
ok: true
|
|
351
|
+
command: task.claim | subtask.claim
|
|
352
|
+
data:
|
|
353
|
+
claimed: true
|
|
354
|
+
currentOwner: <owner>
|
|
355
|
+
currentStatus: in_progress
|
|
356
|
+
task | subtask: { ...full record... }
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
Not claimed (another owner holds it, or status is done/in_progress by others):
|
|
360
|
+
|
|
361
|
+
```text
|
|
362
|
+
ok: true
|
|
363
|
+
command: task.claim | subtask.claim
|
|
364
|
+
data:
|
|
365
|
+
claimed: false
|
|
366
|
+
currentOwner: <string> | null
|
|
367
|
+
currentStatus: in_progress | done | todo | blocked
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
Note: `claimed: false` is a successful response (`ok: true`). The command
|
|
371
|
+
reports the current state, not an error condition. Check `data.claimed` to
|
|
372
|
+
distinguish the two cases.
|
|
373
|
+
|
|
374
|
+
Dependency gating on claim (cr-expert hardening): when the task or subtask is
|
|
375
|
+
in `blocked` or `todo` and has unresolved dependencies, the claim atomically
|
|
376
|
+
fails with `code: dependency_blocked` rather than flipping the row into
|
|
377
|
+
`in_progress`. This mirrors `task done` semantics so neither
|
|
378
|
+
forward-progress transition (`todo|blocked → in_progress` via claim,
|
|
379
|
+
`* → done` via `task done`) can bypass dependency resolution.
|
|
380
|
+
|
|
381
|
+
```text
|
|
382
|
+
ok: false
|
|
383
|
+
command: task.claim | subtask.claim
|
|
384
|
+
error:
|
|
385
|
+
code: dependency_blocked
|
|
386
|
+
message: "task cannot transition to in_progress while dependencies are unresolved"
|
|
387
|
+
data:
|
|
388
|
+
unresolvedDependencyCount: <number>
|
|
389
|
+
unresolvedDependencyIds: [<id>, ...]
|
|
390
|
+
unresolvedDependencies: [{ id, kind, status }, ...]
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
The only intentional direct-status-write exception in the codebase remains
|
|
394
|
+
`MutationService.markTaskDoneAtomically`, which bypasses
|
|
395
|
+
`validateStatusTransition` for the `* → done` flip but still goes through
|
|
396
|
+
`assertNoUnresolvedDependenciesForStatusTransition` before issuing the UPDATE.
|
|
397
|
+
No other call site is permitted to write `status` directly without going
|
|
398
|
+
through the public transition checker.
|
|
399
|
+
|
|
331
400
|
## Owner field in updates
|
|
332
401
|
|
|
333
402
|
Task and subtask update payloads include `owner`:
|
|
@@ -538,6 +607,60 @@ error:
|
|
|
538
607
|
message: "Pending conflicts changed before batch resolution could be applied."
|
|
539
608
|
```
|
|
540
609
|
|
|
610
|
+
## Error code registry
|
|
611
|
+
|
|
612
|
+
All machine-visible error codes emitted by Trekoon. Every `error.code` value in
|
|
613
|
+
any `ok: false` response will be one of the following strings.
|
|
614
|
+
|
|
615
|
+
| Code | Description |
|
|
616
|
+
|---|---|
|
|
617
|
+
| `already_done` | Entity is already in `done` status; transition is a no-op. |
|
|
618
|
+
| `already_resolved` | Conflict was resolved by another process before this write. |
|
|
619
|
+
| `ambiguous_legacy_state` | Legacy worktree state is ambiguous and cannot be automatically resolved. |
|
|
620
|
+
| `backpressure` | SSE snapshot stream disconnected a slow client whose queued bytes exceeded the hard limit. |
|
|
621
|
+
| `backup_already_exists` | A backup file already exists at the target path; overwrite was not requested. |
|
|
622
|
+
| `backup_database_missing` | Source database file not found when attempting to create a backup. |
|
|
623
|
+
| `backup_failed` | Backup operation failed (I/O or copy error). |
|
|
624
|
+
| `cancelled` | Operation was cancelled by the user (e.g. confirmation prompt rejected). |
|
|
625
|
+
| `confirmation_required` | Human-mode operation requires explicit confirmation before proceeding. |
|
|
626
|
+
| `conflict_set_changed` | Batch conflict set changed between preview and confirmed write. |
|
|
627
|
+
| `daemon_start_failed` | Daemon failed to start (socket bind error or already running). |
|
|
628
|
+
| `database_busy` | SQLite database is locked; retry after a short wait. |
|
|
629
|
+
| `dependency_blocked` | Cascade update blocked because one or more descendants have unresolved dependencies. |
|
|
630
|
+
| `disallowed_field` | Sync resolve attempted to write a field that is not on the allow-list. |
|
|
631
|
+
| `events_failed` | Event log query or export failed. |
|
|
632
|
+
| `install_failed` | Skill installation failed (file copy or permission error). |
|
|
633
|
+
| `internal_error` | Unexpected internal error; inspect server logs for details. |
|
|
634
|
+
| `invalid_args` | Required positional arguments are missing or malformed. |
|
|
635
|
+
| `invalid_dependency` | Dependency edge is invalid (self-loop, wrong entity type, or duplicate). |
|
|
636
|
+
| `invalid_input` | One or more option values failed validation. |
|
|
637
|
+
| `invalid_path` | File path is invalid for the requested operation (e.g. path is a directory). |
|
|
638
|
+
| `invalid_source` | Source entity for a dependency or sync operation does not exist or is of wrong kind. |
|
|
639
|
+
| `invalid_state` | Entity or system is in a state that does not permit the requested operation. |
|
|
640
|
+
| `invalid_subcommand` | Unrecognised subcommand for this command group. |
|
|
641
|
+
| `legacy_import_failed` | Import from a legacy (pre-`.trekoon`) data directory failed. |
|
|
642
|
+
| `migrate_failed` | Database schema migration failed. |
|
|
643
|
+
| `migration_down_unsupported` | Down-migrations are not supported; only forward migrations are allowed. |
|
|
644
|
+
| `missing_asset` | Expected bundled asset (skill file, template) was not found. |
|
|
645
|
+
| `no_matching_conflicts` | `sync resolve --all` filters matched zero pending conflicts. |
|
|
646
|
+
| `not_found` | Requested entity (epic, task, subtask, dependency) does not exist. |
|
|
647
|
+
| `orphaned_external_node` | Dependency graph contains a node that belongs to a different epic. |
|
|
648
|
+
| `outside_repo_target` | Skill install target path is outside the repository root. |
|
|
649
|
+
| `permission_denied` | File-system permission denied for the requested path. |
|
|
650
|
+
| `precondition_failed` | `If-Match` precondition header did not match the entity's current `updatedAt`. |
|
|
651
|
+
| `row_not_found` | Sync resolve target row no longer exists in the database. |
|
|
652
|
+
| `status_transition_invalid` | Requested status transition is not permitted by the status machine. |
|
|
653
|
+
| `stream_unavailable` | SSE snapshot stream is not available (board not initialised or shutting down). |
|
|
654
|
+
| `sync_failed` | Sync pull or push operation failed. |
|
|
655
|
+
| `tracked_ignored_mismatch` | Worktree is tracked by Trekoon but its path is in `.gitignore`, or vice-versa. |
|
|
656
|
+
| `unauthorized` | Request lacks valid authentication credentials. |
|
|
657
|
+
| `unhandled_command` | Command matched a known group but no case handled the subcommand. |
|
|
658
|
+
| `unknown_command` | Top-level command token is not recognised. |
|
|
659
|
+
| `unknown_option` | An option flag passed to the command is not recognised. |
|
|
660
|
+
| `unsupported_entity_kind` | Sync resolve encountered an entity kind that the writer does not handle. |
|
|
661
|
+
| `update_failed` | Skill update failed (download, copy, or permission error). |
|
|
662
|
+
| `wrong_entity_type` | Operation requires a specific entity kind but a different kind was supplied. |
|
|
663
|
+
|
|
541
664
|
## Related docs
|
|
542
665
|
|
|
543
666
|
- [Quickstart](quickstart.md)
|
package/docs/quickstart.md
CHANGED
|
@@ -69,7 +69,7 @@ if you just need to refresh the runtime assets without opening the browser.
|
|
|
69
69
|
## Create work
|
|
70
70
|
|
|
71
71
|
```bash
|
|
72
|
-
trekoon epic create --title "Agent backlog stabilization" --description "Track stabilization work" --status todo
|
|
72
|
+
trekoon --toon epic create --title "Agent backlog stabilization" --description "Track stabilization work" --status todo
|
|
73
73
|
trekoon task create --title "Implement sync status" --description "Add status reporting" --epic <epic-id> --status todo
|
|
74
74
|
trekoon subtask create --task <task-id> --title "Add cursor model" --status todo
|
|
75
75
|
```
|
|
@@ -88,7 +88,7 @@ trekoon task list --all --view compact
|
|
|
88
88
|
If you already know the full epic tree, create everything in one call:
|
|
89
89
|
|
|
90
90
|
```bash
|
|
91
|
-
trekoon epic create \
|
|
91
|
+
trekoon --toon epic create \
|
|
92
92
|
--title "Batch command rollout" \
|
|
93
93
|
--description "Ship one-shot planning workflows" \
|
|
94
94
|
--task "task-a|First task|First description|todo" \
|
|
@@ -118,7 +118,7 @@ For larger updates, use batch commands instead of looping:
|
|
|
118
118
|
| Multiple tasks under one epic | `trekoon task create-many --epic <epic-id> --task ...` |
|
|
119
119
|
| Multiple subtasks under one task | `trekoon subtask create-many <task-id> --subtask ...` |
|
|
120
120
|
| Multiple dependency edges | `trekoon dep add-many --dep ...` |
|
|
121
|
-
| Expand an existing epic | `trekoon epic expand <epic-id> ...` |
|
|
121
|
+
| Expand an existing epic | `trekoon --toon epic expand <epic-id> ...` |
|
|
122
122
|
|
|
123
123
|
These validate the whole batch before applying, so a bad input fails the entire
|
|
124
124
|
operation instead of leaving partial state.
|
|
@@ -148,6 +148,58 @@ a file extension means "write this file"; no extension means "put the default-
|
|
|
148
148
|
named file in this directory". Use `--overwrite` to resave after the plan state
|
|
149
149
|
changes.
|
|
150
150
|
|
|
151
|
+
## Claim work atomically
|
|
152
|
+
|
|
153
|
+
When multiple agents or lanes work in parallel, use `claim` to avoid races:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
trekoon task claim <task-id> --owner <owner>
|
|
157
|
+
trekoon subtask claim <subtask-id> --owner <owner>
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Both commands use a SQL compare-and-swap: the claim succeeds only when the item
|
|
161
|
+
is `todo` or `blocked` and the owner is `NULL` or already set to `<owner>`.
|
|
162
|
+
The response includes `claimed` (true/false), `currentOwner`, `currentStatus`,
|
|
163
|
+
and the full entity record on success. Two concurrent claims return exactly one
|
|
164
|
+
`claimed=true`.
|
|
165
|
+
|
|
166
|
+
## Database backup and migration
|
|
167
|
+
|
|
168
|
+
Before any manual migration recovery, snapshot the database:
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
trekoon migrate backup
|
|
172
|
+
trekoon migrate backup --retain 5 # keep last 5 backups (default 10)
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
This writes a timestamped copy of `.trekoon/trekoon.db` next to the live file.
|
|
176
|
+
To check the current schema version or roll back:
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
trekoon migrate status
|
|
180
|
+
trekoon migrate rollback # one version back
|
|
181
|
+
trekoon migrate rollback --to-version 1
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## Daemon mode (experimental)
|
|
185
|
+
|
|
186
|
+
> **Not for routine agent use.** `trekoon serve` and `--daemon` are
|
|
187
|
+
> experimental; use the default one-shot CLI path in automated workflows.
|
|
188
|
+
|
|
189
|
+
`trekoon serve` starts a foreground daemon on a Unix-domain socket inside
|
|
190
|
+
`.trekoon`. Subsequent calls skip Bun startup, module load, and database
|
|
191
|
+
open — per `bench/daemon-session.ts`: daemon median < 10 ms vs. cold
|
|
192
|
+
one-shot median > 50 ms:
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
trekoon serve # start the daemon (foreground)
|
|
196
|
+
trekoon --daemon session # route a call through the daemon
|
|
197
|
+
TREKOON_DAEMON=1 trekoon session # same, via environment variable
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
If the socket is missing or unreachable the client falls back silently to the
|
|
201
|
+
normal one-shot path. The socket is 0o600 and `.trekoon` is forced to 0o700.
|
|
202
|
+
|
|
151
203
|
## Check progress
|
|
152
204
|
|
|
153
205
|
```bash
|
package/package.json
CHANGED