checkpointDiff --> protobuf (#2980)

* Checkpoints diff protobuf

* Requested changes to checkpointDiff protobuf
This commit is contained in:
canvrno 2025-04-19 17:21:10 -07:00 committed by GitHub
parent ba6dcb5bc9
commit 0d38381573
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 112 additions and 29 deletions

View File

@ -93,6 +93,7 @@ async function generateMethodRegistrations() {
const serviceDirs = [ const serviceDirs = [
path.join(ROOT_DIR, "src", "core", "controller", "browser"), path.join(ROOT_DIR, "src", "core", "controller", "browser"),
path.join(ROOT_DIR, "src", "core", "controller", "checkpoints"),
// Add more service directories here as needed // Add more service directories here as needed
] ]

10
proto/checkpoints.proto Normal file
View File

@ -0,0 +1,10 @@
syntax = "proto3";
package cline;
import "common.proto";
service CheckpointsService {
rpc checkpointDiff(Int64Request) returns (Empty);
}

View File

@ -0,0 +1,9 @@
import { Controller } from ".."
import { Empty, Int64Request } from "../../../shared/proto/common"
export async function checkpointDiff(controller: Controller, request: Int64Request): Promise<Empty> {
if (request.value) {
await controller.task?.presentMultifileDiff(request.value, false)
}
return Empty
}

View File

@ -0,0 +1,15 @@
import { createServiceRegistry, ServiceMethodHandler } from "../grpc-service"
import { registerAllMethods } from "./methods"
// Create checkpoints service registry
const checkpointsService = createServiceRegistry("checkpoints")
// Export the method handler type and registration function
export type CheckpointsMethodHandler = ServiceMethodHandler
export const registerMethod = checkpointsService.registerMethod
// Export the request handler
export const handleCheckpointsDiffServiceRequest = checkpointsService.handleRequest
// Register all checkpoints methods
registerAllMethods()

View File

@ -0,0 +1,12 @@
// AUTO-GENERATED FILE - DO NOT MODIFY DIRECTLY
// Generated by proto/build-proto.js
// Import all method implementations
import { registerMethod } from "./index"
import { checkpointDiff } from "./checkpointDiff"
// Register all checkpoints service methods
export function registerAllMethods(): void {
// Register each method with the registry
registerMethod("checkpointDiff", checkpointDiff)
}

View File

@ -1,6 +1,7 @@
import { Controller } from "./index" import { Controller } from "./index"
import { handleBrowserServiceRequest } from "./browser/index" import { handleBrowserServiceRequest } from "./browser/index"
import { ExtensionMessage } from "../../shared/ExtensionMessage" import { ExtensionMessage } from "../../shared/ExtensionMessage"
import { handleCheckpointsDiffServiceRequest } from "./checkpoints"
/** /**
* Handles gRPC requests from the webview * Handles gRPC requests from the webview
@ -27,15 +28,20 @@ export class GrpcHandler {
request_id: string request_id: string
}> { }> {
try { try {
// Handle BrowserService requests switch (service) {
if (service === "cline.BrowserService") { case "cline.BrowserService":
return { return {
message: await handleBrowserServiceRequest(this.controller, method, message), message: await handleBrowserServiceRequest(this.controller, method, message),
request_id: requestId, request_id: requestId,
} }
case "cline.CheckpointsService":
return {
message: await handleCheckpointsDiffServiceRequest(this.controller, method, message),
request_id: requestId,
} }
default:
throw new Error(`Unknown service: ${service}`) throw new Error(`Unknown service: ${service}`)
}
} catch (error) { } catch (error) {
return { return {
error: error instanceof Error ? error.message : String(error), error: error instanceof Error ? error.message : String(error),

View File

@ -483,12 +483,6 @@ export class Controller {
case "openMention": case "openMention":
openMention(message.text) openMention(message.text)
break break
case "checkpointDiff": {
if (message.number) {
await this.task?.presentMultifileDiff(message.number, false)
}
break
}
case "checkpointRestore": { case "checkpointRestore": {
await this.cancelTask() // we cannot alter message history say if the task is active, as it could be in the middle of editing a file or running a command, which expect the ask to be responded to rather than being superseded by a new message eg add deleted_api_reqs await this.cancelTask() // we cannot alter message history say if the task is active, as it could be in the middle of editing a file or running a command, which expect the ask to be responded to rather than being superseded by a new message eg add deleted_api_reqs
// cancel task waits for any open editor to be reverted and starts a new cline instance // cancel task waits for any open editor to be reverted and starts a new cline instance

View File

@ -43,7 +43,6 @@ export interface WebviewMessage {
| "discoverBrowser" | "discoverBrowser"
| "browserRelaunchResult" | "browserRelaunchResult"
| "togglePlanActMode" | "togglePlanActMode"
| "checkpointDiff"
| "checkpointRestore" | "checkpointRestore"
| "taskCompletionViewChanges" | "taskCompletionViewChanges"
| "openExtensionSettings" | "openExtensionSettings"

View File

@ -0,0 +1,26 @@
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
// versions:
// protoc-gen-ts_proto v2.7.0
// protoc v6.30.1
// source: checkpoints.proto
/* eslint-disable */
import { Empty, Int64Request } from "./common"
export const protobufPackage = "cline"
export type CheckpointsServiceDefinition = typeof CheckpointsServiceDefinition
export const CheckpointsServiceDefinition = {
name: "CheckpointsService",
fullName: "cline.CheckpointsService",
methods: {
checkpointDiff: {
name: "checkpointDiff",
requestType: Int64Request,
requestStream: false,
responseType: Empty,
responseStream: false,
options: {},
},
},
} as const

View File

@ -2,6 +2,7 @@ import { useCallback, useRef, useState, useEffect } from "react"
import { useEvent } from "react-use" import { useEvent } from "react-use"
import styled from "styled-components" import styled from "styled-components"
import { ExtensionMessage } from "@shared/ExtensionMessage" import { ExtensionMessage } from "@shared/ExtensionMessage"
import { CheckpointsServiceClient } from "@/services/grpc-client"
import { vscode } from "@/utils/vscode" import { vscode } from "@/utils/vscode"
import { CODE_BLOCK_BG_COLOR } from "@/components/common/CodeBlock" import { CODE_BLOCK_BG_COLOR } from "@/components/common/CodeBlock"
import { VSCodeButton } from "@vscode/webview-ui-toolkit/react" import { VSCodeButton } from "@vscode/webview-ui-toolkit/react"
@ -138,12 +139,17 @@ export const CheckmarkControl = ({ messageTs, isCheckpointCheckedOut }: Checkmar
$isCheckedOut={isCheckpointCheckedOut} $isCheckedOut={isCheckpointCheckedOut}
disabled={compareDisabled} disabled={compareDisabled}
style={{ cursor: compareDisabled ? "wait" : "pointer" }} style={{ cursor: compareDisabled ? "wait" : "pointer" }}
onClick={() => { onClick={async () => {
setCompareDisabled(true) setCompareDisabled(true)
vscode.postMessage({ try {
type: "checkpointDiff", await CheckpointsServiceClient.checkpointDiff({
number: messageTs, value: messageTs,
}) })
} catch (err) {
console.error("CheckpointDiff error:", err)
} finally {
setCompareDisabled(false)
}
}}> }}>
Compare Compare
</CustomButton> </CustomButton>

View File

@ -3,6 +3,7 @@ import { useCallback, useRef, useState } from "react"
import { useClickAway, useEvent } from "react-use" import { useClickAway, useEvent } from "react-use"
import styled from "styled-components" import styled from "styled-components"
import { ExtensionMessage } from "@shared/ExtensionMessage" import { ExtensionMessage } from "@shared/ExtensionMessage"
import { CheckpointsServiceClient } from "@/services/grpc-client"
import { vscode } from "@/utils/vscode" import { vscode } from "@/utils/vscode"
import { CODE_BLOCK_BG_COLOR } from "@/components/common/CodeBlock" import { CODE_BLOCK_BG_COLOR } from "@/components/common/CodeBlock"
import { ClineCheckpointRestore } from "@shared/WebviewMessage" import { ClineCheckpointRestore } from "@shared/WebviewMessage"
@ -110,12 +111,17 @@ export const CheckpointOverlay = ({ messageTs }: CheckpointOverlayProps) => {
appearance="secondary" appearance="secondary"
disabled={compareDisabled} disabled={compareDisabled}
style={{ cursor: compareDisabled ? "wait" : "pointer" }} style={{ cursor: compareDisabled ? "wait" : "pointer" }}
onClick={() => { onClick={async () => {
setCompareDisabled(true) setCompareDisabled(true)
vscode.postMessage({ try {
type: "checkpointDiff", await CheckpointsServiceClient.checkpointDiff({
number: messageTs, value: messageTs,
}) })
} catch (err) {
console.error("CheckpointDiff error:", err)
} finally {
setCompareDisabled(false)
}
}}> }}>
<i className="codicon codicon-diff-multiple" style={{ position: "absolute" }} /> <i className="codicon codicon-diff-multiple" style={{ position: "absolute" }} />
</VSCodeButton> </VSCodeButton>

View File

@ -1,6 +1,7 @@
import { vscode } from "../utils/vscode" import { vscode } from "../utils/vscode"
import { v4 as uuidv4 } from "uuid" import { v4 as uuidv4 } from "uuid"
import { BrowserServiceDefinition } from "@shared/proto/browser" import { BrowserServiceDefinition } from "@shared/proto/browser"
import { CheckpointsServiceDefinition } from "@shared/proto/checkpoints"
import { EmptyRequest } from "@shared/proto/common" import { EmptyRequest } from "@shared/proto/common"
// Generic type for any protobuf service definition // Generic type for any protobuf service definition
@ -92,9 +93,7 @@ function createGrpcClient<T extends ProtoService>(service: T): GrpcClientType<T>
return client return client
} }
// Create the Browser Service Client singleton with inferred types
// No need for manual interface definition - types are inferred from the service definition
const BrowserServiceClient = createGrpcClient(BrowserServiceDefinition) const BrowserServiceClient = createGrpcClient(BrowserServiceDefinition)
const CheckpointsServiceClient = createGrpcClient(CheckpointsServiceDefinition)
// Export the Browser Service Client as a static object export { BrowserServiceClient, CheckpointsServiceClient }
export { BrowserServiceClient }