mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
Get package publisher and name from package.json + command type safety (#3766)
This commit is contained in:
parent
ff837d5cbf
commit
f274a150c4
39 changed files with 361 additions and 235 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -13,7 +13,7 @@ mock/
|
|||
|
||||
# Builds
|
||||
bin/
|
||||
roo-cline-*.vsix
|
||||
*.vsix
|
||||
|
||||
# Local prompts and rules
|
||||
/local-prompts
|
||||
|
|
|
|||
21
e2e/package-lock.json
generated
21
e2e/package-lock.json
generated
|
|
@ -8,6 +8,7 @@
|
|||
"name": "e2e",
|
||||
"version": "0.1.0",
|
||||
"devDependencies": {
|
||||
"@roo-code/types": "^1.12.0",
|
||||
"@types/mocha": "^10.0.10",
|
||||
"@vscode/test-cli": "^0.0.10",
|
||||
"@vscode/test-electron": "^2.4.0",
|
||||
|
|
@ -89,6 +90,16 @@
|
|||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@roo-code/types": {
|
||||
"version": "1.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@roo-code/types/-/types-1.12.0.tgz",
|
||||
"integrity": "sha512-djdZ4lzsiOc+umX357JvcSwRlAMm05P+8DU58IFyZERmEh8wkm4TglDuaaRVGtQSHw9YGFikqfruLtZSEb7zJQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"zod": "^3.24.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/istanbul-lib-coverage": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
|
||||
|
|
@ -2344,6 +2355,16 @@
|
|||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/zod": {
|
||||
"version": "3.25.8",
|
||||
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.8.tgz",
|
||||
"integrity": "sha512-iJPWX8HoZ2VE21VrhHGU9jVo/kVDUQyqM9vF0MxDhW/fp2sAl1eVwGJgiYZdHGiMwQJImXIW80lKk0MnfDxqiQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/colinhacks"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@
|
|||
"build": "rimraf out && tsc -p tsconfig.json",
|
||||
"vscode-test": "cd .. && npm run vscode-test"
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"@roo-code/types": "^1.12.0",
|
||||
"@types/mocha": "^10.0.10",
|
||||
"@vscode/test-cli": "^0.0.10",
|
||||
"@vscode/test-electron": "^2.4.0",
|
||||
|
|
|
|||
|
|
@ -1,24 +1,47 @@
|
|||
import * as assert from "assert"
|
||||
import * as vscode from "vscode"
|
||||
|
||||
import { Package } from "@roo-code/types"
|
||||
|
||||
suite("Roo Code Extension", () => {
|
||||
test("Commands should be registered", async () => {
|
||||
const expectedCommands = [
|
||||
"roo-cline.plusButtonClicked",
|
||||
"roo-cline.mcpButtonClicked",
|
||||
"roo-cline.historyButtonClicked",
|
||||
"roo-cline.popoutButtonClicked",
|
||||
"roo-cline.settingsButtonClicked",
|
||||
"roo-cline.openInNewTab",
|
||||
"roo-cline.explainCode",
|
||||
"roo-cline.fixCode",
|
||||
"roo-cline.improveCode",
|
||||
"SidebarProvider.open",
|
||||
"SidebarProvider.focus",
|
||||
"SidebarProvider.resetViewLocation",
|
||||
"SidebarProvider.toggleVisibility",
|
||||
"SidebarProvider.removeView",
|
||||
"activationCompleted",
|
||||
"plusButtonClicked",
|
||||
"mcpButtonClicked",
|
||||
"promptsButtonClicked",
|
||||
"popoutButtonClicked",
|
||||
"openInNewTab",
|
||||
"settingsButtonClicked",
|
||||
"historyButtonClicked",
|
||||
"showHumanRelayDialog",
|
||||
"registerHumanRelayCallback",
|
||||
"unregisterHumanRelayCallback",
|
||||
"handleHumanRelayResponse",
|
||||
"newTask",
|
||||
"setCustomStoragePath",
|
||||
"focusInput",
|
||||
"acceptInput",
|
||||
"explainCode",
|
||||
"fixCode",
|
||||
"improveCode",
|
||||
"addToContext",
|
||||
"terminalAddToContext",
|
||||
"terminalFixCommand",
|
||||
"terminalExplainCommand",
|
||||
]
|
||||
|
||||
const commands = await vscode.commands.getCommands(true)
|
||||
const commands = new Set(
|
||||
(await vscode.commands.getCommands(true)).filter((cmd) => cmd.startsWith(Package.name)),
|
||||
)
|
||||
|
||||
for (const cmd of expectedCommands) {
|
||||
assert.ok(commands.includes(cmd), `Command ${cmd} should be registered`)
|
||||
for (const command of expectedCommands) {
|
||||
assert.ok(commands.has(`${Package.name}.${command}`), `Command ${command} should be registered`)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import Mocha from "mocha"
|
|||
import { glob } from "glob"
|
||||
import * as vscode from "vscode"
|
||||
|
||||
import type { RooCodeAPI } from "../../../src/exports/roo-code"
|
||||
import { type RooCodeAPI, Package } from "@roo-code/types"
|
||||
|
||||
import { waitFor } from "./utils"
|
||||
|
||||
|
|
@ -12,7 +12,7 @@ declare global {
|
|||
}
|
||||
|
||||
export async function run() {
|
||||
const extension = vscode.extensions.getExtension<RooCodeAPI>("RooVeterinaryInc.roo-cline")
|
||||
const extension = vscode.extensions.getExtension<RooCodeAPI>(`${Package.publisher}.${Package.name}`)
|
||||
|
||||
if (!extension) {
|
||||
throw new Error("Extension not found")
|
||||
|
|
@ -26,7 +26,7 @@ export async function run() {
|
|||
openRouterModelId: "google/gemini-2.0-flash-001",
|
||||
})
|
||||
|
||||
await vscode.commands.executeCommand("roo-cline.SidebarProvider.focus")
|
||||
await vscode.commands.executeCommand(`${Package.name}.SidebarProvider.focus`)
|
||||
await waitFor(() => api.isReady())
|
||||
|
||||
// Expose the API to the tests.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import * as assert from "assert"
|
||||
|
||||
import type { ClineMessage } from "../../../src/exports/roo-code"
|
||||
import type { ClineMessage } from "@roo-code/types"
|
||||
|
||||
import { waitUntilCompleted } from "./utils"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import * as assert from "assert"
|
||||
|
||||
import type { ClineMessage } from "../../../src/exports/roo-code"
|
||||
import type { ClineMessage } from "@roo-code/types"
|
||||
|
||||
import { sleep, waitFor, waitUntilCompleted } from "./utils"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import * as assert from "assert"
|
||||
|
||||
import type { ClineMessage } from "../../../src/exports/roo-code"
|
||||
import type { ClineMessage } from "@roo-code/types"
|
||||
|
||||
import { waitUntilCompleted } from "./utils"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import type { RooCodeAPI } from "../../../src/exports/roo-code"
|
||||
import type { RooCodeAPI } from "@roo-code/types"
|
||||
|
||||
type WaitForOptions = {
|
||||
timeout?: number
|
||||
|
|
|
|||
|
|
@ -1,17 +1,10 @@
|
|||
import * as vscode from "vscode"
|
||||
|
||||
import { CodeActionName, CodeActionId } from "../schemas"
|
||||
import { getCodeActionCommand } from "../utils/commands"
|
||||
import { EditorUtils } from "../integrations/editor/EditorUtils"
|
||||
|
||||
export type CodeActionName = "EXPLAIN" | "FIX" | "IMPROVE" | "ADD_TO_CONTEXT" | "NEW_TASK"
|
||||
|
||||
export type CodeActionId =
|
||||
| "roo-cline.explainCode"
|
||||
| "roo-cline.fixCode"
|
||||
| "roo-cline.improveCode"
|
||||
| "roo-cline.addToContext"
|
||||
| "roo-cline.newTask"
|
||||
|
||||
export const ACTION_TITLES: Record<CodeActionName, string> = {
|
||||
export const TITLES: Record<CodeActionName, string> = {
|
||||
EXPLAIN: "Explain with Roo Code",
|
||||
FIX: "Fix with Roo Code",
|
||||
IMPROVE: "Improve with Roo Code",
|
||||
|
|
@ -19,14 +12,6 @@ export const ACTION_TITLES: Record<CodeActionName, string> = {
|
|||
NEW_TASK: "New Roo Code Task",
|
||||
} as const
|
||||
|
||||
export const COMMAND_IDS: Record<CodeActionName, CodeActionId> = {
|
||||
EXPLAIN: "roo-cline.explainCode",
|
||||
FIX: "roo-cline.fixCode",
|
||||
IMPROVE: "roo-cline.improveCode",
|
||||
ADD_TO_CONTEXT: "roo-cline.addToContext",
|
||||
NEW_TASK: "roo-cline.newTask",
|
||||
} as const
|
||||
|
||||
export class CodeActionProvider implements vscode.CodeActionProvider {
|
||||
public static readonly providedCodeActionKinds = [
|
||||
vscode.CodeActionKind.QuickFix,
|
||||
|
|
@ -40,7 +25,7 @@ export class CodeActionProvider implements vscode.CodeActionProvider {
|
|||
args: any[],
|
||||
): vscode.CodeAction {
|
||||
const action = new vscode.CodeAction(title, kind)
|
||||
action.command = { command, title, arguments: args }
|
||||
action.command = { command: getCodeActionCommand(command), title, arguments: args }
|
||||
return action
|
||||
}
|
||||
|
||||
|
|
@ -60,17 +45,12 @@ export class CodeActionProvider implements vscode.CodeActionProvider {
|
|||
const actions: vscode.CodeAction[] = []
|
||||
|
||||
actions.push(
|
||||
this.createAction(
|
||||
ACTION_TITLES.ADD_TO_CONTEXT,
|
||||
vscode.CodeActionKind.QuickFix,
|
||||
COMMAND_IDS.ADD_TO_CONTEXT,
|
||||
[
|
||||
filePath,
|
||||
effectiveRange.text,
|
||||
effectiveRange.range.start.line + 1,
|
||||
effectiveRange.range.end.line + 1,
|
||||
],
|
||||
),
|
||||
this.createAction(TITLES.ADD_TO_CONTEXT, vscode.CodeActionKind.QuickFix, "addToContext", [
|
||||
filePath,
|
||||
effectiveRange.text,
|
||||
effectiveRange.range.start.line + 1,
|
||||
effectiveRange.range.end.line + 1,
|
||||
]),
|
||||
)
|
||||
|
||||
if (context.diagnostics.length > 0) {
|
||||
|
|
@ -80,7 +60,7 @@ export class CodeActionProvider implements vscode.CodeActionProvider {
|
|||
|
||||
if (relevantDiagnostics.length > 0) {
|
||||
actions.push(
|
||||
this.createAction(ACTION_TITLES.FIX, vscode.CodeActionKind.QuickFix, COMMAND_IDS.FIX, [
|
||||
this.createAction(TITLES.FIX, vscode.CodeActionKind.QuickFix, "fixCode", [
|
||||
filePath,
|
||||
effectiveRange.text,
|
||||
effectiveRange.range.start.line + 1,
|
||||
|
|
@ -91,7 +71,7 @@ export class CodeActionProvider implements vscode.CodeActionProvider {
|
|||
}
|
||||
} else {
|
||||
actions.push(
|
||||
this.createAction(ACTION_TITLES.EXPLAIN, vscode.CodeActionKind.QuickFix, COMMAND_IDS.EXPLAIN, [
|
||||
this.createAction(TITLES.EXPLAIN, vscode.CodeActionKind.QuickFix, "explainCode", [
|
||||
filePath,
|
||||
effectiveRange.text,
|
||||
effectiveRange.range.start.line + 1,
|
||||
|
|
@ -100,7 +80,7 @@ export class CodeActionProvider implements vscode.CodeActionProvider {
|
|||
)
|
||||
|
||||
actions.push(
|
||||
this.createAction(ACTION_TITLES.IMPROVE, vscode.CodeActionKind.QuickFix, COMMAND_IDS.IMPROVE, [
|
||||
this.createAction(TITLES.IMPROVE, vscode.CodeActionKind.QuickFix, "improveCode", [
|
||||
filePath,
|
||||
effectiveRange.text,
|
||||
effectiveRange.range.start.line + 1,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import * as vscode from "vscode"
|
|||
|
||||
import { EditorUtils } from "../../integrations/editor/EditorUtils"
|
||||
|
||||
import { CodeActionProvider, ACTION_TITLES } from "../CodeActionProvider"
|
||||
import { CodeActionProvider, TITLES } from "../CodeActionProvider"
|
||||
|
||||
jest.mock("vscode", () => ({
|
||||
CodeAction: jest.fn().mockImplementation((title, kind) => ({
|
||||
|
|
@ -70,9 +70,9 @@ describe("CodeActionProvider", () => {
|
|||
const actions = provider.provideCodeActions(mockDocument, mockRange, mockContext)
|
||||
|
||||
expect(actions).toHaveLength(3)
|
||||
expect((actions as any)[0].title).toBe(ACTION_TITLES.ADD_TO_CONTEXT)
|
||||
expect((actions as any)[1].title).toBe(ACTION_TITLES.EXPLAIN)
|
||||
expect((actions as any)[2].title).toBe(ACTION_TITLES.IMPROVE)
|
||||
expect((actions as any)[0].title).toBe(TITLES.ADD_TO_CONTEXT)
|
||||
expect((actions as any)[1].title).toBe(TITLES.EXPLAIN)
|
||||
expect((actions as any)[2].title).toBe(TITLES.IMPROVE)
|
||||
})
|
||||
|
||||
it("should provide fix action instead of fix logic when diagnostics exist", () => {
|
||||
|
|
@ -83,8 +83,8 @@ describe("CodeActionProvider", () => {
|
|||
const actions = provider.provideCodeActions(mockDocument, mockRange, mockContext)
|
||||
|
||||
expect(actions).toHaveLength(2)
|
||||
expect((actions as any).some((a: any) => a.title === `${ACTION_TITLES.FIX}`)).toBe(true)
|
||||
expect((actions as any).some((a: any) => a.title === `${ACTION_TITLES.ADD_TO_CONTEXT}`)).toBe(true)
|
||||
expect((actions as any).some((a: any) => a.title === `${TITLES.FIX}`)).toBe(true)
|
||||
expect((actions as any).some((a: any) => a.title === `${TITLES.ADD_TO_CONTEXT}`)).toBe(true)
|
||||
})
|
||||
|
||||
it("should return empty array when no effective range", () => {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,9 @@
|
|||
import * as vscode from "vscode"
|
||||
|
||||
import { Package } from "../schemas"
|
||||
import { ClineProvider } from "../core/webview/ClineProvider"
|
||||
|
||||
import { t } from "../i18n"
|
||||
|
||||
import { COMMAND_IDS } from "./CodeActionProvider"
|
||||
|
||||
export const handleNewTask = async (params: { prompt?: string } | null | undefined) => {
|
||||
let prompt = params?.prompt
|
||||
|
||||
|
|
@ -17,9 +15,9 @@ export const handleNewTask = async (params: { prompt?: string } | null | undefin
|
|||
}
|
||||
|
||||
if (!prompt) {
|
||||
await vscode.commands.executeCommand("roo-cline.SidebarProvider.focus")
|
||||
await vscode.commands.executeCommand(`${Package.name}.SidebarProvider.focus`)
|
||||
return
|
||||
}
|
||||
|
||||
await ClineProvider.handleCodeAction(COMMAND_IDS.NEW_TASK, "NEW_TASK", { userInput: prompt })
|
||||
await ClineProvider.handleCodeAction("newTask", "NEW_TASK", { userInput: prompt })
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,22 +1,22 @@
|
|||
import * as vscode from "vscode"
|
||||
|
||||
import { CodeActionId, CodeActionName } from "../schemas"
|
||||
import { getCodeActionCommand } from "../utils/commands"
|
||||
import { EditorUtils } from "../integrations/editor/EditorUtils"
|
||||
import { ClineProvider } from "../core/webview/ClineProvider"
|
||||
|
||||
import { type CodeActionName, type CodeActionId, COMMAND_IDS } from "./CodeActionProvider"
|
||||
|
||||
export const registerCodeActions = (context: vscode.ExtensionContext) => {
|
||||
registerCodeAction(context, COMMAND_IDS.EXPLAIN, "EXPLAIN")
|
||||
registerCodeAction(context, COMMAND_IDS.FIX, "FIX")
|
||||
registerCodeAction(context, COMMAND_IDS.IMPROVE, "IMPROVE")
|
||||
registerCodeAction(context, COMMAND_IDS.ADD_TO_CONTEXT, "ADD_TO_CONTEXT")
|
||||
registerCodeAction(context, "explainCode", "EXPLAIN")
|
||||
registerCodeAction(context, "fixCode", "FIX")
|
||||
registerCodeAction(context, "improveCode", "IMPROVE")
|
||||
registerCodeAction(context, "addToContext", "ADD_TO_CONTEXT")
|
||||
}
|
||||
|
||||
const registerCodeAction = (context: vscode.ExtensionContext, command: CodeActionId, promptType: CodeActionName) => {
|
||||
let userInput: string | undefined
|
||||
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand(command, async (...args: any[]) => {
|
||||
vscode.commands.registerCommand(getCodeActionCommand(command), async (...args: any[]) => {
|
||||
// Handle both code action and direct command cases.
|
||||
let filePath: string
|
||||
let selectedText: string
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import * as vscode from "vscode"
|
||||
import delay from "delay"
|
||||
|
||||
import { CommandId, Package } from "../schemas"
|
||||
import { getCommand } from "../utils/commands"
|
||||
import { ClineProvider } from "../core/webview/ClineProvider"
|
||||
import { ContextProxy } from "../core/config/ContextProxy"
|
||||
import { telemetryService } from "../services/telemetry/TelemetryService"
|
||||
|
|
@ -57,125 +59,124 @@ export type RegisterCommandOptions = {
|
|||
export const registerCommands = (options: RegisterCommandOptions) => {
|
||||
const { context } = options
|
||||
|
||||
for (const [command, callback] of Object.entries(getCommandsMap(options))) {
|
||||
for (const [id, callback] of Object.entries(getCommandsMap(options))) {
|
||||
const command = getCommand(id as CommandId)
|
||||
context.subscriptions.push(vscode.commands.registerCommand(command, callback))
|
||||
}
|
||||
}
|
||||
|
||||
const getCommandsMap = ({ context, outputChannel, provider }: RegisterCommandOptions) => {
|
||||
return {
|
||||
"roo-cline.activationCompleted": () => {},
|
||||
"roo-cline.plusButtonClicked": async () => {
|
||||
const visibleProvider = getVisibleProviderOrLog(outputChannel)
|
||||
const getCommandsMap = ({ context, outputChannel, provider }: RegisterCommandOptions): Record<CommandId, any> => ({
|
||||
activationCompleted: () => {},
|
||||
plusButtonClicked: async () => {
|
||||
const visibleProvider = getVisibleProviderOrLog(outputChannel)
|
||||
|
||||
if (!visibleProvider) {
|
||||
return
|
||||
}
|
||||
if (!visibleProvider) {
|
||||
return
|
||||
}
|
||||
|
||||
telemetryService.captureTitleButtonClicked("plus")
|
||||
telemetryService.captureTitleButtonClicked("plus")
|
||||
|
||||
await visibleProvider.removeClineFromStack()
|
||||
await visibleProvider.postStateToWebview()
|
||||
await visibleProvider.postMessageToWebview({ type: "action", action: "chatButtonClicked" })
|
||||
},
|
||||
"roo-cline.mcpButtonClicked": () => {
|
||||
const visibleProvider = getVisibleProviderOrLog(outputChannel)
|
||||
await visibleProvider.removeClineFromStack()
|
||||
await visibleProvider.postStateToWebview()
|
||||
await visibleProvider.postMessageToWebview({ type: "action", action: "chatButtonClicked" })
|
||||
},
|
||||
mcpButtonClicked: () => {
|
||||
const visibleProvider = getVisibleProviderOrLog(outputChannel)
|
||||
|
||||
if (!visibleProvider) {
|
||||
return
|
||||
}
|
||||
if (!visibleProvider) {
|
||||
return
|
||||
}
|
||||
|
||||
telemetryService.captureTitleButtonClicked("mcp")
|
||||
telemetryService.captureTitleButtonClicked("mcp")
|
||||
|
||||
visibleProvider.postMessageToWebview({ type: "action", action: "mcpButtonClicked" })
|
||||
},
|
||||
"roo-cline.promptsButtonClicked": () => {
|
||||
const visibleProvider = getVisibleProviderOrLog(outputChannel)
|
||||
visibleProvider.postMessageToWebview({ type: "action", action: "mcpButtonClicked" })
|
||||
},
|
||||
promptsButtonClicked: () => {
|
||||
const visibleProvider = getVisibleProviderOrLog(outputChannel)
|
||||
|
||||
if (!visibleProvider) {
|
||||
return
|
||||
}
|
||||
if (!visibleProvider) {
|
||||
return
|
||||
}
|
||||
|
||||
telemetryService.captureTitleButtonClicked("prompts")
|
||||
telemetryService.captureTitleButtonClicked("prompts")
|
||||
|
||||
visibleProvider.postMessageToWebview({ type: "action", action: "promptsButtonClicked" })
|
||||
},
|
||||
"roo-cline.popoutButtonClicked": () => {
|
||||
telemetryService.captureTitleButtonClicked("popout")
|
||||
visibleProvider.postMessageToWebview({ type: "action", action: "promptsButtonClicked" })
|
||||
},
|
||||
popoutButtonClicked: () => {
|
||||
telemetryService.captureTitleButtonClicked("popout")
|
||||
|
||||
return openClineInNewTab({ context, outputChannel })
|
||||
},
|
||||
"roo-cline.openInNewTab": () => openClineInNewTab({ context, outputChannel }),
|
||||
"roo-cline.settingsButtonClicked": () => {
|
||||
const visibleProvider = getVisibleProviderOrLog(outputChannel)
|
||||
return openClineInNewTab({ context, outputChannel })
|
||||
},
|
||||
openInNewTab: () => openClineInNewTab({ context, outputChannel }),
|
||||
settingsButtonClicked: () => {
|
||||
const visibleProvider = getVisibleProviderOrLog(outputChannel)
|
||||
|
||||
if (!visibleProvider) {
|
||||
return
|
||||
}
|
||||
if (!visibleProvider) {
|
||||
return
|
||||
}
|
||||
|
||||
telemetryService.captureTitleButtonClicked("settings")
|
||||
telemetryService.captureTitleButtonClicked("settings")
|
||||
|
||||
visibleProvider.postMessageToWebview({ type: "action", action: "settingsButtonClicked" })
|
||||
// Also explicitly post the visibility message to trigger scroll reliably
|
||||
visibleProvider.postMessageToWebview({ type: "action", action: "didBecomeVisible" })
|
||||
},
|
||||
"roo-cline.historyButtonClicked": () => {
|
||||
const visibleProvider = getVisibleProviderOrLog(outputChannel)
|
||||
visibleProvider.postMessageToWebview({ type: "action", action: "settingsButtonClicked" })
|
||||
// Also explicitly post the visibility message to trigger scroll reliably
|
||||
visibleProvider.postMessageToWebview({ type: "action", action: "didBecomeVisible" })
|
||||
},
|
||||
historyButtonClicked: () => {
|
||||
const visibleProvider = getVisibleProviderOrLog(outputChannel)
|
||||
|
||||
if (!visibleProvider) {
|
||||
return
|
||||
}
|
||||
if (!visibleProvider) {
|
||||
return
|
||||
}
|
||||
|
||||
telemetryService.captureTitleButtonClicked("history")
|
||||
telemetryService.captureTitleButtonClicked("history")
|
||||
|
||||
visibleProvider.postMessageToWebview({ type: "action", action: "historyButtonClicked" })
|
||||
},
|
||||
"roo-cline.showHumanRelayDialog": (params: { requestId: string; promptText: string }) => {
|
||||
visibleProvider.postMessageToWebview({ type: "action", action: "historyButtonClicked" })
|
||||
},
|
||||
showHumanRelayDialog: (params: { requestId: string; promptText: string }) => {
|
||||
const panel = getPanel()
|
||||
|
||||
if (panel) {
|
||||
panel?.webview.postMessage({
|
||||
type: "showHumanRelayDialog",
|
||||
requestId: params.requestId,
|
||||
promptText: params.promptText,
|
||||
})
|
||||
}
|
||||
},
|
||||
registerHumanRelayCallback: registerHumanRelayCallback,
|
||||
unregisterHumanRelayCallback: unregisterHumanRelayCallback,
|
||||
handleHumanRelayResponse: handleHumanRelayResponse,
|
||||
newTask: handleNewTask,
|
||||
setCustomStoragePath: async () => {
|
||||
const { promptForCustomStoragePath } = await import("../utils/storage")
|
||||
await promptForCustomStoragePath()
|
||||
},
|
||||
focusInput: async () => {
|
||||
try {
|
||||
const panel = getPanel()
|
||||
|
||||
if (panel) {
|
||||
panel?.webview.postMessage({
|
||||
type: "showHumanRelayDialog",
|
||||
requestId: params.requestId,
|
||||
promptText: params.promptText,
|
||||
})
|
||||
if (!panel) {
|
||||
await vscode.commands.executeCommand(`workbench.view.extension.${Package.name}-ActivityBar`)
|
||||
} else if (panel === tabPanel) {
|
||||
panel.reveal(vscode.ViewColumn.Active, false)
|
||||
} else if (panel === sidebarPanel) {
|
||||
await vscode.commands.executeCommand(`${ClineProvider.sideBarId}.focus`)
|
||||
provider.postMessageToWebview({ type: "action", action: "focusInput" })
|
||||
}
|
||||
},
|
||||
"roo-cline.registerHumanRelayCallback": registerHumanRelayCallback,
|
||||
"roo-cline.unregisterHumanRelayCallback": unregisterHumanRelayCallback,
|
||||
"roo-cline.handleHumanRelayResponse": handleHumanRelayResponse,
|
||||
"roo-cline.newTask": handleNewTask,
|
||||
"roo-cline.setCustomStoragePath": async () => {
|
||||
const { promptForCustomStoragePath } = await import("../shared/storagePathManager")
|
||||
await promptForCustomStoragePath()
|
||||
},
|
||||
"roo-cline.focusInput": async () => {
|
||||
try {
|
||||
const panel = getPanel()
|
||||
} catch (error) {
|
||||
outputChannel.appendLine(`Error focusing input: ${error}`)
|
||||
}
|
||||
},
|
||||
acceptInput: () => {
|
||||
const visibleProvider = getVisibleProviderOrLog(outputChannel)
|
||||
|
||||
if (!panel) {
|
||||
await vscode.commands.executeCommand("workbench.view.extension.roo-cline-ActivityBar")
|
||||
} else if (panel === tabPanel) {
|
||||
panel.reveal(vscode.ViewColumn.Active, false)
|
||||
} else if (panel === sidebarPanel) {
|
||||
await vscode.commands.executeCommand(`${ClineProvider.sideBarId}.focus`)
|
||||
provider.postMessageToWebview({ type: "action", action: "focusInput" })
|
||||
}
|
||||
} catch (error) {
|
||||
outputChannel.appendLine(`Error focusing input: ${error}`)
|
||||
}
|
||||
},
|
||||
"roo.acceptInput": () => {
|
||||
const visibleProvider = getVisibleProviderOrLog(outputChannel)
|
||||
if (!visibleProvider) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!visibleProvider) {
|
||||
return
|
||||
}
|
||||
|
||||
visibleProvider.postMessageToWebview({ type: "acceptInput" })
|
||||
},
|
||||
}
|
||||
}
|
||||
visibleProvider.postMessageToWebview({ type: "acceptInput" })
|
||||
},
|
||||
})
|
||||
|
||||
export const openClineInNewTab = async ({ context, outputChannel }: Omit<RegisterCommandOptions, "provider">) => {
|
||||
// (This example uses webviewProvider activation event which is necessary to
|
||||
|
|
|
|||
|
|
@ -1,27 +1,24 @@
|
|||
import * as vscode from "vscode"
|
||||
|
||||
import { TerminalActionId, TerminalActionPromptType } from "../schemas"
|
||||
import { getTerminalCommand } from "../utils/commands"
|
||||
import { ClineProvider } from "../core/webview/ClineProvider"
|
||||
import { Terminal } from "../integrations/terminal/Terminal"
|
||||
import { t } from "../i18n"
|
||||
|
||||
const TERMINAL_COMMAND_IDS = {
|
||||
ADD_TO_CONTEXT: "roo-cline.terminalAddToContext",
|
||||
FIX: "roo-cline.terminalFixCommand",
|
||||
EXPLAIN: "roo-cline.terminalExplainCommand",
|
||||
} as const
|
||||
|
||||
export const registerTerminalActions = (context: vscode.ExtensionContext) => {
|
||||
registerTerminalAction(context, TERMINAL_COMMAND_IDS.ADD_TO_CONTEXT, "TERMINAL_ADD_TO_CONTEXT")
|
||||
registerTerminalAction(context, TERMINAL_COMMAND_IDS.FIX, "TERMINAL_FIX")
|
||||
registerTerminalAction(context, TERMINAL_COMMAND_IDS.EXPLAIN, "TERMINAL_EXPLAIN")
|
||||
registerTerminalAction(context, "terminalAddToContext", "TERMINAL_ADD_TO_CONTEXT")
|
||||
registerTerminalAction(context, "terminalFixCommand", "TERMINAL_FIX")
|
||||
registerTerminalAction(context, "terminalExplainCommand", "TERMINAL_EXPLAIN")
|
||||
}
|
||||
|
||||
const registerTerminalAction = (
|
||||
context: vscode.ExtensionContext,
|
||||
command: string,
|
||||
promptType: "TERMINAL_ADD_TO_CONTEXT" | "TERMINAL_FIX" | "TERMINAL_EXPLAIN",
|
||||
command: TerminalActionId,
|
||||
promptType: TerminalActionPromptType,
|
||||
) => {
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand(command, async (args: any) => {
|
||||
vscode.commands.registerCommand(getTerminalCommand(command), async (args: any) => {
|
||||
let content = args.selection
|
||||
|
||||
if (!content || content === "") {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import fs from "fs/promises"
|
|||
import NodeCache from "node-cache"
|
||||
|
||||
import { ContextProxy } from "../../../core/config/ContextProxy"
|
||||
import { getCacheDirectoryPath } from "../../../shared/storagePathManager"
|
||||
import { getCacheDirectoryPath } from "../../../utils/storage"
|
||||
import { RouterName, ModelRecord } from "../../../shared/api"
|
||||
import { fileExistsAtPath } from "../../../utils/fs"
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import NodeCache from "node-cache"
|
|||
import sanitize from "sanitize-filename"
|
||||
|
||||
import { ContextProxy } from "../../../core/config/ContextProxy"
|
||||
import { getCacheDirectoryPath } from "../../../shared/storagePathManager"
|
||||
import { getCacheDirectoryPath } from "../../../utils/storage"
|
||||
import { RouterName, ModelRecord } from "../../../shared/api"
|
||||
import { fileExistsAtPath } from "../../../utils/fs"
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { Anthropic } from "@anthropic-ai/sdk"
|
|||
import axios from "axios"
|
||||
import OpenAI from "openai"
|
||||
|
||||
import { Package } from "../../schemas"
|
||||
import { ApiHandlerOptions, glamaDefaultModelId, glamaDefaultModelInfo } from "../../shared/api"
|
||||
|
||||
import { ApiStream } from "../transform/stream"
|
||||
|
|
@ -14,7 +15,9 @@ import { RouterProvider } from "./router-provider"
|
|||
const GLAMA_DEFAULT_TEMPERATURE = 0
|
||||
|
||||
const DEFAULT_HEADERS = {
|
||||
"X-Glama-Metadata": JSON.stringify({ labels: [{ key: "app", value: "vscode.rooveterinaryinc.roo-cline" }] }),
|
||||
"X-Glama-Metadata": JSON.stringify({
|
||||
labels: [{ key: "app", value: `vscode.${Package.publisher}.${Package.name}` }],
|
||||
}),
|
||||
}
|
||||
|
||||
export class GlamaHandler extends RouterProvider implements SingleCompletionHandler {
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@ import { Anthropic } from "@anthropic-ai/sdk"
|
|||
import * as vscode from "vscode"
|
||||
|
||||
import { ModelInfo } from "../../shared/api"
|
||||
import { ApiHandler, SingleCompletionHandler } from "../index"
|
||||
import { getCommand } from "../../utils/commands"
|
||||
import { ApiStream } from "../transform/stream"
|
||||
|
||||
import { ApiHandler, SingleCompletionHandler } from "../index"
|
||||
/**
|
||||
* Human Relay API processor
|
||||
* This processor does not directly call the API, but interacts with the model through human operations copy and paste.
|
||||
|
|
@ -111,17 +111,17 @@ function getMessageContent(message: Anthropic.Messages.MessageParam): string {
|
|||
*/
|
||||
async function showHumanRelayDialog(promptText: string): Promise<string | undefined> {
|
||||
return new Promise<string | undefined>((resolve) => {
|
||||
// Create a unique request ID
|
||||
// Create a unique request ID.
|
||||
const requestId = Date.now().toString()
|
||||
|
||||
// Register a global callback function
|
||||
// Register a global callback function.
|
||||
vscode.commands.executeCommand(
|
||||
"roo-cline.registerHumanRelayCallback",
|
||||
getCommand("registerHumanRelayCallback"),
|
||||
requestId,
|
||||
(response: string | undefined) => resolve(response),
|
||||
)
|
||||
|
||||
// Open the dialog box directly using the current panel
|
||||
vscode.commands.executeCommand("roo-cline.showHumanRelayDialog", { requestId, promptText })
|
||||
// Open the dialog box directly using the current panel.
|
||||
vscode.commands.executeCommand(getCommand("showHumanRelayDialog"), { requestId, promptText })
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import * as path from "path"
|
||||
import * as vscode from "vscode"
|
||||
import { getTaskDirectoryPath } from "../../shared/storagePathManager"
|
||||
import { getTaskDirectoryPath } from "../../utils/storage"
|
||||
import { GlobalFileNames } from "../../shared/globalFileNames"
|
||||
import { fileExistsAtPath } from "../../utils/fs"
|
||||
import fs from "fs/promises"
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import { Anthropic } from "@anthropic-ai/sdk"
|
|||
import { fileExistsAtPath } from "../../utils/fs"
|
||||
|
||||
import { GlobalFileNames } from "../../shared/globalFileNames"
|
||||
import { getTaskDirectoryPath } from "../../shared/storagePathManager"
|
||||
import { getTaskDirectoryPath } from "../../utils/storage"
|
||||
|
||||
export type ApiMessage = Anthropic.MessageParam & { ts?: number; isSummary?: boolean }
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { fileExistsAtPath } from "../../utils/fs"
|
|||
|
||||
import { GlobalFileNames } from "../../shared/globalFileNames"
|
||||
import { ClineMessage } from "../../shared/ExtensionMessage"
|
||||
import { getTaskDirectoryPath } from "../../shared/storagePathManager"
|
||||
import { getTaskDirectoryPath } from "../../utils/storage"
|
||||
|
||||
export type ReadTaskMessagesOptions = {
|
||||
taskId: string
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import { combineCommandSequences } from "../../shared/combineCommandSequences"
|
|||
import { getApiMetrics } from "../../shared/getApiMetrics"
|
||||
import { findLastIndex } from "../../shared/array"
|
||||
import { HistoryItem } from "../../shared/HistoryItem"
|
||||
import { getTaskDirectoryPath } from "../../shared/storagePathManager"
|
||||
import { getTaskDirectoryPath } from "../../utils/storage"
|
||||
|
||||
const taskSizeCache = new NodeCache({ stdTTL: 30, checkperiod: 5 * 60 })
|
||||
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ jest.mock("../../environment/getEnvironmentDetails", () => ({
|
|||
jest.mock("../../ignore/RooIgnoreController")
|
||||
|
||||
// Mock storagePathManager to prevent dynamic import issues
|
||||
jest.mock("../../../shared/storagePathManager", () => ({
|
||||
jest.mock("../../../utils/storage", () => ({
|
||||
getTaskDirectoryPath: jest
|
||||
.fn()
|
||||
.mockImplementation((globalStoragePath, taskId) => Promise.resolve(`${globalStoragePath}/tasks/${taskId}`)),
|
||||
|
|
|
|||
|
|
@ -9,7 +9,18 @@ import axios from "axios"
|
|||
import pWaitFor from "p-wait-for"
|
||||
import * as vscode from "vscode"
|
||||
|
||||
import type { GlobalState, ProviderName, ProviderSettings, RooCodeSettings, ProviderSettingsEntry } from "../../schemas"
|
||||
import {
|
||||
GlobalState,
|
||||
ProviderName,
|
||||
ProviderSettings,
|
||||
RooCodeSettings,
|
||||
ProviderSettingsEntry,
|
||||
Package,
|
||||
CodeActionId,
|
||||
CodeActionName,
|
||||
TerminalActionId,
|
||||
TerminalActionPromptType,
|
||||
} from "../../schemas"
|
||||
import { t } from "../../i18n"
|
||||
import { setPanel } from "../../activate/registerCommands"
|
||||
import { requestyDefaultModelId, openRouterDefaultModelId, glamaDefaultModelId } from "../../shared/api"
|
||||
|
|
@ -34,7 +45,6 @@ import { ContextProxy } from "../config/ContextProxy"
|
|||
import { ProviderSettingsManager } from "../config/ProviderSettingsManager"
|
||||
import { CustomModesManager } from "../config/CustomModesManager"
|
||||
import { buildApiHandler } from "../../api"
|
||||
import { CodeActionName } from "../../activate/CodeActionProvider"
|
||||
import { Task, TaskOptions } from "../task/Task"
|
||||
import { getNonce } from "./getNonce"
|
||||
import { getUri } from "./getUri"
|
||||
|
|
@ -54,8 +64,11 @@ export type ClineProviderEvents = {
|
|||
}
|
||||
|
||||
export class ClineProvider extends EventEmitter<ClineProviderEvents> implements vscode.WebviewViewProvider {
|
||||
public static readonly sideBarId = "roo-cline.SidebarProvider" // used in package.json as the view's id. This value cannot be changed due to how vscode caches views based on their id, and updating the id would break existing instances of the extension.
|
||||
public static readonly tabPanelId = "roo-cline.TabPanelProvider"
|
||||
// Used in package.json as the view's id. This value cannot be changed due
|
||||
// to how VSCode caches views based on their id, and updating the id would
|
||||
// break existing instances of the extension.
|
||||
public static readonly sideBarId = `${Package.name}.SidebarProvider`
|
||||
public static readonly tabPanelId = `${Package.name}.TabPanelProvider`
|
||||
private static activeInstances: Set<ClineProvider> = new Set()
|
||||
private disposables: vscode.Disposable[] = []
|
||||
private view?: vscode.WebviewView | vscode.WebviewPanel
|
||||
|
|
@ -225,7 +238,7 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
|
|||
|
||||
// If no visible provider, try to show the sidebar view
|
||||
if (!visibleProvider) {
|
||||
await vscode.commands.executeCommand("roo-cline.SidebarProvider.focus")
|
||||
await vscode.commands.executeCommand(`${Package.name}.SidebarProvider.focus`)
|
||||
// Wait briefly for the view to become visible
|
||||
await delay(100)
|
||||
visibleProvider = ClineProvider.getVisibleInstance()
|
||||
|
|
@ -254,7 +267,7 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
|
|||
}
|
||||
|
||||
public static async handleCodeAction(
|
||||
command: string,
|
||||
command: CodeActionId,
|
||||
promptType: CodeActionName,
|
||||
params: Record<string, string | any[]>,
|
||||
): Promise<void> {
|
||||
|
|
@ -272,7 +285,7 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
|
|||
// TODO: Improve type safety for promptType.
|
||||
const prompt = supportPrompt.create(promptType, params, customSupportPrompts)
|
||||
|
||||
if (command.endsWith("addToContext")) {
|
||||
if (command === "addToContext") {
|
||||
await visibleProvider.postMessageToWebview({ type: "invoke", invoke: "setChatBoxMessage", text: prompt })
|
||||
return
|
||||
}
|
||||
|
|
@ -281,12 +294,12 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
|
|||
}
|
||||
|
||||
public static async handleTerminalAction(
|
||||
command: string,
|
||||
promptType: "TERMINAL_ADD_TO_CONTEXT" | "TERMINAL_FIX" | "TERMINAL_EXPLAIN",
|
||||
command: TerminalActionId,
|
||||
promptType: TerminalActionPromptType,
|
||||
params: Record<string, string | any[]>,
|
||||
): Promise<void> {
|
||||
// Capture telemetry for terminal action usage
|
||||
telemetryService.captureCodeActionUsed(promptType)
|
||||
|
||||
const visibleProvider = await ClineProvider.getInstance()
|
||||
|
||||
if (!visibleProvider) {
|
||||
|
|
@ -294,10 +307,9 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
|
|||
}
|
||||
|
||||
const { customSupportPrompts } = await visibleProvider.getState()
|
||||
|
||||
const prompt = supportPrompt.create(promptType, params, customSupportPrompts)
|
||||
|
||||
if (command.endsWith("AddToContext")) {
|
||||
if (command === "terminalAddToContext") {
|
||||
await visibleProvider.postMessageToWebview({ type: "invoke", invoke: "setChatBoxMessage", text: prompt })
|
||||
return
|
||||
}
|
||||
|
|
@ -974,7 +986,7 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
|
|||
}
|
||||
|
||||
async ensureSettingsDirectoryExists(): Promise<string> {
|
||||
const { getSettingsDirectoryPath } = await import("../../shared/storagePathManager")
|
||||
const { getSettingsDirectoryPath } = await import("../../utils/storage")
|
||||
const globalStoragePath = this.contextProxy.globalStorageUri.fsPath
|
||||
return getSettingsDirectoryPath(globalStoragePath)
|
||||
}
|
||||
|
|
@ -1070,7 +1082,7 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
|
|||
const historyItem = history.find((item) => item.id === id)
|
||||
|
||||
if (historyItem) {
|
||||
const { getTaskDirectoryPath } = await import("../../shared/storagePathManager")
|
||||
const { getTaskDirectoryPath } = await import("../../utils/storage")
|
||||
const globalStoragePath = this.contextProxy.globalStorageUri.fsPath
|
||||
const taskDirPath = await getTaskDirectoryPath(globalStoragePath, id)
|
||||
const apiConversationHistoryFilePath = path.join(taskDirPath, GlobalFileNames.apiConversationHistory)
|
||||
|
|
@ -1260,7 +1272,7 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
|
|||
|
||||
const telemetryKey = process.env.POSTHOG_API_KEY
|
||||
const machineId = vscode.env.machineId
|
||||
const allowedCommands = vscode.workspace.getConfiguration("roo-cline").get<string[]>("allowedCommands") || []
|
||||
const allowedCommands = vscode.workspace.getConfiguration(Package.name).get<string[]>("allowedCommands") || []
|
||||
const cwd = this.cwd
|
||||
|
||||
// Check if there's a system prompt override for the current mode
|
||||
|
|
|
|||
|
|
@ -4,11 +4,10 @@ import pWaitFor from "p-wait-for"
|
|||
import * as vscode from "vscode"
|
||||
|
||||
import { ClineProvider } from "./ClineProvider"
|
||||
import { Language, ProviderSettings, GlobalState } from "../../schemas"
|
||||
import { Language, ProviderSettings, GlobalState, Package } from "../../schemas"
|
||||
import { changeLanguage, t } from "../../i18n"
|
||||
import { RouterName, toRouterName } from "../../shared/api"
|
||||
import { supportPrompt } from "../../shared/support-prompt"
|
||||
|
||||
import { checkoutDiffPayloadSchema, checkoutRestorePayloadSchema, WebviewMessage } from "../../shared/WebviewMessage"
|
||||
import { checkExistKey } from "../../shared/checkExistApiConfig"
|
||||
import { experimentDefault } from "../../shared/experiments"
|
||||
|
|
@ -34,6 +33,7 @@ import { getWorkspacePath } from "../../utils/path"
|
|||
import { Mode, defaultModeSlug } from "../../shared/modes"
|
||||
import { getModels, flushModels } from "../../api/providers/fetchers/modelCache"
|
||||
import { generateSystemPrompt } from "./generateSystemPrompt"
|
||||
import { getCommand } from "../../utils/commands"
|
||||
|
||||
const ALLOWED_VSCODE_SETTINGS = new Set(["terminal.integrated.inheritEnv"])
|
||||
|
||||
|
|
@ -376,7 +376,7 @@ export const webviewMessageHandler = async (provider: ClineProvider, message: We
|
|||
|
||||
// Also update workspace settings.
|
||||
await vscode.workspace
|
||||
.getConfiguration("roo-cline")
|
||||
.getConfiguration(Package.name)
|
||||
.update("allowedCommands", message.commands, vscode.ConfigurationTarget.Global)
|
||||
|
||||
break
|
||||
|
|
@ -1230,7 +1230,7 @@ export const webviewMessageHandler = async (provider: ClineProvider, message: We
|
|||
break
|
||||
case "humanRelayResponse":
|
||||
if (message.requestId && message.text) {
|
||||
vscode.commands.executeCommand("roo-cline.handleHumanRelayResponse", {
|
||||
vscode.commands.executeCommand(getCommand("handleHumanRelayResponse"), {
|
||||
requestId: message.requestId,
|
||||
text: message.text,
|
||||
cancelled: false,
|
||||
|
|
@ -1240,7 +1240,7 @@ export const webviewMessageHandler = async (provider: ClineProvider, message: We
|
|||
|
||||
case "humanRelayCancel":
|
||||
if (message.requestId) {
|
||||
vscode.commands.executeCommand("roo-cline.handleHumanRelayResponse", {
|
||||
vscode.commands.executeCommand(getCommand("handleHumanRelayResponse"), {
|
||||
requestId: message.requestId,
|
||||
cancelled: true,
|
||||
})
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@ The Roo Code extension exposes an API that can be used by other extensions. To u
|
|||
3. Get access to the API with the following code:
|
||||
|
||||
```typescript
|
||||
const extension = vscode.extensions.getExtension<RooCodeAPI>("rooveterinaryinc.roo-cline")
|
||||
import { RooCodeAPI, Package } from "path/to/roo-code"
|
||||
|
||||
const extension = vscode.extensions.getExtension<RooCodeAPI>(`${Package.publisher}.${Package.name}`)
|
||||
|
||||
if (!extension?.isActive) {
|
||||
throw new Error("Extension is not activated")
|
||||
|
|
@ -35,10 +37,10 @@ await api.pressPrimaryButton()
|
|||
await api.pressSecondaryButton()
|
||||
```
|
||||
|
||||
**NOTE:** To ensure that the `rooveterinaryinc.roo-cline` extension is activated before your extension, add it to the `extensionDependencies` in your `package.json`:
|
||||
**NOTE:** To ensure that the `RooVeterinaryInc.roo-cline` extension is activated before your extension, add it to the `extensionDependencies` in your `package.json`:
|
||||
|
||||
```json
|
||||
"extensionDependencies": ["rooveterinaryinc.roo-cline"]
|
||||
"extensionDependencies": ["RooVeterinaryInc.roo-cline"]
|
||||
```
|
||||
|
||||
For detailed information on the available methods and their usage, refer to the `roo-code.d.ts` file.
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import * as vscode from "vscode"
|
|||
import fs from "fs/promises"
|
||||
import * as path from "path"
|
||||
|
||||
import { Package } from "../schemas"
|
||||
import { getWorkspacePath } from "../utils/path"
|
||||
import { ClineProvider } from "../core/webview/ClineProvider"
|
||||
import { openClineInNewTab } from "../activate/registerCommands"
|
||||
|
|
@ -112,7 +113,7 @@ export class API extends EventEmitter<RooCodeEvents> implements RooCodeAPI {
|
|||
provider = await openClineInNewTab({ context: this.context, outputChannel: this.outputChannel })
|
||||
this.registerListeners(provider)
|
||||
} else {
|
||||
await vscode.commands.executeCommand("roo-cline.SidebarProvider.focus")
|
||||
await vscode.commands.executeCommand(`${Package.name}.SidebarProvider.focus`)
|
||||
|
||||
provider = this.sidebarProvider
|
||||
}
|
||||
|
|
@ -122,7 +123,7 @@ export class API extends EventEmitter<RooCodeEvents> implements RooCodeAPI {
|
|||
|
||||
if (configuration.allowedCommands) {
|
||||
await vscode.workspace
|
||||
.getConfiguration("roo-cline")
|
||||
.getConfiguration(Package.name)
|
||||
.update("allowedCommands", configuration.allowedCommands, vscode.ConfigurationTarget.Global)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,9 +43,9 @@ export { RooCodeEventName, IpcOrigin, IpcMessageType }
|
|||
* Constants
|
||||
*/
|
||||
|
||||
import { providerNames } from "../schemas"
|
||||
import { providerNames, Package } from "../schemas"
|
||||
|
||||
export { providerNames }
|
||||
export { providerNames, Package }
|
||||
|
||||
/**
|
||||
* RooCodeAPI
|
||||
|
|
|
|||
6
src/exports/roo-code.d.ts
vendored
6
src/exports/roo-code.d.ts
vendored
|
|
@ -1540,6 +1540,11 @@ type TaskEvent =
|
|||
]
|
||||
}
|
||||
|
||||
declare const Package: {
|
||||
readonly publisher: string
|
||||
readonly name: string
|
||||
readonly version: string
|
||||
}
|
||||
/**
|
||||
* ProviderName
|
||||
*/
|
||||
|
|
@ -1752,6 +1757,7 @@ export {
|
|||
IpcMessageType,
|
||||
IpcOrigin,
|
||||
type IpcServerEvents,
|
||||
Package,
|
||||
type ProviderName,
|
||||
type ProviderSettings,
|
||||
type ProviderSettingsEntry,
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ try {
|
|||
|
||||
import "./utils/path" // Necessary to have access to String.prototype.toPosix.
|
||||
|
||||
import { Package } from "./schemas"
|
||||
import { ContextProxy } from "./core/config/ContextProxy"
|
||||
import { ClineProvider } from "./core/webview/ClineProvider"
|
||||
import { DIFF_VIEW_URI_SCHEME } from "./integrations/editor/DiffViewProvider"
|
||||
|
|
@ -65,7 +66,7 @@ export async function activate(context: vscode.ExtensionContext) {
|
|||
TerminalRegistry.initialize()
|
||||
|
||||
// Get default commands from configuration.
|
||||
const defaultCommands = vscode.workspace.getConfiguration("roo-cline").get<string[]>("allowedCommands") || []
|
||||
const defaultCommands = vscode.workspace.getConfiguration(Package.name).get<string[]>("allowedCommands") || []
|
||||
|
||||
// Initialize global state if not already set.
|
||||
if (!context.globalState.get("allowedCommands")) {
|
||||
|
|
@ -123,7 +124,7 @@ export async function activate(context: vscode.ExtensionContext) {
|
|||
registerTerminalActions(context)
|
||||
|
||||
// Allows other extensions to activate once Roo is ready.
|
||||
vscode.commands.executeCommand("roo-cline.activationCompleted")
|
||||
vscode.commands.executeCommand(`${Package.name}.activationCompleted`)
|
||||
|
||||
// Implements the `RooCodeAPI` interface.
|
||||
const socketPath = process.env.ROO_CODE_IPC_SOCKET_PATH
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ import * as path from "path"
|
|||
import * as fs from "fs/promises"
|
||||
import { convertTheme } from "monaco-vscode-textmate-theme-converter/lib/cjs"
|
||||
|
||||
import { Package } from "../../schemas"
|
||||
|
||||
const defaultThemes: Record<string, string> = {
|
||||
"Default Dark Modern": "dark_modern",
|
||||
"Dark+": "dark_plus",
|
||||
|
|
@ -141,5 +143,5 @@ export function mergeJson(
|
|||
}
|
||||
|
||||
function getExtensionUri(): vscode.Uri {
|
||||
return vscode.extensions.getExtension("rooveterinaryinc.roo-cline")!.extensionUri
|
||||
return vscode.extensions.getExtension(`${Package.publisher}.${Package.name}`)!.extensionUri
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,61 @@ import { z } from "zod"
|
|||
|
||||
import { Equals, Keys, AssertEqual } from "../utils/type-fu"
|
||||
|
||||
/**
|
||||
* Extension
|
||||
*/
|
||||
|
||||
import { publisher, name, version } from "../../package.json"
|
||||
|
||||
export const Package = {
|
||||
publisher,
|
||||
name,
|
||||
version,
|
||||
} as const
|
||||
|
||||
/**
|
||||
* CodeAction
|
||||
*/
|
||||
|
||||
export type CodeActionName = "EXPLAIN" | "FIX" | "IMPROVE" | "ADD_TO_CONTEXT" | "NEW_TASK"
|
||||
|
||||
export type CodeActionId = "explainCode" | "fixCode" | "improveCode" | "addToContext" | "newTask"
|
||||
|
||||
/**
|
||||
* TerminalAction
|
||||
*/
|
||||
|
||||
export type TerminalActionName = "ADD_TO_CONTEXT" | "FIX" | "EXPLAIN"
|
||||
|
||||
export type TerminalActionPromptType = `TERMINAL_${TerminalActionName}`
|
||||
|
||||
export type TerminalActionId = "terminalAddToContext" | "terminalFixCommand" | "terminalExplainCommand"
|
||||
|
||||
/**
|
||||
* Command
|
||||
*/
|
||||
|
||||
const commandIds = [
|
||||
"activationCompleted",
|
||||
"plusButtonClicked",
|
||||
"mcpButtonClicked",
|
||||
"promptsButtonClicked",
|
||||
"popoutButtonClicked",
|
||||
"openInNewTab",
|
||||
"settingsButtonClicked",
|
||||
"historyButtonClicked",
|
||||
"showHumanRelayDialog",
|
||||
"registerHumanRelayCallback",
|
||||
"unregisterHumanRelayCallback",
|
||||
"handleHumanRelayResponse",
|
||||
"newTask",
|
||||
"setCustomStoragePath",
|
||||
"focusInput",
|
||||
"acceptInput",
|
||||
] as const
|
||||
|
||||
export type CommandId = (typeof commandIds)[number]
|
||||
|
||||
/**
|
||||
* ProviderName
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -32,7 +32,18 @@ interface SupportPromptConfig {
|
|||
template: string
|
||||
}
|
||||
|
||||
const supportPromptConfigs: Record<string, SupportPromptConfig> = {
|
||||
type SupportPromptType =
|
||||
| "ENHANCE"
|
||||
| "EXPLAIN"
|
||||
| "FIX"
|
||||
| "IMPROVE"
|
||||
| "ADD_TO_CONTEXT"
|
||||
| "TERMINAL_ADD_TO_CONTEXT"
|
||||
| "TERMINAL_FIX"
|
||||
| "TERMINAL_EXPLAIN"
|
||||
| "NEW_TASK"
|
||||
|
||||
const supportPromptConfigs: Record<SupportPromptType, SupportPromptConfig> = {
|
||||
ENHANCE: {
|
||||
template: `Generate an enhanced version of this prompt (reply with only the enhanced prompt - no conversation, explanations, lead-in, bullet points, placeholders, or surrounding quotes):
|
||||
|
||||
|
|
@ -124,8 +135,6 @@ Please provide:
|
|||
},
|
||||
} as const
|
||||
|
||||
type SupportPromptType = keyof typeof supportPromptConfigs
|
||||
|
||||
export const supportPrompt = {
|
||||
default: Object.fromEntries(Object.entries(supportPromptConfigs).map(([key, config]) => [key, config.template])),
|
||||
get: (customSupportPrompts: Record<string, any> | undefined, type: SupportPromptType): string => {
|
||||
|
|
|
|||
7
src/utils/commands.ts
Normal file
7
src/utils/commands.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
import { Package, CommandId, CodeActionId, TerminalActionId } from "../schemas"
|
||||
|
||||
export const getCommand = (id: CommandId) => `${Package.name}.${id}`
|
||||
|
||||
export const getCodeActionCommand = (id: CodeActionId) => `${Package.name}.${id}`
|
||||
|
||||
export const getTerminalCommand = (id: TerminalActionId) => `${Package.name}.${id}`
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
import * as vscode from "vscode"
|
||||
import * as path from "path"
|
||||
import * as fs from "fs/promises"
|
||||
|
||||
import { Package } from "../schemas"
|
||||
import { t } from "../i18n"
|
||||
|
||||
/**
|
||||
|
|
@ -14,7 +16,7 @@ export async function getStorageBasePath(defaultPath: string): Promise<string> {
|
|||
|
||||
try {
|
||||
// This is the line causing the error in tests
|
||||
const config = vscode.workspace.getConfiguration("roo-cline")
|
||||
const config = vscode.workspace.getConfiguration(Package.name)
|
||||
customStoragePath = config.get<string>("customStoragePath", "")
|
||||
} catch (error) {
|
||||
console.warn("Could not access VSCode configuration - using default path")
|
||||
|
|
@ -88,7 +90,7 @@ export async function promptForCustomStoragePath(): Promise<void> {
|
|||
|
||||
let currentPath = ""
|
||||
try {
|
||||
const currentConfig = vscode.workspace.getConfiguration("roo-cline")
|
||||
const currentConfig = vscode.workspace.getConfiguration(Package.name)
|
||||
currentPath = currentConfig.get<string>("customStoragePath", "")
|
||||
} catch (error) {
|
||||
console.error("Could not access configuration")
|
||||
|
|
@ -123,7 +125,7 @@ export async function promptForCustomStoragePath(): Promise<void> {
|
|||
// If user canceled the operation, result will be undefined
|
||||
if (result !== undefined) {
|
||||
try {
|
||||
const currentConfig = vscode.workspace.getConfiguration("roo-cline")
|
||||
const currentConfig = vscode.workspace.getConfiguration(Package.name)
|
||||
await currentConfig.update("customStoragePath", result, vscode.ConfigurationTarget.Global)
|
||||
|
||||
if (result) {
|
||||
|
|
@ -2,9 +2,10 @@ import { useState, memo } from "react"
|
|||
import { Trans } from "react-i18next"
|
||||
import { VSCodeLink } from "@vscode/webview-ui-toolkit/react"
|
||||
|
||||
import { Package } from "@roo/schemas"
|
||||
|
||||
import { useAppTranslation } from "@src/i18n/TranslationContext"
|
||||
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "@src/components/ui"
|
||||
import { version } from "../../../../package.json"
|
||||
|
||||
interface AnnouncementProps {
|
||||
hideAnnouncement: () => void
|
||||
|
|
@ -35,8 +36,10 @@ const Announcement = ({ hideAnnouncement }: AnnouncementProps) => {
|
|||
}}>
|
||||
<DialogContent className="max-w-96">
|
||||
<DialogHeader>
|
||||
<DialogTitle>{t("chat:announcement.title", { version })}</DialogTitle>
|
||||
<DialogDescription>{t("chat:announcement.description", { version })}</DialogDescription>
|
||||
<DialogTitle>{t("chat:announcement.title", { version: Package.version })}</DialogTitle>
|
||||
<DialogDescription>
|
||||
{t("chat:announcement.description", { version: Package.version })}
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<div>
|
||||
<h3>{t("chat:announcement.whatsNew")}</h3>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { render, screen } from "@testing-library/react"
|
||||
import { jest } from "@jest/globals" // Or 'jest' if using Jest
|
||||
import { version } from "../../../../../package.json"
|
||||
|
||||
import { Package } from "@roo/schemas"
|
||||
|
||||
import Announcement from "../Announcement"
|
||||
|
||||
|
|
@ -31,7 +32,7 @@ jest.mock("@src/i18n/TranslationContext", () => ({
|
|||
|
||||
describe("Announcement", () => {
|
||||
const mockHideAnnouncement = jest.fn()
|
||||
const expectedVersion = version
|
||||
const expectedVersion = Package.version
|
||||
|
||||
it("renders the announcement with the version number from package.json", () => {
|
||||
render(<Announcement hideAnnouncement={mockHideAnnouncement} />)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
import { Package } from "@roo/schemas"
|
||||
|
||||
export function getCallbackUrl(provider: string, uriScheme?: string) {
|
||||
return encodeURIComponent(`${uriScheme || "vscode"}://rooveterinaryinc.roo-cline/${provider}`)
|
||||
return encodeURIComponent(`${uriScheme || "vscode"}://${Package.publisher}.${Package.name}/${provider}`)
|
||||
}
|
||||
|
||||
export function getGlamaAuthUrl(uriScheme?: string) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue