diff --git a/package.json b/package.json index 7b249f2..235ca51 100644 --- a/package.json +++ b/package.json @@ -253,10 +253,6 @@ "command": "devchat.addConext", "title": "Add to DevChat" }, - { - "command": "devchat.addSummaryContext", - "title": "Add summary to DevChat" - }, { "command": "devchat.askForCode", "title": "Add to DevChat" @@ -287,16 +283,6 @@ "title": "Stop AskCode Index", "category": "DevChat" }, - { - "command": "DevChat.AskCodeSummaryIndexStart", - "title": "Start AskCode Summary Index", - "category": "DevChat" - }, - { - "command": "DevChat.AskCodeIndexSummaryStop", - "title": "Stop AskCode Summary Index", - "category": "DevChat" - }, { "command": "DevChat.InstallCommands", "title": "Install slash commands", @@ -364,10 +350,6 @@ "command": "devchat.addConext", "when": "false" }, - { - "command": "devchat.addSummaryContext", - "when": "false" - }, { "command": "devchat.askForCode", "when": "false" @@ -399,11 +381,6 @@ "when": "!isChineseLocale && resourceLangId != 'git'", "command": "devchat.addConext", "group": "navigation" - }, - { - "when": "!isChineseLocale && resourceLangId != 'git'", - "command": "devchat.addSummaryContext", - "group": "navigation" } ], "editor/context": [ diff --git a/src/context/contextSummary.ts b/src/context/contextSummary.ts new file mode 100644 index 0000000..b2247be --- /dev/null +++ b/src/context/contextSummary.ts @@ -0,0 +1,50 @@ +import * as path from 'path'; +import * as fs from 'fs'; +import { ChatContext } from './contextManager'; +import { createTempSubdirectory, runCommandStringAndWriteOutput } from '../util/commonUtil'; + +import { logger } from '../util/logger'; +import { UiUtilWrapper } from '../util/uiUtil'; +import { askcodeSummaryIndex, addSummaryContextFun } from '../contributes/commands'; + + +export const askSummaryContext: ChatContext = { + name: 'askcode summary', + description: 'summary of file or directory', + + handler: async () => { + const uriPath = await UiUtilWrapper.showInputBox({ + prompt: 'File or directory to summary', + placeHolder: 'for example: /some/src' + }); + + if (uriPath) { + // check uriPath is absolute path or relative path + let uriPathAbs = uriPath; + if (!path.isAbsolute(uriPath)) { + // covert uriPath to absolute path, base path is workspacePath + const workspacePath = UiUtilWrapper.workspaceFoldersFirstPath(); + if (!workspacePath) { + logger.channel()?.error(`The workspace is not opened!`); + logger.channel()?.show(); + return []; + } + uriPathAbs = path.join(workspacePath, uriPath); + } + + logger.channel()?.info(`Your input path is: ${uriPathAbs}`); + if (!fs.existsSync(uriPathAbs)) { + logger.channel()?.error(`The path ${uriPath} is not exist!`); + logger.channel()?.show(); + return []; + } + + // index the file or directory + await askcodeSummaryIndex(uriPathAbs); + + // summary the file or directory + await addSummaryContextFun(uriPathAbs); + } + return []; + }, +}; diff --git a/src/context/loadContexts.ts b/src/context/loadContexts.ts index 31d7ab3..ca6557b 100644 --- a/src/context/loadContexts.ts +++ b/src/context/loadContexts.ts @@ -4,6 +4,8 @@ import { gitDiffContext } from './contextGitDiff'; import { customCommandContext } from './contextCustomCommand'; import { refDefsContext } from './contextRefDefs'; import { defRefsContext } from './contextDefRefs'; +import { askSummaryContext } from './contextSummary'; +import { FT } from '../util/feature_flags/feature_toggles'; const chatContextManager = ChatContextManager.getInstance(); @@ -14,3 +16,6 @@ chatContextManager.registerContext(gitDiffContext); chatContextManager.registerContext(refDefsContext); chatContextManager.registerContext(defRefsContext); chatContextManager.registerContext(customCommandContext); +if (FT("ask-code-summary")) { + chatContextManager.registerContext(askSummaryContext); +} \ No newline at end of file diff --git a/src/contributes/commands.ts b/src/contributes/commands.ts index 3698eff..21b5cbe 100644 --- a/src/contributes/commands.ts +++ b/src/contributes/commands.ts @@ -386,49 +386,56 @@ export function registerAskCodeIndexStopCommand(context: vscode.ExtensionContext context.subscriptions.push(disposable); } +let summaryIndexTargetDir: string | undefined = undefined; + +export async function askcodeSummaryIndex(targetDir: string|undefined) { + if (!FT("ask-code-summary")) { + UiUtilWrapper.showErrorMessage("This command is a beta version command and has not been released yet."); + return; + } + summaryIndexTargetDir = targetDir; + + const progressBar = new ProgressBar(); + progressBar.init(); + logger.channel()?.show(); + + progressBar.update("Index source code files for ask codebase summary...", 0); + + const config = getConfig(); + let pythonVirtualEnv: any = config.pythonVirtualEnv; + const supportedFileTypes = config.supportedFileTypes; + + updateIndexingStatus("started"); + + if (pythonVirtualEnv) { + // check whether pythonVirtualEnv is stisfy the requirement version + const devchatAskVersion = getPackageVersion(pythonVirtualEnv, "devchat-ask"); + + let requireAskVersion = "0.0.8"; + if (FT("ask-code-summary")) { + requireAskVersion = "0.0.10"; + } + + if (!devchatAskVersion || devchatAskVersion < requireAskVersion) { + logger.channel()?.info(`The version of devchat-ask is ${devchatAskVersion}`); + pythonVirtualEnv = undefined; + } + } + + if (!pythonVirtualEnv) { + progressBar.update("Installing devchat-ask. See OUTPUT for progress...", 0); + await installAskCode(supportedFileTypes, progressBar, indexCodeSummary); + } else { + progressBar.update("Index source files. See OUTPUT for progress...", 0); + await indexCodeSummary(pythonVirtualEnv, supportedFileTypes, progressBar); + } + + updateIndexingStatus("stopped"); +} + export function registerAskCodeSummaryIndexStartCommand(context: vscode.ExtensionContext) { let disposable = vscode.commands.registerCommand('DevChat.AskCodeSummaryIndexStart', async () => { - if (!FT("ask-code-summary")) { - UiUtilWrapper.showErrorMessage("This command is a beta version command and has not been released yet."); - return; - } - - const progressBar = new ProgressBar(); - progressBar.init(); - logger.channel()?.show(); - - progressBar.update("Index source code files for ask codebase summary...", 0); - - const config = getConfig(); - let pythonVirtualEnv: any = config.pythonVirtualEnv; - const supportedFileTypes = config.supportedFileTypes; - - updateIndexingStatus("started"); - - if (pythonVirtualEnv) { - // check whether pythonVirtualEnv is stisfy the requirement version - const devchatAskVersion = getPackageVersion(pythonVirtualEnv, "devchat-ask"); - - let requireAskVersion = "0.0.8"; - if (FT("ask-code-summary")) { - requireAskVersion = "0.0.10"; - } - - if (!devchatAskVersion || devchatAskVersion < requireAskVersion) { - logger.channel()?.info(`The version of devchat-ask is ${devchatAskVersion}`); - pythonVirtualEnv = undefined; - } - } - - if (!pythonVirtualEnv) { - progressBar.update("Installing devchat-ask. See OUTPUT for progress...", 0); - await installAskCode(supportedFileTypes, progressBar, indexCodeSummary); - } else { - progressBar.update("Index source files. See OUTPUT for progress...", 0); - await indexCodeSummary(pythonVirtualEnv, supportedFileTypes, progressBar); - } - - updateIndexingStatus("stopped"); + askcodeSummaryIndex("*"); }); context.subscriptions.push(disposable); } @@ -454,7 +461,7 @@ async function indexCodeSummary(pythonVirtualEnv, supportedFileTypes, progressBa const workspaceDir = UiUtilWrapper.workspaceFoldersFirstPath(); const command = pythonVirtualEnv.trim(); - const args = [UiUtilWrapper.extensionPath() + "/tools/askcode_summary_index.py", "index", supportedFileTypes]; + const args = [UiUtilWrapper.extensionPath() + "/tools/askcode_summary_index.py", "index", supportedFileTypes, summaryIndexTargetDir]; const options = { env: envs, cwd: workspaceDir }; summaryIndexProcess = new CommandRun(); @@ -516,41 +523,41 @@ export function registerInstallCommandsCommand(context: vscode.ExtensionContext) context.subscriptions.push(disposable); } + +export async function addSummaryContextFun(fsPath: string ) { + if (!FT("ask-code-summary")) { + UiUtilWrapper.showErrorMessage("This command is a beta version command and has not been released yet."); + return; + } + + const workspaceDir = UiUtilWrapper.workspaceFoldersFirstPath(); + if (!workspaceDir) { + return ; + } + // check whether workspaceDir/.chat/.summary.json文件存在 + if (!fs.existsSync(path.join(workspaceDir, '.chat', '.summary.json'))) { + logger.channel()?.info(`You should index this workspace first.`); + logger.channel()?.show(); + return; + } + + const config = getConfig(); + const pythonVirtualEnv: any = config.pythonVirtualEnv; + + const tempDir = await createTempSubdirectory('devchat/context'); + const summaryFile = path.join(tempDir, 'summary.txt'); + + const summaryArgs = [pythonVirtualEnv, UiUtilWrapper.extensionPath() + "/tools/askcode_summary_index.py", "desc", fsPath]; + const result = await runCommandStringArrayAndWriteOutput(summaryArgs, summaryFile); + logger.channel()?.info(` exit code:`, result.exitCode); + + logger.channel()?.debug(` stdout:`, result.stdout); + logger.channel()?.debug(` stderr:`, result.stderr); + MessageHandler.sendMessage(ExtensionContextHolder.provider?.view()!, { command: 'appendContext', context: `[context|${summaryFile}]` }); +} export function registerAddSummaryContextCommand(context: vscode.ExtensionContext) { const callback = async (uri: { fsPath: any; }) => { - if (!FT("ask-code-summary")) { - UiUtilWrapper.showErrorMessage("This command is a beta version command and has not been released yet."); - return; - } - - if (!await ensureChatPanel(context)) { - return; - } - - const workspaceDir = UiUtilWrapper.workspaceFoldersFirstPath(); - if (!workspaceDir) { - return ; - } - // check whether workspaceDir/.chat/.summary.json文件存在 - if (!fs.existsSync(path.join(workspaceDir, '.chat', '.summary.json'))) { - logger.channel()?.info(`You should index this workspace first.`); - logger.channel()?.show(); - return; - } - - const config = getConfig(); - const pythonVirtualEnv: any = config.pythonVirtualEnv; - - const tempDir = await createTempSubdirectory('devchat/context'); - const summaryFile = path.join(tempDir, 'summary.txt'); - - const summaryArgs = [pythonVirtualEnv, UiUtilWrapper.extensionPath() + "/tools/askcode_summary_index.py", "desc", uri.fsPath]; - const result = await runCommandStringArrayAndWriteOutput(summaryArgs, summaryFile); - logger.channel()?.info(` exit code:`, result.exitCode); - - logger.channel()?.debug(` stdout:`, result.stdout); - logger.channel()?.debug(` stderr:`, result.stderr); - MessageHandler.sendMessage(ExtensionContextHolder.provider?.view()!, { command: 'appendContext', context: `[context|${summaryFile}]` }); + addSummaryContextFun(uri.fsPath); }; context.subscriptions.push(vscode.commands.registerCommand('devchat.addSummaryContext', callback)); } diff --git a/tools/askcode_summary_index.py b/tools/askcode_summary_index.py index 093ad7e..07a3ea0 100644 --- a/tools/askcode_summary_index.py +++ b/tools/askcode_summary_index.py @@ -41,7 +41,7 @@ def is_file_modified(filePath: str, supportedFileTypes) -> bool: print("Not hidden file: ", filePath) return False - fileLastModified = g_file_last_modified_saved.get(relativePath, 0) + fileLastModified = g_file_last_modified_saved.get(relativePath, 0) fileCurrentModified = os.path.getmtime(filePath) if fileLastModified != fileCurrentModified: @@ -50,13 +50,18 @@ def is_file_modified(filePath: str, supportedFileTypes) -> bool: return False -def custom_file_filter(file_path: str, supportedFileTypes) -> bool: +def custom_file_filter(file_path: str, supportedFileTypes, target_dir: str) -> bool: needIndex = False + if file_path[0:1] == '/': + file_path = "." + file_path file_path = os.path.abspath(file_path) + + if target_dir != "*" and os.path.isfile(file_path) and not file_path.startswith(target_dir): + return False if file_path in g_file_need_index: return g_file_need_index[file_path] - # check size of true value in g_file_need_index > 100 + # check size of true value in g_file_need_index > 100 if sum(g_file_need_index.values()) > 100: return False @@ -68,7 +73,7 @@ def custom_file_filter(file_path: str, supportedFileTypes) -> bool: return needIndex -def index_directory(repo_dir: str, repo_cache_path: str, supportedFileTypes): +def index_directory(repo_dir: str, repo_cache_path: str, supportedFileTypes, target_dir: str): """ index files in repo_dir """ @@ -78,13 +83,14 @@ def index_directory(repo_dir: str, repo_cache_path: str, supportedFileTypes): sw = SummaryWrapper(repo_cache_path, FileSource( path=repo_dir, rel_root=repo_dir, - file_filter=lambda file_path: custom_file_filter(file_path, supportedFileTypes), + file_filter=lambda file_path: custom_file_filter(file_path, supportedFileTypes, target_dir), )) for progress_info in sw.reindex(True, []): print(progress_info) save_file_last_modified('.chat/.index_modified.json', g_file_last_modified_saved) + def desc(repo_dir: str, repo_cache_path: str, target_path: str): """ @@ -121,12 +127,13 @@ def main(): repo_cache_path = os.path.join(repo_dir, '.chat', '.summary.json') if command == "index": - if len(sys.argv) < 3: - print("Usage: python askcode_summary_index.py index [supportedFileTypes]") + if len(sys.argv) < 4: + print("Usage: python askcode_summary_index.py index [supportedFileTypes] [target_dir]") sys.exit(1) supportedFileTypes = sys.argv[2].split(',') - index_directory(repo_dir, repo_cache_path, supportedFileTypes) + target_dir = sys.argv[3] + index_directory(repo_dir, repo_cache_path, supportedFileTypes, target_dir) elif command == "desc": if len(sys.argv) < 3: