Compare commits

..

1 Commits

Author SHA1 Message Date
Dennis Bartlett 4a2b97d856 Update workflow controls 2025-03-31 00:08:39 -07:00
21 changed files with 73 additions and 120 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"claude-dev": minor
---
improving search and replace edit failure behaviors
+5
View File
@@ -0,0 +1,5 @@
---
"claude-dev": patch
---
Update Google Gemini API key link
+5
View File
@@ -0,0 +1,5 @@
---
"claude-dev": minor
---
added telemetry to track replace_in_file tool failures
+5
View File
@@ -0,0 +1,5 @@
---
"claude-dev": minor
---
feat(extension): add access to history, mcp, and new task buttons in popout view
+5
View File
@@ -0,0 +1,5 @@
---
"claude-dev": minor
---
Support connecting to SSE servers
+5
View File
@@ -0,0 +1,5 @@
---
"claude-dev": patch
---
Move the MCP Restart and Delete buttons and add an auto-approve all toggle
+5
View File
@@ -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
+5
View File
@@ -0,0 +1,5 @@
---
"claude-dev": minor
---
adding task id to request headers
+5
View File
@@ -0,0 +1,5 @@
---
"claude-dev": minor
---
Add toggle disabled for remote servers
+5
View File
@@ -0,0 +1,5 @@
---
"claude-dev": minor
---
added task feedback thumbs up thumbs down telemetry
+2 -2
View File
@@ -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:
-12
View File
@@ -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
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.8.5",
"version": "3.8.4",
"icon": "assets/icons/icon.png",
"engines": {
"vscode": "^1.84.0"
-9
View File
@@ -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()
+1 -6
View File
@@ -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)
+9 -62
View File
@@ -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()
-2
View File
@@ -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
+4 -4
View File
@@ -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": {
+1 -1
View File
@@ -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,