✨ feat(vscode): 侧栏的文件和文件夹可以问 AI

This commit is contained in:
cruldra committed 2026-10-03 03:22:20 +08:00
1 parent fc403d5b20
commit 14450c90bc
6 files changed
+627 -6

No files matched your search

+65
View File
@@ -0,0 +1,65 @@
/**
* 侧栏问一个路径时发给模型的话:写明是文件还是文件夹、相对工作区的路径。
* 文件附上开头若干行;文件夹只列这一层的名字,不把里面的代码贴进去。
*/
/** 文件开头最多贴这么多行,剩下的让模型自己去读。 */
export const PATH_ASK_HEAD_LINES = 80
export interface PathChild {
name: string
kind: 'file' | 'folder'
}
/** 文件开头:贴得下的行,或者为什么没附上。 */
export type PathHead
= | { lines: string[], truncated: boolean }
| { unavailable: string }
export interface PathAskFile {
kind: 'file'
/** 相对所在工作区文件夹的路径 */
relativePath: string
head: PathHead
}
export interface PathAskFolder {
kind: 'folder'
/** 相对所在工作区文件夹的路径 */
relativePath: string
/** 这一层的子文件和子文件夹,调用方排好序;列不出来时是原因 */
children: PathChild[] | { unavailable: string }
}
export type PathAskSubject = PathAskFile | PathAskFolder
const LEAD = '我在看项目里的一个路径,想问它。请用中文、大白话、简洁地回答,不绕弯子。需要时可以自己去读、搜项目里的文件,但只读,不要改任何东西。提到文件时写相对项目根目录的路径。'
/** 一次提问的全文。不写进某一块代码的问答记录。 */
export function pathAskPrompt(subject: PathAskSubject, question: string): string {
const where = subject.kind === 'file'
? `这是一个文件,相对路径:${subject.relativePath}`
: `这是一个文件夹,相对路径:${subject.relativePath}`
const detail = subject.kind === 'file' ? fileHead(subject.head) : folderList(subject.children)
return [LEAD, where, detail, `问题:${question}`].join('\n\n')
}
function fileHead(head: PathHead): string {
if ('unavailable' in head)
return `文件开头没附上:${head.unavailable}`
if (head.lines.length === 0)
return head.truncated ? '文件开头一行都没读全,需要时自己读这个文件。' : '文件是空的。'
const width = String(head.lines.length).length
const body = head.lines.map((line, index) => `${String(index + 1).padStart(width)} | ${line}`).join('\n')
const rest = head.truncated ? `\n(上面只贴了开头 ${head.lines.length} 行,剩下的需要时自己读这个文件)` : ''
return `文件开头:\n${body}${rest}`
}
function folderList(children: PathAskFolder['children']): string {
if (!Array.isArray(children))
return `这一层没列出来:${children.unavailable}`
if (children.length === 0)
return '里面这一层是空的。'
const lines = children.map(child => `- ${child.kind === 'folder' ? '文件夹' : '文件'} ${child.name}`)
return `里面这一层有:\n${lines.join('\n')}\n只列了这一层的名字,没有把里面的代码贴进来。侧栏里不显示的名字这里也没列。需要时自己去读这些文件。`
}