mirror of
https://github.com/cline/cline.git
synced 2026-09-05 05:02:27 +08:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4a2b97d856 |
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"claude-dev": minor
|
||||
---
|
||||
|
||||
improving search and replace edit failure behaviors
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"claude-dev": patch
|
||||
---
|
||||
|
||||
Update Google Gemini API key link
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"claude-dev": minor
|
||||
---
|
||||
|
||||
added telemetry to track replace_in_file tool failures
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"claude-dev": minor
|
||||
---
|
||||
|
||||
feat(extension): add access to history, mcp, and new task buttons in popout view
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"claude-dev": minor
|
||||
---
|
||||
|
||||
Support connecting to SSE servers
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"claude-dev": patch
|
||||
---
|
||||
|
||||
Move the MCP Restart and Delete buttons and add an auto-approve all toggle
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"claude-dev": patch
|
||||
---
|
||||
|
||||
updated gemini-2.0-pro-exp-02-05 to gemini-2.5-pro-exp-03-25 for Vertex AI
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"claude-dev": minor
|
||||
---
|
||||
|
||||
adding task id to request headers
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"claude-dev": minor
|
||||
---
|
||||
|
||||
Add toggle disabled for remote servers
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"claude-dev": minor
|
||||
---
|
||||
|
||||
added task feedback thumbs up thumbs down telemetry
|
||||
@@ -3,6 +3,8 @@ run-name: Changeset Conversion
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
types: [closed]
|
||||
|
||||
env:
|
||||
@@ -14,9 +16,7 @@ jobs:
|
||||
# Job 1: Create version bump PR when changesets are merged to main
|
||||
changeset-pr-version-bump:
|
||||
if: >
|
||||
github.event_name == 'pull_request' &&
|
||||
github.event.pull_request.merged == true &&
|
||||
github.event.pull_request.base.ref == 'main' &&
|
||||
github.actor != 'github-actions'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
|
||||
@@ -1,17 +1,5 @@
|
||||
# Changelog
|
||||
|
||||
## [3.8.5]
|
||||
|
||||
- Add support for remote MCP Servers using SSE
|
||||
- Add gemini-2.5-pro-exp-03-25 to Vertex AI (thanks @arri-cc!)
|
||||
- Add access to history, mcp, and new task buttons in popout view
|
||||
- Add task feedback telemetry (thumbs up/down on task completion)
|
||||
- Add toggle disabled for remote servers
|
||||
- Move the MCP Restart and Delete buttons and add an auto-approve all toggle
|
||||
- Update Requestly UX for model selection (thanks @arafatkatze!)
|
||||
- Add escape for html content for gemini when running commands
|
||||
- Improve search and replace edit failure behaviors
|
||||
|
||||
## [3.8.4]
|
||||
|
||||
- Add Sambanova Deepseek-V3-0324
|
||||
|
||||
+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.8.5",
|
||||
"version": "3.8.4",
|
||||
"icon": "assets/icons/icon.png",
|
||||
"engines": {
|
||||
"vscode": "^1.84.0"
|
||||
|
||||
@@ -165,15 +165,6 @@ export class Controller {
|
||||
*/
|
||||
async handleWebviewMessage(message: WebviewMessage) {
|
||||
switch (message.type) {
|
||||
case "addRemoteServer": {
|
||||
try {
|
||||
await this.mcpHub?.addRemoteServer(message.serverName!, message.serverUrl!)
|
||||
} catch (error) {
|
||||
// We handle the errorin McpHub.ts where the function is defined
|
||||
console.error(`Failed to add remote server ${message.serverName}:`, error)
|
||||
}
|
||||
break
|
||||
}
|
||||
case "authStateChanged":
|
||||
await this.setUserInfo(message.user || undefined)
|
||||
await this.postStateToWebview()
|
||||
|
||||
@@ -2312,7 +2312,7 @@ export class Task {
|
||||
}
|
||||
}
|
||||
case "execute_command": {
|
||||
let command: string | undefined = block.params.command
|
||||
const command: string | undefined = block.params.command
|
||||
const requiresApprovalRaw: string | undefined = block.params.requires_approval
|
||||
const requiresApproval = requiresApprovalRaw?.toLowerCase() === "true"
|
||||
|
||||
@@ -2348,11 +2348,6 @@ export class Task {
|
||||
}
|
||||
this.consecutiveMistakeCount = 0
|
||||
|
||||
// gemini models tend to use unescaped html entities in commands
|
||||
if (this.api.getModel().id.includes("gemini")) {
|
||||
command = fixModelHtmlEscaping(command)
|
||||
}
|
||||
|
||||
const ignoredFileAttemptedToAccess = this.clineIgnoreController.validateCommand(command)
|
||||
if (ignoredFileAttemptedToAccess) {
|
||||
await this.say("clineignore_error", ignoredFileAttemptedToAccess)
|
||||
|
||||
@@ -46,14 +46,6 @@ class CheckpointTracker {
|
||||
private lastRetrievedShadowGitConfigWorkTree?: string
|
||||
private gitOperations: GitOperations
|
||||
|
||||
/**
|
||||
* Helper method to clean commit hashes that might have a "HEAD " prefix.
|
||||
* Used for backward compatibility with old tasks that stored hashes with the prefix.
|
||||
*/
|
||||
private cleanCommitHash(hash: string): string {
|
||||
return hash.startsWith("HEAD ") ? hash.slice(5) : hash
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new CheckpointTracker instance to manage checkpoints for a specific task.
|
||||
* The constructor is private - use the static create() method to instantiate.
|
||||
@@ -250,7 +242,7 @@ class CheckpointTracker {
|
||||
const gitPath = await getShadowGitPath(this.globalStoragePath, this.taskId, this.cwdHash)
|
||||
const git = simpleGit(path.dirname(gitPath))
|
||||
console.debug(`Using shadow git at: ${gitPath}`)
|
||||
await git.reset(["--hard", this.cleanCommitHash(commitHash)]) // Hard reset to target commit
|
||||
await git.reset(["--hard", commitHash]) // Hard reset to target commit
|
||||
console.debug(`Successfully reset to checkpoint: ${commitHash}`)
|
||||
|
||||
const durationMs = Math.round(performance.now() - startTime)
|
||||
@@ -291,8 +283,7 @@ class CheckpointTracker {
|
||||
// Stage all changes so that untracked files appear in diff summary
|
||||
await this.gitOperations.addCheckpointFiles(git)
|
||||
|
||||
const cleanRhs = rhsHash ? this.cleanCommitHash(rhsHash) : undefined
|
||||
const diffRange = cleanRhs ? `${this.cleanCommitHash(lhsHash)}..${cleanRhs}` : this.cleanCommitHash(lhsHash)
|
||||
const diffRange = rhsHash ? `${lhsHash}..${rhsHash}` : lhsHash
|
||||
console.info(`Diff range: ${diffRange}`)
|
||||
const diffSummary = await git.diffSummary([diffRange])
|
||||
|
||||
@@ -303,7 +294,7 @@ class CheckpointTracker {
|
||||
|
||||
let beforeContent = ""
|
||||
try {
|
||||
beforeContent = await git.show([`${this.cleanCommitHash(lhsHash)}:${filePath}`])
|
||||
beforeContent = await git.show([`${lhsHash}:${filePath}`])
|
||||
} catch (_) {
|
||||
// file didn't exist in older commit => remains empty
|
||||
}
|
||||
@@ -311,7 +302,7 @@ class CheckpointTracker {
|
||||
let afterContent = ""
|
||||
if (rhsHash) {
|
||||
try {
|
||||
afterContent = await git.show([`${this.cleanCommitHash(rhsHash)}:${filePath}`])
|
||||
afterContent = await git.show([`${rhsHash}:${filePath}`])
|
||||
} catch (_) {
|
||||
// file didn't exist in newer commit => remains empty
|
||||
}
|
||||
@@ -356,8 +347,7 @@ class CheckpointTracker {
|
||||
// Stage all changes so that untracked files appear in diff summary
|
||||
await this.gitOperations.addCheckpointFiles(git)
|
||||
|
||||
const cleanRhs = rhsHash ? this.cleanCommitHash(rhsHash) : undefined
|
||||
const diffRange = cleanRhs ? `${this.cleanCommitHash(lhsHash)}..${cleanRhs}` : this.cleanCommitHash(lhsHash)
|
||||
const diffRange = rhsHash ? `${lhsHash}..${rhsHash}` : lhsHash
|
||||
const diffSummary = await git.diffSummary([diffRange])
|
||||
|
||||
const durationMs = Math.round(performance.now() - startTime)
|
||||
|
||||
@@ -258,23 +258,15 @@ export class McpHub {
|
||||
const stderrStream = (transport as StdioClientTransport).stderr
|
||||
if (stderrStream) {
|
||||
stderrStream.on("data", async (data: Buffer) => {
|
||||
const output = data.toString()
|
||||
// Check if output contains INFO level log
|
||||
const isInfoLog = /^\s*INFO\b/.test(output)
|
||||
|
||||
if (isInfoLog) {
|
||||
// Log normal informational messages
|
||||
console.info(`Server "${name}" info:`, output)
|
||||
} else {
|
||||
// Treat as error log
|
||||
console.error(`Server "${name}" stderr:`, output)
|
||||
const connection = this.connections.find((conn) => conn.server.name === name)
|
||||
if (connection) {
|
||||
this.appendErrorMessage(connection, output)
|
||||
// Only notify webview if server is already disconnected
|
||||
if (connection.server.status === "disconnected") {
|
||||
await this.notifyWebviewOfServerChanges()
|
||||
}
|
||||
const errorOutput = data.toString()
|
||||
console.error(`Server "${name}" stderr:`, errorOutput)
|
||||
const connection = this.connections.find((conn) => conn.server.name === name)
|
||||
if (connection) {
|
||||
// NOTE: we do not set server status to "disconnected" because stderr logs do not necessarily mean the server crashed or disconnected, it could just be informational. In fact when the server first starts up, it immediately logs "<name> server running on stdio" to stderr.
|
||||
this.appendErrorMessage(connection, errorOutput)
|
||||
// Only need to update webview right away if it's already disconnected
|
||||
if (connection.server.status === "disconnected") {
|
||||
await this.notifyWebviewOfServerChanges()
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -286,7 +278,6 @@ export class McpHub {
|
||||
|
||||
// Connect
|
||||
await client.connect(transport)
|
||||
|
||||
connection.server.status = "connected"
|
||||
connection.server.error = ""
|
||||
|
||||
@@ -637,50 +628,6 @@ export class McpHub {
|
||||
}
|
||||
}
|
||||
|
||||
public async addRemoteServer(serverName: string, serverUrl: string) {
|
||||
try {
|
||||
const settings = await this.readAndValidateMcpSettingsFile()
|
||||
if (!settings) {
|
||||
throw new Error("Failed to read MCP settings")
|
||||
}
|
||||
|
||||
if (settings.mcpServers[serverName]) {
|
||||
throw new Error(`An MCP server with the name "${serverName}" already exists`)
|
||||
}
|
||||
|
||||
const urlValidation = z.string().url().safeParse(serverUrl)
|
||||
if (!urlValidation.success) {
|
||||
throw new Error(`Invalid server URL: ${serverUrl}. Please provide a valid URL.`)
|
||||
}
|
||||
|
||||
const serverConfig = {
|
||||
url: serverUrl,
|
||||
disabled: false,
|
||||
autoApprove: [],
|
||||
}
|
||||
|
||||
// TS expects the server config to be a McpServerConfig, but we know it's valid
|
||||
// The issue is that the type is not having the transportType field added to it
|
||||
|
||||
// ToDo: Add input types reflecting the non-transformed version
|
||||
settings.mcpServers[serverName] = serverConfig as unknown as McpServerConfig
|
||||
const settingsPath = await this.getMcpSettingsFilePath()
|
||||
await fs.writeFile(settingsPath, JSON.stringify(settings, null, 2))
|
||||
|
||||
await this.updateServerConnections(settings.mcpServers)
|
||||
|
||||
vscode.window.showInformationMessage(`Added and connected to ${serverName} MCP server`)
|
||||
} catch (error) {
|
||||
console.error("Failed to add remote MCP server:", error)
|
||||
|
||||
vscode.window.showErrorMessage(
|
||||
`Failed to add remote MCP server: ${error instanceof Error ? error.message : String(error)}`,
|
||||
)
|
||||
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
public async deleteServer(serverName: string) {
|
||||
try {
|
||||
const settingsPath = await this.getMcpSettingsFilePath()
|
||||
|
||||
@@ -8,7 +8,6 @@ import { TelemetrySetting } from "./TelemetrySetting"
|
||||
|
||||
export interface WebviewMessage {
|
||||
type:
|
||||
| "addRemoteServer"
|
||||
| "apiConfiguration"
|
||||
| "webviewDidLaunch"
|
||||
| "newTask"
|
||||
@@ -83,7 +82,6 @@ export interface WebviewMessage {
|
||||
timeout?: number
|
||||
// For toggleToolAutoApprove
|
||||
serverName?: string
|
||||
serverUrl?: string
|
||||
toolNames?: string[]
|
||||
autoApprove?: boolean
|
||||
|
||||
|
||||
Generated
+4
-4
@@ -51,7 +51,7 @@
|
||||
"tailwindcss": "^4.0.12",
|
||||
"typescript": "^5.7.3",
|
||||
"typescript-eslint": "^8.18.2",
|
||||
"vite": "^6.2.4",
|
||||
"vite": "^6.2.3",
|
||||
"vitest": "^3.0.5"
|
||||
}
|
||||
},
|
||||
@@ -8876,9 +8876,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "6.2.4",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-6.2.4.tgz",
|
||||
"integrity": "sha512-veHMSew8CcRzhL5o8ONjy8gkfmFJAd5Ac16oxBUjlwgX3Gq2Wqr+qNC3TjPIpy7TPV/KporLga5GT9HqdrCizw==",
|
||||
"version": "6.2.3",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-6.2.3.tgz",
|
||||
"integrity": "sha512-IzwM54g4y9JA/xAeBPNaDXiBF8Jsgl3VBQ2YQ/wOY6fyW3xMdSoltIV3Bo59DErdqdE6RxUfv8W69DvUorE4Eg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
"tailwindcss": "^4.0.12",
|
||||
"typescript": "^5.7.3",
|
||||
"typescript-eslint": "^8.18.2",
|
||||
"vite": "^6.2.4",
|
||||
"vite": "^6.2.3",
|
||||
"vitest": "^3.0.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1702,12 +1702,6 @@ export function normalizeApiConfiguration(apiConfiguration?: ApiConfiguration):
|
||||
selectedModelId: apiConfiguration?.lmStudioModelId || "",
|
||||
selectedModelInfo: openAiModelInfoSaneDefaults,
|
||||
}
|
||||
case "requesty":
|
||||
return {
|
||||
selectedProvider: provider,
|
||||
selectedModelId: apiConfiguration?.requestyModelId || "",
|
||||
selectedModelInfo: openAiModelInfoSaneDefaults,
|
||||
}
|
||||
case "vscode-lm":
|
||||
return {
|
||||
selectedProvider: provider,
|
||||
|
||||
Reference in New Issue
Block a user