// 桌面端版本与"检查更新"——查 GitHub Releases 最新版,比当前版本新则提示下载。 // 发版流程:bump 此处 APP_VERSION(= package.json version)→ 打 tag vX.Y.Z → release workflow 自动构建+发布。 export const APP_VERSION = "0.1.0"; // 当前桌面端版本(与 git tag 去掉 v 前缀对齐) const REPO = "blizzardzhang/sundynix-agentix"; export interface ReleaseInfo { version: string; // 最新版本号(不含 v) url: string; // release 页面(用户在此选 mac/win 安装包) notes: string; // 更新日志 } // checkUpdate 查 GitHub 最新 release;有比当前更新的版本则返回信息,否则 null(含出错/限流时静默)。 export async function checkUpdate(): Promise { try { const res = await fetch(`https://api.github.com/repos/${REPO}/releases/latest`, { headers: { Accept: "application/vnd.github+json" }, }); if (!res.ok) return null; // 404=还没发过 release / 403=限流 → 静默 const d = (await res.json()) as { tag_name?: string; html_url?: string; body?: string }; const latest = String(d.tag_name ?? "").replace(/^v/, ""); if (!latest || !isNewer(latest, APP_VERSION)) return null; return { version: latest, url: d.html_url ?? `https://github.com/${REPO}/releases/latest`, notes: d.body ?? "" }; } catch { return null; // 离线等 → 不打扰 } } // openExternal 在系统浏览器打开链接(Wails 用 runtime.BrowserOpenURL,浏览器模式回退 window.open)。 export function openExternal(url: string): void { const w = window as unknown as { runtime?: { BrowserOpenURL?: (u: string) => void } }; if (w.runtime?.BrowserOpenURL) { w.runtime.BrowserOpenURL(url); } else { window.open(url, "_blank"); } } // isNewer 语义化版本比较:a 是否比 b 新(按 major.minor.patch)。导出以便单测覆盖版本判定矩阵。 export function isNewer(a: string, b: string): boolean { const pa = a.split(".").map((n) => parseInt(n, 10) || 0); const pb = b.split(".").map((n) => parseInt(n, 10) || 0); for (let i = 0; i < 3; i++) { const x = pa[i] ?? 0; const y = pb[i] ?? 0; if (x !== y) return x > y; } return false; }