fix: doctor ignore install dir in legacy workspace check

This commit is contained in:
Peter Steinberger
2026-01-10 16:23:28 +01:00
parent db5e4b986b
commit e60c3fc1b3
4 changed files with 71 additions and 6 deletions

View File

@@ -7,6 +7,7 @@
- Onboarding/Gateway: persist non-interactive gateway token auth in config; add WS wizard + gateway tool-calling regression coverage.
- CLI: `clawdbot sessions` now includes `elev:*` + `usage:*` flags in the table output.
- Branding: normalize user-facing “ClawdBot”/“CLAWDBOT” → “Clawdbot” (CLI, status, docs).
- Doctor: avoid false legacy workspace warning when install dir is `~/clawdbot`. (#660)
- iMessage: fix reasoning persistence across DMs; avoid partial/duplicate replies when reasoning is enabled. (#655) — thanks @antons.
- Models/Auth: allow MiniMax API configs without `models.providers.minimax.apiKey` (auth profiles / `MINIMAX_API_KEY`). (#656) — thanks @mneves75.
- Agents: avoid duplicate replies when the message tool sends. (#659) — thanks @mickahouan.

View File

@@ -0,0 +1,37 @@
import path from "node:path";
import { describe, expect, it } from "vitest";
import { detectLegacyWorkspaceDirs } from "./doctor-workspace.js";
describe("detectLegacyWorkspaceDirs", () => {
it("ignores ~/clawdbot when it doesn't look like a workspace (e.g. install dir)", () => {
const home = "/home/user";
const workspaceDir = "/home/user/clawd";
const candidate = path.join(home, "clawdbot");
const detection = detectLegacyWorkspaceDirs({
workspaceDir,
homedir: () => home,
exists: (value) => value === candidate,
});
expect(detection.activeWorkspace).toBe(path.resolve(workspaceDir));
expect(detection.legacyDirs).toEqual([]);
});
it("flags ~/clawdis when it contains workspace markers", () => {
const home = "/home/user";
const workspaceDir = "/home/user/clawd";
const candidate = path.join(home, "clawdis");
const agentsPath = path.join(candidate, "AGENTS.md");
const detection = detectLegacyWorkspaceDirs({
workspaceDir,
homedir: () => home,
exists: (value) => value === candidate || value === agentsPath,
});
expect(detection.legacyDirs).toEqual([candidate]);
});
});

View File

@@ -2,7 +2,12 @@ import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { DEFAULT_AGENTS_FILENAME } from "../agents/workspace.js";
import {
DEFAULT_AGENTS_FILENAME,
DEFAULT_IDENTITY_FILENAME,
DEFAULT_SOUL_FILENAME,
DEFAULT_USER_FILENAME,
} from "../agents/workspace.js";
export const MEMORY_SYSTEM_PROMPT = [
"Memory system not found in workspace.",
@@ -46,6 +51,19 @@ export type LegacyWorkspaceDetection = {
legacyDirs: string[];
};
function looksLikeWorkspaceDir(
dir: string,
exists: (value: string) => boolean,
) {
const markers = [
DEFAULT_AGENTS_FILENAME,
DEFAULT_SOUL_FILENAME,
DEFAULT_USER_FILENAME,
DEFAULT_IDENTITY_FILENAME,
];
return markers.some((name) => exists(path.join(dir, name)));
}
export function detectLegacyWorkspaceDirs(params: {
workspaceDir: string;
homedir?: () => string;
@@ -56,10 +74,14 @@ export function detectLegacyWorkspaceDirs(params: {
const home = homedir();
const activeWorkspace = path.resolve(params.workspaceDir);
const candidates = [path.join(home, "clawdis"), path.join(home, "clawdbot")];
const legacyDirs = candidates.filter((candidate) => {
if (!exists(candidate)) return false;
return path.resolve(candidate) !== activeWorkspace;
});
const legacyDirs = candidates
.filter((candidate) => {
if (!exists(candidate)) return false;
return path.resolve(candidate) !== activeWorkspace;
})
.filter((candidate) => {
return looksLikeWorkspaceDir(candidate, exists);
});
return { activeWorkspace, legacyDirs };
}

View File

@@ -535,8 +535,13 @@ describe("doctor", () => {
.mockReturnValue("/Users/steipete");
const realExists = fs.existsSync;
const legacyPath = path.join("/Users/steipete", "clawdis");
const legacyAgentsPath = path.join(legacyPath, "AGENTS.md");
const existsSpy = vi.spyOn(fs, "existsSync").mockImplementation((value) => {
if (value === "/Users/steipete/clawdis" || value === legacyPath)
if (
value === "/Users/steipete/clawdis" ||
value === legacyPath ||
value === legacyAgentsPath
)
return true;
return realExists(value as never);
});