Files
AgentHub/client/src/lib/newBuildReload.ts
T
nntrivi2001 5fe5d51b1b feat: v2.5.5 — AI Router renamed AI Proxy, reload onto new builds, update no longer spins
AI Proxy (was AI Router):
- server/lib/ai-proxies.js, proxy-apply.js, routes/ai-proxies.js mounted at
  /api/ai-proxies and the old /api/ai-routers; `router` still accepted on the
  start routes; profiles move to <CLAUDE_HOME>/agenthub-proxies/
- dashboard_runs.router renamed in place to proxy: an older build on the same
  DB fails on that column, so dev and prod sharing one DB update together
- a proxy's baseUrl stored as its root (a typed /v1 made /v1/v1/messages);
  Test probes Claude /v1/messages and Codex /v1/responses
- Settings → AI Proxy (/settings/ai-router redirects), ProxyPicker

Updates:
- every tab reloads onto the new UI build when its WebSocket reconnects to a
  server of another version (lib/newBuildReload.ts, once per version)
- Update now stops waiting on a plugin chain that failed or pulled nothing
  (the old server never goes down), and reloads as soon as a new version answers

Also:
- a pane whose command exits at once says so (EPANEEXITED) instead of
  "Command failed: tmux set-option … mouse on"
- the pane drag preview draws where the pane actually lands
2026-10-06 22:48:09 +07:00

47 lines
1.5 KiB
TypeScript

/**
* @file newBuildReload.ts
* @description Reloads the tab onto the new UI build after the server was
* updated. Every update — the dashboard's own Update button in any tab,
* `/agenthub-update`, a restart onto a newer plugin — drops the WebSocket; when
* it comes back, `GET /api/health` names the server's version, and a version
* other than this bundle's `__APP_VERSION__` means the page is stale. At most
* one reload per version (sessionStorage), so a server whose UI build failed
* cannot make the tab reload on every reconnect.
* @author Nguyễn Ngọc Trí Vĩ <vinnt@smartgift.vn>
*/
import { eventBus } from "./eventBus";
const KEY = "agenthub.reloadedFor";
export function reloadOnNewBuild({
bundle = __APP_VERSION__,
health = () => fetch("/api/health").then((r) => r.json() as Promise<{ version?: string }>),
reload = () => window.location.reload(),
storage = window.sessionStorage,
}: {
bundle?: string;
health?: () => Promise<{ version?: string }>;
reload?: () => void;
storage?: Pick<Storage, "getItem" | "setItem">;
} = {}): () => void {
let wasDown = false;
return eventBus.onConnection((up) => {
if (!up) {
wasDown = true;
return;
}
if (!wasDown) return;
wasDown = false;
health()
.then(({ version }) => {
if (!version || version === bundle || storage.getItem(KEY) === version) return;
storage.setItem(KEY, version);
reload();
})
.catch(() => {
/* the next reconnect asks again */
});
});
}