devlog-tracker 0.25.1 → 0.29.2
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/README.md +131 -151
- package/README.zh-TW.md +235 -0
- package/claude/hooks.json +75 -0
- package/cli/agents-md.js +15 -8
- package/cli/agents-md.test.js +21 -1
- package/cli/init.js +6 -4
- package/cli/init.test.js +5 -4
- package/cli/merge-hooks.js +5 -2
- package/cli/merge-hooks.test.js +52 -0
- package/cli/platforms/claude.js +55 -0
- package/cli/platforms/claude.test.js +178 -0
- package/cli/platforms/codex.js +6 -18
- package/cli/skills-from-commands.js +32 -0
- package/cli/skills-from-commands.test.js +51 -0
- package/cli/vendor.js +8 -1
- package/cli/vendor.test.js +24 -5
- package/codex/hooks/on-pre-tool.sh +3 -3
- package/codex/hooks/on-session-end.sh +2 -2
- package/codex/hooks/on-session-start.sh +2 -2
- package/codex/hooks/on-stop.sh +3 -3
- package/codex/hooks/on-user-prompt-submit.sh +2 -2
- package/codex/hooks/test-adapters.sh +2 -2
- package/commands/checkpoint.md +2 -2
- package/commands/clean.md +3 -3
- package/commands/compact.md +3 -3
- package/commands/continue.md +4 -4
- package/commands/keep.md +21 -5
- package/commands/lessons-drift.md +4 -4
- package/commands/lessons-off.md +3 -3
- package/commands/lessons-on.md +3 -3
- package/commands/lessons.md +3 -3
- package/commands/overview.md +3 -3
- package/commands/pause.md +3 -3
- package/commands/resume.md +3 -3
- package/commands/search.md +22 -0
- package/commands/segment-watch.md +3 -3
- package/commands/span.md +2 -2
- package/commands/start.md +3 -3
- package/commands/status.md +5 -4
- package/{hooks → core}/scripts/await-open.sh +1 -1
- package/{hooks → core}/scripts/checkpoint-set.sh +1 -1
- package/{hooks → core}/scripts/clean-devlog.sh +2 -1
- package/{hooks → core}/scripts/close-open-round.sh +1 -1
- package/{hooks → core}/scripts/compact-devlog.sh +1 -1
- package/{hooks → core}/scripts/devlog-lock.sh +17 -1
- package/{hooks → core}/scripts/devlog-path.sh +15 -8
- package/{hooks → core}/scripts/enforce-devlog.sh +26 -1
- package/core/scripts/handoff-file.sh +106 -0
- package/{hooks → core}/scripts/keep-move.sh +1 -1
- package/{hooks → core}/scripts/kept-list.sh +1 -1
- package/core/scripts/lessons-advisory-state.sh +51 -0
- package/{hooks → core}/scripts/lessons-append.sh +18 -2
- package/core/scripts/lessons-drift-set.sh +46 -0
- package/{hooks → core}/scripts/lessons-off.sh +1 -1
- package/{hooks → core}/scripts/lessons-on.sh +9 -4
- package/{hooks → core}/scripts/lessons-read.sh +1 -1
- package/{hooks → core}/scripts/on-tool-failure.sh +1 -1
- package/{hooks → core}/scripts/pause-devlog.sh +1 -1
- package/core/scripts/project-dir.sh +19 -0
- package/{hooks → core}/scripts/resume-devlog.sh +1 -1
- package/{hooks → core}/scripts/round-start.sh +52 -17
- package/{hooks → core}/scripts/run-tests.sh +1 -1
- package/core/scripts/search-devlog.sh +63 -0
- package/{hooks → core}/scripts/segment-watch-set.sh +1 -1
- package/{hooks → core}/scripts/segment-watch.sh +1 -1
- package/{hooks → core}/scripts/session-start-devlog.sh +8 -1
- package/{hooks → core}/scripts/span-close.sh +1 -1
- package/{hooks → core}/scripts/span-open.sh +1 -1
- package/{hooks → core}/scripts/start-devlog.sh +1 -1
- package/{hooks → core}/scripts/status-devlog.sh +5 -5
- package/{hooks → core}/scripts/tests/test-clean-devlog.sh +12 -0
- package/core/scripts/tests/test-cli-init-e2e.sh +68 -0
- package/core/scripts/tests/test-devlog-lock.sh +76 -0
- package/{hooks → core}/scripts/tests/test-devlog-path.sh +44 -0
- package/{hooks → core}/scripts/tests/test-enforce-devlog-files.sh +11 -0
- package/core/scripts/tests/test-enforce-devlog-session-handoff.sh +178 -0
- package/{hooks → core}/scripts/tests/test-enforce-devlog-workspace.sh +35 -0
- package/{hooks → core}/scripts/tests/test-enforce-devlog.sh +174 -0
- package/core/scripts/tests/test-handoff-file.sh +98 -0
- package/core/scripts/tests/test-lessons-advisory-state.sh +55 -0
- package/{hooks → core}/scripts/tests/test-lessons-append.sh +18 -0
- package/{hooks → core}/scripts/tests/test-lessons-drift-set.sh +14 -5
- package/{hooks → core}/scripts/tests/test-lessons-on-off.sh +16 -6
- package/core/scripts/tests/test-project-dir.sh +30 -0
- package/{hooks → core}/scripts/tests/test-round-start.sh +247 -13
- package/core/scripts/tests/test-search-devlog.sh +126 -0
- package/{hooks → core}/scripts/tests/test-session-start-devlog.sh +61 -2
- package/{hooks → core}/scripts/tests/test-status-span.sh +3 -3
- package/{hooks → core}/scripts/workspace-snapshot.sh +2 -2
- package/cursor/hooks/on-pre-tool.sh +2 -2
- package/cursor/hooks/on-session-end.sh +2 -2
- package/cursor/hooks/on-session-start.sh +2 -2
- package/cursor/hooks/on-stop.sh +2 -2
- package/cursor/hooks/on-submit-prompt.sh +2 -2
- package/cursor/hooks/on-tool-failure.sh +2 -2
- package/package.json +5 -4
- package/skills/devlog-tracker/SKILL.md +90 -22
- package/skills/devlog-tracker/references/checkpoint-mode.md +21 -6
- package/skills/devlog-tracker/references/contract.md +83 -0
- package/skills/devlog-tracker/references/lessons-mode.md +33 -9
- package/skills/devlog-tracker/references/reply-fold.md +1 -1
- package/hooks/scripts/lessons-drift-set.sh +0 -42
- package/hooks/scripts/tests/test-cli-init-e2e.sh +0 -38
- package/hooks/scripts/tests/test-devlog-lock.sh +0 -37
- /package/{hooks → core}/scripts/detect-pending-question.sh +0 -0
- /package/{hooks → core}/scripts/devlog-md.sh +0 -0
- /package/{hooks → core}/scripts/files-snapshot.sh +0 -0
- /package/{hooks → core}/scripts/json-field.sh +0 -0
- /package/{hooks → core}/scripts/on-session-end.sh +0 -0
- /package/{hooks → core}/scripts/on-stop-failure.sh +0 -0
- /package/{hooks → core}/scripts/redact-prompt.sh +0 -0
- /package/{hooks → core}/scripts/tests/test-await-open.sh +0 -0
- /package/{hooks → core}/scripts/tests/test-branch-scoped-integration.sh +0 -0
- /package/{hooks → core}/scripts/tests/test-checkpoint-set.sh +0 -0
- /package/{hooks → core}/scripts/tests/test-close-open-round.sh +0 -0
- /package/{hooks → core}/scripts/tests/test-compact-devlog.sh +0 -0
- /package/{hooks → core}/scripts/tests/test-devlog-md.sh +0 -0
- /package/{hooks → core}/scripts/tests/test-enforce-devlog-handoff-order.sh +0 -0
- /package/{hooks → core}/scripts/tests/test-files-snapshot.sh +0 -0
- /package/{hooks → core}/scripts/tests/test-json-field.sh +0 -0
- /package/{hooks → core}/scripts/tests/test-keep-move.sh +0 -0
- /package/{hooks → core}/scripts/tests/test-kept-list.sh +0 -0
- /package/{hooks → core}/scripts/tests/test-lessons-read.sh +0 -0
- /package/{hooks → core}/scripts/tests/test-on-interrupt.sh +0 -0
- /package/{hooks → core}/scripts/tests/test-redact-prompt.sh +0 -0
- /package/{hooks → core}/scripts/tests/test-resume-devlog.sh +0 -0
- /package/{hooks → core}/scripts/tests/test-segment-watch-set.sh +0 -0
- /package/{hooks → core}/scripts/tests/test-segment-watch.sh +0 -0
- /package/{hooks → core}/scripts/tests/test-start-pause-devlog.sh +0 -0
- /package/{hooks → core}/scripts/tests/test-workspace-snapshot.sh +0 -0
package/README.md
CHANGED
|
@@ -1,254 +1,234 @@
|
|
|
1
1
|
# devlog-tracker
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
*English | [繁體中文](README.zh-TW.md)*
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**Version** 0.29.2
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Maintains a `.devlog/devlog.md` in your project, turning each conversation round's requests, decisions, and outcomes into a permanent record. A conversation disappears the moment you `/clear` or switch sessions; this file fills that gap so work can pause and resume. Nothing is touched until you explicitly run `/devlog-tracker:start` — installing the plugin alone doesn't create or modify any files.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
## What this is
|
|
10
10
|
|
|
11
|
-
`devlog.md
|
|
11
|
+
Writes "what this round did, what was decided, what's next" into the project's `devlog.md`. A Stop hook guarantees every round is fully written before it's allowed to end; nothing under `.devlog/` is created or changed before an explicit `/devlog-tracker:start`.
|
|
12
12
|
|
|
13
|
-
-
|
|
14
|
-
- 完整逐字過程的真相是對話 transcript(`/clear` 後不存在)
|
|
15
|
-
- 設計決策的真相是 `docs/design/*.md`
|
|
13
|
+
`devlog.md` is only responsible for **cross-session handoff continuity** (the decision trail, current blockers, completion criteria, next steps), and serves as the main entry point for **L1** — after a human-triggered continue or a session-start injection, the agent picks up relying solely on this SSOT, and must **write back** this round's state into this file. It is not the single source of truth for the whole project:
|
|
16
14
|
|
|
17
|
-
|
|
15
|
+
- The source of truth for code/file state is still git
|
|
16
|
+
- The source of truth for the full verbatim process is the conversation transcript (gone after `/clear`)
|
|
17
|
+
- The source of truth for design decisions is `docs/design/*.md`
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
This file simply replaces the gap left by "the terminal clears and it's gone," so work can be interrupted and picked back up at any time. L2 (unattended wake-ups) and L3 (cross-machine shared `.devlog/`) are out of scope; see [`docs/design/devlog-as-ssot-assessment.md`](docs/design/devlog-as-ssot-assessment.md) for details.
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
Every round wraps up with a fixed `Summary`/`Reply` (what was told to the user)/`Handoff` (including `Completion criteria` when unfinished)/`Status`. Picking up work means: check the workspace → do the next step → **write back**; reading without writing counts as a failed handoff.
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
## Install
|
|
24
|
+
|
|
25
|
+
The three platforms are peers, each installed independently; a given project can use one or several, but the same platform should **not** use both the plugin marketplace and `npx init` at once — that fires the hook twice.
|
|
26
|
+
|
|
27
|
+
### Claude Code
|
|
28
|
+
|
|
29
|
+
**Option 1: plugin marketplace (auto-updates)**
|
|
24
30
|
|
|
25
31
|
```
|
|
26
32
|
/plugin marketplace add gogogohuang/devlog-tracker
|
|
27
33
|
/plugin install devlog-tracker@devlog-tracker
|
|
28
34
|
```
|
|
29
35
|
|
|
30
|
-
|
|
36
|
+
Commands are under `/devlog-tracker:*` (e.g. `/devlog-tracker:start`).
|
|
31
37
|
|
|
32
|
-
|
|
38
|
+
**Option 2: npx (vendored into the project, version pinnable)**
|
|
33
39
|
|
|
34
40
|
```bash
|
|
35
|
-
npx devlog-tracker init
|
|
41
|
+
npx devlog-tracker init --claude
|
|
36
42
|
```
|
|
37
43
|
|
|
38
|
-
|
|
44
|
+
Merges the hooks into `.claude/settings.local.json` (not `settings.json` — the merged command paths contain this machine's absolute paths and shouldn't be committed; `settings.local.json` is gitignored by Claude Code by default), and converts `commands/*.md` into `.claude/skills/devlog-<name>/SKILL.md`, invoked with `/devlog-<name>`; it also adds a `<!-- devlog-tracker:begin/end -->` fallback block to `CLAUDE.md`.
|
|
45
|
+
|
|
46
|
+
### Codex
|
|
39
47
|
|
|
40
48
|
```bash
|
|
41
|
-
npx devlog-tracker init --codex
|
|
49
|
+
npx devlog-tracker init --codex
|
|
42
50
|
```
|
|
43
51
|
|
|
44
|
-
|
|
45
|
-
複製進專案的 `.devlog-tracker/`,並把對應平台的 `hooks.json` 合併進專案(不覆蓋
|
|
46
|
-
其他工具已設定的 hook)。重新執行 `npx devlog-tracker init` 可以升級到套件目前的
|
|
47
|
-
版本;`npx devlog-tracker status` 可以查目前裝的版本是否落後。
|
|
52
|
+
Merges the `hooks` from `codex/hooks.json` into the project's `.codex/hooks.json`, and generates `.agents/skills/devlog-<name>/SKILL.md` from `commands/*.md`, invoked with `$devlog-<name>` (or picked from `/skills`); it also adds the same kind of fallback block to `AGENTS.md`. Files the older 0.25.0 version wrote to `.codex/prompts/` are cleared out on the next `init` run — Codex doesn't read project-level custom prompts.
|
|
48
53
|
|
|
49
|
-
|
|
50
|
-
`.agents/skills/devlog-<名稱>/SKILL.md`,例如在 Codex 打 `$devlog-start`(或用 `/skills`
|
|
51
|
-
選)啟動追蹤。舊版(0.25.0)寫到 `.codex/prompts/` 的檔案會在重跑 `init` 時清掉——
|
|
52
|
-
Codex 不讀專案層級的 custom prompts。也會在專案根目錄的
|
|
53
|
-
`AGENTS.md` 加上(或更新)一段以 `<!-- devlog-tracker:begin/end -->` 包住的 fallback
|
|
54
|
-
說明。區塊外的內容不會動,重跑 `init` 只會換掉區塊本身;區塊裡只有相對路徑,可以 commit。
|
|
54
|
+
**Hooks require approval before they run.** Codex requires approval for new or changed hooks; an unapproved hook is silently skipped — **with no warning at all**, so it looks like devlog just isn't recording. This is independent of whether the project is set to `trust_level = "trusted"`; project trust doesn't make hooks active.
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
- Interactive mode: the first time you open it, Codex prompts that hooks need approval; they only run once approved. A later change to hook configuration (e.g. re-running `init` and changing paths or commands) may require approval again.
|
|
57
|
+
- Non-interactive `codex exec` (CI, scripts): unapproved hooks are silently skipped. `--dangerously-bypass-hook-trust` lets them run, but that flag skips trust checks for *all* hooks, so it's only appropriate for automation environments where you've already vetted the hook sources yourself.
|
|
58
|
+
- To confirm it's working: after `start`, send a message and check whether `.devlog/.round-current.md` shows this round's User Input skeleton; if not, the hook didn't run.
|
|
57
59
|
|
|
58
|
-
`
|
|
59
|
-
`.devlog-tracker/env.sh`。如果你把這些檔案 commit 進 git,每位隊友都要在自己的機器上
|
|
60
|
-
跑一次 `npx devlog-tracker init`(路徑每台機器不同);或者改成把 `.devlog-tracker/` 與
|
|
61
|
-
產生出來的 hooks.json 加進 `.gitignore`。
|
|
60
|
+
Codex currently has no equivalent to "user interrupted" (Claude Code's `PostToolUseFailure`/`is_interrupt`) or "this round ended abnormally" (`StopFailure`); these two detailed states won't be marked `INTERRUPTED` on Codex, but the core enforcement mechanism (the `Stop` event blocking unfinished rounds) is unaffected.
|
|
62
61
|
|
|
63
|
-
### Cursor
|
|
62
|
+
### Cursor
|
|
64
63
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
`hooks/scripts/` vendoring 到專案,並調整 command 路徑;兩者的相對目錄必須維持可用。
|
|
64
|
+
```bash
|
|
65
|
+
npx devlog-tracker init --cursor
|
|
66
|
+
```
|
|
69
67
|
|
|
70
|
-
Cursor cloud agent
|
|
71
|
-
hook 仍依 Cursor 支援的事件執行。
|
|
68
|
+
Merges the `hooks` from `cursor/hooks.json` into the project's `.cursor/hooks.json`. Cursor has no slash-command surface, so once hooks are installed, follow the steps in `commands/*.md` to run the corresponding scripts manually. Cursor's cloud agent doesn't run `sessionStart`, so it won't auto-inject a handoff summary; other configured hooks still run on whichever events Cursor supports.
|
|
72
69
|
|
|
73
|
-
|
|
74
|
-
相同的腳本(`commands/*.md` 會優先讀 `CLAUDE_PLUGIN_ROOT`,否則讀
|
|
75
|
-
`DEVLOG_TRACKER_ROOT`):
|
|
70
|
+
### All three platforms
|
|
76
71
|
|
|
77
72
|
```bash
|
|
78
|
-
|
|
79
|
-
export CLAUDE_PROJECT_DIR="$(pwd)"
|
|
80
|
-
bash "$DEVLOG_TRACKER_ROOT/hooks/scripts/start-devlog.sh"
|
|
81
|
-
bash "$DEVLOG_TRACKER_ROOT/hooks/scripts/status-devlog.sh"
|
|
82
|
-
bash "$DEVLOG_TRACKER_ROOT/hooks/scripts/segment-watch-set.sh" 600
|
|
83
|
-
bash "$DEVLOG_TRACKER_ROOT/hooks/scripts/checkpoint-set.sh" 20
|
|
84
|
-
# pause / span-open / span-close / compact / keep-move / clean / resume:見 commands/*.md
|
|
73
|
+
npx devlog-tracker init
|
|
85
74
|
```
|
|
86
75
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
Claude Code 仍是主要安裝方式。若要在 Codex CLI 使用,先設定
|
|
90
|
-
`DEVLOG_TRACKER_ROOT` 為本 plugin 的絕對路徑,再把 `codex/hooks.json` 的
|
|
91
|
-
`hooks` 合併進專案(或 `~/.codex/`)的 `hooks.json`。也可以把整個 `codex/hooks/` 與
|
|
92
|
-
`hooks/scripts/` vendoring 到專案,並調整 command 路徑;兩者的相對目錄必須維持可用。
|
|
93
|
-
|
|
94
|
-
**hook 需要審核才會執行。** Codex 對新增或有變動的 hook 要求先審核;沒核准的 hook 會被
|
|
95
|
-
直接略過,而且**沒有任何警告**,看起來就像 devlog 沒在記錄。這跟專案有沒有設成
|
|
96
|
-
`trust_level = "trusted"` 是兩回事,專案信任不會讓 hook 生效。
|
|
76
|
+
Without `--claude`/`--codex`/`--cursor`, it interactively asks which platform(s) to install; in an environment without a TTY (e.g. CI) and no flags given, `init` skips the prompt and installs all three platforms directly. You can also combine flags, e.g. `npx devlog-tracker init --claude --codex`.
|
|
97
77
|
|
|
98
|
-
-
|
|
99
|
-
有變動(例如重跑 `init` 讓路徑或指令改變)也可能要再核准一次。
|
|
100
|
-
- 非互動的 `codex exec`(CI、腳本):未審核的 hook 會被靜默略過。`--dangerously-bypass-hook-trust`
|
|
101
|
-
可以讓它們跑起來,但那個旗標會略過所有 hook 的信任檢查,只適合已經自己確認過 hook 來源的
|
|
102
|
-
自動化環境。
|
|
103
|
-
- 想確認有沒有生效:`start` 之後送一則訊息,看 `.devlog/.round-current.md` 有沒有出現這一輪的
|
|
104
|
-
User Input skeleton;沒有就代表 hook 沒被執行。
|
|
78
|
+
Copies `core/scripts/`, `claude/hooks.json`, `codex/hooks/`, `cursor/hooks/`, `skills/`, and `commands/` into the project's `.devlog-tracker/`. Re-running `npx devlog-tracker init` upgrades to the package's current version; `npx devlog-tracker status` checks whether the installed version is behind.
|
|
105
79
|
|
|
106
|
-
|
|
107
|
-
`is_interrupt`)與「這輪異常結束」(`StopFailure`)的事件,這兩種細節狀態在
|
|
108
|
-
Codex 上不會被標記成 `INTERRUPTED`;核心強制記錄機制(`Stop` 事件擋住未寫完的
|
|
109
|
-
輪次)不受影響。
|
|
80
|
+
`init` writes this machine's absolute paths into each platform's hooks config and into `.devlog-tracker/env.sh`. If you commit these files to git, each teammate needs to run `npx devlog-tracker init` on their own machine (paths differ per machine); alternatively, add `.devlog-tracker/` and the generated hooks config files to `.gitignore`.
|
|
110
81
|
|
|
111
|
-
|
|
112
|
-
commands 相同的內容。若使用的 Codex 環境沒有載入專案 skills,仍可直接使用以下腳本(`commands/*.md` 會優先讀 `CLAUDE_PLUGIN_ROOT`,否則讀
|
|
113
|
-
`DEVLOG_TRACKER_ROOT`):
|
|
82
|
+
To install manually (without npx), set `DEVLOG_TRACKER_ROOT` to this plugin's absolute path, and merge the `hooks` from the matching platform's `hooks.json` into the project config; `commands/*.md` prefers `DEVLOG_TRACKER_ROOT`, falling back to `CLAUDE_PLUGIN_ROOT`:
|
|
114
83
|
|
|
115
84
|
```bash
|
|
116
85
|
export DEVLOG_TRACKER_ROOT=/absolute/path/to/devlog-tracker
|
|
117
|
-
export
|
|
118
|
-
bash "$DEVLOG_TRACKER_ROOT/
|
|
119
|
-
bash "$DEVLOG_TRACKER_ROOT/
|
|
120
|
-
bash "$DEVLOG_TRACKER_ROOT/
|
|
121
|
-
bash "$DEVLOG_TRACKER_ROOT/
|
|
122
|
-
# pause / span-open / span-close / compact / keep-move / clean / resume
|
|
86
|
+
export DEVLOG_PROJECT_DIR="$(pwd)"
|
|
87
|
+
bash "$DEVLOG_TRACKER_ROOT/core/scripts/start-devlog.sh"
|
|
88
|
+
bash "$DEVLOG_TRACKER_ROOT/core/scripts/status-devlog.sh"
|
|
89
|
+
bash "$DEVLOG_TRACKER_ROOT/core/scripts/segment-watch-set.sh" 600
|
|
90
|
+
bash "$DEVLOG_TRACKER_ROOT/core/scripts/checkpoint-set.sh" 20
|
|
91
|
+
# pause / span-open / span-close / compact / keep-move / clean / resume: see commands/*.md
|
|
123
92
|
```
|
|
124
93
|
|
|
125
|
-
##
|
|
94
|
+
## Quick start
|
|
126
95
|
|
|
127
|
-
|
|
96
|
+
Run once in your project (pick whichever matches your install method):
|
|
128
97
|
|
|
129
98
|
```
|
|
130
|
-
/devlog-tracker:start
|
|
99
|
+
/devlog-tracker:start # Claude Code plugin
|
|
100
|
+
/devlog-start # npx init --claude
|
|
101
|
+
$devlog-start # npx init --codex
|
|
131
102
|
```
|
|
132
103
|
|
|
133
|
-
|
|
104
|
+
After that, just converse normally — every round is enforced-checked and `.devlog/devlog.md` gets updated before it can end. After `/clear`, context is empty; to pick up prior work, run the matching `continue` command. See the command table below for pause, archive, named export, status, and span.
|
|
134
105
|
|
|
135
|
-
##
|
|
106
|
+
## Commands
|
|
136
107
|
|
|
137
|
-
|
|
108
|
+
The table below uses the plugin's `/devlog-tracker:*` namespace; `npx init --claude` installs `/devlog-<name>`, and `npx init --codex` installs `$devlog-<name>` — the command content is the same.
|
|
109
|
+
|
|
110
|
+
| Command | What it does |
|
|
138
111
|
|---|---|
|
|
139
|
-
| `/devlog-tracker:start` |
|
|
140
|
-
| `/devlog-tracker:continue` |
|
|
141
|
-
| `/devlog-tracker:pause` |
|
|
142
|
-
| `/devlog-tracker:compact` |
|
|
143
|
-
| `/devlog-tracker:keep` |
|
|
144
|
-
| `/devlog-tracker:overview` |
|
|
145
|
-
| `/devlog-tracker:
|
|
146
|
-
| `/devlog-tracker:
|
|
147
|
-
| `/devlog-tracker:
|
|
148
|
-
| `/devlog-tracker:
|
|
149
|
-
| `/devlog-tracker:
|
|
150
|
-
| `/devlog-tracker:
|
|
151
|
-
| `/devlog-tracker:
|
|
152
|
-
| `/devlog-tracker:lessons-
|
|
153
|
-
| `/devlog-tracker:lessons
|
|
154
|
-
| `/devlog-tracker:lessons
|
|
155
|
-
|
|
156
|
-
|
|
112
|
+
| `/devlog-tracker:start` | Runs a script that creates `.devlog/.enabled` (missing state files are backfilled; existing thresholds aren't reset). Reads the file to check progress; doesn't auto-start work. `.devlog/` contains a prompt suggesting adding it to `.gitignore`, and only edits it with your consent. |
|
|
113
|
+
| `/devlog-tracker:continue` | Reads `.devlog/devlog.md`, checks the last round's Handoff "Workspace" section, then continues per its next step. Use this after `/clear` to resume. See [`docs/design/continue.md`](docs/design/continue.md). |
|
|
114
|
+
| `/devlog-tracker:pause` | Pauses enforced recording; history files are untouched, and you can `start` again later. |
|
|
115
|
+
| `/devlog-tracker:compact` | A script moves older `DONE` rounds into `devlog.archive.md` (Checkpoints and unfinished rounds stay in the main file). |
|
|
116
|
+
| `/devlog-tracker:keep` | Scans the whole file, groups it by topic, lists suggestions at once, then — after confirmation — moves each section out into its own `devlog.<name>.md` (leaving a `## Kept index` pointer line with a one-sentence topic description in the main file); can also extract a single section or merge everything into one history file. Not the same as compact. See [`docs/design/keep.md`](docs/design/keep.md). |
|
|
117
|
+
| `/devlog-tracker:overview` | Reads all kept `devlog.<name>.md` files and merges them into a cross-topic overview, plus a list of candidate rules that look like they belong in `CLAUDE.md`. Read-only — no workspace check, no confirmation, no writes. See the Kept index section of [`docs/design/keep.md`](docs/design/keep.md). |
|
|
118
|
+
| `/devlog-tracker:search <keyword>` | Case-insensitive string search across `devlog.md`/`devlog.archive.md`/kept `devlog.<name>.md`/`devlog.lessons.<topic>.md`; Claude answers in its own words from the hits (with file/heading/line as evidence). Read-only — no workspace check, no confirmation, no writes. |
|
|
119
|
+
| `/devlog-tracker:resume <name>` | Reads the last round and Handoff of a named saved file, checks the "Workspace" section, and proposes how to continue; new work is still written back to the main `devlog.md`. |
|
|
120
|
+
| `/devlog-tracker:clean` | Unconditionally clears `devlog.md` (including the project summary and all Round history) — no move, no backup, not reversible; it always asks first, and only proceeds once you explicitly reply "clear". Keeps only the currently open round, renumbered as `## Round 1`. |
|
|
121
|
+
| `/devlog-tracker:status` | Shows whether enforced recording is on, Span, Checkpoint, Segment Watch, the Lessons Mode workspace-drift count, and the last round's Status. |
|
|
122
|
+
| `/devlog-tracker:span` | Turns Span Mode on/off, used for auto-continuing long-running tasks (don't hand-edit the `.span-open` JSON). |
|
|
123
|
+
| `/devlog-tracker:segment-watch <duration>` | Adjusts Segment Watch's silence threshold (default 10 minutes). Reports `NOT_STARTED` and creates no files if the project hasn't run `/devlog-tracker:start`. |
|
|
124
|
+
| `/devlog-tracker:checkpoint <rounds>` | Adjusts Checkpoint Mode's silence threshold (default 20 rounds). Reports `NOT_STARTED` if the project hasn't started. |
|
|
125
|
+
| `/devlog-tracker:lessons-on` | Turns on Lessons Mode, which is off by default (subordinate to the main switch; refuses if `start` hasn't run). See [`docs/design/lessons-mode.md`](docs/design/lessons-mode.md). |
|
|
126
|
+
| `/devlog-tracker:lessons-off` | Turns off Lessons Mode; doesn't touch any already-written `devlog.lessons.*.md` files or the index. |
|
|
127
|
+
| `/devlog-tracker:lessons [<topic>]` | No topic given: prints the `## Lessons index`. Topic given: prints that topic file's full content. Read-only — no workspace check, no confirmation. |
|
|
128
|
+
| `/devlog-tracker:lessons-drift <count>` | Adjusts the threshold for Lessons Mode's "recurring workspace drift" mechanical reminder (default 3). Subordinate to Lessons Mode; reports `LESSONS_NOT_ENABLED` if it's off. |
|
|
129
|
+
|
|
130
|
+
## Once enforced recording is on
|
|
157
131
|
|
|
158
132
|
```mermaid
|
|
159
133
|
sequenceDiagram
|
|
160
|
-
participant U as
|
|
134
|
+
participant U as User
|
|
161
135
|
participant H as Hooks
|
|
162
136
|
participant C as Claude
|
|
163
137
|
participant D as .devlog/devlog.md
|
|
164
138
|
|
|
165
|
-
U->>H:
|
|
166
|
-
H->>D:
|
|
167
|
-
C->>D:
|
|
168
|
-
C->>H:
|
|
169
|
-
alt
|
|
170
|
-
H-->>C:
|
|
171
|
-
else
|
|
172
|
-
H-->>C:
|
|
139
|
+
U->>H: Send message
|
|
140
|
+
H->>D: Write the Round skeleton first (User Input + IN_PROGRESS)
|
|
141
|
+
C->>D: Fill in Summary / Reply / Handoff, update Status
|
|
142
|
+
C->>H: This round wants to end
|
|
143
|
+
alt Not written, headings empty, or Status invalid
|
|
144
|
+
H-->>C: Block, require completion
|
|
145
|
+
else Fully written
|
|
146
|
+
H-->>C: Allow
|
|
173
147
|
end
|
|
174
148
|
```
|
|
175
149
|
|
|
176
|
-
|
|
150
|
+
Every round has these fixed sections:
|
|
177
151
|
|
|
178
|
-
- **`User Input`** —
|
|
179
|
-
- **`Summary`** —
|
|
180
|
-
- **`Reply`** —
|
|
181
|
-
- **`Handoff`** —
|
|
182
|
-
- **`Status`** — `DONE` / `IN_PROGRESS` / `BLOCKED` / `INTERRUPTED`
|
|
152
|
+
- **`User Input`** — the raw submitted text takes priority (written by the hook; Claude shouldn't rewrite it), common tokens are masked
|
|
153
|
+
- **`Summary`** — a conclusion a human can scan
|
|
154
|
+
- **`Reply`** — what was said/promised to the user this round
|
|
155
|
+
- **`Handoff`** — for the next round to pick up (decisions / files / workspace / current state / completion criteria / next steps)
|
|
156
|
+
- **`Status`** — one of `DONE` / `IN_PROGRESS` / `BLOCKED` / `INTERRUPTED`
|
|
183
157
|
|
|
184
|
-
|
|
158
|
+
"Workspace" is a git snapshot taken at wrap-up time; required whenever in progress or blocked. `DONE` also requires it if "Files" has content (claiming files were touched/committed). "Completion criteria" is required whenever in progress or blocked.
|
|
185
159
|
|
|
186
|
-
Stop hook
|
|
160
|
+
The Stop hook does the following:
|
|
187
161
|
|
|
188
|
-
1.
|
|
189
|
-
2.
|
|
190
|
-
3.
|
|
162
|
+
1. Confirms `Summary`/`Reply`/`Handoff` headings have content underneath, and Status is one of the four values above; Handoff subsections must be in the order Decisions → Files → Workspace → Current state → Completion criteria → Next steps
|
|
163
|
+
2. In-progress/blocked rounds must have "Completion criteria" and "Next steps"; "Next steps" can't be pure blacklisted filler (e.g. a section that just says "continue finishing up" — string matching, not semantic scoring; see [`docs/design/next-step-blacklist.md`](docs/design/next-step-blacklist.md)); in-progress rounds get an additional lightweight actionability check; blocked rounds require "Current state" or "Next steps" to contain a missing-piece phrasing
|
|
164
|
+
3. Machine-verifies that "Workspace" matches the actual git state at wrap-up time, verbatim (always checked when in progress/blocked; only checked for `DONE` when "Files" is non-empty) — this catches claims like "already committed" that don't actually match reality
|
|
191
165
|
|
|
192
|
-
`####
|
|
166
|
+
When `#### Files` is non-empty, it's likewise machine-verified: the commit section must match that commit's actual content verbatim; for uncommitted sections, it only requires that the claimed paths actually have changes (not full coverage, so leftovers from a previous round aren't counted as missing from this one).
|
|
193
167
|
|
|
194
|
-
|
|
168
|
+
See [`docs/design/summary-handoff.md`](docs/design/summary-handoff.md), [`docs/design/devlog-as-ssot-assessment.md`](docs/design/devlog-as-ssot-assessment.md), [`docs/design/files-verify.md`](docs/design/files-verify.md), and SKILL.md for details.
|
|
195
169
|
|
|
196
|
-
##
|
|
170
|
+
## What the hooks do automatically
|
|
197
171
|
|
|
198
|
-
|
|
172
|
+
The normal rule is "one user message = one round, and Summary/Reply/Handoff/Status must be fully written before it ends." The four mechanisms below each relax a different slice of that rule; they're orthogonal and can coexist:
|
|
199
173
|
|
|
200
|
-
|
|
|
174
|
+
| Mechanism | What it relaxes | What problem it solves |
|
|
201
175
|
|---|---|---|
|
|
202
|
-
| **Span Mode** |
|
|
203
|
-
| **Checkpoint Mode** |
|
|
204
|
-
| **Reply Fold** |
|
|
205
|
-
| **Segment Watch** |
|
|
176
|
+
| **Span Mode** | Whether each automatic wake-up counts as a round | Long-running tasks driven by their own schedule (`/loop`, Workflow) rather than a user typing — forcing a full Round on every automatic tick produces a flood of meaningless records, or even stalls the whole automation |
|
|
177
|
+
| **Checkpoint Mode** | Whether there's a cross-round summary waypoint | Normal interactive conversation writes every round fine, but once the round count grows, reviewers have to crawl through every round to see overall progress; each checkpoint uses a fixed **Decisions / Open questions / Failed attempts** layout so SessionStart injection surfaces blockers quickly |
|
|
178
|
+
| **Reply Fold** | Whether a question-and-answer counts as two rounds | When Claude ends with a plain-text question and the next message is really the answer, the default logic (every `UserPromptSubmit` opens a new Round) would hard-split that Q&A into two unrelated rounds |
|
|
179
|
+
| **Segment Watch** | Whether a round leaves intermediate traces internally | A round that takes a long time (explore, then decide, then implement, then verify) and only writes once at the very end loses the whole process if it crashes partway |
|
|
206
180
|
|
|
207
|
-
|
|
181
|
+
Here's how each mechanism actually behaves when triggered:
|
|
208
182
|
|
|
209
|
-
####
|
|
183
|
+
#### Auto-continue
|
|
210
184
|
|
|
211
|
-
`SessionStart` hook
|
|
185
|
+
The `SessionStart` hook, on new session / resume / `/compact` / `/fork`, first injects the branch-scoped `.devlog/handoff.md` snapshot when non-empty, then the last Checkpoint (if any — including its `### 待解問題` section for open blockers), the `## Kept index` (if any — not the named files' content), plus the last two rounds' Summary / Handoff / Status — not the whole file. Stop overwrites the handoff file on `IN_PROGRESS`/`BLOCKED` closes and deletes it on `DONE`. `/clear` truly clears everything and injects nothing; to continue, use `/devlog-tracker:continue` (which checks "Workspace" first, then proceeds). See [`docs/design/continue.md`](docs/design/continue.md) and [`docs/design/session-handoff-file.md`](docs/design/session-handoff-file.md).
|
|
212
186
|
|
|
213
|
-
####
|
|
187
|
+
#### Same-round workspace-drift detection
|
|
214
188
|
|
|
215
|
-
|
|
189
|
+
When the next message in the same conversation is sent, `UserPromptSubmit` compares the previous round's Handoff "Workspace" against the current git state; on a mismatch, it injects a notice and has `PreToolUse` block non-devlog tools until this round adds a `### Segment` containing an actual snapshot (read-only `git status`/`diff`/`log`/`show`/`rev-parse` are unaffected, so you can check for yourself). Quiet Span ticks, task-notifications, and `DONE` aren't blocked. See [`docs/design/continue.md`](docs/design/continue.md) and [`docs/design/segment-watch.md`](docs/design/segment-watch.md).
|
|
216
190
|
|
|
217
|
-
####
|
|
191
|
+
#### Unexpected interruption
|
|
218
192
|
|
|
219
|
-
|
|
193
|
+
Non-usage API errors, SessionEnd, and a leftover `.round-open` mark an open Round as `INTERRUPTED`. Running out of usage doesn't count as an interruption. A mid-task cancel (e.g. Esc) is usually only recorded on the **next message** or the **next SessionStart** (startup / resume / clear / fork); `PostToolUseFailure`'s `is_interrupt`, when it fires, is best-effort only and can't be relied on to stamp this immediately. A `[reason: ...]` internal code is appended below `Status` for later debugging (e.g. `dangling:next_prompt`); if the interruption happened while waiting on an `AskUserQuestion` answer, Summary/Handoff will say so directly rather than being recorded as an "unexpected" interruption. See [`docs/design/recording-moments.md`](docs/design/recording-moments.md).
|
|
220
194
|
|
|
221
|
-
####
|
|
195
|
+
#### Segment recording
|
|
222
196
|
|
|
223
|
-
|
|
197
|
+
Don't hold a long round until the very end — write `### Segment` entries as you go. If `.round-current.md` hasn't been touched for about 10 minutes within the same round, the `PreToolUse` hook blocks the next tool call; Read first, then Edit/StrReplace to append a segment (don't Write over the whole file). The threshold is adjustable with `/devlog-tracker:segment-watch <duration>`. Claude Code subagents/dynamic workflows (`PreToolUse` carrying `agent_id`) don't apply this gate from the parent round. See [`docs/design/segment-watch.md`](docs/design/segment-watch.md).
|
|
224
198
|
|
|
225
199
|
#### Checkpoint Mode
|
|
226
200
|
|
|
227
|
-
|
|
201
|
+
After roughly 20 rounds without a cross-round summary, the `Stop` hook requires a new `## Checkpoint(Round X-Y)` block (threshold adjustable). Content is structured, not free prose — three subsections under the heading:
|
|
202
|
+
|
|
203
|
+
- **`### 決策`** — decisions made in that stretch
|
|
204
|
+
- **`### 待解問題`** — still-open blockers (primary handoff cue for the next session)
|
|
205
|
+
- **`### 失敗嘗試`** — approaches tried and abandoned, so the next agent doesn't repeat them
|
|
206
|
+
|
|
207
|
+
Hook detection is unchanged (only the `## Checkpoint` heading is verified, not subsection quality). Authoring rules: [`skills/devlog-tracker/references/checkpoint-mode.md`](skills/devlog-tracker/references/checkpoint-mode.md); design: [`docs/design/checkpoint-mode.md`](docs/design/checkpoint-mode.md).
|
|
228
208
|
|
|
229
209
|
#### Span Mode
|
|
230
210
|
|
|
231
|
-
`/loop
|
|
211
|
+
Long-running auto-continuing tasks (`/loop`, Workflow) don't need a full Round on every tick; a tick counter acts as the safety valve, so a crash loses at most a fixed number of ticks, not the whole span. See [`docs/design/span-mode.md`](docs/design/span-mode.md).
|
|
232
212
|
|
|
233
213
|
#### Reply Fold
|
|
234
214
|
|
|
235
|
-
Claude
|
|
215
|
+
When Claude ends a turn with a plain-text question and the next message is the answer, there's no need to open a new Round — record the question text manually first, run `await-open.sh` to mark it, and the next message (the answer) automatically folds into the same Round as a `### Segment`, instead of splitting into two unrelated Rounds. During a long back-and-forth (e.g. grilling), only the question is logged per turn mid-way; Summary/Reply/Handoff/Status don't need to be rewritten every turn — wrap up once when the whole Q&A actually ends. `AskUserQuestion` asks and answers within the same turn, so it doesn't need folding, but still records the question and answer in a `### Segment (AskUserQuestion)`. Background task-notifications (subagent completion notices) also go through this same folding mechanism automatically, keeping only a condensed summary rather than the raw XML. See [`docs/design/reply-fold.md`](docs/design/reply-fold.md).
|
|
236
216
|
|
|
237
|
-
####
|
|
217
|
+
#### Per-branch devlog files
|
|
238
218
|
|
|
239
|
-
|
|
219
|
+
Switching branches within the same working directory automatically splits the main file by the checked-out branch: `main`/`master` keeps using `.devlog/devlog.md`, while other branches each use `.devlog/devlog.<branch>.md` (slashes converted to `-`). A separate `git worktree` (a different directory) already has its own independent `.devlog/` and is unaffected by this mechanism. The first time a branch is detected without its own file while `devlog.md` already has content, it gets renamed (not copied) into that branch's file. See [`docs/design/branch-scoped-devlog.md`](docs/design/branch-scoped-devlog.md).
|
|
240
220
|
|
|
241
|
-
#### Lessons Mode
|
|
221
|
+
#### Lessons Mode (off by default, not automatic)
|
|
242
222
|
|
|
243
|
-
|
|
223
|
+
When enabled, a development-lesson entry is only considered when a `BLOCKED` status resolves, an obvious detour happens, or workspace drift accumulates to a threshold (default 3, adjustable via `/devlog-tracker:lessons-drift <count>`); it's stored per-topic as `devlog.lessons.<topic>.md`, with `devlog.md` keeping only a heading index. None of the three signals are enforced by a hook themselves, and this isn't a knowledge base (architectural decisions still live in `docs/design/*.md`). See [`docs/design/lessons-mode.md`](docs/design/lessons-mode.md).
|
|
244
224
|
|
|
245
|
-
##
|
|
225
|
+
## Tests
|
|
246
226
|
|
|
247
227
|
```
|
|
248
|
-
bash
|
|
228
|
+
bash core/scripts/run-tests.sh
|
|
249
229
|
```
|
|
250
230
|
|
|
251
|
-
|
|
231
|
+
Includes the Cursor adapter.
|
|
252
232
|
|
|
253
233
|
## License
|
|
254
234
|
|