✨ feat(vscode): 问 AI 输入框能粘贴、拖进图片随问题发给 Claude Code,缩略图能点开看大图,图片存进 .spx/code-qa 跟着问答删
This commit is contained in:
1 parent
d9a5c3673e
commit
36d842e18e
28 files changed
+825
-121
No files matched your search
@@ -16,6 +16,8 @@ export interface PathMapFile<T> {
|
||||
label: string
|
||||
/** 认一条的值:不合法的返回 undefined,这条就跳过;合法的可以顺手规范成统一写法 */
|
||||
parse: (value: unknown) => T | undefined
|
||||
/** 一条值带着的文件(相对工作区文件夹,`/` 分隔,例如问答的图片):改表后不再有哪条带着的,跟着删掉 */
|
||||
attachments?: (value: T) => string[]
|
||||
}
|
||||
|
||||
/** 规范成表的键:去掉 `./`、重复和结尾的 `/`;工作区文件夹本身、文件夹外面的路径没有键。 */
|
||||
@@ -62,7 +64,7 @@ export function changedKeys<T>(before: PathMap<T>, after: PathMap<T>): string[]
|
||||
return [...keys].filter(key => JSON.stringify(before[key]) !== JSON.stringify(after[key]))
|
||||
}
|
||||
|
||||
function fileIn(workspaceRoot: string, file: PathMapFile<unknown>): string {
|
||||
function fileIn<T>(workspaceRoot: string, file: PathMapFile<T>): string {
|
||||
return path.join(workspaceRoot, ...file.path.split('/'))
|
||||
}
|
||||
|
||||
@@ -100,3 +102,20 @@ export async function writePathMap<T>(workspaceRoot: string, file: PathMapFile<T
|
||||
const sorted = Object.fromEntries(Object.entries(map).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0))
|
||||
await fsp.writeFile(target, `${JSON.stringify(sorted, null, 2)}\n`, 'utf8')
|
||||
}
|
||||
|
||||
/** 改表前带着、改表后没有哪条再带着的文件(见 PathMapFile.attachments)。 */
|
||||
export function detachedFiles<T>(file: PathMapFile<T>, before: PathMap<T>, after: PathMap<T>): string[] {
|
||||
const { attachments } = file
|
||||
if (!attachments)
|
||||
return []
|
||||
const kept = new Set(Object.values(after).flatMap(attachments))
|
||||
return [...new Set(Object.values(before).flatMap(attachments))].filter(attachment => !kept.has(attachment))
|
||||
}
|
||||
|
||||
/** 删掉工作区文件夹里的这些文件(相对路径);已经没了的不算错,跑到文件夹外面的路径不碰。 */
|
||||
export async function removeFiles(workspaceRoot: string, relativePaths: readonly string[]): Promise<void> {
|
||||
await Promise.all(relativePaths.flatMap((relativePath) => {
|
||||
const key = normalizeKey(relativePath)
|
||||
return key === undefined ? [] : [fsp.rm(path.join(workspaceRoot, ...key.split('/')), { force: true })]
|
||||
}))
|
||||
}
|
||||
Reference in new issue
Block a user