a476a4240c
实现类似 OpenCode 的 Commands 功能: - 支持 Markdown 格式定义命令,带 YAML frontmatter - 变量替换:$ARGUMENTS, $1/$2, @filepath, !`shell` - 三级加载:builtin < user < project - 7 个内置命令:init, review, test, fix, explain, commit, help - 集成终端 UI 支持 /commands 列表和命令执行 - 完整单元测试覆盖 (46 tests)
163 lines
4.5 KiB
JavaScript
163 lines
4.5 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
import { Command } from 'commander';
|
|
import { Agent } from './core/agent.js';
|
|
import { TerminalUI } from './ui/terminal.js';
|
|
import { loadConfig, initConfig } from './utils/config.js';
|
|
import { toolRegistry, todoManager, initTaskContext, updateTaskDescription, updateSkillDescription } from './tools/index.js';
|
|
import { getPermissionManager, promptPermission } from './permission/index.js';
|
|
import { SessionManager } from './session/index.js';
|
|
import { agentRegistry } from './agent/index.js';
|
|
import { initLSP, shutdownLSP } from './lsp/index.js';
|
|
import { getCommandRegistry } from './commands/index.js';
|
|
import { getSkillRegistry } from './skills/index.js';
|
|
import {
|
|
printServerList,
|
|
installServer,
|
|
installAllServers,
|
|
showServerInfo,
|
|
} from './lsp/cli.js';
|
|
|
|
const program = new Command();
|
|
|
|
program
|
|
.name('ai-assist')
|
|
.description('AI Terminal Assistant - 终端中的 AI 编程助手')
|
|
.version('1.0.0');
|
|
|
|
// 初始化命令
|
|
program
|
|
.command('init')
|
|
.description('初始化配置(设置 API Key 等)')
|
|
.action(async () => {
|
|
await initConfig();
|
|
});
|
|
|
|
// LSP 命令组
|
|
const lspCommand = program
|
|
.command('lsp')
|
|
.description('语言服务器管理');
|
|
|
|
lspCommand
|
|
.command('list')
|
|
.description('列出所有语言服务器及其安装状态')
|
|
.action(() => {
|
|
printServerList();
|
|
});
|
|
|
|
lspCommand
|
|
.command('install [servers...]')
|
|
.description('安装指定的语言服务器')
|
|
.option('-a, --all', '安装所有语言服务器')
|
|
.action(async (servers: string[], options: { all?: boolean }) => {
|
|
if (options.all) {
|
|
await installAllServers();
|
|
} else if (servers.length === 0) {
|
|
console.log('用法: ai-assist lsp install <server> [server2] ...');
|
|
console.log(' ai-assist lsp install --all');
|
|
console.log('\n运行 "ai-assist lsp list" 查看可用的服务器');
|
|
} else {
|
|
for (const server of servers) {
|
|
await installServer(server);
|
|
}
|
|
}
|
|
});
|
|
|
|
lspCommand
|
|
.command('info <server>')
|
|
.description('显示语言服务器详细信息')
|
|
.action((server: string) => {
|
|
showServerInfo(server);
|
|
});
|
|
|
|
// 初始化权限系统
|
|
function setupPermissions(): void {
|
|
const permissionManager = getPermissionManager();
|
|
permissionManager.setAskCallback(promptPermission);
|
|
}
|
|
|
|
// 单次查询命令
|
|
program
|
|
.command('ask <question>')
|
|
.description('单次提问(不进入交互模式)')
|
|
.action(async (question: string) => {
|
|
setupPermissions();
|
|
const config = loadConfig();
|
|
const agent = new Agent(config);
|
|
|
|
// 设置工具注册表(支持动态工具发现)
|
|
agent.setRegistry(toolRegistry);
|
|
|
|
try {
|
|
await agent.chat(question, (text) => {
|
|
process.stdout.write(text);
|
|
});
|
|
console.log('');
|
|
} catch (error) {
|
|
console.error(
|
|
'错误:',
|
|
error instanceof Error ? error.message : String(error)
|
|
);
|
|
process.exit(1);
|
|
}
|
|
});
|
|
|
|
// 默认:交互模式
|
|
program.action(async () => {
|
|
setupPermissions();
|
|
const config = loadConfig();
|
|
const agent = new Agent(config);
|
|
|
|
// 初始化 LSP 系统
|
|
initLSP(process.cwd());
|
|
|
|
// 设置工具注册表(支持动态工具发现)
|
|
agent.setRegistry(toolRegistry);
|
|
|
|
// 初始化会话管理器(支持会话持久化)
|
|
const sessionManager = new SessionManager();
|
|
await sessionManager.init(process.cwd());
|
|
agent.setSessionManager(sessionManager);
|
|
|
|
// 初始化 todoManager(让 todo 工具可以访问会话)
|
|
todoManager.setSessionManager(sessionManager);
|
|
|
|
// 初始化 Agent 注册表(加载预设和用户配置)
|
|
await agentRegistry.init(process.cwd());
|
|
|
|
// 初始化 Task 工具上下文
|
|
initTaskContext(config, sessionManager);
|
|
updateTaskDescription();
|
|
|
|
// 初始化 Skill 注册表
|
|
const skillRegistry = getSkillRegistry();
|
|
await skillRegistry.initialize(process.cwd());
|
|
updateSkillDescription();
|
|
|
|
// 初始化 Command 注册表
|
|
const commandRegistry = getCommandRegistry();
|
|
await commandRegistry.initialize(process.cwd());
|
|
|
|
// 显示会话恢复信息
|
|
const session = sessionManager.getSession();
|
|
if (session && session.messages.length > 0) {
|
|
console.log(`\n📂 已恢复会话 (${session.messages.length} 条消息)`);
|
|
}
|
|
|
|
// 启动终端 UI
|
|
const ui = new TerminalUI(agent);
|
|
|
|
// 优雅退出
|
|
process.on('SIGINT', async () => {
|
|
console.log('\n\n👋 再见!');
|
|
await shutdownLSP();
|
|
await sessionManager.close();
|
|
ui.close();
|
|
process.exit(0);
|
|
});
|
|
|
|
await ui.start();
|
|
});
|
|
|
|
program.parse();
|