Переглянути джерело

Add 'reset state' debug option; fix kodu login flow after reset state; update Announcement

Saoud Rizwan 1 рік тому
батько
коміт
4af5eee2a5

+ 23 - 0
src/providers/ClaudeDevProvider.ts

@@ -378,6 +378,9 @@ export class ClaudeDevProvider implements vscode.WebviewViewProvider {
 						await this.updateGlobalState("shouldShowKoduPromo", false)
 						await this.postStateToWebview()
 						break
+					case "resetState":
+						await this.resetState()
+						break
 					// Add more switch case statements here as more webview message commands
 					// are created within the webview context (i.e. inside media/main.js)
 				}
@@ -744,4 +747,24 @@ export class ClaudeDevProvider implements vscode.WebviewViewProvider {
 	private async getSecret(key: SecretKey) {
 		return await this.context.secrets.get(key)
 	}
+
+	// dev
+
+	async resetState() {
+		vscode.window.showInformationMessage("Resetting state...")
+		for (const key of this.context.globalState.keys()) {
+			await this.context.globalState.update(key, undefined)
+		}
+		const secretKeys: SecretKey[] = ["apiKey", "openRouterApiKey", "awsAccessKey", "awsSecretKey", "koduApiKey"]
+		for (const key of secretKeys) {
+			await this.storeSecret(key, undefined)
+		}
+		if (this.claudeDev) {
+			this.claudeDev.abortTask()
+			this.claudeDev = undefined
+		}
+		vscode.window.showInformationMessage("State reset")
+		await this.postStateToWebview()
+		await this.postMessageToWebview({ type: "action", action: "chatButtonTapped" })
+	}
 }

+ 1 - 0
src/shared/WebviewMessage.ts

@@ -19,6 +19,7 @@ export interface WebviewMessage {
 		| "didClickKoduSignOut"
 		| "fetchKoduCredits"
 		| "didDismissKoduPromo"
+		| "resetState"
 	text?: string
 	askResponse?: ClaudeAskResponse
 	apiConfiguration?: ApiConfiguration

+ 10 - 14
webview-ui/src/App.tsx

@@ -33,8 +33,9 @@ const App: React.FC = () => {
 	const [taskHistory, setTaskHistory] = useState<HistoryItem[]>([])
 	const [showAnnouncement, setShowAnnouncement] = useState(false)
 	const [koduCredits, setKoduCredits] = useState<number | undefined>(undefined)
-	const [isNewUser, setIsNewUser] = useState(false)
 	const [shouldShowKoduPromo, setShouldShowKoduPromo] = useState(true)
+	const [didAuthKoduFromWelcome, setDidAuthKoduFromWelcome] = useState<boolean>(false)
+
 	useEffect(() => {
 		vscode.postMessage({ type: "webviewDidLaunch" })
 	}, [])
@@ -51,8 +52,8 @@ const App: React.FC = () => {
 						message.state!.apiConfiguration?.awsAccessKey !== undefined ||
 						message.state!.apiConfiguration?.koduApiKey !== undefined
 					setShowWelcome(!hasKey)
-					if (!hasKey && !isNewUser) {
-						setIsNewUser(true)
+					if (!hasKey) {
+						setDidAuthKoduFromWelcome(false)
 					}
 					setApiConfiguration(message.state!.apiConfiguration)
 					setMaxRequestsPerTask(
@@ -88,31 +89,25 @@ const App: React.FC = () => {
 							setShowSettings(false)
 							setShowHistory(false)
 							break
+						case "koduCreditsFetched":
+							setKoduCredits(message.state!.koduCredits)
+							break
 						case "koduAuthenticated":
-							if (!isNewUser) {
+							if (!didAuthKoduFromWelcome) {
 								setShowSettings(true)
 								setShowHistory(false)
 							}
 							break
-						case "koduCreditsFetched":
-							setKoduCredits(message.state!.koduCredits)
-							break
 					}
 					break
 			}
 			// (react-use takes care of not registering the same listener multiple times even if this callback is updated.)
 		},
-		[isNewUser]
+		[didAuthKoduFromWelcome]
 	)
 
 	useEvent("message", handleMessage)
 
-	useEffect(() => {
-		if (showWelcome === false) {
-			setIsNewUser(false)
-		}
-	}, [showWelcome])
-
 	const { selectedModelInfo } = useMemo(() => {
 		return normalizeApiConfiguration(apiConfiguration)
 	}, [apiConfiguration])
@@ -128,6 +123,7 @@ const App: React.FC = () => {
 					apiConfiguration={apiConfiguration}
 					setApiConfiguration={setApiConfiguration}
 					vscodeUriScheme={vscodeUriScheme}
+					setDidAuthKoduFromWelcome={setDidAuthKoduFromWelcome}
 				/>
 			) : (
 				<>

+ 8 - 8
webview-ui/src/components/Announcement.tsx

@@ -32,11 +32,11 @@ const Announcement = ({ version, hideAnnouncement, apiConfiguration, vscodeUriSc
 				🎉{"  "}New in v{version}
 			</h3>
 
-			<ul style={{ margin: "0 0 8px", paddingLeft: "20px" }}>
+			<ul style={{ margin: "0 0 8px", paddingLeft: "12px" }}>
 				<li>
-					Excited to announce that we've partnered with Anthropic and are offering $20 free credits to help
-					users get the most out of Claude Dev with high rate limits and prompt caching! Stay tuned for some
-					exciting updates like easier billing, voice mode and one click deployment.
+					Excited to announce that we've partnered with Anthropic and are offering <b>$20 free credits</b> to
+					help users get the most out of Claude Dev with increased rate limits and prompt caching! Stay tuned
+					for some exciting updates like easier billing, voice mode and one click deployment!
 					{apiConfiguration?.koduApiKey === undefined && (
 						<VSCodeButtonLink
 							appearance="secondary"
@@ -44,17 +44,17 @@ const Announcement = ({ version, hideAnnouncement, apiConfiguration, vscodeUriSc
 							style={{
 								transform: "scale(0.85)",
 								transformOrigin: "left center",
-								margin: "4px 0 2px 0",
+								margin: "4px -30px 2px 0",
 							}}>
-							Claim $20 Free Credits with Kodu
+							Claim $20 Credits on Kodu
 						</VSCodeButtonLink>
 					)}
 				</li>
 				<li>
 					Added "Always allow read-only operations" setting to let Claude read files and view directories
-					without needing to approve (off by default)
+					without needing to approve (off by default).
 				</li>
-				<li>Added sliding window context management to keep tasks going past 200k tokens</li>
+				<li>Added sliding window context management to keep tasks going past 200k tokens.</li>
 			</ul>
 			<p style={{ margin: "0" }}>
 				Follow me for more updates!{" "}

+ 5 - 1
webview-ui/src/components/ApiOptions.tsx

@@ -26,6 +26,7 @@ interface ApiOptionsProps {
 	koduCredits?: number
 	apiErrorMessage?: string
 	vscodeUriScheme?: string
+	setDidAuthKodu?: React.Dispatch<React.SetStateAction<boolean>>
 }
 
 const ApiOptions: React.FC<ApiOptionsProps> = ({
@@ -35,6 +36,7 @@ const ApiOptions: React.FC<ApiOptionsProps> = ({
 	koduCredits,
 	apiErrorMessage,
 	vscodeUriScheme,
+	setDidAuthKodu,
 }) => {
 	const [, setDidFetchKoduCredits] = useState(false)
 	const handleInputChange = (field: keyof ApiConfiguration) => (event: any) => {
@@ -192,7 +194,9 @@ const ApiOptions: React.FC<ApiOptionsProps> = ({
 						</>
 					) : (
 						<div style={{ margin: "4px 0px" }}>
-							<VSCodeButtonLink href={getKoduSignInUrl(vscodeUriScheme)}>
+							<VSCodeButtonLink
+								href={getKoduSignInUrl(vscodeUriScheme)}
+								onClick={() => setDidAuthKodu?.(true)}>
 								Sign in to Kodu
 							</VSCodeButtonLink>
 						</div>

+ 23 - 0
webview-ui/src/components/SettingsView.tsx

@@ -11,6 +11,8 @@ import { validateApiConfiguration, validateMaxRequestsPerTask } from "../utils/v
 import { vscode } from "../utils/vscode"
 import ApiOptions from "./ApiOptions"
 
+const IS_DEV = true
+
 type SettingsViewProps = {
 	version: string
 	apiConfiguration?: ApiConfiguration
@@ -79,6 +81,10 @@ const SettingsView = ({
 	If we only want to run code once on mount we can use react-use's useEffectOnce or useMount
 	*/
 
+	const handleResetState = () => {
+		vscode.postMessage({ type: "resetState" })
+	}
+
 	return (
 		<div
 			style={{
@@ -183,6 +189,23 @@ const SettingsView = ({
 					)}
 				</div>
 
+				{IS_DEV && (
+					<>
+						<div style={{ marginTop: "10px", marginBottom: "4px" }}>Debug</div>
+						<VSCodeButton onClick={handleResetState} style={{ marginTop: "5px", width: "auto" }}>
+							Reset State
+						</VSCodeButton>
+						<p
+							style={{
+								fontSize: "12px",
+								marginTop: "5px",
+								color: "var(--vscode-descriptionForeground)",
+							}}>
+							This will reset all global state and secret storage in the extension.
+						</p>
+					</>
+				)}
+
 				<div
 					style={{
 						textAlign: "center",

+ 8 - 1
webview-ui/src/components/WelcomeView.tsx

@@ -10,9 +10,15 @@ interface WelcomeViewProps {
 	apiConfiguration?: ApiConfiguration
 	setApiConfiguration: React.Dispatch<React.SetStateAction<ApiConfiguration | undefined>>
 	vscodeUriScheme?: string
+	setDidAuthKoduFromWelcome: React.Dispatch<React.SetStateAction<boolean>>
 }
 
-const WelcomeView: React.FC<WelcomeViewProps> = ({ apiConfiguration, setApiConfiguration, vscodeUriScheme }) => {
+const WelcomeView: React.FC<WelcomeViewProps> = ({
+	apiConfiguration,
+	setApiConfiguration,
+	vscodeUriScheme,
+	setDidAuthKoduFromWelcome,
+}) => {
 	const [apiErrorMessage, setApiErrorMessage] = useState<string | undefined>(undefined)
 
 	const disableLetsGoButton = apiErrorMessage != null
@@ -73,6 +79,7 @@ const WelcomeView: React.FC<WelcomeViewProps> = ({ apiConfiguration, setApiConfi
 					setApiConfiguration={setApiConfiguration}
 					showModelOptions={false}
 					vscodeUriScheme={vscodeUriScheme}
+					setDidAuthKodu={setDidAuthKoduFromWelcome}
 				/>
 				{apiConfiguration?.apiProvider !== "kodu" && (
 					<VSCodeButton onClick={handleSubmit} disabled={disableLetsGoButton} style={{ marginTop: "3px" }}>