/* tslint:disable */ /* eslint-disable */ /* auto-generated by NAPI-RS */ /** Options passed to `new Recorder({...})` from JS. */ export interface RecorderOptions { /** Absolute path where the MP4 will be written. */ output: string /** * Single-monitor MP4 fallback. When `mp4Monitors` is also provided, * it takes precedence and this field is ignored. * * - `Some(id)` — record only this monitor to MP4 at `output` * (legacy behavior, kept for backward compat). * - `None` + no `mp4Monitors` → record **every attached monitor** * (the new default — see `mp4Monitors` for the per-monitor file * path expansion). */ monitorId?: number /** * Which monitors to record to MP4. Mirrors `pairedMonitors` for the * video pipeline: * * - `undefined` (default) — record every attached monitor, one MP4 * per display. Same intelligent-focus stance as paired capture: * the user's full multi-screen session is in the recording. * - `[id, id, ...]` — pin MP4 to exactly these IDs. * - `[]` — disable MP4 entirely while still letting paired capture * run (no ffmpeg process is started). * * When more than one monitor is recorded, `output` is treated as a * path template. If it contains the literal substring * `{monitor_id}`, that's substituted per monitor. Otherwise the * recorder auto-suffixes `-monitor-{id}` before the file extension, * e.g. `/tmp/session.mp4` → `/tmp/session-monitor-1.mp4` + * `/tmp/session-monitor-2.mp4`. Single-monitor recordings use * `output` verbatim. */ mp4Monitors?: Array /** Reserved for future MP4 audio muxing. Accepted today but not recorded. */ microphone?: boolean /** Reserved for future system-audio muxing. Accepted today but not recorded. */ systemAudio?: boolean /** * Substring patterns matched against the focused app name and window title * (case-insensitive). While a matching window is in focus, the recorder * skips writing frames — the MP4 contains a hard cut over the filtered * period. Mirrors the engine's `--ignored-windows` CLI flag. * * Each pattern may use an optional `App::Title` scope: `"Slack::#hr"` * skips only the #hr window inside Slack and leaves other Slack channels * recording. `"::Confidential"` matches any app whose title contains * "Confidential". Plain `"Slack"` keeps the legacy "app OR title * contains" behavior. */ ignoredWindows?: Array /** * Substring whitelist. If non-empty, frames are written ONLY while the * focused app name or window title matches at least one pattern. * Mirrors the engine's `--included-windows` CLI flag. * * Scoped entries (`"Greenhouse::Candidates"`) create a per-app whitelist * — other apps stay unaffected, so this whitelists only that window * without inadvertently blocking Slack/Chrome. Unscoped entries keep * the legacy "must match app or title" global semantics. */ includedWindows?: Array /** * URL patterns to skip (case-insensitive, domain-aware matching). * When the focused window is a browser navigated to a matching URL, * the recorder skips writing frames. Mirrors `--ignored-urls`. */ ignoredUrls?: Array /** * When set, the recorder runs the engine's event-driven paired-capture * pipeline in parallel with the MP4 writer: typed UI events (click, * typing pause, app switch, etc.) + visual-change detection + idle * baseline fire `paired_capture()` against a SQLite at * `{dataDir}/db.sqlite`. JPEG snapshots are written under * `{dataDir}/data/`. Same DB schema and trigger taxonomy the * screenpipe CLI writes, so an SDK-recorded session is queryable by * the existing `screenpipe-js` REST client or any tool that reads the * CLI's DB. * * When omitted, the recorder is video-only — no DB is opened, no * snapshots are written, and the focus-watcher result is consumed only * to gate MP4 frames (the historical SDK behavior). */ dataDir?: string /** * Which monitors to record paired captures from. Only meaningful when * `dataDir` is set. * * - `undefined` (default) — record paired captures from **every * attached monitor**, matching the screenpipe CLI which spins up * one capture loop per monitor and tags each row with its * `monitor_id`. UI events fan out to all monitor loops so a click * on monitor 1 produces a row on every monitor (with the same * `capture_trigger`) — i.e. "what was on every screen the moment * the user did X". Same behavior the CLI ships. * - `[id, id, ...]` — pin paired-capture to this exact set of * monitor IDs. Use when you only care about one display or need * to cap DB volume on a 4-monitor workstation. * * `monitorId` (above) still controls only the MP4 writer — that's * independent of paired capture and remains single-monitor. */ pairedMonitors?: Array /** * Per-event-type toggles for the platform UI hooks that feed * paired-capture triggers. When `undefined`, uses the same defaults * `screenpipe-a11y`'s `UiCaptureConfig::default()` ships with * (clicks, typing pauses, app switches, clipboard ON; keystrokes, * scroll, mouse-move, window-focus OFF — the privacy/volume-friendly * set). Only meaningful when `dataDir` is set. * * Enabling `captureScroll` is required for `scroll_stop` triggers * to fire. Enabling `captureKeystrokes` is required for `key_press` * triggers — note the privacy implication: individual keystrokes * hit the platform hook stream and may surface in event logs. */ uiCapture?: UiCaptureOptions } /** * Per-event-type toggles passed through to the platform UI hooks. Maps * 1-to-1 onto `screenpipe_a11y::config::UiCaptureConfig`. Each field * defaults to the corresponding `UiCaptureConfig::default()` value when * left undefined, so callers can override one knob without restating the * others. See the field doc on each toggle for trigger implications. */ export interface UiCaptureOptions { /** * Capture mouse clicks. Default: true. * Drives the `click` capture trigger. */ captureClicks?: boolean /** * Capture aggregated text input (typing-pause bursts). Default: true. * Drives the `typing_pause` capture trigger. */ captureText?: boolean /** * Capture individual keystrokes. Default: false. * HIGH PRIVACY RISK — individual key events stream through the hook. * Required to enable the `key_press` capture trigger. */ captureKeystrokes?: boolean /** * Capture app-switch events. Default: true. * Drives the `app_switch` capture trigger. */ captureAppSwitch?: boolean /** * Capture window-focus changes within the same app. Default: false. * High volume on workflows with lots of tab/window switching. * Required to enable the `window_focus` capture trigger. */ captureWindowFocus?: boolean /** * Capture scroll events. Default: false. * Very high volume — every wheel tick produces an event. * Required to enable the `scroll_stop` capture trigger. */ captureScroll?: boolean /** * Capture clipboard operations. Default: true. * Drives the `clipboard` capture trigger. */ captureClipboard?: boolean /** * Include clipboard content in the event payload. Default: true. * PRIVACY RISK — clipboard text may include passwords/tokens. */ captureClipboardContent?: boolean /** * Resolve accessibility-element context on each click. Default: true. * Slightly slower but produces richer DB rows. */ captureContext?: boolean /** * Capture mouse-move events. Default: false. * Extreme volume — every pixel of motion. Almost never useful as a * capture trigger; supported for analytics use cases. */ captureMouseMove?: boolean } /** Permission status returned by `requestPermissions`. */ export interface PermissionStatus { /** Screen recording permission granted. */ screen: boolean /** Microphone permission granted. */ microphone: boolean } /** * Lightweight snapshot of the user's focused window. Returned by * `Recorder.focusedApp()`. All fields are best-effort — on some * platforms/apps only `appName` is reliably populated. */ export interface FocusedApp { appName: string windowTitle: string browserUrl?: string nodeCount: number walkMs: number } /** * Current state of the window/URL filter. Returned by * `Recorder.filterStatus()`. When `paused` is true, the capture loop is * dropping frames — `reason` is a short tag identifying which rule fired * (`"ignored_window"`, `"included_window_mismatch"`, `"ignored_url"`, * `"incognito"`, `"excluded_app"`). Both fields are `null`/`false` when * no filter is configured or when a11y permission has not been granted. */ export interface FilterStatus { paused: boolean reason?: string } /** * Patch passed to `Recorder.setFilters({...})` for live filter updates. * Any field omitted (or sent as `null`) clears that list. All three fields * follow the same matching semantics as the matching `RecorderOptions` * fields — including the `App::Title` scope convention on * `ignoredWindows` / `includedWindows`. */ export interface FilterPatch { ignoredWindows?: Array includedWindows?: Array ignoredUrls?: Array } /** * Prompt the OS for screen recording + microphone permissions if not already * granted. On macOS this triggers the TCC dialog the first time; on * subsequent calls it just reports current state. * * Returns `{ screen, microphone }` booleans. */ export declare function requestPermissions(): Promise /** * Record a user's screen to an MP4 file. * * ```ts * import { Recorder } from '@screenpipe/sdk'; * * const r = new Recorder({ output: '/tmp/session.mp4' }); * await r.start(); * // ... user does stuff ... * await r.stop(); * ``` */ export declare class Recorder { /** Construct a recorder. Does NOT start capture — call `.start()`. */ constructor(options: RecorderOptions) /** * Begin writing frames to the output file. Resolves once the * capture stream is live and the MP4 header has been written. */ start(): Promise /** * Stop capture. Flushes the MP4 trailer and closes the file. Idempotent * (safe to call twice). */ stop(): Promise /** * Capture a single frame of the recorder's monitor as a JPEG buffer. * Works whether or not `start()` has been called — useful for live * thumbnail previews in UIs embedding the SDK. */ snapshot(): Promise /** * Number of frames written to the MP4 since `start()`. Useful for * live UI stats. Returns 0 if not recording. */ framesWritten(): Promise /** * Current microphone input level in [0, 1] (smoothed linear RMS). * The first call starts a persistent capture on the default input * device and triggers the macOS Microphone TCC prompt if not yet * granted. Independent of `start()` — works as a pre-flight meter. */ audioLevel(): Promise /** * Current state of the window/URL filter — see `FilterStatus`. * Polled by host integrations to drive UI ("⏸ paused — banking site") * or to count skipped frames. Returns `{ paused: false, reason: null }` * when no filter is configured. */ filterStatus(): Promise /** * Replace the active filter lists at runtime. Each field in `patch` * either provides a new list or — when omitted/`null` — clears that * list. The next focus-watcher tick (≤ 1 s later) re-evaluates the * current focused window against the updated rules. * * Use this for "Pause on banking" toggles, per-session overrides, or * any flow where the filter set isn't known at construction time. */ setFilters(patch: FilterPatch): Promise /** * Snapshot of the currently focused window via accessibility APIs. * Returns `null` when no focused window is detected or the window * is on the skip-list (incognito, excluded app). * * macOS: requires Accessibility permission (System Settings → * Privacy & Security → Accessibility). The first call may silently * return `null` until the user grants it — the SDK does not raise * the dialog itself on macOS, callers should prompt out of band. */ focusedApp(): Promise }