mirror of
https://github.com/pacnpal/Roo-Code.git
synced 2025-12-20 12:21:13 -05:00
Refactor Kodu links
This commit is contained in:
@@ -1,23 +1,11 @@
|
|||||||
import { Anthropic } from "@anthropic-ai/sdk"
|
import { Anthropic } from "@anthropic-ai/sdk"
|
||||||
|
import axios from "axios"
|
||||||
import { ApiHandler, withoutImageData } from "."
|
import { ApiHandler, withoutImageData } from "."
|
||||||
import { ApiHandlerOptions, koduDefaultModelId, KoduModelId, koduModels, ModelInfo } from "../shared/api"
|
import { ApiHandlerOptions, koduDefaultModelId, KoduModelId, koduModels, ModelInfo } from "../shared/api"
|
||||||
import axios from "axios"
|
import { getKoduCreditsUrl, getKoduInferenceUrl } from "../shared/kodu"
|
||||||
import * as vscode from "vscode"
|
|
||||||
|
|
||||||
const KODU_BASE_URL = "https://claude-dev.com"
|
|
||||||
|
|
||||||
export function didClickKoduSignIn() {
|
|
||||||
const loginUrl = `${KODU_BASE_URL}/auth/login?redirectTo=${vscode.env.uriScheme}://saoudrizwan.claude-dev&ext=1`
|
|
||||||
vscode.env.openExternal(vscode.Uri.parse(loginUrl))
|
|
||||||
}
|
|
||||||
|
|
||||||
export function didClickKoduAddCredits() {
|
|
||||||
const addCreditsUrl = `${KODU_BASE_URL}/user/addCredits?redirectTo=${vscode.env.uriScheme}://saoudrizwan.claude-dev&ext=1`
|
|
||||||
vscode.env.openExternal(vscode.Uri.parse(addCreditsUrl))
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function fetchKoduCredits({ apiKey }: { apiKey: string }) {
|
export async function fetchKoduCredits({ apiKey }: { apiKey: string }) {
|
||||||
const response = await axios.get(`${KODU_BASE_URL}/api/credits`, {
|
const response = await axios.get(getKoduCreditsUrl(), {
|
||||||
headers: {
|
headers: {
|
||||||
"x-api-key": apiKey,
|
"x-api-key": apiKey,
|
||||||
},
|
},
|
||||||
@@ -89,7 +77,7 @@ export class KoduHandler implements ApiHandler {
|
|||||||
tool_choice: { type: "auto" },
|
tool_choice: { type: "auto" },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const response = await axios.post(`${KODU_BASE_URL}/api/inference`, requestBody, {
|
const response = await axios.post(getKoduInferenceUrl(), requestBody, {
|
||||||
headers: {
|
headers: {
|
||||||
"x-api-key": this.options.koduApiKey,
|
"x-api-key": this.options.koduApiKey,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { downloadTask, getNonce, getUri, selectImages } from "../utils"
|
|||||||
import * as path from "path"
|
import * as path from "path"
|
||||||
import fs from "fs/promises"
|
import fs from "fs/promises"
|
||||||
import { HistoryItem } from "../shared/HistoryItem"
|
import { HistoryItem } from "../shared/HistoryItem"
|
||||||
import { didClickKoduAddCredits, didClickKoduSignIn, fetchKoduCredits } from "../api/kodu"
|
import { fetchKoduCredits } from "../api/kodu"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
https://github.com/microsoft/vscode-webview-ui-toolkit-samples/blob/main/default/weather-webview/src/providers/WeatherViewProvider.ts
|
https://github.com/microsoft/vscode-webview-ui-toolkit-samples/blob/main/default/weather-webview/src/providers/WeatherViewProvider.ts
|
||||||
@@ -358,15 +358,9 @@ export class ClaudeDevProvider implements vscode.WebviewViewProvider {
|
|||||||
case "exportTaskWithId":
|
case "exportTaskWithId":
|
||||||
this.exportTaskWithId(message.text!)
|
this.exportTaskWithId(message.text!)
|
||||||
break
|
break
|
||||||
case "didClickKoduSignIn":
|
|
||||||
didClickKoduSignIn()
|
|
||||||
break
|
|
||||||
case "didClickKoduSignOut":
|
case "didClickKoduSignOut":
|
||||||
await this.signOutKodu()
|
await this.signOutKodu()
|
||||||
break
|
break
|
||||||
case "didClickKoduAddCredits":
|
|
||||||
didClickKoduAddCredits()
|
|
||||||
break
|
|
||||||
case "fetchKoduCredits":
|
case "fetchKoduCredits":
|
||||||
const koduApiKey = await this.getSecret("koduApiKey")
|
const koduApiKey = await this.getSecret("koduApiKey")
|
||||||
if (koduApiKey) {
|
if (koduApiKey) {
|
||||||
@@ -515,6 +509,7 @@ export class ClaudeDevProvider implements vscode.WebviewViewProvider {
|
|||||||
customInstructions,
|
customInstructions,
|
||||||
alwaysAllowReadOnly,
|
alwaysAllowReadOnly,
|
||||||
themeName: vscode.workspace.getConfiguration("workbench").get<string>("colorTheme"),
|
themeName: vscode.workspace.getConfiguration("workbench").get<string>("colorTheme"),
|
||||||
|
uriScheme: vscode.env.uriScheme,
|
||||||
claudeMessages: this.claudeDev?.claudeMessages || [],
|
claudeMessages: this.claudeDev?.claudeMessages || [],
|
||||||
taskHistory: (taskHistory || []).filter((item) => item.ts && item.task).sort((a, b) => b.ts - a.ts),
|
taskHistory: (taskHistory || []).filter((item) => item.ts && item.task).sort((a, b) => b.ts - a.ts),
|
||||||
shouldShowAnnouncement: lastShownAnnouncementId !== this.latestAnnouncementId,
|
shouldShowAnnouncement: lastShownAnnouncementId !== this.latestAnnouncementId,
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ export interface ExtensionState {
|
|||||||
customInstructions?: string
|
customInstructions?: string
|
||||||
alwaysAllowReadOnly?: boolean
|
alwaysAllowReadOnly?: boolean
|
||||||
themeName?: string
|
themeName?: string
|
||||||
|
uriScheme?: string
|
||||||
claudeMessages: ClaudeMessage[]
|
claudeMessages: ClaudeMessage[]
|
||||||
taskHistory: HistoryItem[]
|
taskHistory: HistoryItem[]
|
||||||
shouldShowAnnouncement: boolean
|
shouldShowAnnouncement: boolean
|
||||||
|
|||||||
@@ -16,9 +16,7 @@ export interface WebviewMessage {
|
|||||||
| "showTaskWithId"
|
| "showTaskWithId"
|
||||||
| "deleteTaskWithId"
|
| "deleteTaskWithId"
|
||||||
| "exportTaskWithId"
|
| "exportTaskWithId"
|
||||||
| "didClickKoduSignIn"
|
|
||||||
| "didClickKoduSignOut"
|
| "didClickKoduSignOut"
|
||||||
| "didClickKoduAddCredits"
|
|
||||||
| "fetchKoduCredits"
|
| "fetchKoduCredits"
|
||||||
text?: string
|
text?: string
|
||||||
askResponse?: ClaudeAskResponse
|
askResponse?: ClaudeAskResponse
|
||||||
|
|||||||
17
src/shared/kodu.ts
Normal file
17
src/shared/kodu.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
const KODU_BASE_URL = "https://claude-dev.com"
|
||||||
|
|
||||||
|
export function getKoduSignInUrl(uriScheme?: string) {
|
||||||
|
return `${KODU_BASE_URL}/auth/login?redirectTo=${uriScheme}://saoudrizwan.claude-dev&ext=1`
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getKoduAddCreditsUrl(uriScheme?: string) {
|
||||||
|
return `${KODU_BASE_URL}/user/addCredits?redirectTo=${uriScheme}://saoudrizwan.claude-dev&ext=1`
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getKoduCreditsUrl() {
|
||||||
|
return `${KODU_BASE_URL}/api/credits`
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getKoduInferenceUrl() {
|
||||||
|
return `${KODU_BASE_URL}/api/inference`
|
||||||
|
}
|
||||||
@@ -28,6 +28,7 @@ const App: React.FC = () => {
|
|||||||
const [customInstructions, setCustomInstructions] = useState<string>("")
|
const [customInstructions, setCustomInstructions] = useState<string>("")
|
||||||
const [alwaysAllowReadOnly, setAlwaysAllowReadOnly] = useState<boolean>(false)
|
const [alwaysAllowReadOnly, setAlwaysAllowReadOnly] = useState<boolean>(false)
|
||||||
const [vscodeThemeName, setVscodeThemeName] = useState<string | undefined>(undefined)
|
const [vscodeThemeName, setVscodeThemeName] = useState<string | undefined>(undefined)
|
||||||
|
const [vscodeUriScheme, setVscodeUriScheme] = useState<string | undefined>(undefined)
|
||||||
const [claudeMessages, setClaudeMessages] = useState<ClaudeMessage[]>([])
|
const [claudeMessages, setClaudeMessages] = useState<ClaudeMessage[]>([])
|
||||||
const [taskHistory, setTaskHistory] = useState<HistoryItem[]>([])
|
const [taskHistory, setTaskHistory] = useState<HistoryItem[]>([])
|
||||||
const [showAnnouncement, setShowAnnouncement] = useState(false)
|
const [showAnnouncement, setShowAnnouncement] = useState(false)
|
||||||
@@ -62,6 +63,7 @@ const App: React.FC = () => {
|
|||||||
setCustomInstructions(message.state!.customInstructions || "")
|
setCustomInstructions(message.state!.customInstructions || "")
|
||||||
setAlwaysAllowReadOnly(message.state!.alwaysAllowReadOnly || false)
|
setAlwaysAllowReadOnly(message.state!.alwaysAllowReadOnly || false)
|
||||||
setVscodeThemeName(message.state!.themeName)
|
setVscodeThemeName(message.state!.themeName)
|
||||||
|
setVscodeUriScheme(message.state!.uriScheme)
|
||||||
setClaudeMessages(message.state!.claudeMessages)
|
setClaudeMessages(message.state!.claudeMessages)
|
||||||
setTaskHistory(message.state!.taskHistory)
|
setTaskHistory(message.state!.taskHistory)
|
||||||
setKoduCredits(message.state!.koduCredits)
|
setKoduCredits(message.state!.koduCredits)
|
||||||
@@ -121,7 +123,11 @@ const App: React.FC = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{showWelcome ? (
|
{showWelcome ? (
|
||||||
<WelcomeView apiConfiguration={apiConfiguration} setApiConfiguration={setApiConfiguration} />
|
<WelcomeView
|
||||||
|
apiConfiguration={apiConfiguration}
|
||||||
|
setApiConfiguration={setApiConfiguration}
|
||||||
|
vscodeUriScheme={vscodeUriScheme}
|
||||||
|
/>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
{showSettings && (
|
{showSettings && (
|
||||||
@@ -137,6 +143,7 @@ const App: React.FC = () => {
|
|||||||
alwaysAllowReadOnly={alwaysAllowReadOnly}
|
alwaysAllowReadOnly={alwaysAllowReadOnly}
|
||||||
setAlwaysAllowReadOnly={setAlwaysAllowReadOnly}
|
setAlwaysAllowReadOnly={setAlwaysAllowReadOnly}
|
||||||
onDone={() => setShowSettings(false)}
|
onDone={() => setShowSettings(false)}
|
||||||
|
vscodeUriScheme={vscodeUriScheme}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{showHistory && <HistoryView taskHistory={taskHistory} onDone={() => setShowHistory(false)} />}
|
{showHistory && <HistoryView taskHistory={taskHistory} onDone={() => setShowHistory(false)} />}
|
||||||
@@ -159,6 +166,7 @@ const App: React.FC = () => {
|
|||||||
setShowAnnouncement(false)
|
setShowAnnouncement(false)
|
||||||
}}
|
}}
|
||||||
apiConfiguration={apiConfiguration}
|
apiConfiguration={apiConfiguration}
|
||||||
|
vscodeUriScheme={vscodeUriScheme}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1,16 +1,18 @@
|
|||||||
import { VSCodeButton, VSCodeLink } from "@vscode/webview-ui-toolkit/react"
|
import { VSCodeButton, VSCodeLink } from "@vscode/webview-ui-toolkit/react"
|
||||||
import { vscode } from "../utils/vscode"
|
|
||||||
import { ApiConfiguration } from "../../../src/shared/api"
|
import { ApiConfiguration } from "../../../src/shared/api"
|
||||||
|
import { getKoduSignInUrl } from "../../../src/shared/kodu"
|
||||||
|
import VSCodeButtonLink from "./VSCodeButtonLink"
|
||||||
|
|
||||||
interface AnnouncementProps {
|
interface AnnouncementProps {
|
||||||
version: string
|
version: string
|
||||||
hideAnnouncement: () => void
|
hideAnnouncement: () => void
|
||||||
apiConfiguration?: ApiConfiguration
|
apiConfiguration?: ApiConfiguration
|
||||||
|
vscodeUriScheme?: string
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
You must update the latestAnnouncementId in ClaudeDevProvider for new announcements to show to users. This new id will be compared with whats in state for the 'last announcement shown', and if it's different then the announcement will render. As soon as an announcement is shown, the id will be updated in state. This ensures that announcements are not shown more than once, even if the user doesn't close it themselves.
|
You must update the latestAnnouncementId in ClaudeDevProvider for new announcements to show to users. This new id will be compared with whats in state for the 'last announcement shown', and if it's different then the announcement will render. As soon as an announcement is shown, the id will be updated in state. This ensures that announcements are not shown more than once, even if the user doesn't close it themselves.
|
||||||
*/
|
*/
|
||||||
const Announcement = ({ version, hideAnnouncement, apiConfiguration }: AnnouncementProps) => {
|
const Announcement = ({ version, hideAnnouncement, apiConfiguration, vscodeUriScheme }: AnnouncementProps) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
@@ -33,23 +35,23 @@ const Announcement = ({ version, hideAnnouncement, apiConfiguration }: Announcem
|
|||||||
<ul style={{ margin: "0 0 8px", paddingLeft: "20px" }}>
|
<ul style={{ margin: "0 0 8px", paddingLeft: "20px" }}>
|
||||||
<li>
|
<li>
|
||||||
Excited to announce that{" "}
|
Excited to announce that{" "}
|
||||||
<VSCodeLink href="https://claude-dev.com" style={{ display: "inline" }}>
|
<VSCodeLink href={getKoduSignInUrl(vscodeUriScheme)} style={{ display: "inline" }}>
|
||||||
Kodu
|
Kodu
|
||||||
</VSCodeLink>{" "}
|
</VSCodeLink>{" "}
|
||||||
is offering $10 free credits to help new users get the most out of Claude Dev with high rate limits
|
is offering $10 free credits to help new users get the most out of Claude Dev with high rate limits
|
||||||
and prompt caching! Stay tuned for some exciting updates like easier billing and deploying live
|
and prompt caching! Stay tuned for some exciting updates like easier billing and deploying live
|
||||||
websites.
|
websites.
|
||||||
{apiConfiguration?.koduApiKey === undefined && (
|
{apiConfiguration?.koduApiKey === undefined && (
|
||||||
<VSCodeButton
|
<VSCodeButtonLink
|
||||||
appearance="secondary"
|
appearance="secondary"
|
||||||
onClick={() => vscode.postMessage({ type: "didClickKoduSignIn" })}
|
href={getKoduSignInUrl(vscodeUriScheme)}
|
||||||
style={{
|
style={{
|
||||||
transform: "scale(0.8)",
|
transform: "scale(0.8)",
|
||||||
transformOrigin: "left center",
|
transformOrigin: "left center",
|
||||||
margin: "4px 0 2px 0",
|
margin: "4px 0 2px 0",
|
||||||
}}>
|
}}>
|
||||||
Claim $10 Free Credits
|
Claim $10 Free Credits
|
||||||
</VSCodeButton>
|
</VSCodeButtonLink>
|
||||||
)}
|
)}
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
import {
|
import { VSCodeDropdown, VSCodeLink, VSCodeOption, VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
|
||||||
VSCodeButton,
|
|
||||||
VSCodeDropdown,
|
|
||||||
VSCodeLink,
|
|
||||||
VSCodeOption,
|
|
||||||
VSCodeTextField,
|
|
||||||
} from "@vscode/webview-ui-toolkit/react"
|
|
||||||
import React, { useCallback, useEffect, useMemo, useState } from "react"
|
import React, { useCallback, useEffect, useMemo, useState } from "react"
|
||||||
|
import { useEvent } from "react-use"
|
||||||
import {
|
import {
|
||||||
ApiConfiguration,
|
ApiConfiguration,
|
||||||
ApiModelId,
|
ApiModelId,
|
||||||
@@ -19,9 +14,10 @@ import {
|
|||||||
openRouterDefaultModelId,
|
openRouterDefaultModelId,
|
||||||
openRouterModels,
|
openRouterModels,
|
||||||
} from "../../../src/shared/api"
|
} from "../../../src/shared/api"
|
||||||
import { vscode } from "../utils/vscode"
|
|
||||||
import { useEvent } from "react-use"
|
|
||||||
import { ExtensionMessage } from "../../../src/shared/ExtensionMessage"
|
import { ExtensionMessage } from "../../../src/shared/ExtensionMessage"
|
||||||
|
import { getKoduAddCreditsUrl, getKoduSignInUrl } from "../../../src/shared/kodu"
|
||||||
|
import { vscode } from "../utils/vscode"
|
||||||
|
import VSCodeButtonLink from "./VSCodeButtonLink"
|
||||||
|
|
||||||
interface ApiOptionsProps {
|
interface ApiOptionsProps {
|
||||||
showModelOptions: boolean
|
showModelOptions: boolean
|
||||||
@@ -29,6 +25,7 @@ interface ApiOptionsProps {
|
|||||||
setApiConfiguration: React.Dispatch<React.SetStateAction<ApiConfiguration | undefined>>
|
setApiConfiguration: React.Dispatch<React.SetStateAction<ApiConfiguration | undefined>>
|
||||||
koduCredits?: number
|
koduCredits?: number
|
||||||
apiErrorMessage?: string
|
apiErrorMessage?: string
|
||||||
|
vscodeUriScheme?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const ApiOptions: React.FC<ApiOptionsProps> = ({
|
const ApiOptions: React.FC<ApiOptionsProps> = ({
|
||||||
@@ -37,6 +34,7 @@ const ApiOptions: React.FC<ApiOptionsProps> = ({
|
|||||||
setApiConfiguration,
|
setApiConfiguration,
|
||||||
koduCredits,
|
koduCredits,
|
||||||
apiErrorMessage,
|
apiErrorMessage,
|
||||||
|
vscodeUriScheme,
|
||||||
}) => {
|
}) => {
|
||||||
const [didFetchKoduCredits, setDidFetchKoduCredits] = useState(false)
|
const [didFetchKoduCredits, setDidFetchKoduCredits] = useState(false)
|
||||||
const handleInputChange = (field: keyof ApiConfiguration) => (event: any) => {
|
const handleInputChange = (field: keyof ApiConfiguration) => (event: any) => {
|
||||||
@@ -184,22 +182,19 @@ const ApiOptions: React.FC<ApiOptionsProps> = ({
|
|||||||
{formatPrice(koduCredits || 0)}
|
{formatPrice(koduCredits || 0)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<VSCodeButton
|
<VSCodeButtonLink
|
||||||
appearance="primary"
|
href={getKoduAddCreditsUrl(vscodeUriScheme)}
|
||||||
onClick={() => vscode.postMessage({ type: "didClickKoduAddCredits" })}
|
|
||||||
style={{
|
style={{
|
||||||
width: "fit-content",
|
width: "fit-content",
|
||||||
}}>
|
}}>
|
||||||
Add Credits
|
Add Credits
|
||||||
</VSCodeButton>
|
</VSCodeButtonLink>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<div style={{ margin: "4px 0px" }}>
|
<div style={{ margin: "4px 0px" }}>
|
||||||
<VSCodeButton
|
<VSCodeButtonLink href={getKoduSignInUrl(vscodeUriScheme)}>
|
||||||
appearance="primary"
|
|
||||||
onClick={() => vscode.postMessage({ type: "didClickKoduSignIn" })}>
|
|
||||||
Sign in to Kodu
|
Sign in to Kodu
|
||||||
</VSCodeButton>
|
</VSCodeButtonLink>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<p
|
<p
|
||||||
@@ -210,7 +205,7 @@ const ApiOptions: React.FC<ApiOptionsProps> = ({
|
|||||||
}}>
|
}}>
|
||||||
Kodu is recommended for its high rate limits and access to the latest features like prompt
|
Kodu is recommended for its high rate limits and access to the latest features like prompt
|
||||||
caching.
|
caching.
|
||||||
<VSCodeLink href="https://claude-dev.com" style={{ display: "inline", fontSize: "12px" }}>
|
<VSCodeLink href="https://kodu.ai" style={{ display: "inline", fontSize: "12px" }}>
|
||||||
Learn more about Kodu here.
|
Learn more about Kodu here.
|
||||||
</VSCodeLink>
|
</VSCodeLink>
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ interface ChatViewProps {
|
|||||||
hideAnnouncement: () => void
|
hideAnnouncement: () => void
|
||||||
showHistoryView: () => void
|
showHistoryView: () => void
|
||||||
apiConfiguration?: ApiConfiguration
|
apiConfiguration?: ApiConfiguration
|
||||||
|
vscodeUriScheme?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const MAX_IMAGES_PER_MESSAGE = 20 // Anthropic limits to 20 images
|
const MAX_IMAGES_PER_MESSAGE = 20 // Anthropic limits to 20 images
|
||||||
@@ -46,6 +47,7 @@ const ChatView = ({
|
|||||||
hideAnnouncement,
|
hideAnnouncement,
|
||||||
showHistoryView,
|
showHistoryView,
|
||||||
apiConfiguration,
|
apiConfiguration,
|
||||||
|
vscodeUriScheme,
|
||||||
}: ChatViewProps) => {
|
}: ChatViewProps) => {
|
||||||
//const task = messages.length > 0 ? (messages[0].say === "task" ? messages[0] : undefined) : undefined) : undefined
|
//const task = messages.length > 0 ? (messages[0].say === "task" ? messages[0] : undefined) : undefined) : undefined
|
||||||
const task = messages.length > 0 ? messages[0] : undefined // leaving this less safe version here since if the first message is not a task, then the extension is in a bad state and needs to be debugged (see ClaudeDev.abort)
|
const task = messages.length > 0 ? messages[0] : undefined // leaving this less safe version here since if the first message is not a task, then the extension is in a bad state and needs to be debugged (see ClaudeDev.abort)
|
||||||
@@ -490,6 +492,7 @@ const ChatView = ({
|
|||||||
version={version}
|
version={version}
|
||||||
hideAnnouncement={hideAnnouncement}
|
hideAnnouncement={hideAnnouncement}
|
||||||
apiConfiguration={apiConfiguration}
|
apiConfiguration={apiConfiguration}
|
||||||
|
vscodeUriScheme={vscodeUriScheme}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<div style={{ padding: "0 20px", flexGrow: taskHistory.length > 0 ? undefined : 1 }}>
|
<div style={{ padding: "0 20px", flexGrow: taskHistory.length > 0 ? undefined : 1 }}>
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import { ApiConfiguration } from "../../../src/shared/api"
|
|||||||
import { validateApiConfiguration, validateMaxRequestsPerTask } from "../utils/validate"
|
import { validateApiConfiguration, validateMaxRequestsPerTask } from "../utils/validate"
|
||||||
import { vscode } from "../utils/vscode"
|
import { vscode } from "../utils/vscode"
|
||||||
import ApiOptions from "./ApiOptions"
|
import ApiOptions from "./ApiOptions"
|
||||||
|
import { getKoduSignInUrl } from "../../../src/shared/kodu"
|
||||||
|
|
||||||
type SettingsViewProps = {
|
type SettingsViewProps = {
|
||||||
version: string
|
version: string
|
||||||
@@ -23,6 +24,7 @@ type SettingsViewProps = {
|
|||||||
onDone: () => void
|
onDone: () => void
|
||||||
alwaysAllowReadOnly: boolean
|
alwaysAllowReadOnly: boolean
|
||||||
setAlwaysAllowReadOnly: React.Dispatch<React.SetStateAction<boolean>>
|
setAlwaysAllowReadOnly: React.Dispatch<React.SetStateAction<boolean>>
|
||||||
|
vscodeUriScheme?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const SettingsView = ({
|
const SettingsView = ({
|
||||||
@@ -37,6 +39,7 @@ const SettingsView = ({
|
|||||||
onDone,
|
onDone,
|
||||||
alwaysAllowReadOnly,
|
alwaysAllowReadOnly,
|
||||||
setAlwaysAllowReadOnly,
|
setAlwaysAllowReadOnly,
|
||||||
|
vscodeUriScheme,
|
||||||
}: SettingsViewProps) => {
|
}: SettingsViewProps) => {
|
||||||
const [apiErrorMessage, setApiErrorMessage] = useState<string | undefined>(undefined)
|
const [apiErrorMessage, setApiErrorMessage] = useState<string | undefined>(undefined)
|
||||||
const [maxRequestsErrorMessage, setMaxRequestsErrorMessage] = useState<string | undefined>(undefined)
|
const [maxRequestsErrorMessage, setMaxRequestsErrorMessage] = useState<string | undefined>(undefined)
|
||||||
@@ -104,6 +107,13 @@ const SettingsView = ({
|
|||||||
<div
|
<div
|
||||||
style={{ flexGrow: 1, overflowY: "scroll", paddingRight: 8, display: "flex", flexDirection: "column" }}>
|
style={{ flexGrow: 1, overflowY: "scroll", paddingRight: 8, display: "flex", flexDirection: "column" }}>
|
||||||
{apiConfiguration?.koduApiKey === undefined && (
|
{apiConfiguration?.koduApiKey === undefined && (
|
||||||
|
<a
|
||||||
|
href={getKoduSignInUrl(vscodeUriScheme)}
|
||||||
|
style={{
|
||||||
|
textDecoration: "none",
|
||||||
|
color: "inherit",
|
||||||
|
outline: "none",
|
||||||
|
}}>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
@@ -115,8 +125,7 @@ const SettingsView = ({
|
|||||||
margin: "0 0 8px 0px",
|
margin: "0 0 8px 0px",
|
||||||
fontSize: "12px",
|
fontSize: "12px",
|
||||||
cursor: "pointer",
|
cursor: "pointer",
|
||||||
}}
|
}}>
|
||||||
onClick={() => vscode.postMessage({ type: "didClickKoduSignIn" })}>
|
|
||||||
<i
|
<i
|
||||||
className="codicon codicon-info"
|
className="codicon codicon-info"
|
||||||
style={{
|
style={{
|
||||||
@@ -125,6 +134,7 @@ const SettingsView = ({
|
|||||||
}}></i>
|
}}></i>
|
||||||
<span>Claim $10 free credits from Kodu</span>
|
<span>Claim $10 free credits from Kodu</span>
|
||||||
</div>
|
</div>
|
||||||
|
</a>
|
||||||
)}
|
)}
|
||||||
<div style={{ marginBottom: 5 }}>
|
<div style={{ marginBottom: 5 }}>
|
||||||
<ApiOptions
|
<ApiOptions
|
||||||
@@ -133,6 +143,7 @@ const SettingsView = ({
|
|||||||
showModelOptions={true}
|
showModelOptions={true}
|
||||||
koduCredits={koduCredits}
|
koduCredits={koduCredits}
|
||||||
apiErrorMessage={apiErrorMessage}
|
apiErrorMessage={apiErrorMessage}
|
||||||
|
vscodeUriScheme={vscodeUriScheme}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
23
webview-ui/src/components/VSCodeButtonLink.tsx
Normal file
23
webview-ui/src/components/VSCodeButtonLink.tsx
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import React from "react"
|
||||||
|
import { VSCodeButton } from "@vscode/webview-ui-toolkit/react"
|
||||||
|
|
||||||
|
interface VSCodeButtonLinkProps {
|
||||||
|
href: string
|
||||||
|
children: React.ReactNode
|
||||||
|
[key: string]: any
|
||||||
|
}
|
||||||
|
|
||||||
|
const VSCodeButtonLink: React.FC<VSCodeButtonLinkProps> = ({ href, children, ...props }) => {
|
||||||
|
return (
|
||||||
|
<a
|
||||||
|
href={href}
|
||||||
|
style={{
|
||||||
|
textDecoration: "none",
|
||||||
|
color: "inherit",
|
||||||
|
}}>
|
||||||
|
<VSCodeButton {...props}>{children}</VSCodeButton>
|
||||||
|
</a>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default VSCodeButtonLink
|
||||||
@@ -4,13 +4,15 @@ import { ApiConfiguration } from "../../../src/shared/api"
|
|||||||
import { validateApiConfiguration } from "../utils/validate"
|
import { validateApiConfiguration } from "../utils/validate"
|
||||||
import { vscode } from "../utils/vscode"
|
import { vscode } from "../utils/vscode"
|
||||||
import ApiOptions from "./ApiOptions"
|
import ApiOptions from "./ApiOptions"
|
||||||
|
import { getKoduSignInUrl } from "../../../src/shared/kodu"
|
||||||
|
|
||||||
interface WelcomeViewProps {
|
interface WelcomeViewProps {
|
||||||
apiConfiguration?: ApiConfiguration
|
apiConfiguration?: ApiConfiguration
|
||||||
setApiConfiguration: React.Dispatch<React.SetStateAction<ApiConfiguration | undefined>>
|
setApiConfiguration: React.Dispatch<React.SetStateAction<ApiConfiguration | undefined>>
|
||||||
|
vscodeUriScheme?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const WelcomeView: React.FC<WelcomeViewProps> = ({ apiConfiguration, setApiConfiguration }) => {
|
const WelcomeView: React.FC<WelcomeViewProps> = ({ apiConfiguration, setApiConfiguration, vscodeUriScheme }) => {
|
||||||
const [apiErrorMessage, setApiErrorMessage] = useState<string | undefined>(undefined)
|
const [apiErrorMessage, setApiErrorMessage] = useState<string | undefined>(undefined)
|
||||||
|
|
||||||
const disableLetsGoButton = apiErrorMessage != null
|
const disableLetsGoButton = apiErrorMessage != null
|
||||||
@@ -59,7 +61,7 @@ const WelcomeView: React.FC<WelcomeViewProps> = ({ apiConfiguration, setApiConfi
|
|||||||
}}></i>
|
}}></i>
|
||||||
<span>
|
<span>
|
||||||
Explore Claude's capabilities with $10 free credits from{" "}
|
Explore Claude's capabilities with $10 free credits from{" "}
|
||||||
<VSCodeLink href="https://claude-dev.com" style={{ display: "inline" }}>
|
<VSCodeLink href={getKoduSignInUrl(vscodeUriScheme)} style={{ display: "inline" }}>
|
||||||
Kodu
|
Kodu
|
||||||
</VSCodeLink>
|
</VSCodeLink>
|
||||||
</span>
|
</span>
|
||||||
@@ -70,6 +72,7 @@ const WelcomeView: React.FC<WelcomeViewProps> = ({ apiConfiguration, setApiConfi
|
|||||||
apiConfiguration={apiConfiguration}
|
apiConfiguration={apiConfiguration}
|
||||||
setApiConfiguration={setApiConfiguration}
|
setApiConfiguration={setApiConfiguration}
|
||||||
showModelOptions={false}
|
showModelOptions={false}
|
||||||
|
vscodeUriScheme={vscodeUriScheme}
|
||||||
/>
|
/>
|
||||||
{apiConfiguration?.apiProvider !== "kodu" && (
|
{apiConfiguration?.apiProvider !== "kodu" && (
|
||||||
<VSCodeButton onClick={handleSubmit} disabled={disableLetsGoButton} style={{ marginTop: "3px" }}>
|
<VSCodeButton onClick={handleSubmit} disabled={disableLetsGoButton} style={{ marginTop: "3px" }}>
|
||||||
|
|||||||
Reference in New Issue
Block a user