Compare commits

...

5 Commits

Author SHA1 Message Date
Arafatkatze 5d77a9a787 Send to cline provider 2026-01-27 18:28:13 -08:00
cline-test 92ebfce0cb feat(settings): Support linking to recommended or free model picker. 2026-01-27 18:01:44 -08:00
cline-test 8a5042a8bc release(3.55.0): Version bump and update WhatsNewModal 2026-01-27 17:31:11 -08:00
github-actions 726853d679 Updating CHANGELOG.md format 2026-01-27 23:52:40 +00:00
github-actions[bot] 0f52d80e55 changeset version bump 2026-01-27 23:52:38 +00:00
11 changed files with 142 additions and 32 deletions
-5
View File
@@ -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>`
+6
View File
@@ -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
+2 -2
View File
@@ -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
View File
@@ -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,