@dmsdc-ai/aigentry-telepty 0.0.8 → 0.0.9

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.
@@ -14,5 +14,6 @@ When the user asks about their current session ID (e.g. "내 세션 ID가 뭐야
14
14
  2. **To list all sessions:**
15
15
  - Run `telepty list`.
16
16
  3. **To inject a command into another session:**
17
- - Ensure you know the target session ID. If not specified, ask the user or run `telepty list` to find it.
18
- - Run `telepty inject <target_session_id> "<message or command>"`.
17
+ - For a single session: Run `telepty inject <target_session_id> "<message or command>"`.
18
+ - For broadcasting to ALL active sessions: Run `telepty broadcast "<message or command>"`.
19
+ - For multicasting to multiple specific sessions: Run `telepty multicast <id1>,<id2> "<message or command>"`.
package/cli.js CHANGED
@@ -355,6 +355,38 @@ async function main() {
355
355
  return;
356
356
  }
357
357
 
358
+ if (cmd === 'multicast') {
359
+ const sessionIdsRaw = args[1]; const prompt = args.slice(2).join(' ');
360
+ if (!sessionIdsRaw || !prompt) { console.error('❌ Usage: telepty multicast <id1,id2,...> "<prompt text>"'); process.exit(1); }
361
+ const sessionIds = sessionIdsRaw.split(',').map(s => s.trim()).filter(s => s);
362
+ try {
363
+ const res = await fetchWithAuth(`${DAEMON_URL}/api/sessions/multicast/inject`, {
364
+ method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ session_ids: sessionIds, prompt })
365
+ });
366
+ const data = await res.json();
367
+ if (!res.ok) { console.error(`❌ Error: ${data.error}`); return; }
368
+ console.log(`✅ Context multicasted successfully to ${data.results.successful.length} sessions.`);
369
+ if (data.results.failed.length > 0) {
370
+ console.warn(`⚠️ Failed to inject into ${data.results.failed.length} sessions:`, data.results.failed.map(f => f.id).join(', '));
371
+ }
372
+ } catch (e) { console.error('❌ Failed to connect to daemon. Is it running?'); }
373
+ return;
374
+ }
375
+
376
+ if (cmd === 'broadcast') {
377
+ const prompt = args.slice(1).join(' ');
378
+ if (!prompt) { console.error('❌ Usage: telepty broadcast "<prompt text>"'); process.exit(1); }
379
+ try {
380
+ const res = await fetchWithAuth(`${DAEMON_URL}/api/sessions/broadcast/inject`, {
381
+ method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ prompt })
382
+ });
383
+ const data = await res.json();
384
+ if (!res.ok) { console.error(`❌ Error: ${data.error}`); return; }
385
+ console.log(`✅ Context broadcasted successfully to ${data.results.successful.length} active sessions.`);
386
+ } catch (e) { console.error('❌ Failed to connect to daemon. Is it running?'); }
387
+ return;
388
+ }
389
+
358
390
  console.log(`
359
391
  \x1b[1maigentry-telepty\x1b[0m - Remote PTY Control
360
392
 
@@ -363,7 +395,9 @@ Usage:
363
395
  telepty spawn --id <id> <command> [args...] Spawn a new background CLI
364
396
  telepty list List all active sessions
365
397
  telepty attach [id] Attach to a session (Interactive picker if no ID)
366
- telepty inject <id> "<prompt>" Inject text into an active session
398
+ telepty inject <id> "<prompt>" Inject text into a single session
399
+ telepty multicast <id1,id2> "<prompt>" Inject text into multiple specific sessions
400
+ telepty broadcast "<prompt>" Inject text into ALL active sessions
367
401
  telepty mcp Start the MCP stdio server
368
402
  `);
369
403
  }
package/daemon.js CHANGED
@@ -94,6 +94,48 @@ app.get('/api/sessions', (req, res) => {
94
94
  res.json(list);
95
95
  });
96
96
 
97
+ app.post('/api/sessions/multicast/inject', (req, res) => {
98
+ const { session_ids, prompt } = req.body;
99
+ if (!prompt) return res.status(400).json({ error: 'prompt is required' });
100
+ if (!Array.isArray(session_ids)) return res.status(400).json({ error: 'session_ids must be an array' });
101
+
102
+ const results = { successful: [], failed: [] };
103
+
104
+ session_ids.forEach(id => {
105
+ const session = sessions[id];
106
+ if (session) {
107
+ try {
108
+ session.ptyProcess.write(`${prompt}\r`);
109
+ results.successful.push(id);
110
+ } catch (err) {
111
+ results.failed.push({ id, error: err.message });
112
+ }
113
+ } else {
114
+ results.failed.push({ id, error: 'Session not found' });
115
+ }
116
+ });
117
+
118
+ res.json({ success: true, results });
119
+ });
120
+
121
+ app.post('/api/sessions/broadcast/inject', (req, res) => {
122
+ const { prompt } = req.body;
123
+ if (!prompt) return res.status(400).json({ error: 'prompt is required' });
124
+
125
+ const results = { successful: [], failed: [] };
126
+
127
+ Object.keys(sessions).forEach(id => {
128
+ try {
129
+ sessions[id].ptyProcess.write(`${prompt}\r`);
130
+ results.successful.push(id);
131
+ } catch (err) {
132
+ results.failed.push({ id, error: err.message });
133
+ }
134
+ });
135
+
136
+ res.json({ success: true, results });
137
+ });
138
+
97
139
  app.post('/api/sessions/:id/inject', (req, res) => {
98
140
  const { id } = req.params;
99
141
  const { prompt } = req.body;
package/install.ps1 CHANGED
@@ -26,7 +26,7 @@ if (!$teleptyCmd) {
26
26
  }
27
27
 
28
28
  $teleptyPath = $teleptyCmd.Source
29
- Start-Process -NoNewWindow -FilePath node -ArgumentList "$teleptyPath daemon" -WindowStyle Hidden
29
+ Start-Process -FilePath node -ArgumentList "$teleptyPath daemon" -WindowStyle Hidden
30
30
  Write-Host "✅ Windows daemon started in background." -ForegroundColor Green
31
31
 
32
32
  Write-Host "`n🎉 Installation complete! Telepty daemon is running." -ForegroundColor Cyan
package/mcp.js CHANGED
@@ -18,8 +18,14 @@ const tools = [
18
18
  },
19
19
  {
20
20
  name: 'telepty_inject_context',
21
- description: 'Inject a prompt or context into an active AI CLI session on a remote machine. WARNING: You MUST use telepty_list_remote_sessions first to find the exact session_id, and ask the user for confirmation if ambiguous.',
22
- schema: z.object({ remote_url: z.string(), session_id: z.string().describe('The EXACT session ID.'), prompt: z.string().describe('Text to inject into stdin.') })
21
+ description: 'Inject a prompt or context into specific active AI CLI sessions on a remote machine. You can specify a single session ID, multiple session IDs, or broadcast to all.',
22
+ schema: z.object({
23
+ remote_url: z.string(),
24
+ session_ids: z.array(z.string()).optional().describe('An array of exact session IDs to inject into. If not provided, it will inject into session_id.'),
25
+ session_id: z.string().optional().describe('Legacy fallback for a single session ID.'),
26
+ broadcast: z.boolean().optional().describe('If true, injects the prompt into ALL active sessions on the remote daemon. Overrides session_ids.'),
27
+ prompt: z.string().describe('Text to inject into stdin.')
28
+ })
23
29
  }
24
30
  ];
25
31
 
@@ -47,12 +53,35 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
47
53
  }
48
54
  if (name === 'telepty_inject_context') {
49
55
  const baseUrl = args.remote_url.startsWith('http') ? args.remote_url : `http://${args.remote_url}`;
50
- const res = await fetch(`${baseUrl}/api/sessions/${encodeURIComponent(args.session_id)}/inject`, {
51
- method: 'POST', headers: { 'Content-Type': 'application/json', 'x-telepty-token': TOKEN }, body: JSON.stringify({ prompt: args.prompt })
56
+
57
+ let endpoint = '';
58
+ let body = {};
59
+
60
+ if (args.broadcast) {
61
+ endpoint = `${baseUrl}/api/sessions/broadcast/inject`;
62
+ body = { prompt: args.prompt };
63
+ } else if (args.session_ids && args.session_ids.length > 0) {
64
+ endpoint = `${baseUrl}/api/sessions/multicast/inject`;
65
+ body = { session_ids: args.session_ids, prompt: args.prompt };
66
+ } else if (args.session_id) {
67
+ endpoint = `${baseUrl}/api/sessions/${encodeURIComponent(args.session_id)}/inject`;
68
+ body = { prompt: args.prompt };
69
+ } else {
70
+ throw new Error('You must provide either broadcast: true, session_ids: [...], or session_id: "..."');
71
+ }
72
+
73
+ const res = await fetch(endpoint, {
74
+ method: 'POST', headers: { 'Content-Type': 'application/json', 'x-telepty-token': TOKEN }, body: JSON.stringify(body)
52
75
  });
53
76
  const data = await res.json();
54
77
  if (!res.ok) throw new Error(data.error || `HTTP ${res.status}`);
55
- return { content: [{ type: 'text', text: `✅ Successfully injected context into session '${args.session_id}'. The remote agent has been awakened.` }] };
78
+
79
+ let msg = `✅ Successfully injected context.`;
80
+ if (args.broadcast) msg += ` (Broadcasted to ${data.results.successful.length} sessions)`;
81
+ else if (args.session_ids) msg += ` (Multicasted to ${data.results.successful.length} sessions)`;
82
+ else msg += ` (Targeted session '${args.session_id}')`;
83
+
84
+ return { content: [{ type: 'text', text: msg }] };
56
85
  }
57
86
  throw new Error(`Unknown tool: ${name}`);
58
87
  } catch (err) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dmsdc-ai/aigentry-telepty",
3
- "version": "0.0.8",
3
+ "version": "0.0.9",
4
4
  "main": "daemon.js",
5
5
  "bin": {
6
6
  "telepty": "cli.js",