From e34a8c39f8a27341e6a725b9251240c9c2e696e4 Mon Sep 17 00:00:00 2001 From: Mike Date: Mon, 26 Jan 2026 17:55:22 -0800 Subject: [PATCH] feat(channels): allow setting config dir for signal Create a clawdbot configuration that sets the Signal config directory. This allows the config dir to be on a volume when clawdbot is running in docker --- src/config/types.signal.ts | 2 ++ src/config/zod-schema.providers-core.ts | 1 + src/signal/daemon.ts | 5 +++++ src/signal/monitor.ts | 4 ++++ 4 files changed, 12 insertions(+) diff --git a/src/config/types.signal.ts b/src/config/types.signal.ts index 014f62841..1ddc83c03 100644 --- a/src/config/types.signal.ts +++ b/src/config/types.signal.ts @@ -31,6 +31,8 @@ export type SignalAccountConfig = { httpPort?: number; /** signal-cli binary path (default: signal-cli). */ cliPath?: string; + /** Custom config/data directory for signal-cli (default: ~/.local/share/signal-cli). */ + configDir?: string; /** Auto-start signal-cli daemon (default: true if httpUrl not set). */ autoStart?: boolean; /** Max time to wait for signal-cli daemon startup (ms, cap 120000). */ diff --git a/src/config/zod-schema.providers-core.ts b/src/config/zod-schema.providers-core.ts index 26e279faf..2f3ca3ec7 100644 --- a/src/config/zod-schema.providers-core.ts +++ b/src/config/zod-schema.providers-core.ts @@ -499,6 +499,7 @@ export const SignalAccountSchemaBase = z httpHost: z.string().optional(), httpPort: z.number().int().positive().optional(), cliPath: ExecutableTokenSchema.optional(), + configDir: z.string().optional(), autoStart: z.boolean().optional(), startupTimeoutMs: z.number().int().min(1000).max(120000).optional(), receiveMode: z.union([z.literal("on-start"), z.literal("manual")]).optional(), diff --git a/src/signal/daemon.ts b/src/signal/daemon.ts index ca1b01b60..cbd7dfa04 100644 --- a/src/signal/daemon.ts +++ b/src/signal/daemon.ts @@ -10,6 +10,8 @@ export type SignalDaemonOpts = { ignoreAttachments?: boolean; ignoreStories?: boolean; sendReadReceipts?: boolean; + /** Custom config/data directory for signal-cli. */ + configDir?: string; runtime?: RuntimeEnv; }; @@ -30,6 +32,9 @@ export function classifySignalCliLogLine(line: string): "log" | "error" | null { function buildDaemonArgs(opts: SignalDaemonOpts): string[] { const args: string[] = []; + if (opts.configDir) { + args.push("-c", opts.configDir); + } if (opts.account) { args.push("-a", opts.account); } diff --git a/src/signal/monitor.ts b/src/signal/monitor.ts index 66b023047..4d9a2ed28 100644 --- a/src/signal/monitor.ts +++ b/src/signal/monitor.ts @@ -45,6 +45,8 @@ export type MonitorSignalOpts = { autoStart?: boolean; startupTimeoutMs?: number; cliPath?: string; + /** Custom config/data directory for signal-cli. */ + configDir?: string; httpHost?: string; httpPort?: number; receiveMode?: "on-start" | "manual"; @@ -295,10 +297,12 @@ export async function monitorSignalProvider(opts: MonitorSignalOpts = {}): Promi if (autoStart) { const cliPath = opts.cliPath ?? accountInfo.config.cliPath ?? "signal-cli"; + const configDir = opts.configDir ?? accountInfo.config.configDir; const httpHost = opts.httpHost ?? accountInfo.config.httpHost ?? "127.0.0.1"; const httpPort = opts.httpPort ?? accountInfo.config.httpPort ?? 8080; daemonHandle = spawnSignalDaemon({ cliPath, + configDir, account, httpHost, httpPort,