devlog-tracker 1.0.0 → 1.1.1

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 (56) hide show
  1. package/README.md +7 -5
  2. package/README.zh-TW.md +7 -5
  3. package/codex/hooks/on-interrupt.sh +1 -0
  4. package/codex/hooks/on-pre-tool.sh +9 -7
  5. package/codex/hooks/on-session-end.sh +1 -0
  6. package/codex/hooks/on-session-start.sh +1 -0
  7. package/codex/hooks/on-stop.sh +1 -0
  8. package/codex/hooks/on-subagent-start.sh +1 -0
  9. package/codex/hooks/on-user-prompt-submit.sh +1 -0
  10. package/codex/hooks/test-adapters.sh +29 -19
  11. package/commands/clean.md +2 -2
  12. package/commands/continue.md +1 -1
  13. package/commands/keep-all.md +4 -4
  14. package/commands/keep.md +4 -4
  15. package/commands/migrate.md +2 -2
  16. package/commands/span.md +4 -4
  17. package/commands/status.md +1 -1
  18. package/core/scripts/await-open.sh +4 -4
  19. package/core/scripts/clean-devlog.sh +11 -5
  20. package/core/scripts/close-open-round.sh +0 -4
  21. package/core/scripts/devlog-md.sh +89 -8
  22. package/core/scripts/devlog-path.sh +128 -10
  23. package/core/scripts/enforce-devlog.sh +35 -19
  24. package/core/scripts/keep-all.js +4 -3
  25. package/core/scripts/keep-all.sh +2 -3
  26. package/core/scripts/keep-all.test.js +31 -0
  27. package/core/scripts/keep-move.sh +13 -9
  28. package/core/scripts/migrate-handoff.sh +2 -2
  29. package/core/scripts/on-tool-failure.sh +6 -1
  30. package/core/scripts/pause-devlog.sh +5 -3
  31. package/core/scripts/round-start.sh +31 -20
  32. package/core/scripts/segment-watch-set.sh +12 -8
  33. package/core/scripts/segment-watch.sh +3 -6
  34. package/core/scripts/session-start-devlog.sh +11 -5
  35. package/core/scripts/span-close.sh +7 -3
  36. package/core/scripts/span-open.sh +4 -4
  37. package/core/scripts/status-devlog.sh +6 -6
  38. package/core/scripts/tests/test-await-open.sh +9 -0
  39. package/core/scripts/tests/test-devlog-md.sh +76 -15
  40. package/core/scripts/tests/test-devlog-path.sh +126 -0
  41. package/core/scripts/tests/test-multi-platform.sh +286 -0
  42. package/core/scripts/tests/test-segment-watch-set.sh +10 -0
  43. package/core/scripts/tests/test-session-start-devlog.sh +15 -0
  44. package/cursor/hooks/on-pre-tool.sh +1 -0
  45. package/cursor/hooks/on-session-end.sh +1 -0
  46. package/cursor/hooks/on-session-start.sh +1 -0
  47. package/cursor/hooks/on-stop.sh +1 -0
  48. package/cursor/hooks/on-submit-prompt.sh +1 -0
  49. package/cursor/hooks/on-tool-failure.sh +1 -0
  50. package/cursor/hooks/test-adapters.sh +19 -16
  51. package/package.json +1 -1
  52. package/skills/devlog-tracker/SKILL.md +23 -18
  53. package/skills/devlog-tracker/references/contract.md +2 -2
  54. package/skills/devlog-tracker/references/reply-fold.md +8 -8
  55. package/skills/devlog-tracker/references/round-segments.md +2 -2
  56. package/skills/devlog-tracker/references/span-mode.md +10 -3
@@ -13,7 +13,7 @@ description: 在專案的 .devlog/devlog.md 維護逐輪對話紀錄。使用者
13
13
  | 維度 | 契約(短) |
14
14
  |---|---|
15
15
  | **Requirements** | 強制記錄需 `.devlog/.enabled`(Claude plugin 用 `/devlog-tracker:start`,Codex 用 `$devlog-start`)。`/clear` 後不自動接續;要開工用對應的 continue 指令(或明確說接續)。Cursor/npx 安裝的 Codex 對照 `.devlog-tracker/commands/*.md`;Codex plugin 對照 plugin 根目錄的 `commands/*.md`。 |
16
- | **Output** | 編輯開著的 Round(`.round-current.md`):必有 `### Summary`/`### Reply`/`### Handoff`/`### Status`;Handoff/Session Handoff 用 XML 標籤,標籤順序固定。格式見「每一輪的紀錄格式」。 |
16
+ | **Output** | 編輯開著的 Round(你所在平台的 round 檔,見「檔案位置」):必有 `### Summary`/`### Reply`/`### Handoff`/`### Status`;Handoff/Session Handoff 用 XML 標籤,標籤順序固定。格式見「每一輪的紀錄格式」。 |
17
17
  | **Invariants** | L1 寫回義務;聊天不旁白記錄動作;不改 User Input(除非 hook `(無 prompt)`);不為同一則訊息再 append `## Round`;設計真相在 `docs/design/*.md`,不是 lessons。 |
18
18
  | **Validation** | Soft:收尾前自檢欄位與工作區。Hard:Stop/PreToolUse/workspace/files snapshot(見「每一輪的紀錄格式」末段與 hook 腳本)。fail-open/loop guard 見下方開關一節。 |
19
19
  | **Transformation** | 單次動作走對應 `commands/*.md`(start/continue/compact/keep/…);本檔管協定與跨指令不變式,不重抄步驟。 |
@@ -34,7 +34,7 @@ devlog.md 是**跨 session 交接連續性**(決策軌跡、目前卡點、下
34
34
 
35
35
  `### Summary`/`### Reply`/`### Handoff`/`### 段落`/`## Checkpoint` 這些內容是寫給「下一個
36
36
  讀 devlog.md 的人」看的,不是講給正在對話的使用者聽的——這是兩件不同的事,收尾時
37
- 用 Edit/Write 工具**安靜地**寫進 `.devlog/.round-current.md`(這一輪還開著時的
37
+ 用 Edit/Write 工具**安靜地**寫進你所在平台的 round 檔(見「檔案位置」;這一輪還開著時的
38
38
  實際編輯對象,收尾成功或被判定中斷後才會由 hook 自動併回 `.devlog/devlog.md`;
39
39
  工具呼叫本身不會顯示給使用者),寫完之後**不要**在聊天回覆裡再提這件事。
40
40
 
@@ -57,10 +57,10 @@ IN_PROGRESS,因為背景任務還在跑)。等它跑完我會回報結果並
57
57
  內部記錄動作。
58
58
 
59
59
  **最容易漏掉的一種情況:結尾的「這輪改了什麼」總結。** 這輪如果除了
60
- `.devlog/.round-current.md`(收尾後才會併入 `devlog.md`)還真的改了別的檔案
60
+ 你所在平台的 round 檔(見「檔案位置」;收尾後才會併入 `devlog.md`)還真的改了別的檔案
61
61
  (例如 README.md、程式碼),結尾照常給一兩句話總結改了什麼、下一步是什麼——
62
62
  但這個異動本身**不算在「改了什麼」裡面,永遠不要提**,因為那是記錄動作本身、
63
- 不是產出。舉例:這輪同時修了 `README.md` 又寫了 `.devlog/.round-current.md`,
63
+ 不是產出。舉例:這輪同時修了 `README.md` 又寫了 round 檔,
64
64
  結尾只講「README.md 已更新成...」,不要接著再講「devlog 也已更新/已補上這輪的
65
65
  Summary/Handoff」——後面這句要整句刪掉,不是縮短。
66
66
 
@@ -71,9 +71,12 @@ Summary/Handoff」——後面這句要整句刪掉,不是縮短。
71
71
  - 歸檔:`.devlog/devlog.archive.md`
72
72
  - 具名保存:`.devlog/devlog.<name>.md`(`/devlog-tracker:keep`/`keep-all` 搬走的主題檔,第一行是 `# Kept log`;SessionStart 不讀這些檔)
73
73
  - keep-all 備份:`.devlog/.keep-all-backup/<時間戳>/`(`/devlog-tracker:keep-all` 動手前的原始檔複本)
74
- - 當輪暫存:`.devlog/.round-current.md`(目前開著的那一輪,Claude 該讀寫的是這個檔,不是 `devlog.md`;
75
- 收尾或中斷時由 hook 自動合併回 `devlog.md` 並清空,設計見 `docs/design/round-current-split.md`)
74
+ - 當輪暫存:`.devlog/.round-current.md`(Claude Code)/`.devlog/.round-current@codex.md`(Codex)/`.devlog/.round-current@cursor.md`(Cursor):這一輪還沒收尾時寫在這裡,只寫你所在平台那一份;hook 的提示會寫出確切檔名。同一個工作樹可以有多個平台同時在跑,別的平台的檔案不要讀寫。
75
+ 該讀寫的是這個檔,不是 `devlog.md`;收尾或中斷時由 hook 自動合併回 `devlog.md` 並清空,設計見 `docs/design/round-current-split.md`;多平台見 `docs/design/multi-platform-concurrency.md`。
76
+ Codex/Cursor 的 Round 標題結尾會帶 ` · codex`/` · cursor`(例如 `## Round 12 — <時間> · codex`),由 hook 寫入,不要自己加或刪。
77
+ 下文說「你所在平台的 round 檔」就是指這一份。
76
78
  - Session Handoff 快照:`.devlog/handoff.md`(`main`/`master`);其他分支 `.devlog/handoff.<branch>.md`。
79
+ Codex/Cursor 各有自己的一份,檔名在 `.md` 前加 `@codex`/`@cursor`(例如 `handoff@codex.md`、`handoff.<branch>@cursor.md`)。
77
80
  由 Stop 在 `IN_PROGRESS`/`BLOCKED` 收尾時覆寫、`DONE` 時刪除;Claude 只寫 Round 內的
78
81
  `### Session Handoff`,不要直接編這個檔。設計見 `docs/design/session-handoff-file.md`。
79
82
  - Cursor/Codex 上沒有 `/devlog-tracker:*` slash 選單。若專案是用 `npx devlog-tracker init` 裝的,指令對照就是 `.devlog-tracker/commands/*.md`:先 `source .devlog-tracker/env.sh`,再照使用者意圖對應的那份 `.md` 檔案的步驟做。Codex plugin 安裝時,指令對照在 plugin 根目錄的 `commands/*.md`,也可直接用 `$devlog-start` 等 skill。手動裝的專案見 README 安裝章節。
@@ -100,24 +103,25 @@ Claude Code 目前沒有正式、穩定的方式讓 hook 知道「這一輪有
100
103
  開關啟動之後,才會進入下面這套強制流程:
101
104
 
102
105
  1. 使用者送出新訊息時,`UserPromptSubmit` hook(`core/scripts/round-start.sh`)
103
- 若開關開著,就在 `.devlog/.round-current.md` 寫入這一輪的 skeleton(`### User Input`
104
- + `Status: IN_PROGRESS`),並寫 `.devlog/.round-open`。
106
+ 若開關開著,就在你所在平台的 round 檔(見「檔案位置」)寫入這一輪的 skeleton(`### User Input`
107
+ + `Status: IN_PROGRESS`),並寫 `.devlog/.round-open`(Codex/Cursor 是 `.round-open@codex`/`.round-open@cursor`)。
108
+ Codex/Cursor 上 hook 會多印一行 `這一輪寫在 .devlog/<檔名>。`。
105
109
  2. Claude 編輯**同一個** Round:不要再 append 一個新的 `## Round`。不要改 User Input
106
110
  (除非裡面是 hook 的 `(無 prompt)` 占位)。補上 `### Summary` / `### Reply` / `### Handoff`,
107
111
  把 Status 改成 `DONE` / `IN_PROGRESS` / `BLOCKED`。這一輪還開著的時候,編輯的對象
108
- 是 `.devlog/.round-current.md`,不是 `devlog.md`——這一輪還沒併回去之前,
112
+ 是你所在平台的 round 檔,不是 `devlog.md`——這一輪還沒併回去之前,
109
113
  `devlog.md` 完全看不到它。
110
114
  3. `Stop` hook(`core/scripts/enforce-devlog.sh`)若雜湊沒變、或最後一個 Round
111
115
  缺少 `### Summary` / `### Reply` / `### Handoff`,就用 exit code 2 擋下來。通過則刪掉
112
- `.round-open`,並把 `.round-current.md` 的內容併回 `devlog.md` 尾端、清空
113
- `.round-current.md`(設計見 `docs/design/round-current-split.md`)。
116
+ `.round-open`,並把 round 檔的內容併回 `devlog.md` 尾端、清空
117
+ round 檔(設計見 `docs/design/round-current-split.md`)。
114
118
 
115
119
  好處:就算工作做到一半被中斷(下一輪還沒開始就被使用者關掉、或換 session),
116
120
  只要**上一輪有正常結束過**,devlog.md 就一定留有當時的 Status(多半是 `IN_PROGRESS`
117
121
  或 `BLOCKED`)可以接續——這跟「plan 是否完成」完全無關,純粹綁在「這一輪有沒有結束」
118
122
  這個事件上。
119
123
 
120
- 需要誠實說明的邊界:User Input 在送出當下就已經在 `.devlog/.round-current.md`
124
+ 需要誠實說明的邊界:User Input 在送出當下就已經在你所在平台的 round 檔
121
125
  (收尾成功或被判定中斷後才會併回 `devlog.md`)。正常結束時 Stop 仍保證有 Summary / Reply / Handoff。
122
126
  意外中斷會把同一塊標成 `INTERRUPTED`(process 被殺、或 mid-turn 取消時,Status 通常要等
123
127
  **下一則訊息**或**下次 SessionStart(startup / resume / clear / fork)**才補上)。
@@ -245,7 +249,7 @@ DONE | IN_PROGRESS | BLOCKED | INTERRUPTED
245
249
 
246
250
  下文提到「決策」「檔案」「工作區」「現況」「完成條件」「下一步」時,指的就是對應標籤。
247
251
 
248
- Round 編號:讀取檔案中最後一個 `## Round <N>`,本輪用 N+1;檔案不存在就從 Round 1 開始。
252
+ Round 編號:讀取檔案中最後一個 `## Round <N>`,本輪用 N+1;檔案不存在就從 Round 1 開始。(hook 併回時若這個編號已被佔用——例如另一個平台同時開著一輪——會自動改成下一個空號,不用自己處理。)
249
253
 
250
254
  寫入原則:
251
255
  - **User Input:送出原文優先。** hook 在 `UserPromptSubmit` 已寫入送出當下的 prompt(截斷/遮罩規則見
@@ -356,8 +360,8 @@ Reply 一句(對使用者說過的話)、Handoff 只留 `<state>` 一句(
356
360
  呼叫次數機械觸發。不要把段落內容再抄進 Summary 或 Handoff。
357
361
 
358
362
  另有一道保底:同一輪連續約 10 分鐘(可用 `/devlog-tracker:segment-watch <時間長度>`
359
- 調整)沒改 `.devlog/.round-current.md`,下一個工具會被 PreToolUse hook 擋住,先
360
- Read `.devlog/.round-current.md` 再用 Edit/StrReplace 追加一段(**禁止**用 Write
363
+ 調整)沒改你所在平台的 round 檔(見「檔案位置」),下一個工具會被 PreToolUse hook 擋住,先
364
+ Read 那個 round 檔再用 Edit/StrReplace 追加一段(**禁止**用 Write
361
365
  覆寫整份檔)。
362
366
 
363
367
  完整格式範例、寫入細則、跟 dynamic workflow/subagent 的例外情況,見
@@ -376,7 +380,8 @@ Reply Fold 讓它折進同一個 Round。
376
380
 
377
381
  **提問前**(純文字跨 turn;結束 turn 之前):先用 Edit 在 `### Summary` 之前插入一段
378
382
  `### 段落(Claude 提問)` 記下問題原文,再跑
379
- `${DEVLOG_TRACKER_ROOT:-${CLAUDE_PLUGIN_ROOT}}/core/scripts/await-open.sh` 標記「下一則訊息大概是在
383
+ `${DEVLOG_TRACKER_ROOT:-${CLAUDE_PLUGIN_ROOT}}/core/scripts/await-open.sh`(前面要帶
384
+ `DEVLOG_PLATFORM="<你所在的平台:claude/codex/cursor>"`,完整指令見 `references/reply-fold.md`)標記「下一則訊息大概是在
380
385
  回答這個 Round」。使用者回答時 `round-start.sh` 會自動折成對應段落,不用手動
381
386
  處理。連續多輪一問一答(例如 grilling)時不必每題重寫 Summary/Reply/Handoff/
382
387
  Status,只有整場問答真正結束才收尾一次。
@@ -390,7 +395,7 @@ Status,只有整場問答真正結束才收尾一次。
390
395
  完成通知)反覆喚醒、不是使用者手動打字觸發的長任務,如果每個自動 tick 都當一
391
396
  輪強制寫,會逼出大量沒意義的紀錄或卡住整條自動化流程。只有**確定接下來會進入
392
397
  一連串自動續接**時才開(一般互動式對話不需要,也不應該開),用
393
- `/devlog-tracker:span` 建立 `.devlog/.span-open`,累積到門檻
398
+ `/devlog-tracker:span` 建立 `.devlog/.span-open`(Codex/Cursor 是 `.span-open@codex`/`.span-open@cursor`),累積到門檻
394
399
  (`max_silent_ticks`)才強制寫一次;崩潰最多漏記固定數量的 tick,不是整段 span。
395
400
 
396
401
  JSON 格式、開關步驟、已知限制(分辨不出自動續接 vs 真人插話),見
@@ -493,4 +498,4 @@ Handoff。核對用 `commands/continue.md` 步驟 5.1–5.2(不要跟著做 5.
493
498
 
494
499
  ## 無條件清空:`/devlog-tracker:clean`
495
500
 
496
- 把 `devlog.md` 整份清空(含專案摘要與所有 Round 歷史),不搬移、不備份,不可復原。跟 compact/keep 不一樣:那兩個都是「搬去別的檔案保留」,clean 是真的丟棄。執行前一定要先問使用者、拿到明確的「清空」才動手;只有目前開著的那一輪會留下(若有開著,內容讀自 `.devlog/.round-current.md`,不是已經清空的 `devlog.md`),重編成 `## Round 1`。步驟見 `commands/clean.md`。不要自動觸發。
501
+ 把 `devlog.md` 整份清空(含專案摘要與所有 Round 歷史),不搬移、不備份,不可復原。跟 compact/keep 不一樣:那兩個都是「搬去別的檔案保留」,clean 是真的丟棄。執行前一定要先問使用者、拿到明確的「清空」才動手;只有目前開著的那一輪會留下(若有開著,內容讀自該平台的 round 檔,不是已經清空的 `devlog.md`;同一工作樹有兩個以上平台的輪次開著時腳本會拒絕執行),重編成 `## Round 1`。步驟見 `commands/clean.md`。不要自動觸發。
@@ -35,7 +35,7 @@
35
35
  | 聊天不旁白記錄動作/不提 Round 欄位名 | `SKILL.md`「寫進 devlog 不等於講給使用者聽」 |
36
36
  | 不改 User Input(除 hook 占位) | `SKILL.md` 寫入原則 |
37
37
  | 同一則使用者訊息不另開 `## Round` | `SKILL.md` 強制流程步驟 2 |
38
- | 編輯對象是 `.round-current.md`(開著時) | `SKILL.md`「檔案位置」;`docs/design/round-current-split.md` |
38
+ | 編輯對象是你所在平台的 round 檔(開著時;Claude Code `.round-current.md`,Codex/Cursor `.round-current@codex.md`/`.round-current@cursor.md`),不碰別的平台的檔 | `SKILL.md`「檔案位置」;`docs/design/round-current-split.md`;`docs/design/multi-platform-concurrency.md` |
39
39
  | Lessons ≠ 架構知識庫;設計在 `docs/design/` | `SKILL.md`「Lessons Mode」;`references/lessons-mode.md` |
40
40
  | `INTERRUPTED` 只由 hook 寫 | `SKILL.md` Status 規則 |
41
41
 
@@ -69,7 +69,7 @@
69
69
 
70
70
  | 主題 | 權威位置 |
71
71
  |---|---|
72
- | 主檔/分支檔/歸檔/keep/round-current/handoff | `SKILL.md`「檔案位置」;`docs/design/branch-scoped-devlog.md`;`docs/design/session-handoff-file.md` |
72
+ | 主檔/分支檔/歸檔/keep/round-current/handoff | `SKILL.md`「檔案位置」;`docs/design/branch-scoped-devlog.md`;`docs/design/session-handoff-file.md`;`docs/design/multi-platform-concurrency.md` |
73
73
  | 錄製時機與截斷 | `docs/design/recording-moments.md` |
74
74
  | Span/Checkpoint/Lessons/Reply Fold/Segments | 各 `references/*.md` + 對應 `docs/design/*` |
75
75
  | 下一步黑名單 | `docs/design/next-step-blacklist.md` |
@@ -33,7 +33,7 @@
33
33
 
34
34
  1. 先用 Edit 在這個 Round 的 `### Summary` 之前插入一個小段落,記下**這次
35
35
  問的問題原文**(跟自動折入答案用同一種格式,方便前後對照)。這一步的
36
- 編輯對象是 `.devlog/.round-current.md`——提問當下這一輪還沒收尾,本來就
36
+ 編輯對象是你所在平台的 round 檔(見 `SKILL.md`「檔案位置」)——提問當下這一輪還沒收尾,本來就
37
37
  還沒併回 `.devlog/devlog.md`(見 `docs/design/round-current-split.md`):
38
38
 
39
39
  `````markdown
@@ -52,24 +52,24 @@
52
52
  3. 用 Bash 執行:
53
53
 
54
54
  ```bash
55
- DEVLOG_PROJECT_DIR="<專案根目錄絕對路徑,不要用 $(pwd)>" bash "${DEVLOG_TRACKER_ROOT:-${CLAUDE_PLUGIN_ROOT}}/core/scripts/await-open.sh"
55
+ DEVLOG_PLATFORM="<你所在的平台:claude/codex/cursor>" DEVLOG_PROJECT_DIR="<專案根目錄絕對路徑,不要用 $(pwd)>" bash "${DEVLOG_TRACKER_ROOT:-${CLAUDE_PLUGIN_ROOT}}/core/scripts/await-open.sh"
56
56
  ```
57
57
 
58
- 這會寫入 `.devlog/.awaiting-reply`,記住「下一則訊息大概是在回答這個
58
+ 這會寫入 `.devlog/.awaiting-reply`(Codex/Cursor 是 `.awaiting-reply@codex`/`.awaiting-reply@cursor`),記住「下一則訊息大概是在回答這個
59
59
  Round」。不需要使用者下任何指令,也不用手寫這個 JSON。
60
60
 
61
61
  上面第 2 步已經讓這一輪正常收尾(Summary/Reply/Handoff/Status 都有效),所以
62
62
  這個 turn 結束時它會照一般流程併回 `.devlog/devlog.md`。也就是說,**提問
63
63
  出去、答案還沒進來的這段期間**(使用者可能過很久才回覆),這一輪確實已經
64
- 完整躺在 `devlog.md` 的歷史裡,不是懸在 `.devlog/.round-current.md` 裡假裝
64
+ 完整躺在 `devlog.md` 的歷史裡,不是懸在 round 檔裡假裝
65
65
  還開著——只有在下一則訊息真的進來、被判定是在回答時,才會被下面的機制短
66
66
  暫重新打開,回覆折進去、這個 turn 收尾後又立刻併回去。
67
67
 
68
68
  **下一則訊息進來之後會自動發生什麼事:** `round-start.sh` 看到
69
- `.awaiting-reply`、且輪次跟 `devlog.md` 目前最後一個 `## Round` 吻合(提問
70
- 時那一輪已經正常收尾過,這時只會存在於 `devlog.md`,不在
71
- `.devlog/.round-current.md` 裡),就不開新 Round,而是先把 `devlog.md` 裡
72
- 那個 Round 整段搬回 `.devlog/.round-current.md`(`devlog_reopen_last_round`,
69
+ `.awaiting-reply`、且標記的輪次號碼還在 `devlog.md` 裡(提問
70
+ 時那一輪已經正常收尾過,這時只會存在於 `devlog.md`,不在 round 檔裡;
71
+ 其他平台之後併進來的 Round 可能排在它後面,所以是照號碼找,不是看最後一個),就不開新 Round,而是先把 `devlog.md` 裡
72
+ 那個 Round 整段搬回你所在平台的 round 檔(`devlog_reopen_round`,
73
73
  `devlog.md` 那邊同步移除),再改成在那個 Round 的 `### Summary` 之前插入一個
74
74
  新段落:
75
75
 
@@ -57,8 +57,8 @@ DONE
57
57
 
58
58
  主路徑仍是判斷何時寫段落,不是照時間機械切段。另外有一道保底:`/devlog-tracker:start`
59
59
  之後,同一輪若連續 10 分鐘(`max_silent_seconds`,預設 600)都沒改
60
- `.devlog/.round-current.md`(目前開著的這一輪,見 `docs/design/round-current-split.md`),
61
- 下一個工具會被 PreToolUse hook 擋住。被擋時先 **Read** `.devlog/.round-current.md`,再用
60
+ 你所在平台的 round 檔(見 `SKILL.md`「檔案位置」;目前開著的這一輪,見 `docs/design/round-current-split.md`),
61
+ 下一個工具會被 PreToolUse hook 擋住(訊息會寫出確切檔名)。被擋時先 **Read** 那個 round 檔,再用
62
62
  Edit/StrReplace **追加**一段 `### 段落`(一行也可以);**禁止**用 Write 覆寫整份檔。
63
63
  寫了任何內容計時就歸零。不要用 Bash 繞過。沒呼叫工具就不會響。Claude Code
64
64
  dynamic workflow/subagent 的 PreToolUse 若帶非空 `agent_id`,此閥門會跳過(它們
@@ -16,7 +16,7 @@
16
16
  ## 怎麼開一個 span
17
17
 
18
18
  寫完這一輪正常的 Round 區塊(Status 用 `IN_PROGRESS`)之後,使用
19
- `/devlog-tracker:span`(或跑 `span-open.sh`)建立 `.devlog/.span-open`。
19
+ `/devlog-tracker:span`(或跑 `DEVLOG_PLATFORM="<你所在的平台:claude/codex/cursor>" DEVLOG_PROJECT_DIR="<專案根目錄絕對路徑,不要用 $(pwd)>" bash "${DEVLOG_TRACKER_ROOT:-${CLAUDE_PLUGIN_ROOT}}/core/scripts/span-open.sh"`)建立你所在平台的 span 檔(Claude Code 是 `.devlog/.span-open`,Codex/Cursor 是 `.devlog/.span-open@codex`/`.devlog/.span-open@cursor`)。
20
20
  除非腳本不可用,否則不要手寫 JSON。檔案格式如下:
21
21
 
22
22
  ```json
@@ -48,14 +48,21 @@ devlog.md 完全不用動。一旦累積到門檻,Stop hook 會退回正常模
48
48
  整個 Ask 真的做完時:**開一個新的 Round**(不要回頭改寫當初開 span 那個
49
49
  Round),User Input 可以寫「(自動續接收尾,接續 Round 12)」,其餘照 SKILL.md
50
50
  「每一輪的紀錄格式」完整收尾(Summary/Reply/Handoff/Status,Handoff 小節的
51
- 必寫與省略規則相同),內容總結整段 span 做了什麼;然後刪掉 `.devlog/.span-open`。
51
+ 必寫與省略規則相同),內容總結整段 span 做了什麼;然後跑
52
+ `DEVLOG_PLATFORM="<你所在的平台:claude/codex/cursor>" DEVLOG_PROJECT_DIR="<專案根目錄絕對路徑,不要用 $(pwd)>" bash "${DEVLOG_TRACKER_ROOT:-${CLAUDE_PLUGIN_ROOT}}/core/scripts/span-close.sh"`
53
+ 關掉 span(不要手動刪 span 檔)。
54
+
55
+ span 裡自己新開的 Round 編號照 SKILL.md 的規則取(最後一個 `## Round <N>` 加 1)。
56
+ 這種 Round 沒有經過 hook 預留編號,所以併回 devlog.md 時如果編號已經被佔用
57
+ (devlog.md 已有、或另一個平台開著的輪次預留了它),hook 會自動改成下一個
58
+ 空號——之後引用這個 Round 時以 devlog.md 裡的編號為準。
52
59
 
53
60
  ## 已知限制:分辨不出「這是自動續接還是真人插話」
54
61
 
55
62
  Claude Code 目前沒有任何 hook 欄位能分辨一個 tick 是自動排程觸發的,還是使用
56
63
  者真的手動打了新訊息——這兩種在 span 開著時會被一視同仁地當成一個 tick。如果
57
64
  span 開著時你發現進來的其實是一個跟自動任務無關的新請求,應該自己先關掉 span
58
- (刪除 `.span-open`、補寫收尾的 Round)再處理新請求,不要讓它悄悄被吞進正在
65
+ (跑上面那行 `span-close.sh`、補寫收尾的 Round)再處理新請求,不要讓它悄悄被吞進正在
59
66
  開著的 span 裡。
60
67
 
61
68
  ## 崩潰時的風險