mirror of
https://github.com/pacnpal/Roo-Code.git
synced 2025-12-20 12:21:13 -05:00
Add secret and global state management + messaging between web and extension; persist API key and max num requests; add Welcome screen
This commit is contained in:
@@ -1,12 +1,69 @@
|
||||
import React from "react"
|
||||
import React, { useEffect, useState } from "react"
|
||||
import { VSCodeTextField, VSCodeDivider, VSCodeLink, VSCodeButton } from "@vscode/webview-ui-toolkit/react"
|
||||
import { vscode } from "../utilities/vscode"
|
||||
|
||||
const SettingsView = () => {
|
||||
const handleDoneClick = () => {
|
||||
// Add your logic here for what should happen when the Done button is clicked
|
||||
console.log("Done button clicked")
|
||||
type SettingsViewProps = {
|
||||
apiKey: string
|
||||
setApiKey: React.Dispatch<React.SetStateAction<string>>
|
||||
maxRequestsPerTask: string
|
||||
setMaxRequestsPerTask: React.Dispatch<React.SetStateAction<string>>
|
||||
onDone: () => void // Define the type of the onDone prop
|
||||
}
|
||||
|
||||
const SettingsView = ({ apiKey, setApiKey, maxRequestsPerTask, setMaxRequestsPerTask, onDone }: SettingsViewProps) => {
|
||||
const [apiKeyErrorMessage, setApiKeyErrorMessage] = useState<string | undefined>(undefined)
|
||||
const [maxRequestsErrorMessage, setMaxRequestsErrorMessage] = useState<string | undefined>(undefined)
|
||||
|
||||
const disableDoneButton = apiKeyErrorMessage != null || maxRequestsErrorMessage != null
|
||||
|
||||
const handleApiKeyChange = (event: any) => {
|
||||
const input = event.target.value
|
||||
setApiKey(input)
|
||||
validateApiKey(input)
|
||||
}
|
||||
|
||||
const validateApiKey = (value: string) => {
|
||||
if (value.trim() === "") {
|
||||
setApiKeyErrorMessage("API Key cannot be empty")
|
||||
} else {
|
||||
setApiKeyErrorMessage(undefined)
|
||||
}
|
||||
}
|
||||
|
||||
const handleMaxRequestsChange = (event: any) => {
|
||||
const input = event.target.value
|
||||
setMaxRequestsPerTask(input)
|
||||
validateMaxRequests(input)
|
||||
}
|
||||
|
||||
const validateMaxRequests = (value: string | undefined) => {
|
||||
if (value?.trim()) {
|
||||
const num = Number(value)
|
||||
if (isNaN(num)) {
|
||||
setMaxRequestsErrorMessage("Maximum requests must be a number")
|
||||
} else if (num < 3 || num > 100) {
|
||||
setMaxRequestsErrorMessage("Maximum requests must be between 3 and 100")
|
||||
} else {
|
||||
setMaxRequestsErrorMessage(undefined)
|
||||
}
|
||||
} else {
|
||||
setMaxRequestsErrorMessage(undefined)
|
||||
}
|
||||
}
|
||||
|
||||
const handleSubmit = () => {
|
||||
vscode.postMessage({ type: "apiKey", text: apiKey })
|
||||
vscode.postMessage({ type: "maxRequestsPerTask", text: maxRequestsPerTask })
|
||||
|
||||
onDone()
|
||||
}
|
||||
|
||||
// validate as soon as the component is mounted
|
||||
useEffect(() => {
|
||||
validateApiKey(apiKey)
|
||||
validateMaxRequests(maxRequestsPerTask)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div style={{ margin: "0 auto", paddingTop: "10px" }}>
|
||||
<div
|
||||
@@ -14,16 +71,32 @@ const SettingsView = () => {
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
marginBottom: "20px",
|
||||
marginBottom: "17px",
|
||||
}}>
|
||||
<h2 style={{ color: "var(--vscode-foreground)", margin: 0 }}>Settings</h2>
|
||||
<VSCodeButton onClick={handleDoneClick}>Done</VSCodeButton>
|
||||
<h3 style={{ color: "var(--vscode-foreground)", margin: 0 }}>Settings</h3>
|
||||
<VSCodeButton onClick={handleSubmit} disabled={disableDoneButton}>
|
||||
Done
|
||||
</VSCodeButton>
|
||||
</div>
|
||||
|
||||
<div style={{ marginBottom: "20px" }}>
|
||||
<VSCodeTextField style={{ width: "100%" }} placeholder="Enter your Anthropic API Key">
|
||||
<VSCodeTextField
|
||||
value={apiKey}
|
||||
style={{ width: "100%" }}
|
||||
placeholder="Enter your Anthropic API Key"
|
||||
onInput={handleApiKeyChange}>
|
||||
Anthropic API Key
|
||||
</VSCodeTextField>
|
||||
{apiKeyErrorMessage && (
|
||||
<p
|
||||
style={{
|
||||
fontSize: "12px",
|
||||
marginTop: "5px",
|
||||
color: "var(--vscode-errorForeground)",
|
||||
}}>
|
||||
{apiKeyErrorMessage}
|
||||
</p>
|
||||
)}
|
||||
<p
|
||||
style={{
|
||||
fontSize: "12px",
|
||||
@@ -38,9 +111,23 @@ const SettingsView = () => {
|
||||
</div>
|
||||
|
||||
<div style={{ marginBottom: "20px" }}>
|
||||
<VSCodeTextField style={{ width: "100%" }} placeholder="Enter maximum number of requests">
|
||||
<VSCodeTextField
|
||||
value={maxRequestsPerTask}
|
||||
style={{ width: "100%" }}
|
||||
placeholder="20"
|
||||
onInput={handleMaxRequestsChange}>
|
||||
Maximum # Requests Per Task
|
||||
</VSCodeTextField>
|
||||
{maxRequestsErrorMessage && (
|
||||
<p
|
||||
style={{
|
||||
fontSize: "12px",
|
||||
marginTop: "5px",
|
||||
color: "var(--vscode-errorForeground)",
|
||||
}}>
|
||||
{maxRequestsErrorMessage}
|
||||
</p>
|
||||
)}
|
||||
<p
|
||||
style={{
|
||||
fontSize: "12px",
|
||||
@@ -65,7 +152,7 @@ const SettingsView = () => {
|
||||
}}>
|
||||
<p>Made possible by the latest breakthroughs in Claude 3.5 Sonnet's agentic coding capabilities.</p>
|
||||
<p>
|
||||
This project was submitted to Anthropic's<br/>"Build with Claude June 2024 contest"
|
||||
This project was made for Anthropic's "Build with Claude June 2024 contest"
|
||||
<VSCodeLink href="https://github.com/saoudrizwan/claude-dev">
|
||||
https://github.com/saoudrizwan/claude-dev
|
||||
</VSCodeLink>
|
||||
|
||||
91
webview-ui/src/components/WelcomeView.tsx
Normal file
91
webview-ui/src/components/WelcomeView.tsx
Normal file
@@ -0,0 +1,91 @@
|
||||
import React, { useState, useEffect } from "react"
|
||||
import { VSCodeButton, VSCodeTextField, VSCodeLink, VSCodeDivider } from "@vscode/webview-ui-toolkit/react"
|
||||
import { vscode } from "../utilities/vscode"
|
||||
|
||||
interface WelcomeViewProps {
|
||||
apiKey: string
|
||||
setApiKey: React.Dispatch<React.SetStateAction<string>>
|
||||
}
|
||||
|
||||
const WelcomeView: React.FC<WelcomeViewProps> = ({ apiKey, setApiKey }) => {
|
||||
const [apiKeyErrorMessage, setApiKeyErrorMessage] = useState<string | undefined>(undefined)
|
||||
|
||||
const disableLetsGoButton = apiKeyErrorMessage != null
|
||||
|
||||
const handleApiKeyChange = (event: any) => {
|
||||
const input = event.target.value
|
||||
setApiKey(input)
|
||||
validateApiKey(input)
|
||||
}
|
||||
|
||||
const validateApiKey = (value: string) => {
|
||||
if (value.trim() === "") {
|
||||
setApiKeyErrorMessage("API Key cannot be empty")
|
||||
} else {
|
||||
setApiKeyErrorMessage(undefined)
|
||||
}
|
||||
}
|
||||
|
||||
const handleSubmit = () => {
|
||||
vscode.postMessage({ type: "apiKey", text: apiKey })
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
validateApiKey(apiKey)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div style={{ maxWidth: "600px", margin: "0 auto", padding: "20px" }}>
|
||||
<h1 style={{ color: "var(--vscode-foreground)" }}>Hi, I'm Claude Dev</h1>
|
||||
<p>
|
||||
I can do all kinds of tasks thanks to the latest breakthroughs in Claude Sonnet 3.5's agentic coding
|
||||
capabilities. I am prompted to think through tasks step-by-step and have access to tools that let me get
|
||||
information about your project, read & write code, and execute terminal commands (with your permission,
|
||||
of course).
|
||||
</p>
|
||||
|
||||
<h3>Here are some cool things I can do:</h3>
|
||||
<ul>
|
||||
<li>Create new projects from scratch based on your requirements</li>
|
||||
<li>Debug and fix code issues in your existing projects</li>
|
||||
<li>Refactor and optimize your codebase</li>
|
||||
<li>Analyze your system's performance and suggest improvements</li>
|
||||
<li>Generate documentation for your code</li>
|
||||
<li>Set up and configure development environments</li>
|
||||
<li>Perform code reviews and suggest best practices</li>
|
||||
</ul>
|
||||
|
||||
<h3>To get started, this extension needs an Anthropic API key:</h3>
|
||||
<ol>
|
||||
<li>
|
||||
Go to{" "}
|
||||
<VSCodeLink href="https://console.anthropic.com/" style={{ display: "inline" }}>
|
||||
https://console.anthropic.com/
|
||||
</VSCodeLink>
|
||||
</li>
|
||||
<li>You may need to buy some credits (although Anthropic is offering $5 free credit for new users)</li>
|
||||
<li>Click 'Get API Keys' and create a new key for me (you can delete it any time)</li>
|
||||
</ol>
|
||||
|
||||
<VSCodeDivider />
|
||||
|
||||
<div style={{ marginTop: "20px", display: "flex", alignItems: "center" }}>
|
||||
<VSCodeTextField
|
||||
style={{ flexGrow: 1, marginRight: "10px" }}
|
||||
placeholder="Enter your Anthropic API Key"
|
||||
value={apiKey}
|
||||
onInput={handleApiKeyChange}
|
||||
/>
|
||||
<VSCodeButton onClick={handleSubmit} disabled={disableLetsGoButton}>
|
||||
Let's go!
|
||||
</VSCodeButton>
|
||||
</div>
|
||||
|
||||
<p style={{ fontSize: "12px", marginTop: "10px", color: "var(--vscode-descriptionForeground)" }}>
|
||||
Your API key is stored securely on your computer and used only for interacting with the Anthropic API.
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default WelcomeView
|
||||
Reference in New Issue
Block a user