refactor: centralize config update logging

This commit is contained in:
Peter Steinberger
2026-01-23 04:01:11 +00:00
parent 246ee490f6
commit e750ad5e75
20 changed files with 73 additions and 70 deletions

View File

@@ -8,7 +8,8 @@ import {
} from "../agents/agent-scope.js";
import { ensureAuthProfileStore } from "../agents/auth-profiles.js";
import { resolveAuthStorePath } from "../agents/auth-profiles/paths.js";
import { CONFIG_PATH_CLAWDBOT, writeConfigFile } from "../config/config.js";
import { writeConfigFile } from "../config/config.js";
import { logConfigUpdated } from "../config/logging.js";
import { DEFAULT_AGENT_ID, normalizeAgentId } from "../routing/session-key.js";
import type { RuntimeEnv } from "../runtime.js";
import { defaultRuntime } from "../runtime.js";
@@ -126,7 +127,7 @@ export async function agentsAddCommand(
: { config: nextConfig, added: [], skipped: [], conflicts: [] };
await writeConfigFile(bindingResult.config);
if (!opts.json) runtime.log(`Updated ${shortenHomePath(CONFIG_PATH_CLAWDBOT)}`);
if (!opts.json) logConfigUpdated(runtime);
const quietRuntime = opts.json ? createQuietRuntime(runtime) : runtime;
await ensureWorkspaceAndSessions(workspaceDir, quietRuntime, {
skipBootstrap: Boolean(bindingResult.config.agents?.defaults?.skipBootstrap),
@@ -334,7 +335,7 @@ export async function agentsAddCommand(
}
await writeConfigFile(nextConfig);
runtime.log(`Updated ${shortenHomePath(CONFIG_PATH_CLAWDBOT)}`);
logConfigUpdated(runtime);
await ensureWorkspaceAndSessions(workspaceDir, runtime, {
skipBootstrap: Boolean(nextConfig.agents?.defaults?.skipBootstrap),
agentId,

View File

@@ -1,10 +1,10 @@
import { resolveAgentDir, resolveAgentWorkspaceDir } from "../agents/agent-scope.js";
import { CONFIG_PATH_CLAWDBOT, writeConfigFile } from "../config/config.js";
import { writeConfigFile } from "../config/config.js";
import { logConfigUpdated } from "../config/logging.js";
import { resolveSessionTranscriptsDirForAgent } from "../config/sessions.js";
import { DEFAULT_AGENT_ID, normalizeAgentId } from "../routing/session-key.js";
import type { RuntimeEnv } from "../runtime.js";
import { defaultRuntime } from "../runtime.js";
import { shortenHomePath } from "../utils.js";
import { createClackPrompter } from "../wizard/clack-prompter.js";
import { createQuietRuntime, requireValidConfig } from "./agents.command-shared.js";
@@ -70,7 +70,7 @@ export async function agentsDeleteCommand(
const result = pruneAgentConfig(cfg, agentId);
await writeConfigFile(result.config);
if (!opts.json) runtime.log(`Updated ${shortenHomePath(CONFIG_PATH_CLAWDBOT)}`);
if (!opts.json) logConfigUpdated(runtime);
const quietRuntime = opts.json ? createQuietRuntime(runtime) : runtime;
await moveToTrash(workspaceDir, quietRuntime);

View File

@@ -4,7 +4,8 @@ import path from "node:path";
import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agents/agent-scope.js";
import { identityHasValues, parseIdentityMarkdown } from "../agents/identity-file.js";
import { DEFAULT_IDENTITY_FILENAME } from "../agents/workspace.js";
import { CONFIG_PATH_CLAWDBOT, writeConfigFile } from "../config/config.js";
import { writeConfigFile } from "../config/config.js";
import { logConfigUpdated } from "../config/logging.js";
import type { IdentityConfig } from "../config/types.js";
import { normalizeAgentId } from "../routing/session-key.js";
import type { RuntimeEnv } from "../runtime.js";
@@ -211,7 +212,7 @@ export async function agentsSetIdentityCommand(
return;
}
runtime.log(`Updated ${shortenHomePath(CONFIG_PATH_CLAWDBOT)}`);
logConfigUpdated(runtime);
runtime.log(`Agent: ${agentId}`);
if (nextIdentity.name) runtime.log(`Name: ${nextIdentity.name}`);
if (nextIdentity.theme) runtime.log(`Theme: ${nextIdentity.theme}`);

View File

@@ -1,16 +1,12 @@
import { formatCliCommand } from "../cli/command-format.js";
import type { ClawdbotConfig } from "../config/config.js";
import {
CONFIG_PATH_CLAWDBOT,
readConfigFileSnapshot,
resolveGatewayPort,
writeConfigFile,
} from "../config/config.js";
import { readConfigFileSnapshot, resolveGatewayPort, writeConfigFile } from "../config/config.js";
import { logConfigUpdated } from "../config/logging.js";
import { ensureControlUiAssetsBuilt } from "../infra/control-ui-assets.js";
import type { RuntimeEnv } from "../runtime.js";
import { defaultRuntime } from "../runtime.js";
import { note } from "../terminal/note.js";
import { resolveUserPath, shortenHomePath } from "../utils.js";
import { resolveUserPath } from "../utils.js";
import { createClackPrompter } from "../wizard/clack-prompter.js";
import { WizardCancelledError } from "../wizard/prompts.js";
import { removeChannelConfigWizard } from "./configure.channels.js";
@@ -253,7 +249,7 @@ export async function runConfigureWizard(
mode,
});
await writeConfigFile(remoteConfig);
runtime.log(`Updated ${shortenHomePath(CONFIG_PATH_CLAWDBOT)}`);
logConfigUpdated(runtime);
outro("Remote gateway configured.");
return;
}
@@ -286,7 +282,7 @@ export async function runConfigureWizard(
mode,
});
await writeConfigFile(nextConfig);
runtime.log(`Updated ${shortenHomePath(CONFIG_PATH_CLAWDBOT)}`);
logConfigUpdated(runtime);
};
if (opts.sections) {

View File

@@ -12,6 +12,7 @@ import {
import { formatCliCommand } from "../cli/command-format.js";
import type { ClawdbotConfig } from "../config/config.js";
import { CONFIG_PATH_CLAWDBOT, readConfigFileSnapshot, writeConfigFile } from "../config/config.js";
import { logConfigUpdated } from "../config/logging.js";
import { resolveGatewayService } from "../daemon/service.js";
import { resolveGatewayAuth } from "../gateway/auth.js";
import { buildGatewayConnectionDetails } from "../gateway/call.js";
@@ -270,7 +271,7 @@ export async function doctorCommand(
if (shouldWriteConfig) {
cfg = applyWizardMetadata(cfg, { command: "doctor", mode: resolveMode(cfg) });
await writeConfigFile(cfg);
runtime.log(`Updated ${shortenHomePath(CONFIG_PATH_CLAWDBOT)}`);
logConfigUpdated(runtime);
const backupPath = `${CONFIG_PATH_CLAWDBOT}.bak`;
if (fs.existsSync(backupPath)) {
runtime.log(`Backup: ${shortenHomePath(backupPath)}`);

View File

@@ -1,6 +1,6 @@
import { CONFIG_PATH_CLAWDBOT, loadConfig } from "../../config/config.js";
import { loadConfig } from "../../config/config.js";
import { logConfigUpdated } from "../../config/logging.js";
import type { RuntimeEnv } from "../../runtime.js";
import { shortenHomePath } from "../../utils.js";
import {
ensureFlagCompatibility,
normalizeAlias,
@@ -75,7 +75,7 @@ export async function modelsAliasesAddCommand(
};
});
runtime.log(`Updated ${shortenHomePath(CONFIG_PATH_CLAWDBOT)}`);
logConfigUpdated(runtime);
runtime.log(`Alias ${alias} -> ${resolved.provider}/${resolved.model}`);
}
@@ -106,7 +106,7 @@ export async function modelsAliasesRemoveCommand(aliasRaw: string, runtime: Runt
};
});
runtime.log(`Updated ${shortenHomePath(CONFIG_PATH_CLAWDBOT)}`);
logConfigUpdated(runtime);
if (
!updated.agents?.defaults?.models ||
Object.values(updated.agents.defaults.models).every((entry) => !entry?.alias?.trim())

View File

@@ -16,14 +16,10 @@ import {
import { resolveDefaultAgentWorkspaceDir } from "../../agents/workspace.js";
import { parseDurationMs } from "../../cli/parse-duration.js";
import { formatCliCommand } from "../../cli/command-format.js";
import {
CONFIG_PATH_CLAWDBOT,
readConfigFileSnapshot,
type ClawdbotConfig,
} from "../../config/config.js";
import { readConfigFileSnapshot, type ClawdbotConfig } from "../../config/config.js";
import { logConfigUpdated } from "../../config/logging.js";
import type { RuntimeEnv } from "../../runtime.js";
import { stylePromptHint, stylePromptMessage } from "../../terminal/prompt-style.js";
import { shortenHomePath } from "../../utils.js";
import { applyAuthProfileConfig } from "../onboard-auth.js";
import { isRemoteEnvironment } from "../oauth-env.js";
import { openUrl } from "../onboard-helpers.js";
@@ -118,7 +114,7 @@ export async function modelsAuthSetupTokenCommand(
}),
);
runtime.log(`Updated ${shortenHomePath(CONFIG_PATH_CLAWDBOT)}`);
logConfigUpdated(runtime);
runtime.log(`Auth profile: ${CLAUDE_CLI_PROFILE_ID} (anthropic/oauth)`);
}
@@ -160,7 +156,7 @@ export async function modelsAuthPasteTokenCommand(
await updateConfig((cfg) => applyAuthProfileConfig(cfg, { profileId, provider, mode: "token" }));
runtime.log(`Updated ${shortenHomePath(CONFIG_PATH_CLAWDBOT)}`);
logConfigUpdated(runtime);
runtime.log(`Auth profile: ${profileId} (${provider}/token)`);
}
@@ -426,7 +422,7 @@ export async function modelsAuthLoginCommand(opts: LoginOptions, runtime: Runtim
return next;
});
runtime.log(`Updated ${shortenHomePath(CONFIG_PATH_CLAWDBOT)}`);
logConfigUpdated(runtime);
for (const profile of result.profiles) {
runtime.log(
`Auth profile: ${profile.profileId} (${profile.credential.provider}/${credentialMode(profile.credential)})`,

View File

@@ -1,7 +1,7 @@
import { buildModelAliasIndex, resolveModelRefFromString } from "../../agents/model-selection.js";
import { CONFIG_PATH_CLAWDBOT, loadConfig } from "../../config/config.js";
import { loadConfig } from "../../config/config.js";
import { logConfigUpdated } from "../../config/logging.js";
import type { RuntimeEnv } from "../../runtime.js";
import { shortenHomePath } from "../../utils.js";
import {
DEFAULT_PROVIDER,
ensureFlagCompatibility,
@@ -79,7 +79,7 @@ export async function modelsFallbacksAddCommand(modelRaw: string, runtime: Runti
};
});
runtime.log(`Updated ${shortenHomePath(CONFIG_PATH_CLAWDBOT)}`);
logConfigUpdated(runtime);
runtime.log(`Fallbacks: ${(updated.agents?.defaults?.model?.fallbacks ?? []).join(", ")}`);
}
@@ -125,7 +125,7 @@ export async function modelsFallbacksRemoveCommand(modelRaw: string, runtime: Ru
};
});
runtime.log(`Updated ${shortenHomePath(CONFIG_PATH_CLAWDBOT)}`);
logConfigUpdated(runtime);
runtime.log(`Fallbacks: ${(updated.agents?.defaults?.model?.fallbacks ?? []).join(", ")}`);
}
@@ -149,6 +149,6 @@ export async function modelsFallbacksClearCommand(runtime: RuntimeEnv) {
};
});
runtime.log(`Updated ${shortenHomePath(CONFIG_PATH_CLAWDBOT)}`);
logConfigUpdated(runtime);
runtime.log("Fallback list cleared.");
}

View File

@@ -1,7 +1,7 @@
import { buildModelAliasIndex, resolveModelRefFromString } from "../../agents/model-selection.js";
import { CONFIG_PATH_CLAWDBOT, loadConfig } from "../../config/config.js";
import { loadConfig } from "../../config/config.js";
import { logConfigUpdated } from "../../config/logging.js";
import type { RuntimeEnv } from "../../runtime.js";
import { shortenHomePath } from "../../utils.js";
import {
DEFAULT_PROVIDER,
ensureFlagCompatibility,
@@ -79,7 +79,7 @@ export async function modelsImageFallbacksAddCommand(modelRaw: string, runtime:
};
});
runtime.log(`Updated ${shortenHomePath(CONFIG_PATH_CLAWDBOT)}`);
logConfigUpdated(runtime);
runtime.log(
`Image fallbacks: ${(updated.agents?.defaults?.imageModel?.fallbacks ?? []).join(", ")}`,
);
@@ -127,7 +127,7 @@ export async function modelsImageFallbacksRemoveCommand(modelRaw: string, runtim
};
});
runtime.log(`Updated ${shortenHomePath(CONFIG_PATH_CLAWDBOT)}`);
logConfigUpdated(runtime);
runtime.log(
`Image fallbacks: ${(updated.agents?.defaults?.imageModel?.fallbacks ?? []).join(", ")}`,
);
@@ -153,6 +153,6 @@ export async function modelsImageFallbacksClearCommand(runtime: RuntimeEnv) {
};
});
runtime.log(`Updated ${shortenHomePath(CONFIG_PATH_CLAWDBOT)}`);
logConfigUpdated(runtime);
runtime.log("Image fallback list cleared.");
}

View File

@@ -2,9 +2,9 @@ import { cancel, multiselect as clackMultiselect, isCancel } from "@clack/prompt
import { resolveApiKeyForProvider } from "../../agents/model-auth.js";
import { type ModelScanResult, scanOpenRouterModels } from "../../agents/model-scan.js";
import { withProgressTotals } from "../../cli/progress.js";
import { CONFIG_PATH_CLAWDBOT, loadConfig } from "../../config/config.js";
import { loadConfig } from "../../config/config.js";
import { logConfigUpdated } from "../../config/logging.js";
import type { RuntimeEnv } from "../../runtime.js";
import { shortenHomePath } from "../../utils.js";
import {
stylePromptHint,
stylePromptMessage,
@@ -344,7 +344,7 @@ export async function modelsScanCommand(
return;
}
runtime.log(`Updated ${shortenHomePath(CONFIG_PATH_CLAWDBOT)}`);
logConfigUpdated(runtime);
runtime.log(`Fallbacks: ${selected.join(", ")}`);
if (selectedImages.length > 0) {
runtime.log(`Image fallbacks: ${selectedImages.join(", ")}`);

View File

@@ -1,7 +1,6 @@
import { CONFIG_PATH_CLAWDBOT } from "../../config/config.js";
import { logConfigUpdated } from "../../config/logging.js";
import type { RuntimeEnv } from "../../runtime.js";
import { resolveModelTarget, updateConfig } from "./shared.js";
import { shortenHomePath } from "../../utils.js";
export async function modelsSetImageCommand(modelRaw: string, runtime: RuntimeEnv) {
const updated = await updateConfig((cfg) => {
@@ -28,6 +27,6 @@ export async function modelsSetImageCommand(modelRaw: string, runtime: RuntimeEn
};
});
runtime.log(`Updated ${shortenHomePath(CONFIG_PATH_CLAWDBOT)}`);
logConfigUpdated(runtime);
runtime.log(`Image model: ${updated.agents?.defaults?.imageModel?.primary ?? modelRaw}`);
}

View File

@@ -1,7 +1,6 @@
import { CONFIG_PATH_CLAWDBOT } from "../../config/config.js";
import { logConfigUpdated } from "../../config/logging.js";
import type { RuntimeEnv } from "../../runtime.js";
import { resolveModelTarget, updateConfig } from "./shared.js";
import { shortenHomePath } from "../../utils.js";
export async function modelsSetCommand(modelRaw: string, runtime: RuntimeEnv) {
const updated = await updateConfig((cfg) => {
@@ -28,6 +27,6 @@ export async function modelsSetCommand(modelRaw: string, runtime: RuntimeEnv) {
};
});
runtime.log(`Updated ${shortenHomePath(CONFIG_PATH_CLAWDBOT)}`);
logConfigUpdated(runtime);
runtime.log(`Default model: ${updated.agents?.defaults?.model?.primary ?? modelRaw}`);
}

View File

@@ -1,8 +1,8 @@
import type { ClawdbotConfig } from "../../config/config.js";
import { CONFIG_PATH_CLAWDBOT, resolveGatewayPort, writeConfigFile } from "../../config/config.js";
import { resolveGatewayPort, writeConfigFile } from "../../config/config.js";
import { logConfigUpdated } from "../../config/logging.js";
import type { RuntimeEnv } from "../../runtime.js";
import { formatCliCommand } from "../../cli/command-format.js";
import { shortenHomePath } from "../../utils.js";
import { DEFAULT_GATEWAY_DAEMON_RUNTIME } from "../daemon-runtime.js";
import { healthCommand } from "../health.js";
import {
@@ -75,7 +75,7 @@ export async function runNonInteractiveOnboardingLocal(params: {
nextConfig = applyWizardMetadata(nextConfig, { command: "onboard", mode });
await writeConfigFile(nextConfig);
runtime.log(`Updated ${shortenHomePath(CONFIG_PATH_CLAWDBOT)}`);
logConfigUpdated(runtime);
await ensureWorkspaceAndSessions(workspaceDir, runtime, {
skipBootstrap: Boolean(nextConfig.agents?.defaults?.skipBootstrap),

View File

@@ -1,10 +1,10 @@
import type { ClawdbotConfig } from "../../config/config.js";
import { CONFIG_PATH_CLAWDBOT, writeConfigFile } from "../../config/config.js";
import { writeConfigFile } from "../../config/config.js";
import { logConfigUpdated } from "../../config/logging.js";
import type { RuntimeEnv } from "../../runtime.js";
import { formatCliCommand } from "../../cli/command-format.js";
import { applyWizardMetadata } from "../onboard-helpers.js";
import type { OnboardOptions } from "../onboard-types.js";
import { shortenHomePath } from "../../utils.js";
export async function runNonInteractiveOnboardingRemote(params: {
opts: OnboardOptions;
@@ -34,7 +34,7 @@ export async function runNonInteractiveOnboardingRemote(params: {
};
nextConfig = applyWizardMetadata(nextConfig, { command: "onboard", mode });
await writeConfigFile(nextConfig);
runtime.log(`Updated ${shortenHomePath(CONFIG_PATH_CLAWDBOT)}`);
logConfigUpdated(runtime);
const payload = {
mode,

View File

@@ -4,6 +4,7 @@ import JSON5 from "json5";
import { DEFAULT_AGENT_WORKSPACE_DIR, ensureAgentWorkspace } from "../agents/workspace.js";
import { type ClawdbotConfig, CONFIG_PATH_CLAWDBOT, writeConfigFile } from "../config/config.js";
import { formatConfigPath, logConfigUpdated } from "../config/logging.js";
import { resolveSessionTranscriptsDir } from "../config/sessions.js";
import type { RuntimeEnv } from "../runtime.js";
import { defaultRuntime } from "../runtime.js";
@@ -53,13 +54,13 @@ export async function setupCommand(
if (!existingRaw.exists || defaults.workspace !== workspace) {
await writeConfigFile(next);
runtime.log(
!existingRaw.exists
? `Wrote ${shortenHomePath(CONFIG_PATH_CLAWDBOT)}`
: `Updated ${shortenHomePath(CONFIG_PATH_CLAWDBOT)} (set agents.defaults.workspace)`,
);
if (!existingRaw.exists) {
runtime.log(`Wrote ${formatConfigPath()}`);
} else {
logConfigUpdated(runtime, { suffix: "(set agents.defaults.workspace)" });
}
} else {
runtime.log(`Config OK: ${shortenHomePath(CONFIG_PATH_CLAWDBOT)}`);
runtime.log(`Config OK: ${formatConfigPath()}`);
}
const ws = await ensureAgentWorkspace({

View File

@@ -12,6 +12,7 @@ import {
import { runCommandWithTimeout } from "../process/exec.js";
import { defaultRuntime } from "../runtime.js";
import { formatCliCommand } from "../cli/command-format.js";
import { displayPath } from "../utils.js";
import {
buildDefaultHookUrl,
buildGogWatchServeArgs,
@@ -276,7 +277,7 @@ export async function runGmailSetup(opts: GmailSetupOptions) {
defaultRuntime.log(`- subscription: ${subscription}`);
defaultRuntime.log(`- push endpoint: ${pushEndpoint}`);
defaultRuntime.log(`- hook url: ${hookUrl}`);
defaultRuntime.log(`- config: ${CONFIG_PATH_CLAWDBOT}`);
defaultRuntime.log(`- config: ${displayPath(CONFIG_PATH_CLAWDBOT)}`);
defaultRuntime.log(`Next: ${formatCliCommand("clawdbot webhooks gmail run")}`);
}

View File

@@ -3,7 +3,7 @@ import { intro, note, outro, select, spinner, text, isCancel } from "@clack/prom
import { ensureAuthProfileStore, upsertAuthProfile } from "../agents/auth-profiles.js";
import { updateConfig } from "../commands/models/shared.js";
import { applyAuthProfileConfig } from "../commands/onboard-auth.js";
import { CONFIG_PATH_CLAWDBOT } from "../config/config.js";
import { logConfigUpdated } from "../config/logging.js";
import type { RuntimeEnv } from "../runtime.js";
import { stylePromptTitle } from "../terminal/prompt-style.js";
import {
@@ -236,7 +236,7 @@ export async function githubCopilotLoginCommand(
}),
);
runtime.log(`Updated ${CONFIG_PATH_CLAWDBOT}`);
logConfigUpdated(runtime);
runtime.log(`Auth profile: ${profileId} (github-copilot/oauth)`);
runtime.log(`Base URL: ${resolveGithubCopilotBaseUrl(enterpriseDomain ?? undefined)}`);

View File

@@ -1,5 +1,5 @@
import { visibleWidth } from "./ansi.js";
import { shortenHomeInString } from "../utils.js";
import { displayString } from "../utils.js";
type Align = "left" | "right" | "center";
@@ -172,7 +172,7 @@ export function renderTable(opts: RenderTableOptions): string {
const rows = opts.rows.map((row) => {
const next: Record<string, string> = {};
for (const [key, value] of Object.entries(row)) {
next[key] = shortenHomeInString(value);
next[key] = displayString(value);
}
return next;
});

View File

@@ -249,6 +249,14 @@ export function shortenHomeInString(input: string): string {
return input.split(home).join("~");
}
export function displayPath(input: string): string {
return shortenHomePath(input);
}
export function displayString(input: string): string {
return shortenHomeInString(input);
}
export function formatTerminalLink(
label: string,
url: string,

View File

@@ -29,12 +29,12 @@ import type {
import { formatCliCommand } from "../cli/command-format.js";
import type { ClawdbotConfig } from "../config/config.js";
import {
CONFIG_PATH_CLAWDBOT,
DEFAULT_GATEWAY_PORT,
readConfigFileSnapshot,
resolveGatewayPort,
writeConfigFile,
} from "../config/config.js";
import { logConfigUpdated } from "../config/logging.js";
import type { RuntimeEnv } from "../runtime.js";
import { defaultRuntime } from "../runtime.js";
import { resolveUserPath } from "../utils.js";
@@ -306,7 +306,7 @@ export async function runOnboardingWizard(
let nextConfig = await promptRemoteGatewayConfig(baseConfig, prompter);
nextConfig = applyWizardMetadata(nextConfig, { command: "onboard", mode });
await writeConfigFile(nextConfig);
runtime.log(`Updated ${CONFIG_PATH_CLAWDBOT}`);
logConfigUpdated(runtime);
await prompter.outro("Remote gateway configured.");
return;
}
@@ -405,7 +405,7 @@ export async function runOnboardingWizard(
}
await writeConfigFile(nextConfig);
runtime.log(`Updated ${CONFIG_PATH_CLAWDBOT}`);
logConfigUpdated(runtime);
await ensureWorkspaceAndSessions(workspaceDir, runtime, {
skipBootstrap: Boolean(nextConfig.agents?.defaults?.skipBootstrap),
});