claude-mem-lite 2.71.1 → 2.71.2
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/stats-quality.mjs +10 -10
- package/mem-cli.mjs +6 -6
- package/package.json +1 -1
- package/schema.mjs +19 -1
- package/scripts/pre-tool-recall.js +6 -4
- package/server.mjs +6 -6
package/lib/stats-quality.mjs
CHANGED
|
@@ -30,10 +30,10 @@ export function computeQualityStats(db, { project, days }) {
|
|
|
30
30
|
const windowRow = db.prepare(`
|
|
31
31
|
SELECT
|
|
32
32
|
COUNT(*) as total,
|
|
33
|
-
SUM(CASE WHEN lesson_learned IS NOT NULL AND lesson_learned != '' THEN 1 ELSE 0 END) as with_lesson,
|
|
34
|
-
SUM(CASE WHEN ${lowSignalIsMatchExpr} THEN 1 ELSE 0 END) as low_signal,
|
|
35
|
-
SUM(CASE WHEN type = 'bugfix' THEN 1 ELSE 0 END) as bugfix_total,
|
|
36
|
-
SUM(CASE WHEN type = 'bugfix' AND ${unresolvedNarrativeExpr} THEN 1 ELSE 0 END) as bugfix_unresolved
|
|
33
|
+
COALESCE(SUM(CASE WHEN lesson_learned IS NOT NULL AND lesson_learned != '' THEN 1 ELSE 0 END), 0) as with_lesson,
|
|
34
|
+
COALESCE(SUM(CASE WHEN ${lowSignalIsMatchExpr} THEN 1 ELSE 0 END), 0) as low_signal,
|
|
35
|
+
COALESCE(SUM(CASE WHEN type = 'bugfix' THEN 1 ELSE 0 END), 0) as bugfix_total,
|
|
36
|
+
COALESCE(SUM(CASE WHEN type = 'bugfix' AND ${unresolvedNarrativeExpr} THEN 1 ELSE 0 END), 0) as bugfix_unresolved
|
|
37
37
|
FROM observations
|
|
38
38
|
WHERE created_at_epoch >= ? ${projectFilter}
|
|
39
39
|
`).get(cutoff, ...baseParams);
|
|
@@ -41,8 +41,8 @@ export function computeQualityStats(db, { project, days }) {
|
|
|
41
41
|
const allTimeRow = db.prepare(`
|
|
42
42
|
SELECT
|
|
43
43
|
COUNT(*) as total,
|
|
44
|
-
SUM(CASE WHEN lesson_learned IS NOT NULL AND lesson_learned != '' THEN 1 ELSE 0 END) as with_lesson,
|
|
45
|
-
SUM(CASE WHEN ${lowSignalIsMatchExpr} THEN 1 ELSE 0 END) as low_signal
|
|
44
|
+
COALESCE(SUM(CASE WHEN lesson_learned IS NOT NULL AND lesson_learned != '' THEN 1 ELSE 0 END), 0) as with_lesson,
|
|
45
|
+
COALESCE(SUM(CASE WHEN ${lowSignalIsMatchExpr} THEN 1 ELSE 0 END), 0) as low_signal
|
|
46
46
|
FROM observations
|
|
47
47
|
WHERE 1=1 ${projectFilter}
|
|
48
48
|
`).get(...baseParams);
|
|
@@ -51,8 +51,8 @@ export function computeQualityStats(db, { project, days }) {
|
|
|
51
51
|
SELECT
|
|
52
52
|
type,
|
|
53
53
|
COUNT(*) as total,
|
|
54
|
-
SUM(CASE WHEN COALESCE(access_count, 0) > 0 THEN 1 ELSE 0 END) as accessed,
|
|
55
|
-
SUM(CASE WHEN lesson_learned IS NOT NULL AND lesson_learned != '' THEN 1 ELSE 0 END) as with_lesson
|
|
54
|
+
COALESCE(SUM(CASE WHEN COALESCE(access_count, 0) > 0 THEN 1 ELSE 0 END), 0) as accessed,
|
|
55
|
+
COALESCE(SUM(CASE WHEN lesson_learned IS NOT NULL AND lesson_learned != '' THEN 1 ELSE 0 END), 0) as with_lesson
|
|
56
56
|
FROM observations
|
|
57
57
|
WHERE created_at_epoch >= ? ${projectFilter}
|
|
58
58
|
GROUP BY type
|
|
@@ -75,8 +75,8 @@ export function computeQualityStats(db, { project, days }) {
|
|
|
75
75
|
// age > 37d, so a sudden write surge inflates this until the cohort ages out.
|
|
76
76
|
const purgeRow = db.prepare(`
|
|
77
77
|
SELECT
|
|
78
|
-
SUM(CASE WHEN compressed_into IS NOT NULL AND compressed_into != 0 THEN 1 ELSE 0 END) as compressed,
|
|
79
|
-
SUM(CASE WHEN compressed_into = ${COMPRESSED_PENDING_PURGE} THEN 1 ELSE 0 END) as pending_purge
|
|
78
|
+
COALESCE(SUM(CASE WHEN compressed_into IS NOT NULL AND compressed_into != 0 THEN 1 ELSE 0 END), 0) as compressed,
|
|
79
|
+
COALESCE(SUM(CASE WHEN compressed_into = ${COMPRESSED_PENDING_PURGE} THEN 1 ELSE 0 END), 0) as pending_purge
|
|
80
80
|
FROM observations
|
|
81
81
|
WHERE 1=1 ${projectFilter}
|
|
82
82
|
`).get(...baseParams);
|
package/mem-cli.mjs
CHANGED
|
@@ -1832,12 +1832,12 @@ function cmdMaintain(db, args) {
|
|
|
1832
1832
|
const stats = db.prepare(`
|
|
1833
1833
|
SELECT
|
|
1834
1834
|
COUNT(*) as total,
|
|
1835
|
-
SUM(CASE WHEN COALESCE(importance, 1) = 1 AND COALESCE(access_count, 0) = 0
|
|
1836
|
-
AND created_at_epoch < ? THEN 1 ELSE 0 END) as stale,
|
|
1837
|
-
SUM(CASE WHEN (title IS NULL OR title = '') AND (narrative IS NULL OR narrative = '')
|
|
1838
|
-
THEN 1 ELSE 0 END) as broken,
|
|
1839
|
-
SUM(CASE WHEN COALESCE(access_count, 0) > 3 AND COALESCE(importance, 1) < 3
|
|
1840
|
-
THEN 1 ELSE 0 END) as boostable
|
|
1835
|
+
COALESCE(SUM(CASE WHEN COALESCE(importance, 1) = 1 AND COALESCE(access_count, 0) = 0
|
|
1836
|
+
AND created_at_epoch < ? THEN 1 ELSE 0 END), 0) as stale,
|
|
1837
|
+
COALESCE(SUM(CASE WHEN (title IS NULL OR title = '') AND (narrative IS NULL OR narrative = '')
|
|
1838
|
+
THEN 1 ELSE 0 END), 0) as broken,
|
|
1839
|
+
COALESCE(SUM(CASE WHEN COALESCE(access_count, 0) > 3 AND COALESCE(importance, 1) < 3
|
|
1840
|
+
THEN 1 ELSE 0 END), 0) as boostable
|
|
1841
1841
|
FROM observations
|
|
1842
1842
|
WHERE COALESCE(compressed_into, 0) = 0 ${projectFilter}
|
|
1843
1843
|
`).get(staleAge, ...baseParams);
|
package/package.json
CHANGED
package/schema.mjs
CHANGED
|
@@ -181,6 +181,21 @@ export function initSchema(db) {
|
|
|
181
181
|
if (e.message?.startsWith('DB schema is v')) throw e;
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
+
// Concurrent-init guard: serialize schema setup against peer processes via
|
|
185
|
+
// BEGIN IMMEDIATE (busy_timeout=3000 from ensureDb makes peers wait). Required
|
|
186
|
+
// because the sdk_sessions_id_mix_check_{ai,au} migration uses DROP+CREATE
|
|
187
|
+
// without IF NOT EXISTS to update the trigger body, which races at cold-start.
|
|
188
|
+
// Re-check schema_version under the lock — a peer may have completed init
|
|
189
|
+
// while we were blocked. Connection close auto-rollbacks if body throws.
|
|
190
|
+
db.exec('BEGIN IMMEDIATE');
|
|
191
|
+
try {
|
|
192
|
+
const underlock = db.prepare('SELECT version FROM schema_version LIMIT 1').get();
|
|
193
|
+
if (underlock && underlock.version === CURRENT_SCHEMA_VERSION) {
|
|
194
|
+
db.exec('COMMIT');
|
|
195
|
+
return db;
|
|
196
|
+
}
|
|
197
|
+
} catch { /* table absent — proceed */ }
|
|
198
|
+
|
|
184
199
|
// Create core tables
|
|
185
200
|
db.exec(CORE_SCHEMA);
|
|
186
201
|
|
|
@@ -264,7 +279,6 @@ export function initSchema(db) {
|
|
|
264
279
|
});
|
|
265
280
|
dedupAndIndex();
|
|
266
281
|
}
|
|
267
|
-
db.pragma('foreign_keys = ON');
|
|
268
282
|
|
|
269
283
|
// Performance indexes
|
|
270
284
|
db.exec(`CREATE INDEX IF NOT EXISTS idx_obs_epoch_project ON observations(created_at_epoch DESC, project)`);
|
|
@@ -580,6 +594,10 @@ export function initSchema(db) {
|
|
|
580
594
|
db.prepare('INSERT INTO schema_version (version) VALUES (?)').run(CURRENT_SCHEMA_VERSION);
|
|
581
595
|
})();
|
|
582
596
|
|
|
597
|
+
db.exec('COMMIT');
|
|
598
|
+
// PRAGMA foreign_keys must run OUTSIDE the transaction (no-op inside).
|
|
599
|
+
db.pragma('foreign_keys = ON');
|
|
600
|
+
|
|
583
601
|
return db;
|
|
584
602
|
}
|
|
585
603
|
|
|
@@ -9,10 +9,12 @@ import { basename, join } from 'path';
|
|
|
9
9
|
import { homedir } from 'os';
|
|
10
10
|
import { buildNotLowSignalSql } from '../lib/low-signal-patterns.mjs';
|
|
11
11
|
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
|
|
15
|
-
const
|
|
12
|
+
// CLAUDE_MEM_DIR matches schema.mjs / main CLI — one env var sandboxes the
|
|
13
|
+
// whole system. CLAUDE_MEM_DB_PATH / CLAUDE_MEM_RUNTIME_DIR remain as
|
|
14
|
+
// per-component overrides for tests that mix isolated + real paths.
|
|
15
|
+
const DATA_DIR = process.env.CLAUDE_MEM_DIR || join(homedir(), '.claude-mem-lite');
|
|
16
|
+
const DB_PATH = process.env.CLAUDE_MEM_DB_PATH || join(DATA_DIR, 'claude-mem-lite.db');
|
|
17
|
+
const RUNTIME_DIR = process.env.CLAUDE_MEM_RUNTIME_DIR || join(DATA_DIR, 'runtime');
|
|
16
18
|
// v2.33.1: cooldown path is session-scoped so same-file-twice within one
|
|
17
19
|
// session never re-injects (was: global file, 5-min window). Cross-session:
|
|
18
20
|
// fresh file, fresh nudges — this is intended. No session_id → fall back to
|
package/server.mjs
CHANGED
|
@@ -1329,12 +1329,12 @@ server.registerTool(
|
|
|
1329
1329
|
const stats = db.prepare(`
|
|
1330
1330
|
SELECT
|
|
1331
1331
|
COUNT(*) as total,
|
|
1332
|
-
SUM(CASE WHEN COALESCE(importance, 1) = 1 AND COALESCE(access_count, 0) = 0
|
|
1333
|
-
AND created_at_epoch < ? THEN 1 ELSE 0 END) as stale,
|
|
1334
|
-
SUM(CASE WHEN (title IS NULL OR title = '') AND (narrative IS NULL OR narrative = '')
|
|
1335
|
-
THEN 1 ELSE 0 END) as broken,
|
|
1336
|
-
SUM(CASE WHEN COALESCE(access_count, 0) > 3 AND COALESCE(importance, 1) < 3
|
|
1337
|
-
THEN 1 ELSE 0 END) as boostable
|
|
1332
|
+
COALESCE(SUM(CASE WHEN COALESCE(importance, 1) = 1 AND COALESCE(access_count, 0) = 0
|
|
1333
|
+
AND created_at_epoch < ? THEN 1 ELSE 0 END), 0) as stale,
|
|
1334
|
+
COALESCE(SUM(CASE WHEN (title IS NULL OR title = '') AND (narrative IS NULL OR narrative = '')
|
|
1335
|
+
THEN 1 ELSE 0 END), 0) as broken,
|
|
1336
|
+
COALESCE(SUM(CASE WHEN COALESCE(access_count, 0) > 3 AND COALESCE(importance, 1) < 3
|
|
1337
|
+
THEN 1 ELSE 0 END), 0) as boostable
|
|
1338
1338
|
FROM observations
|
|
1339
1339
|
WHERE COALESCE(compressed_into, 0) = 0 ${projectFilter}
|
|
1340
1340
|
`).get(staleAge, ...baseParams);
|