refactor!: rename chat providers to channels
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user