refactor!: rename chat providers to channels

This commit is contained in:
Peter Steinberger
2026-01-13 06:16:43 +00:00
parent 0cd632ba84
commit 90342a4f3a
393 changed files with 8004 additions and 6737 deletions

View File

@@ -23,7 +23,7 @@ import {
applyTalkApiKey,
} from "./defaults.js";
import { ConfigIncludeError, resolveConfigIncludes } from "./includes.js";
import { findLegacyConfigIssues } from "./legacy.js";
import { applyLegacyMigrations, findLegacyConfigIssues } from "./legacy.js";
import { normalizeConfigPaths } from "./normalize-paths.js";
import { resolveConfigPath, resolveStateDir } from "./paths.js";
import { applyConfigOverrides } from "./runtime-overrides.js";
@@ -86,6 +86,10 @@ function warnOnConfigMiskeys(
}
}
function formatLegacyMigrationLog(changes: string[]): string {
return `Auto-migrated config:\n${changes.map((entry) => `- ${entry}`).join("\n")}`;
}
function applyConfigEnv(cfg: ClawdbotConfig, env: NodeJS.ProcessEnv): void {
const envConfig = cfg.env;
if (!envConfig) return;
@@ -142,6 +146,53 @@ export function createConfigIO(overrides: ConfigIoDeps = {}) {
const deps = normalizeDeps(overrides);
const configPath = resolveConfigPathForDeps(deps);
const writeConfigFileSync = (cfg: ClawdbotConfig) => {
const dir = path.dirname(configPath);
deps.fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
const json = JSON.stringify(applyModelDefaults(cfg), null, 2)
.trimEnd()
.concat("\n");
const tmp = path.join(
dir,
`${path.basename(configPath)}.${process.pid}.${crypto.randomUUID()}.tmp`,
);
deps.fs.writeFileSync(tmp, json, { encoding: "utf-8", mode: 0o600 });
try {
deps.fs.copyFileSync(configPath, `${configPath}.bak`);
} catch {
// best-effort
}
try {
deps.fs.renameSync(tmp, configPath);
} catch (err) {
const code = (err as { code?: string }).code;
if (code === "EPERM" || code === "EEXIST") {
deps.fs.copyFileSync(tmp, configPath);
try {
deps.fs.chmodSync(configPath, 0o600);
} catch {
// best-effort
}
try {
deps.fs.unlinkSync(tmp);
} catch {
// best-effort
}
return;
}
try {
deps.fs.unlinkSync(tmp);
} catch {
// best-effort
}
throw err;
}
};
function loadConfig(): ClawdbotConfig {
try {
if (!deps.fs.existsSync(configPath)) {
@@ -165,9 +216,12 @@ export function createConfigIO(overrides: ConfigIoDeps = {}) {
parseJson: (raw) => deps.json5.parse(raw),
});
warnOnConfigMiskeys(resolved, deps.logger);
if (typeof resolved !== "object" || resolved === null) return {};
const validated = ClawdbotSchema.safeParse(resolved);
const migrated = applyLegacyMigrations(resolved);
const resolvedConfig = migrated.next ?? resolved;
warnOnConfigMiskeys(resolvedConfig, deps.logger);
if (typeof resolvedConfig !== "object" || resolvedConfig === null)
return {};
const validated = ClawdbotSchema.safeParse(resolvedConfig);
if (!validated.success) {
deps.logger.error("Invalid config:");
for (const iss of validated.error.issues) {
@@ -175,6 +229,16 @@ export function createConfigIO(overrides: ConfigIoDeps = {}) {
}
return {};
}
if (migrated.next && migrated.changes.length > 0) {
deps.logger.warn(formatLegacyMigrationLog(migrated.changes));
try {
writeConfigFileSync(resolvedConfig as ClawdbotConfig);
} catch (err) {
deps.logger.warn(
`Failed to write migrated config at ${configPath}: ${String(err)}`,
);
}
}
const cfg = applyModelDefaults(
applyContextPruningDefaults(
applySessionDefaults(
@@ -287,13 +351,11 @@ export function createConfigIO(overrides: ConfigIoDeps = {}) {
};
}
const legacyIssues = findLegacyConfigIssues(resolved);
const resolvedConfig =
typeof resolved === "object" && resolved !== null
? (resolved as ClawdbotConfig)
: {};
const migrated = applyLegacyMigrations(resolved);
const resolvedConfig = migrated.next ?? resolved;
const legacyIssues = findLegacyConfigIssues(resolvedConfig);
const validated = validateConfigObject(resolved);
const validated = validateConfigObject(resolvedConfig);
if (!validated.ok) {
return {
path: configPath,
@@ -307,6 +369,15 @@ export function createConfigIO(overrides: ConfigIoDeps = {}) {
};
}
if (migrated.next && migrated.changes.length > 0) {
deps.logger.warn(formatLegacyMigrationLog(migrated.changes));
await writeConfigFile(validated.config).catch((err) => {
deps.logger.warn(
`Failed to write migrated config at ${configPath}: ${String(err)}`,
);
});
}
return {
path: configPath,
exists: true,