Passed
Push — master ( 96ef05...f81447 )
by Darko
09:59
created

TmuxSessionManager::getPaneStatus()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 3
c 1
b 0
f 0
dl 0
loc 7
rs 10
cc 2
nc 2
nop 2
1
<?php
2
3
namespace App\Services\Tmux;
4
5
use App\Models\Settings;
6
use Illuminate\Support\Facades\Process;
7
8
/**
9
 * Service for managing tmux sessions and panes
10
 */
11
class TmuxSessionManager
12
{
13
    protected string $sessionName;
14
15
    protected string $configFile;
16
17
    public function __construct(?string $sessionName = null)
18
    {
19
        $this->sessionName = $sessionName ?? $this->getSessionName();
20
        $this->configFile = config('tmux.config_file');
21
    }
22
23
    /**
24
     * Get the tmux session name from settings or config
25
     */
26
    public function getSessionName(): string
27
    {
28
        return Settings::settingValue('tmux_session')
29
            ?? config('tmux.session.name')
30
            ?? config('tmux.session.default_name', 'nntmux');
31
    }
32
33
    /**
34
     * Check if tmux session exists
35
     */
36
    public function sessionExists(): bool
37
    {
38
        $result = Process::timeout(10)
39
            ->run("tmux list-sessions 2>/dev/null | grep -q '^{$this->sessionName}:'");
40
41
        return $result->successful();
42
    }
43
44
    /**
45
     * Create a new tmux session
46
     */
47
    public function createSession(string $windowName = 'Monitor'): bool
48
    {
49
        if ($this->sessionExists()) {
50
            return false;
51
        }
52
53
        $configOption = file_exists($this->configFile) ? "-f {$this->configFile}" : '';
54
55
        $result = Process::timeout(30)->run(
56
            "tmux {$configOption} new-session -d -s {$this->sessionName} -n {$windowName} 'printf \"\\033]2;{$windowName}\\033\"'"
57
        );
58
59
        return $result->successful();
60
    }
61
62
    /**
63
     * Kill the tmux session
64
     */
65
    public function killSession(): bool
66
    {
67
        if (! $this->sessionExists()) {
68
            return true;
69
        }
70
71
        $result = Process::timeout(30)->run("tmux kill-session -t {$this->sessionName}");
72
73
        return $result->successful();
74
    }
75
76
    /**
77
     * Attach to the tmux session
78
     */
79
    public function attachSession(): bool
80
    {
81
        if (! $this->sessionExists()) {
82
            return false;
83
        }
84
85
        $result = Process::timeout(5)->run(
86
            "tmux select-window -t {$this->sessionName}:0; tmux attach-session -d -t {$this->sessionName}"
87
        );
88
89
        return $result->successful();
90
    }
91
92
    /**
93
     * List all panes in the session
94
     */
95
    public function listPanes(): array
96
    {
97
        if (! $this->sessionExists()) {
98
            return [];
99
        }
100
101
        $result = Process::timeout(10)->run(
102
            "tmux list-panes -s -t {$this->sessionName} -F '#{window_index}:#{pane_index} #{pane_title}'"
103
        );
104
105
        if (! $result->successful()) {
106
            return [];
107
        }
108
109
        $panes = [];
110
        $lines = explode("\n", trim($result->output()));
111
112
        foreach ($lines as $line) {
113
            if (empty($line)) {
114
                continue;
115
            }
116
117
            [$position, $title] = explode(' ', $line, 2);
118
            $panes[$position] = $title;
119
        }
120
121
        return $panes;
122
    }
123
124
    /**
125
     * Get pane status
126
     */
127
    public function getPaneStatus(string $window, string $pane): ?string
128
    {
129
        $result = Process::timeout(5)->run(
130
            "tmux display-message -p -t {$this->sessionName}:{$window}.{$pane} '#{pane_current_command}'"
131
        );
132
133
        return $result->successful() ? trim($result->output()) : null;
134
    }
135
136
    /**
137
     * Check if a pane is running a command
138
     */
139
    public function isPaneActive(string $window, string $pane): bool
140
    {
141
        $status = $this->getPaneStatus($window, $pane);
142
143
        return $status !== null && $status !== 'bash' && $status !== 'sh';
144
    }
145
}
146