import type { Logger } from '../utils/logger.js'; import type { Config } from '../config/index.js'; import type { PostsRepository, MessagesRepository, SuccessfulMessagesRepository, ConversationStateRepository, ConversationReadStateRepository, } from '../database/repositories.js'; import type { ChatService } from '../services/chat.js'; import type { MediaService } from '../services/media.js'; import type { MediaSyncService } from '../services/media-sync.js'; import type { ResponseCheckerService } from '../services/response-checker.js'; import type { RateLimiter } from '../utils/rate-limiter.js'; import type { OpenRouterClient } from '../ai/openrouter.js'; import type { StrategySelector } from '../services/strategy-selector.js'; import type { BrowserClient } from '../browser/client.js'; import type { ActivityLog } from './activity-log.js'; import type { LogBroadcaster } from './log-broadcaster.js'; import type { RuntimeConfig } from './types.js'; import type { RedditSessionImporter } from '../services/reddit-session-importer.js'; import type { AccountAuthContext } from '../services/account-auth-context.js'; import type { ConfigStore } from '../config/persistence.js'; import type { RedditAccountsService } from '../services/reddit-accounts.js'; import type { RedditAccountRuntimeManager } from '../services/reddit-account-runtime.js'; import type { AiUsageRepository } from '../database/ai-usage-repository.js'; import type { CandidateQueueRepository } from '../database/candidate-queue-repository.js'; import type { MediaLibraryService } from '../services/media-library.js'; import type { AccountContentRepository } from '../database/account-repositories.js'; /** Bag of everything the route modules might need. */ export interface WebContext { logger: Logger; config: Config; runtimeConfig: RuntimeConfig; activity: ActivityLog; broadcaster: LogBroadcaster; repos: { posts: PostsRepository; messages: MessagesRepository; successful: SuccessfulMessagesRepository; aiUsage?: AiUsageRepository; accountContent?: AccountContentRepository; }; services: { chat?: ChatService; media?: MediaService; mediaSync?: MediaSyncService; responseChecker?: ResponseCheckerService; rateLimiter?: RateLimiter; ai?: OpenRouterClient; strategySelector?: StrategySelector; browser?: BrowserClient; sessionImporter?: RedditSessionImporter; accountAuth?: AccountAuthContext; conversationState?: ConversationStateRepository; conversationReadState?: ConversationReadStateRepository; configStore?: ConfigStore; redditAccounts?: RedditAccountsService; accountRuntimes?: RedditAccountRuntimeManager; candidateQueue?: CandidateQueueRepository; mediaLibrary?: MediaLibraryService; }; /** Bot pause/resume toggle read by the main loop. */ getBotRunning(): boolean; setBotRunning(running: boolean): void; /** Mirrored count for the dashboard's `messagesThisHour` widget. */ getMessagesThisHour(): number; /** * Callback invoked when the dashboard mutates `runtimeConfig`. * Wrapped in a getter so callers see the latest value — it can be installed * after the WebContext is constructed. */ getOnConfigChange(): ((config: RuntimeConfig) => void) | null; }