nyk
feat(refactor): ready for manual QA after main sync (#274)
b6ecafa unverified
Raw
History Blame Contribute Delete
2.04 kB
import { NextResponse } from 'next/server'
import { runOpenClaw } from '@/lib/command'
const GITHUB_RELEASES_URL =
'https://api.github.com/repos/openclaw/openclaw/releases/latest'
function compareSemver(a: string, b: string): number {
const pa = a.replace(/^v/, '').split('.').map(Number)
const pb = b.replace(/^v/, '').split('.').map(Number)
for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
const na = pa[i] ?? 0
const nb = pb[i] ?? 0
if (na > nb) return 1
if (na < nb) return -1
}
return 0
}
const headers = { 'Cache-Control': 'public, max-age=3600' }
export async function GET() {
let installed: string | null = null
try {
const result = await runOpenClaw(['--version'], { timeoutMs: 3000 })
const match = result.stdout.match(/(\d+\.\d+\.\d+)/)
if (match) installed = match[1]
} catch {
// OpenClaw not installed or not reachable
return NextResponse.json(
{ installed: null, latest: null, updateAvailable: false },
{ headers }
)
}
if (!installed) {
return NextResponse.json(
{ installed: null, latest: null, updateAvailable: false },
{ headers }
)
}
try {
const res = await fetch(GITHUB_RELEASES_URL, {
headers: { Accept: 'application/vnd.github+json' },
next: { revalidate: 3600 },
})
if (!res.ok) {
return NextResponse.json(
{ installed, latest: null, updateAvailable: false },
{ headers }
)
}
const release = await res.json()
const latest = (release.tag_name ?? '').replace(/^v/, '')
const updateAvailable = compareSemver(latest, installed) > 0
return NextResponse.json(
{
installed,
latest,
updateAvailable,
releaseUrl: release.html_url ?? '',
releaseNotes: release.body ?? '',
updateCommand: 'openclaw update --channel stable',
},
{ headers }
)
} catch {
return NextResponse.json(
{ installed, latest: null, updateAvailable: false },
{ headers }
)
}
}