claude-mem-lite 2.32.4 → 2.32.6

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.
@@ -10,7 +10,7 @@
10
10
  "plugins": [
11
11
  {
12
12
  "name": "claude-mem-lite",
13
- "version": "2.32.4",
13
+ "version": "2.32.6",
14
14
  "source": "./",
15
15
  "description": "Lightweight persistent memory system for Claude Code — FTS5 search, episode batching, error-triggered recall"
16
16
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-mem-lite",
3
- "version": "2.32.4",
3
+ "version": "2.32.6",
4
4
  "description": "Lightweight persistent memory system for Claude Code — FTS5 search, episode batching, error-triggered recall",
5
5
  "author": {
6
6
  "name": "sdsrss"
package/README.md CHANGED
@@ -455,6 +455,12 @@ npx claude-mem-lite doctor # Diagnose issues
455
455
 
456
456
  Notes:
457
457
  - Plugin mode only reports available updates; it does not self-update plugin files.
458
+ To upgrade an installed plugin to the latest published version, run **inside Claude Code**:
459
+ ```
460
+ /plugin marketplace update sdsrss
461
+ /plugin install claude-mem-lite@sdsrss
462
+ ```
463
+ (The first command refreshes the local marketplace clone; the second reinstalls from it. Without the first command, `/plugin install` reuses the stale local clone and you stay on whichever version you originally pulled.)
458
464
  - Direct install / npx mode keeps auto-update enabled and uses staged replacement with rollback on install failure.
459
465
  - If you disabled the plugin but still have old mem hooks in `~/.claude/settings.json`, run `node install.mjs cleanup-hooks`.
460
466
 
package/hook-handoff.mjs CHANGED
@@ -299,7 +299,16 @@ export function renderHandoffInjection(db, project, currentCcSessionId = null) {
299
299
  ageSec < 86400 ? `${Math.round(ageSec / 3600)}h` :
300
300
  `${Math.round(ageSec / 86400)}d`;
301
301
 
302
- const lines = [`<session-handoff source="${handoff.type}" age="${ageStr}">`];
302
+ // Framing header: `UserPromptSubmit` hook writes this block to stdout, which
303
+ // Claude Code surfaces alongside the real user prompt. Without an explicit
304
+ // "this is not a new message" marker, models can misread `## Working On <text>`
305
+ // as a fresh user utterance and either answer the old task or end the turn.
306
+ // The `[mem]` prefix mirrors the SessionStart dashboard convention; `origin`
307
+ // on the tag gives programmatic callers a stable anchor.
308
+ const lines = [
309
+ `[mem] Resumed context from previous session (${handoff.type}, age ${ageStr}) — system-injected, NOT a new user message:`,
310
+ `<session-handoff source="${handoff.type}" age="${ageStr}" origin="hook-injected">`,
311
+ ];
303
312
 
304
313
  if (handoff.working_on) {
305
314
  lines.push('## Working On', handoff.working_on, '');
package/hook-update.mjs CHANGED
@@ -8,6 +8,7 @@ import { join, dirname } from 'node:path';
8
8
  import { tmpdir, homedir } from 'node:os';
9
9
  import { DB_DIR } from './schema.mjs';
10
10
  import { debugCatch, debugLog } from './utils.mjs';
11
+ import { SOURCE_FILES } from './source-files.mjs';
11
12
 
12
13
  // ── Configuration ──────────────────────────────────────────
13
14
  const GITHUB_REPO = 'sdsrss/claude-mem-lite';
@@ -191,19 +192,10 @@ export function getCurrentVersion() {
191
192
  } catch { return '0.0.0'; }
192
193
  }
193
194
 
194
- // ── Source files to copy (must match install.mjs SOURCE_FILES) ──
195
- const SOURCE_FILES = [
196
- 'cli.mjs', 'server.mjs', 'server-internals.mjs', 'tool-schemas.mjs',
197
- 'hook.mjs', 'hook-shared.mjs', 'hook-llm.mjs', 'hook-memory.mjs', 'skip-tools.mjs',
198
- 'hook-semaphore.mjs', 'hook-episode.mjs', 'hook-context.mjs', 'hook-handoff.mjs', 'hook-update.mjs',
199
- 'hook-optimize.mjs', 'plugin-cache-guard.mjs',
200
- 'haiku-client.mjs', 'utils.mjs', 'schema.mjs', 'package.json', 'package-lock.json', 'skill.md',
201
- 'registry.mjs', 'registry-scanner.mjs', 'registry-indexer.mjs',
202
- 'registry-retriever.mjs', 'resource-discovery.mjs',
203
- 'install.mjs', 'install-metadata.mjs', 'mem-cli.mjs', 'tier.mjs', 'tfidf.mjs',
204
- 'nlp.mjs', 'synonyms.mjs', 'scoring-sql.mjs', 'stop-words.mjs', 'project-utils.mjs',
205
- 'secret-scrub.mjs', 'format-utils.mjs', 'hash-utils.mjs', 'bash-utils.mjs',
206
- ];
195
+ // Source files imported from shared ./source-files.mjs so install.mjs and
196
+ // hook-update.mjs can never drift (see tests/source-files-sync.test.mjs).
197
+ // SWITCHABLE_PATHS = everything in SOURCE_FILES plus the recursive dirs that
198
+ // install.mjs copies as whole subtrees (scripts, registry, node_modules).
207
199
  const SWITCHABLE_PATHS = [...SOURCE_FILES, 'scripts', 'registry', 'node_modules'];
208
200
 
209
201
  // ── Download & Install ─────────────────────────────────────
package/install.mjs CHANGED
@@ -2,7 +2,7 @@
2
2
  // claude-mem-lite Installer — Smart install/uninstall/status/doctor
3
3
 
4
4
  import { execSync, execFileSync } from 'child_process';
5
- import { readFileSync, writeFileSync, existsSync, rmSync, mkdirSync, copyFileSync, cpSync, renameSync, symlinkSync, unlinkSync, readdirSync, statSync } from 'fs';
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 } from 'os';
8
8
  import { fileURLToPath } from 'url';
@@ -27,6 +27,7 @@ const NPM_INSTALL_CMD = 'npm install --omit=dev --no-audit --no-fund';
27
27
 
28
28
  import { RESOURCE_METADATA } from './install-metadata.mjs';
29
29
  import { scanPluginCacheHookPollution } from './plugin-cache-guard.mjs';
30
+ import { SOURCE_FILES } from './source-files.mjs';
30
31
 
31
32
  /**
32
33
  * Derive invocation_name from resource name when metadata doesn't provide one.
@@ -184,6 +185,18 @@ function ok(msg) { console.log(` ✓ ${msg}`); }
184
185
  function warn(msg) { console.log(` ⚠ ${msg}`); }
185
186
  function fail(msg) { console.log(` ✗ ${msg}`); }
186
187
 
188
+ // Dev installs symlink server.mjs → the project's source file. Used to suppress
189
+ // misleading "first run" messages since hook-update.mjs skips state-writes in
190
+ // this mode (see hook-update.mjs isDevMode).
191
+ function isDevInstall() {
192
+ try {
193
+ const serverPath = join(INSTALL_DIR, 'server.mjs');
194
+ return existsSync(serverPath) && lstatSync(serverPath).isSymbolicLink();
195
+ } catch {
196
+ return false;
197
+ }
198
+ }
199
+
187
200
  // ─── Install ────────────────────────────────────────────────────────────────
188
201
 
189
202
  async function install() {
@@ -202,34 +215,6 @@ async function install() {
202
215
 
203
216
  if (!existsSync(DATA_DIR)) mkdirSync(DATA_DIR, { recursive: true });
204
217
 
205
- const SOURCE_FILES = [
206
- 'cli.mjs', 'server.mjs', 'server-internals.mjs', 'tool-schemas.mjs',
207
- 'hook.mjs', 'hook-shared.mjs', 'hook-llm.mjs', 'hook-memory.mjs', 'skip-tools.mjs',
208
- 'hook-semaphore.mjs', 'hook-episode.mjs', 'hook-context.mjs', 'hook-handoff.mjs', 'hook-update.mjs', 'hook-optimize.mjs',
209
- 'plugin-cache-guard.mjs',
210
- 'haiku-client.mjs', 'utils.mjs', 'schema.mjs', 'package.json', 'package-lock.json', 'skill.md',
211
- 'registry.mjs', 'registry-scanner.mjs', 'registry-indexer.mjs',
212
- 'registry-retriever.mjs', 'resource-discovery.mjs',
213
- 'install-metadata.mjs', 'mem-cli.mjs', 'tier.mjs', 'tfidf.mjs',
214
- 'nlp.mjs', 'synonyms.mjs', 'scoring-sql.mjs', 'stop-words.mjs', 'project-utils.mjs',
215
- 'secret-scrub.mjs', 'format-utils.mjs', 'hash-utils.mjs', 'bash-utils.mjs',
216
- // v2.31 T9: hook-llm now statically imports lib/activity.mjs (events routing).
217
- // SOURCE_FILES entries with a subdir prefix require install.mjs to mkdir the
218
- // parent before symlink/copy — handled in the IS_DEV and else-branch loops.
219
- 'lib/activity.mjs',
220
- // v2.31 T10: startup dashboard aggregator + handoff task/git anchoring.
221
- // task-reader + plan-reader + git-state are read by lib/startup-dashboard.mjs
222
- // on SessionStart (hook.mjs) and by hook-handoff.mjs on /exit + /clear.
223
- 'lib/task-reader.mjs',
224
- 'lib/plan-reader.mjs',
225
- 'lib/git-state.mjs',
226
- 'lib/startup-dashboard.mjs',
227
- // v2.32 (invited-memory): memdir primitives + adopt/unadopt CLI.
228
- 'memdir.mjs',
229
- 'adopt-content.mjs',
230
- 'adopt-cli.mjs',
231
- ];
232
-
233
218
  if (IS_DEV) {
234
219
  log('Dev mode — creating symlinks in ~/.claude-mem-lite/...');
235
220
  // Symlink individual source files
@@ -1194,6 +1179,10 @@ async function doctor() {
1194
1179
  if (state.rateLimited) parts.push('rate-limited');
1195
1180
  if (state.lastError) parts.push(`last error: ${state.lastError}`);
1196
1181
  ok(`Update state: ${parts.join(', ') || 'empty'}`);
1182
+ } else if (isDevInstall()) {
1183
+ // Dev installs symlink server.mjs → project source; hook-update.mjs
1184
+ // short-circuits before writing state (see hook-update.mjs isDevMode).
1185
+ ok('Update state: skipped (dev mode — symlinked install)');
1197
1186
  } else {
1198
1187
  warn('Update state: no state file (first run?)');
1199
1188
  }
@@ -1387,7 +1376,10 @@ async function manualUpdate() {
1387
1376
  if (result?.updated) {
1388
1377
  ok(`Updated: v${result.from} → v${result.to}`);
1389
1378
  } else if (result?.updateAvailable && result?.installDeferred) {
1390
- warn(`v${result.to} available — plugin mode only checks for updates, reinstall/update the plugin to apply it`);
1379
+ warn(`v${result.to} available — plugin mode only checks for updates.`);
1380
+ log(' To upgrade, inside Claude Code run:');
1381
+ log(' /plugin marketplace update sdsrss');
1382
+ log(' /plugin install claude-mem-lite@sdsrss');
1391
1383
  } else if (result?.updateAvailable) {
1392
1384
  warn(`v${result.to} available but install failed — try: node install.mjs install`);
1393
1385
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-mem-lite",
3
- "version": "2.32.4",
3
+ "version": "2.32.6",
4
4
  "description": "Lightweight persistent memory system for Claude Code",
5
5
  "type": "module",
6
6
  "engines": {
@@ -55,6 +55,7 @@
55
55
  "registry-importer.mjs",
56
56
  "registry-enricher.mjs",
57
57
  "resource-discovery.mjs",
58
+ "source-files.mjs",
58
59
  "install.mjs",
59
60
  "install-metadata.mjs",
60
61
  "skip-tools.mjs",
@@ -0,0 +1,41 @@
1
+ // Shared runtime source-file manifest — imported by install.mjs and hook-update.mjs
2
+ // so the two code paths never drift. Adding a new .mjs that any entry point
3
+ // (cli.mjs / hook.mjs / server.mjs / mem-cli.mjs / install.mjs) imports requires
4
+ // adding the path here AND to package.json's files array;
5
+ // tests/source-files-sync.test.mjs enforces both.
6
+
7
+ export const SOURCE_FILES = [
8
+ // Entry points and top-level modules
9
+ 'cli.mjs', 'server.mjs', 'server-internals.mjs', 'tool-schemas.mjs',
10
+ 'hook.mjs', 'hook-shared.mjs', 'hook-llm.mjs', 'hook-memory.mjs', 'skip-tools.mjs',
11
+ 'hook-semaphore.mjs', 'hook-episode.mjs', 'hook-context.mjs', 'hook-handoff.mjs',
12
+ 'hook-update.mjs', 'hook-optimize.mjs',
13
+ 'plugin-cache-guard.mjs',
14
+ 'haiku-client.mjs', 'utils.mjs', 'schema.mjs',
15
+ 'package.json', 'package-lock.json', 'skill.md',
16
+ 'registry.mjs', 'registry-scanner.mjs', 'registry-indexer.mjs',
17
+ 'registry-retriever.mjs', 'resource-discovery.mjs',
18
+ // registry-enricher/-github/-importer are dynamically imported by server.mjs
19
+ // (mem_registry tool) and mem-cli.mjs (registry CLI subcommands). Missing
20
+ // them from SOURCE_FILES silently broke those code paths prior to this fix.
21
+ 'registry-enricher.mjs', 'registry-github.mjs', 'registry-importer.mjs',
22
+ // Shared SOURCE_FILES manifest — self-reference so `~/.claude-mem-lite/` can
23
+ // re-run install.mjs (which imports this module) after an auto-update.
24
+ 'source-files.mjs',
25
+ 'install.mjs', 'install-metadata.mjs', 'mem-cli.mjs',
26
+ 'tier.mjs', 'tfidf.mjs',
27
+ 'nlp.mjs', 'synonyms.mjs', 'scoring-sql.mjs', 'stop-words.mjs', 'project-utils.mjs',
28
+ 'secret-scrub.mjs', 'format-utils.mjs', 'hash-utils.mjs', 'bash-utils.mjs',
29
+ // lib/ — statically imported by hook-llm.mjs (activity) + hook-handoff.mjs (git-state, task-reader);
30
+ // dynamically imported by hook.mjs (startup-dashboard) + mem-cli.mjs (doctor-benchmark, plan-reader).
31
+ 'lib/activity.mjs',
32
+ 'lib/task-reader.mjs',
33
+ 'lib/plan-reader.mjs',
34
+ 'lib/git-state.mjs',
35
+ 'lib/startup-dashboard.mjs',
36
+ 'lib/doctor-benchmark.mjs',
37
+ // v2.32 invited-memory: memdir primitives + adopt/unadopt CLI
38
+ 'memdir.mjs',
39
+ 'adopt-content.mjs',
40
+ 'adopt-cli.mjs',
41
+ ];