Add commands for DevChat
- Added commands for adding context and summary to DevChat. - Updated the package.json file to include the new commands. - Added command handlers for indexing and describing codebase summaries. - Created a new file, askcode_summary_index.py, for indexing and describing codebase summaries. - Added a new setting file, _setting_.json, for the summary action in the auto_command workflow. - Added a new handler file, handler.py, for the summary action in the auto_command workflow.
This commit is contained in:
parent
3bf09924d7
commit
6713a98df9
23
package.json
23
package.json
@ -248,6 +248,10 @@
|
||||
"command": "devchat.addConext",
|
||||
"title": "Add to DevChat"
|
||||
},
|
||||
{
|
||||
"command": "devchat.addSummaryContext",
|
||||
"title": "Add summary to DevChat"
|
||||
},
|
||||
{
|
||||
"command": "devchat.askForCode",
|
||||
"title": "Add to DevChat"
|
||||
@ -277,6 +281,16 @@
|
||||
"command": "DevChat.AskCodeIndexStop",
|
||||
"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"
|
||||
}
|
||||
],
|
||||
"menus": {
|
||||
@ -340,6 +354,10 @@
|
||||
"command": "devchat.addConext",
|
||||
"when": "false"
|
||||
},
|
||||
{
|
||||
"command": "devchat.addSummaryContext",
|
||||
"when": "false"
|
||||
},
|
||||
{
|
||||
"command": "devchat.askForCode",
|
||||
"when": "false"
|
||||
@ -371,6 +389,11 @@
|
||||
"when": "!isChineseLocale && resourceLangId != 'git'",
|
||||
"command": "devchat.addConext",
|
||||
"group": "navigation"
|
||||
},
|
||||
{
|
||||
"when": "!isChineseLocale && resourceLangId != 'git'",
|
||||
"command": "devchat.addSummaryContext",
|
||||
"group": "navigation"
|
||||
}
|
||||
],
|
||||
"editor/context": [
|
||||
|
@ -1,4 +1,5 @@
|
||||
import * as vscode from 'vscode';
|
||||
import * as fs from 'fs';
|
||||
import { sendFileSelectMessage, sendCodeSelectMessage } from './util';
|
||||
import ExtensionContextHolder from '../util/extensionContext';
|
||||
import { TopicManager } from '../topic/topicManager';
|
||||
@ -9,14 +10,16 @@ import { UiUtilWrapper } from '../util/uiUtil';
|
||||
import { isValidApiKey } from '../handler/historyMessagesBase';
|
||||
|
||||
import { logger } from '../util/logger';
|
||||
import { CommandRun } from '../util/commonUtil';
|
||||
import { CommandRun, createTempSubdirectory, runCommandAndWriteOutput, runCommandStringAndWriteOutput, runCommandStringArrayAndWriteOutput } from '../util/commonUtil';
|
||||
import { updateIndexingStatus, updateLastModifyTime } from '../util/askCodeUtil';
|
||||
import { installAskCode as installAskCodeFun } from '../util/python_installer/install_askcode';
|
||||
|
||||
import { ProgressBar } from '../util/progressBar';
|
||||
import path from 'path';
|
||||
import { MessageHandler } from '../handler/messageHandler';
|
||||
|
||||
let indexProcess: CommandRun | null = null;
|
||||
|
||||
let summaryIndexProcess: CommandRun | null = null;
|
||||
|
||||
function registerOpenChatPanelCommand(context: vscode.ExtensionContext) {
|
||||
let disposable = vscode.commands.registerCommand('devchat.openChatPanel', async () => {
|
||||
@ -248,7 +251,7 @@ export function registerAskCodeIndexStartCommand(context: vscode.ExtensionContex
|
||||
|
||||
if (!pythonVirtualEnv) {
|
||||
progressBar.update("Install devchat-ask package ...", 0);
|
||||
await installAskCode(supportedFileTypes, progressBar);
|
||||
await installAskCode(supportedFileTypes, progressBar, indexCode);
|
||||
} else {
|
||||
progressBar.update("Index source files ...", 0);
|
||||
await indexCode(pythonVirtualEnv, supportedFileTypes, progressBar);
|
||||
@ -266,19 +269,20 @@ function getConfig() {
|
||||
};
|
||||
}
|
||||
|
||||
async function installAskCode(supportedFileTypes, progressBar: any) {
|
||||
const pythonEnvPath : string = await installAskCodeFun();
|
||||
if (!pythonEnvPath) {
|
||||
logger.channel()?.error(`Installation failed!`);
|
||||
logger.channel()?.show();
|
||||
return;
|
||||
}
|
||||
|
||||
UiUtilWrapper.updateConfiguration("DevChat", "PythonVirtualEnv", pythonEnvPath.trim());
|
||||
async function installAskCode(supportedFileTypes, progressBar: any, callback: Function) {
|
||||
const pythonEnvPath : string = await installAskCodeFun();
|
||||
if (!pythonEnvPath) {
|
||||
logger.channel()?.error(`Installation failed!`);
|
||||
logger.channel()?.show();
|
||||
return;
|
||||
}
|
||||
|
||||
UiUtilWrapper.updateConfiguration("DevChat", "PythonVirtualEnv", pythonEnvPath.trim());
|
||||
logger.channel()?.info(`Installation finished.`);
|
||||
|
||||
// Execute the indexing command after the installation is finished
|
||||
await indexCode(pythonEnvPath, supportedFileTypes, progressBar);
|
||||
// Execute the callback function after the installation is finished
|
||||
await callback(pythonEnvPath, supportedFileTypes, progressBar);
|
||||
}
|
||||
|
||||
async function indexCode(pythonVirtualEnv, supportedFileTypes, progressBar: any) {
|
||||
@ -349,6 +353,136 @@ export function registerAskCodeIndexStopCommand(context: vscode.ExtensionContext
|
||||
context.subscriptions.push(disposable);
|
||||
}
|
||||
|
||||
export function registerAskCodeSummaryIndexStartCommand(context: vscode.ExtensionContext) {
|
||||
let disposable = vscode.commands.registerCommand('DevChat.AskCodeSummaryIndexStart', async () => {
|
||||
const progressBar = new ProgressBar();
|
||||
progressBar.init();
|
||||
|
||||
progressBar.update("Index source code files for ask codebase summary...", 0);
|
||||
|
||||
const config = getConfig();
|
||||
const pythonVirtualEnv = config.pythonVirtualEnv;
|
||||
const supportedFileTypes = config.supportedFileTypes;
|
||||
|
||||
updateIndexingStatus("started");
|
||||
|
||||
if (!pythonVirtualEnv) {
|
||||
progressBar.update("Install devchat-ask package ...", 0);
|
||||
await installAskCode(supportedFileTypes, progressBar, indexCodeSummary);
|
||||
} else {
|
||||
progressBar.update("Index source files for summary...", 0);
|
||||
await indexCodeSummary(pythonVirtualEnv, supportedFileTypes, progressBar);
|
||||
}
|
||||
|
||||
updateIndexingStatus("stopped");
|
||||
});
|
||||
context.subscriptions.push(disposable);
|
||||
}
|
||||
|
||||
async function indexCodeSummary(pythonVirtualEnv, supportedFileTypes, progressBar: any) {
|
||||
let envs = {};
|
||||
|
||||
let openaiApiKey = await ApiKeyManager.getApiKey();
|
||||
if (!openaiApiKey) {
|
||||
logger.channel()?.error('The OpenAI key is invalid!');
|
||||
logger.channel()?.show();
|
||||
|
||||
progressBar.endWithError("The OpenAI key is invalid!");
|
||||
return;
|
||||
}
|
||||
envs['OPENAI_API_KEY'] = openaiApiKey;
|
||||
|
||||
const openAiApiBase = ApiKeyManager.getEndPoint(openaiApiKey);
|
||||
if (openAiApiBase) {
|
||||
envs['OPENAI_API_BASE'] = openAiApiBase;
|
||||
}
|
||||
|
||||
const workspaceDir = UiUtilWrapper.workspaceFoldersFirstPath();
|
||||
|
||||
const command = pythonVirtualEnv.trim();
|
||||
const args = [UiUtilWrapper.extensionPath() + "/tools/askcode_summary_index.py", "index", supportedFileTypes];
|
||||
const options = { env: envs, cwd: workspaceDir };
|
||||
|
||||
summaryIndexProcess = new CommandRun();
|
||||
const result = await summaryIndexProcess.spawnAsync(command, args, options, (data) => {
|
||||
if (data.includes('Skip file:')) {
|
||||
return;
|
||||
}
|
||||
logger.channel()?.info(`${data}`);
|
||||
}, (data) => {
|
||||
if (data.includes('Skip file:')) {
|
||||
return;
|
||||
}
|
||||
logger.channel()?.info(`${data}`);
|
||||
}, undefined, undefined);
|
||||
|
||||
if (result.exitCode !== 0) {
|
||||
if (result.exitCode === null) {
|
||||
logger.channel()?.info(`Indexing stopped!`);
|
||||
progressBar.endWithError(`Indexing stopped!`);
|
||||
} else {
|
||||
logger.channel()?.error(`Indexing failed: ${result.stderr}`);
|
||||
logger.channel()?.show();
|
||||
progressBar.endWithError(`Indexing failed: ${result.stderr}`);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
updateLastModifyTime();
|
||||
logger.channel()?.info(`index finished.`);
|
||||
|
||||
progressBar.update("Indexing finished.");
|
||||
progressBar.end();
|
||||
}
|
||||
|
||||
export function registerAskCodeSummaryIndexStopCommand(context: vscode.ExtensionContext) {
|
||||
let disposable = vscode.commands.registerCommand('DevChat.AskCodeIndexSummaryStop', async () => {
|
||||
// 在这里实现停止索引的功能
|
||||
// 你可能需要检查summaryIndexProcess变量是否为null,如果不为null,那么停止索引进程
|
||||
if (summaryIndexProcess) {
|
||||
summaryIndexProcess.stop();
|
||||
summaryIndexProcess = null;
|
||||
}
|
||||
});
|
||||
context.subscriptions.push(disposable);
|
||||
}
|
||||
|
||||
export function registerAddSummaryContextCommand(context: vscode.ExtensionContext) {
|
||||
const callback = async (uri: { fsPath: any; }) => {
|
||||
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}]` });
|
||||
};
|
||||
context.subscriptions.push(vscode.commands.registerCommand('devchat.addSummaryContext', callback));
|
||||
}
|
||||
|
||||
|
||||
export {
|
||||
registerOpenChatPanelCommand,
|
||||
registerAddContextCommand,
|
||||
|
@ -1,22 +1,25 @@
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
import {
|
||||
registerOpenChatPanelCommand,
|
||||
registerAddContextCommand,
|
||||
registerAskForCodeCommand,
|
||||
registerAskForFileCommand,
|
||||
registerOpenAiApiKeySettingCommand,
|
||||
registerDevChatApiKeySettingCommand,
|
||||
regTopicDeleteCommand,
|
||||
regAddTopicCommand,
|
||||
regDeleteSelectTopicCommand,
|
||||
regSelectTopicCommand,
|
||||
regReloadTopicCommand,
|
||||
regApplyDiffResultCommand,
|
||||
registerStatusBarItemClickCommand,
|
||||
regPythonPathCommand,
|
||||
registerAskCodeIndexStartCommand,
|
||||
registerOpenChatPanelCommand,
|
||||
registerAddContextCommand,
|
||||
registerAskForCodeCommand,
|
||||
registerAskForFileCommand,
|
||||
registerOpenAiApiKeySettingCommand,
|
||||
registerDevChatApiKeySettingCommand,
|
||||
regTopicDeleteCommand,
|
||||
regAddTopicCommand,
|
||||
regDeleteSelectTopicCommand,
|
||||
regSelectTopicCommand,
|
||||
regReloadTopicCommand,
|
||||
regApplyDiffResultCommand,
|
||||
registerStatusBarItemClickCommand,
|
||||
regPythonPathCommand,
|
||||
registerAskCodeIndexStartCommand,
|
||||
registerAskCodeIndexStopCommand,
|
||||
registerAskCodeSummaryIndexStartCommand,
|
||||
registerAskCodeSummaryIndexStopCommand,
|
||||
registerAddSummaryContextCommand,
|
||||
} from './contributes/commands';
|
||||
import { regLanguageContext } from './contributes/context';
|
||||
import { regDevChatView, regTopicView } from './contributes/views';
|
||||
@ -30,36 +33,39 @@ import { UiUtilVscode } from './util/uiUtil_vscode';
|
||||
|
||||
|
||||
function activate(context: vscode.ExtensionContext) {
|
||||
ExtensionContextHolder.context = context;
|
||||
ExtensionContextHolder.context = context;
|
||||
|
||||
logger.init(LoggerChannelVscode.getInstance());
|
||||
UiUtilWrapper.init(new UiUtilVscode());
|
||||
logger.init(LoggerChannelVscode.getInstance());
|
||||
UiUtilWrapper.init(new UiUtilVscode());
|
||||
|
||||
regLanguageContext();
|
||||
regLanguageContext();
|
||||
|
||||
regDevChatView(context);
|
||||
regTopicView(context);
|
||||
regDevChatView(context);
|
||||
regTopicView(context);
|
||||
|
||||
registerOpenAiApiKeySettingCommand(context);
|
||||
registerDevChatApiKeySettingCommand(context);
|
||||
registerOpenChatPanelCommand(context);
|
||||
registerAddContextCommand(context);
|
||||
registerAskForCodeCommand(context);
|
||||
registerAskForFileCommand(context);
|
||||
registerStatusBarItemClickCommand(context);
|
||||
registerOpenAiApiKeySettingCommand(context);
|
||||
registerDevChatApiKeySettingCommand(context);
|
||||
registerOpenChatPanelCommand(context);
|
||||
registerAddContextCommand(context);
|
||||
registerAskForCodeCommand(context);
|
||||
registerAskForFileCommand(context);
|
||||
registerStatusBarItemClickCommand(context);
|
||||
|
||||
createStatusBarItem(context);
|
||||
createAskCodeStatusBarItem(context);
|
||||
createStatusBarItem(context);
|
||||
createAskCodeStatusBarItem(context);
|
||||
|
||||
regTopicDeleteCommand(context);
|
||||
regAddTopicCommand(context);
|
||||
regDeleteSelectTopicCommand(context);
|
||||
regSelectTopicCommand(context);
|
||||
regReloadTopicCommand(context);
|
||||
regApplyDiffResultCommand(context);
|
||||
regTopicDeleteCommand(context);
|
||||
regAddTopicCommand(context);
|
||||
regDeleteSelectTopicCommand(context);
|
||||
regSelectTopicCommand(context);
|
||||
regReloadTopicCommand(context);
|
||||
regApplyDiffResultCommand(context);
|
||||
|
||||
regPythonPathCommand(context);
|
||||
registerAskCodeIndexStartCommand(context);
|
||||
regPythonPathCommand(context);
|
||||
registerAskCodeIndexStartCommand(context);
|
||||
registerAskCodeIndexStopCommand(context);
|
||||
registerAskCodeSummaryIndexStartCommand(context);
|
||||
registerAskCodeSummaryIndexStopCommand(context);
|
||||
registerAddSummaryContextCommand(context);
|
||||
}
|
||||
exports.activate = activate;
|
139
tools/askcode_summary_index.py
Normal file
139
tools/askcode_summary_index.py
Normal file
@ -0,0 +1,139 @@
|
||||
import os
|
||||
import re
|
||||
import json
|
||||
import sys
|
||||
from chat.ask_codebase.indexing.loader.file import FileMetadata, FileSource, simple_file_filter
|
||||
from chat.ask_codebase.indexing.module_summary import SummaryWrapper
|
||||
|
||||
# 为已经分析的文件记录最后修改时间
|
||||
g_file_last_modified_saved = {}
|
||||
|
||||
def load_file_last_modified(filePath: str):
|
||||
if not os.path.exists(filePath):
|
||||
return {}
|
||||
|
||||
with open(filePath, 'r', encoding="utf-8") as f:
|
||||
fileLastModified = json.load(f)
|
||||
|
||||
return fileLastModified
|
||||
|
||||
def save_file_last_modified(filePath: str, fileLastModified: dict):
|
||||
with open(filePath, 'w+', encoding="utf-8") as f:
|
||||
json.dump(fileLastModified, f)
|
||||
|
||||
return fileLastModified
|
||||
|
||||
def is_source_code_new(filePath: str, supportedFileTypes):
|
||||
for pattern in supportedFileTypes:
|
||||
if re.match(pattern.strip(), filePath):
|
||||
return True
|
||||
return False
|
||||
|
||||
def is_file_modified(filePath: str, supportedFileTypes) -> bool:
|
||||
if not is_source_code_new(filePath, supportedFileTypes):
|
||||
return False
|
||||
|
||||
relativePath = os.path.relpath(filePath, os.getcwd())
|
||||
|
||||
for part in relativePath.split(os.sep):
|
||||
if part.startswith('.'):
|
||||
return False
|
||||
|
||||
fileLastModified = g_file_last_modified_saved.get(relativePath, 0)
|
||||
fileCurrentModified = os.path.getmtime(filePath)
|
||||
|
||||
if fileLastModified != fileCurrentModified:
|
||||
g_file_last_modified_saved[relativePath] = fileCurrentModified
|
||||
return True
|
||||
return False
|
||||
|
||||
def custom_file_filter(file_path: str, supportedFileTypes) -> bool:
|
||||
print("==> ", file_path)
|
||||
|
||||
if os.path.isdir(file_path):
|
||||
return True
|
||||
|
||||
return is_file_modified(file_path, supportedFileTypes)
|
||||
|
||||
def index_directory(repo_dir: str, repo_cache_path: str, supportedFileTypes):
|
||||
"""
|
||||
index files in repo_dir
|
||||
"""
|
||||
global g_file_last_modified_saved
|
||||
g_file_last_modified_saved = load_file_last_modified('.chat/.index_modified.json')
|
||||
|
||||
sw = SummaryWrapper(repo_cache_path, FileSource(
|
||||
path=repo_dir,
|
||||
rel_root=repo_dir,
|
||||
file_filter=lambda file_path: custom_file_filter(file_path, supportedFileTypes),
|
||||
))
|
||||
|
||||
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):
|
||||
"""
|
||||
"""
|
||||
target_path = target_path.replace(repo_dir, '')
|
||||
sw = SummaryWrapper(repo_cache_path, FileSource(
|
||||
path=repo_dir,
|
||||
rel_root=repo_dir,
|
||||
file_filter=simple_file_filter,
|
||||
))
|
||||
return sw.get_desc(target_path)
|
||||
|
||||
def context(repo_dir: str, repo_cache_path: str, target_path: str):
|
||||
"""
|
||||
"""
|
||||
target_path = os.path.relpath(target_path, repo_dir)
|
||||
sw = SummaryWrapper(repo_cache_path, FileSource(
|
||||
path=repo_dir,
|
||||
rel_root=repo_dir,
|
||||
file_filter=simple_file_filter,
|
||||
))
|
||||
return sw.prepare_context_by_top_module(target_path)
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 2:
|
||||
print("Usage: python askcode_summary_index.py [command] [args]")
|
||||
print("Available commands: index, desc, context")
|
||||
sys.exit(1)
|
||||
|
||||
command = sys.argv[1]
|
||||
|
||||
# Set default values for repo_dir and repo_cache_path
|
||||
repo_dir = os.getcwd()
|
||||
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]")
|
||||
sys.exit(1)
|
||||
|
||||
supportedFileTypes = sys.argv[2].split(',')
|
||||
index_directory(repo_dir, repo_cache_path, supportedFileTypes)
|
||||
|
||||
elif command == "desc":
|
||||
if len(sys.argv) < 3:
|
||||
print("Usage: python askcode_summary_index.py desc [target_path]")
|
||||
sys.exit(1)
|
||||
|
||||
target_path = sys.argv[2]
|
||||
print(desc(repo_dir, repo_cache_path, target_path))
|
||||
|
||||
elif command == "context":
|
||||
if len(sys.argv) < 3:
|
||||
print("Usage: python askcode_summary_index.py context [target_path]")
|
||||
sys.exit(1)
|
||||
|
||||
target_path = sys.argv[2]
|
||||
print(context(repo_dir, repo_cache_path, target_path))
|
||||
|
||||
else:
|
||||
print("Invalid command. Available commands: index, desc, context")
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
15
workflows/auto_command/action/summary/_setting_.json
Normal file
15
workflows/auto_command/action/summary/_setting_.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "summary",
|
||||
"description": "Get summary of specified file or direcotry in workspace",
|
||||
"type": ["project"],
|
||||
"action": "summary",
|
||||
"args": [
|
||||
{
|
||||
"name": "path",
|
||||
"description": "The relative path of the specified file or folder, for example, /hello.py, represents the hello.py file in the root directory. This arg is required.",
|
||||
"type": "string",
|
||||
"from": "content.content.path"
|
||||
}
|
||||
],
|
||||
"handler": ["${PythonVirtualEnv}", "${CurDir}/handler.py", "${path}"]
|
||||
}
|
37
workflows/auto_command/action/summary/handler.py
Normal file
37
workflows/auto_command/action/summary/handler.py
Normal file
@ -0,0 +1,37 @@
|
||||
"""
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
from chat.ask_codebase.indexing.loader.file import FileMetadata, FileSource, simple_file_filter
|
||||
from chat.ask_codebase.indexing.module_summary import SummaryWrapper
|
||||
|
||||
def desc(repo_dir: str, repo_cache_path: str, target_path: str):
|
||||
"""
|
||||
"""
|
||||
target_path = target_path.replace(repo_dir, '')
|
||||
sw = SummaryWrapper(repo_cache_path, FileSource(
|
||||
path=repo_dir,
|
||||
rel_root=repo_dir,
|
||||
file_filter=simple_file_filter,
|
||||
))
|
||||
return sw.get_desc(target_path)
|
||||
|
||||
|
||||
def summary():
|
||||
"""
|
||||
Get file or directory 's summary
|
||||
"""
|
||||
try:
|
||||
repo_dir = os.getcwd()
|
||||
repo_cache_path = os.path.join(repo_dir, '.chat', '.summary.json')
|
||||
|
||||
target_path = sys.argv[1]
|
||||
return desc(repo_dir, repo_cache_path, target_path)
|
||||
except Exception as e:
|
||||
sys.stderr.write(f"Error: {str(e)}\n")
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(summary())
|
||||
sys.exit(0)
|
Loading…
x
Reference in New Issue
Block a user