squeezr-ai 1.14.13 → 1.15.0

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
@@ -16,6 +16,17 @@ const pkg = require(path.join(ROOT, 'package.json'))
16
16
  const args = process.argv.slice(2)
17
17
  const command = args[0]
18
18
 
19
+ function getMitmPort(port) {
20
+ const envMitm = process.env.SQUEEZR_MITM_PORT
21
+ if (envMitm) return parseInt(envMitm)
22
+ try {
23
+ const toml = fs.readFileSync(path.join(ROOT, 'squeezr.toml'), 'utf-8')
24
+ const m = toml.match(/^mitm_port\s*=\s*(\d+)/m)
25
+ if (m) return parseInt(m[1])
26
+ } catch {}
27
+ return Number(port) + 1
28
+ }
29
+
19
30
  const HELP = `
20
31
  Squeezr v${pkg.version} — AI context compressor for Claude Code, Codex, Aider, Gemini CLI and Ollama
21
32
 
@@ -30,6 +41,7 @@ Usage:
30
41
  squeezr discover Show pattern coverage report (proxy must be running)
31
42
  squeezr status Check if proxy is running
32
43
  squeezr config Print config file path and current settings
44
+ squeezr ports Change HTTP and MITM proxy ports
33
45
  squeezr version Print version
34
46
  squeezr help Show this help
35
47
  `
@@ -65,7 +77,10 @@ async function startDaemon() {
65
77
  req.setTimeout(2000, () => { req.destroy(); resolve(false) })
66
78
  })
67
79
  if (running) {
68
- console.log(`Squeezr is already running on port ${port}`)
80
+ const mitmPort = getMitmPort(port)
81
+ console.log(`Squeezr is already running`)
82
+ console.log(` HTTP proxy (Claude/Aider/Gemini): http://localhost:${port}`)
83
+ console.log(` MITM proxy (Codex): http://localhost:${mitmPort}`)
69
84
  return
70
85
  }
71
86
 
@@ -83,8 +98,11 @@ async function startDaemon() {
83
98
  })
84
99
  child.unref()
85
100
  fs.closeSync(logFd)
86
- console.log(`Squeezr started in background (pid ${child.pid})`)
87
- console.log(`Logs ${logFile}`)
101
+ const mitmPort = getMitmPort(port)
102
+ console.log(`Squeezr started (pid ${child.pid})`)
103
+ console.log(` HTTP proxy (Claude/Aider/Gemini): http://localhost:${port}`)
104
+ console.log(` MITM proxy (Codex): http://localhost:${mitmPort}`)
105
+ console.log(` Logs: ${logFile}`)
88
106
  }
89
107
 
90
108
  function showLogs() {
@@ -106,7 +124,7 @@ function showLogs() {
106
124
 
107
125
  function stopProxy() {
108
126
  const port = process.env.SQUEEZR_PORT || 8080
109
- const mitmPort = Number(port) + 1
127
+ const mitmPort = getMitmPort(port)
110
128
  const ports = [port, mitmPort]
111
129
  let killed = false
112
130
 
@@ -148,7 +166,7 @@ function stopProxy() {
148
166
 
149
167
  async function checkStatus() {
150
168
  const port = process.env.SQUEEZR_PORT || 8080
151
- const mitmPort = Number(port) + 1
169
+ const mitmPort = getMitmPort(port)
152
170
  return new Promise(resolve => {
153
171
  const req = http.get(`http://localhost:${port}/squeezr/health`, res => {
154
172
  let data = ''
@@ -188,6 +206,81 @@ function showConfig() {
188
206
  }
189
207
  }
190
208
 
209
+ // ── squeezr ports ─────────────────────────────────────────────────────────────
210
+
211
+ async function configurePorts() {
212
+ const { createInterface } = await import('readline')
213
+ const tomlPath = path.join(ROOT, 'squeezr.toml')
214
+ let tomlContent = fs.existsSync(tomlPath) ? fs.readFileSync(tomlPath, 'utf-8') : ''
215
+
216
+ // Read current ports from toml
217
+ const portMatch = tomlContent.match(/^port\s*=\s*(\d+)/m)
218
+ const mitmMatch = tomlContent.match(/^mitm_port\s*=\s*(\d+)/m)
219
+ const currentPort = portMatch ? parseInt(portMatch[1]) : 8080
220
+ const currentMitm = mitmMatch ? parseInt(mitmMatch[1]) : currentPort + 1
221
+
222
+ const rl = createInterface({ input: process.stdin, output: process.stdout })
223
+ const ask = (q) => new Promise(resolve => rl.question(q, resolve))
224
+
225
+ console.log(`\nCurrent ports:`)
226
+ console.log(` HTTP proxy (Claude/Aider/Gemini): ${currentPort}`)
227
+ console.log(` MITM proxy (Codex): ${currentMitm}\n`)
228
+
229
+ const newPort = await ask(`HTTP proxy port [${currentPort}]: `)
230
+ const newMitm = await ask(`MITM proxy port [${currentMitm}]: `)
231
+ rl.close()
232
+
233
+ const finalPort = newPort.trim() ? parseInt(newPort.trim()) : currentPort
234
+ const finalMitm = newMitm.trim() ? parseInt(newMitm.trim()) : currentMitm
235
+
236
+ if (isNaN(finalPort) || isNaN(finalMitm) || finalPort < 1 || finalMitm < 1 || finalPort > 65535 || finalMitm > 65535) {
237
+ console.error('Invalid port number. Must be between 1 and 65535.')
238
+ process.exit(1)
239
+ }
240
+ if (finalPort === finalMitm) {
241
+ console.error('HTTP and MITM ports must be different.')
242
+ process.exit(1)
243
+ }
244
+
245
+ // Update toml
246
+ if (portMatch) {
247
+ tomlContent = tomlContent.replace(/^port\s*=\s*\d+/m, `port = ${finalPort}`)
248
+ } else if (tomlContent.includes('[proxy]')) {
249
+ tomlContent = tomlContent.replace('[proxy]', `[proxy]\nport = ${finalPort}`)
250
+ } else {
251
+ tomlContent = `[proxy]\nport = ${finalPort}\n` + tomlContent
252
+ }
253
+
254
+ if (mitmMatch) {
255
+ tomlContent = tomlContent.replace(/^mitm_port\s*=\s*\d+/m, `mitm_port = ${finalMitm}`)
256
+ } else {
257
+ // Add after port line
258
+ tomlContent = tomlContent.replace(/^(port\s*=\s*\d+)/m, `$1\nmitm_port = ${finalMitm}`)
259
+ }
260
+
261
+ fs.writeFileSync(tomlPath, tomlContent)
262
+ console.log(`\nSaved to ${tomlPath}`)
263
+
264
+ // Update env vars
265
+ if (process.platform === 'win32') {
266
+ try { execSync(`setx SQUEEZR_PORT "${finalPort}"`, { stdio: 'pipe' }) } catch {}
267
+ try { execSync(`setx SQUEEZR_MITM_PORT "${finalMitm}"`, { stdio: 'pipe' }) } catch {}
268
+ try { execSync(`setx ANTHROPIC_BASE_URL "http://localhost:${finalPort}"`, { stdio: 'pipe' }) } catch {}
269
+ try { execSync(`setx GEMINI_API_BASE_URL "http://localhost:${finalPort}"`, { stdio: 'pipe' }) } catch {}
270
+ try { execSync(`setx HTTPS_PROXY "http://localhost:${finalMitm}"`, { stdio: 'pipe' }) } catch {}
271
+ console.log('Environment variables updated. Restart your terminal for changes to take effect.')
272
+ } else {
273
+ console.log(`\nUpdate your shell profile:`)
274
+ console.log(` export SQUEEZR_PORT=${finalPort}`)
275
+ console.log(` export SQUEEZR_MITM_PORT=${finalMitm}`)
276
+ console.log(` export ANTHROPIC_BASE_URL=http://localhost:${finalPort}`)
277
+ console.log(` export HTTPS_PROXY=http://localhost:${finalMitm}`)
278
+ }
279
+
280
+ console.log(`\nRestart squeezr for changes to take effect:`)
281
+ console.log(` squeezr stop && squeezr start`)
282
+ }
283
+
191
284
  // ── squeezr setup ─────────────────────────────────────────────────────────────
192
285
 
193
286
  function setupWindows() {
@@ -199,7 +292,7 @@ function setupWindows() {
199
292
 
200
293
  // 1. Set env vars permanently via setx (user scope, no admin needed)
201
294
  const port = process.env.SQUEEZR_PORT || 8080
202
- const mitmPort = Number(port) + 1
295
+ const mitmPort = getMitmPort(port)
203
296
  const caPath = path.join(os.homedir(), '.squeezr', 'mitm-ca', 'ca.crt')
204
297
  const vars = {
205
298
  ANTHROPIC_BASE_URL: `http://localhost:${port}`,
@@ -354,7 +447,7 @@ function setupUnix() {
354
447
  // 1. Set env vars + auto-heal guard in shell profile
355
448
  const distIndex = path.join(ROOT, 'dist', 'index.js')
356
449
  const port = process.env.SQUEEZR_PORT || 8080
357
- const mitmPort = Number(port) + 1
450
+ const mitmPort = getMitmPort(port)
358
451
  const bundlePath = path.join(os.homedir(), '.squeezr', 'mitm-ca', 'bundle.crt')
359
452
  const shellBlock = [
360
453
  `# squeezr env vars`,
@@ -487,7 +580,7 @@ function setupWSL() {
487
580
  // it in the background. This is the safety net for WSL2 where systemd and
488
581
  // Task Scheduler may both fail.
489
582
  const port = process.env.SQUEEZR_PORT || 8080
490
- const mitmPort = Number(port) + 1
583
+ const mitmPort = getMitmPort(port)
491
584
  const bundlePath = path.join(os.homedir(), '.squeezr', 'mitm-ca', 'bundle.crt')
492
585
  const shellBlock = [
493
586
  `# squeezr env vars`,
@@ -668,6 +761,9 @@ switch (command) {
668
761
  checkStatus()
669
762
  break
670
763
 
764
+ case 'ports':
765
+ await configurePorts()
766
+ break
671
767
  case 'config':
672
768
  showConfig()
673
769
  break
package/dist/codexMitm.js CHANGED
@@ -13,7 +13,7 @@ const CA_DIR = join(homedir(), '.squeezr', 'mitm-ca');
13
13
  const CA_KEY_PATH = join(CA_DIR, 'ca.key');
14
14
  const CA_CERT_PATH = join(CA_DIR, 'ca.crt');
15
15
  export const BUNDLE_PATH = join(CA_DIR, 'bundle.crt');
16
- export const MITM_PORT = (config.port ?? 8080) + 1;
16
+ export const MITM_PORT = config.mitmPort;
17
17
  // ── CA generation ─────────────────────────────────────────────────────────────
18
18
  function ensureCA() {
19
19
  if (fs.existsSync(CA_KEY_PATH) && fs.existsSync(CA_CERT_PATH))
package/dist/config.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export declare class Config {
2
2
  readonly port: number;
3
+ readonly mitmPort: number;
3
4
  readonly threshold: number;
4
5
  readonly keepRecent: number;
5
6
  readonly disabled: boolean;
package/dist/config.js CHANGED
@@ -40,6 +40,7 @@ function env(key, fallback) {
40
40
  }
41
41
  export class Config {
42
42
  port;
43
+ mitmPort;
43
44
  threshold;
44
45
  keepRecent;
45
46
  disabled;
@@ -67,6 +68,7 @@ export class Config {
67
68
  const ad = t.adaptive ?? {};
68
69
  const lo = t.local ?? {};
69
70
  this.port = parseInt(env('SQUEEZR_PORT', String(p.port ?? 8080)));
71
+ this.mitmPort = parseInt(env('SQUEEZR_MITM_PORT', String(p.mitm_port ?? this.port + 1)));
70
72
  this.threshold = parseInt(env('SQUEEZR_THRESHOLD', String(c.threshold ?? 800)));
71
73
  this.keepRecent = parseInt(env('SQUEEZR_KEEP_RECENT', String(c.keep_recent ?? 3)));
72
74
  this.disabled = env('SQUEEZR_DISABLED', String(c.disabled ?? false)) === '1' || env('SQUEEZR_DISABLED', '') === 'true';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "squeezr-ai",
3
- "version": "1.14.13",
3
+ "version": "1.15.0",
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",