diff options
Diffstat (limited to 'extension')
-rw-r--r-- | extension/react-app/src/components/CodeBlock.tsx | 6 | ||||
-rw-r--r-- | extension/react-app/src/components/ComboBox.tsx | 15 | ||||
-rw-r--r-- | extension/react-app/src/components/PillButton.tsx | 15 | ||||
-rw-r--r-- | extension/react-app/src/components/RingLoader.tsx | 39 | ||||
-rw-r--r-- | extension/react-app/src/components/StepContainer.tsx | 30 | ||||
-rw-r--r-- | extension/react-app/src/components/UserInputContainer.tsx | 6 | ||||
-rw-r--r-- | extension/react-app/src/hooks/useWebsocket.ts | 7 | ||||
-rw-r--r-- | extension/react-app/src/pages/gui.tsx | 79 | ||||
-rw-r--r-- | extension/src/activation/environmentSetup.ts | 33 | ||||
-rw-r--r-- | extension/src/continueIdeClient.ts | 2 | ||||
-rw-r--r-- | extension/src/debugPanel.ts | 14 | ||||
-rw-r--r-- | extension/src/util/messenger.ts | 1 |
12 files changed, 163 insertions, 84 deletions
diff --git a/extension/react-app/src/components/CodeBlock.tsx b/extension/react-app/src/components/CodeBlock.tsx index f51b7d9f..9909db0f 100644 --- a/extension/react-app/src/components/CodeBlock.tsx +++ b/extension/react-app/src/components/CodeBlock.tsx @@ -52,12 +52,12 @@ function CopyButton(props: { textToCopy: string; visible: boolean }) { }} > {clicked ? ( - <CheckCircleIcon color="#00ff00" width="1.5em" height="1.5em" /> + <CheckCircleIcon color="#00ff00" width="1.4em" height="1.4em" /> ) : ( <ClipboardIcon color={hovered ? "#00ff00" : "white"} - width="1.5em" - height="1.5em" + width="1.4em" + height="1.4em" /> )} </StyledCopyButton> diff --git a/extension/react-app/src/components/ComboBox.tsx b/extension/react-app/src/components/ComboBox.tsx index 9017f19c..df3f970c 100644 --- a/extension/react-app/src/components/ComboBox.tsx +++ b/extension/react-app/src/components/ComboBox.tsx @@ -32,7 +32,9 @@ const SEARCH_INDEX_NAME = "continue_context_items"; const mainInputFontSize = 13; const EmptyPillDiv = styled.div` - padding: 8px; + padding: 4px; + padding-left: 8px; + padding-right: 8px; border-radius: ${defaultBorderRadius}; border: 1px dashed ${lightGray}; color: ${lightGray}; @@ -273,6 +275,7 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => { {props.selectedContextItems.map((item, idx) => { return ( <PillButton + areMultipleItems={props.selectedContextItems.length > 1} key={`${item.description.id.item_id}${idx}`} item={item} warning={ @@ -301,7 +304,7 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => { props.onToggleAddContext(); }} > - <DocumentPlusIcon width="1.5em" height="1.5em" /> + <DocumentPlusIcon width="1.4em" height="1.4em" /> </HeaderButtonWithText> ))} </div> @@ -378,6 +381,14 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => { Math.min(prev + 1, history.length) ); setCurrentlyInContextQuery(false); + } else if (event.key === "Escape") { + setCurrentlyInContextQuery(false); + if (downshiftProps.isOpen) { + downshiftProps.closeMenu(); + } else { + // Move cursor back over to the editor + postVscMessage("focusEditor", {}); + } } }, onClick: () => { diff --git a/extension/react-app/src/components/PillButton.tsx b/extension/react-app/src/components/PillButton.tsx index 8e5f896e..edef808e 100644 --- a/extension/react-app/src/components/PillButton.tsx +++ b/extension/react-app/src/components/PillButton.tsx @@ -28,8 +28,11 @@ const Button = styled.button` color: ${vscForeground}; background-color: ${secondaryDark}; border-radius: ${defaultBorderRadius}; - padding: 8px; + padding: 4px; + padding-left: 8px; + padding-right: 8px; overflow: hidden; + font-size: 13px; cursor: pointer; `; @@ -50,7 +53,6 @@ const GridDiv = styled.div` const ButtonDiv = styled.div<{ backgroundColor: string }>` background-color: ${secondaryDark}; - padding: 3px; height: 100%; display: flex; align-items: center; @@ -81,6 +83,7 @@ interface PillButtonProps { warning?: string; index: number; addingHighlightedCode?: boolean; + areMultipleItems?: boolean; } const PillButton = (props: PillButtonProps) => { @@ -100,8 +103,8 @@ const PillButton = (props: PillButtonProps) => { <pre> <code style={{ - fontSize: "11px", - backgroundColor: vscBackground, + fontSize: "12px", + backgroundColor: "transparent", color: vscForeground, whiteSpace: "pre-wrap", wordWrap: "break-word", @@ -134,8 +137,8 @@ const PillButton = (props: PillButtonProps) => { position: "relative", borderColor: props.warning ? "red" - : props.item.editing - ? "#8800aa" + : props.item.editing && props.areMultipleItems + ? vscForeground : "transparent", borderWidth: "1px", borderStyle: "solid", diff --git a/extension/react-app/src/components/RingLoader.tsx b/extension/react-app/src/components/RingLoader.tsx new file mode 100644 index 00000000..5eb8a60f --- /dev/null +++ b/extension/react-app/src/components/RingLoader.tsx @@ -0,0 +1,39 @@ +import React from "react"; +import styled, { keyframes } from "styled-components"; +import { buttonColor, vscBackground, vscForeground } from "."; + +const rotate = keyframes` + 0% { + stroke-dashoffset: 100; + } + 100% { + stroke-dashoffset: 12; + } +`; + +const LoaderSvg = styled.svg` + transform: rotate(-90deg); + width: 40px; + height: 40px; + opacity: 50%; + + circle { + fill: none; + stroke: ${vscForeground}; + stroke-width: 2; + stroke-dasharray: 100; + stroke-dashoffset: 0; + animation: ${rotate} 6s ease-out infinite; + stroke-linecap: round; + } +`; + +const RingLoader = () => ( + <div className="m-auto w-full text-center"> + <LoaderSvg viewBox="0 0 32 32"> + <circle cx="16" cy="16" r="14" /> + </LoaderSvg> + </div> +); + +export default RingLoader; diff --git a/extension/react-app/src/components/StepContainer.tsx b/extension/react-app/src/components/StepContainer.tsx index 19cdd2e1..1f999892 100644 --- a/extension/react-app/src/components/StepContainer.tsx +++ b/extension/react-app/src/components/StepContainer.tsx @@ -63,6 +63,14 @@ const HeaderDiv = styled.div<{ error: boolean; loading: boolean }>` padding-right: 8px; `; +const LeftHeaderSubDiv = styled.div` + margin: 8px; + display: grid; + grid-template-columns: auto 1fr; + align-items: center; + grid-gap: 2px; +`; + const ContentDiv = styled.div<{ isUserInput: boolean }>` padding: 8px; background-color: ${(props) => @@ -167,16 +175,16 @@ function StepContainer(props: StepContainerProps) { loading={(props.historyNode.active as boolean) || false} error={props.historyNode.observation?.error ? true : false} > - <div className="m-2 flex items-center"> + <LeftHeaderSubDiv> {!isUserInput && (props.open ? ( - <ChevronDownIcon width="1.5em" height="1.5em" /> + <ChevronDownIcon width="1.4em" height="1.4em" /> ) : ( - <ChevronRightIcon width="1.5em" height="1.5em" /> + <ChevronRightIcon width="1.4em" height="1.4em" /> ))} {props.historyNode.observation?.title || (props.historyNode.step.name as any)} - </div> + </LeftHeaderSubDiv> {/* <HeaderButton onClick={(e) => { e.stopPropagation(); @@ -195,7 +203,7 @@ function StepContainer(props: StepContainerProps) { client?.showLogsAtIndex(props.index); }} > - <MagnifyingGlassIcon width="1.5em" height="1.5em" /> + <MagnifyingGlassIcon width="1.4em" height="1.4em" /> </HeaderButtonWithText> )} <HeaderButtonWithText @@ -211,14 +219,14 @@ function StepContainer(props: StepContainerProps) { > {props.historyNode.active ? ( <StopCircleIcon - width="1.5em" - height="1.5em" + width="1.4em" + height="1.4em" onClick={props.onDelete} /> ) : ( <XMarkIcon - width="1.5em" - height="1.5em" + width="1.4em" + height="1.4em" onClick={props.onDelete} /> )} @@ -232,8 +240,8 @@ function StepContainer(props: StepContainerProps) { }} > <ArrowPathIcon - width="1.5em" - height="1.5em" + width="1.4em" + height="1.4em" onClick={props.onRetry} /> </HeaderButtonWithText> diff --git a/extension/react-app/src/components/UserInputContainer.tsx b/extension/react-app/src/components/UserInputContainer.tsx index 25f836de..7e964ad9 100644 --- a/extension/react-app/src/components/UserInputContainer.tsx +++ b/extension/react-app/src/components/UserInputContainer.tsx @@ -21,6 +21,8 @@ const StyledDiv = styled.div` align-items: center; border-bottom: 1px solid ${vscBackground}; padding: 8px; + padding-top: 4px; + padding-bottom: 4px; `; const DeleteButtonDiv = styled.div` @@ -35,7 +37,7 @@ const UserInputContainer = (props: UserInputContainerProps) => { <StyledMarkdownPreview light={true} source={props.children} - className="mr-5" + className="mr-6" /> {/* <ReactMarkdown children={props.children} className="w-fit mr-10" /> */} <DeleteButtonDiv> @@ -46,7 +48,7 @@ const UserInputContainer = (props: UserInputContainerProps) => { }} text="Delete" > - <XMarkIcon width="1.5em" height="1.5em" /> + <XMarkIcon width="1.4em" height="1.4em" /> </HeaderButtonWithText> </DeleteButtonDiv> </StyledDiv> diff --git a/extension/react-app/src/hooks/useWebsocket.ts b/extension/react-app/src/hooks/useWebsocket.ts index 6b36be97..be34861b 100644 --- a/extension/react-app/src/hooks/useWebsocket.ts +++ b/extension/react-app/src/hooks/useWebsocket.ts @@ -25,8 +25,11 @@ function useContinueGUIProtocol(useVscodeMessagePassing: boolean = true) { "/gui/ws?session_id=" + encodeURIComponent(sessionId); - console.log("Creating websocket", serverUrlWithSessionId); - console.log("Using vscode message passing", useVscodeMessagePassing); + console.log( + "Creating GUI websocket", + serverUrlWithSessionId, + useVscodeMessagePassing + ); const newClient = new ContinueGUIClientProtocol( serverUrlWithSessionId, useVscodeMessagePassing diff --git a/extension/react-app/src/pages/gui.tsx b/extension/react-app/src/pages/gui.tsx index 3ae8e14e..ed73ce85 100644 --- a/extension/react-app/src/pages/gui.tsx +++ b/extension/react-app/src/pages/gui.tsx @@ -1,7 +1,7 @@ import styled from "styled-components"; import { defaultBorderRadius, - vscBackground, + secondaryDark, vscForeground, } from "../components"; import Loader from "../components/Loader"; @@ -32,11 +32,30 @@ import { setBottomMessage, setBottomMessageCloseTimeout, } from "../redux/slices/uiStateSlice"; +import RingLoader from "../components/RingLoader"; const TopGUIDiv = styled.div` overflow: hidden; `; +const BottomMessageDiv = styled.div<{ displayOnBottom: boolean }>` + position: fixed; + bottom: ${(props) => (props.displayOnBottom ? "50px" : undefined)}; + top: ${(props) => (props.displayOnBottom ? undefined : "50px")}; + left: 0; + right: 0; + margin: 8px; + margin-top: 0; + background-color: ${secondaryDark}; + color: ${vscForeground}; + border-radius: ${defaultBorderRadius}; + padding: 12px; + z-index: 100; + box-shadow: 0px 0px 2px 0px ${vscForeground}; + max-height: 50vh; + overflow: scroll; +`; + const UserInputQueueItem = styled.div` border-radius: ${defaultBorderRadius}; color: gray; @@ -384,11 +403,31 @@ function GUI(props: GUIProps) { > {typeof client === "undefined" && ( <> - <Loader /> - <p style={{ textAlign: "center" }}>Loading Continue server...</p> - {/* <p style={{ textAlign: "center" }}> - Make sure you have a folder opened in VS Code - </p> */} + <RingLoader /> + <p + style={{ + textAlign: "center", + margin: "0px", + fontSize: "14px", + }} + > + Continue Server Starting + </p> + <p + style={{ + margin: "auto", + textAlign: "center", + marginTop: "4px", + fontSize: "12px", + cursor: "pointer", + opacity: 0.7, + }} + onClick={() => { + postVscMessage("toggleDevTools", {}); + }} + > + <u>Click to view logs</u> + </p> </> )} {history?.timeline.map((node: HistoryNode, index: number) => { @@ -463,7 +502,8 @@ function GUI(props: GUIProps) { /> <ContinueButton onClick={onMainTextInput} /> </TopGUIDiv> - <div + <BottomMessageDiv + displayOnBottom={displayBottomMessageOnBottom} onMouseEnter={() => { dispatch(setBottomMessageCloseTimeout(undefined)); }} @@ -472,27 +512,10 @@ function GUI(props: GUIProps) { dispatch(setBottomMessage(undefined)); } }} - style={{ - position: "fixed", - bottom: displayBottomMessageOnBottom ? "50px" : undefined, - top: displayBottomMessageOnBottom ? undefined : "50px", - left: "0", - right: "0", - margin: "8px", - marginTop: "0px", - backgroundColor: vscBackground, - color: vscForeground, - borderRadius: defaultBorderRadius, - padding: "12px", - zIndex: 100, - boxShadow: `0px 0px 4px 0px ${vscForeground}`, - maxHeight: "50vh", - overflow: "scroll", - }} hidden={!bottomMessage} > {bottomMessage} - </div> + </BottomMessageDiv> <Footer dataSwitchChecked={dataSwitchChecked}> {vscMediaUrl && ( <a @@ -536,14 +559,14 @@ If you already have an LLM deployed on your own infrastructure, or would like to }} text="Clear" > - <TrashIcon width="1.5em" height="1.5em" /> + <TrashIcon width="1.4em" height="1.4em" /> </HeaderButtonWithText> <a href="https://continue.dev/docs/how-to-use-continue" className="no-underline" > <HeaderButtonWithText text="Docs"> - <BookOpenIcon width="1.5em" height="1.5em" /> + <BookOpenIcon width="1.4em" height="1.4em" /> </HeaderButtonWithText> </a> <HeaderButtonWithText @@ -557,7 +580,7 @@ If you already have an LLM deployed on your own infrastructure, or would like to }} text="Feedback" > - <ChatBubbleOvalLeftEllipsisIcon width="1.5em" height="1.5em" /> + <ChatBubbleOvalLeftEllipsisIcon width="1.4em" height="1.4em" /> </HeaderButtonWithText> </Footer> </> diff --git a/extension/src/activation/environmentSetup.ts b/extension/src/activation/environmentSetup.ts index 10a9f75f..db215e11 100644 --- a/extension/src/activation/environmentSetup.ts +++ b/extension/src/activation/environmentSetup.ts @@ -82,18 +82,18 @@ export function getExtensionVersion() { // Returns whether a server of the current version is already running async function checkOrKillRunningServer(serverUrl: string): Promise<boolean> { - console.log("Checking if server is old version"); const serverRunning = await checkServerRunning(serverUrl); // Kill the server if it is running an old version if (fs.existsSync(serverVersionPath())) { const serverVersion = fs.readFileSync(serverVersionPath(), "utf8"); if (serverVersion === getExtensionVersion() && serverRunning) { // The current version is already up and running, no need to continue + console.log("Continue server already running"); return true; } } if (serverRunning) { - console.log("Killing old server..."); + console.log("Killing server from old version of Continue"); try { await fkill(":65432"); } catch (e: any) { @@ -196,16 +196,10 @@ export async function startContinuePythonServer() { // Get name of the corresponding executable for platform if (os.platform() === "darwin") { // Add necessary permissions - console.log("Setting permissions for Continue server..."); fs.chmodSync(destination, 0o7_5_5); - const [stdout1, stderr1] = await runCommand( - `xattr -dr com.apple.quarantine ${destination}` - ); - console.log("stdout: ", stdout1); - console.log("stderr: ", stderr1); + await runCommand(`xattr -dr com.apple.quarantine ${destination}`); } else if (os.platform() === "linux") { // Add necessary permissions - console.log("Setting permissions for Continue server..."); fs.chmodSync(destination, 0o7_5_5); } @@ -217,25 +211,12 @@ export async function startContinuePythonServer() { } // Run the executable - console.log("Starting Continue server..."); + console.log("Starting Continue server"); const child = spawn(destination, { - shell: true, - }); - child.stderr.on("data", (data: any) => { - console.log(data.toString()); - }); - - child.on("error", (error: any) => { - console.log(`error: ${error.message}`); - }); - - child.on("close", (code: any) => { - console.log(`child process exited with code ${code}`); - }); - - child.stdout.on("data", (data: any) => { - console.log(`stdout: ${data.toString()}`); + detached: true, + stdio: "ignore", }); + child.unref(); // Write the current version of vscode extension to a file called server_version.txt fs.writeFileSync(serverVersionPath(), getExtensionVersion()); diff --git a/extension/src/continueIdeClient.ts b/extension/src/continueIdeClient.ts index 1fa41383..cb7baaa6 100644 --- a/extension/src/continueIdeClient.ts +++ b/extension/src/continueIdeClient.ts @@ -413,7 +413,7 @@ class IdeProtocolClient { clearInterval(interval); resolve(null); } else { - console.log("Websocket not yet open, trying again..."); + // console.log("Websocket not yet open, trying again..."); } }, 1000); }); diff --git a/extension/src/debugPanel.ts b/extension/src/debugPanel.ts index 66d22e24..d1fe565f 100644 --- a/extension/src/debugPanel.ts +++ b/extension/src/debugPanel.ts @@ -181,13 +181,11 @@ export function setupDebugPanel( switch (data.type) { case "onLoad": { let sessionId: string; - console.log("Waiting for session id"); if (typeof sessionIdPromise === "string") { sessionId = sessionIdPromise; } else { sessionId = await sessionIdPromise; } - console.log("Done with onLoad: ", sessionId); panel.webview.postMessage({ type: "onLoad", vscMachineId: vscode.env.machineId, @@ -240,10 +238,22 @@ export function setupDebugPanel( openEditorAndRevealRange(data.path, undefined, vscode.ViewColumn.One); break; } + case "toggleDevTools": { + vscode.commands.executeCommand("workbench.action.toggleDevTools"); + vscode.commands.executeCommand("continue.viewLogs"); + break; + } case "blurContinueInput": { setFocusedOnContinueInput(false); break; } + case "focusEditor": { + setFocusedOnContinueInput(false); + vscode.commands.executeCommand( + "workbench.action.focusActiveEditorGroup" + ); + break; + } case "withProgress": { // This message allows withProgress to be used in the webview if (data.done) { diff --git a/extension/src/util/messenger.ts b/extension/src/util/messenger.ts index 3044898e..bcc88fe1 100644 --- a/extension/src/util/messenger.ts +++ b/extension/src/util/messenger.ts @@ -1,4 +1,3 @@ -console.log("Websocket import"); const WebSocket = require("ws"); import fetch from "node-fetch"; |