mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 11:10:45 +00:00
fix(doctor): keep noninteractive service repair explicit
This commit is contained in:
@@ -57,6 +57,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Setup/import: honor non-interactive `--import-from` onboarding flags by running the migration import path instead of silently completing normal setup without importing anything. Thanks @vincentkoc.
|
||||
- Discord/voice: run voice-channel turns under a voice-output policy that hides the agent `tts` tool and asks for spoken reply text, so `/vc join` sessions synthesize and play agent replies instead of ending with `NO_REPLY`. Fixes #61536. Thanks @aounakram.
|
||||
- Doctor/plugins: keep plain `doctor --non-interactive` from installing bundled plugin runtime dependencies, so headless health checks report missing deps while `doctor --fix` remains the explicit repair path. Thanks @vincentkoc.
|
||||
- Doctor/gateway: require an interactive confirmation before installing or rewriting the Gateway service, so `doctor --fix --non-interactive` can repair plugin/config drift without replacing the operator's launchd/systemd service from a temporary environment. Thanks @vincentkoc.
|
||||
- Plugins/runtime-deps: include packaged OpenClaw identity in bundled plugin loader cache keys, so same-path package upgrades stop reusing stale versioned runtime-deps mirrors. Fixes #75045. Thanks @sahilsatralkar.
|
||||
- Plugin SDK: restore reply-prefix and reply-pipeline helpers on the deprecated root/compat SDK surface so external plugins still using `openclaw/plugin-sdk` do not fail message dispatch after update. Fixes #75171. Thanks @zhangxiliang.
|
||||
- Plugins/runtime-deps: prune inactive same-package versioned runtime-deps roots after bundled dependency repair, so upgrades do not leave old `openclaw-<version>-<hash>` package caches behind after doctor runs. Thanks @vincentkoc.
|
||||
|
||||
@@ -185,6 +185,10 @@ describe("maybeRepairGatewayDaemon", () => {
|
||||
|
||||
async function runNonInteractiveUpdateRepair() {
|
||||
process.env.OPENCLAW_UPDATE_IN_PROGRESS = "1";
|
||||
await runNonInteractiveRepair();
|
||||
}
|
||||
|
||||
async function runNonInteractiveRepair() {
|
||||
const runtime = { log: vi.fn(), error: vi.fn(), exit: vi.fn() };
|
||||
await maybeRepairGatewayDaemon({
|
||||
cfg: { gateway: {} },
|
||||
@@ -256,6 +260,20 @@ describe("maybeRepairGatewayDaemon", () => {
|
||||
expect(service.restart).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("skips gateway install during non-interactive doctor repairs", async () => {
|
||||
setPlatform("linux");
|
||||
service.isLoaded.mockResolvedValue(false);
|
||||
|
||||
await runNonInteractiveRepair();
|
||||
|
||||
expect(service.install).not.toHaveBeenCalled();
|
||||
expect(service.restart).not.toHaveBeenCalled();
|
||||
expect(note).toHaveBeenCalledWith(
|
||||
expect.stringContaining("openclaw gateway install"),
|
||||
"Gateway",
|
||||
);
|
||||
});
|
||||
|
||||
it("skips gateway restart during non-interactive update repairs", async () => {
|
||||
setPlatform("linux");
|
||||
|
||||
|
||||
@@ -199,9 +199,16 @@ export async function maybeRepairGatewayDaemon(params: {
|
||||
{
|
||||
message: "Install gateway service now?",
|
||||
initialValue: true,
|
||||
requiresInteractiveConfirmation: true,
|
||||
},
|
||||
serviceRepairPolicy,
|
||||
);
|
||||
if (!install) {
|
||||
note(
|
||||
`Run ${formatCliCommand("openclaw gateway install")} when you want to install the gateway service.`,
|
||||
"Gateway",
|
||||
);
|
||||
}
|
||||
if (install) {
|
||||
const daemonRuntime = await params.prompter.select<GatewayDaemonRuntime>(
|
||||
{
|
||||
|
||||
@@ -664,7 +664,7 @@ describe("maybeRepairGatewayServiceConfig", () => {
|
||||
expect(mocks.stage).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("repairs entrypoint mismatch in non-interactive fix mode", async () => {
|
||||
it("skips entrypoint rewrite in non-interactive fix mode", async () => {
|
||||
setupGatewayEntrypointRepairScenario({
|
||||
currentEntrypoint: "/Users/test/Library/npm/node_modules/openclaw/dist/entry.js",
|
||||
installEntrypoint: "/Users/test/Library/npm/node_modules/openclaw/dist/index.js",
|
||||
@@ -680,8 +680,12 @@ describe("maybeRepairGatewayServiceConfig", () => {
|
||||
expect.stringContaining("Gateway service entrypoint does not match the current install."),
|
||||
"Gateway service config",
|
||||
);
|
||||
expect(mocks.note).toHaveBeenCalledWith(
|
||||
expect.stringContaining("openclaw gateway install --force"),
|
||||
"Gateway service config",
|
||||
);
|
||||
expect(mocks.stage).not.toHaveBeenCalled();
|
||||
expect(mocks.install).toHaveBeenCalledTimes(1);
|
||||
expect(mocks.install).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("stages service config repairs during non-interactive update repairs", async () => {
|
||||
|
||||
@@ -509,19 +509,32 @@ export async function maybeRepairGatewayServiceConfig(
|
||||
return;
|
||||
}
|
||||
|
||||
const repair = needsAggressive
|
||||
? await prompter.confirmAggressiveAutoFix({
|
||||
message: "Overwrite gateway service config with current defaults now?",
|
||||
initialValue: prompter.shouldForce,
|
||||
})
|
||||
: await prompter.confirmAutoFix({
|
||||
message: "Update gateway service config to the recommended defaults now?",
|
||||
initialValue: true,
|
||||
const updateRepairMode = isDoctorUpdateRepairMode(prompter.repairMode);
|
||||
const repairMessage = needsAggressive
|
||||
? "Overwrite gateway service config with current defaults now?"
|
||||
: "Update gateway service config to the recommended defaults now?";
|
||||
const repair = updateRepairMode
|
||||
? needsAggressive
|
||||
? await prompter.confirmAggressiveAutoFix({
|
||||
message: repairMessage,
|
||||
initialValue: prompter.shouldForce,
|
||||
})
|
||||
: await prompter.confirmAutoFix({
|
||||
message: repairMessage,
|
||||
initialValue: true,
|
||||
})
|
||||
: await prompter.confirmRuntimeRepair({
|
||||
message: repairMessage,
|
||||
initialValue: needsAggressive ? prompter.shouldForce : true,
|
||||
requiresInteractiveConfirmation: true,
|
||||
});
|
||||
if (!repair) {
|
||||
note(
|
||||
"Run `openclaw gateway install --force` when you want to replace the gateway service definition.",
|
||||
"Gateway service config",
|
||||
);
|
||||
return;
|
||||
}
|
||||
const updateRepairMode = isDoctorUpdateRepairMode(prompter.repairMode);
|
||||
const serviceEmbeddedToken = readEmbeddedGatewayToken(command);
|
||||
const gatewayTokenForRepair = expectedGatewayToken ?? serviceEmbeddedToken;
|
||||
const configuredGatewayToken =
|
||||
|
||||
Reference in New Issue
Block a user