From 8a1c87a3d1714b2a4e1b2afebc434d9647430d3d Mon Sep 17 00:00:00 2001 From: 7000pctAUTO Date: Thu, 5 Feb 2026 19:31:55 +0000 Subject: [PATCH] Initial upload with CI/CD workflow --- src/parsers/screenParser.ts | 149 ++++++++++++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 src/parsers/screenParser.ts diff --git a/src/parsers/screenParser.ts b/src/parsers/screenParser.ts new file mode 100644 index 0000000..8f8f271 --- /dev/null +++ b/src/parsers/screenParser.ts @@ -0,0 +1,149 @@ +import { shellUtils } from '../utils/shellUtils'; +import { Layout, Session, Window, Pane, ParserResult, TerminalType } from '../models/types'; + +interface ScreenWindowInfo { + number: number; + title: string; + layout?: string; +} + +interface ScreenSessionInfo { + session_name: string; + windows: ScreenWindowInfo[]; +} + +export class ScreenParser { + async isAvailable(): Promise { + return shellUtils.isCommandAvailable('screen'); + } + + async listSessions(): Promise { + const result = await shellUtils.exec('screen -ls | grep -o "[0-9]*\\.[^[:space:]]*"'); + if (!result.success) { + return []; + } + return result.stdout.split('\n').filter(Boolean); + } + + async captureSession(sessionName?: string): Promise> { + try { + const sessions = await this.listSessions(); + if (sessions.length === 0) { + return { success: false, error: 'No screen sessions found' }; + } + + const targetSession = sessionName || sessions[0]; + const sessionInfo = await this.getSessionInfo(targetSession); + + if (!sessionInfo) { + return { success: false, error: `Failed to capture session: ${targetSession}` }; + } + + const layout = this.convertToLayout(sessionInfo); + return { success: true, data: layout }; + } catch (error) { + return { success: false, error: (error as Error).message }; + } + } + + private async getSessionInfo(sessionName: string): Promise { + const result = await shellUtils.exec(`screen -S "${sessionName}" -Q windows`); + if (!result.success) { + return null; + } + + const windows: ScreenWindowInfo[] = []; + const lines = result.stdout.split('\n'); + + for (const line of lines) { + const match = line.match(/(\d+)\s+(\*)?(.+)/); + if (match) { + windows.push({ + number: parseInt(match[1], 10), + title: match[3].trim(), + }); + } + } + + return { + session_name: sessionName, + windows, + }; + } + + private convertToLayout(sessionInfo: ScreenSessionInfo): Layout { + const windows: Window[] = sessionInfo.windows.map((w) => { + const panes: Pane[] = [ + { + id: 'p0', + index: 0, + layout: { x: 0, y: 0, width: 80, height: 24 }, + }, + ]; + + return { + id: `w${w.number}`, + index: w.number, + name: w.title || `window-${w.number}`, + panes, + }; + }); + + const session: Session = { + id: `s-${sessionInfo.session_name}`, + name: sessionInfo.session_name, + windows, + activeWindowIndex: 0, + }; + + return { + version: '1.0.0', + terminalType: 'screen' as TerminalType, + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), + session, + metadata: { + description: `Captured screen session: ${sessionInfo.session_name}`, + }, + }; + } + + async generateRestoreCommands(layout: Layout, sessionName?: string): Promise { + const commands: string[] = []; + const targetSession = sessionName || layout.session.name; + + commands.push(`screen -dmS "${targetSession}"`); + + for (let i = 0; i < layout.session.windows.length; i++) { + const window = layout.session.windows[i]; + + if (i === 0) { + commands.push(`screen -S "${targetSession}" -X title "${window.name}"`); + } else { + commands.push(`screen -S "${targetSession}" -X screen ${window.index}`); + commands.push(`screen -S "${targetSession}" -X title "${window.name}"`); + } + } + + return commands; + } + + async restoreLayout(layout: Layout, sessionName?: string): Promise> { + try { + const commands = await this.generateRestoreCommands(layout, sessionName); + + for (const command of commands) { + const result = await shellUtils.exec(command); + if (!result.success) { + return { success: false, error: `Failed to execute: ${command}\n${result.stderr}` }; + } + } + + return { success: true }; + } catch (error) { + return { success: false, error: (error as Error).message }; + } + } +} + +export const screenParser = new ScreenParser();