@burdenoff/vibe-plugin-session-tmux 2.0.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/README.md ADDED
@@ -0,0 +1,53 @@
1
+ # @burdenoff/vibe-plugin-session-tmux
2
+
3
+ Tmux + ttyd session provider plugin for [VibeControls Agent](https://www.npmjs.com/package/@burdenoff/vibe-agent).
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ vibe plugin install @burdenoff/vibe-plugin-session-tmux
9
+ ```
10
+
11
+ Or install globally alongside the agent:
12
+
13
+ ```bash
14
+ npm install -g @burdenoff/vibe-plugin-session-tmux
15
+ ```
16
+
17
+ ## Features
18
+
19
+ - **Tmux Sessions** -- Create, manage, and destroy tmux terminal sessions
20
+ - **ttyd Integration** -- Web terminal access via ttyd (auto-started per session)
21
+ - **Session Lifecycle** -- Full lifecycle management with health checks
22
+ - **Command Execution** -- Run commands in existing tmux sessions
23
+ - **Terminal Capture** -- Capture terminal output from running sessions
24
+ - **Port Management** -- Automatic free port allocation for ttyd instances
25
+
26
+ ## Provider Interface
27
+
28
+ This plugin registers a `session` provider with the following capabilities:
29
+
30
+ | Method | Description |
31
+ | --- | --- |
32
+ | `create(config)` | Create a new tmux session with optional ttyd terminal |
33
+ | `get(id)` | Get session info by ID |
34
+ | `list()` | List all managed sessions |
35
+ | `terminate(id)` | Kill a tmux session and its ttyd process |
36
+ | `execute(id, command)` | Send a command to a tmux session |
37
+ | `capture(id)` | Capture current terminal output |
38
+ | `startTerminal(id)` | Start a ttyd web terminal for a session |
39
+ | `stopTerminal(id)` | Stop the ttyd process for a session |
40
+ | `healthCheck()` | Check tmux and ttyd health |
41
+ | `getSystemSessions()` | List all system tmux sessions |
42
+ | `getSystemTerminals()` | List all running ttyd processes |
43
+
44
+ ## Requirements
45
+
46
+ - VibeControls Agent >= 2.0.0
47
+ - tmux installed on the host system
48
+ - ttyd installed on the host system (optional, for web terminals)
49
+ - Bun runtime >= 1.3.0
50
+
51
+ ## License
52
+
53
+ Proprietary -- Copyright Burdenoff Consultancy Services Pvt. Ltd.
@@ -0,0 +1,123 @@
1
+ /**
2
+ * @burdenoff/vibe-plugin-session-tmux
3
+ *
4
+ * Tmux + ttyd session provider plugin for VibeControls Agent.
5
+ * Implements the full SessionProvider interface (23 methods) using tmux for
6
+ * terminal session management and ttyd for browser-accessible web terminals.
7
+ */
8
+ type SessionStatus = "active" | "inactive" | "terminated" | "error";
9
+ interface SessionConfig {
10
+ name: string;
11
+ command?: string;
12
+ workingDirectory?: string;
13
+ environment?: Record<string, string>;
14
+ shell?: string;
15
+ size?: {
16
+ cols: number;
17
+ rows: number;
18
+ };
19
+ projectId?: string;
20
+ }
21
+ interface SessionInfo {
22
+ id: string;
23
+ name: string;
24
+ status: SessionStatus;
25
+ provider: string;
26
+ command?: string;
27
+ workingDirectory?: string;
28
+ pid?: number;
29
+ projectId?: string;
30
+ createdAt: string;
31
+ updatedAt?: string;
32
+ terminal?: TerminalInfo;
33
+ metadata?: Record<string, unknown>;
34
+ }
35
+ interface TerminalInfo {
36
+ url: string;
37
+ port: number;
38
+ pid: number;
39
+ }
40
+ interface HealthCheckResult {
41
+ ok: boolean;
42
+ sessions: number;
43
+ terminals: number;
44
+ message?: string;
45
+ }
46
+ interface SystemSessionInfo {
47
+ id: string;
48
+ name: string;
49
+ windows: number;
50
+ attached: boolean;
51
+ createdAt?: string;
52
+ }
53
+ interface SystemTerminalInfo {
54
+ pid: number;
55
+ port: number;
56
+ sessionId?: string;
57
+ }
58
+ interface SessionProvider {
59
+ readonly name: string;
60
+ create(config: SessionConfig): Promise<SessionInfo>;
61
+ terminate(sessionId: string): Promise<void>;
62
+ getInfo(sessionId: string): Promise<SessionInfo | null>;
63
+ list(): Promise<SessionInfo[]>;
64
+ sendCommand(sessionId: string, command: string): Promise<void>;
65
+ sendKeys(sessionId: string, keys: string): Promise<void>;
66
+ sendInterrupt(sessionId: string): Promise<void>;
67
+ captureOutput(sessionId: string): Promise<string>;
68
+ rename(sessionId: string, newName: string): Promise<void>;
69
+ toggleMouse(sessionId: string): Promise<boolean>;
70
+ getTerminationStatus(sessionId: string): Promise<{
71
+ terminated: boolean;
72
+ exists: boolean;
73
+ }>;
74
+ getTerminalInfo(sessionId: string): Promise<TerminalInfo | null>;
75
+ startTerminal(sessionId: string, port?: number): Promise<TerminalInfo>;
76
+ stopTerminal(sessionId: string): Promise<void>;
77
+ listSystemSessions(): Promise<SystemSessionInfo[]>;
78
+ listSystemTerminals(): Promise<SystemTerminalInfo[]>;
79
+ bulkKillSystemSessions(sessionIds: string[]): Promise<{
80
+ killed: number;
81
+ failed: number;
82
+ }>;
83
+ bulkKillSystemTerminals(pids: number[]): Promise<{
84
+ killed: number;
85
+ failed: number;
86
+ }>;
87
+ healthCheck(): Promise<HealthCheckResult>;
88
+ getSessionsByProject(projectId: string): Promise<SessionInfo[]>;
89
+ cleanup(): Promise<{
90
+ cleaned: number;
91
+ }>;
92
+ }
93
+ interface HostLogger {
94
+ info(message: string, meta?: Record<string, unknown>): void;
95
+ warn(message: string, meta?: Record<string, unknown>): void;
96
+ error(message: string, meta?: Record<string, unknown>): void;
97
+ debug(message: string, meta?: Record<string, unknown>): void;
98
+ }
99
+ interface HostStorage {
100
+ get(key: string): Promise<string | null>;
101
+ set(key: string, value: string): Promise<void>;
102
+ delete(key: string): Promise<void>;
103
+ }
104
+ interface HostServices {
105
+ logger: HostLogger;
106
+ storage: HostStorage;
107
+ }
108
+ interface VibePlugin {
109
+ name: string;
110
+ version: string;
111
+ description: string;
112
+ tags?: Array<"backend" | "frontend" | "cli" | "provider" | "adapter" | "integration">;
113
+ providers: {
114
+ session?: SessionProvider;
115
+ };
116
+ onServerStart?(services: HostServices): Promise<void>;
117
+ onServerStop?(): Promise<void>;
118
+ onCliSetup?(): void;
119
+ }
120
+ declare const vibePlugin: VibePlugin;
121
+ export { vibePlugin };
122
+ export type { SessionProvider, SessionConfig, SessionInfo, SessionStatus, TerminalInfo, HealthCheckResult, SystemSessionInfo, SystemTerminalInfo, VibePlugin, HostServices, };
123
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,913 @@
1
+ /**
2
+ * @burdenoff/vibe-plugin-session-tmux
3
+ *
4
+ * Tmux + ttyd session provider plugin for VibeControls Agent.
5
+ * Implements the full SessionProvider interface (23 methods) using tmux for
6
+ * terminal session management and ttyd for browser-accessible web terminals.
7
+ */
8
+ import { execSync } from "node:child_process";
9
+ import { createServer } from "node:net";
10
+ import { randomBytes } from "node:crypto";
11
+ // ---------------------------------------------------------------------------
12
+ // Constants
13
+ // ---------------------------------------------------------------------------
14
+ const PROVIDER_NAME = "session-tmux";
15
+ const STORAGE_NAMESPACE = "session-tmux";
16
+ const STORAGE_KEY_SESSIONS = "sessions";
17
+ const TTYD_BASE_PORT = 7681;
18
+ const TTYD_PORT_RANGE = 200;
19
+ const GRACEFUL_KILL_TIMEOUT_MS = 3000;
20
+ // ---------------------------------------------------------------------------
21
+ // Helpers
22
+ // ---------------------------------------------------------------------------
23
+ /**
24
+ * Generate a short random hex ID (8 chars) for session identifiers.
25
+ */
26
+ function generateId() {
27
+ return randomBytes(4).toString("hex");
28
+ }
29
+ /**
30
+ * Execute a tmux command and return its stdout. Throws on non-zero exit.
31
+ */
32
+ function tmuxExec(args) {
33
+ const result = execSync(`tmux ${args.map(shellEscape).join(" ")}`, {
34
+ stdio: ["pipe", "pipe", "pipe"],
35
+ timeout: 10_000,
36
+ });
37
+ return result.toString("utf-8").trimEnd();
38
+ }
39
+ /**
40
+ * Execute a tmux command, returning true on success, false on failure.
41
+ * Does not throw.
42
+ */
43
+ function tmuxExecSilent(args) {
44
+ try {
45
+ execSync(`tmux ${args.map(shellEscape).join(" ")}`, {
46
+ stdio: ["pipe", "pipe", "pipe"],
47
+ timeout: 10_000,
48
+ });
49
+ return true;
50
+ }
51
+ catch {
52
+ return false;
53
+ }
54
+ }
55
+ /**
56
+ * Escape a single shell argument.
57
+ */
58
+ function shellEscape(arg) {
59
+ // If the arg is already safe, return as-is
60
+ if (/^[a-zA-Z0-9_./:@=+-]+$/.test(arg)) {
61
+ return arg;
62
+ }
63
+ // Wrap in single quotes, escaping existing single quotes
64
+ return `'${arg.replace(/'/g, "'\\''")}'`;
65
+ }
66
+ /**
67
+ * Find an available TCP port starting from `start` within the configured range.
68
+ */
69
+ async function findAvailablePort(start) {
70
+ for (let port = start; port < start + TTYD_PORT_RANGE; port++) {
71
+ const available = await isPortAvailable(port);
72
+ if (available) {
73
+ return port;
74
+ }
75
+ }
76
+ throw new Error(`No available port found in range ${start}-${start + TTYD_PORT_RANGE - 1}`);
77
+ }
78
+ /**
79
+ * Check whether a TCP port is available by attempting to bind to it.
80
+ */
81
+ function isPortAvailable(port) {
82
+ return new Promise((resolve) => {
83
+ const server = createServer();
84
+ server.once("error", () => {
85
+ resolve(false);
86
+ });
87
+ server.once("listening", () => {
88
+ server.close(() => resolve(true));
89
+ });
90
+ server.listen(port, "127.0.0.1");
91
+ });
92
+ }
93
+ /**
94
+ * Send SIGTERM to a process, then SIGKILL after timeout if still alive.
95
+ */
96
+ async function gracefulKill(pid, timeout = GRACEFUL_KILL_TIMEOUT_MS) {
97
+ try {
98
+ process.kill(pid, "SIGTERM");
99
+ }
100
+ catch {
101
+ // Process already dead — nothing to do
102
+ return;
103
+ }
104
+ const deadline = Date.now() + timeout;
105
+ while (Date.now() < deadline) {
106
+ await sleep(200);
107
+ if (!isProcessAlive(pid)) {
108
+ return;
109
+ }
110
+ }
111
+ // Force kill
112
+ try {
113
+ process.kill(pid, "SIGKILL");
114
+ }
115
+ catch {
116
+ // Already gone
117
+ }
118
+ }
119
+ /**
120
+ * Check if a process is still alive.
121
+ */
122
+ function isProcessAlive(pid) {
123
+ try {
124
+ process.kill(pid, 0);
125
+ return true;
126
+ }
127
+ catch {
128
+ return false;
129
+ }
130
+ }
131
+ /**
132
+ * Simple async sleep.
133
+ */
134
+ function sleep(ms) {
135
+ return new Promise((resolve) => setTimeout(resolve, ms));
136
+ }
137
+ /**
138
+ * Get the current ISO timestamp.
139
+ */
140
+ function nowISO() {
141
+ return new Date().toISOString();
142
+ }
143
+ // ---------------------------------------------------------------------------
144
+ // TmuxSessionProvider
145
+ // ---------------------------------------------------------------------------
146
+ class TmuxSessionProvider {
147
+ name = PROVIDER_NAME;
148
+ services;
149
+ log;
150
+ storage;
151
+ /** In-memory map of ttyd child processes keyed by session ID. */
152
+ ttydProcesses = new Map();
153
+ /** In-memory map of ttyd port assignments keyed by session ID. */
154
+ ttydPorts = new Map();
155
+ // -----------------------------------------------------------------------
156
+ // Lifecycle
157
+ // -----------------------------------------------------------------------
158
+ /**
159
+ * Initialise the provider with host services. Called from onServerStart.
160
+ */
161
+ async init(services) {
162
+ this.services = services;
163
+ this.log = services.logger;
164
+ this.storage = services.storage;
165
+ this.log.info("TmuxSessionProvider initialising", { provider: this.name });
166
+ // Verify tmux is available
167
+ try {
168
+ const version = tmuxExec(["-V"]);
169
+ this.log.info("tmux detected", { version });
170
+ }
171
+ catch {
172
+ this.log.error("tmux is not installed or not in PATH — session provider will not function");
173
+ }
174
+ // Reconcile persisted sessions against actual tmux state
175
+ await this.reconcileSessions();
176
+ this.log.info("TmuxSessionProvider ready");
177
+ }
178
+ /**
179
+ * Graceful shutdown: stop all ttyd terminals.
180
+ */
181
+ async shutdown() {
182
+ this.log.info("TmuxSessionProvider shutting down — stopping terminals");
183
+ const stopPromises = [];
184
+ for (const [sessionId] of this.ttydProcesses) {
185
+ stopPromises.push(this.stopTerminal(sessionId));
186
+ }
187
+ await Promise.allSettled(stopPromises);
188
+ this.log.info("TmuxSessionProvider shutdown complete");
189
+ }
190
+ // -----------------------------------------------------------------------
191
+ // SessionProvider — create / terminate / getInfo / list
192
+ // -----------------------------------------------------------------------
193
+ async create(config) {
194
+ const id = generateId();
195
+ const sessionName = `vibe-${id}`;
196
+ const now = nowISO();
197
+ this.log.info("Creating tmux session", {
198
+ id,
199
+ name: config.name,
200
+ sessionName,
201
+ });
202
+ // Build tmux new-session command
203
+ const args = ["new-session", "-d", "-s", sessionName];
204
+ if (config.workingDirectory) {
205
+ args.push("-c", config.workingDirectory);
206
+ }
207
+ if (config.size) {
208
+ args.push("-x", String(config.size.cols), "-y", String(config.size.rows));
209
+ }
210
+ // If a shell is specified, use it as the window command
211
+ if (config.shell) {
212
+ args.push(config.shell);
213
+ }
214
+ try {
215
+ tmuxExec(args);
216
+ }
217
+ catch (err) {
218
+ this.log.error("Failed to create tmux session", {
219
+ id,
220
+ error: String(err),
221
+ });
222
+ throw new Error(`Failed to create tmux session: ${err}`);
223
+ }
224
+ // Apply environment variables
225
+ if (config.environment) {
226
+ for (const [key, value] of Object.entries(config.environment)) {
227
+ tmuxExecSilent([
228
+ "set-environment",
229
+ "-t",
230
+ sessionName,
231
+ key,
232
+ value,
233
+ ]);
234
+ }
235
+ }
236
+ // Enable mouse by default
237
+ tmuxExecSilent(["set", "-t", sessionName, "mouse", "on"]);
238
+ // If an initial command is given, send it
239
+ if (config.command) {
240
+ tmuxExecSilent(["send-keys", "-t", sessionName, config.command, "Enter"]);
241
+ }
242
+ // Get the PID of the session's first pane
243
+ const pid = this.getSessionPanePid(sessionName);
244
+ const info = {
245
+ id,
246
+ name: config.name,
247
+ status: "active",
248
+ provider: this.name,
249
+ command: config.command,
250
+ workingDirectory: config.workingDirectory,
251
+ pid: pid ?? undefined,
252
+ projectId: config.projectId,
253
+ createdAt: now,
254
+ updatedAt: now,
255
+ metadata: {
256
+ tmuxSessionName: sessionName,
257
+ shell: config.shell,
258
+ size: config.size,
259
+ },
260
+ };
261
+ await this.saveSession(info);
262
+ this.log.info("Tmux session created", { id, sessionName, pid });
263
+ return info;
264
+ }
265
+ async terminate(sessionId) {
266
+ const session = await this.getInfo(sessionId);
267
+ if (!session) {
268
+ this.log.warn("Terminate called for unknown session", { sessionId });
269
+ return;
270
+ }
271
+ const tmuxName = this.getTmuxName(session);
272
+ this.log.info("Terminating tmux session", {
273
+ sessionId,
274
+ tmuxName,
275
+ });
276
+ // Stop terminal first if running
277
+ if (this.ttydProcesses.has(sessionId)) {
278
+ await this.stopTerminal(sessionId);
279
+ }
280
+ // Kill the tmux session
281
+ tmuxExecSilent(["kill-session", "-t", tmuxName]);
282
+ // Update stored state
283
+ session.status = "terminated";
284
+ session.updatedAt = nowISO();
285
+ session.terminal = undefined;
286
+ await this.saveSession(session);
287
+ this.log.info("Tmux session terminated", { sessionId });
288
+ }
289
+ async getInfo(sessionId) {
290
+ const sessions = await this.loadSessions();
291
+ const session = sessions.find((s) => s.id === sessionId) ?? null;
292
+ if (session) {
293
+ // Refresh live status from tmux
294
+ const tmuxName = this.getTmuxName(session);
295
+ const exists = tmuxExecSilent(["has-session", "-t", tmuxName]);
296
+ if (!exists && session.status === "active") {
297
+ session.status = "inactive";
298
+ session.updatedAt = nowISO();
299
+ await this.saveSession(session);
300
+ }
301
+ else if (exists && session.status === "inactive") {
302
+ session.status = "active";
303
+ session.updatedAt = nowISO();
304
+ await this.saveSession(session);
305
+ }
306
+ // Attach terminal info if running
307
+ const termInfo = this.getRunningTerminalInfo(sessionId);
308
+ if (termInfo) {
309
+ session.terminal = termInfo;
310
+ }
311
+ }
312
+ return session;
313
+ }
314
+ async list() {
315
+ const sessions = await this.loadSessions();
316
+ // Refresh statuses
317
+ for (const session of sessions) {
318
+ if (session.status === "terminated")
319
+ continue;
320
+ const tmuxName = this.getTmuxName(session);
321
+ const exists = tmuxExecSilent(["has-session", "-t", tmuxName]);
322
+ if (!exists && session.status === "active") {
323
+ session.status = "inactive";
324
+ session.updatedAt = nowISO();
325
+ }
326
+ else if (exists && session.status !== "active") {
327
+ session.status = "active";
328
+ session.updatedAt = nowISO();
329
+ }
330
+ // Attach terminal info
331
+ const termInfo = this.getRunningTerminalInfo(session.id);
332
+ if (termInfo) {
333
+ session.terminal = termInfo;
334
+ }
335
+ }
336
+ await this.saveSessions(sessions);
337
+ return sessions;
338
+ }
339
+ // -----------------------------------------------------------------------
340
+ // SessionProvider — command / keys / interrupt / capture
341
+ // -----------------------------------------------------------------------
342
+ async sendCommand(sessionId, command) {
343
+ const session = await this.requireSession(sessionId);
344
+ const tmuxName = this.getTmuxName(session);
345
+ this.log.debug("Sending command", { sessionId, command });
346
+ try {
347
+ tmuxExec(["send-keys", "-t", tmuxName, command, "Enter"]);
348
+ }
349
+ catch (err) {
350
+ this.log.error("Failed to send command", {
351
+ sessionId,
352
+ error: String(err),
353
+ });
354
+ throw new Error(`Failed to send command to session ${sessionId}: ${err}`);
355
+ }
356
+ }
357
+ async sendKeys(sessionId, keys) {
358
+ const session = await this.requireSession(sessionId);
359
+ const tmuxName = this.getTmuxName(session);
360
+ this.log.debug("Sending keys", { sessionId, keys });
361
+ try {
362
+ tmuxExec(["send-keys", "-t", tmuxName, keys]);
363
+ }
364
+ catch (err) {
365
+ this.log.error("Failed to send keys", {
366
+ sessionId,
367
+ error: String(err),
368
+ });
369
+ throw new Error(`Failed to send keys to session ${sessionId}: ${err}`);
370
+ }
371
+ }
372
+ async sendInterrupt(sessionId) {
373
+ const session = await this.requireSession(sessionId);
374
+ const tmuxName = this.getTmuxName(session);
375
+ this.log.debug("Sending interrupt (C-c)", { sessionId });
376
+ try {
377
+ tmuxExec(["send-keys", "-t", tmuxName, "C-c"]);
378
+ }
379
+ catch (err) {
380
+ this.log.error("Failed to send interrupt", {
381
+ sessionId,
382
+ error: String(err),
383
+ });
384
+ throw new Error(`Failed to send interrupt to session ${sessionId}: ${err}`);
385
+ }
386
+ }
387
+ async captureOutput(sessionId) {
388
+ const session = await this.requireSession(sessionId);
389
+ const tmuxName = this.getTmuxName(session);
390
+ this.log.debug("Capturing output", { sessionId });
391
+ try {
392
+ const output = tmuxExec(["capture-pane", "-t", tmuxName, "-p"]);
393
+ return output;
394
+ }
395
+ catch (err) {
396
+ this.log.error("Failed to capture output", {
397
+ sessionId,
398
+ error: String(err),
399
+ });
400
+ throw new Error(`Failed to capture output from session ${sessionId}: ${err}`);
401
+ }
402
+ }
403
+ // -----------------------------------------------------------------------
404
+ // SessionProvider — rename / toggleMouse / getTerminationStatus
405
+ // -----------------------------------------------------------------------
406
+ async rename(sessionId, newName) {
407
+ const session = await this.requireSession(sessionId);
408
+ const tmuxName = this.getTmuxName(session);
409
+ this.log.info("Renaming session", {
410
+ sessionId,
411
+ from: session.name,
412
+ to: newName,
413
+ });
414
+ try {
415
+ // Rename the display name in our records (not the tmux session name,
416
+ // which is vibe-{id} and must stay stable for lookups)
417
+ session.name = newName;
418
+ session.updatedAt = nowISO();
419
+ await this.saveSession(session);
420
+ }
421
+ catch (err) {
422
+ this.log.error("Failed to rename session", {
423
+ sessionId,
424
+ error: String(err),
425
+ });
426
+ throw new Error(`Failed to rename session ${sessionId}: ${err}`);
427
+ }
428
+ // Also rename the tmux session for cosmetic purposes
429
+ const newTmuxName = `vibe-${session.id}`;
430
+ tmuxExecSilent(["rename-session", "-t", tmuxName, newTmuxName]);
431
+ }
432
+ async toggleMouse(sessionId) {
433
+ const session = await this.requireSession(sessionId);
434
+ const tmuxName = this.getTmuxName(session);
435
+ // Read current mouse setting
436
+ let mouseOn = false;
437
+ try {
438
+ const value = tmuxExec([
439
+ "show-options",
440
+ "-t",
441
+ tmuxName,
442
+ "-v",
443
+ "mouse",
444
+ ]);
445
+ mouseOn = value.trim() === "on";
446
+ }
447
+ catch {
448
+ // Default to off if we can't read
449
+ mouseOn = false;
450
+ }
451
+ const newState = mouseOn ? "off" : "on";
452
+ tmuxExecSilent(["set", "-t", tmuxName, "mouse", newState]);
453
+ this.log.debug("Toggled mouse", { sessionId, mouse: newState });
454
+ return newState === "on";
455
+ }
456
+ async getTerminationStatus(sessionId) {
457
+ const sessions = await this.loadSessions();
458
+ const session = sessions.find((s) => s.id === sessionId);
459
+ if (!session) {
460
+ return { terminated: true, exists: false };
461
+ }
462
+ const tmuxName = this.getTmuxName(session);
463
+ const exists = tmuxExecSilent(["has-session", "-t", tmuxName]);
464
+ return {
465
+ terminated: session.status === "terminated" || !exists,
466
+ exists,
467
+ };
468
+ }
469
+ // -----------------------------------------------------------------------
470
+ // SessionProvider — terminal (ttyd) management
471
+ // -----------------------------------------------------------------------
472
+ async getTerminalInfo(sessionId) {
473
+ return this.getRunningTerminalInfo(sessionId);
474
+ }
475
+ async startTerminal(sessionId, port) {
476
+ const session = await this.requireSession(sessionId);
477
+ const tmuxName = this.getTmuxName(session);
478
+ // If already running, return existing info
479
+ const existing = this.getRunningTerminalInfo(sessionId);
480
+ if (existing) {
481
+ this.log.debug("Terminal already running", { sessionId, ...existing });
482
+ return existing;
483
+ }
484
+ // Find available port
485
+ const assignedPort = port ?? (await findAvailablePort(TTYD_BASE_PORT));
486
+ this.log.info("Starting ttyd terminal", {
487
+ sessionId,
488
+ tmuxName,
489
+ port: assignedPort,
490
+ });
491
+ // Spawn ttyd process
492
+ const child = Bun.spawn([
493
+ "ttyd",
494
+ "--writable",
495
+ "--port",
496
+ String(assignedPort),
497
+ "tmux",
498
+ "attach",
499
+ "-t",
500
+ tmuxName,
501
+ ], {
502
+ stdout: "ignore",
503
+ stderr: "ignore",
504
+ stdin: "ignore",
505
+ });
506
+ if (!child.pid) {
507
+ throw new Error("Failed to start ttyd — no PID returned");
508
+ }
509
+ // Give ttyd a moment to bind the port
510
+ await sleep(500);
511
+ // Store references
512
+ this.ttydProcesses.set(sessionId, child);
513
+ this.ttydPorts.set(sessionId, assignedPort);
514
+ const terminalInfo = {
515
+ url: `http://localhost:${assignedPort}`,
516
+ port: assignedPort,
517
+ pid: child.pid,
518
+ };
519
+ // Update session record with terminal info
520
+ session.terminal = terminalInfo;
521
+ session.updatedAt = nowISO();
522
+ await this.saveSession(session);
523
+ this.log.info("ttyd terminal started", {
524
+ sessionId,
525
+ port: assignedPort,
526
+ pid: child.pid,
527
+ });
528
+ return terminalInfo;
529
+ }
530
+ async stopTerminal(sessionId) {
531
+ const child = this.ttydProcesses.get(sessionId);
532
+ if (!child) {
533
+ this.log.debug("No ttyd process found for session", { sessionId });
534
+ return;
535
+ }
536
+ this.log.info("Stopping ttyd terminal", {
537
+ sessionId,
538
+ pid: child.pid,
539
+ });
540
+ if (child.pid) {
541
+ await gracefulKill(child.pid);
542
+ }
543
+ this.ttydProcesses.delete(sessionId);
544
+ this.ttydPorts.delete(sessionId);
545
+ // Clear terminal from session record
546
+ const session = await this.getInfo(sessionId);
547
+ if (session) {
548
+ session.terminal = undefined;
549
+ session.updatedAt = nowISO();
550
+ await this.saveSession(session);
551
+ }
552
+ this.log.info("ttyd terminal stopped", { sessionId });
553
+ }
554
+ // -----------------------------------------------------------------------
555
+ // SessionProvider — system-level listing and bulk operations
556
+ // -----------------------------------------------------------------------
557
+ async listSystemSessions() {
558
+ try {
559
+ const raw = tmuxExec([
560
+ "list-sessions",
561
+ "-F",
562
+ "#{session_id}:#{session_name}:#{session_windows}:#{session_attached}:#{session_created}",
563
+ ]);
564
+ if (!raw)
565
+ return [];
566
+ return raw.split("\n").map((line) => {
567
+ const [id, name, windows, attached, created] = line.split(":");
568
+ return {
569
+ id: id ?? "",
570
+ name: name ?? "",
571
+ windows: parseInt(windows ?? "0", 10),
572
+ attached: attached === "1",
573
+ createdAt: created
574
+ ? new Date(parseInt(created, 10) * 1000).toISOString()
575
+ : undefined,
576
+ };
577
+ });
578
+ }
579
+ catch {
580
+ // tmux list-sessions fails when there are no sessions
581
+ return [];
582
+ }
583
+ }
584
+ async listSystemTerminals() {
585
+ const terminals = [];
586
+ for (const [sessionId, child] of this.ttydProcesses) {
587
+ const port = this.ttydPorts.get(sessionId);
588
+ if (child.pid && port !== undefined) {
589
+ terminals.push({
590
+ pid: child.pid,
591
+ port,
592
+ sessionId,
593
+ });
594
+ }
595
+ }
596
+ // Also look for any orphaned ttyd processes via pgrep
597
+ try {
598
+ const raw = execSync("pgrep -a ttyd", {
599
+ encoding: "utf-8",
600
+ timeout: 5000,
601
+ stdio: ["pipe", "pipe", "pipe"],
602
+ }).trim();
603
+ if (raw) {
604
+ for (const line of raw.split("\n")) {
605
+ const parts = line.trim().split(/\s+/);
606
+ const pid = parseInt(parts[0] ?? "0", 10);
607
+ if (!pid)
608
+ continue;
609
+ // Skip already-tracked processes
610
+ const alreadyTracked = [...this.ttydProcesses.values()].some((p) => p.pid === pid);
611
+ if (alreadyTracked)
612
+ continue;
613
+ // Try to extract port from command line
614
+ const portIdx = parts.indexOf("--port");
615
+ const port = portIdx !== -1 ? parseInt(parts[portIdx + 1] ?? "0", 10) : 0;
616
+ terminals.push({ pid, port: port || 0 });
617
+ }
618
+ }
619
+ }
620
+ catch {
621
+ // pgrep returns non-zero when no processes found — that's fine
622
+ }
623
+ return terminals;
624
+ }
625
+ async bulkKillSystemSessions(sessionIds) {
626
+ let killed = 0;
627
+ let failed = 0;
628
+ for (const sid of sessionIds) {
629
+ const success = tmuxExecSilent(["kill-session", "-t", sid]);
630
+ if (success) {
631
+ killed++;
632
+ }
633
+ else {
634
+ failed++;
635
+ }
636
+ }
637
+ this.log.info("Bulk kill system sessions", { killed, failed });
638
+ return { killed, failed };
639
+ }
640
+ async bulkKillSystemTerminals(pids) {
641
+ let killed = 0;
642
+ let failed = 0;
643
+ const killPromises = pids.map(async (pid) => {
644
+ try {
645
+ await gracefulKill(pid);
646
+ killed++;
647
+ // Remove from tracked processes if present
648
+ for (const [sessionId, child] of this.ttydProcesses) {
649
+ if (child.pid === pid) {
650
+ this.ttydProcesses.delete(sessionId);
651
+ this.ttydPorts.delete(sessionId);
652
+ break;
653
+ }
654
+ }
655
+ }
656
+ catch {
657
+ failed++;
658
+ }
659
+ });
660
+ await Promise.allSettled(killPromises);
661
+ this.log.info("Bulk kill system terminals", { killed, failed });
662
+ return { killed, failed };
663
+ }
664
+ // -----------------------------------------------------------------------
665
+ // SessionProvider — health / project filter / cleanup
666
+ // -----------------------------------------------------------------------
667
+ async healthCheck() {
668
+ let tmuxOk = false;
669
+ let tmuxVersion = "";
670
+ let sessionCount = 0;
671
+ const terminalCount = this.ttydProcesses.size;
672
+ try {
673
+ tmuxVersion = tmuxExec(["-V"]);
674
+ tmuxOk = true;
675
+ }
676
+ catch {
677
+ return {
678
+ ok: false,
679
+ sessions: 0,
680
+ terminals: terminalCount,
681
+ message: "tmux is not available",
682
+ };
683
+ }
684
+ try {
685
+ const sysSessions = await this.listSystemSessions();
686
+ sessionCount = sysSessions.length;
687
+ }
688
+ catch {
689
+ // Ignore — zero sessions
690
+ }
691
+ // Check ttyd availability
692
+ let ttydOk = false;
693
+ try {
694
+ execSync("which ttyd", {
695
+ encoding: "utf-8",
696
+ timeout: 5000,
697
+ stdio: ["pipe", "pipe", "pipe"],
698
+ });
699
+ ttydOk = true;
700
+ }
701
+ catch {
702
+ // ttyd not found
703
+ }
704
+ const messages = [tmuxVersion];
705
+ if (!ttydOk) {
706
+ messages.push("ttyd not found — web terminals unavailable");
707
+ }
708
+ return {
709
+ ok: tmuxOk,
710
+ sessions: sessionCount,
711
+ terminals: terminalCount,
712
+ message: messages.join("; "),
713
+ };
714
+ }
715
+ async getSessionsByProject(projectId) {
716
+ const sessions = await this.list();
717
+ return sessions.filter((s) => s.projectId === projectId);
718
+ }
719
+ async cleanup() {
720
+ this.log.info("Running cleanup");
721
+ const sessions = await this.loadSessions();
722
+ let cleaned = 0;
723
+ const kept = [];
724
+ for (const session of sessions) {
725
+ const tmuxName = this.getTmuxName(session);
726
+ const exists = tmuxExecSilent(["has-session", "-t", tmuxName]);
727
+ if (session.status === "terminated" || !exists) {
728
+ // Stop terminal if somehow still running
729
+ if (this.ttydProcesses.has(session.id)) {
730
+ await this.stopTerminal(session.id);
731
+ }
732
+ // Kill the tmux session if it still exists but was marked terminated
733
+ if (exists && session.status === "terminated") {
734
+ tmuxExecSilent(["kill-session", "-t", tmuxName]);
735
+ }
736
+ cleaned++;
737
+ this.log.debug("Cleaned session", {
738
+ id: session.id,
739
+ name: session.name,
740
+ });
741
+ }
742
+ else {
743
+ kept.push(session);
744
+ }
745
+ }
746
+ await this.saveSessions(kept);
747
+ this.log.info("Cleanup complete", { cleaned, remaining: kept.length });
748
+ return { cleaned };
749
+ }
750
+ // -----------------------------------------------------------------------
751
+ // Private helpers — storage
752
+ // -----------------------------------------------------------------------
753
+ /**
754
+ * Load all session records from persistent storage.
755
+ */
756
+ async loadSessions() {
757
+ try {
758
+ const raw = await this.storage.get(`${STORAGE_NAMESPACE}:${STORAGE_KEY_SESSIONS}`);
759
+ if (!raw)
760
+ return [];
761
+ return JSON.parse(raw);
762
+ }
763
+ catch (err) {
764
+ this.log.error("Failed to load sessions from storage", {
765
+ error: String(err),
766
+ });
767
+ return [];
768
+ }
769
+ }
770
+ /**
771
+ * Save the full session list to persistent storage.
772
+ */
773
+ async saveSessions(sessions) {
774
+ try {
775
+ await this.storage.set(`${STORAGE_NAMESPACE}:${STORAGE_KEY_SESSIONS}`, JSON.stringify(sessions));
776
+ }
777
+ catch (err) {
778
+ this.log.error("Failed to save sessions to storage", {
779
+ error: String(err),
780
+ });
781
+ }
782
+ }
783
+ /**
784
+ * Save (upsert) a single session record.
785
+ */
786
+ async saveSession(session) {
787
+ const sessions = await this.loadSessions();
788
+ const idx = sessions.findIndex((s) => s.id === session.id);
789
+ if (idx >= 0) {
790
+ sessions[idx] = session;
791
+ }
792
+ else {
793
+ sessions.push(session);
794
+ }
795
+ await this.saveSessions(sessions);
796
+ }
797
+ // -----------------------------------------------------------------------
798
+ // Private helpers — tmux utilities
799
+ // -----------------------------------------------------------------------
800
+ /**
801
+ * Extract the tmux session name from a SessionInfo record.
802
+ * The tmux session name is stored in metadata.tmuxSessionName or
803
+ * defaults to `vibe-{id}`.
804
+ */
805
+ getTmuxName(session) {
806
+ const meta = session.metadata;
807
+ if (meta && typeof meta.tmuxSessionName === "string") {
808
+ return meta.tmuxSessionName;
809
+ }
810
+ return `vibe-${session.id}`;
811
+ }
812
+ /**
813
+ * Get the PID of the first pane in a tmux session.
814
+ */
815
+ getSessionPanePid(tmuxName) {
816
+ try {
817
+ const raw = tmuxExec([
818
+ "list-panes",
819
+ "-t",
820
+ tmuxName,
821
+ "-F",
822
+ "#{pane_pid}",
823
+ ]);
824
+ const pid = parseInt(raw.split("\n")[0] ?? "", 10);
825
+ return isNaN(pid) ? null : pid;
826
+ }
827
+ catch {
828
+ return null;
829
+ }
830
+ }
831
+ /**
832
+ * Look up a session by ID and throw if not found.
833
+ */
834
+ async requireSession(sessionId) {
835
+ const session = await this.getInfo(sessionId);
836
+ if (!session) {
837
+ throw new Error(`Session not found: ${sessionId}`);
838
+ }
839
+ if (session.status === "terminated") {
840
+ throw new Error(`Session is terminated: ${sessionId}`);
841
+ }
842
+ return session;
843
+ }
844
+ /**
845
+ * Get TerminalInfo for a session if ttyd is currently running.
846
+ */
847
+ getRunningTerminalInfo(sessionId) {
848
+ const child = this.ttydProcesses.get(sessionId);
849
+ const port = this.ttydPorts.get(sessionId);
850
+ if (!child || !child.pid || port === undefined) {
851
+ return null;
852
+ }
853
+ // Verify process is still alive
854
+ if (!isProcessAlive(child.pid)) {
855
+ this.ttydProcesses.delete(sessionId);
856
+ this.ttydPorts.delete(sessionId);
857
+ return null;
858
+ }
859
+ return {
860
+ url: `http://localhost:${port}`,
861
+ port,
862
+ pid: child.pid,
863
+ };
864
+ }
865
+ /**
866
+ * Reconcile persisted session records against actual tmux state.
867
+ * Marks sessions as inactive/terminated if their tmux session is gone.
868
+ */
869
+ async reconcileSessions() {
870
+ const sessions = await this.loadSessions();
871
+ let changed = false;
872
+ for (const session of sessions) {
873
+ if (session.status === "terminated")
874
+ continue;
875
+ const tmuxName = this.getTmuxName(session);
876
+ const exists = tmuxExecSilent(["has-session", "-t", tmuxName]);
877
+ if (!exists && session.status === "active") {
878
+ session.status = "inactive";
879
+ session.updatedAt = nowISO();
880
+ session.terminal = undefined;
881
+ changed = true;
882
+ this.log.info("Reconciled stale session as inactive", {
883
+ id: session.id,
884
+ name: session.name,
885
+ });
886
+ }
887
+ }
888
+ if (changed) {
889
+ await this.saveSessions(sessions);
890
+ }
891
+ }
892
+ }
893
+ // ---------------------------------------------------------------------------
894
+ // Plugin export
895
+ // ---------------------------------------------------------------------------
896
+ const provider = new TmuxSessionProvider();
897
+ const vibePlugin = {
898
+ name: "@burdenoff/vibe-plugin-session-tmux",
899
+ version: "1.0.0",
900
+ description: "Tmux + ttyd session provider — manages terminal sessions via tmux and exposes web terminals via ttyd",
901
+ tags: ["backend", "provider"],
902
+ providers: {
903
+ session: provider,
904
+ },
905
+ async onServerStart(services) {
906
+ await provider.init(services);
907
+ },
908
+ async onServerStop() {
909
+ await provider.shutdown();
910
+ },
911
+ };
912
+ export { vibePlugin };
913
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,72 @@
1
+ {
2
+ "name": "@burdenoff/vibe-plugin-session-tmux",
3
+ "version": "2.0.0",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "description": "Tmux + ttyd session provider plugin for VibeControls Agent",
7
+ "engines": {
8
+ "bun": ">=1.3.0"
9
+ },
10
+ "author": {
11
+ "name": "Vignesh T.V",
12
+ "email": "vignesh@burdenoff.com",
13
+ "url": "https://github.com/tvvignesh"
14
+ },
15
+ "license": "SEE LICENSE IN LICENSE",
16
+ "scripts": {
17
+ "build": "tsc",
18
+ "dev": "tsc --watch",
19
+ "lint": "eslint ./src",
20
+ "format": "bunx prettier . --write",
21
+ "format:check": "bunx prettier . --check",
22
+ "type:check": "tsc --noEmit",
23
+ "clean": "rimraf dist",
24
+ "prebuild": "bun run clean",
25
+ "prepublishOnly": "bun run build",
26
+ "sanity": "bun run format:check && bun run lint && bun run type:check && bun run build"
27
+ },
28
+ "dependencies": {},
29
+ "devDependencies": {
30
+ "@types/bun": "^1.3.9",
31
+ "@types/node": "^22.0.0",
32
+ "eslint": "^9.30.1",
33
+ "prettier": "^3.6.2",
34
+ "rimraf": "^6.0.1",
35
+ "typescript": "^5.9.3"
36
+ },
37
+ "peerDependencies": {
38
+ "@burdenoff/vibe-agent": ">=2.0.0"
39
+ },
40
+ "peerDependenciesMeta": {
41
+ "@burdenoff/vibe-agent": {
42
+ "optional": true
43
+ }
44
+ },
45
+ "keywords": [
46
+ "vibecontrols",
47
+ "vibe",
48
+ "vibe-plugin",
49
+ "tmux",
50
+ "ttyd",
51
+ "session",
52
+ "terminal",
53
+ "bun"
54
+ ],
55
+ "repository": {
56
+ "type": "git",
57
+ "url": "git+https://github.com/algoshred/vibe-plugin-session-tmux.git"
58
+ },
59
+ "bugs": {
60
+ "url": "https://github.com/algoshred/vibe-plugin-session-tmux/issues"
61
+ },
62
+ "homepage": "https://vibecontrols.com",
63
+ "publishConfig": {
64
+ "access": "public",
65
+ "registry": "https://registry.npmjs.org/"
66
+ },
67
+ "files": [
68
+ "dist/**/*",
69
+ "README.md",
70
+ "LICENSE"
71
+ ]
72
+ }