claude-mem-lite 3.52.0 → 3.53.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.
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"plugins": [
|
|
11
11
|
{
|
|
12
12
|
"name": "claude-mem-lite",
|
|
13
|
-
"version": "3.
|
|
13
|
+
"version": "3.53.0",
|
|
14
14
|
"source": "./",
|
|
15
15
|
"description": "Persistent long-term memory for Claude Code via MCP — captures coding decisions, bugfixes, and context across sessions. Hybrid FTS5 + TF-IDF search with episode batching. Single SQLite DB, no external services. A lighter, lower-cost alternative to claude-mem (episode batching + a smaller model; cost savings are an internal estimate, not a measured benchmark)."
|
|
16
16
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-mem-lite",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.53.0",
|
|
4
4
|
"description": "Persistent long-term memory for Claude Code via MCP — captures coding decisions, bugfixes, and context across sessions. Hybrid FTS5 + TF-IDF search with episode batching. Single SQLite DB, no external services. A lighter, lower-cost alternative to claude-mem (episode batching + a smaller model; cost savings are an internal estimate, not a measured benchmark).",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "sdsrss"
|
package/hook.mjs
CHANGED
|
@@ -668,7 +668,13 @@ async function handleStop() {
|
|
|
668
668
|
} else {
|
|
669
669
|
const citedMain = extractCitationsFromTranscript(transcriptPath, { mainOnly: true });
|
|
670
670
|
for (const id of citeBackIds) citedMain.add(id);
|
|
671
|
-
|
|
671
|
+
// D#60: the idempotency key must be the CC session UUID, NOT the
|
|
672
|
+
// project-scoped memory sessionId — concurrent same-project CC
|
|
673
|
+
// sessions share the latter, so the second session's decay pass
|
|
674
|
+
// read "already decided" and silently undercounted decay_seen /
|
|
675
|
+
// streaks / adoption denominators. Fallback keeps legacy
|
|
676
|
+
// stdin-less invocations on the old key.
|
|
677
|
+
const r = applyCitationDecay(db, project, injected, citedMain, ccSessionId || sessionId);
|
|
672
678
|
debugLog('DEBUG', 'handleStop', `citation-decay: touched=${r.touched} promoted=${r.promoted} demoted=${r.demoted}`);
|
|
673
679
|
// R1: persist this session's invocation→cite funnel row. touched =
|
|
674
680
|
// obs resolved this run (denominator), promoted = obs cited this run
|
package/lib/citation-tracker.mjs
CHANGED
|
@@ -599,9 +599,35 @@ export function applyCitationDecay(db, project, injectedIds, citedIds, sessionId
|
|
|
599
599
|
const empty = { promoted: 0, demoted: 0, touched: 0 };
|
|
600
600
|
if (process.env.MEM_DISABLE_CITATION_DECAY === '1') return empty;
|
|
601
601
|
if (!db || !project || !sessionId) return empty;
|
|
602
|
-
|
|
602
|
+
let injected = injectedIds instanceof Set ? injectedIds : new Set(injectedIds || []);
|
|
603
603
|
if (injected.size === 0) return empty;
|
|
604
|
-
|
|
604
|
+
let cited = citedIds instanceof Set ? citedIds : new Set(citedIds || []);
|
|
605
|
+
|
|
606
|
+
// D#61: a lesson injected live and then superseded mid-session (auto-dedup /
|
|
607
|
+
// supersedes= save) leaves its citation crediting NOBODY — selectStmt below
|
|
608
|
+
// excludes superseded rows by design (defense-in-depth parity), so the keeper
|
|
609
|
+
// that now carries the lesson goes uncredited. Redirect such ids to their
|
|
610
|
+
// NUMERIC superseded_by keeper (one hop; superseded_by is polymorphic — the
|
|
611
|
+
// typeof guard mirrors timeline-core). Copies, not mutation: callers own the
|
|
612
|
+
// input sets.
|
|
613
|
+
const redirectStmt = db.prepare(
|
|
614
|
+
'SELECT superseded_by FROM observations WHERE id = ? AND project = ? AND superseded_at IS NOT NULL'
|
|
615
|
+
);
|
|
616
|
+
const redirectSet = (set) => {
|
|
617
|
+
const out = new Set();
|
|
618
|
+
for (const id of set) {
|
|
619
|
+
const r = redirectStmt.get(id, project);
|
|
620
|
+
if (r && typeof r.superseded_by === 'number' && Number.isInteger(r.superseded_by)
|
|
621
|
+
&& r.superseded_by > 0 && r.superseded_by !== id) {
|
|
622
|
+
out.add(r.superseded_by);
|
|
623
|
+
} else {
|
|
624
|
+
out.add(id);
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
return out;
|
|
628
|
+
};
|
|
629
|
+
injected = redirectSet(injected);
|
|
630
|
+
cited = redirectSet(cited);
|
|
605
631
|
|
|
606
632
|
// Adoption gate (snapshot taken before any mutation this run). Suppress only
|
|
607
633
|
// demotion; promotion always proceeds. Threshold overridable via env.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-mem-lite",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.53.0",
|
|
4
4
|
"description": "Persistent long-term memory for Claude Code via MCP — captures coding decisions, bugfixes, and context across sessions. Hybrid FTS5 + TF-IDF search with episode batching. Single SQLite DB, no external services. A lighter, lower-cost alternative to claude-mem (episode batching + a smaller model; cost savings are an internal estimate, not a measured benchmark).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"packageManager": "npm@10.9.2",
|