CLI: streamline startup paths and env parsing
Add shared parseBooleanValue()/isTruthyEnvValue() and apply across CLI, gateway, memory, and live-test flags for consistent env handling. Introduce route-first fast paths, lazy subcommand registration, and deferred plugin loading to reduce CLI startup overhead. Centralize config validation via ensureConfigReady() and add config caching/deferred shell env fallback for fewer IO passes. Harden logger initialization/imports and add focused tests for argv, boolean parsing, frontmatter, and CLI subcommands.
This commit is contained in:
committed by
Peter Steinberger
parent
97531f174f
commit
acb523de86
@@ -8,6 +8,7 @@ import JSON5 from "json5";
|
||||
import {
|
||||
loadShellEnvFallback,
|
||||
resolveShellEnvFallbackTimeoutMs,
|
||||
shouldDeferShellEnvFallback,
|
||||
shouldEnableShellEnvFallback,
|
||||
} from "../infra/shell-env.js";
|
||||
import { DuplicateAgentDirError, findDuplicateAgentDirs } from "./agent-dirs.js";
|
||||
@@ -282,7 +283,7 @@ export function createConfigIO(overrides: ConfigIoDeps = {}) {
|
||||
function loadConfig(): ClawdbotConfig {
|
||||
try {
|
||||
if (!deps.fs.existsSync(configPath)) {
|
||||
if (shouldEnableShellEnvFallback(deps.env)) {
|
||||
if (shouldEnableShellEnvFallback(deps.env) && !shouldDeferShellEnvFallback(deps.env)) {
|
||||
loadShellEnvFallback({
|
||||
enabled: true,
|
||||
env: deps.env,
|
||||
@@ -352,7 +353,7 @@ export function createConfigIO(overrides: ConfigIoDeps = {}) {
|
||||
applyConfigEnv(cfg, deps.env);
|
||||
|
||||
const enabled = shouldEnableShellEnvFallback(deps.env) || cfg.env?.shellEnv?.enabled === true;
|
||||
if (enabled) {
|
||||
if (enabled && !shouldDeferShellEnvFallback(deps.env)) {
|
||||
loadShellEnvFallback({
|
||||
enabled: true,
|
||||
env: deps.env,
|
||||
@@ -583,8 +584,54 @@ export function createConfigIO(overrides: ConfigIoDeps = {}) {
|
||||
// NOTE: These wrappers intentionally do *not* cache the resolved config path at
|
||||
// module scope. `CLAWDBOT_CONFIG_PATH` (and friends) are expected to work even
|
||||
// when set after the module has been imported (tests, one-off scripts, etc.).
|
||||
const DEFAULT_CONFIG_CACHE_MS = 200;
|
||||
let configCache:
|
||||
| {
|
||||
configPath: string;
|
||||
expiresAt: number;
|
||||
config: ClawdbotConfig;
|
||||
}
|
||||
| null = null;
|
||||
|
||||
function resolveConfigCacheMs(env: NodeJS.ProcessEnv): number {
|
||||
const raw = env.CLAWDBOT_CONFIG_CACHE_MS?.trim();
|
||||
if (raw === "" || raw === "0") return 0;
|
||||
if (!raw) return DEFAULT_CONFIG_CACHE_MS;
|
||||
const parsed = Number.parseInt(raw, 10);
|
||||
if (!Number.isFinite(parsed)) return DEFAULT_CONFIG_CACHE_MS;
|
||||
return Math.max(0, parsed);
|
||||
}
|
||||
|
||||
function shouldUseConfigCache(env: NodeJS.ProcessEnv): boolean {
|
||||
if (env.CLAWDBOT_DISABLE_CONFIG_CACHE?.trim()) return false;
|
||||
return resolveConfigCacheMs(env) > 0;
|
||||
}
|
||||
|
||||
function clearConfigCache(): void {
|
||||
configCache = null;
|
||||
}
|
||||
|
||||
export function loadConfig(): ClawdbotConfig {
|
||||
return createConfigIO({ configPath: resolveConfigPath() }).loadConfig();
|
||||
const configPath = resolveConfigPath();
|
||||
const now = Date.now();
|
||||
if (shouldUseConfigCache(process.env)) {
|
||||
const cached = configCache;
|
||||
if (cached && cached.configPath === configPath && cached.expiresAt > now) {
|
||||
return cached.config;
|
||||
}
|
||||
}
|
||||
const config = createConfigIO({ configPath }).loadConfig();
|
||||
if (shouldUseConfigCache(process.env)) {
|
||||
const cacheMs = resolveConfigCacheMs(process.env);
|
||||
if (cacheMs > 0) {
|
||||
configCache = {
|
||||
configPath,
|
||||
expiresAt: now + cacheMs,
|
||||
config,
|
||||
};
|
||||
}
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
export async function readConfigFileSnapshot(): Promise<ConfigFileSnapshot> {
|
||||
@@ -594,5 +641,6 @@ export async function readConfigFileSnapshot(): Promise<ConfigFileSnapshot> {
|
||||
}
|
||||
|
||||
export async function writeConfigFile(cfg: ClawdbotConfig): Promise<void> {
|
||||
clearConfigCache();
|
||||
await createConfigIO({ configPath: resolveConfigPath() }).writeConfigFile(cfg);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user