diff --git a/package.json b/package.json index f4e8bbd5c9..178d6a9c7d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@bitkyc08/opencodex", - "version": "2.24.2", + "version": "2.25.0", "description": "Universal provider proxy for OpenAI Codex & Claude Code — use any LLM with Codex CLI/App/SDK and Claude Code", "type": "module", "main": "./bin/package-main.mjs", diff --git a/src/service-manager-probe.ts b/src/service-manager-probe.ts index 8446c78ae5..0c3552488f 100644 --- a/src/service-manager-probe.ts +++ b/src/service-manager-probe.ts @@ -267,9 +267,21 @@ function inspectSystemd(deps: Required>): Servic if (shown.spawnFailed) return { kind: "absent" }; if (shown.timedOut) return unknown("systemctl could not be asked: timed out"); if (shown.status !== 0) { + const err = shown.stderr.trim(); // A missing unit still exits ZERO and says not-found; a non-zero status means - // the question never reached the bus. - return unknown(`systemctl show exited ${String(shown.status)}: ${shown.stderr.trim()}`); + // the question never reached the bus. Two of those failures mean it never + // could: with no session-bus socket (or no systemd at all, e.g. WSL), no + // user unit can be registered, so there is nothing to conflict with — the + // same conclusion as systemctl being absent (#1939). Other bus failures + // (e.g. a misconfigured DBUS_SESSION_BUS_ADDRESS while the user manager + // runs) stay unknown. + if ( + err.includes("Failed to get D-Bus connection: No such file or directory") + || err.includes("System has not been booted with systemd") + ) { + return { kind: "absent" }; + } + return unknown(`systemctl show exited ${String(shown.status)}: ${err}`); } const loadState = systemdProperty(shown.stdout, "LoadState"); diff --git a/tests/codex-service-manager-probe.test.ts b/tests/codex-service-manager-probe.test.ts index d1c5035360..e4ea557f78 100644 --- a/tests/codex-service-manager-probe.test.ts +++ b/tests/codex-service-manager-probe.test.ts @@ -1008,3 +1008,29 @@ describe("ownership refuses what it cannot prove", () => { expect(result.ownership).toBe("owned"); }); }); + +describe("systemd probe: no user session bus", () => { + test("a missing session-bus socket means no user units can exist — absent (#1939)", () => { + const { run } = recorder(() => ({ + status: 1, + stderr: "Failed to get D-Bus connection: No such file or directory", + })); + expect(inspectServiceManagerInstallation({ run, platform: "linux", home }).kind).toBe("absent"); + }); + + test("WSL's not-booted-with-systemd message is absent for the same reason (#1939)", () => { + const { run } = recorder(() => ({ + status: 1, + stderr: "System has not been booted with systemd as init system (PID 1).", + })); + expect(inspectServiceManagerInstallation({ run, platform: "linux", home }).kind).toBe("absent"); + }); + + test("other bus failures stay unknown — the user manager may be running", () => { + const { run } = recorder(() => ({ + status: 1, + stderr: "Failed to connect to bus: $DBUS_SESSION_BUS_ADDRESS not set", + })); + expect(inspectServiceManagerInstallation({ run, platform: "linux", home }).kind).toBe("unknown"); + }); +});