claude-mem-lite 6.30.3 → 6.30.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/install.mjs +1 -1
- package/lib/db-backup.mjs +15 -2
- package/lib/db-unusable.mjs +17 -11
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"plugins": [
|
|
10
10
|
{
|
|
11
11
|
"name": "claude-mem-lite",
|
|
12
|
-
"version": "6.30.
|
|
12
|
+
"version": "6.30.4",
|
|
13
13
|
"source": "./",
|
|
14
14
|
"homepage": "https://github.com/sdsrss/claude-mem-lite",
|
|
15
15
|
"description": "Persistent long-term memory for Claude Code via MCP — captures coding decisions, bugfixes, and context across sessions. FTS5 BM25 keyword 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)."
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-mem-lite",
|
|
3
|
-
"version": "6.30.
|
|
3
|
+
"version": "6.30.4",
|
|
4
4
|
"description": "Persistent long-term memory for Claude Code via MCP — captures coding decisions, bugfixes, and context across sessions. FTS5 BM25 keyword 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/install.mjs
CHANGED
|
@@ -483,7 +483,7 @@ export async function dbCheckRemedy(dbPath, err) {
|
|
|
483
483
|
// its copy of the command.
|
|
484
484
|
if (remedy.kind === 'set-aside') {
|
|
485
485
|
return (
|
|
486
|
-
`No backup snapshot exists beside the database. Once every Claude Code session is closed, ` +
|
|
486
|
+
`No non-empty backup snapshot exists beside the database. Once every Claude Code session is closed, ` +
|
|
487
487
|
`set the broken file aside so a fresh store is created on the next session: ${remedy.command} ` +
|
|
488
488
|
`— memories in that file are not recoverable without a backup.`
|
|
489
489
|
);
|
package/lib/db-backup.mjs
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
//
|
|
8
8
|
// MUST be called OUTSIDE any transaction — VACUUM cannot run inside one, which is
|
|
9
9
|
// why the maintenance entry points snapshot before opening their db.transaction().
|
|
10
|
-
import { readdirSync, unlinkSync, statSync } from 'fs';
|
|
10
|
+
import { existsSync, readdirSync, unlinkSync, statSync } from 'fs';
|
|
11
11
|
import { dirname, basename, join } from 'path';
|
|
12
12
|
import { debugLog } from '../utils.mjs';
|
|
13
13
|
|
|
@@ -149,7 +149,20 @@ export function snapshotDb(db, { tag = 'pre-maintain', retain = 3 } = {}) {
|
|
|
149
149
|
const out = `${dbPath}.${tag}-${stamp}.bak`;
|
|
150
150
|
// Path is internal (db.name from our own config), but escape single quotes
|
|
151
151
|
// defensively since VACUUM INTO takes a string literal, not a bound param.
|
|
152
|
-
|
|
152
|
+
const fresh = !existsSync(out);
|
|
153
|
+
try {
|
|
154
|
+
db.exec(`VACUUM INTO '${out.replace(/'/g, "''")}'`);
|
|
155
|
+
} catch (e) {
|
|
156
|
+
// A failed VACUUM INTO can leave its target behind: 0 bytes on a damaged store, newer than
|
|
157
|
+
// every real snapshot, so a restore command named it (D#551). Only a file it created goes.
|
|
158
|
+
if (fresh)
|
|
159
|
+
try {
|
|
160
|
+
unlinkSync(out);
|
|
161
|
+
} catch {
|
|
162
|
+
/* never created */
|
|
163
|
+
}
|
|
164
|
+
throw e;
|
|
165
|
+
}
|
|
153
166
|
pruneSnapshots(dbPath, tag, retain);
|
|
154
167
|
enforceBackupBudget(dbPath);
|
|
155
168
|
return out;
|
package/lib/db-unusable.mjs
CHANGED
|
@@ -171,46 +171,52 @@ export function dbUnusableRemedy(dbPath, err) {
|
|
|
171
171
|
`fix that directory first, then look for ${basename(dbPath)}.*.bak beside the database.`,
|
|
172
172
|
};
|
|
173
173
|
}
|
|
174
|
-
|
|
174
|
+
// A 0-byte `.bak` is what a failed snapshot of a damaged store left before 6.31.0 (D#551),
|
|
175
|
+
// usually the newest one; it is not a copy of anything.
|
|
176
|
+
const snapshots = snap.snapshots.filter((s) => s.size > 0);
|
|
177
|
+
const empty = snap.snapshots.length - snapshots.length;
|
|
178
|
+
const none =
|
|
179
|
+
empty > 0
|
|
180
|
+
? `No backup snapshot beside the database holds any data (${empty} empty .bak file${empty === 1 ? '' : 's'} skipped).`
|
|
181
|
+
: 'No backup snapshot exists beside the database.';
|
|
182
|
+
if (schema && snapshots.length === 0) {
|
|
175
183
|
return {
|
|
176
184
|
kind: 'schema',
|
|
177
185
|
command: '',
|
|
178
186
|
snapshotCount: 0,
|
|
179
|
-
note:
|
|
187
|
+
note: none,
|
|
180
188
|
};
|
|
181
189
|
}
|
|
182
|
-
if (
|
|
190
|
+
if (snapshots.length === 0) {
|
|
183
191
|
return {
|
|
184
192
|
kind: 'set-aside',
|
|
185
193
|
command: `${clear} && mv ${shellWord(dbPath)} ${shellWord(`${dbPath}.corrupt`)}`,
|
|
186
194
|
snapshotCount: 0,
|
|
187
195
|
note:
|
|
188
|
-
|
|
196
|
+
`${none} That command sets the broken file ` +
|
|
189
197
|
'aside so a fresh store is created on the next session — memories in it are not ' +
|
|
190
198
|
'recoverable without a backup.',
|
|
191
199
|
};
|
|
192
200
|
}
|
|
193
201
|
// Newest by mtime, ties broken by name (which carries an ISO stamp) so the answer is total
|
|
194
202
|
// rather than dependent on readdir order — the D#9 shape.
|
|
195
|
-
const newest =
|
|
196
|
-
.slice()
|
|
197
|
-
.sort((a, b) => b.mtimeMs - a.mtimeMs || (a.path < b.path ? 1 : -1))[0];
|
|
203
|
+
const newest = snapshots.slice().sort((a, b) => b.mtimeMs - a.mtimeMs || (a.path < b.path ? 1 : -1))[0];
|
|
198
204
|
if (schema) {
|
|
199
205
|
return {
|
|
200
206
|
kind: 'schema',
|
|
201
207
|
command: '',
|
|
202
|
-
snapshotCount:
|
|
208
|
+
snapshotCount: snapshots.length,
|
|
203
209
|
note:
|
|
204
|
-
`${
|
|
210
|
+
`${snapshots.length} backup snapshot(s) exist beside it; the newest is ${newest.path}. ` +
|
|
205
211
|
'Restoring one replaces the database file, so copy the broken file aside first.',
|
|
206
212
|
};
|
|
207
213
|
}
|
|
208
214
|
return {
|
|
209
215
|
kind: 'restore',
|
|
210
216
|
command: `${clear} && cp ${shellWord(newest.path)} ${shellWord(dbPath)}`,
|
|
211
|
-
snapshotCount:
|
|
217
|
+
snapshotCount: snapshots.length,
|
|
212
218
|
note:
|
|
213
|
-
`Restores the newest of ${
|
|
219
|
+
`Restores the newest of ${snapshots.length} backup snapshot(s). Move the broken ` +
|
|
214
220
|
'file aside first if you want to keep it for inspection.',
|
|
215
221
|
};
|
|
216
222
|
}
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-mem-lite",
|
|
3
|
-
"version": "6.30.
|
|
3
|
+
"version": "6.30.4",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "claude-mem-lite",
|
|
9
|
-
"version": "6.30.
|
|
9
|
+
"version": "6.30.4",
|
|
10
10
|
"os": [
|
|
11
11
|
"darwin",
|
|
12
12
|
"linux",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-mem-lite",
|
|
3
|
-
"version": "6.30.
|
|
3
|
+
"version": "6.30.4",
|
|
4
4
|
"description": "Persistent long-term memory for Claude Code via MCP — captures coding decisions, bugfixes, and context across sessions. FTS5 BM25 keyword 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",
|