claude-mem-lite 6.23.2 → 6.23.3

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.
@@ -9,7 +9,7 @@
9
9
  "plugins": [
10
10
  {
11
11
  "name": "claude-mem-lite",
12
- "version": "6.23.2",
12
+ "version": "6.23.3",
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.23.2",
3
+ "version": "6.23.3",
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
@@ -189,7 +189,7 @@ cd claude-mem-lite
189
189
  node install.mjs install
190
190
  ```
191
191
 
192
- Source files stay in the cloned repo. Update via `git pull && node install.mjs install`.
192
+ `install` copies the source files to `~/.claude-mem-lite/`, as the npx method does. Update with `node install.mjs update`, which installs the latest signed release. `git pull && node install.mjs install` installs the checked-out branch instead: it can be ahead of the latest release, and no signature is checked.
193
193
 
194
194
  ### What happens during installation
195
195
 
@@ -1091,7 +1091,7 @@ claude-mem-lite.
1091
1091
  | `CLAUDE_MEM_DIR` | Custom data directory. All databases, runtime files, and managed resources are stored here. | `~/.claude-mem-lite/` |
1092
1092
  | `CLAUDE_MEM_MODEL` | LLM model for background calls (episode extraction, session summaries). Accepts `haiku` or `sonnet`. | `haiku` |
1093
1093
  | `ANTHROPIC_API_KEY` | Anthropic API key. When set, all background LLM calls go directly to the Anthropic Messages API (with prompt caching) - or to the `ANTHROPIC_BASE_URL` gateway when that is set. Highest priority. | _(unset → CLI)_ |
1094
- | `ANTHROPIC_BASE_URL` | Base URL for the direct Messages API when an Anthropic-compatible gateway serves the models (Azure AI Foundry, LiteLLM, Bedrock/Vertex proxies). No `/v1` suffix — the endpoint path is appended. The `claude -p` fallback reads the same variable, so one value covers both transports. Plain `http://` is accepted only for a loopback host; anything else would send the API key unencrypted. A value that is set but unusable skips the direct API leg, so background calls fall back to the `claude -p` CLI, and doctor warns. | `https://api.anthropic.com` |
1094
+ | `ANTHROPIC_BASE_URL` | Base URL for the direct Messages API when an Anthropic-compatible gateway serves the models (Azure AI Foundry, LiteLLM, Bedrock/Vertex proxies). No `/v1` suffix — the endpoint path is appended. The `claude -p` fallback reads the same variable, so one value covers both transports. Plain `http://` is accepted only for a loopback host; anything else would send the API key unencrypted. That request always goes straight to the loopback host, even when `NODE_USE_ENV_PROXY=1` sends other requests through `HTTP_PROXY`. A value that is set but unusable skips the direct API leg, so background calls fall back to the `claude -p` CLI, and doctor warns. | `https://api.anthropic.com` |
1095
1095
  | `ANTHROPIC_DEFAULT_HAIKU_MODEL` | Model ID or gateway deployment name for the `haiku` tier, honored on the direct API **only when `ANTHROPIC_BASE_URL` is set**. Without a base URL it stays CLI-only, so the Bedrock/Vertex form of this alias is never sent to `api.anthropic.com`. Use it when the gateway routes on deployment names rather than Anthropic model IDs (Azure Foundry deployments). The `claude -p` fallback resolves its `--model haiku` alias through it too. | built-in `claude-haiku-4-5-…` |
1096
1096
  | `ANTHROPIC_DEFAULT_SONNET_MODEL` | Same as above for the `sonnet` tier. | built-in `claude-sonnet-4-5-…` |
1097
1097
  | `OPENROUTER_API_KEY` | OpenRouter API key (OpenAI-compatible). Used for background LLM calls when `ANTHROPIC_API_KEY` is **not** set. If neither key is set, calls fall back to the `claude -p` CLI. | _(unset)_ |
package/README.zh-CN.md CHANGED
@@ -147,7 +147,7 @@ cd claude-mem-lite
147
147
  node install.mjs install
148
148
  ```
149
149
 
150
- 源文件保留在克隆的仓库中。通过 `git pull && node install.mjs install` 更新。
150
+ `install` 会把源文件复制到 `~/.claude-mem-lite/`,与 npx 方式相同。用 `node install.mjs update` 更新,它安装最新的已签名发布。`git pull && node install.mjs install` 安装的则是当前检出的分支:可能领先于最新发布,也不校验签名。
151
151
 
152
152
  ### 安装过程
153
153
 
@@ -833,7 +833,7 @@ npm run benchmark:gate # CI 门控:指标回退超过 5% 容差时失败
833
833
  | `CLAUDE_MEM_DIR` | 自定义数据目录。所有数据库与运行时文件均存储在此。 | `~/.claude-mem-lite/` |
834
834
  | `CLAUDE_MEM_MODEL` | 后台 LLM 调用模型(Episode 提取、会话总结、调度)。可选 `haiku` 或 `sonnet`。 | `haiku` |
835
835
  | `ANTHROPIC_API_KEY` | Anthropic API key。设置后所有后台 LLM 调用直连 Anthropic Messages API(带 prompt caching);设了 `ANTHROPIC_BASE_URL` 时改发往那个网关。优先级最高。 | _(未设 → CLI)_ |
836
- | `ANTHROPIC_BASE_URL` | 由兼容 Anthropic 的网关(Azure AI Foundry、LiteLLM、Bedrock/Vertex 代理)提供模型时,直连 Messages API 使用的基础 URL。不要带 `/v1` 后缀,端点路径会自动拼上。`claude -p` 兜底读取同一个变量,所以一个值同时作用于两条路径。明文 `http://` 只接受回环主机,否则 API key 会以明文发送。设了但不可用的值会跳过直连这一路,后台调用改走 `claude -p`,doctor 会提示。 | `https://api.anthropic.com` |
836
+ | `ANTHROPIC_BASE_URL` | 由兼容 Anthropic 的网关(Azure AI Foundry、LiteLLM、Bedrock/Vertex 代理)提供模型时,直连 Messages API 使用的基础 URL。不要带 `/v1` 后缀,端点路径会自动拼上。`claude -p` 兜底读取同一个变量,所以一个值同时作用于两条路径。明文 `http://` 只接受回环主机,否则 API key 会以明文发送。这个请求总是直连回环主机,即使 `NODE_USE_ENV_PROXY=1` 让其他请求走 `HTTP_PROXY`。设了但不可用的值会跳过直连这一路,后台调用改走 `claude -p`,doctor 会提示。 | `https://api.anthropic.com` |
837
837
  | `ANTHROPIC_DEFAULT_HAIKU_MODEL` | `haiku` 档的模型 ID 或网关部署名,**仅在设了 `ANTHROPIC_BASE_URL` 时**用于直连 API。没有基础 URL 时只给 CLI 用,所以这个别名的 Bedrock/Vertex 写法不会被发往 `api.anthropic.com`。网关按部署名而不是 Anthropic 模型 ID 路由时(Azure Foundry 部署)使用。`claude -p` 兜底的 `--model haiku` 别名也经由它解析。 | 内置 `claude-haiku-4-5-…` |
838
838
  | `ANTHROPIC_DEFAULT_SONNET_MODEL` | 同上,用于 `sonnet` 档。 | 内置 `claude-sonnet-4-5-…` |
839
839
  | `OPENROUTER_API_KEY` | OpenRouter API key(OpenAI 兼容)。当**未设** `ANTHROPIC_API_KEY` 时用于后台 LLM 调用;两者都未设则回退到 `claude -p` CLI。 | _(未设)_ |
package/haiku-client.mjs CHANGED
@@ -20,7 +20,7 @@ import { randomUUID } from 'crypto';
20
20
  import { debugLog, debugCatch, parseJsonFromLLM } from './utils.mjs';
21
21
  import { DB_DIR } from './schema.mjs';
22
22
  import { resolveRuntimeDir } from './lib/resolve-data-dir.mjs';
23
- import { httpConnectProxyFor, postViaConnectProxy } from './lib/proxy-fetch.mjs';
23
+ import { httpConnectProxyFor, postViaConnectProxy, postDirectHttp } from './lib/proxy-fetch.mjs';
24
24
  import { resolveAnthropicBaseUrl } from './lib/anthropic-base-url.mjs';
25
25
 
26
26
  /**
@@ -553,8 +553,20 @@ async function callModelAPI(prompt, model, { timeout, maxTokens, temperature = D
553
553
  'x-api-key': apiKey,
554
554
  'anthropic-version': '2023-06-01',
555
555
  };
556
+ // Plain http is loopback-only (resolveAnthropicBaseUrl), and loopback must stay on this
557
+ // machine: native fetch would hand it, x-api-key in cleartext, to HTTP_PROXY under
558
+ // NODE_USE_ENV_PROXY=1. (D#250) Parsed, not a prefix test: the resolver accepts the scheme
559
+ // in any case (`HTTP://127.0.0.1`) and returns the raw text.
560
+ const plainHttp = new URL(apiUrl).protocol === 'http:';
556
561
  const send = (payload) => {
557
562
  const json = JSON.stringify(payload);
563
+ if (plainHttp) {
564
+ return postDirectHttp(apiUrl, {
565
+ headers: apiHeaders,
566
+ body: json,
567
+ timeout: Math.max(1, deadline - Date.now()),
568
+ });
569
+ }
558
570
  const apiProxy = httpConnectProxyFor(apiUrl);
559
571
  return apiProxy
560
572
  ? postViaConnectProxy(apiProxy, apiUrl, {
package/hook-update.mjs CHANGED
@@ -1,6 +1,7 @@
1
- // claude-mem-lite: Auto-update via GitHub Releases
2
- // Checks for new versions on SessionStart, downloads and installs automatically.
3
- // Skips in dev mode (symlinked installs). Silent on network failure.
1
+ // claude-mem-lite: update check and installer via GitHub Releases
2
+ // The SessionStart check (hook.mjs, allowInstall:false) only records and announces a newer
3
+ // release; `self-update` and `repair` install one, signature-verified. Skips a dev install
4
+ // (a git checkout or symlinks) and under CLAUDE_MEM_SKIP_UPDATE. Silent on network failure.
4
5
 
5
6
  import { isOurMcpRegistration } from './lib/mcp-ownership.mjs';
6
7
  import { execSync, execFileSync } from 'node:child_process';
@@ -67,12 +68,17 @@ const NPM_INSTALL_CMD = 'npm install --omit=dev --no-audit --no-fund';
67
68
 
68
69
  // ── Main Entry ─────────────────────────────────────────────
69
70
  export async function checkForUpdate(options = {}) {
71
+ // A failed lookup returns null by default, which a background caller wants (silent on
72
+ // network failure). `self-update` printed that null as "Already up to date", so a caller
73
+ // that reports to a person asks for the failure instead. (D#251)
74
+ const failed = (rateLimited) =>
75
+ options.reportFailure ? { updateAvailable: false, updated: false, checkFailed: true, rateLimited } : null;
70
76
  try {
71
77
  const pluginMode = isPluginMode();
72
78
  const force = Boolean(options.force);
73
79
  const allowInstall = options.allowInstall ?? !pluginMode;
74
80
 
75
- if (isDevMode() || process.env.CLAUDE_MEM_SKIP_UPDATE) return null;
81
+ if (updateCheckDisabledReason()) return null;
76
82
 
77
83
  const state = readState();
78
84
  if (!force && !shouldCheck(state)) {
@@ -99,7 +105,7 @@ export async function checkForUpdate(options = {}) {
99
105
  // rate-limit mechanism is dead. Re-reading preserves the freshly-written flag.
100
106
  const fresh = readState();
101
107
  saveState({ ...fresh, lastCheck: new Date().toISOString() });
102
- return null;
108
+ return failed(lastLookupRateLimited);
103
109
  }
104
110
 
105
111
  const currentVersion = getCurrentVersion();
@@ -147,7 +153,7 @@ export async function checkForUpdate(options = {}) {
147
153
  const s = readState();
148
154
  saveState({ ...s, lastCheck: new Date().toISOString(), lastError: err.message });
149
155
  } catch {}
150
- return null;
156
+ return failed(false);
151
157
  }
152
158
  }
153
159
 
@@ -160,7 +166,7 @@ export async function checkForUpdate(options = {}) {
160
166
  // Banner string from cached update-state (≤24h stale), or null. No network I/O.
161
167
  export function getCachedUpdateBanner() {
162
168
  try {
163
- if (isDevMode() || process.env.CLAUDE_MEM_SKIP_UPDATE) return null;
169
+ if (updateCheckDisabledReason()) return null;
164
170
  const state = readState();
165
171
  const running = pendingCachedUpdate(state);
166
172
  if (running) {
@@ -193,7 +199,7 @@ export function pendingCachedUpdate(state) {
193
199
  // Caller spawns the refresh in the background so this session doesn't wait.
194
200
  export function isUpdateCheckDue() {
195
201
  try {
196
- if (isDevMode() || process.env.CLAUDE_MEM_SKIP_UPDATE) return false;
202
+ if (updateCheckDisabledReason()) return false;
197
203
  return shouldCheck(readState());
198
204
  } catch {
199
205
  return false;
@@ -203,7 +209,7 @@ export function isUpdateCheckDue() {
203
209
  // D#187. `CLAUDE_PLUGIN_ROOT` is set in every hook and MCP process Claude Code
204
210
  // spawns, so inside those the env var answers "am I a plugin install?" perfectly —
205
211
  // which is why v3.84.1's fix, which reads it, was enough THERE. It is not set in a
206
- // plain terminal, and a plugin-only user typing `claude-mem-lite update` therefore
212
+ // plain terminal, and a plugin-only user typing `claude-mem-lite self-update` therefore
207
213
  // fell off both plugin paths at once: getCurrentVersion() returned '0.0.0' (so every
208
214
  // release compares as newer, forever), and isPluginMode() was false, so allowInstall
209
215
  // defaulted to true and downloadAndInstall laid a full managed tree into
@@ -252,6 +258,19 @@ function isPluginMode() {
252
258
  // never a command that would overwrite its working tree. Re-implementing the check at the
253
259
  // call site would make it the second copy of a predicate this file has already had to get
254
260
  // right twice (whole-dir symlink, then per-file drift) — the twin-drift class.
261
+ /**
262
+ * Why the update check will not look at all, or null when it will. checkForUpdate returns
263
+ * null both for "nothing newer" and for "never looked", so a caller that reports to a
264
+ * person asks this first: `self-update` used to print "Already up to date" under
265
+ * CLAUDE_MEM_SKIP_UPDATE without a single request (D#251).
266
+ * @returns {'dev-install'|'CLAUDE_MEM_SKIP_UPDATE'|null}
267
+ */
268
+ export function updateCheckDisabledReason() {
269
+ if (isDevMode()) return 'dev-install';
270
+ if (process.env.CLAUDE_MEM_SKIP_UPDATE) return 'CLAUDE_MEM_SKIP_UPDATE';
271
+ return null;
272
+ }
273
+
255
274
  export function isDevMode() {
256
275
  try {
257
276
  // A dev checkout always carries a .git dir. This catches a whole-directory
@@ -285,7 +304,13 @@ function shouldCheck(state) {
285
304
 
286
305
  // ── GitHub API ─────────────────────────────────────────────
287
306
  // Try releases/latest first, fallback to tags (some repos only use tags)
307
+ // Whether the most recent fetchLatestRelease call was refused with 403/429. The persisted
308
+ // `rateLimited` flag is not that: only a successful lookup clears it, so reading it after a
309
+ // network failure blamed a rate limit from an earlier call. (pre-tag review of cd9f1ab7)
310
+ let lastLookupRateLimited = false;
311
+
288
312
  export async function fetchLatestRelease() {
313
+ lastLookupRateLimited = false;
289
314
  const headers = {
290
315
  Accept: 'application/vnd.github+json',
291
316
  'User-Agent': 'claude-mem-lite-updater/1.0',
@@ -347,6 +372,7 @@ async function fetchWithTimeout(url, headers) {
347
372
  const state = readState();
348
373
  saveState({ ...state, rateLimited: true });
349
374
  debugLog('DEBUG', 'hook-update', 'GitHub API rate limited; will retry on the 6h rate-limit cadence');
375
+ lastLookupRateLimited = true;
350
376
  return 'rate-limited';
351
377
  }
352
378
  if (!res.ok) return null;
@@ -412,7 +438,7 @@ export function getCurrentVersion() {
412
438
  }
413
439
  // D#187: no env var in a plain terminal, so ask the filesystem which plugin
414
440
  // version this machine actually runs. Without this a plugin-only user's
415
- // `claude-mem-lite update` reads 0.0.0 and every release compares as newer.
441
+ // `claude-mem-lite self-update` reads 0.0.0 and every release compares as newer.
416
442
  const active = installShape()?.activePluginVersion;
417
443
  if (active) {
418
444
  try {
package/install.mjs CHANGED
@@ -3213,14 +3213,36 @@ function cleanup() {
3213
3213
  // ─── Manual Update ───────────────────────────────────────────────────────────
3214
3214
 
3215
3215
  async function manualUpdate() {
3216
- console.log('\nclaude-mem-lite update\n');
3216
+ // `self-update`, not `update`: through cli.mjs `update <id>` is the memory editor.
3217
+ console.log('\nclaude-mem-lite self-update\n');
3217
3218
 
3218
3219
  // Force check by importing hook-update (bypasses throttle for manual use)
3219
- const { checkForUpdate, getCurrentVersion } = await import('./hook-update.mjs');
3220
+ const { checkForUpdate, getCurrentVersion, updateCheckDisabledReason } = await import('./hook-update.mjs');
3221
+ // checkForUpdate returns null without looking in these two cases, and the branch at the
3222
+ // bottom would then report "Already up to date" for a check that never ran. (D#251)
3223
+ const disabled = updateCheckDisabledReason();
3224
+ if (disabled === 'CLAUDE_MEM_SKIP_UPDATE') {
3225
+ warn('Not checked: CLAUDE_MEM_SKIP_UPDATE is set, which turns off update checks and installs.');
3226
+ log(' Unset it and run this command again to update.');
3227
+ console.log('');
3228
+ return;
3229
+ }
3230
+ if (disabled === 'dev-install') {
3231
+ warn(`Not checked: ${INSTALL_DIR} is a development install (a git checkout or symlinks).`);
3232
+ log(' Update the checkout it points to with git instead.');
3233
+ console.log('');
3234
+ return;
3235
+ }
3220
3236
  log('Checking for updates...');
3221
- const result = await checkForUpdate({ force: true, allowInstall: true });
3237
+ const result = await checkForUpdate({ force: true, allowInstall: true, reportFailure: true });
3222
3238
 
3223
- if (result?.updated) {
3239
+ if (result?.checkFailed) {
3240
+ warn(
3241
+ result.rateLimited
3242
+ ? 'Not checked: GitHub is rate-limiting requests from this address. Try again later.'
3243
+ : 'Not checked: could not reach GitHub Releases (network, proxy or DNS). Nothing was installed.',
3244
+ );
3245
+ } else if (result?.updated) {
3224
3246
  ok(`Updated: v${result.from} → v${result.to}`);
3225
3247
  } else if (result?.updateAvailable && result?.installDeferred) {
3226
3248
  warn(`v${result.to} available — plugin mode only checks for updates.`);
@@ -1,7 +1,8 @@
1
1
  // lib/proxy-fetch.mjs — HTTPS over an HTTP CONNECT tunnel, using node: built-ins only.
2
2
  //
3
- // Node's global fetch (undici) does NOT honour HTTP(S)_PROXY, and undici's
4
- // ProxyAgent is not importable without adding a dependency (this package ships
3
+ // Node's global fetch (undici) does NOT honour HTTP(S)_PROXY unless the user opts in with
4
+ // NODE_USE_ENV_PROXY=1 (which then proxies plain http:// too; see postDirectHttp), and
5
+ // undici's ProxyAgent is not importable without adding a dependency (this package ships
5
6
  // three: @modelcontextprotocol/sdk, better-sqlite3, zod — a proxy shim is not
6
7
  // worth a fourth). In an environment where external hosts are only reachable
7
8
  // through a local proxy, a direct fetch hangs or dies instantly, so every
@@ -276,9 +277,18 @@ export function onceViaConnectProxy(
276
277
  // the certificate identity check, brackets stripped for IPv6.
277
278
  const tlsHost = t.hostname.replace(/^\[|\]$/g, '');
278
279
  const sni = net.isIP(tlsHost) ? {} : { servername: tlsHost };
280
+ // defaultPort: with createConnection and no agent, https.request takes its default
281
+ // port as 80, so a URL without a port went out as `Host: api.github.com:80`. GitHub
282
+ // answers that with 400 (API) or a 301 to the same URL (release downloads), which
283
+ // broke the update check and the release download behind every proxy, silently.
279
284
  const req = https.request(
280
285
  url,
281
- { method, headers, createConnection: () => tls.connect({ socket, host: tlsHost, ...sni }) },
286
+ {
287
+ method,
288
+ headers,
289
+ defaultPort: 443,
290
+ createConnection: () => tls.connect({ socket, host: tlsHost, ...sni }),
291
+ },
282
292
  (resp) => {
283
293
  const chunks = [];
284
294
  // A connection dropped mid-body destroys the response without 'end' (and
@@ -290,17 +300,7 @@ export function onceViaConnectProxy(
290
300
  if (!resp.complete) finish(reject, new Error('proxy response closed before the body ended'));
291
301
  });
292
302
  resp.on('data', (c) => chunks.push(Buffer.from(c)));
293
- resp.on('end', () => {
294
- const buf = Buffer.concat(chunks);
295
- finish(resolve, {
296
- ok: resp.statusCode >= 200 && resp.statusCode < 300,
297
- status: resp.statusCode,
298
- headers: resp.headers,
299
- buffer: () => buf,
300
- text: () => buf.toString('utf8'),
301
- json: () => JSON.parse(buf.toString('utf8')),
302
- });
303
- });
303
+ resp.on('end', () => finish(resolve, fetchLikeResponse(resp, Buffer.concat(chunks))));
304
304
  },
305
305
  );
306
306
  req.setTimeout(remaining(), () => req.destroy(new Error('proxy request timeout')));
@@ -311,6 +311,80 @@ export function onceViaConnectProxy(
311
311
  });
312
312
  }
313
313
 
314
+ /** The fetch-compatible subset both node:http transports below resolve with. */
315
+ function fetchLikeResponse(resp, buf) {
316
+ return {
317
+ ok: resp.statusCode >= 200 && resp.statusCode < 300,
318
+ status: resp.statusCode,
319
+ headers: resp.headers,
320
+ buffer: () => buf,
321
+ text: () => buf.toString('utf8'),
322
+ json: () => JSON.parse(buf.toString('utf8')),
323
+ };
324
+ }
325
+
326
+ /**
327
+ * ONE plain-http POST that never goes through a proxy. Same contract as
328
+ * onceViaConnectProxy: resolves the fetch-compatible subset without following a
329
+ * redirect, and REJECTS on a socket error, on `timeout` (the whole call), or on a body
330
+ * cut off mid-stream.
331
+ *
332
+ * Native fetch cannot promise "direct". With NODE_USE_ENV_PROXY=1 it hands an http:// URL
333
+ * to HTTP_PROXY unless Node's own NO_PROXY matcher exempts the host, headers in cleartext.
334
+ * Measured 2026-10-07 against a fake proxy: Node 26.8.1 sent it as a plain request, Node
335
+ * 22.23.3 wrote it into a CONNECT tunnel the proxy can read, and on both an explicit
336
+ * `agent: false` (a fresh Agent without `proxyEnv`) went straight to the target. The only
337
+ * caller is a loopback gateway (resolveAnthropicBaseUrl refuses plain http to any other
338
+ * host), and the proxy's loopback is not this machine's. (D#250)
339
+ *
340
+ * @param {string} url absolute http:// target
341
+ * @param {{headers?:object, body?:string, timeout?:number}} [opts]
342
+ */
343
+ export function postDirectHttp(url, { headers = {}, body = '', timeout = 20000 } = {}) {
344
+ return new Promise((resolve, reject) => {
345
+ let t;
346
+ try {
347
+ t = new URL(url);
348
+ } catch (e) {
349
+ return reject(e);
350
+ }
351
+ if (t.protocol !== 'http:') {
352
+ return reject(new Error(`direct http supports http targets only (got ${t.protocol})`));
353
+ }
354
+ let settled = false;
355
+ let req = null;
356
+ const finish = (fn, arg) => {
357
+ if (settled) return;
358
+ settled = true;
359
+ clearTimeout(overall);
360
+ fn(arg);
361
+ };
362
+ const overall = setTimeout(() => {
363
+ req?.destroy();
364
+ finish(reject, new Error('direct http request timeout'));
365
+ }, timeout);
366
+ if (typeof overall.unref === 'function') overall.unref();
367
+ req = http.request(
368
+ t,
369
+ {
370
+ method: 'POST',
371
+ headers: { ...headers, 'Content-Length': Buffer.byteLength(body) },
372
+ agent: false,
373
+ },
374
+ (resp) => {
375
+ const chunks = [];
376
+ resp.on('close', () => {
377
+ if (!resp.complete) finish(reject, new Error('response closed before the body ended'));
378
+ });
379
+ resp.on('data', (c) => chunks.push(Buffer.from(c)));
380
+ resp.on('end', () => finish(resolve, fetchLikeResponse(resp, Buffer.concat(chunks))));
381
+ },
382
+ );
383
+ req.on('error', (e) => finish(reject, e));
384
+ req.end(body);
385
+ });
386
+ }
387
+
314
388
  /**
315
389
  * onceViaConnectProxy + redirect following. Native fetch follows redirects by
316
390
  * default, so a call site swapped from fetch to the tunnel needs this or the
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "claude-mem-lite",
3
- "version": "6.23.2",
3
+ "version": "6.23.3",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "claude-mem-lite",
9
- "version": "6.23.2",
9
+ "version": "6.23.3",
10
10
  "os": [
11
11
  "darwin",
12
12
  "linux",
@@ -22,14 +22,14 @@
22
22
  },
23
23
  "devDependencies": {
24
24
  "@eslint/js": "^10.0.1",
25
- "@vitest/coverage-v8": "^5.0.1",
25
+ "@vitest/coverage-v8": "^5.0.3",
26
26
  "acorn": "8.18.0",
27
27
  "eslint": "^10.11.0",
28
28
  "fast-check": "^4.10.2",
29
29
  "knip": "^6.38.0",
30
30
  "picomatch": "^4.0.4",
31
31
  "prettier": "3.9.9",
32
- "vitest": "^5.0.0"
32
+ "vitest": "^5.0.3"
33
33
  },
34
34
  "engines": {
35
35
  "node": ">=22"
@@ -1078,9 +1078,9 @@
1078
1078
  ]
1079
1079
  },
1080
1080
  "node_modules/@rolldown/binding-android-arm-eabi": {
1081
- "version": "1.2.10",
1082
- "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.10.tgz",
1083
- "integrity": "sha512-bp9svZb+QurZeh+8H4BhrZkifEB0YBNvTVzNSJnJQkj4NrRwmQoDUCGP0vSN7PbvLeM7l1tK6GXL8mrTiH2myg==",
1081
+ "version": "1.2.13",
1082
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.13.tgz",
1083
+ "integrity": "sha512-Vu/NICrgdRvUOeaJZIyB2FP63s6fO/4ud5l8dXmxDx9yDyn+mN0y+gsvsVviSli+T361Aqo0h46EuMoobrwawA==",
1084
1084
  "cpu": [
1085
1085
  "arm"
1086
1086
  ],
@@ -1096,9 +1096,9 @@
1096
1096
  }
1097
1097
  },
1098
1098
  "node_modules/@rolldown/binding-android-arm64": {
1099
- "version": "1.2.10",
1100
- "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.10.tgz",
1101
- "integrity": "sha512-wm6Dld3RXUAZ/gRWKyUy+4W1B5CB5UeFaOzsSWJWEdxZXHH8rCYiZ5dGe6oJmhsunAPWzL7FZV+VtvmN5Ye2eA==",
1099
+ "version": "1.2.13",
1100
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.13.tgz",
1101
+ "integrity": "sha512-6LEoIrGy5vvCd2boNnv2soPSUZj/PRvhp8R/t9KlX+mIZxThIE/ZqxrGXxmuNX0FuvQFvLdZr7S4HrYpYBVhEQ==",
1102
1102
  "cpu": [
1103
1103
  "arm64"
1104
1104
  ],
@@ -1114,9 +1114,9 @@
1114
1114
  }
1115
1115
  },
1116
1116
  "node_modules/@rolldown/binding-darwin-arm64": {
1117
- "version": "1.2.10",
1118
- "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.10.tgz",
1119
- "integrity": "sha512-UbEfXq/AqGNgRTV3ik+X/iR6mUxu2QdYAadwRxJWquUGnW6gDqdP1FtLtFXRow7RJx0ssRwi80XAPr4r+4DtsA==",
1117
+ "version": "1.2.13",
1118
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.13.tgz",
1119
+ "integrity": "sha512-CaJSRzlQ6Q+zkDMVA9OkVxBjVoPRCDEE3v0FSJ9kIQBgRjFApA3Si4ijhbNVUji7ZJt+PfO0e46qy4nPInHUPA==",
1120
1120
  "cpu": [
1121
1121
  "arm64"
1122
1122
  ],
@@ -1132,9 +1132,9 @@
1132
1132
  }
1133
1133
  },
1134
1134
  "node_modules/@rolldown/binding-darwin-x64": {
1135
- "version": "1.2.10",
1136
- "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.10.tgz",
1137
- "integrity": "sha512-7f5h17q5KZVx/ji1vb8OTq31ch1O2I7K8NPIr44GkyWTApXMIsmhWqZfgpOH10xeauqghDAvGlZktasCkcF6Eg==",
1135
+ "version": "1.2.13",
1136
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.13.tgz",
1137
+ "integrity": "sha512-e4r340I5hxSzJkD3YJBxgzq/rJ3wwxwdLLb2FPt1Zpyem20nrQPT11DDEEkazwxaHumH8wpglsp/Ozgj/wT6mw==",
1138
1138
  "cpu": [
1139
1139
  "x64"
1140
1140
  ],
@@ -1150,9 +1150,9 @@
1150
1150
  }
1151
1151
  },
1152
1152
  "node_modules/@rolldown/binding-freebsd-x64": {
1153
- "version": "1.2.10",
1154
- "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.10.tgz",
1155
- "integrity": "sha512-ynOk/eEYhC6ZB2xCGvKrEOwE58oBy9LnrAqtkrDF9Fz1VTaNdGZTsV0VarJdhPwb+sOJTGjCLwcuyRJZ1dnMcQ==",
1153
+ "version": "1.2.13",
1154
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.13.tgz",
1155
+ "integrity": "sha512-hoBWDZ4/K/mJKVMbsgUd1jfpA2DiOrJ54mpegObU9TBHBBrtX4FLIXJJQRDPZ/2Dn91GvPob+Z2hwKJzf4E5SQ==",
1156
1156
  "cpu": [
1157
1157
  "x64"
1158
1158
  ],
@@ -1168,9 +1168,9 @@
1168
1168
  }
1169
1169
  },
1170
1170
  "node_modules/@rolldown/binding-linux-arm-gnueabihf": {
1171
- "version": "1.2.10",
1172
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.10.tgz",
1173
- "integrity": "sha512-ERrAs185meZZhGan7a4l3RiiJK1ArSDlHdST++uvSxe+FDbR4TwUPahT/cbZJvaG6fIpDpF78surN+tX708Y4Q==",
1171
+ "version": "1.2.13",
1172
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.13.tgz",
1173
+ "integrity": "sha512-oF9fZu3vTWnTiVAkDFxU9PJLt1nh20K9RRpuHsR7ZnE2L7XookBbDBVLojCVSLGbvtSlxeUNnjAj6DbNsKyzbg==",
1174
1174
  "cpu": [
1175
1175
  "arm"
1176
1176
  ],
@@ -1186,9 +1186,9 @@
1186
1186
  }
1187
1187
  },
1188
1188
  "node_modules/@rolldown/binding-linux-arm64-gnu": {
1189
- "version": "1.2.10",
1190
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.10.tgz",
1191
- "integrity": "sha512-KN7OHKD0J3jy1UzBwZWPxpwhODf9IARUIJcrH+yLYKOcmegZ8luEUM38lDP1bDVj40yP6PsSzCqOJF76vljFnQ==",
1189
+ "version": "1.2.13",
1190
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.13.tgz",
1191
+ "integrity": "sha512-DTpb/+jMiqWMPgphn4ksW1zW+XLJ6dJJ9FMvnIk9I291LhCctMPhMYJrP5t9p6C9qa3KXadDdUEZHBaPh3kNxQ==",
1192
1192
  "cpu": [
1193
1193
  "arm64"
1194
1194
  ],
@@ -1204,9 +1204,9 @@
1204
1204
  }
1205
1205
  },
1206
1206
  "node_modules/@rolldown/binding-linux-arm64-musl": {
1207
- "version": "1.2.10",
1208
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.10.tgz",
1209
- "integrity": "sha512-8l9wP8O+wa8zD6iw6egSfzVtu7oZVfH3hlUsMM4MwbLMhxleqeoXbZzjddyK3YyNlwLhqznq3tF7PkNJ8T/V2w==",
1207
+ "version": "1.2.13",
1208
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.13.tgz",
1209
+ "integrity": "sha512-xU+Kvv9N2A3SY35zFh1FWWNjxbadE/BKeqnkXe7vScU4GZsw757BlVmDLITZEq8DPpk6m7uoDYkK7P+x/uU5Ow==",
1210
1210
  "cpu": [
1211
1211
  "arm64"
1212
1212
  ],
@@ -1222,9 +1222,9 @@
1222
1222
  }
1223
1223
  },
1224
1224
  "node_modules/@rolldown/binding-linux-ppc64-gnu": {
1225
- "version": "1.2.10",
1226
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.10.tgz",
1227
- "integrity": "sha512-SeXNKeQzA5kLhz/J0CH6ZP0/HJ3v1xm/0YbiYpE0kK7emfRC2OIGGIaE14xzkISEGv2aYuUSpiLiU5Gbq+OI0A==",
1225
+ "version": "1.2.13",
1226
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.13.tgz",
1227
+ "integrity": "sha512-XMk/hnhh25oQ756Lclb1Q11h4ll0xC0Esa5w4Vzp+mAE2S3AGJgeM0SonrIgY8fHhjarb6hcoTuwoFG0VVP2ig==",
1228
1228
  "cpu": [
1229
1229
  "ppc64"
1230
1230
  ],
@@ -1240,9 +1240,9 @@
1240
1240
  }
1241
1241
  },
1242
1242
  "node_modules/@rolldown/binding-linux-s390x-gnu": {
1243
- "version": "1.2.10",
1244
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.10.tgz",
1245
- "integrity": "sha512-mtht0nR+y8/hart4175Ll15w7lY8dg7CtQ+j2FDNTsDRspOWTK/2V3l0aj9sIj7XmvqxT8Yli/wq22e7feTTWg==",
1243
+ "version": "1.2.13",
1244
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.13.tgz",
1245
+ "integrity": "sha512-U1BoTHYmlywE2n3HUWjzZ+8EQsKr+OwpxYuDWaubx42tUL8QSL7nOqRz/NVHanibbFP3M1Rxuprz/wNcbMKjqw==",
1246
1246
  "cpu": [
1247
1247
  "s390x"
1248
1248
  ],
@@ -1258,9 +1258,9 @@
1258
1258
  }
1259
1259
  },
1260
1260
  "node_modules/@rolldown/binding-linux-x64-gnu": {
1261
- "version": "1.2.10",
1262
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.10.tgz",
1263
- "integrity": "sha512-FSM94nGd55NYo48usCyM/nHfUKRnqc9+b0vJNuKV0oCCpIp/OGims7rO1Nv/DkFkt0S/s2rxsJ2kkS8J3HcpeA==",
1261
+ "version": "1.2.13",
1262
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.13.tgz",
1263
+ "integrity": "sha512-J4cm80Pc6wEwV5AZ42o62sIQgDk+Y7R2s646jIwuvO+4V46QB58N4vVuMPWCBaNgursXLpmUWJV//WQAkPvHBQ==",
1264
1264
  "cpu": [
1265
1265
  "x64"
1266
1266
  ],
@@ -1276,9 +1276,9 @@
1276
1276
  }
1277
1277
  },
1278
1278
  "node_modules/@rolldown/binding-linux-x64-musl": {
1279
- "version": "1.2.10",
1280
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.10.tgz",
1281
- "integrity": "sha512-C3YxNB16myRLs7o+B+6PnQ6jBsdIS4+AE4Ah8glVGhDpEv9AOvxhZ/1duAb4B0UGczEK/lBbccksd8VI+p6zfw==",
1279
+ "version": "1.2.13",
1280
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.13.tgz",
1281
+ "integrity": "sha512-W0euZS40U4V6JkmEnVCIX9mcsL6cbXQ4X8c2w+MMOIjFg68TXUW+u3RT+2e1t1pv9mg/EP3pDtK3POXdQ7Rxyw==",
1282
1282
  "cpu": [
1283
1283
  "x64"
1284
1284
  ],
@@ -1294,9 +1294,9 @@
1294
1294
  }
1295
1295
  },
1296
1296
  "node_modules/@rolldown/binding-openharmony-arm64": {
1297
- "version": "1.2.10",
1298
- "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.10.tgz",
1299
- "integrity": "sha512-571TlE/F1eeTjjdjYAMMMPs1Mfv3MtX6s3+ZKVU6HiUjZ5Njc6c/qzNy/8K3zALTZnaw3JQVYrHxvNfjm43KAg==",
1297
+ "version": "1.2.13",
1298
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.13.tgz",
1299
+ "integrity": "sha512-do/AF/4n9MRshia3a5aXoy8xM2c6mgfT6D7H/dY6my5z+hfCIR4ab7mk4IRj++nsEQpKy39kd0DQnDq+r692tw==",
1300
1300
  "cpu": [
1301
1301
  "arm64"
1302
1302
  ],
@@ -1312,9 +1312,9 @@
1312
1312
  }
1313
1313
  },
1314
1314
  "node_modules/@rolldown/binding-win32-arm64-msvc": {
1315
- "version": "1.2.10",
1316
- "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.10.tgz",
1317
- "integrity": "sha512-QXW+ZWaiqs2c7Fi++D/SsW07LTPcUrncxcskJGfGNBoaLik1IU6fJymz4HsqwEO0u5Iq11yTO0B/mc4cPk7jrQ==",
1315
+ "version": "1.2.13",
1316
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.13.tgz",
1317
+ "integrity": "sha512-6FtUf2cJZobutJdxnGYX8z0vtbgqU0b2v8vfBhkXb9wp2MppMFtkunE+IaOntyi01rkIQoPW2GHABtfzsC0BRQ==",
1318
1318
  "cpu": [
1319
1319
  "arm64"
1320
1320
  ],
@@ -1330,9 +1330,9 @@
1330
1330
  }
1331
1331
  },
1332
1332
  "node_modules/@rolldown/binding-win32-x64-msvc": {
1333
- "version": "1.2.10",
1334
- "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.10.tgz",
1335
- "integrity": "sha512-5FQFGgah17YeMtG1Yd5a+rMxQpTksyNXxRtKz06FVTaQw3RKYUJQbUoKk0/5jrXBpDo+7makNP7UHA2LQyH64A==",
1333
+ "version": "1.2.13",
1334
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.13.tgz",
1335
+ "integrity": "sha512-UKhFaZTeTcbKrb3iU82m17jVcPEAoqDkCN5MBqgPyZSwp/cQmib21crTS0DdH7T1B7wZRWEI89YQAOJMet5yhg==",
1336
1336
  "cpu": [
1337
1337
  "x64"
1338
1338
  ],
@@ -1406,9 +1406,9 @@
1406
1406
  "license": "MIT"
1407
1407
  },
1408
1408
  "node_modules/@vitest/coverage-v8": {
1409
- "version": "5.0.1",
1410
- "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-5.0.1.tgz",
1411
- "integrity": "sha512-FRC8ACiudC3dI6MTplzRSYWHDRnIv2IPfbzs4FdoJNsMal/35sWV8hwIfV8ZcqzSPy+uXHeMVONt9CEqtOU17w==",
1409
+ "version": "5.0.3",
1410
+ "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-5.0.3.tgz",
1411
+ "integrity": "sha512-+klsyz7BvT1vCU28Zkfzms1Ia78XD0V41U3FUtRaa3S+vOr/EXvK1O6BvVD7l1RzEjm6SONR2aybOvDDf9u0mQ==",
1412
1412
  "dev": true,
1413
1413
  "license": "MIT",
1414
1414
  "dependencies": {
@@ -1425,8 +1425,8 @@
1425
1425
  "url": "https://opencollective.com/vitest"
1426
1426
  },
1427
1427
  "peerDependencies": {
1428
- "@vitest/browser": "5.0.1",
1429
- "vitest": "5.0.1"
1428
+ "@vitest/browser": "5.0.3",
1429
+ "vitest": "5.0.3"
1430
1430
  },
1431
1431
  "peerDependenciesMeta": {
1432
1432
  "@vitest/browser": {
@@ -1458,14 +1458,14 @@
1458
1458
  }
1459
1459
  },
1460
1460
  "node_modules/@vitest/mocker": {
1461
- "version": "5.0.1",
1462
- "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-5.0.1.tgz",
1463
- "integrity": "sha512-6K1DoBNAPGvuOcSsGA4D6x+5zEEff/KmOOP3uetT2TrGpVfI+HRHRnJJfKi5ib/g1vx8IYHQD8s0pbJz8WQI7Q==",
1461
+ "version": "5.0.3",
1462
+ "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-5.0.3.tgz",
1463
+ "integrity": "sha512-T8sWAIbkSyAjkwTcaEc3Iu0o9A27X1/kdXrizhZkGuSKScRQtRzclfAMpOTcGdXCsqxeWlpGy3XjqaW8CpLORg==",
1464
1464
  "dev": true,
1465
1465
  "license": "MIT",
1466
1466
  "dependencies": {
1467
1467
  "@jridgewell/trace-mapping": "0.3.31",
1468
- "@vitest/spy": "5.0.1",
1468
+ "@vitest/spy": "5.0.3",
1469
1469
  "estree-walker": "^3.0.3",
1470
1470
  "magic-string": "^1.2.3"
1471
1471
  },
@@ -1486,9 +1486,9 @@
1486
1486
  }
1487
1487
  },
1488
1488
  "node_modules/@vitest/spy": {
1489
- "version": "5.0.1",
1490
- "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-5.0.1.tgz",
1491
- "integrity": "sha512-rbto/mF/SGERxEgYOek7Xm6B9b+y+mVoo+f4b2LymYO8zM1b7uB5nHuhVMTP2hxdzgxvGiZYGxGIaMvL5y180Q==",
1489
+ "version": "5.0.3",
1490
+ "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-5.0.3.tgz",
1491
+ "integrity": "sha512-XhFysQTB8AZ+P4gMi+Lpo99vg2AZi0qKpaB9yXQl37+CaMEAPO3iH/wGVnSyL5MPERiLezpqTVtrR6UZH5GCXg==",
1492
1492
  "dev": true,
1493
1493
  "license": "MIT",
1494
1494
  "funding": {
@@ -1646,9 +1646,9 @@
1646
1646
  }
1647
1647
  },
1648
1648
  "node_modules/brace-expansion": {
1649
- "version": "5.0.9",
1650
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz",
1651
- "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==",
1649
+ "version": "5.0.12",
1650
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.12.tgz",
1651
+ "integrity": "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==",
1652
1652
  "dev": true,
1653
1653
  "license": "MIT",
1654
1654
  "dependencies": {
@@ -1711,9 +1711,9 @@
1711
1711
  }
1712
1712
  },
1713
1713
  "node_modules/chai": {
1714
- "version": "6.2.2",
1715
- "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz",
1716
- "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==",
1714
+ "version": "6.3.0",
1715
+ "resolved": "https://registry.npmjs.org/chai/-/chai-6.3.0.tgz",
1716
+ "integrity": "sha512-XWAtwJ6OHO+tj0EKCs0Y2UamnyOxseZWltU4x2U2wh8g4AigdjwvtUjvLP2tqkA/avxHEtzxNaqGq/YGNwckKg==",
1717
1717
  "dev": true,
1718
1718
  "license": "MIT",
1719
1719
  "engines": {
@@ -3075,9 +3075,9 @@
3075
3075
  }
3076
3076
  },
3077
3077
  "node_modules/magic-string": {
3078
- "version": "1.4.2",
3079
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-1.4.2.tgz",
3080
- "integrity": "sha512-vG+rjFRj1PqdIBozIxAGMjPlOhaVe+GXpbttY/iSK7rGcJRMlwNJO7dcUwmUqkymsFLJiNGI06t4D7Fr7yRC9g==",
3078
+ "version": "1.4.3",
3079
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-1.4.3.tgz",
3080
+ "integrity": "sha512-z12OxmaPGE0F4xlpGdjuAUckipLpQlTAuAmyGhNoD7ODpYUzvDfvtxUbjM/jwznyP178oju/KDdyi220wNJ0RQ==",
3081
3081
  "dev": true,
3082
3082
  "license": "MIT",
3083
3083
  "dependencies": {
@@ -3174,9 +3174,9 @@
3174
3174
  "license": "MIT"
3175
3175
  },
3176
3176
  "node_modules/nanoid": {
3177
- "version": "3.3.19",
3178
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.19.tgz",
3179
- "integrity": "sha512-Y2tUNy4ouw6tq5oDSKeQYGOyhkUBhNOcGV/02KC+6kd9eDGqdZd++mjMiIDilrBYvjEnCYvVtsuHCuP+okSfug==",
3177
+ "version": "3.3.20",
3178
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.20.tgz",
3179
+ "integrity": "sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ==",
3180
3180
  "dev": true,
3181
3181
  "funding": [
3182
3182
  {
@@ -3240,9 +3240,9 @@
3240
3240
  }
3241
3241
  },
3242
3242
  "node_modules/obug": {
3243
- "version": "2.1.4",
3244
- "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.4.tgz",
3245
- "integrity": "sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==",
3243
+ "version": "2.2.1",
3244
+ "resolved": "https://registry.npmjs.org/obug/-/obug-2.2.1.tgz",
3245
+ "integrity": "sha512-XrsrhT5sybtKI6wakr2SPOlGZWWYbUXZ7a0jT8/QOeAPau+1X/bSegNe5YR75oJmEZQbKningirmGOEJCIk61Q==",
3246
3246
  "dev": true,
3247
3247
  "funding": [
3248
3248
  "https://github.com/sponsors/sxzz",
@@ -3468,9 +3468,9 @@
3468
3468
  }
3469
3469
  },
3470
3470
  "node_modules/postcss": {
3471
- "version": "8.5.28",
3472
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.28.tgz",
3473
- "integrity": "sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==",
3471
+ "version": "8.5.29",
3472
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.29.tgz",
3473
+ "integrity": "sha512-49cGhUbXj8Qenv0iTMxA1cFBzxXoctpC9Ujd77t1WcbJIr6nF/eI7g/8MgxrYldFRuAXvja7xQRwavoW7kgrxQ==",
3474
3474
  "dev": true,
3475
3475
  "funding": [
3476
3476
  {
@@ -3489,9 +3489,9 @@
3489
3489
  "license": "MIT",
3490
3490
  "peer": true,
3491
3491
  "dependencies": {
3492
- "nanoid": "^3.3.18",
3492
+ "nanoid": "^3.3.19",
3493
3493
  "picocolors": "^1.1.1",
3494
- "source-map-js": "^1.2.1"
3494
+ "source-map-js": "^1.2.2"
3495
3495
  },
3496
3496
  "engines": {
3497
3497
  "node": "^10 || ^12 || >=14"
@@ -3647,14 +3647,14 @@
3647
3647
  }
3648
3648
  },
3649
3649
  "node_modules/rolldown": {
3650
- "version": "1.2.10",
3651
- "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.10.tgz",
3652
- "integrity": "sha512-OxkA08pSryMK7B3XiFA09B4OJ1xJMPgIYCBMY2xchzpqgBGsV1o0DetPAE+Sl3N3L4oCPiEzmHVSOj7iR04Zog==",
3650
+ "version": "1.2.13",
3651
+ "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.13.tgz",
3652
+ "integrity": "sha512-/5apOkwWxtACcQtZ5WlrAsKS4JwXVThQPJZ3RqIruRY9UG9M8e0VlXN068xum/JRKA4aIUoJ13ghe/kGCvidiQ==",
3653
3653
  "dev": true,
3654
3654
  "license": "MIT",
3655
3655
  "peer": true,
3656
3656
  "dependencies": {
3657
- "@oxc-project/types": "=0.151.0",
3657
+ "@oxc-project/types": "=0.153.0",
3658
3658
  "@rolldown/pluginutils": "^1.0.0"
3659
3659
  },
3660
3660
  "bin": {
@@ -3664,27 +3664,27 @@
3664
3664
  "node": "^20.19.0 || >=22.12.0"
3665
3665
  },
3666
3666
  "optionalDependencies": {
3667
- "@rolldown/binding-android-arm-eabi": "1.2.10",
3668
- "@rolldown/binding-android-arm64": "1.2.10",
3669
- "@rolldown/binding-darwin-arm64": "1.2.10",
3670
- "@rolldown/binding-darwin-x64": "1.2.10",
3671
- "@rolldown/binding-freebsd-x64": "1.2.10",
3672
- "@rolldown/binding-linux-arm-gnueabihf": "1.2.10",
3673
- "@rolldown/binding-linux-arm64-gnu": "1.2.10",
3674
- "@rolldown/binding-linux-arm64-musl": "1.2.10",
3675
- "@rolldown/binding-linux-ppc64-gnu": "1.2.10",
3676
- "@rolldown/binding-linux-s390x-gnu": "1.2.10",
3677
- "@rolldown/binding-linux-x64-gnu": "1.2.10",
3678
- "@rolldown/binding-linux-x64-musl": "1.2.10",
3679
- "@rolldown/binding-openharmony-arm64": "1.2.10",
3680
- "@rolldown/binding-win32-arm64-msvc": "1.2.10",
3681
- "@rolldown/binding-win32-x64-msvc": "1.2.10"
3667
+ "@rolldown/binding-android-arm-eabi": "1.2.13",
3668
+ "@rolldown/binding-android-arm64": "1.2.13",
3669
+ "@rolldown/binding-darwin-arm64": "1.2.13",
3670
+ "@rolldown/binding-darwin-x64": "1.2.13",
3671
+ "@rolldown/binding-freebsd-x64": "1.2.13",
3672
+ "@rolldown/binding-linux-arm-gnueabihf": "1.2.13",
3673
+ "@rolldown/binding-linux-arm64-gnu": "1.2.13",
3674
+ "@rolldown/binding-linux-arm64-musl": "1.2.13",
3675
+ "@rolldown/binding-linux-ppc64-gnu": "1.2.13",
3676
+ "@rolldown/binding-linux-s390x-gnu": "1.2.13",
3677
+ "@rolldown/binding-linux-x64-gnu": "1.2.13",
3678
+ "@rolldown/binding-linux-x64-musl": "1.2.13",
3679
+ "@rolldown/binding-openharmony-arm64": "1.2.13",
3680
+ "@rolldown/binding-win32-arm64-msvc": "1.2.13",
3681
+ "@rolldown/binding-win32-x64-msvc": "1.2.13"
3682
3682
  }
3683
3683
  },
3684
3684
  "node_modules/rolldown/node_modules/@oxc-project/types": {
3685
- "version": "0.151.0",
3686
- "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.151.0.tgz",
3687
- "integrity": "sha512-J1yXrIlNDZVzE3ada310xeAw7nH8yCAyLPuUIsjKatFPmfn5bS1oW+cM+QsGOtVWd5nhSpbwZWx/rue+r5Z+PA==",
3685
+ "version": "0.153.0",
3686
+ "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.153.0.tgz",
3687
+ "integrity": "sha512-jSNrRIyvPVLL5E1z/tS5zLAprosGz/FuI1PWwEOz59j3E4TTTzSpqKb/RDGqJhhW0QHYISGXxq582wGx6T11Tw==",
3688
3688
  "dev": true,
3689
3689
  "license": "MIT",
3690
3690
  "peer": true,
@@ -3858,17 +3858,10 @@
3858
3858
  "url": "https://github.com/sponsors/ljharb"
3859
3859
  }
3860
3860
  },
3861
- "node_modules/siginfo": {
3862
- "version": "2.0.0",
3863
- "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz",
3864
- "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==",
3865
- "dev": true,
3866
- "license": "ISC"
3867
- },
3868
3861
  "node_modules/smol-toml": {
3869
- "version": "1.8.0",
3870
- "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.8.0.tgz",
3871
- "integrity": "sha512-kCZr2V3ch9i00x8zXRhjUNVcjG9ijES5dDudkXvUVCT5QlJNQWElSJdZqyPemffHoLNUYwOcou0Fy+ojN0uHSQ==",
3862
+ "version": "1.9.0",
3863
+ "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.9.0.tgz",
3864
+ "integrity": "sha512-hpd+HLON7HdZXqYchMM/+LaTTbdK0AU3NngIJ4KVyWbY9bfQqdL9cD+4yf6dUoU2Ap4VsU0JkQi6FxAI1B2mXQ==",
3872
3865
  "dev": true,
3873
3866
  "license": "BSD-3-Clause",
3874
3867
  "engines": {
@@ -3879,22 +3872,15 @@
3879
3872
  }
3880
3873
  },
3881
3874
  "node_modules/source-map-js": {
3882
- "version": "1.2.1",
3883
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
3884
- "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
3875
+ "version": "1.2.2",
3876
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.2.tgz",
3877
+ "integrity": "sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==",
3885
3878
  "dev": true,
3886
3879
  "license": "BSD-3-Clause",
3887
3880
  "engines": {
3888
3881
  "node": ">=0.10.0"
3889
3882
  }
3890
3883
  },
3891
- "node_modules/stackback": {
3892
- "version": "0.0.2",
3893
- "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz",
3894
- "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==",
3895
- "dev": true,
3896
- "license": "MIT"
3897
- },
3898
3884
  "node_modules/statuses": {
3899
3885
  "version": "2.0.2",
3900
3886
  "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
@@ -3905,9 +3891,9 @@
3905
3891
  }
3906
3892
  },
3907
3893
  "node_modules/std-env": {
3908
- "version": "4.2.0",
3909
- "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.2.0.tgz",
3910
- "integrity": "sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==",
3894
+ "version": "4.3.0",
3895
+ "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.3.0.tgz",
3896
+ "integrity": "sha512-OtU/EgQ1kIm5KwqQpBC6ZEMXrZRui11w8zgfTWp8cdO9B8OaPsbA8bTHO2P+HNo1VlUTGMVBwPhydu6poeXiag==",
3911
3897
  "dev": true,
3912
3898
  "license": "MIT"
3913
3899
  },
@@ -3925,9 +3911,9 @@
3925
3911
  }
3926
3912
  },
3927
3913
  "node_modules/tinybench": {
3928
- "version": "6.1.4",
3929
- "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-6.1.4.tgz",
3930
- "integrity": "sha512-9APumHG7r4yOk4X4WlkmE71aZcv1gvin1czO3OQ1U9iJcFA5Ja/ygyb0vPOVHTthFozUYs8CLoLUlM8grb2lTQ==",
3914
+ "version": "6.2.1",
3915
+ "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-6.2.1.tgz",
3916
+ "integrity": "sha512-IAbQaPJIIdhVxi0mqy9lez1wEwje0UQf9F1vwtbelEG5Nbgn0nPOxCvU+mNeNS9gyJTAhrHp74CbUaSynQpZcQ==",
3931
3917
  "dev": true,
3932
3918
  "license": "MIT",
3933
3919
  "engines": {
@@ -3935,9 +3921,9 @@
3935
3921
  }
3936
3922
  },
3937
3923
  "node_modules/tinyexec": {
3938
- "version": "1.3.0",
3939
- "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.3.0.tgz",
3940
- "integrity": "sha512-QKAl9m8gWWGHV8jZcPeym6j+XULi6tOf1mT83WYJ4Lk2ytW/uwAWkrP0uFsdoYMdueVJ0qs26wZ+23xeB4ibNQ==",
3924
+ "version": "1.3.1",
3925
+ "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.3.1.tgz",
3926
+ "integrity": "sha512-GCvB3aoys96IuDFBMcTB46JOR6mdMtAToqwiW8JlWhsoh1mhHi/xn9ss/Dg7N555GiJyEt2qzoG/NHCwM6h1EA==",
3941
3927
  "dev": true,
3942
3928
  "license": "MIT",
3943
3929
  "engines": {
@@ -4061,9 +4047,9 @@
4061
4047
  }
4062
4048
  },
4063
4049
  "node_modules/vite": {
4064
- "version": "8.3.0",
4065
- "resolved": "https://registry.npmjs.org/vite/-/vite-8.3.0.tgz",
4066
- "integrity": "sha512-lhZBVvEHefgE+HQZC9O7EBJgCU/nVzFNl7vkS4RE0APtWLP02/8QVIkQtzBxPquh7lq5/78NHipTj7ODQ6XuyQ==",
4050
+ "version": "8.3.3",
4051
+ "resolved": "https://registry.npmjs.org/vite/-/vite-8.3.3.tgz",
4052
+ "integrity": "sha512-cTAldKPImjg6c+gk48U19POPn3GCBzZwpdsN8ZMEEcbpes+6/wvfqUd0C2y3qYY4wsj8PwgFwrZ/1jBPVttMSg==",
4067
4053
  "dev": true,
4068
4054
  "license": "MIT",
4069
4055
  "peer": true,
@@ -4071,7 +4057,7 @@
4071
4057
  "lightningcss": "^1.33.0",
4072
4058
  "picomatch": "^4.0.7",
4073
4059
  "postcss": "^8.5.28",
4074
- "rolldown": "~1.2.6",
4060
+ "rolldown": "~1.2.11",
4075
4061
  "tinyglobby": "^0.2.17"
4076
4062
  },
4077
4063
  "bin": {
@@ -4140,14 +4126,14 @@
4140
4126
  }
4141
4127
  },
4142
4128
  "node_modules/vitest": {
4143
- "version": "5.0.1",
4144
- "resolved": "https://registry.npmjs.org/vitest/-/vitest-5.0.1.tgz",
4145
- "integrity": "sha512-iA95lQbKEkvrtTkdAgnWbXfbipWiiWe/hDl2P5tMi6WFwD76G0NxXAGp/M9EOcYupeGJRr6wppMc7CoA41TQjg==",
4129
+ "version": "5.0.3",
4130
+ "resolved": "https://registry.npmjs.org/vitest/-/vitest-5.0.3.tgz",
4131
+ "integrity": "sha512-xMw97S3rjdtj5dkVat7jCsqWBpvchs3RlpQctUqwJD0KkERk40vz2fJ77lDwW/Vzh/pk18eItYAzkodhSes3jQ==",
4146
4132
  "dev": true,
4147
4133
  "license": "MIT",
4148
4134
  "dependencies": {
4149
4135
  "@types/chai": "^5.2.2",
4150
- "@vitest/mocker": "5.0.1",
4136
+ "@vitest/mocker": "5.0.3",
4151
4137
  "chai": "^6.2.2",
4152
4138
  "es-module-lexer": "^2.3.2",
4153
4139
  "expect-type": "^1.4.0",
@@ -4155,10 +4141,10 @@
4155
4141
  "obug": "^2.1.4",
4156
4142
  "picomatch": "^4.0.7",
4157
4143
  "std-env": "^4.2.0",
4158
- "tinybench": "6.1.4",
4159
- "tinyexec": "1.3.0",
4144
+ "tinybench": "^6.1.4",
4145
+ "tinyexec": "^1.3.0",
4160
4146
  "tinyglobby": "^0.2.17",
4161
- "why-is-node-running": "^2.3.0"
4147
+ "why-is-node-running": "3.2.1"
4162
4148
  },
4163
4149
  "bin": {
4164
4150
  "vitest": "vitest.mjs"
@@ -4173,12 +4159,12 @@
4173
4159
  "@edge-runtime/vm": "*",
4174
4160
  "@opentelemetry/api": "^1.9.0",
4175
4161
  "@types/node": "^22.0.0 || >=24.0.0",
4176
- "@vitest/browser-playwright": "5.0.1",
4177
- "@vitest/browser-preview": "5.0.1",
4162
+ "@vitest/browser-playwright": "5.0.3",
4163
+ "@vitest/browser-preview": "5.0.3",
4178
4164
  "@vitest/browser-webdriverio": "^5.0.0-beta.5 || >=5.0.0",
4179
- "@vitest/coverage-istanbul": "5.0.1",
4180
- "@vitest/coverage-v8": "5.0.1",
4181
- "@vitest/ui": "5.0.1",
4165
+ "@vitest/coverage-istanbul": "5.0.3",
4166
+ "@vitest/coverage-v8": "5.0.3",
4167
+ "@vitest/ui": "5.0.3",
4182
4168
  "happy-dom": "*",
4183
4169
  "jsdom": "*",
4184
4170
  "vite": "^6.4.0 || ^7.0.0 || ^8.0.0"
@@ -4248,20 +4234,16 @@
4248
4234
  }
4249
4235
  },
4250
4236
  "node_modules/why-is-node-running": {
4251
- "version": "2.3.0",
4252
- "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz",
4253
- "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==",
4237
+ "version": "3.2.1",
4238
+ "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-3.2.1.tgz",
4239
+ "integrity": "sha512-Tb2FUhB4vUsGQlfSquQLYkApkuPAFQXGFzxWKHHumVz2dK+X1RUm/HnID4+TfIGYJ1kTcwOaCk/buYCEJr6YjQ==",
4254
4240
  "dev": true,
4255
4241
  "license": "MIT",
4256
- "dependencies": {
4257
- "siginfo": "^2.0.0",
4258
- "stackback": "0.0.2"
4259
- },
4260
4242
  "bin": {
4261
4243
  "why-is-node-running": "cli.js"
4262
4244
  },
4263
4245
  "engines": {
4264
- "node": ">=8"
4246
+ "node": ">=20.11"
4265
4247
  }
4266
4248
  },
4267
4249
  "node_modules/word-wrap": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-mem-lite",
3
- "version": "6.23.2",
3
+ "version": "6.23.3",
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",
@@ -241,13 +241,13 @@
241
241
  },
242
242
  "devDependencies": {
243
243
  "@eslint/js": "^10.0.1",
244
- "@vitest/coverage-v8": "^5.0.1",
244
+ "@vitest/coverage-v8": "^5.0.3",
245
245
  "acorn": "8.18.0",
246
246
  "eslint": "^10.11.0",
247
247
  "fast-check": "^4.10.2",
248
248
  "knip": "^6.38.0",
249
249
  "picomatch": "^4.0.4",
250
250
  "prettier": "3.9.9",
251
- "vitest": "^5.0.0"
251
+ "vitest": "^5.0.3"
252
252
  }
253
253
  }