team-toon-tack 3.12.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.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/README.md +67 -1
- package/README.zh-TW.md +65 -1
- package/commands/ttt-done.md +15 -4
- package/commands/ttt-order.md +134 -0
- package/commands/ttt-work-on.md +23 -2
- package/dist/bin/cli.js +9 -0
- package/dist/scripts/claim.js +61 -5
- package/dist/scripts/done-job.d.ts +0 -4
- package/dist/scripts/done-job.js +209 -103
- package/dist/scripts/lib/adapters/linear-adapter.js +5 -1
- package/dist/scripts/lib/done/args.js +12 -6
- package/dist/scripts/lib/done/handler.d.ts +2 -0
- package/dist/scripts/lib/done/handler.js +12 -0
- package/dist/scripts/lib/done/index.d.ts +1 -0
- package/dist/scripts/lib/done/index.js +1 -0
- package/dist/scripts/lib/done/status-check.d.ts +2 -1
- package/dist/scripts/lib/done/status-check.js +4 -3
- package/dist/scripts/lib/done/types.d.ts +2 -1
- package/dist/scripts/lib/order/close.d.ts +30 -0
- package/dist/scripts/lib/order/close.js +113 -0
- package/dist/scripts/lib/order/model.d.ts +74 -0
- package/dist/scripts/lib/order/model.js +452 -0
- package/dist/scripts/lib/order/remote.d.ts +34 -0
- package/dist/scripts/lib/order/remote.js +116 -0
- package/dist/scripts/lib/order/store.d.ts +49 -0
- package/dist/scripts/lib/order/store.js +299 -0
- package/dist/scripts/lib/order/transfer.d.ts +8 -0
- package/dist/scripts/lib/order/transfer.js +54 -0
- package/dist/scripts/lib/order/types.d.ts +70 -0
- package/dist/scripts/lib/order/types.js +18 -0
- package/dist/scripts/lib/trello.js +3 -1
- package/dist/scripts/order.d.ts +2 -0
- package/dist/scripts/order.js +493 -0
- package/dist/scripts/test-support/linear-mock.js +128 -23
- package/dist/scripts/test-support/linear-workspace.d.ts +44 -0
- package/dist/scripts/test-support/linear-workspace.js +133 -0
- package/package.json +1 -1
- package/skills/managing-linear-tasks/SKILL.md +33 -2
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,61 @@ 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
|
+
|
|
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
|
+
|
|
199
262
|
### `ttt status`
|
|
200
263
|
|
|
201
264
|
Show or modify task status.
|
|
@@ -257,6 +320,7 @@ your-project/
|
|
|
257
320
|
├── config.toon # Team config (gitignore recommended)
|
|
258
321
|
├── local.toon # Personal settings (gitignore)
|
|
259
322
|
├── cycle.toon # Current cycle data + local estimates (auto-generated)
|
|
323
|
+
├── orders/ # Work orders: <project>/<code>.toon (never commit)
|
|
260
324
|
└── output/ # Downloaded attachments (images, files)
|
|
261
325
|
```
|
|
262
326
|
|
|
@@ -268,6 +332,7 @@ your-project/
|
|
|
268
332
|
| `TRELLO_API_KEY` | **Required for Trello.** Your Trello API key |
|
|
269
333
|
| `TRELLO_TOKEN` | **Required for Trello.** Your Trello authorization token |
|
|
270
334
|
| `TOON_DIR` | Config directory (default: `.ttt`) |
|
|
335
|
+
| `TTT_ACTOR` | Writer's name in work orders (default: `<current_user>@<hostname>`) |
|
|
271
336
|
|
|
272
337
|
### Trello Setup
|
|
273
338
|
|
|
@@ -302,7 +367,8 @@ Install the plugin for Claude Code integration:
|
|
|
302
367
|
| `/ttt:sync` | Sync issues to local cycle data |
|
|
303
368
|
| `/ttt:work-on` | Claim ticket(s) and work on them |
|
|
304
369
|
| `/ttt:estimate` | Save a local human-effort estimate |
|
|
305
|
-
| `/ttt:done` | Mark
|
|
370
|
+
| `/ttt:done` | Mark one or more tasks as completed |
|
|
371
|
+
| `/ttt:order` | Work orders: carry a train batch from claim to Done |
|
|
306
372
|
| `/ttt:status` | Show or modify task status |
|
|
307
373
|
| `/ttt:show` | Show issue details or search issues |
|
|
308
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,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,59 @@ 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
|
+
| 指令 | 作用 |
|
|
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
|
+
|
|
195
256
|
### `ttt status`
|
|
196
257
|
|
|
197
258
|
顯示或修改任務狀態。
|
|
@@ -249,6 +310,7 @@ your-project/
|
|
|
249
310
|
├── config.toon # 團隊配置(建議 gitignore)
|
|
250
311
|
├── local.toon # 個人設定(gitignore)
|
|
251
312
|
├── cycle.toon # 當前 cycle 資料與本地估時(自動產生)
|
|
313
|
+
├── orders/ # 工單:<project>/<code>.toon(不要 commit)
|
|
252
314
|
└── output/ # 下載的附件(圖片、檔案)
|
|
253
315
|
```
|
|
254
316
|
|
|
@@ -260,6 +322,7 @@ your-project/
|
|
|
260
322
|
| `TRELLO_API_KEY` | **Trello 必填**。你的 Trello API 金鑰 |
|
|
261
323
|
| `TRELLO_TOKEN` | **Trello 必填**。你的 Trello 授權 token |
|
|
262
324
|
| `TOON_DIR` | 配置目錄(預設:`.ttt`) |
|
|
325
|
+
| `TTT_ACTOR` | 工單中的寫入者名稱(預設:`<current_user>@<hostname>`) |
|
|
263
326
|
|
|
264
327
|
### Trello 設定
|
|
265
328
|
|
|
@@ -294,7 +357,8 @@ your-project/
|
|
|
294
357
|
| `/ttt:sync` | 同步 issue 到本地 |
|
|
295
358
|
| `/ttt:work-on` | 領票並開始處理 |
|
|
296
359
|
| `/ttt:estimate` | 寫入本地人力估時 |
|
|
297
|
-
| `/ttt:done` |
|
|
360
|
+
| `/ttt:done` | 標記一張或多張任務完成 |
|
|
361
|
+
| `/ttt:order` | 工單:把一批列車的票從領票帶到 Done |
|
|
298
362
|
| `/ttt:status` | 顯示或修改任務狀態 |
|
|
299
363
|
| `/ttt:show` | 顯示 issue 詳情或搜尋 issue |
|
|
300
364
|
|
package/commands/ttt-done.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ttt:done
|
|
3
|
-
description: Mark
|
|
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` |
|
package/commands/ttt-work-on.md
CHANGED
|
@@ -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
|
|
|
@@ -57,7 +64,13 @@ Arguments:
|
|
|
57
64
|
claimed like any other
|
|
58
65
|
|
|
59
66
|
Options:
|
|
60
|
-
--dry-run
|
|
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)
|
|
61
74
|
```
|
|
62
75
|
|
|
63
76
|
Tickets that are already completed, in review, or blocked are reported and
|
|
@@ -82,6 +95,12 @@ This command claims the tickets. The implementation workflow belongs to the user
|
|
|
82
95
|
When several tickets were claimed at once, carry them one at a time and close
|
|
83
96
|
each with `/ttt:done -m "summary"` before starting the next.
|
|
84
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
|
+
|
|
85
104
|
## Error Handling
|
|
86
105
|
|
|
87
106
|
| Error | Solution |
|
|
@@ -89,3 +108,5 @@ each with `/ttt:done -m "summary"` before starting the next.
|
|
|
89
108
|
| `No cycle data found` | Run `ttt sync` first |
|
|
90
109
|
| `No eligible tasks` | All tasks assigned or in-review; run `ttt sync` to refresh |
|
|
91
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`) |
|
package/dist/bin/cli.js
CHANGED
|
@@ -22,6 +22,7 @@ const COMMANDS = [
|
|
|
22
22
|
"assign",
|
|
23
23
|
"edit",
|
|
24
24
|
"cancel",
|
|
25
|
+
"order",
|
|
25
26
|
"config",
|
|
26
27
|
"help",
|
|
27
28
|
"version",
|
|
@@ -47,6 +48,7 @@ COMMANDS:
|
|
|
47
48
|
assign Reassign an issue to a user
|
|
48
49
|
edit Edit issue fields (title, description, priority, labels)
|
|
49
50
|
cancel Cancel an issue
|
|
51
|
+
order Work orders: carry a train batch of tickets from claim to Done
|
|
50
52
|
config Configure settings (status mappings, filters)
|
|
51
53
|
help Show this help message
|
|
52
54
|
version Show version
|
|
@@ -68,6 +70,9 @@ EXAMPLES:
|
|
|
68
70
|
ttt estimate MP-123 6 # Save a 6-hour estimate locally
|
|
69
71
|
ttt done # Complete current task
|
|
70
72
|
ttt done -m "Fixed the bug" # With completion message
|
|
73
|
+
ttt done MP-123 MP-124 # Complete several tickets in one run
|
|
74
|
+
ttt claim MP-123 --order auto # Claim into the project's open work order
|
|
75
|
+
ttt order close app/2026-11-11-a --merged 1a2b3c4 # Batch → Done after merge
|
|
71
76
|
ttt show MP-123 # Show issue from local data
|
|
72
77
|
ttt show --label frontend # Search local issues by label
|
|
73
78
|
ttt show --status "In Progress" # Filter by status
|
|
@@ -217,6 +222,10 @@ async function main() {
|
|
|
217
222
|
process.argv = ["node", "cancel.js", ...commandArgs];
|
|
218
223
|
await importScript("cancel.js");
|
|
219
224
|
break;
|
|
225
|
+
case "order":
|
|
226
|
+
process.argv = ["node", "order.js", ...commandArgs];
|
|
227
|
+
await importScript("order.js");
|
|
228
|
+
break;
|
|
220
229
|
case "config":
|
|
221
230
|
process.argv = ["node", "config.js", ...commandArgs];
|
|
222
231
|
await importScript("config.js");
|