claude-mem-lite 2.84.0 → 2.84.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/README.md +18 -0
- package/README.zh-CN.md +18 -0
- package/install.mjs +34 -8
- package/package.json +1 -1
- package/scripts/hook-launcher.mjs +18 -3
package/README.md
CHANGED
|
@@ -498,6 +498,24 @@ Checks Node.js version, dependencies, server/hook files, database integrity, FTS
|
|
|
498
498
|
|
|
499
499
|
Shows MCP registration, hook configuration, plugin disabled state, and database stats (observation/session counts).
|
|
500
500
|
|
|
501
|
+
### Recovery (stuck install / hook errors)
|
|
502
|
+
|
|
503
|
+
If you see `ERR_MODULE_NOT_FOUND` on PreToolUse:Read/Edit/Skill hooks, or `claude-mem-lite` commands crash with import errors, you're likely hit by a partial auto-update — the updater copied new scripts but missed a sibling `lib/*` file, breaking the hook chain (and the next auto-update that would have healed it).
|
|
504
|
+
|
|
505
|
+
**v2.84.0+** ships a `repair` subcommand that re-syncs from the latest GitHub release:
|
|
506
|
+
|
|
507
|
+
```bash
|
|
508
|
+
claude-mem-lite repair
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
**If `repair` itself fails** (the bin is older than v2.84.0, or the bin is also broken), run this one-liner — it pulls a fresh tarball into a temp dir and runs *that* tarball's `install.mjs`, bypassing every file on your disk:
|
|
512
|
+
|
|
513
|
+
```bash
|
|
514
|
+
T=$(mktemp -d) && curl -sL https://api.github.com/repos/sdsrss/claude-mem-lite/tarball | tar xz -C "$T" --strip-components=1 && node "$T/install.mjs" install
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
After it finishes, `~/.claude-mem-lite/` is back in sync with the latest release and `claude-mem-lite repair` is available for next time.
|
|
518
|
+
|
|
501
519
|
## Uninstall
|
|
502
520
|
|
|
503
521
|
```bash
|
package/README.zh-CN.md
CHANGED
|
@@ -460,6 +460,24 @@ npx claude-mem-lite doctor # 诊断问题
|
|
|
460
460
|
|
|
461
461
|
显示 MCP 注册状态、钩子配置、插件禁用状态和数据库统计(观察/会话数量)。
|
|
462
462
|
|
|
463
|
+
### 故障恢复(安装卡死 / hook 报错)
|
|
464
|
+
|
|
465
|
+
如果你看到 PreToolUse:Read/Edit/Skill hook 报 `ERR_MODULE_NOT_FOUND`,或者 `claude-mem-lite` 命令本身因为 import 错误崩溃,多半是被部分自动更新坑了——更新器复制了新脚本但漏了配套的 `lib/*` 文件,hook 链就此断掉(连下一次本可自愈的自动更新也跑不了)。
|
|
466
|
+
|
|
467
|
+
**v2.84.0+** 提供 `repair` 子命令,从 GitHub 最新 release 重新同步:
|
|
468
|
+
|
|
469
|
+
```bash
|
|
470
|
+
claude-mem-lite repair
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
**如果 `repair` 自己也跑不起来**(bin 比 v2.84.0 旧,或 bin 也坏了),用这条单行命令——它把最新 tarball 拉到临时目录、跑 *那份* tarball 里的 `install.mjs`,完全不依赖你磁盘上的任何文件:
|
|
474
|
+
|
|
475
|
+
```bash
|
|
476
|
+
T=$(mktemp -d) && curl -sL https://api.github.com/repos/sdsrss/claude-mem-lite/tarball | tar xz -C "$T" --strip-components=1 && node "$T/install.mjs" install
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
跑完之后,`~/.claude-mem-lite/` 就和最新 release 对齐,`claude-mem-lite repair` 下次再遇到类似问题也能直接用了。
|
|
480
|
+
|
|
463
481
|
## 卸载
|
|
464
482
|
|
|
465
483
|
```bash
|
package/install.mjs
CHANGED
|
@@ -5,7 +5,8 @@ import { execSync, execFileSync } from 'child_process';
|
|
|
5
5
|
import { readFileSync, writeFileSync, existsSync, rmSync, mkdirSync, copyFileSync, cpSync, renameSync, symlinkSync, unlinkSync, readdirSync, statSync, lstatSync } from 'fs';
|
|
6
6
|
import { join, resolve, dirname, isAbsolute } from 'path';
|
|
7
7
|
import { homedir, tmpdir } from 'os';
|
|
8
|
-
import { fileURLToPath } from 'url';
|
|
8
|
+
import { fileURLToPath, pathToFileURL } from 'url';
|
|
9
|
+
import { createRequire } from 'node:module';
|
|
9
10
|
|
|
10
11
|
const PROJECT_DIR = resolve(import.meta.dirname ?? dirname(fileURLToPath(import.meta.url)));
|
|
11
12
|
const SETTINGS_PATH = join(homedir(), '.claude', 'settings.json');
|
|
@@ -186,9 +187,19 @@ function registerVirtualResources(rdb) {
|
|
|
186
187
|
);
|
|
187
188
|
count += changes;
|
|
188
189
|
|
|
189
|
-
// Backfill FTS5 fields for existing resources
|
|
190
|
+
// Backfill FTS5 fields for existing resources.
|
|
191
|
+
// ?N numbered placeholders REQUIRE object-form binding in better-sqlite3 —
|
|
192
|
+
// positional .run(v1, v2, …) always throws "Too many parameter values"
|
|
193
|
+
// regardless of arg count. Pre-fix this swallow-warned on every install
|
|
194
|
+
// (masked by install.mjs:785 import failure before the v2.84.2 path fix).
|
|
190
195
|
if (changes === 0) {
|
|
191
|
-
updateFts.run(
|
|
196
|
+
updateFts.run({
|
|
197
|
+
1: meta.keywords || '',
|
|
198
|
+
2: meta.tech_stack || '',
|
|
199
|
+
3: meta.use_cases || '',
|
|
200
|
+
4: type,
|
|
201
|
+
5: name,
|
|
202
|
+
});
|
|
192
203
|
}
|
|
193
204
|
}
|
|
194
205
|
|
|
@@ -285,6 +296,16 @@ function isDevInstall() {
|
|
|
285
296
|
async function install() {
|
|
286
297
|
console.log('\nclaude-mem-lite installer\n');
|
|
287
298
|
|
|
299
|
+
// Resolve dynamic imports against the installed copy at INSTALL_DIR rather
|
|
300
|
+
// than install.mjs's own directory. Lets install.mjs run correctly from a
|
|
301
|
+
// /tmp staging dir (repair flow, `curl … | tar xz | node install.mjs install`)
|
|
302
|
+
// where PROJECT_DIR has no node_modules but INSTALL_DIR does — step 2 below
|
|
303
|
+
// ran `npm install --cwd INSTALL_DIR`. Pre-fix, steps 6/7 fired
|
|
304
|
+
// "Cannot find package 'better-sqlite3' imported from /tmp/…/registry.mjs"
|
|
305
|
+
// and silently skipped registry-DB seeding + DB health check on every repair.
|
|
306
|
+
const importFromInstall = (rel) => import(pathToFileURL(join(INSTALL_DIR, rel)).href);
|
|
307
|
+
const requireFromInstall = createRequire(pathToFileURL(join(INSTALL_DIR, 'package.json')).href);
|
|
308
|
+
|
|
288
309
|
// 1. Install source files to ~/.claude-mem-lite/
|
|
289
310
|
const IS_DEV = flags.has('--dev');
|
|
290
311
|
|
|
@@ -782,7 +803,7 @@ async function install() {
|
|
|
782
803
|
(deadRepos.size > 0 ? `, ${deadRepos.size} dead removed` : ''));
|
|
783
804
|
|
|
784
805
|
// 6b. Init registry DB and record preinstalled entries
|
|
785
|
-
const { ensureRegistryDb } = await
|
|
806
|
+
const { ensureRegistryDb } = await importFromInstall('registry.mjs');
|
|
786
807
|
const regDbPath = join(DATA_DIR, 'resource-registry.db');
|
|
787
808
|
const rdb = ensureRegistryDb(regDbPath);
|
|
788
809
|
|
|
@@ -830,7 +851,7 @@ async function install() {
|
|
|
830
851
|
|
|
831
852
|
// 6d. Scan and index resources (fallback-only, Haiku indexing deferred to first run)
|
|
832
853
|
log(' Scanning resources...');
|
|
833
|
-
const { scanAllResources, diffResources } = await
|
|
854
|
+
const { scanAllResources, diffResources } = await importFromInstall('registry-scanner.mjs');
|
|
834
855
|
const scanned = scanAllResources({ dataDir: DATA_DIR });
|
|
835
856
|
|
|
836
857
|
// Attach star counts and repo URLs
|
|
@@ -846,7 +867,7 @@ async function install() {
|
|
|
846
867
|
if (toIndex.length > 0) {
|
|
847
868
|
// Use fallback indexing at install time (no Haiku calls)
|
|
848
869
|
// Full Haiku indexing happens on first SessionStart
|
|
849
|
-
const { upsertResource } = await
|
|
870
|
+
const { upsertResource } = await importFromInstall('registry.mjs');
|
|
850
871
|
for (const res of toIndex) {
|
|
851
872
|
try {
|
|
852
873
|
const metaKey = `${res.type}:${res.name}`;
|
|
@@ -892,7 +913,7 @@ async function install() {
|
|
|
892
913
|
// 7. Verify database
|
|
893
914
|
if (existsSync(DB_PATH)) {
|
|
894
915
|
try {
|
|
895
|
-
const Database = (
|
|
916
|
+
const Database = requireFromInstall('better-sqlite3');
|
|
896
917
|
const db = new Database(DB_PATH, { readonly: true });
|
|
897
918
|
const count = db.prepare('SELECT COUNT(*) as c FROM observations').get();
|
|
898
919
|
db.close();
|
|
@@ -914,7 +935,7 @@ async function install() {
|
|
|
914
935
|
const remote = execFileSync('git', ['-C', PROJECT_DIR, 'config', '--get', 'remote.origin.url'], { encoding: 'utf8', stdio: 'pipe' }).trim();
|
|
915
936
|
const isDogfood = /github\.com[:/]sdsrss\/claude-mem-lite(\.git)?$/i.test(remote);
|
|
916
937
|
if (isDogfood) {
|
|
917
|
-
const { cmdAdopt } = await
|
|
938
|
+
const { cmdAdopt } = await importFromInstall('adopt-cli.mjs');
|
|
918
939
|
cmdAdopt([]);
|
|
919
940
|
ok('Invited-memory: auto-adopt for claude-mem-lite dogfood repo');
|
|
920
941
|
}
|
|
@@ -1795,6 +1816,11 @@ async function repair() {
|
|
|
1795
1816
|
ok('Repair complete — broken install resynced from latest release');
|
|
1796
1817
|
} catch (e) {
|
|
1797
1818
|
fail(`Repair failed: ${e.message}`);
|
|
1819
|
+
console.log('');
|
|
1820
|
+
console.log(' Manual fallback — run this in any shell:');
|
|
1821
|
+
console.log('');
|
|
1822
|
+
console.log(' T=$(mktemp -d) && curl -sL https://api.github.com/repos/sdsrss/claude-mem-lite/tarball | tar xz -C "$T" --strip-components=1 && node "$T/install.mjs" install');
|
|
1823
|
+
console.log('');
|
|
1798
1824
|
process.exit(1);
|
|
1799
1825
|
} finally {
|
|
1800
1826
|
try { rmSync(stagingDir, { recursive: true, force: true }); } catch {}
|
package/package.json
CHANGED
|
@@ -32,6 +32,13 @@ const RUNTIME_DIR = process.env.CLAUDE_MEM_DIR
|
|
|
32
32
|
const HEAL_MARKER = join(RUNTIME_DIR, 'hook-launcher-lastheal');
|
|
33
33
|
const HEAL_COOLDOWN_MS = 6 * 60 * 60 * 1000;
|
|
34
34
|
|
|
35
|
+
// Last-resort recovery string for users whose `claude-mem-lite repair` path
|
|
36
|
+
// itself failed (install.mjs missing / repair errored / retry still drifting).
|
|
37
|
+
// Duplicated in install.mjs::repair() catch; both are reachable when local
|
|
38
|
+
// scripts are broken, so neither can import a shared constant.
|
|
39
|
+
const TARBALL_FALLBACK =
|
|
40
|
+
'T=$(mktemp -d) && curl -sL https://api.github.com/repos/sdsrss/claude-mem-lite/tarball | tar xz -C "$T" --strip-components=1 && node "$T/install.mjs" install';
|
|
41
|
+
|
|
35
42
|
const [, , entryArg, ...rest] = process.argv;
|
|
36
43
|
if (!entryArg) {
|
|
37
44
|
process.stderr.write('[claude-mem-lite] hook-launcher: missing entry argument\n');
|
|
@@ -74,7 +81,9 @@ function recordHealAttempt() {
|
|
|
74
81
|
async function attemptHeal(reason) {
|
|
75
82
|
if (recentHealAttempt()) {
|
|
76
83
|
process.stderr.write(
|
|
77
|
-
`[claude-mem-lite] Self-heal skipped (last attempt < 6h ago)
|
|
84
|
+
`[claude-mem-lite] Self-heal skipped (last attempt < 6h ago).\n` +
|
|
85
|
+
`[claude-mem-lite] Manual recovery: claude-mem-lite repair\n` +
|
|
86
|
+
`[claude-mem-lite] If that fails, run: ${TARBALL_FALLBACK}\n`,
|
|
78
87
|
);
|
|
79
88
|
return false;
|
|
80
89
|
}
|
|
@@ -82,7 +91,10 @@ async function attemptHeal(reason) {
|
|
|
82
91
|
process.stderr.write(`[claude-mem-lite] Detected broken install (${reason}) — running self-heal\n`);
|
|
83
92
|
const installer = join(INSTALL_DIR, 'install.mjs');
|
|
84
93
|
if (!existsSync(installer)) {
|
|
85
|
-
process.stderr.write(
|
|
94
|
+
process.stderr.write(
|
|
95
|
+
`[claude-mem-lite] install.mjs missing at ${installer} — cannot self-heal\n` +
|
|
96
|
+
`[claude-mem-lite] Manual recovery: ${TARBALL_FALLBACK}\n`,
|
|
97
|
+
);
|
|
86
98
|
return false;
|
|
87
99
|
}
|
|
88
100
|
const result = spawnSync(process.execPath, [installer, 'repair'], {
|
|
@@ -102,7 +114,10 @@ try {
|
|
|
102
114
|
try {
|
|
103
115
|
await runEntry({ bustCache: true });
|
|
104
116
|
} catch (retryErr) {
|
|
105
|
-
process.stderr.write(
|
|
117
|
+
process.stderr.write(
|
|
118
|
+
`[claude-mem-lite] Hook still failing after self-heal: ${retryErr.message}\n` +
|
|
119
|
+
`[claude-mem-lite] Manual recovery: ${TARBALL_FALLBACK}\n`,
|
|
120
|
+
);
|
|
106
121
|
process.exit(1);
|
|
107
122
|
}
|
|
108
123
|
}
|