Compare commits

...

2 Commits

Author SHA1 Message Date
Elephant Lumps a5e90c2ab3 changeset 2025-05-20 14:33:07 -07:00
Elephant Lumps efcd9601a6 migrate toggleCursorRule 2025-05-20 14:32:34 -07:00
10 changed files with 181 additions and 16 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"claude-dev": minor
---
Migrate toggleCursorRule to protobus
+10
View File
@@ -37,6 +37,9 @@ service FileService {
// Toggle a Cline rule (enable or disable)
rpc toggleClineRule(ToggleClineRuleRequest) returns (ToggleClineRules);
// Toggle a Cursor rule (enable or disable)
rpc toggleCursorRule(ToggleCursorRuleRequest) returns (ClineRulesToggles);
}
// Request to convert a list of URIs to relative paths
@@ -119,3 +122,10 @@ message ToggleClineRules {
ClineRulesToggles global_cline_rules_toggles = 1;
ClineRulesToggles local_cline_rules_toggles = 2;
}
// Request to toggle a Cursor rule
message ToggleCursorRuleRequest {
Metadata metadata = 1;
string rule_path = 2; // Path to the rule file
bool enabled = 3; // Whether to enable or disable the rule
}
+2
View File
@@ -13,6 +13,7 @@ import { searchCommits } from "./searchCommits"
import { searchFiles } from "./searchFiles"
import { selectImages } from "./selectImages"
import { toggleClineRule } from "./toggleClineRule"
import { toggleCursorRule } from "./toggleCursorRule"
// Register all file service methods
export function registerAllMethods(): void {
@@ -27,4 +28,5 @@ export function registerAllMethods(): void {
registerMethod("searchFiles", searchFiles)
registerMethod("selectImages", selectImages)
registerMethod("toggleClineRule", toggleClineRule)
registerMethod("toggleCursorRule", toggleCursorRule)
}
@@ -0,0 +1,34 @@
import type { ToggleCursorRuleRequest, ClineRulesToggles } from "../../../shared/proto/file"
import type { Controller } from "../index"
import { getWorkspaceState, updateWorkspaceState } from "../../../core/storage/state"
import { ClineRulesToggles as AppClineRulesToggles } from "@shared/cline-rules"
/**
* Toggles a Cursor rule (enable or disable)
* @param controller The controller instance
* @param request The toggle request
* @returns The updated Cursor rule toggles
*/
export async function toggleCursorRule(controller: Controller, request: ToggleCursorRuleRequest): Promise<ClineRulesToggles> {
const { rulePath, enabled } = request
if (!rulePath || typeof enabled !== "boolean") {
console.error("toggleCursorRule: Missing or invalid parameters", {
rulePath,
enabled: typeof enabled === "boolean" ? enabled : `Invalid: ${typeof enabled}`,
})
throw new Error("Missing or invalid parameters for toggleCursorRule")
}
// Update the toggles in workspace state
const toggles = ((await getWorkspaceState(controller.context, "localCursorRulesToggles")) as AppClineRulesToggles) || {}
toggles[rulePath] = enabled
await updateWorkspaceState(controller.context, "localCursorRulesToggles", toggles)
// Get the current state to return in the response
const cursorToggles = ((await getWorkspaceState(controller.context, "localCursorRulesToggles")) as AppClineRulesToggles) || {}
return {
toggles: cursorToggles,
}
}
-13
View File
@@ -422,19 +422,6 @@ export class Controller {
}
break
}
case "toggleCursorRule": {
const { rulePath, enabled } = message
if (rulePath && typeof enabled === "boolean") {
const toggles =
((await getWorkspaceState(this.context, "localCursorRulesToggles")) as ClineRulesToggles) || {}
toggles[rulePath] = enabled
await updateWorkspaceState(this.context, "localCursorRulesToggles", toggles)
await this.postStateToWebview()
} else {
console.error("toggleCursorRule: Missing or invalid parameters")
}
break
}
case "toggleWorkflow": {
const { workflowPath, enabled } = message
if (workflowPath && typeof enabled === "boolean") {
-1
View File
@@ -45,7 +45,6 @@ export interface WebviewMessage {
| "searchFiles"
| "grpc_request"
| "grpc_request_cancel"
| "toggleCursorRule"
| "toggleWindsurfRule"
| "toggleWorkflow"
| "updateTerminalConnectionTimeout"
+111
View File
@@ -114,6 +114,15 @@ export interface ToggleClineRules {
localClineRulesToggles?: ClineRulesToggles | undefined
}
/** Request to toggle a Cursor rule */
export interface ToggleCursorRuleRequest {
metadata?: Metadata | undefined
/** Path to the rule file */
rulePath: string
/** Whether to enable or disable the rule */
enabled: boolean
}
function createBaseRelativePathsRequest(): RelativePathsRequest {
return { metadata: undefined, uris: [] }
}
@@ -1277,6 +1286,99 @@ export const ToggleClineRules: MessageFns<ToggleClineRules> = {
},
}
function createBaseToggleCursorRuleRequest(): ToggleCursorRuleRequest {
return { metadata: undefined, rulePath: "", enabled: false }
}
export const ToggleCursorRuleRequest: MessageFns<ToggleCursorRuleRequest> = {
encode(message: ToggleCursorRuleRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
if (message.metadata !== undefined) {
Metadata.encode(message.metadata, writer.uint32(10).fork()).join()
}
if (message.rulePath !== "") {
writer.uint32(18).string(message.rulePath)
}
if (message.enabled !== false) {
writer.uint32(24).bool(message.enabled)
}
return writer
},
decode(input: BinaryReader | Uint8Array, length?: number): ToggleCursorRuleRequest {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input)
let end = length === undefined ? reader.len : reader.pos + length
const message = createBaseToggleCursorRuleRequest()
while (reader.pos < end) {
const tag = reader.uint32()
switch (tag >>> 3) {
case 1: {
if (tag !== 10) {
break
}
message.metadata = Metadata.decode(reader, reader.uint32())
continue
}
case 2: {
if (tag !== 18) {
break
}
message.rulePath = reader.string()
continue
}
case 3: {
if (tag !== 24) {
break
}
message.enabled = reader.bool()
continue
}
}
if ((tag & 7) === 4 || tag === 0) {
break
}
reader.skip(tag & 7)
}
return message
},
fromJSON(object: any): ToggleCursorRuleRequest {
return {
metadata: isSet(object.metadata) ? Metadata.fromJSON(object.metadata) : undefined,
rulePath: isSet(object.rulePath) ? globalThis.String(object.rulePath) : "",
enabled: isSet(object.enabled) ? globalThis.Boolean(object.enabled) : false,
}
},
toJSON(message: ToggleCursorRuleRequest): unknown {
const obj: any = {}
if (message.metadata !== undefined) {
obj.metadata = Metadata.toJSON(message.metadata)
}
if (message.rulePath !== "") {
obj.rulePath = message.rulePath
}
if (message.enabled !== false) {
obj.enabled = message.enabled
}
return obj
},
create<I extends Exact<DeepPartial<ToggleCursorRuleRequest>, I>>(base?: I): ToggleCursorRuleRequest {
return ToggleCursorRuleRequest.fromPartial(base ?? ({} as any))
},
fromPartial<I extends Exact<DeepPartial<ToggleCursorRuleRequest>, I>>(object: I): ToggleCursorRuleRequest {
const message = createBaseToggleCursorRuleRequest()
message.metadata =
object.metadata !== undefined && object.metadata !== null ? Metadata.fromPartial(object.metadata) : undefined
message.rulePath = object.rulePath ?? ""
message.enabled = object.enabled ?? false
return message
},
}
/** Service for file-related operations */
export type FileServiceDefinition = typeof FileServiceDefinition
export const FileServiceDefinition = {
@@ -1373,6 +1475,15 @@ export const FileServiceDefinition = {
responseStream: false,
options: {},
},
/** Toggle a Cursor rule (enable or disable) */
toggleCursorRule: {
name: "toggleCursorRule",
requestType: ToggleCursorRuleRequest,
requestStream: false,
responseType: ClineRulesToggles,
responseStream: false,
options: {},
},
},
} as const
+2
View File
@@ -30,6 +30,7 @@ import { selectImages } from "../core/controller/file/selectImages"
import { getRelativePaths } from "../core/controller/file/getRelativePaths"
import { searchFiles } from "../core/controller/file/searchFiles"
import { toggleClineRule } from "../core/controller/file/toggleClineRule"
import { toggleCursorRule } from "../core/controller/file/toggleCursorRule"
// Mcp Service
import { toggleMcpServer } from "../core/controller/mcp/toggleMcpServer"
@@ -116,6 +117,7 @@ export function addServices(
getRelativePaths: wrapper(getRelativePaths, controller),
searchFiles: wrapper(searchFiles, controller),
toggleClineRule: wrapper(toggleClineRule, controller),
toggleCursorRule: wrapper(toggleCursorRule, controller),
})
// Mcp Service
@@ -18,6 +18,7 @@ const ClineRulesToggleModal: React.FC = () => {
workflowToggles = {},
setGlobalClineRulesToggles,
setLocalClineRulesToggles,
setLocalCursorRulesToggles,
} = useExtensionState()
const [isVisible, setIsVisible] = useState(false)
const buttonRef = useRef<HTMLDivElement>(null)
@@ -77,11 +78,19 @@ const ClineRulesToggleModal: React.FC = () => {
}
const toggleCursorRule = (rulePath: string, enabled: boolean) => {
vscode.postMessage({
type: "toggleCursorRule",
FileServiceClient.toggleCursorRule({
rulePath,
enabled,
})
.then((response) => {
// Update the local state with the response
if (response.toggles) {
setLocalCursorRulesToggles(response.toggles)
}
})
.catch((error) => {
console.error("Error toggling Cursor rule:", error)
})
}
const toggleWindsurfRule = (rulePath: string, enabled: boolean) => {
@@ -53,6 +53,7 @@ interface ExtensionStateContextType extends ExtensionState {
setMcpServers: (value: McpServer[]) => void
setGlobalClineRulesToggles: (toggles: Record<string, boolean>) => void
setLocalClineRulesToggles: (toggles: Record<string, boolean>) => void
setLocalCursorRulesToggles: (toggles: Record<string, boolean>) => void
// Navigation state setters
setShowMcp: (value: boolean) => void
@@ -526,6 +527,11 @@ export const ExtensionStateContextProvider: React.FC<{
...prevState,
localClineRulesToggles: toggles,
})),
setLocalCursorRulesToggles: (toggles) =>
setState((prevState) => ({
...prevState,
localCursorRulesToggles: toggles,
})),
setMcpTab,
}