refactor(logging): split config + subsystem imports

This commit is contained in:
Peter Steinberger
2026-01-18 23:24:17 +00:00
parent ee36e12f81
commit 50fdd514ae
48 changed files with 109 additions and 72 deletions

View File

@@ -4,7 +4,7 @@ import type { ThinkLevel } from "../auto-reply/thinking.js";
import type { ClawdbotConfig } from "../config/config.js"; import type { ClawdbotConfig } from "../config/config.js";
import { isTruthyEnvValue } from "../infra/env.js"; import { isTruthyEnvValue } from "../infra/env.js";
import { shouldLogVerbose } from "../globals.js"; import { shouldLogVerbose } from "../globals.js";
import { createSubsystemLogger } from "../logging.js"; import { createSubsystemLogger } from "../logging/subsystem.js";
import { runCommandWithTimeout } from "../process/exec.js"; import { runCommandWithTimeout } from "../process/exec.js";
import { resolveUserPath } from "../utils.js"; import { resolveUserPath } from "../utils.js";
import { resolveClawdbotDocsPath } from "./docs-path.js"; import { resolveClawdbotDocsPath } from "./docs-path.js";

View File

@@ -1,3 +1,3 @@
import { createSubsystemLogger } from "../../logging.js"; import { createSubsystemLogger } from "../../logging/subsystem.js";
export const log = createSubsystemLogger("agent/embedded"); export const log = createSubsystemLogger("agent/embedded");

View File

@@ -1,6 +1,6 @@
import { parseReplyDirectives } from "../auto-reply/reply/reply-directives.js"; import { parseReplyDirectives } from "../auto-reply/reply/reply-directives.js";
import { formatToolAggregate } from "../auto-reply/tool-meta.js"; import { formatToolAggregate } from "../auto-reply/tool-meta.js";
import { createSubsystemLogger } from "../logging.js"; import { createSubsystemLogger } from "../logging/subsystem.js";
import type { InlineCodeState } from "../markdown/code-spans.js"; import type { InlineCodeState } from "../markdown/code-spans.js";
import { buildCodeSpanIndex, createInlineCodeState } from "../markdown/code-spans.js"; import { buildCodeSpanIndex, createInlineCodeState } from "../markdown/code-spans.js";
import { EmbeddedBlockChunker } from "./pi-embedded-block-chunker.js"; import { EmbeddedBlockChunker } from "./pi-embedded-block-chunker.js";

View File

@@ -3,7 +3,7 @@ import path from "node:path";
import chokidar, { type FSWatcher } from "chokidar"; import chokidar, { type FSWatcher } from "chokidar";
import type { ClawdbotConfig } from "../../config/config.js"; import type { ClawdbotConfig } from "../../config/config.js";
import { createSubsystemLogger } from "../../logging.js"; import { createSubsystemLogger } from "../../logging/subsystem.js";
import { CONFIG_DIR, resolveUserPath } from "../../utils.js"; import { CONFIG_DIR, resolveUserPath } from "../../utils.js";
type SkillsChangeEvent = { type SkillsChangeEvent = {

View File

@@ -8,7 +8,7 @@ import {
} from "@mariozechner/pi-coding-agent"; } from "@mariozechner/pi-coding-agent";
import type { ClawdbotConfig } from "../../config/config.js"; import type { ClawdbotConfig } from "../../config/config.js";
import { createSubsystemLogger } from "../../logging.js"; import { createSubsystemLogger } from "../../logging/subsystem.js";
import { CONFIG_DIR, resolveUserPath } from "../../utils.js"; import { CONFIG_DIR, resolveUserPath } from "../../utils.js";
import { resolveBundledSkillsDir } from "./bundled-dir.js"; import { resolveBundledSkillsDir } from "./bundled-dir.js";
import { shouldIncludeSkill } from "./config.js"; import { shouldIncludeSkill } from "./config.js";

View File

@@ -1,7 +1,7 @@
import type { AgentToolResult } from "@mariozechner/pi-agent-core"; import type { AgentToolResult } from "@mariozechner/pi-agent-core";
import type { ImageContent } from "@mariozechner/pi-ai"; import type { ImageContent } from "@mariozechner/pi-ai";
import { createSubsystemLogger } from "../logging.js"; import { createSubsystemLogger } from "../logging/subsystem.js";
import { getImageMetadata, resizeToJpeg } from "../media/image-ops.js"; import { getImageMetadata, resizeToJpeg } from "../media/image-ops.js";
type ToolContentBlock = AgentToolResult<unknown>["content"][number]; type ToolContentBlock = AgentToolResult<unknown>["content"][number];

View File

@@ -2,7 +2,7 @@ import crypto from "node:crypto";
import { callGateway } from "../../gateway/call.js"; import { callGateway } from "../../gateway/call.js";
import { formatErrorMessage } from "../../infra/errors.js"; import { formatErrorMessage } from "../../infra/errors.js";
import { createSubsystemLogger } from "../../logging.js"; import { createSubsystemLogger } from "../../logging/subsystem.js";
import type { GatewayMessageChannel } from "../../utils/message-channel.js"; import type { GatewayMessageChannel } from "../../utils/message-channel.js";
import { AGENT_LANE_NESTED } from "../lanes.js"; import { AGENT_LANE_NESTED } from "../lanes.js";
import { readLatestAssistantReply, runAgentStep } from "./agent-step.js"; import { readLatestAssistantReply, runAgentStep } from "./agent-step.js";

View File

@@ -5,7 +5,7 @@ import path from "node:path";
import WebSocket from "ws"; import WebSocket from "ws";
import { ensurePortAvailable } from "../infra/ports.js"; import { ensurePortAvailable } from "../infra/ports.js";
import { createSubsystemLogger } from "../logging.js"; import { createSubsystemLogger } from "../logging/subsystem.js";
import { CONFIG_DIR } from "../utils.js"; import { CONFIG_DIR } from "../utils.js";
import { getHeadersWithAuth, normalizeCdpWsUrl } from "./cdp.js"; import { getHeadersWithAuth, normalizeCdpWsUrl } from "./cdp.js";
import { appendCdpPath } from "./cdp.helpers.js"; import { appendCdpPath } from "./cdp.helpers.js";

View File

@@ -2,7 +2,7 @@ import type { Server } from "node:http";
import express from "express"; import express from "express";
import { loadConfig } from "../config/config.js"; import { loadConfig } from "../config/config.js";
import { createSubsystemLogger } from "../logging.js"; import { createSubsystemLogger } from "../logging/subsystem.js";
import { resolveBrowserConfig, resolveProfile, shouldStartLocalBrowserServer } from "./config.js"; import { resolveBrowserConfig, resolveProfile, shouldStartLocalBrowserServer } from "./config.js";
import { ensureChromeExtensionRelayServer } from "./extension-relay.js"; import { ensureChromeExtensionRelayServer } from "./extension-relay.js";
import { registerBrowserRoutes } from "./routes/index.js"; import { registerBrowserRoutes } from "./routes/index.js";

View File

@@ -15,11 +15,8 @@ import { setGatewayWsLogStyle } from "../../gateway/ws-logging.js";
import { setVerbose } from "../../globals.js"; import { setVerbose } from "../../globals.js";
import { GatewayLockError } from "../../infra/gateway-lock.js"; import { GatewayLockError } from "../../infra/gateway-lock.js";
import { formatPortDiagnostics, inspectPortUsage } from "../../infra/ports.js"; import { formatPortDiagnostics, inspectPortUsage } from "../../infra/ports.js";
import { import { setConsoleSubsystemFilter, setConsoleTimestampPrefix } from "../../logging/console.js";
createSubsystemLogger, import { createSubsystemLogger } from "../../logging/subsystem.js";
setConsoleSubsystemFilter,
setConsoleTimestampPrefix,
} from "../../logging.js";
import { defaultRuntime } from "../../runtime.js"; import { defaultRuntime } from "../../runtime.js";
import { forceFreePortAndWait } from "../ports.js"; import { forceFreePortAndWait } from "../ports.js";
import { ensureDevGatewayConfig } from "./dev.js"; import { ensureDevGatewayConfig } from "./dev.js";

View File

@@ -1,3 +1,8 @@
import { listChannelPlugins } from "../../channels/plugins/index.js";
import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../../agents/agent-scope.js";
import { loadConfig } from "../../config/config.js";
import { createSubsystemLogger } from "../../logging/subsystem.js";
import { loadClawdbotPlugins } from "../../plugins/loader.js";
import { VERSION } from "../../version.js"; import { VERSION } from "../../version.js";
import { resolveCliChannelOptions } from "../channel-options.js"; import { resolveCliChannelOptions } from "../channel-options.js";

View File

@@ -3,7 +3,7 @@ import path from "node:path";
import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../../agents/agent-scope.js"; import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../../agents/agent-scope.js";
import type { ChannelPluginCatalogEntry } from "../../channels/plugins/catalog.js"; import type { ChannelPluginCatalogEntry } from "../../channels/plugins/catalog.js";
import type { ClawdbotConfig } from "../../config/config.js"; import type { ClawdbotConfig } from "../../config/config.js";
import { createSubsystemLogger } from "../../logging.js"; import { createSubsystemLogger } from "../../logging/subsystem.js";
import { recordPluginInstall } from "../../plugins/installs.js"; import { recordPluginInstall } from "../../plugins/installs.js";
import { enablePluginInConfig } from "../../plugins/enable.js"; import { enablePluginInConfig } from "../../plugins/enable.js";
import { loadClawdbotPlugins } from "../../plugins/loader.js"; import { loadClawdbotPlugins } from "../../plugins/loader.js";

View File

@@ -9,7 +9,7 @@ import {
import { danger } from "../../globals.js"; import { danger } from "../../globals.js";
import { formatDurationSeconds } from "../../infra/format-duration.js"; import { formatDurationSeconds } from "../../infra/format-duration.js";
import { enqueueSystemEvent } from "../../infra/system-events.js"; import { enqueueSystemEvent } from "../../infra/system-events.js";
import { createSubsystemLogger } from "../../logging.js"; import { createSubsystemLogger } from "../../logging/subsystem.js";
import { resolveAgentRoute } from "../../routing/resolve-route.js"; import { resolveAgentRoute } from "../../routing/resolve-route.js";
import { import {
normalizeDiscordSlug, normalizeDiscordSlug,
@@ -22,7 +22,7 @@ import { resolveDiscordChannelInfo } from "./message-utils.js";
type LoadedConfig = ReturnType<typeof import("../../config/config.js").loadConfig>; type LoadedConfig = ReturnType<typeof import("../../config/config.js").loadConfig>;
type RuntimeEnv = import("../../runtime.js").RuntimeEnv; type RuntimeEnv = import("../../runtime.js").RuntimeEnv;
type Logger = ReturnType<typeof import("../../logging.js").createSubsystemLogger>; type Logger = ReturnType<typeof import("../../logging/subsystem.js").createSubsystemLogger>;
export type DiscordMessageEvent = Parameters<MessageCreateListener["handle"]>[0]; export type DiscordMessageEvent = Parameters<MessageCreateListener["handle"]>[0];

View File

@@ -6,7 +6,7 @@ import type { CliDeps } from "../cli/deps.js";
import type { ClawdbotConfig } from "../config/config.js"; import type { ClawdbotConfig } from "../config/config.js";
import { resolveMainSessionKey } from "../config/sessions/main-session.js"; import { resolveMainSessionKey } from "../config/sessions/main-session.js";
import { agentCommand } from "../commands/agent.js"; import { agentCommand } from "../commands/agent.js";
import { createSubsystemLogger } from "../logging.js"; import { createSubsystemLogger } from "../logging/subsystem.js";
import { type RuntimeEnv, defaultRuntime } from "../runtime.js"; import { type RuntimeEnv, defaultRuntime } from "../runtime.js";
const log = createSubsystemLogger("gateway/boot"); const log = createSubsystemLogger("gateway/boot");

View File

@@ -4,7 +4,7 @@ import type { ChannelAccountSnapshot } from "../channels/plugins/types.js";
import type { ClawdbotConfig } from "../config/config.js"; import type { ClawdbotConfig } from "../config/config.js";
import { formatErrorMessage } from "../infra/errors.js"; import { formatErrorMessage } from "../infra/errors.js";
import { resetDirectoryCache } from "../infra/outbound/target-resolver.js"; import { resetDirectoryCache } from "../infra/outbound/target-resolver.js";
import type { createSubsystemLogger } from "../logging.js"; import type { createSubsystemLogger } from "../logging/subsystem.js";
import { DEFAULT_ACCOUNT_ID } from "../routing/session-key.js"; import { DEFAULT_ACCOUNT_ID } from "../routing/session-key.js";
import type { RuntimeEnv } from "../runtime.js"; import type { RuntimeEnv } from "../runtime.js";

View File

@@ -7,7 +7,7 @@ import {
import type { WebSocketServer } from "ws"; import type { WebSocketServer } from "ws";
import { handleA2uiHttpRequest } from "../canvas-host/a2ui.js"; import { handleA2uiHttpRequest } from "../canvas-host/a2ui.js";
import type { CanvasHostHandler } from "../canvas-host/server.js"; import type { CanvasHostHandler } from "../canvas-host/server.js";
import type { createSubsystemLogger } from "../logging.js"; import type { createSubsystemLogger } from "../logging/subsystem.js";
import { handleSlackHttpRequest } from "../slack/http/index.js"; import { handleSlackHttpRequest } from "../slack/http/index.js";
import { handleControlUiHttpRequest } from "./control-ui.js"; import { handleControlUiHttpRequest } from "./control-ui.js";
import { import {

View File

@@ -3,7 +3,7 @@ import { WebSocketServer } from "ws";
import { CANVAS_HOST_PATH } from "../canvas-host/a2ui.js"; import { CANVAS_HOST_PATH } from "../canvas-host/a2ui.js";
import { type CanvasHostHandler, createCanvasHostHandler } from "../canvas-host/server.js"; import { type CanvasHostHandler, createCanvasHostHandler } from "../canvas-host/server.js";
import type { CliDeps } from "../cli/deps.js"; import type { CliDeps } from "../cli/deps.js";
import type { createSubsystemLogger } from "../logging.js"; import type { createSubsystemLogger } from "../logging/subsystem.js";
import type { RuntimeEnv } from "../runtime.js"; import type { RuntimeEnv } from "../runtime.js";
import type { ResolvedGatewayAuth } from "./auth.js"; import type { ResolvedGatewayAuth } from "./auth.js";
import type { ChatAbortControllerEntry } from "./chat-abort.js"; import type { ChatAbortControllerEntry } from "./chat-abort.js";

View File

@@ -1,5 +1,5 @@
import type { WebSocketServer } from "ws"; import type { WebSocketServer } from "ws";
import type { createSubsystemLogger } from "../logging.js"; import type { createSubsystemLogger } from "../logging/subsystem.js";
import type { ResolvedGatewayAuth } from "./auth.js"; import type { ResolvedGatewayAuth } from "./auth.js";
import { attachGatewayWsConnectionHandler } from "./server/ws-connection.js"; import { attachGatewayWsConnectionHandler } from "./server/ws-connection.js";
import type { GatewayWsClient } from "./server/ws-types.js"; import type { GatewayWsClient } from "./server/ws-types.js";

View File

@@ -7,7 +7,7 @@ import { runCronIsolatedAgentTurn } from "../../cron/isolated-agent.js";
import type { CronJob } from "../../cron/types.js"; import type { CronJob } from "../../cron/types.js";
import { requestHeartbeatNow } from "../../infra/heartbeat-wake.js"; import { requestHeartbeatNow } from "../../infra/heartbeat-wake.js";
import { enqueueSystemEvent } from "../../infra/system-events.js"; import { enqueueSystemEvent } from "../../infra/system-events.js";
import type { createSubsystemLogger } from "../../logging.js"; import type { createSubsystemLogger } from "../../logging/subsystem.js";
import type { HookMessageChannel, HooksConfigResolved } from "../hooks.js"; import type { HookMessageChannel, HooksConfigResolved } from "../hooks.js";
import { createHooksRequestHandler } from "../server-http.js"; import { createHooksRequestHandler } from "../server-http.js";

View File

@@ -1,6 +1,6 @@
import type { IncomingMessage, ServerResponse } from "node:http"; import type { IncomingMessage, ServerResponse } from "node:http";
import type { createSubsystemLogger } from "../../logging.js"; import type { createSubsystemLogger } from "../../logging/subsystem.js";
import type { PluginRegistry } from "../../plugins/registry.js"; import type { PluginRegistry } from "../../plugins/registry.js";
type SubsystemLogger = ReturnType<typeof createSubsystemLogger>; type SubsystemLogger = ReturnType<typeof createSubsystemLogger>;

View File

@@ -3,7 +3,7 @@ import { randomUUID } from "node:crypto";
import type { WebSocket, WebSocketServer } from "ws"; import type { WebSocket, WebSocketServer } from "ws";
import { resolveCanvasHostUrl } from "../../infra/canvas-host-url.js"; import { resolveCanvasHostUrl } from "../../infra/canvas-host-url.js";
import { listSystemPresence, upsertPresence } from "../../infra/system-presence.js"; import { listSystemPresence, upsertPresence } from "../../infra/system-presence.js";
import type { createSubsystemLogger } from "../../logging.js"; import type { createSubsystemLogger } from "../../logging/subsystem.js";
import { isWebchatClient } from "../../utils/message-channel.js"; import { isWebchatClient } from "../../utils/message-channel.js";
import type { ResolvedGatewayAuth } from "../auth.js"; import type { ResolvedGatewayAuth } from "../auth.js";

View File

@@ -4,7 +4,7 @@ import os from "node:os";
import type { WebSocket } from "ws"; import type { WebSocket } from "ws";
import { upsertPresence } from "../../../infra/system-presence.js"; import { upsertPresence } from "../../../infra/system-presence.js";
import { rawDataToString } from "../../../infra/ws.js"; import { rawDataToString } from "../../../infra/ws.js";
import type { createSubsystemLogger } from "../../../logging.js"; import type { createSubsystemLogger } from "../../../logging/subsystem.js";
import { isGatewayCliClient, isWebchatClient } from "../../../utils/message-channel.js"; import { isGatewayCliClient, isWebchatClient } from "../../../utils/message-channel.js";
import type { ResolvedGatewayAuth } from "../../auth.js"; import type { ResolvedGatewayAuth } from "../../auth.js";
import { authorizeGatewayConnect } from "../../auth.js"; import { authorizeGatewayConnect } from "../../auth.js";

View File

@@ -1,7 +1,8 @@
import chalk from "chalk"; import chalk from "chalk";
import { isVerbose } from "../globals.js"; import { isVerbose } from "../globals.js";
import { parseAgentSessionKey } from "../routing/session-key.js"; import { parseAgentSessionKey } from "../routing/session-key.js";
import { createSubsystemLogger, shouldLogSubsystemToConsole } from "../logging.js"; import { shouldLogSubsystemToConsole } from "../logging/console.js";
import { createSubsystemLogger } from "../logging/subsystem.js";
import { getDefaultRedactPatterns, redactSensitiveText } from "../logging/redact.js"; import { getDefaultRedactPatterns, redactSensitiveText } from "../logging/redact.js";
import { DEFAULT_WS_SLOW_MS, getGatewayWsLogStyle } from "./ws-logging.js"; import { DEFAULT_WS_SLOW_MS, getGatewayWsLogStyle } from "./ws-logging.js";

View File

@@ -8,7 +8,7 @@
import { type ChildProcess, spawn } from "node:child_process"; import { type ChildProcess, spawn } from "node:child_process";
import { hasBinary } from "../agents/skills.js"; import { hasBinary } from "../agents/skills.js";
import type { ClawdbotConfig } from "../config/config.js"; import type { ClawdbotConfig } from "../config/config.js";
import { createSubsystemLogger } from "../logging.js"; import { createSubsystemLogger } from "../logging/subsystem.js";
import { runCommandWithTimeout } from "../process/exec.js"; import { runCommandWithTimeout } from "../process/exec.js";
import { import {
buildGogWatchServeArgs, buildGogWatchServeArgs,

View File

@@ -4,19 +4,22 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import * as logging from "../logging.js"; import * as logging from "../logging.js";
const createService = vi.fn(); const mocks = vi.hoisted(() => ({
const shutdown = vi.fn(); createService: vi.fn(),
const registerUnhandledRejectionHandler = vi.fn(); shutdown: vi.fn(),
registerUnhandledRejectionHandler: vi.fn(),
const logWarn = vi.fn(); logWarn: vi.fn(),
const logDebug = vi.fn(); logDebug: vi.fn(),
const getLoggerInfo = vi.fn(); }));
const { createService, shutdown, registerUnhandledRejectionHandler, logWarn, logDebug } = mocks;
const asString = (value: unknown, fallback: string) => const asString = (value: unknown, fallback: string) =>
typeof value === "string" && value.trim() ? value : fallback; typeof value === "string" && value.trim() ? value : fallback;
vi.mock("../logger.js", () => { vi.mock("../logger.js", async () => {
const actual = await vi.importActual<typeof import("../logger.js")>("../logger.js");
return { return {
...actual,
logWarn: (message: string) => logWarn(message), logWarn: (message: string) => logWarn(message),
logDebug: (message: string) => logDebug(message), logDebug: (message: string) => logDebug(message),
logInfo: vi.fn(), logInfo: vi.fn(),
@@ -73,7 +76,6 @@ describe("gateway bonjour advertiser", () => {
registerUnhandledRejectionHandler.mockReset(); registerUnhandledRejectionHandler.mockReset();
logWarn.mockReset(); logWarn.mockReset();
logDebug.mockReset(); logDebug.mockReset();
getLoggerInfo.mockReset();
vi.useRealTimers(); vi.useRealTimers();
vi.restoreAllMocks(); vi.restoreAllMocks();
}); });

View File

@@ -22,7 +22,7 @@ import {
} from "../config/sessions.js"; } from "../config/sessions.js";
import type { AgentDefaultsConfig } from "../config/types.agent-defaults.js"; import type { AgentDefaultsConfig } from "../config/types.agent-defaults.js";
import { formatErrorMessage } from "../infra/errors.js"; import { formatErrorMessage } from "../infra/errors.js";
import { createSubsystemLogger } from "../logging.js"; import { createSubsystemLogger } from "../logging/subsystem.js";
import { getQueueSize } from "../process/command-queue.js"; import { getQueueSize } from "../process/command-queue.js";
import { defaultRuntime, type RuntimeEnv } from "../runtime.js"; import { defaultRuntime, type RuntimeEnv } from "../runtime.js";
import { normalizeAgentId } from "../routing/session-key.js"; import { normalizeAgentId } from "../routing/session-key.js";

View File

@@ -4,7 +4,7 @@ import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agents/agent
import type { ClawdbotConfig } from "../config/config.js"; import type { ClawdbotConfig } from "../config/config.js";
import type { NodeBridgeServer } from "./bridge/server.js"; import type { NodeBridgeServer } from "./bridge/server.js";
import { listNodePairing, updatePairedNodeMetadata } from "./node-pairing.js"; import { listNodePairing, updatePairedNodeMetadata } from "./node-pairing.js";
import { createSubsystemLogger } from "../logging.js"; import { createSubsystemLogger } from "../logging/subsystem.js";
import { bumpSkillsSnapshotVersion } from "../agents/skills/refresh.js"; import { bumpSkillsSnapshotVersion } from "../agents/skills/refresh.js";
type RemoteNodeRecord = { type RemoteNodeRecord = {

View File

@@ -7,7 +7,7 @@ import type { ClawdbotConfig } from "../config/config.js";
import { resolveOAuthDir, resolveStateDir } from "../config/paths.js"; import { resolveOAuthDir, resolveStateDir } from "../config/paths.js";
import type { SessionEntry } from "../config/sessions.js"; import type { SessionEntry } from "../config/sessions.js";
import { saveSessionStore } from "../config/sessions.js"; import { saveSessionStore } from "../config/sessions.js";
import { createSubsystemLogger } from "../logging.js"; import { createSubsystemLogger } from "../logging/subsystem.js";
import { import {
buildAgentMainSessionKey, buildAgentMainSessionKey,
DEFAULT_ACCOUNT_ID, DEFAULT_ACCOUNT_ID,

View File

@@ -1,5 +1,6 @@
import { danger, info, logVerboseConsole, success, warn } from "./globals.js"; import { danger, info, logVerboseConsole, success, warn } from "./globals.js";
import { createSubsystemLogger, getLogger } from "./logging.js"; import { getLogger } from "./logging/logger.js";
import { createSubsystemLogger } from "./logging/subsystem.js";
import { defaultRuntime, type RuntimeEnv } from "./runtime.js"; import { defaultRuntime, type RuntimeEnv } from "./runtime.js";
const subsystemPrefixRe = /^([a-z][a-z0-9-]{1,20}):\s+(.*)$/i; const subsystemPrefixRe = /^([a-z][a-z0-9-]{1,20}):\s+(.*)$/i;

22
src/logging/config.ts Normal file
View File

@@ -0,0 +1,22 @@
import fs from "node:fs";
import json5 from "json5";
import { resolveConfigPath } from "../config/paths.js";
import type { ClawdbotConfig } from "../config/types.js";
type LoggingConfig = ClawdbotConfig["logging"];
export function readLoggingConfig(): LoggingConfig | undefined {
const configPath = resolveConfigPath();
try {
if (!fs.existsSync(configPath)) return undefined;
const raw = fs.readFileSync(configPath, "utf-8");
const parsed = json5.parse(raw) as Record<string, unknown>;
const logging = parsed?.logging;
if (!logging || typeof logging !== "object" || Array.isArray(logging)) return undefined;
return logging as LoggingConfig;
} catch {
return undefined;
}
}

View File

@@ -1,11 +1,12 @@
import { createRequire } from "node:module"; import { createRequire } from "node:module";
import util from "node:util"; import util from "node:util";
import type { ClawdbotConfig } from "../config/config.js"; import type { ClawdbotConfig } from "../config/types.js";
import { isVerbose } from "../globals.js"; import { isVerbose } from "../globals.js";
import { stripAnsi } from "../terminal/ansi.js"; import { stripAnsi } from "../terminal/ansi.js";
import { type LogLevel, normalizeLogLevel } from "./levels.js"; import { type LogLevel, normalizeLogLevel } from "./levels.js";
import { getLogger, type LoggerSettings } from "./logger.js"; import { getLogger, type LoggerSettings } from "./logger.js";
import { readLoggingConfig } from "./config.js";
import { loggingState } from "./state.js"; import { loggingState } from "./state.js";
export type ConsoleStyle = "pretty" | "compact" | "json"; export type ConsoleStyle = "pretty" | "compact" | "json";
@@ -31,10 +32,9 @@ function normalizeConsoleStyle(style?: string): ConsoleStyle {
} }
function resolveConsoleSettings(): ConsoleSettings { function resolveConsoleSettings(): ConsoleSettings {
let cfg: ClawdbotConfig["logging"] | undefined; let cfg: ClawdbotConfig["logging"] | undefined =
if (loggingState.overrideSettings) { (loggingState.overrideSettings as LoggerSettings | null) ?? readLoggingConfig();
cfg = loggingState.overrideSettings as LoggerSettings; if (!cfg) {
} else {
try { try {
const loaded = requireConfig("../config/config.js") as { const loaded = requireConfig("../config/config.js") as {
loadConfig?: () => ClawdbotConfig; loadConfig?: () => ClawdbotConfig;

View File

@@ -4,9 +4,10 @@ import path from "node:path";
import { Logger as TsLogger } from "tslog"; import { Logger as TsLogger } from "tslog";
import type { ClawdbotConfig } from "../config/config.js"; import type { ClawdbotConfig } from "../config/types.js";
import type { ConsoleStyle } from "./console.js"; import type { ConsoleStyle } from "./console.js";
import { type LogLevel, levelToMinLevel, normalizeLogLevel } from "./levels.js"; import { type LogLevel, levelToMinLevel, normalizeLogLevel } from "./levels.js";
import { readLoggingConfig } from "./config.js";
import { loggingState } from "./state.js"; import { loggingState } from "./state.js";
// Pin to /tmp so mac Debug UI and docs match; os.tmpdir() can be a per-user // Pin to /tmp so mac Debug UI and docs match; os.tmpdir() can be a per-user
@@ -36,10 +37,9 @@ type ResolvedSettings = {
export type LoggerResolvedSettings = ResolvedSettings; export type LoggerResolvedSettings = ResolvedSettings;
function resolveSettings(): ResolvedSettings { function resolveSettings(): ResolvedSettings {
let cfg: ClawdbotConfig["logging"] | undefined; let cfg: ClawdbotConfig["logging"] | undefined =
if (loggingState.overrideSettings) { (loggingState.overrideSettings as LoggerSettings | null) ?? readLoggingConfig();
cfg = loggingState.overrideSettings as LoggerSettings; if (!cfg) {
} else {
try { try {
const loaded = requireConfig("../config/config.js") as { const loaded = requireConfig("../config/config.js") as {
loadConfig?: () => ClawdbotConfig; loadConfig?: () => ClawdbotConfig;

View File

@@ -3,11 +3,15 @@ import type { Server } from "node:http";
import { beforeEach, describe, expect, it, vi } from "vitest"; import { beforeEach, describe, expect, it, vi } from "vitest";
const saveMediaSource = vi.fn(); const mocks = vi.hoisted(() => ({
const getTailnetHostname = vi.fn(); saveMediaSource: vi.fn(),
const ensurePortAvailable = vi.fn(); getTailnetHostname: vi.fn(),
const startMediaServer = vi.fn(); ensurePortAvailable: vi.fn(),
const logInfo = vi.fn(); startMediaServer: vi.fn(),
logInfo: vi.fn(),
}));
const { saveMediaSource, getTailnetHostname, ensurePortAvailable, startMediaServer, logInfo } =
mocks;
vi.mock("./store.js", () => ({ saveMediaSource })); vi.mock("./store.js", () => ({ saveMediaSource }));
vi.mock("../infra/tailscale.js", () => ({ getTailnetHostname })); vi.mock("../infra/tailscale.js", () => ({ getTailnetHostname }));
@@ -16,7 +20,10 @@ vi.mock("../infra/ports.js", async () => {
return { ensurePortAvailable, PortInUseError: actual.PortInUseError }; return { ensurePortAvailable, PortInUseError: actual.PortInUseError };
}); });
vi.mock("./server.js", () => ({ startMediaServer })); vi.mock("./server.js", () => ({ startMediaServer }));
vi.mock("../logger.js", () => ({ logInfo })); vi.mock("../logger.js", async () => {
const actual = await vi.importActual<typeof import("../logger.js")>("../logger.js");
return { ...actual, logInfo };
});
const { ensureMediaHosted } = await import("./host.js"); const { ensureMediaHosted } = await import("./host.js");
const { PortInUseError } = await import("../infra/ports.js"); const { PortInUseError } = await import("../infra/ports.js");

View File

@@ -1,4 +1,4 @@
import { createSubsystemLogger } from "../logging.js"; import { createSubsystemLogger } from "../logging/subsystem.js";
import { isTruthyEnvValue } from "../infra/env.js"; import { isTruthyEnvValue } from "../infra/env.js";
import type { GeminiEmbeddingClient } from "./embeddings-gemini.js"; import type { GeminiEmbeddingClient } from "./embeddings-gemini.js";
import { hashText } from "./internal.js"; import { hashText } from "./internal.js";

View File

@@ -1,6 +1,6 @@
import { resolveApiKeyForProvider } from "../agents/model-auth.js"; import { resolveApiKeyForProvider } from "../agents/model-auth.js";
import { isTruthyEnvValue } from "../infra/env.js"; import { isTruthyEnvValue } from "../infra/env.js";
import { createSubsystemLogger } from "../logging.js"; import { createSubsystemLogger } from "../logging/subsystem.js";
import type { EmbeddingProvider, EmbeddingProviderOptions } from "./embeddings.js"; import type { EmbeddingProvider, EmbeddingProviderOptions } from "./embeddings.js";
export type GeminiEmbeddingClient = { export type GeminiEmbeddingClient = {

View File

@@ -10,7 +10,7 @@ import type { ResolvedMemorySearchConfig } from "../agents/memory-search.js";
import { resolveMemorySearchConfig } from "../agents/memory-search.js"; import { resolveMemorySearchConfig } from "../agents/memory-search.js";
import type { ClawdbotConfig } from "../config/config.js"; import type { ClawdbotConfig } from "../config/config.js";
import { resolveSessionTranscriptsDirForAgent } from "../config/sessions/paths.js"; import { resolveSessionTranscriptsDirForAgent } from "../config/sessions/paths.js";
import { createSubsystemLogger } from "../logging.js"; import { createSubsystemLogger } from "../logging/subsystem.js";
import { onSessionTranscriptUpdate } from "../sessions/transcript-events.js"; import { onSessionTranscriptUpdate } from "../sessions/transcript-events.js";
import { resolveUserPath } from "../utils.js"; import { resolveUserPath } from "../utils.js";
import { import {

View File

@@ -2,7 +2,7 @@ import fs from "node:fs/promises";
import path from "node:path"; import path from "node:path";
import { resolveSessionTranscriptsDirForAgent } from "../config/sessions/paths.js"; import { resolveSessionTranscriptsDirForAgent } from "../config/sessions/paths.js";
import { createSubsystemLogger } from "../logging.js"; import { createSubsystemLogger } from "../logging/subsystem.js";
import { hashText } from "./internal.js"; import { hashText } from "./internal.js";
const log = createSubsystemLogger("memory"); const log = createSubsystemLogger("memory");

View File

@@ -1,6 +1,6 @@
import type { DatabaseSync } from "node:sqlite"; import type { DatabaseSync } from "node:sqlite";
import { createSubsystemLogger } from "../logging.js"; import { createSubsystemLogger } from "../logging/subsystem.js";
import { buildFileEntry, listMemoryFiles, type MemoryFileEntry } from "./internal.js"; import { buildFileEntry, listMemoryFiles, type MemoryFileEntry } from "./internal.js";
const log = createSubsystemLogger("memory"); const log = createSubsystemLogger("memory");

View File

@@ -1,6 +1,6 @@
import type { DatabaseSync } from "node:sqlite"; import type { DatabaseSync } from "node:sqlite";
import { createSubsystemLogger } from "../logging.js"; import { createSubsystemLogger } from "../logging/subsystem.js";
import type { SessionFileEntry } from "./session-files.js"; import type { SessionFileEntry } from "./session-files.js";
import { import {
buildSessionEntry, buildSessionEntry,

View File

@@ -3,7 +3,7 @@ import type { Command } from "commander";
import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agents/agent-scope.js"; import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agents/agent-scope.js";
import type { ClawdbotConfig } from "../config/config.js"; import type { ClawdbotConfig } from "../config/config.js";
import { loadConfig } from "../config/config.js"; import { loadConfig } from "../config/config.js";
import { createSubsystemLogger } from "../logging.js"; import { createSubsystemLogger } from "../logging/subsystem.js";
import { loadClawdbotPlugins } from "./loader.js"; import { loadClawdbotPlugins } from "./loader.js";
import type { PluginLogger } from "./types.js"; import type { PluginLogger } from "./types.js";

View File

@@ -5,7 +5,7 @@
* and can be called from anywhere in the codebase. * and can be called from anywhere in the codebase.
*/ */
import { createSubsystemLogger } from "../logging.js"; import { createSubsystemLogger } from "../logging/subsystem.js";
import { createHookRunner, type HookRunner } from "./hooks.js"; import { createHookRunner, type HookRunner } from "./hooks.js";
import type { PluginRegistry } from "./registry.js"; import type { PluginRegistry } from "./registry.js";

View File

@@ -1,4 +1,4 @@
import { createSubsystemLogger } from "../logging.js"; import { createSubsystemLogger } from "../logging/subsystem.js";
import { loadClawdbotPlugins, type PluginLoadOptions } from "./loader.js"; import { loadClawdbotPlugins, type PluginLoadOptions } from "./loader.js";
import type { ProviderPlugin } from "./types.js"; import type { ProviderPlugin } from "./types.js";

View File

@@ -1,6 +1,6 @@
import type { ClawdbotConfig } from "../config/config.js"; import type { ClawdbotConfig } from "../config/config.js";
import { STATE_DIR_CLAWDBOT } from "../config/paths.js"; import { STATE_DIR_CLAWDBOT } from "../config/paths.js";
import { createSubsystemLogger } from "../logging.js"; import { createSubsystemLogger } from "../logging/subsystem.js";
import type { PluginRegistry } from "./registry.js"; import type { PluginRegistry } from "./registry.js";
const log = createSubsystemLogger("plugins"); const log = createSubsystemLogger("plugins");

View File

@@ -1,7 +1,7 @@
import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agents/agent-scope.js"; import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agents/agent-scope.js";
import { resolveDefaultAgentWorkspaceDir } from "../agents/workspace.js"; import { resolveDefaultAgentWorkspaceDir } from "../agents/workspace.js";
import { loadConfig } from "../config/config.js"; import { loadConfig } from "../config/config.js";
import { createSubsystemLogger } from "../logging.js"; import { createSubsystemLogger } from "../logging/subsystem.js";
import { loadClawdbotPlugins } from "./loader.js"; import { loadClawdbotPlugins } from "./loader.js";
import type { PluginRegistry } from "./registry.js"; import type { PluginRegistry } from "./registry.js";

View File

@@ -1,6 +1,6 @@
import type { AnyAgentTool } from "../agents/tools/common.js"; import type { AnyAgentTool } from "../agents/tools/common.js";
import { normalizeToolName } from "../agents/tool-policy.js"; import { normalizeToolName } from "../agents/tool-policy.js";
import { createSubsystemLogger } from "../logging.js"; import { createSubsystemLogger } from "../logging/subsystem.js";
import { loadClawdbotPlugins } from "./loader.js"; import { loadClawdbotPlugins } from "./loader.js";
import type { ClawdbotPluginToolContext } from "./types.js"; import type { ClawdbotPluginToolContext } from "./types.js";

View File

@@ -1,4 +1,4 @@
import { createSubsystemLogger } from "../../logging.js"; import { createSubsystemLogger } from "../../logging/subsystem.js";
export const whatsappLog = createSubsystemLogger("gateway/channels/whatsapp"); export const whatsappLog = createSubsystemLogger("gateway/channels/whatsapp");
export const whatsappInboundLog = whatsappLog.child("inbound"); export const whatsappInboundLog = whatsappLog.child("inbound");

View File

@@ -3,7 +3,8 @@ import { DisconnectReason, isJidGroup } from "@whiskeysockets/baileys";
import { formatLocationText } from "../../channels/location.js"; import { formatLocationText } from "../../channels/location.js";
import { logVerbose, shouldLogVerbose } from "../../globals.js"; import { logVerbose, shouldLogVerbose } from "../../globals.js";
import { recordChannelActivity } from "../../infra/channel-activity.js"; import { recordChannelActivity } from "../../infra/channel-activity.js";
import { createSubsystemLogger, getChildLogger } from "../../logging.js"; import { getChildLogger } from "../../logging/logger.js";
import { createSubsystemLogger } from "../../logging/subsystem.js";
import { saveMediaBuffer } from "../../media/store.js"; import { saveMediaBuffer } from "../../media/store.js";
import { createInboundDebouncer } from "../../auto-reply/inbound-debounce.js"; import { createInboundDebouncer } from "../../auto-reply/inbound-debounce.js";
import { jidToE164, resolveJidToE164 } from "../../utils.js"; import { jidToE164, resolveJidToE164 } from "../../utils.js";

View File

@@ -1,6 +1,7 @@
import { randomUUID } from "node:crypto"; import { randomUUID } from "node:crypto";
import { createSubsystemLogger, getChildLogger } from "../logging.js"; import { getChildLogger } from "../logging/logger.js";
import { createSubsystemLogger } from "../logging/subsystem.js";
import { normalizePollInput, type PollInput } from "../polls.js"; import { normalizePollInput, type PollInput } from "../polls.js";
import { toWhatsappJid } from "../utils.js"; import { toWhatsappJid } from "../utils.js";
import { type ActiveWebSendOptions, requireActiveWebListener } from "./active-listener.js"; import { type ActiveWebSendOptions, requireActiveWebListener } from "./active-listener.js";