Skip to content

Commit 738c03f

Browse files
0xToshiiCline Evaluationpashpashpashellipsis-dev[bot]
authored
slash command report bug (RooCodeInc#3387)
* slash command report bug * nits * nits * sigh, portible way to open urls with proper escaping because vs code api is broken * only asking for non-algorithmically derived info * Update webview-ui/src/components/chat/ChatView.tsx Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com> * gather user system info * Revert "gather user system info" This reverts commit fb16c72224a25a953efb7fe0539325f89a1e93c8. --------- Co-authored-by: Cline Evaluation <[email protected]> Co-authored-by: pashpashpash <[email protected]> Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
1 parent e8a68c4 commit 738c03f

File tree

12 files changed

+512
-3
lines changed

12 files changed

+512
-3
lines changed

src/core/assistant-message/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export const toolUseNames = [
2525
"attempt_completion",
2626
"new_task",
2727
"condense",
28+
"report_bug",
2829
"new_rule",
2930
] as const
3031

@@ -53,6 +54,11 @@ export const toolParamNames = [
5354
"response",
5455
"result",
5556
"context",
57+
"title",
58+
"what_happened",
59+
"steps_to_reproduce",
60+
"api_request_output",
61+
"additional_context",
5662
] as const
5763

5864
export type ToolParamName = (typeof toolParamNames)[number]

src/core/controller/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,9 @@ export class Controller {
274274
case "condense":
275275
this.task?.handleWebviewAskResponse("yesButtonClicked")
276276
break
277+
case "reportBug":
278+
this.task?.handleWebviewAskResponse("yesButtonClicked")
279+
break
277280
case "apiConfiguration":
278281
if (message.apiConfiguration) {
279282
await updateApiConfiguration(this.context, message.apiConfiguration)

src/core/prompts/commands.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,3 +145,34 @@ Example:
145145
Below is the user's input when they indicated that they wanted to create a new Cline rule file.
146146
</explicit_instructions>\n
147147
`
148+
149+
export const reportBugToolResponse = () =>
150+
`<explicit_instructions type="report_bug">
151+
The user has explicitly asked you to help them submit a bug to the Cline github page (you MUST now help them with this irrespective of what your conversation up to this point in time was). To do so you will use the report_bug tool which is defined below. However, you must first ensure that you have collected all required information to fill in all the parameters for the tool call. If any of the the required information is apparent through your previous conversation with the user, you can suggest how to fill in those entries. However you should NOT assume you know what the issue about unless it's clear.
152+
Otherwise, you should converse with the user until you are able to gather all the required details. When conversing with the user, make sure you ask for/reference all required information/fields. When referencing the required fields, use human friendly versions like "Steps to reproduce" rather than "steps_to_reproduce". Only then should you use the report_bug tool call.
153+
The report_bug tool can be used in either of the PLAN or ACT modes.
154+
155+
The report_bug tool call is defined below:
156+
157+
Description:
158+
Your task is to fill in all of the required fields for a issue/bug report on github. You should attempt to get the user to be as verbose as possible with their description of the bug/issue they encountered. Still, it's okay, when the user is unaware of some of the details, to set those fields as "N/A".
159+
160+
Parameters:
161+
- title: (required) Concise description of the issue.
162+
- what_happened: (required) What happened and also what the user expected to happen instead.
163+
- steps_to_reproduce: (required) What steps are required to reproduce the bug.
164+
- api_request_output: (optional) Relevant API request output.
165+
- additional_context: (optional) Any other context about this bug not already mentioned.
166+
167+
Usage:
168+
<report_bug>
169+
<title>Title of the issue</title>
170+
<what_happened>Description of the issue</what_happened>
171+
<steps_to_reproduce>Steps to reproduce the issue</steps_to_reproduce>
172+
<api_request_output>Output from the LLM API related to the bug</api_request_output>
173+
<additional_context>Other issue details not already covered</additional_context>
174+
</report_bug>
175+
176+
Below is the user's input when they indicated that they wanted to create a new Cline rule file.
177+
</explicit_instructions>\n
178+
`

src/core/slash-commands/index.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
1-
import { newTaskToolResponse, condenseToolResponse, newRuleToolResponse } from "../prompts/commands"
1+
import { newTaskToolResponse, condenseToolResponse, newRuleToolResponse, reportBugToolResponse } from "../prompts/commands"
22

33
/**
44
* Processes text for slash commands and transforms them with appropriate instructions
55
* This is called after parseMentions() to process any slash commands in the user's message
66
*/
77
export function parseSlashCommands(text: string): { processedText: string; needsClinerulesFileCheck: boolean } {
8-
const SUPPORTED_COMMANDS = ["newtask", "smol", "compact", "newrule"]
8+
const SUPPORTED_COMMANDS = ["newtask", "smol", "compact", "newrule", "reportbug"]
99

1010
const commandReplacements: Record<string, string> = {
1111
newtask: newTaskToolResponse(),
1212
smol: condenseToolResponse(),
1313
compact: condenseToolResponse(),
1414
newrule: newRuleToolResponse(),
15+
reportbug: reportBugToolResponse(),
1516
}
1617

1718
// this currently allows matching prepended whitespace prior to /slash-command

src/core/task/index.ts

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ import { DEFAULT_LANGUAGE_SETTINGS, getLanguageKey, LanguageDisplay } from "@sha
5757
import { ClineAskResponse, ClineCheckpointRestore } from "@shared/WebviewMessage"
5858
import { calculateApiCostAnthropic } from "@utils/cost"
5959
import { fileExistsAtPath } from "@utils/fs"
60+
import { createAndOpenGitHubIssue } from "@utils/github-url-utils"
6061
import { arePathsEqual, getReadablePath, isLocatedInWorkspace } from "@utils/path"
6162
import { fixModelHtmlEscaping, removeInvalidChars } from "@utils/string"
6263
import { AssistantMessageContent, parseAssistantMessage, ToolParamName, ToolUseName } from "@core/assistant-message"
@@ -1714,6 +1715,8 @@ export class Task {
17141715
return `[${block.name} for creating a new task]`
17151716
case "condense":
17161717
return `[${block.name}]`
1718+
case "report_bug":
1719+
return `[${block.name}]`
17171720
case "new_rule":
17181721
return `[${block.name} for '${block.params.path}']`
17191722
}
@@ -3141,6 +3144,135 @@ export class Task {
31413144
break
31423145
}
31433146
}
3147+
case "report_bug": {
3148+
const title = block.params.title
3149+
const what_happened = block.params.what_happened
3150+
const steps_to_reproduce = block.params.steps_to_reproduce
3151+
const api_request_output = block.params.api_request_output
3152+
const additional_context = block.params.additional_context
3153+
3154+
try {
3155+
if (block.partial) {
3156+
await this.ask(
3157+
"report_bug",
3158+
JSON.stringify({
3159+
title: removeClosingTag("title", title),
3160+
what_happened: removeClosingTag("what_happened", what_happened),
3161+
steps_to_reproduce: removeClosingTag("steps_to_reproduce", steps_to_reproduce),
3162+
api_request_output: removeClosingTag("api_request_output", api_request_output),
3163+
additional_context: removeClosingTag("additional_context", additional_context),
3164+
}),
3165+
block.partial,
3166+
).catch(() => {})
3167+
break
3168+
} else {
3169+
if (!title) {
3170+
this.consecutiveMistakeCount++
3171+
pushToolResult(await this.sayAndCreateMissingParamError("report_bug", "title"))
3172+
await this.saveCheckpoint()
3173+
break
3174+
}
3175+
if (!what_happened) {
3176+
this.consecutiveMistakeCount++
3177+
pushToolResult(await this.sayAndCreateMissingParamError("report_bug", "what_happened"))
3178+
await this.saveCheckpoint()
3179+
break
3180+
}
3181+
if (!steps_to_reproduce) {
3182+
this.consecutiveMistakeCount++
3183+
pushToolResult(await this.sayAndCreateMissingParamError("report_bug", "steps_to_reproduce"))
3184+
await this.saveCheckpoint()
3185+
break
3186+
}
3187+
if (!api_request_output) {
3188+
this.consecutiveMistakeCount++
3189+
pushToolResult(await this.sayAndCreateMissingParamError("report_bug", "api_request_output"))
3190+
await this.saveCheckpoint()
3191+
break
3192+
}
3193+
if (!additional_context) {
3194+
this.consecutiveMistakeCount++
3195+
pushToolResult(await this.sayAndCreateMissingParamError("report_bug", "additional_context"))
3196+
await this.saveCheckpoint()
3197+
break
3198+
}
3199+
3200+
this.consecutiveMistakeCount = 0
3201+
3202+
if (this.autoApprovalSettings.enabled && this.autoApprovalSettings.enableNotifications) {
3203+
showSystemNotification({
3204+
subtitle: "Cline wants to create a github issue...",
3205+
message: `Cline is suggesting to create a github issue with the title: ${title}`,
3206+
})
3207+
}
3208+
3209+
// Derive system information values algorithmically
3210+
const operatingSystem = os.platform() + " " + os.release()
3211+
const clineVersion =
3212+
vscode.extensions.getExtension("saoudrizwan.claude-dev")?.packageJSON.version || "Unknown"
3213+
const systemInfo = `VSCode: ${vscode.version}, Node.js: ${process.version}, Architecture: ${os.arch()}`
3214+
const providerAndModel = `${(await getGlobalState(this.getContext(), "apiProvider")) as string} / ${this.api.getModel().id}`
3215+
3216+
// Ask user for confirmation
3217+
const bugReportData = JSON.stringify({
3218+
title,
3219+
what_happened,
3220+
steps_to_reproduce,
3221+
api_request_output,
3222+
additional_context,
3223+
// Include derived values in the JSON for display purposes
3224+
provider_and_model: providerAndModel,
3225+
operating_system: operatingSystem,
3226+
system_info: systemInfo,
3227+
cline_version: clineVersion,
3228+
})
3229+
3230+
const { text, images } = await this.ask("report_bug", bugReportData, false)
3231+
3232+
// If the user provided a response, treat it as feedback
3233+
if (text || images?.length) {
3234+
await this.say("user_feedback", text ?? "", images)
3235+
pushToolResult(
3236+
formatResponse.toolResult(
3237+
`The user provided feedback on the Github issue generated:\n<feedback>\n${text}\n</feedback>`,
3238+
images,
3239+
),
3240+
)
3241+
} else {
3242+
// If no response, the user accepted the condensed version
3243+
pushToolResult(
3244+
formatResponse.toolResult(`The user accepted the creation of the Github issue.`),
3245+
)
3246+
3247+
try {
3248+
// Create a Map of parameters for the GitHub issue
3249+
const params = new Map<string, string>()
3250+
params.set("title", title)
3251+
params.set("operating-system", operatingSystem)
3252+
params.set("cline-version", clineVersion)
3253+
params.set("system-info", systemInfo)
3254+
params.set("additional-context", additional_context)
3255+
params.set("what-happened", what_happened)
3256+
params.set("steps", steps_to_reproduce)
3257+
params.set("provider-model", providerAndModel)
3258+
params.set("logs", api_request_output)
3259+
3260+
// Use our utility function to create and open the GitHub issue URL
3261+
// This bypasses VS Code's URI handling issues with special characters
3262+
await createAndOpenGitHubIssue("cline", "cline", "bug_report.yml", params)
3263+
} catch (error) {
3264+
console.error(`An error occurred while attempting to report the bug: ${error}`)
3265+
}
3266+
}
3267+
await this.saveCheckpoint()
3268+
break
3269+
}
3270+
} catch (error) {
3271+
await handleError("reporting bug", error)
3272+
await this.saveCheckpoint()
3273+
break
3274+
}
3275+
}
31443276
case "plan_mode_respond": {
31453277
const response: string | undefined = block.params.response
31463278
const optionsRaw: string | undefined = block.params.options

src/shared/ExtensionMessage.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ export type ClineAsk =
177177
| "use_mcp_server"
178178
| "new_task"
179179
| "condense"
180+
| "report_bug"
180181

181182
export type ClineSay =
182183
| "task"

src/shared/WebviewMessage.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export interface WebviewMessage {
1313
| "webviewDidLaunch"
1414
| "newTask"
1515
| "condense"
16+
| "reportBug"
1617
| "askResponse"
1718
| "didShowAnnouncement"
1819
| "selectImages"

0 commit comments

Comments
 (0)