squeezr-ai 1.16.0 → 1.16.2
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/README.md +5 -3
- package/bin/squeezr.js +76 -16
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
**Token compression proxy for AI coding CLIs.** Sits between your CLI and the API, compresses context on the fly, saves thousands of tokens per session.
|
|
4
4
|
|
|
5
|
-
[](https://www.npmjs.com/package/squeezr-ai) [](LICENSE) [](https://www.npmjs.com/package/squeezr-ai) [](LICENSE) []()
|
|
6
6
|
|
|
7
7
|
## Supported CLIs
|
|
8
8
|
|
|
@@ -24,7 +24,7 @@ squeezr start
|
|
|
24
24
|
```
|
|
25
25
|
|
|
26
26
|
`squeezr setup` handles everything automatically:
|
|
27
|
-
- Sets `ANTHROPIC_BASE_URL`, `GEMINI_API_BASE_URL`, `HTTPS_PROXY`, `NODE_EXTRA_CA_CERTS
|
|
27
|
+
- Sets `ANTHROPIC_BASE_URL`, `GEMINI_API_BASE_URL`, `HTTPS_PROXY`, `NODE_EXTRA_CA_CERTS`
|
|
28
28
|
- Registers auto-start (launchd on macOS, systemd on Linux, Task Scheduler/NSSM on Windows)
|
|
29
29
|
- **Windows:** imports the MITM CA into the Windows Certificate Store (user-level, no admin required) so Rust-based CLIs like Codex trust the proxy's TLS certificates
|
|
30
30
|
- **macOS/Linux:** generates a CA bundle at `~/.squeezr/mitm-ca/bundle.crt` for `SSL_CERT_FILE`
|
|
@@ -92,6 +92,8 @@ Compression aggressiveness scales with context window usage:
|
|
|
92
92
|
|
|
93
93
|
Codex uses WebSocket over TLS to `chatgpt.com` with OAuth authentication — it cannot be proxied via `OPENAI_BASE_URL`. Squeezr runs a TLS-terminating MITM proxy on port 8081 that intercepts and compresses WebSocket frames. See [CODEX.md](CODEX.md) for the full technical breakdown.
|
|
94
94
|
|
|
95
|
+
The MITM proxy **only intercepts `chatgpt.com`** traffic. All other HTTPS requests (npm, git, curl, etc.) pass through as a transparent TCP tunnel — no certificate needed, no interference.
|
|
96
|
+
|
|
95
97
|
## Configuration
|
|
96
98
|
|
|
97
99
|
### Global config: `squeezr.toml` (next to the binary)
|
|
@@ -169,7 +171,7 @@ Squeezr uses cheap/free models for AI compression (the deterministic layer is pu
|
|
|
169
171
|
|
|
170
172
|
```bash
|
|
171
173
|
squeezr setup # configure env vars, auto-start, CA trust
|
|
172
|
-
squeezr start # start the proxy (
|
|
174
|
+
squeezr start # start the proxy (auto-restarts if version mismatch after update)
|
|
173
175
|
squeezr stop # stop the proxy
|
|
174
176
|
squeezr status # check if proxy is running
|
|
175
177
|
squeezr logs # show last 50 log lines
|
package/bin/squeezr.js
CHANGED
|
@@ -16,6 +16,15 @@ 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 getPortFromToml() {
|
|
20
|
+
try {
|
|
21
|
+
const toml = fs.readFileSync(path.join(ROOT, 'squeezr.toml'), 'utf-8')
|
|
22
|
+
const m = toml.match(/^port\s*=\s*(\d+)/m)
|
|
23
|
+
if (m) return parseInt(m[1])
|
|
24
|
+
} catch {}
|
|
25
|
+
return null
|
|
26
|
+
}
|
|
27
|
+
|
|
19
28
|
function getMitmPort(port) {
|
|
20
29
|
const envMitm = process.env.SQUEEZR_MITM_PORT
|
|
21
30
|
if (envMitm) return parseInt(envMitm)
|
|
@@ -27,6 +36,10 @@ function getMitmPort(port) {
|
|
|
27
36
|
return Number(port) + 1
|
|
28
37
|
}
|
|
29
38
|
|
|
39
|
+
function getPort() {
|
|
40
|
+
return process.env.SQUEEZR_PORT || getPortFromToml() || 8080
|
|
41
|
+
}
|
|
42
|
+
|
|
30
43
|
const HELP = `
|
|
31
44
|
Squeezr v${pkg.version} — AI context compressor for Claude Code, Codex, Aider, Gemini CLI and Ollama
|
|
32
45
|
|
|
@@ -68,7 +81,7 @@ async function startDaemon() {
|
|
|
68
81
|
}
|
|
69
82
|
|
|
70
83
|
// Check if already running — and if the version matches
|
|
71
|
-
const port =
|
|
84
|
+
const port = getPort()
|
|
72
85
|
const runningVersion = await new Promise(resolve => {
|
|
73
86
|
const req = http.get(`http://localhost:${port}/squeezr/health`, res => {
|
|
74
87
|
let data = ''
|
|
@@ -134,7 +147,7 @@ function showLogs() {
|
|
|
134
147
|
}
|
|
135
148
|
|
|
136
149
|
function stopProxy() {
|
|
137
|
-
const port =
|
|
150
|
+
const port = getPort()
|
|
138
151
|
const mitmPort = getMitmPort(port)
|
|
139
152
|
const ports = [port, mitmPort]
|
|
140
153
|
let killed = false
|
|
@@ -164,19 +177,22 @@ function stopProxy() {
|
|
|
164
177
|
} else {
|
|
165
178
|
execSync(`kill -9 ${pid}`, { stdio: 'pipe' })
|
|
166
179
|
}
|
|
167
|
-
console.log(`Squeezr stopped (pid ${pid} on port ${p})`)
|
|
168
180
|
killed = true
|
|
169
181
|
} catch {}
|
|
170
182
|
}
|
|
171
183
|
} catch {}
|
|
172
184
|
}
|
|
173
|
-
if (
|
|
174
|
-
console.log(`Squeezr
|
|
185
|
+
if (killed) {
|
|
186
|
+
console.log(`Squeezr stopped`)
|
|
187
|
+
console.log(` HTTP proxy (Claude/Aider/Gemini): http://localhost:${port}`)
|
|
188
|
+
console.log(` MITM proxy (Codex): http://localhost:${mitmPort}`)
|
|
189
|
+
} else {
|
|
190
|
+
console.log(`Squeezr is not running`)
|
|
175
191
|
}
|
|
176
192
|
}
|
|
177
193
|
|
|
178
194
|
async function checkStatus() {
|
|
179
|
-
const port =
|
|
195
|
+
const port = getPort()
|
|
180
196
|
const mitmPort = getMitmPort(port)
|
|
181
197
|
return new Promise(resolve => {
|
|
182
198
|
const req = http.get(`http://localhost:${port}/squeezr/health`, res => {
|
|
@@ -281,15 +297,59 @@ async function configurePorts() {
|
|
|
281
297
|
try { execSync(`setx HTTPS_PROXY "http://localhost:${finalMitm}"`, { stdio: 'pipe' }) } catch {}
|
|
282
298
|
console.log('Environment variables updated. Restart your terminal for changes to take effect.')
|
|
283
299
|
} else {
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
300
|
+
// Update shell profiles directly
|
|
301
|
+
const profiles = [
|
|
302
|
+
path.join(os.homedir(), '.zshrc'),
|
|
303
|
+
path.join(os.homedir(), '.bashrc'),
|
|
304
|
+
path.join(os.homedir(), '.bash_profile'),
|
|
305
|
+
]
|
|
306
|
+
const envBlock = [
|
|
307
|
+
`export SQUEEZR_PORT=${finalPort}`,
|
|
308
|
+
`export SQUEEZR_MITM_PORT=${finalMitm}`,
|
|
309
|
+
`export ANTHROPIC_BASE_URL=http://localhost:${finalPort}`,
|
|
310
|
+
`export GEMINI_API_BASE_URL=http://localhost:${finalPort}`,
|
|
311
|
+
`export HTTPS_PROXY=http://localhost:${finalMitm}`,
|
|
312
|
+
].join('\n')
|
|
313
|
+
for (const p of profiles) {
|
|
314
|
+
try {
|
|
315
|
+
let content = fs.readFileSync(p, 'utf-8')
|
|
316
|
+
if (content.includes('# squeezr env vars')) {
|
|
317
|
+
// Replace existing block (from marker to the closing fi)
|
|
318
|
+
content = content.replace(
|
|
319
|
+
/# squeezr env vars[\s\S]*?fi/,
|
|
320
|
+
`# squeezr env vars\n${envBlock}\n# squeezr auto-heal\nif ! curl -sf http://localhost:${finalPort}/squeezr/health > /dev/null 2>&1; then squeezr start > /dev/null 2>&1; fi`
|
|
321
|
+
)
|
|
322
|
+
fs.writeFileSync(p, content)
|
|
323
|
+
console.log(` [ok] Updated ${p}`)
|
|
324
|
+
}
|
|
325
|
+
} catch {}
|
|
326
|
+
}
|
|
327
|
+
// Also update env for WSL setx if on WSL
|
|
328
|
+
try {
|
|
329
|
+
const procVersion = fs.readFileSync('/proc/version', 'utf-8')
|
|
330
|
+
if (/microsoft|wsl/i.test(procVersion)) {
|
|
331
|
+
const setx = '/mnt/c/Windows/System32/setx.exe'
|
|
332
|
+
try { execSync(`"${setx}" SQUEEZR_PORT "${finalPort}"`, { stdio: 'pipe' }) } catch {}
|
|
333
|
+
try { execSync(`"${setx}" SQUEEZR_MITM_PORT "${finalMitm}"`, { stdio: 'pipe' }) } catch {}
|
|
334
|
+
try { execSync(`"${setx}" ANTHROPIC_BASE_URL "http://localhost:${finalPort}"`, { stdio: 'pipe' }) } catch {}
|
|
335
|
+
try { execSync(`"${setx}" GEMINI_API_BASE_URL "http://localhost:${finalPort}"`, { stdio: 'pipe' }) } catch {}
|
|
336
|
+
try { execSync(`"${setx}" HTTPS_PROXY "http://localhost:${finalMitm}"`, { stdio: 'pipe' }) } catch {}
|
|
337
|
+
}
|
|
338
|
+
} catch {}
|
|
289
339
|
}
|
|
290
340
|
|
|
291
|
-
|
|
292
|
-
|
|
341
|
+
// Apply to current process so stop/start works immediately
|
|
342
|
+
process.env.SQUEEZR_PORT = String(finalPort)
|
|
343
|
+
process.env.SQUEEZR_MITM_PORT = String(finalMitm)
|
|
344
|
+
process.env.ANTHROPIC_BASE_URL = `http://localhost:${finalPort}`
|
|
345
|
+
process.env.HTTPS_PROXY = `http://localhost:${finalMitm}`
|
|
346
|
+
|
|
347
|
+
// Auto stop + start
|
|
348
|
+
console.log('')
|
|
349
|
+
stopProxy()
|
|
350
|
+
await new Promise(r => setTimeout(r, 1500))
|
|
351
|
+
await startDaemon()
|
|
352
|
+
console.log(`\nOpen a new terminal for env vars to apply to other tools.`)
|
|
293
353
|
}
|
|
294
354
|
|
|
295
355
|
// ── squeezr uninstall ─────────────────────────────────────────────────────────
|
|
@@ -390,7 +450,7 @@ function setupWindows() {
|
|
|
390
450
|
console.log('Setting up Squeezr for Windows...\n')
|
|
391
451
|
|
|
392
452
|
// 1. Set env vars permanently via setx (user scope, no admin needed)
|
|
393
|
-
const port =
|
|
453
|
+
const port = getPort()
|
|
394
454
|
const mitmPort = getMitmPort(port)
|
|
395
455
|
const caPath = path.join(os.homedir(), '.squeezr', 'mitm-ca', 'ca.crt')
|
|
396
456
|
const vars = {
|
|
@@ -545,7 +605,7 @@ function setupUnix() {
|
|
|
545
605
|
|
|
546
606
|
// 1. Set env vars + auto-heal guard in shell profile
|
|
547
607
|
const distIndex = path.join(ROOT, 'dist', 'index.js')
|
|
548
|
-
const port =
|
|
608
|
+
const port = getPort()
|
|
549
609
|
const mitmPort = getMitmPort(port)
|
|
550
610
|
const bundlePath = path.join(os.homedir(), '.squeezr', 'mitm-ca', 'bundle.crt')
|
|
551
611
|
const shellBlock = [
|
|
@@ -678,7 +738,7 @@ function setupWSL() {
|
|
|
678
738
|
// The guard checks if the proxy is alive on terminal open. If not, it starts
|
|
679
739
|
// it in the background. This is the safety net for WSL2 where systemd and
|
|
680
740
|
// Task Scheduler may both fail.
|
|
681
|
-
const port =
|
|
741
|
+
const port = getPort()
|
|
682
742
|
const mitmPort = getMitmPort(port)
|
|
683
743
|
const bundlePath = path.join(os.homedir(), '.squeezr', 'mitm-ca', 'bundle.crt')
|
|
684
744
|
const shellBlock = [
|
package/package.json
CHANGED