Skip to content

Commit 2a01993

Browse files
committed
Keep legacy plugin manifest doctor check lint-only
1 parent fa9810e commit 2a01993

4 files changed

Lines changed: 1 addition & 261 deletions

File tree

src/commands/doctor-plugin-manifests.test.ts

Lines changed: 0 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import {
99
collectLegacyPluginManifestContractMigrations,
1010
legacyPluginManifestContractMigrationToHealthFinding,
1111
maybeRepairLegacyPluginManifestContracts,
12-
repairLegacyPluginManifestContractFindings,
1312
} from "./doctor-plugin-manifests.js";
1413
import type { DoctorPrompter } from "./doctor-prompter.js";
1514

@@ -281,63 +280,6 @@ describe("doctor plugin manifest legacy contract repair", () => {
281280
});
282281
});
283282

284-
it("previews legacy manifest rewrites as file effects and diffs", async () => {
285-
const pluginsRoot = await suiteTempDirs.make("preview-capability");
286-
const root = path.join(pluginsRoot, "openai");
287-
fs.mkdirSync(root, { recursive: true });
288-
writePackageJson(root);
289-
writeManifest(root, {
290-
id: "openai",
291-
speechProviders: ["openai"],
292-
configSchema: { type: "object" },
293-
});
294-
const manifestPath = path.join(root, "openclaw.plugin.json");
295-
296-
const result = await repairLegacyPluginManifestContractFindings({
297-
config: configWithPluginLoadPath(pluginsRoot),
298-
env: {
299-
...process.env,
300-
},
301-
manifestRoots: [pluginsRoot],
302-
findings: [
303-
{
304-
checkId: "core/doctor/legacy-plugin-manifests",
305-
severity: "warning",
306-
message: "Plugin manifest openai uses legacy top-level capability keys.",
307-
path: manifestPath,
308-
target: "openai",
309-
requirement: "contracts-capability-keys",
310-
},
311-
],
312-
dryRun: true,
313-
diff: true,
314-
});
315-
316-
expect(result.changes).toEqual([
317-
`- ${manifestPath}: moved speechProviders to contracts.speechProviders`,
318-
]);
319-
expect(result.effects).toEqual([
320-
{
321-
kind: "file",
322-
action: "would-rewrite-legacy-plugin-manifest-contracts",
323-
target: manifestPath,
324-
dryRunSafe: false,
325-
},
326-
]);
327-
expect(result.diffs).toEqual([
328-
expect.objectContaining({
329-
kind: "file",
330-
path: manifestPath,
331-
before: expect.stringContaining('"speechProviders"'),
332-
after: expect.stringContaining('"contracts"'),
333-
}),
334-
]);
335-
const unchanged = JSON.parse(fs.readFileSync(manifestPath, "utf-8")) as {
336-
speechProviders?: string[];
337-
};
338-
expect(unchanged.speechProviders).toEqual(["openai"]);
339-
});
340-
341283
it("ignores non-object contracts payloads when collecting migrations", async () => {
342284
const pluginsRoot = await suiteTempDirs.make("non-object-contracts");
343285
const root = path.join(pluginsRoot, "openai");

src/commands/doctor-plugin-manifests.ts

Lines changed: 1 addition & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,7 @@ import { normalizeTrimmedStringList } from "@openclaw/normalization-core/string-
66
import { z } from "zod";
77
import { note } from "../../packages/terminal-core/src/note.js";
88
import type { OpenClawConfig } from "../config/types.openclaw.js";
9-
import type {
10-
HealthFinding,
11-
HealthRepairDiff,
12-
HealthRepairEffect,
13-
HealthRepairResult,
14-
} from "../flows/health-checks.js";
9+
import type { HealthFinding } from "../flows/health-checks.js";
1510
import { loadPluginManifestRegistry } from "../plugins/manifest-registry.js";
1611
import type { RuntimeEnv } from "../runtime.js";
1712
import { shortenHomePath } from "../utils.js";
@@ -178,132 +173,6 @@ function migrationToManifestJson(migration: LegacyManifestContractMigration): st
178173
return `${JSON.stringify(migration.nextRaw, null, 2)}\n`;
179174
}
180175

181-
function legacyPluginManifestMigrationToRepairEffect(
182-
migration: LegacyManifestContractMigration,
183-
dryRun: boolean,
184-
): HealthRepairEffect {
185-
return {
186-
kind: "file",
187-
action: dryRun
188-
? "would-rewrite-legacy-plugin-manifest-contracts"
189-
: "rewrite-legacy-plugin-manifest-contracts",
190-
target: migration.manifestPath,
191-
dryRunSafe: false,
192-
};
193-
}
194-
195-
function legacyPluginManifestMigrationToRepairDiff(
196-
migration: LegacyManifestContractMigration,
197-
before: string,
198-
): HealthRepairDiff {
199-
return {
200-
kind: "file",
201-
path: migration.manifestPath,
202-
before,
203-
after: migrationToManifestJson(migration),
204-
};
205-
}
206-
207-
/** Repairs or previews selected legacy plugin manifest contract migrations. */
208-
export async function repairLegacyPluginManifestContractFindings(params: {
209-
config?: OpenClawConfig;
210-
env?: NodeJS.ProcessEnv;
211-
manifestRoots?: string[];
212-
workspaceDir?: string;
213-
findings: readonly HealthFinding[];
214-
dryRun?: boolean;
215-
diff?: boolean;
216-
deps?: {
217-
readFileSync?: typeof fs.readFileSync;
218-
writeFileSync?: typeof fs.writeFileSync;
219-
};
220-
}): Promise<HealthRepairResult> {
221-
const selectedPaths = new Set(
222-
params.findings
223-
.filter(
224-
(finding) =>
225-
finding.checkId === LEGACY_PLUGIN_MANIFESTS_CHECK_ID &&
226-
finding.requirement === "contracts-capability-keys" &&
227-
typeof finding.path === "string",
228-
)
229-
.map((finding) => finding.path as string),
230-
);
231-
if (selectedPaths.size === 0) {
232-
return {
233-
status: "skipped",
234-
reason: "no repairable legacy plugin manifest findings were present",
235-
changes: [],
236-
};
237-
}
238-
239-
const migrations = collectLegacyPluginManifestContractMigrations({
240-
...(params.config ? { config: params.config } : {}),
241-
...(params.env ? { env: params.env } : {}),
242-
...(params.manifestRoots ? { manifestRoots: params.manifestRoots } : {}),
243-
...(params.workspaceDir ? { workspaceDir: params.workspaceDir } : {}),
244-
}).filter((migration) => selectedPaths.has(migration.manifestPath));
245-
if (migrations.length === 0) {
246-
return {
247-
status: "skipped",
248-
reason: "selected legacy plugin manifests no longer need repair",
249-
changes: [],
250-
};
251-
}
252-
253-
const readFile = params.deps?.readFileSync ?? fs.readFileSync;
254-
const writeFile = params.deps?.writeFileSync ?? fs.writeFileSync;
255-
const changes: string[] = [];
256-
const diffs: HealthRepairDiff[] = [];
257-
const effects: HealthRepairEffect[] = [];
258-
const warnings: string[] = [];
259-
260-
for (const migration of migrations) {
261-
let before: string | undefined;
262-
if (params.diff === true) {
263-
try {
264-
before = readFile(migration.manifestPath, "utf-8");
265-
diffs.push(legacyPluginManifestMigrationToRepairDiff(migration, before));
266-
} catch (error) {
267-
warnings.push(
268-
`Could not read legacy plugin manifest at ${migration.manifestPath}: ${String(error)}`,
269-
);
270-
}
271-
}
272-
273-
if (params.dryRun !== true) {
274-
try {
275-
writeFile(migration.manifestPath, migrationToManifestJson(migration), "utf-8");
276-
} catch (error) {
277-
warnings.push(
278-
`Failed to rewrite legacy plugin manifest at ${migration.manifestPath}: ${String(error)}`,
279-
);
280-
continue;
281-
}
282-
}
283-
284-
changes.push(...migration.changeLines);
285-
effects.push(legacyPluginManifestMigrationToRepairEffect(migration, params.dryRun === true));
286-
}
287-
288-
if (changes.length === 0 && warnings.length > 0) {
289-
return {
290-
status: "failed",
291-
reason: "could not rewrite selected legacy plugin manifests",
292-
changes,
293-
warnings,
294-
diffs,
295-
effects,
296-
};
297-
}
298-
299-
return {
300-
changes,
301-
warnings,
302-
diffs,
303-
effects,
304-
};
305-
}
306-
307176
/** Prompts and rewrites legacy plugin manifest contract fields when doctor repair is enabled. */
308177
export async function maybeRepairLegacyPluginManifestContracts(params: {
309178
config?: OpenClawConfig;

src/flows/doctor-health-contributions.test.ts

Lines changed: 0 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,6 @@ const mocks = vi.hoisted(() => ({
6969
}),
7070
),
7171
maybeRepairLegacyPluginManifestContracts: vi.fn().mockResolvedValue(undefined),
72-
repairLegacyPluginManifestContractFindings: vi.fn(async () => ({
73-
changes: [] as string[],
74-
effects: [] as unknown[],
75-
})),
7672
detectLegacyClawdBrowserProfileResidue: vi.fn(),
7773
maybeArchiveLegacyClawdBrowserProfileResidue: vi.fn(),
7874
resolveAgentWorkspaceDir: vi.fn(() => "/tmp/openclaw-workspace"),
@@ -179,7 +175,6 @@ vi.mock("../commands/doctor-plugin-manifests.js", () => ({
179175
legacyPluginManifestContractMigrationToHealthFinding:
180176
mocks.legacyPluginManifestContractMigrationToHealthFinding,
181177
maybeRepairLegacyPluginManifestContracts: mocks.maybeRepairLegacyPluginManifestContracts,
182-
repairLegacyPluginManifestContractFindings: mocks.repairLegacyPluginManifestContractFindings,
183178
}));
184179

185180
vi.mock("../commands/doctor-auth-oauth-sidecar.js", () => ({
@@ -390,11 +385,6 @@ describe("doctor health contributions", () => {
390385
mocks.legacyPluginManifestContractMigrationToHealthFinding.mockClear();
391386
mocks.maybeRepairLegacyPluginManifestContracts.mockClear();
392387
mocks.maybeRepairLegacyPluginManifestContracts.mockResolvedValue(undefined);
393-
mocks.repairLegacyPluginManifestContractFindings.mockClear();
394-
mocks.repairLegacyPluginManifestContractFindings.mockResolvedValue({
395-
changes: [],
396-
effects: [],
397-
});
398388
mocks.maybeRepairLegacyOAuthSidecarProfiles.mockClear();
399389
mocks.maybeRepairLegacyOAuthSidecarProfiles.mockResolvedValue(undefined);
400390
mocks.collectAuthProfileHealthFindings.mockClear();
@@ -566,56 +556,6 @@ describe("doctor health contributions", () => {
566556
);
567557
});
568558

569-
it("threads dry-run legacy plugin manifest repairs through the structured check", async () => {
570-
const contribution = requireDoctorContribution("doctor:legacy-plugin-manifests");
571-
const check = contribution.healthChecks[0] as HealthCheck;
572-
const findings = [
573-
{
574-
checkId: "core/doctor/legacy-plugin-manifests",
575-
severity: "warning" as const,
576-
message: "Plugin manifest legacy-plugin uses legacy top-level capability keys.",
577-
path: "/tmp/openclaw-plugin/openclaw.plugin.json",
578-
target: "legacy-plugin",
579-
requirement: "contracts-capability-keys",
580-
},
581-
];
582-
mocks.repairLegacyPluginManifestContractFindings.mockResolvedValueOnce({
583-
changes: ["Would rewrite legacy manifest."],
584-
effects: [
585-
{
586-
kind: "file",
587-
action: "would-rewrite-legacy-plugin-manifest-contracts",
588-
target: "/tmp/openclaw-plugin/openclaw.plugin.json",
589-
dryRunSafe: false,
590-
},
591-
],
592-
});
593-
594-
const result = await check.repair?.(
595-
{
596-
cfg: { plugins: { load: { paths: ["/tmp/openclaw-plugin"] } } },
597-
mode: "fix",
598-
dryRun: true,
599-
diff: true,
600-
runtime: { log: vi.fn(), error: vi.fn(), exit: vi.fn() },
601-
},
602-
findings,
603-
);
604-
605-
expect(mocks.repairLegacyPluginManifestContractFindings).toHaveBeenCalledWith({
606-
config: { plugins: { load: { paths: ["/tmp/openclaw-plugin"] } } },
607-
env: process.env,
608-
findings,
609-
dryRun: true,
610-
diff: true,
611-
});
612-
expect(result?.effects).toContainEqual(
613-
expect.objectContaining({
614-
action: "would-rewrite-legacy-plugin-manifest-contracts",
615-
}),
616-
);
617-
});
618-
619559
it("runs release configured plugin install repair before plugin registry and final config writes", () => {
620560
const ids = resolveDoctorHealthContributions().map((entry) => entry.id);
621561

src/flows/doctor-health-contributions.ts

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1353,17 +1353,6 @@ export function resolveDoctorHealthContributions(): DoctorHealthContribution[] {
13531353
env: process.env,
13541354
}).map(legacyPluginManifestContractMigrationToHealthFinding);
13551355
},
1356-
async repair(ctx, findings) {
1357-
const { repairLegacyPluginManifestContractFindings } =
1358-
await import("../commands/doctor-plugin-manifests.js");
1359-
return await repairLegacyPluginManifestContractFindings({
1360-
config: ctx.cfg,
1361-
env: process.env,
1362-
findings,
1363-
dryRun: ctx.dryRun,
1364-
diff: ctx.diff,
1365-
});
1366-
},
13671356
},
13681357
run: runLegacyPluginManifestHealth,
13691358
}),

0 commit comments

Comments
 (0)