nexusforge-cli 1.0.6 → 1.0.7
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/assets/favicon.png +0 -0
- package/dist/utils/theme.d.ts +1 -0
- package/dist/utils/theme.d.ts.map +1 -1
- package/dist/utils/theme.js +3 -2
- package/dist/utils/theme.js.map +1 -1
- package/package.json +7 -1
- package/src/index.ts +0 -427
- package/src/services/api.ts +0 -211
- package/src/services/auth.ts +0 -230
- package/src/services/executor.ts +0 -250
- package/src/types/index.ts +0 -104
- package/src/utils/config.ts +0 -172
- package/src/utils/theme.ts +0 -163
- package/tsconfig.json +0 -23
|
Binary file
|
package/dist/utils/theme.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../src/utils/theme.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,eAAO,MAAM,MAAM
|
|
1
|
+
{"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../src/utils/theme.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,eAAO,MAAM,MAAM;;;;;;;;;;;;;;CAqBlB,CAAC;AAGF,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;CA+B5B,CAAC;AAGF,eAAO,MAAM,KAAK;iBAEH,MAAM;sBACD,MAAM;sBAGN,MAAM;2BACD,MAAM;oBAGb,MAAM;oBACN,MAAM;kBACR,MAAM;iBACP,MAAM;kBACL,MAAM;mBAGL,MAAM;iBACR,MAAM;oBACH,MAAM;;CAIvB,CAAC;AAGF,eAAO,MAAM,qBAAqB,srFAcjC,CAAC;AAEF;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAuBtF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAGxD;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAI7D;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAgB,GAAG,IAAI,CAGnH"}
|
package/dist/utils/theme.js
CHANGED
|
@@ -11,6 +11,7 @@ import chalk from 'chalk';
|
|
|
11
11
|
export const COLORS = {
|
|
12
12
|
// Primary colors
|
|
13
13
|
teal: '#14b8a6',
|
|
14
|
+
tealLight: '#5eead4', // Ultra light teal for logo/headers
|
|
14
15
|
terracotta: '#c4a484',
|
|
15
16
|
cream: '#faf9f6',
|
|
16
17
|
// Backgrounds
|
|
@@ -98,8 +99,8 @@ export const NEXUSFORGE_ASCII_LOGO = `
|
|
|
98
99
|
export function displayWelcome(version, serverUrl, model) {
|
|
99
100
|
// Clear screen
|
|
100
101
|
console.clear();
|
|
101
|
-
// Logo in teal
|
|
102
|
-
console.log(chalk.hex(
|
|
102
|
+
// Logo in ultra light teal
|
|
103
|
+
console.log(chalk.hex(COLORS.tealLight)(NEXUSFORGE_ASCII_LOGO));
|
|
103
104
|
// Divider
|
|
104
105
|
console.log(style.divider());
|
|
105
106
|
console.log('');
|
package/dist/utils/theme.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme.js","sourceRoot":"","sources":["../../src/utils/theme.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"theme.js","sourceRoot":"","sources":["../../src/utils/theme.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nexusforge-cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"description": "NexusForge CLI - AI-powered development companion for your terminal",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"bin": {
|
|
8
8
|
"nexusforge": "./bin/nexusforge"
|
|
9
9
|
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"bin",
|
|
13
|
+
"assets",
|
|
14
|
+
"README.md"
|
|
15
|
+
],
|
|
10
16
|
"scripts": {
|
|
11
17
|
"build": "tsc",
|
|
12
18
|
"dev": "ts-node src/index.ts",
|
package/src/index.ts
DELETED
|
@@ -1,427 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* NexusForge CLI
|
|
4
|
-
*
|
|
5
|
-
* AI-powered development companion for your terminal.
|
|
6
|
-
* Like Claude Code, but for NexusForge.
|
|
7
|
-
*
|
|
8
|
-
* Usage:
|
|
9
|
-
* nexusforge - Start interactive chat
|
|
10
|
-
* nexusforge login - Authenticate with browser
|
|
11
|
-
* nexusforge logout - Clear credentials
|
|
12
|
-
* nexusforge status - Check connection status
|
|
13
|
-
* nexusforge --session X - Sync with web session
|
|
14
|
-
* nexusforge --help - Show help
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
import { Command } from 'commander';
|
|
18
|
-
import * as readline from 'readline';
|
|
19
|
-
import * as config from './utils/config.js';
|
|
20
|
-
import { displayWelcome, displayUserMessage, displayAssistantMessage, displaySystemMessage, style } from './utils/theme.js';
|
|
21
|
-
import { startDeviceAuth, logout, checkAuth, getCurrentUser } from './services/auth.js';
|
|
22
|
-
import * as api from './services/api.js';
|
|
23
|
-
import * as executor from './services/executor.js';
|
|
24
|
-
import type { ChatMessage } from './types/index.js';
|
|
25
|
-
|
|
26
|
-
const VERSION = '1.0.0';
|
|
27
|
-
|
|
28
|
-
// Current conversation state
|
|
29
|
-
let conversationId: string | undefined;
|
|
30
|
-
let messages: ChatMessage[] = [];
|
|
31
|
-
|
|
32
|
-
// Create CLI program
|
|
33
|
-
const program = new Command();
|
|
34
|
-
|
|
35
|
-
program
|
|
36
|
-
.name('nexusforge')
|
|
37
|
-
.description('NexusForge CLI - AI-powered development companion')
|
|
38
|
-
.version(VERSION);
|
|
39
|
-
|
|
40
|
-
// Login command
|
|
41
|
-
program
|
|
42
|
-
.command('login')
|
|
43
|
-
.description('Authenticate with NexusForge via browser')
|
|
44
|
-
.action(async () => {
|
|
45
|
-
const success = await startDeviceAuth();
|
|
46
|
-
process.exit(success ? 0 : 1);
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
// Logout command
|
|
50
|
-
program
|
|
51
|
-
.command('logout')
|
|
52
|
-
.description('Clear saved credentials')
|
|
53
|
-
.action(() => {
|
|
54
|
-
logout();
|
|
55
|
-
process.exit(0);
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
// Status command
|
|
59
|
-
program
|
|
60
|
-
.command('status')
|
|
61
|
-
.description('Check connection and authentication status')
|
|
62
|
-
.action(async () => {
|
|
63
|
-
console.log('');
|
|
64
|
-
console.log(style.assistant('NexusForge CLI Status'));
|
|
65
|
-
console.log(style.divider());
|
|
66
|
-
console.log('');
|
|
67
|
-
|
|
68
|
-
// Check auth
|
|
69
|
-
const isAuth = await checkAuth();
|
|
70
|
-
const user = getCurrentUser();
|
|
71
|
-
|
|
72
|
-
if (isAuth && user) {
|
|
73
|
-
displaySystemMessage(`Authenticated as: ${user.username}`, 'success');
|
|
74
|
-
} else if (config.isAuthenticated()) {
|
|
75
|
-
displaySystemMessage('Token may be expired. Run "nexusforge login" to re-authenticate.', 'warning');
|
|
76
|
-
} else {
|
|
77
|
-
displaySystemMessage('Not authenticated. Run "nexusforge login" to authenticate.', 'warning');
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// Check API health
|
|
81
|
-
const isHealthy = await api.checkHealth();
|
|
82
|
-
if (isHealthy) {
|
|
83
|
-
displaySystemMessage(`API: ${config.getApiUrl()} (healthy)`, 'success');
|
|
84
|
-
} else {
|
|
85
|
-
displaySystemMessage(`API: ${config.getApiUrl()} (unreachable)`, 'error');
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
console.log('');
|
|
89
|
-
console.log(style.muted(`Config file: ${config.getConfigPath()}`));
|
|
90
|
-
console.log('');
|
|
91
|
-
process.exit(0);
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
// Main command (interactive chat)
|
|
95
|
-
program
|
|
96
|
-
.option('-s, --session <token>', 'Sync with a web session token')
|
|
97
|
-
.option('-m, --model <name>', 'Use a specific model')
|
|
98
|
-
.option('--cwd <path>', 'Set working directory')
|
|
99
|
-
.action(async (options) => {
|
|
100
|
-
// Change working directory if specified
|
|
101
|
-
if (options.cwd) {
|
|
102
|
-
if (!executor.changeCwd(options.cwd)) {
|
|
103
|
-
displaySystemMessage(`Cannot change to directory: ${options.cwd}`, 'error');
|
|
104
|
-
process.exit(1);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// Check authentication
|
|
109
|
-
if (!config.isAuthenticated()) {
|
|
110
|
-
displaySystemMessage('Not authenticated. Starting login...', 'info');
|
|
111
|
-
const success = await startDeviceAuth();
|
|
112
|
-
if (!success) {
|
|
113
|
-
process.exit(1);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// Sync with web session if provided
|
|
118
|
-
if (options.session) {
|
|
119
|
-
try {
|
|
120
|
-
displaySystemMessage('Syncing with web session...', 'info');
|
|
121
|
-
const session = await api.getSessionStatus(options.session);
|
|
122
|
-
conversationId = session.conversation_id;
|
|
123
|
-
displaySystemMessage(`Synced with conversation: ${conversationId}`, 'success');
|
|
124
|
-
} catch (error) {
|
|
125
|
-
displaySystemMessage('Failed to sync with session. Starting fresh.', 'warning');
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// Display welcome screen
|
|
130
|
-
const user = getCurrentUser();
|
|
131
|
-
displayWelcome(
|
|
132
|
-
VERSION,
|
|
133
|
-
config.getApiUrl(),
|
|
134
|
-
options.model || config.get('defaultModel') || 'NexusForge',
|
|
135
|
-
);
|
|
136
|
-
|
|
137
|
-
if (user?.username) {
|
|
138
|
-
displaySystemMessage(`Logged in as ${user.username}`, 'success');
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// Start interactive loop
|
|
142
|
-
await startInteractiveChat(options.model);
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
// Parse arguments
|
|
146
|
-
program.parse();
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Start the interactive chat loop
|
|
150
|
-
*/
|
|
151
|
-
async function startInteractiveChat(model?: string): Promise<void> {
|
|
152
|
-
const rl = readline.createInterface({
|
|
153
|
-
input: process.stdin,
|
|
154
|
-
output: process.stdout,
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
const promptUser = (): void => {
|
|
158
|
-
rl.question(`${style.userLabel('You')} ${style.prompt('❯')} `, async (input) => {
|
|
159
|
-
const trimmedInput = input.trim();
|
|
160
|
-
|
|
161
|
-
if (!trimmedInput) {
|
|
162
|
-
promptUser();
|
|
163
|
-
return;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// Handle slash commands
|
|
167
|
-
if (trimmedInput.startsWith('/')) {
|
|
168
|
-
await handleSlashCommand(trimmedInput, rl);
|
|
169
|
-
promptUser();
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// Send message to AI
|
|
174
|
-
try {
|
|
175
|
-
console.log('');
|
|
176
|
-
process.stdout.write(`${style.assistantLabel('NexusForge')} ${style.prompt('❯')} `);
|
|
177
|
-
|
|
178
|
-
// Stream response
|
|
179
|
-
let fullResponse = '';
|
|
180
|
-
for await (const chunk of api.streamMessage(trimmedInput, conversationId, model)) {
|
|
181
|
-
process.stdout.write(style.assistant(chunk));
|
|
182
|
-
fullResponse += chunk;
|
|
183
|
-
}
|
|
184
|
-
console.log('\n');
|
|
185
|
-
|
|
186
|
-
// Store messages
|
|
187
|
-
messages.push({ role: 'user', content: trimmedInput });
|
|
188
|
-
messages.push({ role: 'assistant', content: fullResponse });
|
|
189
|
-
|
|
190
|
-
// Check for executable commands in response
|
|
191
|
-
const commands = executor.parseCommandsFromResponse(fullResponse);
|
|
192
|
-
if (commands.length > 0 && config.get('autoExecute')) {
|
|
193
|
-
await promptToExecuteCommands(commands, rl);
|
|
194
|
-
}
|
|
195
|
-
} catch (error) {
|
|
196
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
197
|
-
displaySystemMessage(`Error: ${errorMessage}`, 'error');
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
promptUser();
|
|
201
|
-
});
|
|
202
|
-
};
|
|
203
|
-
|
|
204
|
-
promptUser();
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
/**
|
|
208
|
-
* Handle slash commands
|
|
209
|
-
*/
|
|
210
|
-
async function handleSlashCommand(input: string, rl: readline.Interface): Promise<void> {
|
|
211
|
-
const parts = input.slice(1).split(/\s+/);
|
|
212
|
-
const command = parts[0].toLowerCase();
|
|
213
|
-
const args = parts.slice(1);
|
|
214
|
-
|
|
215
|
-
switch (command) {
|
|
216
|
-
case 'help':
|
|
217
|
-
case 'h':
|
|
218
|
-
displayHelp();
|
|
219
|
-
break;
|
|
220
|
-
|
|
221
|
-
case 'exit':
|
|
222
|
-
case 'quit':
|
|
223
|
-
case 'q':
|
|
224
|
-
console.log('');
|
|
225
|
-
displaySystemMessage('Goodbye!', 'info');
|
|
226
|
-
rl.close();
|
|
227
|
-
process.exit(0);
|
|
228
|
-
|
|
229
|
-
case 'clear':
|
|
230
|
-
case 'c':
|
|
231
|
-
console.clear();
|
|
232
|
-
displayWelcome(VERSION, config.getApiUrl(), config.get('defaultModel') || 'NexusForge');
|
|
233
|
-
break;
|
|
234
|
-
|
|
235
|
-
case 'history':
|
|
236
|
-
displayHistory();
|
|
237
|
-
break;
|
|
238
|
-
|
|
239
|
-
case 'resume':
|
|
240
|
-
await resumeConversation(args[0]);
|
|
241
|
-
break;
|
|
242
|
-
|
|
243
|
-
case 'model':
|
|
244
|
-
if (args[0]) {
|
|
245
|
-
config.set('defaultModel', args[0]);
|
|
246
|
-
displaySystemMessage(`Model set to: ${args[0]}`, 'success');
|
|
247
|
-
} else {
|
|
248
|
-
displaySystemMessage(`Current model: ${config.get('defaultModel')}`, 'info');
|
|
249
|
-
}
|
|
250
|
-
break;
|
|
251
|
-
|
|
252
|
-
case 'status':
|
|
253
|
-
await displayStatus();
|
|
254
|
-
break;
|
|
255
|
-
|
|
256
|
-
case 'read':
|
|
257
|
-
if (args[0]) {
|
|
258
|
-
await readFile(args[0]);
|
|
259
|
-
} else {
|
|
260
|
-
displaySystemMessage('Usage: /read <file_path>', 'warning');
|
|
261
|
-
}
|
|
262
|
-
break;
|
|
263
|
-
|
|
264
|
-
case 'exec':
|
|
265
|
-
case 'run':
|
|
266
|
-
if (args.length > 0) {
|
|
267
|
-
const cmd = args.join(' ');
|
|
268
|
-
const result = await executor.executeCommandStream(cmd, undefined,
|
|
269
|
-
(data) => process.stdout.write(data),
|
|
270
|
-
(data) => process.stderr.write(style.error(data))
|
|
271
|
-
);
|
|
272
|
-
executor.displayCommandResult(result);
|
|
273
|
-
} else {
|
|
274
|
-
displaySystemMessage('Usage: /exec <command>', 'warning');
|
|
275
|
-
}
|
|
276
|
-
break;
|
|
277
|
-
|
|
278
|
-
default:
|
|
279
|
-
displaySystemMessage(`Unknown command: /${command}. Type /help for available commands.`, 'warning');
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
/**
|
|
284
|
-
* Display help
|
|
285
|
-
*/
|
|
286
|
-
function displayHelp(): void {
|
|
287
|
-
console.log('');
|
|
288
|
-
console.log(style.assistant('Available Commands:'));
|
|
289
|
-
console.log(style.divider());
|
|
290
|
-
console.log('');
|
|
291
|
-
console.log(` ${style.prompt('/help, /h')} - Show this help`);
|
|
292
|
-
console.log(` ${style.prompt('/exit, /q')} - Exit CLI`);
|
|
293
|
-
console.log(` ${style.prompt('/clear, /c')} - Clear screen`);
|
|
294
|
-
console.log(` ${style.prompt('/history')} - Show conversation history`);
|
|
295
|
-
console.log(` ${style.prompt('/resume [id]')} - Resume a previous conversation`);
|
|
296
|
-
console.log(` ${style.prompt('/model [name]')} - Get or set the model`);
|
|
297
|
-
console.log(` ${style.prompt('/status')} - Show connection status`);
|
|
298
|
-
console.log(` ${style.prompt('/read <path>')} - Read a file into context`);
|
|
299
|
-
console.log(` ${style.prompt('/exec <cmd>')} - Execute a shell command`);
|
|
300
|
-
console.log('');
|
|
301
|
-
console.log(style.muted('Just type your message to chat with NexusForge!'));
|
|
302
|
-
console.log('');
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
/**
|
|
306
|
-
* Display conversation history
|
|
307
|
-
*/
|
|
308
|
-
function displayHistory(): void {
|
|
309
|
-
console.log('');
|
|
310
|
-
if (messages.length === 0) {
|
|
311
|
-
displaySystemMessage('No messages in current conversation.', 'info');
|
|
312
|
-
return;
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
console.log(style.assistant('Conversation History:'));
|
|
316
|
-
console.log(style.divider());
|
|
317
|
-
console.log('');
|
|
318
|
-
|
|
319
|
-
for (const msg of messages) {
|
|
320
|
-
if (msg.role === 'user') {
|
|
321
|
-
displayUserMessage(msg.content);
|
|
322
|
-
} else {
|
|
323
|
-
displayAssistantMessage(msg.content.substring(0, 200) + (msg.content.length > 200 ? '...' : ''));
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
/**
|
|
329
|
-
* Resume a previous conversation
|
|
330
|
-
*/
|
|
331
|
-
async function resumeConversation(id?: string): Promise<void> {
|
|
332
|
-
displaySystemMessage('Resume functionality coming soon!', 'info');
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
/**
|
|
336
|
-
* Display current status
|
|
337
|
-
*/
|
|
338
|
-
async function displayStatus(): Promise<void> {
|
|
339
|
-
console.log('');
|
|
340
|
-
const user = getCurrentUser();
|
|
341
|
-
displaySystemMessage(`User: ${user?.username || 'Unknown'}`, 'info');
|
|
342
|
-
displaySystemMessage(`API: ${config.getApiUrl()}`, 'info');
|
|
343
|
-
displaySystemMessage(`Model: ${config.get('defaultModel')}`, 'info');
|
|
344
|
-
displaySystemMessage(`Conversation: ${conversationId || 'New'}`, 'info');
|
|
345
|
-
displaySystemMessage(`Messages: ${messages.length}`, 'info');
|
|
346
|
-
displaySystemMessage(`CWD: ${executor.getCwd()}`, 'info');
|
|
347
|
-
console.log('');
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
/**
|
|
351
|
-
* Read a file and display it
|
|
352
|
-
*/
|
|
353
|
-
async function readFile(path: string): Promise<void> {
|
|
354
|
-
const fs = await import('fs/promises');
|
|
355
|
-
try {
|
|
356
|
-
const content = await fs.readFile(path, 'utf-8');
|
|
357
|
-
console.log('');
|
|
358
|
-
console.log(style.muted(`--- ${path} ---`));
|
|
359
|
-
console.log(style.code(content));
|
|
360
|
-
console.log(style.muted(`--- end ${path} ---`));
|
|
361
|
-
console.log('');
|
|
362
|
-
displaySystemMessage(`File "${path}" added to context.`, 'success');
|
|
363
|
-
} catch (error) {
|
|
364
|
-
displaySystemMessage(`Cannot read file: ${path}`, 'error');
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
/**
|
|
369
|
-
* Prompt user to execute detected commands
|
|
370
|
-
*/
|
|
371
|
-
async function promptToExecuteCommands(
|
|
372
|
-
commands: string[],
|
|
373
|
-
rl: readline.Interface,
|
|
374
|
-
): Promise<void> {
|
|
375
|
-
console.log('');
|
|
376
|
-
displaySystemMessage(`Found ${commands.length} command(s) in response:`, 'info');
|
|
377
|
-
|
|
378
|
-
for (let i = 0; i < commands.length; i++) {
|
|
379
|
-
console.log(style.muted(` ${i + 1}. ${commands[i]}`));
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
console.log('');
|
|
383
|
-
|
|
384
|
-
return new Promise((resolve) => {
|
|
385
|
-
rl.question(
|
|
386
|
-
`${style.prompt('Execute these commands? [y/N/1-n]: ')}`,
|
|
387
|
-
async (answer) => {
|
|
388
|
-
const trimmed = answer.trim().toLowerCase();
|
|
389
|
-
|
|
390
|
-
if (trimmed === 'y' || trimmed === 'yes') {
|
|
391
|
-
// Execute all commands
|
|
392
|
-
for (const cmd of commands) {
|
|
393
|
-
if (executor.isDangerous(cmd)) {
|
|
394
|
-
displaySystemMessage(`Skipping dangerous command: ${cmd}`, 'warning');
|
|
395
|
-
continue;
|
|
396
|
-
}
|
|
397
|
-
const result = await executor.executeCommandStream(cmd, undefined,
|
|
398
|
-
(data) => process.stdout.write(data),
|
|
399
|
-
(data) => process.stderr.write(style.error(data))
|
|
400
|
-
);
|
|
401
|
-
if (result.exitCode !== 0) {
|
|
402
|
-
displaySystemMessage(`Command failed with exit code ${result.exitCode}`, 'error');
|
|
403
|
-
break;
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
} else if (/^\d+$/.test(trimmed)) {
|
|
407
|
-
// Execute specific command
|
|
408
|
-
const index = parseInt(trimmed, 10) - 1;
|
|
409
|
-
if (index >= 0 && index < commands.length) {
|
|
410
|
-
const cmd = commands[index];
|
|
411
|
-
if (executor.isDangerous(cmd)) {
|
|
412
|
-
displaySystemMessage(`Cannot execute dangerous command`, 'error');
|
|
413
|
-
} else {
|
|
414
|
-
const result = await executor.executeCommandStream(cmd, undefined,
|
|
415
|
-
(data) => process.stdout.write(data),
|
|
416
|
-
(data) => process.stderr.write(style.error(data))
|
|
417
|
-
);
|
|
418
|
-
executor.displayCommandResult(result);
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
resolve();
|
|
424
|
-
},
|
|
425
|
-
);
|
|
426
|
-
});
|
|
427
|
-
}
|