diff --git a/src/cli/index.ts b/src/cli/index.ts index 2c155d2..03a2ded 100644 --- a/src/cli/index.ts +++ b/src/cli/index.ts @@ -50,6 +50,36 @@ interface ResolvedContext { // exactly one command per process. let activeProjectCwd: string | undefined; + +/** + * Läuft der gefundene Hub auf DIESER Maschine, dann Loopback bevorzugen. + * + * Hintergrund (real erlebt, kostete Stunden): Die Selbstheilung unten sucht + * per mDNS, wenn die konfigurierte Adresse kurz nicht antwortet — das passiert + * bei JEDEM Hub-Neustart. Sie fand die LAN-IP und schrieb sie in die Config, + * womit ein zuvor gesetztes 127.0.0.1 verlorenging. Die LAN-IP wiederum bricht + * beim nächsten Netzwechsel oder Neustart weg, also heilte sich das System in + * die instabilere Adresse hinein. Loopback ist für Agenten auf derselben + * Maschine strikt robuster — es kann weder durch mDNS-Neuankündigung noch + * durch einen Netzwechsel ungültig werden. + */ +async function preferLoopback(url: string | undefined): Promise { + if (!url) return url; + let port: string; + try { + port = new URL(url).port || '3377'; + } catch { + return url; + } + const loopback = `http://127.0.0.1:${port}`; + if (url === loopback) return url; + try { + const res = await fetch(`${loopback}/status`, { signal: AbortSignal.timeout(1200) }); + if (res.ok) return loopback; + } catch { /* nicht lokal erreichbar — dann bleibt die gefundene Adresse */ } + return url; +} + async function resolveContext(program: Command, cwd: string): Promise { activeProjectCwd = cwd; const flag = (program.opts().server as string | undefined) || process.env.AGENTHUB_SERVER; @@ -86,7 +116,7 @@ async function resolveContext(program: Command, cwd: string): Promise