squeezr-ai 1.10.2 → 1.10.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/README.md +22 -0
- package/bin/squeezr.js +50 -11
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -422,6 +422,28 @@ Typical 2-hour session (50+ tool calls): ~200K tokens without compression → ~8
|
|
|
422
422
|
|
|
423
423
|
---
|
|
424
424
|
|
|
425
|
+
## Does it add latency?
|
|
426
|
+
|
|
427
|
+
Barely — and in long sessions it makes things faster, not slower.
|
|
428
|
+
|
|
429
|
+
**What Squeezr adds:**
|
|
430
|
+
- Deterministic patterns (git, cargo, vitest, etc.) run in pure Node.js — microseconds, unnoticeable
|
|
431
|
+
- AI compression (Haiku/GPT-4o-mini) adds ~200-400ms **but only once per block**, then cached forever. Every subsequent request that includes that block pays zero
|
|
432
|
+
|
|
433
|
+
**Why it feels faster overall:**
|
|
434
|
+
|
|
435
|
+
The time Squeezr takes to compress a block is parallel to the time you spend reading the previous response and typing the next message. By the time you send your next message, compression is already done.
|
|
436
|
+
|
|
437
|
+
More importantly: sending 60-80% fewer tokens means Claude processes a smaller context and **responds faster** — especially noticeable from turn 10 onward when history accumulates.
|
|
438
|
+
|
|
439
|
+
| | Without Squeezr | With Squeezr |
|
|
440
|
+
|---|---|---|
|
|
441
|
+
| Turn 1-3 | Fast | +200ms first compression (then cached) |
|
|
442
|
+
| Turn 10+ | Getting slower | Stays fast — history is compressed |
|
|
443
|
+
| Turn 30+ | Noticeably slow | Faster than turn 1 without Squeezr |
|
|
444
|
+
|
|
445
|
+
---
|
|
446
|
+
|
|
425
447
|
## Why not just use /compact?
|
|
426
448
|
|
|
427
449
|
`/compact` is a nuclear option: it replaces your entire context with a single lossy summary. You lose granularity and can't go back. Squeezr is surgical — it compresses old, irrelevant content while keeping recent work at full fidelity, with lossless retrieval via `squeezr_expand` for anything that needs to be recovered.
|
package/bin/squeezr.js
CHANGED
|
@@ -23,6 +23,7 @@ Usage:
|
|
|
23
23
|
squeezr Start the proxy (default)
|
|
24
24
|
squeezr start Start the proxy
|
|
25
25
|
squeezr setup One-time setup: auto-start on login + configure all CLIs
|
|
26
|
+
squeezr stop Stop the running proxy
|
|
26
27
|
squeezr gain Show token savings stats
|
|
27
28
|
squeezr gain --reset Reset saved stats
|
|
28
29
|
squeezr discover Show pattern coverage report (proxy must be running)
|
|
@@ -45,6 +46,32 @@ function runNode(script, extraArgs = []) {
|
|
|
45
46
|
child.on('exit', code => process.exit(code ?? 0))
|
|
46
47
|
}
|
|
47
48
|
|
|
49
|
+
function stopProxy() {
|
|
50
|
+
const port = process.env.SQUEEZR_PORT || 8080
|
|
51
|
+
try {
|
|
52
|
+
let pid
|
|
53
|
+
if (process.platform === 'win32') {
|
|
54
|
+
const out = execSync(`netstat -ano | findstr ":${port} "`, { encoding: 'utf-8', stdio: 'pipe' })
|
|
55
|
+
const match = out.match(/LISTENING\s+(\d+)/)
|
|
56
|
+
pid = match?.[1]
|
|
57
|
+
} else {
|
|
58
|
+
pid = execSync(`lsof -ti :${port}`, { encoding: 'utf-8', stdio: 'pipe' }).trim()
|
|
59
|
+
}
|
|
60
|
+
if (!pid) {
|
|
61
|
+
console.log(`Squeezr is not running on port ${port}`)
|
|
62
|
+
return
|
|
63
|
+
}
|
|
64
|
+
if (process.platform === 'win32') {
|
|
65
|
+
execSync(`taskkill /F /PID ${pid}`, { stdio: 'pipe' })
|
|
66
|
+
} else {
|
|
67
|
+
execSync(`kill ${pid}`, { stdio: 'pipe' })
|
|
68
|
+
}
|
|
69
|
+
console.log(`Squeezr stopped (pid ${pid})`)
|
|
70
|
+
} catch {
|
|
71
|
+
console.log(`Squeezr is not running on port ${port}`)
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
48
75
|
async function checkStatus() {
|
|
49
76
|
const port = process.env.SQUEEZR_PORT || 8080
|
|
50
77
|
return new Promise(resolve => {
|
|
@@ -89,6 +116,7 @@ function showConfig() {
|
|
|
89
116
|
function setupWindows() {
|
|
90
117
|
const squeezrBin = process.argv[1]
|
|
91
118
|
const nodeExe = process.execPath
|
|
119
|
+
const distIndex = path.join(ROOT, 'dist', 'index.js')
|
|
92
120
|
|
|
93
121
|
console.log('Setting up Squeezr for Windows...\n')
|
|
94
122
|
|
|
@@ -107,29 +135,36 @@ function setupWindows() {
|
|
|
107
135
|
}
|
|
108
136
|
}
|
|
109
137
|
|
|
110
|
-
// 2. Register Task Scheduler
|
|
138
|
+
// 2. Register Task Scheduler with hidden window so no console pops up on login.
|
|
139
|
+
// The action runs: powershell -WindowStyle Hidden -Command "node dist/index.js"
|
|
111
140
|
const taskName = 'Squeezr'
|
|
141
|
+
const nodeArg = `${nodeExe} \`"${distIndex}\`"`
|
|
112
142
|
const ps = [
|
|
113
143
|
`$e = Get-ScheduledTask -TaskName '${taskName}' -ErrorAction SilentlyContinue`,
|
|
114
144
|
`if ($e) { Unregister-ScheduledTask -TaskName '${taskName}' -Confirm:$false }`,
|
|
115
|
-
`$a = New-ScheduledTaskAction -Execute '
|
|
145
|
+
`$a = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument '-WindowStyle Hidden -NonInteractive -Command "${nodeArg}"' -WorkingDirectory '${ROOT}'`,
|
|
116
146
|
`$t = New-ScheduledTaskTrigger -AtLogon`,
|
|
117
147
|
`$s = New-ScheduledTaskSettingsSet -ExecutionTimeLimit 0 -RestartCount 5 -RestartInterval (New-TimeSpan -Minutes 1)`,
|
|
118
148
|
`Register-ScheduledTask -TaskName '${taskName}' -Action $a -Trigger $t -Settings $s -RunLevel Highest -Force | Out-Null`,
|
|
119
|
-
`Start-ScheduledTask -TaskName '${taskName}'`,
|
|
120
149
|
].join('; ')
|
|
121
150
|
|
|
122
151
|
try {
|
|
123
152
|
execSync(`powershell -NoProfile -Command "${ps}"`, { stdio: 'pipe' })
|
|
124
|
-
console.log(` [ok] Auto-start registered in Task Scheduler`)
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
console.log(` [warn] Task Scheduler failed (try running as admin)`)
|
|
128
|
-
console.log(` Starting Squeezr in background instead...`)
|
|
129
|
-
spawn(nodeExe, [squeezrBin], { detached: true, stdio: 'ignore' }).unref()
|
|
130
|
-
console.log(` [ok] Squeezr started`)
|
|
153
|
+
console.log(` [ok] Auto-start registered in Task Scheduler (hidden, starts on login)`)
|
|
154
|
+
} catch {
|
|
155
|
+
console.log(` [warn] Task Scheduler failed — run as admin for auto-start on login`)
|
|
131
156
|
}
|
|
132
157
|
|
|
158
|
+
// 3. Start Squeezr right now as a detached background process (no window)
|
|
159
|
+
const child = spawn(nodeExe, [distIndex], {
|
|
160
|
+
detached: true,
|
|
161
|
+
stdio: 'ignore',
|
|
162
|
+
windowsHide: true,
|
|
163
|
+
cwd: ROOT,
|
|
164
|
+
})
|
|
165
|
+
child.unref()
|
|
166
|
+
console.log(` [ok] Squeezr started in background (pid ${child.pid})`)
|
|
167
|
+
|
|
133
168
|
console.log(`
|
|
134
169
|
Done!
|
|
135
170
|
|
|
@@ -137,7 +172,7 @@ Done!
|
|
|
137
172
|
All CLIs (Claude Code, Codex, Aider, Gemini, Ollama) are configured.
|
|
138
173
|
|
|
139
174
|
Restart your terminal and Claude Code once for the env vars to take effect.
|
|
140
|
-
After that, everything is automatic.
|
|
175
|
+
After that, everything is automatic — Squeezr starts silently on every login.
|
|
141
176
|
|
|
142
177
|
squeezr status — check it's running
|
|
143
178
|
squeezr gain — see token savings
|
|
@@ -253,6 +288,10 @@ switch (command) {
|
|
|
253
288
|
else setupUnix()
|
|
254
289
|
break
|
|
255
290
|
|
|
291
|
+
case 'stop':
|
|
292
|
+
stopProxy()
|
|
293
|
+
break
|
|
294
|
+
|
|
256
295
|
case 'gain':
|
|
257
296
|
runNode('gain.js', args.slice(1))
|
|
258
297
|
break
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "1.10.
|
|
1
|
+
export declare const VERSION = "1.10.4";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = '1.10.
|
|
1
|
+
export const VERSION = '1.10.4';
|
package/package.json
CHANGED