claude-mem-lite 2.33.2 → 2.33.4
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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/hook.mjs +41 -29
- package/package.json +1 -1
package/hook.mjs
CHANGED
|
@@ -109,7 +109,16 @@ if (!event) process.exit(0);
|
|
|
109
109
|
|
|
110
110
|
// ─── Episode Flush ──────────────────────────────────────────────────────────
|
|
111
111
|
|
|
112
|
-
|
|
112
|
+
// hookEventName defaults to 'PostToolUse' since that's the most common caller.
|
|
113
|
+
// Stop / SessionStart callers MUST pass their own event name — CC rejects
|
|
114
|
+
// hook output whose hookEventName doesn't match the triggering event
|
|
115
|
+
// (regression introduced in v2.33.1's structured receipt, fixed in v2.33.3).
|
|
116
|
+
// v2.33.4: CC's Stop-event schema does NOT accept hookSpecificOutput at all —
|
|
117
|
+
// only PreToolUse / UserPromptSubmit / PostToolUse / SessionStart carry
|
|
118
|
+
// additionalContext. On Stop we flush the episode to DB but skip the JSON
|
|
119
|
+
// receipt entirely; emitting it triggers "Invalid input" schema rejection.
|
|
120
|
+
const RECEIPT_EVENTS = new Set(['PostToolUse', 'SessionStart', 'UserPromptSubmit']);
|
|
121
|
+
function flushEpisode(episode, hookEventName = 'PostToolUse') {
|
|
113
122
|
if (!episode || episode.entries.length === 0) return;
|
|
114
123
|
|
|
115
124
|
// Collect Read file paths tracked by post-tool-use.sh
|
|
@@ -153,32 +162,35 @@ function flushEpisode(episode) {
|
|
|
153
162
|
// and the legacy error→fix nudge consolidates here. PostToolUse JSON with
|
|
154
163
|
// hookSpecificOutput.additionalContext reliably renders across CC variants;
|
|
155
164
|
// the old plain-text stdout write was invisible on some variants.
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
.
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
const
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
165
|
+
// v2.33.4: Stop event rejects hookSpecificOutput entirely — skip receipt.
|
|
166
|
+
if (RECEIPT_EVENTS.has(hookEventName)) {
|
|
167
|
+
try {
|
|
168
|
+
const entries = episode.entries || [];
|
|
169
|
+
const hasError = entries.some(e => e.isError);
|
|
170
|
+
const hasEdit = entries.some(e => EDIT_TOOLS.has(e.tool));
|
|
171
|
+
const toolCounts = {};
|
|
172
|
+
for (const e of entries) toolCounts[e.tool] = (toolCounts[e.tool] || 0) + 1;
|
|
173
|
+
const toolSummary = Object.entries(toolCounts)
|
|
174
|
+
.sort((a, b) => b[1] - a[1])
|
|
175
|
+
.slice(0, 3)
|
|
176
|
+
.map(([t, n]) => `${t}×${n}`)
|
|
177
|
+
.join(', ');
|
|
178
|
+
const lines = [`[mem] episode flushed: ${entries.length} entries (${toolSummary})`];
|
|
179
|
+
if (hasError && hasEdit && entries.length >= 3) {
|
|
180
|
+
const editFiles = entries.filter(e => EDIT_TOOLS.has(e.tool)).flatMap(e => e.files || []);
|
|
181
|
+
const uniqueFiles = [...new Set(editFiles)].slice(0, 3);
|
|
182
|
+
const filesHint = uniqueFiles.length > 0 ? ` (${uniqueFiles.join(', ')})` : '';
|
|
183
|
+
lines.push(`[mem] 💡 error→fix pattern${filesHint} — consider: mem_save(type="bugfix", lesson_learned="<root cause + fix>")`);
|
|
184
|
+
}
|
|
185
|
+
process.stdout.write(JSON.stringify({
|
|
186
|
+
suppressOutput: true,
|
|
187
|
+
hookSpecificOutput: {
|
|
188
|
+
hookEventName,
|
|
189
|
+
additionalContext: lines.join('\n'),
|
|
190
|
+
},
|
|
191
|
+
}));
|
|
192
|
+
} catch { /* never block on receipt */ }
|
|
193
|
+
}
|
|
182
194
|
} else {
|
|
183
195
|
try { unlinkSync(flushFile); } catch {}
|
|
184
196
|
}
|
|
@@ -356,7 +368,7 @@ async function handleStop() {
|
|
|
356
368
|
try {
|
|
357
369
|
const episode = readEpisode();
|
|
358
370
|
if (episode) {
|
|
359
|
-
flushEpisode(episode);
|
|
371
|
+
flushEpisode(episode, 'Stop');
|
|
360
372
|
}
|
|
361
373
|
} finally {
|
|
362
374
|
releaseLock();
|
|
@@ -509,7 +521,7 @@ async function handleSessionStart() {
|
|
|
509
521
|
try {
|
|
510
522
|
const prevEpisode = readEpisode();
|
|
511
523
|
if (prevEpisode && prevEpisode.entries && prevEpisode.entries.length > 0) {
|
|
512
|
-
flushEpisode(prevEpisode);
|
|
524
|
+
flushEpisode(prevEpisode, 'SessionStart');
|
|
513
525
|
}
|
|
514
526
|
} finally {
|
|
515
527
|
releaseLock();
|