Compare commits

...

2 Commits

Author SHA1 Message Date
abeatrix 4e7fb67e98 Add encodeRequest helper to grpc-client-base
This commit introduces an `encodeRequest` helper function to `grpc-client-base.ts`. This function handles the encoding of request objects before they are sent via gRPC. It checks for null/undefined requests, `toJSON` methods, and object types, providing appropriate encoding for each case. This ensures that requests are properly formatted for the gRPC service. The `encodeRequest` function is used in `makeRequest` and other methods.
2025-07-21 21:14:06 -07:00
Sarah Fortune f0b56edbb6 Remove compiled files that were committed by mistake.
Update the protobus script to use the correct service name.
Until now the webview was using `webview-ui/src/services/grpc-client.js` which was not getting updated when
`webview-ui/src/services/grpc-client.ts` was changed.

Add compiled files to the gitignore.
2025-07-21 19:49:20 -07:00
9 changed files with 21 additions and 242 deletions
+3
View File
@@ -15,6 +15,9 @@ pnpm-lock.yaml
.venv
.actrc
webview-ui/src/**/*.js
webview-ui/src/**/*.js.map
# Ignore coverage directories and files
coverage
# But don't ignore the coverage scripts in .github/scripts/
+1 -1
View File
@@ -49,7 +49,7 @@ async function generateWebviewProtobusClients(protobusServices) {
}
}
clients.push(`export class ${serviceName}Client extends ProtoBusClient {
static override serviceName: string = "${serviceName}"
static override serviceName: string = "cline.${serviceName}"
${rpcs.join("\n")}
}`)
}
-126
View File
@@ -1,126 +0,0 @@
import { vscode } from "../utils/vscode"
import { v4 as uuidv4 } from "uuid"
/**
* Helper function to encode request objects
*/
function encodeRequest(request) {
if (request === null || request === undefined) {
return {}
} else if (typeof request.toJSON === "function") {
return request.toJSON()
} else if (typeof request === "object") {
return { ...request }
} else {
return { value: request }
}
}
// Create a client for any protobuf service with inferred types
export function createGrpcClient(service) {
const client = {}
// For each method in the service
Object.values(service.methods).forEach((method) => {
if (method.responseStream) {
// Streaming method implementation
client[method.name] = (request, options) => {
const requestId = uuidv4()
// Set up listener for streaming responses
const handleResponse = (event) => {
const message = event.data
if (message.type === "grpc_response" && message.grpc_response?.request_id === requestId) {
if (message.grpc_response.error) {
// Handle error
if (options.onError) {
options.onError(new Error(message.grpc_response.error))
}
// Only remove the event listener on error
window.removeEventListener("message", handleResponse)
} else if (message.grpc_response.is_streaming === false) {
// End of stream
if (message.grpc_response.message) {
// Process final message if present
const responseType = method.responseType
const response = responseType.fromJSON(message.grpc_response.message)
options.onResponse(response)
}
if (options.onComplete) {
options.onComplete()
}
// Only remove the event listener when the stream is explicitly ended
window.removeEventListener("message", handleResponse)
} else {
// Process streaming message
if (message.grpc_response.message) {
const responseType = method.responseType
const response = responseType.fromJSON(message.grpc_response.message)
options.onResponse(response)
}
}
}
}
window.addEventListener("message", handleResponse)
// Send the streaming request
const encodedRequest = encodeRequest(request)
vscode.postMessage({
type: "grpc_request",
grpc_request: {
service: service.fullName,
method: method.name,
message: encodedRequest,
request_id: requestId,
is_streaming: true,
},
})
// Return a function to cancel the stream
return () => {
window.removeEventListener("message", handleResponse)
// Send cancellation message
vscode.postMessage({
type: "grpc_request_cancel",
grpc_request_cancel: {
request_id: requestId,
},
})
console.log(`[DEBUG] Sent cancellation for request: ${requestId}`)
}
}
} else {
// Unary method implementation
client[method.name] = (request) => {
return new Promise((resolve, reject) => {
const requestId = uuidv4()
// Set up one-time listener for this specific request
const handleResponse = (event) => {
const message = event.data
if (message.type === "grpc_response" && message.grpc_response?.request_id === requestId) {
// Remove listener once we get our response
window.removeEventListener("message", handleResponse)
if (message.grpc_response.error) {
reject(new Error(message.grpc_response.error))
} else {
// Convert JSON back to protobuf message
const responseType = method.responseType
const response = responseType.fromJSON(message.grpc_response.message)
resolve(response)
}
}
}
window.addEventListener("message", handleResponse)
// Send the request
const encodedRequest = encodeRequest(request)
vscode.postMessage({
type: "grpc_request",
grpc_request: {
service: service.fullName,
method: method.name,
message: encodedRequest,
request_id: requestId,
is_streaming: false,
},
})
})
}
}
})
return client
}
//# sourceMappingURL=grpc-client-base.js.map
@@ -1 +0,0 @@
{"version":3,"file":"grpc-client-base.js","sourceRoot":"","sources":["grpc-client-base.ts"],"names":[],"mappings":"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"}
+17 -2
View File
@@ -1,6 +1,21 @@
import { vscode } from "../utils/vscode"
import { v4 as uuidv4 } from "uuid"
/**
* Helper function to encode request objects
*/
function encodeRequest(request: any): unknown {
if (request === null || request === undefined) {
return {}
} else if (typeof request.toJSON === "function") {
return request.toJSON()
} else if (typeof request === "object") {
return { ...request }
} else {
return { value: request }
}
}
export interface Callbacks<TResponse> {
onResponse: (response: TResponse) => void
onError: (error: Error) => void
@@ -12,7 +27,7 @@ export abstract class ProtoBusClient {
static async makeRequest<TRequest, TResponse>(
methodName: string,
request: TRequest,
encodeRequest: (_: TRequest) => unknown,
_encodeRequest: (_: TRequest) => unknown,
decodeResponse: (_: unknown) => TResponse,
): Promise<TResponse> {
return new Promise((resolve, reject) => {
@@ -55,7 +70,7 @@ export abstract class ProtoBusClient {
methodName: string,
request: TRequest,
callbacks: Callbacks<TResponse>,
encodeRequest: (_: TRequest) => unknown,
_encodeRequest: (_: TRequest) => unknown,
decodeResponse: (_: unknown) => TResponse,
): () => void {
const requestId = uuidv4()
-39
View File
@@ -1,39 +0,0 @@
// AUTO-GENERATED FILE - DO NOT MODIFY DIRECTLY
// Generated by proto/build-proto.js
import { createGrpcClient } from "./grpc-client-base"
import { AccountServiceDefinition } from "@shared/proto/account"
import { BrowserServiceDefinition } from "@shared/proto/browser"
import { CheckpointsServiceDefinition } from "@shared/proto/checkpoints"
import { FileServiceDefinition } from "@shared/proto/file"
import { McpServiceDefinition } from "@shared/proto/mcp"
import { StateServiceDefinition } from "@shared/proto/state"
import { TaskServiceDefinition } from "@shared/proto/task"
import { WebServiceDefinition } from "@shared/proto/web"
import { ModelsServiceDefinition } from "@shared/proto/models"
import { SlashServiceDefinition } from "@shared/proto/slash"
import { UiServiceDefinition } from "@shared/proto/ui"
const AccountServiceClient = createGrpcClient(AccountServiceDefinition)
const BrowserServiceClient = createGrpcClient(BrowserServiceDefinition)
const CheckpointsServiceClient = createGrpcClient(CheckpointsServiceDefinition)
const FileServiceClient = createGrpcClient(FileServiceDefinition)
const McpServiceClient = createGrpcClient(McpServiceDefinition)
const StateServiceClient = createGrpcClient(StateServiceDefinition)
const TaskServiceClient = createGrpcClient(TaskServiceDefinition)
const WebServiceClient = createGrpcClient(WebServiceDefinition)
const ModelsServiceClient = createGrpcClient(ModelsServiceDefinition)
const SlashServiceClient = createGrpcClient(SlashServiceDefinition)
const UiServiceClient = createGrpcClient(UiServiceDefinition)
export {
AccountServiceClient,
BrowserServiceClient,
CheckpointsServiceClient,
FileServiceClient,
McpServiceClient,
StateServiceClient,
TaskServiceClient,
WebServiceClient,
ModelsServiceClient,
SlashServiceClient,
UiServiceClient,
}
//# sourceMappingURL=grpc-client.js.map
@@ -1 +0,0 @@
{"version":3,"file":"grpc-client.js","sourceRoot":"","sources":["grpc-client.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,oCAAoC;AAEpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AACrD,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAA;AAChE,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAA;AAChE,OAAO,EAAE,4BAA4B,EAAE,MAAM,2BAA2B,CAAA;AACxE,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAA;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AACxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AAC5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAA;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AACxD,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAA;AAC9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AAEtD,MAAM,oBAAoB,GAAG,gBAAgB,CAAC,wBAAwB,CAAC,CAAA;AACvE,MAAM,oBAAoB,GAAG,gBAAgB,CAAC,wBAAwB,CAAC,CAAA;AACvE,MAAM,wBAAwB,GAAG,gBAAgB,CAAC,4BAA4B,CAAC,CAAA;AAC/E,MAAM,iBAAiB,GAAG,gBAAgB,CAAC,qBAAqB,CAAC,CAAA;AACjE,MAAM,gBAAgB,GAAG,gBAAgB,CAAC,oBAAoB,CAAC,CAAA;AAC/D,MAAM,kBAAkB,GAAG,gBAAgB,CAAC,sBAAsB,CAAC,CAAA;AACnE,MAAM,iBAAiB,GAAG,gBAAgB,CAAC,qBAAqB,CAAC,CAAA;AACjE,MAAM,gBAAgB,GAAG,gBAAgB,CAAC,oBAAoB,CAAC,CAAA;AAC/D,MAAM,mBAAmB,GAAG,gBAAgB,CAAC,uBAAuB,CAAC,CAAA;AACrE,MAAM,kBAAkB,GAAG,gBAAgB,CAAC,sBAAsB,CAAC,CAAA;AACnE,MAAM,eAAe,GAAG,gBAAgB,CAAC,mBAAmB,CAAC,CAAA;AAE7D,OAAO,EACN,oBAAoB,EACpB,oBAAoB,EACpB,wBAAwB,EACxB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,CAAA"}
-71
View File
@@ -1,71 +0,0 @@
class VSCodeAPIWrapper {
vsCodeApi
constructor() {
// Check if the acquireVsCodeApi function exists in the current development
// context (i.e. VS Code development window or web browser)
if (typeof acquireVsCodeApi === "function") {
this.vsCodeApi = acquireVsCodeApi()
}
}
/**
* Post a message (i.e. send arbitrary data) to the owner of the webview.
*
* @remarks When running webview code inside a web browser, postMessage will instead
* log the given message to the console.
*
* @param message Arbitrary data (must be JSON serializable) to send to the extension context.
*/
postMessage(message) {
if (this.vsCodeApi) {
this.vsCodeApi.postMessage(message)
} else if (window.__is_standalone__) {
if (!window.standalonePostMessage) {
console.warn("Standalone postMessage not found.")
return
}
const json = JSON.stringify(message)
console.log("Standalone postMessage: " + json.slice(0, 200))
window.standalonePostMessage(json)
} else {
console.log("postMessage fallback: ", message)
}
}
/**
* Get the persistent state stored for this webview.
*
* @remarks When running webview source code inside a web browser, getState will retrieve state
* from local storage (https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage).
*
* @return The current state or `undefined` if no state has been set.
*/
getState() {
if (this.vsCodeApi) {
return this.vsCodeApi.getState()
} else {
const state = localStorage.getItem("vscodeState")
return state ? JSON.parse(state) : undefined
}
}
/**
* Set the persistent state stored for this webview.
*
* @remarks When running webview source code inside a web browser, setState will set the given
* state using local storage (https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage).
*
* @param newState New persisted state. This must be a JSON serializable object. Can be retrieved
* using {@link getState}.
*
* @return The new state.
*/
setState(newState) {
if (this.vsCodeApi) {
return this.vsCodeApi.setState(newState)
} else {
localStorage.setItem("vscodeState", JSON.stringify(newState))
return newState
}
}
}
// Exports class singleton to prevent multiple invocations of acquireVsCodeApi.
export const vscode = new VSCodeAPIWrapper()
//# sourceMappingURL=vscode.js.map
-1
View File
@@ -1 +0,0 @@
{"version":3,"file":"vscode.js","sourceRoot":"","sources":["vscode.ts"],"names":[],"mappings":"AAmBA,MAAM,gBAAgB;IACJ,SAAS,CAAiC;IAE3D;QACC,2EAA2E;QAC3E,2DAA2D;QAC3D,IAAI,OAAO,gBAAgB,KAAK,UAAU,EAAE,CAAC;YAC5C,IAAI,CAAC,SAAS,GAAG,gBAAgB,EAAE,CAAA;QACpC,CAAC;IACF,CAAC;IAED;;;;;;;OAOG;IACI,WAAW,CAAC,OAAuB;QACzC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,OAAO,CAAC,CAAA;QACpC,CAAC;aAAM,IAAI,MAAM,CAAC,iBAAiB,EAAE,CAAC;YACrC,IAAI,CAAC,MAAM,CAAC,qBAAqB,EAAE,CAAC;gBACnC,OAAO,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAA;gBACjD,OAAM;YACP,CAAC;YACD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;YACpC,OAAO,CAAC,GAAG,CAAC,0BAA0B,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAA;YAC5D,MAAM,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAA;QACnC,CAAC;aAAM,CAAC;YACP,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,OAAO,CAAC,CAAA;QAC/C,CAAC;IACF,CAAC;IAED;;;;;;;OAOG;IACI,QAAQ;QACd,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAA;QACjC,CAAC;aAAM,CAAC;YACP,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,aAAa,CAAC,CAAA;YACjD,OAAO,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;QAC7C,CAAC;IACF,CAAC;IAED;;;;;;;;;;OAUG;IACI,QAAQ,CAAgC,QAAW;QACzD,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;QACzC,CAAC;aAAM,CAAC;YACP,YAAY,CAAC,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAA;YAC7D,OAAO,QAAQ,CAAA;QAChB,CAAC;IACF,CAAC;CACD;AAED,+EAA+E;AAC/E,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,gBAAgB,EAAE,CAAA"}