trekoon 0.4.2 → 0.4.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 +97 -208
- package/.agents/skills/trekoon/reference/execution-with-team.md +87 -149
- package/.agents/skills/trekoon/reference/execution.md +170 -380
- package/.agents/skills/trekoon/reference/harness-primitives.md +77 -0
- package/.agents/skills/trekoon/reference/planning.md +193 -330
- package/.agents/skills/trekoon/reference/sync.md +56 -103
- package/README.md +29 -10
- package/docs/ai-agents.md +48 -4
- package/docs/commands.md +34 -25
- package/docs/machine-contracts.md +1 -1
- package/docs/quickstart.md +9 -9
- package/package.json +2 -2
- package/src/board/asset-root.ts +73 -0
- package/src/board/assets/app.js +5 -3
- package/src/board/assets/components/Component.js +6 -8
- package/src/board/assets/state/actions.js +3 -0
- package/src/board/assets/state/api.js +48 -34
- package/src/board/assets/state/store.js +3 -0
- package/src/board/event-bus.ts +15 -0
- package/src/board/routes.ts +94 -83
- package/src/board/server.ts +35 -8
- package/src/board/snapshot.ts +6 -0
- package/src/board/types.ts +2 -34
- package/src/board/wal-watcher.ts +170 -28
- package/src/commands/board.ts +20 -42
- package/src/commands/help.ts +11 -12
- package/src/commands/init.ts +0 -29
- package/src/commands/quickstart.ts +1 -1
- package/src/commands/skills.ts +17 -5
- package/src/domain/mutation-service.ts +61 -42
- package/src/domain/tracker-domain.ts +20 -16
- package/src/domain/types.ts +3 -0
- package/src/export/render-markdown.ts +1 -2
- package/src/runtime/daemon.ts +110 -49
- package/src/runtime/version.ts +10 -2
- package/src/storage/database.ts +9 -2
- package/src/storage/migrations.ts +19 -2
- package/src/storage/path.ts +0 -36
- package/src/sync/service.ts +47 -27
- package/src/board/install.ts +0 -196
|
@@ -1,129 +1,82 @@
|
|
|
1
1
|
# Sync Reference
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Trekoon uses one live SQLite database per repository at
|
|
4
|
+
`<sharedStorageRoot>/.trekoon/trekoon.db`. Linked worktrees share it. `git
|
|
5
|
+
checkout` and `git switch` do not roll back tracker state. Sync imports tracker
|
|
6
|
+
events between branches; never copy or commit the `.db` file.
|
|
4
7
|
|
|
5
|
-
Same-branch sync is a no-op
|
|
6
|
-
|
|
7
|
-
on the source branch. No action is needed.
|
|
8
|
+
Same-branch sync is a no-op. Cross-branch sync matters before merging a feature
|
|
9
|
+
branch back.
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
## Before Merge
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
Pull tracker events from the base branch:
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
- If conflicts exist, inspect and resolve them explicitly:
|
|
15
|
+
```bash
|
|
16
|
+
trekoon --toon sync pull --from main
|
|
17
|
+
```
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
trekoon --toon sync conflicts list
|
|
21
|
-
trekoon --toon sync conflicts show <conflict-id>
|
|
22
|
-
trekoon --toon sync resolve <conflict-id> --use theirs --dry-run
|
|
23
|
-
trekoon --toon sync resolve <conflict-id> --use ours
|
|
24
|
-
```
|
|
19
|
+
If conflicts exist:
|
|
25
20
|
|
|
26
|
-
|
|
21
|
+
```bash
|
|
22
|
+
trekoon --toon sync conflicts list
|
|
23
|
+
trekoon --toon sync conflicts show <conflict-id>
|
|
24
|
+
trekoon --toon sync resolve <conflict-id> --use theirs --dry-run
|
|
25
|
+
trekoon --toon sync resolve <conflict-id> --use ours
|
|
26
|
+
```
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
(e.g., `status`, `title`, `description`) on one entity.
|
|
28
|
+
## Conflict Rules
|
|
30
29
|
|
|
31
|
-
-
|
|
32
|
-
|
|
33
|
-
resolution event is appended.
|
|
34
|
-
- `--use theirs` — overwrite the shared DB entity field with the source-branch
|
|
35
|
-
value. The conflict record is marked resolved and a resolution event is
|
|
36
|
-
appended.
|
|
37
|
-
- `--dry-run` — preview the resolution without mutating the database. Returns
|
|
38
|
-
`oursValue`, `theirsValue`, `wouldWrite`, and `dryRun: true`. Use this before
|
|
39
|
-
committing to a resolution.
|
|
30
|
+
Conflicts are field-level, not whole-record. Each conflict targets one field on
|
|
31
|
+
one entity.
|
|
40
32
|
|
|
41
|
-
|
|
42
|
-
field
|
|
43
|
-
|
|
44
|
-
-
|
|
45
|
-
|
|
46
|
-
- `--use theirs` changes status to `done` in the live shared DB
|
|
33
|
+
- `--use ours`: keep the current shared DB field value; mark conflict resolved.
|
|
34
|
+
- `--use theirs`: write the source-branch field value into the shared DB; mark
|
|
35
|
+
conflict resolved.
|
|
36
|
+
- `--dry-run`: preview without mutation. Returns `oursValue`, `theirsValue`,
|
|
37
|
+
`wouldWrite`, and `dryRun: true`.
|
|
47
38
|
|
|
48
|
-
Always inspect
|
|
49
|
-
|
|
39
|
+
Always inspect with `sync conflicts show` before resolving. Choosing `theirs`
|
|
40
|
+
without inspection can overwrite in-progress shared DB work.
|
|
50
41
|
|
|
51
|
-
|
|
42
|
+
Typical choices:
|
|
52
43
|
|
|
53
|
-
| Scenario |
|
|
44
|
+
| Scenario | Usually use | Why |
|
|
54
45
|
|---|---|---|
|
|
55
|
-
| Completed work vs stale main
|
|
46
|
+
| Completed work vs stale main | ours | Your branch has latest progress |
|
|
56
47
|
| Enriched descriptions vs original | ours | Your descriptions are more detailed |
|
|
57
|
-
| Upstream updates from another agent | theirs | Accept
|
|
58
|
-
| User-intentional reset | theirs | Respect
|
|
48
|
+
| Upstream updates from another agent | theirs | Accept newer upstream state |
|
|
49
|
+
| User-intentional reset | theirs | Respect explicit user action |
|
|
59
50
|
|
|
60
|
-
|
|
51
|
+
When unsure, ask the user.
|
|
61
52
|
|
|
62
|
-
|
|
63
|
-
2. Group by pattern — are conflicts on the same field or direction?
|
|
64
|
-
3. If uniform pattern, batch resolve: `trekoon --toon sync resolve --all --use ours`
|
|
65
|
-
4. If mixed, narrow by entity or field, or inspect individually
|
|
66
|
-
5. When unsure, ask the user
|
|
67
|
-
|
|
68
|
-
### Batch resolve patterns
|
|
69
|
-
|
|
70
|
-
Common scenarios:
|
|
53
|
+
## Batch Resolve
|
|
71
54
|
|
|
72
55
|
```bash
|
|
73
|
-
# Resolve all conflicts at once (most common after completing work)
|
|
74
|
-
trekoon --toon sync resolve --all --use ours
|
|
75
|
-
|
|
76
|
-
# Preview before resolving
|
|
77
56
|
trekoon --toon sync resolve --all --use ours --dry-run
|
|
78
|
-
|
|
79
|
-
# Narrow to status field conflicts only
|
|
57
|
+
trekoon --toon sync resolve --all --use ours
|
|
80
58
|
trekoon --toon sync resolve --all --use ours --field status
|
|
81
|
-
|
|
82
|
-
# Narrow to a specific entity
|
|
83
59
|
trekoon --toon sync resolve --all --use theirs --entity <id>
|
|
84
|
-
|
|
85
|
-
# Combine filters
|
|
86
60
|
trekoon --toon sync resolve --all --use ours --entity <id> --field description
|
|
87
61
|
```
|
|
88
62
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
**Conflicts are scoped per worktree + branch.** `sync_conflicts` rows are
|
|
110
|
-
recorded with the originating worktree path and current branch, so resolving a
|
|
111
|
-
conflict in one worktree never erases a peer worktree's conflict on the same
|
|
112
|
-
entity. `sync conflicts list` and `sync resolve` from a given worktree only
|
|
113
|
-
see and act on rows scoped to that worktree's branch.
|
|
114
|
-
|
|
115
|
-
## Worktree diagnostics and destructive scope
|
|
116
|
-
|
|
117
|
-
- Inspect machine-readable storage fields when debugging worktrees:
|
|
118
|
-
`storageMode`, `repoCommonDir`, `worktreeRoot`, `sharedStorageRoot`, and
|
|
119
|
-
`databaseFile`.
|
|
120
|
-
- `sharedStorageRoot` is the repo-scoped source of truth for `.trekoon` in git
|
|
121
|
-
worktrees.
|
|
122
|
-
- If `trekoon wipe --yes --toon` is explicitly requested, warn that it deletes
|
|
123
|
-
shared storage for the entire repository and every linked worktree.
|
|
124
|
-
- Wipe is destructive recovery only; it is never the right fix for a tracked DB
|
|
125
|
-
or gitignore mistake.
|
|
126
|
-
|
|
127
|
-
Trekoon stores local state in `.trekoon/trekoon.db`. In git repos and
|
|
128
|
-
worktrees, storage resolves from the shared repository root rather than each
|
|
129
|
-
worktree independently.
|
|
63
|
+
Use batch resolve only when the conflict pattern is uniform. Otherwise inspect
|
|
64
|
+
and resolve individually or narrow by `--entity` / `--field`.
|
|
65
|
+
|
|
66
|
+
## Worktree Scope
|
|
67
|
+
|
|
68
|
+
Inspect machine-readable storage fields when debugging worktrees:
|
|
69
|
+
`storageMode`, `repoCommonDir`, `worktreeRoot`, `sharedStorageRoot`, and
|
|
70
|
+
`databaseFile`.
|
|
71
|
+
|
|
72
|
+
Conflicts are scoped per worktree and branch. `sync conflicts list` and
|
|
73
|
+
`sync resolve` only act on rows for the current worktree/branch, so resolving a
|
|
74
|
+
conflict does not erase a peer worktree's conflict on the same entity.
|
|
75
|
+
|
|
76
|
+
## Destructive Recovery
|
|
77
|
+
|
|
78
|
+
`sharedStorageRoot` is the repo-scoped source of truth for `.trekoon` in git
|
|
79
|
+
worktrees. If the user explicitly requests `trekoon wipe --yes --toon`, warn
|
|
80
|
+
that it deletes shared storage for the whole repository and every linked
|
|
81
|
+
worktree. Wipe is destructive recovery only; it is never the fix for a tracked
|
|
82
|
+
DB or gitignore mistake.
|
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
|
|
|
@@ -182,14 +196,19 @@ call it from any non-done status.
|
|
|
182
196
|
|
|
183
197
|
## Local board
|
|
184
198
|
|
|
185
|
-
Trekoon includes a browser-based board for humans who like having visual
|
|
186
|
-
No build step, no framework dependencies, works offline.
|
|
199
|
+
Trekoon includes a browser-based board for humans who like having a visual
|
|
200
|
+
overview. No build step, no framework dependencies, works offline.
|
|
187
201
|
|
|
188
202
|
```bash
|
|
189
203
|
trekoon board open # starts a local server, opens browser
|
|
190
|
-
trekoon board update # refresh assets only
|
|
191
204
|
```
|
|
192
205
|
|
|
206
|
+
Board code (HTML, JS, CSS, fonts) comes from the running Trekoon install.
|
|
207
|
+
Board data comes from the repo where `trekoon board open` is invoked. Updating
|
|
208
|
+
Trekoon updates the board bundle; no per-repo asset copy is needed.
|
|
209
|
+
Repos with an old ignored `.trekoon/board` directory keep those files on disk,
|
|
210
|
+
but Trekoon no longer reads or refreshes them.
|
|
211
|
+
|
|
193
212
|
Binds to `127.0.0.1` only with a per-session token. Gives you an epics
|
|
194
213
|
overview, kanban workspace per epic, task detail modals, and search. The board
|
|
195
214
|
client subscribes to `/api/snapshot/stream` (SSE), so mutations from another
|
|
@@ -201,7 +220,7 @@ shell, worktree, or browser tab show up live without a manual refresh.
|
|
|
201
220
|
| --- | --- |
|
|
202
221
|
| Set up a repo | `trekoon init` |
|
|
203
222
|
| Open the local board | `trekoon board open` |
|
|
204
|
-
| Plan work | `trekoon epic create ...`, `trekoon epic expand ...` |
|
|
223
|
+
| Plan work | `trekoon --toon epic create ...`, `trekoon --toon epic expand ...` |
|
|
205
224
|
| Create tasks in bulk | `trekoon task create-many ...` |
|
|
206
225
|
| Add dependencies | `trekoon dep add-many ...` |
|
|
207
226
|
| Start an agent session | `trekoon session --epic <id>` |
|
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
|
|
@@ -97,6 +116,17 @@ Typical flow:
|
|
|
97
116
|
|
|
98
117
|
The core loop: **session, work, task done, repeat**.
|
|
99
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
|
+
|
|
100
130
|
Start with a single orientation call, optionally scoped to an epic:
|
|
101
131
|
|
|
102
132
|
```bash
|
|
@@ -193,6 +223,20 @@ notes, mark it done, and repeat until there are no ready tasks or you hit a
|
|
|
193
223
|
blocker.
|
|
194
224
|
```
|
|
195
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
|
+
|
|
196
240
|
### Plan and execute end to end
|
|
197
241
|
|
|
198
242
|
```text
|
package/docs/commands.md
CHANGED
|
@@ -6,7 +6,7 @@ the quickest way to get started, read [Quickstart](quickstart.md) first.
|
|
|
6
6
|
## Command surface
|
|
7
7
|
|
|
8
8
|
- `trekoon init`
|
|
9
|
-
- `trekoon board <open
|
|
9
|
+
- `trekoon board <open>`
|
|
10
10
|
- `trekoon help [command]`
|
|
11
11
|
- `trekoon quickstart`
|
|
12
12
|
- `trekoon epic <create|expand|list|show|search|replace|update|delete|progress>`
|
|
@@ -22,8 +22,8 @@ the quickest way to get started, read [Quickstart](quickstart.md) first.
|
|
|
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
29
|
- `trekoon serve` (experimental)
|
|
@@ -50,25 +50,31 @@ also accept `-h` and `-v`.
|
|
|
50
50
|
|
|
51
51
|
## Board commands
|
|
52
52
|
|
|
53
|
-
`trekoon board open`
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
`trekoon board open` starts a loopback-only server on `127.0.0.1` with a
|
|
54
|
+
random port, opens the browser, and returns the board URL plus a manual
|
|
55
|
+
fallback URL.
|
|
56
56
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
Board code (HTML, JS, CSS, fonts) comes from the running Trekoon install —
|
|
58
|
+
a global install serves the global package assets; a project-local install
|
|
59
|
+
serves the project-local package assets. Board data comes from the repo where
|
|
60
|
+
`trekoon board open` is invoked. Updating Trekoon updates the board bundle;
|
|
61
|
+
no per-repo asset copy is needed.
|
|
60
62
|
|
|
61
63
|
Security model:
|
|
62
64
|
|
|
63
65
|
- Every `board open` session gets a unique token
|
|
64
|
-
-
|
|
65
|
-
`
|
|
66
|
+
- Initial board HTML bootstrap accepts `?token={token}` once, sets an
|
|
67
|
+
HttpOnly `trekoon_board_session` cookie, and redirects to the same URL
|
|
68
|
+
without the token query parameter
|
|
69
|
+
- Board API requests must authenticate with the session cookie,
|
|
70
|
+
`Authorization: Bearer {token}`, or `x-trekoon-token` header
|
|
71
|
+
- API routes reject token query parameters
|
|
72
|
+
- `/api/snapshot/stream` is authenticated by the session cookie
|
|
66
73
|
- Invalid tokens return `401`
|
|
67
74
|
- Static responses use `cache-control: no-store`
|
|
68
75
|
|
|
69
76
|
The board is a self-hosted single-page app (vanilla JS, bundled CSS and fonts,
|
|
70
|
-
no framework or CDN dependencies)
|
|
71
|
-
offline once initialized.
|
|
77
|
+
no framework or CDN dependencies). Works fully offline.
|
|
72
78
|
|
|
73
79
|
Board API endpoints (all require token authentication):
|
|
74
80
|
|
|
@@ -84,27 +90,30 @@ Board API endpoints (all require token authentication):
|
|
|
84
90
|
| `POST` | `/api/dependencies` | Add dependency edge (sourceId, dependsOnId) |
|
|
85
91
|
| `DELETE` | `/api/dependencies?sourceId=...&dependsOnId=...` | Remove dependency |
|
|
86
92
|
|
|
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
93
|
Board mutations from any source — board UI, CLI in another shell, or another
|
|
93
94
|
worktree — propagate to every connected client through the SSE stream. The CLI
|
|
94
95
|
side is driven by a WAL-watcher that diffs the snapshot when
|
|
95
96
|
`.trekoon/trekoon.db-wal` changes; in-process mutations publish deltas
|
|
96
|
-
directly. PATCH endpoints accept `If-Match: <
|
|
97
|
-
concurrency
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
97
|
+
directly. PATCH endpoints accept `If-Match: <version>` for optimistic
|
|
98
|
+
concurrency; RFC 7232 strong or `W/`-prefixed weak ETag forms are accepted,
|
|
99
|
+
but the `*` wildcard is not. A stale value returns `409` with
|
|
100
|
+
`currentVersion` and `providedVersion`. Missing `If-Match` is allowed for
|
|
101
|
+
back-compat.
|
|
102
|
+
|
|
103
|
+
Repos that already have an ignored `.trekoon/board` directory keep those files
|
|
104
|
+
on disk, but current Trekoon versions no longer read, create, refresh, or
|
|
105
|
+
delete them. Remove that directory manually only if you want to clean up the
|
|
106
|
+
old copied board bundle.
|
|
107
|
+
|
|
108
|
+
`trekoon board open` accepts `--reveal-token` to include the raw tokenized URL,
|
|
109
|
+
server token, and browser launch arguments in machine output. Other board
|
|
110
|
+
subcommands and flags are rejected. `TREKOON_BOARD_ASSET_ROOT` overrides the
|
|
111
|
+
asset source for tests and local development.
|
|
102
112
|
|
|
103
113
|
```bash
|
|
104
114
|
trekoon init
|
|
105
115
|
trekoon board open
|
|
106
116
|
trekoon --json board open
|
|
107
|
-
trekoon board update
|
|
108
117
|
```
|
|
109
118
|
|
|
110
119
|
## Human views
|
|
@@ -647,7 +647,7 @@ any `ok: false` response will be one of the following strings.
|
|
|
647
647
|
| `orphaned_external_node` | Dependency graph contains a node that belongs to a different epic. |
|
|
648
648
|
| `outside_repo_target` | Skill install target path is outside the repository root. |
|
|
649
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 `
|
|
650
|
+
| `precondition_failed` | `If-Match` precondition header did not match the entity's current version. Error details include `currentVersion` and `providedVersion`. |
|
|
651
651
|
| `row_not_found` | Sync resolve target row no longer exists in the database. |
|
|
652
652
|
| `status_transition_invalid` | Requested status transition is not permitted by the status machine. |
|
|
653
653
|
| `stream_unavailable` | SSE snapshot stream is not available (board not initialised or shutting down). |
|
package/docs/quickstart.md
CHANGED
|
@@ -50,9 +50,8 @@ trekoon --toon init
|
|
|
50
50
|
trekoon --toon sync status
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
-
Run `init` once per repository. It creates the shared storage root
|
|
54
|
-
|
|
55
|
-
`recoveryRequired` or a tracked/ignored mismatch, fix the setup before
|
|
53
|
+
Run `init` once per repository. It creates the shared storage root. If `sync status`
|
|
54
|
+
reports `recoveryRequired` or a tracked/ignored mismatch, fix the setup before
|
|
56
55
|
continuing.
|
|
57
56
|
|
|
58
57
|
## Open the board
|
|
@@ -62,14 +61,15 @@ trekoon board open
|
|
|
62
61
|
```
|
|
63
62
|
|
|
64
63
|
Starts a loopback-only server on `127.0.0.1`, opens the browser, and prints a
|
|
65
|
-
fallback URL.
|
|
66
|
-
|
|
67
|
-
|
|
64
|
+
fallback URL. Board code (HTML, JS, CSS, fonts) comes from the running Trekoon
|
|
65
|
+
install; board data comes from the repo where the command is invoked. The board
|
|
66
|
+
works fully offline. To get an updated board UI, update Trekoon itself. Old
|
|
67
|
+
ignored `.trekoon/board` copies are left on disk but are no longer used.
|
|
68
68
|
|
|
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.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "trekoon",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.4",
|
|
4
4
|
"description": "AI-first task tracking that lives in your repo. You describe what to build, your agent plans it as a dependency graph, then executes it task by task",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
],
|
|
41
41
|
"scripts": {
|
|
42
42
|
"run": "bun run ./src/index.ts",
|
|
43
|
-
"build": "bun build ./src/index.ts --outdir ./dist --target bun",
|
|
43
|
+
"build": "bun build ./src/index.ts --outdir ./dist --target bun && cp ./package.json ./dist/package.json && rm -rf ./dist/assets && cp -R ./src/board/assets ./dist/assets",
|
|
44
44
|
"test": "bun test ./tests",
|
|
45
45
|
"lint": "bunx tsc --noEmit"
|
|
46
46
|
},
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { existsSync, statSync } from "node:fs";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
|
|
5
|
+
import { BoardAssetError } from "./types";
|
|
6
|
+
|
|
7
|
+
export const BOARD_BUNDLED_ASSET_DIRNAME = "assets";
|
|
8
|
+
export const BOARD_ENTRY_FILENAME = "index.html";
|
|
9
|
+
export const BOARD_ASSET_ROOT_ENV_VAR = "TREKOON_BOARD_ASSET_ROOT";
|
|
10
|
+
|
|
11
|
+
export type BoardAssetRootSource = "override" | "environment" | "package";
|
|
12
|
+
|
|
13
|
+
export interface BoardAssetRoot {
|
|
14
|
+
readonly assetRoot: string;
|
|
15
|
+
readonly entryFile: string;
|
|
16
|
+
readonly source: BoardAssetRootSource;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface ResolveBoardAssetRootOptions {
|
|
20
|
+
readonly assetRootOverride?: string;
|
|
21
|
+
readonly env?: NodeJS.ProcessEnv;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function resolvePackageBoardAssetRoot(): string {
|
|
25
|
+
return fileURLToPath(new URL(`./${BOARD_BUNDLED_ASSET_DIRNAME}`, import.meta.url));
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
interface SelectedAssetRoot {
|
|
29
|
+
readonly rootPath: string;
|
|
30
|
+
readonly source: BoardAssetRootSource;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function selectAssetRoot(options: ResolveBoardAssetRootOptions): SelectedAssetRoot {
|
|
34
|
+
if (options.assetRootOverride !== undefined) {
|
|
35
|
+
return { rootPath: resolve(options.assetRootOverride), source: "override" };
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const env = options.env ?? process.env;
|
|
39
|
+
const envOverrideRaw = env[BOARD_ASSET_ROOT_ENV_VAR];
|
|
40
|
+
const envOverride = typeof envOverrideRaw === "string" ? envOverrideRaw.trim() : "";
|
|
41
|
+
if (envOverride.length > 0) {
|
|
42
|
+
return { rootPath: resolve(envOverride), source: "environment" };
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return { rootPath: resolvePackageBoardAssetRoot(), source: "package" };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function resolveBoardAssetRoot(options: ResolveBoardAssetRootOptions = {}): BoardAssetRoot {
|
|
49
|
+
const { rootPath, source } = selectAssetRoot(options);
|
|
50
|
+
|
|
51
|
+
if (!existsSync(rootPath) || !statSync(rootPath).isDirectory()) {
|
|
52
|
+
throw new BoardAssetError("missing_asset", `Board asset root not found at ${rootPath}`, {
|
|
53
|
+
assetRoot: rootPath,
|
|
54
|
+
source,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const entryFile = resolve(rootPath, BOARD_ENTRY_FILENAME);
|
|
59
|
+
if (!existsSync(entryFile)) {
|
|
60
|
+
throw new BoardAssetError("missing_asset", `Board entry file not found at ${entryFile}`, {
|
|
61
|
+
assetRoot: rootPath,
|
|
62
|
+
entryFile,
|
|
63
|
+
source,
|
|
64
|
+
missingFile: BOARD_ENTRY_FILENAME,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return {
|
|
69
|
+
assetRoot: rootPath,
|
|
70
|
+
entryFile,
|
|
71
|
+
source,
|
|
72
|
+
};
|
|
73
|
+
}
|
package/src/board/assets/app.js
CHANGED
|
@@ -156,7 +156,7 @@ export async function bootLegacyBoard(options = {}) {
|
|
|
156
156
|
</div>
|
|
157
157
|
<span class="${sectionLabelClasses()}">Board ready</span>
|
|
158
158
|
<h1 class="mt-2 text-3xl font-semibold tracking-tight text-[var(--board-text)]">No work has been published yet</h1>
|
|
159
|
-
<p class="mx-auto mt-3 max-w-2xl text-sm leading-6 text-[var(--board-text-muted)] sm:text-base">
|
|
159
|
+
<p class="mx-auto mt-3 max-w-2xl text-sm leading-6 text-[var(--board-text-muted)] sm:text-base">Create or sync an epic in this repository and it will appear here.</p>
|
|
160
160
|
</div>
|
|
161
161
|
</section>
|
|
162
162
|
`;
|
|
@@ -479,9 +479,11 @@ export async function bootLegacyBoard(options = {}) {
|
|
|
479
479
|
rerender,
|
|
480
480
|
});
|
|
481
481
|
if (typeof window !== "undefined" && typeof window.addEventListener === "function") {
|
|
482
|
-
|
|
482
|
+
const disposeSnapshotSubscription = () => {
|
|
483
483
|
snapshotSubscription.dispose();
|
|
484
|
-
}
|
|
484
|
+
};
|
|
485
|
+
window.addEventListener("beforeunload", disposeSnapshotSubscription, { once: true });
|
|
486
|
+
window.addEventListener("pagehide", disposeSnapshotSubscription, { once: true });
|
|
485
487
|
}
|
|
486
488
|
|
|
487
489
|
// Actions for delegation
|