export interface AdditionalMount { hostPath: string; // Absolute path on host (supports ~ for home) containerPath?: string; // Optional — defaults to basename of hostPath. Mounted at /workspace/extra/{value} readonly?: boolean; // Default: true for safety } export interface AgentConfig { additionalMounts?: AdditionalMount[]; timeout?: number; // Default: 300000 (5 minutes) // Per-group model/effort overrides (take precedence over global env vars) codexModel?: string; codexEffort?: string; claudeModel?: string; claudeEffort?: string; } export type AgentType = 'claude-code' | 'codex'; export interface RegisteredGroup { name: string; folder: string; trigger: string; added_at: string; agentConfig?: AgentConfig; requiresTrigger?: boolean; // Default: true for groups, false for solo chats isMain?: boolean; // True for the main control group (no trigger, elevated privileges) agentType?: AgentType; workDir?: string; // Working directory for the agent (defaults to group folder) } export interface NewMessage { id: string; chat_jid: string; sender: string; sender_name: string; content: string; timestamp: string; is_from_me?: boolean; is_bot_message?: boolean; } export interface ScheduledTask { id: string; group_folder: string; chat_jid: string; prompt: string; schedule_type: 'cron' | 'interval' | 'once'; schedule_value: string; context_mode: 'group' | 'isolated'; next_run: string | null; last_run: string | null; last_result: string | null; status: 'active' | 'paused' | 'completed'; created_at: string; } export interface TaskRunLog { task_id: string; run_at: string; duration_ms: number; status: 'success' | 'error'; result: string | null; error: string | null; } // --- Channel abstraction --- export interface Channel { name: string; connect(): Promise; sendMessage(jid: string, text: string): Promise; isConnected(): boolean; ownsJid(jid: string): boolean; disconnect(): Promise; // Optional: typing indicator. Channels that support it implement it. setTyping?(jid: string, isTyping: boolean): Promise; // Optional: edit/delete messages (used by status dashboard). editMessage?(jid: string, messageId: string, text: string): Promise; sendAndTrack?(jid: string, text: string): Promise; // Optional: sync group/chat names from the platform. syncGroups?(force: boolean): Promise; } // Callback type that channels use to deliver inbound messages export type OnInboundMessage = (chatJid: string, message: NewMessage) => void; // Callback for chat metadata discovery. // name is optional — channels that deliver names inline (Telegram) pass it here; // channels that sync names separately (via syncGroups) omit it. export type OnChatMetadata = ( chatJid: string, timestamp: string, name?: string, channel?: string, isGroup?: boolean, ) => void;