claude-mem-lite 2.90.0 → 2.90.1
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/cli.mjs +4 -1
- package/mem-cli.mjs +2 -2
- package/package.json +1 -1
- package/registry-importer.mjs +5 -2
- package/scripts/pre-skill-bridge.js +9 -3
- package/scripts/user-prompt-search.js +11 -3
- package/server.mjs +10 -6
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"plugins": [
|
|
11
11
|
{
|
|
12
12
|
"name": "claude-mem-lite",
|
|
13
|
-
"version": "2.90.
|
|
13
|
+
"version": "2.90.1",
|
|
14
14
|
"source": "./",
|
|
15
15
|
"description": "Persistent long-term memory for Claude Code via MCP — captures coding decisions, bugfixes, and context across sessions. Hybrid FTS5 + TF-IDF 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)."
|
|
16
16
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-mem-lite",
|
|
3
|
-
"version": "2.90.
|
|
3
|
+
"version": "2.90.1",
|
|
4
4
|
"description": "Persistent long-term memory for Claude Code via MCP — captures coding decisions, bugfixes, and context across sessions. Hybrid FTS5 + TF-IDF 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/cli.mjs
CHANGED
|
@@ -32,7 +32,10 @@ if (cmd === '--version' || cmd === '-v') {
|
|
|
32
32
|
// No command: show CLI help if installed, install help if not
|
|
33
33
|
const { existsSync } = await import('fs');
|
|
34
34
|
const { join } = await import('path');
|
|
35
|
-
|
|
35
|
+
// D#29: honor CLAUDE_MEM_DIR so the install-vs-CLI help routing is correct on
|
|
36
|
+
// relocated installs (matches schema.mjs DB_DIR; HOME fallback when env unset).
|
|
37
|
+
const dataDir = process.env.CLAUDE_MEM_DIR || join(process.env.HOME || '', '.claude-mem-lite');
|
|
38
|
+
const dbPath = join(dataDir, 'claude-mem-lite.db');
|
|
36
39
|
if (existsSync(dbPath)) {
|
|
37
40
|
const { run } = await import('./mem-cli.mjs');
|
|
38
41
|
await run(['help']);
|
package/mem-cli.mjs
CHANGED
|
@@ -26,7 +26,7 @@ import { cmdAdopt, cmdUnadopt } from './adopt-cli.mjs';
|
|
|
26
26
|
import { parseIntFlag, isNumericToken } from './lib/cli-flags.mjs';
|
|
27
27
|
import { auditMemdir, memdirPath } from './memdir.mjs';
|
|
28
28
|
import { probeOtherSources as probeIdSources, bucketIdTokens } from './lib/id-routing.mjs';
|
|
29
|
-
import { basename, join } from 'path';
|
|
29
|
+
import { basename, join, sep } from 'path';
|
|
30
30
|
import { readFileSync, existsSync, readdirSync } from 'fs';
|
|
31
31
|
|
|
32
32
|
// v2.41: shared CLI helpers extracted to cli/common.mjs. Keep this file as the
|
|
@@ -2180,7 +2180,7 @@ function cmdRegistry(_memDb, args) {
|
|
|
2180
2180
|
for (const r of results) {
|
|
2181
2181
|
const badge = r.quality_tier === 'installed' ? '[✓]' : r.quality_tier === 'verified' ? '[★]' : '[○]';
|
|
2182
2182
|
const categoryLabel = r.category ? ` [${r.category}]` : '';
|
|
2183
|
-
const isManaged = r.local_path && r.local_path.includes('
|
|
2183
|
+
const isManaged = r.local_path && r.local_path.includes(join(DB_DIR, 'managed') + sep);
|
|
2184
2184
|
const portablePath = isManaged && r.local_path.startsWith(home) ? '~' + r.local_path.slice(home.length) : (r.local_path || '');
|
|
2185
2185
|
let howToUse;
|
|
2186
2186
|
if (isManaged) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-mem-lite",
|
|
3
|
-
"version": "2.90.
|
|
3
|
+
"version": "2.90.1",
|
|
4
4
|
"description": "Persistent long-term memory for Claude Code via MCP — captures coding decisions, bugfixes, and context across sessions. Hybrid FTS5 + TF-IDF 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",
|
package/registry-importer.mjs
CHANGED
|
@@ -8,9 +8,12 @@ import { debugLog, isPathConfined } from './utils.mjs';
|
|
|
8
8
|
import { createHash } from 'crypto';
|
|
9
9
|
import { mkdirSync, writeFileSync } from 'fs';
|
|
10
10
|
import { join } from 'path';
|
|
11
|
-
import {
|
|
11
|
+
import { DB_DIR } from './schema.mjs';
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
// DATA artifact — managed resources live under the env-aware data dir (DB_DIR),
|
|
14
|
+
// NOT a hardcoded homedir, so GitHub imports land where install.mjs + registry-scanner
|
|
15
|
+
// read them under CLAUDE_MEM_DIR relocation (D#29). Equals homedir when the env is unset.
|
|
16
|
+
const MANAGED_DIR = join(DB_DIR, 'managed');
|
|
14
17
|
|
|
15
18
|
// ─── Tree Discovery ─────────────────────────────────────────────────────────
|
|
16
19
|
|
|
@@ -11,9 +11,15 @@ import { recordHookError } from '../lib/hook-telemetry.mjs';
|
|
|
11
11
|
// CLAUDE_MEM_DIR mirrors pre-tool-recall.js — one env var sandboxes everything.
|
|
12
12
|
const DATA_DIR = process.env.CLAUDE_MEM_DIR || join(homedir(), '.claude-mem-lite');
|
|
13
13
|
const RUNTIME_DIR = process.env.CLAUDE_MEM_RUNTIME_DIR || join(DATA_DIR, 'runtime');
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
// D#29: all data artifacts follow DATA_DIR (CLAUDE_MEM_DIR-aware), not a hardcoded
|
|
15
|
+
// homedir — previously REGISTRY_DB_PATH/MANAGED_BASE/MARKER pinned homedir while line 12
|
|
16
|
+
// honored the env, so relocated installs opened the wrong DB and the marker never matched
|
|
17
|
+
// the relocated local_path. MANAGED_MARKER is only a coarse LIKE prefilter; the exact
|
|
18
|
+
// MANAGED_BASE prefix check below is the real confinement gate (so LIKE-wildcard chars in
|
|
19
|
+
// a relocated path can at worst over-admit to that gate, never bypass it).
|
|
20
|
+
const REGISTRY_DB_PATH = join(DATA_DIR, 'resource-registry.db');
|
|
21
|
+
const MANAGED_BASE = DATA_DIR;
|
|
22
|
+
const MANAGED_MARKER = join(DATA_DIR, 'managed') + sep;
|
|
17
23
|
|
|
18
24
|
try {
|
|
19
25
|
// Skip if recursive hook
|
|
@@ -8,7 +8,7 @@ import { sanitizeFtsQuery, relaxFtsQueryToOr, truncate, typeIcon, inferProject,
|
|
|
8
8
|
import { citeFactorClause } from '../scoring-sql.mjs';
|
|
9
9
|
import { cjkPrecisionOk } from '../nlp.mjs';
|
|
10
10
|
import { writeFileSync, readFileSync, existsSync, renameSync } from 'fs';
|
|
11
|
-
import { join } from 'path';
|
|
11
|
+
import { join, sep } from 'path';
|
|
12
12
|
import Database from 'better-sqlite3';
|
|
13
13
|
import { shouldSkip, computeEffectiveLen, detectIntent, shouldSkipByDedup, extractFiles, extractErrorSignature, DEDUP_STALE_MS, matchRegistrySkillName, detectMemOverride } from './prompt-search-utils.mjs';
|
|
14
14
|
|
|
@@ -439,10 +439,18 @@ function loadManagedSkillNames() {
|
|
|
439
439
|
const rdb = new Database(REGISTRY_DB_PATH, { readonly: true });
|
|
440
440
|
rdb.pragma('busy_timeout = 500');
|
|
441
441
|
try {
|
|
442
|
+
// D#29: derive the managed marker from the env-aware data dir, not a hardcoded
|
|
443
|
+
// homedir literal — under CLAUDE_MEM_DIR relocation the stored local_path lives at
|
|
444
|
+
// DB_DIR/managed, so the old literal matched nothing and dropped every managed skill
|
|
445
|
+
// from injection. Coarse LIKE prefilter; resource names are re-validated downstream.
|
|
446
|
+
// D#29: derive the managed marker from the env-aware data dir, not a hardcoded
|
|
447
|
+
// homedir literal — under CLAUDE_MEM_DIR relocation the stored local_path lives at
|
|
448
|
+
// DB_DIR/managed, so the old literal matched nothing and dropped every managed skill
|
|
449
|
+
// from injection. Coarse LIKE prefilter; resource names are re-validated downstream.
|
|
442
450
|
const rows = rdb.prepare(`
|
|
443
451
|
SELECT name FROM resources
|
|
444
|
-
WHERE status = 'active' AND local_path LIKE
|
|
445
|
-
`).all();
|
|
452
|
+
WHERE status = 'active' AND local_path LIKE ?
|
|
453
|
+
`).all(`%${join(DB_DIR, 'managed') + sep}%`);
|
|
446
454
|
return new Set(rows.map(r => r.name.toLowerCase()));
|
|
447
455
|
} finally { rdb.close(); }
|
|
448
456
|
} catch { return new Set(); }
|
package/server.mjs
CHANGED
|
@@ -8,7 +8,7 @@ import { ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
|
8
8
|
import { truncate, typeIcon, sanitizeFtsQuery, relaxFtsQueryToOr, inferProject, scrubSecrets, cjkBigrams, fmtDate, debugLog, debugCatch, SESS_BM25, DEFAULT_DECAY_HALF_LIFE_MS, isPathConfined, notLowSignalTitleClause } from './utils.mjs';
|
|
9
9
|
import { extractCjkLikePatterns, cjkPrecisionOk } from './nlp.mjs';
|
|
10
10
|
import { resolveProject as _resolveProjectShared } from './project-utils.mjs';
|
|
11
|
-
import { ensureDb, DB_PATH, REGISTRY_DB_PATH } from './schema.mjs';
|
|
11
|
+
import { ensureDb, DB_PATH, DB_DIR, REGISTRY_DB_PATH } from './schema.mjs';
|
|
12
12
|
import { reRankWithContext, markSuperseded, autoBoostIfNeeded, runIdleCleanup, buildServerInstructions } from './server-internals.mjs';
|
|
13
13
|
import { searchObservationsHybrid, findFtsAnchor } from './search-engine.mjs';
|
|
14
14
|
import { selectCompressionCandidates, groupByProjectWeek, compressGroup } from './lib/compress-core.mjs';
|
|
@@ -30,7 +30,7 @@ function descriptionOf(name) {
|
|
|
30
30
|
return d;
|
|
31
31
|
}
|
|
32
32
|
import { optimizePreview, optimizeRun } from './hook-optimize.mjs';
|
|
33
|
-
import { basename, join } from 'path';
|
|
33
|
+
import { basename, join, sep } from 'path';
|
|
34
34
|
import { homedir } from 'os';
|
|
35
35
|
import { ensureRegistryDb, upsertResource } from './registry.mjs';
|
|
36
36
|
import { searchResources } from './registry-retriever.mjs';
|
|
@@ -1506,7 +1506,7 @@ server.registerTool(
|
|
|
1506
1506
|
const lines = results.map(r => {
|
|
1507
1507
|
const qualityBadge = r.quality_tier === 'installed' ? '[✓]' : r.quality_tier === 'verified' ? '[★]' : '[○]';
|
|
1508
1508
|
const categoryLabel = r.category ? ` [${r.category}]` : '';
|
|
1509
|
-
const isManaged = r.local_path && r.local_path.includes('
|
|
1509
|
+
const isManaged = r.local_path && r.local_path.includes(join(DB_DIR, 'managed') + sep);
|
|
1510
1510
|
const portablePath = isManaged ? toPortable(r.local_path) : '';
|
|
1511
1511
|
let howToUse;
|
|
1512
1512
|
if (isManaged) {
|
|
@@ -1651,7 +1651,9 @@ server.registerTool(
|
|
|
1651
1651
|
if (!row.local_path) {
|
|
1652
1652
|
return { content: [{ type: 'text', text: `No local_path for ${args.name}` }], isError: true };
|
|
1653
1653
|
}
|
|
1654
|
-
|
|
1654
|
+
// Confine to the env-aware data dir (managed/ relocates with CLAUDE_MEM_DIR, D#29);
|
|
1655
|
+
// === homedir when the env is unset, so non-relocated confinement is unchanged.
|
|
1656
|
+
const enrichBase = DB_DIR;
|
|
1655
1657
|
if (!isPathConfined(row.local_path, enrichBase)) {
|
|
1656
1658
|
return { content: [{ type: 'text', text: `Access denied: path outside managed directory` }], isError: true };
|
|
1657
1659
|
}
|
|
@@ -1719,8 +1721,10 @@ server.registerTool(
|
|
|
1719
1721
|
}
|
|
1720
1722
|
}
|
|
1721
1723
|
|
|
1722
|
-
// 4. Path confinement check — prevent reading arbitrary files via crafted local_path
|
|
1723
|
-
|
|
1724
|
+
// 4. Path confinement check — prevent reading arbitrary files via crafted local_path.
|
|
1725
|
+
// Base is the env-aware data dir (D#29): managed/ relocates with CLAUDE_MEM_DIR and
|
|
1726
|
+
// equals homedir when unset, so this does not weaken the non-relocated confinement.
|
|
1727
|
+
const managedBase = DB_DIR;
|
|
1724
1728
|
if (skillPath && !isPathConfined(skillPath, managedBase)) {
|
|
1725
1729
|
return { content: [{ type: 'text', text: `Access denied: path "${skillPath}" is outside managed directory` }], isError: true };
|
|
1726
1730
|
}
|