fix(cli): Selbstheilung bevorzugt Loopback — sie heilte sich bisher in die instabilere Adresse

Vom CEO an codex' Log entdeckt: der CLI-Worker scheiterte mit
"AgentHub server at http://192.168.178.52:3377 is not reachable" — obwohl die
MCP-Bridge laengst auf 127.0.0.1 zeigte. Grund: die CLI nimmt die
PROJEKT-Config, nicht die MCP-Umgebungsvariable.

Und die Projekt-Config wurde immer wieder zurueckgeschrieben: antwortet die
konfigurierte Adresse kurz nicht — bei JEDEM Hub-Neustart der Fall —, sucht
resolveContext per mDNS, findet die LAN-IP und persistiert sie. Ein zuvor
gesetztes Loopback ging dabei jedes Mal verloren. Die LAN-IP wiederum bricht
beim naechsten Neustart oder Netzwechsel weg: das System heilte sich
zuverlaessig in die instabilere Adresse hinein.

`preferLoopback()` prueft jetzt, ob derselbe Hub auch auf 127.0.0.1 antwortet,
und persistiert dann Loopback. Fuer Agenten auf derselben Maschine ist das
strikt robuster — es kann weder durch mDNS-Neuankuendigung noch durch einen
Netzwechsel ungueltig werden. Projekt-Config zusaetzlich zurueckgesetzt.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
chahinebrini 2026-07-29 21:36:42 +02:00
parent 6e614b1f4d
commit dac8afb3c1

View File

@ -50,6 +50,36 @@ interface ResolvedContext {
// exactly one command per process. // exactly one command per process.
let activeProjectCwd: string | undefined; 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<string | undefined> {
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<ResolvedContext> { async function resolveContext(program: Command, cwd: string): Promise<ResolvedContext> {
activeProjectCwd = cwd; activeProjectCwd = cwd;
const flag = (program.opts().server as string | undefined) || process.env.AGENTHUB_SERVER; const flag = (program.opts().server as string | undefined) || process.env.AGENTHUB_SERVER;
@ -86,7 +116,7 @@ async function resolveContext(program: Command, cwd: string): Promise<ResolvedCo
// Initialized project but no server configured yet: auto-find one on the // Initialized project but no server configured yet: auto-find one on the
// LAN and remember it, so the agent connects with zero manual setup. // LAN and remember it, so the agent connects with zero manual setup.
const discovered = await discoverServer(2000); const discovered = await preferLoopback(await discoverServer(2000));
if (discovered) { if (discovered) {
try { try {
saveConfig(root, { ...config, serverUrl: discovered }); saveConfig(root, { ...config, serverUrl: discovered });