From 5d994cd67b452874c07157ba52dae296b3f1ec5f Mon Sep 17 00:00:00 2001 From: 1bcMax Date: Wed, 9 Sep 2026 23:46:38 -0400 Subject: [PATCH] =?UTF-8?q?desktop:=20delete=20AgentStatus.restartRequired?= =?UTF-8?q?=20=E2=80=94=20nothing=20could=20ever=20read=20it?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Five adapters wrote it, five demo entries mirrored it, and not one line in the app read it. It was write-only state whose only effect was to look consumable. It could not be consumed. Codex and OpenClaw set it to a constant function of `configured`, so it was permanently true from the moment the agent connected — it encoded a category ("this kind of agent needs a restart when you change it"), which `activation` already encodes and `activationLabel` already renders as "Restart gateway/app after changes". Reading it as a state pins those two to a permanent "Restart pending", which is what a reviewer suggestion on #367 would have shipped. The honest reason no adapter can fill it in is that nothing observes whether an agent process has picked a config change up. Desktop knows when it wrote the file; it does not know when the agent last started, and for a CLI invoked per-session there is no such moment to compare against. A field that cannot be computed should not exist, so `types.ts` now says that where the field used to be. `WalletMutationResult.restartRequired` and `PaymentChainSwitchResult.restartRequired` are untouched. There it is a real state: Desktop has just written the config itself and knows whether it also restarted the thing that reads it. `manager.test.ts` pins that behaviour and still passes. Closes #377. Verified: tsc clean, 46 tests pass, vite build and esbuild electron build clean. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_015mUab3xrLHNpYqVHJLgJHL --- apps/desktop/electron/adapters/codex.ts | 1 - apps/desktop/electron/adapters/dsh.ts | 1 - apps/desktop/electron/adapters/hermes.ts | 1 - apps/desktop/electron/adapters/openclaw.ts | 1 - apps/desktop/electron/adapters/pi.ts | 1 - apps/desktop/electron/adapters/shared.ts | 2 -- apps/desktop/electron/core/types.ts | 8 +++++++- apps/desktop/src/api.ts | 5 ----- 8 files changed, 7 insertions(+), 13 deletions(-) diff --git a/apps/desktop/electron/adapters/codex.ts b/apps/desktop/electron/adapters/codex.ts index d1b27930..a8d9b0b4 100644 --- a/apps/desktop/electron/adapters/codex.ts +++ b/apps/desktop/electron/adapters/codex.ts @@ -28,7 +28,6 @@ export class CodexAdapter implements AgentAdapter { installed: Boolean(await findCommand(context, "codex")), configured, activation: this.activation, - restartRequired: configured, details: configured ? ["Restart Codex CLI or Codex Desktop after changing this connection."] : [], diff --git a/apps/desktop/electron/adapters/dsh.ts b/apps/desktop/electron/adapters/dsh.ts index 1d03561c..eec7c40a 100644 --- a/apps/desktop/electron/adapters/dsh.ts +++ b/apps/desktop/electron/adapters/dsh.ts @@ -31,7 +31,6 @@ export class DshAdapter implements AgentAdapter { installed, configured, activation: this.activation, - restartRequired: false, details: ["DSH settings are hot-reloaded.", "DSH is currently a developer preview."], }); } diff --git a/apps/desktop/electron/adapters/hermes.ts b/apps/desktop/electron/adapters/hermes.ts index 66c34499..f8f915bd 100644 --- a/apps/desktop/electron/adapters/hermes.ts +++ b/apps/desktop/electron/adapters/hermes.ts @@ -34,7 +34,6 @@ export class HermesAdapter implements AgentAdapter { installed: Boolean(hermes), configured: hasHermesConfig(config), activation: this.activation, - restartRequired: false, details: hermes ? hasHermesConfig(config) ? ["New Hermes chats use ClawRouter; an open session switches with /model."] diff --git a/apps/desktop/electron/adapters/openclaw.ts b/apps/desktop/electron/adapters/openclaw.ts index f8cdb2e7..33a959b9 100644 --- a/apps/desktop/electron/adapters/openclaw.ts +++ b/apps/desktop/electron/adapters/openclaw.ts @@ -30,7 +30,6 @@ export class OpenClawAdapter implements AgentAdapter { installed, configured: hasOpenClawConfig(config), activation: this.activation, - restartRequired: hasOpenClawConfig(config), details: installed ? hasOpenClawConfig(config) ? ["Restart the OpenClaw gateway after changing this connection."] diff --git a/apps/desktop/electron/adapters/pi.ts b/apps/desktop/electron/adapters/pi.ts index c286ac46..dcfdbb1f 100644 --- a/apps/desktop/electron/adapters/pi.ts +++ b/apps/desktop/electron/adapters/pi.ts @@ -29,7 +29,6 @@ export class PiAdapter implements AgentAdapter { installed: Boolean(await findCommand(context, "pi")), configured, activation: this.activation, - restartRequired: false, details: configured ? [ "Open /model (or press Ctrl+L) in Pi to use or refresh ClawRouter models; no restart is needed.", diff --git a/apps/desktop/electron/adapters/shared.ts b/apps/desktop/electron/adapters/shared.ts index 52841aef..878bc0fd 100644 --- a/apps/desktop/electron/adapters/shared.ts +++ b/apps/desktop/electron/adapters/shared.ts @@ -15,7 +15,6 @@ export async function statusShape(input: { installed: boolean; configured: boolean; activation: ActivationMode; - restartRequired?: boolean; details?: string[]; }): Promise { const proxyReachable = await proxyHealth(input.context); @@ -31,7 +30,6 @@ export async function statusShape(input: { proxyReachable, health, activation: input.activation, - restartRequired: input.restartRequired ?? false, removalMode: "unavailable", details: input.details ?? [], }; diff --git a/apps/desktop/electron/core/types.ts b/apps/desktop/electron/core/types.ts index e99db8f3..409e3fc4 100644 --- a/apps/desktop/electron/core/types.ts +++ b/apps/desktop/electron/core/types.ts @@ -14,8 +14,14 @@ export type AgentStatus = { configured: boolean; proxyReachable: boolean; health: AgentHealth; + // No `restartRequired` here on purpose. Nothing can observe whether an agent + // process has picked a config change up, so a status field claiming it would be + // a guess — and the two adapters that had one set it to a constant function of + // `configured`, making it permanently true. `activation` carries the category + // ("this kind of agent needs a restart when you change it"), which is the only + // part that is knowable. WalletMutationResult and PaymentChainSwitchResult below + // DO carry it, and there it is real: Desktop has just written the config itself. activation: ActivationMode; - restartRequired: boolean; removalMode: "restore" | "disconnect" | "unavailable"; details: string[]; }; diff --git a/apps/desktop/src/api.ts b/apps/desktop/src/api.ts index 39741b6b..d6c04bdb 100644 --- a/apps/desktop/src/api.ts +++ b/apps/desktop/src/api.ts @@ -38,7 +38,6 @@ const demoAgents: AgentStatus[] = [ proxyReachable: true, health: "ready", activation: "restart-gateway", - restartRequired: false, removalMode: "disconnect", details: [], }, @@ -51,7 +50,6 @@ const demoAgents: AgentStatus[] = [ proxyReachable: true, health: "ready", activation: "restart-agent", - restartRequired: true, removalMode: "restore", details: ["Restart Codex Desktop after changing the active provider."], }, @@ -64,7 +62,6 @@ const demoAgents: AgentStatus[] = [ proxyReachable: true, health: "needs-attention", activation: "immediate", - restartRequired: false, removalMode: "disconnect", details: [], }, @@ -77,7 +74,6 @@ const demoAgents: AgentStatus[] = [ proxyReachable: true, health: "not-installed", activation: "immediate", - restartRequired: false, removalMode: "unavailable", details: ["DSH settings are hot-reloaded.", "DSH is currently a developer preview."], }, @@ -90,7 +86,6 @@ const demoAgents: AgentStatus[] = [ proxyReachable: true, health: "needs-attention", activation: "immediate", - restartRequired: false, removalMode: "unavailable", details: [], },