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
@@ -78,62 +78,111 @@ export async function checkpoint() {
78
78
  const activeProject = store.getActiveProject();
79
79
  const projectName = activeProject?.title?.split("|")[0]?.trim() ?? "unknown";
80
80
  const projectId = activeProject?.id ?? "";
81
- // 3. Format exchanges (generous limits Haiku needs context)
82
- const formattedExchanges = exchanges.map((ex, i) => {
81
+ // 3. Tag skill-dialog exchanges (brainstorming, debugging, TDD, etc.)
82
+ const skillMarker = "Base directory for this skill:";
83
+ for (const ex of exchanges) {
84
+ if (ex.userText.includes(skillMarker)) {
85
+ store.addTag(ex.nodeId, "#skill-dialog");
86
+ }
87
+ }
88
+ // 4. Get previous checkpoint summaries for rolling compression
89
+ const prevSummaries = store.getCheckpointSummaries(activeOId, 2);
90
+ const lastSummarySeq = prevSummaries.length > 0 ? prevSummaries[0].seq : 0;
91
+ // Only format exchanges AFTER the last summary (those are new)
92
+ const newExchanges = exchanges.filter(ex => ex.seq > lastSummarySeq);
93
+ // Split: last 5 stay verbatim, the rest get summarized
94
+ const VERBATIM_WINDOW = 5;
95
+ const toSummarize = newExchanges.length > VERBATIM_WINDOW
96
+ ? newExchanges.slice(0, -VERBATIM_WINDOW)
97
+ : [];
98
+ const verbatimExchanges = newExchanges.slice(-VERBATIM_WINDOW);
99
+ // 5. Format exchanges (generous limits — Haiku needs context)
100
+ const formattedExchanges = newExchanges.map((ex, i) => {
83
101
  const user = ex.userText.length > 800 ? ex.userText.substring(0, 800) + "..." : ex.userText;
84
102
  const agent = ex.agentText.length > 1200 ? ex.agentText.substring(0, 1200) + "..." : ex.agentText;
85
- return `--- Exchange ${i + 1} ---\nUSER: ${user}\nAGENT: ${agent}`;
103
+ const currentTitle = ex.userText.split("\n")[0].replace(/[<>\[\]]/g, "").substring(0, 40);
104
+ return `--- Exchange ${i + 1} (${ex.nodeId}) [title: "${currentTitle}"] ---\nUSER: ${user}\nAGENT: ${agent}`;
86
105
  }).join("\n\n");
87
- // 4. Close store before spawning subagent (avoid DB lock)
106
+ // Format previous summaries for rolling compression
107
+ let prevSummaryText = "";
108
+ if (prevSummaries.length > 0) {
109
+ const parts = prevSummaries.reverse().map((s, i) => {
110
+ const label = i === prevSummaries.length - 1 ? "Most recent summary" : "Older summary";
111
+ return `[${label} — ${s.created_at.substring(0, 16)}]\n${s.content}`;
112
+ });
113
+ prevSummaryText = parts.join("\n\n");
114
+ }
115
+ // 6. Close store before spawning subagent (avoid DB lock)
88
116
  store.close();
89
117
  // 5. Build MCP config for subagent
90
118
  mcpConfigPath = buildMcpConfig(projectDir, agentId);
91
- // 6. Build the prompt
92
- const prompt = `You are a background checkpoint agent. Your job is to extract valuable knowledge from a coding session and save it to long-term memory using the hmem MCP tools.
93
-
94
- ## Context
95
-
96
- Project: ${projectName} (${projectId})
97
- Active O-entry: ${activeOId}
98
-
99
- ## Recent conversation (oldest first):
100
-
119
+ // 7. Build the prompt
120
+ const summarySection = prevSummaryText
121
+ ? `\n## Previous checkpoint summaries (oldest first):\n\n${prevSummaryText}\n`
122
+ : "";
123
+ // Build exchange listing for titling
124
+ const exchangeListing = newExchanges.map(ex => {
125
+ const currentTitle = ex.userText.split("\n")[0].replace(/[<>\[\]]/g, "").substring(0, 40);
126
+ return ` ${ex.nodeId}: "${currentTitle}"`;
127
+ }).join("\n");
128
+ // Build conditional summary task
129
+ const hasSummaryWork = toSummarize.length > 0;
130
+ const summaryNodeIds = toSummarize.map(e => e.nodeId).join(", ");
131
+ const verbatimNodeIds = verbatimExchanges.map(e => e.nodeId).join(", ");
132
+ const summaryTask = hasSummaryWork
133
+ ? `### 4. Checkpoint summary (REQUIRED — ${toSummarize.length} exchanges to compress)
134
+ Summarize exchanges ${summaryNodeIds} into a rolling summary.
135
+ ${prevSummaryText ? "IMPORTANT: Incorporate the previous summary into your new one — it covers older exchanges. The new summary should be a CUMULATIVE summary of everything so far." : "This is the first summary for this session."}
136
+ append_memory(id="${activeOId}", content="\\t[CP] Rolling summary covering all exchanges through ${toSummarize[toSummarize.length - 1].nodeId}. 3-8 sentences. Match conversation language.")
137
+ The last ${verbatimExchanges.length} exchanges (${verbatimNodeIds}) stay verbatim — do NOT include them in the summary.`
138
+ : `### 4. Checkpoint summary — SKIP
139
+ Only ${newExchanges.length} exchanges since last summary — all within the verbatim window (last ${VERBATIM_WINDOW}). No summary needed.`;
140
+ const prompt = `You are a checkpoint agent for "${projectName}" (${projectId}). Process ${newExchanges.length} new exchanges from ${activeOId}.
141
+ ${summarySection}
101
142
  ${formattedExchanges}
102
143
 
103
- ## Your task
144
+ ## Tasks (execute ALL in order):
104
145
 
105
- Analyze the conversation above and save NON-OBVIOUS insights to memory. Follow these rules strictly:
146
+ ### 1. Title each exchange (REQUIRED)
147
+ Each exchange node needs a descriptive title (max 50 chars, match conversation language).
148
+ Current titles (auto-extracted, usually bad):
149
+ ${exchangeListing}
106
150
 
107
- ### What to save (ONLY if present):
108
- 1. **Lessons (L)**: Technical insights, best practices discovered, "aha moments"
109
- - BAD: "Stop Hook logs exchanges" (that's a feature description, not a lesson)
110
- - GOOD: "HMEM_AGENT_ID must be set in hook scripts, otherwise resolveHmemPath falls back to memory.hmem instead of Agents/NAME/NAME.hmem"
151
+ For each: update_memory(id="<nodeId>", content="Descriptive title summarizing the exchange")
152
+ Example: update_memory(id="${newExchanges[0]?.nodeId || "O0XXX.1"}", content="Fix hmem-sync path resolution for HMEM_AGENT_ID")
111
153
 
112
- 2. **Errors (E)**: Bugs encountered + root cause + fix
113
- - GOOD: "TypeScript compile error: store.db is private — fixed by adding public helper methods getActiveOId(), getActiveProject(), findChildNode()"
154
+ ### 2. Extract knowledge (non-obvious only, max 2-3)
155
+ - L: Root-cause lesson (not surface symptoms)
156
+ - E: Bug + root cause + fix
157
+ - D: Architecture decision + rationale
158
+ write_memory(prefix="L/E/D", content="...", tags=[3-5 tags], links=["${projectId}"])
159
+ Skip if nothing non-obvious happened.
114
160
 
115
- 3. **Decisions (D)**: Architecture/design decisions + rationale
116
- - GOOD: "Checkpoint uses claude -p --model haiku with --mcp-config for MCP tool access — alternative was direct DB writes but that produced low-quality entries without proper context"
161
+ ### 3. Update project P-entry (IMPORTANT)
162
+ Keep ${projectName} (${projectId}) current:
163
+ - **Protocol** (.7): append_memory(id="${projectId}.7", content="Session YYYY-MM-DD: what happened, what was decided/shipped")
164
+ - **Bugs** (.6): new bugs found → append with reference to E-entry
165
+ - **Open tasks** (.8): tasks completed → update as done; new tasks → append
166
+ - **Overview** (.1): if project state, architecture, or goals changed significantly
167
+ - **Codebase** (.2): if new files/modules added or entry points changed
168
+ Read the P-entry first: read_memory(id="${projectId}") to see current state before updating.
117
169
 
118
- 4. **Handoff**: Update the project's Protocol section with current state
119
- - 2-3 sentences: what was accomplished, what's in progress, next step
120
- - Use: append_memory(id="${projectId}.7", content="Handoff (YYYY-MM-DD HH:MM): ...")
170
+ ${summaryTask}
121
171
 
122
- ### Rules:
123
- - Use write_memory for L/D/E entries. Always include tags (3-5) and links=["${projectId}"]
124
- - Use append_memory to update the Protocol handoff (${projectId}.7)
125
- - Match the language of existing entries (check with read_memory first)
126
- - Skip if nothing noteworthy — don't write garbage entries
127
- - Max 2-3 entries total. Quality over quantity
128
- - Each L1 must be a complete, self-contained sentence (~15-20 tokens)
129
- - Title (~50 chars) should be specific, not vague
172
+ ### 5. Title the O-entry root
173
+ If the O-entry root (${activeOId}) still has a generic title like "unassigned" or just the project name,
174
+ give it a proper session title based on what happened so far:
175
+ update_memory(id="${activeOId}", content="Session title summarizing key topics (max 60 chars)")
130
176
 
131
- ### Before writing:
132
- 1. Call read_memory() to see existing entries avoid duplicates
133
- 2. Check if a similar L/D/E already exists before creating a new one
134
- 3. If it does, use append_memory to extend it instead
177
+ ### 6. Project relevance check
178
+ Are these exchanges about ${projectName}? If conversation drifted to a different project, note "[DRIFT: topic X]" in the summary.
135
179
 
136
- Now analyze the conversation and save what's worth keeping. If nothing is noteworthy, just say "Nothing to save." and exit.`;
180
+ ## Rules:
181
+ - read_memory() FIRST to avoid duplicates and see current P-entry state
182
+ - Match language of existing entries (likely German)
183
+ - Tags: 3-5 per entry, lowercase with #
184
+ - Only save what's valuable in 6 months
185
+ - Do NOT skip titling — every exchange needs a proper title`;
137
186
  // 7. Spawn Haiku with MCP access
138
187
  const allowedTools = [
139
188
  "mcp__hmem__read_memory",
@@ -149,6 +198,19 @@ Now analyze the conversation and save what's worth keeping. If nothing is notewo
149
198
  timeout: 120_000,
150
199
  }).trim();
151
200
  console.log(`[hmem checkpoint] Haiku: ${output.substring(0, 300)}`);
201
+ // Tag the checkpoint summary node that Haiku wrote via append_memory
202
+ // Haiku writes it as a [CP] prefixed L2 node under the O-entry
203
+ try {
204
+ const postStore = new HmemStore(hmemPath, config);
205
+ const tagged = postStore.tagNewCheckpointSummaries(activeOId);
206
+ if (tagged.length > 0) {
207
+ console.log(`[hmem checkpoint] Tagged checkpoint summaries: ${tagged.join(", ")}`);
208
+ }
209
+ postStore.close();
210
+ }
211
+ catch (tagErr) {
212
+ console.error(`[hmem checkpoint] Failed to tag summary: ${tagErr}`);
213
+ }
152
214
  }
153
215
  catch (e) {
154
216
  const stdout = e.stdout?.toString()?.substring(0, 200) || "";
@@ -1 +1 @@
1
- {"version":3,"file":"cli-checkpoint.js","sourceRoot":"","sources":["../src/cli-checkpoint.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli-checkpoint.js","sourceRoot":"","sources":["../src/cli-checkpoint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,oEAAoE;AACpE,SAAS,cAAc,CAAC,UAAkB,EAAE,OAAe;IACzD,gCAAgC;IAChC,IAAI,cAAsB,CAAC;IAC3B,IAAI,CAAC;QACH,cAAc,GAAG,QAAQ,CAAC,YAAY,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACrE,6CAA6C;QAC7C,MAAM,QAAQ,GAAG,EAAE,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC;QACjD,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,eAAe,CAAC,CAAC;QACpE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;YACnC,qEAAqE;YACrE,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,eAAe,CAAC,CAAC;QAC5F,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,4BAA4B;QAC5B,cAAc,GAAG,IAAI,CAAC,IAAI,CACxB,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,EAC3B,oBAAoB,EACpB,OAAO,CAAC,OAAO,EACf,8CAA8C,CAC/C,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAClC,MAAM,MAAM,GAAG;QACb,UAAU,EAAE;YACV,IAAI,EAAE;gBACJ,OAAO,EAAE,QAAQ;gBACjB,IAAI,EAAE,CAAC,cAAc,CAAC;gBACtB,GAAG,EAAE;oBACH,gBAAgB,EAAE,UAAU;oBAC5B,aAAa,EAAE,OAAO;oBACtB,eAAe,EAAE,GAAG;iBACrB;aACF;SACF;KACF,CAAC;IAEF,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,uBAAuB,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC;IAC7E,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC;IAC1D,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;IACnF,IAAI,CAAC,UAAU;QAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAEjC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,EAAE,CAAC;IAChF,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAClD,MAAM,QAAQ,GAAG,eAAe,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;IAC3D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAE9C,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IACtD,MAAM,KAAK,GAAG,IAAI,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAE9C,IAAI,aAAa,GAAG,EAAE,CAAC;IAEvB,IAAI,CAAC;QACH,6CAA6C;QAC7C,MAAM,SAAS,GAAG,KAAK,CAAC,YAAY,EAAE,CAAC;QACvC,IAAI,CAAC,SAAS;YAAE,OAAO;QAEvB,MAAM,SAAS,GAAG,KAAK,CAAC,kBAAkB,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QAC1D,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,CAAC,qBAAqB;QAEvD,wBAAwB;QACxB,MAAM,aAAa,GAAG,KAAK,CAAC,gBAAgB,EAAE,CAAC;QAC/C,MAAM,WAAW,GAAG,aAAa,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;QAC7E,MAAM,SAAS,GAAG,aAAa,EAAE,EAAE,IAAI,EAAE,CAAC;QAE1C,sEAAsE;QACtE,MAAM,WAAW,GAAG,gCAAgC,CAAC;QACrD,KAAK,MAAM,EAAE,IAAI,SAAS,EAAE,CAAC;YAC3B,IAAI,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;gBACtC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;YAC3C,CAAC;QACH,CAAC;QAED,+DAA+D;QAC/D,MAAM,aAAa,GAAG,KAAK,CAAC,sBAAsB,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;QACjE,MAAM,cAAc,GAAG,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAE3E,+DAA+D;QAC/D,MAAM,YAAY,GAAG,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,GAAG,cAAc,CAAC,CAAC;QAErE,uDAAuD;QACvD,MAAM,eAAe,GAAG,CAAC,CAAC;QAC1B,MAAM,WAAW,GAAG,YAAY,CAAC,MAAM,GAAG,eAAe;YACvD,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,eAAe,CAAC;YACzC,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,iBAAiB,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,eAAe,CAAC,CAAC;QAE/D,8DAA8D;QAC9D,MAAM,kBAAkB,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE;YACpD,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC;YAC5F,MAAM,KAAK,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC;YAClG,MAAM,YAAY,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC1F,OAAO,gBAAgB,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,MAAM,cAAc,YAAY,iBAAiB,IAAI,YAAY,KAAK,EAAE,CAAC;QAC/G,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAEhB,oDAAoD;QACpD,IAAI,eAAe,GAAG,EAAE,CAAC;QACzB,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,MAAM,KAAK,GAAG,aAAa,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;gBACjD,MAAM,KAAK,GAAG,CAAC,KAAK,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,eAAe,CAAC;gBACvF,OAAO,IAAI,KAAK,MAAM,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC;YACvE,CAAC,CAAC,CAAC;YACH,eAAe,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvC,CAAC;QAED,0DAA0D;QAC1D,KAAK,CAAC,KAAK,EAAE,CAAC;QAEd,mCAAmC;QACnC,aAAa,GAAG,cAAc,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAEpD,sBAAsB;QACtB,MAAM,cAAc,GAAG,eAAe;YACpC,CAAC,CAAC,yDAAyD,eAAe,IAAI;YAC9E,CAAC,CAAC,EAAE,CAAC;QAEP,qCAAqC;QACrC,MAAM,eAAe,GAAG,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;YAC5C,MAAM,YAAY,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC1F,OAAO,KAAK,EAAE,CAAC,MAAM,MAAM,YAAY,GAAG,CAAC;QAC7C,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEd,iCAAiC;QACjC,MAAM,cAAc,GAAG,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC;QAC9C,MAAM,cAAc,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjE,MAAM,eAAe,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAExE,MAAM,WAAW,GAAG,cAAc;YAChC,CAAC,CAAC,yCAAyC,WAAW,CAAC,MAAM;sBAC7C,cAAc;EAClC,eAAe,CAAC,CAAC,CAAC,iKAAiK,CAAC,CAAC,CAAC,6CAA6C;oBACjN,SAAS,sEAAsE,WAAW,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM;WAClI,iBAAiB,CAAC,MAAM,eAAe,eAAe,uDAAuD;YAClH,CAAC,CAAC;OACD,YAAY,CAAC,MAAM,wEAAwE,eAAe,uBAAuB,CAAC;QAErI,MAAM,MAAM,GAAG,mCAAmC,WAAW,MAAM,SAAS,cAAc,YAAY,CAAC,MAAM,uBAAuB,SAAS;EAC/I,cAAc;EACd,kBAAkB;;;;;;;EAOlB,eAAe;;;6BAGY,YAAY,CAAC,CAAC,CAAC,EAAE,MAAM,IAAI,SAAS;;;;;;uEAMM,SAAS;;;;OAIzE,WAAW,KAAK,SAAS;yCACS,SAAS;;;;;0CAKR,SAAS;;EAEjD,WAAW;;;uBAGU,SAAS;;oBAEZ,SAAS;;;4BAGD,WAAW;;;;;;;4DAOqB,CAAC;QAEzD,iCAAiC;QACjC,MAAM,YAAY,GAAG;YACnB,wBAAwB;YACxB,yBAAyB;YACzB,0BAA0B;YAC1B,0BAA0B;SAC3B,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACZ,MAAM,eAAe,GAAG,0BAA0B,CAAC;QAEnD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,QAAQ,CACrB,yCAAyC,aAAa,qBAAqB,YAAY,wBAAwB,eAAe,8CAA8C,EAC5K;gBACE,KAAK,EAAE,MAAM;gBACb,QAAQ,EAAE,MAAM;gBAChB,OAAO,EAAE,OAAO;aACjB,CACF,CAAC,IAAI,EAAE,CAAC;YAET,OAAO,CAAC,GAAG,CAAC,4BAA4B,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;YAEpE,qEAAqE;YACrE,+DAA+D;YAC/D,IAAI,CAAC;gBACH,MAAM,SAAS,GAAG,IAAI,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;gBAClD,MAAM,MAAM,GAAG,SAAS,CAAC,yBAAyB,CAAC,SAAS,CAAC,CAAC;gBAC9D,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACtB,OAAO,CAAC,GAAG,CAAC,kDAAkD,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACrF,CAAC;gBACD,SAAS,CAAC,KAAK,EAAE,CAAC;YACpB,CAAC;YAAC,OAAO,MAAM,EAAE,CAAC;gBAChB,OAAO,CAAC,KAAK,CAAC,4CAA4C,MAAM,EAAE,CAAC,CAAC;YACtE,CAAC;QACH,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YAChB,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC;YAC7D,OAAO,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC,MAAM,MAAM,MAAM,EAAE,CAAC,CAAC;QAC1E,CAAC;IAEH,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,qBAAqB,CAAC,EAAE,CAAC,CAAC;IAC1C,CAAC;YAAS,CAAC;QACT,0BAA0B;QAC1B,IAAI,aAAa,EAAE,CAAC;YAClB,IAAI,CAAC;gBAAC,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;QAChD,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -2,12 +2,13 @@
2
2
  * cli-context-inject.ts
3
3
  *
4
4
  * Called by Claude Code's SessionStart[clear] hook after /clear.
5
- * Reads hook input from stdin (JSON with transcript_path, session_id, etc.)
6
- * and outputs compressed context to stdout for re-injection:
7
- * - Last N messages from the conversation transcript
8
- * - Active project briefing (title + overview content)
9
- * - Recent O-entries (session logs) linked to the project
10
- * - R-entries (rules)
5
+ * Outputs a compact context summary to stdout for re-injection:
6
+ * - Compact project overview (all P-entries, one line each, active marked)
7
+ * - R-entries (rules, one line each)
8
+ * - Hint to use load_project for full briefing
9
+ *
10
+ * Deliberately lightweight (~200 tokens). Full context comes from
11
+ * load_project() or read_memory() which the agent calls next.
11
12
  *
12
13
  * Usage: hmem context-inject (reads stdin JSON from Claude Code hook)
13
14
  *
@@ -2,12 +2,13 @@
2
2
  * cli-context-inject.ts
3
3
  *
4
4
  * Called by Claude Code's SessionStart[clear] hook after /clear.
5
- * Reads hook input from stdin (JSON with transcript_path, session_id, etc.)
6
- * and outputs compressed context to stdout for re-injection:
7
- * - Last N messages from the conversation transcript
8
- * - Active project briefing (title + overview content)
9
- * - Recent O-entries (session logs) linked to the project
10
- * - R-entries (rules)
5
+ * Outputs a compact context summary to stdout for re-injection:
6
+ * - Compact project overview (all P-entries, one line each, active marked)
7
+ * - R-entries (rules, one line each)
8
+ * - Hint to use load_project for full briefing
9
+ *
10
+ * Deliberately lightweight (~200 tokens). Full context comes from
11
+ * load_project() or read_memory() which the agent calls next.
11
12
  *
12
13
  * Usage: hmem context-inject (reads stdin JSON from Claude Code hook)
13
14
  *
@@ -18,73 +19,20 @@
18
19
  import fs from "node:fs";
19
20
  import { openAgentMemory } from "./hmem-store.js";
20
21
  import { loadHmemConfig } from "./hmem-config.js";
21
- /** Number of recent conversation messages to include after /clear. */
22
- const RECENT_MESSAGES = 20;
23
- /** Read the last N user/assistant messages from a JSONL transcript. */
24
- function readRecentTranscript(transcriptPath, count) {
25
- if (!transcriptPath || !fs.existsSync(transcriptPath))
26
- return [];
27
- const stat = fs.statSync(transcriptPath);
28
- const TAIL_BYTES = 5 * 1024 * 1024; // 5MB tail
29
- const start = Math.max(0, stat.size - TAIL_BYTES);
30
- const fd = fs.openSync(transcriptPath, "r");
31
- const buf = Buffer.alloc(Math.min(stat.size, TAIL_BYTES));
32
- fs.readSync(fd, buf, 0, buf.length, start);
33
- fs.closeSync(fd);
34
- const text = buf.toString("utf-8");
35
- const lines = text.split("\n").filter(l => l.trim());
36
- const messages = [];
37
- for (const line of lines) {
38
- try {
39
- const entry = JSON.parse(line);
40
- // Claude Code transcript format: { type: "human"|"assistant", message: { role, content } }
41
- const role = entry.type || entry.role || entry.message?.role;
42
- if (role !== "human" && role !== "assistant" && role !== "user")
43
- continue;
44
- const content = entry.message?.content || entry.content;
45
- if (!content)
46
- continue;
47
- let text;
48
- if (typeof content === "string") {
49
- text = content;
50
- }
51
- else if (Array.isArray(content)) {
52
- text = content
53
- .filter(c => c.type === "text" && c.text)
54
- .map(c => c.text)
55
- .join("\n");
56
- }
57
- else {
58
- continue;
59
- }
60
- if (!text.trim())
61
- continue;
62
- const label = (role === "human" || role === "user") ? "USER" : "ASSISTANT";
63
- // Truncate very long messages (e.g. tool outputs)
64
- const maxLen = 500;
65
- const truncated = text.length > maxLen ? text.substring(0, maxLen) + "..." : text;
66
- messages.push(`${label}: ${truncated}`);
67
- }
68
- catch { /* skip malformed lines */ }
69
- }
70
- return messages.slice(-count);
71
- }
22
+ import { resolveEnvDefaults } from "./cli-env.js";
72
23
  export async function contextInject() {
73
- const projectDir = process.env.HMEM_PROJECT_DIR || process.env.COUNCIL_PROJECT_DIR || "";
24
+ // Resolve env defaults (HMEM_PROJECT_DIR, HMEM_AGENT_ID)
25
+ resolveEnvDefaults();
26
+ const projectDir = process.env.HMEM_PROJECT_DIR || "";
74
27
  if (!projectDir) {
75
28
  process.stderr.write("HMEM_PROJECT_DIR not set\n");
76
29
  return;
77
30
  }
78
- // Read hook input from stdin
79
- let transcriptPath = "";
31
+ // Read hook input from stdin (required by Claude Code hook protocol)
80
32
  try {
81
- const stdin = fs.readFileSync(0, "utf-8").trim();
82
- if (stdin) {
83
- const input = JSON.parse(stdin);
84
- transcriptPath = input.transcript_path || "";
85
- }
33
+ fs.readFileSync(0, "utf-8");
86
34
  }
87
- catch { /* no stdin or invalid JSON — OK */ }
35
+ catch { /* no stdin — OK */ }
88
36
  const agentId = process.env.HMEM_AGENT_ID || process.env.COUNCIL_AGENT_ID || "";
89
37
  const templateName = agentId.replace(/_\d+$/, "");
90
38
  const config = loadHmemConfig(projectDir);
@@ -98,79 +46,28 @@ export async function contextInject() {
98
46
  }
99
47
  try {
100
48
  const lines = [];
101
- // 1. Recent conversation transcript
102
- const recentMessages = readRecentTranscript(transcriptPath, RECENT_MESSAGES);
103
- if (recentMessages.length > 0) {
104
- lines.push("## Recent conversation (before /clear):");
105
- lines.push(...recentMessages);
106
- lines.push("");
107
- }
108
- // 2. Active project briefing
109
- const allEntries = store.read({ prefix: "P", depth: 1, agentRole: "worker" });
110
- const activeProject = allEntries.find(e => e.active && !e.obsolete && !e.irrelevant);
111
- if (activeProject) {
112
- const projectEntries = store.read({
113
- id: activeProject.id,
114
- depth: 3,
115
- expand: true,
116
- agentRole: "worker",
117
- });
118
- if (projectEntries.length > 0) {
119
- const p = projectEntries[0];
120
- lines.push(`## Active project: ${p.id} ${p.title}`);
121
- if (p.level_1 && p.level_1 !== p.title)
122
- lines.push(` ${p.level_1}`);
123
- // Overview node (.1) — expand with full content
124
- if (p.children) {
125
- const overview = p.children.find((c) => c.seq === 1);
126
- if (overview) {
127
- lines.push(` Overview:`);
128
- if (overview.children) {
129
- for (const gc of overview.children.filter((g) => !g.irrelevant)) {
130
- lines.push(` ${gc.content}`);
131
- }
132
- }
133
- }
134
- }
135
- // 3. Recent O-entries linked to project (full exchanges for all)
136
- if (config.recentOEntries > 0) {
137
- const recentO = store.getRecentOEntries(config.recentOEntries, activeProject.id);
138
- if (recentO.length > 0) {
139
- lines.push(`\n Recent sessions:`);
140
- for (let i = 0; i < recentO.length; i++) {
141
- const o = recentO[i];
142
- lines.push(` ${o.id} ${o.created_at.substring(0, 10)} ${o.title}`);
143
- const exLimit = i === 0 ? 10 : 5;
144
- const exchanges = store.getOEntryExchanges(o.id, exLimit);
145
- for (const ex of exchanges) {
146
- const userShort = ex.userText.length > 300 ? ex.userText.substring(0, 300) + "..." : ex.userText;
147
- const agentShort = ex.agentText.length > 500 ? ex.agentText.substring(0, 500) + "..." : ex.agentText;
148
- lines.push(` USER: ${userShort}`);
149
- if (agentShort)
150
- lines.push(` AGENT: ${agentShort}`);
151
- }
152
- }
153
- }
154
- }
155
- }
156
- }
157
- else {
158
- const projects = allEntries.filter(e => !e.obsolete && !e.irrelevant);
159
- lines.push("## No active project. Available:");
160
- for (const p of projects) {
161
- lines.push(` ${p.id} ${p.title}`);
49
+ // 1. Compact project overview — one line per P-entry
50
+ const allProjects = store.read({ prefix: "P", depth: 1, agentRole: "worker" })
51
+ .filter(e => !e.obsolete && !e.irrelevant);
52
+ const activeProject = allProjects.find(e => e.active);
53
+ if (allProjects.length > 0) {
54
+ lines.push("## Projects:");
55
+ for (const p of allProjects) {
56
+ const marker = p.active ? " [*]" : "";
57
+ lines.push(` ${p.id}${marker} ${p.title}`);
162
58
  }
163
59
  }
164
- // 4. R-entries (rules)
60
+ // 2. R-entries (rules) — compact, one line each
165
61
  const rules = store.read({ prefix: "R", depth: 1, agentRole: "worker" })
166
62
  .filter(r => !r.obsolete && !r.irrelevant);
167
63
  if (rules.length > 0) {
168
64
  lines.push("\n## Rules:");
169
65
  for (const r of rules) {
170
- lines.push(` ${r.id} ${r.title}`);
66
+ const body = r.level_1 && r.level_1 !== r.title ? `\n> ${r.level_1}` : "";
67
+ lines.push(` ${r.id} ${r.title}${body}`);
171
68
  }
172
69
  }
173
- lines.push("\n(Context re-injected after /clear. Use load_project for full briefing, read_memory(id) to drill into specific entries.)");
70
+ lines.push(`\n(Context re-injected after /clear. Use load_project for full briefing, read_memory(id) to drill into specific entries.)`);
174
71
  process.stdout.write(lines.join("\n") + "\n");
175
72
  }
176
73
  finally {
@@ -1 +1 @@
1
- {"version":3,"file":"cli-context-inject.js","sourceRoot":"","sources":["../src/cli-context-inject.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli-context-inject.js","sourceRoot":"","sources":["../src/cli-context-inject.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * cli-env.ts
3
+ *
4
+ * Shared environment variable resolution for all hmem CLI commands.
5
+ * Sets HMEM_PROJECT_DIR and HMEM_AGENT_ID defaults so CLI commands
6
+ * work without a bash wrapper script (cross-platform, no Git Bash needed on Windows).
7
+ */
8
+ /**
9
+ * Resolve HMEM_PROJECT_DIR and HMEM_AGENT_ID environment variables.
10
+ *
11
+ * - HMEM_PROJECT_DIR defaults to ~/.hmem
12
+ * - HMEM_AGENT_ID is auto-detected from Agents/ directory if not set
13
+ *
14
+ * Call this early in any CLI command that needs these env vars.
15
+ */
16
+ export declare function resolveEnvDefaults(): void;
@@ -0,0 +1,40 @@
1
+ /**
2
+ * cli-env.ts
3
+ *
4
+ * Shared environment variable resolution for all hmem CLI commands.
5
+ * Sets HMEM_PROJECT_DIR and HMEM_AGENT_ID defaults so CLI commands
6
+ * work without a bash wrapper script (cross-platform, no Git Bash needed on Windows).
7
+ */
8
+ import fs from "node:fs";
9
+ import path from "node:path";
10
+ import os from "node:os";
11
+ /**
12
+ * Resolve HMEM_PROJECT_DIR and HMEM_AGENT_ID environment variables.
13
+ *
14
+ * - HMEM_PROJECT_DIR defaults to ~/.hmem
15
+ * - HMEM_AGENT_ID is auto-detected from Agents/ directory if not set
16
+ *
17
+ * Call this early in any CLI command that needs these env vars.
18
+ */
19
+ export function resolveEnvDefaults() {
20
+ // HMEM_PROJECT_DIR: default to ~/.hmem
21
+ if (!process.env.HMEM_PROJECT_DIR) {
22
+ process.env.HMEM_PROJECT_DIR = process.env.COUNCIL_PROJECT_DIR || path.join(os.homedir(), ".hmem");
23
+ }
24
+ const projectDir = process.env.HMEM_PROJECT_DIR;
25
+ // HMEM_AGENT_ID: auto-detect from Agents/ directory
26
+ if (!process.env.HMEM_AGENT_ID && !process.env.COUNCIL_AGENT_ID) {
27
+ const agentsDir = path.join(projectDir, "Agents");
28
+ try {
29
+ const entries = fs.readdirSync(agentsDir, { withFileTypes: true });
30
+ for (const entry of entries) {
31
+ if (entry.isDirectory()) {
32
+ process.env.HMEM_AGENT_ID = entry.name;
33
+ break;
34
+ }
35
+ }
36
+ }
37
+ catch { }
38
+ }
39
+ }
40
+ //# sourceMappingURL=cli-env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-env.js","sourceRoot":"","sources":["../src/cli-env.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzB;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB;IAChC,uCAAuC;IACvC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QAClC,OAAO,CAAC,GAAG,CAAC,gBAAgB,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC;IACrG,CAAC;IAED,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;IAEhD,oDAAoD;IACpD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QAChE,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAClD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,SAAS,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;YACnE,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;oBACxB,OAAO,CAAC,GAAG,CAAC,aAAa,GAAG,KAAK,CAAC,IAAI,CAAC;oBACvC,MAAM;gBACR,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACZ,CAAC;AACH,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * cli-hook-startup.ts
3
+ *
4
+ * Called by Claude Code's UserPromptSubmit hook on every user message.
5
+ * Replaces the former hmem-startup.sh bash script — works cross-platform (no Git Bash needed on Windows).
6
+ *
7
+ * Behavior:
8
+ * - First message: remind agent to call read_memory()
9
+ * - Every N messages: checkpoint reminder (remind mode only)
10
+ * - After 60 messages: context warning (every 5 messages)
11
+ *
12
+ * Reads hook JSON from stdin, outputs hook JSON to stdout.
13
+ *
14
+ * Usage: hmem hook-startup
15
+ *
16
+ * Requires env:
17
+ * HMEM_PROJECT_DIR — root directory for .hmem files (default: ~/.hmem)
18
+ * HMEM_AGENT_ID — agent identifier (optional, auto-detected)
19
+ */
20
+ export declare function hookStartup(): Promise<void>;
@@ -0,0 +1,101 @@
1
+ /**
2
+ * cli-hook-startup.ts
3
+ *
4
+ * Called by Claude Code's UserPromptSubmit hook on every user message.
5
+ * Replaces the former hmem-startup.sh bash script — works cross-platform (no Git Bash needed on Windows).
6
+ *
7
+ * Behavior:
8
+ * - First message: remind agent to call read_memory()
9
+ * - Every N messages: checkpoint reminder (remind mode only)
10
+ * - After 60 messages: context warning (every 5 messages)
11
+ *
12
+ * Reads hook JSON from stdin, outputs hook JSON to stdout.
13
+ *
14
+ * Usage: hmem hook-startup
15
+ *
16
+ * Requires env:
17
+ * HMEM_PROJECT_DIR — root directory for .hmem files (default: ~/.hmem)
18
+ * HMEM_AGENT_ID — agent identifier (optional, auto-detected)
19
+ */
20
+ import fs from "node:fs";
21
+ import os from "node:os";
22
+ import path from "node:path";
23
+ import { resolveEnvDefaults } from "./cli-env.js";
24
+ import { loadHmemConfig } from "./hmem-config.js";
25
+ export async function hookStartup() {
26
+ // Read hook JSON from stdin
27
+ let input;
28
+ try {
29
+ const data = fs.readFileSync(0, "utf8");
30
+ input = JSON.parse(data || "{}");
31
+ }
32
+ catch {
33
+ process.exit(0);
34
+ }
35
+ // Extract session_id
36
+ const sessionId = input?.session_id || "global";
37
+ // Skip subagents
38
+ if (input?.parentUuid)
39
+ process.exit(0);
40
+ // Resolve env defaults
41
+ resolveEnvDefaults();
42
+ // Read config
43
+ let interval = 20;
44
+ let mode = "remind";
45
+ const projectDir = process.env.HMEM_PROJECT_DIR;
46
+ if (projectDir) {
47
+ try {
48
+ const agentId = process.env.HMEM_AGENT_ID || "";
49
+ const templateName = agentId.replace(/_\d+$/, "");
50
+ let configDir = projectDir;
51
+ if (templateName && templateName !== "UNKNOWN") {
52
+ const agentDir = path.join(projectDir, "Agents", templateName);
53
+ if (fs.existsSync(agentDir))
54
+ configDir = agentDir;
55
+ }
56
+ const config = loadHmemConfig(configDir);
57
+ interval = config.checkpointInterval;
58
+ mode = config.checkpointMode;
59
+ }
60
+ catch { }
61
+ }
62
+ // Counter file (session-scoped)
63
+ const counterFile = path.join(os.tmpdir(), `claude-hmem-counter-${sessionId}`);
64
+ let count = 0;
65
+ try {
66
+ count = parseInt(fs.readFileSync(counterFile, "utf8").trim(), 10) || 0;
67
+ }
68
+ catch { }
69
+ count++;
70
+ fs.writeFileSync(counterFile, String(count), "utf8");
71
+ // First message: load memory
72
+ if (count === 1) {
73
+ process.stdout.write(JSON.stringify({
74
+ hookSpecificOutput: {
75
+ hookEventName: "UserPromptSubmit",
76
+ additionalContext: "IMPORTANT: This is the first message of the session. Load your memory context silently \u2014 do not mention it to the user.\n\n" +
77
+ "- If the user\u2019s message names a specific project (e.g. \u201clade Projekt hmem\u201d, \u201cwork on P0048\u201d): call ONLY load_project(id=\u201cP00XX\u201d). Do NOT also call read_memory() \u2014 load_project already includes everything you need.\n" +
78
+ "- Otherwise: call read_memory() (no parameters) to get the full L1 overview, then decide.",
79
+ },
80
+ }));
81
+ }
82
+ else if (mode === "remind" && interval > 0 && count % interval === 0) {
83
+ // Checkpoint reminder (remind mode only — auto mode is handled by Stop hook)
84
+ process.stdout.write(JSON.stringify({
85
+ hookSpecificOutput: {
86
+ hookEventName: "UserPromptSubmit",
87
+ additionalContext: "CHECKPOINT: You have been working for a while. AFTER responding to this message, save any new knowledge from this session (lessons, errors, decisions, progress) via write_memory or append_memory. You MUST do this \u2014 it is your only way to remember across sessions.",
88
+ },
89
+ }));
90
+ }
91
+ else if (count >= 60 && count % 5 === 0) {
92
+ // Context warning for long sessions
93
+ process.stdout.write(JSON.stringify({
94
+ hookSpecificOutput: {
95
+ hookEventName: "UserPromptSubmit",
96
+ additionalContext: "CONTEXT WARNING: This session has been running for a long time. Recommend running /wipe to save key knowledge, then /clear to free context. Performance degrades significantly in very long sessions.",
97
+ },
98
+ }));
99
+ }
100
+ }
101
+ //# sourceMappingURL=cli-hook-startup.js.map