diff --git a/lib/daemon.js b/lib/daemon.js index 1972368b..817190aa 100644 --- a/lib/daemon.js +++ b/lib/daemon.js @@ -23,7 +23,7 @@ delete process.env.CLAUDECODE; var fs = require("fs"); var path = require("path"); -var { loadConfig, saveConfig, socketPath, generateSlug, syncClayrc, removeFromClayrc, writeCrashInfo, readCrashInfo, clearCrashInfo, isPidAlive, clearStaleConfig, REAL_HOME } = require("./config"); +var { loadConfig, saveConfig, socketPath, ensureConfigDir, generateSlug, syncClayrc, removeFromClayrc, writeCrashInfo, readCrashInfo, clearCrashInfo, isPidAlive, clearStaleConfig, REAL_HOME } = require("./config"); var { createIPCServer } = require("./ipc"); var { createServer, generateAuthToken } = require("./server"); var { checkAclSupport, grantProjectAccess, revokeProjectAccess, provisionAllUsers, provisionLinuxUser, grantAllUsersAccess, deactivateLinuxUser, ensureProjectsDir } = require("./os-users"); @@ -1150,6 +1150,9 @@ if (existingConfig && existingConfig.pid && existingConfig.pid !== process.pid) clearStaleConfig(); } } +// Ensure config dirs exist before binding the socket. The daemon may start +// without a prior CLI invocation (systemd, supervisor), so it must be self-sufficient. +ensureConfigDir(); var ipc = createIPCServer(socketPath(), function (msg) { console.log("[daemon] IPC:", msg.cmd); switch (msg.cmd) { diff --git a/lib/ipc.js b/lib/ipc.js index 301f7c2f..87964029 100644 --- a/lib/ipc.js +++ b/lib/ipc.js @@ -6,6 +6,12 @@ var fs = require("fs"); * handler(msg) should return a response object (or a Promise of one). */ function createIPCServer(sockPath, handler) { + // Ensure the socket's parent directory exists (e.g. ~/.clagentic/console/). + // The daemon may start without a prior CLI invocation, so it must be self-sufficient. + if (process.platform !== "win32") { + try { fs.mkdirSync(require("path").dirname(sockPath), { recursive: true }); } catch (e) {} + } + // Remove stale socket file (not needed for Windows named pipes) if (process.platform !== "win32") { try { fs.unlinkSync(sockPath); } catch (e) {} @@ -53,6 +59,12 @@ function createIPCServer(sockPath, handler) { console.log("[ipc] Socket in use, removing stale socket and retrying..."); try { fs.unlinkSync(sockPath); } catch (e) {} server.listen(sockPath); + } else if (err.code === "ENOENT" && !retried) { + // Parent directory missing — create it and retry once. + retried = true; + console.log("[ipc] Socket directory missing, creating and retrying..."); + try { fs.mkdirSync(require("path").dirname(sockPath), { recursive: true }); } catch (e) {} + server.listen(sockPath); } else { console.error("[ipc] Failed to bind socket:", err.message); process.exit(1);