Skip to content

Commit

Permalink
feat: Add opt in webview that is shown prior to enabling the coding a…
Browse files Browse the repository at this point in the history
…ssistant (#200)
  • Loading branch information
brendanator authored Aug 8, 2023
1 parent 3076cef commit 489e0cc
Show file tree
Hide file tree
Showing 6 changed files with 198 additions and 88 deletions.
16 changes: 12 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,37 +51,45 @@
},
"views": {
"sourcery-explorer": [
{
"id": "sourcery.coding_assistant_opt_in",
"name": "Coding Assistant",
"type": "webview",
"icon": "sourcery-icon.png",
"contextualTitle": "Coding Assistant",
"when": "sourcery.features.coding_assistant && !sourcery.config.coding_assistant.enabled"
},
{
"id": "sourcery.chat",
"name": "Coding Assistant",
"type": "webview",
"icon": "sourcery-icon.png",
"contextualTitle": "Coding Assistant",
"when": "sourcery.features.coding_assistant"
"when": "sourcery.features.coding_assistant && sourcery.config.coding_assistant.enabled === true"
},
{
"id": "sourcery.troubleshooting",
"name": "Troubleshooting",
"type": "webview",
"icon": "sourcery-icon.png",
"contextualTitle": "Troubleshooting",
"when": "sourcery.features.coding_assistant && sourcery.features.coding_assistant_troubleshooting && sourcery.features.semantic_search"
"when": "sourcery.features.coding_assistant && sourcery.config.coding_assistant.enabled === true && sourcery.features.coding_assistant_troubleshooting && sourcery.features.semantic_search"
},
{
"id": "sourcery.recipes",
"name": "Recipes",
"type": "webview",
"icon": "sourcery-icon.png",
"contextualTitle": "Recipes",
"when": "sourcery.features.coding_assistant"
"when": "sourcery.features.coding_assistant && sourcery.config.coding_assistant.enabled === true"
},
{
"id": "sourcery.code_review",
"name": "Code Review",
"type": "webview",
"icon": "sourcery-icon.png",
"contextualTitle": "Code Review",
"when": "sourcery.features.coding_assistant && sourcery.features.code_review"
"when": "sourcery.features.coding_assistant && sourcery.config.coding_assistant.enabled === true && sourcery.features.code_review"
},
{
"id": "sourcery.rules",
Expand Down
52 changes: 26 additions & 26 deletions src/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,36 +284,36 @@ export class ChatProvider implements vscode.WebviewViewProvider {
/* eslint-enable @typescript-eslint/naming-convention */

return `<!DOCTYPE html>
<html lang="en" style="height: 100%">
<head>
<meta charset="UTF-8">
<!--
Use a content security policy to only allow loading images from https or from our extension directory,
and only allow scripts that have a specific nonce.
-->
<meta http-equiv="Content-Security-Policy" content="${cspStr}">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="${styleResetUri}" rel="stylesheet">
<link href="${styleVSCodeUri}" rel="stylesheet">
<link href="${styleMainUri}" rel="stylesheet">
<link href="${animationsUri}" rel="stylesheet">
<link href="${hljsUri}" rel="stylesheet">
</head>
<body class="sidebar__chat-assistant-body">
<html lang="en" style="height: 100%">
<head>
<meta charset="UTF-8">
<!--
Use a content security policy to only allow loading images from https or from our extension directory,
and only allow scripts that have a specific nonce.
-->
<meta http-equiv="Content-Security-Policy" content="${cspStr}">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="${styleResetUri}" rel="stylesheet">
<link href="${styleVSCodeUri}" rel="stylesheet">
<link href="${styleMainUri}" rel="stylesheet">
<link href="${animationsUri}" rel="stylesheet">
<link href="${hljsUri}" rel="stylesheet">
</head>
<body class="sidebar__chat-assistant-body">
<section id="message-container" class="sidebar__section-container active" data-section="chat-assistant">
<ul class="sidebar__chat-assistant--dialogue-container">
</ul>
</section>
<footer class="sidebar__chat-assistant--footer">
<section class="sidebar__chat-assistant--textarea-container">
<button id="cancel-button" class="sidebar__chat-assistant--cancel-button" disabled>
<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" class="sidebar__chat-assistant--regenerate-button-icon">
<path d="m464 256a208 208 0 1 0 -416 0 208 208 0 1 0 416 0zm-464 0a256 256 0 1 1 512 0 256 256 0 1 1 -512 0zm224-72v144c0 13.3-10.7 24-24 24s-24-10.7-24-24v-144c0-13.3 10.7-24 24-24s24 10.7 24 24zm112 0v144c0 13.3-10.7 24-24 24s-24-10.7-24-24v-144c0-13.3 10.7-24 24-24s24 10.7 24 24z"></path>
</svg>
<span>Cancel</span>
<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" class="sidebar__chat-assistant--regenerate-button-icon">
<path d="m464 256a208 208 0 1 0 -416 0 208 208 0 1 0 416 0zm-464 0a256 256 0 1 1 512 0 256 256 0 1 1 -512 0zm224-72v144c0 13.3-10.7 24-24 24s-24-10.7-24-24v-144c0-13.3 10.7-24 24-24s24 10.7 24 24zm112 0v144c0 13.3-10.7 24-24 24s-24-10.7-24-24v-144c0-13.3 10.7-24 24-24s24 10.7 24 24z"></path>
</svg>
<span>Cancel</span>
</button>
<textarea class="sidebar__chat-assistant--textarea" placeholder="Type your message here!"
id="user-prompt"></textarea>
Expand All @@ -327,9 +327,9 @@ export class ChatProvider implements vscode.WebviewViewProvider {
</button>
</section>
</footer>
</body>
<script nonce="${nonce}" src="${scriptUri}"></script>
</html>`;
</body>
<script nonce="${nonce}" src="${scriptUri}"></script>
</html>`;
}
}

Expand Down
76 changes: 38 additions & 38 deletions src/code-review.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,53 +224,53 @@ export class CodeReviewProvider implements vscode.WebviewViewProvider {
/* eslint-enable @typescript-eslint/naming-convention */

return `<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/html">
<head>
<meta charset="UTF-8">
<!--
Use a content security policy to only allow loading images from https or from our extension directory,
and only allow scripts that have a specific nonce.
-->
<meta http-equiv="Content-Security-Policy" content="${cspStr}">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="${styleResetUri}" rel="stylesheet">
<link href="${styleVSCodeUri}" rel="stylesheet">
<html lang="en" xmlns="http://www.w3.org/1999/html">
<head>
<meta charset="UTF-8">
<!--
Use a content security policy to only allow loading images from https or from our extension directory,
and only allow scripts that have a specific nonce.
-->
<meta http-equiv="Content-Security-Policy" content="${cspStr}">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="${styleResetUri}" rel="stylesheet">
<link href="${styleVSCodeUri}" rel="stylesheet">
<link href="${styleMainUri}" rel="stylesheet">
<link href="${animationsUri}" rel="stylesheet">
<link href="${animationsUri}" rel="stylesheet">
<link href="${hljsUri}" rel="stylesheet">
</head>
<body class="sidebar__chat-assistant-body">
</head>
<body class="sidebar__chat-assistant-body">
<section class="review-button-section">
<div class="sidebar__diff-options-container">
<div class="sidebar__branch-form">
<label for="currentBranch" class="columnOne">Current Branch</label>
<input type="text" class="currentBranch columnTwo" nonce="${nonce}">
<label for="mainBranch" class="columnOne">Main Branch</label>
<input type="text" class="mainBranch columnTwo" nonce="${nonce}">
</div>
</div>
<div class="btnContainer">
<button class="review-button" >Review My Code</button>
<div class="sidebar__diff-options-container">
<div class="sidebar__branch-form">
<label for="currentBranch" class="columnOne">Current Branch</label>
<input type="text" class="currentBranch columnTwo" nonce="${nonce}">
<label for="mainBranch" class="columnOne">Main Branch</label>
<input type="text" class="mainBranch columnTwo" nonce="${nonce}">
</div>
</div>
<div class="btnContainer">
<button class="review-button" >Review My Code</button>
</div>
</section>
<section id="message-container" class="sidebar__section-container active" data-section="chat-assistant">
<ul class="sidebar__chat-assistant--dialogue-container">
</ul>
</section>
</body>
<footer class="sidebar__chat-assistant--footer">
<section class="sidebar__chat-assistant--textarea-container">
<button id="cancel-button" class="sidebar__chat-assistant--cancel-button" disabled>
<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" class="sidebar__chat-assistant--regenerate-button-icon">
<path d="m464 256a208 208 0 1 0 -416 0 208 208 0 1 0 416 0zm-464 0a256 256 0 1 1 512 0 256 256 0 1 1 -512 0zm224-72v144c0 13.3-10.7 24-24 24s-24-10.7-24-24v-144c0-13.3 10.7-24 24-24s24 10.7 24 24zm112 0v144c0 13.3-10.7 24-24 24s-24-10.7-24-24v-144c0-13.3 10.7-24 24-24s24 10.7 24 24z"></path>
</svg>
<span>Cancel</span>
</button>
</section>
</footer>
<script nonce="${nonce}" src="${scriptUri}"></script>
</html>`;
</body>
<footer class="sidebar__chat-assistant--footer">
<section class="sidebar__chat-assistant--textarea-container">
<button id="cancel-button" class="sidebar__chat-assistant--cancel-button" disabled>
<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" class="sidebar__chat-assistant--regenerate-button-icon">
<path d="m464 256a208 208 0 1 0 -416 0 208 208 0 1 0 416 0zm-464 0a256 256 0 1 1 512 0 256 256 0 1 1 -512 0zm224-72v144c0 13.3-10.7 24-24 24s-24-10.7-24-24v-144c0-13.3 10.7-24 24-24s24 10.7 24 24zm112 0v144c0 13.3-10.7 24-24 24s-24-10.7-24-24v-144c0-13.3 10.7-24 24-24s24 10.7 24 24z"></path>
</svg>
<span>Cancel</span>
</button>
</section>
</footer>
<script nonce="${nonce}" src="${scriptUri}"></script>
</html>`;
}
}
20 changes: 20 additions & 0 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
import { getHubSrc } from "./hub";
import { RuleInputProvider } from "./rule-search";
import { ScanResultProvider } from "./rule-search-results";
import { CodingAssistantOptInProvider } from "./opt-in";
import { ChatProvider, ChatRequest } from "./chat";
import { RecipeProvider } from "./recipes";
import { CodeReviewProvider } from "./code-review";
Expand Down Expand Up @@ -238,6 +239,16 @@ function registerCommands(
})
);

context.subscriptions.push(
commands.registerCommand("sourcery.coding_assistant.opt_in", () => {
let request: ExecuteCommandParams = {
command: "sourcery.coding_assistant.opt_in",
arguments: [],
};
languageClient.sendRequest(ExecuteCommandRequest.type, request);
})
);

context.subscriptions.push(
commands.registerCommand("sourcery.chat.clearChat", () => {
let request: ExecuteCommandParams = {
Expand Down Expand Up @@ -654,6 +665,15 @@ export function activate(context: ExtensionContext) {

const riProvider = new RuleInputProvider(context);

const codingAssistantOptInProvider = new CodingAssistantOptInProvider();
context.subscriptions.push(
vscode.window.registerWebviewViewProvider(
CodingAssistantOptInProvider.viewType,
codingAssistantOptInProvider,
{ webviewOptions: { retainContextWhenHidden: true } }
)
);

const chatProvider = new ChatProvider(context);

context.subscriptions.push(
Expand Down
82 changes: 82 additions & 0 deletions src/opt-in.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
"use strict";

import { commands, WebviewView, WebviewViewProvider } from "vscode";

type OptInMessage = {
command: "opt-in";
};

export class CodingAssistantOptInProvider implements WebviewViewProvider {
public static readonly viewType = "sourcery.coding_assistant_opt_in";

public async resolveWebviewView(webviewView: WebviewView) {
webviewView.webview.options = {
enableScripts: true,
};

webviewView.webview.onDidReceiveMessage(async (_message: OptInMessage) =>
commands.executeCommand("sourcery.coding_assistant.opt_in")
);

webviewView.webview.html = `<!DOCTYPE html>
<html>
<head>
<title>Opt-In Form</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 20px;
}
h2 {
margin-top: 0px;
margin-bottom: 20px;
}
p {
margin-bottom: 10px;
}
.opt-in-form {
max-width: 400px;
margin: 0 auto;
padding: 20px;
border: 1px solid #ccc;
border-radius: 5px;
}
.opt-in-button {
display: block;
width: 100%;
margin-top: 15px;
padding: 10px;
background-color: #007bff;
color: #fff;
border: none;
border-radius: 5px;
cursor: pointer;
}
</style>
</head>
<body>
<div class="opt-in-form">
<h2>Sourcery Coding Assistant</h2>
<p>By enabling the Sourcery coding assistant, you agree that Sourcery can send your code to third party LLMs for analysis (OpenAI, Anthropic).</p>
<p>None of your code is ever stored on our servers.</p>
<form onsubmit="submitForm(event)">
<button class="opt-in-button">Enable</button>
</form>
</div>
</body>
<script>
function submitForm(event) {
event.preventDefault();
const vscode = acquireVsCodeApi();
vscode.postMessage({ command: 'opt-in' });
}
</script>
</html>`;
}
}
40 changes: 20 additions & 20 deletions src/recipes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,25 +90,25 @@ export class RecipeProvider implements vscode.WebviewViewProvider {
/* eslint-enable @typescript-eslint/naming-convention */

return `<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/html">
<head>
<meta charset="UTF-8">
<!--
Use a content security policy to only allow loading images from https or from our extension directory,
and only allow scripts that have a specific nonce.
-->
<meta http-equiv="Content-Security-Policy" content="${cspStr}">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="${styleResetUri}" rel="stylesheet">
<link href="${styleVSCodeUri}" rel="stylesheet">
<link href="${animationsUri}" rel="stylesheet">
</head>
<body>
<section class="recipe-section">
</section>
</body>
<script nonce="${nonce}" src="${scriptUri}"></script>
</html>`;
<html lang="en" xmlns="http://www.w3.org/1999/html">
<head>
<meta charset="UTF-8">
<!--
Use a content security policy to only allow loading images from https or from our extension directory,
and only allow scripts that have a specific nonce.
-->
<meta http-equiv="Content-Security-Policy" content="${cspStr}">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="${styleResetUri}" rel="stylesheet">
<link href="${styleVSCodeUri}" rel="stylesheet">
<link href="${animationsUri}" rel="stylesheet">
</head>
<body>
<section class="recipe-section">
</section>
</body>
<script nonce="${nonce}" src="${scriptUri}"></script>
</html>`;
}
}

0 comments on commit 489e0cc

Please sign in to comment.