claude-mem-lite 2.79.1 → 2.80.0
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 +1 -1
- package/README.zh-CN.md +1 -1
- package/install.mjs +18 -4
- package/lib/citation-tracker.mjs +11 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -161,7 +161,7 @@ Source files stay in the cloned repo. Update via `git pull && node install.mjs i
|
|
|
161
161
|
### What happens during installation
|
|
162
162
|
|
|
163
163
|
1. **Install dependencies** -- `npm install --omit=dev` (compiles native `better-sqlite3`)
|
|
164
|
-
2. **Register MCP server** -- `mem-lite` server with
|
|
164
|
+
2. **Register MCP server** -- `mem-lite` server with 20 tools (9 core exposed via `tools/list` + 11 hidden-but-callable; see the Usage section for the full table). 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.
|
|
165
165
|
3. **Configure hooks** -- `PostToolUse`, `SessionStart`, `Stop`, `UserPromptSubmit` lifecycle hooks
|
|
166
166
|
4. **Create data directory** -- `~/.claude-mem-lite/` (hidden) for database, runtime, and managed resource files
|
|
167
167
|
5. **Auto-migrate** -- If `~/.claude-mem/` (original claude-mem) or `~/claude-mem-lite/` (pre-v0.5 unhidden) exists, migrates database and runtime files to `~/.claude-mem-lite/`, preserving the original untouched
|
package/README.zh-CN.md
CHANGED
|
@@ -146,7 +146,7 @@ node install.mjs install
|
|
|
146
146
|
### 安装过程
|
|
147
147
|
|
|
148
148
|
1. **安装依赖** -- `npm install --omit=dev`(编译原生 `better-sqlite3`)
|
|
149
|
-
2. **注册 MCP 服务器** -- `mem-lite` 服务器,包含
|
|
149
|
+
2. **注册 MCP 服务器** -- `mem-lite` 服务器,包含 20 个工具(9 个核心通过 `tools/list` 暴露 + 11 个隐藏但可调;完整表见 Usage 段)。v2.78 前服务器名为通用的 `mem`,现已改名为 `mem-lite` 避免与用户其它 `.mcp.json` 冲突;工具名(`mem_search`/`mem_recall` 等)保持不变。
|
|
150
150
|
|
|
151
151
|
> **每个项目第一次使用,跑一次 `/adopt`。** Plugin 安装给你 MCP server + hooks + slash commands,但**邀请式 memory 哨兵**(一条提升 Claude 主动调用 `mem_recall` / `mem_save` 的 system-authority 指针)是按项目 opt-in 的。不跑 `/adopt` 时 hooks 仍记录观察、注入上下文,但 Claude 不太会主动调 MCP 工具。一次性、按项目:`/adopt`;撤销 `/unadopt`。
|
|
152
152
|
3. **配置钩子** -- `PostToolUse`、`PreToolUse`、`SessionStart`、`Stop`、`UserPromptSubmit` 生命周期钩子
|
package/install.mjs
CHANGED
|
@@ -1522,6 +1522,13 @@ function hasMemHooksConfigured(settings) {
|
|
|
1522
1522
|
* interpreter. ${CLAUDE_PLUGIN_ROOT}-templated commands are ignored — those
|
|
1523
1523
|
* are plugin-owned hooks resolved by Claude Code at runtime, not by us.
|
|
1524
1524
|
*/
|
|
1525
|
+
const HOOK_PATH_EXTS = ['.mjs', '.js', '.cjs', '.sh'];
|
|
1526
|
+
|
|
1527
|
+
function looksLikeHookPath(p) {
|
|
1528
|
+
if (!p || !p.startsWith('/')) return false;
|
|
1529
|
+
return HOOK_PATH_EXTS.some(ext => p.endsWith(ext));
|
|
1530
|
+
}
|
|
1531
|
+
|
|
1525
1532
|
export function collectOrphanHookPaths(settings) {
|
|
1526
1533
|
if (!settings?.hooks) return [];
|
|
1527
1534
|
const out = [];
|
|
@@ -1532,12 +1539,19 @@ export function collectOrphanHookPaths(settings) {
|
|
|
1532
1539
|
for (const h of cfg.hooks || []) {
|
|
1533
1540
|
const cmd = h.command || '';
|
|
1534
1541
|
if (cmd.includes('${CLAUDE_PLUGIN_ROOT}')) continue;
|
|
1535
|
-
|
|
1536
|
-
|
|
1542
|
+
// v2.80: scan ALL quoted tokens (was: only the first), prefer ones
|
|
1543
|
+
// that look like a hook path. Fixes a footgun where a wrapper command
|
|
1544
|
+
// like `bash -c "some inline" "/real/path.sh"` would pick "some inline"
|
|
1545
|
+
// and flag a false orphan. If no quoted token looks like a path, fall
|
|
1546
|
+
// through to the unquoted scanner; if that also misses, skip the
|
|
1547
|
+
// entry — we'd rather under-report than false-flag.
|
|
1548
|
+
let path = null;
|
|
1549
|
+
for (const m of cmd.matchAll(/"([^"]+)"/g)) {
|
|
1550
|
+
if (looksLikeHookPath(m[1])) { path = m[1]; break; }
|
|
1551
|
+
}
|
|
1537
1552
|
if (!path) {
|
|
1538
|
-
// unquoted: split on whitespace, take the first arg that looks like an absolute path
|
|
1539
1553
|
const parts = cmd.split(/\s+/);
|
|
1540
|
-
path = parts.find(p =>
|
|
1554
|
+
path = parts.find(p => looksLikeHookPath(p)) || null;
|
|
1541
1555
|
}
|
|
1542
1556
|
if (!path) continue;
|
|
1543
1557
|
if (!existsSync(path) && !out.includes(path)) out.push(path);
|
package/lib/citation-tracker.mjs
CHANGED
|
@@ -283,8 +283,17 @@ export function hasMainThreadAssistantText(transcriptPath) {
|
|
|
283
283
|
if (!transcriptPath || !existsSync(transcriptPath)) return false;
|
|
284
284
|
let raw;
|
|
285
285
|
try { raw = readFileSync(transcriptPath, 'utf8'); } catch { return false; }
|
|
286
|
-
|
|
287
|
-
|
|
286
|
+
// Reverse-iterate so a turn that just produced text returns true on the
|
|
287
|
+
// FIRST line examined instead of walking the entire transcript. Common case
|
|
288
|
+
// (model wrote a paragraph → Stop fires) short-circuits in O(1) line parses;
|
|
289
|
+
// pathological case (no text anywhere) still walks all entries but that's
|
|
290
|
+
// the degenerate state we want false for anyway. v2.80 perf polish — the
|
|
291
|
+
// pre-v2.80 forward scan held the full transcript in memory and walked
|
|
292
|
+
// every line on the common case too.
|
|
293
|
+
const lines = raw.split('\n');
|
|
294
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
295
|
+
const line = lines[i];
|
|
296
|
+
if (!line || !line.trim()) continue;
|
|
288
297
|
let entry;
|
|
289
298
|
try { entry = JSON.parse(line); } catch { continue; }
|
|
290
299
|
if (entry.type !== 'assistant' || !entry.message) continue;
|