team-toon-tack 3.12.0 → 3.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.codex-plugin/plugin.json +1 -1
  4. package/README.md +95 -2
  5. package/README.zh-TW.md +93 -2
  6. package/bundled-skills/managing-linear-tasks/index.md +186 -0
  7. package/bundled-skills/managing-linear-tasks/orders-coordinator.md +53 -0
  8. package/bundled-skills/managing-linear-tasks/orders-integrator.md +45 -0
  9. package/commands/ttt-done.md +15 -4
  10. package/commands/ttt-order.md +177 -0
  11. package/commands/ttt-work-on.md +23 -2
  12. package/dist/bin/cli.js +19 -0
  13. package/dist/scripts/claim.js +61 -5
  14. package/dist/scripts/done-job.d.ts +0 -4
  15. package/dist/scripts/done-job.js +209 -103
  16. package/dist/scripts/lib/adapters/linear-adapter.js +5 -1
  17. package/dist/scripts/lib/done/args.js +12 -6
  18. package/dist/scripts/lib/done/handler.d.ts +2 -0
  19. package/dist/scripts/lib/done/handler.js +12 -0
  20. package/dist/scripts/lib/done/index.d.ts +1 -0
  21. package/dist/scripts/lib/done/index.js +1 -0
  22. package/dist/scripts/lib/done/status-check.d.ts +2 -1
  23. package/dist/scripts/lib/done/status-check.js +4 -3
  24. package/dist/scripts/lib/done/types.d.ts +2 -1
  25. package/dist/scripts/lib/order/close.d.ts +30 -0
  26. package/dist/scripts/lib/order/close.js +113 -0
  27. package/dist/scripts/lib/order/model.d.ts +125 -0
  28. package/dist/scripts/lib/order/model.js +762 -0
  29. package/dist/scripts/lib/order/remote.d.ts +34 -0
  30. package/dist/scripts/lib/order/remote.js +116 -0
  31. package/dist/scripts/lib/order/store.d.ts +80 -0
  32. package/dist/scripts/lib/order/store.js +394 -0
  33. package/dist/scripts/lib/order/transfer.d.ts +22 -0
  34. package/dist/scripts/lib/order/transfer.js +86 -0
  35. package/dist/scripts/lib/order/types.d.ts +114 -0
  36. package/dist/scripts/lib/order/types.js +19 -0
  37. package/dist/scripts/lib/skills.d.ts +21 -0
  38. package/dist/scripts/lib/skills.js +127 -0
  39. package/dist/scripts/lib/trello.js +3 -1
  40. package/dist/scripts/order.d.ts +2 -0
  41. package/dist/scripts/order.js +848 -0
  42. package/dist/scripts/skill.d.ts +2 -0
  43. package/dist/scripts/skill.js +42 -0
  44. package/dist/scripts/test-support/linear-mock.js +128 -23
  45. package/dist/scripts/test-support/linear-workspace.d.ts +44 -0
  46. package/dist/scripts/test-support/linear-workspace.js +136 -0
  47. package/package.json +3 -2
  48. package/skills/managing-linear-tasks/SKILL.md +6 -136
@@ -13,7 +13,7 @@
13
13
  "name": "team-toon-tack",
14
14
  "source": "./",
15
15
  "description": "Linear/Trello task sync & management CLI with commands and skills",
16
- "version": "3.12.0"
16
+ "version": "3.14.0"
17
17
  }
18
18
  ]
19
19
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "team-toon-tack",
3
3
  "description": "Linear/Trello task sync & management CLI for Claude Code - saves tokens vs MCP",
4
- "version": "3.12.0",
4
+ "version": "3.14.0",
5
5
  "author": {
6
6
  "name": "wayne930242",
7
7
  "email": "wayne930242@gmail.com"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "team-toon-tack",
3
- "version": "3.12.0",
3
+ "version": "3.14.0",
4
4
  "description": "透過 ttt CLI 同步與管理 Linear、Trello 任務。",
5
5
  "author": {
6
6
  "name": "wayne930242"
package/README.md CHANGED
@@ -9,6 +9,7 @@ Optimized task workflow for Claude Code — supports Linear and Trello, saves si
9
9
  - **Token Efficient** — Local cycle cache eliminates repeated API calls, saving significant tokens vs MCP
10
10
  - **Multi-source Support** — Works with both Linear and Trello
11
11
  - **Batch Ticket Claiming** — Claim one or many tickets at once with `ttt claim`, or auto-pick your highest priority pending tasks with `ttt claim next <n>`
12
+ - **Work Orders** — One file per train batch carries its tickets from claim to Done: `ttt claim --order`, then `ttt order close` completes the whole batch after the merge
12
13
  - **Multi-team Support** — Sync and filter issues across multiple teams/boards
13
14
  - **Flexible Sync Modes** — Choose between remote (immediate sync) or local (offline-first, sync later with `--update`)
14
15
  - **Completion Modes** — Four modes for task completion (Linear): simple, strict review, upstream strict, upstream not strict
@@ -156,6 +157,7 @@ ttt claim MP-123 MP-124 # Batch claim
156
157
  ttt claim next # Claim highest priority pending task
157
158
  ttt claim next 3 # Claim top 3 pending tasks
158
159
  ttt claim --dry-run # Preview without changes
160
+ ttt claim MP-123 --order auto --project app # Also record it in the project's open work order
159
161
  ```
160
162
 
161
163
  Completed, in-review, and blocked tickets are reported and skipped without
@@ -168,6 +170,11 @@ that a full `ttt sync` rewrites local data from the current cycle, so a stored
168
170
  ticket outside it drops out on the next sync (`ttt done <id> --from-remote`
169
171
  still completes it).
170
172
 
173
+ `--order <id|auto>` also records the claimed tickets in a [work order](#ttt-order).
174
+ `auto` means the project's open order; when the last one was sealed, a new order `<project>/<YYYY-MM-DD>-<next letter>` is opened.
175
+ `--project <name>` names the project for `auto` (default: the directory that holds `.ttt`).
176
+ An order that cannot take the ticket (sealed, handed off, closed) refuses before anything is claimed.
177
+
171
178
  ### `ttt estimate`
172
179
 
173
180
  Save a local human-effort estimate that persists in `.ttt/cycle.toon`.
@@ -186,6 +193,7 @@ Mark task as completed.
186
193
  ```bash
187
194
  ttt done # Auto-select if only one in-progress
188
195
  ttt done MP-123 # Specific issue
196
+ ttt done MP-123 MP-124 -m "Merged in v1.2.0" # Several issues, one message
189
197
  ttt done -m "Fixed the bug" # With completion message
190
198
  ttt done MP-123 --from-remote # Fetch from remote (bypasses local data check)
191
199
  ttt done MP-123 --commit 1a2b3c4 # Record this commit instead of HEAD
@@ -196,6 +204,74 @@ Use `--from-remote` (or `-r`) when the issue exists in remote but not in local s
196
204
 
197
205
  Use `--commit <sha>` (and `--repo <path>` when the commit lives in another checkout) to close a ticket whose commit was merged earlier. Without it, the current HEAD is recorded.
198
206
 
207
+ With several IDs, `-m`, `--commit`, `--repo`, and `--from-remote` apply to every ticket.
208
+ Every ID must resolve first: one that is unknown or not in progress stops the run before any ticket moves.
209
+ Each ticket gets a result line, and one failing ticket does not stop the rest.
210
+ A ticket that is already done (or, under `strict_review`, already at the testing status) is reported and skipped, so a run can be repeated after a partial failure.
211
+ IDs repeated in another case count once.
212
+ The exit code is non-zero when any ticket failed.
213
+ To close a whole train batch after its merge, use a [work order](#ttt-order) instead.
214
+
215
+ ### `ttt order`
216
+
217
+ A work order is one TOON file per train batch.
218
+ It carries the batch's tickets from claim to Done, with each ticket's branch, MR, head, review verdict, and passed test runs in one place.
219
+ Use it when several tickets ride one integration branch and are closed together after its merge.
220
+
221
+ ```bash
222
+ # Coordinator (the one writer while tickets are being worked on)
223
+ ttt claim MP-1 MP-2 --order auto --project app # Claim into the project's open order
224
+ ttt order set app/2026-11-11-a MP-1 --branch feat/mp-1 --mr '!812' --head 1a2b3c4 \
225
+ --review "P0/P1=0" --tests "bun test scripts/x = pass"
226
+ ttt order review app/2026-11-11-a MP-1 MP-2 # Move to the testing status, keep the assignee
227
+ ttt order train app/2026-11-11-a --branch agent-train/2026-11-11-a --mr '!900'
228
+ ttt order seal app/2026-11-11-a --gated-head 5d6e7f8 # No more tickets
229
+ ttt order export app/2026-11-11-a --handoff # Paste the block into the train MR
230
+
231
+ # Integrator (the writer after the handoff)
232
+ glab mr view 900 | ttt order import - # Reads the block out of any text
233
+ ttt order close app/2026-11-11-a --merged 9a8b7c6 --version v1.2.0 --dry-run
234
+ ttt order close app/2026-11-11-a --merged 9a8b7c6 --version v1.2.0
235
+
236
+ # A ticket pulled out of the train keeps its history
237
+ ttt order return app/2026-11-11-a MP-2 --reason "waits for MP-9" > notice.md # Integrator
238
+ ttt order carry MP-2 --to auto --project app --text notice.md # Coordinator: into the next order
239
+
240
+ # A ticket fixed during integration
241
+ ttt order rework app/2026-11-11-a MP-1 --reason "gate red" # Back to in-progress; a sealed order reopens
242
+ ```
243
+
244
+ | Command | What it does |
245
+ |---------|--------------|
246
+ | `open [<project>/<code>] [--project p] [--reviewer r]` | Open an order. Without an id the code is `<YYYY-MM-DD>-<next letter>`. |
247
+ | `list [--project p] [--all]` | List orders; closed ones only with `--all`. |
248
+ | `show <id> [--toon]` | Show an order, or its stored TOON. |
249
+ | `set <id> <ticket> [--branch --mr --head --review --tests]` | Record what a worker reported. Each `--tests "<cmd> [@ <sha>] [= <result>]"` appends one run; the SHA defaults to the ticket's head and the result to `pass`. A review is bound to the head it was recorded on. |
250
+ | `review <id> <ticket>... [--status name]` | Move tickets to the testing status (`status_transitions.testing`, else `dev_testing_status`) and mark them in-review. |
251
+ | `train <id> [--branch b] [--mr mr]` | Record the train branch and its merge request. |
252
+ | `seal <id> --gated-head <sha>` | Fix the batch on the head the gate passed on. Every ticket must be in review, dropped, or returned. |
253
+ | `drop <id> <ticket> --reason <text>` | Leave a ticket out of the batch. Its remote status is not touched. |
254
+ | `rework <id> <ticket> --reason <text>` | Send an in-review ticket back to in-progress, in the order and at the source (assignee unchanged). A sealed order reopens and its gated head is cleared. |
255
+ | `return <id> <ticket>... --reason <text>` | Writer (normally the integrator): hand tickets back to the coordinator. Marks them returned, moves them to in-progress at the source, and prints a return notice block. Safe to repeat. |
256
+ | `carry <ticket>... --to <id\|auto> [--project p] [--from id \| --text file\|-]` | Coordinator: take tickets into another open order with branch, MR, head, review, and test runs, plus a `carried_from` record. |
257
+ | `export <id> [--handoff]` | Print the order as a fenced block. `--handoff` makes the local copy read-only. |
258
+ | `import <file\|-> [--id id] [--force] [--returns \| --order]` | Take the block from a file or stdin; the importer becomes the writer. A return notice is recorded on the local copy instead, without changing the writer. |
259
+ | `reclaim <id>` | Take a handed-off order back when it was returned without an export. |
260
+ | `close <id> --merged <sha> [--version v] [--dry-run]` | Complete every in-review ticket and comment on each. |
261
+
262
+ How an order behaves:
263
+
264
+ - **Storage.** Orders live in `.ttt/orders/<project>/<code>.toon` on the writer's machine and are never committed. Writes are atomic (temp file, then rename) and serialized by a lock per project. The default project is the directory that holds `.ttt`.
265
+ - **Stages.** `open` → `sealed` → `merged` → `closed`. A project holds one open order at a time. After the seal, `ttt claim --order auto` opens the next one. A ticket fixed inside its order goes through `rework`: the order is `open` again without a gated head, so record the new head with `set`, `review` it, and `seal` again.
266
+ - **Ticket states.** `in-progress`, `in-review`, `dropped`, `returned`, `done`. A dropped or returned ticket is never completed by `close`, does not block `seal` or `close`, and may be taken by another order.
267
+ - **Return and carry.** `return` keeps the ticket's record and adds who returned it, when, and why. The notice it prints (a fenced `toon ttt-return` block) holds the returned tickets' full records. The coordinator's `import` records it on its copy, even a handed-off one, and stays read-only; a text holding both an order block and a notice needs `--returns` or `--order`. `carry` reads the history from a local order (`--from`, else the newest order of the project that holds the ticket) or from a notice or order block in `--text`, and puts the ticket in progress in the destination (`auto`: the project's open order, opened if there is none). A source this machine writes marks the ticket dropped with reason `carried to <order>`. A ticket still held by a writer elsewhere (in progress or in review in a handed-off order) is refused until that writer returns it. `carry` does not change remote statuses.
268
+ - **Stale review.** The head a review was recorded on is stored as `review_head`. When `set --head` moves the head without a new `--review`, `show` marks the review `stale: reviewed <old>, head now <new>` and `seal` warns. Test runs keep the SHA they ran on. Orders written before this field existed are never marked.
269
+ - **One writer.** Workers report; the coordinator records. `export --handoff` passes the pen to the integrator, and write commands on the handed-off copy refuse with the way back: import the returned copy, or `reclaim`. An import never overwrites a writable local copy without `--force`, and never takes an older revision.
270
+ - **Close.** Each in-review ticket goes through the same completion handler as `ttt done`, so `completion_mode` and parent issues apply. Each gets one comment with its MR, the merge commit, the version, and the order id. Dropped and returned tickets are untouched. A ticket canceled at the source, or moved out of review since the seal, stops the close until it is dropped or sent back to review. Close requires the done status: a completion mode that leaves a ticket at testing (`strict_review`, or `upstream_strict` without a parent to take it) fails that ticket and keeps the order merged. A rerun skips what is already done and does not comment twice.
271
+ - **Identity.** The writer's name in `owner` and the log is `TTT_ACTOR`, else `<current_user>@<hostname>`.
272
+
273
+ A ticket rides one order per project at a time: claiming or carrying it into a second order of the same project, or having `review` adopt it there, is refused until it is dropped or returned from the first. `review` leaves a Done or Canceled ticket where it is.
274
+
199
275
  ### `ttt status`
200
276
 
201
277
  Show or modify task status.
@@ -236,6 +312,20 @@ Two options widen a `--remote` search beyond what `ttt sync` stores (both need
236
312
  it, because backlog tickets usually belong to no cycle. Trello has no cycles,
237
313
  so there it changes nothing.
238
314
 
315
+ ### `ttt skills` / `ttt skill`
316
+
317
+ Print the agent skill text bundled with this version of the CLI.
318
+ An agent setup installs only a short stub skill that says to run these commands, so the instructions an agent follows always match the installed `ttt`.
319
+
320
+ ```bash
321
+ ttt skills # Bundled skills, their pages, and the ttt version
322
+ ttt skill managing-linear-tasks # The skill; its header lists the pages
323
+ ttt skill managing-linear-tasks orders-coordinator # Work orders: the coordinator's side
324
+ ttt skill managing-linear-tasks orders-integrator # Work orders: the integrator's side
325
+ ```
326
+
327
+ The text lives in `bundled-skills/<name>/index.md` (plus one `<page>.md` per page) inside the package and is read from the installed package's directory, not the working directory.
328
+
239
329
  ### `ttt config`
240
330
 
241
331
  Configure settings.
@@ -257,6 +347,7 @@ your-project/
257
347
  ├── config.toon # Team config (gitignore recommended)
258
348
  ├── local.toon # Personal settings (gitignore)
259
349
  ├── cycle.toon # Current cycle data + local estimates (auto-generated)
350
+ ├── orders/ # Work orders: <project>/<code>.toon (never commit)
260
351
  └── output/ # Downloaded attachments (images, files)
261
352
  ```
262
353
 
@@ -268,6 +359,7 @@ your-project/
268
359
  | `TRELLO_API_KEY` | **Required for Trello.** Your Trello API key |
269
360
  | `TRELLO_TOKEN` | **Required for Trello.** Your Trello authorization token |
270
361
  | `TOON_DIR` | Config directory (default: `.ttt`) |
362
+ | `TTT_ACTOR` | Writer's name in work orders (default: `<current_user>@<hostname>`) |
271
363
 
272
364
  ### Trello Setup
273
365
 
@@ -302,13 +394,14 @@ Install the plugin for Claude Code integration:
302
394
  | `/ttt:sync` | Sync issues to local cycle data |
303
395
  | `/ttt:work-on` | Claim ticket(s) and work on them |
304
396
  | `/ttt:estimate` | Save a local human-effort estimate |
305
- | `/ttt:done` | Mark current task as completed |
397
+ | `/ttt:done` | Mark one or more tasks as completed |
398
+ | `/ttt:order` | Work orders: carry a train batch from claim to Done |
306
399
  | `/ttt:status` | Show or modify task status |
307
400
  | `/ttt:show` | Show issue details or search issues |
308
401
 
309
402
  ### Auto-Activated Skill
310
403
 
311
- The plugin includes a `managing-linear-tasks` skill that automatically activates when working with tasks, providing workflow guidance and best practices.
404
+ The plugin includes a `managing-linear-tasks` skill that automatically activates when working with tasks. It is a stub: it tells the agent to run `ttt skill managing-linear-tasks`, which prints the full instructions bundled with the installed CLI (see [`ttt skills`](#ttt-skills--ttt-skill)).
312
405
 
313
406
  ## License
314
407
 
package/README.zh-TW.md CHANGED
@@ -9,6 +9,7 @@
9
9
  - **節省 Token** — 本地 cycle 快取避免重複 API 呼叫,比 MCP 省下大量 token
10
10
  - **多來源支援** — 支援 Linear 和 Trello
11
11
  - **批次領票** — `ttt claim` 可一次領一張或多張票,`ttt claim next <n>` 自動領取最高優先級的待辦任務
12
+ - **工單** — 一個列車批次一份檔案,把這批票從領票帶到 Done:`ttt claim --order` 領票入單,合併後 `ttt order close` 一次完成整批
12
13
  - **多團隊支援** — 跨多個團隊/看板同步與過濾 issue
13
14
  - **彈性同步模式** — 選擇 remote(即時同步)或 local(離線優先,稍後用 `--update` 同步)
14
15
  - **完成模式** — 四種任務完成模式(Linear):簡單、嚴格審查、上下游嚴格、上下游非嚴格
@@ -156,6 +157,7 @@ ttt claim MP-123 MP-124 # 批次領票
156
157
  ttt claim next # 領最高優先級的待辦任務
157
158
  ttt claim next 3 # 領最高優先級的前 3 張票
158
159
  ttt claim --dry-run # 預覽,不改狀態
160
+ ttt claim MP-123 --order auto --project app # 同時記進該專案目前開著的工單
159
161
  ```
160
162
 
161
163
  已完成、審核中、blocked 的票會逐張回報並跳過,不中斷整批。
@@ -164,6 +166,11 @@ ttt claim --dry-run # 預覽,不改狀態
164
166
  已關閉(完成或取消)的票會回報並跳過。
165
167
  注意:完整的 `ttt sync` 會依目前 cycle 重寫本地資料,不在 cycle 內的票下次同步後會消失(仍可用 `ttt done <id> --from-remote` 完成)。
166
168
 
169
+ 加 `--order <id|auto>` 會把領到的票同時記進[工單](#ttt-order)。
170
+ `auto` 指該專案目前開著的工單;上一張已封單時,會開一張新的 `<project>/<YYYY-MM-DD>-<下一個字母>`。
171
+ `--project <name>` 指定 `auto` 用的專案(預設:`.ttt` 所在的目錄名稱)。
172
+ 工單無法收票時(已封單、已交接、已關閉),會在領任何票之前拒絕。
173
+
167
174
  ### `ttt estimate`
168
175
 
169
176
  把人類工程工時估算寫進 `.ttt/cycle.toon`,並在之後的同步中保留下來。
@@ -182,6 +189,7 @@ ttt estimate MP-123 --clear # 移除既有估時
182
189
  ```bash
183
190
  ttt done # 若只有一個進行中,自動選擇
184
191
  ttt done MP-123 # 指定 issue
192
+ ttt done MP-123 MP-124 -m "已隨 v1.2.0 合併" # 一次完成多張票,共用說明
185
193
  ttt done -m "修復了錯誤" # 附上完成說明
186
194
  ttt done MP-123 --from-remote # 從遠端取得(略過本地資料檢查)
187
195
  ttt done MP-123 --commit 1a2b3c4 # 記錄指定 commit,而非目前 HEAD
@@ -192,6 +200,72 @@ ttt done MP-123 --commit 1a2b3c4 --repo ~/projects/app # ...從另一個 repos
192
200
 
193
201
  要關閉 commit 早已合併的 ticket,用 `--commit <sha>`(commit 在另一個 checkout 時再加 `--repo <path>`)。未指定時記錄目前的 HEAD。
194
202
 
203
+ 一次給多個 ID 時,`-m`、`--commit`、`--repo`、`--from-remote` 套用到每一張票。
204
+ 每張票各有一行結果,其中一張失敗不會中斷其他票。
205
+ 已經完成的票只回報、不重做,所以部分失敗後可以原指令重跑。
206
+ 只要有一張失敗,結束碼就不是 0。
207
+ 整批列車合併後要一次關票,改用[工單](#ttt-order)。
208
+
209
+ ### `ttt order`
210
+
211
+ 工單(work order)是一個列車批次一份的 TOON 檔。
212
+ 它把這一批票從領票帶到 Done,每張票的分支、MR、head、審查結論與通過的測試紀錄都記在同一處。
213
+ 多張票搭同一條整合分支、合併後一起關票時使用。
214
+
215
+ ```bash
216
+ # 協調者(票還在做的期間,唯一的寫入者)
217
+ ttt claim MP-1 MP-2 --order auto --project app # 領票並寫進該專案目前開著的工單
218
+ ttt order set app/2026-11-11-a MP-1 --branch feat/mp-1 --mr '!812' --head 1a2b3c4 \
219
+ --review "P0/P1=0" --tests "bun test scripts/x = pass"
220
+ ttt order review app/2026-11-11-a MP-1 MP-2 # 改到測試狀態,指派人不變
221
+ ttt order train app/2026-11-11-a --branch agent-train/2026-11-11-a --mr '!900'
222
+ ttt order seal app/2026-11-11-a --gated-head 5d6e7f8 # 封單,不再收票
223
+ ttt order export app/2026-11-11-a --handoff # 把輸出的區塊貼進列車 MR
224
+
225
+ # 整合者(交接後的寫入者)
226
+ glab mr view 900 | ttt order import - # 從任何文字中取出工單區塊
227
+ ttt order close app/2026-11-11-a --merged 9a8b7c6 --version v1.2.0 --dry-run
228
+ ttt order close app/2026-11-11-a --merged 9a8b7c6 --version v1.2.0
229
+
230
+ # 從列車拉下來的票,紀錄跟著走
231
+ ttt order return app/2026-11-11-a MP-2 --reason "等 MP-9" > notice.md # 整合者
232
+ ttt order carry MP-2 --to auto --project app --text notice.md # 協調者:帶進下一張工單
233
+
234
+ # 整合期間要修的票
235
+ ttt order rework app/2026-11-11-a MP-1 --reason "gate 紅燈" # 退回 in-progress;已封的工單重新打開
236
+ ```
237
+
238
+ | 指令 | 作用 |
239
+ |------|------|
240
+ | `open [<project>/<code>] [--project p] [--reviewer r]` | 開工單。不給 id 時,代碼為 `<YYYY-MM-DD>-<下一個字母>`。 |
241
+ | `list [--project p] [--all]` | 列出工單;加 `--all` 才列已關閉的。 |
242
+ | `show <id> [--toon]` | 顯示工單,或印出儲存的 TOON。 |
243
+ | `set <id> <ticket> [--branch --mr --head --review --tests]` | 記錄 worker 回報的內容。每個 `--tests "<指令> [@ <sha>] [= <結果>]"` 追加一筆測試紀錄;SHA 預設為該票的 head,結果預設為 `pass`。審查結論綁定記錄當下的 head。 |
244
+ | `review <id> <ticket>... [--status name]` | 把票改到測試狀態(`status_transitions.testing`,沒有則用 `dev_testing_status`),並在工單標為 in-review。 |
245
+ | `train <id> [--branch b] [--mr mr]` | 記錄列車分支與它的 MR。 |
246
+ | `seal <id> --gated-head <sha>` | 以通過 gate 的 head 封單。每張票都必須已送審、已剔除或已退回。 |
247
+ | `drop <id> <ticket> --reason <text>` | 把票從這一批剔除,遠端狀態不動。 |
248
+ | `rework <id> <ticket> --reason <text>` | 把送審中的票退回 in-progress,工單與遠端一起改,指派人不變。已封的工單會重新打開,並清掉 gated head。 |
249
+ | `return <id> <ticket>... --reason <text>` | 寫入者(通常是整合者)把票退回給協調者:標為 returned、遠端改回 in-progress,並印出退回通知區塊。可重複執行。 |
250
+ | `carry <ticket>... --to <id\|auto> [--project p] [--from id \| --text file\|-]` | 協調者把票帶進另一張開著的工單,分支、MR、head、審查結論與測試紀錄一併帶過去,並記下 `carried_from`。 |
251
+ | `export <id> [--handoff]` | 把工單印成一個 fenced 區塊。加 `--handoff` 後本機這份改為唯讀。 |
252
+ | `import <file\|-> [--id id] [--force] [--returns \| --order]` | 從檔案或 stdin 取出區塊;匯入者成為寫入者。若是退回通知,只記到本機那份工單上,寫入者不變。 |
253
+ | `reclaim <id>` | 對方退回但沒有匯出時,把已交接的工單收回。 |
254
+ | `close <id> --merged <sha> [--version v] [--dry-run]` | 完成每張送審中的票,並各留一則留言。 |
255
+
256
+ 工單的規則:
257
+
258
+ - **儲存。** 工單存在寫入者機器上的 `.ttt/orders/<project>/<code>.toon`,不進版控。寫入先寫暫存檔再改名,並以每個專案一把鎖排隊。預設專案是 `.ttt` 所在的目錄名稱。
259
+ - **階段。** `open` → `sealed` → `merged` → `closed`。一個專案同時只有一張開著的工單。封單之後,`ttt claim --order auto` 會開下一張。要在原工單內修的票用 `rework`:工單回到 `open`、gated head 清空,接著用 `set` 記下新的 head、`review` 送審,再 `seal` 一次。
260
+ - **票的狀態。** `in-progress`、`in-review`、`dropped`、`returned`、`done`。已剔除或已退回的票不會被 `close` 完成,不會擋住 `seal` 與 `close`,也可以被另一張工單收走。
261
+ - **退回與帶票。** `return` 保留票的紀錄,並記下誰退回、何時、原因。它印出的通知(`toon ttt-return` fenced 區塊)帶著這些票的完整紀錄。協調者 `import` 這份通知時,只記到自己那份工單上,已交接的那份也收,而且維持唯讀;文字裡同時有工單區塊與通知時,要用 `--returns` 或 `--order` 指定。`carry` 的紀錄來源是本機的工單(`--from`,沒給就找該專案最新一張含這張票的工單),或 `--text` 裡的通知或工單區塊;票進到目的工單時是 in-progress(`auto` 指該專案開著的工單,沒有就開一張)。來源工單若由本機寫入,票會標為剔除,原因是 `carried to <order>`。別處的寫入者還握著的票(在已交接的工單裡仍是 in-progress 或 in-review)會被拒絕,要等對方退回。`carry` 不改遠端狀態。
262
+ - **審查過期。** 記錄審查結論時的 head 存在 `review_head`。之後 `set --head` 換了 head 卻沒有新的 `--review`,`show` 會標出 `stale: reviewed <舊>, head now <新>`,`seal` 也會警告。測試紀錄維持各自執行時的 SHA。在這個欄位出現之前寫的工單不會被標記。
263
+ - **單一寫入者。** Worker 回報,協調者記錄。`export --handoff` 把寫入權交給整合者;之後在已交接的那份上執行寫入指令會被拒絕,訊息會說明怎麼拿回來:匯入對方退回的版本,或執行 `reclaim`。匯入時,本機那份若仍可寫,沒有 `--force` 不會被覆蓋;版本比本機舊的也不會被接受。
264
+ - **關單。** 每張送審中的票走與 `ttt done` 相同的完成流程,所以 `completion_mode` 與上層 issue 的規則照常套用。每張票各有一則留言,寫明它的 MR、合併 commit、版本與工單 id。已剔除與已退回的票不動。遠端已取消的票會讓關單停下,剔除後才能繼續。重跑時,已完成的票會跳過,留言不會重複。
265
+ - **身分。** `owner` 與紀錄中的寫入者名稱取自 `TTT_ACTOR`,未設定時為 `<current_user>@<hostname>`。
266
+
267
+ 一張票同一時間只搭一張工單:要領進或帶進第二張工單,必須先從第一張剔除或退回。
268
+
195
269
  ### `ttt status`
196
270
 
197
271
  顯示或修改任務狀態。
@@ -228,6 +302,20 @@ ttt show --remote --any-cycle --creator me # 我建立、不限 cycle 的
228
302
  - `--any-cycle`:不限目前 cycle。`--status Backlog` 會自動帶上它,因為 Backlog 票通常不屬於任何 cycle。
229
303
  Trello 沒有 cycle,所以在 Trello 上沒有作用。
230
304
 
305
+ ### `ttt skills` / `ttt skill`
306
+
307
+ 印出隨這個版本的 CLI 一起安裝的 agent 技能說明。
308
+ Agent 那邊只裝一份短的引導技能,內容是要它執行這兩個指令,所以 agent 照著做的說明一定和裝著的 `ttt` 同一版。
309
+
310
+ ```bash
311
+ ttt skills # 內建的技能、各自的分頁與 ttt 版本
312
+ ttt skill managing-linear-tasks # 印出技能;開頭列出有哪些分頁
313
+ ttt skill managing-linear-tasks orders-coordinator # 工單:協調者這一側
314
+ ttt skill managing-linear-tasks orders-integrator # 工單:整合者這一側
315
+ ```
316
+
317
+ 說明文字放在套件裡的 `bundled-skills/<name>/index.md`(每個分頁另有一份 `<page>.md`),讀取時以安裝的套件目錄為準,與目前所在的目錄無關。
318
+
231
319
  ### `ttt config`
232
320
 
233
321
  配置設定。
@@ -249,6 +337,7 @@ your-project/
249
337
  ├── config.toon # 團隊配置(建議 gitignore)
250
338
  ├── local.toon # 個人設定(gitignore)
251
339
  ├── cycle.toon # 當前 cycle 資料與本地估時(自動產生)
340
+ ├── orders/ # 工單:<project>/<code>.toon(不要 commit)
252
341
  └── output/ # 下載的附件(圖片、檔案)
253
342
  ```
254
343
 
@@ -260,6 +349,7 @@ your-project/
260
349
  | `TRELLO_API_KEY` | **Trello 必填**。你的 Trello API 金鑰 |
261
350
  | `TRELLO_TOKEN` | **Trello 必填**。你的 Trello 授權 token |
262
351
  | `TOON_DIR` | 配置目錄(預設:`.ttt`) |
352
+ | `TTT_ACTOR` | 工單中的寫入者名稱(預設:`<current_user>@<hostname>`) |
263
353
 
264
354
  ### Trello 設定
265
355
 
@@ -294,13 +384,14 @@ your-project/
294
384
  | `/ttt:sync` | 同步 issue 到本地 |
295
385
  | `/ttt:work-on` | 領票並開始處理 |
296
386
  | `/ttt:estimate` | 寫入本地人力估時 |
297
- | `/ttt:done` | 標記當前任務完成 |
387
+ | `/ttt:done` | 標記一張或多張任務完成 |
388
+ | `/ttt:order` | 工單:把一批列車的票從領票帶到 Done |
298
389
  | `/ttt:status` | 顯示或修改任務狀態 |
299
390
  | `/ttt:show` | 顯示 issue 詳情或搜尋 issue |
300
391
 
301
392
  ### 自動啟用技能
302
393
 
303
- Plugin 包含 `managing-linear-tasks` 技能,在處理任務時會自動啟用,提供工作流程指導和最佳實踐。
394
+ Plugin 包含 `managing-linear-tasks` 技能,在處理任務時會自動啟用。它只是一份短的引導:要 agent 執行 `ttt skill managing-linear-tasks`,印出隨 CLI 一起安裝的完整說明(見 [`ttt skills`](#ttt-skills--ttt-skill))。
304
395
 
305
396
  ## 授權
306
397
 
@@ -0,0 +1,186 @@
1
+ ---
2
+ name: managing-linear-tasks
3
+ description: Drive Linear/Trello task work through the ttt CLI (sync, claim, record, complete) and carry a train batch of tickets in a work order.
4
+ ---
5
+
6
+ ## 執行方式
7
+
8
+ 在 Codex 與 Claude Code 中,使用可用的 shell 工具執行 `ttt` CLI。
9
+ 任務資料以 CLI 的查詢結果為準;透過 CLI 更新 `.ttt/` 內的設定與狀態。
10
+ 使用者要求完成任務時,執行 `ttt done -m "摘要"`。
11
+ Claude Code 也提供 `/ttt:*` slash commands,對應下方相同的 CLI 操作。
12
+
13
+
14
+ # Task Manager (Linear/Trello)
15
+
16
+ Manage developer task workflows using the `ttt` CLI.
17
+
18
+ ## Command Router
19
+
20
+ 依使用者意圖選擇下列 `ttt` CLI 指令:
21
+
22
+ | User Intent | Command | Example |
23
+ |-------------|---------|---------|
24
+ | Sync/fetch issues | `ttt sync` | "sync my issues", "pull from Linear" |
25
+ | Show/search issues | `ttt show` | "show MP-624", "list my tasks", "what issues do I have" |
26
+ | Claim ticket(s) → in-progress | `ttt claim` | "領票", "work on next", "start MP-624", "claim MP-624 MP-625" |
27
+ | Create a new issue | `ttt create` | "create issue", "open a ticket", "new task" |
28
+ | Reassign an issue | `ttt assign` | "assign MP-624 to john", "reassign to jane" |
29
+ | Edit issue fields | `ttt edit` | "rename MP-624", "change priority", "update labels" |
30
+ | Cancel an issue | `ttt cancel` | "cancel MP-624", "abandon this task" |
31
+ | Record an estimate | `ttt estimate` | "estimate MP-624 as 6h", "save 2.5h estimate" |
32
+ | Check/change status | `ttt status` | "what's my current task", "set MP-624 to blocked" |
33
+ | Add a comment | `ttt comment` | "comment on MP-624", "add note to task" |
34
+ | Complete task(s) | `ttt done` | "done", "mark complete", "finish task", "close MP-624 MP-625" |
35
+ | Track a train batch | `ttt order` | "開工單", "seal the order", "hand off the train", "close the batch after merge" |
36
+
37
+ **意圖符合時,透過 shell 工具執行對應的 `ttt` CLI 指令。**
38
+
39
+ ## Quick Reference
40
+
41
+ ```bash
42
+ ttt sync # Sync Todo/In Progress issues
43
+ ttt sync --all # Sync all statuses
44
+ ttt sync MP-624 # Sync specific issue
45
+ ttt show # List all local issues
46
+ ttt show MP-624 # Show issue details
47
+ ttt show --user me # My issues
48
+ ttt show --remote --status Backlog --creator me # Backlog tickets I created (any cycle)
49
+ ttt show --remote --status Backlog --user me # Backlog tickets assigned to me
50
+ ttt claim next # Claim highest priority pending task
51
+ ttt claim next 3 # Claim top 3 pending tasks
52
+ ttt claim MP-624 MP-625 # Batch claim (alias: ttt work-on)
53
+ ttt claim MP-700 # Not in local data (e.g. Backlog)? Fetched from remote, then claimed
54
+ ttt create # Create new issue (interactive)
55
+ ttt create -t "Title" -p 2 # Quick create with flags
56
+ ttt assign MP-624 -a john # Reassign issue
57
+ ttt edit MP-624 -t "New" # Edit title (or -d/-p/-l)
58
+ ttt cancel MP-624 # Cancel an issue
59
+ ttt estimate MP-624 6 # Save a 6-hour human estimate
60
+ ttt status # Current in-progress task
61
+ ttt status MP-624 --set +1 # Advance status
62
+ ttt comment MP-624 -m "msg" # Add comment to issue
63
+ ttt comment -m "msg" # Comment on current task
64
+ ttt done -m "summary" # Complete with message
65
+ ttt done MP-624 --commit <sha> [--repo <path>] # Close a ticket with an earlier commit
66
+ ttt done MP-624 --from-remote # Complete a Todo ticket without claiming it first
67
+ ttt done MP-624 MP-625 -m "summary" # Complete several tickets; done ones are skipped, exit non-zero if any failed
68
+ ttt claim MP-624 --order auto --project app # Claim into the project's open work order
69
+ ttt order close app/2026-11-11-a --merged <sha> --version v1.2.0 # After the merge: whole batch → Done
70
+ ttt skills # Skills bundled with this ttt version; print one with: ttt skill <name> [page]
71
+ ```
72
+
73
+ ## Prerequisites
74
+
75
+ - **Linear**: `LINEAR_API_KEY` env var set
76
+ - **Trello**: `TRELLO_API_KEY` + `TRELLO_TOKEN` env vars set
77
+ - `.ttt/` directory initialized (`ttt init`)
78
+
79
+ ## Standard Workflow
80
+
81
+ ```
82
+ ttt sync → ttt claim next → ttt estimate <id> <hours> → [implement] → git commit → ttt comment -m "notes" → ttt done -m "..."
83
+ ```
84
+
85
+ ## Batch Work on a Train (Work Order)
86
+
87
+ When several tickets ride one integration branch and close together after its merge, claim them with `--order` and skip the per-ticket `ttt done`: closing a ticket before its train merged reports work as done that is not on the integration branch yet.
88
+ One side writes the order at a time, so workers report and the coordinator records.
89
+
90
+ Before working an order, print the page for your side and follow it:
91
+
92
+ - `ttt skill managing-linear-tasks orders-coordinator`: you claim tickets, record worker reports, and build the train.
93
+ - `ttt skill managing-linear-tasks orders-integrator`: you receive the train, merge it, and close its tickets.
94
+
95
+ ```
96
+ Coordinator: ttt claim <ids> --order auto --project <p>
97
+ ttt order set <order> <id> --branch --mr --head --review --tests (per worker report)
98
+ ttt order review <order> <ids> → testing status, assignee kept
99
+ ttt order train <order> --branch --mr
100
+ ttt order seal <order> --gated-head <sha> → no more tickets; the next claim opens a new order
101
+ ttt order export <order> --handoff → block into the train MR; local copy read-only
102
+ Integrator: ttt order import <file|-> → becomes the writer
103
+ ttt order return <order> <ids> --reason → tickets leave the train; notice block to the coordinator
104
+ ttt order close <order> --merged <sha> [--version v] [--dry-run]
105
+ Coordinator: ttt order carry <ids> --to auto --project <p> --text <notice> → next order, history kept
106
+ Writer: ttt order rework <order> <id> --reason → in-review back to in-progress; a sealed order reopens
107
+ ```
108
+
109
+ `ttt order close` runs each in-review ticket through the configured completion mode, comments MR, merge commit, version, and order id on it, and is safe to rerun after a failure.
110
+ Dropped and returned tickets are never completed and do not keep the order open.
111
+ `ttt order --help` lists every command.
112
+
113
+ ## File Structure
114
+
115
+ ```
116
+ .ttt/
117
+ ├── config.toon # Team configuration
118
+ ├── local.toon # Personal settings
119
+ ├── cycle.toon # Current cycle tasks + local estimates (auto-generated)
120
+ ├── orders/ # Work orders: <project>/<code>.toon (never commit, never edit by hand)
121
+ └── output/ # Downloaded attachments
122
+ ```
123
+
124
+ ## Troubleshooting
125
+
126
+ | Problem | Solution |
127
+ |---------|----------|
128
+ | No cycle data | `ttt sync` |
129
+ | Issue not found locally | `ttt show <id> --remote` or `ttt sync <id>` (`ttt status` auto-fetches from remote) |
130
+ | API key not set | Set `LINEAR_API_KEY` or `TRELLO_API_KEY` + `TRELLO_TOKEN` |
131
+ | Stale data | `ttt sync` to refresh |
132
+ | Order is read-only (handed off) | Import the returned copy, or `ttt order reclaim <order>`; a return notice imports without either |
133
+ | Ticket pulled out of a train | Integrator: `ttt order return`; coordinator: `ttt order carry ... --text <notice>` (keeps branch, MR, head, review, tests) |
134
+ | Ticket in review needs a fix | `ttt order rework <order> <id> --reason ...`, then `set`, `review`, and `seal` again |
135
+ | Order takes no more tickets (sealed) | `ttt claim <id> --order auto` opens the next order |
136
+
137
+ ## Common Rationalizations
138
+
139
+ | Excuse | Reality |
140
+ |--------|---------|
141
+ | "I'll edit `cycle.toon` directly, faster" | `cycle.toon` is auto-generated. Manual edits get overwritten on next `ttt sync`. Always go through the CLI. |
142
+ | "I remember this issue ID, no need to sync" | Remote status, assignee, priority may have changed. Run `ttt sync` or `ttt show <id> --remote` first. |
143
+ | "I'll create the issue in the Linear/Trello UI instead" | Bypassing `ttt create` leaves the new issue outside local cycle data. Use the CLI so it gets tracked. |
144
+ | "The MR is open, so I'll `ttt done` each train ticket now" | The ticket is done when its train merges. Record it in the order (`ttt order review`) and let `ttt order close` complete the batch. |
145
+ | "It left the train, I'll just `ttt claim --order auto` it again" | A fresh claim starts an empty record: branch, MR, head, review, and test runs are lost. `ttt order carry` takes them along. |
146
+ | "Task is obvious, skip `ttt done`" | `ttt done` syncs local + remote status, posts a completion comment, reads git commit info. Skipping leaves state inconsistent. |
147
+ | "I know what the task needs without reading it" | Fabricated assumptions produce wrong work. Run `ttt show <id>` before starting. |
148
+ | "Fetch issue details via Linear MCP / web UI" | The CLI is authoritative and token-efficient. Use `ttt show` / `ttt sync`, not alternate data paths. |
149
+
150
+ ## Flowchart — Intent Routing
151
+
152
+ ```dot
153
+ digraph ttt_router {
154
+ rankdir=LR;
155
+
156
+ user [label="User mentions\nLinear/Trello", shape=doublecircle];
157
+ classify [label="Classify intent", shape=diamond];
158
+
159
+ sync [label="ttt sync", shape=box];
160
+ show [label="ttt show", shape=box];
161
+ claim [label="ttt claim", shape=box];
162
+ create [label="ttt create", shape=box];
163
+ assign [label="ttt assign", shape=box];
164
+ edit [label="ttt edit", shape=box];
165
+ cancel [label="ttt cancel", shape=box];
166
+ estimate [label="ttt estimate", shape=box];
167
+ status [label="ttt status", shape=box];
168
+ comment [label="ttt comment", shape=box];
169
+ done [label="ttt done", shape=box];
170
+ order [label="ttt order", shape=box];
171
+
172
+ user -> classify;
173
+ classify -> sync [label="fetch / pull"];
174
+ classify -> show [label="show / list"];
175
+ classify -> claim [label="claim / start / next"];
176
+ classify -> create [label="create / new"];
177
+ classify -> assign [label="assign / reassign"];
178
+ classify -> edit [label="rename / change field"];
179
+ classify -> cancel [label="cancel / abandon"];
180
+ classify -> estimate [label="estimate / Nh"];
181
+ classify -> status [label="current / set status"];
182
+ classify -> comment [label="comment / note"];
183
+ classify -> done [label="done / complete"];
184
+ classify -> order [label="train batch / work order"];
185
+ }
186
+ ```
@@ -0,0 +1,53 @@
1
+ ---
2
+ description: Coordinator's side of a work order (claim, record worker reports, review, seal, hand off, carry returned tickets on).
3
+ ---
4
+
5
+ # Work orders: coordinator
6
+
7
+ You claim tickets, dispatch workers, and build the train.
8
+ The work order is the batch's record from claim to Done: one order per train, one writer at a time.
9
+ You write it until `export --handoff`; from then on the integrator does.
10
+ Workers never write it: they report, you record.
11
+
12
+ Order ids are `<project>/<code>`.
13
+ Use the repository's directory name as the project and pass `--project <repo dir name>` with every `auto`, because one `.ttt` can serve several repositories.
14
+ From a checkout that has no `.ttt` above it (a worktree outside the project), add `--dir <project checkout>/.ttt`.
15
+
16
+ ## Per ticket
17
+
18
+ 1. Claim before dispatch: `ttt claim <ticket> --order auto --project <repo dir name>`. `auto` is the project's open order; after a seal it opens the next one.
19
+ 2. When the worker reports, record it: `ttt order set <order> <ticket> --branch <b> --mr <!n> --head <sha> --review "<verdict>"`, plus one `--tests "<command with filter> @ <sha> = <result>"` per run. The train and the integrator reuse recorded runs instead of running them again.
20
+ 3. When its merge request is open and its review is clean: `ttt order review <order> <ticket>` moves it to the testing status and keeps the assignee.
21
+ 4. A ticket that rides a train is Done when the train merges: the integrator's `ttt order close` completes the whole order then. `ttt done` on it earlier reports work that is not on the integration branch.
22
+
23
+ A review is bound to the head it was recorded on.
24
+ When the head moves afterwards, `show` marks it `stale: reviewed <old>, head now <new>`: get the new head reviewed and record the verdict with `set --review`, or the integrator receives a stale review.
25
+
26
+ ## Tickets that leave the batch
27
+
28
+ | Situation | Do |
29
+ |-----------|----|
30
+ | Not ready for this train, rides the next | `ttt order drop <order> <ticket> --reason "next train"`, seal, then `ttt order carry <ticket> --to auto --project <p> --from <order>` |
31
+ | Its work failed for good | `ttt order drop <order> <ticket> --reason "<failure>"`, then hand the ticket back by your project's rule (status, assignee, comment) |
32
+ | It broke the train's gate and its worker is fixing it | `ttt order rework <order> <ticket> --reason "<gate>"`; when fixed, `set` the new head, review, and tests, then `review` it again |
33
+ | The integrator pulled it out and sent a return notice | `ttt order carry <ticket> --to auto --project <p> --text <notice file or ->` |
34
+
35
+ `carry` keeps branch, MR, head, review, and test runs and records `carried_from`; it does not touch the ticket's status at the source.
36
+ `ttt claim --order auto` on a ticket that left an order starts an empty record, so use it only when there is no history to keep.
37
+ `carry` refuses a ticket its source's writer still holds (in progress or in review in a handed-off order): the writer returns it first.
38
+
39
+ `rework` puts the ticket in progress in the order and at the source, with the assignee unchanged.
40
+ On a sealed order it also reopens the order and clears the gated head, because the gate no longer covers the batch: gate the new head and seal again.
41
+
42
+ ## Train and handoff
43
+
44
+ 1. Link the train: `ttt order train <order> --branch <train branch> --mr <!n>`. A train rebuilt under a new name is recorded the same way; the order's code need not match the train's name.
45
+ 2. When the train's closing gate is green, seal on the gated head: `ttt order seal <order> --gated-head <sha>`. Every ticket must be in review, dropped, or returned, so first drop the ones still in progress (first row above). Seal warns about each stale review.
46
+ 3. `ttt order export <order> --handoff`, and put the printed block in the train's merge request description under `Work order`. Your copy is read-only from here.
47
+
48
+ ## After the handoff
49
+
50
+ - **A return notice** (a `toon ttt-return` block from the integrator): `ttt order carry <tickets> --to auto --project <p> --text <file|->` takes the tickets on and records the notice on your copy. To record it without carrying: `ttt order import <file|->`. A text that holds both the order block and a notice needs `--returns`.
51
+ - **The whole train comes back**: `ttt order import <file|->` of the integrator's `export --handoff` block makes you the writer again; when no block came back, `ttt order reclaim <order>`. Then `rework` the tickets that need fixing, record the fixes, seal with the new gated head, and export again.
52
+
53
+ `ttt order show <order>` prints every ticket's state and history and the order's log; `ttt order --help` lists every command.