From 2aec2b93d9c876b1a1d91cd28ada25e487d6dd1c Mon Sep 17 00:00:00 2001 From: 7000pctAUTO Date: Thu, 5 Feb 2026 19:31:49 +0000 Subject: [PATCH] Initial upload with CI/CD workflow --- src/utils/shellUtils.ts | 70 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 src/utils/shellUtils.ts diff --git a/src/utils/shellUtils.ts b/src/utils/shellUtils.ts new file mode 100644 index 0000000..7d9adf0 --- /dev/null +++ b/src/utils/shellUtils.ts @@ -0,0 +1,70 @@ +import { execa, ExecaError } from 'execa'; +import { ExecResult } from '../models/types'; + +export class ShellUtils { + async exec(command: string, options?: { cwd?: string; timeout?: number }): Promise { + try { + const result = await execa(command, { + shell: '/bin/bash', + cwd: options?.cwd, + timeout: options?.timeout || 30000, + reject: false, + }); + + return { + success: result.exitCode === 0, + stdout: result.stdout || '', + stderr: result.stderr || '', + exitCode: result.exitCode || 0, + }; + } catch (error) { + const execaError = error as ExecaError; + return { + success: false, + stdout: execaError.stdout || '', + stderr: execaError.stderr || '', + exitCode: execaError.exitCode || 1, + }; + } + } + + async execWithOutput(command: string, options?: { cwd?: string; timeout?: number }): Promise { + const result = await this.exec(command, options); + if (!result.success) { + throw new Error(`Command failed: ${command}\n${result.stderr}`); + } + return result.stdout; + } + + async execSilent(command: string, options?: { cwd?: string; timeout?: number }): Promise { + const result = await this.exec(command, options); + return result.success; + } + + async getExitCode(command: string, options?: { cwd?: string }): Promise { + const result = await this.exec(command, options); + return result.exitCode; + } + + isCommandAvailable(command: string): Promise { + return this.execSilent(`which ${command}`).catch(() => false); + } + + async getTmuxVersion(): Promise { + const result = await this.exec('tmux -V'); + if (result.success) { + return result.stdout; + } + return null; + } + + async getScreenVersion(): Promise { + const result = await this.exec('screen -v'); + if (result.success) { + return result.stdout; + } + return null; + } +} + +export const shellUtils = new ShellUtils();