feat: add config schema and loader with env var expansion

This commit is contained in:
William Valentin
2026-02-02 20:54:19 -08:00
parent 75e64b534d
commit 4adf172c25
5 changed files with 206 additions and 0 deletions
+70
View File
@@ -0,0 +1,70 @@
import { z } from 'zod';
const telegramSchema = z.object({
bot_token: z.string().min(1, 'Bot token is required'),
allowed_chat_ids: z.array(z.number()).min(1, 'At least one chat ID required'),
});
const serverSchema = z.object({
tailscale_only: z.boolean().default(true),
localhost: z.boolean().default(true),
port: z.number().default(18800),
});
const modelConfigSchema = z.object({
provider: z.enum(['anthropic', 'openai', 'gemini', 'ollama', 'llamacpp']),
model: z.string(),
endpoint: z.string().optional(),
for: z.array(z.string()).optional(),
});
const modelsSchema = z.object({
local: modelConfigSchema.optional(),
fast: modelConfigSchema.optional(),
default: modelConfigSchema,
complex: modelConfigSchema.optional(),
fallback_chain: z.array(z.string()).default(['anthropic']),
});
const backendsSchema = z.object({
claude_code: z.object({
enabled: z.boolean().default(false),
path: z.string().optional(),
}).default({ enabled: false }),
opencode: z.object({
enabled: z.boolean().default(false),
path: z.string().optional(),
}).default({ enabled: false }),
native: z.object({
enabled: z.boolean().default(true),
}).default({ enabled: true }),
}).default({});
const hooksSchema = z.object({
confirm: z.array(z.string()).default([]),
log: z.array(z.string()).default([]),
silent: z.array(z.string()).default([]),
}).default({});
const mcpServerSchema = z.object({
name: z.string(),
command: z.string(),
args: z.array(z.string()).default([]),
});
const mcpSchema = z.object({
servers: z.array(mcpServerSchema).default([]),
}).default({ servers: [] });
export const configSchema = z.object({
telegram: telegramSchema,
server: serverSchema.default({}),
models: modelsSchema,
backends: backendsSchema.default({}),
hooks: hooksSchema.default({}),
mcp: mcpSchema.default({ servers: [] }),
});
export type Config = z.infer<typeof configSchema>;
export type TelegramConfig = z.infer<typeof telegramSchema>;
export type ModelConfig = z.infer<typeof modelConfigSchema>;