fix: normalize ~ in path config
This commit is contained in:
parent
9a88c94b30
commit
328d47f1df
@ -24,6 +24,7 @@ import {
|
|||||||
} from "./defaults.js";
|
} from "./defaults.js";
|
||||||
import { ConfigIncludeError, resolveConfigIncludes } from "./includes.js";
|
import { ConfigIncludeError, resolveConfigIncludes } from "./includes.js";
|
||||||
import { findLegacyConfigIssues } from "./legacy.js";
|
import { findLegacyConfigIssues } from "./legacy.js";
|
||||||
|
import { normalizeConfigPaths } from "./normalize-paths.js";
|
||||||
import { resolveConfigPath, resolveStateDir } from "./paths.js";
|
import { resolveConfigPath, resolveStateDir } from "./paths.js";
|
||||||
import { applyConfigOverrides } from "./runtime-overrides.js";
|
import { applyConfigOverrides } from "./runtime-overrides.js";
|
||||||
import type {
|
import type {
|
||||||
@ -182,6 +183,7 @@ export function createConfigIO(overrides: ConfigIoDeps = {}) {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
normalizeConfigPaths(cfg);
|
||||||
|
|
||||||
const duplicates = findDuplicateAgentDirs(cfg, {
|
const duplicates = findDuplicateAgentDirs(cfg, {
|
||||||
env: deps.env,
|
env: deps.env,
|
||||||
@ -306,10 +308,12 @@ export function createConfigIO(overrides: ConfigIoDeps = {}) {
|
|||||||
raw,
|
raw,
|
||||||
parsed: parsedRes.parsed,
|
parsed: parsedRes.parsed,
|
||||||
valid: true,
|
valid: true,
|
||||||
config: applyTalkApiKey(
|
config: normalizeConfigPaths(
|
||||||
applyModelDefaults(
|
applyTalkApiKey(
|
||||||
applySessionDefaults(
|
applyModelDefaults(
|
||||||
applyLoggingDefaults(applyMessageDefaults(validated.config)),
|
applySessionDefaults(
|
||||||
|
applyLoggingDefaults(applyMessageDefaults(validated.config)),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
57
src/config/normalize-paths.ts
Normal file
57
src/config/normalize-paths.ts
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import { resolveUserPath } from "../utils.js";
|
||||||
|
import type { ClawdbotConfig } from "./types.js";
|
||||||
|
|
||||||
|
const PATH_VALUE_RE = /^~(?=$|[\\/])/;
|
||||||
|
|
||||||
|
const PATH_KEY_RE = /(dir|path|paths|file|root|workspace)$/i;
|
||||||
|
const PATH_LIST_KEYS = new Set(["paths"]);
|
||||||
|
|
||||||
|
function isPlainObject(value: unknown): value is Record<string, unknown> {
|
||||||
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeStringValue(key: string | undefined, value: string): string {
|
||||||
|
if (!PATH_VALUE_RE.test(value.trim())) return value;
|
||||||
|
if (!key) return value;
|
||||||
|
if (PATH_KEY_RE.test(key) || PATH_LIST_KEYS.has(key)) {
|
||||||
|
return resolveUserPath(value);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeAny(key: string | undefined, value: unknown): unknown {
|
||||||
|
if (typeof value === "string") return normalizeStringValue(key, value);
|
||||||
|
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
const normalizeChildren = Boolean(key && PATH_LIST_KEYS.has(key));
|
||||||
|
return value.map((entry) => {
|
||||||
|
if (typeof entry === "string") {
|
||||||
|
return normalizeChildren ? normalizeStringValue(key, entry) : entry;
|
||||||
|
}
|
||||||
|
if (Array.isArray(entry)) return normalizeAny(undefined, entry);
|
||||||
|
if (isPlainObject(entry)) return normalizeAny(undefined, entry);
|
||||||
|
return entry;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isPlainObject(value)) return value;
|
||||||
|
|
||||||
|
for (const [childKey, childValue] of Object.entries(value)) {
|
||||||
|
const next = normalizeAny(childKey, childValue);
|
||||||
|
if (next !== childValue) value[childKey] = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalize "~" paths in path-ish config fields.
|
||||||
|
*
|
||||||
|
* Goal: accept `~/...` consistently across config file + env overrides, while
|
||||||
|
* keeping the surface area small and predictable.
|
||||||
|
*/
|
||||||
|
export function normalizeConfigPaths(cfg: ClawdbotConfig): ClawdbotConfig {
|
||||||
|
if (!cfg || typeof cfg !== "object") return cfg;
|
||||||
|
normalizeAny(undefined, cfg);
|
||||||
|
return cfg;
|
||||||
|
}
|
||||||
@ -57,7 +57,7 @@ export function resolveConfigPath(
|
|||||||
stateDir: string = resolveStateDir(env, os.homedir),
|
stateDir: string = resolveStateDir(env, os.homedir),
|
||||||
): string {
|
): string {
|
||||||
const override = env.CLAWDBOT_CONFIG_PATH?.trim();
|
const override = env.CLAWDBOT_CONFIG_PATH?.trim();
|
||||||
if (override) return override;
|
if (override) return resolveUserPath(override);
|
||||||
return path.join(stateDir, "clawdbot.json");
|
return path.join(stateDir, "clawdbot.json");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user