team-toon-tack 3.11.0 → 3.13.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 +89 -2
  5. package/README.zh-TW.md +79 -2
  6. package/commands/ttt-done.md +15 -4
  7. package/commands/ttt-order.md +134 -0
  8. package/commands/ttt-show.md +17 -0
  9. package/commands/ttt-work-on.md +29 -4
  10. package/dist/bin/cli.js +9 -0
  11. package/dist/scripts/claim.js +130 -15
  12. package/dist/scripts/done-job.d.ts +0 -4
  13. package/dist/scripts/done-job.js +209 -103
  14. package/dist/scripts/lib/adapters/linear-adapter.js +20 -1
  15. package/dist/scripts/lib/adapters/trello-adapter.js +3 -0
  16. package/dist/scripts/lib/adapters/types.d.ts +9 -0
  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 +74 -0
  28. package/dist/scripts/lib/order/model.js +452 -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 +49 -0
  32. package/dist/scripts/lib/order/store.js +299 -0
  33. package/dist/scripts/lib/order/transfer.d.ts +8 -0
  34. package/dist/scripts/lib/order/transfer.js +54 -0
  35. package/dist/scripts/lib/order/types.d.ts +70 -0
  36. package/dist/scripts/lib/order/types.js +18 -0
  37. package/dist/scripts/lib/remote-task.d.ts +4 -0
  38. package/dist/scripts/lib/remote-task.js +30 -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 +493 -0
  42. package/dist/scripts/show.js +87 -34
  43. package/dist/scripts/test-support/linear-mock.d.ts +1 -0
  44. package/dist/scripts/test-support/linear-mock.js +192 -0
  45. package/dist/scripts/test-support/linear-workspace.d.ts +44 -0
  46. package/dist/scripts/test-support/linear-workspace.js +133 -0
  47. package/package.json +1 -1
  48. package/skills/managing-linear-tasks/SKILL.md +36 -2
@@ -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.11.0"
16
+ "version": "3.13.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.11.0",
4
+ "version": "3.13.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.11.0",
3
+ "version": "3.13.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,10 +157,23 @@ 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
162
- stopping the rest of the batch. An unknown ID aborts before anything is claimed.
164
+ stopping the rest of the batch. An ID that local data does not hold (for example
165
+ a Backlog ticket outside the cycle) is fetched from the source, stored locally,
166
+ and claimed like any other; with `--dry-run` it is shown but not stored. An ID
167
+ found neither locally nor at the source aborts before anything is claimed.
168
+ A ticket that is already closed (done or canceled) is reported and skipped. Note
169
+ that a full `ttt sync` rewrites local data from the current cycle, so a stored
170
+ ticket outside it drops out on the next sync (`ttt done <id> --from-remote`
171
+ still completes it).
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.
163
177
 
164
178
  ### `ttt estimate`
165
179
 
@@ -179,6 +193,7 @@ Mark task as completed.
179
193
  ```bash
180
194
  ttt done # Auto-select if only one in-progress
181
195
  ttt done MP-123 # Specific issue
196
+ ttt done MP-123 MP-124 -m "Merged in v1.2.0" # Several issues, one message
182
197
  ttt done -m "Fixed the bug" # With completion message
183
198
  ttt done MP-123 --from-remote # Fetch from remote (bypasses local data check)
184
199
  ttt done MP-123 --commit 1a2b3c4 # Record this commit instead of HEAD
@@ -189,6 +204,61 @@ Use `--from-remote` (or `-r`) when the issue exists in remote but not in local s
189
204
 
190
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.
191
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
+
237
+ | Command | What it does |
238
+ |---------|--------------|
239
+ | `open [<project>/<code>] [--project p] [--reviewer r]` | Open an order. Without an id the code is `<YYYY-MM-DD>-<next letter>`. |
240
+ | `list [--project p] [--all]` | List orders; closed ones only with `--all`. |
241
+ | `show <id> [--toon]` | Show an order, or its stored TOON. |
242
+ | `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`. |
243
+ | `review <id> <ticket>... [--status name]` | Move tickets to the testing status (`status_transitions.testing`, else `dev_testing_status`) and mark them in-review. |
244
+ | `train <id> [--branch b] [--mr mr]` | Record the train branch and its merge request. |
245
+ | `seal <id> --gated-head <sha>` | Fix the batch on the head the gate passed on. Every ticket must be in review or dropped. |
246
+ | `drop <id> <ticket> --reason <text>` | Leave a ticket out of the batch. Its remote status is not touched. |
247
+ | `export <id> [--handoff]` | Print the order as a fenced block. `--handoff` makes the local copy read-only. |
248
+ | `import <file\|-> [--id id] [--force]` | Take the block from a file or stdin; the importer becomes the writer. |
249
+ | `reclaim <id>` | Take a handed-off order back when it was returned without an export. |
250
+ | `close <id> --merged <sha> [--version v] [--dry-run]` | Complete every in-review ticket and comment on each. |
251
+
252
+ How an order behaves:
253
+
254
+ - **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`.
255
+ - **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, and a returned ticket is reworked inside its own order: record the new head with `set`, then `seal` again.
256
+ - **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.
257
+ - **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 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.
258
+ - **Identity.** The writer's name in `owner` and the log is `TTT_ACTOR`, else `<current_user>@<hostname>`.
259
+
260
+ A ticket rides one order per project at a time: claiming it into a second order of the same project, or having `review` adopt it there, is refused until it is dropped from the first. `review` leaves a Done or Canceled ticket where it is.
261
+
192
262
  ### `ttt status`
193
263
 
194
264
  Show or modify task status.
@@ -213,8 +283,22 @@ ttt show --label frontend # Filter by label
213
283
  ttt show --status "In Progress" --user me # My in-progress issues
214
284
  ttt show --priority 1 # Show urgent issues
215
285
  ttt show --export # Export as markdown
286
+ ttt show --remote --status Backlog --creator me # Backlog tickets I created
287
+ ttt show --remote --status Backlog --user me # Backlog tickets assigned to me
288
+ ttt show --remote --any-cycle --creator me # My tickets in any cycle
216
289
  ```
217
290
 
291
+ Two options widen a `--remote` search beyond what `ttt sync` stores (both need
292
+ `--remote`; otherwise the command fails instead of ignoring them):
293
+
294
+ - `--creator <me|email|name>` filters by who created the issue (Linear only;
295
+ Trello cards expose no creator, so it fails there). Without `--user`, the
296
+ assignee scope is lifted, so tickets you created for others or left
297
+ unassigned show up.
298
+ - `--any-cycle` searches outside the current cycle. `--status Backlog` implies
299
+ it, because backlog tickets usually belong to no cycle. Trello has no cycles,
300
+ so there it changes nothing.
301
+
218
302
  ### `ttt config`
219
303
 
220
304
  Configure settings.
@@ -236,6 +320,7 @@ your-project/
236
320
  ├── config.toon # Team config (gitignore recommended)
237
321
  ├── local.toon # Personal settings (gitignore)
238
322
  ├── cycle.toon # Current cycle data + local estimates (auto-generated)
323
+ ├── orders/ # Work orders: <project>/<code>.toon (never commit)
239
324
  └── output/ # Downloaded attachments (images, files)
240
325
  ```
241
326
 
@@ -247,6 +332,7 @@ your-project/
247
332
  | `TRELLO_API_KEY` | **Required for Trello.** Your Trello API key |
248
333
  | `TRELLO_TOKEN` | **Required for Trello.** Your Trello authorization token |
249
334
  | `TOON_DIR` | Config directory (default: `.ttt`) |
335
+ | `TTT_ACTOR` | Writer's name in work orders (default: `<current_user>@<hostname>`) |
250
336
 
251
337
  ### Trello Setup
252
338
 
@@ -281,7 +367,8 @@ Install the plugin for Claude Code integration:
281
367
  | `/ttt:sync` | Sync issues to local cycle data |
282
368
  | `/ttt:work-on` | Claim ticket(s) and work on them |
283
369
  | `/ttt:estimate` | Save a local human-effort estimate |
284
- | `/ttt:done` | Mark current task as completed |
370
+ | `/ttt:done` | Mark one or more tasks as completed |
371
+ | `/ttt:order` | Work orders: carry a train batch from claim to Done |
285
372
  | `/ttt:status` | Show or modify task status |
286
373
  | `/ttt:show` | Show issue details or search issues |
287
374
 
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,10 +157,19 @@ 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 的票會逐張回報並跳過,不中斷整批。
162
- 批次中出現不存在的 ID 時,整批在動任何票之前中止。
164
+ 本地資料沒有的 ID(例如不在 cycle 內的 Backlog 票)會從來源抓回、存進本地,再照一般流程領票;
165
+ 加 `--dry-run` 時只顯示、不存入。本地與來源都找不到的 ID,整批在動任何票之前中止。
166
+ 已關閉(完成或取消)的票會回報並跳過。
167
+ 注意:完整的 `ttt sync` 會依目前 cycle 重寫本地資料,不在 cycle 內的票下次同步後會消失(仍可用 `ttt done <id> --from-remote` 完成)。
168
+
169
+ 加 `--order <id|auto>` 會把領到的票同時記進[工單](#ttt-order)。
170
+ `auto` 指該專案目前開著的工單;上一張已封單時,會開一張新的 `<project>/<YYYY-MM-DD>-<下一個字母>`。
171
+ `--project <name>` 指定 `auto` 用的專案(預設:`.ttt` 所在的目錄名稱)。
172
+ 工單無法收票時(已封單、已交接、已關閉),會在領任何票之前拒絕。
163
173
 
164
174
  ### `ttt estimate`
165
175
 
@@ -179,6 +189,7 @@ ttt estimate MP-123 --clear # 移除既有估時
179
189
  ```bash
180
190
  ttt done # 若只有一個進行中,自動選擇
181
191
  ttt done MP-123 # 指定 issue
192
+ ttt done MP-123 MP-124 -m "已隨 v1.2.0 合併" # 一次完成多張票,共用說明
182
193
  ttt done -m "修復了錯誤" # 附上完成說明
183
194
  ttt done MP-123 --from-remote # 從遠端取得(略過本地資料檢查)
184
195
  ttt done MP-123 --commit 1a2b3c4 # 記錄指定 commit,而非目前 HEAD
@@ -189,6 +200,59 @@ ttt done MP-123 --commit 1a2b3c4 --repo ~/projects/app # ...從另一個 repos
189
200
 
190
201
  要關閉 commit 早已合併的 ticket,用 `--commit <sha>`(commit 在另一個 checkout 時再加 `--repo <path>`)。未指定時記錄目前的 HEAD。
191
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
+ | 指令 | 作用 |
232
+ |------|------|
233
+ | `open [<project>/<code>] [--project p] [--reviewer r]` | 開工單。不給 id 時,代碼為 `<YYYY-MM-DD>-<下一個字母>`。 |
234
+ | `list [--project p] [--all]` | 列出工單;加 `--all` 才列已關閉的。 |
235
+ | `show <id> [--toon]` | 顯示工單,或印出儲存的 TOON。 |
236
+ | `set <id> <ticket> [--branch --mr --head --review --tests]` | 記錄 worker 回報的內容。每個 `--tests "<指令> [@ <sha>] [= <結果>]"` 追加一筆測試紀錄;SHA 預設為該票的 head,結果預設為 `pass`。 |
237
+ | `review <id> <ticket>... [--status name]` | 把票改到測試狀態(`status_transitions.testing`,沒有則用 `dev_testing_status`),並在工單標為 in-review。 |
238
+ | `train <id> [--branch b] [--mr mr]` | 記錄列車分支與它的 MR。 |
239
+ | `seal <id> --gated-head <sha>` | 以通過 gate 的 head 封單。每張票都必須已送審或已剔除。 |
240
+ | `drop <id> <ticket> --reason <text>` | 把票從這一批剔除,遠端狀態不動。 |
241
+ | `export <id> [--handoff]` | 把工單印成一個 fenced 區塊。加 `--handoff` 後本機這份改為唯讀。 |
242
+ | `import <file\|-> [--id id] [--force]` | 從檔案或 stdin 取出區塊;匯入者成為寫入者。 |
243
+ | `reclaim <id>` | 對方退回但沒有匯出時,把已交接的工單收回。 |
244
+ | `close <id> --merged <sha> [--version v] [--dry-run]` | 完成每張送審中的票,並各留一則留言。 |
245
+
246
+ 工單的規則:
247
+
248
+ - **儲存。** 工單存在寫入者機器上的 `.ttt/orders/<project>/<code>.toon`,不進版控。寫入先寫暫存檔再改名,並以每個專案一把鎖排隊。預設專案是 `.ttt` 所在的目錄名稱。
249
+ - **階段。** `open` → `sealed` → `merged` → `closed`。一個專案同時只有一張開著的工單。封單之後,`ttt claim --order auto` 會開下一張;被退回的票留在原工單重做:用 `set` 記下新的 head,再 `seal` 一次。
250
+ - **單一寫入者。** Worker 回報,協調者記錄。`export --handoff` 把寫入權交給整合者;之後在已交接的那份上執行寫入指令會被拒絕,訊息會說明怎麼拿回來:匯入對方退回的版本,或執行 `reclaim`。匯入時,本機那份若仍可寫,沒有 `--force` 不會被覆蓋;版本比本機舊的也不會被接受。
251
+ - **關單。** 每張送審中的票走與 `ttt done` 相同的完成流程,所以 `completion_mode` 與上層 issue 的規則照常套用。每張票各有一則留言,寫明它的 MR、合併 commit、版本與工單 id。已剔除的票不動。遠端已取消的票會讓關單停下,剔除後才能繼續。重跑時,已完成的票會跳過,留言不會重複。
252
+ - **身分。** `owner` 與紀錄中的寫入者名稱取自 `TTT_ACTOR`,未設定時為 `<current_user>@<hostname>`。
253
+
254
+ 一張票同一時間只搭一張工單:要領進第二張工單,必須先從第一張剔除。
255
+
192
256
  ### `ttt status`
193
257
 
194
258
  顯示或修改任務狀態。
@@ -213,8 +277,18 @@ ttt show --label frontend # 依標籤過濾
213
277
  ttt show --status "In Progress" --user me # 我進行中的 issue
214
278
  ttt show --priority 1 # 顯示緊急 issue
215
279
  ttt show --export # 輸出為 markdown 格式
280
+ ttt show --remote --status Backlog --creator me # 我建立的 Backlog 票
281
+ ttt show --remote --status Backlog --user me # 指派給我的 Backlog 票
282
+ ttt show --remote --any-cycle --creator me # 我建立、不限 cycle 的票
216
283
  ```
217
284
 
285
+ 兩個選項可把 `--remote` 搜尋範圍放寬到 `ttt sync` 之外(都必須搭配 `--remote`,否則直接報錯,不會默默忽略):
286
+
287
+ - `--creator <me|email|name>`:依建立者過濾(僅 Linear;Trello 卡片沒有建立者,會報錯)。
288
+ 未指定 `--user` 時會解除指派對象的限制,因此你建給別人或未指派的票也找得到。
289
+ - `--any-cycle`:不限目前 cycle。`--status Backlog` 會自動帶上它,因為 Backlog 票通常不屬於任何 cycle。
290
+ Trello 沒有 cycle,所以在 Trello 上沒有作用。
291
+
218
292
  ### `ttt config`
219
293
 
220
294
  配置設定。
@@ -236,6 +310,7 @@ your-project/
236
310
  ├── config.toon # 團隊配置(建議 gitignore)
237
311
  ├── local.toon # 個人設定(gitignore)
238
312
  ├── cycle.toon # 當前 cycle 資料與本地估時(自動產生)
313
+ ├── orders/ # 工單:<project>/<code>.toon(不要 commit)
239
314
  └── output/ # 下載的附件(圖片、檔案)
240
315
  ```
241
316
 
@@ -247,6 +322,7 @@ your-project/
247
322
  | `TRELLO_API_KEY` | **Trello 必填**。你的 Trello API 金鑰 |
248
323
  | `TRELLO_TOKEN` | **Trello 必填**。你的 Trello 授權 token |
249
324
  | `TOON_DIR` | 配置目錄(預設:`.ttt`) |
325
+ | `TTT_ACTOR` | 工單中的寫入者名稱(預設:`<current_user>@<hostname>`) |
250
326
 
251
327
  ### Trello 設定
252
328
 
@@ -281,7 +357,8 @@ your-project/
281
357
  | `/ttt:sync` | 同步 issue 到本地 |
282
358
  | `/ttt:work-on` | 領票並開始處理 |
283
359
  | `/ttt:estimate` | 寫入本地人力估時 |
284
- | `/ttt:done` | 標記當前任務完成 |
360
+ | `/ttt:done` | 標記一張或多張任務完成 |
361
+ | `/ttt:order` | 工單:把一批列車的票從領票帶到 Done |
285
362
  | `/ttt:status` | 顯示或修改任務狀態 |
286
363
  | `/ttt:show` | 顯示 issue 詳情或搜尋 issue |
287
364
 
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  name: ttt:done
3
- description: Mark current task as completed
3
+ description: Mark one or more tasks as completed
4
4
  arguments:
5
5
  - name: issue-id
6
- description: Issue ID if multiple tasks in progress (e.g., MP-624)
6
+ description: Issue ID if multiple tasks in progress (e.g., MP-624); several IDs complete them in one run
7
7
  required: false
8
8
  - name: message
9
9
  description: Completion message summarizing what was done
@@ -40,6 +40,7 @@ ttt done # Complete current in-progress task
40
40
  ttt done MP-624 # Complete specific task
41
41
  ttt done -m "Fixed null check" # With completion message
42
42
  ttt done MP-624 -m "Refactored auth" # Specific task with message
43
+ ttt done MP-624 MP-625 -m "Merged" # Several tasks, options shared by all
43
44
  ttt done MP-624 --from-remote # Issue not in local data, or still Todo (no claim needed)
44
45
  ttt done MP-624 --commit 1a2b3c4 # Record an earlier commit, not HEAD
45
46
  ```
@@ -47,10 +48,11 @@ ttt done MP-624 --commit 1a2b3c4 # Record an earlier commit, not HEAD
47
48
  ## Full CLI Reference
48
49
 
49
50
  ```
50
- Usage: ttt done [issue-id] [-m message] [--from-remote] [--commit <sha>] [--repo <path>]
51
+ Usage: ttt done [issue-id...] [-m message] [--from-remote] [--commit <sha>] [--repo <path>]
51
52
 
52
53
  Arguments:
53
- issue-id Optional. Issue ID if multiple tasks in-progress
54
+ issue-id Optional. Issue ID if multiple tasks in-progress.
55
+ Several IDs complete each ticket with the same options
54
56
 
55
57
  Options:
56
58
  -m, --message Completion message describing what was done
@@ -60,6 +62,14 @@ Options:
60
62
  --repo <path> Git repository to read the commit from (default: cwd)
61
63
  ```
62
64
 
65
+ ## Several Tickets
66
+
67
+ With several IDs each ticket gets a result line (`✅ done`, `⏭️ already done`, `❌ failed`).
68
+ An ID that is unknown or not in progress stops the run before any ticket moves.
69
+ One failing ticket does not stop the rest, and the exit code is non-zero when any failed.
70
+ A ticket that is already done (under `strict_review`: already at the testing status) is skipped, so the same command can be rerun after a partial failure.
71
+ For a train batch tracked in a work order, close it with `/ttt:order` (`ttt order close`) instead.
72
+
63
73
  ## Before Running
64
74
 
65
75
  Ensure:
@@ -89,5 +99,6 @@ Additionally:
89
99
  | `No in-progress task` | Specify issue-id explicitly |
90
100
  | `Multiple in-progress` | Specify issue-id to disambiguate |
91
101
  | `Issue not found` | Use `--from-remote` flag |
102
+ | `❌ MP-x failed` in a batch | Fix the cause and rerun the same command; done tickets are skipped |
92
103
  | `不在進行中狀態` (task is Todo) | `ttt claim <id>` first, or `ttt done <id> --from-remote` |
93
104
  | `No commits found` | Commit your changes first |
@@ -0,0 +1,134 @@
1
+ ---
2
+ name: ttt:order
3
+ description: Work orders - carry a train batch of tickets from claim to Done
4
+ arguments:
5
+ - name: command
6
+ description: "open, list, show, set, review, train, seal, drop, export, import, reclaim, or close"
7
+ required: true
8
+ - name: args
9
+ description: "Order id (<project>/<code>), ticket ids, and options for the command"
10
+ required: false
11
+ ---
12
+
13
+ <law>
14
+ YOU MUST execute `ttt order` (and `ttt claim --order`) using the Bash tool.
15
+ DO NOT edit files under `.ttt/orders/` by hand, and DO NOT commit them.
16
+ ONE side writes an order at a time: the coordinator records for its workers; after `export --handoff` only the receiver writes.
17
+ </law>
18
+
19
+ # /ttt:order — Work Orders
20
+
21
+ A work order is one TOON file per train batch (`.ttt/orders/<project>/<code>.toon`).
22
+ It holds the batch's tickets with each one's branch, MR, head, review verdict, and test runs, and it closes every ticket with one command after the train merged.
23
+
24
+ ## Execution
25
+
26
+ ```bash
27
+ ttt order {{ command }} {{ args }}
28
+ ```
29
+
30
+ ## Flow
31
+
32
+ ### Coordinator: claim, record, review, seal, hand off
33
+
34
+ ```bash
35
+ ttt claim MP-624 MP-625 --order auto --project app # Claim into the project's open order
36
+ ttt order list # Find the order id, e.g. app/2026-11-11-a
37
+
38
+ # A worker reports its MR: the coordinator records it (workers never write the order)
39
+ ttt order set app/2026-11-11-a MP-624 --branch feat/mp-624 --mr '!812' --head 1a2b3c4
40
+ ttt order set app/2026-11-11-a MP-624 --review "P0/P1=0 @1a2b3c4" \
41
+ --tests "bun test scripts/order = pass"
42
+
43
+ ttt order review app/2026-11-11-a MP-624 MP-625 # Move to the testing status
44
+ ttt order drop app/2026-11-11-a MP-626 --reason "not ready for this train"
45
+
46
+ ttt order train app/2026-11-11-a --branch agent-train/2026-11-11-a --mr '!900'
47
+ ttt order seal app/2026-11-11-a --gated-head 5d6e7f8 # No more tickets
48
+ ttt order export app/2026-11-11-a --handoff # Paste the block into the train MR or slip
49
+ ```
50
+
51
+ After the seal, `ttt claim <id> --order auto` opens the next order.
52
+ After `--handoff` the local copy is read-only.
53
+
54
+ ### Integrator: import, merge, close
55
+
56
+ ```bash
57
+ glab mr view 900 | ttt order import - # Or: ttt order import slip.md
58
+ ttt order show app/2026-11-11-a
59
+ # ... merge the train ...
60
+ ttt order close app/2026-11-11-a --merged 9a8b7c6 --version v1.2.0 --dry-run
61
+ ttt order close app/2026-11-11-a --merged 9a8b7c6 --version v1.2.0
62
+ ```
63
+
64
+ `close` completes every in-review ticket through the configured completion mode (parent issues included) and comments MR, merge commit, version, and order id on each.
65
+ Dropped tickets are untouched.
66
+ A ticket must reach the done status: under `strict_review` (or `upstream_strict` without a parent) it stops at testing, so close fails it and the order stays merged.
67
+ When a ticket fails, fix the cause and rerun the same command: done tickets are skipped and no comment is posted twice.
68
+
69
+ ### A returned train
70
+
71
+ The integrator returns the order with `ttt order export <id> --handoff`, and the coordinator runs `ttt order import <file>`.
72
+ When nothing came back, the coordinator runs `ttt order reclaim <id>`.
73
+ A reworked ticket stays in its order: record the new head and test runs with `set`, then `seal` again with the new gated head and hand off again.
74
+
75
+ ## Full CLI Reference
76
+
77
+ ```
78
+ Usage: ttt order <command> [options]
79
+
80
+ Commands:
81
+ open [<project>/<code>] [--project <p>] [--reviewer <name>]
82
+ Open an order. Without an id: <project>/<YYYY-MM-DD>-<next letter>.
83
+ A project holds one open order at a time.
84
+ list [--project <p>] [--all]
85
+ List orders (closed ones only with --all).
86
+ show <id> [--toon]
87
+ Show an order; --toon prints the stored TOON.
88
+ set <id> <ticket> [--branch <b>] [--mr <mr>] [--head <sha>]
89
+ [--review <verdict>] [--tests "<cmd> [@ <sha>] [= <result>]"]...
90
+ Record a ticket's branch, MR, head, review verdict, and test runs.
91
+ Each --tests appends one run; the sha defaults to the ticket's
92
+ head, the result to "pass".
93
+ review <id> <ticket>... [--status <name>]
94
+ Move tickets to the testing status (assignee unchanged) and mark
95
+ them in-review. An open order adopts a ticket it does not hold yet,
96
+ unless another order of the project holds it. Done or Canceled
97
+ tickets are left where they are.
98
+ train <id> [--branch <b>] [--mr <mr>]
99
+ Record the train branch and its merge request.
100
+ seal <id> --gated-head <sha>
101
+ Fix the batch: no more tickets. Every ticket must be in review or
102
+ dropped. Sealing again records a new gated head.
103
+ drop <id> <ticket> --reason <text>
104
+ Leave a ticket out of the batch; its remote status is not touched.
105
+ export <id> [--handoff]
106
+ Print the order as a fenced block for an MR description or a slip.
107
+ --handoff makes this copy read-only: the receiver writes from now on.
108
+ import <file|-> [--id <id>] [--force]
109
+ Read the block out of any text and become the order's writer.
110
+ reclaim <id>
111
+ Take a handed-off order back when it was returned without an export.
112
+ close <id> --merged <sha> [--version <v>] [--dry-run]
113
+ After the train merged: complete every in-review ticket through the
114
+ configured completion mode, and comment MR, merge commit, version,
115
+ and order id on each. Dropped tickets are untouched. Safe to rerun.
116
+ ```
117
+
118
+ The default project is the directory that holds `.ttt`.
119
+ The writer's name is `TTT_ACTOR`, else `<current_user>@<hostname>`.
120
+
121
+ ## Error Handling
122
+
123
+ | Error | Solution |
124
+ |-------|----------|
125
+ | `was handed off ... read-only` | Import the returned copy, or `ttt order reclaim <id>` |
126
+ | `takes no more tickets` | The order is sealed: claim with `--order auto` to use the next one |
127
+ | `Cannot seal ...: MP-x still in progress` | `ttt order review <id> MP-x` or `ttt order drop <id> MP-x --reason ...` |
128
+ | `is not sealed` on close | `ttt order seal <id> --gated-head <sha>` first |
129
+ | `is Canceled at the source` on close | `ttt order drop <id> MP-x --reason canceled`, then rerun close |
130
+ | `no longer in review` on close | The ticket moved since the seal: `ttt order drop` it, or put it back in review |
131
+ | `is In Review, not Done` on close | The completion mode stops at testing; move it to Done or change `completion_mode`, then rerun |
132
+ | `already in order ...` on review | A ticket rides one order per project; drop it there first |
133
+ | `already exists here as a writable copy` on import | Check which copy is current; replace the local one with `--force` |
134
+ | `No work order block found` | Pass text that contains the block printed by `ttt order export` |
@@ -20,6 +20,12 @@ arguments:
20
20
  - name: remote
21
21
  description: Fetch from Linear API instead of local data
22
22
  required: false
23
+ - name: creator
24
+ description: "Filter by creator ('me', email, or name). Needs remote; Linear only"
25
+ required: false
26
+ - name: any-cycle
27
+ description: Search outside the current cycle. Needs remote
28
+ required: false
23
29
  - name: export
24
30
  description: Output as markdown format
25
31
  required: false
@@ -43,6 +49,8 @@ ttt show {{ issue-id }} \
43
49
  {{ "--status \"" + status + "\"" if status }} \
44
50
  {{ "--user " + user if user }} \
45
51
  {{ "--priority " + priority if priority }} \
52
+ {{ "--creator " + creator if creator }} \
53
+ {{ "--any-cycle" if any-cycle }} \
46
54
  {{ "--remote" if remote }} \
47
55
  {{ "--export" if export }}
48
56
  ```
@@ -58,6 +66,9 @@ ttt show --label frontend # Filter by label
58
66
  ttt show --status "In Progress" --user me # My in-progress issues
59
67
  ttt show --priority 1 # All urgent issues
60
68
  ttt show --export # Export all as markdown
69
+ ttt show --remote --status Backlog --creator me # Backlog tickets I created
70
+ ttt show --remote --status Backlog --user me # Backlog tickets assigned to me
71
+ ttt show --remote --any-cycle --creator me # My tickets in any cycle
61
72
  ```
62
73
 
63
74
  ## Full CLI Reference
@@ -75,8 +86,14 @@ Options:
75
86
  --status <status> Filter by status
76
87
  --user <email> Filter by assignee ("me", "unassigned", or email)
77
88
  --priority <n> Filter by priority (0=None, 1=Urgent, 2=High, 3=Medium, 4=Low)
89
+ --creator <who> Filter by creator ("me", email, or name). Needs --remote,
90
+ Linear only. Without --user, the assignee scope is lifted
91
+ --any-cycle Search outside the current cycle. Needs --remote
78
92
  ```
79
93
 
94
+ `--status Backlog` implies `--any-cycle`. `--creator` and `--any-cycle` fail
95
+ without `--remote` instead of being ignored, and `--creator` fails on Trello.
96
+
80
97
  ## After Execution
81
98
 
82
99
  Present the output to the user. If `--export` was used, the output is markdown-formatted and can be used as context.
@@ -8,6 +8,12 @@ arguments:
8
8
  - name: dry-run
9
9
  description: Preview selection without changing status
10
10
  required: false
11
+ - name: order
12
+ description: "Work order to record the claimed tickets in: an order id, or 'auto' for the project's open order"
13
+ required: false
14
+ - name: project
15
+ description: Project for order 'auto' (default - the directory that holds .ttt)
16
+ required: false
11
17
  ---
12
18
 
13
19
  <law>
@@ -24,7 +30,7 @@ to in-progress locally and on the remote source.
24
30
  ## Execution
25
31
 
26
32
  ```bash
27
- ttt claim {{ issue-ids | default: "next" }} {{ "--dry-run" if dry-run }}
33
+ ttt claim {{ issue-ids | default: "next" }} {{ "--dry-run" if dry-run }} {{ "--order " + order if order }} {{ "--project " + project if project }}
28
34
  ```
29
35
 
30
36
  ### Argument Resolution
@@ -38,6 +44,7 @@ ttt claim {{ issue-ids | default: "next" }} {{ "--dry-run" if dry-run }}
38
44
  | `MP-624 MP-625` | `ttt claim MP-624 MP-625` |
39
45
  | `--dry-run` | `ttt claim next --dry-run` |
40
46
  | `MP-624 --dry-run` | `ttt claim MP-624 --dry-run` |
47
+ | `MP-624 MP-625` in a train batch | `ttt claim MP-624 MP-625 --order auto --project <name>` |
41
48
 
42
49
  ## Full CLI Reference
43
50
 
@@ -52,14 +59,24 @@ Arguments:
52
59
  'next' claims the highest priority pending task
53
60
  'next <n>' claims the top <n> pending tasks
54
61
  If omitted, shows interactive multi-select
62
+ An ID missing from local data (e.g. a Backlog ticket outside
63
+ the cycle) is fetched from the source, stored locally, and
64
+ claimed like any other
55
65
 
56
66
  Options:
57
- --dry-run Pick tickets without changing status (preview only)
67
+ --dry-run Pick tickets without changing status (preview only)
68
+ --order <id|auto> Also record the claimed tickets in a work order
69
+ (see 'ttt order --help'). 'auto' is the project's open
70
+ order; when the last one was sealed, a new order
71
+ <project>/<YYYY-MM-DD>-<next letter> is opened
72
+ --project <name> Project for '--order auto'
73
+ (default: the directory that holds .ttt)
58
74
  ```
59
75
 
60
76
  Tickets that are already completed, in review, or blocked are reported and
61
- skipped without stopping the rest of the batch. An unknown ID aborts before
62
- anything is claimed.
77
+ skipped without stopping the rest of the batch. An ID found neither locally nor
78
+ at the source aborts before anything is claimed. Find Backlog tickets first with
79
+ `ttt show --remote --status Backlog --creator me` (or `--user me`), then claim by ID.
63
80
 
64
81
  ## After Claiming — Delegate the Implementation
65
82
 
@@ -78,6 +95,12 @@ This command claims the tickets. The implementation workflow belongs to the user
78
95
  When several tickets were claimed at once, carry them one at a time and close
79
96
  each with `/ttt:done -m "summary"` before starting the next.
80
97
 
98
+ ## Batch Work on a Train
99
+
100
+ When the tickets ride one integration branch and are closed together after its
101
+ merge, claim them with `--order` and do not run `/ttt:done` per ticket. The work
102
+ order then carries them to Done: see `/ttt:order`.
103
+
81
104
  ## Error Handling
82
105
 
83
106
  | Error | Solution |
@@ -85,3 +108,5 @@ each with `/ttt:done -m "summary"` before starting the next.
85
108
  | `No cycle data found` | Run `ttt sync` first |
86
109
  | `No eligible tasks` | All tasks assigned or in-review; run `ttt sync` to refresh |
87
110
  | `Issue not found` | Run `ttt sync <id>` to fetch it |
111
+ | `Order ... takes no more tickets` | The order is sealed; use `--order auto` to claim into the next one |
112
+ | `already in order ...` | The ticket rides another order; drop it there first (`ttt order drop`) |