devlog-tracker 0.27.0 → 0.30.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/README.md +109 -100
- package/README.zh-TW.md +235 -0
- package/claude/hooks.json +21 -0
- package/cli/agents-md.js +1 -0
- package/commands/keep.md +18 -2
- package/commands/lessons-drift.md +2 -2
- package/commands/search.md +22 -0
- package/commands/status.md +2 -1
- package/core/scripts/clean-devlog.sh +1 -0
- package/core/scripts/devlog-lock.sh +17 -1
- package/core/scripts/devlog-path.sh +15 -8
- package/core/scripts/enforce-devlog.sh +25 -0
- package/core/scripts/handoff-file.sh +106 -0
- package/core/scripts/lessons-advisory-state.sh +51 -0
- package/core/scripts/lessons-append.sh +16 -0
- package/core/scripts/lessons-drift-set.sh +14 -10
- package/core/scripts/lessons-on.sh +8 -3
- package/core/scripts/lessons-subagent-done.sh +36 -0
- package/core/scripts/lessons-subagent-start.sh +36 -0
- package/core/scripts/round-start.sh +65 -16
- package/core/scripts/search-devlog.sh +63 -0
- package/core/scripts/session-start-devlog.sh +7 -0
- package/core/scripts/status-devlog.sh +4 -4
- package/core/scripts/tests/test-clean-devlog.sh +12 -0
- package/core/scripts/tests/test-devlog-lock.sh +39 -0
- package/core/scripts/tests/test-devlog-path.sh +44 -0
- package/core/scripts/tests/test-enforce-devlog-files.sh +11 -0
- package/core/scripts/tests/test-enforce-devlog-session-handoff.sh +178 -0
- package/core/scripts/tests/test-enforce-devlog-workspace.sh +35 -0
- package/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/core/scripts/tests/test-lessons-append.sh +18 -0
- package/core/scripts/tests/test-lessons-drift-set.sh +14 -5
- package/core/scripts/tests/test-lessons-on-off.sh +16 -6
- package/core/scripts/tests/test-lessons-subagent-hooks.sh +95 -0
- package/core/scripts/tests/test-round-start.sh +296 -13
- package/core/scripts/tests/test-search-devlog.sh +126 -0
- package/core/scripts/tests/test-session-start-devlog.sh +59 -0
- package/core/scripts/tests/test-status-span.sh +3 -3
- package/package.json +2 -2
- package/skills/devlog-tracker/SKILL.md +83 -13
- 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 +38 -8
package/README.md
CHANGED
|
@@ -1,45 +1,47 @@
|
|
|
1
1
|
# devlog-tracker
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
*English | [繁體中文](README.zh-TW.md)*
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**Version** 0.30.0
|
|
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.
|
|
24
26
|
|
|
25
27
|
### Claude Code
|
|
26
28
|
|
|
27
|
-
|
|
29
|
+
**Option 1: plugin marketplace (auto-updates)**
|
|
28
30
|
|
|
29
31
|
```
|
|
30
32
|
/plugin marketplace add gogogohuang/devlog-tracker
|
|
31
33
|
/plugin install devlog-tracker@devlog-tracker
|
|
32
34
|
```
|
|
33
35
|
|
|
34
|
-
|
|
36
|
+
Commands are under `/devlog-tracker:*` (e.g. `/devlog-tracker:start`).
|
|
35
37
|
|
|
36
|
-
|
|
38
|
+
**Option 2: npx (vendored into the project, version pinnable)**
|
|
37
39
|
|
|
38
40
|
```bash
|
|
39
41
|
npx devlog-tracker init --claude
|
|
40
42
|
```
|
|
41
43
|
|
|
42
|
-
|
|
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`.
|
|
43
45
|
|
|
44
46
|
### Codex
|
|
45
47
|
|
|
@@ -47,15 +49,15 @@ npx devlog-tracker init --claude
|
|
|
47
49
|
npx devlog-tracker init --codex
|
|
48
50
|
```
|
|
49
51
|
|
|
50
|
-
|
|
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.
|
|
51
53
|
|
|
52
|
-
**
|
|
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.
|
|
53
55
|
|
|
54
|
-
-
|
|
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
|
-
Codex
|
|
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.
|
|
59
61
|
|
|
60
62
|
### Cursor
|
|
61
63
|
|
|
@@ -63,21 +65,21 @@ Codex 目前沒有對應「使用者中斷」(Claude Code 的 `PostToolUseFail
|
|
|
63
65
|
npx devlog-tracker init --cursor
|
|
64
66
|
```
|
|
65
67
|
|
|
66
|
-
|
|
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.
|
|
67
69
|
|
|
68
|
-
###
|
|
70
|
+
### All three platforms
|
|
69
71
|
|
|
70
72
|
```bash
|
|
71
73
|
npx devlog-tracker init
|
|
72
74
|
```
|
|
73
75
|
|
|
74
|
-
|
|
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`.
|
|
75
77
|
|
|
76
|
-
|
|
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.
|
|
77
79
|
|
|
78
|
-
`init`
|
|
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`.
|
|
79
81
|
|
|
80
|
-
|
|
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`:
|
|
81
83
|
|
|
82
84
|
```bash
|
|
83
85
|
export DEVLOG_TRACKER_ROOT=/absolute/path/to/devlog-tracker
|
|
@@ -86,12 +88,12 @@ bash "$DEVLOG_TRACKER_ROOT/core/scripts/start-devlog.sh"
|
|
|
86
88
|
bash "$DEVLOG_TRACKER_ROOT/core/scripts/status-devlog.sh"
|
|
87
89
|
bash "$DEVLOG_TRACKER_ROOT/core/scripts/segment-watch-set.sh" 600
|
|
88
90
|
bash "$DEVLOG_TRACKER_ROOT/core/scripts/checkpoint-set.sh" 20
|
|
89
|
-
# pause / span-open / span-close / compact / keep-move / clean / resume
|
|
91
|
+
# pause / span-open / span-close / compact / keep-move / clean / resume: see commands/*.md
|
|
90
92
|
```
|
|
91
93
|
|
|
92
|
-
##
|
|
94
|
+
## Quick start
|
|
93
95
|
|
|
94
|
-
|
|
96
|
+
Run once in your project (pick whichever matches your install method):
|
|
95
97
|
|
|
96
98
|
```
|
|
97
99
|
/devlog-tracker:start # Claude Code plugin
|
|
@@ -99,127 +101,134 @@ bash "$DEVLOG_TRACKER_ROOT/core/scripts/checkpoint-set.sh" 20
|
|
|
99
101
|
$devlog-start # npx init --codex
|
|
100
102
|
```
|
|
101
103
|
|
|
102
|
-
|
|
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.
|
|
103
105
|
|
|
104
|
-
##
|
|
106
|
+
## Commands
|
|
105
107
|
|
|
106
|
-
|
|
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.
|
|
107
109
|
|
|
108
|
-
|
|
|
110
|
+
| Command | What it does |
|
|
109
111
|
|---|---|
|
|
110
|
-
| `/devlog-tracker:start` |
|
|
111
|
-
| `/devlog-tracker:continue` |
|
|
112
|
-
| `/devlog-tracker:pause` |
|
|
113
|
-
| `/devlog-tracker:compact` |
|
|
114
|
-
| `/devlog-tracker:keep` |
|
|
115
|
-
| `/devlog-tracker:overview` |
|
|
116
|
-
| `/devlog-tracker:
|
|
117
|
-
| `/devlog-tracker:
|
|
118
|
-
| `/devlog-tracker:
|
|
119
|
-
| `/devlog-tracker:
|
|
120
|
-
| `/devlog-tracker:
|
|
121
|
-
| `/devlog-tracker:
|
|
122
|
-
| `/devlog-tracker:
|
|
123
|
-
| `/devlog-tracker:lessons-
|
|
124
|
-
| `/devlog-tracker:lessons
|
|
125
|
-
| `/devlog-tracker:lessons
|
|
126
|
-
|
|
127
|
-
|
|
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
|
|
128
131
|
|
|
129
132
|
```mermaid
|
|
130
133
|
sequenceDiagram
|
|
131
|
-
participant U as
|
|
134
|
+
participant U as User
|
|
132
135
|
participant H as Hooks
|
|
133
136
|
participant C as Claude
|
|
134
137
|
participant D as .devlog/devlog.md
|
|
135
138
|
|
|
136
|
-
U->>H:
|
|
137
|
-
H->>D:
|
|
138
|
-
C->>D:
|
|
139
|
-
C->>H:
|
|
140
|
-
alt
|
|
141
|
-
H-->>C:
|
|
142
|
-
else
|
|
143
|
-
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
|
|
144
147
|
end
|
|
145
148
|
```
|
|
146
149
|
|
|
147
|
-
|
|
150
|
+
Every round has these fixed sections:
|
|
148
151
|
|
|
149
|
-
- **`User Input`** —
|
|
150
|
-
- **`Summary`** —
|
|
151
|
-
- **`Reply`** —
|
|
152
|
-
- **`Handoff`** —
|
|
153
|
-
- **`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`
|
|
154
157
|
|
|
155
|
-
|
|
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.
|
|
156
159
|
|
|
157
|
-
Stop hook
|
|
160
|
+
The Stop hook does the following:
|
|
158
161
|
|
|
159
|
-
1.
|
|
160
|
-
2.
|
|
161
|
-
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
|
|
162
165
|
|
|
163
|
-
`####
|
|
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).
|
|
164
167
|
|
|
165
|
-
|
|
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.
|
|
166
169
|
|
|
167
|
-
##
|
|
170
|
+
## What the hooks do automatically
|
|
168
171
|
|
|
169
|
-
|
|
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:
|
|
170
173
|
|
|
171
|
-
|
|
|
174
|
+
| Mechanism | What it relaxes | What problem it solves |
|
|
172
175
|
|---|---|---|
|
|
173
|
-
| **Span Mode** |
|
|
174
|
-
| **Checkpoint Mode** |
|
|
175
|
-
| **Reply Fold** |
|
|
176
|
-
| **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 |
|
|
177
180
|
|
|
178
|
-
|
|
181
|
+
Here's how each mechanism actually behaves when triggered:
|
|
179
182
|
|
|
180
|
-
####
|
|
183
|
+
#### Auto-continue
|
|
181
184
|
|
|
182
|
-
`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).
|
|
183
186
|
|
|
184
|
-
####
|
|
187
|
+
#### Same-round workspace-drift detection
|
|
185
188
|
|
|
186
|
-
|
|
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).
|
|
187
190
|
|
|
188
|
-
####
|
|
191
|
+
#### Unexpected interruption
|
|
189
192
|
|
|
190
|
-
|
|
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).
|
|
191
194
|
|
|
192
|
-
####
|
|
195
|
+
#### Segment recording
|
|
193
196
|
|
|
194
|
-
|
|
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).
|
|
195
198
|
|
|
196
199
|
#### Checkpoint Mode
|
|
197
200
|
|
|
198
|
-
|
|
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).
|
|
199
208
|
|
|
200
209
|
#### Span Mode
|
|
201
210
|
|
|
202
|
-
`/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).
|
|
203
212
|
|
|
204
213
|
#### Reply Fold
|
|
205
214
|
|
|
206
|
-
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).
|
|
207
216
|
|
|
208
|
-
####
|
|
217
|
+
#### Per-branch devlog files
|
|
209
218
|
|
|
210
|
-
|
|
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).
|
|
211
220
|
|
|
212
|
-
#### Lessons Mode
|
|
221
|
+
#### Lessons Mode (off by default, not automatic)
|
|
213
222
|
|
|
214
|
-
|
|
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. On Claude Code, subagents and Workflow agents get the `lessons-append.sh` usage (with absolute paths, so worktree isolation is safe) injected at `SubagentStart` and may record an entry themselves; when a subagent returns or a background task-notification arrives, the main session sees a `[Lessons Mode 提示]` advisory (`failed`/`killed` also count toward the shared counter). None of these signals enforce writing an entry, 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).
|
|
215
224
|
|
|
216
|
-
##
|
|
225
|
+
## Tests
|
|
217
226
|
|
|
218
227
|
```
|
|
219
228
|
bash core/scripts/run-tests.sh
|
|
220
229
|
```
|
|
221
230
|
|
|
222
|
-
|
|
231
|
+
Includes the Cursor adapter.
|
|
223
232
|
|
|
224
233
|
## License
|
|
225
234
|
|