/** * Minimal logger interface. The fork uses the same shape (it is the * client.app.log envelope). Hivemind does not currently export a Logger * type, so this is duplicated here. When a shared/logger.ts module * lands, this can be replaced with `import type { Logger } from "../../shared/logger.js"`. */ export interface Logger { debug(msg: string, data?: unknown): void; info(msg: string, data?: unknown): void; warn(msg: string, data?: unknown): void; error(msg: string, data?: unknown): void; } /** * Tmux layout identifiers. Mirrors the fork's `TmuxLayout` union from * `opencode-tmux/src/config.ts` (1:1 — same string set). */ export type TmuxLayout = "main-vertical" | "main-horizontal" | "tiled" | "even-horizontal" | "even-vertical"; /** * Result of a `spawnPane` call. * - `paneId` is set when `success === true`. * - `error` is set when `success === false` (human-readable failure reason). * ORIGIN: opencode-tmux/src/tmux.ts:8-11 */ export interface PaneResult { success: boolean; paneId?: string; /** * Human-readable failure reason. Set when `success === false` so callers * can surface WHY the spawn failed (binary missing, no main pane, tmux * CLI error, etc.) instead of receiving a silent `{success: false}`. */ error?: string; } /** * Parsed pane state from one line of `tmux list-panes` output. Re-exported * from `./types.js` so the multiplexer is self-contained for any caller * that imports directly from this file. Canonical home is `./types.js`. * * ORIGIN: opencode-tmux/src/tmux.ts:13-20 (carried forward). */ export type { PaneState } from "./types.js"; import type { PaneState } from "./types.js"; /** * Options for `spawnPane`. The `hivemindMeta` field carries the agent * label + delegation id that gets stamped into the pane title * (`[agent] deleg123 — description`). * * ORIGIN: opencode-tmux/src/tmux.ts:22-32 */ export interface SpawnPaneOptions { sessionId: string; description: string; serverUrl: string; directory: string; binaryPath?: string; hivemindMeta?: { agent: string; delegationId: string; }; } /** * Wrapper around the `tmux` CLI binary. Lazily resolves the binary path * on the first call (binary resolution runs `which tmux` / `where tmux`). * * ORIGIN: opencode-tmux/src/tmux.ts:38-47 (constructor) * ORIGIN: opencode-tmux/src/tmux.ts:49-58 (isAvailable + isInsideSession) * ORIGIN: opencode-tmux/src/tmux.ts:60-72 (findBinary + targetArgs helpers) * ORIGIN: opencode-tmux/src/tmux.ts:74-89 (getMainPaneId — promoted to public) * ORIGIN: opencode-tmux/src/tmux.ts:91-94 (getBinary helper) * ORIGIN: opencode-tmux/src/tmux.ts:96-181 (spawnPane) * ORIGIN: opencode-tmux/src/tmux.ts:183-209 (closePane) * ORIGIN: opencode-tmux/src/tmux.ts:223-247 (sendKeys) * ORIGIN: opencode-tmux/src/tmux.ts:261-314 (listPanes) * ORIGIN: opencode-tmux/src/tmux.ts:316-345 (applyLayout) */ export declare class TmuxMultiplexer { private layout; private mainPaneSize; private log?; private binaryPath; private hasChecked; private readonly targetPane; constructor(layout?: TmuxLayout, mainPaneSize?: number, log?: Logger | undefined); /** * Resolve the tmux binary (cached). Returns true iff the binary was * found on PATH. * * ORIGIN: opencode-tmux/src/tmux.ts:49-54 */ isAvailable(): Promise; /** * Are we running inside a tmux session? Synchronous check on * `process.env.TMUX`. Used by `SessionManager` to gate `enabled`. * * ORIGIN: opencode-tmux/src/tmux.ts:56-58 */ isInsideSession(): boolean; /** * Find the tmux binary on PATH. POSIX: `which tmux`; win32: `where tmux`. * Returns the first match, or `null` on failure. * * ORIGIN: opencode-tmux/src/tmux.ts:60-68 */ private findBinary; /** * Build the `-t ` arg pair for tmux commands that target the * current pane (the one the harness is running in). Returns `[]` * outside a tmux session. * * ORIGIN: opencode-tmux/src/tmux.ts:70-72 */ private targetArgs; /** * Resolve the main (pane_index = 0) pane id of the current tmux window. * Returns `null` if tmux is unavailable, no main pane exists, or the * list-panes call fails. * * Originally private in the fork (`opencode-tmux/src/tmux.ts:74-89`). * Promoted to public here because the Hivemind `tmux-copilot` tool's * `getMainPaneId` adapter method needs it (fork-bridge.ts:106). * * ORIGIN: opencode-tmux/src/tmux.ts:74-89 */ getMainPaneId(): Promise; /** * Get the cached binary path, triggering resolution if necessary. * * ORIGIN: opencode-tmux/src/tmux.ts:91-94 */ private getBinary; /** * Spawn a new tmux pane that runs `opencode attach`. The pane is * created via `split-window -h -d -P -F #{pane_id}` (horizontal split, * don't switch focus, print the new pane id). After spawn we apply * the configured layout and (if `hivemindMeta` is supplied) stamp a * `[agent] deleg123 — description` title onto the pane (truncated to * 40 chars — tmux title length limit). * * ORIGIN: opencode-tmux/src/tmux.ts:96-181 */ spawnPane(options: SpawnPaneOptions): Promise; /** * Close a tmux pane: first send `C-c` to give the inner process a * chance to clean up, wait 250ms, then `kill-pane`. After kill, apply * the configured layout (cosmetic). Returns `false` if tmux is not * available or the kill fails. * * ORIGIN: opencode-tmux/src/tmux.ts:183-209 */ closePane(paneId: string): Promise; /** * Send keystrokes to a tmux pane. Awaits the tmux `send-keys` call * to confirm tmux accepted the command. NOTE: tmux does not provide * a signal that the target pane actually consumed the text — a * resolved promise only means tmux accepted the input. A false * confirmation would be worse than no confirmation, so callers * should not assume the pane has processed the keys. * * When `literal` is true, tmux's `-l` flag is used to suppress * special-key interpretation, preserving the text exactly as * provided. * * ORIGIN: opencode-tmux/src/tmux.ts:223-247 */ sendKeys(paneId: string, text: string, literal?: boolean): Promise; /** * List all panes in the current tmux window with parsed metadata. * Uses tmux format `#{pane_id}\t#{pane_title}\t#{pane_active}\t#{pane_width}x#{pane_height}` * and parses one PaneState per non-empty line. Malformed lines * (wrong field count, non-integer dimensions) are logged at debug * and skipped — partial results are preferred over a tool failure. * * When `mainPaneId` is supplied, the matching pane has `isMain: true`. * When undefined, all records have `isMain: false` (graceful * degradation when the caller didn't know the main pane id). * * ORIGIN: opencode-tmux/src/tmux.ts:261-314 */ listPanes(mainPaneId?: string): Promise; /** * Capture the visible content of a tmux pane via `tmux capture-pane -p`. * Returns the raw text content (up to `maxBytes` characters, default 5000) * along with the capture timestamp and byte length. * * This is the read-side companion to `sendKeys` — used by the polling * loop in `SessionManager.startPolling()` (P58.8 S1) and by the * `delegation-status peek` action to surface what the user currently * sees in the pane. The 2-second timeout protects against hung tmux * servers; a timeout returns `byteLength: 0` (the caller can detect * this and skip the cache write). * * @param paneId - The tmux pane id (e.g. `%0`). * @param maxBytes - Maximum content length to return. Defaults to 5000. * @returns Captured content + timestamp + byte length. */ capturePaneContent(paneId: string, maxBytes?: number): Promise<{ content: string; capturedAt: number; byteLength: number; }>; /** * Apply a tmux window layout and (for `main-*` layouts) set the * main-pane size. For `tiled`/`even-*` we only need the * `select-layout` call. * * ORIGIN: opencode-tmux/src/tmux.ts:316-345 */ applyLayout(layout: TmuxLayout, mainPaneSize: number): Promise; } //# sourceMappingURL=tmux-multiplexer.d.ts.map