doctor: exempt the live compatibility agent dir from orphan-dir warnings

This commit is contained in:
carlos4s
2026-05-10 13:17:29 +00:00
committed by Peter Steinberger
parent 67be10c842
commit f841d6ede5
2 changed files with 53 additions and 1 deletions

View File

@@ -33,6 +33,8 @@ type EnvSnapshot = {
OPENCLAW_HOME?: string;
OPENCLAW_STATE_DIR?: string;
OPENCLAW_OAUTH_DIR?: string;
OPENCLAW_AGENT_DIR?: string;
PI_CODING_AGENT_DIR?: string;
};
function captureEnv(): EnvSnapshot {
@@ -41,6 +43,8 @@ function captureEnv(): EnvSnapshot {
OPENCLAW_HOME: process.env.OPENCLAW_HOME,
OPENCLAW_STATE_DIR: process.env.OPENCLAW_STATE_DIR,
OPENCLAW_OAUTH_DIR: process.env.OPENCLAW_OAUTH_DIR,
OPENCLAW_AGENT_DIR: process.env.OPENCLAW_AGENT_DIR,
PI_CODING_AGENT_DIR: process.env.PI_CODING_AGENT_DIR,
};
}
@@ -156,6 +160,8 @@ describe("doctor state integrity oauth dir checks", () => {
process.env.OPENCLAW_HOME = tempHome;
process.env.OPENCLAW_STATE_DIR = path.join(tempHome, ".openclaw");
delete process.env.OPENCLAW_OAUTH_DIR;
delete process.env.OPENCLAW_AGENT_DIR;
delete process.env.PI_CODING_AGENT_DIR;
fs.mkdirSync(process.env.OPENCLAW_STATE_DIR, { recursive: true, mode: 0o700 });
noteMock.mockClear();
});
@@ -249,6 +255,40 @@ describe("doctor state integrity oauth dir checks", () => {
expect(text).not.toContain("Examples:");
});
it("does not warn when the live compatibility main agent dir is missing from agents.list", async () => {
createAgentDir("main");
const text = await runStateIntegrityText({
agents: {
list: [{ id: "jeremiah", default: true }],
},
});
expect(text).not.toContain("without a matching agents.list entry");
expect(text).not.toContain("Examples:");
});
it("does not warn when OPENCLAW_AGENT_DIR points at the live compatibility agent dir", async () => {
createAgentDir("legacy");
const legacyAgentDir = path.join(
process.env.OPENCLAW_STATE_DIR ?? "",
"agents",
"legacy",
"agent",
);
process.env.OPENCLAW_AGENT_DIR = legacyAgentDir;
process.env.PI_CODING_AGENT_DIR = legacyAgentDir;
const text = await runStateIntegrityText({
agents: {
list: [{ id: "main", default: true }],
},
});
expect(text).not.toContain("without a matching agents.list entry");
expect(text).not.toContain("Examples:");
});
it("warns about tombstoned subagent restart recovery sessions", async () => {
const cfg: OpenClawConfig = {};
writeSessionStore(cfg, {

View File

@@ -25,6 +25,7 @@ import { updateSessionStore } from "../config/sessions/store.js";
import type { OpenClawConfig } from "../config/types.openclaw.js";
import { resolveRequiredHomeDir } from "../infra/home-dir.js";
import { resolveMemoryBackendConfig } from "../memory-host-sdk/engine-storage.js";
import { resolveOpenClawAgentDir } from "../plugin-sdk/agent-dir-compat.js";
import { listConfiguredChannelIdsForReadOnlyScope } from "../plugins/channel-plugin-ids.js";
import { normalizeAgentId } from "../routing/session-key.js";
import { parseAgentSessionKey } from "../sessions/session-key-utils.js";
@@ -90,6 +91,12 @@ function resolveComparableTranscriptPath(filePath: string): string {
return tryResolveNativeRealPath(filePath) ?? path.resolve(filePath);
}
function areComparablePathsEqual(leftPath: string, rightPath: string): boolean {
const leftRealPath = tryResolveNativeRealPath(leftPath);
const rightRealPath = tryResolveNativeRealPath(rightPath);
return leftRealPath !== null && leftRealPath === rightRealPath;
}
function isReachableConfiguredAgentDir(params: {
agentsRoot: string;
dirName: string;
@@ -126,6 +133,7 @@ function listOrphanAgentDirs(cfg: OpenClawConfig, stateDir: string): OrphanAgent
}
const agentsRoot = path.join(stateDir, "agents");
const liveCompatibilityAgentDir = resolveOpenClawAgentDir();
try {
const entries = fs.readdirSync(agentsRoot, { withFileTypes: true });
return entries
@@ -135,10 +143,14 @@ function listOrphanAgentDirs(cfg: OpenClawConfig, stateDir: string): OrphanAgent
agentId: normalizeAgentId(entry.name),
}))
.filter(({ dirName, agentId }) => {
const hasNestedAgentDir = existsDir(path.join(agentsRoot, dirName, "agent"));
const nestedAgentDir = path.join(agentsRoot, dirName, "agent");
const hasNestedAgentDir = existsDir(nestedAgentDir);
if (!hasNestedAgentDir) {
return false;
}
if (areComparablePathsEqual(nestedAgentDir, liveCompatibilityAgentDir)) {
return false;
}
if (!configuredIds.has(agentId)) {
return true;
}