49 lines
1.5 KiB
TypeScript
49 lines
1.5 KiB
TypeScript
import * as pty from 'node-pty';
|
|
import type { IPty } from 'node-pty';
|
|
|
|
export interface AttachPtyOptions {
|
|
sessionName: string;
|
|
projectRoot: string;
|
|
cols: number;
|
|
rows: number;
|
|
tmuxConfPath: string;
|
|
}
|
|
|
|
function cleanEnv(): { [key: string]: string } {
|
|
const out: { [key: string]: string } = {};
|
|
for (const [k, v] of Object.entries(process.env)) {
|
|
if (typeof v === 'string') out[k] = v;
|
|
}
|
|
out['TERM'] = 'screen-256color';
|
|
return out;
|
|
}
|
|
|
|
// v1.10.8c: no `-d` (multi-attach friendly — boolab pattern). With per-pane
|
|
// tmux sessions, dropping `-d` means multiple browser tabs viewing the same
|
|
// pane share one tmux session as N clients; tmux fans I/O at the session
|
|
// layer just like boolab's backend. The earlier `-d` flag detached EVERY
|
|
// other client of the session — across windows — which caused the
|
|
// "[detached] from session" bug whenever a new pane attached to a chat
|
|
// session that already had another pane open.
|
|
//
|
|
// Tmux server + session persist across PTY exits, so a refresh resumes with
|
|
// full scrollback. Explicit destroy happens via the /kill route (called from
|
|
// the frontend when the user closes a pane).
|
|
export function attachPty(opts: AttachPtyOptions): IPty {
|
|
return pty.spawn(
|
|
'tmux',
|
|
[
|
|
'-f', opts.tmuxConfPath,
|
|
'attach-session',
|
|
'-t', opts.sessionName,
|
|
],
|
|
{
|
|
name: 'xterm-256color',
|
|
cols: opts.cols,
|
|
rows: opts.rows,
|
|
cwd: opts.projectRoot,
|
|
env: cleanEnv(),
|
|
},
|
|
);
|
|
}
|