@ebowwa/terminal 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +6855 -28130
- package/dist/mcp/index.js +7244 -27317
- package/package.json +1 -1
- package/src/api.js +0 -861
- package/src/client.js +0 -92
- package/src/config.js +0 -490
- package/src/error.js +0 -32
- package/src/exec.js +0 -183
- package/src/files.js +0 -521
- package/src/fingerprint.js +0 -336
- package/src/index.js +0 -127
- package/src/manager.js +0 -358
- package/src/mcp/index.js +0 -555
- package/src/mcp/stdio.js +0 -840
- package/src/network-error-detector.js +0 -101
- package/src/pool.js +0 -840
- package/src/pty.js +0 -344
- package/src/resources.js +0 -64
- package/src/scp.js +0 -166
- package/src/sessions.js +0 -895
- package/src/tmux-exec.js +0 -169
- package/src/tmux-local.js +0 -937
- package/src/tmux-manager.js +0 -1026
- package/src/tmux.js +0 -826
- package/src/types.js +0 -5
package/src/tmux.js
DELETED
|
@@ -1,826 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* tmux-based Terminal Sessions
|
|
4
|
-
* Provides persistent terminal sessions using tmux on remote servers
|
|
5
|
-
* Includes automatic tmux installation and session management
|
|
6
|
-
*/
|
|
7
|
-
var __assign = (this && this.__assign) || function () {
|
|
8
|
-
__assign = Object.assign || function(t) {
|
|
9
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
10
|
-
s = arguments[i];
|
|
11
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
12
|
-
t[p] = s[p];
|
|
13
|
-
}
|
|
14
|
-
return t;
|
|
15
|
-
};
|
|
16
|
-
return __assign.apply(this, arguments);
|
|
17
|
-
};
|
|
18
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
19
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
20
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
21
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
22
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
23
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
24
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
25
|
-
});
|
|
26
|
-
};
|
|
27
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
28
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
29
|
-
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
30
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
31
|
-
function step(op) {
|
|
32
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
33
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
34
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
35
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
36
|
-
switch (op[0]) {
|
|
37
|
-
case 0: case 1: t = op; break;
|
|
38
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
39
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
40
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
41
|
-
default:
|
|
42
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
43
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
44
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
45
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
46
|
-
if (t[2]) _.ops.pop();
|
|
47
|
-
_.trys.pop(); continue;
|
|
48
|
-
}
|
|
49
|
-
op = body.call(thisArg, _);
|
|
50
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
51
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
52
|
-
}
|
|
53
|
-
};
|
|
54
|
-
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
55
|
-
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
56
|
-
if (ar || !(i in from)) {
|
|
57
|
-
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
58
|
-
ar[i] = from[i];
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
return to.concat(ar || Array.prototype.slice.call(from));
|
|
62
|
-
};
|
|
63
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
64
|
-
exports.generateSessionName = generateSessionName;
|
|
65
|
-
exports.isTmuxInstalled = isTmuxInstalled;
|
|
66
|
-
exports.installTmux = installTmux;
|
|
67
|
-
exports.ensureTmux = ensureTmux;
|
|
68
|
-
exports.listTmuxSessions = listTmuxSessions;
|
|
69
|
-
exports.hasTmuxSession = hasTmuxSession;
|
|
70
|
-
exports.createOrAttachTmuxSession = createOrAttachTmuxSession;
|
|
71
|
-
exports.killTmuxSession = killTmuxSession;
|
|
72
|
-
exports.getTmuxSessionInfo = getTmuxSessionInfo;
|
|
73
|
-
exports.cleanupOldTmuxSessions = cleanupOldTmuxSessions;
|
|
74
|
-
exports.getTmuxResourceUsage = getTmuxResourceUsage;
|
|
75
|
-
exports.sendCommandToPane = sendCommandToPane;
|
|
76
|
-
exports.splitPane = splitPane;
|
|
77
|
-
exports.listSessionWindows = listSessionWindows;
|
|
78
|
-
exports.listWindowPanes = listWindowPanes;
|
|
79
|
-
exports.capturePane = capturePane;
|
|
80
|
-
exports.getPaneHistory = getPaneHistory;
|
|
81
|
-
exports.switchWindow = switchWindow;
|
|
82
|
-
exports.switchPane = switchPane;
|
|
83
|
-
exports.renameWindow = renameWindow;
|
|
84
|
-
exports.killPane = killPane;
|
|
85
|
-
exports.getDetailedSessionInfo = getDetailedSessionInfo;
|
|
86
|
-
var pool_js_1 = require("./pool.js");
|
|
87
|
-
var ssh_1 = require("@codespaces/ssh");
|
|
88
|
-
var DEFAULT_CONFIG = {
|
|
89
|
-
sessionPrefix: "codespaces",
|
|
90
|
-
defaultShell: "/bin/bash",
|
|
91
|
-
term: "xterm-256color",
|
|
92
|
-
timeout: 30,
|
|
93
|
-
historyLimit: 10000, // 10k lines ~ 1-2MB per session
|
|
94
|
-
sessionAgeLimit: 30 * 24 * 60 * 60 * 1000, // 30 days
|
|
95
|
-
};
|
|
96
|
-
/**
|
|
97
|
-
* Generate a tmux session name for a host
|
|
98
|
-
*/
|
|
99
|
-
function generateSessionName(host, user) {
|
|
100
|
-
if (user === void 0) { user = "root"; }
|
|
101
|
-
var sanitizedHost = host.replace(/[.]/g, "-");
|
|
102
|
-
return "".concat(DEFAULT_CONFIG.sessionPrefix, "-").concat(sanitizedHost);
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* Check if tmux is installed on the remote server
|
|
106
|
-
*/
|
|
107
|
-
function isTmuxInstalled(options) {
|
|
108
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
109
|
-
var pool, result, _a;
|
|
110
|
-
return __generator(this, function (_b) {
|
|
111
|
-
switch (_b.label) {
|
|
112
|
-
case 0:
|
|
113
|
-
pool = (0, pool_js_1.getSSHPool)();
|
|
114
|
-
_b.label = 1;
|
|
115
|
-
case 1:
|
|
116
|
-
_b.trys.push([1, 3, , 4]);
|
|
117
|
-
return [4 /*yield*/, pool.exec("type tmux", __assign(__assign({}, options), { timeout: 5 }))];
|
|
118
|
-
case 2:
|
|
119
|
-
result = _b.sent();
|
|
120
|
-
return [2 /*return*/, result !== "0"];
|
|
121
|
-
case 3:
|
|
122
|
-
_a = _b.sent();
|
|
123
|
-
return [2 /*return*/, false];
|
|
124
|
-
case 4: return [2 /*return*/];
|
|
125
|
-
}
|
|
126
|
-
});
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* Install tmux on the remote server
|
|
131
|
-
*
|
|
132
|
-
* FALLBACK MECHANISM: This should NOT be the primary installation method.
|
|
133
|
-
* tmux should be installed via cloud-init during initial node provisioning.
|
|
134
|
-
*
|
|
135
|
-
* This function exists for:
|
|
136
|
-
* - Legacy nodes provisioned before cloud-init included tmux
|
|
137
|
-
* - Manual node provisioning outside cheapspaces
|
|
138
|
-
* - Recovery scenarios where cloud-init failed
|
|
139
|
-
*
|
|
140
|
-
* @see workspace/docs/design/node-agent/TMUX-INSTALLATION.md
|
|
141
|
-
* @see workspace/src/lib/bootstrap/cloud-init.ts - where tmux should be added to packages
|
|
142
|
-
*
|
|
143
|
-
* Supports Debian/Ubuntu (apt) and CentOS/RHEL (yum/dnf)
|
|
144
|
-
*/
|
|
145
|
-
function installTmux(options) {
|
|
146
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
147
|
-
var pool, installCmd, installed, error_1;
|
|
148
|
-
return __generator(this, function (_a) {
|
|
149
|
-
switch (_a.label) {
|
|
150
|
-
case 0:
|
|
151
|
-
pool = (0, pool_js_1.getSSHPool)();
|
|
152
|
-
_a.label = 1;
|
|
153
|
-
case 1:
|
|
154
|
-
_a.trys.push([1, 4, , 5]);
|
|
155
|
-
installCmd = "\n if command -v apt-get >/dev/null 2>&1; then\n # Debian/Ubuntu\n export DEBIAN_FRONTEND=noninteractive\n apt-get update -qq && apt-get install -y -qq tmux\n elif command -v yum >/dev/null 2>&1; then\n # CentOS/RHEL (older)\n yum install -y -q tmux\n elif command -v dnf >/dev/null 2>&1; then\n # Fedora/RHEL (newer)\n dnf install -y -q tmux\n elif command -v apk >/dev/null 2>&1; then\n # Alpine\n apk add --no-cache tmux\n else\n echo \"ERROR: No supported package manager found\"\n exit 1\n fi\n ";
|
|
156
|
-
return [4 /*yield*/, pool.exec(installCmd, __assign(__assign({}, options), { timeout: 120 }))];
|
|
157
|
-
case 2:
|
|
158
|
-
_a.sent();
|
|
159
|
-
return [4 /*yield*/, isTmuxInstalled(options)];
|
|
160
|
-
case 3:
|
|
161
|
-
installed = _a.sent();
|
|
162
|
-
if (installed) {
|
|
163
|
-
return [2 /*return*/, { success: true, message: "tmux installed successfully" }];
|
|
164
|
-
}
|
|
165
|
-
else {
|
|
166
|
-
return [2 /*return*/, { success: false, message: "tmux installation failed" }];
|
|
167
|
-
}
|
|
168
|
-
return [3 /*break*/, 5];
|
|
169
|
-
case 4:
|
|
170
|
-
error_1 = _a.sent();
|
|
171
|
-
return [2 /*return*/, {
|
|
172
|
-
success: false,
|
|
173
|
-
message: "tmux installation error: ".concat(error_1 instanceof Error ? error_1.message : String(error_1)),
|
|
174
|
-
}];
|
|
175
|
-
case 5: return [2 /*return*/];
|
|
176
|
-
}
|
|
177
|
-
});
|
|
178
|
-
});
|
|
179
|
-
}
|
|
180
|
-
/**
|
|
181
|
-
* Ensure tmux is available, installing if necessary
|
|
182
|
-
*/
|
|
183
|
-
function ensureTmux(options) {
|
|
184
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
185
|
-
var installed;
|
|
186
|
-
return __generator(this, function (_a) {
|
|
187
|
-
switch (_a.label) {
|
|
188
|
-
case 0: return [4 /*yield*/, isTmuxInstalled(options)];
|
|
189
|
-
case 1:
|
|
190
|
-
installed = _a.sent();
|
|
191
|
-
if (installed) {
|
|
192
|
-
return [2 /*return*/, { success: true, message: "tmux already installed" }];
|
|
193
|
-
}
|
|
194
|
-
console.log("[Tmux] Not installed, attempting installation...");
|
|
195
|
-
return [4 /*yield*/, installTmux(options)];
|
|
196
|
-
case 2: return [2 /*return*/, _a.sent()];
|
|
197
|
-
}
|
|
198
|
-
});
|
|
199
|
-
});
|
|
200
|
-
}
|
|
201
|
-
/**
|
|
202
|
-
* List existing tmux sessions on the remote server
|
|
203
|
-
*/
|
|
204
|
-
function listTmuxSessions(options) {
|
|
205
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
206
|
-
var pool, result, _a;
|
|
207
|
-
return __generator(this, function (_b) {
|
|
208
|
-
switch (_b.label) {
|
|
209
|
-
case 0:
|
|
210
|
-
pool = (0, pool_js_1.getSSHPool)();
|
|
211
|
-
_b.label = 1;
|
|
212
|
-
case 1:
|
|
213
|
-
_b.trys.push([1, 3, , 4]);
|
|
214
|
-
return [4 /*yield*/, pool.exec("tmux list-sessions -F '#{session_name}' 2>/dev/null || echo ''", __assign(__assign({}, options), { timeout: 5 }))];
|
|
215
|
-
case 2:
|
|
216
|
-
result = _b.sent();
|
|
217
|
-
if (!result || result === "0" || result.trim() === "") {
|
|
218
|
-
return [2 /*return*/, []];
|
|
219
|
-
}
|
|
220
|
-
return [2 /*return*/, result.trim().split("\n")];
|
|
221
|
-
case 3:
|
|
222
|
-
_a = _b.sent();
|
|
223
|
-
return [2 /*return*/, []];
|
|
224
|
-
case 4: return [2 /*return*/];
|
|
225
|
-
}
|
|
226
|
-
});
|
|
227
|
-
});
|
|
228
|
-
}
|
|
229
|
-
/**
|
|
230
|
-
* Check if a specific tmux session exists
|
|
231
|
-
*/
|
|
232
|
-
function hasTmuxSession(sessionName, options) {
|
|
233
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
234
|
-
var sessions;
|
|
235
|
-
return __generator(this, function (_a) {
|
|
236
|
-
switch (_a.label) {
|
|
237
|
-
case 0: return [4 /*yield*/, listTmuxSessions(options)];
|
|
238
|
-
case 1:
|
|
239
|
-
sessions = _a.sent();
|
|
240
|
-
return [2 /*return*/, sessions.includes(sessionName)];
|
|
241
|
-
}
|
|
242
|
-
});
|
|
243
|
-
});
|
|
244
|
-
}
|
|
245
|
-
/**
|
|
246
|
-
* Create or attach to a tmux session
|
|
247
|
-
* Returns the SSH command arguments to connect to the tmux session
|
|
248
|
-
*/
|
|
249
|
-
function createOrAttachTmuxSession(host_1) {
|
|
250
|
-
return __awaiter(this, arguments, void 0, function (host, user, keyPath, config) {
|
|
251
|
-
var fullConfig, sessionName, pool, sshOptions, tmuxCheck, sessionExists, flags, sshArgs, tmuxCmd, _a;
|
|
252
|
-
if (user === void 0) { user = "root"; }
|
|
253
|
-
if (config === void 0) { config = {}; }
|
|
254
|
-
return __generator(this, function (_b) {
|
|
255
|
-
switch (_b.label) {
|
|
256
|
-
case 0:
|
|
257
|
-
fullConfig = __assign(__assign({}, DEFAULT_CONFIG), config);
|
|
258
|
-
sessionName = generateSessionName(host, user);
|
|
259
|
-
pool = (0, pool_js_1.getSSHPool)();
|
|
260
|
-
sshOptions = {
|
|
261
|
-
host: host,
|
|
262
|
-
user: user,
|
|
263
|
-
port: 22,
|
|
264
|
-
keyPath: keyPath,
|
|
265
|
-
timeout: fullConfig.timeout,
|
|
266
|
-
};
|
|
267
|
-
return [4 /*yield*/, ensureTmux(sshOptions)];
|
|
268
|
-
case 1:
|
|
269
|
-
tmuxCheck = _b.sent();
|
|
270
|
-
if (!tmuxCheck.success) {
|
|
271
|
-
throw new Error("Failed to setup tmux: ".concat(tmuxCheck.message));
|
|
272
|
-
}
|
|
273
|
-
return [4 /*yield*/, hasTmuxSession(sessionName, sshOptions)];
|
|
274
|
-
case 2:
|
|
275
|
-
sessionExists = _b.sent();
|
|
276
|
-
flags = __spreadArray(__spreadArray([], ssh_1.SSHPresets.default, true), [
|
|
277
|
-
ssh_1.SSHFlags.port(22),
|
|
278
|
-
ssh_1.SSHFlags.forceTTY(2), // -tt for forced PTY
|
|
279
|
-
], false);
|
|
280
|
-
if (keyPath) {
|
|
281
|
-
flags.push(ssh_1.SSHFlags.identity(String(keyPath)));
|
|
282
|
-
}
|
|
283
|
-
sshArgs = (0, ssh_1.buildSSHArgs)(flags, host, user);
|
|
284
|
-
tmuxCmd = [
|
|
285
|
-
"tmux",
|
|
286
|
-
"new-session",
|
|
287
|
-
"-A",
|
|
288
|
-
"-s", sessionName,
|
|
289
|
-
"-n", "codespaces",
|
|
290
|
-
];
|
|
291
|
-
sshArgs.push.apply(sshArgs, tmuxCmd);
|
|
292
|
-
if (!!sessionExists) return [3 /*break*/, 6];
|
|
293
|
-
_b.label = 3;
|
|
294
|
-
case 3:
|
|
295
|
-
_b.trys.push([3, 5, , 6]);
|
|
296
|
-
return [4 /*yield*/, pool.exec("tmux set-option -t \"".concat(sessionName, "\" history-limit ").concat(fullConfig.historyLimit, " 2>/dev/null"), __assign(__assign({}, sshOptions), { timeout: 5 }))];
|
|
297
|
-
case 4:
|
|
298
|
-
_b.sent();
|
|
299
|
-
return [3 /*break*/, 6];
|
|
300
|
-
case 5:
|
|
301
|
-
_a = _b.sent();
|
|
302
|
-
return [3 /*break*/, 6];
|
|
303
|
-
case 6: return [2 /*return*/, {
|
|
304
|
-
sshArgs: sshArgs,
|
|
305
|
-
sessionName: sessionName,
|
|
306
|
-
newlyCreated: !sessionExists,
|
|
307
|
-
}];
|
|
308
|
-
}
|
|
309
|
-
});
|
|
310
|
-
});
|
|
311
|
-
}
|
|
312
|
-
/**
|
|
313
|
-
* Kill a tmux session on the remote server
|
|
314
|
-
*/
|
|
315
|
-
function killTmuxSession(sessionName, options) {
|
|
316
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
317
|
-
var pool, _a;
|
|
318
|
-
return __generator(this, function (_b) {
|
|
319
|
-
switch (_b.label) {
|
|
320
|
-
case 0:
|
|
321
|
-
pool = (0, pool_js_1.getSSHPool)();
|
|
322
|
-
_b.label = 1;
|
|
323
|
-
case 1:
|
|
324
|
-
_b.trys.push([1, 3, , 4]);
|
|
325
|
-
return [4 /*yield*/, pool.exec("tmux kill-session -t \"".concat(sessionName, "\" 2>/dev/null"), __assign(__assign({}, options), { timeout: 5 }))];
|
|
326
|
-
case 2:
|
|
327
|
-
_b.sent();
|
|
328
|
-
return [2 /*return*/, true];
|
|
329
|
-
case 3:
|
|
330
|
-
_a = _b.sent();
|
|
331
|
-
return [2 /*return*/, false];
|
|
332
|
-
case 4: return [2 /*return*/];
|
|
333
|
-
}
|
|
334
|
-
});
|
|
335
|
-
});
|
|
336
|
-
}
|
|
337
|
-
/**
|
|
338
|
-
* Get tmux session information
|
|
339
|
-
*/
|
|
340
|
-
function getTmuxSessionInfo(sessionName, options) {
|
|
341
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
342
|
-
var pool, result, _a, windows, panes, _b;
|
|
343
|
-
return __generator(this, function (_c) {
|
|
344
|
-
switch (_c.label) {
|
|
345
|
-
case 0:
|
|
346
|
-
pool = (0, pool_js_1.getSSHPool)();
|
|
347
|
-
_c.label = 1;
|
|
348
|
-
case 1:
|
|
349
|
-
_c.trys.push([1, 3, , 4]);
|
|
350
|
-
return [4 /*yield*/, pool.exec("tmux display-message -t \"".concat(sessionName, "\" -p '#{session_windows} #{window_panes}' 2>/dev/null || echo \"\""), __assign(__assign({}, options), { timeout: 5 }))];
|
|
351
|
-
case 2:
|
|
352
|
-
result = _c.sent();
|
|
353
|
-
if (!result || result.trim() === "" || result === "0") {
|
|
354
|
-
return [2 /*return*/, { exists: false }];
|
|
355
|
-
}
|
|
356
|
-
_a = result.trim().split(" ").map(Number), windows = _a[0], panes = _a[1];
|
|
357
|
-
return [2 /*return*/, { exists: true, windows: windows, panes: panes }];
|
|
358
|
-
case 3:
|
|
359
|
-
_b = _c.sent();
|
|
360
|
-
return [2 /*return*/, { exists: false }];
|
|
361
|
-
case 4: return [2 /*return*/];
|
|
362
|
-
}
|
|
363
|
-
});
|
|
364
|
-
});
|
|
365
|
-
}
|
|
366
|
-
/**
|
|
367
|
-
* Cleanup old tmux sessions on a remote server
|
|
368
|
-
* Kills sessions with matching prefix that are older than specified age limit
|
|
369
|
-
* @param options SSH connection options
|
|
370
|
-
* @param config Optional configuration (uses default age limit if not provided)
|
|
371
|
-
* @returns Object with cleaned count and errors
|
|
372
|
-
*/
|
|
373
|
-
function cleanupOldTmuxSessions(options_1) {
|
|
374
|
-
return __awaiter(this, arguments, void 0, function (options, config) {
|
|
375
|
-
var fullConfig, pool, errors, cleaned, sessions, codespacesSessions, _i, codespacesSessions_1, sessionName, ageCheckCmd, ageResult, ageMs, err_1, err_2;
|
|
376
|
-
if (config === void 0) { config = {}; }
|
|
377
|
-
return __generator(this, function (_a) {
|
|
378
|
-
switch (_a.label) {
|
|
379
|
-
case 0:
|
|
380
|
-
fullConfig = __assign(__assign({}, DEFAULT_CONFIG), config);
|
|
381
|
-
pool = (0, pool_js_1.getSSHPool)();
|
|
382
|
-
errors = [];
|
|
383
|
-
cleaned = 0;
|
|
384
|
-
_a.label = 1;
|
|
385
|
-
case 1:
|
|
386
|
-
_a.trys.push([1, 11, , 12]);
|
|
387
|
-
return [4 /*yield*/, listTmuxSessions(options)];
|
|
388
|
-
case 2:
|
|
389
|
-
sessions = _a.sent();
|
|
390
|
-
codespacesSessions = sessions.filter(function (s) { return s.startsWith(fullConfig.sessionPrefix); });
|
|
391
|
-
_i = 0, codespacesSessions_1 = codespacesSessions;
|
|
392
|
-
_a.label = 3;
|
|
393
|
-
case 3:
|
|
394
|
-
if (!(_i < codespacesSessions_1.length)) return [3 /*break*/, 10];
|
|
395
|
-
sessionName = codespacesSessions_1[_i];
|
|
396
|
-
_a.label = 4;
|
|
397
|
-
case 4:
|
|
398
|
-
_a.trys.push([4, 8, , 9]);
|
|
399
|
-
ageCheckCmd = "\n find /tmp -type s -name \"*".concat(sessionName, "*\" 2>/dev/null | head -1 | while read socket; do\n if [ -n \"$socket\" ]; then\n # Get file modification time in seconds since epoch\n mtime=$(stat -c %Y \"$socket\" 2>/dev/null || stat -f %m \"$socket\" 2>/dev/null)\n if [ -n \"$mtime\" ]; then\n now=$(date +%s)\n age=$((now - mtime))\n age_ms=$((age * 1000))\n echo \"$age_ms\"\n fi\n fi\n done\n ");
|
|
400
|
-
return [4 /*yield*/, pool.exec(ageCheckCmd, __assign(__assign({}, options), { timeout: 10 }))];
|
|
401
|
-
case 5:
|
|
402
|
-
ageResult = _a.sent();
|
|
403
|
-
ageMs = parseInt(ageResult.trim());
|
|
404
|
-
if (!(!isNaN(ageMs) && ageMs > fullConfig.sessionAgeLimit)) return [3 /*break*/, 7];
|
|
405
|
-
console.log("[Tmux] Cleaning up old session \"".concat(sessionName, "\" (age: ").concat(Math.round(ageMs / 86400000), " days)"));
|
|
406
|
-
return [4 /*yield*/, killTmuxSession(sessionName, options)];
|
|
407
|
-
case 6:
|
|
408
|
-
_a.sent();
|
|
409
|
-
cleaned++;
|
|
410
|
-
_a.label = 7;
|
|
411
|
-
case 7: return [3 /*break*/, 9];
|
|
412
|
-
case 8:
|
|
413
|
-
err_1 = _a.sent();
|
|
414
|
-
errors.push("".concat(sessionName, ": ").concat(err_1 instanceof Error ? err_1.message : String(err_1)));
|
|
415
|
-
return [3 /*break*/, 9];
|
|
416
|
-
case 9:
|
|
417
|
-
_i++;
|
|
418
|
-
return [3 /*break*/, 3];
|
|
419
|
-
case 10: return [2 /*return*/, { cleaned: cleaned, errors: errors }];
|
|
420
|
-
case 11:
|
|
421
|
-
err_2 = _a.sent();
|
|
422
|
-
errors.push("Cleanup failed: ".concat(err_2 instanceof Error ? err_2.message : String(err_2)));
|
|
423
|
-
return [2 /*return*/, { cleaned: cleaned, errors: errors }];
|
|
424
|
-
case 12: return [2 /*return*/];
|
|
425
|
-
}
|
|
426
|
-
});
|
|
427
|
-
});
|
|
428
|
-
}
|
|
429
|
-
/**
|
|
430
|
-
* Get resource usage information for tmux sessions on a remote server
|
|
431
|
-
* @param options SSH connection options
|
|
432
|
-
* @returns Resource usage summary
|
|
433
|
-
*/
|
|
434
|
-
function getTmuxResourceUsage(options) {
|
|
435
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
436
|
-
var pool, sessions, codespacesSessions, estimatedMemoryMB, _a;
|
|
437
|
-
return __generator(this, function (_b) {
|
|
438
|
-
switch (_b.label) {
|
|
439
|
-
case 0:
|
|
440
|
-
pool = (0, pool_js_1.getSSHPool)();
|
|
441
|
-
_b.label = 1;
|
|
442
|
-
case 1:
|
|
443
|
-
_b.trys.push([1, 3, , 4]);
|
|
444
|
-
return [4 /*yield*/, listTmuxSessions(options)];
|
|
445
|
-
case 2:
|
|
446
|
-
sessions = _b.sent();
|
|
447
|
-
codespacesSessions = sessions.filter(function (s) { return s.startsWith(DEFAULT_CONFIG.sessionPrefix); });
|
|
448
|
-
estimatedMemoryMB = codespacesSessions.length * 11;
|
|
449
|
-
return [2 /*return*/, {
|
|
450
|
-
totalSessions: sessions.length,
|
|
451
|
-
codespacesSessions: codespacesSessions.length,
|
|
452
|
-
estimatedMemoryMB: estimatedMemoryMB,
|
|
453
|
-
}];
|
|
454
|
-
case 3:
|
|
455
|
-
_a = _b.sent();
|
|
456
|
-
return [2 /*return*/, null];
|
|
457
|
-
case 4: return [2 /*return*/];
|
|
458
|
-
}
|
|
459
|
-
});
|
|
460
|
-
});
|
|
461
|
-
}
|
|
462
|
-
/**
|
|
463
|
-
* Send a command to a specific pane in a tmux session
|
|
464
|
-
* @param sessionName Target tmux session name
|
|
465
|
-
* @param paneIndex Pane index (default: 0 for first pane)
|
|
466
|
-
* @param command Command to execute (sent as keystrokes)
|
|
467
|
-
* @param options SSH connection options
|
|
468
|
-
*/
|
|
469
|
-
function sendCommandToPane(sessionName_1, command_1) {
|
|
470
|
-
return __awaiter(this, arguments, void 0, function (sessionName, command, paneIndex, options) {
|
|
471
|
-
var pool, escapedCmd, error_2;
|
|
472
|
-
if (paneIndex === void 0) { paneIndex = "0"; }
|
|
473
|
-
return __generator(this, function (_a) {
|
|
474
|
-
switch (_a.label) {
|
|
475
|
-
case 0:
|
|
476
|
-
pool = (0, pool_js_1.getSSHPool)();
|
|
477
|
-
_a.label = 1;
|
|
478
|
-
case 1:
|
|
479
|
-
_a.trys.push([1, 3, , 4]);
|
|
480
|
-
escapedCmd = command.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
481
|
-
return [4 /*yield*/, pool.exec("tmux send-keys -t \"".concat(sessionName, ":").concat(paneIndex, "\" \"").concat(escapedCmd, "\" Enter"), __assign(__assign({}, options), { timeout: 5 }))];
|
|
482
|
-
case 2:
|
|
483
|
-
_a.sent();
|
|
484
|
-
return [2 /*return*/, true];
|
|
485
|
-
case 3:
|
|
486
|
-
error_2 = _a.sent();
|
|
487
|
-
console.error("[Tmux] Failed to send command to ".concat(sessionName, ":").concat(paneIndex, ":"), error_2);
|
|
488
|
-
return [2 /*return*/, false];
|
|
489
|
-
case 4: return [2 /*return*/];
|
|
490
|
-
}
|
|
491
|
-
});
|
|
492
|
-
});
|
|
493
|
-
}
|
|
494
|
-
/**
|
|
495
|
-
* Split a pane horizontally or vertically in a tmux session
|
|
496
|
-
* @param sessionName Target tmux session name
|
|
497
|
-
* @param windowIndex Window index (default: 0)
|
|
498
|
-
* @param direction Split direction: "h" (horizontal) or "v" (vertical)
|
|
499
|
-
* @param command Optional command to run in the new pane
|
|
500
|
-
* @param options SSH connection options
|
|
501
|
-
* @returns The new pane index
|
|
502
|
-
*/
|
|
503
|
-
function splitPane(sessionName_1) {
|
|
504
|
-
return __awaiter(this, arguments, void 0, function (sessionName, direction, command, options) {
|
|
505
|
-
var pool, splitCmd, result, error_3;
|
|
506
|
-
if (direction === void 0) { direction = "v"; }
|
|
507
|
-
if (command === void 0) { command = null; }
|
|
508
|
-
return __generator(this, function (_a) {
|
|
509
|
-
switch (_a.label) {
|
|
510
|
-
case 0:
|
|
511
|
-
pool = (0, pool_js_1.getSSHPool)();
|
|
512
|
-
_a.label = 1;
|
|
513
|
-
case 1:
|
|
514
|
-
_a.trys.push([1, 3, , 4]);
|
|
515
|
-
splitCmd = command
|
|
516
|
-
? "tmux split-window -".concat(direction, " -t \"").concat(sessionName, "\" -c \"#{pane_current_path}\" \"").concat(command, "\"")
|
|
517
|
-
: "tmux split-window -".concat(direction, " -t \"").concat(sessionName, "\"");
|
|
518
|
-
return [4 /*yield*/, pool.exec(splitCmd, __assign(__assign({}, options), { timeout: 10 }))];
|
|
519
|
-
case 2:
|
|
520
|
-
result = _a.sent();
|
|
521
|
-
// Return the result which contains the new pane ID
|
|
522
|
-
return [2 /*return*/, (result === null || result === void 0 ? void 0 : result.trim()) || null];
|
|
523
|
-
case 3:
|
|
524
|
-
error_3 = _a.sent();
|
|
525
|
-
console.error("[Tmux] Failed to split pane in ".concat(sessionName, ":"), error_3);
|
|
526
|
-
return [2 /*return*/, null];
|
|
527
|
-
case 4: return [2 /*return*/];
|
|
528
|
-
}
|
|
529
|
-
});
|
|
530
|
-
});
|
|
531
|
-
}
|
|
532
|
-
/**
|
|
533
|
-
* List all windows in a tmux session
|
|
534
|
-
* @param sessionName Target tmux session name
|
|
535
|
-
* @param options SSH connection options
|
|
536
|
-
*/
|
|
537
|
-
function listSessionWindows(sessionName, options) {
|
|
538
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
539
|
-
var pool, result, _a;
|
|
540
|
-
return __generator(this, function (_b) {
|
|
541
|
-
switch (_b.label) {
|
|
542
|
-
case 0:
|
|
543
|
-
pool = (0, pool_js_1.getSSHPool)();
|
|
544
|
-
_b.label = 1;
|
|
545
|
-
case 1:
|
|
546
|
-
_b.trys.push([1, 3, , 4]);
|
|
547
|
-
return [4 /*yield*/, pool.exec("tmux list-windows -t \"".concat(sessionName, "\" -F '#{window_index} #{window_name} #{window_active}' 2>/dev/null || echo ''"), __assign(__assign({}, options), { timeout: 5 }))];
|
|
548
|
-
case 2:
|
|
549
|
-
result = _b.sent();
|
|
550
|
-
if (!result || result.trim() === "" || result === "0") {
|
|
551
|
-
return [2 /*return*/, []];
|
|
552
|
-
}
|
|
553
|
-
return [2 /*return*/, result.trim().split("\n").map(function (line) {
|
|
554
|
-
var _a = line.split(" "), index = _a[0], name = _a[1], active = _a[2];
|
|
555
|
-
return { index: index, name: name, active: active === "1" };
|
|
556
|
-
})];
|
|
557
|
-
case 3:
|
|
558
|
-
_a = _b.sent();
|
|
559
|
-
return [2 /*return*/, []];
|
|
560
|
-
case 4: return [2 /*return*/];
|
|
561
|
-
}
|
|
562
|
-
});
|
|
563
|
-
});
|
|
564
|
-
}
|
|
565
|
-
/**
|
|
566
|
-
* List all panes in a tmux session window
|
|
567
|
-
* @param sessionName Target tmux session name
|
|
568
|
-
* @param windowIndex Window index (default: 0)
|
|
569
|
-
* @param options SSH connection options
|
|
570
|
-
*/
|
|
571
|
-
function listWindowPanes(sessionName_1) {
|
|
572
|
-
return __awaiter(this, arguments, void 0, function (sessionName, windowIndex, options) {
|
|
573
|
-
var pool, result, _a;
|
|
574
|
-
if (windowIndex === void 0) { windowIndex = "0"; }
|
|
575
|
-
return __generator(this, function (_b) {
|
|
576
|
-
switch (_b.label) {
|
|
577
|
-
case 0:
|
|
578
|
-
pool = (0, pool_js_1.getSSHPool)();
|
|
579
|
-
_b.label = 1;
|
|
580
|
-
case 1:
|
|
581
|
-
_b.trys.push([1, 3, , 4]);
|
|
582
|
-
return [4 /*yield*/, pool.exec("tmux list-panes -t \"".concat(sessionName, ":").concat(windowIndex, "\" -F '#{pane_index} #{pane_current_path} #{pane_pid} #{pane_active}' 2>/dev/null || echo ''"), __assign(__assign({}, options), { timeout: 5 }))];
|
|
583
|
-
case 2:
|
|
584
|
-
result = _b.sent();
|
|
585
|
-
if (!result || result.trim() === "" || result === "0") {
|
|
586
|
-
return [2 /*return*/, []];
|
|
587
|
-
}
|
|
588
|
-
return [2 /*return*/, result.trim().split("\n").map(function (line) {
|
|
589
|
-
var _a = line.split(" "), index = _a[0], currentPath = _a[1], pid = _a[2], active = _a[3];
|
|
590
|
-
return { index: index, currentPath: currentPath, pid: pid, active: active === "1" };
|
|
591
|
-
})];
|
|
592
|
-
case 3:
|
|
593
|
-
_a = _b.sent();
|
|
594
|
-
return [2 /*return*/, []];
|
|
595
|
-
case 4: return [2 /*return*/];
|
|
596
|
-
}
|
|
597
|
-
});
|
|
598
|
-
});
|
|
599
|
-
}
|
|
600
|
-
/**
|
|
601
|
-
* Capture the current output of a pane
|
|
602
|
-
* @param sessionName Target tmux session name
|
|
603
|
-
* @param paneIndex Pane index (default: 0)
|
|
604
|
-
* @param options SSH connection options
|
|
605
|
-
*/
|
|
606
|
-
function capturePane(sessionName_1) {
|
|
607
|
-
return __awaiter(this, arguments, void 0, function (sessionName, paneIndex, options) {
|
|
608
|
-
var pool, result, error_4;
|
|
609
|
-
if (paneIndex === void 0) { paneIndex = "0"; }
|
|
610
|
-
return __generator(this, function (_a) {
|
|
611
|
-
switch (_a.label) {
|
|
612
|
-
case 0:
|
|
613
|
-
pool = (0, pool_js_1.getSSHPool)();
|
|
614
|
-
_a.label = 1;
|
|
615
|
-
case 1:
|
|
616
|
-
_a.trys.push([1, 3, , 4]);
|
|
617
|
-
return [4 /*yield*/, pool.exec("tmux capture-pane -t \"".concat(sessionName, ":").concat(paneIndex, "\" -p"), __assign(__assign({}, options), { timeout: 5 }))];
|
|
618
|
-
case 2:
|
|
619
|
-
result = _a.sent();
|
|
620
|
-
return [2 /*return*/, result || null];
|
|
621
|
-
case 3:
|
|
622
|
-
error_4 = _a.sent();
|
|
623
|
-
console.error("[Tmux] Failed to capture pane ".concat(sessionName, ":").concat(paneIndex, ":"), error_4);
|
|
624
|
-
return [2 /*return*/, null];
|
|
625
|
-
case 4: return [2 /*return*/];
|
|
626
|
-
}
|
|
627
|
-
});
|
|
628
|
-
});
|
|
629
|
-
}
|
|
630
|
-
/**
|
|
631
|
-
* Get scrollback/history from a pane
|
|
632
|
-
* @param sessionName Target tmux session name
|
|
633
|
-
* @param paneIndex Pane index (default: 0)
|
|
634
|
-
* @param lines Number of lines to retrieve (default: all)
|
|
635
|
-
* @param options SSH connection options
|
|
636
|
-
*/
|
|
637
|
-
function getPaneHistory(sessionName_1) {
|
|
638
|
-
return __awaiter(this, arguments, void 0, function (sessionName, paneIndex, lines, options) {
|
|
639
|
-
var pool, linesArg, result, error_5;
|
|
640
|
-
if (paneIndex === void 0) { paneIndex = "0"; }
|
|
641
|
-
if (lines === void 0) { lines = -1; }
|
|
642
|
-
return __generator(this, function (_a) {
|
|
643
|
-
switch (_a.label) {
|
|
644
|
-
case 0:
|
|
645
|
-
pool = (0, pool_js_1.getSSHPool)();
|
|
646
|
-
_a.label = 1;
|
|
647
|
-
case 1:
|
|
648
|
-
_a.trys.push([1, 3, , 4]);
|
|
649
|
-
linesArg = lines > 0 ? "-S -".concat(lines) : "-S -";
|
|
650
|
-
return [4 /*yield*/, pool.exec("tmux capture-pane ".concat(linesArg, " -t \"").concat(sessionName, ":").concat(paneIndex, "\" -p"), __assign(__assign({}, options), { timeout: 10 }))];
|
|
651
|
-
case 2:
|
|
652
|
-
result = _a.sent();
|
|
653
|
-
return [2 /*return*/, result || null];
|
|
654
|
-
case 3:
|
|
655
|
-
error_5 = _a.sent();
|
|
656
|
-
console.error("[Tmux] Failed to get history for ".concat(sessionName, ":").concat(paneIndex, ":"), error_5);
|
|
657
|
-
return [2 /*return*/, null];
|
|
658
|
-
case 4: return [2 /*return*/];
|
|
659
|
-
}
|
|
660
|
-
});
|
|
661
|
-
});
|
|
662
|
-
}
|
|
663
|
-
/**
|
|
664
|
-
* Switch to a specific window in a tmux session
|
|
665
|
-
* @param sessionName Target tmux session name
|
|
666
|
-
* @param windowIndex Target window index
|
|
667
|
-
* @param options SSH connection options
|
|
668
|
-
*/
|
|
669
|
-
function switchWindow(sessionName, windowIndex, options) {
|
|
670
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
671
|
-
var pool, _a;
|
|
672
|
-
return __generator(this, function (_b) {
|
|
673
|
-
switch (_b.label) {
|
|
674
|
-
case 0:
|
|
675
|
-
pool = (0, pool_js_1.getSSHPool)();
|
|
676
|
-
_b.label = 1;
|
|
677
|
-
case 1:
|
|
678
|
-
_b.trys.push([1, 3, , 4]);
|
|
679
|
-
return [4 /*yield*/, pool.exec("tmux select-window -t \"".concat(sessionName, ":").concat(windowIndex, "\""), __assign(__assign({}, options), { timeout: 5 }))];
|
|
680
|
-
case 2:
|
|
681
|
-
_b.sent();
|
|
682
|
-
return [2 /*return*/, true];
|
|
683
|
-
case 3:
|
|
684
|
-
_a = _b.sent();
|
|
685
|
-
return [2 /*return*/, false];
|
|
686
|
-
case 4: return [2 /*return*/];
|
|
687
|
-
}
|
|
688
|
-
});
|
|
689
|
-
});
|
|
690
|
-
}
|
|
691
|
-
/**
|
|
692
|
-
* Switch to a specific pane in a tmux session window
|
|
693
|
-
* @param sessionName Target tmux session name
|
|
694
|
-
* @param paneIndex Target pane index (e.g., "0", "1", "0.1" for window.pane)
|
|
695
|
-
* @param options SSH connection options
|
|
696
|
-
*/
|
|
697
|
-
function switchPane(sessionName, paneIndex, options) {
|
|
698
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
699
|
-
var pool, _a;
|
|
700
|
-
return __generator(this, function (_b) {
|
|
701
|
-
switch (_b.label) {
|
|
702
|
-
case 0:
|
|
703
|
-
pool = (0, pool_js_1.getSSHPool)();
|
|
704
|
-
_b.label = 1;
|
|
705
|
-
case 1:
|
|
706
|
-
_b.trys.push([1, 3, , 4]);
|
|
707
|
-
return [4 /*yield*/, pool.exec("tmux select-pane -t \"".concat(sessionName, ":").concat(paneIndex, "\""), __assign(__assign({}, options), { timeout: 5 }))];
|
|
708
|
-
case 2:
|
|
709
|
-
_b.sent();
|
|
710
|
-
return [2 /*return*/, true];
|
|
711
|
-
case 3:
|
|
712
|
-
_a = _b.sent();
|
|
713
|
-
return [2 /*return*/, false];
|
|
714
|
-
case 4: return [2 /*return*/];
|
|
715
|
-
}
|
|
716
|
-
});
|
|
717
|
-
});
|
|
718
|
-
}
|
|
719
|
-
/**
|
|
720
|
-
* Rename a window in a tmux session
|
|
721
|
-
* @param sessionName Target tmux session name
|
|
722
|
-
* @param windowIndex Window index (default: 0)
|
|
723
|
-
* @param newName New window name
|
|
724
|
-
* @param options SSH connection options
|
|
725
|
-
*/
|
|
726
|
-
function renameWindow(sessionName, windowIndex, newName, options) {
|
|
727
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
728
|
-
var pool, _a;
|
|
729
|
-
return __generator(this, function (_b) {
|
|
730
|
-
switch (_b.label) {
|
|
731
|
-
case 0:
|
|
732
|
-
pool = (0, pool_js_1.getSSHPool)();
|
|
733
|
-
_b.label = 1;
|
|
734
|
-
case 1:
|
|
735
|
-
_b.trys.push([1, 3, , 4]);
|
|
736
|
-
return [4 /*yield*/, pool.exec("tmux rename-window -t \"".concat(sessionName, ":").concat(windowIndex, "\" \"").concat(newName, "\""), __assign(__assign({}, options), { timeout: 5 }))];
|
|
737
|
-
case 2:
|
|
738
|
-
_b.sent();
|
|
739
|
-
return [2 /*return*/, true];
|
|
740
|
-
case 3:
|
|
741
|
-
_a = _b.sent();
|
|
742
|
-
return [2 /*return*/, false];
|
|
743
|
-
case 4: return [2 /*return*/];
|
|
744
|
-
}
|
|
745
|
-
});
|
|
746
|
-
});
|
|
747
|
-
}
|
|
748
|
-
/**
|
|
749
|
-
* Kill a specific pane in a tmux session
|
|
750
|
-
* @param sessionName Target tmux session name
|
|
751
|
-
* @param paneIndex Pane index to kill
|
|
752
|
-
* @param options SSH connection options
|
|
753
|
-
*/
|
|
754
|
-
function killPane(sessionName, paneIndex, options) {
|
|
755
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
756
|
-
var pool, _a;
|
|
757
|
-
return __generator(this, function (_b) {
|
|
758
|
-
switch (_b.label) {
|
|
759
|
-
case 0:
|
|
760
|
-
pool = (0, pool_js_1.getSSHPool)();
|
|
761
|
-
_b.label = 1;
|
|
762
|
-
case 1:
|
|
763
|
-
_b.trys.push([1, 3, , 4]);
|
|
764
|
-
return [4 /*yield*/, pool.exec("tmux kill-pane -t \"".concat(sessionName, ":").concat(paneIndex, "\""), __assign(__assign({}, options), { timeout: 5 }))];
|
|
765
|
-
case 2:
|
|
766
|
-
_b.sent();
|
|
767
|
-
return [2 /*return*/, true];
|
|
768
|
-
case 3:
|
|
769
|
-
_a = _b.sent();
|
|
770
|
-
return [2 /*return*/, false];
|
|
771
|
-
case 4: return [2 /*return*/];
|
|
772
|
-
}
|
|
773
|
-
});
|
|
774
|
-
});
|
|
775
|
-
}
|
|
776
|
-
/**
|
|
777
|
-
* Get detailed information about all panes in a session
|
|
778
|
-
* @param sessionName Target tmux session name
|
|
779
|
-
* @param options SSH connection options
|
|
780
|
-
*/
|
|
781
|
-
function getDetailedSessionInfo(sessionName, options) {
|
|
782
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
783
|
-
var pool, exists, windows, windowsWithPanes, error_6;
|
|
784
|
-
var _this = this;
|
|
785
|
-
return __generator(this, function (_a) {
|
|
786
|
-
switch (_a.label) {
|
|
787
|
-
case 0:
|
|
788
|
-
pool = (0, pool_js_1.getSSHPool)();
|
|
789
|
-
_a.label = 1;
|
|
790
|
-
case 1:
|
|
791
|
-
_a.trys.push([1, 5, , 6]);
|
|
792
|
-
return [4 /*yield*/, hasTmuxSession(sessionName, options)];
|
|
793
|
-
case 2:
|
|
794
|
-
exists = _a.sent();
|
|
795
|
-
if (!exists) {
|
|
796
|
-
return [2 /*return*/, { exists: false, windows: [] }];
|
|
797
|
-
}
|
|
798
|
-
return [4 /*yield*/, listSessionWindows(sessionName, options)];
|
|
799
|
-
case 3:
|
|
800
|
-
windows = _a.sent();
|
|
801
|
-
return [4 /*yield*/, Promise.all(windows.map(function (window) { return __awaiter(_this, void 0, void 0, function () {
|
|
802
|
-
var panes;
|
|
803
|
-
return __generator(this, function (_a) {
|
|
804
|
-
switch (_a.label) {
|
|
805
|
-
case 0: return [4 /*yield*/, listWindowPanes(sessionName, window.index, options)];
|
|
806
|
-
case 1:
|
|
807
|
-
panes = _a.sent();
|
|
808
|
-
return [2 /*return*/, __assign(__assign({}, window), { panes: panes })];
|
|
809
|
-
}
|
|
810
|
-
});
|
|
811
|
-
}); }))];
|
|
812
|
-
case 4:
|
|
813
|
-
windowsWithPanes = _a.sent();
|
|
814
|
-
return [2 /*return*/, {
|
|
815
|
-
exists: true,
|
|
816
|
-
windows: windowsWithPanes,
|
|
817
|
-
}];
|
|
818
|
-
case 5:
|
|
819
|
-
error_6 = _a.sent();
|
|
820
|
-
console.error("[Tmux] Failed to get detailed info for ".concat(sessionName, ":"), error_6);
|
|
821
|
-
return [2 /*return*/, null];
|
|
822
|
-
case 6: return [2 /*return*/];
|
|
823
|
-
}
|
|
824
|
-
});
|
|
825
|
-
});
|
|
826
|
-
}
|