hmem-mcp 5.0.0 → 5.1.21

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 (43) hide show
  1. package/README.md +161 -214
  2. package/dist/cli-checkpoint.js +102 -40
  3. package/dist/cli-checkpoint.js.map +1 -1
  4. package/dist/cli-context-inject.d.ts +7 -6
  5. package/dist/cli-context-inject.js +27 -130
  6. package/dist/cli-context-inject.js.map +1 -1
  7. package/dist/cli-env.d.ts +16 -0
  8. package/dist/cli-env.js +40 -0
  9. package/dist/cli-env.js.map +1 -0
  10. package/dist/cli-hook-startup.d.ts +20 -0
  11. package/dist/cli-hook-startup.js +101 -0
  12. package/dist/cli-hook-startup.js.map +1 -0
  13. package/dist/cli-init.js +97 -188
  14. package/dist/cli-init.js.map +1 -1
  15. package/dist/cli-log-exchange.js +63 -3
  16. package/dist/cli-log-exchange.js.map +1 -1
  17. package/dist/cli-statusline.d.ts +14 -0
  18. package/dist/cli-statusline.js +172 -0
  19. package/dist/cli-statusline.js.map +1 -0
  20. package/dist/cli.js +18 -2
  21. package/dist/cli.js.map +1 -1
  22. package/dist/hmem-config.d.ts +10 -0
  23. package/dist/hmem-config.js +63 -13
  24. package/dist/hmem-config.js.map +1 -1
  25. package/dist/hmem-store.d.ts +30 -1
  26. package/dist/hmem-store.js +219 -48
  27. package/dist/hmem-store.js.map +1 -1
  28. package/dist/mcp-server.js +202 -75
  29. package/dist/mcp-server.js.map +1 -1
  30. package/package.json +1 -1
  31. package/scripts/autoresearch-nightly.sh +84 -0
  32. package/scripts/hmem-statusline.sh +4 -0
  33. package/skills/hmem-config/SKILL.md +112 -147
  34. package/skills/hmem-curate/SKILL.md +56 -6
  35. package/skills/hmem-new-project/SKILL.md +164 -0
  36. package/skills/hmem-read/SKILL.md +174 -146
  37. package/skills/hmem-release/SKILL.md +141 -0
  38. package/skills/hmem-self-curate/SKILL.md +49 -7
  39. package/skills/hmem-setup/SKILL.md +169 -87
  40. package/skills/hmem-sync-setup/SKILL.md +16 -3
  41. package/skills/hmem-update/SKILL.md +254 -0
  42. package/skills/hmem-wipe/SKILL.md +47 -21
  43. package/skills/hmem-write/SKILL.md +38 -14
@@ -0,0 +1,254 @@
1
+ ---
2
+ name: hmem-update
3
+ description: >
4
+ Post-update checklist for hmem-mcp and hmem-sync. Run after npm update or when
5
+ hmem detects a version change. Covers skill sync, entry migration, schema enforcement,
6
+ O-entry curation, and smoke tests. Use when the user says "update hmem", "hmem updaten",
7
+ or when the startup version-check detects a new version.
8
+ ---
9
+
10
+ # /hmem-update — Post-Update Checklist
11
+
12
+ Run this after updating hmem-mcp or hmem-sync. Every step is important — do not skip steps.
13
+
14
+ ---
15
+
16
+ ## Step 1: Version Check
17
+
18
+ Determine what changed:
19
+
20
+ ```bash
21
+ hmem --version # current installed version
22
+ npm view hmem-mcp version # latest on npm
23
+ npm view hmem-mcp versions --json # all versions
24
+ ```
25
+
26
+ Read the changelog for the version range:
27
+ ```bash
28
+ cd ~/projects/hmem && git log --oneline <old-tag>..HEAD # if local repo exists
29
+ ```
30
+
31
+ Or check GitHub releases: `gh release list -R Bumblebiber/hmem --limit 5`
32
+
33
+ **If already on latest:** Tell the user and skip to Step 7 (smoke test).
34
+
35
+ ---
36
+
37
+ ## Step 2: Update Skills
38
+
39
+ ```bash
40
+ hmem update-skills
41
+ ```
42
+
43
+ This syncs all skill files from the npm package to the local skills directory. Verify:
44
+
45
+ ```bash
46
+ ls ~/.claude/skills/hmem-*/SKILL.md # Claude Code
47
+ ls ~/.config/gemini/skills/hmem-*/ # Gemini CLI (if applicable)
48
+ ```
49
+
50
+ Check for new skills that weren't there before — inform the user about new capabilities.
51
+
52
+ ---
53
+
54
+ ## Step 2b: Verify Hooks
55
+
56
+ Hooks are critical — without them, O-entries are never logged and auto-checkpoints never fire.
57
+
58
+ Check the current hook configuration:
59
+ ```bash
60
+ cat ~/.claude/settings.json | grep -A5 hooks
61
+ ```
62
+
63
+ **Required hooks (for `checkpointMode: "auto"`):**
64
+ - **UserPromptSubmit** — memory load + checkpoint reminder
65
+ - **Stop** — exchange logging (`hmem log-exchange`) + O-entry title generation
66
+ - **SessionStart[clear]** — context re-injection after `/clear`
67
+
68
+ **If hooks are missing or empty (`hooks: {}`):**
69
+ 1. Inform the user: "Hooks are not configured — O-entries won't be logged and auto-checkpoints won't fire."
70
+ 2. Suggest: "Run `/hmem-config` to set up hooks, or run `hmem init` to re-initialize."
71
+
72
+ **If hooks exist but reference old paths or scripts:**
73
+ - Check that hook scripts exist and are executable
74
+ - Verify they reference the current hmem installation path
75
+
76
+ ---
77
+
78
+ ## Step 2c: Check load_project Display Config
79
+
80
+ Since v5.1.8, `load_project` supports configurable section expansion:
81
+ - `loadProjectExpand.withBody`: sections showing L3 title + body (default: `[1]` = Overview)
82
+ - `loadProjectExpand.withChildren`: sections listing all L3 children as titles (default: `[6, 8]` = Bugs, Open Tasks)
83
+
84
+ Check if the user has customized this in `hmem.config.json`. If not, inform them about the option:
85
+ ```json
86
+ { "memory": { "loadProjectExpand": { "withBody": [1], "withChildren": [6, 8] } } }
87
+ ```
88
+
89
+ ---
90
+
91
+ ## Step 3: Entry Migration
92
+
93
+ Some versions introduce new data formats. Check if migration is needed:
94
+
95
+ **v5.1.0+ Title/Body Separation:**
96
+ - Entries now support `>` body lines (title shown in listings, body on drill-down)
97
+ - Check if old entries need title/body split:
98
+ ```
99
+ read_memory(titles_only=true)
100
+ ```
101
+ - Look for entries where the title is truncated mid-word or contains too much detail
102
+ - Fix with: `update_memory(id="L0042", content="Clear title\n> Detailed body text")`
103
+
104
+ **v5.1.2+ Checkpoint Summaries:**
105
+ - O-entries with >10 exchanges should have `[CP]` checkpoint summaries
106
+ - Check recent O-entries: `read_memory(prefix="O")`
107
+ - If summaries are missing, write them:
108
+ ```
109
+ append_memory(id="O00XX", content="\t[CP] Factual 3-8 sentence summary of the session")
110
+ ```
111
+
112
+ **v5.1.2+ Skill-Dialog Tags:**
113
+ - Exchanges containing skill activations should be tagged `#skill-dialog`
114
+ - These are auto-tagged by the checkpoint process going forward
115
+ - For old exchanges: the checkpoint auto-tagger picks them up on the next run
116
+
117
+ **General migration pattern:**
118
+ 1. Read a sample of entries to assess the current state
119
+ 2. Identify entries that don't match the new format
120
+ 3. Fix in batches — don't try to fix everything at once
121
+ 4. Prioritize: favorites and pinned entries first, then high-access, then the rest
122
+
123
+ ---
124
+
125
+ ## Step 4: P-Entry Schema Enforcement (R0009)
126
+
127
+ All P-entries (projects) must follow the standard L2 structure:
128
+
129
+ ```
130
+ .1 Overview
131
+ .2 Codebase
132
+ .3 Usage
133
+ .4 Context
134
+ .5 Deployment
135
+ .6 Bugs
136
+ .7 Protocol
137
+ .8 Open tasks
138
+ .9 Ideas
139
+ ```
140
+
141
+ For each active P-entry:
142
+ 1. `read_memory(id="P00XX", depth=2)` — check L2 structure
143
+ 2. Compare against the schema above
144
+ 3. Add missing sections: `append_memory(id="P00XX", content="\tOverview\n\t\tCurrent state: ...")`
145
+ 4. L1 body should be: `Name | Status | Stack | Description`
146
+
147
+ **Do not restructure entries that already follow the schema.** Only fix what's missing or wrong.
148
+
149
+ ---
150
+
151
+ ## Step 5: O-Entry Curation
152
+
153
+ Check recent O-entries for quality:
154
+
155
+ ```
156
+ read_memory(prefix="O")
157
+ ```
158
+
159
+ **Titles:**
160
+ - Replace "unassigned" or generic titles (e.g., "hmem-mcp") with descriptive ones
161
+ - Good: "Title/Body Separation design + v5.1.0 release"
162
+ - Fix: `update_memory(id="O00XX", content="Descriptive session title")`
163
+
164
+ **Tags:**
165
+ - Every O-entry should have at least `#session`
166
+ - Add topic tags where obvious: `#release`, `#bugfix`, `#refactor`, `#brainstorming`
167
+ - Fix: `update_memory(id="O00XX", tags=["#session", "#release"])`
168
+
169
+ **Checkpoint Summaries:**
170
+ - O-entries with >10 exchanges and no `[CP]` summary need one
171
+ - Write summary: `append_memory(id="O00XX", content="\t[CP] Summary...")`
172
+ - The auto-tagger will tag it `#checkpoint-summary` on the next checkpoint run
173
+
174
+ **Cleanup:**
175
+ - Look for duplicate O-entries (same title, same date, 1-2 exchanges) — these are likely subagent artifacts
176
+ - Mark as irrelevant or delete if clearly junk
177
+
178
+ ---
179
+
180
+ ## Step 6: hmem-sync Update (if installed)
181
+
182
+ Check if hmem-sync is installed and needs updating:
183
+
184
+ ```bash
185
+ which hmem-sync && hmem-sync --version # check if installed
186
+ npm view hmem-sync version # latest on npm
187
+ ```
188
+
189
+ If outdated:
190
+ ```bash
191
+ npm update -g hmem-sync
192
+ ```
193
+
194
+ Verify sync still works:
195
+ ```bash
196
+ hmem-sync status # check connection to sync server
197
+ hmem-sync push # test push
198
+ hmem-sync pull # test pull
199
+ ```
200
+
201
+ **If hmem-sync is not installed:** Skip this step. Mention to the user that hmem-sync is available for cross-device sync.
202
+
203
+ ---
204
+
205
+ ## Step 7: Smoke Test
206
+
207
+ Verify everything works after the update:
208
+
209
+ ```
210
+ read_memory() # bulk read works
211
+ read_memory(id="P00XX") # drill-down works
212
+ load_project(id="P00XX") # project loading works
213
+ write_memory(prefix="T", content="Update smoke test — delete me", tags=["#test"])
214
+ # write works → note the ID
215
+ update_memory(id="T00XX", content="Update smoke test — verified", irrelevant=true)
216
+ # update works + mark for cleanup
217
+ ```
218
+
219
+ If any step fails: report the error to the user. Do not proceed with normal work until the issue is resolved.
220
+
221
+ ---
222
+
223
+ ## Step 8: Report
224
+
225
+ Tell the user what was done:
226
+
227
+ ```
228
+ hmem-mcp updated: v5.1.2 → v5.1.4
229
+
230
+ Changes applied:
231
+ - Skills synced (2 new, 3 updated)
232
+ - 5 P-entries checked against R0009 schema (2 fixed)
233
+ - 12 O-entries curated (4 titles fixed, 3 summaries added)
234
+ - Smoke test passed
235
+
236
+ New features in this version:
237
+ - Rolling checkpoint summaries
238
+ - Skill-dialog exchange filtering
239
+ - hmem --version reads from package.json
240
+ ```
241
+
242
+ ---
243
+
244
+ ## Auto-Detection (for hook integration)
245
+
246
+ This skill can be triggered automatically. At session startup, if the hmem MCP server detects that the installed version differs from the last-seen version stored in the config, it appends a notice to the first `read_memory()` response:
247
+
248
+ ```
249
+ ⚠ hmem-mcp updated: v5.1.2 → v5.1.4. Run /hmem-update to apply post-update steps.
250
+ ```
251
+
252
+ The agent should then invoke this skill automatically or ask the user if they want to run it.
253
+
254
+ **Last-seen version** is stored in `hmem.config.json` under `lastSeenVersion`. Updated automatically after a successful `/hmem-update` run.
@@ -1,49 +1,75 @@
1
1
  ---
2
2
  name: hmem-wipe
3
3
  description: >
4
- Flush conversation context to hmem and prepare for /clear. Use when:
4
+ Prepare for /clear by optionally saving high-value knowledge. Use when:
5
5
  - User types /wipe
6
6
  - Context threshold warning appears (100k tokens)
7
7
  - User says "context aufräumen", "clear machen", "wipe"
8
- Saves the current session, then instructs user to /clear for re-injection.
8
+ Handles pre-clear cleanup, then instructs user to /clear for automatic context restoration.
9
9
  ---
10
10
 
11
- # Wipe — Save & Clear Context
11
+ # Wipe — Prepare & Clear Context
12
12
 
13
- You MUST follow these steps in order:
13
+ Follow these steps in order.
14
14
 
15
- ## Step 1: Save pending knowledge
15
+ ## Step 1: Optionally save high-value knowledge
16
16
 
17
- Save any unsaved insights from this session:
18
- - New lessons learned → `write_memory(prefix="L", ...)`
19
- - Project progress → `append_memory(id="P00XX.7", ...)` (Protocol node)
20
- - Decisions made → `write_memory(prefix="D", ...)`
21
- - Errors encountered → `write_memory(prefix="E", ...)`
17
+ Check `checkpointMode` in hmem.config.json to decide what to do:
22
18
 
23
- Skip if you already saved recently (last checkpoint < 5 messages ago).
19
+ ### checkpointMode: "auto"
24
20
 
25
- ## Step 2: Title O-entries
21
+ The Haiku subagent already extracts L/D/E entries every 20 exchanges automatically.
22
+ Skip manual writes unless you have **specific high-value knowledge** that:
23
+ - Was discovered in the last few exchanges (too recent for the last auto-checkpoint)
24
+ - Is critical enough that losing it would cost significant rework
25
+ - Is NOT already covered by a recent auto-checkpoint
26
26
 
27
- Run the title script in the background — it spawns Haiku to title untitled O-entries:
27
+ If nothing qualifies, proceed directly to Step 2.
28
28
 
29
- ```bash
30
- /home/bbbee/.claude/hooks/hmem-title-o-entries.sh &
31
- ```
29
+ ### checkpointMode: "remind"
32
30
 
33
- ## Step 3: Tell the user
31
+ Manually save unsaved insights from this project context:
32
+ - New lessons learned: `write_memory(prefix="L", ...)`
33
+ - Project progress: `append_memory(id="P00XX.7", ...)` (Protocol node)
34
+ - Decisions made: `write_memory(prefix="D", ...)`
35
+ - Errors encountered: `write_memory(prefix="E", ...)`
36
+
37
+ Skip if the last checkpoint was fewer than 5 messages ago.
38
+
39
+ ### Why gate on checkpointMode?
40
+
41
+ Redundant writes waste tokens and create duplicates that clutter memory.
42
+ Auto-checkpoints already call `read_memory` to deduplicate before writing —
43
+ manual writes during wipe bypass that check and risk creating noise.
44
+
45
+ ## Step 2: Tell the user to /clear
46
+
47
+ O-entries are auto-logged by the Stop hook — every exchange is already saved
48
+ to the active project's O-entry. No need to manually create O-entries or call
49
+ `flush_context` for conversation history.
34
50
 
35
51
  Reply with exactly:
36
52
 
37
- > Wissen gesichert, O-Titles werden im Hintergrund erstellt. Tippe jetzt `/clear` — der Hook injiziert automatisch den komprimierten Kontext.
53
+ > Context ready for clear. Type `/clear` — the SessionStart hook will automatically restore your project context.
38
54
 
39
- Do NOT attempt to run /clear yourself — it's a built-in CLI command only the user can execute.
55
+ Do NOT attempt to run /clear yourself — it is a built-in CLI command only the user can execute.
40
56
 
41
57
  ## What happens after /clear
42
58
 
43
59
  The `SessionStart[clear]` hook automatically:
44
60
  1. Resets the MCP session cache
45
- 2. Injects the last 20 conversation messages from the transcript
61
+ 2. Injects recent conversation exchanges from the project's O-entry transcript
46
62
  3. Injects the active project briefing (overview expanded)
47
63
  4. Injects recent O-entry titles + rules
48
64
 
49
- The agent then has full context to continue working.
65
+ The agent then calls `load_project` and has full context to continue working.
66
+ No manual restoration needed.
67
+
68
+ ## Why this flow works
69
+
70
+ - **O-entries are covered.** The Stop hook logs every exchange to the active
71
+ project's O-entry. Wipe does not need to handle conversation history.
72
+ - **Checkpoints are covered (auto mode).** The Haiku subagent extracts knowledge
73
+ every 20 exchanges. Wipe only needs to catch the tail end, if anything.
74
+ - **Context restoration is covered.** The SessionStart[clear] hook handles
75
+ re-injection automatically. The agent just needs the user to type /clear.
@@ -19,13 +19,30 @@ If the tool `write_memory` is not available:
19
19
  ```
20
20
  write_memory(
21
21
  prefix: "E",
22
- content: "Short Title (~50 chars)\nL1 sentenceconcise, understandable without context\n\tL2 detail (1 tab)\n\t\tL3 detail (2 tabs)\n\t\t\tL4 raw data (3 tabs — rarely needed)"
22
+ content: "Short Title (~50 chars)\n> L1 body detailed explanation, can span multiple lines\n> second body line with more context\n\tL2 node title\n\t> L2 body text (supports newlines)\n\t> more L2 body\n\t\tL3 detail (2 tabs)\n\t\t\tL4 raw data (3 tabs — rarely needed)"
23
23
  )
24
24
  ```
25
25
 
26
- **Title convention:** The first non-indented line is the **title** (~50 chars, configurable via `maxTitleChars` in `hmem.config.json`) — a short label for navigation, like a chapter title. The second non-indented line is the L1 summary (full sentence). If only one non-indented line is provided, the title is auto-extracted from the first `maxTitleChars` characters.
26
+ **Title + Body convention:** Every node has a **title** (short navigation label) and an optional **body** (detailed content loaded on drill-down).
27
27
 
28
- **Child node titles** are always auto-extracted from the first `maxTitleChars` characters of their content (or text before ` — ` if shorter). No explicit title needed for children.
28
+ - **Title:** The first non-indented line (L1) or first line at a given indent level (L2+). ~50 chars, like a chapter title.
29
+ - **Body:** Lines starting with `> ` at the same indent level. Joined with newlines. Shown only when the node is drilled into, not in listings.
30
+ - **Backward-compatible:** Without `> ` lines, the full text is stored as `content` and the title is auto-extracted from the first `maxTitleChars` characters (existing behavior).
31
+
32
+ **L1 example with body:**
33
+ ```
34
+ Short Error Title
35
+ > SQLite connection failed because .mcp.json used a relative path.
36
+ > The fix was to use an absolute path in the HMEM_PROJECT_DIR env var.
37
+ Details about reproduction
38
+ > Steps: 1. Set HMEM_PROJECT_DIR=./hmem 2. Run hmem serve 3. Observe SQLITE_CANTOPEN
39
+ ```
40
+
41
+ **L1 example without body (old format, still works):**
42
+ ```
43
+ SQLite connection failed due to wrong path in .mcp.json
44
+ Fix: use absolute path in env var
45
+ ```
29
46
 
30
47
  **Indentation:** 1 tab = 1 level. Alternatively: 2 or 4 spaces per level (auto-detected).
31
48
  **Warning:** A tab at the start of any line always means "go one level deeper" — it is structural, not content. If you need to store code or text that contains leading tabs, use spaces instead.
@@ -167,13 +184,13 @@ The MCP server validates that L2 nodes start with one of these names. Minimum fo
167
184
  ```
168
185
  write_memory(
169
186
  prefix="P",
170
- content="WeatherBot | New | Python/Discord.py | GH: user/weatherbot | Discord bot for weather forecasts\n\tOverview\n\t\tCurrent state scaffolding done, no commands yet\n\t\tGoals — daily/hourly forecasts via slash commands, multi-city\n\t\tArchitecture Discord slash command → OpenWeatherMap API → formatted embed\n\t\tEnvironment /home/user/weatherbot, python bot.py, needs DISCORD_TOKEN + WEATHER_API_KEY\n\tCodebase\n\t\tEntry point — bot.py, start: python bot.py\n\t\tCore modules\n\t\t\tweather_cog.py — WeatherCog(Cog); fetch_forecast(city: str) → discord.Embed\n\t\t\tformatter.py — format_embed(data: dict) → discord.Embed\n\t\tHelpers / Utilities\n\t\t\tapi_client.py — get_weather(city: str) → dict; wraps HTTP to OpenWeatherMap\n\t\tConfig / Constants — .env: DISCORD_TOKEN, WEATHER_API_KEY, DEFAULT_CITY\n\t\tTests — pytest, test_weather_cog.py (3 tests)\n\tUsage\n\t\tInstallation / Setup — pip install -r requirements.txt, cp .env.example .env\n\t\tCLI / API — /weather <city>, /forecast <city> (planned)\n\tContext\n\t\tInitiator — personal project, Mar 2026\n\t\tTarget audience — personal Discord server\n\t\tDependencies — discord.py, OpenWeatherMap API, aiohttp\n\tOpen tasks\n\t\tImplement /forecast command for multi-day view\n\t\tAdd city autocomplete",
187
+ content="WeatherBot | New | Python/Discord.py | GH: user/weatherbot\n> Discord bot for weather forecasts — slash commands for current weather and multi-day forecasts\n\tOverview\n\t\tCurrent state\n\t\t> Scaffolding done, no commands yet. Bot connects to Discord but has no slash commands registered.\n\t\tGoals\n\t\t> Daily/hourly forecasts via slash commands, multi-city support, embed formatting\n\t\tArchitecture\n\t\t> Discord slash command → OpenWeatherMap API → formatted embed. Single-file cog pattern.\n\t\tEnvironment\n\t\t> /home/user/weatherbot, python bot.py, needs DISCORD_TOKEN + WEATHER_API_KEY in .env\n\tCodebase\n\t\tEntry point — bot.py, start: python bot.py\n\t\tCore modules\n\t\t\tweather_cog.py — WeatherCog(Cog); fetch_forecast(city: str) → discord.Embed\n\t\t\tformatter.py — format_embed(data: dict) → discord.Embed\n\t\tHelpers / Utilities\n\t\t\tapi_client.py — get_weather(city: str) → dict; wraps HTTP to OpenWeatherMap\n\t\tConfig / Constants — .env: DISCORD_TOKEN, WEATHER_API_KEY, DEFAULT_CITY\n\t\tTests — pytest, test_weather_cog.py (3 tests)\n\tUsage\n\t\tInstallation / Setup — pip install -r requirements.txt, cp .env.example .env\n\t\tCLI / API — /weather <city>, /forecast <city> (planned)\n\tContext\n\t\tInitiator — personal project, Mar 2026\n\t\tTarget audience — personal Discord server\n\t\tDependencies — discord.py, OpenWeatherMap API, aiohttp\n\tOpen tasks\n\t\tImplement /forecast command\n\t\t> Multi-day view with daily highs/lows and weather icons per day\n\t\tAdd city autocomplete",
171
188
  tags=["#discord", "#python", "#weather", "#bot"],
172
189
  links=[]
173
190
  )
174
191
  ```
175
192
 
176
- Note: L2 nodes use 1 tab, L3 uses 2 tabs, L4 uses 3 tabs. Each module under "Core modules" is an L4 node with signature + purpose. Skip empty sections — no need for placeholder text.
193
+ Note: L2 nodes use 1 tab, L3 uses 2 tabs, L4 uses 3 tabs. Use `> ` for body text that should be hidden in listings but shown on drill-down. Skip empty sections — no need for placeholder text.
177
194
 
178
195
  ### Marking entries as favorites
179
196
 
@@ -234,22 +251,22 @@ write_memory(
234
251
 
235
252
  ---
236
253
 
237
- ## Title + L1 Quality Rules
254
+ ## Title + Body Quality Rules
238
255
 
239
256
  **Title:** Short navigation label, ~50 chars (configurable via `maxTitleChars`). Think "chapter title in a book".
240
257
  - Good: `"hmem.py Performance: Bulk-Queries statt N+1"`, `"Ghost Wakeup Bug in msg-router.ts"`
241
258
  - Bad: `"Fixed a bug"`, `"Important lesson"` (too vague)
242
259
 
243
- **L1:** One complete, informative sentence ~15–20 tokens.
260
+ **Body (via `>` lines):** Detailed explanation — full sentences, multiline OK. Shown on drill-down, hidden in listings.
244
261
  - Must be understandable without any context
245
- - Not "Fixed a bug" — instead "SQLite connection failed due to wrong path in .mcp.json"
262
+ - Not "Fixed a bug" — instead explain root cause, fix, and impact
246
263
 
247
- **With explicit title (recommended):**
264
+ **With title + body (recommended):**
248
265
  ```
249
- write_memory(prefix="L", content="hmem.py Performance\nAlle Nodes in 2 Bulk-Queries laden, nicht pro Entry einzeln\n\tload_nodes() pro Entry = N+1 SQLite-Connections")
266
+ write_memory(prefix="L", content="hmem.py Performance: Bulk-Queries statt N+1\n> Alle Nodes in 2 Bulk-Queries laden, nicht pro Entry einzeln.\n> Vorher: load_nodes() pro Entry = N+1 SQLite-Connections.\n\tImplementation detail\n\t> Changed read() to batch-fetch all nodes for visible entries in one query")
250
267
  ```
251
268
 
252
- **Without explicit title (auto-extracted):**
269
+ **Without body (simple entries, backward-compatible):**
253
270
  ```
254
271
  write_memory(prefix="E", content="SQLite connection failed due to wrong path in .mcp.json\n\tFix: use absolute path in env var")
255
272
  ```
@@ -330,7 +347,13 @@ Only use `write_memory` when:
330
347
 
331
348
  ## When to save?
332
349
 
333
- **Mandatory before terminating.** Only save what is still valuable in 6 months.
350
+ **Checkpoint mode matters.** Check `checkpointMode` in hmem.config.json:
351
+
352
+ - **`"auto"` (recommended):** A background Haiku subagent handles checkpoints automatically every N exchanges. It reads recent O-entry exchanges, calls `read_memory` to avoid duplicates, and writes L/D/E entries + handoff via MCP tools. It also writes a rolling checkpoint summary (`[CP]` node tagged `#checkpoint-summary`) that compresses older exchanges for `load_project`. Skill-dialog exchanges are auto-tagged `#skill-dialog` and filtered from context injection. **You do NOT need to write entries yourself** unless the user explicitly asks you to save something specific.
353
+
354
+ - **`"remind"`:** You will receive a CHECKPOINT reminder every N messages. When you see it, save key learnings yourself using `write_memory` / `append_memory`.
355
+
356
+ **In both modes:** Only save what is still valuable in 6 months.
334
357
 
335
358
  | Save | Don't save |
336
359
  |------|-----------|
@@ -364,13 +387,14 @@ Use when: the wording is wrong, outdated, or needs clarification.
364
387
  Appends new child nodes under an existing root or node. Existing children are preserved.
365
388
 
366
389
  Content indentation is **relative to the parent** — 0 tabs = direct child of `id`.
390
+ Body lines (`> `) work the same as in `write_memory`.
367
391
 
368
392
  ```
369
393
  append_memory(
370
394
  id="L0003",
371
- content="New finding discovered later\n\tSub-detail about it"
395
+ content="New finding discovered later\n> Detailed explanation of what was found and why it matters.\n> This can span multiple lines.\n\tSub-detail about it"
372
396
  )
373
- # → adds L0003.N (L2) and L0003.N.1 (L3)
397
+ # → adds L0003.N (L2 with title + body) and L0003.N.1 (L3)
374
398
 
375
399
  append_memory(
376
400
  id="L0003.2",