pi-remote-control/extensions/remote-control/tmux/snapshot.ts

58 lines
1.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* tmux capture-pane snapshot.
*
* Returns a plain-text snapshot of a pane's visible content.
* Used by the snapshot route (T-1.5) and the /thumbnail endpoint (T-1.6).
*
* Owner: T-1.1
*/
import { execFile } from "node:child_process";
import { promisify } from "node:util";
const execFileAsync = promisify(execFile);
export interface SnapshotOptions {
/** tmux session name */
session: string;
/** pane index within session (default "0.0") */
pane?: string;
/** capture width (default: actual pane width) */
width?: number;
/** capture height (default: actual pane height) */
height?: number;
/** include escape sequences for colour/style (default: false = plain text) */
escapes?: boolean;
}
/**
* Capture a plain-text (or escape-annotated) snapshot of a tmux pane.
* Returns raw text as a string.
*/
export async function capturePane(opts: SnapshotOptions): Promise<string> {
const { session, pane = "0.0", escapes = false } = opts;
const target = `${session}:${pane}`;
const args = ["capture-pane", "-t", target, "-p"];
if (escapes) args.push("-e"); // include escape sequences
// Note: -S/-E (start/end line) omitted — captures current visible content
const { stdout } = await execFileAsync("tmux", args);
return stdout;
}
/**
* Capture a thumbnail-sized snapshot (40×12) for the REST thumbnail endpoint.
* Returns plain text, trimmed.
*/
export async function captureThumbnail(
session: string,
pane = "0.0",
): Promise<string> {
// tmux can't resize the capture directly via capture-pane flags, so we
// capture full content and truncate to 40-char wide × 12 lines.
const raw = await capturePane({ session, pane, escapes: false });
const lines = raw.split("\n").slice(0, 12);
return lines.map((l) => l.slice(0, 40)).join("\n");
}