From 8c7c47c0e855a1bf1004c2d8047f6b840ad71758 Mon Sep 17 00:00:00 2001 From: Blomios Date: Sun, 21 Jun 2026 02:00:13 +0200 Subject: [PATCH] =?UTF-8?q?fix(mcp):=20fallback=20d=C3=A9terministe=20du?= =?UTF-8?q?=20runtime=20dir=20socket?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `unix_runtime_dir` essaie désormais les bases candidates dans l'ordre de priorité ($XDG_RUNTIME_DIR → $TMPDIR → /tmp) et retient la première dont le sous-dossier `idea-mcp` existe ou peut être créé. Un $XDG_RUNTIME_DIR positionné mais inutilisable (sandbox/CI pointant un chemin inexistant ou en lecture seule) ne doit plus dead-end le bind loopback : sans ce fallback le socket ne se liait jamais en silence et la délégation inter-agents mourait. Déterministe pour un environnement donné, donc le côté bind et tout lecteur de `socket_path()` s'accordent sur le même répertoire. Indépendant du Lot E1. Co-Authored-By: Claude Opus 4.8 --- crates/app-tauri/src/mcp_endpoint.rs | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/crates/app-tauri/src/mcp_endpoint.rs b/crates/app-tauri/src/mcp_endpoint.rs index b4dc728..3f9204b 100644 --- a/crates/app-tauri/src/mcp_endpoint.rs +++ b/crates/app-tauri/src/mcp_endpoint.rs @@ -87,13 +87,29 @@ impl McpEndpoint { /// per-user runtime dir (`$XDG_RUNTIME_DIR`, falling back to `$TMPDIR`, then /// `/tmp`). Kept short so the full socket path stays well under the ~108-byte /// `sockaddr_un` limit (`/run/user//idea-mcp/<32 hex>.sock` ≈ 50 bytes). +/// +/// The candidate bases are tried **in priority order**, returning the first whose +/// `idea-mcp` subdir exists or can be created. A set-but-unusable `$XDG_RUNTIME_DIR` +/// (e.g. a sandbox/CI where it points at a non-existent or read-only path) must not +/// dead-end the loopback bind: without this fallback the socket silently never +/// binds and inter-agent delegation dies. Deterministic for a given environment, so +/// the bind side and any `socket_path()` reader always agree on the same directory. #[cfg(unix)] fn unix_runtime_dir() -> PathBuf { - let base = std::env::var_os("XDG_RUNTIME_DIR") - .map(PathBuf::from) - .or_else(|| std::env::var_os("TMPDIR").map(PathBuf::from)) - .unwrap_or_else(|| PathBuf::from("/tmp")); - base.join("idea-mcp") + let candidates = [ + std::env::var_os("XDG_RUNTIME_DIR").map(PathBuf::from), + std::env::var_os("TMPDIR").map(PathBuf::from), + Some(PathBuf::from("/tmp")), + ]; + for base in candidates.into_iter().flatten() { + let dir = base.join("idea-mcp"); + if dir.is_dir() || std::fs::create_dir_all(&dir).is_ok() { + return dir; + } + } + // Last resort: keep the historical `/tmp` target even if creation just failed + // (the bind will surface the real error rather than silently picking nowhere). + PathBuf::from("/tmp").join("idea-mcp") } /// **Single source of truth.** Computes the deterministic loopback endpoint of a