Add InstallCommands functionality to DevChat

- Added a new command "InstallCommands" to the package.json file.
- Created a new function "registerInstallCommandsCommand" in commands.ts to handle the execution of the new command.
- The function checks for a directory in the user's home directory, if it exists it performs a git pull, if not it clones a git repository.
- The function is registered in the extension.ts file.
- Added a function "sendCommandListByDevChatRun" in regCommandList.ts to send the command list.
- The new command is executed in the statusBarView.ts file.
- Updated the InputMessage component to register a handler for the 'regCommandList' message.
- Updated the InputStore to handle the new commands and removed the old "regCommandMenus" function.
This commit is contained in:
bobo.yang 2023-08-30 16:39:47 +08:00
parent c6048d79fb
commit 63fbb1289d
7 changed files with 92 additions and 22 deletions

View File

@ -296,6 +296,11 @@
"command": "DevChat.AskCodeIndexSummaryStop",
"title": "Stop AskCode Summary Index",
"category": "DevChat"
},
{
"command": "DevChat.InstallCommands",
"title": "Install slash commands",
"category": "DevChat"
}
],
"menus": {

View File

@ -20,6 +20,9 @@ import { MessageHandler } from '../handler/messageHandler';
import { FT } from '../util/feature_flags/feature_toggles';
import { getPackageVersion } from '../util/python_installer/pip_package_version';
import { exec } from 'child_process';
import { sendCommandListByDevChatRun } from '../handler/regCommandList';
let indexProcess: CommandRun | null = null;
let summaryIndexProcess: CommandRun | null = null;
@ -500,6 +503,49 @@ export function registerAskCodeSummaryIndexStopCommand(context: vscode.Extension
context.subscriptions.push(disposable);
}
export function registerInstallCommandsCommand(context: vscode.ExtensionContext) {
let disposable = vscode.commands.registerCommand('DevChat.InstallCommands', async () => {
// step 1: find User Home Dir
const homeDir = process.env.HOME || process.env.USERPROFILE;
if (!homeDir) {
logger.channel()?.error(`Error: No valid home directory found.`);
logger.channel()?.show();
return;
}
// step 2: create ensure {User Home Dir}/.chat/workflows/ exists
const targetDir = path.join(homeDir, '.chat', 'workflows');
fs.mkdirSync(targetDir, { recursive: true });
const sysDir = path.join(targetDir, 'sys');
if (fs.existsSync(sysDir)) {
// step 3: if sys exists, then git pull
logger.channel()?.info(`Git pull from sys...`);
exec('git pull', { cwd: sysDir }, (error, stdout, stderr) => {
if (error) {
logger.channel()?.error(`Error pulling git repo: ${error}`);
} else {
logger.channel()?.info(`Git pull successful: ${stdout}`);
sendCommandListByDevChatRun();
}
});
} else {
// step 4: if sys not exists, then git clone
logger.channel()?.info(`Git clone to sys...`);
exec('git clone https://github.com/devchat-ai/workflows.git sys', { cwd: targetDir }, (error, stdout, stderr) => {
if (error) {
logger.channel()?.error(`Error cloning git repo: ${error}`);
} else {
logger.channel()?.info(`Git clone successful: ${stdout}`);
sendCommandListByDevChatRun();
}
});
}
});
context.subscriptions.push(disposable);
}
export function registerAddSummaryContextCommand(context: vscode.ExtensionContext) {
const callback = async (uri: { fsPath: any; }) => {
if (!FT("ask-code-summary")) {

View File

@ -20,6 +20,7 @@ import {
registerAskCodeSummaryIndexStartCommand,
registerAskCodeSummaryIndexStopCommand,
registerAddSummaryContextCommand,
registerInstallCommandsCommand,
} from './contributes/commands';
import { regLanguageContext } from './contributes/context';
import { regDevChatView, regTopicView } from './contributes/views';
@ -52,6 +53,8 @@ function activate(context: vscode.ExtensionContext) {
registerAskForFileCommand(context);
registerStatusBarItemClickCommand(context);
registerInstallCommandsCommand(context);
createStatusBarItem(context);
if (FT("ask-code")) {
createAskCodeStatusBarItem(context);

View File

@ -21,9 +21,13 @@ export async function regCommandList(message: any, panel: vscode.WebviewPanel|vs
return;
}
let existPannel: vscode.WebviewPanel|vscode.WebviewView|undefined = undefined;
regInMessage({command: 'regCommandList'});
regOutMessage({command: 'regCommandList', result: [{name: '', pattern: '', description: ''}]});
export async function regCommandListByDevChatRun(message: any, panel: vscode.WebviewPanel|vscode.WebviewView): Promise<void> {
existPannel = panel;
const commandList = await CommandManager.getInstance().getCommandListByDevChatRun();
const commandCovertedList = commandList.map(command => {
if (command.args > 0) {
@ -38,3 +42,9 @@ export async function regCommandListByDevChatRun(message: any, panel: vscode.Web
return;
}
export async function sendCommandListByDevChatRun() {
if (existPannel) {
regCommandListByDevChatRun({}, existPannel!);
}
}

View File

@ -8,6 +8,9 @@ import { ProgressBar } from '../util/progressBar';
export function createStatusBarItem(context: vscode.ExtensionContext): vscode.StatusBarItem {
const statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 100);
// execute command: DevChat.InstallCommands
vscode.commands.executeCommand('DevChat.InstallCommands');
// Set the status bar item properties
statusBarItem.text = `$(warning)DevChat`;
statusBarItem.tooltip = 'DevChat is checking ..., please wait';

View File

@ -185,6 +185,9 @@ const InputMessage = observer((props: any) => {
useEffect(() => {
input.fetchContextMenus().then();
input.fetchCommandMenus().then();
messageUtil.registerHandler('regCommandList', (message: { result: object[]}) => {
input.updateCommands(message.result);
});
messageUtil.registerHandler('appendContext', (message: { command: string; context: string }) => {
// context is a temp file path
const match = /\|([^]+?)\]/.exec(message.context);

View File

@ -21,20 +21,6 @@ const regContextMenus = async () => {
});
};
const regCommandMenus = async () => {
return new Promise<Item[]>((resolve, reject) => {
try {
messageUtil.sendMessage({ command: 'regCommandList' });
messageUtil.registerHandler('regCommandList', (message: { result: Item[] }) => {
resolve(message.result);
});
} catch (e) {
reject(e);
}
});
};
export const ChatContext = types.model({
file: types.maybe(types.string),
path: types.maybe(types.string),
@ -89,6 +75,11 @@ export const InputStore = types
setCurrentMenuIndex(index: number) {
self.currentMenuIndex = index;
},
updateCommands(items) {
self.commandMenus.clear();
self.commandMenus.push(...items);
self.commandMenus.push({ name: 'help', description: 'View the DevChat documentation.', pattern: 'help' });
},
fetchContextMenus: flow(function* () {
try {
const items = yield regContextMenus();
@ -97,11 +88,20 @@ export const InputStore = types
console.error("Failed to fetch context menus", error);
}
}),
fetchCommandMenus: flow(function* () {
const regCommandMenus = async () => {
return new Promise<Item[]>((resolve, reject) => {
try {
const items = yield regCommandMenus();
self.commandMenus.push(...items);
self.commandMenus.push({ name: 'help', description: 'View the DevChat documentation.', pattern: 'help' });
messageUtil.sendMessage({ command: 'regCommandList' });
} catch (e) {
reject(e);
}
});
};
try {
yield regCommandMenus();
} catch (error) {
console.error("Failed to fetch command menus", error);
}