EasyAgent/demo/lib/ui/command_menu.js
2026-02-28 03:00:08 +08:00

84 lines
2.7 KiB
JavaScript

'use strict';
const readline = require('readline');
const COMMAND_CHOICES = [
{ value: '/new', desc: '创建新对话' },
{ value: '/resume', desc: '加载旧对话' },
{ value: '/allow', desc: '切换运行模式(只读/无限制)' },
{ value: '/model', desc: '切换模型和思考模式' },
{ value: '/status', desc: '查看当前对话状态' },
{ value: '/compact', desc: '压缩当前对话' },
{ value: '/config', desc: '查看当前配置' },
{ value: '/help', desc: '显示指令列表' },
{ value: '/exit', desc: '退出程序' },
];
async function openCommandMenu(options) {
const { rl, prompt, pageSize, colorEnabled, resetAnsi, onInput } = options;
let latestInput = '';
rl.pause();
rl.line = '';
rl.cursor = 0;
readline.clearLine(process.stdout, 0);
readline.cursorTo(process.stdout, 0);
try {
const { default: search } = await import('@inquirer/search');
const chosen = await search({
message: prompt.trimEnd(),
pageSize,
theme: {
helpMode: 'never',
prefix: '',
icon: { cursor: '>' },
style: {
message: (text) => text,
searchTerm: (text) => `/${(text || '').replace(/^\/+/, '')}`,
highlight: (text) => (colorEnabled ? `\x1b[94m${text}${resetAnsi}` : text),
keysHelpTip: () => '',
description: (text) => text,
answer: () => '',
},
},
source: async (input) => {
latestInput = input || '';
if (typeof onInput === 'function') onInput(latestInput);
const term = latestInput.replace(/^\/+/, '').toLowerCase();
const maxCmdLen = Math.max(...COMMAND_CHOICES.map((c) => c.value.length));
const indentLen = Math.max(0, prompt.length - 2);
const indent = ' '.repeat(indentLen);
const format = (c) => {
const pad = ' '.repeat(Math.max(1, maxCmdLen - c.value.length + 2));
return `${indent}${c.value}${pad}${c.desc}`;
};
const filtered = term
? COMMAND_CHOICES.filter((c) => {
return (
c.value.toLowerCase().includes(term) ||
c.desc.toLowerCase().includes(term)
);
})
: COMMAND_CHOICES;
return filtered.map((c) => ({
name: format(c),
value: c.value,
}));
},
});
return { chosen, term: latestInput };
} catch (err) {
console.log('指令菜单不可用,请先安装依赖: npm i @inquirer/search');
return { chosen: null, term: '' };
} finally {
if (process.stdin.isTTY) process.stdin.setRawMode(true);
process.stdin.resume();
try {
rl.resume();
} catch (_) {}
}
}
module.exports = { openCommandMenu };