-
Notifications
You must be signed in to change notification settings - Fork 0
feat(cli): add query-files command for file name search #22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,19 @@ | ||||||||||||||||||||||||||
| import { Command } from 'commander'; | ||||||||||||||||||||||||||
| import { executeHandler } from '../types.js'; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| export const queryFilesCommand = new Command('query-files') | ||||||||||||||||||||||||||
| .description('Query refs table by file name match (substring/prefix/wildcard/regex/fuzzy)') | ||||||||||||||||||||||||||
| .argument('<pattern>', 'File name pattern to search') | ||||||||||||||||||||||||||
| .option('-p, --path <path>', 'Path inside the repository', '.') | ||||||||||||||||||||||||||
| .option('--limit <n>', 'Limit results', '50') | ||||||||||||||||||||||||||
| .option('--mode <mode>', 'Mode: substring|prefix|wildcard|regex|fuzzy (default: auto)') | ||||||||||||||||||||||||||
|
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 SUGGESTION: mode 选项缺少默认值说明 选项描述中提到默认值是 auto,但命令签名中未明确显示,可能导致用户困惑 建议: 修改为:.option('--mode ', 'Mode (default: substring|prefix|wildcard|regex|fuzzy or auto)', 'auto')
Suggested change
|
||||||||||||||||||||||||||
| .option('--case-insensitive', 'Case-insensitive matching', false) | ||||||||||||||||||||||||||
| .option('--max-candidates <n>', 'Max candidates to fetch before filtering', '1000') | ||||||||||||||||||||||||||
| .option('--lang <lang>', 'Language: auto|all|java|ts|python|go|rust|c|markdown|yaml', 'auto') | ||||||||||||||||||||||||||
| .option('--with-repo-map', 'Attach a lightweight repo map (ranked files + top symbols + wiki links)', false) | ||||||||||||||||||||||||||
| .option('--repo-map-files <n>', 'Max repo map files', '20') | ||||||||||||||||||||||||||
| .option('--repo-map-symbols <n>', 'Max repo map symbols per file', '5') | ||||||||||||||||||||||||||
| .option('--wiki <dir>', 'Wiki directory (default: docs/wiki or wiki)', '') | ||||||||||||||||||||||||||
| .action(async (pattern, options) => { | ||||||||||||||||||||||||||
| await executeHandler('query-files', { pattern, ...options }); | ||||||||||||||||||||||||||
|
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. commander.js 将所有选项值作为字符串返回,但 limit、max-candidates、repo-map-files、repo-map-symbols 等应该是 number 类型,直接传递可能导致 executeHandler 中类型错误或比较失败 建议: 在传递前转换数值类型:
Suggested change
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 未验证 pattern 是否为空字符串,空 pattern 可能导致全表扫描或意外行为 建议: 添加验证:
Suggested change
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. limit、max-candidates 等数值选项未验证是否为有效的正整数,负数或非数字可能导致错误 建议: 添加验证函数:
Suggested change
|
||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,303 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import path from 'path'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import fs from 'fs-extra'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { inferWorkspaceRoot, resolveGitRoot } from '../../core/git'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { defaultDbDir, openTablesByLang, type IndexLang } from '../../core/lancedb'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { queryManifestWorkspace } from '../../core/workspace'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { inferSymbolSearchMode, type SymbolSearchMode } from '../../core/symbolSearch'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { createLogger } from '../../core/log'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { resolveLangs } from '../../core/indexCheck'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { resolveLangs } from '../../core/indexCheck'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
catch 块直接使用 String(e?.message ?? e) 将错误信息转换为字符串,可能暴露内部路径、配置或敏感系统信息
建议: 使用通用的错误消息,在日志中记录完整错误,开发环境返回详细错误
| } catch (e: any) { | |
| const safeMessage = process.env.NODE_ENV === 'production' ? 'Failed to build repo map' : String(e?.message ?? e); | |
| return { enabled: false, skippedReason: safeMessage }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
在 Node.js 14+ 中推荐使用 fs.statSync 或 fs.accessSync 配合异常处理,性能更好且更符合 Node.js 风格
建议: 使用 try-catch 块包装 fs.accessSync 检查
| if (fs.existsSync(c)) return c; | |
| for (const c of candidates) { | |
| try { | |
| fs.accessSync(c); | |
| return c; | |
| } catch { /* continue */ } | |
| } |
Copilot
AI
Feb 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
--wiki is resolved with path.resolve(repoRoot, w) without checking that the resulting path stays within repoRoot. Since generateRepoMap will read markdown files from wikiDir, this allows reading arbitrary filesystem locations when a user passes --wiki ../../.... Consider rejecting paths that escape repoRoot (similar to resolveWikiDirInsideRepo in the MCP handler) and returning a clear error or disabling wiki attachment in that case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
将字符串断言为 IndexLang 类型时未验证是否有效值,可能导致后续代码在非法语言类型上失败
建议: 先验证输入值是否在 IndexLang 的合法值列表中
| const target = sel as IndexLang; | |
| const validLangs: IndexLang[] = ['ts', 'python', 'java', 'rust', 'go', 'c', 'markdown', 'yaml']; | |
| const target = validLangs.includes(sel as IndexLang) ? (sel as IndexLang) : undefined; | |
| return rows.filter(r => !target || inferLangFromFile(String((r as any).file ?? '')) === target); |
Copilot
AI
Feb 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file duplicates several helper utilities from queryHandlers.ts (e.g., buildRepoMapAttachment, resolveWikiDir, inferLangFromFile, filterWorkspaceRowsByLang). Since these helpers are now used in multiple commands, consider extracting them into a shared module to avoid divergent behavior/fixes across commands (e.g., wiki-dir validation, language inference changes).
Copilot
AI
Feb 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wildcard mode is prefiltered using LIKE '%${pattern}%' with the raw glob pattern (including */?). For patterns like src/*/handlers this WHERE clause will never match, yielding zero candidates and therefore zero results even though the in-memory glob filter would match. Translate glob to a SQL LIKE pattern (*→%, ?→_, escape literal %/_) or skip the SQL WHERE for wildcard and do in-memory filtering after fetching candidates.
| function buildFileWhere(pattern: string, mode: SymbolSearchMode, caseInsensitive: boolean): string | null { | |
| const safe = escapeQuotes(pattern); | |
| if (!safe) return null; | |
| const likeOp = caseInsensitive ? 'ILIKE' : 'LIKE'; | |
| if (mode === 'prefix') { | |
| return `file ${likeOp} '${safe}%'`; | |
| } | |
| if (mode === 'substring' || mode === 'wildcard') { | |
| return `file ${likeOp} '%${safe}%'`; | |
| } | |
| /** | |
| * Convert a glob pattern to a SQL LIKE pattern. | |
| * | |
| * - Escapes SQL LIKE wildcards (% and _) using backslash. | |
| * - Escapes backslash itself. | |
| * - Converts glob '*' to '%' and '?' to '_'. | |
| */ | |
| function globToSqlLike(pattern: string): string { | |
| // First escape backslash, then SQL LIKE wildcards. | |
| let like = pattern.replace(/\\/g, '\\\\').replace(/([%_])/g, '\\$1'); | |
| // Then convert glob wildcards to SQL LIKE wildcards. | |
| like = like.replace(/\*/g, '%').replace(/\?/g, '_'); | |
| return like; | |
| } | |
| function buildFileWhere(pattern: string, mode: SymbolSearchMode, caseInsensitive: boolean): string | null { | |
| const likeOp = caseInsensitive ? 'ILIKE' : 'LIKE'; | |
| if (!pattern) return null; | |
| if (mode === 'prefix') { | |
| const safe = escapeQuotes(pattern); | |
| if (!safe) return null; | |
| return `file ${likeOp} '${safe}%'`; | |
| } | |
| if (mode === 'substring') { | |
| const safe = escapeQuotes(pattern); | |
| if (!safe) return null; | |
| return `file ${likeOp} '%${safe}%'`; | |
| } | |
| if (mode === 'wildcard') { | |
| const likePattern = globToSqlLike(pattern); | |
| const safeLike = escapeQuotes(likePattern); | |
| if (!safeLike) return null; | |
| // Use ESCAPE '\' so that backslash-escaped % and _ are treated as literals. | |
| return `file ${likeOp} '${safeLike}' ESCAPE '\\\\'`; | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getFile 函数内部和 filterAndRankFileRows 参数都使用 any 类型,绕过了 TypeScript 的类型检查,可能导致运行时错误
建议: 定义明确的接口类型,如:interface FileRow { file: string; lang?: string }
| const getFile = (r: any) => String(r?.file ?? ''); | |
| interface FileRow { file: string; lang?: string } | |
| const getFile = (r: FileRow) => String(r?.file ?? ''); |
Copilot
AI
Feb 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Workspace mode currently calls queryManifestWorkspace with keyword: input.pattern, but queryManifestWorkspace queries refs by symbol ILIKE ... (not by file). This makes query-files in manifests workspaces unreliable/incorrect (often returning no candidates unless the file pattern also appears in a symbol). Consider adding a workspace query that filters on the file column (or disabling workspace support for query-files with a clear error) and, for wildcard/regex/fuzzy, using an appropriate coarse token/prefix for candidate retrieval.
| const res = await queryManifestWorkspace({ | |
| manifestRepoRoot: repoRoot, | |
| keyword: input.pattern, | |
| limit: input.maxCandidates, | |
| }); | |
| const filteredByLang = filterWorkspaceRowsByLang(res.rows, input.lang); | |
| const rows = filterAndRankFileRows( | |
| filteredByLang, | |
| input.pattern, | |
| mode, | |
| input.caseInsensitive, | |
| input.limit | |
| ); | |
| log.info('query_files', { | |
| ok: true, | |
| repoRoot, | |
| workspace: true, | |
| mode, | |
| case_insensitive: input.caseInsensitive, | |
| limit: input.limit, | |
| max_candidates: input.maxCandidates, | |
| candidates: res.rows.length, | |
| rows: rows.length, | |
| duration_ms: Date.now() - startedAt, | |
| }); | |
| const repoMap = input.withRepoMap | |
| ? { enabled: false, skippedReason: 'workspace_mode_not_supported' } | |
| : undefined; | |
| return success({ ...res, rows, ...(repoMap ? { repo_map: repoMap } : {}) }); | |
| const durationMs = Date.now() - startedAt; | |
| log.info('query_files', { | |
| ok: false, | |
| repoRoot, | |
| workspace: true, | |
| mode, | |
| case_insensitive: input.caseInsensitive, | |
| limit: input.limit, | |
| max_candidates: input.maxCandidates, | |
| candidates: 0, | |
| rows: 0, | |
| duration_ms: durationMs, | |
| error: 'workspace_mode_not_supported_for_query_files', | |
| }); | |
| return error({ | |
| message: | |
| 'query-files does not currently support workspace manifests. ' + | |
| 'Please run this command from a non-workspace repository root or disable workspace mode.', | |
| code: 'workspace_mode_not_supported_for_query_files', | |
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isCLIError 已通过类型守卫确认 ctxOrError 的类型,此处 as RepoContext 是多余的,应该直接赋值
建议: 移除类型断言,直接赋值
| const ctx = ctxOrError as RepoContext; | |
| const ctx = ctxOrError; | |
| // 或者利用类型守卫后的类型推断 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ctx.meta?.dim 可能是浮点数或非正数,但代码仅检查是否为 number 类型,可能导致 LanceDB 查询失败
建议: 增加对 dim 值的验证:确保是正整数
| const dim = typeof ctx.meta?.dim === 'number' ? ctx.meta.dim : 256; | |
| const dim = typeof ctx.meta?.dim === 'number' && ctx.meta.dim > 0 ? Math.floor(ctx.meta.dim) : 256; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 SUGGESTION: 循环中重复的类型检查
每次循环迭代都进行类型断言,可考虑提前验证 langs 数组中的值
建议: 在循环前过滤掉无效的语言类型
| const t = byLang[lang as IndexLang]; | |
| const validLangs = langs.filter((l): l is IndexLang => | |
| ['ts', 'python', 'java', 'rust', 'go', 'c', 'markdown', 'yaml'].includes(l) | |
| ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📝 NIT: catch 块类型定义不完整
catch 子句参数 e 隐式为 unknown 类型,代码使用 instanceof Error 判断是正确的,但最终仍使用 String() 转换可能丢失错误堆栈
建议: 保留完整的错误对象用于日志记录
| } catch (e) { | |
| } catch (e: unknown) { | |
| const message = e instanceof Error ? e.message : 'Unknown error'; | |
| log.error('query_files', { ok: false, duration_ms: Date.now() - startedAt, err: message, stack: e instanceof Error ? e.stack : undefined }); | |
| return error('query_files_failed', { message }); | |
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -20,9 +20,11 @@ import { | |||||||||||||||||||||||
| import { SemanticSearchSchema } from './schemas/semanticSchemas'; | ||||||||||||||||||||||||
| import { IndexRepoSchema } from './schemas/indexSchemas'; | ||||||||||||||||||||||||
| import { SearchSymbolsSchema } from './schemas/querySchemas'; | ||||||||||||||||||||||||
| import { SearchFilesSchema } from './schemas/queryFilesSchemas'; | ||||||||||||||||||||||||
|
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📝 NIT: 导入语句位置不符合现有排序规则 现有的导入语句按字母顺序排列(archive, index, query, semantic, status),新添加的 SearchFilesSchema 插在了 IndexRepoSchema 和 SearchSymbolsSchema 之间,破坏了排序一致性 建议: 将 SearchFilesSchema 导入移到第26行之后,使其位于 querySchemas 导入之后
Suggested change
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📝 NIT: Import grouping consistency 新增的 import 语句应该保持与现有代码一致的分组顺序。当前 schema 和 handler 的导入混在一起,建议将所有 schema 导入分组、handler 导入分组 建议: 将导入顺序调整为: 先导入所有 schema, 再导入所有 handler
Suggested change
|
||||||||||||||||||||||||
| import { handleSemanticSearch } from './handlers/semanticHandlers'; | ||||||||||||||||||||||||
| import { handleIndexRepo } from './handlers/indexHandlers'; | ||||||||||||||||||||||||
| import { handleSearchSymbols } from './handlers/queryHandlers'; | ||||||||||||||||||||||||
| import { handleSearchFiles } from './handlers/queryFilesHandlers'; | ||||||||||||||||||||||||
| import { CheckIndexSchema, StatusSchema } from './schemas/statusSchemas'; | ||||||||||||||||||||||||
| import { handleCheckIndex, handleStatus } from './handlers/statusHandlers'; | ||||||||||||||||||||||||
| import { PackIndexSchema, UnpackIndexSchema } from './schemas/archiveSchemas'; | ||||||||||||||||||||||||
|
|
@@ -59,6 +61,10 @@ export const cliHandlers: Record<string, HandlerRegistration<any>> = { | |||||||||||||||||||||||
| schema: SearchSymbolsSchema, | ||||||||||||||||||||||||
| handler: handleSearchSymbols, | ||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||
| 'query-files': { | ||||||||||||||||||||||||
|
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📝 NIT: 命令注册顺序与导入顺序不一致 新增的 'query-files' 命令放置在搜索相关命令之后,但导入语句放在最前面。这种不一致虽然不影响功能,但可能增加维护成本 建议: 保持命令注册顺序与模块逻辑分组一致,或调整导入顺序以匹配注册顺序 |
||||||||||||||||||||||||
| schema: SearchFilesSchema, | ||||||||||||||||||||||||
| handler: handleSearchFiles, | ||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||
| 'status': { | ||||||||||||||||||||||||
| schema: StatusSchema, | ||||||||||||||||||||||||
| handler: handleStatus, | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,20 @@ | ||||||
| import { z } from 'zod'; | ||||||
|
|
||||||
| const languageEnum = z.enum(['auto', 'all', 'java', 'ts', 'python', 'go', 'rust', 'c', 'markdown', 'yaml']); | ||||||
| const searchModeEnum = z.enum(['substring', 'prefix', 'wildcard', 'regex', 'fuzzy']); | ||||||
|
|
||||||
| export const SearchFilesSchema = z.object({ | ||||||
| pattern: z.string().min(1, 'Pattern is required'), | ||||||
| path: z.string().default('.'), | ||||||
| limit: z.coerce.number().int().positive().default(50), | ||||||
| mode: searchModeEnum.optional(), | ||||||
|
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. searchModeEnum 被设为 optional(),但没有提供默认值。当用户未指定 mode 时,mode 值为 undefined,可能导致后续搜索逻辑处理异常 建议: 为 mode 字段添加合理的默认值,例如 'substring'(最常用的搜索模式)
Suggested change
|
||||||
| caseInsensitive: z.boolean().default(false), | ||||||
| maxCandidates: z.coerce.number().int().positive().default(1000), | ||||||
| lang: languageEnum.default('auto'), | ||||||
| withRepoMap: z.boolean().default(false), | ||||||
| repoMapFiles: z.coerce.number().int().positive().default(20), | ||||||
| repoMapSymbols: z.coerce.number().int().positive().default(5), | ||||||
| wiki: z.string().default(''), | ||||||
|
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 SUGGESTION: Wiki 字段类型不明确 wiki 字段使用空字符串作为默认值,但未在 languageEnum 中定义 'wiki' 语言。语义上 wiki 可能代表一种文件格式或需要单独验证其有效值列表 建议: 如果 wiki 是文件格式之一,应将其添加到 languageEnum;如果是其他用途(如维基页面 URL),考虑使用更有描述性的字段名如 wikiPath 或 wikiUrl |
||||||
| }); | ||||||
|
|
||||||
| export type SearchFilesInput = z.infer<typeof SearchFilesSchema>; | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,7 @@ | ||
| import { Command } from 'commander'; | ||
| import { indexCommand } from '../cli/commands/indexCommand.js'; | ||
| import { queryCommand } from '../cli/commands/queryCommand.js'; | ||
| import { queryFilesCommand } from '../cli/commands/queryFilesCommand.js'; | ||
|
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 导入了 queryFilesCommand,但无法确认 '../cli/commands/queryFilesCommand.js' 文件是否存在于项目中 建议: 请确保 '../cli/commands/queryFilesCommand.js' 文件已创建并正确导出 queryFilesCommand |
||
| import { semanticCommand } from '../cli/commands/semanticCommand.js'; | ||
| import { serveCommand, agentCommand } from '../cli/commands/serveCommands.js'; | ||
| import { packCommand, unpackCommand } from '../cli/commands/archiveCommands.js'; | ||
|
|
@@ -16,6 +17,7 @@ export const aiCommand = new Command('ai') | |
| .addCommand(statusCommand) | ||
| .addCommand(repoMapCommand) | ||
| .addCommand(queryCommand) | ||
| .addCommand(queryFilesCommand) | ||
|
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 SUGGESTION: 新增子命令未提供描述 其他子命令(如 queryCommand、statusCommand)通常在各自文件中定义描述,此处仅注册命令 建议: 建议确认 queryFilesCommand 内部已正确配置 description 和相关选项,保持与其他命令的一致性 |
||
| .addCommand(semanticCommand) | ||
| .addCommand(graphCommand) | ||
| .addCommand(packCommand) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📝 NIT: 术语不清晰
命令描述中的 'refs table' 可能不易理解,建议使用更直观的描述
建议: 修改为 'Query files by name pattern (substring/prefix/wildcard/regex/fuzzy)'