refactor: extract inline middleware from index.ts into separate modules (#85)
- Extract update middleware to routes/update.ts - Extract health middleware and version logic to routes/health.ts - Extract shutdown logic to services/shutdown.ts - Extract gateway init to services/gateway-bootstrap.ts - Remove unused variables, fix duplicate app creation - Bump version to 0.4.0 index.ts: 260 lines → 80 lines Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
import Router from '@koa/router'
|
||||
import { resolve } from 'path'
|
||||
import { readFileSync } from 'fs'
|
||||
import { getGatewayManager } from './hermes/gateways'
|
||||
import * as hermesCli from '../services/hermes/hermes-cli'
|
||||
import { config } from '../config'
|
||||
|
||||
function getLocalVersion(): string {
|
||||
const candidates = [
|
||||
resolve(__dirname, '../../../package.json'),
|
||||
resolve(__dirname, '../../../../package.json'),
|
||||
]
|
||||
for (const p of candidates) {
|
||||
try {
|
||||
return JSON.parse(readFileSync(p, 'utf-8')).version
|
||||
} catch { }
|
||||
}
|
||||
return '0.0.0'
|
||||
}
|
||||
|
||||
const LOCAL_VERSION = getLocalVersion()
|
||||
let cachedLatestVersion = ''
|
||||
|
||||
export async function checkLatestVersion(): Promise<void> {
|
||||
try {
|
||||
const res = await fetch('https://registry.npmjs.org/hermes-web-ui/latest', {
|
||||
signal: AbortSignal.timeout(5000),
|
||||
headers: { 'Cache-Control': 'no-cache' },
|
||||
})
|
||||
if (res.ok) {
|
||||
const data = await res.json()
|
||||
const latest = data.version || ''
|
||||
if (latest && latest !== cachedLatestVersion) {
|
||||
cachedLatestVersion = latest
|
||||
if (latest !== LOCAL_VERSION) {
|
||||
console.log(`⬆ New version available: v${LOCAL_VERSION} → v${latest}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch { }
|
||||
}
|
||||
|
||||
export function startVersionCheck(): void {
|
||||
checkLatestVersion()
|
||||
setInterval(checkLatestVersion, 60 * 60 * 1000)
|
||||
}
|
||||
|
||||
export const healthRoutes = new Router()
|
||||
|
||||
healthRoutes.get('/health', async (ctx) => {
|
||||
const raw = await hermesCli.getVersion()
|
||||
const hermesVersion = raw.split('\n')[0].replace('Hermes Agent ', '') || ''
|
||||
|
||||
let gatewayOk = false
|
||||
try {
|
||||
const mgr = getGatewayManager()
|
||||
const upstream = mgr?.getUpstream() || config.upstream
|
||||
const res = await fetch(`${upstream.replace(/\/$/, '')}/health`, {
|
||||
signal: AbortSignal.timeout(5000),
|
||||
})
|
||||
gatewayOk = res.ok
|
||||
} catch { }
|
||||
|
||||
ctx.body = {
|
||||
status: gatewayOk ? 'ok' : 'error',
|
||||
platform: 'hermes-agent',
|
||||
version: hermesVersion,
|
||||
gateway: gatewayOk ? 'running' : 'stopped',
|
||||
webui_version: LOCAL_VERSION,
|
||||
webui_latest: cachedLatestVersion,
|
||||
webui_update_available: cachedLatestVersion && cachedLatestVersion !== LOCAL_VERSION,
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,33 @@
|
||||
import Router from '@koa/router'
|
||||
|
||||
export const updateRoutes = new Router()
|
||||
|
||||
updateRoutes.post('/api/hermes/update', async (ctx) => {
|
||||
const isWin = process.platform === 'win32'
|
||||
const cmd = isWin
|
||||
? 'cmd /c npm install -g hermes-web-ui@latest'
|
||||
: 'npm install -g hermes-web-ui@latest'
|
||||
|
||||
try {
|
||||
const { execSync } = await import('child_process')
|
||||
const output = execSync(cmd, {
|
||||
encoding: 'utf-8',
|
||||
timeout: 120000,
|
||||
stdio: ['pipe', 'pipe', 'pipe'],
|
||||
})
|
||||
ctx.body = { success: true, message: output.trim() }
|
||||
|
||||
setTimeout(() => {
|
||||
const { spawn } = require('child_process')
|
||||
spawn(isWin ? 'cmd' : 'sh', isWin ? ['/c', 'hermes-web-ui restart'] : ['-c', 'hermes-web-ui restart'], {
|
||||
detached: true,
|
||||
stdio: 'ignore',
|
||||
windowsHide: true,
|
||||
}).unref()
|
||||
process.exit(0)
|
||||
}, 2000)
|
||||
} catch (err: any) {
|
||||
ctx.status = 500
|
||||
ctx.body = { success: false, message: err.stderr || err.message }
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user