fix: register API event listeners on tab providers created via commands#11510
fix: register API event listeners on tab providers created via commands#11510roomote[bot] wants to merge 2 commits intomainfrom
Conversation
When opening Roo Code in a new tab via command palette (openInNewTab or popoutButtonClicked), the returned ClineProvider was discarded without calling registerListeners(). This meant events like taskCreated, message, taskCompleted etc. were never forwarded through the RooCodeAPI EventEmitter. This fix adds a callback hook (setOnTabProviderCreated) in registerCommands that the API registers during construction. When openClineInNewTab creates a new tab provider, it invokes this callback so the API can attach its event forwarding listeners. Fixes #11507
All previously flagged issues have been resolved. No new issues found.
Mention @roomote in a comment to request specific changes to this pull request or fix all unresolved issues. |
| this.registerListeners(this.sidebarProvider) | ||
|
|
||
| // Ensure tab providers created via commands also get event listeners. | ||
| setOnTabProviderCreated((provider) => this.registerListeners(provider)) |
There was a problem hiding this comment.
This callback now registers listeners on every tab provider created via openClineInNewTab, but startNewTask({ newTab: true }) (line ~188-189) also explicitly calls this.registerListeners(provider) after openClineInNewTab returns. The result is double-registration: every event from tab providers created through startNewTask will be emitted twice through the API EventEmitter. The explicit this.registerListeners(provider) call in startNewTask should be removed now that the callback handles it.
Fix it with Roo Code or mention @roomote and request a fix.
There was a problem hiding this comment.
Fixaroo
See task
Removed the duplicate registerListeners call in startNewTask since the setOnTabProviderCreated callback already handles it. All tests and checks pass.
The setOnTabProviderCreated callback already registers listeners on tab providers created via openClineInNewTab. The explicit registerListeners call in startNewTask caused double event registration for tab providers created through that code path.
Related GitHub Issue
Closes: #11507
Description
This PR attempts to address Issue #11507. Feedback and guidance are welcome.
Root cause: When
openClineInNewTab()is called from command handlers (popoutButtonClickedoropenInNewTabinregisterCommands.ts), the returnedClineProviderwas discarded without callingAPI.registerListeners(). This meant events liketaskCreated,message,taskCompletedetc. were never forwarded through theRooCodeAPIEventEmitter. In contrast, when called fromAPI.startNewTask(),registerListeners()was properly called.Fix: Added a callback hook mechanism:
src/activate/registerCommands.ts: AddedsetOnTabProviderCreated(callback)function that stores a callback, and invokes it insideopenClineInNewTab()after the tab provider is fully set up.src/extension/api.ts: During API construction, callssetOnTabProviderCreated()with a callback that invokesthis.registerListeners(provider), ensuring every tab provider created via commands gets event listeners registered.This approach is minimally invasive -- it adds a simple hook without changing the existing function signature of
openClineInNewTabor requiring the API instance to be passed into command registration.Test Procedure
src/extension/__tests__/api-tab-events.spec.tswith 3 tests:setOnTabProviderCreatedis called during API constructionregisterListenersis called on tab providers created via commandsregisterListenersis called on the sidebar provider during constructioncd src && npx vitest run extension/__tests__/api-tab-events.spec.tsapi-send-message.spec.ts) continue to passPre-Submission Checklist
Screenshots / Videos
N/A - no UI changes.
Documentation Updates
No documentation updates are required.
Additional Notes
The fix ensures that tab providers created via any path (commands, API) will have their events forwarded through the
RooCodeAPIEventEmitter.Start a new Roo Code Cloud session on this branch