claude-mem-lite 3.3.0 → 3.3.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.
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"plugins": [
|
|
11
11
|
{
|
|
12
12
|
"name": "claude-mem-lite",
|
|
13
|
-
"version": "3.3.
|
|
13
|
+
"version": "3.3.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": "3.3.
|
|
3
|
+
"version": "3.3.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/haiku-client.mjs
CHANGED
|
@@ -6,12 +6,84 @@
|
|
|
6
6
|
// overridable via OPENROUTER_MODEL
|
|
7
7
|
|
|
8
8
|
import { execFileSync, spawn } from 'child_process';
|
|
9
|
+
import http from 'node:http';
|
|
10
|
+
import https from 'node:https';
|
|
11
|
+
import tls from 'node:tls';
|
|
9
12
|
import { readFileSync } from 'fs';
|
|
10
13
|
import { join } from 'path';
|
|
11
14
|
import { randomUUID } from 'crypto';
|
|
12
15
|
import { debugLog, debugCatch, parseJsonFromLLM } from './utils.mjs';
|
|
13
16
|
import { DB_DIR } from './schema.mjs';
|
|
14
17
|
|
|
18
|
+
// ─── Proxy support (native fetch ignores HTTP(S)_PROXY) ──────────────────────
|
|
19
|
+
//
|
|
20
|
+
// Node's global fetch (undici) does NOT honour HTTP(S)_PROXY env vars, and
|
|
21
|
+
// undici's ProxyAgent isn't importable without adding a dependency. In an env
|
|
22
|
+
// that requires a local proxy to reach external APIs (e.g.
|
|
23
|
+
// HTTPS_PROXY=http://127.0.0.1:PORT), a direct fetch to openrouter.ai
|
|
24
|
+
// hangs/times out. We tunnel HTTPS through the HTTP CONNECT proxy using built-ins
|
|
25
|
+
// only. No proxy var (or a NO_PROXY host) → null → callers keep native fetch,
|
|
26
|
+
// unchanged (zero behaviour change when no proxy is configured).
|
|
27
|
+
function httpConnectProxyFor(targetUrl) {
|
|
28
|
+
const proxy = process.env.HTTPS_PROXY || process.env.https_proxy || process.env.HTTP_PROXY || process.env.http_proxy;
|
|
29
|
+
if (!proxy || !/^https?:\/\//.test(proxy)) return null; // socks5 ALL_PROXY not supported here
|
|
30
|
+
try {
|
|
31
|
+
const host = new URL(targetUrl).hostname;
|
|
32
|
+
const noProxy = (process.env.NO_PROXY || process.env.no_proxy || '').split(',').map((s) => s.trim()).filter(Boolean);
|
|
33
|
+
if (noProxy.some((n) => n === host || (n.startsWith('.') && host.endsWith(n.slice(1))))) return null;
|
|
34
|
+
return proxy;
|
|
35
|
+
} catch {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// fetch-compatible (subset) POST over an HTTP CONNECT tunnel: returns
|
|
41
|
+
// { ok, status, json(), text() }. Rejects on connect/timeout/socket error so the
|
|
42
|
+
// caller's try/catch degrades to the CLI exactly as a failed fetch would.
|
|
43
|
+
function postViaConnectProxy(proxy, url, { headers = {}, body = '', timeout = 20000 }) {
|
|
44
|
+
return new Promise((resolve, reject) => {
|
|
45
|
+
const p = new URL(proxy);
|
|
46
|
+
const t = new URL(url);
|
|
47
|
+
const port = Number(t.port) || 443;
|
|
48
|
+
let settled = false;
|
|
49
|
+
const finish = (fn, arg) => { if (!settled) { settled = true; fn(arg); } };
|
|
50
|
+
const connReq = http.request({
|
|
51
|
+
host: p.hostname,
|
|
52
|
+
port: Number(p.port) || 80,
|
|
53
|
+
method: 'CONNECT',
|
|
54
|
+
path: `${t.hostname}:${port}`,
|
|
55
|
+
headers: { Host: `${t.hostname}:${port}` },
|
|
56
|
+
});
|
|
57
|
+
connReq.setTimeout(timeout, () => connReq.destroy(new Error('proxy CONNECT timeout')));
|
|
58
|
+
connReq.on('error', (e) => finish(reject, e));
|
|
59
|
+
connReq.on('connect', (res, socket) => {
|
|
60
|
+
if (res.statusCode !== 200) {
|
|
61
|
+
socket.destroy();
|
|
62
|
+
return finish(reject, new Error(`proxy CONNECT ${res.statusCode}`));
|
|
63
|
+
}
|
|
64
|
+
const req = https.request(
|
|
65
|
+
url,
|
|
66
|
+
{ method: 'POST', headers, createConnection: () => tls.connect({ socket, servername: t.hostname }) },
|
|
67
|
+
(resp) => {
|
|
68
|
+
let data = '';
|
|
69
|
+
resp.setEncoding('utf8');
|
|
70
|
+
resp.on('data', (c) => (data += c));
|
|
71
|
+
resp.on('end', () => finish(resolve, {
|
|
72
|
+
ok: resp.statusCode >= 200 && resp.statusCode < 300,
|
|
73
|
+
status: resp.statusCode,
|
|
74
|
+
json: () => JSON.parse(data),
|
|
75
|
+
text: () => data,
|
|
76
|
+
}));
|
|
77
|
+
}
|
|
78
|
+
);
|
|
79
|
+
req.setTimeout(timeout, () => req.destroy(new Error('proxy request timeout')));
|
|
80
|
+
req.on('error', (e) => finish(reject, e));
|
|
81
|
+
req.end(body);
|
|
82
|
+
});
|
|
83
|
+
connReq.end();
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
15
87
|
// ─── Model Resolution ────────────────────────────────────────────────────────
|
|
16
88
|
|
|
17
89
|
// CLI name → API model ID mapping
|
|
@@ -493,17 +565,20 @@ async function callOpenRouterAPI(prompt, tier, { timeout, maxTokens, temperature
|
|
|
493
565
|
if (system) messages.push({ role: 'system', content: system });
|
|
494
566
|
messages.push({ role: 'user', content: user });
|
|
495
567
|
|
|
496
|
-
const
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
568
|
+
const url = 'https://openrouter.ai/api/v1/chat/completions';
|
|
569
|
+
const reqHeaders = {
|
|
570
|
+
'Content-Type': 'application/json',
|
|
571
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
572
|
+
// Optional OpenRouter attribution headers (ignored by the API if absent).
|
|
573
|
+
'X-Title': 'claude-mem-lite',
|
|
574
|
+
};
|
|
575
|
+
const reqBody = JSON.stringify({ model, max_tokens: maxTokens, temperature, messages });
|
|
576
|
+
// Native fetch ignores HTTP(S)_PROXY; when a proxy is configured, tunnel the
|
|
577
|
+
// request through it — a direct fetch to openrouter.ai times out behind one.
|
|
578
|
+
const proxy = httpConnectProxyFor(url);
|
|
579
|
+
const res = proxy
|
|
580
|
+
? await postViaConnectProxy(proxy, url, { headers: reqHeaders, body: reqBody, timeout })
|
|
581
|
+
: await fetch(url, { method: 'POST', headers: reqHeaders, body: reqBody, signal: controller.signal });
|
|
507
582
|
|
|
508
583
|
if (!res.ok) {
|
|
509
584
|
debugLog('WARN', `${tier}-openrouter`, `HTTP ${res.status}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-mem-lite",
|
|
3
|
-
"version": "3.3.
|
|
3
|
+
"version": "3.3.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",
|