mirror of
https://github.com/cline/cline.git
synced 2026-09-01 23:19:18 +08:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5d77a9a787 | |||
| 92ebfce0cb | |||
| 8a5042a8bc | |||
| 726853d679 | |||
| 0f52d80e55 |
@@ -1,5 +0,0 @@
|
||||
---
|
||||
"claude-dev": patch
|
||||
---
|
||||
|
||||
Add MCP prompts support - prompts from connected MCP servers now appear in slash command autocomplete as `/mcp:<server>:<prompt>`
|
||||
@@ -1,5 +1,11 @@
|
||||
# Changelog
|
||||
|
||||
## [3.55.0]
|
||||
|
||||
- Add new model: Arcee Trinity Large Preview
|
||||
- Add new model: Moonshot Kimi K2.5
|
||||
- Add MCP prompts support - prompts from connected MCP servers now appear in slash command autocomplete as `/mcp:<server>:<prompt>`
|
||||
|
||||
## [3.54.0]
|
||||
|
||||
### Added
|
||||
|
||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "claude-dev",
|
||||
"version": "3.53.1",
|
||||
"version": "3.55.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "claude-dev",
|
||||
"version": "3.53.1",
|
||||
"version": "3.55.0",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@anthropic-ai/sdk": "^0.37.0",
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
"name": "claude-dev",
|
||||
"displayName": "Cline",
|
||||
"description": "Autonomous coding agent right in your IDE, capable of creating/editing files, running commands, using the browser, and more with your permission every step of the way.",
|
||||
"version": "3.54.0",
|
||||
"version": "3.55.0",
|
||||
"icon": "assets/icons/icon.png",
|
||||
"engines": {
|
||||
"vscode": "^1.84.0"
|
||||
|
||||
@@ -16,7 +16,13 @@ interface WhatsNewModalProps {
|
||||
|
||||
export const WhatsNewModal: React.FC<WhatsNewModalProps> = ({ open, onClose, version }) => {
|
||||
const { clineUser } = useClineAuth()
|
||||
const { openRouterModels, setShowChatModelSelector, refreshOpenRouterModels, navigateToSettings } = useExtensionState()
|
||||
const {
|
||||
openRouterModels,
|
||||
setShowChatModelSelector,
|
||||
refreshOpenRouterModels,
|
||||
navigateToSettings,
|
||||
navigateToSettingsModelPicker,
|
||||
} = useExtensionState()
|
||||
const { handleFieldsChange } = useApiConfigurationHandlers()
|
||||
|
||||
const clickedModelsRef = useRef<Set<string>>(new Set())
|
||||
@@ -42,6 +48,19 @@ export const WhatsNewModal: React.FC<WhatsNewModalProps> = ({ open, onClose, ver
|
||||
[handleFieldsChange, openRouterModels, setShowChatModelSelector, onClose],
|
||||
)
|
||||
|
||||
const navigateToModelPicker = useCallback(
|
||||
(initialModelTab: "recommended" | "free") => {
|
||||
// Switch to Cline provider first so the model picker tab works
|
||||
handleFieldsChange({
|
||||
planModeApiProvider: "cline",
|
||||
actModeApiProvider: "cline",
|
||||
})
|
||||
onClose()
|
||||
navigateToSettingsModelPicker({ targetSection: "api-config", initialModelTab })
|
||||
},
|
||||
[handleFieldsChange, navigateToSettingsModelPicker, onClose],
|
||||
)
|
||||
|
||||
const setOpenAiCodexProvider = useCallback(() => {
|
||||
handleFieldsChange({
|
||||
planModeApiProvider: "openai-codex",
|
||||
@@ -79,6 +98,35 @@ export const WhatsNewModal: React.FC<WhatsNewModalProps> = ({ open, onClose, ver
|
||||
</Button>
|
||||
)
|
||||
|
||||
type InlineModelLinkProps =
|
||||
| { type: "model"; modelId: string; label: string }
|
||||
| { type: "picker"; pickerTab: "recommended" | "free"; label: string }
|
||||
|
||||
const InlineModelLink: React.FC<InlineModelLinkProps> = (props) => {
|
||||
if (props.type === "picker") {
|
||||
return (
|
||||
<span
|
||||
onClick={() => navigateToModelPicker(props.pickerTab)}
|
||||
style={{ color: "var(--vscode-textLink-foreground)", cursor: "pointer" }}>
|
||||
{props.label}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
const isClicked = clickedModelsRef.current.has(props.modelId)
|
||||
if (isClicked) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<span
|
||||
onClick={() => setModel(props.modelId)}
|
||||
style={{ color: "var(--vscode-textLink-foreground)", cursor: "pointer" }}>
|
||||
{props.label}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Dialog onOpenChange={(isOpen) => !isOpen && onClose()} open={open}>
|
||||
<DialogContent
|
||||
@@ -96,25 +144,28 @@ export const WhatsNewModal: React.FC<WhatsNewModalProps> = ({ open, onClose, ver
|
||||
{/* Description */}
|
||||
<ul className="text-sm pl-3 list-disc" style={{ color: "var(--vscode-descriptionForeground)" }}>
|
||||
<li className="mb-2">
|
||||
<strong>OpenAI ChatGPT Subscription Integration:</strong> Use your ChatGPT subscription directly in
|
||||
Cline with no additional token cost and no api keys to manage.{" "}
|
||||
<strong>New free model: Arcee Trinity Large:</strong> strong coding performance with an open-weight
|
||||
model.{" "}
|
||||
<InlineModelLink label="Try free" modelId="cline:arcee-ai/trinity-large-preview:free" type="model" />
|
||||
</li>
|
||||
<li className="mb-2">
|
||||
<strong>Try Kimi K2.5:</strong> Moonshot's latest with advanced reasoning for complex, multi-step
|
||||
coding tasks. Great for front-end tasks.{" "}
|
||||
<InlineModelLink label="Try now" modelId="cline:moonshotai/kimi-k2.5" type="model" />
|
||||
</li>
|
||||
<li className="mb-2">
|
||||
<strong>Bring your ChatGPT subscription to Cline!</strong> Use your existing plan directly with no per
|
||||
token costs or API keys to manage.{" "}
|
||||
<span
|
||||
onClick={setOpenAiCodexProvider}
|
||||
style={{ color: "var(--vscode-textLink-foreground)", cursor: "pointer" }}>
|
||||
Sign in
|
||||
Connect
|
||||
</span>
|
||||
</li>
|
||||
<li className="mb-2">
|
||||
<strong>Jupyter Notebooks:</strong> Comprehensive AI-assisted editing of <code>.ipynb</code> files
|
||||
with full cell-level context awareness.{" "}
|
||||
<a
|
||||
href="https://docs.cline.bot/features/jupyter-notebooks"
|
||||
style={{ color: "var(--vscode-textLink-foreground)" }}>
|
||||
Learn More
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<strong>Grok Code Fast 1</strong> and <strong>Devstral-2512</strong> are no longer free to use.
|
||||
<strong>Grok Code Fast 1 & Devstral are saying goodbye (to free):</strong> free promotion is done but
|
||||
there are plenty models in our free tier.{" "}
|
||||
<InlineModelLink label="See alternatives" pickerTab="free" type="picker" />
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -61,6 +61,7 @@ interface ApiOptionsProps {
|
||||
modelIdErrorMessage?: string
|
||||
isPopup?: boolean
|
||||
currentMode: Mode
|
||||
initialModelTab?: "recommended" | "free"
|
||||
}
|
||||
|
||||
// This is necessary to ensure dropdown opens downward, important for when this is used in popup
|
||||
@@ -87,7 +88,14 @@ declare module "vscode" {
|
||||
}
|
||||
}
|
||||
|
||||
const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, isPopup, currentMode }: ApiOptionsProps) => {
|
||||
const ApiOptions = ({
|
||||
showModelOptions,
|
||||
apiErrorMessage,
|
||||
modelIdErrorMessage,
|
||||
isPopup,
|
||||
currentMode,
|
||||
initialModelTab,
|
||||
}: ApiOptionsProps) => {
|
||||
// Use full context state for immediate save payload
|
||||
const { apiConfiguration, remoteConfigSettings } = useExtensionState()
|
||||
|
||||
@@ -349,7 +357,12 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is
|
||||
)}
|
||||
|
||||
{apiConfiguration && selectedProvider === "cline" && (
|
||||
<ClineProvider currentMode={currentMode} isPopup={isPopup} showModelOptions={showModelOptions} />
|
||||
<ClineProvider
|
||||
currentMode={currentMode}
|
||||
initialModelTab={initialModelTab}
|
||||
isPopup={isPopup}
|
||||
showModelOptions={showModelOptions}
|
||||
/>
|
||||
)}
|
||||
|
||||
{apiConfiguration && selectedProvider === "asksage" && (
|
||||
|
||||
@@ -43,6 +43,7 @@ export interface OpenRouterModelPickerProps {
|
||||
isPopup?: boolean
|
||||
currentMode: Mode
|
||||
showProviderRouting?: boolean
|
||||
initialTab?: "recommended" | "free"
|
||||
}
|
||||
|
||||
// Featured models for Cline provider organized by tabs
|
||||
@@ -89,7 +90,12 @@ export const freeModels = [
|
||||
|
||||
const FREE_CLINE_MODELS = freeModels.map((m) => m.id)
|
||||
|
||||
const OpenRouterModelPicker: React.FC<OpenRouterModelPickerProps> = ({ isPopup, currentMode, showProviderRouting }) => {
|
||||
const OpenRouterModelPicker: React.FC<OpenRouterModelPickerProps> = ({
|
||||
isPopup,
|
||||
currentMode,
|
||||
showProviderRouting,
|
||||
initialTab,
|
||||
}) => {
|
||||
const { handleModeFieldChange, handleModeFieldsChange, handleFieldChange } = useApiConfigurationHandlers()
|
||||
const { apiConfiguration, favoritedModelIds, openRouterModels, refreshOpenRouterModels } = useExtensionState()
|
||||
const modeFields = getModeSpecificFields(apiConfiguration, currentMode)
|
||||
@@ -97,9 +103,19 @@ const OpenRouterModelPicker: React.FC<OpenRouterModelPickerProps> = ({ isPopup,
|
||||
const [isDropdownVisible, setIsDropdownVisible] = useState(false)
|
||||
const [selectedIndex, setSelectedIndex] = useState(-1)
|
||||
const [activeTab, setActiveTab] = useState<"recommended" | "free">(() => {
|
||||
if (initialTab) {
|
||||
return initialTab
|
||||
}
|
||||
const currentModelId = modeFields.openRouterModelId || openRouterDefaultModelId
|
||||
return freeModels.some((m) => m.id === currentModelId) ? "free" : "recommended"
|
||||
})
|
||||
|
||||
// If a caller wants to deep-link to the Free tab (or Recommended), honor that.
|
||||
useEffect(() => {
|
||||
if (initialTab) {
|
||||
setActiveTab(initialTab)
|
||||
}
|
||||
}, [initialTab])
|
||||
const dropdownRef = useRef<HTMLDivElement>(null)
|
||||
const itemRefs = useRef<(HTMLDivElement | null)[]>([])
|
||||
const dropdownListRef = useRef<HTMLDivElement>(null)
|
||||
|
||||
@@ -131,7 +131,7 @@ const SettingsView = ({ onDone, targetSection }: SettingsViewProps) => {
|
||||
[],
|
||||
) // Empty deps - these imports never change
|
||||
|
||||
const { version, environment } = useExtensionState()
|
||||
const { version, environment, settingsInitialModelTab } = useExtensionState()
|
||||
|
||||
const [activeTab, setActiveTab] = useState<string>(targetSection || SETTINGS_TABS[0].id)
|
||||
|
||||
@@ -233,10 +233,12 @@ const SettingsView = ({ onDone, targetSection }: SettingsViewProps) => {
|
||||
props.onResetState = handleResetState
|
||||
} else if (activeTab === "about") {
|
||||
props.version = version
|
||||
} else if (activeTab === "api-config") {
|
||||
props.initialModelTab = settingsInitialModelTab
|
||||
}
|
||||
|
||||
return <Component {...props} />
|
||||
}, [activeTab, handleResetState, version])
|
||||
}, [activeTab, handleResetState, settingsInitialModelTab, version])
|
||||
|
||||
const titleColor = getEnvironmentColor(environment)
|
||||
|
||||
|
||||
@@ -9,12 +9,13 @@ interface ClineProviderProps {
|
||||
showModelOptions: boolean
|
||||
isPopup?: boolean
|
||||
currentMode: Mode
|
||||
initialModelTab?: "recommended" | "free"
|
||||
}
|
||||
|
||||
/**
|
||||
* The Cline provider configuration component
|
||||
*/
|
||||
export const ClineProvider = ({ showModelOptions, isPopup, currentMode }: ClineProviderProps) => {
|
||||
export const ClineProvider = ({ showModelOptions, isPopup, currentMode, initialModelTab }: ClineProviderProps) => {
|
||||
return (
|
||||
<div>
|
||||
{/* Cline Account Info Card */}
|
||||
@@ -25,7 +26,12 @@ export const ClineProvider = ({ showModelOptions, isPopup, currentMode }: ClineP
|
||||
{showModelOptions && (
|
||||
<>
|
||||
{/* OpenRouter Model Picker - includes Provider Routing in Advanced section */}
|
||||
<OpenRouterModelPicker currentMode={currentMode} isPopup={isPopup} showProviderRouting={true} />
|
||||
<OpenRouterModelPicker
|
||||
currentMode={currentMode}
|
||||
initialTab={initialModelTab}
|
||||
isPopup={isPopup}
|
||||
showProviderRouting={true}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -12,9 +12,10 @@ import { useApiConfigurationHandlers } from "../utils/useApiConfigurationHandler
|
||||
|
||||
interface ApiConfigurationSectionProps {
|
||||
renderSectionHeader?: (tabId: string) => JSX.Element | null
|
||||
initialModelTab?: "recommended" | "free"
|
||||
}
|
||||
|
||||
const ApiConfigurationSection = ({ renderSectionHeader }: ApiConfigurationSectionProps) => {
|
||||
const ApiConfigurationSection = ({ renderSectionHeader, initialModelTab }: ApiConfigurationSectionProps) => {
|
||||
const { planActSeparateModelsSetting, mode, apiConfiguration } = useExtensionState()
|
||||
const [currentTab, setCurrentTab] = useState<Mode>(mode)
|
||||
const { handleFieldsChange } = useApiConfigurationHandlers()
|
||||
@@ -50,11 +51,11 @@ const ApiConfigurationSection = ({ renderSectionHeader }: ApiConfigurationSectio
|
||||
|
||||
{/* Content container */}
|
||||
<div className="-mb-3">
|
||||
<ApiOptions currentMode={currentTab} showModelOptions={true} />
|
||||
<ApiOptions currentMode={currentTab} initialModelTab={initialModelTab} showModelOptions={true} />
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<ApiOptions currentMode={mode} showModelOptions={true} />
|
||||
<ApiOptions currentMode={mode} initialModelTab={initialModelTab} showModelOptions={true} />
|
||||
)}
|
||||
|
||||
<div className="mb-[5px]">
|
||||
|
||||
@@ -54,6 +54,7 @@ export interface ExtensionStateContextType extends ExtensionState {
|
||||
mcpTab?: McpViewTab
|
||||
showSettings: boolean
|
||||
settingsTargetSection?: string
|
||||
settingsInitialModelTab?: "recommended" | "free"
|
||||
showHistory: boolean
|
||||
showAccount: boolean
|
||||
showWorktrees: boolean
|
||||
@@ -102,6 +103,7 @@ export interface ExtensionStateContextType extends ExtensionState {
|
||||
// Navigation functions
|
||||
navigateToMcp: (tab?: McpViewTab) => void
|
||||
navigateToSettings: (targetSection?: string) => void
|
||||
navigateToSettingsModelPicker: (opts: { targetSection?: string; initialModelTab?: "recommended" | "free" }) => void
|
||||
navigateToHistory: () => void
|
||||
navigateToAccount: () => void
|
||||
navigateToWorktrees: () => void
|
||||
@@ -130,6 +132,7 @@ export const ExtensionStateContextProvider: React.FC<{
|
||||
const [mcpTab, setMcpTab] = useState<McpViewTab | undefined>(undefined)
|
||||
const [showSettings, setShowSettings] = useState(false)
|
||||
const [settingsTargetSection, setSettingsTargetSection] = useState<string | undefined>(undefined)
|
||||
const [settingsInitialModelTab, setSettingsInitialModelTab] = useState<"recommended" | "free" | undefined>(undefined)
|
||||
const [showHistory, setShowHistory] = useState(false)
|
||||
const [showAccount, setShowAccount] = useState(false)
|
||||
const [showWorktrees, setShowWorktrees] = useState(false)
|
||||
@@ -146,6 +149,7 @@ export const ExtensionStateContextProvider: React.FC<{
|
||||
const hideSettings = useCallback(() => {
|
||||
setShowSettings(false)
|
||||
setSettingsTargetSection(undefined)
|
||||
setSettingsInitialModelTab(undefined)
|
||||
}, [])
|
||||
const hideHistory = useCallback(() => setShowHistory(false), [setShowHistory])
|
||||
const hideAccount = useCallback(() => setShowAccount(false), [setShowAccount])
|
||||
@@ -175,6 +179,20 @@ export const ExtensionStateContextProvider: React.FC<{
|
||||
setShowAccount(false)
|
||||
setShowWorktrees(false)
|
||||
setSettingsTargetSection(targetSection)
|
||||
setSettingsInitialModelTab(undefined)
|
||||
setShowSettings(true)
|
||||
},
|
||||
[closeMcpView],
|
||||
)
|
||||
|
||||
const navigateToSettingsModelPicker = useCallback(
|
||||
(opts: { targetSection?: string; initialModelTab?: "recommended" | "free" }) => {
|
||||
setShowHistory(false)
|
||||
closeMcpView()
|
||||
setShowAccount(false)
|
||||
setShowWorktrees(false)
|
||||
setSettingsTargetSection(opts.targetSection)
|
||||
setSettingsInitialModelTab(opts.initialModelTab)
|
||||
setShowSettings(true)
|
||||
},
|
||||
[closeMcpView],
|
||||
@@ -773,6 +791,7 @@ export const ExtensionStateContextProvider: React.FC<{
|
||||
mcpTab,
|
||||
showSettings,
|
||||
settingsTargetSection,
|
||||
settingsInitialModelTab,
|
||||
showHistory,
|
||||
showAccount,
|
||||
showWorktrees,
|
||||
@@ -793,6 +812,7 @@ export const ExtensionStateContextProvider: React.FC<{
|
||||
// Navigation functions
|
||||
navigateToMcp,
|
||||
navigateToSettings,
|
||||
navigateToSettingsModelPicker,
|
||||
navigateToHistory,
|
||||
navigateToAccount,
|
||||
navigateToWorktrees,
|
||||
|
||||
Reference in New Issue
Block a user