Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/delete-file-cli-display.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@kilocode/cli": patch
---

Add proper display for deleteFile tool in CLI instead of showing "Unknown tool: deleteFile"
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,52 @@ describe("ExtensionMessageRow", () => {
expect(lastFrame()).toBeDefined()
expect(lastFrame()).not.toContain("Unknown message type")
})

it("should handle 'ask' deleteFile tool messages for single file", () => {
const message: ExtensionChatMessage = {
ts: Date.now(),
type: "ask",
ask: "tool",
text: JSON.stringify({
tool: "deleteFile",
path: "src/test.ts",
}),
}

const { lastFrame } = render(<ExtensionMessageRow message={message} />)

expect(lastFrame()).toBeDefined()
expect(lastFrame()).not.toContain("Unknown tool")
expect(lastFrame()).toContain("Delete")
expect(lastFrame()).toContain("src/test.ts")
})

it("should handle 'ask' deleteFile tool messages for directory with stats", () => {
const message: ExtensionChatMessage = {
ts: Date.now(),
type: "ask",
ask: "tool",
text: JSON.stringify({
tool: "deleteFile",
path: "src/components",
stats: {
files: 5,
directories: 2,
size: 1024,
isComplete: true,
},
}),
}

const { lastFrame } = render(<ExtensionMessageRow message={message} />)

expect(lastFrame()).toBeDefined()
expect(lastFrame()).not.toContain("Unknown tool")
expect(lastFrame()).toContain("Delete")
expect(lastFrame()).toContain("src/components")
expect(lastFrame()).toContain("5 files")
expect(lastFrame()).toContain("2 dirs")
})
})

describe("MCP Server Messages", () => {
Expand Down
27 changes: 27 additions & 0 deletions cli/src/ui/messages/extension/__tests__/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
isMcpServerData,
parseMcpServerData,
formatUnknownMessageContent,
getToolIcon,
} from "../utils.js"
import type { ExtensionChatMessage } from "../../../../types/messages.js"

Expand Down Expand Up @@ -492,3 +493,29 @@ describe("formatUnknownMessageContent", () => {
})
})
})

describe("getToolIcon", () => {
it("should return 🗑️ for deleteFile tool", () => {
expect(getToolIcon("deleteFile")).toBe("🗑️")
})

it("should return ± for editedExistingFile tool", () => {
expect(getToolIcon("editedExistingFile")).toBe("±")
})

it("should return ± for appliedDiff tool", () => {
expect(getToolIcon("appliedDiff")).toBe("±")
})

it("should return 📄 for newFileCreated tool", () => {
expect(getToolIcon("newFileCreated")).toBe("📄")
})

it("should return 📝 for readFile tool", () => {
expect(getToolIcon("readFile")).toBe("📝")
})

it("should return ⚙ for unknown tools", () => {
expect(getToolIcon("unknownTool")).toBe("⚙")
})
})
67 changes: 67 additions & 0 deletions cli/src/ui/messages/extension/tools/ToolDeleteFileMessage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import React, { useMemo } from "react"
import { Box, Text } from "ink"
import type { ToolMessageProps } from "../types.js"
import { formatFilePath, getToolIcon } from "../utils.js"
import { useTheme } from "../../../../state/hooks/useTheme.js"

/**
* Display file or directory deletion
* Uses compact format: 🗑️ Delete(filename) or 🗑️ Delete(dirname) ⎿ X files, Y dirs
*/
export const ToolDeleteFileMessage: React.FC<ToolMessageProps> = ({ toolData }) => {
const theme = useTheme()

// Format stats summary for directory deletion
const statsSummary = useMemo(() => {
if (!toolData.stats) {
return null
}

const { files, directories, isComplete } = toolData.stats

if (!isComplete) {
return "scanning..."
}

const parts: string[] = []
if (files > 0 || directories === 0) {
parts.push(`${files} ${files === 1 ? "file" : "files"}`)
}
if (directories > 0) {
parts.push(`${directories} ${directories === 1 ? "dir" : "dirs"}`)
}

return parts.length > 0 ? `⎿ ${parts.join(", ")}` : null
}, [toolData.stats])

const icon = getToolIcon("deleteFile")

return (
<Box flexDirection="column" marginY={1}>
{/* Compact header: 🗑️ Delete(filename) ⎿ X files, Y dirs */}
<Box>
<Text color={theme.semantic.error} bold>
{icon} Delete(
</Text>
<Text color={theme.semantic.error} bold>
{formatFilePath(toolData.path || "")}
</Text>
<Text color={theme.semantic.error} bold>
)
</Text>
{toolData.isOutsideWorkspace && (
<Text color={theme.semantic.warning} dimColor>
{" "}
</Text>
)}
{statsSummary && (
<Text color={theme.ui.text.dimmed} dimColor>
{" "}
{statsSummary}
</Text>
)}
</Box>
</Box>
)
}
4 changes: 4 additions & 0 deletions cli/src/ui/messages/extension/tools/ToolRouter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
ToolFinishTaskMessage,
ToolFetchInstructionsMessage,
ToolRunSlashCommandMessage,
ToolDeleteFileMessage,
} from "./index.js"

/**
Expand Down Expand Up @@ -82,6 +83,9 @@ export const ToolRouter: React.FC<ToolMessageProps> = ({ message, toolData }) =>
case "runSlashCommand":
return <ToolRunSlashCommandMessage message={message} toolData={toolData} />

case "deleteFile":
return <ToolDeleteFileMessage message={message} toolData={toolData} />

default:
return (
<Box marginY={1}>
Expand Down
Loading