import { ChildProcess } from 'child_process'; export declare class MessageBoxHandle { readonly result: Promise; readonly pid: number | undefined; private child; private _closed; constructor(child: ChildProcess, resultPromise: Promise); close(): boolean; get closed(): boolean; } export declare function closeMessageBox(pid: number): boolean; export interface MessageBoxOptions { title?: string; /** The title text displayed in the window title bar */ message?: string; /** The plain text message to display (optional if url or html is provided) */ html?: string; /** HTML content to display in the message box */ url?: string; /** URL to load external content (web URL or file path) */ hash?: string; /** Hash fragment to append to URL (requires url to be set). Leading # is optional. */ rawHtml?: boolean; /** When true with html, load HTML as-is (no msger template wrapper, no buttons). Used by mdview. */ size?: { width: number; /** Window width */ height: number; /** Window height */ }; pos?: { x: number; /** Window X position in pixels */ y: number; /** Window Y position in pixels */ screen?: number; /** Optional screen index (0-based). Offsets x/y into that monitor. Was Windows-only; now applied on Mac and X11 too. Wayland ignores client-set window positions entirely — use `fullscreen` + `screen` there. */ }; screen?: number; /** Monitor index (0-based) for `fullscreen`, and the fallback for `pos.screen`. The portable way to target a display: Wayland refuses client-set coordinates but honors fullscreen-on-a-given-output. */ overlay?: boolean; /** Frameless, transparent, click-through, always-on-top window drawn over the desktop — transient notices, e.g. per-monitor identification. Combine with `fullscreen` + `screen` to cover one display and `timeout` to dismiss it; an overlay has no close button and passes clicks through, so nothing in it can be operated. With `url` / `rawHtml` the page must set its own transparent background (the built-in template already does). */ listMonitors?: boolean; /** Print the monitor layout as JSON (`{monitors:[{index,name,x,y,width,height,scale,primary}]}`) and exit without opening a window. Indices match `screen`. */ zoom?: number; /** Initial zoom level as percentage (100=100%, 150=150%, 50=50%, etc.) */ autoSize?: boolean; /** Automatically resize window to fit content (default: false) */ alwaysOnTop?: boolean; /** Keep window on top of other windows (default: false) */ focusOnCreate?: boolean; contextMenuItems?: Array<{ id: string; label: string; }>; /** App items appended to the NATIVE right-click menu (spell suggestions preserved). Selection calls window.__msgerContextCommand(id) in the page. Windows only. */ /** Force the window to the foreground on creation. Needed when a BACKGROUND process (daemon) spawns the window — otherwise it shows without activation and lands behind the caller's focused window (default: false) */ buttons?: string[]; /** Array of button labels to display (default: ['OK']) */ defaultValue?: string; /** Default value for input field when allowInput is true */ inputPlaceholder?: string; /** Placeholder text (gray hint) shown in input field */ allowInput?: boolean; /** Enable an input field in the message box (default: false) */ timeout?: number; /** Auto-close the message box after specified seconds */ detach?: boolean; /** Launch the message box detached from parent process */ fullscreen?: boolean; /** Start window in fullscreen mode (F11 to toggle, Escape to exit) */ escapeCloses?: boolean; /** Legacy boolean form of `escape`: true = Escape dismisses the window, false = it never does. Leave it UNDEFINED to get `escape: 'auto'`. Always exits fullscreen first either way. */ escape?: 'exit' | 'noexit' | 'auto'; /** What the Escape key does. 'exit' = dismiss the window; 'noexit' = Escape only goes to the page; 'auto' (default) = decide from the window kind — a dialog (message/html/prompt) is dismissed, a `url` window is NOT, because there Esc belongs to the page (closing its menu, autocomplete, lightbox) and a host that quits on it looks like msger "exiting spontaneously". Service mode never exits on Escape. Overrides `escapeCloses` when both are given. */ reset?: boolean; /** Clear localStorage on startup (default: false) */ icon?: string; /** Path to window icon. Decoded for the runtime title-bar / taskbar icon. PNG decodes most reliably; the `image` crate's ICO+PNG path is fragile. */ relaunchIcon?: string; /** Optional path forwarded to `PKEY_AppUserModel_RelaunchIconResource` so pinned taskbar shortcuts get the app's own icon. Must be a `.ico`. Path is consumed verbatim (no decode). */ relaunchCommand?: string; /** Command Windows runs when the user clicks the pinned shortcut (`PKEY_AppUserModel_RelaunchCommand`). Critical for msger-hosted apps: without it, the pin captures the bare `mailx.exe` (a webview host that expects JSON stdin) and clicking it does nothing. */ relaunchDisplayName?: string; /** Display name for the pinned shortcut (`PKEY_AppUserModel_RelaunchDisplayNameResource`). */ dev?: boolean; /** Open DevTools automatically on startup (default: false) */ debug?: boolean; /** Return debug information (HTML, size) in result (default: false) */ showVersion?: boolean; /** Show version in window title (default: false) */ appUserModelId?: string; /** Windows AppUserModelID for taskbar pinning (internal use) */ aumid?: string; /** Same as appUserModelId — short name for callers (forwarded to Rust) */ initScript?: string; /** Custom JS injected into WebView alongside msger-api.js (inline) */ initScriptPath?: string; /** Path to JS file injected into WebView (avoids large JSON) */ service?: boolean; /** Service mode: bidirectional IPC with parent. Stdin/stdout stay open. */ contentDir?: string; /** Base directory for custom protocol file serving (avoids file:// URLs) */ hidden?: boolean; /** Create the window invisible. The WebView still renders so JS / CSS / layout queries (e.g. `getComputedStyle`, `contrast-color()`) resolve; the window just isn't mapped on screen. Set by the CLI's `-noshow` flag. */ render?: boolean | string; /** Render to a bitmap instead of displaying. The window stays hidden; after the page loads (plus renderDelay) a screenshot is captured and msger exits. A string is a file path to write — format from extension (.png/.jpg/.jpeg/.bmp), result.render = {format,width,height,path}. `true` returns the image in result.render = {format,width,height,data(base64)}. Windows (WebView2) only for now. */ renderDelay?: number; /** Render mode: settle delay in ms between the page's load event and the capture (fonts/images/async paint). Default 100. */ renderFormat?: string; /** Render mode image format: png (default), jpeg, or bmp. Derived from the file extension when `render` is a path; settable directly when `render: true`. */ profile?: string; /** Named WebView2 profile: user-data dir becomes `%LOCALAPPDATA%\\webview2-` so this window gets its OWN browser-process cluster. Windows sharing one user-data dir share one browser process — a crash there blacks out ALL of them. Pass a name (e.g. "popout") for secondary windows so they can't take the main window down. */ } /** Screenshot returned in MessageBoxResult.render (render mode). Width/height * are physical pixels — the capture includes the monitor's DPI scale, so a * 400x300 logical window on a 125% display comes back 500x375. */ export interface RenderResult { format: string; /** png | jpeg | bmp */ width: number; /** Physical pixel width */ height: number; /** Physical pixel height */ data?: string; /** Base64 image bytes (render: true) */ path?: string; /** Absolute path of the written file (render: "file") */ } export interface MessageBoxResult { button: string; value?: string; form?: Record; closed?: boolean; dismissed?: boolean; timeout?: boolean; debug?: { html: string; width: number; height: number; autoSize: boolean; }; render?: RenderResult; /** Captured screenshot (render mode) */ renderError?: string; /** Why render mode produced no image — the result promise rejects with this */ exitReason?: string; /** WHY the window went away: 'escape', 'closeRequested', 'timeout', 'render', or 'page' (the page posted a result — button click, msgapi.close(), form submit). Answers "it exited spontaneously" without guessing; MSGER_DIAG=1 logs the same line to msger-diag.log. */ } /** Set the app name used for the per-user bin dir AND the per-app exe filename. * Call before showService/showMessageBox — e.g. `setAppName("mailx")` makes * the running process appear as `mailx.exe` in Task Manager and the taskbar. */ export declare function setAppName(name: string): void; /** Set a per-app icon (PNG or ICO). Copied next to the per-app exe at first * provision so Rust's window icon search picks it up. Per-call `icon` in * `MessageBoxOptions` still takes precedence. */ export declare function setAppIcon(iconPath: string): void; /** The right packages for this distro. Only runtime pieces — building msger * additionally needs the -dev package, which is not msger's business to * install on a machine that only runs it. * * Two dependencies, different weight: * - WebKitGTK is *required*: msger renders with the system webview and its * binary won't even load without it. * - An emoji font is *recommended*: msger runs fine, but every emoji in a * hosted page draws as a tofu box, since Linux browsers take emoji from * system fonts and nothing bundles them. */ export declare function webkitInstallCommand(missing?: { webkit: boolean; emoji: boolean; }): string; /** Does any installed font provide emoji? fontconfig is authoritative when it * is present; otherwise fall back to looking for a font file with "emoji" in * the name. Keep in sync with the copy in msger-native/builder/postinstall.js. */ export declare function hasEmojiFont(): boolean; /** `msger --install-deps` — install the WebKitGTK runtime msger links against. * * Deliberately NOT done from postinstall: an npm script that shells out to * `sudo apt` escalates privilege behind the user's back, blocks forever on a * password prompt in any non-interactive install (CI, containers, unattended * provisioning), and guesses wrong on distros it doesn't know. postinstall * detects and tells; installing stays an explicit, interactive choice. * * Returns the process exit code to use. */ export declare function installLinuxDeps(): number; /** Is the WebKitGTK runtime msger links against present? Mirrors the check in * msger-native/builder/postinstall.js — keep the two in step. */ export declare function hasWebkitRuntime(): boolean; /** * Show a message box dialog using native Rust implementation (extended version) * @param options Message box configuration * @returns MessageBoxHandle with result promise and control methods */ export declare function showMessageBoxEx(options: MessageBoxOptions): MessageBoxHandle; /** * Show a message box dialog using native Rust implementation * @param options Message box configuration * @returns Promise that resolves with user's response */ export declare function showMessageBox(options: MessageBoxOptions): Promise; export type ServiceRequestHandler = (request: any) => void; /** Handle for a service-mode msger instance. Bidirectional IPC with the WebView. */ export declare class ServiceHandle { private child; private _closed; private _onRequest; readonly closed: Promise; constructor(child: ChildProcess); /** Register handler for requests from the WebView (_action messages) */ onRequest(handler: ServiceRequestHandler): void; /** Send a response or event to the WebView (written to child's stdin) */ send(msg: any): void; /** Close the window */ close(): void; } /** * Open msger in service mode — bidirectional IPC, no HTTP. * Parent process handles requests via onRequest, sends responses via send(). */ export declare function showService(options: Omit): ServiceHandle;