capture_pane
Capture the last lines from a session's active pane to check training progress and recent output.
Instructions
Capture the last N lines visible in the session's active pane (default 100, max 10000). Returns the joined text. The primary primitive for "is my training still running? show me the latest output".
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Session name. | |
| lines | No | Number of lines to capture (default 100). |
Implementation Reference
- server.js:134-151 (handler)The 'capturePane' function that executes the capture_pane tool logic. It shells out to tmux capture-pane to capture visible pane text.
async function capturePane(args) { const missing = requireTmux(); if (missing) return errorResult(missing); const bad = validSessionName(args.name); if (bad) return errorResult(bad); const lines = Math.max(1, Math.min(10000, Math.floor(args.lines ?? 100))); // `-p` prints to stdout, `-S -<N>` starts N lines before the bottom of the // scrollback, `-J` joins wrapped lines, `-t =<name>` targets the session's // active pane. // `=NAME:` targets the session's active window + active pane with exact name match. // `=NAME` (no colon) is a session target and fails on capture-pane which needs a pane. const r = await run(BIN.tmux, ['capture-pane', '-p', '-J', '-S', `-${lines}`, '-t', `=${args.name}:`]); if (r.code !== 0) return errorResult(`tmux capture-pane failed: ${r.stderr || r.stdout}`); // Trim trailing blank lines from the visible-pane snapshot; they're just // empty rows below the cursor and add noise. const text = r.stdout.replace(/\n+$/, ''); return textResult({ session: args.name, lines, text }); } - server.js:267-280 (schema)The input schema registration for the capture_pane tool, defining name (required) and lines (optional, 1-10000) properties.
{ name: 'capture_pane', description: 'Capture the last N lines visible in the session\'s active pane (default 100, max 10000). Returns the joined text. The primary primitive for "is my training still running? show me the latest output".', annotations: { title: 'Capture pane output', readOnlyHint: true, destructiveHint: false, openWorldHint: false }, inputSchema: { type: 'object', properties: { name: { type: 'string', description: 'Session name.' }, lines: { type: 'integer', minimum: 1, maximum: 10000, description: 'Number of lines to capture (default 100).' }, }, required: ['name'], additionalProperties: false, }, }, - server.js:326-334 (registration)The HANDLERS map that registers capture_pane -> capturePane for JSON-RPC dispatch.
const HANDLERS = { list_sessions: listSessions, has_session: hasSession, list_windows: listWindows, capture_pane: capturePane, new_session: newSession, send_keys: sendKeys, kill_session: killSession, }; - server.js:49-64 (helper)The 'run' helper function that spawns a child process and captures stdout/stderr, used by capturePane to execute tmux.
function run(cmd, args, opts = {}) { return new Promise((resolve) => { const child = spawn(cmd, args, { stdio: ['pipe', 'pipe', 'pipe'], ...opts }); let out = Buffer.alloc(0); let err = Buffer.alloc(0); child.stdout.on('data', (d) => { out = Buffer.concat([out, d]); }); child.stderr.on('data', (d) => { err = Buffer.concat([err, d]); }); child.on('error', (e) => resolve({ code: -1, stdout: '', stderr: e.message })); child.stdin.end(); child.on('close', (code) => resolve({ code, stdout: out.toString('utf8'), stderr: err.toString('utf8'), })); }); } - server.js:69-74 (helper)The 'validSessionName' helper used by capturePane to validate the session name input.
function validSessionName(name) { if (typeof name !== 'string' || !name.length) return 'name is required (non-empty string)'; if (name.length > 100) return 'name too long (max 100)'; if (/[.:\s|]/.test(name)) return "name cannot contain '.', ':', '|', or whitespace"; return null; }