genbox 1.0.211 → 1.0.213
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.
|
@@ -69,6 +69,7 @@ const watch_1 = require("./watch");
|
|
|
69
69
|
const logs_1 = require("./logs");
|
|
70
70
|
const show_1 = require("./show");
|
|
71
71
|
const send_1 = require("./send");
|
|
72
|
+
const templates_1 = require("./templates");
|
|
72
73
|
const child_process_1 = require("child_process");
|
|
73
74
|
const os = __importStar(require("os"));
|
|
74
75
|
const path = __importStar(require("path"));
|
|
@@ -1776,6 +1777,7 @@ exports.sessionCommand = new commander_1.Command('session')
|
|
|
1776
1777
|
.addCommand(logs_1.sessionLogsCommand)
|
|
1777
1778
|
.addCommand(show_1.sessionShowCommand)
|
|
1778
1779
|
.addCommand(send_1.sessionSendCommand)
|
|
1780
|
+
.addCommand(templates_1.sessionTemplatesCommand)
|
|
1779
1781
|
.action(async (sessionArg, providerArgs, options) => {
|
|
1780
1782
|
try {
|
|
1781
1783
|
// Clean up stale sockets on startup (silently)
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Session Send Command
|
|
4
4
|
*
|
|
5
|
-
* Send a prompt to
|
|
6
|
-
*
|
|
5
|
+
* Send a prompt to running session(s) without attaching.
|
|
6
|
+
* Supports single session or multi-session broadcasting.
|
|
7
7
|
*
|
|
8
8
|
* Usage:
|
|
9
|
-
* gb session send <session> "prompt" # Send
|
|
10
|
-
* gb session send
|
|
11
|
-
* gb session send
|
|
9
|
+
* gb session send <session> "prompt" # Send to single session
|
|
10
|
+
* gb session send --all "prompt" # Broadcast to all sessions
|
|
11
|
+
* gb session send --provider claude "prompt" # Send to all Claude sessions
|
|
12
12
|
*/
|
|
13
13
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
14
14
|
if (k2 === undefined) k2 = k;
|
|
@@ -72,6 +72,56 @@ function getPrivateSshKey() {
|
|
|
72
72
|
}
|
|
73
73
|
return null;
|
|
74
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* Find all active sessions matching filters
|
|
77
|
+
*/
|
|
78
|
+
async function findAllSessions(options) {
|
|
79
|
+
const result = await (0, unified_session_1.listAllSessions)({ includeEnded: false });
|
|
80
|
+
const targets = [];
|
|
81
|
+
// Process local sessions
|
|
82
|
+
for (const session of result.sessions) {
|
|
83
|
+
if (session.status !== 'running' && session.status !== 'active' && session.status !== 'idle') {
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
// Filter by provider
|
|
87
|
+
if (options.provider && session.provider !== options.provider)
|
|
88
|
+
continue;
|
|
89
|
+
// Filter by genbox
|
|
90
|
+
if (options.genbox) {
|
|
91
|
+
const genboxName = session.infrastructure?.genboxName ||
|
|
92
|
+
session.infrastructure?.vmName ||
|
|
93
|
+
session.infrastructure?.containerName ||
|
|
94
|
+
session.name;
|
|
95
|
+
if (!genboxName.toLowerCase().includes(options.genbox.toLowerCase()))
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
targets.push({
|
|
99
|
+
name: session.name,
|
|
100
|
+
type: session.type === 'native' ? 'local' :
|
|
101
|
+
session.type === 'docker' ? 'docker' :
|
|
102
|
+
session.type === 'multipass' ? 'multipass' : 'cloud',
|
|
103
|
+
session,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
// Process remote sessions
|
|
107
|
+
for (const remote of result.remoteSessions) {
|
|
108
|
+
// Filter by provider
|
|
109
|
+
if (options.provider && remote.provider !== options.provider)
|
|
110
|
+
continue;
|
|
111
|
+
// Filter by genbox
|
|
112
|
+
if (options.genbox && !remote.genboxName.toLowerCase().includes(options.genbox.toLowerCase()))
|
|
113
|
+
continue;
|
|
114
|
+
targets.push({
|
|
115
|
+
name: remote.name,
|
|
116
|
+
type: 'remote',
|
|
117
|
+
remoteSession: {
|
|
118
|
+
...remote,
|
|
119
|
+
provider: remote.provider,
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
return targets;
|
|
124
|
+
}
|
|
75
125
|
/**
|
|
76
126
|
* Find session by name or ID
|
|
77
127
|
*/
|
|
@@ -86,7 +136,13 @@ async function findSession(nameOrId) {
|
|
|
86
136
|
session.id === nameOrId ||
|
|
87
137
|
session.id.startsWith(nameOrId) ||
|
|
88
138
|
session.name.includes(nameOrId)) {
|
|
89
|
-
return {
|
|
139
|
+
return {
|
|
140
|
+
name: session.name,
|
|
141
|
+
type: session.type === 'native' ? 'local' :
|
|
142
|
+
session.type === 'docker' ? 'docker' :
|
|
143
|
+
session.type === 'multipass' ? 'multipass' : 'cloud',
|
|
144
|
+
session,
|
|
145
|
+
};
|
|
90
146
|
}
|
|
91
147
|
}
|
|
92
148
|
// Check remote sessions
|
|
@@ -94,10 +150,12 @@ async function findSession(nameOrId) {
|
|
|
94
150
|
if (remote.name === nameOrId ||
|
|
95
151
|
remote.name.includes(nameOrId)) {
|
|
96
152
|
return {
|
|
153
|
+
name: remote.name,
|
|
154
|
+
type: 'remote',
|
|
97
155
|
remoteSession: {
|
|
98
156
|
...remote,
|
|
99
157
|
provider: remote.provider,
|
|
100
|
-
}
|
|
158
|
+
},
|
|
101
159
|
};
|
|
102
160
|
}
|
|
103
161
|
}
|
|
@@ -122,6 +180,7 @@ function getPromptFromEditor() {
|
|
|
122
180
|
// Create temp file with instructions
|
|
123
181
|
fs.writeFileSync(tmpFile, `# Enter your prompt below (lines starting with # are ignored)
|
|
124
182
|
# Save and close the editor when done
|
|
183
|
+
# This prompt will be sent to the session(s)
|
|
125
184
|
|
|
126
185
|
`);
|
|
127
186
|
// Open editor
|
|
@@ -154,11 +213,13 @@ function getDtachSocketDir() {
|
|
|
154
213
|
/**
|
|
155
214
|
* Send prompt to local native session via dtach
|
|
156
215
|
*/
|
|
157
|
-
async function sendToLocalSession(session, prompt
|
|
216
|
+
async function sendToLocalSession(session, prompt) {
|
|
217
|
+
const start = Date.now();
|
|
158
218
|
const socketPath = session.infrastructure?.dtachSocketPath ||
|
|
159
219
|
path.join(getDtachSocketDir(), `${session.name}.sock`);
|
|
160
220
|
if (!fs.existsSync(socketPath)) {
|
|
161
221
|
return {
|
|
222
|
+
session: session.name,
|
|
162
223
|
success: false,
|
|
163
224
|
message: `Socket not found: ${socketPath}. Session may not be running.`,
|
|
164
225
|
};
|
|
@@ -169,8 +230,6 @@ async function sendToLocalSession(session, prompt, options) {
|
|
|
169
230
|
.replace(/\\/g, '\\\\')
|
|
170
231
|
.replace(/'/g, "'\\''")
|
|
171
232
|
.replace(/\n/g, '\\n');
|
|
172
|
-
// Use printf to send prompt to dtach session
|
|
173
|
-
// The -p flag attaches briefly to push input
|
|
174
233
|
const result = (0, child_process_1.spawnSync)('bash', [
|
|
175
234
|
'-c',
|
|
176
235
|
`printf '%s\\n' '${escapedPrompt}' | dtach -p "${socketPath}"`,
|
|
@@ -180,17 +239,21 @@ async function sendToLocalSession(session, prompt, options) {
|
|
|
180
239
|
});
|
|
181
240
|
if (result.status !== 0) {
|
|
182
241
|
return {
|
|
242
|
+
session: session.name,
|
|
183
243
|
success: false,
|
|
184
244
|
message: `Failed to send prompt: ${result.stderr || 'Unknown error'}`,
|
|
185
245
|
};
|
|
186
246
|
}
|
|
187
247
|
return {
|
|
248
|
+
session: session.name,
|
|
188
249
|
success: true,
|
|
189
|
-
message: `Prompt sent
|
|
250
|
+
message: `Prompt sent`,
|
|
251
|
+
duration: Date.now() - start,
|
|
190
252
|
};
|
|
191
253
|
}
|
|
192
254
|
catch (error) {
|
|
193
255
|
return {
|
|
256
|
+
session: session.name,
|
|
194
257
|
success: false,
|
|
195
258
|
message: `Error: ${error.message}`,
|
|
196
259
|
};
|
|
@@ -200,9 +263,11 @@ async function sendToLocalSession(session, prompt, options) {
|
|
|
200
263
|
* Send prompt to remote session via SSH + dtach
|
|
201
264
|
*/
|
|
202
265
|
async function sendToRemoteSession(ipAddress, sessionName, prompt, sshPort) {
|
|
266
|
+
const start = Date.now();
|
|
203
267
|
const keyPath = getPrivateSshKey();
|
|
204
268
|
if (!keyPath) {
|
|
205
269
|
return {
|
|
270
|
+
session: sessionName,
|
|
206
271
|
success: false,
|
|
207
272
|
message: 'SSH key not found. Run `gb login` first.',
|
|
208
273
|
};
|
|
@@ -232,17 +297,21 @@ async function sendToRemoteSession(ipAddress, sessionName, prompt, sshPort) {
|
|
|
232
297
|
});
|
|
233
298
|
if (result.status !== 0) {
|
|
234
299
|
return {
|
|
300
|
+
session: sessionName,
|
|
235
301
|
success: false,
|
|
236
302
|
message: `Failed to send prompt: ${result.stderr || 'Unknown error'}`,
|
|
237
303
|
};
|
|
238
304
|
}
|
|
239
305
|
return {
|
|
306
|
+
session: sessionName,
|
|
240
307
|
success: true,
|
|
241
|
-
message: `Prompt sent
|
|
308
|
+
message: `Prompt sent`,
|
|
309
|
+
duration: Date.now() - start,
|
|
242
310
|
};
|
|
243
311
|
}
|
|
244
312
|
catch (error) {
|
|
245
313
|
return {
|
|
314
|
+
session: sessionName,
|
|
246
315
|
success: false,
|
|
247
316
|
message: `Error: ${error.message}`,
|
|
248
317
|
};
|
|
@@ -251,7 +320,8 @@ async function sendToRemoteSession(ipAddress, sessionName, prompt, sshPort) {
|
|
|
251
320
|
/**
|
|
252
321
|
* Send prompt via API remote control
|
|
253
322
|
*/
|
|
254
|
-
async function sendViaApi(sessionId, prompt) {
|
|
323
|
+
async function sendViaApi(sessionId, sessionName, prompt) {
|
|
324
|
+
const start = Date.now();
|
|
255
325
|
try {
|
|
256
326
|
await (0, api_1.fetchApi)(`/sessions/v2/${sessionId}/command`, {
|
|
257
327
|
method: 'POST',
|
|
@@ -262,34 +332,111 @@ async function sendViaApi(sessionId, prompt) {
|
|
|
262
332
|
}),
|
|
263
333
|
});
|
|
264
334
|
return {
|
|
335
|
+
session: sessionName,
|
|
265
336
|
success: true,
|
|
266
337
|
message: 'Prompt queued via API',
|
|
338
|
+
duration: Date.now() - start,
|
|
267
339
|
};
|
|
268
340
|
}
|
|
269
341
|
catch (error) {
|
|
270
342
|
return {
|
|
343
|
+
session: sessionName,
|
|
271
344
|
success: false,
|
|
272
345
|
message: `API error: ${error.message}`,
|
|
273
346
|
};
|
|
274
347
|
}
|
|
275
348
|
}
|
|
349
|
+
/**
|
|
350
|
+
* Send prompt to a single target
|
|
351
|
+
*/
|
|
352
|
+
async function sendToTarget(target, prompt) {
|
|
353
|
+
if (target.remoteSession) {
|
|
354
|
+
return sendToRemoteSession(target.remoteSession.ipAddress, target.remoteSession.name, prompt);
|
|
355
|
+
}
|
|
356
|
+
const session = target.session;
|
|
357
|
+
if (target.type === 'local') {
|
|
358
|
+
return sendToLocalSession(session, prompt);
|
|
359
|
+
}
|
|
360
|
+
else if (target.type === 'cloud' && session.infrastructure?.ipAddress) {
|
|
361
|
+
return sendToRemoteSession(session.infrastructure.ipAddress, session.name, prompt);
|
|
362
|
+
}
|
|
363
|
+
else if (target.type === 'docker' || target.type === 'multipass') {
|
|
364
|
+
const ip = target.type === 'docker' ? '127.0.0.1' : session.infrastructure?.vmIpAddress;
|
|
365
|
+
const port = session.infrastructure?.sshPort;
|
|
366
|
+
if (!ip) {
|
|
367
|
+
return {
|
|
368
|
+
session: session.name,
|
|
369
|
+
success: false,
|
|
370
|
+
message: 'Cannot determine session IP address',
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
return sendToRemoteSession(ip, session.name, prompt, port);
|
|
374
|
+
}
|
|
375
|
+
else if (session.syncEnabled && session.apiSessionIdV2) {
|
|
376
|
+
return sendViaApi(session.apiSessionIdV2, session.name, prompt);
|
|
377
|
+
}
|
|
378
|
+
return {
|
|
379
|
+
session: session.name,
|
|
380
|
+
success: false,
|
|
381
|
+
message: `Cannot send to session type: ${session.type}`,
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Send to multiple sessions
|
|
386
|
+
*/
|
|
387
|
+
async function sendToMultipleSessions(targets, prompt, parallel) {
|
|
388
|
+
if (parallel) {
|
|
389
|
+
// Send in parallel
|
|
390
|
+
return Promise.all(targets.map(target => sendToTarget(target, prompt)));
|
|
391
|
+
}
|
|
392
|
+
// Send sequentially
|
|
393
|
+
const results = [];
|
|
394
|
+
for (const target of targets) {
|
|
395
|
+
results.push(await sendToTarget(target, prompt));
|
|
396
|
+
}
|
|
397
|
+
return results;
|
|
398
|
+
}
|
|
276
399
|
exports.sessionSendCommand = new commander_1.Command('send')
|
|
277
|
-
.description('Send a prompt to
|
|
278
|
-
.argument('
|
|
400
|
+
.description('Send a prompt to running session(s)')
|
|
401
|
+
.argument('[session]', 'Session name or ID (not needed with --all)')
|
|
279
402
|
.argument('[prompt]', 'Prompt text (or use -f/-e)')
|
|
280
403
|
.option('-f, --file <path>', 'Read prompt from file')
|
|
281
404
|
.option('-e, --editor', 'Open $EDITOR to compose prompt')
|
|
282
|
-
.option('--
|
|
405
|
+
.option('--all', 'Send to ALL active sessions (broadcast)')
|
|
406
|
+
.option('--provider <provider>', 'Filter by provider when using --all (claude, gemini, codex)')
|
|
407
|
+
.option('--genbox <name>', 'Filter by genbox name when using --all')
|
|
408
|
+
.option('--parallel', 'Send to all sessions in parallel (default: sequential)')
|
|
283
409
|
.option('--json', 'Output result as JSON')
|
|
284
410
|
.addHelpText('after', `
|
|
285
411
|
Examples:
|
|
412
|
+
# Single session
|
|
286
413
|
gb session send claude-fox "Add unit tests" # Inline prompt
|
|
287
414
|
gb session send claude-fox -f prompt.txt # From file
|
|
288
415
|
gb session send claude-fox -e # Open editor
|
|
289
|
-
|
|
416
|
+
|
|
417
|
+
# Multi-session broadcast
|
|
418
|
+
gb session send --all "Run the test suite" # All sessions
|
|
419
|
+
gb session send --all --provider claude "Fix bugs" # All Claude sessions
|
|
420
|
+
gb session send --all --genbox dusty "Deploy" # All on dusty genbox
|
|
421
|
+
gb session send --all --parallel "Check status" # Parallel broadcast
|
|
422
|
+
|
|
423
|
+
# JSON output (for scripting)
|
|
424
|
+
gb session send --all --json "Hello" # JSON results
|
|
290
425
|
`)
|
|
291
426
|
.action(async (sessionArg, promptArg, options) => {
|
|
292
427
|
try {
|
|
428
|
+
// Validate arguments
|
|
429
|
+
if (!options.all && !sessionArg) {
|
|
430
|
+
console.log(chalk_1.default.red('\nNo session specified.'));
|
|
431
|
+
console.log(chalk_1.default.dim('Use: gb session send <session> "prompt"'));
|
|
432
|
+
console.log(chalk_1.default.dim(' or: gb session send --all "prompt"\n'));
|
|
433
|
+
process.exit(1);
|
|
434
|
+
}
|
|
435
|
+
// Handle the case where session arg might actually be the prompt for --all
|
|
436
|
+
let actualPromptArg = promptArg;
|
|
437
|
+
if (options.all && sessionArg && !promptArg) {
|
|
438
|
+
actualPromptArg = sessionArg;
|
|
439
|
+
}
|
|
293
440
|
// Get the prompt
|
|
294
441
|
let prompt;
|
|
295
442
|
if (options.file) {
|
|
@@ -298,17 +445,88 @@ Examples:
|
|
|
298
445
|
else if (options.editor) {
|
|
299
446
|
prompt = getPromptFromEditor();
|
|
300
447
|
}
|
|
301
|
-
else if (
|
|
302
|
-
prompt =
|
|
448
|
+
else if (actualPromptArg) {
|
|
449
|
+
prompt = actualPromptArg;
|
|
303
450
|
}
|
|
304
451
|
else {
|
|
305
452
|
console.log(chalk_1.default.red('\nNo prompt provided.'));
|
|
306
453
|
console.log(chalk_1.default.dim('Use: gb session send <session> "prompt"'));
|
|
307
|
-
console.log(chalk_1.default.dim(' or: gb session send
|
|
308
|
-
console.log(chalk_1.default.dim(' or: gb session send
|
|
454
|
+
console.log(chalk_1.default.dim(' or: gb session send --all -f prompt.txt'));
|
|
455
|
+
console.log(chalk_1.default.dim(' or: gb session send --all -e\n'));
|
|
309
456
|
process.exit(1);
|
|
310
457
|
}
|
|
311
|
-
//
|
|
458
|
+
// Handle multi-session broadcast
|
|
459
|
+
if (options.all) {
|
|
460
|
+
const targets = await findAllSessions({
|
|
461
|
+
provider: options.provider,
|
|
462
|
+
genbox: options.genbox,
|
|
463
|
+
});
|
|
464
|
+
if (targets.length === 0) {
|
|
465
|
+
const output = {
|
|
466
|
+
success: false,
|
|
467
|
+
error: 'No active sessions found matching filters',
|
|
468
|
+
filters: {
|
|
469
|
+
provider: options.provider,
|
|
470
|
+
genbox: options.genbox,
|
|
471
|
+
},
|
|
472
|
+
};
|
|
473
|
+
if (options.json) {
|
|
474
|
+
console.log(JSON.stringify(output));
|
|
475
|
+
}
|
|
476
|
+
else {
|
|
477
|
+
console.log(chalk_1.default.red('\nNo active sessions found matching filters.'));
|
|
478
|
+
if (options.provider)
|
|
479
|
+
console.log(chalk_1.default.dim(` Provider: ${options.provider}`));
|
|
480
|
+
if (options.genbox)
|
|
481
|
+
console.log(chalk_1.default.dim(` Genbox: ${options.genbox}`));
|
|
482
|
+
console.log(chalk_1.default.dim('\nRun `gb session list` to see active sessions.\n'));
|
|
483
|
+
}
|
|
484
|
+
process.exit(1);
|
|
485
|
+
}
|
|
486
|
+
if (!options.json) {
|
|
487
|
+
console.log(chalk_1.default.bold(`\nBroadcasting to ${targets.length} session(s)...`));
|
|
488
|
+
console.log(chalk_1.default.dim(`Prompt: "${prompt.substring(0, 50)}${prompt.length > 50 ? '...' : ''}"`));
|
|
489
|
+
console.log('');
|
|
490
|
+
}
|
|
491
|
+
const results = await sendToMultipleSessions(targets, prompt, !!options.parallel);
|
|
492
|
+
// Output results
|
|
493
|
+
if (options.json) {
|
|
494
|
+
const successCount = results.filter(r => r.success).length;
|
|
495
|
+
console.log(JSON.stringify({
|
|
496
|
+
success: successCount === results.length,
|
|
497
|
+
total: results.length,
|
|
498
|
+
succeeded: successCount,
|
|
499
|
+
failed: results.length - successCount,
|
|
500
|
+
promptLength: prompt.length,
|
|
501
|
+
results,
|
|
502
|
+
}, null, 2));
|
|
503
|
+
}
|
|
504
|
+
else {
|
|
505
|
+
let successCount = 0;
|
|
506
|
+
let failCount = 0;
|
|
507
|
+
for (const result of results) {
|
|
508
|
+
if (result.success) {
|
|
509
|
+
successCount++;
|
|
510
|
+
console.log(chalk_1.default.green(` ✓ ${result.session}`) + chalk_1.default.dim(` (${result.duration}ms)`));
|
|
511
|
+
}
|
|
512
|
+
else {
|
|
513
|
+
failCount++;
|
|
514
|
+
console.log(chalk_1.default.red(` ✗ ${result.session}: ${result.message}`));
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
console.log('');
|
|
518
|
+
if (failCount === 0) {
|
|
519
|
+
console.log(chalk_1.default.green(`✓ Sent to all ${successCount} session(s)`));
|
|
520
|
+
}
|
|
521
|
+
else {
|
|
522
|
+
console.log(chalk_1.default.yellow(`Sent to ${successCount}/${results.length} sessions (${failCount} failed)`));
|
|
523
|
+
}
|
|
524
|
+
console.log('');
|
|
525
|
+
}
|
|
526
|
+
const anyFailed = results.some(r => !r.success);
|
|
527
|
+
process.exit(anyFailed ? 1 : 0);
|
|
528
|
+
}
|
|
529
|
+
// Single session send
|
|
312
530
|
const found = await findSession(sessionArg);
|
|
313
531
|
if (!found) {
|
|
314
532
|
const output = {
|
|
@@ -324,67 +542,27 @@ Examples:
|
|
|
324
542
|
}
|
|
325
543
|
process.exit(1);
|
|
326
544
|
}
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
// Remote session on cloud genbox
|
|
330
|
-
if (!options.json) {
|
|
331
|
-
console.log(chalk_1.default.dim(`\nSending to remote session: ${found.remoteSession.name}`));
|
|
332
|
-
console.log(chalk_1.default.dim(` Genbox: ${found.remoteSession.genboxName}`));
|
|
333
|
-
}
|
|
334
|
-
result = await sendToRemoteSession(found.remoteSession.ipAddress, found.remoteSession.name, prompt);
|
|
335
|
-
}
|
|
336
|
-
else {
|
|
337
|
-
const session = found.session;
|
|
338
|
-
if (!options.json) {
|
|
339
|
-
console.log(chalk_1.default.dim(`\nSending to session: ${session.name}`));
|
|
340
|
-
}
|
|
341
|
-
// Try different methods based on session type
|
|
342
|
-
if (session.type === 'native') {
|
|
343
|
-
// Local native session - use dtach directly
|
|
344
|
-
result = await sendToLocalSession(session, prompt, options);
|
|
345
|
-
}
|
|
346
|
-
else if (session.type === 'cloud' && session.infrastructure?.ipAddress) {
|
|
347
|
-
// Cloud session - use SSH
|
|
348
|
-
result = await sendToRemoteSession(session.infrastructure.ipAddress, session.name, prompt);
|
|
349
|
-
}
|
|
350
|
-
else if (session.type === 'docker' || session.type === 'multipass') {
|
|
351
|
-
// Local VM/Docker - use SSH to localhost with port
|
|
352
|
-
const ip = session.type === 'docker' ? '127.0.0.1' : session.infrastructure?.vmIpAddress;
|
|
353
|
-
const port = session.infrastructure?.sshPort;
|
|
354
|
-
if (!ip) {
|
|
355
|
-
result = { success: false, message: 'Cannot determine session IP address' };
|
|
356
|
-
}
|
|
357
|
-
else {
|
|
358
|
-
result = await sendToRemoteSession(ip, session.name, prompt, port);
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
else if (session.syncEnabled && session.apiSessionIdV2) {
|
|
362
|
-
// Fall back to API remote control
|
|
363
|
-
result = await sendViaApi(session.apiSessionIdV2, prompt);
|
|
364
|
-
}
|
|
365
|
-
else {
|
|
366
|
-
result = {
|
|
367
|
-
success: false,
|
|
368
|
-
message: `Cannot send to session type: ${session.type}`,
|
|
369
|
-
};
|
|
370
|
-
}
|
|
545
|
+
if (!options.json) {
|
|
546
|
+
console.log(chalk_1.default.dim(`\nSending to session: ${found.name}`));
|
|
371
547
|
}
|
|
548
|
+
const result = await sendToTarget(found, prompt);
|
|
372
549
|
// Output result
|
|
373
550
|
if (options.json) {
|
|
374
551
|
console.log(JSON.stringify({
|
|
375
552
|
success: result.success,
|
|
376
553
|
message: result.message,
|
|
377
|
-
session:
|
|
554
|
+
session: result.session,
|
|
378
555
|
promptLength: prompt.length,
|
|
556
|
+
duration: result.duration,
|
|
379
557
|
}));
|
|
380
558
|
}
|
|
381
559
|
else {
|
|
382
560
|
if (result.success) {
|
|
383
|
-
console.log(chalk_1.default.green(`\n✓ ${result.message}`));
|
|
561
|
+
console.log(chalk_1.default.green(`\n✓ ${result.message} to ${result.session}`));
|
|
384
562
|
console.log(chalk_1.default.dim(` Prompt: "${prompt.substring(0, 50)}${prompt.length > 50 ? '...' : ''}"`));
|
|
385
563
|
console.log('');
|
|
386
564
|
console.log(chalk_1.default.dim('View progress:'));
|
|
387
|
-
console.log(chalk_1.default.cyan(` gb session logs ${
|
|
565
|
+
console.log(chalk_1.default.cyan(` gb session logs ${result.session} -f\n`));
|
|
388
566
|
}
|
|
389
567
|
else {
|
|
390
568
|
console.log(chalk_1.default.red(`\n✗ ${result.message}\n`));
|