@quangnv13/nonstop 1.0.3 → 1.0.5
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/dist/ui.js +51 -56
- package/package.json +1 -1
package/dist/ui.js
CHANGED
|
@@ -67,12 +67,22 @@ function infoRow(label, value, valueColor = (s) => s) {
|
|
|
67
67
|
function separator() {
|
|
68
68
|
return chalk_1.default.gray(' ' + '─'.repeat(44));
|
|
69
69
|
}
|
|
70
|
-
async function
|
|
71
|
-
|
|
70
|
+
async function askQuestion(query) {
|
|
71
|
+
const rl = (0, promises_1.createInterface)({ input: node_process_1.stdin, output: node_process_1.stdout });
|
|
72
|
+
try {
|
|
73
|
+
return await rl.question(query);
|
|
74
|
+
}
|
|
75
|
+
finally {
|
|
76
|
+
rl.close();
|
|
77
|
+
process.stdin.resume();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async function pause() {
|
|
81
|
+
await askQuestion(`\n${chalk_1.default.gray('Nhấn Enter để tiếp tục...')}`);
|
|
72
82
|
}
|
|
73
|
-
async function askWithDefault(
|
|
83
|
+
async function askWithDefault(label, currentValue) {
|
|
74
84
|
const prompt = `${chalk_1.default.bold(label)}${currentValue ? chalk_1.default.gray(` [${currentValue}]`) : ''}: `;
|
|
75
|
-
const answer = await
|
|
85
|
+
const answer = await askQuestion(prompt);
|
|
76
86
|
return answer.trim() || currentValue;
|
|
77
87
|
}
|
|
78
88
|
async function runSelectionMenu(headerRenderer, options, initialIndex = 0) {
|
|
@@ -172,10 +182,9 @@ async function launchControlCenter() {
|
|
|
172
182
|
let config = (0, config_js_1.loadConfigFromDisk)();
|
|
173
183
|
const isTTY = process.stdin.isTTY;
|
|
174
184
|
const wasRaw = process.stdin.isRaw;
|
|
175
|
-
const rl = (0, promises_1.createInterface)({ input: node_process_1.stdin, output: node_process_1.stdout });
|
|
176
185
|
try {
|
|
177
186
|
if ((0, config_js_1.getMissingConfigFields)(config).length > 0) {
|
|
178
|
-
config = await runSetupWizard(config
|
|
187
|
+
config = await runSetupWizard(config);
|
|
179
188
|
}
|
|
180
189
|
let lastSelection = 0;
|
|
181
190
|
while (true) {
|
|
@@ -195,42 +204,39 @@ async function launchControlCenter() {
|
|
|
195
204
|
{ label: t('menu.logs'), value: 'logs' },
|
|
196
205
|
{ label: t('menu.exit'), value: 'exit' }
|
|
197
206
|
];
|
|
198
|
-
rl.pause();
|
|
199
207
|
const choice = await runSelectionMenu(() => renderDashboardHeader(config, (0, runtime_manager_js_1.getRuntimeStatus)().snapshot), options, lastSelection);
|
|
200
|
-
rl.resume();
|
|
201
208
|
lastSelection = options.findIndex(opt => opt.value === choice);
|
|
202
209
|
if (lastSelection < 0)
|
|
203
210
|
lastSelection = 0;
|
|
204
211
|
if (choice === 'exit')
|
|
205
212
|
break;
|
|
206
213
|
if (choice === 'toggle') {
|
|
207
|
-
await handleToggleRuntime(config
|
|
214
|
+
await handleToggleRuntime(config);
|
|
208
215
|
continue;
|
|
209
216
|
}
|
|
210
217
|
if (choice === 'settings') {
|
|
211
|
-
config = await editConfig(config
|
|
218
|
+
config = await editConfig(config);
|
|
212
219
|
continue;
|
|
213
220
|
}
|
|
214
221
|
if (choice === 'workspaces') {
|
|
215
|
-
await manageWorkspaces(
|
|
222
|
+
await manageWorkspaces(config.language);
|
|
216
223
|
continue;
|
|
217
224
|
}
|
|
218
225
|
if (choice === 'startup') {
|
|
219
|
-
config = await configureStartup(config
|
|
226
|
+
config = await configureStartup(config);
|
|
220
227
|
continue;
|
|
221
228
|
}
|
|
222
229
|
if (choice === 'language') {
|
|
223
|
-
config = await switchLanguage(config
|
|
230
|
+
config = await switchLanguage(config);
|
|
224
231
|
continue;
|
|
225
232
|
}
|
|
226
233
|
if (choice === 'logs') {
|
|
227
|
-
await showRecentLogs(
|
|
234
|
+
await showRecentLogs();
|
|
228
235
|
continue;
|
|
229
236
|
}
|
|
230
237
|
}
|
|
231
238
|
}
|
|
232
239
|
finally {
|
|
233
|
-
rl.close();
|
|
234
240
|
process.stdout.write('\u001b[?25h');
|
|
235
241
|
if (isTTY) {
|
|
236
242
|
try {
|
|
@@ -242,8 +248,7 @@ async function launchControlCenter() {
|
|
|
242
248
|
console.log(chalk_1.default.gray('Đã thoát nonstop client.'));
|
|
243
249
|
}
|
|
244
250
|
}
|
|
245
|
-
async function runSetupWizard(currentConfig
|
|
246
|
-
rl.pause();
|
|
251
|
+
async function runSetupWizard(currentConfig) {
|
|
247
252
|
const language = await runSelectionMenu(() => {
|
|
248
253
|
console.log(titleBox('Thiết lập nonstop'));
|
|
249
254
|
console.log(chalk_1.default.gray(' Chọn ngôn ngữ / Choose language:'));
|
|
@@ -251,15 +256,13 @@ async function runSetupWizard(currentConfig, rl) {
|
|
|
251
256
|
{ label: 'Tiếng Việt (vi)', value: 'vi' },
|
|
252
257
|
{ label: 'English (en)', value: 'en' }
|
|
253
258
|
], currentConfig.language === 'en' ? 1 : 0);
|
|
254
|
-
rl.resume();
|
|
255
259
|
const t = (0, i18n_js_1.createTranslator)(language);
|
|
256
260
|
clearScreen();
|
|
257
261
|
console.log(titleBox(t('wizard.title')));
|
|
258
262
|
console.log('');
|
|
259
|
-
const telegramBotToken = await askWithDefault(
|
|
260
|
-
const adminUsername = await askWithDefault(
|
|
261
|
-
const clientName = await askWithDefault(
|
|
262
|
-
rl.pause();
|
|
263
|
+
const telegramBotToken = await askWithDefault(t('wizard.token'), currentConfig.telegramBotToken);
|
|
264
|
+
const adminUsername = await askWithDefault(t('wizard.admin'), currentConfig.adminUsername);
|
|
265
|
+
const clientName = await askWithDefault(t('wizard.clientName'), currentConfig.clientName);
|
|
263
266
|
const startupMode = await runSelectionMenu(() => {
|
|
264
267
|
console.log(titleBox(t('wizard.title')));
|
|
265
268
|
console.log(chalk_1.default.gray(` ${t('wizard.startupMode')}:`));
|
|
@@ -268,7 +271,6 @@ async function runSetupWizard(currentConfig, rl) {
|
|
|
268
271
|
{ label: `Chạy nền (background)`, value: 'background' },
|
|
269
272
|
{ label: `Mở giao diện (open-ui)`, value: 'open-ui' }
|
|
270
273
|
], 0);
|
|
271
|
-
rl.resume();
|
|
272
274
|
const nextConfig = {
|
|
273
275
|
...currentConfig,
|
|
274
276
|
language,
|
|
@@ -282,10 +284,10 @@ async function runSetupWizard(currentConfig, rl) {
|
|
|
282
284
|
clearScreen();
|
|
283
285
|
console.log(titleBox(t('wizard.title')));
|
|
284
286
|
console.log(`\n${chalk_1.default.green(t('wizard.complete'))}`);
|
|
285
|
-
await pause(
|
|
287
|
+
await pause();
|
|
286
288
|
return nextConfig;
|
|
287
289
|
}
|
|
288
|
-
async function handleToggleRuntime(config
|
|
290
|
+
async function handleToggleRuntime(config) {
|
|
289
291
|
const status = (0, runtime_manager_js_1.getRuntimeStatus)();
|
|
290
292
|
const targetState = !status.running;
|
|
291
293
|
clearScreen();
|
|
@@ -308,31 +310,30 @@ async function handleToggleRuntime(config, rl) {
|
|
|
308
310
|
}
|
|
309
311
|
catch (error) {
|
|
310
312
|
console.log(`\n${chalk_1.default.red(error instanceof Error ? error.message : String(error))}`);
|
|
311
|
-
await pause(
|
|
313
|
+
await pause();
|
|
312
314
|
return;
|
|
313
315
|
}
|
|
314
|
-
// Không pause — quay lại menu ngay để trạng thái cập nhật tức thì
|
|
315
316
|
}
|
|
316
|
-
async function editConfig(config
|
|
317
|
+
async function editConfig(config) {
|
|
317
318
|
clearScreen();
|
|
318
319
|
console.log(titleBox('Sửa cấu hình'));
|
|
319
320
|
console.log('');
|
|
320
321
|
const nextConfig = {
|
|
321
322
|
...config,
|
|
322
|
-
telegramBotToken: await askWithDefault(
|
|
323
|
-
adminUsername: await askWithDefault(
|
|
324
|
-
clientName: await askWithDefault(
|
|
325
|
-
telegramUsername: await askWithDefault(
|
|
326
|
-
codexCmd: await askWithDefault(
|
|
327
|
-
antigravityCmd: await askWithDefault(
|
|
323
|
+
telegramBotToken: await askWithDefault('TELEGRAM_BOT_TOKEN', config.telegramBotToken),
|
|
324
|
+
adminUsername: await askWithDefault('ADMIN_USERNAME', config.adminUsername),
|
|
325
|
+
clientName: await askWithDefault('CLIENT_NAME', config.clientName),
|
|
326
|
+
telegramUsername: await askWithDefault('TELEGRAM_USERNAME', config.telegramUsername),
|
|
327
|
+
codexCmd: await askWithDefault('CODEX_CMD', config.codexCmd),
|
|
328
|
+
antigravityCmd: await askWithDefault('ANTIGRAVITY_CMD', config.antigravityCmd)
|
|
328
329
|
};
|
|
329
330
|
(0, config_js_1.saveConfigToDisk)(nextConfig);
|
|
330
331
|
console.log(`\n${chalk_1.default.green('✓ Đã lưu cấu hình.')}`);
|
|
331
332
|
console.log(chalk_1.default.gray('Khởi động lại runtime nền nếu đang chạy để áp dụng thay đổi.'));
|
|
332
|
-
await pause(
|
|
333
|
+
await pause();
|
|
333
334
|
return nextConfig;
|
|
334
335
|
}
|
|
335
|
-
async function manageWorkspaces(
|
|
336
|
+
async function manageWorkspaces(language) {
|
|
336
337
|
const isVi = language === 'vi';
|
|
337
338
|
while (true) {
|
|
338
339
|
const workspaces = (0, store_js_1.loadWorkspaces)();
|
|
@@ -344,23 +345,21 @@ async function manageWorkspaces(rl, language) {
|
|
|
344
345
|
})),
|
|
345
346
|
{ label: isVi ? '← Quay lại menu chính' : '← Back', value: { type: 'back' } }
|
|
346
347
|
];
|
|
347
|
-
rl.pause();
|
|
348
348
|
const selection = await runSelectionMenu(() => {
|
|
349
349
|
console.log(titleBox(isVi ? 'Quản lý Workspace' : 'Manage Workspaces'));
|
|
350
350
|
console.log(chalk_1.default.gray(` ${isVi ? 'Chọn workspace hoặc thêm mới:' : 'Select workspace or add new:'}`));
|
|
351
351
|
}, options);
|
|
352
|
-
rl.resume();
|
|
353
352
|
if (selection.type === 'back')
|
|
354
353
|
return;
|
|
355
354
|
if (selection.type === 'add') {
|
|
356
355
|
clearScreen();
|
|
357
356
|
console.log(titleBox(isVi ? 'Thêm workspace mới' : 'Add workspace'));
|
|
358
357
|
console.log('');
|
|
359
|
-
const name = (await
|
|
360
|
-
const rawPath = (await
|
|
358
|
+
const name = (await askQuestion(chalk_1.default.bold(isVi ? 'Tên workspace: ' : 'Workspace name: '))).trim();
|
|
359
|
+
const rawPath = (await askQuestion(chalk_1.default.bold(isVi ? 'Đường dẫn: ' : 'Path: '))).trim();
|
|
361
360
|
if (!rawPath) {
|
|
362
361
|
console.log(chalk_1.default.red(isVi ? ' Đường dẫn không được để trống.' : ' Path cannot be empty.'));
|
|
363
|
-
await pause(
|
|
362
|
+
await pause();
|
|
364
363
|
continue;
|
|
365
364
|
}
|
|
366
365
|
const resolvedPath = path.resolve(rawPath);
|
|
@@ -370,7 +369,7 @@ async function manageWorkspaces(rl, language) {
|
|
|
370
369
|
workspaces.push({ id: (0, store_js_1.createWorkspaceId)(), name: name || 'Workspace', path: resolvedPath });
|
|
371
370
|
(0, store_js_1.saveWorkspaces)(workspaces);
|
|
372
371
|
console.log(chalk_1.default.green(`\n ✓ ${isVi ? 'Đã thêm workspace.' : 'Workspace added.'}`));
|
|
373
|
-
await pause(
|
|
372
|
+
await pause();
|
|
374
373
|
continue;
|
|
375
374
|
}
|
|
376
375
|
if (selection.type === 'workspace' && typeof selection.index === 'number') {
|
|
@@ -392,15 +391,15 @@ async function manageWorkspaces(rl, language) {
|
|
|
392
391
|
(0, store_js_1.saveWorkspaces)(workspaces);
|
|
393
392
|
clearScreen();
|
|
394
393
|
console.log(chalk_1.default.green(`\n ✓ ${isVi ? 'Đã xóa workspace.' : 'Workspace deleted.'}`));
|
|
395
|
-
await pause(
|
|
394
|
+
await pause();
|
|
396
395
|
continue;
|
|
397
396
|
}
|
|
398
397
|
if (action === 'edit') {
|
|
399
398
|
clearScreen();
|
|
400
399
|
console.log(titleBox(isVi ? 'Sửa workspace' : 'Edit workspace'));
|
|
401
400
|
console.log('');
|
|
402
|
-
const newName = await askWithDefault(
|
|
403
|
-
const newPath = await askWithDefault(
|
|
401
|
+
const newName = await askWithDefault(isVi ? 'Tên mới' : 'New name', ws.name);
|
|
402
|
+
const newPath = await askWithDefault(isVi ? 'Đường dẫn mới' : 'New path', ws.path);
|
|
404
403
|
const resolvedPath = path.resolve(newPath.trim());
|
|
405
404
|
if (!fs.existsSync(resolvedPath)) {
|
|
406
405
|
console.log(chalk_1.default.yellow(` ⚠ ${isVi ? 'Đường dẫn không tồn tại.' : 'Path does not exist.'}`));
|
|
@@ -408,15 +407,14 @@ async function manageWorkspaces(rl, language) {
|
|
|
408
407
|
workspaces[idx] = { ...ws, name: newName.trim() || ws.name, path: resolvedPath };
|
|
409
408
|
(0, store_js_1.saveWorkspaces)(workspaces);
|
|
410
409
|
console.log(chalk_1.default.green(`\n ✓ ${isVi ? 'Đã cập nhật workspace.' : 'Workspace updated.'}`));
|
|
411
|
-
await pause(
|
|
410
|
+
await pause();
|
|
412
411
|
continue;
|
|
413
412
|
}
|
|
414
413
|
}
|
|
415
414
|
}
|
|
416
415
|
}
|
|
417
|
-
async function configureStartup(config
|
|
416
|
+
async function configureStartup(config) {
|
|
418
417
|
const isVi = config.language === 'vi';
|
|
419
|
-
rl.pause();
|
|
420
418
|
const nextMode = await runSelectionMenu(() => {
|
|
421
419
|
console.log(titleBox(isVi ? 'Cấu hình khởi động' : 'Configure startup'));
|
|
422
420
|
console.log(chalk_1.default.gray(` ${isVi ? 'Chế độ hiện tại:' : 'Current mode:'} ${config.startupMode}`));
|
|
@@ -425,7 +423,6 @@ async function configureStartup(config, rl) {
|
|
|
425
423
|
{ label: isVi ? 'Chạy nền (background)' : 'Background', value: 'background' },
|
|
426
424
|
{ label: isVi ? 'Mở giao diện (open-ui)' : 'Open UI', value: 'open-ui' }
|
|
427
425
|
], ['disabled', 'background', 'open-ui'].indexOf(config.startupMode));
|
|
428
|
-
rl.resume();
|
|
429
426
|
const entryScriptPath = path.join(process.cwd(), 'dist', 'index.js');
|
|
430
427
|
const result = (0, startup_js_1.applyStartupMode)(nextMode, entryScriptPath, process.cwd());
|
|
431
428
|
const nextConfig = { ...config, startupMode: nextMode };
|
|
@@ -433,11 +430,10 @@ async function configureStartup(config, rl) {
|
|
|
433
430
|
clearScreen();
|
|
434
431
|
console.log(titleBox(isVi ? 'Cấu hình khởi động' : 'Configure startup'));
|
|
435
432
|
console.log(`\n${chalk_1.default.green(result)}`);
|
|
436
|
-
await pause(
|
|
433
|
+
await pause();
|
|
437
434
|
return nextConfig;
|
|
438
435
|
}
|
|
439
|
-
async function switchLanguage(config
|
|
440
|
-
rl.pause();
|
|
436
|
+
async function switchLanguage(config) {
|
|
441
437
|
const language = await runSelectionMenu(() => {
|
|
442
438
|
console.log(titleBox('Đổi ngôn ngữ / Switch language'));
|
|
443
439
|
console.log(chalk_1.default.gray(` Hiện tại: ${config.language}`));
|
|
@@ -445,21 +441,20 @@ async function switchLanguage(config, rl) {
|
|
|
445
441
|
{ label: 'Tiếng Việt (vi)', value: 'vi' },
|
|
446
442
|
{ label: 'English (en)', value: 'en' }
|
|
447
443
|
], config.language === 'en' ? 1 : 0);
|
|
448
|
-
rl.resume();
|
|
449
444
|
const nextConfig = { ...config, language };
|
|
450
445
|
(0, config_js_1.saveConfigToDisk)(nextConfig);
|
|
451
446
|
return nextConfig;
|
|
452
447
|
}
|
|
453
|
-
async function showRecentLogs(
|
|
448
|
+
async function showRecentLogs() {
|
|
454
449
|
clearScreen();
|
|
455
450
|
console.log(titleBox('Nhật ký gần đây'));
|
|
456
451
|
const logPath = path.join(process.cwd(), 'data', 'nonstop.log');
|
|
457
452
|
if (!fs.existsSync(logPath)) {
|
|
458
453
|
console.log(chalk_1.default.gray('\n Chưa có nhật ký.'));
|
|
459
|
-
await pause(
|
|
454
|
+
await pause();
|
|
460
455
|
return;
|
|
461
456
|
}
|
|
462
457
|
const lines = fs.readFileSync(logPath, 'utf8').split(/\r?\n/).filter(Boolean).slice(-25);
|
|
463
458
|
console.log('\n' + lines.map(l => chalk_1.default.gray(' ') + l).join('\n'));
|
|
464
|
-
await pause(
|
|
459
|
+
await pause();
|
|
465
460
|
}
|