This commit is contained in:
Deleted user 2026-05-27 11:07:13 +08:00 committed by GitHub
commit 31327fbda5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 88 additions and 2 deletions

View file

@ -29,6 +29,19 @@ export function getVisibleProviderOrLog(outputChannel: vscode.OutputChannel): Cl
let sidebarPanel: vscode.WebviewView | undefined = undefined
let tabPanel: vscode.WebviewPanel | undefined = undefined
// Callback invoked when a tab provider is created via openClineInNewTab.
// This allows the API to register event listeners on dynamically created tab providers.
let onTabProviderCreatedCallback: ((provider: ClineProvider) => void) | undefined
/**
* Register a callback that will be invoked whenever a new tab provider is
* created via `openClineInNewTab`. Used by the API to forward events from
* tab providers to the `RooCodeAPI` EventEmitter.
*/
export function setOnTabProviderCreated(callback: (provider: ClineProvider) => void): void {
onTabProviderCreatedCallback = callback
}
/**
* Get the currently active panel
* @returns WebviewPanel或WebviewView
@ -235,5 +248,8 @@ export const openClineInNewTab = async ({ context, outputChannel }: Omit<Registe
await delay(100)
await vscode.commands.executeCommand("workbench.action.lockEditorGroup")
// Notify the API (if registered) so it can forward events from this tab provider.
onTabProviderCreatedCallback?.(tabProvider)
return tabProvider
}

View file

@ -0,0 +1,68 @@
import { describe, it, expect, vi, beforeEach } from "vitest"
import * as vscode from "vscode"
import { API } from "../api"
import { ClineProvider } from "../../core/webview/ClineProvider"
import { setOnTabProviderCreated } from "../../activate/registerCommands"
vi.mock("vscode")
vi.mock("../../core/webview/ClineProvider")
// Capture the callback registered by the API constructor.
let capturedCallback: ((provider: ClineProvider) => void) | undefined
vi.mock("../../activate/registerCommands", () => ({
openClineInNewTab: vi.fn(),
setOnTabProviderCreated: vi.fn((cb: (provider: ClineProvider) => void) => {
capturedCallback = cb
}),
}))
describe("API - Tab Provider Event Registration", () => {
let mockOutputChannel: vscode.OutputChannel
let mockSidebarProvider: ClineProvider
let api: API
beforeEach(() => {
capturedCallback = undefined
mockOutputChannel = {
appendLine: vi.fn(),
} as unknown as vscode.OutputChannel
mockSidebarProvider = {
context: {} as vscode.ExtensionContext,
on: vi.fn(),
postMessageToWebview: vi.fn(),
getCurrentTaskStack: vi.fn().mockReturnValue([]),
getCurrentTask: vi.fn().mockReturnValue(undefined),
viewLaunched: true,
} as unknown as ClineProvider
api = new API(mockOutputChannel, mockSidebarProvider, undefined, false)
})
it("should call setOnTabProviderCreated during construction", () => {
expect(setOnTabProviderCreated).toHaveBeenCalledWith(expect.any(Function))
expect(capturedCallback).toBeDefined()
})
it("should register listeners on tab providers created via commands", () => {
const mockTabProvider = {
on: vi.fn(),
context: {} as vscode.ExtensionContext,
} as unknown as ClineProvider
// Simulate a tab provider being created via command
capturedCallback!(mockTabProvider)
// registerListeners calls provider.on(RooCodeEventName.TaskCreated, ...)
// so we verify that on() was called on the tab provider
expect(mockTabProvider.on).toHaveBeenCalled()
})
it("should register listeners on the sidebar provider during construction", () => {
// The sidebar provider should also have listeners registered
expect(mockSidebarProvider.on).toHaveBeenCalled()
})
})

View file

@ -25,7 +25,7 @@ import { IpcServer } from "@roo-code/ipc"
import { Package } from "../shared/package"
import { ClineProvider } from "../core/webview/ClineProvider"
import { openClineInNewTab } from "../activate/registerCommands"
import { openClineInNewTab, setOnTabProviderCreated } from "../activate/registerCommands"
import { getCommands } from "../services/command/commands"
import { getModels } from "../api/providers/fetchers/modelCache"
@ -62,6 +62,9 @@ export class API extends EventEmitter<RooCodeEvents> implements RooCodeAPI {
this.registerListeners(this.sidebarProvider)
// Ensure tab providers created via commands also get event listeners.
setOnTabProviderCreated((provider) => this.registerListeners(provider))
if (socketPath) {
const ipc = (this.ipc = new IpcServer(socketPath, this.log))
@ -190,7 +193,6 @@ export class API extends EventEmitter<RooCodeEvents> implements RooCodeAPI {
await vscode.commands.executeCommand("workbench.action.closeAllEditors")
provider = await openClineInNewTab({ context: this.context, outputChannel: this.outputChannel })
this.registerListeners(provider)
} else {
await vscode.commands.executeCommand(`${Package.name}.SidebarProvider.focus`)