mirror of
https://github.com/EthanMarti/infio-copilot.git
synced 2026-01-16 16:31:56 +00:00
update release logs
This commit is contained in:
parent
fea5b382cf
commit
98bc810b86
@ -36,6 +36,8 @@ import {
|
|||||||
LLMModelNotSetException,
|
LLMModelNotSetException,
|
||||||
} from '../../core/llm/exception'
|
} from '../../core/llm/exception'
|
||||||
import { TransformationType } from '../../core/transformations/trans-engine'
|
import { TransformationType } from '../../core/transformations/trans-engine'
|
||||||
|
import { Workspace } from '../../database/json/workspace/types'
|
||||||
|
import { WorkspaceManager } from '../../database/json/workspace/WorkspaceManager'
|
||||||
import { useChatHistory } from '../../hooks/use-chat-history'
|
import { useChatHistory } from '../../hooks/use-chat-history'
|
||||||
import { useCustomModes } from '../../hooks/use-custom-mode'
|
import { useCustomModes } from '../../hooks/use-custom-mode'
|
||||||
import { t } from '../../lang/helpers'
|
import { t } from '../../lang/helpers'
|
||||||
@ -139,6 +141,10 @@ const Chat = forwardRef<ChatRef, ChatProps>((props, ref) => {
|
|||||||
return new PromptGenerator(getRAGEngine, app, settings, diffStrategy, customModePrompts, customModeList, getMcpHub)
|
return new PromptGenerator(getRAGEngine, app, settings, diffStrategy, customModePrompts, customModeList, getMcpHub)
|
||||||
}, [getRAGEngine, app, settings, diffStrategy, customModePrompts, customModeList, getMcpHub])
|
}, [getRAGEngine, app, settings, diffStrategy, customModePrompts, customModeList, getMcpHub])
|
||||||
|
|
||||||
|
const workspaceManager = useMemo(() => {
|
||||||
|
return new WorkspaceManager(app)
|
||||||
|
}, [app])
|
||||||
|
|
||||||
const [inputMessage, setInputMessage] = useState<ChatUserMessage>(() => {
|
const [inputMessage, setInputMessage] = useState<ChatUserMessage>(() => {
|
||||||
const newMessage = getNewInputMessage(app, settings.defaultMention)
|
const newMessage = getNewInputMessage(app, settings.defaultMention)
|
||||||
if (props.selectedBlock) {
|
if (props.selectedBlock) {
|
||||||
@ -618,8 +624,24 @@ const Chat = forwardRef<ChatRef, ChatProps>((props, ref) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
} else if (toolArgs.type === 'list_files') {
|
} else if (toolArgs.type === 'list_files') {
|
||||||
const files = await listFilesAndFolders(app.vault, toolArgs.filepath)
|
// 获取当前工作区
|
||||||
const formattedContent = `[list_files for '${toolArgs.filepath}'] Result:\n${files.join('\n')}\n`;
|
let currentWorkspace: Workspace | null = null
|
||||||
|
if (settings.workspace && settings.workspace !== 'vault') {
|
||||||
|
currentWorkspace = await workspaceManager.findByName(String(settings.workspace))
|
||||||
|
}
|
||||||
|
|
||||||
|
const files = await listFilesAndFolders(
|
||||||
|
app.vault,
|
||||||
|
toolArgs.filepath,
|
||||||
|
toolArgs.recursive,
|
||||||
|
currentWorkspace || undefined,
|
||||||
|
app
|
||||||
|
)
|
||||||
|
|
||||||
|
const contextInfo = currentWorkspace
|
||||||
|
? `workspace '${currentWorkspace.name}'`
|
||||||
|
: toolArgs.filepath || 'vault root'
|
||||||
|
const formattedContent = `[list_files for '${contextInfo}'] Result:\n${files.join('\n')}\n`;
|
||||||
return {
|
return {
|
||||||
type: 'list_files',
|
type: 'list_files',
|
||||||
applyMsgId,
|
applyMsgId,
|
||||||
|
|||||||
@ -1,10 +1,9 @@
|
|||||||
import { ChevronDown, FolderOpen, Plus, Tag, Trash2, X } from 'lucide-react'
|
import { ChevronDown, FolderOpen, Plus, Tag, Trash2, X } from 'lucide-react'
|
||||||
import { App, TFile, TFolder } from 'obsidian'
|
import { App, TFolder } from 'obsidian'
|
||||||
import { useEffect, useRef, useState } from 'react'
|
import { useEffect, useRef, useState } from 'react'
|
||||||
|
|
||||||
import { Workspace, WorkspaceContent } from '../../database/json/workspace/types'
|
import { Workspace, WorkspaceContent } from '../../database/json/workspace/types'
|
||||||
import { t } from '../../lang/helpers'
|
import { t } from '../../lang/helpers'
|
||||||
import { createDataviewManager } from '../../utils/dataview'
|
|
||||||
|
|
||||||
interface WorkspaceEditModalProps {
|
interface WorkspaceEditModalProps {
|
||||||
workspace?: Workspace
|
workspace?: Workspace
|
||||||
@ -22,10 +21,10 @@ const WorkspaceEditModal = ({
|
|||||||
onSave
|
onSave
|
||||||
}: WorkspaceEditModalProps) => {
|
}: WorkspaceEditModalProps) => {
|
||||||
// 生成默认工作区名称
|
// 生成默认工作区名称
|
||||||
const getDefaultWorkspaceName = () => {
|
const getDefaultWorkspaceName = (): string => {
|
||||||
const now = new Date()
|
const now = new Date()
|
||||||
const date = `${now.getFullYear()}-${(now.getMonth() + 1).toString().padStart(2, '0')}-${now.getDate().toString().padStart(2, '0')}`
|
const date = `${now.getFullYear()}-${(now.getMonth() + 1).toString().padStart(2, '0')}-${now.getDate().toString().padStart(2, '0')}`
|
||||||
return t('workspace.editModal.defaultName', { date })
|
return String(t('workspace.editModal.defaultName', { date }))
|
||||||
}
|
}
|
||||||
|
|
||||||
const [name, setName] = useState(workspace?.name || getDefaultWorkspaceName())
|
const [name, setName] = useState(workspace?.name || getDefaultWorkspaceName())
|
||||||
@ -51,11 +50,6 @@ const WorkspaceEditModal = ({
|
|||||||
const folders: string[] = []
|
const folders: string[] = []
|
||||||
const addFolder = (folder: TFolder) => {
|
const addFolder = (folder: TFolder) => {
|
||||||
folders.push(folder.path)
|
folders.push(folder.path)
|
||||||
// folder.children.forEach(child => {
|
|
||||||
// if (child instanceof TFolder) {
|
|
||||||
// addFolder(child)
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
app.vault.getAllFolders(false).forEach(folder => {
|
app.vault.getAllFolders(false).forEach(folder => {
|
||||||
@ -64,68 +58,17 @@ const WorkspaceEditModal = ({
|
|||||||
|
|
||||||
setAvailableFolders(folders.sort())
|
setAvailableFolders(folders.sort())
|
||||||
|
|
||||||
// 使用 dataview 查询获取所有标签
|
// 直接使用 Obsidian 的内置接口获取所有标签
|
||||||
const dataviewManager = createDataviewManager(app)
|
try {
|
||||||
|
const tagsObject = app.metadataCache.getTags() // 获取所有标签 {'#tag1': 2, '#tag2': 4}
|
||||||
if (dataviewManager.isDataviewAvailable()) {
|
const tags = Object.keys(tagsObject).sort()
|
||||||
try {
|
setAvailableTags(tags)
|
||||||
const result = await dataviewManager.executeQuery('TABLE file.tags FROM ""')
|
} catch (error) {
|
||||||
|
console.error('获取标签失败:', error)
|
||||||
if (result.success && result.data) {
|
setAvailableTags([])
|
||||||
const tags = new Set<string>()
|
|
||||||
|
|
||||||
// 解析结果中的标签
|
|
||||||
const lines = result.data.split('\n')
|
|
||||||
lines.forEach(line => {
|
|
||||||
if (line.includes('#')) {
|
|
||||||
const tagMatches = line.match(/#[a-zA-Z0-9\u4e00-\u9fa5_-]+/g)
|
|
||||||
if (tagMatches) {
|
|
||||||
tagMatches.forEach(tag => tags.add(tag))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
setAvailableTags(Array.from(tags).sort())
|
|
||||||
} else {
|
|
||||||
// 回退到传统方法
|
|
||||||
fallbackToTraditionalTagQuery()
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Dataview 查询失败:', error)
|
|
||||||
// 回退到传统方法
|
|
||||||
fallbackToTraditionalTagQuery()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 回退到传统方法
|
|
||||||
fallbackToTraditionalTagQuery()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 传统方法获取标签(作为回退方案)
|
|
||||||
const fallbackToTraditionalTagQuery = () => {
|
|
||||||
const tags = new Set<string>()
|
|
||||||
app.vault.getAllLoadedFiles().forEach(file => {
|
|
||||||
if (file instanceof TFile) {
|
|
||||||
const cache = app.metadataCache.getFileCache(file)
|
|
||||||
if (cache?.tags) {
|
|
||||||
cache.tags.forEach(tag => {
|
|
||||||
tags.add(tag.tag)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if (cache?.frontmatter?.tags) {
|
|
||||||
const frontmatterTags = cache.frontmatter.tags
|
|
||||||
if (Array.isArray(frontmatterTags)) {
|
|
||||||
frontmatterTags.forEach(tag => tags.add(`#${tag}`))
|
|
||||||
} else if (typeof frontmatterTags === 'string') {
|
|
||||||
tags.add(`#${frontmatterTags}`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
setAvailableTags(Array.from(tags).sort())
|
|
||||||
}
|
|
||||||
|
|
||||||
loadAvailableOptions()
|
loadAvailableOptions()
|
||||||
}, [isOpen, app])
|
}, [isOpen, app])
|
||||||
|
|
||||||
@ -161,9 +104,15 @@ const WorkspaceEditModal = ({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// 搜索匹配的标签
|
// 搜索匹配的标签
|
||||||
availableTags.forEach(tag => {
|
availableTags.forEach(tag => {
|
||||||
if (tag.toLowerCase().includes(searchTerm)) {
|
// 改善搜索匹配逻辑,支持中文和更灵活的匹配
|
||||||
|
const tagForSearch = tag.toLowerCase()
|
||||||
|
const shouldMatch = searchTerm.startsWith('#')
|
||||||
|
? tagForSearch.includes(searchTerm.toLowerCase()) // 如果搜索词以#开头,直接匹配
|
||||||
|
: tagForSearch.includes(searchTerm) || tagForSearch.includes(`#${searchTerm}`) // 否则同时匹配带#和不带#的情况
|
||||||
|
|
||||||
|
if (shouldMatch) {
|
||||||
// 检查是否已存在
|
// 检查是否已存在
|
||||||
const exists = content.some(item =>
|
const exists = content.some(item =>
|
||||||
item.type === 'tag' && item.content === tag
|
item.type === 'tag' && item.content === tag
|
||||||
@ -190,7 +139,7 @@ const WorkspaceEditModal = ({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
setFilteredSuggestions(suggestions.slice(0, 10)) // 限制显示数量
|
setFilteredSuggestions(suggestions.slice(0, 20)) // 限制显示数量
|
||||||
setShowSuggestions(suggestions.length > 0)
|
setShowSuggestions(suggestions.length > 0)
|
||||||
setSelectedSuggestionIndex(-1)
|
setSelectedSuggestionIndex(-1)
|
||||||
}, [inputValue, availableFolders, availableTags, content])
|
}, [inputValue, availableFolders, availableTags, content])
|
||||||
|
|||||||
@ -81,6 +81,40 @@ export class DataviewManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行 Dataview JS
|
||||||
|
*/
|
||||||
|
async executeJs(js: string): Promise<DataviewQueryResult> {
|
||||||
|
const api = this.getAPI();
|
||||||
|
if (!api) {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: "Dataview 插件未安装或未启用"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await api.evaluate(js);
|
||||||
|
if (result.successful) {
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
data: result.value
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: String(result.error || 'JS 查询失败')
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Dataview JS 执行失败:', error);
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: error instanceof Error ? error.message : '未知错误'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 格式化查询结果(备用方法)
|
* 格式化查询结果(备用方法)
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
import { minimatch } from 'minimatch'
|
import { minimatch } from 'minimatch'
|
||||||
import { TFile, TFolder, Vault } from 'obsidian'
|
import { App, TFile, TFolder, Vault } from 'obsidian'
|
||||||
|
|
||||||
|
import { Workspace } from '../database/json/workspace/types'
|
||||||
|
|
||||||
export const findFilesMatchingPatterns = async (
|
export const findFilesMatchingPatterns = async (
|
||||||
patterns: string[],
|
patterns: string[],
|
||||||
@ -11,27 +13,216 @@ export const findFilesMatchingPatterns = async (
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const listFilesAndFolders = async (vault: Vault, path: string) => {
|
/**
|
||||||
const folder = vault.getAbstractFileByPath(path)
|
* 根据标签查找文件
|
||||||
const childrenFiles: string[] = []
|
*/
|
||||||
const childrenFolders: string[] = []
|
|
||||||
if (folder instanceof TFolder) {
|
export const getFilesWithTag = (targetTag: string, app: App): string[] => {
|
||||||
folder.children.forEach((child) => {
|
// 确保输入的标签以 '#' 开头
|
||||||
if (child instanceof TFile) {
|
if (!targetTag.startsWith('#')) {
|
||||||
childrenFiles.push(child.path)
|
targetTag = '#' + targetTag;
|
||||||
} else if (child instanceof TFolder) {
|
}
|
||||||
childrenFolders.push(child.path + "/")
|
|
||||||
|
const filesWithTag: string[] = []; // 文件路径列表
|
||||||
|
|
||||||
|
// 1. 获取 Vault 中所有的 Markdown 文件
|
||||||
|
const allFiles = app.vault.getMarkdownFiles();
|
||||||
|
|
||||||
|
// 2. 遍历所有文件
|
||||||
|
for (const file of allFiles) {
|
||||||
|
// 3. 获取当前文件的元数据缓存
|
||||||
|
// 这个操作非常快,因为它读取的是内存中的缓存
|
||||||
|
const cache = app.metadataCache.getFileCache(file);
|
||||||
|
|
||||||
|
// 检查缓存是否存在,以及缓存中是否有 tags 属性
|
||||||
|
if (cache?.tags) {
|
||||||
|
// 4. 在文件的标签数组中查找目标标签
|
||||||
|
// cache.tags 是一个 TagCache[] 数组,每个对象的格式为 { tag: string; position: Pos; }
|
||||||
|
const found = cache.tags.find(tagObj => tagObj.tag === targetTag);
|
||||||
|
if (found) {
|
||||||
|
filesWithTag.push(file.path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return filesWithTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 列出工作区的文件和文件夹
|
||||||
|
*/
|
||||||
|
export const listFilesAndFolders = async (
|
||||||
|
vault: Vault,
|
||||||
|
path?: string,
|
||||||
|
recursive = false,
|
||||||
|
workspace?: Workspace,
|
||||||
|
app?: App
|
||||||
|
): Promise<string[]> => {
|
||||||
|
const result: string[] = []
|
||||||
|
|
||||||
|
// 如果有工作区,使用工作区内容
|
||||||
|
if (workspace && app) {
|
||||||
|
result.push(`[Workspace: ${workspace.name}]`)
|
||||||
|
result.push('')
|
||||||
|
|
||||||
|
// 按类型分组处理工作区内容
|
||||||
|
const folders = workspace.content.filter(c => c.type === 'folder')
|
||||||
|
const tags = workspace.content.filter(c => c.type === 'tag')
|
||||||
|
|
||||||
|
// 处理文件夹
|
||||||
|
if (folders.length > 0) {
|
||||||
|
result.push('=== FOLDERS ===')
|
||||||
|
for (const folderItem of folders) {
|
||||||
|
const folder = vault.getAbstractFileByPath(folderItem.content)
|
||||||
|
if (folder && folder instanceof TFolder) {
|
||||||
|
result.push(`├── ${folder.path}/`)
|
||||||
|
|
||||||
|
if (recursive) {
|
||||||
|
// 递归显示文件夹内容
|
||||||
|
const subContent = await listFolderContentsRecursively(folder, '│ ')
|
||||||
|
result.push(...subContent)
|
||||||
|
} else {
|
||||||
|
// 只显示第一层内容
|
||||||
|
const subContent = await listFolderContentsFirstLevel(folder, '│ ')
|
||||||
|
result.push(...subContent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果还有标签,添加空行分隔
|
||||||
|
if (tags.length > 0) {
|
||||||
|
result.push('')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理标签(使用平铺格式,不使用树状结构)
|
||||||
|
if (tags.length > 0) {
|
||||||
|
result.push('=== TAGS ===')
|
||||||
|
for (const tagItem of tags) {
|
||||||
|
const files = getFilesWithTag(tagItem.content, app)
|
||||||
|
if (files.length > 0) {
|
||||||
|
result.push(`${tagItem.content} (${files.length} files):`)
|
||||||
|
|
||||||
|
// 使用简单的列表格式显示文件
|
||||||
|
files.forEach((file) => {
|
||||||
|
result.push(`${file}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 在标签组之间添加空行
|
||||||
|
result.push('')
|
||||||
|
} else {
|
||||||
|
result.push(`${tagItem.content} (0 files)`)
|
||||||
|
result.push('')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// 原有的单个路径逻辑(保持向后兼容)
|
||||||
|
const startPath = path && path !== '' && path !== '.' && path !== '/' ? path : ''
|
||||||
|
const folder = startPath ? vault.getAbstractFileByPath(startPath) : vault.getRoot()
|
||||||
|
|
||||||
|
if (!folder || !(folder instanceof TFolder)) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
const listFolderContents = (currentFolder: TFolder, prefix = '') => {
|
||||||
|
const children = [...currentFolder.children].sort((a, b) => {
|
||||||
|
if (a instanceof TFolder && b instanceof TFile) return -1
|
||||||
|
if (a instanceof TFile && b instanceof TFolder) return 1
|
||||||
|
return a.name.localeCompare(b.name)
|
||||||
|
})
|
||||||
|
|
||||||
|
children.forEach((child, index) => {
|
||||||
|
const isLast = index === children.length - 1
|
||||||
|
const currentPrefix = prefix + (isLast ? '└── ' : '├── ')
|
||||||
|
const nextPrefix = prefix + (isLast ? ' ' : '│ ')
|
||||||
|
|
||||||
|
if (child instanceof TFolder) {
|
||||||
|
result.push(`${currentPrefix}${child.path}/`)
|
||||||
|
|
||||||
|
if (recursive) {
|
||||||
|
listFolderContents(child, nextPrefix)
|
||||||
|
}
|
||||||
|
} else if (child instanceof TFile) {
|
||||||
|
result.push(`${currentPrefix}${child.path}`)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return [...childrenFolders, ...childrenFiles]
|
|
||||||
}
|
}
|
||||||
return []
|
|
||||||
|
if (startPath) {
|
||||||
|
result.push(`${folder.path}/`)
|
||||||
|
listFolderContents(folder, '')
|
||||||
|
} else {
|
||||||
|
result.push(`${vault.getName()}/`)
|
||||||
|
listFolderContents(folder, '')
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 递归列出文件夹内容
|
||||||
|
*/
|
||||||
|
const listFolderContentsRecursively = async (folder: TFolder, prefix: string): Promise<string[]> => {
|
||||||
|
const result: string[] = []
|
||||||
|
|
||||||
|
const children = [...folder.children].sort((a, b) => {
|
||||||
|
if (a instanceof TFolder && b instanceof TFile) return -1
|
||||||
|
if (a instanceof TFile && b instanceof TFolder) return 1
|
||||||
|
return a.name.localeCompare(b.name)
|
||||||
|
})
|
||||||
|
|
||||||
|
for (let i = 0; i < children.length; i++) {
|
||||||
|
const child = children[i]
|
||||||
|
const isLast = i === children.length - 1
|
||||||
|
const currentPrefix = prefix + (isLast ? '└── ' : '├── ')
|
||||||
|
const nextPrefix = prefix + (isLast ? ' ' : '│ ')
|
||||||
|
|
||||||
|
if (child instanceof TFolder) {
|
||||||
|
result.push(`${currentPrefix}${child.path}/`)
|
||||||
|
const subContent = await listFolderContentsRecursively(child, nextPrefix)
|
||||||
|
result.push(...subContent)
|
||||||
|
} else if (child instanceof TFile) {
|
||||||
|
result.push(`${currentPrefix}${child.path}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 只列出文件夹第一层内容
|
||||||
|
*/
|
||||||
|
const listFolderContentsFirstLevel = async (folder: TFolder, prefix: string): Promise<string[]> => {
|
||||||
|
const result: string[] = []
|
||||||
|
|
||||||
|
const children = [...folder.children].sort((a, b) => {
|
||||||
|
if (a instanceof TFolder && b instanceof TFile) return -1
|
||||||
|
if (a instanceof TFile && b instanceof TFolder) return 1
|
||||||
|
return a.name.localeCompare(b.name)
|
||||||
|
})
|
||||||
|
|
||||||
|
children.forEach((child, index) => {
|
||||||
|
const isLast = index === children.length - 1
|
||||||
|
const currentPrefix = prefix + (isLast ? '└── ' : '├── ')
|
||||||
|
|
||||||
|
if (child instanceof TFolder) {
|
||||||
|
result.push(`${currentPrefix}${child.path}/`)
|
||||||
|
} else if (child instanceof TFile) {
|
||||||
|
result.push(`${currentPrefix}${child.path}`)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
export const matchSearchFiles = async (vault: Vault, path: string, query: string, file_pattern: string) => {
|
export const matchSearchFiles = async (vault: Vault, path: string, query: string, file_pattern: string) => {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const regexSearchFiles = async (vault: Vault, path: string, regex: string, file_pattern: string) => {
|
export const regexSearchFiles = async (vault: Vault, path: string, regex: string, file_pattern: string) => {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -413,7 +413,16 @@ export class PromptGenerator {
|
|||||||
if (currentWorkspaceName && currentWorkspaceName !== 'vault') {
|
if (currentWorkspaceName && currentWorkspaceName !== 'vault') {
|
||||||
const workspace = await this.workspaceManager.findByName(currentWorkspaceName)
|
const workspace = await this.workspaceManager.findByName(currentWorkspaceName)
|
||||||
if (workspace) {
|
if (workspace) {
|
||||||
overview += `\n\n# Current Workspace\n${workspace.name}`
|
// 使用 listFilesAndFolders 获取详细的工作区结构
|
||||||
|
const { listFilesAndFolders } = await import('./glob-utils')
|
||||||
|
const workspaceStructure = await listFilesAndFolders(
|
||||||
|
this.app.vault,
|
||||||
|
undefined,
|
||||||
|
false, // 非递归,只显示第一层
|
||||||
|
workspace,
|
||||||
|
this.app
|
||||||
|
)
|
||||||
|
overview += `\n\n# Current Workspace\n${workspaceStructure.join('\n')}`
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
overview += `\n\n# Current Workspace\n${this.app.vault.getName()} (entire vault)`
|
overview += `\n\n# Current Workspace\n${this.app.vault.getName()} (entire vault)`
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user