@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/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 escaped = prompt.replace(/'/g, "'\\''");
178
- const fromFlag = options.from ? `--from '${options.from}'` : '';
179
- const noEnterFlag = options.no_enter ? '--no-enter' : '';
180
- execSync(
181
- `ssh -o ControlPath=${peer.controlSocket} ${peer.target} "telepty inject ${noEnterFlag} ${fromFlag} '${sessionId}' '${escaped}'"`,
182
- { timeout: 15000, encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] }
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