@ebowwa/terminal 0.3.0 → 0.3.1

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.
Files changed (50) hide show
  1. package/dist/api.d.ts +7 -0
  2. package/dist/client.d.ts +14 -0
  3. package/dist/config.d.ts +85 -0
  4. package/dist/error.d.ts +7 -0
  5. package/dist/exec.d.ts +46 -0
  6. package/dist/files.d.ts +123 -0
  7. package/dist/fingerprint.d.ts +66 -0
  8. package/dist/index.d.ts +20 -0
  9. package/dist/index.js +5722 -6207
  10. package/dist/manager.d.ts +102 -0
  11. package/dist/mcp/index.d.ts +8 -0
  12. package/dist/mcp/index.js +6160 -6717
  13. package/dist/mcp/stdio.d.ts +8 -0
  14. package/dist/network-error-detector.d.ts +18 -0
  15. package/dist/pool.d.ts +142 -0
  16. package/dist/pty.d.ts +58 -0
  17. package/dist/resources.d.ts +62 -0
  18. package/dist/scp.d.ts +29 -0
  19. package/dist/sessions.d.ts +100 -0
  20. package/dist/tmux-exec.d.ts +49 -0
  21. package/dist/tmux-local.d.ts +272 -0
  22. package/dist/tmux-manager.d.ts +327 -0
  23. package/dist/tmux.d.ts +212 -0
  24. package/dist/types.d.ts +17 -0
  25. package/mcp/package.json +1 -1
  26. package/package.json +7 -7
  27. package/src/api.js +861 -0
  28. package/src/client.js +92 -0
  29. package/src/config.js +490 -0
  30. package/src/error.js +32 -0
  31. package/src/exec.js +183 -0
  32. package/src/files.js +521 -0
  33. package/src/fingerprint.js +336 -0
  34. package/src/index.js +127 -0
  35. package/src/manager.js +358 -0
  36. package/src/mcp/index.js +555 -0
  37. package/src/mcp/stdio.js +840 -0
  38. package/src/network-error-detector.js +101 -0
  39. package/src/pool.js +840 -0
  40. package/src/pty.js +344 -0
  41. package/src/resources.js +64 -0
  42. package/src/scp.js +166 -0
  43. package/src/sessions.js +895 -0
  44. package/src/tmux-exec.js +169 -0
  45. package/src/tmux-local.js +937 -0
  46. package/src/tmux-manager.js +1026 -0
  47. package/src/tmux.js +826 -0
  48. package/src/tmux.ts +1 -1
  49. package/src/types.js +5 -0
  50. package/tsconfig.json +28 -0
package/src/api.js ADDED
@@ -0,0 +1,861 @@
1
+ "use strict";
2
+ /**
3
+ * API routes for Multi-Node Tmux Session Manager
4
+ * Provides REST API for managing tmux sessions across multiple VPS nodes
5
+ */
6
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
7
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
8
+ return new (P || (P = Promise))(function (resolve, reject) {
9
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
10
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
11
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
12
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
13
+ });
14
+ };
15
+ var __generator = (this && this.__generator) || function (thisArg, body) {
16
+ 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);
17
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
18
+ function verb(n) { return function (v) { return step([n, v]); }; }
19
+ function step(op) {
20
+ if (f) throw new TypeError("Generator is already executing.");
21
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
22
+ 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;
23
+ if (y = 0, t) op = [op[0] & 2, t.value];
24
+ switch (op[0]) {
25
+ case 0: case 1: t = op; break;
26
+ case 4: _.label++; return { value: op[1], done: false };
27
+ case 5: _.label++; y = op[1]; op = [0]; continue;
28
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
29
+ default:
30
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
31
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
32
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
33
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
34
+ if (t[2]) _.ops.pop();
35
+ _.trys.pop(); continue;
36
+ }
37
+ op = body.call(thisArg, _);
38
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
39
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
40
+ }
41
+ };
42
+ Object.defineProperty(exports, "__esModule", { value: true });
43
+ exports.tmuxApi = void 0;
44
+ var hono_1 = require("hono");
45
+ var activities_1 = require("../lib/activities");
46
+ var tmux_manager_js_1 = require("./tmux-manager.js");
47
+ var api_1 = require("@ebowwa/codespaces-types/runtime/api");
48
+ var tmuxApi = new hono_1.Hono();
49
+ exports.tmuxApi = tmuxApi;
50
+ /**
51
+ * Helper function to validate request body against Zod schema
52
+ */
53
+ function validateRequest(schema, data) {
54
+ try {
55
+ var result = schema.safeParse(data);
56
+ if (result.success) {
57
+ return { success: true, data: result.data };
58
+ }
59
+ else {
60
+ return {
61
+ success: false,
62
+ error: result.error.issues
63
+ .map(function (e) { return "".concat(e.path.join("."), ": ").concat(e.message); })
64
+ .join(", "),
65
+ };
66
+ }
67
+ }
68
+ catch (error) {
69
+ return { success: false, error: String(error) };
70
+ }
71
+ }
72
+ // ============================================
73
+ // Node Management
74
+ // ============================================
75
+ /**
76
+ * POST /api/tmux/manager/nodes - Add a node to the manager
77
+ */
78
+ tmuxApi.post("/manager/nodes", function (c) { return __awaiter(void 0, void 0, void 0, function () {
79
+ var body, validation, manager;
80
+ return __generator(this, function (_a) {
81
+ switch (_a.label) {
82
+ case 0: return [4 /*yield*/, c.req.json()];
83
+ case 1:
84
+ body = _a.sent();
85
+ validation = validateRequest(api_1.TmuxManagerAddNodeSchema, body);
86
+ if (!validation.success) {
87
+ return [2 /*return*/, c.json({ success: false, error: validation.error }, 400)];
88
+ }
89
+ try {
90
+ manager = (0, tmux_manager_js_1.getTmuxManager)();
91
+ manager.addNode(validation.data);
92
+ return [2 /*return*/, c.json({ success: true, node: validation.data })];
93
+ }
94
+ catch (error) {
95
+ return [2 /*return*/, c.json({ success: false, error: String(error) }, 500)];
96
+ }
97
+ return [2 /*return*/];
98
+ }
99
+ });
100
+ }); });
101
+ /**
102
+ * GET /api/tmux/manager/nodes - List all nodes
103
+ */
104
+ tmuxApi.get("/manager/nodes", function (c) { return __awaiter(void 0, void 0, void 0, function () {
105
+ var manager, nodes;
106
+ return __generator(this, function (_a) {
107
+ try {
108
+ manager = (0, tmux_manager_js_1.getTmuxManager)();
109
+ nodes = manager.getAllNodes();
110
+ return [2 /*return*/, c.json({ success: true, nodes: nodes })];
111
+ }
112
+ catch (error) {
113
+ return [2 /*return*/, c.json({ success: false, error: String(error) }, 500)];
114
+ }
115
+ return [2 /*return*/];
116
+ });
117
+ }); });
118
+ /**
119
+ * GET /api/tmux/manager/nodes/:id - Get a specific node
120
+ */
121
+ tmuxApi.get("/manager/nodes/:id", function (c) { return __awaiter(void 0, void 0, void 0, function () {
122
+ var id, manager, node;
123
+ return __generator(this, function (_a) {
124
+ id = c.req.param("id");
125
+ if (!id) {
126
+ return [2 /*return*/, c.json({ success: false, error: "Node ID is required" }, 400)];
127
+ }
128
+ try {
129
+ manager = (0, tmux_manager_js_1.getTmuxManager)();
130
+ node = manager.getNode(id);
131
+ if (!node) {
132
+ return [2 /*return*/, c.json({ success: false, error: "Node not found" }, 404)];
133
+ }
134
+ return [2 /*return*/, c.json({ success: true, node: node })];
135
+ }
136
+ catch (error) {
137
+ return [2 /*return*/, c.json({ success: false, error: String(error) }, 500)];
138
+ }
139
+ return [2 /*return*/];
140
+ });
141
+ }); });
142
+ /**
143
+ * DELETE /api/tmux/manager/nodes/:id - Remove a node
144
+ */
145
+ tmuxApi.delete("/manager/nodes/:id", function (c) { return __awaiter(void 0, void 0, void 0, function () {
146
+ var id, manager, node;
147
+ return __generator(this, function (_a) {
148
+ id = c.req.param("id");
149
+ if (!id) {
150
+ return [2 /*return*/, c.json({ success: false, error: "Node ID is required" }, 400)];
151
+ }
152
+ try {
153
+ manager = (0, tmux_manager_js_1.getTmuxManager)();
154
+ node = manager.getNode(id);
155
+ if (!node) {
156
+ return [2 /*return*/, c.json({ success: false, error: "Node not found" }, 404)];
157
+ }
158
+ manager.removeNode(id);
159
+ return [2 /*return*/, c.json({ success: true })];
160
+ }
161
+ catch (error) {
162
+ return [2 /*return*/, c.json({ success: false, error: String(error) }, 500)];
163
+ }
164
+ return [2 /*return*/];
165
+ });
166
+ }); });
167
+ // ============================================
168
+ // Session Management
169
+ // ============================================
170
+ /**
171
+ * POST /api/tmux/manager/sessions - Create a new session
172
+ */
173
+ tmuxApi.post("/manager/sessions", function (c) { return __awaiter(void 0, void 0, void 0, function () {
174
+ var body, validation, manager, result, node, error_1;
175
+ return __generator(this, function (_a) {
176
+ switch (_a.label) {
177
+ case 0: return [4 /*yield*/, c.req.json()];
178
+ case 1:
179
+ body = _a.sent();
180
+ validation = validateRequest(api_1.TmuxManagerCreateSessionSchema, body);
181
+ if (!validation.success) {
182
+ return [2 /*return*/, c.json({ success: false, error: validation.error }, 400)];
183
+ }
184
+ _a.label = 2;
185
+ case 2:
186
+ _a.trys.push([2, 4, , 5]);
187
+ manager = (0, tmux_manager_js_1.getTmuxManager)();
188
+ return [4 /*yield*/, manager.createSession(validation.data.nodeId, validation.data)];
189
+ case 3:
190
+ result = _a.sent();
191
+ if (result.success) {
192
+ node = manager.getNode(validation.data.nodeId);
193
+ if (node) {
194
+ (0, activities_1.addActivity)({
195
+ environmentId: node.id,
196
+ action: "tmux_session_created",
197
+ environmentName: node.name,
198
+ details: result.sessionName
199
+ ? "Session \"".concat(result.sessionName, "\" created")
200
+ : "Session created",
201
+ });
202
+ }
203
+ }
204
+ return [2 /*return*/, c.json(result)];
205
+ case 4:
206
+ error_1 = _a.sent();
207
+ return [2 /*return*/, c.json({ success: false, error: String(error_1) }, 500)];
208
+ case 5: return [2 /*return*/];
209
+ }
210
+ });
211
+ }); });
212
+ /**
213
+ * GET /api/tmux/manager/sessions - List all sessions
214
+ */
215
+ tmuxApi.get("/manager/sessions", function (c) { return __awaiter(void 0, void 0, void 0, function () {
216
+ var manager, nodeIds, tags, detailed, includeInactive, sessions, error_2;
217
+ return __generator(this, function (_a) {
218
+ switch (_a.label) {
219
+ case 0:
220
+ _a.trys.push([0, 2, , 3]);
221
+ manager = (0, tmux_manager_js_1.getTmuxManager)();
222
+ nodeIds = c.req.queries()["nodeIds"];
223
+ tags = c.req.queries()["tags"];
224
+ detailed = c.req.query("detailed") === "true";
225
+ includeInactive = c.req.query("includeInactive") === "true";
226
+ return [4 /*yield*/, manager.listSessions({
227
+ nodeIds: nodeIds,
228
+ tags: tags,
229
+ detailed: detailed,
230
+ includeInactive: includeInactive,
231
+ })];
232
+ case 1:
233
+ sessions = _a.sent();
234
+ return [2 /*return*/, c.json({ success: true, sessions: sessions })];
235
+ case 2:
236
+ error_2 = _a.sent();
237
+ return [2 /*return*/, c.json({ success: false, error: String(error_2) }, 500)];
238
+ case 3: return [2 /*return*/];
239
+ }
240
+ });
241
+ }); });
242
+ /**
243
+ * POST /api/tmux/manager/sessions/attach - Attach to a session
244
+ */
245
+ tmuxApi.post("/manager/sessions/attach", function (c) { return __awaiter(void 0, void 0, void 0, function () {
246
+ var body, validation, manager, result, node, error_3;
247
+ return __generator(this, function (_a) {
248
+ switch (_a.label) {
249
+ case 0: return [4 /*yield*/, c.req.json()];
250
+ case 1:
251
+ body = _a.sent();
252
+ validation = validateRequest(api_1.TmuxManagerAttachSessionSchema, body);
253
+ if (!validation.success) {
254
+ return [2 /*return*/, c.json({ success: false, error: validation.error }, 400)];
255
+ }
256
+ _a.label = 2;
257
+ case 2:
258
+ _a.trys.push([2, 4, , 5]);
259
+ manager = (0, tmux_manager_js_1.getTmuxManager)();
260
+ return [4 /*yield*/, manager.attachSession(validation.data.nodeId, validation.data.sessionName)];
261
+ case 3:
262
+ result = _a.sent();
263
+ if (result.success) {
264
+ node = manager.getNode(validation.data.nodeId);
265
+ if (node) {
266
+ (0, activities_1.addActivity)({
267
+ environmentId: node.id,
268
+ action: "tmux_session_attached",
269
+ environmentName: node.name,
270
+ details: "Attached to session \"".concat(result.sessionName, "\""),
271
+ });
272
+ }
273
+ }
274
+ return [2 /*return*/, c.json(result)];
275
+ case 4:
276
+ error_3 = _a.sent();
277
+ return [2 /*return*/, c.json({ success: false, error: String(error_3) }, 500)];
278
+ case 5: return [2 /*return*/];
279
+ }
280
+ });
281
+ }); });
282
+ /**
283
+ * DELETE /api/tmux/manager/sessions - Kill a session
284
+ */
285
+ tmuxApi.delete("/manager/sessions", function (c) { return __awaiter(void 0, void 0, void 0, function () {
286
+ var body, validation, manager, node, result, error_4;
287
+ return __generator(this, function (_a) {
288
+ switch (_a.label) {
289
+ case 0: return [4 /*yield*/, c.req.json()];
290
+ case 1:
291
+ body = _a.sent();
292
+ validation = validateRequest(api_1.TmuxManagerKillSessionSchema, body);
293
+ if (!validation.success) {
294
+ return [2 /*return*/, c.json({ success: false, error: validation.error }, 400)];
295
+ }
296
+ _a.label = 2;
297
+ case 2:
298
+ _a.trys.push([2, 4, , 5]);
299
+ manager = (0, tmux_manager_js_1.getTmuxManager)();
300
+ node = manager.getNode(validation.data.nodeId);
301
+ return [4 /*yield*/, manager.killSession(validation.data.nodeId, validation.data.sessionName)];
302
+ case 3:
303
+ result = _a.sent();
304
+ if (result.success && node) {
305
+ (0, activities_1.addActivity)({
306
+ environmentId: node.id,
307
+ action: "tmux_session_killed",
308
+ environmentName: node.name,
309
+ details: "Session \"".concat(validation.data.sessionName, "\" killed"),
310
+ });
311
+ }
312
+ return [2 /*return*/, c.json(result)];
313
+ case 4:
314
+ error_4 = _a.sent();
315
+ return [2 /*return*/, c.json({ success: false, error: String(error_4) }, 500)];
316
+ case 5: return [2 /*return*/];
317
+ }
318
+ });
319
+ }); });
320
+ // ============================================
321
+ // Command Execution
322
+ // ============================================
323
+ /**
324
+ * POST /api/tmux/manager/sessions/command - Send command to a session
325
+ */
326
+ tmuxApi.post("/manager/sessions/command", function (c) { return __awaiter(void 0, void 0, void 0, function () {
327
+ var body, validation, manager, node, result, error_5;
328
+ return __generator(this, function (_a) {
329
+ switch (_a.label) {
330
+ case 0: return [4 /*yield*/, c.req.json()];
331
+ case 1:
332
+ body = _a.sent();
333
+ validation = validateRequest(api_1.TmuxManagerSendCommandSchema, body);
334
+ if (!validation.success) {
335
+ return [2 /*return*/, c.json({ success: false, error: validation.error }, 400)];
336
+ }
337
+ _a.label = 2;
338
+ case 2:
339
+ _a.trys.push([2, 4, , 5]);
340
+ manager = (0, tmux_manager_js_1.getTmuxManager)();
341
+ node = manager.getNode(validation.data.nodeId);
342
+ return [4 /*yield*/, manager.sendCommand(validation.data.nodeId, validation.data.sessionName, validation.data.command, validation.data.paneIndex)];
343
+ case 3:
344
+ result = _a.sent();
345
+ if (result.success && node) {
346
+ (0, activities_1.addActivity)({
347
+ environmentId: node.id,
348
+ action: "tmux_command_sent",
349
+ environmentName: node.name,
350
+ details: "Command: ".concat(validation.data.command.slice(0, 100)).concat(validation.data.command.length > 100 ? "..." : ""),
351
+ });
352
+ }
353
+ return [2 /*return*/, c.json(result)];
354
+ case 4:
355
+ error_5 = _a.sent();
356
+ return [2 /*return*/, c.json({ success: false, error: String(error_5) }, 500)];
357
+ case 5: return [2 /*return*/];
358
+ }
359
+ });
360
+ }); });
361
+ /**
362
+ * POST /api/tmux/manager/sessions/command/batch - Send command to multiple nodes
363
+ */
364
+ tmuxApi.post("/manager/sessions/command/batch", function (c) { return __awaiter(void 0, void 0, void 0, function () {
365
+ var body, validation, manager, result, _i, _a, r, node, error_6;
366
+ return __generator(this, function (_b) {
367
+ switch (_b.label) {
368
+ case 0: return [4 /*yield*/, c.req.json()];
369
+ case 1:
370
+ body = _b.sent();
371
+ validation = validateRequest(api_1.TmuxManagerBatchSendCommandSchema, body);
372
+ if (!validation.success) {
373
+ return [2 /*return*/, c.json({ success: false, error: validation.error }, 400)];
374
+ }
375
+ _b.label = 2;
376
+ case 2:
377
+ _b.trys.push([2, 4, , 5]);
378
+ manager = (0, tmux_manager_js_1.getTmuxManager)();
379
+ return [4 /*yield*/, manager.sendCommandToNodes(validation.data.nodeIds, validation.data.sessionName, validation.data.command, {
380
+ paneIndex: validation.data.paneIndex,
381
+ parallel: validation.data.parallel,
382
+ continueOnError: validation.data.continueOnError,
383
+ timeout: validation.data.timeout,
384
+ })];
385
+ case 3:
386
+ result = _b.sent();
387
+ // Log activity per node
388
+ for (_i = 0, _a = result.results; _i < _a.length; _i++) {
389
+ r = _a[_i];
390
+ if (r.success) {
391
+ node = manager.getNode(r.nodeId);
392
+ if (node) {
393
+ (0, activities_1.addActivity)({
394
+ environmentId: node.id,
395
+ action: "tmux_batch_command_sent",
396
+ environmentName: node.name,
397
+ details: "Batch command to ".concat(result.total, " nodes: ").concat(validation.data.command.slice(0, 80)).concat(validation.data.command.length > 80 ? "..." : ""),
398
+ });
399
+ }
400
+ }
401
+ }
402
+ return [2 /*return*/, c.json({ success: true, result: result })];
403
+ case 4:
404
+ error_6 = _b.sent();
405
+ return [2 /*return*/, c.json({ success: false, error: String(error_6) }, 500)];
406
+ case 5: return [2 /*return*/];
407
+ }
408
+ });
409
+ }); });
410
+ // ============================================
411
+ // Pane Operations
412
+ // ============================================
413
+ /**
414
+ * POST /api/tmux/manager/sessions/split - Split a pane
415
+ */
416
+ tmuxApi.post("/manager/sessions/split", function (c) { return __awaiter(void 0, void 0, void 0, function () {
417
+ var body, validation, manager, node, result, error_7;
418
+ return __generator(this, function (_a) {
419
+ switch (_a.label) {
420
+ case 0: return [4 /*yield*/, c.req.json()];
421
+ case 1:
422
+ body = _a.sent();
423
+ validation = validateRequest(api_1.TmuxManagerSplitPaneSchema, body);
424
+ if (!validation.success) {
425
+ return [2 /*return*/, c.json({ success: false, error: validation.error }, 400)];
426
+ }
427
+ _a.label = 2;
428
+ case 2:
429
+ _a.trys.push([2, 4, , 5]);
430
+ manager = (0, tmux_manager_js_1.getTmuxManager)();
431
+ node = manager.getNode(validation.data.nodeId);
432
+ return [4 /*yield*/, manager.splitPaneOnNode(validation.data.nodeId, validation.data.sessionName, validation.data.direction, validation.data.command, validation.data.windowIndex)];
433
+ case 3:
434
+ result = _a.sent();
435
+ if (result.success && node) {
436
+ (0, activities_1.addActivity)({
437
+ environmentId: node.id,
438
+ action: "tmux_pane_split",
439
+ environmentName: node.name,
440
+ details: "Split pane ".concat(validation.data.direction === "h" ? "horizontally" : "vertically").concat(validation.data.command ? " with command: ".concat(validation.data.command.slice(0, 50), "...") : ""),
441
+ });
442
+ }
443
+ return [2 /*return*/, c.json(result)];
444
+ case 4:
445
+ error_7 = _a.sent();
446
+ return [2 /*return*/, c.json({ success: false, error: String(error_7) }, 500)];
447
+ case 5: return [2 /*return*/];
448
+ }
449
+ });
450
+ }); });
451
+ /**
452
+ * POST /api/tmux/manager/sessions/capture - Capture pane output
453
+ */
454
+ tmuxApi.post("/manager/sessions/capture", function (c) { return __awaiter(void 0, void 0, void 0, function () {
455
+ var body, validation, manager, result, error_8;
456
+ return __generator(this, function (_a) {
457
+ switch (_a.label) {
458
+ case 0: return [4 /*yield*/, c.req.json()];
459
+ case 1:
460
+ body = _a.sent();
461
+ validation = validateRequest(api_1.TmuxManagerCapturePaneSchema, body);
462
+ if (!validation.success) {
463
+ return [2 /*return*/, c.json({ success: false, error: validation.error }, 400)];
464
+ }
465
+ _a.label = 2;
466
+ case 2:
467
+ _a.trys.push([2, 4, , 5]);
468
+ manager = (0, tmux_manager_js_1.getTmuxManager)();
469
+ return [4 /*yield*/, manager.capturePaneOutput(validation.data.nodeId, validation.data.sessionName, validation.data.paneIndex)];
470
+ case 3:
471
+ result = _a.sent();
472
+ return [2 /*return*/, c.json(result)];
473
+ case 4:
474
+ error_8 = _a.sent();
475
+ return [2 /*return*/, c.json({ success: false, error: String(error_8) }, 500)];
476
+ case 5: return [2 /*return*/];
477
+ }
478
+ });
479
+ }); });
480
+ /**
481
+ * POST /api/tmux/manager/sessions/history - Get pane history
482
+ */
483
+ tmuxApi.post("/manager/sessions/history", function (c) { return __awaiter(void 0, void 0, void 0, function () {
484
+ var body, validation, manager, result, error_9;
485
+ return __generator(this, function (_a) {
486
+ switch (_a.label) {
487
+ case 0: return [4 /*yield*/, c.req.json()];
488
+ case 1:
489
+ body = _a.sent();
490
+ validation = validateRequest(api_1.TmuxManagerGetHistorySchema, body);
491
+ if (!validation.success) {
492
+ return [2 /*return*/, c.json({ success: false, error: validation.error }, 400)];
493
+ }
494
+ _a.label = 2;
495
+ case 2:
496
+ _a.trys.push([2, 4, , 5]);
497
+ manager = (0, tmux_manager_js_1.getTmuxManager)();
498
+ return [4 /*yield*/, manager.getPaneHistory(validation.data.nodeId, validation.data.sessionName, validation.data.paneIndex, validation.data.lines)];
499
+ case 3:
500
+ result = _a.sent();
501
+ return [2 /*return*/, c.json(result)];
502
+ case 4:
503
+ error_9 = _a.sent();
504
+ return [2 /*return*/, c.json({ success: false, error: String(error_9) }, 500)];
505
+ case 5: return [2 /*return*/];
506
+ }
507
+ });
508
+ }); });
509
+ /**
510
+ * DELETE /api/tmux/manager/sessions/pane - Kill a pane
511
+ */
512
+ tmuxApi.delete("/manager/sessions/pane", function (c) { return __awaiter(void 0, void 0, void 0, function () {
513
+ var body, validation, manager, node, result, error_10;
514
+ return __generator(this, function (_a) {
515
+ switch (_a.label) {
516
+ case 0: return [4 /*yield*/, c.req.json()];
517
+ case 1:
518
+ body = _a.sent();
519
+ validation = validateRequest(api_1.TmuxManagerKillPaneSchema, body);
520
+ if (!validation.success) {
521
+ return [2 /*return*/, c.json({ success: false, error: validation.error }, 400)];
522
+ }
523
+ _a.label = 2;
524
+ case 2:
525
+ _a.trys.push([2, 4, , 5]);
526
+ manager = (0, tmux_manager_js_1.getTmuxManager)();
527
+ node = manager.getNode(validation.data.nodeId);
528
+ return [4 /*yield*/, manager.killPaneInSession(validation.data.nodeId, validation.data.sessionName, validation.data.paneIndex)];
529
+ case 3:
530
+ result = _a.sent();
531
+ if (result.success && node) {
532
+ (0, activities_1.addActivity)({
533
+ environmentId: node.id,
534
+ action: "tmux_pane_killed",
535
+ environmentName: node.name,
536
+ details: "Pane ".concat(validation.data.paneIndex, " killed in session \"").concat(validation.data.sessionName, "\""),
537
+ });
538
+ }
539
+ return [2 /*return*/, c.json(result)];
540
+ case 4:
541
+ error_10 = _a.sent();
542
+ return [2 /*return*/, c.json({ success: false, error: String(error_10) }, 500)];
543
+ case 5: return [2 /*return*/];
544
+ }
545
+ });
546
+ }); });
547
+ // ============================================
548
+ // Window Operations
549
+ // ============================================
550
+ /**
551
+ * POST /api/tmux/manager/sessions/windows - List windows in a session
552
+ */
553
+ tmuxApi.post("/manager/sessions/windows", function (c) { return __awaiter(void 0, void 0, void 0, function () {
554
+ var body, validation, manager, result, error_11;
555
+ return __generator(this, function (_a) {
556
+ switch (_a.label) {
557
+ case 0: return [4 /*yield*/, c.req.json()];
558
+ case 1:
559
+ body = _a.sent();
560
+ validation = validateRequest(api_1.TmuxManagerListWindowsSchema, body);
561
+ if (!validation.success) {
562
+ return [2 /*return*/, c.json({ success: false, error: validation.error }, 400)];
563
+ }
564
+ _a.label = 2;
565
+ case 2:
566
+ _a.trys.push([2, 4, , 5]);
567
+ manager = (0, tmux_manager_js_1.getTmuxManager)();
568
+ return [4 /*yield*/, manager.listWindows(validation.data.nodeId, validation.data.sessionName)];
569
+ case 3:
570
+ result = _a.sent();
571
+ return [2 /*return*/, c.json(result)];
572
+ case 4:
573
+ error_11 = _a.sent();
574
+ return [2 /*return*/, c.json({ success: false, error: String(error_11) }, 500)];
575
+ case 5: return [2 /*return*/];
576
+ }
577
+ });
578
+ }); });
579
+ /**
580
+ * POST /api/tmux/manager/sessions/panes - List panes in a window
581
+ */
582
+ tmuxApi.post("/manager/sessions/panes", function (c) { return __awaiter(void 0, void 0, void 0, function () {
583
+ var body, validation, manager, result, error_12;
584
+ return __generator(this, function (_a) {
585
+ switch (_a.label) {
586
+ case 0: return [4 /*yield*/, c.req.json()];
587
+ case 1:
588
+ body = _a.sent();
589
+ validation = validateRequest(api_1.TmuxManagerListPanesSchema, body);
590
+ if (!validation.success) {
591
+ return [2 /*return*/, c.json({ success: false, error: validation.error }, 400)];
592
+ }
593
+ _a.label = 2;
594
+ case 2:
595
+ _a.trys.push([2, 4, , 5]);
596
+ manager = (0, tmux_manager_js_1.getTmuxManager)();
597
+ return [4 /*yield*/, manager.listPanes(validation.data.nodeId, validation.data.sessionName, validation.data.windowIndex)];
598
+ case 3:
599
+ result = _a.sent();
600
+ return [2 /*return*/, c.json(result)];
601
+ case 4:
602
+ error_12 = _a.sent();
603
+ return [2 /*return*/, c.json({ success: false, error: String(error_12) }, 500)];
604
+ case 5: return [2 /*return*/];
605
+ }
606
+ });
607
+ }); });
608
+ /**
609
+ * POST /api/tmux/manager/sessions/windows/switch - Switch to a window
610
+ */
611
+ tmuxApi.post("/manager/sessions/windows/switch", function (c) { return __awaiter(void 0, void 0, void 0, function () {
612
+ var body, validation, manager, node, result, error_13;
613
+ return __generator(this, function (_a) {
614
+ switch (_a.label) {
615
+ case 0: return [4 /*yield*/, c.req.json()];
616
+ case 1:
617
+ body = _a.sent();
618
+ validation = validateRequest(api_1.TmuxManagerSwitchWindowSchema, body);
619
+ if (!validation.success) {
620
+ return [2 /*return*/, c.json({ success: false, error: validation.error }, 400)];
621
+ }
622
+ _a.label = 2;
623
+ case 2:
624
+ _a.trys.push([2, 4, , 5]);
625
+ manager = (0, tmux_manager_js_1.getTmuxManager)();
626
+ node = manager.getNode(validation.data.nodeId);
627
+ return [4 /*yield*/, manager.switchToWindow(validation.data.nodeId, validation.data.sessionName, validation.data.windowIndex)];
628
+ case 3:
629
+ result = _a.sent();
630
+ if (result.success && node) {
631
+ (0, activities_1.addActivity)({
632
+ environmentId: node.id,
633
+ action: "tmux_window_switched",
634
+ environmentName: node.name,
635
+ details: "Switched to window ".concat(validation.data.windowIndex, " in session \"").concat(validation.data.sessionName, "\""),
636
+ });
637
+ }
638
+ return [2 /*return*/, c.json(result)];
639
+ case 4:
640
+ error_13 = _a.sent();
641
+ return [2 /*return*/, c.json({ success: false, error: String(error_13) }, 500)];
642
+ case 5: return [2 /*return*/];
643
+ }
644
+ });
645
+ }); });
646
+ /**
647
+ * POST /api/tmux/manager/sessions/panes/switch - Switch to a pane
648
+ */
649
+ tmuxApi.post("/manager/sessions/panes/switch", function (c) { return __awaiter(void 0, void 0, void 0, function () {
650
+ var body, validation, manager, node, result, error_14;
651
+ return __generator(this, function (_a) {
652
+ switch (_a.label) {
653
+ case 0: return [4 /*yield*/, c.req.json()];
654
+ case 1:
655
+ body = _a.sent();
656
+ validation = validateRequest(api_1.TmuxManagerSwitchPaneSchema, body);
657
+ if (!validation.success) {
658
+ return [2 /*return*/, c.json({ success: false, error: validation.error }, 400)];
659
+ }
660
+ _a.label = 2;
661
+ case 2:
662
+ _a.trys.push([2, 4, , 5]);
663
+ manager = (0, tmux_manager_js_1.getTmuxManager)();
664
+ node = manager.getNode(validation.data.nodeId);
665
+ return [4 /*yield*/, manager.switchToPane(validation.data.nodeId, validation.data.sessionName, validation.data.paneIndex)];
666
+ case 3:
667
+ result = _a.sent();
668
+ if (result.success && node) {
669
+ (0, activities_1.addActivity)({
670
+ environmentId: node.id,
671
+ action: "tmux_pane_switched",
672
+ environmentName: node.name,
673
+ details: "Switched to pane ".concat(validation.data.paneIndex, " in session \"").concat(validation.data.sessionName, "\""),
674
+ });
675
+ }
676
+ return [2 /*return*/, c.json(result)];
677
+ case 4:
678
+ error_14 = _a.sent();
679
+ return [2 /*return*/, c.json({ success: false, error: String(error_14) }, 500)];
680
+ case 5: return [2 /*return*/];
681
+ }
682
+ });
683
+ }); });
684
+ /**
685
+ * PUT /api/tmux/manager/sessions/windows/rename - Rename a window
686
+ */
687
+ tmuxApi.put("/manager/sessions/windows/rename", function (c) { return __awaiter(void 0, void 0, void 0, function () {
688
+ var body, validation, manager, node, result, error_15;
689
+ return __generator(this, function (_a) {
690
+ switch (_a.label) {
691
+ case 0: return [4 /*yield*/, c.req.json()];
692
+ case 1:
693
+ body = _a.sent();
694
+ validation = validateRequest(api_1.TmuxManagerRenameWindowSchema, body);
695
+ if (!validation.success) {
696
+ return [2 /*return*/, c.json({ success: false, error: validation.error }, 400)];
697
+ }
698
+ _a.label = 2;
699
+ case 2:
700
+ _a.trys.push([2, 4, , 5]);
701
+ manager = (0, tmux_manager_js_1.getTmuxManager)();
702
+ node = manager.getNode(validation.data.nodeId);
703
+ return [4 /*yield*/, manager.renameWindowInSession(validation.data.nodeId, validation.data.sessionName, validation.data.windowIndex, validation.data.newName)];
704
+ case 3:
705
+ result = _a.sent();
706
+ if (result.success && node) {
707
+ (0, activities_1.addActivity)({
708
+ environmentId: node.id,
709
+ action: "tmux_window_renamed",
710
+ environmentName: node.name,
711
+ details: "Renamed window ".concat(validation.data.windowIndex, " to \"").concat(validation.data.newName, "\" in session \"").concat(validation.data.sessionName, "\""),
712
+ });
713
+ }
714
+ return [2 /*return*/, c.json(result)];
715
+ case 4:
716
+ error_15 = _a.sent();
717
+ return [2 /*return*/, c.json({ success: false, error: String(error_15) }, 500)];
718
+ case 5: return [2 /*return*/];
719
+ }
720
+ });
721
+ }); });
722
+ // ============================================
723
+ // Maintenance & Monitoring
724
+ // ============================================
725
+ /**
726
+ * GET /api/tmux/manager/sessions/detailed - Get detailed session info
727
+ */
728
+ tmuxApi.get("/manager/sessions/detailed", function (c) { return __awaiter(void 0, void 0, void 0, function () {
729
+ var nodeId, sessionName, manager, result, error_16;
730
+ return __generator(this, function (_a) {
731
+ switch (_a.label) {
732
+ case 0:
733
+ nodeId = c.req.query("nodeId");
734
+ sessionName = c.req.query("sessionName");
735
+ if (!nodeId || !sessionName) {
736
+ return [2 /*return*/, c.json({ success: false, error: "nodeId and sessionName are required" }, 400)];
737
+ }
738
+ _a.label = 1;
739
+ case 1:
740
+ _a.trys.push([1, 3, , 4]);
741
+ manager = (0, tmux_manager_js_1.getTmuxManager)();
742
+ return [4 /*yield*/, manager.getDetailedSession(nodeId, sessionName)];
743
+ case 2:
744
+ result = _a.sent();
745
+ return [2 /*return*/, c.json({ success: result !== null, session: result })];
746
+ case 3:
747
+ error_16 = _a.sent();
748
+ return [2 /*return*/, c.json({ success: false, error: String(error_16) }, 500)];
749
+ case 4: return [2 /*return*/];
750
+ }
751
+ });
752
+ }); });
753
+ /**
754
+ * POST /api/tmux/manager/sessions/cleanup - Cleanup old sessions
755
+ */
756
+ tmuxApi.post("/manager/sessions/cleanup", function (c) { return __awaiter(void 0, void 0, void 0, function () {
757
+ var body, validation, manager, node, result, error_17;
758
+ return __generator(this, function (_a) {
759
+ switch (_a.label) {
760
+ case 0: return [4 /*yield*/, c.req.json()];
761
+ case 1:
762
+ body = _a.sent();
763
+ validation = validateRequest(api_1.TmuxManagerCleanupOldSessionsSchema, body);
764
+ if (!validation.success) {
765
+ return [2 /*return*/, c.json({ success: false, error: validation.error }, 400)];
766
+ }
767
+ _a.label = 2;
768
+ case 2:
769
+ _a.trys.push([2, 4, , 5]);
770
+ manager = (0, tmux_manager_js_1.getTmuxManager)();
771
+ node = manager.getNode(validation.data.nodeId);
772
+ return [4 /*yield*/, manager.cleanupOldSessions(validation.data.nodeId, validation.data.ageLimitMs)];
773
+ case 3:
774
+ result = _a.sent();
775
+ if (result.success && result.cleaned && result.cleaned > 0 && node) {
776
+ (0, activities_1.addActivity)({
777
+ environmentId: node.id,
778
+ action: "tmux_sessions_cleaned",
779
+ environmentName: node.name,
780
+ details: "Cleaned up ".concat(result.cleaned, " old tmux sessions"),
781
+ });
782
+ }
783
+ return [2 /*return*/, c.json(result)];
784
+ case 4:
785
+ error_17 = _a.sent();
786
+ return [2 /*return*/, c.json({ success: false, error: String(error_17) }, 500)];
787
+ case 5: return [2 /*return*/];
788
+ }
789
+ });
790
+ }); });
791
+ /**
792
+ * GET /api/tmux/manager/nodes/:id/resources - Get resource usage for a node
793
+ */
794
+ tmuxApi.get("/manager/nodes/:id/resources", function (c) { return __awaiter(void 0, void 0, void 0, function () {
795
+ var id, manager, result, error_18;
796
+ return __generator(this, function (_a) {
797
+ switch (_a.label) {
798
+ case 0:
799
+ id = c.req.param("id");
800
+ if (!id) {
801
+ return [2 /*return*/, c.json({ success: false, error: "Node ID is required" }, 400)];
802
+ }
803
+ _a.label = 1;
804
+ case 1:
805
+ _a.trys.push([1, 3, , 4]);
806
+ manager = (0, tmux_manager_js_1.getTmuxManager)();
807
+ return [4 /*yield*/, manager.getResourceUsage(id)];
808
+ case 2:
809
+ result = _a.sent();
810
+ return [2 /*return*/, c.json(result)];
811
+ case 3:
812
+ error_18 = _a.sent();
813
+ return [2 /*return*/, c.json({ success: false, error: String(error_18) }, 500)];
814
+ case 4: return [2 /*return*/];
815
+ }
816
+ });
817
+ }); });
818
+ /**
819
+ * GET /api/tmux/manager/summary - Get summary statistics
820
+ */
821
+ tmuxApi.get("/manager/summary", function (c) { return __awaiter(void 0, void 0, void 0, function () {
822
+ var manager, summary, error_19;
823
+ return __generator(this, function (_a) {
824
+ switch (_a.label) {
825
+ case 0:
826
+ _a.trys.push([0, 2, , 3]);
827
+ manager = (0, tmux_manager_js_1.getTmuxManager)();
828
+ return [4 /*yield*/, manager.getSummary()];
829
+ case 1:
830
+ summary = _a.sent();
831
+ return [2 /*return*/, c.json({ success: true, summary: summary })];
832
+ case 2:
833
+ error_19 = _a.sent();
834
+ return [2 /*return*/, c.json({ success: false, error: String(error_19) }, 500)];
835
+ case 3: return [2 /*return*/];
836
+ }
837
+ });
838
+ }); });
839
+ /**
840
+ * POST /api/tmux/manager/cache/invalidate - Invalidate session cache
841
+ */
842
+ tmuxApi.post("/manager/cache/invalidate", function (c) { return __awaiter(void 0, void 0, void 0, function () {
843
+ var manager, body, nodeId, error_20;
844
+ return __generator(this, function (_a) {
845
+ switch (_a.label) {
846
+ case 0:
847
+ _a.trys.push([0, 2, , 3]);
848
+ manager = (0, tmux_manager_js_1.getTmuxManager)();
849
+ return [4 /*yield*/, c.req.json().catch(function () { return ({}); })];
850
+ case 1:
851
+ body = _a.sent();
852
+ nodeId = body === null || body === void 0 ? void 0 : body.nodeId;
853
+ manager.invalidateCache(nodeId);
854
+ return [2 /*return*/, c.json({ success: true })];
855
+ case 2:
856
+ error_20 = _a.sent();
857
+ return [2 /*return*/, c.json({ success: false, error: String(error_20) }, 500)];
858
+ case 3: return [2 /*return*/];
859
+ }
860
+ });
861
+ }); });