remote-cli-agent 0.1.0 → 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/terminal.d.ts +1 -2
- package/dist/terminal.js +85 -19
- package/package.json +2 -1
package/dist/terminal.d.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { IPty } from 'node-pty';
|
|
2
1
|
export interface TerminalSession {
|
|
3
2
|
id: string;
|
|
4
3
|
name: string;
|
|
5
4
|
command?: string;
|
|
6
|
-
pty?:
|
|
5
|
+
pty?: any;
|
|
7
6
|
tmuxSession?: string;
|
|
8
7
|
}
|
|
9
8
|
export declare function setOutputHandler(handler: (sessionId: string, data: string) => void): void;
|
package/dist/terminal.js
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
import { spawn as
|
|
2
|
-
import { execSync } from 'child_process';
|
|
1
|
+
import { execSync, spawn as childSpawn } from 'child_process';
|
|
3
2
|
import { v4 as uuidv4 } from 'uuid';
|
|
3
|
+
// Try to load node-pty, fall back to child_process
|
|
4
|
+
let nodePtySpawn;
|
|
5
|
+
try {
|
|
6
|
+
const pty = await import('node-pty');
|
|
7
|
+
nodePtySpawn = pty.spawn;
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
nodePtySpawn = null;
|
|
11
|
+
}
|
|
4
12
|
// Active sessions
|
|
5
13
|
const sessions = new Map();
|
|
6
14
|
// Callbacks
|
|
@@ -39,15 +47,27 @@ export function attachTmuxSession(sessionName) {
|
|
|
39
47
|
return null;
|
|
40
48
|
}
|
|
41
49
|
const id = uuidv4();
|
|
42
|
-
const shell = process.env.SHELL || '/bin/
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
const shell = process.env.SHELL || '/bin/zsh';
|
|
51
|
+
const tmuxArgs = ['-c', `tmux attach-session -t ${sessionName}`];
|
|
52
|
+
let pty;
|
|
53
|
+
if (nodePtySpawn) {
|
|
54
|
+
try {
|
|
55
|
+
pty = nodePtySpawn(shell, tmuxArgs, {
|
|
56
|
+
name: 'xterm-256color',
|
|
57
|
+
cols: 80,
|
|
58
|
+
rows: 24,
|
|
59
|
+
cwd: process.env.HOME || '/',
|
|
60
|
+
env: process.env
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
console.warn('node-pty spawn failed, falling back:', err.message);
|
|
65
|
+
pty = null;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (!pty) {
|
|
69
|
+
pty = createScriptPty(shell, tmuxArgs);
|
|
70
|
+
}
|
|
51
71
|
const session = {
|
|
52
72
|
id,
|
|
53
73
|
name: `tmux: ${sessionName}`,
|
|
@@ -69,16 +89,29 @@ export function attachTmuxSession(sessionName) {
|
|
|
69
89
|
// Spawn a new PTY session
|
|
70
90
|
export function spawnSession(command) {
|
|
71
91
|
const id = uuidv4();
|
|
72
|
-
const shell = process.env.SHELL || '/bin/
|
|
92
|
+
const shell = process.env.SHELL || '/bin/zsh';
|
|
73
93
|
const cmd = command || shell;
|
|
74
94
|
const args = command ? ['-c', command] : [];
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
95
|
+
let pty;
|
|
96
|
+
if (nodePtySpawn) {
|
|
97
|
+
try {
|
|
98
|
+
pty = nodePtySpawn(shell, args, {
|
|
99
|
+
name: 'xterm-256color',
|
|
100
|
+
cols: 80,
|
|
101
|
+
rows: 24,
|
|
102
|
+
cwd: process.env.HOME || '/',
|
|
103
|
+
env: process.env
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
console.warn('node-pty spawn failed, falling back to child_process:', err.message);
|
|
108
|
+
pty = null;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
if (!pty) {
|
|
112
|
+
// Fallback: use child_process with script command to get a PTY
|
|
113
|
+
pty = createScriptPty(shell, args);
|
|
114
|
+
}
|
|
82
115
|
const session = {
|
|
83
116
|
id,
|
|
84
117
|
name: command || shell,
|
|
@@ -91,6 +124,39 @@ export function spawnSession(command) {
|
|
|
91
124
|
console.log(`Spawned session "${session.name}" with id ${id}`);
|
|
92
125
|
return session;
|
|
93
126
|
}
|
|
127
|
+
// Fallback PTY using macOS/Linux `script` command
|
|
128
|
+
function createScriptPty(shell, args) {
|
|
129
|
+
const fullCmd = args.length > 0 ? `${shell} ${args.join(' ')}` : shell;
|
|
130
|
+
// Use `script` to allocate a PTY
|
|
131
|
+
const proc = childSpawn('script', ['-q', '/dev/null', shell, ...args], {
|
|
132
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
133
|
+
env: { ...process.env, TERM: 'xterm-256color' },
|
|
134
|
+
cwd: process.env.HOME || '/',
|
|
135
|
+
});
|
|
136
|
+
const dataHandlers = [];
|
|
137
|
+
const exitHandlers = [];
|
|
138
|
+
proc.stdout?.on('data', (data) => {
|
|
139
|
+
for (const h of dataHandlers)
|
|
140
|
+
h(data.toString());
|
|
141
|
+
});
|
|
142
|
+
proc.stderr?.on('data', (data) => {
|
|
143
|
+
for (const h of dataHandlers)
|
|
144
|
+
h(data.toString());
|
|
145
|
+
});
|
|
146
|
+
proc.on('exit', (code) => {
|
|
147
|
+
for (const h of exitHandlers)
|
|
148
|
+
h({ exitCode: code ?? 0 });
|
|
149
|
+
});
|
|
150
|
+
return {
|
|
151
|
+
onData(handler) { dataHandlers.push(handler); },
|
|
152
|
+
onExit(handler) { exitHandlers.push(handler); },
|
|
153
|
+
write(data) { proc.stdin?.write(data); },
|
|
154
|
+
resize(_cols, _rows) { },
|
|
155
|
+
kill() { proc.kill(); },
|
|
156
|
+
cols: 80,
|
|
157
|
+
rows: 24,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
94
160
|
function setupPtyHandlers(session) {
|
|
95
161
|
if (!session.pty)
|
|
96
162
|
return;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "remote-cli-agent",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"remote-cli": "./dist/index.js"
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
"build": "tsc",
|
|
10
10
|
"start": "node dist/index.js",
|
|
11
11
|
"dev": "tsx src/index.ts",
|
|
12
|
+
"postinstall": "node -e \"const fs=require('fs'),p=require('path'),d=p.join(__dirname,'node_modules','node-pty','prebuilds');try{fs.readdirSync(d).forEach(a=>{const h=p.join(d,a,'spawn-helper');try{fs.chmodSync(h,0o755);console.log('Fixed permissions:',h)}catch{}})}catch{}\"",
|
|
12
13
|
"prepublishOnly": "npm run build"
|
|
13
14
|
},
|
|
14
15
|
"dependencies": {
|