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:
Gustavo Madeira Santana
2026-01-18 15:56:24 -05:00
committed by Peter Steinberger
parent 97531f174f
commit acb523de86
58 changed files with 1274 additions and 500 deletions

View File

@@ -1,14 +1,4 @@
import type { Command } from "commander";
import {
isNixMode,
loadConfig,
migrateLegacyConfig,
readConfigFileSnapshot,
writeConfigFile,
} from "../../config/config.js";
import { danger } from "../../globals.js";
import { autoMigrateLegacyState } from "../../infra/state-migrations.js";
import { defaultRuntime } from "../../runtime.js";
import { emitCliBanner } from "../banner.js";
function setProcessTitleForCommand(actionCommand: Command) {
@@ -25,52 +15,5 @@ export function registerPreActionHooks(program: Command, programVersion: string)
program.hook("preAction", async (_thisCommand, actionCommand) => {
setProcessTitleForCommand(actionCommand);
emitCliBanner(programVersion);
if (actionCommand.name() === "doctor") return;
const snapshot = await readConfigFileSnapshot();
if (snapshot.legacyIssues.length === 0) return;
if (isNixMode) {
defaultRuntime.error(
danger(
"Legacy config entries detected while running in Nix mode. Update your Nix config to the latest schema and retry.",
),
);
process.exit(1);
}
const migrated = migrateLegacyConfig(snapshot.parsed);
if (migrated.config) {
await writeConfigFile(migrated.config);
if (migrated.changes.length > 0) {
defaultRuntime.log(
`Migrated legacy config entries:\n${migrated.changes
.map((entry) => `- ${entry}`)
.join("\n")}`,
);
}
return;
}
const issues = snapshot.legacyIssues
.map((issue) => `- ${issue.path}: ${issue.message}`)
.join("\n");
defaultRuntime.error(
danger(
`Legacy config entries detected. Run "clawdbot doctor" (or ask your agent) to migrate.\n${issues}`,
),
);
process.exit(1);
});
program.hook("preAction", async (_thisCommand, actionCommand) => {
if (actionCommand.name() === "doctor") return;
const snapshot = await readConfigFileSnapshot();
if (snapshot.exists && !snapshot.valid) {
defaultRuntime.error(`Config invalid at ${snapshot.path}.`);
for (const issue of snapshot.issues) {
defaultRuntime.error(`- ${issue.path || "<root>"}: ${issue.message}`);
}
defaultRuntime.error("Run `clawdbot doctor` to repair, then retry.");
process.exit(1);
}
const cfg = loadConfig();
await autoMigrateLegacyState({ cfg });
});
}