/** * Desktop Screenshot Extension * * Takes screenshots of the entire desktop or a specific application window * using native OS commands. Zero external npm dependencies. * * Platforms: * - macOS: screencapture + swift (CGWindowList) * - Linux: import (ImageMagick) + wmctrl * - Windows: PowerShell (System.Drawing + user32.dll) * * The screenshot is returned as a base64-encoded PNG that the spectral-vision * extension automatically analyzes with a vision model. */ import type { ExtensionAPI } from "../../sdk/coding-agent/index.js"; import type { ImageContent } from "../../sdk/ai/index.js"; export type ScreenshotFormat = "png" | "jpg" | "jpeg"; export interface ScreenshotOptions { screen?: string | number; format?: ScreenshotFormat; filename?: string; } export interface WindowInfo { id: number | string; owner: string; title: string; } export declare function tmpDir(): string; export declare function saveScreenshot(buf: Buffer, format: ScreenshotFormat, cwd: string): string; interface DarwinScreenRect { x: number; y: number; width: number; height: number; } export interface DarwinScreenGeometry { displayCount: number; /** Primary display top-left origin in the global CGEvent (points) space. */ primaryOrigin: { x: number; y: number; }; /** Main screen (keyboard focus): logical size + top-left global origin, in points. */ main: DarwinScreenRect; backingScaleFactor: number; } /** Test hook: forget the cached geometry so the next probe hits osascript again. */ export declare function resetDarwinScreenGeometryCache(): void; /** * Logical display geometry via JXA/AppKit, cached for a few seconds (display * arrangements rarely change mid-session). Resolves to `null` when the probe * fails — captures are then left untouched and the tool result says the * scale is unverified. Exported for tests. */ export declare function darwinScreenGeometry(): Promise; export type DarwinScreenshotMode = "screen" | "window"; export interface DarwinNormalizedScreenshot { buffer: Buffer; /** Coordinate-space metadata appended to the tool result text ("" when nothing to say). */ metadata: string; /** Structured fields mirrored into the tool result `details` (additive). */ details: { imageWidthPx?: number; imageHeightPx?: number; logicalWidthPt?: number; logicalHeightPt?: number; displayCount?: number; primaryOriginPt?: { x: number; y: number; }; scaleApplied?: number; resampled?: boolean; }; } /** * Normalize a macOS capture so image pixels map 1:1 onto the logical screen * points the desktop_* tools accept. Full-screen captures are resampled to * the main screen's logical width when the file is a Retina (backing-scale) * capture; window captures are resampled by the display's backing scale * factor (their coordinates are window-local, which the metadata states). * Never throws: on any probe failure the original buffer comes back with a * caution note instead of a silently wrong scale. Exported for tests. */ export declare function normalizeDarwinScreenshot(buf: Buffer, format: ScreenshotFormat, mode: DarwinScreenshotMode): Promise; /** * Run a PowerShell script file and return its stdout as a string. * * Uses `cross-spawn` instead of Node's `execFile` because, on Windows, * `execFile` does not resolve commands through PATHEXT and requires a fully * populated PATH. Inside Electron/desktop sandboxes the PATH is often trimmed, * which leads to `spawn powershell.exe ENOENT`. `cross-spawn` resolves the * executable via PATHEXT/PATH like a shell would. * * `-Sta` is passed so the single-threaded apartment required by * System.Windows.Forms / CopyFromScreen is initialized even in sessions that * default to MTA (avoids COM failures). */ export declare function runPowerShell(psPath: string, opts?: { timeoutMs?: number; }): Promise; export declare function screenshot(options?: ScreenshotOptions): Promise; export declare function screenshotWindow(windowId: number | string, options: ScreenshotOptions, platform: string): Promise; export declare function listWindows(): Promise; export declare function formatWindowList(windows: WindowInfo[], maxRows?: number): string; /** * Last-resort inline carrier for a screenshot that could not be hosted. * * Returns the image unchanged when its base64 payload already fits * `MAX_INLINE_IMAGE_BASE64_CHARS`, a downscaled/re-encoded copy when resizing * gets it under the cap, and `null` when even that fails (no image resizer * available, or the capture is absurdly large). Callers MUST treat `null` as * "do not attach base64" and report the failure — never as "attach it anyway". * * Exported for tests. */ export declare function fitInlineScreenshot(image: ImageContent, maxBase64Chars?: number): Promise; export default function desktopScreenshotExtension(ext: ExtensionAPI): Promise; export {}; //# sourceMappingURL=index.d.ts.map