@@ -2,7 +2,13 @@ import fs from "node:fs/promises";
22import path from "node:path" ;
33import { readConfigFileSnapshot , recoverConfigFromJsonRootSuffix } from "../config/io.js" ;
44import { formatConfigIssueLines } from "../config/issue-format.js" ;
5+ import { findLegacyConfigIssues } from "../config/legacy.js" ;
6+ import type { LegacyConfigIssue } from "../config/types.js" ;
57import type { OpenClawConfig } from "../config/types.openclaw.js" ;
8+ import {
9+ collectRelevantDoctorPluginIds ,
10+ listPluginDoctorLegacyConfigRules ,
11+ } from "../plugins/doctor-contract-registry.js" ;
612import { note } from "../terminal/note.js" ;
713import { resolveHomeDir } from "../utils.js" ;
814import { noteIncludeConfinementWarning } from "./doctor-config-analysis.js" ;
@@ -55,6 +61,33 @@ export type DoctorConfigPreflightResult = {
5561 baseConfig : OpenClawConfig ;
5662} ;
5763
64+ function collectDoctorLegacyIssues (
65+ snapshot : Awaited < ReturnType < typeof readConfigFileSnapshot > > ,
66+ ) : LegacyConfigIssue [ ] {
67+ if ( ! snapshot . exists ) {
68+ return [ ] ;
69+ }
70+ const resolvedRaw = snapshot . sourceConfig ?? snapshot . config ?? { } ;
71+ const sourceRaw = snapshot . parsed ?? resolvedRaw ;
72+ return findLegacyConfigIssues (
73+ resolvedRaw ,
74+ sourceRaw ,
75+ listPluginDoctorLegacyConfigRules ( {
76+ pluginIds : collectRelevantDoctorPluginIds ( resolvedRaw ) ,
77+ } ) ,
78+ ) ;
79+ }
80+
81+ function addDoctorLegacyIssues (
82+ snapshot : Awaited < ReturnType < typeof readConfigFileSnapshot > > ,
83+ ) : Awaited < ReturnType < typeof readConfigFileSnapshot > > {
84+ const legacyIssues = collectDoctorLegacyIssues ( snapshot ) ;
85+ if ( legacyIssues . length === 0 ) {
86+ return snapshot ;
87+ }
88+ return { ...snapshot , legacyIssues } ;
89+ }
90+
5891export async function runDoctorConfigPreflight (
5992 options : {
6093 migrateState ?: boolean ;
@@ -81,15 +114,15 @@ export async function runDoctorConfigPreflight(
81114 }
82115 }
83116
84- let snapshot = await readConfigFileSnapshot ( ) ;
117+ let snapshot = addDoctorLegacyIssues ( await readConfigFileSnapshot ( ) ) ;
85118 if (
86119 options . repairPrefixedConfig === true &&
87120 snapshot . exists &&
88121 ! snapshot . valid &&
89122 ( await recoverConfigFromJsonRootSuffix ( snapshot ) )
90123 ) {
91124 note ( "Removed non-JSON prefix from openclaw.json; original saved as .clobbered.*." , "Config" ) ;
92- snapshot = await readConfigFileSnapshot ( ) ;
125+ snapshot = addDoctorLegacyIssues ( await readConfigFileSnapshot ( ) ) ;
93126 }
94127 const invalidConfigNote =
95128 options . invalidConfigNote ?? "Config invalid; doctor will run with best-effort config." ;
0 commit comments