Skip to content

Commit 8dc36c7

Browse files
committed
0.5.32 - 🔄 Restart outdated daemon automatically on version mismatch
1 parent de61331 commit 8dc36c7

4 files changed

Lines changed: 35 additions & 4 deletions

File tree

bin/free-coding-models.js

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
// 📖 npm install running on the same machine.
1111
// 📖 IMPORTANT: these checks MUST run synchronously before any static imports
1212
// 📖 resolve, because router-daemon.js reads FCM_DEV at module load time.
13-
import { existsSync } from 'node:fs'
13+
import { existsSync, readFileSync } from 'node:fs'
1414
import { join, dirname } from 'node:path'
1515
import { fileURLToPath } from 'node:url'
1616
if (process.argv.includes('--dev') || (!process.env.FCM_DEV && existsSync(join(dirname(fileURLToPath(import.meta.url)), '..', '.git')))) {
@@ -78,7 +78,14 @@ async function main() {
7878
})
7979
: { latestVersion: null, allowedOutdated: false, warningMessage: null, failures: 0, checked: false, updated: false, blocked: false };
8080

81-
if (startupUpdate.updated) return;
81+
if (startupUpdate.updated) {
82+
try {
83+
// 📖 Stop any running daemon so that the relaunch/restart will start the new version.
84+
const { stopRouterDaemon } = await import('../src/core/router-daemon.js');
85+
await stopRouterDaemon();
86+
} catch {}
87+
return;
88+
}
8289
if (startupUpdate.blocked) process.exit(1);
8390
if (startupUpdate.allowedOutdated) {
8491
process.env.FCM_UPDATE_ALLOWED_OUTDATED = '1';
@@ -87,6 +94,19 @@ async function main() {
8794
process.env.FCM_UPDATE_FAILURES = String(startupUpdate.failures || 0);
8895
}
8996

97+
// 📖 If the daemon is running an outdated version, stop it so it will restart on the new version.
98+
if (!cliArgs.daemonStopMode && !cliArgs.daemonStatusMode) {
99+
try {
100+
const { getRouterDaemonStatus, stopRouterDaemon } = await import('../src/core/router-daemon.js');
101+
const status = await getRouterDaemonStatus();
102+
const LOCAL_VERSION = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')).version;
103+
if (status.ok && status.version && status.version !== LOCAL_VERSION) {
104+
console.log(chalk.yellow(` ⚠ Outdated daemon version v${status.version} detected (current: v${LOCAL_VERSION}). Stopping old daemon...`));
105+
await stopRouterDaemon();
106+
}
107+
} catch {}
108+
}
109+
90110
// 📖 Standalone web dashboard: same full-catalog ping UI as the TUI, served
91111
// 📖 locally with Socket.IO/SSE/REST realtime updates.
92112
if (cliArgs.webMode) {

changelog/v0.5.32.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Changelog v0.5.32 - 2026-06-15
2+
3+
### Added
4+
- **Automatic daemon restart on version mismatch.** Added version detection to the daemon `/health` status payload. The CLI now automatically checks the running daemon version on startup (or when starting the daemon in the background) and terminates the outdated daemon if a version mismatch with the current CLI is detected, forcing a restart on the new version.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "free-coding-models",
3-
"version": "0.5.31",
3+
"version": "0.5.32",
44
"description": "Find the fastest coding LLM models in seconds — ping free models from multiple providers, pick the best one for OpenCode, Cursor, or any AI coding assistant.",
55
"keywords": [
66
"nvidia",

src/core/router-daemon.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1379,6 +1379,7 @@ class RouterRuntime {
13791379
// 📖 the Playground showed "router offline" even when the Router card
13801380
// 📖 said "Running" — both hit /api/router/status but read different fields.
13811381
running: true,
1382+
version: LOCAL_VERSION,
13821383
pid: process.pid,
13831384
port: this.port,
13841385
enabled: router.enabled,
@@ -3526,7 +3527,13 @@ export async function getRouterDaemonStatus() {
35263527

35273528
export async function startRouterDaemonBackground() {
35283529
const existing = await getRouterDaemonStatus()
3529-
if (existing.ok) return { ...existing, alreadyRunning: true }
3530+
if (existing.ok) {
3531+
if (existing.version && existing.version !== LOCAL_VERSION) {
3532+
await stopRouterDaemon()
3533+
} else {
3534+
return { ...existing, alreadyRunning: true }
3535+
}
3536+
}
35303537

35313538
const child = fork(CLI_ENTRY_PATH, ['--daemon'], {
35323539
detached: true,

0 commit comments

Comments
 (0)