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
32 changes: 32 additions & 0 deletions src/activate/handleUri.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import * as vscode from "vscode"

import { ClineProvider } from "../core/webview/ClineProvider"

export const handleUri = async (uri: vscode.Uri) => {
const path = uri.path
const query = new URLSearchParams(uri.query.replace(/\+/g, "%2B"))
const visibleProvider = ClineProvider.getVisibleInstance()

if (!visibleProvider) {
return
}

switch (path) {
case "/glama": {
const code = query.get("code")
if (code) {
await visibleProvider.handleGlamaCallback(code)
}
break
}
case "/openrouter": {
const code = query.get("code")
if (code) {
await visibleProvider.handleOpenRouterCallback(code)
}
break
}
default:
break
}
}
3 changes: 3 additions & 0 deletions src/activate/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { handleUri } from "./handleUri"
export { registerCommands } from "./registerCommands"
export { registerCodeActions } from "./registerCodeActions"
91 changes: 91 additions & 0 deletions src/activate/registerCodeActions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import * as vscode from "vscode"

import { ACTION_NAMES, COMMAND_IDS } from "../core/CodeActionProvider"
import { EditorUtils } from "../core/EditorUtils"
import { ClineProvider } from "../core/webview/ClineProvider"

export const registerCodeActions = (context: vscode.ExtensionContext) => {
registerCodeActionPair(
context,
COMMAND_IDS.EXPLAIN,
"EXPLAIN",
"What would you like Roo to explain?",
"E.g. How does the error handling work?",
)

registerCodeActionPair(
context,
COMMAND_IDS.FIX,
"FIX",
"What would you like Roo to fix?",
"E.g. Maintain backward compatibility",
)

registerCodeActionPair(
context,
COMMAND_IDS.IMPROVE,
"IMPROVE",
"What would you like Roo to improve?",
"E.g. Focus on performance optimization",
)

registerCodeAction(context, COMMAND_IDS.ADD_TO_CONTEXT, "ADD_TO_CONTEXT")
}

const registerCodeAction = (
context: vscode.ExtensionContext,
command: string,
promptType: keyof typeof ACTION_NAMES,
inputPrompt?: string,
inputPlaceholder?: string,
) => {
let userInput: string | undefined

context.subscriptions.push(
vscode.commands.registerCommand(command, async (...args: any[]) => {
if (inputPrompt) {
userInput = await vscode.window.showInputBox({
prompt: inputPrompt,
placeHolder: inputPlaceholder,
})
}

// Handle both code action and direct command cases.
let filePath: string
let selectedText: string
let diagnostics: any[] | undefined

if (args.length > 1) {
// Called from code action.
;[filePath, selectedText, diagnostics] = args
} else {
// Called directly from command palette.
const context = EditorUtils.getEditorContext()
if (!context) return
;({ filePath, selectedText, diagnostics } = context)
}

const params = {
...{ filePath, selectedText },
...(diagnostics ? { diagnostics } : {}),
...(userInput ? { userInput } : {}),
}

await ClineProvider.handleCodeAction(command, promptType, params)
}),
)
}

const registerCodeActionPair = (
context: vscode.ExtensionContext,
baseCommand: string,
promptType: keyof typeof ACTION_NAMES,
inputPrompt?: string,
inputPlaceholder?: string,
) => {
// Register new task version.
registerCodeAction(context, baseCommand, promptType, inputPrompt, inputPlaceholder)

// Register current task version.
registerCodeAction(context, `${baseCommand}InCurrentTask`, promptType, inputPrompt, inputPlaceholder)
}
83 changes: 83 additions & 0 deletions src/activate/registerCommands.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import * as vscode from "vscode"
import delay from "delay"

import { ClineProvider } from "../core/webview/ClineProvider"

export type RegisterCommandOptions = {
context: vscode.ExtensionContext
outputChannel: vscode.OutputChannel
provider: ClineProvider
}

export const registerCommands = (options: RegisterCommandOptions) => {
const { context, outputChannel } = options

for (const [command, callback] of Object.entries(getCommandsMap(options))) {
context.subscriptions.push(vscode.commands.registerCommand(command, callback))
}
}

const getCommandsMap = ({ context, outputChannel, provider }: RegisterCommandOptions) => {
return {
"roo-cline.plusButtonClicked": async () => {
await provider.clearTask()
await provider.postStateToWebview()
await provider.postMessageToWebview({ type: "action", action: "chatButtonClicked" })
},
"roo-cline.mcpButtonClicked": () => {
provider.postMessageToWebview({ type: "action", action: "mcpButtonClicked" })
},
"roo-cline.promptsButtonClicked": () => {
provider.postMessageToWebview({ type: "action", action: "promptsButtonClicked" })
},
"roo-cline.popoutButtonClicked": () => openClineInNewTab({ context, outputChannel }),
"roo-cline.openInNewTab": () => openClineInNewTab({ context, outputChannel }),
"roo-cline.settingsButtonClicked": () => {
provider.postMessageToWebview({ type: "action", action: "settingsButtonClicked" })
},
"roo-cline.historyButtonClicked": () => {
provider.postMessageToWebview({ type: "action", action: "historyButtonClicked" })
},
}
}

const openClineInNewTab = async ({ context, outputChannel }: Omit<RegisterCommandOptions, "provider">) => {
outputChannel.appendLine("Opening Roo Code in new tab")

// (This example uses webviewProvider activation event which is necessary to
// deserialize cached webview, but since we use retainContextWhenHidden, we
// don't need to use that event).
// https://github.com/microsoft/vscode-extension-samples/blob/main/webview-sample/src/extension.ts
const tabProvider = new ClineProvider(context, outputChannel)
// const column = vscode.window.activeTextEditor ? vscode.window.activeTextEditor.viewColumn : undefined
const lastCol = Math.max(...vscode.window.visibleTextEditors.map((editor) => editor.viewColumn || 0))

// Check if there are any visible text editors, otherwise open a new group
// to the right.
const hasVisibleEditors = vscode.window.visibleTextEditors.length > 0

if (!hasVisibleEditors) {
await vscode.commands.executeCommand("workbench.action.newGroupRight")
}

const targetCol = hasVisibleEditors ? Math.max(lastCol + 1, 1) : vscode.ViewColumn.Two

const panel = vscode.window.createWebviewPanel(ClineProvider.tabPanelId, "Roo Code", targetCol, {
enableScripts: true,
retainContextWhenHidden: true,
localResourceRoots: [context.extensionUri],
})

// TODO: use better svg icon with light and dark variants (see
// https://stackoverflow.com/questions/58365687/vscode-extension-iconpath).
panel.iconPath = {
light: vscode.Uri.joinPath(context.extensionUri, "assets", "icons", "rocket.png"),
dark: vscode.Uri.joinPath(context.extensionUri, "assets", "icons", "rocket.png"),
}

tabProvider.resolveWebviewView(panel)

// Lock the editor group so clicking on files doesn't open them over the panel
await delay(100)
await vscode.commands.executeCommand("workbench.action.lockEditorGroup")
}
2 changes: 1 addition & 1 deletion src/core/CodeActionProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const ACTION_NAMES = {
ADD_TO_CONTEXT: "Roo Code: Add to Context",
} as const

const COMMAND_IDS = {
export const COMMAND_IDS = {
EXPLAIN: "roo-cline.explainCode",
FIX: "roo-cline.fixCode",
IMPROVE: "roo-cline.improveCode",
Expand Down
Loading
Loading