Compare commits

...

4 Commits

Author SHA1 Message Date
celestial-vault c0e5425016 changeset 2025-04-04 14:13:25 -07:00
celestial-vault 49715795e1 update imports to aliases 2025-04-04 13:09:59 -07:00
Evan 8404e74ea1 Reorganize Webview MCP Directory Structure (#2658)
* reorganize directory structure

* rename back files to make diff more readable

* rename back because it didn't help

* rename index files to their component names

* fix addLocalServerForm imports
2025-04-04 12:48:31 -07:00
Evan 9d5772c42c Webview - Add Import Path Aliasing (#2673)
* add import path aliasing

* changeset

* shared directory path aliasing
2025-04-04 12:28:40 -07:00
61 changed files with 441 additions and 446 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"claude-dev": minor
---
Add import path aliasing to the webview
+5
View File
@@ -0,0 +1,5 @@
---
"claude-dev": patch
---
Update import aliases in webview
+2 -2
View File
@@ -1,6 +1,6 @@
import { useCallback, useEffect, useState } from "react"
import { useEvent } from "react-use"
import { ExtensionMessage } from "../../src/shared/ExtensionMessage"
import { ExtensionMessage } from "@shared/ExtensionMessage"
import ChatView from "./components/chat/ChatView"
import HistoryView from "./components/history/HistoryView"
import SettingsView from "./components/settings/SettingsView"
@@ -9,7 +9,7 @@ import AccountView from "./components/account/AccountView"
import { ExtensionStateContextProvider, useExtensionState } from "./context/ExtensionStateContext"
import { FirebaseAuthProvider } from "./context/FirebaseAuthContext"
import { vscode } from "./utils/vscode"
import McpView from "./components/mcp/McpView"
import McpView from "./components/mcp/configuration/McpConfigurationView"
const AppContent = () => {
const { didHydrateState, showWelcome, shouldShowAnnouncement, telemetrySetting, vscMachineId } = useExtensionState()
@@ -1,5 +1,5 @@
import { memo } from "react"
import { vscode } from "../../utils/vscode"
import { vscode } from "@/utils/vscode"
const AccountOptions = () => {
const handleAccountClick = () => {
@@ -1,13 +1,13 @@
import { VSCodeButton, VSCodeDivider, VSCodeLink } from "@vscode/webview-ui-toolkit/react"
import { memo, useEffect, useState } from "react"
import { useFirebaseAuth } from "../../context/FirebaseAuthContext"
import { vscode } from "../../utils/vscode"
import { useFirebaseAuth } from "@/context/FirebaseAuthContext"
import { vscode } from "@/utils/vscode"
import VSCodeButtonLink from "../common/VSCodeButtonLink"
import ClineLogoWhite from "../../assets/ClineLogoWhite"
import CountUp from "react-countup"
import CreditsHistoryTable from "./CreditsHistoryTable"
import { UsageTransaction, PaymentTransaction } from "../../../../src/shared/ClineAccount"
import { useExtensionState } from "../../context/ExtensionStateContext"
import { UsageTransaction, PaymentTransaction } from "@shared/ClineAccount"
import { useExtensionState } from "@/context/ExtensionStateContext"
type AccountViewProps = {
onDone: () => void
@@ -1,8 +1,8 @@
import { VSCodeDataGrid, VSCodeDataGridRow, VSCodeDataGridCell } from "@vscode/webview-ui-toolkit/react"
import { useState } from "react"
import { TabButton } from "../mcp/McpView"
import { UsageTransaction, PaymentTransaction } from "../../../../src/shared/ClineAccount"
import { formatDollars, formatTimestamp } from "../../utils/format"
import { TabButton } from "../mcp/configuration/McpConfigurationView"
import { UsageTransaction, PaymentTransaction } from "@shared/ClineAccount"
import { formatDollars, formatTimestamp } from "@/utils/format"
interface CreditsHistoryTableProps {
isLoading: boolean
@@ -2,9 +2,9 @@ import { VSCodeButton, VSCodeCheckbox, VSCodeDropdown, VSCodeOption } from "@vsc
import React, { useRef, useState } from "react"
import { useClickAway } from "react-use"
import styled from "styled-components"
import { BROWSER_VIEWPORT_PRESETS } from "../../../../src/shared/BrowserSettings"
import { useExtensionState } from "../../context/ExtensionStateContext"
import { vscode } from "../../utils/vscode"
import { BROWSER_VIEWPORT_PRESETS } from "@shared/BrowserSettings"
import { useExtensionState } from "@/context/ExtensionStateContext"
import { vscode } from "@/utils/vscode"
import { CODE_BLOCK_BG_COLOR } from "../common/CodeBlock"
interface BrowserSettingsMenuProps {
@@ -1,6 +1,6 @@
import { VSCodeButton, VSCodeLink } from "@vscode/webview-ui-toolkit/react"
import { CSSProperties, memo } from "react"
import { getAsVar, VSC_DESCRIPTION_FOREGROUND, VSC_INACTIVE_SELECTION_BACKGROUND } from "../../utils/vscStyles"
import { getAsVar, VSC_DESCRIPTION_FOREGROUND, VSC_INACTIVE_SELECTION_BACKGROUND } from "@/utils/vscStyles"
interface AnnouncementProps {
version: string
@@ -1,10 +1,10 @@
import { VSCodeCheckbox, VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
import { useCallback, useState } from "react"
import styled from "styled-components"
import { useExtensionState } from "../../context/ExtensionStateContext"
import { AutoApprovalSettings } from "../../../../src/shared/AutoApprovalSettings"
import { vscode } from "../../utils/vscode"
import { getAsVar, VSC_FOREGROUND, VSC_TITLEBAR_INACTIVE_FOREGROUND, VSC_DESCRIPTION_FOREGROUND } from "../../utils/vscStyles"
import { useExtensionState } from "@/context/ExtensionStateContext"
import { AutoApprovalSettings } from "@shared/AutoApprovalSettings"
import { vscode } from "@/utils/vscode"
import { getAsVar, VSC_FOREGROUND, VSC_TITLEBAR_INACTIVE_FOREGROUND, VSC_DESCRIPTION_FOREGROUND } from "@/utils/vscStyles"
interface AutoApproveMenuProps {
style?: React.CSSProperties
@@ -3,14 +3,14 @@ import deepEqual from "fast-deep-equal"
import React, { CSSProperties, memo, useEffect, useMemo, useRef, useState } from "react"
import { useSize } from "react-use"
import styled from "styled-components"
import { BROWSER_VIEWPORT_PRESETS } from "../../../../src/shared/BrowserSettings"
import { BrowserAction, BrowserActionResult, ClineMessage, ClineSayBrowserAction } from "../../../../src/shared/ExtensionMessage"
import { useExtensionState } from "../../context/ExtensionStateContext"
import { vscode } from "../../utils/vscode"
import { BrowserSettingsMenu } from "../browser/BrowserSettingsMenu"
import { CheckpointControls } from "../common/CheckpointControls"
import CodeBlock, { CODE_BLOCK_BG_COLOR } from "../common/CodeBlock"
import { ChatRowContent, ProgressIndicator } from "./ChatRow"
import { BROWSER_VIEWPORT_PRESETS } from "@shared/BrowserSettings"
import { BrowserAction, BrowserActionResult, ClineMessage, ClineSayBrowserAction } from "@shared/ExtensionMessage"
import { useExtensionState } from "@/context/ExtensionStateContext"
import { vscode } from "@/utils/vscode"
import { BrowserSettingsMenu } from "@/components/browser/BrowserSettingsMenu"
import { CheckpointControls } from "@/components/common/CheckpointControls"
import CodeBlock, { CODE_BLOCK_BG_COLOR } from "@/components/common/CodeBlock"
import { ChatRowContent, ProgressIndicator } from "@/components/chat/ChatRow"
interface BrowserSessionRowProps {
messages: ClineMessage[]
+16 -16
View File
@@ -12,25 +12,25 @@ import {
ClineSayTool,
COMPLETION_RESULT_CHANGES_FLAG,
ExtensionMessage,
} from "../../../../src/shared/ExtensionMessage"
import { COMMAND_OUTPUT_STRING, COMMAND_REQ_APP_STRING } from "../../../../src/shared/combineCommandSequences"
import { useExtensionState } from "../../context/ExtensionStateContext"
import { findMatchingResourceOrTemplate, getMcpServerDisplayName } from "../../utils/mcp"
import { vscode } from "../../utils/vscode"
import { CheckmarkControl } from "../common/CheckmarkControl"
} from "@shared/ExtensionMessage"
import { COMMAND_OUTPUT_STRING, COMMAND_REQ_APP_STRING } from "@shared/combineCommandSequences"
import { useExtensionState } from "@/context/ExtensionStateContext"
import { findMatchingResourceOrTemplate, getMcpServerDisplayName } from "@/utils/mcp"
import { vscode } from "@/utils/vscode"
import { CheckmarkControl } from "@/components/common/CheckmarkControl"
import { CheckpointControls, CheckpointOverlay } from "../common/CheckpointControls"
import CodeAccordian, { cleanPathPrefix } from "../common/CodeAccordian"
import CodeBlock, { CODE_BLOCK_BG_COLOR } from "../common/CodeBlock"
import MarkdownBlock from "../common/MarkdownBlock"
import Thumbnails from "../common/Thumbnails"
import McpResourceRow from "../mcp/McpResourceRow"
import McpToolRow from "../mcp/McpToolRow"
import McpResponseDisplay from "../mcp/McpResponseDisplay"
import CreditLimitError from "./CreditLimitError"
import { OptionsButtons } from "./OptionsButtons"
import CodeBlock, { CODE_BLOCK_BG_COLOR } from "@/components/common/CodeBlock"
import MarkdownBlock from "@/components/common/MarkdownBlock"
import Thumbnails from "@/components/common/Thumbnails"
import McpToolRow from "@/components/mcp/configuration/tabs/installed/server-row/McpToolRow"
import McpResponseDisplay from "@/components/mcp/chat-display/McpResponseDisplay"
import CreditLimitError from "@/components/chat/CreditLimitError"
import { OptionsButtons } from "@/components/chat/OptionsButtons"
import { highlightMentions } from "./TaskHeader"
import SuccessButton from "../common/SuccessButton"
import TaskFeedbackButtons from "./TaskFeedbackButtons"
import SuccessButton from "@/components/common/SuccessButton"
import TaskFeedbackButtons from "@/components/chat/TaskFeedbackButtons"
import McpResourceRow from "@/components/mcp/configuration/tabs/installed/server-row/McpResourceRow"
const ChatRowContainer = styled.div`
padding: 10px 6px 10px 15px;
+14 -14
View File
@@ -3,26 +3,26 @@ import React, { forwardRef, useCallback, useEffect, useLayoutEffect, useMemo, us
import DynamicTextArea from "react-textarea-autosize"
import { useClickAway, useEvent, useWindowSize } from "react-use"
import styled from "styled-components"
import { mentionRegex, mentionRegexGlobal } from "../../../../src/shared/context-mentions"
import { ExtensionMessage } from "../../../../src/shared/ExtensionMessage"
import { useExtensionState } from "../../context/ExtensionStateContext"
import { mentionRegex, mentionRegexGlobal } from "@shared/context-mentions"
import { ExtensionMessage } from "@shared/ExtensionMessage"
import { useExtensionState } from "@/context/ExtensionStateContext"
import {
ContextMenuOptionType,
getContextMenuOptions,
insertMention,
removeMention,
shouldShowContextMenu,
} from "../../utils/context-mentions"
import { useMetaKeyDetection, useShortcut } from "../../utils/hooks"
import { validateApiConfiguration, validateModelId } from "../../utils/validate"
import { vscode } from "../../utils/vscode"
import { CODE_BLOCK_BG_COLOR } from "../common/CodeBlock"
import Thumbnails from "../common/Thumbnails"
import Tooltip from "../common/Tooltip"
import ApiOptions, { normalizeApiConfiguration } from "../settings/ApiOptions"
import { MAX_IMAGES_PER_MESSAGE } from "./ChatView"
import ContextMenu from "./ContextMenu"
import { ChatSettings } from "../../../../src/shared/ChatSettings"
} from "@/utils/context-mentions"
import { useMetaKeyDetection, useShortcut } from "@/utils/hooks"
import { validateApiConfiguration, validateModelId } from "@/utils/validate"
import { vscode } from "@/utils/vscode"
import { CODE_BLOCK_BG_COLOR } from "@/components/common/CodeBlock"
import Thumbnails from "@/components/common/Thumbnails"
import Tooltip from "@/components/common/Tooltip"
import ApiOptions, { normalizeApiConfiguration } from "@/components/settings/ApiOptions"
import { MAX_IMAGES_PER_MESSAGE } from "@/components/chat/ChatView"
import ContextMenu from "@/components/chat/ContextMenu"
import { ChatSettings } from "@shared/ChatSettings"
interface ChatTextAreaProps {
inputValue: string
+16 -16
View File
@@ -11,22 +11,22 @@ import {
ClineSayBrowserAction,
ClineSayTool,
ExtensionMessage,
} from "../../../../src/shared/ExtensionMessage"
import { findLast } from "../../../../src/shared/array"
import { combineApiRequests } from "../../../../src/shared/combineApiRequests"
import { combineCommandSequences } from "../../../../src/shared/combineCommandSequences"
import { getApiMetrics } from "../../../../src/shared/getApiMetrics"
import { useExtensionState } from "../../context/ExtensionStateContext"
import { vscode } from "../../utils/vscode"
import HistoryPreview from "../history/HistoryPreview"
import { normalizeApiConfiguration } from "../settings/ApiOptions"
import Announcement from "./Announcement"
import AutoApproveMenu from "./AutoApproveMenu"
import BrowserSessionRow from "./BrowserSessionRow"
import ChatRow from "./ChatRow"
import ChatTextArea from "./ChatTextArea"
import TaskHeader from "./TaskHeader"
import TelemetryBanner from "../common/TelemetryBanner"
} from "@shared/ExtensionMessage"
import { findLast } from "@shared/array"
import { combineApiRequests } from "@shared/combineApiRequests"
import { combineCommandSequences } from "@shared/combineCommandSequences"
import { getApiMetrics } from "@shared/getApiMetrics"
import { useExtensionState } from "@/context/ExtensionStateContext"
import { vscode } from "@/utils/vscode"
import HistoryPreview from "@/components/history/HistoryPreview"
import { normalizeApiConfiguration } from "@/components/settings/ApiOptions"
import Announcement from "@/components/chat/Announcement"
import AutoApproveMenu from "@/components/chat/AutoApproveMenu"
import BrowserSessionRow from "@/components/chat/BrowserSessionRow"
import ChatRow from "@/components/chat/ChatRow"
import ChatTextArea from "@/components/chat/ChatTextArea"
import TaskHeader from "@/components/chat/TaskHeader"
import TelemetryBanner from "@/components/common/TelemetryBanner"
interface ChatViewProps {
isHidden: boolean
@@ -1,6 +1,6 @@
import React, { useEffect, useMemo, useRef } from "react"
import { ContextMenuOptionType, ContextMenuQueryItem, getContextMenuOptions } from "../../utils/context-mentions"
import { cleanPathPrefix } from "../common/CodeAccordian"
import { ContextMenuOptionType, ContextMenuQueryItem, getContextMenuOptions } from "@/utils/context-mentions"
import { cleanPathPrefix } from "@/components/common/CodeAccordian"
interface ContextMenuProps {
onSelect: (type: ContextMenuOptionType, value?: string) => void
@@ -1,8 +1,8 @@
import React from "react"
import VSCodeButtonLink from "../common/VSCodeButtonLink"
import VSCodeButtonLink from "@/components/common/VSCodeButtonLink"
import { VSCodeButton } from "@vscode/webview-ui-toolkit/react"
import { vscode } from "../../utils/vscode"
import { Invoke } from "../../../../src/shared/ExtensionMessage"
import { vscode } from "@/utils/vscode"
import { Invoke } from "@shared/ExtensionMessage"
interface CreditLimitErrorProps {
currentBalance: number
@@ -1,6 +1,6 @@
import styled from "styled-components"
import { CODE_BLOCK_BG_COLOR } from "../common/CodeBlock"
import { vscode } from "../../utils/vscode"
import { CODE_BLOCK_BG_COLOR } from "@/components/common/CodeBlock"
import { vscode } from "@/utils/vscode"
const OptionButton = styled.button<{ isSelected?: boolean; isNotSelectable?: boolean }>`
padding: 8px 12px;
@@ -1,9 +1,8 @@
import React, { useState, useEffect } from "react"
import styled from "styled-components"
import { vscode } from "../../utils/vscode"
import { TaskFeedbackType } from "../../../../src/shared/WebviewMessage"
import { vscode } from "@/utils/vscode"
import { TaskFeedbackType } from "@shared/WebviewMessage"
import { VSCodeButton } from "@vscode/webview-ui-toolkit/react"
import VSCodeButtonLink from "../common/VSCodeButtonLink"
interface TaskFeedbackButtonsProps {
messageTs: number
@@ -1,14 +1,14 @@
import { VSCodeButton } from "@vscode/webview-ui-toolkit/react"
import React, { memo, useEffect, useMemo, useRef, useState } from "react"
import { useWindowSize } from "react-use"
import { mentionRegexGlobal } from "../../../../src/shared/context-mentions"
import { ClineMessage } from "../../../../src/shared/ExtensionMessage"
import { useExtensionState } from "../../context/ExtensionStateContext"
import { formatLargeNumber } from "../../utils/format"
import { formatSize } from "../../utils/format"
import { vscode } from "../../utils/vscode"
import Thumbnails from "../common/Thumbnails"
import { normalizeApiConfiguration } from "../settings/ApiOptions"
import { mentionRegexGlobal } from "@shared/context-mentions"
import { ClineMessage } from "@shared/ExtensionMessage"
import { useExtensionState } from "@/context/ExtensionStateContext"
import { formatLargeNumber } from "@/utils/format"
import { formatSize } from "@/utils/format"
import { vscode } from "@/utils/vscode"
import Thumbnails from "@/components/common/Thumbnails"
import { normalizeApiConfiguration } from "@/components/settings/ApiOptions"
interface TaskHeaderProps {
task: ClineMessage
@@ -1,10 +1,9 @@
import { useCallback, useRef, useState, useEffect } from "react"
import { useClickAway, useEvent } from "react-use"
import { useEvent } from "react-use"
import styled from "styled-components"
import { ExtensionMessage } from "../../../../src/shared/ExtensionMessage"
import { vscode } from "../../utils/vscode"
import { CODE_BLOCK_BG_COLOR } from "./CodeBlock"
import { ClineCheckpointRestore } from "../../../../src/shared/WebviewMessage"
import { ExtensionMessage } from "@shared/ExtensionMessage"
import { vscode } from "@/utils/vscode"
import { CODE_BLOCK_BG_COLOR } from "@/components/common/CodeBlock"
import { VSCodeButton } from "@vscode/webview-ui-toolkit/react"
import { createPortal } from "react-dom"
import { useFloating, offset, flip, shift } from "@floating-ui/react"
@@ -2,10 +2,10 @@ import { VSCodeButton } from "@vscode/webview-ui-toolkit/react"
import { useCallback, useRef, useState } from "react"
import { useClickAway, useEvent } from "react-use"
import styled from "styled-components"
import { ExtensionMessage } from "../../../../src/shared/ExtensionMessage"
import { vscode } from "../../utils/vscode"
import { CODE_BLOCK_BG_COLOR } from "./CodeBlock"
import { ClineCheckpointRestore } from "../../../../src/shared/WebviewMessage"
import { ExtensionMessage } from "@shared/ExtensionMessage"
import { vscode } from "@/utils/vscode"
import { CODE_BLOCK_BG_COLOR } from "@/components/common/CodeBlock"
import { ClineCheckpointRestore } from "@shared/WebviewMessage"
interface CheckpointOverlayProps {
messageTs?: number
@@ -1,6 +1,6 @@
import { memo, useMemo } from "react"
import { getLanguageFromPath } from "../../utils/getLanguageFromPath"
import CodeBlock, { CODE_BLOCK_BG_COLOR } from "./CodeBlock"
import { getLanguageFromPath } from "@/utils/getLanguageFromPath"
import CodeBlock, { CODE_BLOCK_BG_COLOR } from "@/components/common/CodeBlock"
interface CodeAccordianProps {
code?: string
@@ -3,7 +3,7 @@ import { useRemark } from "react-remark"
import rehypeHighlight, { Options } from "rehype-highlight"
import styled from "styled-components"
import { visit } from "unist-util-visit"
import { useExtensionState } from "../../context/ExtensionStateContext"
import { useExtensionState } from "@/context/ExtensionStateContext"
export const CODE_BLOCK_BG_COLOR = "var(--vscode-editor-background, --vscode-sideBar-background, rgb(30 30 30))"
@@ -3,9 +3,9 @@ import { useRemark } from "react-remark"
import rehypeHighlight, { Options } from "rehype-highlight"
import styled from "styled-components"
import { visit } from "unist-util-visit"
import { useExtensionState } from "../../context/ExtensionStateContext"
import { CODE_BLOCK_BG_COLOR } from "./CodeBlock"
import MermaidBlock from "./MermaidBlock"
import { useExtensionState } from "@/context/ExtensionStateContext"
import { CODE_BLOCK_BG_COLOR } from "@/components/common/CodeBlock"
import MermaidBlock from "@/components/common/MermaidBlock"
interface MarkdownBlockProps {
markdown?: string
@@ -1,8 +1,8 @@
import { useEffect, useRef, useState } from "react"
import mermaid from "mermaid"
import { useDebounceEffect } from "../../utils/useDebounceEffect"
import { useDebounceEffect } from "@/utils/useDebounceEffect"
import styled from "styled-components"
import { vscode } from "../../utils/vscode"
import { vscode } from "@/utils/vscode"
const MERMAID_THEME = {
background: "#1e1e1e", // VS Code dark theme background
@@ -1,8 +1,8 @@
import { VSCodeButton, VSCodeLink } from "@vscode/webview-ui-toolkit/react"
import { memo, useState } from "react"
import styled from "styled-components"
import { vscode } from "../../utils/vscode"
import { TelemetrySetting } from "../../../../src/shared/TelemetrySetting"
import { vscode } from "@/utils/vscode"
import { TelemetrySetting } from "@shared/TelemetrySetting"
const BannerContainer = styled.div`
background-color: var(--vscode-banner-background);
@@ -1,6 +1,6 @@
import React, { useState, useRef, useLayoutEffect, memo } from "react"
import { useWindowSize } from "react-use"
import { vscode } from "../../utils/vscode"
import { vscode } from "@/utils/vscode"
interface ThumbnailsProps {
images: string[]
+1 -1
View File
@@ -6,7 +6,7 @@ import {
VSC_SIDEBAR_BACKGROUND,
VSC_INPUT_PLACEHOLDER_FOREGROUND,
VSC_INPUT_BORDER,
} from "../../utils/vscStyles"
} from "@/utils/vscStyles"
interface TooltipProps {
visible: boolean
@@ -1,8 +1,8 @@
import { VSCodeButton } from "@vscode/webview-ui-toolkit/react"
import { useExtensionState } from "../../context/ExtensionStateContext"
import { vscode } from "../../utils/vscode"
import { useExtensionState } from "@/context/ExtensionStateContext"
import { vscode } from "@/utils/vscode"
import { memo } from "react"
import { formatLargeNumber } from "../../utils/format"
import { formatLargeNumber } from "@/utils/format"
type HistoryPreviewProps = {
showHistoryView: () => void
@@ -1,14 +1,14 @@
import { VSCodeButton, VSCodeTextField, VSCodeRadioGroup, VSCodeRadio } from "@vscode/webview-ui-toolkit/react"
import { useExtensionState } from "../../context/ExtensionStateContext"
import { vscode } from "../../utils/vscode"
import { useExtensionState } from "@/context/ExtensionStateContext"
import { vscode } from "@/utils/vscode"
import { Virtuoso } from "react-virtuoso"
import { memo, useMemo, useState, useEffect, useCallback } from "react"
import Fuse, { FuseResult } from "fuse.js"
import { formatLargeNumber } from "../../utils/format"
import { formatSize } from "../../utils/format"
import { ExtensionMessage } from "../../../../src/shared/ExtensionMessage"
import { formatLargeNumber } from "@/utils/format"
import { formatSize } from "@/utils/format"
import { ExtensionMessage } from "@shared/ExtensionMessage"
import { useEvent } from "react-use"
import DangerButton from "../common/DangerButton"
import DangerButton from "@/components/common/DangerButton"
type HistoryViewProps = {
onDone: () => void
@@ -1,8 +1,8 @@
import React, { useEffect, useRef } from "react"
import { vscode } from "../../utils/vscode"
import React from "react"
import { vscode } from "@/utils/vscode"
import DOMPurify from "dompurify"
import { getSafeHostname, formatUrlForOpening, checkIfImageUrl } from "./McpRichUtil"
import ChatErrorBoundary from "../chat/ChatErrorBoundary"
import { getSafeHostname, formatUrlForOpening, checkIfImageUrl } from "./utils/mcpRichUtil"
import ChatErrorBoundary from "@/components/chat/ChatErrorBoundary"
interface ImagePreviewProps {
url: string
@@ -1,8 +1,8 @@
import React, { useEffect, useState } from "react"
import { vscode } from "../../utils/vscode"
import React from "react"
import { vscode } from "@/utils/vscode"
import DOMPurify from "dompurify"
import { getSafeHostname, normalizeRelativeUrl } from "./McpRichUtil"
import ChatErrorBoundary from "../chat/ChatErrorBoundary"
import { getSafeHostname, normalizeRelativeUrl } from "./utils/mcpRichUtil"
import ChatErrorBoundary from "@/components/chat/ChatErrorBoundary"
interface OpenGraphData {
title?: string
@@ -1,20 +1,10 @@
import React, { useEffect, useState, useCallback } from "react"
import LinkPreview from "./LinkPreview"
import ImagePreview from "./ImagePreview"
import { vscode } from "../../utils/vscode"
import DOMPurify from "dompurify"
import styled from "styled-components"
import { CODE_BLOCK_BG_COLOR } from "../common/CodeBlock"
import ChatErrorBoundary from "../chat/ChatErrorBoundary"
import {
safeCreateUrl,
isUrl,
getSafeHostname,
isLocalhostUrl,
normalizeRelativeUrl,
formatUrlForOpening,
checkIfImageUrl,
} from "./McpRichUtil"
import { CODE_BLOCK_BG_COLOR } from "@/components/common/CodeBlock"
import ChatErrorBoundary from "@/components/chat/ChatErrorBoundary"
import { isUrl, isLocalhostUrl, formatUrlForOpening, checkIfImageUrl } from "./utils/mcpRichUtil"
// Maximum number of URLs to process in total, per response
export const MAX_URLS = 50
@@ -1,4 +1,4 @@
import { vscode } from "../../utils/vscode"
import { vscode } from "@/utils/vscode"
// Safely create a URL object with error handling and ensure HTTPS
export const safeCreateUrl = (url: string): URL | null => {
@@ -0,0 +1,121 @@
import { VSCodeButton } from "@vscode/webview-ui-toolkit/react"
import { useEffect, useState } from "react"
import styled from "styled-components"
import { useExtensionState } from "@/context/ExtensionStateContext"
import { vscode } from "@/utils/vscode"
import AddRemoteServerForm from "./tabs/add-server/AddRemoteServerForm"
import McpMarketplaceView from "./tabs/marketplace/McpMarketplaceView"
import InstalledServersView from "./tabs/installed/InstalledServersView"
type McpViewProps = {
onDone: () => void
}
const McpConfigurationView = ({ onDone }: McpViewProps) => {
const { mcpMarketplaceEnabled } = useExtensionState()
const [activeTab, setActiveTab] = useState(mcpMarketplaceEnabled ? "marketplace" : "installed")
const handleTabChange = (tab: string) => {
setActiveTab(tab)
}
useEffect(() => {
if (!mcpMarketplaceEnabled && activeTab === "marketplace") {
// If marketplace is disabled and we're on marketplace tab, switch to installed
setActiveTab("installed")
}
}, [mcpMarketplaceEnabled, activeTab])
useEffect(() => {
if (mcpMarketplaceEnabled) {
vscode.postMessage({ type: "silentlyRefreshMcpMarketplace" })
vscode.postMessage({ type: "fetchLatestMcpServersFromHub" })
}
}, [mcpMarketplaceEnabled])
return (
<div
style={{
position: "fixed",
top: 0,
left: 0,
right: 0,
bottom: 0,
display: "flex",
flexDirection: "column",
}}>
<div
style={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
padding: "10px 17px 5px 20px",
}}>
<h3 style={{ color: "var(--vscode-foreground)", margin: 0 }}>MCP Servers</h3>
<VSCodeButton onClick={onDone}>Done</VSCodeButton>
</div>
<div style={{ flex: 1, overflow: "auto" }}>
{/* Tabs container */}
<div
style={{
display: "flex",
gap: "1px",
padding: "0 20px 0 20px",
borderBottom: "1px solid var(--vscode-panel-border)",
}}>
{mcpMarketplaceEnabled && (
<TabButton isActive={activeTab === "marketplace"} onClick={() => handleTabChange("marketplace")}>
Marketplace
</TabButton>
)}
<TabButton isActive={activeTab === "addRemote"} onClick={() => handleTabChange("addRemote")}>
Remote Servers
</TabButton>
<TabButton isActive={activeTab === "installed"} onClick={() => handleTabChange("installed")}>
Installed
</TabButton>
</div>
{/* Content container */}
<div style={{ width: "100%" }}>
{mcpMarketplaceEnabled && activeTab === "marketplace" && <McpMarketplaceView />}
{activeTab === "addRemote" && <AddRemoteServerForm onServerAdded={() => handleTabChange("installed")} />}
{activeTab === "installed" && <InstalledServersView />}
</div>
</div>
</div>
)
}
const StyledTabButton = styled.button<{ isActive: boolean }>`
background: none;
border: none;
border-bottom: 2px solid ${(props) => (props.isActive ? "var(--vscode-foreground)" : "transparent")};
color: ${(props) => (props.isActive ? "var(--vscode-foreground)" : "var(--vscode-descriptionForeground)")};
padding: 8px 16px;
cursor: pointer;
font-size: 13px;
margin-bottom: -1px;
font-family: inherit;
&:hover {
color: var(--vscode-foreground);
}
`
export const TabButton = ({
children,
isActive,
onClick,
}: {
children: React.ReactNode
isActive: boolean
onClick: () => void
}) => (
<StyledTabButton isActive={isActive} onClick={onClick}>
{children}
</StyledTabButton>
)
export default McpConfigurationView
@@ -1,8 +1,7 @@
import { VSCodeButton, VSCodeLink } from "@vscode/webview-ui-toolkit/react"
import { vscode } from "../../../utils/vscode"
import { vscode } from "@/utils/vscode"
import styled from "styled-components"
import { LINKS } from "../../../constants"
import { LINKS } from "@/constants"
type AddLocalServerFormProps = {
onServerAdded: () => void
@@ -1,8 +1,8 @@
import { useCallback, useRef, useState } from "react"
import { vscode } from "../../../utils/vscode"
import { vscode } from "@/utils/vscode"
import { VSCodeButton, VSCodeLink, VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
import { useEvent } from "react-use"
import { LINKS } from "../../../constants"
import { LINKS } from "@/constants"
const AddRemoteServerForm = ({ onServerAdded }: { onServerAdded: () => void }) => {
const [serverName, setServerName] = useState("")
const [serverUrl, setServerUrl] = useState("")
@@ -0,0 +1,87 @@
import { VSCodeButton, VSCodeLink } from "@vscode/webview-ui-toolkit/react"
import { vscode } from "@/utils/vscode"
import { useExtensionState } from "@/context/ExtensionStateContext"
import ServerRow from "./server-row/ServerRow"
const InstalledServersView = () => {
const { mcpServers: servers } = useExtensionState()
return (
<div style={{ padding: "16px 20px" }}>
<div
style={{
color: "var(--vscode-foreground)",
fontSize: "13px",
marginBottom: "16px",
marginTop: "5px",
}}>
The{" "}
<VSCodeLink href="https://github.com/modelcontextprotocol" style={{ display: "inline" }}>
Model Context Protocol
</VSCodeLink>{" "}
enables communication with locally running MCP servers that provide additional tools and resources to extend
Cline's capabilities. You can use{" "}
<VSCodeLink href="https://github.com/modelcontextprotocol/servers" style={{ display: "inline" }}>
community-made servers
</VSCodeLink>{" "}
or ask Cline to create new tools specific to your workflow (e.g., "add a tool that gets the latest npm docs").{" "}
<VSCodeLink href="https://x.com/sdrzn/status/1867271665086074969" style={{ display: "inline" }}>
See a demo here.
</VSCodeLink>
</div>
{servers.length > 0 ? (
<div
style={{
display: "flex",
flexDirection: "column",
gap: "10px",
}}>
{servers.map((server) => (
<ServerRow key={server.name} server={server} />
))}
</div>
) : (
<div
style={{
display: "flex",
flexDirection: "column",
alignItems: "center",
gap: "12px",
marginTop: 20,
marginBottom: 20,
color: "var(--vscode-descriptionForeground)",
}}>
No MCP servers installed
</div>
)}
{/* Settings Section */}
<div style={{ marginBottom: "20px", marginTop: 10 }}>
<VSCodeButton
appearance="secondary"
style={{ width: "100%", marginBottom: "5px" }}
onClick={() => {
vscode.postMessage({ type: "openMcpSettings" })
}}>
<span className="codicon codicon-server" style={{ marginRight: "6px" }}></span>
Configure MCP Servers
</VSCodeButton>
<div style={{ textAlign: "center" }}>
<VSCodeLink
onClick={() => {
vscode.postMessage({
type: "openExtensionSettings",
text: "cline.mcp",
})
}}
style={{ fontSize: "12px" }}>
Advanced MCP Settings
</VSCodeLink>
</div>
</div>
</div>
)
}
export default InstalledServersView
@@ -1,4 +1,4 @@
import { McpResource, McpResourceTemplate } from "../../../../src/shared/mcp"
import { McpResource, McpResourceTemplate } from "@shared/mcp"
type McpResourceRowProps = {
item: McpResource | McpResourceTemplate
@@ -1,7 +1,7 @@
import { VSCodeCheckbox } from "@vscode/webview-ui-toolkit/react"
import { McpTool } from "../../../../src/shared/mcp"
import { vscode } from "../../utils/vscode"
import { useExtensionState } from "../../context/ExtensionStateContext"
import { McpTool } from "@shared/mcp"
import { vscode } from "@/utils/vscode"
import { useExtensionState } from "@/context/ExtensionStateContext"
type McpToolRowProps = {
tool: McpTool
@@ -1,241 +1,22 @@
import { McpServer } from "@shared/mcp"
import { DEFAULT_MCP_TIMEOUT_SECONDS } from "@shared/mcp"
import { useState } from "react"
import { vscode } from "@/utils/vscode"
import {
VSCodeButton,
VSCodeLink,
VSCodeCheckbox,
VSCodeDropdown,
VSCodeOption,
VSCodePanels,
VSCodePanelTab,
VSCodePanelView,
VSCodeDropdown,
VSCodeOption,
VSCodeCheckbox,
} from "@vscode/webview-ui-toolkit/react"
import { useEffect, useState } from "react"
import styled from "styled-components"
import { DEFAULT_MCP_TIMEOUT_SECONDS, McpServer } from "../../../../src/shared/mcp"
import { useExtensionState } from "../../context/ExtensionStateContext"
import { getMcpServerDisplayName } from "../../utils/mcp"
import { vscode } from "../../utils/vscode"
import McpMarketplaceView from "./marketplace/McpMarketplaceView"
import McpResourceRow from "./McpResourceRow"
import { getMcpServerDisplayName } from "@/utils/mcp"
import DangerButton from "@/components/common/DangerButton"
import McpToolRow from "./McpToolRow"
import DangerButton from "../common/DangerButton"
import AddRemoteServerForm from "./tabs/AddRemoteServerForm"
import AddLocalServerForm from "./tabs/AddLocalServerForm"
import McpResourceRow from "./McpResourceRow"
import { useExtensionState } from "@/context/ExtensionStateContext"
type McpViewProps = {
onDone: () => void
}
const McpView = ({ onDone }: McpViewProps) => {
const { mcpServers: servers, mcpMarketplaceEnabled } = useExtensionState()
const [activeTab, setActiveTab] = useState(mcpMarketplaceEnabled ? "marketplace" : "installed")
const [activeSubTab, setActiveSubTab] = useState("remote")
const handleTabChange = (tab: string) => {
setActiveTab(tab)
}
useEffect(() => {
if (!mcpMarketplaceEnabled && activeTab === "marketplace") {
// If marketplace is disabled and we're on marketplace tab, switch to installed
setActiveTab("installed")
}
}, [mcpMarketplaceEnabled, activeTab])
useEffect(() => {
if (mcpMarketplaceEnabled) {
vscode.postMessage({ type: "silentlyRefreshMcpMarketplace" })
vscode.postMessage({ type: "fetchLatestMcpServersFromHub" })
}
}, [mcpMarketplaceEnabled])
return (
<div
style={{
position: "fixed",
top: 0,
left: 0,
right: 0,
bottom: 0,
display: "flex",
flexDirection: "column",
}}>
<div
style={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
padding: "10px 17px 5px 20px",
}}>
<h3 style={{ color: "var(--vscode-foreground)", margin: 0 }}>MCP Servers</h3>
<VSCodeButton onClick={onDone}>Done</VSCodeButton>
</div>
<div style={{ flex: 1, overflow: "auto" }}>
{/* Tabs container */}
<div
style={{
display: "flex",
gap: "1px",
padding: "0 20px 0 20px",
borderBottom: "1px solid var(--vscode-panel-border)",
}}>
{mcpMarketplaceEnabled && (
<TabButton isActive={activeTab === "marketplace"} onClick={() => handleTabChange("marketplace")}>
Marketplace
</TabButton>
)}
<TabButton isActive={activeTab === "addRemote"} onClick={() => handleTabChange("addRemote")}>
Add Server
</TabButton>
<TabButton isActive={activeTab === "installed"} onClick={() => handleTabChange("installed")}>
Installed
</TabButton>
</div>
{/* Content container */}
<div style={{ width: "100%" }}>
{mcpMarketplaceEnabled && activeTab === "marketplace" && <McpMarketplaceView />}
{activeTab === "addRemote" && (
<div style={{ padding: "5px 0 0 0" }}>
<div
style={{
display: "flex",
gap: "1px",
padding: "0 20px 0 20px",
borderBottom: "1px solid var(--vscode-panel-border)",
}}>
<TabButton isActive={activeSubTab === "remote"} onClick={() => setActiveSubTab("remote")}>
Remote (SSE)
</TabButton>
<TabButton isActive={activeSubTab === "local"} onClick={() => setActiveSubTab("local")}>
Local (Command)
</TabButton>
</div>
<div>
{activeSubTab === "remote" && (
<AddRemoteServerForm onServerAdded={() => handleTabChange("installed")} />
)}
{activeSubTab === "local" && (
<AddLocalServerForm onServerAdded={() => handleTabChange("installed")} />
)}
</div>
</div>
)}
{activeTab === "installed" && (
<div style={{ padding: "16px 20px" }}>
<div
style={{
color: "var(--vscode-foreground)",
fontSize: "13px",
marginBottom: "16px",
marginTop: "5px",
}}>
The{" "}
<VSCodeLink href="https://github.com/modelcontextprotocol" style={{ display: "inline" }}>
Model Context Protocol
</VSCodeLink>{" "}
enables communication with locally running MCP servers that provide additional tools and resources
to extend Cline's capabilities. You can use{" "}
<VSCodeLink href="https://github.com/modelcontextprotocol/servers" style={{ display: "inline" }}>
community-made servers
</VSCodeLink>{" "}
or ask Cline to create new tools specific to your workflow (e.g., "add a tool that gets the latest
npm docs").{" "}
<VSCodeLink href="https://x.com/sdrzn/status/1867271665086074969" style={{ display: "inline" }}>
See a demo here.
</VSCodeLink>
</div>
{servers.length > 0 ? (
<div
style={{
display: "flex",
flexDirection: "column",
gap: "10px",
}}>
{servers.map((server) => (
<ServerRow key={server.name} server={server} />
))}
</div>
) : (
<div
style={{
display: "flex",
flexDirection: "column",
alignItems: "center",
gap: "12px",
marginTop: 20,
marginBottom: 20,
color: "var(--vscode-descriptionForeground)",
}}>
No MCP servers installed
</div>
)}
{/* Settings Section */}
<div style={{ marginBottom: "20px", marginTop: 10 }}>
<VSCodeButton
appearance="secondary"
style={{ width: "100%", marginBottom: "5px" }}
onClick={() => {
vscode.postMessage({ type: "openMcpSettings" })
}}>
Edit Configuration
</VSCodeButton>
<div style={{ textAlign: "center" }}>
<VSCodeLink
onClick={() => {
vscode.postMessage({
type: "openExtensionSettings",
text: "cline.mcp",
})
}}
style={{ fontSize: "12px" }}>
Advanced MCP Settings
</VSCodeLink>
</div>
</div>
</div>
)}
</div>
</div>
</div>
)
}
const StyledTabButton = styled.button<{ isActive: boolean }>`
background: none;
border: none;
border-bottom: 2px solid ${(props) => (props.isActive ? "var(--vscode-foreground)" : "transparent")};
color: ${(props) => (props.isActive ? "var(--vscode-foreground)" : "var(--vscode-descriptionForeground)")};
padding: 8px 16px;
cursor: pointer;
font-size: 13px;
margin-bottom: -1px;
font-family: inherit;
&:hover {
color: var(--vscode-foreground);
}
`
export const TabButton = ({
children,
isActive,
onClick,
}: {
children: React.ReactNode
isActive: boolean
onClick: () => void
}) => (
<StyledTabButton isActive={isActive} onClick={onClick}>
{children}
</StyledTabButton>
)
// Server Row Component
const ServerRow = ({ server }: { server: McpServer }) => {
const { mcpMarketplaceCatalog, autoApprovalSettings } = useExtensionState()
@@ -576,4 +357,4 @@ const ServerRow = ({ server }: { server: McpServer }) => {
)
}
export default McpView
export default ServerRow
@@ -1,7 +1,7 @@
import { useCallback, useState, useRef, useMemo } from "react"
import styled from "styled-components"
import { McpMarketplaceItem, McpServer } from "../../../../../src/shared/mcp"
import { vscode } from "../../../utils/vscode"
import { McpMarketplaceItem, McpServer } from "@shared/mcp"
import { vscode } from "@/utils/vscode"
import { useEvent } from "react-use"
interface McpMarketplaceCardProps {
@@ -8,9 +8,9 @@ import {
VSCodeOption,
VSCodeTextField,
} from "@vscode/webview-ui-toolkit/react"
import { McpMarketplaceItem } from "../../../../../src/shared/mcp"
import { useExtensionState } from "../../../context/ExtensionStateContext"
import { vscode } from "../../../utils/vscode"
import { McpMarketplaceItem } from "@shared/mcp"
import { useExtensionState } from "@/context/ExtensionStateContext"
import { vscode } from "@/utils/vscode"
import McpMarketplaceCard from "./McpMarketplaceCard"
import McpSubmitCard from "./McpSubmitCard"
const McpMarketplaceView = () => {
@@ -45,12 +45,12 @@ import {
xaiModels,
sambanovaModels,
sambanovaDefaultModelId,
} from "../../../../src/shared/api"
import { ExtensionMessage } from "../../../../src/shared/ExtensionMessage"
import { useExtensionState } from "../../context/ExtensionStateContext"
import { vscode } from "../../utils/vscode"
import { getAsVar, VSC_DESCRIPTION_FOREGROUND } from "../../utils/vscStyles"
import VSCodeButtonLink from "../common/VSCodeButtonLink"
} from "@shared/api"
import { ExtensionMessage } from "@shared/ExtensionMessage"
import { useExtensionState } from "@/context/ExtensionStateContext"
import { vscode } from "@/utils/vscode"
import { getAsVar, VSC_DESCRIPTION_FOREGROUND } from "@/utils/vscStyles"
import VSCodeButtonLink from "@/components/common/VSCodeButtonLink"
import OpenRouterModelPicker, { ModelDescriptionMarkdown, OPENROUTER_MODEL_PICKER_Z_INDEX } from "./OpenRouterModelPicker"
import { ClineAccountInfoCard } from "./ClineAccountInfoCard"
@@ -1,7 +1,7 @@
import { VSCodeButton } from "@vscode/webview-ui-toolkit/react"
import { useFirebaseAuth } from "../../context/FirebaseAuthContext"
import { vscode } from "../../utils/vscode"
import { useExtensionState } from "../../context/ExtensionStateContext"
import { useFirebaseAuth } from "@/context/FirebaseAuthContext"
import { vscode } from "@/utils/vscode"
import { useExtensionState } from "@/context/ExtensionStateContext"
export const ClineAccountInfoCard = () => {
const { user: firebaseUser, handleSignOut } = useFirebaseAuth()
@@ -2,7 +2,7 @@ import { VSCodeLink } from "@vscode/webview-ui-toolkit/react"
import { memo, useEffect, useRef, useState } from "react"
import { useRemark } from "react-remark"
import styled from "styled-components"
import { CODE_BLOCK_BG_COLOR } from "../common/CodeBlock"
import { CODE_BLOCK_BG_COLOR } from "@/components/common/CodeBlock"
const StyledMarkdown = styled.div`
font-family:
@@ -3,8 +3,8 @@ import Fuse from "fuse.js"
import React, { KeyboardEvent, memo, useEffect, useMemo, useRef, useState } from "react"
import { useRemark } from "react-remark"
import styled from "styled-components"
import { useExtensionState } from "../../context/ExtensionStateContext"
import { vscode } from "../../utils/vscode"
import { useExtensionState } from "@/context/ExtensionStateContext"
import { vscode } from "@/utils/vscode"
import { highlight } from "../history/HistoryView"
const OpenAiModelPicker: React.FC = () => {
@@ -1,15 +1,15 @@
import { VSCodeCheckbox, VSCodeDropdown, VSCodeLink, VSCodeOption, VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
import { VSCodeLink, VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
import Fuse from "fuse.js"
import React, { KeyboardEvent, memo, useEffect, useMemo, useRef, useState } from "react"
import { useRemark } from "react-remark"
import { useMount } from "react-use"
import styled from "styled-components"
import { openRouterDefaultModelId } from "../../../../src/shared/api"
import { useExtensionState } from "../../context/ExtensionStateContext"
import { vscode } from "../../utils/vscode"
import { openRouterDefaultModelId } from "@shared/api"
import { useExtensionState } from "@/context/ExtensionStateContext"
import { vscode } from "@/utils/vscode"
import { highlight } from "../history/HistoryView"
import { DropdownContainer, ModelInfoView, normalizeApiConfiguration } from "./ApiOptions"
import { CODE_BLOCK_BG_COLOR } from "../common/CodeBlock"
import { ModelInfoView, normalizeApiConfiguration } from "./ApiOptions"
import { CODE_BLOCK_BG_COLOR } from "@/components/common/CodeBlock"
import ThinkingBudgetSlider from "./ThinkingBudgetSlider"
export interface OpenRouterModelPickerProps {
@@ -1,21 +1,13 @@
import {
VSCodeButton,
VSCodeCheckbox,
VSCodeLink,
VSCodeTextArea,
VSCodePanels,
VSCodePanelTab,
VSCodePanelView,
} from "@vscode/webview-ui-toolkit/react"
import { VSCodeButton, VSCodeCheckbox, VSCodeLink, VSCodeTextArea } from "@vscode/webview-ui-toolkit/react"
import { memo, useCallback, useEffect, useState } from "react"
import { useExtensionState } from "../../context/ExtensionStateContext"
import { validateApiConfiguration, validateModelId } from "../../utils/validate"
import { vscode } from "../../utils/vscode"
import SettingsButton from "../common/SettingsButton"
import { useExtensionState } from "@/context/ExtensionStateContext"
import { validateApiConfiguration, validateModelId } from "@/utils/validate"
import { vscode } from "@/utils/vscode"
import SettingsButton from "@/components/common/SettingsButton"
import ApiOptions from "./ApiOptions"
import { TabButton } from "../mcp/McpView"
import { TabButton } from "../mcp/configuration/McpConfigurationView"
import { useEvent } from "react-use"
import { ExtensionMessage } from "../../../../src/shared/ExtensionMessage"
import { ExtensionMessage } from "@shared/ExtensionMessage"
const { IS_DEV } = process.env
type SettingsViewProps = {
@@ -1,5 +1,5 @@
import { memo, useState } from "react"
import { anthropicModels, ApiConfiguration } from "../../../../src/shared/api"
import { anthropicModels, ApiConfiguration } from "@shared/api"
import { VSCodeCheckbox } from "@vscode/webview-ui-toolkit/react"
import styled from "styled-components"
@@ -1,7 +1,7 @@
import { render, screen, fireEvent } from "@testing-library/react"
import { describe, it, expect, vi } from "vitest"
import ApiOptions from "../ApiOptions"
import { ExtensionStateContextProvider } from "../../../context/ExtensionStateContext"
import { ExtensionStateContextProvider } from "@/context/ExtensionStateContext"
vi.mock("../../../context/ExtensionStateContext", async (importOriginal) => {
const actual = await importOriginal()
@@ -1,12 +1,10 @@
import { VSCodeButton, VSCodeDivider, VSCodeLink, VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
import { useCallback, useEffect, useState } from "react"
import { useEvent } from "react-use"
import { ExtensionMessage } from "../../../../src/shared/ExtensionMessage"
import { useExtensionState } from "../../context/ExtensionStateContext"
import { validateApiConfiguration } from "../../utils/validate"
import { vscode } from "../../utils/vscode"
import ApiOptions from "../settings/ApiOptions"
import ClineLogoWhite from "../../assets/ClineLogoWhite"
import { VSCodeButton, VSCodeLink } from "@vscode/webview-ui-toolkit/react"
import { useEffect, useState } from "react"
import { useExtensionState } from "@/context/ExtensionStateContext"
import { validateApiConfiguration } from "@/utils/validate"
import { vscode } from "@/utils/vscode"
import ApiOptions from "@/components/settings/ApiOptions"
import ClineLogoWhite from "@/assets/ClineLogoWhite"
const WelcomeView = () => {
const { apiConfiguration } = useExtensionState()
@@ -1,15 +1,15 @@
import React, { createContext, useCallback, useContext, useEffect, useState } from "react"
import { useEvent } from "react-use"
import { DEFAULT_AUTO_APPROVAL_SETTINGS } from "../../../src/shared/AutoApprovalSettings"
import { ExtensionMessage, ExtensionState, DEFAULT_PLATFORM } from "../../../src/shared/ExtensionMessage"
import { ApiConfiguration, ModelInfo, openRouterDefaultModelId, openRouterDefaultModelInfo } from "../../../src/shared/api"
import { findLastIndex } from "../../../src/shared/array"
import { DEFAULT_AUTO_APPROVAL_SETTINGS } from "@shared/AutoApprovalSettings"
import { ExtensionMessage, ExtensionState, DEFAULT_PLATFORM } from "@shared/ExtensionMessage"
import { ApiConfiguration, ModelInfo, openRouterDefaultModelId, openRouterDefaultModelInfo } from "@shared/api"
import { findLastIndex } from "@shared/array"
import { McpMarketplaceCatalog, McpServer } from "../../../src/shared/mcp"
import { convertTextMateToHljs } from "../utils/textMateToHljs"
import { vscode } from "../utils/vscode"
import { DEFAULT_BROWSER_SETTINGS } from "../../../src/shared/BrowserSettings"
import { DEFAULT_CHAT_SETTINGS } from "../../../src/shared/ChatSettings"
import { TelemetrySetting } from "../../../src/shared/TelemetrySetting"
import { DEFAULT_BROWSER_SETTINGS } from "@shared/BrowserSettings"
import { DEFAULT_CHAT_SETTINGS } from "@shared/ChatSettings"
import { TelemetrySetting } from "@shared/TelemetrySetting"
interface ExtensionStateContextType extends ExtensionState {
didHydrateState: boolean
@@ -1,7 +1,7 @@
import { User, getAuth, signInWithCustomToken, signOut } from "firebase/auth"
import { initializeApp } from "firebase/app"
import React, { createContext, useCallback, useContext, useEffect, useState } from "react"
import { vscode } from "../utils/vscode"
import { vscode } from "@/utils/vscode"
// Firebase configuration from extension
const firebaseConfig = {
-1
View File
@@ -1,6 +1,5 @@
import { StrictMode } from "react"
import { createRoot } from "react-dom/client"
import { PostHogProvider } from "posthog-js/react"
import "./index.css"
import App from "./App.tsx"
import "../../node_modules/@vscode/codicons/dist/codicon.css"
+1 -1
View File
@@ -1,4 +1,4 @@
import { mentionRegex } from "../../../src/shared/context-mentions"
import { mentionRegex } from "@shared/context-mentions"
import { Fzf } from "fzf"
export function insertMention(text: string, position: number, value: string): { newValue: string; mentionIndex: number } {
+1 -1
View File
@@ -1,4 +1,4 @@
import { McpMarketplaceCatalog, McpResource, McpResourceTemplate } from "../../../src/shared/mcp"
import { McpMarketplaceCatalog, McpResource, McpResourceTemplate } from "@shared/mcp"
/**
* Matches a URI against an array of URI templates and returns the matching template
+2 -2
View File
@@ -1,5 +1,5 @@
import { ApiConfiguration, openRouterDefaultModelId } from "../../../src/shared/api"
import { ModelInfo } from "../../../src/shared/api"
import { ApiConfiguration, openRouterDefaultModelId, ModelInfo } from "@shared/api"
export function validateApiConfiguration(apiConfiguration?: ApiConfiguration): string | undefined {
if (apiConfiguration) {
switch (apiConfiguration.apiProvider) {
+1 -1
View File
@@ -1,4 +1,4 @@
import { WebviewMessage } from "../../../src/shared/WebviewMessage"
import { WebviewMessage } from "@shared/WebviewMessage"
import type { WebviewApi } from "vscode-webview"
/**
+11 -1
View File
@@ -18,7 +18,17 @@
/* Linting */
"strict": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true
"noUncheckedSideEffectImports": true,
/* Aliasing */
"baseUrl": ".",
"paths": {
"@/*": ["src/*"],
"@components/*": ["src/components/*"],
"@context/*": ["src/context/*"],
"@shared/*": ["../src/shared/*"],
"@utils/*": ["src/utils/*"]
}
},
"include": ["src"],
"exclude": ["src/**/__tests__/**"]
+10
View File
@@ -3,6 +3,7 @@
import { defineConfig } from "vite"
import tailwindcss from "@tailwindcss/vite"
import react from "@vitejs/plugin-react-swc"
import { resolve } from "path"
export default defineConfig({
plugins: [react(), tailwindcss()],
@@ -45,4 +46,13 @@ export default defineConfig({
IS_DEV: JSON.stringify(process.env.IS_DEV),
},
},
resolve: {
alias: {
"@": resolve(__dirname, "./src"),
"@components": resolve(__dirname, "./src/components"),
"@context": resolve(__dirname, "./src/context"),
"@shared": resolve(__dirname, "../src/shared"),
"@utils": resolve(__dirname, "./src/utils"),
},
},
})