AgentStatus.restartRequired reads like "a change is waiting for the agent to pick up". It isn't. Two of the five adapters set it to a constant function of configured:
apps/desktop/electron/adapters/codex.ts:31 — restartRequired: configured
apps/desktop/electron/adapters/openclaw.ts:33 — restartRequired: hasOpenClawConfig(config)
So it is permanently true from the moment the agent is connected and never becomes false again. What it actually encodes is a category — "this kind of agent needs a restart when you change it" — which activation already encodes, and which activationLabel already renders honestly as "Restart gateway after changes" / "Restart app after changes".
The flag being a category rather than a state is not itself a bug; it just means nothing can consume it as a state. That is what makes it a trap:
What a real fix needs: something that observes whether the running agent has picked the config up. Desktop writes the config, so it knows the write time; what it lacks is the agent process's start time. For Codex and OpenClaw that is knowable — find the process, read its start time, compare against the managed file's mtime — which would make restartRequired mean what it says and let the pill go back to "Connected" once the user has actually restarted.
Alternative, much cheaper: drop restartRequired from AgentStatus entirely and let activation carry the category, since that is all it currently expresses. The three call sites in manager.ts that return it as part of an action result (168, 175, 182 …) are a different thing and genuinely are a state — those should keep it.
Worth deciding which before anyone else tries to wire the flag into UI.
AgentStatus.restartRequiredreads like "a change is waiting for the agent to pick up". It isn't. Two of the five adapters set it to a constant function ofconfigured:apps/desktop/electron/adapters/codex.ts:31—restartRequired: configuredapps/desktop/electron/adapters/openclaw.ts:33—restartRequired: hasOpenClawConfig(config)So it is permanently true from the moment the agent is connected and never becomes false again. What it actually encodes is a category — "this kind of agent needs a restart when you change it" — which
activationalready encodes, and whichactivationLabelalready renders honestly as "Restart gateway after changes" / "Restart app after changes".The flag being a category rather than a state is not itself a bug; it just means nothing can consume it as a state. That is what makes it a trap:
healthLabelon it in desktop: visual refresh of the control plane #367 (App.tsx:1650). I applied that and had to revert it — it would have pinned Codex and OpenClaw to a permanent "Restart pending" pill, strictly worse than the "Connected" it replaced. There is now a comment inhealthLabelexplaining why, but the comment is a fence, not a fix.desktop-v0.1.3-preview.1line these agents read "Configured · restart required" permanently after connecting.activation: "immediate",restartRequired: false) and the chain-switch case by doing the restart. Codex and OpenClaw are the two left, and neither can be fixed that way — Desktop does not own those processes.What a real fix needs: something that observes whether the running agent has picked the config up. Desktop writes the config, so it knows the write time; what it lacks is the agent process's start time. For Codex and OpenClaw that is knowable — find the process, read its start time, compare against the managed file's mtime — which would make
restartRequiredmean what it says and let the pill go back to "Connected" once the user has actually restarted.Alternative, much cheaper: drop
restartRequiredfromAgentStatusentirely and letactivationcarry the category, since that is all it currently expresses. The three call sites inmanager.tsthat return it as part of an action result (168, 175, 182 …) are a different thing and genuinely are a state — those should keep it.Worth deciding which before anyone else tries to wire the flag into UI.