From 792b65745b89bb59802294357378113493d25b63 Mon Sep 17 00:00:00 2001
From: Nate Sesti <sestinj@gmail.com>
Date: Mon, 12 Jun 2023 10:50:33 -0700
Subject: calculate diff and highlight changes

---
 .../react-app/src/components/StepContainer.tsx     | 23 +++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

(limited to 'extension/react-app/src/components/StepContainer.tsx')

diff --git a/extension/react-app/src/components/StepContainer.tsx b/extension/react-app/src/components/StepContainer.tsx
index 8ea54325..fb0143b5 100644
--- a/extension/react-app/src/components/StepContainer.tsx
+++ b/extension/react-app/src/components/StepContainer.tsx
@@ -84,6 +84,15 @@ const OnHoverDiv = styled.div`
   animation: ${appear} 0.3s ease-in-out;
 `;
 
+const MarkdownPre = styled.pre`
+  background-color: ${secondaryDark};
+  padding: 10px;
+  border-radius: ${defaultBorderRadius};
+  border: 0.5px solid white;
+`;
+
+const MarkdownCode = styled.code``;
+
 function StepContainer(props: StepContainerProps) {
   const [open, setOpen] = useState(
     typeof props.open === "undefined" ? true : props.open
@@ -182,7 +191,19 @@ function StepContainer(props: StepContainerProps) {
               {props.historyNode.observation.error as string}
             </pre>
           ) : (
-            <ReactMarkdown key={1} className="overflow-scroll">
+            <ReactMarkdown
+              key={1}
+              className="overflow-scroll"
+              components={{
+                pre: ({ node, ...props }) => {
+                  return (
+                    <CodeBlock
+                      children={props.children[0] as string}
+                    ></CodeBlock>
+                  );
+                },
+              }}
+            >
               {props.historyNode.step.description as any}
             </ReactMarkdown>
           )}
-- 
cgit v1.2.3-70-g09d2


From a13cb867ec0ea831d78e6d928463bd256babced5 Mon Sep 17 00:00:00 2001
From: Nate Sesti <sestinj@gmail.com>
Date: Mon, 12 Jun 2023 13:18:16 -0700
Subject: clear history and delete step buttons

---
 continuedev/src/continuedev/core/autopilot.py      |  10 +
 .../src/continuedev/libs/util/calculate_diff.py    |  14 ++
 continuedev/src/continuedev/server/gui.py          |  10 +
 continuedev/src/continuedev/server/gui_protocol.py |   8 +
 continuedev/src/continuedev/steps/core/core.py     |   2 +-
 .../react-app/src/components/StepContainer.tsx     |  44 ++--
 extension/react-app/src/components/index.ts        |  18 ++
 .../src/hooks/ContinueGUIClientProtocol.ts         |   6 +
 .../react-app/src/hooks/useContinueGUIProtocol.ts  |   8 +
 extension/react-app/src/tabs/gui.tsx               | 272 +++++++++++----------
 10 files changed, 245 insertions(+), 147 deletions(-)

(limited to 'extension/react-app/src/components/StepContainer.tsx')

diff --git a/continuedev/src/continuedev/core/autopilot.py b/continuedev/src/continuedev/core/autopilot.py
index c979d53a..1642003c 100644
--- a/continuedev/src/continuedev/core/autopilot.py
+++ b/continuedev/src/continuedev/core/autopilot.py
@@ -40,6 +40,12 @@ class Autopilot(ContinueBaseModel):
     def get_full_state(self) -> FullState:
         return FullState(history=self.history, active=self._active, user_input_queue=self._main_user_input_queue)
 
+    async def clear_history(self):
+        self.history = History.from_empty()
+        self._main_user_input_queue = []
+        self._active = False
+        await self.update_subscribers()
+
     def on_update(self, callback: Coroutine["FullState", None, None]):
         """Subscribe to changes to state"""
         self._on_update_callbacks.append(callback)
@@ -88,6 +94,10 @@ class Autopilot(ContinueBaseModel):
     async def retry_at_index(self, index: int):
         self._retry_queue.post(str(index), None)
 
+    async def delete_at_index(self, index: int):
+        self.history.timeline[index].step.hide = True
+        await self.update_subscribers()
+
     async def _run_singular_step(self, step: "Step", is_future_step: bool = False) -> Coroutine[Observation, None, None]:
         capture_event(
             'step run', {'step_name': step.name, 'params': step.dict()})
diff --git a/continuedev/src/continuedev/libs/util/calculate_diff.py b/continuedev/src/continuedev/libs/util/calculate_diff.py
index d778891b..ff0a135f 100644
--- a/continuedev/src/continuedev/libs/util/calculate_diff.py
+++ b/continuedev/src/continuedev/libs/util/calculate_diff.py
@@ -67,6 +67,20 @@ def calculate_diff(filepath: str, original: str, updated: str) -> List[FileEdit]
 
 
 def calculate_diff2(filepath: str, original: str, updated: str) -> List[FileEdit]:
+    # original_lines = original.splitlines()
+    # updated_lines = updated.splitlines()
+    # offset = 0
+    # while len(original_lines) and len(updated_lines) and original_lines[0] == updated_lines[0]:
+    #     original_lines = original_lines[1:]
+    #     updated_lines = updated_lines[1:]
+
+    # while len(original_lines) and len(updated_lines) and original_lines[-1] == updated_lines[-1]:
+    #     original_lines = original_lines[:-1]
+    #     updated_lines = updated_lines[:-1]
+
+    # original = "\n".join(original_lines)
+    # updated = "\n".join(updated_lines)
+
     edits = []
     max_iterations = 1000
     i = 0
diff --git a/continuedev/src/continuedev/server/gui.py b/continuedev/src/continuedev/server/gui.py
index b873a88f..e8b52004 100644
--- a/continuedev/src/continuedev/server/gui.py
+++ b/continuedev/src/continuedev/server/gui.py
@@ -77,6 +77,10 @@ class GUIProtocolServer(AbstractGUIProtocolServer):
                 self.on_reverse_to_index(data["index"])
             elif message_type == "retry_at_index":
                 self.on_retry_at_index(data["index"])
+            elif message_type == "clear_history":
+                self.on_clear_history()
+            elif message_type == "delete_at_index":
+                self.on_delete_at_index(data["index"])
         except Exception as e:
             print(e)
 
@@ -106,6 +110,12 @@ class GUIProtocolServer(AbstractGUIProtocolServer):
         asyncio.create_task(
             self.session.autopilot.retry_at_index(index))
 
+    def on_clear_history(self):
+        asyncio.create_task(self.session.autopilot.clear_history())
+
+    def on_delete_at_index(self, index: int):
+        asyncio.create_task(self.session.autopilot.delete_at_index(index))
+
 
 @router.websocket("/ws")
 async def websocket_endpoint(websocket: WebSocket, session: Session = Depends(websocket_session)):
diff --git a/continuedev/src/continuedev/server/gui_protocol.py b/continuedev/src/continuedev/server/gui_protocol.py
index 287f9e3b..889c6761 100644
--- a/continuedev/src/continuedev/server/gui_protocol.py
+++ b/continuedev/src/continuedev/server/gui_protocol.py
@@ -30,3 +30,11 @@ class AbstractGUIProtocolServer(ABC):
     @abstractmethod
     def on_retry_at_index(self, index: int):
         """Called when the user requests a retry at a previous index"""
+
+    @abstractmethod
+    def on_clear_history(self):
+        """Called when the user requests to clear the history"""
+
+    @abstractmethod
+    def on_delete_at_index(self, index: int):
+        """Called when the user requests to delete a step at a given index"""
diff --git a/continuedev/src/continuedev/steps/core/core.py b/continuedev/src/continuedev/steps/core/core.py
index 4288ffd2..dacf0e7b 100644
--- a/continuedev/src/continuedev/steps/core/core.py
+++ b/continuedev/src/continuedev/steps/core/core.py
@@ -193,7 +193,7 @@ class Gpt35EditCodeStep(Step):
                 edit.range.end.line += rif.range.start.line
                 edit.range.end.character += rif.range.start.character if edit.range.end.line == 0 else 0
 
-                for line in range(edit.range.start.line, edit.range.end.line + 1):
+                for line in range(edit.range.start.line, edit.range.end.line + 1 + len(edit.replacement.splitlines()) - (edit.range.end.line - edit.range.start.line + 1)):
                     lines_to_highlight.add(line)
 
                 await sdk.ide.applyFileSystemEdit(edit)
diff --git a/extension/react-app/src/components/StepContainer.tsx b/extension/react-app/src/components/StepContainer.tsx
index fb0143b5..2d85b4f0 100644
--- a/extension/react-app/src/components/StepContainer.tsx
+++ b/extension/react-app/src/components/StepContainer.tsx
@@ -7,6 +7,7 @@ import {
   vscBackground,
   GradientBorder,
   vscBackgroundTransparent,
+  HeaderButton,
 } from ".";
 import { RangeInFile, FileEdit } from "../../../src/client";
 import CodeBlock from "./CodeBlock";
@@ -15,7 +16,7 @@ import SubContainer from "./SubContainer";
 import {
   ChevronDown,
   ChevronRight,
-  Backward,
+  XMark,
   ArrowPath,
 } from "@styled-icons/heroicons-outline";
 import { HistoryNode } from "../../../schema/HistoryNode";
@@ -31,6 +32,7 @@ interface StepContainerProps {
   onRefinement: (input: string) => void;
   onUserInput: (input: string) => void;
   onRetry: () => void;
+  onDelete: () => void;
   open?: boolean;
 }
 
@@ -54,8 +56,10 @@ const HeaderDiv = styled.div<{ error: boolean }>`
   background-color: ${(props) =>
     props.error ? "#522" : vscBackgroundTransparent};
   display: grid;
-  grid-template-columns: 1fr auto;
+  grid-template-columns: 1fr auto auto;
+  grid-gap: 8px;
   align-items: center;
+  padding-right: 8px;
 `;
 
 const ContentDiv = styled.div`
@@ -64,20 +68,6 @@ const ContentDiv = styled.div`
   background-color: ${vscBackground};
 `;
 
-const HeaderButton = styled.button`
-  background-color: transparent;
-  border: 1px solid white;
-  border-radius: ${defaultBorderRadius};
-  padding: 2px;
-  cursor: pointer;
-  color: white;
-
-  &:hover {
-    background-color: white;
-    color: black;
-  }
-`;
-
 const OnHoverDiv = styled.div`
   text-align: center;
   padding: 10px;
@@ -161,18 +151,28 @@ function StepContainer(props: StepContainerProps) {
               <Backward size="1.6em" onClick={props.onReverse}></Backward>
             </HeaderButton> */}
 
-            {props.historyNode.observation?.error ? (
+            <>
               <HeaderButton
                 onClick={(e) => {
                   e.stopPropagation();
-                  props.onRetry();
+                  props.onDelete();
                 }}
               >
-                <ArrowPath size="1.6em" onClick={props.onRetry}></ArrowPath>
+                <XMark size="1.6em" onClick={props.onDelete} />
               </HeaderButton>
-            ) : (
-              <></>
-            )}
+              {props.historyNode.observation?.error ? (
+                <HeaderButton
+                  onClick={(e) => {
+                    e.stopPropagation();
+                    props.onRetry();
+                  }}
+                >
+                  <ArrowPath size="1.6em" onClick={props.onRetry} />
+                </HeaderButton>
+              ) : (
+                <></>
+              )}
+            </>
           </HeaderDiv>
         </GradientBorder>
         <ContentDiv hidden={!open}>
diff --git a/extension/react-app/src/components/index.ts b/extension/react-app/src/components/index.ts
index 4966f3e8..525989af 100644
--- a/extension/react-app/src/components/index.ts
+++ b/extension/react-app/src/components/index.ts
@@ -143,3 +143,21 @@ export const appear = keyframes`
         transform: translateY(0px);
     }
 `;
+
+export const HeaderButton = styled.button`
+  background-color: transparent;
+  border: 1px solid white;
+  border-radius: ${defaultBorderRadius};
+  cursor: pointer;
+  color: white;
+
+  &:hover {
+    background-color: white;
+    color: black;
+  }
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  gap: 4px;
+  padding: 1px;
+`;
diff --git a/extension/react-app/src/hooks/ContinueGUIClientProtocol.ts b/extension/react-app/src/hooks/ContinueGUIClientProtocol.ts
index 18a91de7..71303c70 100644
--- a/extension/react-app/src/hooks/ContinueGUIClientProtocol.ts
+++ b/extension/react-app/src/hooks/ContinueGUIClientProtocol.ts
@@ -8,6 +8,12 @@ abstract class AbstractContinueGUIClientProtocol {
   abstract sendStepUserInput(input: string, index: number): void;
 
   abstract onStateUpdate(state: any): void;
+
+  abstract sendClear(): void;
+
+  abstract retryAtIndex(index: number): void;
+
+  abstract deleteAtIndex(index: number): void;
 }
 
 export default AbstractContinueGUIClientProtocol;
diff --git a/extension/react-app/src/hooks/useContinueGUIProtocol.ts b/extension/react-app/src/hooks/useContinueGUIProtocol.ts
index f27895fb..a8e28fc5 100644
--- a/extension/react-app/src/hooks/useContinueGUIProtocol.ts
+++ b/extension/react-app/src/hooks/useContinueGUIProtocol.ts
@@ -45,9 +45,17 @@ class ContinueGUIClientProtocol extends AbstractContinueGUIClientProtocol {
     });
   }
 
+  sendClear() {
+    this.messenger.send("clear_history", {});
+  }
+
   retryAtIndex(index: number) {
     this.messenger.send("retry_at_index", { index });
   }
+
+  deleteAtIndex(index: number) {
+    this.messenger.send("delete_at_index", { index });
+  }
 }
 
 export default ContinueGUIClientProtocol;
diff --git a/extension/react-app/src/tabs/gui.tsx b/extension/react-app/src/tabs/gui.tsx
index 9f7e651f..cb7a5440 100644
--- a/extension/react-app/src/tabs/gui.tsx
+++ b/extension/react-app/src/tabs/gui.tsx
@@ -4,6 +4,7 @@ import {
   vscBackground,
   Loader,
   MainTextInput,
+  HeaderButton,
 } from "../components";
 import ContinueButton from "../components/ContinueButton";
 import { useCallback, useEffect, useRef, useState } from "react";
@@ -11,7 +12,7 @@ import { History } from "../../../schema/History";
 import { HistoryNode } from "../../../schema/HistoryNode";
 import StepContainer from "../components/StepContainer";
 import useContinueGUIProtocol from "../hooks/useWebsocket";
-
+import { Trash } from "@styled-icons/heroicons-outline";
 let TopGUIDiv = styled.div`
   display: grid;
   grid-template-columns: 1fr;
@@ -26,6 +27,14 @@ let UserInputQueueItem = styled.div`
   text-align: center;
 `;
 
+const TopBar = styled.div`
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  padding: 8px;
+  align-items: center;
+`;
+
 interface GUIProps {
   firstObservation?: any;
 }
@@ -33,129 +42,128 @@ interface GUIProps {
 function GUI(props: GUIProps) {
   const [waitingForSteps, setWaitingForSteps] = useState(false);
   const [userInputQueue, setUserInputQueue] = useState<string[]>([]);
-  const [history, setHistory] = useState<History | undefined>();
-  //   {
-  //   timeline: [
-  //     {
-  //       step: {
-  //         name: "Waiting for user input",
-  //         cmd: "python3 /Users/natesesti/Desktop/continue/extension/examples/python/main.py",
-  //         description:
-  //           "Run `python3 /Users/natesesti/Desktop/continue/extension/examples/python/main.py` and ```\nprint(sum(first, second))\n```\n- Testing\n- Testing 2\n- Testing 3",
-  //       },
-  //       observation: {
-  //         title: "ERROR FOUND",
-  //         error:
-  //           "Traceback (most recent call last):\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/main.py\", line 7, in <module>\n    print(sum(first, second))\n          ^^^^^^^^^^^^^^^^^^\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/sum.py\", line 2, in sum\n    return a + b\n           ~~^~~\nTypeError: unsupported operand type(s) for +: 'int' and 'str'",
-  //       },
-  //       output: [
-  //         {
-  //           traceback: {
-  //             frames: [
-  //               {
-  //                 filepath:
-  //                   "/Users/natesesti/Desktop/continue/extension/examples/python/main.py",
-  //                 lineno: 7,
-  //                 function: "<module>",
-  //                 code: "print(sum(first, second))",
-  //               },
-  //             ],
-  //             message: "unsupported operand type(s) for +: 'int' and 'str'",
-  //             error_type:
-  //               '          ^^^^^^^^^^^^^^^^^^\n  File "/Users/natesesti/Desktop/continue/extension/examples/python/sum.py", line 2, in sum\n    return a + b\n           ~~^~~\nTypeError',
-  //             full_traceback:
-  //               "Traceback (most recent call last):\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/main.py\", line 7, in <module>\n    print(sum(first, second))\n          ^^^^^^^^^^^^^^^^^^\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/sum.py\", line 2, in sum\n    return a + b\n           ~~^~~\nTypeError: unsupported operand type(s) for +: 'int' and 'str'",
-  //           },
-  //         },
-  //         null,
-  //       ],
-  //     },
-  //     {
-  //       step: {
-  //         name: "EditCodeStep",
-  //         range_in_files: [
-  //           {
-  //             filepath:
-  //               "/Users/natesesti/Desktop/continue/extension/examples/python/main.py",
-  //             range: {
-  //               start: {
-  //                 line: 0,
-  //                 character: 0,
-  //               },
-  //               end: {
-  //                 line: 6,
-  //                 character: 25,
-  //               },
-  //             },
-  //           },
-  //         ],
-  //         prompt:
-  //           "I ran into this problem with my Python code:\n\n                Traceback (most recent call last):\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/main.py\", line 7, in <module>\n    print(sum(first, second))\n          ^^^^^^^^^^^^^^^^^^\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/sum.py\", line 2, in sum\n    return a + b\n           ~~^~~\nTypeError: unsupported operand type(s) for +: 'int' and 'str'\n\n                Below are the files that might need to be fixed:\n\n                {code}\n\n                This is what the code should be in order to avoid the problem:\n",
-  //         description:
-  //           "Run `python3 /Users/natesesti/Desktop/continue/extension/examples/python/main.py` and\n```python\nprint(sum(first, second))\n```\n- Testing\n- Testing 2\n- Testing 3",
-  //       },
-  //       output: [
-  //         null,
-  //         {
-  //           reversible: true,
-  //           actions: [
-  //             {
-  //               reversible: true,
-  //               filesystem: {},
-  //               filepath:
-  //                 "/Users/natesesti/Desktop/continue/extension/examples/python/main.py",
-  //               range: {
-  //                 start: {
-  //                   line: 0,
-  //                   character: 0,
-  //                 },
-  //                 end: {
-  //                   line: 6,
-  //                   character: 25,
-  //                 },
-  //               },
-  //               replacement:
-  //                 "\nfrom sum import sum\n\nfirst = 1\nsecond = 2\n\nprint(sum(first, second))",
-  //             },
-  //           ],
-  //         },
-  //       ],
-  //     },
-  //     {
-  //       step: {
-  //         name: "SolveTracebackStep",
-  //         traceback: {
-  //           frames: [
-  //             {
-  //               filepath:
-  //                 "/Users/natesesti/Desktop/continue/extension/examples/python/main.py",
-  //               lineno: 7,
-  //               function: "<module>",
-  //               code: "print(sum(first, second))",
-  //             },
-  //           ],
-  //           message: "unsupported operand type(s) for +: 'int' and 'str'",
-  //           error_type:
-  //             '          ^^^^^^^^^^^^^^^^^^\n  File "/Users/natesesti/Desktop/continue/extension/examples/python/sum.py", line 2, in sum\n    return a + b\n           ~~^~~\nTypeError',
-  //           full_traceback:
-  //             "Traceback (most recent call last):\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/main.py\", line 7, in <module>\n    print(sum(first, second))\n          ^^^^^^^^^^^^^^^^^^\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/sum.py\", line 2, in sum\n    return a + b\n           ~~^~~\nTypeError: unsupported operand type(s) for +: 'int' and 'str'",
-  //         },
-  //         description: "Running step: SolveTracebackStep",
-  //       },
-  //       output: [null, null],
-  //     },
-  //     {
-  //       step: {
-  //         name: "RunCodeStep",
-  //         cmd: "python3 /Users/natesesti/Desktop/continue/extension/examples/python/main.py",
-  //         description:
-  //           "Run `python3 /Users/natesesti/Desktop/continue/extension/examples/python/main.py`",
-  //       },
-  //       output: [null, null],
-  //     },
-  //   ],
-  //   current_index: 3,
-  // } as any);
+  const [history, setHistory] = useState<History | undefined>({
+    timeline: [
+      {
+        step: {
+          name: "Waiting for user input",
+          cmd: "python3 /Users/natesesti/Desktop/continue/extension/examples/python/main.py",
+          description:
+            "Run `python3 /Users/natesesti/Desktop/continue/extension/examples/python/main.py` and ```\nprint(sum(first, second))\n```\n- Testing\n- Testing 2\n- Testing 3",
+        },
+        observation: {
+          title: "ERROR FOUND",
+          error:
+            "Traceback (most recent call last):\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/main.py\", line 7, in <module>\n    print(sum(first, second))\n          ^^^^^^^^^^^^^^^^^^\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/sum.py\", line 2, in sum\n    return a + b\n           ~~^~~\nTypeError: unsupported operand type(s) for +: 'int' and 'str'",
+        },
+        output: [
+          {
+            traceback: {
+              frames: [
+                {
+                  filepath:
+                    "/Users/natesesti/Desktop/continue/extension/examples/python/main.py",
+                  lineno: 7,
+                  function: "<module>",
+                  code: "print(sum(first, second))",
+                },
+              ],
+              message: "unsupported operand type(s) for +: 'int' and 'str'",
+              error_type:
+                '          ^^^^^^^^^^^^^^^^^^\n  File "/Users/natesesti/Desktop/continue/extension/examples/python/sum.py", line 2, in sum\n    return a + b\n           ~~^~~\nTypeError',
+              full_traceback:
+                "Traceback (most recent call last):\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/main.py\", line 7, in <module>\n    print(sum(first, second))\n          ^^^^^^^^^^^^^^^^^^\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/sum.py\", line 2, in sum\n    return a + b\n           ~~^~~\nTypeError: unsupported operand type(s) for +: 'int' and 'str'",
+            },
+          },
+          null,
+        ],
+      },
+      {
+        step: {
+          name: "EditCodeStep",
+          range_in_files: [
+            {
+              filepath:
+                "/Users/natesesti/Desktop/continue/extension/examples/python/main.py",
+              range: {
+                start: {
+                  line: 0,
+                  character: 0,
+                },
+                end: {
+                  line: 6,
+                  character: 25,
+                },
+              },
+            },
+          ],
+          prompt:
+            "I ran into this problem with my Python code:\n\n                Traceback (most recent call last):\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/main.py\", line 7, in <module>\n    print(sum(first, second))\n          ^^^^^^^^^^^^^^^^^^\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/sum.py\", line 2, in sum\n    return a + b\n           ~~^~~\nTypeError: unsupported operand type(s) for +: 'int' and 'str'\n\n                Below are the files that might need to be fixed:\n\n                {code}\n\n                This is what the code should be in order to avoid the problem:\n",
+          description:
+            "Run `python3 /Users/natesesti/Desktop/continue/extension/examples/python/main.py` and\n```python\nprint(sum(first, second))\n```\n- Testing\n- Testing 2\n- Testing 3",
+        },
+        output: [
+          null,
+          {
+            reversible: true,
+            actions: [
+              {
+                reversible: true,
+                filesystem: {},
+                filepath:
+                  "/Users/natesesti/Desktop/continue/extension/examples/python/main.py",
+                range: {
+                  start: {
+                    line: 0,
+                    character: 0,
+                  },
+                  end: {
+                    line: 6,
+                    character: 25,
+                  },
+                },
+                replacement:
+                  "\nfrom sum import sum\n\nfirst = 1\nsecond = 2\n\nprint(sum(first, second))",
+              },
+            ],
+          },
+        ],
+      },
+      {
+        step: {
+          name: "SolveTracebackStep",
+          traceback: {
+            frames: [
+              {
+                filepath:
+                  "/Users/natesesti/Desktop/continue/extension/examples/python/main.py",
+                lineno: 7,
+                function: "<module>",
+                code: "print(sum(first, second))",
+              },
+            ],
+            message: "unsupported operand type(s) for +: 'int' and 'str'",
+            error_type:
+              '          ^^^^^^^^^^^^^^^^^^\n  File "/Users/natesesti/Desktop/continue/extension/examples/python/sum.py", line 2, in sum\n    return a + b\n           ~~^~~\nTypeError',
+            full_traceback:
+              "Traceback (most recent call last):\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/main.py\", line 7, in <module>\n    print(sum(first, second))\n          ^^^^^^^^^^^^^^^^^^\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/sum.py\", line 2, in sum\n    return a + b\n           ~~^~~\nTypeError: unsupported operand type(s) for +: 'int' and 'str'",
+          },
+          description: "Running step: SolveTracebackStep",
+        },
+        output: [null, null],
+      },
+      {
+        step: {
+          name: "RunCodeStep",
+          cmd: "python3 /Users/natesesti/Desktop/continue/extension/examples/python/main.py",
+          description:
+            "Run `python3 /Users/natesesti/Desktop/continue/extension/examples/python/main.py`",
+        },
+        output: [null, null],
+      },
+    ],
+    current_index: 3,
+  } as any);
 
   const topGuiDivRef = useRef<HTMLDivElement>(null);
   const client = useContinueGUIProtocol();
@@ -261,6 +269,19 @@ function GUI(props: GUIProps) {
         }
       }}
     >
+      <TopBar>
+        <h3>Continue</h3>
+        <HeaderButton style={{ padding: "3px" }}>
+          Clear History
+          <Trash
+            size="1.6em"
+            onClick={() => {
+              client?.sendClear();
+            }}
+          />
+        </HeaderButton>
+      </TopBar>
+
       {typeof client === "undefined" && (
         <>
           <Loader></Loader>
@@ -288,6 +309,9 @@ function GUI(props: GUIProps) {
               client?.retryAtIndex(index);
               setWaitingForSteps(true);
             }}
+            onDelete={() => {
+              client?.deleteAtIndex(index);
+            }}
           />
         );
       })}
-- 
cgit v1.2.3-70-g09d2

