fix: migrate legacy state/config paths

This commit is contained in:
Peter Steinberger
2026-01-28 00:15:54 +00:00
parent 0770194b29
commit e2c437e81e
19 changed files with 492 additions and 33 deletions

View File

@@ -1,3 +1,4 @@
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import type { MoltbotConfig } from "./types.js";
@@ -18,6 +19,7 @@ export const isNixMode = resolveIsNixMode();
const LEGACY_STATE_DIRNAME = ".clawdbot";
const NEW_STATE_DIRNAME = ".moltbot";
const CONFIG_FILENAME = "moltbot.json";
const LEGACY_CONFIG_FILENAME = "clawdbot.json";
function legacyStateDir(homedir: () => string = os.homedir): string {
return path.join(homedir(), LEGACY_STATE_DIRNAME);
@@ -27,10 +29,19 @@ function newStateDir(homedir: () => string = os.homedir): string {
return path.join(homedir(), NEW_STATE_DIRNAME);
}
export function resolveLegacyStateDir(homedir: () => string = os.homedir): string {
return legacyStateDir(homedir);
}
export function resolveNewStateDir(homedir: () => string = os.homedir): string {
return newStateDir(homedir);
}
/**
* State directory for mutable data (sessions, logs, caches).
* Can be overridden via MOLTBOT_STATE_DIR (preferred) or CLAWDBOT_STATE_DIR (legacy).
* Default: ~/.clawdbot (legacy default for compatibility)
* If ~/.moltbot exists and ~/.clawdbot does not, prefer ~/.moltbot.
*/
export function resolveStateDir(
env: NodeJS.ProcessEnv = process.env,
@@ -38,7 +49,12 @@ export function resolveStateDir(
): string {
const override = env.MOLTBOT_STATE_DIR?.trim() || env.CLAWDBOT_STATE_DIR?.trim();
if (override) return resolveUserPath(override);
return legacyStateDir(homedir);
const legacyDir = legacyStateDir(homedir);
const newDir = newStateDir(homedir);
const hasLegacy = fs.existsSync(legacyDir);
const hasNew = fs.existsSync(newDir);
if (!hasLegacy && hasNew) return newDir;
return legacyDir;
}
function resolveUserPath(input: string): string {
@@ -58,7 +74,7 @@ export const STATE_DIR = resolveStateDir();
* Can be overridden via MOLTBOT_CONFIG_PATH (preferred) or CLAWDBOT_CONFIG_PATH (legacy).
* Default: ~/.clawdbot/moltbot.json (or $*_STATE_DIR/moltbot.json)
*/
export function resolveConfigPath(
export function resolveCanonicalConfigPath(
env: NodeJS.ProcessEnv = process.env,
stateDir: string = resolveStateDir(env, os.homedir),
): string {
@@ -67,7 +83,56 @@ export function resolveConfigPath(
return path.join(stateDir, CONFIG_FILENAME);
}
export const CONFIG_PATH = resolveConfigPath();
/**
* Resolve the active config path by preferring existing config candidates
* (new/legacy filenames) before falling back to the canonical path.
*/
export function resolveConfigPathCandidate(
env: NodeJS.ProcessEnv = process.env,
homedir: () => string = os.homedir,
): string {
const candidates = resolveDefaultConfigCandidates(env, homedir);
const existing = candidates.find((candidate) => {
try {
return fs.existsSync(candidate);
} catch {
return false;
}
});
if (existing) return existing;
return resolveCanonicalConfigPath(env, resolveStateDir(env, homedir));
}
/**
* Active config path (prefers existing legacy/new config files).
*/
export function resolveConfigPath(
env: NodeJS.ProcessEnv = process.env,
stateDir: string = resolveStateDir(env, os.homedir),
homedir: () => string = os.homedir,
): string {
const override = env.MOLTBOT_CONFIG_PATH?.trim() || env.CLAWDBOT_CONFIG_PATH?.trim();
if (override) return resolveUserPath(override);
const candidates = [
path.join(stateDir, CONFIG_FILENAME),
path.join(stateDir, LEGACY_CONFIG_FILENAME),
];
const existing = candidates.find((candidate) => {
try {
return fs.existsSync(candidate);
} catch {
return false;
}
});
if (existing) return existing;
const defaultStateDir = resolveStateDir(env, homedir);
if (path.resolve(stateDir) === path.resolve(defaultStateDir)) {
return resolveConfigPathCandidate(env, homedir);
}
return path.join(stateDir, CONFIG_FILENAME);
}
export const CONFIG_PATH = resolveConfigPathCandidate();
/**
* Resolve default config path candidates across new + legacy locations.
@@ -84,14 +149,18 @@ export function resolveDefaultConfigCandidates(
const moltbotStateDir = env.MOLTBOT_STATE_DIR?.trim();
if (moltbotStateDir) {
candidates.push(path.join(resolveUserPath(moltbotStateDir), CONFIG_FILENAME));
candidates.push(path.join(resolveUserPath(moltbotStateDir), LEGACY_CONFIG_FILENAME));
}
const legacyStateDirOverride = env.CLAWDBOT_STATE_DIR?.trim();
if (legacyStateDirOverride) {
candidates.push(path.join(resolveUserPath(legacyStateDirOverride), CONFIG_FILENAME));
candidates.push(path.join(resolveUserPath(legacyStateDirOverride), LEGACY_CONFIG_FILENAME));
}
candidates.push(path.join(newStateDir(homedir), CONFIG_FILENAME));
candidates.push(path.join(newStateDir(homedir), LEGACY_CONFIG_FILENAME));
candidates.push(path.join(legacyStateDir(homedir), CONFIG_FILENAME));
candidates.push(path.join(legacyStateDir(homedir), LEGACY_CONFIG_FILENAME));
return candidates;
}