openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
176 lines (175 loc) • 7.48 kB
JavaScript
import { t as defineSplitHealthCheckInput } from "./health-check-adapter-EMFeb2Zf.js";
import { r as resolveDoctorWorkspaceDir } from "./doctor-health-contribution-utils-BSNOrYZa.js";
//#region src/flows/doctor-health-contribution.ts
function createDoctorHealthContribution(params) {
const healthChecks = normalizeHealthChecks(params.id, params.healthChecks);
const healthCheckIds = params.healthCheckIds ?? healthChecks.map((check) => check.id);
if (params.run === void 0 && healthChecks.length === 0) throw new Error(`doctor contribution ${params.id} must define run or healthChecks`);
return {
id: params.id,
kind: "core",
surface: "health",
option: {
value: params.id,
label: params.label,
...params.hint ? { hint: params.hint } : {}
},
source: "doctor",
healthChecks,
healthCheckIds,
...params.required ? { required: true } : {},
run: params.run ?? ((ctx) => runStructuredDoctorHealthContribution({
contributionId: params.id,
ctx,
checks: healthChecks
}))
};
}
function normalizeHealthChecks(contributionId, healthChecks) {
if (healthChecks === void 0) return [];
const checks = Array.isArray(healthChecks) ? healthChecks : [healthChecks];
return checks.map((check) => normalizeContributionHealthCheck(check, contributionId, checks.length));
}
function normalizeContributionHealthCheck(check, contributionId, count) {
const id = check.id ?? (count === 1 ? deriveCoreHealthCheckId(contributionId) : void 0);
if (id === void 0) throw new Error(`doctor contribution ${contributionId} must specify health check ids when it declares multiple healthChecks`);
const identity = {
id,
kind: check.kind ?? "core",
source: check.source ?? "doctor"
};
return "run" in check ? {
...check,
...identity,
sourceContract: "run"
} : {
...check,
...identity,
sourceContract: "split"
};
}
function deriveCoreHealthCheckId(contributionId) {
return contributionId.startsWith("doctor:") ? `core/doctor/${contributionId.slice(7)}` : `core/doctor/${contributionId}`;
}
async function runStructuredDoctorHealthContribution(params) {
if (params.checks.length === 0) throw new Error(`doctor contribution ${params.contributionId} has no structured health`);
const { runDoctorHealthRepairs } = await import("./doctor-repair-flow-DqatSdUQ.js");
const workspaceDir = resolveDoctorWorkspaceDir(params.ctx.cfg, params.ctx.env);
const dryRun = !params.ctx.prompter.shouldRepair;
const result = await runDoctorHealthRepairs({
mode: "fix",
runtime: params.ctx.runtime,
cfg: params.ctx.cfg,
cwd: workspaceDir,
configPath: params.ctx.configPath,
dryRun,
allowExecSecretRefs: params.ctx.options.allowExec === true
}, {
checks: params.checks,
dryRun
});
params.ctx.cfg = result.config;
renderStructuredHealthFindings(params.ctx, result.findings);
for (const warning of result.warnings) params.ctx.runtime.error(warning);
for (const change of result.changes) params.ctx.runtime.log(change);
}
function renderStructuredHealthFindings(ctx, findings) {
for (const finding of findings) {
const write = finding.severity === "error" ? ctx.runtime.error : ctx.runtime.log;
const where = finding.path !== void 0 ? ` ${finding.path}` : "";
const line = finding.line !== void 0 ? `:${finding.line}` : "";
write(`[${finding.severity}] ${finding.checkId}${where}${line} - ${finding.message}`);
if (finding.fixHint !== void 0) ctx.runtime.log(` fix: ${finding.fixHint}`);
}
}
//#endregion
//#region src/flows/doctor-health-contribution-core.ts
const loadHealthCheckRegistryModule = async () => await import("./health-check-registry-BzU8tXic.js");
function withDoctorHealthCheckFacts(ctx, input) {
return {
...input,
...ctx.runWithPluginMetadataSnapshot ? { runWithPluginMetadataSnapshot: ctx.runWithPluginMetadataSnapshot } : {}
};
}
async function runStructuredHealthRepairs(ctx, resolveCoreChecks) {
if (!ctx.prompter.shouldRepair) return;
const { registerBundledHealthChecks } = await import("./bundled-health-checks-BKqYeSZp.js");
const { listExtensionHealthChecksForDoctor } = await loadHealthCheckRegistryModule();
const { runDoctorHealthRepairs } = await import("./doctor-repair-flow-DqatSdUQ.js");
const { note } = await import("./terminal-core/note.js");
const workspaceDir = resolveDoctorWorkspaceDir(ctx.cfg, ctx.env);
registerBundledHealthChecks({
cfg: ctx.cfg,
cwd: workspaceDir
});
const checks = listExtensionHealthChecksForDoctor(await resolveCoreChecks()).map(defineSplitHealthCheckInput);
const result = await runDoctorHealthRepairs(withDoctorHealthCheckFacts(ctx, {
mode: "fix",
runtime: ctx.runtime,
cfg: ctx.cfg,
cwd: workspaceDir,
configPath: ctx.configPath
}), { checks });
ctx.cfg = result.config;
if (result.changes.length > 0) note(result.changes.join("\n"), "Doctor changes");
if (result.warnings.length > 0) note(result.warnings.join("\n"), "Doctor warnings");
}
async function runCoreContributionHealth(ctx, checkIds) {
if (checkIds.length === 0) return;
const { CORE_HEALTH_CHECKS } = await import("./doctor-core-checks-DgO120cz.js");
const { runDoctorHealthRepairs } = await import("./doctor-repair-flow-DqatSdUQ.js");
const { note } = await import("./terminal-core/note.js");
const selectedIds = new Set(checkIds);
const checks = CORE_HEALTH_CHECKS.filter((check) => selectedIds.has(check.id));
if (checks.length === 0) return;
const workspaceDir = resolveDoctorWorkspaceDir(ctx.cfg, ctx.env);
const dryRun = !ctx.prompter.shouldRepair;
const result = await runDoctorHealthRepairs(withDoctorHealthCheckFacts(ctx, {
mode: "fix",
runtime: ctx.runtime,
cfg: ctx.cfg,
cwd: workspaceDir,
configPath: ctx.configPath,
dryRun
}), {
checks,
dryRun
});
ctx.cfg = result.config;
renderStructuredHealthFindings(ctx, dryRun ? result.findings : result.remainingFindings);
if (result.changes.length > 0) note(result.changes.join("\n"), "Doctor changes");
if (result.warnings.length > 0) note(result.warnings.join("\n"), "Doctor warnings");
}
function formatHealthFindings(findings) {
return findings.map((finding) => {
const lines = [`- ${finding.message}`];
if (finding.path) lines.push(` path: ${finding.path}`);
if (finding.requirement) lines.push(` issue: ${finding.requirement}`);
if (finding.fixHint) lines.push(` fix: ${finding.fixHint}`);
return lines.join("\n");
}).join("\n");
}
async function runCoreHealthFindingNote(ctx, checkId) {
const { CORE_HEALTH_CHECKS } = await import("./doctor-core-checks-DgO120cz.js");
const { note } = await import("./terminal-core/note.js");
const check = CORE_HEALTH_CHECKS.find((candidate) => candidate.id === checkId);
if (!check) return;
const findings = await check.detect(withDoctorHealthCheckFacts(ctx, {
mode: "doctor",
runtime: ctx.runtime,
cfg: ctx.cfg,
cwd: resolveDoctorWorkspaceDir(ctx.cfg, ctx.env),
configPath: ctx.configPath,
allowExecSecretRefs: ctx.options.allowExec === true
}));
if (findings.length === 0) return;
const information = findings.filter((finding) => finding.severity === "info");
const warnings = findings.filter((finding) => finding.severity !== "info");
if (information.length > 0) note(formatHealthFindings(information), "Doctor information");
if (warnings.length > 0) {
ctx.healthOk = false;
note(formatHealthFindings(warnings), "Doctor warnings");
}
}
//#endregion
export { createDoctorHealthContribution as i, runCoreHealthFindingNote as n, runStructuredHealthRepairs as r, runCoreContributionHealth as t };