squeezr-ai 1.14.0 → 1.14.4

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/bin/squeezr.js CHANGED
@@ -190,10 +190,16 @@ function setupWindows() {
190
190
  console.log('Setting up Squeezr for Windows...\n')
191
191
 
192
192
  // 1. Set env vars permanently via setx (user scope, no admin needed)
193
+ const port = process.env.SQUEEZR_PORT || 8080
194
+ const mitmPort = Number(port) + 1
195
+ const caPath = path.join(os.homedir(), '.squeezr', 'mitm-ca', 'ca.crt')
193
196
  const vars = {
194
- ANTHROPIC_BASE_URL: 'http://localhost:8080',
195
- openai_base_url: 'http://localhost:8080',
196
- GEMINI_API_BASE_URL: 'http://localhost:8080',
197
+ ANTHROPIC_BASE_URL: `http://localhost:${port}`,
198
+ openai_base_url: `http://localhost:${port}`,
199
+ GEMINI_API_BASE_URL: `http://localhost:${port}`,
200
+ HTTPS_PROXY: `http://localhost:${mitmPort}`,
201
+ // Node.js does NOT use the Windows Certificate Store — this makes Codex (Node.js) trust the MITM CA
202
+ NODE_EXTRA_CA_CERTS: caPath,
197
203
  }
198
204
  for (const [key, value] of Object.entries(vars)) {
199
205
  try {
@@ -277,18 +283,49 @@ function setupWindows() {
277
283
  console.log(` [ok] Squeezr started in background (pid ${child.pid})`)
278
284
  console.log(` [ok] Logs → ${logFile}`)
279
285
 
280
- console.log(`
286
+ // 4. Trust MITM CA in Windows Certificate Store (for native apps like browsers)
287
+ // Node.js apps (Codex) use NODE_EXTRA_CA_CERTS set above instead.
288
+ // The CA is generated on first proxy start — wait briefly for it to appear
289
+ const waitForCa = (retries = 10, interval = 500) => new Promise(resolve => {
290
+ const check = (n) => {
291
+ if (fs.existsSync(caPath)) return resolve(true)
292
+ if (n <= 0) return resolve(false)
293
+ setTimeout(() => check(n - 1), interval)
294
+ }
295
+ check(retries)
296
+ })
297
+
298
+ waitForCa().then(found => {
299
+ if (!found) {
300
+ console.log(` [warn] MITM CA not found yet — run 'squeezr setup' again after first start`)
301
+ printDone()
302
+ return
303
+ }
304
+ try {
305
+ execSync(`certutil -addstore -f Root "${caPath}"`, { stdio: 'pipe' })
306
+ console.log(` [ok] MITM CA trusted in Windows Certificate Store (Codex TLS interception ready)`)
307
+ } catch {
308
+ console.log(` [warn] Could not trust MITM CA — run as Administrator or trust manually:`)
309
+ console.log(` certutil -addstore -f Root "${caPath}"`)
310
+ }
311
+ printDone()
312
+ })
313
+
314
+ function printDone() {
315
+ console.log(`
281
316
  Done!
282
317
 
283
- Squeezr is running on http://localhost:8080
318
+ Squeezr is running on http://localhost:${port}
319
+ MITM proxy on http://localhost:${mitmPort} (Codex TLS interception)
284
320
  All CLIs (Claude Code, Codex, Aider, Gemini, Ollama) are configured.
285
321
 
286
- Restart your terminal and Claude Code once for the env vars to take effect.
322
+ Restart your terminal once for the env vars to take effect.
287
323
  After that, everything is automatic — Squeezr starts silently on every login.
288
324
 
289
325
  squeezr status — check it's running
290
326
  squeezr gain — see token savings
291
327
  `)
328
+ }
292
329
  }
293
330
 
294
331
  function setupUnix() {
@@ -25,7 +25,9 @@ async function compressWithHaiku(text, apiKey) {
25
25
  // The Anthropic SDK accepts both: apiKey → x-api-key header,
26
26
  // authToken → Authorization: Bearer header.
27
27
  const authOpts = apiKey.startsWith('sk-') ? { apiKey } : { authToken: apiKey };
28
- const client = new Anthropic(authOpts);
28
+ // Force real API URL — ANTHROPIC_BASE_URL points to this proxy, which would cause
29
+ // infinite recursion if we let the SDK inherit it from the environment.
30
+ const client = new Anthropic({ ...authOpts, baseURL: 'https://api.anthropic.com' });
29
31
  const resp = await client.messages.create({
30
32
  model: 'claude-haiku-4-5-20251001',
31
33
  max_tokens: 300,
package/dist/server.js CHANGED
@@ -1,3 +1,6 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { homedir } from 'node:os';
1
4
  import { Hono } from 'hono';
2
5
  import { stream } from 'hono/streaming';
3
6
  import { config } from './config.js';
@@ -13,6 +16,15 @@ const ANTHROPIC_API = 'https://api.anthropic.com';
13
16
  const OPENAI_API = 'https://api.openai.com';
14
17
  const GOOGLE_API = 'https://generativelanguage.googleapis.com';
15
18
  const SKIP_REQ_HEADERS = new Set(['host', 'content-length', 'transfer-encoding', 'connection']);
19
+ function readCodexToken() {
20
+ try {
21
+ const d = JSON.parse(readFileSync(join(homedir(), '.codex', 'auth.json'), 'utf-8'));
22
+ return d?.tokens?.access_token ?? null;
23
+ }
24
+ catch {
25
+ return null;
26
+ }
27
+ }
16
28
  const SKIP_RESP_HEADERS = new Set(['content-encoding', 'transfer-encoding', 'connection', 'content-length']);
17
29
  export const stats = new Stats();
18
30
  function forwardHeaders(headers) {
@@ -245,13 +257,23 @@ app.post('/oauth/token', async (c) => {
245
257
  });
246
258
  // ── Catch-all ─────────────────────────────────────────────────────────────────
247
259
  app.all('*', async (c) => {
248
- const upstream = detectUpstream(c.req.raw.headers);
260
+ let upstream = detectUpstream(c.req.raw.headers);
249
261
  const url = new URL(c.req.url);
250
- const NEEDS_V1 = new Set(['/models', '/engines', '/files', '/embeddings', '/moderations', '/completions', '/edits']);
262
+ const NEEDS_V1 = new Set(['/models', '/engines', '/files', '/embeddings', '/moderations', '/completions', '/edits', '/responses']);
251
263
  const pathname = NEEDS_V1.has(url.pathname) ? `/v1${url.pathname}` : url.pathname;
264
+ // /responses is exclusively an OpenAI Codex endpoint — override upstream regardless
265
+ // of what detectUpstream inferred from headers (Codex sends no auth to custom base URLs).
266
+ if (pathname === '/v1/responses')
267
+ upstream = OPENAI_API;
252
268
  const targetUrl = `${upstream}${pathname}${url.search}`;
253
269
  const body = await c.req.arrayBuffer();
254
270
  const fwdHeaders = forwardHeaders(c.req.raw.headers);
271
+ // Inject Codex OAuth token from ~/.codex/auth.json when no auth header present.
272
+ if (upstream === OPENAI_API && !fwdHeaders['authorization']) {
273
+ const codexToken = readCodexToken();
274
+ if (codexToken)
275
+ fwdHeaders['authorization'] = `Bearer ${codexToken}`;
276
+ }
255
277
  const resp = await fetch(targetUrl, {
256
278
  method: c.req.method,
257
279
  headers: fwdHeaders,
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const VERSION = "1.14.0";
1
+ export declare const VERSION = "1.14.4";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const VERSION = '1.14.0';
1
+ export const VERSION = '1.14.4';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "squeezr-ai",
3
- "version": "1.14.0",
3
+ "version": "1.14.4",
4
4
  "description": "AI proxy that compresses Claude Code, Codex, Aider, Gemini CLI and Ollama context windows to save thousands of tokens per session",
5
5
  "keywords": [
6
6
  "claude",