mirror of
https://github.com/cline/cline.git
synced 2026-10-30 18:12:49 +08:00
Add delete rule button (#2958)
* add a delete button to the cline rules modal * changeset
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"claude-dev": minor
|
||||
---
|
||||
|
||||
Add a delete button to the Cline Rules modal to delete rule files
|
||||
@@ -173,3 +173,49 @@ export async function refreshClineRulesToggles(
|
||||
localToggles: updatedLocalToggles,
|
||||
}
|
||||
}
|
||||
|
||||
export async function deleteRuleFile(
|
||||
context: vscode.ExtensionContext,
|
||||
rulePath: string,
|
||||
isGlobal: boolean,
|
||||
): Promise<{ success: boolean; message: string }> {
|
||||
try {
|
||||
// Check if file exists
|
||||
const fileExists = await fileExistsAtPath(rulePath)
|
||||
if (!fileExists) {
|
||||
return {
|
||||
success: false,
|
||||
message: `Rule file does not exist: ${rulePath}`,
|
||||
}
|
||||
}
|
||||
|
||||
// Delete the file from disk
|
||||
await fs.unlink(rulePath)
|
||||
|
||||
// Get the filename for messages
|
||||
const fileName = path.basename(rulePath)
|
||||
|
||||
// Update the appropriate toggles
|
||||
if (isGlobal) {
|
||||
const toggles = ((await getGlobalState(context, "globalClineRulesToggles")) as ClineRulesToggles) || {}
|
||||
delete toggles[rulePath]
|
||||
await updateGlobalState(context, "globalClineRulesToggles", toggles)
|
||||
} else {
|
||||
const toggles = ((await getWorkspaceState(context, "localClineRulesToggles")) as ClineRulesToggles) || {}
|
||||
delete toggles[rulePath]
|
||||
await updateWorkspaceState(context, "localClineRulesToggles", toggles)
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: `Rule file "${fileName}" deleted successfully`,
|
||||
}
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : String(error)
|
||||
console.error(`Error deleting rule file: ${errorMessage}`, error)
|
||||
return {
|
||||
success: false,
|
||||
message: `Failed to delete rule file.`,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ import {
|
||||
} from "../storage/state"
|
||||
import { Task, cwd } from "../task"
|
||||
import { ClineRulesToggles } from "../../shared/cline-rules"
|
||||
import { refreshClineRulesToggles } from "../context/instructions/user-instructions/cline-rules"
|
||||
import { deleteRuleFile, refreshClineRulesToggles } from "../context/instructions/user-instructions/cline-rules"
|
||||
|
||||
/*
|
||||
https://github.com/microsoft/vscode-webview-ui-toolkit-samples/blob/main/default/weather-webview/src/providers/WeatherViewProvider.ts
|
||||
@@ -634,6 +634,24 @@ export class Controller {
|
||||
}
|
||||
break
|
||||
}
|
||||
case "deleteClineRule": {
|
||||
const { isGlobal, rulePath } = message
|
||||
if (rulePath && typeof isGlobal === "boolean") {
|
||||
const result = await deleteRuleFile(this.context, rulePath, isGlobal)
|
||||
if (result.success) {
|
||||
await refreshClineRulesToggles(this.context, cwd)
|
||||
await this.postStateToWebview()
|
||||
} else {
|
||||
console.error("Failed to delete rule file:", result.message)
|
||||
}
|
||||
} else {
|
||||
console.error("deleteClineRule: Missing or invalid parameters", {
|
||||
rulePath,
|
||||
isGlobal: typeof isGlobal === "boolean" ? isGlobal : `Invalid: ${typeof isGlobal}`,
|
||||
})
|
||||
}
|
||||
break
|
||||
}
|
||||
case "requestTotalTasksSize": {
|
||||
this.refreshTotalTasksSize()
|
||||
break
|
||||
|
||||
@@ -82,6 +82,7 @@ export interface WebviewMessage {
|
||||
| "toggleFavoriteModel"
|
||||
| "grpc_request"
|
||||
| "toggleClineRule"
|
||||
| "deleteClineRule"
|
||||
|
||||
// | "relaunchChromeDebugMode"
|
||||
text?: string
|
||||
|
||||
@@ -111,6 +111,7 @@ const ClineRulesToggleModal: React.FC = () => {
|
||||
<RulesToggleList
|
||||
rules={globalRules}
|
||||
toggleRule={(rulePath, enabled) => toggleRule(true, rulePath, enabled)}
|
||||
isGlobal={true}
|
||||
listGap="small"
|
||||
/>
|
||||
</div>
|
||||
@@ -121,6 +122,7 @@ const ClineRulesToggleModal: React.FC = () => {
|
||||
<RulesToggleList
|
||||
rules={localRules}
|
||||
toggleRule={(rulePath, enabled) => toggleRule(false, rulePath, enabled)}
|
||||
isGlobal={false}
|
||||
listGap="small"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -4,8 +4,9 @@ import { VSCodeButton } from "@vscode/webview-ui-toolkit/react"
|
||||
const RuleRow: React.FC<{
|
||||
rulePath: string
|
||||
enabled: boolean
|
||||
isGlobal: boolean
|
||||
toggleRule: (rulePath: string, enabled: boolean) => void
|
||||
}> = ({ rulePath, enabled, toggleRule }) => {
|
||||
}> = ({ rulePath, enabled, isGlobal, toggleRule }) => {
|
||||
// Get the filename from the path for display
|
||||
const displayName = rulePath.split("/").pop() || rulePath
|
||||
|
||||
@@ -16,6 +17,14 @@ const RuleRow: React.FC<{
|
||||
})
|
||||
}
|
||||
|
||||
const handleDeleteClick = () => {
|
||||
vscode.postMessage({
|
||||
type: "deleteClineRule",
|
||||
rulePath: rulePath,
|
||||
isGlobal: isGlobal,
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="mb-2.5">
|
||||
<div
|
||||
@@ -58,6 +67,14 @@ const RuleRow: React.FC<{
|
||||
style={{ height: "20px" }}>
|
||||
<span className="codicon codicon-edit" style={{ fontSize: "14px" }} />
|
||||
</VSCodeButton>
|
||||
<VSCodeButton
|
||||
appearance="icon"
|
||||
aria-label="Delete rule file"
|
||||
title="Delete rule file"
|
||||
onClick={handleDeleteClick}
|
||||
style={{ height: "20px" }}>
|
||||
<span className="codicon codicon-trash" style={{ fontSize: "14px" }} />
|
||||
</VSCodeButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3,10 +3,12 @@ import RuleRow from "./RuleRow"
|
||||
const RulesToggleList = ({
|
||||
rules,
|
||||
toggleRule,
|
||||
isGlobal,
|
||||
listGap = "medium",
|
||||
}: {
|
||||
rules: [string, boolean][]
|
||||
toggleRule: (rulePath: string, enabled: boolean) => void
|
||||
isGlobal: boolean
|
||||
listGap?: "small" | "medium" | "large"
|
||||
}) => {
|
||||
const gapClasses = {
|
||||
@@ -20,7 +22,7 @@ const RulesToggleList = ({
|
||||
return rules.length > 0 ? (
|
||||
<div className={`flex flex-col ${gapClass}`}>
|
||||
{rules.map(([rulePath, enabled]) => (
|
||||
<RuleRow key={rulePath} rulePath={rulePath} enabled={enabled} toggleRule={toggleRule} />
|
||||
<RuleRow key={rulePath} rulePath={rulePath} enabled={enabled} isGlobal={isGlobal} toggleRule={toggleRule} />
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
|
||||
Reference in New Issue
Block a user