claude-mem-lite 2.33.3 → 2.33.5
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 +38 -30
- package/package.json +1 -1
package/hook.mjs
CHANGED
|
@@ -109,10 +109,15 @@ if (!event) process.exit(0);
|
|
|
109
109
|
|
|
110
110
|
// ─── Episode Flush ──────────────────────────────────────────────────────────
|
|
111
111
|
|
|
112
|
-
// hookEventName
|
|
113
|
-
//
|
|
114
|
-
//
|
|
115
|
-
//
|
|
112
|
+
// hookEventName serves two roles: it is written into the emitted receipt JSON
|
|
113
|
+
// AND it gates emission via RECEIPT_EVENTS. Callers MUST pass their triggering
|
|
114
|
+
// event name so both work — Stop falls outside the allowlist, so its receipt
|
|
115
|
+
// is skipped entirely (CC's Stop schema rejects hookSpecificOutput at the root,
|
|
116
|
+
// not just on event-name mismatch). The episode still flushes to DB and
|
|
117
|
+
// spawns llm-episode background enrichment; only the stdout receipt is gated.
|
|
118
|
+
// Regression chain: v2.33.1 introduced the receipt; v2.33.3 misdiagnosed the
|
|
119
|
+
// Stop rejection as event-name mismatch; v2.33.4 is the root-cause fix.
|
|
120
|
+
const RECEIPT_EVENTS = new Set(['PostToolUse', 'SessionStart', 'UserPromptSubmit']);
|
|
116
121
|
function flushEpisode(episode, hookEventName = 'PostToolUse') {
|
|
117
122
|
if (!episode || episode.entries.length === 0) return;
|
|
118
123
|
|
|
@@ -157,32 +162,35 @@ function flushEpisode(episode, hookEventName = 'PostToolUse') {
|
|
|
157
162
|
// and the legacy error→fix nudge consolidates here. PostToolUse JSON with
|
|
158
163
|
// hookSpecificOutput.additionalContext reliably renders across CC variants;
|
|
159
164
|
// the old plain-text stdout write was invisible on some variants.
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
.
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
const
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
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
|
+
}
|
|
186
194
|
} else {
|
|
187
195
|
try { unlinkSync(flushFile); } catch {}
|
|
188
196
|
}
|