feat(ui): 实现 @ 文件提及自动补全功能

- Core: 添加 file-index 模块,使用 ripgrep 索引文件,fuzzysort 模糊搜索
- Server: 添加 /api/files/search 端点,支持文件模糊搜索
- Server: WebSocket 消息处理中将 @filepath 转换为 ./filepath 格式
- UI: 新增 FileMenu 组件,显示文件搜索结果列表
- UI: 新增 FileMentionTag 组件,高亮显示文件提及
- UI: 新增 useFileMention hook,管理文件提及状态
- UI: ChatInput 集成 @ 触发的文件自动补全
- UI: ChatMessage 用户消息中高亮显示 @filepath
This commit is contained in:
2025-12-15 16:32:59 +08:00
parent 5b7b0ff1e4
commit 865e0906b9
15 changed files with 1137 additions and 53 deletions
+30
View File
@@ -7,6 +7,7 @@
import { Hono } from 'hono';
import { readdir, stat, readFile } from 'node:fs/promises';
import { join, resolve, basename, extname, dirname } from 'node:path';
import { searchFiles as coreSearchFiles, type FileIndexEntry } from '@ai-assistant/core';
const filesRouter = new Hono();
@@ -368,4 +369,33 @@ filesRouter.get('/tree', async (c) => {
}
});
// ============================================================================
// GET /api/files/search?query=&limit=&type= - 模糊搜索文件
// ============================================================================
filesRouter.get('/search', async (c) => {
const query = c.req.query('query') || '';
const limit = parseInt(c.req.query('limit') || '10', 10);
const type = (c.req.query('type') || 'file') as 'file' | 'directory' | 'all';
try {
const results = await coreSearchFiles({
query,
limit,
type,
cwd: workingDirectory,
});
return c.json({
success: true,
data: {
files: results,
total: results.length,
},
});
} catch (error) {
const message = error instanceof Error ? error.message : 'Unknown error';
return c.json({ success: false, error: message }, 500);
}
});
export { filesRouter };