claude-mem-lite 6.30.5 → 6.30.7
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 +10 -9
- package/README.zh-CN.md +10 -9
- package/install.mjs +5 -11
- package/lib/hook-prune.mjs +1 -1
- package/npm-shrinkwrap.json +23 -23
- package/package.json +4 -4
- package/schema.mjs +25 -13
- package/scripts/setup.sh +18 -14
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"plugins": [
|
|
10
10
|
{
|
|
11
11
|
"name": "claude-mem-lite",
|
|
12
|
-
"version": "6.30.
|
|
12
|
+
"version": "6.30.7",
|
|
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.7",
|
|
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/README.md
CHANGED
|
@@ -197,7 +197,7 @@ node install.mjs install
|
|
|
197
197
|
2. **Register MCP server** -- `mem-lite` server with 19 tool definitions (10 core + 9 hidden-but-callable; `mem_search_feedback` is registered only when search telemetry is enabled). The pre-v2.78 generic server name `mem` is renamed to `mem-lite` for namespace hygiene; the tool names themselves (`mem_search`, `mem_recall`, ...) are unchanged.
|
|
198
198
|
3. **Configure hooks** -- all seven lifecycle events: `SessionStart`, `PreCompact`, `PreToolUse`, `PostToolUse`, `PostToolUseFailure`, `Stop`, `UserPromptSubmit`
|
|
199
199
|
4. **Create data directory** -- `~/.claude-mem-lite/` (hidden) for database, runtime, and managed resource files
|
|
200
|
-
5. **Auto-migrate** --
|
|
200
|
+
5. **Auto-migrate** -- `~/.claude-mem/claude-mem.db` (original claude-mem) is moved into `~/.claude-mem-lite/` as a `.legacy-backup-<time>` file and a fresh database is created. A database left in `~/claude-mem-lite/` (the unhidden directory of versions before the first release, 2.0.0) is moved into the data directory at the first open, when the data directory holds no database, log, snapshot or kept copy of a claude-mem-lite store yet; nothing else in either directory is moved or removed
|
|
201
201
|
6. **Initialize database** -- SQLite with WAL mode, FTS5 indexes created on first server start
|
|
202
202
|
|
|
203
203
|
Restart Claude Code after installation to activate.
|
|
@@ -207,20 +207,21 @@ Restart Claude Code after installation to activate.
|
|
|
207
207
|
All installation methods auto-detect and migrate from previous versions:
|
|
208
208
|
|
|
209
209
|
**From claude-mem (original `~/.claude-mem/`):**
|
|
210
|
-
-
|
|
211
|
-
-
|
|
212
|
-
-
|
|
210
|
+
- `claude-mem.db` and its `-wal`/`-shm` are moved into `~/.claude-mem-lite/` under `.legacy-backup-<time>` names (`claude-mem-lite.db.legacy-backup-<time>`, `claude-mem-lite.db-wal.legacy-backup-<time>`), when `~/.claude-mem-lite/claude-mem-lite.db` does not exist yet
|
|
211
|
+
- The plugin install copies `claude-mem.db` alone into the data directory under the first of those names and leaves `~/.claude-mem/` as it is; it does so while the data directory holds neither a database nor such a backup
|
|
212
|
+
- A fresh database is created: the original claude-mem schema has no upgrade path
|
|
213
213
|
|
|
214
|
-
**From
|
|
215
|
-
-
|
|
214
|
+
**From the unhidden directory of versions before the first release, 2.0.0 (`~/claude-mem-lite/`):**
|
|
215
|
+
- Its database (`claude-mem-lite.db` or `claude-mem.db`, with its `-wal` and `-shm`) is moved into the data directory at the first open, when the data directory holds no database, log, snapshot or kept copy of a claude-mem-lite store yet. Nothing else is moved, and nothing in either directory is removed
|
|
216
|
+
- The move is a rename: with `CLAUDE_MEM_DIR` on another filesystem it fails, and so does every open, until the database is moved there by hand together with its `-wal` and `-shm`
|
|
216
217
|
|
|
217
218
|
**In-place rename:**
|
|
218
219
|
- Existing `claude-mem.db` in `~/.claude-mem-lite/` is automatically renamed to `claude-mem-lite.db`
|
|
219
220
|
|
|
220
|
-
Remove old directories manually
|
|
221
|
+
Remove old directories manually once nothing in them is needed. A database still in `~/claude-mem-lite/` has not moved (see above), and the command below deletes it:
|
|
221
222
|
```bash
|
|
222
223
|
rm -rf ~/.claude-mem/ # original claude-mem
|
|
223
|
-
rm -rf ~/claude-mem-lite/ #
|
|
224
|
+
rm -rf ~/claude-mem-lite/ # unhidden data dir from before the first release (not a git clone of this repository)
|
|
224
225
|
```
|
|
225
226
|
|
|
226
227
|
### Directory Structure
|
|
@@ -1069,7 +1070,7 @@ claude-mem-lite/
|
|
|
1069
1070
|
skill.md # MCP skill definition (npx/git clone mode)
|
|
1070
1071
|
package.json # Dependencies and metadata
|
|
1071
1072
|
scripts/
|
|
1072
|
-
setup.sh # Setup hook: npm install + migration (
|
|
1073
|
+
setup.sh # Setup hook: npm install + migration (original claude-mem DB, old file name)
|
|
1073
1074
|
post-tool-use.sh # Bash pre-filter: skips noise in ~5ms, tracks Read paths
|
|
1074
1075
|
user-prompt-search.js # UserPromptSubmit hook: auto-search memory on user prompts
|
|
1075
1076
|
pre-tool-recall.js # PreToolUse hook: file lesson recall before Edit/Write
|
package/README.zh-CN.md
CHANGED
|
@@ -159,7 +159,7 @@ node install.mjs install
|
|
|
159
159
|
> **想把托管块改写进 `CLAUDE.md`**(例如与团队共享)?运行 `claude-mem-lite adopt`:它向 `<cwd>/CLAUDE.md` 写入 slug 限定的托管块和详情文件,块以外的内容逐字保留,并删除自动写入的那份本地副本(`CLAUDE.local.md` 或 rules 文件)。`CLAUDE.md` 一存在,Claude Code 就不再读 `AGENTS.md`,所以 adopt 在 `AGENTS.md`(或 `.claude/AGENTS.md`)旁边新建 `CLAUDE.md` 时,会在文件开头导入它(`@AGENTS.md`,前面一行是 Claude Code 不加载的标记注释),`AGENTS.md` 因此继续加载;上层目录里的、或 git 跟踪在子目录里的 `AGENTS.md` 不能这样导入,adopt 会在输出里列出它们,并给出保留它们的设置(Project instructions 设为 `claude-md-and-agents-md`)。已经有你自己的 `CLAUDE.md` 时不导入,因为那里本来就不读 `AGENTS.md`。`unadopt` 会删除只剩这些行和托管块的 `CLAUDE.md`。带托管块的项目在**每次 SessionStart** 都会同步,出货模板变了会刷新,且不会再叠加本地副本或注入,从子目录启动的会话也一样。只有托管块的 `CLAUDE.md`(旧版本自动 adopt 写的)会在下一次从它所在目录启动的会话里补上同样的 `AGENTS.md` 导入,并给一次性提示。从子目录启动的会话看来,这个导入指向工作目录之外,Claude Code 会请你批准一次。插件创建过、又被你删掉(或被 `claude-mem-lite unadopt` 删掉)的本地托管块(`CLAUDE.local.md` 或 rules 文件)不会被写回,改为注入,直到运行 `claude-mem-lite adopt --enable`(在 `CLAUDE.local.md` 会让 `AGENTS.md` 失效的仓库里,还要设 `CLAUDE_MEM_RULES_STEERING=1` 才会再写文件)。关闭方式:项目级 `claude-mem-lite adopt --disable`(同时删除本地托管块;`CLAUDE.md` 托管块保留到 `unadopt`;重新启用用 `--enable`);全局 `export MEM_NO_AUTO_ADOPT=1`(已写入的托管块保留并继续加载,直到 `unadopt`);只冻结模板刷新用 `CLAUDE_MEM_NO_TEMPLATE_REFRESH=1`。`claude-mem-lite unadopt` 会移除 `CLAUDE.md` 托管块、详情文件,以及本地托管块(`CLAUDE.local.md` 或 `.claude/rules/claude-mem-lite.md`)和它的 exclude 条目。
|
|
160
160
|
3. **配置钩子** -- 全部七个生命周期事件:`SessionStart`、`PreCompact`、`PreToolUse`、`PostToolUse`、`PostToolUseFailure`、`Stop`、`UserPromptSubmit`
|
|
161
161
|
4. **创建数据目录** -- `~/.claude-mem-lite/`(隐藏目录),存放数据库与运行时文件
|
|
162
|
-
5. **自动迁移** --
|
|
162
|
+
5. **自动迁移** -- `~/.claude-mem/claude-mem.db`(原版 claude-mem)以 `.legacy-backup-<时间>` 文件的形式移入 `~/.claude-mem-lite/`,并新建一个数据库。`~/claude-mem-lite/`(首个发布版 2.0.0 之前的非隐藏目录)里留下的数据库在第一次打开时移入数据目录,前提是数据目录里还没有 claude-mem-lite 的数据库、日志、快照或保留副本;两个目录里的其他文件都不移动、不删除
|
|
163
163
|
6. **初始化数据库** -- SQLite WAL 模式,FTS5 索引在服务器首次启动时创建
|
|
164
164
|
|
|
165
165
|
安装后重启 Claude Code 以激活。
|
|
@@ -169,20 +169,21 @@ node install.mjs install
|
|
|
169
169
|
所有安装方式自动检测并从旧版本迁移:
|
|
170
170
|
|
|
171
171
|
**从 claude-mem 原版(`~/.claude-mem/`):**
|
|
172
|
-
-
|
|
173
|
-
-
|
|
174
|
-
-
|
|
172
|
+
- `claude-mem.db` 连同 `-wal`/`-shm` 以 `.legacy-backup-<时间>` 的名字(`claude-mem-lite.db.legacy-backup-<时间>`、`claude-mem-lite.db-wal.legacy-backup-<时间>`)移入 `~/.claude-mem-lite/`,前提是 `~/.claude-mem-lite/claude-mem-lite.db` 还不存在
|
|
173
|
+
- 插件安装只把 `claude-mem.db` 以上面第一个名字复制进数据目录,`~/.claude-mem/` 原样不动;数据目录里既没有数据库、也没有这样的备份时才复制
|
|
174
|
+
- 新建一个数据库:原版 claude-mem 的 schema 没有升级路径
|
|
175
175
|
|
|
176
|
-
|
|
177
|
-
-
|
|
176
|
+
**从首个发布版(2.0.0)之前的非隐藏目录(`~/claude-mem-lite/`):**
|
|
177
|
+
- 它的数据库(`claude-mem-lite.db` 或 `claude-mem.db`,连同 `-wal` 和 `-shm`)在第一次打开时移入数据目录,前提是数据目录里还没有 claude-mem-lite 的数据库、日志、快照或保留副本。其他文件都不移动,两个目录里都不删除任何东西
|
|
178
|
+
- 移动用的是改名:`CLAUDE_MEM_DIR` 在另一个文件系统上时会失败,之后每次打开都失败,直到手动把数据库连同 `-wal` 和 `-shm` 移过去
|
|
178
179
|
|
|
179
180
|
**就地重命名:**
|
|
180
181
|
- 已有的 `~/.claude-mem-lite/claude-mem.db` 会自动重命名为 `claude-mem-lite.db`
|
|
181
182
|
|
|
182
|
-
|
|
183
|
+
确认里面的东西都不再需要后,手动删除旧目录。`~/claude-mem-lite/` 里还在的数据库没有被迁移(见上文),下面的命令会删掉它:
|
|
183
184
|
```bash
|
|
184
185
|
rm -rf ~/.claude-mem/ # 原版 claude-mem
|
|
185
|
-
rm -rf ~/claude-mem-lite/ #
|
|
186
|
+
rm -rf ~/claude-mem-lite/ # 首个发布版之前的非隐藏目录(不是本仓库的 git 克隆)
|
|
186
187
|
```
|
|
187
188
|
|
|
188
189
|
### 目录结构
|
|
@@ -839,7 +840,7 @@ claude-mem-lite/
|
|
|
839
840
|
skill.md # MCP 技能定义(npx/git clone 模式)
|
|
840
841
|
package.json # 依赖和元数据
|
|
841
842
|
scripts/
|
|
842
|
-
setup.sh # Setup 钩子:npm install +
|
|
843
|
+
setup.sh # Setup 钩子:npm install + 迁移(原版 claude-mem 数据库、旧文件名)
|
|
843
844
|
post-tool-use.sh # Bash 预过滤器:~5ms 跳过噪声,追踪 Read 路径
|
|
844
845
|
user-prompt-search.js # UserPromptSubmit 钩子:用户提问时自动搜索记忆
|
|
845
846
|
pre-tool-recall.js # PreToolUse 钩子:Edit/Write 前文件教训回忆
|
package/install.mjs
CHANGED
|
@@ -530,18 +530,12 @@ export async function withSwapBarrier(fn) {
|
|
|
530
530
|
}
|
|
531
531
|
}
|
|
532
532
|
|
|
533
|
-
// Creates the data dirs the swap barrier then writes its marker into.
|
|
534
|
-
//
|
|
535
|
-
//
|
|
533
|
+
// Creates the data dirs the swap barrier then writes its marker into. A store left in the
|
|
534
|
+
// unhidden dir of versions before the first release (~/claude-mem-lite/) is ensureDb's to move
|
|
535
|
+
// (migrateUnhiddenStore). Install no longer renames that directory into the code dir (D#561): it
|
|
536
|
+
// did so only under CLAUDE_MEM_DIR relocation, where the code dir does not exist yet, and that
|
|
537
|
+
// directory can be a git clone of this repository made in ~.
|
|
536
538
|
function prepareInstallDirs() {
|
|
537
|
-
// Auto-migrate unhidden dir (~/claude-mem-lite/ → ~/.claude-mem-lite/)
|
|
538
|
-
const oldUnhidden = join(homedir(), 'claude-mem-lite');
|
|
539
|
-
if (!existsSync(DATA_DIR) && existsSync(oldUnhidden)) {
|
|
540
|
-
log('Migrating ~/claude-mem-lite/ → ~/.claude-mem-lite/...');
|
|
541
|
-
renameSync(oldUnhidden, DATA_DIR);
|
|
542
|
-
ok('Directory migrated');
|
|
543
|
-
}
|
|
544
|
-
|
|
545
539
|
if (!existsSync(DATA_DIR)) mkdirSync(DATA_DIR, { recursive: true });
|
|
546
540
|
// Under relocation the DB/managed/runtime live here, not in the code dir — create it too.
|
|
547
541
|
if (!existsSync(MEM_DATA_DIR)) mkdirSync(MEM_DATA_DIR, { recursive: true });
|
package/lib/hook-prune.mjs
CHANGED
|
@@ -34,7 +34,7 @@ export function isMemHook(cfg, roots = null) {
|
|
|
34
34
|
|
|
35
35
|
// The product name only as the DIRECTORY holding one of our entry points — every shape an
|
|
36
36
|
// install has written: `<dir>/hook.mjs <event>` (legacy direct) and `<dir>/scripts/<x>.js|mjs|sh`,
|
|
37
|
-
// under `.claude-mem-lite`, the pre-
|
|
37
|
+
// under `.claude-mem-lite`, the pre-2.0.0 unhidden `claude-mem-lite`, or a checkout named after it
|
|
38
38
|
// (`claude-mem-lite-main` from a zip), with either separator. A bare substring also took
|
|
39
39
|
// `claude-mem-lite export > ~/backups/…` and `~/tools/claude-mem-lite-prompt-audit.py`, which
|
|
40
40
|
// install and uninstall then deleted. The directory name alone still took a user's own
|
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.7",
|
|
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.7",
|
|
10
10
|
"os": [
|
|
11
11
|
"darwin",
|
|
12
12
|
"linux",
|
|
@@ -22,11 +22,11 @@
|
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"@eslint/js": "^10.0.1",
|
|
25
|
-
"@vitest/coverage-v8": "^5.0.
|
|
25
|
+
"@vitest/coverage-v8": "^5.0.5",
|
|
26
26
|
"acorn": "8.19.0",
|
|
27
|
-
"eslint": "^10.
|
|
27
|
+
"eslint": "^10.13.0",
|
|
28
28
|
"fast-check": "^4.10.2",
|
|
29
|
-
"knip": "^6.
|
|
29
|
+
"knip": "^6.42.1",
|
|
30
30
|
"picomatch": "^4.0.4",
|
|
31
31
|
"prettier": "3.9.10",
|
|
32
32
|
"vitest": "^5.0.3"
|
|
@@ -146,18 +146,18 @@
|
|
|
146
146
|
}
|
|
147
147
|
},
|
|
148
148
|
"node_modules/body-parser": {
|
|
149
|
-
"version": "2.
|
|
150
|
-
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.
|
|
151
|
-
"integrity": "sha512-
|
|
149
|
+
"version": "2.4.0",
|
|
150
|
+
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.4.0.tgz",
|
|
151
|
+
"integrity": "sha512-Ifk1KcLrxaGt1occQagQNFNNOqRt1LFuehEnHHzB8Z6cRgIxRU1TBaiIsUiCdA+gy5PL7Y1IX31DNKkRmxtXjQ==",
|
|
152
152
|
"license": "MIT",
|
|
153
153
|
"dependencies": {
|
|
154
154
|
"bytes": "^3.1.2",
|
|
155
|
-
"content-type": "^2.
|
|
155
|
+
"content-type": "^2.1.0",
|
|
156
156
|
"debug": "^4.4.3",
|
|
157
157
|
"http-errors": "^2.0.1",
|
|
158
|
-
"iconv-lite": "^0.7.
|
|
158
|
+
"iconv-lite": "^0.7.3",
|
|
159
159
|
"on-finished": "^2.4.1",
|
|
160
|
-
"qs": "^6.
|
|
160
|
+
"qs": "^6.16.1",
|
|
161
161
|
"raw-body": "^3.0.2",
|
|
162
162
|
"type-is": "^2.1.0"
|
|
163
163
|
},
|
|
@@ -170,9 +170,9 @@
|
|
|
170
170
|
}
|
|
171
171
|
},
|
|
172
172
|
"node_modules/body-parser/node_modules/content-type": {
|
|
173
|
-
"version": "2.
|
|
174
|
-
"resolved": "https://registry.npmjs.org/content-type/-/content-type-2.
|
|
175
|
-
"integrity": "sha512-
|
|
173
|
+
"version": "2.1.0",
|
|
174
|
+
"resolved": "https://registry.npmjs.org/content-type/-/content-type-2.1.0.tgz",
|
|
175
|
+
"integrity": "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==",
|
|
176
176
|
"license": "MIT",
|
|
177
177
|
"engines": {
|
|
178
178
|
"node": ">=18"
|
|
@@ -480,9 +480,9 @@
|
|
|
480
480
|
"license": "MIT"
|
|
481
481
|
},
|
|
482
482
|
"node_modules/fast-uri": {
|
|
483
|
-
"version": "3.1.
|
|
484
|
-
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.
|
|
485
|
-
"integrity": "sha512-
|
|
483
|
+
"version": "3.1.9",
|
|
484
|
+
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.9.tgz",
|
|
485
|
+
"integrity": "sha512-hS/0Wt3Ya043oKXs0sIxrMpKQITXhMLIrVAKKXi4gozGC9v7YRWVnXIZzjNPTO02M9BdxLCWqK1yRXgNziVyJQ==",
|
|
486
486
|
"funding": [
|
|
487
487
|
{
|
|
488
488
|
"type": "github",
|
|
@@ -646,9 +646,9 @@
|
|
|
646
646
|
}
|
|
647
647
|
},
|
|
648
648
|
"node_modules/iconv-lite": {
|
|
649
|
-
"version": "0.7.
|
|
650
|
-
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.
|
|
651
|
-
"integrity": "sha512-
|
|
649
|
+
"version": "0.7.3",
|
|
650
|
+
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz",
|
|
651
|
+
"integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==",
|
|
652
652
|
"license": "MIT",
|
|
653
653
|
"dependencies": {
|
|
654
654
|
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
|
@@ -894,9 +894,9 @@
|
|
|
894
894
|
}
|
|
895
895
|
},
|
|
896
896
|
"node_modules/qs": {
|
|
897
|
-
"version": "6.16.
|
|
898
|
-
"resolved": "https://registry.npmjs.org/qs/-/qs-6.16.
|
|
899
|
-
"integrity": "sha512-
|
|
897
|
+
"version": "6.16.1",
|
|
898
|
+
"resolved": "https://registry.npmjs.org/qs/-/qs-6.16.1.tgz",
|
|
899
|
+
"integrity": "sha512-5Px6J7rfHBAGUhNQ3es4YzcOdBBw0SDcVtThJml4RdnKw4tKs2epA0kPZ+K8X+WiHktT93RHVcQ/3ym5aTCgtg==",
|
|
900
900
|
"license": "BSD-3-Clause",
|
|
901
901
|
"dependencies": {
|
|
902
902
|
"es-define-property": "^1.0.1",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-mem-lite",
|
|
3
|
-
"version": "6.30.
|
|
3
|
+
"version": "6.30.7",
|
|
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",
|
|
@@ -249,11 +249,11 @@
|
|
|
249
249
|
},
|
|
250
250
|
"devDependencies": {
|
|
251
251
|
"@eslint/js": "^10.0.1",
|
|
252
|
-
"@vitest/coverage-v8": "^5.0.
|
|
252
|
+
"@vitest/coverage-v8": "^5.0.5",
|
|
253
253
|
"acorn": "8.19.0",
|
|
254
|
-
"eslint": "^10.
|
|
254
|
+
"eslint": "^10.13.0",
|
|
255
255
|
"fast-check": "^4.10.2",
|
|
256
|
-
"knip": "^6.
|
|
256
|
+
"knip": "^6.42.1",
|
|
257
257
|
"picomatch": "^4.0.4",
|
|
258
258
|
"prettier": "3.9.10",
|
|
259
259
|
"vitest": "^5.0.3"
|
package/schema.mjs
CHANGED
|
@@ -1657,6 +1657,30 @@ function capBusyWaits(db) {
|
|
|
1657
1657
|
};
|
|
1658
1658
|
}
|
|
1659
1659
|
|
|
1660
|
+
/**
|
|
1661
|
+
* Move a store left in the unhidden data dir of versions before the first release (2.0.0),
|
|
1662
|
+
* ~/claude-mem-lite/, into DB_DIR. Only the store's own files move (the database, then its -wal
|
|
1663
|
+
* and -shm, under the same name; ensureDb then renames claude-mem.db), and only into a DB_DIR
|
|
1664
|
+
* holding no file of a store's family: a database, a log, a snapshot or a kept copy. install's
|
|
1665
|
+
* backup of an original claude-mem store (migrateLegacyClaudeMemData, `.legacy-backup-<ms>`) is
|
|
1666
|
+
* not one. Nothing is removed. It used to rename the whole directory over a DB_DIR it first
|
|
1667
|
+
* removed when DB_DIR held no `*.db` name (D#561): after the set-aside command that took the kept
|
|
1668
|
+
* file, DB_DIR is also the code dir of a direct install, and a git clone of this repository made
|
|
1669
|
+
* in ~ is at that path.
|
|
1670
|
+
*/
|
|
1671
|
+
function migrateUnhiddenStore() {
|
|
1672
|
+
const oldDir = join(homedir(), 'claude-mem-lite');
|
|
1673
|
+
const name = ['claude-mem-lite.db', 'claude-mem.db'].find((n) => existsSync(join(oldDir, n)));
|
|
1674
|
+
if (!name) return;
|
|
1675
|
+
const storeFile = (f) =>
|
|
1676
|
+
(f.startsWith('claude-mem-lite.db') || f.startsWith('claude-mem.db')) && !/\.legacy-backup-\d+$/.test(f);
|
|
1677
|
+
if (existsSync(DB_DIR) && readdirSync(DB_DIR).some(storeFile)) return;
|
|
1678
|
+
mkdirSync(DB_DIR, { recursive: true, mode: 0o700 });
|
|
1679
|
+
for (const ext of ['', '-wal', '-shm']) {
|
|
1680
|
+
if (existsSync(join(oldDir, name + ext))) renameSync(join(oldDir, name + ext), join(DB_DIR, name + ext));
|
|
1681
|
+
}
|
|
1682
|
+
}
|
|
1683
|
+
|
|
1660
1684
|
/**
|
|
1661
1685
|
* Ensure DB directory, database file, and all tables exist.
|
|
1662
1686
|
* Safe to call from any process (hook or server). Idempotent.
|
|
@@ -1671,19 +1695,7 @@ export function ensureDb() {
|
|
|
1671
1695
|
code: 'CLAUDE_MEM_DATA_DIR_GONE',
|
|
1672
1696
|
});
|
|
1673
1697
|
}
|
|
1674
|
-
|
|
1675
|
-
// Check DB_PATH (not DB_DIR) because hook-shared.mjs module-level init may create DB_DIR early
|
|
1676
|
-
const oldUnhidden = join(homedir(), 'claude-mem-lite');
|
|
1677
|
-
if (existsSync(oldUnhidden) && !existsSync(DB_PATH)) {
|
|
1678
|
-
// Remove DB_DIR only if it has no user data (no .db files)
|
|
1679
|
-
if (existsSync(DB_DIR)) {
|
|
1680
|
-
try {
|
|
1681
|
-
const hasDbFiles = readdirSync(DB_DIR).some((f) => f.endsWith('.db'));
|
|
1682
|
-
if (!hasDbFiles) rmSync(DB_DIR, { recursive: true, force: true });
|
|
1683
|
-
} catch {}
|
|
1684
|
-
}
|
|
1685
|
-
if (!existsSync(DB_DIR)) renameSync(oldUnhidden, DB_DIR);
|
|
1686
|
-
}
|
|
1698
|
+
if (!existsSync(DB_PATH)) migrateUnhiddenStore();
|
|
1687
1699
|
|
|
1688
1700
|
if (!existsSync(DB_DIR)) mkdirSync(DB_DIR, { recursive: true, mode: 0o700 });
|
|
1689
1701
|
|
package/scripts/setup.sh
CHANGED
|
@@ -99,8 +99,6 @@ if [[ -n "${CLAUDE_MEM_DIR:-}" || -n "${CLAUDE_MEM_RUNTIME_DIR:-}" ]] && [[ -f "
|
|
|
99
99
|
unset _resolved _db _rt
|
|
100
100
|
fi
|
|
101
101
|
|
|
102
|
-
OLD_UNHIDDEN_DIR="$HOME/claude-mem-lite"
|
|
103
|
-
|
|
104
102
|
# Colors
|
|
105
103
|
if [[ -t 2 ]]; then
|
|
106
104
|
GREEN='\033[0;32m'; YELLOW='\033[0;33m'; BLUE='\033[0;34m'; RED='\033[0;31m'; NC='\033[0m'
|
|
@@ -120,17 +118,12 @@ log_warn() { echo -e "${YELLOW}⚠${NC} $*" >&2; }
|
|
|
120
118
|
# day GitHub bumps the runner image. Keep SC2317 for anyone on an older shellcheck.
|
|
121
119
|
log_err() { echo -e "${RED}✗${NC} $*" >&2; }
|
|
122
120
|
|
|
123
|
-
# 1.
|
|
124
|
-
#
|
|
125
|
-
#
|
|
126
|
-
#
|
|
127
|
-
# strand every absolute path settings.json and the MCP registration baked.
|
|
128
|
-
if [[ -d "$OLD_UNHIDDEN_DIR" && ! -d "$CODE_DIR" ]]; then
|
|
129
|
-
mv "$OLD_UNHIDDEN_DIR" "$CODE_DIR"
|
|
130
|
-
log_ok "Migrated ~/claude-mem-lite/ → ~/.claude-mem-lite/"
|
|
131
|
-
fi
|
|
121
|
+
# 1. ~/claude-mem-lite/ (the unhidden dir of versions before the first release) is not moved
|
|
122
|
+
# here: the first open moves a store left there into DB_DIR, and only the store
|
|
123
|
+
# (schema.mjs migrateUnhiddenStore). This script moved the whole directory into a missing
|
|
124
|
+
# CODE_DIR, and a git clone of this repository made in ~ is at that path (D#568).
|
|
132
125
|
|
|
133
|
-
# 2. Ensure both locations exist
|
|
126
|
+
# 2. Ensure both locations exist
|
|
134
127
|
mkdir -p "$CODE_DIR"
|
|
135
128
|
mkdir -p "$DB_DIR"
|
|
136
129
|
if [[ "$DB_DIR" == "$CODE_DIR" ]]; then
|
|
@@ -150,8 +143,19 @@ fi
|
|
|
150
143
|
# a relocation it never closed — nothing ever writes a database THERE — so this block
|
|
151
144
|
# copied the legacy database again on every single SessionStart, without bound. Measured
|
|
152
145
|
# 2026-09-14: control arm stable at 1 backup across three runs, relocated arm 1 → 3.
|
|
146
|
+
# A backup already in DB_DIR closes it as well: while every open fails before creating the
|
|
147
|
+
# database (D#569's EXDEV did), the first condition never closes (D#573). Only the suffix is a
|
|
148
|
+
# pattern, so a `[` or `*` in DB_DIR's own path is matched as itself.
|
|
153
149
|
OLD_DIR="$HOME/.claude-mem"
|
|
154
|
-
|
|
150
|
+
has_legacy_backup() {
|
|
151
|
+
local f
|
|
152
|
+
for f in "$DB_DIR"/claude-mem-lite.db.legacy-backup-*; do
|
|
153
|
+
[[ -e "$f" ]] && return 0
|
|
154
|
+
done
|
|
155
|
+
return 1
|
|
156
|
+
}
|
|
157
|
+
if [[ -f "$OLD_DIR/claude-mem.db" && ! -f "$DB_DIR/claude-mem-lite.db" && ! -f "$DB_DIR/claude-mem.db" ]] &&
|
|
158
|
+
! has_legacy_backup; then
|
|
155
159
|
BACKUP="$DB_DIR/claude-mem-lite.db.legacy-backup-$(date +%s)"
|
|
156
160
|
if cp "$OLD_DIR/claude-mem.db" "$BACKUP" 2>/dev/null; then
|
|
157
161
|
log_info "Legacy ~/.claude-mem/ DB is schema-incompatible; backed up to $(basename "$BACKUP") (a fresh DB will be created). Old ~/.claude-mem/ preserved."
|
|
@@ -169,7 +173,7 @@ if [[ -f "$DB_DIR/claude-mem.db" && ! -f "$DB_DIR/claude-mem-lite.db" ]]; then
|
|
|
169
173
|
log_ok "Database renamed: claude-mem.db → claude-mem-lite.db"
|
|
170
174
|
fi
|
|
171
175
|
|
|
172
|
-
# 5. Ensure runtime directories exist
|
|
176
|
+
# 5. Ensure runtime directories exist.
|
|
173
177
|
# Both: RUNTIME_DIR carries the cross-component flag below, while CODE_DIR/runtime keeps
|
|
174
178
|
# the two run-once install markers at the bottom of this file.
|
|
175
179
|
mkdir -p "$RUNTIME_DIR"
|