summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--continuedev/src/continuedev/core/autopilot.py56
-rw-r--r--continuedev/src/continuedev/core/main.py47
-rw-r--r--continuedev/src/continuedev/core/observation.py1
-rw-r--r--continuedev/src/continuedev/core/policy.py8
-rw-r--r--continuedev/src/continuedev/core/sdk.py29
-rw-r--r--continuedev/src/continuedev/recipes/CreatePipelineRecipe/main.py11
-rw-r--r--continuedev/src/continuedev/recipes/CreatePipelineRecipe/steps.py110
-rw-r--r--continuedev/src/continuedev/server/ide.py15
-rw-r--r--continuedev/src/continuedev/server/ide_protocol.py8
-rw-r--r--continuedev/src/continuedev/steps/core/core.py129
-rw-r--r--continuedev/src/continuedev/steps/main.py17
-rw-r--r--extension/esbuild.mjs14
-rw-r--r--extension/package-lock.json1136
-rw-r--r--extension/package.json11
-rw-r--r--extension/react-app/src/components/ContinueButton.tsx8
-rw-r--r--extension/react-app/src/components/DebugPanel.tsx15
-rw-r--r--extension/react-app/src/components/InputAndButton.tsx77
-rw-r--r--extension/react-app/src/components/StepContainer.tsx94
-rw-r--r--extension/react-app/src/components/ToggleErrorDiv.tsx41
-rw-r--r--extension/react-app/src/components/index.ts19
-rw-r--r--extension/react-app/src/tabs/chat/MessageDiv.tsx1
-rw-r--r--extension/react-app/src/tabs/gui.tsx91
-rw-r--r--extension/scripts/continuedev-0.1.1-py3-none-any.whlbin0 -> 59915 bytes
-rw-r--r--extension/src/activation/environmentSetup.ts11
-rw-r--r--extension/src/continueIdeClient.ts44
-rw-r--r--extension/src/terminal/terminalEmulator.ts302
26 files changed, 805 insertions, 1490 deletions
diff --git a/continuedev/src/continuedev/core/autopilot.py b/continuedev/src/continuedev/core/autopilot.py
index db06c975..5a6bd2e7 100644
--- a/continuedev/src/continuedev/core/autopilot.py
+++ b/continuedev/src/continuedev/core/autopilot.py
@@ -1,13 +1,13 @@
import traceback
import time
-from typing import Callable, Coroutine, List
+from typing import Any, Callable, Coroutine, Dict, List
from ..models.filesystem_edit import FileEditWithFullContents
from ..libs.llm import LLM
from .observation import Observation, InternalErrorObservation
from ..server.ide_protocol import AbstractIdeProtocolServer
from ..libs.util.queue import AsyncSubscriptionQueue
from ..models.main import ContinueBaseModel
-from .main import Policy, History, FullState, Step, HistoryNode
+from .main import Context, ContinueCustomException, Policy, History, FullState, Step, HistoryNode
from ..steps.core.core import ReversibleStep, ManualEditStep, UserInputStep
from ..libs.util.telemetry import capture_event
from .sdk import ContinueSDK
@@ -18,6 +18,7 @@ class Autopilot(ContinueBaseModel):
policy: Policy
ide: AbstractIdeProtocolServer
history: History = History.from_empty()
+ context: Context = Context()
_on_update_callbacks: List[Callable[[FullState], None]] = []
_active: bool = False
@@ -26,6 +27,10 @@ class Autopilot(ContinueBaseModel):
_user_input_queue = AsyncSubscriptionQueue()
+ @property
+ def continue_sdk(self) -> ContinueSDK:
+ return ContinueSDK(self)
+
class Config:
arbitrary_types_allowed = True
@@ -60,7 +65,7 @@ class Autopilot(ContinueBaseModel):
current_step = self.history.get_current().step
self.history.step_back()
if issubclass(current_step.__class__, ReversibleStep):
- await current_step.reverse(ContinueSDK(self))
+ await current_step.reverse(self.continue_sdk)
await self.update_subscribers()
except Exception as e:
@@ -78,9 +83,9 @@ class Autopilot(ContinueBaseModel):
_step_depth: int = 0
async def retry_at_index(self, index: int):
- last_step = self.history.pop_last_step()
+ step = self.history.timeline[index].step.copy()
await self.update_subscribers()
- await self._run_singular_step(last_step)
+ await self._run_singular_step(step)
async def _run_singular_step(self, step: "Step", is_future_step: bool = False) -> Coroutine[Observation, None, None]:
capture_event(
@@ -105,7 +110,26 @@ class Autopilot(ContinueBaseModel):
self._step_depth += 1
try:
- observation = await step(ContinueSDK(self))
+ observation = await step(self.continue_sdk)
+ except ContinueCustomException as e:
+ # Attach an InternalErrorObservation to the step and unhide it.
+ error_string = e.message
+ print(
+ f"\n{error_string}\n{e}")
+
+ observation = InternalErrorObservation(
+ error=error_string, title=e.title)
+
+ # Reveal this step, but hide all of the following steps (its substeps)
+ step.hide = False
+ i = self.history.get_current_index()
+ while self.history.timeline[i].step.name != step.name:
+ self.history.timeline[i].step.hide = True
+ i -= 1
+
+ if e.with_step is not None:
+ await self._run_singular_step(e.with_step)
+
except Exception as e:
# Attach an InternalErrorObservation to the step and unhide it.
error_string = '\n\n'.join(
@@ -114,8 +138,14 @@ class Autopilot(ContinueBaseModel):
f"Error while running step: \n{error_string}\n{e}")
observation = InternalErrorObservation(
- error=error_string)
+ error=error_string, title=e.__repr__())
+
+ # Reveal this step, but hide all of the following steps (its substeps)
step.hide = False
+ i = self.history.get_current_index()
+ while self.history.timeline[i].step.name != step.name:
+ self.history.timeline[i].step.hide = True
+ i -= 1
self._step_depth -= 1
@@ -125,11 +155,13 @@ class Autopilot(ContinueBaseModel):
await self.update_subscribers()
# Update its description
- async def update_description():
- step._set_description(await step.describe(ContinueSDK(self).models))
- # Update subscribers with new description
- await self.update_subscribers()
- asyncio.create_task(update_description())
+ if step.description is None:
+ async def update_description():
+ step.description = await step.describe(self.continue_sdk.models)
+ # Update subscribers with new description
+ await self.update_subscribers()
+
+ asyncio.create_task(update_description())
return observation
diff --git a/continuedev/src/continuedev/core/main.py b/continuedev/src/continuedev/core/main.py
index b2b97bae..37d80de3 100644
--- a/continuedev/src/continuedev/core/main.py
+++ b/continuedev/src/continuedev/core/main.py
@@ -67,11 +67,16 @@ class History(ContinueBaseModel):
return None
return state.observation
- def pop_last_step(self) -> Union[HistoryNode, None]:
- if self.current_index < 0:
+ def pop_step(self, index: int = None) -> Union[HistoryNode, None]:
+ index = index if index is not None else self.current_index
+ if index < 0 or self.current_index < 0:
return None
- node = self.timeline.pop(self.current_index)
- self.current_index -= 1
+
+ node = self.timeline.pop(index)
+
+ if index <= self.current_index:
+ self.current_index -= 1
+
return node.step
@classmethod
@@ -105,7 +110,7 @@ class Policy(ContinueBaseModel):
class Step(ContinueBaseModel):
name: str = None
hide: bool = False
- _description: Union[str, None] = None
+ description: Union[str, None] = None
system_message: Union[str, None] = None
@@ -113,17 +118,14 @@ class Step(ContinueBaseModel):
copy_on_model_validation = False
async def describe(self, models: Models) -> Coroutine[str, None, None]:
- if self._description is not None:
- return self._description
+ if self.description is not None:
+ return self.description
return "Running step: " + self.name
- def _set_description(self, description: str):
- self._description = description
-
def dict(self, *args, **kwargs):
d = super().dict(*args, **kwargs)
- if self._description is not None:
- d["description"] = self._description
+ if self.description is not None:
+ d["description"] = self.description
else:
d["description"] = "`Description loading...`"
return d
@@ -173,4 +175,25 @@ class Validator(Step):
raise NotImplementedError
+class Context:
+ key_value: Dict[str, str] = {}
+
+ def set(self, key: str, value: str):
+ self.key_value[key] = value
+
+ def get(self, key: str) -> str:
+ return self.key_value[key]
+
+
+class ContinueCustomException(Exception):
+ title: str
+ message: str
+ with_step: Union[Step, None]
+
+ def __init__(self, message: str, title: str = "Error while running step:", with_step: Union[Step, None] = None):
+ self.message = message
+ self.title = title
+ self.with_step = with_step
+
+
HistoryNode.update_forward_refs()
diff --git a/continuedev/src/continuedev/core/observation.py b/continuedev/src/continuedev/core/observation.py
index b6117236..126cf19e 100644
--- a/continuedev/src/continuedev/core/observation.py
+++ b/continuedev/src/continuedev/core/observation.py
@@ -36,4 +36,5 @@ class TextObservation(Observation):
class InternalErrorObservation(Observation):
+ title: str
error: str
diff --git a/continuedev/src/continuedev/core/policy.py b/continuedev/src/continuedev/core/policy.py
index 4287bb6e..8aea8de7 100644
--- a/continuedev/src/continuedev/core/policy.py
+++ b/continuedev/src/continuedev/core/policy.py
@@ -17,7 +17,11 @@ class DemoPolicy(Policy):
def next(self, history: History) -> Step:
# At the very start, run initial Steps spcecified in the config
if history.get_current() is None:
- return MessageStep(message="Welcome to Continue!") >> SetupContinueWorkspaceStep() >> CreateCodebaseIndexChroma() >> StepsOnStartupStep()
+ return (
+ # MessageStep(name="Welcome to Continue!", message="") >>
+ # SetupContinueWorkspaceStep() >>
+ # CreateCodebaseIndexChroma() >>
+ StepsOnStartupStep())
observation = history.get_current().observation
if observation is not None and isinstance(observation, UserInputObservation):
@@ -34,7 +38,7 @@ class DemoPolicy(Policy):
return EditFileChroma(request=" ".join(observation.user_input.split(" ")[1:]))
elif "/step" in observation.user_input:
return ContinueStepStep(prompt=" ".join(observation.user_input.split(" ")[1:]))
- return StarCoderEditHighlightedCodeStep(user_input=observation.user_input)
+ return EditHighlightedCodeStep(user_input=observation.user_input)
state = history.get_current()
diff --git a/continuedev/src/continuedev/core/sdk.py b/continuedev/src/continuedev/core/sdk.py
index 8317a3d1..51faadf2 100644
--- a/continuedev/src/continuedev/core/sdk.py
+++ b/continuedev/src/continuedev/core/sdk.py
@@ -2,16 +2,17 @@ from abc import ABC, abstractmethod
from typing import Coroutine, Union
import os
+from ..steps.core.core import Gpt35EditCodeStep
+from ..models.main import Range
from .abstract_sdk import AbstractContinueSDK
from .config import ContinueConfig, load_config
from ..models.filesystem_edit import FileEdit, FileSystemEdit, AddFile, DeleteFile, AddDirectory, DeleteDirectory
from ..models.filesystem import RangeInFile
-from ..libs.llm import LLM
from ..libs.llm.hf_inference_api import HuggingFaceInferenceAPI
from ..libs.llm.openai import OpenAI
from .observation import Observation
from ..server.ide_protocol import AbstractIdeProtocolServer
-from .main import History, Step
+from .main import Context, ContinueCustomException, History, Step
from ..steps.core.core import *
@@ -44,6 +45,7 @@ class ContinueSDK(AbstractContinueSDK):
ide: AbstractIdeProtocolServer
steps: ContinueSDKSteps
models: Models
+ context: Context
__autopilot: Autopilot
def __init__(self, autopilot: Autopilot):
@@ -51,6 +53,7 @@ class ContinueSDK(AbstractContinueSDK):
self.__autopilot = autopilot
self.steps = ContinueSDKSteps(self)
self.models = Models(self)
+ self.context = autopilot.context
@property
def history(self) -> History:
@@ -64,8 +67,8 @@ class ContinueSDK(AbstractContinueSDK):
async def run_step(self, step: Step) -> Coroutine[Observation, None, None]:
return await self.__autopilot._run_singular_step(step)
- async def apply_filesystem_edit(self, edit: FileSystemEdit):
- return await self.run_step(FileSystemEditStep(edit=edit))
+ async def apply_filesystem_edit(self, edit: FileSystemEdit, name: str = None, description: str = None):
+ return await self.run_step(FileSystemEditStep(edit=edit, description=description, **({'name': name} if name else {})))
async def wait_for_user_input(self) -> str:
return await self.__autopilot.wait_for_user_input()
@@ -73,18 +76,21 @@ class ContinueSDK(AbstractContinueSDK):
async def wait_for_user_confirmation(self, prompt: str):
return await self.run_step(WaitForUserConfirmationStep(prompt=prompt))
- async def run(self, commands: Union[List[str], str], cwd: str = None):
+ async def run(self, commands: Union[List[str], str], cwd: str = None, name: str = None, description: str = None) -> Coroutine[str, None, None]:
commands = commands if isinstance(commands, List) else [commands]
- return await self.run_step(ShellCommandsStep(cmds=commands, cwd=cwd))
+ return (await self.run_step(ShellCommandsStep(cmds=commands, cwd=cwd, description=description, **({'name': name} if name else {})))).text
- async def edit_file(self, filename: str, prompt: str):
+ async def edit_file(self, filename: str, prompt: str, name: str = None, description: str = None, range: Range = None):
filepath = await self._ensure_absolute_path(filename)
await self.ide.setFileOpen(filepath)
contents = await self.ide.readFile(filepath)
- await self.run_step(EditCodeStep(
- range_in_files=[RangeInFile.from_entire_file(filepath, contents)],
- prompt=f'Here is the code before:\n\n{{code}}\n\nHere is the user request:\n\n{prompt}\n\nHere is the code edited to perfectly solve the user request:\n\n'
+ await self.run_step(Gpt35EditCodeStep(
+ range_in_files=[RangeInFile(filepath=filename, range=range) if range is not None else RangeInFile.from_entire_file(
+ filepath, contents)],
+ user_input=prompt,
+ description=description,
+ **({'name': name} if name else {})
))
async def append_to_file(self, filename: str, content: str):
@@ -126,3 +132,6 @@ class ContinueSDK(AbstractContinueSDK):
def set_loading_message(self, message: str):
# self.__autopilot.set_loading_message(message)
raise NotImplementedError()
+
+ def raise_exception(self, message: str, title: str, with_step: Union[Step, None] = None):
+ raise ContinueCustomException(message, title, with_step)
diff --git a/continuedev/src/continuedev/recipes/CreatePipelineRecipe/main.py b/continuedev/src/continuedev/recipes/CreatePipelineRecipe/main.py
index 4a4604d6..428ac9cc 100644
--- a/continuedev/src/continuedev/recipes/CreatePipelineRecipe/main.py
+++ b/continuedev/src/continuedev/recipes/CreatePipelineRecipe/main.py
@@ -11,8 +11,8 @@ class CreatePipelineRecipe(Step):
hide: bool = True
async def run(self, sdk: ContinueSDK):
- await sdk.run_step(
- MessageStep(message=dedent("""\
+ text_observation = await sdk.run_step(
+ MessageStep(name="Building your first dlt pipeline", message=dedent("""\
This recipe will walk you through the process of creating a dlt pipeline for your chosen data source. With the help of Continue, you will:
- Create a Python virtual environment with dlt installed
- Run `dlt init` to generate a pipeline template
@@ -21,7 +21,10 @@ class CreatePipelineRecipe(Step):
- Test that the API call works
- Load the data into a local DuckDB instance
- Write a query to view the data""")) >>
- WaitForUserInputStep(prompt="What API do you want to load data from?") >>
- SetupPipelineStep(api_description="WeatherAPI.com API") >>
+ WaitForUserInputStep(
+ prompt="What API do you want to load data from? (e.g. weatherapi.com, chess.com)")
+ )
+ await sdk.run_step(
+ SetupPipelineStep(api_description=text_observation.text) >>
ValidatePipelineStep()
)
diff --git a/continuedev/src/continuedev/recipes/CreatePipelineRecipe/steps.py b/continuedev/src/continuedev/recipes/CreatePipelineRecipe/steps.py
index ef5e3b43..511abd1f 100644
--- a/continuedev/src/continuedev/recipes/CreatePipelineRecipe/steps.py
+++ b/continuedev/src/continuedev/recipes/CreatePipelineRecipe/steps.py
@@ -1,12 +1,19 @@
+import os
+import subprocess
from textwrap import dedent
+import time
+from ...models.main import Range
+from ...models.filesystem import RangeInFile
from ...steps.main import MessageStep
from ...core.sdk import Models
-from ...core.observation import DictObservation
-from ...models.filesystem_edit import AddFile
+from ...core.observation import DictObservation, InternalErrorObservation
+from ...models.filesystem_edit import AddFile, FileEdit
from ...core.main import Step
from ...core.sdk import ContinueSDK
+AI_ASSISTED_STRING = "(✨ AI-Assisted ✨)"
+
class SetupPipelineStep(Step):
hide: bool = True
@@ -21,6 +28,8 @@ class SetupPipelineStep(Step):
""")
async def run(self, sdk: ContinueSDK):
+ sdk.context.set("api_description", self.api_description)
+
source_name = (await sdk.models.gpt35()).complete(
f"Write a snake_case name for the data source described by {self.api_description}: ").strip()
filename = f'{source_name}.py'
@@ -30,48 +39,100 @@ class SetupPipelineStep(Step):
'python3 -m venv env',
'source env/bin/activate',
'pip install dlt',
- f'dlt init {source_name} duckdb',
- 'Y',
+ f'dlt --non-interactive init {source_name} duckdb',
'pip install -r requirements.txt'
- ])
+ ], description=dedent(f"""\
+ Running the following commands:
+ - `python3 -m venv env`: Create a Python virtual environment
+ - `source env/bin/activate`: Activate the virtual environment
+ - `pip install dlt`: Install dlt
+ - `dlt init {source_name} duckdb`: Create a new dlt pipeline called {source_name} that loads data into a local DuckDB instance
+ - `pip install -r requirements.txt`: Install the Python dependencies for the pipeline"""), name="Setup Python environment")
# editing the resource function to call the requested API
+ resource_function_range = Range.from_shorthand(15, 0, 29, 0)
+ await sdk.ide.highlightCode(RangeInFile(filepath=os.path.join(await sdk.ide.getWorkspaceDirectory(), filename), range=resource_function_range), "#00ff0022")
+
+ # sdk.set_loading_message("Writing code to call the API...")
await sdk.edit_file(
+ range=resource_function_range,
filename=filename,
- prompt=f'Edit the resource function to call the API described by this: {self.api_description}'
+ prompt=f'Edit the resource function to call the API described by this: {self.api_description}. Do not move or remove the exit() call in __main__.',
+ name=f"Edit the resource function to call the API {AI_ASSISTED_STRING}"
)
+ time.sleep(1)
+
# wait for user to put API key in secrets.toml
await sdk.ide.setFileOpen(await sdk.ide.getWorkspaceDirectory() + "/.dlt/secrets.toml")
await sdk.wait_for_user_confirmation("If this service requires an API key, please add it to the `secrets.toml` file and then press `Continue`")
- return DictObservation(values={"source_name": source_name})
+
+ sdk.context.set("source_name", source_name)
class ValidatePipelineStep(Step):
hide: bool = True
async def run(self, sdk: ContinueSDK):
- source_name = sdk.history.last_observation().values["source_name"]
+ workspace_dir = await sdk.ide.getWorkspaceDirectory()
+ source_name = sdk.context.get("source_name")
filename = f'{source_name}.py'
- await sdk.run_step(MessageStep(message=dedent("""\
- This step will validate that your dlt pipeline is working as expected:
- - Test that the API call works
- - Load the data into a local DuckDB instance
- - Write a query to view the data
- """)))
+ # await sdk.run_step(MessageStep(name="Validate the pipeline", message=dedent("""\
+ # Next, we will validate that your dlt pipeline is working as expected:
+ # - Test that the API call works
+ # - Load the data into a local DuckDB instance
+ # - Write a query to view the data
+ # """)))
# test that the API call works
- await sdk.run(f'python3 {filename}')
+ output = await sdk.run(f'python3 {filename}', name="Test the pipeline", description=f"Running `python3 {filename}` to test loading data from the API")
+
+ # If it fails, return the error
+ if "Traceback" in output:
+ output = "Traceback" + output.split("Traceback")[-1]
+ file_content = await sdk.ide.readFile(os.path.join(workspace_dir, filename))
+ suggestion = (await sdk.models.gpt35()).complete(dedent(f"""\
+ ```python
+ {file_content}
+ ```
+ This above code is a dlt pipeline that loads data from an API. The function with the @resource decorator is responsible for calling the API and returning the data. While attempting to run the pipeline, the following error occurred:
+
+ ```ascii
+ {output}
+ ```
+
+ This is a brief summary of the error followed by a suggestion on how it can be fixed by editing the resource function:"""))
+
+ api_documentation_url = (await sdk.models.gpt35()).complete(dedent(f"""\
+ The API I am trying to call is the '{sdk.context.get('api_description')}'. I tried calling it in the @resource function like this:
+ ```python
+ {file_content}
+ ```
+ What is the URL for the API documentation that will help me learn how to make this call? Please format in markdown so I can click the link."""))
+
+ sdk.raise_exception(
+ title=f"Error while running pipeline.\nFix the resource function in {filename} and rerun this step", message=output, with_step=MessageStep(name=f"Suggestion to solve error {AI_ASSISTED_STRING}", message=dedent(f"""\
+ {suggestion}
+
+ {api_documentation_url}
+
+ After you've fixed the code, click the retry button at the top of the Validate Pipeline step above.""")))
# remove exit() from the main main function
- await sdk.edit_file(
- filename=filename,
- prompt='Remove exit() from the main function'
- )
+ await sdk.run_step(MessageStep(name="Remove early exit() from main function", message="Remove the early exit() from the main function now that we are done testing and want the pipeline to load the data into DuckDB."))
+
+ contents = await sdk.ide.readFile(os.path.join(workspace_dir, filename))
+ replacement = "\n".join(
+ list(filter(lambda line: line.strip() != "exit()", contents.split("\n"))))
+ await sdk.ide.applyFileSystemEdit(FileEdit(
+ filepath=os.path.join(workspace_dir, filename),
+ replacement=replacement,
+ range=Range.from_entire_file(contents)
+ ))
# load the data into the DuckDB instance
- await sdk.run(f'python3 {filename}')
+ await sdk.run(f'python3 {filename}', name="Load data into DuckDB", description=f"Running python3 {filename} to load data into DuckDB")
table_name = f"{source_name}.{source_name}_resource"
tables_query_code = dedent(f'''\
@@ -85,9 +146,8 @@ class ValidatePipelineStep(Step):
# print table names
for row in rows:
- print(row)
- ''')
+ print(row)''')
- query_filename = (await sdk.ide.getWorkspaceDirectory()) + "/query.py"
- await sdk.apply_filesystem_edit(AddFile(filepath=query_filename, content=tables_query_code))
- await sdk.run('env/bin/python3 query.py')
+ query_filename = os.path.join(workspace_dir, "query.py")
+ await sdk.apply_filesystem_edit(AddFile(filepath=query_filename, content=tables_query_code), name="Add query.py file", description="Adding a file called `query.py` to the workspace that will run a test query on the DuckDB instance")
+ await sdk.run('env/bin/python3 query.py', name="Run test query", description="Running `env/bin/python3 query.py` to test that the data was loaded into DuckDB as expected")
diff --git a/continuedev/src/continuedev/server/ide.py b/continuedev/src/continuedev/server/ide.py
index eec5b607..007eb2b4 100644
--- a/continuedev/src/continuedev/server/ide.py
+++ b/continuedev/src/continuedev/server/ide.py
@@ -76,6 +76,10 @@ class GetUserSecretResponse(BaseModel):
value: str
+class RunCommandResponse(BaseModel):
+ output: str
+
+
T = TypeVar("T", bound=BaseModel)
@@ -110,7 +114,7 @@ class IdeProtocolServer(AbstractIdeProtocolServer):
fileEdits = list(
map(lambda d: FileEditWithFullContents.parse_obj(d), data["fileEdits"]))
self.onFileEdits(fileEdits)
- elif message_type in ["highlightedCode", "openFiles", "readFile", "editFile", "workspaceDirectory", "getUserSecret"]:
+ elif message_type in ["highlightedCode", "openFiles", "readFile", "editFile", "workspaceDirectory", "getUserSecret", "runCommand"]:
self.sub_queue.post(message_type, data)
else:
raise ValueError("Unknown message type", message_type)
@@ -133,6 +137,15 @@ class IdeProtocolServer(AbstractIdeProtocolServer):
"sessionId": session_id
})
+ async def highlightCode(self, range_in_file: RangeInFile, color: str):
+ await self._send_json("highlightCode", {
+ "rangeInFile": range_in_file.dict(),
+ "color": color
+ })
+
+ async def runCommand(self, command: str) -> str:
+ return (await self._send_and_receive_json({"command": command}, RunCommandResponse, "runCommand")).output
+
async def showSuggestionsAndWait(self, suggestions: List[FileEdit]) -> bool:
ids = [str(uuid.uuid4()) for _ in suggestions]
for i in range(len(suggestions)):
diff --git a/continuedev/src/continuedev/server/ide_protocol.py b/continuedev/src/continuedev/server/ide_protocol.py
index 8f155415..4622d6ff 100644
--- a/continuedev/src/continuedev/server/ide_protocol.py
+++ b/continuedev/src/continuedev/server/ide_protocol.py
@@ -82,3 +82,11 @@ class AbstractIdeProtocolServer(ABC):
@abstractmethod
async def getUserSecret(self, key: str):
"""Get a user secret"""
+
+ @abstractmethod
+ async def highlightCode(self, range_in_file: RangeInFile, color: str):
+ """Highlight code"""
+
+ @abstractmethod
+ async def runCommand(self, command: str) -> str:
+ """Run a command"""
diff --git a/continuedev/src/continuedev/steps/core/core.py b/continuedev/src/continuedev/steps/core/core.py
index fdcd9837..413bc195 100644
--- a/continuedev/src/continuedev/steps/core/core.py
+++ b/continuedev/src/continuedev/steps/core/core.py
@@ -4,7 +4,7 @@ from textwrap import dedent
from typing import Coroutine, List, Union
from ...libs.llm.prompt_utils import MarkdownStyleEncoderDecoder
-from ...models.filesystem_edit import EditDiff, FileEditWithFullContents, FileSystemEdit
+from ...models.filesystem_edit import EditDiff, FileEdit, FileEditWithFullContents, FileSystemEdit
from ...models.filesystem import FileSystem, RangeInFile, RangeInFileWithContents
from ...core.observation import Observation, TextObservation, TracebackObservation, UserInputObservation
from ...core.main import Step, SequentialStep
@@ -55,40 +55,67 @@ class ShellCommandsStep(Step):
async def run(self, sdk: ContinueSDK) -> Coroutine[Observation, None, None]:
cwd = await sdk.ide.getWorkspaceDirectory() if self.cwd is None else self.cwd
- process = subprocess.Popen(
- '/bin/bash', stdin=subprocess.PIPE, stdout=subprocess.PIPE, cwd=cwd)
+ for cmd in self.cmds:
+ output = await sdk.ide.runCommand(cmd)
- stdin_input = "\n".join(self.cmds)
- out, err = process.communicate(stdin_input.encode())
+ return TextObservation(text=output)
- # If it fails, return the error
- if err is not None and err != "":
- self._err_text = err
- return TextObservation(text=err)
+ # process = subprocess.Popen(
+ # '/bin/bash', stdin=subprocess.PIPE, stdout=subprocess.PIPE, cwd=cwd)
- return None
+ # stdin_input = "\n".join(self.cmds)
+ # out, err = process.communicate(stdin_input.encode())
+ # # If it fails, return the error
+ # if err is not None and err != "":
+ # self._err_text = err
+ # return TextObservation(text=err)
-class EditCodeStep(Step):
- # Might make an even more specific atomic step, which is "apply file edit"
- range_in_files: List[RangeInFile]
- prompt: str # String with {code} somewhere
- name: str = "Edit code"
+ # return None
- _edit_diffs: Union[List[EditDiff], None] = None
- _prompt: Union[str, None] = None
- _completion: Union[str, None] = None
- async def describe(self, models: Models) -> Coroutine[str, None, None]:
- if self._edit_diffs is None:
- return "Editing files: " + ", ".join(map(lambda rif: rif.filepath, self.range_in_files))
- elif len(self._edit_diffs) == 0:
- return "No edits made"
- else:
- return (await models.gpt35()).complete(dedent(f"""{self._prompt}{self._completion}
+class Gpt35EditCodeStep(Step):
+ user_input: str
+ range_in_files: List[RangeInFile]
+ name: str = "Editing Code"
+ hide = False
+ _prompt: str = dedent("""\
+ Take the file prefix and suffix into account, but only rewrite the commit before as specified in the commit message. Here's an example:
+
+ <file_prefix>
+ a = 5
+ b = 4
+
+ <file_suffix>
+
+ def mul(a, b):
+ return a * b
+ <commit_before>
+ def sum():
+ return a + b
+ <commit_msg>
+ Make a and b parameters of sum
+ <commit_after>
+ def sum(a, b):
+ return a + b
+ <|endoftext|>
+
+ Now complete the real thing:
+
+ <file_prefix>
+ {file_prefix}
+ <file_suffix>
+ {file_suffix}
+ <commit_before>
+ {code}
+ <commit_msg>
+ {user_request}
+ <commit_after>""")
+
+ _prompt_and_completion: str = ""
- Maximally concise summary of changes in bullet points (can use markdown):
- """))
+ async def describe(self, models: Models) -> Coroutine[str, None, None]:
+ return (await models.gpt35()).complete(f"{self._prompt_and_completion}\n\nPlease give brief a description of the changes made above using markdown bullet points:")
async def run(self, sdk: ContinueSDK) -> Coroutine[Observation, None, None]:
rif_with_contents = []
@@ -96,28 +123,27 @@ class EditCodeStep(Step):
file_contents = await sdk.ide.readRangeInFile(range_in_file)
rif_with_contents.append(
RangeInFileWithContents.from_range_in_file(range_in_file, file_contents))
- enc_dec = MarkdownStyleEncoderDecoder(rif_with_contents)
- code_string = enc_dec.encode()
- prompt = self.prompt.format(code=code_string)
-
- completion = (await sdk.models.gpt35()).complete(prompt)
- # Temporarily doing this to generate description.
- self._prompt = prompt
- self._completion = completion
+ rif_dict = {}
+ for rif in rif_with_contents:
+ rif_dict[rif.filepath] = rif.contents
- file_edits = enc_dec.decode(completion)
+ for rif in rif_with_contents:
+ full_file_contents = await sdk.ide.readFile(rif.filepath)
+ segs = full_file_contents.split(rif.contents)
+ prompt = self._prompt.format(
+ code=rif.contents, user_request=self.user_input, file_prefix=segs[0], file_suffix=segs[1])
- self._edit_diffs = []
- for file_edit in file_edits:
- diff = await sdk.apply_filesystem_edit(file_edit)
- self._edit_diffs.append(diff)
+ completion = str((await sdk.models.gpt35()).complete(prompt))
+ eot_token = "<|endoftext|>"
+ completion = completion.removesuffix(eot_token)
- for filepath in set([file_edit.filepath for file_edit in file_edits]):
- await sdk.ide.saveFile(filepath)
- await sdk.ide.setFileOpen(filepath)
+ self._prompt_and_completion += prompt + completion
- return None
+ await sdk.ide.applyFileSystemEdit(
+ FileEdit(filepath=rif.filepath, range=rif.range, replacement=completion))
+ await sdk.ide.saveFile(rif.filepath)
+ await sdk.ide.setFileOpen(rif.filepath)
class EditFileStep(Step):
@@ -130,10 +156,10 @@ class EditFileStep(Step):
async def run(self, sdk: ContinueSDK) -> Coroutine[Observation, None, None]:
file_contents = await sdk.ide.readFile(self.filepath)
- await sdk.run_step(EditCodeStep(
+ await sdk.run_step(Gpt35EditCodeStep(
range_in_files=[RangeInFile.from_entire_file(
self.filepath, file_contents)],
- prompt=self.prompt
+ user_input=self.prompt
))
@@ -191,13 +217,18 @@ class WaitForUserInputStep(Step):
name: str = "Waiting for user input"
_description: Union[str, None] = None
+ _response: Union[str, None] = None
async def describe(self, models: Models) -> Coroutine[str, None, None]:
- return self.prompt
+ if self._response is None:
+ return self.prompt
+ else:
+ return f"{self.prompt}\n\n`{self._response}`"
async def run(self, sdk: ContinueSDK) -> Coroutine[Observation, None, None]:
- self._description = self.prompt
+ self.description = self.prompt
resp = await sdk.wait_for_user_input()
+ self.description = f"{self.prompt}\n\n`{resp}`"
return TextObservation(text=resp)
@@ -209,7 +240,7 @@ class WaitForUserConfirmationStep(Step):
return self.prompt
async def run(self, sdk: ContinueSDK) -> Coroutine[Observation, None, None]:
- self._description = self.prompt
+ self.description = self.prompt
resp = await sdk.wait_for_user_input()
self.hide = True
return TextObservation(text=resp)
diff --git a/continuedev/src/continuedev/steps/main.py b/continuedev/src/continuedev/steps/main.py
index da0fc8d2..69c98bd4 100644
--- a/continuedev/src/continuedev/steps/main.py
+++ b/continuedev/src/continuedev/steps/main.py
@@ -15,7 +15,7 @@ from ..core.main import Step
from ..core.sdk import ContinueSDK, Models
from ..core.observation import Observation
import subprocess
-from .core.core import EditCodeStep
+from .core.core import Gpt35EditCodeStep
class SetupContinueWorkspaceStep(Step):
@@ -255,19 +255,9 @@ class StarCoderEditHighlightedCodeStep(Step):
class EditHighlightedCodeStep(Step):
user_input: str
hide = True
- _prompt: str = dedent("""Below is the code before changes:
-
-{code}
-
-This is the user request:
-
-{user_input}
-
-This is the code after being changed to perfectly satisfy the user request:
- """)
async def describe(self, models: Models) -> Coroutine[str, None, None]:
- return "Editing highlighted code"
+ return "Editing code"
async def run(self, sdk: ContinueSDK) -> Coroutine[Observation, None, None]:
range_in_files = await sdk.ide.getHighlightedCode()
@@ -281,8 +271,7 @@ This is the code after being changed to perfectly satisfy the user request:
range_in_files = [RangeInFile.from_entire_file(
filepath, content) for filepath, content in contents.items()]
- await sdk.run_step(EditCodeStep(
- range_in_files=range_in_files, prompt=self._prompt.format(code="{code}", user_input=self.user_input)))
+ await sdk.run_step(Gpt35EditCodeStep(user_input=self.user_input, range_in_files=range_in_files))
class FindCodeStep(Step):
diff --git a/extension/esbuild.mjs b/extension/esbuild.mjs
new file mode 100644
index 00000000..bc1b3e5f
--- /dev/null
+++ b/extension/esbuild.mjs
@@ -0,0 +1,14 @@
+import * as esbuild from "esbuild";
+// esbuild ./src/extension.ts --bundle --outfile=out/extension.js --external:vscode --format=cjs --platform=node
+await esbuild.build({
+ entryPoints: ["src/extension.ts"],
+ bundle: true,
+ outfile: "out/extension.js",
+ external: ["vscode"],
+ format: "cjs",
+ platform: "node",
+ sourcemap: true,
+ loader: {
+ ".node": "file",
+ },
+});
diff --git a/extension/package-lock.json b/extension/package-lock.json
index fa09527e..0b0e063b 100644
--- a/extension/package-lock.json
+++ b/extension/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "continue",
- "version": "0.0.20",
+ "version": "0.0.23",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "continue",
- "version": "0.0.20",
+ "version": "0.0.23",
"license": "Apache-2.0",
"dependencies": {
"@electron/rebuild": "^3.2.10",
@@ -16,11 +16,10 @@
"@vitejs/plugin-react-swc": "^3.3.2",
"axios": "^1.2.5",
"highlight.js": "^11.7.0",
- "octokit": "^2.0.11",
"posthog-js": "^1.63.3",
"react-markdown": "^8.0.7",
"react-redux": "^8.0.5",
- "strip-ansi": "^7.0.1",
+ "strip-ansi": "^7.1.0",
"tailwindcss": "^3.3.2",
"vite": "^4.3.9",
"vscode-languageclient": "^8.0.2",
@@ -1120,457 +1119,6 @@
"npm": ">=5.0.0"
}
},
- "node_modules/@octokit/app": {
- "version": "13.1.2",
- "resolved": "https://registry.npmjs.org/@octokit/app/-/app-13.1.2.tgz",
- "integrity": "sha512-Kf+h5sa1SOI33hFsuHvTsWj1jUrjp1x4MuiJBq7U/NicfEGa6nArPUoDnyfP/YTmcQ5cQ5yvOgoIBkbwPg6kzQ==",
- "dependencies": {
- "@octokit/auth-app": "^4.0.8",
- "@octokit/auth-unauthenticated": "^3.0.0",
- "@octokit/core": "^4.0.0",
- "@octokit/oauth-app": "^4.0.7",
- "@octokit/plugin-paginate-rest": "^6.0.0",
- "@octokit/types": "^9.0.0",
- "@octokit/webhooks": "^10.0.0"
- },
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/@octokit/app/node_modules/@octokit/openapi-types": {
- "version": "16.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-16.0.0.tgz",
- "integrity": "sha512-JbFWOqTJVLHZSUUoF4FzAZKYtqdxWu9Z5m2QQnOyEa04fOFljvyh7D3GYKbfuaSWisqehImiVIMG4eyJeP5VEA=="
- },
- "node_modules/@octokit/app/node_modules/@octokit/plugin-paginate-rest": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.0.0.tgz",
- "integrity": "sha512-Sq5VU1PfT6/JyuXPyt04KZNVsFOSBaYOAq2QRZUwzVlI10KFvcbUo8lR258AAQL1Et60b0WuVik+zOWKLuDZxw==",
- "dependencies": {
- "@octokit/types": "^9.0.0"
- },
- "engines": {
- "node": ">= 14"
- },
- "peerDependencies": {
- "@octokit/core": ">=4"
- }
- },
- "node_modules/@octokit/app/node_modules/@octokit/types": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.0.0.tgz",
- "integrity": "sha512-LUewfj94xCMH2rbD5YJ+6AQ4AVjFYTgpp6rboWM5T7N3IsIF65SBEOVcYMGAEzO/kKNiNaW4LoWtoThOhH06gw==",
- "dependencies": {
- "@octokit/openapi-types": "^16.0.0"
- }
- },
- "node_modules/@octokit/auth-app": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/@octokit/auth-app/-/auth-app-4.0.8.tgz",
- "integrity": "sha512-miI7y9FfS/fL1bSPsDaAfCGSxQ04iGLyisI2GA8N7P6eB6AkCOt+F1XXapJKRnAubQubvYF0dqxoTZYyKk93NQ==",
- "dependencies": {
- "@octokit/auth-oauth-app": "^5.0.0",
- "@octokit/auth-oauth-user": "^2.0.0",
- "@octokit/request": "^6.0.0",
- "@octokit/request-error": "^3.0.0",
- "@octokit/types": "^8.0.0",
- "@types/lru-cache": "^5.1.0",
- "deprecation": "^2.3.1",
- "lru-cache": "^6.0.0",
- "universal-github-app-jwt": "^1.1.1",
- "universal-user-agent": "^6.0.0"
- },
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/@octokit/auth-oauth-app": {
- "version": "5.0.5",
- "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-app/-/auth-oauth-app-5.0.5.tgz",
- "integrity": "sha512-UPX1su6XpseaeLVCi78s9droxpGtBWIgz9XhXAx9VXabksoF0MyI5vaa1zo1njyYt6VaAjFisC2A2Wchcu2WmQ==",
- "dependencies": {
- "@octokit/auth-oauth-device": "^4.0.0",
- "@octokit/auth-oauth-user": "^2.0.0",
- "@octokit/request": "^6.0.0",
- "@octokit/types": "^9.0.0",
- "@types/btoa-lite": "^1.0.0",
- "btoa-lite": "^1.0.0",
- "universal-user-agent": "^6.0.0"
- },
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/@octokit/auth-oauth-app/node_modules/@octokit/openapi-types": {
- "version": "16.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-16.0.0.tgz",
- "integrity": "sha512-JbFWOqTJVLHZSUUoF4FzAZKYtqdxWu9Z5m2QQnOyEa04fOFljvyh7D3GYKbfuaSWisqehImiVIMG4eyJeP5VEA=="
- },
- "node_modules/@octokit/auth-oauth-app/node_modules/@octokit/types": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.0.0.tgz",
- "integrity": "sha512-LUewfj94xCMH2rbD5YJ+6AQ4AVjFYTgpp6rboWM5T7N3IsIF65SBEOVcYMGAEzO/kKNiNaW4LoWtoThOhH06gw==",
- "dependencies": {
- "@octokit/openapi-types": "^16.0.0"
- }
- },
- "node_modules/@octokit/auth-oauth-device": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-device/-/auth-oauth-device-4.0.3.tgz",
- "integrity": "sha512-KPTx5nMntKjNZzzltO3X4T68v22rd7Cp/TcLJXQE2U8aXPcZ9LFuww9q9Q5WUNSu3jwi3lRwzfkPguRfz1R8Vg==",
- "dependencies": {
- "@octokit/oauth-methods": "^2.0.0",
- "@octokit/request": "^6.0.0",
- "@octokit/types": "^8.0.0",
- "universal-user-agent": "^6.0.0"
- },
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/@octokit/auth-oauth-user": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-user/-/auth-oauth-user-2.1.0.tgz",
- "integrity": "sha512-TC2Mj8NkSy9uAnZLYX+FKB/IH6uDe+qYNzHzH8l13JlzsrTE7GKkcqtXdSGGN4tncyROAB4/KS5rDPRCEnWHlA==",
- "dependencies": {
- "@octokit/auth-oauth-device": "^4.0.0",
- "@octokit/oauth-methods": "^2.0.0",
- "@octokit/request": "^6.0.0",
- "@octokit/types": "^8.0.0",
- "btoa-lite": "^1.0.0",
- "universal-user-agent": "^6.0.0"
- },
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/@octokit/auth-token": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.3.tgz",
- "integrity": "sha512-/aFM2M4HVDBT/jjDBa84sJniv1t9Gm/rLkalaz9htOm+L+8JMj1k9w0CkUdcxNyNxZPlTxKPVko+m1VlM58ZVA==",
- "dependencies": {
- "@octokit/types": "^9.0.0"
- },
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/@octokit/auth-token/node_modules/@octokit/openapi-types": {
- "version": "16.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-16.0.0.tgz",
- "integrity": "sha512-JbFWOqTJVLHZSUUoF4FzAZKYtqdxWu9Z5m2QQnOyEa04fOFljvyh7D3GYKbfuaSWisqehImiVIMG4eyJeP5VEA=="
- },
- "node_modules/@octokit/auth-token/node_modules/@octokit/types": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.0.0.tgz",
- "integrity": "sha512-LUewfj94xCMH2rbD5YJ+6AQ4AVjFYTgpp6rboWM5T7N3IsIF65SBEOVcYMGAEzO/kKNiNaW4LoWtoThOhH06gw==",
- "dependencies": {
- "@octokit/openapi-types": "^16.0.0"
- }
- },
- "node_modules/@octokit/auth-unauthenticated": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/@octokit/auth-unauthenticated/-/auth-unauthenticated-3.0.4.tgz",
- "integrity": "sha512-AT74XGBylcLr4lmUp1s6mjSUgphGdlse21Qjtv5DzpX1YOl5FXKwvNcZWESdhyBbpDT8VkVyLFqa/7a7eqpPNw==",
- "dependencies": {
- "@octokit/request-error": "^3.0.0",
- "@octokit/types": "^9.0.0"
- },
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/@octokit/auth-unauthenticated/node_modules/@octokit/openapi-types": {
- "version": "16.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-16.0.0.tgz",
- "integrity": "sha512-JbFWOqTJVLHZSUUoF4FzAZKYtqdxWu9Z5m2QQnOyEa04fOFljvyh7D3GYKbfuaSWisqehImiVIMG4eyJeP5VEA=="
- },
- "node_modules/@octokit/auth-unauthenticated/node_modules/@octokit/types": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.0.0.tgz",
- "integrity": "sha512-LUewfj94xCMH2rbD5YJ+6AQ4AVjFYTgpp6rboWM5T7N3IsIF65SBEOVcYMGAEzO/kKNiNaW4LoWtoThOhH06gw==",
- "dependencies": {
- "@octokit/openapi-types": "^16.0.0"
- }
- },
- "node_modules/@octokit/core": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.0.tgz",
- "integrity": "sha512-AgvDRUg3COpR82P7PBdGZF/NNqGmtMq2NiPqeSsDIeCfYFOZ9gddqWNQHnFdEUf+YwOj4aZYmJnlPp7OXmDIDg==",
- "dependencies": {
- "@octokit/auth-token": "^3.0.0",
- "@octokit/graphql": "^5.0.0",
- "@octokit/request": "^6.0.0",
- "@octokit/request-error": "^3.0.0",
- "@octokit/types": "^9.0.0",
- "before-after-hook": "^2.2.0",
- "universal-user-agent": "^6.0.0"
- },
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/@octokit/core/node_modules/@octokit/openapi-types": {
- "version": "16.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-16.0.0.tgz",
- "integrity": "sha512-JbFWOqTJVLHZSUUoF4FzAZKYtqdxWu9Z5m2QQnOyEa04fOFljvyh7D3GYKbfuaSWisqehImiVIMG4eyJeP5VEA=="
- },
- "node_modules/@octokit/core/node_modules/@octokit/types": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.0.0.tgz",
- "integrity": "sha512-LUewfj94xCMH2rbD5YJ+6AQ4AVjFYTgpp6rboWM5T7N3IsIF65SBEOVcYMGAEzO/kKNiNaW4LoWtoThOhH06gw==",
- "dependencies": {
- "@octokit/openapi-types": "^16.0.0"
- }
- },
- "node_modules/@octokit/endpoint": {
- "version": "7.0.4",
- "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.4.tgz",
- "integrity": "sha512-hXJP43VT2IrUxBCNIahta8qawpIzLvCjHLCuDDsdIPbd6+jPwsc3KGl/kdQ37mLd+sdiJm6c9qKI7k5CjE0Z9A==",
- "dependencies": {
- "@octokit/types": "^9.0.0",
- "is-plain-object": "^5.0.0",
- "universal-user-agent": "^6.0.0"
- },
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/@octokit/endpoint/node_modules/@octokit/openapi-types": {
- "version": "16.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-16.0.0.tgz",
- "integrity": "sha512-JbFWOqTJVLHZSUUoF4FzAZKYtqdxWu9Z5m2QQnOyEa04fOFljvyh7D3GYKbfuaSWisqehImiVIMG4eyJeP5VEA=="
- },
- "node_modules/@octokit/endpoint/node_modules/@octokit/types": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.0.0.tgz",
- "integrity": "sha512-LUewfj94xCMH2rbD5YJ+6AQ4AVjFYTgpp6rboWM5T7N3IsIF65SBEOVcYMGAEzO/kKNiNaW4LoWtoThOhH06gw==",
- "dependencies": {
- "@octokit/openapi-types": "^16.0.0"
- }
- },
- "node_modules/@octokit/graphql": {
- "version": "5.0.5",
- "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.5.tgz",
- "integrity": "sha512-Qwfvh3xdqKtIznjX9lz2D458r7dJPP8l6r4GQkIdWQouZwHQK0mVT88uwiU2bdTU2OtT1uOlKpRciUWldpG0yQ==",
- "dependencies": {
- "@octokit/request": "^6.0.0",
- "@octokit/types": "^9.0.0",
- "universal-user-agent": "^6.0.0"
- },
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/@octokit/graphql/node_modules/@octokit/openapi-types": {
- "version": "16.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-16.0.0.tgz",
- "integrity": "sha512-JbFWOqTJVLHZSUUoF4FzAZKYtqdxWu9Z5m2QQnOyEa04fOFljvyh7D3GYKbfuaSWisqehImiVIMG4eyJeP5VEA=="
- },
- "node_modules/@octokit/graphql/node_modules/@octokit/types": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.0.0.tgz",
- "integrity": "sha512-LUewfj94xCMH2rbD5YJ+6AQ4AVjFYTgpp6rboWM5T7N3IsIF65SBEOVcYMGAEzO/kKNiNaW4LoWtoThOhH06gw==",
- "dependencies": {
- "@octokit/openapi-types": "^16.0.0"
- }
- },
- "node_modules/@octokit/oauth-app": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/@octokit/oauth-app/-/oauth-app-4.2.0.tgz",
- "integrity": "sha512-gyGclT77RQMkVUEW3YBeAKY+LBSc5u3eC9Wn/Uwt3WhuKuu9mrV18EnNpDqmeNll+mdV02yyBROU29Tlili6gg==",
- "dependencies": {
- "@octokit/auth-oauth-app": "^5.0.0",
- "@octokit/auth-oauth-user": "^2.0.0",
- "@octokit/auth-unauthenticated": "^3.0.0",
- "@octokit/core": "^4.0.0",
- "@octokit/oauth-authorization-url": "^5.0.0",
- "@octokit/oauth-methods": "^2.0.0",
- "@types/aws-lambda": "^8.10.83",
- "fromentries": "^1.3.1",
- "universal-user-agent": "^6.0.0"
- },
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/@octokit/oauth-authorization-url": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/oauth-authorization-url/-/oauth-authorization-url-5.0.0.tgz",
- "integrity": "sha512-y1WhN+ERDZTh0qZ4SR+zotgsQUE1ysKnvBt1hvDRB2WRzYtVKQjn97HEPzoehh66Fj9LwNdlZh+p6TJatT0zzg==",
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/@octokit/oauth-methods": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/@octokit/oauth-methods/-/oauth-methods-2.0.4.tgz",
- "integrity": "sha512-RDSa6XL+5waUVrYSmOlYROtPq0+cfwppP4VaQY/iIei3xlFb0expH6YNsxNrZktcLhJWSpm9uzeom+dQrXlS3A==",
- "dependencies": {
- "@octokit/oauth-authorization-url": "^5.0.0",
- "@octokit/request": "^6.0.0",
- "@octokit/request-error": "^3.0.0",
- "@octokit/types": "^8.0.0",
- "btoa-lite": "^1.0.0"
- },
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/@octokit/openapi-types": {
- "version": "14.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-14.0.0.tgz",
- "integrity": "sha512-HNWisMYlR8VCnNurDU6os2ikx0s0VyEjDYHNS/h4cgb8DeOxQ0n72HyinUtdDVxJhFy3FWLGl0DJhfEWk3P5Iw=="
- },
- "node_modules/@octokit/plugin-paginate-rest": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-5.0.1.tgz",
- "integrity": "sha512-7A+rEkS70pH36Z6JivSlR7Zqepz3KVucEFVDnSrgHXzG7WLAzYwcHZbKdfTXHwuTHbkT1vKvz7dHl1+HNf6Qyw==",
- "dependencies": {
- "@octokit/types": "^8.0.0"
- },
- "engines": {
- "node": ">= 14"
- },
- "peerDependencies": {
- "@octokit/core": ">=4"
- }
- },
- "node_modules/@octokit/plugin-rest-endpoint-methods": {
- "version": "6.8.1",
- "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-6.8.1.tgz",
- "integrity": "sha512-QrlaTm8Lyc/TbU7BL/8bO49vp+RZ6W3McxxmmQTgYxf2sWkO8ZKuj4dLhPNJD6VCUW1hetCmeIM0m6FTVpDiEg==",
- "dependencies": {
- "@octokit/types": "^8.1.1",
- "deprecation": "^2.3.1"
- },
- "engines": {
- "node": ">= 14"
- },
- "peerDependencies": {
- "@octokit/core": ">=3"
- }
- },
- "node_modules/@octokit/plugin-retry": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-4.0.4.tgz",
- "integrity": "sha512-d7qGFLR3AH+WbNEDUvBPgMc7wRCxU40FZyNXFFqs8ISw75ZYS5/P3ScggzU13dCoY0aywYDxKugGstQTwNgppA==",
- "dependencies": {
- "@octokit/types": "^9.0.0",
- "bottleneck": "^2.15.3"
- },
- "engines": {
- "node": ">= 14"
- },
- "peerDependencies": {
- "@octokit/core": ">=3"
- }
- },
- "node_modules/@octokit/plugin-retry/node_modules/@octokit/openapi-types": {
- "version": "16.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-16.0.0.tgz",
- "integrity": "sha512-JbFWOqTJVLHZSUUoF4FzAZKYtqdxWu9Z5m2QQnOyEa04fOFljvyh7D3GYKbfuaSWisqehImiVIMG4eyJeP5VEA=="
- },
- "node_modules/@octokit/plugin-retry/node_modules/@octokit/types": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.0.0.tgz",
- "integrity": "sha512-LUewfj94xCMH2rbD5YJ+6AQ4AVjFYTgpp6rboWM5T7N3IsIF65SBEOVcYMGAEzO/kKNiNaW4LoWtoThOhH06gw==",
- "dependencies": {
- "@octokit/openapi-types": "^16.0.0"
- }
- },
- "node_modules/@octokit/plugin-throttling": {
- "version": "4.3.2",
- "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-4.3.2.tgz",
- "integrity": "sha512-ZaCK599h3tzcoy0Jtdab95jgmD7X9iAk59E2E7hYKCAmnURaI4WpzwL9vckImilybUGrjY1JOWJapDs2N2D3vw==",
- "dependencies": {
- "@octokit/types": "^8.0.0",
- "bottleneck": "^2.15.3"
- },
- "engines": {
- "node": ">= 14"
- },
- "peerDependencies": {
- "@octokit/core": "^4.0.0"
- }
- },
- "node_modules/@octokit/request": {
- "version": "6.2.2",
- "resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.2.tgz",
- "integrity": "sha512-6VDqgj0HMc2FUX2awIs+sM6OwLgwHvAi4KCK3mT2H2IKRt6oH9d0fej5LluF5mck1lRR/rFWN0YIDSYXYSylbw==",
- "dependencies": {
- "@octokit/endpoint": "^7.0.0",
- "@octokit/request-error": "^3.0.0",
- "@octokit/types": "^8.0.0",
- "is-plain-object": "^5.0.0",
- "node-fetch": "^2.6.7",
- "universal-user-agent": "^6.0.0"
- },
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/@octokit/request-error": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-3.0.3.tgz",
- "integrity": "sha512-crqw3V5Iy2uOU5Np+8M/YexTlT8zxCfI+qu+LxUB7SZpje4Qmx3mub5DfEKSO8Ylyk0aogi6TYdf6kxzh2BguQ==",
- "dependencies": {
- "@octokit/types": "^9.0.0",
- "deprecation": "^2.0.0",
- "once": "^1.4.0"
- },
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/@octokit/request-error/node_modules/@octokit/openapi-types": {
- "version": "16.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-16.0.0.tgz",
- "integrity": "sha512-JbFWOqTJVLHZSUUoF4FzAZKYtqdxWu9Z5m2QQnOyEa04fOFljvyh7D3GYKbfuaSWisqehImiVIMG4eyJeP5VEA=="
- },
- "node_modules/@octokit/request-error/node_modules/@octokit/types": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.0.0.tgz",
- "integrity": "sha512-LUewfj94xCMH2rbD5YJ+6AQ4AVjFYTgpp6rboWM5T7N3IsIF65SBEOVcYMGAEzO/kKNiNaW4LoWtoThOhH06gw==",
- "dependencies": {
- "@octokit/openapi-types": "^16.0.0"
- }
- },
- "node_modules/@octokit/types": {
- "version": "8.2.1",
- "resolved": "https://registry.npmjs.org/@octokit/types/-/types-8.2.1.tgz",
- "integrity": "sha512-8oWMUji8be66q2B9PmEIUyQm00VPDPun07umUWSaCwxmeaquFBro4Hcc3ruVoDo3zkQyZBlRvhIMEYS3pBhanw==",
- "dependencies": {
- "@octokit/openapi-types": "^14.0.0"
- }
- },
- "node_modules/@octokit/webhooks": {
- "version": "10.7.0",
- "resolved": "https://registry.npmjs.org/@octokit/webhooks/-/webhooks-10.7.0.tgz",
- "integrity": "sha512-zZBbQMpXXnK/ki/utrFG/TuWv9545XCSLibfDTxrYqR1PmU6zel02ebTOrA7t5XIGHzlEOc/NgISUIBUe7pMFA==",
- "dependencies": {
- "@octokit/request-error": "^3.0.0",
- "@octokit/webhooks-methods": "^3.0.0",
- "@octokit/webhooks-types": "6.10.0",
- "aggregate-error": "^3.1.0"
- },
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/@octokit/webhooks-methods": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/@octokit/webhooks-methods/-/webhooks-methods-3.0.2.tgz",
- "integrity": "sha512-Vlnv5WBscf07tyAvfDbp7pTkMZUwk7z7VwEF32x6HqI+55QRwBTcT+D7DDjZXtad/1dU9E32x0HmtDlF9VIRaQ==",
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/@octokit/webhooks-types": {
- "version": "6.10.0",
- "resolved": "https://registry.npmjs.org/@octokit/webhooks-types/-/webhooks-types-6.10.0.tgz",
- "integrity": "sha512-lDNv83BeEyxxukdQ0UttiUXawk9+6DkdjjFtm2GFED+24IQhTVaoSbwV9vWWKONyGLzRmCQqZmoEWkDhkEmPlw=="
- },
"node_modules/@openapitools/openapi-generator-cli": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/@openapitools/openapi-generator-cli/-/openapi-generator-cli-2.6.0.tgz",
@@ -2028,16 +1576,6 @@
"node": ">= 6"
}
},
- "node_modules/@types/aws-lambda": {
- "version": "8.10.109",
- "resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.109.tgz",
- "integrity": "sha512-/ME92FneNyXQzrAfcnQQlW1XkCZGPDlpi2ao1MJwecN+6SbeonKeggU8eybv1DfKli90FAVT1MlIZVXfwVuCyg=="
- },
- "node_modules/@types/btoa-lite": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/@types/btoa-lite/-/btoa-lite-1.0.0.tgz",
- "integrity": "sha512-wJsiX1tosQ+J5+bY5LrSahHxr2wT+uME5UDwdN1kg4frt40euqA+wzECkmq4t5QbveHiJepfdThgQrPw6KiSlg=="
- },
"node_modules/@types/cacheable-request": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz",
@@ -2095,14 +1633,6 @@
"integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==",
"dev": true
},
- "node_modules/@types/jsonwebtoken": {
- "version": "9.0.1",
- "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.1.tgz",
- "integrity": "sha512-c5ltxazpWabia/4UzhIoaDcIza4KViOQhdbjRlfcIGVnsE3c3brkz9Z+F/EeJIECOQP7W7US2hNE930cWWkPiw==",
- "dependencies": {
- "@types/node": "*"
- }
- },
"node_modules/@types/keyv": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz",
@@ -2117,11 +1647,6 @@
"integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==",
"dev": true
},
- "node_modules/@types/lru-cache": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz",
- "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw=="
- },
"node_modules/@types/mdast": {
"version": "3.0.11",
"resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.11.tgz",
@@ -2760,11 +2285,6 @@
}
]
},
- "node_modules/before-after-hook": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz",
- "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ=="
- },
"node_modules/big-integer": {
"version": "1.6.51",
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz",
@@ -2830,11 +2350,6 @@
"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
"dev": true
},
- "node_modules/bottleneck": {
- "version": "2.19.5",
- "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz",
- "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw=="
- },
"node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -2861,11 +2376,6 @@
"integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
"dev": true
},
- "node_modules/btoa-lite": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz",
- "integrity": "sha512-gvW7InbIyF8AicrqWoptdW08pUxuhq8BEgowNajy9RhiE86fmGAGl+bLKo6oB8QP0CkqHLowfN0oJdKC/J6LbA=="
- },
"node_modules/buffer": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
@@ -2898,11 +2408,6 @@
"node": "*"
}
},
- "node_modules/buffer-equal-constant-time": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
- "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
- },
"node_modules/buffer-indexof-polyfill": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz",
@@ -3643,11 +3148,6 @@
"node": ">= 0.6"
}
},
- "node_modules/deprecation": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
- "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
- },
"node_modules/dequal": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
@@ -3787,14 +3287,6 @@
"wcwidth": ">=1.0.1"
}
},
- "node_modules/ecdsa-sig-formatter": {
- "version": "1.0.11",
- "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
- "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
- "dependencies": {
- "safe-buffer": "^5.0.1"
- }
- },
"node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
@@ -4443,25 +3935,6 @@
"node": ">= 6"
}
},
- "node_modules/fromentries": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz",
- "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ]
- },
"node_modules/fs-constants": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
@@ -5201,14 +4674,6 @@
"node": ">=8"
}
},
- "node_modules/is-plain-object": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
- "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/is-promise": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz",
@@ -5410,40 +4875,6 @@
"graceful-fs": "^4.1.6"
}
},
- "node_modules/jsonwebtoken": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz",
- "integrity": "sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==",
- "dependencies": {
- "jws": "^3.2.2",
- "lodash": "^4.17.21",
- "ms": "^2.1.1",
- "semver": "^7.3.8"
- },
- "engines": {
- "node": ">=12",
- "npm": ">=6"
- }
- },
- "node_modules/jwa": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
- "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
- "dependencies": {
- "buffer-equal-constant-time": "1.0.1",
- "ecdsa-sig-formatter": "1.0.11",
- "safe-buffer": "^5.0.1"
- }
- },
- "node_modules/jws": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
- "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
- "dependencies": {
- "jwa": "^1.4.1",
- "safe-buffer": "^5.0.1"
- }
- },
"node_modules/keytar": {
"version": "7.9.0",
"resolved": "https://registry.npmjs.org/keytar/-/keytar-7.9.0.tgz",
@@ -6782,24 +6213,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/octokit": {
- "version": "2.0.11",
- "resolved": "https://registry.npmjs.org/octokit/-/octokit-2.0.11.tgz",
- "integrity": "sha512-Ivjapy5RXWvJfmZe0BvfMM2gnNi39rjheZV/s3SjICb7gfl83JWPDmBERe4f/l2czdRnj4NVIn4YO7Q737oLCg==",
- "dependencies": {
- "@octokit/app": "^13.1.1",
- "@octokit/core": "^4.0.4",
- "@octokit/oauth-app": "^4.0.6",
- "@octokit/plugin-paginate-rest": "^5.0.0",
- "@octokit/plugin-rest-endpoint-methods": "^6.0.0",
- "@octokit/plugin-retry": "^4.0.3",
- "@octokit/plugin-throttling": "^4.0.1",
- "@octokit/types": "^8.0.0"
- },
- "engines": {
- "node": ">= 14"
- }
- },
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
@@ -7836,6 +7249,7 @@
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true,
"funding": [
{
"type": "github",
@@ -8119,9 +7533,9 @@
}
},
"node_modules/strip-ansi": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz",
- "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==",
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+ "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
"dependencies": {
"ansi-regex": "^6.0.1"
},
@@ -8758,20 +8172,6 @@
"url": "https://opencollective.com/unified"
}
},
- "node_modules/universal-github-app-jwt": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/universal-github-app-jwt/-/universal-github-app-jwt-1.1.1.tgz",
- "integrity": "sha512-G33RTLrIBMFmlDV4u4CBF7dh71eWwykck4XgaxaIVeZKOYZRAAxvcGMRFTUclVY6xoUPQvO4Ne5wKGxYm/Yy9w==",
- "dependencies": {
- "@types/jsonwebtoken": "^9.0.0",
- "jsonwebtoken": "^9.0.0"
- }
- },
- "node_modules/universal-user-agent": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
- "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
- },
"node_modules/universalify": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
@@ -10018,394 +9418,6 @@
"node-fetch": "^2.6.1"
}
},
- "@octokit/app": {
- "version": "13.1.2",
- "resolved": "https://registry.npmjs.org/@octokit/app/-/app-13.1.2.tgz",
- "integrity": "sha512-Kf+h5sa1SOI33hFsuHvTsWj1jUrjp1x4MuiJBq7U/NicfEGa6nArPUoDnyfP/YTmcQ5cQ5yvOgoIBkbwPg6kzQ==",
- "requires": {
- "@octokit/auth-app": "^4.0.8",
- "@octokit/auth-unauthenticated": "^3.0.0",
- "@octokit/core": "^4.0.0",
- "@octokit/oauth-app": "^4.0.7",
- "@octokit/plugin-paginate-rest": "^6.0.0",
- "@octokit/types": "^9.0.0",
- "@octokit/webhooks": "^10.0.0"
- },
- "dependencies": {
- "@octokit/openapi-types": {
- "version": "16.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-16.0.0.tgz",
- "integrity": "sha512-JbFWOqTJVLHZSUUoF4FzAZKYtqdxWu9Z5m2QQnOyEa04fOFljvyh7D3GYKbfuaSWisqehImiVIMG4eyJeP5VEA=="
- },
- "@octokit/plugin-paginate-rest": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.0.0.tgz",
- "integrity": "sha512-Sq5VU1PfT6/JyuXPyt04KZNVsFOSBaYOAq2QRZUwzVlI10KFvcbUo8lR258AAQL1Et60b0WuVik+zOWKLuDZxw==",
- "requires": {
- "@octokit/types": "^9.0.0"
- }
- },
- "@octokit/types": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.0.0.tgz",
- "integrity": "sha512-LUewfj94xCMH2rbD5YJ+6AQ4AVjFYTgpp6rboWM5T7N3IsIF65SBEOVcYMGAEzO/kKNiNaW4LoWtoThOhH06gw==",
- "requires": {
- "@octokit/openapi-types": "^16.0.0"
- }
- }
- }
- },
- "@octokit/auth-app": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/@octokit/auth-app/-/auth-app-4.0.8.tgz",
- "integrity": "sha512-miI7y9FfS/fL1bSPsDaAfCGSxQ04iGLyisI2GA8N7P6eB6AkCOt+F1XXapJKRnAubQubvYF0dqxoTZYyKk93NQ==",
- "requires": {
- "@octokit/auth-oauth-app": "^5.0.0",
- "@octokit/auth-oauth-user": "^2.0.0",
- "@octokit/request": "^6.0.0",
- "@octokit/request-error": "^3.0.0",
- "@octokit/types": "^8.0.0",
- "@types/lru-cache": "^5.1.0",
- "deprecation": "^2.3.1",
- "lru-cache": "^6.0.0",
- "universal-github-app-jwt": "^1.1.1",
- "universal-user-agent": "^6.0.0"
- }
- },
- "@octokit/auth-oauth-app": {
- "version": "5.0.5",
- "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-app/-/auth-oauth-app-5.0.5.tgz",
- "integrity": "sha512-UPX1su6XpseaeLVCi78s9droxpGtBWIgz9XhXAx9VXabksoF0MyI5vaa1zo1njyYt6VaAjFisC2A2Wchcu2WmQ==",
- "requires": {
- "@octokit/auth-oauth-device": "^4.0.0",
- "@octokit/auth-oauth-user": "^2.0.0",
- "@octokit/request": "^6.0.0",
- "@octokit/types": "^9.0.0",
- "@types/btoa-lite": "^1.0.0",
- "btoa-lite": "^1.0.0",
- "universal-user-agent": "^6.0.0"
- },
- "dependencies": {
- "@octokit/openapi-types": {
- "version": "16.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-16.0.0.tgz",
- "integrity": "sha512-JbFWOqTJVLHZSUUoF4FzAZKYtqdxWu9Z5m2QQnOyEa04fOFljvyh7D3GYKbfuaSWisqehImiVIMG4eyJeP5VEA=="
- },
- "@octokit/types": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.0.0.tgz",
- "integrity": "sha512-LUewfj94xCMH2rbD5YJ+6AQ4AVjFYTgpp6rboWM5T7N3IsIF65SBEOVcYMGAEzO/kKNiNaW4LoWtoThOhH06gw==",
- "requires": {
- "@octokit/openapi-types": "^16.0.0"
- }
- }
- }
- },
- "@octokit/auth-oauth-device": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-device/-/auth-oauth-device-4.0.3.tgz",
- "integrity": "sha512-KPTx5nMntKjNZzzltO3X4T68v22rd7Cp/TcLJXQE2U8aXPcZ9LFuww9q9Q5WUNSu3jwi3lRwzfkPguRfz1R8Vg==",
- "requires": {
- "@octokit/oauth-methods": "^2.0.0",
- "@octokit/request": "^6.0.0",
- "@octokit/types": "^8.0.0",
- "universal-user-agent": "^6.0.0"
- }
- },
- "@octokit/auth-oauth-user": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-user/-/auth-oauth-user-2.1.0.tgz",
- "integrity": "sha512-TC2Mj8NkSy9uAnZLYX+FKB/IH6uDe+qYNzHzH8l13JlzsrTE7GKkcqtXdSGGN4tncyROAB4/KS5rDPRCEnWHlA==",
- "requires": {
- "@octokit/auth-oauth-device": "^4.0.0",
- "@octokit/oauth-methods": "^2.0.0",
- "@octokit/request": "^6.0.0",
- "@octokit/types": "^8.0.0",
- "btoa-lite": "^1.0.0",
- "universal-user-agent": "^6.0.0"
- }
- },
- "@octokit/auth-token": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.3.tgz",
- "integrity": "sha512-/aFM2M4HVDBT/jjDBa84sJniv1t9Gm/rLkalaz9htOm+L+8JMj1k9w0CkUdcxNyNxZPlTxKPVko+m1VlM58ZVA==",
- "requires": {
- "@octokit/types": "^9.0.0"
- },
- "dependencies": {
- "@octokit/openapi-types": {
- "version": "16.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-16.0.0.tgz",
- "integrity": "sha512-JbFWOqTJVLHZSUUoF4FzAZKYtqdxWu9Z5m2QQnOyEa04fOFljvyh7D3GYKbfuaSWisqehImiVIMG4eyJeP5VEA=="
- },
- "@octokit/types": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.0.0.tgz",
- "integrity": "sha512-LUewfj94xCMH2rbD5YJ+6AQ4AVjFYTgpp6rboWM5T7N3IsIF65SBEOVcYMGAEzO/kKNiNaW4LoWtoThOhH06gw==",
- "requires": {
- "@octokit/openapi-types": "^16.0.0"
- }
- }
- }
- },
- "@octokit/auth-unauthenticated": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/@octokit/auth-unauthenticated/-/auth-unauthenticated-3.0.4.tgz",
- "integrity": "sha512-AT74XGBylcLr4lmUp1s6mjSUgphGdlse21Qjtv5DzpX1YOl5FXKwvNcZWESdhyBbpDT8VkVyLFqa/7a7eqpPNw==",
- "requires": {
- "@octokit/request-error": "^3.0.0",
- "@octokit/types": "^9.0.0"
- },
- "dependencies": {
- "@octokit/openapi-types": {
- "version": "16.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-16.0.0.tgz",
- "integrity": "sha512-JbFWOqTJVLHZSUUoF4FzAZKYtqdxWu9Z5m2QQnOyEa04fOFljvyh7D3GYKbfuaSWisqehImiVIMG4eyJeP5VEA=="
- },
- "@octokit/types": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.0.0.tgz",
- "integrity": "sha512-LUewfj94xCMH2rbD5YJ+6AQ4AVjFYTgpp6rboWM5T7N3IsIF65SBEOVcYMGAEzO/kKNiNaW4LoWtoThOhH06gw==",
- "requires": {
- "@octokit/openapi-types": "^16.0.0"
- }
- }
- }
- },
- "@octokit/core": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.0.tgz",
- "integrity": "sha512-AgvDRUg3COpR82P7PBdGZF/NNqGmtMq2NiPqeSsDIeCfYFOZ9gddqWNQHnFdEUf+YwOj4aZYmJnlPp7OXmDIDg==",
- "requires": {
- "@octokit/auth-token": "^3.0.0",
- "@octokit/graphql": "^5.0.0",
- "@octokit/request": "^6.0.0",
- "@octokit/request-error": "^3.0.0",
- "@octokit/types": "^9.0.0",
- "before-after-hook": "^2.2.0",
- "universal-user-agent": "^6.0.0"
- },
- "dependencies": {
- "@octokit/openapi-types": {
- "version": "16.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-16.0.0.tgz",
- "integrity": "sha512-JbFWOqTJVLHZSUUoF4FzAZKYtqdxWu9Z5m2QQnOyEa04fOFljvyh7D3GYKbfuaSWisqehImiVIMG4eyJeP5VEA=="
- },
- "@octokit/types": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.0.0.tgz",
- "integrity": "sha512-LUewfj94xCMH2rbD5YJ+6AQ4AVjFYTgpp6rboWM5T7N3IsIF65SBEOVcYMGAEzO/kKNiNaW4LoWtoThOhH06gw==",
- "requires": {
- "@octokit/openapi-types": "^16.0.0"
- }
- }
- }
- },
- "@octokit/endpoint": {
- "version": "7.0.4",
- "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.4.tgz",
- "integrity": "sha512-hXJP43VT2IrUxBCNIahta8qawpIzLvCjHLCuDDsdIPbd6+jPwsc3KGl/kdQ37mLd+sdiJm6c9qKI7k5CjE0Z9A==",
- "requires": {
- "@octokit/types": "^9.0.0",
- "is-plain-object": "^5.0.0",
- "universal-user-agent": "^6.0.0"
- },
- "dependencies": {
- "@octokit/openapi-types": {
- "version": "16.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-16.0.0.tgz",
- "integrity": "sha512-JbFWOqTJVLHZSUUoF4FzAZKYtqdxWu9Z5m2QQnOyEa04fOFljvyh7D3GYKbfuaSWisqehImiVIMG4eyJeP5VEA=="
- },
- "@octokit/types": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.0.0.tgz",
- "integrity": "sha512-LUewfj94xCMH2rbD5YJ+6AQ4AVjFYTgpp6rboWM5T7N3IsIF65SBEOVcYMGAEzO/kKNiNaW4LoWtoThOhH06gw==",
- "requires": {
- "@octokit/openapi-types": "^16.0.0"
- }
- }
- }
- },
- "@octokit/graphql": {
- "version": "5.0.5",
- "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.5.tgz",
- "integrity": "sha512-Qwfvh3xdqKtIznjX9lz2D458r7dJPP8l6r4GQkIdWQouZwHQK0mVT88uwiU2bdTU2OtT1uOlKpRciUWldpG0yQ==",
- "requires": {
- "@octokit/request": "^6.0.0",
- "@octokit/types": "^9.0.0",
- "universal-user-agent": "^6.0.0"
- },
- "dependencies": {
- "@octokit/openapi-types": {
- "version": "16.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-16.0.0.tgz",
- "integrity": "sha512-JbFWOqTJVLHZSUUoF4FzAZKYtqdxWu9Z5m2QQnOyEa04fOFljvyh7D3GYKbfuaSWisqehImiVIMG4eyJeP5VEA=="
- },
- "@octokit/types": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.0.0.tgz",
- "integrity": "sha512-LUewfj94xCMH2rbD5YJ+6AQ4AVjFYTgpp6rboWM5T7N3IsIF65SBEOVcYMGAEzO/kKNiNaW4LoWtoThOhH06gw==",
- "requires": {
- "@octokit/openapi-types": "^16.0.0"
- }
- }
- }
- },
- "@octokit/oauth-app": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/@octokit/oauth-app/-/oauth-app-4.2.0.tgz",
- "integrity": "sha512-gyGclT77RQMkVUEW3YBeAKY+LBSc5u3eC9Wn/Uwt3WhuKuu9mrV18EnNpDqmeNll+mdV02yyBROU29Tlili6gg==",
- "requires": {
- "@octokit/auth-oauth-app": "^5.0.0",
- "@octokit/auth-oauth-user": "^2.0.0",
- "@octokit/auth-unauthenticated": "^3.0.0",
- "@octokit/core": "^4.0.0",
- "@octokit/oauth-authorization-url": "^5.0.0",
- "@octokit/oauth-methods": "^2.0.0",
- "@types/aws-lambda": "^8.10.83",
- "fromentries": "^1.3.1",
- "universal-user-agent": "^6.0.0"
- }
- },
- "@octokit/oauth-authorization-url": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/oauth-authorization-url/-/oauth-authorization-url-5.0.0.tgz",
- "integrity": "sha512-y1WhN+ERDZTh0qZ4SR+zotgsQUE1ysKnvBt1hvDRB2WRzYtVKQjn97HEPzoehh66Fj9LwNdlZh+p6TJatT0zzg=="
- },
- "@octokit/oauth-methods": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/@octokit/oauth-methods/-/oauth-methods-2.0.4.tgz",
- "integrity": "sha512-RDSa6XL+5waUVrYSmOlYROtPq0+cfwppP4VaQY/iIei3xlFb0expH6YNsxNrZktcLhJWSpm9uzeom+dQrXlS3A==",
- "requires": {
- "@octokit/oauth-authorization-url": "^5.0.0",
- "@octokit/request": "^6.0.0",
- "@octokit/request-error": "^3.0.0",
- "@octokit/types": "^8.0.0",
- "btoa-lite": "^1.0.0"
- }
- },
- "@octokit/openapi-types": {
- "version": "14.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-14.0.0.tgz",
- "integrity": "sha512-HNWisMYlR8VCnNurDU6os2ikx0s0VyEjDYHNS/h4cgb8DeOxQ0n72HyinUtdDVxJhFy3FWLGl0DJhfEWk3P5Iw=="
- },
- "@octokit/plugin-paginate-rest": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-5.0.1.tgz",
- "integrity": "sha512-7A+rEkS70pH36Z6JivSlR7Zqepz3KVucEFVDnSrgHXzG7WLAzYwcHZbKdfTXHwuTHbkT1vKvz7dHl1+HNf6Qyw==",
- "requires": {
- "@octokit/types": "^8.0.0"
- }
- },
- "@octokit/plugin-rest-endpoint-methods": {
- "version": "6.8.1",
- "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-6.8.1.tgz",
- "integrity": "sha512-QrlaTm8Lyc/TbU7BL/8bO49vp+RZ6W3McxxmmQTgYxf2sWkO8ZKuj4dLhPNJD6VCUW1hetCmeIM0m6FTVpDiEg==",
- "requires": {
- "@octokit/types": "^8.1.1",
- "deprecation": "^2.3.1"
- }
- },
- "@octokit/plugin-retry": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-4.0.4.tgz",
- "integrity": "sha512-d7qGFLR3AH+WbNEDUvBPgMc7wRCxU40FZyNXFFqs8ISw75ZYS5/P3ScggzU13dCoY0aywYDxKugGstQTwNgppA==",
- "requires": {
- "@octokit/types": "^9.0.0",
- "bottleneck": "^2.15.3"
- },
- "dependencies": {
- "@octokit/openapi-types": {
- "version": "16.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-16.0.0.tgz",
- "integrity": "sha512-JbFWOqTJVLHZSUUoF4FzAZKYtqdxWu9Z5m2QQnOyEa04fOFljvyh7D3GYKbfuaSWisqehImiVIMG4eyJeP5VEA=="
- },
- "@octokit/types": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.0.0.tgz",
- "integrity": "sha512-LUewfj94xCMH2rbD5YJ+6AQ4AVjFYTgpp6rboWM5T7N3IsIF65SBEOVcYMGAEzO/kKNiNaW4LoWtoThOhH06gw==",
- "requires": {
- "@octokit/openapi-types": "^16.0.0"
- }
- }
- }
- },
- "@octokit/plugin-throttling": {
- "version": "4.3.2",
- "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-4.3.2.tgz",
- "integrity": "sha512-ZaCK599h3tzcoy0Jtdab95jgmD7X9iAk59E2E7hYKCAmnURaI4WpzwL9vckImilybUGrjY1JOWJapDs2N2D3vw==",
- "requires": {
- "@octokit/types": "^8.0.0",
- "bottleneck": "^2.15.3"
- }
- },
- "@octokit/request": {
- "version": "6.2.2",
- "resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.2.tgz",
- "integrity": "sha512-6VDqgj0HMc2FUX2awIs+sM6OwLgwHvAi4KCK3mT2H2IKRt6oH9d0fej5LluF5mck1lRR/rFWN0YIDSYXYSylbw==",
- "requires": {
- "@octokit/endpoint": "^7.0.0",
- "@octokit/request-error": "^3.0.0",
- "@octokit/types": "^8.0.0",
- "is-plain-object": "^5.0.0",
- "node-fetch": "^2.6.7",
- "universal-user-agent": "^6.0.0"
- }
- },
- "@octokit/request-error": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-3.0.3.tgz",
- "integrity": "sha512-crqw3V5Iy2uOU5Np+8M/YexTlT8zxCfI+qu+LxUB7SZpje4Qmx3mub5DfEKSO8Ylyk0aogi6TYdf6kxzh2BguQ==",
- "requires": {
- "@octokit/types": "^9.0.0",
- "deprecation": "^2.0.0",
- "once": "^1.4.0"
- },
- "dependencies": {
- "@octokit/openapi-types": {
- "version": "16.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-16.0.0.tgz",
- "integrity": "sha512-JbFWOqTJVLHZSUUoF4FzAZKYtqdxWu9Z5m2QQnOyEa04fOFljvyh7D3GYKbfuaSWisqehImiVIMG4eyJeP5VEA=="
- },
- "@octokit/types": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.0.0.tgz",
- "integrity": "sha512-LUewfj94xCMH2rbD5YJ+6AQ4AVjFYTgpp6rboWM5T7N3IsIF65SBEOVcYMGAEzO/kKNiNaW4LoWtoThOhH06gw==",
- "requires": {
- "@octokit/openapi-types": "^16.0.0"
- }
- }
- }
- },
- "@octokit/types": {
- "version": "8.2.1",
- "resolved": "https://registry.npmjs.org/@octokit/types/-/types-8.2.1.tgz",
- "integrity": "sha512-8oWMUji8be66q2B9PmEIUyQm00VPDPun07umUWSaCwxmeaquFBro4Hcc3ruVoDo3zkQyZBlRvhIMEYS3pBhanw==",
- "requires": {
- "@octokit/openapi-types": "^14.0.0"
- }
- },
- "@octokit/webhooks": {
- "version": "10.7.0",
- "resolved": "https://registry.npmjs.org/@octokit/webhooks/-/webhooks-10.7.0.tgz",
- "integrity": "sha512-zZBbQMpXXnK/ki/utrFG/TuWv9545XCSLibfDTxrYqR1PmU6zel02ebTOrA7t5XIGHzlEOc/NgISUIBUe7pMFA==",
- "requires": {
- "@octokit/request-error": "^3.0.0",
- "@octokit/webhooks-methods": "^3.0.0",
- "@octokit/webhooks-types": "6.10.0",
- "aggregate-error": "^3.1.0"
- }
- },
- "@octokit/webhooks-methods": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/@octokit/webhooks-methods/-/webhooks-methods-3.0.2.tgz",
- "integrity": "sha512-Vlnv5WBscf07tyAvfDbp7pTkMZUwk7z7VwEF32x6HqI+55QRwBTcT+D7DDjZXtad/1dU9E32x0HmtDlF9VIRaQ=="
- },
- "@octokit/webhooks-types": {
- "version": "6.10.0",
- "resolved": "https://registry.npmjs.org/@octokit/webhooks-types/-/webhooks-types-6.10.0.tgz",
- "integrity": "sha512-lDNv83BeEyxxukdQ0UttiUXawk9+6DkdjjFtm2GFED+24IQhTVaoSbwV9vWWKONyGLzRmCQqZmoEWkDhkEmPlw=="
- },
"@openapitools/openapi-generator-cli": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/@openapitools/openapi-generator-cli/-/openapi-generator-cli-2.6.0.tgz",
@@ -10658,16 +9670,6 @@
"integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==",
"dev": true
},
- "@types/aws-lambda": {
- "version": "8.10.109",
- "resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.109.tgz",
- "integrity": "sha512-/ME92FneNyXQzrAfcnQQlW1XkCZGPDlpi2ao1MJwecN+6SbeonKeggU8eybv1DfKli90FAVT1MlIZVXfwVuCyg=="
- },
- "@types/btoa-lite": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/@types/btoa-lite/-/btoa-lite-1.0.0.tgz",
- "integrity": "sha512-wJsiX1tosQ+J5+bY5LrSahHxr2wT+uME5UDwdN1kg4frt40euqA+wzECkmq4t5QbveHiJepfdThgQrPw6KiSlg=="
- },
"@types/cacheable-request": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz",
@@ -10725,14 +9727,6 @@
"integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==",
"dev": true
},
- "@types/jsonwebtoken": {
- "version": "9.0.1",
- "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.1.tgz",
- "integrity": "sha512-c5ltxazpWabia/4UzhIoaDcIza4KViOQhdbjRlfcIGVnsE3c3brkz9Z+F/EeJIECOQP7W7US2hNE930cWWkPiw==",
- "requires": {
- "@types/node": "*"
- }
- },
"@types/keyv": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz",
@@ -10747,11 +9741,6 @@
"integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==",
"dev": true
},
- "@types/lru-cache": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz",
- "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw=="
- },
"@types/mdast": {
"version": "3.0.11",
"resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.11.tgz",
@@ -11217,11 +10206,6 @@
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
},
- "before-after-hook": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz",
- "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ=="
- },
"big-integer": {
"version": "1.6.51",
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz",
@@ -11277,11 +10261,6 @@
"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
"dev": true
},
- "bottleneck": {
- "version": "2.19.5",
- "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz",
- "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw=="
- },
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -11305,11 +10284,6 @@
"integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
"dev": true
},
- "btoa-lite": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz",
- "integrity": "sha512-gvW7InbIyF8AicrqWoptdW08pUxuhq8BEgowNajy9RhiE86fmGAGl+bLKo6oB8QP0CkqHLowfN0oJdKC/J6LbA=="
- },
"buffer": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
@@ -11325,11 +10299,6 @@
"integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
"dev": true
},
- "buffer-equal-constant-time": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
- "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
- },
"buffer-indexof-polyfill": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz",
@@ -11862,11 +10831,6 @@
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
"integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ=="
},
- "deprecation": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
- "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
- },
"dequal": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
@@ -11970,14 +10934,6 @@
"wcwidth": ">=1.0.1"
}
},
- "ecdsa-sig-formatter": {
- "version": "1.0.11",
- "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
- "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
- "requires": {
- "safe-buffer": "^5.0.1"
- }
- },
"emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
@@ -12488,11 +11444,6 @@
"mime-types": "^2.1.12"
}
},
- "fromentries": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz",
- "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg=="
- },
"fs-constants": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
@@ -13030,11 +11981,6 @@
"integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
"dev": true
},
- "is-plain-object": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
- "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
- },
"is-promise": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz",
@@ -13183,36 +12129,6 @@
"universalify": "^2.0.0"
}
},
- "jsonwebtoken": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz",
- "integrity": "sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==",
- "requires": {
- "jws": "^3.2.2",
- "lodash": "^4.17.21",
- "ms": "^2.1.1",
- "semver": "^7.3.8"
- }
- },
- "jwa": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
- "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
- "requires": {
- "buffer-equal-constant-time": "1.0.1",
- "ecdsa-sig-formatter": "1.0.11",
- "safe-buffer": "^5.0.1"
- }
- },
- "jws": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
- "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
- "requires": {
- "jwa": "^1.4.1",
- "safe-buffer": "^5.0.1"
- }
- },
"keytar": {
"version": "7.9.0",
"resolved": "https://registry.npmjs.org/keytar/-/keytar-7.9.0.tgz",
@@ -14121,21 +13037,6 @@
"integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==",
"dev": true
},
- "octokit": {
- "version": "2.0.11",
- "resolved": "https://registry.npmjs.org/octokit/-/octokit-2.0.11.tgz",
- "integrity": "sha512-Ivjapy5RXWvJfmZe0BvfMM2gnNi39rjheZV/s3SjICb7gfl83JWPDmBERe4f/l2czdRnj4NVIn4YO7Q737oLCg==",
- "requires": {
- "@octokit/app": "^13.1.1",
- "@octokit/core": "^4.0.4",
- "@octokit/oauth-app": "^4.0.6",
- "@octokit/plugin-paginate-rest": "^5.0.0",
- "@octokit/plugin-rest-endpoint-methods": "^6.0.0",
- "@octokit/plugin-retry": "^4.0.3",
- "@octokit/plugin-throttling": "^4.0.1",
- "@octokit/types": "^8.0.0"
- }
- },
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
@@ -14844,7 +13745,8 @@
"safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
- "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true
},
"safer-buffer": {
"version": "2.1.2",
@@ -15042,9 +13944,9 @@
}
},
"strip-ansi": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz",
- "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==",
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+ "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
"requires": {
"ansi-regex": "^6.0.1"
}
@@ -15516,20 +14418,6 @@
"unist-util-is": "^5.0.0"
}
},
- "universal-github-app-jwt": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/universal-github-app-jwt/-/universal-github-app-jwt-1.1.1.tgz",
- "integrity": "sha512-G33RTLrIBMFmlDV4u4CBF7dh71eWwykck4XgaxaIVeZKOYZRAAxvcGMRFTUclVY6xoUPQvO4Ne5wKGxYm/Yy9w==",
- "requires": {
- "@types/jsonwebtoken": "^9.0.0",
- "jsonwebtoken": "^9.0.0"
- }
- },
- "universal-user-agent": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
- "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
- },
"universalify": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
diff --git a/extension/package.json b/extension/package.json
index 7bd48f98..c979a435 100644
--- a/extension/package.json
+++ b/extension/package.json
@@ -14,7 +14,7 @@
"displayName": "Continue",
"pricing": "Free",
"description": "Refine code 10x faster",
- "version": "0.0.20",
+ "version": "0.0.23",
"publisher": "Continue",
"engines": {
"vscode": "^1.74.0"
@@ -42,12 +42,12 @@
"description": "The URL of the Continue server to use."
},
"continue.OPENAI_API_KEY": {
- "type": "string",
+ "type": "password",
"default": "",
"description": "The OpenAI API key to use for code generation."
},
"continue.HUGGING_FACE_TOKEN": {
- "type": "string",
+ "type": "password",
"default": "",
"description": "The Hugging Face API token to use for code generation."
}
@@ -169,7 +169,7 @@
"scripts": {
"vscode:prepublish": "npm run esbuild-base -- --minify",
"esbuild-base": "rm -rf ./out && esbuild ./src/extension.ts --bundle --outfile=out/extension.js --external:vscode --format=cjs --platform=node",
- "esbuild": "rm -rf ./out && npm run esbuild-base -- --sourcemap",
+ "esbuild": "rm -rf ./out && node esbuild.mjs",
"esbuild-watch": "npm run esbuild-base -- --sourcemap --watch",
"test-compile": "tsc -p ./",
"clientgen": "rm -rf src/client/ && npx @openapitools/openapi-generator-cli generate -i ../schema/openapi.json -g typescript-fetch -o src/client/ --additional-properties=supportsES6=true,npmVersion=8.19.2,typescriptThreePlus=true",
@@ -215,11 +215,10 @@
"@vitejs/plugin-react-swc": "^3.3.2",
"axios": "^1.2.5",
"highlight.js": "^11.7.0",
- "octokit": "^2.0.11",
"posthog-js": "^1.63.3",
"react-markdown": "^8.0.7",
"react-redux": "^8.0.5",
- "strip-ansi": "^7.0.1",
+ "strip-ansi": "^7.1.0",
"tailwindcss": "^3.3.2",
"vite": "^4.3.9",
"vscode-languageclient": "^8.0.2",
diff --git a/extension/react-app/src/components/ContinueButton.tsx b/extension/react-app/src/components/ContinueButton.tsx
index 11dc7a92..c6117bf9 100644
--- a/extension/react-app/src/components/ContinueButton.tsx
+++ b/extension/react-app/src/components/ContinueButton.tsx
@@ -24,9 +24,13 @@ let StyledButton = styled(Button)`
}
`;
-function ContinueButton(props: { onClick?: () => void }) {
+function ContinueButton(props: { onClick?: () => void; hidden?: boolean }) {
return (
- <StyledButton className="m-auto" onClick={props.onClick}>
+ <StyledButton
+ hidden={props.hidden}
+ className="m-auto"
+ onClick={props.onClick}
+ >
<Play />
{/* <img src={"/continue_arrow.png"} width="16px"></img> */}
Continue
diff --git a/extension/react-app/src/components/DebugPanel.tsx b/extension/react-app/src/components/DebugPanel.tsx
index 9dacc624..11ec2fe2 100644
--- a/extension/react-app/src/components/DebugPanel.tsx
+++ b/extension/react-app/src/components/DebugPanel.tsx
@@ -9,7 +9,7 @@ import {
} from "../redux/slices/configSlice";
import { setHighlightedCode } from "../redux/slices/miscSlice";
import { updateFileSystem } from "../redux/slices/debugContexSlice";
-import { buttonColor, defaultBorderRadius, vscBackground } from ".";
+import { defaultBorderRadius, secondaryDark, vscBackground } from ".";
interface DebugPanelProps {
tabs: {
element: React.ReactElement;
@@ -19,14 +19,15 @@ interface DebugPanelProps {
const GradientContainer = styled.div`
// Uncomment to get gradient border
- background: linear-gradient(
+ /* background: linear-gradient(
101.79deg,
#12887a 0%,
#87245c 37.64%,
#e12637 65.98%,
#ffb215 110.45%
- );
+ ); */
/* padding: 10px; */
+ background-color: ${secondaryDark};
margin: 0;
height: 100%;
/* border: 1px solid white; */
@@ -36,11 +37,8 @@ const GradientContainer = styled.div`
const MainDiv = styled.div`
height: 100%;
border-radius: ${defaultBorderRadius};
- overflow-y: scroll;
- scrollbar-gutter: stable both-edges;
scrollbar-base-color: transparent;
- /* background: ${vscBackground}; */
- background-color: #1e1e1ede;
+ background-color: ${vscBackground};
`;
const TabBar = styled.div<{ numTabs: number }>`
@@ -105,9 +103,6 @@ function DebugPanel(props: DebugPanelProps) {
<div
key={index}
hidden={index !== currentTab}
- className={
- tab.title === "Chat" ? "overflow-hidden" : "overflow-scroll"
- }
style={{ scrollbarGutter: "stable both-edges" }}
>
{tab.element}
diff --git a/extension/react-app/src/components/InputAndButton.tsx b/extension/react-app/src/components/InputAndButton.tsx
new file mode 100644
index 00000000..0a8592f2
--- /dev/null
+++ b/extension/react-app/src/components/InputAndButton.tsx
@@ -0,0 +1,77 @@
+import React, { useRef } from "react";
+import styled from "styled-components";
+import { vscBackground } from ".";
+
+interface InputAndButtonProps {
+ onUserInput: (input: string) => void;
+}
+
+const TopDiv = styled.div`
+ display: grid;
+ grid-template-columns: 3fr 1fr;
+ grid-gap: 0;
+`;
+
+const Input = styled.input`
+ padding: 0.5rem;
+ border: 1px solid white;
+ background-color: ${vscBackground};
+ color: white;
+ border-radius: 4px;
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+ outline: none;
+`;
+
+const Button = styled.button`
+ padding: 0.5rem;
+ border: 1px solid white;
+ background-color: ${vscBackground};
+ color: white;
+ border-radius: 4px;
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+ border-left: 0;
+ cursor: pointer;
+
+ &:hover {
+ background-color: white;
+ color: black;
+ }
+`;
+
+function InputAndButton(props: InputAndButtonProps) {
+ const userInputRef = useRef<HTMLInputElement>(null);
+
+ return (
+ <TopDiv className="grid grid-cols-2 space-x-0">
+ <Input
+ ref={userInputRef}
+ onKeyDown={(e) => {
+ if (e.key === "Enter") {
+ props.onUserInput(e.currentTarget.value);
+ }
+ }}
+ type="text"
+ onSubmit={(ev) => {
+ props.onUserInput(ev.currentTarget.value);
+ }}
+ onClick={(e) => {
+ e.stopPropagation();
+ }}
+ />
+ <Button
+ onClick={(e) => {
+ if (userInputRef.current) {
+ props.onUserInput(userInputRef.current.value);
+ }
+ e.stopPropagation();
+ }}
+ >
+ Enter
+ </Button>
+ </TopDiv>
+ );
+}
+
+export default InputAndButton;
diff --git a/extension/react-app/src/components/StepContainer.tsx b/extension/react-app/src/components/StepContainer.tsx
index 903f9b94..8ea54325 100644
--- a/extension/react-app/src/components/StepContainer.tsx
+++ b/extension/react-app/src/components/StepContainer.tsx
@@ -2,13 +2,11 @@ import { useCallback, useEffect, useRef, useState } from "react";
import styled, { keyframes } from "styled-components";
import {
appear,
- buttonColor,
defaultBorderRadius,
- MainContainerWithBorder,
- MainTextInput,
secondaryDark,
vscBackground,
GradientBorder,
+ vscBackgroundTransparent,
} from ".";
import { RangeInFile, FileEdit } from "../../../src/client";
import CodeBlock from "./CodeBlock";
@@ -23,6 +21,8 @@ import {
import { HistoryNode } from "../../../schema/HistoryNode";
import ReactMarkdown from "react-markdown";
import ContinueButton from "./ContinueButton";
+import InputAndButton from "./InputAndButton";
+import ToggleErrorDiv from "./ToggleErrorDiv";
interface StepContainerProps {
historyNode: HistoryNode;
@@ -31,6 +31,7 @@ interface StepContainerProps {
onRefinement: (input: string) => void;
onUserInput: (input: string) => void;
onRetry: () => void;
+ open?: boolean;
}
const MainDiv = styled.div<{ stepDepth: number; inFuture: boolean }>`
@@ -43,17 +44,26 @@ const MainDiv = styled.div<{ stepDepth: number; inFuture: boolean }>`
`;
const StepContainerDiv = styled.div<{ open: boolean }>`
- background-color: ${(props) => (props.open ? vscBackground : secondaryDark)};
- border-radius: ${defaultBorderRadius};
- padding: 8px;
+ /* background-color: ${(props) =>
+ props.open ? vscBackground : secondaryDark}; */
+ /* border-radius: ${defaultBorderRadius}; */
+ /* padding: 8px; */
`;
-const HeaderDiv = styled.div`
+const HeaderDiv = styled.div<{ error: boolean }>`
+ background-color: ${(props) =>
+ props.error ? "#522" : vscBackgroundTransparent};
display: grid;
grid-template-columns: 1fr auto;
align-items: center;
`;
+const ContentDiv = styled.div`
+ padding: 8px;
+ padding-left: 16px;
+ background-color: ${vscBackground};
+`;
+
const HeaderButton = styled.button`
background-color: transparent;
border: 1px solid white;
@@ -74,12 +84,10 @@ const OnHoverDiv = styled.div`
animation: ${appear} 0.3s ease-in-out;
`;
-const NaturalLanguageInput = styled(MainTextInput)`
- width: 80%;
-`;
-
function StepContainer(props: StepContainerProps) {
- const [open, setOpen] = useState(false);
+ const [open, setOpen] = useState(
+ typeof props.open === "undefined" ? true : props.open
+ );
const [isHovered, setIsHovered] = useState(false);
const naturalLanguageInputRef = useRef<HTMLTextAreaElement>(null);
const userInputRef = useRef<HTMLInputElement>(null);
@@ -115,19 +123,25 @@ function StepContainer(props: StepContainerProps) {
}}
hidden={props.historyNode.step.hide as any}
>
- <GradientBorder
- className="m-2 overflow-hidden cursor-pointer"
- onClick={() => setOpen((prev) => !prev)}
- >
- <StepContainerDiv open={open}>
- <HeaderDiv>
+ <StepContainerDiv open={open}>
+ <GradientBorder
+ borderColor={
+ props.historyNode.observation?.error ? "#f00" : undefined
+ }
+ className="overflow-hidden cursor-pointer"
+ onClick={() => setOpen((prev) => !prev)}
+ >
+ <HeaderDiv
+ error={props.historyNode.observation?.error ? true : false}
+ >
<h4 className="m-2">
{open ? (
<ChevronDown size="1.4em" />
) : (
<ChevronRight size="1.4em" />
)}
- {props.historyNode.step.name as any}:
+ {props.historyNode.observation?.title ||
+ (props.historyNode.step.name as any)}
</h4>
{/* <HeaderButton
onClick={(e) => {
@@ -151,8 +165,9 @@ function StepContainer(props: StepContainerProps) {
<></>
)}
</HeaderDiv>
-
- {open && (
+ </GradientBorder>
+ <ContentDiv hidden={!open}>
+ {open && false && (
<>
<pre className="overflow-scroll">
Step Details:
@@ -163,36 +178,21 @@ function StepContainer(props: StepContainerProps) {
)}
{props.historyNode.observation?.error ? (
- <>
- Error while running step:
- <br />
- <pre className="overflow-scroll">
- {props.historyNode.observation.error as string}
- </pre>
- </>
+ <pre className="overflow-x-scroll">
+ {props.historyNode.observation.error as string}
+ </pre>
) : (
<ReactMarkdown key={1} className="overflow-scroll">
{props.historyNode.step.description as any}
</ReactMarkdown>
)}
- {props.historyNode.step.name === "Waiting for user input" && (
- <input
- ref={userInputRef}
- className="m-auto p-2 rounded-md border-1 border-solid text-white w-3/4 border-gray-200 bg-vsc-background"
- onKeyDown={(e) => {
- if (e.key === "Enter") {
- props.onUserInput(e.currentTarget.value);
- }
- }}
- type="text"
- onSubmit={(ev) => {
- props.onUserInput(ev.currentTarget.value);
+ {/* {props.historyNode.step.name === "Waiting for user input" && (
+ <InputAndButton
+ onUserInput={(value) => {
+ props.onUserInput(value);
}}
- onClick={(e) => {
- e.stopPropagation();
- }}
- />
+ ></InputAndButton>
)}
{props.historyNode.step.name === "Waiting for user confirmation" && (
<>
@@ -212,9 +212,9 @@ function StepContainer(props: StepContainerProps) {
value="Confirm"
/>
</>
- )}
- </StepContainerDiv>
- </GradientBorder>
+ )} */}
+ </ContentDiv>
+ </StepContainerDiv>
{/* <OnHoverDiv hidden={!open}>
<NaturalLanguageInput
diff --git a/extension/react-app/src/components/ToggleErrorDiv.tsx b/extension/react-app/src/components/ToggleErrorDiv.tsx
new file mode 100644
index 00000000..69112ef7
--- /dev/null
+++ b/extension/react-app/src/components/ToggleErrorDiv.tsx
@@ -0,0 +1,41 @@
+import React, { useState } from "react";
+import styled from "styled-components";
+import { defaultBorderRadius } from ".";
+
+// Should be a toggleable div with red border and light red background that displays a main message and detail inside
+
+interface ToggleErrorDivProps {
+ title: string;
+ error: string;
+}
+
+const TopDiv = styled.div`
+ border: 1px solid red;
+ background-color: #ff000020;
+ padding: 8px;
+
+ border-radius: ${defaultBorderRadius};
+ cursor: pointer;
+`;
+
+const ToggleErrorDiv = (props: ToggleErrorDivProps) => {
+ const [open, setOpen] = useState(false);
+ return (
+ <TopDiv
+ onClick={() => {
+ setOpen(!open);
+ }}
+ >
+ <div className="flex flex-row">
+ <div className="flex-grow">
+ <p>
+ {open ? "▼" : "▶"} {props.title}
+ </p>
+ </div>
+ </div>
+ {open && <pre className="overflow-scroll">{props.error}</pre>}
+ </TopDiv>
+ );
+};
+
+export default ToggleErrorDiv;
diff --git a/extension/react-app/src/components/index.ts b/extension/react-app/src/components/index.ts
index 7ba60467..4966f3e8 100644
--- a/extension/react-app/src/components/index.ts
+++ b/extension/react-app/src/components/index.ts
@@ -3,6 +3,7 @@ import styled, { keyframes } from "styled-components";
export const defaultBorderRadius = "5px";
export const secondaryDark = "rgb(37 37 38)";
export const vscBackground = "rgb(30 30 30)";
+export const vscBackgroundTransparent = "#1e1e1ede";
export const buttonColor = "rgb(113 28 59)";
export const buttonColorHover = "rgb(113 28 59 0.67)";
@@ -94,16 +95,24 @@ export const Loader = styled.div`
margin: auto;
`;
-export const GradientBorder = styled.div<{ borderWidth?: string }>`
- border-radius: ${defaultBorderRadius};
- padding: ${(props) => props.borderWidth || "1px"};
- background: linear-gradient(
+export const GradientBorder = styled.div<{
+ borderWidth?: string;
+ borderRadius?: string;
+ borderColor?: string;
+}>`
+ border-radius: ${(props) => props.borderRadius || "0"};
+ padding-top: ${(props) => props.borderWidth || "1px"};
+ padding-bottom: ${(props) => props.borderWidth || "1px"};
+ background: ${(props) =>
+ props.borderColor
+ ? props.borderColor
+ : `linear-gradient(
101.79deg,
#12887a 0%,
#87245c 37.64%,
#e12637 65.98%,
#ffb215 110.45%
- );
+ )`};
`;
export const MainContainerWithBorder = styled.div<{ borderWidth?: string }>`
diff --git a/extension/react-app/src/tabs/chat/MessageDiv.tsx b/extension/react-app/src/tabs/chat/MessageDiv.tsx
index ad81f5e9..1d7bb5f5 100644
--- a/extension/react-app/src/tabs/chat/MessageDiv.tsx
+++ b/extension/react-app/src/tabs/chat/MessageDiv.tsx
@@ -21,7 +21,6 @@ const Container = styled.div`
width: fit-content;
max-width: 75%;
overflow-y: scroll;
- scrollbar-gutter: stable both-edges;
word-wrap: break-word;
-ms-word-wrap: break-word;
height: fit-content;
diff --git a/extension/react-app/src/tabs/gui.tsx b/extension/react-app/src/tabs/gui.tsx
index a08698a4..5c75579b 100644
--- a/extension/react-app/src/tabs/gui.tsx
+++ b/extension/react-app/src/tabs/gui.tsx
@@ -1,25 +1,21 @@
import styled from "styled-components";
import {
- Button,
defaultBorderRadius,
vscBackground,
- MainTextInput,
Loader,
+ MainTextInput,
} from "../components";
import ContinueButton from "../components/ContinueButton";
import { useCallback, useEffect, useRef, useState } from "react";
import { History } from "../../../schema/History";
import { HistoryNode } from "../../../schema/HistoryNode";
import StepContainer from "../components/StepContainer";
-import { useSelector } from "react-redux";
-import { RootStore } from "../redux/store";
-import useContinueWebsocket from "../hooks/useWebsocket";
import useContinueGUIProtocol from "../hooks/useWebsocket";
let TopGUIDiv = styled.div`
display: grid;
grid-template-columns: 1fr;
- overflow: scroll;
+ background-color: ${vscBackground};
`;
let UserInputQueueItem = styled.div`
@@ -38,15 +34,20 @@ function GUI(props: GUIProps) {
const [waitingForSteps, setWaitingForSteps] = useState(false);
const [userInputQueue, setUserInputQueue] = useState<string[]>([]);
const [history, setHistory] = useState<History | undefined>();
- // {
+ // {
// timeline: [
// {
// step: {
- // name: "RunCodeStep",
+ // 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`",
// },
+ // 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: {
@@ -156,8 +157,20 @@ function GUI(props: GUIProps) {
// current_index: 0,
// } as any);
+ const topGuiDivRef = useRef<HTMLDivElement>(null);
const client = useContinueGUIProtocol();
+ const scrollToBottom = useCallback(() => {
+ if (topGuiDivRef.current) {
+ setTimeout(() => {
+ window.scrollTo({
+ top: window.outerHeight,
+ behavior: "smooth",
+ });
+ }, 100);
+ }
+ }, [topGuiDivRef.current]);
+
useEffect(() => {
console.log("CLIENT ON STATE UPDATE: ", client, client?.onStateUpdate);
client?.onStateUpdate((state) => {
@@ -165,9 +178,15 @@ function GUI(props: GUIProps) {
setWaitingForSteps(state.active);
setHistory(state.history);
setUserInputQueue(state.user_input_queue);
+
+ scrollToBottom();
});
}, [client]);
+ useEffect(() => {
+ scrollToBottom();
+ }, [waitingForSteps]);
+
const mainTextInputRef = useRef<HTMLTextAreaElement>(null);
useEffect(() => {
@@ -189,14 +208,33 @@ function GUI(props: GUIProps) {
if (mainTextInputRef.current) {
if (!client) return;
let input = mainTextInputRef.current.value;
- setWaitingForSteps(true);
- client.sendMainInput(input);
- setUserInputQueue((queue) => {
- return [...queue, input];
- });
+
+ if (
+ history &&
+ history.timeline[history.current_index].step.name ===
+ "Waiting for user input"
+ ) {
+ if (input.trim() === "") return;
+ onStepUserInput(input, history!.current_index);
+ } else if (
+ history &&
+ history.timeline[history.current_index].step.name ===
+ "Waiting for user confirmation"
+ ) {
+ onStepUserInput("ok", history!.current_index);
+ } else {
+ if (input.trim() === "") return;
+
+ client.sendMainInput(input);
+ setUserInputQueue((queue) => {
+ return [...queue, input];
+ });
+ }
mainTextInputRef.current.value = "";
mainTextInputRef.current.style.height = "";
}
+
+ setWaitingForSteps(true);
};
const onStepUserInput = (input: string, index: number) => {
@@ -207,7 +245,14 @@ function GUI(props: GUIProps) {
// const iterations = useSelector(selectIterations);
return (
- <TopGUIDiv>
+ <TopGUIDiv
+ ref={topGuiDivRef}
+ onKeyDown={(e) => {
+ if (e.key === "Enter" && e.ctrlKey) {
+ onMainTextInput();
+ }
+ }}
+ >
{typeof client === "undefined" && (
<>
<Loader></Loader>
@@ -247,6 +292,12 @@ function GUI(props: GUIProps) {
</div>
<MainTextInput
+ disabled={
+ history
+ ? history.timeline[history.current_index].step.name ===
+ "Waiting for user confirmation"
+ : false
+ }
ref={mainTextInputRef}
onKeyDown={(e) => {
if (e.key === "Enter") {
@@ -257,13 +308,15 @@ function GUI(props: GUIProps) {
}}
rows={1}
onChange={() => {
- let textarea = mainTextInputRef.current!;
+ const textarea = mainTextInputRef.current!;
textarea.style.height = ""; /* Reset the height*/
- textarea.style.height =
- Math.min(textarea.scrollHeight - 15, 500) + "px";
+ textarea.style.height = `${Math.min(
+ textarea.scrollHeight - 15,
+ 500
+ )}px`;
}}
- ></MainTextInput>
- <ContinueButton onClick={onMainTextInput}></ContinueButton>
+ />
+ <ContinueButton onClick={onMainTextInput} />
</TopGUIDiv>
);
}
diff --git a/extension/scripts/continuedev-0.1.1-py3-none-any.whl b/extension/scripts/continuedev-0.1.1-py3-none-any.whl
new file mode 100644
index 00000000..e9d03c6e
--- /dev/null
+++ b/extension/scripts/continuedev-0.1.1-py3-none-any.whl
Binary files differ
diff --git a/extension/src/activation/environmentSetup.ts b/extension/src/activation/environmentSetup.ts
index 21f867b1..bc071461 100644
--- a/extension/src/activation/environmentSetup.ts
+++ b/extension/src/activation/environmentSetup.ts
@@ -5,7 +5,6 @@ const { spawn } = require("child_process");
import * as path from "path";
import * as fs from "fs";
import rebuild from "@electron/rebuild";
-import * as vscode from "vscode";
import { getContinueServerUrl } from "../bridge";
import fetch from "node-fetch";
@@ -14,7 +13,9 @@ async function runCommand(cmd: string): Promise<[string, string | undefined]> {
var stdout: any = "";
var stderr: any = "";
try {
- var { stdout, stderr } = await exec(cmd);
+ var { stdout, stderr } = await exec(cmd, {
+ shell: process.platform === "win32" ? "powershell.exe" : undefined,
+ });
} catch (e: any) {
stderr = e.stderr;
stdout = e.stdout;
@@ -70,7 +71,9 @@ function checkEnvExists() {
);
return (
fs.existsSync(path.join(envBinPath, "activate")) &&
- fs.existsSync(path.join(envBinPath, "pip"))
+ fs.existsSync(
+ path.join(envBinPath, process.platform == "win32" ? "pip.exe" : "pip")
+ )
);
}
@@ -88,7 +91,7 @@ async function setupPythonEnv() {
const createEnvCommand = [
`cd ${path.join(getExtensionUri().fsPath, "scripts")}`,
`${pythonCmd} -m venv env`,
- ].join(" ; ");
+ ].join("; ");
// Repeat until it is successfully created (sometimes it fails to generate the bin, need to try again)
while (true) {
diff --git a/extension/src/continueIdeClient.ts b/extension/src/continueIdeClient.ts
index a5a1c5dc..bbaf5f08 100644
--- a/extension/src/continueIdeClient.ts
+++ b/extension/src/continueIdeClient.ts
@@ -12,6 +12,7 @@ import { debugPanelWebview, setupDebugPanel } from "./debugPanel";
import { FileEditWithFullContents } from "../schema/FileEditWithFullContents";
import fs = require("fs");
import { WebsocketMessenger } from "./util/messenger";
+import { CapturedTerminal } from "./terminal/terminalEmulator";
class IdeProtocolClient {
private messenger: WebsocketMessenger | null = null;
@@ -96,6 +97,14 @@ class IdeProtocolClient {
fileEdit,
});
break;
+ case "highlightCode":
+ this.highlightCode(data.rangeInFile, data.color);
+ break;
+ case "runCommand":
+ this.messenger?.send("runCommand", {
+ output: await this.runCommand(data.command),
+ });
+ break;
case "saveFile":
this.saveFile(data.filepath);
break;
@@ -117,6 +126,29 @@ class IdeProtocolClient {
// ------------------------------------ //
// On message handlers
+ async highlightCode(rangeInFile: RangeInFile, color: string) {
+ const range = new vscode.Range(
+ rangeInFile.range.start.line,
+ rangeInFile.range.start.character,
+ rangeInFile.range.end.line,
+ rangeInFile.range.end.character
+ );
+ const editor = await openEditorAndRevealRange(
+ rangeInFile.filepath,
+ range,
+ vscode.ViewColumn.One
+ );
+ if (editor) {
+ editor.setDecorations(
+ vscode.window.createTextEditorDecorationType({
+ backgroundColor: color,
+ isWholeLine: true,
+ }),
+ [range]
+ );
+ }
+ }
+
showSuggestion(edit: FileEdit) {
// showSuggestion already exists
showSuggestion(
@@ -288,9 +320,15 @@ class IdeProtocolClient {
return rangeInFiles;
}
- runCommand(command: string) {
- vscode.window.terminals[0].sendText(command, true);
- // But need to know when it's done executing...
+ private continueTerminal: CapturedTerminal | undefined;
+
+ async runCommand(command: string) {
+ if (!this.continueTerminal) {
+ this.continueTerminal = new CapturedTerminal("Continue");
+ }
+
+ this.continueTerminal.show();
+ return await this.continueTerminal.runCommand(command);
}
}
diff --git a/extension/src/terminal/terminalEmulator.ts b/extension/src/terminal/terminalEmulator.ts
index 6cf65970..67b47e2f 100644
--- a/extension/src/terminal/terminalEmulator.ts
+++ b/extension/src/terminal/terminalEmulator.ts
@@ -1,140 +1,162 @@
-// /* Terminal emulator - commented because node-pty is causing problems. */
-
-// import * as vscode from "vscode";
-// import pty = require("node-pty");
-// import os = require("os");
-// import { extensionContext } from "../activation/activate";
-// import { debugPanelWebview } from "../debugPanel"; // Need to consider having multiple panels, where to store this state.
-// import {
-// CommandCaptureSnooper,
-// PythonTracebackSnooper,
-// TerminalSnooper,
-// } from "./snoopers";
-
-// export function tracebackToWebviewAction(traceback: string) {
-// if (debugPanelWebview) {
-// debugPanelWebview.postMessage({
-// type: "traceback",
-// value: traceback,
-// });
-// } else {
-// vscode.commands
-// .executeCommand("continue.openContinueGUI", extensionContext)
-// .then(() => {
-// // TODO: Waiting for the webview to load, but should add a hook to the onLoad message event. Same thing in autodebugTest command in commands.ts
-// setTimeout(() => {
-// debugPanelWebview?.postMessage({
-// type: "traceback",
-// value: traceback,
-// });
-// }, 500);
-// });
-// }
-// }
-
-// const DEFAULT_SNOOPERS = [
-// new PythonTracebackSnooper(tracebackToWebviewAction),
-// new CommandCaptureSnooper((data: string) => {
-// if (data.trim().startsWith("pytest ")) {
-// let fileAndFunctionSpecifier = data.split(" ")[1];
-// vscode.commands.executeCommand(
-// "continue.debugTest",
-// fileAndFunctionSpecifier
-// );
-// }
-// }),
-// ];
-
-// // Whenever a user opens a terminal, replace it with ours
-// vscode.window.onDidOpenTerminal((terminal) => {
-// if (terminal.name != "Continue") {
-// terminal.dispose();
-// openCapturedTerminal();
-// }
-// });
-
-// function getDefaultShell(): string {
-// if (process.platform !== "win32") {
-// return os.userInfo().shell;
-// }
-// switch (process.platform) {
-// case "win32":
-// return process.env.COMSPEC || "cmd.exe";
-// // case "darwin":
-// // return process.env.SHELL || "/bin/zsh";
-// // default:
-// // return process.env.SHELL || "/bin/sh";
-// }
-// }
-
-// function getRootDir(): string | undefined {
-// var isWindows = os.platform() === "win32";
-// let cwd = isWindows ? process.env.USERPROFILE : process.env.HOME;
-// if (
-// vscode.workspace.workspaceFolders &&
-// vscode.workspace.workspaceFolders.length > 0
-// ) {
-// cwd = vscode.workspace.workspaceFolders[0].uri.fsPath;
-// }
-// return cwd;
-// }
-
-// export function openCapturedTerminal(
-// snoopers: TerminalSnooper<string>[] = DEFAULT_SNOOPERS
-// ) {
-// // If there is another existing, non-Continue terminal, delete it
-// let terminals = vscode.window.terminals;
-// for (let i = 0; i < terminals.length; i++) {
-// if (terminals[i].name != "Continue") {
-// terminals[i].dispose();
-// }
-// }
-
-// let env = { ...(process.env as any) };
-// if (os.platform() !== "win32") {
-// env["PATH"] += ":" + ["/opt/homebrew/bin", "/opt/homebrew/sbin"].join(":");
-// }
-
-// var ptyProcess = pty.spawn(getDefaultShell(), [], {
-// name: "xterm-256color",
-// cols: 160, // TODO: Get size of vscode terminal, and change with resize
-// rows: 26,
-// cwd: getRootDir(),
-// env,
-// useConpty: true,
-// });
-
-// const writeEmitter = new vscode.EventEmitter<string>();
-
-// ptyProcess.onData((data: any) => {
-// // Let each of the snoopers see the new data
-// for (let snooper of snoopers) {
-// snooper.onData(data);
-// }
-
-// // Pass data through to terminal
-// writeEmitter.fire(data);
-// });
-// process.on("exit", () => ptyProcess.kill());
-
-// const newPty: vscode.Pseudoterminal = {
-// onDidWrite: writeEmitter.event,
-// open: () => {},
-// close: () => {},
-// handleInput: (data) => {
-// for (let snooper of snoopers) {
-// snooper.onWrite(data);
-// }
-// ptyProcess.write(data);
-// },
-// };
-// const terminal = vscode.window.createTerminal({
-// name: "Continue",
-// pty: newPty,
-// });
-// terminal.show();
-
-// setTimeout(() => {
-// ptyProcess.write("clear\r");
-// }, 500);
-// }
+/* Terminal emulator - commented because node-pty is causing problems. */
+
+import * as vscode from "vscode";
+import os = require("os");
+import stripAnsi from "strip-ansi";
+
+function loadNativeModule<T>(id: string): T | null {
+ try {
+ return require(`${vscode.env.appRoot}/node_modules.asar/${id}`);
+ } catch (err) {
+ // ignore
+ }
+
+ try {
+ return require(`${vscode.env.appRoot}/node_modules/${id}`);
+ } catch (err) {
+ // ignore
+ }
+
+ return null;
+}
+
+const pty = loadNativeModule<any>("node-pty");
+
+function getDefaultShell(): string {
+ if (process.platform !== "win32") {
+ return os.userInfo().shell;
+ }
+ switch (process.platform) {
+ case "win32":
+ return process.env.COMSPEC || "cmd.exe";
+ // case "darwin":
+ // return process.env.SHELL || "/bin/zsh";
+ // default:
+ // return process.env.SHELL || "/bin/sh";
+ }
+}
+
+function getRootDir(): string | undefined {
+ const isWindows = os.platform() === "win32";
+ let cwd = isWindows ? process.env.USERPROFILE : process.env.HOME;
+ if (
+ vscode.workspace.workspaceFolders &&
+ vscode.workspace.workspaceFolders.length > 0
+ ) {
+ cwd = vscode.workspace.workspaceFolders[0].uri.fsPath;
+ }
+ return cwd;
+}
+
+export class CapturedTerminal {
+ private readonly terminal: vscode.Terminal;
+ private readonly shellCmd: string;
+ private readonly ptyProcess: any;
+
+ private shellPrompt: string | undefined = undefined;
+ private dataBuffer: string = "";
+
+ private onDataListeners: ((data: string) => void)[] = [];
+
+ show() {
+ this.terminal.show();
+ }
+
+ private commandQueue: [string, (output: string) => void][] = [];
+ private hasRunCommand: boolean = false;
+
+ private async waitForCommandToFinish() {
+ return new Promise<string>((resolve, reject) => {
+ this.onDataListeners.push((data: any) => {
+ const strippedData = stripAnsi(data);
+ this.dataBuffer += strippedData;
+ const lines = this.dataBuffer.split("\n");
+ if (
+ lines.length > 0 &&
+ (lines[lines.length - 1].includes("bash-") ||
+ lines[lines.length - 1].includes("(main)")) &&
+ lines[lines.length - 1].includes("$")
+ ) {
+ resolve(this.dataBuffer);
+ this.dataBuffer = "";
+ this.onDataListeners = [];
+ }
+ });
+ });
+ }
+
+ async runCommand(command: string): Promise<string> {
+ if (!this.hasRunCommand) {
+ this.hasRunCommand = true;
+ // Let the first bash- prompt appear and let python env be opened
+ await this.waitForCommandToFinish();
+ }
+
+ if (this.commandQueue.length === 0) {
+ return new Promise(async (resolve, reject) => {
+ this.commandQueue.push([command, resolve]);
+
+ while (this.commandQueue.length > 0) {
+ const [command, resolve] = this.commandQueue.shift()!;
+
+ this.terminal.sendText(command);
+ resolve(await this.waitForCommandToFinish());
+ }
+ });
+ } else {
+ return new Promise((resolve, reject) => {
+ this.commandQueue.push([command, resolve]);
+ });
+ }
+ }
+
+ private readonly writeEmitter: vscode.EventEmitter<string>;
+
+ constructor(terminalName: string) {
+ this.shellCmd = "bash"; // getDefaultShell();
+
+ const env = { ...(process.env as any) };
+ if (os.platform() !== "win32") {
+ env.PATH += `:${["/opt/homebrew/bin", "/opt/homebrew/sbin"].join(":")}`;
+ }
+
+ // Create the pseudo terminal
+ this.ptyProcess = pty.spawn(this.shellCmd, [], {
+ name: "xterm-256color",
+ cols: 160, // TODO: Get size of vscode terminal, and change with resize
+ rows: 26,
+ cwd: getRootDir(),
+ env,
+ useConpty: true,
+ });
+
+ this.writeEmitter = new vscode.EventEmitter<string>();
+
+ this.ptyProcess.onData((data: any) => {
+ // Pass data through to terminal
+ this.writeEmitter.fire(data);
+
+ for (let listener of this.onDataListeners) {
+ listener(data);
+ }
+ });
+
+ process.on("exit", () => this.ptyProcess.kill());
+
+ const newPty: vscode.Pseudoterminal = {
+ onDidWrite: this.writeEmitter.event,
+ open: () => {},
+ close: () => {},
+ handleInput: (data) => {
+ this.ptyProcess.write(data);
+ },
+ };
+
+ // Create and clear the terminal
+ this.terminal = vscode.window.createTerminal({
+ name: terminalName,
+ pty: newPty,
+ });
+ this.terminal.show();
+ }
+}