{"version":3,"sources":["../src/types/advanced.ts","../src/utils/common.ts","../src/core/chain.ts","../src/core/errors.ts","../src/plugins/core.ts","../src/utils/platform.ts","../src/utils/temp-file-manager.ts","../src/core/constants.ts","../src/core/database.ts","../src/core/outgoing-manager.ts","../src/utils/applescript.ts","../src/utils/download.ts","../src/utils/semaphore.ts","../src/core/message-promise.ts","../src/core/sender.ts","../src/core/watcher.ts","../src/core/sdk.ts","../src/plugins/logger.ts","../src/helpers/attachment.ts"],"names":["str","resolve","join","homedir","existsSync","readdirSync","statSync","unlinkSync","promisify","exec","path","tmpdir","writeFile","unlink","execAsync","fs","delay","TEMP_DIR","ext","writeFileSync","result"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Utility types and helper functions\n */\n\n// ==================== Format validation regex patterns ====================\n\n/**\n * Phone number format regex\n * Supports international format, spaces, hyphens, and parentheses\n * Must contain at least one digit\n */\nconst PHONE_REGEX = /^\\+?[\\d\\s\\-()]+$/\n\n/**\n * Check if string contains at least minimum number of digits\n */\nconst hasMinDigits = (str: string, min: number): boolean => {\n    const digits = str.replace(/\\D/g, '')\n    return digits.length >= min\n}\n\n/**\n * Email format regex\n * Basic email format validation\n */\nconst EMAIL_REGEX = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/\n\n/**\n * URL format regex\n * Matches URLs starting with http:// or https://\n */\nconst URL_REGEX = /^https?:\\/\\/.+/\n\n// ==================== Recipient type ====================\n\n/**\n * Recipient type\n *\n * Can be one of the following formats:\n * - Phone number\n * - Email address\n */\nexport type Recipient = string\n\n/**\n * Validate recipient format\n *\n * Supported formats:\n * - Phone number: +1234567890, (123) 456-7890\n * - Email address: user@example.com\n *\n * @param value Recipient string (phone or email)\n * @returns Validated recipient\n * @throws TypeError when format is invalid\n */\nexport const asRecipient = (value: string): Recipient => {\n    const normalized = value.trim()\n\n    if (!normalized) {\n        throw new TypeError('Recipient cannot be empty')\n    }\n\n    // Check email first (more specific)\n    if (EMAIL_REGEX.test(normalized)) {\n        return normalized\n    }\n\n    // Check phone number format and minimum digits\n    // Most phone numbers have 7-10 digits (excluding country code)\n    if (PHONE_REGEX.test(normalized) && hasMinDigits(normalized, 7)) {\n        return normalized\n    }\n\n    throw new TypeError(`Invalid recipient format: ${value} (phone number or email required)`)\n}\n\n/**\n * Check if string is a HTTP(S) URL\n *\n * @param value String to check\n * @returns true if it's a valid URL\n */\nexport const isURL = (value: string): boolean => {\n    return URL_REGEX.test(value)\n}\n\n// ==================== Chain API function types ====================\n\n/**\n * Predicate function\n * Returns whether a condition is met\n */\nexport type Predicate<T> = (value: T) => boolean\n\n/**\n * Async predicate function\n * Returns Promise-wrapped predicate result\n */\nexport type AsyncPredicate<T> = (value: T) => Promise<boolean>\n\n/**\n * Mapper function\n * Transforms type T to type U\n */\nexport type Mapper<T, U> = (value: T) => U\n\n/**\n * Handler function\n * Executes operation on data, no return value\n */\nexport type Handler<T> = (value: T) => void\n\n/**\n * Async handler function\n * Executes async operation, no return value\n */\nexport type AsyncHandler<T> = (value: T) => Promise<void>\n","/**\n * Common utility functions\n */\n\n/**\n * Delay for specified milliseconds\n * @param ms Milliseconds\n */\nexport const delay = (ms: number): Promise<void> => {\n    return new Promise<void>((resolve) => setTimeout(resolve, ms))\n}\n\n/**\n * Validate message content\n * @param text Text content\n * @param attachments Attachment list\n * @returns Validation result: hasText, hasAttachments\n * @throws Error when content is empty\n */\nexport function validateMessageContent(\n    text: string | undefined,\n    attachments: readonly string[] | undefined\n): { hasText: boolean; hasAttachments: boolean } {\n    const hasText = Boolean(text && text.trim().length > 0)\n    const hasAttachments = Boolean(attachments && attachments.length > 0)\n\n    if (!hasText && !hasAttachments) {\n        throw new Error('Message must contain text or attachments')\n    }\n\n    return { hasText, hasAttachments }\n}\n\n/**\n * Normalize chatId format\n * - Extracts GUID from AppleScript group format (e.g., `iMessage;+;chat...` -> `chat...`)\n * - Returns normalized chatId for consistent handling\n * @param chatId Chat identifier (may be in various formats)\n * @returns Normalized chatId\n */\nexport function normalizeChatId(chatId: string): string {\n    // AppleScript group format: iMessage;+;chat...\n    // Extract GUID part (chat...) for normalization\n    if (chatId.includes(';')) {\n        const parts = chatId.split(';')\n        // Check if it matches AppleScript group format: iMessage;+;chat...\n        if (parts.length >= 3 && parts[0] === 'iMessage' && parts[1] === '+' && parts[2]?.startsWith('chat')) {\n            // Extract GUID part (everything after the second semicolon)\n            return parts.slice(2).join(';')\n        }\n    }\n    return chatId\n}\n\n/**\n * Check if a chatId represents a group chat (not a DM)\n *\n * @param chatId The chat identifier to check\n * @returns true if it's a group chat, false if it's a DM\n */\nexport function isGroupChatId(chatId: string): boolean {\n    // AppleScript group format: iMessage;+;chat...\n    if (chatId.startsWith('iMessage;+;chat')) {\n        return true\n    }\n\n    // Pure GUID format (no semicolon, starts with 'chat')\n    if (!chatId.includes(';') && chatId.startsWith('chat') && chatId.length > 10) {\n        return true\n    }\n\n    return false\n}\n\n/**\n * Extract recipient from a service-prefixed chatId\n *\n * @param chatId The chat identifier (e.g., 'iMessage;+1234567890')\n * @returns The recipient part (e.g., '+1234567890'), or null if not a DM format\n */\nexport function extractRecipientFromChatId(chatId: string): string | null {\n    if (!chatId.includes(';')) {\n        return null\n    }\n\n    // Skip group chat formats\n    if (isGroupChatId(chatId)) {\n        return null\n    }\n\n    // Extract recipient from service-prefixed format: service;recipient\n    const parts = chatId.split(';')\n    if (parts.length === 2) {\n        return parts[1] || null\n    }\n\n    return null\n}\n\n/**\n * Validate chatId format\n * - Must be a non-empty string\n * - Three accepted forms:\n *   1) Group chats: GUID-like string without semicolon (e.g., `chat...`)\n *   2) Group chats (AppleScript): `iMessage;+;chat...` format\n *   3) DMs: service-prefixed identifier with semicolon (e.g., `iMessage;+1234567890`)\n * @throws Error when chatId is invalid\n */\nexport function validateChatId(chatId: string): void {\n    if (!chatId || typeof chatId !== 'string') {\n        throw new Error('chatId must be a non-empty string')\n    }\n\n    // Check for AppleScript group format: iMessage;+;chat...\n    if (chatId.includes(';')) {\n        const parts = chatId.split(';')\n        // AppleScript group format: iMessage;+;chat...\n        if (parts.length >= 3 && parts[0] === 'iMessage' && parts[1] === '+' && parts[2]?.startsWith('chat')) {\n            // Validate GUID part length\n            const guidPart = parts.slice(2).join(';')\n            if (guidPart.length < 8) {\n                throw new Error('Invalid chatId format: GUID too short')\n            }\n            return\n        }\n\n        // DM format: <service>;<address>\n        const service = parts[0] || ''\n        const address = parts[1] || ''\n        const allowedServices = new Set(['iMessage', 'SMS', 'RCS'])\n        if (!allowedServices.has(service) || !address) {\n            throw new Error('Invalid chatId format: expected \"<service>;<address>\" or group GUID')\n        }\n        return\n    }\n\n    // No semicolon: treat as GUID-like; ensure non-trivial length\n    if (chatId.length < 8) {\n        throw new Error('Invalid chatId format: GUID too short')\n    }\n}\n","/**\n * Message Processing Chain\n */\n\nimport type { Mapper, Predicate } from '../types/advanced'\nimport { asRecipient } from '../types/advanced'\nimport type { Message } from '../types/message'\nimport { extractRecipientFromChatId, isGroupChatId } from '../utils/common'\nimport type { MessageSender } from './sender'\n\n/**\n * Message Processing Chain\n *\n * Note: You must explicitly call execute() to perform operations\n *\n * @example\n * ```ts\n * await sdk.message(msg)\n *   .ifFromOthers()\n *   .matchText('hello')\n *   .replyText('Hi!')\n *   .execute()  // Must call execute()\n * ```\n */\nexport class MessageChain {\n    /** Whether to execute */\n    private shouldExecute = true\n\n    /** Actions */\n    private actions: Array<() => Promise<void>> = []\n\n    /** Whether already executed */\n    private executed = false\n\n    constructor(\n        /** Message */\n        private readonly message: Message,\n        /** Sender */\n        private readonly sender: MessageSender\n    ) {\n        /** If you forgot to call .execute(), we will automatically detect and warn you */\n        if (typeof process !== 'undefined' && process.env.NODE_ENV !== 'production') {\n            /** Development mode: Delayed execution detection */\n            setTimeout(() => {\n                if (!this.executed && this.actions.length > 0) {\n                    console.warn(\n                        '[MessageChain] Warning: Unexecuted message chain detected.',\n                        'You need to explicitly call .execute() method.\\n',\n                        `Message ID: ${this.message.id}, Sender: ${this.message.sender}`\n                    )\n                }\n            }, 1000)\n        }\n    }\n\n    /**\n     * Conditional check\n     */\n    when(predicate: Predicate<Message>): this {\n        if (this.shouldExecute) {\n            this.shouldExecute = predicate(this.message)\n        }\n        return this\n    }\n\n    /**\n     * Match text pattern\n     */\n    matchText(pattern: string | RegExp): this {\n        return this.when((m) => {\n            if (!m.text) return false\n            return typeof pattern === 'string' ? m.text.includes(pattern) : pattern.test(m.text)\n        })\n    }\n\n    /**\n     * Only process unread messages\n     */\n    ifUnread(): this {\n        return this.when((m) => !m.isRead)\n    }\n\n    /**\n     * Only process messages from others\n     */\n    ifFromOthers(): this {\n        return this.when((m) => !m.isFromMe)\n    }\n\n    /**\n     * Only process my own messages\n     */\n    ifFromMe(): this {\n        return this.when((m) => m.isFromMe)\n    }\n\n    /**\n     * Only process group chat messages\n     */\n    ifGroupChat(): this {\n        return this.when((m) => m.isGroupChat)\n    }\n\n    /**\n     * Reply with text\n     *\n     * Automatically routes to recipient or group based on message.chatId\n     */\n    replyText(text: string | Mapper<Message, string>): this {\n        if (this.shouldExecute) {\n            this.actions.push(async () => {\n                const replyText = typeof text === 'function' ? text(this.message) : text\n\n                // Determine if chatId is a group or recipient\n                if (isGroupChatId(this.message.chatId)) {\n                    // Group chat - use sendToGroup\n                    await this.sender.sendToGroup({ groupId: this.message.chatId, text: replyText })\n                } else {\n                    // DM - extract recipient and use send\n                    const extracted = extractRecipientFromChatId(this.message.chatId)\n                    const recipient = extracted || asRecipient(this.message.chatId)\n                    await this.sender.send({ to: recipient, text: replyText })\n                }\n            })\n        }\n        return this\n    }\n\n    /**\n     * Reply with image\n     *\n     * Automatically routes to recipient or group based on message.chatId\n     */\n    replyImage(images: string | string[] | Mapper<Message, string | string[]>): this {\n        if (this.shouldExecute) {\n            this.actions.push(async () => {\n                const imagePaths = typeof images === 'function' ? images(this.message) : images\n                const paths = Array.isArray(imagePaths) ? imagePaths : [imagePaths]\n\n                // Determine if chatId is a group or recipient\n                if (isGroupChatId(this.message.chatId)) {\n                    // Group chat - use sendToGroup\n                    await this.sender.sendToGroup({ groupId: this.message.chatId, attachments: paths })\n                } else {\n                    // DM - extract recipient and use send\n                    const extracted = extractRecipientFromChatId(this.message.chatId)\n                    const recipient = extracted || asRecipient(this.message.chatId)\n                    await this.sender.send({ to: recipient, attachments: paths })\n                }\n            })\n        }\n        return this\n    }\n\n    /**\n     * Execute custom operation\n     */\n    do(handler: (message: Message) => void | Promise<void>): this {\n        if (this.shouldExecute) {\n            this.actions.push(async () => {\n                await Promise.resolve(handler(this.message))\n            })\n        }\n        return this\n    }\n\n    /**\n     * Execute all operations (explicit call)\n     *\n     * This is the only method that actually performs operations\n     *\n     * @throws If an error occurs during execution\n     */\n    async execute(): Promise<void> {\n        this.executed = true\n\n        if (!this.shouldExecute || this.actions.length === 0) {\n            return\n        }\n\n        for (const action of this.actions) {\n            await action()\n        }\n    }\n}\n","/**\n * SDK Error Types\n */\n\n/** Error code types */\nexport type ErrorCode = 'PLATFORM' | 'DATABASE' | 'SEND' | 'WEBHOOK' | 'CONFIG' | 'UNKNOWN'\n\n/**\n * Unified SDK Error Class\n */\nexport class IMessageError extends Error {\n    constructor(\n        public readonly code: ErrorCode,\n        message: string,\n        options?: ErrorOptions\n    ) {\n        super(message, options)\n        this.name = 'IMessageError'\n        Error.captureStackTrace?.(this, this.constructor)\n    }\n\n    /** Type guard */\n    static is(error: unknown): error is IMessageError {\n        return error instanceof IMessageError\n    }\n\n    /** Check if error is of specific type */\n    is(code: ErrorCode): boolean {\n        return this.code === code\n    }\n}\n\n/** Factory functions */\nexport const PlatformError = (msg = 'Only macOS is supported', cause?: Error) =>\n    new IMessageError('PLATFORM', msg, cause ? { cause } : undefined)\nexport const DatabaseError = (msg: string, cause?: Error) =>\n    new IMessageError('DATABASE', msg, cause ? { cause } : undefined)\nexport const SendError = (msg: string, cause?: Error) => new IMessageError('SEND', msg, cause ? { cause } : undefined)\nexport const WebhookError = (msg: string, cause?: Error) =>\n    new IMessageError('WEBHOOK', msg, cause ? { cause } : undefined)\nexport const ConfigError = (msg: string, cause?: Error) =>\n    new IMessageError('CONFIG', msg, cause ? { cause } : undefined)\n","/**\n * Plugin System\n *\n * Plugins can listen to the following lifecycle hooks:\n * - SDK initialization and destruction\n * - Before and after message queries\n * - Before and after sending messages\n * - When new messages are received\n * - When errors occur\n */\n\nimport type { SendResult } from '../core/sender'\nimport type { Message } from '../types/message'\n\n/**\n * Plugin lifecycle hooks\n */\nexport interface PluginHooks {\n    /** Called when SDK initialization is complete */\n    onInit?: () => void | Promise<void>\n\n    /** Called before querying messages (useful for logging) */\n    onBeforeQuery?: (filter: unknown) => void | Promise<void>\n\n    /** Called after querying messages (useful for data processing) */\n    onAfterQuery?: (messages: readonly Message[]) => void | Promise<void>\n\n    /** Called before sending a message (useful for validation, logging) */\n    onBeforeSend?: (to: string, content: { text?: string; attachments?: string[] }) => void | Promise<void>\n\n    /** Called after sending a message (useful for logging results) */\n    onAfterSend?: (to: string, result: SendResult) => void | Promise<void>\n\n    /** Called when a new message is received (triggered by listener) */\n    onNewMessage?: (message: Message) => void | Promise<void>\n\n    /** Called when an error occurs (global error handling) */\n    onError?: (error: Error, context?: string) => void | Promise<void>\n\n    /** Called when SDK is destroyed (cleanup resources) */\n    onDestroy?: () => void | Promise<void>\n}\n\n/**\n * Plugin metadata\n */\nexport interface PluginMetadata {\n    /** Unique plugin name */\n    readonly name: string\n\n    /** Plugin version number (optional) */\n    readonly version?: string\n\n    /** Plugin description (optional) */\n    readonly description?: string\n}\n\n/**\n * Complete plugin interface\n * Plugin = metadata + hook functions\n */\nexport interface Plugin extends PluginMetadata, PluginHooks {}\n\n/**\n * Plugin manager\n */\nexport class PluginManager {\n    /** List of registered plugins */\n    private plugins: Plugin[] = []\n\n    /** Whether the plugin manager has been initialized */\n    initialized = false\n\n    /**\n     * Register a plugin\n     * If the manager is already initialized, the plugin's onInit hook will be called immediately\n     * @param plugin Plugin instance\n     * @returns this - Supports method chaining\n     */\n    use(plugin: Plugin): this {\n        this.plugins.push(plugin)\n\n        if (this.initialized && plugin.onInit) {\n            Promise.resolve(plugin.onInit()).catch((error) => {\n                const errorMsg = `[Plugin ${plugin.name}] Initialization failed:`\n                console.error(errorMsg, error)\n            })\n        }\n\n        return this\n    }\n\n    /**\n     * Initialize all plugins\n     * Calls the onInit hook for all plugins\n     */\n    async init(): Promise<void> {\n        this.initialized = true\n        await this.callHookForAll('onInit')\n    }\n\n    /**\n     * Destroy all plugins\n     * Calls the onDestroy hook for all plugins and clears the plugin list\n     */\n    async destroy(): Promise<void> {\n        await this.callHookForAll('onDestroy')\n        this.plugins = []\n        this.initialized = false\n    }\n\n    /**\n     * Call the specified hook for all plugins\n     * @param hookName Hook name\n     * @param args Hook arguments\n     * @returns List of plugin errors (if any)\n     */\n    async callHookForAll<K extends keyof PluginHooks>(\n        hookName: K,\n        ...args: Parameters<NonNullable<PluginHooks[K]>>\n    ): Promise<Array<{ plugin: string; error: Error }>> {\n        const pluginsWithHook = this.plugins.filter((p) => p[hookName])\n\n        if (pluginsWithHook.length === 0) {\n            return []\n        }\n\n        const results = await Promise.allSettled(\n            pluginsWithHook.map(async (plugin) => {\n                try {\n                    const hook = plugin[hookName]!\n                    const hookFn = hook as (...a: typeof args) => void | Promise<void>\n                    await Promise.resolve(hookFn(...args))\n\n                    return {\n                        plugin: plugin.name,\n                        success: true,\n                    }\n                } catch (error) {\n                    const normalizedError = error instanceof Error ? error : new Error(String(error))\n\n                    return {\n                        plugin: plugin.name,\n                        success: false,\n                        error: normalizedError,\n                    }\n                }\n            })\n        )\n\n        // Collect all errors\n        const errors: Array<{ plugin: string; error: Error }> = []\n\n        for (const result of results) {\n            if (result.status === 'fulfilled' && !result.value.success) {\n                errors.push({\n                    plugin: result.value.plugin,\n                    error: result.value.error!,\n                })\n            } else if (result.status === 'rejected') {\n                const normalizedError =\n                    result.reason instanceof Error ? result.reason : new Error(String(result.reason))\n\n                errors.push({\n                    plugin: 'unknown',\n                    error: normalizedError,\n                })\n            }\n        }\n\n        // If there are errors and it's not the onError hook, trigger the onError hook\n        if (errors.length > 0 && hookName !== 'onError') {\n            for (const { plugin, error } of errors) {\n                console.error(`[Plugin ${plugin}] ${hookName} failed:`, error)\n\n                // Trigger onError hook (recursive, but won't trigger onError again)\n                try {\n                    const context = `Plugin ${plugin} - ${String(hookName)}`\n                    await this.callHookForAll('onError', error, context)\n                } catch {\n                    // Ignore onError hook errors to avoid infinite loops\n                }\n            }\n        }\n\n        return errors\n    }\n}\n\n/**\n * Helper function to define a plugin\n */\nexport const definePlugin = (plugin: Plugin) => plugin\n","/**\n * Platform check utilities\n */\n\nimport { PlatformError } from '../core/errors'\n\nexport { asRecipient } from '../types/advanced'\n\n/**\n * Check and require running on macOS platform\n *\n * @throws PlatformError when not macOS\n */\nexport const requireMacOS = (): void => {\n    if (process.platform !== 'darwin') {\n        throw PlatformError('Only macOS is supported')\n    }\n}\n\n/**\n * Check if current system is macOS\n *\n * @returns true if macOS\n */\nexport const isMacOS = (): boolean => {\n    return process.platform === 'darwin'\n}\n\n/**\n * Get default path of iMessage database\n *\n * @returns Full path to database file\n * @throws Error when HOME environment variable is not set\n */\nexport const getDefaultDatabasePath = (): string => {\n    const home = process.env.HOME\n\n    if (!home) {\n        throw new Error('HOME environment variable is not set')\n    }\n\n    return `${home}/Library/Messages/chat.db`\n}\n","/**\n * Temporary file manager\n */\n\nimport { existsSync, readdirSync, statSync, unlinkSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\n\n/** Temp file prefix */\nconst TEMP_FILE_PREFIX = 'imsg_temp_'\n\n/** Temp file directory */\nconst TEMP_DIR = join(homedir(), 'Pictures')\n\n/** Default cleanup configuration */\nconst DEFAULT_CONFIG = {\n    /** File retention time (milliseconds), default 10 minutes */\n    maxAge: 10 * 60 * 1000,\n    /** Cleanup interval (milliseconds), default 5 minutes */\n    cleanupInterval: 5 * 60 * 1000,\n}\n\n/**\n * Temp file manager configuration\n */\nexport interface TempFileManagerConfig {\n    /** File retention time (milliseconds) */\n    maxAge?: number\n    /** Cleanup interval (milliseconds) */\n    cleanupInterval?: number\n    /** Whether to enable debug logs */\n    debug?: boolean\n}\n\n/**\n * Temp file manager class\n */\nexport class TempFileManager {\n    private readonly config: Required<TempFileManagerConfig>\n    private cleanupTimer: NodeJS.Timeout | null = null\n    private isDestroyed = false\n\n    constructor(config: TempFileManagerConfig = {}) {\n        this.config = {\n            maxAge: config.maxAge ?? DEFAULT_CONFIG.maxAge,\n            cleanupInterval: config.cleanupInterval ?? DEFAULT_CONFIG.cleanupInterval,\n            debug: config.debug ?? false,\n        }\n    }\n\n    /**\n     * Start cleanup task\n     */\n    start(): void {\n        if (this.isDestroyed) {\n            throw new Error('TempFileManager is destroyed, cannot start')\n        }\n\n        /** Clean up immediately (clean up leftover files) */\n        this.cleanup().catch((error) => {\n            if (this.config.debug) {\n                console.error('[TempFileManager] Startup cleanup failed:', error)\n            }\n        })\n\n        /** Periodic cleanup */\n        this.cleanupTimer = setInterval(() => {\n            this.cleanup().catch((error) => {\n                if (this.config.debug) {\n                    console.error('[TempFileManager] Periodic cleanup failed:', error)\n                }\n            })\n        }, this.config.cleanupInterval)\n\n        /** Prevent timer from blocking process exit */\n        this.cleanupTimer.unref()\n\n        if (this.config.debug) {\n            const intervalSec = this.config.cleanupInterval / 1000\n            const maxAgeSec = this.config.maxAge / 1000\n            console.log(\n                `[TempFileManager] Started, cleanup interval: ${intervalSec}s, max file retention: ${maxAgeSec}s`\n            )\n        }\n    }\n\n    /**\n     * Clean up old temporary files\n     *\n     * By scanning ~/Pictures directory,\n     * auto-discover and clean all imsg_temp_* files exceeding retention time\n     */\n    async cleanup(): Promise<{ removed: number; errors: number }> {\n        if (this.isDestroyed) {\n            return { removed: 0, errors: 0 }\n        }\n\n        let removed = 0\n        let errors = 0\n        const now = Date.now()\n\n        try {\n            if (existsSync(TEMP_DIR)) {\n                const files = readdirSync(TEMP_DIR)\n\n                for (const file of files) {\n                    if (!file.startsWith(TEMP_FILE_PREFIX)) {\n                        continue\n                    }\n\n                    const filePath = join(TEMP_DIR, file)\n\n                    try {\n                        const stats = statSync(filePath)\n                        const fileAge = now - stats.mtimeMs\n\n                        /** Delete files exceeding retention time */\n                        if (fileAge > this.config.maxAge) {\n                            unlinkSync(filePath)\n                            removed++\n\n                            if (this.config.debug) {\n                                const ageMinutes = (fileAge / 60000).toFixed(1)\n                                console.log(`[TempFileManager] Removed old file: ${file} (${ageMinutes} minutes ago)`)\n                            }\n                        }\n                    } catch (error) {\n                        errors++\n                        if (this.config.debug) {\n                            console.error(`[TempFileManager] Failed to remove file: ${file}`, error)\n                        }\n                    }\n                }\n            }\n\n            if (this.config.debug && (removed > 0 || errors > 0)) {\n                console.log(`[TempFileManager] Cleanup complete: removed ${removed} files, ${errors} errors`)\n            }\n        } catch (error) {\n            if (this.config.debug) {\n                console.error('[TempFileManager] Cleanup process error:', error)\n            }\n        }\n\n        return { removed, errors }\n    }\n\n    /**\n     * Clean up all temporary files (regardless of time)\n     *\n     * Called when SDK is destroyed, immediately clean all imsg_temp_* files\n     */\n    async cleanupAll(): Promise<{ removed: number; errors: number }> {\n        if (this.isDestroyed) {\n            return { removed: 0, errors: 0 }\n        }\n\n        let removed = 0\n        let errors = 0\n\n        try {\n            if (existsSync(TEMP_DIR)) {\n                const files = readdirSync(TEMP_DIR)\n\n                for (const file of files) {\n                    if (!file.startsWith(TEMP_FILE_PREFIX)) {\n                        continue\n                    }\n\n                    const filePath = join(TEMP_DIR, file)\n\n                    try {\n                        unlinkSync(filePath)\n                        removed++\n\n                        if (this.config.debug) {\n                            console.log(`[TempFileManager] Removed file: ${file}`)\n                        }\n                    } catch (error) {\n                        errors++\n                        if (this.config.debug) {\n                            console.error(`[TempFileManager] Failed to remove file: ${file}`, error)\n                        }\n                    }\n                }\n            }\n\n            if (this.config.debug) {\n                console.log(`[TempFileManager] Cleanup all files complete: removed ${removed}, ${errors} errors`)\n            }\n        } catch (error) {\n            if (this.config.debug) {\n                console.error('[TempFileManager] Cleanup all files error:', error)\n            }\n        }\n\n        return { removed, errors }\n    }\n\n    /**\n     * Stop cleanup task\n     */\n    stop(): void {\n        if (this.cleanupTimer) {\n            clearInterval(this.cleanupTimer)\n            this.cleanupTimer = null\n        }\n    }\n\n    /**\n     * Destroy manager (stop cleanup and clean all files)\n     */\n    async destroy(): Promise<void> {\n        if (this.isDestroyed) {\n            return\n        }\n\n        this.isDestroyed = true\n        this.stop()\n\n        // Clean up all temp files\n        await this.cleanupAll()\n\n        if (this.config.debug) {\n            console.log('[TempFileManager] Destroyed')\n        }\n    }\n\n    /**\n     * Get statistics\n     */\n    getStats(): {\n        currentFiles: number\n        isRunning: boolean\n        config: Required<TempFileManagerConfig>\n    } {\n        let currentFiles = 0\n\n        try {\n            if (existsSync(TEMP_DIR)) {\n                const files = readdirSync(TEMP_DIR)\n                currentFiles = files.filter((f) => f.startsWith(TEMP_FILE_PREFIX)).length\n            }\n        } catch {\n            /** Return 0 when scan fails */\n        }\n\n        return {\n            currentFiles,\n            isRunning: this.cleanupTimer !== null,\n            config: { ...this.config },\n        }\n    }\n}\n","/**\n * SDK Constants\n */\n\n/** Error messages */\nexport const ERROR_SDK_DESTROYED = 'SDK is destroyed'\nexport const ERROR_WATCHER_RUNNING = 'Watcher is already running'\nexport const ERROR_WATCHER_NOT_RUNNING = 'Watcher is not running'\n","/**\n * Database Access Layer\n *\n * - Query message history (with multiple filter options)\n * - Read message attachment information\n * - Support all message types (iMessage, SMS, RCS)\n * - Support both Bun and Node.js runtimes\n */\n\nimport { exec } from 'node:child_process'\nimport { unlink, writeFile } from 'node:fs/promises'\nimport { homedir, tmpdir } from 'node:os'\nimport { join } from 'node:path'\nimport { promisify } from 'node:util'\nimport type { Attachment, ChatSummary, Message, MessageFilter, MessageQueryResult, ServiceType } from '../types/message'\nimport { DatabaseError } from './errors'\n\nconst execAsync = promisify(exec)\n\n/** Safe type conversion helper functions */\nconst str = (v: unknown, fallback = ''): string => (v == null ? fallback : String(v))\nconst num = (v: unknown, fallback = 0): number => (typeof v === 'number' ? v : fallback)\nconst bool = (v: unknown): boolean => Boolean(v)\n\n/**\n * Runtime detection and database adapter\n * Automatically uses bun:sqlite for Bun runtime, better-sqlite3 for Node.js\n */\ntype DatabaseAdapter = any\n\nlet Database: new (path: string, options?: { readonly?: boolean }) => DatabaseAdapter\n\nasync function initDatabase() {\n    if (Database) return\n\n    // Detect runtime\n    if (typeof Bun !== 'undefined') {\n        // Bun runtime\n        const bunSqlite = await import('bun:sqlite')\n        Database = bunSqlite.Database\n    } else {\n        // Node.js runtime\n        try {\n            const BetterSqlite3 = await import('better-sqlite3')\n            // better-sqlite3 uses default export\n            Database = BetterSqlite3.default || BetterSqlite3\n        } catch (_error) {\n            throw DatabaseError(\n                'better-sqlite3 is required for Node.js runtime. Install it with: npm install better-sqlite3'\n            )\n        }\n    }\n}\n\n/**\n * Read-only access to macOS Messages app SQLite database\n */\nexport class IMessageDatabase {\n    /** SQLite database instance */\n    private db: DatabaseAdapter\n    /** macOS epoch time (timestamp of 2001-01-01) */\n    private readonly MAC_EPOCH = new Date('2001-01-01T00:00:00Z').getTime()\n    /** Initialization promise */\n    private initPromise: Promise<void>\n\n    /**\n     * Open iMessage database\n     * @param path Database file path\n     * @throws DatabaseError When database fails to open\n     */\n    constructor(path: string) {\n        this.initPromise = this.init(path)\n    }\n\n    /**\n     * Initialize database (async)\n     */\n    private async init(path: string): Promise<void> {\n        try {\n            await initDatabase()\n            this.db = new Database(path, { readonly: true })\n        } catch (error) {\n            throw DatabaseError(\n                `Failed to open database at ${path}: ${error instanceof Error ? error.message : String(error)}`\n            )\n        }\n    }\n\n    /**\n     * Ensure database is initialized before any operation\n     */\n    private async ensureInit(): Promise<void> {\n        await this.initPromise\n    }\n\n    /**\n     * Query messages (with multiple filter options)\n     *\n     * @param filter Filter conditions (optional)\n     * @returns Message query result (includes message list and statistics)\n     * @throws DatabaseError When query fails\n     *\n     * @example Query all unread messages\n     * ```ts\n     * const result = await db.getMessages({ unreadOnly: true })\n     * ```\n     *\n     * @example Query messages from specific sender\n     * ```ts\n     * const result = await db.getMessages({\n     *   sender: '+1234567890',\n     *   limit: 20\n     * })\n     * ```\n     *\n     * @example Query recent messages with attachments\n     * ```ts\n     * const result = await db.getMessages({\n     *   hasAttachments: true,\n     *   since: new Date('2024-01-01'),\n     *   limit: 10\n     * })\n     * ```\n     */\n    async getMessages(filter: MessageFilter = {}): Promise<MessageQueryResult> {\n        await this.ensureInit()\n        const {\n            unreadOnly,\n            excludeOwnMessages = true,\n            sender,\n            chatId,\n            service,\n            hasAttachments,\n            since,\n            search,\n            limit,\n        } = filter\n\n        let query = `\n        SELECT \n            message.ROWID as id,\n            message.guid,\n            message.text,\n            message.attributedBody,\n            message.date,\n            message.is_read,\n            message.is_from_me,\n            message.service,\n            handle.id as sender,\n            handle.ROWID as sender_rowid,\n            chat.chat_identifier as chat_id,\n            chat.display_name as chat_name,\n            chat.ROWID as chat_rowid,\n            (SELECT COUNT(*) FROM chat_handle_join WHERE chat_handle_join.chat_id = chat.ROWID) > 1 as is_group_chat\n        FROM message\n        LEFT JOIN handle ON message.handle_id = handle.ROWID\n        LEFT JOIN chat_message_join ON message.ROWID = chat_message_join.message_id\n        LEFT JOIN chat ON chat_message_join.chat_id = chat.ROWID\n        WHERE 1=1\n        `\n\n        const params: (string | number)[] = []\n\n        if (unreadOnly) {\n            query += ' AND message.is_read = 0'\n        }\n\n        if (excludeOwnMessages) {\n            query += ' AND message.is_from_me = 0'\n        }\n\n        if (sender) {\n            query += ' AND handle.id = ?'\n            params.push(sender)\n        }\n\n        if (chatId) {\n            query += ' AND chat.chat_identifier = ?'\n            params.push(chatId)\n        }\n\n        if (service) {\n            query += ' AND message.service = ?'\n            params.push(service)\n        }\n\n        if (hasAttachments) {\n            query += `\n            AND EXISTS (\n                SELECT 1 FROM message_attachment_join \n                WHERE message_attachment_join.message_id = message.ROWID\n            )\n            `\n        }\n\n        if (since) {\n            /** Convert to macOS timestamp (nanoseconds since 2001-01-01) */\n            const macTimestampNs = (since.getTime() - this.MAC_EPOCH) * 1000000\n            query += ' AND message.date >= ?'\n            params.push(macTimestampNs)\n        }\n\n        if (search) {\n            query += ' AND (message.text LIKE ? OR message.attributedBody LIKE ?)'\n            params.push(`%${search}%`, `%${search}%`)\n        }\n\n        query += ' ORDER BY message.date DESC'\n\n        if (limit) {\n            query += ' LIMIT ?'\n            params.push(limit)\n        }\n\n        try {\n            const rows = this.db.prepare(query).all(...params) as Array<Record<string, unknown>>\n            const messages = await Promise.all(rows.map((row) => this.rowToMessage(row)))\n\n            return {\n                messages,\n                total: messages.length,\n                unreadCount: messages.filter((m) => !m.isRead).length,\n            }\n        } catch (error) {\n            throw DatabaseError(`Failed to query messages: ${error instanceof Error ? error.message : String(error)}`)\n        }\n    }\n\n    /**\n     * Get unread messages grouped by sender\n     *\n     * @returns Object with grouped messages and total count\n     *\n     * @example\n     * ```ts\n     * const { grouped, total } = await db.getUnreadMessages()\n     * for (const [sender, messages] of grouped) {\n     *   console.log(`${sender}: ${messages.length} unread messages`)\n     * }\n     * console.log(`Total: ${total}`)\n     * ```\n     */\n    async getUnreadMessages(): Promise<{ grouped: Map<string, Message[]>; total: number }> {\n        const { messages, total } = await this.getMessages({ unreadOnly: true })\n        const grouped = new Map<string, Message[]>()\n\n        for (const msg of messages) {\n            const existing = grouped.get(msg.sender)\n            if (existing) {\n                existing.push(msg)\n            } else {\n                grouped.set(msg.sender, [msg])\n            }\n        }\n\n        return { grouped, total }\n    }\n\n    /**\n     * List chats with filtering and sorting options\n     *\n     * @param options Filter and sort options\n     * @returns Array of chat summaries with unread counts\n     *\n     * @example\n     * ```ts\n     * // Get recent group chats with unread messages\n     * const chats = await db.listChats({\n     *   type: 'group',\n     *   hasUnread: true,\n     *   limit: 20\n     * })\n     * ```\n     */\n    async listChats(options: import('../types/message').ListChatsOptions = {}): Promise<ChatSummary[]> {\n        await this.ensureInit()\n        const { limit, type = 'all', hasUnread, sortBy = 'recent', search } = options\n\n        let query = `\n        SELECT \n            chat.chat_identifier AS chat_identifier,\n            chat.guid AS chat_guid,\n            chat.service_name AS service_name,\n            chat.display_name AS display_name,\n            (\n              SELECT MAX(message.date) \n              FROM chat_message_join cmj \n              INNER JOIN message ON message.ROWID = cmj.message_id \n              WHERE cmj.chat_id = chat.ROWID\n            ) AS last_date,\n            (SELECT COUNT(*) FROM chat_handle_join WHERE chat_handle_join.chat_id = chat.ROWID) > 1 AS is_group_chat,\n            (\n              SELECT COUNT(*) \n              FROM chat_message_join cmj \n              INNER JOIN message ON message.ROWID = cmj.message_id \n              WHERE cmj.chat_id = chat.ROWID \n                AND message.is_read = 0 \n                AND message.is_from_me = 0\n            ) AS unread_count\n        FROM chat\n        WHERE 1=1\n        `\n\n        const params: (string | number)[] = []\n\n        // Filter by type\n        if (type === 'group') {\n            query += ' AND (SELECT COUNT(*) FROM chat_handle_join WHERE chat_handle_join.chat_id = chat.ROWID) > 1'\n        } else if (type === 'dm') {\n            query += ' AND (SELECT COUNT(*) FROM chat_handle_join WHERE chat_handle_join.chat_id = chat.ROWID) <= 1'\n        }\n\n        // Filter by unread\n        if (hasUnread) {\n            query +=\n                ' AND (SELECT COUNT(*) FROM chat_message_join cmj INNER JOIN message ON message.ROWID = cmj.message_id WHERE cmj.chat_id = chat.ROWID AND message.is_read = 0 AND message.is_from_me = 0) > 0'\n        }\n\n        // Search by display name\n        if (search) {\n            query += ' AND chat.display_name LIKE ?'\n            params.push(`%${search}%`)\n        }\n\n        // Sort order\n        if (sortBy === 'recent') {\n            query += ' ORDER BY (last_date IS NULL), last_date DESC'\n        } else if (sortBy === 'name') {\n            query += ' ORDER BY (chat.display_name IS NULL), chat.display_name ASC'\n        }\n\n        // Limit\n        if (limit && limit > 0) {\n            query += ' LIMIT ?'\n            params.push(limit)\n        }\n\n        try {\n            const rows = this.db.prepare(query).all(...params) as Array<Record<string, unknown>>\n            return rows.map((row) => {\n                const isGroup = bool(row.is_group_chat)\n                const guid = str(row.chat_guid)\n                const identifierRaw = row.chat_identifier == null ? '' : str(row.chat_identifier)\n                const service = row.service_name == null ? '' : str(row.service_name)\n\n                // chatId rules:\n                // - Group chats: use chat.guid (stable routing key)\n                // - Direct chats (DM): prefer database chat_identifier if it already contains a semicolon; otherwise prefix with service_name\n                let chatId: string\n                if (isGroup || !identifierRaw) {\n                    chatId = guid\n                } else if (identifierRaw.includes(';')) {\n                    chatId = identifierRaw\n                } else if (service) {\n                    chatId = `${service};${identifierRaw}`\n                } else {\n                    // In rare cases service_name is missing, default to iMessage prefix for consistency\n                    chatId = `iMessage;${identifierRaw}`\n                }\n\n                const displayName = row.display_name == null ? null : str(row.display_name)\n                const lastDateRaw = row.last_date\n                const lastMessageAt = typeof lastDateRaw === 'number' ? this.convertMacTimestamp(lastDateRaw) : null\n                const unreadCount = typeof row.unread_count === 'number' ? row.unread_count : 0\n\n                return {\n                    chatId,\n                    displayName,\n                    lastMessageAt,\n                    isGroup,\n                    unreadCount,\n                }\n            })\n        } catch (error) {\n            throw DatabaseError(`Failed to list chats: ${error instanceof Error ? error.message : String(error)}`)\n        }\n    }\n\n    /**\n     * Get all attachments for specified message\n     * @param messageId Message ID\n     * @returns Array of attachments, returns empty array if no attachments\n     */\n    private async getAttachments(messageId: string): Promise<Attachment[]> {\n        await this.ensureInit()\n        const query = `\n        SELECT \n            attachment.ROWID as id,\n            attachment.filename,\n            attachment.mime_type,\n            attachment.total_bytes as size,\n            attachment.created_date as created_date\n        FROM attachment\n        INNER JOIN message_attachment_join ON attachment.ROWID = message_attachment_join.attachment_id\n        WHERE message_attachment_join.message_id = ?\n        `\n\n        try {\n            const rows = this.db.prepare(query).all(messageId) as Array<Record<string, unknown>>\n\n            return rows.map((row) => {\n                const rawPath = str(row.filename)\n                const mimeType = str(row.mime_type, 'application/octet-stream')\n\n                /** Expand path: ~ to home directory, relative paths joined to Messages attachments directory */\n                let fullPath: string\n                if (rawPath.startsWith('~')) {\n                    fullPath = rawPath.replace(/^~/, homedir())\n                } else if (rawPath && !rawPath.startsWith('/')) {\n                    fullPath = join(homedir(), 'Library/Messages/Attachments', rawPath)\n                } else {\n                    fullPath = rawPath\n                }\n\n                return {\n                    id: str(row.id),\n                    filename: rawPath.split('/').pop() || 'unknown',\n                    mimeType,\n                    path: fullPath,\n                    size: num(row.size, 0),\n                    isImage: mimeType.startsWith('image/'),\n                    createdAt: this.convertMacTimestamp(row.created_date),\n                }\n            })\n        } catch {\n            return []\n        }\n    }\n\n    /**\n     * Decode XML entities in a string\n     * @param text Text with XML entities\n     * @returns Decoded text\n     */\n    private decodeXmlEntities(text: string): string {\n        return text\n            .replace(/&lt;/g, '<')\n            .replace(/&gt;/g, '>')\n            .replace(/&amp;/g, '&')\n            .replace(/&quot;/g, '\"')\n            .replace(/&apos;/g, \"'\")\n    }\n\n    /**\n     * Extract text from attributedBody (binary plist format)\n     * @param attributedBody Binary plist data\n     * @returns Extracted text or null if extraction fails\n     */\n    private async extractTextFromAttributedBody(attributedBody: unknown): Promise<string | null> {\n        if (!attributedBody) return null\n\n        try {\n            // attributedBody is typically a Buffer in Node.js or Uint8Array in Bun\n            let buffer: Buffer | Uint8Array\n            if (Buffer.isBuffer(attributedBody)) {\n                buffer = attributedBody\n            } else if (attributedBody instanceof Uint8Array) {\n                buffer = Buffer.from(attributedBody)\n            } else {\n                return null\n            }\n\n            // First, try to extract text directly from buffer (faster fallback)\n            // NSAttributedString plist often contains the actual text as readable strings\n            const bufferStr = buffer.toString('utf8')\n            // Look for longer readable text patterns (at least 5 characters) that are likely message content\n            // Exclude common plist keywords like \"NSAttributedString\", \"NSDictionary\", etc.\n            const excludedPatterns =\n                /^(NSAttributedString|NSMutableAttributedString|NSObject|NSString|NSMutableString|NSDictionary|NSNumber|NSValue|streamtyped|__kIMMessagePartAttributeName|__kIMPhoneNumberAttributeName|PhoneNumber|NS\\.rangeval|locationZNS\\.special)$/i\n            const readableMatches = bufferStr.match(/[\\x20-\\x7E\\u4e00-\\u9fff]{5,}/g)\n            if (readableMatches) {\n                // Filter out plist keywords and find text that looks like actual message content\n                const messageCandidates = readableMatches\n                    .filter((match) => {\n                        // Exclude plist keywords\n                        if (excludedPatterns.test(match)) return false\n                        // Exclude patterns that look like metadata (contain brackets, colons in wrong places, etc.)\n                        if (/^[\\[\\(\\)\\]\\*,\\-:X]+$/.test(match)) return false\n                        // Exclude NS object property patterns like \"NS.rangeval.locationZNS.special\"\n                        if (/^NS\\.\\w+/.test(match)) return false\n                        // Exclude attribute names starting with __kIM\n                        if (/^__kIM/.test(match)) return false\n                        // Exclude plist binary format markers like \"$versionY$archiverT$topX$objects\"\n                        if (/\\$version|\\$archiver|\\$top|\\$objects|\\$class/.test(match)) return false\n                        // Prefer text that contains Chinese characters or looks like actual content\n                        return match.length > 5\n                    })\n                    .map((match) => ({\n                        text: match,\n                        // Score: higher for Chinese characters, longer text, and content-like patterns\n                        score:\n                            (match.match(/[\\u4e00-\\u9fff]/g)?.length || 0) * 10 +\n                            match.length +\n                            (match.match(/[a-zA-Z]/) ? 5 : 0) -\n                            (match.match(/[\\[\\(\\)\\]\\*,\\-:X]/g)?.length || 0) * 5 -\n                            (match.match(/^__kIM|^NS\\.|\\$version|\\$archiver|\\$top|\\$objects|\\$class/) ? 100 : 0), // Heavily penalize attribute names and plist markers\n                    }))\n                    .sort((a, b) => b.score - a.score) // Sort by score, highest first\n\n                if (messageCandidates.length > 0) {\n                    // Return the highest-scoring candidate that's likely the actual message\n                    const bestCandidate = messageCandidates[0]!\n                    // Clean up common prefixes/suffixes that might be plist artifacts\n                    return bestCandidate.text\n                        .replace(/^\\+\"/, '') // Remove leading +\"\n                        .replace(/\"$/, '') // Remove trailing \"\n                        .trim()\n                }\n            }\n\n            // If direct extraction didn't work, try plutil (macOS built-in tool)\n            // Write buffer to a temporary file and convert plist to XML\n            const tempFile = join(\n                tmpdir(),\n                `imsg_attributedBody_${Date.now()}_${Math.random().toString(36).substring(7)}.plist`\n            )\n\n            try {\n                await writeFile(tempFile, buffer)\n\n                // Convert binary plist to XML using plutil\n                const { stdout } = await execAsync(`plutil -convert xml1 -o - \"${tempFile}\"`, {\n                    timeout: 5000,\n                    maxBuffer: 1024 * 1024, // 1MB buffer\n                })\n\n                // Extract string content from NSAttributedString plist\n                // Look for <string> tags in the XML\n                const stringMatches = stdout.match(/<string>([\\s\\S]*?)<\\/string>/g)\n                if (stringMatches && stringMatches.length > 0) {\n                    // Filter out plist keywords and find the actual message text\n                    const textCandidates = stringMatches\n                        .map((match) => {\n                            const textMatch = match.match(/<string>([\\s\\S]*?)<\\/string>/)\n                            return textMatch?.[1]\n                        })\n                        .filter((text): text is string => {\n                            if (!text) return false\n                            // Decode XML entities\n                            const decoded = this.decodeXmlEntities(text)\n                            // Exclude plist keywords\n                            return decoded.length > 5 && !excludedPatterns.test(decoded)\n                        })\n                        .sort((a, b) => b.length - a.length) // Sort by length, longest first\n\n                    if (textCandidates.length > 0) {\n                        // Decode XML entities for the selected candidate\n                        return this.decodeXmlEntities(textCandidates[0]!)\n                    }\n                }\n            } finally {\n                // Clean up temp file\n                try {\n                    await unlink(tempFile)\n                } catch {\n                    // Ignore cleanup errors\n                }\n            }\n        } catch (error) {\n            // If all methods fail, return null\n        }\n\n        return null\n    }\n\n    /**\n     * Convert database query result to Message object\n     * @param row Raw row data from database query\n     * @returns Formatted Message object\n     */\n    private async rowToMessage(row: Record<string, unknown>): Promise<Message> {\n        // Try to get text from text field first\n        let messageText: string | null = row.text ? str(row.text) : null\n\n        // If text is null and attributedBody exists, try to extract from attributedBody\n        if (!messageText && row.attributedBody) {\n            messageText = await this.extractTextFromAttributedBody(row.attributedBody)\n        }\n\n        return {\n            id: str(row.id),\n            guid: str(row.guid),\n            text: messageText,\n            sender: str(row.sender, 'Unknown'),\n            senderName: null,\n            chatId: str(row.chat_id),\n            isGroupChat: bool(row.is_group_chat),\n            service: this.mapService(row.service),\n            isRead: bool(row.is_read),\n            isFromMe: bool(row.is_from_me),\n            attachments: await this.getAttachments(str(row.id)),\n            date: this.convertMacTimestamp(row.date),\n        }\n    }\n\n    /**\n     * Map service type string from database\n     * @param service Service identifier from database\n     * @returns Standardized service type\n     */\n    private mapService(service: unknown): ServiceType {\n        if (!service || typeof service !== 'string') return 'iMessage'\n        const lower = service.toLowerCase()\n        if (lower.includes('sms')) return 'SMS'\n        if (lower.includes('rcs')) return 'RCS'\n        return 'iMessage'\n    }\n\n    /**\n     * Convert macOS timestamp to JavaScript Date object\n     *\n     * macOS epoch starts at 2001-01-01, unit is nanoseconds\n     * @param timestamp macOS timestamp\n     * @returns JavaScript Date object\n     */\n    private convertMacTimestamp(timestamp: unknown): Date {\n        if (!timestamp || typeof timestamp !== 'number') return new Date()\n        return new Date(this.MAC_EPOCH + timestamp / 1000000)\n    }\n\n    /**\n     * Close database connection\n     */\n    async close() {\n        await this.ensureInit()\n        this.db.close()\n    }\n}\n","/**\n * Outgoing Message Manager\n *\n * Manages all pending outgoing messages and matches them with database entries\n */\n\nimport type { Message } from '../types/message'\nimport type { MessagePromise } from './message-promise'\n\nexport class OutgoingMessageManager {\n    private promises: MessagePromise[] = []\n    private debug: boolean\n\n    constructor(debug = false) {\n        this.debug = debug\n    }\n\n    /**\n     * Add a new message promise to track\n     */\n    add(promise: MessagePromise): void {\n        this.promises.push(promise)\n\n        if (this.debug) {\n            console.log(\n                `[OutgoingManager] Tracking new ${promise.isAttachment ? 'attachment' : 'message'}: ${promise.chatId}`\n            )\n        }\n    }\n\n    /**\n     * Try to match and resolve a message promise\n     * Returns true if a match was found\n     */\n    tryResolve(message: Message): boolean {\n        // Only process messages from self\n        if (!message.isFromMe) {\n            return false\n        }\n\n        // Find matching promise\n        for (let i = 0; i < this.promises.length; i++) {\n            const promise = this.promises[i]\n\n            if (!promise || promise.isResolved) continue\n\n            if (promise.matches(message)) {\n                if (this.debug) {\n                    console.log(`[OutgoingManager] Matched message: ${message.id}`)\n                }\n\n                promise.resolve(message)\n                return true\n            }\n        }\n\n        return false\n    }\n\n    /**\n     * Clean up resolved promises (older than 1 minute)\n     */\n    cleanup(): void {\n        const now = Date.now()\n        const oneMinute = 60 * 1000\n\n        this.promises = this.promises.filter((p) => {\n            if (!p.isResolved) return true\n\n            // Keep resolved promises for 1 minute\n            return now - p.sentAt < oneMinute\n        })\n    }\n\n    /**\n     * Get count of pending promises\n     */\n    getPendingCount(): number {\n        return this.promises.filter((p) => !p.isResolved).length\n    }\n\n    /**\n     * Reject all pending promises (used when closing SDK)\n     */\n    rejectAll(reason = 'SDK closed'): void {\n        for (const promise of this.promises) {\n            if (!promise.isResolved) {\n                promise.reject(reason)\n            }\n        }\n        this.promises = []\n    }\n}\n","/**\n * AppleScript Utilities\n *\n * Generate and execute Messages app control scripts\n * Wait for script completion (30s timeout)\n * Special character escaping (prevent injection)\n * Sandbox bypass (auto-copy to ~/Pictures)\n * Upload wait (ensure iMessage uploads to iCloud)\n */\n\nimport { exec } from 'node:child_process'\nimport { promisify } from 'node:util'\n\nconst execAsync = promisify(exec)\n\n/** Default script execution timeout (can be overridden) */\nconst DEFAULT_SCRIPT_TIMEOUT = 30000\n\n/**\n * Execute AppleScript\n *\n * @param script - AppleScript code\n * @param debug - Whether to output debug logs\n * @param timeoutMs - Timeout in milliseconds (default 30s)\n * @returns Script output\n * @throws Error when execution fails\n */\nexport const execAppleScript = async (\n    script: string,\n    debug = false,\n    timeoutMs = DEFAULT_SCRIPT_TIMEOUT\n): Promise<string> => {\n    if (debug) {\n        console.log('[AppleScript] Executing script:\\n', script)\n    }\n\n    try {\n        const escapedScript = script.replace(/'/g, \"'\\\\''\")\n        const { stdout, stderr } = await execAsync(`osascript -e '${escapedScript}'`, {\n            timeout: timeoutMs,\n            encoding: 'utf-8',\n        })\n\n        if (stderr && debug) {\n            console.warn('[AppleScript] Warning:', stderr)\n        }\n\n        if (debug) {\n            console.log('[AppleScript] Success:', stdout || '(no output)')\n        }\n\n        return stdout.trim()\n    } catch (error: any) {\n        const errorMsg = error.message || String(error)\n\n        if (error.killed || errorMsg.includes('timeout')) {\n            const message = [\n                `AppleScript execution timeout (${timeoutMs}ms)`,\n                'may be slow network or large file',\n            ].join(' - ')\n            throw new Error(message)\n        }\n\n        if (errorMsg.includes(\"Can't get buddy\")) {\n            throw new Error('Recipient not found or not added to iMessage contacts')\n        }\n\n        if (errorMsg.includes(\"Can't send\")) {\n            const reasons = [\n                '1) Is Messages signed in to iMessage',\n                '2) Is recipient correct',\n                '3) Network connection',\n            ].join(', ')\n            throw new Error(`Send failed - please check: ${reasons}`)\n        }\n\n        if (debug) {\n            console.error('[AppleScript] Error details:', error)\n        }\n\n        throw new Error(`AppleScript execution failed: ${errorMsg}`)\n    }\n}\n\n/**\n * Check if Messages app is running\n *\n * Uses pgrep command to find process\n *\n * @returns true if app is running\n */\nexport const checkMessagesApp = async (): Promise<boolean> => {\n    try {\n        await execAsync('pgrep -x Messages', {\n            timeout: DEFAULT_SCRIPT_TIMEOUT,\n        })\n        return true\n    } catch {\n        return false\n    }\n}\n\n/**\n * Check if iMessage is signed in and active\n *\n * @param debug - Whether to output debug logs\n * @returns true if likely signed in\n */\nexport const checkIMessageStatus = async (debug = false): Promise<boolean> => {\n    try {\n        const script = `\ntell application \"Messages\"\n    try\n        set accountList to every account\n        if (count of accountList) is 0 then\n            return \"no_accounts\"\n        end if\n        \n        set hasActiveAccount to false\n        repeat with acct in accountList\n            if enabled of acct is true then\n                set hasActiveAccount to true\n                exit repeat\n            end if\n        end repeat\n        \n        if hasActiveAccount then\n            return \"active\"\n        else\n            return \"inactive\"\n        end if\n    on error\n        return \"error\"\n    end try\nend tell\n`\n        const escapedScript = script.replace(/'/g, \"'\\\\''\")\n        const { stdout } = await execAsync(`osascript -e '${escapedScript}'`, {\n            timeout: 5000,\n        })\n\n        const result = stdout.trim()\n\n        if (debug) {\n            console.log('[iMessage Status Check]', result)\n        }\n\n        return result === 'active'\n    } catch (error) {\n        if (debug) {\n            console.warn('[iMessage Status Check Failed]', error)\n        }\n        return true\n    }\n}\n\n/**\n * Escape special characters in AppleScript string\n *\n * Prevent script injection and syntax errors\n *\n * @param str Original string\n * @returns Escaped string\n */\nconst escapeAppleScriptString = (str: string): string => {\n    /** Escape mapping table */\n    const escapeMap: Record<string, string> = {\n        '\\\\': '\\\\\\\\', // Backslash\n        '\"': '\\\\\"', // Double quote\n        '\\n': '\\\\n', // Newline\n        '\\r': '\\\\r', // Carriage return\n        '\\t': '\\\\t', // Tab\n    }\n\n    return str.replace(/[\\\\\\n\\r\\t\"]/g, (char) => escapeMap[char] || char)\n}\n\n/**\n * Generate AppleScript for sending plain text message\n *\n * @param recipient Recipient (phone number or email)\n * @param text Message content\n * @returns AppleScript code\n */\nexport const generateSendTextScript = (recipient: string, text: string): string => {\n    const escapedText = escapeAppleScriptString(text)\n\n    return `\ntell application \"Messages\"\n    set targetBuddy to buddy \"${recipient}\"\n    send \"${escapedText}\" to targetBuddy\nend tell\n`.trim()\n}\n\n/**\n * Generate AppleScript for sending plain text to a chat by chatId\n *\n * @param chatId Chat identifier from Messages database\n * @param text Message content\n * @returns AppleScript code\n */\nexport const generateSendTextToChat = (chatId: string, text: string): string => {\n    const escapedText = escapeAppleScriptString(text)\n    const escapedChatId = escapeAppleScriptString(chatId)\n\n    return `\ntell application \"Messages\"\n    set targetChat to chat id \"${escapedChatId}\"\n    send \"${escapedText}\" to targetChat\nend tell\n`.trim()\n}\n\n/**\n * Check if file needs sandbox bypass\n */\nfunction needsSandboxBypass(filePath: string): boolean {\n    return !filePath.match(/(Pictures|Downloads|Documents)/)\n}\n\n/**\n * Calculate delay based on file size\n * Small files: 2s, Medium files: 3s, Large files: 5s\n */\nfunction calculateFileDelay(filePath: string): number {\n    try {\n        const fs = require('node:fs')\n        const stats = fs.statSync(filePath)\n        const sizeInMB = stats.size / (1024 * 1024)\n\n        if (sizeInMB < 1) return 2 // < 1MB: 2 seconds\n        if (sizeInMB < 10) return 3 // 1-10MB: 3 seconds\n        return 5 // > 10MB: 5 seconds\n    } catch {\n        return 3 // Default to 3 seconds if file size check fails\n    }\n}\n\n/**\n * Generate sandbox bypass script snippet\n *\n * Copy file to ~/Pictures/imsg_temp_* to bypass sandbox restrictions\n * TempFileManager will auto-scan and clean these files\n */\nfunction generateSandboxBypassScript(filePath: string, recipient: string): string {\n    const fileName = filePath.split('/').pop()\n    const tempFileName = `imsg_temp_${Date.now()}_${fileName}`\n    const delay = calculateFileDelay(filePath)\n\n    return `\n    -- Bypass sandbox: copy to Pictures directory\n    set picturesFolder to POSIX path of (path to pictures folder)\n    set targetPath to picturesFolder & \"${tempFileName}\"\n    do shell script \"cp \" & quoted form of \"${filePath}\" & \" \" & quoted form of targetPath\n    \n    -- Create file reference and send\n    set theFile to (POSIX file targetPath) as alias\n    set targetBuddy to buddy \"${recipient}\"\n    send theFile to targetBuddy\n    delay ${delay}\n    `.trim()\n}\n\n/**\n * Generate sandbox bypass script snippet for chatId target\n */\nfunction generateSandboxBypassScriptForChat(filePath: string, chatId: string): string {\n    const escapedChatId = escapeAppleScriptString(chatId)\n    const fileName = filePath.split('/').pop()\n    const tempFileName = `imsg_temp_${Date.now()}_${fileName}`\n    const delay = calculateFileDelay(filePath)\n\n    return `\n    -- Bypass sandbox: copy to Pictures directory\n    set picturesFolder to POSIX path of (path to pictures folder)\n    set targetPath to picturesFolder & \"${tempFileName}\"\n    do shell script \"cp \" & quoted form of \"${filePath}\" & \" \" & quoted form of targetPath\n    \n    -- Create file reference and send\n    set theFile to (POSIX file targetPath) as alias\n    set targetChat to chat id \"${escapedChatId}\"\n    send theFile to targetChat\n    delay ${delay}\n    `.trim()\n}\n\n/**\n * Generate direct file send script snippet\n */\nfunction generateDirectSendScript(filePath: string, recipient: string): string {\n    const escapedPath = escapeAppleScriptString(filePath)\n    const delay = calculateFileDelay(filePath)\n    return `\n    set targetBuddy to buddy \"${recipient}\"\n    send POSIX file \"${escapedPath}\" to targetBuddy\n    delay ${delay}\n    `.trim()\n}\n\n/**\n * Generate direct file send script snippet for chatId target\n */\nfunction generateDirectSendScriptForChat(filePath: string, chatId: string): string {\n    const escapedChatId = escapeAppleScriptString(chatId)\n    const escapedPath = escapeAppleScriptString(filePath)\n    const delay = calculateFileDelay(filePath)\n    return `\n    set targetChat to chat id \"${escapedChatId}\"\n    send POSIX file \"${escapedPath}\" to targetChat\n    delay ${delay}\n    `.trim()\n}\n\n/**\n * Generate AppleScript for sending attachment\n *\n * @param recipient Recipient\n * @param filePath Full path to attachment file\n * @param debug - Whether to output debug logs\n * @returns { script } - AppleScript code\n */\nexport const generateSendAttachmentScript = (\n    recipient: string,\n    filePath: string,\n    debug = false\n): { script: string } => {\n    const needsBypass = needsSandboxBypass(filePath)\n\n    if (needsBypass && debug) {\n        console.log('[AppleScript] Non-sandbox directory detected, will temporarily copy to ~/Pictures')\n    }\n\n    const sendScript = needsBypass\n        ? generateSandboxBypassScript(filePath, recipient)\n        : generateDirectSendScript(filePath, recipient)\n\n    return {\n        script: `\ntell application \"Messages\"\n${sendScript}\nend tell\n        `.trim(),\n    }\n}\n\n/**\n * Generate AppleScript for sending attachment to a chat by chatId\n */\nexport const generateSendAttachmentToChat = (chatId: string, filePath: string, debug = false): { script: string } => {\n    const needsBypass = needsSandboxBypass(filePath)\n\n    if (needsBypass && debug) {\n        console.log('[AppleScript] Non-sandbox directory detected, will temporarily copy to ~/Pictures')\n    }\n\n    const sendScript = needsBypass\n        ? generateSandboxBypassScriptForChat(filePath, chatId)\n        : generateDirectSendScriptForChat(filePath, chatId)\n\n    return {\n        script: `\ntell application \"Messages\"\n${sendScript}\nend tell\n        `.trim(),\n    }\n}\n\n/**\n * Generate AppleScript for sending text with attachment\n *\n * Send text first, then attachment (also handles sandbox restrictions)\n *\n * @param recipient Recipient\n * @param text Message content\n * @param filePath Attachment file path\n * @returns { script } - AppleScript code\n */\nexport const generateSendWithAttachmentScript = (\n    recipient: string,\n    text: string,\n    filePath: string\n): { script: string } => {\n    const escapedText = escapeAppleScriptString(text)\n    const needsBypass = needsSandboxBypass(filePath)\n\n    const attachmentScript = needsBypass\n        ? generateSandboxBypassScript(filePath, recipient)\n        : generateDirectSendScript(filePath, recipient)\n\n    return {\n        script: `\ntell application \"Messages\"\n    set targetBuddy to buddy \"${recipient}\"\n    \n    -- Send text\n    send \"${escapedText}\" to targetBuddy\n    \n    -- Send attachment\n${attachmentScript}\nend tell\n        `.trim(),\n    }\n}\n\n/**\n * Generate AppleScript for sending text with attachment to a chat by chatId\n */\nexport const generateSendWithAttachmentToChat = (\n    chatId: string,\n    text: string,\n    filePath: string\n): { script: string } => {\n    const escapedText = escapeAppleScriptString(text)\n    const escapedChatId = escapeAppleScriptString(chatId)\n    const needsBypass = needsSandboxBypass(filePath)\n\n    const attachmentScript = needsBypass\n        ? generateSandboxBypassScriptForChat(filePath, chatId)\n        : generateDirectSendScriptForChat(filePath, chatId)\n\n    return {\n        script: `\ntell application \"Messages\"\n    set targetChat to chat id \"${escapedChatId}\"\n    \n    -- Send text\n    send \"${escapedText}\" to targetChat\n    \n    -- Send attachment\n${attachmentScript}\nend tell\n        `.trim(),\n    }\n}\n","/**\n * Network image download and format conversion\n * - Downloads images to temp directory\n * - Converts AVIF/WebP to JPEG for iMessage compatibility\n */\n\nimport { exec } from 'node:child_process'\nimport { existsSync, writeFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { promisify } from 'node:util'\nimport { SendError } from '../core/errors'\nimport { delay } from './common'\n\nconst execAsync = promisify(exec)\nconst TEMP_DIR = join(homedir(), 'Pictures')\n\ninterface DownloadOptions {\n    timeout?: number // Default: 15000ms\n    maxRetries?: number // Default: 2\n    retryDelay?: number // Default: 1000ms\n    debug?: boolean\n}\n\n/** Convert image to JPEG using macOS sips command */\nconst convertImageToJPEG = async (inputPath: string, outputPath?: string): Promise<string> => {\n    const output = outputPath || join(TEMP_DIR, `imsg_temp_${Date.now()}.jpg`)\n\n    try {\n        const cmd = `sips -s format jpeg \"${inputPath}\" --out \"${output}\"`\n        await execAsync(cmd, { timeout: 10000 })\n\n        if (!existsSync(output)) {\n            throw new Error('Converted file does not exist')\n        }\n\n        return output\n    } catch (error) {\n        const msg = error instanceof Error ? error.message : String(error)\n        throw SendError(`Image format conversion failed: ${msg}`)\n    }\n}\n\n/**\n * Download network image with automatic format conversion\n * @throws SendError when download fails after retries\n */\nexport const downloadImage = async (url: string, options: DownloadOptions = {}): Promise<string> => {\n    const { timeout = 15000, maxRetries = 2, retryDelay = 1000, debug = false } = options\n    let lastError: Error | null = null\n\n    if (debug) {\n        console.log(`[Download] ${url.length > 60 ? `${url.slice(0, 60)}...` : url}`)\n    }\n\n    for (let attempt = 0; attempt <= maxRetries; attempt++) {\n        try {\n            if (attempt > 0) {\n                await delay(retryDelay * 2 ** (attempt - 1))\n            }\n\n            const controller = new AbortController()\n            const timeoutId = setTimeout(() => controller.abort(), timeout)\n\n            const response = await fetch(url, {\n                signal: controller.signal,\n                headers: {\n                    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36',\n                    Accept: 'image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8',\n                    'Accept-Encoding': 'gzip, deflate, br',\n                },\n            })\n\n            clearTimeout(timeoutId)\n\n            if (!response.ok) {\n                throw new Error(`HTTP ${response.status} ${response.statusText}`)\n            }\n\n            const contentType = response.headers.get('content-type')?.toLowerCase() || ''\n            const buffer = Buffer.from(await response.arrayBuffer())\n\n            // Handle AVIF/WebP - convert to JPEG\n            if (contentType.includes('avif') || contentType.includes('webp')) {\n                const ext = contentType.includes('avif') ? '.avif' : '.webp'\n                const tempPath = join(TEMP_DIR, `imsg_temp_${Date.now()}${ext}`)\n                writeFileSync(tempPath, buffer)\n\n                const converted = await convertImageToJPEG(tempPath)\n                if (debug) {\n                    console.log(`[Download] Converted ${ext} -> .jpg`)\n                }\n                return converted\n            }\n\n            // Detect extension for other formats\n            const extMap: Record<string, string> = {\n                png: '.png',\n                gif: '.gif',\n                svg: '.svg',\n                bmp: '.bmp',\n            }\n            const ext = Object.entries(extMap).find(([key]) => contentType.includes(key))?.[1] || '.jpg'\n\n            const path = join(TEMP_DIR, `imsg_temp_${Date.now()}${ext}`)\n            writeFileSync(path, buffer)\n            return path\n        } catch (error) {\n            lastError = error instanceof Error ? error : new Error(String(error))\n\n            if (lastError.name === 'AbortError') {\n                lastError = new Error(`Request timeout (${timeout}ms)`)\n            }\n\n            if (attempt === maxRetries) {\n                throw SendError(`Download failed (${maxRetries + 1} attempts): ${lastError.message}\\nURL: ${url}`)\n            }\n\n            if (debug && attempt > 0) {\n                console.warn(`[Download] Retry ${attempt + 1}/${maxRetries + 1}: ${lastError.message}`)\n            }\n        }\n    }\n\n    throw SendError(`Download failed: ${lastError?.message}`)\n}\n\n/**\n * Convert AVIF/WebP images to JPEG for iMessage compatibility\n * @returns {path, converted} - Returns original path if no conversion needed\n */\nexport const convertToCompatibleFormat = async (filePath: string): Promise<{ path: string; converted: boolean }> => {\n    const ext = filePath.split('.').pop()?.toLowerCase()\n\n    if (!ext || !['avif', 'webp'].includes(ext)) {\n        return { path: filePath, converted: false }\n    }\n\n    const fileName = filePath\n        .split('/')\n        .pop()!\n        .replace(/\\.(avif|webp)$/i, '.jpg')\n    const isOurTemp = fileName.startsWith('imsg_temp_')\n    const output = isOurTemp ? join(TEMP_DIR, fileName) : join(TEMP_DIR, `imsg_temp_${Date.now()}_${fileName}`)\n\n    const converted = await convertImageToJPEG(filePath, output)\n    return { path: converted, converted: true }\n}\n","/**\n * Semaphore - Limit concurrency\n */\nexport class Semaphore {\n    private running = 0\n    private waiting: Array<() => void> = []\n\n    constructor(private readonly limit: number) {\n        if (limit <= 0) {\n            throw new Error('Concurrency limit must be greater than 0')\n        }\n    }\n\n    /**\n     * Acquire semaphore\n     *\n     * @returns Release function\n     */\n    async acquire(): Promise<() => void> {\n        while (this.running >= this.limit) {\n            await new Promise<void>((resolve) => this.waiting.push(resolve))\n        }\n\n        this.running++\n\n        return () => {\n            this.running--\n            const next = this.waiting.shift()\n            if (next) {\n                next()\n            }\n        }\n    }\n\n    /**\n     * Run async function (auto-manage semaphore)\n     *\n     * @param fn Async function\n     * @returns Function execution result\n     */\n    async run<T>(fn: () => Promise<T>): Promise<T> {\n        const release = await this.acquire()\n        try {\n            return await fn()\n        } finally {\n            release()\n        }\n    }\n}\n","/**\n * Message Promise\n *\n * Tracks outgoing messages and resolves when they appear in the database\n */\n\nimport type { Message } from '../types/message'\n\nexport class MessagePromiseRejection extends Error {\n    readonly error: string\n    readonly msg: Message | null\n    readonly tempGuid: string | null\n\n    constructor(error: string, message?: Message, tempGuid?: string) {\n        super(error)\n        this.name = this.constructor.name\n        this.error = error\n        this.msg = message ?? null\n        this.tempGuid = tempGuid ?? null\n        Error.captureStackTrace(this, this.constructor)\n    }\n}\n\nexport interface MessagePromiseOptions {\n    chatId: string\n    text?: string\n    attachmentName?: string\n    isAttachment: boolean\n    sentAt: Date | number\n    debug?: boolean\n}\n\n/**\n * Promise wrapper for tracking outgoing messages\n */\nexport class MessagePromise {\n    promise: Promise<Message>\n\n    private resolvePromise!: (value: Message) => void\n    private rejectPromise!: (reason: MessagePromiseRejection) => void\n\n    readonly chatId: string\n    readonly text: string\n    readonly attachmentName: string | null\n    readonly isAttachment: boolean\n    readonly sentAt: number\n    private readonly debug: boolean\n\n    isResolved = false\n    errored = false\n    error: any = null\n\n    private timeoutHandle: NodeJS.Timeout\n\n    constructor(options: MessagePromiseOptions) {\n        this.debug = options.debug ?? false\n        this.chatId = options.chatId\n        this.text = this.normalizeText(options.text ?? '')\n        this.attachmentName = options.attachmentName ?? null\n        this.isAttachment = options.isAttachment\n        this.sentAt = typeof options.sentAt === 'number' ? options.sentAt : options.sentAt.getTime()\n\n        this.promise = new Promise((resolve, reject) => {\n            this.resolvePromise = resolve\n            this.rejectPromise = reject\n        })\n\n        this.promise.catch((err: any) => {\n            this.errored = true\n            this.error = err\n        })\n\n        // Timeout configuration:\n        // - Attachments: 30 seconds (longer due to file upload time, especially for large files)\n        // - Text messages: 10 seconds (typically faster, only text data to send)\n        // These values account for AppleScript execution, Messages app processing,\n        // and database write delays. Adjust if experiencing frequent timeouts.\n        const timeout = this.isAttachment ? 30 * 1000 : 10 * 1000\n        this.timeoutHandle = setTimeout(() => {\n            if (!this.isResolved) {\n                this.reject(`Message send timeout after ${timeout}ms`)\n            }\n        }, timeout)\n    }\n\n    /**\n     * Normalize text for comparison\n     * Only remove whitespace and convert to lowercase for case-insensitive matching\n     * Keep all other characters including Unicode (Chinese, emoji, etc.)\n     */\n    private normalizeText(text: string): string {\n        return text.replace(/\\s+/g, '').toLowerCase()\n    }\n\n    /**\n     * Get filename without extension\n     */\n    private getFilenameWithoutExtension(filename: string): string {\n        const lastDot = filename.lastIndexOf('.')\n        if (lastDot === -1) return filename\n        return filename.substring(0, lastDot)\n    }\n\n    /**\n     * Resolve the promise with the sent message\n     */\n    resolve(message: Message): void {\n        if (this.isResolved) return\n\n        this.isResolved = true\n        clearTimeout(this.timeoutHandle)\n        this.resolvePromise(message)\n    }\n\n    /**\n     * Reject the promise with an error\n     */\n    reject(reason: string, message?: Message): void {\n        if (this.isResolved) return\n\n        this.isResolved = true\n        clearTimeout(this.timeoutHandle)\n        this.rejectPromise(new MessagePromiseRejection(reason, message))\n    }\n\n    /**\n     * Check if this promise matches the given message\n     */\n    matches(message: Message): boolean {\n        // Check if message is too old (sent before this promise was created)\n        const timeDiff = message.date.getTime() - this.sentAt\n        if (timeDiff < -5000) {\n            if (this.debug) console.log('[MessagePromise] Time check failed:', { timeDiff, tooOld: true })\n            return false\n        }\n\n        // Check chat ID\n        if (!this.matchesChatId(message.chatId)) {\n            if (this.debug)\n                console.log('[MessagePromise] ChatId mismatch:', {\n                    expected: this.chatId,\n                    actual: message.chatId,\n                })\n            return false\n        }\n\n        // Check attachment\n        if (this.isAttachment) {\n            if (!message.attachments || message.attachments.length === 0) {\n                if (this.debug) console.log('[MessagePromise] No attachments in message')\n                return false\n            }\n\n            // Match by attachment filename\n            if (this.attachmentName) {\n                const normalizedName = this.getFilenameWithoutExtension(this.attachmentName).toLowerCase()\n                const match = message.attachments.some((att) => {\n                    const attName = this.getFilenameWithoutExtension(att.filename).toLowerCase()\n                    return attName === normalizedName\n                })\n                if (this.debug)\n                    console.log('[MessagePromise] Attachment match:', {\n                        expected: normalizedName,\n                        actual: message.attachments.map((a) =>\n                            this.getFilenameWithoutExtension(a.filename).toLowerCase()\n                        ),\n                        match,\n                    })\n                return match\n            }\n\n            return true\n        }\n\n        // Check text content\n        const messageText = this.normalizeText(message.text ?? '')\n        const matches = this.text === messageText\n\n        if (this.debug) {\n            console.log('[MessagePromise] Text match:', {\n                expected: this.text,\n                actual: messageText,\n                matches,\n                originalText: message.text,\n            })\n        }\n\n        return matches\n    }\n\n    /**\n     * Check if chat ID matches (handles different formats)\n     */\n    private matchesChatId(chatId: string): boolean {\n        if (chatId === this.chatId) return true\n\n        // Handle different chat ID formats\n        // e.g., \"iMessage;+;chat123\" vs \"chat123\"\n        const normalized1 = this.normalizeChatId(chatId)\n        const normalized2 = this.normalizeChatId(this.chatId)\n\n        return normalized1 === normalized2\n    }\n\n    /**\n     * Normalize chat ID for comparison\n     *\n     * Handles format differences between what we construct and what's in the database:\n     *\n     * Database stores (from message.chatId):\n     * - DM: \"pilot@photon.codes\" (no prefix)\n     * - Group: \"chat493787071395575843\" (no prefix)\n     *\n     * We construct (in sender.ts):\n     * - DM: \"iMessage;-;pilot@photon.codes\"\n     * - Group: \"iMessage;+;chat493787071395575843\" or just the GUID\n     *\n     * This method extracts the core identifier (last part after semicolons) to ensure\n     * both formats match correctly. For example:\n     * - \"iMessage;-;pilot@photon.codes\" → \"pilot@photon.codes\"\n     * - \"pilot@photon.codes\" → \"pilot@photon.codes\"\n     * Both normalize to the same value, enabling successful matching.\n     */\n    private normalizeChatId(chatId: string): string {\n        // Extract the core identifier (everything after last semicolon, or the whole string)\n        if (chatId.includes(';')) {\n            const parts = chatId.split(';')\n            // For \"iMessage;+;chat123\", return \"chat123\"\n            // For \"iMessage;pilot@photon.codes\", return \"pilot@photon.codes\"\n            // For \"iMessage;-;pilot@photon.codes\", return \"pilot@photon.codes\"\n            return parts[parts.length - 1] ?? chatId\n        }\n        return chatId\n    }\n}\n","/**\n * Message Sender\n */\n\nimport { existsSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport type { Recipient } from '../types/advanced'\nimport { asRecipient, isURL as checkIsURL } from '../types/advanced'\nimport type { RetryConfig } from '../types/config'\nimport type { Message } from '../types/message'\nimport {\n    checkIMessageStatus,\n    checkMessagesApp,\n    execAppleScript,\n    generateSendAttachmentScript,\n    generateSendAttachmentToChat,\n    generateSendTextScript,\n    generateSendTextToChat,\n    generateSendWithAttachmentScript,\n    generateSendWithAttachmentToChat,\n} from '../utils/applescript'\nimport { delay, validateChatId, validateMessageContent } from '../utils/common'\nimport { convertToCompatibleFormat, downloadImage } from '../utils/download'\nimport { Semaphore } from '../utils/semaphore'\nimport { IMessageError, SendError } from './errors'\nimport { MessagePromise } from './message-promise'\nimport type { OutgoingMessageManager } from './outgoing-manager'\n\n/** Send result */\nexport interface SendResult {\n    readonly sentAt: Date\n    /** The sent message (only available if watcher is running and message was confirmed) */\n    readonly message?: Message\n}\n\n/** Send options */\nexport interface SendOptions {\n    /** Recipient */\n    readonly to: string | Recipient\n    /** Text content */\n    readonly text?: string\n    /** Attachments */\n    readonly attachments?: readonly string[]\n    /** Abort signal (optional) */\n    readonly signal?: AbortSignal\n}\n\n/** Send options for group chat */\nexport interface SendToGroupOptions {\n    /** Group chat identifier (GUID) */\n    readonly groupId: string\n    /** Text content */\n    readonly text?: string\n    /** Attachments */\n    readonly attachments?: readonly string[]\n    /** Abort signal (optional) */\n    readonly signal?: AbortSignal\n}\n\n/**\n * Message Sender Class\n */\nexport class MessageSender {\n    /** Debug mode */\n    private readonly debug: boolean\n    /** Maximum retry attempts */\n    private readonly maxRetries: number\n    /** Retry delay */\n    private readonly retryDelay: number\n    /** Concurrency limiter */\n    private readonly semaphore: Semaphore | null\n    /** AppleScript timeout */\n    private readonly scriptTimeout: number\n    /** Outgoing message manager */\n    private outgoingManager: OutgoingMessageManager | null = null\n\n    constructor(debug = false, retryConfig?: Required<RetryConfig>, maxConcurrent = 5, scriptTimeout = 30000) {\n        this.debug = debug\n        this.maxRetries = retryConfig?.max ?? 2\n        this.retryDelay = retryConfig?.delay ?? 1500\n        this.semaphore = maxConcurrent > 0 ? new Semaphore(maxConcurrent) : null\n        this.scriptTimeout = scriptTimeout\n    }\n\n    /**\n     * Set outgoing message manager (called by SDK)\n     */\n    setOutgoingManager(manager: OutgoingMessageManager): void {\n        this.outgoingManager = manager\n    }\n\n    /**\n     * Execute script with retry\n     *\n     * @param script AppleScript code\n     * @param description Operation description\n     * @returns Execution result\n     */\n    private async executeWithRetry(script: string, description: string): Promise<void> {\n        let lastError: Error | null = null\n\n        for (let attempt = 1; attempt <= this.maxRetries; attempt++) {\n            try {\n                if (attempt > 1) {\n                    await delay(this.retryDelay)\n                }\n\n                await execAppleScript(script, this.debug, this.scriptTimeout)\n                return\n            } catch (error) {\n                lastError = error instanceof Error ? error : new Error(String(error))\n            }\n        }\n\n        const errorMsg = lastError?.message || 'unknown error'\n        throw SendError(`${description} failed (retried ${this.maxRetries} times): ${errorMsg}`)\n    }\n\n    /**\n     * Resolve attachment path\n     * - Download network images (HTTP URL) → ~/Pictures/imsg_temp_*\n     * - Validate local file path\n     * - Auto-convert incompatible formats (AVIF/WebP -> JPEG) → ~/Pictures/imsg_temp_*\n     *\n     * Note: All temporary files are automatically named imsg_temp_* and stored in ~/Pictures\n     *       TempFileManager will automatically scan and clean up these files, no manual tracking needed\n     *\n     * @param path Attachment path (local path or HTTP URL)\n     * @returns Local path\n     */\n    private async resolveAttachment(path: string): Promise<string> {\n        if (checkIsURL(path)) {\n            // Download network image (auto-converts incompatible formats)\n            return await downloadImage(path, { debug: this.debug })\n        }\n\n        // Handle local file\n        const localPath = resolve(path)\n        if (!existsSync(localPath)) {\n            throw SendError(`File not found: ${path}`)\n        }\n\n        // Convert incompatible formats (AVIF/WebP -> JPEG) for local files\n        const converted = await convertToCompatibleFormat(localPath)\n\n        if (converted.converted && this.debug) {\n            const originalFile = localPath.split('/').pop()\n            const convertedFile = converted.path.split('/').pop()\n            console.log(`[Format Conversion] ${originalFile} -> ${convertedFile}`)\n        }\n\n        return converted.path\n    }\n\n    /**\n     * Send message to recipient\n     */\n    async send(options: SendOptions): Promise<SendResult> {\n        const task = async () => {\n            const { to, text, attachments = [], signal } = options\n            const target = String(to)\n\n            this.checkAbortSignal(signal)\n\n            // Validate message content\n            let hasText: boolean\n            try {\n                const validation = validateMessageContent(text, attachments)\n                hasText = validation.hasText\n            } catch (error) {\n                const errorMsg = error instanceof Error ? error.message : String(error)\n                throw SendError(errorMsg)\n            }\n\n            try {\n                this.checkAbortSignal(signal)\n                await this.checkMessagesEnvironment()\n\n                const paths = await this.prepareAttachments(attachments)\n                const recipient = asRecipient(target)\n\n                // Create message promise if outgoingManager is available\n                // Use full chat GUID format: iMessage;-;recipient (for DMs)\n                // Note: Database may store just the recipient (e.g., \"pilot@photon.codes\")\n                // but MessagePromise.normalizeChatId() handles both formats by extracting\n                // the core identifier (last part after semicolons), ensuring proper matching\n                const chatId = `iMessage;-;${recipient}`\n                const sentAt = new Date()\n                let messagePromise: MessagePromise | null = null\n\n                if (this.outgoingManager && paths.length > 0) {\n                    // For attachments, create promise to track delivery\n                    const attachmentName = paths[0]?.split('/').pop()\n                    messagePromise = new MessagePromise({\n                        chatId,\n                        text: text,\n                        attachmentName,\n                        isAttachment: true,\n                        sentAt,\n                    })\n                    this.outgoingManager.add(messagePromise)\n                } else if (this.outgoingManager && hasText) {\n                    // For text messages, create promise to track delivery\n                    messagePromise = new MessagePromise({\n                        chatId,\n                        text: text,\n                        isAttachment: false,\n                        sentAt,\n                    })\n                    this.outgoingManager.add(messagePromise)\n                }\n\n                // Send the message\n                await this.sendToRecipient(recipient, text, hasText, paths)\n\n                // Wait for message to appear in database (if promise was created)\n                let confirmedMessage: Message | undefined\n                if (messagePromise) {\n                    try {\n                        confirmedMessage = await messagePromise.promise\n                        if (this.debug) {\n                            console.log('[Sender] Message confirmed in database')\n                        }\n                    } catch (promiseError) {\n                        if (this.debug) {\n                            console.warn('[Sender] Message promise rejected:', promiseError)\n                        }\n                        // Don't throw - message was sent, just not confirmed\n                    }\n                }\n\n                return { sentAt, message: confirmedMessage }\n            } catch (error) {\n                const errorMsg = error instanceof Error ? error.message : String(error)\n                const context = `[To: ${target}] [Text: ${hasText ? 'yes' : 'no'}] [Attachments: ${attachments.length}]`\n                const cause = error instanceof Error ? error : undefined\n\n                if (error instanceof IMessageError) {\n                    throw SendError(`${errorMsg} ${context}`, cause)\n                }\n                throw SendError(`Send failed ${context}: ${errorMsg}`, cause)\n            }\n        }\n\n        return this.semaphore ? await this.semaphore.run(task) : await task()\n    }\n\n    /**\n     * Check abort signal\n     */\n    private checkAbortSignal(signal?: AbortSignal): void {\n        if (signal?.aborted) {\n            throw SendError('Send cancelled')\n        }\n    }\n\n    /**\n     * Check Messages environment\n     */\n    private async checkMessagesEnvironment(): Promise<void> {\n        const isAvailable = await checkMessagesApp()\n\n        if (!isAvailable) {\n            throw SendError('Messages app is not running')\n        }\n\n        // Check iMessage account status (debug mode)\n        if (this.debug) {\n            const iMessageActive = await checkIMessageStatus(this.debug)\n\n            if (!iMessageActive) {\n                console.warn(\n                    '[Warning] iMessage account may not be logged in or activated, ' +\n                        'messages may show \"Not Delivered\"'\n                )\n                console.warn('[Suggestion] Open Messages app > Settings > iMessage, ' + 'ensure Apple ID is logged in')\n            }\n        }\n    }\n\n    /**\n     * Prepare all attachments (download, convert)\n     */\n    private async prepareAttachments(attachments: readonly string[]): Promise<string[]> {\n        if (attachments.length === 0) {\n            return []\n        }\n\n        if (this.debug) {\n            console.log(`[Processing Attachments] Total ${attachments.length} attachments`)\n        }\n\n        const resolvedPaths: string[] = []\n\n        for (let i = 0; i < attachments.length; i++) {\n            const attachment = attachments[i]!\n\n            if (this.debug) {\n                const attachmentPreview = attachment.length > 80 ? `${attachment.slice(0, 80)}...` : attachment\n\n                console.log(`[Processing Attachments] ${i + 1}/${attachments.length}: ${attachmentPreview}`)\n            }\n\n            const resolved = await this.resolveAttachment(attachment)\n            resolvedPaths.push(resolved)\n        }\n\n        return resolvedPaths\n    }\n\n    /**\n     * Send to recipient using buddy method\n     */\n    private async sendToRecipient(\n        recipient: string,\n        text: string | undefined,\n        hasText: boolean,\n        resolvedPaths: string[]\n    ): Promise<void> {\n        if (hasText && resolvedPaths.length > 0) {\n            // Strategy 1: Text + Attachments\n            const firstAttachment = resolvedPaths[0]!\n            const { script } = generateSendWithAttachmentScript(recipient, text!, firstAttachment)\n            await this.executeWithRetry(script, `Send text and attachment to ${recipient}`)\n\n            // Send remaining attachments\n            for (let i = 1; i < resolvedPaths.length; i++) {\n                const { script: attachScript } = generateSendAttachmentScript(recipient, resolvedPaths[i]!, this.debug)\n                await this.executeWithRetry(attachScript, `Send attachment ${i + 1}/${resolvedPaths.length}`)\n                // Extra delay between attachments\n                if (i < resolvedPaths.length - 1) {\n                    await delay(500)\n                }\n            }\n        } else if (hasText) {\n            // Strategy 2: Text only\n            const script = generateSendTextScript(recipient, text!)\n            await this.executeWithRetry(script, `Send text to ${recipient}`)\n        } else {\n            // Strategy 3: Attachments only\n            for (let i = 0; i < resolvedPaths.length; i++) {\n                const { script } = generateSendAttachmentScript(recipient, resolvedPaths[i]!, this.debug)\n                const description = `Send attachment ${i + 1}/${resolvedPaths.length} to ${recipient}`\n                await this.executeWithRetry(script, description)\n                // Extra delay between attachments to ensure previous one is sent\n                if (i < resolvedPaths.length - 1) {\n                    await delay(500)\n                }\n            }\n        }\n    }\n\n    /**\n     * Send to group using chat id method\n     */\n    private async sendToGroupChat(\n        groupId: string,\n        text: string | undefined,\n        hasText: boolean,\n        resolvedPaths: string[]\n    ): Promise<void> {\n        if (hasText && resolvedPaths.length > 0) {\n            // Strategy 1: Text + Attachments\n            const firstAttachment = resolvedPaths[0]!\n            const { script } = generateSendWithAttachmentToChat(groupId, text!, firstAttachment)\n            await this.executeWithRetry(script, `Send text and attachment to group ${groupId}`)\n\n            // Send remaining attachments\n            for (let i = 1; i < resolvedPaths.length; i++) {\n                const { script: attachScript } = generateSendAttachmentToChat(groupId, resolvedPaths[i]!, this.debug)\n                await this.executeWithRetry(attachScript, `Send attachment ${i + 1}/${resolvedPaths.length}`)\n                // Extra delay between attachments\n                if (i < resolvedPaths.length - 1) {\n                    await delay(500)\n                }\n            }\n        } else if (hasText) {\n            // Strategy 2: Text only\n            const script = generateSendTextToChat(groupId, text!)\n            await this.executeWithRetry(script, `Send text to group ${groupId}`)\n        } else {\n            // Strategy 3: Attachments only\n            for (let i = 0; i < resolvedPaths.length; i++) {\n                const { script } = generateSendAttachmentToChat(groupId, resolvedPaths[i]!, this.debug)\n                const description = `Send attachment ${i + 1}/${resolvedPaths.length} to group ${groupId}`\n                await this.executeWithRetry(script, description)\n                // Extra delay between attachments to ensure previous one is sent\n                if (i < resolvedPaths.length - 1) {\n                    await delay(500)\n                }\n            }\n        }\n    }\n\n    /**\n     * Send message to group chat\n     */\n    async sendToGroup(options: SendToGroupOptions): Promise<SendResult> {\n        const task = async () => {\n            const { groupId, text, attachments = [], signal } = options\n\n            this.checkAbortSignal(signal)\n\n            // Validate groupId format\n            try {\n                validateChatId(groupId)\n            } catch (error) {\n                const errorMsg = error instanceof Error ? error.message : String(error)\n                throw SendError(errorMsg)\n            }\n\n            // Validate message content\n            let hasText: boolean\n            try {\n                const validation = validateMessageContent(text, attachments)\n                hasText = validation.hasText\n            } catch (error) {\n                const errorMsg = error instanceof Error ? error.message : String(error)\n                throw SendError(errorMsg)\n            }\n\n            try {\n                this.checkAbortSignal(signal)\n                await this.checkMessagesEnvironment()\n\n                const paths = await this.prepareAttachments(attachments)\n\n                // Create message promise if outgoingManager is available\n                const sentAt = new Date()\n                let messagePromise: MessagePromise | null = null\n\n                if (this.outgoingManager && paths.length > 0) {\n                    // For attachments, create promise to track delivery\n                    const attachmentName = paths[0]?.split('/').pop()\n                    messagePromise = new MessagePromise({\n                        chatId: groupId,\n                        text: text,\n                        attachmentName,\n                        isAttachment: true,\n                        sentAt,\n                    })\n                    this.outgoingManager.add(messagePromise)\n                } else if (this.outgoingManager && hasText) {\n                    // For text messages, create promise to track delivery\n                    messagePromise = new MessagePromise({\n                        chatId: groupId,\n                        text: text,\n                        isAttachment: false,\n                        sentAt,\n                    })\n                    this.outgoingManager.add(messagePromise)\n                }\n\n                // Send the message\n                await this.sendToGroupChat(groupId, text, hasText, paths)\n\n                // Wait for message to appear in database (if promise was created)\n                let confirmedMessage: Message | undefined\n                if (messagePromise) {\n                    try {\n                        confirmedMessage = await messagePromise.promise\n                        if (this.debug) {\n                            console.log('[Sender] Group message confirmed in database')\n                        }\n                    } catch (promiseError) {\n                        if (this.debug) {\n                            console.warn('[Sender] Group message promise rejected:', promiseError)\n                        }\n                        // Don't throw - message was sent, just not confirmed\n                    }\n                }\n\n                return { sentAt, message: confirmedMessage }\n            } catch (error) {\n                const errorMsg = error instanceof Error ? error.message : String(error)\n                const context = `[Group: ${groupId}] [Text: ${hasText ? 'yes' : 'no'}] [Attachments: ${attachments.length}]`\n                const cause = error instanceof Error ? error : undefined\n\n                if (error instanceof IMessageError) {\n                    throw SendError(`${errorMsg} ${context}`, cause)\n                }\n                throw SendError(`Send failed ${context}: ${errorMsg}`, cause)\n            }\n        }\n\n        return this.semaphore ? await this.semaphore.run(task) : await task()\n    }\n}\n","/**\n * Message Watcher\n */\n\nimport type { PluginManager } from '../plugins/core'\nimport type { WebhookConfig } from '../types/config'\nimport type { Message } from '../types/message'\nimport type { IMessageDatabase } from './database'\nimport { WebhookError } from './errors'\nimport type { OutgoingMessageManager } from './outgoing-manager'\n\n/** Message callback */\nexport type MessageCallback = (message: Message) => void | Promise<void>\n\n/** Watcher event callbacks */\nexport interface WatcherEvents {\n    /** Triggered when any new message arrives (DM or group) */\n    onMessage?: MessageCallback\n    /** Triggered when new direct message arrives */\n    onDirectMessage?: MessageCallback\n    /** Triggered when new group message arrives */\n    onGroupMessage?: MessageCallback\n    /** Triggered when error occurs */\n    onError?: (error: Error) => void\n}\n\n/**\n * Message Watcher Class\n */\nexport class MessageWatcher {\n    /** Whether currently running */\n    private isRunning = false\n    /** Polling timer ID */\n    private intervalId: ReturnType<typeof setInterval> | null = null\n    /** Whether currently checking */\n    private isChecking = false\n    /** Last check time (for incremental queries) */\n    private lastCheckTime: Date\n    /** Set of processed message IDs (simple deduplication) */\n    private seenMessageIds = new Map<string, number>()\n\n    constructor(\n        private database: IMessageDatabase,\n        private pollInterval: number,\n        private unreadOnly: boolean,\n        private excludeOwnMessages: boolean,\n        private webhookConfig: WebhookConfig | null,\n        private events: WatcherEvents = {},\n        private pluginManager?: PluginManager,\n        private debug = false,\n        private outgoingManager?: OutgoingMessageManager,\n        initialLookbackMs = 10000\n    ) {\n        // Start from initialLookbackMs ago to catch recently sent messages\n        // Default 10 seconds helps catch messages sent just before watcher starts\n        // Note: This may cause duplicate processing if watcher is frequently restarted\n        this.lastCheckTime = new Date(Date.now() - initialLookbackMs)\n    }\n\n    /**\n     * Start watching for new messages\n     */\n    async start(): Promise<void> {\n        if (this.isRunning) return\n\n        this.isRunning = true\n        if (this.debug) {\n            console.log(`[Watcher] Started (poll interval: ${this.pollInterval}ms)`)\n        }\n\n        try {\n            await this.check()\n        } catch (error) {\n            this.isRunning = false\n            throw error\n        }\n\n        this.intervalId = setInterval(() => {\n            this.check().catch((error) => {\n                this.handleError(error)\n            })\n        }, this.pollInterval)\n    }\n\n    /**\n     * Stop watching\n     */\n    stop(): void {\n        if (!this.isRunning) return\n\n        this.isRunning = false\n        if (this.intervalId) {\n            clearInterval(this.intervalId)\n            this.intervalId = null\n        }\n\n        if (this.debug) {\n            console.log('[Watcher] Stopped')\n        }\n    }\n\n    /**\n     * Check for new messages\n     */\n    private async check() {\n        if (this.isChecking) return\n\n        this.isChecking = true\n        try {\n            const overlapMs = Math.min(1000, this.pollInterval)\n            const checkStart = new Date()\n            const since = new Date(this.lastCheckTime.getTime() - overlapMs)\n\n            const { messages } = await this.database.getMessages({\n                since,\n                excludeOwnMessages: false, // Always fetch own messages for outgoing resolution\n            })\n\n            this.lastCheckTime = checkStart\n\n            /** Filter out new messages */\n            let newMessages = messages.filter((msg) => !this.seenMessageIds.has(msg.id))\n\n            /** Try to resolve outgoing messages BEFORE filtering (critical for reliable send) */\n            if (this.outgoingManager) {\n                for (const msg of newMessages) {\n                    if (msg.isFromMe) {\n                        const matched = this.outgoingManager.tryResolve(msg)\n                        if (this.debug && matched) {\n                            console.log(`[Watcher] Resolved outgoing message: ${msg.id}`)\n                        }\n                    }\n                }\n            }\n\n            /** Filter by unread status if configured */\n            if (this.unreadOnly) {\n                newMessages = newMessages.filter((msg) => !msg.isRead)\n            }\n\n            /** Filter out own messages if configured (default: true) */\n            if (this.excludeOwnMessages) {\n                newMessages = newMessages.filter((msg) => !msg.isFromMe)\n            }\n\n            /** Mark as processed */\n            const now = Date.now()\n            for (const msg of newMessages) {\n                this.seenMessageIds.set(msg.id, now)\n            }\n\n            /** Process all new messages concurrently */\n            await Promise.all(\n                newMessages.map((msg) => this.handleNewMessage(msg).catch((err) => this.handleError(err)))\n            )\n\n            /** Keep only messages from last 1 hour */\n            if (this.seenMessageIds.size > 10000) {\n                const hourAgo = now - 3600000\n                for (const [id, timestamp] of this.seenMessageIds.entries()) {\n                    if (timestamp < hourAgo) {\n                        this.seenMessageIds.delete(id)\n                    }\n                }\n            }\n\n            /** Cleanup resolved outgoing message promises */\n            if (this.outgoingManager) {\n                this.outgoingManager.cleanup()\n            }\n        } catch (error) {\n            this.handleError(error)\n        } finally {\n            this.isChecking = false\n        }\n    }\n\n    /**\n     * Handle new message\n     * Triggers in sequence: Plugin hooks -> Event callback -> Webhook notification\n     * @param message New message object\n     */\n    private async handleNewMessage(message: Message) {\n        try {\n            /** Call plugin's onNewMessage hook */\n            await this.pluginManager?.callHookForAll('onNewMessage', message)\n\n            /** Call onMessage for all messages */\n            await this.events.onMessage?.(message)\n\n            /** Dispatch to specific callbacks based on message type */\n            if (message.isGroupChat) {\n                await this.events.onGroupMessage?.(message)\n            } else {\n                await this.events.onDirectMessage?.(message)\n            }\n\n            /** Send webhook notification */\n            if (this.webhookConfig) await this.sendWebhook(message)\n        } catch (error) {\n            this.handleError(error)\n        }\n    }\n\n    /**\n     * Send webhook notification\n     * POST message data to configured webhook URL\n     * @param message Message to notify\n     */\n    private async sendWebhook(message: Message): Promise<void> {\n        if (!this.webhookConfig) return\n\n        const retries = this.webhookConfig.retries ?? 0\n        const backoffMs = this.webhookConfig.backoffMs ?? 0\n\n        let lastError: unknown = null\n        for (let attempt = 0; attempt <= retries; attempt++) {\n            try {\n                const response = await fetch(this.webhookConfig.url, {\n                    method: 'POST',\n                    headers: {\n                        'Content-Type': 'application/json',\n                        ...this.webhookConfig.headers,\n                    },\n                    body: JSON.stringify({\n                        event: 'new_message',\n                        message: {\n                            id: message.id,\n                            text: message.text,\n                            sender: message.sender,\n                            senderName: message.senderName,\n                            isRead: message.isRead,\n                            service: message.service,\n                            hasAttachments: message.attachments.length > 0,\n                            attachments: message.attachments.map((a) => ({\n                                filename: a.filename,\n                                mimeType: a.mimeType,\n                                size: a.size,\n                                isImage: a.isImage,\n                            })),\n                            date: message.date.toISOString(),\n                        },\n                        timestamp: new Date().toISOString(),\n                    }),\n                    signal: AbortSignal.timeout(this.webhookConfig.timeout || 5000),\n                })\n\n                if (!response.ok) {\n                    throw WebhookError(`Webhook failed with status ${response.status}`)\n                }\n                // Success\n                return\n            } catch (error) {\n                lastError = error\n                if (attempt < retries && backoffMs > 0) {\n                    await new Promise((resolve) => setTimeout(resolve, backoffMs))\n                }\n            }\n        }\n        throw WebhookError(\n            `Failed to send webhook: ${\n                lastError instanceof Error ? lastError.message : String(lastError ?? 'unknown error')\n            }`\n        )\n    }\n\n    /**\n     * Unified error handling\n     * Output error to console and trigger error callback\n     * @param error Error object of any type\n     */\n    private handleError(error: unknown) {\n        const err = error instanceof Error ? error : new Error(String(error))\n        if (this.debug) {\n            console.error('[Watcher] Error:', err)\n        }\n        this.events.onError?.(err)\n    }\n}\n","/**\n * IMessage SDK - Type-safe macOS iMessage SDK\n *\n * @example\n * ```typescript\n * import { IMessageSDK, loggerPlugin } from '@photon-ai/imessage-kit'\n *\n * const sdk = new IMessageSDK({\n *   plugins: [loggerPlugin()]\n * })\n *\n * /// Send messages\n * await sdk.send('+1234567890', 'Hello!')\n * await sdk.send('+1234567890', { images: ['photo.jpg'] })\n *\n * /// Chain processing\n * await sdk.message(msg)\n *   .ifFromOthers()\n *   .matchText('hello')\n *   .replyText('Hi!')\n *   .execute()\n * ```\n */\n\nimport { type Plugin, PluginManager } from '../plugins/core'\nimport { type Recipient, asRecipient } from '../types/advanced'\nimport type { IMessageConfig, ResolvedConfig } from '../types/config'\nimport type {\n    ChatSummary,\n    ListChatsOptions,\n    Message,\n    MessageFilter,\n    MessageQueryResult,\n    UnreadMessagesResult,\n} from '../types/message'\nimport { extractRecipientFromChatId, isGroupChatId, validateChatId } from '../utils/common'\nimport { getDefaultDatabasePath, requireMacOS } from '../utils/platform'\nimport { TempFileManager } from '../utils/temp-file-manager'\nimport { MessageChain } from './chain'\nimport { ERROR_SDK_DESTROYED, ERROR_WATCHER_RUNNING } from './constants'\nimport { IMessageDatabase } from './database'\nimport { OutgoingMessageManager } from './outgoing-manager'\nimport { MessageSender, type SendResult } from './sender'\nimport { MessageWatcher, type WatcherEvents } from './watcher'\n\n/** SDK dependency injection interface */\nexport interface SDKDependencies {\n    database?: IMessageDatabase\n    sender?: MessageSender\n    pluginManager?: PluginManager\n}\n\n/** IMessage SDK Core Class */\nexport class IMessageSDK {\n    /** Configuration */\n    private readonly config: ResolvedConfig\n\n    /** Database */\n    private readonly database: IMessageDatabase\n\n    /** Temporary file manager */\n    private readonly tempFileManager: TempFileManager\n\n    /** Message sender */\n    private readonly sender: MessageSender\n\n    /** Plugin manager */\n    private readonly pluginManager: PluginManager\n\n    /** Message watcher */\n    private watcher: MessageWatcher | null = null\n\n    /** Outgoing message manager */\n    private readonly outgoingManager: OutgoingMessageManager\n\n    /** Whether destroyed */\n    private destroyed = false\n\n    constructor(config: IMessageConfig = {}, dependencies?: SDKDependencies) {\n        requireMacOS()\n        this.config = this.resolveConfig(config)\n        this.database = dependencies?.database ?? new IMessageDatabase(this.config.databasePath)\n\n        this.tempFileManager = new TempFileManager({\n            maxAge: this.config.tempFile?.maxAge,\n            cleanupInterval: this.config.tempFile?.cleanupInterval,\n            debug: this.config.debug,\n        })\n        this.tempFileManager.start()\n\n        this.sender =\n            dependencies?.sender ??\n            new MessageSender(\n                this.config.debug,\n                this.config.retry,\n                this.config.maxConcurrent,\n                this.config.scriptTimeout\n            )\n\n        this.pluginManager = dependencies?.pluginManager ?? new PluginManager()\n\n        this.outgoingManager = new OutgoingMessageManager(this.config.debug)\n\n        // Connect sender with outgoingManager (if sender supports it)\n        if ('setOutgoingManager' in this.sender && typeof this.sender.setOutgoingManager === 'function') {\n            this.sender.setOutgoingManager(this.outgoingManager)\n        }\n\n        if (config.plugins) {\n            for (const plugin of config.plugins) {\n                this.pluginManager.use(plugin)\n            }\n        }\n\n        if (this.config.debug) {\n            console.log('[SDK] Initialization complete')\n        }\n    }\n\n    private async ensurePluginsReady() {\n        if (!this.pluginManager.initialized) {\n            await this.pluginManager.init()\n        }\n    }\n\n    private resolveConfig(config: IMessageConfig): ResolvedConfig {\n        const clamp = (v: number | undefined, min: number, max: number, def: number) => {\n            const val = v ?? def\n            if (val < min || val > max) {\n                throw new Error(`Value must be between ${min} and ${max}`)\n            }\n            return val\n        }\n\n        return {\n            databasePath: config.databasePath ?? getDefaultDatabasePath(),\n            webhook: config.webhook ?? null,\n            watcher: {\n                pollInterval: clamp(config.watcher?.pollInterval, 100, 60000, 2000),\n                unreadOnly: config.watcher?.unreadOnly ?? false,\n                excludeOwnMessages: config.watcher?.excludeOwnMessages ?? true,\n            },\n            retry: {\n                max: clamp(config.retry?.max, 0, 10, 2),\n                delay: clamp(config.retry?.delay, 0, 10000, 1500),\n            },\n            tempFile: {\n                maxAge: clamp(config.tempFile?.maxAge, 60000, 3600000, 600000),\n                // 1 minute ~ 1 hour, default 10 minutes\n                cleanupInterval: clamp(config.tempFile?.cleanupInterval, 60000, 1800000, 300000), // 1 minute ~ 30 minutes, default 5 minutes\n            },\n            scriptTimeout: clamp(config.scriptTimeout, 5000, 120000, 30000),\n            // 5 seconds ~ 2 minutes, default 30 seconds\n            maxConcurrent: clamp(config.maxConcurrent, 0, 50, 5),\n            debug: config.debug ?? false,\n        }\n    }\n\n    /**\n     * Determine if a string is a chatId (not a recipient)\n     *\n     * ChatId formats:\n     * - Group GUID: `chat123...`\n     * - AppleScript group: `iMessage;+;chat123...`\n     *\n     * Recipient formats:\n     * - Phone: `+1234567890`\n     * - Email: `user@example.com`\n     *\n     * Note: `iMessage;+1234567890` is NOT a chatId for routing purposes.\n     * It's a service-prefixed recipient that should be sent via buddy method.\n     */\n    private isChatId(value: string): boolean {\n        // Use helper to check if it's a group chat\n        if (isGroupChatId(value)) {\n            return true\n        }\n\n        // Try to parse as recipient\n        try {\n            asRecipient(value)\n            return false // It's a valid recipient\n        } catch {\n            // Not a valid recipient, could be service-prefixed DM\n            // Try to extract recipient from service-prefixed format\n            const extracted = extractRecipientFromChatId(value)\n            if (extracted) {\n                // It's a service-prefixed DM, treat as recipient\n                return false\n            }\n            // Unknown format, treat as chatId\n            return true\n        }\n    }\n\n    /**\n     * Register plugin\n     */\n    use(plugin: Plugin): this {\n        if (this.destroyed) throw new Error(ERROR_SDK_DESTROYED)\n        this.pluginManager.use(plugin)\n        return this\n    }\n\n    /**\n     * Get plugin manager\n     * @returns PluginManager instance\n     */\n    get plugins() {\n        return this.pluginManager\n    }\n\n    /**\n     * Query messages\n     */\n    async getMessages(filter?: MessageFilter): Promise<MessageQueryResult> {\n        if (this.destroyed) throw new Error(ERROR_SDK_DESTROYED)\n\n        await this.ensurePluginsReady()\n        await this.pluginManager.callHookForAll('onBeforeQuery', filter)\n        const result = await this.database.getMessages(filter)\n        await this.pluginManager.callHookForAll('onAfterQuery', result.messages)\n\n        return result\n    }\n\n    /**\n     * Get unread messages (grouped by sender)\n     *\n     * @returns Unread messages with statistics\n     * @example\n     * ```ts\n     * const unread = await sdk.getUnreadMessages()\n     * console.log(`${unread.total} unread messages from ${unread.senderCount} senders`)\n     * for (const { sender, messages } of unread.groups) {\n     *   console.log(`${sender}: ${messages.length} messages`)\n     * }\n     * ```\n     */\n    async getUnreadMessages(): Promise<UnreadMessagesResult> {\n        if (this.destroyed) throw new Error(ERROR_SDK_DESTROYED)\n\n        await this.ensurePluginsReady()\n        await this.pluginManager.callHookForAll('onBeforeQuery', { unreadOnly: true })\n\n        const { grouped, total } = await this.database.getUnreadMessages()\n        const groups = Array.from(grouped.entries()).map(([sender, messages]) => ({\n            sender,\n            messages,\n        }))\n\n        const result = {\n            groups,\n            total,\n            senderCount: groups.length,\n        }\n\n        // Flatten all messages for plugin hook\n        const allMessages = groups.flatMap((g) => g.messages)\n        await this.pluginManager.callHookForAll('onAfterQuery', allMessages)\n\n        return result\n    }\n\n    /**\n     * Send message to recipient (phone/email) or chat (chatId)\n     *\n     * Automatically detects whether the target is:\n     * - A recipient (phone number or email): e.g., '+1234567890', 'user@example.com'\n     * - A chatId (group or DM): e.g., 'chat123...', 'iMessage;+1234567890'\n     *\n     * @example\n     * ```ts\n     * // Send to phone number\n     * await sdk.send('+1234567890', 'Hello')\n     *\n     * // Send to email\n     * await sdk.send('user@example.com', 'Hello')\n     *\n     * // Send to group chat\n     * await sdk.send('chat123...', 'Hello')\n     *\n     * // Send with attachments\n     * await sdk.send('+1234567890', { images: ['/img.jpg'] })\n     * await sdk.send('chat123...', { text: 'Hi', files: ['/doc.pdf'] })\n     * ```\n     */\n    async send(\n        to: string | Recipient,\n        content: string | { text?: string; images?: string[]; files?: string[] }\n    ): Promise<SendResult> {\n        if (this.destroyed) throw new Error(ERROR_SDK_DESTROYED)\n\n        /** Normalize to object format */\n        const normalized =\n            typeof content === 'string'\n                ? { text: content, attachments: [] }\n                : {\n                      text: content.text,\n                      attachments: [...(content.images || []), ...(content.files || [])],\n                  }\n\n        const target = String(to)\n\n        // Determine if target is a chatId or recipient\n        const isChatIdTarget = this.isChatId(target)\n\n        if (isChatIdTarget) {\n            // Target is a group chat - validate and send to group\n            validateChatId(target)\n\n            await this.ensurePluginsReady()\n            await this.pluginManager.callHookForAll('onBeforeSend', target, {\n                text: normalized.text,\n                attachments: normalized.attachments,\n            })\n\n            const result = await this.sender.sendToGroup({\n                groupId: target,\n                text: normalized.text,\n                attachments: normalized.attachments,\n            })\n\n            await this.pluginManager.callHookForAll('onAfterSend', target, result)\n            return result\n        }\n\n        // Target is a recipient (phone/email or service-prefixed)\n        // Extract pure recipient if it's service-prefixed (e.g., 'iMessage;+1234567890' -> '+1234567890')\n        const extracted = extractRecipientFromChatId(target)\n        const recipient = extracted || asRecipient(target)\n        const chatId = target.includes(';') ? target : `iMessage;${recipient}`\n\n        await this.ensurePluginsReady()\n        await this.pluginManager.callHookForAll('onBeforeSend', chatId, {\n            text: normalized.text,\n            attachments: normalized.attachments,\n        })\n\n        const result = await this.sender.send({\n            to: recipient,\n            text: normalized.text,\n            attachments: normalized.attachments,\n        })\n\n        await this.pluginManager.callHookForAll('onAfterSend', chatId, result)\n        return result\n    }\n\n    /**\n     * List chats with filtering and sorting options\n     *\n     * @param options Filter and sort options (or a number for backward compatibility)\n     * @returns Array of chat summaries with unread counts\n     *\n     * @example\n     * ```ts\n     * // Get all chats\n     * const all = await sdk.listChats()\n     *\n     * // Get recent group chats with unread messages\n     * const groups = await sdk.listChats({\n     *   type: 'group',\n     *   hasUnread: true,\n     *   limit: 20\n     * })\n     *\n     * // Search chats by name\n     * const found = await sdk.listChats({\n     *   search: 'John',\n     *   sortBy: 'name'\n     * })\n     *\n     * // Backward compatible: limit only\n     * const recent = await sdk.listChats({ limit: 50 })\n     * ```\n     */\n    async listChats(options?: ListChatsOptions | number): Promise<ChatSummary[]> {\n        if (this.destroyed) throw new Error(ERROR_SDK_DESTROYED)\n        await this.ensurePluginsReady()\n\n        // Backward compatibility: convert number to options object\n        const opts: ListChatsOptions = typeof options === 'number' ? { limit: options } : options || {}\n\n        await this.pluginManager.callHookForAll('onBeforeQuery', opts)\n        const result = await this.database.listChats(opts)\n        // Note: onAfterQuery expects Message[], but listChats returns ChatSummary[]\n        // We pass empty array to maintain hook signature compatibility\n        await this.pluginManager.callHookForAll('onAfterQuery', [])\n        return result\n    }\n\n    /**\n     * Send batch messages (concurrency controlled by sender's maxConcurrent config)\n     *\n     * @param messages Batch message list\n     * @returns List of send results (including success and failure)\n     *\n     * @example\n     * ```ts\n     * const results = await sdk.sendBatch([\n     *   { to: '+1234567890', content: 'Hello' },\n     *   { to: '+0987654321', content: 'Hi' },\n     * ])\n     *\n     * for (const result of results) {\n     *   if (result.success) {\n     *     console.log('Send success:', result.to)\n     *   } else {\n     *     console.error('Send failed:', result.to, result.error)\n     *   }\n     * }\n     * ```\n     */\n    async sendBatch(\n        messages: Array<{\n            to: string | Recipient\n            content: string | { text?: string; images?: string[]; files?: string[] }\n        }>\n    ): Promise<\n        Array<{\n            to: string\n            success: boolean\n            result?: SendResult\n            error?: Error\n        }>\n    > {\n        if (this.destroyed) throw new Error(ERROR_SDK_DESTROYED)\n\n        const results = await Promise.allSettled(\n            messages.map(async ({ to, content }) => ({\n                to: String(to),\n                result: await this.send(to, content),\n            }))\n        )\n\n        return results.map((result, index) => {\n            const to = String(messages[index]!.to)\n\n            if (result.status === 'fulfilled') {\n                return {\n                    to,\n                    success: true,\n                    result: result.value.result,\n                }\n            }\n            return {\n                to,\n                success: false,\n                error: result.reason instanceof Error ? result.reason : new Error(String(result.reason)),\n            }\n        })\n    }\n\n    /**\n     * Send file (convenience method)\n     *\n     * Supports both recipient (phone/email) and chatId\n     *\n     * @example\n     * ```ts\n     * // Send to phone number\n     * await sdk.sendFile('+1234567890', '/path/to/document.pdf')\n     *\n     * // Send to group chat\n     * await sdk.sendFile('chat123...', '/path/to/document.pdf', 'Here is the file')\n     * ```\n     */\n    async sendFile(to: string | Recipient, filePath: string, text?: string): Promise<SendResult> {\n        return this.send(to, { text, files: [filePath] })\n    }\n\n    /**\n     * Send multiple files (convenience method)\n     *\n     * Supports both recipient (phone/email) and chatId\n     *\n     * @example\n     * ```ts\n     * // Send to phone number\n     * await sdk.sendFiles('+1234567890', ['/file1.pdf', '/file2.csv'])\n     *\n     * // Send to group chat\n     * await sdk.sendFiles('chat123...', ['/data.xlsx'], 'Check these files')\n     * ```\n     */\n    async sendFiles(to: string | Recipient, filePaths: string[], text?: string): Promise<SendResult> {\n        return this.send(to, { text, files: filePaths })\n    }\n\n    // ==================== Message Chain Processing ====================\n\n    /**\n     * Create message processing chain\n     */\n    message(message: Message) {\n        if (this.destroyed) throw new Error(ERROR_SDK_DESTROYED)\n        return new MessageChain(message, this.sender)\n    }\n\n    /**\n     * Start watching for new messages\n     */\n    async startWatching(events?: WatcherEvents): Promise<void> {\n        if (this.destroyed) throw new Error(ERROR_SDK_DESTROYED)\n        if (this.watcher) throw new Error(ERROR_WATCHER_RUNNING)\n\n        const watcher = new MessageWatcher(\n            this.database,\n            this.config.watcher.pollInterval,\n            this.config.watcher.unreadOnly,\n            this.config.watcher.excludeOwnMessages,\n            this.config.webhook,\n            events,\n            this.pluginManager,\n            this.config.debug,\n            this.outgoingManager\n        )\n\n        try {\n            await watcher.start()\n            this.watcher = watcher\n        } catch (error) {\n            watcher.stop()\n            throw error\n        }\n    }\n\n    /**\n     * Stop watching for new messages\n     */\n    stopWatching(): void {\n        this.watcher?.stop()\n        this.watcher = null\n    }\n\n    /**\n     * Close SDK and release resources\n     */\n    async close() {\n        if (this.destroyed) return\n\n        this.destroyed = true\n        const errors: Array<{ component: string; error: Error }> = []\n\n        /** 1. Stop watcher */\n        try {\n            this.watcher?.stop()\n        } catch (error) {\n            errors.push({\n                component: 'watcher',\n                error: error instanceof Error ? error : new Error(String(error)),\n            })\n        }\n        this.watcher = null\n\n        /** 2. Reject all pending message promises */\n        try {\n            this.outgoingManager.rejectAll('SDK closed')\n        } catch (error) {\n            errors.push({\n                component: 'outgoingManager',\n                error: error instanceof Error ? error : new Error(String(error)),\n            })\n        }\n\n        /** 3. Destroy plugins */\n        try {\n            await this.pluginManager.destroy()\n        } catch (error) {\n            errors.push({\n                component: 'pluginManager',\n                error: error instanceof Error ? error : new Error(String(error)),\n            })\n        }\n\n        /** 4. Destroy temporary file manager (clean up all temp files) */\n        try {\n            await this.tempFileManager.destroy()\n        } catch (error) {\n            errors.push({\n                component: 'tempFileManager',\n                error: error instanceof Error ? error : new Error(String(error)),\n            })\n        }\n\n        /** 5. Close database */\n        try {\n            this.database.close()\n        } catch (error) {\n            errors.push({\n                component: 'database',\n                error: error instanceof Error ? error : new Error(String(error)),\n            })\n        }\n\n        /** If there are errors, aggregate and throw */\n        if (errors.length > 0) {\n            if (this.config.debug) {\n                console.error('[SDK] Error occurred during shutdown:', errors)\n            }\n\n            /** Node.js 15+ supports AggregateError */\n            if (typeof AggregateError !== 'undefined') {\n                throw new AggregateError(\n                    errors.map((e) => e.error),\n                    `SDK shutdown failed: ${errors.map((e) => e.component).join(', ')}`\n                )\n            }\n            /** Fallback: throw first error */\n            throw errors[0]!.error\n        }\n    }\n\n    /** Support using declaration (TypeScript 5.2+) */\n    async [Symbol.asyncDispose]() {\n        await this.close()\n    }\n\n    /** Support using declaration (sync version) */\n    [Symbol.dispose]() {\n        this.close().catch(console.error)\n    }\n}\n","/**\n * Logger Plugin\n */\n\nimport { type Plugin, definePlugin } from './core'\n\n/**\n * Log level\n */\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error'\n\n/**\n * Logger plugin options\n */\nexport interface LoggerOptions {\n    /** Log level (default: info) */\n    level?: LogLevel\n\n    /** Whether to use colored output (default: true) */\n    colored?: boolean\n\n    /** Whether to show timestamps (default: false) */\n    timestamp?: boolean\n\n    /** Whether to log send operations (default: true) */\n    logSend?: boolean\n\n    /** Whether to log new messages (default: false) */\n    logNewMessage?: boolean\n}\n\nconst LEVELS = { debug: 0, info: 1, warn: 2, error: 3 }\n\nconst COLORS = {\n    debug: '\\x1b[36m',\n    info: '\\x1b[32m',\n    warn: '\\x1b[33m',\n    error: '\\x1b[31m',\n}\n\nconst RESET = '\\x1b[0m'\n\n/**\n * Create a logger plugin\n *\n * @param options Logger configuration (optional)\n * @returns Plugin instance\n *\n * @example Basic usage\n * ```ts\n * const sdk = new IMessageSDK({\n *   plugins: [loggerPlugin()]  // Use default configuration\n * })\n * ```\n *\n * @example Custom configuration\n * ```ts\n * const sdk = new IMessageSDK({\n *   plugins: [\n *     loggerPlugin({\n *       level: 'info',        // Only show info and above\n *       colored: true,        // Colored output\n *       timestamp: true,      // Show timestamps\n *       logSend: true,        // Log send operations\n *       logNewMessage: true   // Log new messages\n *     })\n *   ]\n * })\n * ```\n *\n * @example Production configuration\n * ```ts\n * const sdk = new IMessageSDK({\n *   plugins: [\n *     loggerPlugin({\n *       level: 'warn',        // Only show warnings and errors\n *       colored: false,       // Plain text output\n *       logSend: false        // Don't log send operations\n *     })\n *   ]\n * })\n * ```\n */\nexport const loggerPlugin = (options: LoggerOptions = {}): Plugin => {\n    const { level = 'info', colored = true, timestamp = false, logSend = true, logNewMessage = false } = options\n\n    const log = (logLevel: LogLevel, message: string, data?: unknown) => {\n        if (LEVELS[logLevel] < LEVELS[level]) return\n\n        const time = timestamp ? new Date().toLocaleTimeString('en-US') : ''\n        const tag = logLevel.toUpperCase().padEnd(5)\n        const color = colored ? COLORS[logLevel] : ''\n        const reset = colored ? RESET : ''\n\n        const prefix = time ? `${time} ${color}[${tag}]${reset}` : `${color}[${tag}]${reset}`\n\n        const output = data ? `${prefix} ${message} ${JSON.stringify(data)}` : `${prefix} ${message}`\n\n        console.log(output)\n    }\n\n    return definePlugin({\n        name: 'logger',\n        version: '1.0.0',\n        description: 'Logger plugin',\n\n        onInit: () => {\n            log('info', 'SDK initialized')\n        },\n\n        onBeforeSend: (to, content) => {\n            if (!logSend) return\n\n            const preview = content.text?.substring(0, 30) || '(no text)'\n            const attachCount = content.attachments?.length || 0\n            const attachInfo = attachCount ? ` + ${attachCount} attachment(s)` : ''\n\n            log('info', `[SEND] Sending to ${to}: ${preview}${attachInfo}`)\n        },\n\n        onAfterSend: (to) => {\n            if (logSend) {\n                log('info', `[OK] Sent successfully -> ${to}`)\n            }\n        },\n\n        onNewMessage: (message) => {\n            if (!logNewMessage) return\n\n            const preview = message.text?.substring(0, 40) || '(no text)'\n            const attachCount = message.attachments.length\n            const attachInfo = attachCount ? ` [${attachCount}]` : ''\n\n            log('info', `[MSG] New message from ${message.sender}: ${preview}${attachInfo}`)\n        },\n\n        onError: (error, context) => {\n            const contextInfo = context || 'Error'\n            log('error', `[ERROR] ${contextInfo}: ${error.message}`)\n        },\n\n        onDestroy: () => {\n            log('info', '[CLOSE] SDK destroyed')\n        },\n    })\n}\n","/**\n * Attachment Helper Functions\n *\n * Provides utility functions for working with message attachments\n * without adding methods to the Attachment interface (keeping it as pure data)\n */\n\nimport * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport type { Attachment } from '../types/message'\n\n/** Supported image file extensions */\nconst IMAGE_EXTENSIONS = ['jpg', 'jpeg', 'png', 'gif', 'heic', 'heif', 'webp', 'bmp', 'tiff', 'svg'] as const\ntype ImageExtension = (typeof IMAGE_EXTENSIONS)[number]\n\n/** Supported video file extensions */\nconst VIDEO_EXTENSIONS = ['mp4', 'mov', 'avi', 'mkv', 'm4v', 'wmv', 'flv', 'webm'] as const\ntype VideoExtension = (typeof VIDEO_EXTENSIONS)[number]\n\n/** Supported audio file extensions */\nconst AUDIO_EXTENSIONS = ['mp3', 'm4a', 'wav', 'aac', 'flac', 'ogg', 'wma'] as const\ntype AudioExtension = (typeof AUDIO_EXTENSIONS)[number]\n\n/**\n * Check if attachment file exists on disk\n *\n * @param attachment Attachment object\n * @returns True if file exists, false otherwise\n *\n * @example\n * ```ts\n * import { attachmentExists } from '@photon-ai/imessage-kit/helpers'\n *\n * const attachment = message.attachments[0]\n * if (await attachmentExists(attachment)) {\n *   console.log('Attachment exists')\n * }\n * ```\n */\nexport async function attachmentExists(attachment: Attachment): Promise<boolean> {\n    try {\n        await fs.promises.access(attachment.path, fs.constants.F_OK)\n        return true\n    } catch {\n        return false\n    }\n}\n\n/**\n * Download (copy) attachment to specified destination\n *\n * @param attachment Attachment object\n * @param destPath Destination file path\n * @throws Error if source file doesn't exist or copy fails\n *\n * @example\n * ```ts\n * import { downloadAttachment } from '@photon-ai/imessage-kit/helpers'\n *\n * const attachment = message.attachments[0]\n * await downloadAttachment(attachment, '/path/to/save/file.jpg')\n * ```\n */\nexport async function downloadAttachment(attachment: Attachment, destPath: string): Promise<void> {\n    // Ensure destination directory exists\n    const destDir = path.dirname(destPath)\n    await fs.promises.mkdir(destDir, { recursive: true })\n\n    // Copy file\n    await fs.promises.copyFile(attachment.path, destPath)\n}\n\n/**\n * Get attachment file size in bytes\n *\n * @param attachment Attachment object\n * @returns File size in bytes, or 0 if file doesn't exist\n *\n * @example\n * ```ts\n * import { getAttachmentSize } from '@photon-ai/imessage-kit/helpers'\n *\n * const size = await getAttachmentSize(attachment)\n * console.log(`File size: ${(size / 1024 / 1024).toFixed(2)} MB`)\n * ```\n */\nexport async function getAttachmentSize(attachment: Attachment): Promise<number> {\n    try {\n        const stats = await fs.promises.stat(attachment.path)\n        return stats.size\n    } catch {\n        return 0\n    }\n}\n\n/**\n * Get attachment metadata (size, modified time, etc.)\n *\n * @param attachment Attachment object\n * @returns File stats or null if file doesn't exist\n *\n * @example\n * ```ts\n * import { getAttachmentMetadata } from '@photon-ai/imessage-kit/helpers'\n *\n * const metadata = await getAttachmentMetadata(attachment)\n * if (metadata) {\n *   console.log(`Size: ${metadata.size}, Modified: ${metadata.mtime}`)\n * }\n * ```\n */\nexport async function getAttachmentMetadata(attachment: Attachment): Promise<fs.Stats | null> {\n    try {\n        return await fs.promises.stat(attachment.path)\n    } catch {\n        return null\n    }\n}\n\n/**\n * Read attachment content as Buffer\n *\n * Useful for processing file contents without saving to disk\n *\n * @param attachment Attachment object\n * @returns File content as Buffer\n * @throws Error if file doesn't exist or read fails\n *\n * @example\n * ```ts\n * import { readAttachment } from '@photon-ai/imessage-kit/helpers'\n *\n * const buffer = await readAttachment(attachment)\n * // Process buffer...\n * ```\n */\nexport async function readAttachment(attachment: Attachment): Promise<Buffer> {\n    return await fs.promises.readFile(attachment.path)\n}\n\n/**\n * Get attachment file extension\n *\n * @param attachment Attachment object\n * @returns File extension (without dot) or empty string\n *\n * @example\n * ```ts\n * import { getAttachmentExtension } from '@photon-ai/imessage-kit/helpers'\n *\n * const ext = getAttachmentExtension(attachment)\n * if (ext === 'jpg' || ext === 'png') {\n *   console.log('Image file')\n * }\n * ```\n */\nexport function getAttachmentExtension(attachment: Attachment): string {\n    const ext = path.extname(attachment.path)\n    return ext ? ext.slice(1).toLowerCase() : ''\n}\n\n/**\n * Check if attachment is an image\n *\n * @param attachment Attachment object\n * @returns True if attachment is an image file\n *\n * @example\n * ```ts\n * import { isImageAttachment } from '@photon-ai/imessage-kit/helpers'\n *\n * if (isImageAttachment(attachment)) {\n *   console.log('This is an image')\n * }\n * ```\n */\nexport function isImageAttachment(attachment: Attachment): boolean {\n    const ext = getAttachmentExtension(attachment)\n    return IMAGE_EXTENSIONS.includes(ext as ImageExtension)\n}\n\n/**\n * Check if attachment is a video\n *\n * @param attachment Attachment object\n * @returns True if attachment is a video file\n */\nexport function isVideoAttachment(attachment: Attachment): boolean {\n    const ext = getAttachmentExtension(attachment)\n    return VIDEO_EXTENSIONS.includes(ext as VideoExtension)\n}\n\n/**\n * Check if attachment is an audio file\n *\n * @param attachment Attachment object\n * @returns True if attachment is an audio file\n */\nexport function isAudioAttachment(attachment: Attachment): boolean {\n    const ext = getAttachmentExtension(attachment)\n    return AUDIO_EXTENSIONS.includes(ext as AudioExtension)\n}\n"]}