From 6639ea4a0ca34e259778736e5d0c4e2fc92560f4 Mon Sep 17 00:00:00 2001
From: Nate Sesti
Date: Sun, 9 Jul 2023 16:19:16 -0700
Subject: cache server env in .continue folder
---
extension/DEV_README.md | 2 +-
extension/package.json | 2 +-
extension/react-app/src/tabs/gui.tsx | 2 +-
extension/scripts/.gitignore | 5 -
extension/scripts/README.md | 5 -
extension/scripts/chroma.py | 152 ----------------------
extension/scripts/index.py | 52 --------
extension/scripts/query.py | 63 ---------
extension/scripts/replace.py | 17 ---
extension/scripts/requirements.txt | 6 -
extension/scripts/run_continue_server.py | 4 -
extension/scripts/update.py | 185 ---------------------------
extension/server/.gitignore | 1 +
extension/server/README.md | 3 +
extension/server/requirements.txt | 1 +
extension/server/run_continue_server.py | 4 +
extension/src/activation/environmentSetup.ts | 97 ++++++++++----
17 files changed, 85 insertions(+), 516 deletions(-)
delete mode 100644 extension/scripts/.gitignore
delete mode 100644 extension/scripts/README.md
delete mode 100644 extension/scripts/chroma.py
delete mode 100644 extension/scripts/index.py
delete mode 100644 extension/scripts/query.py
delete mode 100644 extension/scripts/replace.py
delete mode 100644 extension/scripts/requirements.txt
delete mode 100644 extension/scripts/run_continue_server.py
delete mode 100644 extension/scripts/update.py
create mode 100644 extension/server/.gitignore
create mode 100644 extension/server/README.md
create mode 100644 extension/server/requirements.txt
create mode 100644 extension/server/run_continue_server.py
(limited to 'extension')
diff --git a/extension/DEV_README.md b/extension/DEV_README.md
index c247b82c..87ed9334 100644
--- a/extension/DEV_README.md
+++ b/extension/DEV_README.md
@@ -4,7 +4,7 @@ This is the Continue VS Code Extension. Its primary jobs are
1. Implement the IDE side of the Continue IDE protocol, allowing a Continue server to interact natively in an IDE. This happens in `src/continueIdeClient.ts`.
2. Open the Continue React app in a side panel. The React app's source code lives in the `react-app` directory. The panel is opened by the `continue.openContinueGUI` command, as defined in `src/commands.ts`.
-3. Run a Continue server in the background, which connects to both the IDE protocol and the React app. The server is launched in `src/activation/environmentSetup.ts` by calling Python code that lives in `scripts/` (unless extension settings define a server URL other than localhost:65432, in which case the extension will just connect to that).
+3. Run a Continue server in the background, which connects to both the IDE protocol and the React app. The server is launched in `src/activation/environmentSetup.ts` by calling Python code that lives in `server/` (unless extension settings define a server URL other than localhost:65432, in which case the extension will just connect to that).
4. Open Continue
diff --git a/extension/package.json b/extension/package.json
index 444372f8..3b23ff19 100644
--- a/extension/package.json
+++ b/extension/package.json
@@ -227,7 +227,7 @@
"test": "node ./out/test/runTest.js",
"jest": "jest --config ./jest.config.js",
"package": "cp ./config/prod_config.json ./config/config.json && mkdir -p ./build && vsce package --out ./build && cp ./config/dev_config.json ./config/config.json",
- "full-package": "cd ../continuedev && poetry build && cp ./dist/continuedev-0.1.2-py3-none-any.whl ../extension/scripts/continuedev-0.1.2-py3-none-any.whl && cd ../extension && npm install && npm run typegen && npm run clientgen && cd react-app && npm install && npm run build && cd .. && npm run package",
+ "full-package": "cd ../continuedev && poetry build && cp ./dist/continuedev-0.1.2-py3-none-any.whl ../extension/server/continuedev-0.1.2-py3-none-any.whl && cd ../extension && npm install && npm run typegen && npm run clientgen && cd react-app && npm install && npm run build && cd .. && npm run package",
"install-extension": "code --install-extension ./build/continue-0.0.8.vsix",
"uninstall": "code --uninstall-extension .continue",
"reinstall": "rm -rf ./build && npm run package && npm run uninstall && npm run install-extension"
diff --git a/extension/react-app/src/tabs/gui.tsx b/extension/react-app/src/tabs/gui.tsx
index e1ecec9e..646aef50 100644
--- a/extension/react-app/src/tabs/gui.tsx
+++ b/extension/react-app/src/tabs/gui.tsx
@@ -438,7 +438,7 @@ function GUI(props: GUIProps) {
if (!usingFastModel) {
// Show the dialog
setFeedbackDialogMessage(
- "We don't yet support local models, but we're working on it! If privacy is a concern of yours, please use the feedback button in the bottom right to let us know."
+ "We don't yet support local models, but we're working on it! If privacy is a concern of yours, please write a short note to let us know."
);
setShowFeedbackDialog(true);
}
diff --git a/extension/scripts/.gitignore b/extension/scripts/.gitignore
deleted file mode 100644
index fbb3bf9f..00000000
--- a/extension/scripts/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-testdb
-env
-stdout.txt
-.continue_env_installed
-**.whl
\ No newline at end of file
diff --git a/extension/scripts/README.md b/extension/scripts/README.md
deleted file mode 100644
index da1ad493..00000000
--- a/extension/scripts/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# Scripts
-
-Whenever we need python to run on the client side, we include a script file at the top level of this folder. All other files that are not to be run directly as a script (utility files) should be in a subfolder of `scripts`. You can call one of these scripts from the VS Code extension using the `runPythonScript` function in `bridge.ts`.
-
-When the extension is activated (`activate` function in `src/extension.ts`), we call `setupPythonEnv`, which makes the virtual environment and downloads all the necessary requirements as given in `requirements.txt`. With this in mind, be sure to run `pip freeze > requirements.txt` whenever you add a new requirement.
diff --git a/extension/scripts/chroma.py b/extension/scripts/chroma.py
deleted file mode 100644
index 7425394e..00000000
--- a/extension/scripts/chroma.py
+++ /dev/null
@@ -1,152 +0,0 @@
-import chromadb
-import os
-import json
-import subprocess
-
-from typing import List, Tuple
-
-from chromadb.config import Settings
-
-client = chromadb.Client(Settings(
- chroma_db_impl="duckdb+parquet",
- persist_directory="./data/"
-))
-
-FILE_TYPES_TO_IGNORE = [
- '.pyc',
- '.png',
- '.jpg',
- '.jpeg',
- '.gif',
- '.svg',
- '.ico'
-]
-
-def further_filter(files: List[str], root_dir: str):
- """Further filter files before indexing."""
- for file in files:
- if file.endswith(tuple(FILE_TYPES_TO_IGNORE)) or file.startswith('.git') or file.startswith('archive'):
- continue
- yield root_dir + "/" + file
-
-def get_git_root_dir(path: str):
- """Get the root directory of a Git repository."""
- try:
- return subprocess.check_output(['git', 'rev-parse', '--show-toplevel'], cwd=path).strip().decode()
- except subprocess.CalledProcessError:
- return None
-
-def get_git_ignored_files(root_dir: str):
- """Get the list of ignored files in a Git repository."""
- try:
- output = subprocess.check_output(['git', 'ls-files', '--ignored', '--others', '--exclude-standard'], cwd=root_dir).strip().decode()
- return output.split('\n')
- except subprocess.CalledProcessError:
- return []
-
-def get_all_files(root_dir: str):
- """Get a list of all files in a directory."""
- for dir_path, _, file_names in os.walk(root_dir):
- for file_name in file_names:
- yield os.path.join(os.path.relpath(dir_path, root_dir), file_name)
-
-def get_input_files(root_dir: str):
- """Get a list of all files in a Git repository that are not ignored."""
- ignored_files = set(get_git_ignored_files(root_dir))
- all_files = set(get_all_files(root_dir))
- nonignored_files = all_files - ignored_files
- return further_filter(nonignored_files, root_dir)
-
-def get_git_root_dir(cwd: str):
- """Get the root directory of a Git repository."""
- result = subprocess.run(['git', 'rev-parse', '--show-toplevel'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd)
- return result.stdout.decode().strip()
-
-def get_current_branch(cwd: str) -> str:
- """Get the current Git branch."""
- try:
- return subprocess.check_output(["git", "rev-parse", "--abbrev-ref", "HEAD"], cwd=cwd).decode("utf-8").strip()
- except:
- return "main"
-
-def get_current_commit(cwd: str) -> str:
- try:
- return subprocess.check_output(["git", "rev-parse", "HEAD"], cwd=cwd).decode("utf-8").strip()
- except:
- return "NO_COMMITS"
-
-def get_modified_deleted_files(cwd: str) -> Tuple[List[str], List[str]]:
- """Get a list of all files that have been modified since the last commit."""
- branch = get_current_branch(cwd)
- current_commit = get_current_commit(cwd)
-
- with open(f"./data/{branch}.json", 'r') as f:
- previous_commit = json.load(f)["commit"]
-
- modified_deleted_files = subprocess.check_output(["git", "diff", "--name-only", previous_commit, current_commit], cwd=cwd).decode("utf-8").strip()
- modified_deleted_files = modified_deleted_files.split("\n")
- modified_deleted_files = [f for f in modified_deleted_files if f]
-
- root = get_git_root_dir(cwd)
- deleted_files = [f for f in modified_deleted_files if not os.path.exists(root + "/" + f)]
- modified_files = [f for f in modified_deleted_files if os.path.exists(root + "/" + f)]
-
- return further_filter(modified_files, root), further_filter(deleted_files, root)
-
-def create_collection(branch: str, cwd: str):
- """Create a new collection, returning whether it already existed."""
- try:
- collection = client.create_collection(name=branch)
- except Exception as e:
- print(e)
- return
-
- files = get_input_files(get_git_root_dir(cwd))
- for file in files:
- with open(file, 'r') as f:
- collection.add(documents=[f.read()], ids=[file])
- print(f"Added {file}")
- with open(f"./data/{branch}.json", 'w') as f:
- json.dump({"commit": get_current_commit(cwd)}, f)
-
-def collection_exists(cwd: str):
- """Check if a collection exists."""
- branch = get_current_branch(cwd)
- return branch in client.list_collections()
-
-def update_collection(cwd: str):
- """Update the collection."""
- branch = get_current_branch(cwd)
-
- try:
-
- collection = client.get_collection(branch)
-
- modified_files, deleted_files = get_modified_deleted_files(cwd)
-
- for file in deleted_files:
- collection.delete(ids=[file])
- print(f"Deleted {file}")
-
- for file in modified_files:
- with open(file, 'r') as f:
- collection.update(documents=[f.read()], ids=[file])
- print(f"Updated {file}")
-
- with open(f"./data/{branch}.json", 'w') as f:
- json.dump({"commit": get_current_commit(cwd)}, f)
-
- except:
-
- create_collection(branch, cwd)
-
-def query_collection(query: str, n_results: int, cwd: str):
- """Query the collection."""
- branch = get_current_branch(cwd)
- try:
- collection = client.get_collection(branch)
- except:
- create_collection(branch, cwd)
- collection = client.get_collection(branch)
- results = collection.query(query_texts=[query], n_results=n_results)
- return results
\ No newline at end of file
diff --git a/extension/scripts/index.py b/extension/scripts/index.py
deleted file mode 100644
index 3afc9131..00000000
--- a/extension/scripts/index.py
+++ /dev/null
@@ -1,52 +0,0 @@
-import sys
-import os
-from typing import TextIO
-from chroma import update_collection, query_collection, create_collection, collection_exists, get_current_branch
-from typer import Typer
-
-app = Typer()
-
-class SilenceStdoutContextManager:
- saved_stdout: TextIO
-
- def __enter__(self):
- self._original_stdout = sys.stdout
- sys.stdout = open(os.devnull, 'w')
-
- def __exit__(self, exc_type, exc_val, exc_tb):
- sys.stdout.close()
- sys.stdout = self._original_stdout
-
-silence = SilenceStdoutContextManager()
-
-@app.command("exists")
-def exists(cwd: str):
- with silence:
- exists = collection_exists(cwd)
- print({"exists": exists})
-
-@app.command("create")
-def create(cwd: str):
- with silence:
- branch = get_current_branch(cwd)
- create_collection(branch, cwd)
- print({"success": True})
-
-@app.command("update")
-def update(cwd: str):
- with silence:
- update_collection(cwd)
- print({"success": True})
-
-@app.command("query")
-def query(query: str, n_results: int, cwd: str):
- with silence:
- resp = query_collection(query, n_results, cwd)
- results = [{
- "id": resp["ids"][0][i],
- "document": resp["documents"][0][i]
- } for i in range(len(resp["ids"][0]))]
- print({"results": results})
-
-if __name__ == "__main__":
- app()
\ No newline at end of file
diff --git a/extension/scripts/query.py b/extension/scripts/query.py
deleted file mode 100644
index f2e44413..00000000
--- a/extension/scripts/query.py
+++ /dev/null
@@ -1,63 +0,0 @@
-import subprocess
-import sys
-from gpt_index import GPTSimpleVectorIndex, GPTFaissIndex
-import os
-from typer import Typer
-from enum import Enum
-from update import update_codebase_index, create_codebase_index, index_dir_for, get_current_branch
-from replace import replace_additional_index
-
-app = Typer()
-
-def query_codebase_index(query: str) -> str:
- """Query the codebase index."""
- branch = subprocess.check_output(["git", "rev-parse", "--abbrev-ref", "HEAD"]).decode("utf-8").strip()
- path = 'data/{branch}/index.json'
- if not os.path.exists(path):
- print("No index found for the codebase")
- return ""
- index = GPTFaissIndex.load_from_disk(path)
- return index.query(query)
-
-def query_additional_index(query: str) -> str:
- """Query the additional index."""
- index = GPTSimpleVectorIndex.load_from_disk('data/additional_index.json')
- return index.query(query)
-
-class IndexTypeOption(str, Enum):
- codebase = "codebase"
- additional = "additional"
-
-@app.command()
-def query(context: IndexTypeOption, query: str):
- if context == IndexTypeOption.additional:
- response = query_additional_index(query)
- elif context == IndexTypeOption.codebase:
- response = query_codebase_index(query)
- else:
- print("Error: unknown context")
- print({ "response": response })
-
-@app.command()
-def check_index_exists(root_path: str):
- branch = get_current_branch()
- exists = os.path.exists(index_dir_for(branch))
- print({ "exists": exists })
-
-@app.command()
-def update():
- update_codebase_index()
- print("Updated codebase index")
-
-@app.command()
-def create_index(path: str):
- create_codebase_index()
- print("Created file index")
-
-@app.command()
-def replace_additional_index(info: str):
- replace_additional_index()
- print("Replaced additional index")
-
-if __name__ == '__main__':
- app()
\ No newline at end of file
diff --git a/extension/scripts/replace.py b/extension/scripts/replace.py
deleted file mode 100644
index 08810243..00000000
--- a/extension/scripts/replace.py
+++ /dev/null
@@ -1,17 +0,0 @@
-import sys
-from gpt_index import GPTSimpleVectorIndex, Document
-
-def replace_additional_index(info: str):
- """Replace the additional index."""
- with open('data/additional_context.txt', 'w') as f:
- f.write(info)
- documents = [Document(info)]
- index = GPTSimpleVectorIndex(documents)
- index.save_to_disk('data/additional_index.json')
- print("Additional index replaced")
-
-if __name__ == "__main__":
- """python3 replace.py """
- info = sys.argv[1] if len(sys.argv) > 1 else None
- if info:
- replace_additional_index(info)
\ No newline at end of file
diff --git a/extension/scripts/requirements.txt b/extension/scripts/requirements.txt
deleted file mode 100644
index c51c9d73..00000000
--- a/extension/scripts/requirements.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-# chromadb==0.3.10
-# pathspec==0.11.0
-# typer==0.7.0
-# pydantic
-# pytest
-./continuedev-0.1.2-py3-none-any.whl
\ No newline at end of file
diff --git a/extension/scripts/run_continue_server.py b/extension/scripts/run_continue_server.py
deleted file mode 100644
index 089cc54d..00000000
--- a/extension/scripts/run_continue_server.py
+++ /dev/null
@@ -1,4 +0,0 @@
-from continuedev.server.main import run_server
-
-if __name__ == "__main__":
- run_server()
diff --git a/extension/scripts/update.py b/extension/scripts/update.py
deleted file mode 100644
index 15ad6ac0..00000000
--- a/extension/scripts/update.py
+++ /dev/null
@@ -1,185 +0,0 @@
-# import faiss
-import json
-import os
-import subprocess
-
-from gpt_index.langchain_helpers.text_splitter import TokenTextSplitter
-from gpt_index import GPTSimpleVectorIndex, SimpleDirectoryReader, Document, GPTFaissIndex
-from typing import List, Generator, Tuple
-
-FILE_TYPES_TO_IGNORE = [
- '.pyc',
- '.png',
- '.jpg',
- '.jpeg',
- '.gif',
- '.svg',
- '.ico'
-]
-
-def further_filter(files: List[str], root_dir: str):
- """Further filter files before indexing."""
- for file in files:
- if file.endswith(tuple(FILE_TYPES_TO_IGNORE)) or file.startswith('.git') or file.startswith('archive'):
- continue
- yield root_dir + "/" + file
-
-def get_git_root_dir(path: str):
- """Get the root directory of a Git repository."""
- try:
- return subprocess.check_output(['git', 'rev-parse', '--show-toplevel'], cwd=path).strip().decode()
- except subprocess.CalledProcessError:
- return None
-
-def get_git_ignored_files(root_dir: str):
- """Get the list of ignored files in a Git repository."""
- try:
- output = subprocess.check_output(['git', 'ls-files', '--ignored', '--others', '--exclude-standard'], cwd=root_dir).strip().decode()
- return output.split('\n')
- except subprocess.CalledProcessError:
- return []
-
-def get_all_files(root_dir: str):
- """Get a list of all files in a directory."""
- for dir_path, _, file_names in os.walk(root_dir):
- for file_name in file_names:
- yield os.path.join(os.path.relpath(dir_path, root_dir), file_name)
-
-def get_input_files(root_dir: str):
- """Get a list of all files in a Git repository that are not ignored."""
- ignored_files = set(get_git_ignored_files(root_dir))
- all_files = set(get_all_files(root_dir))
- nonignored_files = all_files - ignored_files
- return further_filter(nonignored_files, root_dir)
-
-def load_gpt_index_documents(root: str) -> List[Document]:
- """Loads a list of GPTIndex Documents, respecting .gitignore files."""
- # Get input files
- input_files = get_input_files(root)
- # Use SimpleDirectoryReader to load the files into Documents
- return SimpleDirectoryReader(root, input_files=input_files, file_metadata=lambda filename: {"filename": filename}).load_data()
-
-def index_dir_for(branch: str) -> str:
- return f"data/{branch}"
-
-def get_git_root_dir():
- result = subprocess.run(['git', 'rev-parse', '--show-toplevel'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- return result.stdout.decode().strip()
-
-def get_current_branch() -> str:
- return subprocess.check_output(["git", "rev-parse", "--abbrev-ref", "HEAD"]).decode("utf-8").strip()
-
-def get_current_commit() -> str:
- return subprocess.check_output(["git", "rev-parse", "HEAD"]).decode("utf-8").strip()
-
-def create_codebase_index():
- """Create a new index for the current branch."""
- branch = get_current_branch()
- if not os.path.exists(index_dir_for(branch)):
- os.makedirs(index_dir_for(branch))
-
- documents = load_gpt_index_documents(get_git_root_dir())
-
- chunks = {}
- doc_chunks = []
- for doc in documents:
- text_splitter = TokenTextSplitter()
- text_chunks = text_splitter.split_text(doc.text)
- filename = doc.extra_info["filename"]
- chunks[filename] = len(text_chunks)
- for i, text in enumerate(text_chunks):
- doc_chunks.append(Document(text, doc_id=f"{filename}::{i}"))
-
- with open(f"{index_dir_for(branch)}/metadata.json", "w") as f:
- json.dump({"commit": get_current_commit(), "chunks" : chunks}, f, indent=4)
-
- index = GPTSimpleVectorIndex([])
- for chunk in doc_chunks:
- index.insert(chunk)
-
- # d = 1536 # Dimension of text-ada-embedding-002
- # faiss_index = faiss.IndexFlatL2(d)
- # index = GPTFaissIndex(documents, faiss_index=faiss_index)
- # index.save_to_disk(f"{index_dir_for(branch)}/index.json", faiss_index_save_path=f"{index_dir_for(branch)}/index_faiss_core.index")
-
- index.save_to_disk(f"{index_dir_for(branch)}/index.json")
-
- print("Codebase index created")
-
-def get_modified_deleted_files() -> Tuple[List[str], List[str]]:
- """Get a list of all files that have been modified since the last commit."""
- branch = get_current_branch()
- current_commit = get_current_commit()
-
- metadata = f"{index_dir_for(branch)}/metadata.json"
- with open(metadata, "r") as f:
- previous_commit = json.load(f)["commit"]
-
- modified_deleted_files = subprocess.check_output(["git", "diff", "--name-only", previous_commit, current_commit]).decode("utf-8").strip()
- modified_deleted_files = modified_deleted_files.split("\n")
- modified_deleted_files = [f for f in modified_deleted_files if f]
-
- root = get_git_root_dir()
- deleted_files = [f for f in modified_deleted_files if not os.path.exists(root + "/" + f)]
- modified_files = [f for f in modified_deleted_files if os.path.exists(root + "/" + f)]
-
- return further_filter(modified_files, index_dir_for(branch)), further_filter(deleted_files, index_dir_for(branch))
-
-def update_codebase_index():
- """Update the index with a list of files."""
- branch = get_current_branch()
-
- if not os.path.exists(index_dir_for(branch)):
- create_codebase_index()
- else:
- # index = GPTFaissIndex.load_from_disk(f"{index_dir_for(branch)}/index.json", faiss_index_save_path=f"{index_dir_for(branch)}/index_faiss_core.index")
- index = GPTSimpleVectorIndex.load_from_disk(f"{index_dir_for(branch)}/index.json")
- modified_files, deleted_files = get_modified_deleted_files()
-
- with open(f"{index_dir_for(branch)}/metadata.json", "r") as f:
- metadata = json.load(f)
-
- for file in deleted_files:
-
- num_chunks = metadata["chunks"][file]
- for i in range(num_chunks):
- index.delete(f"{file}::{i}")
-
- del metadata["chunks"][file]
-
- print(f"Deleted {file}")
-
- for file in modified_files:
-
- if file in metadata["chunks"]:
-
- num_chunks = metadata["chunks"][file]
-
- for i in range(num_chunks):
- index.delete(f"{file}::{i}")
-
- print(f"Deleted old version of {file}")
-
- with open(file, "r") as f:
- text = f.read()
-
- text_splitter = TokenTextSplitter()
- text_chunks = text_splitter.split_text(text)
-
- for i, text in enumerate(text_chunks):
- index.insert(Document(text, doc_id=f"{file}::{i}"))
-
- metadata["chunks"][file] = len(text_chunks)
-
- print(f"Inserted new version of {file}")
-
- metadata["commit"] = get_current_commit()
-
- with open(f"{index_dir_for(branch)}/metadata.json", "w") as f:
- json.dump(metadata, f, indent=4)
-
- print("Codebase index updated")
-
-if __name__ == "__main__":
- """python3 update.py"""
- update_codebase_index()
\ No newline at end of file
diff --git a/extension/server/.gitignore b/extension/server/.gitignore
new file mode 100644
index 00000000..0b6e11dd
--- /dev/null
+++ b/extension/server/.gitignore
@@ -0,0 +1 @@
+**.whl
\ No newline at end of file
diff --git a/extension/server/README.md b/extension/server/README.md
new file mode 100644
index 00000000..56208b5a
--- /dev/null
+++ b/extension/server/README.md
@@ -0,0 +1,3 @@
+# server
+
+These are the files that get copied over to `~/.continue/server` in order to create the Python environment and start the Continue server.
diff --git a/extension/server/requirements.txt b/extension/server/requirements.txt
new file mode 100644
index 00000000..eb1f3738
--- /dev/null
+++ b/extension/server/requirements.txt
@@ -0,0 +1 @@
+./continuedev-0.1.2-py3-none-any.whl
\ No newline at end of file
diff --git a/extension/server/run_continue_server.py b/extension/server/run_continue_server.py
new file mode 100644
index 00000000..089cc54d
--- /dev/null
+++ b/extension/server/run_continue_server.py
@@ -0,0 +1,4 @@
+from continuedev.server.main import run_server
+
+if __name__ == "__main__":
+ run_server()
diff --git a/extension/src/activation/environmentSetup.ts b/extension/src/activation/environmentSetup.ts
index 714080e3..02118501 100644
--- a/extension/src/activation/environmentSetup.ts
+++ b/extension/src/activation/environmentSetup.ts
@@ -7,6 +7,7 @@ import * as fs from "fs";
import { getContinueServerUrl } from "../bridge";
import fetch from "node-fetch";
import * as vscode from "vscode";
+import * as os from "os";
import fkill from "fkill";
import { sendTelemetryEvent, TelemetryEvent } from "../telemetry";
@@ -127,8 +128,7 @@ function getActivateUpgradeCommands(pythonCmd: string, pipCmd: string) {
function checkEnvExists() {
const envBinPath = path.join(
- getExtensionUri().fsPath,
- "scripts",
+ serverPath(),
"env",
process.platform == "win32" ? "Scripts" : "bin"
);
@@ -140,10 +140,32 @@ function checkEnvExists() {
);
}
-function checkRequirementsInstalled() {
+async function checkRequirementsInstalled() {
+ // First, check if the requirements have been installed most recently for a later version of the extension
+ if (fs.existsSync(requirementsVersionPath())) {
+ const requirementsVersion = fs.readFileSync(
+ requirementsVersionPath(),
+ "utf8"
+ );
+ if (requirementsVersion !== getExtensionVersion()) {
+ // Remove the old version of continuedev from site-packages
+ const [pythonCmd, pipCmd] = await getPythonPipCommands();
+ const [activateCmd] = getActivateUpgradeCommands(pythonCmd, pipCmd);
+ const removeOldVersionCommand = [
+ `cd "${serverPath()}"`,
+ activateCmd,
+ `${pipCmd} uninstall -y continuedev`,
+ ].join(" ; ");
+ const [, stderr] = await runCommand(removeOldVersionCommand);
+ if (stderr) {
+ throw new Error(stderr);
+ }
+ return false;
+ }
+ }
+
let envLibsPath = path.join(
- getExtensionUri().fsPath,
- "scripts",
+ serverPath(),
"env",
process.platform == "win32" ? "Lib" : "lib"
);
@@ -165,10 +187,6 @@ function checkRequirementsInstalled() {
const continuePath = path.join(envLibsPath, "continuedev");
return fs.existsSync(continuePath);
-
- // return fs.existsSync(
- // path.join(getExtensionUri().fsPath, "scripts", ".continue_env_installed")
- // );
}
async function setupPythonEnv() {
@@ -180,12 +198,13 @@ async function setupPythonEnv() {
pipCmd
);
+ // First, create the virtual environment
if (checkEnvExists()) {
console.log("Python env already exists, skipping...");
} else {
// Assemble the command to create the env
const createEnvCommand = [
- `cd "${path.join(getExtensionUri().fsPath, "scripts")}"`,
+ `cd "${serverPath()}"`,
`${pythonCmd} -m venv env`,
].join(" ; ");
@@ -216,10 +235,7 @@ async function setupPythonEnv() {
console.log(msg);
await vscode.window.showErrorMessage(msg);
} else if (checkEnvExists()) {
- console.log(
- "Successfully set up python env at ",
- getExtensionUri().fsPath + "/scripts/env"
- );
+ console.log("Successfully set up python env at ", `${serverPath()}/env`);
} else {
const msg = [
"Python environment not successfully created. Trying again. Here was the stdout + stderr: ",
@@ -231,12 +247,13 @@ async function setupPythonEnv() {
}
}
+ // Install the requirements
await retryThenFail(async () => {
- if (checkRequirementsInstalled()) {
+ if (await checkRequirementsInstalled()) {
console.log("Python requirements already installed, skipping...");
} else {
const installRequirementsCommand = [
- `cd "${path.join(getExtensionUri().fsPath, "scripts")}"`,
+ `cd "${serverPath()}"`,
activateCmd,
pipUpgradeCmd,
`${pipCmd} install -r requirements.txt`,
@@ -245,6 +262,8 @@ async function setupPythonEnv() {
if (stderr) {
throw new Error(stderr);
}
+ // Write the version number for which requirements were installed
+ fs.writeFileSync(requirementsVersionPath(), getExtensionVersion());
}
});
}
@@ -297,9 +316,39 @@ async function checkServerRunning(serverUrl: string): Promise {
}
}
+export function getContinueGlobalPath(): string {
+ // This is ~/.continue on mac/linux
+ const continuePath = path.join(os.homedir(), ".continue");
+ if (!fs.existsSync(continuePath)) {
+ fs.mkdirSync(continuePath);
+ }
+ return continuePath;
+}
+
+function setupServerPath() {
+ const sPath = serverPath();
+ const extensionServerPath = path.join(getExtensionUri().fsPath, "server");
+ const files = fs.readdirSync(extensionServerPath);
+ files.forEach((file) => {
+ const filePath = path.join(extensionServerPath, file);
+ fs.copyFileSync(filePath, path.join(sPath, file));
+ });
+}
+
+function serverPath(): string {
+ const sPath = path.join(getContinueGlobalPath(), "server");
+ if (!fs.existsSync(sPath)) {
+ fs.mkdirSync(sPath);
+ }
+ return sPath;
+}
+
function serverVersionPath(): string {
- const extensionPath = getExtensionUri().fsPath;
- return path.join(extensionPath, "server_version.txt");
+ return path.join(serverPath(), "server_version.txt");
+}
+
+function requirementsVersionPath(): string {
+ return path.join(serverPath(), "requirements_version.txt");
}
function getExtensionVersion() {
@@ -314,6 +363,8 @@ export async function startContinuePythonServer() {
return;
}
+ setupServerPath();
+
return await retryThenFail(async () => {
if (await checkServerRunning(serverUrl)) {
// Kill the server if it is running an old version
@@ -337,16 +388,14 @@ export async function startContinuePythonServer() {
// Do this after above check so we don't have to waste time setting up the env
await setupPythonEnv();
+ // Spawn the server process on port 65432
const [pythonCmd] = await getPythonPipCommands();
const activateCmd =
process.platform == "win32"
? ".\\env\\Scripts\\activate"
: ". env/bin/activate";
- const command = `cd "${path.join(
- getExtensionUri().fsPath,
- "scripts"
- )}" && ${activateCmd} && cd .. && ${pythonCmd} -m scripts.run_continue_server`;
+ const command = `cd "${serverPath()}" && ${activateCmd} && cd .. && ${pythonCmd} -m server.run_continue_server`;
console.log("Starting Continue python server...");
@@ -392,8 +441,8 @@ export async function startContinuePythonServer() {
}
export function isPythonEnvSetup(): boolean {
- let pathToEnvCfg = getExtensionUri().fsPath + "/scripts/env/pyvenv.cfg";
- return fs.existsSync(path.join(pathToEnvCfg));
+ const pathToEnvCfg = path.join(serverPath(), "env", "pyvenv.cfg");
+ return fs.existsSync(pathToEnvCfg);
}
export async function downloadPython3() {
--
cgit v1.2.3-70-g09d2
From c84fdf356dccad9bb41140572b5704ee53807021 Mon Sep 17 00:00:00 2001
From: Nate Sesti
Date: Sun, 9 Jul 2023 17:43:37 -0700
Subject: say "No edits were made" if true
---
continuedev/src/continuedev/steps/core/core.py | 11 +++++++----
extension/package-lock.json | 4 ++--
extension/package.json | 2 +-
3 files changed, 10 insertions(+), 7 deletions(-)
(limited to 'extension')
diff --git a/continuedev/src/continuedev/steps/core/core.py b/continuedev/src/continuedev/steps/core/core.py
index 4b35a758..b0d9d719 100644
--- a/continuedev/src/continuedev/steps/core/core.py
+++ b/continuedev/src/continuedev/steps/core/core.py
@@ -167,10 +167,13 @@ class DefaultModelEditCodeStep(Step):
return output
async def describe(self, models: Models) -> Coroutine[str, None, None]:
- description = await models.gpt3516k.complete(dedent(f"""\
- {self._prompt_and_completion}
-
- Please give brief a description of the changes made above using markdown bullet points. Be concise and only mention changes made to the commit before, not prefix or suffix:"""))
+ if self._prompt_and_completion == "":
+ description = "No edits were made"
+ else:
+ description = await models.gpt3516k.complete(dedent(f"""\
+ {self._prompt_and_completion}
+
+ Please give brief a description of the changes made above using markdown bullet points. Be concise and only mention changes made to the commit before, not prefix or suffix:"""))
name = await models.gpt3516k.complete(f"Write a very short title to describe this requested change (no quotes): '{self.user_input}'. This is the title:")
self.name = self._cleanup_output(name)
diff --git a/extension/package-lock.json b/extension/package-lock.json
index 5733c2dd..a2ac0a04 100644
--- a/extension/package-lock.json
+++ b/extension/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "continue",
- "version": "0.0.143",
+ "version": "0.0.145",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "continue",
- "version": "0.0.143",
+ "version": "0.0.145",
"license": "Apache-2.0",
"dependencies": {
"@electron/rebuild": "^3.2.10",
diff --git a/extension/package.json b/extension/package.json
index 3b23ff19..0464ba55 100644
--- a/extension/package.json
+++ b/extension/package.json
@@ -14,7 +14,7 @@
"displayName": "Continue",
"pricing": "Free",
"description": "The open-source coding autopilot",
- "version": "0.0.143",
+ "version": "0.0.145",
"publisher": "Continue",
"engines": {
"vscode": "^1.67.0"
--
cgit v1.2.3-70-g09d2
From 05f3a1f35f1d0f85df15ac78f2f285d54ab45118 Mon Sep 17 00:00:00 2001
From: Ty Dunn
Date: Mon, 10 Jul 2023 15:25:29 -0700
Subject: adding onboarding
---
extension/react-app/public/edit.gif | Bin 0 -> 41667733 bytes
extension/react-app/public/explain.gif | Bin 0 -> 56475028 bytes
extension/react-app/public/generate.gif | Bin 0 -> 32532380 bytes
extension/react-app/public/intro.gif | Bin 0 -> 3976676 bytes
extension/react-app/src/components/Onboarding.tsx | 51 ++++++++++++++++++++++
extension/react-app/src/tabs/gui.tsx | 2 +
6 files changed, 53 insertions(+)
create mode 100644 extension/react-app/public/edit.gif
create mode 100644 extension/react-app/public/explain.gif
create mode 100644 extension/react-app/public/generate.gif
create mode 100644 extension/react-app/public/intro.gif
create mode 100644 extension/react-app/src/components/Onboarding.tsx
(limited to 'extension')
diff --git a/extension/react-app/public/edit.gif b/extension/react-app/public/edit.gif
new file mode 100644
index 00000000..6780cdf7
Binary files /dev/null and b/extension/react-app/public/edit.gif differ
diff --git a/extension/react-app/public/explain.gif b/extension/react-app/public/explain.gif
new file mode 100644
index 00000000..e74803dc
Binary files /dev/null and b/extension/react-app/public/explain.gif differ
diff --git a/extension/react-app/public/generate.gif b/extension/react-app/public/generate.gif
new file mode 100644
index 00000000..5c1d112b
Binary files /dev/null and b/extension/react-app/public/generate.gif differ
diff --git a/extension/react-app/public/intro.gif b/extension/react-app/public/intro.gif
new file mode 100644
index 00000000..f872dc91
Binary files /dev/null and b/extension/react-app/public/intro.gif differ
diff --git a/extension/react-app/src/components/Onboarding.tsx b/extension/react-app/src/components/Onboarding.tsx
new file mode 100644
index 00000000..373f7bea
--- /dev/null
+++ b/extension/react-app/src/components/Onboarding.tsx
@@ -0,0 +1,51 @@
+import { useSelector } from "react-redux";
+import { RootStore } from "../redux/store";
+import React, { useState } from 'react';
+
+
+const Onboarding = () => {
+ const [counter, setCounter] = useState(0);
+
+ const handleClick = () => {
+ setCounter(counter + 1);
+ }
+
+ const vscMediaUrl = useSelector(
+ (state: RootStore) => state.config.vscMediaUrl
+ );
+
+ return (
+
+ {counter === 0 && (
+
+
Welcome to Continue!
+
+
+ )}
+ {counter === 1 && (
+
+
Answer coding questions
+
+
Ask Continue about a part of your code to get another perspective
+
+ )}
+ {counter === 2 && (
+
+
Edit in natural language
+
+
Highlight a section of code and instruct Continue to refactor it
+
+ )}
+ {counter === 3 && (
+
+
Generate files from scratch
+
+
Let Continue build the scaffolding of Python scripts, React components, and more
+
+ )}
+
Click to learn how to use Continue...
+
+ );
+}
+
+export default Onboarding;
diff --git a/extension/react-app/src/tabs/gui.tsx b/extension/react-app/src/tabs/gui.tsx
index e1ecec9e..14556829 100644
--- a/extension/react-app/src/tabs/gui.tsx
+++ b/extension/react-app/src/tabs/gui.tsx
@@ -23,6 +23,7 @@ import { RootStore } from "../redux/store";
import LoadingCover from "../components/LoadingCover";
import { postVscMessage } from "../vscode";
import UserInputContainer from "../components/UserInputContainer";
+import Onboarding from "../components/Onboarding";
const TopGUIDiv = styled.div`
overflow: hidden;
@@ -267,6 +268,7 @@ function GUI(props: GUIProps) {
// const iterations = useSelector(selectIterations);
return (
<>
+
Date: Mon, 10 Jul 2023 15:44:35 -0700
Subject: update for v2
---
README.md | 22 ++++++++++-----------
docs/docs/how-to-use-continue.md | 40 +++++++++++++++++++++++++++++++++++++++
edit.gif | Bin 11209423 -> 14939314 bytes
extension/README.md | 18 +++++++++---------
extension/media/edit.png | Bin 246984 -> 675283 bytes
extension/media/explain.png | Bin 464952 -> 897037 bytes
extension/media/generate.png | Bin 1049613 -> 411580 bytes
extension/package.json | 6 +++---
8 files changed, 63 insertions(+), 23 deletions(-)
(limited to 'extension')
diff --git a/README.md b/README.md
index a91fbdf4..01462247 100644
--- a/README.md
+++ b/README.md
@@ -19,26 +19,26 @@
## Task, not tab, auto-complete
-### Edit in natural language
-
### Get possible explainations
Ask Continue about a part of your code to get another perspective
-- `what might cause this error?`
-- `what is the load_dotenv library name?`
-- `how do I find running process on port 8000?`
+- “how can I set up a Prisma schema that cascades deletes?”
+- “where in the page should I be making this request to the backend?”
+- “how can I communicate between these iframes?”
+
+### Edit in natural language
Highlight a section of code and instruct Continue to refactor it
-- `/edit Make this use more descriptive variable names`
-- `/edit Rewrite this API call to grab all pages`
-- `/edit Use 'Union' instead of a vertical bar here`
+- “/edit migrate this digital ocean terraform file into one that works for GCP”
+- “/edit change this plot into a bar chart in this dashboard component”
+- “/edit rewrite this function to be async”
### Generate files from scratch
Let Continue build the scaffolding of Python scripts, React components, and more
-- `Create a shell script to back up my home dir to /tmp/`
-- `Write a Python script to get Posthog events`
-- `Add a React component for syntax highlighted code`
+- “/edit here is a connector for postgres, now write one for kafka”
+- “/edit make an IAM policy that creates a user with read-only access to S3”
+- “/edit use this schema to write me a SQL query that gets recently churned users”
## Getting Started
diff --git a/docs/docs/how-to-use-continue.md b/docs/docs/how-to-use-continue.md
index 96c44228..66de7ee9 100644
--- a/docs/docs/how-to-use-continue.md
+++ b/docs/docs/how-to-use-continue.md
@@ -29,42 +29,82 @@ Here are tasks that Continue excels at helping you complete:
Continue works well in situations where find and replace does not work (i.e. “/edit change all of these to be like that”)
+Examples
+- "/edit Use 'Union' instead of a vertical bar here"
+- “/edit Make this use more descriptive variable names”
+
### Writing files from scratch
Continue can help you get started building React components, Python scripts, Shell scripts, Makefiles, Unit tests, etc.
+Examples
+- “/edit write a python script to get Posthog events"
+- “/edit add a React component for syntax highlighted code"
+
### Creating projects from scratch
Continue can go even further. For example, it can help build the scaffolding for a Python package, which includes a typer cli app to sort the arguments and print them back out.
+Examples
+- “/edit use this schema to write me a SQL query that gets recently churned users”
+- “/edit create a shell script to back up my home dir to /tmp/"
+
### Fix highlighted code
After selecting a code section, try to refactor it with Continue (e.g “/edit change the function to work like this”, “/edit do this everywhere”)
+Examples
+- “/edit migrate this digital ocean terraform file into one that works for GCP”
+- “/edit rewrite this function to be async”
+
### Ask about highlighted code or an entire file
If you don't understand how some code works, highlight it and ask "how does this code work?"
+Examples
+- “where in the page should I be making this request to the backend?”
+- “how can I communicate between these iframes?”
+
### Ask about errors
Continue can also help explain errors and offer possible solutions. You will need to copy and paste the error text into the text input though.
+Examples
+- “explain this error to me in human understandable way”
+- "what are some ideas for how I might solve this problem?"
+
### Figure out what shell command to run
Instead of switching windows and getting distracted, you can ask things like "How do I find running process on port 8000?"
+Examples
+- "what is the load_dotenv library name?"
+- "how do I find running process on port 8000?"
+
### Ask single-turn open-ended questions
Instead of leaving your IDE, you can ask open-ended questions that you don't expect to turn into multi-turn conversations.
+Examples
+- “how can I set up a Prisma schema that cascades deletes?”
+- "what is the difference between dense and sparse embeddings?"
+
### Editing small existing files
You can highlight an entire file and ask Continue to improve it as long as the file is not too large.
+Examples
+- “/edit here is a connector for postgres, now write one for kafka”
+- "/edit Rewrite this API call to grab all pages"
+
### Tasks with a few steps
There are many more tasks that Continue can help you complete. Typically, these will be tasks that don't involve too many steps to complete.
+Examples
+- “/edit make an IAM policy that creates a user with read-only access to S3”
+- “/edit change this plot into a bar chart in this dashboard component”
+
## When to not use Continue
Here are tasks that Continue is **not** helpful with today:
diff --git a/edit.gif b/edit.gif
index 6a53a14b..96240dfe 100644
Binary files a/edit.gif and b/edit.gif differ
diff --git a/extension/README.md b/extension/README.md
index b57aedb7..2d449b92 100644
--- a/extension/README.md
+++ b/extension/README.md
@@ -7,23 +7,23 @@
### Get possible explainations
Ask Continue about a part of your code to get another perspective
-- `what might cause this error?`
-- `what is the load_dotenv library name?`
-- `how do I find running process on port 8000?`
+- “how can I set up a Prisma schema that cascades deletes?”
+- “where in the page should I be making this request to the backend?”
+- “how can I communicate between these iframes?”
### Edit in natural language
Highlight a section of code and instruct Continue to refactor it
-- `/edit Make this use more descriptive variable names`
-- `/edit Rewrite this API call to grab all pages`
-- `/edit Use 'Union' instead of a vertical bar here`
+- “/edit migrate this digital ocean terraform file into one that works for GCP”
+- “/edit change this plot into a bar chart in this dashboard component”
+- “/edit rewrite this function to be async”
### Generate files from scratch
Let Continue build the scaffolding of Python scripts, React components, and more
-- `Create a shell script to back up my home dir to /tmp/`
-- `Write Python in a new file to get Posthog events`
-- `Add a React component for syntax highlighted code`
+- “/edit here is a connector for postgres, now write one for kafka”
+- “/edit make an IAM policy that creates a user with read-only access to S3”
+- “/edit use this schema to write me a SQL query that gets recently churned users”
## OpenAI API Key
diff --git a/extension/media/edit.png b/extension/media/edit.png
index 5e77c0ea..f4ca623c 100644
Binary files a/extension/media/edit.png and b/extension/media/edit.png differ
diff --git a/extension/media/explain.png b/extension/media/explain.png
index 196ab914..79e8ccc9 100644
Binary files a/extension/media/explain.png and b/extension/media/explain.png differ
diff --git a/extension/media/generate.png b/extension/media/generate.png
index 9d84e4ae..c16d9f9f 100644
Binary files a/extension/media/generate.png and b/extension/media/generate.png differ
diff --git a/extension/package.json b/extension/package.json
index 444372f8..0477a450 100644
--- a/extension/package.json
+++ b/extension/package.json
@@ -181,7 +181,7 @@
{
"id": "edit",
"title": "Edit in natural language",
- "description": "Highlight a section of code and instruct Continue to refactor it (e.g. `/edit Make this use more descriptive variable names`)",
+ "description": "Highlight a section of code and instruct Continue to refactor it (e.g. `/edit rewrite this function to be async`)",
"media": {
"image": "media/edit.png",
"altText": "Empty image"
@@ -191,7 +191,7 @@
{
"id": "explain",
"title": "Get possible explanations",
- "description": "Ask Continue about a part of your code to get another perspective (e.g. `how do I find running process on port 8000?`)",
+ "description": "Ask Continue about a part of your code to get another perspective (e.g. `where in the page should I be making this request to the backend?`)",
"media": {
"image": "media/explain.png",
"altText": "Empty image"
@@ -201,7 +201,7 @@
{
"id": "generate",
"title": "Generate files from scratch",
- "description": "Let Continue build the scaffolding of Python scripts, React components, and more (e.g. `Create a shell script to back up my home dir to /tmp/`)",
+ "description": "Let Continue build the scaffolding of Python scripts, React components, and more (e.g. `/edit here is a connector for postgres, now write one for kafka`)",
"media": {
"image": "media/generate.png",
"altText": "Empty image"
--
cgit v1.2.3-70-g09d2
From 78168d47e3b2642bbd0eb6b4d072e9ca8c70ecba Mon Sep 17 00:00:00 2001
From: Nate Sesti
Date: Mon, 10 Jul 2023 17:31:38 -0700
Subject: sprucing up onboarding
---
extension/react-app/src/components/Onboarding.tsx | 146 ++++++++++++++++------
1 file changed, 105 insertions(+), 41 deletions(-)
(limited to 'extension')
diff --git a/extension/react-app/src/components/Onboarding.tsx b/extension/react-app/src/components/Onboarding.tsx
index 373f7bea..0e188e7a 100644
--- a/extension/react-app/src/components/Onboarding.tsx
+++ b/extension/react-app/src/components/Onboarding.tsx
@@ -1,51 +1,115 @@
import { useSelector } from "react-redux";
import { RootStore } from "../redux/store";
-import React, { useState } from 'react';
+import React, { useState, useEffect } from "react";
+import styled from "styled-components";
+import { ArrowLeft, ArrowRight } from "@styled-icons/heroicons-outline";
+import { defaultBorderRadius } from ".";
+const StyledDiv = styled.div`
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background-color: #1e1e1e;
+ z-index: 200;
+`;
+
+const StyledSpan = styled.span`
+ padding: 8px;
+ border-radius: ${defaultBorderRadius};
+ &:hover {
+ background-color: #ffffff33;
+ }
+`;
const Onboarding = () => {
- const [counter, setCounter] = useState(0);
+ const [counter, setCounter] = useState(4);
+ const gifs = ["intro", "explain", "edit", "generate"];
+ const topMessages = [
+ "Welcome to Continue!",
+ "Answer coding questions",
+ "Edit in natural language",
+ "Generate files from scratch",
+ ];
+ const bottomMessages = [
+ "",
+ "Ask Continue about a part of your code to get another perspective",
+ "Highlight a section of code and instruct Continue to refactor it",
+ "Let Continue build the scaffolding of Python scripts, React components, and more",
+ ];
- const handleClick = () => {
- setCounter(counter + 1);
- }
+ const vscMediaUrl = useSelector(
+ (state: RootStore) => state.config.vscMediaUrl
+ );
- const vscMediaUrl = useSelector(
- (state: RootStore) => state.config.vscMediaUrl
- );
+ useEffect(() => {
+ const hasVisited = localStorage.getItem("hasVisited");
+ if (hasVisited) {
+ setCounter(4);
+ } else {
+ setCounter(0);
+ localStorage.setItem("hasVisited", "true");
+ }
+ }, []);
- return (
-
- {counter === 0 && (
-
-
Welcome to Continue!
-
-
- )}
- {counter === 1 && (
-
-
Answer coding questions
-
-
Ask Continue about a part of your code to get another perspective
-
- )}
- {counter === 2 && (
-
-
Edit in natural language
-
-
Highlight a section of code and instruct Continue to refactor it
-
- )}
- {counter === 3 && (
-
-
Generate files from scratch
-
-
Let Continue build the scaffolding of Python scripts, React components, and more
- {/*
- Highlight code to include as context. Currently open file included by
- default. {highlightedCodeSections.length === 0 && ""}
- */}
+ {highlightedCodeSections.length === 0 &&
+ (downshiftProps.inputValue?.startsWith("/edit") || metaKeyPressed) && (
+
+ Inserting at cursor
+
+ )}
{
setHoveringContextDropdown(true);
diff --git a/extension/src/diffs.ts b/extension/src/diffs.ts
index 1dc292e1..3ea6b4f8 100644
--- a/extension/src/diffs.ts
+++ b/extension/src/diffs.ts
@@ -164,7 +164,12 @@ class DiffManager {
// Stop the step at step_index in case it is still streaming
ideProtocolClient.deleteAtIndex(diffInfo.step_index);
- this.cleanUpDiff(diffInfo);
+ vscode.workspace.textDocuments
+ .find((doc) => doc.uri.fsPath === newFilepath)
+ ?.save()
+ .then(() => {
+ this.cleanUpDiff(diffInfo);
+ });
}
}
--
cgit v1.2.3-70-g09d2
From 35f447b643f76afaeff81d75408393359ff9ef67 Mon Sep 17 00:00:00 2001
From: Nate Sesti
Date: Tue, 11 Jul 2023 11:48:43 -0700
Subject: air on the side of killing server
---
extension/package-lock.json | 4 ++--
extension/package.json | 2 +-
extension/src/activation/environmentSetup.ts | 34 +++++++++++++++-------------
3 files changed, 21 insertions(+), 19 deletions(-)
(limited to 'extension')
diff --git a/extension/package-lock.json b/extension/package-lock.json
index 71f4d974..d778b097 100644
--- a/extension/package-lock.json
+++ b/extension/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "continue",
- "version": "0.0.147",
+ "version": "0.0.149",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "continue",
- "version": "0.0.147",
+ "version": "0.0.149",
"license": "Apache-2.0",
"dependencies": {
"@electron/rebuild": "^3.2.10",
diff --git a/extension/package.json b/extension/package.json
index d9f155df..56c49f27 100644
--- a/extension/package.json
+++ b/extension/package.json
@@ -14,7 +14,7 @@
"displayName": "Continue",
"pricing": "Free",
"description": "The open-source coding autopilot",
- "version": "0.0.147",
+ "version": "0.0.149",
"publisher": "Continue",
"engines": {
"vscode": "^1.67.0"
diff --git a/extension/src/activation/environmentSetup.ts b/extension/src/activation/environmentSetup.ts
index 02118501..ff8d3158 100644
--- a/extension/src/activation/environmentSetup.ts
+++ b/extension/src/activation/environmentSetup.ts
@@ -366,24 +366,26 @@ export async function startContinuePythonServer() {
setupServerPath();
return await retryThenFail(async () => {
- if (await checkServerRunning(serverUrl)) {
- // Kill the server if it is running an old version
- if (fs.existsSync(serverVersionPath())) {
- const serverVersion = fs.readFileSync(serverVersionPath(), "utf8");
- if (serverVersion === getExtensionVersion()) {
- return;
- }
- }
- console.log("Killing old server...");
- try {
- await fkill(":65432");
- } catch (e) {
- console.log(
- "Failed to kill old server, likely because it didn't exist:",
- e
- );
+ // Kill the server if it is running an old version
+ if (fs.existsSync(serverVersionPath())) {
+ const serverVersion = fs.readFileSync(serverVersionPath(), "utf8");
+ if (
+ serverVersion === getExtensionVersion() &&
+ (await checkServerRunning(serverUrl))
+ ) {
+ // The current version is already up and running, no need to continue
+ return;
}
}
+ console.log("Killing old server...");
+ try {
+ await fkill(":65432");
+ } catch (e) {
+ console.log(
+ "Failed to kill old server, likely because it didn't exist:",
+ e
+ );
+ }
// Do this after above check so we don't have to waste time setting up the env
await setupPythonEnv();
--
cgit v1.2.3-70-g09d2
From 857303c78860806fb28205389cb6304cfd374111 Mon Sep 17 00:00:00 2001
From: Nate Sesti
Date: Tue, 11 Jul 2023 12:15:35 -0700
Subject: don't override error messages with a second one
---
extension/src/activation/environmentSetup.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'extension')
diff --git a/extension/src/activation/environmentSetup.ts b/extension/src/activation/environmentSetup.ts
index ff8d3158..f5d825c9 100644
--- a/extension/src/activation/environmentSetup.ts
+++ b/extension/src/activation/environmentSetup.ts
@@ -22,7 +22,7 @@ async function retryThenFail(
if (retries > 0) {
return await retryThenFail(fn, retries - 1);
}
- vscode.window.showErrorMessage(
+ vscode.window.showInformationMessage(
"Failed to set up Continue extension. Please email nate@continue.dev and we'll get this fixed ASAP!"
);
sendTelemetryEvent(TelemetryEvent.ExtensionSetupError, {
--
cgit v1.2.3-70-g09d2
From 655b4394507a351a76d32cbb018b448c9f7ebda4 Mon Sep 17 00:00:00 2001
From: Nate Sesti
Date: Tue, 11 Jul 2023 12:33:02 -0700
Subject: patch
---
extension/package-lock.json | 4 ++--
extension/package.json | 2 +-
extension/src/activation/environmentSetup.ts | 3 +++
3 files changed, 6 insertions(+), 3 deletions(-)
(limited to 'extension')
diff --git a/extension/package-lock.json b/extension/package-lock.json
index d778b097..c43851a2 100644
--- a/extension/package-lock.json
+++ b/extension/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "continue",
- "version": "0.0.149",
+ "version": "0.0.150",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "continue",
- "version": "0.0.149",
+ "version": "0.0.150",
"license": "Apache-2.0",
"dependencies": {
"@electron/rebuild": "^3.2.10",
diff --git a/extension/package.json b/extension/package.json
index 56c49f27..e2fe6e8e 100644
--- a/extension/package.json
+++ b/extension/package.json
@@ -14,7 +14,7 @@
"displayName": "Continue",
"pricing": "Free",
"description": "The open-source coding autopilot",
- "version": "0.0.149",
+ "version": "0.0.150",
"publisher": "Continue",
"engines": {
"vscode": "^1.67.0"
diff --git a/extension/src/activation/environmentSetup.ts b/extension/src/activation/environmentSetup.ts
index f5d825c9..8b384e1d 100644
--- a/extension/src/activation/environmentSetup.ts
+++ b/extension/src/activation/environmentSetup.ts
@@ -224,6 +224,9 @@ async function setupPythonEnv() {
// First, try to run the command to install python3-venv
let [stdout, stderr] = await runCommand(`${pythonCmd} --version`);
if (stderr) {
+ await vscode.window.showErrorMessage(
+ "Python3 is not installed. Please install from https://www.python.org/downloads, reload VS Code, and try again."
+ );
throw new Error(stderr);
}
const version = stdout.split(" ")[1].split(".")[1];
--
cgit v1.2.3-70-g09d2
From f52f108e971b590f80bbf0806f30b0ebf60e139c Mon Sep 17 00:00:00 2001
From: Nate Sesti
Date: Tue, 11 Jul 2023 12:43:15 -0700
Subject: fix bug uninstalling continuedev
---
extension/package-lock.json | 4 ++--
extension/package.json | 2 +-
extension/src/activation/environmentSetup.ts | 5 +----
3 files changed, 4 insertions(+), 7 deletions(-)
(limited to 'extension')
diff --git a/extension/package-lock.json b/extension/package-lock.json
index c43851a2..b6147b2c 100644
--- a/extension/package-lock.json
+++ b/extension/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "continue",
- "version": "0.0.150",
+ "version": "0.0.151",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "continue",
- "version": "0.0.150",
+ "version": "0.0.151",
"license": "Apache-2.0",
"dependencies": {
"@electron/rebuild": "^3.2.10",
diff --git a/extension/package.json b/extension/package.json
index e2fe6e8e..a57f6065 100644
--- a/extension/package.json
+++ b/extension/package.json
@@ -14,7 +14,7 @@
"displayName": "Continue",
"pricing": "Free",
"description": "The open-source coding autopilot",
- "version": "0.0.150",
+ "version": "0.0.151",
"publisher": "Continue",
"engines": {
"vscode": "^1.67.0"
diff --git a/extension/src/activation/environmentSetup.ts b/extension/src/activation/environmentSetup.ts
index 8b384e1d..881da9b5 100644
--- a/extension/src/activation/environmentSetup.ts
+++ b/extension/src/activation/environmentSetup.ts
@@ -156,10 +156,7 @@ async function checkRequirementsInstalled() {
activateCmd,
`${pipCmd} uninstall -y continuedev`,
].join(" ; ");
- const [, stderr] = await runCommand(removeOldVersionCommand);
- if (stderr) {
- throw new Error(stderr);
- }
+ await runCommand(removeOldVersionCommand);
return false;
}
}
--
cgit v1.2.3-70-g09d2
From 3ca5c52e83f27bc1cda1b3f696dc86296ada2370 Mon Sep 17 00:00:00 2001
From: Nate Sesti
Date: Tue, 11 Jul 2023 14:13:14 -0700
Subject: little ui stuff
---
extension/react-app/src/components/ComboBox.tsx | 3 ++-
extension/react-app/src/tabs/gui.tsx | 11 +++--------
2 files changed, 5 insertions(+), 9 deletions(-)
(limited to 'extension')
diff --git a/extension/react-app/src/components/ComboBox.tsx b/extension/react-app/src/components/ComboBox.tsx
index 585a0584..ac994b0a 100644
--- a/extension/react-app/src/components/ComboBox.tsx
+++ b/extension/react-app/src/components/ComboBox.tsx
@@ -378,7 +378,8 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => {
{highlightedCodeSections.length === 0 &&
- (downshiftProps.inputValue?.startsWith("/edit") || metaKeyPressed) && (
+ (downshiftProps.inputValue?.startsWith("/edit") ||
+ (metaKeyPressed && downshiftProps.inputValue?.length > 0)) && (
Inserting at cursor
diff --git a/extension/react-app/src/tabs/gui.tsx b/extension/react-app/src/tabs/gui.tsx
index 0e60e05c..619b91e1 100644
--- a/extension/react-app/src/tabs/gui.tsx
+++ b/extension/react-app/src/tabs/gui.tsx
@@ -170,6 +170,7 @@ function GUI(props: GUIProps) {
const waitingForSteps =
state.active &&
state.history.current_index < state.history.timeline.length &&
+ state.history.timeline[state.history.current_index] &&
state.history.timeline[
state.history.current_index
].step.description?.trim() === "";
@@ -236,14 +237,14 @@ function GUI(props: GUIProps) {
history.current_index < history.timeline.length
) {
if (
- history.timeline[history.current_index].step.name ===
+ history.timeline[history.current_index]?.step.name ===
"Waiting for user input"
) {
if (input.trim() === "") return;
onStepUserInput(input, history!.current_index);
return;
} else if (
- history.timeline[history.current_index].step.name ===
+ history.timeline[history.current_index]?.step.name ===
"Waiting for user confirmation"
) {
onStepUserInput("ok", history!.current_index);
@@ -350,12 +351,6 @@ function GUI(props: GUIProps) {
{
onMainTextInput(e);
--
cgit v1.2.3-70-g09d2
From 64e9877d2929f36aa2af94708620d3f2247ebebb Mon Sep 17 00:00:00 2001
From: Nate Sesti
Date: Tue, 11 Jul 2023 15:14:03 -0700
Subject: check for old version of Continue, notify
---
extension/src/activation/activate.ts | 22 +++++++++++++++++++++-
extension/src/activation/environmentSetup.ts | 2 +-
2 files changed, 22 insertions(+), 2 deletions(-)
(limited to 'extension')
diff --git a/extension/src/activation/activate.ts b/extension/src/activation/activate.ts
index 18650561..2c5ba58c 100644
--- a/extension/src/activation/activate.ts
+++ b/extension/src/activation/activate.ts
@@ -7,9 +7,16 @@ import IdeProtocolClient from "../continueIdeClient";
import { getContinueServerUrl } from "../bridge";
import { CapturedTerminal } from "../terminal/terminalEmulator";
import { setupDebugPanel, ContinueGUIWebviewViewProvider } from "../debugPanel";
-import { startContinuePythonServer } from "./environmentSetup";
+import {
+ getExtensionVersion,
+ startContinuePythonServer,
+} from "./environmentSetup";
+import fetch from "node-fetch";
// import { CapturedTerminal } from "../terminal/terminalEmulator";
+const PACKAGE_JSON_RAW_GITHUB_URL =
+ "https://raw.githubusercontent.com/continuedev/continue/main/extension/package.json";
+
export let extensionContext: vscode.ExtensionContext | undefined = undefined;
export let ideProtocolClient: IdeProtocolClient;
@@ -20,6 +27,19 @@ export async function activateExtension(
) {
extensionContext = context;
+ // Before anything else, check whether this is an out-of-date version of the extension
+ // Do so by grabbing the package.json off of the GitHub respository for now.
+ fetch(PACKAGE_JSON_RAW_GITHUB_URL)
+ .then(async (res) => res.json())
+ .then((packageJson) => {
+ if (packageJson.version !== getExtensionVersion()) {
+ vscode.window.showInformationMessage(
+ `You are using an out-of-date version of the Continue extension. Please update to the latest version.`
+ );
+ }
+ })
+ .catch((e) => console.log("Error checking for extension updates: ", e));
+
await new Promise((resolve, reject) => {
vscode.window.withProgress(
{
diff --git a/extension/src/activation/environmentSetup.ts b/extension/src/activation/environmentSetup.ts
index 881da9b5..c277a539 100644
--- a/extension/src/activation/environmentSetup.ts
+++ b/extension/src/activation/environmentSetup.ts
@@ -351,7 +351,7 @@ function requirementsVersionPath(): string {
return path.join(serverPath(), "requirements_version.txt");
}
-function getExtensionVersion() {
+export function getExtensionVersion() {
const extension = vscode.extensions.getExtension("continue.continue");
return extension?.packageJSON.version || "";
}
--
cgit v1.2.3-70-g09d2
From a6c2490bc32dd670f4afaf6db097422e920404e8 Mon Sep 17 00:00:00 2001
From: Nate Sesti
Date: Tue, 11 Jul 2023 15:51:26 -0700
Subject: patch
---
extension/package-lock.json | 4 ++--
extension/package.json | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
(limited to 'extension')
diff --git a/extension/package-lock.json b/extension/package-lock.json
index b6147b2c..683bf261 100644
--- a/extension/package-lock.json
+++ b/extension/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "continue",
- "version": "0.0.151",
+ "version": "0.0.152",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "continue",
- "version": "0.0.151",
+ "version": "0.0.152",
"license": "Apache-2.0",
"dependencies": {
"@electron/rebuild": "^3.2.10",
diff --git a/extension/package.json b/extension/package.json
index a57f6065..a0f970ed 100644
--- a/extension/package.json
+++ b/extension/package.json
@@ -14,7 +14,7 @@
"displayName": "Continue",
"pricing": "Free",
"description": "The open-source coding autopilot",
- "version": "0.0.151",
+ "version": "0.0.152",
"publisher": "Continue",
"engines": {
"vscode": "^1.67.0"
--
cgit v1.2.3-70-g09d2
From 72ade108029a1f3a1f5964501ff4670e655efa6b Mon Sep 17 00:00:00 2001
From: Nate Sesti
Date: Tue, 11 Jul 2023 16:40:11 -0700
Subject: explain accept/reject, better edit summaries
---
continuedev/src/continuedev/steps/core/core.py | 19 ++++++++++++-----
extension/src/diffs.ts | 29 ++++++++++++++++++++++++--
2 files changed, 41 insertions(+), 7 deletions(-)
(limited to 'extension')
diff --git a/continuedev/src/continuedev/steps/core/core.py b/continuedev/src/continuedev/steps/core/core.py
index d4d067ba..9eddc03f 100644
--- a/continuedev/src/continuedev/steps/core/core.py
+++ b/continuedev/src/continuedev/steps/core/core.py
@@ -152,7 +152,8 @@ class DefaultModelEditCodeStep(Step):
Main task:
""")
-
+ _previous_contents: str = ""
+ _new_contents: str = ""
_prompt_and_completion: str = ""
def _cleanup_output(self, output: str) -> str:
@@ -167,13 +168,19 @@ class DefaultModelEditCodeStep(Step):
return output
async def describe(self, models: Models) -> Coroutine[str, None, None]:
- if self._prompt_and_completion == "":
+ if self._previous_contents.strip() == self._new_contents.strip():
description = "No edits were made"
else:
description = await models.gpt3516k.complete(dedent(f"""\
- {self._prompt_and_completion}
-
- Please give brief a description of the changes made above using markdown bullet points. Be concise and only mention changes made to the commit before, not prefix or suffix:"""))
+ ```original
+ {self._previous_contents}
+ ```
+
+ ```new
+ {self._new_contents}
+ ```
+
+ Please give brief a description of the changes made above using markdown bullet points. Be concise:"""))
name = await models.gpt3516k.complete(f"Write a very short title to describe this requested change (no quotes): '{self.user_input}'. This is the title:")
self.name = self._cleanup_output(name)
@@ -573,6 +580,8 @@ Please output the code to be inserted at the cursor in order to fulfill the user
# Record the completion
completion = "\n".join(lines)
+ self._previous_contents = "\n".join(original_lines)
+ self._new_contents = completion
self._prompt_and_completion += prompt + completion
async def run(self, sdk: ContinueSDK) -> Coroutine[Observation, None, None]:
diff --git a/extension/src/diffs.ts b/extension/src/diffs.ts
index 3ea6b4f8..28089fc6 100644
--- a/extension/src/diffs.ts
+++ b/extension/src/diffs.ts
@@ -2,7 +2,7 @@ import * as os from "os";
import * as path from "path";
import * as fs from "fs";
import * as vscode from "vscode";
-import { ideProtocolClient } from "./activation/activate";
+import { extensionContext, ideProtocolClient } from "./activation/activate";
interface DiffInfo {
originalFilepath: string;
@@ -70,6 +70,28 @@ class DiffManager {
.getConfiguration("diffEditor", editor.document.uri)
.update("codeLens", true, vscode.ConfigurationTarget.Global);
+ if (
+ extensionContext?.globalState.get(
+ "continue.showDiffInfoMessage"
+ ) !== false
+ ) {
+ vscode.window
+ .showInformationMessage(
+ "Accept (⌘⇧↩) or reject (⌘⇧⌫) at the top of the file.",
+ "Got it",
+ "Don't show again"
+ )
+ .then((selection) => {
+ if (selection === "Don't show again") {
+ // Get the global state
+ extensionContext?.globalState.update(
+ "continue.showDiffInfoMessage",
+ false
+ );
+ }
+ });
+ }
+
return editor;
}
@@ -152,7 +174,10 @@ class DiffManager {
newFilepath = Array.from(this.diffs.keys())[0];
}
if (!newFilepath) {
- console.log("No newFilepath provided to reject the diff");
+ console.log(
+ "No newFilepath provided to reject the diff, diffs.size was",
+ this.diffs.size
+ );
return;
}
const diffInfo = this.diffs.get(newFilepath);
--
cgit v1.2.3-70-g09d2
From 67d6a3f0ea00e55aea47b4eeff4cdb0d8321ce2f Mon Sep 17 00:00:00 2001
From: Nate Sesti
Date: Tue, 11 Jul 2023 18:25:48 -0700
Subject: onboarding fix
---
extension/react-app/src/components/Onboarding.tsx | 27 +++++++++--------------
1 file changed, 11 insertions(+), 16 deletions(-)
(limited to 'extension')
diff --git a/extension/react-app/src/components/Onboarding.tsx b/extension/react-app/src/components/Onboarding.tsx
index 061faba5..1b37acc4 100644
--- a/extension/react-app/src/components/Onboarding.tsx
+++ b/extension/react-app/src/components/Onboarding.tsx
@@ -87,25 +87,20 @@ const Onboarding = () => {
paddingRight: "50px",
paddingBottom: "50px",
textAlign: "center",
+ cursor: "pointer",
}}
>
-
+ By turning on this switch, you will begin collecting accepted and
+ rejected suggestions in .continue/suggestions.json. This data is stored
+ locally on your machine and not sent anywhere.
+
+
+
+ {dataSwitchChecked
+ ? "👍 Data is being collected"
+ : "👎 No data is being collected"}
+
+
- By turning on this switch, you will begin collecting accepted and
- rejected suggestions in .continue/suggestions.json. This data is stored
- locally on your machine and not sent anywhere.
-
-
-
- {dataSwitchChecked
- ? "👍 Data is being collected"
- : "👎 No data is being collected"}
-
-