squeezr-ai 1.16.2 → 1.16.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 +1 -0
- package/bin/squeezr.js +90 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -172,6 +172,7 @@ Squeezr uses cheap/free models for AI compression (the deterministic layer is pu
|
|
|
172
172
|
```bash
|
|
173
173
|
squeezr setup # configure env vars, auto-start, CA trust
|
|
174
174
|
squeezr start # start the proxy (auto-restarts if version mismatch after update)
|
|
175
|
+
squeezr update # kill old processes, install latest from npm, restart
|
|
175
176
|
squeezr stop # stop the proxy
|
|
176
177
|
squeezr status # check if proxy is running
|
|
177
178
|
squeezr logs # show last 50 log lines
|
package/bin/squeezr.js
CHANGED
|
@@ -16,6 +16,55 @@ 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
|
+
// ── update check (non-blocking) ───────────────────────────────────────────────
|
|
20
|
+
|
|
21
|
+
const UPDATE_CHECK_FILE = path.join(os.homedir(), '.squeezr', 'update-check.json')
|
|
22
|
+
const UPDATE_CHECK_INTERVAL = 4 * 60 * 60 * 1000 // 4 hours
|
|
23
|
+
|
|
24
|
+
// Fire and forget — runs in background, never blocks CLI
|
|
25
|
+
const updateCheckPromise = (async () => {
|
|
26
|
+
try {
|
|
27
|
+
// Read cached check
|
|
28
|
+
let cached = null
|
|
29
|
+
try { cached = JSON.parse(fs.readFileSync(UPDATE_CHECK_FILE, 'utf-8')) } catch {}
|
|
30
|
+
if (cached && Date.now() - cached.checkedAt < UPDATE_CHECK_INTERVAL) {
|
|
31
|
+
return cached.latest !== pkg.version ? cached.latest : null
|
|
32
|
+
}
|
|
33
|
+
// Fetch latest from npm (with timeout)
|
|
34
|
+
const { get } = await import('https')
|
|
35
|
+
const latest = await new Promise((resolve, reject) => {
|
|
36
|
+
const req = get('https://registry.npmjs.org/squeezr-ai/latest', { timeout: 3000 }, res => {
|
|
37
|
+
let data = ''
|
|
38
|
+
res.on('data', chunk => { data += chunk })
|
|
39
|
+
res.on('end', () => {
|
|
40
|
+
try { resolve(JSON.parse(data).version) } catch { resolve(null) }
|
|
41
|
+
})
|
|
42
|
+
})
|
|
43
|
+
req.on('error', () => resolve(null))
|
|
44
|
+
req.setTimeout(3000, () => { req.destroy(); resolve(null) })
|
|
45
|
+
})
|
|
46
|
+
if (!latest) return null
|
|
47
|
+
// Cache result
|
|
48
|
+
const dir = path.dirname(UPDATE_CHECK_FILE)
|
|
49
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true })
|
|
50
|
+
fs.writeFileSync(UPDATE_CHECK_FILE, JSON.stringify({ latest, checkedAt: Date.now() }))
|
|
51
|
+
return latest !== pkg.version ? latest : null
|
|
52
|
+
} catch { return null }
|
|
53
|
+
})()
|
|
54
|
+
|
|
55
|
+
async function showUpdateBanner() {
|
|
56
|
+
try {
|
|
57
|
+
const latest = await Promise.race([updateCheckPromise, new Promise(r => setTimeout(() => r(null), 500))])
|
|
58
|
+
if (latest) {
|
|
59
|
+
console.log('')
|
|
60
|
+
console.log(` ╭─────────────────────────────────────────────────────────╮`)
|
|
61
|
+
console.log(` │ Update available: v${pkg.version} → v${latest}${' '.repeat(Math.max(0, 30 - pkg.version.length - latest.length))}│`)
|
|
62
|
+
console.log(` │ Run: squeezr update │`)
|
|
63
|
+
console.log(` ╰─────────────────────────────────────────────────────────╯`)
|
|
64
|
+
}
|
|
65
|
+
} catch {}
|
|
66
|
+
}
|
|
67
|
+
|
|
19
68
|
function getPortFromToml() {
|
|
20
69
|
try {
|
|
21
70
|
const toml = fs.readFileSync(path.join(ROOT, 'squeezr.toml'), 'utf-8')
|
|
@@ -55,6 +104,7 @@ Usage:
|
|
|
55
104
|
squeezr status Check if proxy is running
|
|
56
105
|
squeezr config Print config file path and current settings
|
|
57
106
|
squeezr ports Change HTTP and MITM proxy ports
|
|
107
|
+
squeezr update Kill old processes, install latest from npm, restart
|
|
58
108
|
squeezr uninstall Remove Squeezr completely (env vars, CA, auto-start, logs)
|
|
59
109
|
squeezr version Print version
|
|
60
110
|
squeezr help Show this help
|
|
@@ -900,6 +950,44 @@ switch (command) {
|
|
|
900
950
|
else setupUnix()
|
|
901
951
|
break
|
|
902
952
|
|
|
953
|
+
case 'update':
|
|
954
|
+
await (async () => {
|
|
955
|
+
console.log('Stopping Squeezr...')
|
|
956
|
+
stopProxy()
|
|
957
|
+
// Also kill anything on the ports by brute force
|
|
958
|
+
const uPort = getPort()
|
|
959
|
+
const uMitmPort = getMitmPort(uPort)
|
|
960
|
+
if (process.platform === 'win32') {
|
|
961
|
+
try { execSync(`for /f "tokens=5" %a in ('netstat -ano ^| findstr ":${uPort} " ^| findstr LISTENING') do taskkill /F /PID %a`, { stdio: 'pipe', shell: 'cmd.exe' }) } catch {}
|
|
962
|
+
try { execSync(`for /f "tokens=5" %a in ('netstat -ano ^| findstr ":${uMitmPort} " ^| findstr LISTENING') do taskkill /F /PID %a`, { stdio: 'pipe', shell: 'cmd.exe' }) } catch {}
|
|
963
|
+
} else {
|
|
964
|
+
try { execSync(`kill -9 $(lsof -ti:${uPort}) 2>/dev/null`, { stdio: 'pipe' }) } catch {}
|
|
965
|
+
try { execSync(`kill -9 $(lsof -ti:${uMitmPort}) 2>/dev/null`, { stdio: 'pipe' }) } catch {}
|
|
966
|
+
}
|
|
967
|
+
await new Promise(r => setTimeout(r, 1000))
|
|
968
|
+
|
|
969
|
+
console.log('Installing latest version...')
|
|
970
|
+
try {
|
|
971
|
+
const npmCmd = process.platform === 'win32' ? 'npm' : 'HTTPS_PROXY= npm'
|
|
972
|
+
execSync(`${npmCmd} install -g squeezr-ai@latest`, { stdio: 'inherit' })
|
|
973
|
+
} catch (e) {
|
|
974
|
+
// On Unix, might need sudo
|
|
975
|
+
try {
|
|
976
|
+
execSync('sudo HTTPS_PROXY= npm install -g squeezr-ai@latest', { stdio: 'inherit' })
|
|
977
|
+
} catch {
|
|
978
|
+
console.error('npm install failed. Try manually: npm install -g squeezr-ai')
|
|
979
|
+
process.exit(1)
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
console.log('\nStarting Squeezr...')
|
|
984
|
+
// Re-exec the new binary so we run the updated code
|
|
985
|
+
const squeezrBin = process.argv[1]
|
|
986
|
+
try {
|
|
987
|
+
execSync(`node "${squeezrBin}" start`, { stdio: 'inherit' })
|
|
988
|
+
} catch {}
|
|
989
|
+
})()
|
|
990
|
+
break
|
|
903
991
|
case 'stop':
|
|
904
992
|
stopProxy()
|
|
905
993
|
break
|
|
@@ -947,3 +1035,5 @@ switch (command) {
|
|
|
947
1035
|
console.log(HELP)
|
|
948
1036
|
process.exit(1)
|
|
949
1037
|
}
|
|
1038
|
+
|
|
1039
|
+
await showUpdateBanner()
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "squeezr-ai",
|
|
3
|
-
"version": "1.16.
|
|
3
|
+
"version": "1.16.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",
|
|
@@ -50,6 +50,7 @@
|
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@types/node": "^22.14.0",
|
|
52
52
|
"@types/node-forge": "^1.3.14",
|
|
53
|
+
"@vitest/coverage-v8": "^4.1.2",
|
|
53
54
|
"tsx": "^4.19.3",
|
|
54
55
|
"typescript": "^5.8.3",
|
|
55
56
|
"vitest": "^3.1.1"
|