Merge branch 'runjinz-chat-messages'
This commit is contained in:
commit
7352fb6fc7
@ -32,7 +32,7 @@ function initClipboard(codeBlocks, onApplyButtonClick, onApplyCodeButtonClick, o
|
|||||||
// Add 'Apply' button
|
// Add 'Apply' button
|
||||||
const applyButton = document.createElement('button');
|
const applyButton = document.createElement('button');
|
||||||
applyButton.classList.add('apply-button');
|
applyButton.classList.add('apply-button');
|
||||||
applyButton.innerText = 'Apply Patch';
|
applyButton.innerText = 'Show Diff';
|
||||||
block.appendChild(applyButton);
|
block.appendChild(applyButton);
|
||||||
|
|
||||||
applyButton.addEventListener('click', () => {
|
applyButton.addEventListener('click', () => {
|
||||||
|
@ -1 +0,0 @@
|
|||||||
You are a software developer assistant.
|
|
902
package-lock.json
generated
902
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
36
package.json
36
package.json
@ -18,6 +18,41 @@
|
|||||||
"README.md"
|
"README.md"
|
||||||
],
|
],
|
||||||
"contributes": {
|
"contributes": {
|
||||||
|
"configuration": {
|
||||||
|
"title": "DevChat",
|
||||||
|
"properties": {
|
||||||
|
"DevChat.llmModel": {
|
||||||
|
"type": "string",
|
||||||
|
"default": "OpenAI",
|
||||||
|
"enum": ["OpenAI"],
|
||||||
|
"description": "Select whose llm to use."
|
||||||
|
},
|
||||||
|
"DevChat.OpenAI.model": {
|
||||||
|
"type": "string",
|
||||||
|
"default": "gpt-4",
|
||||||
|
"description": "Specify llm model",
|
||||||
|
"when": "DevChat.llmModel == 'OpenAI'"
|
||||||
|
},
|
||||||
|
"DevChat.OpenAI.temperature": {
|
||||||
|
"type": "number",
|
||||||
|
"default": 0.2,
|
||||||
|
"description": "Specify llm temperature",
|
||||||
|
"when": "DevChat.llmModel == 'OpenAI'"
|
||||||
|
},
|
||||||
|
"DevChat.OpenAI.stream": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": true,
|
||||||
|
"description": "Specify llm stream",
|
||||||
|
"when": "DevChat.llmModel == 'OpenAI'"
|
||||||
|
},
|
||||||
|
"DevChat.OpenAI.apiKey": {
|
||||||
|
"type": "string",
|
||||||
|
"default": "",
|
||||||
|
"description": "Open API Key",
|
||||||
|
"when": "DevChat.llmModel == 'OpenAI'"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"views": {
|
"views": {
|
||||||
"explorer": [
|
"explorer": [
|
||||||
{
|
{
|
||||||
@ -139,6 +174,7 @@
|
|||||||
"nonce": "^1.0.4",
|
"nonce": "^1.0.4",
|
||||||
"openai": "^3.2.1",
|
"openai": "^3.2.1",
|
||||||
"quote": "^0.4.0",
|
"quote": "^0.4.0",
|
||||||
|
"react-remark": "^2.1.0",
|
||||||
"shell-escape": "^0.2.0",
|
"shell-escape": "^0.2.0",
|
||||||
"uuid": "^9.0.0"
|
"uuid": "^9.0.0"
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
const vscode = require('vscode');
|
const vscode = require('vscode');
|
||||||
|
import * as path from 'path';
|
||||||
|
import { createTempSubdirectory } from './commonUtil';
|
||||||
|
|
||||||
|
|
||||||
export async function applyCodeFile(text: string) {
|
export async function applyCodeFile(text: string) {
|
||||||
@ -23,7 +25,7 @@ export async function applyCodeFile(text: string) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function applyCode(text: string) {
|
export async function applyCode(text: string) {
|
||||||
if (vscode.window.visibleTextEditors.length > 1) {
|
if (vscode.window.visibleTextEditors.length > 1) {
|
||||||
vscode.window.showErrorMessage(`There are more then one visible text editors. Please close all but one and try again.`);
|
vscode.window.showErrorMessage(`There are more then one visible text editors. Please close all but one and try again.`);
|
||||||
return;
|
return;
|
||||||
@ -43,4 +45,43 @@ async function applyCode(text: string) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export default applyCode;
|
export async function diffView(code: string) {
|
||||||
|
if (vscode.window.visibleTextEditors.length > 1) {
|
||||||
|
vscode.window.showErrorMessage(`There are more then one visible text editors. Please close all but one and try again.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const editor = vscode.window.visibleTextEditors[0];
|
||||||
|
if (!editor) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const selectedText = editor.document.getText(editor.selection);
|
||||||
|
|
||||||
|
const curFile = editor.document.fileName;
|
||||||
|
|
||||||
|
// get file name from fileSelected
|
||||||
|
const fileName = path.basename(curFile);
|
||||||
|
|
||||||
|
// create temp directory and file
|
||||||
|
const tempDir = await createTempSubdirectory('devchat/context');
|
||||||
|
const tempFile = path.join(tempDir, fileName);
|
||||||
|
|
||||||
|
// save code to temp file
|
||||||
|
await vscode.workspace.fs.writeFile(vscode.Uri.file(tempFile), Buffer.from(code));
|
||||||
|
|
||||||
|
if (selectedText) {
|
||||||
|
// create temp directory and file
|
||||||
|
const tempDir = await createTempSubdirectory('devchat/context');
|
||||||
|
const tempSelectCodeFile = path.join(tempDir, fileName);
|
||||||
|
|
||||||
|
// save code to temp file
|
||||||
|
await vscode.workspace.fs.writeFile(vscode.Uri.file(tempSelectCodeFile), Buffer.from(selectedText));
|
||||||
|
|
||||||
|
// open diff view
|
||||||
|
vscode.commands.executeCommand('vscode.diff', vscode.Uri.file(tempSelectCodeFile), vscode.Uri.file(tempFile), 'Diff View');
|
||||||
|
} else {
|
||||||
|
// open diff view
|
||||||
|
vscode.commands.executeCommand('vscode.diff', vscode.Uri.file(curFile), vscode.Uri.file(tempFile), 'Diff View');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -44,15 +44,22 @@ async function writeDiffFile(diff_file: string) {
|
|||||||
|
|
||||||
export const commitMessageCommand: Command = {
|
export const commitMessageCommand: Command = {
|
||||||
name: 'commitMessageCommand',
|
name: 'commitMessageCommand',
|
||||||
pattern: 'git: commit message',
|
pattern: 'commit_meesage',
|
||||||
description: 'commit message for changes',
|
description: 'commit message for changes',
|
||||||
handler: async (userInput: string) => {
|
handler: async (userInput: string) => {
|
||||||
const tempDir = createTempSubdirectory('devchat/context');
|
const tempDir = createTempSubdirectory('devchat/context');
|
||||||
|
|
||||||
// 创建临时目录
|
// // 创建临时目录
|
||||||
const diff_file = path.join(tempDir, 'diff_output.txt');
|
// const diff_file = path.join(tempDir, 'diff_output.txt');
|
||||||
await writeDiffFile(diff_file);
|
// await writeDiffFile(diff_file);
|
||||||
|
|
||||||
return `[context|${diff_file}] Write a commit message`;
|
// return `[context|${diff_file}] Write a commit message`;
|
||||||
|
|
||||||
|
const workspaceDir = vscode.workspace.workspaceFolders?.[0].uri.fsPath;
|
||||||
|
if (workspaceDir) {
|
||||||
|
const commitmessageInstruction = path.join(workspaceDir, '.chat', 'instructions', 'commit_message', 'instCommitMessage.txt');
|
||||||
|
return `[instruction|${commitmessageInstruction}] Write a commit message`;
|
||||||
|
}
|
||||||
|
return 'Write a commit message';
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -5,6 +5,7 @@ import { promisify } from "util";
|
|||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import * as dotenv from 'dotenv';
|
import * as dotenv from 'dotenv';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
|
||||||
const spawnAsync = async (command: string, args: string[], options: any, onData: (data: string) => void): Promise<{code: number, stdout: string; stderr: string }> => {
|
const spawnAsync = async (command: string, args: string[], options: any, onData: (data: string) => void): Promise<{code: number, stdout: string; stderr: string }> => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@ -82,7 +83,28 @@ class DevChat {
|
|||||||
args.push(content)
|
args.push(content)
|
||||||
|
|
||||||
const workspaceDir = vscode.workspace.workspaceFolders?.[0].uri.fsPath;
|
const workspaceDir = vscode.workspace.workspaceFolders?.[0].uri.fsPath;
|
||||||
const openaiApiKey = process.env.OPENAI_API_KEY;
|
// const openaiApiKey = process.env.OPENAI_API_KEY;
|
||||||
|
|
||||||
|
const openaiApiKey = vscode.workspace.getConfiguration('DevChat').get('OpenAI.apiKey');
|
||||||
|
|
||||||
|
const openaiModel = vscode.workspace.getConfiguration('DevChat').get('OpenAI.model');
|
||||||
|
const openaiTemperature = vscode.workspace.getConfiguration('DevChat').get('OpenAI.temperature');
|
||||||
|
const openaiStream = vscode.workspace.getConfiguration('DevChat').get('OpenAI.stream');
|
||||||
|
const llmModel = vscode.workspace.getConfiguration('DevChat').get('llmModel');
|
||||||
|
|
||||||
|
const devchatConfig = {
|
||||||
|
llm: llmModel,
|
||||||
|
OpenAI: {
|
||||||
|
model: openaiModel,
|
||||||
|
temperature: openaiTemperature,
|
||||||
|
stream: openaiStream
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// write to config file
|
||||||
|
const configPath = path.join(workspaceDir!, '.chatconfig.json');
|
||||||
|
// write devchatConfig to configPath
|
||||||
|
const configJson = JSON.stringify(devchatConfig, null, 2);
|
||||||
|
fs.writeFileSync(configPath, configJson);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const {code, stdout, stderr } = await spawnAsync('devchat', args, {
|
const {code, stdout, stderr } = await spawnAsync('devchat', args, {
|
||||||
|
@ -6,7 +6,7 @@ import * as path from 'path';
|
|||||||
import { promisify } from 'util';
|
import { promisify } from 'util';
|
||||||
import DevChat, { LogOptions } from './devchat';
|
import DevChat, { LogOptions } from './devchat';
|
||||||
import DtmWrapper from './dtm';
|
import DtmWrapper from './dtm';
|
||||||
import applyCode, {applyCodeFile} from './applyCode';
|
import {applyCodeFile, diffView, applyCode} from './applyCode';
|
||||||
|
|
||||||
import './loadCommands';
|
import './loadCommands';
|
||||||
import './loadContexts'
|
import './loadContexts'
|
||||||
@ -87,7 +87,7 @@ function getInstructionFiles(): string[] {
|
|||||||
const instructionFiles: string[] = [];
|
const instructionFiles: string[] = [];
|
||||||
const workspaceDir = vscode.workspace.workspaceFolders?.[0].uri.fsPath;
|
const workspaceDir = vscode.workspace.workspaceFolders?.[0].uri.fsPath;
|
||||||
if (workspaceDir) {
|
if (workspaceDir) {
|
||||||
const chatInstructionsPath = path.join(workspaceDir, '.chat', 'instructions');
|
const chatInstructionsPath = path.join(workspaceDir, '.chat', 'instructions', 'default');
|
||||||
try {
|
try {
|
||||||
// 读取 chatInstructionsPath 目录下的所有文件和目录
|
// 读取 chatInstructionsPath 目录下的所有文件和目录
|
||||||
const files = fs.readdirSync(chatInstructionsPath);
|
const files = fs.readdirSync(chatInstructionsPath);
|
||||||
@ -126,6 +126,9 @@ async function handleMessage(
|
|||||||
}
|
}
|
||||||
|
|
||||||
chatOptions.header = getInstructionFiles();
|
chatOptions.header = getInstructionFiles();
|
||||||
|
if (parsedMessage.instruction.length > 0) {
|
||||||
|
chatOptions.header = parsedMessage.instruction;
|
||||||
|
}
|
||||||
|
|
||||||
if (parsedMessage.reference.length > 0) {
|
if (parsedMessage.reference.length > 0) {
|
||||||
chatOptions.reference = parsedMessage.reference;
|
chatOptions.reference = parsedMessage.reference;
|
||||||
@ -147,20 +150,12 @@ async function handleMessage(
|
|||||||
const logEntries = await devChat.log(logOptions);
|
const logEntries = await devChat.log(logOptions);
|
||||||
panel.webview.postMessage({ command: 'loadHistoryMessages', entries: logEntries });
|
panel.webview.postMessage({ command: 'loadHistoryMessages', entries: logEntries });
|
||||||
return;
|
return;
|
||||||
|
case 'show_diff':
|
||||||
|
diffView(message.content);
|
||||||
|
return;
|
||||||
|
// TODO: remove block_apply
|
||||||
case 'block_apply':
|
case 'block_apply':
|
||||||
const tempPatchFile = await saveTempPatchFile(message.content);
|
diffView(message.content);
|
||||||
try {
|
|
||||||
const patchResult = await dtmWrapper.patch(tempPatchFile);
|
|
||||||
await deleteTempPatchFile(tempPatchFile);
|
|
||||||
if (patchResult.status === 0) {
|
|
||||||
vscode.window.showInformationMessage('Patch applied successfully.');
|
|
||||||
} else {
|
|
||||||
vscode.window.showErrorMessage(`Error applying patch: ${patchResult.message} ${patchResult.log}`);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
await deleteTempPatchFile(tempPatchFile);
|
|
||||||
vscode.window.showErrorMessage(`Error applying patch: ${error}`);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
case 'code_apply':
|
case 'code_apply':
|
||||||
await applyCode(message.content);
|
await applyCode(message.content);
|
||||||
|
45
src/utils/MessageUtil.ts
Normal file
45
src/utils/MessageUtil.ts
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
const vscodeApi = window.acquireVsCodeApi();
|
||||||
|
|
||||||
|
class MessageUtil {
|
||||||
|
handlers: { [x: string]: any; };
|
||||||
|
constructor() {
|
||||||
|
this.handlers = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register a message handler for a specific message type
|
||||||
|
registerHandler(messageType: string, handler: { (message: { text: string; }): void; (message: { text: string; }): void; }) {
|
||||||
|
if (!this.handlers[messageType]) {
|
||||||
|
this.handlers[messageType] = [];
|
||||||
|
}
|
||||||
|
this.handlers[messageType].push(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unregister a message handler for a specific message type
|
||||||
|
unregisterHandler(messageType: string | number, handler: any) {
|
||||||
|
if (this.handlers[messageType]) {
|
||||||
|
this.handlers[messageType] = this.handlers[messageType].filter(
|
||||||
|
(h: any) => h !== handler
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle a received message
|
||||||
|
handleMessage(message: { command: string | number; }) {
|
||||||
|
console.log("handleMessage", message);
|
||||||
|
const handlers = this.handlers[message.command];
|
||||||
|
if (handlers) {
|
||||||
|
handlers.forEach((handler: (arg0: { command: string | number; }) => any) => handler(message));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send a message to the VSCode API
|
||||||
|
sendMessage(message: { command: string; text: string; }) {
|
||||||
|
console.log("sendMessage", message);
|
||||||
|
vscodeApi.postMessage(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Export the MessageUtil class as a module
|
||||||
|
export default MessageUtil;
|
@ -1,6 +1,6 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { Container } from '@mantine/core';
|
import { Avatar, Container, Divider, Flex, Grid, Stack, TypographyStylesProvider } from '@mantine/core';
|
||||||
import { Input, Tooltip } from '@mantine/core';
|
import { Input, Tooltip } from '@mantine/core';
|
||||||
import { List } from '@mantine/core';
|
import { List } from '@mantine/core';
|
||||||
import { ScrollArea } from '@mantine/core';
|
import { ScrollArea } from '@mantine/core';
|
||||||
@ -8,8 +8,11 @@ import { createStyles } from '@mantine/core';
|
|||||||
import { ActionIcon } from '@mantine/core';
|
import { ActionIcon } from '@mantine/core';
|
||||||
import { Menu, Button, Text } from '@mantine/core';
|
import { Menu, Button, Text } from '@mantine/core';
|
||||||
import { useViewportSize } from '@mantine/hooks';
|
import { useViewportSize } from '@mantine/hooks';
|
||||||
import { IconSend, IconSquareRoundedPlus } from '@tabler/icons-react';
|
import { IconEdit, IconRobot, IconSend, IconSquareRoundedPlus, IconUser } from '@tabler/icons-react';
|
||||||
import { IconSettings, IconSearch, IconPhoto, IconMessageCircle, IconTrash, IconArrowsLeftRight } from '@tabler/icons-react';
|
import { IconSettings, IconSearch, IconPhoto, IconMessageCircle, IconTrash, IconArrowsLeftRight } from '@tabler/icons-react';
|
||||||
|
import { Prism } from '@mantine/prism';
|
||||||
|
import { useRemark } from 'react-remark';
|
||||||
|
import MessageUtil from '../utils/MessageUtil';
|
||||||
|
|
||||||
const useStyles = createStyles((theme, _params, classNames) => ({
|
const useStyles = createStyles((theme, _params, classNames) => ({
|
||||||
panel: {
|
panel: {
|
||||||
@ -34,17 +37,40 @@ const useStyles = createStyles((theme, _params, classNames) => ({
|
|||||||
fontSize: '0.8rem',
|
fontSize: '0.8rem',
|
||||||
color: theme.colors.gray[6],
|
color: theme.colors.gray[6],
|
||||||
},
|
},
|
||||||
|
responseContent: {
|
||||||
|
marginTop: 8,
|
||||||
|
marginLeft: 0,
|
||||||
|
marginRight: 0,
|
||||||
|
},
|
||||||
icon: {
|
icon: {
|
||||||
pointerEvents: 'all',
|
pointerEvents: 'all',
|
||||||
},
|
},
|
||||||
|
avatar: {
|
||||||
|
marginTop: 8,
|
||||||
|
marginLeft: 8,
|
||||||
|
},
|
||||||
|
messageBody: {
|
||||||
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const chatPanel = () => {
|
const chatPanel = () => {
|
||||||
|
|
||||||
|
const [reactContent, setMarkdownSource] = useRemark();
|
||||||
const [opened, setOpened] = useState(false);
|
const [opened, setOpened] = useState(false);
|
||||||
|
const [input, setInput] = useState('');
|
||||||
const [commandOpened, setCommandOpened] = useState(false);
|
const [commandOpened, setCommandOpened] = useState(false);
|
||||||
const { classes } = useStyles();
|
const { classes } = useStyles();
|
||||||
const { height, width } = useViewportSize();
|
const { height, width } = useViewportSize();
|
||||||
|
const messageUtil = new MessageUtil();
|
||||||
|
|
||||||
|
const demoCode = `import { Button } from '@mantine/core';
|
||||||
|
function Demo() {
|
||||||
|
return <Button>Hello</Button>
|
||||||
|
}`;
|
||||||
|
|
||||||
|
setMarkdownSource(`# code block
|
||||||
|
print '3 backticks or'
|
||||||
|
print 'indent 4 spaces'`);
|
||||||
|
|
||||||
const handlePlusBottonClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
const handlePlusBottonClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
||||||
setOpened(!opened);
|
setOpened(!opened);
|
||||||
@ -53,26 +79,89 @@ const chatPanel = () => {
|
|||||||
const handleContainerClick = (event: React.MouseEvent<HTMLDivElement>) => {
|
const handleContainerClick = (event: React.MouseEvent<HTMLDivElement>) => {
|
||||||
if (opened) { setOpened(false); }
|
if (opened) { setOpened(false); }
|
||||||
};
|
};
|
||||||
|
const handleSendClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
||||||
|
const message = input;
|
||||||
|
if (message) {
|
||||||
|
// Add the user's message to the chat UI
|
||||||
|
// addMessageToUI('user', message);
|
||||||
|
|
||||||
|
// Clear the input field
|
||||||
|
event.currentTarget.value = '';
|
||||||
|
|
||||||
|
// Process and send the message to the extension
|
||||||
|
messageUtil.sendMessage({
|
||||||
|
command: 'sendMessage',
|
||||||
|
text: message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Register message handlers for receiving messages from the extension
|
||||||
|
messageUtil.registerHandler('receiveMessage', (message: { text: string; }) => {
|
||||||
|
console.log(`receiveMessage: ${message.text}`);
|
||||||
|
// Add the received message to the chat UI as a bot message
|
||||||
|
setMarkdownSource(message.text);
|
||||||
|
});
|
||||||
|
|
||||||
|
messageUtil.registerHandler('receiveMessagePartial', (message: { text: string; }) => {
|
||||||
|
console.log(`receiveMessagePartial: ${message.text}`);
|
||||||
|
// Add the received message to the chat UI as a bot message
|
||||||
|
setMarkdownSource(message.text);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
const value = event.target.value
|
const value = event.target.value;
|
||||||
// if value start with '/' command show menu
|
// if value start with '/' command show menu
|
||||||
if (value.startsWith('/')) {
|
if (value.startsWith('/')) {
|
||||||
setCommandOpened(true);
|
setCommandOpened(true);
|
||||||
} else {
|
} else {
|
||||||
setCommandOpened(false);
|
setCommandOpened(false);
|
||||||
}
|
}
|
||||||
}
|
setInput(value);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container className={classes.panel} onClick={handleContainerClick}>
|
<Container className={classes.panel} onClick={handleContainerClick}>
|
||||||
<ScrollArea h={height - 70} type="never">
|
<ScrollArea h={height - 70} type="never">
|
||||||
<List>
|
<Flex
|
||||||
<List.Item>Clone or download repository from GitHub</List.Item>
|
mih={50}
|
||||||
<List.Item>Install dependencies with yarn</List.Item>
|
gap="md"
|
||||||
<List.Item>To start development server run npm start command</List.Item>
|
justify="flex-start"
|
||||||
<List.Item>Run tests to make sure your changes do not break the build</List.Item>
|
align="flex-start"
|
||||||
<List.Item>Submit a pull request once you are done</List.Item>
|
direction="row"
|
||||||
</List>
|
wrap="wrap"
|
||||||
|
className={classes.messageBody}
|
||||||
|
>
|
||||||
|
<Avatar color="indigo" size='md' radius="xl" className={classes.avatar}>
|
||||||
|
<IconUser size="1.5rem" />
|
||||||
|
</Avatar>
|
||||||
|
<Container className={classes.responseContent}>
|
||||||
|
<Text>
|
||||||
|
Write a hello world, and explain it.
|
||||||
|
</Text>
|
||||||
|
</Container>
|
||||||
|
{/* <ActionIcon>
|
||||||
|
<IconEdit size="1.5rem" />
|
||||||
|
</ActionIcon> */}
|
||||||
|
</Flex>
|
||||||
|
<Divider my="sm" label="Mar 4, 2023" labelPosition="center" />
|
||||||
|
<Flex
|
||||||
|
mih={50}
|
||||||
|
gap="md"
|
||||||
|
justify="flex-start"
|
||||||
|
align="flex-start"
|
||||||
|
direction="row"
|
||||||
|
wrap="wrap"
|
||||||
|
className={classes.messageBody}
|
||||||
|
>
|
||||||
|
<Avatar color="blue" size='md' radius="xl" className={classes.avatar}>
|
||||||
|
<IconRobot size="1.5rem" />
|
||||||
|
</Avatar>
|
||||||
|
<Container className={classes.responseContent}>
|
||||||
|
{reactContent}
|
||||||
|
</Container>
|
||||||
|
</Flex>
|
||||||
</ScrollArea>
|
</ScrollArea>
|
||||||
<Menu id='plusMenu' shadow="md" width={200} opened={opened} onChange={setOpened} >
|
<Menu id='plusMenu' shadow="md" width={200} opened={opened} onChange={setOpened} >
|
||||||
<Menu.Dropdown className={classes.plusMenu}>
|
<Menu.Dropdown className={classes.plusMenu}>
|
||||||
@ -154,7 +243,7 @@ const chatPanel = () => {
|
|||||||
</ActionIcon>
|
</ActionIcon>
|
||||||
}
|
}
|
||||||
rightSection={
|
rightSection={
|
||||||
<ActionIcon>
|
<ActionIcon onClick={handleSendClick}>
|
||||||
<IconSend size="1rem" />
|
<IconSend size="1rem" />
|
||||||
</ActionIcon>
|
</ActionIcon>
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
|
import { createRoot } from 'react-dom/client';
|
||||||
import { MantineProvider } from '@mantine/core';
|
import { MantineProvider } from '@mantine/core';
|
||||||
import App from './App';
|
import App from './App';
|
||||||
|
|
||||||
ReactDOM.render(
|
const container = document.getElementById('app')!;
|
||||||
|
const root = createRoot(container); // createRoot(container!) if you use TypeScript
|
||||||
|
root.render(
|
||||||
<MantineProvider withGlobalStyles withNormalizeCSS>
|
<MantineProvider withGlobalStyles withNormalizeCSS>
|
||||||
<App />
|
<App />
|
||||||
</MantineProvider>,
|
</MantineProvider>
|
||||||
document.getElementById('app'));
|
);
|
||||||
|
@ -12,17 +12,16 @@ const CopyWebpackPlugin = require('copy-webpack-plugin');
|
|||||||
|
|
||||||
/** @type WebpackConfig */
|
/** @type WebpackConfig */
|
||||||
const extensionConfig = {
|
const extensionConfig = {
|
||||||
|
name: 'vscode extension',
|
||||||
target: 'node', // VS Code extensions run in a Node.js-context 📖 -> https://webpack.js.org/configuration/node/
|
target: 'node', // VS Code extensions run in a Node.js-context 📖 -> https://webpack.js.org/configuration/node/
|
||||||
mode: 'none', // this leaves the source code as close as possible to the original (when packaging we set this to 'production')
|
mode: 'none', // this leaves the source code as close as possible to the original (when packaging we set this to 'production')
|
||||||
|
|
||||||
entry: {
|
entry: './src/extension.ts', // the entry point of this extension, 📖 -> https://webpack.js.org/configuration/entry-context/
|
||||||
extension: './src/extension.ts', // the entry point of this extension, 📖 -> https://webpack.js.org/configuration/entry-context/
|
|
||||||
index: './src/views/index.tsx'
|
|
||||||
},
|
|
||||||
output: {
|
output: {
|
||||||
// the bundle is stored in the 'dist' folder (check package.json), 📖 -> https://webpack.js.org/configuration/output/
|
// the bundle is stored in the 'dist' folder (check package.json), 📖 -> https://webpack.js.org/configuration/output/
|
||||||
path: path.resolve(__dirname, 'dist'),
|
path: path.resolve(__dirname, 'dist'),
|
||||||
filename: '[name].js',
|
filename: 'extension.js',
|
||||||
libraryTarget: 'commonjs2'
|
libraryTarget: 'commonjs2'
|
||||||
},
|
},
|
||||||
externals: {
|
externals: {
|
||||||
@ -31,6 +30,51 @@ const extensionConfig = {
|
|||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
// support reading TypeScript and JavaScript files, 📖 -> https://github.com/TypeStrong/ts-loader
|
// support reading TypeScript and JavaScript files, 📖 -> https://github.com/TypeStrong/ts-loader
|
||||||
|
extensions: ['.ts', '.json']
|
||||||
|
},
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.ts?$/,
|
||||||
|
exclude: /node_modules/,
|
||||||
|
use: [
|
||||||
|
{
|
||||||
|
loader: 'babel-loader',
|
||||||
|
options: {
|
||||||
|
presets: [
|
||||||
|
'@babel/preset-env',
|
||||||
|
'@babel/preset-react',
|
||||||
|
'@babel/preset-typescript'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loader: 'ts-loader'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
devtool: 'nosources-source-map',
|
||||||
|
infrastructureLogging: {
|
||||||
|
level: "log", // enables logging required for problem matchers
|
||||||
|
},
|
||||||
|
plugins: []
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** @type WebpackConfig */
|
||||||
|
const webviewConfig = {
|
||||||
|
name: 'webview',
|
||||||
|
target: 'web',
|
||||||
|
mode: 'development',
|
||||||
|
|
||||||
|
entry: './src/views/index.tsx',
|
||||||
|
output: {
|
||||||
|
path: path.resolve(__dirname, 'dist'),
|
||||||
|
filename: 'index.js',
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
extensions: ['.ts', '.tsx', '.js', '.json']
|
extensions: ['.ts', '.tsx', '.js', '.json']
|
||||||
},
|
},
|
||||||
module: {
|
module: {
|
||||||
@ -56,8 +100,18 @@ const extensionConfig = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.jsx?$/,
|
test: /\.jsx?$/,
|
||||||
use: 'babel-loader',
|
|
||||||
exclude: /node_modules/,
|
exclude: /node_modules/,
|
||||||
|
use: [{
|
||||||
|
loader: 'babel-loader',
|
||||||
|
options: {
|
||||||
|
presets: [
|
||||||
|
[
|
||||||
|
'@babel/preset-env',
|
||||||
|
'@babel/preset-react',
|
||||||
|
],
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.css$/i,
|
test: /\.css$/i,
|
||||||
@ -94,9 +148,9 @@ const extensionConfig = {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
devtool: 'nosources-source-map',
|
devtool: 'source-map',
|
||||||
infrastructureLogging: {
|
infrastructureLogging: {
|
||||||
level: "log", // enables logging required for problem matchers
|
level: "log",
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
// generate an HTML file that includes the extension's JavaScript file
|
// generate an HTML file that includes the extension's JavaScript file
|
||||||
@ -109,12 +163,9 @@ const extensionConfig = {
|
|||||||
patterns: [
|
patterns: [
|
||||||
{ from: 'assets', to: 'assets' },
|
{ from: 'assets', to: 'assets' },
|
||||||
],
|
],
|
||||||
}),
|
|
||||||
// define global variables
|
|
||||||
new DefinePlugin({
|
|
||||||
'process.env.NODE_ENV': JSON.stringify('development')
|
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = [extensionConfig];
|
|
||||||
|
module.exports = [extensionConfig, webviewConfig];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user