@dmsdc-ai/aigentry-telepty 0.1.75 → 0.1.77
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/.claude/commands/telepty-inject.md +45 -7
- package/cli.js +559 -59
- package/cross-machine.js +68 -8
- package/daemon.js +697 -441
- package/package.json +1 -1
- package/session-routing.js +7 -5
- package/shared-context.js +147 -0
package/cross-machine.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const { execSync, spawn } = require('child_process');
|
|
3
|
+
const { execSync, spawn, spawnSync } = require('child_process');
|
|
4
4
|
const fs = require('fs');
|
|
5
5
|
const path = require('path');
|
|
6
6
|
const os = require('os');
|
|
7
|
+
const { getSharedContextPromptPath } = require('./shared-context');
|
|
7
8
|
|
|
8
9
|
const PEERS_PATH = path.join(os.homedir(), '.telepty', 'peers.json');
|
|
9
10
|
const CONTROL_DIR = path.join(os.homedir(), '.telepty', 'ssh');
|
|
@@ -30,6 +31,35 @@ function savePeers(data) {
|
|
|
30
31
|
// In-memory active peers
|
|
31
32
|
const activePeers = new Map(); // name -> { target, controlSocket, connectedAt, machineId }
|
|
32
33
|
|
|
34
|
+
function shellQuote(value) {
|
|
35
|
+
return `'${String(value).replace(/'/g, `'\\''`)}'`;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function runRemoteCommand(peer, remoteCommand, options = {}) {
|
|
39
|
+
const result = spawnSync('ssh', [
|
|
40
|
+
'-o', `ControlPath=${peer.controlSocket}`,
|
|
41
|
+
peer.target,
|
|
42
|
+
remoteCommand
|
|
43
|
+
], {
|
|
44
|
+
timeout: options.timeout ?? 15000,
|
|
45
|
+
encoding: 'utf8',
|
|
46
|
+
input: options.input,
|
|
47
|
+
stdio: ['pipe', 'pipe', 'pipe']
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
if (result.error) {
|
|
51
|
+
throw result.error;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (result.status !== 0) {
|
|
55
|
+
const stderr = String(result.stderr || '').trim();
|
|
56
|
+
const stdout = String(result.stdout || '').trim();
|
|
57
|
+
throw new Error(stderr || stdout || `Remote command failed with exit code ${result.status}`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return String(result.stdout || '');
|
|
61
|
+
}
|
|
62
|
+
|
|
33
63
|
/**
|
|
34
64
|
* Connect to a remote machine via SSH ControlMaster.
|
|
35
65
|
*/
|
|
@@ -174,19 +204,48 @@ function remoteInject(name, sessionId, prompt, options = {}) {
|
|
|
174
204
|
if (!peer) return { success: false, error: `Not connected to ${name}` };
|
|
175
205
|
|
|
176
206
|
try {
|
|
177
|
-
const
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
);
|
|
207
|
+
const parts = ['telepty', 'inject'];
|
|
208
|
+
if (options.ref) parts.push('--ref');
|
|
209
|
+
if (options.no_enter) parts.push('--no-enter');
|
|
210
|
+
if (options.from) parts.push('--from', options.from);
|
|
211
|
+
if (options.reply_to) parts.push('--reply-to', options.reply_to);
|
|
212
|
+
if (options.reply_expected) parts.push('--reply-expected');
|
|
213
|
+
parts.push(sessionId, prompt);
|
|
214
|
+
|
|
215
|
+
const remoteCommand = parts.map(shellQuote).join(' ');
|
|
216
|
+
runRemoteCommand(peer, remoteCommand, { timeout: 15000 });
|
|
184
217
|
return { success: true };
|
|
185
218
|
} catch (err) {
|
|
186
219
|
return { success: false, error: err.message };
|
|
187
220
|
}
|
|
188
221
|
}
|
|
189
222
|
|
|
223
|
+
function remoteEnsureSharedContext(name, descriptor) {
|
|
224
|
+
const peer = activePeers.get(name);
|
|
225
|
+
if (!peer) return { success: false, error: `Not connected to ${name}` };
|
|
226
|
+
|
|
227
|
+
try {
|
|
228
|
+
const remotePath = `$HOME/.telepty/shared/${descriptor.fileName}`;
|
|
229
|
+
const remoteCommand = [
|
|
230
|
+
'sh',
|
|
231
|
+
'-lc',
|
|
232
|
+
shellQuote(`umask 077 && mkdir -p "$HOME/.telepty/shared" && cat > "${remotePath}"`)
|
|
233
|
+
].join(' ');
|
|
234
|
+
|
|
235
|
+
runRemoteCommand(peer, remoteCommand, {
|
|
236
|
+
timeout: 15000,
|
|
237
|
+
input: descriptor.content
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
return {
|
|
241
|
+
success: true,
|
|
242
|
+
promptPath: getSharedContextPromptPath(descriptor.fileName)
|
|
243
|
+
};
|
|
244
|
+
} catch (err) {
|
|
245
|
+
return { success: false, error: err.message };
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
190
249
|
/**
|
|
191
250
|
* Spawn an interactive SSH attach to a remote session.
|
|
192
251
|
* Returns the child process for stdin/stdout piping.
|
|
@@ -261,6 +320,7 @@ module.exports = {
|
|
|
261
320
|
listRemoteSessions,
|
|
262
321
|
discoverAllRemoteSessions,
|
|
263
322
|
remoteInject,
|
|
323
|
+
remoteEnsureSharedContext,
|
|
264
324
|
remoteAttach,
|
|
265
325
|
findSessionPeer,
|
|
266
326
|
PEERS_PATH
|