UNPKG

build-in-public-bot

Version:

AI-powered CLI bot for automating build-in-public tweets with code screenshots

203 lines 9.27 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.terminalCommand = void 0; const commander_1 = require("commander"); const chalk_1 = __importDefault(require("chalk")); const ora_1 = __importDefault(require("ora")); const terminal_capture_1 = require("../services/terminal-capture"); const errors_1 = require("../utils/errors"); const fs = __importStar(require("fs/promises")); exports.terminalCommand = new commander_1.Command('terminal') .description('Capture and annotate terminal output') .option('-o, --output <path>', 'Output file path', 'terminal-capture.png') .option('-h, --height <lines>', 'Number of lines to capture', '30') .option('--theme <theme>', 'Color theme to apply') .option('-s, --select <ranges>', 'Select line ranges (e.g., "5-10,15,20-")') .option('--highlight <pattern>', 'Highlight lines matching pattern') .option('--highlight-regex <regex>', 'Highlight lines matching regex') .option('--last-command', 'Capture last command with output') .option('--command <n>', 'Capture nth command (negative for reverse)') .option('--select-errors', 'Auto-select error output') .option('--select-diff', 'Highlight diff changes') .option('--select-prompts', 'Include command prompts') .option('--cursor <pos>', 'Show cursor at position (line:col)') .option('--no-colors', 'Strip ANSI colors') .option('--font-size <size>', 'Font size in pixels', '14') .option('--padding <padding>', 'Padding in pixels', '20') .option('--arrow <spec...>', 'Add arrow annotation (from:to:label)') .option('--box <spec...>', 'Add box annotation (startLine-endLine:startCol-endCol)') .option('--note <spec...>', 'Add note annotation (line:text)') .option('--format <format>', 'Output format (png, svg)', 'png') .option('--list-themes', 'List available terminal themes') .option('--detect-editor', 'Show editor detection information') .option('--dry-run', 'Show what would be captured without saving') .action(async (options) => { try { const terminalCapture = new terminal_capture_1.TerminalCapture(); if (options.listThemes) { const themes = terminalCapture.getAvailableThemes(); console.log(chalk_1.default.cyan('Available terminal themes:')); themes.forEach((theme) => console.log(` - ${theme}`)); return; } if (options.detectEditor) { const editorInfo = terminalCapture.getEditorInfo(); console.log(chalk_1.default.cyan('Editor Detection:')); console.log(` Running in editor: ${editorInfo.isEditor ? chalk_1.default.green('Yes') : chalk_1.default.red('No')}`); if (editorInfo.isEditor && editorInfo.editor) { console.log(` Editor type: ${chalk_1.default.yellow(editorInfo.editor)}`); } if (editorInfo.mode) { console.log(` Mode: ${chalk_1.default.yellow(editorInfo.mode)}`); } return; } const spinner = (0, ora_1.default)('Capturing terminal...').start(); try { const captureOptions = { height: parseInt(options.height), theme: options.theme || 'auto', includeColors: !options.noColors, fontSize: parseInt(options.fontSize), padding: parseInt(options.padding) }; const terminalData = await terminalCapture.capture(captureOptions); if (options.select) { terminalCapture.selectLines(parseRanges(options.select)); } if (options.highlight) { terminalCapture.highlightPattern(options.highlight); } if (options.highlightRegex) { terminalCapture.highlightRegex(new RegExp(options.highlightRegex)); } if (options.lastCommand) { terminalCapture.selectLastCommand(); } if (options.command) { terminalCapture.selectCommand(parseInt(options.command)); } if (options.selectErrors) { terminalCapture.selectErrors(); } if (options.selectDiff) { terminalCapture.selectDiff(); } if (options.cursor) { const [line, col] = options.cursor.split(':').map(Number); terminalCapture.showCursor(line, col); } for (const arrow of (options.arrow || [])) { const parts = arrow.split(':'); if (parts.length >= 4) { const fromLine = parseInt(parts[0]); const fromCol = parseInt(parts[1]); const toLine = parseInt(parts[2]); const toCol = parseInt(parts[3]); const label = parts.slice(4).join(':').replace(/['"]/g, ''); terminalCapture.addArrow({ line: fromLine, col: fromCol }, { line: toLine, col: toCol }, label); } else { const [from, to, label] = parts; const [fromLine, fromCol] = from.split(',').map(Number); const [toLine, toCol] = to.split(',').map(Number); terminalCapture.addArrow({ line: fromLine, col: fromCol }, { line: toLine, col: toCol }, label); } } for (const box of (options.box || [])) { const [range, cols] = box.split(':'); const [startLine, endLine] = range.split('-').map(Number); const [startCol, endCol] = cols ? cols.split('-').map(Number) : [0, -1]; terminalCapture.addBox({ startLine, endLine, startCol, endCol }); } for (const note of (options.note || [])) { const [line, ...text] = note.split(':'); terminalCapture.addNote(parseInt(line), text.join(':')); } if (options.dryRun) { spinner.stop(); console.log(chalk_1.default.yellow('Dry run - would capture:')); console.log(` Lines: ${terminalData.lines.length}`); console.log(` Theme: ${captureOptions.theme}`); console.log(` Output: ${options.output}`); console.log(` Format: ${options.format}`); if (options.select) { console.log(` Selected lines: ${options.select}`); } return; } const buffer = await terminalCapture.render(options.format); await fs.writeFile(options.output, buffer); spinner.succeed(chalk_1.default.green(`Terminal captured to ${options.output}`)); } catch (error) { spinner.fail(chalk_1.default.red('Failed to capture terminal')); throw error; } } catch (error) { (0, errors_1.handleError)(error); } }); function parseRanges(rangeStr) { const ranges = []; const parts = rangeStr.split(','); for (const part of parts) { const trimmed = part.trim(); if (trimmed.includes('-')) { const [start, end] = trimmed.split('-'); ranges.push({ start: start ? parseInt(start) : 1, end: end ? parseInt(end) : -1 }); } else { const line = parseInt(trimmed); ranges.push({ start: line, end: line }); } } return ranges; } exports.default = exports.terminalCommand; //# sourceMappingURL=terminal.js.map