mirror of
https://github.com/cline/cline.git
synced 2026-09-03 12:14:00 +08:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| eebb99c1e3 | |||
| 9ed44f7a83 | |||
| 6a95cc5f19 | |||
| 1d0637f39c | |||
| f2c16bae7a | |||
| 204f15ce1c | |||
| 8118e11596 | |||
| f7b593df35 | |||
| 2e0358a7a1 | |||
| 0fbc10f807 |
@@ -1,5 +0,0 @@
|
||||
---
|
||||
"claude-dev": patch
|
||||
---
|
||||
|
||||
improve cline command permission validation logic. add cline command permission man page documentation
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
"claude-dev": patch
|
||||
---
|
||||
|
||||
fix(extract-text): strip notebook outputs to reduce context size
|
||||
|
||||
Strip notebook cell outputs when extracting text content from Jupyter notebooks, significantly reducing the amount of context sent to the LLM while preserving the essential code and markdown content.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
"claude-dev": patch
|
||||
---
|
||||
|
||||
Wiring-up "conditionals" for Cline Rules files.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"claude-dev": patch
|
||||
---
|
||||
|
||||
Make Sonnet 4.5 the default Amazon Bedrock model id
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
"claude-dev": patch
|
||||
---
|
||||
|
||||
Fix drag & drop files from SSH remote workspaces into chat
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
"claude-dev": patch
|
||||
---
|
||||
|
||||
Updated switch component to adhere to 3:1 contrast accessibility standard for both light and dark vscode themes
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
"claude-dev": patch
|
||||
---
|
||||
|
||||
Remove hooks feature setting and make it always enabled (except on Windows).
|
||||
+7
-2
@@ -1,18 +1,23 @@
|
||||
# Changelog
|
||||
|
||||
## [3.53.0]
|
||||
|
||||
### Fixed
|
||||
- Removed grok model from free tier
|
||||
|
||||
## [3.52.0]
|
||||
|
||||
### Added
|
||||
|
||||
- Users with ChatGPT Plus or Pro subscriptions can now use GPT-5 models directly through Cline without needing an API key. Authentication is handled via OAuth through OpenAI's authentication system.
|
||||
- Grok models are now moving out of free tier and into paid plans.
|
||||
- Introduces comprehensive Jupyter Notebook support for Cline, enabling AI-assisted editing of `.ipynb` files with full cell-level context awareness.
|
||||
- Introduces comprehensive Jupyter Notebook support for Cline, enabling AI-assisted editing of `.ipynb` files with full cell-level context awareness.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Bugs in DiffViewProvider for file editing
|
||||
- Ollama's recommended models to use correct identifiers
|
||||
|
||||
|
||||
## [3.51.0]
|
||||
|
||||
### Added
|
||||
|
||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "claude-dev",
|
||||
"version": "3.52.0",
|
||||
"version": "3.53.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "claude-dev",
|
||||
"version": "3.52.0",
|
||||
"version": "3.53.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.52.0",
|
||||
"version": "3.53.0",
|
||||
"icon": "assets/icons/icon.png",
|
||||
"engines": {
|
||||
"vscode": "^1.84.0"
|
||||
|
||||
@@ -110,9 +110,13 @@ interface ProviderChainOptions {
|
||||
profile?: string
|
||||
}
|
||||
|
||||
// a special jp inference profile was created for sonnet 4.5
|
||||
// a special jp inference profile was created for sonnet 4.5 & haiku 4.5
|
||||
// https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles-support.html
|
||||
const JP_SUPPORTED_CRIS_MODELS = ["anthropic.claude-sonnet-4-5-20250929-v1:0", "anthropic.claude-sonnet-4-5-20250929-v1:0:1m"]
|
||||
const JP_SUPPORTED_CRIS_MODELS = [
|
||||
"anthropic.claude-sonnet-4-5-20250929-v1:0",
|
||||
"anthropic.claude-sonnet-4-5-20250929-v1:0:1m",
|
||||
"anthropic.claude-haiku-4-5-20251001-v1:0",
|
||||
]
|
||||
|
||||
// https://docs.anthropic.com/en/api/claude-on-amazon-bedrock
|
||||
export class AwsBedrockHandler implements ApiHandler {
|
||||
|
||||
@@ -112,10 +112,11 @@ export class CerebrasHandler implements ApiHandler {
|
||||
}
|
||||
|
||||
try {
|
||||
const model = this.getModel()
|
||||
const stream = await client.chat.completions.create({
|
||||
model: this.getModel().id,
|
||||
model: model.id,
|
||||
messages: cerebrasMessages,
|
||||
temperature: 0,
|
||||
temperature: model.info.temperature ?? 0,
|
||||
stream: true,
|
||||
max_tokens: CEREBRAS_DEFAULT_MAX_TOKENS,
|
||||
})
|
||||
|
||||
@@ -199,7 +199,7 @@ export class ClineHandler implements ApiHandler {
|
||||
// @ts-ignore-next-line
|
||||
let totalCost = (chunk.usage.cost || 0) + (chunk.usage.cost_details?.upstream_inference_cost || 0)
|
||||
|
||||
if (["x-ai/grok-code-fast-1", "kwaipilot/kat-coder-pro"].includes(this.getModel().id)) {
|
||||
if (["kwaipilot/kat-coder-pro"].includes(this.getModel().id)) {
|
||||
totalCost = 0
|
||||
}
|
||||
|
||||
|
||||
@@ -4,14 +4,12 @@ import * as pathUtils from "@utils/path"
|
||||
import { expect } from "chai"
|
||||
import { afterEach, beforeEach, describe, it } from "mocha"
|
||||
import * as sinon from "sinon"
|
||||
import { Logger } from "@/shared/services/Logger"
|
||||
import { ifFileExistsRelativePath } from "../ifFileExistsRelativePath"
|
||||
|
||||
describe("ifFileExistsRelativePath", () => {
|
||||
let sandbox: sinon.SinonSandbox
|
||||
let mockController: Controller
|
||||
let getWorkspacePathStub: sinon.SinonStub
|
||||
let consoleErrorStub: sinon.SinonStub
|
||||
|
||||
beforeEach(() => {
|
||||
sandbox = sinon.createSandbox()
|
||||
@@ -21,9 +19,6 @@ describe("ifFileExistsRelativePath", () => {
|
||||
|
||||
// Stub getWorkspacePath utility
|
||||
getWorkspacePathStub = sandbox.stub(pathUtils, "getWorkspacePath")
|
||||
|
||||
// Stub Logger.error to prevent test output pollution
|
||||
consoleErrorStub = sandbox.stub(Logger, "error")
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
@@ -44,12 +39,11 @@ describe("ifFileExistsRelativePath", () => {
|
||||
expect(typeof result.value).to.equal("boolean")
|
||||
})
|
||||
|
||||
it("should return false and log error when no workspace path is available", async () => {
|
||||
it("should return false when no workspace path is available", async () => {
|
||||
const noWorkspaceScenarios = [null, undefined]
|
||||
|
||||
for (const workspaceValue of noWorkspaceScenarios) {
|
||||
getWorkspacePathStub.resolves(workspaceValue)
|
||||
consoleErrorStub.resetHistory()
|
||||
|
||||
const request = StringRequest.create({
|
||||
value: "src/test.ts",
|
||||
@@ -58,7 +52,6 @@ describe("ifFileExistsRelativePath", () => {
|
||||
const result = await ifFileExistsRelativePath(mockController, request)
|
||||
|
||||
expect(result).to.deep.equal(BooleanResponse.create({ value: false }))
|
||||
expect(consoleErrorStub.called).to.be.true
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ import { workspaceResolver } from "@core/workspace"
|
||||
import { BooleanResponse, StringRequest } from "@shared/proto/cline/common"
|
||||
import { getWorkspacePath } from "@utils/path"
|
||||
import * as fs from "fs"
|
||||
import { Logger } from "@/shared/services/Logger"
|
||||
import { Controller } from ".."
|
||||
|
||||
/**
|
||||
@@ -16,7 +15,6 @@ export async function ifFileExistsRelativePath(_controller: Controller, request:
|
||||
|
||||
if (!workspacePath) {
|
||||
// If no workspace is open, return false
|
||||
Logger.error("Error in ifFileExistsRelativePath: No workspace path available") // TODO
|
||||
return BooleanResponse.create({ value: false })
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,6 @@ export class GrpcRequestRegistry {
|
||||
timestamp: new Date(),
|
||||
responseStream,
|
||||
})
|
||||
Logger.log(`[DEBUG] Registered request: ${requestId}`)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,9 +69,8 @@ export class GrpcRequestRegistry {
|
||||
}
|
||||
try {
|
||||
requestInfo.cleanup()
|
||||
Logger.debug(`Cleaned up request: ${requestId}`)
|
||||
} catch (error) {
|
||||
Logger.debug(`Error cleaning up request ${requestId}:`, error)
|
||||
Logger.error(`Error cleaning up request ${requestId}:`, error)
|
||||
}
|
||||
this.activeRequests.delete(requestId)
|
||||
return true
|
||||
|
||||
@@ -242,7 +242,7 @@ export async function refreshOpenRouterModels(controller: Controller): Promise<R
|
||||
Logger.error("Invalid response from OpenRouter API")
|
||||
}
|
||||
await fs.writeFile(openRouterModelsFilePath, JSON.stringify(models))
|
||||
Logger.log("OpenRouter models fetched and saved", JSON.stringify(models).slice(0, 300))
|
||||
Logger.log("OpenRouter models fetched and saved")
|
||||
} catch (error) {
|
||||
Logger.error("Error fetching OpenRouter models:", error)
|
||||
|
||||
|
||||
@@ -20,15 +20,12 @@ export async function subscribeToOpenRouterModels(
|
||||
responseStream: StreamingResponseHandler<OpenRouterCompatibleModelInfo>,
|
||||
requestId?: string,
|
||||
): Promise<void> {
|
||||
Logger.log("[DEBUG] set up OpenRouter models subscription")
|
||||
|
||||
// Add this subscription to the active subscriptions
|
||||
activeOpenRouterModelsSubscriptions.add(responseStream)
|
||||
|
||||
// Register cleanup when the connection is closed
|
||||
const cleanup = () => {
|
||||
activeOpenRouterModelsSubscriptions.delete(responseStream)
|
||||
Logger.log("[DEBUG] Cleaned up OpenRouter models subscription")
|
||||
}
|
||||
|
||||
// Register the cleanup function with the request registry if we have a requestId
|
||||
|
||||
@@ -27,7 +27,6 @@ export async function subscribeToState(
|
||||
// Register cleanup when the connection is closed
|
||||
const cleanup = () => {
|
||||
activeStateSubscriptions.delete(responseStream)
|
||||
//Logger.log(`[DEBUG] Cleaned up state subscription`)
|
||||
}
|
||||
|
||||
// Register the cleanup function with the request registry if we have a requestId
|
||||
@@ -39,8 +38,6 @@ export async function subscribeToState(
|
||||
const initialState = await controller.getStateToPostToWebview()
|
||||
const initialStateJson = JSON.stringify(initialState)
|
||||
|
||||
//Logger.log(`[DEBUG] set up state subscription`)
|
||||
|
||||
try {
|
||||
await responseStream(
|
||||
{
|
||||
@@ -69,7 +66,6 @@ export async function sendStateUpdate(state: ExtensionState): Promise<void> {
|
||||
},
|
||||
false, // Not the last message
|
||||
)
|
||||
//Logger.log(`[DEBUG] sending followup state`, stateJson.length, "chars")
|
||||
} catch (error) {
|
||||
Logger.error("Error sending state update:", error)
|
||||
// Remove the subscription if there was an error
|
||||
|
||||
@@ -19,8 +19,6 @@ export async function subscribeToAccountButtonClicked(
|
||||
responseStream: StreamingResponseHandler<Empty>,
|
||||
requestId?: string,
|
||||
): Promise<void> {
|
||||
Logger.log(`[DEBUG] set up accountButtonClicked subscription`)
|
||||
|
||||
// Add this subscription to the active subscriptions
|
||||
activeAccountButtonClickedSubscriptions.add(responseStream)
|
||||
|
||||
|
||||
@@ -19,15 +19,12 @@ export async function subscribeToAddToInput(
|
||||
responseStream: StreamingResponseHandler<ProtoString>,
|
||||
requestId?: string,
|
||||
): Promise<void> {
|
||||
Logger.log("[DEBUG] set up addToInput subscription")
|
||||
|
||||
// Add this subscription to the active subscriptions
|
||||
activeAddToInputSubscriptions.add(responseStream)
|
||||
|
||||
// Register cleanup when the connection is closed
|
||||
const cleanup = () => {
|
||||
activeAddToInputSubscriptions.delete(responseStream)
|
||||
Logger.log("[DEBUG] Cleaned up addToInput subscription")
|
||||
}
|
||||
|
||||
// Register the cleanup function with the request registry if we have a requestId
|
||||
@@ -51,7 +48,6 @@ export async function sendAddToInputEvent(text: string): Promise<void> {
|
||||
event,
|
||||
false, // Not the last message
|
||||
)
|
||||
Logger.log("[DEBUG] sending addToInput event", text.length, "chars")
|
||||
} catch (error) {
|
||||
Logger.error("Error sending addToInput event:", error)
|
||||
// Remove the subscription if there was an error
|
||||
|
||||
@@ -19,8 +19,6 @@ export async function subscribeToChatButtonClicked(
|
||||
responseStream: StreamingResponseHandler<Empty>,
|
||||
requestId?: string,
|
||||
): Promise<void> {
|
||||
Logger.log(`[DEBUG] set up chatButtonClicked subscription`)
|
||||
|
||||
// Add this subscription to the active subscriptions
|
||||
activeChatButtonClickedSubscriptions.add(responseStream)
|
||||
|
||||
|
||||
@@ -19,8 +19,6 @@ export async function subscribeToMcpButtonClicked(
|
||||
responseStream: StreamingResponseHandler<Empty>,
|
||||
requestId?: string,
|
||||
): Promise<void> {
|
||||
Logger.log(`[DEBUG] set up mcpButtonClicked subscription`)
|
||||
|
||||
// Add this subscription to the active subscriptions
|
||||
activeMcpButtonClickedSubscriptions.add(responseStream)
|
||||
|
||||
|
||||
@@ -79,8 +79,10 @@ async function extractTextFromIPYNB(filePath: string): Promise<string> {
|
||||
const encoding = await detectEncoding(fileBuffer)
|
||||
const data = iconv.decode(fileBuffer, encoding)
|
||||
|
||||
// Return sanitized JSON for proper editing (enhanced notebook behavior is now always enabled)
|
||||
return sanitizeNotebookForLLM(data)
|
||||
// Strip all outputs to reduce context size - outputs aren't needed for understanding
|
||||
// notebook structure. For Jupyter commands, the specific cell's outputs are included
|
||||
// separately via sanitizeCellForLLM which preserves text outputs.
|
||||
return sanitizeNotebookForLLM(data, true)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -60,7 +60,6 @@ export class AudioRecordingService {
|
||||
return
|
||||
}
|
||||
|
||||
Logger.info("Terminating recording process...")
|
||||
this.recordingProcess.kill("SIGINT")
|
||||
|
||||
// Wait for the process to finish with timeout
|
||||
|
||||
@@ -125,9 +125,6 @@ class ClineTempManagerImpl {
|
||||
await fs.promises.unlink(fileInfo.path)
|
||||
deletedCount++
|
||||
freedBytes += fileInfo.size
|
||||
Logger.info(
|
||||
`Cleaned up old temp file: ${path.basename(fileInfo.path)} (age: ${Math.round(age / 3600000)}h)`,
|
||||
)
|
||||
} catch {
|
||||
// File might have been deleted by another process
|
||||
}
|
||||
@@ -150,9 +147,6 @@ class ClineTempManagerImpl {
|
||||
totalSize -= fileInfo.size
|
||||
deletedCount++
|
||||
freedBytes += fileInfo.size
|
||||
Logger.info(
|
||||
`Cleaned up temp file for space: ${path.basename(fileInfo.path)} (${Math.round(fileInfo.size / 1024)}KB)`,
|
||||
)
|
||||
} catch {
|
||||
// File might have been deleted by another process
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ export const DEFAULT_BROWSER_SETTINGS: BrowserSettings = {
|
||||
remoteBrowserHost: "http://localhost:9222",
|
||||
chromeExecutablePath: "", // Changed from undefined to empty string
|
||||
// chromeType: "chromium",
|
||||
disableToolUse: false,
|
||||
disableToolUse: true,
|
||||
customArgs: "",
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -352,7 +352,7 @@ export const claudeCodeModels = {
|
||||
// AWS Bedrock
|
||||
// https://docs.aws.amazon.com/bedrock/latest/userguide/conversation-inference.html
|
||||
export type BedrockModelId = keyof typeof bedrockModels
|
||||
export const bedrockDefaultModelId: BedrockModelId = "anthropic.claude-sonnet-4-20250514-v1:0" // TODO: update to 4-5
|
||||
export const bedrockDefaultModelId: BedrockModelId = "anthropic.claude-sonnet-4-5-20250929-v1:0"
|
||||
export const bedrockModels = {
|
||||
"anthropic.claude-sonnet-4-5-20250929-v1:0": {
|
||||
maxTokens: 8192,
|
||||
@@ -385,6 +385,7 @@ export const bedrockModels = {
|
||||
supportsImages: true,
|
||||
supportsPromptCache: true,
|
||||
supportsReasoning: true,
|
||||
supportsGlobalEndpoint: true,
|
||||
inputPrice: 1,
|
||||
outputPrice: 5.0,
|
||||
cacheWritesPrice: 1.25,
|
||||
@@ -3333,6 +3334,7 @@ export const cerebrasModels = {
|
||||
contextWindow: 131072,
|
||||
supportsImages: false,
|
||||
supportsPromptCache: false,
|
||||
temperature: 0.9,
|
||||
inputPrice: 0,
|
||||
outputPrice: 0,
|
||||
description:
|
||||
|
||||
@@ -114,7 +114,7 @@ export const WhatsNewModal: React.FC<WhatsNewModalProps> = ({ open, onClose, ver
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<strong>Grok Code Fast 1: </strong> is saying goodbye (to free) this Friday at 11:00 am PT.
|
||||
<strong>Grok Code Fast 1: </strong> is no longer free to use.
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -80,11 +80,6 @@ export const freeModels = [
|
||||
description: "KwaiKAT's most advanced agentic coding model in the KAT-Coder series",
|
||||
label: "FREE",
|
||||
},
|
||||
{
|
||||
id: "x-ai/grok-code-fast-1",
|
||||
description: "Fast inference with strong coding performance",
|
||||
label: "FREE",
|
||||
},
|
||||
{
|
||||
id: "mistralai/devstral-2512:free",
|
||||
description: "Mistral's latest model with strong coding abilities",
|
||||
|
||||
Reference in New Issue
Block a user