diff --git a/README.md b/README.md index 39c825bfa4..876ccdd145 100644 --- a/README.md +++ b/README.md @@ -1,40 +1,25 @@
-

Join the Roo Code Community

+

Join the Roo Code Community

Connect with developers, contribute ideas, and stay ahead with the latest AI-powered coding tools.

- - Join Discord - - - Join Reddit - - -

- GitHub Stars - VS Marketplace Installs - -

+ Join Discord + Join Reddit + + GitHub Stars + VS Marketplace Installs
+
+
---- -# Roo Code (prev. Roo Cline) - - - - - - - - -
- Download on VS Marketplace - - Feature Requests - - Rate & Review -
+
+

Roo Code (prev. Roo Cline)

+ +Download on VS Marketplace +Feature Requests +Rate & Review +
**Roo Code** is an AI-powered **autonomous coding agent** that lives in your editor. It can: diff --git a/package.json b/package.json index cf1e4cc47a..ac0f116691 100644 --- a/package.json +++ b/package.json @@ -123,6 +123,31 @@ "command": "roo-cline.addToContext", "title": "Roo Code: Add To Context", "category": "Roo Code" + }, + { + "command": "roo-cline.terminalAddToContext", + "title": "Roo Code: Add Terminal Content to Context", + "category": "Terminal" + }, + { + "command": "roo-cline.terminalFixCommand", + "title": "Roo Code: Fix This Command", + "category": "Terminal" + }, + { + "command": "roo-cline.terminalExplainCommand", + "title": "Roo Code: Explain This Command", + "category": "Terminal" + }, + { + "command": "roo-cline.terminalFixCommandInCurrentTask", + "title": "Roo Code: Fix This Command (Current Task)", + "category": "Terminal" + }, + { + "command": "roo-cline.terminalExplainCommandInCurrentTask", + "title": "Roo Code: Explain This Command (Current Task)", + "category": "Terminal" } ], "menus": { @@ -148,6 +173,28 @@ "group": "Roo Code@4" } ], + "terminal/context": [ + { + "command": "roo-cline.terminalAddToContext", + "group": "Roo Code@1" + }, + { + "command": "roo-cline.terminalFixCommand", + "group": "Roo Code@2" + }, + { + "command": "roo-cline.terminalExplainCommand", + "group": "Roo Code@3" + }, + { + "command": "roo-cline.terminalFixCommandInCurrentTask", + "group": "Roo Code@5" + }, + { + "command": "roo-cline.terminalExplainCommandInCurrentTask", + "group": "Roo Code@6" + } + ], "view/title": [ { "command": "roo-cline.plusButtonClicked", diff --git a/src/activate/index.ts b/src/activate/index.ts index 76eebd185e..658bf467f7 100644 --- a/src/activate/index.ts +++ b/src/activate/index.ts @@ -1,3 +1,4 @@ export { handleUri } from "./handleUri" export { registerCommands } from "./registerCommands" export { registerCodeActions } from "./registerCodeActions" +export { registerTerminalActions } from "./registerTerminalActions" diff --git a/src/activate/registerTerminalActions.ts b/src/activate/registerTerminalActions.ts new file mode 100644 index 0000000000..fbf2a0510c --- /dev/null +++ b/src/activate/registerTerminalActions.ts @@ -0,0 +1,81 @@ +import * as vscode from "vscode" +import { ClineProvider } from "../core/webview/ClineProvider" +import { TerminalManager } from "../integrations/terminal/TerminalManager" + +const TERMINAL_COMMAND_IDS = { + ADD_TO_CONTEXT: "roo-cline.terminalAddToContext", + FIX: "roo-cline.terminalFixCommand", + FIX_IN_CURRENT_TASK: "roo-cline.terminalFixCommandInCurrentTask", + EXPLAIN: "roo-cline.terminalExplainCommand", + EXPLAIN_IN_CURRENT_TASK: "roo-cline.terminalExplainCommandInCurrentTask", +} as const + +export const registerTerminalActions = (context: vscode.ExtensionContext) => { + const terminalManager = new TerminalManager() + + registerTerminalAction(context, terminalManager, TERMINAL_COMMAND_IDS.ADD_TO_CONTEXT, "TERMINAL_ADD_TO_CONTEXT") + + registerTerminalActionPair( + context, + terminalManager, + TERMINAL_COMMAND_IDS.FIX, + "TERMINAL_FIX", + "What would you like Roo to fix?", + ) + + registerTerminalActionPair( + context, + terminalManager, + TERMINAL_COMMAND_IDS.EXPLAIN, + "TERMINAL_EXPLAIN", + "What would you like Roo to explain?", + ) +} + +const registerTerminalAction = ( + context: vscode.ExtensionContext, + terminalManager: TerminalManager, + command: string, + promptType: "TERMINAL_ADD_TO_CONTEXT" | "TERMINAL_FIX" | "TERMINAL_EXPLAIN", + inputPrompt?: string, +) => { + context.subscriptions.push( + vscode.commands.registerCommand(command, async (args: any) => { + let content = args.selection + if (!content || content === "") { + content = await terminalManager.getTerminalContents(promptType === "TERMINAL_ADD_TO_CONTEXT" ? -1 : 1) + } + + if (!content) { + vscode.window.showWarningMessage("No terminal content selected") + return + } + + const params: Record = { + terminalContent: content, + } + + if (inputPrompt) { + params.userInput = + (await vscode.window.showInputBox({ + prompt: inputPrompt, + })) ?? "" + } + + await ClineProvider.handleTerminalAction(command, promptType, params) + }), + ) +} + +const registerTerminalActionPair = ( + context: vscode.ExtensionContext, + terminalManager: TerminalManager, + baseCommand: string, + promptType: "TERMINAL_ADD_TO_CONTEXT" | "TERMINAL_FIX" | "TERMINAL_EXPLAIN", + inputPrompt?: string, +) => { + // Register new task version + registerTerminalAction(context, terminalManager, baseCommand, promptType, inputPrompt) + // Register current task version + registerTerminalAction(context, terminalManager, `${baseCommand}InCurrentTask`, promptType, inputPrompt) +} diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 96526491ed..9326c83350 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -256,6 +256,41 @@ export class ClineProvider implements vscode.WebviewViewProvider { await visibleProvider.initClineWithTask(prompt) } + public static async handleTerminalAction( + command: string, + promptType: "TERMINAL_ADD_TO_CONTEXT" | "TERMINAL_FIX" | "TERMINAL_EXPLAIN", + params: Record, + ): Promise { + const visibleProvider = await ClineProvider.getInstance() + if (!visibleProvider) { + return + } + + const { customSupportPrompts } = await visibleProvider.getState() + + const prompt = supportPrompt.create(promptType, params, customSupportPrompts) + + if (command.endsWith("AddToContext")) { + await visibleProvider.postMessageToWebview({ + type: "invoke", + invoke: "setChatBoxMessage", + text: prompt, + }) + return + } + + if (visibleProvider.cline && command.endsWith("InCurrentTask")) { + await visibleProvider.postMessageToWebview({ + type: "invoke", + invoke: "sendMessage", + text: prompt, + }) + return + } + + await visibleProvider.initClineWithTask(prompt) + } + async resolveWebviewView(webviewView: vscode.WebviewView | vscode.WebviewPanel) { this.outputChannel.appendLine("Resolving webview view") this.view = webviewView diff --git a/src/extension.ts b/src/extension.ts index 39f3d909d5..8ca7f3312c 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -5,7 +5,7 @@ import { createClineAPI } from "./exports" import "./utils/path" // Necessary to have access to String.prototype.toPosix. import { CodeActionProvider } from "./core/CodeActionProvider" import { DIFF_VIEW_URI_SCHEME } from "./integrations/editor/DiffViewProvider" -import { handleUri, registerCommands, registerCodeActions } from "./activate" +import { handleUri, registerCommands, registerCodeActions, registerTerminalActions } from "./activate" /** * Built using https://github.com/microsoft/vscode-webview-ui-toolkit @@ -78,6 +78,7 @@ export function activate(context: vscode.ExtensionContext) { ) registerCodeActions(context) + registerTerminalActions(context) return createClineAPI(outputChannel, sidebarProvider) } diff --git a/src/integrations/terminal/TerminalActions.ts b/src/integrations/terminal/TerminalActions.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/integrations/terminal/TerminalManager.ts b/src/integrations/terminal/TerminalManager.ts index ecc555fd53..d5496e20fb 100644 --- a/src/integrations/terminal/TerminalManager.ts +++ b/src/integrations/terminal/TerminalManager.ts @@ -224,4 +224,57 @@ export class TerminalManager { this.disposables.forEach((disposable) => disposable.dispose()) this.disposables = [] } + + /** + * Gets the terminal contents based on the number of commands to include + * @param commands Number of previous commands to include (-1 for all) + * @returns The selected terminal contents + */ + public async getTerminalContents(commands = -1): Promise { + // Save current clipboard content + const tempCopyBuffer = await vscode.env.clipboard.readText() + + try { + // Select terminal content + if (commands < 0) { + await vscode.commands.executeCommand("workbench.action.terminal.selectAll") + } else { + for (let i = 0; i < commands; i++) { + await vscode.commands.executeCommand("workbench.action.terminal.selectToPreviousCommand") + } + } + + // Copy selection and clear it + await vscode.commands.executeCommand("workbench.action.terminal.copySelection") + await vscode.commands.executeCommand("workbench.action.terminal.clearSelection") + + // Get copied content + let terminalContents = (await vscode.env.clipboard.readText()).trim() + + // Restore original clipboard content + await vscode.env.clipboard.writeText(tempCopyBuffer) + + if (tempCopyBuffer === terminalContents) { + // No terminal content was copied + return "" + } + + // Process multi-line content + const lines = terminalContents.split("\n") + const lastLine = lines.pop()?.trim() + if (lastLine) { + let i = lines.length - 1 + while (i >= 0 && !lines[i].trim().startsWith(lastLine)) { + i-- + } + terminalContents = lines.slice(Math.max(i, 0)).join("\n") + } + + return terminalContents + } catch (error) { + // Ensure clipboard is restored even if an error occurs + await vscode.env.clipboard.writeText(tempCopyBuffer) + throw error + } + } } diff --git a/src/shared/support-prompt.ts b/src/shared/support-prompt.ts index d097162a4e..3861da3139 100644 --- a/src/shared/support-prompt.ts +++ b/src/shared/support-prompt.ts @@ -101,6 +101,46 @@ Provide the improved code along with explanations for each enhancement.`, \${selectedText} \`\`\``, }, + TERMINAL_ADD_TO_CONTEXT: { + label: "Add Terminal Content to Context", + description: + "Add terminal output to your current task or conversation. Useful for providing command outputs or logs. Available in the terminal context menu (right-click on selected terminal content).", + template: `\${userInput} +Terminal output: +\`\`\` +\${terminalContent} +\`\`\``, + }, + TERMINAL_FIX: { + label: "Fix Terminal Command", + description: + "Get help fixing terminal commands that failed or need improvement. Available in the terminal context menu (right-click on selected terminal content).", + template: `\${userInput} +Fix this terminal command: +\`\`\` +\${terminalContent} +\`\`\` + +Please: +1. Identify any issues in the command +2. Provide the corrected command +3. Explain what was fixed and why`, + }, + TERMINAL_EXPLAIN: { + label: "Explain Terminal Command", + description: + "Get detailed explanations of terminal commands and their outputs. Available in the terminal context menu (right-click on selected terminal content).", + template: `\${userInput} +Explain this terminal command: +\`\`\` +\${terminalContent} +\`\`\` + +Please provide: +1. What the command does +2. Explanation of each part/flag +3. Expected output and behavior`, + }, } as const type SupportPromptType = keyof typeof supportPromptConfigs