claude-mem-lite 3.76.0 → 3.76.1
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/lib/maintain-core.mjs +17 -8
- package/mem-cli.mjs +1 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/server.mjs +2 -2
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"plugins": [
|
|
11
11
|
{
|
|
12
12
|
"name": "claude-mem-lite",
|
|
13
|
-
"version": "3.76.
|
|
13
|
+
"version": "3.76.1",
|
|
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.76.
|
|
3
|
+
"version": "3.76.1",
|
|
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/lib/maintain-core.mjs
CHANGED
|
@@ -397,6 +397,20 @@ export function boostAccessed(db, { projectFilter, baseParams, opCap = OP_CAP })
|
|
|
397
397
|
// background machinery must not quietly dispose of one.
|
|
398
398
|
const NO_LESSON_SQL = "(lesson_learned IS NULL OR lesson_learned = '' OR lesson_learned = 'none')";
|
|
399
399
|
|
|
400
|
+
// The floor demotePinned writes, and therefore also the bound that decides whether a row
|
|
401
|
+
// still HAS anything to demote. One home: v3.76.0 shipped with the floor here and the
|
|
402
|
+
// forecast in maintenanceStats still hard-coded `importance > 1`, so a lesson row already
|
|
403
|
+
// at 2 was counted as pinned forever while every execute reported "Demoted 0" — the exact
|
|
404
|
+
// scan-forecast-vs-execute drift the decayAndMarkIdle comment below exists to prevent.
|
|
405
|
+
const PINNED_FLOOR_SQL = `(CASE WHEN ${NO_LESSON_SQL} THEN 1 ELSE 2 END)`;
|
|
406
|
+
// Shared by the op and its forecast. Callers add their own compressed_into/project filter.
|
|
407
|
+
// Module-private on purpose: nothing outside this file consumes it, and exporting by habit
|
|
408
|
+
// is how the knip baseline drifts (cf. the v3.70.0 DEFAULT_MARKETPLACE trio).
|
|
409
|
+
const PINNED_PREDICATE_SQL = `
|
|
410
|
+
COALESCE(injection_count, 0) >= ${PINNED_INJ_THRESHOLD}
|
|
411
|
+
AND COALESCE(cited_count, 0) = 0
|
|
412
|
+
AND COALESCE(importance, 1) > ${PINNED_FLOOR_SQL}`;
|
|
413
|
+
|
|
400
414
|
/**
|
|
401
415
|
* Repair the citation-decay blind spot: heavy-injection + zero-citation rows that
|
|
402
416
|
* decay protects (injection_count>0) stay pinned at max importance forever. Floor
|
|
@@ -421,15 +435,12 @@ const NO_LESSON_SQL = "(lesson_learned IS NULL OR lesson_learned = '' OR lesson_
|
|
|
421
435
|
* report phantom demotions on every run forever.
|
|
422
436
|
*/
|
|
423
437
|
export function demotePinned(db, { projectFilter, baseParams, opCap = OP_CAP }) {
|
|
424
|
-
const floor = `(CASE WHEN ${NO_LESSON_SQL} THEN 1 ELSE 2 END)`;
|
|
425
438
|
return db.prepare(`
|
|
426
|
-
UPDATE observations SET importance = ${
|
|
439
|
+
UPDATE observations SET importance = ${PINNED_FLOOR_SQL}
|
|
427
440
|
WHERE id IN (
|
|
428
441
|
SELECT id FROM observations
|
|
429
442
|
WHERE COALESCE(compressed_into, 0) = 0
|
|
430
|
-
AND
|
|
431
|
-
AND COALESCE(cited_count, 0) = 0
|
|
432
|
-
AND COALESCE(importance, 1) > ${floor}
|
|
443
|
+
AND ${PINNED_PREDICATE_SQL}
|
|
433
444
|
${projectFilter} LIMIT ${opCap}
|
|
434
445
|
)
|
|
435
446
|
`).run(...baseParams).changes;
|
|
@@ -603,9 +614,7 @@ export function maintenanceStats(db, { projectFilter, baseParams, staleAge }) {
|
|
|
603
614
|
THEN 1 ELSE 0 END), 0) as broken,
|
|
604
615
|
COALESCE(SUM(CASE WHEN COALESCE(access_count, 0) > 3 AND COALESCE(importance, 1) < 3
|
|
605
616
|
THEN 1 ELSE 0 END), 0) as boostable,
|
|
606
|
-
COALESCE(SUM(CASE WHEN
|
|
607
|
-
AND COALESCE(cited_count, 0) = 0 AND COALESCE(importance, 1) > 1
|
|
608
|
-
THEN 1 ELSE 0 END), 0) as pinned
|
|
617
|
+
COALESCE(SUM(CASE WHEN ${PINNED_PREDICATE_SQL} THEN 1 ELSE 0 END), 0) as pinned
|
|
609
618
|
FROM observations
|
|
610
619
|
WHERE COALESCE(compressed_into, 0) = 0 ${projectFilter}
|
|
611
620
|
`).get(staleAge, ...baseParams);
|
package/mem-cli.mjs
CHANGED
|
@@ -2012,7 +2012,7 @@ function cmdMaintain(db, args) {
|
|
|
2012
2012
|
out(` Stale (>30d, imp=1, no access, never injected): ${stats.stale}`);
|
|
2013
2013
|
out(` Broken (no title/narrative): ${stats.broken}`);
|
|
2014
2014
|
out(` Boostable (accessed>3, imp<3): ${stats.boostable}`);
|
|
2015
|
-
out(` Pinned-but-uncited (inj>=${PINNED_INJ_THRESHOLD}, cited=0,
|
|
2015
|
+
out(` Pinned-but-uncited (inj>=${PINNED_INJ_THRESHOLD}, cited=0, above floor): ${stats.pinned} — floored by the default maintain set since v3.76.0, no lesson → 1, lesson → 2 (opt out: CLAUDE_MEM_SKIP_DEMOTE_PINNED=1)`);
|
|
2016
2016
|
out(formatPendingPurgeLine(stats.pendingPurge));
|
|
2017
2017
|
if (duplicates.length > 0) {
|
|
2018
2018
|
const autoMergeable = duplicates.filter(d => parseFloat(d.similarity) >= AUTO_MERGE_THRESHOLD);
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-mem-lite",
|
|
3
|
-
"version": "3.76.
|
|
3
|
+
"version": "3.76.1",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "claude-mem-lite",
|
|
9
|
-
"version": "3.76.
|
|
9
|
+
"version": "3.76.1",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
12
12
|
"better-sqlite3": "^12.6.2",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-mem-lite",
|
|
3
|
-
"version": "3.76.
|
|
3
|
+
"version": "3.76.1",
|
|
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",
|
package/server.mjs
CHANGED
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
recoverOrphanedChildren, recoverBuriedLessons, sweepDeferredWorkOrphans,
|
|
20
20
|
purgeStale, purgeStalePreview, findDuplicates, maintenanceStats, rebuildVectors, vacuum,
|
|
21
21
|
hardDeleteCandidateCount,
|
|
22
|
-
OP_CAP, STALE_AGE_MS, resolveDefaultMaintainOps,
|
|
22
|
+
OP_CAP, STALE_AGE_MS, resolveDefaultMaintainOps, DEFAULT_MAINTAIN_OPS,
|
|
23
23
|
} from './lib/maintain-core.mjs';
|
|
24
24
|
import { snapshotDb } from './lib/db-backup.mjs';
|
|
25
25
|
import { deleteObservations, previewDeleteRows } from './lib/delete-core.mjs';
|
|
@@ -1152,7 +1152,7 @@ server.registerTool(
|
|
|
1152
1152
|
// T2-P1-A: reject explicit empty array (vs. omitted → defaults above). Empty-array
|
|
1153
1153
|
// callers are almost always mistakes; silently running only FTS5 optimize hides the error.
|
|
1154
1154
|
if (args.operations && args.operations.length === 0) {
|
|
1155
|
-
return { content: [{ type: 'text', text:
|
|
1155
|
+
return { content: [{ type: 'text', text: `operations array is empty. Pass a non-empty list (e.g. ${JSON.stringify(DEFAULT_MAINTAIN_OPS)}) or omit operations to use the default set.` }], isError: true };
|
|
1156
1156
|
}
|
|
1157
1157
|
const results = [];
|
|
1158
1158
|
const staleAge = Date.now() - STALE_AGE_MS;
|